From 66526765714b08969548a414d3fa87dbe333242d Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Sat, 28 Jul 2012 19:25:08 +0000 Subject: "!Deprecated" folders moved from root directory to plugins git-svn-id: http://svn.miranda-ng.org/main/trunk@1230 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- !Deprecated/NewAwaySysMod/AggressiveOptimize.h | 169 - !Deprecated/NewAwaySysMod/AwayOpt.cpp | 1711 ---- !Deprecated/NewAwaySysMod/AwaySys.cpp | 1025 -- !Deprecated/NewAwaySysMod/Client.cpp | 232 - !Deprecated/NewAwaySysMod/Common.h | 411 - !Deprecated/NewAwaySysMod/ContactList.cpp | 905 -- !Deprecated/NewAwaySysMod/ContactList.h | 142 - !Deprecated/NewAwaySysMod/Images/Delete.ico | Bin 2038 -> 0 bytes !Deprecated/NewAwaySysMod/Images/DisableNotify.ico | Bin 2038 -> 0 bytes !Deprecated/NewAwaySysMod/Images/Dot.ico | Bin 2550 -> 0 bytes !Deprecated/NewAwaySysMod/Images/EnableNotify.ico | Bin 2038 -> 0 bytes !Deprecated/NewAwaySysMod/Images/Ignore.ico | Bin 2550 -> 0 bytes !Deprecated/NewAwaySysMod/Images/Indefinite.ico | Bin 2550 -> 0 bytes !Deprecated/NewAwaySysMod/Images/MsgIcon.ico | Bin 1150 -> 0 bytes !Deprecated/NewAwaySysMod/Images/NewCat.ico | Bin 2550 -> 0 bytes !Deprecated/NewAwaySysMod/Images/NewMessage.ico | Bin 2550 -> 0 bytes !Deprecated/NewAwaySysMod/Images/SaveAsNew.ico | Bin 2038 -> 0 bytes !Deprecated/NewAwaySysMod/Images/SaveMsg.ico | Bin 1150 -> 0 bytes !Deprecated/NewAwaySysMod/Images/Settings.ico | Bin 2550 -> 0 bytes !Deprecated/NewAwaySysMod/Images/Status_Other.ico | Bin 1406 -> 0 bytes !Deprecated/NewAwaySysMod/Images/Variables.ico | Bin 2550 -> 0 bytes !Deprecated/NewAwaySysMod/Images/off.bmp | Bin 1336 -> 0 bytes !Deprecated/NewAwaySysMod/Images/off.ico | Bin 1150 -> 0 bytes !Deprecated/NewAwaySysMod/Images/on.bmp | Bin 1016 -> 0 bytes !Deprecated/NewAwaySysMod/Images/on.ico | Bin 1150 -> 0 bytes !Deprecated/NewAwaySysMod/MsgEventAdded.cpp | 317 - !Deprecated/NewAwaySysMod/MsgTree.cpp | 790 -- !Deprecated/NewAwaySysMod/MsgTree.h | 95 - !Deprecated/NewAwaySysMod/NewAwaySys.rc | 701 -- !Deprecated/NewAwaySysMod/NewAwaySys.vcxproj | 242 - .../NewAwaySysMod/NewAwaySys.vcxproj.filters | 187 - !Deprecated/NewAwaySysMod/Notification.cpp | 289 - !Deprecated/NewAwaySysMod/Path.h | 43 - !Deprecated/NewAwaySysMod/Properties.cpp | 411 - !Deprecated/NewAwaySysMod/Properties.h | 605 -- !Deprecated/NewAwaySysMod/ReadAwayMsg.cpp | 161 - !Deprecated/NewAwaySysMod/Services.cpp | 231 - !Deprecated/NewAwaySysMod/Services.h | 27 - !Deprecated/NewAwaySysMod/SetAwayMsg.cpp | 1706 ---- !Deprecated/NewAwaySysMod/VersionNo.h | 5 - !Deprecated/NewAwaySysMod/copying.txt | 340 - !Deprecated/NewAwaySysMod/nas_readme.txt | 281 - !Deprecated/NewAwaySysMod/nas_translation.txt | 238 - .../NewAwaySysMod/newawaysysmod-translation.txt | 226 - !Deprecated/NewAwaySysMod/resource.h | 261 - !Deprecated/NewAwaySysMod/version.rc | 58 - !NotAdopted/IMO2sProxy/Makefile | 11 - !NotAdopted/IMO2sProxy/README.txt | 240 - !NotAdopted/IMO2sProxy/bin/setupimo.bat | 24 - !NotAdopted/IMO2sProxy/msvc/imoproxy.dsp | 248 - !NotAdopted/IMO2sProxy/msvc/imoproxy.dsw | 41 - !NotAdopted/IMO2sProxy/msvc/imoproxy.mak | 221 - !NotAdopted/IMO2sProxy/msvc/imoskype.dsp | 230 - !NotAdopted/IMO2sProxy/msvc/imoskype.dsw | 29 - !NotAdopted/IMO2sProxy/msvc/imoskype.mak | 193 - !NotAdopted/IMO2sProxy/msvc/make.bat | 2 - !NotAdopted/IMO2sProxy/msvc/make_w32.bat | 7 - !NotAdopted/IMO2sProxy/msvc/make_w64.bat | 5 - !NotAdopted/IMO2sProxy/src/common/cJSON.c | 365 - !NotAdopted/IMO2sProxy/src/common/cJSON.h | 97 - !NotAdopted/IMO2sProxy/src/common/fifo.c | 144 - !NotAdopted/IMO2sProxy/src/common/fifo.h | 26 - !NotAdopted/IMO2sProxy/src/common/memlist.c | 158 - !NotAdopted/IMO2sProxy/src/common/memlist.h | 30 - !NotAdopted/IMO2sProxy/src/imo2skype/Makefile | 19 - !NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.c | 110 - !NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.h | 16 - !NotAdopted/IMO2sProxy/src/imo2skype/buddylist.c | 204 - !NotAdopted/IMO2sProxy/src/imo2skype/buddylist.h | 28 - !NotAdopted/IMO2sProxy/src/imo2skype/callqueue.c | 95 - !NotAdopted/IMO2sProxy/src/imo2skype/callqueue.h | 32 - !NotAdopted/IMO2sProxy/src/imo2skype/crash.c | 295 - !NotAdopted/IMO2sProxy/src/imo2skype/crash.h | 1 - .../IMO2sProxy/src/imo2skype/imo2skypeapi.c | 1959 ---- .../IMO2sProxy/src/imo2skype/imo2skypeapi.h | 13 - !NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.c | 78 - !NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.h | 28 - !NotAdopted/IMO2sProxy/src/imo2skype/imo2stest.c | 60 - !NotAdopted/IMO2sProxy/src/imo2skype/main.c | 197 - .../IMO2sProxy/src/imo2skype/miranda/imoproxy.c | 882 -- .../src/imo2skype/miranda/io_layer_netlib.c | 340 - .../IMO2sProxy/src/imo2skype/miranda/res.aps | Bin 20400 -> 0 bytes .../IMO2sProxy/src/imo2skype/miranda/res.rc | 145 - .../IMO2sProxy/src/imo2skype/miranda/resource.h | 39 - .../src/imo2skype/miranda/sdk/m_updater.h | 146 - .../src/imo2skype/miranda/skypepluginlink.c | 233 - .../src/imo2skype/miranda/skypepluginlink.h | 10 - !NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.c | 158 - !NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.h | 28 - !NotAdopted/IMO2sProxy/src/imo2skype/queue.c | 94 - !NotAdopted/IMO2sProxy/src/imo2skype/queue.h | 17 - !NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c | 565 -- !NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.h | 11 - !NotAdopted/IMO2sProxy/src/imo2skype/w32browser.c | 1143 --- !NotAdopted/IMO2sProxy/src/imo2skype/w32browser.h | 5 - !NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.c | 387 - !NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.h | 6 - !NotAdopted/IMO2sProxy/src/imolib/Makefile | 14 - !NotAdopted/IMO2sProxy/src/imolib/imo_request.c | 388 - !NotAdopted/IMO2sProxy/src/imolib/imo_request.h | 36 - !NotAdopted/IMO2sProxy/src/imolib/imo_skype.c | 707 -- !NotAdopted/IMO2sProxy/src/imolib/imo_skype.h | 37 - !NotAdopted/IMO2sProxy/src/imolib/io_layer.c | 175 - !NotAdopted/IMO2sProxy/src/imolib/io_layer.h | 25 - !NotAdopted/IMO2sProxy/src/imolib/io_layer_win32.c | 440 - !NotAdopted/IMO2sProxy/src/imolib/skypetst.c | 211 - !NotAdopted/IMO2sProxy/structure.txt | 102 - .../NotesAndReminders/NotesReminders.vcxproj | 121 - .../NotesReminders.vcxproj.filters | 53 - .../NotesAndReminders/docs/N&R - langpack.txt | 169 - .../NotesAndReminders/docs/N&R - readme.txt | 315 - !NotAdopted/NotesAndReminders/res/addremin.ico | Bin 1406 -> 0 bytes !NotAdopted/NotesAndReminders/res/bringfront.ico | Bin 1406 -> 0 bytes !NotAdopted/NotesAndReminders/res/captioni.ico | Bin 766 -> 0 bytes !NotAdopted/NotesAndReminders/res/captionn.ico | Bin 766 -> 0 bytes !NotAdopted/NotesAndReminders/res/deleteic.ico | Bin 1406 -> 0 bytes !NotAdopted/NotesAndReminders/res/deletere.ico | Bin 1406 -> 0 bytes !NotAdopted/NotesAndReminders/res/hidenote.ico | Bin 766 -> 0 bytes !NotAdopted/NotesAndReminders/res/noteicon.ico | Bin 1406 -> 0 bytes !NotAdopted/NotesAndReminders/res/playsound.ico | Bin 318 -> 0 bytes !NotAdopted/NotesAndReminders/res/reminder.ico | Bin 1406 -> 0 bytes !NotAdopted/NotesAndReminders/res/removeno.ico | Bin 766 -> 0 bytes !NotAdopted/NotesAndReminders/res/resource.rc | 362 - !NotAdopted/NotesAndReminders/res/showhide.ico | Bin 1406 -> 0 bytes !NotAdopted/NotesAndReminders/res/viewnotes.ico | Bin 3638 -> 0 bytes !NotAdopted/NotesAndReminders/res/viewremi.ico | Bin 3638 -> 0 bytes !NotAdopted/NotesAndReminders/src/globals.h | 147 - !NotAdopted/NotesAndReminders/src/hotkeys.cpp | 137 - !NotAdopted/NotesAndReminders/src/main.cpp | 389 - !NotAdopted/NotesAndReminders/src/miscutils.cpp | 246 - !NotAdopted/NotesAndReminders/src/miscutils.h | 47 - !NotAdopted/NotesAndReminders/src/notes.cpp | 2180 ---- !NotAdopted/NotesAndReminders/src/options.cpp | 637 -- !NotAdopted/NotesAndReminders/src/reminders.cpp | 2890 ------ !NotAdopted/NotesAndReminders/src/resource.h | 65 - !NotAdopted/SMS/!clear.bat | 36 - .../SMS/AdditionalFunctions/BuffToLowerCase.h | 56 - .../SMS/AdditionalFunctions/DebugFunctions.h | 101 - .../SMS/AdditionalFunctions/InterlockedFunctions.h | 127 - !NotAdopted/SMS/AdditionalFunctions/ListMT.h | 328 - .../SMS/AdditionalFunctions/MemoryCompare.h | 177 - !NotAdopted/SMS/AdditionalFunctions/MemoryFind.h | 81 - .../SMS/AdditionalFunctions/MemoryFindByte.h | 71 - !NotAdopted/SMS/SMS.def | 8 - !NotAdopted/SMS/SMSConstans.h | 108 - !NotAdopted/SMS/SMS_svc.cpp | 243 - !NotAdopted/SMS/functions.cpp | 761 -- !NotAdopted/SMS/langpack_sms.txt | 119 - !NotAdopted/SMS/main.cpp | 298 - !NotAdopted/SMS/main.h | 236 - !NotAdopted/SMS/options.cpp | 116 - !NotAdopted/SMS/readme.txt | 49 - !NotAdopted/SMS/receive.cpp | 310 - !NotAdopted/SMS/recvdlg.cpp | 269 - !NotAdopted/SMS/recvdlg.h | 18 - !NotAdopted/SMS/res/SMSNOTSENT.ico | Bin 1406 -> 0 bytes !NotAdopted/SMS/res/SMSSENT.ico | Bin 1406 -> 0 bytes !NotAdopted/SMS/res/halftick.ico | Bin 318 -> 0 bytes !NotAdopted/SMS/resource.h | 70 - !NotAdopted/SMS/resource.rc | 291 - !NotAdopted/SMS/send.cpp | 88 - !NotAdopted/SMS/senddlg.cpp | 1177 --- !NotAdopted/SMS/senddlg.h | 40 - !NotAdopted/SMS/sms.dsp | 231 - !NotAdopted/SMS/sms.dsw | 29 - !NotAdopted/SMS/sms.opt | Bin 52736 -> 0 bytes !NotAdopted/SMS/sms.vcproj | 388 - !NotAdopted/Skype/Skript1.aps | Bin 122080 -> 0 bytes !NotAdopted/Skype/Skript1.rc | 484 - !NotAdopted/Skype/Skype_protocol.dsp | 394 - !NotAdopted/Skype/Skype_protocol.dsw | 29 - !NotAdopted/Skype/Skype_protocol.mak | 238 - !NotAdopted/Skype/Skype_protocol.sln | 44 - !NotAdopted/Skype/Skype_protocol.vcproj | 2843 ------ !NotAdopted/Skype/alogon.c | 129 - !NotAdopted/Skype/alogon.h | 1 - !NotAdopted/Skype/changelog.txt | 330 - !NotAdopted/Skype/contacts.c | 417 - !NotAdopted/Skype/contacts.h | 11 - !NotAdopted/Skype/debug.c | 75 - !NotAdopted/Skype/debug.h | 23 - !NotAdopted/Skype/deploy.bat | 15 - !NotAdopted/Skype/ezxml/ezxml.c | 1033 -- !NotAdopted/Skype/ezxml/ezxml.h | 167 - !NotAdopted/Skype/gchat.c | 910 -- !NotAdopted/Skype/gchat.h | 47 - !NotAdopted/Skype/m_popup.h | 307 - !NotAdopted/Skype/m_toptoolbar.h | 107 - !NotAdopted/Skype/make.bat | 6 - !NotAdopted/Skype/make_w32.bat | 5 - !NotAdopted/Skype/make_w64.bat | 6 - !NotAdopted/Skype/memlist.c | 248 - !NotAdopted/Skype/memlist.h | 43 - !NotAdopted/Skype/msglist.c | 86 - !NotAdopted/Skype/msglist.h | 15 - !NotAdopted/Skype/msgq.c | 90 - !NotAdopted/Skype/msgq.h | 64 - !NotAdopted/Skype/pthread.c | 70 - !NotAdopted/Skype/pthread.h | 26 - !NotAdopted/Skype/readme.txt | 47 - !NotAdopted/Skype/res/8060.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/Copy of online.ico | Bin 1406 -> 0 bytes !NotAdopted/Skype/res/DND.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/Invite.ico | Bin 1886 -> 0 bytes !NotAdopted/Skype/res/NA.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/add.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/add2.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/auth.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/away.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/call.bmp | Bin 214 -> 0 bytes !NotAdopted/Skype/res/call.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/chat.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/conference.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/error.ico | Bin 9062 -> 0 bytes !NotAdopted/Skype/res/hang_up.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/history.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/hold.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/import.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/invisible.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/message.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/occupied.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/offline.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/online.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/pause.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/phone.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/resume.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/search.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/skype.ico | Bin 13270 -> 0 bytes !NotAdopted/Skype/res/skypeout.ico | Bin 2550 -> 0 bytes !NotAdopted/Skype/res/skyping.ico | Bin 2038 -> 0 bytes !NotAdopted/Skype/resource.h | 124 - !NotAdopted/Skype/skype.c | 3465 ------- !NotAdopted/Skype/skype.h | 188 - !NotAdopted/Skype/skypeapi.c | 1699 ---- !NotAdopted/Skype/skypeapi.h | 69 - !NotAdopted/Skype/skypeopt.c | 969 -- !NotAdopted/Skype/skypeopt.h | 49 - !NotAdopted/Skype/skypeprofile.c | 145 - !NotAdopted/Skype/skypeprofile.h | 33 - !NotAdopted/Skype/skypeproxy.h | 7 - !NotAdopted/Skype/skypeproxy/skypeproxy.c | 651 -- !NotAdopted/Skype/skypeproxy/skypeproxy.h | 36 - !NotAdopted/Skype/skypesvc.c | 188 - !NotAdopted/Skype/skypesvc.h | 24 - !NotAdopted/Skype/utf8.c | 334 - !NotAdopted/Skype/utf8.h | 47 - !NotAdopted/Skype/util.c | 57 - !NotAdopted/Skype/util.h | 7 - !NotAdopted/Skype/voiceservice.c | 156 - !NotAdopted/Skype/voiceservice.h | 18 - !NotAdopted/SmartAutoAway/AggressiveOptimize.h | 166 - !NotAdopted/SmartAutoAway/aa_utils.cpp | 396 - !NotAdopted/SmartAutoAway/autoaway.cpp | 662 -- !NotAdopted/SmartAutoAway/dlgproc.cpp | 281 - !NotAdopted/SmartAutoAway/globals.cpp | 113 - !NotAdopted/SmartAutoAway/globals.h | 349 - !NotAdopted/SmartAutoAway/here.ico | Bin 2550 -> 0 bytes !NotAdopted/SmartAutoAway/idle.cpp | 374 - !NotAdopted/SmartAutoAway/idleMenu.cpp | 147 - !NotAdopted/SmartAutoAway/idleMessages.cpp | 282 - !NotAdopted/SmartAutoAway/long.ico | Bin 2550 -> 0 bytes !NotAdopted/SmartAutoAway/reconnect.cpp | 328 - !NotAdopted/SmartAutoAway/reconnect.ico | Bin 2550 -> 0 bytes !NotAdopted/SmartAutoAway/resource.h | 77 - !NotAdopted/SmartAutoAway/saa-res.rc | 238 - !NotAdopted/SmartAutoAway/saa.cpp | 130 - !NotAdopted/SmartAutoAway/saa.dsp | 291 - !NotAdopted/SmartAutoAway/saa.dsw | 41 - !NotAdopted/SmartAutoAway/saa.h | 1 - !NotAdopted/SmartAutoAway/saamain.cpp | 415 - !NotAdopted/SmartAutoAway/saani.c | 85 - !NotAdopted/SmartAutoAway/saani.dsp | 107 - !NotAdopted/SmartAutoAway/short.ico | Bin 2550 -> 0 bytes !NotAdopted/SmartAutoAway/version.txt | 7 - !NotAdopted/SmartAutoReplier/ActionsHandler.cpp | 31 - !NotAdopted/SmartAutoReplier/ActionsHandler.h | 30 - !NotAdopted/SmartAutoReplier/AggressiveOptimize.h | 59 - !NotAdopted/SmartAutoReplier/Crc32Static.cpp | 139 - !NotAdopted/SmartAutoReplier/Crc32Static.h | 33 - !NotAdopted/SmartAutoReplier/CrushLog.cpp | 165 - !NotAdopted/SmartAutoReplier/CrushLog.h | 54 - !NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.cpp | 219 - !NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.h | 67 - !NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.cpp | 88 - !NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.h | 55 - !NotAdopted/SmartAutoReplier/GUI/OptionsDlg.cpp | 528 - !NotAdopted/SmartAutoReplier/GUI/OptionsDlg.h | 119 - !NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.cpp | 109 - !NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.h | 58 - .../SmartAutoReplier/GUI/SettingsDlgHolder.cpp | 207 - .../SmartAutoReplier/GUI/SettingsDlgHolder.h | 69 - .../SmartAutoReplier/Interfaces/ISettings.h | 34 - .../SmartAutoReplier/Interfaces/ISingletone.h | 35 - !NotAdopted/SmartAutoReplier/LuaBridge.cpp | 127 - !NotAdopted/SmartAutoReplier/LuaBridge.h | 96 - !NotAdopted/SmartAutoReplier/LuaScript.cpp | 215 - !NotAdopted/SmartAutoReplier/LuaScript.h | 68 - !NotAdopted/SmartAutoReplier/MessagesHandler.cpp | 469 - !NotAdopted/SmartAutoReplier/MessagesHandler.h | 72 - !NotAdopted/SmartAutoReplier/ModeMessHandler.cpp | 119 - !NotAdopted/SmartAutoReplier/ModeMessHandler.h | 34 - !NotAdopted/SmartAutoReplier/RuleItem.h | 47 - !NotAdopted/SmartAutoReplier/RulesStorage.cpp | 536 - !NotAdopted/SmartAutoReplier/RulesStorage.h | 63 - !NotAdopted/SmartAutoReplier/SAR.cpp | 462 - !NotAdopted/SmartAutoReplier/SAR.rc | 274 - !NotAdopted/SmartAutoReplier/SAR.vcxproj | 189 - !NotAdopted/SmartAutoReplier/SAR.vcxproj.filters | 77 - !NotAdopted/SmartAutoReplier/SarLuaScript.cpp | 358 - !NotAdopted/SmartAutoReplier/SarLuaScript.h | 57 - !NotAdopted/SmartAutoReplier/ScriptsReader.cpp | 175 - !NotAdopted/SmartAutoReplier/ScriptsReader.h | 57 - !NotAdopted/SmartAutoReplier/SettingsHandler.cpp | 204 - !NotAdopted/SmartAutoReplier/SettingsHandler.h | 96 - !NotAdopted/SmartAutoReplier/comfunc.cpp | 74 - !NotAdopted/SmartAutoReplier/comfunc.h | 26 - !NotAdopted/SmartAutoReplier/comlogging.h | 42 - !NotAdopted/SmartAutoReplier/luainc.h | 31 - !NotAdopted/SmartAutoReplier/lualib/ReadMe.txt | 37 - !NotAdopted/SmartAutoReplier/lualib/lapi.c | 922 -- !NotAdopted/SmartAutoReplier/lualib/lapi.h | 16 - !NotAdopted/SmartAutoReplier/lualib/lauxlib.c | 591 -- !NotAdopted/SmartAutoReplier/lualib/lauxlib.h | 145 - !NotAdopted/SmartAutoReplier/lualib/lbaselib.c | 674 -- !NotAdopted/SmartAutoReplier/lualib/lcode.c | 714 -- !NotAdopted/SmartAutoReplier/lualib/lcode.h | 74 - !NotAdopted/SmartAutoReplier/lualib/ldblib.c | 299 - !NotAdopted/SmartAutoReplier/lualib/ldebug.c | 585 -- !NotAdopted/SmartAutoReplier/lualib/ldebug.h | 31 - !NotAdopted/SmartAutoReplier/lualib/ldo.c | 458 - !NotAdopted/SmartAutoReplier/lualib/ldo.h | 60 - !NotAdopted/SmartAutoReplier/lualib/ldump.c | 170 - !NotAdopted/SmartAutoReplier/lualib/lfunc.c | 135 - !NotAdopted/SmartAutoReplier/lualib/lfunc.h | 25 - !NotAdopted/SmartAutoReplier/lualib/lgc.c | 493 - !NotAdopted/SmartAutoReplier/lualib/lgc.h | 25 - !NotAdopted/SmartAutoReplier/lualib/liolib.c | 750 -- !NotAdopted/SmartAutoReplier/lualib/llex.c | 417 - !NotAdopted/SmartAutoReplier/lualib/llex.h | 75 - !NotAdopted/SmartAutoReplier/lualib/llimits.h | 185 - !NotAdopted/SmartAutoReplier/lualib/lmathlib.c | 246 - !NotAdopted/SmartAutoReplier/lualib/lmem.c | 91 - !NotAdopted/SmartAutoReplier/lualib/lmem.h | 44 - !NotAdopted/SmartAutoReplier/lualib/loadlib.c | 205 - !NotAdopted/SmartAutoReplier/lualib/lobject.c | 195 - !NotAdopted/SmartAutoReplier/lualib/lobject.h | 336 - !NotAdopted/SmartAutoReplier/lualib/lopcodes.c | 102 - !NotAdopted/SmartAutoReplier/lualib/lopcodes.h | 238 - !NotAdopted/SmartAutoReplier/lualib/lparser.c | 1329 --- !NotAdopted/SmartAutoReplier/lualib/lparser.h | 71 - !NotAdopted/SmartAutoReplier/lualib/lstate.c | 220 - !NotAdopted/SmartAutoReplier/lualib/lstate.h | 195 - !NotAdopted/SmartAutoReplier/lualib/lstring.c | 102 - !NotAdopted/SmartAutoReplier/lualib/lstring.h | 33 - !NotAdopted/SmartAutoReplier/lualib/lstrlib.c | 770 -- !NotAdopted/SmartAutoReplier/lualib/ltable.c | 509 - !NotAdopted/SmartAutoReplier/lualib/ltable.h | 31 - !NotAdopted/SmartAutoReplier/lualib/ltablib.c | 250 - !NotAdopted/SmartAutoReplier/lualib/ltests.c | 852 -- !NotAdopted/SmartAutoReplier/lualib/ltm.c | 70 - !NotAdopted/SmartAutoReplier/lualib/ltm.h | 51 - !NotAdopted/SmartAutoReplier/lualib/lua.h | 391 - !NotAdopted/SmartAutoReplier/lualib/luainc.h | 12 - !NotAdopted/SmartAutoReplier/lualib/lualib.h | 56 - !NotAdopted/SmartAutoReplier/lualib/lualib.vcxproj | 138 - .../SmartAutoReplier/lualib/lualib.vcxproj.filters | 186 - !NotAdopted/SmartAutoReplier/lualib/lundump.c | 286 - !NotAdopted/SmartAutoReplier/lualib/lundump.h | 34 - !NotAdopted/SmartAutoReplier/lualib/lvm.c | 780 -- !NotAdopted/SmartAutoReplier/lualib/lvm.h | 35 - !NotAdopted/SmartAutoReplier/lualib/lzio.c | 81 - !NotAdopted/SmartAutoReplier/lualib/lzio.h | 64 - !NotAdopted/SmartAutoReplier/lualib/targetver.h | 8 - !NotAdopted/SmartAutoReplier/resource.h | 52 - !NotAdopted/SmartAutoReplier/sar.ico | Bin 318 -> 0 bytes !NotAdopted/SmartAutoReplier/stdafx.cpp | 27 - !NotAdopted/SmartAutoReplier/stdafx.h | 74 - !NotAdopted/SmartAutoReplier/wtl/atlapp.h | 2035 ---- !NotAdopted/SmartAutoReplier/wtl/atlcrack.h | 2384 ----- !NotAdopted/SmartAutoReplier/wtl/atlctrls.h | 10041 ------------------- !NotAdopted/SmartAutoReplier/wtl/atlctrlw.h | 4157 -------- !NotAdopted/SmartAutoReplier/wtl/atlctrlx.h | 5004 --------- !NotAdopted/SmartAutoReplier/wtl/atlddx.h | 679 -- !NotAdopted/SmartAutoReplier/wtl/atldlgs.h | 6403 ------------ !NotAdopted/SmartAutoReplier/wtl/atldwm.h | 461 - !NotAdopted/SmartAutoReplier/wtl/atlfind.h | 1032 -- !NotAdopted/SmartAutoReplier/wtl/atlframe.h | 3688 ------- !NotAdopted/SmartAutoReplier/wtl/atlgdi.h | 3891 ------- !NotAdopted/SmartAutoReplier/wtl/atlmisc.h | 3817 ------- !NotAdopted/SmartAutoReplier/wtl/atlprint.h | 1109 -- !NotAdopted/SmartAutoReplier/wtl/atlres.h | 263 - !NotAdopted/SmartAutoReplier/wtl/atlresce.h | 93 - !NotAdopted/SmartAutoReplier/wtl/atlribbon.h | 3446 ------- !NotAdopted/SmartAutoReplier/wtl/atlscrl.h | 2011 ---- !NotAdopted/SmartAutoReplier/wtl/atlsplit.h | 917 -- !NotAdopted/SmartAutoReplier/wtl/atltheme.h | 1218 --- !NotAdopted/SmartAutoReplier/wtl/atluser.h | 1391 --- !NotAdopted/SmartAutoReplier/wtl/atlwince.h | 2987 ------ !NotAdopted/SmartAutoReplier/wtl/atlwinx.h | 525 - !NotAdopted/Tlen/codec/gsm.h | 65 - !NotAdopted/Tlen/codec/gsm_codec.c | 283 - !NotAdopted/Tlen/codec/gsm_long.c | 183 - !NotAdopted/Tlen/codec/gsm_lpc.c | 208 - !NotAdopted/Tlen/codec/gsm_preprocess.c | 103 - !NotAdopted/Tlen/codec/gsm_rpe.c | 248 - !NotAdopted/Tlen/codec/gsm_short.c | 211 - !NotAdopted/Tlen/commons.h | 32 - !NotAdopted/Tlen/crypto/aes.c | 1336 --- !NotAdopted/Tlen/crypto/bignum.c | 2097 ---- !NotAdopted/Tlen/crypto/padlock.c | 162 - !NotAdopted/Tlen/crypto/polarssl/aes.h | 167 - !NotAdopted/Tlen/crypto/polarssl/bignum.h | 587 -- !NotAdopted/Tlen/crypto/polarssl/bn_mul.h | 738 -- !NotAdopted/Tlen/crypto/polarssl/config.h | 625 -- !NotAdopted/Tlen/crypto/polarssl/padlock.h | 100 - !NotAdopted/Tlen/docs/InstallScript.xml | 27 - !NotAdopted/Tlen/docs/changelog_tlen.txt | 269 - !NotAdopted/Tlen/docs/gpl.txt | 340 - !NotAdopted/Tlen/docs/gpl_comment.txt | 20 - !NotAdopted/Tlen/docs/readme_tlen.txt | 60 - !NotAdopted/Tlen/docs/tlen-translation.txt | 153 - !NotAdopted/Tlen/icos/auth_grant.ico | Bin 2550 -> 0 bytes !NotAdopted/Tlen/icos/auth_request.ico | Bin 2550 -> 0 bytes !NotAdopted/Tlen/icos/groupchats.ico | Bin 2550 -> 0 bytes !NotAdopted/Tlen/icos/image.ico | Bin 2550 -> 0 bytes !NotAdopted/Tlen/icos/mail.ico | Bin 2550 -> 0 bytes !NotAdopted/Tlen/icos/microphone.ico | Bin 2550 -> 0 bytes !NotAdopted/Tlen/icos/speaker.ico | Bin 2550 -> 0 bytes !NotAdopted/Tlen/icos/tlen.ico | Bin 2550 -> 0 bytes !NotAdopted/Tlen/icos/tlenchats.ico | Bin 2550 -> 0 bytes !NotAdopted/Tlen/icos/voicechat.ico | Bin 2550 -> 0 bytes !NotAdopted/Tlen/jabber.h | 438 - !NotAdopted/Tlen/jabber_iq.c | 114 - !NotAdopted/Tlen/jabber_iq.h | 61 - !NotAdopted/Tlen/jabber_iqid.c | 629 -- !NotAdopted/Tlen/jabber_list.c | 314 - !NotAdopted/Tlen/jabber_list.h | 90 - !NotAdopted/Tlen/jabber_misc.c | 219 - !NotAdopted/Tlen/jabber_opt.c | 708 -- !NotAdopted/Tlen/jabber_svc.c | 1300 --- !NotAdopted/Tlen/jabber_thread.c | 1465 --- !NotAdopted/Tlen/jabber_util.c | 635 -- !NotAdopted/Tlen/jabber_ws.c | 159 - !NotAdopted/Tlen/jabber_xml.c | 568 -- !NotAdopted/Tlen/jabber_xml.h | 78 - !NotAdopted/Tlen/resource.h | 147 - !NotAdopted/Tlen/tlen.c | 636 -- !NotAdopted/Tlen/tlen.rc | 439 - !NotAdopted/Tlen/tlen_10.vcxproj | 928 -- !NotAdopted/Tlen/tlen_advsearch.c | 113 - !NotAdopted/Tlen/tlen_avatar.c | 422 - !NotAdopted/Tlen/tlen_avatar.h | 34 - !NotAdopted/Tlen/tlen_czaty/AdminWindow.cpp | 490 - !NotAdopted/Tlen/tlen_czaty/AdminWindow.h | 63 - !NotAdopted/Tlen/tlen_czaty/ChatContainer.cpp | 480 - !NotAdopted/Tlen/tlen_czaty/ChatContainer.h | 100 - !NotAdopted/Tlen/tlen_czaty/ChatEvent.cpp | 174 - !NotAdopted/Tlen/tlen_czaty/ChatEvent.h | 60 - !NotAdopted/Tlen/tlen_czaty/ChatGroup.cpp | 99 - !NotAdopted/Tlen/tlen_czaty/ChatGroup.h | 55 - !NotAdopted/Tlen/tlen_czaty/ChatRoom.cpp | 68 - !NotAdopted/Tlen/tlen_czaty/ChatRoom.h | 51 - !NotAdopted/Tlen/tlen_czaty/ChatUser.cpp | 83 - !NotAdopted/Tlen/tlen_czaty/ChatUser.h | 49 - !NotAdopted/Tlen/tlen_czaty/ChatWindow.cpp | 2108 ---- !NotAdopted/Tlen/tlen_czaty/ChatWindow.h | 196 - !NotAdopted/Tlen/tlen_czaty/FontList.cpp | 206 - !NotAdopted/Tlen/tlen_czaty/FontList.h | 90 - !NotAdopted/Tlen/tlen_czaty/HelperDialog.cpp | 589 -- !NotAdopted/Tlen/tlen_czaty/HelperDialog.h | 95 - !NotAdopted/Tlen/tlen_czaty/ManagerWindow.cpp | 1067 -- !NotAdopted/Tlen/tlen_czaty/ManagerWindow.h | 93 - !NotAdopted/Tlen/tlen_czaty/Options.cpp | 789 -- !NotAdopted/Tlen/tlen_czaty/Options.h | 75 - !NotAdopted/Tlen/tlen_czaty/Utils.cpp | 138 - !NotAdopted/Tlen/tlen_czaty/Utils.h | 38 - !NotAdopted/Tlen/tlen_czaty/icos/admin.ico | Bin 894 -> 0 bytes .../Tlen/tlen_czaty/icos/administration.ico | Bin 894 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/blank.ico | Bin 318 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/bold.ico | Bin 894 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/chat.ico | Bin 894 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/delete.ico | Bin 1406 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/glowner.ico | Bin 894 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/invite.ico | Bin 894 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/italic.ico | Bin 894 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/message.ico | Bin 1406 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/next.ico | Bin 894 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/options.ico | Bin 1406 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/owner.ico | Bin 894 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/prev.ico | Bin 894 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/r_anon.ico | Bin 894 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/r_memb.ico | Bin 894 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/r_mod.ico | Bin 894 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/registered.ico | Bin 894 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/save.ico | Bin 318 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/search.ico | Bin 1406 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/sendmail.ico | Bin 1406 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/smile.ico | Bin 1406 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/tlenbig.ico | Bin 2238 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/tlensmall.ico | Bin 894 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/icos/underline.ico | Bin 894 -> 0 bytes !NotAdopted/Tlen/tlen_czaty/mucc.cpp | 188 - !NotAdopted/Tlen/tlen_czaty/mucc.h | 106 - !NotAdopted/Tlen/tlen_czaty/mucc.rc | 579 -- !NotAdopted/Tlen/tlen_czaty/mucc.vcxproj | 1245 --- !NotAdopted/Tlen/tlen_czaty/mucc_services.cpp | 140 - !NotAdopted/Tlen/tlen_czaty/mucc_services.h | 35 - !NotAdopted/Tlen/tlen_czaty/resource.h | 218 - !NotAdopted/Tlen/tlen_file.c | 718 -- !NotAdopted/Tlen/tlen_file.h | 34 - !NotAdopted/Tlen/tlen_muc.c | 1071 -- !NotAdopted/Tlen/tlen_muc.h | 45 - !NotAdopted/Tlen/tlen_p2p_new.c | 361 - !NotAdopted/Tlen/tlen_p2p_old.c | 536 - !NotAdopted/Tlen/tlen_p2p_old.h | 66 - !NotAdopted/Tlen/tlen_picture.c | 320 - !NotAdopted/Tlen/tlen_picture.h | 41 - !NotAdopted/Tlen/tlen_presence.c | 314 - !NotAdopted/Tlen/tlen_presence.h | 37 - !NotAdopted/Tlen/tlen_userinfo.c | 335 - !NotAdopted/Tlen/tlen_voice.c | 1122 --- !NotAdopted/Tlen/tlen_voice.h | 68 - !NotAdopted/XSoundNotify/DebugLogger.hpp | 91 - !NotAdopted/XSoundNotify/EventProcessor.cpp | 84 - !NotAdopted/XSoundNotify/EventProcessor.h | 27 - !NotAdopted/XSoundNotify/README | 1 - !NotAdopted/XSoundNotify/SettingsDialog.cpp | 124 - !NotAdopted/XSoundNotify/SettingsDialog.h | 60 - !NotAdopted/XSoundNotify/SoundNotifyData.cpp | 37 - !NotAdopted/XSoundNotify/SoundNotifyData.h | 33 - .../XSoundNotify/SoundNotifyDataStorage.cpp | 74 - !NotAdopted/XSoundNotify/SoundNotifyDataStorage.h | 34 - !NotAdopted/XSoundNotify/XSoundNotify.rc | Bin 5494 -> 0 bytes !NotAdopted/XSoundNotify/resource.h | Bin 1556 -> 0 bytes !NotAdopted/XSoundNotify/testplug.vcxproj | 167 - !NotAdopted/XSoundNotify/xsn_main.cpp | 122 - !NotAdopted/XSoundNotify/xsn_types.cpp | 32 - !NotAdopted/XSoundNotify/xsn_types.h | 33 - !NotAdopted/XSoundNotify/xsn_utils.cpp | 60 - !NotAdopted/XSoundNotify/xsn_utils.h | 18 - .../!Deprecated/NewAwaySysMod/AggressiveOptimize.h | 169 + plugins/!Deprecated/NewAwaySysMod/AwayOpt.cpp | 1711 ++++ plugins/!Deprecated/NewAwaySysMod/AwaySys.cpp | 1025 ++ plugins/!Deprecated/NewAwaySysMod/Client.cpp | 232 + plugins/!Deprecated/NewAwaySysMod/Common.h | 411 + plugins/!Deprecated/NewAwaySysMod/ContactList.cpp | 905 ++ plugins/!Deprecated/NewAwaySysMod/ContactList.h | 142 + .../!Deprecated/NewAwaySysMod/Images/Delete.ico | Bin 0 -> 2038 bytes .../NewAwaySysMod/Images/DisableNotify.ico | Bin 0 -> 2038 bytes plugins/!Deprecated/NewAwaySysMod/Images/Dot.ico | Bin 0 -> 2550 bytes .../NewAwaySysMod/Images/EnableNotify.ico | Bin 0 -> 2038 bytes .../!Deprecated/NewAwaySysMod/Images/Ignore.ico | Bin 0 -> 2550 bytes .../NewAwaySysMod/Images/Indefinite.ico | Bin 0 -> 2550 bytes .../!Deprecated/NewAwaySysMod/Images/MsgIcon.ico | Bin 0 -> 1150 bytes .../!Deprecated/NewAwaySysMod/Images/NewCat.ico | Bin 0 -> 2550 bytes .../NewAwaySysMod/Images/NewMessage.ico | Bin 0 -> 2550 bytes .../!Deprecated/NewAwaySysMod/Images/SaveAsNew.ico | Bin 0 -> 2038 bytes .../!Deprecated/NewAwaySysMod/Images/SaveMsg.ico | Bin 0 -> 1150 bytes .../!Deprecated/NewAwaySysMod/Images/Settings.ico | Bin 0 -> 2550 bytes .../NewAwaySysMod/Images/Status_Other.ico | Bin 0 -> 1406 bytes .../!Deprecated/NewAwaySysMod/Images/Variables.ico | Bin 0 -> 2550 bytes plugins/!Deprecated/NewAwaySysMod/Images/off.bmp | Bin 0 -> 1336 bytes plugins/!Deprecated/NewAwaySysMod/Images/off.ico | Bin 0 -> 1150 bytes plugins/!Deprecated/NewAwaySysMod/Images/on.bmp | Bin 0 -> 1016 bytes plugins/!Deprecated/NewAwaySysMod/Images/on.ico | Bin 0 -> 1150 bytes .../!Deprecated/NewAwaySysMod/MsgEventAdded.cpp | 317 + plugins/!Deprecated/NewAwaySysMod/MsgTree.cpp | 790 ++ plugins/!Deprecated/NewAwaySysMod/MsgTree.h | 95 + plugins/!Deprecated/NewAwaySysMod/NewAwaySys.rc | 701 ++ .../!Deprecated/NewAwaySysMod/NewAwaySys.vcxproj | 242 + .../NewAwaySysMod/NewAwaySys.vcxproj.filters | 187 + plugins/!Deprecated/NewAwaySysMod/Notification.cpp | 289 + plugins/!Deprecated/NewAwaySysMod/Path.h | 43 + plugins/!Deprecated/NewAwaySysMod/Properties.cpp | 411 + plugins/!Deprecated/NewAwaySysMod/Properties.h | 605 ++ plugins/!Deprecated/NewAwaySysMod/ReadAwayMsg.cpp | 161 + plugins/!Deprecated/NewAwaySysMod/Services.cpp | 231 + plugins/!Deprecated/NewAwaySysMod/Services.h | 27 + plugins/!Deprecated/NewAwaySysMod/SetAwayMsg.cpp | 1706 ++++ plugins/!Deprecated/NewAwaySysMod/VersionNo.h | 5 + plugins/!Deprecated/NewAwaySysMod/copying.txt | 340 + plugins/!Deprecated/NewAwaySysMod/nas_readme.txt | 281 + .../!Deprecated/NewAwaySysMod/nas_translation.txt | 238 + .../NewAwaySysMod/newawaysysmod-translation.txt | 226 + plugins/!Deprecated/NewAwaySysMod/resource.h | 261 + plugins/!Deprecated/NewAwaySysMod/version.rc | 58 + plugins/!NotAdopted/IMO2sProxy/Makefile | 11 + plugins/!NotAdopted/IMO2sProxy/README.txt | 240 + plugins/!NotAdopted/IMO2sProxy/bin/setupimo.bat | 24 + plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsp | 248 + plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsw | 41 + plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.mak | 221 + plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.dsp | 230 + plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.dsw | 29 + plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.mak | 193 + plugins/!NotAdopted/IMO2sProxy/msvc/make.bat | 2 + plugins/!NotAdopted/IMO2sProxy/msvc/make_w32.bat | 7 + plugins/!NotAdopted/IMO2sProxy/msvc/make_w64.bat | 5 + plugins/!NotAdopted/IMO2sProxy/src/common/cJSON.c | 365 + plugins/!NotAdopted/IMO2sProxy/src/common/cJSON.h | 97 + plugins/!NotAdopted/IMO2sProxy/src/common/fifo.c | 144 + plugins/!NotAdopted/IMO2sProxy/src/common/fifo.h | 26 + .../!NotAdopted/IMO2sProxy/src/common/memlist.c | 158 + .../!NotAdopted/IMO2sProxy/src/common/memlist.h | 30 + .../!NotAdopted/IMO2sProxy/src/imo2skype/Makefile | 19 + .../IMO2sProxy/src/imo2skype/avatarlist.c | 110 + .../IMO2sProxy/src/imo2skype/avatarlist.h | 16 + .../IMO2sProxy/src/imo2skype/buddylist.c | 204 + .../IMO2sProxy/src/imo2skype/buddylist.h | 28 + .../IMO2sProxy/src/imo2skype/callqueue.c | 95 + .../IMO2sProxy/src/imo2skype/callqueue.h | 32 + .../!NotAdopted/IMO2sProxy/src/imo2skype/crash.c | 295 + .../!NotAdopted/IMO2sProxy/src/imo2skype/crash.h | 1 + .../IMO2sProxy/src/imo2skype/imo2skypeapi.c | 1959 ++++ .../IMO2sProxy/src/imo2skype/imo2skypeapi.h | 13 + .../IMO2sProxy/src/imo2skype/imo2sproxy.c | 78 + .../IMO2sProxy/src/imo2skype/imo2sproxy.h | 28 + .../IMO2sProxy/src/imo2skype/imo2stest.c | 60 + .../!NotAdopted/IMO2sProxy/src/imo2skype/main.c | 197 + .../IMO2sProxy/src/imo2skype/miranda/imoproxy.c | 882 ++ .../src/imo2skype/miranda/io_layer_netlib.c | 340 + .../IMO2sProxy/src/imo2skype/miranda/res.aps | Bin 0 -> 20400 bytes .../IMO2sProxy/src/imo2skype/miranda/res.rc | 145 + .../IMO2sProxy/src/imo2skype/miranda/resource.h | 39 + .../src/imo2skype/miranda/sdk/m_updater.h | 146 + .../src/imo2skype/miranda/skypepluginlink.c | 233 + .../src/imo2skype/miranda/skypepluginlink.h | 10 + .../IMO2sProxy/src/imo2skype/msgqueue.c | 158 + .../IMO2sProxy/src/imo2skype/msgqueue.h | 28 + .../!NotAdopted/IMO2sProxy/src/imo2skype/queue.c | 94 + .../!NotAdopted/IMO2sProxy/src/imo2skype/queue.h | 17 + .../IMO2sProxy/src/imo2skype/socksproxy.c | 565 ++ .../IMO2sProxy/src/imo2skype/socksproxy.h | 11 + .../IMO2sProxy/src/imo2skype/w32browser.c | 1143 +++ .../IMO2sProxy/src/imo2skype/w32browser.h | 5 + .../IMO2sProxy/src/imo2skype/w32skypeemu.c | 387 + .../IMO2sProxy/src/imo2skype/w32skypeemu.h | 6 + plugins/!NotAdopted/IMO2sProxy/src/imolib/Makefile | 14 + .../IMO2sProxy/src/imolib/imo_request.c | 388 + .../IMO2sProxy/src/imolib/imo_request.h | 36 + .../!NotAdopted/IMO2sProxy/src/imolib/imo_skype.c | 707 ++ .../!NotAdopted/IMO2sProxy/src/imolib/imo_skype.h | 37 + .../!NotAdopted/IMO2sProxy/src/imolib/io_layer.c | 175 + .../!NotAdopted/IMO2sProxy/src/imolib/io_layer.h | 25 + .../IMO2sProxy/src/imolib/io_layer_win32.c | 440 + .../!NotAdopted/IMO2sProxy/src/imolib/skypetst.c | 211 + plugins/!NotAdopted/IMO2sProxy/structure.txt | 102 + .../NotesAndReminders/NotesReminders.vcxproj | 121 + .../NotesReminders.vcxproj.filters | 53 + .../NotesAndReminders/docs/N&R - langpack.txt | 169 + .../NotesAndReminders/docs/N&R - readme.txt | 315 + .../!NotAdopted/NotesAndReminders/res/addremin.ico | Bin 0 -> 1406 bytes .../NotesAndReminders/res/bringfront.ico | Bin 0 -> 1406 bytes .../!NotAdopted/NotesAndReminders/res/captioni.ico | Bin 0 -> 766 bytes .../!NotAdopted/NotesAndReminders/res/captionn.ico | Bin 0 -> 766 bytes .../!NotAdopted/NotesAndReminders/res/deleteic.ico | Bin 0 -> 1406 bytes .../!NotAdopted/NotesAndReminders/res/deletere.ico | Bin 0 -> 1406 bytes .../!NotAdopted/NotesAndReminders/res/hidenote.ico | Bin 0 -> 766 bytes .../!NotAdopted/NotesAndReminders/res/noteicon.ico | Bin 0 -> 1406 bytes .../NotesAndReminders/res/playsound.ico | Bin 0 -> 318 bytes .../!NotAdopted/NotesAndReminders/res/reminder.ico | Bin 0 -> 1406 bytes .../!NotAdopted/NotesAndReminders/res/removeno.ico | Bin 0 -> 766 bytes .../!NotAdopted/NotesAndReminders/res/resource.rc | 362 + .../!NotAdopted/NotesAndReminders/res/showhide.ico | Bin 0 -> 1406 bytes .../NotesAndReminders/res/viewnotes.ico | Bin 0 -> 3638 bytes .../!NotAdopted/NotesAndReminders/res/viewremi.ico | Bin 0 -> 3638 bytes .../!NotAdopted/NotesAndReminders/src/globals.h | 147 + .../!NotAdopted/NotesAndReminders/src/hotkeys.cpp | 137 + plugins/!NotAdopted/NotesAndReminders/src/main.cpp | 389 + .../NotesAndReminders/src/miscutils.cpp | 246 + .../!NotAdopted/NotesAndReminders/src/miscutils.h | 47 + .../!NotAdopted/NotesAndReminders/src/notes.cpp | 2180 ++++ .../!NotAdopted/NotesAndReminders/src/options.cpp | 637 ++ .../NotesAndReminders/src/reminders.cpp | 2890 ++++++ .../!NotAdopted/NotesAndReminders/src/resource.h | 65 + plugins/!NotAdopted/SMS/!clear.bat | 36 + .../SMS/AdditionalFunctions/BuffToLowerCase.h | 56 + .../SMS/AdditionalFunctions/DebugFunctions.h | 101 + .../SMS/AdditionalFunctions/InterlockedFunctions.h | 127 + .../!NotAdopted/SMS/AdditionalFunctions/ListMT.h | 328 + .../SMS/AdditionalFunctions/MemoryCompare.h | 177 + .../SMS/AdditionalFunctions/MemoryFind.h | 81 + .../SMS/AdditionalFunctions/MemoryFindByte.h | 71 + plugins/!NotAdopted/SMS/SMS.def | 8 + plugins/!NotAdopted/SMS/SMSConstans.h | 108 + plugins/!NotAdopted/SMS/SMS_svc.cpp | 243 + plugins/!NotAdopted/SMS/functions.cpp | 761 ++ plugins/!NotAdopted/SMS/langpack_sms.txt | 119 + plugins/!NotAdopted/SMS/main.cpp | 298 + plugins/!NotAdopted/SMS/main.h | 236 + plugins/!NotAdopted/SMS/options.cpp | 116 + plugins/!NotAdopted/SMS/readme.txt | 49 + plugins/!NotAdopted/SMS/receive.cpp | 310 + plugins/!NotAdopted/SMS/recvdlg.cpp | 269 + plugins/!NotAdopted/SMS/recvdlg.h | 18 + plugins/!NotAdopted/SMS/res/SMSNOTSENT.ico | Bin 0 -> 1406 bytes plugins/!NotAdopted/SMS/res/SMSSENT.ico | Bin 0 -> 1406 bytes plugins/!NotAdopted/SMS/res/halftick.ico | Bin 0 -> 318 bytes plugins/!NotAdopted/SMS/resource.h | 70 + plugins/!NotAdopted/SMS/resource.rc | 291 + plugins/!NotAdopted/SMS/send.cpp | 88 + plugins/!NotAdopted/SMS/senddlg.cpp | 1177 +++ plugins/!NotAdopted/SMS/senddlg.h | 40 + plugins/!NotAdopted/SMS/sms.dsp | 231 + plugins/!NotAdopted/SMS/sms.dsw | 29 + plugins/!NotAdopted/SMS/sms.opt | Bin 0 -> 52736 bytes plugins/!NotAdopted/SMS/sms.vcproj | 388 + plugins/!NotAdopted/Skype/Skript1.aps | Bin 0 -> 122080 bytes plugins/!NotAdopted/Skype/Skript1.rc | 484 + plugins/!NotAdopted/Skype/Skype_protocol.dsp | 394 + plugins/!NotAdopted/Skype/Skype_protocol.dsw | 29 + plugins/!NotAdopted/Skype/Skype_protocol.mak | 238 + plugins/!NotAdopted/Skype/Skype_protocol.sln | 44 + plugins/!NotAdopted/Skype/Skype_protocol.vcproj | 2843 ++++++ plugins/!NotAdopted/Skype/alogon.c | 129 + plugins/!NotAdopted/Skype/alogon.h | 1 + plugins/!NotAdopted/Skype/changelog.txt | 330 + plugins/!NotAdopted/Skype/contacts.c | 417 + plugins/!NotAdopted/Skype/contacts.h | 11 + plugins/!NotAdopted/Skype/debug.c | 75 + plugins/!NotAdopted/Skype/debug.h | 23 + plugins/!NotAdopted/Skype/deploy.bat | 15 + plugins/!NotAdopted/Skype/ezxml/ezxml.c | 1033 ++ plugins/!NotAdopted/Skype/ezxml/ezxml.h | 167 + plugins/!NotAdopted/Skype/gchat.c | 910 ++ plugins/!NotAdopted/Skype/gchat.h | 47 + plugins/!NotAdopted/Skype/m_popup.h | 307 + plugins/!NotAdopted/Skype/m_toptoolbar.h | 107 + plugins/!NotAdopted/Skype/make.bat | 6 + plugins/!NotAdopted/Skype/make_w32.bat | 5 + plugins/!NotAdopted/Skype/make_w64.bat | 6 + plugins/!NotAdopted/Skype/memlist.c | 248 + plugins/!NotAdopted/Skype/memlist.h | 43 + plugins/!NotAdopted/Skype/msglist.c | 86 + plugins/!NotAdopted/Skype/msglist.h | 15 + plugins/!NotAdopted/Skype/msgq.c | 90 + plugins/!NotAdopted/Skype/msgq.h | 64 + plugins/!NotAdopted/Skype/pthread.c | 70 + plugins/!NotAdopted/Skype/pthread.h | 26 + plugins/!NotAdopted/Skype/readme.txt | 47 + plugins/!NotAdopted/Skype/res/8060.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/Copy of online.ico | Bin 0 -> 1406 bytes plugins/!NotAdopted/Skype/res/DND.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/Invite.ico | Bin 0 -> 1886 bytes plugins/!NotAdopted/Skype/res/NA.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/add.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/add2.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/auth.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/away.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/call.bmp | Bin 0 -> 214 bytes plugins/!NotAdopted/Skype/res/call.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/chat.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/conference.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/error.ico | Bin 0 -> 9062 bytes plugins/!NotAdopted/Skype/res/hang_up.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/history.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/hold.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/import.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/invisible.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/message.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/occupied.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/offline.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/online.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/pause.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/phone.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/resume.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/search.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/skype.ico | Bin 0 -> 13270 bytes plugins/!NotAdopted/Skype/res/skypeout.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Skype/res/skyping.ico | Bin 0 -> 2038 bytes plugins/!NotAdopted/Skype/resource.h | 124 + plugins/!NotAdopted/Skype/skype.c | 3465 +++++++ plugins/!NotAdopted/Skype/skype.h | 188 + plugins/!NotAdopted/Skype/skypeapi.c | 1699 ++++ plugins/!NotAdopted/Skype/skypeapi.h | 69 + plugins/!NotAdopted/Skype/skypeopt.c | 969 ++ plugins/!NotAdopted/Skype/skypeopt.h | 49 + plugins/!NotAdopted/Skype/skypeprofile.c | 145 + plugins/!NotAdopted/Skype/skypeprofile.h | 33 + plugins/!NotAdopted/Skype/skypeproxy.h | 7 + plugins/!NotAdopted/Skype/skypeproxy/skypeproxy.c | 651 ++ plugins/!NotAdopted/Skype/skypeproxy/skypeproxy.h | 36 + plugins/!NotAdopted/Skype/skypesvc.c | 188 + plugins/!NotAdopted/Skype/skypesvc.h | 24 + plugins/!NotAdopted/Skype/utf8.c | 334 + plugins/!NotAdopted/Skype/utf8.h | 47 + plugins/!NotAdopted/Skype/util.c | 57 + plugins/!NotAdopted/Skype/util.h | 7 + plugins/!NotAdopted/Skype/voiceservice.c | 156 + plugins/!NotAdopted/Skype/voiceservice.h | 18 + .../!NotAdopted/SmartAutoAway/AggressiveOptimize.h | 166 + plugins/!NotAdopted/SmartAutoAway/aa_utils.cpp | 396 + plugins/!NotAdopted/SmartAutoAway/autoaway.cpp | 662 ++ plugins/!NotAdopted/SmartAutoAway/dlgproc.cpp | 281 + plugins/!NotAdopted/SmartAutoAway/globals.cpp | 113 + plugins/!NotAdopted/SmartAutoAway/globals.h | 349 + plugins/!NotAdopted/SmartAutoAway/here.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/SmartAutoAway/idle.cpp | 374 + plugins/!NotAdopted/SmartAutoAway/idleMenu.cpp | 147 + plugins/!NotAdopted/SmartAutoAway/idleMessages.cpp | 282 + plugins/!NotAdopted/SmartAutoAway/long.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/SmartAutoAway/reconnect.cpp | 328 + plugins/!NotAdopted/SmartAutoAway/reconnect.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/SmartAutoAway/resource.h | 77 + plugins/!NotAdopted/SmartAutoAway/saa-res.rc | 238 + plugins/!NotAdopted/SmartAutoAway/saa.cpp | 130 + plugins/!NotAdopted/SmartAutoAway/saa.dsp | 291 + plugins/!NotAdopted/SmartAutoAway/saa.dsw | 41 + plugins/!NotAdopted/SmartAutoAway/saa.h | 1 + plugins/!NotAdopted/SmartAutoAway/saamain.cpp | 415 + plugins/!NotAdopted/SmartAutoAway/saani.c | 85 + plugins/!NotAdopted/SmartAutoAway/saani.dsp | 107 + plugins/!NotAdopted/SmartAutoAway/short.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/SmartAutoAway/version.txt | 7 + .../SmartAutoReplier/ActionsHandler.cpp | 31 + .../!NotAdopted/SmartAutoReplier/ActionsHandler.h | 30 + .../SmartAutoReplier/AggressiveOptimize.h | 59 + .../!NotAdopted/SmartAutoReplier/Crc32Static.cpp | 139 + plugins/!NotAdopted/SmartAutoReplier/Crc32Static.h | 33 + plugins/!NotAdopted/SmartAutoReplier/CrushLog.cpp | 165 + plugins/!NotAdopted/SmartAutoReplier/CrushLog.h | 54 + .../SmartAutoReplier/GUI/AddRuleDlg.cpp | 219 + .../!NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.h | 67 + .../SmartAutoReplier/GUI/EditReplyDlg.cpp | 88 + .../SmartAutoReplier/GUI/EditReplyDlg.h | 55 + .../SmartAutoReplier/GUI/OptionsDlg.cpp | 528 + .../!NotAdopted/SmartAutoReplier/GUI/OptionsDlg.h | 119 + .../SmartAutoReplier/GUI/SelectUserDlg.cpp | 109 + .../SmartAutoReplier/GUI/SelectUserDlg.h | 58 + .../SmartAutoReplier/GUI/SettingsDlgHolder.cpp | 207 + .../SmartAutoReplier/GUI/SettingsDlgHolder.h | 69 + .../SmartAutoReplier/Interfaces/ISettings.h | 34 + .../SmartAutoReplier/Interfaces/ISingletone.h | 35 + plugins/!NotAdopted/SmartAutoReplier/LuaBridge.cpp | 127 + plugins/!NotAdopted/SmartAutoReplier/LuaBridge.h | 96 + plugins/!NotAdopted/SmartAutoReplier/LuaScript.cpp | 215 + plugins/!NotAdopted/SmartAutoReplier/LuaScript.h | 68 + .../SmartAutoReplier/MessagesHandler.cpp | 469 + .../!NotAdopted/SmartAutoReplier/MessagesHandler.h | 72 + .../SmartAutoReplier/ModeMessHandler.cpp | 119 + .../!NotAdopted/SmartAutoReplier/ModeMessHandler.h | 34 + plugins/!NotAdopted/SmartAutoReplier/RuleItem.h | 47 + .../!NotAdopted/SmartAutoReplier/RulesStorage.cpp | 536 + .../!NotAdopted/SmartAutoReplier/RulesStorage.h | 63 + plugins/!NotAdopted/SmartAutoReplier/SAR.cpp | 462 + plugins/!NotAdopted/SmartAutoReplier/SAR.rc | 274 + plugins/!NotAdopted/SmartAutoReplier/SAR.vcxproj | 189 + .../SmartAutoReplier/SAR.vcxproj.filters | 77 + .../!NotAdopted/SmartAutoReplier/SarLuaScript.cpp | 358 + .../!NotAdopted/SmartAutoReplier/SarLuaScript.h | 57 + .../!NotAdopted/SmartAutoReplier/ScriptsReader.cpp | 175 + .../!NotAdopted/SmartAutoReplier/ScriptsReader.h | 57 + .../SmartAutoReplier/SettingsHandler.cpp | 204 + .../!NotAdopted/SmartAutoReplier/SettingsHandler.h | 96 + plugins/!NotAdopted/SmartAutoReplier/comfunc.cpp | 74 + plugins/!NotAdopted/SmartAutoReplier/comfunc.h | 26 + plugins/!NotAdopted/SmartAutoReplier/comlogging.h | 42 + plugins/!NotAdopted/SmartAutoReplier/luainc.h | 31 + .../!NotAdopted/SmartAutoReplier/lualib/ReadMe.txt | 37 + plugins/!NotAdopted/SmartAutoReplier/lualib/lapi.c | 922 ++ plugins/!NotAdopted/SmartAutoReplier/lualib/lapi.h | 16 + .../!NotAdopted/SmartAutoReplier/lualib/lauxlib.c | 591 ++ .../!NotAdopted/SmartAutoReplier/lualib/lauxlib.h | 145 + .../!NotAdopted/SmartAutoReplier/lualib/lbaselib.c | 674 ++ .../!NotAdopted/SmartAutoReplier/lualib/lcode.c | 714 ++ .../!NotAdopted/SmartAutoReplier/lualib/lcode.h | 74 + .../!NotAdopted/SmartAutoReplier/lualib/ldblib.c | 299 + .../!NotAdopted/SmartAutoReplier/lualib/ldebug.c | 585 ++ .../!NotAdopted/SmartAutoReplier/lualib/ldebug.h | 31 + plugins/!NotAdopted/SmartAutoReplier/lualib/ldo.c | 458 + plugins/!NotAdopted/SmartAutoReplier/lualib/ldo.h | 60 + .../!NotAdopted/SmartAutoReplier/lualib/ldump.c | 170 + .../!NotAdopted/SmartAutoReplier/lualib/lfunc.c | 135 + .../!NotAdopted/SmartAutoReplier/lualib/lfunc.h | 25 + plugins/!NotAdopted/SmartAutoReplier/lualib/lgc.c | 493 + plugins/!NotAdopted/SmartAutoReplier/lualib/lgc.h | 25 + .../!NotAdopted/SmartAutoReplier/lualib/liolib.c | 750 ++ plugins/!NotAdopted/SmartAutoReplier/lualib/llex.c | 417 + plugins/!NotAdopted/SmartAutoReplier/lualib/llex.h | 75 + .../!NotAdopted/SmartAutoReplier/lualib/llimits.h | 185 + .../!NotAdopted/SmartAutoReplier/lualib/lmathlib.c | 246 + plugins/!NotAdopted/SmartAutoReplier/lualib/lmem.c | 91 + plugins/!NotAdopted/SmartAutoReplier/lualib/lmem.h | 44 + .../!NotAdopted/SmartAutoReplier/lualib/loadlib.c | 205 + .../!NotAdopted/SmartAutoReplier/lualib/lobject.c | 195 + .../!NotAdopted/SmartAutoReplier/lualib/lobject.h | 336 + .../!NotAdopted/SmartAutoReplier/lualib/lopcodes.c | 102 + .../!NotAdopted/SmartAutoReplier/lualib/lopcodes.h | 238 + .../!NotAdopted/SmartAutoReplier/lualib/lparser.c | 1329 +++ .../!NotAdopted/SmartAutoReplier/lualib/lparser.h | 71 + .../!NotAdopted/SmartAutoReplier/lualib/lstate.c | 220 + .../!NotAdopted/SmartAutoReplier/lualib/lstate.h | 195 + .../!NotAdopted/SmartAutoReplier/lualib/lstring.c | 102 + .../!NotAdopted/SmartAutoReplier/lualib/lstring.h | 33 + .../!NotAdopted/SmartAutoReplier/lualib/lstrlib.c | 770 ++ .../!NotAdopted/SmartAutoReplier/lualib/ltable.c | 509 + .../!NotAdopted/SmartAutoReplier/lualib/ltable.h | 31 + .../!NotAdopted/SmartAutoReplier/lualib/ltablib.c | 250 + .../!NotAdopted/SmartAutoReplier/lualib/ltests.c | 852 ++ plugins/!NotAdopted/SmartAutoReplier/lualib/ltm.c | 70 + plugins/!NotAdopted/SmartAutoReplier/lualib/ltm.h | 51 + plugins/!NotAdopted/SmartAutoReplier/lualib/lua.h | 391 + .../!NotAdopted/SmartAutoReplier/lualib/luainc.h | 12 + .../!NotAdopted/SmartAutoReplier/lualib/lualib.h | 56 + .../SmartAutoReplier/lualib/lualib.vcxproj | 138 + .../SmartAutoReplier/lualib/lualib.vcxproj.filters | 186 + .../!NotAdopted/SmartAutoReplier/lualib/lundump.c | 286 + .../!NotAdopted/SmartAutoReplier/lualib/lundump.h | 34 + plugins/!NotAdopted/SmartAutoReplier/lualib/lvm.c | 780 ++ plugins/!NotAdopted/SmartAutoReplier/lualib/lvm.h | 35 + plugins/!NotAdopted/SmartAutoReplier/lualib/lzio.c | 81 + plugins/!NotAdopted/SmartAutoReplier/lualib/lzio.h | 64 + .../SmartAutoReplier/lualib/targetver.h | 8 + plugins/!NotAdopted/SmartAutoReplier/resource.h | 52 + plugins/!NotAdopted/SmartAutoReplier/sar.ico | Bin 0 -> 318 bytes plugins/!NotAdopted/SmartAutoReplier/stdafx.cpp | 27 + plugins/!NotAdopted/SmartAutoReplier/stdafx.h | 74 + plugins/!NotAdopted/SmartAutoReplier/wtl/atlapp.h | 2035 ++++ .../!NotAdopted/SmartAutoReplier/wtl/atlcrack.h | 2384 +++++ .../!NotAdopted/SmartAutoReplier/wtl/atlctrls.h | 10041 +++++++++++++++++++ .../!NotAdopted/SmartAutoReplier/wtl/atlctrlw.h | 4157 ++++++++ .../!NotAdopted/SmartAutoReplier/wtl/atlctrlx.h | 5004 +++++++++ plugins/!NotAdopted/SmartAutoReplier/wtl/atlddx.h | 679 ++ plugins/!NotAdopted/SmartAutoReplier/wtl/atldlgs.h | 6403 ++++++++++++ plugins/!NotAdopted/SmartAutoReplier/wtl/atldwm.h | 461 + plugins/!NotAdopted/SmartAutoReplier/wtl/atlfind.h | 1032 ++ .../!NotAdopted/SmartAutoReplier/wtl/atlframe.h | 3688 +++++++ plugins/!NotAdopted/SmartAutoReplier/wtl/atlgdi.h | 3891 +++++++ plugins/!NotAdopted/SmartAutoReplier/wtl/atlmisc.h | 3817 +++++++ .../!NotAdopted/SmartAutoReplier/wtl/atlprint.h | 1109 ++ plugins/!NotAdopted/SmartAutoReplier/wtl/atlres.h | 263 + .../!NotAdopted/SmartAutoReplier/wtl/atlresce.h | 93 + .../!NotAdopted/SmartAutoReplier/wtl/atlribbon.h | 3446 +++++++ plugins/!NotAdopted/SmartAutoReplier/wtl/atlscrl.h | 2011 ++++ .../!NotAdopted/SmartAutoReplier/wtl/atlsplit.h | 917 ++ .../!NotAdopted/SmartAutoReplier/wtl/atltheme.h | 1218 +++ plugins/!NotAdopted/SmartAutoReplier/wtl/atluser.h | 1391 +++ .../!NotAdopted/SmartAutoReplier/wtl/atlwince.h | 2987 ++++++ plugins/!NotAdopted/SmartAutoReplier/wtl/atlwinx.h | 525 + plugins/!NotAdopted/Tlen/codec/gsm.h | 65 + plugins/!NotAdopted/Tlen/codec/gsm_codec.c | 283 + plugins/!NotAdopted/Tlen/codec/gsm_long.c | 183 + plugins/!NotAdopted/Tlen/codec/gsm_lpc.c | 208 + plugins/!NotAdopted/Tlen/codec/gsm_preprocess.c | 103 + plugins/!NotAdopted/Tlen/codec/gsm_rpe.c | 248 + plugins/!NotAdopted/Tlen/codec/gsm_short.c | 211 + plugins/!NotAdopted/Tlen/commons.h | 32 + plugins/!NotAdopted/Tlen/crypto/aes.c | 1336 +++ plugins/!NotAdopted/Tlen/crypto/bignum.c | 2097 ++++ plugins/!NotAdopted/Tlen/crypto/padlock.c | 162 + plugins/!NotAdopted/Tlen/crypto/polarssl/aes.h | 167 + plugins/!NotAdopted/Tlen/crypto/polarssl/bignum.h | 587 ++ plugins/!NotAdopted/Tlen/crypto/polarssl/bn_mul.h | 738 ++ plugins/!NotAdopted/Tlen/crypto/polarssl/config.h | 625 ++ plugins/!NotAdopted/Tlen/crypto/polarssl/padlock.h | 100 + plugins/!NotAdopted/Tlen/docs/InstallScript.xml | 27 + plugins/!NotAdopted/Tlen/docs/changelog_tlen.txt | 269 + plugins/!NotAdopted/Tlen/docs/gpl.txt | 340 + plugins/!NotAdopted/Tlen/docs/gpl_comment.txt | 20 + plugins/!NotAdopted/Tlen/docs/readme_tlen.txt | 60 + plugins/!NotAdopted/Tlen/docs/tlen-translation.txt | 153 + plugins/!NotAdopted/Tlen/icos/auth_grant.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Tlen/icos/auth_request.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Tlen/icos/groupchats.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Tlen/icos/image.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Tlen/icos/mail.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Tlen/icos/microphone.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Tlen/icos/speaker.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Tlen/icos/tlen.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Tlen/icos/tlenchats.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Tlen/icos/voicechat.ico | Bin 0 -> 2550 bytes plugins/!NotAdopted/Tlen/jabber.h | 438 + plugins/!NotAdopted/Tlen/jabber_iq.c | 114 + plugins/!NotAdopted/Tlen/jabber_iq.h | 61 + plugins/!NotAdopted/Tlen/jabber_iqid.c | 629 ++ plugins/!NotAdopted/Tlen/jabber_list.c | 314 + plugins/!NotAdopted/Tlen/jabber_list.h | 90 + plugins/!NotAdopted/Tlen/jabber_misc.c | 219 + plugins/!NotAdopted/Tlen/jabber_opt.c | 708 ++ plugins/!NotAdopted/Tlen/jabber_svc.c | 1300 +++ plugins/!NotAdopted/Tlen/jabber_thread.c | 1465 +++ plugins/!NotAdopted/Tlen/jabber_util.c | 635 ++ plugins/!NotAdopted/Tlen/jabber_ws.c | 159 + plugins/!NotAdopted/Tlen/jabber_xml.c | 568 ++ plugins/!NotAdopted/Tlen/jabber_xml.h | 78 + plugins/!NotAdopted/Tlen/resource.h | 147 + plugins/!NotAdopted/Tlen/tlen.c | 636 ++ plugins/!NotAdopted/Tlen/tlen.rc | 439 + plugins/!NotAdopted/Tlen/tlen_10.vcxproj | 928 ++ plugins/!NotAdopted/Tlen/tlen_advsearch.c | 113 + plugins/!NotAdopted/Tlen/tlen_avatar.c | 422 + plugins/!NotAdopted/Tlen/tlen_avatar.h | 34 + .../!NotAdopted/Tlen/tlen_czaty/AdminWindow.cpp | 490 + plugins/!NotAdopted/Tlen/tlen_czaty/AdminWindow.h | 63 + .../!NotAdopted/Tlen/tlen_czaty/ChatContainer.cpp | 480 + .../!NotAdopted/Tlen/tlen_czaty/ChatContainer.h | 100 + plugins/!NotAdopted/Tlen/tlen_czaty/ChatEvent.cpp | 174 + plugins/!NotAdopted/Tlen/tlen_czaty/ChatEvent.h | 60 + plugins/!NotAdopted/Tlen/tlen_czaty/ChatGroup.cpp | 99 + plugins/!NotAdopted/Tlen/tlen_czaty/ChatGroup.h | 55 + plugins/!NotAdopted/Tlen/tlen_czaty/ChatRoom.cpp | 68 + plugins/!NotAdopted/Tlen/tlen_czaty/ChatRoom.h | 51 + plugins/!NotAdopted/Tlen/tlen_czaty/ChatUser.cpp | 83 + plugins/!NotAdopted/Tlen/tlen_czaty/ChatUser.h | 49 + plugins/!NotAdopted/Tlen/tlen_czaty/ChatWindow.cpp | 2108 ++++ plugins/!NotAdopted/Tlen/tlen_czaty/ChatWindow.h | 196 + plugins/!NotAdopted/Tlen/tlen_czaty/FontList.cpp | 206 + plugins/!NotAdopted/Tlen/tlen_czaty/FontList.h | 90 + .../!NotAdopted/Tlen/tlen_czaty/HelperDialog.cpp | 589 ++ plugins/!NotAdopted/Tlen/tlen_czaty/HelperDialog.h | 95 + .../!NotAdopted/Tlen/tlen_czaty/ManagerWindow.cpp | 1067 ++ .../!NotAdopted/Tlen/tlen_czaty/ManagerWindow.h | 93 + plugins/!NotAdopted/Tlen/tlen_czaty/Options.cpp | 789 ++ plugins/!NotAdopted/Tlen/tlen_czaty/Options.h | 75 + plugins/!NotAdopted/Tlen/tlen_czaty/Utils.cpp | 138 + plugins/!NotAdopted/Tlen/tlen_czaty/Utils.h | 38 + plugins/!NotAdopted/Tlen/tlen_czaty/icos/admin.ico | Bin 0 -> 894 bytes .../Tlen/tlen_czaty/icos/administration.ico | Bin 0 -> 894 bytes plugins/!NotAdopted/Tlen/tlen_czaty/icos/blank.ico | Bin 0 -> 318 bytes plugins/!NotAdopted/Tlen/tlen_czaty/icos/bold.ico | Bin 0 -> 894 bytes plugins/!NotAdopted/Tlen/tlen_czaty/icos/chat.ico | Bin 0 -> 894 bytes .../!NotAdopted/Tlen/tlen_czaty/icos/delete.ico | Bin 0 -> 1406 bytes .../!NotAdopted/Tlen/tlen_czaty/icos/glowner.ico | Bin 0 -> 894 bytes .../!NotAdopted/Tlen/tlen_czaty/icos/invite.ico | Bin 0 -> 894 bytes .../!NotAdopted/Tlen/tlen_czaty/icos/italic.ico | Bin 0 -> 894 bytes .../!NotAdopted/Tlen/tlen_czaty/icos/message.ico | Bin 0 -> 1406 bytes plugins/!NotAdopted/Tlen/tlen_czaty/icos/next.ico | Bin 0 -> 894 bytes .../!NotAdopted/Tlen/tlen_czaty/icos/options.ico | Bin 0 -> 1406 bytes plugins/!NotAdopted/Tlen/tlen_czaty/icos/owner.ico | Bin 0 -> 894 bytes plugins/!NotAdopted/Tlen/tlen_czaty/icos/prev.ico | Bin 0 -> 894 bytes .../!NotAdopted/Tlen/tlen_czaty/icos/r_anon.ico | Bin 0 -> 894 bytes .../!NotAdopted/Tlen/tlen_czaty/icos/r_memb.ico | Bin 0 -> 894 bytes plugins/!NotAdopted/Tlen/tlen_czaty/icos/r_mod.ico | Bin 0 -> 894 bytes .../Tlen/tlen_czaty/icos/registered.ico | Bin 0 -> 894 bytes plugins/!NotAdopted/Tlen/tlen_czaty/icos/save.ico | Bin 0 -> 318 bytes .../!NotAdopted/Tlen/tlen_czaty/icos/search.ico | Bin 0 -> 1406 bytes .../!NotAdopted/Tlen/tlen_czaty/icos/sendmail.ico | Bin 0 -> 1406 bytes plugins/!NotAdopted/Tlen/tlen_czaty/icos/smile.ico | Bin 0 -> 1406 bytes .../!NotAdopted/Tlen/tlen_czaty/icos/tlenbig.ico | Bin 0 -> 2238 bytes .../!NotAdopted/Tlen/tlen_czaty/icos/tlensmall.ico | Bin 0 -> 894 bytes .../!NotAdopted/Tlen/tlen_czaty/icos/underline.ico | Bin 0 -> 894 bytes plugins/!NotAdopted/Tlen/tlen_czaty/mucc.cpp | 188 + plugins/!NotAdopted/Tlen/tlen_czaty/mucc.h | 106 + plugins/!NotAdopted/Tlen/tlen_czaty/mucc.rc | 579 ++ plugins/!NotAdopted/Tlen/tlen_czaty/mucc.vcxproj | 1245 +++ .../!NotAdopted/Tlen/tlen_czaty/mucc_services.cpp | 140 + .../!NotAdopted/Tlen/tlen_czaty/mucc_services.h | 35 + plugins/!NotAdopted/Tlen/tlen_czaty/resource.h | 218 + plugins/!NotAdopted/Tlen/tlen_file.c | 718 ++ plugins/!NotAdopted/Tlen/tlen_file.h | 34 + plugins/!NotAdopted/Tlen/tlen_muc.c | 1071 ++ plugins/!NotAdopted/Tlen/tlen_muc.h | 45 + plugins/!NotAdopted/Tlen/tlen_p2p_new.c | 361 + plugins/!NotAdopted/Tlen/tlen_p2p_old.c | 536 + plugins/!NotAdopted/Tlen/tlen_p2p_old.h | 66 + plugins/!NotAdopted/Tlen/tlen_picture.c | 320 + plugins/!NotAdopted/Tlen/tlen_picture.h | 41 + plugins/!NotAdopted/Tlen/tlen_presence.c | 314 + plugins/!NotAdopted/Tlen/tlen_presence.h | 37 + plugins/!NotAdopted/Tlen/tlen_userinfo.c | 335 + plugins/!NotAdopted/Tlen/tlen_voice.c | 1122 +++ plugins/!NotAdopted/Tlen/tlen_voice.h | 68 + plugins/!NotAdopted/XSoundNotify/DebugLogger.hpp | 91 + .../!NotAdopted/XSoundNotify/EventProcessor.cpp | 84 + plugins/!NotAdopted/XSoundNotify/EventProcessor.h | 27 + plugins/!NotAdopted/XSoundNotify/README | 1 + .../!NotAdopted/XSoundNotify/SettingsDialog.cpp | 124 + plugins/!NotAdopted/XSoundNotify/SettingsDialog.h | 60 + .../!NotAdopted/XSoundNotify/SoundNotifyData.cpp | 37 + plugins/!NotAdopted/XSoundNotify/SoundNotifyData.h | 33 + .../XSoundNotify/SoundNotifyDataStorage.cpp | 74 + .../XSoundNotify/SoundNotifyDataStorage.h | 34 + plugins/!NotAdopted/XSoundNotify/XSoundNotify.rc | Bin 0 -> 5494 bytes plugins/!NotAdopted/XSoundNotify/resource.h | Bin 0 -> 1556 bytes plugins/!NotAdopted/XSoundNotify/testplug.vcxproj | 167 + plugins/!NotAdopted/XSoundNotify/xsn_main.cpp | 122 + plugins/!NotAdopted/XSoundNotify/xsn_types.cpp | 32 + plugins/!NotAdopted/XSoundNotify/xsn_types.h | 33 + plugins/!NotAdopted/XSoundNotify/xsn_utils.cpp | 60 + plugins/!NotAdopted/XSoundNotify/xsn_utils.h | 18 + 1080 files changed, 170016 insertions(+), 170016 deletions(-) delete mode 100644 !Deprecated/NewAwaySysMod/AggressiveOptimize.h delete mode 100644 !Deprecated/NewAwaySysMod/AwayOpt.cpp delete mode 100644 !Deprecated/NewAwaySysMod/AwaySys.cpp delete mode 100644 !Deprecated/NewAwaySysMod/Client.cpp delete mode 100644 !Deprecated/NewAwaySysMod/Common.h delete mode 100644 !Deprecated/NewAwaySysMod/ContactList.cpp delete mode 100644 !Deprecated/NewAwaySysMod/ContactList.h delete mode 100644 !Deprecated/NewAwaySysMod/Images/Delete.ico delete mode 100644 !Deprecated/NewAwaySysMod/Images/DisableNotify.ico delete mode 100644 !Deprecated/NewAwaySysMod/Images/Dot.ico delete mode 100644 !Deprecated/NewAwaySysMod/Images/EnableNotify.ico delete mode 100644 !Deprecated/NewAwaySysMod/Images/Ignore.ico delete mode 100644 !Deprecated/NewAwaySysMod/Images/Indefinite.ico delete mode 100644 !Deprecated/NewAwaySysMod/Images/MsgIcon.ico delete mode 100644 !Deprecated/NewAwaySysMod/Images/NewCat.ico delete mode 100644 !Deprecated/NewAwaySysMod/Images/NewMessage.ico delete mode 100644 !Deprecated/NewAwaySysMod/Images/SaveAsNew.ico delete mode 100644 !Deprecated/NewAwaySysMod/Images/SaveMsg.ico delete mode 100644 !Deprecated/NewAwaySysMod/Images/Settings.ico delete mode 100644 !Deprecated/NewAwaySysMod/Images/Status_Other.ico delete mode 100644 !Deprecated/NewAwaySysMod/Images/Variables.ico delete mode 100644 !Deprecated/NewAwaySysMod/Images/off.bmp delete mode 100644 !Deprecated/NewAwaySysMod/Images/off.ico delete mode 100644 !Deprecated/NewAwaySysMod/Images/on.bmp delete mode 100644 !Deprecated/NewAwaySysMod/Images/on.ico delete mode 100644 !Deprecated/NewAwaySysMod/MsgEventAdded.cpp delete mode 100644 !Deprecated/NewAwaySysMod/MsgTree.cpp delete mode 100644 !Deprecated/NewAwaySysMod/MsgTree.h delete mode 100644 !Deprecated/NewAwaySysMod/NewAwaySys.rc delete mode 100644 !Deprecated/NewAwaySysMod/NewAwaySys.vcxproj delete mode 100644 !Deprecated/NewAwaySysMod/NewAwaySys.vcxproj.filters delete mode 100644 !Deprecated/NewAwaySysMod/Notification.cpp delete mode 100644 !Deprecated/NewAwaySysMod/Path.h delete mode 100644 !Deprecated/NewAwaySysMod/Properties.cpp delete mode 100644 !Deprecated/NewAwaySysMod/Properties.h delete mode 100644 !Deprecated/NewAwaySysMod/ReadAwayMsg.cpp delete mode 100644 !Deprecated/NewAwaySysMod/Services.cpp delete mode 100644 !Deprecated/NewAwaySysMod/Services.h delete mode 100644 !Deprecated/NewAwaySysMod/SetAwayMsg.cpp delete mode 100644 !Deprecated/NewAwaySysMod/VersionNo.h delete mode 100644 !Deprecated/NewAwaySysMod/copying.txt delete mode 100644 !Deprecated/NewAwaySysMod/nas_readme.txt delete mode 100644 !Deprecated/NewAwaySysMod/nas_translation.txt delete mode 100644 !Deprecated/NewAwaySysMod/newawaysysmod-translation.txt delete mode 100644 !Deprecated/NewAwaySysMod/resource.h delete mode 100644 !Deprecated/NewAwaySysMod/version.rc delete mode 100644 !NotAdopted/IMO2sProxy/Makefile delete mode 100644 !NotAdopted/IMO2sProxy/README.txt delete mode 100644 !NotAdopted/IMO2sProxy/bin/setupimo.bat delete mode 100644 !NotAdopted/IMO2sProxy/msvc/imoproxy.dsp delete mode 100644 !NotAdopted/IMO2sProxy/msvc/imoproxy.dsw delete mode 100644 !NotAdopted/IMO2sProxy/msvc/imoproxy.mak delete mode 100644 !NotAdopted/IMO2sProxy/msvc/imoskype.dsp delete mode 100644 !NotAdopted/IMO2sProxy/msvc/imoskype.dsw delete mode 100644 !NotAdopted/IMO2sProxy/msvc/imoskype.mak delete mode 100644 !NotAdopted/IMO2sProxy/msvc/make.bat delete mode 100644 !NotAdopted/IMO2sProxy/msvc/make_w32.bat delete mode 100644 !NotAdopted/IMO2sProxy/msvc/make_w64.bat delete mode 100644 !NotAdopted/IMO2sProxy/src/common/cJSON.c delete mode 100644 !NotAdopted/IMO2sProxy/src/common/cJSON.h delete mode 100644 !NotAdopted/IMO2sProxy/src/common/fifo.c delete mode 100644 !NotAdopted/IMO2sProxy/src/common/fifo.h delete mode 100644 !NotAdopted/IMO2sProxy/src/common/memlist.c delete mode 100644 !NotAdopted/IMO2sProxy/src/common/memlist.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/Makefile delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/buddylist.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/buddylist.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/callqueue.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/callqueue.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/crash.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/crash.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/imo2stest.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/main.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/miranda/imoproxy.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/miranda/io_layer_netlib.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.aps delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.rc delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/miranda/resource.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/miranda/sdk/m_updater.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/queue.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/queue.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/w32browser.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/w32browser.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imolib/Makefile delete mode 100644 !NotAdopted/IMO2sProxy/src/imolib/imo_request.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imolib/imo_request.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imolib/imo_skype.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imolib/imo_skype.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imolib/io_layer.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imolib/io_layer.h delete mode 100644 !NotAdopted/IMO2sProxy/src/imolib/io_layer_win32.c delete mode 100644 !NotAdopted/IMO2sProxy/src/imolib/skypetst.c delete mode 100644 !NotAdopted/IMO2sProxy/structure.txt delete mode 100644 !NotAdopted/NotesAndReminders/NotesReminders.vcxproj delete mode 100644 !NotAdopted/NotesAndReminders/NotesReminders.vcxproj.filters delete mode 100644 !NotAdopted/NotesAndReminders/docs/N&R - langpack.txt delete mode 100644 !NotAdopted/NotesAndReminders/docs/N&R - readme.txt delete mode 100644 !NotAdopted/NotesAndReminders/res/addremin.ico delete mode 100644 !NotAdopted/NotesAndReminders/res/bringfront.ico delete mode 100644 !NotAdopted/NotesAndReminders/res/captioni.ico delete mode 100644 !NotAdopted/NotesAndReminders/res/captionn.ico delete mode 100644 !NotAdopted/NotesAndReminders/res/deleteic.ico delete mode 100644 !NotAdopted/NotesAndReminders/res/deletere.ico delete mode 100644 !NotAdopted/NotesAndReminders/res/hidenote.ico delete mode 100644 !NotAdopted/NotesAndReminders/res/noteicon.ico delete mode 100644 !NotAdopted/NotesAndReminders/res/playsound.ico delete mode 100644 !NotAdopted/NotesAndReminders/res/reminder.ico delete mode 100644 !NotAdopted/NotesAndReminders/res/removeno.ico delete mode 100644 !NotAdopted/NotesAndReminders/res/resource.rc delete mode 100644 !NotAdopted/NotesAndReminders/res/showhide.ico delete mode 100644 !NotAdopted/NotesAndReminders/res/viewnotes.ico delete mode 100644 !NotAdopted/NotesAndReminders/res/viewremi.ico delete mode 100644 !NotAdopted/NotesAndReminders/src/globals.h delete mode 100644 !NotAdopted/NotesAndReminders/src/hotkeys.cpp delete mode 100644 !NotAdopted/NotesAndReminders/src/main.cpp delete mode 100644 !NotAdopted/NotesAndReminders/src/miscutils.cpp delete mode 100644 !NotAdopted/NotesAndReminders/src/miscutils.h delete mode 100644 !NotAdopted/NotesAndReminders/src/notes.cpp delete mode 100644 !NotAdopted/NotesAndReminders/src/options.cpp delete mode 100644 !NotAdopted/NotesAndReminders/src/reminders.cpp delete mode 100644 !NotAdopted/NotesAndReminders/src/resource.h delete mode 100644 !NotAdopted/SMS/!clear.bat delete mode 100644 !NotAdopted/SMS/AdditionalFunctions/BuffToLowerCase.h delete mode 100644 !NotAdopted/SMS/AdditionalFunctions/DebugFunctions.h delete mode 100644 !NotAdopted/SMS/AdditionalFunctions/InterlockedFunctions.h delete mode 100644 !NotAdopted/SMS/AdditionalFunctions/ListMT.h delete mode 100644 !NotAdopted/SMS/AdditionalFunctions/MemoryCompare.h delete mode 100644 !NotAdopted/SMS/AdditionalFunctions/MemoryFind.h delete mode 100644 !NotAdopted/SMS/AdditionalFunctions/MemoryFindByte.h delete mode 100644 !NotAdopted/SMS/SMS.def delete mode 100644 !NotAdopted/SMS/SMSConstans.h delete mode 100644 !NotAdopted/SMS/SMS_svc.cpp delete mode 100644 !NotAdopted/SMS/functions.cpp delete mode 100644 !NotAdopted/SMS/langpack_sms.txt delete mode 100644 !NotAdopted/SMS/main.cpp delete mode 100644 !NotAdopted/SMS/main.h delete mode 100644 !NotAdopted/SMS/options.cpp delete mode 100644 !NotAdopted/SMS/readme.txt delete mode 100644 !NotAdopted/SMS/receive.cpp delete mode 100644 !NotAdopted/SMS/recvdlg.cpp delete mode 100644 !NotAdopted/SMS/recvdlg.h delete mode 100644 !NotAdopted/SMS/res/SMSNOTSENT.ico delete mode 100644 !NotAdopted/SMS/res/SMSSENT.ico delete mode 100644 !NotAdopted/SMS/res/halftick.ico delete mode 100644 !NotAdopted/SMS/resource.h delete mode 100644 !NotAdopted/SMS/resource.rc delete mode 100644 !NotAdopted/SMS/send.cpp delete mode 100644 !NotAdopted/SMS/senddlg.cpp delete mode 100644 !NotAdopted/SMS/senddlg.h delete mode 100644 !NotAdopted/SMS/sms.dsp delete mode 100644 !NotAdopted/SMS/sms.dsw delete mode 100644 !NotAdopted/SMS/sms.opt delete mode 100644 !NotAdopted/SMS/sms.vcproj delete mode 100644 !NotAdopted/Skype/Skript1.aps delete mode 100644 !NotAdopted/Skype/Skript1.rc delete mode 100644 !NotAdopted/Skype/Skype_protocol.dsp delete mode 100644 !NotAdopted/Skype/Skype_protocol.dsw delete mode 100644 !NotAdopted/Skype/Skype_protocol.mak delete mode 100644 !NotAdopted/Skype/Skype_protocol.sln delete mode 100644 !NotAdopted/Skype/Skype_protocol.vcproj delete mode 100644 !NotAdopted/Skype/alogon.c delete mode 100644 !NotAdopted/Skype/alogon.h delete mode 100644 !NotAdopted/Skype/changelog.txt delete mode 100644 !NotAdopted/Skype/contacts.c delete mode 100644 !NotAdopted/Skype/contacts.h delete mode 100644 !NotAdopted/Skype/debug.c delete mode 100644 !NotAdopted/Skype/debug.h delete mode 100644 !NotAdopted/Skype/deploy.bat delete mode 100644 !NotAdopted/Skype/ezxml/ezxml.c delete mode 100644 !NotAdopted/Skype/ezxml/ezxml.h delete mode 100644 !NotAdopted/Skype/gchat.c delete mode 100644 !NotAdopted/Skype/gchat.h delete mode 100644 !NotAdopted/Skype/m_popup.h delete mode 100644 !NotAdopted/Skype/m_toptoolbar.h delete mode 100644 !NotAdopted/Skype/make.bat delete mode 100644 !NotAdopted/Skype/make_w32.bat delete mode 100644 !NotAdopted/Skype/make_w64.bat delete mode 100644 !NotAdopted/Skype/memlist.c delete mode 100644 !NotAdopted/Skype/memlist.h delete mode 100644 !NotAdopted/Skype/msglist.c delete mode 100644 !NotAdopted/Skype/msglist.h delete mode 100644 !NotAdopted/Skype/msgq.c delete mode 100644 !NotAdopted/Skype/msgq.h delete mode 100644 !NotAdopted/Skype/pthread.c delete mode 100644 !NotAdopted/Skype/pthread.h delete mode 100644 !NotAdopted/Skype/readme.txt delete mode 100644 !NotAdopted/Skype/res/8060.ico delete mode 100644 !NotAdopted/Skype/res/Copy of online.ico delete mode 100644 !NotAdopted/Skype/res/DND.ico delete mode 100644 !NotAdopted/Skype/res/Invite.ico delete mode 100644 !NotAdopted/Skype/res/NA.ico delete mode 100644 !NotAdopted/Skype/res/add.ico delete mode 100644 !NotAdopted/Skype/res/add2.ico delete mode 100644 !NotAdopted/Skype/res/auth.ico delete mode 100644 !NotAdopted/Skype/res/away.ico delete mode 100644 !NotAdopted/Skype/res/call.bmp delete mode 100644 !NotAdopted/Skype/res/call.ico delete mode 100644 !NotAdopted/Skype/res/chat.ico delete mode 100644 !NotAdopted/Skype/res/conference.ico delete mode 100644 !NotAdopted/Skype/res/error.ico delete mode 100644 !NotAdopted/Skype/res/hang_up.ico delete mode 100644 !NotAdopted/Skype/res/history.ico delete mode 100644 !NotAdopted/Skype/res/hold.ico delete mode 100644 !NotAdopted/Skype/res/import.ico delete mode 100644 !NotAdopted/Skype/res/invisible.ico delete mode 100644 !NotAdopted/Skype/res/message.ico delete mode 100644 !NotAdopted/Skype/res/occupied.ico delete mode 100644 !NotAdopted/Skype/res/offline.ico delete mode 100644 !NotAdopted/Skype/res/online.ico delete mode 100644 !NotAdopted/Skype/res/pause.ico delete mode 100644 !NotAdopted/Skype/res/phone.ico delete mode 100644 !NotAdopted/Skype/res/resume.ico delete mode 100644 !NotAdopted/Skype/res/search.ico delete mode 100644 !NotAdopted/Skype/res/skype.ico delete mode 100644 !NotAdopted/Skype/res/skypeout.ico delete mode 100644 !NotAdopted/Skype/res/skyping.ico delete mode 100644 !NotAdopted/Skype/resource.h delete mode 100644 !NotAdopted/Skype/skype.c delete mode 100644 !NotAdopted/Skype/skype.h delete mode 100644 !NotAdopted/Skype/skypeapi.c delete mode 100644 !NotAdopted/Skype/skypeapi.h delete mode 100644 !NotAdopted/Skype/skypeopt.c delete mode 100644 !NotAdopted/Skype/skypeopt.h delete mode 100644 !NotAdopted/Skype/skypeprofile.c delete mode 100644 !NotAdopted/Skype/skypeprofile.h delete mode 100644 !NotAdopted/Skype/skypeproxy.h delete mode 100644 !NotAdopted/Skype/skypeproxy/skypeproxy.c delete mode 100644 !NotAdopted/Skype/skypeproxy/skypeproxy.h delete mode 100644 !NotAdopted/Skype/skypesvc.c delete mode 100644 !NotAdopted/Skype/skypesvc.h delete mode 100644 !NotAdopted/Skype/utf8.c delete mode 100644 !NotAdopted/Skype/utf8.h delete mode 100644 !NotAdopted/Skype/util.c delete mode 100644 !NotAdopted/Skype/util.h delete mode 100644 !NotAdopted/Skype/voiceservice.c delete mode 100644 !NotAdopted/Skype/voiceservice.h delete mode 100644 !NotAdopted/SmartAutoAway/AggressiveOptimize.h delete mode 100644 !NotAdopted/SmartAutoAway/aa_utils.cpp delete mode 100644 !NotAdopted/SmartAutoAway/autoaway.cpp delete mode 100644 !NotAdopted/SmartAutoAway/dlgproc.cpp delete mode 100644 !NotAdopted/SmartAutoAway/globals.cpp delete mode 100644 !NotAdopted/SmartAutoAway/globals.h delete mode 100644 !NotAdopted/SmartAutoAway/here.ico delete mode 100644 !NotAdopted/SmartAutoAway/idle.cpp delete mode 100644 !NotAdopted/SmartAutoAway/idleMenu.cpp delete mode 100644 !NotAdopted/SmartAutoAway/idleMessages.cpp delete mode 100644 !NotAdopted/SmartAutoAway/long.ico delete mode 100644 !NotAdopted/SmartAutoAway/reconnect.cpp delete mode 100644 !NotAdopted/SmartAutoAway/reconnect.ico delete mode 100644 !NotAdopted/SmartAutoAway/resource.h delete mode 100644 !NotAdopted/SmartAutoAway/saa-res.rc delete mode 100644 !NotAdopted/SmartAutoAway/saa.cpp delete mode 100644 !NotAdopted/SmartAutoAway/saa.dsp delete mode 100644 !NotAdopted/SmartAutoAway/saa.dsw delete mode 100644 !NotAdopted/SmartAutoAway/saa.h delete mode 100644 !NotAdopted/SmartAutoAway/saamain.cpp delete mode 100644 !NotAdopted/SmartAutoAway/saani.c delete mode 100644 !NotAdopted/SmartAutoAway/saani.dsp delete mode 100644 !NotAdopted/SmartAutoAway/short.ico delete mode 100644 !NotAdopted/SmartAutoAway/version.txt delete mode 100644 !NotAdopted/SmartAutoReplier/ActionsHandler.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/ActionsHandler.h delete mode 100644 !NotAdopted/SmartAutoReplier/AggressiveOptimize.h delete mode 100644 !NotAdopted/SmartAutoReplier/Crc32Static.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/Crc32Static.h delete mode 100644 !NotAdopted/SmartAutoReplier/CrushLog.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/CrushLog.h delete mode 100644 !NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.h delete mode 100644 !NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.h delete mode 100644 !NotAdopted/SmartAutoReplier/GUI/OptionsDlg.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/GUI/OptionsDlg.h delete mode 100644 !NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.h delete mode 100644 !NotAdopted/SmartAutoReplier/GUI/SettingsDlgHolder.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/GUI/SettingsDlgHolder.h delete mode 100644 !NotAdopted/SmartAutoReplier/Interfaces/ISettings.h delete mode 100644 !NotAdopted/SmartAutoReplier/Interfaces/ISingletone.h delete mode 100644 !NotAdopted/SmartAutoReplier/LuaBridge.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/LuaBridge.h delete mode 100644 !NotAdopted/SmartAutoReplier/LuaScript.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/LuaScript.h delete mode 100644 !NotAdopted/SmartAutoReplier/MessagesHandler.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/MessagesHandler.h delete mode 100644 !NotAdopted/SmartAutoReplier/ModeMessHandler.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/ModeMessHandler.h delete mode 100644 !NotAdopted/SmartAutoReplier/RuleItem.h delete mode 100644 !NotAdopted/SmartAutoReplier/RulesStorage.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/RulesStorage.h delete mode 100644 !NotAdopted/SmartAutoReplier/SAR.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/SAR.rc delete mode 100644 !NotAdopted/SmartAutoReplier/SAR.vcxproj delete mode 100644 !NotAdopted/SmartAutoReplier/SAR.vcxproj.filters delete mode 100644 !NotAdopted/SmartAutoReplier/SarLuaScript.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/SarLuaScript.h delete mode 100644 !NotAdopted/SmartAutoReplier/ScriptsReader.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/ScriptsReader.h delete mode 100644 !NotAdopted/SmartAutoReplier/SettingsHandler.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/SettingsHandler.h delete mode 100644 !NotAdopted/SmartAutoReplier/comfunc.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/comfunc.h delete mode 100644 !NotAdopted/SmartAutoReplier/comlogging.h delete mode 100644 !NotAdopted/SmartAutoReplier/luainc.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/ReadMe.txt delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lapi.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lapi.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lauxlib.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lauxlib.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lbaselib.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lcode.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lcode.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/ldblib.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/ldebug.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/ldebug.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/ldo.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/ldo.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/ldump.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lfunc.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lfunc.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lgc.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lgc.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/liolib.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/llex.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/llex.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/llimits.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lmathlib.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lmem.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lmem.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/loadlib.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lobject.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lobject.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lopcodes.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lopcodes.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lparser.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lparser.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lstate.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lstate.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lstring.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lstring.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lstrlib.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/ltable.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/ltable.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/ltablib.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/ltests.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/ltm.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/ltm.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lua.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/luainc.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lualib.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lualib.vcxproj delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lualib.vcxproj.filters delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lundump.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lundump.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lvm.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lvm.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lzio.c delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/lzio.h delete mode 100644 !NotAdopted/SmartAutoReplier/lualib/targetver.h delete mode 100644 !NotAdopted/SmartAutoReplier/resource.h delete mode 100644 !NotAdopted/SmartAutoReplier/sar.ico delete mode 100644 !NotAdopted/SmartAutoReplier/stdafx.cpp delete mode 100644 !NotAdopted/SmartAutoReplier/stdafx.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlapp.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlcrack.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlctrls.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlctrlw.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlctrlx.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlddx.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atldlgs.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atldwm.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlfind.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlframe.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlgdi.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlmisc.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlprint.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlres.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlresce.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlribbon.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlscrl.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlsplit.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atltheme.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atluser.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlwince.h delete mode 100644 !NotAdopted/SmartAutoReplier/wtl/atlwinx.h delete mode 100644 !NotAdopted/Tlen/codec/gsm.h delete mode 100644 !NotAdopted/Tlen/codec/gsm_codec.c delete mode 100644 !NotAdopted/Tlen/codec/gsm_long.c delete mode 100644 !NotAdopted/Tlen/codec/gsm_lpc.c delete mode 100644 !NotAdopted/Tlen/codec/gsm_preprocess.c delete mode 100644 !NotAdopted/Tlen/codec/gsm_rpe.c delete mode 100644 !NotAdopted/Tlen/codec/gsm_short.c delete mode 100644 !NotAdopted/Tlen/commons.h delete mode 100644 !NotAdopted/Tlen/crypto/aes.c delete mode 100644 !NotAdopted/Tlen/crypto/bignum.c delete mode 100644 !NotAdopted/Tlen/crypto/padlock.c delete mode 100644 !NotAdopted/Tlen/crypto/polarssl/aes.h delete mode 100644 !NotAdopted/Tlen/crypto/polarssl/bignum.h delete mode 100644 !NotAdopted/Tlen/crypto/polarssl/bn_mul.h delete mode 100644 !NotAdopted/Tlen/crypto/polarssl/config.h delete mode 100644 !NotAdopted/Tlen/crypto/polarssl/padlock.h delete mode 100644 !NotAdopted/Tlen/docs/InstallScript.xml delete mode 100644 !NotAdopted/Tlen/docs/changelog_tlen.txt delete mode 100644 !NotAdopted/Tlen/docs/gpl.txt delete mode 100644 !NotAdopted/Tlen/docs/gpl_comment.txt delete mode 100644 !NotAdopted/Tlen/docs/readme_tlen.txt delete mode 100644 !NotAdopted/Tlen/docs/tlen-translation.txt delete mode 100644 !NotAdopted/Tlen/icos/auth_grant.ico delete mode 100644 !NotAdopted/Tlen/icos/auth_request.ico delete mode 100644 !NotAdopted/Tlen/icos/groupchats.ico delete mode 100644 !NotAdopted/Tlen/icos/image.ico delete mode 100644 !NotAdopted/Tlen/icos/mail.ico delete mode 100644 !NotAdopted/Tlen/icos/microphone.ico delete mode 100644 !NotAdopted/Tlen/icos/speaker.ico delete mode 100644 !NotAdopted/Tlen/icos/tlen.ico delete mode 100644 !NotAdopted/Tlen/icos/tlenchats.ico delete mode 100644 !NotAdopted/Tlen/icos/voicechat.ico delete mode 100644 !NotAdopted/Tlen/jabber.h delete mode 100644 !NotAdopted/Tlen/jabber_iq.c delete mode 100644 !NotAdopted/Tlen/jabber_iq.h delete mode 100644 !NotAdopted/Tlen/jabber_iqid.c delete mode 100644 !NotAdopted/Tlen/jabber_list.c delete mode 100644 !NotAdopted/Tlen/jabber_list.h delete mode 100644 !NotAdopted/Tlen/jabber_misc.c delete mode 100644 !NotAdopted/Tlen/jabber_opt.c delete mode 100644 !NotAdopted/Tlen/jabber_svc.c delete mode 100644 !NotAdopted/Tlen/jabber_thread.c delete mode 100644 !NotAdopted/Tlen/jabber_util.c delete mode 100644 !NotAdopted/Tlen/jabber_ws.c delete mode 100644 !NotAdopted/Tlen/jabber_xml.c delete mode 100644 !NotAdopted/Tlen/jabber_xml.h delete mode 100644 !NotAdopted/Tlen/resource.h delete mode 100644 !NotAdopted/Tlen/tlen.c delete mode 100644 !NotAdopted/Tlen/tlen.rc delete mode 100644 !NotAdopted/Tlen/tlen_10.vcxproj delete mode 100644 !NotAdopted/Tlen/tlen_advsearch.c delete mode 100644 !NotAdopted/Tlen/tlen_avatar.c delete mode 100644 !NotAdopted/Tlen/tlen_avatar.h delete mode 100644 !NotAdopted/Tlen/tlen_czaty/AdminWindow.cpp delete mode 100644 !NotAdopted/Tlen/tlen_czaty/AdminWindow.h delete mode 100644 !NotAdopted/Tlen/tlen_czaty/ChatContainer.cpp delete mode 100644 !NotAdopted/Tlen/tlen_czaty/ChatContainer.h delete mode 100644 !NotAdopted/Tlen/tlen_czaty/ChatEvent.cpp delete mode 100644 !NotAdopted/Tlen/tlen_czaty/ChatEvent.h delete mode 100644 !NotAdopted/Tlen/tlen_czaty/ChatGroup.cpp delete mode 100644 !NotAdopted/Tlen/tlen_czaty/ChatGroup.h delete mode 100644 !NotAdopted/Tlen/tlen_czaty/ChatRoom.cpp delete mode 100644 !NotAdopted/Tlen/tlen_czaty/ChatRoom.h delete mode 100644 !NotAdopted/Tlen/tlen_czaty/ChatUser.cpp delete mode 100644 !NotAdopted/Tlen/tlen_czaty/ChatUser.h delete mode 100644 !NotAdopted/Tlen/tlen_czaty/ChatWindow.cpp delete mode 100644 !NotAdopted/Tlen/tlen_czaty/ChatWindow.h delete mode 100644 !NotAdopted/Tlen/tlen_czaty/FontList.cpp delete mode 100644 !NotAdopted/Tlen/tlen_czaty/FontList.h delete mode 100644 !NotAdopted/Tlen/tlen_czaty/HelperDialog.cpp delete mode 100644 !NotAdopted/Tlen/tlen_czaty/HelperDialog.h delete mode 100644 !NotAdopted/Tlen/tlen_czaty/ManagerWindow.cpp delete mode 100644 !NotAdopted/Tlen/tlen_czaty/ManagerWindow.h delete mode 100644 !NotAdopted/Tlen/tlen_czaty/Options.cpp delete mode 100644 !NotAdopted/Tlen/tlen_czaty/Options.h delete mode 100644 !NotAdopted/Tlen/tlen_czaty/Utils.cpp delete mode 100644 !NotAdopted/Tlen/tlen_czaty/Utils.h delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/admin.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/administration.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/blank.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/bold.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/chat.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/delete.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/glowner.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/invite.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/italic.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/message.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/next.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/options.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/owner.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/prev.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/r_anon.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/r_memb.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/r_mod.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/registered.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/save.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/search.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/sendmail.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/smile.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/tlenbig.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/tlensmall.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/icos/underline.ico delete mode 100644 !NotAdopted/Tlen/tlen_czaty/mucc.cpp delete mode 100644 !NotAdopted/Tlen/tlen_czaty/mucc.h delete mode 100644 !NotAdopted/Tlen/tlen_czaty/mucc.rc delete mode 100644 !NotAdopted/Tlen/tlen_czaty/mucc.vcxproj delete mode 100644 !NotAdopted/Tlen/tlen_czaty/mucc_services.cpp delete mode 100644 !NotAdopted/Tlen/tlen_czaty/mucc_services.h delete mode 100644 !NotAdopted/Tlen/tlen_czaty/resource.h delete mode 100644 !NotAdopted/Tlen/tlen_file.c delete mode 100644 !NotAdopted/Tlen/tlen_file.h delete mode 100644 !NotAdopted/Tlen/tlen_muc.c delete mode 100644 !NotAdopted/Tlen/tlen_muc.h delete mode 100644 !NotAdopted/Tlen/tlen_p2p_new.c delete mode 100644 !NotAdopted/Tlen/tlen_p2p_old.c delete mode 100644 !NotAdopted/Tlen/tlen_p2p_old.h delete mode 100644 !NotAdopted/Tlen/tlen_picture.c delete mode 100644 !NotAdopted/Tlen/tlen_picture.h delete mode 100644 !NotAdopted/Tlen/tlen_presence.c delete mode 100644 !NotAdopted/Tlen/tlen_presence.h delete mode 100644 !NotAdopted/Tlen/tlen_userinfo.c delete mode 100644 !NotAdopted/Tlen/tlen_voice.c delete mode 100644 !NotAdopted/Tlen/tlen_voice.h delete mode 100644 !NotAdopted/XSoundNotify/DebugLogger.hpp delete mode 100644 !NotAdopted/XSoundNotify/EventProcessor.cpp delete mode 100644 !NotAdopted/XSoundNotify/EventProcessor.h delete mode 100644 !NotAdopted/XSoundNotify/README delete mode 100644 !NotAdopted/XSoundNotify/SettingsDialog.cpp delete mode 100644 !NotAdopted/XSoundNotify/SettingsDialog.h delete mode 100644 !NotAdopted/XSoundNotify/SoundNotifyData.cpp delete mode 100644 !NotAdopted/XSoundNotify/SoundNotifyData.h delete mode 100644 !NotAdopted/XSoundNotify/SoundNotifyDataStorage.cpp delete mode 100644 !NotAdopted/XSoundNotify/SoundNotifyDataStorage.h delete mode 100644 !NotAdopted/XSoundNotify/XSoundNotify.rc delete mode 100644 !NotAdopted/XSoundNotify/resource.h delete mode 100644 !NotAdopted/XSoundNotify/testplug.vcxproj delete mode 100644 !NotAdopted/XSoundNotify/xsn_main.cpp delete mode 100644 !NotAdopted/XSoundNotify/xsn_types.cpp delete mode 100644 !NotAdopted/XSoundNotify/xsn_types.h delete mode 100644 !NotAdopted/XSoundNotify/xsn_utils.cpp delete mode 100644 !NotAdopted/XSoundNotify/xsn_utils.h create mode 100644 plugins/!Deprecated/NewAwaySysMod/AggressiveOptimize.h create mode 100644 plugins/!Deprecated/NewAwaySysMod/AwayOpt.cpp create mode 100644 plugins/!Deprecated/NewAwaySysMod/AwaySys.cpp create mode 100644 plugins/!Deprecated/NewAwaySysMod/Client.cpp create mode 100644 plugins/!Deprecated/NewAwaySysMod/Common.h create mode 100644 plugins/!Deprecated/NewAwaySysMod/ContactList.cpp create mode 100644 plugins/!Deprecated/NewAwaySysMod/ContactList.h create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/Delete.ico create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/DisableNotify.ico create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/Dot.ico create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/EnableNotify.ico create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/Ignore.ico create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/Indefinite.ico create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/MsgIcon.ico create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/NewCat.ico create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/NewMessage.ico create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/SaveAsNew.ico create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/SaveMsg.ico create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/Settings.ico create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/Status_Other.ico create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/Variables.ico create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/off.bmp create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/off.ico create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/on.bmp create mode 100644 plugins/!Deprecated/NewAwaySysMod/Images/on.ico create mode 100644 plugins/!Deprecated/NewAwaySysMod/MsgEventAdded.cpp create mode 100644 plugins/!Deprecated/NewAwaySysMod/MsgTree.cpp create mode 100644 plugins/!Deprecated/NewAwaySysMod/MsgTree.h create mode 100644 plugins/!Deprecated/NewAwaySysMod/NewAwaySys.rc create mode 100644 plugins/!Deprecated/NewAwaySysMod/NewAwaySys.vcxproj create mode 100644 plugins/!Deprecated/NewAwaySysMod/NewAwaySys.vcxproj.filters create mode 100644 plugins/!Deprecated/NewAwaySysMod/Notification.cpp create mode 100644 plugins/!Deprecated/NewAwaySysMod/Path.h create mode 100644 plugins/!Deprecated/NewAwaySysMod/Properties.cpp create mode 100644 plugins/!Deprecated/NewAwaySysMod/Properties.h create mode 100644 plugins/!Deprecated/NewAwaySysMod/ReadAwayMsg.cpp create mode 100644 plugins/!Deprecated/NewAwaySysMod/Services.cpp create mode 100644 plugins/!Deprecated/NewAwaySysMod/Services.h create mode 100644 plugins/!Deprecated/NewAwaySysMod/SetAwayMsg.cpp create mode 100644 plugins/!Deprecated/NewAwaySysMod/VersionNo.h create mode 100644 plugins/!Deprecated/NewAwaySysMod/copying.txt create mode 100644 plugins/!Deprecated/NewAwaySysMod/nas_readme.txt create mode 100644 plugins/!Deprecated/NewAwaySysMod/nas_translation.txt create mode 100644 plugins/!Deprecated/NewAwaySysMod/newawaysysmod-translation.txt create mode 100644 plugins/!Deprecated/NewAwaySysMod/resource.h create mode 100644 plugins/!Deprecated/NewAwaySysMod/version.rc create mode 100644 plugins/!NotAdopted/IMO2sProxy/Makefile create mode 100644 plugins/!NotAdopted/IMO2sProxy/README.txt create mode 100644 plugins/!NotAdopted/IMO2sProxy/bin/setupimo.bat create mode 100644 plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsp create mode 100644 plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsw create mode 100644 plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.mak create mode 100644 plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.dsp create mode 100644 plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.dsw create mode 100644 plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.mak create mode 100644 plugins/!NotAdopted/IMO2sProxy/msvc/make.bat create mode 100644 plugins/!NotAdopted/IMO2sProxy/msvc/make_w32.bat create mode 100644 plugins/!NotAdopted/IMO2sProxy/msvc/make_w64.bat create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/common/cJSON.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/common/cJSON.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/common/fifo.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/common/fifo.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/common/memlist.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/common/memlist.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/Makefile create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/crash.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/crash.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2stest.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/main.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/imoproxy.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/io_layer_netlib.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.aps create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.rc create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/resource.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/sdk/m_updater.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/queue.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/queue.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imolib/Makefile create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_request.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_request.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer.h create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer_win32.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/src/imolib/skypetst.c create mode 100644 plugins/!NotAdopted/IMO2sProxy/structure.txt create mode 100644 plugins/!NotAdopted/NotesAndReminders/NotesReminders.vcxproj create mode 100644 plugins/!NotAdopted/NotesAndReminders/NotesReminders.vcxproj.filters create mode 100644 plugins/!NotAdopted/NotesAndReminders/docs/N&R - langpack.txt create mode 100644 plugins/!NotAdopted/NotesAndReminders/docs/N&R - readme.txt create mode 100644 plugins/!NotAdopted/NotesAndReminders/res/addremin.ico create mode 100644 plugins/!NotAdopted/NotesAndReminders/res/bringfront.ico create mode 100644 plugins/!NotAdopted/NotesAndReminders/res/captioni.ico create mode 100644 plugins/!NotAdopted/NotesAndReminders/res/captionn.ico create mode 100644 plugins/!NotAdopted/NotesAndReminders/res/deleteic.ico create mode 100644 plugins/!NotAdopted/NotesAndReminders/res/deletere.ico create mode 100644 plugins/!NotAdopted/NotesAndReminders/res/hidenote.ico create mode 100644 plugins/!NotAdopted/NotesAndReminders/res/noteicon.ico create mode 100644 plugins/!NotAdopted/NotesAndReminders/res/playsound.ico create mode 100644 plugins/!NotAdopted/NotesAndReminders/res/reminder.ico create mode 100644 plugins/!NotAdopted/NotesAndReminders/res/removeno.ico create mode 100644 plugins/!NotAdopted/NotesAndReminders/res/resource.rc create mode 100644 plugins/!NotAdopted/NotesAndReminders/res/showhide.ico create mode 100644 plugins/!NotAdopted/NotesAndReminders/res/viewnotes.ico create mode 100644 plugins/!NotAdopted/NotesAndReminders/res/viewremi.ico create mode 100644 plugins/!NotAdopted/NotesAndReminders/src/globals.h create mode 100644 plugins/!NotAdopted/NotesAndReminders/src/hotkeys.cpp create mode 100644 plugins/!NotAdopted/NotesAndReminders/src/main.cpp create mode 100644 plugins/!NotAdopted/NotesAndReminders/src/miscutils.cpp create mode 100644 plugins/!NotAdopted/NotesAndReminders/src/miscutils.h create mode 100644 plugins/!NotAdopted/NotesAndReminders/src/notes.cpp create mode 100644 plugins/!NotAdopted/NotesAndReminders/src/options.cpp create mode 100644 plugins/!NotAdopted/NotesAndReminders/src/reminders.cpp create mode 100644 plugins/!NotAdopted/NotesAndReminders/src/resource.h create mode 100644 plugins/!NotAdopted/SMS/!clear.bat create mode 100644 plugins/!NotAdopted/SMS/AdditionalFunctions/BuffToLowerCase.h create mode 100644 plugins/!NotAdopted/SMS/AdditionalFunctions/DebugFunctions.h create mode 100644 plugins/!NotAdopted/SMS/AdditionalFunctions/InterlockedFunctions.h create mode 100644 plugins/!NotAdopted/SMS/AdditionalFunctions/ListMT.h create mode 100644 plugins/!NotAdopted/SMS/AdditionalFunctions/MemoryCompare.h create mode 100644 plugins/!NotAdopted/SMS/AdditionalFunctions/MemoryFind.h create mode 100644 plugins/!NotAdopted/SMS/AdditionalFunctions/MemoryFindByte.h create mode 100644 plugins/!NotAdopted/SMS/SMS.def create mode 100644 plugins/!NotAdopted/SMS/SMSConstans.h create mode 100644 plugins/!NotAdopted/SMS/SMS_svc.cpp create mode 100644 plugins/!NotAdopted/SMS/functions.cpp create mode 100644 plugins/!NotAdopted/SMS/langpack_sms.txt create mode 100644 plugins/!NotAdopted/SMS/main.cpp create mode 100644 plugins/!NotAdopted/SMS/main.h create mode 100644 plugins/!NotAdopted/SMS/options.cpp create mode 100644 plugins/!NotAdopted/SMS/readme.txt create mode 100644 plugins/!NotAdopted/SMS/receive.cpp create mode 100644 plugins/!NotAdopted/SMS/recvdlg.cpp create mode 100644 plugins/!NotAdopted/SMS/recvdlg.h create mode 100644 plugins/!NotAdopted/SMS/res/SMSNOTSENT.ico create mode 100644 plugins/!NotAdopted/SMS/res/SMSSENT.ico create mode 100644 plugins/!NotAdopted/SMS/res/halftick.ico create mode 100644 plugins/!NotAdopted/SMS/resource.h create mode 100644 plugins/!NotAdopted/SMS/resource.rc create mode 100644 plugins/!NotAdopted/SMS/send.cpp create mode 100644 plugins/!NotAdopted/SMS/senddlg.cpp create mode 100644 plugins/!NotAdopted/SMS/senddlg.h create mode 100644 plugins/!NotAdopted/SMS/sms.dsp create mode 100644 plugins/!NotAdopted/SMS/sms.dsw create mode 100644 plugins/!NotAdopted/SMS/sms.opt create mode 100644 plugins/!NotAdopted/SMS/sms.vcproj create mode 100644 plugins/!NotAdopted/Skype/Skript1.aps create mode 100644 plugins/!NotAdopted/Skype/Skript1.rc create mode 100644 plugins/!NotAdopted/Skype/Skype_protocol.dsp create mode 100644 plugins/!NotAdopted/Skype/Skype_protocol.dsw create mode 100644 plugins/!NotAdopted/Skype/Skype_protocol.mak create mode 100644 plugins/!NotAdopted/Skype/Skype_protocol.sln create mode 100644 plugins/!NotAdopted/Skype/Skype_protocol.vcproj create mode 100644 plugins/!NotAdopted/Skype/alogon.c create mode 100644 plugins/!NotAdopted/Skype/alogon.h create mode 100644 plugins/!NotAdopted/Skype/changelog.txt create mode 100644 plugins/!NotAdopted/Skype/contacts.c create mode 100644 plugins/!NotAdopted/Skype/contacts.h create mode 100644 plugins/!NotAdopted/Skype/debug.c create mode 100644 plugins/!NotAdopted/Skype/debug.h create mode 100644 plugins/!NotAdopted/Skype/deploy.bat create mode 100644 plugins/!NotAdopted/Skype/ezxml/ezxml.c create mode 100644 plugins/!NotAdopted/Skype/ezxml/ezxml.h create mode 100644 plugins/!NotAdopted/Skype/gchat.c create mode 100644 plugins/!NotAdopted/Skype/gchat.h create mode 100644 plugins/!NotAdopted/Skype/m_popup.h create mode 100644 plugins/!NotAdopted/Skype/m_toptoolbar.h create mode 100644 plugins/!NotAdopted/Skype/make.bat create mode 100644 plugins/!NotAdopted/Skype/make_w32.bat create mode 100644 plugins/!NotAdopted/Skype/make_w64.bat create mode 100644 plugins/!NotAdopted/Skype/memlist.c create mode 100644 plugins/!NotAdopted/Skype/memlist.h create mode 100644 plugins/!NotAdopted/Skype/msglist.c create mode 100644 plugins/!NotAdopted/Skype/msglist.h create mode 100644 plugins/!NotAdopted/Skype/msgq.c create mode 100644 plugins/!NotAdopted/Skype/msgq.h create mode 100644 plugins/!NotAdopted/Skype/pthread.c create mode 100644 plugins/!NotAdopted/Skype/pthread.h create mode 100644 plugins/!NotAdopted/Skype/readme.txt create mode 100644 plugins/!NotAdopted/Skype/res/8060.ico create mode 100644 plugins/!NotAdopted/Skype/res/Copy of online.ico create mode 100644 plugins/!NotAdopted/Skype/res/DND.ico create mode 100644 plugins/!NotAdopted/Skype/res/Invite.ico create mode 100644 plugins/!NotAdopted/Skype/res/NA.ico create mode 100644 plugins/!NotAdopted/Skype/res/add.ico create mode 100644 plugins/!NotAdopted/Skype/res/add2.ico create mode 100644 plugins/!NotAdopted/Skype/res/auth.ico create mode 100644 plugins/!NotAdopted/Skype/res/away.ico create mode 100644 plugins/!NotAdopted/Skype/res/call.bmp create mode 100644 plugins/!NotAdopted/Skype/res/call.ico create mode 100644 plugins/!NotAdopted/Skype/res/chat.ico create mode 100644 plugins/!NotAdopted/Skype/res/conference.ico create mode 100644 plugins/!NotAdopted/Skype/res/error.ico create mode 100644 plugins/!NotAdopted/Skype/res/hang_up.ico create mode 100644 plugins/!NotAdopted/Skype/res/history.ico create mode 100644 plugins/!NotAdopted/Skype/res/hold.ico create mode 100644 plugins/!NotAdopted/Skype/res/import.ico create mode 100644 plugins/!NotAdopted/Skype/res/invisible.ico create mode 100644 plugins/!NotAdopted/Skype/res/message.ico create mode 100644 plugins/!NotAdopted/Skype/res/occupied.ico create mode 100644 plugins/!NotAdopted/Skype/res/offline.ico create mode 100644 plugins/!NotAdopted/Skype/res/online.ico create mode 100644 plugins/!NotAdopted/Skype/res/pause.ico create mode 100644 plugins/!NotAdopted/Skype/res/phone.ico create mode 100644 plugins/!NotAdopted/Skype/res/resume.ico create mode 100644 plugins/!NotAdopted/Skype/res/search.ico create mode 100644 plugins/!NotAdopted/Skype/res/skype.ico create mode 100644 plugins/!NotAdopted/Skype/res/skypeout.ico create mode 100644 plugins/!NotAdopted/Skype/res/skyping.ico create mode 100644 plugins/!NotAdopted/Skype/resource.h create mode 100644 plugins/!NotAdopted/Skype/skype.c create mode 100644 plugins/!NotAdopted/Skype/skype.h create mode 100644 plugins/!NotAdopted/Skype/skypeapi.c create mode 100644 plugins/!NotAdopted/Skype/skypeapi.h create mode 100644 plugins/!NotAdopted/Skype/skypeopt.c create mode 100644 plugins/!NotAdopted/Skype/skypeopt.h create mode 100644 plugins/!NotAdopted/Skype/skypeprofile.c create mode 100644 plugins/!NotAdopted/Skype/skypeprofile.h create mode 100644 plugins/!NotAdopted/Skype/skypeproxy.h create mode 100644 plugins/!NotAdopted/Skype/skypeproxy/skypeproxy.c create mode 100644 plugins/!NotAdopted/Skype/skypeproxy/skypeproxy.h create mode 100644 plugins/!NotAdopted/Skype/skypesvc.c create mode 100644 plugins/!NotAdopted/Skype/skypesvc.h create mode 100644 plugins/!NotAdopted/Skype/utf8.c create mode 100644 plugins/!NotAdopted/Skype/utf8.h create mode 100644 plugins/!NotAdopted/Skype/util.c create mode 100644 plugins/!NotAdopted/Skype/util.h create mode 100644 plugins/!NotAdopted/Skype/voiceservice.c create mode 100644 plugins/!NotAdopted/Skype/voiceservice.h create mode 100644 plugins/!NotAdopted/SmartAutoAway/AggressiveOptimize.h create mode 100644 plugins/!NotAdopted/SmartAutoAway/aa_utils.cpp create mode 100644 plugins/!NotAdopted/SmartAutoAway/autoaway.cpp create mode 100644 plugins/!NotAdopted/SmartAutoAway/dlgproc.cpp create mode 100644 plugins/!NotAdopted/SmartAutoAway/globals.cpp create mode 100644 plugins/!NotAdopted/SmartAutoAway/globals.h create mode 100644 plugins/!NotAdopted/SmartAutoAway/here.ico create mode 100644 plugins/!NotAdopted/SmartAutoAway/idle.cpp create mode 100644 plugins/!NotAdopted/SmartAutoAway/idleMenu.cpp create mode 100644 plugins/!NotAdopted/SmartAutoAway/idleMessages.cpp create mode 100644 plugins/!NotAdopted/SmartAutoAway/long.ico create mode 100644 plugins/!NotAdopted/SmartAutoAway/reconnect.cpp create mode 100644 plugins/!NotAdopted/SmartAutoAway/reconnect.ico create mode 100644 plugins/!NotAdopted/SmartAutoAway/resource.h create mode 100644 plugins/!NotAdopted/SmartAutoAway/saa-res.rc create mode 100644 plugins/!NotAdopted/SmartAutoAway/saa.cpp create mode 100644 plugins/!NotAdopted/SmartAutoAway/saa.dsp create mode 100644 plugins/!NotAdopted/SmartAutoAway/saa.dsw create mode 100644 plugins/!NotAdopted/SmartAutoAway/saa.h create mode 100644 plugins/!NotAdopted/SmartAutoAway/saamain.cpp create mode 100644 plugins/!NotAdopted/SmartAutoAway/saani.c create mode 100644 plugins/!NotAdopted/SmartAutoAway/saani.dsp create mode 100644 plugins/!NotAdopted/SmartAutoAway/short.ico create mode 100644 plugins/!NotAdopted/SmartAutoAway/version.txt create mode 100644 plugins/!NotAdopted/SmartAutoReplier/ActionsHandler.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/ActionsHandler.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/AggressiveOptimize.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/Crc32Static.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/Crc32Static.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/CrushLog.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/CrushLog.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/GUI/OptionsDlg.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/GUI/OptionsDlg.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/GUI/SettingsDlgHolder.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/GUI/SettingsDlgHolder.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/Interfaces/ISettings.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/Interfaces/ISingletone.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/LuaBridge.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/LuaBridge.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/LuaScript.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/LuaScript.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/MessagesHandler.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/MessagesHandler.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/ModeMessHandler.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/ModeMessHandler.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/RuleItem.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/RulesStorage.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/RulesStorage.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/SAR.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/SAR.rc create mode 100644 plugins/!NotAdopted/SmartAutoReplier/SAR.vcxproj create mode 100644 plugins/!NotAdopted/SmartAutoReplier/SAR.vcxproj.filters create mode 100644 plugins/!NotAdopted/SmartAutoReplier/SarLuaScript.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/SarLuaScript.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/ScriptsReader.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/ScriptsReader.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/SettingsHandler.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/SettingsHandler.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/comfunc.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/comfunc.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/comlogging.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/luainc.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/ReadMe.txt create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lapi.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lapi.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lauxlib.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lauxlib.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lbaselib.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lcode.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lcode.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/ldblib.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/ldebug.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/ldebug.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/ldo.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/ldo.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/ldump.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lfunc.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lfunc.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lgc.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lgc.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/liolib.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/llex.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/llex.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/llimits.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lmathlib.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lmem.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lmem.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/loadlib.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lobject.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lobject.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lopcodes.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lopcodes.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lparser.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lparser.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lstate.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lstate.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lstring.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lstring.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lstrlib.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/ltable.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/ltable.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/ltablib.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/ltests.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/ltm.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/ltm.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lua.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/luainc.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lualib.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lualib.vcxproj create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lualib.vcxproj.filters create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lundump.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lundump.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lvm.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lvm.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lzio.c create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/lzio.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/lualib/targetver.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/resource.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/sar.ico create mode 100644 plugins/!NotAdopted/SmartAutoReplier/stdafx.cpp create mode 100644 plugins/!NotAdopted/SmartAutoReplier/stdafx.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlapp.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlcrack.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlctrls.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlctrlw.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlctrlx.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlddx.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atldlgs.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atldwm.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlfind.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlframe.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlgdi.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlmisc.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlprint.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlres.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlresce.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlribbon.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlscrl.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlsplit.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atltheme.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atluser.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlwince.h create mode 100644 plugins/!NotAdopted/SmartAutoReplier/wtl/atlwinx.h create mode 100644 plugins/!NotAdopted/Tlen/codec/gsm.h create mode 100644 plugins/!NotAdopted/Tlen/codec/gsm_codec.c create mode 100644 plugins/!NotAdopted/Tlen/codec/gsm_long.c create mode 100644 plugins/!NotAdopted/Tlen/codec/gsm_lpc.c create mode 100644 plugins/!NotAdopted/Tlen/codec/gsm_preprocess.c create mode 100644 plugins/!NotAdopted/Tlen/codec/gsm_rpe.c create mode 100644 plugins/!NotAdopted/Tlen/codec/gsm_short.c create mode 100644 plugins/!NotAdopted/Tlen/commons.h create mode 100644 plugins/!NotAdopted/Tlen/crypto/aes.c create mode 100644 plugins/!NotAdopted/Tlen/crypto/bignum.c create mode 100644 plugins/!NotAdopted/Tlen/crypto/padlock.c create mode 100644 plugins/!NotAdopted/Tlen/crypto/polarssl/aes.h create mode 100644 plugins/!NotAdopted/Tlen/crypto/polarssl/bignum.h create mode 100644 plugins/!NotAdopted/Tlen/crypto/polarssl/bn_mul.h create mode 100644 plugins/!NotAdopted/Tlen/crypto/polarssl/config.h create mode 100644 plugins/!NotAdopted/Tlen/crypto/polarssl/padlock.h create mode 100644 plugins/!NotAdopted/Tlen/docs/InstallScript.xml create mode 100644 plugins/!NotAdopted/Tlen/docs/changelog_tlen.txt create mode 100644 plugins/!NotAdopted/Tlen/docs/gpl.txt create mode 100644 plugins/!NotAdopted/Tlen/docs/gpl_comment.txt create mode 100644 plugins/!NotAdopted/Tlen/docs/readme_tlen.txt create mode 100644 plugins/!NotAdopted/Tlen/docs/tlen-translation.txt create mode 100644 plugins/!NotAdopted/Tlen/icos/auth_grant.ico create mode 100644 plugins/!NotAdopted/Tlen/icos/auth_request.ico create mode 100644 plugins/!NotAdopted/Tlen/icos/groupchats.ico create mode 100644 plugins/!NotAdopted/Tlen/icos/image.ico create mode 100644 plugins/!NotAdopted/Tlen/icos/mail.ico create mode 100644 plugins/!NotAdopted/Tlen/icos/microphone.ico create mode 100644 plugins/!NotAdopted/Tlen/icos/speaker.ico create mode 100644 plugins/!NotAdopted/Tlen/icos/tlen.ico create mode 100644 plugins/!NotAdopted/Tlen/icos/tlenchats.ico create mode 100644 plugins/!NotAdopted/Tlen/icos/voicechat.ico create mode 100644 plugins/!NotAdopted/Tlen/jabber.h create mode 100644 plugins/!NotAdopted/Tlen/jabber_iq.c create mode 100644 plugins/!NotAdopted/Tlen/jabber_iq.h create mode 100644 plugins/!NotAdopted/Tlen/jabber_iqid.c create mode 100644 plugins/!NotAdopted/Tlen/jabber_list.c create mode 100644 plugins/!NotAdopted/Tlen/jabber_list.h create mode 100644 plugins/!NotAdopted/Tlen/jabber_misc.c create mode 100644 plugins/!NotAdopted/Tlen/jabber_opt.c create mode 100644 plugins/!NotAdopted/Tlen/jabber_svc.c create mode 100644 plugins/!NotAdopted/Tlen/jabber_thread.c create mode 100644 plugins/!NotAdopted/Tlen/jabber_util.c create mode 100644 plugins/!NotAdopted/Tlen/jabber_ws.c create mode 100644 plugins/!NotAdopted/Tlen/jabber_xml.c create mode 100644 plugins/!NotAdopted/Tlen/jabber_xml.h create mode 100644 plugins/!NotAdopted/Tlen/resource.h create mode 100644 plugins/!NotAdopted/Tlen/tlen.c create mode 100644 plugins/!NotAdopted/Tlen/tlen.rc create mode 100644 plugins/!NotAdopted/Tlen/tlen_10.vcxproj create mode 100644 plugins/!NotAdopted/Tlen/tlen_advsearch.c create mode 100644 plugins/!NotAdopted/Tlen/tlen_avatar.c create mode 100644 plugins/!NotAdopted/Tlen/tlen_avatar.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/AdminWindow.cpp create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/AdminWindow.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/ChatContainer.cpp create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/ChatContainer.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/ChatEvent.cpp create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/ChatEvent.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/ChatGroup.cpp create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/ChatGroup.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/ChatRoom.cpp create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/ChatRoom.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/ChatUser.cpp create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/ChatUser.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/ChatWindow.cpp create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/ChatWindow.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/FontList.cpp create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/FontList.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/HelperDialog.cpp create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/HelperDialog.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/ManagerWindow.cpp create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/ManagerWindow.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/Options.cpp create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/Options.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/Utils.cpp create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/Utils.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/admin.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/administration.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/blank.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/bold.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/chat.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/delete.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/glowner.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/invite.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/italic.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/message.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/next.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/options.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/owner.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/prev.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/r_anon.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/r_memb.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/r_mod.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/registered.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/save.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/search.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/sendmail.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/smile.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/tlenbig.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/tlensmall.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/icos/underline.ico create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/mucc.cpp create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/mucc.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/mucc.rc create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/mucc.vcxproj create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/mucc_services.cpp create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/mucc_services.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_czaty/resource.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_file.c create mode 100644 plugins/!NotAdopted/Tlen/tlen_file.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_muc.c create mode 100644 plugins/!NotAdopted/Tlen/tlen_muc.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_p2p_new.c create mode 100644 plugins/!NotAdopted/Tlen/tlen_p2p_old.c create mode 100644 plugins/!NotAdopted/Tlen/tlen_p2p_old.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_picture.c create mode 100644 plugins/!NotAdopted/Tlen/tlen_picture.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_presence.c create mode 100644 plugins/!NotAdopted/Tlen/tlen_presence.h create mode 100644 plugins/!NotAdopted/Tlen/tlen_userinfo.c create mode 100644 plugins/!NotAdopted/Tlen/tlen_voice.c create mode 100644 plugins/!NotAdopted/Tlen/tlen_voice.h create mode 100644 plugins/!NotAdopted/XSoundNotify/DebugLogger.hpp create mode 100644 plugins/!NotAdopted/XSoundNotify/EventProcessor.cpp create mode 100644 plugins/!NotAdopted/XSoundNotify/EventProcessor.h create mode 100644 plugins/!NotAdopted/XSoundNotify/README create mode 100644 plugins/!NotAdopted/XSoundNotify/SettingsDialog.cpp create mode 100644 plugins/!NotAdopted/XSoundNotify/SettingsDialog.h create mode 100644 plugins/!NotAdopted/XSoundNotify/SoundNotifyData.cpp create mode 100644 plugins/!NotAdopted/XSoundNotify/SoundNotifyData.h create mode 100644 plugins/!NotAdopted/XSoundNotify/SoundNotifyDataStorage.cpp create mode 100644 plugins/!NotAdopted/XSoundNotify/SoundNotifyDataStorage.h create mode 100644 plugins/!NotAdopted/XSoundNotify/XSoundNotify.rc create mode 100644 plugins/!NotAdopted/XSoundNotify/resource.h create mode 100644 plugins/!NotAdopted/XSoundNotify/testplug.vcxproj create mode 100644 plugins/!NotAdopted/XSoundNotify/xsn_main.cpp create mode 100644 plugins/!NotAdopted/XSoundNotify/xsn_types.cpp create mode 100644 plugins/!NotAdopted/XSoundNotify/xsn_types.h create mode 100644 plugins/!NotAdopted/XSoundNotify/xsn_utils.cpp create mode 100644 plugins/!NotAdopted/XSoundNotify/xsn_utils.h diff --git a/!Deprecated/NewAwaySysMod/AggressiveOptimize.h b/!Deprecated/NewAwaySysMod/AggressiveOptimize.h deleted file mode 100644 index 65cfa5b010..0000000000 --- a/!Deprecated/NewAwaySysMod/AggressiveOptimize.h +++ /dev/null @@ -1,169 +0,0 @@ - -////////////////////////////// -// Version 1.40 -// October 22nd, 2002 - .NET (VC7, _MSC_VER=1300) support! -// Version 1.30 -// Nov 24th, 2000 -// Version 1.20 -// Jun 9th, 2000 -// Version 1.10 -// Jan 23rd, 2000 -// Version 1.00 -// May 20th, 1999 -// Todd C. Wilson, Fresh Ground Software -// (todd@nopcode.com) -// This header file will kick in settings for Visual C++ 5 and 6 that will (usually) -// result in smaller exe's. -// The "trick" is to tell the compiler to not pad out the function calls; this is done -// by not using the /O1 or /O2 option - if you do, you implicitly use /Gy, which pads -// out each and every function call. In one single 500k dll, I managed to cut out 120k -// by this alone! -// The other two "tricks" are telling the Linker to merge all data-type segments together -// in the exe file. The relocation, read-only (constants) data, and code section (.text) -// sections can almost always be merged. Each section merged can save 4k in exe space, -// since each section is padded out to 4k chunks. This is very noticeable with smaller -// exes, since you could have only 700 bytes of data, 300 bytes of code, 94 bytes of -// strings - padded out, this could be 12k of runtime, for 1094 bytes of stuff! For larger -// programs, this is less overall, but can save at least 4k. -// Note that if you're using MFC static or some other 3rd party libs, you may get poor -// results with merging the readonly (.rdata) section - the exe may grow larger. -// To use this feature, define _MERGE_DATA_ in your project or before this header is used. -// With Visual C++ 5, the program uses a file alignment of 512 bytes, which results -// in a small exe. Under VC6, the program instead uses 4k, which is the same as the -// section size. The reason (from what I understand) is that 4k is the chunk size of -// the virtual memory manager, and that WinAlign (an end-user tuning tool for Win98) -// will re-align the programs on this boundary. The problem with this is that all of -// Microsoft's system exes and dlls are *NOT* tuned like this, and using 4k causes serious -// exe bloat. This is very noticeable for smaller programs. -// The "trick" for this is to use the undocumented FILEALIGN linker parm to change the -// padding from 4k to 1/2k, which results in a much smaller exe - anywhere from 20%-75% -// depending on the size. Note that this is the same as using /OPT:NOWIN98, which *is* -// a previously documented switch, but was left out of the docs for some reason in VC6 and -// all of the current MSDN's - see KB:Q235956 for more information. -// Microsoft does say that using the 4k alignment will "speed up process loading", -// but I've been unable to notice a difference, even on my P180, with a very large (4meg) exe. -// Please note, however, that this will probably not change the size of the COMPRESSED -// file (either in a .zip file or in an install archive), since this 4k is all zeroes and -// gets compressed away. -// Also, the /ALIGN:4096 switch will "magically" do the same thing, even though this is the -// default setting for this switch. Apparently this sets the same values as the above two -// switches do. We do not use this in this header, since it smacks of a bug and not a feature. -// Thanks to Michael Geary for some additional tips! -// -// Notes about using this header in .NET -// First off, VC7 does not allow a lot of the linker command options in pragma's. There is no -// honest or good reason why Microsoft decided to make this change, it just doesn't. -// So that is why there are a lot of <1300 #if's in the header. -// If you want to take full advantage of the VC7 linker options, you will need to do it on a -// PER PROJECT BASIS; you can no longer use a global header file like this to make it better. -// Items I strongly suggest putting in all your VC7 project linker options command line settings: -// /ignore:4078 /RELEASE -// Compiler options: -// /GL (Whole Program Optimization) -// If you're making an .EXE and not a .DLL, consider adding in: -// /GA (Optimize for Windows Application) -// Some items to consider using in your VC7 projects (not VC6): -// Link-time Code Generation - whole code optimization. Put this in your exe/dll project link settings. -// /LTCG:NOSTATUS -// The classic no-padding and no-bloat compiler C/C++ switch: -// /opt:nowin98 -// -// (C++ command line options: /GL /opt:nowin98 and /GA for .exe files) -// (Link command line options: /ignore:4078 /RELEASE /LTCG:NOSTATUS) -// -// Now, notes on using these options in VC7 vs VC6. -// VC6 consistently, for me, produces smaller code from C++ the exact same sources, -// with or without this header. On average, VC6 produces 5% smaller binaries compared -// to VC7 compiling the exact same project, *without* this header. With this header, VC6 -// will make a 13k file, while VC7 will make a 64k one. VC7 is just bloaty, pure and -// simple - all that managed/unmanaged C++ runtimes, and the CLR stuff must be getting -// in the way of code generation. However, template support is better, so there. -// Both VC6 and VC7 show the same end kind of end result savings - larger binary output -// will shave about 2% off, where as smaller projects (support DLL's, cpl's, -// activex controls, ATL libs, etc) get the best result, since the padding is usually -// more than the actual usable code. But again, VC7 does not compile down as small as VC6. -// -// The argument can be made that doing this is a waste of time, since the "zero bytes" -// will be compressed out in a zip file or install archive. Not really - it doesn't matter -// if the data is a string of zeroes or ones or 85858585 - it will still take room (20 bytes -// in a zip file, 29 bytes if only *4* of them 4k bytes are not the same) and time to -// compress that data and decompress it. Also, 20k of zeros is NOT 20k on disk - it's the -// size of the cluster slop- for Fat32 systems, 20k can be 32k, NTFS could make it 24k if you're -// just 1 byte over (round up). Most end users do not have the dual P4 Xeon systems with -// two gigs of RDram and a Raid 0+1 of Western Digital 120meg Special Editions that all -// worthy developers have (all six of us), so they will need any space and LOADING TIME -// savings they will need; taking an extra 32k or more out of your end user's 64megs of -// ram on Windows 98 is Not a Good Thing. -// -// Now, as a ADDED BONUS at NO EXTRA COST TO YOU! Under VC6, using the /merge:.text=.data -// pragma will cause the output file to be un-disassembleable! (is that a word?) At least, -// with the normal tools - WinDisam, DumpBin, and the like will not work. Try it - use the -// header, compile release, and then use DUMPBIN /DISASM filename.exe - no code! -// Thanks to Gлzim Pani for discovering this gem - for a full writeup on -// this issue and the ramifactions of it, visit www.nopcode.com for the Aggressive Optimize -// article. - -#ifndef _AGGRESSIVEOPTIMIZE_H_ -#define _AGGRESSIVEOPTIMIZE_H_ - -#pragma warning(disable:4711) - -#ifdef NDEBUG -// /Og (global optimizations), /Os (favor small code), /Oy (no frame pointers) -#pragma optimize("gsy",on) - -#if (_MSC_VER<1300) - #pragma comment(linker,"/RELEASE") -#endif - -// Note that merging the .rdata section will result in LARGER exe's if you using -// MFC (esp. static link). If this is desirable, define _MERGE_RDATA_ in your project. -/* DEP prevents the plugin from running when section merging is used. Had to disable it. */ -/* -#ifdef _MERGE_RDATA_ -#pragma comment(linker,"/merge:.rdata=.data") -#endif // _MERGE_RDATA_ - -#pragma comment(linker,"/merge:.text=.data") -#if (_MSC_VER<1300) - // In VC7, this causes problems with the relocation and data tables, so best to not merge them - #pragma comment(linker,"/merge:.reloc=.data") -#endif -*/ - -// Merging sections with different attributes causes a linker warning, so -// turn off the warning. From Michael Geary. Undocumented, as usual! -#if (_MSC_VER<1300) - // In VC7, you will need to put this in your project settings - #pragma comment(linker,"/ignore:4078") -#endif - -// With Visual C++ 5, you already get the 512-byte alignment, so you will only need -// it for VC6, and maybe later. -#if _MSC_VER >= 1000 - -// Option #1: use /filealign -// Totally undocumented! And if you set it lower than 512 bytes, the program crashes. -// Either leave at 0x200 or 0x1000 -//#pragma comment(linker,"/FILEALIGN:0x200") - -// Option #2: use /opt:nowin98 -// See KB:Q235956 or the READMEVC.htm in your VC directory for info on this one. -// This is our currently preferred option, since it is fully documented and unlikely -// to break in service packs and updates. -#if (_MSC_VER<1300) - // In VC7, you will need to put this in your project settings - #pragma comment(linker,"/opt:nowin98") -#else - -// Option #3: use /align:4096 -// A side effect of using the default align value is that it turns on the above switch. -// Does nothing under Vc7 that /opt:nowin98 doesn't already give you -// #pragma comment(linker,"/ALIGN:512") -#endif - -#endif // _MSC_VER >= 1000 - -#endif // NDEBUG - -#endif // _AGGRESSIVEOPTIMIZE_H_ diff --git a/!Deprecated/NewAwaySysMod/AwayOpt.cpp b/!Deprecated/NewAwaySysMod/AwayOpt.cpp deleted file mode 100644 index d40fb85b18..0000000000 --- a/!Deprecated/NewAwaySysMod/AwayOpt.cpp +++ /dev/null @@ -1,1711 +0,0 @@ -/* - New Away System - plugin for Miranda IM - Copyright (C) 2005-2007 Chervov Dmitry - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "Common.h" -#include "MsgTree.h" -#include "Properties.h" -#include "Path.h" -#include "m_button.h" -#include "m_clc.h" -#include "..\CommonLibs\Themes.h" -#include "..\CommonLibs\GroupCheckbox.h" -#include "..\CommonLibs\ThemedImageCheckbox.h" - -//NightFox -#include - -int g_Messages_RecentRootID, g_Messages_PredefinedRootID; -CIconList g_IconList; - - -void MySetPos(HWND hwndParent) -// Set window size and center its controls -{ - HWND hWndTab = FindWindowEx(GetParent(hwndParent), NULL, _T("SysTabControl32"), _T("")); - if (!hWndTab) - { - _ASSERT(0); - return; - } - RECT rcDlg; - GetClientRect(hWndTab, &rcDlg); - TabCtrl_AdjustRect(hWndTab, false, &rcDlg); - rcDlg.right -= rcDlg.left - 2; - rcDlg.bottom -= rcDlg.top; - rcDlg.top += 2; - if (hwndParent) - { - RECT OldSize; - GetClientRect(hwndParent, &OldSize); - MoveWindow(hwndParent, rcDlg.left, rcDlg.top, rcDlg.right, rcDlg.bottom, true); - int dx = (rcDlg.right - OldSize.right) >> 1; - int dy = (rcDlg.bottom - OldSize.bottom) >> 1; - HWND hCurWnd = GetWindow(hwndParent, GW_CHILD); - while (hCurWnd) - { - RECT CWOldPos; - GetWindowRect(hCurWnd, &CWOldPos); - POINT pt; - pt.x = CWOldPos.left; - pt.y = CWOldPos.top; - ScreenToClient(hwndParent, &pt); - SetWindowPos(hCurWnd, NULL, pt.x + dx, pt.y + dy, 0, 0, SWP_NOSIZE | SWP_NOZORDER); - hCurWnd = GetNextWindow(hCurWnd, GW_HWNDNEXT); - } - } -} - -// ================================================ Message options ================================================ - -COptPage g_MessagesOptPage(MOD_NAME, NULL); - -void EnableMessagesOptDlgControls(CMsgTree* MsgTree) -{ - int I; - int IsNotGroup = false; - int Selected = false; - CBaseTreeItem* TreeItem = MsgTree->GetSelection(); - if (TreeItem && !(TreeItem->Flags & TIF_ROOTITEM)) - { - IsNotGroup = !(TreeItem->Flags & TIF_GROUP); - Selected = true; - } - g_MessagesOptPage.Enable(IDC_MESSAGEDLG_DEL, Selected); - g_MessagesOptPage.Enable(IDC_MESSAGEDLG_MSGTITLE, Selected); - for (I = 0; I < g_MessagesOptPage.Items.GetSize(); I++) - { - if (g_MessagesOptPage.Items[I]->GetParam() == IDC_MESSAGEDLG_MSGTREE) - { - g_MessagesOptPage.Items[I]->Enable(IsNotGroup); - } - } - SendDlgItemMessage(g_MessagesOptPage.GetWnd(), IDC_MESSAGEDLG_MSGDATA, EM_SETREADONLY, !IsNotGroup, 0); - g_MessagesOptPage.MemToPage(true); -} - -static WNDPROC g_OrigDefStatusButtonMsgProc; - -static LRESULT CALLBACK DefStatusButtonSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - if (Msg == WM_LBUTTONUP && IsDlgButtonChecked(GetParent(hWnd), GetDlgCtrlID(hWnd))) - { - return 0; - } - return CallWindowProc(g_OrigDefStatusButtonMsgProc, hWnd, Msg, wParam, lParam); -} - - -INT_PTR CALLBACK MessagesOptDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static int ChangeLock = 0; - static CMsgTree* MsgTree = NULL; - static struct { - int DlgItem, Status, IconIndex; - } DefMsgDlgItems[] = { - IDC_MESSAGEDLG_DEF_ONL, ID_STATUS_ONLINE, ILI_PROTO_ONL, - IDC_MESSAGEDLG_DEF_AWAY, ID_STATUS_AWAY, ILI_PROTO_AWAY, - IDC_MESSAGEDLG_DEF_NA, ID_STATUS_NA, ILI_PROTO_NA, - IDC_MESSAGEDLG_DEF_OCC, ID_STATUS_OCCUPIED, ILI_PROTO_OCC, - IDC_MESSAGEDLG_DEF_DND, ID_STATUS_DND, ILI_PROTO_DND, - IDC_MESSAGEDLG_DEF_FFC, ID_STATUS_FREECHAT, ILI_PROTO_FFC, - IDC_MESSAGEDLG_DEF_INV, ID_STATUS_INVISIBLE, ILI_PROTO_INV, - IDC_MESSAGEDLG_DEF_OTP, ID_STATUS_ONTHEPHONE, ILI_PROTO_OTP, - IDC_MESSAGEDLG_DEF_OTL, ID_STATUS_OUTTOLUNCH, ILI_PROTO_OTL - }; - static struct { - int DlgItem, IconIndex; - TCHAR* Text; - } Buttons[] = { - IDC_MESSAGEDLG_NEWMSG, ILI_NEWMESSAGE, LPGENT("Create new message"), - IDC_MESSAGEDLG_NEWCAT, ILI_NEWCATEGORY, LPGENT("Create new category"), - IDC_MESSAGEDLG_DEL, ILI_DELETE, LPGENT("Delete"), - IDC_MESSAGEDLG_VARS, ILI_NOICON, LPGENT("Open Variables help dialog"), - }; - switch (msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - MySetPos(hwndDlg); - ChangeLock++; - g_MessagesOptPage.SetWnd(hwndDlg); - SendMessage(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTITLE), EM_LIMITTEXT, TREEITEMTITLE_MAXLEN, 0); - SendMessage(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGDATA), EM_LIMITTEXT, AWAY_MSGDATA_MAX, 0); - // init image buttons - int I; - for (I = 0; I < lengthof(Buttons); I++) - { - HWND hButton = GetDlgItem(hwndDlg, Buttons[I].DlgItem); - SendMessage(hButton, BUTTONADDTOOLTIP, (WPARAM)TranslateTS(Buttons[I].Text), BATF_TCHAR); - SendMessage(hButton, BUTTONSETASFLATBTN, TRUE, 0); - } - // now default status message buttons - for (I = 0; I < lengthof(DefMsgDlgItems); I++) - { - HWND hButton = GetDlgItem(hwndDlg, DefMsgDlgItems[I].DlgItem); - SendMessage(hButton, BUTTONADDTOOLTIP, CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, DefMsgDlgItems[I].Status, GSMDF_TCHAR), BATF_TCHAR); - SendMessage(hButton, BUTTONSETASPUSHBTN, 0, 0); - SendMessage(hButton, BUTTONSETASFLATBTN, TRUE, 0); - g_OrigDefStatusButtonMsgProc = (WNDPROC)SetWindowLongPtr(hButton, GWLP_WNDPROC, (LONG_PTR)DefStatusButtonSubclassProc); - } - SendMessage(hwndDlg, UM_ICONSCHANGED, 0, 0); - g_MessagesOptPage.DBToMemToPage(); - _ASSERT(!MsgTree); - MsgTree = new CMsgTree(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTREE)); - if (!MsgTree->SetSelection(MsgTree->GetDefMsg(ID_STATUS_AWAY), MTSS_BYID)) - { - MsgTree->SetSelection(g_Messages_PredefinedRootID, MTSS_BYID); - } - ChangeLock--; - return true; - } break; - case UM_ICONSCHANGED: - { - int I; - for (I = 0; I < lengthof(DefMsgDlgItems); I++) - { - SendDlgItemMessage(hwndDlg, DefMsgDlgItems[I].DlgItem, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[DefMsgDlgItems[I].IconIndex]); - } - for (I = 0; I < lengthof(Buttons); I++) - { - if (Buttons[I].IconIndex != ILI_NOICON) - { - SendDlgItemMessage(hwndDlg, Buttons[I].DlgItem, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[Buttons[I].IconIndex]); - } - } - my_variables_skin_helpbutton(hwndDlg, IDC_MESSAGEDLG_VARS); - } break; - case WM_NOTIFY: - { - switch (((NMHDR*)lParam)->code) - { - case PSN_APPLY: - { - HWND hTreeView = GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTREE); - HTREEITEM hSelectedItem = TreeView_GetSelection(hTreeView); - ChangeLock++; - TreeView_SelectItem(hTreeView, NULL); - TreeView_SelectItem(hTreeView, hSelectedItem); - ChangeLock--; - MsgTree->Save(); - return true; - } break; - } - if (((LPNMHDR)lParam)->idFrom == IDC_MESSAGEDLG_MSGTREE) - { - switch (((LPNMHDR)lParam)->code) - { - case MTN_SELCHANGED: - { - PNMMSGTREE pnm = (PNMMSGTREE)lParam; - int I; - if (pnm->ItemOld && !(pnm->ItemOld->Flags & (TIF_ROOTITEM | TIF_GROUP))) - { - TCString Msg; - GetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGDATA, Msg.GetBuffer(AWAY_MSGDATA_MAX), AWAY_MSGDATA_MAX); - Msg.ReleaseBuffer(); - if (((CTreeItem*)pnm->ItemOld)->User_Str1 != (const TCHAR*)Msg) - { - ((CTreeItem*)pnm->ItemOld)->User_Str1 = Msg; - MsgTree->SetModified(true); - } - } - if (pnm->ItemNew) - { - ChangeLock++; - if (!(pnm->ItemNew->Flags & TIF_ROOTITEM)) - { - SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGTITLE, pnm->ItemNew->Title); - SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGDATA, (pnm->ItemNew->Flags & TIF_GROUP) ? _T("") : ((CTreeItem*)pnm->ItemNew)->User_Str1); - } else - { - SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGTITLE, _T("")); - if (pnm->ItemNew->ID == g_Messages_RecentRootID) - { - SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGDATA, TranslateT("Your most recent status messages are placed in this category. It's not recommended to put your messages manually here, as they'll be replaced by your recent messages.")); - } else - { - _ASSERT(pnm->ItemNew->ID == g_Messages_PredefinedRootID); - SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGDATA, TranslateT("You can put your frequently used and favorite messages in this category.")); - } - } - for (I = 0; I < lengthof(DefMsgDlgItems); I++) - { - COptItem_Checkbox *Checkbox = (COptItem_Checkbox*)g_MessagesOptPage.Find(DefMsgDlgItems[I].DlgItem); - Checkbox->SetWndValue(g_MessagesOptPage.GetWnd(), MsgTree->GetDefMsg(DefMsgDlgItems[I].Status) == pnm->ItemNew->ID); - } - ChangeLock--; - } - EnableMessagesOptDlgControls(MsgTree); - return 0; - } break; - case MTN_DEFMSGCHANGED: - { - PNMMSGTREE pnm = (PNMMSGTREE)lParam; - if (!ChangeLock) - { - CBaseTreeItem* SelectedItem = MsgTree->GetSelection(); - _ASSERT(SelectedItem); - if ((pnm->ItemOld && pnm->ItemOld->ID == SelectedItem->ID) || (pnm->ItemNew && pnm->ItemNew->ID == SelectedItem->ID)) - { // SelectedItem contains the same info as one of ItemOld or ItemNew - so we'll just use SelectedItem and won't bother with identifying which of ItemOld or ItemNew is currently selected - int I; - for (I = 0; I < lengthof(DefMsgDlgItems); I++) - { - COptItem_Checkbox *Checkbox = (COptItem_Checkbox*)g_MessagesOptPage.Find(DefMsgDlgItems[I].DlgItem); - Checkbox->SetWndValue(g_MessagesOptPage.GetWnd(), MsgTree->GetDefMsg(DefMsgDlgItems[I].Status) == SelectedItem->ID); - } - } - } - if (!ChangeLock) - { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); - } - return 0; - } break; - case MTN_ITEMRENAMED: - { - PNMMSGTREE pnm = (PNMMSGTREE)lParam; - CBaseTreeItem* SelectedItem = MsgTree->GetSelection(); - _ASSERT(SelectedItem); - if (pnm->ItemNew->ID == SelectedItem->ID && !ChangeLock) - { - ChangeLock++; - SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGTITLE, pnm->ItemNew->Title); - ChangeLock--; - } - } // go through - case MTN_ENDDRAG: - case MTN_NEWCATEGORY: - case MTN_NEWMESSAGE: - case MTN_DELETEITEM: - case TVN_ITEMEXPANDED: - { - if (!ChangeLock) - { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); - } - return 0; - } break; - } - } - } break; - case WM_COMMAND: - { - switch (HIWORD(wParam)) - { - case BN_CLICKED: - { - switch (LOWORD(wParam)) - { - case IDC_MESSAGEDLG_DEF_ONL: - case IDC_MESSAGEDLG_DEF_AWAY: - case IDC_MESSAGEDLG_DEF_NA: - case IDC_MESSAGEDLG_DEF_OCC: - case IDC_MESSAGEDLG_DEF_DND: - case IDC_MESSAGEDLG_DEF_FFC: - case IDC_MESSAGEDLG_DEF_INV: - case IDC_MESSAGEDLG_DEF_OTP: - case IDC_MESSAGEDLG_DEF_OTL: - { - int I; - for (I = 0; I < lengthof(DefMsgDlgItems); I++) - { - if (LOWORD(wParam) == DefMsgDlgItems[I].DlgItem) - { - MsgTree->SetDefMsg(DefMsgDlgItems[I].Status, MsgTree->GetSelection()->ID); // PSM_CHANGED is sent here through MTN_DEFMSGCHANGED, so we don't need to send it once more - break; - } - } - } break; - case IDC_MESSAGEDLG_VARS: - { - my_variables_showhelp(hwndDlg, IDC_MESSAGEDLG_MSGDATA); - } break; - case IDC_MESSAGEDLG_DEL: - { - MsgTree->EnsureVisible(MsgTree->GetSelection()->hItem); - MsgTree->DeleteSelectedItem(); - } break; - case IDC_MESSAGEDLG_NEWCAT: - { - MsgTree->AddCategory(); - SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTITLE)); - } break; - case IDC_MESSAGEDLG_NEWMSG: - { - MsgTree->AddMessage(); - SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTITLE)); - } break; - } - } break; - case EN_CHANGE: - { - if (LOWORD(wParam) == IDC_MESSAGEDLG_MSGDATA || LOWORD(wParam) == IDC_MESSAGEDLG_MSGTITLE) - { - if (!ChangeLock) - { - if (LOWORD(wParam) == IDC_MESSAGEDLG_MSGTITLE) - { - CBaseTreeItem* TreeItem = MsgTree->GetSelection(); - if (TreeItem && !(TreeItem->Flags & TIF_ROOTITEM)) - { - GetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGTITLE, TreeItem->Title.GetBuffer(TREEITEMTITLE_MAXLEN), TREEITEMTITLE_MAXLEN); - TreeItem->Title.ReleaseBuffer(); - ChangeLock++; - MsgTree->UpdateItem(TreeItem->ID); - ChangeLock--; - } - } - MsgTree->SetModified(true); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); - } - } - } break; - } - } break; - case WM_DESTROY: - { - delete MsgTree; - MsgTree = NULL; - g_MessagesOptPage.SetWnd(NULL); - } break; - } - return 0; -} - -// ================================================ Main options ================================================ - - -COptPage g_MoreOptPage(MOD_NAME, NULL); - - -void EnableMoreOptDlgControls() -{ - g_MoreOptPage.Enable(IDC_MOREOPTDLG_PERSTATUSPERSONAL, g_MoreOptPage.GetWndValue(IDC_MOREOPTDLG_SAVEPERSONALMSGS)); - int Enabled = g_MoreOptPage.GetWndValue(IDC_MOREOPTDLG_RECENTMSGSCOUNT); - g_MoreOptPage.Enable(IDC_MOREOPTDLG_PERSTATUSMRM, Enabled); - g_MoreOptPage.Enable(IDC_MOREOPTDLG_USELASTMSG, Enabled); - g_MoreOptPage.Enable(IDC_MOREOPTDLG_USEDEFMSG, Enabled); - g_MoreOptPage.Enable(IDC_MOREOPTDLG_PERSTATUSPERSONAL, g_MoreOptPage.GetWndValue(IDC_MOREOPTDLG_SAVEPERSONALMSGS)); - g_MoreOptPage.Enable(IDC_MOREOPTDLG_UPDATEMSGSPERIOD, g_MoreOptPage.GetWndValue(IDC_MOREOPTDLG_UPDATEMSGS)); - InvalidateRect(GetDlgItem(g_MoreOptPage.GetWnd(), IDC_MOREOPTDLG_UPDATEMSGSPERIOD_SPIN), NULL, false); // update spin control - g_MoreOptPage.MemToPage(true); -} - - -INT_PTR CALLBACK MoreOptDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static int ChangeLock = 0; - static struct { - int DlgItem, Status, IconIndex; - } StatusButtons[] = { - IDC_MOREOPTDLG_DONTPOPDLG_ONL, ID_STATUS_ONLINE, ILI_PROTO_ONL, - IDC_MOREOPTDLG_DONTPOPDLG_AWAY, ID_STATUS_AWAY, ILI_PROTO_AWAY, - IDC_MOREOPTDLG_DONTPOPDLG_NA, ID_STATUS_NA, ILI_PROTO_NA, - IDC_MOREOPTDLG_DONTPOPDLG_OCC, ID_STATUS_OCCUPIED, ILI_PROTO_OCC, - IDC_MOREOPTDLG_DONTPOPDLG_DND, ID_STATUS_DND, ILI_PROTO_DND, - IDC_MOREOPTDLG_DONTPOPDLG_FFC, ID_STATUS_FREECHAT, ILI_PROTO_FFC, - IDC_MOREOPTDLG_DONTPOPDLG_INV, ID_STATUS_INVISIBLE, ILI_PROTO_INV, - IDC_MOREOPTDLG_DONTPOPDLG_OTP, ID_STATUS_ONTHEPHONE, ILI_PROTO_OTP, - IDC_MOREOPTDLG_DONTPOPDLG_OTL, ID_STATUS_OUTTOLUNCH, ILI_PROTO_OTL - }; - switch (msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - MySetPos(hwndDlg); - ChangeLock++; - g_MoreOptPage.SetWnd(hwndDlg); - SendDlgItemMessage(hwndDlg, IDC_MOREOPTDLG_WAITFORMSG, EM_LIMITTEXT, 4, 0); - SendDlgItemMessage(hwndDlg, IDC_MOREOPTDLG_RECENTMSGSCOUNT, EM_LIMITTEXT, 2, 0); - SendDlgItemMessage(hwndDlg, IDC_MOREOPTDLG_WAITFORMSG_SPIN, UDM_SETRANGE32, -1, 9999); - SendDlgItemMessage(hwndDlg, IDC_MOREOPTDLG_RECENTMSGSCOUNT_SPIN, UDM_SETRANGE32, 0, 99); - SendDlgItemMessage(hwndDlg, IDC_MOREOPTDLG_UPDATEMSGSPERIOD_SPIN, UDM_SETRANGE32, 30, 99999); - int I; - for (I = 0; I < lengthof(StatusButtons); I++) - { - HWND hButton = GetDlgItem(hwndDlg, StatusButtons[I].DlgItem); - SendMessage(hButton, BUTTONADDTOOLTIP, CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, StatusButtons[I].Status, GSMDF_TCHAR), BATF_TCHAR); - SendMessage(hButton, BUTTONSETASPUSHBTN, TRUE, 0); - SendMessage(hButton, BUTTONSETASFLATBTN, TRUE, 0); - } - SendMessage(hwndDlg, UM_ICONSCHANGED, 0, 0); - g_MoreOptPage.DBToMemToPage(); - EnableMoreOptDlgControls(); - ChangeLock--; - return true; - } break; - case UM_ICONSCHANGED: - { - int I; - for (I = 0; I < lengthof(StatusButtons); I++) - { - SendDlgItemMessage(hwndDlg, StatusButtons[I].DlgItem, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[StatusButtons[I].IconIndex]); - } - } break; - case WM_NOTIFY: - { - switch (((NMHDR*)lParam)->code) - { - case PSN_APPLY: - { - g_MoreOptPage.PageToMemToDB(); - InitUpdateMsgs(); - return true; - } break; - } - } break; - case WM_COMMAND: - { - switch (HIWORD(wParam)) - { - case BN_CLICKED: - { - switch (LOWORD(wParam)) - { - - case IDC_MOREOPTDLG_RESETPROTOMSGS: - case IDC_MOREOPTDLG_SAVEPERSONALMSGS: - case IDC_MOREOPTDLG_UPDATEMSGS: - { - EnableMoreOptDlgControls(); - } // go through - case IDC_MOREOPTDLG_PERSTATUSMRM: - case IDC_MOREOPTDLG_PERSTATUSPROTOMSGS: - case IDC_MOREOPTDLG_PERSTATUSPROTOSETTINGS: - case IDC_MOREOPTDLG_PERSTATUSPERSONAL: - case IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS: - case IDC_MOREOPTDLG_USEMENUITEM: - case IDC_MOREOPTDLG_MYNICKPERPROTO: - case IDC_MOREOPTDLG_USEDEFMSG: - case IDC_MOREOPTDLG_USELASTMSG: - case IDC_MOREOPTDLG_DONTPOPDLG_ONL: - case IDC_MOREOPTDLG_DONTPOPDLG_AWAY: - case IDC_MOREOPTDLG_DONTPOPDLG_NA: - case IDC_MOREOPTDLG_DONTPOPDLG_OCC: - case IDC_MOREOPTDLG_DONTPOPDLG_DND: - case IDC_MOREOPTDLG_DONTPOPDLG_FFC: - case IDC_MOREOPTDLG_DONTPOPDLG_INV: - case IDC_MOREOPTDLG_DONTPOPDLG_OTP: - case IDC_MOREOPTDLG_DONTPOPDLG_OTL: - { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); - return 0; - } break; - } - } break; - case EN_CHANGE: - { - if (!ChangeLock && g_MoreOptPage.GetWnd()) - { - if (LOWORD(wParam) == IDC_MOREOPTDLG_RECENTMSGSCOUNT) - { - EnableMoreOptDlgControls(); - } - SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); - } - } break; - } - } break; - case WM_DESTROY: - { - g_MoreOptPage.SetWnd(NULL); - } break; - } - return 0; -} - - -// ================================================ Autoreply options ================================================ - - -COptPage g_AutoreplyOptPage(MOD_NAME, NULL); - - -void EnableAutoreplyOptDlgControls() -{ - int I; - g_AutoreplyOptPage.PageToMem(); - int Autoreply = g_AutoreplyOptPage.GetValue(IDC_REPLYDLG_ENABLEREPLY); - - for (I = 0; I < g_AutoreplyOptPage.Items.GetSize(); I++) - { - switch (g_AutoreplyOptPage.Items[I]->GetParam()) - { - case IDC_REPLYDLG_ENABLEREPLY: - { - g_AutoreplyOptPage.Items[I]->Enable(Autoreply); - } break; - case IDC_REPLYDLG_SENDCOUNT: - { - g_AutoreplyOptPage.Items[I]->Enable(Autoreply && g_AutoreplyOptPage.GetValue(IDC_REPLYDLG_SENDCOUNT) > 0); - } break; - } - } - g_AutoreplyOptPage.MemToPage(true); - InvalidateRect(GetDlgItem(g_AutoreplyOptPage.GetWnd(), IDC_REPLYDLG_SENDCOUNT_SPIN), NULL, 0); // update spin control -} - -INT_PTR CALLBACK AutoreplyOptDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static int ChangeLock = 0; - static HWND hWndTooltips; - static HFONT s_hDrawFont; - static struct { - int DlgItem, Status, IconIndex; - } StatusButtons[] = { - IDC_REPLYDLG_DISABLE_ONL, ID_STATUS_ONLINE, ILI_PROTO_ONL, - IDC_REPLYDLG_DISABLE_AWAY, ID_STATUS_AWAY, ILI_PROTO_AWAY, - IDC_REPLYDLG_DISABLE_NA, ID_STATUS_NA, ILI_PROTO_NA, - IDC_REPLYDLG_DISABLE_OCC, ID_STATUS_OCCUPIED, ILI_PROTO_OCC, - IDC_REPLYDLG_DISABLE_DND, ID_STATUS_DND, ILI_PROTO_DND, - IDC_REPLYDLG_DISABLE_FFC, ID_STATUS_FREECHAT, ILI_PROTO_FFC, - IDC_REPLYDLG_DISABLE_INV, ID_STATUS_INVISIBLE, ILI_PROTO_INV, - IDC_REPLYDLG_DISABLE_OTP, ID_STATUS_ONTHEPHONE, ILI_PROTO_OTP, - IDC_REPLYDLG_DISABLE_OTL, ID_STATUS_OUTTOLUNCH, ILI_PROTO_OTL - }; - switch (msg) - { - case WM_INITDIALOG: - { - ChangeLock++; - TranslateDialogDefault(hwndDlg); - MySetPos(hwndDlg); - g_AutoreplyOptPage.SetWnd(hwndDlg); - - LOGFONT logFont; - HFONT hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_REPLYDLG_STATIC_DISABLEWHENSTATUS, WM_GETFONT, 0, 0); // try getting the font used by the control - if (!hFont) - { - hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); - } - GetObject(hFont, sizeof(logFont), &logFont); - logFont.lfWeight = FW_BOLD; - s_hDrawFont = CreateFontIndirect(&logFont); // recreate the font - SendDlgItemMessage(hwndDlg, IDC_REPLYDLG_STATIC_DISABLEWHENSTATUS, WM_SETFONT, (WPARAM)s_hDrawFont, true); - SendDlgItemMessage(hwndDlg, IDC_REPLYDLG_STATIC_FORMAT, WM_SETFONT, (WPARAM)s_hDrawFont, true); - - SendDlgItemMessage(hwndDlg, IDC_REPLYDLG_SENDCOUNT, EM_LIMITTEXT, 3, 0); - SendDlgItemMessage(hwndDlg, IDC_REPLYDLG_SENDCOUNT_SPIN, UDM_SETRANGE32, -1, 999); - - HWND hCombo = GetDlgItem(hwndDlg, IDC_REPLYDLG_ONLYIDLEREPLY_COMBO); - static struct { - TCHAR *Text; - int Meaning; - } IdleComboValues[] = { - LPGENT("Windows"), AUTOREPLY_IDLE_WINDOWS, - LPGENT("Miranda"), AUTOREPLY_IDLE_MIRANDA - }; - int I; - for (I = 0; I < lengthof(IdleComboValues); I++) - { - SendMessage(hCombo, CB_SETITEMDATA, SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)TranslateTS(IdleComboValues[I].Text)), IdleComboValues[I].Meaning); - } - - for (I = 0; I < lengthof(StatusButtons); I++) - { - HWND hButton = GetDlgItem(hwndDlg, StatusButtons[I].DlgItem); - SendMessage(hButton, BUTTONADDTOOLTIP, CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, StatusButtons[I].Status, GSMDF_TCHAR), BATF_TCHAR); - SendMessage(hButton, BUTTONSETASPUSHBTN, TRUE, 0); - SendMessage(hButton, BUTTONSETASFLATBTN, TRUE, 0); - } - HWND hButton = GetDlgItem(hwndDlg, IDC_REPLYDLG_VARS); - SendMessage(hButton, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Open Variables help dialog"), BATF_TCHAR); - SendMessage(hButton, BUTTONSETASFLATBTN, TRUE, 0); - MakeThemedImageCheckbox(GetDlgItem(hwndDlg, IDC_MOREOPTDLG_EVNTMSG)); - MakeThemedImageCheckbox(GetDlgItem(hwndDlg, IDC_MOREOPTDLG_EVNTURL)); - MakeThemedImageCheckbox(GetDlgItem(hwndDlg, IDC_MOREOPTDLG_EVNTFILE)); - SendMessage(hwndDlg, UM_ICONSCHANGED, 0, 0); - - // init tooltips - struct { - int DlgItemID; - TCHAR* Text; - } Tooltips[] = { - IDC_REPLYDLG_RESETCOUNTERWHENSAMEICON, LPGENT("When this checkbox is ticked, NewAwaySys counts \"send times\" starting from the last status message change, even if status mode didn't change.\nWhen the checkbox isn't ticked, \"send times\" are counted from last status mode change (i.e. disabled state is more restrictive)."), - IDC_MOREOPTDLG_EVNTMSG, LPGENT("Message"), - IDC_MOREOPTDLG_EVNTURL, LPGENT("URL"), - IDC_MOREOPTDLG_EVNTFILE, LPGENT("File") - }; - TOOLINFO ti = {0}; - hWndTooltips = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, _T(""), WS_POPUP | TTS_NOPREFIX, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL); - ti.cbSize = sizeof(ti); - ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS; - ti.hwnd = hwndDlg; - for (I = 0; I < lengthof(Tooltips); I++) - { - ti.uId = (UINT)GetDlgItem(hwndDlg, Tooltips[I].DlgItemID); - ti.lpszText = TranslateTS(Tooltips[I].Text); - SendMessage(hWndTooltips, TTM_ADDTOOL, 0, (LPARAM)&ti); - } - SendMessage(hWndTooltips, TTM_SETMAXTIPWIDTH, 0, 500); - SendMessage(hWndTooltips, TTM_SETDELAYTIME, TTDT_AUTOPOP, 32767); // tooltip hide time; looks like 32 seconds is the maximum - - g_AutoreplyOptPage.DBToMemToPage(); - EnableAutoreplyOptDlgControls(); - ChangeLock--; - MakeGroupCheckbox(GetDlgItem(hwndDlg, IDC_REPLYDLG_ENABLEREPLY)); - return true; - } break; - case UM_ICONSCHANGED: - { - int I; - for (I = 0; I < lengthof(StatusButtons); I++) - { - SendDlgItemMessage(hwndDlg, StatusButtons[I].DlgItem, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[StatusButtons[I].IconIndex]); - } - my_variables_skin_helpbutton(hwndDlg, IDC_REPLYDLG_VARS); - SendDlgItemMessage(hwndDlg, IDC_MOREOPTDLG_EVNTMSG, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[ILI_EVENT_MESSAGE]); - SendDlgItemMessage(hwndDlg, IDC_MOREOPTDLG_EVNTURL, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[ILI_EVENT_URL]); - SendDlgItemMessage(hwndDlg, IDC_MOREOPTDLG_EVNTFILE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[ILI_EVENT_FILE]); - } break; - case WM_NOTIFY: - { - switch (((NMHDR*)lParam)->code) - { - case PSN_APPLY: - { - g_AutoreplyOptPage.PageToMemToDB(); - //UpdateSOEButtons(); - return true; - } break; - } - } break; - case WM_COMMAND: - { - switch (HIWORD(wParam)) - { - case BN_CLICKED: - { - switch (LOWORD(wParam)) - { - case IDC_REPLYDLG_ENABLEREPLY: - { - EnableAutoreplyOptDlgControls(); - } // go through - case IDC_REPLYDLG_DONTSENDTOICQ: - case IDC_REPLYDLG_DONTREPLYINVISIBLE: - case IDC_REPLYDLG_ONLYCLOSEDDLGREPLY: - case IDC_REPLYDLG_ONLYIDLEREPLY: - case IDC_REPLYDLG_RESETCOUNTERWHENSAMEICON: - case IDC_REPLYDLG_EVENTMSG: - case IDC_REPLYDLG_EVENTURL: - case IDC_REPLYDLG_EVENTFILE: - case IDC_REPLYDLG_LOGREPLY: - case IDC_REPLYDLG_DISABLE_ONL: - case IDC_REPLYDLG_DISABLE_AWAY: - case IDC_REPLYDLG_DISABLE_NA: - case IDC_REPLYDLG_DISABLE_OCC: - case IDC_REPLYDLG_DISABLE_DND: - case IDC_REPLYDLG_DISABLE_FFC: - case IDC_REPLYDLG_DISABLE_INV: - case IDC_REPLYDLG_DISABLE_OTP: - case IDC_REPLYDLG_DISABLE_OTL: - { - if (!ChangeLock) - { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); - } - } break; - case IDC_REPLYDLG_VARS: - { - my_variables_showhelp(hwndDlg, IDC_REPLYDLG_PREFIX); - } break; - } - } break; - case EN_CHANGE: - { - if ((LOWORD(wParam) == IDC_REPLYDLG_SENDCOUNT) || (LOWORD(wParam) == IDC_REPLYDLG_PREFIX)) - { - if (!ChangeLock && g_AutoreplyOptPage.GetWnd()) - { - if (LOWORD(wParam) == IDC_REPLYDLG_SENDCOUNT) - { - EnableAutoreplyOptDlgControls(); - } - SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); - } - } - } break; - case CBN_SELCHANGE: - { - if (LOWORD(wParam) == IDC_REPLYDLG_ONLYIDLEREPLY_COMBO) - { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); - } - } break; - } - } break; - case WM_DESTROY: - { - g_AutoreplyOptPage.SetWnd(NULL); - if (s_hDrawFont) - { - DeleteObject(s_hDrawFont); - } - DestroyWindow(hWndTooltips); - } break; - } - return 0; -} -// ================================================ Modern options ============================================== - -INT_PTR CALLBACK MessagesModernOptDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static int ChangeLock = 0; - static CMsgTree* MsgTree = NULL; - static struct { - int DlgItem, Status, IconIndex; - } DefMsgDlgItems[] = { - IDC_MESSAGEDLG_DEF_ONL, ID_STATUS_ONLINE, ILI_PROTO_ONL, - IDC_MESSAGEDLG_DEF_AWAY, ID_STATUS_AWAY, ILI_PROTO_AWAY, - IDC_MESSAGEDLG_DEF_NA, ID_STATUS_NA, ILI_PROTO_NA, - IDC_MESSAGEDLG_DEF_OCC, ID_STATUS_OCCUPIED, ILI_PROTO_OCC, - IDC_MESSAGEDLG_DEF_DND, ID_STATUS_DND, ILI_PROTO_DND, - IDC_MESSAGEDLG_DEF_FFC, ID_STATUS_FREECHAT, ILI_PROTO_FFC, - IDC_MESSAGEDLG_DEF_INV, ID_STATUS_INVISIBLE, ILI_PROTO_INV, - IDC_MESSAGEDLG_DEF_OTP, ID_STATUS_ONTHEPHONE, ILI_PROTO_OTP, - IDC_MESSAGEDLG_DEF_OTL, ID_STATUS_OUTTOLUNCH, ILI_PROTO_OTL - }; - static struct { - int DlgItem, IconIndex; - TCHAR* Text; - } Buttons[] = { - IDC_MESSAGEDLG_NEWMSG, ILI_NEWMESSAGE, LPGENT("Create new message"), - IDC_MESSAGEDLG_NEWCAT, ILI_NEWCATEGORY, LPGENT("Create new category"), - IDC_MESSAGEDLG_DEL, ILI_DELETE, LPGENT("Delete"), - IDC_MESSAGEDLG_VARS, ILI_NOICON, LPGENT("Open Variables help dialog"), - }; - switch (msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - MySetPos(hwndDlg); - ChangeLock++; - g_MessagesOptPage.SetWnd(hwndDlg); - SendMessage(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTITLE), EM_LIMITTEXT, TREEITEMTITLE_MAXLEN, 0); - SendMessage(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGDATA), EM_LIMITTEXT, AWAY_MSGDATA_MAX, 0); - // init image buttons - int I; - for (I = 0; I < lengthof(Buttons); I++) - { - HWND hButton = GetDlgItem(hwndDlg, Buttons[I].DlgItem); - SendMessage(hButton, BUTTONADDTOOLTIP, (WPARAM)TranslateTS(Buttons[I].Text), BATF_TCHAR); - SendMessage(hButton, BUTTONSETASFLATBTN, TRUE, 0); - } - // now default status message buttons - for (I = 0; I < lengthof(DefMsgDlgItems); I++) - { - HWND hButton = GetDlgItem(hwndDlg, DefMsgDlgItems[I].DlgItem); - SendMessage(hButton, BUTTONADDTOOLTIP, CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, DefMsgDlgItems[I].Status, GSMDF_TCHAR), BATF_TCHAR); - SendMessage(hButton, BUTTONSETASPUSHBTN, TRUE, 0); - SendMessage(hButton, BUTTONSETASFLATBTN, TRUE, 0); - g_OrigDefStatusButtonMsgProc = (WNDPROC)SetWindowLongPtr(hButton, GWLP_WNDPROC, (LONG_PTR)DefStatusButtonSubclassProc); - } - SendMessage(hwndDlg, UM_ICONSCHANGED, 0, 0); - g_MessagesOptPage.DBToMemToPage(); - _ASSERT(!MsgTree); - MsgTree = new CMsgTree(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTREE)); - if (!MsgTree->SetSelection(MsgTree->GetDefMsg(ID_STATUS_AWAY), MTSS_BYID)) - { - MsgTree->SetSelection(g_Messages_PredefinedRootID, MTSS_BYID); - } - ChangeLock--; - //MakeGroupCheckbox(GetDlgItem(hwndDlg, IDC_REPLYDLG_ENABLEREPLY)); - return true; - } break; - case UM_ICONSCHANGED: - { - int I; - for (I = 0; I < lengthof(DefMsgDlgItems); I++) - { - SendDlgItemMessage(hwndDlg, DefMsgDlgItems[I].DlgItem, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[DefMsgDlgItems[I].IconIndex]); - } - for (I = 0; I < lengthof(Buttons); I++) - { - if (Buttons[I].IconIndex != ILI_NOICON) - { - SendDlgItemMessage(hwndDlg, Buttons[I].DlgItem, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[Buttons[I].IconIndex]); - } - } - my_variables_skin_helpbutton(hwndDlg, IDC_MESSAGEDLG_VARS); - } break; - case WM_NOTIFY: - { - switch (((NMHDR*)lParam)->code) - { - case PSN_APPLY: - { - HWND hTreeView = GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTREE); - HTREEITEM hSelectedItem = TreeView_GetSelection(hTreeView); - ChangeLock++; - TreeView_SelectItem(hTreeView, NULL); - TreeView_SelectItem(hTreeView, hSelectedItem); - ChangeLock--; - MsgTree->Save(); - return true; - } break; - } - if (((LPNMHDR)lParam)->idFrom == IDC_MESSAGEDLG_MSGTREE) - { - switch (((LPNMHDR)lParam)->code) - { - case MTN_SELCHANGED: - { - PNMMSGTREE pnm = (PNMMSGTREE)lParam; - int I; - if (pnm->ItemOld && !(pnm->ItemOld->Flags & (TIF_ROOTITEM | TIF_GROUP))) - { - TCString Msg; - GetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGDATA, Msg.GetBuffer(AWAY_MSGDATA_MAX), AWAY_MSGDATA_MAX); - Msg.ReleaseBuffer(); - if (((CTreeItem*)pnm->ItemOld)->User_Str1 != (const TCHAR*)Msg) - { - ((CTreeItem*)pnm->ItemOld)->User_Str1 = Msg; - MsgTree->SetModified(true); - } - } - if (pnm->ItemNew) - { - ChangeLock++; - if (!(pnm->ItemNew->Flags & TIF_ROOTITEM)) - { - SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGTITLE, pnm->ItemNew->Title); - SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGDATA, (pnm->ItemNew->Flags & TIF_GROUP) ? _T("") : ((CTreeItem*)pnm->ItemNew)->User_Str1); - } else - { - SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGTITLE, _T("")); - if (pnm->ItemNew->ID == g_Messages_RecentRootID) - { - SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGDATA, TranslateT("Your most recent status messages are placed in this category. It's not recommended to put your messages manually here, as they'll be replaced by your recent messages.")); - } else - { - _ASSERT(pnm->ItemNew->ID == g_Messages_PredefinedRootID); - SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGDATA, TranslateT("You can put your frequently used and favorite messages in this category.")); - } - } - for (I = 0; I < lengthof(DefMsgDlgItems); I++) - { - COptItem_Checkbox *Checkbox = (COptItem_Checkbox*)g_MessagesOptPage.Find(DefMsgDlgItems[I].DlgItem); - Checkbox->SetWndValue(g_MessagesOptPage.GetWnd(), MsgTree->GetDefMsg(DefMsgDlgItems[I].Status) == pnm->ItemNew->ID); - } - ChangeLock--; - } - EnableMessagesOptDlgControls(MsgTree); - return 0; - } break; - case MTN_DEFMSGCHANGED: - { - PNMMSGTREE pnm = (PNMMSGTREE)lParam; - if (!ChangeLock) - { - CBaseTreeItem* SelectedItem = MsgTree->GetSelection(); - _ASSERT(SelectedItem); - if ((pnm->ItemOld && pnm->ItemOld->ID == SelectedItem->ID) || (pnm->ItemNew && pnm->ItemNew->ID == SelectedItem->ID)) - { // SelectedItem contains the same info as one of ItemOld or ItemNew - so we'll just use SelectedItem and won't bother with identifying which of ItemOld or ItemNew is currently selected - int I; - for (I = 0; I < lengthof(DefMsgDlgItems); I++) - { - COptItem_Checkbox *Checkbox = (COptItem_Checkbox*)g_MessagesOptPage.Find(DefMsgDlgItems[I].DlgItem); - Checkbox->SetWndValue(g_MessagesOptPage.GetWnd(), MsgTree->GetDefMsg(DefMsgDlgItems[I].Status) == SelectedItem->ID); - } - } - } - if (!ChangeLock) - { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); - } - return 0; - } break; - case MTN_ITEMRENAMED: - { - PNMMSGTREE pnm = (PNMMSGTREE)lParam; - CBaseTreeItem* SelectedItem = MsgTree->GetSelection(); - _ASSERT(SelectedItem); - if (pnm->ItemNew->ID == SelectedItem->ID && !ChangeLock) - { - ChangeLock++; - SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGTITLE, pnm->ItemNew->Title); - ChangeLock--; - } - } // go through - case MTN_ENDDRAG: - case MTN_NEWCATEGORY: - case MTN_NEWMESSAGE: - case MTN_DELETEITEM: - case TVN_ITEMEXPANDED: - { - if (!ChangeLock) - { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); - } - return 0; - } break; - } - } - } break; - case WM_COMMAND: - { - switch (HIWORD(wParam)) - { - case BN_CLICKED: - { - - - switch (LOWORD(wParam)) - { - - case IDC_MESSAGEDLG_DEF_ONL: - case IDC_MESSAGEDLG_DEF_AWAY: - case IDC_MESSAGEDLG_DEF_NA: - case IDC_MESSAGEDLG_DEF_OCC: - case IDC_MESSAGEDLG_DEF_DND: - case IDC_MESSAGEDLG_DEF_FFC: - case IDC_MESSAGEDLG_DEF_INV: - case IDC_MESSAGEDLG_DEF_OTP: - case IDC_MESSAGEDLG_DEF_OTL: - { - int I; - for (I = 0; I < lengthof(DefMsgDlgItems); I++) - { - if (LOWORD(wParam) == DefMsgDlgItems[I].DlgItem) - { - MsgTree->SetDefMsg(DefMsgDlgItems[I].Status, MsgTree->GetSelection()->ID); // PSM_CHANGED is sent here through MTN_DEFMSGCHANGED, so we don't need to send it once more - break; - } - } - } break; - case IDC_MESSAGEDLG_VARS: - { - my_variables_showhelp(hwndDlg, IDC_MESSAGEDLG_MSGDATA); - } break; - case IDC_MESSAGEDLG_DEL: - { - MsgTree->EnsureVisible(MsgTree->GetSelection()->hItem); - MsgTree->DeleteSelectedItem(); - } break; - case IDC_MESSAGEDLG_NEWCAT: - { - MsgTree->AddCategory(); - SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTITLE)); - } break; - case IDC_MESSAGEDLG_NEWMSG: - { - MsgTree->AddMessage(); - SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTITLE)); - } break; - - //NightFox: - case IDC_LNK_AUTOAWAY: - { - OPENOPTIONSDIALOG ood = {0}; - ood.cbSize = sizeof(ood); - ood.pszPage = "Status"; - ood.pszTab = "Autoreply"; - //CallService( MS_OPT_OPENOPTIONS, 0, (LPARAM)&ood ); - CallService( MS_OPT_OPENOPTIONSPAGE, 0, (LPARAM)&ood ); - break; - } - - } - - - } break; - case EN_CHANGE: - { - if (LOWORD(wParam) == IDC_MESSAGEDLG_MSGDATA || LOWORD(wParam) == IDC_MESSAGEDLG_MSGTITLE) - { - if (!ChangeLock) - { - if (LOWORD(wParam) == IDC_MESSAGEDLG_MSGTITLE) - { - CBaseTreeItem* TreeItem = MsgTree->GetSelection(); - if (TreeItem && !(TreeItem->Flags & TIF_ROOTITEM)) - { - GetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGTITLE, TreeItem->Title.GetBuffer(TREEITEMTITLE_MAXLEN), TREEITEMTITLE_MAXLEN); - TreeItem->Title.ReleaseBuffer(); - ChangeLock++; - MsgTree->UpdateItem(TreeItem->ID); - ChangeLock--; - } - } - MsgTree->SetModified(true); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); - } - } - } break; - } - } break; - case WM_DESTROY: - { - delete MsgTree; - MsgTree = NULL; - g_MessagesOptPage.SetWnd(NULL); - } break; - } - return 0; -} - - - -// ================================================ Contact list ================================================ -// Based on the code from built-in Miranda ignore module - -#define UM_CONTACTSDLG_RESETLISTOPTIONS (WM_USER + 20) - -#define EXTRACOLUMNSCOUNT 3 -#define IGNORECOLUMN 2 -#define AUTOREPLYCOLUMN 1 -#define NOTIFYCOLUMN 0 - -#define EXTRAICON_DOT 0 -#define EXTRAICON_IGNORE 1 -#define EXTRAICON_AUTOREPLYON 2 -#define EXTRAICON_AUTOREPLYOFF 3 -//#define EXTRAICON_ENABLENOTIFY 4 -//#define EXTRAICON_DISABLENOTIFY 5 -//#define EXTRAICON_INDEFINITE 6 -#define EXTRAICON_INDEFINITE 4 - -#define VAL_INDEFINITE (-2) - -static WNDPROC g_OrigContactsProc; - -__inline int DBValueToIgnoreIcon(int Value) -{ - switch (Value) - { - case VAL_INDEFINITE: return EXTRAICON_INDEFINITE; - case 0: return EXTRAICON_DOT; - default: return EXTRAICON_IGNORE; - } -} - -__inline int IgnoreIconToDBValue(int Value) -{ - switch (Value) - { - case EXTRAICON_DOT: return 0; - case EXTRAICON_IGNORE: return 1; - default: return VAL_INDEFINITE; // EXTRAICON_INDEFINITE and 0xFF - } -} - -__inline int DBValueToOptReplyIcon(int Value) -{ - switch (Value) - { - case VAL_INDEFINITE: return EXTRAICON_INDEFINITE; - case VAL_USEDEFAULT: return EXTRAICON_DOT; - case 0: return EXTRAICON_AUTOREPLYOFF; - default: return EXTRAICON_AUTOREPLYON; - } -} - -__inline int ReplyIconToDBValue(int Value) -{ - switch (Value) - { - case EXTRAICON_DOT: return VAL_USEDEFAULT; - case EXTRAICON_AUTOREPLYOFF: return 0; - case EXTRAICON_AUTOREPLYON: return 1; - default: return VAL_INDEFINITE; // EXTRAICON_INDEFINITE and 0xFF - } -} -/* -__inline int DBValueToNotifyIcon(int Value) -{ - switch (Value) - { - case VAL_INDEFINITE: return EXTRAICON_INDEFINITE; - case VAL_USEDEFAULT: return EXTRAICON_DOT; - case 0: return EXTRAICON_DISABLENOTIFY; - default: return EXTRAICON_ENABLENOTIFY; - } -} - -__inline int NotifyIconToDBValue(int Value) -{ - switch (Value) - { - case EXTRAICON_DOT: return VAL_USEDEFAULT; - case EXTRAICON_DISABLENOTIFY: return 0; - case EXTRAICON_ENABLENOTIFY: return 1; - default: return VAL_INDEFINITE; // EXTRAICON_INDEFINITE and 0xFF - } -}*/ - -static void SetListGroupIcons(HWND hwndList, HANDLE hFirstItem, HANDLE hParentItem) -{ - int Icons[EXTRACOLUMNSCOUNT] = {0xFF, 0xFF, 0xFF}; - int I; - HANDLE hItem; - int FirstItemType = SendMessage(hwndList, CLM_GETITEMTYPE, (WPARAM)hFirstItem, 0); - hItem = (FirstItemType == CLCIT_GROUP) ? hFirstItem : (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hFirstItem); - while (hItem) - { - HANDLE hChildItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); - if (hChildItem) - { - SetListGroupIcons(hwndList, hChildItem, hItem); - } - for (I = 0; I < lengthof(Icons); I++) - { - int Icon = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(I, 0)); - if (Icons[I] == 0xFF) - { - Icons[I] = Icon; - } else if (Icon != 0xFF && Icons[I] != Icon) - { - Icons[I] = EXTRAICON_INDEFINITE; - } - } - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hItem); - } - hItem = (FirstItemType == CLCIT_CONTACT) ? hFirstItem : (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hFirstItem); - while (hItem) - { - for (I = 0; I < lengthof(Icons); I++) - { - int Icon = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(I, 0)); - if (Icons[I] == 0xFF) - { - Icons[I] = Icon; - } else if (Icon != 0xFF && Icons[I] != Icon) - { - Icons[I] = EXTRAICON_INDEFINITE; - } - } - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hItem); - } -// set icons - for (I = 0; I < lengthof(Icons); I++) - { - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hParentItem, MAKELPARAM(I, Icons[I])); - } -} - -static void SetAllChildIcons(HWND hwndList, HANDLE hFirstItem, int iColumn, int iImage) -{ - int typeOfFirst, iOldIcon; - HANDLE hItem, hChildItem; - typeOfFirst = SendMessage(hwndList, CLM_GETITEMTYPE, (WPARAM)hFirstItem, 0); - //check groups - if (typeOfFirst == CLCIT_GROUP) - { - hItem = hFirstItem; - } else - { - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hFirstItem); - } - while (hItem) - { - hChildItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); - if (hChildItem) - { - SetAllChildIcons(hwndList, hChildItem, iColumn, iImage); - } - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hItem); - } - //check contacts - if (typeOfFirst == CLCIT_CONTACT) - { - hItem = hFirstItem; - } else - { - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hFirstItem); - } - while (hItem) - { - iOldIcon = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, iColumn); - if (iOldIcon != 0xFF && iOldIcon != iImage) - { - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(iColumn, iImage)); - } - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hItem); - } -} - -static void SetIconsForColumn(HWND hwndList, HANDLE hItem, HANDLE hItemAll, int iColumn, int iImage) -{ - int itemType = SendMessage(hwndList, CLM_GETITEMTYPE, (WPARAM)hItem, 0); - switch (itemType) - { - case CLCIT_CONTACT: - { - int oldiImage = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, iColumn); - if (oldiImage != 0xFF && oldiImage != iImage) - { - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(iColumn, iImage)); - } - } break; - case CLCIT_INFO: - { - if (hItem == hItemAll) - { - SetAllChildIcons(hwndList, hItem, iColumn, iImage); - } else - { -// _ASSERT(hItem == hItemUnknown); - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(iColumn, iImage)); - } - } break; - case CLCIT_GROUP: - { - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); - if (hItem) - { - SetAllChildIcons(hwndList, hItem, iColumn, iImage); - } - } break; - } -} - -static void SaveItemState(HWND hwndList, HANDLE hContact, HANDLE hItem) -{ // hContact == INVALID_HANDLE_VALUE means that hItem is hItemUnknown - int Ignore = IgnoreIconToDBValue(SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(IGNORECOLUMN, 0))); - int Reply = ReplyIconToDBValue(SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(AUTOREPLYCOLUMN, 0))); -// int Notify = NotifyIconToDBValue(SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(NOTIFYCOLUMN, 0))); - if (Ignore != VAL_INDEFINITE) - { - CContactSettings(ID_STATUS_ONLINE, hContact).Ignore = Ignore; - } - if (Reply != VAL_INDEFINITE) - { - CContactSettings(ID_STATUS_ONLINE, hContact).Autoreply = Reply; - } -/* if (Notify != VAL_INDEFINITE) - { - CContactSettings(ID_STATUS_ONLINE, hContact).PopupNotify = Notify; - }*/ - if (hContact != INVALID_HANDLE_VALUE && g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS)) - { - int iMode; - for (iMode = ID_STATUS_AWAY; iMode < ID_STATUS_OUTTOLUNCH; iMode++) - { - if (Ignore != VAL_INDEFINITE) - { - CContactSettings(iMode, hContact).Ignore = Ignore; - } - if (Reply != VAL_INDEFINITE) - { - CContactSettings(iMode, hContact).Autoreply = Reply; - } // Notify is not per-status, so we're not setting it here - } - } -} - -static void SetAllContactIcons(HWND hwndList, HANDLE hItemUnknown) -{ - HANDLE hContact, hItem; - char *szProto; -// set values for hItemUnknown first - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItemUnknown, MAKELPARAM(IGNORECOLUMN, DBValueToIgnoreIcon(CContactSettings(ID_STATUS_ONLINE, INVALID_HANDLE_VALUE).Ignore))); - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItemUnknown, MAKELPARAM(AUTOREPLYCOLUMN, DBValueToOptReplyIcon(CContactSettings(ID_STATUS_ONLINE, INVALID_HANDLE_VALUE).Autoreply))); -// SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItemUnknown, MAKELPARAM(NOTIFYCOLUMN, DBValueToNotifyIcon(CContactSettings(ID_STATUS_ONLINE, INVALID_HANDLE_VALUE).PopupNotify))); - - hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - do - { - hItem = (HANDLE)SendMessage(hwndList, CLM_FINDCONTACT, (WPARAM)hContact, 0); - if (hItem)// && SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(IGNOREEVENT_MAX, 0)) == 0xFF) - { - szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - int Ignore = CContactSettings(ID_STATUS_ONLINE, hContact).Ignore; - int Reply = CContactSettings(ID_STATUS_ONLINE, hContact).Autoreply; -// int Notify = CContactSettings(ID_STATUS_ONLINE, hContact).PopupNotify; - if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS)) - { - int iMode; - for (iMode = ID_STATUS_AWAY; iMode < ID_STATUS_OUTTOLUNCH; iMode++) - { - if (CContactSettings(iMode, hContact).Ignore != Ignore) - { - Ignore = VAL_INDEFINITE; - } - if (CContactSettings(iMode, hContact).Autoreply != Reply) - { - Reply = VAL_INDEFINITE; - } // Notify is not per-status, so we're not checking it here - } - } - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(IGNORECOLUMN, DBValueToIgnoreIcon(Ignore))); - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(AUTOREPLYCOLUMN, DBValueToOptReplyIcon(Reply))); -// SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(NOTIFYCOLUMN, (szProto && IsAnICQProto(szProto)) ? DBValueToNotifyIcon(Notify) : 0xFF)); - } - } while (hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)); -} - -static LRESULT CALLBACK ContactsSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - switch (Msg) - { - case WM_LBUTTONDBLCLK: - { - DWORD hitFlags; - HANDLE hItem = (HANDLE)SendMessage(hWnd, CLM_HITTEST, (WPARAM)&hitFlags, lParam); - if (hItem && (hitFlags & CLCHT_ONITEMEXTRA)) - { - Msg = WM_LBUTTONDOWN; // may be considered as a hack, but it's needed to make clicking on extra icons more convenient - } - } break; - } - return CallWindowProc(g_OrigContactsProc, hWnd, Msg, wParam, lParam); -} - -INT_PTR CALLBACK ContactsOptDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static HANDLE hItemAll, hItemUnknown; - switch (msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - MySetPos(hwndDlg); - HWND hwndList = GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST); - HIMAGELIST hIml; - hIml = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), (IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR8) | ILC_MASK, 5, 2); - ImageList_AddIcon(hIml, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_DOT))); - ImageList_AddIcon(hIml, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_IGNORE))); - ImageList_AddIcon(hIml, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SOE_ENABLED))); - ImageList_AddIcon(hIml, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SOE_DISABLED))); - //ImageList_AddIcon(hIml, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ENABLENOTIFY))); - //ImageList_AddIcon(hIml, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_DISABLENOTIFY))); - ImageList_AddIcon(hIml, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_INDEFINITE))); - SendMessage(hwndList, CLM_SETEXTRAIMAGELIST, 0, (LPARAM)hIml); - SendMessage(hwndDlg, UM_CONTACTSDLG_RESETLISTOPTIONS, 0, 0); - SendMessage(hwndList, CLM_SETEXTRACOLUMNS, EXTRACOLUMNSCOUNT, 0); - CLCINFOITEM cii={0}; - cii.cbSize = sizeof(cii); - cii.flags = CLCIIF_GROUPFONT; - cii.pszText = TranslateT("** All contacts **"); - hItemAll = (HANDLE)SendMessage(hwndList, CLM_ADDINFOITEM, 0, (LPARAM)&cii); - cii.pszText = TranslateT("** Not-on-list contacts **"); // == Unknown contacts - hItemUnknown = (HANDLE)SendMessage(hwndList, CLM_ADDINFOITEM, 0, (LPARAM)&cii); - HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - do - { - char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - if (szProto) - { - int Flag1 = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0); - if ((Flag1 & PF1_IM) != PF1_IM && !(Flag1 & PF1_INDIVMODEMSG)) - { // does contact's protocol supports message sending/receiving or individual status messages? - SendMessage(hwndList, CLM_DELETEITEM, SendMessage(hwndList, CLM_FINDCONTACT, (WPARAM)hContact, 0), 0); - } - } - } while (hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)); - SetAllContactIcons(hwndList, hItemUnknown); - SetListGroupIcons(hwndList, (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll); - g_OrigContactsProc = (WNDPROC)SetWindowLongPtr(hwndList, GWLP_WNDPROC, (LONG_PTR)ContactsSubclassProc); - } break; - case UM_CONTACTSDLG_RESETLISTOPTIONS: - { - HWND hwndList = GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST); - SendMessage(hwndList, CLM_SETBKBITMAP, 0, NULL); - SendMessage(hwndList, CLM_SETBKCOLOR, GetSysColor(COLOR_WINDOW), 0); - SendMessage(hwndList, CLM_SETGREYOUTFLAGS, 0, 0); - SendMessage(hwndList, CLM_SETLEFTMARGIN, 4, 0); - SendMessage(hwndList, CLM_SETINDENT, 10, 0); - SendMessage(hwndList, CLM_SETHIDEEMPTYGROUPS, 1, 0); - int I; - for (I = 0; I <= FONTID_MAX; I++) - { - SendMessage(hwndList, CLM_SETTEXTCOLOR, I, GetSysColor(COLOR_WINDOWTEXT)); - } - } break; - case WM_SETFOCUS: - { - SetFocus(GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST)); - } break; - case WM_NOTIFY: - { - switch (((LPNMHDR)lParam)->idFrom) - { - case IDC_CONTACTSDLG_LIST: - { - switch (((LPNMHDR)lParam)->code) - { - case CLN_NEWCONTACT: - case CLN_LISTREBUILT: - { - SetAllContactIcons(GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST), hItemUnknown); - } // fall through - case CLN_CONTACTMOVED: - { - SetListGroupIcons(GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST), (HANDLE)SendDlgItemMessage(hwndDlg, IDC_CONTACTSDLG_LIST, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll); - } break; - case CLN_OPTIONSCHANGED: - { - SendMessage(hwndDlg, UM_CONTACTSDLG_RESETLISTOPTIONS, 0, 0); - } break; - case NM_CLICK: - case NM_DBLCLK: - { - NMCLISTCONTROL *nm = (NMCLISTCONTROL*)lParam; - HWND hwndList = GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST); - HANDLE hItem; - DWORD hitFlags; - if (nm->iColumn == -1) - { - break; - } - hItem = (HANDLE)SendMessage(hwndList, CLM_HITTEST, (WPARAM)&hitFlags, MAKELPARAM(nm->pt.x, nm->pt.y)); - if (!hItem || !(hitFlags & CLCHT_ONITEMEXTRA)) - { - break; - } - int iImage = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(nm->iColumn, 0)); - switch (nm->iColumn) - { - case AUTOREPLYCOLUMN: - { - switch (iImage) - { - case EXTRAICON_DOT: iImage = EXTRAICON_AUTOREPLYOFF; break; - case EXTRAICON_AUTOREPLYOFF: iImage = EXTRAICON_AUTOREPLYON; break; - default: iImage = EXTRAICON_DOT; // EXTRAICON_AUTOREPLYON and EXTRAICON_INDEFINITE - } - } break; - case IGNORECOLUMN: - { - iImage = (iImage == EXTRAICON_DOT) ? EXTRAICON_IGNORE : EXTRAICON_DOT; - } break; - /*case NOTIFYCOLUMN: - { - switch (iImage) - { - case EXTRAICON_DOT: iImage = EXTRAICON_DISABLENOTIFY; break; - case EXTRAICON_DISABLENOTIFY: iImage = EXTRAICON_ENABLENOTIFY; break; - default: iImage = EXTRAICON_DOT; // EXTRAICON_ENABLENOTIFY and EXTRAICON_INDEFINITE - } - }*/ break; - } - SetIconsForColumn(hwndList, hItem, hItemAll, nm->iColumn, iImage); - SetListGroupIcons(hwndList, (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } break; - } - } break; - case 0: - { - switch (((LPNMHDR)lParam)->code) - { - case PSN_APPLY: - { - HANDLE hContact, hItem; - hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - do - { - hItem = (HANDLE)SendDlgItemMessage(hwndDlg, IDC_CONTACTSDLG_LIST, CLM_FINDCONTACT, (WPARAM)hContact, 0); - if (hItem) - { - SaveItemState(GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST), hContact, hItem); - } - } while (hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)); -// SaveItemMask(GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST), NULL, hItemAll, "Default1"); // TODO: store All Contacts setting here too, - change global Notify and Autoreply settings? (& set the All Contacts icons to "?" initially if the global setting doesn't coincide with the setting calculated in the _current_ way); and also make sure that these settings will be refreshed in the other windows too - SaveItemState(GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST), INVALID_HANDLE_VALUE, hItemUnknown); - return true; - } break; - } - } break; - } - } break; - case WM_DESTROY: - { - HIMAGELIST hIml = (HIMAGELIST)SendDlgItemMessage(hwndDlg, IDC_CONTACTSDLG_LIST, CLM_GETEXTRAIMAGELIST, 0, 0); - _ASSERT(hIml); - ImageList_Destroy(hIml); - } break; - } - return 0; -} - - -int OptsDlgInit(WPARAM wParam, LPARAM lParam) -{ - OPTIONSDIALOGPAGE optDi = {0}; - optDi.cbSize = sizeof(optDi); - optDi.position = 920000000; - optDi.hInstance = g_hInstance; - optDi.flags = ODPF_BOLDGROUPS; - - optDi.pszTitle = OPT_MAINGROUP; - optDi.pfnDlgProc = MessagesOptDlg; - optDi.pszTemplate = MAKEINTRESOURCEA(IDD_MESSAGES); - optDi.pszTab = LPGEN("Statuses messages"); - Options_AddPage(wParam, &optDi); - - optDi.pfnDlgProc = MoreOptDlg; - optDi.pszTemplate = MAKEINTRESOURCEA(IDD_MOREOPTDIALOG); - optDi.pszTab = LPGEN("Main options"); - Options_AddPage(wParam, &optDi); - - optDi.pfnDlgProc = AutoreplyOptDlg; - optDi.pszTemplate = MAKEINTRESOURCEA(IDD_AUTOREPLY); - optDi.pszTab = LPGEN("Autoreply"); - Options_AddPage(wParam, &optDi); - - optDi.pfnDlgProc = ContactsOptDlg; - optDi.pszTemplate = MAKEINTRESOURCEA(IDD_CONTACTSOPTDLG); - optDi.pszTab = LPGEN("Contacts"); - Options_AddPage(wParam, &optDi); - return 0; -} - - -COptPage g_SetAwayMsgPage(MOD_NAME, NULL); -COptPage g_MsgTreePage(MOD_NAME, NULL); - -void InitOptions() -{ - InitThemes(); - g_MessagesOptPage.Items.AddElem(new COptItem_Generic(IDC_MESSAGEDLG_VARS, IDC_MESSAGEDLG_MSGTREE)); - g_MessagesOptPage.Items.AddElem(new COptItem_Generic(IDC_MESSAGEDLG_DEL)); - g_MessagesOptPage.Items.AddElem(new COptItem_Generic(IDC_MESSAGEDLG_MSGTITLE)); - g_MessagesOptPage.Items.AddElem(new COptItem_Generic(IDC_MESSAGEDLG_MSGDATA)); - g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_ONL, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); - g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_AWAY, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); - g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_NA, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); - g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_OCC, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); - g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_DND, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); - g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_FFC, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); - g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_INV, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); - g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_OTP, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); - g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_OTL, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); - TreeItemArray DefMsgTree; - int ParentID1; - int ID = 0; - TreeRootItemArray RootItems; - RootItems.AddElem(CTreeRootItem(TranslateT("Predefined messages"), g_Messages_PredefinedRootID = ID++, TIF_EXPANDED)); - RootItems.AddElem(CTreeRootItem(TranslateT("Recent messages"), g_Messages_RecentRootID = ID++, TIF_EXPANDED)); - DefMsgTree.AddElem(CTreeItem(TranslateT("Gone fragging"), g_Messages_PredefinedRootID, ID++, 0, TranslateTS(_T("Been fragging since %") _T(VAR_AWAYSINCE_TIME) _T("%, I'll msg you later when the adrenaline wears off.")))); - DefMsgTree.AddElem(CTreeItem(TranslateT("Creepy"), g_Messages_PredefinedRootID, ID++, 0, TranslateT("Your master, %nas_mynick%, has been %nas_statdesc% since the day that is only known as ?nas_awaysince_date(dddd)... When he gets back, I'll tell him you dropped by..."))); - DefMsgTree.AddElem(CTreeItem(TranslateT("Default messages"), g_Messages_PredefinedRootID, ParentID1 = ID++, TIF_GROUP | TIF_EXPANDED)); - g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_ONL, StatusToDBSetting(ID_STATUS_ONLINE, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); - DefMsgTree.AddElem(CTreeItem(TranslateT("Online"), ParentID1, ID++, 0, TranslateT("Yep, I'm here."))); - g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_AWAY, StatusToDBSetting(ID_STATUS_AWAY, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); - DefMsgTree.AddElem(CTreeItem(TranslateT("Away"), ParentID1, ID++, 0, TranslateT("Been gone since %nas_awaysince_time%, will be back later."))); - g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_NA, StatusToDBSetting(ID_STATUS_NA, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); - DefMsgTree.AddElem(CTreeItem(TranslateT("NA"), ParentID1, ID++, 0, TranslateT("Give it up, I'm not in!"))); - g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_OCC, StatusToDBSetting(ID_STATUS_OCCUPIED, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); - DefMsgTree.AddElem(CTreeItem(TranslateT("Occupied"), ParentID1, ID++, 0, TranslateT("Not right now."))); - g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_DND, StatusToDBSetting(ID_STATUS_DND, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); - DefMsgTree.AddElem(CTreeItem(TranslateT("DND"), ParentID1, ID++, 0, TranslateT("Give a guy some peace, would ya?"))); - g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_FFC, StatusToDBSetting(ID_STATUS_FREECHAT, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); - DefMsgTree.AddElem(CTreeItem(TranslateT("Free for chat"), ParentID1, ID++, 0, TranslateT("I'm a chatbot!"))); - g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_INV, StatusToDBSetting(ID_STATUS_INVISIBLE, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); - DefMsgTree.AddElem(CTreeItem(TranslateT("Invisible"), ParentID1, ID++, 0, TranslateT("I'm hiding from the mafia."))); - g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_OTP, StatusToDBSetting(ID_STATUS_ONTHEPHONE, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); - DefMsgTree.AddElem(CTreeItem(TranslateT("On the phone"), ParentID1, ID++, 0, TranslateT("I've been on the phone since %nas_awaysince_time%, give me a sec!"))); - g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_OTL, StatusToDBSetting(ID_STATUS_OUTTOLUNCH, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); - DefMsgTree.AddElem(CTreeItem(TranslateT("Out to lunch"), ParentID1, ID++, 0, TranslateT("Been having ?ifgreater(?ctime(H),2,?ifgreater(?ctime(H),10,?ifgreater(?ctime(H),16,supper,dinner),breakfast),supper) since %nas_awaysince_time%."))); - g_MsgTreePage.Items.AddElem(new COptItem_TreeCtrl(IDV_MSGTREE, "MsgTree", DefMsgTree, RootItems, 0, "Text")); - - g_SetAwayMsgPage.Items.AddElem(new COptItem_BitDBSetting(IDS_SAWAYMSG_SHOWMSGTREE, "SAMDlgFlags", DBVT_BYTE, DF_SAM_DEFDLGFLAGS, DF_SAM_SHOWMSGTREE)); - g_SetAwayMsgPage.Items.AddElem(new COptItem_BitDBSetting(IDS_SAWAYMSG_SHOWCONTACTTREE, "SAMDlgFlags", DBVT_BYTE, DF_SAM_DEFDLGFLAGS, DF_SAM_SHOWCONTACTTREE)); - g_SetAwayMsgPage.Items.AddElem(new COptItem_BitDBSetting(IDS_SAWAYMSG_AUTOSAVEDLGSETTINGS, "AutoSaveDlgSettings", DBVT_BYTE, 1)); - g_SetAwayMsgPage.Items.AddElem(new COptItem_BitDBSetting(IDS_SAWAYMSG_DISABLEVARIABLES, "DisableVariables", DBVT_BYTE, 0)); - - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_PERSTATUSMRM, "PerStatusMRM", DBVT_BYTE, 0)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_RESETPROTOMSGS, "ResetProtoMsgs", DBVT_BYTE, 1)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_PERSTATUSPROTOMSGS, "PerStatusProtoMsgs", DBVT_BYTE, 0)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_PERSTATUSPROTOSETTINGS, "PerStatusProtoSettings", DBVT_BYTE, 0)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_SAVEPERSONALMSGS, "SavePersonalMsgs", DBVT_BYTE, 1)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_PERSTATUSPERSONAL, "PerStatusPersonal", DBVT_BYTE, 0)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS, "PerStatusPersonalSettings", DBVT_BYTE, 0)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_USEMENUITEM, "UseMenuItem", DBVT_BYTE, 0)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_MYNICKPERPROTO, "MyNickPerProto", DBVT_BYTE, 1)); - g_MoreOptPage.Items.AddElem(new COptItem_IntEdit(IDC_MOREOPTDLG_WAITFORMSG, "WaitForMsg", DBVT_WORD, TRUE, 5)); - g_MoreOptPage.Items.AddElem(new COptItem_IntEdit(IDC_MOREOPTDLG_RECENTMSGSCOUNT, "MRMCount", DBVT_WORD, TRUE, 5)); - g_MoreOptPage.Items.AddElem(new COptItem_Radiobutton(IDC_MOREOPTDLG_USEDEFMSG, "UseByDefault", DBVT_BYTE, MOREOPTDLG_DEF_USEBYDEFAULT, 0)); - g_MoreOptPage.Items.AddElem(new COptItem_Radiobutton(IDC_MOREOPTDLG_USELASTMSG, "UseByDefault", DBVT_BYTE, MOREOPTDLG_DEF_USEBYDEFAULT, 1)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_UPDATEMSGS, "UpdateMsgs", DBVT_BYTE, 0)); - g_MoreOptPage.Items.AddElem(new COptItem_IntEdit(IDC_MOREOPTDLG_UPDATEMSGSPERIOD, "UpdateMsgsPeriod", DBVT_WORD, FALSE, 300)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_ONL, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_ONL)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_AWAY, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_AWAY)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_NA, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_NA)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_OCC, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_OCC)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_DND, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_DND)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_FFC, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_FFC)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_INV, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_INV)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_OTP, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_OTP)); - g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_OTL, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_OTL)); - - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_ENABLEREPLY, DB_ENABLEREPLY, DBVT_BYTE, AUTOREPLY_DEF_REPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Generic(IDC_REPLYDLG_STATIC_ONEVENT, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_EVENTMSG, "ReplyOnEvent", DBVT_BYTE, AUTOREPLY_DEF_REPLYONEVENT, EF_MSG, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_EVENTURL, "ReplyOnEvent", DBVT_BYTE, AUTOREPLY_DEF_REPLYONEVENT, EF_URL, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_EVENTFILE, "ReplyOnEvent", DBVT_BYTE, AUTOREPLY_DEF_REPLYONEVENT, EF_FILE, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DONTSENDTOICQ, "DontSendToICQ", DBVT_BYTE, 0, 0, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DONTREPLYINVISIBLE, "DontReplyInvisible", DBVT_BYTE, 1, 0, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_LOGREPLY, "LogReply", DBVT_BYTE, 1, 0, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_ONLYIDLEREPLY, "OnlyIdleReply", DBVT_BYTE, 0, 0, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_ONLYCLOSEDDLGREPLY, "OnlyClosedDlgReply", DBVT_BYTE, 1, 0, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Generic(IDC_REPLYDLG_STATIC_SEND, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_IntEdit(IDC_REPLYDLG_SENDCOUNT, "ReplyCount", DBVT_WORD, TRUE, -1, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Generic(IDC_REPLYDLG_STATIC_TIMES, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_RESETCOUNTERWHENSAMEICON, "ResetReplyCounterWhenSameIcon", DBVT_BYTE, 1, 0, IDC_REPLYDLG_SENDCOUNT)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Generic(IDC_REPLYDLG_STATIC_DISABLEWHENSTATUS, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_ONL, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_ONL, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_AWAY, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_AWAY, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_NA, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_NA, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_OCC, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_OCC, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_DND, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_DND, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_FFC, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_FFC, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_INV, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_INV, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_OTP, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_OTP, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_OTL, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_OTL, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Generic(IDC_REPLYDLG_STATIC_FORMAT, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Edit(IDC_REPLYDLG_PREFIX, "ReplyPrefix", AWAY_MSGDATA_MAX, AUTOREPLY_DEF_PREFIX, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Generic(IDC_REPLYDLG_VARS, IDC_REPLYDLG_ENABLEREPLY)); - g_AutoreplyOptPage.Items.AddElem(new COptItem_Generic(IDC_REPLYDLG_STATIC_EXTRATEXT, IDC_REPLYDLG_ENABLEREPLY)); -} - -//NightFox -int ModernOptInitialise(WPARAM wParam, LPARAM lParam) -{ - static int iBoldControls[] = - { - IDC_TXT_TITLE1, - IDC_TXT_TITLE2, - IDC_TXT_TITLE3, - MODERNOPT_CTRL_LAST - }; - - MODERNOPTOBJECT obj = {0}; - - obj.cbSize = sizeof(obj); - obj.dwFlags = MODEROPT_FLG_TCHAR|MODEROPT_FLG_NORESIZE; - obj.hInstance = g_hInstance; - obj.iSection = MODERNOPT_PAGE_STATUS; - obj.iType = MODERNOPT_TYPE_SECTIONPAGE; - obj.iBoldControls = iBoldControls; -// obj.lpzClassicGroup = NULL; - obj.lpzClassicPage = "Status"; - obj.lpzClassicTab = "Main options"; -// obj.lpzHelpUrl = "http://wiki.miranda-im.org/"; - - obj.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_MESSAGES); - obj.pfnDlgProc = MessagesModernOptDlg; - CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); - return 0; -} \ No newline at end of file diff --git a/!Deprecated/NewAwaySysMod/AwaySys.cpp b/!Deprecated/NewAwaySysMod/AwaySys.cpp deleted file mode 100644 index d573009ede..0000000000 --- a/!Deprecated/NewAwaySysMod/AwaySys.cpp +++ /dev/null @@ -1,1025 +0,0 @@ -/* - New Away System - plugin for Miranda IM - Copyright (c) 2005-2007 Chervov Dmitry - Copyright (c) 2004-2005 Iksaif Entertainment - Copyright (c) 2002-2003 Goblineye Entertainment - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - Thanx to Faith Healer for icons and help, Unregistered for his plugins (variables, AAA :p), - mistag for GamerStatus, BigMuscle for his code to use AAA - Thanx to Tornado, orignal developer of AwaySys. - Please note that some code from the Miranda's original away module (SRAway) is used around - AwaySys. i tried to mention it wherever possible, but i might have forgotten a few. Kudos to Miranda's authors. - The Read-Away-Msg part was practically copied from Miranda, not proud of it, but since i really can't see how can i make it better, there - was no point in rewriting it all. -*/ - -#include "Common.h" -#include "m_genmenu.h" -#include "m_idle.h" -#include "m_statusplugins.h" -#include "m_NewAwaySys.h" -#include "m_ContactSettings.h" -#include "MsgTree.h" -#include "ContactList.h" -#include "Properties.h" -#include "Path.h" -#include "Services.h" -#include "VersionNo.h" - -//NightFox -#include -#include // needed for MSVC 7 msvcr7*.dll patch - -HINSTANCE g_hInstance; - -int hLangpack = 0; -LIST hHooks(5), hServices(5); -HANDLE g_hContactMenuItem = NULL, g_hReadStatMenuItem = NULL, /*g_hTopToolbarbutton = NULL, */g_hToggleSOEMenuItem = NULL, g_hToggleSOEContactMenuItem = NULL, g_hAutoreplyOnContactMenuItem = NULL, g_hAutoreplyOffContactMenuItem = NULL, g_hAutoreplyUseDefaultContactMenuItem = NULL; -bool g_fNoProcessing = false; // tells the status change proc not to do anything -int g_bIsIdle = false; -HANDLE hMainThread; -int g_CSProtoCount = 0; // CommonStatus - StartupStatus and AdvancedAutoAway -VAR_PARSE_DATA VarParseData; -INT_PTR (*g_OldCallService)(const char *, WPARAM, LPARAM) = NULL; - -static struct -{ - int Status, DisableReplyCtlID, DontShowDialogCtlID; -} StatusModeList[] = { - ID_STATUS_ONLINE, IDC_REPLYDLG_DISABLE_ONL, IDC_MOREOPTDLG_DONTPOPDLG_ONL, - ID_STATUS_AWAY, IDC_REPLYDLG_DISABLE_AWAY, IDC_MOREOPTDLG_DONTPOPDLG_AWAY, - ID_STATUS_NA, IDC_REPLYDLG_DISABLE_NA, IDC_MOREOPTDLG_DONTPOPDLG_NA, - ID_STATUS_OCCUPIED, IDC_REPLYDLG_DISABLE_OCC, IDC_MOREOPTDLG_DONTPOPDLG_OCC, - ID_STATUS_DND, IDC_REPLYDLG_DISABLE_DND, IDC_MOREOPTDLG_DONTPOPDLG_DND, - ID_STATUS_FREECHAT, IDC_REPLYDLG_DISABLE_FFC, IDC_MOREOPTDLG_DONTPOPDLG_FFC, - ID_STATUS_INVISIBLE, IDC_REPLYDLG_DISABLE_INV, IDC_MOREOPTDLG_DONTPOPDLG_INV, - ID_STATUS_ONTHEPHONE, IDC_REPLYDLG_DISABLE_OTP, IDC_MOREOPTDLG_DONTPOPDLG_OTP, - ID_STATUS_OUTTOLUNCH, IDC_REPLYDLG_DISABLE_OTL, IDC_MOREOPTDLG_DONTPOPDLG_OTL -}; - -// took this nice idea from MetaContacts plugin ;) -// my_make_version is required to break up #define PRODUCTVER from VersionNo.h -DWORD my_make_version(const int a, const int b, const int c, const int d) -{ - return PLUGIN_MAKE_VERSION(a, b, c, d); -} - -PLUGININFOEX pluginInfo = { - sizeof(PLUGININFOEX), - "New Away System Mod", - my_make_version(PRODUCTVER), // see VersionNo.h - "New Away System Mod plugin for Miranda IM.", - "NightFox; Deathdemon; XF007; Goblineye Entertainment", - "NightFox@myied.org", - "© 2010 NightFox; © 2005-2007 Chervov Dmitry; © 2004-2005 Iksaif; © 2002-2003 Goblineye Entertainment", - "http://MyiEd.org/packs", - UNICODE_AWARE, - {0xb2dd9270, 0xce5e, 0x11df, {0xbd, 0x3d, 0x8, 0x0, 0x20, 0xc, 0x9a, 0x66}} -}; - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - g_hInstance = hinstDLL; - return TRUE; -} - -extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_SRAWAY, MIID_LAST}; // TODO: add MIID_WHOISREADING here if there'll be any some time in future.. - -extern "C" __declspec(dllexport) PLUGININFOEX *MirandaPluginInfoEx(DWORD mirandaVersion) -{ - return &pluginInfo; -} - -//NightFox -int ModernOptInitialise(WPARAM wParam,LPARAM lParam); - -TCString GetDynamicStatMsg(HANDLE hContact, char *szProto, DWORD UIN, int iStatus) -{ -// hContact is the contact that requests the status message - if (hContact != INVALID_HANDLE_VALUE) - { - VarParseData.Message = CContactSettings(iStatus, hContact).GetMsgFormat(GMF_ANYCURRENT, NULL, szProto); - } else - { // contact is unknown - VarParseData.Message = CProtoSettings(szProto, iStatus).GetMsgFormat(iStatus ? GMF_LASTORDEFAULT : GMF_ANYCURRENT); - } - TCString sTime; - VarParseData.szProto = szProto ? szProto : ((hContact && hContact != INVALID_HANDLE_VALUE) ? (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0) : NULL); - VarParseData.UIN = UIN; - VarParseData.Flags = 0; - if (ServiceExists(MS_VARS_FORMATSTRING) && !g_SetAwayMsgPage.GetDBValueCopy(IDS_SAWAYMSG_DISABLEVARIABLES)) - { - FORMATINFO fi = {0}; - fi.cbSize = sizeof(fi); - fi.tszFormat = VarParseData.Message; - fi.hContact = hContact; - fi.flags = FIF_TCHAR; - TCHAR *szResult = (TCHAR*)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0); - if (szResult) - { - VarParseData.Message = szResult; - CallService(MS_VARS_FREEMEMORY, (WPARAM)szResult, 0); - } - } - return VarParseData.Message = VarParseData.Message.Left(AWAY_MSGDATA_MAX); -} - - -int StatusMsgReq(WPARAM wParam, LPARAM lParam, CString &szProto) -{ - _ASSERT(szProto != NULL); - LogMessage("ME_ICQ_STATUSMSGREQ called. szProto=%s, Status=%d, UIN=%d", (char*)szProto, wParam, lParam); -// find the contact - char *szFoundProto; - HANDLE hFoundContact = NULL; // if we'll find the contact only on some other protocol, but not on szProto, then we'll use that hContact. - HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - while (hContact) - { - char *szCurProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - if (DBGetContactSettingDword(hContact, szCurProto, "UIN", 0) == lParam) - { - szFoundProto = szCurProto; - hFoundContact = hContact; - if (!strcmp(szCurProto, szProto)) - { - break; - } - } - hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); - } - int iMode = ICQStatusToGeneralStatus(wParam); - if (!hFoundContact) - { - hFoundContact = INVALID_HANDLE_VALUE; - } else if (iMode >= ID_STATUS_ONLINE && iMode <= ID_STATUS_OUTTOLUNCH) - { // don't count xstatus requests - DBWriteContactSettingWord(hFoundContact, MOD_NAME, DB_REQUESTCOUNT, DBGetContactSettingWord(hFoundContact, MOD_NAME, DB_REQUESTCOUNT, 0) + 1); - } - HANDLE hContactForSettings = hFoundContact; // used to take into account not-on-list contacts when getting contact settings, but at the same time allows to get correct contact info for contacts that are in the DB - if (hContactForSettings != INVALID_HANDLE_VALUE && DBGetContactSettingByte(hContactForSettings, "CList", "NotOnList", 0)) - { - hContactForSettings = INVALID_HANDLE_VALUE; // INVALID_HANDLE_VALUE means the contact is not-on-list - } - if (g_SetAwayMsgPage.GetWnd()) - { - CallAllowedPS_SETAWAYMSG(szProto, iMode, NULL); // we can set status messages to NULL here, as they'll be changed again when the SAM dialog closes. - return 0; - } - if (CContactSettings(iMode, hContactForSettings).Ignore) - { - CallAllowedPS_SETAWAYMSG(szProto, iMode, ""); // currently NULL makes ICQ to ignore _any_ further status message requests until the next PS_SETAWAYMSG, so i can't use it here.. - return 0; // move along, sir - } - - if (iMode) - { // if it's not an xstatus message request - CallAllowedPS_SETAWAYMSG(szProto, iMode, (char*)TCHAR2ANSI(GetDynamicStatMsg(hFoundContact, szProto, lParam))); - } -// COptPage PopupNotifyData(g_PopupOptPage); -// PopupNotifyData.DBToMem(); - VarParseData.szProto = szProto; - VarParseData.UIN = lParam; - VarParseData.Flags = 0; - if (!iMode) - { - VarParseData.Flags |= VPF_XSTATUS; - } -/* - int ShowPopup = ((iMode == ID_STATUS_ONLINE && PopupNotifyData.GetValue(IDC_POPUPOPTDLG_ONLNOTIFY)) || - (iMode == ID_STATUS_AWAY && PopupNotifyData.GetValue(IDC_POPUPOPTDLG_AWAYNOTIFY)) || - (iMode == ID_STATUS_DND && PopupNotifyData.GetValue(IDC_POPUPOPTDLG_DNDNOTIFY)) || - (iMode == ID_STATUS_NA && PopupNotifyData.GetValue(IDC_POPUPOPTDLG_NANOTIFY)) || - (iMode == ID_STATUS_OCCUPIED && PopupNotifyData.GetValue(IDC_POPUPOPTDLG_OCCNOTIFY)) || - (iMode == ID_STATUS_FREECHAT && PopupNotifyData.GetValue(IDC_POPUPOPTDLG_FFCNOTIFY)) || - (!iMode && PopupNotifyData.GetValue(IDC_POPUPOPTDLG_OTHERNOTIFY))) && - CContactSettings(iMode, hContactForSettings).PopupNotify.IncludingParents(); - -// Show popup and play a sound - if (ShowPopup) - { - ShowPopup = ShowPopupNotification(PopupNotifyData, hFoundContact, iMode); // we need ShowPopup also to determine whether to log to file or not - } -*/ -// Log status message request to a file -// if (!PopupNotifyData.GetValue(IDC_POPUPOPTDLG_LOGONLYWITHPOPUP) || ShowPopup) -// { - TCString LogMsg; - if (!iMode) - { // if it's an xstatus message request - LogMsg = DBGetContactSettingString(NULL, szProto, "XStatusName", _T("")); - TCString XMsg(DBGetContactSettingString(NULL, szProto, "XStatusMsg", _T(""))); - if (XMsg.GetLen()) - { - if (LogMsg.GetLen()) - { - LogMsg += _T("\r\n"); - } - LogMsg += XMsg; - } - } else - { - LogMsg = VarParseData.Message; - } - if (ServiceExists(MS_VARS_FORMATSTRING)) - { - logservice_log(LOG_ID, hFoundContact, LogMsg); - } else - { - TCString szUIN; - _ultot(lParam, szUIN.GetBuffer(16), 10); - szUIN.ReleaseBuffer(); - TCHAR *szStatDesc = iMode ? (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iMode, 0) : STR_XSTATUSDESC; - if (!szStatDesc) - { - _ASSERT(0); - szStatDesc = _T(""); - } - logservice_log(LOG_ID, hFoundContact, TCString((TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hFoundContact, GCDNF_TCHAR)) + _T(" (") + szUIN + TranslateT(") read your ") + szStatDesc + TranslateT(" message:\r\n") + LogMsg); - } -// } - return 0; -} - -// Here is an ugly workaround to support multiple ICQ accounts -// hope 5 icq accounts will be sufficient for everyone ;) -#define MAXICQACCOUNTS 5 -CString ICQProtoList[MAXICQACCOUNTS]; -#define StatusMsgReqN(N) int StatusMsgReq##N(WPARAM wParam, LPARAM lParam) {return StatusMsgReq(wParam, lParam, ICQProtoList[N - 1]);} -StatusMsgReqN(1) StatusMsgReqN(2) StatusMsgReqN(3) StatusMsgReqN(4) StatusMsgReqN(5) -MIRANDAHOOK StatusMsgReqHooks[] = {StatusMsgReq1, StatusMsgReq2, StatusMsgReq3, StatusMsgReq4, StatusMsgReq5}; - -int IsAnICQProto(char *szProto) -{ - int i; - for (i = 0; i < MAXICQACCOUNTS; i++) - { - if (ICQProtoList[i] == (const char*)szProto) - { - return true; - } - } - return false; -} - - -int StatusChanged(WPARAM wParam, LPARAM lParam) -{ -// wParam = iMode -// lParam = (char*)szProto - LogMessage("MS_CLIST_SETSTATUSMODE called. szProto=%s, Status=%d", lParam ? (char*)lParam : "NULL", wParam); - g_ProtoStates[(char*)lParam].Status = wParam; -// let's check if we handle this thingy - if (g_fNoProcessing) // we're told not to do anything - { - g_fNoProcessing = false; // take it off - return 0; - } - DWORD Flag1 = 0; - DWORD Flag3 = 0; - if (lParam) - { - Flag1 = CallProtoService((char*)lParam, PS_GETCAPS, PFLAGNUM_1, 0); - Flag3 = CallProtoService((char*)lParam, PS_GETCAPS, PFLAGNUM_3, 0); - } else - { - PROTOCOLDESCRIPTOR **proto; - int iProtoCount = 0; - CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&iProtoCount, (LPARAM)&proto); - int i; - for (i = 0; i < iProtoCount; i++) - { - if (proto[i]->type == PROTOTYPE_PROTOCOL) - { - Flag1 |= CallProtoService(proto[i]->szName, PS_GETCAPS, PFLAGNUM_1, 0); - Flag3 |= CallProtoService(proto[i]->szName, PS_GETCAPS, PFLAGNUM_3, 0); - } - } - } - if (!(Flag1 & PF1_MODEMSGSEND || Flag3 & Proto_Status2Flag(wParam) || (Flag1 & PF1_IM) == PF1_IM)) - { - return 0; // there are no protocols with changed status that support autoreply or away messages for this status - } - if (g_SetAwayMsgPage.GetWnd()) - { - SetForegroundWindow(g_SetAwayMsgPage.GetWnd()); - return 0; - } - int i; - for (i = lengthof(StatusModeList) - 1; i >= 0; i--) - { - if (wParam == StatusModeList[i].Status) - { - break; - } - } - if (i < 0) - { - return 0; - } - BOOL bScreenSaverRunning; - SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &bScreenSaverRunning, 0); - if (bScreenSaverRunning || g_MoreOptPage.GetDBValueCopy(StatusModeList[i].DontShowDialogCtlID)) - { - CProtoSettings((char*)lParam).SetMsgFormat(SMF_PERSONAL, CProtoSettings((char*)lParam).GetMsgFormat(GMF_LASTORDEFAULT)); - ChangeProtoMessages((char*)lParam, wParam, TCString()); - } else - { - SetAwayMsgData *dat = new SetAwayMsgData; - ZeroMemory(dat, sizeof(SetAwayMsgData)); - dat->szProtocol = (char*)lParam; - dat->IsModeless = false; - DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_SETAWAYMSG), NULL, SetAwayMsgDlgProc, (LPARAM)dat); - } - return 0; -} - - -#define ID_STATUS_LAST 40081 // yes, 40081 means internal CommonStatus' ID_STATUS_LAST here, not ID_STATUS_IDLE :-S -#define ID_STATUS_CURRENT 40082 -#define ID_STATUS_DISABLED 41083 -int CSStatusChange(WPARAM wParam, LPARAM lParam) // CommonStatus plugins (StartupStatus and AdvancedAutoAway) -{ -// wParam = PROTOCOLSETTINGEX** protoSettings - PROTOCOLSETTINGEX** ps = *(PROTOCOLSETTINGEX***)wParam; - if (!ps) - { - return -1; - } - LogMessage("ME_CS_STATUSCHANGEEX event:"); - int i; - for (i = 0; i < g_CSProtoCount; i++) - { - LogMessage("%d: cbSize=%d, szProto=%s, status=%d, lastStatus=%d, szMsg:", i + 1, ps[i]->cbSize, ps[i]->szName ? (char*)ps[i]->szName : "NULL", ps[i]->status, ps[i]->lastStatus, ps[i]->szMsg ? ps[i]->szMsg : "NULL"); - if (ps[i]->status != ID_STATUS_DISABLED) - { - if (ps[i]->status != ID_STATUS_CURRENT) - { - g_ProtoStates[ps[i]->szName].Status = (ps[i]->status == ID_STATUS_LAST) ? ps[i]->lastStatus : ps[i]->status; - } - CProtoSettings(ps[i]->szName).SetMsgFormat(SMF_TEMPORARY, ps[i]->szMsg ? ANSI2TCHAR(ps[i]->szMsg) : CProtoSettings(ps[i]->szName).GetMsgFormat(GMF_LASTORDEFAULT)); - } - } - return 0; -} - - -static int IdleChangeEvent(WPARAM wParam, LPARAM lParam) -{ - LogMessage("ME_IDLE_CHANGED event. lParam=0x%x", lParam); // yes, we don't do anything with status message changes on idle.. there seems to be no any good solution for the wrong status message issue :( - g_bIsIdle = lParam & IDF_ISIDLE; - return 0; -} - - -int CSModuleLoaded(WPARAM wParam, LPARAM lParam) // StartupStatus and AdvancedAutoAway -{ -// wParam = ProtoCount - g_CSProtoCount = wParam; - return 0; -} - - -int PreBuildContactMenu(WPARAM wParam, LPARAM lParam) -{ - HANDLE hContact = (HANDLE)wParam; - char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - CLISTMENUITEM miSetMsg = {0}; - miSetMsg.cbSize = sizeof(miSetMsg); - miSetMsg.flags = CMIM_FLAGS | CMIF_TCHAR | CMIF_HIDDEN; - CLISTMENUITEM miReadMsg = {0}; - miReadMsg.cbSize = sizeof(miReadMsg); - miReadMsg.flags = CMIM_FLAGS | CMIF_TCHAR | CMIF_HIDDEN; - int iMode = szProto ? CallProtoService(szProto, PS_GETSTATUS, 0, 0) : 0; - int Flag1 = szProto ? CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) : 0; - int iContactMode = DBGetContactSettingWord(hContact, szProto, "Status", ID_STATUS_OFFLINE); - TCHAR szSetStr[256], szReadStr[256]; - if (szProto) - { - int i; - for (i = lengthof(StatusModeList) - 1; i >= 0; i--) - { - if (iMode == StatusModeList[i].Status) - { - break; - } - } - if ((Flag1 & PF1_MODEMSGSEND && CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_3, 0) & Proto_Status2Flag(iMode)) || ((Flag1 & PF1_IM) == PF1_IM && (i < 0 || !g_AutoreplyOptPage.GetDBValueCopy(StatusModeList[i].DisableReplyCtlID)))) - { // the protocol supports status message sending for current status, or autoreplying - mir_sntprintf(szSetStr, SIZEOF(szSetStr), TranslateT("Set %s message for the contact"), CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iMode, GSMDF_TCHAR), CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR)); - miSetMsg.ptszName = szSetStr; - miSetMsg.flags = CMIM_FLAGS | CMIF_TCHAR | CMIM_NAME; - } - if (Flag1 & PF1_MODEMSGRECV && CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_3, 0) & Proto_Status2Flag(iContactMode)) - { // the protocol supports status message reading for contact's status - mir_sntprintf(szReadStr, SIZEOF(szReadStr), TranslateT("Re&ad %s Message"), CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iContactMode, GSMDF_TCHAR)); - miReadMsg.ptszName = szReadStr; - miReadMsg.flags = CMIM_FLAGS | CMIF_TCHAR | CMIM_NAME | CMIM_ICON; - miReadMsg.hIcon = LoadSkinnedProtoIcon(szProto, iContactMode); - } - } - if (g_hContactMenuItem) - { - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hContactMenuItem, (LPARAM)&miSetMsg); - - if ((Flag1 & PF1_IM) == PF1_IM) - { // if this contact supports sending/receiving messages - int iAutoreply = CContactSettings(g_ProtoStates[szProto].Status, hContact).Autoreply; - CLISTMENUITEM mi = {0}; - mi.cbSize = sizeof(mi); - mi.flags = CMIM_ICON | CMIM_FLAGS | CMIF_TCHAR; - switch (iAutoreply) - { - case VAL_USEDEFAULT: mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_DOT)); break; - case 0: mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SOE_DISABLED)); break; - default: iAutoreply = 1; mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SOE_ENABLED)); break; - } - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hToggleSOEContactMenuItem, (LPARAM)&mi); - mi.flags = CMIM_FLAGS | CMIF_TCHAR | (iAutoreply == 1 ? CMIF_CHECKED : 0); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hAutoreplyOnContactMenuItem, (LPARAM)&mi); - mi.flags = CMIM_FLAGS | CMIF_TCHAR | (iAutoreply == 0 ? CMIF_CHECKED : 0); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hAutoreplyOffContactMenuItem, (LPARAM)&mi); - mi.flags = CMIM_FLAGS | CMIF_TCHAR | (iAutoreply == VAL_USEDEFAULT ? CMIF_CHECKED : 0); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hAutoreplyUseDefaultContactMenuItem, (LPARAM)&mi); - } else - { // hide the Autoreply menu item - CLISTMENUITEM mi = {0}; - mi.cbSize = sizeof(mi); - mi.flags = CMIM_FLAGS | CMIF_TCHAR | CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hToggleSOEContactMenuItem, (LPARAM)&mi); - } - } - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hReadStatMenuItem, (LPARAM)&miReadMsg); - return 0; -} - - -static INT_PTR SetContactStatMsg(WPARAM wParam, LPARAM lParam) -{ - if (g_SetAwayMsgPage.GetWnd()) // already setting something - { - SetForegroundWindow(g_SetAwayMsgPage.GetWnd()); - return 0; - } - SetAwayMsgData *dat = new SetAwayMsgData; - ZeroMemory(dat, sizeof(SetAwayMsgData)); - dat->hInitContact = (HANDLE)wParam; - dat->szProtocol = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0); - dat->IsModeless = false; - DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_SETAWAYMSG), NULL, SetAwayMsgDlgProc, (LPARAM)dat); - return 0; -} - -/* //NightFox: deleted used-to-be support -void UpdateSOEButtons(HANDLE hContact) -{ - if (!hContact) - { - int SendOnEvent = CContactSettings(g_ProtoStates[(char*)NULL].Status).Autoreply; - CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)g_hTopToolbarbutton, SendOnEvent ? TTBST_PUSHED : TTBST_RELEASED); - CLISTMENUITEM mi = {0}; - mi.cbSize = sizeof(mi); - mi.position = 1000020000; - mi.flags = CMIF_TCHAR | CMIM_NAME | CMIM_ICON; // strange, but CMIF_TCHAR is still necessary even without CMIM_FLAGS - mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(SendOnEvent ? IDI_SOE_ENABLED : IDI_SOE_DISABLED)); - mi.ptszName = SendOnEvent ? DISABLE_SOE_COMMAND : ENABLE_SOE_COMMAND; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hToggleSOEMenuItem, (LPARAM)&mi); - } - if (g_SetAwayMsgPage.GetWnd()) - { - SendMessage(g_SetAwayMsgPage.GetWnd(), UM_SAM_REPLYSETTINGCHANGED, (WPARAM)hContact, 0); - } -} -*/ - -INT_PTR ToggleSendOnEvent(WPARAM wParam, LPARAM lParam) -{ // used only for the global setting - HANDLE hContact = (HANDLE)wParam; - CContactSettings(g_ProtoStates[hContact ? (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0) : (char*)NULL].Status, hContact).Autoreply.Toggle(); - //UpdateSOEButtons(); - return 0; -} - - -INT_PTR srvAutoreplyOn(WPARAM wParam, LPARAM lParam) -{ // wParam = hContact - HANDLE hContact = (HANDLE)wParam; - CContactSettings(g_ProtoStates[(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0)].Status, hContact).Autoreply = 1; - //UpdateSOEButtons(hContact); - return 0; -} - - -INT_PTR srvAutoreplyOff(WPARAM wParam, LPARAM lParam) -{ // wParam = hContact - HANDLE hContact = (HANDLE)wParam; - CContactSettings(g_ProtoStates[(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0)].Status, hContact).Autoreply = 0; - //UpdateSOEButtons(hContact); - return 0; -} - - -INT_PTR srvAutoreplyUseDefault(WPARAM wParam, LPARAM lParam) -{ // wParam = hContact - HANDLE hContact = (HANDLE)wParam; - CContactSettings(g_ProtoStates[(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0)].Status, hContact).Autoreply = VAL_USEDEFAULT; - //UpdateSOEButtons(hContact); - return 0; -} - -/* //NightFox: deleted used-to-be support -int Create_TopToolbar(WPARAM wParam, LPARAM lParam) -{ - int SendOnEvent = CContactSettings(g_ProtoStates[(char*)NULL].Status).Autoreply; - if (ServiceExists(MS_TTB_ADDBUTTON)) - { - TTBButton ttbb = {0}; - ttbb.cbSize = sizeof(ttbb); - ttbb.hbBitmapUp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_SOE_DISABLED)); - ttbb.hbBitmapDown = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_SOE_ENABLED)); - ttbb.pszServiceUp = MS_AWAYSYS_AUTOREPLY_TOGGLE; - ttbb.pszServiceDown = MS_AWAYSYS_AUTOREPLY_TOGGLE; - ttbb.dwFlags = TTBBF_VISIBLE | TTBBF_SHOWTOOLTIP; - ttbb.name = Translate("Toggle autoreply on/off"); - g_hTopToolbarbutton = (HANDLE)CallService(MS_TTB_ADDBUTTON, (WPARAM)&ttbb, 0); - CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)g_hTopToolbarbutton, SendOnEvent ? TTBST_PUSHED : TTBST_RELEASED); - } - return 0; -} -*/ - -static int IconsChanged(WPARAM wParam, LPARAM lParam) -{ - g_IconList.ReloadIcons(); - if (g_MessagesOptPage.GetWnd()) - { - SendMessage(g_MessagesOptPage.GetWnd(), UM_ICONSCHANGED, 0, 0); - } - if (g_MoreOptPage.GetWnd()) - { - SendMessage(g_MoreOptPage.GetWnd(), UM_ICONSCHANGED, 0, 0); - } - if (g_AutoreplyOptPage.GetWnd()) - { - SendMessage(g_AutoreplyOptPage.GetWnd(), UM_ICONSCHANGED, 0, 0); - } -/* if (g_PopupOptPage.GetWnd()) - { - SendMessage(g_PopupOptPage.GetWnd(), UM_ICONSCHANGED, 0, 0); - }*/ - return 0; -} - - -static int ContactSettingsInit(WPARAM wParam, LPARAM lParam) -{ - CONTACTSETTINGSINIT *csi = (CONTACTSETTINGSINIT*)wParam; - char *szProto = (csi->Type == CSIT_CONTACT) ? (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)csi->hContact, 0) : NULL; - if ((csi->Type == CSIT_GROUP) || szProto) - { - int Flag1 = (csi->Type == CSIT_CONTACT) ? CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) : PF1_IM; // we assume that there can be some contacts in the group with PF1_IM capability - if ((Flag1 & PF1_IM) == PF1_IM || Flag1 & PF1_INDIVMODEMSG) - { // does contact's protocol supports message sending/receiving or individual status messages? - CONTACTSETTINGSCONTROL csc = {0}; - csc.cbSize = sizeof(csc); - csc.cbStateSize = sizeof(CSCONTROLSTATE); - csc.Position = CSPOS_SORTBYALPHABET; - csc.ControlType = CSCT_CHECKBOX; - csc.szModule = MOD_NAME; - csc.StateNum = 3; - csc.DefState = 2; // these settings are used for all controls below - - /*if ((csi->Type == CSIT_GROUP) || IsAnICQProto(szProto)) - { - csc.Flags = CSCF_TCHAR; - csc.ptszTitle = LPGENT("New Away System: Status message request notifications"); - csc.ptszGroup = CSGROUP_NOTIFICATIONS; - csc.ptszTooltip = NULL; - csc.szSetting = DB_POPUPNOTIFY; - CallService(MS_CONTACTSETTINGS_ADDCONTROL, wParam, (LPARAM)&csc); - }*/ - int StatusMode = 0; - if (csi->Type == CSIT_CONTACT) - { - CContactSettings CSettings(0, csi->hContact); - StatusMode = CSettings.Status; - } else - { - _ASSERT(csi->Type == CSIT_GROUP); - StatusMode = g_ProtoStates[(char*)NULL].Status; - } - if (StatusMode == ID_STATUS_OFFLINE) - { - StatusMode = ID_STATUS_AWAY; - } - CString Setting; - TCHAR Title[128]; - csc.Flags = CSCF_TCHAR | CSCF_DONT_TRANSLATE_STRINGS; // these Flags and ptszGroup are used for both controls below - csc.ptszGroup = TranslateT("New Away System"); - - if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS)) - { - mir_sntprintf(Title, SIZEOF(Title), TranslateT("Enable autoreply when you are %s"), (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, StatusMode, GSMDF_TCHAR)); - csc.ptszTitle = Title; - csc.ptszTooltip = TranslateT("\"Store contact autoreply/ignore settings for each status separately\" is enabled, so this setting is per-contact AND per-status."); - } else - { - csc.ptszTitle = TranslateT("Enable autoreply"); - csc.ptszTooltip = NULL; - } - Setting = StatusToDBSetting(StatusMode, DB_ENABLEREPLY, IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS); - csc.szSetting = Setting; - CallService(MS_CONTACTSETTINGS_ADDCONTROL, wParam, (LPARAM)&csc); - - if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS)) - { - mir_sntprintf(Title, SIZEOF(Title), TranslateT("Don't send status message when you are %s"), (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, StatusMode, GSMDF_TCHAR)); - csc.ptszTitle = Title; - csc.ptszTooltip = TranslateT("Ignore status message requests from this contact and don't send an autoreply.\r\n\"Store contact autoreply/ignore settings for each status separately\" is enabled, so this setting is per-contact AND per-status."); - } else - { - csc.ptszTitle = TranslateT("Don't send status message"); - csc.ptszTooltip = TranslateT("Ignore status message requests from this contact and don't send an autoreply"); - } - Setting = StatusToDBSetting(StatusMode, DB_IGNOREREQUESTS, IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS); - csc.szSetting = Setting; - CallService(MS_CONTACTSETTINGS_ADDCONTROL, wParam, (LPARAM)&csc); - } - } - return 0; -} - - -INT_PTR srvVariablesHandler(WPARAM wParam, LPARAM lParam) -{ - ARGUMENTSINFO *ai = (ARGUMENTSINFO*)lParam; - ai->flags = AIF_DONTPARSE; - TCString Result; - if (!lstrcmp(ai->targv[0], _T(VAR_AWAYSINCE_TIME))) - { - GetTimeFormat(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), 0, g_ProtoStates[VarParseData.szProto].AwaySince, (ai->argc > 1 && *ai->targv[1]) ? ai->targv[1] : _T("H:mm"), Result.GetBuffer(256), 256); - Result.ReleaseBuffer(); - } else if (!lstrcmp(ai->targv[0], _T(VAR_AWAYSINCE_DATE))) - { - GetDateFormat(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), 0, g_ProtoStates[VarParseData.szProto].AwaySince, (ai->argc > 1 && *ai->targv[1]) ? ai->targv[1] : NULL, Result.GetBuffer(256), 256); - Result.ReleaseBuffer(); - } else if (!lstrcmp(ai->targv[0], _T(VAR_STATDESC))) - { - Result = (VarParseData.Flags & VPF_XSTATUS) ? STR_XSTATUSDESC : (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, g_ProtoStates[VarParseData.szProto].Status, GSMDF_TCHAR); - } else if (!lstrcmp(ai->targv[0], _T(VAR_MYNICK))) - { - if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_MYNICKPERPROTO) && VarParseData.szProto) - { - Result = DBGetContactSettingString(NULL, VarParseData.szProto, "Nick", (TCHAR*)NULL); - } - if (Result == NULL) - { - Result = (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, NULL, GCDNF_TCHAR); - } - if (Result == NULL) - { - Result = TranslateT("Stranger"); - } - } else if (!lstrcmp(ai->targv[0], _T(VAR_REQUESTCOUNT))) - { - mir_sntprintf(Result.GetBuffer(16), 16, _T("%d"), DBGetContactSettingWord(ai->fi->hContact, MOD_NAME, DB_REQUESTCOUNT, 0)); - Result.ReleaseBuffer(); - } else if (!lstrcmp(ai->targv[0], _T(VAR_MESSAGENUM))) - { - mir_sntprintf(Result.GetBuffer(16), 16, _T("%d"), DBGetContactSettingWord(ai->fi->hContact, MOD_NAME, DB_MESSAGECOUNT, 0)); - Result.ReleaseBuffer(); - } else if (!lstrcmp(ai->targv[0], _T(VAR_TIMEPASSED))) - { - ULARGE_INTEGER ul_AwaySince, ul_Now; - SYSTEMTIME st; - GetLocalTime(&st); - SystemTimeToFileTime(&st, (LPFILETIME)&ul_Now); - SystemTimeToFileTime(g_ProtoStates[VarParseData.szProto].AwaySince, (LPFILETIME)&ul_AwaySince); - ul_Now.QuadPart -= ul_AwaySince.QuadPart; - ul_Now.QuadPart /= 10000000; // now it's in seconds - Result.GetBuffer(256); - if (ul_Now.LowPart >= 7200) // more than 2 hours - { - mir_sntprintf(Result, 256, TranslateT("%d hours"), ul_Now.LowPart / 3600); - } else if (ul_Now.LowPart >= 120) // more than 2 minutes - { - mir_sntprintf(Result, 256, TranslateT("%d minutes"), ul_Now.LowPart / 60); - } else - { - mir_sntprintf(Result, 256, TranslateT("%d seconds"), ul_Now.LowPart); - } - Result.ReleaseBuffer(); - } else if (!lstrcmp(ai->targv[0], _T(VAR_PREDEFINEDMESSAGE))) - { - ai->flags = 0; // reset AIF_DONTPARSE flag - if (ai->argc != 2) - { - return NULL; - } - COptPage MsgTreeData(g_MsgTreePage); - COptItem_TreeCtrl *TreeCtrl = (COptItem_TreeCtrl*)MsgTreeData.Find(IDV_MSGTREE); - TreeCtrl->DBToMem(CString(MOD_NAME)); - int i; - for (i = 0; i < TreeCtrl->Value.GetSize(); i++) - { - if (!(TreeCtrl->Value[i].Flags & TIF_GROUP) && !_tcsicmp(TreeCtrl->Value[i].Title, ai->targv[1])) - { - Result = TreeCtrl->Value[i].User_Str1; - break; - } - } - if (Result == NULL) - { // if we didn't find a message with specified title - return NULL; // return it now, as later we change NULL to "" - } - } else if (!lstrcmp(ai->targv[0], _T(VAR_PROTOCOL))) - { - if (VarParseData.szProto) - { - CString AnsiResult; - CallProtoService(VarParseData.szProto, PS_GETNAME, 256, (LPARAM)AnsiResult.GetBuffer(256)); - AnsiResult.ReleaseBuffer(); - Result = ANSI2TCHAR(AnsiResult); - } - if (Result == NULL) - { // if we didn't find a message with specified title - return NULL; // return it now, as later we change NULL to "" - } - } - TCHAR *szResult; - if (!(szResult = (TCHAR*)malloc((Result.GetLen() + 1) * sizeof(TCHAR)))) - { - return NULL; - } - _tcscpy(szResult, (Result != NULL) ? Result : _T("")); - return (int)szResult; -} - - -INT_PTR srvFreeVarMem(WPARAM wParam, LPARAM lParam) -{ - if (!lParam) - { - return -1; - } - free((void*)lParam); - return 0; -} - - -static INT_PTR MyCallService(const char *name, WPARAM wParam, LPARAM lParam) -{ - if (name && wParam <= ID_STATUS_OUTTOLUNCH && wParam >= ID_STATUS_OFFLINE) // wParam conditions here are distinctive "features" of PS_SETSTATUS and PS_SETAWAYMSG services, so if wParam does not suit them, we'll pass the control to the old CallService function as soon as possible - { - const char *pProtoNameEnd = strrchr(name, '/'); - if (pProtoNameEnd) - { - if (!lstrcmpA(pProtoNameEnd, PS_SETSTATUS)) - { - // it's PS_SETSTATUS service; wParam = status; lParam = 0 - // returns 0 on success, nonzero on failure - CString Proto(""); - Proto.DiffCat(name, pProtoNameEnd); - if (wParam != g_ProtoStates[Proto].Status) - { - g_ProtoStates[Proto].Status = wParam; - TCString Msg(CProtoSettings(Proto).GetMsgFormat(GMF_LASTORDEFAULT)); - LogMessage("Detected a PS_SETSTATUS call with Status different from the one known to NAS. szProto=%s, NewStatus=%d, NewMsg:\n%s", (char*)Proto, wParam, (Msg != NULL) ? TCHAR2ANSI(Msg) : "NULL"); - CProtoSettings(Proto).SetMsgFormat(SMF_TEMPORARY, Msg); - } - } else if (!lstrcmpA(pProtoNameEnd, PS_SETAWAYMSG)) - { - // PS_SETAWAYMSG service; wParam = status; lParam = (const char*)szMessage - // returns 0 on success, nonzero on failure - CString Proto(""); - Proto.DiffCat(name, pProtoNameEnd); - LogMessage("Someone else than NAS called PS_SETAWAYMSG. szProto=%s, Status=%d, Msg:\n%s", (char*)Proto, wParam, lParam ? (char*)lParam : "NULL"); - CProtoSettings(Proto).SetMsgFormat(SMF_TEMPORARY, lParam ? ((ServiceExists(MS_VARS_FORMATSTRING) && !g_SetAwayMsgPage.GetDBValueCopy(IDS_SAWAYMSG_DISABLEVARIABLES)) ? VariablesEscape(ANSI2TCHAR((char*)lParam)) : ANSI2TCHAR((char*)lParam)) : TCString(_T(""))); - ChangeProtoMessages(Proto, wParam, TCString()); - return 0; - } - } - } - return g_OldCallService(name, wParam, lParam); -} - - -int MirandaLoaded(WPARAM wParam, LPARAM lParam) -{ - LoadMsgTreeModule(); - LoadCListModule(); - InitUpdateMsgs(); - g_IconList.ReloadIcons(); - - PROTOCOLDESCRIPTOR **proto; - DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hMainThread, THREAD_SET_CONTEXT, false, 0); - int iProtoCount = 0; - CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&iProtoCount, (LPARAM)&proto); - int i; - int CurProtoIndex; - for (i = 0, CurProtoIndex = 0; i < iProtoCount && CurProtoIndex < MAXICQACCOUNTS; i++) - { - if (proto[i]->type == PROTOTYPE_PROTOCOL) - { - HANDLE hHook = HookEvent(CString(proto[i]->szName) + ME_ICQ_STATUSMSGREQ, StatusMsgReqHooks[CurProtoIndex]); - if (hHook) - { - hHooks.insert(hHook); - ICQProtoList[CurProtoIndex] = proto[i]->szName; - CurProtoIndex++; - } - } - } - hServices.insert(CreateServiceFunction(MS_AWAYSYS_SETCONTACTSTATMSG, SetContactStatMsg)); - hServices.insert(CreateServiceFunction(MS_AWAYSYS_AUTOREPLY_TOGGLE, ToggleSendOnEvent)); - hServices.insert(CreateServiceFunction(MS_AWAYSYS_AUTOREPLY_ON, srvAutoreplyOn)); - hServices.insert(CreateServiceFunction(MS_AWAYSYS_AUTOREPLY_OFF, srvAutoreplyOff)); - hServices.insert(CreateServiceFunction(MS_AWAYSYS_AUTOREPLY_USEDEFAULT, srvAutoreplyUseDefault)); - hServices.insert(CreateServiceFunction(MS_NAS_GETSTATEA, GetStateA)); - hServices.insert(CreateServiceFunction(MS_NAS_SETSTATEA, SetStateA)); - hServices.insert(CreateServiceFunction(MS_NAS_GETSTATEW, GetStateW)); - hServices.insert(CreateServiceFunction(MS_NAS_SETSTATEW, SetStateW)); - hServices.insert(CreateServiceFunction(MS_NAS_INVOKESTATUSWINDOW, InvokeStatusWindow)); - hServices.insert(CreateServiceFunction(MS_AWAYMSG_GETSTATUSMSG, GetStatusMsg)); -// and old AwaySysMod service, for compatibility reasons - hServices.insert(CreateServiceFunction(MS_AWAYSYS_SETSTATUSMODE, SetStatusMode)); -//NightFox: none; -// hHooks.insert(HookEvent(ME_TTB_MODULELOADED, Create_TopToolbar)); - hHooks.insert(HookEvent(ME_OPT_INITIALISE, OptsDlgInit)); - hHooks.insert(HookEvent(ME_CLIST_STATUSMODECHANGE, StatusChanged)); - hHooks.insert(HookEvent(ME_CS_STATUSCHANGEEX, CSStatusChange)); // for compatibility with StartupStatus and AdvancedAutoAway - hHooks.insert(HookEvent(ME_DB_EVENT_FILTER_ADD, MsgEventAdded)); - hHooks.insert(HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PreBuildContactMenu)); - hHooks.insert(HookEvent(ME_SKIN_ICONSCHANGED, IconsChanged)); - hHooks.insert(HookEvent(ME_IDLE_CHANGED, IdleChangeEvent)); - hHooks.insert(HookEvent(ME_CONTACTSETTINGS_INITIALISE, ContactSettingsInit)); - g_hReadWndList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); - int SendOnEvent = CContactSettings(g_ProtoStates[(char*)NULL].Status).Autoreply; - - CLISTMENUITEM mi = {0}; - mi.cbSize = sizeof(mi); - mi.position = 1000020000; - mi.flags = CMIF_TCHAR | CMIF_NOTOFFLINE; - mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(SendOnEvent ? IDI_SOE_ENABLED : IDI_SOE_DISABLED)); - mi.ptszName = SendOnEvent ? DISABLE_SOE_COMMAND : ENABLE_SOE_COMMAND; - mi.pszService = MS_AWAYSYS_AUTOREPLY_TOGGLE; - g_hToggleSOEMenuItem = Menu_AddMainMenuItem(&mi); - - ZeroMemory(&mi, sizeof(mi)); - mi.cbSize = sizeof(mi); - mi.position = -2000005000; - mi.flags = CMIF_TCHAR | CMIF_NOTOFFLINE | CMIF_HIDDEN; - mi.ptszName = LPGENT("Read status message"); // never seen... - mi.pszService = MS_AWAYMSG_SHOWAWAYMSG; - g_hReadStatMenuItem = Menu_AddContactMenuItem(&mi); - if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_USEMENUITEM)) { - ZeroMemory(&mi, sizeof(mi)); - mi.cbSize = sizeof(mi); - mi.flags = CMIF_TCHAR | CMIF_HIDDEN; - mi.ptszName = LPGENT("Set status message"); // will never be shown - mi.position = 1000020000; - mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_MSGICON)); - mi.pszService = MS_AWAYSYS_SETCONTACTSTATMSG; - g_hContactMenuItem = Menu_AddContactMenuItem(&mi); - - ZeroMemory(&mi, sizeof(mi)); - mi.cbSize = sizeof(mi); - mi.flags = CMIF_TCHAR | CMIF_ROOTPOPUP; - mi.hIcon = NULL; - mi.pszPopupName = (char*)-1; - mi.position = 1000020000; - mi.ptszName = LPGENT("Autoreply"); - g_hToggleSOEContactMenuItem = Menu_AddContactMenuItem(&mi); - - mi.flags = CMIF_TCHAR | CMIF_CHILDPOPUP; - mi.pszPopupName = (char*)g_hToggleSOEContactMenuItem; - mi.popupPosition = 1000020000; - mi.position = 1000020000; - - mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SOE_ENABLED)); - mi.ptszName = LPGENT("On"); - mi.pszService = MS_AWAYSYS_AUTOREPLY_ON; - g_hAutoreplyOnContactMenuItem = Menu_AddContactMenuItem(&mi); - - mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SOE_DISABLED)); - mi.ptszName = LPGENT("Off"); - mi.pszService = MS_AWAYSYS_AUTOREPLY_OFF; - g_hAutoreplyOffContactMenuItem = Menu_AddContactMenuItem(&mi); - - mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_DOT)); - mi.ptszName = LPGENT("Use the default setting"); - mi.pszService = MS_AWAYSYS_AUTOREPLY_USEDEFAULT; - g_hAutoreplyUseDefaultContactMenuItem = Menu_AddContactMenuItem(&mi); - } - // add that funky thingy (just tweaked a bit, was spotted in Miranda's src code) - // we have to read the status message from contacts too... err - hServices.insert(CreateServiceFunction(MS_AWAYMSG_SHOWAWAYMSG, GetContactStatMsg)); - - SkinAddNewSoundEx(AWAYSYS_STATUSMSGREQUEST_SOUND, NULL, LPGEN("NewAwaySys: Incoming status message request")); - - if (ServiceExists(MS_VARS_REGISTERTOKEN)) { - struct - { - TCHAR *Name; - char *Descr; - int Flags; - } Variables[] = { - _T(VAR_AWAYSINCE_TIME), LPGEN("New Away System\t(x)\tAway since time in default format; ?nas_awaysince_time(x) in format x"), TRF_FIELD | TRF_FUNCTION, - _T(VAR_AWAYSINCE_DATE), LPGEN("New Away System\t(x)\tAway since date in default format; ?nas_awaysince_date(x) in format x"), TRF_FIELD | TRF_FUNCTION, - _T(VAR_STATDESC), LPGEN("New Away System\tStatus description"), TRF_FIELD | TRF_FUNCTION, - _T(VAR_MYNICK), LPGEN("New Away System\tYour nick for current protocol"), TRF_FIELD | TRF_FUNCTION, - _T(VAR_REQUESTCOUNT), LPGEN("New Away System\tNumber of status message requests from the contact"), TRF_FIELD | TRF_FUNCTION, - _T(VAR_MESSAGENUM), LPGEN("New Away System\tNumber of messages from the contact"), TRF_FIELD | TRF_FUNCTION, - _T(VAR_TIMEPASSED), LPGEN("New Away System\tTime passed until request"), TRF_FIELD | TRF_FUNCTION, - _T(VAR_PREDEFINEDMESSAGE), LPGEN("New Away System\t(x)\tReturns one of your predefined messages by its title: ?nas_predefinedmessage(creepy)"), TRF_FUNCTION, - _T(VAR_PROTOCOL), LPGEN("New Away System\tCurrent protocol name"), TRF_FIELD | TRF_FUNCTION - }; - hServices.insert(CreateServiceFunction(MS_AWAYSYS_FREEVARMEM, srvFreeVarMem)); - hServices.insert(CreateServiceFunction(MS_AWAYSYS_VARIABLESHANDLER, srvVariablesHandler)); - TOKENREGISTER tr = {0}; - tr.cbSize = sizeof(TOKENREGISTER); - tr.szService = MS_AWAYSYS_VARIABLESHANDLER; - tr.szCleanupService = MS_AWAYSYS_FREEVARMEM; - tr.memType = TR_MEM_OWNER; - int i; - for (i = 0; i < lengthof(Variables); i++) - { - tr.flags = Variables[i].Flags | TRF_CALLSVC | TRF_TCHAR; - tr.tszTokenString = Variables[i].Name; - tr.szHelpText = Variables[i].Descr; - CallService(MS_VARS_REGISTERTOKEN, 0, (LPARAM)&tr); - } - } - - //NightFox - HookEvent(ME_MODERNOPT_INITIALIZE, ModernOptInitialise); - - - return 0; -} - - -extern "C" int __declspec(dllexport) Load(void) -{ - - mir_getLP( &pluginInfo ); - - hHooks.insert(HookEvent(ME_SYSTEM_MODULESLOADED, MirandaLoaded)); - if (DBGetContactSettingString(NULL, "KnownModules", "New Away System", (char*)NULL) == NULL) - DBWriteContactSettingString(NULL, "KnownModules", "New Away System", MOD_NAME); - - InitCommonControls(); - InitOptions(); // must be called before we hook CallService - - logservice_register(LOG_ID, LPGENT("New Away System"), _T("NewAwaySys?puts(p,?dbsetting(%subject%,Protocol,p))?if2(_?dbsetting(,?get(p),?pinfo(?get(p),uidsetting)),).log"), TranslateTS(_T("`[`!cdate()-!ctime()`]` ?cinfo(%subject%,display) (?cinfo(%subject%,id)) read your %") _T(VAR_STATDESC) _T("% message:\r\n%extratext%\r\n\r\n"))); - - if (DBGetContactSettingByte(NULL, MOD_NAME, DB_SETTINGSVER, 0) < 1) - { // change all %nas_message% variables to %extratext% if it wasn't done before - TCString Str; - Str = DBGetContactSettingString(NULL, MOD_NAME, "PopupsFormat", _T("")); - if (Str.GetLen()) - { - DBWriteContactSettingTString(NULL, MOD_NAME, "PopupsFormat", Str.Replace(_T("nas_message"), _T("extratext"))); - } - Str = DBGetContactSettingString(NULL, MOD_NAME, "ReplyPrefix", _T("")); - if (Str.GetLen()) - { - DBWriteContactSettingTString(NULL, MOD_NAME, "ReplyPrefix", Str.Replace(_T("nas_message"), _T("extratext"))); - } - } - if (DBGetContactSettingByte(NULL, MOD_NAME, DB_SETTINGSVER, 0) < 2) - { // disable autoreply for not-on-list contacts, as such contact may be a spam bot - DBWriteContactSettingByte(NULL, MOD_NAME, ContactStatusToDBSetting(0, DB_ENABLEREPLY, 0, INVALID_HANDLE_VALUE), 0); - DBWriteContactSettingByte(NULL, MOD_NAME, DB_SETTINGSVER, 2); - } - return 0; -} - - -extern "C" int __declspec(dllexport) Unload() -{ - CloseHandle(hMainThread); - int i; - for (i = 0; i < hHooks.getCount(); i++) - UnhookEvent(hHooks[i]); - - for (i = 0; i < hServices.getCount(); i++) - DestroyServiceFunction(hServices[i]); - - return 0; -} diff --git a/!Deprecated/NewAwaySysMod/Client.cpp b/!Deprecated/NewAwaySysMod/Client.cpp deleted file mode 100644 index 7767bdb285..0000000000 --- a/!Deprecated/NewAwaySysMod/Client.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* - New Away System - plugin for Miranda IM - Copyright (c) 2005-2007 Chervov Dmitry - Copyright (c) 2004-2005 Iksaif Entertainment - Copyright (c) 2002-2003 Goblineye Entertainment - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "Common.h" -#include "MsgTree.h" -#include "Properties.h" - -#define PARSE_INTERVAL 10000 - -HANDLE g_hTerminateUpdateMsgsThread = NULL; -HANDLE g_hUpdateMsgsThread = NULL; - -void __cdecl UpdateMsgsThreadProc(void *) -{ - int ProtoCount; - PROTOCOLDESCRIPTOR **proto; - CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&ProtoCount, (LPARAM)&proto); - int I; - while (WaitForSingleObject(g_hTerminateUpdateMsgsThread, 0) == WAIT_TIMEOUT && !Miranda_Terminated()) - { - DWORD MinUpdateTimeDifference = g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_UPDATEMSGSPERIOD) * 1000; // in milliseconds - for (I = 0; I < ProtoCount; I++) - { - if (proto[I]->type == PROTOTYPE_PROTOCOL && CallProtoService(proto[I]->szName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND && !IsAnICQProto(proto[I]->szName)) - { - int Status = CallProtoService(proto[I]->szName, PS_GETSTATUS, 0, 0); - if (Status < ID_STATUS_OFFLINE || Status > ID_STATUS_OUTTOLUNCH) - { - Status = g_ProtoStates[proto[I]->szName].Status; - } - if (CallProtoService(proto[I]->szName, PS_GETCAPS, PFLAGNUM_3, 0) & Proto_Status2Flag(Status) && g_ProtoStates[proto[I]->szName].CurStatusMsg.GetUpdateTimeDifference() >= MinUpdateTimeDifference) - { - TCString CurMsg(GetDynamicStatMsg(INVALID_HANDLE_VALUE, proto[I]->szName)); - if ((TCString)g_ProtoStates[proto[I]->szName].CurStatusMsg != (const TCHAR*)CurMsg) // if the message has changed - { - g_ProtoStates[proto[I]->szName].CurStatusMsg = CurMsg; - CallAllowedPS_SETAWAYMSG(proto[I]->szName, Status, (char*)TCHAR2ANSI(CurMsg)); - } - } - } - } - SleepEx(PARSE_INTERVAL, true); - } -} - - -static void __stdcall DummyAPCFunc(ULONG_PTR) -{ - return; -} - - -void InitUpdateMsgs() -{ - int UpdateMsgs = g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_UPDATEMSGS); - if (g_hUpdateMsgsThread && !UpdateMsgs) - { - _ASSERT(WaitForSingleObject(g_hUpdateMsgsThread, 0) == WAIT_TIMEOUT); - SetEvent(g_hTerminateUpdateMsgsThread); - QueueUserAPC(DummyAPCFunc, g_hUpdateMsgsThread, 0); // wake up the thread, as it's most probably in SleepEx() now - WaitForSingleObject(g_hUpdateMsgsThread, INFINITE); - g_hUpdateMsgsThread = NULL; - CloseHandle(g_hTerminateUpdateMsgsThread); - } else if (!g_hUpdateMsgsThread && UpdateMsgs) - { - g_hTerminateUpdateMsgsThread = CreateEvent(NULL, TRUE, FALSE, NULL); - g_hUpdateMsgsThread = (HANDLE)mir_forkthread(UpdateMsgsThreadProc, NULL); - } -} - - -void ChangeProtoMessages(char* szProto, int iMode, TCString &Msg) -{ - TCString CurMsg(Msg); - if (szProto) - { - if (Msg == NULL) - { - CurMsg = GetDynamicStatMsg(INVALID_HANDLE_VALUE, szProto); - } - CallAllowedPS_SETAWAYMSG(szProto, iMode, (char*)TCHAR2ANSI(CurMsg)); - g_ProtoStates[szProto].CurStatusMsg = CurMsg; - } else // change message of all protocols - { - int ProtoCount; - PROTOCOLDESCRIPTOR **proto; - CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&ProtoCount, (LPARAM)&proto); - int I; - for (I = 0; I < ProtoCount; I++) - { - if (proto[I]->type == PROTOTYPE_PROTOCOL && !DBGetContactSettingByte(NULL, proto[I]->szName, "LockMainStatus", 0)) - { - if (Msg == NULL) - { - CurMsg = GetDynamicStatMsg(INVALID_HANDLE_VALUE, proto[I]->szName); - } - CallAllowedPS_SETAWAYMSG(proto[I]->szName, iMode, (char*)TCHAR2ANSI(CurMsg)); - g_ProtoStates[proto[I]->szName].CurStatusMsg = CurMsg; - } - } - } - static struct - { - int Status; - char *Setting; - } StatusSettings[] = { - ID_STATUS_OFFLINE, "Off", - ID_STATUS_ONLINE, "On", - ID_STATUS_AWAY, "Away", - ID_STATUS_NA, "Na", - ID_STATUS_DND, "Dnd", - ID_STATUS_OCCUPIED, "Occupied", - ID_STATUS_FREECHAT, "FreeChat", - ID_STATUS_INVISIBLE, "Inv", - ID_STATUS_ONTHEPHONE, "Otp", - ID_STATUS_OUTTOLUNCH, "Otl", - ID_STATUS_IDLE, "Idl" - }; - int I; - for (I = 0; I < lengthof(StatusSettings); I++) - { - if (iMode == StatusSettings[I].Status) - { - DBWriteContactSettingTString(NULL, "SRAway", CString(StatusSettings[I].Setting) + "Msg", CurMsg); - DBWriteContactSettingTString(NULL, "SRAway", CString(StatusSettings[I].Setting) + "Default", CurMsg); // TODO: make it more accurate, and change not only here, but when changing status messages through UpdateMsgsTimerFunc too; and when changing messages through AutoAway() ? - break; - } - } -// InitUpdateMsgs(); -} - - -int GetRecentGroupID(int iMode) -{ // returns an ID of a group where recent messages are stored, accordingly to current settings and status mode. - // -1 if the group is not found -// COptPage MoreOptData(g_MoreOptPage); - COptPage MsgTreeData(g_MsgTreePage); - COptItem_TreeCtrl *TreeCtrl = (COptItem_TreeCtrl*)MsgTreeData.Find(IDV_MSGTREE); - TreeCtrl->DBToMem(CString(MOD_NAME)); - int Order; - if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_PERSTATUSMRM)) - { - for (Order = 0; Order < TreeCtrl->Value.GetSize(); Order++) // find a group named accordingly to the current status - { - if (TreeCtrl->Value[Order].ParentID == g_Messages_RecentRootID && TreeCtrl->Value[Order].Flags & TIF_GROUP && !_tcsicmp(TreeCtrl->Value[Order].Title, iMode ? (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iMode, GSMDF_TCHAR) : MSGTREE_RECENT_OTHERGROUP)) - { - return TreeCtrl->Value[Order].ID; - } - } - } else // simply use Recent Messages category - { - return g_Messages_RecentRootID; - } - return -1; -} - - -int ICQStatusToGeneralStatus(int bICQStat) -{ - switch (bICQStat) - { - case MTYPE_AUTOONLINE: return ID_STATUS_ONLINE; - case MTYPE_AUTOAWAY: return ID_STATUS_AWAY; - case MTYPE_AUTONA: return ID_STATUS_NA; - case MTYPE_AUTODND: return ID_STATUS_DND; - case MTYPE_AUTOBUSY: return ID_STATUS_OCCUPIED; - case MTYPE_AUTOFFC: return ID_STATUS_FREECHAT; - default: return 0; - } -} - - -TCString VariablesEscape(TCString Str) -{ - if (!Str.GetLen()) - { - return _T(""); - } - enum eState - { - ST_TEXT, ST_QUOTE - }; - eState State = ST_QUOTE; - TCString Result(_T("`")); - const TCHAR *p = Str; - while (*p) - { - if (*p == '`') - { - if (State == ST_TEXT) - { - Result += _T("````"); - State = ST_QUOTE; - } else - { - Result += _T("``"); - } - } else - { - Result += *p; - State = ST_TEXT; - } - p++; - } - if (State == ST_QUOTE) - { - Result.GetBuffer()[Result.GetLen() - 1] = '\0'; - Result.ReleaseBuffer(); - } else - { - Result += '`'; - } - return Result; -} diff --git a/!Deprecated/NewAwaySysMod/Common.h b/!Deprecated/NewAwaySysMod/Common.h deleted file mode 100644 index 7e261d875d..0000000000 --- a/!Deprecated/NewAwaySysMod/Common.h +++ /dev/null @@ -1,411 +0,0 @@ -/* - New Away System - plugin for Miranda IM - Copyright (c) 2005-2007 Chervov Dmitry - Copyright (c) 2004-2005 Iksaif Entertainment - Copyright (c) 2002-2003 Goblineye Entertainment - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#pragma once - -#define _CRT_SECURE_NO_WARNINGS -#define WIN32_LEAN_AND_MEAN -#define _WIN32_WINNT 0x0500 - -#define MIRANDA_VER 0x0600 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "newpluginapi.h" -#include "m_clist.h" -#include "m_system.h" -#include "m_database.h" -#include "m_clui.h" -#include "m_langpack.h" -#include "m_protosvc.h" -#include "m_options.h" -#include "..\..\protocols\IcqOscarJ\icq_constants.h" -#include "m_skin.h" -#include "m_awaymsg.h" -#include "m_utils.h" -#include "m_system_cpp.h" -#include "m_history.h" -#include "m_message.h" -#include "m_userinfo.h" -#include "m_icq.h" -#define THEMEAPI // we don't need no uxtheme defines :-/ they break everything when trying to include tmschema.h later -#include "win2k.h" -#undef THEMEAPI - -#include "resource.h" - -#include "m_variables.h" -//#include "m_toptoolbar.h" -#include "m_popup.h" -//#include "m_popupw.h" -#include "m_metacontacts.h" -#include "m_LogService.h" -#include "..\CommonLibs\CString.h" -#include "..\CommonLibs\Options.h" - - -#pragma comment(lib,"comctl32.lib") - -#define VAR_AWAYSINCE_TIME "nas_awaysince_time" -#define VAR_AWAYSINCE_DATE "nas_awaysince_date" -#define VAR_STATDESC "nas_statdesc" -#define VAR_MYNICK "nas_mynick" -#define VAR_REQUESTCOUNT "nas_requestcount" -#define VAR_MESSAGENUM "nas_messagecount" -#define VAR_TIMEPASSED "nas_timepassed" -#define VAR_PREDEFINEDMESSAGE "nas_predefinedmessage" -#define VAR_PROTOCOL "nas_protocol" - -#define SENDSMSG_EVENT_MSG 0x1 -#define SENDSMSG_EVENT_URL 0x2 -#define SENDSMSG_EVENT_FILE 0x4 - -#define AWAY_MSGDATA_MAX 8000 - -// Flags for status database settings -#define SF_OFF 0x1 -#define SF_ONL 0x2 -#define SF_AWAY 0x4 -#define SF_NA 0x8 -#define SF_OCC 0x10 -#define SF_DND 0x20 -#define SF_FFC 0x40 -#define SF_INV 0x80 -#define SF_OTP 0x100 -#define SF_OTL 0x200 -#define SF_OTHER 0x80000000 -/* -// Actions on popup click -#define PCA_OPENMESSAGEWND 0 // open message window -#define PCA_CLOSEPOPUP 1 // close popup -#define PCA_OPENDETAILS 2 // open contact details window -#define PCA_OPENMENU 3 // open contact menu -#define PCA_OPENHISTORY 4 // open contact history -#define PCA_OPENLOG 5 // open log file -#define PCA_DONOTHING 6 // do nothing - -// Notification options defaults -#define POPUP_DEF_POPUP_FORMAT TranslateT("?cinfo(%subject%,display) (?cinfo(%subject%,id)) is reading your %nas_statdesc% message:\r\n%extratext%") -#define POPUP_DEF_USEPOPUPS 0 -#define POPUP_DEF_LCLICKACTION PCA_OPENMESSAGEWND -#define POPUP_DEF_RCLICKACTION PCA_CLOSEPOPUP -#define POPUP_DEF_POPUP_BGCOLOUR 0xFFB5BC -#define POPUP_DEF_POPUP_TEXTCOLOUR 0 -#define POPUP_DEF_USEDEFBGCOLOUR 0 -#define POPUP_DEF_USEDEFTEXTCOLOUR 0 -#define POPUP_DEF_POPUPNOTIFYFLAGS (SF_ONL | SF_AWAY | SF_NA | SF_OCC | SF_DND | SF_FFC | SF_INV | SF_OTP | SF_OTL) -#define POPUP_DEF_POPUPDELAY 0 - -#define POPUP_MAXPOPUPDELAY 9999 -*/ -#define MOREOPTDLG_DEF_DONTPOPDLG (SF_ONL | SF_INV) -#define MOREOPTDLG_DEF_USEBYDEFAULT 0 - -// Event flags (used for "reply on event" options) -#define EF_MSG 1 -#define EF_URL 2 -#define EF_FILE 4 - -#define AUTOREPLY_DEF_REPLY 0 -#define AUTOREPLY_DEF_REPLYONEVENT (EF_MSG | EF_URL | EF_FILE) -#define AUTOREPLY_DEF_PREFIX TranslateT("Miranda IM autoreply >\r\n%extratext%") -#define AUTOREPLY_DEF_DISABLEREPLY (SF_ONL | SF_INV) - -#define AUTOREPLY_IDLE_WINDOWS 0 -#define AUTOREPLY_IDLE_MIRANDA 1 -#define AUTOREPLY_DEF_IDLEREPLYVALUE AUTOREPLY_IDLE_WINDOWS - -#define AUTOREPLY_MAXPREFIXLEN 8000 - -#define VAL_USEDEFAULT 2 // undefined value for ignore/autoreply/notification settings in the db; must be 2 for proper ContactSettings support - -// Set Away Message dialog flags -#define DF_SAM_SHOWMSGTREE 1 -#define DF_SAM_SHOWCONTACTTREE 2 -#define DF_SAM_DEFDLGFLAGS DF_SAM_SHOWMSGTREE - -// WriteAwayMsgInDB option flags: -#define WRITE_LMSG 1 -#define WRITE_RMSG 2 -#define WRITE_INTERPRET 4 -#define WRITE_CMSG 8 - -#define TOGGLE_SOE_COMMAND LPGENT("Toggle autoreply on/off") -#define DISABLE_SOE_COMMAND LPGENT("Toggle autoreply off") -#define ENABLE_SOE_COMMAND LPGENT("Toggle autoreply on") - -#define STR_XSTATUSDESC TranslateT("extended status") - -#define MOD_NAME "NewAwaySys" -#define LOG_ID MOD_NAME // LogService log ID -#define LOG_PREFIX MOD_NAME ": " // netlib.log prefix for all NAS' messages - -#define DB_SETTINGSVER "SettingsVer" - -#ifndef lengthof -#define lengthof(s) (sizeof(s) / sizeof(*s)) -#endif - -#define MS_NETLIB_LOG "Netlib/Log" - -#define UM_ICONSCHANGED (WM_USER + 121) - -// IDD_READAWAYMSG user-defined message constants -#define UM_RAM_AWAYMSGACK (WM_USER + 10) - -// IDD_SETAWAYMSG user-defined message constants -#define UM_SAM_SPLITTERMOVED (WM_USER + 1) -#define UM_SAM_SAVEDLGSETTINGS (WM_USER + 2) -#define UM_SAM_APPLYANDCLOSE (WM_USER + 3) -#define UM_SAM_KILLTIMER (WM_USER + 4) -#define UM_SAM_REPLYSETTINGCHANGED (WM_USER + 5) -#define UM_SAM_PROTOSTATUSCHANGED (WM_USER + 6) // wParam = (char*)szProto - -#define UM_CLICK (WM_USER + 100) - -#define SAM_DB_DLGPOSX "SAMDlgPosX" -#define SAM_DB_DLGPOSY "SAMDlgPosY" -#define SAM_DB_DLGSIZEX "SAMDlgSizeX" -#define SAM_DB_DLGSIZEY "SAMDlgSizeY" -#define SAM_DB_MSGSPLITTERPOS "SAMMsgSplitterPos" -#define SAM_DB_CONTACTSPLITTERPOS "SAMContactSplitterPos" - -#define DB_MESSAGECOUNT "MessageCount" -#define DB_REQUESTCOUNT "RequestCount" -#define DB_SENDCOUNT "SendCount" -#define MESSAGES_DB_MSGTREEDEF "MsgTreeDef" - -#define MSGTREE_RECENT_OTHERGROUP _T("Other") - -// GetMsgFormat flags -#define GMF_PERSONAL 1 // is also used to get global status message, when hContact = NULL (szProto = NULL) -#define GMF_PROTOORGLOBAL 2 -#define GMF_LASTORDEFAULT 4 // this flag doesn't require hContact or szProto -#define GMF_TEMPORARY 8 // doesn't require status -#define GMF_ANYCURRENT (GMF_TEMPORARY | GMF_PERSONAL | GMF_PROTOORGLOBAL) - -// SetMsgFormat flags -#define SMF_PERSONAL 1 // is also used to set global status message, when hContact = NULL (szProto = NULL) -#define SMF_LAST 2 -#define SMF_TEMPORARY 4 // doesn't require status - -// VAR_PARSE_DATA flags -#define VPF_XSTATUS 1 // use "extended status" instead of the usual status description in %nas_statdesc%, and XStatus message in %nas_message% - -// options dialog -#define OPT_TITLE LPGENT("Away System") -#define OPT_MAINGROUP LPGEN("Status") -#define OPT_POPUPGROUP LPGEN("PopUps") - -#define MRM_MAX_GENERATED_TITLE_LEN 35 // maximum length of automatically generated title for recent messages - -int ICQStatusToGeneralStatus(int bICQStat); // TODO: get rid of these protocol-specific functions, if possible - -#define MS_AWAYSYS_SETCONTACTSTATMSG "AwaySys/SetContactStatMsg" - -#define MS_AWAYSYS_AUTOREPLY_TOGGLE "AwaySys/AutoreplyToggle" -#define MS_AWAYSYS_AUTOREPLY_ON "AwaySys/AutoreplyOn" -#define MS_AWAYSYS_AUTOREPLY_OFF "AwaySys/AutoreplyOff" -#define MS_AWAYSYS_AUTOREPLY_USEDEFAULT "AwaySys/AutoreplyUseDefault" - -#define MS_AWAYSYS_VARIABLESHANDLER "AwaySys/VariablesHandler" -#define MS_AWAYSYS_FREEVARMEM "AwaySys/FreeVarMem" -// these are obsolete AwaySysMod services, though they're still here for compatibility with old plugins -#define MS_AWAYSYS_SETSTATUSMODE "AwaySys/SetStatusMode" // change the status mode. wParam is new mode, lParam is new status message (AwaySys will interpret variables out of it), may be NULL. -#define MS_AWAYSYS_IGNORENEXT "AwaySys/IgnoreNextStatusChange" //ignore nest status change - -typedef struct SetAwayMsgData_type -{ - CString szProtocol; - HANDLE hInitContact; // initial contact (filled by caller) - TCString Message; // initial message, NULL means default - bool IsModeless; // means the dialog was created with the CreateDialogParam function, not DialogBoxParam - int ISW_Flags; // InvokeStatusWindow service flags -} SetAwayMsgData; - -typedef struct READAWAYMSGDATA_TYPE -{ - HANDLE hContact; // contact - HANDLE hSeq; // sequence for stat msg request - HANDLE hAwayMsgEvent; // hooked -} READAWAYMSGDATA; - -typedef struct -{ - char *szProto; - TCString Message; - DWORD UIN; - int Flags; // a combination of VPF_ flags -} VAR_PARSE_DATA; - -typedef struct -{ - HANDLE hContact; - int iStatusMode; - TCString Proto; -} DYNAMIC_NOTIFY_DATA; - -typedef struct -{ - BYTE PopupLClickAction, PopupRClickAction; - HANDLE hContact; - HICON hStatusIcon; // needed here to destroy its handle on UM_FREEPLUGINDATA -} PLUGIN_DATA; - -typedef struct -{ - int cbSize; - char *szProto; - HANDLE hContact; - char *szMsg; - WORD status; -} NAS_ISWINFOv1; - -#define MTYPE_AUTOONLINE 0xE7 // required to support ICQ Plus online status messages -/* -// additional m_popup.h declarations - - typedef struct - { - HANDLE lchContact; - HICON lchIcon; - WCHAR lpzContactName[MAX_CONTACTNAME]; - WCHAR lpzText[MAX_SECONDLINE]; - COLORREF colorBack; - COLORREF colorText; - WNDPROC PluginWindowProc; - void * PluginData; - int iSeconds; - char cZero[16]; - } POPUPDATAT; - - #define MS_POPUP_ADDPOPUPT MS_POPUP_ADDPOPUPW - -*/ -// Beware of conflicts between two different windows trying to use the same page at a time! -// Other windows than the owner of the Page must copy the page to their own memory, -// or use GetDBValueCopy to retrieve values -extern COptPage g_MessagesOptPage; -extern COptPage g_AutoreplyOptPage; -//extern COptPage g_PopupOptPage; -extern COptPage g_MoreOptPage; -extern COptPage g_SetAwayMsgPage; - -extern HINSTANCE g_hInstance; -extern HANDLE hMainThread; -extern int g_Messages_RecentRootID, g_Messages_PredefinedRootID; -extern VAR_PARSE_DATA VarParseData; -extern bool g_fNoProcessing; -extern int g_bIsIdle; - -// AwaySys.cpp -TCString GetDynamicStatMsg(HANDLE hContact, char *szProto = NULL, DWORD UIN = 0, int iStatus = 0); -int IsAnICQProto(char *szProto); - -// Client.cpp -void InitUpdateMsgs(); -void ChangeProtoMessages(char* szProto, int iMode, TCString &Msg); -int GetRecentGroupID(int iMode); -TCString VariablesEscape(TCString Str); - -// SetAwayMsg.cpp -INT_PTR CALLBACK SetAwayMsgDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - -// ReadAwayMsg.cpp -extern HANDLE g_hReadWndList; -INT_PTR GetContactStatMsg(WPARAM wParam, LPARAM lParam); - -// AwayOpt.cpp -int OptsDlgInit(WPARAM wParam, LPARAM lParam); // called on opening of the options dialog -void InitOptions(); // called once when plugin is loaded - -//int ShowPopupNotification(COptPage &PopupNotifyData, HANDLE hContact, int iStatusMode); -void ShowLog(TCString &LogFilePath); -void ShowMsg(TCHAR *szFirstLine, TCHAR *szSecondLine = _T(""), bool IsErrorMsg = false, int Timeout = 0); - -#define AWAYSYS_STATUSMSGREQUEST_SOUND "AwaySysStatusMsgRequest" -#define ME_AWAYSYS_WORKAROUND "AwaySys/_CallService" -int _Workaround_CallService(const char *name, WPARAM wParam, LPARAM lParam); - -// MsgEventAdded.cpp -int MsgEventAdded(WPARAM wParam, LPARAM lParam); - -// buttons -//void UpdateSOEButtons(HANDLE hContact = NULL); -INT_PTR ToggleSendOnEvent(WPARAM wParam, LPARAM lParam); -//int Create_TopToolbar(WPARAM wParam, LPARAM lParam); - - -static __inline int LogMessage(const char *Format, ...) -{ - va_list va; - char szText[8096]; - strcpy(szText, LOG_PREFIX); - va_start(va, Format); - mir_vsnprintf(szText + (lengthof(LOG_PREFIX) - 1), sizeof(szText) - (lengthof(LOG_PREFIX) - 1), Format, va); - va_end(va); - return CallService(MS_NETLIB_LOG, NULL, (LPARAM)szText); -} - -__inline int CallAllowedPS_SETAWAYMSG(const char *szProto, int iMode, const char *szMsg) -{ // we must use this function everywhere we want to call PS_SETAWAYMSG, otherwise NAS won't allow to change the message! - LogMessage("PS_SETAWAYMSG called by NAS. szProto=%s, Status=%d, Msg:\n%s", szProto, iMode, szMsg ? szMsg : "NULL"); - char str[MAXMODULELABELLENGTH]; - strcpy(str, szProto); - strcat(str, PS_SETAWAYMSG); - return CallService(str, (WPARAM)iMode, (LPARAM)szMsg); -} - -static __inline void my_variables_skin_helpbutton(HWND hwndDlg, UINT uIDButton) -{ - HICON hIcon = ServiceExists(MS_VARS_GETSKINITEM) ? (HICON)CallService(MS_VARS_GETSKINITEM, 0, (LPARAM)VSI_HELPICON) : NULL; - if (hIcon) - { - SendDlgItemMessage(hwndDlg, uIDButton, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); - } -} - -static __inline int my_variables_showhelp(HWND hwndDlg, UINT uIDEdit, int flags = 0, char *szSubjectDesc = NULL, char *szExtraDesc = NULL) -{ - if (ServiceExists(MS_VARS_SHOWHELPEX)) - { - VARHELPINFO vhi = {0}; - vhi.cbSize = sizeof(VARHELPINFO); - vhi.flags = flags ? flags : (VHF_FULLDLG | VHF_SETLASTSUBJECT); - vhi.hwndCtrl = GetDlgItem(hwndDlg, uIDEdit); - vhi.szSubjectDesc = szSubjectDesc; - vhi.szExtraTextDesc = szExtraDesc; - return CallService(MS_VARS_SHOWHELPEX, (WPARAM)hwndDlg, (LPARAM)&vhi); - } else - { - ShowMsg(TranslateT("New Away System"), TranslateT("Variables plugin is not installed"), true); - return -1; - } -} diff --git a/!Deprecated/NewAwaySysMod/ContactList.cpp b/!Deprecated/NewAwaySysMod/ContactList.cpp deleted file mode 100644 index 70b26d1d57..0000000000 --- a/!Deprecated/NewAwaySysMod/ContactList.cpp +++ /dev/null @@ -1,905 +0,0 @@ -/* - New Away System - plugin for Miranda IM - Copyright (c) 2005-2007 Chervov Dmitry - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "Common.h" -#include "ContactList.h" -#include "Properties.h" - -#define INTM_CONTACTDELETED (WM_USER + 1) -#define INTM_ICONCHANGED (WM_USER + 2) -#define INTM_INVALIDATE (WM_USER + 3) - -#define HCONTACT_ISGROUP 0x80000000 -#define HCONTACT_ISINFO 0xFFFF0000 -#define IsHContactInfo(h) (((unsigned)(h) & HCONTACT_ISINFO) == HCONTACT_ISINFO) -#define IsHContactGroup(h) (!IsHContactInfo(h) && ((unsigned)(h) & HCONTACT_ISGROUP)) -#define IsHContactContact(h) (((unsigned)(h) & HCONTACT_ISGROUP) == 0) - -#define EXTRAICON_XSTEP (GetSystemMetrics(SM_CXSMICON) + 1) - -static HANDLE hCLWindowList; - - -static int CLContactDeleted(WPARAM wParam, LPARAM lParam) -{ - WindowList_Broadcast(hCLWindowList, INTM_CONTACTDELETED, wParam, lParam); - return 0; -} - -static int CLContactIconChanged(WPARAM wParam, LPARAM lParam) -{ - WindowList_Broadcast(hCLWindowList, INTM_ICONCHANGED, wParam, lParam); - return 0; -} - -static int CLIconsChanged(WPARAM wParam, LPARAM lParam) -{ - WindowList_Broadcast(hCLWindowList, INTM_INVALIDATE, 0, 0); - return 0; -} - -void LoadCListModule() -{ - hCLWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); - HookEvent(ME_DB_CONTACT_DELETED, CLContactDeleted); - HookEvent(ME_CLIST_CONTACTICONCHANGED, CLContactIconChanged); - HookEvent(ME_SKIN_ICONSCHANGED, CLIconsChanged); -} - - -static LRESULT CALLBACK ParentSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - CCList *dat = CWndUserData(hWnd).GetCList(); - switch (Msg) - { - case WM_NOTIFY: - { - LPNMHDR pnmh = (LPNMHDR)lParam; - if (pnmh->hwndFrom == dat->hTreeView) - { - switch (pnmh->code) - { - case TVN_ITEMEXPANDED: // just set an appropriate group image - { - LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam; - TVITEM tvItem; - tvItem.hItem = pnmtv->itemNew.hItem; - tvItem.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; - tvItem.iImage = tvItem.iSelectedImage = (pnmtv->itemNew.state & TVIS_EXPANDED) ? IMAGE_GROUPOPEN : IMAGE_GROUPSHUT; - TreeView_SetItem(dat->hTreeView, &tvItem); - } break; - case TVN_SELCHANGED: - { - LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam; - TREEITEMARRAY OldSelection = dat->SelectedItems; - int I; - for (I = 0; I < dat->SelectedItems.GetSize(); I++) - { - if (dat->SelectedItems[I] != pnmtv->itemNew.hItem) - { - TreeView_SetItemState(dat->hTreeView, dat->SelectedItems[I], 0, TVIS_SELECTED); - } - } - dat->SelectedItems.RemoveAll(); - if (pnmtv->itemNew.hItem) - { - dat->SelectedItems.AddElem(pnmtv->itemNew.hItem); - dat->SelectGroups(pnmtv->itemNew.hItem, true); - } - NMCLIST nm; - nm.hdr.code = MCLN_SELCHANGED; - nm.hdr.hwndFrom = dat->hTreeView; - nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); - nm.OldSelection = &OldSelection; - nm.NewSelection = &dat->SelectedItems; - SendMessage(hWnd, WM_NOTIFY, 0, (LPARAM)&nm); - } break; - case TVN_DELETEITEM: - { - if (dat->Items.GetSize()) // if Items size = 0, then this TVN_DELETEITEM came after WM_DESTROY, so there is no need to do anything - { - LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam; - TREEITEMARRAY OldSelection = dat->SelectedItems; - int Index = dat->SelectedItems.Find(pnmtv->itemOld.hItem); - if (Index != -1) - { - dat->SelectedItems.RemoveElem(Index); - } - // find an item to pass to SelectGroups() - HTREEITEM hItem = TreeView_GetNextSibling(dat->hTreeView, pnmtv->itemOld.hItem); - if (!hItem) - { - hItem = TreeView_GetPrevSibling(dat->hTreeView, pnmtv->itemOld.hItem); - if (!hItem) - { - hItem = TreeView_GetParent(dat->hTreeView, pnmtv->itemOld.hItem); - } - } - if (hItem) // if it wasn't one of the root items - { - dat->SelectGroups(hItem, dat->SelectedItems.Find(hItem) != -1); - } - NMCLIST nm; - nm.hdr.code = MCLN_SELCHANGED; - nm.hdr.hwndFrom = dat->hTreeView; - nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); - nm.OldSelection = &OldSelection; - nm.NewSelection = &dat->SelectedItems; - SendMessage(hWnd, WM_NOTIFY, 0, (LPARAM)&nm); - dat->Items[pnmtv->itemOld.lParam].hContact = INVALID_HANDLE_VALUE; - } - } break; - case NM_CUSTOMDRAW: - { - LPNMTVCUSTOMDRAW lpNMCD = (LPNMTVCUSTOMDRAW)lParam; - switch (lpNMCD->nmcd.dwDrawStage) - { - case CDDS_PREPAINT: // the control is about to start painting - { - return CDRF_NOTIFYITEMDRAW; // instruct the control to return information when it draws items - } break; - case CDDS_ITEMPREPAINT: - { - return CDRF_NOTIFYPOSTPAINT; - } break; - case CDDS_ITEMPOSTPAINT: - { - RECT rc; - if (TreeView_GetItemRect(dat->hTreeView, (HTREEITEM)lpNMCD->nmcd.dwItemSpec, &rc, false)) - { - int I; - for (I = 0; I < MAXEXTRAICONS; I++) - { - BYTE nIndex = dat->Items[lpNMCD->nmcd.lItemlParam].ExtraIcons[I]; - if (nIndex != CLC_EXTRAICON_EMPTY) - { - ImageList_DrawEx(dat->ExtraImageList, nIndex, lpNMCD->nmcd.hdc, rc.right - EXTRAICON_XSTEP * (I + 1), rc.top, 0, 0, /*GetSysColor(COLOR_WINDOW)*/CLR_NONE, CLR_NONE, ILD_NORMAL); - } - } - } - } break; - } - } break; - } - } - } - } - return CallWindowProc(dat->OrigParentProc, hWnd, Msg, wParam, lParam); -} - - -static LRESULT CALLBACK ContactListSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - CCList *dat = CWndUserData(GetParent(hWnd)).GetCList(); - switch (Msg) - { - case INTM_CONTACTDELETED: // wParam = (HANDLE)hContact - { - HTREEITEM hItem = dat->FindContact((HANDLE)wParam); - if (hItem) - { - TreeView_DeleteItem(hWnd, hItem); - } - } break; - case INTM_ICONCHANGED: // wParam = (HANDLE)hContact, lParam = IconID - { - TVITEM tvi; - tvi.hItem = dat->FindContact((HANDLE)wParam); - if (tvi.hItem) - { - tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; - tvi.iImage = tvi.iSelectedImage = lParam; - TreeView_SetItem(hWnd, &tvi); - dat->SortContacts(); - InvalidateRect(hWnd, NULL, false); - } - } break; - case INTM_INVALIDATE: - { - InvalidateRect(hWnd, NULL, true); - } break; - case WM_RBUTTONDOWN: - { - SetFocus(hWnd); - TVHITTESTINFO hitTest; - hitTest.pt.x = (short)LOWORD(lParam); - hitTest.pt.y = (short)HIWORD(lParam); - TreeView_HitTest(hWnd, &hitTest); - if (hitTest.hItem && hitTest.flags & TVHT_ONITEM) - { - TreeView_SelectItem(hWnd, hitTest.hItem); - } - return DefWindowProc(hWnd, Msg, wParam, lParam); - } break; - case WM_LBUTTONDOWN: - { - POINT pt = {(short)LOWORD(lParam), (short)HIWORD(lParam)}; - DWORD hitFlags; - HTREEITEM hItem = dat->HitTest(&pt, &hitFlags); - if (!hItem) - { - break; - } - if (hitFlags & MCLCHT_ONITEMICON) - { - if (TreeView_GetChild(hWnd, hItem)) // if it's a group, then toggle its state - { - NMTREEVIEW nmtv; - nmtv.hdr.hwndFrom = hWnd; - nmtv.hdr.idFrom = GetDlgCtrlID(hWnd); - nmtv.hdr.code = TVN_ITEMEXPANDING; - nmtv.action = TVE_TOGGLE; - nmtv.itemNew.hItem = hItem; - nmtv.itemNew.mask = TVIF_HANDLE | TVIF_STATE | TVIF_PARAM; - TreeView_GetItem(hWnd, &nmtv.itemNew); - nmtv.ptDrag = pt; - if (SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nmtv)) - { - return 0; - } - HTREEITEM hOldSelItem = TreeView_GetSelection(hWnd); - TreeView_Expand(hWnd, hItem, TVE_TOGGLE); - HTREEITEM hNewSelItem = TreeView_GetSelection(hWnd); - if (hNewSelItem != hOldSelItem) - { - TreeView_SetItemState(hWnd, hOldSelItem, (dat->SelectedItems.Find(hOldSelItem) == -1) ? 0 : TVIS_SELECTED, TVIS_SELECTED); - TreeView_SetItemState(hWnd, hNewSelItem, (dat->SelectedItems.Find(hNewSelItem) == -1) ? 0 : TVIS_SELECTED, TVIS_SELECTED); - } - nmtv.hdr.code = TVN_ITEMEXPANDED; - TreeView_GetItem(hWnd, &nmtv.itemNew); - SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nmtv); - return 0; - } - } - if (hitFlags & MCLCHT_ONITEM) - { - if (wParam & MK_CONTROL) - { - SetFocus(hWnd); - TREEITEMARRAY OldSelection = dat->SelectedItems; - int nIndex = dat->SelectedItems.Find(hItem); - if (nIndex == -1) - { - TreeView_SetItemState(hWnd, hItem, TVIS_SELECTED, TVIS_SELECTED); - dat->SelectedItems.AddElem(hItem); - } else - { - TreeView_SetItemState(hWnd, hItem, 0, TVIS_SELECTED); - dat->SelectedItems.RemoveElem(nIndex); - } - dat->SelectGroups(hItem, nIndex == -1); - NMCLIST nm; - nm.hdr.code = MCLN_SELCHANGED; - nm.hdr.hwndFrom = hWnd; - nm.hdr.idFrom = GetDlgCtrlID(hWnd); - nm.OldSelection = &OldSelection; - nm.NewSelection = &dat->SelectedItems; - SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nm); - return 0; - } else - { - if (hItem == TreeView_GetSelection(hWnd) && (dat->SelectedItems.GetSize() != 1 || (dat->SelectedItems.GetSize() == 1 && dat->SelectedItems[0] != hItem))) // if it was a click on the selected item and there's need to do something in this case, then send SELCHANGED notification by ourselves, as the tree control doesn't do anything - { - TreeView_SetItemState(hWnd, hItem, TVIS_SELECTED, TVIS_SELECTED); - NMTREEVIEW nm = {0}; - nm.hdr.code = TVN_SELCHANGED; - nm.hdr.hwndFrom = hWnd; - nm.hdr.idFrom = GetDlgCtrlID(hWnd); - nm.itemOld.hItem = TreeView_GetSelection(hWnd); - nm.itemOld.mask = TVIF_HANDLE | TVIF_STATE | TVIF_PARAM; - TreeView_GetItem(hWnd, &nm.itemOld); - nm.itemNew = nm.itemOld; - SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nm); - } - } - } - } break; - case WM_SETFOCUS: - case WM_KILLFOCUS: - { - int I; - for (I = 0; I < dat->SelectedItems.GetSize(); I++) - { - RECT rc; - if (TreeView_GetItemRect(hWnd, dat->SelectedItems[I], &rc, false)) - { - InvalidateRect(hWnd, &rc, false); - } - } - } break; - case WM_SIZE: - case WM_HSCROLL: - { - InvalidateRect(hWnd, NULL, false); - } break; - case WM_MEASUREITEM: - { - if (!wParam) // if the message was sent by a menu - { - return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); - } - } break; - case WM_DRAWITEM: - { - if (!wParam) // if the message was sent by a menu - { - return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); - } - } break; - case WM_CONTEXTMENU: - { - POINT pt; - pt.x = (short)LOWORD(lParam); - pt.y = (short)HIWORD(lParam); - HTREEITEM hItem = NULL; - if (pt.x == -1 && pt.y == -1) - { - if (dat->SelectedItems.GetSize() == 1) - { - hItem = dat->SelectedItems[0]; - TreeView_EnsureVisible(hWnd, hItem); - RECT rc; - TreeView_GetItemRect(hWnd, hItem, &rc, true); - pt.x = rc.left; - pt.y = rc.bottom; - } - } else - { - DWORD hitFlags; - ScreenToClient(hWnd, &pt); - hItem = dat->HitTest(&pt, &hitFlags); - if (!(hitFlags & MCLCHT_ONITEM)) - { - hItem = NULL; - } - } - if (hItem) - { - HANDLE hContact = dat->GetItemData(hItem).hContact; - if (IsHContactContact(hContact)) - { - HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)hContact, 0); - if (hMenu) - { - ClientToScreen(hWnd, &pt); - CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, 0, hWnd, NULL), MPCF_CONTACTMENU), (LPARAM)hContact); - DestroyMenu(hMenu); - return 0; - } - } - } - } break; - case WM_DESTROY: - { - if (dat->ExtraImageList) - { - ImageList_Destroy(dat->ExtraImageList); - } - dat->SelectedItems.RemoveAll(); - dat->Items.RemoveAll(); - } break; - } - return CallWindowProc(dat->OrigTreeViewProc, hWnd, Msg, wParam, lParam); -} - - -CCList::CCList(HWND hTreeView): hTreeView(hTreeView), ExtraImageList(NULL) -{ - CWndUserData(GetParent(hTreeView)).SetCList(this); - OrigTreeViewProc = (WNDPROC)SetWindowLongPtr(hTreeView, GWLP_WNDPROC, (LONG_PTR)ContactListSubclassProc); - OrigParentProc = (WNDPROC)SetWindowLongPtr(GetParent(hTreeView), GWLP_WNDPROC, (LONG_PTR)ParentSubclassProc); - TreeView_SetImageList(hTreeView, CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0), TVSIL_NORMAL); - WindowList_Add(hCLWindowList, hTreeView, NULL); - TreeView_SetIndent(hTreeView, 5); // doesn't set it less than the initial value on my system, and I guess it's because of icons... but who knows - maybe it will work somewhere -} - - -CCList::~CCList() -{ - WindowList_Remove(hCLWindowList, hTreeView); - _ASSERT(GetWindowLongPtr(GetParent(hTreeView), GWLP_WNDPROC) == (LONG_PTR)ParentSubclassProc); // we won't allow anyone to change our WNDPROC. otherwise we're not sure that we're setting the right WNDPROC back - SetWindowLongPtr(hTreeView, GWLP_WNDPROC, (LONG_PTR)OrigTreeViewProc); - SetWindowLongPtr(GetParent(hTreeView), GWLP_WNDPROC, (LONG_PTR)OrigParentProc); - CWndUserData(GetParent(hTreeView)).SetCList(NULL); -} - - -HTREEITEM CCList::AddContact(HANDLE hContact) -// adds a new contact if it doesn't exist yet; returns its hItem -{ - _ASSERT(IsHContactContact(hContact)); - HTREEITEM hContactItem = FindContact(hContact); - if (hContactItem) - { - return hContactItem; - } - TVINSERTSTRUCT tvIns; - ZeroMemory(&tvIns, sizeof(tvIns)); - tvIns.hParent = AddGroup(DBGetContactSettingString(hContact, "CList", "Group", _T(""))); -/* if (!tvIns.hParent) - { - return NULL; - }*/ // <- place hidden contacts in the root anyway, as otherwise we won't see icq contacts that are hidden beneath metacontacts; TODO: show metacontacts as groups?? - tvIns.item.pszText = (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR); - tvIns.hInsertAfter = TVI_ROOT; - tvIns.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; - tvIns.item.iImage = tvIns.item.iSelectedImage = CallService(MS_CLIST_GETCONTACTICON, (WPARAM)hContact, 0); - tvIns.item.lParam = Items.AddElem(CCLItemData(hContact)); - return TreeView_InsertItem(hTreeView, &tvIns); -} - - -typedef struct -{ - HANDLE hGroup; - TCString GroupName; -} sGroupEnumData; - -int GroupEnum(const char *szSetting, LPARAM lParam) -{ - sGroupEnumData *GroupEnumData = (sGroupEnumData*)lParam; - TCString GroupName = DBGetContactSettingString(NULL, "CListGroups", szSetting, _T(" ")); - if (!lstrcmp(GroupEnumData->GroupName, &GroupName[1])) - { - GroupEnumData->hGroup = (HANDLE)(atol(szSetting) | HCONTACT_ISGROUP); - } - return 0; -} - -HTREEITEM CCList::AddGroup(TCString GroupName) -// adds a new group if it doesn't exist yet; returns its hItem -{ - if (GroupName == _T("")) - { - return TVI_ROOT; - } - sGroupEnumData GroupEnumData; - GroupEnumData.GroupName = GroupName; - GroupEnumData.hGroup = NULL; - DBCONTACTENUMSETTINGS dbEnum; - ZeroMemory(&dbEnum, sizeof(dbEnum)); - dbEnum.lParam = (LPARAM)&GroupEnumData; - dbEnum.pfnEnumProc = GroupEnum; - dbEnum.szModule = "CListGroups"; - CallService(MS_DB_CONTACT_ENUMSETTINGS, NULL, (LPARAM)&dbEnum); - if (!GroupEnumData.hGroup) // means there is no such group in the groups list - { - return NULL; - } - HTREEITEM hGroupItem = FindContact(GroupEnumData.hGroup); - if (hGroupItem) - { - return hGroupItem; // exists already, just return its handle - } - TVINSERTSTRUCT tvIns = {0}; - tvIns.hParent = TVI_ROOT; - tvIns.item.pszText = _tcsrchr(GroupName, '\\'); - if (tvIns.item.pszText) - { - TCString ParentGroupName(_T("")); - tvIns.hParent = AddGroup(ParentGroupName.DiffCat(GroupName, tvIns.item.pszText)); - tvIns.item.pszText++; - } else - { - tvIns.item.pszText = GroupName; - } - tvIns.hInsertAfter = TVI_ROOT; - tvIns.item.mask = TVIF_TEXT | TVIF_STATE | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; - tvIns.item.state = tvIns.item.stateMask = TVIS_BOLD | TVIS_EXPANDED; - tvIns.item.iImage = tvIns.item.iSelectedImage = IMAGE_GROUPOPEN; - tvIns.item.lParam = Items.AddElem(CCLItemData(GroupEnumData.hGroup)); - return TreeView_InsertItem(hTreeView, &tvIns); -} - - -HTREEITEM CCList::AddInfo(TCString Title, HTREEITEM hParent, HTREEITEM hInsertAfter, LPARAM lParam, HICON hIcon) -{ - TVINSERTSTRUCT tvi = {0}; - tvi.item.mask = TVIF_TEXT | TVIF_STATE | TVIF_PARAM; - tvi.item.pszText = Title; - tvi.hParent = hParent; - tvi.hInsertAfter = hInsertAfter; - tvi.item.lParam = Items.AddElem(CCLItemData()); - Items[tvi.item.lParam].lParam = lParam; - tvi.item.state = tvi.item.stateMask = TVIS_BOLD | TVIS_EXPANDED; - if (hIcon) - { - HIMAGELIST iml = TreeView_GetImageList(hTreeView, TVSIL_NORMAL); - tvi.item.mask |= TVIF_IMAGE | TVIF_SELECTEDIMAGE; - tvi.item.iImage = tvi.item.iSelectedImage = ImageList_AddIcon(iml, hIcon); // we don't check for duplicate icons, but I think that's ok, judging that the check will require some pretty significant amount of additional coding - TreeView_SetImageList(hTreeView, iml, TVSIL_NORMAL); - } - return TreeView_InsertItem(hTreeView, &tvi); -} - - -void CCList::SetInfoIcon(HTREEITEM hItem, HICON hIcon) -{ - _ASSERT(hItem && hIcon && GetItemType(hItem) == MCLCIT_INFO); - TVITEM tvi = {0}; - tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; - tvi.hItem = hItem; - HIMAGELIST iml = TreeView_GetImageList(hTreeView, TVSIL_NORMAL); - tvi.iImage = tvi.iSelectedImage = ImageList_AddIcon(iml, hIcon); // again, we don't check for duplicate icons - TreeView_SetImageList(hTreeView, iml, TVSIL_NORMAL); - TreeView_SetItem(hTreeView, &tvi); -} - - -static int CALLBACK CompareItemsCallback(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) -{ - CCList *dat = (CCList*)lParamSort; - if (IsHContactInfo(dat->Items[lParam1].hContact)) // Info items precede all other items - { - return (IsHContactInfo(dat->Items[lParam2].hContact)) ? 0 : -1; - } else if (IsHContactInfo(dat->Items[lParam2].hContact)) - { - return 1; - } - if (IsHContactGroup(dat->Items[lParam1].hContact)) // groups precede contacts - { - if (IsHContactGroup(dat->Items[lParam2].hContact)) - { - return (unsigned)dat->Items[lParam1].hContact - (unsigned)dat->Items[lParam2].hContact; - } else - { - return -1; - } - } else if (IsHContactGroup(dat->Items[lParam2].hContact)) - { - return 1; - } - return CallService(MS_CLIST_CONTACTSCOMPARE, (WPARAM)dat->Items[lParam1].hContact, (LPARAM)dat->Items[lParam2].hContact); -} - -void CCList::SortContacts() -{ - TVSORTCB tvSort; - ZeroMemory(&tvSort, sizeof(tvSort)); - tvSort.lpfnCompare = CompareItemsCallback; - tvSort.hParent = TVI_ROOT; - tvSort.lParam = (LPARAM)this; - while (tvSort.hParent) - { - TreeView_SortChildrenCB(hTreeView, &tvSort, 0); - tvSort.hParent = GetNextItem(MCLGN_NEXT | MCLGN_GROUP | MCLGN_MULTILEVEL, tvSort.hParent); - } -} - - -int CCList::GetExtraImage(HTREEITEM hItem, int iColumn) // returns iImage, or CLC_EXTRAICON_EMPTY -{ - _ASSERT(iColumn < MAXEXTRAICONS); - return GetItemData(hItem).ExtraIcons[iColumn]; -} - - -void CCList::SetExtraImage(HTREEITEM hItem, int iColumn, int iImage) // set iImage to CLC_EXTRAICON_EMPTY to reset image -{ - _ASSERT(iColumn < MAXEXTRAICONS); - GetItemData(hItem).ExtraIcons[iColumn] = iImage; - RECT rc; - if (TreeView_GetItemRect(hTreeView, hItem, &rc, false)) - { - InvalidateRect(hTreeView, &rc, true); - } -} - - -void CCList::SetExtraImageList(HIMAGELIST hImgList) -{ - ExtraImageList = hImgList; - InvalidateRect(hTreeView, NULL, false); -} - - -int CCList::GetItemType(HTREEITEM hItem) // returns a MCLCIT_ (see below) -{ - HANDLE hContact = GetItemData(hItem).hContact; - return (IsHContactInfo(hContact)) ? MCLCIT_INFO : ((IsHContactGroup(hContact)) ? MCLCIT_GROUP : MCLCIT_CONTACT); -} - - -DWORD CCList::GetItemTypeAsCLGNFlag(HTREEITEM hItem) -{ - HANDLE hContact = GetItemData(hItem).hContact; - return (IsHContactInfo(hContact)) ? MCLGN_INFO : ((IsHContactGroup(hContact)) ? MCLGN_GROUP : MCLGN_CONTACT); -} - - -HTREEITEM CCList::GetNextItem(DWORD Flags, HTREEITEM hItem) -{ - switch (Flags & ~(MCLGN_MULTILEVEL | MCLGN_NOTCHILD | MCLGN_ANY)) - { - case MCLGN_ROOT: - { - return TreeView_GetRoot(hTreeView); - } break; - case MCLGN_LAST: - { - HTREEITEM hNextItem = TVI_ROOT; - do - { - hItem = hNextItem; - hNextItem = TreeView_GetLastChild(hTreeView, hNextItem); - } while (hNextItem); - return (hItem == TVI_ROOT) ? NULL : hItem; - } break; - case MCLGN_CHILD: - { - return TreeView_GetChild(hTreeView, hItem); - } break; - case MCLGN_LASTCHILD: - { - return TreeView_GetLastChild(hTreeView, hItem); - } break; - case MCLGN_PARENT: - { - return TreeView_GetParent(hTreeView, hItem); - } break; - case MCLGN_NEXT: - { - do - { - if (Flags & MCLGN_MULTILEVEL) - { - HTREEITEM hNextItem = NULL; - if ((Flags & MCLGN_NOTCHILD) != MCLGN_NOTCHILD) - { - hNextItem = TreeView_GetChild(hTreeView, hItem); - } - if (!hNextItem) - { - hNextItem = TreeView_GetNextSibling(hTreeView, hItem); - while (!hNextItem) // move back until we find next sibling of the item or one of its parents - { - hItem = TreeView_GetParent(hTreeView, hItem); - if (!hItem) // means it was the root, there are no items left. - { - break; // returns NULL as the next item - } - hNextItem = TreeView_GetNextSibling(hTreeView, hItem); - } - } - hItem = hNextItem; - } else - { - hItem = TreeView_GetNextSibling(hTreeView, hItem); - } - Flags &= ~(MCLGN_NOTCHILD & ~MCLGN_MULTILEVEL); // clear MCLGN_NOTCHILD flag - } while (hItem && !(Flags & GetItemTypeAsCLGNFlag(hItem))); - return hItem; - } break; - case MCLGN_PREV: - { - do - { - if (Flags & MCLGN_MULTILEVEL) - { - HTREEITEM hNextItem = TreeView_GetPrevSibling(hTreeView, hItem); - if (hNextItem) - { - if ((Flags & MCLGN_NOTCHILD) != MCLGN_NOTCHILD) - { - while (hNextItem) - { - hItem = hNextItem; - hNextItem = TreeView_GetLastChild(hTreeView, hItem); - } - } else - { - hItem = hNextItem; - } - } else - { - hItem = TreeView_GetParent(hTreeView, hItem); - } - } else - { - hItem = TreeView_GetPrevSibling(hTreeView, hItem); - } - Flags &= ~(MCLGN_NOTCHILD & ~MCLGN_MULTILEVEL); // clear MCLGN_NOTCHILD flag - } while (hItem && !(Flags & GetItemTypeAsCLGNFlag(hItem))); - return hItem; - } break; - default: - { - _ASSERT(0); - } break; - } - return NULL; -} - - -HANDLE CCList::GethContact(HTREEITEM hItem) // returns hContact, hGroup or hInfo -{ - HANDLE hContact = GetItemData(hItem).hContact; - if (IsHContactContact(hContact)) - { - return hContact; - } else if (IsHContactGroup(hContact)) - { - return (HANDLE)((int)hContact & ~HCONTACT_ISGROUP); - } else - { - return (HANDLE)((int)hContact & ~HCONTACT_ISINFO); - } -} - - -HTREEITEM CCList::HitTest(LPPOINT pt, PDWORD hitFlags) // pt is relative to control; returns hItem or NULL -{ - TVHITTESTINFO hti; - hti.pt = *pt; - TreeView_HitTest(hTreeView, &hti); - *hitFlags = 0; - if (hti.flags & TVHT_ABOVE) - { - *hitFlags |= MCLCHT_ABOVE; - } - if (hti.flags & TVHT_BELOW) - { - *hitFlags |= MCLCHT_BELOW; - } - if (hti.flags & TVHT_TOLEFT) - { - *hitFlags |= MCLCHT_TOLEFT; - } - if (hti.flags & TVHT_TORIGHT) - { - *hitFlags |= MCLCHT_TORIGHT; - } - if (hti.flags & TVHT_NOWHERE) - { - *hitFlags |= MCLCHT_NOWHERE; - } - if (hti.flags & TVHT_ONITEMINDENT) - { - *hitFlags |= MCLCHT_ONITEMINDENT; - } - if (hti.flags & (TVHT_ONITEMICON | TVHT_ONITEMSTATEICON)) - { - *hitFlags |= MCLCHT_ONITEMICON; - } - if (hti.flags & TVHT_ONITEMLABEL) - { - *hitFlags |= MCLCHT_ONITEMLABEL; - } - if (hti.flags & TVHT_ONITEMRIGHT) - { - *hitFlags |= MCLCHT_ONITEMRIGHT; - } - if (hti.flags & (TVHT_ONITEMINDENT | TVHT_ONITEM | TVHT_ONITEMRIGHT)) - { - // extraicon tests - RECT rc; - if (TreeView_GetItemRect(hTreeView, hti.hItem, &rc, false)) - { - int nIndex = (rc.right - pt->x - 1) / EXTRAICON_XSTEP; - if (nIndex >= 0 && nIndex < MAXEXTRAICONS && GetItemData(hti.hItem).ExtraIcons[nIndex] != CLC_EXTRAICON_EMPTY) - { - *hitFlags |= MCLCHT_ONITEMEXTRA | (nIndex << 24); - } - } - } - return hti.hItem; -} - - -int CCList::Array_SetItemState(HTREEITEM hItem, bool bSelected) -{ - _ASSERT(hItem); - int nIndex = SelectedItems.Find(hItem); - if (nIndex == -1 && bSelected) - { - return SelectedItems.AddElem(hItem); - } else if (nIndex != -1 && !bSelected) - { - SelectedItems.RemoveElem(nIndex); - return -1; - } - return nIndex; -} - - -CCLItemData& CCList::GetItemData(HTREEITEM hItem) -{ - _ASSERT(hItem && hItem != INVALID_HANDLE_VALUE); - TVITEM tvi; - tvi.mask = TVIF_HANDLE | TVIF_PARAM; - tvi.hItem = hItem; - int Res = TreeView_GetItem(hTreeView, &tvi); - _ASSERT(Res); - return Items[tvi.lParam]; -} - - -HTREEITEM CCList::TreeView_GetLastChild(HWND hTreeView, HTREEITEM hItem) -{ - HTREEITEM hPrevItem = TreeView_GetChild(hTreeView, hItem); - hItem = hPrevItem; - while (hItem) // find last sibling - { - hPrevItem = hItem; - hItem = TreeView_GetNextSibling(hTreeView, hPrevItem); - } - return hPrevItem; -} - - -HTREEITEM CCList::FindContact(HANDLE hContact) -{ - TVITEM tvi; - tvi.mask = TVIF_HANDLE | TVIF_PARAM; - tvi.hItem = TreeView_GetRoot(hTreeView); - while (tvi.hItem) - { - TreeView_GetItem(hTreeView, &tvi); - if (Items[tvi.lParam].hContact == hContact) - { - return tvi.hItem; - } - tvi.hItem = GetNextItem(MCLGN_NEXT | MCLGN_ANY | MCLGN_MULTILEVEL, tvi.hItem); - } - return NULL; -} - - -void CCList::SelectGroups(HTREEITEM hCurItem, bool bSelected) -{ -// select/deselect all child items - HTREEITEM hItem = TreeView_GetChild(hTreeView, hCurItem); - HTREEITEM hLimitItem = GetNextItem(MCLGN_NEXT | MCLGN_ANY | MCLGN_NOTCHILD, hCurItem); - while (hItem && hItem != hLimitItem) - { - TreeView_SetItemState(hTreeView, hItem, bSelected ? TVIS_SELECTED : 0, TVIS_SELECTED); - Array_SetItemState(hItem, bSelected); - hItem = GetNextItem(MCLGN_NEXT | MCLGN_ANY | MCLGN_MULTILEVEL, hItem); - } -// select/deselect all parent groups - hCurItem = TreeView_GetParent(hTreeView, hCurItem); - if (bSelected) - { - while (hCurItem) // select until we'll find an unselected item or until we'll reach the root - { - hItem = TreeView_GetChild(hTreeView, hCurItem); - while (hItem) // walk through all siblings - { - if (!(TreeView_GetItemState(hTreeView, hItem, TVIS_SELECTED) & TVIS_SELECTED)) - { - break; - } - hItem = TreeView_GetNextSibling(hTreeView, hItem); - } - if (hItem) // means there was at least one unselected item - { - break; - } - TreeView_SetItemState(hTreeView, hCurItem, TVIS_SELECTED, TVIS_SELECTED); - Array_SetItemState(hCurItem, true); - hCurItem = TreeView_GetParent(hTreeView, hCurItem); - } - } - while (hCurItem) // and deselect all remaining parent groups - { - TreeView_SetItemState(hTreeView, hCurItem, 0, TVIS_SELECTED); - Array_SetItemState(hCurItem, false); - hCurItem = TreeView_GetParent(hTreeView, hCurItem); - } -} diff --git a/!Deprecated/NewAwaySysMod/ContactList.h b/!Deprecated/NewAwaySysMod/ContactList.h deleted file mode 100644 index 1730887954..0000000000 --- a/!Deprecated/NewAwaySysMod/ContactList.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - New Away System - plugin for Miranda IM - Copyright (c) 2005-2007 Chervov Dmitry - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -// Miranda's built-in CListControl is very slow and it has too limited functionality... 8( So I had to use my own control instead. - -#pragma once - -typedef TMyArray TREEITEMARRAY; -typedef TREEITEMARRAY* PTREEITEMARRAY; - - -#define CLC_EXTRAICON_EMPTY 0xFF -#define CLC_ROOT TVI_ROOT - -#define MAXEXTRAICONS 16 - -class CCLItemData // internal CCList's class -{ -public: - CCLItemData(HANDLE hContact = INVALID_HANDLE_VALUE): hContact(hContact) {FillMemory(ExtraIcons, sizeof(ExtraIcons), CLC_EXTRAICON_EMPTY);}; - - BYTE ExtraIcons[MAXEXTRAICONS]; - HANDLE hContact; - LPARAM lParam; -}; - -typedef TMyArray TREEITEMDATAARRAY; -typedef TREEITEMDATAARRAY* PTREEITEMDATAARRAY; - -class CCList -{ -public: - CCList(HWND hTreeView); - ~CCList(); - - HTREEITEM AddContact(HANDLE hContact); - HTREEITEM AddGroup(TCString GroupName); - HTREEITEM AddInfo(TCString Title, HTREEITEM hParent, HTREEITEM hInsertAfter, LPARAM lParam = NULL, HICON hIcon = NULL); - void SetInfoIcon(HTREEITEM hItem, HICON hIcon); - int GetExtraImage(HTREEITEM hItem, int iColumn); // returns iImage, or CLC_EXTRAICON_EMPTY - void SetExtraImage(HTREEITEM hItem, int iColumn, int iImage); // set iImage to CLC_EXTRAICON_EMPTY to reset image - void SetExtraImageList(HIMAGELIST hImgList); - int GetItemType(HTREEITEM hItem); // returns a MCLCIT_ (see below) - HTREEITEM GetNextItem(DWORD Flags, HTREEITEM hItem); - void SortContacts(); - HANDLE GethContact(HTREEITEM hItem); // returns hContact, hGroup or hInfo - HTREEITEM HitTest(LPPOINT pt, PDWORD hitFlags); // pt is relative to control; returns hItem or NULL - void EnsureVisible(HTREEITEM hItem) {TreeView_EnsureVisible(hTreeView, hItem); InvalidateRect(hTreeView, NULL, false);} // sometimes horizontal scrollbar position changes too, so we must redraw extra icons - that's why here is InvalidateRect. TODO: try to find a way to invalidate it on _every_ horizontal scrollbar position change, instead of just here - unfortunately the scrollbar doesn't notify the tree control of its position change through WM_HSCROLL in some cases - int SelectItem(HTREEITEM hItem) {return TreeView_SelectItem(hTreeView, hItem);} - void SetItemParam(HTREEITEM hItem, LPARAM lParam) {GetItemData(hItem).lParam = lParam;} - LPARAM GetItemParam(HTREEITEM hItem) {return GetItemData(hItem).lParam;} - PTREEITEMARRAY GetSelection() {return &SelectedItems;} - void SetRedraw(bool bRedraw) {SendMessage(hTreeView, WM_SETREDRAW, bRedraw, 0);} - - friend LRESULT CALLBACK ParentSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); - friend LRESULT CALLBACK ContactListSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); - friend int CALLBACK CompareItemsCallback(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); - -private: - int Array_SetItemState(HTREEITEM hItem, bool bSelected); - CCLItemData& GetItemData(HTREEITEM hItem); - HTREEITEM TreeView_GetLastChild(HWND hTreeView, HTREEITEM hItem); - HTREEITEM FindContact(HANDLE hContact); // returns NULL if not found - void SelectGroups(HTREEITEM hCurItem, bool bSelected); - DWORD GetItemTypeAsCLGNFlag(HTREEITEM hItem); // returns MCLGN_CONTACT, MCLGN_GROUP or MCLGN_INFO - - HWND hTreeView; - WNDPROC OrigTreeViewProc; - WNDPROC OrigParentProc; - TREEITEMDATAARRAY Items; // array that stores info for every tree item; array items are left even if corresponding tree item was deleted, so treeitem's lParam can be used as an index of an item in this array. - TREEITEMARRAY SelectedItems; // contains HTREEITEMs of all selected items - HIMAGELIST ExtraImageList; -}; - - -// HitTest constants -#define MCLCHT_ABOVE 0x0001 // above the client area -#define MCLCHT_BELOW 0x0002 // below the client area -#define MCLCHT_TOLEFT 0x0004 // to the left of the client area -#define MCLCHT_TORIGHT 0x0008 // to the right of the client area -#define MCLCHT_NOWHERE 0x0010 // in the client area, but below the last item -#define MCLCHT_ONITEMINDENT 0x0020 // to the left of an item icon -#define MCLCHT_ONITEMICON 0x0040 -#define MCLCHT_ONITEMLABEL 0x0080 -#define MCLCHT_ONITEMRIGHT 0x0100 // in the area to the right of an item -#define MCLCHT_ONITEMEXTRA 0x0200 // on an extra icon, HIBYTE(HIWORD(hitFlags)) says which -#define MCLCHT_ONITEM (MCLCHT_ONITEMICON | MCLCHT_ONITEMLABEL) - -// item types -#define MCLCIT_GROUP 0 -#define MCLCIT_CONTACT 1 -#define MCLCIT_INFO 3 - -// GetNextItem constants -#define MCLGN_ROOT 0 -#define MCLGN_LAST 1 -#define MCLGN_CHILD 2 -#define MCLGN_LASTCHILD 3 -#define MCLGN_PARENT 4 -#define MCLGN_NEXT 5 -#define MCLGN_PREV 6 -// flags for use with MCLGN_NEXT and MCLGN_PREV: -#define MCLGN_CONTACT 0x20 // you need to specify at least one of these three! otherwise GetNextItem will not find anything -#define MCLGN_GROUP 0x40 -#define MCLGN_INFO 0x80 -#define MCLGN_ANY (MCLGN_CONTACT | MCLGN_GROUP | MCLGN_INFO) -#define MCLGN_MULTILEVEL 0x100 // walk through items of different levels too (ex.: MCLGN_NEXT | MCLGN_MULTILEVEL) -#define MCLGN_NOTCHILD (0x200 | MCLGN_MULTILEVEL) // when this flag is set, child items of specified hItem are ignored. for example, MCLGN_NEXT | MCLGN_CONTACT | MCLGN_NOTCHILD retrieves next contact that is not a child of hItem. -// GetNextItem(MCLGN_PREV | MCLGN_ALL | MCLGN_NOTCHILD, CLM_GETNEXTITEM(MCLGN_NEXT | MCLGN_ALL | MCLGN_NOTCHILD, hItem) === hItem - - -// notifications - -typedef struct -{ - NMHDR hdr; - PTREEITEMARRAY OldSelection, NewSelection; -} NMCLIST; -typedef NMCLIST* PNMCLIST; - -#define MCLN_FIRST (0U - 100U) - -#define MCLN_SELCHANGED (MCLN_FIRST - 20) // lParam = &NMCLIST; OldSelection and NewSelection contain selection info - - -void LoadCListModule(); diff --git a/!Deprecated/NewAwaySysMod/Images/Delete.ico b/!Deprecated/NewAwaySysMod/Images/Delete.ico deleted file mode 100644 index b44da83dbc..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/Delete.ico and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/Images/DisableNotify.ico b/!Deprecated/NewAwaySysMod/Images/DisableNotify.ico deleted file mode 100644 index 5df846b34e..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/DisableNotify.ico and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/Images/Dot.ico b/!Deprecated/NewAwaySysMod/Images/Dot.ico deleted file mode 100644 index 12ffcb1997..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/Dot.ico and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/Images/EnableNotify.ico b/!Deprecated/NewAwaySysMod/Images/EnableNotify.ico deleted file mode 100644 index da4e6af1c0..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/EnableNotify.ico and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/Images/Ignore.ico b/!Deprecated/NewAwaySysMod/Images/Ignore.ico deleted file mode 100644 index 1ba34d7244..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/Ignore.ico and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/Images/Indefinite.ico b/!Deprecated/NewAwaySysMod/Images/Indefinite.ico deleted file mode 100644 index fb895622ff..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/Indefinite.ico and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/Images/MsgIcon.ico b/!Deprecated/NewAwaySysMod/Images/MsgIcon.ico deleted file mode 100644 index 7880f71a70..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/MsgIcon.ico and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/Images/NewCat.ico b/!Deprecated/NewAwaySysMod/Images/NewCat.ico deleted file mode 100644 index c6d213b289..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/NewCat.ico and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/Images/NewMessage.ico b/!Deprecated/NewAwaySysMod/Images/NewMessage.ico deleted file mode 100644 index 1ba04c8d6a..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/NewMessage.ico and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/Images/SaveAsNew.ico b/!Deprecated/NewAwaySysMod/Images/SaveAsNew.ico deleted file mode 100644 index 6954faa978..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/SaveAsNew.ico and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/Images/SaveMsg.ico b/!Deprecated/NewAwaySysMod/Images/SaveMsg.ico deleted file mode 100644 index e972db2923..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/SaveMsg.ico and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/Images/Settings.ico b/!Deprecated/NewAwaySysMod/Images/Settings.ico deleted file mode 100644 index ddb72fb8ca..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/Settings.ico and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/Images/Status_Other.ico b/!Deprecated/NewAwaySysMod/Images/Status_Other.ico deleted file mode 100644 index 922d911bbb..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/Status_Other.ico and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/Images/Variables.ico b/!Deprecated/NewAwaySysMod/Images/Variables.ico deleted file mode 100644 index 7fd7196664..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/Variables.ico and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/Images/off.bmp b/!Deprecated/NewAwaySysMod/Images/off.bmp deleted file mode 100644 index fcc9507634..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/off.bmp and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/Images/off.ico b/!Deprecated/NewAwaySysMod/Images/off.ico deleted file mode 100644 index 0facbfa29f..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/off.ico and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/Images/on.bmp b/!Deprecated/NewAwaySysMod/Images/on.bmp deleted file mode 100644 index cf7343ef31..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/on.bmp and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/Images/on.ico b/!Deprecated/NewAwaySysMod/Images/on.ico deleted file mode 100644 index f236715870..0000000000 Binary files a/!Deprecated/NewAwaySysMod/Images/on.ico and /dev/null differ diff --git a/!Deprecated/NewAwaySysMod/MsgEventAdded.cpp b/!Deprecated/NewAwaySysMod/MsgEventAdded.cpp deleted file mode 100644 index a8219e7bd7..0000000000 --- a/!Deprecated/NewAwaySysMod/MsgEventAdded.cpp +++ /dev/null @@ -1,317 +0,0 @@ -/* - New Away System - plugin for Miranda IM - Copyright (C) 2005-2007 Chervov Dmitry - Copyright (C) 2004-2005 Iksaif Entertainment - Copyright (C) 2002-2003 Goblineye Entertainment - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "Common.h" -#include "Properties.h" - -// stupid compiler.. kept returning me an "INTERNAL COMPILER ERROR" on almost every line of MsgEventAdded function with Release mode and unicode enabled >:( even disabling optimization through #pragma optimize didn't help.. The only acceptable solution I found is to move this function to a separate file and to disable optimization for the whole file in the project properties. - -static struct -{ - int Status, DisableReplyCtlID, DontShowDialogCtlID; -} StatusModeList[] = { - ID_STATUS_ONLINE, IDC_REPLYDLG_DISABLE_ONL, IDC_MOREOPTDLG_DONTPOPDLG_ONL, - ID_STATUS_AWAY, IDC_REPLYDLG_DISABLE_AWAY, IDC_MOREOPTDLG_DONTPOPDLG_AWAY, - ID_STATUS_NA, IDC_REPLYDLG_DISABLE_NA, IDC_MOREOPTDLG_DONTPOPDLG_NA, - ID_STATUS_OCCUPIED, IDC_REPLYDLG_DISABLE_OCC, IDC_MOREOPTDLG_DONTPOPDLG_OCC, - ID_STATUS_DND, IDC_REPLYDLG_DISABLE_DND, IDC_MOREOPTDLG_DONTPOPDLG_DND, - ID_STATUS_FREECHAT, IDC_REPLYDLG_DISABLE_FFC, IDC_MOREOPTDLG_DONTPOPDLG_FFC, - ID_STATUS_INVISIBLE, IDC_REPLYDLG_DISABLE_INV, IDC_MOREOPTDLG_DONTPOPDLG_INV, - ID_STATUS_ONTHEPHONE, IDC_REPLYDLG_DISABLE_OTP, IDC_MOREOPTDLG_DONTPOPDLG_OTP, - ID_STATUS_OUTTOLUNCH, IDC_REPLYDLG_DISABLE_OTL, IDC_MOREOPTDLG_DONTPOPDLG_OTL -}; - - -class CAutoreplyData -{ -public: - CAutoreplyData(HANDLE hContact, TCString Reply): hContact(hContact), Reply(Reply) {} - - HANDLE hContact; - TCString Reply; -}; - - -void __cdecl AutoreplyDelayThread(void *_ad) -{ // _ad must be allocated using "new CAutoreplyData()" - CAutoreplyData *ad = (CAutoreplyData*)_ad; - _ASSERT(ad && ad->hContact && ad->Reply.GetLen()); - char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ad->hContact, 0); - if (!szProto) - { - _ASSERT(0); - return; - } - - int ReplyLen = (ad->Reply.GetLen() + 1) * (sizeof(char) + sizeof(WCHAR)); - PBYTE pBuf = (PBYTE)malloc(ReplyLen); - memcpy(pBuf, TCHAR2ANSI(ad->Reply), ad->Reply.GetLen() + 1); - memcpy(pBuf + ad->Reply.GetLen() + 1, ad->Reply, (ad->Reply.GetLen() + 1) * sizeof(WCHAR)); - CallContactService(ad->hContact, ServiceExists(CString(szProto) + PSS_MESSAGE "W") ? (PSS_MESSAGE "W") : PSS_MESSAGE, PREF_UNICODE, (LPARAM)pBuf); - - if (g_AutoreplyOptPage.GetDBValueCopy(IDC_REPLYDLG_LOGREPLY)) - { // store in the history - DBEVENTINFO dbeo = {0}; - dbeo.cbSize = sizeof(dbeo); - dbeo.eventType = EVENTTYPE_MESSAGE; - dbeo.flags = DBEF_SENT; - dbeo.szModule = szProto; - dbeo.timestamp = time(NULL); - - dbeo.cbBlob = ReplyLen; - dbeo.pBlob = pBuf; - - SleepEx(1000, true); // delay before sending the reply, as we need it to be later than the message we're replying to (without this delay, srmm puts the messages in a wrong order) - CallService(MS_DB_EVENT_ADD, (WPARAM)ad->hContact, (LPARAM)&dbeo); - } - - free(pBuf); - -/* - char *utf8Reply = mir_utf8encodeT(ad->Reply); // todo: use this instead of the code above, when 0.7 will be released - if (g_AutoreplyOptPage.GetDBValueCopy(IDC_REPLYDLG_LOGREPLY)) - { // store in the history - DBEVENTINFO dbeo = {0}; - dbeo.cbSize = sizeof(dbeo); - dbeo.eventType = EVENTTYPE_MESSAGE; - dbeo.flags = DBEF_SENT | DBEF_UTF; - dbeo.szModule = szProto; - dbeo.timestamp = time(NULL); - dbeo.cbBlob = strlen(utf8Reply); - dbeo.pBlob = utf8Reply; - CallService(MS_DB_EVENT_ADD, (WPARAM)ad->hContact, (LPARAM)&dbeo); - } - CallContactService(ad->hContact, ServiceExists(CString(szProto) + PSS_MESSAGE "W") ? (PSS_MESSAGE "W") : PSS_MESSAGE, PREF_UTF, (LPARAM)utf8Reply); - mir_free(utf8Reply); -*/ - delete ad; -} - - -int IsSRMsgWindowOpen(HANDLE hContact, int DefaultRetVal) -{ - if (ServiceExists(MS_MSG_GETWINDOWDATA)) - { - MessageWindowData mwd = {0}; - mwd.cbSize = sizeof(mwd); - MessageWindowInputData mwid = {0}; - mwid.cbSize = sizeof(mwid); - mwid.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH; - mwid.hContact = hContact; - return !CallService(MS_MSG_GETWINDOWDATA, (WPARAM)&mwid, (LPARAM)&mwd) && mwd.hwndWindow; - } else - { - return DefaultRetVal; - } -} - - -#define MAX_REPLY_TIMEDIFF 5 // maximum "age" of an event to remain unfiltered; in seconds -#define MSGWNDOPEN_UNDEFINED (-1) - -class CMetacontactEvent -{ -public: - CMetacontactEvent(HANDLE hMetaContact, DWORD timestamp, int bMsgWindowIsOpen): hMetaContact(hMetaContact), timestamp(timestamp), bMsgWindowIsOpen(bMsgWindowIsOpen) {}; - - HANDLE hMetaContact; - DWORD timestamp; - int bMsgWindowIsOpen; -}; - -TMyArray MetacontactEvents; - - -int MsgEventAdded(WPARAM wParam, LPARAM lParam) -{ - HANDLE hContact = (HANDLE)wParam; - DBEVENTINFO *dbei = (DBEVENTINFO*)lParam; - if (!hContact) - { - return 0; - } - if (dbei->flags & DBEF_SENT || (dbei->eventType != EVENTTYPE_MESSAGE && dbei->eventType != EVENTTYPE_URL && dbei->eventType != EVENTTYPE_FILE)) - { - return 0; - } - if (time(NULL) - dbei->timestamp > MAX_REPLY_TIMEDIFF) - { // don't reply to offline messages - return 0; - } - char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - if (!szProto) - { - return 0; - } - DWORD Flags1 = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0); - if (!(Flags1 & PF1_IMSEND)) - { // don't reply to protocols that don't support outgoing messages - return 0; - } - int bMsgWindowIsOpen = MSGWNDOPEN_UNDEFINED; - if (dbei->flags & DBEF_READ) - { - HANDLE hMetaContact; - if (ServiceExists(MS_MC_GETMETACONTACT) && (hMetaContact = (HANDLE)CallService(MS_MC_GETMETACONTACT, (WPARAM)hContact, 0))) // if it's a subcontact of a metacontact - { // ugly workaround for metacontacts, part II - // remove outdated events first - DWORD CurTime = time(NULL); - int I; - for (I = MetacontactEvents.GetSize() - 1; I >= 0; I--) - { - if (CurTime - MetacontactEvents[I].timestamp > MAX_REPLY_TIMEDIFF) - { - MetacontactEvents.RemoveElem(I); - } - } - // we compare only event timestamps, and do not look at the message itself. it's unlikely that there'll be two events from a contact at the same second, so it's a trade-off between speed and reliability - for (I = MetacontactEvents.GetSize() - 1; I >= 0; I--) - { - if (MetacontactEvents[I].timestamp == dbei->timestamp && MetacontactEvents[I].hMetaContact == hMetaContact) - { - bMsgWindowIsOpen = MetacontactEvents[I].bMsgWindowIsOpen; - break; - } - } - if (I < 0) - { - _ASSERT(0); - return 0; - } - } else - { - return 0; - } - } - if (ServiceExists(MS_MC_GETPROTOCOLNAME) && !lstrcmpA(szProto, (char*)CallService(MS_MC_GETPROTOCOLNAME, 0, 0))) - { // ugly workaround for metacontacts, part I; store all metacontacts' events to a temporary array, so we'll be able to get the 'source' protocol when subcontact event happens later. we need the protocol to get its status and per-status settings properly - // remove outdated events first - DWORD CurTime = time(NULL); - int I; - for (I = MetacontactEvents.GetSize() - 1; I >= 0; I--) - { - if (CurTime - MetacontactEvents[I].timestamp > MAX_REPLY_TIMEDIFF) - { - MetacontactEvents.RemoveElem(I); - } - } - // add the new event and wait for a subcontact's event - MetacontactEvents.AddElem(CMetacontactEvent(hContact, dbei->timestamp, IsSRMsgWindowOpen(hContact, false))); - return 0; - } - unsigned int iMode = CallProtoService(szProto, PS_GETSTATUS, 0, 0); - int I; - for (I = lengthof(StatusModeList) - 1; I >= 0; I--) - { - if (iMode == StatusModeList[I].Status) - { - break; - } - } - if (I < 0) - { - return 0; - } - COptPage AutoreplyOptData(g_AutoreplyOptPage); - AutoreplyOptData.DBToMem(); - if (dbei->eventType == EVENTTYPE_MESSAGE) - { - DBWriteContactSettingWord(hContact, MOD_NAME, DB_MESSAGECOUNT, DBGetContactSettingWord(hContact, MOD_NAME, DB_MESSAGECOUNT, 0) + 1); // increment message counter - } - if (AutoreplyOptData.GetValue(StatusModeList[I].DisableReplyCtlID)) - { - return 0; - } - HANDLE hContactForSettings = hContact; // used to take into account not-on-list contacts when getting contact settings, but at the same time allows to get correct contact info for contacts that are in the DB - if (hContactForSettings != INVALID_HANDLE_VALUE && DBGetContactSettingByte(hContactForSettings, "CList", "NotOnList", 0)) - { - hContactForSettings = INVALID_HANDLE_VALUE; // INVALID_HANDLE_VALUE means the contact is not-on-list - } - if (!CContactSettings(iMode, hContactForSettings).Autoreply.IncludingParents(szProto) || CContactSettings(iMode, hContactForSettings).Ignore) - { - return 0; - } - if (AutoreplyOptData.GetValue(IDC_REPLYDLG_DONTREPLYINVISIBLE)) - { - WORD ApparentMode = DBGetContactSettingWord(hContact, szProto, "ApparentMode", 0); - if ((iMode == ID_STATUS_INVISIBLE && (!(Flags1 & PF1_INVISLIST) || ApparentMode != ID_STATUS_ONLINE)) || - (Flags1 & PF1_VISLIST && ApparentMode == ID_STATUS_OFFLINE)) - { - return 0; - } - } - if (AutoreplyOptData.GetValue(IDC_REPLYDLG_ONLYCLOSEDDLGREPLY)) - { - if (bMsgWindowIsOpen && bMsgWindowIsOpen != MSGWNDOPEN_UNDEFINED) - { - return 0; - } - // we never get here for a metacontact; we did check for metacontact's window earlier, and here we need to check only for subcontact's window - if (IsSRMsgWindowOpen(hContact, false)) - { - return 0; - } - } - if (AutoreplyOptData.GetValue(IDC_REPLYDLG_ONLYIDLEREPLY) && !g_bIsIdle) - { - return 0; - } - int UIN = 0; - if (IsAnICQProto(szProto)) - { - UIN = DBGetContactSettingDword(hContact, szProto, "UIN", 0); - } - int SendCount = AutoreplyOptData.GetValue(IDC_REPLYDLG_SENDCOUNT); - if ((AutoreplyOptData.GetValue(IDC_REPLYDLG_DONTSENDTOICQ) && UIN) || // an icq contact - (SendCount != -1 && DBGetContactSettingByte(hContact, MOD_NAME, DB_SENDCOUNT, 0) >= SendCount)) - { - return 0; - } - if ((dbei->eventType == EVENTTYPE_MESSAGE && !AutoreplyOptData.GetValue(IDC_REPLYDLG_EVENTMSG)) || (dbei->eventType == EVENTTYPE_URL && !AutoreplyOptData.GetValue(IDC_REPLYDLG_EVENTURL)) || (dbei->eventType == EVENTTYPE_FILE && !AutoreplyOptData.GetValue(IDC_REPLYDLG_EVENTFILE))) - { - return 0; - } - DBWriteContactSettingByte(hContact, MOD_NAME, DB_SENDCOUNT, DBGetContactSettingByte(hContact, MOD_NAME, DB_SENDCOUNT, 0) + 1); - GetDynamicStatMsg(hContact); // it updates VarParseData.Message needed for %extratext% in the format - TCString Reply(*(TCString*)AutoreplyOptData.GetValue(IDC_REPLYDLG_PREFIX)); - if (Reply != NULL && ServiceExists(MS_VARS_FORMATSTRING) && !g_SetAwayMsgPage.GetDBValueCopy(IDS_SAWAYMSG_DISABLEVARIABLES)) - { - FORMATINFO fi = {0}; - fi.cbSize = sizeof(FORMATINFO); - fi.tszFormat = Reply; - fi.hContact = hContact; - fi.flags = FIF_TCHAR; - fi.tszExtraText = VarParseData.Message; - TCHAR *szResult = (TCHAR *)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0); - if (szResult != NULL) - { - Reply = szResult; - CallService(MS_VARS_FREEMEMORY, (WPARAM)szResult, 0); - } - } - if (Reply.GetLen()) - { - CAutoreplyData *ad = new CAutoreplyData(hContact, Reply); - mir_forkthread(AutoreplyDelayThread, ad); - } - return 0; -} - diff --git a/!Deprecated/NewAwaySysMod/MsgTree.cpp b/!Deprecated/NewAwaySysMod/MsgTree.cpp deleted file mode 100644 index c04665d33f..0000000000 --- a/!Deprecated/NewAwaySysMod/MsgTree.cpp +++ /dev/null @@ -1,790 +0,0 @@ -/* - New Away System - plugin for Miranda IM - Copyright (c) 2005-2007 Chervov Dmitry - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "Common.h" -#include "MsgTree.h" -#include "Properties.h" - -#define UM_MSGTREE_INIT (WM_USER + 0x2103) -#define UM_MSGTREE_UPDATE (WM_USER + 0x2104) - -#define MSGTREE_TIMER_ID 0x2103 -#define MSGTREE_DRAGANDDROP_GROUPEXPANDTIME 600 - -#define IMGLIST_NEWMESSAGE 0 -#define IMGLIST_NEWCATEGORY 1 -#define IMGLIST_DELETE 2 - -struct { - int DBSetting, Status, MenuItemID; -} StatusModeList[] = { - IDS_MESSAGEDLG_DEF_ONL, ID_STATUS_ONLINE, IDR_MSGTREEMENU_DEF_ONL, - IDS_MESSAGEDLG_DEF_AWAY, ID_STATUS_AWAY, IDR_MSGTREEMENU_DEF_AWAY, - IDS_MESSAGEDLG_DEF_NA, ID_STATUS_NA, IDR_MSGTREEMENU_DEF_NA, - IDS_MESSAGEDLG_DEF_OCC, ID_STATUS_OCCUPIED, IDR_MSGTREEMENU_DEF_OCC, - IDS_MESSAGEDLG_DEF_DND, ID_STATUS_DND, IDR_MSGTREEMENU_DEF_DND, - IDS_MESSAGEDLG_DEF_FFC, ID_STATUS_FREECHAT, IDR_MSGTREEMENU_DEF_FFC, - IDS_MESSAGEDLG_DEF_INV, ID_STATUS_INVISIBLE, IDR_MSGTREEMENU_DEF_INV, - IDS_MESSAGEDLG_DEF_OTP, ID_STATUS_ONTHEPHONE, IDR_MSGTREEMENU_DEF_OTP, - IDS_MESSAGEDLG_DEF_OTL, ID_STATUS_OUTTOLUNCH, IDR_MSGTREEMENU_DEF_OTL -}; - -static HANDLE hMTWindowList; -static WNDPROC g_OrigEditProc; - - -void LoadMsgTreeModule() -{ - hMTWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); -} - - -static LRESULT CALLBACK EditSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - switch (Msg) - { - case WM_GETDLGCODE: - { - return CallWindowProc(g_OrigEditProc, hWnd, Msg, wParam, lParam) | DLGC_WANTALLKEYS; - } break; - } - return CallWindowProc(g_OrigEditProc, hWnd, Msg, wParam, lParam); -} - -static LRESULT CALLBACK ParentSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - CMsgTree *dat = CWndUserData(hWnd).GetMsgTree(); - switch (Msg) - { - case WM_NOTIFY: - { - if (((LPNMHDR)lParam)->hwndFrom == dat->hTreeView) - { - switch (((LPNMHDR)lParam)->code) - { - case TVN_BEGINDRAGA: - case TVN_BEGINDRAGW: - { - LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam; - NMMSGTREE nm = {0}; - COptItem_TreeCtrl *TreeCtrl = dat->GetTreeCtrl(); - int Order = TreeCtrl->hItemToOrder(pnmtv->itemNew.hItem); - _ASSERT(Order != -1); - if (Order != -1) - { - nm.ItemOld = (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; - nm.hdr.code = MTN_BEGINDRAG; - nm.hdr.hwndFrom = dat->hTreeView; - nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); - if (!SendMessage(hWnd, WM_NOTIFY, 0, (LPARAM)&nm)) - { - SetCapture(hWnd); - dat->hPrevDropTarget = dat->hDragItem = pnmtv->itemNew.hItem; - SetFocus(dat->hTreeView); - TreeView_SelectItem(dat->hTreeView, dat->hDragItem); - } - } - } break; - case TVN_SELCHANGEDA: - case TVN_SELCHANGEDW: - { - if (dat->UpdateLock) - { - return 0; - } - LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam; - NMMSGTREE nm = {0}; - COptItem_TreeCtrl *TreeCtrl = dat->GetTreeCtrl(); - if (pnmtv->itemOld.hItem) - { - int Order = TreeCtrl->IDToOrder(pnmtv->itemOld.lParam); - if (Order != -1) - { - nm.ItemOld = (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; - } - } - if (pnmtv->itemNew.hItem) - { - int Order = TreeCtrl->IDToOrder(pnmtv->itemNew.lParam); - if (Order != -1) - { - nm.ItemNew = (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; - } - } - nm.hdr.code = MTN_SELCHANGED; - nm.hdr.hwndFrom = dat->hTreeView; - nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); - SendMessage(hWnd, WM_NOTIFY, 0, (LPARAM)&nm); - } break; - case TVN_BEGINLABELEDITA: - case TVN_BEGINLABELEDITW: - { - if (dat->GetTreeCtrl()->IDToOrder(((LPNMTVDISPINFO)lParam)->item.lParam) < 0) - { - return true; // cancel editing - } - g_OrigEditProc = (WNDPROC)SetWindowLongPtr(TreeView_GetEditControl(dat->hTreeView), GWLP_WNDPROC, (LONG_PTR)EditSubclassProc); - } break; -// case TVN_ENDLABELEDITA: // stupid miranda options.. how am I supposed to get ptvdi->item.pszText if it's in ANSI?? - case TVN_ENDLABELEDIT: - { - LPNMTVDISPINFO ptvdi = (LPNMTVDISPINFO)lParam; - if (ptvdi->item.pszText) - { - COptItem_TreeCtrl *TreeCtrl = dat->GetTreeCtrl(); - int Order = TreeCtrl->IDToOrder(ptvdi->item.lParam); - if (Order >= 0) - { - TreeCtrl->Value[Order].Title = ptvdi->item.pszText; - TreeCtrl->SetModified(true); - NMMSGTREE nm = {0}; - nm.ItemNew = &TreeCtrl->Value[Order]; - nm.hdr.code = MTN_ITEMRENAMED; - nm.hdr.hwndFrom = dat->hTreeView; - nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); - SendMessage(GetParent(dat->hTreeView), WM_NOTIFY, 0, (LPARAM)&nm); - return true; // commit new text - } - } - } break; - case NM_CLICK: - case NM_RCLICK: - { - TVHITTESTINFO hitTest; - hitTest.pt.x = (short)LOWORD(GetMessagePos()); - hitTest.pt.y = (short)HIWORD(GetMessagePos()); - ScreenToClient(dat->hTreeView, &hitTest.pt); - TreeView_HitTest(dat->hTreeView, &hitTest); - if (hitTest.hItem) - { - if (TreeView_GetSelection(dat->hTreeView) == hitTest.hItem) - { // make sure TVN_SELCHANGED notification is sent always, even if previous selected item was the same as new - TreeView_SelectItem(dat->hTreeView, NULL); - } - TreeView_SelectItem(dat->hTreeView, hitTest.hItem); - } - } break; - case NM_CUSTOMDRAW: - { - NMTVCUSTOMDRAW *lpNMCD = (NMTVCUSTOMDRAW*)lParam; - switch (lpNMCD->nmcd.dwDrawStage) - { - case CDDS_PREPAINT: // the control is about to start painting - { - return CDRF_NOTIFYITEMDRAW; // instruct the control to return information when it draws items - } break; - case CDDS_ITEMPREPAINT: - { - return CDRF_NOTIFYPOSTPAINT; - } break; - case CDDS_ITEMPOSTPAINT: - { - RECT rc; - TreeView_GetItemRect(lpNMCD->nmcd.hdr.hwndFrom, (HTREEITEM)lpNMCD->nmcd.dwItemSpec, &rc, true); - int iSize = GetSystemMetrics(SM_CXSMICON); - int I; - int x = rc.left - iSize - 5; - for (I = 0; I < lengthof(StatusModeList); I++) - { - if (lpNMCD->nmcd.lItemlParam == dat->MsgTreePage.GetValue(StatusModeList[I].DBSetting)) - { - DrawIconEx(lpNMCD->nmcd.hdc, x, rc.top, LoadSkinnedProtoIcon(NULL, StatusModeList[I].Status), iSize, iSize, 0, GetSysColorBrush(COLOR_WINDOW), DI_NORMAL); - x -= iSize + 1; - } -/* if (lpNMCD->nmcd.lItemlParam == GetRecentGroupID(StatusModeList[I].Status)) - { - DrawIconEx(lpNMCD->nmcd.hdc, 3, rc.top, LoadSkinnedProtoIcon(NULL, StatusModeList[I].Status), iSize, iSize, 0, GetSysColorBrush(COLOR_WINDOW), DI_NORMAL); - }*/ - } - } break; - } - } break; - } - } - } break; - case WM_MOUSEMOVE: - { - if (dat->hDragItem) - { - TVHITTESTINFO hti; - hti.pt.x = (short)LOWORD(lParam); - hti.pt.y = (short)HIWORD(lParam); - ClientToScreen(hWnd, &hti.pt); - ScreenToClient(dat->hTreeView, &hti.pt); - TreeView_HitTest(dat->hTreeView, &hti); - if (hti.hItem) - { - TreeView_SelectDropTarget(dat->hTreeView, hti.hItem); - SetTimer(hWnd, MSGTREE_TIMER_ID, MSGTREE_DRAGANDDROP_GROUPEXPANDTIME, NULL); - } else - { - if (hti.flags & TVHT_ABOVE) - { - SendMessage(dat->hTreeView, WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), 0); - } - if (hti.flags & TVHT_BELOW) - { - SendMessage(dat->hTreeView, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0); - } - TreeView_SelectDropTarget(dat->hTreeView, NULL); - KillTimer(hWnd, MSGTREE_TIMER_ID); - } - } - } break; - case WM_LBUTTONUP: - { - if (dat->hDragItem) - { - TreeView_SelectDropTarget(dat->hTreeView, NULL); - KillTimer(hWnd, MSGTREE_TIMER_ID); - ReleaseCapture(); - TVHITTESTINFO hti; - hti.pt.x = (short)LOWORD(lParam); - hti.pt.y = (short)HIWORD(lParam); - ClientToScreen(hWnd, &hti.pt); - ScreenToClient(dat->hTreeView, &hti.pt); - TreeView_HitTest(dat->hTreeView, &hti); - if (hti.hItem && dat->hDragItem != hti.hItem) - { - NMMSGTREE nm = {0}; - COptItem_TreeCtrl *TreeCtrl = dat->GetTreeCtrl(); - int OrderOld = TreeCtrl->hItemToOrder(dat->hDragItem); - int OrderNew = TreeCtrl->hItemToOrder(hti.hItem); - _ASSERT(OrderOld != -1 && OrderNew != -1); - nm.ItemOld = (OrderOld <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(OrderOld)] : (CBaseTreeItem*)&TreeCtrl->Value[OrderOld]; - nm.ItemNew = (OrderNew <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(OrderNew)] : (CBaseTreeItem*)&TreeCtrl->Value[OrderNew]; - nm.hdr.code = MTN_ENDDRAG; - nm.hdr.hwndFrom = dat->hTreeView; - nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); - if (!SendMessage(hWnd, WM_NOTIFY, 0, (LPARAM)&nm)) - { - dat->UpdateLock++; - dat->GetTreeCtrl()->MoveItem(hWnd, dat->hDragItem, hti.hItem); - dat->UpdateLock--; - } - } - dat->hDragItem = NULL; - } - } break; - case WM_TIMER: - { - if (wParam == MSGTREE_TIMER_ID) - { - KillTimer(hWnd, MSGTREE_TIMER_ID); - TVHITTESTINFO hti; - hti.pt.x = (short)LOWORD(GetMessagePos()); - hti.pt.y = (short)HIWORD(GetMessagePos()); - ScreenToClient(dat->hTreeView, &hti.pt); - TreeView_HitTest(dat->hTreeView, &hti); - if (hti.hItem && dat->hDragItem != hti.hItem && TreeView_GetChild(dat->hTreeView, hti.hItem)) // target is a group and is not the same item that we're dragging - { - TreeView_Expand(dat->hTreeView, hti.hItem, TVE_EXPAND); - } - } - } break; - } - return CallWindowProc(dat->OrigParentProc, hWnd, Msg, wParam, lParam); -} - - -static LRESULT CALLBACK MsgTreeSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - CMsgTree *dat = CWndUserData(GetParent(hWnd)).GetMsgTree(); - switch (Msg) - { - case UM_MSGTREE_UPDATE: // returns TRUE if updated - { - bool Modified = dat->MsgTreePage.GetModified(); - TCString WndTitle; - if (Modified) - { - WndTitle.GetBuffer(256); - HWND hCurWnd = hWnd; - do - { - hCurWnd = GetParent(hCurWnd); - } while (hCurWnd && !GetWindowText(hCurWnd, WndTitle, 256)); - WndTitle.ReleaseBuffer(); - } - if (!Modified || MessageBox(GetParent(hWnd), TCString(TranslateT("You've made changes to multiple Message trees at a time.\r\nDo you want to leave changes in \"")) + WndTitle + TranslateT("\" dialog?\r\nPress Yes to leave changes in this dialog, or No to discard its changes and save changes of the other Message tree instead."), WndTitle + _T(" - ") + TranslateT("New Away System"), MB_ICONQUESTION | MB_YESNO) == IDNO) - { - COptItem_TreeCtrl *TreeCtrl = dat->GetTreeCtrl(); - TCString OldTitle, OldMsg, NewTitle, NewMsg; - int OldOrder = TreeCtrl->IDToOrder(TreeCtrl->GetSelectedItemID(GetParent(hWnd))); - if (OldOrder != -1) - { - CBaseTreeItem* ItemOld = (OldOrder <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(OldOrder)] : (CBaseTreeItem*)&TreeCtrl->Value[OldOrder]; - OldTitle = ItemOld->Title; - if (!(ItemOld->Flags & TIF_ROOTITEM)) - { - OldMsg = ((CTreeItem*)ItemOld)->User_Str1; - } - } - dat->UpdateLock++; - dat->MsgTreePage.DBToMemToPage(); - dat->UpdateLock--; - NMMSGTREE nm = {0}; - int Order = TreeCtrl->IDToOrder(TreeCtrl->GetSelectedItemID(GetParent(hWnd))); - if (Order != -1) - { - nm.ItemNew = (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; - NewTitle = nm.ItemNew->Title; - if (!(nm.ItemNew->Flags & TIF_ROOTITEM)) - { - NewMsg = ((CTreeItem*)nm.ItemNew)->User_Str1; - } - } - if (OldTitle.IsEmpty()) - { - OldTitle = _T(""); // to be sure that NULL will be equal to "" in the latter comparisons - } - if (OldMsg.IsEmpty()) - { - OldMsg = _T(""); - } - if (NewTitle.IsEmpty()) - { - NewTitle = _T(""); - } - if (NewMsg.IsEmpty()) - { - NewMsg = _T(""); - } - if (OldTitle != (const TCHAR*)NewTitle || OldMsg != (const TCHAR*)NewMsg) - { - // probably it's better to leave nm.ItemOld = NULL, to prevent accidental rewriting of it with old data from an edit control etc. - nm.hdr.code = MTN_SELCHANGED; - nm.hdr.hwndFrom = hWnd; - nm.hdr.idFrom = GetDlgCtrlID(hWnd); - SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nm); - } - return true; - } - return false; - } break; - case WM_KEYDOWN: - { - switch (wParam) - { - case VK_DELETE: - { - dat->DeleteSelectedItem(); - } break; - case VK_INSERT: - { - dat->AddMessage(); - } break; - } - } break; - case WM_RBUTTONDOWN: - { - SetFocus(hWnd); - TVHITTESTINFO hitTest; - hitTest.pt.x = (short)LOWORD(lParam); - hitTest.pt.y = (short)HIWORD(lParam); - TreeView_HitTest(hWnd, &hitTest); - if (hitTest.hItem && hitTest.flags & TVHT_ONITEM) - { - TreeView_SelectItem(hWnd, hitTest.hItem); - } - return DefWindowProc(hWnd, Msg, wParam, lParam); - } break; - case WM_CONTEXTMENU: - { - TVHITTESTINFO ht; - ht.pt.x = (short)LOWORD(lParam); - ht.pt.y = (short)HIWORD(lParam); - TVITEM tvi = {0}; - if (ht.pt.x == -1 && ht.pt.y == -1) // use selected item - { - if (tvi.hItem = TreeView_GetSelection(hWnd)) - { - TreeView_EnsureVisible(hWnd, tvi.hItem); - RECT rc; - TreeView_GetItemRect(hWnd, tvi.hItem, &rc, true); - ht.pt.x = rc.left; - ht.pt.y = rc.bottom; - } - } else - { - ScreenToClient(hWnd, &ht.pt); - TreeView_HitTest(hWnd, &ht); - if (ht.hItem && ht.flags & TVHT_ONITEM) - { - tvi.hItem = ht.hItem; - } - } - if (tvi.hItem) - { - COptItem_TreeCtrl *TreeCtrl = dat->GetTreeCtrl(); - tvi.mask = TVIF_HANDLE | TVIF_PARAM; - TreeView_GetItem(hWnd, &tvi); - int Order = TreeCtrl->IDToOrder(tvi.lParam); - if (Order >= 0) - { - HMENU hMenu; - if (TreeCtrl->Value[Order].Flags & TIF_GROUP) - { - hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_MSGTREE_CATEGORYMENU)); - } else - { - hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_MSGTREE_MESSAGEMENU)); - } - _ASSERT(hMenu); - HMENU hPopupMenu = GetSubMenu(hMenu, 0); - TranslateMenu(hPopupMenu); - ClientToScreen(hWnd, &ht.pt); - struct - { - int ItemID, IconID; - } MenuItems[] = { - IDM_MSGTREEMENU_NEWMESSAGE, IMGLIST_NEWMESSAGE, - IDM_MSGTREEMENU_NEWCATEGORY, IMGLIST_NEWCATEGORY, - IDM_MSGTREEMENU_DELETE, IMGLIST_DELETE - }; - MENUITEMINFO mii = {0}; - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_BITMAP | MIIM_DATA | MIIM_STATE | MIIM_CHECKMARKS; - mii.hbmpItem = HBMMENU_CALLBACK; - int I; - for (I = 0; I < lengthof(MenuItems); I++) // set icons - { - mii.dwItemData = MenuItems[I].IconID; - SetMenuItemInfo(hPopupMenu, MenuItems[I].ItemID, false, &mii); - } - mii.fMask = MIIM_STATE; - mii.fState = MFS_CHECKED; - for (I = 0; I < lengthof(StatusModeList); I++) // set checkmarks - { - if (TreeCtrl->Value[Order].ID == dat->MsgTreePage.GetValue(StatusModeList[I].DBSetting)) - { - SetMenuItemInfo(hPopupMenu, StatusModeList[I].MenuItemID, false, &mii); - } - } - int MenuResult = TrackPopupMenu(hPopupMenu, TPM_RIGHTBUTTON | TPM_RETURNCMD, ht.pt.x, ht.pt.y, 0, hWnd, NULL); - switch (MenuResult) - { - case IDM_MSGTREEMENU_NEWMESSAGE: - { - dat->AddMessage(); - } break; - case IDM_MSGTREEMENU_NEWCATEGORY: - { - dat->AddCategory(); - } break; - case IDM_MSGTREEMENU_RENAME: - { - TreeView_EditLabel(hWnd, tvi.hItem); - } break; - case IDM_MSGTREEMENU_DELETE: - { - dat->DeleteSelectedItem(); - } break; - case IDR_MSGTREEMENU_DEF_ONL: - case IDR_MSGTREEMENU_DEF_AWAY: - case IDR_MSGTREEMENU_DEF_NA: - case IDR_MSGTREEMENU_DEF_OCC: - case IDR_MSGTREEMENU_DEF_DND: - case IDR_MSGTREEMENU_DEF_FFC: - case IDR_MSGTREEMENU_DEF_INV: - case IDR_MSGTREEMENU_DEF_OTP: - case IDR_MSGTREEMENU_DEF_OTL: - { - int I; - for (I = 0; I < lengthof(StatusModeList); I++) - { - if (StatusModeList[I].MenuItemID == MenuResult) - { - dat->SetDefMsg(StatusModeList[I].Status, tvi.lParam); - break; - } - } - } break; - } - DestroyMenu(hMenu); - return 0; - } - } - } break; - case WM_MEASUREITEM: - { - LPMEASUREITEMSTRUCT lpmi = (LPMEASUREITEMSTRUCT)lParam; - if (lpmi->CtlType == ODT_MENU) - { - lpmi->itemWidth = max(0, GetSystemMetrics(SM_CXSMICON) - GetSystemMetrics(SM_CXMENUCHECK) + 4); - lpmi->itemHeight = GetSystemMetrics(SM_CYSMICON) + 2; - return true; - } - } break; - case WM_DRAWITEM: - { - LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lParam; - if (dis->CtlType == ODT_MENU) - { - ImageList_DrawEx(dat->hImageList, dis->itemData, dis->hDC, 2, (dis->rcItem.bottom + dis->rcItem.top - GetSystemMetrics(SM_CYSMICON)) / 2 + 1, 0, 0, GetSysColor(COLOR_WINDOW), CLR_NONE, ILD_NORMAL); - return true; - } - } break; - } - return CallWindowProc(dat->OrigTreeViewProc, hWnd, Msg, wParam, lParam); -} - - -CMsgTree::CMsgTree(HWND hTreeView): MsgTreePage(g_MsgTreePage), hTreeView(hTreeView), hDragItem(NULL), hPrevDropTarget(NULL), UpdateLock(0) -{ - CWndUserData(GetParent(hTreeView)).SetMsgTree(this); - OrigParentProc = (WNDPROC)SetWindowLongPtr(GetParent(hTreeView), GWLP_WNDPROC, (LONG_PTR)ParentSubclassProc); - OrigTreeViewProc = (WNDPROC)SetWindowLongPtr(hTreeView, GWLP_WNDPROC, (LONG_PTR)MsgTreeSubclassProc); - MsgTreePage.SetWnd(GetParent(hTreeView)); - COptItem_TreeCtrl* TreeCtrl = (COptItem_TreeCtrl*)MsgTreePage.Find(IDV_MSGTREE); - TreeCtrl->SetDlgItemID(GetDlgCtrlID(hTreeView)); - hImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), (IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR16) | ILC_MASK, 5, 2); - ImageList_AddIcon(hImageList, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_NEWMESSAGE))); - ImageList_AddIcon(hImageList, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_NEWCATEGORY))); - ImageList_AddIcon(hImageList, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_DELETE))); - MsgTreePage.DBToMemToPage(); - if (!g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_RECENTMSGSCOUNT)) - { // show "Recent messages" group only when RECENTMSGSCOUNT is not set to 0. - TreeView_DeleteItem(hTreeView, TreeCtrl->RootItems[g_Messages_RecentRootID].hItem); - } - WindowList_Add(hMTWindowList, hTreeView, NULL); -} - -CMsgTree::~CMsgTree() -{ - _ASSERT(GetWindowLongPtr(GetParent(hTreeView), GWLP_WNDPROC) == (LONG_PTR)ParentSubclassProc); // we won't allow anyone to change our WNDPROC. otherwise we're not sure that we're setting the right WNDPROC back - SetWindowLongPtr(hTreeView, GWLP_WNDPROC, (GetWindowLongPtr(GetParent(hTreeView), GWLP_WNDPROC) == (LONG_PTR)ParentSubclassProc) ? (LONG_PTR)OrigTreeViewProc : (LONG_PTR)DefDlgProc); // yeah, if that crazy Help plugin substituted MY WndProc again, he won't get his WndProc back.. he-he >:) - SetWindowLongPtr(GetParent(hTreeView), GWLP_WNDPROC, (LONG_PTR)OrigParentProc); - CWndUserData(GetParent(hTreeView)).SetMsgTree(NULL); - WindowList_Remove(hMTWindowList, hTreeView); - ImageList_Destroy(hImageList); -} - -CBaseTreeItem* CMsgTree::GetSelection() // returns NULL if there's nothing selected -{ - COptItem_TreeCtrl *TreeCtrl = GetTreeCtrl(); - int Order = TreeCtrl->IDToOrder(TreeCtrl->GetSelectedItemID(GetParent(hTreeView))); - if (Order != -1) - { - return (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; - } - return NULL; -} - -bool CMsgTree::SetSelection(int ID, int Flags) // set ID = -1 to unselect; returns TRUE on unselect and on successful select -{ - COptItem_TreeCtrl *TreeCtrl = GetTreeCtrl(); - int Order = (Flags & MTSS_BYORDER) ? ID : TreeCtrl->IDToOrder(ID); - if (Order == -1 && ID != -1) - { - return false; - } - TreeView_SelectItem(hTreeView, (Order == -1) ? NULL : ((Order <= TREECTRL_ROOTORDEROFFS) ? TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)].hItem : TreeCtrl->Value[Order].hItem)); - return true; -} - -int CMsgTree::GetDefMsg(int iMode) -{ - int I; - for (I = 0; I < lengthof(StatusModeList); I++) - { - if (StatusModeList[I].Status == iMode) - { - return MsgTreePage.GetValue(StatusModeList[I].DBSetting); - } - } - return 0; -} - -void CMsgTree::SetDefMsg(int iMode, int ID) -{ - int I; - for (I = 0; I < lengthof(StatusModeList); I++) - { - if (StatusModeList[I].Status == iMode) - { - if (MsgTreePage.GetValue(StatusModeList[I].DBSetting) != ID) - { - RECT rc; - COptItem_TreeCtrl *TreeCtrl = GetTreeCtrl(); - int OrderOld = TreeCtrl->IDToOrder(MsgTreePage.GetValue(StatusModeList[I].DBSetting)); - if (OrderOld >= 0 && TreeView_GetItemRect(hTreeView, TreeCtrl->Value[OrderOld].hItem, &rc, false)) - { - InvalidateRect(hTreeView, &rc, true); // refresh icons of previous default tree item - } - int OrderNew = TreeCtrl->IDToOrder(ID); - if (OrderNew >= 0 && TreeView_GetItemRect(hTreeView, TreeCtrl->Value[OrderNew].hItem, &rc, false)) - { - InvalidateRect(hTreeView, &rc, true); // refresh new default item icons - } - MsgTreePage.SetValue(StatusModeList[I].DBSetting, ID); - NMMSGTREE nm = {0}; - if (OrderOld >= 0) - { - nm.ItemOld = &TreeCtrl->Value[OrderOld]; - } - if (OrderNew >= 0) - { - nm.ItemNew = &TreeCtrl->Value[OrderNew]; - } - nm.hdr.code = MTN_DEFMSGCHANGED; - nm.hdr.hwndFrom = hTreeView; - nm.hdr.idFrom = GetDlgCtrlID(hTreeView); - SendMessage(GetParent(hTreeView), WM_NOTIFY, 0, (LPARAM)&nm); - } - break; - } - } -} - -void CMsgTree::Save() -{ - if (MsgTreePage.GetModified()) - { - MsgTreePage.PageToMemToDB(); - WindowList_BroadcastAsync(hMTWindowList, UM_MSGTREE_UPDATE, 0, 0); - } -} - -void CMsgTree::UpdateItem(int ID) // updates item title, and expanded/collapsed state for groups -{ - COptItem_TreeCtrl *TreeCtrl = GetTreeCtrl(); - int Order = TreeCtrl->IDToOrder(ID); - if (Order != -1) - { - CBaseTreeItem* TreeItem = (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; - TCString NewTitle; - TVITEM tvi; - tvi.mask = TVIF_HANDLE | TVIF_TEXT; - tvi.hItem = TreeItem->hItem; - tvi.pszText = NewTitle.GetBuffer(TREEITEMTITLE_MAXLEN); - tvi.cchTextMax = TREEITEMTITLE_MAXLEN; - TreeView_GetItem(hTreeView, &tvi); - if (TreeItem->Title != (const TCHAR*)tvi.pszText) - { - TreeCtrl->SetModified(true); - NMMSGTREE nm = {0}; - nm.ItemNew = TreeItem; - nm.hdr.code = MTN_ITEMRENAMED; - nm.hdr.hwndFrom = hTreeView; - nm.hdr.idFrom = GetDlgCtrlID(hTreeView); - SendMessage(GetParent(hTreeView), WM_NOTIFY, 0, (LPARAM)&nm); - } - tvi.mask = TVIF_HANDLE | TVIF_TEXT; - tvi.pszText = TreeItem->Title; - TreeView_SetItem(hTreeView, &tvi); - TreeView_Expand(hTreeView, tvi.hItem, (TreeItem->Flags & TIF_EXPANDED) ? TVE_EXPAND : TVE_COLLAPSE); - } -} - -bool CMsgTree::DeleteSelectedItem() // returns true if the item was deleted -{ - COptItem_TreeCtrl *TreeCtrl = GetTreeCtrl(); - int Order = TreeCtrl->IDToOrder(TreeCtrl->GetSelectedItemID(GetParent(hTreeView))); - _ASSERT(Order >= 0); - CTreeItem *SelectedItem = &TreeCtrl->Value[Order]; - //NightFox: fix for langpack and fix cut char space in text - //if (MessageBox(GetParent(hTreeView), TCString(TranslateT("Do you really want to delete this ")) + ((SelectedItem->Flags & TIF_GROUP) ? TranslateT("category with its messages?") : TranslateT("message?")), TranslateT("New Away System"), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2) == IDYES) - if (MessageBox(GetParent(hTreeView), - ((SelectedItem->Flags & TIF_GROUP) ? - TranslateT("Do you really want to delete this category with its messages?") - : - TranslateT("Do you really want to delete this message?")) - , - TranslateT("New Away System"), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2) == IDYES) - { - NMMSGTREE nm = {0}; - nm.ItemOld = SelectedItem; - nm.hdr.code = MTN_DELETEITEM; - nm.hdr.hwndFrom = hTreeView; - nm.hdr.idFrom = GetDlgCtrlID(hTreeView); - if (!SendMessage(GetParent(hTreeView), WM_NOTIFY, 0, (LPARAM)&nm)) - { - TreeCtrl->Delete(GetParent(hTreeView), TreeCtrl->GetSelectedItemID(GetParent(hTreeView))); - return true; - } - } - return false; -} - -CTreeItem* CMsgTree::AddCategory() -{ - COptItem_TreeCtrl *TreeCtrl = GetTreeCtrl(); - CTreeItem* TreeItem = TreeCtrl->InsertItem(GetParent(hTreeView), CTreeItem(_T(""), 0, 0, TIF_GROUP)); - TVITEM tvi; - tvi.mask = TVIF_HANDLE | TVIF_TEXT; - tvi.hItem = TreeItem->hItem; - TreeItem->Title = tvi.pszText = TranslateT("New category"); - TreeView_SetItem(hTreeView, &tvi); - TreeView_EditLabel(hTreeView, TreeItem->hItem); - NMMSGTREE nm = {0}; - nm.ItemNew = TreeItem; - nm.hdr.code = MTN_NEWCATEGORY; - nm.hdr.hwndFrom = hTreeView; - nm.hdr.idFrom = GetDlgCtrlID(hTreeView); - SendMessage(GetParent(hTreeView), WM_NOTIFY, 0, (LPARAM)&nm); - return TreeItem; -} - -CTreeItem* CMsgTree::AddMessage() -{ - COptItem_TreeCtrl *TreeCtrl = GetTreeCtrl(); - CTreeItem* TreeItem = TreeCtrl->InsertItem(GetParent(hTreeView), CTreeItem(_T(""), 0, 0)); - TVITEM tvi; - tvi.mask = TVIF_HANDLE | TVIF_TEXT; - tvi.hItem = TreeItem->hItem; - TreeItem->Title = tvi.pszText = TranslateT("New message"); - TreeView_SetItem(hTreeView, &tvi); - TreeView_EditLabel(hTreeView, TreeItem->hItem); - NMMSGTREE nm = {0}; - nm.ItemNew = TreeItem; - nm.hdr.code = MTN_NEWMESSAGE; - nm.hdr.hwndFrom = hTreeView; - nm.hdr.idFrom = GetDlgCtrlID(hTreeView); - SendMessage(GetParent(hTreeView), WM_NOTIFY, 0, (LPARAM)&nm); - return TreeItem; -} - -CBaseTreeItem* CMsgTree::GetNextItem(int Flags, CBaseTreeItem* Item) // Item is 'int ID' if MTGN_BYID flag is set; returns CBaseTreeItem* or NULL -{ - COptItem_TreeCtrl *TreeCtrl = GetTreeCtrl(); - CBaseTreeItem* TreeItem = Item; - if (Flags & MTGN_BYID) - { - int Order = TreeCtrl->IDToOrder((int)Item); - _ASSERT(Order != -1); - TreeItem = (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; - } - int TVFlag = 0; - switch (Flags & ~MTGN_BYID) - { - case MTGN_ROOT: TVFlag = TVGN_ROOT; break; - case MTGN_CHILD: TVFlag = TVGN_CHILD; break; - case MTGN_PARENT: TVFlag = TVGN_PARENT; break; - case MTGN_NEXT: TVFlag = TVGN_NEXT; break; - case MTGN_PREV: TVFlag = TVGN_PREVIOUS; break; - default: _ASSERT(0); - } - int Order = TreeCtrl->hItemToOrder(TreeView_GetNextItem(hTreeView, TreeItem ? TreeItem->hItem : NULL, TVFlag)); - if (Order != -1) - { - return (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; - } - return NULL; -} diff --git a/!Deprecated/NewAwaySysMod/MsgTree.h b/!Deprecated/NewAwaySysMod/MsgTree.h deleted file mode 100644 index 98b2f9d6cc..0000000000 --- a/!Deprecated/NewAwaySysMod/MsgTree.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - New Away System - plugin for Miranda IM - Copyright (c) 2005-2007 Chervov Dmitry - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#pragma once - -extern COptPage g_MsgTreePage; - -class CMsgTree -{ -public: - CMsgTree(HWND hTreeView); // warning: it changes GWLP_USERDATA of the parent window - ~CMsgTree(); - - CBaseTreeItem* GetSelection(); // returns NULL if there's nothing selected - bool SetSelection(int ID, int Flags); // set ID = -1 to unselect; ID specifies an order of an item if Flags = MTSS_BYORDER - int GetDefMsg(int iMode); - void SetDefMsg(int iMode, int ID); - void Save(); - void UpdateItem(int ID); // updates item title, and expanded/collapsed state for groups; set SetModified to TRUE to change Modified flag of the tree - bool DeleteSelectedItem(); // returns true if the item was deleted - CTreeItem* AddCategory(); - CTreeItem* AddMessage(); - CBaseTreeItem* GetNextItem(int Flags, CBaseTreeItem* Item); // Item is 'int ID' if MTGN_BYID flag is set; returns CBaseTreeItem* or NULL - void EnsureVisible(HTREEITEM hItem) {TreeView_EnsureVisible(hTreeView, hItem);} - bool GetModified() {return MsgTreePage.GetModified();} - void SetModified(bool Modified) {MsgTreePage.SetModified(Modified);} - - friend LRESULT CALLBACK ParentSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); - friend LRESULT CALLBACK MsgTreeSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); - -private: - COptItem_TreeCtrl* GetTreeCtrl() {return (COptItem_TreeCtrl*)MsgTreePage.Find(GetDlgCtrlID(hTreeView));} - - HWND hTreeView; - WNDPROC OrigTreeViewProc; - WNDPROC OrigParentProc; - COptPage MsgTreePage; - HTREEITEM hDragItem; - HTREEITEM hPrevDropTarget; - int UpdateLock; - HIMAGELIST hImageList; -}; - -// SetSelection constants -#define MTSS_BYID 0 -#define MTSS_BYORDER 1 - -// GetNextItem constants -#define MTGN_ROOT 0 -#define MTGN_CHILD 1 -#define MTGN_PARENT 2 -#define MTGN_NEXT 3 -#define MTGN_PREV 4 -#define MTGN_BYID 0x8000 // means that lParam is ID of an item, not a pointer to its data - - -// notifications - -typedef struct -{ - NMHDR hdr; - CBaseTreeItem* ItemOld; - CBaseTreeItem* ItemNew; -} NMMSGTREE; -typedef NMMSGTREE* PNMMSGTREE; - -#define MTN_FIRST (0U - 100U) - -#define MTN_SELCHANGED (MTN_FIRST - 0) // lParam = &NMMSGTREE; ItemOld and ItemNew contain old and new item info -#define MTN_BEGINDRAG (MTN_FIRST - 1) // lParam = &NMMSGTREE; ItemOld points to the item info; return TRUE to cancel dragging -#define MTN_ENDDRAG (MTN_FIRST - 2) // lParam = &NMMSGTREE; ItemOld points to the item info; ItemNew points to the item on which ItemOld was dropped; return TRUE to cancel moving -#define MTN_NEWCATEGORY (MTN_FIRST - 3) // lParam = &NMMSGTREE; ItemNew points to new category info -#define MTN_NEWMESSAGE (MTN_FIRST - 4) // lParam = &NMMSGTREE; ItemNew points to new message info -#define MTN_ITEMRENAMED (MTN_FIRST - 5) // lParam = &NMMSGTREE; ItemNew points to renamed item info -#define MTN_DELETEITEM (MTN_FIRST - 6) // lParam = &NMMSGTREE; ItemOld points to the item info; return TRUE to prevent item from being deleted -#define MTN_DEFMSGCHANGED (MTN_FIRST - 7) // lParam = &NMMSGTREE; ItemOld and ItemNew point to old and new default item info correspondingly - - -void LoadMsgTreeModule(); diff --git a/!Deprecated/NewAwaySysMod/NewAwaySys.rc b/!Deprecated/NewAwaySysMod/NewAwaySys.rc deleted file mode 100644 index 7a0bfba8ee..0000000000 --- a/!Deprecated/NewAwaySysMod/NewAwaySys.rc +++ /dev/null @@ -1,701 +0,0 @@ -//Microsoft Developer Studio generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Russian resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) -#ifdef _WIN32 -LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -#pragma code_page(1251) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -3 TEXTINCLUDE DISCARDABLE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // Russian resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE MOVEABLE PURE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE MOVEABLE PURE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_POPUPOPTDLG DIALOG DISCARDABLE 0, 0, 312, 237 -STYLE DS_SETFOREGROUND | DS_FIXEDSYS | DS_CONTROL | DS_CENTER | WS_CHILD -FONT 8, "MS Shell Dlg" -BEGIN - GROUPBOX "",IDC_POPUPOPTDLG_GROUP_NOTIFICATION,6,6,300,208 - CONTROL "Popup notification",IDC_POPUPOPTDLG_USEPOPUPS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,12,5,108,10 - GROUPBOX "Popup text format",IDC_STATIC,12,18,288,76 - EDITTEXT IDC_POPUPOPTDLG_POPUPFORMAT,18,30,222,48,ES_MULTILINE | - ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | - WS_VSCROLL | WS_HSCROLL - PUSHBUTTON "Preview",IDC_POPUPOPTDLG_POPUPPREVIEW,246,30,48,14 - CONTROL "V",IDC_POPUPOPTDLG_VARS,"MButtonClass",WS_TABSTOP,246, - 50,16,14,0x18000000L - LTEXT "%extratext% is your status message", - IDC_POPUPOPTDLG_STATIC_EXTRATEXT,18,81,276,8 - GROUPBOX "Click action",IDC_STATIC,12,100,199,54 - RTEXT "On left click",IDC_POPUPOPTDLG_STATIC_LCLICK,17,115,55, - 8 - COMBOBOX IDC_POPUPOPTDLG_LCLICK_ACTION,78,112,125,86, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - RTEXT "On right click",IDC_POPUPOPTDLG_STATIC_RCLICK,17,133,55, - 8 - COMBOBOX IDC_POPUPOPTDLG_RCLICK_ACTION,78,130,125,86, - CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Delay",IDC_STATIC,217,100,83,54 - EDITTEXT IDC_POPUPOPTDLG_POPUPDELAY,240,112,32,12,ES_AUTOHSCROLL - CONTROL "",IDC_POPUPOPTDLG_POPUPDELAY_SPIN,"msctls_updown32", - UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | - UDS_ARROWKEYS | UDS_NOTHOUSANDS,260,112,12,12 - LTEXT "Sec",IDC_POPUPOPTDLG_STATIC_SEC,275,114,21,8 - CTEXT "0 = Default",IDC_POPUPOPTDLG_STATIC_DEFAULT,224,128,70, - 8 - CTEXT "-1 = Infinite",IDC_POPUPOPTDLG_STATIC_INFINITE,224,140, - 70,8 - GROUPBOX "Colours",IDC_STATIC,12,160,155,48 - CONTROL "",IDC_POPUPOPTDLG_BGCOLOUR,"ColourPicker",WS_TABSTOP,19, - 172,19,12 - LTEXT "Background",IDC_POPUPOPTDLG_STATIC_BGCOLOUR,43,175,39,8 - CONTROL "Use default",IDC_POPUPOPTDLG_DEFBGCOLOUR,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,90,175,73,10 - CONTROL "",IDC_POPUPOPTDLG_TEXTCOLOUR,"ColourPicker",WS_TABSTOP, - 19,190,19,12 - LTEXT "Text",IDC_POPUPOPTDLG_STATIC_TEXTCOLOUR,43,193,15,8 - CONTROL "Use default",IDC_POPUPOPTDLG_DEFTEXTCOLOUR,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,90,193,73,10 - GROUPBOX "Only notify when:",IDC_STATIC,174,160,125,32 - CONTROL "On&line",IDC_POPUPOPTDLG_ONLNOTIFY,"MButtonClass", - WS_TABSTOP,180,172,16,14,0x18000000L - CONTROL "&Away",IDC_POPUPOPTDLG_AWAYNOTIFY,"MButtonClass", - WS_TABSTOP,196,172,16,14,0x18000000L - CONTROL "&NA",IDC_POPUPOPTDLG_NANOTIFY,"MButtonClass",WS_TABSTOP, - 212,172,16,14,0x18000000L - CONTROL "Occ&upied",IDC_POPUPOPTDLG_OCCNOTIFY,"MButtonClass", - WS_TABSTOP,228,172,16,14,0x18000000L - CONTROL "&DND",IDC_POPUPOPTDLG_DNDNOTIFY,"MButtonClass", - WS_TABSTOP,244,172,16,14,0x18000000L - CONTROL "&Free for chat",IDC_POPUPOPTDLG_FFCNOTIFY,"MButtonClass", - WS_TABSTOP,260,172,16,14,0x18000000L - CONTROL "&Other",IDC_POPUPOPTDLG_OTHERNOTIFY,"MButtonClass", - WS_TABSTOP,276,172,16,14,0x18000000L - CONTROL "Log to a file only when popup notification for a contact is enabled", - IDC_POPUPOPTDLG_LOGONLYWITHPOPUP,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,6,219,300,10 -END - -IDD_AUTOREPLY DIALOG DISCARDABLE 0, 0, 312, 231 -STYLE DS_SETFOREGROUND | DS_FIXEDSYS | DS_CONTROL | DS_CENTER | WS_CHILD -FONT 8, "MS Shell Dlg" -BEGIN - GROUPBOX "",IDC_MOREOPTDLG_PANEL,6,6,300,220 - CONTROL "Enable autoreply",IDC_REPLYDLG_ENABLEREPLY,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,12,5,139,10 - RTEXT "On event...",IDC_REPLYDLG_STATIC_ONEVENT,43,19,59,8 - CONTROL "",IDC_REPLYDLG_EVENTMSG,"Button",BS_AUTOCHECKBOX | - BS_ICON | WS_TABSTOP,110,17,29,12 - CONTROL "",IDC_REPLYDLG_EVENTURL,"Button",BS_AUTOCHECKBOX | - BS_ICON | WS_TABSTOP,145,17,29,12 - CONTROL "",IDC_REPLYDLG_EVENTFILE,"Button",BS_AUTOCHECKBOX | - BS_ICON | WS_TABSTOP,180,17,29,12 - CONTROL "Don't reply to ICQ contacts",IDC_REPLYDLG_DONTSENDTOICQ, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,119,275,10 - CONTROL "Don't reply when I'm invisible to the contact", - IDC_REPLYDLG_DONTREPLYINVISIBLE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,21,107,275,10 - CONTROL "Save autoreply to the history",IDC_REPLYDLG_LOGREPLY, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,34,275,10 - CONTROL "Reply only when Idle",IDC_REPLYDLG_ONLYIDLEREPLY,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,21,48,275,10 - CONTROL "Reply only when contact's message window is closed", - IDC_REPLYDLG_ONLYCLOSEDDLGREPLY,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,21,59,275,10 - LTEXT "Send maximum",IDC_REPLYDLG_STATIC_SEND,33,72,90,8 - EDITTEXT IDC_REPLYDLG_SENDCOUNT,127,70,40,12,ES_AUTOHSCROLL - CONTROL "",IDC_REPLYDLG_SENDCOUNT_SPIN,"msctls_updown32", - UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | - UDS_ARROWKEYS | UDS_NOTHOUSANDS,156,70,12,12 - LTEXT "times (-1=infinite)",IDC_REPLYDLG_STATIC_TIMES,172,72, - 124,8 - CONTROL "Reset this counter also when I just change my status text\n(when status icon remains the same)", - IDC_REPLYDLG_RESETCOUNTERWHENSAMEICON,"Button", - BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,34, - 84,262,18 - LTEXT "Disable autoreply when...", - IDC_REPLYDLG_STATIC_DISABLEWHENSTATUS,13,134,283,8 - CONTROL "On&line",IDC_REPLYDLG_DISABLE_ONL,"MButtonClass", - WS_TABSTOP,21,146,16,14,0x18000000L - CONTROL "&Away",IDC_REPLYDLG_DISABLE_AWAY,"MButtonClass", - WS_TABSTOP,37,146,16,14,0x18000000L - CONTROL "&NA",IDC_REPLYDLG_DISABLE_NA,"MButtonClass",WS_TABSTOP, - 53,146,16,14,0x18000000L - CONTROL "Occ&upied",IDC_REPLYDLG_DISABLE_OCC,"MButtonClass", - WS_TABSTOP,69,146,16,14,0x18000000L - CONTROL "&DND",IDC_REPLYDLG_DISABLE_DND,"MButtonClass", - WS_TABSTOP,85,146,16,14,0x18000000L - CONTROL "&Free for chat",IDC_REPLYDLG_DISABLE_FFC,"MButtonClass", - WS_TABSTOP,101,146,16,14,0x18000000L - CONTROL "&Invisible",IDC_REPLYDLG_DISABLE_INV,"MButtonClass", - WS_TABSTOP,117,146,16,14,0x18000000L - CONTROL "On the &Phone",IDC_REPLYDLG_DISABLE_OTP,"MButtonClass", - WS_TABSTOP,133,146,16,14,0x18000000L - CONTROL "Out to &Lunch",IDC_REPLYDLG_DISABLE_OTL,"MButtonClass", - WS_TABSTOP,149,146,16,14,0x18000000L - LTEXT "Autoreply format:",IDC_REPLYDLG_STATIC_FORMAT,13,168, - 283,8 - EDITTEXT IDC_REPLYDLG_PREFIX,21,180,209,30,ES_MULTILINE | - ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL - CONTROL "V",IDC_REPLYDLG_VARS,"MButtonClass",WS_TABSTOP,231,180, - 16,14,0x18000000L - LTEXT "%extratext% is your status message", - IDC_REPLYDLG_STATIC_EXTRATEXT,21,212,234,8 -END - -IDD_SETAWAYMSG DIALOGEX 0, 0, 398, 132 -STYLE DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | - WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - EDITTEXT IDC_SAWAYMSG_MSGDATA,116,1,170,114,ES_MULTILINE | - ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL - PUSHBUTTON "OK",IDC_OK,115,117,60,14 - CONTROL "&Variables",IDC_SAWAYMSG_VARS,"MButtonClass",WS_TABSTOP, - 255,117,16,14,0x18000000L - CONTROL "Se&ttings",IDC_SAWAYMSG_OPTIONS,"MButtonClass", - WS_TABSTOP,271,117,16,14,0x18000000L - ICON IDI_IGNORE,IDC_SAWAYMSG_STATIC_IGNOREICON,382,109,16,16, - SS_CENTERIMAGE | SS_REALSIZEIMAGE - ICON IDI_SOE_ENABLED,IDC_SAWAYMSG_STATIC_REPLYICON,382,118,16, - 16,SS_CENTERIMAGE | SS_REALSIZEIMAGE - CONTROL "",IDC_SAWAYMSG_CONTACTSTREE,"SysTreeView32", - TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | - TVS_TRACKSELECT | WS_BORDER | WS_TABSTOP,289,1,108,114 - CONTROL "Ignore requests",IDC_SAWAYMSG_IGNOREREQ,"Button", - BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,307,116,80,8, - WS_EX_RIGHT - CONTROL "Send an autoreply",IDC_SAWAYMSG_SENDMSG,"Button", - BS_AUTO3STATE | BS_LEFTTEXT | WS_TABSTOP,307,124,80,8, - WS_EX_RIGHT - CONTROL "",IDC_SAWAYMSG_TREE,"SysTreeView32",TVS_HASBUTTONS | - TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | - TVS_SHOWSELALWAYS | TVS_TRACKSELECT | WS_BORDER | - WS_TABSTOP,1,1,112,114 - CONTROL "&Delete",IDC_SAWAYMSG_DELETE,"MButtonClass",WS_TABSTOP, - 58,116,16,14,0x18000000L - CONTROL "New &Category",IDC_SAWAYMSG_NEWCATEGORY,"MButtonClass", - WS_TABSTOP,2,116,16,14,0x18000000L - CONTROL "Save As &New",IDC_SAWAYMSG_SAVEASNEW,"MButtonClass", - WS_TABSTOP,18,116,16,14,0x18000000L - CONTROL "&Save",IDC_SAWAYMSG_SAVEMSG,"MButtonClass",WS_TABSTOP, - 34,116,16,14,0x18000000L - CONTROL "",IDC_SAWAYMSG_MSGSPLITTER,"Static",SS_ENHMETAFILE | - SS_SUNKEN,114,0,1,115 - CONTROL "",IDC_SAWAYMSG_CONTACTSPLITTER,"Static",SS_ENHMETAFILE | - SS_SUNKEN,287,0,1,115 -END - -IDD_MESSAGES DIALOG DISCARDABLE 0, 0, 311, 221 -STYLE DS_SETFOREGROUND | DS_FIXEDSYS | DS_CONTROL | DS_CENTER | WS_CHILD -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "",IDC_MESSAGEDLG_MSGTREE,"SysTreeView32",TVS_HASBUTTONS | - TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | - TVS_SHOWSELALWAYS | TVS_TRACKSELECT | WS_BORDER | - WS_TABSTOP,6,6,126,210 - RTEXT "Title:",IDC_STATIC,136,8,51,8 - EDITTEXT IDC_MESSAGEDLG_MSGTITLE,189,6,115,12,ES_AUTOHSCROLL - EDITTEXT IDC_MESSAGEDLG_MSGDATA,138,24,166,138,ES_MULTILINE | - ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL - GROUPBOX "Use this message as default for",IDC_STATIC,138,186,166, - 30,BS_LEFT - CONTROL "On&line",IDC_MESSAGEDLG_DEF_ONL,"MButtonClass", - WS_TABSTOP,149,197,16,14,0x18000000L - CONTROL "&Away",IDC_MESSAGEDLG_DEF_AWAY,"MButtonClass", - WS_TABSTOP,165,197,16,14,0x18000000L - CONTROL "&NA",IDC_MESSAGEDLG_DEF_NA,"MButtonClass",WS_TABSTOP, - 181,197,16,14,0x18000000L - CONTROL "Occ&upied",IDC_MESSAGEDLG_DEF_OCC,"MButtonClass", - WS_TABSTOP,197,197,16,14,0x18000000L - CONTROL "&DND",IDC_MESSAGEDLG_DEF_DND,"MButtonClass",WS_TABSTOP, - 213,197,16,14,0x18000000L - CONTROL "&Free for chat",IDC_MESSAGEDLG_DEF_FFC,"MButtonClass", - WS_TABSTOP,229,197,16,14,0x18000000L - CONTROL "&Invisible",IDC_MESSAGEDLG_DEF_INV,"MButtonClass", - WS_TABSTOP,245,197,16,14,0x18000000L - CONTROL "On the &Phone",IDC_MESSAGEDLG_DEF_OTP,"MButtonClass", - WS_TABSTOP,261,197,16,14,0x18000000L - CONTROL "Out to &Lunch",IDC_MESSAGEDLG_DEF_OTL,"MButtonClass", - WS_TABSTOP,277,197,16,14,0x18000000L - CONTROL "New message",IDC_MESSAGEDLG_NEWMSG,"MButtonClass", - WS_TABSTOP,138,166,16,14,0x18000000L - CONTROL "New category",IDC_MESSAGEDLG_NEWCAT,"MButtonClass", - WS_TABSTOP,154,166,16,14,0x18000000L - CONTROL "Delete",IDC_MESSAGEDLG_DEL,"MButtonClass",WS_TABSTOP, - 170,166,16,14,0x18000000L - CONTROL "V",IDC_MESSAGEDLG_VARS,"MButtonClass",WS_TABSTOP,288, - 166,16,14,0x18000000L -END - -IDD_MODERNOPT_MESSAGES DIALOG DISCARDABLE 0, 0, 373, 154 -STYLE DS_SETFOREGROUND | DS_FIXEDSYS | DS_CONTROL | DS_CENTER | WS_CHILD -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "",IDC_MESSAGEDLG_MSGTREE,"SysTreeView32",TVS_HASBUTTONS | - TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | - TVS_SHOWSELALWAYS | TVS_TRACKSELECT | WS_BORDER | - WS_TABSTOP,6,13,126,128 - LTEXT "Title:",IDC_TXT_TITLE2,138,14,51,8 - EDITTEXT IDC_MESSAGEDLG_MSGTITLE,194,13,172,12,ES_AUTOHSCROLL - EDITTEXT IDC_MESSAGEDLG_MSGDATA,138,30,228,57,ES_MULTILINE | - ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL - GROUPBOX "Use this message as default for",IDC_TXT_TITLE3,138,111, - 228,30,BS_LEFT - CONTROL "On&line",IDC_MESSAGEDLG_DEF_ONL,"MButtonClass", - WS_TABSTOP,144,122,16,14,0x18000000L - CONTROL "&Away",IDC_MESSAGEDLG_DEF_AWAY,"MButtonClass", - WS_TABSTOP,160,122,16,14,0x18000000L - CONTROL "&NA",IDC_MESSAGEDLG_DEF_NA,"MButtonClass",WS_TABSTOP, - 176,122,16,14,0x18000000L - CONTROL "Occ&upied",IDC_MESSAGEDLG_DEF_OCC,"MButtonClass", - WS_TABSTOP,192,122,16,14,0x18000000L - CONTROL "&DND",IDC_MESSAGEDLG_DEF_DND,"MButtonClass",WS_TABSTOP, - 208,122,16,14,0x18000000L - CONTROL "&Free for chat",IDC_MESSAGEDLG_DEF_FFC,"MButtonClass", - WS_TABSTOP,224,122,16,14,0x18000000L - CONTROL "&Invisible",IDC_MESSAGEDLG_DEF_INV,"MButtonClass", - WS_TABSTOP,240,122,16,14,0x18000000L - CONTROL "On the &Phone",IDC_MESSAGEDLG_DEF_OTP,"MButtonClass", - WS_TABSTOP,256,122,16,14,0x18000000L - CONTROL "Out to &Lunch",IDC_MESSAGEDLG_DEF_OTL,"MButtonClass", - WS_TABSTOP,272,122,16,14,0x18000000L - CONTROL "New message",IDC_MESSAGEDLG_NEWMSG,"MButtonClass", - WS_TABSTOP,138,95,16,14,0x18000000L - CONTROL "New category",IDC_MESSAGEDLG_NEWCAT,"MButtonClass", - WS_TABSTOP,154,95,16,14,0x18000000L - CONTROL "Delete",IDC_MESSAGEDLG_DEL,"MButtonClass",WS_TABSTOP, - 170,95,16,14,0x18000000L - CONTROL "V",IDC_MESSAGEDLG_VARS,"MButtonClass",WS_TABSTOP,350,95, - 16,14,0x18000000L - LTEXT "Statuses messages:",IDC_TXT_TITLE1,0,2,99,9 - CONTROL "Configure autoaway",IDC_LNK_AUTOAWAY,"Hyperlink", - WS_TABSTOP,6,142,126,11 -END - -IDD_MOREOPTDIALOG DIALOG DISCARDABLE 0, 0, 311, 235 -STYLE DS_SETFOREGROUND | DS_FIXEDSYS | DS_CONTROL | DS_CENTER | WS_CHILD -FONT 8, "MS Shell Dlg" -BEGIN - RTEXT "Wait",IDC_STATIC_MOREOPTDLG_WAIT,2,10,36,8 - EDITTEXT IDC_MOREOPTDLG_WAITFORMSG,41,8,28,12,ES_AUTOHSCROLL - CONTROL "",IDC_MOREOPTDLG_WAITFORMSG_SPIN,"msctls_updown32", - UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | - UDS_ARROWKEYS | UDS_NOTHOUSANDS,57,8,12,12 - LTEXT "seconds before closing the status message dialog (-1=don't close)", - IDC_STATIC_MOREOPTDLG_SECONDSREMAIN,74,10,235,8 - RTEXT "Store",IDC_STATIC,2,28,36,8 - EDITTEXT IDC_MOREOPTDLG_RECENTMSGSCOUNT,41,26,28,12, - ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_MOREOPTDLG_RECENTMSGSCOUNT_SPIN,"msctls_updown32", - UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | - UDS_ARROWKEYS | UDS_NOTHOUSANDS,57,26,12,12 - LTEXT "most recent messages (0=disable)",IDC_STATIC,74,28,119, - 8 - CONTROL "Store for each status separately", - IDC_MOREOPTDLG_PERSTATUSMRM,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,41,42,267,10 - GROUPBOX "Use default...",IDC_STATIC,6,58,294,30 - CONTROL "Use the most recent message",IDC_MOREOPTDLG_USELASTMSG, - "Button",BS_AUTORADIOBUTTON | WS_TABSTOP,12,70,138,10 - CONTROL "Use the default message",IDC_MOREOPTDLG_USEDEFMSG, - "Button",BS_AUTORADIOBUTTON | WS_TABSTOP,156,70,138,10 - CONTROL "Reset per-protocol messages when changing global status", - IDC_MOREOPTDLG_RESETPROTOMSGS,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,7,95,300,10 - CONTROL "Store protocol messages for each status separately", - IDC_MOREOPTDLG_PERSTATUSPROTOMSGS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,15,107,294,10 - CONTROL "Store protocol autoreply settings for each status separately", - IDC_MOREOPTDLG_PERSTATUSPROTOSETTINGS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,15,119,294,10 - CONTROL "Remember last message used for a contact...", - IDC_MOREOPTDLG_SAVEPERSONALMSGS,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,6,133,297,10 - CONTROL "Store for each status separately", - IDC_MOREOPTDLG_PERSTATUSPERSONAL,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,15,146,288,10 - CONTROL "Store contact autoreply/ignore settings for each status separately", - IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS,"Button", - BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,15, - 157,294,16 - CONTROL "Enable contact menu items",IDC_MOREOPTDLG_USEMENUITEM, - "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | - WS_TABSTOP,167,203,142,17 - CONTROL "Use protocol specific nick for %nas_mynick%", - IDC_MOREOPTDLG_MYNICKPERPROTO,"Button",BS_AUTOCHECKBOX | - BS_MULTILINE | WS_TABSTOP,6,175,294,8 - CONTROL "Update status messages for non-ICQ protocols every", - IDC_MOREOPTDLG_UPDATEMSGS,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,6,187,199,10 - EDITTEXT IDC_MOREOPTDLG_UPDATEMSGSPERIOD,207,186,38,12, - ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_MOREOPTDLG_UPDATEMSGSPERIOD_SPIN,"msctls_updown32", - UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | - UDS_ARROWKEYS | UDS_NOTHOUSANDS,230,186,12,12 - LTEXT "seconds",IDC_STATIC,249,187,60,8 - GROUPBOX "Don't show the message dialog for",IDC_STATIC,6,200,156, - 31 - CONTROL "On&line",IDC_MOREOPTDLG_DONTPOPDLG_ONL,"MButtonClass", - WS_TABSTOP,12,212,16,14,0x18000000L - CONTROL "&Away",IDC_MOREOPTDLG_DONTPOPDLG_AWAY,"MButtonClass", - WS_TABSTOP,28,212,16,14,0x18000000L - CONTROL "&NA",IDC_MOREOPTDLG_DONTPOPDLG_NA,"MButtonClass", - WS_TABSTOP,44,212,16,14,0x18000000L - CONTROL "Occ&upied",IDC_MOREOPTDLG_DONTPOPDLG_OCC,"MButtonClass", - WS_TABSTOP,60,212,16,14,0x18000000L - CONTROL "&DND",IDC_MOREOPTDLG_DONTPOPDLG_DND,"MButtonClass", - WS_TABSTOP,76,212,16,14,0x18000000L - CONTROL "&Free for chat",IDC_MOREOPTDLG_DONTPOPDLG_FFC, - "MButtonClass",WS_TABSTOP,92,212,16,14,0x18000000L - CONTROL "&Invisible",IDC_MOREOPTDLG_DONTPOPDLG_INV,"MButtonClass", - WS_TABSTOP,108,212,16,14,0x18000000L - CONTROL "On the &Phone",IDC_MOREOPTDLG_DONTPOPDLG_OTP, - "MButtonClass",WS_TABSTOP,124,212,16,14,0x18000000L - CONTROL "Out to &Lunch",IDC_MOREOPTDLG_DONTPOPDLG_OTL, - "MButtonClass",WS_TABSTOP,140,212,16,14,0x18000000L -END - -IDD_READAWAYMSG DIALOGEX 0, 0, 186, 72 -STYLE DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | - WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "%s Message for %s" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - EDITTEXT IDC_READAWAYMSG_MSG,5,5,177,43,ES_MULTILINE | - ES_AUTOVSCROLL | ES_READONLY | NOT WS_VISIBLE | - WS_VSCROLL - CTEXT "Retrieving %s message...",IDC_READAWAYMSG_RETRIEVE,5,21, - 177,8,SS_NOPREFIX - DEFPUSHBUTTON "&Cancel",IDOK,69,53,50,14,BS_NOTIFY -END - -IDD_CONTACTSOPTDLG DIALOGEX 0, 0, 311, 221 -STYLE DS_FIXEDSYS | DS_CONTROL | DS_CENTER | WS_CHILD -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "",IDC_CONTACTSDLG_LIST,"CListControl",WS_TABSTOP | - 0x1f0,6,30,299,160,WS_EX_CLIENTEDGE - ICON 141,IDC_STATIC,197,0,20,20,SS_CENTERIMAGE | - SS_REALSIZEIMAGE | NOT WS_VISIBLE - LTEXT "Notify of requests",IDC_STATIC,217,5,87,8,SS_NOPREFIX | - SS_CENTERIMAGE | NOT WS_VISIBLE - ICON 140,IDC_STATIC,197,12,20,20,SS_CENTERIMAGE | - SS_REALSIZEIMAGE | NOT WS_VISIBLE - LTEXT "Don't notify of requests",IDC_STATIC,217,18,87,8, - SS_NOPREFIX | SS_CENTERIMAGE | NOT WS_VISIBLE - ICON IDI_SOE_ENABLED,IDC_STATIC,3,190,20,20,SS_CENTERIMAGE | - SS_REALSIZEIMAGE - LTEXT "Autoreply on",IDC_STATIC,24,196,106,8,SS_NOPREFIX | - SS_CENTERIMAGE - ICON IDI_SOE_DISABLED,IDC_STATIC,3,204,20,20,SS_CENTERIMAGE | - SS_REALSIZEIMAGE - LTEXT "Autoreply off",IDC_STATIC,24,210,107,8,SS_NOPREFIX | - SS_CENTERIMAGE - ICON IDI_IGNORE,IDC_STATIC,132,190,20,20,SS_CENTERIMAGE | - SS_REALSIZEIMAGE - LTEXT "Don't send status message",IDC_STATIC,151,196,153,8, - SS_NOPREFIX | SS_CENTERIMAGE - LTEXT "Note: these settings are applied to all status modes at once.", - IDC_STATIC,6,1,300,9 - ICON IDI_INDEFINITE,IDC_STATIC,6,13,16,16,SS_CENTERIMAGE | - SS_REALSIZEIMAGE - LTEXT "Means the setting is different for different status modes / contacts", - IDC_STATIC,22,17,281,8,SS_NOPREFIX | SS_CENTERIMAGE -END - -IDD_SETAWAYMSG_BAK DIALOGEX 0, 0, 398, 133 -STYLE DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | - WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - EDITTEXT IDC_SAWAYMSG_MSGDATA,115,1,172,114,ES_MULTILINE | - ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL - PUSHBUTTON "OK",IDC_OK,115,117,60,14 - CONTROL "&Variables",IDC_SAWAYMSG_VARS,"MButtonClass",WS_TABSTOP, - 255,117,16,14,0x18000000L - CONTROL "Se&ttings",IDC_SAWAYMSG_OPTIONS,"MButtonClass", - WS_TABSTOP,271,117,16,14,0x18000000L - ICON IDI_IGNORE,IDC_SAWAYMSG_STATIC_IGNOREICON,379,108,18,16, - SS_CENTERIMAGE | SS_REALSIZEIMAGE - ICON IDI_SOE_ENABLED,IDC_SAWAYMSG_STATIC_REPLYICON,379,116,18, - 16,SS_CENTERIMAGE | SS_REALSIZEIMAGE - CONTROL "",IDC_SAWAYMSG_CONTACTSTREE,"SysTreeView32", - TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | - TVS_TRACKSELECT | WS_BORDER | WS_TABSTOP,289,1,108,114 - CONTROL "Ignore requests",IDC_SAWAYMSG_IGNOREREQ,"Button", - BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,307,116,80,8, - WS_EX_RIGHT - CONTROL "Send an autoreply",IDC_SAWAYMSG_SENDMSG,"Button", - BS_AUTO3STATE | BS_LEFTTEXT | WS_TABSTOP,307,124,80,8, - WS_EX_RIGHT - CONTROL "",IDC_SAWAYMSG_TREE,"SysTreeView32",TVS_HASBUTTONS | - TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | - TVS_SHOWSELALWAYS | TVS_TRACKSELECT | WS_BORDER | - WS_TABSTOP,1,1,112,114 - CONTROL "&Delete",IDC_SAWAYMSG_DELETE,"MButtonClass",WS_TABSTOP, - 2,117,16,14,0x18000000L - CONTROL "New &Category",IDC_SAWAYMSG_NEWCATEGORY,"MButtonClass", - WS_TABSTOP,18,117,16,14,0x18000000L - CONTROL "Save As &New",IDC_SAWAYMSG_SAVEASNEW,"MButtonClass", - WS_TABSTOP,34,117,16,14,0x18000000L - CONTROL "&Save",IDC_SAWAYMSG_SAVEMSG,"MButtonClass",WS_TABSTOP, - 50,117,16,14,0x18000000L - CONTROL "",IDC_SAWAYMSG_MSGSPLITTER,"Static",SS_ENHMETAFILE,113, - 0,2,115,WS_EX_STATICEDGE - CONTROL "",IDC_SAWAYMSG_CONTACTSPLITTER,"Static",SS_ENHMETAFILE, - 287,0,2,115,WS_EX_STATICEDGE -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO MOVEABLE PURE -BEGIN - IDD_POPUPOPTDLG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 305 - VERTGUIDE, 90 - VERTGUIDE, 163 - TOPMARGIN, 7 - BOTTOMMARGIN, 230 - END - - IDD_AUTOREPLY, DIALOG - BEGIN - RIGHTMARGIN, 297 - VERTGUIDE, 6 - VERTGUIDE, 21 - VERTGUIDE, 296 - VERTGUIDE, 306 - TOPMARGIN, 7 - BOTTOMMARGIN, 224 - END - - IDD_SETAWAYMSG, DIALOG - BEGIN - BOTTOMMARGIN, 124 - END - - IDD_MESSAGES, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 304 - VERTGUIDE, 138 - TOPMARGIN, 7 - BOTTOMMARGIN, 164 - END - - IDD_MODERNOPT_MESSAGES, DIALOG - BEGIN - RIGHTMARGIN, 366 - VERTGUIDE, 138 - HORZGUIDE, 13 - END - - IDD_MOREOPTDIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 309 - TOPMARGIN, 7 - BOTTOMMARGIN, 229 - END - - IDD_READAWAYMSG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 178 - TOPMARGIN, 7 - END - - IDD_CONTACTSOPTDLG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 304 - TOPMARGIN, 7 - BOTTOMMARGIN, 214 - END - - IDD_SETAWAYMSG_BAK, DIALOG - BEGIN - VERTGUIDE, 98 - HORZGUIDE, 111 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_MSGICON ICON DISCARDABLE "Images\\MsgIcon.ico" -IDI_SOE_ENABLED ICON DISCARDABLE "Images\\on.ico" -IDI_SOE_DISABLED ICON DISCARDABLE "Images\\off.ico" -IDI_DOT ICON DISCARDABLE "Images\\Dot.ico" -IDI_IGNORE ICON DISCARDABLE "Images\\Ignore.ico" -IDI_SAVE ICON DISCARDABLE "Images\\SaveMsg.ico" -IDI_SAVEASNEW ICON DISCARDABLE "Images\\SaveAsNew.ico" -IDI_DELETE ICON DISCARDABLE "Images\\Delete.ico" -IDI_NEWCATEGORY ICON DISCARDABLE "Images\\NewCat.ico" -IDI_VARIABLES ICON DISCARDABLE "Images\\Variables.ico" -IDI_NEWMESSAGE ICON DISCARDABLE "Images\\NewMessage.ico" -IDI_SETTINGS ICON DISCARDABLE "Images\\Settings.ico" -IDI_STATUS_OTHER ICON DISCARDABLE "Images\\Status_Other.ico" -IDI_INDEFINITE ICON DISCARDABLE "Images\\Indefinite.ico" - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDR_SAM_OPTIONS MENU DISCARDABLE -BEGIN - POPUP "Set away message window options" - BEGIN - MENUITEM "Show predefined &messages", IDM_SAM_OPTIONS_SHOWMSGTREE - MENUITEM "Show &contacts", IDM_SAM_OPTIONS_SHOWCONTACTTREE - - MENUITEM SEPARATOR - MENUITEM "Save default window settings &automatically", - IDM_SAM_OPTIONS_AUTOSAVEDLGSETTINGS - - MENUITEM "&Save current window settings as default", - IDM_SAM_OPTIONS_SAVEDLGSETTINGSNOW - - MENUITEM SEPARATOR - MENUITEM "Disable parsing of status messages by Variables plugin", - IDM_SAM_OPTIONS_DISABLEVARIABLES - - END -END - -IDR_MSGTREE_CATEGORYMENU MENU DISCARDABLE -BEGIN - POPUP "Message tree menu" - BEGIN - MENUITEM "Create new &message", IDM_MSGTREEMENU_NEWMESSAGE - MENUITEM "Create new &category", IDM_MSGTREEMENU_NEWCATEGORY - MENUITEM "&Rename", IDM_MSGTREEMENU_RENAME - MENUITEM "&Delete", IDM_MSGTREEMENU_DELETE - END -END - -IDR_MSGTREE_MESSAGEMENU MENU DISCARDABLE -BEGIN - POPUP "Message tree category menu" - BEGIN - POPUP "Set as &default for" - BEGIN - MENUITEM "On&line", IDR_MSGTREEMENU_DEF_ONL - MENUITEM "&Away", IDR_MSGTREEMENU_DEF_AWAY - MENUITEM "&NA", IDR_MSGTREEMENU_DEF_NA - MENUITEM "Occ&upied", IDR_MSGTREEMENU_DEF_OCC - MENUITEM "&DND", IDR_MSGTREEMENU_DEF_DND - MENUITEM "&Free for chat", IDR_MSGTREEMENU_DEF_FFC - MENUITEM "&Invisible", IDR_MSGTREEMENU_DEF_INV - MENUITEM "On the &Phone", IDR_MSGTREEMENU_DEF_OTP - MENUITEM "Out to &Lunch", IDR_MSGTREEMENU_DEF_OTL - END - MENUITEM SEPARATOR - MENUITEM "Create new &message", 40022 - MENUITEM "Create new &category", 40024 - MENUITEM "&Rename", IDM_MSGTREEMENU_RENAME - MENUITEM "&Delete", 40026 - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap -// - -IDB_SOE_ENABLED BITMAP MOVEABLE PURE "Images\\on.bmp" -IDB_SOE_DISABLED BITMAP MOVEABLE PURE "Images\\off.bmp" -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/!Deprecated/NewAwaySysMod/NewAwaySys.vcxproj b/!Deprecated/NewAwaySysMod/NewAwaySys.vcxproj deleted file mode 100644 index b6693ffd31..0000000000 --- a/!Deprecated/NewAwaySysMod/NewAwaySys.vcxproj +++ /dev/null @@ -1,242 +0,0 @@ -п»ї - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {6A516E27-AC50-5374-756B-A1558DB2EFA9} - - - - DynamicLibrary - Unicode - true - - - DynamicLibrary - Unicode - true - - - DynamicLibrary - Unicode - - - DynamicLibrary - Unicode - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - $(SolutionDir)$(Configuration)\Plugins\ - $(SolutionDir)$(Configuration)64\Plugins\ - $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ - $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ - $(SolutionDir)$(Configuration)\Plugins\ - $(SolutionDir)$(Configuration)64\Plugins\ - $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ - $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ - true - - - - Disabled - ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - Use - Level3 - EditAndContinue - Common.h - - - true - $(IntDir)$(TargetName).lib - Windows - false - $(SolutionDir)\lib - - - _DEBUG;%(PreprocessorDefinitions) - ..\..\include\msapi - - - - - Disabled - ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) - WIN64;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebugDLL - Use - Level3 - Common.h - - - true - $(IntDir)$(TargetName).lib - Windows - false - $(SolutionDir)\lib - - - _DEBUG;%(PreprocessorDefinitions) - ..\..\include\msapi - - - - - Full - OnlyExplicitInline - ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - Sync - false - false - Use - Level3 - Size - Common.h - - - true - $(IntDir)$(TargetName).lib - true - true - Windows - false - $(SolutionDir)\lib - - - NDEBUG;%(PreprocessorDefinitions) - ..\..\include\msapi - - - - - Full - OnlyExplicitInline - ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) - WIN64;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - Sync - false - false - Use - Level3 - Size - Common.h - - - true - $(IntDir)$(TargetName).lib - true - true - Windows - false - $(SolutionDir)\lib - - - NDEBUG;%(PreprocessorDefinitions) - ..\..\include\msapi - - - - - - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/!Deprecated/NewAwaySysMod/NewAwaySys.vcxproj.filters b/!Deprecated/NewAwaySysMod/NewAwaySys.vcxproj.filters deleted file mode 100644 index bb85b875dd..0000000000 --- a/!Deprecated/NewAwaySysMod/NewAwaySys.vcxproj.filters +++ /dev/null @@ -1,187 +0,0 @@ -п»ї - - - - {116110a1-b9f8-4995-aab2-1de50eab806f} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {7c639270-1dc0-403f-a6ba-7da092e1f885} - h;hpp;hxx;hm;inl - - - {bbdb7c3b-6f74-434a-b577-46de841df2af} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - {b1737ff9-4769-4f5b-b414-ee0f5256de7f} - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Resource Files - - - Documentation - - - Documentation - - - Documentation - - - - - Resource Files - - - \ No newline at end of file diff --git a/!Deprecated/NewAwaySysMod/Notification.cpp b/!Deprecated/NewAwaySysMod/Notification.cpp deleted file mode 100644 index ca3f271f47..0000000000 --- a/!Deprecated/NewAwaySysMod/Notification.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/* - New Away System - plugin for Miranda IM - Copyright (C) 2005-2007 Chervov Dmitry - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "Common.h" -#include "Path.h" -#include "Properties.h" - - -void ShowMsg(TCHAR *FirstLine, TCHAR *SecondLine, bool IsErrorMsg, int Timeout) -{ - if (ServiceExists(MS_POPUP_ADDPOPUPEX)) - { - POPUPDATAT ppd = {0}; - ppd.lchIcon = LoadIcon(NULL, IsErrorMsg ? IDI_EXCLAMATION : IDI_INFORMATION); -// lstrcpy(ppd.lpzContactName, FirstLine); -// lstrcpy(ppd.lpzText, SecondLine); - lstrcpy(ppd.lptzContactName, FirstLine); - lstrcpy(ppd.lptzText, SecondLine); - ppd.colorBack = IsErrorMsg ? 0x0202E3 : 0xE8F1FD; - ppd.colorText = IsErrorMsg ? 0xE8F1FD : 0x000000; - ppd.iSeconds = Timeout; - CallService(MS_POPUP_ADDPOPUPT, (WPARAM)&ppd, 0); - } else - { - MessageBox(NULL, SecondLine, FirstLine, MB_OK | (IsErrorMsg ? MB_ICONEXCLAMATION : MB_ICONINFORMATION)); - } -} - - -static int CALLBACK MenuWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) - { - case WM_MEASUREITEM: - { - return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); - } - case WM_DRAWITEM: - { - return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); - } - } - return DefWindowProc(hWnd, uMsg, wParam, lParam); -} - - -static VOID CALLBACK ShowContactMenu(DWORD wParam) -// wParam = hContact -{ - POINT pt; - HWND hMenuWnd = CreateWindowEx(WS_EX_TOOLWINDOW, _T("static"), _T(MOD_NAME)_T("_MenuWindow"), 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, g_hInstance, NULL); - SetWindowLongPtr(hMenuWnd, GWLP_WNDPROC, (LONG)(WNDPROC)MenuWndProc); - HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)wParam, 0); - GetCursorPos(&pt); - SetForegroundWindow(hMenuWnd); - CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, 0, hMenuWnd, NULL), MPCF_CONTACTMENU), (LPARAM)wParam); - PostMessage(hMenuWnd, WM_NULL, 0, 0); - DestroyMenu(hMenu); - DestroyWindow(hMenuWnd); -} - -/* -void Popup_DoAction(HWND hWnd, BYTE Action, PLUGIN_DATA *pdata) -{ - HANDLE hContact = (HANDLE)CallService(MS_POPUP_GETCONTACT, (WPARAM)hWnd, 0); - switch (Action) - { - case PCA_OPENMESSAGEWND: // open message window - { - if (hContact && hContact != INVALID_HANDLE_VALUE) - { - CallServiceSync(ServiceExists("SRMsg/LaunchMessageWindow") ? "SRMsg/LaunchMessageWindow" : MS_MSG_SENDMESSAGE, (WPARAM)hContact, 0); - } - } break; - case PCA_OPENMENU: // open contact menu - { - if (hContact && hContact != INVALID_HANDLE_VALUE) - { - QueueUserAPC(ShowContactMenu, hMainThread, (ULONG_PTR)hContact); - } - } break; - case PCA_OPENDETAILS: // open contact details window - { - if (hContact != INVALID_HANDLE_VALUE) - { - CallServiceSync(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0); - } - } break; - case PCA_OPENHISTORY: // open contact history - { - if (hContact != INVALID_HANDLE_VALUE) - { - CallServiceSync(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM)hContact, 0); - } - } break; - case PCA_OPENLOG: // open log file - { - TCString LogFilePath; - LS_LOGINFO li = {0}; - li.cbSize = sizeof(li); - li.szID = LOG_ID; - li.hContact = hContact; - li.Flags = LSLI_TCHAR; - li.tszLogPath = LogFilePath.GetBuffer(MAX_PATH); - if (!CallService(MS_LOGSERVICE_GETLOGINFO, (WPARAM)&li, 0)) - { - LogFilePath.ReleaseBuffer(); - ShowLog(LogFilePath); - } else - { - LogFilePath.ReleaseBuffer(); - } - } break; - case PCA_CLOSEPOPUP: // close popup - { - PUDeletePopUp(hWnd); - } break; - case PCA_DONOTHING: // do nothing - break; - } -} - - -static int CALLBACK ReqNotifyPopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - PLUGIN_DATA *pdata; - switch (message) - { - case WM_COMMAND: - { - if (HIWORD(wParam) == STN_CLICKED) // left mouse button - { - pdata = (PLUGIN_DATA*)CallService(MS_POPUP_GETPLUGINDATA, (WPARAM)hWnd, 0); - if (pdata) - { - Popup_DoAction(hWnd, pdata->PopupLClickAction, pdata); - } - return true; - } - } break; - case WM_CONTEXTMENU: // right mouse button - { - pdata = (PLUGIN_DATA*)CallService(MS_POPUP_GETPLUGINDATA, (WPARAM)hWnd, 0); - if (pdata) - { - Popup_DoAction(hWnd, pdata->PopupRClickAction, pdata); - } - return true; - } break; - case UM_FREEPLUGINDATA: - { - pdata = (PLUGIN_DATA*)CallService(MS_POPUP_GETPLUGINDATA, (WPARAM)hWnd, 0); - if (pdata) - { - if (pdata->hStatusIcon) - { - DestroyIcon(pdata->hStatusIcon); - } - free(pdata); - } - return true; - } break; - } - return DefWindowProc(hWnd, message, wParam, lParam); -} - - -int ShowPopupNotification(COptPage &PopupNotifyData, HANDLE hContact, int iStatusMode) -{ // returns TRUE if popup was shown -// we take szProto, UIN and Message from VarParseData - POPUPDATAT ppd = {0}; - ppd.lchContact = hContact; - TCString ExtraText; - if (!iStatusMode) - { // if it's an xstatus message request - ExtraText = DBGetContactSettingString(NULL, VarParseData.szProto, "XStatusName", _T("")); - TCString XMsg(DBGetContactSettingString(NULL, VarParseData.szProto, "XStatusMsg", _T(""))); - if (XMsg.GetLen()) - { - if (ExtraText.GetLen()) - { - ExtraText += _T("\r\n"); - } - ExtraText += XMsg; - } - } else - { - ExtraText = VarParseData.Message; - } - TCString PopupMsg(*(TCString*)PopupNotifyData.GetValue(IDC_POPUPOPTDLG_POPUPFORMAT)); - if (ServiceExists(MS_VARS_FORMATSTRING)) - { - FORMATINFO fi = {0}; - fi.cbSize = sizeof(fi); - fi.flags = FIF_TCHAR; - fi.tszFormat = PopupMsg; - fi.hContact = hContact; - fi.tszExtraText = ExtraText; - TCHAR *szResult = (TCHAR*)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0); - if (szResult) - { - PopupMsg = szResult; - CallService(MS_VARS_FREEMEMORY, (WPARAM)szResult, 0); - } - } else - { - TCString szUIN; - _ultot(VarParseData.UIN, szUIN.GetBuffer(16), 10); - szUIN.ReleaseBuffer(); - TCHAR *szStatDesc = iStatusMode ? (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iStatusMode, GSMDF_TCHAR) : STR_XSTATUSDESC; - _ASSERT(szStatDesc); - PopupMsg = TCString((TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR)) + _T(" (") + szUIN + TranslateT(") is reading your ") + szStatDesc + TranslateT(" message:\r\n") + ExtraText; - } - if (PopupMsg.GetLen()) - { - TCHAR *pLineBreak = _tcsstr(PopupMsg, _T("\n")); - if (pLineBreak) - { - PopupMsg.GetBuffer(); - TCHAR *pNextLine = pLineBreak + 1; - while ((*pNextLine == '\r' || *pNextLine == '\n') && *pNextLine) - { - *pNextLine++; - } - _tcsncpy(ppd.lpzText, pNextLine, 499); - while ((*pLineBreak == '\r' || *pLineBreak == '\n') && (pLineBreak >= PopupMsg)) - { - *pLineBreak-- = 0; - } - PopupMsg.ReleaseBuffer(); - } else - { - lstrcpy(ppd.lpzText, _T("")); - } - _tcsncpy(ppd.lpzContactName, PopupMsg, 499); - ppd.colorBack = (PopupNotifyData.GetValue(IDC_POPUPOPTDLG_DEFBGCOLOUR) ? 0 : PopupNotifyData.GetValue(IDC_POPUPOPTDLG_BGCOLOUR)); - ppd.colorText = (PopupNotifyData.GetValue(IDC_POPUPOPTDLG_DEFTEXTCOLOUR) ? 0 : PopupNotifyData.GetValue(IDC_POPUPOPTDLG_TEXTCOLOUR)); - ppd.PluginWindowProc = (WNDPROC)ReqNotifyPopupDlgProc; - PLUGIN_DATA *pdata = (PLUGIN_DATA*)calloc(1, sizeof(PLUGIN_DATA)); - if (!iStatusMode) - { // it's an xstatus message request - ppd.lchIcon = pdata->hStatusIcon = (HICON)CallProtoService(VarParseData.szProto, PS_ICQ_GETCUSTOMSTATUSICON, 0, 0); - } - if (!pdata->hStatusIcon || (DWORD)pdata->hStatusIcon == CALLSERVICE_NOTFOUND) - { - pdata->hStatusIcon = NULL; - ppd.lchIcon = LoadSkinnedProtoIcon(VarParseData.szProto, iStatusMode); - } - pdata->PopupLClickAction = PopupNotifyData.GetValue(IDC_POPUPOPTDLG_LCLICK_ACTION); - pdata->PopupRClickAction = PopupNotifyData.GetValue(IDC_POPUPOPTDLG_RCLICK_ACTION); - ppd.PluginData = pdata; - ppd.iSeconds = PopupNotifyData.GetValue(IDC_POPUPOPTDLG_POPUPDELAY); - CallService(MS_POPUP_ADDPOPUPT, (WPARAM)&ppd, 0); - if (hContact) - { - SkinPlaySound(AWAYSYS_STATUSMSGREQUEST_SOUND); - } - return true; - } - return false; -} -*/ - -void ShowLog(TCString &LogFilePath) -{ - int Result = (int)ShellExecute(NULL, _T("open"), LogFilePath, NULL, NULL, SW_SHOW); - if (Result <= 32) // Error - { - TCHAR szError[64]; - mir_sntprintf(szError, SIZEOF(szError), TranslateT("Error #%d"), Result); - ShowMsg(szError, TranslateT("Can't open log file ") + LogFilePath, true); - } -} diff --git a/!Deprecated/NewAwaySysMod/Path.h b/!Deprecated/NewAwaySysMod/Path.h deleted file mode 100644 index e64b7ceb3c..0000000000 --- a/!Deprecated/NewAwaySysMod/Path.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - New Away System - plugin for Miranda IM - Copyright (c) 2005-2007 Chervov Dmitry - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#pragma once - -#include "m_utils.h" -#include "..\CommonLibs\CString.h" - - -__inline TCString Path_ToRelative(TCString &Path) -{ - CString Str; - Str.GetBuffer(MAX_PATH); - CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)(const char*)TCHAR2ANSI(Path), (LPARAM)(char*)Str); - Str.ReleaseBuffer(); - return ANSI2TCHAR(Str); -} - - -__inline TCString Path_ToAbsolute(TCString &Path) -{ - CString Str; - Str.GetBuffer(MAX_PATH); - CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)(const char*)TCHAR2ANSI(Path), (LPARAM)(char*)Str); - Str.ReleaseBuffer(); - return ANSI2TCHAR(Str); -} diff --git a/!Deprecated/NewAwaySysMod/Properties.cpp b/!Deprecated/NewAwaySysMod/Properties.cpp deleted file mode 100644 index c9dc3c1c9c..0000000000 --- a/!Deprecated/NewAwaySysMod/Properties.cpp +++ /dev/null @@ -1,411 +0,0 @@ -/* - New Away System - plugin for Miranda IM - Copyright (C) 2005-2007 Chervov Dmitry - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "Common.h" -#include "Properties.h" - -CProtoStates g_ProtoStates; - -void ResetContactSettingsOnStatusChange(HANDLE hContact) -{ - DBDeleteContactSetting(hContact, MOD_NAME, DB_REQUESTCOUNT); - DBDeleteContactSetting(hContact, MOD_NAME, DB_SENDCOUNT); - DBDeleteContactSetting(hContact, MOD_NAME, DB_MESSAGECOUNT); -} - - -void ResetSettingsOnStatusChange(const char *szProto = NULL, int bResetPersonalMsgs = false, int Status = 0) -{ - if (bResetPersonalMsgs) - { // bResetPersonalMsgs &&= g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_SAVEPERSONALMSGS); - bResetPersonalMsgs = !g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_SAVEPERSONALMSGS); - } - HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - while (hContact) - { - const char *szCurProto; - if (!szProto || ((szCurProto = (const char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0)) && !lstrcmpA(szProto, szCurProto))) - { - ResetContactSettingsOnStatusChange(hContact); - if (bResetPersonalMsgs) - { - CContactSettings(Status, hContact).SetMsgFormat(SMF_PERSONAL, NULL); // TODO: delete only when SAM dialog opens? - } - } - hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); - } -} - - -CProtoState::CStatus& CProtoState::CStatus::operator = (int Status) -{ - _ASSERT(Status >= ID_STATUS_OFFLINE && Status <= ID_STATUS_OUTTOLUNCH); - if (Status < ID_STATUS_OFFLINE || Status > ID_STATUS_OUTTOLUNCH) - { - return *this; // ignore status change if the new status is unknown - } - bool bModified = false; - if (szProto) - { - if (this->Status != Status) - { - this->Status = Status; - (*GrandParent)[szProto].AwaySince.Reset(); - ResetSettingsOnStatusChange(szProto, true, Status); - bModified = true; - } - if ((*GrandParent)[szProto].TempMsg.IsSet()) - { - (*GrandParent)[szProto].TempMsg.Unset(); - bModified = true; - } - } else // global status change - { - int I; - int bStatusModified = false; - for (I = 0; I < GrandParent->GetSize(); I++) - { - CProtoState &State = (*GrandParent)[I]; - if (!DBGetContactSettingByte(NULL, State.GetProto(), "LockMainStatus", 0)) // if the protocol isn't locked - { - if (State.Status != Status) - { - State.Status.Status = Status; // "Status.Status" - changing Status directly to prevent recursive calls to the function - State.AwaySince.Reset(); - bModified = true; - bStatusModified = true; - } - if (State.TempMsg.IsSet()) - { - State.TempMsg.Unset(); - bModified = true; - } - if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_RESETPROTOMSGS)) - { - CProtoSettings(State.szProto, Status).SetMsgFormat(SMF_PERSONAL, NULL); - } - } - } - if (bStatusModified) - { - ResetSettingsOnStatusChange(NULL, true, Status); - } - } - if (bModified && g_SetAwayMsgPage.GetWnd()) - { - SendMessage(g_SetAwayMsgPage.GetWnd(), UM_SAM_PROTOSTATUSCHANGED, (WPARAM)(char*)szProto, 0); - } - return *this; -} - - -void CProtoState::CAwaySince::Reset() -{ - GetLocalTime(&AwaySince); - if (GrandParent && !szProto) - { - int I; - for (I = 0; I < GrandParent->GetSize(); I++) - { - GetLocalTime((*GrandParent)[I].AwaySince); - } - } -} - - -void CContactSettings::SetMsgFormat(int Flags, TCString Message) -{ - if (Flags & SMF_PERSONAL) - { // set a personal message for a contact. also it's used to set global status message (hContact = NULL). - // if Message == NULL, then the function deletes the message. - CString DBSetting(StatusToDBSetting(Status, DB_STATUSMSG, IDC_MOREOPTDLG_PERSTATUSPERSONAL)); - if (g_AutoreplyOptPage.GetDBValueCopy(IDC_REPLYDLG_RESETCOUNTERWHENSAMEICON) && GetMsgFormat(SMF_PERSONAL) != (const TCHAR*)Message) - { - ResetContactSettingsOnStatusChange(hContact); - } - if (Message != NULL) - { - DBWriteContactSettingTString(hContact, MOD_NAME, DBSetting, Message); - } else - { - DBDeleteContactSetting(hContact, MOD_NAME, DBSetting); - } - } - if (Flags & (SMF_LAST | SMF_TEMPORARY)) - { - _ASSERT(!hContact); - CProtoSettings().SetMsgFormat(Flags & (SMF_LAST | SMF_TEMPORARY), Message); - } -} - - -TCString CContactSettings::GetMsgFormat(int Flags, int *pOrder, char *szProtoOverride) -// returns the requested message; sets Order to the order of the message in the message tree, if available; or to -1 otherwise. -// szProtoOverride is needed only to get status message of the right protocol when the ICQ contact is on list, but not with the same protocol on which it requests the message - this way we can still get contact details. -{ - TCString Message = NULL; - if (pOrder) - { - *pOrder = -1; - } - if (Flags & GMF_PERSONAL) - { // try getting personal message (it overrides global) - Message = DBGetContactSettingString(hContact, MOD_NAME, StatusToDBSetting(Status, DB_STATUSMSG, IDC_MOREOPTDLG_PERSTATUSPERSONAL), (TCHAR*)NULL); - } - if (Flags & (GMF_LASTORDEFAULT | GMF_PROTOORGLOBAL | GMF_TEMPORARY) && Message.IsEmpty()) - { - char *szProto = szProtoOverride ? szProtoOverride : (hContact ? (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0) : NULL); - if (Flags & (GMF_LASTORDEFAULT | GMF_PROTOORGLOBAL)) - { // we mustn't pass here by GMF_TEMPORARY flag, as otherwise we'll handle GMF_TEMPORARY | GMF_PERSONAL combination incorrectly, which is supposed to get only per-contact messages, and at the same time also may be used with NULL contact to get the global status message - Message = CProtoSettings(szProto).GetMsgFormat(Flags, pOrder); - } else if (!hContact) - { // handle global temporary message too - if (g_ProtoStates[szProto].TempMsg.IsSet()) - { - Message = g_ProtoStates[szProto].TempMsg; - } - } - } - return Message; -} - - -void CProtoSettings::SetMsgFormat(int Flags, TCString Message) -{ - if (Flags & (SMF_TEMPORARY | SMF_PERSONAL) && g_AutoreplyOptPage.GetDBValueCopy(IDC_REPLYDLG_RESETCOUNTERWHENSAMEICON) && GetMsgFormat(Flags & (SMF_TEMPORARY | SMF_PERSONAL)) != (const TCHAR*)Message) - { - ResetSettingsOnStatusChange(szProto); - } - if (Flags & SMF_TEMPORARY) - { - _ASSERT(!Status || Status == g_ProtoStates[szProto].Status); - g_ProtoStates[szProto].TempMsg = (szProto || Message != NULL) ? Message : CProtoSettings(NULL, Status).GetMsgFormat(GMF_LASTORDEFAULT); - } - if (Flags & SMF_PERSONAL) - { // set a "personal" message for a protocol. also it's used to set global status message (hContact = NULL). - // if Message == NULL, then we'll use the "default" message - i.e. it's either the global message for szProto != NULL (we delete the per-proto DB setting), or it's just a default message for a given status for szProto == NULL. - g_ProtoStates[szProto].TempMsg.Unset(); - CString DBSetting(ProtoStatusToDBSetting(DB_STATUSMSG, IDC_MOREOPTDLG_PERSTATUSPROTOMSGS)); - if (Message != NULL) - { - DBWriteContactSettingTString(NULL, MOD_NAME, DBSetting, Message); - } else - { - if (!szProto) - { - DBWriteContactSettingTString(NULL, MOD_NAME, DBSetting, CProtoSettings(NULL, Status).GetMsgFormat(GMF_LASTORDEFAULT)); // global message can't be NULL; we can use an empty string instead if it's really necessary - } else - { - DBDeleteContactSetting(NULL, MOD_NAME, DBSetting); - } - } - } - if (Flags & SMF_LAST) - { - COptPage MsgTreeData(g_MsgTreePage); - COptItem_TreeCtrl *TreeCtrl = (COptItem_TreeCtrl*)MsgTreeData.Find(IDV_MSGTREE); - TreeCtrl->DBToMem(CString(MOD_NAME)); - int RecentGroupID = GetRecentGroupID(Status); - if (RecentGroupID == -1) - { // we didn't find the group, it also means that we're using per status messages; so we need to create it - TreeCtrl->Value.AddElem(CTreeItem(Status ? (const TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, Status, GSMDF_TCHAR) : MSGTREE_RECENT_OTHERGROUP, g_Messages_RecentRootID, RecentGroupID = TreeCtrl->GenerateID(), TIF_GROUP)); - TreeCtrl->SetModified(true); - } - int I; - TCString Title(_T("")); - for (I = 0; I < TreeCtrl->Value.GetSize(); I++) // try to find an identical message in the same group (to prevent saving multiple identical messages), or at least if we'll find an identical message somewhere else, then we'll use its title for our new message - { - if (!(TreeCtrl->Value[I].Flags & TIF_GROUP) && TreeCtrl->Value[I].User_Str1 == (const TCHAR*)Message) - { - if (TreeCtrl->Value[I].ParentID == RecentGroupID) - { // found it in the same group - int GroupOrder = TreeCtrl->IDToOrder(RecentGroupID); - TreeCtrl->Value.MoveElem(I, (GroupOrder >= 0) ? (GroupOrder + 1) : 0); // now move it to the top of recent messages list - TreeCtrl->SetModified(true); - break; // no reason to search for anything else - } else if (Title.IsEmpty()) - { // it's not in the same group, but at least we'll use its title - Title = TreeCtrl->Value[I].Title; - } - } - } - if (I == TreeCtrl->Value.GetSize()) - { // we didn't find an identical message in the same group, so we'll add our new message here - if (Title.IsEmpty()) - { // didn't find a title for our message either - if (Message.GetLen() > MRM_MAX_GENERATED_TITLE_LEN) - { - Title = Message.Left(MRM_MAX_GENERATED_TITLE_LEN - 3) + _T("..."); - } else - { - Title = Message; - } - TCHAR *p = Title.GetBuffer(); - while (*p) // remove "garbage" - { - if (!(p = _tcspbrk(p, _T("\r\n\t")))) - { - break; - } - *p++ = ' '; - } - Title.ReleaseBuffer(); - } - int GroupOrder = TreeCtrl->IDToOrder(RecentGroupID); - TreeCtrl->Value.InsertElem(CTreeItem(Title, RecentGroupID, TreeCtrl->GenerateID(), 0, Message), (GroupOrder >= 0) ? (GroupOrder + 1) : 0); - TreeCtrl->SetModified(true); - } - // now clean up here - int MRMNum = 0; - int MaxMRMNum = g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_RECENTMSGSCOUNT); - for (I = 0; I < TreeCtrl->Value.GetSize(); I++) - { - if (TreeCtrl->Value[I].ParentID == RecentGroupID) - { // found a child of our group - if (TreeCtrl->Value[I].Flags & TIF_GROUP || ++MRMNum > MaxMRMNum) // what groups are doing here?! :)) - { - TreeCtrl->Value.RemoveElem(I); - TreeCtrl->SetModified(true); - I--; - } - } - } - if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_PERSTATUSMRM)) - { // if we're saving recent messages per status, then remove any messages that were left at the recent messages' root - for (I = 0; I < TreeCtrl->Value.GetSize(); I++) - { - if (TreeCtrl->Value[I].ParentID == g_Messages_RecentRootID) - { - if (!(TreeCtrl->Value[I].Flags & TIF_GROUP)) - { - TreeCtrl->Value.RemoveElem(I); - TreeCtrl->SetModified(true); - I--; - } - } - } - } - TreeCtrl->MemToDB(CString(MOD_NAME)); - } -} - - -TCString CProtoSettings::GetMsgFormat(int Flags, int *pOrder) -// returns the requested message; sets Order to the order of the message in the message tree, if available; or to -1 otherwise. -{ - TCString Message = NULL; - if (pOrder) - { - *pOrder = -1; - } - if (Flags & GMF_TEMPORARY) - { - _ASSERT(!Status || Status == g_ProtoStates[szProto].Status); - if (g_ProtoStates[szProto].TempMsg.IsSet()) - { - Message = g_ProtoStates[szProto].TempMsg; - Flags &= ~GMF_PERSONAL; // don't allow personal message to overwrite our NULL temporary message - } - } - if (Flags & GMF_PERSONAL && Message == NULL) - { // try getting personal message (it overrides global) - Message = DBGetContactSettingString(NULL, MOD_NAME, ProtoStatusToDBSetting(DB_STATUSMSG, IDC_MOREOPTDLG_PERSTATUSPROTOMSGS), (TCHAR*)NULL); - } - if (Flags & GMF_PROTOORGLOBAL && Message == NULL) - { - Message = CProtoSettings().GetMsgFormat(GMF_PERSONAL | (Flags & GMF_TEMPORARY), pOrder); - return (Message == NULL) ? _T("") : Message; // global message can't be NULL - } - if (Flags & GMF_LASTORDEFAULT && Message == NULL) - { // try to get the last or default message, depending on current settings - COptPage MsgTreeData(g_MsgTreePage); - COptItem_TreeCtrl *TreeCtrl = (COptItem_TreeCtrl*)MsgTreeData.Find(IDV_MSGTREE); - TreeCtrl->DBToMem(CString(MOD_NAME)); - Message = NULL; - if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_USELASTMSG)) // if using last message by default... - { - Message = DBGetContactSettingString(NULL, MOD_NAME, ProtoStatusToDBSetting(DB_STATUSMSG, IDC_MOREOPTDLG_PERSTATUSPROTOMSGS), (TCHAR*)NULL); // try per-protocol message first - if (Message.IsEmpty()) - { - Message = NULL; // to be sure it's NULL, not "" - as we're checking 'Message == NULL' later - int RecentGroupID = GetRecentGroupID(Status); - if (RecentGroupID != -1) - { - int I; - for (I = 0; I < TreeCtrl->Value.GetSize(); I++) // find first message in the group - { - if (TreeCtrl->Value[I].ParentID == RecentGroupID && !(TreeCtrl->Value[I].Flags & TIF_GROUP)) - { - Message = TreeCtrl->Value[I].User_Str1; - if (pOrder) - { - *pOrder = I; - } - break; - } - } - } - } - } // else, if using default message by default... - if (Message == NULL) // ...or we didn't succeed retrieving the last message - { // get default message for this status - int DefMsgID = -1; - static struct { - int DBSetting, Status; - } DefMsgDlgItems[] = { - IDS_MESSAGEDLG_DEF_ONL, ID_STATUS_ONLINE, - IDS_MESSAGEDLG_DEF_AWAY, ID_STATUS_AWAY, - IDS_MESSAGEDLG_DEF_NA, ID_STATUS_NA, - IDS_MESSAGEDLG_DEF_OCC, ID_STATUS_OCCUPIED, - IDS_MESSAGEDLG_DEF_DND, ID_STATUS_DND, - IDS_MESSAGEDLG_DEF_FFC, ID_STATUS_FREECHAT, - IDS_MESSAGEDLG_DEF_INV, ID_STATUS_INVISIBLE, - IDS_MESSAGEDLG_DEF_OTP, ID_STATUS_ONTHEPHONE, - IDS_MESSAGEDLG_DEF_OTL, ID_STATUS_OUTTOLUNCH - }; - int I; - for (I = 0; I < lengthof(DefMsgDlgItems); I++) - { - if (DefMsgDlgItems[I].Status == Status) - { - DefMsgID = MsgTreeData.GetDBValue(DefMsgDlgItems[I].DBSetting); - break; - } - } - if (DefMsgID == -1) - { - DefMsgID = MsgTreeData.GetDBValue(IDS_MESSAGEDLG_DEF_AWAY); // use away message for unknown statuses - } - int Order = TreeCtrl->IDToOrder(DefMsgID); // this will return -1 in any case if something goes wrong - if (Order >= 0) - { - Message = TreeCtrl->Value[Order].User_Str1; - } - if (pOrder) - { - *pOrder = Order; - } - } - if (Message == NULL) - { - Message = _T(""); // last or default message can't be NULL.. otherwise ICQ won't reply to status message requests and won't notify us of status message requests at all - } - } - return Message; -} diff --git a/!Deprecated/NewAwaySysMod/Properties.h b/!Deprecated/NewAwaySysMod/Properties.h deleted file mode 100644 index 6b981bd77e..0000000000 --- a/!Deprecated/NewAwaySysMod/Properties.h +++ /dev/null @@ -1,605 +0,0 @@ -/* - New Away System - plugin for Miranda IM - Copyright (c) 2005-2007 Chervov Dmitry - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#pragma once - -#include "Common.h" -#include "MsgTree.h" -#include "ContactList.h" -#include "statusmodes.h" - -#define DB_STATUSMSG "StatusMsg" -#define DB_ENABLEREPLY "EnableReply" -#define DB_IGNOREREQUESTS "IgnoreRequests" -//#define DB_POPUPNOTIFY "UsePopups" -#define DB_UNK_CONTACT_PREFIX "Unk" // DB_ENABLEREPLY, DB_IGNOREREQUESTS and DB_POPUPNOTIFY settings prefix for not-on-list contacts - -class _CWndUserData -{ -public: - _CWndUserData(): MsgTree(NULL), CList(NULL) {} - - CMsgTree *MsgTree; - CCList *CList; -}; - - -class CWndUserData -{ -public: - CWndUserData(HWND hWnd): hWnd(hWnd) - { - _ASSERT(hWnd); - dat = (_CWndUserData*)GetWindowLongPtr(hWnd, GWLP_USERDATA); - if (!dat) - { - dat = new _CWndUserData; - SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)dat); - } - } - - ~CWndUserData() - { - _ASSERT(dat == (_CWndUserData*)GetWindowLongPtr(hWnd, GWLP_USERDATA)); - if (!dat->MsgTree && !dat->CList) // TODO: Uninitialized Memory Read on closing the options dialog - fix it - { - SetWindowLongPtr(hWnd, GWLP_USERDATA, NULL); - delete dat; // TODO: memory leak - this is never executed - fix it - } - } - - CMsgTree *GetMsgTree() {return dat->MsgTree;} - void SetMsgTree(CMsgTree *MsgTree) {dat->MsgTree = MsgTree;} - CCList *GetCList() {return dat->CList;} - void SetCList(CCList *CList) {dat->CList = CList;} - -private: - HWND hWnd; - _CWndUserData *dat; -}; - -#define IL_SKINICON 0x80000000 -#define IL_PROTOICON 0x40000000 - -#define ILI_NOICON (-1) -#define ILI_EVENT_MESSAGE 0 -#define ILI_EVENT_URL 1 -#define ILI_EVENT_FILE 2 -#define ILI_PROTO_ONL 3 -#define ILI_PROTO_AWAY 4 -#define ILI_PROTO_NA 5 -#define ILI_PROTO_OCC 6 -#define ILI_PROTO_DND 7 -#define ILI_PROTO_FFC 8 -#define ILI_PROTO_INV 9 -#define ILI_PROTO_OTP 10 -#define ILI_PROTO_OTL 11 -#define ILI_DOT 12 -#define ILI_MSGICON 13 -#define ILI_IGNORE 14 -#define ILI_SOE_DISABLED 15 -#define ILI_SOE_ENABLED 16 -#define ILI_NEWMESSAGE 17 -#define ILI_NEWCATEGORY 18 -#define ILI_SAVE 19 -#define ILI_SAVEASNEW 20 -#define ILI_DELETE 21 -#define ILI_SETTINGS 22 -#define ILI_STATUS_OTHER 23 - -static int Icons[] = { - SKINICON_EVENT_MESSAGE | IL_SKINICON, SKINICON_EVENT_URL | IL_SKINICON, SKINICON_EVENT_FILE | IL_SKINICON, - ID_STATUS_ONLINE | IL_PROTOICON, ID_STATUS_AWAY | IL_PROTOICON, ID_STATUS_NA | IL_PROTOICON, ID_STATUS_OCCUPIED | IL_PROTOICON, ID_STATUS_DND | IL_PROTOICON, ID_STATUS_FREECHAT | IL_PROTOICON, ID_STATUS_INVISIBLE | IL_PROTOICON, ID_STATUS_ONTHEPHONE | IL_PROTOICON, ID_STATUS_OUTTOLUNCH | IL_PROTOICON, - IDI_DOT, IDI_MSGICON, IDI_IGNORE, IDI_SOE_ENABLED, IDI_SOE_DISABLED, IDI_NEWMESSAGE, IDI_NEWCATEGORY, IDI_SAVE, IDI_SAVEASNEW, IDI_DELETE, IDI_SETTINGS, IDI_STATUS_OTHER -}; - - -class CIconList -{ -public: - ~CIconList() - { - int I; - for (I = 0; I < IconList.GetSize(); I++) - { - if (IconList[I]) - { - DestroyIcon(IconList[I]); - } - } - } - - HICON& operator [] (int nIndex) {return IconList[nIndex];} - void ReloadIcons() - { - int cxIcon = GetSystemMetrics(SM_CXSMICON); - int cyIcon = GetSystemMetrics(SM_CYSMICON); - int I; - for (I = 0; I < lengthof(Icons); I++) - { - if (IconList.GetSize() > I && IconList[I]) - { - DestroyIcon(IconList[I]); - } - if (Icons[I] & IL_SKINICON) - { - IconList.SetAtGrow(I) = (HICON)CopyImage(LoadSkinnedIcon(Icons[I] & ~IL_SKINICON), IMAGE_ICON, cxIcon, cyIcon, LR_COPYFROMRESOURCE); - } else if (Icons[I] & IL_PROTOICON) - { - IconList.SetAtGrow(I) = (HICON)CopyImage(LoadSkinnedProtoIcon(NULL, Icons[I] & ~IL_PROTOICON), IMAGE_ICON, cxIcon, cyIcon, LR_COPYFROMRESOURCE); - } else - { - IconList.SetAtGrow(I) = (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(Icons[I]), IMAGE_ICON, cxIcon, cyIcon, 0); - } - } - } - -private: - TMyArray IconList; -}; - -extern CIconList g_IconList; - - -class CProtoStates; - -class CProtoState -{ -public: - CProtoState(const char* szProto, CProtoStates* Parent): szProto(szProto), Parent(Parent), Status(szProto, Parent), AwaySince(szProto, Parent) {} - - class CStatus - { - public: - CStatus(const char* szProto, CProtoStates* GrandParent): szProto(szProto), GrandParent(GrandParent), Status(ID_STATUS_OFFLINE) {} - CStatus& operator = (int Status); - operator int() {return Status;} - friend class CProtoState; - private: - int Status; - CString szProto; - CProtoStates* GrandParent; - } Status; - - class CAwaySince - { - public: - CAwaySince(const char* szProto, CProtoStates* GrandParent): szProto(szProto), GrandParent(GrandParent) {Reset();} - void Reset(); - operator LPSYSTEMTIME() {return &AwaySince;} - friend class CProtoState; - private: - SYSTEMTIME AwaySince; - CString szProto; - CProtoStates* GrandParent; - } AwaySince; - - class CCurStatusMsg - { - public: - CCurStatusMsg() {*this = NULL;} - CCurStatusMsg& operator = (TCString Msg) - { - CurStatusMsg = Msg; - SYSTEMTIME st; - GetLocalTime(&st); - SystemTimeToFileTime(&st, (LPFILETIME)&LastUpdateTime); // I'm too lazy to declare FILETIME structure and then copy its data to absolutely equivalent ULARGE_INTEGER structure, so we'll just pass a pointer to the ULARGE_INTEGER directly ;-P - return *this; - } - operator TCString() {return CurStatusMsg;} - DWORD GetUpdateTimeDifference() - { - ULARGE_INTEGER CurTime; - SYSTEMTIME st; - GetLocalTime(&st); - SystemTimeToFileTime(&st, (LPFILETIME)&CurTime); - return (DWORD)((CurTime.QuadPart - LastUpdateTime.QuadPart) / 10000); // in milliseconds - } - private: - TCString CurStatusMsg; - ULARGE_INTEGER LastUpdateTime; - } CurStatusMsg; - - class CTempMsg - { // we use temporary messages to keep user-defined per-protocol messages intact, when changing messages through MS_NAS_SETSTATE, or when autoaway becomes active etc.. temporary messages are automatically resetted when protocol status changes - public: - CTempMsg(): iIsSet(0) {} - CTempMsg& operator = (TCString Msg) {this->Msg = Msg; iIsSet = true; return *this;} - operator TCString() - { - _ASSERT(iIsSet); - return Msg; - } - void Unset() {iIsSet = false;} - int IsSet() {return iIsSet;} - - private: - int iIsSet; // as we need TempMsg to support every possible value, including NULL and "", we'll use this variable to specify whether TempMsg is set - TCString Msg; - } TempMsg; - - void SetParent(CProtoStates* Parent) - { - this->Parent = Parent; - Status.GrandParent = Parent; - AwaySince.GrandParent = Parent; - } - - CString &GetProto() {return szProto;} - -//NightFox: fix? -//private: -public: - CString szProto; - CProtoStates* Parent; -}; - - -class CProtoStates // this class stores all protocols' dynamic data -{ -public: - CProtoStates() {} - - CProtoStates(const CProtoStates &States) {*this = States;} - CProtoStates& operator = (const CProtoStates& States) - { - ProtoStates = States.ProtoStates; - int I; - for (I = 0; I < ProtoStates.GetSize(); I++) - { - ProtoStates[I].SetParent(this); - } - return *this; - } - - CProtoState& operator[](const char *szProto) - { - int I; - for (I = 0; I < ProtoStates.GetSize(); I++) - { - if (ProtoStates[I].GetProto() == szProto) - { - return ProtoStates[I]; - } - } - if (!szProto) // we need to be sure that we have _all_ protocols in the list, before dealing with global status, so we're adding them here. - { - int ProtoCount; - PROTOCOLDESCRIPTOR **proto; - CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&ProtoCount, (LPARAM)&proto); - int I; - for (I = 0; I < ProtoCount; I++) - { - if (proto[I]->type == PROTOTYPE_PROTOCOL) - { - (*this)[proto[I]->szName]; // add a protocol if it isn't in the list yet - } - } - } - return ProtoStates[ProtoStates.AddElem(CProtoState(szProto, this))]; - } - - friend class CProtoState; - friend class CProtoState::CStatus; - friend class CProtoState::CAwaySince; - -private: - CProtoState& operator[](int nIndex) {return ProtoStates[nIndex];} - int GetSize() {return ProtoStates.GetSize();} - - TMyArray ProtoStates; -}; - -extern CProtoStates g_ProtoStates; - - -static struct -{ - int Status; - char *Setting; -} StatusSettings[] = { - ID_STATUS_OFFLINE, "Off", - ID_STATUS_ONLINE, "Onl", - ID_STATUS_AWAY, "Away", - ID_STATUS_NA, "Na", - ID_STATUS_DND, "Dnd", - ID_STATUS_OCCUPIED, "Occ", - ID_STATUS_FREECHAT, "Ffc", - ID_STATUS_INVISIBLE, "Inv", - ID_STATUS_ONTHEPHONE, "Otp", - ID_STATUS_OUTTOLUNCH, "Otl", - ID_STATUS_IDLE, "Idle" -}; - - -class CProtoSettings -{ -public: - CProtoSettings(const char *szProto = NULL, int iStatus = 0): szProto(szProto), Status(iStatus, szProto) - { - Autoreply.Parent = this; - } - - CString ProtoStatusToDBSetting(const char *Prefix, int MoreOpt_PerStatusID = 0) - { - if (!MoreOpt_PerStatusID || g_MoreOptPage.GetDBValueCopy(MoreOpt_PerStatusID)) - { - int I; - for (I = 0; I < lengthof(StatusSettings); I++) - { - if (Status == StatusSettings[I].Status) - { - return szProto ? (CString(Prefix) + "_" + szProto + "_" + StatusSettings[I].Setting) : (CString(Prefix) + StatusSettings[I].Setting); - } - } - } - return szProto ? (CString(Prefix) + "_" + szProto) : CString(Prefix); - } - - class CAutoreply - { - public: - CAutoreply& operator = (const int Value) - { - CString Setting(Parent->szProto ? Parent->ProtoStatusToDBSetting(DB_ENABLEREPLY, IDC_MOREOPTDLG_PERSTATUSPROTOSETTINGS) : DB_ENABLEREPLY); - if (DBGetContactSettingByte(NULL, MOD_NAME, Setting, VAL_USEDEFAULT) == Value) - { - return *this; // prevent deadlocks when calling UpdateSOEButtons - } - if (Value != VAL_USEDEFAULT) - { - DBWriteContactSettingByte(NULL, MOD_NAME, Setting, Value != 0); - } else - { - DBDeleteContactSetting(NULL, MOD_NAME, Setting); - } - /*if (!Parent->szProto) - { - UpdateSOEButtons(); - }*/ - return *this; - } - operator int() {return DBGetContactSettingByte(NULL, MOD_NAME, Parent->szProto ? Parent->ProtoStatusToDBSetting(DB_ENABLEREPLY, IDC_MOREOPTDLG_PERSTATUSPROTOSETTINGS) : DB_ENABLEREPLY, Parent->szProto ? VAL_USEDEFAULT : AUTOREPLY_DEF_REPLY);} - int IncludingParents() // takes into account global data also, if per-protocol setting is not defined - { - _ASSERT(Parent->szProto); - int Value = *this; - return (Value == VAL_USEDEFAULT) ? CProtoSettings(NULL).Autoreply : Value; - } - friend class CProtoSettings; - private: - CProtoSettings *Parent; - } Autoreply; - - class CStatus - { - public: - CStatus(int iStatus = 0, const char *szProto = NULL): Status(iStatus), szProto(szProto) {} - CStatus& operator = (int Status) {this->Status = Status; return *this;} - operator int() - { - if (!Status) - { - Status = g_ProtoStates[szProto].Status; - } - return Status; - } - private: - int Status; - const char *szProto; - } Status; - - void SetMsgFormat(int Flags, TCString Message); - TCString GetMsgFormat(int Flags, int *pOrder = NULL); - -//NightFox: fix? -//private: -public: - const char *szProto; -}; - - -__inline CString StatusToDBSetting(int Status, const char *Prefix, int MoreOpt_PerStatusID = 0) -{ - if (!MoreOpt_PerStatusID || g_MoreOptPage.GetDBValueCopy(MoreOpt_PerStatusID)) - { - int I; - for (I = 0; I < lengthof(StatusSettings); I++) - { - if (Status == StatusSettings[I].Status) - { - return CString(Prefix) + StatusSettings[I].Setting; - } - } - } - return CString(Prefix); -} - - -__inline CString ContactStatusToDBSetting(int Status, const char *Prefix, int MoreOpt_PerStatusID, HANDLE hContact) -{ - if (hContact == INVALID_HANDLE_VALUE) - { // it's a not-on-list contact - return CString(DB_UNK_CONTACT_PREFIX) + Prefix; - } - if (hContact) - { - StatusToDBSetting(Status, Prefix, MoreOpt_PerStatusID); - } - return CString(Prefix); -} - - -class CContactSettings -{ -public: - CContactSettings(int iStatus = 0, HANDLE hContact = NULL): Status(iStatus, hContact), hContact(hContact) - { - Ignore.Parent = this; - Autoreply.Parent = this; -// PopupNotify.Parent = this; - } - - CString ContactStatusToDBSetting(const char *Prefix, int MoreOpt_PerStatusID = 0) - { - return ::ContactStatusToDBSetting((hContact != INVALID_HANDLE_VALUE) ? Status : NULL, Prefix, MoreOpt_PerStatusID, hContact); - } - - class CIgnore - { - public: - CIgnore& operator = (const int Value) - { - CString Setting(Parent->ContactStatusToDBSetting(DB_IGNOREREQUESTS, IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS)); - HANDLE hContact = (Parent->hContact != INVALID_HANDLE_VALUE) ? Parent->hContact : NULL; - if (Value) - { - DBWriteContactSettingByte(hContact, MOD_NAME, Setting, 1); - } else - { - DBDeleteContactSetting(hContact, MOD_NAME, Setting); - } - return *this; - } - operator int() {return DBGetContactSettingByte((Parent->hContact != INVALID_HANDLE_VALUE) ? Parent->hContact : NULL, MOD_NAME, Parent->ContactStatusToDBSetting(DB_IGNOREREQUESTS, IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS), 0);} - friend class CContactSettings; - private: - CContactSettings *Parent; - } Ignore; - - class CAutoreply - { - public: - CAutoreply& operator = (const int Value) - { - CString Setting(Parent->ContactStatusToDBSetting(DB_ENABLEREPLY, IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS)); - HANDLE hContact = (Parent->hContact != INVALID_HANDLE_VALUE) ? Parent->hContact : NULL; - if (DBGetContactSettingByte(hContact, MOD_NAME, Setting, VAL_USEDEFAULT) == Value) - { - return *this; // prevent deadlocks when calling UpdateSOEButtons - } - if (Value != VAL_USEDEFAULT) - { - DBWriteContactSettingByte(hContact, MOD_NAME, Setting, Value != 0); - } else - { - DBDeleteContactSetting(hContact, MOD_NAME, Setting); - } - /*if (Parent->hContact != INVALID_HANDLE_VALUE) - { - UpdateSOEButtons(Parent->hContact); - }*/ - return *this; - } - operator int() {return DBGetContactSettingByte((Parent->hContact != INVALID_HANDLE_VALUE) ? Parent->hContact : NULL, MOD_NAME, Parent->ContactStatusToDBSetting(DB_ENABLEREPLY, IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS), Parent->hContact ? VAL_USEDEFAULT : AUTOREPLY_DEF_REPLY);} - int IncludingParents(const char *szProtoOverride = NULL) // takes into account protocol and global data also, if per-contact setting is not defined - { - _ASSERT((Parent->hContact && Parent->hContact != INVALID_HANDLE_VALUE) || szProtoOverride); // we need either correct protocol or a correct hContact to determine its protocol - int Value = *this; - if (Value == VAL_USEDEFAULT) - { - const char *szProto = (Parent->hContact && Parent->hContact != INVALID_HANDLE_VALUE) ? (const char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)Parent->hContact, 0) : szProtoOverride; - return CProtoSettings(szProto).Autoreply.IncludingParents(); - } - return Value; - } - int GetNextToggleValue() - { - switch ((int)*this) - { - case VAL_USEDEFAULT: return 0; break; - case 0: return 1; break; - default: return Parent->hContact ? VAL_USEDEFAULT : AUTOREPLY_DEF_REPLY; break; - } - } - int Toggle() {return *this = GetNextToggleValue();} - friend class CContactSettings; - private: - CContactSettings *Parent; - } Autoreply; - -/* class CPopupNotify - { - public: - CPopupNotify& operator = (const int Value) - { - //CString Setting(Parent->ContactStatusToDBSetting(DB_POPUPNOTIFY, 0)); //IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS - HANDLE hContact = (Parent->hContact != INVALID_HANDLE_VALUE) ? Parent->hContact : NULL; - if (DBGetContactSettingByte(hContact, MOD_NAME, Setting, VAL_USEDEFAULT) == Value) - { - return *this; // prevent deadlocks when calling UpdateSOEButtons - } - if (Value != VAL_USEDEFAULT) - { - DBWriteContactSettingByte(hContact, MOD_NAME, Setting, Value != 0); - } else - { - DBDeleteContactSetting(hContact, MOD_NAME, Setting); - } - if (!Parent->hContact) - { - //UpdateSOEButtons(); - } - return *this; - } - operator int() {return DBGetContactSettingByte((Parent->hContact != INVALID_HANDLE_VALUE) ? Parent->hContact : NULL, MOD_NAME, Parent->ContactStatusToDBSetting(DB_POPUPNOTIFY, 0), Parent->hContact ? VAL_USEDEFAULT : POPUP_DEF_USEPOPUPS);} //IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS - int IncludingParents() // takes into account protocol and global data also, if per-contact setting is not defined - { - int Value = *this; - if (Value == VAL_USEDEFAULT) - { // PopupNotify setting is not per-status - return CContactSettings(ID_STATUS_ONLINE).PopupNotify; - } - return Value; - } - friend class CContactSettings; - private: - CContactSettings *Parent; - } PopupNotify; -*/ - class CStatus - { - public: - CStatus(int iStatus = 0, HANDLE hContact = NULL): Status(iStatus), hContact(hContact) {} - CStatus& operator = (int Status) {this->Status = Status; return *this;} - operator int() - { - if (!Status) - { - _ASSERT(hContact != INVALID_HANDLE_VALUE); - char *szProto = hContact ? (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0) : NULL; - Status = (szProto || !hContact) ? g_ProtoStates[szProto].Status : ID_STATUS_AWAY; - } - return Status; - } - friend class CPopupNotify; - friend class CAutoreply; - private: - int Status; - HANDLE hContact; - } Status; - - void SetMsgFormat(int Flags, TCString Message); - TCString GetMsgFormat(int Flags, int *pOrder = NULL, char *szProtoOverride = NULL); - -//NightFox: fix? -//private: -public: - HANDLE hContact; -}; diff --git a/!Deprecated/NewAwaySysMod/ReadAwayMsg.cpp b/!Deprecated/NewAwaySysMod/ReadAwayMsg.cpp deleted file mode 100644 index 6d197b7614..0000000000 --- a/!Deprecated/NewAwaySysMod/ReadAwayMsg.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/* - New Away System - plugin for Miranda IM - Copyright (C) 2005-2007 Chervov Dmitry - Copyright (C) 2004-2005 Iksaif Entertainment - Copyright (C) 2002-2003 Goblineye Entertainment - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "Common.h" - -#define RAMDLGSIZESETTING "ReadAwayMsgDlg" - -HANDLE g_hReadWndList = NULL; - - -static int ReadAwayMsgDlgResize(HWND hwndDlg, LPARAM lParam, UTILRESIZECONTROL *urc) -{ - switch (urc->wId) - { - case IDC_READAWAYMSG_MSG: - { - return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; - } - case IDC_READAWAYMSG_RETRIEVE: - { - return RD_ANCHORX_CENTRE | RD_ANCHORY_CENTRE; - } - case IDOK: - { - return RD_ANCHORX_CENTRE | RD_ANCHORY_BOTTOM; - } - } - return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; -} - - -static INT_PTR CALLBACK ReadAwayMsgDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - HICON hTitleIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); - SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hTitleIcon); - SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hTitleIcon); - Utils_RestoreWindowPosition(hwndDlg, NULL, MOD_NAME, RAMDLGSIZESETTING); - READAWAYMSGDATA *awayData = new READAWAYMSGDATA; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)awayData); - awayData->hContact = (HANDLE)lParam; - awayData->hAwayMsgEvent = HookEventMessage(ME_PROTO_ACK, hwndDlg, UM_RAM_AWAYMSGACK); - awayData->hSeq = (HANDLE)CallContactService(awayData->hContact, PSS_GETAWAYMSG, 0, 0); - WindowList_Add(g_hReadWndList, hwndDlg, awayData->hContact); - - TCHAR str[256], format[128]; - TCHAR *status, *contactName; - contactName = (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)awayData->hContact, GCDNF_TCHAR); - char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)awayData->hContact, 0); - status = (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, DBGetContactSettingWord(awayData->hContact, szProto, "Status", ID_STATUS_OFFLINE), GSMDF_TCHAR); - GetWindowText(hwndDlg, format, lengthof(format)); - _sntprintf(str, lengthof(str), format, status, contactName); - SetWindowText(hwndDlg, str); - GetDlgItemText(hwndDlg, IDC_READAWAYMSG_RETRIEVE, format, sizeof(format)); - _sntprintf(str, lengthof(str), format, status); - SetDlgItemText(hwndDlg, IDC_READAWAYMSG_RETRIEVE, str); - return true; - } break; - case UM_RAM_AWAYMSGACK: // got away msg - { - ACKDATA *ack = (ACKDATA*)lParam; - READAWAYMSGDATA *awayData = (READAWAYMSGDATA*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - // make sure everything is ok, and this is our ack - if (ack->hContact != awayData->hContact || ack->type != ACKTYPE_AWAYMSG || ack->hProcess != awayData->hSeq || ack->result != ACKRESULT_SUCCESS) - { - break; - } - // done with the event - if (awayData->hAwayMsgEvent) - { - UnhookEvent(awayData->hAwayMsgEvent); - awayData->hAwayMsgEvent = NULL; - } - SetDlgItemText(hwndDlg, IDC_READAWAYMSG_MSG, (const TCHAR*)ack->lParam); - ShowWindow(GetDlgItem(hwndDlg, IDC_READAWAYMSG_RETRIEVE), SW_HIDE); - ShowWindow(GetDlgItem(hwndDlg, IDC_READAWAYMSG_MSG), SW_SHOW); - SetDlgItemText(hwndDlg, IDOK, TranslateT("&Close")); - DBWriteContactSettingString(awayData->hContact, "CList", "StatusMsg", (const char*)ack->lParam); - } break; - case WM_COMMAND: - { - switch (HIWORD(wParam)) - { - case BN_CLICKED: - { - switch(LOWORD(wParam)) - { - case IDCANCEL: - case IDOK: - { - DestroyWindow(hwndDlg); - } break; - } - } break; - } - } break; - case WM_SIZE: - { - UTILRESIZEDIALOG urd = {0}; - urd.cbSize = sizeof(urd); - urd.hInstance = g_hInstance; - urd.hwndDlg = hwndDlg; - urd.lpTemplate = MAKEINTRESOURCEA(IDD_READAWAYMSG); - urd.pfnResizer = ReadAwayMsgDlgResize; - CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); - break; - } - case WM_CLOSE: - { - DestroyWindow(hwndDlg); - } break; - case WM_DESTROY: - { - READAWAYMSGDATA *awayData = (READAWAYMSGDATA*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - if (awayData->hAwayMsgEvent) - { - UnhookEvent(awayData->hAwayMsgEvent); - awayData->hAwayMsgEvent = NULL; - } - delete awayData; - Utils_SaveWindowPosition(hwndDlg, NULL, MOD_NAME, RAMDLGSIZESETTING); - WindowList_Remove(g_hReadWndList, hwndDlg); - } break; - } - return false; -} - - -INT_PTR GetContactStatMsg(WPARAM wParam, LPARAM lParam) -{ - if (HWND hWnd = WindowList_Find(g_hReadWndList, (HANDLE)wParam)) // already have it - { - SetForegroundWindow(hWnd); - } else - { - CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_READAWAYMSG), NULL, ReadAwayMsgDlgProc, wParam); - } - return 0; -} diff --git a/!Deprecated/NewAwaySysMod/Services.cpp b/!Deprecated/NewAwaySysMod/Services.cpp deleted file mode 100644 index c8108eb1a9..0000000000 --- a/!Deprecated/NewAwaySysMod/Services.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/* - New Away System - plugin for Miranda IM - Copyright (c) 2005-2007 Chervov Dmitry - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - - -#include "Common.h" -#include "Properties.h" -#include "m_NewAwaySys.h" - - -typedef struct { - int cbSize; - char *szProto; - union - { - char *szMsg; - WCHAR *wszMsg; - TCHAR *tszMsg; - }; - WORD status; -} NAS_PROTOINFOv1; - - -__inline void PSSetStatus(char *szProto, WORD Status, int bNoClistSetStatusMode = false) // just a helper function that sets the status and handles szProto==NULL correctly -{ - g_ProtoStates[szProto].Status = Status; - if (szProto) - { - CallProtoService(szProto, PS_SETSTATUS, Status, 0); - } else if (!bNoClistSetStatusMode) // global status - { -/* int ProtoCount; - PROTOCOLDESCRIPTOR **proto; - CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&ProtoCount, (LPARAM)&proto); - int i; - for (i = 0; i < ProtoCount; i++) - { - if (proto[i]->type == PROTOTYPE_PROTOCOL) - { - CallProtoService(proto[i]->szName, PS_SETSTATUS, Status, 0); - } - }*/ - g_fNoProcessing = true; - CallService(MS_CLIST_SETSTATUSMODE, Status, 0); - _ASSERT(!g_fNoProcessing && g_ProtoStates[(char*)NULL].Status == Status); - g_fNoProcessing = false; - } -} - - -INT_PTR GetStatusMsg(WPARAM wParam, LPARAM lParam) // called by GamerStatus and built-in miranda autoaway module -// wParam = (int)status, lParam = 0 -// MS_AWAYMSG_GETSTATUSMSG "SRAway/GetStatusMessage" -{ - LogMessage("MS_AWAYMSG_GETSTATUSMSG called. status=%d", wParam); - CString Msg(TCHAR2ANSI(GetDynamicStatMsg(INVALID_HANDLE_VALUE, NULL, 0, wParam))); - char *szMsg; - if (Msg == NULL) - { // it's ok to return NULL, so we'll do it - szMsg = NULL; - } else - { - szMsg = (char*)mir_alloc(Msg.GetLen() + 1); - lstrcpyA(szMsg, Msg); - } - LogMessage("returned szMsg:\n%s", szMsg ? szMsg : "NULL"); - return (int)szMsg; -} - - -INT_PTR SetStatusMode(WPARAM wParam, LPARAM lParam) // called by GamerStatus and StatCtrl -{ -// wParam = int iMode -// lParam = char* szMsg, may be null - then we need to use the default message -/* if (CallService(MS_CLIST_GETSTATUSMODE, 0, 0) != wParam) // not same status - {*/ // try this way; global status may be not the same as current status of some separate protocol - LogMessage("MS_AWAYSYS_SETSTATUSMODE called. status=%d, szMsg:\n%s", wParam, lParam ? (char*)lParam : "NULL"); - g_fNoProcessing = true; - CallService(MS_CLIST_SETSTATUSMODE, wParam, 0); -// } - _ASSERT(!g_fNoProcessing && g_ProtoStates[(char*)NULL].Status == wParam); - g_fNoProcessing = false; - CProtoSettings(NULL, wParam).SetMsgFormat(SMF_TEMPORARY, lParam ? ANSI2TCHAR((char*)lParam) : CProtoSettings(NULL, wParam).GetMsgFormat(GMF_LASTORDEFAULT)); - ChangeProtoMessages(NULL, wParam, TCString()); - return 0; -} - - -int GetState(WPARAM wParam, LPARAM lParam, int Widechar) -// wParam = (WPARAM)(NAS_PROTOINFO*)pi - pointer to an array of NAS_PROTOINFO items to be filled. -// lParam = (LPARAM)(int)protoCount - number of items in pi. -// returns 0 on success -{ - NAS_PROTOINFO *pi = (NAS_PROTOINFO*)wParam; - LogMessage("MS_NAS_GETSTATE called with %d items and Widechar=%d:", lParam, Widechar); - for (int i = 0; i < lParam; i++) - { - if (pi->cbSize < sizeof(NAS_PROTOINFO) && pi->cbSize != sizeof(NAS_PROTOINFOv1)) - return 1; - - int Flags = (pi->cbSize > sizeof(NAS_PROTOINFOv1)) ? pi->Flags : 0; - LogMessage("%d (received): cbSize=%d, status=%d, szProto=%s, Flags=0x%x", i + 1, pi->cbSize, pi->status, pi->szProto ? pi->szProto : "NULL", Flags); - if ((pi->status >= ID_STATUS_ONLINE && pi->status <= ID_STATUS_OUTTOLUNCH) || !pi->status) - { - TCString Msg(pi->status ? CProtoSettings(pi->szProto, pi->status).GetMsgFormat(GMF_LASTORDEFAULT) : CProtoSettings(pi->szProto).GetMsgFormat(((Flags & PIF_NOTTEMPORARY) ? 0 : GMF_TEMPORARY) | GMF_PERSONAL)); - if (Msg != NULL) - { - pi->szMsg = (char*)mir_alloc(Msg.GetLen() + 1); - _ASSERT(pi->szMsg); - if (Widechar) - lstrcpyW(pi->wszMsg, TCHAR2WCHAR(Msg)); - else - lstrcpyA(pi->szMsg, TCHAR2ANSI(Msg)); - } - else pi->szMsg = NULL; - - if (!pi->status) - pi->status = g_ProtoStates[pi->szProto].Status; - } - else pi->szMsg = NULL; - - LogMessage("%d (returned): status=%d, Flags=0x%x, szMsg:\n%s", i + 1, pi->status, (pi->cbSize > sizeof(NAS_PROTOINFOv1)) ? pi->Flags : 0, pi->szMsg ? (Widechar ? WCHAR2ANSI(pi->wszMsg) : pi->szMsg) : "NULL"); - *(char**)&pi += pi->cbSize; - } - return 0; -} - - -INT_PTR GetStateA(WPARAM wParam, LPARAM lParam) -{ - return GetState(wParam, lParam, false); -} - - -INT_PTR GetStateW(WPARAM wParam, LPARAM lParam) -{ - return GetState(wParam, lParam, true); -} - - -int SetState(WPARAM wParam, LPARAM lParam, int Widechar) -// wParam = (WPARAM)(NAS_PROTOINFO*)pi - pointer to an array of NAS_PROTOINFO items. -// lParam = (LPARAM)(int)protoCount - number of items in pi. -// returns 0 on success -{ - NAS_PROTOINFO *pi = (NAS_PROTOINFO*)wParam; - LogMessage("MS_NAS_SETSTATE called with %d items and Widechar=%d:", lParam, Widechar); - for (int i = 0; i < lParam; i++) - { - _ASSERT(pi->szMsg != (char*)(-1)); - if (pi->cbSize < sizeof(NAS_PROTOINFO) && pi->cbSize != sizeof(NAS_PROTOINFOv1)) - return 1; - - int Flags = (pi->cbSize > sizeof(NAS_PROTOINFOv1)) ? pi->Flags : 0; - LogMessage("%d: cbSize=%d, status=%d, szProto=%s, Flags=0x%x, szMsg:\n%s", i + 1, pi->cbSize, pi->status, pi->szProto ? pi->szProto : "NULL", Flags, pi->szMsg ? (Widechar ? WCHAR2ANSI(pi->wszMsg) : pi->szMsg) : "NULL"); - if (pi->status) - PSSetStatus(pi->szProto, pi->status, Flags & PIF_NO_CLIST_SETSTATUSMODE); - else - pi->status = g_ProtoStates[pi->szProto].Status; - - CProtoSettings(pi->szProto).SetMsgFormat((Flags & PIF_NOTTEMPORARY) ? SMF_PERSONAL : SMF_TEMPORARY, Widechar ? WCHAR2TCHAR(pi->wszMsg) : ANSI2TCHAR(pi->szMsg)); - if (pi->szMsg || !(Flags & PIF_NO_CLIST_SETSTATUSMODE)) - ChangeProtoMessages(pi->szProto, pi->status, TCString()); - - mir_free(pi->szMsg); - pi->szMsg = (char*)(-1); - *(char**)&pi += pi->cbSize; - } - return 0; -} - - -INT_PTR SetStateA(WPARAM wParam, LPARAM lParam) -{ - return SetState(wParam, lParam, false); -} - - -INT_PTR SetStateW(WPARAM wParam, LPARAM lParam) -{ - return SetState(wParam, lParam, true); -} - - -INT_PTR InvokeStatusWindow(WPARAM wParam, LPARAM lParam) -// wParam = (WPARAM)(NAS_ISWINFO*)iswi - pointer to a NAS_ISWINFO structure. -// lParam = 0 -// returns HWND of the window on success, or NULL on failure. -{ - NAS_ISWINFO *iswi = (NAS_ISWINFO*)wParam; - if (iswi->cbSize != sizeof(NAS_ISWINFOv1) && iswi->cbSize < sizeof(NAS_ISWINFO)) - { - return NULL; - } - LogMessage("MS_NAS_INVOKESTATUSWINDOW called. cbSize=%d, status=%d, szProto=%s, hContact=0x%08x, Flags=0x%x, szMsg:\n%s", iswi->cbSize, iswi->status, iswi->szProto ? iswi->szProto : "NULL", iswi->hContact, (iswi->cbSize < sizeof(NAS_ISWINFO)) ? 0 : iswi->Flags, iswi->szMsg ? ((iswi->Flags & ISWF_UNICODE) ? WCHAR2ANSI(iswi->wszMsg) : iswi->szMsg) : "NULL"); - if (iswi->status) - { - PSSetStatus(iswi->szProto, iswi->status); - } - if (g_SetAwayMsgPage.GetWnd()) // already setting something - { - SetForegroundWindow(g_SetAwayMsgPage.GetWnd()); - return (int)g_SetAwayMsgPage.GetWnd(); - } - SetAwayMsgData *dat = new SetAwayMsgData; - ZeroMemory(dat, sizeof(SetAwayMsgData)); - dat->hInitContact = iswi->hContact; - dat->szProtocol = iswi->szProto; - dat->Message = (iswi->Flags & ISWF_UNICODE) ? WCHAR2TCHAR(iswi->wszMsg) : ANSI2TCHAR(iswi->szMsg); - dat->IsModeless = true; - if (iswi->cbSize > sizeof(NAS_ISWINFOv1)) - { - dat->ISW_Flags = iswi->Flags; - } - return (int)CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_SETAWAYMSG), NULL, SetAwayMsgDlgProc, (LPARAM)dat); -} diff --git a/!Deprecated/NewAwaySysMod/Services.h b/!Deprecated/NewAwaySysMod/Services.h deleted file mode 100644 index 903bbd3784..0000000000 --- a/!Deprecated/NewAwaySysMod/Services.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - New Away System - plugin for Miranda IM - Copyright (c) 2005-2007 Chervov Dmitry - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -INT_PTR GetStatusMsg(WPARAM wParam, LPARAM lParam); -INT_PTR SetStatusMode(WPARAM wParam, LPARAM lParam); -// int IgnoreNextStatusChange(WPARAM wParam, LPARAM lParam); -INT_PTR GetStateA(WPARAM wParam, LPARAM lParam); -INT_PTR SetStateA(WPARAM wParam, LPARAM lParam); -INT_PTR GetStateW(WPARAM wParam, LPARAM lParam); -INT_PTR SetStateW(WPARAM wParam, LPARAM lParam); -INT_PTR InvokeStatusWindow(WPARAM wParam, LPARAM lParam); diff --git a/!Deprecated/NewAwaySysMod/SetAwayMsg.cpp b/!Deprecated/NewAwaySysMod/SetAwayMsg.cpp deleted file mode 100644 index 46748b991b..0000000000 --- a/!Deprecated/NewAwaySysMod/SetAwayMsg.cpp +++ /dev/null @@ -1,1706 +0,0 @@ -/* - New Away System plugin for Miranda IM - Copyright (c) 2005-2007 Chervov Dmitry - Copyright (c) 2004-2005 Iksaif Entertainment - Copyright (c) 2002-2003 Goblineye Entertainment - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - - -#include "Common.h" -#include "m_button.h" -#include "m_icolib.h" -#include "ContactList.h" -#include "MsgTree.h" -#include "Properties.h" -#include "m_NewAwaySys.h" - -#define EXTRAIMGLIST_DOT 0 -#define EXTRAIMGLIST_IGNORE 1 -#define EXTRAIMGLIST_MSG 2 -#define EXTRAIMGLIST_AUTOREPLY_ON 3 -#define EXTRAIMGLIST_AUTOREPLY_OFF 4 - -#define EXTRACOLUMN_IGNORE 0 -#define EXTRACOLUMN_REPLY 1 - -#define MINSPLITTERPOS 176 -#define MINYDLGSIZE 100 - -#define SAM_TIMER_ID 1 - -#define UM_SAM_INITCLIST (WM_USER + 100) - -#define CLSEL_DAT_CONTACT ((PTREEITEMARRAY)(-1)) // these constants are used to specify selection when the contact list is not loaded -#define CLSEL_DAT_NOTHING ((PTREEITEMARRAY)(-2)) - -static WNDPROC g_OrigEditMsgProc; -static WNDPROC g_OrigSplitterProc; -static WNDPROC g_OrigCListProc; -static int g_VariablesButtonDX; -static int g_MsgSplitterX, g_ContactSplitterX; -static int MinMsgSplitterX, MinContactSplitterX; -static int MinMsgEditSize; // used to calculate minimal X size of the dialog - - - -static LRESULT CALLBACK MsgEditSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - switch (Msg) - { - case WM_CHAR: - { - if (GetKeyState(VK_CONTROL) & 0x8000) - { - if (wParam == '\n') - { // ctrl-enter - PostMessage(GetParent(hWnd), WM_COMMAND, IDC_OK, 0); - return 0; - } - if (wParam == 1) - { // ctrl-a - SendMessage(hWnd, EM_SETSEL, 0, -1); - return 0; - } - if (wParam == 23) - { // ctrl-w - SendMessage(GetParent(hWnd), WM_CLOSE, 0, 0); - return 0; - } - if (wParam == 127) - { // ctrl-backspace - DWORD start, end; - SendMessage(hWnd, EM_GETSEL, (WPARAM)&end, NULL); - SendMessage(hWnd, WM_KEYDOWN, VK_LEFT, 0); - SendMessage(hWnd, EM_GETSEL, (WPARAM)&start, NULL); - int nLen = GetWindowTextLength(hWnd); - TCHAR *text = (TCHAR*)malloc((nLen + 1) * sizeof(TCHAR)); - GetWindowText(hWnd, text, nLen + 1); - MoveMemory(text + start, text + end, sizeof(TCHAR) * (_tcslen(text) + 1 - end)); - SetWindowText(hWnd, text); - free(text); - SendMessage(hWnd, EM_SETSEL, start, start); - SendMessage(GetParent(hWnd), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hWnd), EN_CHANGE), (LPARAM)hWnd); - return 0; - } - } - } break; - case WM_KEYDOWN: - { - SendMessage(GetParent(hWnd), UM_SAM_KILLTIMER, 0, 0); - } break; - } - return CallWindowProc(g_OrigEditMsgProc, hWnd, Msg, wParam, lParam); -} - -// used splitter code from TabSRMM as a base -static LRESULT CALLBACK SplitterSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - switch (Msg) - { - case WM_NCHITTEST: - { - return HTCLIENT; - } - case WM_SETCURSOR: - { - SetCursor(LoadCursor(NULL, IDC_SIZEWE)); - return true; - } - case WM_LBUTTONDOWN: - { - SetCapture(hWnd); - return false; - } - case WM_MOUSEMOVE: - { - if (GetCapture() == hWnd) - { - RECT rc; - GetClientRect(hWnd, &rc); - SendMessage(GetParent(hWnd), UM_SAM_SPLITTERMOVED, (short)LOWORD(GetMessagePos()) + rc.right / 2, (LPARAM)GetDlgCtrlID(hWnd)); - } - return 0; - } - case WM_LBUTTONUP: - { - ReleaseCapture(); - return false; - } - } - return CallWindowProc(g_OrigSplitterProc, hWnd, Msg, wParam, lParam); -} - -static LRESULT CALLBACK CListSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - CCList *dat = CWndUserData(GetParent(hWnd)).GetCList(); - switch (Msg) - { - case WM_MOUSEMOVE: - { - DWORD hitFlags; - POINT pt = {(short)LOWORD(lParam), (short)HIWORD(lParam)}; - if (dat->HitTest(&pt, &hitFlags) && hitFlags & MCLCHT_ONITEMEXTRA) - { - lParam = 0; // reset mouse coordinates, so TreeView's wndproc will not draw any item in a hovered state - } - } break; - case WM_LBUTTONDOWN: - case WM_LBUTTONDBLCLK: - { - DWORD hitFlags; - POINT pt = {(short)LOWORD(lParam), (short)HIWORD(lParam)}; - if (dat->HitTest(&pt, &hitFlags) && hitFlags & MCLCHT_ONITEMEXTRA) - { - SetFocus(hWnd); - NMHDR nmhdr; - nmhdr.code = NM_CLICK; - nmhdr.hwndFrom = hWnd; - nmhdr.idFrom = GetDlgCtrlID(hWnd); - SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nmhdr); - return DefWindowProc(hWnd, Msg, wParam, lParam); - } - } break; - } - return CallWindowProc(g_OrigCListProc, hWnd, Msg, wParam, lParam); -} - - -static int SetAwayMsgDlgResize(HWND hwndDlg, LPARAM lParam, UTILRESIZECONTROL *urc) -{ - COptPage *SetAwayMsgPage = (COptPage*)lParam; - int bShowMsgTree = SetAwayMsgPage->GetValue(IDS_SAWAYMSG_SHOWMSGTREE); - int bShowContactTree = SetAwayMsgPage->GetValue(IDS_SAWAYMSG_SHOWCONTACTTREE); - switch (urc->wId) - { - case IDC_SAWAYMSG_MSGDATA: - { - urc->rcItem.right = urc->dlgOriginalSize.cx - 2; - if (bShowContactTree) - { - urc->rcItem.right -= g_ContactSplitterX; - } - urc->rcItem.left = (bShowMsgTree) ? (g_MsgSplitterX + 2) : 2; - return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; - } - case IDC_SAWAYMSG_TREE: - { - urc->rcItem.right = g_MsgSplitterX - 2; - return RD_ANCHORX_LEFT | RD_ANCHORY_HEIGHT; - } - case IDC_SAWAYMSG_CONTACTSTREE: - { - urc->rcItem.left = urc->dlgOriginalSize.cx - g_ContactSplitterX + 2; - return RD_ANCHORX_RIGHT | RD_ANCHORY_HEIGHT; - } - case IDC_OK: - { - int X = bShowMsgTree ? min(max(g_MsgSplitterX, MinMsgSplitterX), urc->dlgNewSize.cx - ((bShowContactTree ? MinContactSplitterX : 0) + MinMsgEditSize)) : 0; - OffsetRect(&urc->rcItem, X + 2 - urc->rcItem.left, 0); - return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM; - } - case IDC_SAWAYMSG_EDITMSGS: - case IDC_SAWAYMSG_SAVEMSG: - case IDC_SAWAYMSG_SAVEASNEW: - case IDC_SAWAYMSG_NEWCATEGORY: - case IDC_SAWAYMSG_DELETE: - { - return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM; - } - case IDC_SAWAYMSG_VARS: - case IDC_SAWAYMSG_OPTIONS: - { - int X = bShowContactTree ? max(min(g_ContactSplitterX, urc->dlgNewSize.cx - (bShowMsgTree ? max(g_MsgSplitterX, MinMsgSplitterX) : 0) - MinMsgEditSize), MinContactSplitterX) : 0; - OffsetRect(&urc->rcItem, urc->dlgOriginalSize.cx - X - 2 - urc->rcItem.right - ((urc->wId == IDC_SAWAYMSG_VARS) ? g_VariablesButtonDX : 0), 0); - return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM; - } - case IDC_SAWAYMSG_STATIC_IGNOREICON: - case IDC_SAWAYMSG_STATIC_REPLYICON: - { - urc->rcItem.left = urc->rcItem.right - 16; - urc->rcItem.top = urc->rcItem.bottom - 16; - } // go through - case IDC_SAWAYMSG_IGNOREREQ: - case IDC_SAWAYMSG_SENDMSG: - { - return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM; - } - case IDC_SAWAYMSG_MSGSPLITTER: - { - OffsetRect(&urc->rcItem, g_MsgSplitterX - (urc->rcItem.left + ++urc->rcItem.right) / 2, 0); - return RD_ANCHORX_LEFT | RD_ANCHORY_HEIGHT; - } - case IDC_SAWAYMSG_CONTACTSPLITTER: - { - OffsetRect(&urc->rcItem, urc->dlgOriginalSize.cx - g_ContactSplitterX - (urc->rcItem.left + urc->rcItem.right) / 2, 0); - return RD_ANCHORX_RIGHT | RD_ANCHORY_HEIGHT; - } - } - - - return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM; -} - - -__inline int DBValueToReplyIcon(int Value) -{ - switch (Value) - { - case VAL_USEDEFAULT: return EXTRAIMGLIST_DOT; - case 0: return EXTRAIMGLIST_AUTOREPLY_OFF; - default: return EXTRAIMGLIST_AUTOREPLY_ON; - } -} - - -int GetRealReplyIcon(CCList *CList, HTREEITEM hItem) -{ - _ASSERT(CList); - HANDLE hContact = CList->GethContact(hItem); - int ItemType = CList->GetItemType(hItem); - char *szProto = (char*)CList->GetItemParam(hItem); - return (ItemType == MCLCIT_GROUP) ? CList->GetItemParam(hItem) : DBValueToReplyIcon((ItemType == MCLCIT_CONTACT) ? (int)CContactSettings(0, hContact).Autoreply : CProtoSettings(szProto).Autoreply); -} - - -void SetExtraIcon(CCList *CList, int nColumn, HTREEITEM hItem, int nIcon) -{ - _ASSERT(CList); - int ItemType = CList->GetItemType(hItem); - HANDLE hContact = CList->GethContact(hItem); - if (ItemType == MCLCIT_CONTACT) - { - if (nIcon == -1) // means we need to retrieve it from the db by ourselves - { - if (nColumn == EXTRACOLUMN_IGNORE) - { - nIcon = CContactSettings(0, hContact).Ignore ? EXTRAIMGLIST_IGNORE : EXTRAIMGLIST_DOT; - } else - { - _ASSERT(nColumn == EXTRACOLUMN_REPLY); - nIcon = DBValueToReplyIcon(CContactSettings(0, hContact).Autoreply); - } - } else // save it back to the db - { - if (nColumn == EXTRACOLUMN_IGNORE) - { - CContactSettings(0, hContact).Ignore = nIcon == EXTRAIMGLIST_IGNORE; - } else - { - _ASSERT(nColumn == EXTRACOLUMN_REPLY); - CContactSettings(0, hContact).Autoreply = (nIcon == EXTRAIMGLIST_DOT) ? VAL_USEDEFAULT : (nIcon == EXTRAIMGLIST_AUTOREPLY_ON); - } - } - if (nColumn == EXTRACOLUMN_IGNORE && nIcon != EXTRAIMGLIST_IGNORE) - { - nIcon = (CContactSettings(0, hContact).GetMsgFormat(GMF_PERSONAL) == NULL) ? EXTRAIMGLIST_DOT : EXTRAIMGLIST_MSG; - } - } else if (ItemType == MCLCIT_INFO) - { - char *szProto = (char*)CList->GetItemParam(hItem); - if (nColumn == EXTRACOLUMN_REPLY) - { - if (nIcon == -1) - { - nIcon = DBValueToReplyIcon(CProtoSettings(szProto).Autoreply); - } else - { - CProtoSettings(szProto).Autoreply = (nIcon == EXTRAIMGLIST_DOT) ? VAL_USEDEFAULT : (nIcon == EXTRAIMGLIST_AUTOREPLY_ON); - } - if (!szProto && nIcon == EXTRAIMGLIST_DOT) - { - nIcon = EXTRAIMGLIST_AUTOREPLY_OFF; - } - } else - { - nIcon = (CProtoSettings(szProto).GetMsgFormat(GMF_TEMPORARY | GMF_PERSONAL) == NULL) ? EXTRAIMGLIST_DOT : EXTRAIMGLIST_MSG; - } - } - int Ignore = (nColumn == EXTRACOLUMN_IGNORE) ? (nIcon == EXTRAIMGLIST_IGNORE) : ((ItemType == MCLCIT_CONTACT) ? CContactSettings(0, hContact).Ignore : ((ItemType == MCLCIT_GROUP) ? CList->GetExtraImage(hItem, EXTRACOLUMN_IGNORE) : false)); - if (Ignore) - { - if (nColumn == EXTRACOLUMN_IGNORE) - { - CList->SetExtraImage(hItem, EXTRACOLUMN_REPLY, CLC_EXTRAICON_EMPTY); - } else - { - nIcon = CLC_EXTRAICON_EMPTY; - } - } else - { - int nReplyIcon; - if (ItemType == MCLCIT_CONTACT) - { - nReplyIcon = DBValueToReplyIcon(CContactSettings(0, hContact).Autoreply); - } else if (ItemType == MCLCIT_GROUP) - { - nReplyIcon = GetRealReplyIcon(CList, hItem); - } else - { - _ASSERT(ItemType == MCLCIT_INFO); - char *szProto = (char*)CList->GetItemParam(hItem); - nReplyIcon = DBValueToReplyIcon(CProtoSettings(szProto).Autoreply); - } - if (nColumn == EXTRACOLUMN_IGNORE) - { - CList->SetExtraImage(hItem, EXTRACOLUMN_REPLY, nReplyIcon); - } else if (nIcon == CLC_EXTRAICON_EMPTY) - { - nIcon = nReplyIcon; - } - } - CList->SetExtraImage(hItem, nColumn, nIcon); -} - - -void SetCListGroupIcons(SetAwayMsgData *dat, CCList *CList) -{ - _ASSERT(CList); - HTREEITEM hItem = CList->GetNextItem(MCLGN_LAST, NULL); // start from last item, so every item is processed before its parents - if (!hItem) - { - return; - } - if (CList->GetItemType(hItem) != MCLCIT_GROUP) - { - hItem = CList->GetNextItem(MCLGN_PREV | MCLGN_GROUP | MCLGN_MULTILEVEL, hItem); - if (!hItem) - { - return; - } - } - do - { - HTREEITEM hCurItem = CList->GetNextItem(MCLGN_CHILD, hItem); - if (hCurItem) - { - int IgnoreIcon = CList->GetExtraImage(hCurItem, EXTRACOLUMN_IGNORE); - int AutoreplyIcon = GetRealReplyIcon(CList, hCurItem); - if (IgnoreIcon == EXTRAIMGLIST_MSG) - { - IgnoreIcon = EXTRAIMGLIST_DOT; - } - while ((hCurItem = CList->GetNextItem(MCLGN_NEXT | MCLGN_ANY, hCurItem)) && (IgnoreIcon != EXTRAIMGLIST_DOT || AutoreplyIcon != EXTRAIMGLIST_DOT)) - { - if (CList->GetExtraImage(hCurItem, EXTRACOLUMN_IGNORE) != EXTRAIMGLIST_IGNORE) - { - IgnoreIcon = EXTRAIMGLIST_DOT; - } - int CurReplyIcon = GetRealReplyIcon(CList, hCurItem); - if (CurReplyIcon != AutoreplyIcon) - { - AutoreplyIcon = EXTRAIMGLIST_DOT; - } - } - CList->SetItemParam(hItem, AutoreplyIcon); // store Reply icon in item's Param, so that we can always get real reply icon for groups later, even if CLC_EXTRAICON_EMPTY is set instead of it - SetExtraIcon(CList, EXTRACOLUMN_IGNORE, hItem, IgnoreIcon); - SetExtraIcon(CList, EXTRACOLUMN_REPLY, hItem, AutoreplyIcon); - } - } while (hItem = CList->GetNextItem(MCLGN_PREV | MCLGN_GROUP | MCLGN_MULTILEVEL, hItem)); -} - - -int GetSelContactsNum(CCList *CList, PTREEITEMARRAY Selection = NULL, bool *bOnlyInfo = NULL) // "SelContacts" mean not only contacts, but everything with "personal" status messages and settings - i.e. "All contacts" and protocol items are counted too. -{ - if (!CList) - { - return (Selection == CLSEL_DAT_NOTHING) ? 0 : 1; // Selection == NULL means we need to retrieve current selection by ourselves, and current selection is always CLSEL_DAT_CONTACT in this case - } - if (!Selection) - { - Selection = CList->GetSelection(); - } - int I; - int nContacts = 0; - if (bOnlyInfo) - { - *bOnlyInfo = true; - } - for (I = 0; I < Selection->GetSize(); I++) - { - int ItemType = CList->GetItemType((*Selection)[I]); - if (bOnlyInfo && ItemType != MCLCIT_INFO) - { - *bOnlyInfo = false; - } - nContacts += ItemType == MCLCIT_CONTACT || ItemType == MCLCIT_INFO; - } - return nContacts; -} - - -void ApplySelContactsMessage(SetAwayMsgData* dat, CCList *CList, PTREEITEMARRAY Selection = NULL) -{ - TCString Message; - HWND hwndDlg = g_SetAwayMsgPage.GetWnd(); - GetDlgItemText(hwndDlg, IDC_SAWAYMSG_MSGDATA, Message.GetBuffer(AWAY_MSGDATA_MAX), AWAY_MSGDATA_MAX); - Message.ReleaseBuffer(); - if (!lstrlen(Message)) - { - Message = NULL; // delete personal message if it's empty - } - if (CList) - { - if (!Selection) - { - Selection = CList->GetSelection(); - } - int I; - for (I = 0; I < Selection->GetSize(); I++) - { - HTREEITEM hItem = (*Selection)[I]; - int ItemType = CList->GetItemType(hItem); - if (ItemType == MCLCIT_CONTACT) - { - HANDLE hContact = CList->GethContact(hItem); - CContactSettings(0, hContact).SetMsgFormat(SMF_PERSONAL, Message); - } else if (ItemType == MCLCIT_INFO) - { - char *szProto = (char*)CList->GetItemParam(hItem); - CProtoSettings(szProto).SetMsgFormat(SMF_PERSONAL, (szProto || Message != NULL) ? Message : _T("")); // "szProto || Message != NULL..." means that we'll set an empty message instead of NULL for the global status, if the message is empty (NULL for the global status has a special meaning - SetMsgFormat will set the default message instead of NULL) - } else - { - continue; - } - SetExtraIcon(CList, EXTRACOLUMN_IGNORE, hItem, -1); // refresh contact's personal message icon (MSG or DOT) - } - } else if (Selection != CLSEL_DAT_NOTHING) - { - if (dat->hInitContact) - { - CContactSettings(0, dat->hInitContact).SetMsgFormat(SMF_PERSONAL, Message); - } else - { - CProtoSettings(dat->szProtocol).SetMsgFormat(SMF_PERSONAL, (dat->szProtocol || Message != NULL) ? Message : _T("")); - } - } - SendDlgItemMessage(hwndDlg, IDC_SAWAYMSG_MSGDATA, EM_SETMODIFY, false, 0); - SetDlgItemText(hwndDlg, IDC_OK, TranslateT("OK")); -} - - -void UpdateCheckboxesState(CCList *CList) -{ - _ASSERT(CList); - PTREEITEMARRAY Selection = CList->GetSelection(); - int I; - int ReplyIcon = -1; - int IgnoreIcon = -1; - for (I = 0; I < Selection->GetSize() && (IgnoreIcon != EXTRAIMGLIST_DOT || ReplyIcon != EXTRAIMGLIST_DOT); I++) - { - HTREEITEM hItem = (*Selection)[I]; - int ItemType = CList->GetItemType(hItem); - if (ItemType == MCLCIT_CONTACT || ItemType == MCLCIT_INFO) - { - int CurIgnoreIcon = CList->GetExtraImage(hItem, EXTRACOLUMN_IGNORE); - if (IgnoreIcon == -1) - { - IgnoreIcon = CurIgnoreIcon; - } else if (CurIgnoreIcon != EXTRAIMGLIST_IGNORE) - { - IgnoreIcon = EXTRAIMGLIST_DOT; - } - int CurReplyIcon = CList->GetExtraImage(hItem, EXTRACOLUMN_REPLY); - if (ReplyIcon == -1) - { - ReplyIcon = CurReplyIcon; - } else if (CurReplyIcon != ReplyIcon) - { - ReplyIcon = EXTRAIMGLIST_DOT; - } - } - } - HWND hwndDlg = g_SetAwayMsgPage.GetWnd(); - CheckDlgButton(hwndDlg, IDC_SAWAYMSG_IGNOREREQ, (IgnoreIcon == EXTRAIMGLIST_IGNORE) ? BST_CHECKED : BST_UNCHECKED); - EnableWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_SENDMSG), IgnoreIcon != EXTRAIMGLIST_IGNORE); - CheckDlgButton(hwndDlg, IDC_SAWAYMSG_SENDMSG, (ReplyIcon == EXTRAIMGLIST_AUTOREPLY_ON) ? BST_CHECKED : ((ReplyIcon == EXTRAIMGLIST_AUTOREPLY_OFF) ? BST_UNCHECKED : BST_INDETERMINATE)); -} - -HICON g_LoadIconEx( const char* name, bool big ) -{ - char szSettingName[100]; - mir_snprintf( szSettingName, sizeof( szSettingName ), "%s_%s", "", name ); - return ( HICON )CallService( MS_SKIN2_GETICON, big, (LPARAM)szSettingName ); -} -INT_PTR CALLBACK SetAwayMsgDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - static int SetMsgSplitterX, SetContactSplitterX; - static SetAwayMsgData *dat; - static HWND hWndTooltips; - static int UpdateLock = 0; - static int Countdown; - static CMsgTree *MsgTree = NULL; - static CCList *CList = NULL; - static struct { - int DlgItem, IconIndex; - TCHAR* Text; - } Buttons[] = { - IDC_SAWAYMSG_SAVEMSG, ILI_SAVE, LPGENT("Save, replacing the selected message"), - IDC_SAWAYMSG_SAVEASNEW, ILI_SAVEASNEW, LPGENT("Save as a new message"), - IDC_SAWAYMSG_NEWCATEGORY, ILI_NEWCATEGORY, LPGENT("Create new category"), - IDC_SAWAYMSG_DELETE, ILI_DELETE, LPGENT("Delete"), - IDC_SAWAYMSG_VARS, ILI_NOICON, LPGENT("Open Variables help dialog"), - IDC_SAWAYMSG_OPTIONS, ILI_SETTINGS, LPGENT("Show settings menu") - }; - - - switch (uMsg) - { - case WM_INITDIALOG: - { - dat = (SetAwayMsgData*)lParam; - TranslateDialogDefault(hwndDlg); - g_SetAwayMsgPage.SetWnd(hwndDlg); - g_SetAwayMsgPage.DBToMemToPage(); -/* - HICON hTitleIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); - HICON hTitleIconBig = LoadSkinnedIconBig(SKINICON_OTHER_MIRANDA); - SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hTitleIconBig); - SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hTitleIcon); -*/ - HICON hTitleIconBigElse = LoadSkinnedIconBig(SKINICON_OTHER_MIRANDA); - - char *szProto = dat->hInitContact ? (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)dat->hInitContact, 0) : dat->szProtocol; - int Status = 0; - Status = g_ProtoStates[dat->szProtocol].Status; - HICON hTitleIcon = LoadSkinnedProtoIcon(szProto, Status); - HICON hTitleIconBig = LoadSkinnedProtoIconBig(szProto, Status); - - - - - if(hTitleIconBig == NULL || (HICON)CALLSERVICE_NOTFOUND == hTitleIconBig) { - SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hTitleIconBigElse); - } else { - SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hTitleIconBig); - } - - SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hTitleIcon); - - - SendDlgItemMessage(hwndDlg, IDC_SAWAYMSG_MSGDATA, EM_LIMITTEXT, AWAY_MSGDATA_MAX, 0); - - - - - // init window size variables / resize the window - RECT rc; - POINT pt; - GetWindowRect(GetDlgItem(hwndDlg, IDC_SAWAYMSG_MSGSPLITTER), &rc); - pt.x = (rc.left + rc.right) / 2; - pt.y = 0; - ScreenToClient(hwndDlg, &pt); - g_MsgSplitterX = pt.x; - RECT rcContactSplitter; - GetWindowRect(GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSPLITTER), &rcContactSplitter); - RECT rcMsgDlg; - GetWindowRect(hwndDlg, &rcMsgDlg); - g_ContactSplitterX = rcMsgDlg.right - rcContactSplitter.left - (rcContactSplitter.right - rcContactSplitter.left) / 2; - RECT rcVars; - GetWindowRect(GetDlgItem(hwndDlg, IDC_SAWAYMSG_VARS), &rcVars); - g_VariablesButtonDX = rcContactSplitter.left - rcVars.right; -// GetWindowRect(GetDlgItem(hwndDlg, IDC_OK), &rc); - RECT rcOK; - GetWindowRect(GetDlgItem(hwndDlg, IDC_OK), &rcOK); - //MinMsgEditSize = rc.right - rc.left + rcContactSplitter.right - rcVars.left + 3; - MinMsgEditSize = rcOK.right - rc.left + rcContactSplitter.right - rcVars.left + 3; - rc.left = MINSPLITTERPOS; - - //NightFox: use MINSPLITTERPOS as min size ; -// GetWindowRect(GetDlgItem(hwndDlg, IDC_SAWAYMSG_SAVEMSG), &rc); -// GetWindowRect(GetDlgItem(hwndDlg, IDC_SAWAYMSG_DELETE), &rc); -// rc.left = MINSPLITTERPOS; - //GetWindowRect(GetDlgItem(hwndDlg, IDC_OK), &rc); - //GetWindowRect(GetDlgItem(hwndDlg, IDC_OK), &rc); - - pt.x = rc.right; - pt.y = 0; - ScreenToClient(hwndDlg, &pt); - MinMsgSplitterX = pt.x; - GetWindowRect(GetDlgItem(hwndDlg, IDC_SAWAYMSG_IGNOREREQ), &rc); - MinContactSplitterX = rcMsgDlg.right - rc.left + 1; - - /* - - //NightFox: add status bar - - PROTOACCOUNT * acc = ProtoGetAccount(szProto); - - //HWND hWndStatusBar = CreateStatusWindow(WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | SBARS_SIZEGRIP, NULL, hwndDlg, 999);//IDC_STATUSBAR); - SetWindowPos(hWndStatusBar, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); - - - SIZE sz; - - HDC hdc = GetDC(hWndStatusBar); - HFONT hFntSave = (HFONT)SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT)); - GetTextExtentPoint32(hdc, acc->tszAccountName, lstrlen(acc->tszAccountName), &sz); - sz.cx += GetSystemMetrics(SM_CXSMICON) * 3; - SelectObject(hdc, hFntSave); - ReleaseDC(hWndStatusBar, hdc); - - RECT rcStatus; GetWindowRect(hWndStatusBar, &rcStatus); - int parts[] = { rcStatus.right-rcStatus.left - sz.cx, -1 }; - SendMessage(hWndStatusBar, SB_SETPARTS, 2, (LPARAM)parts); - SendMessage(hWndStatusBar, SB_SETICON, 1, (LPARAM)LoadSkinnedProtoIcon(szProto, Status)); - SendMessage(hWndStatusBar, SB_SETTEXT, 1, (LPARAM)acc->tszAccountName); - */ - - - - - - - - - - - // [try] getting dialog position - int DlgPosX = DBGetContactSettingDword(NULL, MOD_NAME, SAM_DB_DLGPOSX, -1); - int DlgPosY = DBGetContactSettingDword(NULL, MOD_NAME, SAM_DB_DLGPOSY, -1); - int DlgSizeX = DBGetContactSettingDword(NULL, MOD_NAME, SAM_DB_DLGSIZEX, -1); - int DlgSizeY = DBGetContactSettingDword(NULL, MOD_NAME, SAM_DB_DLGSIZEY, -1); - int MsgSplitterX = DBGetContactSettingDword(NULL, MOD_NAME, SAM_DB_MSGSPLITTERPOS, -1); - int ContactSplitterX = DBGetContactSettingDword(NULL, MOD_NAME, SAM_DB_CONTACTSPLITTERPOS, -1); - if (DlgPosX >= 0 && DlgPosY >= 0 && DlgSizeX > 0 && DlgSizeY > 0 && MsgSplitterX > 0 && ContactSplitterX > 0) - { - RECT rcWorkArea, rcIntersect; - SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, 0); - RECT rcDlgPos = {DlgPosX, DlgPosY, DlgPosX + DlgSizeX, DlgPosY + DlgSizeY}; - if (!IntersectRect(&rcIntersect, &rcDlgPos, &rcWorkArea)) // make sure the window will be visible - { - DlgPosX = rcWorkArea.left; - DlgPosY = rcWorkArea.top; - } - SetWindowPos(hwndDlg, NULL, DlgPosX, DlgPosY, DlgSizeX, DlgSizeY, SWP_NOZORDER); - g_MsgSplitterX = MsgSplitterX; - g_ContactSplitterX = ContactSplitterX; - } - - SetMsgSplitterX = g_MsgSplitterX; - SetContactSplitterX = g_ContactSplitterX; - SendMessage(hwndDlg, WM_SIZE, 0, 0); // show/hide dialog controls accordingly to the settings - - MsgTree = new CMsgTree(GetDlgItem(hwndDlg, IDC_SAWAYMSG_TREE)); // Attention: it's important to call NEW and DELETE in a proper order, as CMsgTree and CCList are setting their own WNDPROCs for the parent window, so we must prevent WNDPROC conflicts. - CList = NULL; - if (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWCONTACTTREE)) - { - SendMessage(hwndDlg, UM_SAM_INITCLIST, 0, 0); - } else - { - NMCLIST nm; - nm.hdr.code = MCLN_SELCHANGED; - nm.hdr.hwndFrom = GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE); - nm.hdr.idFrom = IDC_SAWAYMSG_CONTACTSTREE; - nm.OldSelection = CLSEL_DAT_NOTHING; - nm.NewSelection = CLSEL_DAT_CONTACT; - SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&nm); - } - - // init message tree - if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_RECENTMSGSCOUNT) && g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_PERSTATUSMRM)) - { - char *szProto = dat->hInitContact ? (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)dat->hInitContact, 0) : dat->szProtocol; - int ID = GetRecentGroupID((szProto || !dat->hInitContact) ? g_ProtoStates[szProto].Status : ID_STATUS_AWAY); - CBaseTreeItem* pTreeItem = MsgTree->GetNextItem(MTGN_CHILD | MTGN_BYID, (CBaseTreeItem*)g_Messages_RecentRootID); - while (pTreeItem) - { - if (pTreeItem->Flags & TIF_GROUP) - { - if (pTreeItem->ID == ID) - { - pTreeItem->Flags |= TIF_EXPANDED; // leave expanded only one appropriate subgroup of Recent Messages group - } else - { - pTreeItem->Flags &= ~TIF_EXPANDED; - } - MsgTree->UpdateItem(pTreeItem->ID); - } - pTreeItem = MsgTree->GetNextItem(MTGN_NEXT, pTreeItem); - } -// InvalidateRect(GetDlgItem(hwndDlg, IDC_SAWAYMSG_TREE), NULL, true); - } - int Order; - CProtoSettings(dat->szProtocol).GetMsgFormat(GMF_LASTORDEFAULT, &Order); - if (Order >= 0) - { // so just select an appropriate message tree item; MSGDATA text is filled automatically through SELCHANGED notification - MsgTree->SetSelection(Order, MTSS_BYORDER); - } - - if (dat->Message != NULL) // this allows to override the default message - { - SetDlgItemText(hwndDlg, IDC_SAWAYMSG_MSGDATA, dat->Message); - SendDlgItemMessage(hwndDlg, IDC_SAWAYMSG_MSGDATA, EM_SETMODIFY, true, 0); - } - SendDlgItemMessage(hwndDlg, IDC_SAWAYMSG_MSGDATA, EM_SETSEL, 0, -1); // select all the text in the edit control - - // init timer - Countdown = (dat->ISW_Flags & ISWF_NOCOUNTDOWN) ? -1 : g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_WAITFORMSG); - if (Countdown == -1) // infinite - { - SetDlgItemText(hwndDlg, IDC_OK, TranslateT("OK")); - } else - { - SendMessage(hwndDlg, WM_TIMER, SAM_TIMER_ID, NULL); - SetTimer(hwndDlg, SAM_TIMER_ID, 1000, NULL); - } - - // init image buttons - int I; - for (I = 0; I < lengthof(Buttons); I++) - { - HWND hButton = GetDlgItem(hwndDlg, Buttons[I].DlgItem); - SendMessage(hButton, BUTTONADDTOOLTIP, (WPARAM)TranslateTS(Buttons[I].Text), BATF_TCHAR); - SendMessage(hButton, BUTTONSETASFLATBTN, TRUE, 0); - } - - // init tooltips - struct { - int DlgItemID; - TCHAR* Text; - } Tooltips[] = { - IDC_SAWAYMSG_IGNOREREQ, LPGENT("Don't send the status message to selected contact(s)"), - IDC_SAWAYMSG_SENDMSG, LPGENT("Send an autoreply to selected contact(s)"), - }; - TOOLINFO ti = {0}; - hWndTooltips = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, _T(""), WS_POPUP, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL); - ti.cbSize = sizeof(ti); - ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS; - for (I = 0; I < lengthof(Tooltips); I++) - { - ti.uId = (UINT)GetDlgItem(hwndDlg, Tooltips[I].DlgItemID); - ti.lpszText = TranslateTS(Tooltips[I].Text); - SendMessage(hWndTooltips, TTM_ADDTOOL, 0, (LPARAM)&ti); - } - SendMessage(hwndDlg, UM_ICONSCHANGED, 0, 0); - - g_OrigCListProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE), GWLP_WNDPROC, (LONG_PTR)CListSubclassProc); - g_OrigEditMsgProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_SAWAYMSG_MSGDATA), GWLP_WNDPROC, (LONG_PTR)MsgEditSubclassProc); - g_OrigSplitterProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_SAWAYMSG_MSGSPLITTER), GWLP_WNDPROC, (LONG_PTR)SplitterSubclassProc); - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSPLITTER), GWLP_WNDPROC, (LONG_PTR)SplitterSubclassProc); - return false; - } break; - case WM_NOTIFY: - { - switch (((NMHDR*)lParam)->idFrom) - { - case IDC_SAWAYMSG_CONTACTSTREE: - { - switch (((NMHDR*)lParam)->code) // check the notification code - { - case NM_CLICK: - { - _ASSERT(CList); - HWND hTreeView = GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE); - POINT pt = {(short)LOWORD(GetMessagePos()), (short)HIWORD(GetMessagePos())}; - ScreenToClient(hTreeView, &pt); - DWORD hitFlags; - HTREEITEM hItem = CList->HitTest(&pt, &hitFlags); - if (hitFlags & MCLCHT_ONITEMEXTRA) - { - int nColumn = HIBYTE(HIWORD(hitFlags)); - int CurIcon = CList->GetExtraImage(hItem, nColumn); - int ItemType = CList->GetItemType(hItem); - if (nColumn == EXTRACOLUMN_IGNORE) - { - CurIcon = (CurIcon == EXTRAIMGLIST_IGNORE) ? EXTRAIMGLIST_DOT : EXTRAIMGLIST_IGNORE; - } else - { - _ASSERT(nColumn == EXTRACOLUMN_REPLY); - switch (CurIcon) - { - case EXTRAIMGLIST_DOT: CurIcon = EXTRAIMGLIST_AUTOREPLY_OFF; break; - case EXTRAIMGLIST_AUTOREPLY_OFF: CurIcon = EXTRAIMGLIST_AUTOREPLY_ON; break; - case EXTRAIMGLIST_AUTOREPLY_ON: CurIcon = EXTRAIMGLIST_DOT; break; - } - } - SetExtraIcon(CList, nColumn, hItem, CurIcon); - if (ItemType == MCLCIT_GROUP) // set all child items - { - HTREEITEM hCurItem = CList->GetNextItem(MCLGN_CHILD, hItem); - HTREEITEM hLimitItem = CList->GetNextItem(MCLGN_NEXT | MCLGN_ANY | MCLGN_NOTCHILD, hItem); - while (hCurItem && hCurItem != hLimitItem) - { - SetExtraIcon(CList, nColumn, hCurItem, CurIcon); - hCurItem = CList->GetNextItem(MCLGN_NEXT | MCLGN_ANY | MCLGN_MULTILEVEL, hCurItem); - } - } - SetCListGroupIcons(dat, CList); - UpdateCheckboxesState(CList); - } - } break; - case MCLN_SELCHANGED: - { - PNMCLIST nm = (PNMCLIST)lParam; - TCString BtnTitle(TranslateT("OK")); - if (CList) - { - UpdateCheckboxesState(CList); - } - bool bOnlyInfo; - bool bLeaveOldMessage = nm->OldSelection == nm->NewSelection; // OldSelection == NewSelection when we send MCLN_SELCHANGED from UM_SAM_PROTOSTATUSCHANGED; seems that it's better to leave old message then - int nOldContacts = GetSelContactsNum(CList, nm->OldSelection); - int nNewContacts = GetSelContactsNum(CList, nm->NewSelection, &bOnlyInfo); - EnableWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_IGNOREREQ), !bOnlyInfo); - if (CList) - { - if (SendDlgItemMessage(hwndDlg, IDC_SAWAYMSG_MSGDATA, EM_GETMODIFY, 0, 0)) - { - int I, J; - for (I = nm->OldSelection->GetSize() - 1; I >= 0; I--) - { - for (J = nm->NewSelection->GetSize() - 1; J >= 0; J--) - { - if ((*nm->NewSelection)[J] == (*nm->OldSelection)[I]) - { - break; - } - } - if (J < 0) - { - break; - } - } - if (nNewContacts > 1) - { - BtnTitle = TranslateT("Apply"); - } - if (I >= 0 && nOldContacts) // there's at least one item in the old selection that is not present in the new one - { - if ((nOldContacts == 1) || MessageBox(hwndDlg, TranslateT("Do you want to apply the message?"), TranslateT("New Away System"), MB_ICONQUESTION | MB_YESNO) == IDYES) - { - ApplySelContactsMessage(dat, CList, nm->OldSelection); - } - } else if (nOldContacts) - { - bLeaveOldMessage = true; // don't change the edit control text yet - we're still writing... - } - } - } else - { - if (nOldContacts && !nNewContacts) - { - ApplySelContactsMessage(dat, CList, nm->OldSelection); - } - } - - // determine the right new message and window title for the edit control now - TCString Message; - int Status = 0; - if (CList) - { - bool MessageDetermined = false; - bool StatusDetermined = false; - int I; - for (I = 0; I < nm->NewSelection->GetSize(); I++) - { - HTREEITEM hItem = (*nm->NewSelection)[I]; - HANDLE hContact; - char *szProto; - int ItemType = CList->GetItemType(hItem); - if (ItemType == MCLCIT_CONTACT) - { - hContact = CList->GethContact(hItem); - _ASSERT(hContact); - szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - _ASSERT(szProto); - } else if (ItemType == MCLCIT_INFO) - { - szProto = (char*)CList->GetItemParam(hItem); - } - if (ItemType == MCLCIT_CONTACT || ItemType == MCLCIT_INFO) - { - int CurStatus = g_ProtoStates[szProto].Status; - if (!MessageDetermined) - { - TCString CurMessage((ItemType == MCLCIT_CONTACT) ? CContactSettings(0, hContact).GetMsgFormat(GMF_PERSONAL) : CProtoSettings(szProto).GetMsgFormat(GMF_TEMPORARY | GMF_PERSONAL)); - if (CurMessage == NULL) - { - CurMessage = _T(""); - } - if (Message == NULL) - { - Message = CurMessage; - } else if (CurMessage != (const TCHAR*)Message) - { - Message = _T(""); - BtnTitle = TranslateT("Apply"); - MessageDetermined = true; - } - } - if (!StatusDetermined) - { - if (!Status) - { - Status = CurStatus; - } else if (CurStatus != Status) - { - Status = 0; - StatusDetermined = true; - } - } - } - } - } else if (nNewContacts) // if (!CList) - { - Status = g_ProtoStates[dat->szProtocol].Status; - Message = dat->hInitContact ? CContactSettings(0, dat->hInitContact).GetMsgFormat(GMF_PERSONAL) : CProtoSettings(dat->szProtocol).GetMsgFormat(GMF_TEMPORARY | GMF_PERSONAL); - } - if (!bLeaveOldMessage) - { - SetDlgItemText(hwndDlg, IDC_SAWAYMSG_MSGDATA, (Message == NULL) ? _T("") : Message); - } - SetDlgItemText(hwndDlg, IDC_OK, BtnTitle); - //NightFox: fix titlebar - //TCString WindowTitle(TranslateT("Set ")); - TCString WindowTitle(TranslateT("Set message for")); - WindowTitle += _T(" \""); - WindowTitle += Status ? (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, Status, GSMDF_TCHAR) : TranslateT("Statuses"); - //WindowTitle += TranslateT(" message"); - if (nNewContacts == 1) - { - WindowTitle += TCString(TranslateT("\" (")); - HANDLE hContact = NULL; - char *szProto = NULL; - if (CList) - { - int I; - for (I = 0; I < nm->NewSelection->GetSize(); I++) - { - HTREEITEM hItem = (*nm->NewSelection)[I]; - int ItemType = CList->GetItemType(hItem); - if (ItemType == MCLCIT_CONTACT) - { - hContact = CList->GethContact((*nm->NewSelection)[I]); - break; - } else if (ItemType == MCLCIT_INFO) - { - szProto = (char*)CList->GetItemParam(hItem); - break; - } - } - } else - { - hContact = dat->hInitContact; - szProto = dat->szProtocol; - } - if (hContact) - { - - if (IsAnICQProto((char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0))) { - WindowTitle += TranslateT("message for"); - WindowTitle += _T(" "); - } else { - WindowTitle += TranslateT("for"); - WindowTitle += _T(" "); - } - - - WindowTitle += (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR); - if (!IsAnICQProto((char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0))) - { - //WindowTitle += TranslateT(" (autoreply only)"); - WindowTitle += _T(" "); - WindowTitle += TranslateT("available autoreply only"); - WindowTitle += _T(")"); - } else { - WindowTitle += _T(")"); - } - } else - { - if (!szProto) - { - //WindowTitle += TranslateT("all contacts"); - WindowTitle += TranslateT("all accounts"); - WindowTitle += _T(")"); - } else - { - //CString ProtoTitle; - - /*if (CallProtoService(szProto, PS_GETNAME, 256, (LPARAM)ProtoTitle.GetBuffer(256))) - { // on a failure, set ProtoTitle to an empty string - //ProtoTitle[0] = '\0'; - }*/ - //ProtoTitle.ReleaseBuffer(); - //WindowTitle += ANSI2TCHAR(ProtoTitle) + TranslateT(" protocol"); - - PROTOACCOUNT * acc = ProtoGetAccount(szProto); - - WindowTitle += acc->tszAccountName; - //WindowTitle += _T(" "); - //WindowTitle += TranslateT("account"); - WindowTitle += _T(")"); - } - } - } else { - WindowTitle += _T("\""); - } - SetWindowText(hwndDlg, WindowTitle); - } break; - } - } break; - case IDC_SAWAYMSG_TREE: - { - switch (((NMHDR*)lParam)->code) - { - case MTN_SELCHANGED: - { - if (!UpdateLock) - { - PNMMSGTREE pnm = (PNMMSGTREE)lParam; - if (pnm->ItemNew && !(pnm->ItemNew->Flags & (TIF_ROOTITEM | TIF_GROUP))) - { - SetDlgItemText(hwndDlg, IDC_SAWAYMSG_MSGDATA, ((CTreeItem*)pnm->ItemNew)->User_Str1); - SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_SAWAYMSG_MSGDATA, EN_CHANGE), (LPARAM)GetDlgItem(hwndDlg, IDC_SAWAYMSG_MSGDATA)); - SendDlgItemMessage(hwndDlg, IDC_SAWAYMSG_MSGDATA, EM_SETMODIFY, true, 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_SAVEMSG), true); - } else - { - EnableWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_SAVEMSG), false); - } - EnableWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_DELETE), pnm->ItemNew && !(pnm->ItemNew->Flags & TIF_ROOTITEM)); - } - } break; - } - } break; - } - return true; - } break; - case WM_TIMER: - { - if (wParam == SAM_TIMER_ID) - { - if (!Countdown) - { - SendMessage(hwndDlg, UM_SAM_APPLYANDCLOSE, 0, 0); - return true; - } - TCHAR BtnTitle[64]; - _sntprintf(BtnTitle, sizeof(BtnTitle), TranslateT("Closing in %d"), Countdown); - SetDlgItemText(hwndDlg, IDC_OK, BtnTitle); - Countdown--; - } - } break; - case UM_SAM_INITCLIST: - { - _ASSERT(!CList); - CList = new CCList(GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE)); - - // init contact tree - HIMAGELIST hil; - hil = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), (IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR16) | ILC_MASK, 5, 2); - ImageList_AddIcon(hil, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_DOT))); - ImageList_AddIcon(hil, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_IGNORE))); - ImageList_AddIcon(hil, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_MSGICON))); - ImageList_AddIcon(hil, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SOE_ENABLED))); - ImageList_AddIcon(hil, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SOE_DISABLED))); - CList->SetExtraImageList(hil); - - HTREEITEM hSelItem; - HTREEITEM hItem = hSelItem = CList->AddInfo(TranslateT("** All contacts **"), CLC_ROOT, CLC_ROOT, NULL, LoadSkinnedProtoIcon(NULL, g_ProtoStates[(char*)NULL].Status)); - int ProtoCount; - PROTOCOLDESCRIPTOR **proto; - CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&ProtoCount, (LPARAM)&proto); - int I; - for (I = 0; I < ProtoCount; I++) - { - if (proto[I]->type == PROTOTYPE_PROTOCOL && CallProtoService(proto[I]->szName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND) // don't forget to change Recent Message Save loop in the UM_SAM_APPLYANDCLOSE if you're changing something here - { - //CString ProtoTitle; - //CallProtoService(proto[I]->szName, PS_GETNAME, 256, (LPARAM)ProtoTitle.GetBuffer(256)); - //ProtoTitle.ReleaseBuffer(); - - PROTOACCOUNT * acc = ProtoGetAccount(proto[I]->szName); - //NightFox: protocols -> accounts - //hItem = CList->AddInfo(TCString(_T("* ")) + ANSI2TCHAR(ProtoTitle) + TranslateT(" contacts *"), CLC_ROOT, hItem, (LPARAM)proto[I]->szName, LoadSkinnedProtoIcon(proto[I]->szName, g_ProtoStates[proto[I]->szName].Status)); - hItem = CList->AddInfo(TCString(_T("* ")) + acc->tszAccountName/* + TranslateT(" contacts *")*/ + _T(" *"), CLC_ROOT, hItem, (LPARAM)proto[I]->szName, LoadSkinnedProtoIcon(proto[I]->szName, g_ProtoStates[proto[I]->szName].Status)); - if (dat->szProtocol && !strcmp(proto[I]->szName, dat->szProtocol)) - { - hSelItem = hItem; - } - } - } - - HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - CList->SetRedraw(false); - do - { - char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - if (szProto) - { - int Flag1 = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0); - if ((Flag1 & PF1_IM) == PF1_IM || Flag1 & PF1_INDIVMODEMSG) - { // check if the protocol supports message sending/receiving or individual status messages before adding this contact - HTREEITEM hItem = CList->AddContact(hContact); - if (dat->hInitContact == hContact) - { - hSelItem = hItem; - } - } - } - } while (hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)); - CList->SortContacts(); - hItem = CLC_ROOT; - while (hItem = CList->GetNextItem(MCLGN_NEXT | MCLGN_CONTACT | MCLGN_INFO | MCLGN_MULTILEVEL, hItem)) - { - SetExtraIcon(CList, EXTRACOLUMN_IGNORE, hItem, -1); - SetExtraIcon(CList, EXTRACOLUMN_REPLY, hItem, -1); - } - SetCListGroupIcons(dat, CList); - CList->SetRedraw(true); // SetRedraw must be before SelectItem - otherwise SelectItem won't change scrollbar position to make the selected contact visible - CList->SelectItem(hSelItem); // must be selected after setting all extra icons, to set checkboxes properly - } break; - case UM_SAM_APPLYANDCLOSE: - { - KillTimer(hwndDlg, SAM_TIMER_ID); - if (CList) - { - CList->SelectItem(NULL); - } else - { - NMCLIST nm; - nm.hdr.code = MCLN_SELCHANGED; - nm.hdr.hwndFrom = GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE); - nm.hdr.idFrom = IDC_SAWAYMSG_CONTACTSTREE; - nm.OldSelection = CLSEL_DAT_CONTACT; - nm.NewSelection = CLSEL_DAT_NOTHING; - SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&nm); - } - MsgTree->Save(); - // save Recent Messages - int ProtoCount; - PROTOCOLDESCRIPTOR **proto; - CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&ProtoCount, (LPARAM)&proto); - int I; - for (I = 0; I < ProtoCount; I++) - { - if (proto[I]->type == PROTOTYPE_PROTOCOL && CallProtoService(proto[I]->szName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND) - { - TCString Message(CProtoSettings(proto[I]->szName).GetMsgFormat(GMF_PERSONAL)); // yes, we don't specify GMF_TEMPORARY here, because we don't need to save it - if (Message != NULL) - { - CProtoSettings(proto[I]->szName).SetMsgFormat(SMF_LAST, Message); // if the user set a message for this protocol, save it to the recent messages - } - ChangeProtoMessages(proto[I]->szName, g_ProtoStates[proto[I]->szName].Status, TCString(NULL)); // and actual setting of a status message for the protocol - } - } - TCString Message(CProtoSettings().GetMsgFormat(GMF_PERSONAL)); - if (Message != NULL) - { - CProtoSettings().SetMsgFormat(SMF_LAST, Message); // save the global message to the recent messages - } - if (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_AUTOSAVEDLGSETTINGS)) - { - SendMessage(hwndDlg, UM_SAM_SAVEDLGSETTINGS, 0, 0); - } - if (dat->IsModeless) - { - DestroyWindow(hwndDlg); - } else - { - EndDialog(hwndDlg, 2); - } - return true; - } break; - case UM_SAM_SAVEDLGSETTINGS: - { - RECT rcRect; - GetWindowRect(hwndDlg, &rcRect); - DBWriteContactSettingDword(NULL, MOD_NAME, SAM_DB_DLGPOSX, rcRect.left); - DBWriteContactSettingDword(NULL, MOD_NAME, SAM_DB_DLGPOSY, rcRect.top); - DBWriteContactSettingDword(NULL, MOD_NAME, SAM_DB_DLGSIZEX, rcRect.right - rcRect.left); - DBWriteContactSettingDword(NULL, MOD_NAME, SAM_DB_DLGSIZEY, rcRect.bottom - rcRect.top); - DBWriteContactSettingDword(NULL, MOD_NAME, SAM_DB_MSGSPLITTERPOS, g_MsgSplitterX); - DBWriteContactSettingDword(NULL, MOD_NAME, SAM_DB_CONTACTSPLITTERPOS, g_ContactSplitterX); - g_SetAwayMsgPage.PageToMemToDB(); - } break; - case UM_SAM_REPLYSETTINGCHANGED: - { // wParam = (HANDLE)hContact - if (CList) - { - HTREEITEM hItem = CLC_ROOT; - if (!wParam) - { // it's the global autoreply setting - while (hItem = CList->GetNextItem(MCLGN_NEXT | MCLGN_INFO | MCLGN_MULTILEVEL, hItem)) - { - if (!CList->GetItemParam(hItem)) - { // we found the item - SetExtraIcon(CList, EXTRACOLUMN_REPLY, hItem, -1); // update it - break; - } - } - } else - { // it's a contact's autoreply setting - while (hItem = CList->GetNextItem(MCLGN_NEXT | MCLGN_CONTACT | MCLGN_MULTILEVEL, hItem)) - { - HANDLE hContact = CList->GethContact(hItem); - if (CList->GethContact(hItem) == (HANDLE)wParam) - { // we found the item - SetExtraIcon(CList, EXTRACOLUMN_REPLY, hItem, -1); // update it - break; - } - } - } - UpdateCheckboxesState(CList); - } - } break; - case UM_SAM_PROTOSTATUSCHANGED: - { // wParam = (char*)szProto - if (CList) - { - HTREEITEM hItem = CLC_ROOT; - while (hItem = CList->GetNextItem(MCLGN_NEXT | MCLGN_CONTACT | MCLGN_INFO | MCLGN_MULTILEVEL, hItem)) - { - if (CList->GetItemType(hItem) == MCLCIT_INFO) - { - char *szProto = (char*)CList->GetItemParam(hItem); - if (!wParam || !lstrcmpA(szProto, (char*)wParam)) - { - CList->SetInfoIcon(hItem, LoadSkinnedProtoIcon(szProto, g_ProtoStates[szProto].Status)); - } - } - SetExtraIcon(CList, EXTRACOLUMN_IGNORE, hItem, -1); - SetExtraIcon(CList, EXTRACOLUMN_REPLY, hItem, -1); - } - SetCListGroupIcons(dat, CList); - } -/* dat->hInitContact = NULL; // TODO: test it - dat->szProtocol = (char*)wParam;*/ - NMCLIST nm; - nm.hdr.code = MCLN_SELCHANGED; - nm.hdr.hwndFrom = GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE); - nm.hdr.idFrom = IDC_SAWAYMSG_CONTACTSTREE; - nm.OldSelection = nm.NewSelection = CList ? CList->GetSelection() : CLSEL_DAT_CONTACT; - SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&nm); // everything else is in the MCLN_SELCHANGED handler, so we'll just call it from here. - } break; - case UM_ICONSCHANGED: - { - int I; - for (I = 0; I < lengthof(Buttons); I++) - { - if (Buttons[I].IconIndex != ILI_NOICON) - { - SendDlgItemMessage(hwndDlg, Buttons[I].DlgItem, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[Buttons[I].IconIndex]); - } - } - my_variables_skin_helpbutton(hwndDlg, IDC_SAWAYMSG_VARS); - } break; - case WM_COMMAND: - { - switch (HIWORD(wParam)) - { - case EN_CHANGE: - { - if (LOWORD(wParam) == IDC_SAWAYMSG_MSGDATA) - { - SetDlgItemText(hwndDlg, IDC_OK, TranslateTS((GetSelContactsNum(CList) > 1) ? LPGENT("Apply") : LPGENT("OK"))); - } - } break; - case EN_KILLFOCUS: - { - if (LOWORD(wParam) == IDC_SAWAYMSG_MSGDATA && GetForegroundWindow() == hwndDlg) - { - SendMessage(hwndDlg, UM_SAM_KILLTIMER, 0, 0); - } - } break; - case BN_CLICKED: - { - switch (LOWORD(wParam)) - { - case IDC_SAWAYMSG_IGNOREREQ: - { - _ASSERT(CList); - int Ignore = IsDlgButtonChecked(hwndDlg, IDC_SAWAYMSG_IGNOREREQ) == BST_CHECKED; - EnableWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_SENDMSG), !Ignore); - PTREEITEMARRAY Selection = CList->GetSelection(); - int I; - for (I = 0; I < Selection->GetSize(); I++) - { - if (CList->GetItemType((*Selection)[I]) == MCLCIT_CONTACT) - { - SetExtraIcon(CList, EXTRACOLUMN_IGNORE, (*Selection)[I], Ignore ? EXTRAIMGLIST_IGNORE : EXTRAIMGLIST_DOT); - } - } - if (Selection->GetSize() == 1) - { - CList->EnsureVisible((*Selection)[0]); - } - SetCListGroupIcons(dat, CList); - } break; - case IDC_SAWAYMSG_SENDMSG: - { - _ASSERT(CList); - int Reply = IsDlgButtonChecked(hwndDlg, IDC_SAWAYMSG_SENDMSG); - int ReplyIcon = (Reply == BST_CHECKED) ? EXTRAIMGLIST_AUTOREPLY_ON : ((Reply == BST_UNCHECKED) ? EXTRAIMGLIST_AUTOREPLY_OFF : EXTRAIMGLIST_DOT); - PTREEITEMARRAY Selection = CList->GetSelection(); - int I; - for (I = 0; I < Selection->GetSize(); I++) - { - SetExtraIcon(CList, EXTRACOLUMN_REPLY, (*Selection)[I], ReplyIcon); - } - if (Selection->GetSize() == 1) - { - CList->EnsureVisible((*Selection)[0]); - } - SetCListGroupIcons(dat, CList); - } break; - case IDC_SAWAYMSG_OPTIONS: - { - HMENU hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_SAM_OPTIONS)); - _ASSERT(hMenu); - HMENU hPopupMenu = GetSubMenu(hMenu, 0); - TranslateMenu(hPopupMenu); - CheckMenuItem(hPopupMenu, IDM_SAM_OPTIONS_SHOWMSGTREE, MF_BYCOMMAND | (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWMSGTREE) ? MF_CHECKED : MF_UNCHECKED)); - CheckMenuItem(hPopupMenu, IDM_SAM_OPTIONS_SHOWCONTACTTREE, MF_BYCOMMAND | (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWCONTACTTREE) ? MF_CHECKED : MF_UNCHECKED)); - CheckMenuItem(hPopupMenu, IDM_SAM_OPTIONS_AUTOSAVEDLGSETTINGS, MF_BYCOMMAND | (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_AUTOSAVEDLGSETTINGS) ? MF_CHECKED : MF_UNCHECKED)); - int VariablesInstalled = ServiceExists(MS_VARS_FORMATSTRING); - CheckMenuItem(hPopupMenu, IDM_SAM_OPTIONS_DISABLEVARIABLES, MF_BYCOMMAND | ((g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_DISABLEVARIABLES) || !VariablesInstalled) ? MF_CHECKED : MF_UNCHECKED)); - if (!VariablesInstalled) - { - EnableMenuItem(hPopupMenu, IDM_SAM_OPTIONS_DISABLEVARIABLES, MF_BYCOMMAND | MF_GRAYED); - } - switch (TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, (short)LOWORD(GetMessagePos()), (short)HIWORD(GetMessagePos()), 0, hwndDlg, NULL)) - { - case IDM_SAM_OPTIONS_SHOWMSGTREE: - { - int bShow = !g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWMSGTREE); - g_SetAwayMsgPage.SetValue(IDS_SAWAYMSG_SHOWMSGTREE, bShow); - RECT rcDlg; - GetWindowRect(hwndDlg, &rcDlg); - rcDlg.left -= bShow ? g_MsgSplitterX : -g_MsgSplitterX; - SendMessage(hwndDlg, WM_SIZING, WMSZ_LEFT, (LPARAM)&rcDlg); - SetWindowPos(hwndDlg, NULL, rcDlg.left, rcDlg.top, rcDlg.right - rcDlg.left, rcDlg.bottom - rcDlg.top, SWP_NOZORDER); - SendMessage(hwndDlg, WM_SIZE, 0, 0); // show/hide dialog controls accordingly - } break; - case IDM_SAM_OPTIONS_SHOWCONTACTTREE: - { - int bShow = !g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWCONTACTTREE); - if (bShow && !CList) - { - NMCLIST nm; - nm.hdr.code = MCLN_SELCHANGED; - nm.hdr.hwndFrom = GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE); - nm.hdr.idFrom = IDC_SAWAYMSG_CONTACTSTREE; - nm.OldSelection = CLSEL_DAT_CONTACT; - nm.NewSelection = CLSEL_DAT_NOTHING; - SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&nm); // save current message - SendMessage(hwndDlg, UM_SAM_INITCLIST, 0, 0); - } - g_SetAwayMsgPage.SetValue(IDS_SAWAYMSG_SHOWCONTACTTREE, bShow); - RECT rcDlg; - GetWindowRect(hwndDlg, &rcDlg); - rcDlg.right += bShow ? g_ContactSplitterX : -g_ContactSplitterX; - SendMessage(hwndDlg, WM_SIZING, WMSZ_RIGHT, (LPARAM)&rcDlg); - SetWindowPos(hwndDlg, NULL, 0, 0, rcDlg.right - rcDlg.left, rcDlg.bottom - rcDlg.top, SWP_NOZORDER | SWP_NOMOVE); - SendMessage(hwndDlg, WM_SIZE, 0, 0); // show/hide dialog controls accordingly - } break; - case IDM_SAM_OPTIONS_AUTOSAVEDLGSETTINGS: - { - g_SetAwayMsgPage.SetDBValue(IDS_SAWAYMSG_AUTOSAVEDLGSETTINGS, !g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_AUTOSAVEDLGSETTINGS)); - } break; - case IDM_SAM_OPTIONS_SAVEDLGSETTINGSNOW: - { - SendMessage(hwndDlg, UM_SAM_SAVEDLGSETTINGS, 0, 0); - } break; - case IDM_SAM_OPTIONS_DISABLEVARIABLES: - { - g_SetAwayMsgPage.SetDBValue(IDS_SAWAYMSG_DISABLEVARIABLES, !g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_DISABLEVARIABLES)); - } break; - } - DestroyMenu(hMenu); - } break; - case IDC_SAWAYMSG_SAVEMSG: - { - CBaseTreeItem* TreeItem = MsgTree->GetSelection(); - if (TreeItem && !(TreeItem->Flags & TIF_ROOTITEM)) - { - MsgTree->EnsureVisible(TreeItem->hItem); - TCString NewMsg; - GetDlgItemText(hwndDlg, IDC_SAWAYMSG_MSGDATA, NewMsg.GetBuffer(AWAY_MSGDATA_MAX), AWAY_MSGDATA_MAX); - NewMsg.ReleaseBuffer(); - if (((CTreeItem*)TreeItem)->User_Str1 != (const TCHAR*)NewMsg) - { - ((CTreeItem*)TreeItem)->User_Str1 = NewMsg; - MsgTree->SetModified(true); - } - } - } break; - case IDC_SAWAYMSG_SAVEASNEW: - { - TCString Text; - GetDlgItemText(hwndDlg, IDC_SAWAYMSG_MSGDATA, Text.GetBuffer(AWAY_MSGDATA_MAX), AWAY_MSGDATA_MAX); - Text.ReleaseBuffer(); - UpdateLock++; - CTreeItem* TreeItem = MsgTree->AddMessage(); - UpdateLock--; - TreeItem->User_Str1 = Text; - } break; - case IDC_SAWAYMSG_NEWCATEGORY: - { - MsgTree->AddCategory(); - } break; - case IDC_SAWAYMSG_DELETE: - { - MsgTree->EnsureVisible(MsgTree->GetSelection()->hItem); - MsgTree->DeleteSelectedItem(); - } break; - case IDC_SAWAYMSG_VARS: - { - my_variables_showhelp(hwndDlg, IDC_SAWAYMSG_MSGDATA); - } break; - case IDC_OK: - { - // save OK button title before resetting it in SetSelContactsMessage - TCString BtnTitle; - GetDlgItemText(hwndDlg, IDC_OK, BtnTitle.GetBuffer(64), 64); - BtnTitle.ReleaseBuffer(); - ApplySelContactsMessage(dat, CList); - if (BtnTitle != (const TCHAR*)TranslateT("Apply")) - { - SendMessage(hwndDlg, UM_SAM_APPLYANDCLOSE, 0, 0); - } - } break; - } - } break; - } - } break; - case UM_SAM_SPLITTERMOVED: - { - switch (lParam) - { - RECT rc; - POINT pt; - case IDC_SAWAYMSG_MSGSPLITTER: - { - GetClientRect(hwndDlg, &rc); - pt.x = wParam; - pt.y = 0; - ScreenToClient(hwndDlg, &pt); - g_MsgSplitterX = (pt.x < MINSPLITTERPOS) ? MINSPLITTERPOS : pt.x; - int MaxSetSplitterX = rc.right - MINSPLITTERPOS + 2; - int MaxSplitterX = MaxSetSplitterX; - if (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWCONTACTTREE)) - { - MaxSetSplitterX -= g_ContactSplitterX; - MaxSplitterX -= MINSPLITTERPOS; - } - if (g_MsgSplitterX > MaxSetSplitterX) - { - if (g_MsgSplitterX > MaxSplitterX) - { - g_ContactSplitterX = MINSPLITTERPOS; - g_MsgSplitterX = MaxSplitterX; - } else - { - g_ContactSplitterX = MINSPLITTERPOS + MaxSplitterX - g_MsgSplitterX; - } - } - } break; - case IDC_SAWAYMSG_CONTACTSPLITTER: - { - GetClientRect(hwndDlg, &rc); - pt.x = wParam; - pt.y = 0; - ScreenToClient(hwndDlg, &pt); - g_ContactSplitterX = (rc.right - pt.x < MINSPLITTERPOS) ? MINSPLITTERPOS : (rc.right - pt.x); - int MaxSetSplitterX = rc.right - MINSPLITTERPOS + 2; - int MaxSplitterX = MaxSetSplitterX; - if (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWMSGTREE)) - { - MaxSetSplitterX -= g_MsgSplitterX; - MaxSplitterX -= MINSPLITTERPOS; - } - if (g_ContactSplitterX > MaxSetSplitterX) - { - if (g_ContactSplitterX > MaxSplitterX) - { - g_MsgSplitterX = MINSPLITTERPOS; - g_ContactSplitterX = MaxSplitterX; - } else - { - g_MsgSplitterX = MINSPLITTERPOS + MaxSplitterX - g_ContactSplitterX; - } - } - } break; - } - SetMsgSplitterX = g_MsgSplitterX; - SetContactSplitterX = g_ContactSplitterX; - SendMessage(hwndDlg, WM_SIZE, 0, 0); - } break; - case WM_SIZING: - { - RECT *prcDlg = (RECT*)lParam; - int MinSetXSize = MINSPLITTERPOS + 7; - int MinXSize = MinMsgEditSize + 7; - if (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWMSGTREE)) - { - MinSetXSize += SetMsgSplitterX - 1; - MinXSize += MinMsgSplitterX - 1; - } - if (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWCONTACTTREE)) - { - MinSetXSize += SetContactSplitterX - 1; - MinXSize += MinContactSplitterX - 1; - } - if (prcDlg->right - prcDlg->left < MinXSize) - { - if (wParam != WMSZ_LEFT && wParam != WMSZ_TOPLEFT && wParam != WMSZ_BOTTOMLEFT) - { - prcDlg->right = prcDlg->left + MinXSize; - } else - { - prcDlg->left = prcDlg->right - MinXSize; - } - } - if (prcDlg->right - prcDlg->left < MinSetXSize) - { - int Delta = MinSetXSize - (prcDlg->right - prcDlg->left); - if (SetMsgSplitterX > MinMsgSplitterX) - { - int D2 = min(Delta, SetMsgSplitterX - MinMsgSplitterX); - g_MsgSplitterX = SetMsgSplitterX - D2; - Delta -= D2; - } - g_ContactSplitterX = SetContactSplitterX - Delta; - } else - { - g_MsgSplitterX = SetMsgSplitterX; - g_ContactSplitterX = SetContactSplitterX; - } - if (prcDlg->bottom - prcDlg->top < MINYDLGSIZE) - { - if (wParam != WMSZ_TOP && wParam != WMSZ_TOPLEFT && wParam != WMSZ_TOPRIGHT) - { - prcDlg->bottom = prcDlg->top + MINYDLGSIZE; - } else - { - prcDlg->top = prcDlg->bottom - MINYDLGSIZE; - } - } - return true; - } break; - case WM_SIZE: - { - UTILRESIZEDIALOG urd = {0}; - urd.cbSize = sizeof(urd); - urd.hInstance = g_hInstance; - urd.hwndDlg = hwndDlg; - urd.lParam = (LPARAM)&g_SetAwayMsgPage; - urd.lpTemplate = MAKEINTRESOURCEA(IDD_SETAWAYMSG); - urd.pfnResizer = SetAwayMsgDlgResize; - CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); - if (!wParam && !lParam) // means that we sent WM_SIZE message to apply new settings to the dialog; probably it's somewhat a misuse, but who cares ;-P - { - int bShow; - bShow = g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWMSGTREE) ? SW_SHOW : SW_HIDE; - ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_TREE), bShow); - ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_SAVEMSG), bShow); - ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_SAVEASNEW), bShow); - ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_NEWCATEGORY), bShow); - ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_DELETE), bShow); - ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_MSGSPLITTER), bShow); - bShow = g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWCONTACTTREE) ? SW_SHOW : SW_HIDE; - ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE), bShow); - ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_IGNOREREQ), bShow); - ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_SENDMSG), bShow); - ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSPLITTER), bShow); - ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_STATIC_IGNOREICON), bShow); - ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_STATIC_REPLYICON), bShow); - } - /*if (hWndStatusBar) - { - RECT rcStatus; GetWindowRect(hWndStatusBar, &rcStatus); - RECT rcClient; GetClientRect(hwndDlg, &rcClient); - SetWindowPos(hWndStatusBar, NULL, 0, rcClient.bottom-(rcStatus.bottom-rcStatus.top), rcClient.right, (rcStatus.bottom-rcStatus.top), SWP_NOZORDER); - }*/ - - - } // go through - case UM_SAM_KILLTIMER: - case WM_LBUTTONDOWN: - case WM_MOUSEACTIVATE: - case WM_MOVING: // stops counting - { - if (Countdown != -1) // still counting - { - KillTimer(hwndDlg, SAM_TIMER_ID); - SetDlgItemText(hwndDlg, IDC_OK, TranslateT("OK")); - Countdown = -1; - } - } break; - case WM_SETCURSOR: - { - HWND hTreeView = GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE); - if ((HWND)wParam == hTreeView && LOWORD(lParam) == HTCLIENT) - { - _ASSERT(CList); - DWORD hitFlags; - POINT pt; - pt.x = (short)LOWORD(GetMessagePos()); - pt.y = (short)HIWORD(GetMessagePos()); - ScreenToClient(hTreeView, &pt); - CList->HitTest(&pt, &hitFlags); - HCURSOR hCursor = NULL; - if (hitFlags & (MCLCHT_ONITEM | MCLCHT_ONITEMEXTRA)) - { - SetClassLong(hTreeView, GCLP_HCURSOR, NULL); - hCursor = LoadCursor(NULL, IDC_HAND); // set mouse cursor to a hand when hovering over items or their extra images - } else - { - SetClassLong(hTreeView, GCLP_HCURSOR, (LONG)LoadCursor(NULL, IDC_ARROW)); - } - if (!hCursor) - { - hCursor = LoadCursor(NULL, IDC_ARROW); - } - SetCursor(hCursor); - return true; - } else - { - SetClassLong(hTreeView, GCLP_HCURSOR, (LONG)LoadCursor(NULL, IDC_ARROW)); - } - } break; - case WM_CLOSE: - { - KillTimer(hwndDlg, SAM_TIMER_ID); - if (dat->IsModeless) - { - DestroyWindow(hwndDlg); - } else - { - EndDialog(hwndDlg, 2); - } - } break; - case WM_DESTROY: - { - if (dat) - { - delete dat; - } - if (CList) - { - delete CList; - CList = NULL; - } - delete MsgTree; - MsgTree = NULL; - g_SetAwayMsgPage.SetWnd(NULL); - DestroyWindow(hWndTooltips); - return false; - } break; - } - return false; -} diff --git a/!Deprecated/NewAwaySysMod/VersionNo.h b/!Deprecated/NewAwaySysMod/VersionNo.h deleted file mode 100644 index 3634e99662..0000000000 --- a/!Deprecated/NewAwaySysMod/VersionNo.h +++ /dev/null @@ -1,5 +0,0 @@ -#define STRSPECIALBUILD "2636" -#define FILEVER 0, 3, 8, 4 -#define STRFILEVER "0, 3, 8, 4" -#define PRODUCTVER FILEVER -#define STRPRODUCTVER STRFILEVER diff --git a/!Deprecated/NewAwaySysMod/copying.txt b/!Deprecated/NewAwaySysMod/copying.txt deleted file mode 100644 index 45645b4b53..0000000000 --- a/!Deprecated/NewAwaySysMod/copying.txt +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/!Deprecated/NewAwaySysMod/nas_readme.txt b/!Deprecated/NewAwaySysMod/nas_readme.txt deleted file mode 100644 index 83395abf60..0000000000 --- a/!Deprecated/NewAwaySysMod/nas_readme.txt +++ /dev/null @@ -1,281 +0,0 @@ -New Away System plugin - by Chervov Dmitry aka Deathdemon - -You can always find the latest plugin version here: http://deathdemon.int.ru/projects.php -If you have some questions, you'll find answers on most of them on the Miranda forums: http://forums.miranda-im.org/showthread.php?t=2179 - -New Away System requires at least Miranda v0.6 to work properly. v0.7 or above is recommended. -If you use an older Miranda core, either update it or use New Away System v0.3.7.8, which is available here: -http://deathdemon.int.ru/projects/archive/NewAwaySysW_build2371.zip (Unicode; Windows XP/2000/NT) -http://deathdemon.int.ru/projects/archive/NewAwaySys_build2371.zip (ANSI; Windows 95/98/ME) - -Overview -======== - -New Away System is a successor to AwaySysMod plugin by XF007 and Tornado. -It allows to set your status messages using dynamic variables and do some interesting tricks, like different message each time someone requests it, or different status message depending on a time of the day, and much more... - -If you're confused by all these variables, it's not a problem :) NAS can also be used in a usual way, by entering usual text as a status message. the only thing you really need to remember is that if your message gets parsed incorrectly (and this happens in some rare cases, when you accidentally use some special characters in the message, like # character), try enclosing that part of your message in `quotes` (note, it's `, not ' !) - -Main features: -- categorized predefined status messages (a message tree is used to store them) -- autoreply -- per-protocol status messages, and (ICQ only) per-contact status messages -- optional notification through a popup that someone read your status message (works only for ICQ, as it's the only protocol that stores status messages on the client side) -- logging ICQ status message requests to a file (requires LogService plugin) -- optional updating of your status messages on non-ICQ protocols every X seconds -- multiple ICQ accounts support - -Known issues: -- currently there is no way to show UINs of contacts that are not on the contact list and requesting a status message - it requires some changes to Variables plugin -- there's still no proper unicode status message support in protocol plugins, so even with unicode NAS version much depends on protocol itself - -To use dynamic variables in NAS, you need to install Variables plugin by Unregistered: http://www.pboon.nl/projects.htm (highly recommended, as without Variables NAS will have a limited functionality). -To log ICQ status message requests to a file, you need LogService plugin: http://deathdemon.int.ru/projects.php - -some useful variables: -?cinfo(%subject%,display) - nick of the contact who is reading your status message -?cinfo(%subject%,first) - first name of the contact -?cinfo(%subject%,last) - last name of the contact -(for detailed description of other possible values, see the Variables help dialog and readme) - -A brief description of the plugin options, just to make things more clear: -Default messages are used by default for each status, unless you set "by default... use the message from last time" in the miranda options -> Status -> Away System -> Main options tab. -Each status can have one and only one default message. that's why it's not possible to 'uncheck' "use this message as default for.." buttons, once they were checked. - just select another message in the tree and set it as default. -You can set any predefined message to be default for certain statuses. -Also you can add/delete/modify/move your messages/categories in the "Predefined messages" category of the message tree. -Most recent status messages are placed in the "Recent messages" category; it's not recommended to put your messages manually there, as they'll be replaced by your recent messages. However this category is editable too, just like "predefined messages" is. - -FAQ -=== - -Q: when I click on the blue question mark button, nothing happens -A: make sure you have the latest build of Variables plugin installed - -Q: all variables remain unparsed and other contacts read my status message, for example, as "Gone since %nas_awaysince_time%" instead of "Gone since 11:45" -A: Either a) see the previous answer Or b) you checked the "Disable parsing of status messages by Variables plugin" checkbox in the settings menu (one of the buttons on the bottom of the status message change dialog) - -Q: NAS uses a wrong status message when miranda sets idle status automatically after several minutes of inactivity -A: it's a known incompatibility with the built-in autoaway module and it's impossible to solve it in a reasonable way without changes to the miranda core. you can use AdvancedAutoAway plugin if you really need a correct status message with autoaway - -Q: NAS uses a wrong status message even when I set it manually -A: You cannot ever trust contact list's status bar tooltips that show your own status message (though in many cases they still show it correctly). The only way to make sure that your status message is correct is to ask your friend to read it. - -Q: what about xstatus support? -A: it's planned - -Q: why does NAS show ?cinfo variables unparsed ("?cinfo(%subject%,display)", "?cinfo(%subject%,id)" etc.) when the contact is not on the contact list? -A: it requires changes to Variables plugin to allow NAS to override the default behavior of ?cinfo variable. currently there's no any solution of this issue - -Q: I can't read or set a status message in unicode -A: there's still no proper support of unicode status messages by protocol plugins. So, currently even the unicode build of NAS is unable to show unicode status messages of your contacts. I'll fix it as soon as protocol plugins allow me to do that. - -Q: I updated NAS and an autoreply doesn't contain my status message now. with an old version it appended the status message at the end. -A: check that %extratext% is present at the end of Autoreply format (options ->Status->Away System->Autoreply tab). If it's not there, just add it at the end. for example, the default format is: -Miranda IM autoreply > -%extratext% - - -Thanks to -========= - -- Faith Healer for icons and useful suggestions -- Nullbie for his ideas -- Bio for a nice idea of msvcr70->msvcrt patch -- UnregistereD for Variables plugin -- ...and to many other people who reported bugs and gave me ideas - - -Contact -======= -The preferable way for questions, bug reports or some suggestions is using Miranda forums: -http://forums.miranda-im.org/showthread.php?t=2179 -Otherwise, if you have something extremely important to say, you can contact me on ICQ or e-mail :) ICQ: 310927; e-mail: dchervov@yahoo.com - - -Changelog -========= - -v0.3.8.3 (build 26xx; xxx xx, 2007) ---------- - - fixed some GDI leaks - -v0.3.8.2 (build 2628; Oct 13, 2007) ---------- - - fixed a bug with default messages and per-contact notification settings, introduced in the previous build - -v0.3.8.1 (build 2626; Oct 13, 2007) ---------- - - added "Not-on-list contacts" setting to the NAS' contact list in the options - - added back an option to log to a file only when popup notification for a contact is enabled - - fix for %nas_timepassed% to return correct value - - minor interface improvements - - ContactSettings api change - - some minor fixes - -v0.3.8.0 (build 2601; Oct 4, 2007) ---------- - - added Miranda 0.8 support - - significantly improved autoreply, added more options and fixed bugs - - added support for ICQ Plus online status messages - - removed %nas_message% variable. use %extratext% instead - - fixed xstatus request notifications - - moved logging features to a separate plugin - LogService - - added support for ContactSettings plugin - - MS_VARS_GETICON service is used now to get an icon for Variables help buttons - - some more minor fixes and improvements - -v0.3.7.8 (build 2371; Jul 2, 2006) ---------- - - fixed a bug with disappeared notification icons under the Contacts tab - - other minor fixes - -v0.3.7.7 (build 2368; Jul 2, 2006) ---------- - - support for locked protocols - - implemented unicode logging correctly (thanks to Unregistered) - - fix for MS_AWAYMSG_GETSTATUSMSG to return parsed status message - - made xstatus notification popups show current xstatus icon - - added possibility to change per-contact autoreply setting from the contact menu - - fix for wrong extra icons in the contact list of the status message change window - - other minor fixes and improvements - -v0.3.7.6 (build 2348; May 12, 2006) ---------- - - changed NAS behavior so that it accepts status message changes through PS_SETAWAYMSG service now - - removed some obsolete implementations of NAS services (update your MyDetails/StartupStatus/AdvancedAutoAway plugins if they stopped working with this release of NAS) - - fixed a minor bug - empty status message after setting it through a service, in some specific cases - -v0.3.7.5 (build 2346; May 8, 2006) ---------- - - fixed crash on startup on some systems - -v0.3.7.4 (build 2344; May 5, 2006) ---------- - - fix due to database API change in nightly build #53 that made NAS reset its message tree to the defaults - -v0.3.7.3 (build 2341; May 4, 2006) ---------- - - fix for a wrong message in some cases, when using NAS' services - - some other minor fixes - -v0.3.7.2 (build 2338; April 30, 2006) ---------- - - various improvements and fixes to the NAS services (finally managed to get SS and NAS working together ok (hopefully); thanks to Unregistered) - - improved compatibility with plugins that don't support NAS (implemented a method to detect status changes by such plugins) - - disabled autoreply on protocols that don't support outgoing messages - - fixed a bug with usual status in popups on extended status message request when logging is disabled - - fixed some other bugs - -v0.3.7.1 (build 2311; April 22, 2006) ---------- - - fix for contact menu items in unicode build (only the first letter was displayed) - - some other minor changes - -v0.3.7.0 (build 2305; April 21, 2006) ---------- - - unicode support - - some fixes to the NAS services for compatibility with StartupStatus and AdvancedAutoAway plugins - - fixed an unnecessary 0x13 character at the end of the popup header - -v0.3.6.9 (build 2264; March 15, 2006) --------- - - now it's possible to get default messages for any status mode using NAS services - -v0.3.6.8 (build 2262; March 13, 2006) --------- - - %nas_requestcount% and %nas_messagecount% fix - - status message is automatically selected now when the status selection window opens - - now NAS doesn't add status message to an autoreply automatically. use %extratext% variable in the Autoreply format for that - -v0.3.6.7 (build 2257; February 12, 2006) --------- - - some minor changes to improve MyDetails plugin support - -v0.3.6.6 (build 2256; November 2, 2005) --------- - - status message change dialog didn't ever pop up for Online and Invisible modes, regardless of settings. fixed. - -v0.3.6.5 (build 2253; October 30, 2005) --------- - - updated all the links (also for Updater plugin) to point to deathdemon.int.ru - -v0.3.6.4 (build 2250; October 16, 2005) --------- - - now NAS shares contact status messages with other plugins when requesting them through contact's menu. - - improved accuracy of status message updates - - Read status message window is resizeable now - - Updater plugin support - - implemented MS_NAS_INVOKESTATUSWINDOW service - -v0.3.6.3 (build 2216; September 14, 2005) --------- - - correct ICQ XStatus logging and popup notification. - - fixed a bug with status message refresh on startup when setting status through StartupStatus. - -v0.3.6.3 (build 2210; September 12, 2005) --------- - - added a possibility to use %nas_message% variable in the autoreply format, to specify where exactly NAS should place usual status message. - - added "Log requests only if popup notification for a contact is enabled" checkbox in the Log tab - - some strings were untranslatable. fixed. - -v0.3.6.3 (build 2200; September 11, 2005) --------- - - workaround for contact list's CLGN_NEXT bug. - -v0.3.6.3 (build 2193; September 10, 2005) --------- - - now NAS will open the status message change window much faster when "Show contacts" is disabled - - optimized tabs in the options - now NAS' options will load faster - - previous NAS build didn't load on systems with an old msvcrt.dll version. fixed. (thanks to scHacklaban) - -v0.3.6.3 (build 2186; September 8, 2005) --------- - - fixed a crash on status change when there are no groups in a contact list (thanks to Ladiko) - - added "Contacts" options tab - it allows to set per-contact settings, and also there is a new setting - per-contact popup notification - - added %nas_protocol% variable that returns current protocol name - - fixed a bug with message tree scrolling when per-status recent messages are enabled - - NAS stored per-protocol recent messages in wrong categories with per-status recent messages enabled - - some other minor bugfixes - -v0.3.6.2 (build 2136; August 28, 2005) --------- - - fixed a bug with wrong status messages that was introduced in the previous build - - implemented services that will allow other plugins to get/set status messages in a way compatible with NAS - -v0.3.6.2 (build 2129; August 27, 2005) --------- - - added support for StartupStatus and AdvancedAutoAway, and also hopefully for some other plugins that change status - - added nas_predefinedmessage variable - - some minor bugfixes - -v0.3.6.2 (build 2110; August 26, 2005) --------- -bugfixes: - - hopefully fixed problems with autoreply - - previous builds set an empty message on statuses for which "don't show status message dialog.." was enabled - -v0.3.6.2 (build 2108; August 26, 2005) --------- - - multiple ICQ accounts support - - optional updating of your status messages on non-ICQ protocols - - now NAS works pretty well even without Variables plugin - - some bugfixes - - added translation.txt - -v0.3.6.1 (build 2083; August 25, 2005) --------- -Added a lot of new features: - - categorized predefined status messages - - separate default messages for different statuses - - (bugfix) NAS stores status messages separately for different protocols now. for example, if you'll change your MSN status message, your ICQ message won't be overwritten now. - - many improvements in user interface - - some bugfixes - -v0.3.6.0 (build 733; August 13, 2005) --------- - - Just a quick fix of an old build to stop notification of custom status message requests (newer builds are still very unstable). - -v0.3.6.0 (build 732; May 16, 2005) --------- - - First public release. \ No newline at end of file diff --git a/!Deprecated/NewAwaySysMod/nas_translation.txt b/!Deprecated/NewAwaySysMod/nas_translation.txt deleted file mode 100644 index 9d7053a732..0000000000 --- a/!Deprecated/NewAwaySysMod/nas_translation.txt +++ /dev/null @@ -1,238 +0,0 @@ -Miranda Language Pack Version 1 -Locale: 0809 -Authors: Deathdemon; XF007; Goblineye Entertainment -Author-email: dchervov@yahoo.com -Last-Modified-Using: Miranda IM 0.7svn -Plugins-included: NewAwaySys -; Generated by lpgen on Sat Oct 13 14:56:33 2007 -; Translations: 210 - -; Common strings that belong to many files -;[ message:\r\n] -;[** All contacts **] -;[Autoreply] -;[Create new category] -;[Delete] -;[Don't send status message] -;[Enable autoreply] -;[New Away System] -;[New category] -;[New message] -;[OK] -;[Open Variables help dialog] -;[PopUps] -;[Toggle autoreply on/off] - -; C:/VSProjects/Miranda/plugins/NewAwaySys/AwayOpt.cpp -;[** Not-on-list contacts **] -;[Away] -;[Been gone since %nas_awaysince_time%, will be back later.] -;[Been having ?ifgreater(?ctime(H),2,?ifgreater(?ctime(H),10,?ifgreater(?ctime(H),16,supper,dinner),breakfast),supper) since %nas_awaysince_time%.] -;[Close popup] -;[Contacts] -;[Create new message] -;[Creepy] -;[DND] -;[Default messages] -;[Do nothing] -;[Edit status messages] -;[File] -;[Free for chat] -;[Give a guy some peace, would ya?] -;[Give it up, I'm not in!] -;[Gone fragging] -;[I'm a chatbot!] -;[I'm hiding from the mafia.] -;[I've been on the phone since %nas_awaysince_time%, give me a sec!] -;[Invisible] -;[Main options] -;[Message] -;[Miranda] -;[NA] -;[Not right now.] -;[Occupied] -;[On the phone] -;[Online] -;[Open contact details window] -;[Open contact history] -;[Open contact menu] -;[Open log file] -;[Open message window] -;[Other (XStatus)] -;[Out to lunch] -;[Predefined messages] -;[Recent messages] -;[URL] -;[When this checkbox is ticked, NewAwaySys counts \"send times\" starting from the last status message change, even if status mode didn't change.\nWhen the checkbox isn't ticked, \"send times\" are counted from last status mode change (i.e. disabled state is more restrictive).] -;[Windows] -;[Yep, I'm here.] -;[You can put your frequently used and favorite messages in this category.] -;[Your master, %nas_mynick%, has been %nas_statdesc% since the day that is only known as ?nas_awaysince_date(dddd)... When he gets back, I'll tell him you dropped by...] -;[Your most recent status messages are placed in this category. It's not recommended to put your messages manually here, as they'll be replaced by your recent messages.] - -; C:/VSProjects/Miranda/plugins/NewAwaySys/AwaySys.cpp -;[%d hours] -;[%d minutes] -;[%d seconds] -;[) read your ] -;[Don't send status message when you are %s] -;[Enable autoreply when you are %s] -;[Ignore status message requests from this contact and don't send an autoreply] -;[Ignore status message requests from this contact and don't send an autoreply.\r\n\"Store contact autoreply/ignore settings for each status separately\" is enabled, so this setting is per-contact AND per-status.] -;[New Away System plugin requires Miranda version 0.6.0.0 or above.] -;[New Away System: Status message request notifications] -;[New Away System\t(x)\tAway since date in format x (x is optional)] -;[New Away System\t(x)\tAway since time in format x (x is optional)] -;[New Away System\t(x)\tReturns one of your predefined messages by its title: ?nas_predefinedmessage(creepy)] -;[New Away System\tCurrent protocol name] -;[New Away System\tNumber of messages from the contact] -;[New Away System\tNumber of status message requests from the contact] -;[New Away System\tStatus description] -;[New Away System\tTime passed until request] -;[New Away System\tYour nick for current protocol] -;[NewAwaySys: Incoming status message request] -;[Off] -;[On] -;[Re&ad %s Message] -;[Read status message] -;[Set %s message for the contact] -;[Set status message] -;[Stranger] -;[Use the default setting] -;[\"Store contact autoreply/ignore settings for each status separately\" is enabled, so this setting is per-contact AND per-status.] - -; C:/VSProjects/Miranda/plugins/NewAwaySys/Common.h -;[?cinfo(%subject%,display) (?cinfo(%subject%,id)) is reading your %nas_statdesc% message:\r\n%extratext%] -;[Away System] -;[Miranda IM autoreply >\r\n%extratext%] -;[Status] -;[Toggle autoreply off] -;[Toggle autoreply on] -;[Variables plugin is not installed] -;[extended status] - -; C:/VSProjects/Miranda/plugins/NewAwaySys/MsgTree.cpp -;[Do you really want to delete this ] -;[You've made changes to multiple Message trees at a time.\r\nDo you want to leave changes in \"] -;[\" dialog?\r\nPress Yes to leave changes in this dialog, or No to discard its changes and save changes of the other Message tree instead.] -;[category with its messages?] -;[message?] - -; C:/VSProjects/Miranda/plugins/NewAwaySys/Notification.cpp -;[) is reading your ] -;[Can't open log file ] -;[Error #%d] - -; C:/VSProjects/Miranda/plugins/NewAwaySys/ReadAwayMsg.cpp -;[&Close] - -; C:/VSProjects/Miranda/plugins/NewAwaySys/Resources.rc -;[%extratext% is your status message] -;[%s Message for %s] -;[&Away] -;[&Cancel] -;[&DND] -;[&Delete] -;[&Free for chat] -;[&Invisible] -;[&NA] -;[&Other] -;[&Rename] -;[&Save] -;[&Save current window settings as default] -;[&Variables] -;[-1 = Infinite] -;[...for each status separately] -;[0 = Default] -;[Autoreply format:] -;[Autoreply off] -;[Autoreply on] -;[Background] -;[By default...] -;[Click action] -;[Colours] -;[Create new &category] -;[Create new &message] -;[Delay] -;[Disable autoreply when...] -;[Disable parsing of status messages by Variables plugin] -;[Don't notify of requests] -;[Don't reply to ICQ contacts] -;[Don't reply when I'm invisible to the contact] -;[Don't show the message dialog for] -;[Enable contact menu items] -;[Ignore requests] -;[Log to a file only when popup notification for a contact is enabled] -;[Means the setting is different for different status modes / contacts] -;[Message tree category menu] -;[Message tree menu] -;[New &Category] -;[Note: these settings are applied to all status modes at once.] -;[Notify of requests] -;[Occ&upied] -;[On event...] -;[On left click] -;[On right click] -;[On the &Phone] -;[On&line] -;[Only notify when:] -;[Out to &Lunch] -;[Popup notification] -;[Popup text format] -;[Preview] -;[Remember last message used for a contact...] -;[Reply only when Idle] -;[Reply only when contact's message window is closed] -;[Reset per-protocol messages when changing global status] -;[Reset this counter also when I just change my status text\n(when status icon remains the same)] -;[Retrieving %s message...] -;[Save As &New] -;[Save autoreply to the history] -;[Save default window settings &automatically] -;[Se&ttings] -;[Sec] -;[Send an autoreply] -;[Send maximum] -;[Set as &default for] -;[Set away message window options] -;[Show &contacts] -;[Show predefined &messages] -;[Store] -;[Store contact autoreply/ignore settings for each status separately] -;[Store protocol autoreply settings for each status separately] -;[Store protocol messages for each status separately] -;[Text] -;[Title:] -;[Update status messages for non-ICQ protocols every] -;[Use default] -;[Use protocol specific nick for %nas_mynick%] -;[Use the default message] -;[Use the most recent message] -;[Use this message as default for] -;[V] -;[Wait] -;[most recent messages (0=disable)] -;[seconds] -;[seconds before closing the status message dialog (-1=don't close)] -;[times (-1=infinite)] - -; C:/VSProjects/Miranda/plugins/NewAwaySys/SetAwayMsg.cpp -;[ (autoreply only)] -;[ contacts *] -;[ for ] -;[ message] -;[ protocol] -;[Apply] -;[Closing in %d] -;[Do you want to apply the message?] -;[Don't send the status message to selected contact(s)] -;[Save as a new message] -;[Save, replacing the selected message] -;[Send an autoreply to selected contact(s)] -;[Set ] -;[Show settings menu] -;[all contacts] -;[status] - -; C:/VSProjects/Miranda/plugins/NewAwaySys/m_variables.h -;[Open String Formatting Help] diff --git a/!Deprecated/NewAwaySysMod/newawaysysmod-translation.txt b/!Deprecated/NewAwaySysMod/newawaysysmod-translation.txt deleted file mode 100644 index b89a9f4867..0000000000 --- a/!Deprecated/NewAwaySysMod/newawaysysmod-translation.txt +++ /dev/null @@ -1,226 +0,0 @@ -; Common strings that belong to many files -;[ message:\r\n] -;[** All contacts **] -;[Autoreply] -;[Create new category] -;[Delete] -;[Don't send status message] -;[Enable autoreply] -;[New Away System] -;[New category] -;[New message] -;[OK] -;[Open Variables help dialog] -;[Toggle autoreply on/off] - -; ../../plugins/NewAwaySysMod/AwayOpt.cpp -;[** Not-on-list contacts **] -;[Away] -;[Been gone since %nas_awaysince_time%, will be back later.] -;[Been having ?ifgreater(?ctime(H),2,?ifgreater(?ctime(H),10,?ifgreater(?ctime(H),16,supper,dinner),breakfast),supper) since %nas_awaysince_time%.] -;[Contacts] -;[Create new message] -;[Creepy] -;[DND] -;[Default messages] -;[File] -;[Free for chat] -;[Give a guy some peace, would ya?] -;[Give it up, I'm not in!] -;[Gone fragging] -;[I'm a chatbot!] -;[I'm hiding from the mafia.] -;[I've been on the phone since %nas_awaysince_time%, give me a sec!] -;[Invisible] -;[Main options] -;[Message] -;[Miranda] -;[NA] -;[Not right now.] -;[Occupied] -;[On the phone] -;[Online] -;[Out to lunch] -;[Predefined messages] -;[Recent messages] -;[Statuses messages] -;[URL] -;[When this checkbox is ticked, NewAwaySys counts \"send times\" starting from the last status message change, even if status mode didn't change.\nWhen the checkbox isn't ticked, \"send times\" are counted from last status mode change (i.e. disabled state is more restrictive).] -;[Windows] -;[Yep, I'm here.] -;[You can put your frequently used and favorite messages in this category.] -;[Your master, %nas_mynick%, has been %nas_statdesc% since the day that is only known as ?nas_awaysince_date(dddd)... When he gets back, I'll tell him you dropped by...] -;[Your most recent status messages are placed in this category. It's not recommended to put your messages manually here, as they'll be replaced by your recent messages.] - -; ../../plugins/NewAwaySysMod/AwaySys.cpp -;[%d hours] -;[%d minutes] -;[%d seconds] -;[) read your ] -;[Don't send status message when you are %s] -;[Enable autoreply when you are %s] -;[Ignore status message requests from this contact and don't send an autoreply] -;[Ignore status message requests from this contact and don't send an autoreply.\r\n\"Store contact autoreply/ignore settings for each status separately\" is enabled, so this setting is per-contact AND per-status.] -;[New Away System: Status message request notifications] -;[New Away System\t(x)\tAway since date in default format; ?nas_awaysince_date(x) in format x] -;[New Away System\t(x)\tAway since time in default format; ?nas_awaysince_time(x) in format x] -;[New Away System\t(x)\tReturns one of your predefined messages by its title: ?nas_predefinedmessage(creepy)] -;[New Away System\tCurrent protocol name] -;[New Away System\tNumber of messages from the contact] -;[New Away System\tNumber of status message requests from the contact] -;[New Away System\tStatus description] -;[New Away System\tTime passed until request] -;[New Away System\tYour nick for current protocol] -;[NewAwaySys: Incoming status message request] -;[Off] -;[On] -;[Re&ad %s Message] -;[Read status message] -;[Set %s message for the contact] -;[Set status message] -;[Stranger] -;[Use the default setting] -;[\"Store contact autoreply/ignore settings for each status separately\" is enabled, so this setting is per-contact AND per-status.] - -; ../../plugins/NewAwaySysMod/Common.h -;[?cinfo(%subject%,display) (?cinfo(%subject%,id)) is reading your %nas_statdesc% message:\r\n%extratext%] -;[Away System] -;[Miranda IM autoreply >\r\n%extratext%] -;[PopUps] -;[Status] -;[Toggle autoreply off] -;[Toggle autoreply on] -;[Variables plugin is not installed] -;[extended status] - -; ../../plugins/NewAwaySysMod/MsgTree.cpp -;[Do you really want to delete this ] -;[Do you really want to delete this category with its messages?] -;[Do you really want to delete this message?] -;[You've made changes to multiple Message trees at a time.\r\nDo you want to leave changes in \"] -;[\" dialog?\r\nPress Yes to leave changes in this dialog, or No to discard its changes and save changes of the other Message tree instead.] -;[category with its messages?] -;[message?] - -; ../../plugins/NewAwaySysMod/NewAwaySys.rc -;[%extratext% is your status message] -;[%s Message for %s] -;[&Away] -;[&Cancel] -;[&DND] -;[&Delete] -;[&Free for chat] -;[&Invisible] -;[&NA] -;[&Other] -;[&Rename] -;[&Save] -;[&Save current window settings as default] -;[&Variables] -;[-1 = Infinite] -;[0 = Default] -;[Autoreply format:] -;[Autoreply off] -;[Autoreply on] -;[Background] -;[Click action] -;[Colours] -;[Configure autoaway] -;[Create new &category] -;[Create new &message] -;[Delay] -;[Disable autoreply when...] -;[Disable parsing of status messages by Variables plugin] -;[Don't notify of requests] -;[Don't reply to ICQ contacts] -;[Don't reply when I'm invisible to the contact] -;[Don't show the message dialog for] -;[Enable contact menu items] -;[Ignore requests] -;[Log to a file only when popup notification for a contact is enabled] -;[Means the setting is different for different status modes / contacts] -;[Message tree category menu] -;[Message tree menu] -;[New &Category] -;[Note: these settings are applied to all status modes at once.] -;[Notify of requests] -;[Occ&upied] -;[On event...] -;[On left click] -;[On right click] -;[On the &Phone] -;[On&line] -;[Only notify when:] -;[Out to &Lunch] -;[Popup notification] -;[Popup text format] -;[Preview] -;[Remember last message used for a contact...] -;[Reply only when Idle] -;[Reply only when contact's message window is closed] -;[Reset per-protocol messages when changing global status] -;[Reset this counter also when I just change my status text\n(when status icon remains the same)] -;[Retrieving %s message...] -;[Save As &New] -;[Save autoreply to the history] -;[Save default window settings &automatically] -;[Se&ttings] -;[Sec] -;[Send an autoreply] -;[Send maximum] -;[Set as &default for] -;[Set away message window options] -;[Show &contacts] -;[Show predefined &messages] -;[Statuses messages:] -;[Store] -;[Store contact autoreply/ignore settings for each status separately] -;[Store for each status separately] -;[Store protocol autoreply settings for each status separately] -;[Store protocol messages for each status separately] -;[Text] -;[Title:] -;[Update status messages for non-ICQ protocols every] -;[Use default] -;[Use default...] -;[Use protocol specific nick for %nas_mynick%] -;[Use the default message] -;[Use the most recent message] -;[Use this message as default for] -;[V] -;[Wait] -;[most recent messages (0=disable)] -;[seconds] -;[seconds before closing the status message dialog (-1=don't close)] -;[times (-1=infinite)] - -; ../../plugins/NewAwaySysMod/Notification.cpp -;[) is reading your ] -;[Can't open log file ] -;[Error #%d] - -; ../../plugins/NewAwaySysMod/ReadAwayMsg.cpp -;[&Close] - -; ../../plugins/NewAwaySysMod/SetAwayMsg.cpp -;[ (autoreply only)] -;[ contacts *] -;[ message] -;[ protocol] -;[Apply] -;[Closing in %d] -;[Do you want to apply the message?] -;[Don't send the status message to selected contact(s)] -;[Save as a new message] -;[Save, replacing the selected message] -;[Send an autoreply to selected contact(s)] -;[Set ] -;[Set message for] -;[Show settings menu] -;[Statuses] -;[account] -;[all accounts] -;[all contacts] -;[available autoreply only] -;[for] -;[message for] diff --git a/!Deprecated/NewAwaySysMod/resource.h b/!Deprecated/NewAwaySysMod/resource.h deleted file mode 100644 index 1c6190554b..0000000000 --- a/!Deprecated/NewAwaySysMod/resource.h +++ /dev/null @@ -1,261 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by NewAwaySys.rc -// -#define IDD_OPTDIALOGMAIN 101 -#define IDD_MESSAGES 101 -#define IDD_MODERNOPT_MESSAGES 102 -#define IDI_MSGICON 109 -#define IDI_SOE_ENABLED 110 -#define IDD_READAWAYMSG 111 -#define IDI_SOE_DISABLED 111 -#define IDB_SOE_ENABLED 112 -#define IDB_SOE_DISABLED 114 -#define IDD_NOTIFYOPTDLG 115 -#define IDD_NOTIFYVARSDLG 116 -#define IDD_AUTOREPLY 121 -#define IDR_SAM_OPTIONS 122 -#define IDI_DOT 123 -#define IDI_IGNORE 124 -#define IDI_SAVEMSG 127 -#define IDI_SAVE 127 -#define IDI_SAVEASNEW 128 -#define IDI_DELETE 130 -#define IDI_NEWCATEGORY 133 -#define IDR_MSGTREE_CATEGORYMENU 134 -#define IDR_MSGTREE_MESSAGEMENU 135 -#define IDI_NEWMESSAGE 136 -#define IDI_SETTINGS 137 -#define IDI_STATUS_OTHER 138 -#define IDD_CONTACTSOPTDLG 139 -#define IDI_DISABLENOTIFY 140 -#define IDI_ENABLENOTIFY 141 -#define IDI_INDEFINITE 142 -#define IDD_SETAWAYMSG_BAK 144 -#define IDD_SETAWAYMSG 216 -#define IDD_MOREOPTDIALOG 217 -#define IDD_POPUPOPTDLG 218 -#define IDC_STATUSBAR 999 -#define IDC_SAWAYMSG_MSGNAME 1001 -#define IDC_MESSAGEDLG_DEL 1002 -#define IDC_OPTDLG_MSGDATA 1003 -#define IDC_MESSAGEDLG_MSGDATA 1003 -#define IDC_OPTDLG_MSGNAME 1004 -#define IDC_OPTDLG_MAKEDEFAULT 1005 -#define IDC_OPTDLG_USELASTMSG 1007 -#define IDC_MOREOPTDLG_USELASTMSG 1007 -#define IDC_OPTDLG_USEDEFAULT 1008 -#define IDC_SAWAYMSG_MSGDATA 1008 -#define IDC_MOREOPTDLG_USEDEFMSG 1008 -#define IDC_OPTDLG_SAVE 1010 -#define IDC_LNK_AUTOAWAY 1010 -#define IDC_OPTDLG_RESET 1012 -#define IDC_OPTDLG_VARSLIST 1013 -#define IDC_MESSAGEDLG_VARS 1013 -#define IDC_SAWAYMSG_STATIC_CHARSTXT 1014 -#define IDC_STATIC_BYDEFAULT 1017 -#define IDC_STATIC_MSG 1021 -#define IDC_MOREOPTDLG_NEVERSTATDLG 1028 -#define IDC_MOREOPTDLG_WAITFORMSG 1029 -#define IDC_STATIC_MOREOPTDLG_WAIT 1030 -#define IDC_STATIC_MOREOPTDLG_SECONDSREMAIN 1031 -#define IDC_MOREOPTDLG_LMESTAT 1032 -#define IDC_MOREOPTDLG_PERSTATUSMRM 1032 -#define IDC_MOREOPTDLG_RMDLGPOS 1033 -#define IDC_MOREOPTDLG_SAVEDLGPOS 1033 -#define IDC_MOREOPTDLG_SETLASTCONTCAT 1034 -#define IDC_MOREOPTDLG_SAVECONTACTMSGS 1034 -#define IDC_MOREOPTDLG_SAVEPERSONALMSGS 1034 -#define IDC_MOREOPTDLG_USEMENUITEM 1035 -#define IDC_MOREOPTDLG_PERSTATUSPERSONAL 1036 -#define IDC_MOREOPTDLG_RESETPROTOMSGS 1037 -#define IDC_MOREOPTDLG_PERSTATUSPROTOMSGS 1038 -#define IDC_MOREOPTDLG_PERSTATUSPROTOSETTINGS 1039 -#define IDC_SAWAYMSG_CONTACTSTREE 1040 -#define IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS 1040 -#define IDC_SAWAYMSG_STATIC_VARS 1041 -#define IDC_SAWAYMSG_SHOWCONTACTS 1042 -#define IDC_SAWAYMSG_STATIC_RESETCHNG 1043 -#define IDC_SAWAYMSG_OPTIONS 1043 -#define IDC_MOREOPTDLG_SENDNONICQ 1049 -#define IDC_REPLYDLG_DONTSENDTOICQ 1049 -#define IDC_MOREOPTDLG_EVNTMSG 1050 -#define IDC_REPLYDLG_EVENTMSG 1050 -#define IDC_MOREOPTDLG_EVNTURL 1051 -#define IDC_REPLYDLG_EVENTURL 1051 -#define IDC_MOREOPTDLG_EVNTFILE 1052 -#define IDC_REPLYDLG_EVENTFILE 1052 -#define IDC_MOREOPTDLG_SENDONCE 1053 -#define IDC_SAWAYMSG_SENDMSG 1054 -#define IDC_MOREOPTDLG_SENDALL 1054 -#define IDC_SAWAYMSG_IGNOREREQ 1055 -#define IDC_MOREOPTDLG_STATIC_SEND 1057 -#define IDC_REPLYDLG_STATIC_SEND 1057 -#define IDC_MOREOPTDLG_STATIC_ONEVENT 1058 -#define IDC_REPLYDLG_STATIC_ONEVENT 1058 -#define IDC_VARSLIST_STATIC_TIME 1061 -#define IDC_MOREOPTDLG_NOPOPLIST 1062 -#define IDC_MOREOPTDLG_NOPOP 1063 -#define IDC_MOREOPTDLG_NOSSMLIST 1064 -#define IDC_MOREOPTDLG_NOSSM 1065 -#define IDC_OPTDLG_PREFIX 1065 -#define IDC_REPLYDLG_PREFIX 1065 -#define IDC_MOREOPTDLG_LOGMSG 1066 -#define IDC_REPLYDLG_LOGREPLY 1066 -#define IDC_OPTDLG_USEDEFNICK 1068 -#define IDC_MOREOPTDLG_MYNICKPERPROTO 1068 -#define IDC_MOREOPTDLG_SHOWRMSG 1069 -#define IDC_MOREOPTDLG_SENDMSG 1070 -#define IDC_REPLYDLG_ENABLEREPLY 1070 -#define IDC_POPUPOPTDLG_POPUPFORMAT 1071 -#define IDC_POPUPOPTDLG_USEPOPUPS 1072 -#define IDC_POPUPOPTDLG_BGCOLOUR 1073 -#define IDC_POPUPOPTDLG_TEXTCOLOUR 1074 -#define IDC_POPUPOPTDLG_LCLICK_ACTION 1075 -#define IDC_POPUPOPTDLG_RCLICK_ACTION 1077 -#define IDC_POPUPOPTDLG_POPUPPREVIEW 1078 -#define IDC_POPUPOPTDLG_AWAYNOTIFY 1084 -#define IDC_POPUPOPTDLG_NANOTIFY 1085 -#define IDC_POPUPOPTDLG_OCCNOTIFY 1086 -#define IDC_POPUPOPTDLG_DNDNOTIFY 1087 -#define IDC_POPUPOPTDLG_FFCNOTIFY 1088 -#define IDC_POPUPOPTDLG_DEFBGCOLOUR 1089 -#define IDC_POPUPOPTDLG_DEFTEXTCOLOUR 1090 -#define IDC_NOTIFYVARS_STATIC_TIME 1091 -#define IDC_VARS_STATIC_TIME 1091 -#define IDC_POPUPOPTDLG_OTHERNOTIFY 1091 -#define IDC_POPUPOPTDLG_STATIC_LCLICK 1092 -#define IDC_POPUPOPTDLG_STATIC_RCLICK 1093 -#define IDC_POPUPOPTDLG_STATIC_BGCOLOUR 1094 -#define IDC_POPUPOPTDLG_STATIC_TEXTCOLOUR 1095 -#define IDC_POPUPOPTDLG_ONLNOTIFY 1096 -#define IDC_POPUPOPTDLG_POPUPDELAY 1099 -#define IDC_POPUPOPTDLG_STATIC_SEC 1100 -#define IDC_POPUPOPTDLG_STATIC_DEFAULT 1101 -#define IDC_POPUPOPTDLG_STATIC_INFINITE 1102 -#define IDC_MESSAGEDLG_DEF_AWAY 1109 -#define IDC_SAWAYMSG_SAVEMSG 1109 -#define IDC_REPLYDLG_ONLYIDLEREPLY 1109 -#define IDC_POPUPOPTDLG_VARS 1110 -#define IDC_REPLYDLG_DISABLE_AWAY 1110 -#define IDC_SAWAYMSG_SAVEASNEW 1110 -#define IDC_MOREOPTDLG_PANEL 1111 -#define IDC_SAWAYMSG_NEWCATEGORY 1111 -#define IDC_SAWAYMSG_DELETE 1112 -#define IDC_MESSAGEDLG_DEF_ONL 1113 -#define IDC_MESSAGEDLG_DEF_NA 1114 -#define IDC_MESSAGEDLG_DEF_OCC 1115 -#define IDC_MESSAGEDLG_DEF_DND 1116 -#define IDC_MESSAGEDLG_DEF_FFC 1117 -#define IDC_MESSAGEDLG_DEF_OTP 1118 -#define IDC_MESSAGEDLG_DEF_OTL 1119 -#define IDC_MESSAGEDLG_MSGTITLE 1120 -#define IDC_MOREOPTDLG_DONTPOPDLG_INV 1120 -#define IDC_MESSAGEDLG_MSGTREE 1121 -#define IDC_REPLYDLG_DISABLE_ONL 1121 -#define IDC_MESSAGEDLG_NEWCAT 1122 -#define IDC_REPLYDLG_DISABLE_NA 1122 -#define IDC_MESSAGEDLG_NEWMSG 1123 -#define IDC_REPLYDLG_DISABLE_OCC 1123 -#define IDC_REPLYDLG_DISABLE_DND 1124 -#define IDC_REPLYDLG_DISABLE_FFC 1125 -#define IDC_REPLYDLG_DISABLE_OTP 1126 -#define IDC_REPLYDLG_DISABLE_OTL 1127 -#define IDC_REPLYDLG_DISABLE_INV 1128 -#define IDC_MOREOPTDLG_RECENTMSGSCOUNT 1129 -#define IDC_MOREOPTDLG_UPDATEMSGSPERIOD 1130 -#define IDC_MESSAGEDLG_DEF_INV 1131 -#define IDC_REPLYDLG_SENDCOUNT 1132 -#define IDC_MOREOPTDLG_DONTPOPDLG_ONL 1133 -#define IDC_MOREOPTDLG_DONTPOPDLG_AWAY 1134 -#define IDC_MOREOPTDLG_DONTPOPDLG_NA 1135 -#define IDC_MOREOPTDLG_DONTPOPDLG_OCC 1136 -#define IDC_MOREOPTDLG_DONTPOPDLG_DND 1137 -#define IDC_MOREOPTDLG_DONTPOPDLG_FFC 1138 -#define IDC_MOREOPTDLG_DONTPOPDLG_OTP 1139 -#define IDC_MOREOPTDLG_DONTPOPDLG_OTL 1140 -#define IDC_REPLYDLG_STATIC_TIMES 1141 -#define IDC_MESSAGEDLG_TEST 1142 -#define IDC_MOREOPTDLG_EDITMESSAGES 1142 -#define IDC_SAWAYMSG_VARS 1142 -#define IDC_SAWAYMSG_TREE 1149 -#define IDC_SAWAYMSG_EDITMSGS 1150 -#define IDC_SAWAYMSG_RESET 1151 -#define IDC_OK 1152 -#define IDC_MSGSPLITTER 1154 -#define IDC_SAWAYMSG_MSGSPLITTER 1154 -#define IDC_CONTACTSPLITTER 1155 -#define IDC_SAWAYMSG_CONTACTSPLITTER 1155 -#define IDC_SAWAYMSG_STATIC_IGNOREICON 1157 -#define IDC_SAWAYMSG_STATIC_REPLYICON 1158 -#define IDC_MOREOPTDLG_WAITFORMSG_SPIN 1161 -#define IDC_MOREOPTDLG_RECENTMSGSCOUNT_SPIN 1162 -#define IDC_REPLYDLG_SENDCOUNT_SPIN 1163 -#define IDC_MOREOPTDLG_UPDATEMSGSPERIOD_SPIN 1163 -#define IDC_POPUPOPTDLG_POPUPDELAY_SPIN 1164 -#define IDC_REPLYDLG_VARS 1165 -#define IDC_MOREOPTDLG_UPDATEMSGS 1166 -#define IDC_CONTACTSDLG_LIST 1168 -#define IDC_REPLYDLG_DONTREPLYINVISIBLE 1169 -#define IDC_REPLYDLG_ONLYIDLEREPLY_COMBO 1170 -#define IDC_REPLYDLG_ONLYCLOSEDDLGREPLY 1171 -#define IDC_REPLYDLG_RESETCOUNTERWHENSAMEICON 1172 -#define IDC_REPLYDLG_STATIC_DISABLEWHENSTATUS 1174 -#define IDC_REPLYDLG_STATIC_FORMAT 1175 -#define IDC_POPUPOPTDLG_GROUP_NOTIFICATION 1176 -#define IDC_POPUPOPTDLG_LOGONLYWITHPOPUP 1177 -#define IDC_POPUPOPTDLG_STATIC_EXTRATEXT 1178 -#define IDC_REPLYDLG_STATIC_EXTRATEXT 1179 -#define IDC_TXT_TITLE1 1181 -#define IDC_TXT_TITLE2 1182 -#define IDC_TXT_TITLE3 1183 -#define IDC_SAWAYMSG_STATIC_COUNTER 1202 -#define IDC_READAWAYMSG_RETRIEVE 3453 -#define IDS_MESSAGEDLG_DEF_ONL 20000 -#define IDS_MESSAGEDLG_DEF_AWAY 20001 -#define IDS_MESSAGEDLG_DEF_NA 20002 -#define IDS_MESSAGEDLG_DEF_OCC 20003 -#define IDS_MESSAGEDLG_DEF_DND 20004 -#define IDS_MESSAGEDLG_DEF_FFC 20005 -#define IDS_MESSAGEDLG_DEF_INV 20006 -#define IDS_MESSAGEDLG_DEF_OTP 20007 -#define IDS_MESSAGEDLG_DEF_OTL 20008 -#define IDV_MSGTREE 20009 -#define IDS_SAWAYMSG_SHOWMSGTREE 20100 -#define IDS_SAWAYMSG_SHOWCONTACTTREE 20101 -#define IDS_SAWAYMSG_AUTOSAVEDLGSETTINGS 20102 -#define IDS_SAWAYMSG_DISABLEVARIABLES 20103 -#define IDM_SAM_OPTIONS_SHOWMSGTREE 40007 -#define IDM_SAM_OPTIONS_SHOWCONTACTTREE 40008 -#define IDM_SAM_OPTIONS_EDITMSGS 40009 -#define IDM_SAM_OPTIONS_AUTOSAVEDLGSETTINGS 40014 -#define IDM_SAM_OPTIONS_SAVEDLGSETTINGSNOW 40015 -#define IDM_MSGTREEMENU_RENAME 40017 -#define IDM_MSGTREEMENU_NEWMESSAGE 40022 -#define IDM_MSGTREEMENU_NEWCATEGORY 40024 -#define IDM_MSGTREEMENU_DELETE 40026 -#define ID_MESSAGETREECATEGORYMENU_SETASDEFAULTFOR 40027 -#define IDR_MSGTREEMENU_DEF_ONL 40037 -#define IDR_MSGTREEMENU_DEF_AWAY 40038 -#define IDR_MSGTREEMENU_DEF_NA 40039 -#define IDR_MSGTREEMENU_DEF_OCC 40040 -#define IDR_MSGTREEMENU_DEF_DND 40041 -#define IDR_MSGTREEMENU_DEF_FFC 40042 -#define IDR_MSGTREEMENU_DEF_INV 40043 -#define IDR_MSGTREEMENU_DEF_OTP 40044 -#define IDR_MSGTREEMENU_DEF_OTL 40045 -#define IDM_SAM_OPTIONS_DISABLEVARIABLES 40047 -#define IDC_READAWAYMSG_MSG 54765 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NO_MFC 1 -#define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 145 -#define _APS_NEXT_COMMAND_VALUE 40048 -#define _APS_NEXT_CONTROL_VALUE 1185 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/!Deprecated/NewAwaySysMod/version.rc b/!Deprecated/NewAwaySysMod/version.rc deleted file mode 100644 index 71fc8d12c6..0000000000 --- a/!Deprecated/NewAwaySysMod/version.rc +++ /dev/null @@ -1,58 +0,0 @@ -// -// version.rc - resources Microsoft Visual C++ does not edit directly -// -#ifdef APSTUDIO_INVOKED -#error this file is not editable by Microsoft Visual C++ -#endif //APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// Add manually edited resources here... - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// -#include "VersionNo.h" -VS_VERSION_INFO VERSIONINFO - FILEVERSION FILEVER - PRODUCTVERSION PRODUCTVER - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x21L -#else - FILEFLAGS 0x20L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "NightFox; Deathdemon; XF007; Goblineye Entertainment" - VALUE "FileDescription", "New Away System plugin for Miranda IM" - VALUE "FileVersion", STRFILEVER - VALUE "LegalCopyright", "© 2010 NightFox; © 2005-2006 Chervov Dmitry; © 2004-2005 Iksaif Entertainment; © 2002-2003 Goblineye Entertainment" -#ifdef _UNICODE - VALUE "InternalName", "NewAwaySysW" - VALUE "OriginalFilename", "NewAwaySysW.dll" - VALUE "ProductName", "New Away System (Unicode)" -#else - VALUE "InternalName", "NewAwaySys" - VALUE "OriginalFilename", "NewAwaySys.dll" - VALUE "ProductName", "New Away System (ANSI)" -#endif - VALUE "ProductVersion", STRPRODUCTVER - VALUE "SpecialBuild", STRSPECIALBUILD - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -///////////////////////////////////////////////////////////////////////////// diff --git a/!NotAdopted/IMO2sProxy/Makefile b/!NotAdopted/IMO2sProxy/Makefile deleted file mode 100644 index e83db3ec76..0000000000 --- a/!NotAdopted/IMO2sProxy/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -.PHONY: all imo2sproxy clean - -all : imo2sproxy - -imo2sproxy: - cd src/imo2skype && make imo2sproxy - cd ../.. - mv src/imo2skype/imo2sproxy bin/ - -clean : - rm imo2sproxy diff --git a/!NotAdopted/IMO2sProxy/README.txt b/!NotAdopted/IMO2sProxy/README.txt deleted file mode 100644 index 0bd77dc7c2..0000000000 --- a/!NotAdopted/IMO2sProxy/README.txt +++ /dev/null @@ -1,240 +0,0 @@ -What is the SkypeProxy for imo.im ----------------------------------- -Back in 2005 when I developed the Skype plugin for Miranda IM, I also developed -a very simple protocol to tunnel the Skype API protocol via a socket. -The reason was, that some users wanted the possibility to run Skype on a -machine different to the machine they are using Miranda IM on. -So to tunnel the Skype API remotely over the network SkypeProxy was built and -was shipped with every Skype plugin build. - -The Skype API plugin for Miranda got more and more functions as the API evolved -and finally as I didn't have enough time to continue development, I handed over -development to user "tweety" who did the later versions. -The SkypeProxy-feature is still present in the current versions, as it is very -simple. It just wraps the communiction layer with the Skype API, therefore -this concept can also be adopted by other Skype-Plugins of other IMs. - -Ever since the first version of Skype plugin, people complained that they had to -install the Skype client on their machine in order to get it to work. -The Skype client was always bloated but it got even worse throughout the years. -I abandoned Skype some time ago, as this application is just consuming far too -many system ressources. However, there are some people that are only using Skype -and I need a way to communicate with them. I'm just interested in the chat -feature, so I only need to send and receive messages from other chat users. -So what can we do about it? - -There were some attempts to reverse-engineer the Skype protocol, but nobody -succeeded so far as the protocol relies heavily on cryptography, is proprietary -closed source and the Skype client itself is heaviely protected agains all -kinds of reverse-engineering (decrypts code on the fly, uses anti-debugging -tricks, etc.). - -However some users recently discovered, that there is a new Web 2.0 service that -makes it possible to do Instant messaging via the web browser using the Ajax -framework. The name of the service is imo.im -imo.im managed to provide basic connectivity to the Skype network via SkypeKit -and the nice thing about their service is, that you don't need to register, you -can just use it out of the box. -However most people are not so excited about IM in a web interface, there are -many features that an IM application provides and that are not so convenient in -a webinterface. But as their service is a webservice using jSON calls, -it is relatively easy to talk to their application server and so users of -Instant messengers that provide Skype protocol support can take advantage of -this for providing basic connectivity to the Skype network for instant messaging -without having to install the bloated Skype client application. -Only instant messaging is possible. In fact there is also alpha-Support for -Voicechat via the imo.im flash application, but this currently doesn't work -reliable due to some Macromedia Flash sandboxing issues. -But I think for most users like me that just want to stay in contact with -other Skype users via chat these functions will be enough. - -So as mentioned above the most generic approach to link imo.im services with an -Instant messanger would be to implement this as a wrapper between imo.im and -the Skype API. This way, we don't need to implement an extra plugin and it is -easily adaptable to Skype plugins of IMs, as you only need to use the -application in Skype API emulator mode. The Skype Plugin of the IM would need to do -proper error handling, but if the plugin is coded well (must be compatible with -Skype Protocol V3), this may even work out of the box. -The plugins mustn't assume that an API call always returns something useful on -every call. -The Skype API Emulation currently only works on Windows, other clients would -need to implement the very simple socket protocol for message exchange. -This application was originally developed to work with Miranda IM, so this IM -is officially supported. - -The application runs on Win32 as well as on Unix, so it's a cross-platform layer -that you can also install on your personal Server. By design, it would be even -able to manage multiple users at once, however this feature is currently not -implemented in the SkypeProxy protocol. Depeding on the user's needs, this -can be implemented, most of the code for this is already there. - -For usage with Miranda IM, a special plugin version was written, which -implementes the layer as a plugin so that it can be loaded into Miranda -and the user doesn't have to run the proxy application seperately. -The plugin version also has the advantage that it is able to communicate -with the Skype plugin directly. - -How does it work ----------------- - -Is described in the preamble, this is just a drop-in replacement for the -communication end point of the Skype API. -The classical communication model for Skype API is: - -[ Skype servers ] <--> [ Skype App ] <--> [ Plugin ] - -The SkypeProxy communication model is: - -[ Skype servers ] <--> [ Skype App ] <--> [ SkypeProxy ] <--> [ Plugin ] - -Now with this Drop-in replacement the communication model is: - -[ Skype servers ] <--> [ imo.im ] <--> [ SkypeProxy ] <--> [ Plugin ] - -The application communicates via a socket connection on Port 1402, like -SkypeProxy does. It uses the imo.im services to connect to the Skype network. - -You also have the possibility to emulate the Skype WIN32-API so that -any plugin can communicate with this application instead of Skype. - -As said, there are 3 connection points to communicate with the plugin: - - WIN32 Skype API via Windowmessages, emulates the real Skype API for - compatibility with any Skype plugin. (Windows) - - Socket communication layer via TCP/IP. (Windows/Unix) - - Internal plugin communcation layer used by the Miranda IM plugin to - communicate with Skype plugin versions starting with 0.0.0.46 - (Windows, Miranda IM plugin only) - -How to compile --------------- -On Unix type systems, just extract this package and type "make". -After compiling, you will find imo2sproxy in the bin/ directory - -On Windows systems, you will find Visual C 6 project files in the -msvc/ subdirectory. -You have Makefiles available for the appropriate modules: -imoskype.mak - Compiles the imo2sproxy standalone executable -imoproxy.mak - Compiles the Miranda IM Plugin - -There are 4 available Targets: -Win32 Release - 32bit Windows Release version -Win64 Release - 64bit Windows Release version -Win32 Debug - 32bit Windows Debug version -Win64 Debug - 64bit Windows Debug version - -i.e.: -nmake -f imoskype.mak CFG="Win32 Release" - -Requirements ------------- -On Linux, libcurl Libraries and the pthread library for threading -are needed in order to get this to work. -You can download CURL on http://curl.haxx.se/download.html -To install, just use libtool as usual. - -On Windows, WININET is required which should be shipped with -Internet Explorer. So on an average Windows System, you shouldn't -need to install any additional libraries. -Please note, that libcurl IS NO LONGER NEEDED on Windows. - -How to use the commandline version ----------------------------------- -Find the precompiled binaries in the bin/ subdirectory. - -imo2sproxy [-d] [-v [-l ]] [-t] [-i] - [-m] [-h ] [-p ] - --v - Verbose mode, log commands to console --l - Set logfile to redirect verbose log to. --d - Daemonize (detach from console) --i - Use interactive mode (starts imo.im flash app upon call) --t - Ignore server timestamp and use current time for messages --h - Bind to a specific IP, not to all interfaces (default) --p - Bind to another port (default: 1401) --m - Specify connection mode to use: - s Socket mode (SkypeProxy protocol) [default] - a Skype API Emulation via Window messages (real Skype API) - --ma is only available on Windows systems. - -As there is currently only a single-user implementation of this application, you - need to start imo2sproxy with your Skype username and password as parameters. - -Example for using the socket protocol: -imo2sproxy -d -h 127.0.0.1 myuser mypass - -As soon as the imo2sproxy is running, setup your Skype Plugin to use the -SkypeProxy at the machine you are running imo2sproxy on. -If you are running imo2sproxy locally, enter 127.0.0.1 as IP address. -After setting the SkypeProxy, you have to restart Miranda IM. - -If all works well, you should now be able to use Skype via imo.im. -If it doesn't work, you can use the -v parameter to see what's going on and -if the connection works. - -If it all works well, you can also install imo2sproxy on your machine -as a service using srvany. - -Example for using the Skype API Emulation (win32 only): -imo2sproxy.exe -d -ma myuser mypass - -As soon as the imo2sproxy is running, just try to use your Skype plugin and -see if it connects to the imo2sproxy locally. -Of course, if you have the Skype application installed, you mustn't run -it concurrently with the plugin with this configuration. - -How to use the Miranda plugin ------------------------------ -Copy the imoproxy.dll file to your Miranda Plugins-directory. -As the name starts with i and the the Skype plugin name starts with s, -the imoproxy.dll module is loaded prior to the Skype-Plugin DLL which -is important to work properly if you are using the socket method. - -For older versions of the Skype plugin (prior to 0.0.0.46, which is -currently still beta), you should use the socket communication method: -Configure the plugin DLL in the Options dialog Network/Skype Imoproxy. -Bind to address 127.0.0.1, Port 1401 -Make sure that the Skype Proxy settings in your Skype plugin are the -same. The Skypeproxy-Plugin tries to take care of that. -Enter your Username and Password, set the appropriate options and press -OK. The Skypeproxy-plugin restarts itself. Try to reconnect Skype plugin -and see if it works. -The plugin is still experimental and may contain some bugs or stability -problems, so use with care. It may be harder to hunt down bugs with this -Plugin as its running as Miranda plugin and the only logging facility is -a logfile. So if you want to hunt down bugs, you may be better off with -using the standalone version, however the plugin is a start to make the -use of imo2sproxy easier. Feel free to improve the plugin. - -For Skype plugin versions starting with 0.0.0.46, there is an internal -plugin link facility which makes it easier for the user to setup. -Bascially this should work out of the box, just enter your username and -password in the options dialog and ensute that the internal plugin -link service is active. -It will then automatically register to the Skype plugin. - -Module structure ----------------- - -For the structure of the code-modules, please refer to the -structure.txt document. - -SkypeProxy protocol -------------------- - -Plase download the sourcecode of skypeproxy.c of Miranda IM Skype plugin, it's -all well documented in the .c file. Basically the protocol just consists of: - -[UCHAR: number of bytes to send/receive][ Data] - -for every line sent or received. - -Contact -------- -Feel free to contact me regarding this project or if you wish to implement -SkypeProxy protocol in your own Skype-plugin implementation. - -leecher@dose.0wnz.at - - -Vienna, 10/07/2009 diff --git a/!NotAdopted/IMO2sProxy/bin/setupimo.bat b/!NotAdopted/IMO2sProxy/bin/setupimo.bat deleted file mode 100644 index 9c765c6479..0000000000 --- a/!NotAdopted/IMO2sProxy/bin/setupimo.bat +++ /dev/null @@ -1,24 +0,0 @@ -@echo off -SET /P USER=Skype username: -IF "%USER%"=="" ( - echo Username is mandatory, aborting. - GOTO fini -) -SET /P PASS=Skype password: -IF "%PASS%"=="" ( - echo Password is mandatory, aborting. - GOTO fini -) -SET /P IP=Bind to IP [0.0.0.0]: -SET /P PORT=Bind to Port [1401]: -SET /P DAEM=Do you want to daemonize [N]: -IF /I "%DAEM%" NEQ "Y" SET /P VERB=Do you want verbose command output [N]: -IF /I "%DAEM%"=="Y" SET CMDLINE=%CMDLINE% -d -IF /I "%VERB%"=="Y" SET CMDLINE=%CMDLINE% -v -IF NOT "%IP%"=="" SET CMDLINE=%CMDLINE% -h %IP% -IF NOT "%PORT%"=="" SET CMDLINE=%CMDLINE% -p %PORT% -SET CMDLINE=%CMDLINE% %USER% %PASS% -echo imo2sproxy %CMDLINE% >startimo.bat -echo startimo.bat created. -:fini -pause diff --git a/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsp b/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsp deleted file mode 100644 index d607233428..0000000000 --- a/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsp +++ /dev/null @@ -1,248 +0,0 @@ -# Microsoft Developer Studio Project File - Name="imoproxy" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** NICHT BEARBEITEN ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=imoproxy - Win32 Debug -!MESSAGE Dies ist kein gьltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE -!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fьhren Sie den Befehl -!MESSAGE -!MESSAGE NMAKE /f "imoproxy.mak". -!MESSAGE -!MESSAGE Sie kцnnen beim Ausfьhren von NMAKE eine Konfiguration angeben -!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: -!MESSAGE -!MESSAGE NMAKE /f "imoproxy.mak" CFG="imoproxy - Win32 Debug" -!MESSAGE -!MESSAGE Fьr die Konfiguration stehen zur Auswahl: -!MESSAGE -!MESSAGE "imoproxy - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library") -!MESSAGE "imoproxy - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=xicl6.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "imoproxy - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\src\common" /I "..\src\imolib" /I "..\src\imo2skype" /I "F:\miranda09_src\miranda" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /FR /YX /FD /c -# SUBTRACT CPP /X -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0xc07 /d "NDEBUG" -# ADD RSC /l 0xc07 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 - -!ELSEIF "$(CFG)" == "imoproxy - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\src\common" /I "..\src\imolib" /I "..\src\imo2skype" /I "F:\miranda09_src\miranda" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /FR /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0xc07 /d "_DEBUG" -# ADD RSC /l 0xc07 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"F:\miranda09_src\miranda\bin\debug\Plugins\imoproxy.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "imoproxy - Win32 Release" -# Name "imoproxy - Win32 Debug" -# Begin Group "Quellcodedateien" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\src\imo2skype\avatarlist.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\buddylist.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\callqueue.c -# End Source File -# Begin Source File - -SOURCE=..\src\common\cJSON.c -# End Source File -# Begin Source File - -SOURCE=..\src\common\fifo.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\imo2skypeapi.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\imo2sproxy.c -# End Source File -# Begin Source File - -SOURCE=..\src\imolib\imo_request.c -# End Source File -# Begin Source File - -SOURCE=..\src\imolib\imo_skype.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\miranda\imoproxy.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\miranda\io_layer_netlib.c -# End Source File -# Begin Source File - -SOURCE=..\src\imolib\io_layer_win32.c -# End Source File -# Begin Source File - -SOURCE=..\src\common\memlist.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\msgqueue.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\queue.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\miranda\skypepluginlink.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\socksproxy.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\w32browser.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\w32skypeemu.c -# End Source File -# End Group -# Begin Group "Header-Dateien" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\src\imo2skype\buddylist.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\callqueue.h -# End Source File -# Begin Source File - -SOURCE=..\src\common\cJSON.h -# End Source File -# Begin Source File - -SOURCE=..\src\common\fifo.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\imo2skypeapi.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\imo2sproxy.h -# End Source File -# Begin Source File - -SOURCE=..\src\imolib\imo_request.h -# End Source File -# Begin Source File - -SOURCE=..\src\imolib\imo_skype.h -# End Source File -# Begin Source File - -SOURCE=..\src\imolib\io_layer.h -# End Source File -# Begin Source File - -SOURCE=..\src\common\memlist.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\msgqueue.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\queue.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\miranda\skypepluginlink.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\socksproxy.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\w32browser.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\w32skypeemu.h -# End Source File -# End Group -# Begin Group "Ressourcendateien" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# Begin Source File - -SOURCE=..\src\imo2skype\miranda\res.rc -# End Source File -# End Group -# End Target -# End Project diff --git a/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsw b/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsw deleted file mode 100644 index 2d4fb49ab6..0000000000 --- a/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsw +++ /dev/null @@ -1,41 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELЦSCHT WERDEN! - -############################################################################### - -Project: "imoproxy"=.\imoproxy.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "imoskype"=.\imoskype.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/!NotAdopted/IMO2sProxy/msvc/imoproxy.mak b/!NotAdopted/IMO2sProxy/msvc/imoproxy.mak deleted file mode 100644 index 04b4371268..0000000000 --- a/!NotAdopted/IMO2sProxy/msvc/imoproxy.mak +++ /dev/null @@ -1,221 +0,0 @@ -!IF "$(CFG)" == "" -CFG=Win32 Debug -!MESSAGE Keine Konfiguration angegeben. Win32 Debug wird als Standard verwendet. -!ENDIF - -!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug" && "$(CFG)" != "Win64 Release" && "$(CFG)" != "Win64 Debug" -!MESSAGE Ungьltige Konfiguration "$(CFG)" angegeben. -!MESSAGE Sie kцnnen beim Ausfьhren von NMAKE eine Konfiguration angeben -!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: -!MESSAGE -!MESSAGE NMAKE /f "imoproxy.mak" CFG="Win32 Debug" -!MESSAGE -!MESSAGE Fьr die Konfiguration stehen zur Auswahl: -!MESSAGE -!MESSAGE "Win32 Release" -!MESSAGE "Win32 Debug" -!MESSAGE "Win64 Release" -!MESSAGE "Win64 Debug" -!MESSAGE -!ERROR Eine ungьltige Konfiguration wurde angegeben. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe -LINK32=link.exe - -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /pdb:"$(INTDIR)\imoproxy.pdb" /out:"$(OUTDIR)\imoproxy.dll" /implib:"$(INTDIR)\imoproxy.lib" -INCLUDES=/I "../src/common" /I "../src/imo2skype" /I "../src/imolib" /I "F:\miranda09_src\miranda" - -!IF "$(CFG)" == "Win64 Release" -OUTDIR=..\bin64 -INTDIR=.\Release64 -CPP_PROJ=/nologo /MT /W3 /O2 $(INCLUDES) /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /Fp"$(INTDIR)\imoproxy.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c -LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 -RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\res.res" /d "NDEBUG" -!ELSEIF "$(CFG)" == "Win32 Release" -OUTDIR=..\bin -INTDIR=.\Release -CPP_PROJ=/nologo /MT /W3 /O2 $(INCLUDES) /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /Fp"$(INTDIR)\imoproxy.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c -LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 -RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\res.res" /d "NDEBUG" -!ELSEIF "$(CFG)" == "Win64 Debug" -OUTDIR=.\Debug64 -INTDIR=$(OUTDIR) -CPP_PROJ=/nologo /MTd /W3 /Gm /ZI /Od $(INCLUDES) /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\imoproxy.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c -LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 -RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\res.res" /d "_DEBUG" -!ELSEIF "$(CFG)" == "Win32 Debug" -OUTDIR=.\Debug -INTDIR=$(OUTDIR) -CPP_PROJ=/nologo /MTd /W3 /Gm /ZI /Od $(INCLUDES) /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\imoproxy.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c -LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 -RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\res.res" /d "_DEBUG" -!ENDIF - -LINK32_OBJS= \ - "$(INTDIR)\avatarlist.obj" \ - "$(INTDIR)\buddylist.obj" \ - "$(INTDIR)\callqueue.obj" \ - "$(INTDIR)\cJSON.obj" \ - "$(INTDIR)\fifo.obj" \ - "$(INTDIR)\imo2skypeapi.obj" \ - "$(INTDIR)\imo2sproxy.obj" \ - "$(INTDIR)\imo_request.obj" \ - "$(INTDIR)\imo_skype.obj" \ - "$(INTDIR)\imoproxy.obj" \ - "$(INTDIR)\io_layer_win32.obj" \ - "$(INTDIR)\io_layer_netlib.obj" \ - "$(INTDIR)\memlist.obj" \ - "$(INTDIR)\msgqueue.obj" \ - "$(INTDIR)\queue.obj" \ - "$(INTDIR)\socksproxy.obj" \ - "$(INTDIR)\w32browser.obj" \ - "$(INTDIR)\w32skypeemu.obj" \ - "$(INTDIR)\res.res" \ - "$(INTDIR)\skypepluginlink.obj" - - -ALL : "$(OUTDIR)\imoproxy.dll" - - -CLEAN : - -@erase "$(INTDIR)\avatarlist.obj" - -@erase "$(INTDIR)\buddylist.obj" - -@erase "$(INTDIR)\callqueue.obj" - -@erase "$(INTDIR)\cJSON.obj" - -@erase "$(INTDIR)\fifo.obj" - -@erase "$(INTDIR)\imo2skypeapi.obj" - -@erase "$(INTDIR)\imo2sproxy.obj" - -@erase "$(INTDIR)\imo_request.obj" - -@erase "$(INTDIR)\imo_skype.obj" - -@erase "$(INTDIR)\imoproxy.obj" - -@erase "$(INTDIR)\io_layer_win32.obj" - -@erase "$(INTDIR)\io_layer_netlib.obj" - -@erase "$(INTDIR)\memlist.obj" - -@erase "$(INTDIR)\msgqueue.obj" - -@erase "$(INTDIR)\queue.obj" - -@erase "$(INTDIR)\res.res" - -@erase "$(INTDIR)\skypepluginlink.obj" - -@erase "$(INTDIR)\socksproxy.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\w32browser.obj" - -@erase "$(INTDIR)\w32skypeemu.obj" - -@erase "$(OUTDIR)\imoproxy.dll" - -@erase "$(OUTDIR)\imoproxy.exp" - -@erase "$(OUTDIR)\imoproxy.lib" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -"$(OUTDIR)\imoproxy.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("imoproxy.dep") -!INCLUDE "imoproxy.dep" -!ELSE -!MESSAGE Warning: cannot find "imoproxy.dep" -!ENDIF -!ENDIF - - -SOURCE=..\src\imo2skype\avatarlist.c -"$(INTDIR)\avatarlist.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\buddylist.c -"$(INTDIR)\buddylist.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\callqueue.c -"$(INTDIR)\callqueue.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\common\cJSON.c -"$(INTDIR)\cJSON.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\common\fifo.c -"$(INTDIR)\fifo.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\imo2skypeapi.c -"$(INTDIR)\imo2skypeapi.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\imo2sproxy.c -"$(INTDIR)\imo2sproxy.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imolib\imo_request.c -"$(INTDIR)\imo_request.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imolib\imo_skype.c -"$(INTDIR)\imo_skype.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\miranda\imoproxy.c -"$(INTDIR)\imoproxy.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imolib\io_layer_win32.c -"$(INTDIR)\io_layer_win32.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\common\memlist.c -"$(INTDIR)\memlist.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\msgqueue.c -"$(INTDIR)\msgqueue.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\queue.c -"$(INTDIR)\queue.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\miranda\skypepluginlink.c -"$(INTDIR)\skypepluginlink.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\miranda\io_layer_netlib.c -"$(INTDIR)\io_layer_netlib.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\socksproxy.c -"$(INTDIR)\socksproxy.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\w32browser.c -"$(INTDIR)\w32browser.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\w32skypeemu.c -"$(INTDIR)\w32skypeemu.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=..\src\imo2skype\miranda\res.rc -"$(INTDIR)\res.res" : $(SOURCE) "$(INTDIR)" - $(RSC) /l 0xc07 /fo"$(INTDIR)\res.res" /i "..\src\imo2skype\miranda" /d "NDEBUG" $(SOURCE) - diff --git a/!NotAdopted/IMO2sProxy/msvc/imoskype.dsp b/!NotAdopted/IMO2sProxy/msvc/imoskype.dsp deleted file mode 100644 index 00d324b5b8..0000000000 --- a/!NotAdopted/IMO2sProxy/msvc/imoskype.dsp +++ /dev/null @@ -1,230 +0,0 @@ -# Microsoft Developer Studio Project File - Name="imoskype" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** NICHT BEARBEITEN ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=imoskype - Win32 Debug -!MESSAGE Dies ist kein gьltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE -!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fьhren Sie den Befehl -!MESSAGE -!MESSAGE NMAKE /f "imoskype.mak". -!MESSAGE -!MESSAGE Sie kцnnen beim Ausfьhren von NMAKE eine Konfiguration angeben -!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: -!MESSAGE -!MESSAGE NMAKE /f "imoskype.mak" CFG="imoskype - Win32 Debug" -!MESSAGE -!MESSAGE Fьr die Konfiguration stehen zur Auswahl: -!MESSAGE -!MESSAGE "imoskype - Win32 Release" (basierend auf "Win32 (x86) Console Application") -!MESSAGE "imoskype - Win32 Debug" (basierend auf "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=xicl6.exe -RSC=rc.exe - -!IF "$(CFG)" == "imoskype - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "../src/common" /I "../src/imo2skype" /I "../src/imolib" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c -# ADD BASE RSC /l 0xc07 /d "NDEBUG" -# ADD RSC /l 0xc07 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /out:"../bin/imo2sproxy.exe" - -!ELSEIF "$(CFG)" == "imoskype - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../src/common" /I "../src/imo2skype" /I "../src/imolib" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0xc07 /d "_DEBUG" -# ADD RSC /l 0xc07 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/imo2sproxy.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "imoskype - Win32 Release" -# Name "imoskype - Win32 Debug" -# Begin Group "Quellcodedateien" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=\temp\debug\imo.im\src\imo2skype\avatarlist.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\buddylist.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\callqueue.c -# End Source File -# Begin Source File - -SOURCE=..\src\common\cJSON.c -# End Source File -# Begin Source File - -SOURCE=..\src\common\fifo.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\imo2skypeapi.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\imo2sproxy.c -# End Source File -# Begin Source File - -SOURCE=..\src\imolib\imo_request.c -# End Source File -# Begin Source File - -SOURCE=..\src\imolib\imo_skype.c -# End Source File -# Begin Source File - -SOURCE=..\src\imolib\io_layer_win32.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\main.c -# End Source File -# Begin Source File - -SOURCE=..\src\common\memlist.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\msgqueue.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\queue.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\socksproxy.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\w32browser.c -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\w32skypeemu.c -# End Source File -# End Group -# Begin Group "Header-Dateien" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=\temp\debug\imo.im\src\imo2skype\avatarlist.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\buddylist.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\callqueue.h -# End Source File -# Begin Source File - -SOURCE=..\src\common\cJSON.h -# End Source File -# Begin Source File - -SOURCE=..\src\common\fifo.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\imo2skypeapi.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\imo2sproxy.h -# End Source File -# Begin Source File - -SOURCE=..\src\imolib\imo_request.h -# End Source File -# Begin Source File - -SOURCE=..\src\imolib\imo_skype.h -# End Source File -# Begin Source File - -SOURCE=..\src\imolib\io_layer.h -# End Source File -# Begin Source File - -SOURCE=..\src\common\memlist.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\msgqueue.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\queue.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\socksproxy.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\w32browser.h -# End Source File -# Begin Source File - -SOURCE=..\src\imo2skype\w32skypeemu.h -# End Source File -# End Group -# Begin Group "Ressourcendateien" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/!NotAdopted/IMO2sProxy/msvc/imoskype.dsw b/!NotAdopted/IMO2sProxy/msvc/imoskype.dsw deleted file mode 100644 index a4c512f5e0..0000000000 --- a/!NotAdopted/IMO2sProxy/msvc/imoskype.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELЦSCHT WERDEN! - -############################################################################### - -Project: "imoskype"=.\imoskype.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/!NotAdopted/IMO2sProxy/msvc/imoskype.mak b/!NotAdopted/IMO2sProxy/msvc/imoskype.mak deleted file mode 100644 index be7b29f013..0000000000 --- a/!NotAdopted/IMO2sProxy/msvc/imoskype.mak +++ /dev/null @@ -1,193 +0,0 @@ -!IF "$(CFG)" == "" -CFG=Win32 Debug -!MESSAGE Keine Konfiguration angegeben. Win32 Debug wird als Standard verwendet. -!ENDIF - -!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug" && "$(CFG)" != "Win64 Release" && "$(CFG)" != "Win64 Debug" -!MESSAGE UngЃltige Konfiguration "$(CFG)" angegeben. -!MESSAGE Sie k”nnen beim AusfЃhren von NMAKE eine Konfiguration angeben -!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: -!MESSAGE -!MESSAGE NMAKE /f "imoskype.mak" CFG="Win32 Debug" -!MESSAGE -!MESSAGE FЃr die Konfiguration stehen zur Auswahl: -!MESSAGE -!MESSAGE "Win32 Release" -!MESSAGE "Win32 Debug" -!MESSAGE "Win64 Release" -!MESSAGE "Win64 Debug" -!MESSAGE -!ERROR Eine ungЃltige Konfiguration wurde angegeben. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -CPP=cl.exe -RSC=rc.exe -LINK32=link.exe - -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ws2_32.lib /nologo /subsystem:console /pdb:"$(INTDIR)\imo2sproxy.pdb" /out:"$(OUTDIR)/imo2sproxy.exe" -INCLUDES=/I "../src/common" /I "../src/imo2skype" /I "../src/imolib" - -!IF "$(CFG)" == "Win64 Release" -OUTDIR=..\bin64 -INTDIR=.\Release64 -CPP_PROJ=/nologo /MT /W3 /O2 $(INCLUDES) /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\imoskype.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c -LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no -!ELSEIF "$(CFG)" == "Win32 Release" -OUTDIR=..\bin -INTDIR=.\Release -CPP_PROJ=/nologo /MT /W3 /O2 $(INCLUDES) /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\imoskype.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c -LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no -!ELSEIF "$(CFG)" == "Win64 Debug" -OUTDIR=.\Debug64 -INTDIR=$(OUTDIR) -CPP_PROJ=/nologo /MTd /W3 /Gm /ZI /Od $(INCLUDES) /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\imoskype.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c -LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept -!ELSEIF "$(CFG)" == "Win32 Debug" -OUTDIR=.\Debug -INTDIR=$(OUTDIR) -CPP_PROJ=/nologo /MTd /W3 /Gm /ZI /Od $(INCLUDES) /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\imoskype.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c -LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept -!ENDIF - -LINK32_OBJS= \ - "$(INTDIR)\avatarlist.obj" \ - "$(INTDIR)\buddylist.obj" \ - "$(INTDIR)\callqueue.obj" \ - "$(INTDIR)\cJSON.obj" \ - "$(INTDIR)\fifo.obj" \ - "$(INTDIR)\imo2skypeapi.obj" \ - "$(INTDIR)\imo2sproxy.obj" \ - "$(INTDIR)\imo_request.obj" \ - "$(INTDIR)\imo_skype.obj" \ - "$(INTDIR)\io_layer_win32.obj" \ - "$(INTDIR)\main.obj" \ - "$(INTDIR)\memlist.obj" \ - "$(INTDIR)\msgqueue.obj" \ - "$(INTDIR)\queue.obj" \ - "$(INTDIR)\socksproxy.obj" \ - "$(INTDIR)\w32browser.obj" \ - "$(INTDIR)\w32skypeemu.obj" - -ALL : "$(OUTDIR)\imo2sproxy.exe" - -CLEAN : - -@erase "$(INTDIR)\avatarlist.obj" - -@erase "$(INTDIR)\buddylist.obj" - -@erase "$(INTDIR)\callqueue.obj" - -@erase "$(INTDIR)\cJSON.obj" - -@erase "$(INTDIR)\fifo.obj" - -@erase "$(INTDIR)\imo2skypeapi.obj" - -@erase "$(INTDIR)\imo2sproxy.obj" - -@erase "$(INTDIR)\imo_request.obj" - -@erase "$(INTDIR)\imo_skype.obj" - -@erase "$(INTDIR)\io_layer_win32.obj" - -@erase "$(INTDIR)\main.obj" - -@erase "$(INTDIR)\memlist.obj" - -@erase "$(INTDIR)\msgqueue.obj" - -@erase "$(INTDIR)\queue.obj" - -@erase "$(INTDIR)\socksproxy.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\w32browser.obj" - -@erase "$(INTDIR)\w32skypeemu.obj" - -@erase "$(INTDIR)\imo2sproxy.ilk" - -@erase "$(INTDIR)\imo2sproxy.pdb" - -@erase "$(OUTDIR)\imo2sproxy.exe" - - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -"$(OUTDIR)\imo2sproxy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("imoskype.dep") -!INCLUDE "imoskype.dep" -!ELSE -!MESSAGE Warning: cannot find "imoskype.dep" -!ENDIF -!ENDIF - - -SOURCE=..\src\imo2skype\avatarlist.c -"$(INTDIR)\avatarlist.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\buddylist.c -"$(INTDIR)\buddylist.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\callqueue.c -"$(INTDIR)\callqueue.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\common\cJSON.c -"$(INTDIR)\cJSON.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\common\fifo.c -"$(INTDIR)\fifo.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\imo2skypeapi.c -"$(INTDIR)\imo2skypeapi.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\imo2sproxy.c -"$(INTDIR)\imo2sproxy.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imolib\imo_request.c -"$(INTDIR)\imo_request.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imolib\imo_skype.c -"$(INTDIR)\imo_skype.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imolib\io_layer_win32.c -"$(INTDIR)\io_layer_win32.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\main.c -"$(INTDIR)\main.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\common\memlist.c -"$(INTDIR)\memlist.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\msgqueue.c -"$(INTDIR)\msgqueue.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\queue.c -"$(INTDIR)\queue.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\socksproxy.c -"$(INTDIR)\socksproxy.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\w32browser.c -"$(INTDIR)\w32browser.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - -SOURCE=..\src\imo2skype\w32skypeemu.c -"$(INTDIR)\w32skypeemu.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - diff --git a/!NotAdopted/IMO2sProxy/msvc/make.bat b/!NotAdopted/IMO2sProxy/msvc/make.bat deleted file mode 100644 index a974f238ab..0000000000 --- a/!NotAdopted/IMO2sProxy/msvc/make.bat +++ /dev/null @@ -1,2 +0,0 @@ -cmd /c make_w32 -cmd /c make_w64 diff --git a/!NotAdopted/IMO2sProxy/msvc/make_w32.bat b/!NotAdopted/IMO2sProxy/msvc/make_w32.bat deleted file mode 100644 index e5f7eafd2f..0000000000 --- a/!NotAdopted/IMO2sProxy/msvc/make_w32.bat +++ /dev/null @@ -1,7 +0,0 @@ -call "F:\Programme\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT" -nmake -f imoproxy.mak CFG="Win32 Release" clean -nmake -f imoskype.mak CFG="Win32 Release" clean -nmake -f imoproxy.mak CFG="Win32 Release" -nmake -f imoskype.mak CFG="Win32 Release" -nmake -f imoproxy.mak CFG="Win32 Debug" -nmake -f imoskype.mak CFG="Win32 Debug" diff --git a/!NotAdopted/IMO2sProxy/msvc/make_w64.bat b/!NotAdopted/IMO2sProxy/msvc/make_w64.bat deleted file mode 100644 index a97d4a2d7d..0000000000 --- a/!NotAdopted/IMO2sProxy/msvc/make_w64.bat +++ /dev/null @@ -1,5 +0,0 @@ -call f:\PlatformSDK\SetEnv /X64 /RETAIL -nmake -f imoproxy.mak CFG="Win64 Release" clean -nmake -f imoskype.mak CFG="Win64 Release" clean -nmake -f imoproxy.mak CFG="Win64 Release" -nmake -f imoskype.mak CFG="Win64 Release" diff --git a/!NotAdopted/IMO2sProxy/src/common/cJSON.c b/!NotAdopted/IMO2sProxy/src/common/cJSON.c deleted file mode 100644 index 72f35f6117..0000000000 --- a/!NotAdopted/IMO2sProxy/src/common/cJSON.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - Copyright (c) 2009 Dave Gamble - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -// cJSON -// JSON parser in C. - -#include -#include -#include -#include -#include -#include "cJSON.h" -#ifdef WIN32 -#define strcasecmp stricmp -#endif - -// Internal constructor. -static cJSON *cJSON_New_Item() { return (cJSON*)calloc(sizeof(cJSON),1); } - -// Delete a cJSON structure. -void cJSON_Delete(cJSON *c) -{ - cJSON *next; - while (c) - { - next=c->next; - if (c->child) cJSON_Delete(c->child); - if (c->valuestring) free(c->valuestring); - if (c->string) free(c->string); - free(c); - c=next; - } -} - -// Parse the input text to generate a number, and populate the result into item. -static const char *parse_number(cJSON *item,const char *num) -{ - double n=0,sign=1,scale=0;int subscale=0,signsubscale=1; - - // Could use sscanf for this? - if (*num=='-') sign=-1,num++; // Has sign? - if (*num=='0') num++; // is zero - if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); // Number? - if (*num=='.') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} // Fractional part? - if (*num=='e' || *num=='E') // Exponent? - { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; // With sign? - while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); // Number? - } - - n=sign*n*pow(10.0,(scale+subscale*signsubscale)); // number = +/- number.fraction * 10^+/- exponent - - item->valuedouble=n; - item->valueint=(int)n; - item->type=cJSON_Number; - return num; -} - -// Render the number nicely from the given item into a string. -static char *print_number(cJSON *item) -{ - char *str; - double d=item->valuedouble; - if (fabs(((double)item->valueint)-d)<=DBL_EPSILON) - { - str=malloc(21); // 2^64+1 can be represented in 21 chars. - sprintf(str,"%d",item->valueint); - } - else - { - str=malloc(64); // This is a nice tradeoff. - if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d); - else sprintf(str,"%f",d); - } - return str; -} - -// Parse the input text into an unescaped cstring, and populate item. -static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; -static const char *parse_string(cJSON *item,const char *str) -{ - const unsigned char *ptr=str+1; - unsigned char *ptr2; - char *out;int len=0;unsigned uc; - if (*str!='\"') return 0; // not a string! - - while (*ptr!='\"' && *ptr>31 && ++len) if (*ptr++ == '\\') ptr++; // Skip escaped quotes. - - out=(char*)malloc(len+1); // This is how long we need for the string, roughly. - - ptr=str+1;ptr2=out; - while (*ptr!='\"' && *ptr>31) - { - if (*ptr!='\\') *ptr2++=*ptr++; - else - { - ptr++; - switch (*ptr) - { - case 'b': *ptr2++='\b'; break; - case 'f': *ptr2++='\f'; break; - case 'n': *ptr2++='\n'; break; - case 'r': *ptr2++='\r'; break; - case 't': *ptr2++='\t'; break; - case 'u': // transcode utf16 to utf8. DOES NOT SUPPORT SURROGATE PAIRS CORRECTLY. - sscanf(ptr+1,"%4x",&uc); // get the unicode char. - len=3;if (uc<0x80) len=1;else if (uc<0x800) len=2;ptr2+=len; - - switch (len) { - case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; - case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; - case 1: *--ptr2 =(uc | firstByteMark[len]); - } - ptr2+=len;ptr+=4; - break; - default: *ptr2++=*ptr; break; - } - ptr++; - } - } - *ptr2=0; - if (*ptr=='\"') ptr++; - item->valuestring=out; - item->type=cJSON_String; - return ptr; -} - -// Render the cstring provided to an escaped version that can be printed. -static char *print_string_ptr(const char *str) -{ - const unsigned char *ptr; unsigned char *ptr2,*out;int len=0; - - ptr=str;while (*ptr && ++len) {if (*ptr<32 || *ptr=='\"' || *ptr=='\\') len++;ptr++;} - - out=(char*)malloc(len+3); - ptr2=out;ptr=str; - *ptr2++='\"'; - while (*ptr) - { - if (*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++; - else - { - *ptr2++='\\'; - switch (*ptr++) - { - case '\\': *ptr2++='\\'; break; - case '\"': *ptr2++='\"'; break; - case '\b': *ptr2++='b'; break; - case '\f': *ptr2++='f'; break; - case '\n': *ptr2++='n'; break; - case '\r': *ptr2++='r'; break; - case '\t': *ptr2++='t'; break; - default: ptr2--; break; // eviscerate with prejudice. - } - } - } - *ptr2++='\"';*ptr2++=0; - return out; -} -// Invote print_string_ptr (which is useful) on an item. -static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);} - -// Predeclare these prototypes. -static const char *parse_value(cJSON *item,const char *value); -static char *print_value(cJSON *item,int depth); -static const char *parse_array(cJSON *item,const char *value); -static char *print_array(cJSON *item,int depth); -static const char *parse_object(cJSON *item,const char *value); -static char *print_object(cJSON *item,int depth); - -// Parse an object - create a new root, and populate. -cJSON *cJSON_Parse(const char *value) {cJSON *c=cJSON_New_Item();parse_value(c,value);return c;} -// Render a cJSON item/entity/structure to text. -char *cJSON_Print(cJSON *item) {return print_value(item,0);} - -// Parser core - when encountering text, process appropriately. -static const char *parse_value(cJSON *item,const char *value) -{ - if (!value) return 0; // Fail on null. - if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; } - if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; } - if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; } - if (*value=='\"') { return parse_string(item,value); } - if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); } - if (*value=='[') { return parse_array(item,value); } - if (*value=='{') { return parse_object(item,value); } - - return 0; // failure. -} - -// Render a value to text. -static char *print_value(cJSON *item,int depth) -{ - char *out=0; - switch (item->type) - { - case cJSON_NULL: out=strdup("null"); break; - case cJSON_False: out=strdup("false");break; - case cJSON_True: out=strdup("true"); break; - case cJSON_Number: out=print_number(item);break; - case cJSON_String: out=print_string(item);break; - case cJSON_Array: out=print_array(item,depth);break; - case cJSON_Object: out=print_object(item,depth);break; - } - return out; -} - -// Utility to jump whitespace and cr/lf -static const char *skip(const char *in) {while (in && *in<=32) in++; return in;} - -// Build an array from input text. -static const char *parse_array(cJSON *item,const char *value) -{ - cJSON *child; - if (*value!='[') return 0; // not an array! - - item->type=cJSON_Array; - value=skip(value+1); - if (*value==']') return value+1; // empty array. - - item->child=child=cJSON_New_Item(); - value=skip(parse_value(child,skip(value))); // skip any spacing, get the value. - - while (*value==',') - { - cJSON *new_item; - if (!(new_item=cJSON_New_Item())) return 0; // memory fail - child->next=new_item;new_item->prev=child;child=new_item; - value=skip(parse_value(child,skip(value+1))); - } - - if (*value==']') return value+1; // end of array - return 0; // malformed. -} - -// Render an array to text -static char *print_array(cJSON *item,int depth) -{ - char *out,*ptr,*ret;int len=5; - cJSON *child=item->child; - - out=malloc(len);*out='['; - ptr=out+1;*ptr=0; - while (child) - { - ret=print_value(child,depth+1); - if (!ret) {free(out);return 0;} // Check for failure! - len+=strlen(ret)+3; - out=realloc(out,len); - ptr=out+strlen(out); - ptr+=sprintf(ptr,"%s",ret); - if (child->next) {*ptr++=',';*ptr++=' ';*ptr=0;} - child=child->next; - free(ret); - } - *ptr++=']';*ptr++=0; - return out; -} - -// Build an object from the text. -static const char *parse_object(cJSON *item,const char *value) -{ - cJSON *child; - if (*value!='{') return 0; // not an object! - - item->type=cJSON_Object; - value=skip(value+1); - if (*value=='}') return value+1; // empty array. - - item->child=child=cJSON_New_Item(); - value=skip(parse_string(child,skip(value))); - child->string=child->valuestring;child->valuestring=0; - if (*value!=':') return 0; // fail! - value=skip(parse_value(child,skip(value+1))); // skip any spacing, get the value. - - while (*value==',') - { - cJSON *new_item; - if (!(new_item=cJSON_New_Item())) return 0; // memory fail - child->next=new_item;new_item->prev=child;child=new_item; - value=skip(parse_string(child,skip(value+1))); - child->string=child->valuestring;child->valuestring=0; - if (*value!=':') return 0; // fail! - value=skip(parse_value(child,skip(value+1))); // skip any spacing, get the value. - } - - if (*value=='}') return value+1; // end of array - return 0; // malformed. -} - -// Render an object to text. -static char *print_object(cJSON *item,int depth) -{ - char *out,*ptr,*ret,*str;int len=7;//,i; - cJSON *child=item->child; - - depth++;out=malloc(len+depth);*out='{'; - ptr=out+1;*ptr++=' ';*ptr=0; - while (child) - { - str=print_string_ptr(child->string); - if (!str) {free(out);return 0;} - ret=print_value(child,depth); - if (!ret) {free(out);return 0;} // Check for failure! - len+=strlen(ret)+strlen(str)+4+depth; - out=realloc(out,len); - ptr=out+strlen(out); -// for (i=0;inext) *ptr++=','; - *ptr++=' ';*ptr=0; - child=child->next; - free(str);free(ret); - } -// for (i=0;ichild;int i=0;while(c)i++,c=c->next;return i;} -cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item) item--,c=c->next; return c;} -cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && strcasecmp(c->string,string)) c=c->next; return c;} - -// Utility for array list handling. -static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;} - -// Add item to array/object. -void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}} -void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (item->string) free(item->string);item->string=strdup(string);cJSON_AddItemToArray(object,item);} - -// Create basic types: -cJSON *cJSON_CreateNull() {cJSON *item=cJSON_New_Item();item->type=cJSON_NULL;return item;} -cJSON *cJSON_CreateTrue() {cJSON *item=cJSON_New_Item();item->type=cJSON_True;return item;} -cJSON *cJSON_CreateFalse() {cJSON *item=cJSON_New_Item();item->type=cJSON_False;return item;} -cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;return item;} -cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();item->type=cJSON_String;item->valuestring=strdup(string);return item;} -cJSON *cJSON_CreateArray() {cJSON *item=cJSON_New_Item();item->type=cJSON_Array;return item;} -cJSON *cJSON_CreateObject() {cJSON *item=cJSON_New_Item();item->type=cJSON_Object;return item;} - -// Create Arrays: -cJSON *cJSON_CreateIntArray(int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;ichild=n;else suffix_object(p,n);p=n;}return a;} -cJSON *cJSON_CreateFloatArray(float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;ichild=n;else suffix_object(p,n);p=n;}return a;} -cJSON *cJSON_CreateDoubleArray(double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;ichild=n;else suffix_object(p,n);p=n;}return a;} -cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;ichild=n;else suffix_object(p,n);p=n;}return a;} diff --git a/!NotAdopted/IMO2sProxy/src/common/cJSON.h b/!NotAdopted/IMO2sProxy/src/common/cJSON.h deleted file mode 100644 index debda45bc0..0000000000 --- a/!NotAdopted/IMO2sProxy/src/common/cJSON.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - Copyright (c) 2009 Dave Gamble - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#ifndef cJSON__h -#define cJSON__h - -#ifdef __cplusplus -extern "C" -{ -#endif - -// cJSON Types: -#define cJSON_False 0 -#define cJSON_True 1 -#define cJSON_NULL 2 -#define cJSON_Number 3 -#define cJSON_String 4 -#define cJSON_Array 5 -#define cJSON_Object 6 - -// The cJSON structure: -typedef struct cJSON { - struct cJSON *next,*prev; // next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem - struct cJSON *child; // An array or object item will have a child pointer pointing to a chain of the items in the array/object. - - int type; // The type of the item, as above. - - char *valuestring; // The item's string, if type==cJSON_String - int valueint; // The item's number, if type==cJSON_Number - double valuedouble; // The item's number, if type==cJSON_Number - - char *string; // The item's name string, if this item is the child of, or is in the list of subitems of an object. -} cJSON; - -// Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. -extern cJSON *cJSON_Parse(const char *value); -// Render a cJSON entity to text for transfer/storage. Free the char* when finished. -extern char *cJSON_Print(cJSON *item); -// Delete a cJSON entity and all subentities. -extern void cJSON_Delete(cJSON *c); - -// Returns the number of items in an array (or object). -extern int cJSON_GetArraySize(cJSON *array); -// Retrieve item number "item" from array "array". Returns NULL if unsuccessful. -extern cJSON *cJSON_GetArrayItem(cJSON *array,int item); -// Get item "string" from object. Case insensitive. -extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string); - -// These calls create a cJSON item of the appropriate type. -extern cJSON *cJSON_CreateNull(); -extern cJSON *cJSON_CreateTrue(); -extern cJSON *cJSON_CreateFalse(); -extern cJSON *cJSON_CreateNumber(double num); -extern cJSON *cJSON_CreateString(const char *string); -extern cJSON *cJSON_CreateArray(); -extern cJSON *cJSON_CreateObject(); - -// These utilities create an Array of count items. -extern cJSON *cJSON_CreateIntArray(int *numbers,int count); -extern cJSON *cJSON_CreateFloatArray(float *numbers,int count); -extern cJSON *cJSON_CreateDoubleArray(double *numbers,int count); -extern cJSON *cJSON_CreateStringArray(const char **strings,int count); - -// Append item to the specified array/object. -extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); -extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item); - -#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) -#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) -#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) -#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) -#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/!NotAdopted/IMO2sProxy/src/common/fifo.c b/!NotAdopted/IMO2sProxy/src/common/fifo.c deleted file mode 100644 index d703ac33d4..0000000000 --- a/!NotAdopted/IMO2sProxy/src/common/fifo.c +++ /dev/null @@ -1,144 +0,0 @@ -#include -#include -#include "fifo.h" - -struct _tagFIFO -{ - unsigned int uiCount; - unsigned int uiCapacity; - unsigned int uiActInd; - char *acStorage; -}; - - -TYP_FIFO *Fifo_Init(unsigned int uiCapacity) -{ - TYP_FIFO *pstHandle; - - pstHandle = (TYP_FIFO *)malloc(sizeof(TYP_FIFO)); - if (!pstHandle) return NULL; - pstHandle->uiCount = pstHandle->uiActInd = 0; - pstHandle->uiCapacity = uiCapacity; - if (uiCapacity == 0) - pstHandle->acStorage = NULL; - else - { - pstHandle->acStorage = (char *)malloc(uiCapacity); - if (!pstHandle->acStorage) - { - free (pstHandle); - return NULL; - } - } - return pstHandle; -} - -void Fifo_Exit(TYP_FIFO *pstHandle) -{ - if (pstHandle->acStorage) - free (pstHandle->acStorage); - free (pstHandle); -} - -char *Fifo_AllocBuffer(TYP_FIFO *pstHandle, unsigned int uiPCount) -{ - unsigned int uiCount = pstHandle->uiCount; - - if (!Fifo_Add (pstHandle, NULL, uiPCount)) return NULL; - return &pstHandle->acStorage[pstHandle->uiActInd+uiCount]; - -} - -BOOL Fifo_Add(TYP_FIFO *pstHandle, char *acPBytes, unsigned int uiPCount) -{ - unsigned int uiFree; - - if (uiPCount == 0) return TRUE; - if (pstHandle->uiCapacity == 0) - { - if (!(pstHandle->acStorage = (char *)calloc(1, uiPCount))) - return FALSE; - if (acPBytes) - memcpy(pstHandle->acStorage, acPBytes, uiPCount); - else - memset(pstHandle->acStorage, 0, uiPCount); - pstHandle->uiCapacity = pstHandle->uiCount = uiPCount; - pstHandle->uiActInd = 0; - } - else - { - uiFree = pstHandle->uiCapacity-(pstHandle->uiActInd+pstHandle->uiCount); - if (uiFree < uiPCount) - { - if (pstHandle->uiActInd>=uiPCount && pstHandle->uiActInd*4>pstHandle->uiCount) - { - memmove(pstHandle->acStorage, pstHandle->acStorage+pstHandle->uiActInd, pstHandle->uiCount); - pstHandle->uiActInd = 0; - } - else - { - char *acBuf; - unsigned int uiNewLen; - - if (pstHandle->uiCapacity*2 < - pstHandle->uiCount+pstHandle->uiActInd+uiPCount) - uiNewLen = pstHandle->uiCount+pstHandle->uiActInd+uiPCount; - else - uiNewLen = pstHandle->uiCapacity*2; - acBuf = realloc(pstHandle->acStorage, uiNewLen); - if (acBuf == NULL) return FALSE; - pstHandle->acStorage = acBuf; - memset (acBuf+pstHandle->uiCapacity, 0, uiNewLen-pstHandle->uiCapacity); - pstHandle->uiCapacity = uiNewLen; - } - } - if (acPBytes) - memcpy (&pstHandle->acStorage[pstHandle->uiActInd+pstHandle->uiCount], acPBytes, uiPCount); - else - memset (&pstHandle->acStorage[pstHandle->uiActInd+pstHandle->uiCount], 0, uiPCount); - - pstHandle->uiCount += uiPCount; - } - - return TRUE; -} - -BOOL Fifo_AddString(TYP_FIFO *pstHandle, char *pszString) -{ - BOOL bRet; - - while (pstHandle->uiCount && pstHandle->acStorage[pstHandle->uiCount+pstHandle->uiActInd-1]==0) - pstHandle->uiCount--; - bRet = Fifo_Add (pstHandle, pszString, strlen(pszString)+1); - return bRet; -} - -char *Fifo_Get (TYP_FIFO *pstHandle, unsigned int *uiPCount) -{ - unsigned int uiCount; - char *pRet; - - if (!uiPCount) uiCount = pstHandle->uiCount; - else - { - if (pstHandle->uiCount < *uiPCount) - *uiPCount = pstHandle->uiCount; - uiCount = *uiPCount; - } - if (!uiCount) return NULL; - - pRet = &pstHandle->acStorage[pstHandle->uiActInd]; - pstHandle->uiActInd += uiCount; - pstHandle->uiCount -= uiCount; - return pRet; -} - -void Fifo_Reset (TYP_FIFO *pstHandle) -{ - pstHandle->uiCount = pstHandle->uiActInd = 0; -} - -unsigned int Fifo_Count (TYP_FIFO *pstHandle) -{ - return pstHandle->uiCount; -} diff --git a/!NotAdopted/IMO2sProxy/src/common/fifo.h b/!NotAdopted/IMO2sProxy/src/common/fifo.h deleted file mode 100644 index 0ab9f4f469..0000000000 --- a/!NotAdopted/IMO2sProxy/src/common/fifo.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __FIFO_H__ -#define __FIFO_H__ - -struct _tagFIFO; -typedef struct _tagFIFO TYP_FIFO; - -#ifndef BOOL -#define BOOL int -#endif -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -TYP_FIFO *Fifo_Init(unsigned int uiCapacity); -void Fifo_Exit(TYP_FIFO *pstHandle); -char *Fifo_AllocBuffer(TYP_FIFO *pstHandle, unsigned int uiPCount); -BOOL Fifo_Add(TYP_FIFO *pstHandle, char *acPBytes, unsigned int uiPCount); -BOOL Fifo_AddString(TYP_FIFO *pstHandle, char *pszString); -char *Fifo_Get (TYP_FIFO *pstHandle, unsigned int *uiPCount); -unsigned int Fifo_Count (TYP_FIFO *pstHandle); -void Fifo_Reset (TYP_FIFO *hFifo); - -#endif diff --git a/!NotAdopted/IMO2sProxy/src/common/memlist.c b/!NotAdopted/IMO2sProxy/src/common/memlist.c deleted file mode 100644 index 137a03eeac..0000000000 --- a/!NotAdopted/IMO2sProxy/src/common/memlist.c +++ /dev/null @@ -1,158 +0,0 @@ -#include "memlist.h" -#include -#include - -struct _tagLIST -{ - unsigned int uiCount; - unsigned int uiCapacity; - void **apStorage; -}; - -// ----------------------------------------------------------------------------- -// Interface -// ----------------------------------------------------------------------------- - -TYP_LIST *List_Init(unsigned int uiCapacity) -{ - TYP_LIST *pstHandle; - - pstHandle = (TYP_LIST *)malloc(sizeof(TYP_LIST)); - - if (!pstHandle) return NULL; - pstHandle->uiCount = 0; - pstHandle->uiCapacity = uiCapacity; - if (uiCapacity == 0) - pstHandle->apStorage = NULL; - else - { - pstHandle->apStorage = (void **)malloc(sizeof(void *)*uiCapacity); - if (!pstHandle->apStorage) - { - free(pstHandle); - return NULL; - } - } - return pstHandle; -} - -// ----------------------------------------------------------------------------- - -void List_Exit(TYP_LIST *pstHandle) -{ - if (pstHandle->apStorage) - free (pstHandle->apStorage); - free (pstHandle); -} - -// ----------------------------------------------------------------------------- - -BOOL List_Push(TYP_LIST *pstHandle, void *pItem) -{ - return List_InsertElementAt(pstHandle, pItem,pstHandle->uiCount); -} - -// ----------------------------------------------------------------------------- - -void *List_Pop (TYP_LIST *pstHandle) -{ - if (pstHandle->uiCount) - return List_RemoveElementAt(pstHandle ,pstHandle->uiCount-1); - else return NULL; -} - -// ----------------------------------------------------------------------------- - -BOOL List_ReplaceElementAt(TYP_LIST *pstHandle, void *pItem, unsigned int uiPos) -{ - if (uiPos >= pstHandle->uiCount) return NULL; - pstHandle->apStorage[uiPos]=pItem; - return TRUE; -} - -// ----------------------------------------------------------------------------- - -BOOL List_InsertElementAt(TYP_LIST *pstHandle, void *pItem, unsigned int uiPos) -{ - unsigned int uiStep; - void **apNewStorage; - - if (uiPos > pstHandle->uiCount) - uiPos = pstHandle->uiCount; - - if (pstHandle->uiCount >= pstHandle->uiCapacity) - { - uiStep = pstHandle->uiCount*2; - if (uiStep < 8) uiStep = 8; - - if (!pstHandle->apStorage) - apNewStorage = (void **)malloc(sizeof(void *)*uiStep); - else - apNewStorage = realloc (pstHandle->apStorage, sizeof(void *)*uiStep); - if (!apNewStorage) return FALSE; - pstHandle->apStorage = apNewStorage; - pstHandle->uiCapacity = uiStep; - } - - if (uiPosuiCount) - memmove(&pstHandle->apStorage[uiPos+1], &pstHandle->apStorage[uiPos], (pstHandle->uiCount-uiPos)*sizeof(void*)); - pstHandle->apStorage[uiPos] = pItem; - pstHandle->uiCount++; - return TRUE; -} - -// ----------------------------------------------------------------------------- - -void *List_RemoveElementAt(TYP_LIST *pstHandle, unsigned int uiPos) -{ - void *pRet; - - pRet = pstHandle->apStorage[uiPos]; - if (uiPosuiCount-1) - memmove (&pstHandle->apStorage[uiPos], &pstHandle->apStorage[uiPos+1], (pstHandle->uiCount-uiPos-1)*sizeof(void*)); - pstHandle->uiCount--; - return pRet; -} - -// ----------------------------------------------------------------------------- - -unsigned int List_Count(TYP_LIST *pstHandle) -{ - return pstHandle->uiCount; -} - -// ----------------------------------------------------------------------------- - -void *List_ElementAt(TYP_LIST *pstHandle,unsigned int uiPos) -{ - if (uiPos >= pstHandle->uiCount) return NULL; - return pstHandle->apStorage[uiPos]; -} - -// ----------------------------------------------------------------------------- - -void *List_Top(TYP_LIST *pstHandle) -{ - if (pstHandle->uiCount) - return List_ElementAt (pstHandle, pstHandle->uiCount-1); - else return NULL; -} - -// ----------------------------------------------------------------------------- - -void List_Sort(TYP_LIST *pstHandle, int (*pFunc)(const void*,const void*)) -{ - qsort(pstHandle->apStorage,pstHandle->uiCount,sizeof(void *),pFunc); -} - -// ----------------------------------------------------------------------------- - -void List_FreeElements(TYP_LIST *pstHandle) -{ - void *pEntry; - - while (pEntry = List_Pop(pstHandle)) - free (pEntry); -} - -// ----------------------------------------------------------------------------- diff --git a/!NotAdopted/IMO2sProxy/src/common/memlist.h b/!NotAdopted/IMO2sProxy/src/common/memlist.h deleted file mode 100644 index be37bbb723..0000000000 --- a/!NotAdopted/IMO2sProxy/src/common/memlist.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __LIST_H__ -#define __LIST_H__ - -#ifndef BOOL -#define BOOL int -#endif -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -struct _tagLIST; -typedef struct _tagLIST TYP_LIST; - -TYP_LIST *List_Init(unsigned int uiCapacity); -void List_Exit(TYP_LIST *pstHandle); -BOOL List_Push(TYP_LIST *pstHandle, void *pItem); -void *List_Pop (TYP_LIST *pstHandle); -BOOL List_ReplaceElementAt(TYP_LIST *pstHandle, void *pItem, unsigned int uiPos); -BOOL List_InsertElementAt(TYP_LIST *pstHandle, void *pItem, unsigned int uiPos); -void *List_RemoveElementAt(TYP_LIST *pstHandle, unsigned int uiPos); -unsigned int List_Count(TYP_LIST *pstHandle); -void *List_ElementAt(TYP_LIST *pstHandle,unsigned int uiPos); -void *List_Top(TYP_LIST *pstHandle); -void List_FreeElements(TYP_LIST *pstHandle); -void List_Sort(TYP_LIST *pstHandle, int (*pFunc)(const void*,const void*)); - -#endif diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/Makefile b/!NotAdopted/IMO2sProxy/src/imo2skype/Makefile deleted file mode 100644 index 7e4420f87f..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -CFLAGS = -O0 -g -I../common/ -I../imolib/ -lcurl -lpthread -lm -CC = gcc -COMMON = ../common/fifo.c ../common/cJSON.c ../common/memlist.c -IMOLIB = ../imolib/imo_request.c ../imolib/imo_skype.c ../imolib/io_layer.c -IMO2S = buddylist.c queue.c msgqueue.c imo2skypeapi.c callqueue.c socksproxy.c avatarlist.c -.PHONY: all imo2stest imo2sproxy clean - -all : imo2stest imo2sproxy - -imo2stest: $(COMMON) $(IMO2S) $(IMOLIB) imo2stest.c - $(CC) -o imo2stest $(COMMON) $(IMO2S) $(IMOLIB) imo2stest.c $(CFLAGS) - strip imo2stest - -imo2sproxy: $(COMMON) $(IMO2S) $(IMOLIB) imo2sproxy.c main.c - $(CC) -o imo2sproxy $(COMMON) $(IMO2S) $(IMOLIB) imo2sproxy.c main.c $(CFLAGS) -# strip imo2sproxy - -clean : - rm imo2stest imo2sproxy diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.c b/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.c deleted file mode 100644 index f1c78f0567..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.c +++ /dev/null @@ -1,110 +0,0 @@ -/* Module: avatarlist.c - Purpose: Manages the avatars of your buddies - Author: leecher - Date: 18.08.2011 -*/ - -#include -#include -#include "memlist.h" -#include "avatarlist.h" - -static void SetEntry(AVATARENTRY *pEntry, cJSON *pNick); - -// ----------------------------------------------------------------------------- -// Interface -// ----------------------------------------------------------------------------- - -TYP_LIST *AvatarList_Init(void) -{ - TYP_LIST *hList = List_Init(16); - - return hList; -} - -// ----------------------------------------------------------------------------- - -void AvatarList_Exit(TYP_LIST *hList) -{ - AVATARENTRY *pEntry; - - while (pEntry=(AVATARENTRY*)List_Pop(hList)) - { - AvatarList_FreeEntry(pEntry); - free (pEntry); - } - List_Exit(hList); -} - -// ----------------------------------------------------------------------------- - -BOOL AvatarList_Insert(TYP_LIST *hList, cJSON *pIcon) -{ - AVATARENTRY *pEntry; - - if (pEntry=AvatarList_Find (hList, cJSON_GetObjectItem(pIcon, "buid")->valuestring)) - AvatarList_FreeEntry (pEntry); - else - { - if (!(pEntry = calloc (1, sizeof(AVATARENTRY)))) return FALSE; - if (!List_Push(hList, pEntry)) return FALSE; - } - SetEntry(pEntry, pIcon); - return TRUE; -} - -// ----------------------------------------------------------------------------- - -BOOL AvatarList_Remove(TYP_LIST *hList, AVATARENTRY *pEntry) -{ - AVATARENTRY *pListEntry; - int i, nCount; - - for (i=0, nCount=List_Count(hList); ipszUser, pszUser) == 0) - return pEntry; - } - return NULL; -} - -// ----------------------------------------------------------------------------- - -void AvatarList_FreeEntry(AVATARENTRY *pEntry) -{ - if (pEntry->pszUser) free (pEntry->pszUser); - if (pEntry->pszIcon) free (pEntry->pszIcon); -} - -// ----------------------------------------------------------------------------- -// Static -// ----------------------------------------------------------------------------- - -static void SetEntry(AVATARENTRY *pEntry, cJSON *pNick) -{ - pEntry->pszUser = strdup(cJSON_GetObjectItem(pNick, "buid")->valuestring); - pEntry->pszIcon = strdup(cJSON_GetObjectItem(pNick, "icon")->valuestring); -} diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.h b/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.h deleted file mode 100644 index 6a47ed2fa5..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.h +++ /dev/null @@ -1,16 +0,0 @@ -#include "cJSON.h" -#include "memlist.h" - -typedef struct -{ - char *pszUser; - char *pszIcon; -} AVATARENTRY; - -TYP_LIST *AvatarList_Init(void); -void AvatarList_Exit(TYP_LIST *hList); - -BOOL AvatarList_Insert(TYP_LIST *hList, cJSON *pIcon); -BOOL AvatarList_Remove(TYP_LIST *hList, AVATARENTRY *pEntry); -AVATARENTRY *AvatarList_Find(TYP_LIST *hList, char *pszUser); -void AvatarList_FreeEntry(AVATARENTRY *pEntry); diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.c b/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.c deleted file mode 100644 index 6d228ae4b9..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.c +++ /dev/null @@ -1,204 +0,0 @@ -/* Module: buddylist.c - Purpose: Manages your list of buddies in memory - Author: leecher - Date: 30.08.2009 -*/ - -#include -#include -#include -#include "memlist.h" -#include "buddylist.h" - -static void SetEntry(NICKENTRY *pEntry, cJSON *pNick); - -// ----------------------------------------------------------------------------- -// Interface -// ----------------------------------------------------------------------------- - -TYP_LIST *BuddyList_Init(void) -{ - TYP_LIST *hList = List_Init(16); - - return hList; -} - -// ----------------------------------------------------------------------------- - -void BuddyList_Exit(TYP_LIST *hList) -{ - NICKENTRY *pEntry; - - while (pEntry=(NICKENTRY*)List_Pop(hList)) - { - BuddyList_FreeEntry(pEntry, TRUE); - free (pEntry); - } - List_Exit(hList); -} - -// ----------------------------------------------------------------------------- - -BOOL BuddyList_Insert(TYP_LIST *hList, cJSON *pNick) -{ - NICKENTRY *pEntry; - cJSON *pElem; - - if (pEntry=BuddyList_Find (hList, cJSON_GetObjectItem(pNick, "buid")->valuestring)) - BuddyList_FreeEntry (pEntry, FALSE); - else - { - if (!(pEntry = calloc (1, sizeof(NICKENTRY)))) return FALSE; - if ((pElem=cJSON_GetObjectItem(pNick, "group")) && strcmp(pElem->valuestring, "Skype")) - { - char szBUID[256]; - NICKENTRY *pGroup; - - // Buddy Belongs to a chatgroup - sprintf (szBUID, "%s;", pElem->valuestring); - pGroup = BuddyList_Find (hList, szBUID); - - if (pGroup) // Group not yet created? Shouldn't be the case - { - if (!pGroup->hGCMembers) pGroup->hGCMembers=List_Init(1); - hList = pGroup->hGCMembers; - pEntry->pGroup = pGroup; - } - } - if (!List_Push(hList, pEntry)) return FALSE; - } - SetEntry(pEntry, pNick); - pEntry->iBuddyStatus = 3; - return TRUE; -} - -// ----------------------------------------------------------------------------- - -BOOL BuddyList_AddTemporaryUser(TYP_LIST *hList, char *pszUser) -{ - NICKENTRY *pEntry; - - if (BuddyList_Find (hList, pszUser)) return TRUE; - if (!(pEntry = calloc (1, sizeof(NICKENTRY)))) return FALSE; - pEntry->pszUser = strdup(pszUser); - pEntry->pszAlias = strdup(pszUser); - strcpy (pEntry->szStatus, "OFFLINE"); - pEntry->iBuddyStatus = 2; - return List_Push(hList, pEntry); -} - -// ----------------------------------------------------------------------------- - -BOOL BuddyList_Remove(TYP_LIST *hList, NICKENTRY *pEntry) -{ - NICKENTRY *pListEntry; - int i, nCount; - - if (pEntry->pGroup) hList=pEntry->pGroup->hGCMembers; - for (i=0, nCount=List_Count(hList); ipszUser, pszUser) == 0) - return pEntry; - else if (pEntry->hGCMembers) - { - if (pEntry = BuddyList_Find(pEntry->hGCMembers, pszUser)) - return pEntry; - } - } - return NULL; -} - -// ----------------------------------------------------------------------------- - -BOOL BuddyList_SetStatus(TYP_LIST *hList, cJSON *pNick) -{ - NICKENTRY *pEntry; - - if ((pEntry = BuddyList_Find(hList, cJSON_GetObjectItem(pNick, "buid")->valuestring))) - { - BuddyList_FreeEntry(pEntry, FALSE); - SetEntry(pEntry, pNick); - return TRUE; - } - return FALSE; -} - -// ----------------------------------------------------------------------------- - -void BuddyList_FreeEntry(NICKENTRY *pEntry, BOOL bFreeGC) -{ - if (pEntry->pszAlias) - { - free (pEntry->pszAlias); - pEntry->pszAlias = NULL; - } - if (pEntry->pszUser) - { - free (pEntry->pszUser); - pEntry->pszUser = NULL; - } - if (pEntry->pszStatusText) - { - free(pEntry->pszStatusText); - pEntry->pszStatusText = NULL; - } - if (pEntry->pszDisplay) - { - free(pEntry->pszDisplay); - pEntry->pszDisplay = NULL; - } - if (bFreeGC && pEntry->hGCMembers) - { - NICKENTRY *pNick; - - while (pNick=(NICKENTRY*)List_Pop(pEntry->hGCMembers)) - { - BuddyList_FreeEntry(pNick, bFreeGC); - free (pNick); - } - List_Exit (pEntry->hGCMembers); - pEntry->hGCMembers = NULL; - } -} - -// ----------------------------------------------------------------------------- -// Static -// ----------------------------------------------------------------------------- - -static void SetEntry(NICKENTRY *pEntry, cJSON *pNick) -{ - cJSON *obj; - - if ((obj=cJSON_GetObjectItem(pNick, "alias")) && obj->valuestring) - pEntry->pszAlias = strdup(obj->valuestring); - pEntry->pszUser = strdup(cJSON_GetObjectItem(pNick, "buid")->valuestring); - if ((obj=cJSON_GetObjectItem(pNick, "status")) && obj->valuestring) - pEntry->pszStatusText = strdup(obj->valuestring); - if ((obj=cJSON_GetObjectItem(pNick, "primitive")) && obj->valuestring) - strcpy (pEntry->szStatus, obj->valuestring); - if ((obj=cJSON_GetObjectItem(pNick, "display")) && obj->valuestring) - pEntry->pszDisplay = strdup(obj->valuestring); -} diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.h b/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.h deleted file mode 100644 index 3774ef3e5e..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.h +++ /dev/null @@ -1,28 +0,0 @@ -#include "cJSON.h" -#include "memlist.h" - -struct tag_nickentry; -typedef struct tag_nickentry NICKENTRY; - -struct tag_nickentry -{ - char *pszUser; - char *pszStatusText; - char szStatus[16]; - char *pszAlias; - char *pszDisplay; // Display name, on Groupchat it is topic - int iBuddyStatus; - TYP_LIST *hGCMembers; // List of groupchat members, if this is a groupchat - NICKENTRY *pGroup; // Uplink to Chatgroup, if Groupchat-Member -}; - -TYP_LIST *BuddyList_Init(void); -void BuddyList_Exit(TYP_LIST *hList); - -BOOL BuddyList_Insert(TYP_LIST *hList, cJSON *pNick); -BOOL BuddyList_AddTemporaryUser(TYP_LIST *hList, char *pszUser); -BOOL BuddyList_Remove(TYP_LIST *hList, NICKENTRY *pEntry); -NICKENTRY *BuddyList_Find(TYP_LIST *hList, char *pszUser); -BOOL BuddyList_SetStatus(TYP_LIST *hList, cJSON *pNick); -void BuddyList_FreeEntry(NICKENTRY *pEntry, BOOL bFreeGC); -#define BuddyList_IsGroupchat(pEntry) (pEntry->hGCMembers!=NULL) diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.c b/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.c deleted file mode 100644 index f579eb184e..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.c +++ /dev/null @@ -1,95 +0,0 @@ -/* Module: callqueue.c - Purpose: Queue for incoming calls - Author: leecher - Date: 02.09.2009 - - Fixme: Sort on insert, do a binary search instead of iterating list. -*/ - -#include -#include -#include -#include "callqueue.h" - -static volatile unsigned int m_uMsgNr=0; -static void FreeEntry(void *pPEntry); - -// ----------------------------------------------------------------------------- -// Interface -// ----------------------------------------------------------------------------- - -TYP_LIST *CallQueue_Init(void) -{ - TYP_LIST *hList = List_Init(16); - - return hList; -} - -// ----------------------------------------------------------------------------- - -void CallQueue_Exit(TYP_LIST *hList) -{ - Queue_Exit (hList, FreeEntry); -} - -// ----------------------------------------------------------------------------- - -CALLENTRY *CallQueue_Insert(TYP_LIST *hList, cJSON *pNick, int iDirection) -{ - CALLENTRY *pEntry; - cJSON *pStream, *pVal, *pPipe; - - if (!(pEntry = Queue_InsertEntry(hList, sizeof(CALLENTRY), ++m_uMsgNr, - FreeEntry))) return NULL; - pEntry->pszUser = strdup(cJSON_GetObjectItem(pNick, "buid")->valuestring); - time (&pEntry->timestamp); - strcpy (pEntry->szStatus, "RINGING"); - - if (pStream = cJSON_GetObjectItem(pNick, "send_stream")) - { - strcpy (pEntry->szSendStream, pStream->valuestring); - if (pStream = cJSON_GetObjectItem(pNick, "recv_stream")) - strcpy (pEntry->szRecvStream, pStream->valuestring); - } - else - { - // Copy pipe to Call object - if (pPipe = cJSON_GetObjectItem(pNick, "pipe")) - { - if (pVal = cJSON_GetObjectItem(pPipe, "ip")) - strncpy (pEntry->szIP, pVal->valuestring, sizeof(pEntry->szIP)); - if (pVal = cJSON_GetObjectItem(pPipe, "conv")) - strncpy (pEntry->szConv, pVal->valuestring, sizeof(pEntry->szConv)); - if (pVal = cJSON_GetObjectItem(pPipe, "role")) - pEntry->iRole = pVal->valueint; - } - } - pEntry->iDirection = iDirection; - return pEntry; -} - -// ----------------------------------------------------------------------------- - -BOOL CallQueue_Remove(TYP_LIST *hList, unsigned int uMsgNr) -{ - return Queue_Remove (hList, uMsgNr, FreeEntry); -} - -// ----------------------------------------------------------------------------- - -CALLENTRY *CallQueue_Find(TYP_LIST *hList, unsigned int uMsgNr) -{ - return (CALLENTRY*)Queue_Find(hList, uMsgNr); -} - -// ----------------------------------------------------------------------------- -// Static -// ----------------------------------------------------------------------------- - -static void FreeEntry(void *pPEntry) -{ - CALLENTRY *pEntry = (CALLENTRY*)pPEntry; - - free (pEntry->pszUser); -} - diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.h b/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.h deleted file mode 100644 index 0c4fcfd2cf..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.h +++ /dev/null @@ -1,32 +0,0 @@ -#include "cJSON.h" -#include "queue.h" -#include - -#define CALL_INCOMING 0 -#define CALL_OUTGOING 1 - -typedef struct -{ - QUEUEHDR hdr; - char *pszUser; - char szStatus[16]; - - char szSendStream[18]; - char szRecvStream[18]; - - char szConv[18]; - char szIP[16]; - int iRole; - - char szCallFile[256]; - void *hCallWnd; - int iDirection; - time_t timestamp; -} CALLENTRY; - -TYP_LIST *CallQueue_Init(void); -void CallQueue_Exit(TYP_LIST *hList); - -CALLENTRY *CallQueue_Insert(TYP_LIST *hList, cJSON *pNick, int iDirection); -BOOL CallQueue_Remove(TYP_LIST *hList, unsigned int uCallNr); -CALLENTRY *CallQueue_Find(TYP_LIST *hList, unsigned int uCallNr); diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/crash.c b/!NotAdopted/IMO2sProxy/src/imo2skype/crash.c deleted file mode 100644 index 91ad90032e..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/crash.c +++ /dev/null @@ -1,295 +0,0 @@ -#include -#include -#pragma comment (lib, "imagehlp.lib") - -#define MAXNAMELEN 1024 -#define HEXDUMP_BREAK 16 - -void HexDump(char *pszOutput, PBYTE pData, int cbLength, BOOL bShow) -{ - char *pszLastLine; - int i; - - *pszOutput=0; - pszLastLine = pszOutput; - for (i=0; i=HEXDUMP_BREAK) - { - int j; - - strcat (pszOutput, " "); - for (j=i-HEXDUMP_BREAK; j (DWORD)sysInfo.lpMaximumApplicationAddress) - return; - - if (ReadProcessMemory (GetCurrentProcess(), (PVOID)dwBase, mem, cbLength, &read)) - { - char *pszHexdump = (char *)alloca (((cbLength/HEXDUMP_BREAK)+1)*81); - - LOG (("Memory dump for %s:\n", pszName)); - HexDump (pszHexdump, mem, read, TRUE); - LOG (("\n")); - } -} - - -BOOL ShowThreadStack (HANDLE hThread, CONTEXT *c) -{ - STACKFRAME stFrame={0}; - DWORD dwSymOptions, dwFrameNum=0, dwMachine, dwOffsetFromSym=0; - IMAGEHLP_LINE Line={0}; - IMAGEHLP_MODULE Module={0}; - HANDLE hProcess = GetCurrentProcess(); - BYTE pbSym[sizeof(IMAGEHLP_SYMBOL) + MAXNAMELEN]; - IMAGEHLP_SYMBOL *pSym = (IMAGEHLP_SYMBOL *)&pbSym; - char szUndecName[MAXNAMELEN], szUndecFullName[MAXNAMELEN]; - - /* - if ( ! GetThreadContext( hThread, &c ) ) - { - SetError (NULL, NULL, 0); - LOG (("Cannot get thread context%d\n", GetLastError())); - return FALSE; - } - */ - LOG (("Please wait...\n")); - if (!SymInitialize (hProcess, NULL, TRUE)) - { - LOG (("Cannot initialize symbol engine (%08X)\n", GetLastError())); - return FALSE; - } - - dwSymOptions = SymGetOptions(); - dwSymOptions |= SYMOPT_LOAD_LINES; - dwSymOptions &= ~SYMOPT_UNDNAME; - SymSetOptions (dwSymOptions); - - stFrame.AddrPC.Mode = AddrModeFlat; - dwMachine = IMAGE_FILE_MACHINE_I386; - stFrame.AddrPC.Offset = c->Eip; - stFrame.AddrStack.Offset = c->Esp; - stFrame.AddrStack.Mode = AddrModeFlat; - stFrame.AddrFrame.Offset = c->Ebp; - stFrame.AddrFrame.Mode = AddrModeFlat; - - Module.SizeOfStruct = sizeof(Module); - Line.SizeOfStruct = sizeof(Module); - - LOG (("\n--# FV EIP----- RetAddr- FramePtr StackPtr Symbol\n")); - do - { - if (!StackWalk (dwMachine, hProcess, hThread, &stFrame, &c, NULL, &SymFunctionTableAccess, &SymGetModuleBase, NULL)) - break; - - LOG (( "\n%3d %c%c %08lx %08lx %08lx %08lx ", - dwFrameNum, stFrame.Far? 'F': '.', stFrame.Virtual? 'V': '.', - stFrame.AddrPC.Offset, stFrame.AddrReturn.Offset, - stFrame.AddrFrame.Offset, stFrame.AddrStack.Offset )); - - if (stFrame.AddrPC.Offset == 0) - { - LOG (( "(-nosymbols-)\n" )); - } - else - { // we seem to have a valid PC - if (!SymGetSymFromAddr (hProcess, stFrame.AddrPC.Offset, &dwOffsetFromSym, pSym)) - { - if (GetLastError() != 487) - { - LOG (("Unable to get symbol from addr (%08X)", GetLastError())); - } - } - else - { - UnDecorateSymbolName (pSym->Name, szUndecName, MAXNAMELEN, UNDNAME_NAME_ONLY ); - UnDecorateSymbolName (pSym->Name, szUndecFullName, MAXNAMELEN, UNDNAME_COMPLETE ); - LOG (("%s", szUndecName)); - if (dwOffsetFromSym) LOG ((" %+ld bytes", (long)dwOffsetFromSym)); - LOG (("\n Sig: %s\n Decl: %s\n", pSym->Name, szUndecFullName)); - } - - if (!SymGetLineFromAddr (hProcess, stFrame.AddrPC.Offset, &dwOffsetFromSym, &Line)) - { - if (GetLastError() != 487) - { - LOG (("Unable to get line from addr (%08X)", GetLastError())); - } - } - else - { - LOG ((" Line: %s(%lu) %+ld bytes\n", Line.FileName, Line.LineNumber, dwOffsetFromSym )); - } - - if (!SymGetModuleInfo (hProcess, stFrame.AddrPC.Offset, &Module)) - { - if (GetLastError() != 487) - { - LOG (("Unable to get module info (%08X)", GetLastError())); - } - } - else - { - char ty[80]; - - switch ( Module.SymType ) - { - case SymNone: - strcpy( ty, "-nosymbols-" ); - break; - case SymCoff: - strcpy( ty, "COFF" ); - break; - case SymCv: - strcpy( ty, "CV" ); - break; - case SymPdb: - strcpy( ty, "PDB" ); - break; - case SymExport: - strcpy( ty, "-exported-" ); - break; - case SymDeferred: - strcpy( ty, "-deferred-" ); - break; - case SymSym: - strcpy( ty, "SYM" ); - break; - default: - _snprintf( ty, sizeof ty, "symtype=%ld", (long) Module.SymType ); - break; - - } - LOG (( " Mod: %s[%s], base: %08lxh\n", Module.ModuleName, Module.ImageName, Module.BaseOfImage )); - LOG (( " Sym: type: %s, file: %s\n", ty, Module.LoadedImageName)); - } - } - dwFrameNum++; - } while (stFrame.AddrReturn.Offset); - SymCleanup (hProcess); - return TRUE; -} - - -LONG Win32FaultHandler(struct _EXCEPTION_POINTERS * ExInfo) -{ - char *FaultTx; - int wsFault = ExInfo->ExceptionRecord->ExceptionCode; - PVOID CodeAdress = ExInfo->ExceptionRecord->ExceptionAddress; -#ifndef USE_GUI - char choice[10]; -#endif - - if (//IsDebuggerPresent() || - ExInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) - return EXCEPTION_CONTINUE_SEARCH; - - switch(ExInfo->ExceptionRecord->ExceptionCode) - { - case EXCEPTION_ACCESS_VIOLATION : FaultTx = "ACCESS VIOLATION"; break; - case EXCEPTION_DATATYPE_MISALIGNMENT : FaultTx = "DATATYPE MISALIGNMENT"; break; - case EXCEPTION_FLT_DIVIDE_BY_ZERO : FaultTx = "FLT DIVIDE BY ZERO"; break; - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED : FaultTx = "ARRAY BOUNDS EXCEEDED"; break; - case EXCEPTION_FLT_DENORMAL_OPERAND : FaultTx = "FLT DENORMAL OPERAND"; break; - case EXCEPTION_FLT_INEXACT_RESULT : FaultTx = "FLT INEXACT RESULT"; break; - case EXCEPTION_FLT_INVALID_OPERATION : FaultTx = "FLT INVALID OPERATION"; break; - case EXCEPTION_FLT_OVERFLOW : FaultTx = "FLT OVERFLOW"; break; - case EXCEPTION_FLT_STACK_CHECK : FaultTx = "FLT STACK CHECK"; break; - case EXCEPTION_FLT_UNDERFLOW : FaultTx = "FLT UNDERFLOW"; break; - case EXCEPTION_ILLEGAL_INSTRUCTION : FaultTx = "ILLEGAL INSTRUCTION"; break; - case EXCEPTION_IN_PAGE_ERROR : FaultTx = "IN PAGE ERROR"; break; - case EXCEPTION_INT_DIVIDE_BY_ZERO : FaultTx = "INT DEVIDE BY ZERO"; break; - case EXCEPTION_INT_OVERFLOW : FaultTx = "INT OVERFLOW"; break; - case EXCEPTION_INVALID_DISPOSITION : FaultTx = "INVALID DISPOSITION"; break; - case EXCEPTION_NONCONTINUABLE_EXCEPTION:FaultTx= "NONCONTINUABLE EXCEPTION"; break; - case EXCEPTION_PRIV_INSTRUCTION : FaultTx = "PRIVILEGED INSTRUCTION";break; - case EXCEPTION_SINGLE_STEP : FaultTx = "SINGLE STEP"; break; - case EXCEPTION_STACK_OVERFLOW : FaultTx = "STACK OVERFLOW"; break; - case DBG_CONTROL_C : return EXCEPTION_EXECUTE_HANDLER; - default : FaultTx = "(unknown)"; break; - } - - LOG (("****************************************************\n")); - LOG (("*** A Program Fault occurred: ***\n")); - LOG (("*** Error code %08X: %-24s***\n", wsFault, FaultTx)); - LOG (("****************************************************\n")); - LOG (("*** Address: %08X Flags: %08X ***\n", (int)CodeAdress, ExInfo->ExceptionRecord->ExceptionFlags)); - LOG (("*** EAX=%08X EBX=%08X ECX=%08X ***\n", ExInfo->ContextRecord->Eax, ExInfo->ContextRecord->Ebx, ExInfo->ContextRecord->Ecx)); - LOG (("*** EDX=%08X EBP=%08X ESI=%08X ***\n", ExInfo->ContextRecord->Edx, ExInfo->ContextRecord->Ebp, ExInfo->ContextRecord->Esi)); - LOG (("*** EDI=%08X ESP=%08X EIP=%08X ***\n", ExInfo->ContextRecord->Edi, ExInfo->ContextRecord->Esp, ExInfo->ContextRecord->Eip)); - LOG (("****************************************************\n")); - CrashDumpMem (ExInfo->ContextRecord->Eax, "EAX", 8); - CrashDumpMem (ExInfo->ContextRecord->Ebx, "EBX", 8); - CrashDumpMem (ExInfo->ContextRecord->Ecx, "ECX", 8); - CrashDumpMem (ExInfo->ContextRecord->Edx, "EDX", 8); - CrashDumpMem (ExInfo->ContextRecord->Esi, "ESI", 8); - CrashDumpMem (ExInfo->ContextRecord->Edi, "EDI", 8); - CrashDumpMem (ExInfo->ContextRecord->Esp, "ESP", 32); - CrashDumpMem (ExInfo->ContextRecord->Ebp, "EBP", 32); - { - OSVERSIONINFO ov={0}; - - ov.dwOSVersionInfoSize=sizeof(ov); - GetVersionEx (&ov); - LOG (("Target platform: Microsoft Windows NT %d.%d Build %d %s\n", ov.dwMajorVersion, ov.dwMinorVersion, - ov.dwBuildNumber, ov.szCSDVersion)); - } - - //LogStackFrames(CodeAddress, (char *)ExInfo->ContextRecord->Ebp); - ShowThreadStack (GetCurrentThread(), ExInfo->ContextRecord); - -#ifdef USE_GUI - if (MessageBox(NULL, "A Program Fault occurred. Do you want to continue execution (not recommended)?", "CRASH!", MB_ICONERROR | MB_YESNO) == IDYES) -#else - printf ("Do you want to continue program execution (not recommended) [y/N]? "); - fgets(choice, sizeof(choice) - 1, stdin); - - if (*choice=='y' || *choice=='Y') -#endif - { - ExInfo->ContextRecord->Eip++; - return EXCEPTION_CONTINUE_EXECUTION; - } - return EXCEPTION_EXECUTE_HANDLER; -} - -void Crash_Init(void) -{ -//#ifndef _DEBUG - SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER) Win32FaultHandler); -//#endif -} diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/crash.h b/!NotAdopted/IMO2sProxy/src/imo2skype/crash.h deleted file mode 100644 index 7f2d790f6c..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/crash.h +++ /dev/null @@ -1 +0,0 @@ -void Crash_Init(void); diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.c b/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.c deleted file mode 100644 index de0a9b4028..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.c +++ /dev/null @@ -1,1959 +0,0 @@ -/* Module: imo2skypeapi.c - Purpose: Simple wrapper for imo.im Webservice to SKYPE API to maintain compatibility with Skype-Plugins - Author: leecher - Date: 30.08.2009 -*/ - -#define VOICECALL_VERSION 1221873445 -#define IVC_VERSION "98a29c15e305a7af04634b03d5e1425d6c67806e" - -#include -#include -#include -#include -#include -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include "w32browser.h" -#define strcasecmp stricmp -#define strncasecmp strnicmp -#define thread_t HANDLE -#define vsnprintf _vsnprintf -#define GWL_PINST 0 -#define GWL_ORIGWPRC 1*sizeof(PVOID) -#else -#define thread_t pthread_t -#include -#include -#endif -#include "imo_skype.h" -#include "imo_request.h" -#include "fifo.h" -#include "memlist.h" -#include "buddylist.h" -#include "avatarlist.h" -#include "msgqueue.h" -#include "callqueue.h" -#include "imo2skypeapi.h" - -typedef struct -{ - char *pszImoStat; - char *pszSkypeStat; -} STATMAP; - -struct _tagIMOSAPI -{ - IMOSKYPE *hInst; - NICKENTRY myUser; - char *pszPass; - char *pszLogBuf; - char *pszClientName; - int cbBuf; - TYP_LIST *hBuddyList; - TYP_LIST *hAvatarList; - TYP_LIST *hMsgQueue; - TYP_LIST *hCallQueue; - int iProtocol; - int iLoginStat; - IMO2SCB Callback; - void *pUser; - FILE *fpLog; - thread_t hThread; - int bFriendsPending; - int iFlags; - int iShuttingDown; - volatile time_t tSetMoodText; - char *pszCmdID; - char *pszBuddiesToAdd; -}; - -static STATMAP m_stMap[] = -{ - {"available", "ONLINE"}, - {"available", "SKYPEME"}, - {"offline", "OFFLINE"}, - {"away", "AWAY"}, - {"busy", "DND"}, - {"busy", "NA"}, - {"invisible", "INVISIBLE"} -}; - -static int StartCallSWF (IMOSAPI *pInst, CALLENTRY *pCall); -static int StatusCallback (cJSON *pMsg, void *pUser); -static void DispatcherThread(void *pUser); -static int Dispatcher_Start(IMOSAPI *pInst); -static int Dispatcher_Stop(IMOSAPI *pInst); -static void Send(IMOSAPI *pInst, const char *pszMsg, ...); -static void HandleMessage(IMOSAPI *pInst, char *pszMsg); - - -// ----------------------------------------------------------------------------- -// Interface -// ----------------------------------------------------------------------------- - -IMOSAPI *Imo2S_Init(IMO2SCB Callback, void *pUser, int iFlags) -{ - IMOSAPI *pInst = calloc(1, sizeof(IMOSAPI)); - - if (!pInst) return NULL; - if (!(pInst->pszLogBuf = malloc(pInst->cbBuf=512)) || - !(pInst->hInst = ImoSkype_Init(StatusCallback, pInst)) || - !(pInst->hBuddyList = BuddyList_Init()) || - !(pInst->hAvatarList = AvatarList_Init()) || - !(pInst->hMsgQueue = MsgQueue_Init()) || -#ifdef WIN32 - ((iFlags & IMO2S_FLAG_ALLOWINTERACT) && W32Browser_Init(0)==-1) || -#endif - !(pInst->hCallQueue = CallQueue_Init())) - { - Imo2S_Exit(pInst); - return NULL; - } - pInst->Callback = Callback; - pInst->pUser = pUser; - pInst->iFlags = iFlags; - pInst->myUser.iBuddyStatus = 3; - strcpy (pInst->myUser.szStatus, "OFFLINE"); - pInst->iProtocol = 3; - return pInst; -} - -// ----------------------------------------------------------------------------- - -void Imo2S_SetLog (IMOSAPI *pInst, FILE *fpLog) -{ - pInst->fpLog = fpLog; -} - -// ----------------------------------------------------------------------------- - -void Imo2S_Exit (IMOSAPI *pInst) -{ - if (!pInst) return; - pInst->iShuttingDown = 1; - if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S_Exit()\n"); - if (pInst->iLoginStat == 1) Imo2S_Logout(pInst); - if (pInst->hInst) ImoSkype_Exit(pInst->hInst); - if (pInst->hBuddyList) BuddyList_Exit(pInst->hBuddyList); - if (pInst->hAvatarList) AvatarList_Exit(pInst->hAvatarList); - if (pInst->hMsgQueue) MsgQueue_Exit(pInst->hMsgQueue); - if (pInst->hCallQueue) CallQueue_Exit(pInst->hCallQueue); - if (pInst->pszPass) free (pInst->pszPass); - if (pInst->pszLogBuf) free(pInst->pszLogBuf); - if (pInst->pszClientName) free(pInst->pszClientName); -#ifdef WIN32 - if (pInst->iFlags & IMO2S_FLAG_ALLOWINTERACT) W32Browser_Exit(); -#endif - BuddyList_FreeEntry(&pInst->myUser, TRUE); - memset (pInst, 0, sizeof(IMOSAPI)); - free (pInst); -} - -// ----------------------------------------------------------------------------- - -int Imo2S_Login (IMOSAPI *pInst, char *pszUser, char *pszPass, char **ppszError) -{ - // In case this module is passing in the original values... - char *pszLocalUser, *pszLocalPass; - - if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S_Login(%s, ****)\n", pszUser); - if (pInst->iLoginStat == 1) return pInst->iLoginStat; - if (!pInst->hInst) pInst->hInst=ImoSkype_Init(StatusCallback, pInst); - pszLocalUser = strdup(pszUser); - if (pInst->myUser.pszUser) free (pInst->myUser.pszUser); - pInst->myUser.pszUser = pszLocalUser; - pszLocalPass = strdup(pszPass); - if (pInst->pszPass) free (pInst->pszPass); - pInst->pszPass = pszLocalPass; - Send(pInst, "CONNSTATUS CONNECTING"); - pInst->iLoginStat = ImoSkype_Login(pInst->hInst, pszLocalUser, pszLocalPass); - if (pInst->iLoginStat == 1) - { - ImoSkype_GetUnreadMsgs(pInst->hInst); - if (IMO_API_VERSION > 0) ImoSkype_GetAlpha(pInst->hInst); - Dispatcher_Start(pInst); - } - else - if (ppszError) *ppszError = ImoSkype_GetLastError(pInst->hInst); - return pInst->iLoginStat; -} - -// ----------------------------------------------------------------------------- - -void Imo2S_Logout(IMOSAPI *pInst) -{ - if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S_Logout()\n"); - Dispatcher_Stop(pInst); - if (ImoSkype_Logout(pInst->hInst) == 1) - { - pInst->iLoginStat = 0; - strcpy (pInst->myUser.szStatus, "OFFLINE"); - } - - - // If we relogin, user information won't be re-propagated if we - // reuse the same connection. Therefore also dispose the connection - // to imo.im service (wouldn't be necessary, but to ensure proper - // repropagation of contacts on login, we have to do it, sorry) - if (!pInst->iShuttingDown) - { - ImoSkype_Exit(pInst->hInst); - pInst->hInst = NULL; - } -} - -// ----------------------------------------------------------------------------- - -int Imo2S_Send (IMOSAPI *pInst, char *pszMsg) -{ - char *pszDup = strdup(pszMsg); - char *pszRealMsg = pszMsg; - - if (*pszRealMsg=='#') - { - char *p; - if (p = strchr (pszRealMsg, ' ')) pszRealMsg=p+1; - } - if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S_Send(%s)\n", pszMsg); - if (strlen(pszRealMsg)>15 && strncasecmp (pszRealMsg, "SET ", 4)== 0 && - (strncasecmp (pszRealMsg+4, "USERSTATUS", 10)==0 || - strncasecmp (pszRealMsg+4, "CONNSTATUS", 10)==0)) - { -// if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S_Send: iLoginStat = %d\n", -// pInst->iLoginStat); - if (pInst->iLoginStat == 0) - { - if (pInst->myUser.pszUser && pInst->pszPass && strncasecmp (pszRealMsg+15, "OFFLINE", 7)) - { - Imo2S_Login(pInst, pInst->myUser.pszUser, pInst->pszPass, NULL); - } - } - else - { - HandleMessage (pInst, pszDup); - if (strncasecmp (pszRealMsg+15, "OFFLINE", 7) == 0) - Imo2S_Logout(pInst); - free (pszDup); - return 0; - } - } - if (pInst->iLoginStat != 1) return -1; - HandleMessage(pInst, pszDup); - free (pszDup); - return 0; -} - -// ----------------------------------------------------------------------------- -// Static -// ----------------------------------------------------------------------------- - - -static int StatusCallback (cJSON *pMsg, void *pUser) -{ - char *pszName; - BOOL bAdded; - cJSON *pContent, *pProto; - IMOSAPI *pInst = (IMOSAPI*)pUser; - int m, iSize = cJSON_GetArraySize(pMsg); - - if (pInst->fpLog) - { - char *pszMsg = cJSON_Print(pMsg); - fprintf (pInst->fpLog, "Imo2S::StatusCallback():%s\n", pszMsg); - free(pszMsg); - } - - for (m=0; mvaluestring; - - if ((pProto = cJSON_GetObjectItem(pContent,"proto")) && strcasecmp (pProto->valuestring, "prpl-skype")) - continue; - - if (!strcmp(pszName, "recv_im")) - { - // I got a message! - cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"); - - if (pEdata) - { - MSGENTRY *pMsg; - - // imo.im sometimes seems to send information about messages you sent yourself. - // We have to ignore them. - if (strcmp(cJSON_GetObjectItem(pEdata, "buid")->valuestring, pInst->myUser.pszUser) && - (pMsg = MsgQueue_Insert(pInst->hMsgQueue, pEdata))) - { - if (pInst->iFlags & IMO2S_FLAG_CURRTIMESTAMP) time(&pMsg->timestamp); - Send(pInst, "%sMESSAGE %d STATUS %s", pInst->iProtocol>=3?"CHAT":"", - pMsg->hdr.uMsgNr, pMsg->szStatus); - } - } - } - else if (!strcmp(pszName, "signed_on")) - { - // I just signed on. - cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"); - char *pszAlias; - - Send(pInst, "CONNSTATUS ONLINE"); - if (strcmp(pInst->myUser.szStatus, "OFFLINE")==0) - strcpy (pInst->myUser.szStatus, "ONLINE"); - Send(pInst, "USERSTATUS %s", pInst->myUser.szStatus); - if (pEdata && (pszAlias = cJSON_GetObjectItem(pEdata, "alias")->valuestring)) - { - pInst->myUser.pszAlias = strdup(pszAlias); - } - Send(pInst, "CURRENTUSERHANDLE %s", cJSON_GetObjectItem(pContent, "uid")->valuestring); - } - else if (!strcmp(pszName, "buddy_icon")) - { - // Here are the Avatars for the buddies - //We have to track them in a seperate list as the buddies may get populated lateron - cJSON *pArray = cJSON_GetObjectItem(pContent,"edata"), *pItem; - int i, iCount; - - if (pArray) - { - for (i=0, iCount = cJSON_GetArraySize(pArray); ihAvatarList, pItem); - } - } - } - else if (!strcmp(pszName, "disconnect")) - { - // I got disconnected (wrong user/pass?) - cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"); - //char *pszMsg; - - Send(pInst, "CONNSTATUS OFFLINE"); - Send(pInst, "USERSTATUS OFFLINE"); - strcpy (pInst->myUser.szStatus, "OFFLINE"); - /* - if (pEdata && (pszMsg = cJSON_GetObjectItem(pEdata, "msg")->valuestring)) - { - if (strcmp(pszMsg, "uidpassword")==0) - { - fprintf (stderr, "Invalid username / password combination!\n"); - } - } - */ - } - else if ((bAdded = !strcmp(pszName, "buddy_added")) || !strcmp(pszName, "buddy_status")) - { - // Here comes the contact list - cJSON *pArray = cJSON_GetObjectItem(pContent,"edata"), *pItem; - char *pszLastBUID = NULL, *pszLastGroup = NULL; - int i, iCount; - - if (pArray) - { - TYP_LIST *hListMemToAdd = NULL; - - for (i=0, iCount = cJSON_GetArraySize(pArray); ivaluestring; - cJSON *pGroup = cJSON_GetObjectItem(pItem, "group"); - cJSON *pDisplay = cJSON_GetObjectItem(pItem, "display"); - - if (bAdded) - { - /* - if (BuddyList_Find (pInst->hBuddyList, cJSON_GetObjectItem(pItem, "buid")->valuestring)) - bAdded=FALSE; - else - */ - BuddyList_Insert(pInst->hBuddyList, pItem); - } - else BuddyList_SetStatus(pInst->hBuddyList, pItem); - - if ((!pGroup || strcmp(pGroup->valuestring, "Skype")==0 || - strcmp(pGroup->valuestring, "Offline")==0) && - !pDisplay) - { - // Normal user, not groupchat, so output this - sprintf (szQuery, "GET USER %s ONLINESTATUS", pszBUID); - HandleMessage (pInst, szQuery); - sprintf (szQuery, "GET USER %s MOOD_TEXT", pszBUID); - HandleMessage (pInst, szQuery); - } - else - { - // Groupchat created/added - MSGENTRY * pMsgEntry = NULL; - - if (bAdded && pInst->pszBuddiesToAdd) - { - // Process pending ADDs - char *pTok, szQuery[256]; - - for (pTok = strtok(pInst->pszBuddiesToAdd, ", "); pTok; pTok=strtok(NULL, ", ")) - ImoSkype_GroupInvite(pInst->hInst, pszBUID, pTok); - free (pInst->pszBuddiesToAdd); - pInst->pszBuddiesToAdd = NULL; - sprintf (szQuery, "GET CHAT %s STATUS", pszBUID); - HandleMessage (pInst, szQuery); - } - else - { - if (bAdded || !pDisplay) - { - char szQuery[256], szGroup[256]={0}; - NICKENTRY *pChat; - - if (pGroup) sprintf (szGroup, "%s;", pGroup->valuestring); - if (pGroup && (pChat=BuddyList_Find(pInst->hBuddyList, szGroup)) && - pChat->hGCMembers) - { - sprintf (szQuery, "GET CHAT %s MEMBERS", szGroup); - HandleMessage (pInst, szQuery); - } - else - { - if ((bAdded || !pChat) && (!pszLastBUID || strcmp(pszLastBUID, pszBUID)) && - (!pszLastGroup || (pGroup && strcmp(pszLastGroup, pGroup->valuestring)))) - { - if (!hListMemToAdd) hListMemToAdd=List_Init(0); - List_Push(hListMemToAdd, pItem); - pszLastBUID = pszBUID; - if (pGroup) pszLastGroup = pGroup->valuestring; - } - } - } - /* - else - { - pMsgEntry = MsgQueue_AddEvent (pInst->hMsgQueue, pszBUID, "SETTOPIC"); - if (pDisplay->valuestring) pMsgEntry->pszMessage = strdup(pDisplay->valuestring); - } - */ - if (pMsgEntry) - Send(pInst, "%sMESSAGE %d STATUS %s", pInst->iProtocol>=3?"CHAT":"", - pMsgEntry->hdr.uMsgNr, pMsgEntry->szStatus); - - } - } - } - } - if (hListMemToAdd) - { - int nCount; - - for (i=0, nCount=List_Count(hListMemToAdd); ihMsgQueue, cJSON_GetObjectItem(pItem, "buid")->valuestring, "ADDEDMEMBERS")) // MULTI_SUBSCRIBED - { - if (pInviter) pMsgEntry->pszAuthor = strdup(pInviter->valuestring); - Send(pInst, "%sMESSAGE %d STATUS %s", pInst->iProtocol>=3?"CHAT":"", - pMsgEntry->hdr.uMsgNr, pMsgEntry->szStatus); - } - } - - List_Exit(hListMemToAdd); - hListMemToAdd = NULL; - } - if (bAdded && pInst->bFriendsPending) - { - char szMsg[]="SEARCH FRIENDS"; - pInst->bFriendsPending = 0; - HandleMessage (pInst, szMsg); - } - } - } - else if (!strcmp(pszName, "buddy_removed")) - { - // Here comes the contact list - cJSON *pArray = cJSON_GetObjectItem(pContent,"edata"), *pItem; - int i, iCount; - - if (pArray) - { - for (i=0, iCount = cJSON_GetArraySize(pArray); ivaluestring)) - { - NICKENTRY *pNick = BuddyList_Find (pInst->hBuddyList, pszUser); - - if (pNick && pNick->pGroup) - { - MSGENTRY *pMsg = MsgQueue_AddEvent (pInst->hMsgQueue, pszUser, "KICKED"); - cJSON *pUid = cJSON_GetObjectItem(pContent,"uid"); - if (pUid) pMsg->pszAuthor = strdup(pUid->valuestring); - Send(pInst, "%sMESSAGE %d STATUS %s", pInst->iProtocol>=3?"CHAT":"", - pMsg->hdr.uMsgNr, pMsg->szStatus); - } - else - Send (pInst, "USER %s BUDDYSTATUS 1", pszUser); - if (pNick) - BuddyList_Remove (pInst->hBuddyList, pNick); - } - } - } - } - else - if (/*!strcmp(pszName, "recv") || */!strcmp(pszName, "streams_info")) - { - cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"), - *pType = cJSON_GetObjectItem(pContent,"type"), *pVal; - - if (pType && pEdata) - { - if (strcasecmp(pType->valuestring, "call")==0 || strcasecmp(pType->valuestring, "video")==0 || - strcasecmp(pType->valuestring, "av")==0) - { - // Rring, rrring... - int iDirection = ((pVal = cJSON_GetObjectItem(pEdata, "is_initiator")) && pVal->type == cJSON_True)?CALL_OUTGOING:CALL_INCOMING; - CALLENTRY *pCall = CallQueue_Insert (pInst->hCallQueue, pEdata, iDirection); - if (pCall) - { - Send (pInst, "CALL %d STATUS %s", pCall->hdr.uMsgNr, pCall->szStatus); - if ((pInst->iFlags & IMO2S_FLAG_ALLOWINTERACT) && iDirection == CALL_OUTGOING) - StartCallSWF (pInst, pCall); - } - } - } - } - else - if (!strcmp(pszName, "ended")) - { - cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"), - *pType = cJSON_GetObjectItem(pContent,"type"); - - if (pType && pEdata) - { - if (strcasecmp(pType->valuestring, "call")==0 || strcasecmp(pType->valuestring, "video")==0) - { - // No call ID, so just hangup all calls to this user - int i, nCount = List_Count(pInst->hCallQueue); - char *pszUser = cJSON_GetObjectItem(pEdata, "buid")->valuestring; - - for (i=0; ihCallQueue, i); - - if (!strcmp(pCall->pszUser, pszUser) && strcmp (pCall->szStatus, "FINISHED")) - { - char szQuery[256]; - - sprintf (szQuery, "SET CALL %d STATUS FINISHED", pCall->hdr.uMsgNr); - HandleMessage (pInst, szQuery); - } - } - } - } - } - else - if (!strcmp(pszName, "reflect")) // Status reflections. We may want to support more of them in the future - { - cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"), - *pType = cJSON_GetObjectItem(pContent,"type"), *pRname, *pValue; - - if (pEdata && pType && (pRname = cJSON_GetObjectItem(pEdata,"r_name"))) - { - if (strcasecmp(pType->valuestring, "account") == 0) - { - if (strcasecmp (pRname->valuestring, "set_status") == 0 && - (pValue = cJSON_GetObjectItem(pEdata,"primitive")) ) - { - unsigned int i; - - for (i=0; ivaluestring)) - { - strcpy (pInst->myUser.szStatus, m_stMap[i].pszSkypeStat); - Send (pInst, "USERSTATUS %s", pInst->myUser.szStatus); - break; - } - } - - // Just ensure that on autoaway we notify imo.im that we are still there - if (!strcmp (pValue->valuestring, "away")) - ImoSkype_KeepAlive(pInst->hInst); - - if (pValue = cJSON_GetObjectItem(pEdata,"status")) - { - if (pInst->myUser.pszStatusText) free (pInst->myUser.pszStatusText); - pInst->myUser.pszStatusText = NULL; - if (*pValue->valuestring) - pInst->myUser.pszStatusText = strdup(pValue->valuestring); - } - - } - } - else - if (strcasecmp(pType->valuestring, "conv") == 0) - { - if (strcasecmp (pRname->valuestring, "send_im") == 0) - { - MSGENTRY *pMsg; - - if (pMsg = MsgQueue_AddReflect(pInst->hMsgQueue, pEdata, pInst->hBuddyList)) - { - if (pInst->iFlags & IMO2S_FLAG_CURRTIMESTAMP) time(&pMsg->timestamp); - Send(pInst, "%sMESSAGE %d STATUS %s", pInst->iProtocol>=3?"CHAT":"", - pMsg->hdr.uMsgNr, pMsg->szStatus); - } - } - - } - } - } - else - if (!strcmp(pszName, "expired") && m>=iSize-1) - { - // Session expired, so we have to reconnect - Send(pInst, "CONNSTATUS OFFLINE"); - Send(pInst, "USERSTATUS OFFLINE"); - strcpy (pInst->myUser.szStatus, "OFFLINE"); - pInst->iLoginStat = 0; - Dispatcher_Stop(pInst); - if (pInst->myUser.pszUser && pInst->pszPass) - Imo2S_Login(pInst, pInst->myUser.pszUser, pInst->pszPass, NULL); - } - else - if (!strcmp(pszName, "ack")) - { - MSGENTRY *pMsg; - cJSON *pRqId = cJSON_GetObjectItem(pContent,"request_id"); - - if (pRqId && (pMsg = MsgQueue_FindByRqId(pInst->hMsgQueue, pRqId->valueint))) - { - cJSON *pResp, *pTS; - - strcpy (pMsg->szStatus, "SENT"); - if ((pResp = cJSON_GetObjectItem(pContent,"response")) && - (pTS = cJSON_GetObjectItem(pResp,"timestamp"))) - pMsg->timestamp = pTS->valueint; - Send (pInst, "MESSAGE %d STATUS %s", pMsg->hdr.uMsgNr, pMsg->szStatus); - } - } - else - { - char *pszMsg = cJSON_Print(pMsg); - fprintf (stderr, "%s\n\n", pszMsg); - free (pszMsg); - } - } - return 0; -} - -// ----------------------------------------------------------------------------- - -#ifdef WIN32 -// Set call status to finished when closing phone applet window just in case -// there is no callback by imo.im upon closure -static LRESULT CallWndFilter(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) - { - case WM_DESTROY: - { - IMOSAPI *pInst = (IMOSAPI*)GetWindowLong (hWnd, GWL_PINST); - int i, nCount; - - if (!pInst) break; - for (i=0, nCount = List_Count(pInst->hCallQueue); ihCallQueue, i); - - if (pCall->hCallWnd == hWnd) - { - char szQuery[256]; - - sprintf (szQuery, "SET CALL %d STATUS FINISHED", pCall->hdr.uMsgNr); - HandleMessage (pInst, szQuery); - break; - } - } - break; - } - } - return CallWindowProc((WNDPROC)GetWindowLong (hWnd, GWL_ORIGWPRC), hWnd, message, wParam, lParam); -} -#endif - - -// ----------------------------------------------------------------------------- - -static int StartCallSWF (IMOSAPI *pInst, CALLENTRY *pCall) -{ - char szSWF[256], szFlashVars[1024], szID[18]; - char szHTML[2048]; - static unsigned int id=100; - - - /* The flash plugin basically opens rtmp://[host]/mchat in case of type=imo, otherwise rtmp://[host]/ivc - Maybe this can also be used with a SIP-phone or Asterisk? - */ -#ifndef WIN32 - FILE *fpTemp; - int iFound; - - sprintf (pCall->szCallFile, "xdg-open %s.html", tmpnam(NULL)); - if (!(fpTemp=fopen(pCall->szCallFile, "w"))) return -1; -#else - // Windows: - // Ensure that we are allowed to load the .swf from imo.im -#ifndef CSIDL_APPDATA -#define CSIDL_APPDATA 0x001a -#endif - static BOOL bInit = TRUE; - - if (bInit) - { - char szPath[MAX_PATH]={0}; - HMODULE hModule; - typedef HMODULE (__stdcall *SHGETFOLDERPATH)(HWND, int, HANDLE, DWORD, LPTSTR); - - if (hModule = LoadLibrary("SHFOLDER.DLL")) - { - SHGETFOLDERPATH fnShGetFolderPath = (SHGETFOLDERPATH)GetProcAddress(hModule, "SHGetFolderPathA"); - - if (fnShGetFolderPath && fnShGetFolderPath( NULL, CSIDL_APPDATA, NULL, 0, szPath)==S_OK) - { - strcat (szPath, "\\Macromedia\\Flash Player"); - if (GetFileAttributes (szPath) != 0xFFFFFFFF) - { - strcat (szPath, "\\#Security"); - _mkdir (szPath); - strcat (szPath, "\\FlashPlayerTrust"); - _mkdir (szPath); - strcat (szPath, "\\imo2sproxy.cfg"); - if (GetFileAttributes (szPath) == 0xFFFFFFFF) - { - FILE *fp = fopen (szPath, "w"); - - if (fp) - { - fputs ("https://imo.im/images/nchat.swf\nabout:blank\n", fp); - fclose (fp); - } - } - } - } - FreeLibrary(hModule); - } - bInit = FALSE; - } -#endif - sprintf (szSWF, "https://imo.im/images/nchat.swf?%s", IVC_VERSION); - ImoRq_CreateID (szID, 16); - //sprintf (szID, "imo%d", id++); - - if (*pCall->szSendStream) - sprintf (szFlashVars, - "type=skype&" - "send_stream=%s&" - "recv_stream=%s&" - "id=skype#%s&" - "host=video0.imo.im&" - "debug=conv net&" - "buddy_icon=https://imo.im/assets/main/icn_default.png&" - "setCookie=setCookie&" - "getCookie=getCookie&" - "removeCookie=removeCookie&" - "log=log&" - "init_callback=init_callback&" - "video_options_changed_cb=video_options_changed_cb&" - "options_changed_cb=options_changed_cb&" - "mic_changed_cb=mic_changed_cb&" - "cam_changed_cb=cam_changed_cb&" - "connection_status_cb=connection_status_cb", - pCall->szSendStream, pCall->szRecvStream, pCall->szSendStream); - else - return -1; - // sprintf (szFlashVars, "type=imo&conv=%s&role=%d&host=%s&id=%s", pCall->szConv, pCall->iRole, pCall->szIP, szID); - - strcat (szFlashVars, "&audio_only=true"); - // Currently not supported - sprintf (szHTML, "\n" - "" - "\n" - "\n" - "\n" - "\n" - "" - "\n" - "
\n" - "\n", - szSWF, szID, szSWF, szFlashVars); - -#ifdef WIN32 - //OutputDebugString (szHTML); - sprintf (szSWF, "Voicechat with %s", pCall->pszUser); - - /* - - { - FILE *fpOut = fopen("C:\\TEMP\\CALL.HTML", "w"); - - fputs (szHTML, fpOut); - fclose (fpOut); - system ("\"C:\\Programme\\Internet Explorer\\IEXPLORE.EXE\" C:\\TEMP\\CALL.HTML"); - } - */ - - if ((pCall->hCallWnd = W32Browser_ShowHTMLStr (szHTML,420, 280, szSWF))>0) - { - // Hook WndProc to handle WM_DESTROY so that we generate a CALL %d STATUS FINISHED on - // closing the chat window -#ifdef _WIN64 - SetWindowLongPtr ((HWND)pCall->hCallWnd, GWL_PINST, (LONG_PTR)pInst); - SetWindowLongPtr ((HWND)pCall->hCallWnd, GWL_ORIGWPRC, - GetWindowLongPtr ((HWND)pCall->hCallWnd, GWLP_WNDPROC)); - SetWindowLongPtr ((HWND)pCall->hCallWnd, GWLP_WNDPROC, (LONG_PTR)CallWndFilter); -#else - SetWindowLong ((HWND)pCall->hCallWnd, GWL_PINST, (LONG)pInst); - SetWindowLong ((HWND)pCall->hCallWnd, GWL_ORIGWPRC, GetWindowLong ((HWND)pCall->hCallWnd, GWL_WNDPROC)); - SetWindowLong((HWND)pCall->hCallWnd, GWL_WNDPROC, (LONG)CallWndFilter); -#endif - return 0; - } - return -1; -#else - fprintf (fpTemp, "%s", szHTML); - fclose (fpTemp); - iFound = system(pCall->szCallFile); - return (iFound == -1 || iFound == 127)?-1:0; -#endif -} - -// ----------------------------------------------------------------------------- - -static void DispatcherThread(void *pUser) -{ - IMOSAPI *pInst = (IMOSAPI*)pUser; - time_t t = 0, tcur; - - if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S::DispatcherThread() start\n"); - while (!pInst->iShuttingDown) - { -#if defined(WIN32) && defined(WIN32) - char szBuf[128]; - - sprintf (szBuf, "DispatcherThread %d loops.\n", GetCurrentThreadId()); - OutputDebugString (szBuf); -#endif - if (time(&tcur)>=t+300) - { - t=tcur; - //ImoSkype_Ping (pInst->hInst); - ImoSkype_KeepAlive(pInst->hInst); - } - - // Set status in case this is needed - if (pInst->tSetMoodText && tcur>=pInst->tSetMoodText) - { - int i; - - pInst->tSetMoodText = 0; - for (i=0; imyUser.szStatus)) - { - ImoSkype_SetStatus(pInst->hInst, m_stMap[i].pszImoStat, - pInst->myUser.pszStatusText?pInst->myUser.pszStatusText:""); - break; - } - } - } - ImoSkype_Poll(pInst->hInst); - } -} - -// ----------------------------------------------------------------------------- - -#ifdef WIN32 -static int Dispatcher_Start(IMOSAPI *pInst) -{ - DWORD ThreadID; - - if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S::Dispatcher_Start()\n"); - return (pInst->hThread=(thread_t)_beginthreadex(NULL, 0, - (unsigned(__stdcall *)(void*))DispatcherThread, pInst, 0, &ThreadID))!=0; - -} - -static int Dispatcher_Stop(IMOSAPI *pInst) -{ - int iRet, iOldShutdown; - - if (pInst->fpLog) - { - fprintf (pInst->fpLog, "Imo2S::Dispatcher_Stop()\n"); - fflush(pInst->fpLog); - } - - // Shutdown polling socket and wait some time if thread terminates - // gracefully, otherwise kill it - iOldShutdown = pInst->iShuttingDown; - pInst->iShuttingDown = 1; - ImoSkype_CancelPolling (pInst->hInst); - if (WaitForSingleObject (pInst->hThread, 2000) == WAIT_TIMEOUT) - iRet = TerminateThread (pInst->hThread, 0); - else iRet = 1; - pInst->iShuttingDown = iOldShutdown; - - if (iRet) - { - CloseHandle (pInst->hThread); - pInst->hThread = 0; - } - - if (pInst->fpLog) - { - fprintf (pInst->fpLog, "Imo2S::Dispatcher_Stop() done.\n"); - pInst->fpLog = NULL; - } - - return iRet; -} - -#else -static int Dispatcher_Start(IMOSAPI *pInst) -{ - if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S::Dispatcher_Start()\n"); - return pthread_create(&pInst->hThread, NULL, DispatcherThread, pInst)==0; -} - -static int Dispatcher_Stop(IMOSAPI *pInst) -{ - if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S::Dispatcher_Stop()\n"); - if (pthread_cancel(pInst->hThread)) - { - pInst->hThread=0; - return 1; - } - return 0; -} -#endif - -// ----------------------------------------------------------------------------- - -static void Send(IMOSAPI *pInst, const char *pszMsg, ...) -{ - va_list ap; - int iLen, iLenCmdID; - char *pszLogBuf = pInst->pszLogBuf; - int cbBuf = pInst->cbBuf; - - iLenCmdID = pInst->pszCmdID?strlen(pInst->pszCmdID)+1:0; - do - { - cbBuf = pInst->cbBuf - iLenCmdID; - pszLogBuf = pInst->pszLogBuf + iLenCmdID; - va_start(ap, pszMsg); - iLen = vsnprintf (pszLogBuf, cbBuf, pszMsg, ap); - va_end(ap); -#ifndef WIN32 - if (iLen>=cbBuf) iLen=-1; -#endif - if (iLen == -1) - { - char *pNewBuf; - - if (!(pNewBuf = realloc(pInst->pszLogBuf, pInst->cbBuf*2))) - { - break; - } - pInst->cbBuf*=2; - pInst->pszLogBuf = pNewBuf; - } - } while (iLen == -1); - if (pInst->pszCmdID && iLenCmdID>1) - { - memcpy (pInst->pszLogBuf, pInst->pszCmdID, iLenCmdID); - pInst->pszLogBuf[iLenCmdID-1]=' '; - } - -//printf ("%s\n", szBuf); - pInst->Callback(pInst->pszLogBuf, pInst->pUser); -} - -// ----------------------------------------------------------------------------- - -static void HandleMessage(IMOSAPI *pInst, char *pszMsg) -{ - char *pszCmd=strtok(pszMsg, " "); - - if (!pInst || !pszCmd || !pInst->hInst) return; - if (*pszCmd=='#') - { - // This is a PROTOCOL 4 feature, but we will support it just in case... - pInst->pszCmdID = pszCmd; - if (!(pszCmd=strtok(NULL, " "))) - { - pInst->pszCmdID = NULL; - return; - } - } - else pInst->pszCmdID = NULL; - - if (strcasecmp(pszCmd, "PROTOCOL") == 0) - { - if (pszCmd = strtok(NULL, " ")) - { - pInst->iProtocol = atoi(pszCmd); - if (pInst->iProtocol>3) pInst->iProtocol=3; - } - - Send (pInst, "PROTOCOL %d", pInst->iProtocol); - return; - } - else - if (strcasecmp(pszCmd, "PING") == 0) - { - Send (pInst, "PONG"); - return; - } - else - if (strcasecmp(pszCmd, "SEARCH") == 0) - { - TYP_FIFO *hFifo; - - if (!(pszCmd = strtok(NULL, " "))) - { - Send (pInst, "ERROR 2 Invalid command"); - return; - } - - if (strcasecmp(pszCmd, "FRIENDS") == 0) - { - unsigned int nCount =List_Count(pInst->hBuddyList); - - if (!nCount) - { - pInst->bFriendsPending = 1; - return; - } - if(hFifo=Fifo_Init(512)) - { - unsigned int i; - char *pszUsers; - - for (i=0; ihBuddyList, i); - if (!pEntry->pGroup && !pEntry->hGCMembers) - { - if (i>0) Fifo_AddString (hFifo, ", "); - Fifo_AddString (hFifo, pEntry->pszUser); - } - } - if (pszUsers = Fifo_Get(hFifo, NULL)) - Send (pInst, "USERS %s", pszUsers); - else - pInst->bFriendsPending = 1; - Fifo_Exit(hFifo); - } - } - else if (strcasecmp(pszCmd, "MISSEDMESSAGES") == 0) - { - unsigned int nCount=List_Count(pInst->hMsgQueue); - - if(nCount && (hFifo=Fifo_Init(512))) - { - unsigned int i, j=0; - - for (i=0; ihMsgQueue, i); - char szNr[32]; - - if (!strcmp(pEntry->szStatus, "RECEIVED")) - { - if (j>0) Fifo_AddString (hFifo, ", "); - sprintf (szNr, "%d", pEntry->hdr.uMsgNr); - Fifo_AddString (hFifo, szNr); - j++; - } - } - Send (pInst, "MESSAGES %s", Fifo_Get(hFifo, NULL)); - Fifo_Exit(hFifo); - } - } - else if (strcasecmp(pszCmd, "USERS") == 0) - { - // There is no possibility to search Skype users in imo.im - // therefore just return that the user exists even if it doesn't :( - Send (pInst, "USERS %s", pszCmd+6); - // We add the user as a temporary contact to our list so that the - // client can get the empty properties and set the buddystatus. - BuddyList_AddTemporaryUser (pInst->hBuddyList, pszCmd+6); - } - else if (strcasecmp(pszCmd, "USERSWAITINGMYAUTHORIZATION") == 0) - { - Send (pInst, "USERS"); - } - else if (strcasecmp(pszCmd, "ACTIVECALLS") == 0) - { - char szCalls[512]; - int i, nCount, iOffs=0; - - iOffs = sprintf (szCalls, "CALLS"); - for (i=0, nCount=List_Count(pInst->hCallQueue); ihCallQueue, i))->hdr.uMsgNr); - if (iOffs+6>=sizeof(szCalls)) break; - } - Send (pInst, szCalls); - } - else if (strcasecmp(pszCmd, "RECENTCHATS") == 0) - { - char szChats[2056]; - int i, nCount, iOffs=0, j=0; - - iOffs = sprintf (szChats, "CHATS "); - for (i=0, nCount=List_Count(pInst->hBuddyList); ihBuddyList, i); - - if (BuddyList_IsGroupchat(pChat)) - { - if (j) iOffs+=sprintf(&szChats[iOffs], ", "); - iOffs+=sprintf(&szChats[iOffs], "%s", pChat->pszUser); - if (iOffs+6>=sizeof(szChats)) break; - j++; - } - } - Send (pInst, szChats); - } - return; - } - else - if (strcasecmp(pszCmd, "GET") == 0) - { - if (!(pszCmd = strtok(NULL, " "))) - { - Send (pInst, "ERROR 7 Invalid property"); - return; - } - - if (strcasecmp(pszCmd, "USER") == 0) - { - NICKENTRY *pUser = NULL; - - if (pszCmd = strtok(NULL, " ")) - { - if (!strcasecmp (pszCmd, pInst->myUser.pszUser)) - pUser = &pInst->myUser; - else - pUser = BuddyList_Find(pInst->hBuddyList, pszCmd); - } - - if (!pUser) - { - Send (pInst, "ERROR 26 Invalid user handle"); - return; - } - if (!(pszCmd = strtok(NULL, " "))) - { - Send (pInst, "ERROR 10 Invalid property"); - return; - } - - if (!strcasecmp (pszCmd, "HANDLE")) - { - if (pUser->pszAlias) Send (pInst, "USER %s HANDLE %s", pUser->pszUser, pUser->pszAlias); - } - else if (!strcasecmp (pszCmd, "FULLNAME")) /* Workaround */ - Send (pInst, "USER %s FULLNAME %s", pUser->pszUser, pUser->pszAlias); - else if (!strcasecmp (pszCmd, "DISPLAYNAME")) - Send (pInst, "USER %s DISPLAYNAME %s", pUser->pszUser, pUser->pszAlias); - else if (!strcasecmp (pszCmd, "HASCALLEQUIPMENT")) - Send (pInst, "USER %s HASCALLEQUIPMENT TRUE", pUser->pszUser); - else if (!strcasecmp (pszCmd, "BUDDYSTATUS")) - Send (pInst, "USER %s BUDDYSTATUS %d", pUser->pszUser, pUser->iBuddyStatus); - else if (!strcasecmp (pszCmd, "ISAUTHORIZED")) - Send (pInst, "USER %s ISAUTHORIZED TRUE", pUser->pszUser); - else if (!strcasecmp (pszCmd, "MOOD_TEXT")) - Send (pInst, "USER %s MOOD_TEXT %s", pUser->pszUser, - pUser->pszStatusText?pUser->pszStatusText:""); - else if (!strcasecmp (pszCmd, "SEX")) - Send (pInst, "USER %s SEX UNKNOWN", pUser->pszUser); - else if (!strcasecmp (pszCmd, "BIRTHDAY")) - Send (pInst, "USER %s BIRTHDAY 0", pUser->pszUser); - else if (!strcasecmp (pszCmd, "ONLINESTATUS")) - { - unsigned int i; - - for (i=0; iszStatus)) - { - Send (pInst, "USER %s ONLINESTATUS %s", pUser->pszUser, m_stMap[i].pszSkypeStat); - break; - } - } - } - else if (!strcasecmp (pszCmd, "AVATAR")) - { - char *pszFile, *pAvatarBuf; - unsigned int dwLength; - AVATARENTRY *pAvatar; - FILE *fp; - - if (!(pszFile = strtok(NULL, " ")) || strcasecmp (pszFile, "1")) - { - Send (pInst, "ERROR 116 GET invalid ID"); - return; - } - if (!(pszFile = strtok(NULL, "\n"))) - { - Send (pInst, "ERROR 7 GET: invalid WHAT"); - return; - } - if (fp=fopen(pszFile, "r")) - { - fseek (fp, 0, SEEK_END); - if (ftell(fp)) - { - fclose(fp); - Send (pInst, "ERROR 124 GET Destination file is not empty"); - return; - } - fclose(fp); - } - if (!(pAvatar = AvatarList_Find(pInst->hAvatarList, pUser->pszUser)) || - !(pAvatarBuf = ImoSkype_GetAvatar (pInst->hInst, pAvatar->pszIcon, &dwLength))) - { - // FIXME: Normally we should return default avatar if pAvatar is NULL. - // Default avatar from imo.im is PNG, but JPEG is expected, so we - // return an error here - Send (pInst, "ERROR 122 GET Unable to load avatar"); - return; - } - if (!(fp=fopen(pszFile, -#ifdef WIN32 - "wb" -#else - "w" -#endif - ))) - { - Send (pInst, "ERROR 121 GET File path doesn't exist"); - return; - } - fwrite (pAvatarBuf, dwLength, 1, fp); - fclose (fp); - Send (pInst, "USER %s AVATAR 1 %s", pUser->pszUser, pszFile); - } - else - { - Send(pInst, "ERROR 10 Invalid propery"); - } - return; - } - else - if (strcasecmp(pszCmd, "CURRENTUSERHANDLE") == 0) - { - if (pInst->myUser.pszUser) - Send(pInst, "CURRENTUSERHANDLE %s", pInst->myUser.pszUser); - } - else - if (strcasecmp(pszCmd, "USERSTATUS") == 0) - { - Send(pInst, "USERSTATUS %s", pInst->myUser.szStatus); - } - else - if (strcasecmp(pszCmd, "MESSAGE") == 0 || strcasecmp(pszCmd, "CHATMESSAGE") == 0) - { - MSGENTRY *pEntry; - char *pszMessage = pszCmd; - - if (!(pszCmd = strtok(NULL, " ")) || !(pEntry = MsgQueue_Find(pInst->hMsgQueue, atol(pszCmd)))) - { - Send (pInst, "ERROR 14 Invalid message id"); - return; - } - if (!(pszCmd = strtok(NULL, " "))) - { - Send (pInst, "ERROR 10 Invalid property"); - return; - } - if (!strcasecmp (pszCmd, "TIMESTAMP")) - Send (pInst, "%s %d TIMESTAMP %ld", pszMessage, pEntry->hdr.uMsgNr, pEntry->timestamp); - else if (!strcasecmp (pszCmd, "PARTNER_HANDLE") || !strcasecmp (pszCmd, "FROM_HANDLE")) - { - char *pszUser = strdup(pEntry->pszAuthor?pEntry->pszAuthor:pEntry->pszUser), *p, *pszRealUser=pszUser; - - if (p=strtok(pszUser, ";")) - { - if (!(pszRealUser=strtok(NULL, ";"))) pszRealUser=p; - } - Send (pInst, "%s %d %s %s", pszMessage, pEntry->hdr.uMsgNr, pszCmd, pszRealUser); - free (pszUser); - } - else if (!strcasecmp (pszCmd, "PARTNER_DISPNAME")) - Send (pInst, "%s %d PARTNER_DISPNAME %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->pszAlias); - else if (!strcasecmp (pszCmd, "TYPE")) - Send (pInst, "%s %d TYPE %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->szType); - else if (!strcasecmp (pszCmd, "STATUS")) - Send (pInst, "%s %d STATUS %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->szStatus); - else if (!strcasecmp (pszCmd, "FAILUREREASON")) - Send (pInst, "%s %d FAILUREREASON %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->szFailure); - else if (!strcasecmp (pszCmd, "BODY")) - Send (pInst, "%s %d BODY %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->pszMessage); - else if (!strcasecmp (pszCmd, "CHATNAME")) - { - if (pEntry->pszAuthor || !pEntry->pszMessage || strchr(pEntry->pszUser, ';')) // Groupchat - { - char *pszUser = strdup(pEntry->pszUser), *p; - - if (p=strchr(pszUser, ';')) p[1]=0; - Send (pInst, "%s %d CHATNAME %s", pszMessage, pEntry->hdr.uMsgNr, pszUser); - free (pszUser); - } - else - Send (pInst, "%s %d CHATNAME #%s/$%s", pszMessage, pEntry->hdr.uMsgNr, pInst->myUser.pszUser, pEntry->pszUser); - } - else if (!strcasecmp (pszCmd, "USERS")) - { - // On KICK, this is the user who GOT kicked - char *pszUser = strchr(pEntry->pszUser, ';'); - if (pszUser) pszUser++; else pszUser=pEntry->pszUser; - Send (pInst, "%s %d USERS %s", pszMessage, pEntry->hdr.uMsgNr, pszUser); - } - else - Send (pInst, "ERROR 10 Invalid property / not implemented"); - return; - } - else - if (strcasecmp(pszCmd, "PRIVILEGE") == 0) - { - if (!(pszCmd = strtok(NULL, " ")) || - (strcasecmp (pszCmd, "SKYPEOUT") && - strcasecmp (pszCmd, "SKYPEIN") && - strcasecmp (pszCmd, "VOICEMAIL"))) - { - Send (pInst, "ERROR 40 Unknown Privilege"); - return; - } - Send (pInst, "PRIVILEGE %s FALSE", pszCmd); - return; - } - else - if (strcasecmp(pszCmd, "CHAT") == 0) - { - char *pszChat; - NICKENTRY *pChat=NULL; - - // A $ sign is in the name of a dialog, otherwise it's a groupchat ID - if (!(pszChat = strtok(NULL, " ")) || - (!strchr(pszChat, '$') && !(pChat=BuddyList_Find(pInst->hBuddyList, pszChat)))) - { - Send (pInst, "ERROR 14 Invalid message id"); - return; - } - - - if (!(pszCmd = strtok(NULL, " "))) - { - Send (pInst, "ERROR 10 Invalid property"); - return; - } - - if (strcasecmp(pszCmd, "NAME") == 0) - Send (pInst, "CHAT %s NAME %s", pszChat, pszChat); - else if (strcasecmp(pszCmd, "STATUS") == 0) - // A $ sign is in the name of a dialog, otherwise it's a groupchat ID - Send (pInst, "CHAT %s STATUS %s", pszChat, pChat?"MULTI_SUBSCRIBED":"LEGACY_DIALOG"); - else if (strcasecmp(pszCmd, "ADDER") == 0) - Send (pInst, "CHAT %s ADDER %s", pszChat, pInst->myUser.pszUser); - else if (strcasecmp(pszCmd, "TYPE") == 0) - Send (pInst, "CHAT %s TYPE %s", pszChat, pChat?"MULTICHAT":"DIALOG"); - else if (strcasecmp(pszCmd, "MYROLE") == 0) - Send (pInst, "CHAT %s MYROLE USER", pszChat); - else if (strcasecmp(pszCmd, "MYSTATUS") == 0) - Send (pInst, "CHAT %s MYSTATUS SUBSCRIBED", pszChat); - else if ((strcasecmp(pszCmd, "TOPIC") == 0 || strcasecmp(pszCmd, "FRIENDLYNAME") == 0) && pChat) - Send (pInst, "CHAT %s %s %s", pszChat, pszCmd, pChat->pszDisplay); - else if ((strcasecmp(pszCmd, "ACTIVEMEMBERS") == 0 || strcasecmp(pszCmd, "MEMBERS") == 0) && pChat) - { - char szMembers[1024]={0}; - int i, nCount, iOffs=0; - - iOffs = sprintf (szMembers, "CHAT %s %s ", pszChat, pszCmd); - for (i=0, nCount=List_Count(pChat->hGCMembers); ihGCMembers, i); - char szUser[512], *pTok; - - if (i) iOffs+=sprintf(&szMembers[iOffs], " "); - strcpy (szUser, pMemb->pszUser); - pTok=strtok(szUser, ";"); - pTok=strtok(NULL, ";"); - iOffs+=sprintf(&szMembers[iOffs], "%s", pTok); - if (iOffs+6>=sizeof(szMembers)) break; - } - Send (pInst, szMembers); - } - else - Send(pInst, "ERROR 7 Invalid property / not implemented"); - return; - } - else - if (strcasecmp(pszCmd, "CALL") == 0) - { - CALLENTRY *pEntry; - - if (!(pszCmd = strtok(NULL, " ")) || !(pEntry = CallQueue_Find(pInst->hCallQueue, atol(pszCmd)))) - { - Send (pInst, "ERROR 11 Invalid call id"); - return; - } - if (!(pszCmd = strtok(NULL, " "))) - { - Send (pInst, "ERROR 10 Invalid property"); - return; - } - if (!strcasecmp (pszCmd, "TIMESTAMP")) - Send (pInst, "CALL %d TIMESTAMP %ld", pEntry->hdr.uMsgNr, pEntry->timestamp); - else if (!strcasecmp (pszCmd, "PARTNER_HANDLE")) - Send (pInst, "CALL %d PARTNER_HANDLE %s", pEntry->hdr.uMsgNr, pEntry->pszUser); - else if (!strcasecmp (pszCmd, "PARTNER_DISPNAME")) - { - NICKENTRY *pNick = BuddyList_Find (pInst->hBuddyList, pEntry->pszUser); - - if (pNick) - Send (pInst, "CALL %d PARTNER_DISPNAME %s", pEntry->hdr.uMsgNr, pNick->pszAlias); - } - else if (!strcasecmp (pszCmd, "CONF_ID")) - Send (pInst, "CALL %d CONF_ID 0", pEntry->hdr.uMsgNr); - else if (!strcasecmp (pszCmd, "TYPE")) - Send (pInst, "CALL %d TYPE %s", pEntry->hdr.uMsgNr, pEntry->iDirection==CALL_INCOMING?"INCOMING_P2P":"OUTGOING_P2P"); - else if (!strcasecmp (pszCmd, "STATUS")) - Send (pInst, "CALL %d STATUS %s", pEntry->hdr.uMsgNr, pEntry->szStatus); - else if (!strcasecmp (pszCmd, "VIDEO_STATUS")) - Send (pInst, "CALL %d VIDEO_STATUS VIDEO_NONE", pEntry->hdr.uMsgNr); - else if (!strcasecmp (pszCmd, "VIDEO_SEND_STATUS") || !strcasecmp (pszCmd, "VIDEO_RECEIVE_STATUS")) - Send (pInst, "CALL %d %s NOT_AVAILABLE", pEntry->hdr.uMsgNr, pszCmd); - else if (!strcasecmp (pszCmd, "FAILUREREASON")) - Send (pInst, "CALL %d FAILUREREASON UNKNOWN", pEntry->hdr.uMsgNr); - else if (!strcasecmp (pszCmd, "DURATION")) - Send (pInst, "CALL %d DURATION 0", pEntry->hdr.uMsgNr); - else if (!strcasecmp (pszCmd, "CONF_PARTICIPANTS_COUNT")) - Send (pInst, "CALL %d CONF_PARTICIPANTS_COUNT 0", pEntry->hdr.uMsgNr); - else - Send (pInst, "ERROR 10 Invalid property / not implemented"); - return; - } - else - if (strcasecmp(pszCmd, "SKYPEVERSION") == 0) - { - Send (pInst, "SKYPEVERSION 3.8.0.188"); // Fake - } - else - { - Send(pInst, "ERROR 7 Invalid property / not implemented"); - } - return; - } - else - if (strcasecmp(pszCmd, "SET") == 0) - { - if (!(pszCmd = strtok(NULL, " "))) - { - Send (pInst, "ERROR 7 Invalid property"); - return; - } - - if (strcasecmp(pszCmd, "USER") == 0) - { - char *pszUser; - NICKENTRY *pUser = NULL; - - if (!(pszUser = strtok(NULL, " "))) - { - Send (pInst, "ERROR 26 Invalid user handle"); - return; - } - - if (!(pszCmd = strtok(NULL, " "))) - { - Send (pInst, "ERROR 7 Invalid property"); - return; - } - - pUser = BuddyList_Find(pInst->hBuddyList, pszUser); - - if (strcasecmp(pszCmd, "BUDDYSTATUS") == 0) - { - int iStatus = -1; - - if (pszCmd = strtok(NULL, " ")) - iStatus = atoi(pszCmd); - - if (!pUser && iStatus < 2) - { - Send (pInst, "ERROR 26 Invalid user handle"); - return; - } - if (iStatus == 2 || (iStatus > 2 && !pUser) || iStatus != pUser->iBuddyStatus) - { - switch (iStatus) - { - case 1: - if (ImoSkype_DelBuddy (pInst->hInst, pUser->pszUser, - strcmp(pUser->szStatus, "OFFLINE")?"Skype":"Offline") == 1) - pUser->iBuddyStatus = iStatus; - break; - case 2: - case 3: - ImoSkype_AddBuddy (pInst->hInst, pszUser); - return; - default: - Send (pInst, "ERROR 518 Invalid status given for BUDDYSTATUS"); - return; - } - } - Send (pInst, "USER %s BUDDYSTATUS %d", pUser->pszUser, pUser->iBuddyStatus); - return; - } - else if (!pUser) - { - Send (pInst, "ERROR 26 Invalid user handle"); - return; - } - else - { - // ISAUTHORIZED - Send (pInst, "ERROR 7 Not implemented"); - } - } - else - if (strcasecmp(pszCmd, "USERSTATUS") == 0) - { - unsigned int i; - - if (!(pszCmd = strtok(NULL, " "))) - { - Send (pInst, "ERROR 28 Unknown userstatus"); - return; - } - - if (strcasecmp(pInst->myUser.szStatus, pszCmd)) - { - for (i=0; itSetMoodText = 0; - if (ImoSkype_SetStatus(pInst->hInst, m_stMap[i].pszImoStat, - pInst->myUser.pszStatusText?pInst->myUser.pszStatusText:"")>0) - strcpy (pInst->myUser.szStatus, pszCmd); - Send (pInst, "USERSTATUS %s", pInst->myUser.szStatus); - break; - } - } - if (i==sizeof(m_stMap)/sizeof(m_stMap[0])) - Send (pInst, "ERROR 28 Unknown userstatus"); - } else Send (pInst, "USERSTATUS %s", pInst->myUser.szStatus); - return; - } - else - if (strcasecmp(pszCmd, "MESSAGE") == 0 || strcasecmp(pszCmd, "CHATMESSAGE") == 0) - { - MSGENTRY *pEntry; - char *pszMessage = pszCmd; - - if (!(pszCmd = strtok(NULL, " ")) || !(pEntry = MsgQueue_Find(pInst->hMsgQueue, atol(pszCmd)))) - { - Send (pInst, "ERROR 14 Invalid message id"); - return; - } - if (!(pszCmd = strtok(NULL, " "))) - { - Send (pInst, "ERROR 10 Invalid property"); - return; - } - if (!strcasecmp (pszCmd, "SEEN")) - { - strcpy (pEntry->szStatus, "READ"); - Send (pInst, "%s %d STATUS %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->szStatus); - } - else - Send (pInst, "ERROR 10 Invalid property / not implemented"); - return; - } - else - if (strcasecmp(pszCmd, "CALL") == 0) - { - CALLENTRY *pEntry; - - if (!(pszCmd = strtok(NULL, " ")) || !(pEntry = CallQueue_Find(pInst->hCallQueue, atol(pszCmd)))) - { - Send (pInst, "ERROR 11 Invalid call id"); - return; - } - if (!(pszCmd = strtok(NULL, " "))) - { - Send (pInst, "ERROR 10 Invalid property"); - return; - } - if (!strcasecmp (pszCmd, "STATUS")) - { - if (!(pszCmd = strtok(NULL, " "))) - { - Send (pInst, "ERROR 21 Unknown/disallowed call prop"); - return; - } - strcpy (pEntry->szStatus, pszCmd); - Send (pInst, "CALL %d STATUS %s", pEntry->hdr.uMsgNr, pEntry->szStatus); - - // {RINGING, INPROGRESS, ONHOLD, FINISHED} - if (pInst->iFlags & IMO2S_FLAG_ALLOWINTERACT) - { - if (strcasecmp (pEntry->szStatus, "INPROGRESS") == 0 && pEntry->iDirection == CALL_INCOMING) - { - StartCallSWF (pInst, pEntry); - } - else - if (strcasecmp (pEntry->szStatus, "FINISHED") == 0 && pEntry->hCallWnd) - { - if (*pEntry->szCallFile) - { - unlink(pEntry->szCallFile); - *pEntry->szCallFile=0; - } -#ifdef WIN32 - if (pEntry->hCallWnd) - { - W32Browser_CloseWindow (pEntry->hCallWnd); - pEntry->hCallWnd = NULL; - } -#endif - - // On incoming call, hang up - } - } - - // Currently we don't support calls, just hang up - /* FIXME: Hangup! */ - return; - } - return; - } - else - if (strcasecmp(pszCmd, "PROFILE") == 0) - { - if (!(pszCmd = strtok(NULL, " "))) - { - Send (pInst, "ERROR 10 Invalid property"); - return; - } - - if (!strcasecmp (pszCmd, "MOOD_TEXT")) - { - if (!pInst->myUser.pszStatusText || - strcasecmp(pInst->myUser.pszStatusText, pszCmd+10)) - { - time_t t; - // Delay setting of MOOD_TEXT, as next command in chain may change online status - // and we want to prevent double calls - // The polling-thread will take care of this event - pInst->tSetMoodText = time(&t)+15; - if (pInst->myUser.pszStatusText) free (pInst->myUser.pszStatusText); - pInst->myUser.pszStatusText = strdup (pszCmd+10); - } - } - else - { - Send (pInst, "ERROR 552 Invalid property"); - return; - } - } - else - { - Send (pInst, "ERROR 7 Invalid property"); - return; - } - } - else - if (strcasecmp(pszCmd, "MESSAGE") == 0 || strcasecmp(pszCmd, "CHATMESSAGE") == 0) - { - NICKENTRY *pUser; - unsigned int uMsgId; - MSGENTRY *pMsg; - - if (!(pszCmd = strtok(NULL, " ")) || !(pUser = BuddyList_Find(pInst->hBuddyList, pszCmd))) - { - Send (pInst, "ERROR 26 Invalid user handle"); - return; - } - pszCmd+=strlen(pszCmd)+1; - if (!*pszCmd) - { - Send (pInst, "ERROR 43 Cannot send empty message"); - return; - } - if (!(pMsg = MsgQueue_AddSent (pInst->hMsgQueue, pUser->pszUser, pUser->pszAlias, pszCmd, &uMsgId))) - { - Send (pInst, "ERROR 9901 Internal error"); - return; - } - if (IMO_API_VERSION == 0) Send (pInst, "MESSAGE %d STATUS SENDING", uMsgId); - if (ImoSkype_SendMessage(pInst->hInst, pUser->pszUser, pszCmd, &pMsg->uRqId)>0) - { - if (IMO_API_VERSION == 0) strcpy (pMsg->szStatus, "SENT"); - } - else - { - strcpy (pMsg->szStatus, "FAILED"); - strncpy (pMsg->szFailure, ImoSkype_GetLastError(pInst->hInst), sizeof(pMsg->szFailure)); - } - Send (pInst, "MESSAGE %d STATUS %s", uMsgId, pMsg->szStatus); - } - else - if (strcasecmp(pszCmd, "CHAT") == 0) - { - if (!(pszCmd = strtok(NULL, " "))) - { - Send (pInst, "ERROR 536 CREATE: no object or type given"); - return; - } - if (strcasecmp(pszCmd, "CREATE") == 0) - { - char szName[128]; // No name given here, so make up a name - time_t t; - - time(&t); - sprintf (szName, "%d", t); - if (ImoSkype_CreateSharedGroup(pInst->hInst, szName)<1) return; - - // Now buddy_added should be called which gives us the ID of the new groupchat - // where we can then add members to. However this is not known here yet, so feed - // list with users to add to instance and let it be processed by buddy_added handler - if (pszCmd = strtok(NULL, "\n")) - { - if (pInst->pszBuddiesToAdd) free(pInst->pszBuddiesToAdd); - pInst->pszBuddiesToAdd = strdup(pszCmd); - } - } - else - Send (pInst, "ERROR 503 CHAT: Invalid or unknown action"); - return; - } - else - if (strcasecmp(pszCmd, "CALL") == 0) - { - NICKENTRY *pUser; - - if (!(pszCmd = strtok(NULL, " ")) || !(pUser = BuddyList_Find(pInst->hBuddyList, pszCmd))) - { - Send (pInst, "ERROR 26 Invalid user handle"); - return; - } - - ImoSkype_StartVoiceCall (pInst->hInst, pUser->pszUser); - return; - } - else - if (strcasecmp(pszCmd, "OPEN") == 0) - { - return; - } - else - if (strcasecmp(pszCmd, "CREATE") == 0) - { - if (!(pszCmd = strtok(NULL, " "))) - { - Send (pInst, "ERROR 536 CREATE: no object or type given"); - return; - } - if (strcasecmp(pszCmd, "APPLICATION") == 0) - { - if (!(pszCmd = strtok(NULL, " ")) || strcasecmp(pszCmd, "libpurple_typing")) - Send (pInst, "ERROR 540 CREATE APPLICATION: Missing or invalid name"); - else - Send (pInst, "CREATE APPLICATION libpurple_typing"); - } - else - Send (pInst, "ERROR 537 CREATE: Unknown object type given"); - return; - } - else - if (strcasecmp(pszCmd, "DELETE") == 0) - { - if (!(pszCmd = strtok(NULL, " "))) - { - Send (pInst, "ERROR 538 DELETE: no object or type given"); - return; - } - if (strcasecmp(pszCmd, "APPLICATION") == 0) - { - if (!(pszCmd = strtok(NULL, " ")) || strcasecmp(pszCmd, "libpurple_typing")) - Send (pInst, "ERROR 542 DELETE APPLICATION: Missing or invalid application name"); - else - Send (pInst, "DELETE APPLICATION libpurple_typing"); - } - else - Send (pInst, "ERROR 539 DELETE: Unknown object type given"); - return; - } - else - if (strcasecmp(pszCmd, "ALTER") == 0) - { - if (!(pszCmd = strtok(NULL, " "))) - Send (pInst, "ERROR 526 ALTER: no object type given"); - else - { - if (strcasecmp(pszCmd, "APPLICATION") == 0) - { - if (!(pszCmd = strtok(NULL, " ")) || strcasecmp(pszCmd, "libpurple_typing") || - !(pszCmd = strtok(NULL, " "))) - Send (pInst, "ERROR 545 ALTER: missing or invalid action"); - else - { - NICKENTRY *pUser; - - if (strcasecmp (pszCmd, "CONNECT") == 0) - { - if (!(pszCmd = strtok(NULL, " ")) || !(pUser = BuddyList_Find(pInst->hBuddyList, pszCmd))) - Send (pInst, "ERROR 547 ALTER APPLICATION CONNECT: Invalid user handle"); - else - { - Send (pInst, "ALTER APPLICATION libpurple_typing CONNECT %s", pszCmd); - Send (pInst, "APPLICATION CONNECTING %s", pszCmd); - Send (pInst, "APPLICATION libpurple_typing STREAMS %s:1", pszCmd); - // FIXME: Shouldn't we enumerate all STREAMS here? dunno... - } - } else - if (strcasecmp (pszCmd, "DATAGRAM") == 0) - { - char *pSep; - - if (!(pszCmd = strtok(NULL, " ")) || !(pSep = strchr(pszCmd, ':'))) - Send (pInst, "ERROR 551 ALTER APPLICATION DATAGRAM: Missing or invalid stream identifier"); - else - { - *pSep=0; - if (!(pUser = BuddyList_Find(pInst->hBuddyList, pszCmd))) - Send (pInst, "ERROR 551 ALTER APPLICATION DATAGRAM: Missing or invalid stream identifier"); - else - { - *pSep=':'; - if (!(pszCmd = strtok(NULL, " "))) - Send (pInst, "ERROR 541 APPLICATION: Operation failed"); - else - { - if (!strcmp (pszCmd, "PURPLE_TYPING")) - ImoSkype_Typing (pInst->hInst, pUser->pszUser, "typing"); - else if (!strcmp (pszCmd, "PURPLE_TYPED")) - ImoSkype_Typing (pInst->hInst, pUser->pszUser, "typed"); - else if (!strcmp (pszCmd, "PURPLE_NOT_TYPING")) - ImoSkype_Typing (pInst->hInst, pUser->pszUser, "not_typing"); - } - } - } - } - } - - } - else - if (strcasecmp(pszCmd, "CHAT") == 0) - { - char *pszChat; - NICKENTRY *pChat; - - if (!(pszChat = strtok(NULL, " ")) || - !(pChat=BuddyList_Find(pInst->hBuddyList, pszChat))) - { - Send (pInst, "ERROR 14 Invalid message id"); - return; - } - - - if (!(pszCmd = strtok(NULL, " "))) - { - Send (pInst, "ERROR 503 CHAT: Invalid or unknown action"); - return; - } - - if (strcasecmp (pszCmd, "ADDMEMBERS") == 0) - { - while(pszCmd = strtok(NULL, ", ")) - { - ImoSkype_GroupInvite (pInst->hInst, pChat->pszUser, pszCmd); - } - } - else if (strcasecmp (pszCmd, "KICK") == 0) - { - while(pszCmd = strtok(NULL, ", ")) - { - ImoSkype_GroupKick (pInst->hInst, pChat->pszUser, pszCmd); - } - } - else if (strcasecmp (pszCmd, "SETTOPIC") == 0) - { - if(pszCmd = strtok(NULL, "")) - { - ImoSkype_GroupTopic (pInst->hInst, pChat->pszUser, pszCmd); - } - } - else if (strcasecmp (pszCmd, "LEAVE") == 0) - { - if(pszCmd = strtok(NULL, "")) - { - ImoSkype_GroupLeave (pInst->hInst, pChat->pszUser); - } - } - else Send (pInst, "ERROR 503 CHAT: Invalid or unknown action"); - } else - Send (pInst, "ERROR 527 ALTER: unknown object type given"); - } - return; - } - else - if (strcasecmp(pszCmd, "NAME") == 0) - { - if (pszCmd = strtok(NULL, " ")) - { - if (pInst->pszClientName) free(pInst->pszClientName); - pInst->pszClientName = strdup(pszCmd); - } - Send (pInst, "OK"); - return; - } - else - { - Send (pInst, "ERROR 2 Not Implemented"); - } -} - -// ----------------------------------------------------------------------------- - diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.h b/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.h deleted file mode 100644 index fa68dd3899..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.h +++ /dev/null @@ -1,13 +0,0 @@ -typedef void(*IMO2SCB)(char *pszMsg, void *pUser); -struct _tagIMOSAPI; -typedef struct _tagIMOSAPI IMOSAPI; - -#define IMO2S_FLAG_CURRTIMESTAMP 1 // Use current timestamp on MSG receive -#define IMO2S_FLAG_ALLOWINTERACT 2 // Allow GUI interaction (CALL) - -IMOSAPI *Imo2S_Init(IMO2SCB Callback, void *pUser, int iFlags); -void Imo2S_Exit (IMOSAPI *pInst); -void Imo2S_SetLog (IMOSAPI *pInst, FILE *fpLog); -int Imo2S_Login (IMOSAPI *pInst, char *pszUser, char *pszPass, char **ppszError); -void Imo2S_Logout(IMOSAPI *pInst); -int Imo2S_Send (IMOSAPI *pInst, char *pszMsg); diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.c b/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.c deleted file mode 100644 index 1615d6ac46..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Module: imo2skypeproxy.c - Purpose: Implementation of imo2skype API as Skype proxy (for Miranda Skype plugin) - Author: leecher - Date: 01.09.2009 - - Changelog: - 1.00 - 01.09.2009 - Initial release - 1.01 - 02.09.2009 - Little bugfix for Onlinestatus, introduced mutex for send thread. - 1.02 - 02.09.2009 - Added support for incoming call notifications and expired sessions. - 1.03 - 03.09.2009 - As WIN32-port of libcurl is a total mess, Win32-version now uses WinINET. - 1.04 - 04.09.2009 - Added support for searching, adding and removing buddies - 1.05 - 06.09.2009 - * Mapped "busy" to DND, not NA, as forum user AL|EN proposed. - * Mood text will now also be sent on status change of a contact - (doesn't really have an effect though) - * New Parameter -d (daemonize) to launch proxy in background - * Fixed a bug with a crash when encoding umlauts on Win32 - 1.06 - 25.09.2009 - Added parameter -t for local timestamps. - 1.07 - 07.10.2009 - Bugfix: Added parsing of multiple JSON messages - Added support for writing to logfile while in daemon mode (-l) - 1.08 - 18.10.2009 - Added support for voice calls via imo.im flash on WIN32 (-i) - - Limited memory queues to 50 entries to reduce memory usage. - 1.09 - 07.11.2009 - Split command line main module and proxy module to make proxy - accessible by different layers (i.e. new Miranda Plugin layer) - 1.10 - 14.12.2009 - Bug in the cJson library. The authors used the String as second - sprintf-Parameter which contains the format string instead of - ["%s", StringParam] causing problems sending Messages containt a % - - Added some space in the dialog for translations and added Translate() - function to some strings in the Wrapper-DLL - - More verbose output if you enable logging - - Fixes a Bug that caused the plugin to block after going offline - and reconnecting back online - - Hopefully fixed a severe threading problem: The Send-Mutex was not - covering a full transaction, but only 1 send causing the receiver - the receive garbled data causing "An existing connection was forcibly - closed by the remote host." error. - - Imo2S_Exit freed the temporary buffer too early resulting in a crash - on exit. - 1.12 - 19.04.2010 - POST interface changed from www.imo.im/amy to s.imo.im/amy - 1.13 - 19.12.2010 - imo.im modified their interface, so tried to adapt the communication - routines at low level to be compatible again. There still may be - many bugs. Don't forget to turn off history logging in the options - at https://imo.im - There also seems to be a nice new feature called "reflection" so that - you can login from multiple sessions and messages etc. entered there - will be reflected to the current session. This may be addressed in one - of the next builds... - 1.14 - 02.03.2011 - Added a Skype WIN32-API Emulation Layer for better compatibility with - other clients that don't want to implement the socks-protocol, so that - we are compatible out-of-the-box. - - Added a few features to be compatible with libpurple. i.e. we now support - message numbering, even tough this is only supported in PROTOCOL 4. - - Added Keepalive packet sending to circumvent imo.im AutoAway. - 1.15 - 18.07.2012 - Avatar support - - Support for new imo.im protocol, can now be compiled to use old or new - protocol, in case there are troubles. New protocol enables participation - in groupchats generated with native Skype client with at least 3 - participants (still a bit experimental) - - WININET HTTPS communication layer now uses async calls to try to prevent - lockups on connection loss. -*/ - -#include -#include "imo2sproxy.h" - -// ----------------------------------------------------------------------------- -// PUBLIC -// ----------------------------------------------------------------------------- - -void Imo2sproxy_Defaults (IMO2SPROXY_CFG *pCfg) -{ - memset (pCfg, 0, sizeof(IMO2SPROXY_CFG)); - pCfg->fpLog = stdout; - pCfg->logerror = fprintf; -} - -/* Real implementation is now in socksproxy.c for the socket communication method - and in w32skypeemu.c for the Window messages Skype emulation - */ diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.h b/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.h deleted file mode 100644 index dbdbbf1cf7..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.h +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include "imo2skypeapi.h" -#ifndef WIN32 -#define __cdecl -#endif - -typedef struct -{ - int bVerbose; - FILE *fpLog; - int iFlags; - int (__cdecl *logerror)( FILE *stream, const char *format, ...); -// FIXME: user+pass from cmdline, until there is a possibility for -// a client to authenticate - char *pszUser; - char *pszPass; -} IMO2SPROXY_CFG; - -typedef struct tag_imo2sproxy IMO2SPROXY; - -struct tag_imo2sproxy -{ - int (*Open)(IMO2SPROXY*); - void (*Loop)(IMO2SPROXY*); - void (*Exit)(IMO2SPROXY*); -}; - -void Imo2sproxy_Defaults (IMO2SPROXY_CFG *pCfg); diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/imo2stest.c b/!NotAdopted/IMO2sProxy/src/imo2skype/imo2stest.c deleted file mode 100644 index 3007e3ce06..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/imo2stest.c +++ /dev/null @@ -1,60 +0,0 @@ -/* Module: imo2stest.c - Purpose: Simple test application for imo2skypeapi - Author: leecher - Date: 31.08.2009 -*/ -#include -#include -#include -#include "imo2skypeapi.h" - -// ----------------------------------------------------------------------------- -// Static -// ----------------------------------------------------------------------------- -static void Recv(char *pszMsg, void *pUser) -{ - printf ("< %s\n", pszMsg); -} - -// ----------------------------------------------------------------------------- -// EIP -// ----------------------------------------------------------------------------- -int main(int argc, char **argv) -{ - int iRet = -1; - IMOSAPI *pInst; - char *pszError = NULL; - - if (argc<3) - { - printf ("Usage: %s [username] [password]\n", argv[0]); - return -1; - } - - if (!(pInst = Imo2S_Init(Recv, NULL,0))) - { - fprintf (stderr, "Failed initialization.\n"); - return -1; - } - - /* Logon */ - if (Imo2S_Login(pInst, argv[1], argv[2], &pszError) == 1) - { - /* Dispatch loop */ - char szLine[4096]={0}; - - while (gets(szLine)) - { - Imo2S_Send (pInst, szLine); - memset (szLine, 0, sizeof(szLine)); - } - } - else - { - fprintf (stderr, "Login failed: %s\n", pszError); - return -1; - } - - Imo2S_Exit (pInst); - return iRet; -} diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/main.c b/!NotAdopted/IMO2sProxy/src/imo2skype/main.c deleted file mode 100644 index 872509616d..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/main.c +++ /dev/null @@ -1,197 +0,0 @@ -/* Module: main.c - Purpose: Main commandline dispatcher for imo.im Skypeproxy - Author: leecher - Date: 07.11.2009 -*/ -#include -#include -#include "imo2sproxy.h" -#include "socksproxy.h" -#ifdef WIN32 -#include "w32skypeemu.h" -#define WIN32_LEAN_AND_MEAN -#include -#include -#define Daemonize FreeConsole() -#ifdef _DEBUG -#define LOG(_args_) printf _args_ -#ifndef _WIN64 -#include "crash.c" -#endif -#endif -#else -#define Daemonize daemon(0, 0) -#endif - -// ----------------------------------------------------------------------------- -// EIP -// ----------------------------------------------------------------------------- -int main(int argc, char **argv) -{ - int i, j=0, bDaemon = 0; - char cMode='s'; - IMO2SPROXY_CFG stCfg; - SOCKSPROXY_CFG stSocksCfg; -#ifdef WIN32 - W32SKYPEEMU_CFG stSypeEmuCfg; -#endif - IMO2SPROXY *pProxy; - -#ifdef _DEBUG - Crash_Init(); -#endif - - Imo2sproxy_Defaults (&stCfg); - SocksProxy_Defaults (&stSocksCfg); -#ifdef WIN32 - W32SkypeEmu_Defaults(&stSypeEmuCfg); -#endif - if (argc<3) - { - printf ("imo.im Skypeproxy V1.15 - (c) by leecher 2009-2012\n\n" - "%s [-d] [-v [-l ]] [-t] [-i]\n" - "[-m] [-h ] [-p ] \n\n" - "-d\t- Daemonize (detach from console)\n" - "-v\t- Verbose mode, log commands to console\n" - "-l\t- Set logfile to redirect verbose log to.\n" - "-t\t- Ignore server timestamp and use current time for messages\n" - "-i\t- Use interactive mode (starts imo.im flash app upon call)\n" - "-m\t- Specify connection mode to use:\n" - "\t\ts\tSocket mode (SkypeProxy protocol) [default]\n" -#ifdef WIN32 - "\t\ta\tSkype API Emulation via Window messages (real Skype API)\n" -#endif - "\tParameters for socket mode:\n" - "-h\t- Bind to a specific IP, not to all interfaces (default)\n" - "-p\t- Bind to another port (default: 1401)\n" - "Default: Bind to any interface, Use Port %d\n", argv[0], stSocksCfg.sPort); - return EXIT_FAILURE; - } - - for (i=1; iOpen(pProxy) == 0) - pProxy->Loop(pProxy); - pProxy->Exit(pProxy); - - if (stCfg.fpLog && stCfg.fpLog != stdout && stCfg.fpLog != stderr) - { - fclose(stCfg.fpLog); - stCfg.fpLog = NULL; - } - - return EXIT_SUCCESS; -} - diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/imoproxy.c b/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/imoproxy.c deleted file mode 100644 index 195f479ea6..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/imoproxy.c +++ /dev/null @@ -1,882 +0,0 @@ -/* Module: imoproxy.c - Purpose: Proxy-DLL for Miranda IM to load imo2sproxy as plugin - Author: leecher - Date: 26.10.2009 -*/ - -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include -#include -#include -#include -#pragma comment (lib, "Ws2_32.lib") -#include -#include "io_layer.h" -#include "imo2sproxy.h" -#include "imo_request.h" -#include "socksproxy.h" -#include "w32skypeemu.h" -#include "skypepluginlink.h" -#include "include/newpluginapi.h" -#include "include/m_langpack.h" -#include "include/m_options.h" -#include "include/m_database.h" -#include "include/m_system.h" -#include "sdk/m_updater.h" -#include "resource.h" - -// Crash dumper -#ifdef _DEBUG -void CrashLog (const char *pszFormat, ...) -{ - static FILE *fpLog = NULL; - char szLine[1024]; - va_list ap; - - if (!fpLog) fpLog=fopen("imoproxy.log", "a"); - va_start(ap, pszFormat); - _vsnprintf(szLine, sizeof(szLine), pszFormat, ap); - va_end(ap); - - if (fpLog) - { - fprintf (fpLog, "%s", szLine); - fflush (fpLog); - } -} -#define LOG(_args_) CrashLog _args_ -#ifndef _WIN64 -#include "crash.c" -#endif -#endif - - -PLUGINLINK *pluginLink; -HINSTANCE m_hInst; -static HANDLE m_hOptHook=NULL, m_hPreShutdownHook=NULL, m_hHookModulesLoaded=NULL; - -#define PROXY_SOCKS 0 -#define PROXY_W32SKYPEEMU 1 -#define PROXY_SKYPEPLUGIN 2 -#define PROXY_MAX 3 - -static IMO2SPROXY_CFG m_stCfg; -static SOCKSPROXY_CFG m_stSocksCfg; -static W32SKYPEEMU_CFG m_stSypeEmuCfg; -static SKYPEPLUGINLINK_CFG m_stSkypePluginCfg; - -static IMO2SPROXY *m_apProxy[PROXY_MAX] = {0}; -static HANDLE m_hThread[PROXY_MAX]={0}, m_hEvent = INVALID_HANDLE_VALUE; -static BOOL m_bConsole = FALSE; - -#define ANY_SIZE 1 - -typedef struct _MIB_IPADDRROW { - DWORD dwAddr; - DWORD dwIndex; - DWORD dwMask; - DWORD dwBCastAddr; - DWORD dwReasmSize; - unsigned short unused1; - unsigned short wType; -}MIB_IPADDRROW, *PMIB_IPADDRROW; - -typedef struct _MIB_IPADDRTABLE { - DWORD dwNumEntries; - MIB_IPADDRROW table[ANY_SIZE]; -}MIB_IPADDRTABLE, *PMIB_IPADDRTABLE; - - -// Plugin Info -#define PINFO \ - "imo2sproxy-Plugin", \ - PLUGIN_MAKE_VERSION(1,0,0,15), \ - "Tunnelling Skype traffic via imo.im Web service", \ - "leecher", \ - "leecher@dose.0wnz.at", \ - "© 2010-2012 leecher", \ - "http://dose.0wnz.at", \ - 0, \ - 0 //doesn't replace anything built-in - - -PLUGININFO pluginInfo = { - sizeof(PLUGININFO), - PINFO -}; - -// New plugininfo -PLUGININFOEX pluginInfoEx = { - sizeof (pluginInfoEx), - PINFO, - { 0x3005c2b1, 0x4278, 0x470c, { 0x94, 0x98, 0x5, 0x95, 0x3d, 0xfa, 0x4d, 0x88 } } // // {3005C2B1-4278-470c-9498-05953DFA4D88} -}; - -// Whatever this is... -// {95061E8D-B18C-4c1c-8E14-686DE967D851} -#define MIID_IMOPROXY { 0x95061e8d, 0xb18c, 0x4c1c, { 0x8e, 0x14, 0x68, 0x6d, 0xe9, 0x67, 0xd8, 0x51 } } -static const MUUID interfaces[] = { MIID_IMOPROXY, MIID_LAST }; - -// ----------------------------------------------------------------------------- -// ----------------------------------------------------------------------------- - -int ShowError( FILE *stream, const char *format, ...) -{ - char szBuf[1024]; - va_list ap; - int iRet; - - va_start(ap, format); - iRet = _vsnprintf (szBuf, sizeof(szBuf), format, ap); - va_end(ap); - - MessageBox (NULL, szBuf, Translate("IMOPROXY Error"), MB_ICONSTOP | MB_OK); - return iRet; -} - -// ----------------------------------------------------------------------------- - -static void LoadSettings(void) -{ - DBVARIANT dbv; - - // General config - if (!m_bConsole) - { - if (DBGetContactSetting(NULL, "IMOPROXY", "Logfile", &dbv)==0) - { - if ((m_stCfg.bVerbose = DBGetContactSettingByte(NULL, "IMOPROXY", "Verbose", 0)) && - *dbv.pszVal) - { - if (m_stCfg.fpLog) fclose (m_stCfg.fpLog); - if (!(m_stCfg.fpLog = fopen(dbv.pszVal, "a"))) - { - char szMsg[MAX_PATH+64]; - - sprintf (szMsg, Translate("Cannot open Logfile %s for writing."), dbv.pszVal); - MessageBox(NULL,szMsg,"IMOPROXY", MB_OK | MB_ICONWARNING); - m_stCfg.bVerbose = FALSE; - } - } - DBFreeVariant(&dbv); - } - } - m_stCfg.iFlags = DBGetContactSettingDword(NULL, "IMOPROXY", "Flags", 0); - if (DBGetContactSetting(NULL, "IMOPROXY", "User", &dbv)==0) - { - if (m_stCfg.pszUser) free(m_stCfg.pszUser); - m_stCfg.pszUser = strdup(dbv.pszVal); - DBFreeVariant(&dbv); - } - if (DBGetContactSetting(NULL, "IMOPROXY", "Password", &dbv)==0) - { - if (m_stCfg.pszPass) free(m_stCfg.pszPass); - m_stCfg.pszPass = strdup(dbv.pszVal); - DBFreeVariant(&dbv); - } - - // Socks Proxy config - m_stSocksCfg.sPort = DBGetContactSettingWord(NULL, "IMOPROXY", "Port", 1401); - if (DBGetContactSetting(NULL, "IMOPROXY", "Host", &dbv)==0) - { - m_stSocksCfg.lAddr = inet_addr(dbv.pszVal); - DBFreeVariant(&dbv); - } -} - -// ----------------------------------------------------------------------------- - -static BOOL CheckSettings(int iMask) -{ - DBVARIANT dbv; - - if (iMask & PROXY_SOCKS) - { - if (DBGetContactSetting(NULL, SKYPE_PROTONAME, "Host", &dbv)==0) - { - if (DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseSkype2Socket", 0) && - (lstrcmp (dbv.pszVal, "127.0.0.1")==0 || - lstrcmp (dbv.pszVal, "localhost")==0) && - DBGetContactSettingWord(NULL, SKYPE_PROTONAME, "Port", 0) == - DBGetContactSettingWord(NULL, "IMOPROXY", "Port", 1401)) - { - DBFreeVariant(&dbv); - return TRUE; - } - DBFreeVariant(&dbv); - } - } - if (DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "FirstRun", 9) == 9) - { - MessageBox (NULL, Translate("SKYPE plugin may not be installed, this plugin only works together with " - "the SKYPE-plugin. Please check if you installed and enabled it."), "IMOPROXY", - MB_OK | MB_ICONWARNING); - } - else - { - - if ((iMask & PROXY_SOCKS) && !ServiceExists(SKYPE_PROTONAME PSS_SKYPEAPIMSG) ) - { - if (MessageBox (NULL, Translate("Your Skype plugin currently doesn't seem to be setup to use imo2proxy, " - "do you want me to change its settings so that it uses this plugins?"), "IMOPROXY", - MB_YESNO | MB_ICONQUESTION) == IDYES) - { - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "UseSkype2Socket", 1); - DBWriteContactSettingWord (NULL, SKYPE_PROTONAME, "Port", m_stSocksCfg.sPort); - DBWriteContactSettingString (NULL, SKYPE_PROTONAME, "Host", "127.0.0.1"); - return TRUE; - } - } - } - return FALSE; -} - -// ----------------------------------------------------------------------------- - -static BOOL EnumNetInterfaces (HWND hwndControl) -{ - HINSTANCE hLib; - BOOL bRet = FALSE; - - if (hLib = LoadLibrary("Iphlpapi.dll")) - { - PMIB_IPADDRTABLE pTable; - ULONG uSize=1; - DWORD i; - FARPROC GetIpAddrTable; - - if (GetIpAddrTable = (FARPROC)GetProcAddress (hLib, "GetIpAddrTable")) - { - if ((GetIpAddrTable (&pTable, &uSize, TRUE) == ERROR_INSUFFICIENT_BUFFER) && - (pTable = HeapAlloc (GetProcessHeap(), 0, uSize))) - { - if (GetIpAddrTable (pTable, &uSize, TRUE) == NO_ERROR) - { - struct in_addr addr; - - for (i=0; idwNumEntries; i++) - { - addr.S_un.S_addr = pTable->table[i].dwAddr; - SendMessage (hwndControl, CB_ADDSTRING, 0, (LPARAM)inet_ntoa(addr)); - } - bRet = pTable->dwNumEntries > 0; - } - HeapFree (GetProcessHeap(), 0, pTable); - } - } - FreeLibrary (hLib); - } - return bRet; -} - -// ----------------------------------------------------------------------------- - -static DWORD WINAPI ProxyThread(IMO2SPROXY *pProxy) -{ - if (pProxy->Open(pProxy)<0) return -1; - SetEvent (m_hEvent); - pProxy->Loop(pProxy); - return 0; -} - -// ----------------------------------------------------------------------------- - -static BYTE GetProxies(void) -{ - return DBGetContactSettingByte(NULL, "IMOPROXY", "Proxies", - (ServiceExists(SKYPE_PROTONAME PSS_SKYPEAPIMSG)?(1<Open(m_apProxy[i])<0) - { - m_apProxy[i]->Exit(m_apProxy[i]); - return FALSE; - } - return TRUE; - default: - return FALSE; - } - if (!m_apProxy[i]) return FALSE; - - // As for example W32SKYPEEMU runs its own messagepump and the Window is - // Registered in the Open-Function (as it can fail), we have to start - // our Mainloop-Thread and wait for the Open() part to finish. - // If it worked ok, the loop will start to run, otherwise we return - // an error. So we need a Mutex for synchronisation. - m_hEvent = ahEvents[1] = CreateEvent (NULL, FALSE, FALSE, NULL); - - if (!(m_hThread[i] = ahEvents[0] = (HANDLE)_beginthreadex (NULL, 0, ProxyThread, m_apProxy[i], 0, &dwThreadId))) - { - MessageBox (NULL, Translate("IMOPROXY Cannot start dispatch thread"), "IMOPROXY", MB_OK | MB_ICONSTOP); - CloseHandle (m_hEvent); - m_apProxy[i]->Exit(m_apProxy[i]); - return FALSE; - } - - bRet = WaitForMultipleObjects (2, ahEvents, FALSE, INFINITE)==WAIT_OBJECT_0+1; - CloseHandle (m_hEvent); - return bRet; -} - -// ----------------------------------------------------------------------------- - -static void StopProxy (int i) -{ - if (m_apProxy[i]) - { - m_apProxy[i]->Exit(m_apProxy[i]); - m_apProxy[i] = NULL; - } - - if (m_hThread[i]) - { - if (WaitForSingleObject (m_hThread[i], 3000) != WAIT_OBJECT_0) - TerminateThread (m_hThread[i], -1); - m_hThread[i] = NULL; - } -} - -// ----------------------------------------------------------------------------- - -static BOOL StartProxies(int iMask) -{ - int i; - BOOL bRet=TRUE; - - for (i=0; i= 0x080000) - { - EnableWindow (GetDlgItem (hWnd, IDC_USENETLIB), TRUE); - if (DBGetContactSettingByte (NULL, "IMOPROXY", "UseNetlib", 0)) - CheckDlgButton (hWnd, IDC_USENETLIB, BST_CHECKED); - } - SetDlgItemText (hWnd, IDC_LOGFILE, szOldLog); - if (bOldVerbose = DBGetContactSettingByte(NULL, "IMOPROXY", "Verbose", 0)) - CheckDlgButton (hWnd, IDC_LOG, BST_CHECKED); - else - { - EnableWindow (GetDlgItem (hWnd, IDC_LOGFILE), FALSE); - EnableWindow (GetDlgItem (hWnd, IDC_OPEN), FALSE); - } - if (DBGetContactSetting(NULL, "IMOPROXY", "User", &dbv)==0) - { - lstrcpyn (szOldUser, dbv.pszVal, sizeof(szOldUser)); - DBFreeVariant(&dbv); - } - SetDlgItemText (hWnd, IDC_USERNAME, szOldUser); - if (DBGetContactSetting(NULL, "IMOPROXY", "Password", &dbv)==0) - { - lstrcpyn (szOldPass, dbv.pszVal, sizeof(szOldPass)); - DBFreeVariant(&dbv); - } - iOldProxies= GetProxies(); - CheckDlgButton (hWnd, IDC_USESOCKS, (iOldProxies&(1<code) - { - case PSN_APPLY: - case PSN_KILLACTIVE: - { - int iFlags=0, iProxies=0; - short sPort; - char szHost[64], szLog[MAX_PATH], szUser[64], szPass[64]; - BOOL bVerbose; - - GetDlgItemText (hWnd, IDC_BINDIP, szHost, sizeof(szHost)); - DBWriteContactSettingString (NULL, "IMOPROXY", "Host", szHost); - DBWriteContactSettingWord (NULL, "IMOPROXY", "Port", - (sPort = GetDlgItemInt (hWnd, IDC_BINDPORT, NULL, FALSE))); - if (IsDlgButtonChecked (hWnd, IDC_INTERACT)==BST_CHECKED) - iFlags|=IMO2S_FLAG_ALLOWINTERACT; - if (IsDlgButtonChecked (hWnd, IDC_CURRTIMESTAMP)==BST_CHECKED) - iFlags|=IMO2S_FLAG_CURRTIMESTAMP; - GetDlgItemText (hWnd, IDC_USERNAME, szUser, sizeof(szUser)); - DBWriteContactSettingString (NULL, "IMOPROXY", "User", szUser); - GetDlgItemText (hWnd, IDC_PASSWORD, szPass, sizeof(szPass)); - DBWriteContactSettingString (NULL, "IMOPROXY", "Password", szPass); - DBWriteContactSettingDword (NULL, "IMOPROXY", "Flags", iFlags); - DBWriteContactSettingByte(NULL, "IMOPROXY", "Verbose", - (char)(bVerbose = (IsDlgButtonChecked (hWnd, IDC_LOG)==BST_CHECKED))); - GetDlgItemText (hWnd, IDC_LOGFILE, szLog, sizeof(szLog)); - DBWriteContactSettingString (NULL, "IMOPROXY", "Logfile", szLog); - if (IsDlgButtonChecked (hWnd, IDC_USESOCKS)==BST_CHECKED) - iProxies|=(1<Skype to imo.im Gateway "; - update.szBetaUpdateURL = "http://dose.0wnz.at/miranda/Skype/imo2sproxy_w32_binonly.zip"; - update.szBetaVersionURL = "http://dose.0wnz.at/miranda/Skype/"; - update.pbBetaVersionPrefix = (BYTE *)"imo2sproxy version "; -#endif - - update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix); - update.cpbBetaVersionPrefix = strlen((char *)update.pbBetaVersionPrefix); - - CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update); - - } -} - -// ----------------------------------------------------------------------------- - -int PreShutdown(WPARAM wParam, LPARAM lParam) -{ - OutputDebugString ("IMOPROXY: PreShutdown"); - StopProxies (-1); - if (m_stCfg.fpLog && m_stCfg.fpLog != stdout && m_stCfg.fpLog != stderr) - { - fclose(m_stCfg.fpLog); - m_stCfg.fpLog = NULL; - } - if (m_stCfg.pszUser) - { - free(m_stCfg.pszUser); - m_stCfg.pszUser = NULL; - } - if (m_stCfg.pszPass) - { - free(m_stCfg.pszPass); - m_stCfg.pszPass = NULL; - } - - FreeConsole(); - return 0; -} - -// ----------------------------------------------------------------------------- - -int OnModulesLoaded(WPARAM wParam, LPARAM lParam) -{ - BYTE CheckSkype = DBGetContactSettingByte (NULL, "IMOPROXY", "CheckSkype", 2); - if (CheckSkype) CheckSettings(-1); - if (CheckSkype == 2) DBWriteContactSettingByte (NULL, "IMOPROXY", "CheckSkype", 0); - RegisterToUpdate(); - - // On Miranda 0.0.0.8+ NETLIB suppotrs HTTPS, therefore we can use - // Netlib there - if (CallService (MS_SYSTEM_GETVERSION, 0, 0) >= 0x080000 && - DBGetContactSettingByte (NULL, "IMOPROXY", "UseNetlib", 0)) - ImoRq_SetIOLayer (IoLayerNETLIB_Init); - StartProxies(-1); - - return 0; -} - -// ----------------------------------------------------------------------------- - -BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) -{ - m_hInst=hinstDLL; - return TRUE; -} - -// ----------------------------------------------------------------------------- -// ----------------------------------------------------------------------------- - -__declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion) -{ - return &pluginInfo; -} - -// ----------------------------------------------------------------------------- - -// New plugin API -__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) -{ - return &pluginInfoEx; -} - -// ----------------------------------------------------------------------------- - -__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} - -// ----------------------------------------------------------------------------- - -int __declspec(dllexport) Load(PLUGINLINK *link) -{ - -#ifdef _DEBUG - Crash_Init(); -#endif - pluginLink = link; - - // Init IMO2S config structures - Imo2sproxy_Defaults (&m_stCfg); - SocksProxy_Defaults (&m_stSocksCfg); - W32SkypeEmu_Defaults(&m_stSypeEmuCfg); - SkypePluginLink_Defaults(&m_stSkypePluginCfg); - m_stCfg.logerror = ShowError; - LoadSettings(); - - m_hOptHook = HookEvent(ME_OPT_INITIALISE, RegisterOptions); - m_hPreShutdownHook = HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown); - m_hHookModulesLoaded = HookEvent( ME_SYSTEM_MODULESLOADED, OnModulesLoaded); - - OutputDebugString ("IMOPROXY: Loaded"); - return 0; -} - -// ----------------------------------------------------------------------------- - -int __declspec(dllexport) Unload(void) -{ - OutputDebugString ("IMOPROXY: Unload"); - UnhookEvent(m_hOptHook); - UnhookEvent(m_hPreShutdownHook); - UnhookEvent(m_hHookModulesLoaded); - return 0; -} diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/io_layer_netlib.c b/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/io_layer_netlib.c deleted file mode 100644 index 378f72e65f..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/io_layer_netlib.c +++ /dev/null @@ -1,340 +0,0 @@ -/* Module: io_layer_netlib.c - Purpose: IO Layer for Internet communication using Miranda NETLIB - Author: leecher - Date: 20.04.2011 :=) -*/ -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include "include/newpluginapi.h" -#include "include/m_netlib.h" -#include "fifo.h" -#include "memlist.h" -#include "io_layer.h" - -#define USER_AGENT "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13" - -typedef struct -{ - IOLAYER vtbl; - int iRecursion; - NETLIBHTTPREQUEST *nlhrReply; - LPVOID lpErrorBuf; - HANDLE nlc; -} IOLAYER_INST; - -typedef struct -{ - HANDLE hNetlib; - TYP_LIST *hCookies; - TYP_FIFO *hCookieStr; - char *pszCookies; - LONG lRefCount; - CRITICAL_SECTION cs; -} IOLAYER_SINGLETON; - -static IOLAYER_SINGLETON *m_hNL = NULL; - -static void IoLayer_Exit (IOLAYER *hPIO); -static char *IoLayer_Post(IOLAYER *hPIO, char *pszURL, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength); -static char *IoLayer_Get(IOLAYER *hIO, char *pszURL, unsigned int *pdwLength); -static void IoLayer_Cancel(IOLAYER *hIO); -static char *IoLayer_GetLastError(IOLAYER *hIO); -static char *IoLayer_EscapeString(IOLAYER *hPIO, char *pszData); -static void IoLayer_FreeEscapeString(char *pszData); -static void FetchLastError (IOLAYER_INST *hIO); -static void add_cookies(char *pszCookies); -static void refresh_cookies(); -static HANDLE *OpenConnection(NETLIBHTTPREQUEST *nlhr); - -// ----------------------------------------------------------------------------- -// Interface -// ----------------------------------------------------------------------------- - -IOLAYER *IoLayerNETLIB_Init(void) -{ - IOLAYER_INST *hIO; - - if (CallService (MS_SYSTEM_GETVERSION, 0, 0) < 0x080000 || // Miranda HTTPS support starting with 0.8.0.0 - !(hIO = calloc(1, sizeof(IOLAYER_INST)))) - return NULL; - - // NETLIB only works as singleton - if (!m_hNL) - { - NETLIBUSER nlu={0}; - - if (!(m_hNL = calloc (1, sizeof(IOLAYER_SINGLETON)))) - { - free (hIO); - return NULL; - } - m_hNL->lRefCount++; - - // Init Netlib - nlu.cbSize = sizeof(nlu); - nlu.flags = NUF_OUTGOING; - nlu.szDescriptiveName = "imo2sproxy connection"; - nlu.szSettingsModule = "IMOPROXY"; - nlu.szHttpGatewayUserAgent = USER_AGENT; - if (!(m_hNL->hNetlib = (HANDLE)CallService (MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu)) || - !(m_hNL->hCookies = List_Init(0)) || - !(m_hNL->hCookieStr = Fifo_Init(0))) - { - IoLayer_Exit((IOLAYER*)hIO); - return NULL; - } - m_hNL->pszCookies = ""; - InitializeCriticalSection (&m_hNL->cs); - } else m_hNL->lRefCount++; - - // Init Vtbl - hIO->vtbl.Exit = IoLayer_Exit; - hIO->vtbl.Post = IoLayer_Post; - hIO->vtbl.Get = IoLayer_Get; - hIO->vtbl.Cancel = IoLayer_Cancel; - hIO->vtbl.GetLastError = IoLayer_GetLastError; - hIO->vtbl.EscapeString = IoLayer_EscapeString; - hIO->vtbl.FreeEscapeString = IoLayer_FreeEscapeString; - - return (IOLAYER*)hIO; -} -// ----------------------------------------------------------------------------- - -static void IoLayer_Exit (IOLAYER *hPIO) -{ - IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; - - if (hIO->nlhrReply) CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)hIO->nlhrReply); - if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf); - if (InterlockedDecrement(&m_hNL->lRefCount) <= 0) - { - if (m_hNL->hNetlib) Netlib_CloseHandle (m_hNL->hNetlib); - if (m_hNL->hCookies) { - List_FreeElements(m_hNL->hCookies); - List_Exit (m_hNL->hCookies); - } - if (m_hNL->hCookieStr) Fifo_Exit(m_hNL->hCookieStr); - DeleteCriticalSection (&m_hNL->cs); - free (m_hNL); - m_hNL = NULL; - } - free (hIO); -} - -// ----------------------------------------------------------------------------- - -static char *IoLayer_Post(IOLAYER *hPIO, char *pszURL, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength) -{ - IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; - NETLIBHTTPREQUEST nlhr={0}; - NETLIBHTTPHEADER headers[5]; - int i; - char *pszCookies = NULL; - - - /* - char szDbg[256]; - sprintf (szDbg, "Thread %d with hIO %08X requests %s\n", GetCurrentThreadId(), hIO, pszURL); - OutputDebugString(szDbg); - */ - - // Build basic request - nlhr.cbSize = sizeof(nlhr); - nlhr.flags = NLHRF_GENERATEHOST | NLHRF_SMARTREMOVEHOST | NLHRF_REDIRECT; - if (!pdwLength) nlhr.flags |= NLHRF_DUMPASTEXT; // pdwLength needed -> Binary data - nlhr.requestType = pszPostFields?REQUEST_POST:REQUEST_GET; - nlhr.szUrl = pszURL; - nlhr.pData = pszPostFields; - nlhr.dataLength = cbPostFields; - nlhr.headers = headers; - - // Add headers - EnterCriticalSection (&m_hNL->cs); - if (m_hNL->pszCookies && *m_hNL->pszCookies) - { - headers[nlhr.headersCount].szName = "Cookie"; - headers[nlhr.headersCount++].szValue = pszCookies = strdup(m_hNL->pszCookies); - } - headers[nlhr.headersCount].szName = "User-Agent"; - headers[nlhr.headersCount++].szValue = USER_AGENT; - headers[nlhr.headersCount].szName = "Accept-Encoding"; - headers[nlhr.headersCount++].szValue = "deflate, gzip"; - headers[nlhr.headersCount].szName = "Content-Type"; - headers[nlhr.headersCount++].szValue = "application/x-www-form-urlencoded; charset=UTF-8"; - headers[nlhr.headersCount].szName = "X-Requested-With"; - headers[nlhr.headersCount++].szValue = "XMLHttpRequest"; - LeaveCriticalSection (&m_hNL->cs); - - // Do the transaction - nlhr.nlc = hIO->nlc = OpenConnection (&nlhr); - if (hIO->nlhrReply) CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)hIO->nlhrReply); - hIO->nlhrReply = (NETLIBHTTPREQUEST*)CallService (MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNL->hNetlib, (LPARAM)&nlhr); - hIO->nlc = NULL; - - if (pszCookies) free (pszCookies); - if (!hIO->nlhrReply) - { - FetchLastError (hIO); - return NULL; - } - - if (!hIO->nlhrReply || !hIO->nlhrReply->dataLength || !hIO->nlhrReply->pData) - { - if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf); - if (hIO->lpErrorBuf = LocalAlloc (LPTR, 64)) - strcpy (hIO->lpErrorBuf, "Reply contained no data"); - return NULL; - } - - // Error handling - if (hIO->nlhrReply->resultCode < 200 || hIO->nlhrReply->resultCode >= 300) - { - if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf); - if (hIO->lpErrorBuf = LocalAlloc (LPTR, 64)) - sprintf (hIO->lpErrorBuf, "HTTP transaction returned status %d", hIO->nlhrReply->resultCode); - return NULL; - } - - // Process headers to collect cookies - EnterCriticalSection (&m_hNL->cs); - for (i=0; inlhrReply->headersCount; i++) - { - if (!strnicmp(hIO->nlhrReply->headers[i].szName, "Set-Cookie", 10)) - add_cookies(hIO->nlhrReply->headers[i].szValue); - } - LeaveCriticalSection (&m_hNL->cs); - - // Return reply - if (pdwLength) *pdwLength = hIO->nlhrReply->dataLength; - return hIO->nlhrReply->pData; -} - -// ----------------------------------------------------------------------------- - -static char *IoLayer_Get(IOLAYER *hIO, char *pszURL, unsigned int *pdwLength) -{ - return IoLayer_Post (hIO, pszURL, NULL, 0, pdwLength); -} - -// ----------------------------------------------------------------------------- - -static void IoLayer_Cancel(IOLAYER *hPIO) -{ - IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; - - if (hIO->nlc && Netlib_CloseHandle(hIO->nlc)) - hIO->nlc = NULL; -} - -// ----------------------------------------------------------------------------- - -static char *IoLayer_GetLastError(IOLAYER *hIO) -{ - return (char*)((IOLAYER_INST*)hIO)->lpErrorBuf; -} - -// ----------------------------------------------------------------------------- - -static char *IoLayer_EscapeString(IOLAYER *hPIO, char *pszData) -{ - return (char*)CallService (MS_NETLIB_URLENCODE, 0, (LPARAM)pszData); -} - -// ----------------------------------------------------------------------------- - -static void IoLayer_FreeEscapeString(char *pszData) -{ - HeapFree(GetProcessHeap(), 0, pszData); -} - -// ----------------------------------------------------------------------------- -// Static -// ----------------------------------------------------------------------------- - -static void FetchLastError (IOLAYER_INST *hIO) -{ - if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf); - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, - GetLastError(), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), - (LPTSTR)&hIO->lpErrorBuf, 0, NULL); -} - -// ----------------------------------------------------------------------------- - -static void add_cookies(char *pszCookies) -{ - int i, nCount, iLenCmp, iLenCookie; - char *p, *pszCookie = NULL; - - if (!(p = strchr(pszCookies, '='))) return; - iLenCmp=p-pszCookies+1; - if ((p=strchr (p, ';')) || (p=strchr (p, ';'))) iLenCookie = p-pszCookies; - else iLenCookie=strlen(pszCookies); - - for (i=0, nCount=List_Count(m_hNL->hCookies); ihCookies, i); - if (!strncmp(pszCookie, pszCookies, iLenCmp)) - break; - } - - if (i==nCount) pszCookie = NULL; - if (pszCookie = realloc (pszCookie, iLenCookie+1)) - { - strncpy (pszCookie, pszCookies, iLenCookie); - pszCookie[iLenCookie]=0; - if (ihCookies, pszCookie, i); - else - List_Push (m_hNL->hCookies, pszCookie); - } - refresh_cookies (); -} - -// ----------------------------------------------------------------------------- - -static void refresh_cookies() -{ - int i, nCount; - - Fifo_Reset (m_hNL->hCookieStr); - for (i=0, nCount=List_Count(m_hNL->hCookies); ihCookies, i); - Fifo_Add (m_hNL->hCookieStr, pszCookie, strlen(pszCookie)); - Fifo_Add (m_hNL->hCookieStr, "; ", 2); - } - Fifo_Add (m_hNL->hCookieStr, "", 1); - m_hNL->pszCookies = Fifo_Get (m_hNL->hCookieStr, NULL); -} - -// ----------------------------------------------------------------------------- - -static HANDLE *OpenConnection(NETLIBHTTPREQUEST *nlhr) -{ - NETLIBOPENCONNECTION nloc={0}; - BOOL secur = (nlhr->flags & NLHRF_SSL) || _strnicmp(nlhr->szUrl, "https", 5) == 0; - char* phost = strstr(nlhr->szUrl, "://"); - char *ppath, *pcolon; - - // Poor man's InternetCrackUrl - nloc.cbSize = sizeof(NETLIBOPENCONNECTION); - if (phost) phost+=3; else phost=nlhr->szUrl; - nloc.szHost = _alloca (strlen(phost)+1); - strcpy ((char*)nloc.szHost, phost); - if (ppath = strchr(nloc.szHost, '/')) *ppath = '\0'; - if (pcolon = strrchr(nloc.szHost, ':')) - { - *pcolon = '\0'; - nloc.wPort = (WORD)strtol(pcolon+1, NULL, 10); - } - else nloc.wPort = secur ? 443 : 80; - nloc.flags = (secur ? NLOCF_SSL : 0) | NLOCF_HTTP; - if (secur) nlhr->flags |= NLHRF_SSL; else nlhr->flags &= ~NLHRF_SSL; - - // Open connection - return (HANDLE)CallService (MS_NETLIB_OPENCONNECTION, (WPARAM)m_hNL->hNetlib, (LPARAM)&nloc); -} \ No newline at end of file diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.aps b/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.aps deleted file mode 100644 index 280086f42b..0000000000 Binary files a/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.aps and /dev/null differ diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.rc b/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.rc deleted file mode 100644 index 487426fbfe..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.rc +++ /dev/null @@ -1,145 +0,0 @@ -//Microsoft Developer Studio generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Deutsch (Цsterreich) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEA) -#ifdef _WIN32 -LANGUAGE LANG_GERMAN, SUBLANG_GERMAN_AUSTRIAN -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_OPTIONS DIALOGEX 0, 0, 287, 224 -STYLE WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Sans Serif" -BEGIN - GROUPBOX "Account information",IDC_STATIC,7,7,273,31 - LTEXT "Username:",IDC_STATIC,17,20,53,9 - EDITTEXT IDC_USERNAME,74,18,56,12,ES_AUTOHSCROLL - LTEXT "Password:",IDC_STATIC,135,20,47,9 - EDITTEXT IDC_PASSWORD,185,18,56,12,ES_PASSWORD | ES_AUTOHSCROLL - CONTROL "Support for Voicecalls via imo.im Flash in Internet Explorer", - IDC_INTERACT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,42, - 273,9 - CONTROL "Ignore server timestamp and use current time for messages", - IDC_CURRTIMESTAMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 7,60,273,10 - CONTROL "Log traffic to file:",IDC_LOG,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,7,71,110,10 - EDITTEXT IDC_LOGFILE,119,71,128,12,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_OPEN,248,71,14,12 - LTEXT "Status:",IDC_STATIC,126,140,29,10 - LTEXT "Stopped",IDC_STATUSSOCKS,157,140,54,9,SS_SUNKEN - GROUPBOX "Socket Proxy",IDC_STATIC,7,129,273,45 - LTEXT "Bind to address:",IDC_STATIC,17,157,73,9 - COMBOBOX IDC_BINDIP,95,155,75,12,CBS_DROPDOWN | CBS_SORT | - WS_VSCROLL | WS_TABSTOP - LTEXT "Port:",IDC_STATIC,179,157,31,9 - EDITTEXT IDC_BINDPORT,211,155,31,12,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "Use Socket Proxy",IDC_USESOCKS,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,18,140,81,9 - PUSHBUTTON "Start",IDC_STARTSOCKS,216,137,30,12 - PUSHBUTTON "Stop",IDC_STOPSOCKS,246,137,30,12,WS_DISABLED - GROUPBOX "Skype compatible communication API",IDC_STATIC,7,177, - 273,40 - LTEXT "Caution: Don't use this if you have the Skype application running!", - IDC_STATIC,13,188,260,8 - LTEXT "Status:",IDC_STATIC,126,201,29,10 - LTEXT "Stopped",IDC_STATUSCOMM,158,201,54,9,SS_SUNKEN - CONTROL "Use compatible comm API",IDC_USECOMM,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,18,201,105,9 - PUSHBUTTON "Start",IDC_STARTCOMM,216,198,30,12 - PUSHBUTTON "Stop",IDC_STOPCOMM,246,198,30,12,WS_DISABLED - CONTROL "Console",IDC_CONSOLE,"Button",BS_AUTOCHECKBOX | - BS_PUSHLIKE | WS_TABSTOP,216,87,45,11 - GROUPBOX "Skype Plugin 0.0.0.46+ internal communication link", - IDC_STATIC,7,102,273,25 - LTEXT "Status:",IDC_STATIC,126,113,29,10 - LTEXT "Stopped",IDC_STATUSSKYPEPL,158,113,54,9,SS_SUNKEN - CONTROL "Use plugin link",IDC_USESKYPEPL,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,18,113,105,9 - PUSHBUTTON "Start",IDC_STARTSKYPEPL,216,110,30,12 - PUSHBUTTON "Stop",IDC_STOPSKYPEPL,246,110,30,12,WS_DISABLED - CONTROL "Use Netlib instead of WinInet (Experimental)", - IDC_USENETLIB,"Button",BS_AUTOCHECKBOX | WS_DISABLED | - WS_TABSTOP,7,51,273,9 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE -BEGIN - IDD_OPTIONS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 280 - TOPMARGIN, 7 - BOTTOMMARGIN, 217 - END -END -#endif // APSTUDIO_INVOKED - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE DISCARDABLE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE DISCARDABLE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE DISCARDABLE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // Deutsch (Цsterreich) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/resource.h b/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/resource.h deleted file mode 100644 index e0da6bef1d..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/resource.h +++ /dev/null @@ -1,39 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by res.rc -// -#define IDD_OPTIONS 101 -#define IDC_BINDPORT 1001 -#define IDC_BINDIP 1002 -#define IDC_INTERACT 1003 -#define IDC_CURRTIMESTAMP 1004 -#define IDC_LOG 1005 -#define IDC_LOGFILE 1006 -#define IDC_OPEN 1007 -#define IDC_USERNAME 1008 -#define IDC_PASSWORD 1009 -#define IDC_STATUSSOCKS 1010 -#define IDC_STATUSCOMM 1011 -#define IDC_STATUSSKYPEPL 1012 -#define IDC_USESOCKS 1013 -#define IDC_STARTSOCKS 1014 -#define IDC_STOPSOCKS 1015 -#define IDC_USECOMM 1016 -#define IDC_STARTCOMM 1017 -#define IDC_STOPCOMM 1018 -#define IDC_CONSOLE 1019 -#define IDC_USESKYPEPL 1020 -#define IDC_STARTSKYPEPL 1021 -#define IDC_STOPSKYPEPL 1022 -#define IDC_USENETLIB 1023 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1020 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/sdk/m_updater.h b/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/sdk/m_updater.h deleted file mode 100644 index 371b7437a0..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/sdk/m_updater.h +++ /dev/null @@ -1,146 +0,0 @@ -#ifndef _M_UPDATER_H -#define _M_UPDATER_H - -// NOTES: -// - For langpack updates, include a string of the following format in the langpack text file: -// ";FLID: " -// version must be four numbers seperated by '.', in the range 0-255 inclusive -// - Updater will disable plugins that are downloaded but were not active prior to the update (this is so that, if an archive contains e.g. ansi and -// unicode versions, the correct plugin will be the only one active after the new version is installed)...so if you add a support plugin, you may need -// to install an ini file to make the plugin activate when miranda restarts after the update -// - Updater will replace all dlls that have the same internal shortName as a downloaded update dll (this is so that msn1.dll and msn2.dll, for example, -// will both be updated) - so if you have a unicode and a non-unicode version of a plugin in your archive, you should make the internal names different (which will break automatic -// updates from the file listing if there is only one file listing entry for both versions, unless you use the 'MS_UPDATE_REGISTER' service below) -// - Updater will install all files in the root of the archive into the plugins folder, except for langpack files that contain the FLID string which go into the root folder (same -// folder as miranda32.exe)...all folders in the archive will also be copied to miranda's root folder, and their contents transferred into the new folders. The only exception is a -// special folder called 'root_files' - if there is a folder by that name in the archive, it's contents will also be copied into miranda's root folder - this is intended to be used -// to install additional dlls etc that a plugin may require) - -// if you set Update.szUpdateURL to the following value when registering, as well as setting your beta site and version data, -// Updater will ignore szVersionURL and pbVersionPrefix, and attempt to find the file listing URL's from the backend XML data. -// for this to work, the plugin name in pluginInfo.shortName must match the file listing exactly (except for case) -#define UPDATER_AUTOREGISTER "UpdaterAUTOREGISTER" -// Updater will also use the backend xml data if you provide URL's that reference the miranda file listing for updates (so you can use that method -// if e.g. your plugin shortName does not match the file listing) - it will grab the file listing id from the end of these URLs - -typedef struct Update_tag { - int cbSize; - char *szComponentName; // component name as it will appear in the UI (will be translated before displaying) - - char *szVersionURL; // URL where the current version can be found (NULL to disable) - BYTE *pbVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data - // (note that this URL could point at a binary file - dunno why, but it could :) - int cpbVersionPrefix; // number of bytes pointed to by pbVersionPrefix - char *szUpdateURL; // URL where dll/zip is located - // set to UPDATER_AUTOREGISTER if you want Updater to find the file listing URLs (ensure plugin shortName matches file listing!) - - char *szBetaVersionURL; // URL where the beta version can be found (NULL to disable betas) - BYTE *pbBetaVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data - int cpbBetaVersionPrefix; // number of bytes pointed to by pbVersionPrefix - char *szBetaUpdateURL; // URL where dll/zip is located - - BYTE *pbVersion; // bytes of current version, used for comparison with those in VersionURL - int cpbVersion; // number of bytes pointed to by pbVersion - - char *szBetaChangelogURL; // url for displaying changelog for beta versions -} Update; - -// register a comonent with Updater -// -// wparam = 0 -// lparam = (LPARAM)&Update -#define MS_UPDATE_REGISTER "Update/Register" - -// utility functions to create a version string from a DWORD or from pluginInfo -// point buf at a buffer at least 16 chars wide - but note the version string returned may be shorter -// -__inline static char *CreateVersionString(DWORD version, char *buf) { - mir_snprintf(buf, 16, "%d.%d.%d.%d", (version >> 24) & 0xFF, (version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF); - return buf; -} - -__inline static char *CreateVersionStringPlugin(PLUGININFO *pluginInfo, char *buf) { - return CreateVersionString(pluginInfo->version, buf); -} - - -// register the 'easy' way - use this method if you have no beta URL and the plugin is on the miranda file listing -// NOTE: the plugin version string on the file listing must be the string version of the version in pluginInfo (i.e. 0.0.0.1, -// four numbers between 0 and 255 inclusivem, so no letters, brackets, etc.) -// -// wParam = (int)fileID - this is the file ID from the file listing (i.e. the number at the end of the download link) -// lParam = (PLUGININFO*)&pluginInfo -#define MS_UPDATE_REGISTERFL "Update/RegisterFL" - -// this function can be used to 'unregister' components - useful for plugins that register non-plugin/langpack components and -// may need to change those components on the fly -// lParam = (char *)szComponentName -#define MS_UPDATE_UNREGISTER "Update/Unregister" - -// this event is fired when the startup process is complete, but NOT if a restart is imminent -// it is designed for status managment plugins to use as a trigger for beggining their own startup process -// wParam = lParam = 0 (unused) -// (added in version 0.1.6.0) -#define ME_UPDATE_STARTUPDONE "Update/StartupDone" - -// this service can be used to enable/disable Updater's global status control -// it can be called from the StartupDone event handler -// wParam = (BOOL)enable -// lParam = 0 -// (added in version 0.1.6.0) -#define MS_UPDATE_ENABLESTATUSCONTROL "Update/EnableStatusControl" - -// An description of usage of the above service and event: -// Say you are a status control plugin that normally sets protocol or global statuses in your ModulesLoaded event handler. -// In order to make yourself 'Updater compatible', you would move the status control code from ModulesLoaded to another function, -// say DoStartup. Then, in ModulesLoaded you would check for the existence of the MS_UPDATE_ENABLESTATUSCONTROL service. -// If it does not exist, call DoStartup. If it does exist, hook the ME_UPDATE_STARTUPDONE event and call DoStartup from there. You may -// also wish to call MS_UPDATE_ENABLESTATUSCONTROL with wParam == FALSE at this time, to disable Updater's own status control feature. - -// this service can be used to determine whether updates are possible for a component with the given name -// wParam = 0 -// lParam = (char *)szComponentName -// returns TRUE if updates are supported, FALSE otherwise -#define MS_UPDATE_ISUPDATESUPPORTED "Update/IsUpdateSupported" - -#endif - - -/////////////// Usage Example /////////////// - -#ifdef EXAMPLE_CODE - -// you need to #include "m_updater.h" and HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded) in your Load function... - -int OnModulesLoaded(WPARAM wParam, LPARAM lParam) { - - Update update = {0}; // for c you'd use memset or ZeroMemory... - char szVersion[16]; - - update.cbSize = sizeof(Update); - - update.szComponentName = pluginInfo.shortName; - update.pbVersion = (BYTE *)CreateVersionString(&pluginInfo, szVersion); - update.cpbVersion = strlen((char *)update.pbVersion); - - // these are the three lines that matter - the archive, the page containing the version string, and the text (or data) - // before the version that we use to locate it on the page - // (note that if the update URL and the version URL point to standard file listing entries, the backend xml - // data will be used to check for updates rather than the actual web page - this is not true for beta urls) - update.szUpdateURL = "http://scottellis.com.au:81/test/updater.zip"; - update.szVersionURL = "http://scottellis.com.au:81/test/updater_test.html"; - update.pbVersionPrefix = (BYTE *)"Updater version "; - - update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix); - - // do the same for the beta versions of the above struct members if you wish to allow beta updates from another URL - - CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update); - - // Alternatively, to register a plugin with e.g. file ID 2254 on the file listing... - // CallService(MS_UPDATE_REGISTERFL, (WPARAM)2254, (LPARAM)&pluginInfo); - - return 0; -} - -#endif diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.c b/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.c deleted file mode 100644 index 0109bd6ede..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.c +++ /dev/null @@ -1,233 +0,0 @@ -#include "imo2sproxy.h" -#define WIN32_LEAN_AND_MEAN -#include -#include -#include "skypepluginlink.h" -#include "include/newpluginapi.h" -#include "include/m_system.h" - -#define LockMutex(x) EnterCriticalSection (&x) -#define UnlockMutex(x) LeaveCriticalSection(&x) -#define InitMutex(x) InitializeCriticalSection(&x) -#define ExitMutex(x) DeleteCriticalSection(&x) -#define mutex_t CRITICAL_SECTION - - -// ----------------------------------------------------------------------------- - -struct tag_proxyInst; -typedef struct tag_proxyInst IMO2SPROXY_INST; - -typedef struct -{ - IMOSAPI *hInst; - IMO2SPROXY_INST *hProxy; - mutex_t sendmutex; - mutex_t rcvmutex; - int iConnectionStat; -} CONNINST; - -struct tag_proxyInst -{ - IMO2SPROXY vtbl; // Must be first! - IMO2SPROXY_CFG *pCfg; - SKYPEPLUGINLINK_CFG *pMyCfg; - HANDLE hService; - CONNINST stClient; // Currently only 1 connection -}; - - -static CONNINST *m_pConn = NULL; - -// ----------------------------------------------------------------------------- - -static void EventHandler(char *pszMsg, void *pUser); -static int InitProxy(IMO2SPROXY_INST *hProxy); - -static int Imo2sproxy_Open(IMO2SPROXY *hInst); -static void Imo2sproxy_Loop(IMO2SPROXY *hInst); -static void Imo2sproxy_Exit(IMO2SPROXY *hInst); - -// ----------------------------------------------------------------------------- -static void EventHandler(char *pszMsg, void *pUser) -{ - CONNINST *pInst = (CONNINST*)pUser; - COPYDATASTRUCT cds; - DWORD dwRes = 0; - - //LockMutex (pInst->sendmutex); - if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) - { - fprintf (pInst->hProxy->pCfg->fpLog, "> %s\n", pszMsg); - fflush (pInst->hProxy->pCfg->fpLog); - } - cds.dwData = 0; - cds.cbData = strlen(pszMsg)+1; - cds.lpData = pszMsg; - CallService (SKYPE_PROTONAME PSS_SKYPEAPIMSG, 0, (LPARAM)&cds); - //UnlockMutex (pInst->sendmutex); -} - -// ----------------------------------------------------------------------------- - -INT_PTR CallIn(WPARAM wParam,LPARAM lParam) -{ - CONNINST *pInst = (CONNINST*)m_pConn; - PCOPYDATASTRUCT pCopyData = (PCOPYDATASTRUCT)lParam; - - if (!pInst) return -1; - - if (pInst->hProxy->pMyCfg->bDelayLogin && pInst->iConnectionStat < 1) - { - LockMutex (pInst->rcvmutex); - if (InitProxy(pInst->hProxy)<0) - { - UnlockMutex(pInst->rcvmutex); - return -1; - } - UnlockMutex(pInst->rcvmutex); - } - - if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) - { - fprintf (pInst->hProxy->pCfg->fpLog, "< [%s]\n", pCopyData->lpData); - fflush (pInst->hProxy->pCfg->fpLog); - } - Imo2S_Send (pInst->hInst, pCopyData->lpData); - return 0; -} - -// ----------------------------------------------------------------------------- - -static void FreeConnection (CONNINST *pInst) -{ - if (!pInst || !pInst->hProxy) return; - if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) - { - fprintf (pInst->hProxy->pCfg->fpLog, "SkypePluginLink: Closed connection\n"); - fflush (pInst->hProxy->pCfg->fpLog); - } - - if (pInst->hProxy->hService) - { - DestroyServiceFunction(pInst->hProxy->hService); - pInst->hProxy->hService = NULL; - CallService (SKYPE_PROTONAME SKYPE_REGPROXY, 0, 0); - } - ExitMutex(pInst->sendmutex); - ExitMutex(pInst->rcvmutex); - if (pInst->hInst) - { - IMOSAPI *hInst = pInst->hInst; - pInst->hInst = NULL; - Imo2S_Exit(hInst); - } -} - -// ----------------------------------------------------------------------------- - -static int InitProxy(IMO2SPROXY_INST *hProxy) -{ - char *pszError; - - if (!hProxy->stClient.hInst) - { - if (!(hProxy->stClient.hInst = Imo2S_Init(EventHandler, &hProxy->stClient, hProxy->pCfg->iFlags))) - { - hProxy->pCfg->logerror (stderr, "SkypePluginLink: Cannot start Imo2Skype instance.\n"); - return -1; - } - } - - // FIXME: We should enable logging dependent on a loglevel rather than just enabling it - Imo2S_SetLog (hProxy->stClient.hInst, hProxy->pCfg->fpLog); - - if (hProxy->stClient.iConnectionStat == 0 || - (hProxy->stClient.iConnectionStat = Imo2S_Login (hProxy->stClient.hInst, - hProxy->pCfg->pszUser, hProxy->pCfg->pszPass, &pszError)) != 1) - { - hProxy->pCfg->logerror (stderr, "SkypePluginLink: Cannot login with (%s/****): %s\n", - hProxy->pCfg->pszUser, pszError); - return -1; - } - return 0; -} - -// ----------------------------------------------------------------------------- -// PUBLIC -// ----------------------------------------------------------------------------- - -void SkypePluginLink_Defaults (SKYPEPLUGINLINK_CFG *pMyCfg) -{ - memset (pMyCfg, 0, sizeof(SKYPEPLUGINLINK_CFG)); - pMyCfg->bDelayLogin = TRUE; -} - -// ----------------------------------------------------------------------------- - -IMO2SPROXY *SkypePluginLink_Init (IMO2SPROXY_CFG *pCfg, SKYPEPLUGINLINK_CFG *pMyCfg) -{ - IMO2SPROXY_INST *pstInst = calloc(sizeof(IMO2SPROXY_INST), 1); - - pstInst->vtbl.Open = Imo2sproxy_Open; - pstInst->vtbl.Loop = Imo2sproxy_Loop; - pstInst->vtbl.Exit = Imo2sproxy_Exit; - pstInst->pCfg = pCfg; - pstInst->pMyCfg = pMyCfg; - return (IMO2SPROXY*)pstInst; -} - -// ----------------------------------------------------------------------------- -// IMPLEMENTATION -// ----------------------------------------------------------------------------- -static int Imo2sproxy_Open(IMO2SPROXY *hInst) -{ - IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst; - WNDCLASS WndClass ={0}; - - if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) - fprintf (hProxy->pCfg->fpLog, "SkypePluginLink:Open(Start)\n"); - - // Only 1 connection instance, so we can init it right here - InitMutex(hProxy->stClient.sendmutex); - InitMutex(hProxy->stClient.rcvmutex); - hProxy->stClient.hProxy = hProxy; - m_pConn = &hProxy->stClient; - - // Register with Skype Plugin - hProxy->hService = CreateServiceFunction("IMO2SPROXY" PSS_SKYPEAPIMSG, CallIn); - CallService (SKYPE_PROTONAME SKYPE_REGPROXY, 0, (LPARAM)"IMO2SPROXY" PSS_SKYPEAPIMSG); - hProxy->stClient.iConnectionStat = -1; - - if (!hProxy->pMyCfg->bDelayLogin) - { - if (InitProxy(hProxy)<0) - { - FreeConnection(&hProxy->stClient); - return -1; - } - } - return 0; -} - -// ----------------------------------------------------------------------------- - -static void Imo2sproxy_Loop(IMO2SPROXY *hInst) -{ - // No loop needed for call-in -} - - -// ----------------------------------------------------------------------------- - -static void Imo2sproxy_Exit(IMO2SPROXY *hInst) -{ - IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst; - - if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) - fprintf (hProxy->pCfg->fpLog, "SkypePluginLink:Exit()\n"); - - FreeConnection (&hProxy->stClient); - free (hProxy); -} - diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.h b/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.h deleted file mode 100644 index ecc520ff1e..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.h +++ /dev/null @@ -1,10 +0,0 @@ -typedef struct { - int bDelayLogin; -} SKYPEPLUGINLINK_CFG; - -#define SKYPE_PROTONAME "SKYPE" -#define PSS_SKYPEAPIMSG "/SendSkypeAPIMsg" -#define SKYPE_REGPROXY "/RegisterProxySvc" - -void SkypePluginLink_Defaults (SKYPEPLUGINLINK_CFG *pMyCfg); -IMO2SPROXY *SkypePluginLink_Init (IMO2SPROXY_CFG *pCfg, SKYPEPLUGINLINK_CFG *pMyCfg); diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.c b/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.c deleted file mode 100644 index 7f1db504e9..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.c +++ /dev/null @@ -1,158 +0,0 @@ -/* Module: msgqueue.c - Purpose: Message queue for incoming messages - Author: leecher - Date: 30.08.2009 - - Fixme: Sort on insert, do a binary search instead of iterating list. -*/ - -#include -#include -#include -#include "msgqueue.h" -#include "buddylist.h" - -static volatile unsigned int m_uMsgNr=0; -static void FreeEntry(void *pEntry); - -// ----------------------------------------------------------------------------- -// Interface -// ----------------------------------------------------------------------------- - -TYP_LIST *MsgQueue_Init(void) -{ - TYP_LIST *hList = List_Init(16); - - return hList; -} - -// ----------------------------------------------------------------------------- - -void MsgQueue_Exit(TYP_LIST *hList) -{ - Queue_Exit(hList, FreeEntry); -} - -// ----------------------------------------------------------------------------- - -MSGENTRY *MsgQueue_Insert(TYP_LIST *hList, cJSON *pNick) -{ - MSGENTRY *pEntry; - cJSON *pVal; - - if (!(pEntry = Queue_InsertEntry(hList, sizeof(MSGENTRY), ++m_uMsgNr, - FreeEntry))) return NULL; - pEntry->pszUser = strdup(cJSON_GetObjectItem(pNick, "buid")->valuestring); - pEntry->pszAlias = strdup(cJSON_GetObjectItem(pNick, "alias")->valuestring); - pEntry->pszMessage = strdup(cJSON_GetObjectItem(pNick, "msg")->valuestring); - pEntry->timestamp = cJSON_GetObjectItem(pNick, "timestamp")->valueint; - if (pVal = cJSON_GetObjectItem(pNick, "author")) pEntry->pszAuthor=strdup(pVal->valuestring); - strcpy (pEntry->szStatus, "RECEIVED"); - strcpy (pEntry->szType, "TEXT"); - // imo.im somehow sets group topic via recv_im?? - if (strcmp(pEntry->pszAlias, pEntry->pszMessage) == 0) strcpy (pEntry->szType, "SETTOPIC"); - return pEntry; -} - -// ----------------------------------------------------------------------------- - -MSGENTRY *MsgQueue_AddReflect(TYP_LIST *hList, cJSON *pNick, TYP_LIST *hBuddyList) -{ - MSGENTRY *pEntry; - cJSON *pVal; - - if (!(pEntry = Queue_InsertEntry(hList, sizeof(MSGENTRY), ++m_uMsgNr, - FreeEntry))) return NULL; - pEntry->pszUser = strdup(cJSON_GetObjectItem(pNick, "buid")->valuestring); - - // Usually no alias in Reflection, so query buddy list, if available - if (pVal = cJSON_GetObjectItem(pNick, "alias")) - pEntry->pszAlias = strdup(pVal->valuestring); - else - { - NICKENTRY *pBuddy = hBuddyList?BuddyList_Find (hBuddyList, pEntry->pszUser):NULL; - pEntry->pszAlias = strdup (pBuddy?pBuddy->pszAlias:pEntry->pszUser); - } - - pEntry->pszMessage = strdup(cJSON_GetObjectItem(pNick, "msg")->valuestring); - pEntry->timestamp = cJSON_GetObjectItem(pNick, "timestamp")->valueint; - strcpy (pEntry->szStatus, "SENT"); - return pEntry; -} - -// ----------------------------------------------------------------------------- - -MSGENTRY *MsgQueue_AddSent(TYP_LIST *hList, char *pszUser, char *pszAlias, char *pszMessage, unsigned int *puMsgId) -{ - MSGENTRY *pEntry; - - if (!(pEntry = Queue_InsertEntry(hList, sizeof(MSGENTRY), ++m_uMsgNr, - FreeEntry))) return NULL; - pEntry->pszUser = strdup(pszUser); - pEntry->pszAlias = strdup(pszAlias); - pEntry->pszMessage = strdup(pszMessage); - time (&pEntry->timestamp); - strcpy (pEntry->szStatus, "SENDING"); - if (puMsgId) *puMsgId = pEntry->hdr.uMsgNr; - return pEntry; -} - -// ----------------------------------------------------------------------------- - -MSGENTRY *MsgQueue_AddEvent(TYP_LIST *hList, char *pszUser, char *pszType) -{ - MSGENTRY *pEntry; - - if (!(pEntry = Queue_InsertEntry(hList, sizeof(MSGENTRY), ++m_uMsgNr, - FreeEntry))) return NULL; - pEntry->pszUser = strdup(pszUser); - time (&pEntry->timestamp); - strcpy (pEntry->szStatus, "RECEIVED"); - strcpy (pEntry->szType, pszType); - return pEntry; -} - -// ----------------------------------------------------------------------------- - -BOOL MsgQueue_Remove(TYP_LIST *hList, unsigned int uMsgNr) -{ - return Queue_Remove(hList, uMsgNr, FreeEntry); -} - -// ----------------------------------------------------------------------------- - -MSGENTRY *MsgQueue_Find(TYP_LIST *hList, unsigned int uMsgNr) -{ - return (MSGENTRY*)Queue_Find(hList, uMsgNr); -} - -// ----------------------------------------------------------------------------- - -MSGENTRY *MsgQueue_FindByRqId(TYP_LIST *hList, unsigned int uRqId) -{ - unsigned int i; - MSGENTRY *pEntry; - - for (i=List_Count(hList)-1; (int)i!=-1; i--) - { - pEntry = (MSGENTRY*)List_ElementAt (hList, i); - if (pEntry->uRqId == uRqId) - return pEntry; - } - return NULL; -} - -// ----------------------------------------------------------------------------- -// Static -// ----------------------------------------------------------------------------- - -static void FreeEntry(void *pPEntry) -{ - MSGENTRY *pEntry = (MSGENTRY*)pPEntry; - - if (pEntry->pszAlias) free (pEntry->pszAlias); - free (pEntry->pszUser); - if (pEntry->pszMessage) free (pEntry->pszMessage); - if (pEntry->pszAuthor) free (pEntry->pszAuthor); -} - diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.h b/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.h deleted file mode 100644 index ac8ce1cf8d..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.h +++ /dev/null @@ -1,28 +0,0 @@ -#include "cJSON.h" -#include "queue.h" -#include - -typedef struct -{ - QUEUEHDR hdr; - char *pszUser; - char *pszAuthor; // In case of groupchat, pszUser is the Groupchat ID and pszAuthor is the user sending it, if not a GC message, pszAuthor is NULL - char *pszAlias; - char *pszMessage; - time_t timestamp; - char szStatus[16]; - char szFailure[256]; - char szType[20]; // TEXT, SETTOPIC, ADDEDMEMBERS, CREATEDCHATWITH, LEFT, KICKED, ... - unsigned int uRqId; -} MSGENTRY; - -TYP_LIST *MsgQueue_Init(void); -void MsgQueue_Exit(TYP_LIST *hList); - -MSGENTRY *MsgQueue_Insert(TYP_LIST *hList, cJSON *pNick); -MSGENTRY *MsgQueue_AddReflect(TYP_LIST *hList, cJSON *pNick, TYP_LIST *hBuddyList); -MSGENTRY *MsgQueue_AddSent(TYP_LIST *hList, char *pszUser, char *pszAlias, char *pszMessage, unsigned int *puMsgId); -MSGENTRY *MsgQueue_AddEvent(TYP_LIST *hList, char *pszUser, char *pszType); -BOOL MsgQueue_Remove(TYP_LIST *hList, unsigned int uMsgNr); -MSGENTRY *MsgQueue_Find(TYP_LIST *hList, unsigned int uMsgNr); -MSGENTRY *MsgQueue_FindByRqId(TYP_LIST *hList, unsigned int uRqId); diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/queue.c b/!NotAdopted/IMO2sProxy/src/imo2skype/queue.c deleted file mode 100644 index a163314c8e..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/queue.c +++ /dev/null @@ -1,94 +0,0 @@ -/* Module: queue.c - Purpose: Queue management - Author: leecher - Date: 02.09.2009 -*/ - -#include -#include -#include -#include "memlist.h" -#include "queue.h" - -// Maximum threshold for queues (So that we don't leak memory) -#define THRESHOLD 50 - -// ----------------------------------------------------------------------------- -// Interface -// ----------------------------------------------------------------------------- - -void Queue_Exit(TYP_LIST *hList, void (*fpFree)(void *pEntry)) -{ - void *pEntry; - - while (pEntry=List_Pop(hList)) - { - if (fpFree) fpFree(pEntry); - free (pEntry); - } - List_Exit(hList); -} - -// ----------------------------------------------------------------------------- - -void* Queue_InsertEntry (TYP_LIST *hList, unsigned int cbSize, unsigned int uMsgNr, - void (*fpFree)(void *pEntry)) -{ - void *pEntry; - - if (!(pEntry = calloc (1, cbSize))) return NULL; - if (!List_Push(hList, pEntry)) - { - free (pEntry); - return NULL; - } else ((QUEUEHDR*)pEntry)->uMsgNr = uMsgNr; -#ifdef THRESHOLD - if (List_Count(hList)>THRESHOLD) - { - void *pEntry = List_RemoveElementAt(hList, 0); - - if (pEntry) fpFree (pEntry); - free (pEntry); - } -#endif - return pEntry; -} - -// ----------------------------------------------------------------------------- - -BOOL Queue_Remove(TYP_LIST *hList, unsigned int uMsgNr, void (*fpFree)(void *pEntry)) -{ - QUEUEHDR *pListEntry; - unsigned int i; - - for (i=List_Count(hList)-1; (int)i!=-1; i--) - { - pListEntry = List_ElementAt (hList, i); - if (pListEntry->uMsgNr == uMsgNr) - { - if (fpFree) fpFree (pListEntry); - List_RemoveElementAt(hList, i); - free (pListEntry); - return TRUE; - } - } - return FALSE; -} - -// ----------------------------------------------------------------------------- - -void *Queue_Find(TYP_LIST *hList, unsigned int uMsgNr) -{ - unsigned int i; - QUEUEHDR *pEntry; - - for (i=List_Count(hList)-1; (int)i!=-1; i--) - { - pEntry = (QUEUEHDR*)List_ElementAt (hList, i); - if (pEntry->uMsgNr == uMsgNr) - return pEntry; - } - return NULL; -} - -// ----------------------------------------------------------------------------- diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/queue.h b/!NotAdopted/IMO2sProxy/src/imo2skype/queue.h deleted file mode 100644 index 4f42a3b42f..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/queue.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __QUEUE_H__ -#define __QUEUE_H__ - -#include "memlist.h" - -typedef struct -{ - unsigned int uMsgNr; -} QUEUEHDR; - -void Queue_Exit(TYP_LIST *hList, void (*fpFree)(void *pEntry)); -void* Queue_InsertEntry (TYP_LIST *hList, unsigned int cbSize, unsigned int uMsgNr, - void (*fpFree)(void *pEntry)); -BOOL Queue_Remove(TYP_LIST *hList, unsigned int uMsgNr, void (*fpFree)(void *pEntry)); -void *Queue_Find(TYP_LIST *hList, unsigned int uMsgNr); - -#endif diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c b/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c deleted file mode 100644 index 20c56a7a66..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c +++ /dev/null @@ -1,565 +0,0 @@ -/* Module: imo2skypeproxy.c - Purpose: Implementation of imo2skype API as Skype proxy (for Miranda Skype plugin) - Author: leecher - Date: 01.09.2009 - - Changelog: - 1.00 - 01.09.2009 - Initial release - 1.01 - 02.09.2009 - Little bugfix for Onlinestatus, introduced mutex for send thread. - 1.02 - 02.09.2009 - Added support for incoming call notifications and expired sessions. - 1.03 - 03.09.2009 - As WIN32-port of libcurl is a total mess, Win32-version now uses WinINET. - 1.04 - 04.09.2009 - Added support for searching, adding and removing buddies - 1.05 - 06.09.2009 - * Mapped "busy" to DND, not NA, as forum user AL|EN proposed. - * Mood text will now also be sent on status change of a contact - (doesn't really have an effect though) - * New Parameter -d (daemonize) to launch proxy in background - * Fixed a bug with a crash when encoding umlauts on Win32 - 1.06 - 25.09.2009 - Added parameter -t for local timestamps. - 1.07 - 07.10.2009 - Bugfix: Added parsing of multiple JSON messages - Added support for writing to logfile while in daemon mode (-l) - 1.08 - 18.10.2009 - Added support for voice calls via imo.im flash on WIN32 (-i) - - Limited memory queues to 50 entries to reduce memory usage. - 1.09 - 07.11.2009 - Split command line main module and proxy module to make proxy - accessible by different layers (i.e. new Miranda Plugin layer) - 1.10 - 14.12.2009 - Bug in the cJson library. The authors used the String as second - sprintf-Parameter which contains the format string instead of - ["%s", StringParam] causing problems sending Messages containt a % - - Added some space in the dialog for translations and added Translate() - function to some strings in the Wrapper-DLL - - More verbose output if you enable logging - - Fixes a Bug that caused the plugin to block after going offline - and reconnecting back online - - Hopefully fixed a severe threading problem: The Send-Mutex was not - covering a full transaction, but only 1 send causing the receiver - the receive garbled data causing "An existing connection was forcibly - closed by the remote host." error. - - Imo2S_Exit freed the temporary buffer too early resulting in a crash - on exit. - 1.12 - 19.04.2010 - POST interface changed from www.imo.im/amy to s.imo.im/amy - 1.13 - 19.12.2010 - imo.im modified their interface, so tried to adapt the communication - routines at low level to be compatible again. There still may be - many bugs. Don't forget to turn off history logging in the options - at https://imo.im - There also seems to be a nice new feature called "reflection" so that - you can login from multiple sessions and messages etc. entered there - will be reflected to the current session. This may be addressed in one - of the next builds... -*/ - -#include -#include "imo2sproxy.h" -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#define thread_t HANDLE -#define LockMutex(x) EnterCriticalSection (&x) -#define UnlockMutex(x) LeaveCriticalSection(&x) -#define InitMutex(x) InitializeCriticalSection(&x) -#define ExitMutex(x) DeleteCriticalSection(&x) -#define strcasecmp stricmp -#define strncasecmp stricmpn -#define mutex_t CRITICAL_SECTION -#define SHUT_RD SD_RECEIVE -#define SHUT_WR SD_SEND -#define SHUT_RDWR SD_BOTH -#else -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define SOCKET int -#define thread_t pthread_t -#define mutex_t pthread_mutex_t -#define INVALID_SOCKET -1 -#define SOCKET_ERROR INVALID_SOCKET -#define closesocket close -#define LockMutex(x) pthread_mutex_lock(&x) -#define UnlockMutex(x) pthread_mutex_unlock(&x) -#define InitMutex(x) pthread_mutex_init(&x, NULL); -#define ExitMutex(x) -#endif -#include -#include -#include -#include "memlist.h" -#include "socksproxy.h" - -// ----------------------------------------------------------------------------- - -#define AUTHENTICATE 0x01 -#define CAPABILITIES 0x02 -#define USE_AUTHENTICATION 0x01 - -typedef struct -{ - IMO2SPROXY vtbl; // Must be first! - IMO2SPROXY_CFG *pCfg; - SOCKSPROXY_CFG *pMyCfg; - - SOCKET listen_fd; - volatile int iRunning; - mutex_t loopmutex; -} IMO2SPROXY_INST; - -typedef struct -{ - SOCKET hSock; - thread_t hThread; - IMOSAPI *hInst; - int iConnectionStat; - mutex_t connected; - mutex_t sendmutex; - IMO2SPROXY_INST *hProxy; -} CONNINST; - - -// ----------------------------------------------------------------------------- - -static void EventHandler(char *pszMsg, void *pUser); -static void DispatcherThread(void *pUser); -static int Dispatcher_Start(CONNINST *pInst); -static int Dispatcher_Stop(CONNINST *pInst); -static char *GetError(void); -static int RcvPacket (CONNINST *pInst, void *buf, int len); -static int SendPacket (CONNINST *pInst, void *buf, int len); -static void FreeConnection (CONNINST *pInst); -static void CleanConnections (TYP_LIST *hList); -static SOCKET Init(unsigned long int lHost, short sPort, int iMaxConn); -static void Loop(SOCKET listen_fd); -static void Exit(SOCKET listen_fd); - -static int Imo2sproxy_Open(IMO2SPROXY *hInst); -static void Imo2sproxy_Loop(IMO2SPROXY *hInst); -static void Imo2sproxy_Exit(IMO2SPROXY *hInst); - -// ----------------------------------------------------------------------------- -static void EventHandler(char *pszMsg, void *pUser) -{ - CONNINST *pInst = (CONNINST*)pUser; - unsigned int uiLen = strlen (pszMsg); - static BOOL bFirstLogin = TRUE; - - if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) - { - fprintf (pInst->hProxy->pCfg->fpLog, "%03d> %s\n", pInst->hSock, pszMsg); - fflush (pInst->hProxy->pCfg->fpLog); - } - if (bFirstLogin && strncmp (pszMsg, "CONNSTATUS", 10) == 0 && - strcmp(pszMsg+11, "CONNECTING")) - { - pInst->iConnectionStat = (strcmp(pszMsg+11, "ONLINE")==0); - UnlockMutex (pInst->connected); - bFirstLogin = FALSE; - } - LockMutex(pInst->sendmutex); - if (!(SendPacket (pInst, &uiLen, sizeof(uiLen)) && SendPacket (pInst, pszMsg, uiLen))) - { - //Dispatcher_Stop(pInst); - //FreeConnection (pInst); - } - UnlockMutex(pInst->sendmutex); -} - -// ----------------------------------------------------------------------------- - -static void DispatcherThread(void *pUser) -{ - CONNINST *pInst = (CONNINST*)pUser; - char *pszUser, *pszPass, *pszError, *pszMsgBuf=NULL; - unsigned int uiLength, cbMsgBuf=0, bAuthenticated = 0, iConnected=0, iLogin=1; - char command=0, reply=0; - - if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) - fprintf (pInst->hProxy->pCfg->fpLog, "Imo2sproxy::DispatcherThread()\n"); - - if (!(pInst->hInst = Imo2S_Init(EventHandler, pInst, pInst->hProxy->pCfg->iFlags))) - { - pInst->hProxy->pCfg->logerror (stderr, "Connection %d: Cannot start Imo2Skype instance.\n", pInst->hSock); - FreeConnection (pInst); - return; - } - - // FIXME: Static user+pass from cmdline, until there is a possibility for - // a client to authenticate - pszUser = pInst->hProxy->pCfg->pszUser; - pszPass = pInst->hProxy->pCfg->pszPass; - - // FIXME: We should enable logging dependent on a loglevel rather than just enabling it - if (pInst->hProxy->pCfg->bVerbose) - Imo2S_SetLog (pInst->hInst, pInst->hProxy->pCfg->fpLog); - - - while (pInst->hProxy->iRunning) - { - if (RcvPacket(pInst, &uiLength, sizeof(uiLength))<=0) break; - LockMutex(pInst->sendmutex); - - if (uiLength == 0) - { - if (RcvPacket(pInst, &command, 1)<=0) - { - UnlockMutex(pInst->sendmutex); - break; - } - switch (command) - { - case AUTHENTICATE: - if (pInst->hProxy->pMyCfg->pszAuthPass) reply=1; - break; - case CAPABILITIES: - if (pInst->hProxy->pMyCfg->pszAuthPass) reply=USE_AUTHENTICATION; - break; - } - if (SendPacket (pInst, &reply, 1)<=0) - { - UnlockMutex(pInst->sendmutex); - break; - } - UnlockMutex(pInst->sendmutex); - continue; - } - - if (uiLength >= cbMsgBuf) - { - pszMsgBuf = realloc (pszMsgBuf, uiLength+1); - if (!pszMsgBuf) - { - UnlockMutex(pInst->sendmutex); - break; - } - cbMsgBuf=uiLength+1; - } - - if (RcvPacket(pInst, pszMsgBuf, uiLength)<=0) - { - UnlockMutex(pInst->sendmutex); - break; - } - - if (command) - { - if (command == AUTHENTICATE) - { - bAuthenticated = pInst->hProxy->pMyCfg->pszAuthPass && strcmp(pInst->hProxy->pMyCfg->pszAuthPass, pszMsgBuf) == 0; - if (SendPacket (pInst, &bAuthenticated, 1)<=0) - { - UnlockMutex(pInst->sendmutex); - break; - } - } - command = 0; - } - UnlockMutex(pInst->sendmutex); - - if (iLogin) - { - if (Imo2S_Login (pInst->hInst, pszUser, pszPass, &pszError) != 1) - { - pInst->hProxy->pCfg->logerror (stderr, "Connection %d: Cannot login with (%s/****): %s\n", - pInst->hSock, pszUser, pszError); - FreeConnection (pInst); - return; - } - iLogin = 0; - } - - if (pInst->hProxy->pMyCfg->pszAuthPass && !bAuthenticated)continue; - pszMsgBuf[uiLength]=0; - if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) - { - fprintf (pInst->hProxy->pCfg->fpLog, "%03d< [%s]\n", pInst->hSock, pszMsgBuf); - fflush (pInst->hProxy->pCfg->fpLog); - } - if (!iConnected) - { - LockMutex (pInst->connected); - iConnected = pInst->iConnectionStat; - if (!iConnected) - { - pInst->hProxy->pCfg->logerror(stderr, "Invalid username / password"); - } - } - Imo2S_Send (pInst->hInst, pszMsgBuf); - } - - FreeConnection (pInst); - if (pszMsgBuf) free (pszMsgBuf); - return; -} - -// ----------------------------------------------------------------------------- - -#ifdef WIN32 -static int Dispatcher_Start(CONNINST *pInst) -{ - DWORD ThreadID; - - return (pInst->hThread=(thread_t)_beginthreadex(NULL, 0, - (unsigned(__stdcall *)(void*))DispatcherThread, pInst, 0, &ThreadID))!=0; - -} - -static int Dispatcher_Stop(CONNINST *pInst) -{ - return pInst->hThread?TerminateThread (pInst->hThread, 0):1; -} - -static char *GetError(void) -{ - static char szMessage[1024]; - DWORD dwErr = WSAGetLastError(); - - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, 0, szMessage, sizeof(szMessage), NULL); - return szMessage; -} - -#else -static int Dispatcher_Start(CONNINST *pInst) -{ - return pthread_create(&pInst->hThread, NULL, DispatcherThread, pInst)==0; -} - -static int Dispatcher_Stop(CONNINST *pInst) -{ - if (!pInst->hThread || pthread_cancel(pInst->hThread)) - { - pInst->hThread=0; - return 1; - } - return 0; -} - -static char *GetError(void) -{ - return strerror (errno); -} - -#endif - -// ----------------------------------------------------------------------------- - -static int RcvPacket (CONNINST *pInst, void *buf, int len) -{ - int iReceived = recv (pInst->hSock, buf, len, 0); - if (iReceived <= 0) - pInst->hProxy->pCfg->logerror(stderr, "Connection %d (Receive): %s", pInst->hSock, GetError()); - return iReceived; -} - -// ----------------------------------------------------------------------------- - -static int SendPacket (CONNINST *pInst, void *buf, int len) -{ - int iSent; - - iSent = send (pInst->hSock, buf, len, 0); - if (iSent <= 0) - pInst->hProxy->pCfg->logerror (stderr, "Connection %d (Send): %s", pInst->hSock, GetError()); - return iSent; -} -// ----------------------------------------------------------------------------- - -static void FreeConnection (CONNINST *pInst) -{ - if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) - { - fprintf (pInst->hProxy->pCfg->fpLog, "Closed connection %d\n", pInst->hSock); - fflush (pInst->hProxy->pCfg->fpLog); - } - if (pInst->hSock != INVALID_SOCKET) - closesocket(pInst->hSock); - pInst->hSock = INVALID_SOCKET; - pInst->hThread = 0; - ExitMutex (pInst->connected); - ExitMutex (pInst->sendmutex); - if (pInst->hInst) - { - IMOSAPI *hInst = pInst->hInst; - pInst->hInst = NULL; - Imo2S_Exit(hInst); - } -} - -// ----------------------------------------------------------------------------- - -static void CleanConnections (TYP_LIST *hList) -{ - unsigned int i; - CONNINST *hInst; - - for (i=0; ihThread == 0) - { - free (List_RemoveElementAt(hList, i)); - i--; - } - } -} - -// ----------------------------------------------------------------------------- -// PUBLIC -// ----------------------------------------------------------------------------- - -void SocksProxy_Defaults (SOCKSPROXY_CFG *pMyCfg) -{ - memset (pMyCfg, 0, sizeof(SOCKSPROXY_CFG)); - pMyCfg->lAddr = htonl(INADDR_ANY); - pMyCfg->sPort = 1401; - pMyCfg->iMaxConn = SOMAXCONN; -} - -// ----------------------------------------------------------------------------- - -IMO2SPROXY *SocksProxy_Init (IMO2SPROXY_CFG *pCfg, SOCKSPROXY_CFG *pMyCfg) -{ - IMO2SPROXY_INST *pstInst = calloc(sizeof(IMO2SPROXY_INST), 1); - - pstInst->vtbl.Open = Imo2sproxy_Open; - pstInst->vtbl.Loop = Imo2sproxy_Loop; - pstInst->vtbl.Exit = Imo2sproxy_Exit; - pstInst->pCfg = pCfg; - pstInst->pMyCfg = pMyCfg; - InitMutex(pstInst->loopmutex); - return (IMO2SPROXY*)pstInst; -} - -// ----------------------------------------------------------------------------- -// IMPLEMENTATION -// ----------------------------------------------------------------------------- -static int Imo2sproxy_Open(IMO2SPROXY *hInst) -{ - struct sockaddr_in sock={0}; - int yes = 1; - IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst; - -#ifdef WIN32 - WSADATA wsaData; - - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) - { - hProxy->pCfg->logerror (stderr, "WSAStartup failed"); - return INVALID_SOCKET; - } -#endif - if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) - fprintf (hProxy->pCfg->fpLog, "Socksproxy:Loop(Start)\n"); - hProxy->listen_fd = socket(PF_INET, SOCK_STREAM, 0); - if(hProxy->listen_fd == INVALID_SOCKET) return -1; - if (setsockopt(hProxy->listen_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(int))<0) - { - hProxy->pCfg->logerror (stderr, "Cannot set socket options to SO_REUSEADDR"); - closesocket(hProxy->listen_fd); - return -1; - } - sock.sin_family = AF_INET; - sock.sin_addr.s_addr = hProxy->pMyCfg->lAddr; - sock.sin_port = htons(hProxy->pMyCfg->sPort); - - if (bind(hProxy->listen_fd, (struct sockaddr *) &sock, sizeof(sock)) != 0) - { - hProxy->pCfg->logerror (stderr, "Cannot bind socket"); - closesocket(hProxy->listen_fd); - return -1; - } - - if (listen(hProxy->listen_fd, hProxy->pMyCfg->iMaxConn) < 0) - { - hProxy->pCfg->logerror (stderr, "Cannot listen on socket"); - closesocket(hProxy->listen_fd); - return -1; - } - - return 0; -} - -// ----------------------------------------------------------------------------- - -static void Imo2sproxy_Loop(IMO2SPROXY *hInst) -{ - struct sockaddr_in sock; - int socklen; - SOCKET new_fd; - TYP_LIST *hConns = List_Init(32); - CONNINST *pInst; - IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst; - fd_set fdListen; - - if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) - fprintf (hProxy->pCfg->fpLog, "Socksproxy:Loop(Start)\n"); - hProxy->iRunning = 1; - LockMutex(hProxy->loopmutex); - while (hProxy->iRunning) - { - FD_ZERO(&fdListen); - FD_SET(hProxy->listen_fd, &fdListen); - socklen = sizeof(sock); - if (select (0, &fdListen, NULL, NULL, NULL) != SOCKET_ERROR && FD_ISSET(hProxy->listen_fd, &fdListen)) - { - new_fd = accept(hProxy->listen_fd, (struct sockaddr *) &sock, &socklen); - if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) - { - fprintf (hProxy->pCfg->fpLog, "Connection from %s:%d -> Connection: %d\n", inet_ntoa(sock.sin_addr), - ntohs(sock.sin_port), new_fd); - fflush (hProxy->pCfg->fpLog); - } - if (new_fd != INVALID_SOCKET && (pInst = calloc (1, sizeof(CONNINST)))) - { - CleanConnections (hConns); - List_Push(hConns, pInst); - pInst->hSock = new_fd; - pInst->hProxy = hProxy; - InitMutex(pInst->connected); - LockMutex(pInst->connected); - InitMutex(pInst->sendmutex); - Dispatcher_Start(pInst); - } - } - } - if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) - fprintf (hProxy->pCfg->fpLog, "Socksproxy:Loop(End)\n"); - - CleanConnections (hConns); - while (pInst=List_Pop(hConns)) - { - Dispatcher_Stop(pInst); - FreeConnection(pInst); - free (pInst); - } - List_Exit(hConns); - UnlockMutex(hProxy->loopmutex); -} - - -// ----------------------------------------------------------------------------- - -static void Imo2sproxy_Exit(IMO2SPROXY *hInst) -{ - IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst; - - if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) - fprintf (hProxy->pCfg->fpLog, "Socksproxy:Exit()\n"); - - hProxy->iRunning = 0; - shutdown (hProxy->listen_fd, SHUT_RDWR); - closesocket (hProxy->listen_fd); - LockMutex(hProxy->loopmutex); - -/* -#ifdef WIN32 - WSACleanup(); -#endif -*/ - UnlockMutex(hProxy->loopmutex); - ExitMutex(hProxy->loopmutex); - free (hProxy); -} - diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.h b/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.h deleted file mode 100644 index 6010e749f1..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.h +++ /dev/null @@ -1,11 +0,0 @@ -typedef struct -{ - char *pszAuthPass; - unsigned long int lAddr; - short sPort; - int iMaxConn; -} SOCKSPROXY_CFG; - - -void SocksProxy_Defaults (SOCKSPROXY_CFG *pMyCfg); -IMO2SPROXY *SocksProxy_Init (IMO2SPROXY_CFG *pCfg, SOCKSPROXY_CFG *pMyCfg); diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.c b/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.c deleted file mode 100644 index 8053a3c16d..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.c +++ /dev/null @@ -1,1143 +0,0 @@ -/* Module: win32_browsewnd.c - Purpose: Displays a window with an embedded browser in order to display the Voicechat - flash from imo.im - This example is bsaed on the work of Jeff Glatt (http://www.codeproject.com/KB/COM/cwebpage.aspx?msg=2852721) - Author: leecher, credits go to Jeff Glatt for his excellent work. - Date: 18.10.2009 -*/ - -#include -#include -#include -#include -#include -#include "memlist.h" -#include "w32browser.h" - -#ifndef _WIN64 -#if WINVER<0x0500 -#define SetWindowLongPtr SetWindowLong -#define GetWindowLongPtr GetWindowLong -#endif -#ifndef LONG_PTR -#define LONG_PTR LONG -#endif -#ifndef GWLP_USERDATA -#define GWLP_USERDATA GWL_USERDATA -#endif -#endif - -static const SAFEARRAYBOUND ArrayBound = {1, 0}; -static TYP_LIST *m_hWindows = NULL; -static DWORD m_dwThread = 0; -static HANDLE m_hThread = NULL, m_hEvent = NULL; - - -HRESULT STDMETHODCALLTYPE Frame_QueryInterface(IOleInPlaceFrame FAR* This, REFIID riid, LPVOID FAR* ppvObj); -HRESULT STDMETHODCALLTYPE Frame_AddRef(IOleInPlaceFrame FAR* This); -HRESULT STDMETHODCALLTYPE Frame_Release(IOleInPlaceFrame FAR* This); -HRESULT STDMETHODCALLTYPE Frame_GetWindow(IOleInPlaceFrame FAR* This, HWND FAR* lphwnd); -HRESULT STDMETHODCALLTYPE Frame_ContextSensitiveHelp(IOleInPlaceFrame FAR* This, BOOL fEnterMode); -HRESULT STDMETHODCALLTYPE Frame_GetBorder(IOleInPlaceFrame FAR* This, LPRECT lprectBorder); -HRESULT STDMETHODCALLTYPE Frame_RequestBorderSpace(IOleInPlaceFrame FAR* This, LPCBORDERWIDTHS pborderwidths); -HRESULT STDMETHODCALLTYPE Frame_SetBorderSpace(IOleInPlaceFrame FAR* This, LPCBORDERWIDTHS pborderwidths); -HRESULT STDMETHODCALLTYPE Frame_SetActiveObject(IOleInPlaceFrame FAR* This, IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName); -HRESULT STDMETHODCALLTYPE Frame_InsertMenus(IOleInPlaceFrame FAR* This, HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths); -HRESULT STDMETHODCALLTYPE Frame_SetMenu(IOleInPlaceFrame FAR* This, HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject); -HRESULT STDMETHODCALLTYPE Frame_RemoveMenus(IOleInPlaceFrame FAR* This, HMENU hmenuShared); -HRESULT STDMETHODCALLTYPE Frame_SetStatusText(IOleInPlaceFrame FAR* This, LPCOLESTR pszStatusText); -HRESULT STDMETHODCALLTYPE Frame_EnableModeless(IOleInPlaceFrame FAR* This, BOOL fEnable); -HRESULT STDMETHODCALLTYPE Frame_TranslateAccelerator(IOleInPlaceFrame FAR* This, LPMSG lpmsg, WORD wID); - -IOleInPlaceFrameVtbl MyIOleInPlaceFrameTable = {Frame_QueryInterface, -Frame_AddRef, -Frame_Release, -Frame_GetWindow, -Frame_ContextSensitiveHelp, -Frame_GetBorder, -Frame_RequestBorderSpace, -Frame_SetBorderSpace, -Frame_SetActiveObject, -Frame_InsertMenus, -Frame_SetMenu, -Frame_RemoveMenus, -Frame_SetStatusText, -Frame_EnableModeless, -Frame_TranslateAccelerator}; - -typedef struct { - IOleInPlaceFrame frame; - HWND window; -} _IOleInPlaceFrameEx; - -HRESULT STDMETHODCALLTYPE Site_QueryInterface(IOleClientSite FAR* This, REFIID riid, void ** ppvObject); -HRESULT STDMETHODCALLTYPE Site_AddRef(IOleClientSite FAR* This); -HRESULT STDMETHODCALLTYPE Site_Release(IOleClientSite FAR* This); -HRESULT STDMETHODCALLTYPE Site_SaveObject(IOleClientSite FAR* This); -HRESULT STDMETHODCALLTYPE Site_GetMoniker(IOleClientSite FAR* This, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk); -HRESULT STDMETHODCALLTYPE Site_GetContainer(IOleClientSite FAR* This, LPOLECONTAINER FAR* ppContainer); -HRESULT STDMETHODCALLTYPE Site_ShowObject(IOleClientSite FAR* This); -HRESULT STDMETHODCALLTYPE Site_OnShowWindow(IOleClientSite FAR* This, BOOL fShow); -HRESULT STDMETHODCALLTYPE Site_RequestNewObjectLayout(IOleClientSite FAR* This); - -IOleClientSiteVtbl MyIOleClientSiteTable = {Site_QueryInterface, -Site_AddRef, -Site_Release, -Site_SaveObject, -Site_GetMoniker, -Site_GetContainer, -Site_ShowObject, -Site_OnShowWindow, -Site_RequestNewObjectLayout}; - -HRESULT STDMETHODCALLTYPE UI_QueryInterface(IDocHostUIHandler FAR* This, REFIID riid, void ** ppvObject); -HRESULT STDMETHODCALLTYPE UI_AddRef(IDocHostUIHandler FAR* This); -HRESULT STDMETHODCALLTYPE UI_Release(IDocHostUIHandler FAR* This); -HRESULT STDMETHODCALLTYPE UI_ShowContextMenu(IDocHostUIHandler FAR* This, DWORD dwID, POINT __RPC_FAR *ppt, IUnknown __RPC_FAR *pcmdtReserved, IDispatch __RPC_FAR *pdispReserved); -HRESULT STDMETHODCALLTYPE UI_GetHostInfo(IDocHostUIHandler FAR* This, DOCHOSTUIINFO __RPC_FAR *pInfo); -HRESULT STDMETHODCALLTYPE UI_ShowUI(IDocHostUIHandler FAR* This, DWORD dwID, IOleInPlaceActiveObject __RPC_FAR *pActiveObject, IOleCommandTarget __RPC_FAR *pCommandTarget, IOleInPlaceFrame __RPC_FAR *pFrame, IOleInPlaceUIWindow __RPC_FAR *pDoc); -HRESULT STDMETHODCALLTYPE UI_HideUI(IDocHostUIHandler FAR* This); -HRESULT STDMETHODCALLTYPE UI_UpdateUI(IDocHostUIHandler FAR* This); -HRESULT STDMETHODCALLTYPE UI_EnableModeless(IDocHostUIHandler FAR* This, BOOL fEnable); -HRESULT STDMETHODCALLTYPE UI_OnDocWindowActivate(IDocHostUIHandler FAR* This, BOOL fActivate); -HRESULT STDMETHODCALLTYPE UI_OnFrameWindowActivate(IDocHostUIHandler FAR* This, BOOL fActivate); -HRESULT STDMETHODCALLTYPE UI_ResizeBorder(IDocHostUIHandler FAR* This, LPCRECT prcBorder, IOleInPlaceUIWindow __RPC_FAR *pUIWindow, BOOL fRameWindow); -HRESULT STDMETHODCALLTYPE UI_TranslateAccelerator(IDocHostUIHandler FAR* This, LPMSG lpMsg, const GUID __RPC_FAR *pguidCmdGroup, DWORD nCmdID); -HRESULT STDMETHODCALLTYPE UI_GetOptionKeyPath(IDocHostUIHandler FAR* This, LPOLESTR __RPC_FAR *pchKey, DWORD dw); -HRESULT STDMETHODCALLTYPE UI_GetDropTarget(IDocHostUIHandler FAR* This, IDropTarget __RPC_FAR *pDropTarget, IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget); -HRESULT STDMETHODCALLTYPE UI_GetExternal(IDocHostUIHandler FAR* This, IDispatch __RPC_FAR *__RPC_FAR *ppDispatch); -HRESULT STDMETHODCALLTYPE UI_TranslateUrl(IDocHostUIHandler FAR* This, DWORD dwTranslate, OLECHAR __RPC_FAR *pchURLIn, OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut); -HRESULT STDMETHODCALLTYPE UI_FilterDataObject(IDocHostUIHandler FAR* This, IDataObject __RPC_FAR *pDO, IDataObject __RPC_FAR *__RPC_FAR *ppDORet); - -IDocHostUIHandlerVtbl MyIDocHostUIHandlerTable = {UI_QueryInterface, -UI_AddRef, -UI_Release, -UI_ShowContextMenu, -UI_GetHostInfo, -UI_ShowUI, -UI_HideUI, -UI_UpdateUI, -UI_EnableModeless, -UI_OnDocWindowActivate, -UI_OnFrameWindowActivate, -UI_ResizeBorder, -UI_TranslateAccelerator, -UI_GetOptionKeyPath, -UI_GetDropTarget, -UI_GetExternal, -UI_TranslateUrl, -UI_FilterDataObject}; - -HRESULT STDMETHODCALLTYPE InPlace_QueryInterface(IOleInPlaceSite FAR* This, REFIID riid, void ** ppvObject); -HRESULT STDMETHODCALLTYPE InPlace_AddRef(IOleInPlaceSite FAR* This); -HRESULT STDMETHODCALLTYPE InPlace_Release(IOleInPlaceSite FAR* This); -HRESULT STDMETHODCALLTYPE InPlace_GetWindow(IOleInPlaceSite FAR* This, HWND FAR* lphwnd); -HRESULT STDMETHODCALLTYPE InPlace_ContextSensitiveHelp(IOleInPlaceSite FAR* This, BOOL fEnterMode); -HRESULT STDMETHODCALLTYPE InPlace_CanInPlaceActivate(IOleInPlaceSite FAR* This); -HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceActivate(IOleInPlaceSite FAR* This); -HRESULT STDMETHODCALLTYPE InPlace_OnUIActivate(IOleInPlaceSite FAR* This); -HRESULT STDMETHODCALLTYPE InPlace_GetWindowContext(IOleInPlaceSite FAR* This, LPOLEINPLACEFRAME FAR* lplpFrame,LPOLEINPLACEUIWINDOW FAR* lplpDoc,LPRECT lprcPosRect,LPRECT lprcClipRect,LPOLEINPLACEFRAMEINFO lpFrameInfo); -HRESULT STDMETHODCALLTYPE InPlace_Scroll(IOleInPlaceSite FAR* This, SIZE scrollExtent); -HRESULT STDMETHODCALLTYPE InPlace_OnUIDeactivate(IOleInPlaceSite FAR* This, BOOL fUndoable); -HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceDeactivate(IOleInPlaceSite FAR* This); -HRESULT STDMETHODCALLTYPE InPlace_DiscardUndoState(IOleInPlaceSite FAR* This); -HRESULT STDMETHODCALLTYPE InPlace_DeactivateAndUndo(IOleInPlaceSite FAR* This); -HRESULT STDMETHODCALLTYPE InPlace_OnPosRectChange(IOleInPlaceSite FAR* This, LPCRECT lprcPosRect); - -IOleInPlaceSiteVtbl MyIOleInPlaceSiteTable = {InPlace_QueryInterface, -InPlace_AddRef, -InPlace_Release, -InPlace_GetWindow, -InPlace_ContextSensitiveHelp, -InPlace_CanInPlaceActivate, -InPlace_OnInPlaceActivate, -InPlace_OnUIActivate, -InPlace_GetWindowContext, -InPlace_Scroll, -InPlace_OnUIDeactivate, -InPlace_OnInPlaceDeactivate, -InPlace_DiscardUndoState, -InPlace_DeactivateAndUndo, -InPlace_OnPosRectChange}; - -typedef struct { - IOleInPlaceSite inplace; - _IOleInPlaceFrameEx frame; -} _IOleInPlaceSiteEx; - -typedef struct { - IDocHostUIHandler ui; -} _IDocHostUIHandlerEx; - -typedef struct { - IOleClientSite client; - _IOleInPlaceSiteEx inplace; - _IDocHostUIHandlerEx ui; -} _IOleClientSiteEx; - -#define NOTIMPLEMENTED return(E_NOTIMPL) - -typedef struct -{ - char *pszHTML; - char *pszTitle; - int width; - int height; - HWND hWnd; // out -} ShowIEWndParam; - - -//////////////////////////////////// My IDocHostUIHandler functions ////////////////////////////////////// -// -HRESULT STDMETHODCALLTYPE UI_QueryInterface(IDocHostUIHandler FAR* This, REFIID riid, LPVOID FAR* ppvObj) -{ - return(Site_QueryInterface((IOleClientSite *)((char *)This - sizeof(IOleClientSite) - sizeof(_IOleInPlaceSiteEx)), riid, ppvObj)); -} - -HRESULT STDMETHODCALLTYPE UI_AddRef(IDocHostUIHandler FAR* This) -{ - return(1); -} - -HRESULT STDMETHODCALLTYPE UI_Release(IDocHostUIHandler FAR* This) -{ - return(1); -} - -HRESULT STDMETHODCALLTYPE UI_ShowContextMenu(IDocHostUIHandler FAR* This, DWORD dwID, POINT __RPC_FAR *ppt, IUnknown __RPC_FAR *pcmdtReserved, IDispatch __RPC_FAR *pdispReserved) -{ - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE UI_GetHostInfo(IDocHostUIHandler FAR* This, DOCHOSTUIINFO __RPC_FAR *pInfo) -{ - pInfo->cbSize = sizeof(DOCHOSTUIINFO); - pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER; - pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT; - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE UI_ShowUI(IDocHostUIHandler FAR* This, DWORD dwID, IOleInPlaceActiveObject __RPC_FAR *pActiveObject, IOleCommandTarget __RPC_FAR *pCommandTarget, IOleInPlaceFrame __RPC_FAR *pFrame, IOleInPlaceUIWindow __RPC_FAR *pDoc) -{ - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE UI_HideUI(IDocHostUIHandler FAR* This) -{ - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE UI_UpdateUI(IDocHostUIHandler FAR* This) -{ - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE UI_EnableModeless(IDocHostUIHandler FAR* This, BOOL fEnable) -{ - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE UI_OnDocWindowActivate(IDocHostUIHandler FAR* This, BOOL fActivate) -{ - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE UI_OnFrameWindowActivate(IDocHostUIHandler FAR* This, BOOL fActivate) -{ - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE UI_ResizeBorder(IDocHostUIHandler FAR* This, LPCRECT prcBorder, IOleInPlaceUIWindow __RPC_FAR *pUIWindow, BOOL fRameWindow) -{ - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE UI_TranslateAccelerator(IDocHostUIHandler FAR* This, LPMSG lpMsg, const GUID __RPC_FAR *pguidCmdGroup, DWORD nCmdID) -{ - return(S_FALSE); -} - -HRESULT STDMETHODCALLTYPE UI_GetOptionKeyPath(IDocHostUIHandler FAR* This, LPOLESTR __RPC_FAR *pchKey, DWORD dw) -{ - return(S_FALSE); -} - -HRESULT STDMETHODCALLTYPE UI_GetDropTarget(IDocHostUIHandler FAR* This, IDropTarget __RPC_FAR *pDropTarget, IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget) -{ - return(S_FALSE); -} - -HRESULT STDMETHODCALLTYPE UI_GetExternal(IDocHostUIHandler FAR* This, IDispatch __RPC_FAR *__RPC_FAR *ppDispatch) -{ - *ppDispatch = 0; - return(S_FALSE); -} - -HRESULT STDMETHODCALLTYPE UI_TranslateUrl(IDocHostUIHandler FAR* This, DWORD dwTranslate, OLECHAR __RPC_FAR *pchURLIn, OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut) -{ - *ppchURLOut = 0; - return(S_FALSE); -} - -HRESULT STDMETHODCALLTYPE UI_FilterDataObject(IDocHostUIHandler FAR* This, IDataObject __RPC_FAR *pDO, IDataObject __RPC_FAR *__RPC_FAR *ppDORet) -{ - *ppDORet = 0; - return(S_FALSE); -} - -////////////////////////////////////// My IOleClientSite functions ///////////////////////////////////// -// - -HRESULT STDMETHODCALLTYPE Site_QueryInterface(IOleClientSite FAR* This, REFIID riid, void ** ppvObject) -{ - if (!memcmp(riid, &IID_IUnknown, sizeof(GUID)) || !memcmp(riid, &IID_IOleClientSite, sizeof(GUID))) - *ppvObject = &((_IOleClientSiteEx *)This)->client; - else if (!memcmp(riid, &IID_IOleInPlaceSite, sizeof(GUID))) - *ppvObject = &((_IOleClientSiteEx *)This)->inplace; - else if (!memcmp(riid, &IID_IDocHostUIHandler, sizeof(GUID))) - *ppvObject = &((_IOleClientSiteEx *)This)->ui; - else - { - *ppvObject = 0; - return(E_NOINTERFACE); - } - - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE Site_AddRef(IOleClientSite FAR* This) -{ - return(1); -} - -HRESULT STDMETHODCALLTYPE Site_Release(IOleClientSite FAR* This) -{ - return(1); -} - -HRESULT STDMETHODCALLTYPE Site_SaveObject(IOleClientSite FAR* This) -{ - NOTIMPLEMENTED; -} - -HRESULT STDMETHODCALLTYPE Site_GetMoniker(IOleClientSite FAR* This, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk) -{ - NOTIMPLEMENTED; -} - -HRESULT STDMETHODCALLTYPE Site_GetContainer(IOleClientSite FAR* This, LPOLECONTAINER FAR* ppContainer) -{ - *ppContainer = 0; - - return(E_NOINTERFACE); -} - -HRESULT STDMETHODCALLTYPE Site_ShowObject(IOleClientSite FAR* This) -{ - return(NOERROR); -} - -HRESULT STDMETHODCALLTYPE Site_OnShowWindow(IOleClientSite FAR* This, BOOL fShow) -{ - NOTIMPLEMENTED; -} - -HRESULT STDMETHODCALLTYPE Site_RequestNewObjectLayout(IOleClientSite FAR* This) -{ - NOTIMPLEMENTED; -} - - -////////////////////////////////////// My IOleInPlaceSite functions ///////////////////////////////////// -// -HRESULT STDMETHODCALLTYPE InPlace_QueryInterface(IOleInPlaceSite FAR* This, REFIID riid, LPVOID FAR* ppvObj) -{ - return(Site_QueryInterface((IOleClientSite *)((char *)This - sizeof(IOleClientSite)), riid, ppvObj)); -} - -HRESULT STDMETHODCALLTYPE InPlace_AddRef(IOleInPlaceSite FAR* This) -{ - return(1); -} - -HRESULT STDMETHODCALLTYPE InPlace_Release(IOleInPlaceSite FAR* This) -{ - return(1); -} - -HRESULT STDMETHODCALLTYPE InPlace_GetWindow(IOleInPlaceSite FAR* This, HWND FAR* lphwnd) -{ - *lphwnd = ((_IOleInPlaceSiteEx FAR*)This)->frame.window; - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE InPlace_ContextSensitiveHelp(IOleInPlaceSite FAR* This, BOOL fEnterMode) -{ - NOTIMPLEMENTED; -} - -HRESULT STDMETHODCALLTYPE InPlace_CanInPlaceActivate(IOleInPlaceSite FAR* This) -{ - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceActivate(IOleInPlaceSite FAR* This) -{ - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE InPlace_OnUIActivate(IOleInPlaceSite FAR* This) -{ - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE InPlace_GetWindowContext(IOleInPlaceSite FAR* This, LPOLEINPLACEFRAME FAR* lplpFrame, LPOLEINPLACEUIWINDOW FAR* lplpDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo) -{ - *lplpFrame = (LPOLEINPLACEFRAME)&((_IOleInPlaceSiteEx *)This)->frame; - *lplpDoc = 0; - - lpFrameInfo->fMDIApp = FALSE; - lpFrameInfo->hwndFrame = ((_IOleInPlaceFrameEx *)*lplpFrame)->window; - lpFrameInfo->haccel = 0; - lpFrameInfo->cAccelEntries = 0; - - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE InPlace_Scroll(IOleInPlaceSite FAR* This, SIZE scrollExtent) -{ - NOTIMPLEMENTED; -} - -HRESULT STDMETHODCALLTYPE InPlace_OnUIDeactivate(IOleInPlaceSite FAR* This, BOOL fUndoable) -{ - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceDeactivate(IOleInPlaceSite FAR* This) -{ - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE InPlace_DiscardUndoState(IOleInPlaceSite FAR* This) -{ - NOTIMPLEMENTED; -} - -HRESULT STDMETHODCALLTYPE InPlace_DeactivateAndUndo(IOleInPlaceSite FAR* This) -{ - NOTIMPLEMENTED; -} - -HRESULT STDMETHODCALLTYPE InPlace_OnPosRectChange(IOleInPlaceSite FAR* This, LPCRECT lprcPosRect) -{ - IOleObject *browserObject; - IOleInPlaceObject *inplace; - - browserObject = *((IOleObject **)((char *)This - sizeof(IOleObject *) - sizeof(IOleClientSite))); - if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IOleInPlaceObject, (void**)&inplace)) - { - inplace->lpVtbl->SetObjectRects(inplace, lprcPosRect, lprcPosRect); - inplace->lpVtbl->Release(inplace); - } - - return(S_OK); -} - - - -////////////////////////////////////// My IOleInPlaceFrame functions ///////////////////////////////////////// -// -HRESULT STDMETHODCALLTYPE Frame_QueryInterface(IOleInPlaceFrame FAR* This, REFIID riid, LPVOID FAR* ppvObj) -{ - NOTIMPLEMENTED; -} - -HRESULT STDMETHODCALLTYPE Frame_AddRef(IOleInPlaceFrame FAR* This) -{ - return(1); -} - -HRESULT STDMETHODCALLTYPE Frame_Release(IOleInPlaceFrame FAR* This) -{ - return(1); -} - -HRESULT STDMETHODCALLTYPE Frame_GetWindow(IOleInPlaceFrame FAR* This, HWND FAR* lphwnd) -{ - *lphwnd = ((_IOleInPlaceFrameEx *)This)->window; - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE Frame_ContextSensitiveHelp(IOleInPlaceFrame FAR* This, BOOL fEnterMode) -{ - NOTIMPLEMENTED; -} - -HRESULT STDMETHODCALLTYPE Frame_GetBorder(IOleInPlaceFrame FAR* This, LPRECT lprectBorder) -{ - NOTIMPLEMENTED; -} - -HRESULT STDMETHODCALLTYPE Frame_RequestBorderSpace(IOleInPlaceFrame FAR* This, LPCBORDERWIDTHS pborderwidths) -{ - NOTIMPLEMENTED; -} - -HRESULT STDMETHODCALLTYPE Frame_SetBorderSpace(IOleInPlaceFrame FAR* This, LPCBORDERWIDTHS pborderwidths) -{ - NOTIMPLEMENTED; -} - -HRESULT STDMETHODCALLTYPE Frame_SetActiveObject(IOleInPlaceFrame FAR* This, IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName) -{ - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE Frame_InsertMenus(IOleInPlaceFrame FAR* This, HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths) -{ - NOTIMPLEMENTED; -} - -HRESULT STDMETHODCALLTYPE Frame_SetMenu(IOleInPlaceFrame FAR* This, HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject) -{ - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE Frame_RemoveMenus(IOleInPlaceFrame FAR* This, HMENU hmenuShared) -{ - NOTIMPLEMENTED; -} - -HRESULT STDMETHODCALLTYPE Frame_SetStatusText(IOleInPlaceFrame FAR* This, LPCOLESTR pszStatusText) -{ - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE Frame_EnableModeless(IOleInPlaceFrame FAR* This, BOOL fEnable) -{ - return(S_OK); -} - -HRESULT STDMETHODCALLTYPE Frame_TranslateAccelerator(IOleInPlaceFrame FAR* This, LPMSG lpmsg, WORD wID) -{ - NOTIMPLEMENTED; -} - - - - -/*************************** UnEmbedBrowserObject() ************************ - * Called to detach the browser object from our host window, and free its - * resources, right before we destroy our window. - * - * hwnd = Handle to the window hosting the browser object. - * - * NOTE: The pointer to the browser object must have been stored in the - * window's USERDATA field. In other words, don't call UnEmbedBrowserObject(). - * with a HWND that wasn't successfully passed to EmbedBrowserObject(). - */ - -void UnEmbedBrowserObject(HWND hwnd) -{ - IOleObject **browserHandle; - IOleObject *browserObject; - - // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when - // we initially attached the browser object to this window. - if ((browserHandle = (IOleObject **)GetWindowLongPtr(hwnd, GWLP_USERDATA))) - { - // Unembed the browser object, and release its resources. - browserObject = *browserHandle; - browserObject->lpVtbl->Close(browserObject, OLECLOSE_NOSAVE); - browserObject->lpVtbl->Release(browserObject); - - GlobalFree(browserHandle); - - return; - } -} - - -/******************************* DisplayHTMLStr() **************************** - * Takes a string containing some HTML BODY, and displays it in the specified - * window. For example, perhaps you want to display the HTML text of... - * - *

This is a picture.

- * - * hwnd = Handle to the window hosting the browser object. - * string = Pointer to nul-terminated string containing the HTML BODY. - * (NOTE: No tags are required in the string). - * - * RETURNS: 0 if success, or non-zero if an error. - * - * NOTE: EmbedBrowserObject() must have been successfully called once with the - * specified window, prior to calling this function. You need call - * EmbedBrowserObject() once only, and then you can make multiple calls to - * this function to display numerous pages in the specified window. - */ - -long DisplayHTMLStr(HWND hwnd, LPCTSTR string) -{ - IWebBrowser2 *webBrowser2; - LPDISPATCH lpDispatch; - IHTMLDocument2 *htmlDoc2; - IOleObject *browserObject; - SAFEARRAY *sfArray; - VARIANT myURL; - VARIANT *pVar; - BSTR bstr; - - // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when - // we initially attached the browser object to this window. - browserObject = *((IOleObject **)GetWindowLongPtr(hwnd, GWLP_USERDATA)); - - // Assume an error. - bstr = 0; - - // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser - // object, so we can call some of the functions in the former's table. - if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2)) - { - // Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is - // webBrowser2->lpVtbl. - - // Before we can get_Document(), we actually need to have some HTML page loaded in the browser. So, - // let's load an empty HTML page. Then, once we have that empty page, we can get_Document() and - // write() to stuff our HTML string into it. - VariantInit(&myURL); - myURL.vt = VT_BSTR; - myURL.bstrVal = SysAllocString(L"about:blank"); - - // Call the Navigate2() function to actually display the page. - webBrowser2->lpVtbl->Navigate2(webBrowser2, &myURL, 0, 0, 0, 0); - - // Free any resources (including the BSTR). - VariantClear(&myURL); - - // Call the IWebBrowser2 object's get_Document so we can get its DISPATCH object. I don't know why you - // don't get the DISPATCH object via the browser object's QueryInterface(), but you don't. - if (!webBrowser2->lpVtbl->get_Document(webBrowser2, &lpDispatch)) - { - // We want to get a pointer to the IHTMLDocument2 object embedded within the DISPATCH - // object, so we can call some of the functions in the former's table. - if (!lpDispatch->lpVtbl->QueryInterface(lpDispatch, &IID_IHTMLDocument2, (void**)&htmlDoc2)) - { - // Ok, now the pointer to our IHTMLDocument2 object is in 'htmlDoc2', and so its VTable is - // htmlDoc2->lpVtbl. - - // Our HTML must be in the form of a BSTR. And it must be passed to write() in an - // array of "VARIENT" structs. So let's create all that. - if ((sfArray = SafeArrayCreate(VT_VARIANT, 1, (SAFEARRAYBOUND *)&ArrayBound))) - { - if (!SafeArrayAccessData(sfArray, (void**)&pVar)) - { - pVar->vt = VT_BSTR; -#ifndef UNICODE - { - wchar_t *buffer; - DWORD size; - - size = MultiByteToWideChar(CP_ACP, 0, string, -1, 0, 0); - if (!(buffer = (wchar_t *)GlobalAlloc(GMEM_FIXED, sizeof(wchar_t) * size))) goto bad; - MultiByteToWideChar(CP_ACP, 0, string, -1, buffer, size); - bstr = SysAllocString(buffer); - GlobalFree(buffer); - } -#else - bstr = SysAllocString(string); -#endif - // Store our BSTR pointer in the VARIENT. - if ((pVar->bstrVal = bstr)) - { - htmlDoc2->lpVtbl->clear(htmlDoc2); - // Pass the VARIENT with its BSTR to write() in order to shove our desired HTML string - // into the body of that empty page we created above. - htmlDoc2->lpVtbl->write(htmlDoc2, sfArray); - - // Close the document. If we don't do this, subsequent calls to DisplayHTMLStr - // would append to the current contents of the page - htmlDoc2->lpVtbl->close(htmlDoc2); - - // Normally, we'd need to free our BSTR, but SafeArrayDestroy() does it for us -// SysFreeString(bstr); - } - } - - // Free the array. This also frees the VARIENT that SafeArrayAccessData created for us, - // and even frees the BSTR we allocated with SysAllocString - SafeArrayDestroy(sfArray); - } - - // Release the IHTMLDocument2 object. -bad: htmlDoc2->lpVtbl->Release(htmlDoc2); - } - - // Release the DISPATCH object. - lpDispatch->lpVtbl->Release(lpDispatch); - } - - // Release the IWebBrowser2 object. - webBrowser2->lpVtbl->Release(webBrowser2); - } - - // No error? - if (bstr) return(0); - - // An error - return(-1); -} - - - -/******************************* ResizeBrowser() **************************** - * Resizes the browser object for the specified window to the specified - * width and height. - * - * hwnd = Handle to the window hosting the browser object. - * width = Width. - * height = Height. - * - * NOTE: EmbedBrowserObject() must have been successfully called once with the - * specified window, prior to calling this function. You need call - * EmbedBrowserObject() once only, and then you can make multiple calls to - * this function to resize the browser object. - */ - -void ResizeBrowser(HWND hwnd, DWORD width, DWORD height) -{ - IWebBrowser2 *webBrowser2; - IOleObject *browserObject; - - // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when - // we initially attached the browser object to this window. - browserObject = *((IOleObject **)GetWindowLongPtr(hwnd, GWLP_USERDATA)); - - // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser - // object, so we can call some of the functions in the former's table. - if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2)) - { - // Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is - // webBrowser2->lpVtbl. - - // Call are put_Width() and put_Height() to set the new width/height. - webBrowser2->lpVtbl->put_Width(webBrowser2, width); - webBrowser2->lpVtbl->put_Height(webBrowser2, height); - - // We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it, - // so we can release our hold on it). Note that we'll still maintain our hold on the browser - // object. - webBrowser2->lpVtbl->Release(webBrowser2); - } -} - - - - - -/***************************** EmbedBrowserObject() ************************** - * Puts the browser object inside our host window, and save a pointer to this - * window's browser object in the window's GWL_USERDATA field. - * - * hwnd = Handle of our window into which we embed the browser object. - * - * RETURNS: 0 if success, or non-zero if an error. - * - * NOTE: We tell the browser object to occupy the entire client area of the - * window. - * - * NOTE: No HTML page will be displayed here. We can do that with a subsequent - * call to either DisplayHTMLPage() or DisplayHTMLStr(). This is merely once-only - * initialization for using the browser object. In a nutshell, what we do - * here is get a pointer to the browser object in our window's GWL_USERDATA - * so we can access that object's functions whenever we want, and we also pass - * the browser a pointer to our IOleClientSite struct so that the browser can - * call our functions in our struct's VTable. - */ - -long EmbedBrowserObject(HWND hwnd) -{ - LPCLASSFACTORY pClassFactory; - IOleObject *browserObject; - IWebBrowser2 *webBrowser2; - RECT rect; - char *ptr; - _IOleClientSiteEx *_iOleClientSiteEx; - - // Our IOleClientSite, IOleInPlaceSite, and IOleInPlaceFrame functions need to get our window handle. We - // could store that in some global. But then, that would mean that our functions would work with only that - // one window. If we want to create multiple windows, each hosting its own browser object (to display its - // own web page), then we need to create unique IOleClientSite, IOleInPlaceSite, and IOleInPlaceFrame - // structs for each window. And we'll put an extra field at the end of those structs to store our extra - // data such as a window handle. So, our functions won't have to touch global data, and can therefore be - // re-entrant and work with multiple objects/windows. - // - // Remember that a pointer to our IOleClientSite we create here will be passed as the first arg to every - // one of our IOleClientSite functions. Ditto with the IOleInPlaceFrame object we create here, and the - // IOleInPlaceFrame functions. So, our functions are able to retrieve the window handle we'll store here, - // and then, they'll work with all such windows containing a browser control. - // - // Furthermore, since the browser will be calling our IOleClientSite's QueryInterface to get a pointer to - // our IOleInPlaceSite and IDocHostUIHandler objects, that means that our IOleClientSite QueryInterface - // must have an easy way to grab those pointers. Probably the easiest thing to do is just embed our - // IOleInPlaceSite and IDocHostUIHandler objects inside of an extended IOleClientSite which we'll call - // a _IOleClientSiteEx. As long as they come after the pointer to the IOleClientSite VTable, then we're - // ok. - // - // Of course, we need to GlobalAlloc the above structs now. We'll just get all 4 with a single call to - // GlobalAlloc, especially since 3 of them are all contained inside of our _IOleClientSiteEx anyway. - // - // So, we're not actually allocating separate IOleClientSite, IOleInPlaceSite, IOleInPlaceFrame and - // IDocHostUIHandler structs. - // - // One final thing. We're going to allocate extra room to store the pointer to the browser object. - if (!(ptr = (char *)GlobalAlloc(GMEM_FIXED, sizeof(_IOleClientSiteEx) + sizeof(IOleObject *)))) - return(-1); - - // Initialize our IOleClientSite object with a pointer to our IOleClientSite VTable. - _iOleClientSiteEx = (_IOleClientSiteEx *)(ptr + sizeof(IOleObject *)); - _iOleClientSiteEx->client.lpVtbl = &MyIOleClientSiteTable; - - // Initialize our IOleInPlaceSite object with a pointer to our IOleInPlaceSite VTable. - _iOleClientSiteEx->inplace.inplace.lpVtbl = &MyIOleInPlaceSiteTable; - - // Initialize our IOleInPlaceFrame object with a pointer to our IOleInPlaceFrame VTable. - _iOleClientSiteEx->inplace.frame.frame.lpVtbl = &MyIOleInPlaceFrameTable; - - // Save our HWND (in the IOleInPlaceFrame object) so our IOleInPlaceFrame functions can retrieve it. - _iOleClientSiteEx->inplace.frame.window = hwnd; - - // Initialize our IDocHostUIHandler object with a pointer to our IDocHostUIHandler VTable. - _iOleClientSiteEx->ui.ui.lpVtbl = &MyIDocHostUIHandlerTable; - - // Get a pointer to the browser object and lock it down (so it doesn't "disappear" while we're using - // it in this program). We do this by calling the OS function CoGetClassObject(). - // - // NOTE: We need this pointer to interact with and control the browser. With normal WIN32 controls such as a - // Static, Edit, Combobox, etc, you obtain an HWND and send messages to it with SendMessage(). Not so with - // the browser object. You need to get a pointer to its "base structure" (as returned by CoGetClassObject()). This - // structure contains an array of pointers to functions you can call within the browser object. Actually, the - // base structure contains a 'lpVtbl' field that is a pointer to that array. We'll call the array a 'VTable'. - // - // For example, the browser object happens to have a SetHostNames() function we want to call. So, after we - // retrieve the pointer to the browser object (in a local we'll name 'browserObject'), then we can call that - // function, and pass it args, as so: - // - // browserObject->lpVtbl->SetHostNames(browserObject, SomeString, SomeString); - // - // There's our pointer to the browser object in 'browserObject'. And there's the pointer to the browser object's - // VTable in 'browserObject->lpVtbl'. And the pointer to the SetHostNames function happens to be stored in an - // field named 'SetHostNames' within the VTable. So we are actually indirectly calling SetHostNames by using - // a pointer to it. That's how you use a VTable. - // - // NOTE: We pass our _IOleClientSiteEx struct and lie -- saying that it's a IOleClientSite. It's ok. A - // _IOleClientSiteEx struct starts with an embedded IOleClientSite. So the browser won't care, and we want - // this extended struct passed to our IOleClientSite functions. - - // Get a pointer to the browser object's IClassFactory object via CoGetClassObject() - pClassFactory = 0; - if (!CoGetClassObject(&CLSID_WebBrowser, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, NULL, &IID_IClassFactory, (void **)&pClassFactory) && pClassFactory) - { - // Call the IClassFactory's CreateInstance() to create a browser object - if (!pClassFactory->lpVtbl->CreateInstance(pClassFactory, 0, &IID_IOleObject, &browserObject)) - { - // Free the IClassFactory. We need it only to create a browser object instance - pClassFactory->lpVtbl->Release(pClassFactory); - - // Ok, we now have the pointer to the browser object in 'browserObject'. Let's save this in the - // memory block we allocated above, and then save the pointer to that whole thing in our window's - // USERDATA field. That way, if we need multiple windows each hosting its own browser object, we can - // call EmbedBrowserObject() for each one, and easily associate the appropriate browser object with - // its matching window and its own objects containing per-window data. - *((IOleObject **)ptr) = browserObject; - SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)ptr); - - // Give the browser a pointer to my IOleClientSite object - if (!browserObject->lpVtbl->SetClientSite(browserObject, (IOleClientSite *)_iOleClientSiteEx)) - { - // We can now call the browser object's SetHostNames function. SetHostNames lets the browser object know our - // application's name and the name of the document in which we're embedding the browser. (Since we have no - // document name, we'll pass a 0 for the latter). When the browser object is opened for editing, it displays - // these names in its titlebar. - // - // We are passing 3 args to SetHostNames. You'll note that the first arg to SetHostNames is the base - // address of our browser control. This is something that you always have to remember when working in C - // (as opposed to C++). When calling a VTable function, the first arg to that function must always be the - // structure which contains the VTable. (In this case, that's the browser control itself). Why? That's - // because that function is always assumed to be written in C++. And the first argument to any C++ function - // must be its 'this' pointer (ie, the base address of its class, which in this case is our browser object - // pointer). In C++, you don't have to pass this first arg, because the C++ compiler is smart enough to - // produce an executable that always adds this first arg. In fact, the C++ compiler is smart enough to - // know to fetch the function pointer from the VTable, so you don't even need to reference that. In other - // words, the C++ equivalent code would be: - // - // browserObject->SetHostNames(L"My Host Name", 0); - // - // So, when you're trying to convert C++ code to C, always remember to add this first arg whenever you're - // dealing with a VTable (ie, the field is usually named 'lpVtbl') in the standard objects, and also add - // the reference to the VTable itself. - // - // Oh yeah, the L is because we need UNICODE strings. And BTW, the host and document names can be anything - // you want. - browserObject->lpVtbl->SetHostNames(browserObject, L"My Host Name", 0); - - GetClientRect(hwnd, &rect); - - // Let browser object know that it is embedded in an OLE container. - if (!OleSetContainedObject((struct IUnknown *)browserObject, TRUE) && - - // Set the display area of our browser control the same as our window's size - // and actually put the browser object into our window. - !browserObject->lpVtbl->DoVerb(browserObject, OLEIVERB_SHOW, NULL, (IOleClientSite *)_iOleClientSiteEx, -1, hwnd, &rect) && - - // Ok, now things may seem to get even trickier, One of those function pointers in the browser's VTable is - // to the QueryInterface() function. What does this function do? It lets us grab the base address of any - // other object that may be embedded within the browser object. And this other object has its own VTable - // containing pointers to more functions we can call for that object. - // - // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser - // object, so we can call some of the functions in the former's table. For example, one IWebBrowser2 function - // we intend to call below will be Navigate2(). So we call the browser object's QueryInterface to get our - // pointer to the IWebBrowser2 object. - !browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2)) - { - // Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is - // webBrowser2->lpVtbl. - - // Let's call several functions in the IWebBrowser2 object to position the browser display area - // in our window. The functions we call are put_Left(), put_Top(), put_Width(), and put_Height(). - // Note that we reference the IWebBrowser2 object's VTable to get pointers to those functions. And - // also note that the first arg we pass to each is the pointer to the IWebBrowser2 object. - webBrowser2->lpVtbl->put_Left(webBrowser2, 0); - webBrowser2->lpVtbl->put_Top(webBrowser2, 0); - webBrowser2->lpVtbl->put_Width(webBrowser2, rect.right); - webBrowser2->lpVtbl->put_Height(webBrowser2, rect.bottom); - - // We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it - // right now, so we can release our hold on it). Note that we'll still maintain our hold on the - // browser object until we're done with that object. - webBrowser2->lpVtbl->Release(webBrowser2); - - // Success - return(0); - } - } - - // Something went wrong setting up the browser! - UnEmbedBrowserObject(hwnd); - return(-4); - } - - pClassFactory->lpVtbl->Release(pClassFactory); - GlobalFree(ptr); - - // Can't create an instance of the browser! - return(-3); - } - - GlobalFree(ptr); - - // Can't get the web browser's IClassFactory! - return(-2); -} - - - - - -/****************************** WindowProc() *************************** - * Our message handler for our window to host the browser. - */ - -LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) - { - case WM_SIZE: - { - // Resize the browser object to fit the window - ResizeBrowser(hwnd, LOWORD(lParam), HIWORD(lParam)); - return(0); - } - - case WM_CREATE: - { - // Embed the browser object into our host window. We need do this only - // once. Note that the browser object will start calling some of our - // IOleInPlaceFrame and IOleClientSite functions as soon as we start - // calling browser object functions in EmbedBrowserObject(). - if (EmbedBrowserObject(hwnd)) return(-1); - - // Success - return(0); - } - - case WM_DESTROY: - { - int i, nCount; - - // Detach the browser object from this window, and free resources. - UnEmbedBrowserObject(hwnd); - - // If all the windows are now closed, quit this app - if (m_hWindows) - { - for (i=0, nCount=List_Count(m_hWindows); ihWnd = CreateWindowEx(0, wc.lpszClassName, Param->pszTitle, WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, Param->width, Param->height, - HWND_DESKTOP, NULL, wc.hInstance, 0))) - { - List_Push (m_hWindows, Param->hWnd); - DisplayHTMLStr(Param->hWnd, Param->pszHTML); - ShowWindow(Param->hWnd, SW_SHOWNORMAL); - SetForegroundWindow (Param->hWnd); - UpdateWindow(Param->hWnd); - } - SetEvent (m_hEvent); - break; - } - case WM_USER+1: - { - DestroyWindow ((HWND)msg.lParam); - break; - } - } - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - UnregisterClass (wc.lpszClassName, wc.hInstance); - CoUninitialize(); - if (m_hWindows) List_Exit (m_hWindows); - ExitThread (0); - return 0; -} - -// ----------------------------------------------------------------------------- -// Interface -// ----------------------------------------------------------------------------- - -// bInitBrowser - Tries to initialize a dummy window on start so that subsequent -// calls are faster as all libraries are already present in -// memory. Drawback: Higher memory consumption -int W32Browser_Init(BOOL bInitBrowser) -{ - if (m_hThread) W32Browser_Exit(); - m_hThread = (HANDLE)_beginthreadex(NULL, 0, ShowIEWndFunc, (LPVOID)bInitBrowser, 0, &m_dwThread); - if (!m_hThread) return -1; - if (!(m_hEvent = CreateEvent (NULL, FALSE, FALSE, NULL))) - { - TerminateThread (m_hThread, -1); - CloseHandle (m_hThread); - return -1; - } - return 0; -} - -// ----------------------------------------------------------------------------- - -void W32Browser_Exit(void) -{ - if (m_hWindows) - { - HWND hWnd; - - while (hWnd = List_Pop(m_hWindows)) - W32Browser_CloseWindow (hWnd); - m_hWindows = NULL; - } - if (m_hThread) - { - PostThreadMessage (m_dwThread, WM_QUIT, 0, 0); - if (WaitForSingleObject (m_hThread, 2000) == WAIT_TIMEOUT) - TerminateThread (m_hThread, -1); - CloseHandle (m_hThread); - m_hThread = NULL; - } - if (m_hEvent) - { - CloseHandle (m_hEvent); - m_hEvent = NULL; - } -} - -// ----------------------------------------------------------------------------- - -void *W32Browser_ShowHTMLStr(char *pszHTMLStr, int width, int height, char *pszTitle) -{ - // Window gets its own thread to not block the Mainthread - static ShowIEWndParam Param; - - Param.width = width; - Param.height = height; - Param.pszHTML = pszHTMLStr; - Param.pszTitle = pszTitle; - Param.hWnd = 0; - PostThreadMessage (m_dwThread, WM_USER, 0, (LPARAM)&Param); - WaitForSingleObject (m_hEvent, INFINITE); - return (void*)Param.hWnd; -} - -// ----------------------------------------------------------------------------- - -void W32Browser_CloseWindow (void *pWnd) -{ - PostThreadMessage (m_dwThread, WM_USER+1, 0, (LPARAM)pWnd); -} diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.h b/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.h deleted file mode 100644 index effc86998d..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.h +++ /dev/null @@ -1,5 +0,0 @@ -int W32Browser_Init(int bInitBrowser); -void W32Browser_Exit(void); - -void *W32Browser_ShowHTMLStr(char *pszHTMLStr, int width, int height, char *pszTitle); -void W32Browser_CloseWindow (void *pWnd); diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.c b/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.c deleted file mode 100644 index f9cc734cd1..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.c +++ /dev/null @@ -1,387 +0,0 @@ -#include -#include "imo2sproxy.h" -#define WIN32_LEAN_AND_MEAN -#include -#define LockMutex(x) EnterCriticalSection (&x) -#define UnlockMutex(x) LeaveCriticalSection(&x) -#define InitMutex(x) InitializeCriticalSection(&x) -#define ExitMutex(x) DeleteCriticalSection(&x) -#define strcasecmp stricmp -#define strncasecmp stricmpn -#define mutex_t CRITICAL_SECTION -#include -#include -#include -#include "memlist.h" -#include "w32skypeemu.h" - -#ifndef _WIN64 -#if WINVER<0x0500 -#define SetWindowLongPtr SetWindowLong -#define GetWindowLongPtr GetWindowLong -#endif -#ifndef LONG_PTR -#define LONG_PTR LONG -#endif -#ifndef GWLP_USERDATA -#define GWLP_USERDATA GWL_USERDATA -#endif -#endif - -// Skype API defines -#define SKYPECONTROLAPI_ATTACH_SUCCESS 0 -#define SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION 1 -#define SKYPECONTROLAPI_ATTACH_REFUSED 2 -#define SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE 3 -#define SKYPECONTROLAPI_ATTACH_API_AVAILABLE 0x8001 - -// ----------------------------------------------------------------------------- - -typedef struct -{ - IMO2SPROXY vtbl; // Must be first! - IMO2SPROXY_CFG *pCfg; - W32SKYPEEMU_CFG *pMyCfg; - HWND hWndDispatch; - TYP_LIST *hClients; - mutex_t loopmutex; - DWORD dwThreadID; -} IMO2SPROXY_INST; - -typedef struct -{ - HWND hWnd; - IMOSAPI *hInst; - IMO2SPROXY_INST *hProxy; - mutex_t sendmutex; - int iConnectionStat; -} CONNINST; - -static UINT m_ControlAPIAttach = 0; -static UINT m_ControlAPIDiscover = 0; - -// ----------------------------------------------------------------------------- - -static void EventHandler(char *pszMsg, void *pUser); -static CONNINST *FindClient(IMO2SPROXY_INST *hProxy, HWND hWnd); -static void CleanConnections (TYP_LIST *hList); -static void FreeConnection (CONNINST *pInst); -static LONG APIENTRY WndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam); - -static int Imo2sproxy_Open(IMO2SPROXY *hInst); -static void Imo2sproxy_Loop(IMO2SPROXY *hInst); -static void Imo2sproxy_Exit(IMO2SPROXY *hInst); - -// ----------------------------------------------------------------------------- -static void EventHandler(char *pszMsg, void *pUser) -{ - CONNINST *pInst = (CONNINST*)pUser; - COPYDATASTRUCT cds; - DWORD dwRes = 0; - - LockMutex(pInst->sendmutex); - if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) - { - fprintf (pInst->hProxy->pCfg->fpLog, "%08X> %s\n", pInst->hWnd, pszMsg); - fflush (pInst->hProxy->pCfg->fpLog); - } - cds.dwData = 0; - cds.cbData = strlen(pszMsg)+1; - cds.lpData = pszMsg; - SendMessageTimeout (pInst->hWnd, WM_COPYDATA, (WPARAM)pInst->hProxy->hWndDispatch, (LPARAM)&cds, SMTO_NORMAL, 1000, &dwRes); - UnlockMutex(pInst->sendmutex); -} - -// ----------------------------------------------------------------------------- - -static CONNINST *FindClient(IMO2SPROXY_INST *hProxy, HWND hWnd) -{ - int i, nCount; - CONNINST *pConn; - - for (i=0, nCount=List_Count(hProxy->hClients); ihClients, i))->hWnd == hWnd) - return pConn; - } - return NULL; -} - -// ----------------------------------------------------------------------------- - -static void CleanConnections (TYP_LIST *hList) -{ - unsigned int i; - CONNINST *pInst; - - for (i=0; ihWnd)) - { - if (pInst->hInst) FreeConnection(pInst); - free (List_RemoveElementAt(hList, i)); - i--; - } - } -} - -// ----------------------------------------------------------------------------- - -static void FreeConnection (CONNINST *pInst) -{ - if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) - { - fprintf (pInst->hProxy->pCfg->fpLog, "Closed connection %08X\n", pInst->hWnd); - fflush (pInst->hProxy->pCfg->fpLog); - } - ExitMutex (pInst->sendmutex); - if (pInst->hInst) - { - IMOSAPI *hInst = pInst->hInst; - pInst->hInst = NULL; - Imo2S_Exit(hInst); - } -} - -// ----------------------------------------------------------------------------- - -static LONG APIENTRY WndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam) -{ - switch (message) - { - case WM_CREATE: - { - LPCREATESTRUCT lpCr = (LPCREATESTRUCT)lParam; - - SetWindowLongPtr (hWnd, GWLP_USERDATA, (LONG_PTR)lpCr->lpCreateParams); - SetTimer (hWnd, 0, 60000, NULL); - break; - } - case WM_COPYDATA: - { - PCOPYDATASTRUCT pCopyData = (PCOPYDATASTRUCT)lParam; - CONNINST *pInst; - IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)GetWindowLongPtr(hWnd, GWLP_USERDATA); - - if (pInst = FindClient (hProxy, (HWND)wParam)) - { - if (pInst->hProxy->pMyCfg->bDelayLogin && pInst->iConnectionStat < 1) - { - char *pszError; - - if ((pInst->iConnectionStat = Imo2S_Login (pInst->hInst, hProxy->pCfg->pszUser, hProxy->pCfg->pszPass, &pszError)) != 1) - { - pInst->hProxy->pCfg->logerror (stderr, "Connection %08X: Cannot login with (%s/****): %s\n", - pInst->hWnd, hProxy->pCfg->pszUser, pszError); - FreeConnection(pInst); - free (List_Pop(hProxy->hClients)); - PostMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_REFUSED); - return 0; - } - } - LockMutex(pInst->sendmutex); - if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) - { - fprintf (pInst->hProxy->pCfg->fpLog, "%08X< [%s]\n", pInst->hWnd, pCopyData->lpData); - fflush (pInst->hProxy->pCfg->fpLog); - } - Imo2S_Send (pInst->hInst, pCopyData->lpData); - UnlockMutex(pInst->sendmutex); - } - return 1; - } - case WM_TIMER: - // Housekeeping timer - CleanConnections (((IMO2SPROXY_INST*)GetWindowLongPtr(hWnd, GWLP_USERDATA))->hClients); - break; - case WM_DESTROY: - KillTimer (hWnd, 0); - break; - default: - if (message == m_ControlAPIDiscover) - { - CONNINST *pInst; - IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)GetWindowLongPtr(hWnd, GWLP_USERDATA); - char *pszError; - - if (!(pInst = FindClient (hProxy, (HWND)wParam))) - { - pInst = (CONNINST*)calloc (1, sizeof(CONNINST)); - if (!pInst) break; - List_Push(hProxy->hClients, pInst); - pInst->hProxy = hProxy; - pInst->hWnd = (HWND)wParam; - if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) - fprintf (hProxy->pCfg->fpLog, "Imo2sproxy::SkypeControlAPIDiscover\n"); - - if (!(pInst->hInst = Imo2S_Init(EventHandler, pInst, hProxy->pCfg->iFlags))) - { - hProxy->pCfg->logerror (stderr, "Connection %08X: Cannot start Imo2Skype instance.\n", pInst->hWnd); - free (List_Pop(hProxy->hClients)); - PostMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_REFUSED); - return 0; - } - - // FIXME: We should enable logging dependent on a loglevel rather than just enabling it - if (hProxy->pCfg->bVerbose) - Imo2S_SetLog (pInst->hInst, hProxy->pCfg->fpLog); - - InitMutex(pInst->sendmutex); - - if (!pInst->hProxy->pMyCfg->bDelayLogin) - { - PostMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE); - if ((pInst->iConnectionStat = Imo2S_Login (pInst->hInst, hProxy->pCfg->pszUser, hProxy->pCfg->pszPass, &pszError)) != 1) - { - pInst->hProxy->pCfg->logerror (stderr, "Connection %08X: Cannot login with (%s/****): %s\n", - pInst->hWnd, hProxy->pCfg->pszUser, pszError); - FreeConnection(pInst); - free (List_Pop(hProxy->hClients)); - PostMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_REFUSED); - return 0; - } - PostMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_API_AVAILABLE); - } - else - { - SendMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_SUCCESS); - } - return 0; - } - else - SendMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_SUCCESS); - return 0; - } - break; - } - return (DefWindowProc(hWnd, message, wParam, lParam)); -} - - - -// ----------------------------------------------------------------------------- -// PUBLIC -// ----------------------------------------------------------------------------- - -void W32SkypeEmu_Defaults (W32SKYPEEMU_CFG *pMyCfg) -{ - memset (pMyCfg, 0, sizeof(W32SKYPEEMU_CFG)); - // Login on first command from Client, immediately send SKYPECONTROLAPI_ATTACH_SUCCESS - // This is necessary for some broken plugins, i.e. current SVN build of Miranda - // Skype plugin, which doesn't correctly poll again if SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE - // is sent. - pMyCfg->bDelayLogin = TRUE; -} - -// ----------------------------------------------------------------------------- - -IMO2SPROXY *W32SkypeEmu_Init (IMO2SPROXY_CFG *pCfg, W32SKYPEEMU_CFG *pMyCfg) -{ - IMO2SPROXY_INST *pstInst = calloc(sizeof(IMO2SPROXY_INST), 1); - - pstInst->vtbl.Open = Imo2sproxy_Open; - pstInst->vtbl.Loop = Imo2sproxy_Loop; - pstInst->vtbl.Exit = Imo2sproxy_Exit; - pstInst->pCfg = pCfg; - pstInst->pMyCfg = pMyCfg; - InitMutex(pstInst->loopmutex); - return (IMO2SPROXY*)pstInst; -} - -// ----------------------------------------------------------------------------- -// IMPLEMENTATION -// ----------------------------------------------------------------------------- -static int Imo2sproxy_Open(IMO2SPROXY *hInst) -{ - IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst; - WNDCLASS WndClass ={0}; - - // Start Skype connection - if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) - fprintf (hProxy->pCfg->fpLog, "W32SkypeEmu:Open(Start)\n"); - if ((!m_ControlAPIAttach && !(m_ControlAPIAttach=RegisterWindowMessage("SkypeControlAPIAttach"))) || - (!m_ControlAPIDiscover && !(m_ControlAPIDiscover=RegisterWindowMessage("SkypeControlAPIDiscover")))) - { - hProxy->pCfg->logerror (stderr, "Cannot register Window messages!"); - return -1; - } - - // Create window class - WndClass.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS; - WndClass.lpfnWndProc = (WNDPROC)WndProc; - WndClass.hInstance = GetModuleHandle(NULL); - WndClass.lpszClassName = "Imo2SProxyDispatchWindow"; - RegisterClass(&WndClass); - - if (!(hProxy->hWndDispatch=CreateWindowEx( WS_EX_APPWINDOW|WS_EX_WINDOWEDGE, - WndClass.lpszClassName, "", WS_BORDER|WS_SYSMENU|WS_MINIMIZEBOX, - CW_USEDEFAULT, CW_USEDEFAULT, 128, 128, NULL, 0, (HINSTANCE)WndClass.hInstance, (LPVOID)hProxy))) - { - hProxy->pCfg->logerror (stderr, "Unable to create dispatch window!"); - UnregisterClass (WndClass.lpszClassName, WndClass.hInstance); - return -1; - } - - hProxy->hClients = List_Init(32); - return 0; -} - -// ----------------------------------------------------------------------------- - -static void Imo2sproxy_Loop(IMO2SPROXY *hInst) -{ - IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst; - MSG Message; - - if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) - fprintf (hProxy->pCfg->fpLog, "W32SkypeEmu:Loop(Start)\n"); - - // Pump da messages - hProxy->dwThreadID = GetCurrentThreadId(); - LockMutex(hProxy->loopmutex); - while (GetMessage(&Message, NULL, 0, 0)) - { - TranslateMessage(&Message); - DispatchMessage(&Message); - } - - if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) - fprintf (hProxy->pCfg->fpLog, "W32SkypeEmu:Loop(End)\n"); - UnlockMutex(hProxy->loopmutex); -} - - -// ----------------------------------------------------------------------------- - -static void Imo2sproxy_Exit(IMO2SPROXY *hInst) -{ - IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst; - CONNINST *pInst; - - if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) - fprintf (hProxy->pCfg->fpLog, "W32SkypeEmu:Exit()\n"); - - if (hProxy->hWndDispatch) DestroyWindow (hProxy->hWndDispatch); - if (hProxy->dwThreadID) PostThreadMessage (hProxy->dwThreadID, WM_QUIT, 0, 0); - LockMutex(hProxy->loopmutex); - - // Kill 'em all! - if (hProxy->hClients) - { - while (pInst=List_Pop(hProxy->hClients)) - { - FreeConnection(pInst); - free (pInst); - } - List_Exit (hProxy->hClients); - } - - UnregisterClass ("Imo2SProxyDispatchWindow", GetModuleHandle(NULL)); - - UnlockMutex(hProxy->loopmutex); - ExitMutex(hProxy->loopmutex); - - free (hProxy); -} - diff --git a/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.h b/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.h deleted file mode 100644 index a8291f3357..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.h +++ /dev/null @@ -1,6 +0,0 @@ -typedef struct { - int bDelayLogin; -} W32SKYPEEMU_CFG; - -void W32SkypeEmu_Defaults (W32SKYPEEMU_CFG *pMyCfg); -IMO2SPROXY *W32SkypeEmu_Init (IMO2SPROXY_CFG *pCfg, W32SKYPEEMU_CFG *pMyCfg); diff --git a/!NotAdopted/IMO2sProxy/src/imolib/Makefile b/!NotAdopted/IMO2sProxy/src/imolib/Makefile deleted file mode 100644 index 30775becec..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imolib/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -CFLAGS = -I../common/ -lcurl -lpthread -lm -O0 -g -CC = gcc -COMMON = ../common/fifo.c ../common/cJSON.c -OBJS = imo_request.c imo_skype.c skypetst.c io_layer.c - -.PHONY: all skypetst clean - -all : skypetst - -skypetst: $(COMMON) $(OBJS) - $(CC) -o skypetst $(COMMON) $(OBJS) $(CFLAGS) - -clean : - rm skypetst diff --git a/!NotAdopted/IMO2sProxy/src/imolib/imo_request.c b/!NotAdopted/IMO2sProxy/src/imolib/imo_request.c deleted file mode 100644 index 732a7e3e48..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imolib/imo_request.c +++ /dev/null @@ -1,388 +0,0 @@ -/* Module: imo_request.c - Purpose: Posts XMLHHTP-Requests to imo.im server - Author: leecher - Date: 30.08.2009 -*/ -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#define LockMutex(x) EnterCriticalSection (&x) -#define UnlockMutex(x) LeaveCriticalSection(&x) -#define InitMutex(x) InitializeCriticalSection(&x) -#define ExitMutex(x) DeleteCriticalSection(&x) -#define mutex_t CRITICAL_SECTION -#else -#include -#define LockMutex(x) pthread_mutex_lock(&x) -#define UnlockMutex(x) pthread_mutex_unlock(&x) -#define InitMutex(x) pthread_mutex_init(&x, NULL); -#define ExitMutex(x) -#define mutex_t pthread_mutex_t -#endif -#include -#include -#include -#include -#include "fifo.h" -#include "imo_request.h" -#include "io_layer.h" - -#define SSID_LENGTH 16 - -struct _tagIMORQ -{ - IOLAYER *hIO; - char szSessId[SSID_LENGTH+2]; - unsigned long send_ack; // Some Sending ACK number - unsigned long send_seq; // Within one ACK there seems to be a SEQ-Number? - unsigned long *psend_ack; // Pointer to send_ack to use - unsigned long *psend_seq; // Pointer to send_seq to use - mutex_t mutex; // Mutex for securing psend_ack and psend_seq read/write - BOOL bIsClone; // Indicates that the current handle is a clone - char *pszHost; // Login host - char szReqURL[32]; // Request-URL -}; - -static IOLAYER *(*IoLayer_Init)(void) = -#ifdef WIN32 -IoLayerW32_Init; -#else -IoLayerCURL_Init; -#endif - -// Forward declaration of private functions -static size_t add_data(char *data, size_t size, size_t nmemb, void *ctx); -static IMORQ *Init(void); - -// ----------------------------------------------------------------------------- -// Interface -// ----------------------------------------------------------------------------- - -void ImoRq_SetIOLayer(IOLAYER *(*fp_Init)(void)) -{ - IoLayer_Init = fp_Init; -} - -// ----------------------------------------------------------------------------- - -IMORQ *ImoRq_Init(void) -{ - - IMORQ *hRq; - - if (hRq = Init()) - { - /* Create session ID */ - ImoRq_CreateID (hRq->szSessId, SSID_LENGTH+1); - - hRq->psend_seq = &hRq->send_seq; - hRq->psend_ack = &hRq->send_ack; - InitMutex(hRq->mutex); - - /* Disptch version of imo.im protocol */ - switch (IMO_API_VERSION) - { - case 0: - hRq->pszHost = "https://o.imo.im/"; - break; - case 1: - hRq->pszHost = "https://imo.im/"; - break; - } - sprintf (hRq->szReqURL, "%simo", hRq->pszHost); - - /* Fetch start page to get cookies */ - if (hRq->hIO->Get (hRq->hIO, hRq->pszHost, NULL)) - - /* Get new session ID from system */ - { - char *pszRPC = ImoRq_ResetRPC (hRq), *pszRPCRes; - if (pszRPC) - { - if ((pszRPCRes = strstr(pszRPC, "ssid\":\"")) || (pszRPCRes = strstr(pszRPC, "ssid\": \""))) - strcpy (hRq->szSessId, strtok (pszRPCRes+7, "\"")); - } - } else { - ImoRq_Exit(hRq); - hRq = NULL; - } - } - - return hRq; -} - -// ----------------------------------------------------------------------------- - -IMORQ *ImoRq_Clone (IMORQ *hRq) -{ - IMORQ *hDup; - - if (!(hDup = Init())) return NULL; - strcpy (hDup->szSessId, hRq->szSessId); - hDup->psend_seq = hRq->psend_seq; - hDup->psend_ack = hRq->psend_ack; - hDup->mutex = hRq->mutex; - hDup->bIsClone = TRUE; - hDup->pszHost = hRq->pszHost; - strcpy (hDup->szReqURL, hRq->szReqURL); - return hDup; -} - -// ----------------------------------------------------------------------------- - -void ImoRq_Exit (IMORQ *hRq) -{ - if (hRq->hIO) hRq->hIO->Exit(hRq->hIO); - if (!hRq->bIsClone) ExitMutex (hRq->mutex); - free (hRq); -} -// ----------------------------------------------------------------------------- - -void ImoRq_Cancel (IMORQ *hRq) -{ - if (hRq->hIO) hRq->hIO->Cancel(hRq->hIO); -} - -// ----------------------------------------------------------------------------- - -char *ImoRq_PostImo(IMORQ *hRq, char *pszMethod, cJSON *data) -{ - TYP_FIFO *hPostString; - char *pszData, *pszEscData; - unsigned int uiCount = -1; - - if (!(pszData = cJSON_Print(data))) return NULL; -printf ("-> %s\n", pszData); -#ifdef _WIN32 -OutputDebugString (pszData); -OutputDebugString ("\n"); -#endif - pszEscData = hRq->hIO->EscapeString(hRq->hIO, pszData); - free (pszData); - if (!pszEscData || !(hPostString = Fifo_Init(strlen(pszEscData)+32))) - { - if (pszEscData) hRq->hIO->FreeEscapeString (pszEscData); - return NULL; - } - Fifo_AddString (hPostString, "method="); - Fifo_AddString (hPostString, pszMethod); - Fifo_AddString (hPostString, "&data="); - Fifo_AddString (hPostString, pszEscData); - hRq->hIO->FreeEscapeString (pszEscData); - pszEscData = Fifo_Get(hPostString, &uiCount); - pszData = hRq->hIO->Post (hRq->hIO, hRq->szReqURL, pszEscData, - uiCount-1, NULL); - Fifo_Exit(hPostString); -printf ("<- %s\n", pszData); - return pszData; -} - -// ----------------------------------------------------------------------------- - -char *ImoRq_PostSystem(IMORQ *hRq, char *pszMethod, char *pszSysTo, char *pszSysFrom, cJSON *data, int bFreeData) -{ - cJSON *root, *msgs, *msg, *to, *from; - char *pszRet; - - if (!(root=cJSON_CreateObject())) return NULL; - LockMutex (hRq->mutex); - cJSON_AddNumberToObject (root, "ack", *hRq->psend_ack); - if (*hRq->szSessId) cJSON_AddStringToObject (root, "ssid", hRq->szSessId); - else cJSON_AddNumberToObject (root, "ssid", 0); - cJSON_AddItemToObject (root, "messages", (msgs = cJSON_CreateArray())); - if (data) - { - msg=cJSON_CreateObject(); - cJSON_AddItemToObject(msg, "data", data); - to = cJSON_CreateObject(); - cJSON_AddStringToObject (to, "system", pszSysTo); - cJSON_AddItemToObject(msg, "to", to); - from = cJSON_CreateObject(); - cJSON_AddStringToObject (from, "system", pszSysFrom); - if (*hRq->szSessId) cJSON_AddStringToObject (from, "ssid", hRq->szSessId); - else cJSON_AddNumberToObject (from, "ssid", 0); - cJSON_AddItemToObject(msg, "from", from); - cJSON_AddNumberToObject (msg, "seq", (*hRq->psend_seq)++); - cJSON_AddItemToArray (msgs, msg); - } - UnlockMutex (hRq->mutex); - pszRet = ImoRq_PostImo (hRq, pszMethod, root); - if (data && !bFreeData) - { - msg->child = data->next; - data->next = NULL; - } - cJSON_Delete (root); - return pszRet; -} - -// ----------------------------------------------------------------------------- - -char *ImoRq_ResetRPC(IMORQ *hRq) -{ - cJSON *root, *ssid; - char *pszRet; - - if (!(root=cJSON_CreateObject())) return NULL; - cJSON_AddStringToObject (root, "method", (IMO_API_VERSION==0?"get_ssid":"get_cookie_and_ssid")); - ssid=cJSON_CreateObject(); - cJSON_AddStringToObject (ssid, "ssid", hRq->szSessId); - if (IMO_API_VERSION > 0) - { - cJSON_AddStringToObject (ssid, "kind", "reui"); - cJSON_AddStringToObject (ssid, "version", "1336611734.48"); - } - cJSON_AddItemToObject(root, "data", ssid); - if (IMO_API_VERSION == 0) *hRq->szSessId = 0; - pszRet = ImoRq_PostSystem (hRq, "rest_rpc", (IMO_API_VERSION==0?"ssid":"session"), "client", root, 1); - LockMutex (hRq->mutex); - *hRq->psend_seq=0; - UnlockMutex (hRq->mutex); - return pszRet; -} - -// ----------------------------------------------------------------------------- - -char *ImoRq_UserActivity(IMORQ *hRq) -{ - cJSON *ssid; - - ssid=cJSON_CreateObject(); - cJSON_AddStringToObject (ssid, "ssid", hRq->szSessId); - return ImoRq_PostToSys (hRq, "observed_user_activity", "session", ssid, 1, NULL); -} - -// ----------------------------------------------------------------------------- - -char *ImoRq_Echo(IMORQ *hRq) -{ - cJSON *data; - time_t t; - char szTime[16], *pszRet; - - if (!(data=cJSON_CreateObject())) return NULL; - sprintf (szTime, "%ld", time(&t)*1000); - cJSON_AddStringToObject (data, "t", szTime); - pszRet = ImoRq_PostImo (hRq, "echo", data); - cJSON_Delete (data); - return pszRet; -} - -// ----------------------------------------------------------------------------- - -char *ImoRq_Reui_Session(IMORQ *hRq) -{ - cJSON *ssid; - - ssid=cJSON_CreateObject(); - cJSON_AddStringToObject (ssid, "ssid", hRq->szSessId); - return ImoRq_PostToSys (hRq, "reui_session", "session", ssid, 1, NULL); -} - -// ----------------------------------------------------------------------------- - -char *ImoRq_PostToSys(IMORQ *hRq, char *pszMethod, char *pszSysTo, cJSON *data, int bFreeData, int *pireqid) -{ - cJSON *root; - char *pszRet; - - if (!(root=cJSON_CreateObject())) return NULL; - cJSON_AddStringToObject (root, "method", pszMethod); - if (pireqid) cJSON_AddNumberToObject(root, "request_id", *pireqid); - cJSON_AddItemToObject(root, "data", data); - pszRet = ImoRq_PostSystem (hRq, "forward_to_server", pszSysTo, "client", root, bFreeData); - if (!bFreeData) - { - data->prev->next = data->next; - if (data->next) data->next->prev = data->prev; - data->prev = data->next = NULL; - cJSON_Delete (root); - } - return pszRet; -} -// ----------------------------------------------------------------------------- - -char *ImoRq_PostAmy(IMORQ *hRq, char *pszMethod, cJSON *data) -{ - return ImoRq_PostToSys (hRq, pszMethod, "im", data, FALSE, NULL); -} - -// ----------------------------------------------------------------------------- - -char *ImoRq_SessId(IMORQ *hRq) -{ - return hRq->szSessId; -} - -// ----------------------------------------------------------------------------- - -char *ImoRq_GetLastError(IMORQ *hRq) -{ - return hRq->hIO->GetLastError (hRq->hIO); -} - -// ----------------------------------------------------------------------------- -char *ImoRq_GetHost(IMORQ *hRq) -{ - return hRq->pszHost; -} - -// ----------------------------------------------------------------------------- -void ImoRq_UpdateAck(IMORQ *hRq, unsigned long lAck) -{ - LockMutex (hRq->mutex); - *hRq->psend_ack = lAck; - UnlockMutex (hRq->mutex); -} -// ----------------------------------------------------------------------------- -unsigned long ImoRq_GetSeq(IMORQ *hRq) -{ - unsigned long lRet; - - LockMutex (hRq->mutex); - lRet = *hRq->psend_seq; - UnlockMutex (hRq->mutex); - return lRet; -} -// ----------------------------------------------------------------------------- - -void ImoRq_CreateID(char *pszID, int cbID) -{ - int i, r; - time_t curtime; - - srand(time(&curtime)); - for (i=0; ihIO->Get (hRq->hIO, pszURL, pdwLength); -} - -// ----------------------------------------------------------------------------- - -static IMORQ *Init(void) -{ - IMORQ *hRq = calloc(1, sizeof(IMORQ)); - - /* Setup CURL */ - if (!hRq) return NULL; - if (!(hRq->hIO = IoLayer_Init())) - { - ImoRq_Exit(hRq); - return NULL; - } - return hRq; -} - diff --git a/!NotAdopted/IMO2sProxy/src/imolib/imo_request.h b/!NotAdopted/IMO2sProxy/src/imolib/imo_request.h deleted file mode 100644 index 42da000bc2..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imolib/imo_request.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef _IMO_REQUEST_H_ -#define _IMO_REQUEST_H_ - -#include "cJSON.h" - -// 1 - New imo.im api -// 0 - o.imo.im api -#define IMO_API_VERSION 1 - -struct _tagIMORQ; -typedef struct _tagIMORQ IMORQ; - -#ifdef _IOLAYER_H_ -void ImoRq_SetIOLayer(IOLAYER *(*fp_Init)(void)); -#endif - -IMORQ *ImoRq_Init(void); -IMORQ *ImoRq_Clone (IMORQ *hRq); -void ImoRq_Cancel (IMORQ *hRq); -void ImoRq_Exit (IMORQ *hRq); - -char *ImoRq_SessId(IMORQ *hRq); -char *ImoRq_GetLastError(IMORQ *hRq); -char *ImoRq_GetHost(IMORQ *hRq); -char *ImoRq_PostAmy(IMORQ *hRq, char *pszMethod, cJSON *data); -void ImoRq_CreateID(char *pszID, int cbID); -char *ImoRq_PostSystem(IMORQ *hRq, char *pszMethod, char *pszSysTo, char *pszSysFrom, cJSON *data, int bFreeData); -char *ImoRq_PostToSys(IMORQ *hRq, char *pszMethod, char *pszSysTo, cJSON *data, int bFreeData, int *pireqid); -void ImoRq_UpdateAck(IMORQ *hRq, unsigned long lAck); -unsigned long ImoRq_GetSeq(IMORQ *hRq); -char *ImoRq_UserActivity(IMORQ *hRq); -char *ImoRq_ResetRPC(IMORQ *hRq); -char *ImoRq_Reui_Session(IMORQ *hRq); -char *ImoRq_Echo(IMORQ *hRq); -char *ImoRq_HTTPGet(IMORQ *hRq, char *pszURL, unsigned int *pdwLength); -#endif diff --git a/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.c b/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.c deleted file mode 100644 index f2bca4d7b8..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.c +++ /dev/null @@ -1,707 +0,0 @@ -/* Module: imo_skype.c - Purpose: Communication layer for imo.im Skype - Author: leecher - Date: 30.08.2009 -*/ -#include -#include -#include -#include "imo_request.h" -#include "imo_skype.h" - -#ifdef _WIN64 -#pragma comment (lib, "bufferoverflowU.lib") -#endif - -#define PROTO "prpl-skype" - -struct _tagIMOSKYPE -{ - IMORQ *hRq; - IMORQ *hPoll; - char *pszUser; - IMOSTATCB StatusCb; - char *pszLastRes; - void *pUser; - int request_id; -}; - -static int CheckReturn (IMOSKYPE *hSkype, char *pszMsg, char *pszExpected); -static int ManageBuddy(IMOSKYPE *hSkype, char *pszAction, char *pszBuddy, char *pszGroup); - -// ----------------------------------------------------------------------------- -// Interface -// ----------------------------------------------------------------------------- - -IMOSKYPE *ImoSkype_Init(IMOSTATCB StatusCb, void *pUser) -{ - IMOSKYPE *hSkype = calloc(1, sizeof(IMOSKYPE)); - - if (!hSkype) return NULL; - if (!(hSkype->hRq = ImoRq_Init()) || !(hSkype->hPoll = ImoRq_Clone(hSkype->hRq))) - { - ImoSkype_Exit(hSkype); - return NULL; - } - hSkype->StatusCb = StatusCb; - hSkype->pUser = pUser; - return hSkype; -} - -// ----------------------------------------------------------------------------- - -void ImoSkype_Exit(IMOSKYPE *hSkype) -{ - if (!hSkype) return; - if (hSkype->hRq) ImoRq_Exit(hSkype->hRq); - if (hSkype->hPoll) ImoRq_Exit(hSkype->hPoll); - if (hSkype->pszUser) free(hSkype->pszUser); - free (hSkype); -} - -// ----------------------------------------------------------------------------- - -void ImoSkype_CancelPolling(IMOSKYPE *hSkype) -{ - if (hSkype->hPoll) - ImoRq_Cancel(hSkype->hPoll); -} - -// ----------------------------------------------------------------------------- - -char *ImoSkype_GetLastError(IMOSKYPE *hSkype) -{ - char *pszRet = ImoRq_GetLastError(hSkype->hRq); - - if (!pszRet || !*pszRet) return hSkype->pszLastRes; - return pszRet; -} - -// ----------------------------------------------------------------------------- - -char *ImoSkype_GetUserHandle(IMOSKYPE *hSkype) -{ - return hSkype->pszUser; -} - -// ----------------------------------------------------------------------------- - -// -1 - Error -// 0 - Login failed -// 1 - Login successful -int ImoSkype_Login(IMOSKYPE *hSkype, char *pszUser, char *pszPass) -{ - cJSON *root; - char *pszRet; - int iRet = -1; - - if (!hSkype) return 0; - if (IMO_API_VERSION == 0) - { - if (!(root=cJSON_CreateObject())) return 0; - cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); - if (pszRet = ImoRq_PostToSys(hSkype->hRq, "cookie_login", "session", root, 1, NULL)) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - } - - if (!(root=cJSON_CreateObject())) return 0; - if (hSkype->pszUser) free (hSkype->pszUser); - cJSON_AddStringToObject(root, "uid", hSkype->pszUser = strdup(pszUser)); - cJSON_AddStringToObject(root, "proto", PROTO); - cJSON_AddStringToObject(root, "passwd", pszPass); - cJSON_AddNullToObject(root, "captcha"); // Uh-oh, thay may get annoying in the future! :( - cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); - if (pszRet = ImoRq_PostAmy(hSkype->hRq, "account_login", root)) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - cJSON_Delete(root); - - return iRet; -} - -// ----------------------------------------------------------------------------- - -// -1 - Error -// 0 - Logout failed -// 1 - Logout successful -int ImoSkype_Logout(IMOSKYPE *hSkype) -{ - cJSON *root; - char *pszRet; - int iRet = -1; - - if (!hSkype || !(root=cJSON_CreateObject())) return 0; - cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); - if (pszRet = ImoRq_PostToSys(hSkype->hRq, "signoff_all", "session", root, 1, NULL)) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - return iRet; -} - -// ----------------------------------------------------------------------------- - -// -1 - Error -// 0 - Received unknown answer -// 1 - Got back information, called notification callback -// 2 - Received PING [deprecated] -int ImoSkype_Poll(IMOSKYPE *hSkype) -{ - char *pszRet; - - if (!hSkype || !hSkype->hPoll) return 0; - pszRet = ImoRq_PostSystem(hSkype->hPoll, "forward_to_server", NULL, NULL, NULL, 1); - if (!pszRet) return -1; - return CheckReturn (hSkype, pszRet, "ping"); -} - -// ----------------------------------------------------------------------------- - -int ImoSkype_KeepAlive(IMOSKYPE *hSkype) -{ - char *pszRet; - - /* In case we want to receive Promo-Infos... - { - cJSON *edata = cJSON_CreateObject(), *root; - - root=cJSON_CreateObject(); - cJSON_AddStringToObject(edata, "kind", "web"); - cJSON_AddNumberToObject(edata, "quantity", 1); - cJSON_AddItemToObject(root, "edata", edata); - if (pszRet = ImoRq_PostToSys(hSkype->hRq, "get_promos", "promo", root, 1)) - CheckReturn(hSkype, pszRet, "ok"); - } - */ - - if (!hSkype) return 0; - pszRet = ImoRq_UserActivity(hSkype->hPoll); - if (!pszRet) return -1; - return CheckReturn (hSkype, pszRet, "ok"); -} - -// ----------------------------------------------------------------------------- - -// pszStatus: -// Valid states: -// typing -// typed -// not_typing -// -// -1 - Error -// 0 - Typing notification failed -// 1 - Typing notification successful -int ImoSkype_Typing(IMOSKYPE *hSkype, char *pszBuddy, char *pszStatus) -{ - cJSON *root; - char *pszRet; - int iRet = -1; - - if (!hSkype || !hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; - cJSON_AddStringToObject(root, "uid", hSkype->pszUser); - cJSON_AddStringToObject(root, "proto", PROTO); - cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); - cJSON_AddStringToObject(root, "buid", pszBuddy); - cJSON_AddStringToObject(root, "typing_state", pszStatus); - if (pszRet = ImoRq_PostAmy(hSkype->hRq, "im_typing", root)) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - cJSON_Delete(root); - return iRet; -} - -// ----------------------------------------------------------------------------- - -// -1 - Error -// 0 - Sending failed -// 1 - Send pending -int ImoSkype_SendMessage(IMOSKYPE *hSkype, char *pszBuddy, char *pszMessage, int *prequest_id) -{ - cJSON *root; - char *pszRet; - int iRet = -1; - - if (!hSkype || !hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; - cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); - cJSON_AddStringToObject(root, "uid", hSkype->pszUser); - cJSON_AddStringToObject(root, "proto", PROTO); - cJSON_AddStringToObject(root, "buid", pszBuddy); - cJSON_AddStringToObject(root, "msg", pszMessage); - if (pszRet = (IMO_API_VERSION==0?ImoRq_PostAmy(hSkype->hRq, "send_im", root):ImoRq_PostToSys (hSkype->hRq, "send_im", "im", root, 0, &hSkype->request_id))) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - if (prequest_id) *prequest_id = hSkype->request_id; - hSkype->request_id++; - cJSON_Delete(root); - return iRet; -} - -// ----------------------------------------------------------------------------- - -// pszStatus: -// Valid states: -// available -// away -// busy -// invisible -// -// -1 - Error -// 0 - Failed -// 1 - OK -int ImoSkype_SetStatus(IMOSKYPE *hSkype, char *pszStatus, char *pszStatusMsg) -{ - cJSON *root; - char *pszRet; - int iRet = -1; - - /* - if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; - cJSON_AddStringToObject(root, "uid", hSkype->pszUser); - cJSON_AddStringToObject(root, "proto", PROTO); - cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); - cJSON_AddStringToObject(root, "ad", ""); - cJSON_AddStringToObject(root, "primitive", pszStatus); - cJSON_AddStringToObject(root, "status", pszStatusMsg); - if (pszRet = ImoRq_PostAmy(hSkype->hRq, "set_status", root)) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - */ - - if (!hSkype || !hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; - cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); - cJSON_AddStringToObject(root, "ad", ""); - cJSON_AddStringToObject(root, "primitive", pszStatus); - cJSON_AddStringToObject(root, "status", pszStatusMsg); - cJSON_AddFalseToObject (root, "auto_away"); - if (pszRet = ImoRq_PostToSys(hSkype->hRq, "set_status", "session", root, 0, NULL)) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - - cJSON_Delete(root); - return iRet; -} - -// ----------------------------------------------------------------------------- - -// -1 - Error -// 0 - Failed -// 1 - OK -int ImoSkype_AddBuddy(IMOSKYPE *hSkype, char *pszBuddy) -{ - return ManageBuddy (hSkype, "add_buddy", pszBuddy, "Offline"); -} - -// ----------------------------------------------------------------------------- - -// pszGroup = "Offline" if the user if offline, otherwise "Skype" or "Buddies" -// -1 - Error -// 0 - Failed -// 1 - OK -int ImoSkype_DelBuddy(IMOSKYPE *hSkype, char *pszBuddy, char *pszGroup) -{ - int iRet = ManageBuddy (hSkype, "del_buddy", pszBuddy, pszGroup); - - if (iRet<1 && strcmp(pszGroup, "Skype")==0) - return ManageBuddy (hSkype, "del_buddy", pszBuddy, "Buddies"); - return iRet; -} -// ----------------------------------------------------------------------------- - -int ImoSkype_BlockBuddy(IMOSKYPE *hSkype, char *pszBuddy) -{ - return ManageBuddy (hSkype, "block_buddy", pszBuddy, NULL); -} - -// ----------------------------------------------------------------------------- - -int ImoSkype_UnblockBuddy(IMOSKYPE *hSkype, char *pszBuddy) -{ - return ManageBuddy (hSkype, "unblock_buddy", pszBuddy, NULL); -} - -// ----------------------------------------------------------------------------- - -int ImoSkype_ChangeAlias(IMOSKYPE *hSkype, char *pszBuddy, char *pszNewAlias) -{ - cJSON *root; - char *pszRet; - int iRet = -1; - - if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; - cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); - cJSON_AddStringToObject(root, "uid", hSkype->pszUser); - cJSON_AddStringToObject(root, "proto", PROTO); - cJSON_AddStringToObject(root, "buid", pszBuddy); - cJSON_AddStringToObject(root, "alias", pszNewAlias); - if (pszRet = ImoRq_PostAmy(hSkype->hRq, "change_buddy_alias", root)) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - cJSON_Delete(root); - return iRet; -} - -// ----------------------------------------------------------------------------- - -int ImoSkype_StartVoiceCall(IMOSKYPE *hSkype, char *pszBuddy) -{ - cJSON *root; - char *pszRet; - int iRet = -1; - - if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; - cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); - cJSON_AddStringToObject(root, "uid", hSkype->pszUser); - cJSON_AddStringToObject(root, "proto", PROTO); - cJSON_AddStringToObject(root, "buid", pszBuddy); - if (pszRet = ImoRq_PostToSys (hSkype->hRq, "start_audio_chat", "av", root, 1, NULL)) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - return iRet; -} - -// ----------------------------------------------------------------------------- - -int ImoSkype_Ping(IMOSKYPE *hSkype) -{ - char *pszRet; - int iRet = -1; - - if (pszRet = ImoRq_Echo(hSkype->hRq)) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - return iRet; -} - -// ----------------------------------------------------------------------------- - -char *ImoSkype_GetAvatar(IMOSKYPE *hSkype, char *pszID, unsigned int *pdwLength) -{ - char szURL[256]; - - sprintf (szURL, "%sb/%s", ImoRq_GetHost(hSkype->hRq), pszID); - return ImoRq_HTTPGet (hSkype->hRq, szURL, pdwLength); -} - -// ----------------------------------------------------------------------------- - -int ImoSkype_GetUnreadMsgs(IMOSKYPE *hSkype) -{ - cJSON *root; - char *pszRet; - int iRet = -1; - - if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; - cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); - cJSON_AddStringToObject(root, "uid", hSkype->pszUser); - cJSON_AddStringToObject(root, "proto", PROTO); - if (pszRet = ImoRq_PostAmy(hSkype->hRq, "get_unread_msgs", root)) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - cJSON_Delete(root); - return iRet; -} - -// ----------------------------------------------------------------------------- - -int ImoSkype_GetAlpha(IMOSKYPE *hSkype) -{ - cJSON *root; - char *pszRet; - int iRet = -1; - - if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; - cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); - cJSON_AddStringToObject(root, "uid", hSkype->pszUser); - cJSON_AddStringToObject(root, "proto", PROTO); - if (pszRet = ImoRq_PostToSys (hSkype->hRq, "get_alpha_for_user", "alpha", root, 1, NULL)) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - return iRet; -} - -// ----------------------------------------------------------------------------- - - -int ImoSkype_CreateSharedGroup(IMOSKYPE *hSkype, char *pszName) -{ - cJSON *root; - char *pszRet; - int iRet = -1; - - if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; - cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); - cJSON_AddStringToObject(root, "uid", hSkype->pszUser); - cJSON_AddStringToObject(root, "proto", PROTO); - cJSON_AddFalseToObject(root, "is_native"); // TRUE would be great, but not yet supported? - cJSON_AddStringToObject(root, "name", pszName); - if (pszRet = ImoRq_PostAmy(hSkype->hRq, "create_shared_group", root)) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - cJSON_Delete(root); - return iRet; -} - -// ----------------------------------------------------------------------------- - -int ImoSkype_GroupInvite(IMOSKYPE *hSkype, char *pszGroup, char *pszUser) -{ - cJSON *root; - char *pszRet, *p, *pszGroupDup = strdup(pszGroup); - int iRet = -1; - - if (p=strrchr(pszGroupDup, ';')) *p=0; - if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; - cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); - cJSON_AddStringToObject(root, "uid", hSkype->pszUser); - cJSON_AddStringToObject(root, "proto", PROTO); - cJSON_AddStringToObject(root, "gid", pszGroupDup); - cJSON_AddStringToObject(root, "iproto", PROTO); - cJSON_AddStringToObject(root, "iuid", hSkype->pszUser); - cJSON_AddStringToObject(root, "ibuid", pszUser); - if (pszRet = ImoRq_PostAmy(hSkype->hRq, "invite_to_group", root)) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - free (pszGroupDup); - cJSON_Delete(root); - return iRet; -} - -// ----------------------------------------------------------------------------- - -int ImoSkype_GroupKick(IMOSKYPE *hSkype, char *pszGroup, char *pszUser) -{ - cJSON *root; - char *pszRet, *p, *pszGroupDup = strdup(pszGroup), szBUID[256]; - int iRet = -1; - - if (p=strrchr(pszGroupDup, ';')) *p=0; - sprintf (szBUID, "%s;%s;"PROTO, pszGroupDup, pszUser); - if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; - cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); - cJSON_AddStringToObject(root, "uid", hSkype->pszUser); - cJSON_AddStringToObject(root, "proto", PROTO); - cJSON_AddStringToObject(root, "buid", szBUID); - if (pszRet = ImoRq_PostAmy(hSkype->hRq, "kick_member", root)) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - free (pszGroupDup); - cJSON_Delete(root); - return iRet; -} - -// ----------------------------------------------------------------------------- - -int ImoSkype_GroupTopic(IMOSKYPE *hSkype, char *pszGroup, char *pszTopic) -{ - cJSON *root; - char *pszRet, *p, *pszGroupDup = strdup(pszGroup); - int iRet = -1; - - if (p=strrchr(pszGroupDup, ';')) *p=0; - if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; - cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); - cJSON_AddStringToObject(root, "uid", hSkype->pszUser); - cJSON_AddStringToObject(root, "proto", PROTO); - cJSON_AddStringToObject(root, "gid", pszGroupDup); - cJSON_AddStringToObject(root, "topic", pszTopic); - if (pszRet = ImoRq_PostAmy(hSkype->hRq, "set_group_topic", root)) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - free (pszGroupDup); - cJSON_Delete(root); - return iRet; -} - -// ----------------------------------------------------------------------------- - -int ImoSkype_GroupLeave(IMOSKYPE *hSkype, char *pszGroup) -{ - cJSON *root; - char *pszRet, *p, *pszGroupDup = strdup(pszGroup); - int iRet = -1; - - if (p=strrchr(pszGroupDup, ';')) *p=0; - if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; - cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); - cJSON_AddStringToObject(root, "uid", hSkype->pszUser); - cJSON_AddStringToObject(root, "proto", PROTO); - cJSON_AddStringToObject(root, "gid", pszGroupDup); - if (pszRet = ImoRq_PostAmy(hSkype->hRq, "leave_group", root)) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - free (pszGroupDup); - cJSON_Delete(root); - return iRet; -} - -// ----------------------------------------------------------------------------- -// Static -// ----------------------------------------------------------------------------- -static void PostDisconnect(IMOSKYPE *hSkype) -{ - cJSON *arr, *root; - - if (arr = cJSON_CreateArray()) - { - if (!(root=cJSON_CreateObject())) return; - cJSON_AddStringToObject(root, "name", "disconnect"); - cJSON_AddItemToArray (arr, root); - hSkype->StatusCb(arr, hSkype->pUser); - cJSON_Delete(arr); - } -} - -// 0 - Unexpected answer -// 1 - Got back JSON data, notified callback -// 2 - Received expected message pszExpected [deprecated] -static int CheckReturn (IMOSKYPE *hSkype, char *pszMsg, char *pszExpected) -{ - cJSON *root, *data, *msgs, *msg, *sys, *arr, *prefs, *pref; - char *pszMethod, *pszSys; - - hSkype->pszLastRes = pszMsg; - if (root = cJSON_Parse(pszMsg)) - { - // Now let's see if this one is interesting for our system - if ((data = cJSON_GetObjectItem(root,"method")) && - (pszMethod = data->valuestring) && - strcmp(pszMethod, "forward_to_client") == 0 && - (data = cJSON_GetObjectItem(root,"data")) && - (msgs = cJSON_GetObjectItem(data,"messages"))) - { - int i, iCount = cJSON_GetArraySize(msgs); - - if (!iCount && pszExpected && strcmp(pszExpected, "ok") == 0) - { - if ((sys = cJSON_GetObjectItem(data,"ack")) && (unsigned long)sys->valueint >= ImoRq_GetSeq(hSkype->hRq)) - return 2; // imoim ACKnowledged this - else - { - if (sys && sys->valueint==0) - { - // ACK error, reset to 0, better reset the connection - PostDisconnect(hSkype); - } - return 0; // No ACK, sequence number not incremented :( - } - } - for (i=0; ivaluestring) && - strcmp (pszSys, "client") == 0) - { - if (sys = cJSON_GetObjectItem(msg,"seq")) - { - ImoRq_UpdateAck(hSkype->hRq, sys->valueint+1); - ImoRq_UpdateAck(hSkype->hPoll, sys->valueint+1); - } - - // Callback is only called for system IM - if ((sys = cJSON_GetObjectItem(msg,"from")) && - (pszSys = cJSON_GetObjectItem(sys, "system")->valuestring)) - { - if ((strcmp (pszSys, "im") == 0 || strcmp (pszSys, "av") == 0) && - (data = cJSON_GetObjectItem(msg,"data")) && - (arr = cJSON_CreateArray())) - { - // Pack data into array for Callback backwards - // compatibility - cJSON *next; - - next = data->next; - data->next = NULL; - cJSON_AddItemToArray (arr, data); - hSkype->StatusCb(arr, hSkype->pUser); - data->next = next; - free(arr); - } - else if (strcmp (pszSys, "internal") == 0 && - (data = cJSON_GetObjectItem(msg,"data")) && - (arr = cJSON_CreateArray())) - { - // Pack ACK msgs into a fake "ack" method so that callback - // function can dispatch them without interface change - cJSON *next; - - cJSON_AddStringToObject (data, "name", "ack"); - next = data->next; - data->next = NULL; - cJSON_AddItemToArray (arr, data); - hSkype->StatusCb(arr, hSkype->pUser); - data->next = next; - free(arr); - } - // Ensure to disable annoying autoaway - else if (strcmp (pszSys, "preference") == 0 && - (data = cJSON_GetObjectItem(msg,"data")) && - (prefs = cJSON_GetObjectItem(data, "preferences"))) - { - int j, nPrefs = cJSON_GetArraySize(prefs); - cJSON *kind, *thispref, *value, *prefdata; - - for (j=0; jvaluestring, "impref") == 0 && - (thispref = cJSON_GetObjectItem(pref, "pref")) && - strcmp (thispref->valuestring, "auto_away") == 0 && - (value = cJSON_GetObjectItem(pref, "value")) && - value->type == cJSON_True && hSkype->pszUser && - (prefdata = cJSON_CreateObject())) - { - cJSON *accs, *acc, *setprefs, *newpref; - - if (accs = cJSON_CreateArray()) - { - if (acc = cJSON_CreateObject()) - { - cJSON_AddStringToObject(acc, "uid", hSkype->pszUser); - cJSON_AddStringToObject(acc, "proto", PROTO); - cJSON_AddItemToArray (accs, acc); - } - cJSON_AddItemToObject(prefdata, "accounts", accs); - } - if (setprefs = cJSON_CreateArray()) - { - if (newpref = cJSON_CreateObject()) - { - cJSON_AddStringToObject(newpref, "kind", kind->valuestring); - cJSON_AddStringToObject(newpref, "pref", thispref->valuestring); - cJSON_AddFalseToObject (newpref, "value"); - cJSON_AddItemToArray (setprefs, newpref); - } - cJSON_AddItemToObject(prefdata, "preferences", setprefs); - } - ImoRq_PostToSys (hSkype->hRq, "set", "preference", prefdata, 1, NULL); - } - } - } - else if (strcmp (pszSys, "reset") == 0) - { - // System requested to reset connection - // Let's issue a "disconnect" to the callback to let it handle - // this situation - } - } - } - } - } - } - cJSON_Delete(root); - return 1; - } - else - { - if (pszExpected && strcmp(pszMsg, pszExpected)==0) - return 2; - } - return 0; -} - -// ----------------------------------------------------------------------------- - -static int ManageBuddy(IMOSKYPE *hSkype, char *pszAction, char *pszBuddy, char *pszGroup) -{ - cJSON *root; - char *pszRet; - int iRet = -1; - - if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; - cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); - cJSON_AddStringToObject(root, "uid", hSkype->pszUser); - cJSON_AddStringToObject(root, "proto", PROTO); - cJSON_AddStringToObject(root, "buid", pszBuddy); - if (pszGroup) cJSON_AddStringToObject(root, "group", pszGroup); - if (pszRet = ImoRq_PostAmy(hSkype->hRq, pszAction, root)) - iRet = CheckReturn(hSkype, pszRet, "ok")>0; - cJSON_Delete(root); - return iRet; -} diff --git a/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.h b/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.h deleted file mode 100644 index d9e1697ed6..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.h +++ /dev/null @@ -1,37 +0,0 @@ -#include "cJSON.h" - -struct _tagIMOSKYPE; -typedef struct _tagIMOSKYPE IMOSKYPE; -// 0 - Message received, you may delete the cJSON object now -// 1 - Don't delete cJSON object, callback will take care of freeing -typedef int(*IMOSTATCB)(cJSON *pMsg, void *pUser); - -IMOSKYPE *ImoSkype_Init(IMOSTATCB StatusCb, void *pUser); -void ImoSkype_Exit(IMOSKYPE *hSkype); -void ImoSkype_CancelPolling(IMOSKYPE *hSkype); -char *ImoSkype_GetLastError(IMOSKYPE *hSkype); -char *ImoSkype_GetUserHandle(IMOSKYPE *hSkype); - -int ImoSkype_Login(IMOSKYPE *hSkype, char *pszUser, char *pszPass); -int ImoSkype_Logout(IMOSKYPE *hSkype); -int ImoSkype_Poll(IMOSKYPE *hSkype); -int ImoSkype_Typing(IMOSKYPE *hSkype, char *pszBuddy, char *pszStatus); -int ImoSkype_SetStatus(IMOSKYPE *hSkype, char *pszStatus, char *pszStatusMsg); -int ImoSkype_SendMessage(IMOSKYPE *hSkype, char *pszBuddy, char *pszMessage, int *prequest_id); -int ImoSkype_AddBuddy(IMOSKYPE *hSkype, char *pszBuddy); -int ImoSkype_DelBuddy(IMOSKYPE *hSkype, char *pszBuddy, char *pszGroup); -int ImoSkype_BlockBuddy(IMOSKYPE *hSkype, char *pszBuddy); -int ImoSkype_UnblockBuddy(IMOSKYPE *hSkype, char *pszBuddy); -int ImoSkype_ChangeAlias(IMOSKYPE *hSkype, char *pszBuddy, char *pszNewAlias); -int ImoSkype_StartVoiceCall(IMOSKYPE *hSkype, char *pszBuddy); -int ImoSkype_KeepAlive(IMOSKYPE *hSkype); -int ImoSkype_Ping(IMOSKYPE *hSkype); -char *ImoSkype_GetAvatar(IMOSKYPE *hSkype, char *pszID, unsigned int *pdwLength); -int ImoSkype_GetUnreadMsgs(IMOSKYPE *hSkype); -int ImoSkype_GetAlpha(IMOSKYPE *hSkype); - -int ImoSkype_CreateSharedGroup(IMOSKYPE *hSkype, char *pszName); -int ImoSkype_GroupInvite(IMOSKYPE *hSkype, char *pszGroup, char *pszUser); -int ImoSkype_GroupKick(IMOSKYPE *hSkype, char *pszGroup, char *pszUser); -int ImoSkype_GroupTopic(IMOSKYPE *hSkype, char *pszGroup, char *pszTopic); -int ImoSkype_GroupLeave(IMOSKYPE *hSkype, char *pszGroup); diff --git a/!NotAdopted/IMO2sProxy/src/imolib/io_layer.c b/!NotAdopted/IMO2sProxy/src/imolib/io_layer.c deleted file mode 100644 index 1e18464682..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imolib/io_layer.c +++ /dev/null @@ -1,175 +0,0 @@ -/* Module: io_layer.c - Purpose: IO Layer for Internet communication using libcurl - Author: leecher - Date: 30.08.2009 -*/ -#include -#include -#include -#include -#include "fifo.h" -#include "io_layer.h" - -typedef struct -{ - IOLAYER vtbl; - CURL *hCurl; - TYP_FIFO *hResult; - char szErrorBuf[CURL_ERROR_SIZE+1]; -} IOLAYER_INST; - -static void IoLayer_Exit (IOLAYER *hPIO); -static char *IoLayer_Post(IOLAYER *hPIO, char *pszUrl, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength); -static char *IoLayer_Get(IOLAYER *hPIO, char *pszUrl, unsigned int *pdwLength); -static void IoLayer_Cancel(IOLAYER *hIO); -static char *IoLayer_GetLastError(IOLAYER *hIO); -static char *IoLayer_EscapeString(IOLAYER *hIO, char *pszData); -static void IoLayer_FreeEscapeString(char *pszData); -static size_t add_data(char *data, size_t size, size_t nmemb, void *ctx); - -// ----------------------------------------------------------------------------- -// Interface -// ----------------------------------------------------------------------------- - -IOLAYER *IoLayerCURL_Init(void) -{ - IOLAYER_INST *hIO; - - if (!(hIO = calloc(1, sizeof(IOLAYER_INST)))) - return NULL; - - if (!(hIO->hCurl = curl_easy_init())) - { - free (hIO); - return NULL; - } - - if (!(hIO->hResult = Fifo_Init(1024))) - { - IoLayer_Exit((IOLAYER*)hIO); - return NULL; - } - - curl_easy_setopt(hIO->hCurl, CURLOPT_USERAGENT, "XMLHttpRequest/1.0"); - curl_easy_setopt(hIO->hCurl, CURLOPT_HEADER, 0); - curl_easy_setopt(hIO->hCurl, CURLOPT_AUTOREFERER, 1); -// curl_easy_setopt(hRq->hCurl, CURLOPT_RETURNTRANSFER, 1); - curl_easy_setopt(hIO->hCurl, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(hIO->hCurl, CURLOPT_SSL_VERIFYHOST, 0); - curl_easy_setopt(hIO->hCurl, CURLOPT_ERRORBUFFER, hIO->szErrorBuf); - curl_easy_setopt(hIO->hCurl, CURLOPT_COOKIEFILE, "cookies.txt"); - curl_easy_setopt(hIO->hCurl, CURLOPT_COOKIEJAR, "cookies.txt"); - curl_easy_setopt(hIO->hCurl, CURLOPT_WRITEFUNCTION, add_data); - curl_easy_setopt(hIO->hCurl, CURLOPT_FILE, hIO); - - // Init Vtbl - hIO->vtbl.Exit = IoLayer_Exit; - hIO->vtbl.Post = IoLayer_Post; - hIO->vtbl.Get = IoLayer_Get; - hIO->vtbl.Cancel = IoLayer_Cancel; - hIO->vtbl.GetLastError = IoLayer_GetLastError; - hIO->vtbl.EscapeString = IoLayer_EscapeString; - hIO->vtbl.FreeEscapeString = IoLayer_FreeEscapeString; - - return (IOLAYER*)hIO; -} - -// ----------------------------------------------------------------------------- - -static void IoLayer_Exit (IOLAYER *hPIO) -{ - IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; - - if (hIO->hCurl) curl_easy_cleanup(hIO->hCurl); - if (hIO->hResult) Fifo_Exit(hIO->hResult); - free (hIO); -} - -// ----------------------------------------------------------------------------- - -static char *IoLayer_Post(IOLAYER *hPIO, char *pszUrl, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength) -{ - IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; - - curl_easy_setopt(hIO->hCurl, CURLOPT_POST, 1); - curl_easy_setopt(hIO->hCurl, CURLOPT_URL, pszUrl); - curl_easy_setopt(hIO->hCurl, CURLOPT_POSTFIELDS, pszPostFields); - curl_easy_setopt(hIO->hCurl, CURLOPT_POSTFIELDSIZE, cbPostFields); - if (curl_easy_perform(hIO->hCurl)) return NULL; - if (!pdwLength) - { - // Get string - Fifo_Add (hIO->hResult, "", 1); - return Fifo_Get (hIO->hResult, NULL); - } - else - { - // Get binary, return size of buffer - *pdwLength = (unsigned int)-1; - return Fifo_Get (hIO->hResult, pdwLength); - } -} - -// ----------------------------------------------------------------------------- - -static char *IoLayer_Get(IOLAYER *hPIO, char *pszUrl, unsigned int *pdwLength) -{ - IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; - - curl_easy_setopt(hIO->hCurl, CURLOPT_POST, 0); - curl_easy_setopt(hIO->hCurl, CURLOPT_URL, pszUrl); - if (curl_easy_perform(hIO->hCurl)) return NULL; - if (!pdwLength) - { - // Get string - Fifo_Add (hIO->hResult, "", 1); - return Fifo_Get (hIO->hResult, NULL); - } - else - { - // Get binary, return size of buffer - *pdwLength = (unsigned int)-1; - return Fifo_Get (hIO->hResult, pdwLength); - } -} - -// ----------------------------------------------------------------------------- - -static void IoLayer_Cancel(IOLAYER *hIO) -{ - // FIXME: Currently not implemented -} - -// ----------------------------------------------------------------------------- - -static char *IoLayer_GetLastError(IOLAYER *hIO) -{ - return ((IOLAYER_INST*)hIO)->szErrorBuf; -} - -// ----------------------------------------------------------------------------- - -static char *IoLayer_EscapeString(IOLAYER *hIO, char *pszData) -{ - return curl_easy_escape(((IOLAYER_INST*)hIO)->hCurl, pszData, 0); -} - -// ----------------------------------------------------------------------------- - -static void IoLayer_FreeEscapeString(char *pszData) -{ - curl_free(pszData); -} - -// ----------------------------------------------------------------------------- -// Static -// ----------------------------------------------------------------------------- - -static size_t add_data(char *data, size_t size, size_t nmemb, void *ctx) -{ - IOLAYER_INST *hIO = (IOLAYER_INST*)ctx; - - if (Fifo_Add(hIO->hResult, data, size * nmemb)) return size * nmemb; - return 0; -} - diff --git a/!NotAdopted/IMO2sProxy/src/imolib/io_layer.h b/!NotAdopted/IMO2sProxy/src/imolib/io_layer.h deleted file mode 100644 index 13e10cf888..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imolib/io_layer.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _IOLAYER_H_ -#define _IOLAYER_H_ - -struct _tagIOLAYER; -typedef struct _tagIOLAYER IOLAYER; - -struct _tagIOLAYER -{ - void (*Exit) (IOLAYER *hIO); - - char *(*Post) (IOLAYER *hIO, char *pszURL, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength); - char *(*Get) (IOLAYER *hIO, char *pszURL, unsigned int *pdwLength); - void (*Cancel) (IOLAYER *hIO); - char *(*GetLastError) (IOLAYER *hIO); - char *(*EscapeString) (IOLAYER *hIO, char *pszData); - void (*FreeEscapeString) (char *pszData); -}; - -#ifdef WIN32 -IOLAYER *IoLayerW32_Init(void); -IOLAYER *IoLayerNETLIB_Init(void); -#endif -IOLAYER *IoLayerCURL_Init(void); - -#endif diff --git a/!NotAdopted/IMO2sProxy/src/imolib/io_layer_win32.c b/!NotAdopted/IMO2sProxy/src/imolib/io_layer_win32.c deleted file mode 100644 index 1fd425ced7..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imolib/io_layer_win32.c +++ /dev/null @@ -1,440 +0,0 @@ -/* Module: io_layer_win32.c - Purpose: IO Layer for Internet communication using WININET (Win32) - Author: leecher - Date: 30.08.2009 -*/ -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include -#include "fifo.h" -#include "io_layer.h" - -#ifndef LongToPtr -#define DWORD_PTR DWORD -#endif - -/* Set this to use asynchronous I/O - This is needed as synchronous WININET functions tend to block forever on connection - loss or other occasions leading to a deadlock of the whole application - */ -#define ASYNC -#define ASYNC_CONN_TIMEOUT 5000 // Connection timeout in ms -#define ASYNC_REQ_TIMEOUT 40000 // HttpSendRequest timeout in ms in async mode (Should be at least 30 sec!) - -#pragma comment(lib,"wininet.lib") - -#define INET_FLAGS INTERNET_FLAG_IGNORE_CERT_CN_INVALID | INTERNET_FLAG_IGNORE_CERT_DATE_INVALID | \ - INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_UI | \ - INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_SECURE - -typedef struct -{ - IOLAYER vtbl; - HINTERNET hInet; - HINTERNET hRequest; -#ifdef ASYNC - INTERNET_ASYNC_RESULT stAsyncRes; - HANDLE hConnectedEvent; - HANDLE hRequestCompleteEvent; -#endif - TYP_FIFO *hResult; - LPVOID lpErrorBuf; -} IOLAYER_INST; - -static void IoLayer_Exit (IOLAYER *hPIO); -static char *IoLayer_Post(IOLAYER *hPIO, char *pszURL, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength); -static char *IoLayer_Get(IOLAYER *hIO, char *pszURL, unsigned int *pdwLength); -static void IoLayer_Cancel(IOLAYER *hIO); -static char *IoLayer_GetLastError(IOLAYER *hIO); -static char *IoLayer_EscapeString(IOLAYER *hPIO, char *pszData); -static void IoLayer_FreeEscapeString(char *pszData); -static void FetchLastError (IOLAYER_INST *hIO); -#ifdef ASYNC -static void __stdcall Callback(HINTERNET hInternet, DWORD dwContext, DWORD dwInternetStatus, - LPVOID lpStatusInfo, DWORD dwStatusInfoLen); -#endif - -// ----------------------------------------------------------------------------- -// Interface -// ----------------------------------------------------------------------------- - -IOLAYER *IoLayerW32_Init(void) -{ - IOLAYER_INST *hIO; - - if (!(hIO = calloc(1, sizeof(IOLAYER_INST)))) - return NULL; - - // Init Inet - if (!(hIO->hInet = InternetOpen ("Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13", - INTERNET_OPEN_TYPE_PRECONFIG, NULL, "", -#ifdef ASYNC - INTERNET_FLAG_ASYNC -#else - 0 -#endif - ))) - { - free (hIO); - return NULL; - } - - if (!(hIO->hResult = Fifo_Init(1024))) - { - IoLayer_Exit((IOLAYER*)hIO); - return NULL; - } - -#ifdef ASYNC - if (InternetSetStatusCallback(hIO->hInet, (INTERNET_STATUS_CALLBACK)&Callback) == INTERNET_INVALID_STATUS_CALLBACK) - { - IoLayer_Exit((IOLAYER*)hIO); - return NULL; - } - - hIO->hConnectedEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - hIO->hRequestCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL); -#endif - - //InternetSetCookie ("https://o.imo.im/", "proto", "prpl-skype"); - - // Init Vtbl - hIO->vtbl.Exit = IoLayer_Exit; - hIO->vtbl.Post = IoLayer_Post; - hIO->vtbl.Get = IoLayer_Get; - hIO->vtbl.Cancel = IoLayer_Cancel; - hIO->vtbl.GetLastError = IoLayer_GetLastError; - hIO->vtbl.EscapeString = IoLayer_EscapeString; - hIO->vtbl.FreeEscapeString = IoLayer_FreeEscapeString; - - return (IOLAYER*)hIO; -} -// ----------------------------------------------------------------------------- - -static void IoLayer_Exit (IOLAYER *hPIO) -{ - IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; - - if (hIO->hInet) InternetCloseHandle (hIO->hInet); - if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf); - if (hIO->hResult) Fifo_Exit(hIO->hResult); - -#ifdef ASYNC - if (hIO->hConnectedEvent) CloseHandle (hIO->hConnectedEvent); - if (hIO->hRequestCompleteEvent) CloseHandle (hIO->hRequestCompleteEvent); -#endif - free (hIO); -} - -// ----------------------------------------------------------------------------- - -static char *IoLayer_Post(IOLAYER *hPIO, char *pszURL, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength) -{ - IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; - URL_COMPONENTS urlInfo = {0}; - HINTERNET hUrl; - DWORD dwFlags = 0, cbFlags = sizeof(dwFlags), dwRemaining = 0; - char szHostName[INTERNET_MAX_HOST_NAME_LENGTH], - szURLPath[INTERNET_MAX_URL_LENGTH], *p; -#ifdef ASYNC - INTERNET_BUFFERS InetBuff={0}; - InetBuff.dwStructSize = sizeof(InetBuff); - - ResetEvent (hIO->hConnectedEvent); - ResetEvent (hIO->hRequestCompleteEvent); -#endif - -//OutputDebugString(pszPostFields); - urlInfo.dwStructSize = sizeof (URL_COMPONENTS); - urlInfo.lpszHostName = szHostName; - urlInfo.dwHostNameLength = sizeof(szHostName); - urlInfo.lpszUrlPath = szURLPath; - urlInfo.dwUrlPathLength = sizeof(szURLPath); - if (!InternetCrackUrl(pszURL, strlen(pszURL), 0, &urlInfo)) return NULL; - /* - if (!pszPostFields) - { - if (pszPostFields=strchr (pszURL, '?')) - cbPostFields = strlen(pszPostFields); - } - */ - if (!(hUrl = InternetConnect (hIO->hInet, szHostName, - INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)hIO))) - { -#ifdef ASYNC - if (GetLastError() == ERROR_IO_PENDING) - { - if (WaitForSingleObject(hIO->hConnectedEvent, ASYNC_CONN_TIMEOUT) == WAIT_OBJECT_0) - { - hUrl = (HINTERNET)hIO->stAsyncRes.dwResult; - hIO->stAsyncRes.dwResult = 0; - SetLastError(hIO->stAsyncRes.dwError); - } - } - if (!hUrl) -#endif - { - FetchLastError (hIO); - return NULL; - } - } - - hIO->hRequest = HttpOpenRequest (hUrl, pszPostFields?"POST":"GET", szURLPath, NULL, "https://imo.im/", NULL, - INET_FLAGS, (DWORD_PTR)hIO); - if (!hIO->hRequest) - { -#ifdef ASYNC - if (GetLastError() == ERROR_IO_PENDING) - { - if (WaitForSingleObject(hIO->hConnectedEvent, ASYNC_CONN_TIMEOUT) == WAIT_OBJECT_0) - { - hIO->hRequest = (HINTERNET)hIO->stAsyncRes.dwResult; - hIO->stAsyncRes.dwResult = 0; - SetLastError(hIO->stAsyncRes.dwError); - } - } - if (!hUrl) -#endif - { - FetchLastError (hIO); - InternetCloseHandle (hUrl); - return NULL; - } - } - - InternetQueryOption (hIO->hRequest, INTERNET_OPTION_SECURITY_FLAGS, (LPVOID)&dwFlags, &cbFlags); - dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA; - InternetSetOption (hIO->hRequest, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags)); - - /* - { - char szCookies[4096]; - DWORD cbCookies, dwIndex=0; - - OutputDebugString ("Sending headers:\n"); - do - { - cbCookies=sizeof(szCookies); - if (!HttpQueryInfo (hIO->hRequest, HTTP_QUERY_FLAG_REQUEST_HEADERS|HTTP_QUERY_RAW_HEADERS_CRLF, szCookies, &cbCookies, &dwIndex) || - GetLastError() != ERROR_SUCCESS) - break; - OutputDebugString (szCookies); - } while (1); - } - */ - -// ASYNC: This needs to block for at least 30 seconds on poll! - if (!(HttpSendRequest (hIO->hRequest, "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n" - "X-Requested-With: XMLHttpRequest", -1, - pszPostFields, cbPostFields))) - { -#ifdef ASYNC - BOOL bRes = FALSE; - - if (GetLastError() == ERROR_IO_PENDING) - { - if (WaitForSingleObject(hIO->hRequestCompleteEvent, ASYNC_REQ_TIMEOUT) == WAIT_OBJECT_0) - { - bRes = hIO->stAsyncRes.dwResult; - hIO->stAsyncRes.dwResult = 0; - SetLastError(hIO->stAsyncRes.dwError); - } - } - if (!bRes) -#endif - { - FetchLastError (hIO); - InternetCloseHandle (hIO->hRequest); - hIO->hRequest = NULL; - InternetCloseHandle (hUrl); - return NULL; - } - } -#ifdef ASYNC - else WaitForSingleObject(hIO->hRequestCompleteEvent, ASYNC_REQ_TIMEOUT); -#endif - - /* - { - char szCookies[4096]; - DWORD cbCookies, dwIndex=0; - - OutputDebugString ("Received headers:\n"); - do - { - cbCookies=sizeof(szCookies); - if (!HttpQueryInfo (hIO->hRequest, HTTP_QUERY_FLAG_REQUEST_HEADERS|HTTP_QUERY_RAW_HEADERS_CRLF, szCookies, &cbCookies, &dwIndex) || - GetLastError() != ERROR_SUCCESS) - break; - OutputDebugString (szCookies); - } while (1); - } - */ - -#ifdef ASYNC - do - { - if (!InternetQueryDataAvailable (hIO->hRequest, &InetBuff.dwBufferLength, 0, 0)) - { - BOOL bRes = FALSE; - - if (GetLastError() == ERROR_IO_PENDING) - { - if (WaitForSingleObject(hIO->hRequestCompleteEvent, ASYNC_REQ_TIMEOUT) == WAIT_OBJECT_0) - { - bRes = hIO->stAsyncRes.dwResult; - hIO->stAsyncRes.dwResult = 0; - SetLastError(hIO->stAsyncRes.dwError); - } - } - if (!bRes) break; - } - if (InetBuff.dwBufferLength == 0) break; - if (InetBuff.lpvBuffer = Fifo_AllocBuffer (hIO->hResult, InetBuff.dwBufferLength)) - { - if (!InternetReadFileEx (hIO->hRequest, &InetBuff, 0, (DWORD_PTR)hIO)) - { - BOOL bRes=FALSE; - - if (GetLastError() == ERROR_IO_PENDING) - { - if (WaitForSingleObject(hIO->hRequestCompleteEvent, ASYNC_REQ_TIMEOUT) == WAIT_OBJECT_0) - { - bRes = hIO->stAsyncRes.dwResult; - hIO->stAsyncRes.dwResult = 0; - SetLastError(hIO->stAsyncRes.dwError); - } - } - if (!bRes) break; - } - } - } - while(InetBuff.dwBufferLength); -#else - while (InternetQueryDataAvailable (hIO->hRequest, &dwRemaining, 0, 0) && dwRemaining > 0) - { - if (p = Fifo_AllocBuffer (hIO->hResult, dwRemaining)) - InternetReadFile (hIO->hRequest, p, dwRemaining, &dwRemaining); - } -#endif - - if (!pdwLength) - { - // Get string - Fifo_Add (hIO->hResult, "", 1); - p = Fifo_Get (hIO->hResult, NULL); - } - else - { - // Get binary, return size of buffer - *pdwLength = (unsigned int)-1; - p = Fifo_Get (hIO->hResult, pdwLength); - } - InternetCloseHandle (hIO->hRequest); - hIO->hRequest = NULL; - InternetCloseHandle (hUrl); -OutputDebugString(p); -OutputDebugString("\n"); - return p; -} - -// ----------------------------------------------------------------------------- - -static char *IoLayer_Get(IOLAYER *hIO, char *pszURL, unsigned int *pdwLength) -{ - return IoLayer_Post (hIO, pszURL, NULL, 0, pdwLength); -} - -// ----------------------------------------------------------------------------- - -static void IoLayer_Cancel(IOLAYER *hPIO) -{ - IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; - -#ifdef ASYNC - if (hIO->hRequest) - { - hIO->stAsyncRes.dwResult = 0; - hIO->stAsyncRes.dwError = ERROR_CANCELLED; - SetEvent(hIO->hRequestCompleteEvent); - } -#else - if (hIO->hRequest && InternetCloseHandle(hIO->hRequest)) - hIO->hRequest = NULL; -#endif -} - -// ----------------------------------------------------------------------------- - -static char *IoLayer_GetLastError(IOLAYER *hIO) -{ - return (char*)((IOLAYER_INST*)hIO)->lpErrorBuf; -} - -// ----------------------------------------------------------------------------- - -static char *IoLayer_EscapeString(IOLAYER *hPIO, char *pszData) -{ - IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; - TYP_FIFO *hFifo; - char szBuf[8], *pszRet; - unsigned char *p; - - if (!(hFifo = Fifo_Init(strlen(pszData)))) return NULL; - for (p=pszData; *p; p++) - { - if (isalnum(*p)) Fifo_Add (hFifo, p, 1); - else { - wsprintf (szBuf, "%%%02X", *p); - Fifo_Add (hFifo, szBuf, 3); - } - } - Fifo_Add (hFifo, "", 1); - if (pszRet = Fifo_Get(hFifo, NULL)) - pszRet = strdup(pszRet); - Fifo_Exit(hFifo); - return pszRet; -} - -// ----------------------------------------------------------------------------- - -static void IoLayer_FreeEscapeString(char *pszData) -{ - free (pszData); -} - -// ----------------------------------------------------------------------------- -// Static -// ----------------------------------------------------------------------------- - -static void FetchLastError (IOLAYER_INST *hIO) -{ - if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf); - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, - GetLastError(), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), - (LPTSTR)&hIO->lpErrorBuf, 0, NULL); -} - -#ifdef ASYNC -static void __stdcall Callback(HINTERNET hInternet, DWORD dwContext, DWORD dwInternetStatus, - LPVOID lpStatusInfo, DWORD dwStatusInfoLen) -{ - IOLAYER_INST *hIO = (IOLAYER_INST*)dwContext; - - - switch(dwInternetStatus) - { - case INTERNET_STATUS_HANDLE_CREATED: - SetEvent (hIO->hConnectedEvent); - break; - case INTERNET_STATUS_REQUEST_COMPLETE: - hIO->stAsyncRes = *((INTERNET_ASYNC_RESULT *)lpStatusInfo); - SetEvent(hIO->hRequestCompleteEvent); - break; - } -} -#endif \ No newline at end of file diff --git a/!NotAdopted/IMO2sProxy/src/imolib/skypetst.c b/!NotAdopted/IMO2sProxy/src/imolib/skypetst.c deleted file mode 100644 index 5c80533eaf..0000000000 --- a/!NotAdopted/IMO2sProxy/src/imolib/skypetst.c +++ /dev/null @@ -1,211 +0,0 @@ -/* Module: skypetst.c - Purpose: Very simple and straight forward testing application for Skype imo.im service - Author: leecher - Date: 30.08.2009 -*/ - -#include -#include -#include -#include -#include -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#else -#include -#include -#endif -#include "imo_skype.h" - -static IMOSKYPE *m_hInst = NULL; - -// ----------------------------------------------------------------------------- -// Static -// ----------------------------------------------------------------------------- -static int StatusCallback (cJSON *pMsg, void *pUser) -{ - char *pszName; - cJSON *pContent = cJSON_GetArrayItem(pMsg, 0); - - if (!pContent) return; - pszName = cJSON_GetObjectItem(pContent,"name")->valuestring; - - if (!strcmp(pszName, "recv_im")) - { - // I got a message! - cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"); - - if (pEdata) - { - time_t timestamp = (time_t)cJSON_GetObjectItem(pEdata, "timestamp")->valueint; - char szTimestamp[32]; - - strftime (szTimestamp, sizeof(szTimestamp), "%d.%m.%Y %H.%M.%S", localtime(×tamp)); - printf ("[%s] %s: %s\n", szTimestamp, - cJSON_GetObjectItem(pEdata, "alias")->valuestring, - cJSON_GetObjectItem(pEdata, "msg")->valuestring); - } - } - else if (!strcmp(pszName, "signed_on")) - { - // I just signed on. - cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"); - char *pszAlias; - - if (pEdata && (pszAlias = cJSON_GetObjectItem(pEdata, "alias")->valuestring)) - { - printf ("My alias is: %s\n", pszAlias); - } - } - else if (!strcmp(pszName, "buddy_added") || !strcmp(pszName, "buddy_status")) - { - // Here comes the contact list - cJSON *pArray = cJSON_GetObjectItem(pContent,"edata"), *pItem; - int i, iCount; - - if (pArray) - { - for (i=0, iCount = cJSON_GetArraySize(pArray); ivaluestring, - cJSON_GetObjectItem(pItem, "buid")->valuestring, - cJSON_GetObjectItem(pItem, "primitive")->valuestring); - } - } - } - } - else - { - char *pszMsg = cJSON_Print(pMsg); - fprintf (stderr, "%s\n\n", pszMsg); - free (pszMsg); - } - - return 0; -} - -// ----------------------------------------------------------------------------- - -static void DispatcherThread(void *pDummy) -{ - while (1) - ImoSkype_Poll(m_hInst); -} - -// ----------------------------------------------------------------------------- - -#ifdef WIN32 -static HANDLE m_hThread; - -static int Dispatcher_Start(void) -{ - DWORD ThreadID; - - return (m_hThread=CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE)DispatcherThread, NULL, 0, &ThreadID))!=0; - -} - -static int Dispatcher_Stop(void) -{ - return TerminateThread (m_hThread, 0); -} - -#else -static pthread_t m_hThread; - -static int Dispatcher_Start(void) -{ - return pthread_create(&m_hThread, NULL, DispatcherThread, NULL)==0; -} - -static int Dispatcher_Stop(void) -{ - if (pthread_cancel(m_hThread)) - { - m_hThread=0; - return 1; - } - return 0; -} -#endif - -// ----------------------------------------------------------------------------- -// EIP -// ----------------------------------------------------------------------------- - -int main(int argc, char **argv) -{ - int iRet = -1; - - if (argc<3) - { - printf ("Usage: %s [username] [password]\n", argv[0]); - return -1; - } - - /* Logon */ - if (!(m_hInst = ImoSkype_Init(StatusCallback, NULL))) - { - fprintf (stderr, "Initializing failed.\n"); - return -1; - } - if (ImoSkype_Login(m_hInst, argv[1], argv[2]) == 1) - { - /* Dispatch loop */ - char szLine[4096]={0}; - - Dispatcher_Start(); - printf ("> "); - fflush(stdout); - while (gets(szLine)) - { - if (strcmp(szLine, "exit") == 0) break; - if (strcmp(szLine, "help") == 0) - { - printf ("msg [buddy] [message]\nstatus [available|away|busy|invisible] \nexit\n"); - } else - if (strncmp(szLine, "msg ", 4) == 0) - { - char *pszBuddy; - - if (pszBuddy = strtok (szLine+4, " ")) - { - if (ImoSkype_SendMessage(m_hInst, pszBuddy, pszBuddy+strlen(pszBuddy)+1)) - printf ("Sent.\n"); - else - printf ("Sending failed: %s.\n", ImoSkype_GetLastError(m_hInst)); - } - } else - if (strncmp(szLine, "status ", 7) == 0) - { - char *pszStatus; - - if (pszStatus = strtok (szLine+7, " ")) - { - if (ImoSkype_SetStatus(m_hInst, pszStatus, pszStatus+strlen(pszStatus)+1)) - printf ("Status set.\n"); - else - printf ("Setting status failed: %s.\n", ImoSkype_GetLastError(m_hInst)); - } - } - memset (szLine, 0, sizeof(szLine)); - printf ("> "); - fflush(stdout); - } - Dispatcher_Stop(); - ImoSkype_Logout(m_hInst); - } - else - { - fprintf (stderr, "Login failed: %s\n", ImoSkype_GetLastError(m_hInst)); - return -1; - } - - ImoSkype_Exit(m_hInst); - return iRet; -} diff --git a/!NotAdopted/IMO2sProxy/structure.txt b/!NotAdopted/IMO2sProxy/structure.txt deleted file mode 100644 index 37de021e3a..0000000000 --- a/!NotAdopted/IMO2sProxy/structure.txt +++ /dev/null @@ -1,102 +0,0 @@ -The communication module is divided into multiple layers that -are replacable or usable on their own. -First let's start with a list of files and a short description: - -+----------------+---+-------------------------------------------------------+ -| Module | T | Description | -+----------------+---+-------------------------------------------------------+ -| fifo.c | M | A simple fifo (First In, First Out) buffer | -| memlist.c | M | A simple memory list module | -| io_layer.c | M | Communication layer for HTTP requests | -| io_layer_win32.| M | Communication layer WIN32 | -| imo_request.c | M | Posts XMLHHTP-Requests to imo.im server | -| cJSON.c | M | JSON parser in C (by Dave Gamble, slightly modified | -| imo_skype.c | M | Communication layer for imo.im Skype | -| skypetst.c | X | Testing application for Skype imo.im service | -| queue.c | M | General Queue functions | -| msgqueue.c | M | Message queue for incoming messages | -| callqueue.c | M | Queue of incoming calls | -| buddylist.c | M | Manages your list of buddies in memory | -| imo2skypeapi.c | M | Wrapper for imo.im Webservice to SKYPE API | -| imo2stest.c | X | Simple test application for imo2skypeapi | -| imo2sproxy.c | M | Skypeproxy implementation to wrap imo2skypeapi | -| w32browser.c | M | C COM Interface to Internet Explorer for call supp. | -| main.c | X | Commandline interface for imo2sproxy module | -| imoproxy.c | X | Miranda plugin implementation for imo2sproxy | -| skypepluginlink| M | Communication layer with Miranda Skype Plugin 0.0.0.46| -| socksproxy.c | M | Communication layer with socket protocol. | -| w32skypeemu.c | M | Communication layer via Win32 Skype API emulation | -+----------------+---+-------------------------------------------------------+ - [T]ype is: M...Module, X...Executable (Application) - - -Now here is the module list with their dependencies divided into layers: - -==================================================================== - IMO.IM Communication layer -==================================================================== - -+------------------------------------------------------------------+ -| io_layer.c | -+------------------------------------------------------------------+ -| Communication layer for HTTP requests | -| Depends on: fifo.c, Win32:WinInet, linux:libCURL | -+------------------------------------------------------------------+ - || - || - \/ -+------------------------------------------------------------------+ -| imo_request.c | -+------------------------------------------------------------------+ -| Communication module with imo.im | -| Depends on: fifo.c, cJSON.c, io_layer.c | -+------------------------------------------------------------------+ - || - || - \/ -+------------------------------------------------------------------+ -| imo_skype.c | -+------------------------------------------------------------------+ -| Description: Skype protocol layer for imo.im | -| Depends on: imo_request.c, cJSON.c | -| Test application: skypetst.c | -+------------------------------------------------------------------+ - || -==================================================================== - imo.im <--> SkypeAPI wrapper -==================================================================== - || - \/ -+------------------------------------------------------------------+ -| imo2skypeapi.c | -+------------------------------------------------------------------+ -| Description: Mapper for imo.im to simple implementation of | -| SkypeAPI | -| Depends on: fifo.c, memlist.c, buddylist.c, msgqueue.c, | -| imo_skype.c, (w32browser.c),(libpthread) | -| Test application: imo2stest.c | -+------------------------------------------------------------------+ - || - || - \/ -+------------------------------------------------------------------+ -| imo2sproxy.c | -+------------------------------------------------------------------+ -| Description: Skypeproxy implementation to wrap imo2skypeapi| -| for Miranda Plugin and potentially others | -| Depends on: memlist.c, imo2skypeapi.c, (libpthread) | -+------------------------------------------------------------------+ - || || - || || - \/ \/ -+-----------------------------------------++-----------------------------------------+ -| main.c || imoproxy.c | -+-----------------------------------------++-----------------------------------------+ -| Description: Commandline dispatcher || Description: Miranda IM Plugin | -| Depends on: memlist.c, imo2skypeapi.c, || Depends on: memlist.c, imo2skypeapi.c, | -| imo2sproxy.c, (libpthread) || imo2sproxy.c, (libpthread) | -+-----------------------------------------++-----------------------------------------+ - | | | - +-------------------+ | - | | | -Communication layer: socksproxy.c w32skypeemu.c skypepluginlink.c diff --git a/!NotAdopted/NotesAndReminders/NotesReminders.vcxproj b/!NotAdopted/NotesAndReminders/NotesReminders.vcxproj deleted file mode 100644 index d77a0f481c..0000000000 --- a/!NotAdopted/NotesAndReminders/NotesReminders.vcxproj +++ /dev/null @@ -1,121 +0,0 @@ -п»ї - - - - Debug - Win32 - - - Release - Win32 - - - - {EEB57129-946C-4B98-8856-FDA501AE2A5E} - NotesReminders - - - - DynamicLibrary - MultiByte - true - - - DynamicLibrary - MultiByte - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - $(SolutionDir)$(Configuration)\Plugins\ - $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ - $(SolutionDir)$(Configuration)\Plugins\ - $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ - true - - - - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Level3 - ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) - EditAndContinue - Use - globals.h - EnableFastChecks - - - _DEBUG;%(PreprocessorDefinitions) - ..\..\include\msapi - - - comctl32.lib;Gdi32.lib;winmm.lib;wsock32.lib;%(AdditionalDependencies) - true - 0x14310000 - false - $(IntDir)$(TargetName).lib - Windows - $(SolutionDir)\lib - - - - - Full - OnlyExplicitInline - Size - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - true - Level3 - ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) - Use - global.h - - - NDEBUG;%(PreprocessorDefinitions) - ..\..\include\msapi - - - Gdi32.lib;comctl32.lib;winmm.lib;wsock32.lib;%(AdditionalDependencies) - true - 0x14310000 - false - $(IntDir)$(TargetName).lib - true - Windows - $(SolutionDir)\lib - true - - - - - - Create - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/!NotAdopted/NotesAndReminders/NotesReminders.vcxproj.filters b/!NotAdopted/NotesAndReminders/NotesReminders.vcxproj.filters deleted file mode 100644 index 5eccb5444e..0000000000 --- a/!NotAdopted/NotesAndReminders/NotesReminders.vcxproj.filters +++ /dev/null @@ -1,53 +0,0 @@ -п»ї - - - - {0542c19a-ad49-4dd8-8643-47204fa16e58} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {1e7a703d-e0f4-42ff-9e78-49de3375d4a5} - h;hpp;hxx;hm;inl - - - {38ee8469-7af5-4130-90a1-f4e8c620f475} - ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - - - Resource Files - - - \ No newline at end of file diff --git a/!NotAdopted/NotesAndReminders/docs/N&R - langpack.txt b/!NotAdopted/NotesAndReminders/docs/N&R - langpack.txt deleted file mode 100644 index ebb446c99b..0000000000 --- a/!NotAdopted/NotesAndReminders/docs/N&R - langpack.txt +++ /dev/null @@ -1,169 +0,0 @@ -Miranda Language Pack Version 1 -Language: English (EN) -Locale: 0409 -Last-Modified-Using: Miranda 0.9.2 -Authors: d00mEr, Joe @ Whale, Georg Fischer -Author-email: d00mEr@dir.bg, jokusoftware@gmail.com -Plugins-included: Notes & Reminders 0.0.5.0 - -[&Close] - -;Name In Options Page -;-------------------- -[Notes & Reminders] -[Plugins] -[Alerts] -[Reminder Notify] - -;Menu Strings -;------------ -[Notes && Reminders] -[&New Note] -[&Show / Hide Notes] -[Vie&w Notes] -[Delete &All Notes] -[New &Reminder] -[&View Reminders] -[D&elete All Reminders] -[&Bring All to Front] - -;Hotkeys -;------- -[Bring All Notes to Front] -[Toggle Notes Visibility] - -;Sounds -;------ -[Reminder triggered] -[Reminder triggered (Alternative 1)] -[Reminder triggered (Alternative 2)] - -;Confirmation and Message Dialogs ---------------------------------- -[Are you sure you want to delete all notes?] -[Are you sure you want to delete this note?] -[Are you sure you want to delete all reminders?] -[Are you sure you want to delete this reminder?] -[The specified time is invalid.] -[The specified time offset is invalid.] -[The specified time is invalid due to begin of daylight saving (summer time).] -[Miranda could not load the Note & Reminders plugin, RICHED20.DLL is missing. If you are using Windows 95 or WINE please make sure you have riched20.dll installed. Press 'Yes' to continue loading Miranda.] - -;Note Window Popup Menu -;---------------------- -[&Delete Note] -[&Hide Note] -[&Always On Top] -[Appearance] -[Background Color] -[Text Color] -[Font] -[Custom...] -[Reset] -[Paste Title] -[Reset Title] -[Undo] -[&Copy] -[&Paste] -[C&ut] -[C&lear] - -;Note Window Popup Menu Color Presets -------------------------------------- -[Black] -[Maroon] -[Green] -[Olive] -[Navy] -[Purple] -[Teal] -[Gray] -[Silver] -[Red] -[Orange] -[Lime] -[Yellow] -[Blue] -[Fuchsia] -[Aqua] -[White] - -;Notes List Dialog and Popup Menu -;----------------------------------- -[Notes] -[Date/Title] -[Note text] -[V] -[T] -[Edi&t Note] -[&Visible] -[Always &On Top] - -;New Reminder Dialog -;------------------- -[&Add Reminder] -[&Update Reminder] -[Add Reminder] -[Trigger On Time && Date:] -[Date] -[Time] -[Reminder Note:] -[Reoccurence] -[None] -[Daily] -[Weekly] -[Monthly] -[Minutes] -[Hours] -[Every] -[Seconds] -[Default] -[Alternative 1] -[Alternative 2] -[Never] -[None] - -;Reminder List Dialog and Popup Menu -;----------------------------------- -[Reminders] -[Date of activation] -[Reminder text] -[Add New] -[Edi&t Reminder] -[&Delete Reminder] - -;Reminder Notify Dialog -;---------------------- -[&Dismiss] -[&Remind Again] -[Reminder] -[min.] -[After:] -[On Time && Date:] -[Hour] -[Day] -[Days] -[Week] - -;Options Dialog -;-------------- -[Note Transparency (Minimum Win 2k/XP)] -[Default Note Size] -[Width (Pixels)] -[Height (Pixels)] -[Startup options] -[Reset to defaults] -[Hide notes at startup] -[Add Contact list menu items] -[(Requires Miranda restart)] -[Send Reminders through E-mail / SMS :] -[Open links with this program instead:] -[Select Executable] -[Show Scrollbar] -[Show Buttons] -[Title Date] -[Title Time] -[Reminder Options] -[Add Reminder closes dialog] -[Use MCI to play alert sounds] -[(Using MCI allows different sounds to be played simultaneously, may not be needed or desired when a custom sound plugin is installed.)] diff --git a/!NotAdopted/NotesAndReminders/docs/N&R - readme.txt b/!NotAdopted/NotesAndReminders/docs/N&R - readme.txt deleted file mode 100644 index 30ced4b8f1..0000000000 --- a/!NotAdopted/NotesAndReminders/docs/N&R - readme.txt +++ /dev/null @@ -1,315 +0,0 @@ -About ------ -New "Notes & Reminders" Plugin - -Version 0.0.5.0 -Updated by Georg Fischer for Miranda IM 0.9.2+ (may work on earlier versions -possibly down to 0.7.0 but not tested) and VS2008, based on code: - -by Joe @ Whale (Joe Kucera) jokusoftware@gmail.com -Originally by d00mEr (Lubomir Ivanov) d00mEr@dir.bg -for Miranda ICQ 0.1.2.1+ written with Visual C++ 6.0 IMPORTANT: When upgrading to 0.0.5.0 (from 0.0.4.5-), it's recommended to make a backup of the Miranda DB file, because the format for notes and reminder DB data has changed. Allthough the new version should be able to read the old format, the old plugin version will not be able to read the new format, in case you need to downgrade plugin version again. -Description ------------ -This plugin allows user to create Sticky Notes, to -store some important data in a well visible place :) -New features allow to create reminders. This is a -note that will show up on specified date and time. -The notes are completely customizable. - -Features --------- -+ Sticky Notes (each Note is limited to 16000 chars) -+ Reminders (each Reminder Text is limited to 16000 chars) -+ Reminder time input displays a preset list with times. For the current date (if date is not - changed) it displays presets for 5, 10, 15, 30 minutes and then every full and half hour. When - the time input is in current date mode, you can also enter a delta time by first entering a +. - For example +5 would specify in 5 minutes, +1:15 would specify in 1 hour and 15 minutes. -+ Allow change of fonts and colors -+ Allow setting default size for Notes -+ Notes always stay on top of all windows (unless option is disabled) -+ Show and Hide all notes -+ Show or Hide notes at startup. -+ Bring all notes to front (for notes that are not on top and are hidden behind other windows). -+ Hot Keys for New Note, New Reminder, Show/Hide notes and Bring All Notes to Front -+ Manage Reminder list. -+ Manage Notes list. -+ Quick delete all notes and/or reminders -+ Transparent Notes (on Windows 2000 or newer) -+ Language translations (see langpack_N&R.txt for details) -+ Select between 3 custom sounds to play On Reminder -+ Reminder alert sound can optionally play repeatedly at specified interval until user responds - to alert (makes it less likely to miss important reminders) -+ Font Colors -+ Reminder notification via E-mail or SMS. - -To Do: ------- -- Verify langpack for changes and new features introduced in 0.0.5.0 -- User configurable icons through the Miranda icon configuration functionality -- Icons for : Fix/Move the note -- Text formatting support for notes -- "best fit" feature - by pressing one button I would adjust the size of the note automatically -- double clicking a note's title-bar scrolls up the note (to be just the title bar). -- import/export of all notes/alarms -- Reminder (daily, weekly or monthly) without a specified time? i.e. when you start miranda... -- Trigger on event (remind me when is user online) -- Unicode support (Use Japanese texts was garbled) -- Easier way to delete notes (like Ctrl-D or ctrl-shift-d) - -Installation ------------- -Just copy the dll into Miranda's plugin subdirectory. - -Translation ------------ -see N&R-langpack.txt for details - -License -------- -Copyright (C) 2002 Lubomir Ivanov -Copyright (C) 2005 Joe Kucera - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. - -For more information, e-mail jokusoftware@gmail.com - d00mEr@dir.bg - -Changes -------- -0.0.5.1 -------- -! BugFix: Notes window init issue that could result in scrollbar being shown when it shouldn't. -! BugFix: Notes window init issue that could result in scrollbar position not being restored correctly - for notes that are suposed to be scrolled to top -+ Feature: Option to specify a custom program to use when opening links in notes. By default links - are opened using the system default web browser. -+ Feature: Set custom font on individual notes. - -------- -0.0.5.0 -------- -* (Temporary) Developer: Georg Fischer, I just updated it to work properly with the latest Miranda - version and added some features and polish. I don't know if I'll do much more work aside from immediate - bug fixes, at least on any regular basis. -! BugFix: Custom frame drawing for notes to look nicer but also avoid issues especially with Aero. -! BugFix: Changed window type/parent for notes so that they don't show up on Windows alt-tab list - and other issues. -! BugFix: Cleaned up custom window drawing for notes windows, to hopefully work more solidly. -! BugFix: Fixed pasting into notes window, so it doesn't paste text formatting (as formatting - is not currently supported and would be lost next time Miranda starts). -! BugFix: Removed reminder reoccurrence dialog options, it would just confuse the user because - there is no support for that functionality in the code. -! BugFix: Time handling reworked, which hopefully also fixes reported issue with reminders triggering at - wrong time (an hour early or later). Special handling for daylight saving (summer time) begin - and end was also added, which in some cases could lead to some issues on old Windows versions - which have outdated being and end dates/times. -! BugFix: Potential crash bug with reminder list window and empty reminder note. -! BugFix: Transparency slider (in options) now uses correct direction, previously 100% transparent was - actually 100% Opaque. Also clamped the internal max value to avoid 100% transparent windows. -! BugFix: Creating note from a reminder could result in a crash or corrupted data if note was deleted - before the reminder. -! BugFix: A few other unlisted bug/issue fixes. -+ Change: Changed DB format to be more flexible and easily allow adding features in the future without - breaking existing notes and reminders. -+ Change: Changed "Show notes at startup" to "Hide notes at startup" because that better matches - actual behavior. -+ Change: Changed the default menu item order to have New Note and New Reminder first as they're the - most commonly used commands. -+ Optimization: changed list iterations in various placed to directly iterate linked lists instead - of using index based for-loops. -+ Optimization: reminder list sorted by trigger time, which reduces update function to a single - check 99.99+% of the time. -+ Feature: Hotkeys, fonts and colors now configurable through the common config interface. -+ Feature: Notes save/restore their current scroll position. -+ Feature: Notes title bar is configurable to select prefered date and time formats or disable them. -+ Feature: Buttons in notes title bar can be disabled (all functions are also available in the context menu). -+ Feature: Bring All Notes to Front command, brings all visible notes in front of other windows - (without changing the on-top state). -+ Feature: Tweaked notes window context menu and added a couple of commands. -+ Feature: Option to make "Add Reminder" button in New Reminder dialog close the dialog (previously - it was required to click Close after Add Reminder to get rid of the dialog). -+ Feature: Reminder alerts now generate a Miranda system event, meaning it will blink the tray icon - which the user has to click in order to open the reminder dialog. Previously the reminder - dialog opened automatically which could interfere with the application currently being used. -+ Feature: Delete confirmation dialogs for all notes and reminder delete actions, to avoid accidental - deletion. -+ Feature: Reworked reminder date and time input controls. In particularily the time edit control works - more like it did in ICQ aswell as allowing user to enter custom values. -+ Feature: Per-reminder option to have alert sound repeat (until reminder event is acknowledged by - clicking the tray icon). Repeat interval can be selected between 5 and 60 seconds. -+ Feature: Set custom background and text color on individual notes. -+ Feature: Set custom title/caption on individual notes. (max 63 characters) -+ Feature: Select between 3 sound presets or disable sound completely for individual reminders. -+ Feature: Edit/Update reminders. -+ Feature: Update reminder message in reminder notify dialog, so that the text can be updated - before chosing to remind again. -+ Feature: Notes list dialog. -+ Feature: Notes/Reminders list dialogs resizable with persistent window and column sizes. - -------- -0.0.4.5 -------- -* New Developer: Joe @ Whale, jokusoftware@gmail.com, I took over the development - of this great plug-in, got sources of 0.0.4.0 from original author (newer were - lost), hopfully managed to add features of succeeding versions. -! BugFix: Hopefully fixed all crash issues & memory leaks -! BugFix: Fixed random reminder issue -+ Optimisation: minimised use of memory alloc/free (much faster loading) -+ Feature: reminder sound now configurable thru default Skin/Sounds module (EVents/Sounds) - -------- -0.0.4.2 -------- -! BugFix: Reminder -> SMS Notify now works. -+ Option: Show vertical scrollbar in Notes. -+ Feature: Create Note from content of Reminder Notify. -+ Feature: Icons for Delete Note, Hide Note - -------- -0.0.4.1 -------- -! BugFix: URL in Note problem fixed -! Bugfix: Closing Reminder dialog will now mean "Remind me again" - You must press "Dismiss" to remove reminder -! BugFix: Strange behaviour to add reminders + 1 hour.. (Now uses Localtime) -! BugFix: Missing Langpack strings - -------- -0.0.4.0 -------- -+ Totaly revriten everything!!! Moved to Microsoft (R) Visual C ++ 6.0 -+ Added TopToolbar buttons for "New Reminder" and "New Note" -+ Notify via SMS to E-mail gateway (Only for Reminders) - -------- -0.0.3.1 -------- -+ Sorry, i've forgot to remove debug :( That's why the plugin crashes - Now i've removed it :) Also i've relocated plugin to new base addres, so - there must not be a crash on start or exit (btw if you use any other - Delphi plugins, please contact autor to relocate them to a different - base addres than standart $4000000, or there will be a crash !! - -0.0.3.0 -------- -+ Reocurrence of Reminders (Daily, Weekly, Monthly) -+ Fixed bug with crash :( - -0.0.2.8 -------- -+ Changed DB structure again (fixed bug with Notes & Reminders size greater - than 4096 bytes). Now every Note & Reminder are stored into separate DB - setting, but every Note or Reminder is still limited to 4000 bytes :( sorry - for that. It is recomended you to clear all notes & Reminders to avoid errors :) -+ Implemented Purge function to free unused Notes & Reminders data from DB :) -+ Removed 'Empty' sign when a Note or Reminder have no text :) -+ Is the "Reminder On Top" bug still there? It works fine for me ?!? :) - (I've tested on Win ME, 2K Pro & XP) - -0.0.2.7 -------- -+ Fixed bug with Reminders not showing on top of all windows - -0.0.2.6 -------- -+ "Remind me again in:" now includes any date and(or) time in the future, - not just (5,10,15...etc min.). -+ Changed Name in Options dialog. - -0.0.2.5 -------- -+ Togle On-Top with the pin icon (Icon reflects status) -+ Change Font effects & colors (For Caption & Note body) -+ A "View Reminders" button in the "Add Reminder" box. -+ Rearanged TAB order :) - -0.0.2.4 -------- -+ Custom Sound to play On Reminder - -0.0.2.3 -------- -[Warning!!! New Format of DB data! Incompatible with old versions] -[It is recomended to delete all Notes and Reminders ] - -+ Fixed bug - not showing corectly "Remind Again In :" Combo Box -+ Fixed bug - Trying to delete from empty list of reminders causes - error message. -+ Fixed bug - Problem when using Unicode characters -+ Other minor bug (or not bug) fixes :) - -0.0.2.2 -------- -+ Switched to Delphi 6 (smaller code) -+ There where so many feature requests for language translations :) - So i decided to implement this feature :) -+ I think finally fixed the on-top bug ?!? - -0.0.2.1 -------- -+ Fixed bug on 9X platforms (Didn't draw notes correct) :) Sorry, i forgot - to initialize length of an structure :) -+ Changed Name :) -+ Added transparency of Notes (Win 2K & XP) - -0.0.2.0 -------- -+ Reminder function implemented :) -+ Changed version to 2.0 :) - -0.0.1.6 -------- -+ Fixed structure in DB to store new features (Visible,On Top). - (Now DB Settings of plugin are incompatible with old versions, - so if you update , you will loose all notes). -+ Added Popup menu items for new features (Visible, On Top). -+ Minor changes in code to improve preformance. Smaller code :) - -0.0.1.5 -------- -+ Replaced Hot Keys with global Hot Keys. -+ Added option to change these Hot Keys. -+ Added Popup menu to Notes (Cut,Copy,Paste). -+ Added option to set default size of notes on create new. -+ Basic Implementation of reminders. - -0.0.1.4 -------- -+ Now saving Notes data on every change to avoid loosing notes if crash. -+ Fixed some bugs with window placement. -+ Added options for staying Always On Top. -+ Added Hot Keys to menu. - -0.0.1.3 -------- -+ Fixed bug with notes that have no text. -+ Added functions to Show/Hide Notes. -+ Added some icons :) - -0.0.1.2 -------- -+ Added Options dialog, to alow change of color and fonts for notes. - -0.0.1.1 -------- -+ Changed to save Notes data into Miranda database insted - of Windows registry. - -0.0.1.0 -------- -+ First release of this plugin. \ No newline at end of file diff --git a/!NotAdopted/NotesAndReminders/res/addremin.ico b/!NotAdopted/NotesAndReminders/res/addremin.ico deleted file mode 100644 index 0264fd1716..0000000000 Binary files a/!NotAdopted/NotesAndReminders/res/addremin.ico and /dev/null differ diff --git a/!NotAdopted/NotesAndReminders/res/bringfront.ico b/!NotAdopted/NotesAndReminders/res/bringfront.ico deleted file mode 100644 index 11984568a8..0000000000 Binary files a/!NotAdopted/NotesAndReminders/res/bringfront.ico and /dev/null differ diff --git a/!NotAdopted/NotesAndReminders/res/captioni.ico b/!NotAdopted/NotesAndReminders/res/captioni.ico deleted file mode 100644 index c7543c075f..0000000000 Binary files a/!NotAdopted/NotesAndReminders/res/captioni.ico and /dev/null differ diff --git a/!NotAdopted/NotesAndReminders/res/captionn.ico b/!NotAdopted/NotesAndReminders/res/captionn.ico deleted file mode 100644 index fd925f0660..0000000000 Binary files a/!NotAdopted/NotesAndReminders/res/captionn.ico and /dev/null differ diff --git a/!NotAdopted/NotesAndReminders/res/deleteic.ico b/!NotAdopted/NotesAndReminders/res/deleteic.ico deleted file mode 100644 index 5aa90434c1..0000000000 Binary files a/!NotAdopted/NotesAndReminders/res/deleteic.ico and /dev/null differ diff --git a/!NotAdopted/NotesAndReminders/res/deletere.ico b/!NotAdopted/NotesAndReminders/res/deletere.ico deleted file mode 100644 index 8560fc8f5e..0000000000 Binary files a/!NotAdopted/NotesAndReminders/res/deletere.ico and /dev/null differ diff --git a/!NotAdopted/NotesAndReminders/res/hidenote.ico b/!NotAdopted/NotesAndReminders/res/hidenote.ico deleted file mode 100644 index bada524874..0000000000 Binary files a/!NotAdopted/NotesAndReminders/res/hidenote.ico and /dev/null differ diff --git a/!NotAdopted/NotesAndReminders/res/noteicon.ico b/!NotAdopted/NotesAndReminders/res/noteicon.ico deleted file mode 100644 index 5479ed29e7..0000000000 Binary files a/!NotAdopted/NotesAndReminders/res/noteicon.ico and /dev/null differ diff --git a/!NotAdopted/NotesAndReminders/res/playsound.ico b/!NotAdopted/NotesAndReminders/res/playsound.ico deleted file mode 100644 index 0e3711dbc5..0000000000 Binary files a/!NotAdopted/NotesAndReminders/res/playsound.ico and /dev/null differ diff --git a/!NotAdopted/NotesAndReminders/res/reminder.ico b/!NotAdopted/NotesAndReminders/res/reminder.ico deleted file mode 100644 index d3bed91d4d..0000000000 Binary files a/!NotAdopted/NotesAndReminders/res/reminder.ico and /dev/null differ diff --git a/!NotAdopted/NotesAndReminders/res/removeno.ico b/!NotAdopted/NotesAndReminders/res/removeno.ico deleted file mode 100644 index d2aae887a6..0000000000 Binary files a/!NotAdopted/NotesAndReminders/res/removeno.ico and /dev/null differ diff --git a/!NotAdopted/NotesAndReminders/res/resource.rc b/!NotAdopted/NotesAndReminders/res/resource.rc deleted file mode 100644 index 064efb6453..0000000000 --- a/!NotAdopted/NotesAndReminders/res/resource.rc +++ /dev/null @@ -1,362 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "..\src\resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Neutral resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) -#ifdef _WIN32 -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "..\\src\\resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,5,1 - PRODUCTVERSION 0,0,5,1 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000004b0" - BEGIN - VALUE "Comments", "New ""Notes And Reminders"" plugin for Miranda IM" - VALUE "CompanyName", "Jokusoftware, Digital Forcess" - VALUE "FileDescription", "New ""Notes And Reminders""" - VALUE "FileVersion", "0.0.5.1" - VALUE "InternalName", "NewNotesAndReminders" - VALUE "LegalCopyright", "(C) 2003,2005 by Joe Kucera, Lubomir Ivanov" - VALUE "LegalTrademarks", "Digital Forcess" - VALUE "OriginalFilename", "NewNR.dll" - VALUE "ProductName", "New ""Notes And Reminders""" - VALUE "ProductVersion", "0.0.5.1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0, 1200 - END -END - -#endif // Neutral resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_STNOTEOPTIONS DIALOGEX 47, 55, 301, 254 -STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE | WS_CAPTION -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Sticky Notes Options" -FONT 8, "MS Sans Serif", 0, 0, 0x1 -BEGIN - GROUPBOX "Default Note Size",IDC_STATIC,5,6,159,51 - LTEXT "Width (Pixels)",IDC_STATIC,12,20,44,8 - EDITTEXT 1012,70,20,62,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "Height (Pixels)",IDC_STATIC,12,41,46,8 - EDITTEXT 1013,70,39,62,12,ES_AUTOHSCROLL | ES_NUMBER - GROUPBOX "Notes Appearance",IDC_STATIC,5,61,159,72 - CONTROL "Show Scrollbars",1018,"Button",BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,12,77,67,10 - CONTROL "Show Buttons",1019,"Button",BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,88,77,64,10 - LTEXT "Title Date",IDC_STATIC,12,96,32,8 - COMBOBOX IDC_COMBODATE,53,95,92,149,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Title Time",IDC_STATIC,12,115,32,8 - COMBOBOX IDC_COMBOTIME,53,114,92,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Startup options",IDC_STATIC,179,6,116,56 - CONTROL "Hide notes at startup",1010,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | BS_FLAT | WS_TABSTOP,185,17,82,16 - CONTROL "Add Contact list menu items",1011,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | BS_FLAT | WS_TABSTOP,185,35,103,10 - CTEXT "(Requires Miranda restart)",IDC_STATIC,196,50,84,10 - GROUPBOX "Reminder options",IDC_STATIC,179,66,116,90 - CONTROL "Add Reminder closes dialog",1020,"Button",BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,185,81,103,10 - CONTROL "Use MCI to play alert sounds",1023,"Button",BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,185,96,106,10 - GROUPBOX "Note Transparency (Minimum Win 2k/XP)",IDC_STATIC,6,161,290,35 - CONTROL "Slider1",1014,"msctls_trackbar32",TBS_ENABLESELRANGE | WS_TABSTOP,8,171,283,14 - LTEXT "0%",IDC_STATIC,12,185,9,8 - LTEXT "100%",IDC_STATIC,276,186,18,8 - LTEXT "Send Reminders through E-mail / SMS :",IDC_STATIC,6,207,130,10 - EDITTEXT 1017,137,204,158,14,ES_AUTOHSCROLL - LTEXT "Open links with this program instead:",IDC_STATIC,5,228,125,8 - EDITTEXT IDC_EDIT_ALTBROWSER,138,225,140,14,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_BTN_BROWSEBROWSER,280,225,15,15 - PUSHBUTTON "Reset to defaults",1007,32,140,94,14 - CTEXT "(Using MCI allows different sounds to be played simultaneously, may not be needed or desired when a custom sound plugin is installed.)",IDC_STATIC,181,111,111,42 -END - -IDD_ADDREMINDER DIALOGEX 0, 0, 238, 199 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Add Reminder" -FONT 8, "MS Sans Serif", 0, 0, 0x1 -BEGIN - GROUPBOX "Trigger On Time && Date:",1005,4,2,146,52 - LTEXT "Date",IDC_STATIC,10,18,24,8 - CONTROL "DateTimePicker1",1000,"SysDateTimePick32",DTS_LONGDATEFORMAT | WS_TABSTOP,38,16,107,13 - LTEXT "Time",IDC_STATIC,10,37,25,8 - COMBOBOX IDC_COMBOREMINDERTIME,38,35,107,198,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Reminder Note:",1006,4,58,230,99 - EDITTEXT 1004,9,70,220,81,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL - GROUPBOX "",IDC_STATIC,4,157,228,22,NOT WS_VISIBLE - CONTROL "None",1008,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_TABSTOP,13,167,45,8 - CONTROL "Daily",1009,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_TABSTOP,68,167,45,8 - CONTROL "Weekly",1010,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_TABSTOP,124,167,45,8 - CONTROL "Monthly",1011,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_TABSTOP,178,167,45,8 - LTEXT "Repeat Alert Sound",IDC_STATIC,31,166,90,8,0,WS_EX_RIGHT - COMBOBOX IDC_COMBO_REPEATSND,126,163,107,81,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Use Sound",IDC_STATIC,31,185,90,8,0,WS_EX_RIGHT - COMBOBOX IDC_COMBO_SOUND,126,182,90,81,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "",IDC_BTN_PLAYSOUND,220,183,13,12,BS_ICON - DEFPUSHBUTTON "&Add Reminder",1002,158,6,76,14 - PUSHBUTTON "&Close",1003,158,23,76,14 - PUSHBUTTON "&View Reminders",1007,158,40,76,14 - LTEXT "reftime",IDC_REFTIME,0,191,22,8,NOT WS_VISIBLE | NOT WS_GROUP -END - -IDD_NOTIFYREMINDER DIALOGEX 0, 0, 240, 146 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Reminder" -FONT 8, "MS Sans Serif", 0, 0, 0x1 -BEGIN - EDITTEXT 1000,3,4,233,80,ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL - CONTROL "After:",1004,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,11,90,32,10,WS_EX_TRANSPARENT - CONTROL "On Time && Date:",1005,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,51,90,65,10,WS_EX_TRANSPARENT - GROUPBOX "",-1,4,90,148,52 - COMBOBOX 1003,24,113,107,104,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - LTEXT "Date",IDC_STATIC_DATE,10,106,23,8 - CONTROL "DateTimePicker1",1006,"SysDateTimePick32",DTS_LONGDATEFORMAT | WS_TABSTOP,39,104,107,13 - LTEXT "Time",IDC_STATIC_TIME,10,125,24,8 - COMBOBOX 1007,39,123,107,198,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "&Remind Again",1002,161,92,75,14 - PUSHBUTTON "&Create Note",1008,161,111,75,14 - PUSHBUTTON "&Dismiss",1001,161,129,75,14 - LTEXT "reftime",IDC_REFTIME,0,137,22,8,NOT WS_VISIBLE | NOT WS_GROUP -END - -IDD_LISTREMINDERS DIALOGEX 0, 0, 258, 244 -STYLE DS_SETFONT | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Reminders" -FONT 8, "MS Sans Serif", 0, 0, 0x1 -BEGIN - CONTROL "List1",1000,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,3,4,251,146 - EDITTEXT 1001,3,153,251,69,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL - PUSHBUTTON "Add New",1002,151,227,50,14 - DEFPUSHBUTTON "&Close",1003,203,227,50,14 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_ADDREMINDER ICON "addremin.ico" -IDI_DELETEICON ICON "deleteic.ico" -IDI_NOTEICON ICON "noteicon.ico" -IDI_SHOWHIDE ICON "showhide.ico" -IDI_CAPTIONICON ICON "captioni.ico" -IDI_DELETEREMINDER ICON "deletere.ico" -IDI_VIEWREMINDERS ICON "viewremi.ico" -IDI_CAPTIONICONNOTTOP ICON "captionn.ico" -IDI_HIDENOTE ICON "hidenote.ico" -IDI_REMOVENOTE ICON "removeno.ico" -IDI_REMINDER ICON "reminder.ico" -IDI_BRINGFRONT ICON "bringfront.ico" -IDI_PLAYSOUND ICON "playsound.ico" -IDI_VIEWNOTES ICON "viewnotes.ico" - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -MNU_REMINDERPOPUP MENU -BEGIN - POPUP "Context Menu Reminder ListView" - BEGIN - MENUITEM "Edi&t Reminder", ID_CONTEXTMENUREMINDERLISTVIEW_EDIT - MENUITEM SEPARATOR - MENUITEM "New &Reminder", 40001 - MENUITEM "&Delete Reminder", 40002 - MENUITEM SEPARATOR - MENUITEM "D&elete All Reminders", 40003 - END -END - -MNU_NOTEPOPUP MENU -BEGIN - POPUP "Context Menu Note Popup" - BEGIN - MENUITEM "&Hide Note", 40002 - MENUITEM "&Always On Top", 40003 - MENUITEM "&New Note", ID_CONTEXTMENUNOTEPOPUP_NEWNOTE - MENUITEM "&Delete Note", 40001 - MENUITEM SEPARATOR - POPUP "Appearance" - BEGIN - POPUP "Background Color" - BEGIN - MENUITEM "Custom...", ID_APPEARANCE_CUSTOMBG - MENUITEM SEPARATOR - MENUITEM "Reset", ID_BACKGROUNDCOLOR_RESET - END - POPUP "Text Color" - BEGIN - MENUITEM "Custom...", ID_APPEARANCE_CUSTOMTEXT - MENUITEM SEPARATOR - MENUITEM "Reset", ID_TEXTCOLOR_RESET - END - POPUP "Font" - BEGIN - MENUITEM "Custom...", ID_APPEARANCE_CUSTOMFONT - MENUITEM SEPARATOR - MENUITEM "Reset", ID_FONT_RESET - END - END - MENUITEM "Paste Title", ID_CONTEXTMENUNOTEPOPUP_PASTETITLE - MENUITEM "Reset Title", ID_CONTEXTMENUNOTEPOPUP_RESETTITLE - MENUITEM SEPARATOR - MENUITEM "Undo", 40004 - MENUITEM SEPARATOR - MENUITEM "&Copy", 40005 - MENUITEM "&Paste", 40006 - MENUITEM "C&ut", 40007 - MENUITEM "C&lear", 40008 - MENUITEM SEPARATOR - MENUITEM "&View Notes", ID_CONTEXTMENUNOTEPOPUP_VIEWNOTES - MENUITEM "&Bring All To Front", ID_CONTEXTMENUNOTEPOPUP_BRINGALLTOTOP - END -END - -MNU_NOTELISTPOPUP MENU -BEGIN - POPUP "Context Menu Note ListView" - BEGIN - MENUITEM "Edi&t Note", ID_CONTEXTMENUNOTELISTVIEW_EDITNOTE - MENUITEM SEPARATOR - MENUITEM "&Visible", ID_CONTEXTMENUNOTELISTVIEW_TOGGLEVISIBILITY - MENUITEM "Always &On Top", 40003 - MENUITEM "&New Note", ID_CONTEXTMENUNOTEPOPUP_NEWNOTE - MENUITEM "&Delete Note", 40001 - MENUITEM SEPARATOR - MENUITEM "Delete &All Notes", ID_CONTEXTMENUNOTELISTVIEW_DELETEALLNOTES - MENUITEM SEPARATOR - MENUITEM "&Show / Hide Notes", ID_CONTEXTMENUNOTELISTVIEW_SHOW - MENUITEM "&Bring All To Front", ID_CONTEXTMENUNOTEPOPUP_BRINGALLTOTOP - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - "IDD_STNOTEOPTIONS", DIALOG - BEGIN - VERTGUIDE, 5 - VERTGUIDE, 12 - VERTGUIDE, 70 - VERTGUIDE, 88 - VERTGUIDE, 179 - VERTGUIDE, 185 - VERTGUIDE, 295 - BOTTOMMARGIN, 249 - HORZGUIDE, 6 - HORZGUIDE, 20 - END - - "IDD_ADDREMINDER", DIALOG - BEGIN - VERTGUIDE, 4 - END - - "IDD_NOTIFYREMINDER", DIALOG - BEGIN - VERTGUIDE, 161 - VERTGUIDE, 236 - END -END -#endif // APSTUDIO_INVOKED - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/!NotAdopted/NotesAndReminders/res/showhide.ico b/!NotAdopted/NotesAndReminders/res/showhide.ico deleted file mode 100644 index 99b241d4fb..0000000000 Binary files a/!NotAdopted/NotesAndReminders/res/showhide.ico and /dev/null differ diff --git a/!NotAdopted/NotesAndReminders/res/viewnotes.ico b/!NotAdopted/NotesAndReminders/res/viewnotes.ico deleted file mode 100644 index 18057a372a..0000000000 Binary files a/!NotAdopted/NotesAndReminders/res/viewnotes.ico and /dev/null differ diff --git a/!NotAdopted/NotesAndReminders/res/viewremi.ico b/!NotAdopted/NotesAndReminders/res/viewremi.ico deleted file mode 100644 index b9e8bce9d5..0000000000 Binary files a/!NotAdopted/NotesAndReminders/res/viewremi.ico and /dev/null differ diff --git a/!NotAdopted/NotesAndReminders/src/globals.h b/!NotAdopted/NotesAndReminders/src/globals.h deleted file mode 100644 index f8cc794e4a..0000000000 --- a/!NotAdopted/NotesAndReminders/src/globals.h +++ /dev/null @@ -1,147 +0,0 @@ -#define _CRT_SECURE_NO_WARNINGS - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "win2k.h" -#include "newpluginapi.h" -#include "m_system.h" -#include "m_database.h" -#include "m_clist.h" -#include "m_langpack.h" -#include "m_options.h" -#include "m_skin.h" -#include "m_fontservice.h" -#include "m_hotkeys.h" -#include "m_icolib.h" - -#include "m_toptoolbar.h" - -#include "miscutils.h" -#include "resource.h" - -// {842A6668-F9DA-4968-BFD7-D2BD9DF848EE} -#define MIID_NNR {0x842a6668, 0xf9da, 0x4968, {0xbf, 0xd7, 0xd2, 0xbd, 0x9d, 0xf8, 0x48, 0xee}} - -#define MODULENAME "StickyNotes" -#define SECTIONNAME "Notes & Reminders" - -// normal timer interval for reminder update processing -#define REMINDER_UPDATE_INTERVAL 10000 -// short timer interval for reminder updates used as long as there are pending alarams in the event queue -#define REMINDER_UPDATE_INTERVAL_SHORT 5000 - - -// font IDs used with LoadNRFont -#define NR_FONTID_CAPTION 0 -#define NR_FONTID_BODY 1 -#define NR_FONTID_MAX NR_FONTID_BODY - - -typedef struct { - HFONT hFont; - char size; - BYTE style; // see the DBFONTF_* flags - BYTE charset; - char szFace[LF_FACESIZE]; -} STICKYNOTEFONT; - -typedef struct { - HWND SNHwnd,REHwnd; - BOOL Visible,OnTop; - char *data; - ULARGE_INTEGER ID; // FILETIME in UTC - char *title; - BOOL CustomTitle; - DWORD BgColor; // custom bg color override (only valid if non-zero) - DWORD FgColor; // custom fg/text color override (only valid if non-zero) - STICKYNOTEFONT *pCustomFont;// custom (body) font override (NULL if default font is used) -} STICKYNOTE; - -typedef struct { - HWND handle; - BOOL RemVisible; - DWORD uid; - char *Reminder; - ULARGE_INTEGER When; // FILETIME in UTC - UINT RepeatSound; - UINT RepeatSoundTTL; - int SoundSel; // -1 if sound disabled - BOOL SystemEventQueued; -} REMINDERDATA; - - -extern void CreateMsgWindow(void); -extern void DestroyMsgWindow(void); - -extern STICKYNOTE* NewNote(int Ax,int Ay,int Aw,int Ah,char *Data, - ULARGE_INTEGER *ID,BOOL Visible,BOOL OnTop,int scrollV); -extern void LoadNotes(BOOL bIsStartup); -extern void SaveNotes(void); -extern void DeleteNotes(void); -extern void ShowHideNotes(void); -extern void ListNotes(void); - -extern void NewReminder(void); -extern void LoadReminders(void); -extern void SaveReminders(void); -extern void DeleteReminders(void); -extern void ListReminders(void); -extern BOOL CheckRemindersAndStart(void); - -extern void InitSettings(void); -extern void TermSettings(void); -extern int CALLBACK DlgProcOptions(HWND hdlg,UINT message, - WPARAM wParam,LPARAM lParam); -extern void LoadNRFont(int i, LOGFONT *lf, COLORREF *colour); - -extern BOOL WS_Init(); -extern void WS_CleanUp(); - -extern LPCSTR GetDateFormatStr(); -extern LPCSTR GetTimeFormatStr(); - -extern HINSTANCE hinstance; -extern HINSTANCE hmiranda; -extern PLUGINLINK *pluginLink; - -extern BOOL g_CloseAfterAddReminder, g_UseDefaultPlaySound; -extern HICON g_hReminderIcon; - -extern LOGFONT lfBody,lfCaption; -extern HFONT hBodyFont,hCaptionFont; - -extern long BodyColor; -extern long CaptionFontColor,BodyFontColor; - -extern BOOL g_ShowNotesAtStart,g_ShowScrollbar,g_AddContListMI,g_ShowNoteButtons; -extern int g_NoteTitleDate, g_NoteTitleTime; - -extern int g_NoteWidth,g_NoteHeight; - -extern int g_Transparency; - -extern char *g_RemindSMS; - -extern BOOL g_isWin2kPlus; - -extern TCHAR *g_lpszAltBrowser; - -extern int g_reminderListGeom[4]; -extern int g_reminderListColGeom[2]; -extern int g_notesListGeom[4]; -extern int g_notesListColGeom[4]; - -extern HWND HKHwnd; -extern HANDLE hIconLibItem[]; - -// these defs are only used to emphasize that SYSTEMTIMEtoFILETIME/FILETIMEtoSYSTEMTIME only convert the data type, -// it does not apply any time conversion/correction like UTC to local etc. (if input is local, then output is local too) -#define SYSTEMTIMEtoFILETIME SystemTimeToFileTime -#define FILETIMEtoSYSTEMTIME FileTimeToSystemTime diff --git a/!NotAdopted/NotesAndReminders/src/hotkeys.cpp b/!NotAdopted/NotesAndReminders/src/hotkeys.cpp deleted file mode 100644 index a8bd8d3c53..0000000000 --- a/!NotAdopted/NotesAndReminders/src/hotkeys.cpp +++ /dev/null @@ -1,137 +0,0 @@ -#include "globals.h" - -#define MSG_WND_CLASS "MIM_SNMsgWindow" - - -HWND HKHwnd; - - -enum KB_ACTIONS {KB_NEW_NOTE = 1, KB_TOGGLE_NOTES, KB_NEW_REMINDER}; - - -void RegisterKeyBindings() -{ - HOTKEYDESC desc; - - ZeroMemory(&desc, sizeof(desc)); - desc.cbSize = sizeof(desc); - desc.pszSection = SECTIONNAME; - - desc.pszName = MODULENAME"/NewNote"; - desc.pszDescription = "New Note"; - desc.lParam = KB_NEW_NOTE; - desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, VK_INSERT); - desc.pszService = MODULENAME"/MenuCommandAddNew"; - Hotkey_Register(&desc); - - desc.pszName = MODULENAME"/ToggleNotesVis"; - desc.pszDescription = "Toggle Notes Visibility"; - desc.lParam = KB_TOGGLE_NOTES; - desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, VK_ADD); - desc.pszService = MODULENAME"/MenuCommandShowHide"; - Hotkey_Register(&desc); - - desc.pszName = MODULENAME"/BringNotesFront"; - desc.pszDescription = "Bring All Notes to Front"; - desc.lParam = KB_TOGGLE_NOTES; - desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, VK_HOME); - desc.pszService = MODULENAME"/MenuCommandBringAllFront"; - Hotkey_Register(&desc); - - desc.pszName = MODULENAME"/NewReminder"; - desc.pszDescription = "New Reminder"; - desc.lParam = KB_NEW_REMINDER; - desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, VK_SUBTRACT); - desc.pszService = MODULENAME"/MenuCommandNewReminder"; - Hotkey_Register(&desc); -} - - -/*int HandleNRShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - STICKYNOTE* PSN; - - BOOL isShift = GetKeyState(VK_SHIFT) & 0x8000; - BOOL isAlt = GetKeyState(VK_MENU) & 0x8000; - BOOL isCtrl = (GetKeyState(VK_CONTROL) & 0x8000) && !isAlt; - - int action; - MSG amsg; - amsg.hwnd = hwnd; - amsg.message = msg; - amsg.wParam = wParam; - amsg.lParam = lParam; - - switch ( (action = CallService(MS_HOTKEY_CHECK, (WPARAM)&amsg, (LPARAM)SECTIONNAME)) ) - { - case KB_NEW_NOTE: - PSN = NewNote(0,0,0,0,NULL,NULL,TRUE,TRUE,0); - SetFocus(PSN->REHwnd); - return FALSE; - case KB_TOGGLE_NOTES: - ShowHideNotes(); - return FALSE; - case KB_NEW_REMINDER: - NewReminder(); - return FALSE; - } - - return -1; -}*/ - - -int CALLBACK NotifyHotKeyWndProc(HWND AHwnd,UINT Message,WPARAM wParam,LPARAM lParam) -{ - BOOL b; - - switch (Message) - { - case WM_TIMER: - { - KillTimer(HKHwnd,1026); - b = CheckRemindersAndStart(); - SetTimer(HKHwnd,1026,b ? REMINDER_UPDATE_INTERVAL_SHORT : REMINDER_UPDATE_INTERVAL,0); - - return FALSE; - } - } - - return DefWindowProc(AHwnd,Message,wParam,lParam); -} - -void CreateMsgWindow(void) -{ - HWND hParent = NULL; - WNDCLASSEX TWC = {0}; - - if (!GetClassInfoEx(hmiranda,MSG_WND_CLASS,&TWC)) - { - TWC.style = 0; - TWC.cbClsExtra = 0; - TWC.cbWndExtra = 0; - TWC.hInstance = hmiranda; - TWC.hIcon = 0; - TWC.hCursor = 0; - TWC.hbrBackground = 0; - TWC.lpszMenuName = NULL; - TWC.lpszClassName = MSG_WND_CLASS; - TWC.cbSize = sizeof(TWC); - TWC.lpfnWndProc = (WNDPROC)NotifyHotKeyWndProc; - RegisterClassEx(&TWC); - } - - if ( IsWinVer2000Plus() ) - { - // win2k+ has special message-only windows support - hParent = HWND_MESSAGE; - } - - HKHwnd = CreateWindowEx(WS_EX_TOOLWINDOW,MSG_WND_CLASS,_T("StickyNotes"),0,0,0,0,0,hParent,NULL,hmiranda,NULL); - SetTimer(HKHwnd,1026,REMINDER_UPDATE_INTERVAL,0); -} - -void DestroyMsgWindow(void) -{ - KillTimer(HKHwnd,1026); - DestroyWindow(HKHwnd); -} diff --git a/!NotAdopted/NotesAndReminders/src/main.cpp b/!NotAdopted/NotesAndReminders/src/main.cpp deleted file mode 100644 index 2165a8e49b..0000000000 --- a/!NotAdopted/NotesAndReminders/src/main.cpp +++ /dev/null @@ -1,389 +0,0 @@ -#include "globals.h" - -HINSTANCE hinstance = NULL; -HINSTANCE hmiranda = NULL; -int hLangpack; - -HANDLE hkOptInit = NULL; -HANDLE hkTopToolbarInit = NULL; -HANDLE hkModulesLoaded = NULL; -HANDLE hkFontChange = NULL; -HANDLE hkColorChange = NULL; -HMODULE hUserDll = NULL; -HMODULE hRichedDll = NULL; -HMODULE hKernelDll = NULL; - -extern TREEELEMENT *g_Stickies; -extern TREEELEMENT *RemindersList; - -static PLUGININFOEX pluginInfo = -{ - sizeof(PLUGININFOEX), - "Sticky Notes & Reminders", - PLUGIN_MAKE_VERSION(0,0,5,1), - "Sticky Notes & Reminders Implementation for Miranda IM.", - "Joe Kucera, Lubomir Kolev Ivanov, Georg Fischer", - "jokusoftware@users.sourceforge.net; d00mEr@dir.bg", - "(C) 2003,2005 Joe Kucera, Lubomir Ivanov", - "http://d00mer.freeshell.org/miranda/", - UNICODE_AWARE, - MIID_NNR -}; - - -void RegisterFontServiceFonts(); -void RegisterKeyBindings(); -int OpenTriggeredReminder(WPARAM w, LPARAM l); -void BringAllNotesToFront(STICKYNOTE *pActive); -void CloseNotesList(); -void CloseReminderList(); - -int PluginMenuCommandAddNew(WPARAM w,LPARAM l) -{ - STICKYNOTE* PSN; - PSN = NewNote(0,0,0,0,NULL,NULL,TRUE,TRUE,0); - SetFocus(PSN->REHwnd); - return 0; -} - -int PluginMenuCommandDeleteAll(WPARAM w,LPARAM l) -{ - if (g_Stickies && MessageBox(NULL, Translate("Are you sure you want to delete all notes?"), SECTIONNAME, MB_OKCANCEL) == IDOK) - DeleteNotes(); - return 0; -} - -int PluginMenuCommandShowHide(WPARAM w,LPARAM l) -{ - ShowHideNotes(); - return 0; -} - -int PluginMenuCommandViewNotes(WPARAM w,LPARAM l) -{ - ListNotes(); - return 0; -} - -int PluginMenuCommandAllBringFront(WPARAM w,LPARAM l) -{ - BringAllNotesToFront(NULL); - return 0; -} - -int PluginMenuCommandNewReminder(WPARAM w,LPARAM l) -{ - NewReminder(); - return 0; -} - -int PluginMenuCommandViewReminders(WPARAM w,LPARAM l) -{ - ListReminders(); - return 0; -} - -int PluginMenuCommandDeleteReminders(WPARAM w,LPARAM l) -{ - if (RemindersList && MessageBox(NULL, Translate("Are you sure you want to delete all reminders?"), SECTIONNAME, MB_OKCANCEL) == IDOK) - DeleteReminders(); - return 0; -} - -struct -{ - char* szDescr; - char* szName; - int defIconID; -} -static const iconList[] = -{ - {"New Reminder", "AddReminder", IDI_ADDREMINDER}, - {"Delete All Notes", "DeleteIcon", IDI_DELETEICON}, - {"New Note", "NoteIcon", IDI_NOTEICON}, - {"Show/Hide Notes", "ShowHide", IDI_SHOWHIDE}, - {"On Top Caption Icon", "CaptionIcon", IDI_CAPTIONICON}, - {"Delete All Reminders", "DeleteReminder", IDI_DELETEREMINDER}, - {"View Reminders", "ViewReminders", IDI_VIEWREMINDERS}, - {"Not on Top Caption Icon", "CaptionIconNotTop", IDI_CAPTIONICONNOTTOP}, - {"Hide Note Icon", "HideNote", IDI_HIDENOTE}, - {"Remove Note Icon", "RemoveNote", IDI_REMOVENOTE}, - {"Reminder Icon", "Reminder", IDI_REMINDER}, - {"Bring All to Front", "BringFront", IDI_BRINGFRONT}, - {"Play Sound Icon", "PlaySound", IDI_PLAYSOUND}, - {"View Notes", "ViewNotes", IDI_VIEWNOTES}, - {"New Note", "NewNote", IDI_NOTEICON}, - {"New Reminder", "NewReminder", IDI_ADDREMINDER} -}; - -HANDLE hIconLibItem[SIZEOF(iconList)]; - -void InitIcons(void) -{ - int i; - char szSettingName[100]; - SKINICONDESC sid = {0}; - TCHAR szFile[MAX_PATH]; - - GetModuleFileName(hinstance, szFile, SIZEOF(szFile)); - - sid.cbSize = sizeof(SKINICONDESC); - sid.ptszDefaultFile = szFile; - sid.pszName = szSettingName; - sid.pszSection = MODULENAME; - sid.flags = SIDF_PATH_TCHAR; - - for (i = 0; i < SIZEOF(iconList); i++) - { - mir_snprintf(szSettingName, SIZEOF(szSettingName), "%s_%s", MODULENAME, iconList[i].szName); - - sid.pszDescription = iconList[i].szDescr; - sid.iDefaultIndex = -iconList[i].defIconID; - hIconLibItem[i] = Skin_AddIcon(&sid); - } -} - -int OnOptInitialise(WPARAM w, LPARAM L) -{ - OPTIONSDIALOGPAGE odp = {0}; - odp.cbSize = sizeof(odp); - odp.position = 900002000; - odp.hInstance = hinstance; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_STNOTEOPTIONS); - odp.pszTitle = _T(SECTIONNAME); - odp.pszGroup = _T("Plugins"); - odp.pfnDlgProc = DlgProcOptions; - Options_AddPage(w, &odp); - return 0; -} - -int OnTopToolBarInit(WPARAM w,LPARAM L) -{ - TTBButton ttb = {0}; - ttb.cbSize = sizeof(TTBButton); - ttb.dwFlags = TTBBF_VISIBLE | TTBBF_SHOWTOOLTIP; - - ttb.hIconHandleUp = hIconLibItem[14]; - ttb.pszService = MODULENAME"/MenuCommandAddNew"; - ttb.name = ttb.pszTooltipUp = LPGEN("Add New Note"); - TopToolbar_AddButton(&ttb); - - ttb.hIconHandleUp = hIconLibItem[15]; - ttb.pszService = MODULENAME"/MenuCommandNewReminder"; - ttb.name = ttb.pszTooltipUp = LPGEN("Add New Reminder"); - TopToolbar_AddButton(&ttb); - - UnhookEvent(hkTopToolbarInit); - return 0; -} - -static void InitServices() -{ - // register sounds - - SkinAddNewSoundEx("AlertReminder", "Alerts", "Reminder triggered"); - SkinAddNewSoundEx("AlertReminder2", "Alerts", "Reminder triggered (Alternative 1)"); - SkinAddNewSoundEx("AlertReminder3", "Alerts", "Reminder triggered (Alternative 2)"); - - // register menu command services - - CreateServiceFunction(MODULENAME"/MenuCommandAddNew",PluginMenuCommandAddNew); - CreateServiceFunction(MODULENAME"/MenuCommandShowHide",PluginMenuCommandShowHide); - CreateServiceFunction(MODULENAME"/MenuCommandViewNotes",PluginMenuCommandViewNotes); - CreateServiceFunction(MODULENAME"/MenuCommandDeleteAll",PluginMenuCommandDeleteAll); - CreateServiceFunction(MODULENAME"/MenuCommandBringAllFront",PluginMenuCommandAllBringFront); - - // - - CreateServiceFunction(MODULENAME"/MenuCommandNewReminder",PluginMenuCommandNewReminder); - CreateServiceFunction(MODULENAME"/MenuCommandViewReminders",PluginMenuCommandViewReminders); - CreateServiceFunction(MODULENAME"/MenuCommandDeleteReminders",PluginMenuCommandDeleteReminders); - - // register misc - - CreateServiceFunction(MODULENAME"/OpenTriggeredReminder",OpenTriggeredReminder); -} - -int OnModulesLoaded(WPARAM wparam,LPARAM lparam) -{ - CLISTMENUITEM cmi = {0}; - - // register fonts and hotkeys - - RegisterFontServiceFonts(); - RegisterKeyBindings(); - - // register menus - - cmi.cbSize = sizeof(cmi); - cmi.pszContactOwner = NULL; - cmi.pszPopupName = "Notes && Reminders"; - cmi.flags = CMIM_ICON | CMIF_ICONFROMICOLIB; - - cmi.position = 1600000000; - cmi.icolibItem = hIconLibItem[2]; - cmi.pszName = "New &Note"; - cmi.pszService = MODULENAME"/MenuCommandAddNew"; - if (g_AddContListMI) Menu_AddContactMenuItem(&cmi); - Menu_AddMainMenuItem(&cmi); - - cmi.position = 1600000001; - cmi.icolibItem = hIconLibItem[0]; - cmi.pszName = "New &Reminder"; - cmi.pszService = MODULENAME"/MenuCommandNewReminder"; - if (g_AddContListMI) Menu_AddContactMenuItem(&cmi); - Menu_AddMainMenuItem(&cmi); - - // - - cmi.position = 1600100000; - cmi.icolibItem = hIconLibItem[3]; - cmi.pszName = "&Show / Hide Notes"; - cmi.pszService = MODULENAME"/MenuCommandShowHide"; - if (g_AddContListMI) Menu_AddContactMenuItem(&cmi); - Menu_AddMainMenuItem(&cmi); - - cmi.position = 1600100001; - cmi.icolibItem = hIconLibItem[13]; - cmi.pszName = "Vie&w Notes"; - cmi.pszService = MODULENAME"/MenuCommandViewNotes"; - if (g_AddContListMI) Menu_AddContactMenuItem(&cmi); - Menu_AddMainMenuItem(&cmi); - - cmi.position = 1600100002; - cmi.icolibItem = hIconLibItem[1]; - cmi.pszName = "&Delete All Notes"; - cmi.pszService = MODULENAME"/MenuCommandDeleteAll"; - if (g_AddContListMI) Menu_AddContactMenuItem(&cmi); - Menu_AddMainMenuItem(&cmi); - - cmi.position = 1600100003; - cmi.icolibItem = hIconLibItem[11]; - cmi.pszName = "&Bring All to Front"; - cmi.pszService = MODULENAME"/MenuCommandBringAllFront"; - if (g_AddContListMI) Menu_AddContactMenuItem(&cmi); - Menu_AddMainMenuItem(&cmi); - - // - - cmi.position = 1600200000; - cmi.icolibItem = hIconLibItem[6]; - cmi.pszName = "&View Reminders"; - cmi.pszService = MODULENAME"/MenuCommandViewReminders"; - if (g_AddContListMI) Menu_AddContactMenuItem(&cmi); - Menu_AddMainMenuItem(&cmi); - - cmi.position = 1600200001; - cmi.icolibItem = hIconLibItem[5]; - cmi.pszName = "D&elete All Reminders"; - cmi.pszService = MODULENAME"/MenuCommandDeleteReminders"; - if (g_AddContListMI) Menu_AddContactMenuItem(&cmi); - Menu_AddMainMenuItem(&cmi); - - // register misc - - hkOptInit = HookEvent(ME_OPT_INITIALISE, OnOptInitialise); - hkTopToolbarInit = HookEvent("TopToolBar/ModuleLoaded", OnTopToolBarInit); - UnhookEvent(hkModulesLoaded); - - // init vars and load all data - - InitSettings(); - CreateMsgWindow(); - LoadNotes(TRUE); - LoadReminders(); - - return 0; -} - -extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) -{ - return &pluginInfo; -} - -extern "C" __declspec(dllexport) int Unload(void) -{ - CloseNotesList(); - CloseReminderList(); - SaveNotes(); - SaveReminders(); - DestroyMsgWindow(); - WS_CleanUp(); - TermSettings(); - - UnhookEvent(hkFontChange); - UnhookEvent(hkColorChange); - - UnhookEvent(hkOptInit); - - Skin_ReleaseIcon(g_hReminderIcon); - DeleteObject(hBodyFont); - DeleteObject(hCaptionFont); - - if (hRichedDll) - FreeLibrary(hRichedDll); - if (hUserDll) - FreeLibrary(hUserDll); - if (hKernelDll) - FreeLibrary(hKernelDll); - - return 0; -} - -BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID lpvReserved) -{ - hinstance = hinst; - return TRUE; -} - -extern "C" __declspec(dllexport) int Load(void) -{ - mir_getLP(&pluginInfo); - - INITCOMMONCONTROLSEX ctrls = {0}; - ctrls.dwSize = sizeof(INITCOMMONCONTROLSEX); - ctrls.dwICC = ICC_DATE_CLASSES; - InitCommonControlsEx(&ctrls); - - g_isWin2kPlus = IsWinVer2000Plus(); - - hRichedDll = LoadLibrary("RICHED20.DLL"); - if (!hRichedDll) - { - if (MessageBox(0, Translate("Miranda could not load the Note & Reminders plugin, RICHED20.DLL is missing. If you are using Windows 95 or WINE please make sure you have riched20.dll installed. Press 'Yes' to continue loading Miranda."), SECTIONNAME, MB_YESNO | MB_ICONINFORMATION) != IDYES) - return 1; - return 0; - } - - hUserDll = LoadLibrary("user32.dll"); - if (hUserDll) - { - MySetLayeredWindowAttributes = (BOOL (WINAPI *)(HWND,COLORREF,BYTE,DWORD))GetProcAddress(hUserDll,"SetLayeredWindowAttributes"); - MyMonitorFromWindow = (HANDLE (WINAPI*)(HWND,DWORD))GetProcAddress(hUserDll,"MonitorFromWindow"); - } - else - { - MySetLayeredWindowAttributes = NULL; - MyMonitorFromWindow = NULL; - } - - hKernelDll = LoadLibrary("kernel32.dll"); - if (hKernelDll) - { - MyTzSpecificLocalTimeToSystemTime = (BOOL (WINAPI*)(LPTIME_ZONE_INFORMATION,LPSYSTEMTIME,LPSYSTEMTIME))GetProcAddress(hKernelDll,"TzSpecificLocalTimeToSystemTime"); - MySystemTimeToTzSpecificLocalTime = (BOOL (WINAPI*)(LPTIME_ZONE_INFORMATION,LPSYSTEMTIME,LPSYSTEMTIME))GetProcAddress(hKernelDll,"SystemTimeToTzSpecificLocalTime"); - } - else - { - MyTzSpecificLocalTimeToSystemTime = NULL; - MySystemTimeToTzSpecificLocalTime = NULL; - } - - InitServices(); - WS_Init(); - - hkModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED,OnModulesLoaded); - InitIcons(); - - return 0; -} \ No newline at end of file diff --git a/!NotAdopted/NotesAndReminders/src/miscutils.cpp b/!NotAdopted/NotesAndReminders/src/miscutils.cpp deleted file mode 100644 index b4de98404c..0000000000 --- a/!NotAdopted/NotesAndReminders/src/miscutils.cpp +++ /dev/null @@ -1,246 +0,0 @@ -#include "globals.h" - -BOOL (WINAPI *MySetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD); -HANDLE (WINAPI *MyMonitorFromWindow)(HWND,DWORD); -BOOL (WINAPI *MyTzSpecificLocalTimeToSystemTime)(LPTIME_ZONE_INFORMATION,LPSYSTEMTIME,LPSYSTEMTIME); -BOOL (WINAPI *MySystemTimeToTzSpecificLocalTime)(LPTIME_ZONE_INFORMATION,LPSYSTEMTIME,LPSYSTEMTIME); - - -WORD ConvertHotKeyToControl(WORD HK) -{ - WORD R = 0; - if ((HK & MOD_CONTROL) == MOD_CONTROL) R = R | HOTKEYF_CONTROL; - if ((HK & MOD_ALT) == MOD_ALT) R = R | HOTKEYF_ALT; - if ((HK & MOD_SHIFT) == MOD_SHIFT) R = R | HOTKEYF_SHIFT; - return R; -} - -WORD ConvertControlToHotKey(WORD HK) -{ - WORD R = 0; - if ((HK & HOTKEYF_CONTROL) == HOTKEYF_CONTROL) R = R | MOD_CONTROL; - if ((HK & HOTKEYF_ALT) == HOTKEYF_ALT) R = R | MOD_ALT; - if ((HK & HOTKEYF_SHIFT) == HOTKEYF_SHIFT) R = R | MOD_SHIFT; - return R; -} - -void WriteSettingInt(HANDLE hContact,char *ModuleName,char *SettingName,int Value) -{ - DBCONTACTWRITESETTING cws = {0}; - DBVARIANT dbv = {0}; - dbv.type = DBVT_DWORD; - dbv.dVal = Value; - cws.szModule = ModuleName; - cws.szSetting = SettingName; - cws.value = dbv; - CallService(MS_DB_CONTACT_WRITESETTING,(DWORD)hContact,(DWORD)&cws); -} - -int ReadSettingInt(HANDLE hContact,char *ModuleName,char *SettingName,int Default) -{ - DBCONTACTGETSETTING cws = {0}; - DBVARIANT dbv = {0}; - dbv.type = DBVT_DWORD; - dbv.dVal = Default; - cws.szModule = ModuleName; - cws.szSetting = SettingName; - cws.pValue = &dbv; - if (CallService(MS_DB_CONTACT_GETSETTING,(DWORD)hContact,(DWORD)&cws)) - return Default; - else - return dbv.dVal; -} - -void DeleteSetting(HANDLE hContact,char *ModuleName,char *SettingName) -{ - DBCONTACTGETSETTING dbcgs = {0}; - dbcgs.szModule = ModuleName; - dbcgs.szSetting = SettingName; - dbcgs.pValue = NULL; - CallService(MS_DB_CONTACT_DELETESETTING,(DWORD)hContact,(DWORD)&dbcgs); -} - -void FreeSettingBlob(WORD pSize,void * pbBlob) -{ - DBVARIANT dbv = {0}; - dbv.type = DBVT_BLOB; - dbv.cpbVal = pSize; - dbv.pbVal = (BYTE*)pbBlob; - CallService(MS_DB_CONTACT_FREEVARIANT,0,(DWORD)&dbv); -} - -void WriteSettingBlob(HANDLE hContact,char *ModuleName,char *SettingName,WORD pSize,void *pbBlob) -{ - DBCONTACTWRITESETTING cgs = {0}; - DBVARIANT dbv = {0}; - dbv.type = DBVT_BLOB; - dbv.cpbVal = pSize; - dbv.pbVal = (BYTE*)pbBlob; - cgs.szModule = ModuleName; - cgs.szSetting = SettingName; - cgs.value = dbv; - CallService(MS_DB_CONTACT_WRITESETTING,(DWORD)hContact,(DWORD)&cgs); -} - -void ReadSettingBlob(HANDLE hContact, char *ModuleName, char *SettingName, WORD *pSize, void **pbBlob) -{ - DBCONTACTGETSETTING cgs = {0}; - DBVARIANT dbv = {0}; - dbv.type = DBVT_BLOB; -// dbv.cpbVal = (LOBYTE(pSize) | HIBYTE((BYTE)pbBlob)); // this is not used anyway - cgs.szModule = ModuleName; - cgs.szSetting = SettingName; - cgs.pValue = &dbv; - if (CallService(MS_DB_CONTACT_GETSETTING,(DWORD)hContact,(DWORD)&cgs)) - { - pSize = 0; // tohle asi ve 4.2 neni - pbBlob = NULL; - } - else - { - *pSize = LOWORD(dbv.cpbVal); - *pbBlob = (int*)dbv.pbVal; - } -} - -void WriteSettingIntArray(HANDLE hContact,char *ModuleName,char *SettingName,const int *Value, int Size) -{ - WriteSettingBlob(hContact,ModuleName,SettingName,sizeof(int)*Size,(void*)Value); -} - -BOOL ReadSettingIntArray(HANDLE hContact,char *ModuleName,char *SettingName,int *Value, int Size) -{ - WORD sz = 4096; - int *pData; - BOOL bResult; - - ReadSettingBlob(hContact, ModuleName, SettingName, &sz, (void**)&pData); - - if (!pData) - return FALSE; - - bResult = FALSE; - - if (sz == sizeof(int)*Size) - { - memcpy(Value, pData, sizeof(int)*Size); - bResult = TRUE; - } - - FreeSettingBlob(sz,pData); - - return bResult; -} - -void TreeAdd(TREEELEMENT **root, void *Data) -{ - TREEELEMENT *NTE; - NTE = (TREEELEMENT*)malloc(sizeof(TREEELEMENT)); - if (NTE) - { - NTE->ptrdata = Data; - NTE->next = *root; - *root = NTE; - } -} - -void TreeAddSorted(TREEELEMENT **root,void *Data,int (*CompareCb)(TREEELEMENT*,TREEELEMENT*)) -{ - TREEELEMENT *TTE,*Prev; - TREEELEMENT *NTE; - - if (!*root) - { - // list empty, just add normally - TreeAdd(root,Data); - return; - } - - NTE = (TREEELEMENT*)malloc(sizeof(TREEELEMENT)); - if (!NTE) - return; - - NTE->ptrdata = Data; - NTE->next = NULL; - - // insert sorted - - Prev = NULL; - TTE = *root; - - while (TTE) - { - if (CompareCb(NTE, TTE) < 0) - { - if (Prev) - { - Prev->next = NTE; - NTE->next = TTE; - } - else - { - // first in list - NTE->next = TTE; - *root = NTE; - } - return; - } - - Prev = TTE; - TTE = (TREEELEMENT*)TTE->next; - } - - // add last - Prev->next = NTE; -} - -void TreeDelete(TREEELEMENT **root,void *Item) -{ - TREEELEMENT *TTE,*Prev = NULL; - TTE = *root; - if (!TTE) return; - while ((TTE) && (TTE->ptrdata != Item)) - { - Prev = TTE; - TTE = (TREEELEMENT*)TTE->next; - } - if (TTE) - { - if (Prev) - Prev->next = TTE->next; - else - *root = (TREEELEMENT*)TTE->next; - SAFE_FREE((void**)&TTE); - } -} - -void *TreeGetAt(TREEELEMENT *root,int Item) -{ - TREEELEMENT *TTE; - int I = 0; - if (!root) return NULL; - TTE = root; - while ((TTE) && (I != Item)) - { - TTE = (TREEELEMENT*)TTE->next; - I++; - } - if (!TTE) - return NULL; - else - return TTE->ptrdata; -} - -int TreeGetCount(TREEELEMENT *root) -{ - int I = 0; - TREEELEMENT *TTE; - if (!root) return 0; - TTE = root; - while (TTE) - { - TTE = (TREEELEMENT*)TTE->next; - I++; - } - return I; -} diff --git a/!NotAdopted/NotesAndReminders/src/miscutils.h b/!NotAdopted/NotesAndReminders/src/miscutils.h deleted file mode 100644 index 104de5313c..0000000000 --- a/!NotAdopted/NotesAndReminders/src/miscutils.h +++ /dev/null @@ -1,47 +0,0 @@ -void WriteSettingInt(HANDLE hContact,char *ModuleName, - char *SettingName,int Value); -int ReadSettingInt(HANDLE hContact,char *ModuleName, - char *SettingName,int Default); -void ReadSettingBlob(HANDLE hContact, char *ModuleName, - char *SettingName, WORD *pSize, void **pbBlob); -void WriteSettingBlob(HANDLE hContact,char *ModuleName, - char *SettingName,WORD pSize,void *pbBlob); -void FreeSettingBlob(WORD pSize,void * pbBlob); -BOOL ReadSettingBool(HANDLE hContact,char *ModuleName, - char *SettingName,BOOL Default); -void WriteSettingBool(HANDLE hContact,char *ModuleName, - char *SettingName,BOOL Value); -void DeleteSetting(HANDLE hContact,char *ModuleName, - char *SettingName); -void WriteSettingIntArray(HANDLE hContact,char *ModuleName, - char *SettingName,const int *Value, int Size); -BOOL ReadSettingIntArray(HANDLE hContact,char *ModuleName, - char *SettingName,int *Value, int Size); - -extern BOOL (WINAPI *MySetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD); -extern HANDLE (WINAPI *MyMonitorFromWindow)(HWND,DWORD); -extern BOOL (WINAPI *MyTzSpecificLocalTimeToSystemTime)(LPTIME_ZONE_INFORMATION,LPSYSTEMTIME,LPSYSTEMTIME); -extern BOOL (WINAPI *MySystemTimeToTzSpecificLocalTime)(LPTIME_ZONE_INFORMATION,LPSYSTEMTIME,LPSYSTEMTIME); - -WORD ConvertHotKeyToControl(WORD HK); -WORD ConvertControlToHotKey(WORD HK); - -typedef struct { - void *ptrdata; - void *next; -} TREEELEMENT; - -void TreeAdd(TREEELEMENT **root,void *Data); -void TreeAddSorted(TREEELEMENT **root,void *Data,int (*CompareCb)(TREEELEMENT*,TREEELEMENT*)); -void TreeDelete(TREEELEMENT **root,void *Item); -void *TreeGetAt(TREEELEMENT *root,int Item); -int TreeGetCount(TREEELEMENT *root); - -static void __inline SAFE_FREE(void** p) -{ - if (*p) - { - free(*p); - *p = NULL; - } -} diff --git a/!NotAdopted/NotesAndReminders/src/notes.cpp b/!NotAdopted/NotesAndReminders/src/notes.cpp deleted file mode 100644 index 5f98768d8b..0000000000 --- a/!NotAdopted/NotesAndReminders/src/notes.cpp +++ /dev/null @@ -1,2180 +0,0 @@ -#include "globals.h" - -#ifndef MONITOR_DEFAULTTONULL -#define MONITOR_DEFAULTTONULL 0x00000000 -#endif - - -// NotesData DB data params -#define DATATAG_TEXT 1 // %s -#define DATATAG_SCROLLPOS 2 // %u (specifies rich edit controls scroll post as first visible line) -#define DATATAG_BGCOL 3 // %x (custom background color) -#define DATATAG_FGCOL 4 // %x (custom text/fg colors) -#define DATATAG_TITLE 5 // %s (custom note title) -#define DATATAG_FONT 6 // %d:%u:%u:%s (custom font) - - -#define MAX_TITLE_LEN 63 -#define MAX_NOTE_LEN 16384 - -// delay before saving note changes (ms) -#define NOTE_CHANGE_COMMIT_DELAY 1000 - - -#ifndef WS_EX_NOACTIVATE -#define WS_EX_NOACTIVATE 0x08000000 -#endif -#define IDM_REMOVENOTE 40001 -#define IDM_HIDENOTE 40002 -#define IDM_TOGGLEONTOP 40003 -#define IDM_UNDO 40004 -#define IDM_COPY 40005 -#define IDM_PASTE 40006 -#define IDM_CUT 40007 -#define IDM_CLEAR 40008 -#define WS_EX_LAYERED 0x00080000 -#define LWA_ALPHA 0x00000002 - -#define IDC_LISTREMINDERS 1000 -#define IDC_LISTREMINDERS_HEADER 2000 -#define IDC_REMINDERDATA 1001 -#define IDC_ADDNEWREMINDER 1002 -#define IDC_CLOSE 1003 -#define WM_RELOAD (WM_USER + 100) - -#define NOTIFY_LIST() if (ListNotesVisible) PostMessage(LV,WM_RELOAD,0,0) - -#define PENLINK ENLINK * - -#define NOTE_WND_CLASS "MIM_StickyNote" - - -#define IDM_COLORPRESET_BG 41000 -#define IDM_COLORPRESET_FG 41100 - - -static BOOL ListNotesVisible = FALSE; -static HWND LV; - - -struct ColorPreset -{ - TCHAR *szName; - COLORREF color; -}; - -static struct ColorPreset clrPresets[] = -{ - {"Black", RGB(0,0,0)}, - {"Maroon", RGB(128,0,0)}, - {"Green", RGB(0,128,0)}, - {"Olive", RGB(128,128,0)}, - {"Navy", RGB(0,0,128)}, - {"Purple", RGB(128,0,128)}, - {"Teal", RGB(0,128,128)}, - {"Gray", RGB(128,128,128)}, - {"Silver", RGB(192,192,192)}, - {"Red", RGB(255,0,0)}, - {"Orange", RGB(255,155,0)}, - {"Lime", RGB(0,255,0)}, - {"Yellow", RGB(255,255,0)}, - {"Blue", RGB(0,0,255)}, - {"Fuchsia", RGB(255,0,255)}, - {"Aqua", RGB(0,255,255)}, - {"White", RGB(255,255,255)} -}; - - -TREEELEMENT *g_Stickies = NULL; - - -int CALLBACK StickyNoteWndProc(HWND hdlg,UINT message, - WPARAM wParam,LPARAM lParam); -int CALLBACK DlgProcViewNotes(HWND Dialog,UINT Message,WPARAM wParam, - LPARAM lParam); -void JustSaveNotes(void); -int PluginMenuCommandAddNew(WPARAM w,LPARAM l); -int PluginMenuCommandDeleteAll(WPARAM w,LPARAM l); -void GetTriggerTimeString(const ULARGE_INTEGER *When, char *s, UINT strSize, BOOL bUtc); -void OnListResize(HWND Dialog); -void UpdateGeomFromWnd(HWND Dialog, int *geom, int *colgeom, int nCols); -void FileTimeToTzLocalST(const FILETIME *lpUtc, SYSTEMTIME *tmLocal); - - -COLORREF GetCaptionColor(COLORREF bodyClr) -{ - const DWORD r = ((bodyClr & 0xff) * 4) / 5; - const DWORD g = (((bodyClr & 0xff00) * 4) / 5) & 0xff00; - const DWORD b = (((bodyClr & 0xff0000) * 4) / 5) & 0xff0000; - - return (COLORREF)(r|g|b); -} - - -static void EnsureUniqueID(STICKYNOTE *TSN) -{ - TREEELEMENT *TTE; - - if (!g_Stickies) - return; - -try_next: - - // check existing notes if id is in use - TTE = g_Stickies; - while (TTE) - { - if (((STICKYNOTE*)TTE->ptrdata)->ID.QuadPart == TSN->ID.QuadPart) - { - // id in use, try new (increases the ID/time stamp by 100 nanosecond steps until an unused time is found, - // allthough it's very unlikely that there will be duplicated id's it's better to make 100% sure) - TSN->ID.QuadPart++; - goto try_next; - } - - TTE = (TREEELEMENT*)TTE->next; - } -} - - -static void InitNoteTitle(STICKYNOTE *TSN) -{ - if (g_NoteTitleDate) - { - char TempStr[MAX_PATH]; - SYSTEMTIME tm; - LCID lc = GetUserDefaultLCID(); - - TempStr[0] = 0; - - memset(&tm, 0, sizeof(tm)); - FileTimeToTzLocalST((FILETIME*)&TSN->ID, &tm); - - if ( GetDateFormat(lc, 0, &tm, GetDateFormatStr(), TempStr, MAX_PATH) ) - { - // append time if requested - if (g_NoteTitleTime) - { - int n = strlen(TempStr); - TempStr[n++] = ' '; - TempStr[n] = 0; - - GetTimeFormat(MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),0), 0, &tm, GetTimeFormatStr(), TempStr+n, MAX_PATH-n); - } - - TSN->title = _strdup(TempStr); - } - } - - TSN->CustomTitle = FALSE; -} - - -static void InitStickyNoteLogFont(STICKYNOTEFONT *pCustomFont, LOGFONT *lf) -{ - if (!pCustomFont->size) - { - HDC hdc; - - SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, FALSE); - lf->lfHeight = 10; - hdc = GetDC(0); - lf->lfHeight = -MulDiv(lf->lfHeight,GetDeviceCaps(hdc, LOGPIXELSY), 72); - ReleaseDC(0, hdc); - } - else - { - lf->lfHeight = pCustomFont->size; - } - - _tcscpy(lf->lfFaceName, pCustomFont->szFace); - - lf->lfWidth = lf->lfEscapement = lf->lfOrientation = 0; - lf->lfWeight = pCustomFont->style & DBFONTF_BOLD ? FW_BOLD : FW_NORMAL; - lf->lfItalic = (pCustomFont->style & DBFONTF_ITALIC) != 0; - lf->lfUnderline = (pCustomFont->style & DBFONTF_UNDERLINE) != 0; - lf->lfStrikeOut = (pCustomFont->style & DBFONTF_STRIKEOUT) != 0; - lf->lfCharSet = pCustomFont->charset; - lf->lfOutPrecision = OUT_DEFAULT_PRECIS; - lf->lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf->lfQuality = DEFAULT_QUALITY; - lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; -} - -static BOOL CreateStickyNoteFont(STICKYNOTEFONT *pCustomFont, LOGFONT *plf) -{ - LOGFONT lf = {0}; - - if (!plf) - { - InitStickyNoteLogFont(pCustomFont, &lf); - plf = &lf; - } - - if (pCustomFont->hFont) - DeleteObject(pCustomFont->hFont); - - pCustomFont->hFont = CreateFontIndirect(plf); - - return pCustomFont->hFont != NULL; -} - - -STICKYNOTE* NewNoteEx(int Ax,int Ay,int Aw,int Ah,char *Data,ULARGE_INTEGER *ID,BOOL Visible,BOOL OnTop,int scrollV,COLORREF bgClr,COLORREF fgClr,char *Title,STICKYNOTEFONT *pCustomFont,BOOL bLoading) -{ - STICKYNOTE* TSN; - WNDCLASSEX TWC = {0}; - WINDOWPLACEMENT TWP; - DWORD L1,L2; - SYSTEMTIME tm; - char TempStr[MAX_PATH] = {0}; - char *TData; - - const BOOL bIsStartup = Visible & 0x10000; - Visible &= ~0x10000; - - if (Data) TData = Data; else TData = NULL; - - if (!GetClassInfoEx(hmiranda, NOTE_WND_CLASS, &TWC)) - { - TWC.style = CS_HREDRAW | CS_VREDRAW | CS_NOCLOSE; - TWC.cbClsExtra = 0; - TWC.cbWndExtra = 0; - TWC.hInstance = hmiranda; - TWC.hIcon = LoadIcon(0,IDI_APPLICATION); - TWC.hCursor = LoadCursor(0,IDC_ARROW); - TWC.hbrBackground = 0; - TWC.lpszMenuName = 0; - TWC.lpszClassName = NOTE_WND_CLASS; - TWC.cbSize = sizeof(WNDCLASSEX); - TWC.lpfnWndProc = (WNDPROC)StickyNoteWndProc; - if (!RegisterClassEx(&TWC)) return NULL; - } - - if (!TData || Aw < 0 || Ah < 0) - { - TWP.length = sizeof(WINDOWPLACEMENT); - GetWindowPlacement(GetDesktopWindow(),&TWP); - Aw = g_NoteWidth; Ah = g_NoteHeight; - Ax = ((TWP.rcNormalPosition.right - TWP.rcNormalPosition.left) / 2) - (Aw / 2); - Ay = ((TWP.rcNormalPosition.bottom - TWP.rcNormalPosition.top) / 2) - (Ah / 2); - } - - TSN = (STICKYNOTE*)malloc(sizeof(STICKYNOTE)); - - if (ID) - { - TSN->ID = *ID; - } - else - { - GetSystemTime(&tm); - SYSTEMTIMEtoFILETIME(&tm, (FILETIME*)&TSN->ID); - } - - EnsureUniqueID(TSN); - - TreeAdd(&g_Stickies,TSN); - - if (!TData) - { - TData = _strdup(""); - TSN->data = TData; - } - else - TSN->data = TData; - - // init note title (time-stamp) - if (Title) - { - TSN->title = Title; - TSN->CustomTitle = TRUE; - } - else - { - TSN->title = NULL; - InitNoteTitle(TSN); - } - - TSN->Visible = Visible; - TSN->OnTop = OnTop; - - TSN->BgColor = bgClr; - TSN->FgColor = fgClr; - - TSN->pCustomFont = pCustomFont; - - L1 = WS_EX_TOOLWINDOW; - if (MySetLayeredWindowAttributes && g_Transparency < 255) L1 |= WS_EX_LAYERED; - if (OnTop) L1 |= WS_EX_TOPMOST; - - L2 = WS_POPUP | WS_THICKFRAME | WS_CAPTION; - - // NOTE: loaded note positions stem from GetWindowPlacement, which normally have a different coord space than - // CreateWindow/SetWindowPos, BUT since we now use WS_EX_TOOLWINDOW they use the same coord space so - // we don't have to worry about notes "drifting" between sessions - TSN->SNHwnd = CreateWindowEx(L1, NOTE_WND_CLASS, _T("StickyNote"), L2, Ax,Ay,Aw,Ah, NULL, 0, hmiranda, TSN); - - if (MySetLayeredWindowAttributes && g_Transparency < 255) - MySetLayeredWindowAttributes(TSN->SNHwnd,0,(BYTE)g_Transparency,LWA_ALPHA); - - // ensure that window is not placed off-screen (if previous session had different monitor count or resolution) - // NOTE: SetWindowPlacement should do this, but it's extremly flakey - if (Data) - { - if (MyMonitorFromWindow && !MyMonitorFromWindow(TSN->SNHwnd, MONITOR_DEFAULTTONULL) ) - { - TWP.length = sizeof(WINDOWPLACEMENT); - GetWindowPlacement(GetDesktopWindow(), &TWP); - - if (Aw > 500) Aw = 500; - if (Ay < TWP.rcNormalPosition.left+10 || Ax > TWP.rcNormalPosition.right-120) - Ax = ((TWP.rcNormalPosition.right - TWP.rcNormalPosition.left) / 2) - (Aw / 2) + (rand() & 0x3f); - if (Ay < TWP.rcNormalPosition.top+50 || Ay > TWP.rcNormalPosition.bottom-50) - Ay = ((TWP.rcNormalPosition.bottom - TWP.rcNormalPosition.top) / 4) + (rand() & 0x1f); - - SetWindowPos(TSN->SNHwnd, NULL, Ax, Ay, Aw, Ah, SWP_NOZORDER|SWP_NOACTIVATE); - } - } - - if (Visible) - { - ShowWindow(TSN->SNHwnd, SW_SHOWNA); - - // when loading notes (only at startup), place all non-top notes at the bottom so they don't cover other windows - if (Data && !OnTop && bIsStartup) - SetWindowPos(TSN->SNHwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_ASYNCWINDOWPOS); - } - - if (scrollV) - { - SendMessage(TSN->REHwnd, EM_LINESCROLL, 0, scrollV); - } - - // make sure that any event triggered by init doesn't cause a meaningless save - KillTimer(TSN->SNHwnd, 1025); - - if (!bLoading) - { - NOTIFY_LIST(); - } - - return TSN; -} - -STICKYNOTE* NewNote(int Ax,int Ay,int Aw,int Ah,char *Data,ULARGE_INTEGER *ID,BOOL Visible,BOOL OnTop,int scrollV) -{ - return NewNoteEx(Ax,Ay,Aw,Ah,Data,ID,Visible,OnTop,scrollV,0,0,NULL,NULL,FALSE); -} - -void LoadNotes(BOOL bIsStartup) -{ - int I; - int NotesCount; - WORD Size; - char *Value = NULL, *TVal = NULL; - char ValueName[32]; - - g_Stickies = NULL; - - NotesCount = ReadSettingInt(0,MODULENAME,"NotesData",0); - - for (I = 0; I < NotesCount; I++) - { - char *DelPos; - - sprintf(ValueName, "NotesData%d", I); - - if (Value) - { - FreeSettingBlob(Size, Value); - Value = NULL; - } - - Size = 65535; // does not get used - - ReadSettingBlob(0, MODULENAME, ValueName, &Size, (void**)&Value); - - if (!Size || !Value) - continue; // the setting could not be read from DB -> skip - - if (Value[0] == 'X') - { - // new eXtended/fleXible data format - - STICKYNOTE note = {0}; - int i, rect[4]; - int scrollV = 0; - STICKYNOTEFONT *pCustomFont = NULL; - DWORD flags; - - DelPos = strchr(Value+1,0x1B); - if (DelPos) - *DelPos = 0; - - // id:x:y:w:h:flags - - TVal = strchr(Value+1, ':'); - if (!TVal || (DelPos && TVal > DelPos)) - continue; - *TVal++ = 0; - - note.ID.QuadPart = _strtoui64(Value+1, NULL, 16); - - for (i=0; i<4; i++) - { - char *sep = strchr(TVal, ':'); - if (!sep || (DelPos && sep > DelPos)) - goto skip; - *sep++ = 0; - - rect[i] = strtol(TVal, NULL, 10); - - TVal = sep; - } - - flags = strtoul(TVal, NULL, 16); - - if (flags & 1) - note.Visible = TRUE; - if (flags & 2) - note.OnTop = TRUE; - - // optional \033 separated params - while (DelPos) - { - char *sep; - UINT tag; - - TVal = DelPos + 1; - // find param end and make sure it's null-terminated (if end of data then it's already null-terminated) - DelPos = strchr(TVal, 0x1B); - if (DelPos) - *DelPos = 0; - - // tag: - - sep = strchr(TVal, ':'); - if (!sep || (DelPos && sep > DelPos)) - goto skip; - - tag = strtoul(TVal, NULL, 10); - TVal = sep + 1; - - switch (tag) - { - case DATATAG_TEXT: - note.data = _strdup(TVal); - break; - - case DATATAG_SCROLLPOS: - scrollV = (int)strtoul(TVal, NULL, 10); - break; - - case DATATAG_BGCOL: - note.BgColor = strtoul(TVal, NULL, 16) | 0xff000000; - break; - - case DATATAG_FGCOL: - note.FgColor = strtoul(TVal, NULL, 16) | 0xff000000; - break; - - case DATATAG_TITLE: - if (strlen(TVal) > MAX_TITLE_LEN) - TVal[MAX_TITLE_LEN] = 0; - note.title = _strdup(TVal); - note.CustomTitle = TRUE; - break; - - case DATATAG_FONT: - { - int fsize; - UINT fstyle, fcharset; - - char *TVal2 = TVal; - sep = strchr(TVal2, ':'); - if (!sep || (DelPos && sep > DelPos)) - goto skip; - *sep++ = 0; - fsize = strtol(TVal2, NULL, 10); - TVal2 = sep; - - sep = strchr(TVal2, ':'); - if (!sep || (DelPos && sep > DelPos)) - goto skip; - *sep++ = 0; - fstyle = strtoul(TVal2, NULL, 10); - TVal2 = sep; - - sep = strchr(TVal2, ':'); - if (!sep || (DelPos && sep > DelPos)) - goto skip; - *sep++ = 0; - fcharset = strtoul(TVal2, NULL, 10); - TVal2 = sep; - - if (TVal2 >= DelPos) - goto skip; - - pCustomFont = (STICKYNOTEFONT*)malloc(sizeof(STICKYNOTEFONT)); - pCustomFont->size = (char)fsize; - pCustomFont->style = (BYTE)fstyle; - pCustomFont->charset = (BYTE)fcharset; - _tcscpy(pCustomFont->szFace, TVal2); - pCustomFont->hFont = NULL; - - if ( !CreateStickyNoteFont(pCustomFont, NULL) ) - { - free(pCustomFont); - pCustomFont = NULL; - } - } - break; - } - } - - if (!note.data) - note.data = _strdup(""); - - note.Visible = note.Visible && (!bIsStartup || g_ShowNotesAtStart); - if (bIsStartup) - note.Visible |= 0x10000; - - NewNoteEx(rect[0],rect[1],rect[2],rect[3],note.data,¬e.ID,note.Visible,note.OnTop,scrollV,note.BgColor,note.FgColor,note.title,pCustomFont,TRUE); - } - else - { - // old format (for DB backward compatibility) - - int Tx,Ty,Tw,Th,TV,OT; - BOOL V; - char *Data,*ID; - ULARGE_INTEGER newid; - - OT = 1; TV = 1; - Tx = 100; Ty = 100; - Tw = 179; Th = 35; - Data = NULL; ID = NULL; - - if (DelPos = strchr(Value,0x1B)) - { // get first delimiter - int PartLen = DelPos - TVal; - - Data = NULL; - ID = NULL; - TVal = Value; - DelPos[0] = 0x0; - Tx = strtol(TVal, NULL, 10); - - TVal = DelPos + 1; - DelPos = strchr(TVal, 0x1B); - if (!DelPos) continue; // setting is broken, do not crash - DelPos[0] = 0x0; - Ty = strtol(TVal, NULL, 10); - - TVal = DelPos + 1; - DelPos = strchr(TVal, 0x1B); - if (!DelPos) continue; // setting is broken, do not crash - DelPos[0] = 0x0; - Tw = strtol(TVal, NULL, 10); - - TVal = DelPos + 1; - DelPos = strchr(TVal, 0x1B); - if (!DelPos) continue; // setting is broken, do not crash - DelPos[0] = 0x0; - Th = strtol(TVal, NULL, 10); - - TVal = DelPos + 1; - DelPos = strchr(TVal, 0x1B); - if (!DelPos) continue; // setting is broken, do not crash - DelPos[0] = 0x0; - TV = strtol(TVal, NULL, 10); - - TVal = DelPos + 1; - DelPos = strchr(TVal, 0x1B); - if (!DelPos) continue; // setting is broken, do not crash - DelPos[0] = 0x0; - OT = strtol(TVal, NULL, 10); - - TVal = DelPos + 1; - DelPos = strchr(TVal, 0x1B); - if (!DelPos) continue; // setting is broken, do not crash - DelPos[0] = 0x0; - Data = _strdup(TVal); - - TVal = DelPos + 1; - ID = TVal; - - V = (BOOL)TV && (!bIsStartup || g_ShowNotesAtStart); - - if (bIsStartup) - V |= 0x10000; - - // convert old ID format to new - if ( strchr(ID, '-') ) - { - // validate format (otherwise create new) - if (strlen(ID) < 19 || ID[2] != '-' || ID[5] != '-' || ID[10] != ' ' || ID[13] != ':' || ID[16] != ':') - { - ID = NULL; - } - else - { - SYSTEMTIME tm; - - ID[2] = ID[5] = ID[10] = ID[13] = ID[16] = 0; - - memset(&tm, 0, sizeof(tm)); - tm.wDay = (WORD)strtoul(ID, NULL, 10); - tm.wMonth = (WORD)strtoul(ID+3, NULL, 10); - tm.wYear = (WORD)strtoul(ID+6, NULL, 10); - tm.wHour = (WORD)strtoul(ID+11, NULL, 10); - tm.wMinute = (WORD)strtoul(ID+14, NULL, 10); - tm.wSecond = (WORD)strtoul(ID+17, NULL, 10); - - SYSTEMTIMEtoFILETIME(&tm, (FILETIME*)&newid); - } - } - else - { - ID = NULL; - } - - NewNoteEx(Tx,Ty,Tw,Th,Data,ID?&newid:NULL,V,(BOOL)OT,0,0,0,NULL,NULL,TRUE); - } - } -skip:; - } - - if (Value) - FreeSettingBlob(Size, Value); // we do not leak on bad setting - - NOTIFY_LIST(); -} - -void CloseNotesList() -{ - if (ListNotesVisible) - { - DestroyWindow(LV); - ListNotesVisible = FALSE; - } -} - -static void PurgeNotesTree() -{ - STICKYNOTE *pt; - - while (g_Stickies) // empty whole tree - { - pt = (STICKYNOTE*)g_Stickies->ptrdata; - if (pt->SNHwnd) DestroyWindow(pt->SNHwnd); - SAFE_FREE((void**)&pt->title); - SAFE_FREE((void**)&pt->data); - if (pt->pCustomFont) - { - DeleteObject(pt->pCustomFont->hFont); - free(pt->pCustomFont); - } - TreeDelete(&g_Stickies,pt); - SAFE_FREE((void**)&pt); - } - g_Stickies = NULL; -} - -void SaveNotes(void) -{ - JustSaveNotes(); - PurgeNotesTree(); -} - -void PurgeNotes(void) -{ - int NotesCount, I; - char ValueName[16]; - - NotesCount = ReadSettingInt(0,MODULENAME,"NotesData",0); - for(I = 0; I < NotesCount; I++) - { - sprintf(ValueName, "NotesData%d", I); - DBDeleteContactSetting(0,MODULENAME,ValueName); - } -} - -void OnDeleteNote(HWND hdlg, STICKYNOTE *SN) -{ - if (MessageBox(hdlg, Translate("Are you sure you want to delete this note?"), SECTIONNAME, MB_OKCANCEL) == IDOK) - { - DestroyWindow(hdlg); - TreeDelete(&g_Stickies,SN); - SAFE_FREE((void**)&SN->data); - if (SN->pCustomFont) - { - DeleteObject(SN->pCustomFont->hFont); - free(SN->pCustomFont); - } - SAFE_FREE((void**)&SN); - JustSaveNotes(); - } -} - -void DeleteNotes(void) -{ - PurgeNotes(); - WriteSettingInt(0, MODULENAME, "NotesData", 0); - PurgeNotesTree(); -} - -void ShowHideNotes(void) -{ - TREEELEMENT *TTE; - int bShow; - UINT nHideCount, nVisCount; - BOOL Visible; - - if (!g_Stickies) - return; - - // if some notes are hidden but others visible then first make all visible - // only toggle vis state if all are hidden or all are visible - - nHideCount = nVisCount = 0; - TTE = g_Stickies; - while (TTE) - { - if (((STICKYNOTE*)TTE->ptrdata)->Visible) - nVisCount++; - else - nHideCount++; - - TTE = (TREEELEMENT*)TTE->next; - } - - if (!nVisCount) - Visible = TRUE; - else if (!nHideCount) - Visible = FALSE; - else - Visible = TRUE; - - bShow = Visible ? SW_SHOWNA : SW_HIDE; - - TTE = g_Stickies; - while (TTE) - { - STICKYNOTE *SN = (STICKYNOTE*)TTE->ptrdata; - - if ((!Visible) != (!SN->Visible)) - { - ShowWindow(SN->SNHwnd, bShow); - SN->Visible = Visible; - } - - TTE = (TREEELEMENT*)TTE->next; - } - - JustSaveNotes(); -} - -void BringAllNotesToFront(STICKYNOTE *pActive) -{ - TREEELEMENT *TTE; - - if (!g_Stickies) - return; - - // NOTE: for some reason there are issues when bringing to top through hotkey while another app (like Explorer) - // is active, it refuses to move notes to top like it should with HWND_TOP. as a workaround still doesn't - // work 100% of the time, but at least more often, we first move not to top-most then for non-always-on-top - // notes we demote them back as a non top-most window - - TTE = g_Stickies; - while (TTE) - { - STICKYNOTE *SN = (STICKYNOTE*)TTE->ptrdata; - - if (SN->Visible && pActive != SN) - { - SetWindowPos(SN->SNHwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); - if (!SN->OnTop) - SetWindowPos(SN->SNHwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); - } - - TTE = (TREEELEMENT*)TTE->next; - } - - if (pActive) - { - SetWindowPos(pActive->SNHwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); - if (!pActive->OnTop) - SetWindowPos(pActive->SNHwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); - } -} - -static void JustSaveNotesEx(STICKYNOTE *pModified) -{ - // pModified optionally points to the modified note that invoked the JustSaveNotesEx call - - TREEELEMENT *TTE; - int I, NotesCount = TreeGetCount(g_Stickies); - int n, l; - char ValueName[32]; - WINDOWPLACEMENT wp; - int TX,TY,TW,TH; - DWORD flags; - int SzT; - int scrollV; - char *tData, *Value; - - const int OldNotesCount = ReadSettingInt(0, MODULENAME, "NotesData", 0); - - WriteSettingInt(0, MODULENAME, "NotesData", NotesCount); - - for (TTE = g_Stickies, I = 0; TTE; TTE = (TREEELEMENT*)TTE->next, I++) - { - STICKYNOTE *pNote = (STICKYNOTE*)TTE->ptrdata; - BOOL bDeleteTData = TRUE; - scrollV = 0; - tData = NULL; - - // window pos and size - wp.length = sizeof(WINDOWPLACEMENT); - GetWindowPlacement(pNote->SNHwnd, &wp); - TX = wp.rcNormalPosition.left; - TY = wp.rcNormalPosition.top; - TW = wp.rcNormalPosition.right - wp.rcNormalPosition.left; - TH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; - - // set flags - flags = 0; - if (pNote->Visible) flags |= 1; - if (pNote->OnTop) flags |= 2; - - // get note text - SzT = SendMessage(pNote->REHwnd, WM_GETTEXTLENGTH, 0, 0); - if (SzT) // TODO: change to support unicode and rtf, use EM_STREAMOUT - { - if (SzT > MAX_NOTE_LEN) SzT = MAX_NOTE_LEN; // we want to be far below the 64k limit - tData = (char*)malloc(SzT+1); - if (tData) - SendMessage(pNote->REHwnd, WM_GETTEXT, SzT+1, (LPARAM)tData); - } - - if (pNote == pModified) - { - // update the data of the modified note - if (pNote->data) - free(pNote->data); - pNote->data = tData ? tData : _strdup(""); - bDeleteTData = FALSE; - } - - if (!tData) - // empty note - SzT = 0; - else - // get current scroll position - scrollV = SendMessage(pNote->REHwnd, EM_GETFIRSTVISIBLELINE, 0, 0); - - // - - Value = (char*)malloc(SzT + 512); - - if (!Value) - { - if (bDeleteTData) - SAFE_FREE((void**)&tData); - continue; - } - - n = 0; - - // data header - l = sprintf(Value, "X%I64x:%d:%d:%d:%d:%x", pNote->ID.QuadPart, TX, TY, TW, TH, flags); - if (l > 0) n += l; - - // scroll pos - if (scrollV > 0) - { - l = sprintf(Value+n, "\033""%u:%u", DATATAG_SCROLLPOS, (UINT)scrollV); - if (l > 0) n += l; - } - - // custom bg color - if (pNote->BgColor) - { - l = sprintf(Value+n, "\033""%u:%x", DATATAG_BGCOL, (UINT)(pNote->BgColor&0xffffff)); - if (l > 0) n += l; - } - - // custom fg color - if (pNote->FgColor) - { - l = sprintf(Value+n, "\033""%u:%x", DATATAG_FGCOL, (UINT)(pNote->FgColor&0xffffff)); - if (l > 0) n += l; - } - - if (pNote->pCustomFont) - { - l = sprintf(Value+n, "\033""%u:%d:%u:%u:%s", DATATAG_FONT, - (int)pNote->pCustomFont->size, (UINT)pNote->pCustomFont->style, (UINT)pNote->pCustomFont->charset, - pNote->pCustomFont->szFace); - if (l > 0) n += l; - } - - // custom title - if (pNote->CustomTitle && pNote->title) - { - l = sprintf(Value+n, "\033""%u:%s", DATATAG_TITLE, pNote->title); - if (l > 0) n += l; - } - - // note text (ALWAYS PUT THIS PARAM LAST) - if (tData) - { - l = sprintf(Value+n, "\033""%u:%s", DATATAG_TEXT, tData); - if (l > 0) n += l; - } - - // clamp data size to WORD (including null terminator) - if (n >= 0xffff) - { - // huston, we have a problem, strip some reminder text - n = 0xfffe; - ValueName[0xffff] = 0; - } - - sprintf(ValueName, "NotesData%d", NotesCount - I - 1); // we do not reverse notes in DB - - WriteSettingBlob(0, MODULENAME, ValueName, (WORD)(n+1), Value); - - SAFE_FREE((void**)&Value); - if (bDeleteTData) - SAFE_FREE((void**)&tData); - - // make no save is queued for the note - if (pNote->SNHwnd) - KillTimer(pNote->SNHwnd, 1025); - } - - // delete any left over DB note entries - for(; I < OldNotesCount; I++) - { - sprintf(ValueName, "NotesData%d", I); - DBDeleteContactSetting(0,MODULENAME,ValueName); - } - - NOTIFY_LIST(); -} - -__inline void JustSaveNotes(void) -{ - JustSaveNotesEx(NULL); -} - - -///////////////////////////////////////////////////////////////////// -// Note Window - -static int FindMenuItem(HMENU h, LPTSTR lpszName) -{ - int n; - UINT i; - TCHAR s[128]; - - n = GetMenuItemCount(h); - - if (n <= 0) - { - return -1; - } - - // searches for a menu item based on name (used to avoid hardcoding item indices for sub-menus) - for (i=0; i<(UINT)n; i++) - { - if ( GetMenuString(h, i, s, 128, MF_BYPOSITION) ) - { - if ( !_tcscmp(s, lpszName) ) - { - return (int)i; - } - } - } - - return -1; -} - -static BOOL DoContextMenu(HWND AhWnd,WPARAM wParam,LPARAM lParam) -{ - int n, i; - STICKYNOTE *SN = (STICKYNOTE*)GetProp(AhWnd,"ctrldata"); - - HMENU hMenuLoad, FhMenu, hSub; - hMenuLoad = LoadMenu(hinstance,"MNU_NOTEPOPUP"); - FhMenu = GetSubMenu(hMenuLoad,0); - - if (SN->OnTop) - CheckMenuItem(FhMenu, IDM_TOGGLEONTOP, MF_CHECKED|MF_BYCOMMAND); - - EnableMenuItem(FhMenu, ID_CONTEXTMENUNOTEPOPUP_PASTETITLE, MF_BYCOMMAND | (IsClipboardFormatAvailable(CF_TEXT) ? MF_ENABLED : MF_GRAYED)); - - if (!SN->CustomTitle) - EnableMenuItem(FhMenu, ID_CONTEXTMENUNOTEPOPUP_RESETTITLE, MF_BYCOMMAND | MF_GRAYED); - - // NOTE: names used for FindMenuItem would need to include & chars if such shortcuts are added to the menus - - // color preset menu items uses features that require win2k or later, I'm too lazy to make a fallback path - // for obsolete OS versions (win95/98/ME users can still use the "Custom" menu option) - if (g_isWin2kPlus) - { - n = FindMenuItem(FhMenu, _T("Appearance")); - if (n >= 0 && (hSub = GetSubMenu(FhMenu, n))) - { - HMENU hBg = GetSubMenu(hSub, FindMenuItem(hSub, _T("Background Color"))); - HMENU hFg = GetSubMenu(hSub, FindMenuItem(hSub, _T("Text Color"))); - - for (i=0; iszName); - SIZE sz; - GetTextExtentPoint32(hdc, lpsz, _tcslen(lpsz), &sz); - ReleaseDC(hdlg, hdc); - - lpMeasureItem->itemWidth = 50 + sz.cx; - lpMeasureItem->itemHeight = (sz.cy+2)>18 ? sz.cy+2 : 18; -} - -static void PaintColorPresetMenuItem(LPDRAWITEMSTRUCT lpDrawItem, struct ColorPreset *clrPresets) -{ - UINT n = lpDrawItem->itemID - IDM_COLORPRESET_BG; - RECT rect; - rect.left = lpDrawItem->rcItem.left + 50; - rect.top = lpDrawItem->rcItem.top; - rect.right = lpDrawItem->rcItem.right; - rect.bottom = lpDrawItem->rcItem.bottom; - - if (lpDrawItem->itemState & ODS_SELECTED) - { - SetDCBrushColor(lpDrawItem->hDC, GetSysColor(COLOR_MENUHILIGHT)); - FillRect(lpDrawItem->hDC, &lpDrawItem->rcItem, (HBRUSH)GetStockObject(DC_BRUSH)); - - SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); - } - else - { - SetDCBrushColor(lpDrawItem->hDC, GetSysColor(COLOR_MENU)); - FillRect(lpDrawItem->hDC, &lpDrawItem->rcItem, (HBRUSH)GetStockObject(DC_BRUSH)); - - SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_MENUTEXT)); - } - - SetBkMode(lpDrawItem->hDC, TRANSPARENT); - DrawText(lpDrawItem->hDC,clrPresets->szName,-1,&rect,DT_LEFT | DT_SINGLELINE | DT_END_ELLIPSIS | DT_VCENTER); - - { - int h = lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top; - rect.left = lpDrawItem->rcItem.left + 5; - rect.top = lpDrawItem->rcItem.top + ((h-14)>>1); - rect.right = rect.left + 40; - rect.bottom = rect.top + 14; - - FrameRect(lpDrawItem->hDC, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH)); - rect.left++; rect.top++; - rect.right--; rect.bottom--; - SetDCBrushColor(lpDrawItem->hDC, clrPresets->color); - FillRect(lpDrawItem->hDC, &rect, (HBRUSH)GetStockObject(DC_BRUSH)); - } -} - -static BOOL GetClipboardText_Title(char *pOut, int size) -{ - BOOL bResult = FALSE; - - if ( OpenClipboard(NULL) ) - { - HANDLE hData = GetClipboardData(CF_TEXT); - LPCSTR buffer; - - if (hData && (buffer = (LPCSTR)GlobalLock(hData))) - { - // trim initial white spaces - while (*buffer && isspace(*buffer)) - buffer++; - - if (buffer) - { - char *p; - - int n = (int)strlen(buffer); - if (n >= size) - n = size-1; - memcpy(pOut, buffer, n); - pOut[n] = 0; - - // end string on line break and convert tabs to spaces - p = pOut; - while (*p) - { - if (*p == '\r' || *p == '\n') - { - *p = 0; - n = strlen(pOut); - break; - } - else if (*p == '\t') - { - *p = ' '; - } - p++; - } - - // trim trailing white spaces - while (n && isspace(pOut[n-1])) - pOut[--n] = 0; - - if (n) - bResult = TRUE; - } - - GlobalUnlock(hData); - } - - CloseClipboard(); - } - - return bResult; -} - -static void SetNoteTextControl(STICKYNOTE *SN) -{ - CHARFORMAT CF = {0}; - CF.cbSize = sizeof(CHARFORMAT); - CF.dwMask = CFM_COLOR; - CF.crTextColor = SN->FgColor ? (SN->FgColor&0xffffff) : BodyFontColor; - SendMessage(SN->REHwnd, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&CF); - - if (SN->data) // TODO: use EM_STREAMIN - SendMessage(SN->REHwnd, WM_SETTEXT, 0, (LPARAM)(SN->data)); -} - - -static UINT_PTR CALLBACK CFHookProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (msg == WM_INITDIALOG) - { - // hide color selector - ShowWindow(GetDlgItem(hdlg,0x443), SW_HIDE); - ShowWindow(GetDlgItem(hdlg,0x473), SW_HIDE); - TranslateDialogDefault(hdlg); - } - - return 0; -} - - -int CALLBACK StickyNoteWndProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) -{ - switch (message) - { - case WM_CLOSE: - return TRUE; - - case WM_SIZE: - { - HWND H; - RECT SZ; - - GetClientRect(hdlg,&SZ); - H = GetDlgItem(hdlg,1); - MoveWindow(H, 0, 0, SZ.right,SZ.bottom, TRUE); - - KillTimer(hdlg, 1025); - SetTimer(hdlg, 1025, NOTE_CHANGE_COMMIT_DELAY, 0); - - return TRUE; - } - case WM_TIMER: - if (wParam == 1025) - { - STICKYNOTE *SN = (STICKYNOTE*)GetProp(hdlg,"ctrldata"); - - KillTimer(hdlg, 1025); - JustSaveNotesEx(SN); - } - break; - case WM_MOVE: - { - KillTimer(hdlg, 1025); - SetTimer(hdlg, 1025, NOTE_CHANGE_COMMIT_DELAY, 0); - return TRUE; - } - case WM_CREATE: - { - STICKYNOTE *SN = (STICKYNOTE*)GetProp(hdlg,"ctrldata"); - - CREATESTRUCT *CS = (CREATESTRUCT *)lParam; - HWND H; - DWORD mystyle; - - SN = (STICKYNOTE*)CS->lpCreateParams; - SetProp(hdlg,"ctrldata",(HANDLE)SN); - BringWindowToTop(hdlg); - mystyle = WS_CHILD | WS_VISIBLE | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN; - if (g_ShowScrollbar) mystyle |= WS_VSCROLL; - H = CreateWindow(RICHEDIT_CLASS, 0, mystyle, 0, 0, CS->cx-3-3, CS->cy-3-(3+14), hdlg, (HMENU)1, hmiranda, 0); - SN->REHwnd = H; - SendMessage(H, EM_SETTEXTMODE, TM_PLAINTEXT, 0); - SendMessage(H, EM_LIMITTEXT, MAX_NOTE_LEN, 0); - SendMessage(H, WM_SETFONT, (WPARAM)(SN->pCustomFont ? SN->pCustomFont->hFont : hBodyFont), 1); - SendMessage(H, EM_SETEVENTMASK, 0, ENM_CHANGE | ENM_LINK); - SendMessage(H, EM_SETBKGNDCOLOR, 0, SN->BgColor ? (SN->BgColor&0xffffff) : BodyColor); - SendMessage(H, EM_AUTOURLDETECT, 1, 0); - SetNoteTextControl(SN); - return TRUE; - } - case WM_GETMINMAXINFO: - { - MINMAXINFO *mm = (MINMAXINFO*)lParam; - // min width accomodates frame, buttons and some extra space for sanity - mm->ptMinTrackSize.x = 48+3+3+8 + 40; - // min height allows collapsing entire client area, only leaving frame and caption - mm->ptMinTrackSize.y = 3+3+14; - } - return 0; - case WM_ERASEBKGND: - // no BG needed as edit control takes up entire client area - return TRUE; - case WM_NCPAINT: - // make window borders have the same color as caption - { - STICKYNOTE *SN = (STICKYNOTE*)GetProp(hdlg,"ctrldata"); - - HBRUSH hBkBrush; - RECT rect, wr, r; - //HDC hdc = GetDCEx(hdlg, (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN); - HDC hdc = GetWindowDC(hdlg); - - GetWindowRect(hdlg, &wr); - if (wParam && wParam != 1) - { - SelectClipRgn(hdc, (HRGN)wParam); - OffsetClipRgn(hdc, -wr.left, -wr.top); - } - - rect = wr; - OffsetRect(&rect, -wr.left, -wr.top); - - if (g_isWin2kPlus) - { - hBkBrush = (HBRUSH)GetStockObject(DC_BRUSH); - SetDCBrushColor(hdc, GetCaptionColor((SN && SN->BgColor) ? SN->BgColor : BodyColor)); - } - else - { - hBkBrush = (HBRUSH)CreateSolidBrush( GetCaptionColor((SN && SN->BgColor) ? SN->BgColor : BodyColor) ); - } - - //FillRect(hdc, &rect, hBkBrush); - // draw all frame sides separately to avoid filling client area (which flickers) - { - // top - r.left = rect.left; r.right = rect.right; - r.top = rect.top; r.bottom = r.top + 3+14; - FillRect(hdc, &r, hBkBrush); - // bottom - r.top = rect.bottom - 3; r.bottom = rect.bottom; - FillRect(hdc, &r, hBkBrush); - // left - r.left = rect.left; r.right = r.left + 3; - r.top = rect.top + 3+14; r.bottom = rect.bottom - 3; - FillRect(hdc, &r, hBkBrush); - // right - r.left = rect.right - 3; r.right = rect.right; - FillRect(hdc, &r, hBkBrush); - } - if (hBkBrush && !g_isWin2kPlus) DeleteObject(hBkBrush); - - // paint title bar contents (time stamp and buttons) - - if (SN && SN->title) - { - RECT R; - SelectObject(hdc,hCaptionFont); - R.top = 3+1; R.bottom = 3+11; R.left = 3+2; R.right = rect.right-3-1; - if (g_ShowNoteButtons) - R.right -= 48; - - SetTextColor(hdc,SN->FgColor ? (SN->FgColor&0xffffff) : CaptionFontColor); - SetBkMode(hdc, TRANSPARENT); - DrawText(hdc,SN->title,-1,&R,DT_LEFT | DT_SINGLELINE | DT_END_ELLIPSIS | DT_VCENTER); - } - - if (g_ShowNoteButtons) - { - HICON hcIcon; - if (SN->OnTop) - hcIcon = Skin_GetIconByHandle(hIconLibItem[4]); - else - hcIcon = Skin_GetIconByHandle(hIconLibItem[7]); - DrawIcon(hdc, wr.right - wr.left - 16, 0 + 3, hcIcon); - Skin_ReleaseIcon(hcIcon); - - hcIcon = Skin_GetIconByHandle(hIconLibItem[9]); - DrawIcon(hdc, wr.right - wr.left - 32, 1 + 3, hcIcon); - Skin_ReleaseIcon(hcIcon); - - hcIcon = Skin_GetIconByHandle(hIconLibItem[8]); - DrawIcon(hdc, wr.right - wr.left - 48, 1 + 3, hcIcon); - Skin_ReleaseIcon(hcIcon); - } - - if (wParam && wParam != 1) - { - SelectClipRgn(hdc, NULL); - } - - ReleaseDC(hdlg, hdc); - return TRUE; - } - case WM_NCCALCSIZE: - { - RECT *pRect = wParam ? &((NCCALCSIZE_PARAMS*)lParam)->rgrc[0] : (RECT*)lParam; - pRect->bottom -= 3; - pRect->right -= 3; - pRect->left += 3; - pRect->top += 3+14; - return WVR_REDRAW; - } - case WM_NCACTIVATE: - // update window (so that parts that potentially became visible through activation get redrawn immediately) - RedrawWindow(hdlg, NULL, NULL, RDW_UPDATENOW); - return TRUE; - case WM_NOTIFY: - if (LOWORD(wParam) == 1) - { - char *Buff; - PENLINK PEnLnk = (PENLINK)lParam; - - if (PEnLnk->msg == WM_LBUTTONDOWN) - { - SendDlgItemMessage(hdlg,1,EM_EXSETSEL,0,(LPARAM)&(PEnLnk->chrg)); - Buff = (char*)malloc(PEnLnk->chrg.cpMax - PEnLnk->chrg.cpMin + 1); - SendDlgItemMessage(hdlg,1,EM_GETSELTEXT,0,(LPARAM)Buff); - if ((GetAsyncKeyState(VK_CONTROL) >> 15) != 0) - ShellExecute(hdlg,"open","iexplore",Buff,"",SW_SHOWNORMAL); - else if (g_lpszAltBrowser && *g_lpszAltBrowser) - ShellExecute(hdlg,"open",g_lpszAltBrowser,Buff,"",SW_SHOWNORMAL); - else - ShellExecute(hdlg,"open",Buff,"","",SW_SHOWNORMAL); - SAFE_FREE((void**)&Buff); - return TRUE; - } - return FALSE; - } - break; - case WM_NCHITTEST: - { - int r = DefWindowProc(hdlg,message,wParam,lParam); - // filter out potential hits on windows default title bar buttons - switch (r) - { - case HTSYSMENU: - case HTCLOSE: - case HTMINBUTTON: - case HTMAXBUTTON: - return HTCAPTION; - } - return r; - } - case WM_NCLBUTTONDOWN: - if (wParam == HTCAPTION && g_ShowNoteButtons) - { - long X,Y; - RECT rect; - int Tw; - - GetWindowRect(hdlg, &rect); - Tw = rect.right - rect.left; - - X = LOWORD(lParam) - rect.left; - Y = HIWORD(lParam) - rect.top; - - if (X > Tw - 16) - { - SendMessage(hdlg,WM_COMMAND,IDM_TOGGLEONTOP,0); - return TRUE; - } - else if (X > Tw - 31 && X < Tw - 16) - { - SendMessage(hdlg,WM_COMMAND,IDM_REMOVENOTE,0); - return TRUE; - } - else if (X > Tw - 48 && X < Tw - 32) - { - SendMessage(hdlg,WM_COMMAND,IDM_HIDENOTE,0); - return TRUE; - } - } - return DefWindowProc(hdlg,message,wParam,lParam); - case WM_MEASUREITEM: - { - LPMEASUREITEMSTRUCT lpMeasureItem = (LPMEASUREITEMSTRUCT)lParam; - - if (lpMeasureItem->CtlType != ODT_MENU) - break; - - if (lpMeasureItem->itemID >= IDM_COLORPRESET_BG && lpMeasureItem->itemID <= IDM_COLORPRESET_BG+SIZEOF(clrPresets)) - { - MeasureColorPresetMenuItem(hdlg, lpMeasureItem, clrPresets + (lpMeasureItem->itemID - IDM_COLORPRESET_BG)); - return TRUE; - } - else if (lpMeasureItem->itemID >= IDM_COLORPRESET_FG && lpMeasureItem->itemID <= IDM_COLORPRESET_FG+SIZEOF(clrPresets)) - { - MeasureColorPresetMenuItem(hdlg, lpMeasureItem, clrPresets + (lpMeasureItem->itemID - IDM_COLORPRESET_FG)); - return TRUE; - } - } - break; - case WM_DRAWITEM: - if (!wParam) - { - LPDRAWITEMSTRUCT lpDrawItem = (LPDRAWITEMSTRUCT)lParam; - - if (lpDrawItem->CtlType != ODT_MENU) - break; - - if (lpDrawItem->itemID >= IDM_COLORPRESET_BG && lpDrawItem->itemID <= IDM_COLORPRESET_BG+SIZEOF(clrPresets)) - { - PaintColorPresetMenuItem(lpDrawItem, clrPresets + (lpDrawItem->itemID - IDM_COLORPRESET_BG)); - return TRUE; - } - else if (lpDrawItem->itemID >= IDM_COLORPRESET_FG && lpDrawItem->itemID <= IDM_COLORPRESET_FG+SIZEOF(clrPresets)) - { - PaintColorPresetMenuItem(lpDrawItem, clrPresets + (lpDrawItem->itemID - IDM_COLORPRESET_FG)); - return TRUE; - } - } - break; - case WM_COMMAND: - { - STICKYNOTE *SN = (STICKYNOTE*)GetProp(hdlg,"ctrldata"); - - HWND H; - UINT id; - - switch ( HIWORD(wParam) ) - { - case EN_CHANGE: - case EN_VSCROLL: - case EN_HSCROLL: - { - KillTimer(hdlg,1025); - SetTimer(hdlg, 1025, NOTE_CHANGE_COMMIT_DELAY, 0); - } - break; - } - - id = (UINT) LOWORD(wParam); - - H = SN->REHwnd; - - if (id >= IDM_COLORPRESET_BG && id <= IDM_COLORPRESET_BG+SIZEOF(clrPresets)) - { - SN->BgColor = clrPresets[id-IDM_COLORPRESET_BG].color | 0xff000000; - SendMessage(H, EM_SETBKGNDCOLOR, 0, (LPARAM)(SN->BgColor&0xffffff)); - RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); - JustSaveNotes(); - return FALSE; - } - else if (id >= IDM_COLORPRESET_FG && id <= IDM_COLORPRESET_FG+SIZEOF(clrPresets)) - { - CHARFORMAT CF = {0}; - SN->FgColor = clrPresets[id-IDM_COLORPRESET_FG].color | 0xff000000; - CF.cbSize = sizeof(CHARFORMAT); - CF.dwMask = CFM_COLOR; - CF.crTextColor = SN->FgColor & 0xffffff; - SendMessage(H, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&CF); - RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); - JustSaveNotes(); - return FALSE; - } - - switch (id) - { - case ID_CONTEXTMENUNOTEPOPUP_NEWNOTE: - { - PluginMenuCommandAddNew(0,0); - } - break; - case ID_APPEARANCE_CUSTOMBG: - { - COLORREF custclr[16] = {0}; - CHOOSECOLOR cc = {0}; - COLORREF orgclr = SN->BgColor ? (COLORREF)(SN->BgColor&0xffffff) : (COLORREF)(BodyColor&0xffffff); - cc.lStructSize = sizeof(cc); - cc.hwndOwner = SN->SNHwnd; - cc.rgbResult = orgclr; - cc.Flags = CC_ANYCOLOR | CC_FULLOPEN | CC_RGBINIT | CC_SOLIDCOLOR; - cc.lpCustColors = custclr; - - if (ChooseColor(&cc) && cc.rgbResult != orgclr) - { - SN->BgColor = cc.rgbResult | 0xff000000; - SendMessage(H, EM_SETBKGNDCOLOR, 0, (LPARAM)(SN->BgColor&0xffffff)); - RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); - JustSaveNotes(); - } - } - break; - case ID_APPEARANCE_CUSTOMTEXT: - { - COLORREF custclr[16] = {0}; - CHOOSECOLOR cc = {0}; - COLORREF orgclr = SN->FgColor ? (COLORREF)(SN->FgColor&0xffffff) : (COLORREF)(BodyFontColor&0xffffff); - cc.lStructSize = sizeof(cc); - cc.hwndOwner = SN->SNHwnd; - cc.rgbResult = orgclr; - cc.Flags = CC_ANYCOLOR | CC_FULLOPEN | CC_RGBINIT | CC_SOLIDCOLOR; - cc.lpCustColors = custclr; - - if (ChooseColor(&cc) && cc.rgbResult != orgclr) - { - CHARFORMAT CF = {0}; - SN->FgColor = cc.rgbResult | 0xff000000; - CF.cbSize = sizeof(CHARFORMAT); - CF.dwMask = CFM_COLOR; - CF.crTextColor = SN->FgColor & 0xffffff; - SendMessage(H, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&CF); - RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); - JustSaveNotes(); - } - } - break; - case ID_APPEARANCE_CUSTOMFONT: - { - CHOOSEFONT cf = {0}; - LOGFONT lf = {0}; - - if (SN->pCustomFont) - InitStickyNoteLogFont(SN->pCustomFont, &lf); - else - LoadNRFont(NR_FONTID_BODY, &lf, NULL); - - cf.lStructSize = sizeof(cf); - cf.hwndOwner = SN->SNHwnd; - cf.lpLogFont = &lf; - cf.Flags = CF_EFFECTS | CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_ENABLEHOOK; - cf.lpfnHook = CFHookProc; - - if ( ChooseFont(&cf) ) - { - if (!SN->pCustomFont) - { - SN->pCustomFont = (STICKYNOTEFONT*)malloc(sizeof(STICKYNOTEFONT)); - SN->pCustomFont->hFont = NULL; - } - - SN->pCustomFont->size = (char)lf.lfHeight; - SN->pCustomFont->style = (lf.lfWeight >= FW_BOLD ? DBFONTF_BOLD : 0) | (lf.lfItalic ? DBFONTF_ITALIC : 0) | (lf.lfUnderline ? DBFONTF_UNDERLINE : 0) | (lf.lfStrikeOut ? DBFONTF_STRIKEOUT : 0); - SN->pCustomFont->charset = lf.lfCharSet; - _tcscpy(SN->pCustomFont->szFace, lf.lfFaceName); - - if ( !CreateStickyNoteFont(SN->pCustomFont, &lf) ) - { - // failed - free(SN->pCustomFont); - SN->pCustomFont = NULL; - } - - // clear text first to force a reformatting w.r.t scrollbar - SendMessage(H, WM_SETTEXT, 0, (LPARAM)""); - SendMessage(H, WM_SETFONT, (WPARAM)(SN->pCustomFont ? SN->pCustomFont->hFont : hBodyFont), FALSE); - SetNoteTextControl(SN); - RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); - JustSaveNotes(); - } - } - break; - case ID_BACKGROUNDCOLOR_RESET: - { - SN->BgColor = 0; - SendMessage(H, EM_SETBKGNDCOLOR, 0, (LPARAM)BodyColor); - RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); - JustSaveNotes(); - } - break; - case ID_TEXTCOLOR_RESET: - { - CHARFORMAT CF = {0}; - SN->FgColor = 0; - CF.cbSize = sizeof(CHARFORMAT); - CF.dwMask = CFM_COLOR; - CF.crTextColor = BodyFontColor; - SendMessage(H, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&CF); - RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); - JustSaveNotes(); - } - break; - case ID_FONT_RESET: - { - if (SN->pCustomFont) - { - DeleteObject(SN->pCustomFont->hFont); - free(SN->pCustomFont); - SN->pCustomFont = NULL; - - // clear text first to force a reformatting w.r.t scrollbar - SendMessage(H, WM_SETTEXT, 0, (LPARAM)""); - SendMessage(H, WM_SETFONT, (WPARAM)hBodyFont, FALSE); - SetNoteTextControl(SN); - RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); - JustSaveNotes(); - } - } - break; - case ID_CONTEXTMENUNOTEPOPUP_PASTETITLE: - { - char s[MAX_TITLE_LEN+1]; - if ( GetClipboardText_Title(s, sizeof(s)) ) - { - if (SN->title) - free(SN->title); - SN->title = _strdup(s); - SN->CustomTitle = TRUE; - RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); - JustSaveNotes(); - } - } - break; - case ID_CONTEXTMENUNOTEPOPUP_RESETTITLE: - if (SN->CustomTitle) - { - if (SN->title) - { - free(SN->title); - SN->title = NULL; - } - InitNoteTitle(SN); - RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); - JustSaveNotes(); - } - break; - case IDM_REMOVENOTE: - OnDeleteNote(hdlg, SN); - break; - case IDM_HIDENOTE: - { - SN->Visible = FALSE; - ShowWindow(hdlg,SW_HIDE); - JustSaveNotes(); - } - break; - case IDM_COPY: SendMessage(H,WM_COPY,0,0); break; - case IDM_PASTE: SendMessage(H,WM_PASTE,0,0); break; - case IDM_CUT: SendMessage(H,WM_CUT,0,0); break; - case IDM_CLEAR: SendMessage(H,WM_CLEAR,0,0); break; - case IDM_UNDO: SendMessage(H,WM_UNDO,0,0); break; - case IDM_TOGGLEONTOP: - { - SN->OnTop = !SN->OnTop; - SetWindowPos(hdlg, SN->OnTop ? HWND_TOPMOST : HWND_NOTOPMOST, 0,0,0,0, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE); - RedrawWindow(hdlg, NULL, NULL, RDW_FRAME|RDW_INVALIDATE|RDW_UPDATENOW); - JustSaveNotes(); - } - break; - case ID_CONTEXTMENUNOTEPOPUP_VIEWNOTES: - ListNotes(); - break; - case ID_CONTEXTMENUNOTEPOPUP_BRINGALLTOTOP: - BringAllNotesToFront(SN); - break; - } - return TRUE; - } - case WM_NCDESTROY: - { - RemoveProp(hdlg, "ctrldata"); - } - break; - case WM_CONTEXTMENU: - if (DoContextMenu(hdlg,wParam,lParam)) return FALSE; - - default: - return DefWindowProc(hdlg,message,wParam,lParam); - } - return FALSE; -} - - -///////////////////////////////////////////////////////////////////// -// Notes List Dialog (uses same dialog template as reminder list) - -void ListNotes(void) -{ - if (!ListNotesVisible) - { - CreateDialog(hinstance, MAKEINTRESOURCE(IDD_LISTREMINDERS), 0, DlgProcViewNotes); - ListNotesVisible = TRUE; - } - else - { - BringWindowToTop(LV); - } -} - -static void EditNote(STICKYNOTE *SN) -{ - if (!SN) - return; - - if (!SN->Visible) - { - SN->Visible = TRUE; - JustSaveNotes(); - } - - SetWindowPos(SN->SNHwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); - if (!SN->OnTop) - SetWindowPos(SN->SNHwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); - - SetFocus(SN->REHwnd); -} - -char* GetPreviewString(const char *lpsz) -{ - int l; - char *p; - const int MaxLen = 80; - static char s[80+8]; - - if (!lpsz) - return ""; - - // trim leading spaces - while ( iswspace(*lpsz) ) - lpsz++; - - l = strlen(lpsz); - - if (!l) - return ""; - - if (l <= MaxLen) - { - strcpy(s, lpsz); - } - else - { - memcpy(s, lpsz, MaxLen); - s[MaxLen] = '.'; - s[MaxLen+1] = '.'; - s[MaxLen+2] = '.'; - s[MaxLen+3] = 0; - } - - if (!s) - return NULL; - - // convert line breaks and tabs to spaces - - p = s; - - while (*p) - { - if ( iswspace(*p) ) - *p = ' '; - p++; - } - - return s; -} - -static void InitListView(HWND AHLV) -{ - LV_ITEM lvTIt; - int I; - char *S; - char S1[128]; - STICKYNOTE *pNote; - TREEELEMENT *TTE; - - char *V = Translate("V"); - char *T = Translate("T"); - - ListView_SetHoverTime(AHLV,700); - ListView_SetExtendedListViewStyle(AHLV,LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_TRACKSELECT); - ListView_DeleteAllItems(AHLV); - - I = 0; - TTE = g_Stickies; - while (TTE) - { - pNote = (STICKYNOTE*)TTE->ptrdata; - - lvTIt.mask = LVIF_TEXT; - - if (!pNote->CustomTitle || !pNote->title) - GetTriggerTimeString(&pNote->ID, S1, sizeof(S1), TRUE); - - lvTIt.iItem = I; - lvTIt.iSubItem = 0; - lvTIt.pszText = (pNote->CustomTitle && pNote->title) ? pNote->title : S1; - lvTIt.cchTextMax = strlen(S1); - ListView_InsertItem(AHLV,&lvTIt); - - if (pNote->Visible) - { - lvTIt.iItem = I; - lvTIt.iSubItem = 1; - lvTIt.pszText = V; - lvTIt.cchTextMax = strlen(lvTIt.pszText); - ListView_SetItem(AHLV,&lvTIt); - } - - if (pNote->OnTop) - { - lvTIt.iItem = I; - lvTIt.iSubItem = 2; - lvTIt.pszText = T; - lvTIt.cchTextMax = strlen(lvTIt.pszText); - ListView_SetItem(AHLV,&lvTIt); - } - - S = GetPreviewString(pNote->data); - lvTIt.iItem = I; - lvTIt.iSubItem = 3; - lvTIt.pszText = S; - lvTIt.cchTextMax = strlen(S); - ListView_SetItem(AHLV,&lvTIt); - - I++; - TTE = (TREEELEMENT*)TTE->next; - } - - ListView_SetItemState(AHLV,0,LVIS_SELECTED,LVIS_SELECTED); -} - -static BOOL DoListContextMenu(HWND AhWnd,WPARAM wParam,LPARAM lParam,STICKYNOTE *pNote) -{ - HWND hwndListView; - HMENU hMenuLoad,FhMenu; - MENUITEMINFO mii; - - hwndListView = (HWND)wParam; - if (hwndListView != GetDlgItem(AhWnd,IDC_LISTREMINDERS)) return FALSE; - hMenuLoad = LoadMenu(hinstance,"MNU_NOTELISTPOPUP"); - FhMenu = GetSubMenu(hMenuLoad,0); - - mii.cbSize = sizeof(mii); - mii.fMask = MIIM_STATE; - mii.fState = MFS_DEFAULT; - if (!pNote) - mii.fState |= MFS_GRAYED; - SetMenuItemInfo(FhMenu, ID_CONTEXTMENUNOTELISTVIEW_EDITNOTE, FALSE, &mii); - - if (!pNote) - { - EnableMenuItem(FhMenu, IDM_REMOVENOTE, MF_GRAYED|MF_BYCOMMAND); - EnableMenuItem(FhMenu, ID_CONTEXTMENUNOTELISTVIEW_TOGGLEVISIBILITY, MF_GRAYED|MF_BYCOMMAND); - EnableMenuItem(FhMenu, IDM_TOGGLEONTOP, MF_GRAYED|MF_BYCOMMAND); - } - else - { - if (pNote->Visible) - CheckMenuItem(FhMenu, ID_CONTEXTMENUNOTELISTVIEW_TOGGLEVISIBILITY, MF_CHECKED|MF_BYCOMMAND); - if (pNote->OnTop) - CheckMenuItem(FhMenu, IDM_TOGGLEONTOP, MF_CHECKED|MF_BYCOMMAND); - } - - CallService(MS_LANGPACK_TRANSLATEMENU,(DWORD)FhMenu,0); - TrackPopupMenu(FhMenu,TPM_LEFTALIGN | TPM_RIGHTBUTTON,LOWORD(lParam),HIWORD(lParam),0,AhWnd,0); - DestroyMenu(hMenuLoad); - - return TRUE; -} - - -int CALLBACK DlgProcViewNotes(HWND Dialog,UINT Message,WPARAM wParam,LPARAM lParam) -{ - LV_COLUMN lvCol; - NMLISTVIEW *NM; - char *S; - int I; - - switch (Message) - { - case WM_SIZE: - { - OnListResize(Dialog); - UpdateGeomFromWnd(Dialog, g_notesListGeom, NULL, 0); - break; - } - case WM_MOVE: - UpdateGeomFromWnd(Dialog, g_notesListGeom, NULL, 0); - break; - case WM_GETMINMAXINFO: - { - MINMAXINFO *mm = (MINMAXINFO*)lParam; - mm->ptMinTrackSize.x = 394; - mm->ptMinTrackSize.y = 300; - } - return 0; - case WM_RELOAD: - { - SetDlgItemText(Dialog,IDC_REMINDERDATA,""); - InitListView(GetDlgItem(Dialog,IDC_LISTREMINDERS)); - return TRUE; - } - case WM_CONTEXTMENU: - { - HWND H; - STICKYNOTE *pNote = NULL; - - H = GetDlgItem(Dialog,IDC_LISTREMINDERS); - if ( ListView_GetSelectedCount(H) ) - { - I = ListView_GetSelectionMark(H); - if (I != -1) - { - pNote = (STICKYNOTE*)TreeGetAt(g_Stickies, I); - } - } - - if (DoListContextMenu(Dialog, wParam, lParam, pNote)) - return TRUE; - } - break; - case WM_INITDIALOG: - { - HWND H; - - HICON hIcon = Skin_GetIconByHandle(hIconLibItem[13], ICON_SMALL); - SendMessage(Dialog, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIcon); - hIcon = Skin_GetIconByHandle(hIconLibItem[13], ICON_BIG); - SendMessage(Dialog, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hIcon); - - SetWindowText(Dialog, _T("Notes")); - - TranslateDialogDefault(Dialog); - - SetDlgItemText(Dialog,IDC_REMINDERDATA,""); - - H = GetDlgItem(Dialog,IDC_LISTREMINDERS); - lvCol.mask = LVCF_TEXT | LVCF_WIDTH; - - S = Translate("Note text"); - lvCol.pszText = S; - lvCol.cchTextMax = strlen(S); - lvCol.cx = g_notesListColGeom[3]; - ListView_InsertColumn(H,0,&lvCol); - lvCol.mask = LVCF_TEXT | LVCF_WIDTH; - - S = Translate("T"); - lvCol.pszText = S; - lvCol.cchTextMax = strlen(S); - lvCol.cx = g_notesListColGeom[2]; - ListView_InsertColumn(H,0,&lvCol); - lvCol.mask = LVCF_TEXT | LVCF_WIDTH; - - S = Translate("V"); - lvCol.pszText = S; - lvCol.cchTextMax = strlen(S); - lvCol.cx = g_notesListColGeom[1]; - ListView_InsertColumn(H,0,&lvCol); - lvCol.mask = LVCF_TEXT | LVCF_WIDTH; - - S = Translate("Date/Title"); - lvCol.pszText = S; - lvCol.cchTextMax = strlen(S); - lvCol.cx = g_notesListColGeom[0]; - ListView_InsertColumn(H,0,&lvCol); - - InitListView(H); - SetWindowLong(GetDlgItem(H, 0), GWL_ID, IDC_LISTREMINDERS_HEADER); - LV = Dialog; - - if (g_notesListGeom[1] && g_notesListGeom[2]) - { - WINDOWPLACEMENT wp; - wp.length = sizeof(WINDOWPLACEMENT); - GetWindowPlacement(Dialog, &wp); - wp.rcNormalPosition.left = g_notesListGeom[0]; - wp.rcNormalPosition.top = g_notesListGeom[1]; - wp.rcNormalPosition.right = g_notesListGeom[2] + g_notesListGeom[0]; - wp.rcNormalPosition.bottom = g_notesListGeom[3] + g_notesListGeom[1]; - SetWindowPlacement(Dialog, &wp); - } - return TRUE; - } - case WM_CLOSE: - { - DestroyWindow(Dialog); - ListNotesVisible = FALSE; - return TRUE; - } - case WM_DESTROY: - ListNotesVisible = FALSE; - CallService(MS_SKIN2_RELEASEICONBIG, (WPARAM)SendMessage(Dialog, WM_SETICON, ICON_BIG, (LPARAM)NULL), 0); - CallService(MS_SKIN2_RELEASEICON, (WPARAM)SendMessage(Dialog, WM_SETICON, ICON_SMALL, (LPARAM)NULL), 0); - return TRUE; - case WM_NOTIFY: - { - if (wParam == IDC_LISTREMINDERS) - { - NM = (NMLISTVIEW *)lParam; - switch (NM->hdr.code) - { - case LVN_ITEMCHANGED: - { - S = ((STICKYNOTE*)TreeGetAt(g_Stickies,NM->iItem))->data; - SetDlgItemText(Dialog,IDC_REMINDERDATA,S); - } - break; - case NM_DBLCLK: - { - HWND H; - - H = GetDlgItem(Dialog,IDC_LISTREMINDERS); - if ( ListView_GetSelectedCount(H) ) - { - I = ListView_GetSelectionMark(H); - if (I != -1) - { - EditNote((STICKYNOTE *)TreeGetAt(g_Stickies, I)); - } - } - } - break; - } - } - else if (wParam == IDC_LISTREMINDERS_HEADER) - { - NMHEADER *NM = (NMHEADER*)lParam; - switch (NM->hdr.code) - { - case HDN_ENDTRACK: - UpdateGeomFromWnd(Dialog, NULL, g_notesListColGeom, SIZEOF(g_notesListColGeom)); - break; - } - } - } - break; - case WM_COMMAND: - { - switch(LOWORD(wParam)) - { - case ID_CONTEXTMENUNOTELISTVIEW_EDITNOTE: - { - HWND H; - - H = GetDlgItem(Dialog,IDC_LISTREMINDERS); - if ( ListView_GetSelectedCount(H) ) - { - I = ListView_GetSelectionMark(H); - if (I != -1) - { - EditNote((STICKYNOTE*)TreeGetAt(g_Stickies, I)); - } - } - } - return TRUE; - case ID_CONTEXTMENUNOTELISTVIEW_TOGGLEVISIBILITY: - { - HWND H; - - H = GetDlgItem(Dialog,IDC_LISTREMINDERS); - if ( ListView_GetSelectedCount(H) ) - { - I = ListView_GetSelectionMark(H); - if (I != -1) - { - STICKYNOTE *SN = (STICKYNOTE*)TreeGetAt(g_Stickies, I); - SN->Visible = !SN->Visible; - ShowWindow(SN->SNHwnd,SN->Visible?SW_SHOWNA:SW_HIDE); - JustSaveNotes(); - } - } - } - return TRUE; - case IDM_TOGGLEONTOP: - { - HWND H; - - H = GetDlgItem(Dialog,IDC_LISTREMINDERS); - if ( ListView_GetSelectedCount(H) ) - { - I = ListView_GetSelectionMark(H); - if (I != -1) - { - STICKYNOTE *SN = (STICKYNOTE*)TreeGetAt(g_Stickies,I); - SN->OnTop = !SN->OnTop; - SetWindowPos(SN->SNHwnd, SN->OnTop ? HWND_TOPMOST : HWND_NOTOPMOST, 0,0,0,0, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE); - RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_FRAME|RDW_INVALIDATE|RDW_UPDATENOW); - JustSaveNotes(); - } - } - } - return TRUE; - case IDC_CLOSE: - { - DestroyWindow(Dialog); - ListNotesVisible = FALSE; - return TRUE; - } - case ID_CONTEXTMENUNOTEPOPUP_NEWNOTE: - case IDC_ADDNEWREMINDER: - { - PluginMenuCommandAddNew(0,0); - return TRUE; - } - case ID_CONTEXTMENUNOTELISTVIEW_DELETEALLNOTES: - { - PluginMenuCommandDeleteAll(0,0); - return TRUE; - } - case IDM_REMOVENOTE: - { - HWND H; - - H = GetDlgItem(Dialog,IDC_LISTREMINDERS); - if ( ListView_GetSelectedCount(H) ) - { - I = ListView_GetSelectionMark(H); - if (I != -1) - { - OnDeleteNote(Dialog, (STICKYNOTE*)TreeGetAt(g_Stickies, I)); - } - } - } - return TRUE; - case ID_CONTEXTMENUNOTELISTVIEW_SHOW: - { - ShowHideNotes(); - return TRUE; - } - case ID_CONTEXTMENUNOTEPOPUP_BRINGALLTOTOP: - { - BringAllNotesToFront(NULL); - return TRUE; - } - } - } - } - return FALSE; -} diff --git a/!NotAdopted/NotesAndReminders/src/options.cpp b/!NotAdopted/NotesAndReminders/src/options.cpp deleted file mode 100644 index 8e15946db9..0000000000 --- a/!NotAdopted/NotesAndReminders/src/options.cpp +++ /dev/null @@ -1,637 +0,0 @@ -#include "globals.h" - -#ifndef OFN_DONTADDTORECENT -#define OFN_DONTADDTORECENT 0x02000000 -#endif - - -// min allowed alpha (don't want 0 because it's a waste of resources as well as might confuse user) -#define MIN_ALPHA 30 - - -#define IDC_RESET 1007 -#define IDC_SHOWNOTES 1010 -#define IDC_ADDCONTACTMENU 1011 -#define IDC_NOTEWIDTH 1012 -#define IDC_NOTEHEIGHT 1013 -#define IDC_TRANSTRACK 1014 -#define IDC_REMINDEMAIL 1017 -#define IDC_SHOWSCROLLBAR 1018 -#define IDC_SHOWBUTTONS 1019 -#define IDC_ADDREMINDERCLOSES 1020 -#define IDC_USEMCI 1023 -#define PSM_CHANGED (WM_USER + 104) - - -extern HANDLE hkFontChange; -extern HANDLE hkColorChange; - -BOOL g_CloseAfterAddReminder, g_UseDefaultPlaySound; -HICON g_hReminderIcon = NULL; - -LOGFONT lfBody,lfCaption; -HFONT hBodyFont = NULL, hCaptionFont = NULL; -long BodyColor; -long CaptionFontColor,BodyFontColor; -BOOL g_ShowNotesAtStart,g_ShowScrollbar,g_AddContListMI,g_ShowNoteButtons; -int g_NoteTitleDate, g_NoteTitleTime; -int g_NoteWidth,g_NoteHeight; -int g_Transparency; -char *g_RemindSMS = NULL; -BOOL g_isWin2kPlus = TRUE; - -TCHAR *g_lpszAltBrowser = NULL; - -int g_reminderListGeom[4] = {0}; -int g_reminderListColGeom[2] = { 150, 205 }; -int g_notesListGeom[4] = {0}; -int g_notesListColGeom[4] = { 150, 20, 20, 165 }; - - -#define NRCDEFAULT_BODYCLR RGB(255,255,0) - - -struct DateFormat -{ - LPCSTR lpszUI; - LPCSTR lpszFmt; -} -static dateFormats[] = -{ - { "1981-12-31", "yyyy'-'MM'-'dd" }, - { "31-12-1981", "dd'-'MM'-'yyyy" }, - { "12-31-1981", "MM'-'dd'-'yyyy" }, - { "1981-dec-31", "yyyy'-'MMM'-'dd" }, - { "31-dec-1981", "dd'-'MMM'-'yyyy" }, - { "dec-31-1981", "MMM'-'dd'-'yyyy" }, - { "1981/12/31", "yyyy'/'MM'/'dd" }, - { "31/12/1981", "dd'/'MM'/'yyyy" }, - { "12/31/1981", "MM'/'dd'/'yyyy" }, - { "1981/dec/31", "yyyy'/'MMM'/'dd" }, - { "31/dec/1981", "dd'/'MMM'/'yyyy" }, - { "dec/31/1981", "MMM'/'dd'/'yyyy" }, - { "1981 dec 31", "yyyy MMM dd" }, - { "31 dec 1981", "dd MMM yyyy" }, - { "dec 31 1981", "MMM dd yyyy" } -}; - -struct TimeFormat -{ - LPCSTR lpszUI; - LPCSTR lpszFmt; -} -static timeFormats[] = -{ - { "19:30:00", "HH':'mm':'ss" }, - { "19:30", "HH':'mm'" }, - { "7:30:00 PM", "hh':'mm':'ss tt" }, - { "7:30 PM", "hh':'mm tt" }, - { "7:30:00P", "hh':'mm':'sst" }, - { "7:30P", "hh':'mmt" } -}; - - -struct FontOptionsList -{ - TCHAR *szDescr; - COLORREF defColour; - TCHAR *szDefFace; - BYTE defStyle; - char defSize; - TCHAR *szBkgName; -} -static fontOptionsList[] = -{ - {LPGENT("Sticky Note Caption"), RGB(0,0,0), _T("Small Fonts"), 0, 7, LPGENT("Sticky Note Background Color")}, - //{LPGENT("Sticky Note Caption"), RGB(0,0,0), _T("Terminal"), 0, 6, LPGENT("Sticky Note Background Color")}, - //{LPGENT("Sticky Note Caption"), RGB(0,0,0), _T("MS Serif"), 0, 7, LPGENT("Sticky Note Background Color")}, - //{LPGENT("Sticky Note Body"), RGB(0,0,0), _T("Tahoma"), 0, 8, LPGENT("Sticky Note Background Color")}, - {LPGENT("Sticky Note Body"), RGB(0,0,0), _T("System"), DBFONTF_BOLD, 10, LPGENT("Sticky Note Background Color")}, -}; - - -struct ColourOptionsList -{ - TCHAR *szName; - char *szSettingName; - COLORREF defColour; -} -static colourOptionsList[] = -{ - {LPGENT("Sticky Note Background Color"), "BodyColor", NRCDEFAULT_BODYCLR} -}; - - -LPCSTR GetDateFormatStr() -{ - return dateFormats[g_NoteTitleDate ? g_NoteTitleDate-1 : 0].lpszFmt; -} - -LPCSTR GetTimeFormatStr() -{ - return timeFormats[g_NoteTitleTime ? g_NoteTitleTime-1 : 0].lpszFmt; -} - -#if defined( _UNICODE ) -static BYTE MsgDlgGetFontDefaultCharset(const TCHAR* szFont) -{ - return DEFAULT_CHARSET; -} -#else -// get font charset according to current CP -static BYTE MsgDlgGetCPDefaultCharset() -{ - switch (GetACP()) { - case 1250: - return EASTEUROPE_CHARSET; - case 1251: - return RUSSIAN_CHARSET; - case 1252: - return ANSI_CHARSET; - case 1253: - return GREEK_CHARSET; - case 1254: - return TURKISH_CHARSET; - case 1255: - return HEBREW_CHARSET; - case 1256: - return ARABIC_CHARSET; - case 1257: - return BALTIC_CHARSET; - case 1361: - return JOHAB_CHARSET; - case 874: - return THAI_CHARSET; - case 932: - return SHIFTJIS_CHARSET; - case 936: - return GB2312_CHARSET; - case 949: - return HANGEUL_CHARSET; - case 950: - return CHINESEBIG5_CHARSET; - default: - return DEFAULT_CHARSET; - } -} - -static int CALLBACK EnumFontFamExProc(const LOGFONT *lpelfe, const TEXTMETRIC *lpntme, DWORD FontType, LPARAM lParam) -{ - *(int*)lParam = 1; - return 0; -} - -// get font charset according to current CP, if available for specified font -static BYTE MsgDlgGetFontDefaultCharset(const TCHAR* szFont) -{ - HDC hdc; - LOGFONT lf = {0}; - int found = 0; - - _tcscpy(lf.lfFaceName, szFont); - lf.lfCharSet = MsgDlgGetCPDefaultCharset(); - - // check if the font supports specified charset - hdc = GetDC(0); - EnumFontFamiliesEx(hdc, &lf, &EnumFontFamExProc, (LPARAM)&found, 0); - ReleaseDC(0, hdc); - - if (found) - return lf.lfCharSet; - else // no, give default - return DEFAULT_CHARSET; -} -#endif - - -static void InitFonts() -{ - ZeroMemory(&lfBody,sizeof(LOGFONT)); - ZeroMemory(&lfCaption,sizeof(LOGFONT)); - - LoadNRFont(NR_FONTID_CAPTION, &lfCaption, (COLORREF*)&CaptionFontColor); - LoadNRFont(NR_FONTID_BODY, &lfBody, (COLORREF*)&BodyFontColor); - - if (hBodyFont) - DeleteObject(hBodyFont); - if (hCaptionFont) - DeleteObject(hCaptionFont); - - hBodyFont = CreateFontIndirect(&lfBody); - hCaptionFont = CreateFontIndirect(&lfCaption); -} - - -static int FS_FontsChanged(WPARAM wParam, LPARAM lParam) -{ - InitFonts(); - - SaveNotes(); - LoadNotes(FALSE); - - return 0; -} - -static int FS_ColorChanged(WPARAM wParam, LPARAM lParam) -{ - LoadNRFont(NR_FONTID_CAPTION, &lfCaption, (COLORREF*)&CaptionFontColor); - LoadNRFont(NR_FONTID_BODY, &lfBody, (COLORREF*)&BodyFontColor); - - BodyColor = DBGetContactSettingDword(NULL, MODULENAME, colourOptionsList[0].szSettingName, colourOptionsList[0].defColour); - - SaveNotes(); - LoadNotes(FALSE); - - return 0; -} - -void RegisterFontServiceFonts() -{ - HDC hDC; - int nFontScale; - FontIDT fontid = {0}; - ColourIDT colorid = {0}; - char szTemp[100]; - int i; - - fontid.cbSize = sizeof(FontIDT); - - mir_sntprintf(fontid.group, SIZEOF(fontid.group), _T("%s"), LPGENT(SECTIONNAME)); - mir_sntprintf(fontid.backgroundGroup, SIZEOF(fontid.backgroundGroup), _T("%s"), LPGENT(SECTIONNAME)); - strncpy(fontid.dbSettingsGroup, MODULENAME, SIZEOF(fontid.dbSettingsGroup)); - fontid.flags = FIDF_ALLOWREREGISTER | FIDF_DEFAULTVALID | FIDF_SAVEPOINTSIZE; - - hDC = GetDC(NULL); - nFontScale = GetDeviceCaps(hDC, LOGPIXELSY); - ReleaseDC(NULL, hDC); - - for (i = 0; i < SIZEOF(fontOptionsList); i++) - { - fontid.order = i; - mir_snprintf(szTemp, SIZEOF(szTemp), "Font%d", i); - strncpy(fontid.prefix, szTemp, SIZEOF(fontid.prefix)); - _tcsncpy(fontid.name, fontOptionsList[i].szDescr, SIZEOF(fontid.name)); - fontid.deffontsettings.colour = fontOptionsList[i].defColour; - - fontid.deffontsettings.size = (char)-MulDiv(fontOptionsList[i].defSize, nFontScale, 72); - //fontid.deffontsettings.size = fontOptionsList[i].defSize; - - fontid.deffontsettings.style = fontOptionsList[i].defStyle; - fontid.deffontsettings.charset = MsgDlgGetFontDefaultCharset(fontOptionsList[i].szDefFace); - _tcsncpy(fontid.deffontsettings.szFace, fontOptionsList[i].szDefFace, SIZEOF(fontid.deffontsettings.szFace)); - _tcsncpy(fontid.backgroundName, fontOptionsList[i].szBkgName, SIZEOF(fontid.backgroundName)); - - FontRegister(&fontid); - } - - colorid.cbSize = sizeof(ColourIDT); - - mir_sntprintf(colorid.group, SIZEOF(colorid.group), _T("%s"), LPGENT(SECTIONNAME)); - strncpy(colorid.dbSettingsGroup, MODULENAME, SIZEOF(fontid.dbSettingsGroup)); - colorid.flags = 0; - - for (i = 0; i < SIZEOF(colourOptionsList); i++) - { - colorid.order = i; - _tcsncpy(colorid.name, colourOptionsList[i].szName, SIZEOF(colorid.name)); - colorid.defcolour = colourOptionsList[i].defColour; - strncpy(colorid.setting, colourOptionsList[i].szSettingName, SIZEOF(colorid.setting)); - - ColourRegister(&colorid); - } - - hkFontChange = HookEvent(ME_FONT_RELOAD, FS_FontsChanged); - hkColorChange = HookEvent(ME_COLOUR_RELOAD, FS_ColorChanged); -} - -void LoadNRFont(int i, LOGFONT *lf, COLORREF *colour) -{ - COLORREF col; - FontIDT fontid = {0}; - - fontid.cbSize = sizeof(fontid); - _tcsncpy(fontid.group, LPGENT(SECTIONNAME), SIZEOF(fontid.group)); - _tcsncpy(fontid.name, fontOptionsList[i].szDescr, SIZEOF(fontid.name)); - - col = CallService(MS_FONT_GETT, (WPARAM)&fontid, (LPARAM)lf); - - if (colour) - { - *colour = col; - } -} - - -static void TrimString(TCHAR *s) -{ - TCHAR *start; - TCHAR *end; - UINT n; - - if (!s || !*s) - { - return; - } - - start = s; - n = _tcslen(s) - 1; - - end = s + n; - - if (!_istspace(*start) && !_istspace(*end)) - { - // nothing to trim - return; - } - - // scan past leading spaces - while (*start && _istspace(*start)) start++; - - if (!*start) - { - // empty string - *s = 0; - return; - } - - // trim trailing spaces - while ( _istspace(*end) ) end--; - end[1] = 0; - - if (start > s) - { - // remove leading spaces - memmove(s, start, ((UINT)(end-start)+2)*sizeof(TCHAR)); - } -} - - -int CALLBACK DlgProcOptions(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) -{ - BOOL LB; - WORD SzT; - void *P; - int i; - - switch (message) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hdlg); - SendDlgItemMessage(hdlg,IDC_TRANSTRACK,TBM_SETRANGE,TRUE,MAKELONG(0,255-MIN_ALPHA)); - SendDlgItemMessage(hdlg,IDC_TRANSTRACK,TBM_SETPOS,TRUE,255-g_Transparency); - SendDlgItemMessage(hdlg,IDC_SHOWNOTES,BM_SETCHECK,(WPARAM)!g_ShowNotesAtStart,0); - SendDlgItemMessage(hdlg,IDC_SHOWBUTTONS,BM_SETCHECK,(WPARAM)g_ShowNoteButtons,0); - SendDlgItemMessage(hdlg,IDC_SHOWSCROLLBAR,BM_SETCHECK,(WPARAM)g_ShowScrollbar,0); // 4.2 - SendDlgItemMessage(hdlg,IDC_ADDCONTACTMENU,BM_SETCHECK,(WPARAM)g_AddContListMI,0); - SetDlgItemInt(hdlg,IDC_NOTEWIDTH,g_NoteWidth,FALSE); - SetDlgItemInt(hdlg,IDC_NOTEHEIGHT,g_NoteHeight,FALSE); - SendDlgItemMessage(hdlg,IDC_ADDREMINDERCLOSES,BM_SETCHECK,(WPARAM)g_CloseAfterAddReminder,0); - SendDlgItemMessage(hdlg,IDC_USEMCI,BM_SETCHECK,(WPARAM)!g_UseDefaultPlaySound,0); - - SendDlgItemMessage(hdlg,IDC_COMBODATE,CB_RESETCONTENT,0,0); - SendDlgItemMessage(hdlg,IDC_COMBOTIME,CB_RESETCONTENT,0,0); - for (i=0; icode == PSN_APPLY) - { - g_ShowNotesAtStart = !(BOOL)SendDlgItemMessage(hdlg,IDC_SHOWNOTES,BM_GETCHECK,0,0); - g_ShowNoteButtons = (BOOL)SendDlgItemMessage(hdlg,IDC_SHOWBUTTONS,BM_GETCHECK,0,0); - g_ShowScrollbar = (BOOL)SendDlgItemMessage(hdlg,IDC_SHOWSCROLLBAR,BM_GETCHECK,0,0); // 4.2 - g_AddContListMI = (BOOL)SendDlgItemMessage(hdlg,IDC_ADDCONTACTMENU,BM_GETCHECK,0,0); - g_NoteWidth = GetDlgItemInt(hdlg,IDC_NOTEWIDTH,&LB,FALSE); - g_NoteHeight = GetDlgItemInt(hdlg,IDC_NOTEHEIGHT,&LB,FALSE); - g_Transparency = 255-SendDlgItemMessage(hdlg,IDC_TRANSTRACK,TBM_GETPOS,0,0); - g_CloseAfterAddReminder = (BOOL)SendDlgItemMessage(hdlg,IDC_ADDREMINDERCLOSES,BM_GETCHECK,0,0); - g_UseDefaultPlaySound = !(BOOL)SendDlgItemMessage(hdlg,IDC_USEMCI,BM_GETCHECK,0,0); - g_NoteTitleDate = (SendDlgItemMessage(hdlg,IDC_COMBODATE,CB_GETCURSEL,0,0) + 1) % SendDlgItemMessage(hdlg,IDC_COMBODATE,CB_GETCOUNT,0,0); - g_NoteTitleTime = (SendDlgItemMessage(hdlg,IDC_COMBOTIME,CB_GETCURSEL,0,0) + 1) % SendDlgItemMessage(hdlg,IDC_COMBOTIME,CB_GETCOUNT,0,0); - if (g_NoteWidth < 179) - { - g_NoteWidth = 179; - SetDlgItemInt(hdlg,IDC_NOTEWIDTH,g_NoteWidth,FALSE); - } - if (g_NoteHeight < 35) - { - g_NoteHeight = 35; - SetDlgItemInt(hdlg,IDC_NOTEHEIGHT,g_NoteHeight,FALSE); - } - SzT = (WORD)SendDlgItemMessage(hdlg,IDC_REMINDEMAIL,WM_GETTEXTLENGTH,0,0); - if (SzT != 0) - { - g_RemindSMS = (char*)realloc(g_RemindSMS,SzT+1); - SendDlgItemMessage(hdlg,IDC_REMINDEMAIL,WM_GETTEXT,SzT+1,(LPARAM)g_RemindSMS); - } - P = g_RemindSMS; - WriteSettingBlob(0,MODULENAME,"RemindEmail",SzT,P); - - SzT = (WORD)SendDlgItemMessage(hdlg,IDC_EDIT_ALTBROWSER,WM_GETTEXTLENGTH,0,0); - if (SzT != 0) - { - g_lpszAltBrowser = (TCHAR*)mir_realloc(g_lpszAltBrowser,SzT+1); - SendDlgItemMessage(hdlg,IDC_EDIT_ALTBROWSER,WM_GETTEXT,SzT+1,(LPARAM)g_lpszAltBrowser); - TrimString(g_lpszAltBrowser); - if (!*g_lpszAltBrowser) - { - mir_free(g_lpszAltBrowser); - g_lpszAltBrowser = NULL; - } - } - else if (g_lpszAltBrowser) - { - mir_free(g_lpszAltBrowser); - g_lpszAltBrowser = NULL; - } - SetDlgItemText(hdlg,IDC_EDIT_ALTBROWSER,g_lpszAltBrowser ? g_lpszAltBrowser : _T("")); - if (g_lpszAltBrowser) - DBWriteContactSettingString(0,MODULENAME,"AltBrowser",g_lpszAltBrowser); - else - DBDeleteContactSetting(0,MODULENAME,"AltBrowser"); - - WriteSettingInt(0,MODULENAME,"ShowNotesAtStart",g_ShowNotesAtStart); - WriteSettingInt(0,MODULENAME,"ShowNoteButtons",g_ShowNoteButtons); - WriteSettingInt(0,MODULENAME,"ShowScrollbar",g_ShowScrollbar); // 4.2 - WriteSettingInt(0,MODULENAME,"AddContactMenuItems",g_AddContListMI); - WriteSettingInt(0,MODULENAME,"NoteWidth",g_NoteWidth); - WriteSettingInt(0,MODULENAME,"NoteHeight",g_NoteHeight); - WriteSettingInt(0,MODULENAME,"Transparency",g_Transparency); - WriteSettingInt(0,MODULENAME,"NoteTitleDate",g_NoteTitleDate); - WriteSettingInt(0,MODULENAME,"NoteTitleTime",g_NoteTitleTime); - WriteSettingInt(0,MODULENAME,"CloseAfterAddReminder",g_CloseAfterAddReminder); - WriteSettingInt(0,MODULENAME,"UseMCI",!g_UseDefaultPlaySound); - SaveNotes(); - LoadNotes(FALSE); - return TRUE; - } - break; - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_BTN_BROWSEBROWSER: - { - TCHAR s[MAX_PATH]; - - OPENFILENAME ofn = {0}; -#if defined(WINVER) && _WIN32_WINNT >= 0x0500 - ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; -#else - ofn.lStructSize = sizeof(ofn); -#endif - ofn.hwndOwner = hdlg; - ofn.lpstrFilter = "Executable Files\0*.exe\0All Files\0*.*\0\0"; - ofn.lpstrFile = s; - ofn.nMaxFile = SIZEOF(s); - ofn.lpstrTitle = Translate("Select Executable"); - ofn.lpstrInitialDir = "."; - ofn.Flags = OFN_FILEMUSTEXIST|OFN_LONGNAMES; - if ( IsWinVer98Plus() ) - { - ofn.Flags |= OFN_ENABLESIZING; - if (g_isWin2kPlus) - ofn.Flags |= OFN_DONTADDTORECENT; - } - - SendDlgItemMessage(hdlg,IDC_EDIT_ALTBROWSER,WM_GETTEXT,(WPARAM)ofn.nMaxFile,(LPARAM)s); - - if ( GetOpenFileName(&ofn) ) - { - SetDlgItemText(hdlg,IDC_EDIT_ALTBROWSER,s); - } - } - break; - case IDC_RESET: - { - SAFE_FREE((void**)&g_RemindSMS); - SetDlgItemText(hdlg,IDC_REMINDEMAIL,""); - if (g_lpszAltBrowser) - { - mir_free(g_lpszAltBrowser); - g_lpszAltBrowser = NULL; - } - SetDlgItemText(hdlg,IDC_EDIT_ALTBROWSER,""); - g_ShowNotesAtStart = TRUE; - g_AddContListMI = TRUE; - g_ShowScrollbar = TRUE; // 4.2 - g_ShowNoteButtons = TRUE; - g_NoteTitleDate = 1; - g_NoteTitleTime = 1; - g_CloseAfterAddReminder = TRUE; - g_UseDefaultPlaySound = FALSE; - SendDlgItemMessage(hdlg,IDC_SHOWNOTES,BM_SETCHECK,!g_ShowNotesAtStart,0); - SendDlgItemMessage(hdlg,IDC_ADDCONTACTMENU,BM_SETCHECK,g_AddContListMI,0); - SendDlgItemMessage(hdlg,IDC_SHOWSCROLLBAR,BM_SETCHECK,g_ShowScrollbar,0); - SendDlgItemMessage(hdlg,IDC_SHOWBUTTONS,BM_SETCHECK,(WPARAM)g_ShowNoteButtons,0); - SendDlgItemMessage(hdlg,IDC_ADDREMINDERCLOSES,BM_SETCHECK,g_CloseAfterAddReminder,0); - SendDlgItemMessage(hdlg,IDC_USEMCI,BM_SETCHECK,!g_UseDefaultPlaySound,0); - SendDlgItemMessage(hdlg,IDC_COMBODATE,CB_SETCURSEL,(WPARAM)(g_NoteTitleDate-1),0); - SendDlgItemMessage(hdlg,IDC_COMBOTIME,CB_SETCURSEL,(WPARAM)(g_NoteTitleTime-1),0); - g_NoteWidth = 179; // 4.2 - g_NoteHeight = 35; - SetDlgItemInt(hdlg,IDC_NOTEWIDTH,g_NoteWidth,FALSE); - SetDlgItemInt(hdlg,IDC_NOTEHEIGHT,g_NoteHeight,FALSE); - g_Transparency = 255; - SendDlgItemMessage(hdlg,IDC_TRANSTRACK,TBM_SETPOS,TRUE,0); - SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0); // JK optim - return TRUE; - } - default: - SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0); - return TRUE; - } - } - return FALSE; -} - -void InitSettings(void) -{ - void *P = NULL; - short Sz1; - - Sz1 = MAX_PATH; P = NULL; - ReadSettingBlob(0, MODULENAME, "RemindEmail", (WORD*)&Sz1, &P); - if (!(Sz1 && P)) - g_RemindSMS = NULL; - else - { - g_RemindSMS = (char*)malloc(Sz1+1); - ZeroMemory(g_RemindSMS,Sz1+1); - memcpy(g_RemindSMS,P,Sz1); - FreeSettingBlob(Sz1,P); - } - - g_lpszAltBrowser = DBGetString(0,MODULENAME,"AltBrowser"); - - g_ShowNotesAtStart = (BOOL)ReadSettingInt(0,MODULENAME,"ShowNotesAtStart",1); - g_ShowNoteButtons = (BOOL)ReadSettingInt(0,MODULENAME,"ShowNoteButtons",1); - g_ShowScrollbar = (BOOL)ReadSettingInt(0,MODULENAME,"ShowScrollbar",1); - g_AddContListMI = (BOOL)ReadSettingInt(0,MODULENAME,"AddContactMenuItems",1); - g_NoteWidth = ReadSettingInt(0,MODULENAME,"NoteWidth",179); - g_NoteHeight = ReadSettingInt(0,MODULENAME,"NoteHeight",50); - g_Transparency = ReadSettingInt(0,MODULENAME,"Transparency",255); - g_NoteTitleDate = ReadSettingInt(0,MODULENAME,"NoteTitleDate",1); - g_NoteTitleTime = ReadSettingInt(0,MODULENAME,"NoteTitleTime",1); - g_CloseAfterAddReminder = (BOOL)ReadSettingInt(0,MODULENAME,"CloseAfterAddReminder",1); - g_UseDefaultPlaySound = !(BOOL)ReadSettingInt(0,MODULENAME,"UseMCI",1); - - ReadSettingIntArray(0,MODULENAME,"ReminderListGeom",g_reminderListGeom,SIZEOF(g_reminderListGeom)); - ReadSettingIntArray(0,MODULENAME,"ReminderListColGeom",g_reminderListColGeom,SIZEOF(g_reminderListColGeom)); - ReadSettingIntArray(0,MODULENAME,"NotesListGeom",g_notesListGeom,SIZEOF(g_notesListGeom)); - ReadSettingIntArray(0,MODULENAME,"NotesListColGeom",g_notesListColGeom,SIZEOF(g_notesListColGeom)); - - BodyColor = DBGetContactSettingDword(NULL, MODULENAME, colourOptionsList[0].szSettingName, colourOptionsList[0].defColour); - - InitFonts(); - - g_hReminderIcon = Skin_GetIconByHandle(hIconLibItem[10]); - - if (g_Transparency < MIN_ALPHA) - g_Transparency = MIN_ALPHA; - else if (g_Transparency > 255) - g_Transparency = 255; -} - -void TermSettings(void) -{ - if (g_reminderListGeom[2] > 0 && g_reminderListGeom[3] > 0) - { - WriteSettingIntArray(0,MODULENAME,"ReminderListGeom",g_reminderListGeom,SIZEOF(g_reminderListGeom)); - WriteSettingIntArray(0,MODULENAME,"ReminderListColGeom",g_reminderListColGeom,SIZEOF(g_reminderListColGeom)); - } - if (g_notesListGeom[2] > 0 && g_notesListGeom[3] > 0) - { - WriteSettingIntArray(0,MODULENAME,"NotesListGeom",g_notesListGeom,SIZEOF(g_notesListGeom)); - WriteSettingIntArray(0,MODULENAME,"NotesListColGeom",g_notesListColGeom,SIZEOF(g_notesListColGeom)); - } - - if (g_lpszAltBrowser) - { - mir_free(g_lpszAltBrowser); - g_lpszAltBrowser = NULL; - } -} diff --git a/!NotAdopted/NotesAndReminders/src/reminders.cpp b/!NotAdopted/NotesAndReminders/src/reminders.cpp deleted file mode 100644 index 0d545056f9..0000000000 --- a/!NotAdopted/NotesAndReminders/src/reminders.cpp +++ /dev/null @@ -1,2890 +0,0 @@ -#include "globals.h" - -#define FILETIME_TICKS_PER_SEC ((ULONGLONG)10000000) - -#define MAX_REMINDER_LEN 16384 - - -// RemindersData DB data params -#define DATATAG_TEXT 1 // %s -#define DATATAG_SNDREPEAT 2 // %u (specifies seconds to wait between sound repeats, 0 if repeat is disabled) -#define DATATAG_SNDSEL 3 // %d (which sound to use, default, alt1, alt2, -1 means no sound at all) - - -#define IDC_DATE 1000 -#define IDC_TIME IDC_COMBOREMINDERTIME -#define IDC_ADDREMINDER 1002 -#define IDC_CLOSE 1003 -#define IDC_REMINDER 1004 -#define IDC_LISTREMINDERS 1000 -#define IDC_LISTREMINDERS_HEADER 2000 -#define IDC_REMINDERDATA 1001 -#define IDC_ADDNEWREMINDER 1002 -#define IDC_REMDATA 1000 -#define IDC_DISMISS 1001 -#define IDC_REMINDAGAIN 1002 -#define IDC_REMINDAGAININ 1003 -#define IDC_AFTER 1004 -#define IDC_ONDATE 1005 -#define IDC_DATEAGAIN 1006 -#define IDC_TIMEAGAIN 1007 -#define IDC_VIEWREMINDERS 1007 -#define IDC_NONE 1008 -#define IDC_DAILY 1009 -#define IDC_WEEKLY 1010 -#define IDC_MONTHLY 1011 -#define IDM_NEWREMINDER 40001 -#define IDM_DELETEREMINDER 40002 -#define IDM_DELETEALLREMINDERS 40003 -#define WM_RELOAD (WM_USER + 100) - -#define NOTIFY_LIST() if (ListReminderVisible) PostMessage(LV,WM_RELOAD,0,0) - - -TREEELEMENT *RemindersList = NULL; -static UINT QueuedReminderCount = 0; -static BOOL ListReminderVisible = FALSE; -static BOOL NewReminderVisible = FALSE; -static REMINDERDATA *pEditReminder = NULL; -static HWND LV; -static SOCKET S; - -int WS_Send(SOCKET s,char *data,int datalen); -unsigned long WS_ResolveName(char *name,WORD *port,int defaultPort); - -int CALLBACK DlgProcNotifyReminder(HWND Dialog,UINT Message, - WPARAM wParam,LPARAM lParam); -int CALLBACK DlgProcNewReminder(HWND Dialog,UINT Message,WPARAM wParam, - LPARAM lParam); -int CALLBACK DlgProcViewReminders(HWND Dialog,UINT Message,WPARAM wParam, - LPARAM lParam); - -void Send(char *user, char *host, char *Msg, char* server); -char* GetPreviewString(const char *lpsz); - - -static int ReminderSortCb(TREEELEMENT *v1, TREEELEMENT *v2) -{ - return (((REMINDERDATA*)v1->ptrdata)->When.QuadPart < ((REMINDERDATA*)v2->ptrdata)->When.QuadPart) ? -1 : 1; -} - - -#ifndef WINXP_MINIMUM -// TzSpecificLocalTimeToSystemTime/SystemTimeToTzSpecificLocalTime (re-)implemented to work on win2k and older - -static const int DaysInMonth[2][12] = -{ - { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, // normal year - { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } // leap year -}; - -static __inline BOOL IsLeapYear(UINT Y) -{ - return !(Y & 3) && ((Y % 100) || !(Y % 400)); -} - -static int TZDateComp(const SYSTEMTIME *lpDate, const SYSTEMTIME *lpDateRef) -{ - int boundaryDay, day; - - if (lpDate->wMonth < lpDateRef->wMonth) - return -1; - if (lpDate->wMonth > lpDateRef->wMonth) - return 1; - - if (!lpDateRef->wYear) - { - const int week = (int)lpDateRef->wDay; - const WORD wFirst = (6 + lpDateRef->wDayOfWeek - lpDate->wDayOfWeek + lpDate->wDay) % 7 + 1; - boundaryDay = (int)wFirst + 7 * (week - 1); - if (boundaryDay > DaysInMonth[ IsLeapYear(lpDate->wYear) ][lpDate->wMonth-1]) - boundaryDay -= 7; - } - else - boundaryDay = (int)lpDateRef->wDay; - - boundaryDay = ((boundaryDay * 24 + (int)lpDateRef->wHour) * 60 + (int)lpDateRef->wMinute) * 60; - day = (((int)lpDate->wDay * 24 + (int)lpDate->wHour) * 60 + (int)lpDate->wMinute) * 60 + (int)lpDate->wSecond; - - return (day < boundaryDay) ? -1 : (day > boundaryDay); -} - -static UINT TZGetType(LPTIME_ZONE_INFORMATION lpTZI, ULARGE_INTEGER *lpFT, BOOL bLocal) -{ - if (lpTZI->DaylightDate.wMonth) - { - ULARGE_INTEGER ft = *lpFT; - SYSTEMTIME tm; - BOOL BeforeStandardDate, AfterDaylightDate; - UINT id; - - if (!lpTZI->StandardDate.wMonth || (!lpTZI->StandardDate.wYear - && (!lpTZI->StandardDate.wDay || lpTZI->StandardDate.wDay > 5 - || !lpTZI->DaylightDate.wDay || lpTZI->DaylightDate.wDay > 5))) - return TIME_ZONE_ID_INVALID; - - if (!bLocal) - ft.QuadPart -= (LONGLONG)(lpTZI->Bias + lpTZI->DaylightBias) * (LONGLONG)600000000; - - FileTimeToSystemTime((FILETIME*)&ft, &tm); - - BeforeStandardDate = (TZDateComp(&tm, &lpTZI->StandardDate) < 0); - - if (!bLocal) - { - ft.QuadPart -= (LONGLONG)(lpTZI->StandardBias - lpTZI->DaylightBias) * (LONGLONG)600000000; - FileTimeToSystemTime((FILETIME*)&ft, &tm); - } - - AfterDaylightDate = (TZDateComp(&tm, &lpTZI->DaylightDate) >= 0); - - id = TIME_ZONE_ID_STANDARD; - if (lpTZI->DaylightDate.wMonth < lpTZI->StandardDate.wMonth) - { - if (BeforeStandardDate && AfterDaylightDate) - id = TIME_ZONE_ID_DAYLIGHT; - } - else - { - if (BeforeStandardDate || AfterDaylightDate) - id = TIME_ZONE_ID_DAYLIGHT; - } - - return id; - } - - return TIME_ZONE_ID_UNKNOWN; -} - -static BOOL TZGetBias(LPTIME_ZONE_INFORMATION lpTZI, ULARGE_INTEGER *lpFT, BOOL bLocal, LONG *pBias) -{ - LONG Bias = lpTZI->Bias; - - switch ( TZGetType(lpTZI, lpFT, bLocal) ) - { - case TIME_ZONE_ID_INVALID: return FALSE; - case TIME_ZONE_ID_DAYLIGHT: Bias += lpTZI->DaylightBias; break; - case TIME_ZONE_ID_STANDARD: Bias += lpTZI->StandardBias; break; - } - - *pBias = Bias; - - return TRUE; -} - -#define TzSpecificLocalTimeToSystemTime _TzSpecificLocalTimeToSystemTime -static BOOL _TzSpecificLocalTimeToSystemTime(LPTIME_ZONE_INFORMATION lpTZI, LPSYSTEMTIME lpLocal, LPSYSTEMTIME lpUtc) -{ - TIME_ZONE_INFORMATION tzi; - ULARGE_INTEGER ft; - LONG Bias; - - // if possible use the real function (shouldn't be necessary, be feels more comfortable) - if (MyTzSpecificLocalTimeToSystemTime) - return MyTzSpecificLocalTimeToSystemTime(lpTZI, lpLocal, lpUtc); - - if (!lpTZI) - { - if (GetTimeZoneInformation(&tzi) == TIME_ZONE_ID_INVALID) - return FALSE; - lpTZI = &tzi; - } - - if (!SystemTimeToFileTime(lpLocal, (FILETIME*)&ft) - || !TZGetBias(lpTZI, &ft, TRUE, &Bias)) - return FALSE; - - ft.QuadPart += (LONGLONG)Bias * (LONGLONG)600000000; - - return FileTimeToSystemTime((FILETIME*)&ft, lpUtc); -} - -#define SystemTimeToTzSpecificLocalTime _SystemTimeToTzSpecificLocalTime -static BOOL _SystemTimeToTzSpecificLocalTime(LPTIME_ZONE_INFORMATION lpTZI, LPSYSTEMTIME lpUtc, LPSYSTEMTIME lpLocal) -{ - TIME_ZONE_INFORMATION tzi; - ULARGE_INTEGER ft; - LONG Bias; - - // if possible use the real function (shouldn't be necessary, be feels more comfortable) - if (MySystemTimeToTzSpecificLocalTime) - return MySystemTimeToTzSpecificLocalTime(lpTZI, lpUtc, lpLocal); - - if (!lpTZI) - { - if (GetTimeZoneInformation(&tzi) == TIME_ZONE_ID_INVALID) - return FALSE; - lpTZI = &tzi; - } - - if (!SystemTimeToFileTime(lpUtc, (FILETIME*)&ft) - || !TZGetBias(lpTZI, &ft, FALSE, &Bias)) - return FALSE; - - ft.QuadPart -= (LONGLONG)Bias * (LONGLONG)600000000; - - return FileTimeToSystemTime((FILETIME*)&ft, lpLocal); -} - -#endif - - -// time convertsion routines that take local time-zone specific daylight saving configuration into account -// (unlike the standard FileTimeToLocalFileTime functions) - -void UtcToTzLocalFT(const FILETIME *lpUtc, FILETIME *lpLocal) -{ - SYSTEMTIME tm, tmLocal; - FILETIMEtoSYSTEMTIME(lpUtc, &tm); - SystemTimeToTzSpecificLocalTime(NULL, &tm, &tmLocal); - SYSTEMTIMEtoFILETIME(&tmLocal, lpLocal); -} - -void TzLocalToUtcFT(const FILETIME *lpLocal, FILETIME *lpUtc) -{ - SYSTEMTIME tm, tmUtc; - FILETIMEtoSYSTEMTIME(lpLocal, &tm); - TzSpecificLocalTimeToSystemTime(NULL, &tm, &tmUtc); - SYSTEMTIMEtoFILETIME(&tmUtc, lpUtc); -} - -void FileTimeToTzLocalST(const FILETIME *lpUtc, SYSTEMTIME *tmLocal) -{ - SYSTEMTIME tm; - FILETIMEtoSYSTEMTIME(lpUtc, &tm); - SystemTimeToTzSpecificLocalTime(NULL, &tm, tmLocal); -} - -void TzLocalSTToFileTime(const SYSTEMTIME *tmLocal, FILETIME *lpUtc) -{ - SYSTEMTIME tm; - TzSpecificLocalTimeToSystemTime(NULL, (SYSTEMTIME*)tmLocal, &tm); - SYSTEMTIMEtoFILETIME(&tm, lpUtc); -} - -/*void AddToTzLocalFT(FILETIME *lpLocal, UINT nSeconds) -{ - ULARGE_INTEGER utc; - TzLocalToUtcFT(lpLocal, (FILETIME*)&utc); - utc.QuadPart += (ULONGLONG)nSeconds * FILETIME_TICKS_PER_SEC; - UtcToTzLocalFT((FILETIME*)&utc, lpLocal); -}*/ - -/*static void AddToSystemTime(SYSTEMTIME *tm, UINT nSeconds) -{ - ULARGE_INTEGER li; - FILETIME ft; - - SYSTEMTIMEtoFILETIME(tm, &ft); - - li.HighPart = ft.dwHighDateTime; - li.LowPart = ft.dwLowDateTime; - li.QuadPart += (ULONGLONG)nSeconds * FILETIME_TICKS_PER_SEC; - - FILETIMEtoSYSTEMTIME((FILETIME*)&li, tm); -}*/ - - -static DWORD CreateUid() -{ - DWORD uid; - TREEELEMENT *TTE; - - if (!RemindersList) - return 1; - - for (uid = 1; ; uid++) - { - // check existing reminders if uid is in use - TTE = RemindersList; - while (TTE) - { - if (((REMINDERDATA*)TTE->ptrdata)->uid == uid) - // uid in use - goto try_next; - - TTE = (TREEELEMENT*)TTE->next; - } - - return uid; - -try_next:; - } - - // should never get here (unless someone has 4294967295 reminders) - return 0; -} - -static REMINDERDATA* FindReminder(DWORD uid) -{ - TREEELEMENT *TTE; - - if (!RemindersList) - return NULL; - - TTE = RemindersList; - while (TTE) - { - REMINDERDATA *pReminder = (REMINDERDATA*)TTE->ptrdata; - - if (pReminder->uid == uid) - { - return pReminder; - } - - TTE = (TREEELEMENT*)TTE->next; - } - - return NULL; -} - - -static void RemoveReminderSystemEvent(REMINDERDATA *p) -{ - if (p->SystemEventQueued) - { - int i; - - for (i=0; ; i++) - { - CLISTEVENT *pev; - - pev = (CLISTEVENT*) CallService(MS_CLIST_GETEVENT,(WPARAM)INVALID_HANDLE_VALUE,i); - if (!pev) - break; - - if ((ULONG)pev->lParam == p->uid && !pev->hContact - && pev->pszService && !strcmp(pev->pszService, MODULENAME"/OpenTriggeredReminder")) - { - if ( !CallService(MS_CLIST_REMOVEEVENT,(WPARAM)pev->hContact,(LPARAM)pev->hDbEvent) ) - { - p->SystemEventQueued = FALSE; - if (QueuedReminderCount) - QueuedReminderCount--; - } - break; - } - } - } -} - -void PurgeReminders(void) -{ - int ReminderCount,I; - char ValueName[32]; - - ReminderCount = ReadSettingInt(0,MODULENAME,"RemindersData",0); - for(I = 0;I < ReminderCount;I++) - { - sprintf(ValueName, "RemindersData%d", I); - DeleteSetting(0,MODULENAME,ValueName); - } -} - -void JustSaveReminders(void) -{ - TREEELEMENT *TTE; - int I, n, l; - char *tmpReminder = NULL,*Value; - char ValueName[32]; - int ReminderCount; - REMINDERDATA *pReminder; - - const int OldReminderCount = ReadSettingInt(0, MODULENAME, "RemindersData", 0); - - ReminderCount = TreeGetCount(RemindersList); - - WriteSettingInt(0,MODULENAME, "RemindersData", ReminderCount); - - for (TTE = RemindersList, I = 0; TTE; TTE = (TREEELEMENT*)TTE->next, I++) - { - pReminder = (REMINDERDATA*)TTE->ptrdata; - if (pReminder->Reminder && strlen(pReminder->Reminder)) - tmpReminder = pReminder->Reminder; - else - tmpReminder = NULL; - - if (!tmpReminder) - tmpReminder = ""; - - Value = (char*)malloc(strlen(tmpReminder) + 512); - - if (!Value) - continue; - - n = 0; - - // data header (save 'When' with 1-second resolution, it's just a waste to have 100-nanosecond resolution - // which results in larger DB strings with no use) - l = sprintf(Value, "X%u:%I64x", pReminder->uid, pReminder->When.QuadPart/FILETIME_TICKS_PER_SEC); - if (l > 0) n += l; - - // sound repeat - if (pReminder->RepeatSound) - { - l = sprintf(Value+n, "\033""%u:%u", DATATAG_SNDREPEAT, pReminder->RepeatSound); - if (l > 0) n += l; - } - - // sound - if (pReminder->SoundSel) - { - l = sprintf(Value+n, "\033""%u:%d", DATATAG_SNDSEL, pReminder->SoundSel); - if (l > 0) n += l; - } - - // reminder text/note (ALWAYS PUT THIS PARAM LAST) - if (tmpReminder && *tmpReminder) - { - l = sprintf(Value+n, "\033""%u:%s", DATATAG_TEXT, tmpReminder); - if (l > 0) n += l; - } - - // clamp data size to WORD (including null terminator) - if (n >= 0xffff) - { - // huston, we have a problem, strip some reminder text - n = 0xfffe; - ValueName[0xffff] = 0; - } - - sprintf(ValueName, "RemindersData%d", ReminderCount - I - 1); // do not want to reverse in DB - - WriteSettingBlob(0, MODULENAME, ValueName, (WORD)(n+1), Value); - - SAFE_FREE((void**)&Value); - } - - // delete any left over DB reminder entries - for(; I < OldReminderCount; I++) - { - sprintf(ValueName, "RemindersData%d", I); - DBDeleteContactSetting(0,MODULENAME,ValueName); - } -} - -void LoadReminders(void) -{ - int I,RemindersCount; - char *Value; - WORD Size; - char ValueName[32]; - BOOL GenerateUids = FALSE; - - RemindersList = NULL; - RemindersCount = ReadSettingInt(0, MODULENAME, "RemindersData", 0); - - for (I = 0; I < RemindersCount; I++) - { - Size = 65535; - Value = NULL; - sprintf(ValueName, "RemindersData%d", I); - - ReadSettingBlob(0, MODULENAME, ValueName, &Size, (void**)&Value); - - if (Size && Value) // was the blob found - { - REMINDERDATA rem = {0}; - char *TVal; - REMINDERDATA *TempRem; - char *DelPos = strchr(Value, 0x1B); - - // ensure that read data is null-terminated - Value[(UINT)Size-1] = 0; - - if (Value[0] == 'X') - { - // new eXtended/fleXible data format - - if (DelPos) - *DelPos = 0; - - // uid:when - - TVal = strchr(Value+1, ':'); - if (!TVal || (DelPos && TVal > DelPos)) - continue; - *TVal++ = 0; - - rem.uid = strtoul(Value+1, NULL, 10); - rem.When.QuadPart = _strtoui64(TVal, NULL, 16) * FILETIME_TICKS_PER_SEC; - - // optional \033 separated params - while (DelPos) - { - char *sep; - UINT tag; - - TVal = DelPos + 1; - // find param end and make sure it's null-terminated (if end of data then it's already null-terminated) - DelPos = strchr(TVal, 0x1B); - if (DelPos) - *DelPos = 0; - - // tag: - - sep = strchr(TVal, ':'); - if (!sep || (DelPos && sep > DelPos)) - goto skip; - - tag = strtoul(TVal, NULL, 10); - TVal = sep + 1; - - switch (tag) - { - case DATATAG_TEXT: - rem.Reminder = _strdup(TVal); - break; - - case DATATAG_SNDREPEAT: - rem.RepeatSound = strtoul(TVal, NULL, 10); - break; - - case DATATAG_SNDSEL: - rem.SoundSel = strtol(TVal, NULL, 10); - if (rem.SoundSel > 2) rem.SoundSel = 2; - break; - } - } - - if (rem.SoundSel < 0) - rem.RepeatSound = 0; - if (!rem.Reminder) - rem.Reminder = _strdup(""); - } - else - { - // old format (for DB backward compatibility) - - if (!DelPos) - continue; - - DelPos[0] = 0; - // convert time_t to (local) FILETIME - { - SYSTEMTIME tm; - struct tm *stm; - time_t tt; - - tt = (time_t)strtoul(Value, NULL, 10); - stm = localtime(&tt); - tm.wDayOfWeek = 0; - tm.wSecond = 0; - tm.wMilliseconds = 0; - tm.wHour = stm->tm_hour; - tm.wMinute = stm->tm_min; - tm.wSecond = stm->tm_sec; - tm.wYear = stm->tm_year + 1900; - tm.wMonth = stm->tm_mon + 1; - tm.wDay = stm->tm_mday; - SYSTEMTIMEtoFILETIME(&tm, (FILETIME*)&rem.When); - } - TVal = DelPos + 1; - rem.Reminder = _strdup(TVal); - } - - // queue uid generation if invalid uid is present - if (!rem.uid) - GenerateUids = TRUE; - - TempRem = (REMINDERDATA*)malloc(sizeof(REMINDERDATA)); - if (TempRem) - { - *TempRem = rem; - TreeAddSorted(&RemindersList, TempRem, ReminderSortCb); - } - else if (rem.Reminder) - { - free(rem.Reminder); - } -skip:; - } - - FreeSettingBlob(Size, Value); - } - - // generate UIDs if there are any items with an invalid UID - if (GenerateUids && RemindersList) - { - TREEELEMENT *TTE; - - TTE = RemindersList; - while (TTE) - { - REMINDERDATA *pReminder = (REMINDERDATA*)TTE->ptrdata; - - if (!pReminder->uid) - pReminder->uid = CreateUid(); - - TTE = (TREEELEMENT*)TTE->next; - } - - JustSaveReminders(); - } -} - - -/*void EscapeString(LPCSTR lpszSrc, char *s, int maxLen) -{ - maxLen -= 3; - - *s++ = '"'; - - while (*lpszSrc && maxLen > 1) - { - switch (*lpszSrc) - { - case '\r': *s++ = '\\'; *s++ = 'r'; break; - case '\n': *s++ = '\\'; *s++ = 'n'; break; - case '"': *s++ = '\\'; *s++ = '"'; break; - case '\t': *s++ = '\\'; *s++ = 't'; break; - case '\\': *s++ = '\\'; *s++ = '\\'; break; - default: - *s++ = *lpszSrc; - } - - lpszSrc++; - maxLen--; - } - - *s++ = '"'; - *s = 0; -} - -void ExportReminders() -{ - LPCSTR lpsz; - TREEELEMENT *TTE; - char s[MAX_REMINDER_LEN+512]; - - if (!RemindersList) - return NULL; - - // CSV header - lpsz = "TimeUTC,SoundSel,SoundRepeat,Description"; - WriteFile(hFile, lpsz, strlen(lpsz), NULL, NULL); - - TTE = RemindersList; - while (TTE) - { - REMINDERDATA *pReminder = (REMINDERDATA*)TTE->ptrdata; - - sprintf(s, "%I64u,%d,%d,", (pReminder->When.QuadPart-(ULONGLONG)116444736000000000)/FILETIME_TICKS_PER_SEC, pReminder->SoundSel, pReminder->RepeatSound); - WriteFile(hFile, s, strlen(s), NULL, NULL); - - if (pReminder->Reminder) - { - EscapeString(pReminder->Reminder, s, sizeof(s)); - WriteFile(hFile, s, strlen(s), NULL, NULL); - } - - WriteFile(hFile, (LPCVOID)"\r\n", 2, NULL, NULL); - - TTE = TTE->next; - } - - return NULL; -}*/ - - -void NewReminder(void) -{ - if (!NewReminderVisible) - { - NewReminderVisible = TRUE; - CreateDialog(hinstance, MAKEINTRESOURCE(IDD_ADDREMINDER), 0, DlgProcNewReminder); - } -} - -void EditReminder(REMINDERDATA *p) -{ - if (!p) - return; - - if (!NewReminderVisible && !p->SystemEventQueued) - { - if (!p->RemVisible) - { - p->RemVisible = TRUE; - NewReminderVisible = 2; - pEditReminder = p; - CreateDialog(hinstance, MAKEINTRESOURCE(IDD_ADDREMINDER), 0, DlgProcNewReminder); - } - else - { - BringWindowToTop(p->handle); - } - } -} - -static void DeleteReminder(REMINDERDATA *p) -{ - if (!p) - return; - - if (p->SystemEventQueued) - { - // remove pending system event - RemoveReminderSystemEvent(p); - } - - TreeDelete(&RemindersList, p); - SAFE_FREE((void**)&p->Reminder); - SAFE_FREE((void**)&p); -} - -void CloseReminderList() -{ - if (ListReminderVisible) - { - DestroyWindow(LV); - ListReminderVisible = FALSE; - } -} - -static void PurgeReminderTree() -{ - REMINDERDATA *pt; - - while (RemindersList) // empty whole tree - { - pt = (REMINDERDATA*)RemindersList->ptrdata; - if (pt->handle) DestroyWindow(pt->handle); - DeleteReminder(pt); - } - RemindersList = NULL; -} - -void SaveReminders(void) -{ - JustSaveReminders(); - PurgeReminderTree(); -} - -void DeleteReminders(void) -{ - PurgeReminders(); - WriteSettingInt(0,MODULENAME,"RemindersData",0); - PurgeReminderTree(); -} - -void ListReminders(void) -{ - if (!ListReminderVisible) - { - CreateDialog(hinstance, MAKEINTRESOURCE(IDD_LISTREMINDERS), 0, DlgProcViewReminders); - ListReminderVisible = TRUE; - } - else - { - BringWindowToTop(LV); - } -} - - -void GetTriggerTimeString(const ULARGE_INTEGER *When, char *s, UINT strSize, BOOL bUtc) -{ - SYSTEMTIME tm; - LCID lc = GetUserDefaultLCID(); - - *s = 0; - - memset(&tm, 0, sizeof(tm)); - if (bUtc) - FileTimeToTzLocalST((const FILETIME*)When, &tm); - else - FILETIMEtoSYSTEMTIME((FILETIME*)When, &tm); - - if ( GetDateFormat(lc, DATE_LONGDATE, &tm, NULL, s, strSize) ) - { - // append time - { - int n = strlen(s); - s[n++] = ' '; - s[n] = 0; - - if ( !GetTimeFormat(lc, LOCALE_NOUSEROVERRIDE|TIME_NOSECONDS, &tm, NULL, s+n, strSize-n) ) - { - mir_snprintf(s+n, strSize-n, "%02d:%02d", tm.wHour, tm.wMinute); - } - } - } - else - { - mir_snprintf(s, strSize, "%d-%02d-%02d %02d:%02d", tm.wYear, tm.wMonth, tm.wDay, tm.wHour, tm.wMinute); - } -} - - -int OpenTriggeredReminder(WPARAM w, LPARAM l) -{ - REMINDERDATA *pReminder; - - if (!l) - return 0; - - l = ((CLISTEVENT*)l)->lParam; - - pReminder = (REMINDERDATA*)FindReminder((DWORD)l); - if (!pReminder || !pReminder->SystemEventQueued) - return 0; - - pReminder->SystemEventQueued = FALSE; - if (QueuedReminderCount) - QueuedReminderCount--; - - { - char S[MAX_PATH]; - char S1[128]; - HWND H; - GetTriggerTimeString(&pReminder->When, S1, sizeof(S1), TRUE); - - pReminder->RemVisible = TRUE; - - pReminder->handle = H = CreateDialog(hinstance, MAKEINTRESOURCE(IDD_NOTIFYREMINDER), 0, DlgProcNotifyReminder); - - sprintf(S, "%s! - %s", Translate("Reminder"), S1); - SetWindowText(H, S); - - if (pReminder->Reminder) - SetDlgItemText(H, IDC_REMDATA, pReminder->Reminder); - - BringWindowToTop(H); - } - - return 0; -} - -static void SkinPlaySoundPoly(LPCSTR pszSoundName) -{ - if (g_UseDefaultPlaySound) - { - SkinPlaySound(pszSoundName); - return; - } - - if (DBGetContactSettingByte(NULL, "SkinSoundsOff", pszSoundName, 0)==0) { - DBVARIANT dbv; - - if (DBGetContactSettingString(NULL, "SkinSounds", pszSoundName, &dbv)==0) { - char szFull[MAX_PATH]; - - CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)dbv.pszVal, (LPARAM)szFull); - - //NotifyEventHooks(hPlayEvent, 0, (LPARAM)szFull); - { - // use MCI device which allows multiple sounds playing at once - // NOTE: mciSendString does not like long paths names, must convert to short - char szShort[MAX_PATH]; - char s[512]; - GetShortPathNameA(szFull, szShort, sizeof(szShort)); - mir_snprintf(s, sizeof(s), "play \"%s\"", szShort); - mciSendStringA(s, NULL, 0, NULL); - } - - DBFreeVariant(&dbv); - } - } -} - -static void UpdateReminderEvent(REMINDERDATA *pReminder, UINT nElapsedSeconds, BOOL *pHasPlayedSound) -{ - DWORD dwSoundMask; - - if (pReminder->RepeatSound) - { - if (nElapsedSeconds >= pReminder->RepeatSoundTTL) - { - pReminder->RepeatSoundTTL = pReminder->RepeatSound; - - dwSoundMask = 1 << pReminder->SoundSel; - - if ( !(*pHasPlayedSound & dwSoundMask) ) - { - switch (pReminder->SoundSel) - { - case 1: SkinPlaySoundPoly("AlertReminder2"); break; - case 2: SkinPlaySoundPoly("AlertReminder3"); break; - default: - SkinPlaySoundPoly("AlertReminder"); - } - - *pHasPlayedSound |= dwSoundMask; - } - } - else - { - pReminder->RepeatSoundTTL -= nElapsedSeconds; - } - } -} - -static void FireReminder(REMINDERDATA *pReminder, BOOL *pHasPlayedSound) -{ - DWORD dwSoundMask; - - if (pReminder->SystemEventQueued) - return; - - // add a system event - { - CLISTEVENT ev = { 0 }; - - ev.cbSize = sizeof(ev); - ev.hIcon = g_hReminderIcon; - ev.flags = CLEF_URGENT; - ev.lParam = (LPARAM)pReminder->uid; - ev.pszService = MODULENAME"/OpenTriggeredReminder"; - ev.pszTooltip = Translate("Reminder"); - - CallService(MS_CLIST_ADDEVENT,0,(LPARAM)&ev); - } - - pReminder->SystemEventQueued = TRUE; - QueuedReminderCount++; - - if (pReminder->SoundSel < 0) - { - // sound disabled - return; - } - - dwSoundMask = 1 << pReminder->SoundSel; - - pReminder->RepeatSoundTTL = pReminder->RepeatSound; - - if ( !(*pHasPlayedSound & dwSoundMask) ) - { - switch (pReminder->SoundSel) - { - case 1: SkinPlaySoundPoly("AlertReminder2"); break; - case 2: SkinPlaySoundPoly("AlertReminder3"); break; - default: - SkinPlaySoundPoly("AlertReminder"); - } - - *pHasPlayedSound |= dwSoundMask; - } -} - - -BOOL CheckRemindersAndStart(void) -{ - // returns TRUE if there are any triggered reminder with SystemEventQueued, this will shorten the update interval - // allowing sound repeats with shorter intervals - - TREEELEMENT *TTE; - ULARGE_INTEGER curT; - BOOL bHasPlayedSound; - BOOL bResult; - BOOL bHasQueuedReminders; - - if (!RemindersList) - return FALSE; - - { - SYSTEMTIME tm; - GetSystemTime(&tm); - SYSTEMTIMEtoFILETIME(&tm, (FILETIME*)&curT); - } - - // NOTE: reminder list is sorted by trigger time, so we can early out on the first reminder > cur time - - // quick check for normal case with no reminder ready to be triggered and no queued triggered reminders - // (happens 99.99999999999% of the time) - if (curT.QuadPart < ((REMINDERDATA*)RemindersList->ptrdata)->When.QuadPart && !QueuedReminderCount) - { - return FALSE; - } - - bResult = FALSE; - - // var used to avoid playing multiple alarm sounds during a single update - bHasPlayedSound = FALSE; - - // if there are queued (triggered) reminders then iterate through entire list, becaue of WM_TIMECHANGE events - // and for example daylight saving changes it's possible for an already triggered event to end up with When>curT - bHasQueuedReminders = (QueuedReminderCount != 0); - - // allthough count should always be correct, it's fool proof to just count them again in the loop below - QueuedReminderCount = 0; - - TTE = RemindersList; - while (TTE && (bHasQueuedReminders || ((REMINDERDATA*)TTE->ptrdata)->When.QuadPart <= curT.QuadPart)) - { - REMINDERDATA *pReminder = (REMINDERDATA*)TTE->ptrdata; - - if (!pReminder->RemVisible) - { - if (pReminder->SystemEventQueued) - { - UpdateReminderEvent(pReminder, REMINDER_UPDATE_INTERVAL_SHORT/1000, &bHasPlayedSound); - - QueuedReminderCount++; - bResult = TRUE; - } - else if (((REMINDERDATA*)TTE->ptrdata)->When.QuadPart <= curT.QuadPart) - { - if (!g_RemindSMS) - { - FireReminder(pReminder, &bHasPlayedSound); - - if (pReminder->SystemEventQueued) - bResult = TRUE; - } - else - { - char* S2 = strchr(g_RemindSMS, '@'); - char* S1 = (char*)malloc(S2 - g_RemindSMS); - - strncpy(S1, g_RemindSMS, S2 - g_RemindSMS); - S1[S2 - g_RemindSMS]= 0x0; - S2++; - Send(S1, S2, pReminder->Reminder ? pReminder->Reminder : "", NULL); - SAFE_FREE((void**)&S1); - DeleteReminder(pReminder); - JustSaveReminders(); - NOTIFY_LIST(); - } - } - } - - TTE = (TREEELEMENT*)TTE->next; - } - - return bResult; -} - - -static LRESULT CALLBACK DatePickerWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) - { - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_RBUTTONDBLCLK: - case WM_KEYDOWN: - case WM_KEYUP: - case WM_CHAR: - case WM_INITMENUPOPUP: - case WM_PASTE: - return TRUE; - case WM_SYSKEYUP: - case WM_SYSKEYDOWN: - case WM_SYSCHAR: - return FALSE; - } - - return CallWindowProc((WNDPROC)GetProp(hWnd, TEXT("OldWndProc")), hWnd, message, wParam, lParam); -} - -static void InitDatePicker(HWND Dialog, UINT nIDDate) -{ - // subclass date picker to prevent user editing (should only use the dropdown calender to ensure valid dates) - WNDPROC pOldWndProc; - HWND hCtrl = GetDlgItem(Dialog, nIDDate); - - // tweak style of picker - if ( IsWinVerVistaPlus() ) - { - DWORD dw = SendDlgItemMessage(Dialog,nIDDate,DTM_GETMCSTYLE,0,0); - dw |= MCS_WEEKNUMBERS | MCS_NOSELCHANGEONNAV; - SendDlgItemMessage(Dialog,nIDDate,DTM_SETMCSTYLE,0,dw); - } - -#ifdef _WIN64 - pOldWndProc = (WNDPROC)SetWindowLongPtr(hCtrl, GWLP_WNDPROC, (LONG_PTR)DatePickerWndProc); -#else - pOldWndProc = (WNDPROC)SetWindowLong(hCtrl, GWL_WNDPROC, (LONG)DatePickerWndProc); -#endif - - SetProp(hCtrl, TEXT("OldWndProc"), pOldWndProc); -} - -static BOOL ParseTime(LPCSTR s, int *hout, int *mout, BOOL bTimeOffset, BOOL bAllowOffsetOverride) -{ - // validate format: [][':'[]][p | P].* - - // if bTimeOffset is FALSE the user may still enter a time offset by using + as the first char, the - // delta time will be returned in minutes (even > 60) and hout will always be -1 - - // if bTimeOffset is TRUE time is always interpreted as an offset (ignores PM indicator and defaults to minutes) - - int h, m; - BOOL bOffset = bTimeOffset; - - // read hour - - while ( iswspace(*s) ) s++; - - if (*s == '+') - { - if (!bTimeOffset) - { - if (!bAllowOffsetOverride) - return FALSE; - - // treat value as an offset anyway - bOffset = TRUE; - } - - s++; - while ( iswspace(*s) ) s++; - } - - if ( !isdigit(*s) ) - return FALSE; - h = (int)(*s-'0'); - s++; - - if (!bOffset) - { - if ( isdigit(*s) ) - { - h = h * 10 + (int)(*s-'0'); - s++; - } - - if ( isdigit(*s) ) - return FALSE; - } - else - { - // allow more than 2-digit numbers for offset - while ( isdigit(*s) ) - { - h = h * 10 + (int)(*s-'0'); - s++; - } - } - - // find : separator - - while ( iswspace(*s) ) s++; - - if (*s == ':') - { - s++; - - // read minutes - - while ( iswspace(*s) ) s++; - - if ( !isdigit(*s) ) - return FALSE; - m = (int)(*s-'0'); - s++; - - if ( isdigit(*s) ) - { - m = m * 10 + (int)(*s-'0'); - s++; - } - } - else - { - if (bOffset) - { - // no : separator found, interpret the entered number as minutes and allow > 60 - - if (h < 0) - return FALSE; - - if (bTimeOffset) - { - *hout = h / 60; - *mout = h % 60; - } - else - { - *mout = h; - *hout = -1; - } - - return TRUE; - } - else - { - m = 0; - } - } - - // validate time - if (bOffset) - { - if (h < 0) - return FALSE; - if (m < 0 || m > 59) - return FALSE; - } - else - { - if (h == 24) - h = 0; - else if (h < 0 || h > 23) - return FALSE; - if (m < 0 || m > 59) - return FALSE; - } - - if (!bOffset) - { - // check for PM indicator (not strict, only checks for P char) - - while ( iswspace(*s) ) s++; - - if (*s == 'p' || *s == 'P') - { - if (h < 13) - h += 12; - else if (h == 12) - h = 0; - } - } - else if (!bTimeOffset) - { - // entered time is an offset - - *mout = h * 60 + m; - *hout = -1; - - return TRUE; - } - - *hout = h; - *mout = m; - - return TRUE; -} - -// returns TRUE if combo box list displays time offsets ("23:34 (5 Minutes)" etc.) -__inline static BOOL IsRelativeCombo(HWND Dialog, UINT nIDTime) -{ - return (int)SendDlgItemMessage(Dialog,nIDTime,CB_GETITEMDATA,0,0) >= 0; -} - -static void PopulateTimeCombo(HWND Dialog, UINT nIDTime, BOOL bRelative, const SYSTEMTIME *tmUtc) -{ - // NOTE: may seem like a bit excessive time converstion and handling, but this is done in order - // to gracefully handle crossing daylight saving boundaries - - SYSTEMTIME tm2; - ULARGE_INTEGER li; - ULONGLONG ref; - int i, n; - char s[64]; - const ULONGLONG MinutesToFileTime = (ULONGLONG)60 * FILETIME_TICKS_PER_SEC; - LPCSTR lpszMinutes; - LPCSTR lpszHours; - WORD wCurHour, wCurMinute; - - if (!bRelative) - { - SendDlgItemMessage(Dialog,nIDTime,CB_RESETCONTENT,0,0); - - // ensure that we start on midnight local time - SystemTimeToTzSpecificLocalTime(NULL, (SYSTEMTIME*)tmUtc, &tm2); - tm2.wHour = 0; - tm2.wMinute = 0; - tm2.wSecond = 0; - tm2.wMilliseconds = 0; - TzSpecificLocalTimeToSystemTime(NULL, &tm2, &tm2); - SYSTEMTIMEtoFILETIME(&tm2, (FILETIME*)&li); - - // from 00:00 to 23:30 in 30 minute steps - for (i=0; i<50; i++) - { - const int h = i>>1; - const int m = (i&1) ? 30 : 0; - - FileTimeToTzLocalST((FILETIME*)&li, &tm2); - sprintf(s, "%02d:%02d", (UINT)tm2.wHour, (UINT)tm2.wMinute); - n = SendDlgItemMessage(Dialog,nIDTime,CB_ADDSTRING,0,(LPARAM)s); - // item data contains time offset from midnight in seconds (bit 31 is set to flag that - // combo box items are absolute times and not relative times like below - SendDlgItemMessage(Dialog,nIDTime,CB_SETITEMDATA,(WPARAM)n,(LPARAM)((ULONG)((h*60+m)*60) | 0x80000000)); - - li.QuadPart += (ULONGLONG)30 * MinutesToFileTime; - - if (tm2.wHour == 23 && tm2.wMinute >= 30) - break; - } - - return; - } - - // - - SendDlgItemMessage(Dialog, nIDTime, CB_RESETCONTENT, 0, 0); - - lpszMinutes = Translate("Minutes"); - lpszHours = Translate("Hours"); - - SYSTEMTIMEtoFILETIME(tmUtc, (FILETIME*)&li); - ref = li.QuadPart; - - // NOTE: item data contains offset from reference time (tmUtc) in seconds - - // cur time - FileTimeToTzLocalST((FILETIME*)&li, &tm2); - wCurHour = tm2.wHour; - wCurMinute = tm2.wMinute; - mir_snprintf(s, sizeof(s), "%02d:%02d", (UINT)tm2.wHour, (UINT)tm2.wMinute); - n = SendDlgItemMessage(Dialog,nIDTime,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,nIDTime,CB_SETITEMDATA,(WPARAM)n,(LPARAM)((li.QuadPart-ref)/FILETIME_TICKS_PER_SEC)); - - // 5 minutes - li.QuadPart += (ULONGLONG)5 * MinutesToFileTime; - FileTimeToTzLocalST((FILETIME*)&li, &tm2); - mir_snprintf(s, sizeof(s), "%02d:%02d (5 %s)", (UINT)tm2.wHour, (UINT)tm2.wMinute, lpszMinutes); - n = SendDlgItemMessage(Dialog,nIDTime,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,nIDTime,CB_SETITEMDATA,(WPARAM)n,(LPARAM)((li.QuadPart-ref)/FILETIME_TICKS_PER_SEC)); - - // 10 minutes - li.QuadPart += (ULONGLONG)5 * MinutesToFileTime; - FileTimeToTzLocalST((FILETIME*)&li, &tm2); - mir_snprintf(s, sizeof(s), "%02d:%02d (10 %s)", (UINT)tm2.wHour, (UINT)tm2.wMinute, lpszMinutes); - n = SendDlgItemMessage(Dialog,nIDTime,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,nIDTime,CB_SETITEMDATA,(WPARAM)n,(LPARAM)((li.QuadPart-ref)/FILETIME_TICKS_PER_SEC)); - - // 15 minutes - li.QuadPart += (ULONGLONG)5 * MinutesToFileTime; - FileTimeToTzLocalST((FILETIME*)&li, &tm2); - mir_snprintf(s, sizeof(s), "%02d:%02d (15 %s)", (UINT)tm2.wHour, (UINT)tm2.wMinute, lpszMinutes); - n = SendDlgItemMessage(Dialog,nIDTime,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,nIDTime,CB_SETITEMDATA,(WPARAM)n,(LPARAM)((li.QuadPart-ref)/FILETIME_TICKS_PER_SEC)); - - // 30 minutes - li.QuadPart += (ULONGLONG)15 * MinutesToFileTime; - FileTimeToTzLocalST((FILETIME*)&li, &tm2); - mir_snprintf(s, sizeof(s), "%02d:%02d (30 %s)", (UINT)tm2.wHour, (UINT)tm2.wMinute, lpszMinutes); - n = SendDlgItemMessage(Dialog,nIDTime,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,nIDTime,CB_SETITEMDATA,(WPARAM)n,(LPARAM)((li.QuadPart-ref)/FILETIME_TICKS_PER_SEC)); - - // round +1h time to nearest even or half hour - li.QuadPart += (ULONGLONG)30 * MinutesToFileTime; - li.QuadPart = (li.QuadPart / (30 * MinutesToFileTime)) * (30 * MinutesToFileTime); - - // add from +1 to +23.5 (in half hour steps) if crossing daylight saving boundary it may be 22.5 or 24.5 hours - for (i=0; i<50; i++) - { - UINT dt; - - FileTimeToTzLocalST((FILETIME*)&li, &tm2); - - if (i > 40) - { - UINT nLastEntry = ((UINT)wCurHour * 60 + (UINT)wCurMinute) / 30; - if (nLastEntry) - nLastEntry *= 30; - else - nLastEntry = 23*60 + 30; - - if (((UINT)tm2.wHour * 60 + (UINT)tm2.wMinute) == nLastEntry) - break; - } - - // icq-style display 1.0, 1.5 etc. hours even though that isn't accurate due to rounding - //mir_snprintf(s, sizeof(s), "%02d:%02d (%d.%d %s)", (UINT)tm2.wHour, (UINT)tm2.wMinute, 1+(i>>1), (i&1) ? 5 : 0, lpszHours); - // display delta time more accurately to match reformatting (that icq doesn't do) - dt = (UINT)((li.QuadPart/MinutesToFileTime) - (ref/MinutesToFileTime)); - if (dt < 60) - mir_snprintf(s, sizeof(s), "%02d:%02d (%d %s)", (UINT)tm2.wHour, (UINT)tm2.wMinute, dt, lpszMinutes); - else - mir_snprintf(s, sizeof(s), "%02d:%02d (%d.%d %s)", (UINT)tm2.wHour, (UINT)tm2.wMinute, dt/60, ((dt%60)*10)/60, lpszHours); - n = SendDlgItemMessage(Dialog,nIDTime,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,nIDTime,CB_SETITEMDATA,(WPARAM)n,(LPARAM)(dt*60)); - - li.QuadPart += (ULONGLONG)30 * MinutesToFileTime; - } -} - -static void PopulateTimeOffsetCombo(HWND Dialog, UINT nIDCombo) -{ - int i, n; - LPCSTR lpszMinutes; - LPCSTR lpszHour; - LPCSTR lpszHours; - LPCSTR lpszDay; - LPCSTR lpszDays; - LPCSTR lpszWeek; - char s[MAX_PATH]; - - SendDlgItemMessage(Dialog,nIDCombo,CB_RESETCONTENT,0,0); - - lpszMinutes = Translate("Minutes"); - lpszHour = Translate("Hour"); - lpszHours = Translate("Hours"); - lpszDay = Translate("Day"); - lpszDays = Translate("Days"); - lpszWeek = Translate("Week"); - - // 5 - 55 minutes (in 5 minute steps) - for (i = 1; i < 12; i++) - { - mir_snprintf(s, sizeof(s), "%d %s", i*5, lpszMinutes); - n = SendDlgItemMessage(Dialog,nIDCombo,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,nIDCombo,CB_SETITEMDATA,(WPARAM)n,(LPARAM)(i*5)); - } - - // 1 hour - mir_snprintf(s, sizeof(s), "1 %s", lpszHour); - n = SendDlgItemMessage(Dialog,nIDCombo,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,nIDCombo,CB_SETITEMDATA,(WPARAM)n,(LPARAM)60); - - // 2, 4, 8 hours - for (i = 2; i <= 8; i+=2) - { - mir_snprintf(s, sizeof(s), "%d %s", i, lpszHours); - n = SendDlgItemMessage(Dialog,nIDCombo,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,nIDCombo,CB_SETITEMDATA,(WPARAM)n,(LPARAM)(i*60)); - } - - // 1 day - mir_snprintf(s, sizeof(s), "1 %s", lpszDay); - n = SendDlgItemMessage(Dialog,nIDCombo,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,nIDCombo,CB_SETITEMDATA,(WPARAM)n,(LPARAM)(24*60)); - - // 2-4 days - for (i = 2; i <= 4; i++) - { - mir_snprintf(s, sizeof(s), "%d %s", i, lpszDays); - n = SendDlgItemMessage(Dialog,nIDCombo,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,nIDCombo,CB_SETITEMDATA,(WPARAM)n,(LPARAM)(i*24*60)); - } - - // 1 week - mir_snprintf(s, sizeof(s), "1 %s", lpszWeek); - n = SendDlgItemMessage(Dialog,nIDCombo,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,nIDCombo,CB_SETITEMDATA,(WPARAM)n,(LPARAM)(7*24*60)); -} - -// returns non-zero if specified time was inside "missing" hour of daylight saving -// IMPORTANT: triggerRelUtcOut is only initialized if IsRelativeCombo() is TRUE and return value is 0 -static int ReformatTimeInputEx(HWND Dialog, UINT nIDTime, UINT nIDRefTime, int h, int m, const SYSTEMTIME *pDateLocal, ULARGE_INTEGER *triggerRelUtcOut) -{ - int n; - UINT dt; - char buf[64]; - const ULONGLONG MinutesToFileTime = (ULONGLONG)60 * FILETIME_TICKS_PER_SEC; - - if (h < 0) - { - // time value is an offset ('m' holds the offset in minutes) - - if ( IsRelativeCombo(Dialog, nIDTime) ) - { - ULONGLONG ref; - ULARGE_INTEGER li; - SYSTEMTIME tm; - - // get reference time (UTC) from hidden control - { - GetDlgItemText(Dialog, nIDRefTime, buf, 30); - li.QuadPart = ref = _strtoui64(buf, NULL, 16); - } - - // clamp delta time to 23.5 hours (coule be issues otherwise as relative combo only handles <24) - if (m > (23*60+30)) - m = 23*60+30; - - li.QuadPart += (ULONGLONG)(m * 60) * FILETIME_TICKS_PER_SEC; - - FileTimeToTzLocalST((FILETIME*)&li, &tm); - h = (int)tm.wHour; - m = (int)tm.wMinute; - - if (triggerRelUtcOut) - *triggerRelUtcOut = li; - - dt = (UINT)((li.QuadPart/MinutesToFileTime) - (ref/MinutesToFileTime)); - - if (dt < 60) - mir_snprintf(buf, sizeof(buf), "%02d:%02d (%d %s)", h, m, dt, Translate("Minutes")); - else - mir_snprintf(buf, sizeof(buf), "%02d:%02d (%d.%d %s)", h, m, dt/60, ((dt%60)*10)/60, Translate("Hours")); - - // search for preset - n = SendDlgItemMessage(Dialog, nIDTime, CB_FINDSTRING, (WPARAM)-1, (LPARAM)buf); - if (n != CB_ERR) - { - SendDlgItemMessage(Dialog, nIDTime, CB_SETCURSEL, (WPARAM)n, 0); - return 0; - } - - SetDlgItemText(Dialog, nIDTime, buf); - } - else - { - // should never happen - SendDlgItemMessage(Dialog, nIDTime, CB_SETCURSEL, 0, 0); - } - - return 0; - } - - // - - sprintf(buf, "%02d:%02d", h, m); - - // search for preset first - n = SendDlgItemMessage(Dialog, nIDTime, CB_FINDSTRING, (WPARAM)-1, (LPARAM)buf); - if (n != CB_ERR) - { - SendDlgItemMessage(Dialog, nIDTime, CB_SETCURSEL, (WPARAM)n, 0); - return 0; - } - - if ( IsRelativeCombo(Dialog, nIDTime) ) - { - // date format is a time offset ("24:43 (5 Minutes)" etc.) - - ULONGLONG ref; - SYSTEMTIME tmRefLocal; - SYSTEMTIME tmTriggerLocal, tmTriggerLocal2; - - // get reference time (UTC) from hidden control - { - GetDlgItemText(Dialog, nIDRefTime, buf, 30); - ref = _strtoui64(buf, NULL, 16); - } - - FileTimeToTzLocalST((FILETIME*)&ref, &tmRefLocal); - - { - ULARGE_INTEGER li; - const UINT nRefT = (UINT)tmRefLocal.wHour * 60 + (UINT)tmRefLocal.wMinute; - const UINT nT = h * 60 + m; - - tmTriggerLocal = tmRefLocal; - tmTriggerLocal.wHour = (WORD)h; - tmTriggerLocal.wMinute = (WORD)m; - tmTriggerLocal.wSecond = 0; - tmTriggerLocal.wMilliseconds = 0; - - if (nT < nRefT) - { - // (this special case only works correctly if time can be returned in triggerRelUtcOut) - if (tmRefLocal.wHour == tmTriggerLocal.wHour && triggerRelUtcOut) - { - // check for special case if daylight saving ends in this hour, then interpret as within the next hour - TzLocalSTToFileTime(&tmTriggerLocal, (FILETIME*)&li); - li.QuadPart += (ULONGLONG)3600*FILETIME_TICKS_PER_SEC; - FileTimeToTzLocalST((FILETIME*)&li, &tmTriggerLocal2); - if ((tmTriggerLocal2.wHour*60+tmTriggerLocal2.wMinute) == (tmTriggerLocal.wHour*60+tmTriggerLocal.wMinute)) - // special case detected - goto output_result; - } - - // tomorrow (add 24h to local time) - SYSTEMTIMEtoFILETIME(&tmTriggerLocal, (FILETIME*)&li); - li.QuadPart += (ULONGLONG)(24*3600)*FILETIME_TICKS_PER_SEC; - FILETIMEtoSYSTEMTIME((FILETIME*)&li, &tmTriggerLocal); - } - - // clean up value for potential daylight saving boundary - TzLocalSTToFileTime(&tmTriggerLocal, (FILETIME*)&li); - FileTimeToTzLocalST((FILETIME*)&li, &tmTriggerLocal2); - - // NOTE: win32 time functions will round hour downward if supplied hour does not exist due to daylight saving - // for example if supplied time is 02:30 on the night the clock is turned forward at 02:00 to 03:00, thus - // there never is a 02:30, the time functions will convert it to 01:30 (and not 03:30 as one might think) - // (02:00 would return 01:00) - - // check for special case when the current time and requested time is inside the "missing" hour - // standard->daylight switch, so that the cleaned up time ends up being earlier than the current - // time even though it originally wasn't (see note above) - if ((tmTriggerLocal2.wHour*60+tmTriggerLocal2.wMinute) < (tmTriggerLocal.wHour*60+tmTriggerLocal.wMinute)) - { - // special case detected, fall back to current time so at least the reminder won't be missed - // due to ending up at an undesired time (this way the user immediately notices something was wrong) - SendDlgItemMessage(Dialog, nIDTime, CB_SETCURSEL, 0, 0); -invalid_dst: - MessageBox(Dialog, Translate("The specified time is invalid due to begin of daylight saving (summer time)."), SECTIONNAME, MB_OK|MB_ICONWARNING); - return 1; - } - -output_result: - if (triggerRelUtcOut) - *triggerRelUtcOut = li; - - dt = (UINT)((li.QuadPart/MinutesToFileTime) - (ref/MinutesToFileTime)); - - if (dt < 60) - mir_snprintf(buf, sizeof(buf), "%02d:%02d (%d %s)", h, m, dt, Translate("Minutes")); - else - mir_snprintf(buf, sizeof(buf), "%02d:%02d (%d.%d %s)", h, m, dt/60, ((dt%60)*10)/60, Translate("Hours")); - } - } - else - { - // absolute time (00:00 to 23:59), clean up time to make sure it's not inside "missing" hour (will be rounded downard) - - FILETIME ft; - SYSTEMTIME Date = *pDateLocal; - Date.wHour = h; - Date.wMinute = m; - Date.wSecond = 0; - Date.wMilliseconds = 0; - - TzLocalSTToFileTime(&Date, &ft); - FileTimeToTzLocalST(&ft, &Date); - - if ((int)Date.wHour != h || (int)Date.wMinute != m) - { - sprintf(buf, "%02d:%02d", (UINT)Date.wHour, (UINT)Date.wMinute); - - // search for preset again - n = SendDlgItemMessage(Dialog, nIDTime, CB_FINDSTRING, (WPARAM)-1, (LPARAM)buf); - if (n != CB_ERR) - { - SendDlgItemMessage(Dialog, nIDTime, CB_SETCURSEL, (WPARAM)n, 0); - goto invalid_dst; - } - - SetDlgItemText(Dialog, nIDTime, buf); - - goto invalid_dst; - } - } - - SetDlgItemText(Dialog, nIDTime, buf); - - return 0; -} - -static __inline int ReformatTimeInput(HWND Dialog, UINT nIDTime, UINT nIDRefTime, int h, int m, const SYSTEMTIME *pDateLocal) -{ - return ReformatTimeInputEx(Dialog, nIDTime, nIDRefTime, h, m, pDateLocal, NULL); -} - -// in: pDate contains the desired trigger date in LOCAL time -// out: pDate contains the resulting trigger time and date in UTC -static BOOL GetTriggerTime(HWND Dialog, UINT nIDTime, UINT nIDRefTime, SYSTEMTIME *pDate) -{ - ULARGE_INTEGER li; - char buf[32]; - int n; - int h, m; - - // get reference (UTC) time from hidden control - { - GetDlgItemText(Dialog, nIDRefTime, buf, 30); - li.QuadPart = _strtoui64(buf, NULL, 16); - } - - if ((n = SendDlgItemMessage(Dialog, nIDTime, CB_GETCURSEL, 0, 0)) != CB_ERR) - { - // use preset value -preset_value:; - if ( IsRelativeCombo(Dialog, nIDTime) ) - { - // time offset from ref time ("24:43 (5 Minutes)" etc.) - - UINT nDeltaSeconds = (UINT)SendDlgItemMessage(Dialog, nIDTime, CB_GETITEMDATA, (WPARAM)n, 0); - li.QuadPart += (ULONGLONG)nDeltaSeconds * FILETIME_TICKS_PER_SEC; - - FILETIMEtoSYSTEMTIME((FILETIME*)&li, pDate); - - // if specified time is a small offset (< 10 Minutes) then retain current second count for better accuracy - // otherwise try to match specified time (which never contains seconds only even minutes) as close as possible - if (nDeltaSeconds >= 10*60) - { - pDate->wSecond = 0; - pDate->wMilliseconds = 0; - } - } - else - { - // absolute time (offset from midnight on pDate) - - UINT nDeltaSeconds = (UINT)((ULONG)SendDlgItemMessage(Dialog, nIDTime, CB_GETITEMDATA, (WPARAM)n, 0) & ~0x80000000); - pDate->wHour = 0; - pDate->wMinute = 0; - pDate->wSecond = 0; - pDate->wMilliseconds = 0; - TzLocalSTToFileTime(pDate, (FILETIME*)&li); - li.QuadPart += (ULONGLONG)nDeltaSeconds * FILETIME_TICKS_PER_SEC; - - FILETIMEtoSYSTEMTIME((FILETIME*)&li, pDate); - } - - return TRUE; - } - - // user entered a custom value - - GetDlgItemText(Dialog, nIDTime, buf, 30); - - if ( !ParseTime(buf, &h, &m, FALSE, IsRelativeCombo(Dialog, nIDTime)) ) - { - MessageBox(Dialog, Translate("The specified time is invalid."), SECTIONNAME, MB_OK|MB_ICONWARNING); - return FALSE; - } - - if ( IsRelativeCombo(Dialog, nIDTime) ) - { - // date has not been changed, the specified time is a time between reftime and reftime+24h - - ULARGE_INTEGER li2; - - if ( ReformatTimeInputEx(Dialog, nIDTime, nIDRefTime, h, m, pDate, &li2) ) - return FALSE; - - // check if reformatted value is a preset - if ((n = SendDlgItemMessage(Dialog, nIDTime, CB_GETCURSEL, 0, 0)) != CB_ERR) - goto preset_value; - - FILETIMEtoSYSTEMTIME((FILETIME*)&li2, pDate); - - return TRUE; - } - else - { - if ( ReformatTimeInputEx(Dialog, nIDTime, nIDRefTime, h, m, pDate, NULL) ) - return FALSE; - - // check if reformatted value is a preset - if ((n = SendDlgItemMessage(Dialog, nIDTime, CB_GETCURSEL, 0, 0)) != CB_ERR) - goto preset_value; - } - - // absolute time (on pDate) - - pDate->wHour = h; - pDate->wMinute = m; - pDate->wSecond = 0; - pDate->wMilliseconds = 0; - - TzLocalSTToFileTime(pDate, (FILETIME*)&li); - FILETIMEtoSYSTEMTIME((FILETIME*)&li, pDate); - - return TRUE; -} - -static void OnDateChanged(HWND Dialog, UINT nDateID, UINT nTimeID, UINT nRefTimeID) -{ - // repopulate time combo list with regular times (not offsets like "23:32 (5 minutes)" etc.) - - SYSTEMTIME Date, DateUtc; - int h = -1, m; - char s[32]; - - GetDlgItemText(Dialog, nTimeID, s, 30); - - ParseTime(s, &h, &m, FALSE, FALSE); - - SendDlgItemMessage(Dialog, nDateID, DTM_GETSYSTEMTIME, 0, (LPARAM)&Date); - - TzSpecificLocalTimeToSystemTime(NULL, &Date, &DateUtc); - PopulateTimeCombo(Dialog, nTimeID, FALSE, &DateUtc); - - if (h < 0) - { - // parsing failed, default to current time - SYSTEMTIME tm; - GetLocalTime(&tm); - h = (UINT)tm.wHour; - m = (UINT)tm.wMinute; - } - - ReformatTimeInput(Dialog, nTimeID, nRefTimeID, h, m, &Date); -} - - -int CALLBACK DlgProcNotifyReminder(HWND Dialog,UINT Message,WPARAM wParam,LPARAM lParam) -{ - int I; - - switch (Message) - { - case WM_INITDIALOG: - { - SYSTEMTIME tm; - ULARGE_INTEGER li; - - GetSystemTime(&tm); - SYSTEMTIMEtoFILETIME(&tm, (FILETIME*)&li); - - TranslateDialogDefault(Dialog); - - // save reference time in hidden control, is needed when adding reminder to properly detect if speicifed - // time wrapped around to tomorrow or not (dialog could in theory be open for a longer period of time - // which could potentially mess up things otherwise) - { - char s[32]; - sprintf(s, "%I64x", li.QuadPart); - SetDlgItemText(Dialog, IDC_REFTIME, s); - } - - BringWindowToTop(Dialog); - - PopulateTimeOffsetCombo(Dialog, IDC_REMINDAGAININ); - - ShowWindow(GetDlgItem(Dialog,IDC_REMINDAGAININ),SW_SHOW); - ShowWindow(GetDlgItem(Dialog,IDC_DATEAGAIN),SW_HIDE); - ShowWindow(GetDlgItem(Dialog,IDC_TIMEAGAIN),SW_HIDE); - ShowWindow(GetDlgItem(Dialog,IDC_STATIC_DATE),SW_HIDE); - ShowWindow(GetDlgItem(Dialog,IDC_STATIC_TIME),SW_HIDE); - SendDlgItemMessage(Dialog,IDC_AFTER,BM_SETCHECK,1,0); - SendDlgItemMessage(Dialog,IDC_ONDATE,BM_SETCHECK,0,0); - SendDlgItemMessage(Dialog,IDC_REMINDAGAININ,CB_SETCURSEL,0,0); - - SendDlgItemMessage(Dialog, IDC_REMDATA, EM_LIMITTEXT, MAX_REMINDER_LEN, 0); - - PopulateTimeCombo(Dialog, IDC_TIMEAGAIN, TRUE, &tm); - - FileTimeToTzLocalST((FILETIME*)&li, &tm); - - // make sure date picker uses reference time - SendDlgItemMessage(Dialog,IDC_DATEAGAIN,DTM_SETSYSTEMTIME,0,(LPARAM)&tm); - InitDatePicker(Dialog, IDC_DATEAGAIN); - - SendDlgItemMessage(Dialog,IDC_TIMEAGAIN,CB_SETCURSEL,0,0); - - return TRUE; - } - case WM_NCDESTROY: - RemoveProp(GetDlgItem(Dialog, IDC_DATEAGAIN), TEXT("OldWndProc")); - return TRUE; - case WM_NOTIFY: - { - if (wParam == IDC_DATEAGAIN) - { - NMLISTVIEW *NM = (NMLISTVIEW*)lParam; - - switch (NM->hdr.code) - { - case DTN_DATETIMECHANGE: - OnDateChanged(Dialog, IDC_DATEAGAIN, IDC_TIMEAGAIN, IDC_REFTIME); - break; - } - } - } - break; - case WM_CLOSE: - { - int ReminderCount = TreeGetCount(RemindersList); - for (I = 0; I < ReminderCount; I++) - { - REMINDERDATA *pReminder = (REMINDERDATA*)TreeGetAt(RemindersList, I); - - if (pReminder->handle == Dialog) - { - DeleteReminder(pReminder); - JustSaveReminders(); - break; - } - } - NOTIFY_LIST(); - } - DestroyWindow(Dialog); - return TRUE; - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case IDC_TIMEAGAIN: - switch (HIWORD(wParam)) - { - case CBN_KILLFOCUS: - // reformat displayed value - if (SendDlgItemMessage(Dialog, IDC_TIMEAGAIN, CB_GETCURSEL, 0, 0) == CB_ERR) - { - char buf[64]; - int h, m; - GetDlgItemText(Dialog, IDC_TIMEAGAIN, buf, 30); - - if ( ParseTime(buf, &h, &m, FALSE, IsRelativeCombo(Dialog, IDC_TIMEAGAIN)) ) - { - SYSTEMTIME Date; - SendDlgItemMessage(Dialog,IDC_DATEAGAIN,DTM_GETSYSTEMTIME,0,(LPARAM)&Date); - - ReformatTimeInput(Dialog, IDC_TIMEAGAIN, IDC_REFTIME, h, m, &Date); - } - else - { - SendDlgItemMessage(Dialog, IDC_TIMEAGAIN, CB_SETCURSEL, 0, 0); - } - } - break; - } - break; - - case IDC_REMINDAGAININ: - switch (HIWORD(wParam)) - { - case CBN_KILLFOCUS: - // reformat displayed value if it has been edited - if (SendDlgItemMessage(Dialog,IDC_REMINDAGAININ,CB_GETCURSEL,0,0) == CB_ERR) - { - char buf[64]; - int h, m; - GetDlgItemText(Dialog, IDC_REMINDAGAININ, buf, 30); - - if (ParseTime(buf, &h, &m, TRUE, TRUE) && h+m) - { - if (h) - { - LPCSTR lpszHours = Translate("Hours"); - sprintf(buf, "%d:%02d %s", h, m, lpszHours); - } - else - { - LPCSTR lpszMinutes = Translate("Minutes"); - sprintf(buf, "%d %s", m, lpszMinutes); - } - SetDlgItemText(Dialog, IDC_REMINDAGAININ, buf); - } - else - { - SendDlgItemMessage(Dialog,IDC_REMINDAGAININ,CB_SETCURSEL,0,0); - } - } - break; - } - break; - - case IDC_AFTER: - { - ShowWindow(GetDlgItem(Dialog,IDC_REMINDAGAININ),SW_SHOW); - ShowWindow(GetDlgItem(Dialog,IDC_DATEAGAIN),SW_HIDE); - ShowWindow(GetDlgItem(Dialog,IDC_TIMEAGAIN),SW_HIDE); - ShowWindow(GetDlgItem(Dialog,IDC_STATIC_DATE),SW_HIDE); - ShowWindow(GetDlgItem(Dialog,IDC_STATIC_TIME),SW_HIDE); - return TRUE; - } - case IDC_ONDATE: - { - ShowWindow(GetDlgItem(Dialog,IDC_DATEAGAIN),SW_SHOW); - ShowWindow(GetDlgItem(Dialog,IDC_TIMEAGAIN),SW_SHOW); - ShowWindow(GetDlgItem(Dialog,IDC_STATIC_DATE),SW_SHOW); - ShowWindow(GetDlgItem(Dialog,IDC_STATIC_TIME),SW_SHOW); - ShowWindow(GetDlgItem(Dialog,IDC_REMINDAGAININ),SW_HIDE); - return TRUE; - } - case IDC_DISMISS: - { - int ReminderCount = TreeGetCount(RemindersList); - for (I = 0; I < ReminderCount; I++) - { - REMINDERDATA *pReminder = (REMINDERDATA*)TreeGetAt(RemindersList, I); - - if (pReminder->handle == Dialog) - { - DeleteReminder(pReminder); - JustSaveReminders(); - break; - } - } - NOTIFY_LIST(); - DestroyWindow(Dialog); - return TRUE; - } - case IDC_REMINDAGAIN: - { - int ReminderCount = TreeGetCount(RemindersList); - for (I = 0; I < ReminderCount; I++) - { - REMINDERDATA *pReminder = (REMINDERDATA*)TreeGetAt(RemindersList, I); - - if (pReminder->handle == Dialog) - { - if (SendDlgItemMessage(Dialog,IDC_AFTER,BM_GETCHECK,0,0) == BST_CHECKED) - { - // delta time - - ULONGLONG TT; - SYSTEMTIME tm; - ULARGE_INTEGER li; - int n; - - GetSystemTime(&tm); - SYSTEMTIMEtoFILETIME(&tm, (FILETIME*)&li); - - n = SendDlgItemMessage(Dialog,IDC_REMINDAGAININ,CB_GETCURSEL,0,0); - if (n != CB_ERR) - { - TT = SendDlgItemMessage(Dialog,IDC_REMINDAGAININ,CB_GETITEMDATA,(WPARAM)n,0) * 60; - - if (TT >= 24*3600) - { - // selection is 1 day or more, take daylight saving boundaries into consideration - // (ie. 24 hour might actually be 23 or 25, in order for reminder to pop up at the - // same time tomorrow) - SYSTEMTIME tm2, tm3; - ULARGE_INTEGER li2 = li; - FileTimeToTzLocalST((FILETIME*)&li2, &tm2); - li2.QuadPart += (TT * FILETIME_TICKS_PER_SEC); - FileTimeToTzLocalST((FILETIME*)&li2, &tm3); - if (tm2.wHour != tm3.wHour || tm2.wMinute != tm3.wMinute) - { - // boundary crossed - - // do a quick and dirty sanity check that times not more than 2 hours apart - if (abs((int)(tm3.wHour*60+tm3.wMinute)-(int)(tm2.wHour*60+tm2.wMinute)) <= 120) - { - // adjust TT so that same HH:MM is set - tm3.wHour = tm2.wHour; - tm3.wMinute = tm2.wMinute; - TzLocalSTToFileTime(&tm3, (FILETIME*)&li2); - TT = (li2.QuadPart - li.QuadPart) / FILETIME_TICKS_PER_SEC; - } - } - } - } - else - { - // parse user input - char s[32]; - int h = 0, m = 0; - GetDlgItemText(Dialog, IDC_REMINDAGAININ, s, 30); - ParseTime(s, &h, &m, TRUE, TRUE); - m += h * 60; - if (!m) - { - MessageBox(Dialog, Translate("The specified time offset is invalid."), SECTIONNAME, MB_OK|MB_ICONWARNING); - return TRUE; - } - - TT = m * 60; - } - - pReminder->When = li; - pReminder->When.QuadPart += (TT * FILETIME_TICKS_PER_SEC); - } - else if (SendDlgItemMessage(Dialog,IDC_ONDATE,BM_GETCHECK,0,0) == BST_CHECKED) - { - SYSTEMTIME Date; - - SendDlgItemMessage(Dialog,IDC_DATEAGAIN,DTM_GETSYSTEMTIME,0,(LPARAM)&Date); - - if ( !GetTriggerTime(Dialog, IDC_TIMEAGAIN, IDC_REFTIME, &Date) ) - break; - - SYSTEMTIMEtoFILETIME(&Date, (FILETIME*)&pReminder->When); - } - - // update reminder text - { - char *ReminderText = NULL; - int SzT = SendDlgItemMessage(Dialog,IDC_REMDATA,WM_GETTEXTLENGTH,0,0); - if (SzT) - { - if (SzT > MAX_REMINDER_LEN) SzT = MAX_REMINDER_LEN; - ReminderText = (char*)malloc(SzT+1); - SendDlgItemMessage(Dialog,IDC_REMDATA,WM_GETTEXT,SzT+1,(LPARAM)ReminderText); - } - if (pReminder->Reminder) - free(pReminder->Reminder); - pReminder->Reminder = ReminderText; - } - - pReminder->RemVisible = FALSE; - pReminder->handle = NULL; - - // re-insert tree item sorted - TreeDelete(&RemindersList,pReminder); - TreeAddSorted(&RemindersList,pReminder,ReminderSortCb); - JustSaveReminders(); - break; - } - } - NOTIFY_LIST(); - DestroyWindow(Dialog); - return TRUE; - } - case IDC_NONE: - {// create note from remainder - int ReminderCount = TreeGetCount(RemindersList); - for (I = 0; I < ReminderCount; I++) - { - REMINDERDATA *pReminder = (REMINDERDATA*)TreeGetAt(RemindersList, I); - - if (pReminder->handle == Dialog) - { - // get up-to-date reminder text - char *ReminderText = NULL; - int SzT = SendDlgItemMessage(Dialog,IDC_REMDATA,WM_GETTEXTLENGTH,0,0); - if (SzT) - { - if (SzT > MAX_REMINDER_LEN) SzT = MAX_REMINDER_LEN; - ReminderText = (char*)malloc(SzT+1); - SendDlgItemMessage(Dialog,IDC_REMDATA,WM_GETTEXT,SzT+1,(LPARAM)ReminderText); - } - - SetFocus(NewNote(0, 0, -1, -1, ReminderText, 0, TRUE, TRUE, 0)->REHwnd); - break; - } - } - return TRUE; - } - } - } - } - return FALSE; -} - -int CALLBACK DlgProcNewReminder(HWND Dialog,UINT Message,WPARAM wParam,LPARAM lParam) -{ - HICON hIcon = NULL; - switch (Message) - { - case WM_INITDIALOG: - { - ULARGE_INTEGER li; - SYSTEMTIME tm; - - if (NewReminderVisible == 2) - { - // opening the edit reminder dialog (uses same dialog resource as add reminder) - SetWindowText(Dialog, _T("Reminder")); - SetDlgItemText(Dialog, IDC_ADDREMINDER, _T("&Update Reminder")); - ShowWindow(GetDlgItem(Dialog, IDC_VIEWREMINDERS), SW_HIDE); - - li = pEditReminder->When; - FILETIMEtoSYSTEMTIME((FILETIME*)&li, &tm); - } - else - { - GetSystemTime(&tm); - SYSTEMTIMEtoFILETIME(&tm, (FILETIME*)&li); - } - - TranslateDialogDefault(Dialog); - - // save reference time in hidden control, is needed when adding reminder to properly detect if speicifed - // time wrapped around to tomorrow or not (dialog could in theory be open for a longer period of time - // which could potentially mess up things otherwise) - { - char s[32]; - sprintf(s, "%I64x", li.QuadPart); - SetDlgItemText(Dialog, IDC_REFTIME, s); - } - - /*SendDlgItemMessage(Dialog,IDC_NONE,BM_SETCHECK,1,0); - SendDlgItemMessage(Dialog,IDC_DAILY,BM_SETCHECK,0,0); - SendDlgItemMessage(Dialog,IDC_WEEKLY,BM_SETCHECK,0,0); - SendDlgItemMessage(Dialog,IDC_MONTHLY,BM_SETCHECK,0,0);*/ - - PopulateTimeCombo(Dialog, IDC_TIME, NewReminderVisible != 2, &tm); - - FileTimeToTzLocalST((FILETIME*)&li, &tm); - - // make sure date picker uses reference time - SendDlgItemMessage(Dialog,IDC_DATE,DTM_SETSYSTEMTIME,0,(LPARAM)&tm); - InitDatePicker(Dialog, IDC_DATE); - - SendDlgItemMessage(Dialog, IDC_REMINDER, EM_LIMITTEXT, MAX_REMINDER_LEN, 0); - - if (NewReminderVisible == 2) - { - int n; - char s[32]; - mir_snprintf(s, sizeof(s), "%02d:%02d", (UINT)tm.wHour, (UINT)tm.wMinute); - - // search for preset first - n = SendDlgItemMessage(Dialog, IDC_TIME, CB_FINDSTRING, (WPARAM)-1, (LPARAM)s); - if (n != CB_ERR) - SendDlgItemMessage(Dialog, IDC_TIME, CB_SETCURSEL, (WPARAM)n, 0); - else - SetDlgItemText(Dialog, IDC_TIME, s); - - SetDlgItemText(Dialog, IDC_REMINDER, pEditReminder->Reminder); - } - else - { - SendDlgItemMessage(Dialog,IDC_TIME,CB_SETCURSEL,0,0); - } - - // populate sound repeat combo - { - char s[64]; - int n; - LPCSTR lpszEvery = Translate("Every"); - LPCSTR lpszSeconds = Translate("Seconds"); - - // NOTE: use multiples of REMINDER_UPDATE_INTERVAL_SHORT (currently 5 seconds) - - n = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_ADDSTRING,0,(LPARAM)Translate("Never")); - SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)0); - - mir_snprintf(s, sizeof(s), "%s 5 %s", lpszEvery, lpszSeconds); - n = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)5); - - mir_snprintf(s, sizeof(s), "%s 10 %s", lpszEvery, lpszSeconds); - n = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)10); - - mir_snprintf(s, sizeof(s), "%s 15 %s", lpszEvery, lpszSeconds); - n = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)15); - - mir_snprintf(s, sizeof(s), "%s 20 %s", lpszEvery, lpszSeconds); - n = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)20); - - mir_snprintf(s, sizeof(s), "%s 30 %s", lpszEvery, lpszSeconds); - n = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)30); - - mir_snprintf(s, sizeof(s), "%s 60 %s", lpszEvery, lpszSeconds); - n = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_ADDSTRING,0,(LPARAM)s); - SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)60); - - if (NewReminderVisible == 2 && pEditReminder->RepeatSound) - { - mir_snprintf(s, sizeof(s), "%s %d %s", lpszEvery, pEditReminder->RepeatSound, lpszSeconds); - SetDlgItemText(Dialog, IDC_COMBO_REPEATSND, s); - SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETCURSEL,SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_FINDSTRINGEXACT,(WPARAM)-1,(LPARAM)s),0); - } - else - { - SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETCURSEL,0,0); - } - } - - // populate sound selection combo - { - int n = SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_ADDSTRING,0,(LPARAM)Translate("Default")); - SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)0); - n = SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_ADDSTRING,0,(LPARAM)Translate("Alternative 1")); - SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)1); - n = SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_ADDSTRING,0,(LPARAM)Translate("Alternative 2")); - SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)2); - n = SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_ADDSTRING,0,(LPARAM)Translate("None")); - SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)-1); - - if (NewReminderVisible == 2 && pEditReminder->SoundSel) - { - const UINT n = pEditReminder->SoundSel<0 ? 3 : pEditReminder->SoundSel; - SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_SETCURSEL,n,0); - } - else - { - SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_SETCURSEL,0,0); - } - } - - hIcon = Skin_GetIconByHandle(hIconLibItem[12]); - SendDlgItemMessage(Dialog,IDC_BTN_PLAYSOUND,BM_SETIMAGE,(WPARAM)IMAGE_ICON,(LPARAM)hIcon); - - if (NewReminderVisible == 2 && pEditReminder->SoundSel) - { - EnableWindow(GetDlgItem(Dialog, IDC_BTN_PLAYSOUND), pEditReminder->SoundSel>=0); - EnableWindow(GetDlgItem(Dialog, IDC_COMBO_REPEATSND), pEditReminder->SoundSel>=0); - } - - if (NewReminderVisible == 2) - SetFocus( GetDlgItem(Dialog, IDC_ADDREMINDER) ); - else - SetFocus( GetDlgItem(Dialog, IDC_REMINDER) ); - - return FALSE; - } - case WM_NCDESTROY: - RemoveProp(GetDlgItem(Dialog, IDC_DATE), TEXT("OldWndProc")); - return TRUE; - case WM_CLOSE: - { - if (NewReminderVisible == 2) - { - pEditReminder->RemVisible = FALSE; - } - DestroyWindow(Dialog); - NewReminderVisible = FALSE; - pEditReminder = NULL; - return TRUE; - } - case WM_NOTIFY: - { - if (wParam == IDC_DATE) - { - NMLISTVIEW *NM = (NMLISTVIEW*)lParam; - - switch (NM->hdr.code) - { - case DTN_DATETIMECHANGE: - OnDateChanged(Dialog, IDC_DATE, IDC_TIME, IDC_REFTIME); - break; - } - } - } - break; - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case IDC_TIME: - switch (HIWORD(wParam)) - { - case CBN_KILLFOCUS: - // reformat displayed value - if (SendDlgItemMessage(Dialog, IDC_TIME, CB_GETCURSEL, 0, 0) == CB_ERR) - { - char buf[64]; - int h, m; - GetDlgItemText(Dialog, IDC_TIME, buf, 30); - - if ( ParseTime(buf, &h, &m, FALSE, IsRelativeCombo(Dialog, IDC_TIME)) ) - { - SYSTEMTIME Date; - SendDlgItemMessage(Dialog,IDC_DATE,DTM_GETSYSTEMTIME,0,(LPARAM)&Date); - ReformatTimeInput(Dialog, IDC_TIME, IDC_REFTIME, h, m, &Date); - } - else - { - SendDlgItemMessage(Dialog, IDC_TIME, CB_SETCURSEL, 0, 0); - } - } - break; - } - break; - case IDC_COMBO_SOUND: - switch (HIWORD(wParam)) - { - case CBN_SELENDOK: - { - int n = SendDlgItemMessage(Dialog, IDC_COMBO_SOUND, CB_GETCURSEL, 0, 0); - n = (int)SendDlgItemMessage(Dialog, IDC_COMBO_SOUND, CB_GETITEMDATA, (WPARAM)n, 0); - - EnableWindow(GetDlgItem(Dialog, IDC_BTN_PLAYSOUND), n>=0); - EnableWindow(GetDlgItem(Dialog, IDC_COMBO_REPEATSND), n>=0); - } - break; - } - break; - - case IDC_BTN_PLAYSOUND: - { - int n = SendDlgItemMessage(Dialog, IDC_COMBO_SOUND, CB_GETCURSEL, 0, 0); - n = (int)SendDlgItemMessage(Dialog, IDC_COMBO_SOUND, CB_GETITEMDATA, (WPARAM)n, 0); - switch (n) - { - case 0: SkinPlaySound("AlertReminder"); break; - case 1: SkinPlaySound("AlertReminder2"); break; - case 2: SkinPlaySound("AlertReminder3"); break; - } - } - return TRUE; - case IDC_CLOSE: - { - if (NewReminderVisible == 2) - { - pEditReminder->RemVisible = FALSE; - } - DestroyWindow(Dialog); - NewReminderVisible = FALSE; - pEditReminder = NULL; - return TRUE; - } - case IDC_VIEWREMINDERS: - { - ListReminders(); - return TRUE; - } - case IDC_ADDREMINDER: - { - char *ReminderText = NULL; - int SzT; - SYSTEMTIME Date; - REMINDERDATA* TempRem; - int RepeatSound; - - SendDlgItemMessage(Dialog,IDC_DATE,DTM_GETSYSTEMTIME,0,(LPARAM)&Date); - - if ( !GetTriggerTime(Dialog, IDC_TIME, IDC_REFTIME, &Date) ) - break; - - RepeatSound = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_GETCURSEL,0,0); - if (RepeatSound != CB_ERR) - RepeatSound = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_GETITEMDATA,(WPARAM)RepeatSound,0); - else - RepeatSound = 0; - - SzT = SendDlgItemMessage(Dialog,IDC_REMINDER,WM_GETTEXTLENGTH,0,0); - if (SzT) - { - if (SzT > MAX_REMINDER_LEN) SzT = MAX_REMINDER_LEN; - ReminderText = (char*)malloc(SzT+1); - SendDlgItemMessage(Dialog,IDC_REMINDER,WM_GETTEXT,SzT+1,(LPARAM)ReminderText); - } - - if (NewReminderVisible != 2) - { - // new reminder - TempRem = (REMINDERDATA*)malloc(sizeof(REMINDERDATA)); - TempRem->uid = CreateUid(); - SYSTEMTIMEtoFILETIME(&Date, (FILETIME*)&TempRem->When); - TempRem->Reminder = ReminderText; - TempRem->RemVisible = FALSE; - TempRem->SystemEventQueued = 0; - TempRem->RepeatSoundTTL = 0; - TempRem->SoundSel = (int)SendDlgItemMessage(Dialog, IDC_COMBO_SOUND, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(Dialog, IDC_COMBO_SOUND, CB_GETCURSEL, 0, 0), 0); - TempRem->RepeatSound = TempRem->SoundSel<0 ? 0 : (UINT)RepeatSound; - TreeAddSorted(&RemindersList,TempRem,ReminderSortCb); - } - else - { - // update existing reminder - - SYSTEMTIMEtoFILETIME(&Date, (FILETIME*)&pEditReminder->When); - if (pEditReminder->Reminder) - free(pEditReminder->Reminder); - pEditReminder->Reminder = ReminderText; - pEditReminder->SoundSel = (int)SendDlgItemMessage(Dialog, IDC_COMBO_SOUND, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(Dialog, IDC_COMBO_SOUND, CB_GETCURSEL, 0, 0), 0); - pEditReminder->RepeatSound = pEditReminder->SoundSel<0 ? 0 : (UINT)RepeatSound; - - // re-insert tree item sorted - TreeDelete(&RemindersList,pEditReminder); - TreeAddSorted(&RemindersList,pEditReminder,ReminderSortCb); - - pEditReminder->RemVisible = FALSE; - } - SetDlgItemText(Dialog,IDC_REMINDER,""); - JustSaveReminders(); - NOTIFY_LIST(); - - if (g_CloseAfterAddReminder || NewReminderVisible == 2) - { - DestroyWindow(Dialog); - NewReminderVisible = FALSE; - pEditReminder = NULL; - } - } - } - } - case WM_DESTROY: - { - Skin_ReleaseIcon(hIcon); - break; - } - } - return FALSE; -} - -static void InitListView(HWND AHLV) -{ - LV_ITEM lvTIt; - int I; - char *S; - char S1[128]; - REMINDERDATA *pReminder; - TREEELEMENT *TTE; - - ListView_SetHoverTime(AHLV,700); - ListView_SetExtendedListViewStyle(AHLV,LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_TRACKSELECT); - ListView_DeleteAllItems(AHLV); - - I = 0; - TTE = RemindersList; - while (TTE) - { - pReminder = (REMINDERDATA*)TTE->ptrdata; - - lvTIt.mask = LVIF_TEXT; - - GetTriggerTimeString(&pReminder->When, S1, sizeof(S1), TRUE); - - lvTIt.iItem = I; - lvTIt.iSubItem = 0; - lvTIt.pszText = S1; - lvTIt.cchTextMax = strlen(S1); - ListView_InsertItem(AHLV,&lvTIt); - lvTIt.mask = LVIF_TEXT; - S = GetPreviewString(pReminder->Reminder); - lvTIt.iItem = I; - lvTIt.iSubItem = 1; - lvTIt.pszText = S; - lvTIt.cchTextMax = strlen(S); - ListView_SetItem(AHLV,&lvTIt); - - I++; - TTE = (TREEELEMENT*)TTE->next; - } - - ListView_SetItemState(AHLV,0,LVIS_SELECTED,LVIS_SELECTED); -} - -void OnListResize(HWND Dialog) -{ - HWND hList, hText, hBtnNew, hBtnClose; - RECT lr, cr, tr, clsr; - int th, btnh, btnw, MARGIN; - POINT org = {0}; - - hList = GetDlgItem(Dialog, IDC_LISTREMINDERS); - hText = GetDlgItem(Dialog, IDC_REMINDERDATA); - hBtnNew = GetDlgItem(Dialog, IDC_ADDNEWREMINDER); - hBtnClose = GetDlgItem(Dialog, IDC_CLOSE); - - ClientToScreen(Dialog, &org); - GetClientRect(Dialog, &cr); - - GetWindowRect(hList, &lr); OffsetRect(&lr, -org.x, -org.y); - GetWindowRect(hText, &tr); OffsetRect(&tr, -org.x, -org.y); - GetWindowRect(hBtnClose, &clsr); OffsetRect(&clsr, -org.x, -org.y); - - MARGIN = lr.left; - - th = tr.bottom - tr.top; - btnh = clsr.bottom - clsr.top; - btnw = clsr.right - clsr.left; - - clsr.left = cr.right - MARGIN - btnw; - clsr.top = cr.bottom - MARGIN - btnh; - - tr.left = MARGIN; - tr.right = cr.right - MARGIN; - tr.bottom = clsr.top - MARGIN - 2; - tr.top = tr.bottom - th; - - lr.right = cr.right - MARGIN; - lr.bottom = tr.top - 5; - - MoveWindow(hList, lr.left, lr.top, lr.right-lr.left, lr.bottom-lr.top, FALSE); - MoveWindow(hText, tr.left, tr.top, tr.right-tr.left, tr.bottom-tr.top, FALSE); - - MoveWindow(hBtnClose, clsr.left, clsr.top, btnw, btnh, FALSE); - clsr.left -= btnw + 2; - MoveWindow(hBtnNew, clsr.left, clsr.top, btnw, btnh, FALSE); - - RedrawWindow(Dialog, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE); - //UpdateWindow(Dialog); -} - -void UpdateGeomFromWnd(HWND Dialog, int *geom, int *colgeom, int nCols) -{ - if (geom) - { - WINDOWPLACEMENT wp; - wp.length = sizeof(WINDOWPLACEMENT); - - GetWindowPlacement(Dialog, &wp); - - geom[0] = wp.rcNormalPosition.left; - geom[1] = wp.rcNormalPosition.top; - geom[2] = wp.rcNormalPosition.right - wp.rcNormalPosition.left; - geom[3] = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; - } - - if (colgeom) - { - int i; - HWND H = GetDlgItem(Dialog, IDC_LISTREMINDERS); - - for (i=0; iSystemEventQueued) - mii.fState |= MFS_GRAYED; - SetMenuItemInfo(FhMenu, ID_CONTEXTMENUREMINDERLISTVIEW_EDIT, FALSE, &mii); - - if (!pReminder) - EnableMenuItem(FhMenu, IDM_DELETEREMINDER, MF_GRAYED|MF_BYCOMMAND); - - CallService(MS_LANGPACK_TRANSLATEMENU,(DWORD)FhMenu,0); - TrackPopupMenu(FhMenu,TPM_LEFTALIGN | TPM_RIGHTBUTTON,LOWORD(lParam),HIWORD(lParam),0,AhWnd,0); - DestroyMenu(hMenuLoad); - return TRUE; -} - -int CALLBACK DlgProcViewReminders(HWND Dialog,UINT Message,WPARAM wParam,LPARAM lParam) -{ - LV_COLUMN lvCol; - NMLISTVIEW *NM; - char *S; - int I; - - switch (Message) - { - case WM_SIZE: - { - OnListResize(Dialog); - UpdateGeomFromWnd(Dialog, g_reminderListGeom, NULL, 0); - break; - } - case WM_MOVE: - UpdateGeomFromWnd(Dialog, g_reminderListGeom, NULL, 0); - break; - case WM_GETMINMAXINFO: - { - MINMAXINFO *mm = (MINMAXINFO*)lParam; - mm->ptMinTrackSize.x = 394; - mm->ptMinTrackSize.y = 300; - } - return 0; - case WM_RELOAD: - { - SetDlgItemText(Dialog,IDC_REMINDERDATA,""); - InitListView(GetDlgItem(Dialog,IDC_LISTREMINDERS)); - return TRUE; - } - case WM_CONTEXTMENU: - { - HWND H; - REMINDERDATA *pReminder = NULL; - - H = GetDlgItem(Dialog,IDC_LISTREMINDERS); - if ( ListView_GetSelectedCount(H) ) - { - I = ListView_GetSelectionMark(H); - if (I != -1) - { - pReminder = (REMINDERDATA*)TreeGetAt(RemindersList,I); - } - } - - if ( DoListContextMenu(Dialog, wParam, lParam, pReminder) ) - return TRUE; - } - break; - case WM_INITDIALOG: - { - HWND H; - - HICON hIcon = Skin_GetIconByHandle(hIconLibItem[6], ICON_SMALL); - SendMessage(Dialog, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIcon); - hIcon = Skin_GetIconByHandle(hIconLibItem[6], ICON_BIG); - SendMessage(Dialog, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hIcon); - - TranslateDialogDefault(Dialog); - SetDlgItemText(Dialog,IDC_REMINDERDATA,""); - H = GetDlgItem(Dialog,IDC_LISTREMINDERS); - lvCol.mask = LVCF_TEXT | LVCF_WIDTH; - S = Translate("Reminder text"); - lvCol.pszText = S; - lvCol.cchTextMax = strlen(S); - lvCol.cx = g_reminderListColGeom[1]; - ListView_InsertColumn(H,0,&lvCol); - lvCol.mask = LVCF_TEXT | LVCF_WIDTH; - S = Translate("Date of activation"); - lvCol.pszText = S; - lvCol.cchTextMax = strlen(S); - lvCol.cx = g_reminderListColGeom[0]; - ListView_InsertColumn(H,0,&lvCol); - InitListView(H); - SetWindowLong(GetDlgItem(H, 0), GWL_ID, IDC_LISTREMINDERS_HEADER); - LV = Dialog; - - if (g_reminderListGeom[1] && g_reminderListGeom[2]) - { - WINDOWPLACEMENT wp; - wp.length = sizeof(WINDOWPLACEMENT); - GetWindowPlacement(Dialog, &wp); - wp.rcNormalPosition.left = g_reminderListGeom[0]; - wp.rcNormalPosition.top = g_reminderListGeom[1]; - wp.rcNormalPosition.right = g_reminderListGeom[2] + g_reminderListGeom[0]; - wp.rcNormalPosition.bottom = g_reminderListGeom[3] + g_reminderListGeom[1]; - SetWindowPlacement(Dialog, &wp); - } - return TRUE; - } - case WM_CLOSE: - { - DestroyWindow(Dialog); - ListReminderVisible = FALSE; - return TRUE; - } - case WM_NOTIFY: - { - if (wParam == IDC_LISTREMINDERS) - { - NM = (NMLISTVIEW *)lParam; - switch (NM->hdr.code) - { - case LVN_ITEMCHANGED: - { - S = ((REMINDERDATA*)TreeGetAt(RemindersList,NM->iItem))->Reminder; - SetDlgItemText(Dialog,IDC_REMINDERDATA,S); - } - break; - case NM_DBLCLK: - { - HWND H; - - H = GetDlgItem(Dialog,IDC_LISTREMINDERS); - if ( ListView_GetSelectedCount(H) ) - { - I = ListView_GetSelectionMark(H); - if (I != -1) - { - EditReminder((REMINDERDATA*)TreeGetAt(RemindersList, I)); - } - } - } - break; - } - } - else if (wParam == IDC_LISTREMINDERS_HEADER) - { - NMHEADER *NM = (NMHEADER*)lParam; - switch (NM->hdr.code) - { - case HDN_ENDTRACK: - UpdateGeomFromWnd(Dialog, NULL, g_reminderListColGeom, SIZEOF(g_reminderListColGeom)); - break; - } - } - } - break; - case WM_COMMAND: - { - switch(LOWORD(wParam)) - { - case ID_CONTEXTMENUREMINDERLISTVIEW_EDIT: - { - HWND H; - - H = GetDlgItem(Dialog,IDC_LISTREMINDERS); - if ( ListView_GetSelectedCount(H) ) - { - I = ListView_GetSelectionMark(H); - if (I != -1) - { - EditReminder((REMINDERDATA*)TreeGetAt(RemindersList, I)); - } - } - } - return TRUE; - case IDC_CLOSE: - { - DestroyWindow(Dialog); - ListReminderVisible = FALSE; - return TRUE; - } - case IDM_NEWREMINDER: - case IDC_ADDNEWREMINDER: - { - NewReminder(); - return TRUE; - } - case IDM_DELETEALLREMINDERS: - if (RemindersList && MessageBox(Dialog, Translate("Are you sure you want to delete all reminders?"), SECTIONNAME, MB_OKCANCEL) == IDOK) - { - SetDlgItemText(Dialog,IDC_REMINDERDATA,""); - DeleteReminders(); - InitListView(GetDlgItem(Dialog,IDC_LISTREMINDERS)); - } - return TRUE; - case IDM_DELETEREMINDER: - { - HWND H; - - H = GetDlgItem(Dialog,IDC_LISTREMINDERS); - if ( ListView_GetSelectedCount(H) ) - { - I = ListView_GetSelectionMark(H); - if (I != -1 - && MessageBox(Dialog, Translate("Are you sure you want to delete this reminder?"), SECTIONNAME, MB_OKCANCEL) == IDOK) - { - SetDlgItemText(Dialog,IDC_REMINDERDATA,""); - DeleteReminder((REMINDERDATA*)TreeGetAt(RemindersList, I)); - JustSaveReminders(); - InitListView(H); - } - } - return TRUE; - } - } - } - case WM_DESTROY: - { - CallService(MS_SKIN2_RELEASEICONBIG, (WPARAM)SendMessage(Dialog, WM_SETICON, ICON_BIG, (LPARAM)NULL), 0); - CallService(MS_SKIN2_RELEASEICON, (WPARAM)SendMessage(Dialog, WM_SETICON, ICON_SMALL, (LPARAM)NULL), 0); - break; - } - } - return FALSE; -} - - -///////////////////////////////////////////////////////////////////// -// Email/SMS and WinSock functions - -BOOL WS_Init() -{ - WSADATA wsd; - if (WSAStartup(MAKEWORD(2,2),&wsd)!=0) return FALSE; - return TRUE; -} - -void WS_CleanUp() -{ - WSACleanup(); -} - -int WS_Send(SOCKET s,char *data,int datalen) -{ - int rlen; - if ((rlen = send(s,data,datalen,0)) == SOCKET_ERROR) return FALSE; - return TRUE; -} - -unsigned long WS_ResolveName(char *name,WORD *port,int defaultPort) -{ - HOSTENT *lk; - char *pcolon,*nameCopy; - DWORD ret; - nameCopy=_strdup(name); - if(port != NULL) *port = defaultPort; - pcolon = strchr(nameCopy,':'); - if(pcolon != NULL) - { - if(port != NULL) *port = atoi(pcolon+1); - *pcolon = 0; - } - if (inet_addr(nameCopy) == INADDR_NONE) - { - lk = gethostbyname(nameCopy); - if(lk == 0) return SOCKET_ERROR; - else {free(nameCopy); return *(u_long*)lk->h_addr_list[0];} - } - ret=inet_addr(nameCopy); - free(nameCopy); - return ret; -} - -void Send(char *user, char *host, char *Msg, char *server) -{ - SOCKADDR_IN sockaddr; - WORD port; - char *ch = NULL; - S = socket(AF_INET,SOCK_STREAM,0); - if (!server) server = host; - if ((sockaddr.sin_addr.S_un.S_addr = WS_ResolveName(server, - &port,25))==SOCKET_ERROR) return; - sockaddr.sin_port = htons(port); - sockaddr.sin_family = AF_INET; - if(connect(S,(SOCKADDR*)&sockaddr,sizeof(sockaddr)) == SOCKET_ERROR) return; - ch = (char*)malloc(strlen(user) + strlen(host) + 16); - ch = (char*)realloc(ch,sprintf(ch,"rcpt to:%s@%s\r\n",user,host)); - WS_Send(S,"mail from: \r\n",13); - WS_Send(S,ch,strlen(ch)); - WS_Send(S,"data\r\n",6); - WS_Send(S,"From:\r\n\r\n",14); - WS_Send(S,Msg,strlen(Msg)); - WS_Send(S,"\r\n.\r\n",5); - WS_Send(S,"quit\r\n",6); - SAFE_FREE((void**)&ch); - closesocket(S); -} diff --git a/!NotAdopted/NotesAndReminders/src/resource.h b/!NotAdopted/NotesAndReminders/src/resource.h deleted file mode 100644 index 0ddf8b4031..0000000000 --- a/!NotAdopted/NotesAndReminders/src/resource.h +++ /dev/null @@ -1,65 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by resource.rc -// -#define IDD_STNOTEOPTIONS 101 -#define IDD_ADDREMINDER 102 -#define IDD_NOTIFYREMINDER 103 -#define IDD_LISTREMINDERS 104 -#define IDI_ADDREMINDER 110 -#define IDI_DELETEICON 111 -#define IDI_NOTEICON 112 -#define IDI_SHOWHIDE 113 -#define IDI_CAPTIONICON 114 -#define IDI_DELETEREMINDER 115 -#define IDI_VIEWREMINDERS 116 -#define IDI_CAPTIONICONNOTTOP 117 -#define IDI_HIDENOTE 118 -#define IDI_REMOVENOTE 119 -#define IDI_REMINDER 120 -#define IDI_BRINGFRONT 121 -#define IDI_PLAYSOUND 122 -#define IDI_VIEWNOTES 123 - -#define IDC_COMBODATE 1021 -#define IDC_COMBOTIME 1022 -#define IDC_COMBOREMINDERTIME 1023 -#define IDC_REFTIME 1024 -#define IDC_STATIC_DATE 1025 -#define IDC_STATIC_TIME 1026 -#define IDC_COMBO_REPEATSND 1028 -#define IDC_COMBO_SOUND 1029 -#define IDC_BTN_PLAYSOUND 1030 -#define IDC_EDIT_ALTBROWSER 1031 -#define IDC_BTN_BROWSEBROWSER 1032 -#define ID_CONTEXTMENUNOTEPOPUP_NEWNOTE 40009 -#define ID_CONTEXTMENUNOTEPOPUP_BRINGALLTOTOP 40010 -#define ID_CONTEXTMENUNOTEPOPUP_APPEARANCE 40011 -#define ID_APPEARANCE_BACKGROUNDCOLOR 40013 -#define ID_APPEARANCE_TEXTCOLOR 40014 -#define ID_APPEARANCE_CUSTOMTEXT 40015 -#define ID_APPEARANCE_CUSTOMBG 40016 -#define ID_BACKGROUNDCOLOR_RESET 40017 -#define ID_TEXTCOLOR_RESET 40018 -#define ID_CONTEXTMENUNOTEPOPUP_PASTETITLE 40019 -#define ID_CONTEXTMENUNOTEPOPUP_RESETTITLE 40020 -#define ID_CONTEXTMENUREMINDERLISTVIEW_EDIT 40021 -#define ID_CONTEXTMENUNOTELISTVIEW_EDITNOTE 40022 -#define ID_CONTEXTMENUNOTELISTVIEW_SHOW 40023 -#define ID_CONTEXTMENUNOTELISTVIEW_DELETEALLNOTES 40024 -#define ID_CONTEXTMENUNOTEPOPUP_VIEWNOTES 40025 -#define ID_CONTEXTMENUNOTELISTVIEW_TOGGLEVISIBILITY 40026 -#define ID_APPEARANCE_FONT 40027 -#define ID_APPEARANCE_CUSTOMFONT 40028 -#define ID_FONT_RESET 40029 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 106 -#define _APS_NEXT_COMMAND_VALUE 40030 -#define _APS_NEXT_CONTROL_VALUE 1033 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/!NotAdopted/SMS/!clear.bat b/!NotAdopted/SMS/!clear.bat deleted file mode 100644 index f35ebe94fd..0000000000 --- a/!NotAdopted/SMS/!clear.bat +++ /dev/null @@ -1,36 +0,0 @@ -@echo off - -del .\*.aps /q -del .\*.clw /q -del .\*.ncb /q -rem del .\*.opt /q -del .\*.plg /q - -del .\Release\*.obj /q -del .\Release\*.pch /q -del .\Release\*.pdb /q -del .\Release\*.idb /q -del .\Release\*.res /q -del .\Release\*.exp /q -del .\Release\*.sbr /q -del .\Release\*.map /q -del .\Release\*.cod /q - -del .\debug\*.obj /q -del .\debug\*.pch /q -del .\debug\*.pdb /q -del .\debug\*.idb /q -del .\debug\*.res /q -del .\debug\*.ilk /q -del .\debug\*.exp /q -del .\debug\*.sbr /q -del .\debug\*.asm /q -del .\debug\*.cod /q -del .\debug\*.map /q -del .\debug\*.opt /q -del .\debug\*._xe /q -del .\debug\*.pbi /q -del .\debug\*.pbo /q -del .\debug\*.pbt /q -del .\debug\*.map /q -del .\debug\*.cod /q diff --git a/!NotAdopted/SMS/AdditionalFunctions/BuffToLowerCase.h b/!NotAdopted/SMS/AdditionalFunctions/BuffToLowerCase.h deleted file mode 100644 index d2bb7a6671..0000000000 --- a/!NotAdopted/SMS/AdditionalFunctions/BuffToLowerCase.h +++ /dev/null @@ -1,56 +0,0 @@ -#if !defined(AFX_BUFFTOLOWERCASE__H__INCLUDED_) -#define AFX_BUFFTOLOWERCASE__H__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - - - -__inline DWORD BuffToLowerCase(LPCVOID lpcOutBuff,LPCVOID lpcBuff,SIZE_T dwLen) -{ - DWORD dwRetErrorCode=NO_ERROR; - - __asm - { - mov ecx,dwLen - test ecx,ecx - jz short end_func - - push ebx // сохраняем регистр - push edi // сохраняем регистр - push esi // сохраняем регистр - mov esi,lpcBuff - mov edi,lpcOutBuff - mov bl,'A' - mov bh,'Z' - mov ah,32 - cld - - lowcaseloop: - lodsb - cmp al,bl - jl short savebyte - cmp al,bh - jg short savebyte - or al,ah - - savebyte: - stosb - - dec ecx - jnz short lowcaseloop - - pop esi // восстанавливаем содержимое регистра - pop edi // восстанавливаем содержимое регистра - pop ebx // восстанавливаем содержимое регистра - end_func: - } - -return(dwRetErrorCode); -} - - - - -#endif // !defined(AFX_BUFFTOLOWERCASE__H__INCLUDED_) \ No newline at end of file diff --git a/!NotAdopted/SMS/AdditionalFunctions/DebugFunctions.h b/!NotAdopted/SMS/AdditionalFunctions/DebugFunctions.h deleted file mode 100644 index 8b21d1bc5a..0000000000 --- a/!NotAdopted/SMS/AdditionalFunctions/DebugFunctions.h +++ /dev/null @@ -1,101 +0,0 @@ -#if !defined(AFX_DEBUG_FUNCTIONS__H__INCLUDED_) -#define AFX_DEBUG_FUNCTIONS__H__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#ifndef szCRLF -#define szCRLF TEXT("\r\n") -#endif -////////////////////////////////////////////////////////////////////////// -////////////////////////////DebugPrint//////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -// DebugBuildPrint(Helo world); -// Отображение текста в Debug окне во время отладки -#ifdef _DEBUG - #define DebugPrintA(szText) OutputDebugStringA((szText)) - #define DebugPrintW(szText) OutputDebugStringW((szText)) - #define DebugPrintCRLFA(szText) OutputDebugStringA((szText));OutputDebugStringA("\r\n") - #define DebugPrintCRLFW(szText) OutputDebugStringW((szText));OutputDebugStringW(L"\r\n") -#else - #define DebugPrintA(szText) - #define DebugPrintW(szText) - #define DebugPrintCRLFA(szText) - #define DebugPrintCRLFW(szText) -#endif //_DEBUG - - -#ifdef UNICODE - #define DebugPrint DebugPrintW - #define DebugPrintCRLF DebugPrintCRLFW -#else - #define DebugPrint DebugPrintA - #define DebugPrintCRLF DebugPrintCRLFA -#endif -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - - - - -////////////////////////////////////////////////////////////////////////// -////////////////////////////DebugBuildPrint/////////////////////////////// -////////////////////////////////////////////////////////////////////////// -// #pragma DebugBuildPrint(Helo world); -// Отображение сообщений в Build окне во время компиляции -#ifdef _DEBUG - #pragma warning(disable:4081) - #define chSTR2(x) #x - #define chSTR(x) chSTR2(x) - #define DebugBuildPrint(szText) message(__FILE__ "(" chSTR(__LINE__) "): " #szText) - #pragma warning(default:4081) -#else - #define DebugBuildPrint(szText) -#endif //_DEBUG -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - - - - -////////////////////////////////////////////////////////////////////////// -////////////////////////////DebugBufferFill/////////////////////////////// -////////////////////////////////////////////////////////////////////////// -// DebugBufferFill(szString,sizeof(szString)); -// Полностью заполняет переданный буффер символом "A", применяется -// для выходного буффера на входе в функцию. -#ifdef _DEBUG - #define DebugBufferFill(lpBuffer,dwSize) memset(lpBuffer,'A',dwSize) -#else - #define DebugBufferFill(lpBuffer,dwSize) -#endif //_DEBUG -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - - - - -////////////////////////////////////////////////////////////////////////// -////////////////////////////DebugBreak//////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -// DebugBreak(); -// Точка останова, более удобная альтернатива API -#if defined(_DEBUG) && defined(_X86_) - #define DebugBreak() _asm{int 3} -#else - #define DebugBreak() -#endif //_DEBUG -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - - - - - - -#endif // !defined(AFX_DEBUG_FUNCTIONS__H__INCLUDED_) diff --git a/!NotAdopted/SMS/AdditionalFunctions/InterlockedFunctions.h b/!NotAdopted/SMS/AdditionalFunctions/InterlockedFunctions.h deleted file mode 100644 index 3fb008b216..0000000000 --- a/!NotAdopted/SMS/AdditionalFunctions/InterlockedFunctions.h +++ /dev/null @@ -1,127 +0,0 @@ -#if !defined(AFX_INTERLOCKED_FUNCTIONS__H__INCLUDED_) -#define AFX_INTERLOCKED_FUNCTIONS__H__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - - - - - -#ifdef InterlockedCompareExchange -#ifndef InterlockedAnd -LONG FORCEINLINE InterlockedAnd(LONG volatile *Destination,LONG Value) -{ - LONG Old; - - do - { - Old=*Destination; - }while(InterlockedCompareExchange(Destination,(Old&Value),Old)!=Old); -return(Old); -} -#endif //InterlockedAnd - - -#ifndef InterlockedOr -LONG FORCEINLINE InterlockedOr(LONG volatile *Destination,LONG Value) -{ - LONG Old; - - do - { - Old=*Destination; - }while(InterlockedCompareExchange(Destination,(Old|Value),Old)!=Old); -return(Old); -} -#endif //InterlockedOr - - -#ifndef InterlockedXor -LONG FORCEINLINE InterlockedXor(LONG volatile *Destination,LONG Value) -{ - LONG Old; - - do - { - Old=*Destination; - }while(InterlockedCompareExchange(Destination,(Old^Value),Old)!=Old); -return(Old); -} -#endif //InterlockedXor -#endif //InterlockedCompareExchange - - - - - -#ifdef InterlockedCompareExchange64 -#ifndef InterlockedAnd64 -LONGLONG FORCEINLINE InterlockedAnd64(LONGLONG volatile *Destination,LONGLONG Value) -{ - LONGLONG Old; - - do - { - Old=*Destination; - }while(InterlockedCompareExchange64(Destination,(Old&Value),Old)!=Old); -return(Old); -} -#endif //InterlockedAnd64 - - -#ifndef InterlockedOr64 -LONGLONG FORCEINLINE InterlockedOr64(LONGLONG volatile *Destination,LONGLONG Value) -{ - LONGLONG Old; - - do - { - Old=*Destination; - }while(InterlockedCompareExchange64(Destination,(Old|Value),Old)!=Old); -return(Old); -} -#endif //InterlockedOr64 - - -#ifndef InterlockedXor64 -LONGLONG FORCEINLINE InterlockedXor64(LONGLONG volatile *Destination,LONGLONG Value) -{ - LONGLONG Old; - - do - { - Old=*Destination; - }while(InterlockedCompareExchange64(Destination,(Old^Value),Old)!=Old); -return(Old); -} -#endif //InterlockedXor64 -#endif //InterlockedCompareExchange64 - - - - - -#ifndef InterlockedIncrementPointer -#if defined(_WIN64) -#define InterlockedIncrementPointer(lpAddend) (LPVOID)InterlockedIncrement64((LONGLONG volatile*)lpAddend) -#else -#define InterlockedIncrementPointer(lpAddend) (LPVOID)InterlockedIncrement((LONG volatile*)lpAddend) -#endif -#endif //InterlockedIncrementPointer - - -#ifndef InterlockedDecrementPointer -#if defined(_WIN64) -#define InterlockedDecrementPointer(lpAddend) (LPVOID)InterlockedDecrement64((LONGLONG volatile*)lpAddend) -#else -#define InterlockedDecrementPointer(lpAddend) (LPVOID)InterlockedDecrement((LONG volatile*)lpAddend) -#endif -#endif //InterlockedDecrementPointer - - - - - -#endif // !defined(AFX_INTERLOCKED_FUNCTIONS__H__INCLUDED_) diff --git a/!NotAdopted/SMS/AdditionalFunctions/ListMT.h b/!NotAdopted/SMS/AdditionalFunctions/ListMT.h deleted file mode 100644 index 7cf1e81808..0000000000 --- a/!NotAdopted/SMS/AdditionalFunctions/ListMT.h +++ /dev/null @@ -1,328 +0,0 @@ -#if !defined(AFX_LIST_MT__H__INCLUDED_) -#define AFX_LIST_MT__H__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - - -#include - -#if defined(_MSC_VER) -#if _MSC_VER >= 800 -#if _MSC_VER >= 1200 -#pragma warning(push) -#endif -#pragma warning(disable:4312) // warning C4312: 'type cast' : conversion from 'LONG' to 'PVOID' of greater size -#endif -#endif - - -// структура для работы со списком, элемент списка -typedef struct _LIST_MT_ITEM -{ -#ifdef __cplusplus - _LIST_MT_ITEM *plmtiPrev; // *предыдущий элемент в списке - _LIST_MT_ITEM *plmtiNext; // *следующий элемент в списке -#else - LPVOID *plmtiPrev; // *предыдущий элемент в списке - LPVOID *plmtiNext; // *следующий элемент в списке -#endif - LPVOID lpData; // указатель на данные, связанные с элементом списка - LPVOID lpListMT; // указатель на заголовок списка, см структуру ниже -}LIST_MT_ITEM, *PLIST_MT_ITEM, *LPLIST_MT_ITEM; -typedef CONST PLIST_MT_ITEM PCLIST_MT_ITEM, LPCLIST_MT_ITEM; - - -// структура для работы со списком, заголовок списка -typedef struct _LIST_MT -{ - SIZE_T nCount; // *колличество элементов в списке - PLIST_MT_ITEM plmtiFirst; // *указывает на первый элемент в списке - PLIST_MT_ITEM plmtiLast; // *указывает на последний элемент в списке - CRITICAL_SECTION cs; // *section for exclysive access to List -}LIST_MT, *PLIST_MT, *LPLIST_MT; -typedef CONST PLIST_MT PCLIST_MT, LPCLIST_MT; - - -// структура для работы с итератором -typedef struct _LIST_MT_ITERATOR -{ - PLIST_MT_ITEM plmtListMTItem; -}LIST_MT_ITERATOR, *PLIST_MT_ITERATOR, *LPLIST_MT_ITERATOR; -//typedef LIST_MT_ITEM LIST_MT_ITERATOR, *PLIST_MT_ITERATOR, *LPLIST_MT_ITERATOR; -typedef CONST PLIST_MT_ITERATOR PCLIST_MT_ITERATOR, LPCLIST_MT_ITERATOR; - - - - -__inline DWORD ListMTInitialize(PCLIST_MT pclmtListMT,DWORD dwSpinCount) -{ - DWORD dwRetErrorCode; - -#if (_WIN32_WINNT >= 0x0403) - if (InitializeCriticalSectionAndSpinCount(&pclmtListMT->cs,((dwSpinCount)? (dwSpinCount | 0x80000000):0L))) -#else - InitializeCriticalSection(&pclmtListMT->cs); - if (TRUE) -#endif - { - InterlockedExchangePointer(&pclmtListMT->nCount,NULL); - pclmtListMT->plmtiFirst=NULL; - pclmtListMT->plmtiLast=NULL; - dwRetErrorCode=NO_ERROR; - }else{ - dwRetErrorCode=GetLastError(); - } -return(dwRetErrorCode); -} - - -__inline void ListMTDestroy(PCLIST_MT pclmtListMT) -{ - InterlockedExchangePointer(&pclmtListMT->nCount,NULL); - pclmtListMT->plmtiFirst=NULL; - pclmtListMT->plmtiLast=NULL; - DeleteCriticalSection(&pclmtListMT->cs); -} - - -__inline BOOL ListMTTryLock(PCLIST_MT pclmtListMT) -{ -#if (_WIN32_WINNT >= 0x0400) - return(TryEnterCriticalSection(&pclmtListMT->cs)); -#else - return(FALSE); -#endif -} - - -__inline void ListMTLock(PCLIST_MT pclmtListMT) -{ - EnterCriticalSection(&pclmtListMT->cs); -} - - -__inline void ListMTUnLock(PCLIST_MT pclmtListMT) -{ - LeaveCriticalSection(&pclmtListMT->cs); -} - - -__inline SIZE_T ListMTGetCount(PCLIST_MT pclmtListMT) -{ - return((SIZE_T)InterlockedCompareExchangePointer((LPVOID*)&pclmtListMT->nCount,NULL,NULL)); -} - - -__inline SIZE_T ListMTItemAdd(PCLIST_MT pclmtListMT,PCLIST_MT_ITEM pclmtListMTItem,LPVOID lpData) -{ - SIZE_T dwRet=(SIZE_T)InterlockedIncrementPointer(&pclmtListMT->nCount);//pclmtListMT->nCount++; - pclmtListMTItem->lpData=lpData; - pclmtListMTItem->lpListMT=pclmtListMT; - - if (pclmtListMT->plmtiLast) - {// add node to end of list - pclmtListMTItem->plmtiPrev=pclmtListMT->plmtiLast; - pclmtListMTItem->plmtiNext=NULL; - pclmtListMT->plmtiLast->plmtiNext=pclmtListMTItem; - pclmtListMT->plmtiLast=pclmtListMTItem; - }else{// add the first node to the linked list - pclmtListMTItem->plmtiPrev=NULL; - pclmtListMTItem->plmtiNext=NULL; - pclmtListMT->plmtiFirst=pclmtListMTItem; - pclmtListMT->plmtiLast=pclmtListMTItem; - } - -return(dwRet); -} - - -__inline DWORD ListMTItemDelete(PCLIST_MT pclmtListMT,PCLIST_MT_ITEM pclmtListMTItem) -{ - DWORD dwRetErrorCode; - - if (pclmtListMTItem->lpListMT==pclmtListMT && pclmtListMT) - {// Данный элемент принадлежит к этому списку, можно удалить. - PLIST_MT_ITEM plmtiPrevNode=pclmtListMTItem->plmtiPrev,plmtiNextNode=pclmtListMTItem->plmtiNext; - - if (plmtiPrevNode || plmtiNextNode) - { - if (plmtiPrevNode && plmtiNextNode==NULL) - {// This is the start node in the list to delete - // отключился последний подключившийся - plmtiPrevNode->plmtiNext=NULL; - pclmtListMT->plmtiLast=plmtiPrevNode; - }else{ - if (plmtiPrevNode==NULL && plmtiNextNode) - {// This is the end node in the list to delete - // отключился первый подключившийся - plmtiNextNode->plmtiPrev=NULL; - pclmtListMT->plmtiFirst=plmtiNextNode; - }else{// оключился клиент не первый и не последний - //if (plmtiPrev && plmtiNext) - {// Neither start node nor end node in the list - plmtiPrevNode->plmtiNext=plmtiNextNode; - plmtiNextNode->plmtiPrev=plmtiPrevNode; - } - } - } - }else{// This is the only node in the list to delete - pclmtListMT->plmtiFirst=NULL; - pclmtListMT->plmtiLast=NULL; - } - - pclmtListMTItem->lpListMT=NULL; - InterlockedDecrementPointer(&pclmtListMT->nCount);// pclmtListMT->nCount--; - dwRetErrorCode=NO_ERROR; - }else{// попытались удалить элемент не относящийся к данному списку - dwRetErrorCode=ERROR_INVALID_HANDLE; - } -return(dwRetErrorCode); -} - - -__inline LPVOID ListMTItemDataGet(PCLIST_MT_ITEM pclmtListMTItem) -{ - return(pclmtListMTItem->lpData); -} - - -__inline void ListMTItemDataSet(PCLIST_MT_ITEM pclmtListMTItem, LPVOID lpData) -{ - pclmtListMTItem->lpData=lpData; -} - - -__inline DWORD ListMTItemGetFirst(PCLIST_MT pclmtListMT,PLIST_MT_ITEM *pplmtListMTItem,LPVOID *plpData) -{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock - DWORD dwRetErrorCode; - - if (pclmtListMT->plmtiFirst) - { - if (pplmtListMTItem) (*pplmtListMTItem)=pclmtListMT->plmtiFirst; - if (plpData) (*plpData)=pclmtListMT->plmtiFirst->lpData; - dwRetErrorCode=NO_ERROR; - }else{ - dwRetErrorCode=ERROR_NO_MORE_ITEMS; - } -return(dwRetErrorCode); -} - - -__inline DWORD ListMTItemGetLast(PCLIST_MT pclmtListMT,PLIST_MT_ITEM *pplmtListMTItem,LPVOID *plpData) -{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock - DWORD dwRetErrorCode; - - if (pclmtListMT->plmtiLast) - { - if (pplmtListMTItem) (*pplmtListMTItem)=pclmtListMT->plmtiLast; - if (plpData) (*plpData)=pclmtListMT->plmtiLast->lpData; - dwRetErrorCode=NO_ERROR; - }else{ - dwRetErrorCode=ERROR_NO_MORE_ITEMS; - } -return(dwRetErrorCode); -} - - - -__inline void ListMTItemSwap(PCLIST_MT pclmtListMT,PCLIST_MT_ITEM pclmtListMTItem1,PCLIST_MT_ITEM pclmtListMTItem2) -{// поменять два элемента списка местами, даже если они из разных списков - - if (pclmtListMTItem1!=pclmtListMTItem2) - {// это разные элементы списка - PLIST_MT_ITEM lpTemp; - - lpTemp=pclmtListMTItem1->plmtiPrev; - if ((pclmtListMTItem1->plmtiPrev=pclmtListMTItem2->plmtiPrev)==NULL) - {// pclmtListMTItem2 был первым, обновляем заголвок листа, теперь первый pclmtListMTItem1 - pclmtListMT->plmtiFirst=pclmtListMTItem1; - } - - if ((pclmtListMTItem2->plmtiPrev=lpTemp)==NULL) - {// pclmtListMTItem1 был первым, обновляем заголвок листа, теперь первый pclmtListMTItem2 - pclmtListMT->plmtiFirst=pclmtListMTItem2; - } - - - lpTemp=pclmtListMTItem1->plmtiNext; - if ((pclmtListMTItem1->plmtiNext=pclmtListMTItem2->plmtiNext)==NULL) - {// pclmtListMTItem2 был последним, обновляем заголвок листа, теперь последний pclmtListMTItem1 - pclmtListMT->plmtiLast=pclmtListMTItem1; - } - - if ((pclmtListMTItem2->plmtiNext=lpTemp)==NULL) - {// pclmtListMTItem1 был последним, обновляем заголвок листа, теперь последний pclmtListMTItem2 - pclmtListMT->plmtiLast=pclmtListMTItem2; - } - } -} - - -__inline BOOL ListMTIteratorMoveFirst(PCLIST_MT pclmtListMT,PCLIST_MT_ITERATOR pclmtiIterator) -{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock - return((pclmtiIterator->plmtListMTItem=pclmtListMT->plmtiFirst)? TRUE:FALSE); -} - - -__inline BOOL ListMTIteratorMoveLast(PCLIST_MT pclmtListMT,PCLIST_MT_ITERATOR pclmtiIterator) -{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock - return((pclmtiIterator->plmtListMTItem=pclmtListMT->plmtiLast)? TRUE:FALSE); -} - - -__inline BOOL ListMTIteratorMovePrev(PCLIST_MT_ITERATOR pclmtiIterator) -{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock - BOOL bRet=FALSE; - - if (pclmtiIterator->plmtListMTItem) - { - if (pclmtiIterator->plmtListMTItem=pclmtiIterator->plmtListMTItem->plmtiPrev) bRet=TRUE; - } -return(bRet); -} - - -__inline BOOL ListMTIteratorMoveNext(PCLIST_MT_ITERATOR pclmtiIterator) -{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock - BOOL bRet=FALSE; - - if (pclmtiIterator->plmtListMTItem) - { - if (pclmtiIterator->plmtListMTItem=pclmtiIterator->plmtListMTItem->plmtiNext) bRet=TRUE; - } -return(bRet); -} - - -__inline DWORD ListMTIteratorGet(PCLIST_MT_ITERATOR pclmtiIterator,PLIST_MT_ITEM *pplmtListMTItem,LPVOID *plpData) -{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock - DWORD dwRetErrorCode; - - if (pclmtiIterator->plmtListMTItem) - { - if (pplmtListMTItem) (*pplmtListMTItem)=pclmtiIterator->plmtListMTItem; - if (plpData) (*plpData)=pclmtiIterator->plmtListMTItem->lpData; - dwRetErrorCode=NO_ERROR; - }else{ - dwRetErrorCode=ERROR_NO_MORE_ITEMS; - } -return(dwRetErrorCode); -} - - - -#if defined(_MSC_VER) -#if _MSC_VER >= 800 -#if _MSC_VER >= 1200 -#pragma warning(pop) -#else -#pragma warning(default:4312) // warning C4312: 'type cast' : conversion from 'LONG' to 'PVOID' of greater size -#endif -#endif -#endif - - - -#endif // !defined(AFX_LIST_MT__H__INCLUDED_) diff --git a/!NotAdopted/SMS/AdditionalFunctions/MemoryCompare.h b/!NotAdopted/SMS/AdditionalFunctions/MemoryCompare.h deleted file mode 100644 index de663c6d8a..0000000000 --- a/!NotAdopted/SMS/AdditionalFunctions/MemoryCompare.h +++ /dev/null @@ -1,177 +0,0 @@ -#if !defined(AFX_MEMORYCOMPARE__H__INCLUDED_) -#define AFX_MEMORYCOMPARE__H__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - - -// If the string pointed to by lpString1 is less than the string pointed -// to by lpString2, the return value is negative. -// If the string pointed to by lpString1 is greater than the string pointed -// to by lpString2, the return value is positive. -// If the strings are equal, the return value is zero. -// -// lpString1> ret=1=CSTR_LESS_THAN -// lpString1=lpString2 >> ret=2=CSTR_EQUAL -// lpString1>lpString2 >> ret=3=CSTR_GREATER_THAN - - -/*__inline DWORD MemoryCompare(LPCVOID lpcSource1,SIZE_T dwSource1Size,LPCVOID lpcSource2,SIZE_T dwSource2Size) -{ - DWORD dwRet; - - __asm - { - mov ecx,dwSource1Size //; ecx = Source string 1 Size - cmp ecx,dwSource2Size //; сверяем длинны участков памяти - jg short greater_than - jl short less_than - test ecx,ecx - jz short equal //; NULL=NULL - - mov esi,lpcSource1 //; edi = Source string 1 - mov edi,lpcSource2 //; esi = Source string 2 - cmp edi,esi //; сверяем указатели на участки памяти - je short equal //; это один и тотже участок, они естественно равны - - test esi,esi //; lpcSource1=NULL, lpcSource1lpcSource2 - jz short greater_than //; CSTR_GREATER_THAN - - //cld //; сканируя в прямом направлении - - repe cmpsb //; цикл сравнения. - cmp_loop: - //sub ecx,4 - //jz short equal - - //inc esi - //inc edi - //mov al,byte ptr [esi] - //cmpsd - //cmp al,byte ptr [edi] - //je short cmp_loop - jg short greater_than - jl short less_than - - equal: //; если мы попали сюда, значит, они - mov dwRet,CSTR_EQUAL //; совпадают (match) - jmp end_func - less_than: //; не совпадают - mov dwRet,CSTR_LESS_THAN - jmp end_func - greater_than: - mov dwRet,CSTR_GREATER_THAN - - end_func: - } -return(dwRet); -}//*/ - -__inline DWORD MemoryCompare(LPCVOID lpcSource1,SIZE_T dwSource1Size,LPCVOID lpcSource2,SIZE_T dwSource2Size) -{ - DWORD dwRet; - - if (dwSource1Size==dwSource2Size) - { - if (lpcSource1==lpcSource2) - { - dwRet=CSTR_EQUAL; - }else{ - if (lpcSource1 && lpcSource2) - { -#ifdef _INC_MEMORY - dwRet=(2+memcmp(lpcSource1,lpcSource2,dwSource1Size)); -#else - SIZE_T dwDiffPosition; - - //dwDiffPosition=RtlCompareMemory(lpcSource1,lpcSource2,dwSource1Size); - for(dwDiffPosition=0; (dwDiffPosition(*((BYTE*)(((SIZE_T)lpcSource2)+dwDiffPosition)))) - { - dwRet=CSTR_GREATER_THAN; - }else{ - dwRet=CSTR_LESS_THAN; - } - } -#endif - }else{ - if (lpcSource1) - {//lpcSource2==NULL - dwRet=CSTR_GREATER_THAN; - }else{//lpcSource1==NULL - dwRet=CSTR_LESS_THAN; - } - } - } - }else{ - if (dwSource1Size(*((BYTE*)(((SIZE_T)lpcSource2)+dwDiffPosition)))) - { - dwRet=CSTR_GREATER_THAN; - }else{ - dwRet=CSTR_LESS_THAN; - } - } - - if (pdwDiffPosition) (*pdwDiffPosition)=dwDiffPosition; - }else{ - if (lpcSource1) - {//lpcSource2==NULL - dwRet=CSTR_GREATER_THAN; - }else{//lpcSource1==NULL - dwRet=CSTR_LESS_THAN; - } - } - } - }else{ - if (dwSource1Size 1000 -#pragma once -#endif // _MSC_VER > 1000 - -__inline LPVOID MemoryFind(SIZE_T dwFrom,LPCVOID lpcSource,SIZE_T dwSourceSize,LPCVOID lpcWhatFind,SIZE_T dwWhatFindSize) -{ - LPVOID lpRet=NULL; - - __asm - { - push ebx // сохраняем регистр - push edi // сохраняем регистр - push esi // сохраняем регистр - - mov ecx,dwSourceSize //; ecx = Source string Size - test ecx,ecx // is size unknown? - jz short end_func - - mov edx,dwWhatFindSize //; edx = WhatFind string Size - test edx,edx // is size unknown? - jz short end_func - - mov ebx,dwFrom // ebx - start pos in Source string - mov edi,lpcSource //; edi = Source string - mov esi,lpcWhatFind //; esi = WhatFind string - - cmp ebx,ecx // проверка ecx(=len)=>ulFrom - jae short end_func - - add edi,ebx // сдвигаем начало на ulFrom(нач смещен) - sub ecx,ebx // уменьшаем длинну SourceSize на ulFrom(нач смещен) - - cmp ecx,edx // проверка NEWSourceSize ??? ulWhatFindSize - je short begin_memorycompare // NEWulSourceSize==ulWhatFindSize, Source ??? WhatFind - jl short end_func // NEWulSourceSize Source!=WhatFind - - sub ecx,edx // уменьшаем длинну SourceSize на ulWhatFindSize - inc ecx - - mov al,[esi] //; al=search byte - dec edi - cld //; сканируя в прямом направлении - - find_loop: - test ecx,ecx - jz short end_func - inc edi - repne scasb //; find that byte - dec edi //; di points to byte which stopped scan - - cmp [edi],al //; see if we have a hit - jne short end_func //; yes, point to byte - - begin_memorycompare: - push esi - push edi - push ecx - mov ecx,edx //; ulWhatFindSize байтов (CX используется в REPE), - repe cmpsb //; сравниваем их. - pop ecx - pop edi - pop esi - jne short find_loop //; признак ZF = 0, если сравниваемые - //; строки не совпадают (mismatch) match: - //; если мы попали сюда, значит, они - //; совпадают (match) - mov lpRet,edi //; ax=pointer to byte - end_func: - - pop esi // восстанавливаем содержимое регистра - pop edi // восстанавливаем содержимое регистра - pop ebx // восстанавливаем содержимое регистра - } -return(lpRet); -} - - -#endif // !defined(AFX_MEMORYFIND__H__INCLUDED_) diff --git a/!NotAdopted/SMS/AdditionalFunctions/MemoryFindByte.h b/!NotAdopted/SMS/AdditionalFunctions/MemoryFindByte.h deleted file mode 100644 index 0dcc1f91a6..0000000000 --- a/!NotAdopted/SMS/AdditionalFunctions/MemoryFindByte.h +++ /dev/null @@ -1,71 +0,0 @@ -#if !defined(AFX_MEMORYFINDBYTE__H__INCLUDED_) -#define AFX_MEMORYFINDBYTE__H__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - - - -__inline LPVOID MemoryFindByte(SIZE_T dwFrom,LPCVOID lpcSource,SIZE_T dwSourceSize,unsigned char chWhatFind) -{ - LPVOID lpRet=NULL; - - if (lpcSource && dwSourceSize) - { - if (dwFromdwFrom - jae short end_func - - std //; count 'up' on string this time - sub ecx,eax //; уменьшаем длинну на dwFrom(нач смещен) - add edi,ecx //; сдвигаем начало на dwSourceSize(на конец) - mov al,chWhatFind //; al=search byte - repne scasb //; find that byte - inc edi //; di points to byte which stopped scan - cmp [edi],al //; see if we have a hit - jne short end_func //; yes, point to byte - mov lpRet,edi //; ax=pointer to byte - end_func: - - cld - pop esi // восстанавливаем содержимое регистра - pop edi // восстанавливаем содержимое регистра - pop ebx // восстанавливаем содержимое регистра - } -return(lpRet); -} - - - -#endif // !defined(AFX_MEMORYFINDBYTE__H__INCLUDED_) diff --git a/!NotAdopted/SMS/SMS.def b/!NotAdopted/SMS/SMS.def deleted file mode 100644 index 3ec70ac7bb..0000000000 --- a/!NotAdopted/SMS/SMS.def +++ /dev/null @@ -1,8 +0,0 @@ -LIBRARY SMS - -EXPORTS - MirandaPluginInfo @1 - MirandaPluginInfoEx @2 - MirandaPluginInterfaces @3 - Load @4 - Unload @5 diff --git a/!NotAdopted/SMS/SMSConstans.h b/!NotAdopted/SMS/SMSConstans.h deleted file mode 100644 index ddaddc3df7..0000000000 --- a/!NotAdopted/SMS/SMSConstans.h +++ /dev/null @@ -1,108 +0,0 @@ -#if !defined(AFX_SMS_CONSTANS_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_) -#define AFX_SMS_CONSTANS_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_ - - - - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - - - -// {CF97FD5D-B911-47a8-AF03-D21968B5B894} -#define SMS_GUID { 0xcf97fd5d, 0xb911, 0x47a8, { 0xaf, 0x3, 0xd2, 0x19, 0x68, 0xb5, 0xb8, 0x94 } } - - -#define MIN_MIR_VER_VERSION_DWORD PLUGIN_MAKE_VERSION(0,8,0,0) - - -#define PLUGIN_VERSION_DWORD PLUGIN_MAKE_VERSION(0,2,5,3) -#define PROTOCOL_NAMEA "SMSPlugin" -#define PROTOCOL_NAMEW TEXT(PROTOCOL_NAMEA) -#define PROTOCOL_NAME_LEN (sizeof(PROTOCOL_NAMEA)-1) -#define PROTOCOL_NAME_SIZE sizeof(PROTOCOL_NAMEA) -#define PROTOCOL_DISPLAY_NAME_ORIG "SMS" -#define PROTOCOL_DISPLAY_NAME_ORIGW TEXT(PROTOCOL_DISPLAY_NAME_ORIG) - - - - -#define TIMEOUT_MSGSEND 60000 // send sms timeout -#define MIN_SMS_DBEVENT_LEN 4 // для фильтрации событий авторизации от джабер плагина -#define MAX_PHONE_LEN MAX_PATH -#define PHONES_MIN_COUNT 4 //internal // колличество элементов обязательно проверяемых при извлечении email адреса из инфы юзера -#define SMS_PLUGIN_UPDATER_ID 4187 //появляется после первого выкладывания на сайт - - - -#define SMS_DEFAULT_ -#define SMS_DEFAULT_SIGNATUREPOS FALSE -#define SMS_DEFAULT_SHOWACK TRUE -#define SMS_DEFAULT_USESIGNATURE TRUE -#define SMS_DEFAULT_AUTOPOP FALSE -#define SMS_DEFAULT_SAVEWINPOS FALSE - - - -// -#define ICQEVENTTYPE_SMSCONFIRMATION 3001 - - -//Fonts defenitions -//#define SRMMMOD "SRMM" -#define SRMMMOD "TabSRMM_Fonts" - -#define FONTF_BOLD 1 -#define FONTF_ITALIC 2 -struct FontOptionsList -{ - COLORREF defColour; - TCHAR* szDefFace; - BYTE defStyle; - char defSize; -} - -static fontOptionsList[] = { - { RGB(106, 106, 106), _T("Arial"), 0, -12}, -}; - - -#define MSGFONTID_MYMSG 0 -#define MSGFONTID_YOURMSG 2 -#define MSGFONTID_MESSAGEAREA 16 - - -#define SRMSGSET_BKGCOLOUR "BkgColour" -#define SRMSGSET_INPBKGCOLOUR "inputbg" -#define SRMSGDEFSET_BKGCOLOUR GetSysColor(COLOR_WINDOW) -#define FONTF_BOLD 1 -#define FONTF_ITALIC 2 - - - -//Decleration of functions that used when user hit miranda for new message/confirmation -int ReadAckSMS(WPARAM wParam,LPARAM lParam); -int ReadMsgSMS(WPARAM wParam,LPARAM lParam); -int SendSMSMenuCommand(WPARAM wParam,LPARAM lParam); - - - -#define SMS_READ "/ReadSms" -#define SMS_READ_ACK "/ReadSmsAck" -#define SMS_SEND "/SendSMS" -#define SMS_SEND_STR L"Send &SMS..." -#define SMS_SEND_CM_STR L"&SMS Message" - - -static const SERVICE_ITEM siPluginServices[] = -{ - { SMS_READ, ReadMsgSMS }, - { SMS_READ_ACK, ReadAckSMS }, - { SMS_SEND, SendSMSMenuCommand }, -}; - - - - -#endif // !defined(AFX_SMS_CONSTANS_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_) diff --git a/!NotAdopted/SMS/SMS_svc.cpp b/!NotAdopted/SMS/SMS_svc.cpp deleted file mode 100644 index 24e6d1ad2f..0000000000 --- a/!NotAdopted/SMS/SMS_svc.cpp +++ /dev/null @@ -1,243 +0,0 @@ -#include "main.h" - - - -int LoadServices(void) -{ - CHAR szServiceFunction[MAX_PATH],*pszServiceFunctionName; - - CopyMemory(szServiceFunction,PROTOCOL_NAMEA,PROTOCOL_NAME_SIZE); - pszServiceFunctionName=szServiceFunction+PROTOCOL_NAME_LEN; - - // Service creation - for (SIZE_T i=0;ihDbEvent,0))!=-1) - { - dbei.pBlob=(PBYTE)MEMALLOC(dbei.cbBlob); - if (dbei.pBlob) - { - if (CallService(MS_DB_EVENT_GET,(WPARAM)((CLISTEVENT*)lParam)->hDbEvent,(LPARAM)&dbei)==0) - if (dbei.eventType==ICQEVENTTYPE_SMS || dbei.eventType==ICQEVENTTYPE_SMSCONFIRMATION) - if (dbei.cbBlob>MIN_SMS_DBEVENT_LEN) - { - if (RecvSMSWindowAdd(((CLISTEVENT*)lParam)->hContact,ICQEVENTTYPE_SMS,NULL,0,(LPSTR)dbei.pBlob,dbei.cbBlob)) - { - CallService(MS_DB_EVENT_MARKREAD,(WPARAM)((CLISTEVENT*)lParam)->hContact,(LPARAM)((CLISTEVENT*)lParam)->hDbEvent); - iRet=0; - } - } - MEMFREE(dbei.pBlob); - } - } -return(iRet); -} - -//This function used to popup a read SMS window after the user clicked on the received SMS confirmation. -int ReadAckSMS(WPARAM wParam,LPARAM lParam) -{ - int iRet=1; - DBEVENTINFO dbei={0}; - - dbei.cbSize=sizeof(dbei); - if ((dbei.cbBlob=CallService(MS_DB_EVENT_GETBLOBSIZE,(WPARAM)((CLISTEVENT*)lParam)->hDbEvent,0))!=-1) - { - dbei.pBlob=(PBYTE)MEMALLOC(dbei.cbBlob); - if (dbei.pBlob) - { - if (CallService(MS_DB_EVENT_GET,(WPARAM)((CLISTEVENT*)lParam)->hDbEvent,(LPARAM)&dbei)==0) - if (dbei.eventType==ICQEVENTTYPE_SMS || dbei.eventType==ICQEVENTTYPE_SMSCONFIRMATION) - if (dbei.cbBlob>MIN_SMS_DBEVENT_LEN) - { - if (RecvSMSWindowAdd(((CLISTEVENT*)lParam)->hContact,ICQEVENTTYPE_SMSCONFIRMATION,NULL,0,(LPSTR)dbei.pBlob,dbei.cbBlob)) - { - CallService(MS_DB_EVENT_DELETE,(WPARAM)((CLISTEVENT*)lParam)->hContact,(LPARAM)((CLISTEVENT*)lParam)->hDbEvent); - iRet=0; - } - } - MEMFREE(dbei.pBlob); - } - } -return(iRet); -} - -void RestoreUnreadMessageAlerts(void) -{ - DBEVENTINFO dbei={0}; - HANDLE hDbEvent,hContact; - - dbei.cbSize=sizeof(dbei); - for(hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);hContact!=NULL;hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)) - for(hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDFIRSTUNREAD,(WPARAM)hContact,0);hDbEvent!=NULL;hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hDbEvent,0)) - { - dbei.cbBlob=0; - if (CallService(MS_DB_EVENT_GET,(WPARAM)hDbEvent,(LPARAM)&dbei)==0) - if ((dbei.flags&(DBEF_SENT|DBEF_READ))==0 && ((dbei.eventType==ICQEVENTTYPE_SMS) || (dbei.eventType==ICQEVENTTYPE_SMSCONFIRMATION))) - if (dbei.cbBlob>MIN_SMS_DBEVENT_LEN) - { - handleNewMessage((WPARAM)hContact,(LPARAM)hDbEvent); - } - } - - hContact=NULL; - for(hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDFIRSTUNREAD,(WPARAM)hContact,0);hDbEvent!=NULL;hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hDbEvent,0)) - { - dbei.cbBlob=0; - if (CallService(MS_DB_EVENT_GET,(WPARAM)hDbEvent,(LPARAM)&dbei)==0) - if ((dbei.flags&(DBEF_SENT|DBEF_READ))==0 && ((dbei.eventType==ICQEVENTTYPE_SMS) || (dbei.eventType==ICQEVENTTYPE_SMSCONFIRMATION))) - if (dbei.cbBlob>MIN_SMS_DBEVENT_LEN) - { - handleNewMessage((WPARAM)hContact,(LPARAM)hDbEvent); - } - } -} - - - - - - - - - - - - - - - - diff --git a/!NotAdopted/SMS/functions.cpp b/!NotAdopted/SMS/functions.cpp deleted file mode 100644 index aebafa42d8..0000000000 --- a/!NotAdopted/SMS/functions.cpp +++ /dev/null @@ -1,761 +0,0 @@ -#include "main.h" - - - - - -BOOL DB_GetStaticStringW(HANDLE hContact,LPSTR lpszModule,LPSTR lpszValueName,LPWSTR lpwszRetBuff,SIZE_T dwRetBuffSize,SIZE_T *pdwRetBuffSize) -{// sizes in wchars - BOOL bRet=FALSE; - SIZE_T dwReadedStringLen; - DBVARIANT dbv={0}; - DBCONTACTGETSETTING sVal={0}; - - dbv.type=DBVT_WCHAR; - sVal.pValue=&dbv; - sVal.szModule=lpszModule; - sVal.szSetting=lpszValueName; - if (CallService(MS_DB_CONTACT_GETSETTING_STR,(WPARAM)hContact,(LPARAM)&sVal)==0) - { - dwReadedStringLen=lstrlenW(dbv.pwszVal); - if (lpwszRetBuff && (dwRetBuffSize>dwReadedStringLen)) - { - CopyMemory(lpwszRetBuff,dbv.pszVal,(dwReadedStringLen*sizeof(WCHAR)));//include null terminated - (*((WCHAR*)(lpwszRetBuff+dwReadedStringLen)))=0; - bRet=TRUE; - }else{ - if (lpwszRetBuff && dwRetBuffSize>=sizeof(WCHAR)) (*((WCHAR*)lpwszRetBuff))=0; - } - if (pdwRetBuffSize) (*pdwRetBuffSize)=dwReadedStringLen; - - DBFreeVariant(&dbv); - }else{ - if (lpwszRetBuff && dwRetBuffSize>=sizeof(WCHAR)) (*((WCHAR*)lpwszRetBuff))=0; - if (pdwRetBuffSize) (*pdwRetBuffSize)=0; - } -return(bRet); -} - - -BOOL DB_SetStringExW(HANDLE hContact,LPSTR lpszModule,LPSTR lpszValueName,LPWSTR lpwszValue,SIZE_T dwValueSize) -{ - BOOL bRet=FALSE; - - if (lpwszValue && dwValueSize) - { - LPWSTR lpwszValueLocal=(LPWSTR)MEMALLOC(((dwValueSize+MAX_PATH)*sizeof(WCHAR))); - - if (lpwszValueLocal) - { - DBCONTACTWRITESETTING cws={0}; - - cws.szModule=lpszModule; - cws.szSetting=lpszValueName; - cws.value.type=DBVT_WCHAR; - cws.value.pwszVal=(WCHAR*)lpwszValueLocal; - CopyMemory(lpwszValueLocal,lpwszValue,(dwValueSize*sizeof(WCHAR))); - bRet=(CallService(MS_DB_CONTACT_WRITESETTING,(WPARAM)hContact,(LPARAM)&cws)==0); - - MEMFREE(lpwszValueLocal); - } - }else{ - bRet=TRUE; - DBDeleteContactSetting(hContact,lpszModule,lpszValueName); - } -return(bRet); -} - - -LPSTR GetModuleName(HANDLE hContact) -{ - LPSTR lpszRet; - - if (hContact) - { - lpszRet=(LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0); - if (lpszRet==NULL) lpszRet=PROTOCOL_NAMEA; - }else{ - lpszRet=PROTOCOL_NAMEA; - } -return(lpszRet); -} - - -void EnableControlsArray(HWND hWndDlg,WORD *pwControlsList,SIZE_T dwControlsListCount,BOOL bEnabled) -{ - for(SIZE_T i=0;i='0' && btChar<='9') (*lpbOutBuff++)=btChar; - } - (*lpbOutBuff)=0; - -return((lpbOutBuff-(LPBYTE)lpszOutBuff)); -} - -SIZE_T CopyNumberW(LPWSTR lpcOutBuff,LPWSTR lpcBuff,SIZE_T dwLen) -{ - WCHAR wChar; - LPWSTR lpwszOutBuff=lpcOutBuff,lpwszInBuff=lpcBuff; - - for(SIZE_T i=0;i='0' && wChar<='9') (*lpwszOutBuff++)=wChar; - } - (*lpwszOutBuff)=0; - -return((lpwszOutBuff-lpcOutBuff)); -} - - -BOOL IsPhoneW(LPWSTR lpwszString,SIZE_T dwStringLen) -{ - BOOL bRet; - - if (dwStringLen>1) - {// country code - WCHAR wChar; - - bRet=TRUE; - for(SIZE_T i=0;i'9') - if (wChar!='+' && wChar!='S' && wChar!='M' && wChar!=' ' && wChar!='(' && wChar!=')') - { - bRet=FALSE; - break; - } - } - }else{ - bRet=FALSE; - } -return(bRet); -} - - - -DWORD GetContactPhonesCountParam(HANDLE hContact,LPSTR lpszModule,LPSTR lpszValueName) -{ - DWORD dwRet=0; - char szBuff[MAX_PATH]; - WCHAR wszPhone[MAX_PHONE_LEN]; - SIZE_T i,dwPhoneSize; - - if (DB_GetStaticStringW(hContact,lpszModule,lpszValueName,wszPhone,SIZEOF(wszPhone),&dwPhoneSize)) - { - if (IsPhoneW(wszPhone,dwPhoneSize)) dwRet++; - } - - for (i=0;TRUE;i++) - { - mir_snprintf(szBuff,sizeof(szBuff),"%s%ld",lpszValueName,i); - if (DB_GetStaticStringW(hContact,lpszModule,szBuff,wszPhone,SIZEOF(wszPhone),&dwPhoneSize)) - { - if (IsPhoneW(wszPhone,dwPhoneSize)) dwRet++; - }else{ - if (i>PHONES_MIN_COUNT) break; - } - } -return(dwRet); -} - - -DWORD GetContactPhonesCount(HANDLE hContact) -{ - DWORD dwRet=0; - LPSTR lpszProto; - - lpszProto=(LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0); - if (lpszProto) - { - dwRet+=GetContactPhonesCountParam(hContact,lpszProto,"Phone"); - dwRet+=GetContactPhonesCountParam(hContact,lpszProto,"Cellular"); - dwRet+=GetContactPhonesCountParam(hContact,lpszProto,"Fax"); - } - dwRet+=GetContactPhonesCountParam(hContact,"UserInfo","MyPhone"); - dwRet+=GetContactPhonesCountParam(hContact,"UserInfo","Phone"); - dwRet+=GetContactPhonesCountParam(hContact,"UserInfo","Cellular"); - dwRet+=GetContactPhonesCountParam(hContact,"UserInfo","Fax"); - -return(dwRet); -} - - -BOOL IsContactPhoneParam(HANDLE hContact,LPSTR lpszModule,LPSTR lpszValueName,LPWSTR lpwszPhone,SIZE_T dwPhoneSize) -{ - BOOL bRet=FALSE; - char szBuff[MAX_PATH]; - WCHAR wszPhoneLocal[MAX_PHONE_LEN]; - SIZE_T i,dwPhoneSizeLocal; - - if (DB_GetStaticStringW(hContact,lpszModule,lpszValueName,wszPhoneLocal,SIZEOF(wszPhoneLocal),&dwPhoneSizeLocal)) - if (IsPhoneW(wszPhoneLocal,dwPhoneSizeLocal)) - { - dwPhoneSizeLocal=CopyNumberW(wszPhoneLocal,wszPhoneLocal,dwPhoneSizeLocal); - if (MemoryCompare(wszPhoneLocal,dwPhoneSizeLocal,lpwszPhone,dwPhoneSize)==CSTR_EQUAL) - { - bRet=TRUE; - } - } - - for (i=0;bRet==FALSE;i++) - { - mir_snprintf(szBuff,sizeof(szBuff),"%s%ld",lpszValueName,i); - if (DB_GetStaticStringW(hContact,lpszModule,szBuff,wszPhoneLocal,SIZEOF(wszPhoneLocal),&dwPhoneSizeLocal)) - { - if (IsPhoneW(wszPhoneLocal,dwPhoneSizeLocal)) - { - dwPhoneSizeLocal=CopyNumberW(wszPhoneLocal,wszPhoneLocal,dwPhoneSizeLocal); - if (MemoryCompare(wszPhoneLocal,dwPhoneSizeLocal,lpwszPhone,dwPhoneSize)==CSTR_EQUAL) - { - bRet=TRUE; - break; - } - } - }else{ - if (i>PHONES_MIN_COUNT) break; - } - } -return(bRet); -} - - -BOOL IsContactPhone(HANDLE hContact,LPWSTR lpwszPhone,SIZE_T dwPhoneSize) -{ - BOOL bRet=FALSE; - WCHAR wszPhoneLocal[MAX_PHONE_LEN]; - LPSTR lpszProto; - SIZE_T dwPhoneSizeLocal; - - dwPhoneSizeLocal=CopyNumberW(wszPhoneLocal,lpwszPhone,dwPhoneSize); - lpszProto=(LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0); - if (lpszProto) - { - if (bRet==FALSE) bRet=IsContactPhoneParam(hContact,lpszProto,"Phone",wszPhoneLocal,dwPhoneSizeLocal); - if (bRet==FALSE) bRet=IsContactPhoneParam(hContact,lpszProto,"Cellular",wszPhoneLocal,dwPhoneSizeLocal); - if (bRet==FALSE) bRet=IsContactPhoneParam(hContact,lpszProto,"Fax",wszPhoneLocal,dwPhoneSizeLocal); - } - if (bRet==FALSE) bRet=IsContactPhoneParam(hContact,"UserInfo","MyPhone",wszPhoneLocal,dwPhoneSizeLocal); - if (bRet==FALSE) bRet=IsContactPhoneParam(hContact,"UserInfo","Phone",wszPhoneLocal,dwPhoneSizeLocal); - if (bRet==FALSE) bRet=IsContactPhoneParam(hContact,"UserInfo","Cellular",wszPhoneLocal,dwPhoneSizeLocal); - if (bRet==FALSE) bRet=IsContactPhoneParam(hContact,"UserInfo","Fax",wszPhoneLocal,dwPhoneSizeLocal); - -return(bRet); -} - - -//This function get a string cellular number and return the HANDLE of the contact that has this -//number in the miranda phonebook (and marked as an SMS able) at the User Details. -//If no one has this number function returns NULL. -HANDLE HContactFromPhone(LPWSTR lpwszPhone,SIZE_T dwPhoneSize) -{ - HANDLE hContact=NULL; - - if (lpwszPhone && dwPhoneSize) - { - //check not already on list - for(hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);hContact!=NULL;hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)) - { - if (IsContactPhone(hContact,lpwszPhone,dwPhoneSize)) break; - } - } -return(hContact); -} - - -BOOL GetDataFromMessage(LPSTR lpszMessage,SIZE_T dwMessageSize,DWORD *pdwEventType,LPWSTR lpwszPhone,SIZE_T dwPhoneSize,SIZE_T *pdwPhoneSizeRet,UINT *piIcon) -{ - BOOL bRet=FALSE; - - DWORD dwEventTypeRet=0; - SIZE_T dwPhoneSizeRet=0; - UINT iIconRet=0; - - if (lpszMessage && dwMessageSize) - { - LPSTR lpsz; - - if (MemoryCompare(lpszMessage,10,"SMS From: ",10)==CSTR_EQUAL) - { - lpsz=(LPSTR)MemoryFind(10,lpszMessage,dwMessageSize,"\r\n",2); - if (lpsz) - { - if (lpwszPhone && dwPhoneSize) - { - dwPhoneSizeRet=MultiByteToWideChar(CP_UTF8,0,(lpszMessage+10),min((SIZE_T)(lpsz-(lpszMessage+10)),dwPhoneSize),lpwszPhone,dwPhoneSize); - dwPhoneSizeRet=CopyNumberW(lpwszPhone,lpwszPhone,dwPhoneSizeRet); - } - } - iIconRet=0; - dwEventTypeRet=ICQEVENTTYPE_SMS; - bRet=TRUE; - }else - if (MemoryCompare(lpszMessage,23,"SMS Confirmation From: ",23)==CSTR_EQUAL) - { - lpsz=(LPSTR)MemoryFind(23,lpszMessage,dwMessageSize,"\r\n",2); - if (lpsz) - { - if (lpwszPhone && dwPhoneSize) - { - dwPhoneSizeRet=MultiByteToWideChar(CP_UTF8,0,(lpszMessage+23),min((SIZE_T)(lpsz-(lpszMessage+23)),dwPhoneSize),lpwszPhone,dwPhoneSize); - dwPhoneSizeRet=CopyNumberW(lpwszPhone,lpwszPhone,dwPhoneSizeRet); - } - - lpsz+=2; - if (MemoryCompare(lpsz,24,"SMS was sent succesfully",24)==CSTR_EQUAL) - { - iIconRet=IDI_SMSSENT; - }else{ - iIconRet=IDI_SMSNOTSENT; - } - } - dwEventTypeRet=ICQEVENTTYPE_SMSCONFIRMATION; - bRet=TRUE; - } - } - - if (pdwPhoneSizeRet) (*pdwPhoneSizeRet)=dwPhoneSizeRet; - if (pdwEventType) (*pdwEventType)=dwEventTypeRet; - if (piIcon) (*piIcon)=iIconRet; - -return(bRet); -} - -BOOL GetXMLFieldEx(LPSTR lpszXML,SIZE_T dwXMLSize,LPSTR *plpszData,SIZE_T *pdwDataSize,const char *tag1,...) -{ - BOOL bRet=FALSE; - int thisLevel=0; - LPSTR lpszFindTag=(LPSTR)tag1,lpszTagStart,lpszTagEnd=lpszXML,lpszDataStart=NULL; - va_list va; - - va_start(va,tag1); - while(TRUE) - { - lpszTagStart=(LPSTR)MemoryFindByte((lpszTagEnd-lpszXML),lpszXML,dwXMLSize,'<'); - if (lpszTagStart) - { - lpszTagEnd=(LPSTR)MemoryFindByte((lpszTagStart-lpszXML),lpszXML,dwXMLSize,'>'); - if (lpszTagEnd) - { - lpszTagStart++; - lpszTagEnd--; - if ((*((BYTE*)lpszTagStart))=='/') - { - if (--thisLevel<0) - { - if (lpszDataStart) - { - if (plpszData) (*plpszData)=lpszDataStart; - if (pdwDataSize) (*pdwDataSize)=((lpszTagStart-1)-lpszDataStart); - bRet=TRUE; - } - break; - } - }else{ - if (++thisLevel==1) - if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszFindTag,-1,lpszTagStart,((lpszTagEnd+1)-lpszTagStart))==CSTR_EQUAL) - { - lpszFindTag=va_arg(va,LPSTR); - if (lpszFindTag==NULL) lpszDataStart=(lpszTagEnd+2); - thisLevel=0; - } - } - }else{ - break; - } - }else{ - break; - } - } - va_end(va); -return(bRet); -} - - -BOOL GetXMLFieldExBuff(LPSTR lpszXML,SIZE_T dwXMLSize,LPSTR lpszBuff,SIZE_T dwBuffSize,SIZE_T *pdwBuffSizeRet,const char *tag1,...) -{ - BOOL bRet=FALSE; - int thisLevel=0; - LPSTR lpszFindTag=(LPSTR)tag1,lpszTagStart,lpszTagEnd=lpszXML,lpszDataStart=NULL; - va_list va; - - - va_start(va,tag1); - while(TRUE) - { - lpszTagStart=(LPSTR)MemoryFindByte((lpszTagEnd-lpszXML),lpszXML,dwXMLSize,'<'); - if (lpszTagStart) - { - lpszTagEnd=(LPSTR)MemoryFindByte((lpszTagStart-lpszXML),lpszXML,dwXMLSize,'>'); - if (lpszTagEnd) - { - lpszTagStart++; - lpszTagEnd--; - if ((*((BYTE*)lpszTagStart))=='/') - { - if (--thisLevel<0) - { - if (lpszDataStart) - { - SIZE_T dwBuffSizeRet=min((dwBuffSize-2),(SIZE_T)((lpszTagStart-1)-lpszDataStart)); - if (lpszBuff && dwBuffSize) CopyMemory(lpszBuff,lpszDataStart,dwBuffSizeRet);(*((WORD*)(lpszBuff+dwBuffSizeRet)))=0; - if (pdwBuffSizeRet) (*pdwBuffSizeRet)=dwBuffSizeRet; - bRet=TRUE; - } - break; - } - }else{ - if (++thisLevel==1) - if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszFindTag,-1,lpszTagStart,((lpszTagEnd+1)-lpszTagStart))==CSTR_EQUAL) - { - lpszFindTag=va_arg(va,LPSTR); - if (lpszFindTag==NULL) lpszDataStart=(lpszTagEnd+2); - thisLevel=0; - } - } - }else{ - break; - } - }else{ - break; - } - } - va_end(va); - - - if (bRet==FALSE) - { - if (lpszBuff) (*((WORD*)lpszBuff))=0; - if (pdwBuffSizeRet) (*pdwBuffSizeRet)=0; - } - -return(bRet); -} - - -/*BOOL GetXMLFieldExW(LPWSTR lpwszXML,SIZE_T dwXMLSize,LPWSTR *plpwszData,SIZE_T *pdwDataSize,const WCHAR *tag1,...) -{ - BOOL bRet=FALSE; - int thisLevel=0; - LPWSTR lpwszFindTag=(LPWSTR)tag1,lpwszTagStart,lpwszTagEnd=lpwszXML,lpwszDataStart=NULL; - va_list va; - - va_start(va,tag1); - while(TRUE) - { - lpwszTagStart=(LPWSTR)MemoryFind((lpwszTagEnd-lpwszXML),lpwszXML,dwXMLSize,L"<",2); - if (lpwszTagStart) - { - lpwszTagEnd=(LPWSTR)MemoryFind((lpwszTagStart-lpwszXML),lpwszXML,dwXMLSize,L">",2); - if (lpwszTagEnd) - { - lpwszTagStart++; - lpwszTagEnd--; - if ((*((WORD*)lpwszTagStart))==(*((WORD*)"/"))) - { - if (--thisLevel<0) - { - if (lpwszDataStart) - { - if (plpwszData) (*plpwszData)=lpwszDataStart; - if (pdwDataSize) (*pdwDataSize)=((lpwszTagStart-1)-lpwszDataStart); - bRet=TRUE; - } - break; - } - }else{ - if (++thisLevel==1) - if (CompareStringW(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpwszFindTag,-1,lpwszTagStart,((lpwszTagEnd+1)-lpwszTagStart))==CSTR_EQUAL) - { - lpwszFindTag=va_arg(va,LPWSTR); - if (lpwszFindTag==NULL) lpwszDataStart=(lpwszTagEnd+2); - thisLevel=0; - } - } - }else{ - break; - } - }else{ - break; - } - } - va_end(va); -return(bRet); -} - - -BOOL GetXMLFieldExBuffW(LPWSTR lpwszXML,SIZE_T dwXMLSize,LPWSTR lpwszBuff,SIZE_T dwBuffSize,SIZE_T *pdwBuffSizeRet,const WCHAR *tag1,...) -{ - BOOL bRet; - LPWSTR lpwszData; - SIZE_T dwDataSize; - - if ((bRet=GetXMLFieldExW(lpwszXML,dwXMLSize,&lpwszData,&dwDataSize,tag1))) - { - SIZE_T dwBuffSizeRet=min((dwBuffSize-2),dwDataSize); - - if (lpwszBuff && dwBuffSize) CopyMemory(lpwszBuff,lpwszData,dwBuffSizeRet);(*((WORD*)(lpwszBuff+dwBuffSizeRet)))=0; - if (pdwBuffSizeRet) (*pdwBuffSizeRet)=dwBuffSizeRet; - }else{ - if (lpwszBuff) (*((WORD*)lpwszBuff))=0; - if (pdwBuffSizeRet) (*pdwBuffSizeRet)=0; - } - -return(bRet); -}//*/ - - -DWORD ReplaceInBuff(LPVOID lpInBuff,SIZE_T dwInBuffSize,SIZE_T dwReplaceItemsCount,LPVOID *plpInReplaceItems,SIZE_T *pdwInReplaceItemsCounts,LPVOID *plpOutReplaceItems,SIZE_T *pdwOutReplaceItemsCounts,LPVOID lpOutBuff,SIZE_T dwOutBuffSize,SIZE_T *pdwOutBuffSize) -{ - DWORD dwRetErrorCode=NO_ERROR; - LPBYTE *plpszFounded,lpszMessageConvertedCur,lpszMessageCur,lpszMessageCurPrev,lpszMessageConvertedMax; - SIZE_T i,dwFirstFoundedIndex=0,dwFoundedCount=0,dwMemPartToCopy; - -#ifdef _DEBUG //check tables - for(i=0;i(lpszMessageConvertedCur+(dwMemPartToCopy+pdwInReplaceItemsCounts[dwFirstFoundedIndex]))) - { - CopyMemory(lpszMessageConvertedCur,lpszMessageCurPrev,dwMemPartToCopy);lpszMessageConvertedCur+=dwMemPartToCopy; - CopyMemory(lpszMessageConvertedCur,plpOutReplaceItems[dwFirstFoundedIndex],pdwOutReplaceItemsCounts[dwFirstFoundedIndex]);lpszMessageConvertedCur+=pdwOutReplaceItemsCounts[dwFirstFoundedIndex]; - lpszMessageCurPrev=(plpszFounded[dwFirstFoundedIndex]+pdwInReplaceItemsCounts[dwFirstFoundedIndex]); - - for(i=0;i")}; -static const SIZE_T dwXMLSymbolsCount[] ={sizeof(TCHAR), sizeof(TCHAR), sizeof(TCHAR), sizeof(TCHAR), sizeof(TCHAR)}; - -//Decode XML coded string. The function translate special xml code into standard characters. -DWORD DecodeXML(LPTSTR lptszMessage,SIZE_T dwMessageSize,LPTSTR lptszMessageConverted,SIZE_T dwMessageConvertedBuffSize,SIZE_T *pdwMessageConvertedSize) -{ - DWORD dwRet=ReplaceInBuff(lptszMessage,(dwMessageSize*sizeof(TCHAR)),SIZEOF(lpszXMLTags),(LPVOID*)lpszXMLTags,(SIZE_T*)dwXMLTagsCount,(LPVOID*)lpszXMLSymbols,(SIZE_T*)dwXMLSymbolsCount,lptszMessageConverted,(dwMessageConvertedBuffSize*sizeof(TCHAR)),pdwMessageConvertedSize); - - if (pdwMessageConvertedSize) (*pdwMessageConvertedSize)/=sizeof(TCHAR); -return(dwRet); -} - -//Encode XML coded string. The function translate special saved xml characters into special characters. -DWORD EncodeXML(LPTSTR lptszMessage,SIZE_T dwMessageSize,LPTSTR lptszMessageConverted,SIZE_T dwMessageConvertedBuffSize,SIZE_T *pdwMessageConvertedSize) -{ - DWORD dwRet=ReplaceInBuff(lptszMessage,(dwMessageSize*sizeof(TCHAR)),SIZEOF(lpszXMLTags),(LPVOID*)lpszXMLSymbols,(SIZE_T*)dwXMLSymbolsCount,(LPVOID*)lpszXMLTags,(SIZE_T*)dwXMLTagsCount,lptszMessageConverted,(dwMessageConvertedBuffSize*sizeof(TCHAR)),pdwMessageConvertedSize); - - if (pdwMessageConvertedSize) (*pdwMessageConvertedSize)/=sizeof(TCHAR); -return(dwRet); -} - - -//(Taken from Miranda-IM source code:) -BYTE MsgDlgGetFontDefaultCharset(const TCHAR* szFont) -{ - return(DEFAULT_CHARSET); -} - - -void LoadMsgDlgFont(int i,LOGFONT *lf,COLORREF *colour) -{ - int style; - char str[MAX_PATH]; - DBVARIANT dbv; - - if (colour) - { - mir_snprintf(str,sizeof(str),"Font%dCol",i); - (*colour)=DBGetContactSettingDword(NULL,SRMMMOD,str,fontOptionsList[0].defColour); - } - - if (lf) - { - if (DBGetContactSetting(NULL,SRMMMOD,str,&dbv)) - { - lstrcpyn(lf->lfFaceName,fontOptionsList[0].szDefFace,SIZEOF(lf->lfFaceName)); - }else{ - lstrcpyn(lf->lfFaceName,dbv.ptszVal,SIZEOF(lf->lfFaceName)); - DBFreeVariant(&dbv); - } - - mir_snprintf(str,sizeof(str),"Font%dSize",i); - lf->lfHeight=(char)DBGetContactSettingByte(NULL,SRMMMOD,str,fontOptionsList[0].defSize); - lf->lfWidth=0; - lf->lfEscapement=0; - lf->lfOrientation=0; - mir_snprintf(str,sizeof(str),"Font%dSty",i); - style=DBGetContactSettingByte(NULL,SRMMMOD,str,fontOptionsList[0].defStyle); - lf->lfWeight=style&FONTF_BOLD?FW_BOLD:FW_NORMAL; - lf->lfItalic=style&FONTF_ITALIC?1:0; - lf->lfUnderline=0; - lf->lfStrikeOut=0; - mir_snprintf(str,sizeof(str),"Font%dSet",i); - lf->lfCharSet=DBGetContactSettingByte(NULL,SRMMMOD,str,MsgDlgGetFontDefaultCharset(lf->lfFaceName)); - lf->lfOutPrecision=OUT_DEFAULT_PRECIS; - lf->lfClipPrecision=CLIP_DEFAULT_PRECIS; - lf->lfQuality=DEFAULT_QUALITY; - lf->lfPitchAndFamily=DEFAULT_PITCH|FF_DONTCARE; - mir_snprintf(str,sizeof(str),"Font%d",i); - } -} - - -LRESULT CALLBACK MessageSubclassProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) -{ - LRESULT lrRet=0; - WNDPROC OldMessageEditProc=(WNDPROC)GetWindowLongPtr(hwnd,GWL_USERDATA); - - switch(message){ - case WM_CHAR: - if (wParam=='\n' && GetKeyState(VK_CONTROL)&0x8000) - { - PostMessage(GetParent(hwnd),WM_COMMAND,IDOK,0); - return(0); - } - break; - } - - if (OldMessageEditProc) lrRet=CallWindowProc(OldMessageEditProc,hwnd,message,wParam,lParam); - -return(lrRet); -} - - - - -//This function refresh account list. -//It called when SMS plugin loaded and upon change in the account list. -int RefreshAccountList(WPARAM eventCode,LPARAM lParam) -{ - SIZE_T dwAccCount=0,i,dwSMSAccountsCount=0; - PROTOACCOUNT **ppaAccounts; - - ProtoEnumAccounts((int*)&dwAccCount,&ppaAccounts); - - FreeAccountList(); - ssSMSSettings.ppaSMSAccounts=(PROTOACCOUNT**)MEMALLOC((dwAccCount*sizeof(LPVOID))); - if (ssSMSSettings.ppaSMSAccounts) - { - char szServiceName[MAX_PATH]; - - for (i=0;iszModuleName,MS_ICQ_SENDSMS); - if (ServiceExists(szServiceName)) - { - ssSMSSettings.ppaSMSAccounts[dwSMSAccountsCount++]=ppaAccounts[i]; - } - } - } - } - ssSMSSettings.dwSMSAccountsCount=dwSMSAccountsCount; - SendSMSWindowsUpdateAllAccountLists(); - -return(0); -} - -//This function free the global account list. -//This function should be called before list refresh or when SMS plugin unloaded. -void FreeAccountList() -{ - MEMFREE(ssSMSSettings.ppaSMSAccounts); - ssSMSSettings.dwSMSAccountsCount=0; -} - -//This function check if the module is in the account list that supports sms sending in miranda. -/*BOOL IsModuleInAccountList(LPSTR lpszModule) -{ - BOOL bRet=FALSE; - - if (ssSMSSettings.ppaSMSAccounts && ssSMSSettings.dwSMSAccountsCount) - { - for(SIZE_T i=0;iszModuleName,-1,lpszModule,-1)==CSTR_EQUAL) - { - bRet=TRUE; - break; - } - } - } -return(bRet); -}//*/ - diff --git a/!NotAdopted/SMS/langpack_sms.txt b/!NotAdopted/SMS/langpack_sms.txt deleted file mode 100644 index 376dff2c65..0000000000 --- a/!NotAdopted/SMS/langpack_sms.txt +++ /dev/null @@ -1,119 +0,0 @@ -Miranda Language Pack Version 1 -Language: English (UK) for Multi-Status Msgs -Locale: 0809 -Last-Modified-Using: Miranda 0.2.1.0 -Authors: bid, NuKe007 -Author-email: electrodudez@yahoo.com, nuke007@nuke007.tk -Plugins-included: SMS - - -; !!!SMS by Nuke007!!! -; The name of this file should be langpack_sms.txt and be in the miranda directory! -; Under all the [STRING] put your desired text to replace, and in all places that has %d, %s, /r, /n please keep them, because it could cause problem - -[Send &SMS...] - -[&SMS Message] - -[Can't load SMS Plugin, ICQ protocol must be loaded.] - -[SMS Plugin Error] - -[Unknown] - -; Don't forget the %d, and this could be in other langpack files. -[Custom %d] - -[Send SMS] - -[From %s on ICQ:\r\n\r\n] - -[Events] - -[SMS Plugin] - -[Multiple >>] - -[<< Single] - -[SMS message didn't send by ICQ to %s because:\r\n] - -[SMS Confirmation from %s] - -[SMS Message from %s] - -[Incoming SMS Message] - -[View User's History] - -[Add Number To The Multiple List] - -[Save Number To The User's Details Phonebook] - -[Show/Hide Multiple List] - -[Shows How Much Chars You've Typed] - -[The SMS message send to %s timed out.] - -[The phone number should start with a + and consist of numbers, spaces, brackets and hyphens only.] - -[Invalid Phone Number] - -[Error - Message too long] - -[Message is too long, press OK to continue.] - -[Valid phone numbers are of the form '+(country code)(phone number)'. The contents of the phone number portion is dependent on the national layout of phone numbers, but often omits the leading zero.] - -[No Numbers] - -[There must be numbers in the list first.] - -[Signature:] - -[Put signature at the:] - -[Begining] - -[End] - -[Show server notifications:] - -[Yes] - -[No] - -[To:] - -[Number:] - -[Enter message:] - -[&Send] - -[&Close] - -[Chars:] - -[Save number] - -[Add number to list] - -[From:] - -[Message received:] - -[&Reply] - -[Message ID:] - -[Network:] - -[Source:] - -[&Ok] - -[&Try again] - -[&Cancel] \ No newline at end of file diff --git a/!NotAdopted/SMS/main.cpp b/!NotAdopted/SMS/main.cpp deleted file mode 100644 index 64ff1a92f1..0000000000 --- a/!NotAdopted/SMS/main.cpp +++ /dev/null @@ -1,298 +0,0 @@ -/* -Miranda-IM SMS Plugin -Copyright (C) 2001-2 Richard Hughes -Copyright (C) 2007-8 Rozhuk Ivan - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ---------------------------------------------------------------------------- - -This was the original words. -This plugin was modified by Ariel Shulman (NuKe007). -For any comments, problems, etc. contact me at Miranda-IM forums or E-Mail or ICQ. -All the information needed you can find at www.nuke007.tk -Enjoy the code and use it smartly! -*/ - -#include "main.h" - - - - - -extern "C" __declspec(naked) void __cdecl _chkstk() -{ - #define _PAGESIZE_ 4096 - - __asm - { - push ecx - - ; Calculate new TOS. - - lea ecx, [esp] + 8 - 4 ; TOS before entering function + size for ret value - sub ecx, eax ; new TOS - - ; Handle allocation size that results in wraparound. - ; Wraparound will result in StackOverflow exception. - - sbb eax, eax ; 0 if CF==0, ~0 if CF==1 - not eax ; ~0 if TOS did not wrapped around, 0 otherwise - and ecx, eax ; set to 0 if wraparound - - mov eax, esp ; current TOS - and eax, not ( _PAGESIZE_ - 1) ; Round down to current page boundary - - cs10: - cmp ecx, eax ; Is new TOS - jb short cs20 ; in probed page? - mov eax, ecx ; yes. - pop ecx - xchg esp, eax ; update esp - mov eax, dword ptr [eax] ; get return address - mov dword ptr [esp], eax ; and put it at new TOS - ret - - ; Find next lower page and probe - cs20: - sub eax, _PAGESIZE_ ; decrease by PAGESIZE - test dword ptr [eax],eax ; probe page. - jmp short cs10 - - } -}// - - -extern "C" void __declspec(naked) __cdecl _aulldiv() -{// http://tamiaode.3322.org/svn/ntldr/trunk/source/ntldr/ia32/x86stub.cpp - __asm - { - push ebx - push esi - - mov eax,[esp + 24] - or eax,eax - jnz short L1 - - mov ecx,[esp + 20] - mov eax,[esp + 16] - xor edx,edx - div ecx - mov ebx,eax - mov eax,[esp + 12] - div ecx - mov edx,ebx - jmp short L2 - - L1: - mov ecx,eax - mov ebx,[esp + 20] - mov edx,[esp + 14] - mov eax,[esp + 12] - - L3: - shr ecx,1 - rcr ebx,1 - shr edx,1 - rcr eax,1 - or ecx,ecx - jnz short L3 - div ebx - mov esi,eax - - mul dword ptr [esp + 24] - mov ecx,eax - mov eax,[esp + 20] - mul esi - add edx,ecx - jc short L4 - - cmp edx,[esp + 16] - ja short L4 - jb short L5 - cmp eax,[esp + 12] - jbe short L5 - L4: - dec esi - L5: - xor edx,edx - mov eax,esi - - L2: - - pop esi - pop ebx - - ret 16 - } -}// - - - - - -MM_INTERFACE mmi; -PLUGINLINK *pluginLink; -SMS_SETTINGS ssSMSSettings; - - -PLUGININFOEX pluginInfoEx={ - sizeof(PLUGININFOEX), - PROTOCOL_DISPLAY_NAME_ORIG" (Unicode)", - PLUGIN_VERSION_DWORD, - "Send SMS text messages to mobile phones through the IM networks ("__DATE__" "__TIME__")", - "Richard Hughes, Improved by Ariel Shulman, rewritten by Rozhuk Ivan", - "Rozhuk_I@mail.ru", - "© 2001-2 Richard Hughes, 2003 Ariel Shulman, 2007-2009 Rozhuk Ivan (Rozhuk_I@mail.ru)", - "http://miranda-icq.sourceforge.net/", - UNICODE_AWARE, //not transient - 0, //doesn't replace anything built-in - // {70AC2AC9-85C6-4624-9B05-24733FEBB052} - SMS_GUID -}; - - -extern "C" __declspec(dllexport) const MUUID interfaces[]={SMS_GUID,MIID_LAST}; - - - -int OnModulesLoaded (WPARAM wParam,LPARAM lParam); -int OnPreShutdown (WPARAM wParam,LPARAM lParam); -void VersionConversions(); - - - -BOOL WINAPI DllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID lpvReserved) -{ - switch(dwReason){ - case DLL_PROCESS_ATTACH: - ZeroMemory(&ssSMSSettings,sizeof(ssSMSSettings)); - ssSMSSettings.hInstance=hInstance; - ssSMSSettings.hHeap=HeapCreate(0,0,0);//GetProcessHeap(); - DisableThreadLibraryCalls((HMODULE)hInstance); - break; - case DLL_PROCESS_DETACH: - HeapDestroy(ssSMSSettings.hHeap); - ssSMSSettings.hHeap=NULL; - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - break; - } -return(TRUE); -} - -__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) -{ - if (mirandaVersion -#include -#include -#include -#ifdef NDEBUG - #include <..\minicrt\minicrt.h> -#else - #include <..\minicrt\timefuncs.h> -#endif //_DEBUG*/ - -#include -#include -#include -#include -#include -#include -#include "newpluginapi.h" -#include "m_database.h" -#include "m_clist.h" -#include "m_langpack.h" -#include "m_history.h" -#include "m_protomod.h" -#include "m_autoreplacer.h" -#include "resource.h" -#include "m_skin.h" -#include "m_protosvc.h" -#include "m_icq.h" -#include "m_protosvc.h" -#include "m_system.h" -#include "m_utils.h" -#include "m_options.h" -#include "m_updater.h" -#include "win2k.h" - - -// структура содержащая информацию по построению меню или расширеных иконок -struct GUI_DISPLAY_ITEM -{ - LPSTR lpszName; // имя сервиса, оно же имя в иколибе - LPWSTR lpwszDescr; // текстовое описание отображаемое юзеру - LONG defIcon; // иконка из ресурсов - LPVOID lpFunc; // функция вызываемая меню -}; - - -// структура содержащая информацию о сервисах/функциях -struct SERVICE_ITEM -{ - LPSTR lpszName; // имя сервиса, оно же имя в иколибе - LPVOID lpFunc; // функция вызываемая -}; - - - - -#include "SMSConstans.h" -#include "senddlg.h" -#include "recvdlg.h" - - - -#define MAIN_MENU_ITEMS_COUNT 1 -#define CONTACT_MENU_ITEMS_COUNT 1 - - -typedef struct -{ - HANDLE hHeap; - HINSTANCE hInstance; - - //HANDLE hMainMenuIcons[MAIN_MENU_ITEMS_COUNT+1]; - HANDLE hMainMenuItems[MAIN_MENU_ITEMS_COUNT+1]; - - //HANDLE hContactMenuIcons[CONTACT_MENU_ITEMS_COUNT+1]; - HANDLE hContactMenuItems[CONTACT_MENU_ITEMS_COUNT+1]; - - HANDLE hHookModulesLoaded; - HANDLE hHookPreShutdown; - HANDLE hHookOptInitialize; - HANDLE hHookRebuildCMenu; - HANDLE hHookDbAdd; - HANDLE hHookProtoAck; - HANDLE hHookAccListChanged; - - LIST_MT lmtSendSMSWindowsListMT; - LIST_MT lmtRecvSMSWindowsListMT; - - PROTOACCOUNT **ppaSMSAccounts; - SIZE_T dwSMSAccountsCount; - -} SMS_SETTINGS; - - - -extern SMS_SETTINGS ssSMSSettings; - - - - -#define MEMALLOC(Size) HeapAlloc(ssSMSSettings.hHeap,HEAP_ZERO_MEMORY,(Size+sizeof(SIZE_T))) -#define MEMREALLOC(Mem,Size) HeapReAlloc(ssSMSSettings.hHeap,(HEAP_ZERO_MEMORY),(LPVOID)Mem,(Size+sizeof(SIZE_T))) -#define MEMFREE(Mem) if (Mem) {HeapFree(ssSMSSettings.hHeap,0,(LPVOID)Mem);Mem=NULL;} - -#define SEND_DLG_ITEM_MESSAGEW(hDlg,nIDDlgItem,Msg,wParam,lParam) SendMessageW(GetDlgItem(hDlg,nIDDlgItem),Msg,wParam,lParam) -#define SEND_DLG_ITEM_MESSAGEA(hDlg,nIDDlgItem,Msg,wParam,lParam) SendMessageA(GetDlgItem(hDlg,nIDDlgItem),Msg,wParam,lParam) -#define SEND_DLG_ITEM_MESSAGE(hDlg,nIDDlgItem,Msg,wParam,lParam) SendMessage(GetDlgItem(hDlg,nIDDlgItem),Msg,wParam,lParam) - -#define IS_DLG_BUTTON_CHECKED(hDlg,nIDDlgItem) SEND_DLG_ITEM_MESSAGE(hDlg,nIDDlgItem,BM_GETCHECK,NULL,NULL) -#define CHECK_DLG_BUTTON(hDlg,nIDDlgItem,uCheck) SEND_DLG_ITEM_MESSAGE(hDlg,nIDDlgItem,BM_SETCHECK,(WPARAM)uCheck,NULL) - -#define SET_DLG_ITEM_TEXTW(hDlg,nIDDlgItem,lpString) SEND_DLG_ITEM_MESSAGEW(hDlg,nIDDlgItem,WM_SETTEXT,0,(LPARAM)lpString) -#define SET_DLG_ITEM_TEXTA(hDlg,nIDDlgItem,lpString) SEND_DLG_ITEM_MESSAGEA(hDlg,nIDDlgItem,WM_SETTEXT,0,(LPARAM)lpString) -#define SET_DLG_ITEM_TEXT(hDlg,nIDDlgItem,lpString) SEND_DLG_ITEM_MESSAGE(hDlg,nIDDlgItem,WM_SETTEXT,0,(LPARAM)lpString) - -#define GET_DLG_ITEM_TEXTW(hDlg,nIDDlgItem,lpString,nMaxCount) SEND_DLG_ITEM_MESSAGEW(hDlg,nIDDlgItem,WM_GETTEXT,(WPARAM)nMaxCount,(LPARAM)lpString) -#define GET_DLG_ITEM_TEXTA(hDlg,nIDDlgItem,lpString,nMaxCount) SEND_DLG_ITEM_MESSAGEA(hDlg,nIDDlgItem,WM_GETTEXT,(WPARAM)nMaxCount,(LPARAM)lpString) -#define GET_DLG_ITEM_TEXT(hDlg,nIDDlgItem,lpString,nMaxCount) SEND_DLG_ITEM_MESSAGE(hDlg,nIDDlgItem,WM_GETTEXT,(WPARAM)nMaxCount,(LPARAM)lpString) - -#define GET_DLG_ITEM_TEXT_LENGTH(hDlg,nIDDlgItem) SEND_DLG_ITEM_MESSAGE(hDlg,nIDDlgItem,WM_GETTEXTLENGTH,NULL,NULL) -#define GET_WINDOW_TEXT_LENGTH(hDlg) SendMessage(hDlg,WM_GETTEXTLENGTH,NULL,NULL) - -#define GET_CURRENT_COMBO_DATA(hWndDlg,ControlID) SEND_DLG_ITEM_MESSAGE(hWndDlg,ControlID,CB_GETITEMDATA,SEND_DLG_ITEM_MESSAGE(hWndDlg,ControlID,CB_GETCURSEL,0,0),0) - - - - -#define GetContactNameA(Contact) (LPSTR)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)Contact,0) -#define GetContactNameW(Contact) (LPWSTR)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)Contact,GCDNF_UNICODE) - -#define DB_SMS_DeleteValue(Contact,valueName) DBDeleteContactSetting(Contact,PROTOCOL_NAMEA,valueName) -#define DB_SMS_GetDword(Contact,valueName,parDefltValue) DBGetContactSettingDword(Contact,PROTOCOL_NAMEA,valueName,parDefltValue) -#define DB_SMS_SetDword(Contact,valueName,parValue) DBWriteContactSettingDword(Contact,PROTOCOL_NAMEA,valueName,parValue) -#define DB_SMS_GetWord(Contact,valueName,parDefltValue) DBGetContactSettingWord(Contact,PROTOCOL_NAMEA,valueName,parDefltValue) -#define DB_SMS_SetWord(Contact,valueName,parValue) DBWriteContactSettingWord(Contact,PROTOCOL_NAMEA,valueName,parValue) -#define DB_SMS_GetByte(Contact,valueName,parDefltValue) DBGetContactSettingByte(Contact,PROTOCOL_NAMEA,valueName,parDefltValue) -#define DB_SMS_SetByte(Contact,valueName,parValue) DBWriteContactSettingByte(Contact,PROTOCOL_NAMEA,valueName,parValue) -BOOL DB_GetStaticStringW(HANDLE hContact,LPSTR lpszModule,LPSTR lpszValueName,LPWSTR lpszRetBuff,SIZE_T dwRetBuffSize,SIZE_T *pdwRetBuffSize); -#define DB_SMS_GetStaticStringW(Contact,ValueName,Ret,RetBuffSize,pRetBuffSize) DB_GetStaticStringW(Contact,PROTOCOL_NAMEA,ValueName,Ret,RetBuffSize,pRetBuffSize) -BOOL DB_SetStringExW(HANDLE hContact,LPSTR lpszModule,LPSTR lpszValueName,LPWSTR lpwszValue,SIZE_T dwValueSize); -#define DB_SetStringW(Contact,Module,valueName,parValue) DBWriteContactSettingWString(Contact,Module,valueName,parValue) -#define DB_SMS_SetStringW(Contact,valueName,parValue) DBWriteContactSettingWString(Contact,PROTOCOL_NAMEA,valueName,parValue) -#define DB_SMS_SetStringExW(Contact,valueName,parValue,parValueSize) DB_SetStringExW(Contact,PROTOCOL_NAMEA,valueName,parValue,parValueSize) - - -LPSTR GetModuleName (HANDLE hContact); -void EnableControlsArray (HWND hWndDlg,WORD *pwControlsList,SIZE_T dwControlsListCount,BOOL bEnabled); -void CListShowMenuItem (HANDLE hMenuItem,BOOL bShow); -//Decleration of function that returns received string with only numbers -SIZE_T CopyNumberA (LPSTR lpszOutBuff,LPSTR lpszBuff,SIZE_T dwLen); -SIZE_T CopyNumberW (LPWSTR lpcOutBuff,LPWSTR lpcBuff,SIZE_T dwLen); -BOOL IsPhoneW (LPWSTR lpwszString,SIZE_T dwStringLen); -DWORD GetContactPhonesCount (HANDLE hContact); -BOOL IsContactPhone (HANDLE hContact,LPWSTR lpwszPhone,SIZE_T dwPhoneSize); -//Decleration of function that returns HANDLE of contact by his cellular number -HANDLE HContactFromPhone (LPWSTR lpwszPhone,SIZE_T dwPhoneSize); -BOOL GetDataFromMessage (LPSTR lpszMessage,SIZE_T dwMessageSize,DWORD *pdwEventType,LPWSTR lpwszPhone,SIZE_T dwPhoneSize,SIZE_T *pdwPhoneSizeRet,UINT *piIcon); -//Decleration of function that gets a XML string and return the asked tag. -BOOL GetXMLFieldEx (LPSTR lpszXML,SIZE_T dwXMLSize,LPSTR *plpszData,SIZE_T *pdwDataSize,const char *tag1,...); -BOOL GetXMLFieldExBuff (LPSTR lpszXML,SIZE_T dwXMLSize,LPSTR lpszBuff,SIZE_T dwBuffSize,SIZE_T *pdwBuffSizeRet,const char *tag1,...); -//BOOL GetXMLFieldExW (LPWSTR lpwszXML,SIZE_T dwXMLSize,LPWSTR *plpwszData,SIZE_T *pdwDataSize,const WCHAR *tag1,...); -//BOOL GetXMLFieldExBuffW (LPWSTR lpwszXML,SIZE_T dwXMLSize,LPWSTR lpwszBuff,SIZE_T dwBuffSize,SIZE_T *pdwBuffSizeRet,const WCHAR *tag1,...); -DWORD DecodeXML (LPTSTR lptszMessage,SIZE_T dwMessageSize,LPTSTR lptszMessageConverted,SIZE_T dwMessageConvertedBuffSize,SIZE_T *pdwMessageConvertedSize); -DWORD EncodeXML (LPTSTR lptszMessage,SIZE_T dwMessageSize,LPTSTR lptszMessageConverted,SIZE_T dwMessageConvertedBuffSize,SIZE_T *pdwMessageConvertedSize); -void LoadMsgDlgFont (int i,LOGFONT *lf,COLORREF *colour); -LRESULT CALLBACK MessageSubclassProc (HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam); -int RefreshAccountList (WPARAM eventCode,LPARAM lParam); -void FreeAccountList (); -//BOOL IsModuleInAccountList (LPSTR lpszModule); - - - - -int OptInitialise (WPARAM wParam,LPARAM lParam); - -int LoadServices (); -int LoadModules (); -void UnloadModules (); -void UnloadServices (); - -int handleAckSMS(WPARAM wParam,LPARAM lParam); -int handleNewMessage(WPARAM wParam,LPARAM lParam); -void RestoreUnreadMessageAlerts(); - -//Decleration of Menu SMS send click function -int SmsRebuildContactMenu(WPARAM wParam,LPARAM lParam); - - -void StartSmsSend(HWND hWndDlg,SIZE_T dwModuleIndex,LPWSTR lpwszPhone,SIZE_T dwPhoneSize,LPWSTR lpwszMessage,SIZE_T dwMessageSize); - - - - - - - - - - - -#endif \ No newline at end of file diff --git a/!NotAdopted/SMS/options.cpp b/!NotAdopted/SMS/options.cpp deleted file mode 100644 index dd52602484..0000000000 --- a/!NotAdopted/SMS/options.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* -Miranda-IM SMS Plugin -Copyright (C) 2001-2002 Richard Hughes -Copyright (C) 2007-2009 Rozhuk Ivan - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ---------------------------------------------------------------------------- - -This was the original words. -This plugin was modified by Ariel Shulman (NuKe007). -For any comments, problems, etc. contact me at Miranda-IM forums or E-Mail or ICQ. -All the information needed you can find at www.nuke007.tk -Enjoy the code and use it smartly! -*/ -#include "main.h" - - - -WORD wSMSSignControlsList[]={ - IDC_BEGIN, - IDC_END, - IDC_SIGNATURE, - IDC_SIGNGROUP -}; - - -BOOL CALLBACK DlgProcEditorOptions(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg){ - case WM_INITDIALOG: - TranslateDialogDefault(hWndDlg); - { - WCHAR wszSign[1024]; - BOOL bSignBebefore,bUseSign; - - if (DB_SMS_GetStaticStringW(NULL,"Signature",wszSign,SIZEOF(wszSign),NULL)==FALSE) - { - mir_sntprintf(wszSign,SIZEOF(wszSign),TranslateW(L"From %s:\r\n\r\n"),GetContactNameW(NULL)); - } - SET_DLG_ITEM_TEXTW(hWndDlg,IDC_SIGNATURE,wszSign); - - bUseSign=DB_SMS_GetByte(NULL,"UseSignature",SMS_DEFAULT_USESIGNATURE); - CHECK_DLG_BUTTON(hWndDlg,IDC_USESIGNATURE,bUseSign); - EnableControlsArray(hWndDlg,(WORD*)&wSMSSignControlsList,SIZEOF(wSMSSignControlsList),bUseSign); - - bSignBebefore=DB_SMS_GetByte(NULL,"SignaturePos",SMS_DEFAULT_SIGNATUREPOS); - CHECK_DLG_BUTTON(hWndDlg,IDC_BEGIN,bSignBebefore); - CHECK_DLG_BUTTON(hWndDlg,IDC_END,(!bSignBebefore)); - - CHECK_DLG_BUTTON(hWndDlg,IDC_SHOWACK,DB_SMS_GetByte(NULL,"ShowACK",SMS_DEFAULT_SHOWACK)); - CHECK_DLG_BUTTON(hWndDlg,IDC_AUTOPOP,DB_SMS_GetByte(NULL,"AutoPopup",SMS_DEFAULT_AUTOPOP)); - CHECK_DLG_BUTTON(hWndDlg,IDC_SAVEWINPOS,DB_SMS_GetByte(NULL,"SavePerContact",SMS_DEFAULT_SAVEWINPOS)); - } - return(TRUE); - case WM_COMMAND: - SendMessage(GetParent(hWndDlg),PSM_CHANGED,0,0); - switch(LOWORD(wParam)){ - case IDC_USESIGNATURE: - EnableControlsArray(hWndDlg,(WORD*)&wSMSSignControlsList,SIZEOF(wSMSSignControlsList),IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_USESIGNATURE)); - break; - } - break; - case WM_NOTIFY: - switch(((LPNMHDR)lParam)->idFrom){ - case 0: - switch (((LPNMHDR)lParam)->code){ - case PSN_APPLY: - { - WCHAR wszSign[1024]; - - GET_DLG_ITEM_TEXTW(hWndDlg,IDC_SIGNATURE,wszSign,SIZEOF(wszSign)); - DB_SMS_SetStringW(NULL,"Signature",wszSign); - - DB_SMS_SetByte(NULL,"UseSignature",IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_USESIGNATURE)); - DB_SMS_SetByte(NULL,"SignaturePos",IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_BEGIN)); - DB_SMS_SetByte(NULL,"ShowACK",IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_SHOWACK)); - DB_SMS_SetByte(NULL,"AutoPopup",IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_AUTOPOP)); - DB_SMS_SetByte(NULL,"SavePerContact",IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_SAVEWINPOS)); - } - return(TRUE); - } - break; - } - break; - } -return(FALSE); -} - -int OptInitialise(WPARAM wParam,LPARAM lParam) -{ - OPTIONSDIALOGPAGE odp={0}; - - odp.cbSize=sizeof(odp); - odp.position=910000000; - odp.hInstance=ssSMSSettings.hInstance; - odp.ptszGroup=TranslateW(L"Events"); - odp.flags=(ODPF_BOLDGROUPS|ODPF_UNICODE); - odp.pszTemplate=MAKEINTRESOURCEA(IDD_OPT_SMSPLUGIN); - odp.ptszTitle=PROTOCOL_DISPLAY_NAME_ORIGW; - odp.pfnDlgProc=DlgProcEditorOptions; - CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp); -return(0); -} - diff --git a/!NotAdopted/SMS/readme.txt b/!NotAdopted/SMS/readme.txt deleted file mode 100644 index 3fe787fec8..0000000000 --- a/!NotAdopted/SMS/readme.txt +++ /dev/null @@ -1,49 +0,0 @@ -SMS плагин для Miranda IM - - -2001-2002 Richard Hughes -2003 Ariel Shulman -2007-2009 Rozhuk Ivan (Ivan 83) - - - Плагин предназначен для отправки SMS сообщений через миранду -с использованием ICQ, MRA и других протоколов поддерживающих отправку SMS. - - Эта версия плагина была переписана почти полностью, сохранены без изменений -только диалоги и часть коментариев. - - -Home page: http://www.rozhuk.org.ru/forum/index.php?topic=3.0 - - - - -Change Log: - -Version 0.2.5.3 // 02.11.2009 - - Поддержка Updater плагина - -Version 0.2.5.2 // 01.11.2009 - - Unicode версия - - Поддержка мультиакаунтов - - Добавлены настройки - - Внутренние изменения - - Частично используются иконки из миранды (Main Icons) - - Исправлены недочёты при обработке XML - - Улучшен алгоритм подсчёта "оставшихся" символов - -Version 0.2.5.1 // 26.10.2009 - - В диалоге отправки автоматически выбирается первый номер телефона из списка - - Настройки шрифтов и цветов фона берутся от TabSRMM - - Уменьшен размер плагина - - Устранены утечки ресурсов - - Устранено появление ложных пустых сообщений от джабер протокола - -Version 0.2.5.0 // 17.03.2008 - - Добавлена совместимость с новым ядром (GUID идентификатор) - -Version 0.2.4.9 - - Полностью переписан код: оптимизирован, устранены утечки памяти - - Добавленна возможность выбора потокола для отправки сообщений - - Автоподстановка номера при ответе - - Мелкие исправлени \ No newline at end of file diff --git a/!NotAdopted/SMS/receive.cpp b/!NotAdopted/SMS/receive.cpp deleted file mode 100644 index 24a1df5be5..0000000000 --- a/!NotAdopted/SMS/receive.cpp +++ /dev/null @@ -1,310 +0,0 @@ -/* -Miranda-IM SMS Plugin -Copyright (C) 2001-2 Richard Hughes -Copyright (C) 2007-2009 Rozhuk Ivan - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ---------------------------------------------------------------------------- - -This was the original words. -This plugin was modified by Ariel Shulman (NuKe007). -For any comments, problems, etc. contact me at Miranda-IM forums or E-Mail or ICQ. -All the information needed you can find at www.nuke007.tk -Enjoy the code and use it smartly! -*/ - -#include "main.h" - - - -//This function handles the ACK received from that hooked. -int handleAckSMS(WPARAM wParam,LPARAM lParam) -{ - if (lParam) - if (((ACKDATA*)lParam)->type==ICQACKTYPE_SMS) - { - char szPhone[MAX_PHONE_LEN]={0}; - WCHAR wszPhone[MAX_PHONE_LEN]={0}; - LPSTR lpszXML=(LPSTR)((ACKDATA*)lParam)->lParam,lpszData,lpszPhone; - SIZE_T dwXMLSize=lstrlenA(lpszXML),dwDataSize,dwPhoneSize; - ACKDATA *ack=((ACKDATA*)lParam); - - if (GetXMLFieldEx(lpszXML,dwXMLSize,&lpszData,&dwDataSize,"sms_message","text",NULL)) - { - if (GetXMLFieldEx(lpszXML,dwXMLSize,&lpszPhone,&dwPhoneSize,"sms_message","sender",NULL)) - { - LPSTR lpszMessageUTF; - LPWSTR lpwszMessageXMLEncoded,lpwszMessageXMLDecoded; - SIZE_T dwBuffLen,dwMessageXMLEncodedSize,dwMessageXMLDecodedSize; - HANDLE hContact; - DBEVENTINFO dbei={0}; - - dwBuffLen=(dwDataSize+MAX_PATH); - dbei.pBlob=(LPBYTE)MEMALLOC((dwBuffLen+dwPhoneSize)); - lpwszMessageXMLEncoded=(LPWSTR)MEMALLOC((dwBuffLen*sizeof(WCHAR))); - lpwszMessageXMLDecoded=(LPWSTR)MEMALLOC((dwBuffLen*sizeof(WCHAR))); - if (dbei.pBlob && lpwszMessageXMLEncoded && lpwszMessageXMLDecoded) - { - dwMessageXMLEncodedSize=MultiByteToWideChar(CP_UTF8,0,lpszData,dwDataSize,lpwszMessageXMLEncoded,dwBuffLen); - DecodeXML(lpwszMessageXMLEncoded,dwMessageXMLEncodedSize,lpwszMessageXMLDecoded,dwBuffLen,&dwMessageXMLDecodedSize); - lpszMessageUTF=(LPSTR)lpwszMessageXMLEncoded; - WideCharToMultiByte(CP_UTF8,0,lpwszMessageXMLDecoded,dwMessageXMLDecodedSize,lpszMessageUTF,dwBuffLen,NULL,NULL); - - dwPhoneSize=CopyNumberA(szPhone,lpszPhone,dwPhoneSize); - dwPhoneSize=MultiByteToWideChar(CP_UTF8,0,szPhone,dwPhoneSize,wszPhone,MAX_PHONE_LEN); - hContact=HContactFromPhone(wszPhone,dwPhoneSize); - - dbei.cbSize=sizeof(dbei); - dbei.szModule=GetModuleName(hContact); - dbei.timestamp=time(NULL); - dbei.flags=(DBEF_UTF); - dbei.eventType=ICQEVENTTYPE_SMS; - dbei.cbBlob=(mir_snprintf((LPSTR)dbei.pBlob,((dwBuffLen+dwPhoneSize)),"SMS From: +%s\r\n%s",szPhone,lpszMessageUTF)+sizeof(DWORD)); - //dbei.pBlob=(LPBYTE)lpszBuff; - (*((DWORD*)(dbei.pBlob+(dbei.cbBlob-sizeof(DWORD)))))=0; - CallService(MS_DB_EVENT_ADD,(WPARAM)hContact,(LPARAM)&dbei); - if (hContact==NULL) - { - if (RecvSMSWindowAdd(NULL,ICQEVENTTYPE_SMS,wszPhone,dwPhoneSize,(LPSTR)dbei.pBlob,dbei.cbBlob)) - { - CallService(MS_DB_EVENT_MARKREAD,(WPARAM)hContact,(LPARAM)&dbei); - SkinPlaySound("RecvSMSMsg"); - } - } - } - MEMFREE(lpwszMessageXMLDecoded); - MEMFREE(lpwszMessageXMLEncoded); - MEMFREE(dbei.pBlob); - } - }else - if (GetXMLFieldEx(lpszXML,dwXMLSize,&lpszData,&dwDataSize,"sms_delivery_receipt","delivered",NULL)) - { - if (GetXMLFieldEx(lpszXML,dwXMLSize,&lpszPhone,&dwPhoneSize,"sms_delivery_receipt","destination",NULL)) - { - HANDLE hContact; - DBEVENTINFO dbei={0}; - - dwPhoneSize=CopyNumberA(szPhone,lpszPhone,dwPhoneSize); - dwPhoneSize=MultiByteToWideChar(CP_UTF8,0,szPhone,dwPhoneSize,wszPhone,MAX_PHONE_LEN); - hContact=HContactFromPhone(wszPhone,dwPhoneSize); - - dbei.cbSize=sizeof(dbei); - dbei.szModule=GetModuleName(hContact); - dbei.timestamp=time(NULL); - dbei.eventType=ICQEVENTTYPE_SMSCONFIRMATION; - if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszData,dwDataSize,"yes",3)==CSTR_EQUAL) - { - dbei.cbBlob=(MAX_PHONE_LEN+MAX_PATH); - dbei.pBlob=(PBYTE)MEMALLOC(dbei.cbBlob); - if (dbei.pBlob) dbei.cbBlob=(mir_snprintf((LPSTR)dbei.pBlob,dbei.cbBlob,"SMS Confirmation From: +%s\r\nSMS was sent succesfully",szPhone)+4); - }else{ - if (GetXMLFieldEx(lpszXML,dwXMLSize,&lpszData,&dwDataSize,"sms_delivery_receipt","error","params","param",NULL)==FALSE) - { - lpszData=""; - dwDataSize=0; - } - dbei.cbBlob=(MAX_PHONE_LEN+MAX_PATH+dwDataSize); - dbei.pBlob=(PBYTE)MEMALLOC(dbei.cbBlob); - if (dbei.pBlob) - { - dbei.cbBlob=mir_snprintf((LPSTR)dbei.pBlob,dbei.cbBlob,"SMS Confirmation From: +%s\r\nSMS was not sent succesfully: ",szPhone); - CopyMemory((dbei.pBlob+dbei.cbBlob),lpszData,dwDataSize); - dbei.cbBlob+=(dwDataSize+sizeof(DWORD)); - (*((DWORD*)(dbei.pBlob+(dbei.cbBlob-sizeof(DWORD)))))=0; - } - } - - if (dbei.pBlob) - { - if (hContact) - { - CallService(MS_DB_EVENT_ADD,(WPARAM)hContact,(LPARAM)&dbei); - }else{ - RecvSMSWindowAdd(NULL,ICQEVENTTYPE_SMSCONFIRMATION,wszPhone,dwPhoneSize,(LPSTR)dbei.pBlob,dbei.cbBlob); - } - MEMFREE(dbei.pBlob); - } - } - }else - if ((ack->result==ACKRESULT_FAILED) || GetXMLFieldEx(lpszXML,dwXMLSize,&lpszData,&dwDataSize,"sms_response","deliverable",NULL)) - { - HWND hWndDlg=SendSMSWindowHwndByHProcessGet(ack->hProcess); - if (hWndDlg) - { - char szNetwork[MAX_PATH]; - - KillTimer(hWndDlg,wParam); - GetXMLFieldExBuff(lpszXML,dwXMLSize,szNetwork,sizeof(szNetwork),NULL,"sms_response","network",NULL); - - if (ack->result==ACKRESULT_FAILED || CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszData,dwDataSize,"no",2)==CSTR_EQUAL) - { - HWND hwndTimeOut; - char szBuff[1024]; - WCHAR wszErrorMessage[1028]; - LPSTR lpszErrorDescription; - - if (SendSMSWindowMultipleGet(hWndDlg)) - { - TVITEM tvi; - tvi.mask=TVIF_TEXT; - tvi.hItem=SendSMSWindowHItemSendGet(hWndDlg); - tvi.pszText=wszPhone; - tvi.cchTextMax=SIZEOF(wszPhone); - TreeView_GetItem(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),&tvi); - }else{ - GET_DLG_ITEM_TEXTW(hWndDlg,IDC_ADDRESS,wszPhone,SIZEOF(szPhone)); - } - - if (ack->result==ACKRESULT_FAILED) - { - lpszErrorDescription=lpszXML; - }else{ - lpszErrorDescription=szBuff; - GetXMLFieldExBuff(lpszXML,dwXMLSize,szBuff,sizeof(szBuff),NULL,"sms_response","error","params","param",NULL); - } - - mir_sntprintf(wszErrorMessage,SIZEOF(wszErrorMessage),TranslateW(L"SMS message didn't send by %S to %s because: %S"),szNetwork,wszPhone,lpszErrorDescription); - ShowWindow(hWndDlg,SW_SHOWNORMAL); - EnableWindow(hWndDlg,FALSE); - hwndTimeOut=CreateDialog(ssSMSSettings.hInstance,MAKEINTRESOURCE(IDD_SENDSMSTIMEDOUT),hWndDlg,SMSTimedOutDlgProc); - SET_DLG_ITEM_TEXTW(hwndTimeOut,IDC_STATUS,wszErrorMessage); - }else{ - SendSMSWindowDBAdd(hWndDlg); - if (SendSMSWindowMultipleGet(hWndDlg)) - { - if (SendSMSWindowNextHItemGet(hWndDlg,SendSMSWindowHItemSendGet(hWndDlg))) - { - SendSMSWindowAsSentSet(hWndDlg); - SendSMSWindowHItemSendSet(hWndDlg,SendSMSWindowNextHItemGet(hWndDlg,SendSMSWindowHItemSendGet(hWndDlg))); - SendSMSWindowNext(hWndDlg); - }else{ - SendSMSWindowRemove(hWndDlg); - } - }else{ - if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszData,dwDataSize,"yes",3)==CSTR_EQUAL || CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszData,dwDataSize,"smtp",4)==CSTR_EQUAL) - { - char szSource[MAX_PATH],szMessageID[MAX_PATH]; - - if (DB_SMS_GetByte(NULL,"ShowACK",SMS_DEFAULT_SHOWACK)) - { - HWND hwndAccepted=CreateDialog(ssSMSSettings.hInstance,MAKEINTRESOURCE(IDD_SENDSMSACCEPT),hWndDlg,SMSAcceptedDlgProc); - if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszData,dwDataSize,"yes",3)==CSTR_EQUAL) - { - GetXMLFieldExBuff(lpszXML,dwXMLSize,szSource,sizeof(szSource),NULL,"sms_response","source",NULL); - GetXMLFieldExBuff(lpszXML,dwXMLSize,szMessageID,sizeof(szMessageID),NULL,"sms_response","message_id",NULL); - }else{ - SET_DLG_ITEM_TEXTW(hwndAccepted,IDC_ST_SOURCE,TranslateW(L"From:")); - SET_DLG_ITEM_TEXTW(hwndAccepted,IDC_ST_MESSAGEID,TranslateW(L"To:")); - GetXMLFieldExBuff(lpszXML,dwXMLSize,szSource,sizeof(szSource),NULL,"sms_response","from",NULL); - GetXMLFieldExBuff(lpszXML,dwXMLSize,szMessageID,sizeof(szMessageID),NULL,"sms_response","to",NULL); - } - SET_DLG_ITEM_TEXTA(hwndAccepted,IDC_NETWORK,szNetwork); - SET_DLG_ITEM_TEXTA(hwndAccepted,IDC_SOURCE,szSource); - SET_DLG_ITEM_TEXTA(hwndAccepted,IDC_MESSAGEID,szMessageID); - }else{ - SendSMSWindowRemove(hWndDlg); - } - }else{ - SendSMSWindowRemove(hWndDlg); - } - } - } - } - } - } -return(0); -} - -//Handles new SMS messages added to the database -int handleNewMessage(WPARAM wParam,LPARAM lParam) -{ - CHAR szServiceFunction[MAX_PATH],*pszServiceFunctionName; - WCHAR szToolTip[MAX_PATH]; - HANDLE hContact=(HANDLE)wParam,hDbEvent=(HANDLE)lParam; - CLISTEVENT cle={0}; - DBEVENTINFO dbei={0}; - - dbei.cbSize=sizeof(dbei); - if ((dbei.cbBlob=CallService(MS_DB_EVENT_GETBLOBSIZE,lParam,0))!=-1) - { - dbei.pBlob=(PBYTE)MEMALLOC(dbei.cbBlob); - if (dbei.pBlob) - { - CopyMemory(szServiceFunction,PROTOCOL_NAMEA,PROTOCOL_NAME_SIZE); - pszServiceFunctionName=szServiceFunction+PROTOCOL_NAME_LEN; - - if (CallService(MS_DB_EVENT_GET,lParam,(LPARAM)&dbei)==0) - if ((dbei.flags&DBEF_SENT)==0) - if (dbei.eventType==ICQEVENTTYPE_SMS) - { - if (dbei.cbBlob>MIN_SMS_DBEVENT_LEN) - { - SkinPlaySound("RecvSMSMsg"); - if (DB_SMS_GetByte(NULL,"AutoPopup",0)) - { - if (RecvSMSWindowAdd(hContact,ICQEVENTTYPE_SMS,NULL,0,(LPSTR)dbei.pBlob,dbei.cbBlob)) - { - CallService(MS_DB_EVENT_MARKREAD,(WPARAM)hContact,(LPARAM)&dbei); - } - }else{ - CopyMemory(pszServiceFunctionName,SMS_READ,sizeof(SMS_READ)); - - cle.cbSize=sizeof(cle); - cle.flags=CLEF_UNICODE; - cle.hContact=hContact; - cle.hDbEvent=hDbEvent; - cle.hIcon=LoadSkinnedIcon(SKINICON_OTHER_SMS); - cle.pszService=szServiceFunction; - mir_sntprintf(szToolTip,SIZEOF(szToolTip),TranslateW(L"SMS Message from %s"),GetContactNameW(hContact)); - cle.ptszTooltip=szToolTip; - CallService(MS_CLIST_ADDEVENT,0,(LPARAM)&cle); - } - } - }else - if (dbei.eventType==ICQEVENTTYPE_SMSCONFIRMATION) - { - SkinPlaySound("RecvSMSConfirmation"); - if (DB_SMS_GetByte(NULL,"AutoPopup",0)) - { - if (RecvSMSWindowAdd(hContact,ICQEVENTTYPE_SMSCONFIRMATION,NULL,0,(LPSTR)dbei.pBlob,dbei.cbBlob)) - { - CallService(MS_DB_EVENT_DELETE,(WPARAM)hContact,(LPARAM)&dbei); - } - }else{ - UINT iIcon; - - if (GetDataFromMessage((LPSTR)dbei.pBlob,dbei.cbBlob,NULL,NULL,0,NULL,&iIcon)) - { - CopyMemory(pszServiceFunctionName,SMS_READ_ACK,sizeof(SMS_READ_ACK)); - - cle.cbSize=sizeof(cle); - cle.flags=(CLEF_UNICODE); - cle.hContact=hContact; - cle.hDbEvent=hDbEvent; - cle.hIcon=(HICON)LoadImage(ssSMSSettings.hInstance,MAKEINTRESOURCE(iIcon),IMAGE_ICON,0,0,LR_SHARED); - cle.pszService=szServiceFunction; - mir_sntprintf(szToolTip,SIZEOF(szToolTip),TranslateW(L"SMS Confirmation from %s"),GetContactNameW(hContact)); - cle.ptszTooltip=szToolTip; - CallService(MS_CLIST_ADDEVENT,0,(LPARAM)&cle); - } - } - } - MEMFREE(dbei.pBlob); - } - } -return(0); -} - - diff --git a/!NotAdopted/SMS/recvdlg.cpp b/!NotAdopted/SMS/recvdlg.cpp deleted file mode 100644 index ec3998edfc..0000000000 --- a/!NotAdopted/SMS/recvdlg.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/* -Miranda-IM SMS Plugin -Copyright (C) 2001-2 Richard Hughes -Copyright (C) 2007-2009 Rozhuk Ivan - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ---------------------------------------------------------------------------- - -This was the original words. -This plugin was modified by Ariel Shulman (NuKe007). -For any comments, problems, etc. contact me at Miranda-IM forums or E-Mail or ICQ. -All the information needed you can find at www.nuke007.tk -Enjoy the code and use it smartly! -*/ - -#include "main.h" -#include "recvdlg.h" - -//Defnition needed to the SMS window list -typedef struct -{ - LIST_MT_ITEM lmtListMTItem; - HWND hWnd; - HBRUSH hBkgBrush; - HANDLE hContact; -} RECV_SMS_WINDOW_DATA; - - - -BOOL CALLBACK RecvSmsDlgProc (HWND hWndDlg,UINT message,WPARAM wParam,LPARAM lParam); -#define GET_WINDOW_DATA(hWndDlg) ((RECV_SMS_WINDOW_DATA*)GetWindowLongPtr(hWndDlg,GWL_USERDATA)) - - - - - -DWORD RecvSMSWindowInitialize() -{ - DWORD dwRetErrorCode; - - dwRetErrorCode=ListMTInitialize(&ssSMSSettings.lmtRecvSMSWindowsListMT,0); -return(dwRetErrorCode); -} - -//This function destroy all SMS receive windows -void RecvSMSWindowDestroy() -{ - RECV_SMS_WINDOW_DATA *prswdWindowData; - - ListMTLock(&ssSMSSettings.lmtRecvSMSWindowsListMT); - while(ListMTItemGetFirst(&ssSMSSettings.lmtRecvSMSWindowsListMT,NULL,(LPVOID*)&prswdWindowData)==NO_ERROR) - {// цикл - RecvSMSWindowRemove(prswdWindowData->hWnd); - } - ListMTUnLock(&ssSMSSettings.lmtRecvSMSWindowsListMT); - ListMTDestroy(&ssSMSSettings.lmtRecvSMSWindowsListMT); -} - - -BOOL CALLBACK RecvSmsDlgProc(HWND hWndDlg,UINT message,WPARAM wParam,LPARAM lParam) -{ - RECV_SMS_WINDOW_DATA *prswdWindowData=GET_WINDOW_DATA(hWndDlg); - - switch(message){ - case WM_INITDIALOG: - TranslateDialogDefault(hWndDlg); //Translate intially - bid - - prswdWindowData=(RECV_SMS_WINDOW_DATA*)lParam; - SetWindowLongPtr(hWndDlg,GWL_USERDATA,(LONG_PTR)lParam); - - { - WNDPROC OldEditWndProc; - - OldEditWndProc=(WNDPROC)SetWindowLongPtr(GetDlgItem(hWndDlg,IDC_MESSAGE),GWL_WNDPROC,(LONG_PTR)MessageSubclassProc); - SetWindowLongPtr(GetDlgItem(hWndDlg,IDC_MESSAGE),GWL_USERDATA,(LONG_PTR)OldEditWndProc); - } - - { - HFONT hFont; - LOGFONT lf; - hFont=(HFONT)SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,WM_GETFONT,0,0); - if (hFont && hFont!=(HFONT)SEND_DLG_ITEM_MESSAGE(hWndDlg,IDOK,WM_GETFONT,0,0)) DeleteObject(hFont); - LoadMsgDlgFont(MSGFONTID_YOURMSG,&lf,NULL); - hFont=CreateFontIndirect(&lf); - SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,WM_SETFONT,(WPARAM)hFont,MAKELPARAM(TRUE,0)); - - COLORREF colour=DBGetContactSettingDword(NULL,SRMMMOD,SRMSGSET_BKGCOLOUR,SRMSGDEFSET_BKGCOLOUR); - prswdWindowData->hBkgBrush=CreateSolidBrush(colour); - } - - if (Utils_RestoreWindowPosition(hWndDlg,(DB_SMS_GetByte(NULL,"SavePerContact",0)? prswdWindowData->hContact:NULL),PROTOCOL_NAMEA,"recv")) - {// def pos - SetWindowPos(hWndDlg,0,200,200,400,350,SWP_NOZORDER); - } - InvalidateRect(GetDlgItem(hWndDlg,IDC_MESSAGE),NULL,FALSE); - break; - case WM_CTLCOLORSTATIC: - if ((HWND)lParam==GetDlgItem(hWndDlg,IDC_MESSAGE)) - { - COLORREF colour; - - LoadMsgDlgFont(MSGFONTID_YOURMSG,NULL,&colour); - SetTextColor((HDC)wParam,colour); - SetBkColor((HDC)wParam,DBGetContactSettingDword(NULL,SRMMMOD,SRMSGSET_BKGCOLOUR,SRMSGDEFSET_BKGCOLOUR)); - return((BOOL)prswdWindowData->hBkgBrush); - } - break; - case WM_GETMINMAXINFO: - ((LPMINMAXINFO)lParam)->ptMinTrackSize.x=300; - ((LPMINMAXINFO)lParam)->ptMinTrackSize.y=230; - break; - case WM_SIZE: - { - int cx,cy; - RECT rcWin; - - GetWindowRect(hWndDlg,&rcWin); - cx = rcWin.right - rcWin.left; - cy = rcWin.bottom - rcWin.top; - SetWindowPos(GetDlgItem(hWndDlg,IDC_MESSAGE),0,0,0,cx - 14,cy - 112,SWP_NOZORDER|SWP_NOMOVE); - SetWindowPos(GetDlgItem(hWndDlg,IDC_NAME),0,0,0,(cx*35)/100,20,SWP_NOZORDER|SWP_NOMOVE); - SetWindowPos(GetDlgItem(hWndDlg,IDC_NUMBER),0,cx - (cx*35)/100 - 11,5,(cx*35)/100,20,SWP_NOZORDER); - SetWindowPos(GetDlgItem(hWndDlg,IDC_ST_NUMBER),0,cx - (cx*35)/100 - 58,5,40,20,SWP_NOZORDER); - SetWindowPos(GetDlgItem(hWndDlg,IDC_READNEXT),0,cx - 87, cy - 60,80,25,SWP_NOZORDER); - SetWindowPos(GetDlgItem(hWndDlg,IDOK),0,cx/2 - 87,cy - 60,80,25,SWP_NOZORDER); - SetWindowPos(GetDlgItem(hWndDlg,IDCANCEL),0,cx/2 + 7,cy - 60,80,25,SWP_NOZORDER); - - RedrawWindow(hWndDlg,NULL,NULL,RDW_FRAME|RDW_INVALIDATE); - } - break; - case WM_COMMAND: - switch(LOWORD(wParam)){ - case IDOK: - { - WCHAR wszPhone[MAX_PHONE_LEN]; - HWND hwndSendSms; - HANDLE hContact; - - hContact=HContactFromPhone(wszPhone,GET_DLG_ITEM_TEXTW(hWndDlg,IDC_NUMBER,wszPhone,SIZEOF(wszPhone))); - hwndSendSms=SendSMSWindowIsOtherInstanceHContact(hContact); - if (hwndSendSms) - { - SetFocus(hwndSendSms); - }else{ - hwndSendSms=SendSMSWindowAdd(prswdWindowData->hContact); - SET_DLG_ITEM_TEXTW(hwndSendSms,IDC_ADDRESS,wszPhone); - } - } - case IDCANCEL: - RecvSMSWindowRemove(hWndDlg); - break; - } - break; - case WM_CLOSE: - DeleteObject(prswdWindowData->hBkgBrush); - RecvSMSWindowRemove(hWndDlg); - break; - } -return(FALSE); -} - -//SMS Receive window list functions - -//This function create a new SMS receive window, and insert it to the list. -//The function gets void and return the window HWND -HWND RecvSMSWindowAdd(HANDLE hContact,DWORD dwEventType,LPWSTR lpwszPhone,SIZE_T dwPhoneSize,LPSTR lpszMessage,SIZE_T dwMessageSize) -{ - HWND hRet=NULL; - - if ((dwPhoneSize+dwMessageSize)>MIN_SMS_DBEVENT_LEN) - { - LPWSTR lpwszMessage; - - lpwszMessage=(LPWSTR)MEMALLOC(((dwMessageSize+MAX_PATH)*sizeof(WCHAR))); - if (lpwszMessage) - { - RECV_SMS_WINDOW_DATA *prswdWindowData; - - prswdWindowData=(RECV_SMS_WINDOW_DATA*)MEMALLOC(sizeof(RECV_SMS_WINDOW_DATA)); - if (prswdWindowData) - { - prswdWindowData->hContact=hContact; - prswdWindowData->hWnd=CreateDialogParam(ssSMSSettings.hInstance,MAKEINTRESOURCE(IDD_RECVSMS),NULL,RecvSmsDlgProc,(LPARAM)prswdWindowData); - if (prswdWindowData->hWnd) - { - HICON hIcon; - WCHAR wszTitle[MAX_PATH]={0},wszPhoneLocal[MAX_PHONE_LEN]={0}; - UINT iIcon; - LPWSTR lpwszContactDisplayName,lpwszTitlepart; - - ListMTLock(&ssSMSSettings.lmtRecvSMSWindowsListMT); - ListMTItemAdd(&ssSMSSettings.lmtRecvSMSWindowsListMT,&prswdWindowData->lmtListMTItem,prswdWindowData); - ListMTUnLock(&ssSMSSettings.lmtRecvSMSWindowsListMT); - - switch(dwEventType){ - case ICQEVENTTYPE_SMS: - lpwszTitlepart=TranslateW(L"Received SMS"); - hIcon=LoadSkinnedIcon(SKINICON_OTHER_SMS); - break; - case ICQEVENTTYPE_SMSCONFIRMATION: - lpwszTitlepart=TranslateW(L"Received SMS Confirmation"); - GetDataFromMessage(lpszMessage,dwMessageSize,NULL,NULL,0,NULL,&iIcon); - hIcon=(HICON)LoadImage(ssSMSSettings.hInstance,MAKEINTRESOURCE(iIcon),IMAGE_ICON,0,0,LR_SHARED); - break; - default: - lpwszTitlepart=L"Unknown event type"; - } - - wszPhoneLocal[0]='+'; - if (dwPhoneSize) - { - dwPhoneSize=CopyNumberW((wszPhoneLocal+1),lpwszPhone,dwPhoneSize); - }else{ - GetDataFromMessage(lpszMessage,dwMessageSize,NULL,(wszPhoneLocal+1),(SIZEOF(wszPhoneLocal)-1),&dwPhoneSize,NULL); - dwPhoneSize++; - } - - lpwszContactDisplayName=GetContactNameW(hContact); - mir_sntprintf(wszTitle,SIZEOF(wszTitle),L"%s - %s",lpwszContactDisplayName,lpwszTitlepart); - MultiByteToWideChar(CP_UTF8,0,lpszMessage,dwMessageSize,lpwszMessage,(dwMessageSize+MAX_PATH)); - - SendMessageW(prswdWindowData->hWnd,WM_SETTEXT,NULL,(LPARAM)wszTitle); - SET_DLG_ITEM_TEXTW(prswdWindowData->hWnd,IDC_NAME,lpwszContactDisplayName); - SET_DLG_ITEM_TEXTW(prswdWindowData->hWnd,IDC_NUMBER,wszPhoneLocal); - SET_DLG_ITEM_TEXTW(prswdWindowData->hWnd,IDC_MESSAGE,lpwszMessage); - SendMessage(prswdWindowData->hWnd,WM_SETICON,ICON_BIG,(LPARAM)hIcon); - - SetFocus(GetDlgItem(prswdWindowData->hWnd,IDC_MESSAGE)); - hRet=prswdWindowData->hWnd; - }else{ - MEMFREE(prswdWindowData); - } - } - MEMFREE(lpwszMessage); - } - } -return(hRet); -} - -//This function close the SMS receive window that given, and remove it from the list. -//The function gets the HWND of the window that should be removed and return void -void RecvSMSWindowRemove(HWND hWndDlg) -{ - RECV_SMS_WINDOW_DATA *prswdWindowData=GET_WINDOW_DATA(hWndDlg); - - if (prswdWindowData) - { - Utils_SaveWindowPosition(hWndDlg,(DB_SMS_GetByte(NULL,"SavePerContact",0)? prswdWindowData->hContact:NULL),PROTOCOL_NAMEA,"recv"); - - ListMTLock(&ssSMSSettings.lmtRecvSMSWindowsListMT); - ListMTItemDelete(&ssSMSSettings.lmtRecvSMSWindowsListMT,&prswdWindowData->lmtListMTItem); - ListMTUnLock(&ssSMSSettings.lmtRecvSMSWindowsListMT); - MEMFREE(prswdWindowData); - } - DestroyWindow(hWndDlg); -} - diff --git a/!NotAdopted/SMS/recvdlg.h b/!NotAdopted/SMS/recvdlg.h deleted file mode 100644 index a34231b255..0000000000 --- a/!NotAdopted/SMS/recvdlg.h +++ /dev/null @@ -1,18 +0,0 @@ -#if !defined(AFX_SMS_RECVDLG_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_) -#define AFX_SMS_RECVDLG_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_ - - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - - - -DWORD RecvSMSWindowInitialize (); -void RecvSMSWindowDestroy (); -HWND RecvSMSWindowAdd (HANDLE hContact,DWORD dwEventType,LPWSTR lpwszPhone,SIZE_T dwPhoneSize,LPSTR lpszMessage,SIZE_T dwMessageSize); -void RecvSMSWindowRemove (HWND hWndDlg); - - - -#endif // !defined(AFX_SMS_RECVDLG_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_) diff --git a/!NotAdopted/SMS/res/SMSNOTSENT.ico b/!NotAdopted/SMS/res/SMSNOTSENT.ico deleted file mode 100644 index edc59a9d00..0000000000 Binary files a/!NotAdopted/SMS/res/SMSNOTSENT.ico and /dev/null differ diff --git a/!NotAdopted/SMS/res/SMSSENT.ico b/!NotAdopted/SMS/res/SMSSENT.ico deleted file mode 100644 index da61e1c52c..0000000000 Binary files a/!NotAdopted/SMS/res/SMSSENT.ico and /dev/null differ diff --git a/!NotAdopted/SMS/res/halftick.ico b/!NotAdopted/SMS/res/halftick.ico deleted file mode 100644 index a7fcd94b7a..0000000000 Binary files a/!NotAdopted/SMS/res/halftick.ico and /dev/null differ diff --git a/!NotAdopted/SMS/resource.h b/!NotAdopted/SMS/resource.h deleted file mode 100644 index 3a7e98455d..0000000000 --- a/!NotAdopted/SMS/resource.h +++ /dev/null @@ -1,70 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by resource.rc -// -#define IDD_SENDSMS 102 -#define IDR_CONTEXT 104 -#define IDD_RECVSMS 109 -#define IDI_SMSNOTSENT 110 -#define IDI_SMSSENT 111 -#define IDD_SMSTIMEDOUT 112 -#define IDD_SENDSMSTIMEDOUT 113 -#define IDI_HALFTICK 119 -#define IDD_SENDSMSACCEPT 120 -#define IDD_OPT_SMSPLUGIN 234 -#define IDC_ADDRESS 1000 -#define IDC_EDIT 1001 -#define IDC_ADDRESS2 1001 -#define IDC_ACCOUNTS 1001 -#define IDC_MESSAGE 1002 -#define IDC_STATUS 1003 -#define IDC_NUMBER 1004 -#define IDC_NAME 1005 -#define IDC_ADD 1006 -#define IDC_DELETE 1008 -#define IDC_SIGNATURE 1008 -#define IDC_LIST 1009 -#define IDC_COUNT 1010 -#define IDC_TEXT 1011 -#define IDC_MSGTYPE 1012 -#define IDC_MSGTIME 1013 -#define IDC_BEGIN 1017 -#define IDC_END 1018 -#define IDC_SAVENUMBER 1020 -#define IDC_MULTIPLE 1025 -#define IDC_ADDNUMBER 1029 -#define IDC_ST_CHARS 1033 -#define IDC_ST_ENTERMESSAGE 1034 -#define IDC_ST_TO 1035 -#define IDC_ST_ADDRESS 1036 -#define IDC_ST_NUMBER 1037 -#define IDC_NUMBERSLIST 1038 -#define IDC_MESSAGEID 1039 -#define IDC_SOURCE 1040 -#define IDC_NETWORK 1041 -#define IDC_SHOWACK 1044 -#define IDC_NOSHOWACK 1045 -#define IDC_AUTOPOP 1045 -#define IDC_READNEXT 1046 -#define IDC_SAVEWINPOS 1046 -#define IDC_USESIGNATURE 1047 -#define IDC_SIGNGROUP 1048 -#define IDC_ST_MESSAGEID 1049 -#define IDC_ST_NETWORK 1050 -#define IDC_ST_SOURCE 1051 -#define IDC_HISTORY 1080 -#define IDM_VIEWMSG 40001 -#define IDM_VIEWACK 40002 -#define IDM_VIEWRCPT 40003 -#define IDC_STATIC -1 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 121 -#define _APS_NEXT_COMMAND_VALUE 40004 -#define _APS_NEXT_CONTROL_VALUE 1053 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/!NotAdopted/SMS/resource.rc b/!NotAdopted/SMS/resource.rc deleted file mode 100644 index 50c92a2c70..0000000000 --- a/!NotAdopted/SMS/resource.rc +++ /dev/null @@ -1,291 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Neutral resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) -#ifdef _WIN32 -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -#pragma code_page(1251) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,2,5,3 - PRODUCTVERSION 0,2,5,3 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000004b0" - BEGIN - VALUE "Comments", "Send and receive SMS messages" - VALUE "CompanyName", " " - VALUE "FileDescription", "Miranda SMS plugin" - VALUE "FileVersion", "0.2.5.3" - VALUE "InternalName", "sms plugin" - VALUE "LegalCopyright", "Copyright © 2002-3 Ariel Shulman (Original by Richard Hughes), 2007-2009 Rozhuk Ivan (Ivan 83)" - VALUE "OriginalFilename", "sms.dll" - VALUE "ProductName", "Miranda IM" - VALUE "ProductVersion", "0.2.5.3" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0, 1200 - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_SMSNOTSENT ICON "res\\SMSNOTSENT.ico" -IDI_SMSSENT ICON "res\\SMSSENT.ico" -IDI_HALFTICK ICON "res\\halftick.ico" - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_RECVSMS DIALOGEX 0, 0, 278, 126 -STYLE DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "Received SMS" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - EDITTEXT IDC_MESSAGE,3,29,271,76,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | ES_WANTRETURN | WS_VSCROLL,WS_EX_CLIENTEDGE - DEFPUSHBUTTON "&Reply",IDOK,83,108,50,14 - PUSHBUTTON "&Close",IDCANCEL,143,108,50,14 - PUSHBUTTON "Read Next",IDC_READNEXT,217,105,57,17,NOT WS_VISIBLE - LTEXT "From:",IDC_STATIC,3,6,19,11 - LTEXT "Message received:",IDC_STATIC,3,20,108,8 - LTEXT "",IDC_NAME,24,5,105,11,SS_SUNKEN - LTEXT "Number:",IDC_ST_NUMBER,133,6,28,11 - LTEXT "",IDC_NUMBER,164,5,110,11,SS_SUNKEN -END - -IDD_SENDSMS DIALOGEX 0, 0, 394, 145 -STYLE DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "Send SMS" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "To:",IDC_ST_TO,2,5,18,8 - COMBOBOX IDC_NAME,20,3,111,12,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP - RTEXT "Number:",IDC_ST_ADDRESS,134,5,30,8 - COMBOBOX IDC_ADDRESS,164,3,113,62,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Add number to list",IDC_ADDNUMBER,284,3,108,14 - CONTROL "Tree1",IDC_NUMBERSLIST,"SysTreeView32",TVS_HASBUTTONS | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | TVS_NOTOOLTIPS | TVS_TRACKSELECT | TVS_FULLROWSELECT | WS_BORDER | WS_HSCROLL | WS_TABSTOP,284,17,108,109 - PUSHBUTTON "&H",IDC_HISTORY,2,17,15,11,BS_ICON - COMBOBOX IDC_ACCOUNTS,20,18,72,83,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Save number",IDC_SAVENUMBER,133,17,46,11 - PUSHBUTTON "Multiple >>",IDC_MULTIPLE,232,17,45,11 - LTEXT "Enter message:",IDC_ST_ENTERMESSAGE,2,32,76,9 - RTEXT "Chars:",IDC_ST_CHARS,207,32,34,8 - RTEXT "%d/160",IDC_COUNT,242,32,35,8,SS_NOPREFIX | SS_SUNKEN - EDITTEXT IDC_MESSAGE,2,42,275,84,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL,WS_EX_CLIENTEDGE - DEFPUSHBUTTON "&Send",IDOK,73,130,50,14 - PUSHBUTTON "&Close",IDCANCEL,143,130,50,14 -END - -IDD_SENDSMSTIMEDOUT DIALOG 0, 0, 211, 94 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "SMS Message Didn't Send" -FONT 8, "MS Shell Dlg" -BEGIN - DEFPUSHBUTTON "&Try again",IDOK,39,73,62,16 - PUSHBUTTON "&Cancel",IDCANCEL,106,73,62,16 - LTEXT "The SMS message send timed out",IDC_STATUS,5,6,201,61 -END - -IDD_OPT_SMSPLUGIN DIALOGEX 0, 0, 255, 161 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "SMS Plugin",IDC_STATIC,6,4,244,150 - GROUPBOX "",IDC_SIGNGROUP,12,28,231,74,WS_GROUP - EDITTEXT IDC_SIGNATURE,17,40,221,44,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN - CONTROL "Begining",IDC_BEGIN,"Button",BS_AUTORADIOBUTTON | WS_GROUP,115,90,65,8 - CONTROL "End",IDC_END,"Button",BS_AUTORADIOBUTTON,180,90,58,8 - LTEXT "Put signature at the:",IDC_STATIC,18,90,89,10 - CONTROL "Use Signature",IDC_USESIGNATURE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,21,226,10 - CONTROL "Show server notifications",IDC_SHOWACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,108,226,10 - CONTROL "Auto popup on new message",IDC_AUTOPOP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,120,226,10 - CONTROL "Save window position per contact",IDC_SAVEWINPOS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,132,226,10 -END - -IDD_SENDSMSACCEPT DIALOG 0, 0, 256, 90 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "SMS Message Sent" -FONT 8, "MS Shell Dlg" -BEGIN - PUSHBUTTON "&OK",IDOK,91,69,62,16 - LTEXT "",IDC_MESSAGEID,57,6,194,9 - LTEXT "Message ID:",IDC_ST_MESSAGEID,5,6,52,8 - LTEXT "Source:",IDC_ST_SOURCE,5,27,52,8 - LTEXT "",IDC_SOURCE,57,27,194,39 - LTEXT "Network:",IDC_ST_NETWORK,5,17,52,8 - LTEXT "",IDC_NETWORK,57,17,194,10 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_RECVSMS, DIALOG - BEGIN - LEFTMARGIN, 3 - RIGHTMARGIN, 274 - TOPMARGIN, 5 - BOTTOMMARGIN, 122 - HORZGUIDE, 16 - HORZGUIDE, 29 - HORZGUIDE, 105 - END - - IDD_SENDSMS, DIALOG - BEGIN - LEFTMARGIN, 2 - RIGHTMARGIN, 392 - VERTGUIDE, 164 - VERTGUIDE, 277 - VERTGUIDE, 284 - TOPMARGIN, 3 - BOTTOMMARGIN, 144 - HORZGUIDE, 17 - HORZGUIDE, 28 - HORZGUIDE, 32 - HORZGUIDE, 51 - HORZGUIDE, 111 - HORZGUIDE, 126 - HORZGUIDE, 130 - END - - IDD_SENDSMSTIMEDOUT, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 206 - TOPMARGIN, 6 - BOTTOMMARGIN, 89 - END - - IDD_OPT_SMSPLUGIN, DIALOG - BEGIN - RIGHTMARGIN, 250 - VERTGUIDE, 6 - VERTGUIDE, 12 - VERTGUIDE, 18 - VERTGUIDE, 115 - VERTGUIDE, 180 - VERTGUIDE, 238 - VERTGUIDE, 243 - VERTGUIDE, 248 - BOTTOMMARGIN, 150 - HORZGUIDE, 84 - HORZGUIDE, 90 - HORZGUIDE, 95 - HORZGUIDE, 107 - HORZGUIDE, 116 - END - - IDD_SENDSMSACCEPT, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 251 - VERTGUIDE, 57 - TOPMARGIN, 6 - BOTTOMMARGIN, 85 - HORZGUIDE, 14 - HORZGUIDE, 17 - HORZGUIDE, 27 - END -END -#endif // APSTUDIO_INVOKED - -#endif // Neutral resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// English (U.K.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include \r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // English (U.K.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/!NotAdopted/SMS/send.cpp b/!NotAdopted/SMS/send.cpp deleted file mode 100644 index fdfc80ffd8..0000000000 --- a/!NotAdopted/SMS/send.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* -Miranda-IM SMS Plugin -Copyright (C) 2001-2 Richard Hughes -Copyright (C) 2007-2009 Rozhuk Ivan - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ---------------------------------------------------------------------------- - -This was the original words. -This plugin was modified by Ariel Shulman (NuKe007). -For any comments, problems, etc. contact me at Miranda-IM forums or E-Mail or ICQ. -All the information needed you can find at www.nuke007.tk -Enjoy the code and use it smartly! -*/ - -#include "main.h" - - - -//This function gets HWND of the window, the number, and the message. -void StartSmsSend(HWND hWndDlg,SIZE_T dwModuleIndex,LPWSTR lpwszPhone,SIZE_T dwPhoneSize,LPWSTR lpwszMessage,SIZE_T dwMessageSize) -{ - if (ssSMSSettings.ppaSMSAccounts && dwModuleIndex!=-1 && dwModuleIndextimestamp=time(NULL); - pdbei->flags=(DBEF_SENT|DBEF_UTF); - pdbei->eventType=ICQEVENTTYPE_SMS; - pdbei->cbBlob=(mir_snprintf(lpszBuff,dwBuffSize,"SMS To: +%s\r\n%s",szPhone,lpszMessageUTF)+4); - pdbei->pBlob=(PBYTE)lpszBuff; - SendSMSWindowDbeiSet(hWndDlg,pdbei); - - mir_snprintf(szServiceName,sizeof(szServiceName),"%s%s",ssSMSSettings.ppaSMSAccounts[dwModuleIndex]->szModuleName,MS_ICQ_SENDSMS); - if (ServiceExists(szServiceName)) - { - WideCharToMultiByte(CP_UTF8,0,lpwszMessageXMLEncoded,dwMessageXMLEncodedSize,lpszMessageUTF,dwMessageUTFBuffSize,NULL,NULL); - hProcess=(HANDLE)CallService(szServiceName,(WPARAM)szPhone,(LPARAM)lpszMessageUTF); - SendSMSWindowHProcessSet(hWndDlg,hProcess); - }else{ - MEMFREE(pdbei); - } - } - MEMFREE(lpszMessageUTF); - } - MEMFREE(lpwszMessageXMLEncoded); - } - } -} - - - diff --git a/!NotAdopted/SMS/senddlg.cpp b/!NotAdopted/SMS/senddlg.cpp deleted file mode 100644 index dbecd20ec6..0000000000 --- a/!NotAdopted/SMS/senddlg.cpp +++ /dev/null @@ -1,1177 +0,0 @@ -/* -Miranda-IM SMS Plugin -Copyright (C) 2001-2 Richard Hughes -Copyright (C) 2007-2009 Rozhuk Ivan - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ---------------------------------------------------------------------------- - -This was the original words. -This plugin was modified by Ariel Shulman (NuKe007). -For any comments, problems, etc. contact me at Miranda-IM forums or E-Mail or ICQ. -All the information needed you can find at www.nuke007.tk -Enjoy the code and use it smartly! -*/ - -#include "main.h" - - - -#define TIMERID_MSGSEND 0 -#define TIMEDOUT_CANCEL 0 -#define TIMEDOUT_RETRY 1 -#define DM_TIMEOUTDECIDED (WM_USER+18) - - -//Defnition needed to the SMS window list -typedef struct -{ - LIST_MT_ITEM lmtListMTItem; - HWND hWnd; - HBRUSH hBkgBrush; - HANDLE hProcess; - HANDLE hContact; - HANDLE hMyContact; - HTREEITEM hItemSend; - BOOL bMultiple; - SIZE_T dwContactsListCount; - HANDLE *phContactsList; - DBEVENTINFO *pdbei; -} SEND_SMS_WINDOW_DATA; - - - -void AddContactPhonesToCombo (HWND hWnd,HANDLE hContact); -void SendSMSWindowFillTreeView (HWND hWnd); -SIZE_T GetSMSMessageLenMax (HWND hWndDlg); - -#define GET_WINDOW_DATA(hWndDlg) ((SEND_SMS_WINDOW_DATA*)GetWindowLongPtr(hWndDlg,GWL_USERDATA)) - - - - - -DWORD SendSMSWindowInitialize() -{ - DWORD dwRetErrorCode; - - dwRetErrorCode=ListMTInitialize(&ssSMSSettings.lmtSendSMSWindowsListMT,0); -return(dwRetErrorCode); -} - -void SendSMSWindowDestroy() -{ - SEND_SMS_WINDOW_DATA *psswdWindowData; - - ListMTLock(&ssSMSSettings.lmtSendSMSWindowsListMT); - while(ListMTItemGetFirst(&ssSMSSettings.lmtSendSMSWindowsListMT,NULL,(LPVOID*)&psswdWindowData)==NO_ERROR) - {// цикл - SendSMSWindowRemove(psswdWindowData->hWnd); - } - ListMTUnLock(&ssSMSSettings.lmtSendSMSWindowsListMT); - ListMTDestroy(&ssSMSSettings.lmtSendSMSWindowsListMT); -} - - - -BOOL CALLBACK SendSmsDlgProc(HWND hWndDlg,UINT message,WPARAM wParam,LPARAM lParam) -{ - SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); - - switch(message){ - case WM_INITDIALOG: - TranslateDialogDefault(hWndDlg); //Translate intially - bid - AddWinHandle(GetDlgItem(hWndDlg,IDC_MESSAGE)); - - psswdWindowData=(SEND_SMS_WINDOW_DATA*)lParam; - SetWindowLongPtr(hWndDlg,GWL_USERDATA,(LONG_PTR)lParam); - - { - WNDPROC OldEditWndProc; - - OldEditWndProc=(WNDPROC)SetWindowLongPtr(GetDlgItem(hWndDlg,IDC_MESSAGE),GWL_WNDPROC,(LONG_PTR)MessageSubclassProc); - SetWindowLongPtr(GetDlgItem(hWndDlg,IDC_MESSAGE),GWL_USERDATA,(LONG_PTR)OldEditWndProc); - } - - SendMessage(hWndDlg,WM_SETICON,ICON_BIG,(LPARAM)LoadSkinnedIcon(SKINICON_OTHER_SMS)); - SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_HISTORY,BM_SETIMAGE,IMAGE_ICON,(LPARAM)LoadSkinnedIcon(SKINICON_OTHER_HISTORY)); - { - HICON hIcon; - HIMAGELIST hIml=ImageList_Create(16,16,ILC_COLOR32|ILC_MASK,0,30); - TreeView_SetImageList(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),hIml,TVSIL_NORMAL); - hIcon=LoadSkinnedIcon(SKINICON_OTHER_NOTICK); ImageList_AddIcon(hIml,hIcon); - hIcon=LoadSkinnedIcon(SKINICON_OTHER_TICK); ImageList_AddIcon(hIml,hIcon); - hIcon=(HICON)LoadImage(ssSMSSettings.hInstance,MAKEINTRESOURCE(IDI_HALFTICK),IMAGE_ICON,0,0,LR_SHARED); ImageList_AddIcon(hIml,hIcon); - } - { - HFONT hFont; - LOGFONT lf; - hFont=(HFONT)SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,WM_GETFONT,0,0); - if (hFont && hFont!=(HFONT)SEND_DLG_ITEM_MESSAGE(hWndDlg,IDOK,WM_GETFONT,0,0)) DeleteObject(hFont); - LoadMsgDlgFont(MSGFONTID_MESSAGEAREA,&lf,NULL); - hFont=CreateFontIndirect(&lf); - SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,WM_SETFONT,(WPARAM)hFont,MAKELPARAM(TRUE,0)); - - COLORREF colour=DBGetContactSettingDword(NULL,SRMMMOD,SRMSGSET_INPBKGCOLOUR,SRMSGDEFSET_BKGCOLOUR); - psswdWindowData->hBkgBrush=CreateSolidBrush(colour); - } - { - TOOLINFO ti; - HWND hwndToolTips; - hwndToolTips=CreateWindowEx(WS_EX_TOPMOST,TOOLTIPS_CLASS,TEXT(""),WS_POPUP,0,0,0,0,NULL,NULL,GetModuleHandle(NULL),NULL); - ZeroMemory(&ti,sizeof(ti)); - ti.cbSize=sizeof(ti); - ti.uFlags=TTF_IDISHWND|TTF_SUBCLASS; - ti.uId=(UINT)GetDlgItem(hWndDlg,IDC_HISTORY); - ti.lpszText=TranslateW(L"View User's History"); - SendMessage(hwndToolTips,TTM_ADDTOOL,0,(LPARAM)&ti); - ti.uId=(UINT)GetDlgItem(hWndDlg,IDC_ADDNUMBER); - ti.lpszText=TranslateW(L"Add Number To The Multiple List"); - SendMessage(hwndToolTips,TTM_ADDTOOL,0,(LPARAM)&ti); - ti.uId=(UINT)GetDlgItem(hWndDlg,IDC_SAVENUMBER); - ti.lpszText=TranslateW(L"Save Number To The User's Details Phonebook"); - SendMessage(hwndToolTips,TTM_ADDTOOL,0,(LPARAM)&ti); - ti.uId=(UINT)GetDlgItem(hWndDlg,IDC_MULTIPLE); - ti.lpszText=TranslateW(L"Show/Hide Multiple List"); - SendMessage(hwndToolTips,TTM_ADDTOOL,0,(LPARAM)&ti); - ti.uId=(UINT)GetDlgItem(hWndDlg,IDC_COUNT); - ti.lpszText=TranslateW(L"Shows How Much Chars You've Typed"); - SendMessage(hwndToolTips,TTM_ADDTOOL,0,(LPARAM)&ti); - } - { - RECT rcWin,rcList; - GetWindowRect(hWndDlg,&rcWin); - GetWindowRect(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),&rcList); - SetWindowPos(hWndDlg,0,rcWin.left,rcWin.top,rcWin.right-rcWin.left - (rcList.right-rcList.left) - 10,rcWin.bottom - rcWin.top,SWP_NOZORDER|SWP_NOMOVE); - } - - SendSMSWindowUpdateAccountList(hWndDlg); - - { - WCHAR wszSign[1024]; - SIZE_T dwSignLen; - - if (DB_SMS_GetByte(NULL,"UseSignature",SMS_DEFAULT_USESIGNATURE)) - if (DB_SMS_GetStaticStringW(NULL,"Signature",wszSign,SIZEOF(wszSign),&dwSignLen)) - { - SET_DLG_ITEM_TEXTW(hWndDlg,IDC_MESSAGE,wszSign); - - if (DB_SMS_GetByte(NULL,"SignaturePos",SMS_DEFAULT_SIGNATUREPOS)) SEND_DLG_ITEM_MESSAGEW(hWndDlg,IDC_MESSAGE,EM_SETSEL,dwSignLen,dwSignLen); - EnableWindow(GetDlgItem(hWndDlg,IDOK),dwSignLen); - } - - mir_sntprintf(wszSign,SIZEOF(wszSign),L"%d/%d",dwSignLen,GetSMSMessageLenMax(hWndDlg)); - SET_DLG_ITEM_TEXTW(hWndDlg,IDC_COUNT,wszSign); - } - - if (Utils_RestoreWindowPosition(hWndDlg,(DB_SMS_GetByte(NULL,"SavePerContact",0)? psswdWindowData->hMyContact:NULL),PROTOCOL_NAMEA,"send")) - {// def pos - SetWindowPos(hWndDlg,0,200,200,400,350,SWP_NOZORDER); - } - InvalidateRect(GetDlgItem(hWndDlg,IDC_MESSAGE),NULL,FALSE); - return(TRUE); - case WM_GETMINMAXINFO: - if (psswdWindowData->bMultiple) - { - ((LPMINMAXINFO)lParam)->ptMinTrackSize.x=461; - ((LPMINMAXINFO)lParam)->ptMinTrackSize.y=230; - }else{ - ((LPMINMAXINFO)lParam)->ptMinTrackSize.x=300; - ((LPMINMAXINFO)lParam)->ptMinTrackSize.y=230; - } - break; - case WM_SIZE: - { - int cx,cy; - RECT rcWin; - GetWindowRect(hWndDlg,&rcWin); - if (psswdWindowData->bMultiple) - { - cx=rcWin.right-rcWin.left-181; - cy=rcWin.bottom-rcWin.top; - }else{ - cx=rcWin.right-rcWin.left; - cy=rcWin.bottom-rcWin.top; - } - SetWindowPos(GetDlgItem(hWndDlg,IDC_MESSAGE),0,0,0,cx - 14,cy - 132,SWP_NOZORDER|SWP_NOMOVE); - SetWindowPos(GetDlgItem(hWndDlg,IDC_NAME),0,0,0,(cx*35)/100,20,SWP_NOZORDER|SWP_NOMOVE); - SetWindowPos(GetDlgItem(hWndDlg,IDC_ACCOUNTS),0,0,0,(cx*35)/100,20,SWP_NOZORDER|SWP_NOMOVE); - SetWindowPos(GetDlgItem(hWndDlg,IDC_ADDRESS),0,cx - (cx*35)/100 - 11,5,(cx*35)/100,20,SWP_NOZORDER); - SetWindowPos(GetDlgItem(hWndDlg,IDC_ST_ADDRESS),0,cx - (cx*35)/100 - 68,5,50,20,SWP_NOZORDER); - SetWindowPos(GetDlgItem(hWndDlg,IDC_MULTIPLE),0,cx - ((cx*35)/100 + 35)/2 - 11,30,((cx*35)/100 + 35)/2,20,SWP_NOZORDER); - SetWindowPos(GetDlgItem(hWndDlg,IDC_SAVENUMBER),0,cx - (cx*35)/100 - 58,30,((cx*35)/100 + 35)/2,20,SWP_NOZORDER); - SetWindowPos(GetDlgItem(hWndDlg,IDC_HISTORY),0,0,0,20,20,SWP_NOZORDER|SWP_NOMOVE); - SetWindowPos(GetDlgItem(hWndDlg,IDC_COUNT),0,cx - 61,52,50,15,SWP_NOZORDER); - SetWindowPos(GetDlgItem(hWndDlg,IDC_ST_CHARS),0,cx - 106,52,40,15,SWP_NOZORDER); - SetWindowPos(GetDlgItem(hWndDlg,IDC_ADDNUMBER),0,cx,5,170,20,SWP_NOZORDER); - SetWindowPos(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),0,cx,25,170,cy - 90,SWP_NOZORDER); - //SetWindowPos(GetDlgItem(hWndDlg,IDC_REMOVENUMBER),0,cx,cy - 110 + 25,170,20,SWP_NOZORDER); - SetWindowPos(GetDlgItem(hWndDlg,IDOK),0,cx/2 - 87,cy - 60,80,25,SWP_NOZORDER); - SetWindowPos(GetDlgItem(hWndDlg,IDCANCEL),0,cx/2 + 7,cy - 60,80,25,SWP_NOZORDER); - RedrawWindow(hWndDlg,NULL,NULL,RDW_FRAME|RDW_INVALIDATE); - } - break; - case WM_TIMER: - if (wParam==TIMERID_MSGSEND) - { - HWND hwndTimeOut; - WCHAR wszMessage[1028],wszPhone[MAX_PHONE_LEN]; - - if (psswdWindowData->bMultiple) - { - TVITEM tvi; - tvi.mask=TVIF_TEXT; - tvi.hItem=SendSMSWindowHItemSendGet(hWndDlg); - tvi.pszText=wszPhone; - tvi.cchTextMax=SIZEOF(wszPhone); - TreeView_GetItem(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),&tvi); - }else{ - GET_DLG_ITEM_TEXTW(hWndDlg,IDC_ADDRESS,wszPhone,SIZEOF(wszPhone)); - } - mir_sntprintf(wszMessage,SIZEOF(wszMessage),TranslateW(L"The SMS message send to %s timed out."),wszPhone); - KillTimer(hWndDlg,wParam); - ShowWindow(hWndDlg,SW_SHOWNORMAL); - EnableWindow(hWndDlg,FALSE); - hwndTimeOut=CreateDialog(ssSMSSettings.hInstance,MAKEINTRESOURCE(IDD_SENDSMSTIMEDOUT),hWndDlg,SMSTimedOutDlgProc); - SET_DLG_ITEM_TEXTW(hwndTimeOut,IDC_STATUS,wszMessage); - } - break; - case WM_CTLCOLOREDIT: - if ((HWND)lParam==GetDlgItem(hWndDlg,IDC_MESSAGE)) - { - COLORREF colour; - - LoadMsgDlgFont(MSGFONTID_MESSAGEAREA,NULL,&colour); - SetTextColor((HDC)wParam,colour); - SetBkColor((HDC)wParam,DBGetContactSettingDword(NULL,SRMMMOD,SRMSGSET_INPBKGCOLOUR,SRMSGDEFSET_BKGCOLOUR)); - return((BOOL)psswdWindowData->hBkgBrush); - } - break; - case DM_TIMEOUTDECIDED: - EnableWindow(hWndDlg,TRUE); - switch(wParam){ - case TIMEDOUT_CANCEL: - if (psswdWindowData->bMultiple) - { - if (SendSMSWindowNextHItemGet(hWndDlg,psswdWindowData->hItemSend)) - { - psswdWindowData->hItemSend=SendSMSWindowNextHItemGet(hWndDlg,psswdWindowData->hItemSend); - SendSMSWindowNext(hWndDlg); - }else{ - SendSMSWindowRemove(hWndDlg); - } - }else{ - EnableWindow(GetDlgItem(hWndDlg,IDOK),TRUE); - SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,EM_SETREADONLY,FALSE,0); - EnableWindow(GetDlgItem(hWndDlg,IDC_ACCOUNTS),TRUE); - EnableWindow(GetDlgItem(hWndDlg,IDC_ADDRESS),TRUE); - EnableWindow(GetDlgItem(hWndDlg,IDC_SAVENUMBER),TRUE); - EnableWindow(GetDlgItem(hWndDlg,IDC_MULTIPLE),TRUE); - EnableWindow(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),TRUE); - if (psswdWindowData->hMyContact==NULL) EnableWindow(GetDlgItem(hWndDlg,IDC_NAME),TRUE); - SetFocus(GetDlgItem(hWndDlg,IDC_MESSAGE)); - psswdWindowData->hItemSend=NULL; - } - break; - case TIMEDOUT_RETRY: - { - WCHAR wszPhone[MAX_PHONE_LEN]; - LPWSTR lpwszMessage; - SIZE_T dwPhoneSize,dwMessageSize; - - dwMessageSize=GET_DLG_ITEM_TEXT_LENGTH(hWndDlg,IDC_MESSAGE); - lpwszMessage=(LPWSTR)MEMALLOC(((dwMessageSize+4)*sizeof(WCHAR))); - if (lpwszMessage) - { - if (psswdWindowData->bMultiple) - { - TVITEM tvi; - tvi.mask=TVIF_TEXT; - tvi.hItem=psswdWindowData->hItemSend; - tvi.pszText=wszPhone; - tvi.cchTextMax=SIZEOF(wszPhone); - TreeView_GetItem(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),&tvi); - dwPhoneSize=lstrlenW(wszPhone); - }else{ - dwPhoneSize=GET_DLG_ITEM_TEXTW(hWndDlg,IDC_ADDRESS,wszPhone,SIZEOF(wszPhone)); - } - dwMessageSize=GET_DLG_ITEM_TEXTW(hWndDlg,IDC_MESSAGE,lpwszMessage,(dwMessageSize+2)); - SendSMSWindowNumberSet(hWndDlg,wszPhone,dwPhoneSize); - StartSmsSend(hWndDlg,SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ACCOUNTS,CB_GETCURSEL,0,0),wszPhone,dwPhoneSize,lpwszMessage,dwMessageSize); - MEMFREE(lpwszMessage); - } - } - SetTimer(hWndDlg,TIMERID_MSGSEND,TIMEOUT_MSGSEND,NULL); - break; - } - break; - case WM_COMMAND: - switch(LOWORD(wParam)){ - case IDC_MULTIPLE: - SendSMSWindowMultipleSet(hWndDlg,!psswdWindowData->bMultiple); - break; - case IDC_ADDNUMBER: - { - WCHAR wszPhone[MAX_PHONE_LEN]; - if (IsPhoneW(wszPhone,GET_DLG_ITEM_TEXTW(hWndDlg,IDC_ADDRESS,wszPhone,SIZEOF(wszPhone)))) - { - TVINSERTSTRUCT tvis={0}; - - tvis.item.mask=(TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE); - tvis.hInsertAfter=TVI_SORT; - tvis.item.pszText=wszPhone; - TreeView_InsertItem(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),&tvis); - }else{ - MessageBox(hWndDlg,TranslateW(L"The phone szPhone should start with a + and consist of numbers, spaces, brackets and hyphens only."),TranslateW(L"Invalid Phone Number"),MB_OK); - } - } - break; - case IDC_HISTORY: - CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)psswdWindowData->hMyContact,0); - break; - case IDOK: - if ((SIZE_T)GET_DLG_ITEM_TEXT_LENGTH(hWndDlg,IDC_MESSAGE) > GetSMSMessageLenMax(hWndDlg)) - { - MessageBox(hWndDlg,TranslateW(L"Message is too long, press OK to continue."),TranslateW(L"Error - Message too long"),MB_OK); - }else{ - if (psswdWindowData->bMultiple) - { - HTREEITEM hItem=SendSMSWindowNextHItemGet(hWndDlg,TreeView_GetRoot(GetDlgItem(hWndDlg,IDC_NUMBERSLIST))); - if (hItem) - { - psswdWindowData->hItemSend=hItem; - EnableWindow(GetDlgItem(hWndDlg,IDOK),FALSE); - EnableWindow(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),FALSE); - EnableWindow(GetDlgItem(hWndDlg,IDC_SAVENUMBER),FALSE); - EnableWindow(GetDlgItem(hWndDlg,IDC_NAME),FALSE); - EnableWindow(GetDlgItem(hWndDlg,IDC_MULTIPLE),FALSE); - EnableWindow(GetDlgItem(hWndDlg,IDC_ADDNUMBER),FALSE); - //EnableWindow(GetDlgItem(hWndDlg,IDC_REMOVENUMBER),FALSE); - SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,EM_SETREADONLY,TRUE,0); - EnableWindow(GetDlgItem(hWndDlg,IDC_ACCOUNTS),FALSE); - EnableWindow(GetDlgItem(hWndDlg,IDC_ADDRESS),FALSE); - SendSMSWindowNext(hWndDlg); - }else{ - MessageBox(hWndDlg,TranslateW(L"There must be numbers in the list first."),TranslateW(L"No Numbers"),MB_OK); - } - }else{ - WCHAR wszPhone[MAX_PHONE_LEN]; - SIZE_T dwPhoneSize; - - dwPhoneSize=GET_DLG_ITEM_TEXTW(hWndDlg,IDC_ADDRESS,wszPhone,SIZEOF(wszPhone)); - if (IsPhoneW(wszPhone,dwPhoneSize)) - { - LPWSTR lpwszMessage; - SIZE_T dwMessageSize; - - dwMessageSize=GET_DLG_ITEM_TEXT_LENGTH(hWndDlg,IDC_MESSAGE); - lpwszMessage=(LPWSTR)MEMALLOC((dwMessageSize+4)*sizeof(WCHAR)); - if (lpwszMessage) - { - dwMessageSize=GET_DLG_ITEM_TEXTW(hWndDlg,IDC_MESSAGE,lpwszMessage,(dwMessageSize+2)); - SendSMSWindowNumberSet(hWndDlg,wszPhone,dwPhoneSize); - EnableWindow(GetDlgItem(hWndDlg,IDOK),FALSE); - EnableWindow(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),FALSE); - EnableWindow(GetDlgItem(hWndDlg,IDC_SAVENUMBER),FALSE); - EnableWindow(GetDlgItem(hWndDlg,IDC_NAME),FALSE); - EnableWindow(GetDlgItem(hWndDlg,IDC_MULTIPLE),FALSE); - EnableWindow(GetDlgItem(hWndDlg,IDC_ACCOUNTS),FALSE); - EnableWindow(GetDlgItem(hWndDlg,IDC_ADDRESS),FALSE); - SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,EM_SETREADONLY,TRUE,0); - StartSmsSend(hWndDlg,SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ACCOUNTS,CB_GETCURSEL,0,0),wszPhone,dwPhoneSize,lpwszMessage,dwMessageSize); - SetTimer(hWndDlg,TIMERID_MSGSEND,TIMEOUT_MSGSEND,NULL); - - MEMFREE(lpwszMessage); - } - }else{ - MessageBox(hWndDlg,TranslateW(L"Valid phone numbers are of the form '+(country code)(phone szPhone)'. The contents of the phone szPhone portion is dependent on the national layout of phone numbers, but often omits the leading zero."),TranslateW(L"Invalid phone number"),MB_OK); - SetFocus(GetDlgItem(hWndDlg,IDC_ADDRESS)); - SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ADDRESS,CB_SETEDITSEL,0,MAKELPARAM(0,-1)); - } - } - } - break; - case IDCANCEL: - DeleteObject((HFONT)SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,WM_GETFONT,0,0)); - KillTimer(GetParent(hWndDlg),TIMERID_MSGSEND); - SendSMSWindowRemove(hWndDlg); - break; - case IDC_MESSAGE: - if (HIWORD(wParam)==EN_CHANGE) - { - WCHAR wszBuff[MAX_PATH]; - SIZE_T dwMessageSize=GET_DLG_ITEM_TEXT_LENGTH(hWndDlg,IDC_MESSAGE); - - EnableWindow(GetDlgItem(hWndDlg,IDOK),dwMessageSize); - mir_sntprintf(wszBuff,SIZEOF(wszBuff),L"%d/%d",dwMessageSize,GetSMSMessageLenMax(hWndDlg)); - SET_DLG_ITEM_TEXTW(hWndDlg,IDC_COUNT,wszBuff); - } - break; - case IDC_SAVENUMBER: - { - BOOL bCont=TRUE; - char szBuff[MAX_PATH]; - WCHAR wszPhone[MAX_PHONE_LEN]; - SIZE_T dwPhoneSize; - DBVARIANT dbv; - - dwPhoneSize=GET_DLG_ITEM_TEXTW(hWndDlg,IDC_ADDRESS,wszPhone,(SIZEOF(wszPhone)-4)); - if (IsPhoneW(wszPhone,dwPhoneSize)) - { - if (IsContactPhone(psswdWindowData->hMyContact,wszPhone,dwPhoneSize)==FALSE) - { - lstrcatW(wszPhone,L" SMS"); - for(DWORD i=0;bCont;i++) - { - mir_snprintf(szBuff,SIZEOF(szBuff),"MyPhone%d",i); - if (DBGetContactSetting(psswdWindowData->hMyContact,"UserInfo",szBuff,&dbv)) bCont=FALSE; - DBFreeVariant(&dbv); - } - DB_SetStringW(psswdWindowData->hMyContact,"UserInfo",szBuff,wszPhone); - } - }else{ - MessageBox(hWndDlg,TranslateW(L"The phone szPhone should start with a + and consist of numbers, spaces, brackets and hyphens only."),TranslateW(L"Invalid Phone Number"),MB_OK); - } - } - break; - case IDC_NAME: - if (HIWORD(wParam)==CBN_SELCHANGE) - { - SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ADDRESS,CB_RESETCONTENT,0,0); - if (SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_NAME,CB_GETCURSEL,0,0)) - { - HANDLE hContact=SendSMSWindowSMSContactGet(hWndDlg,(SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_NAME,CB_GETCURSEL,0,0)-1)); - if (hContact) AddContactPhonesToCombo(hWndDlg,hContact); - } - } - break; - } - break; - case WM_NOTIFY: - switch(((NMHDR*)lParam)->idFrom){ - case IDC_NUMBERSLIST: - switch(((NMHDR*)lParam)->code){ - case NM_CLICK: - { - int iImage,iSame=1; - HWND hWndTree=GetDlgItem(hWndDlg,IDC_NUMBERSLIST); - TVITEM tvi={0}; - HTREEITEM hParent; - TVHITTESTINFO hti={0}; - - hti.pt.x=(short)LOWORD(GetMessagePos()); - hti.pt.y=(short)HIWORD(GetMessagePos()); - ScreenToClient(((LPNMHDR)lParam)->hwndFrom,&hti.pt); - - if (TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom,&hti)) - if (hti.flags&TVHT_ONITEMICON) - { - tvi.mask=(TVIF_IMAGE|TVIF_SELECTEDIMAGE); - tvi.hItem=hti.hItem; - TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom,&tvi); - iImage=tvi.iImage=tvi.iSelectedImage=!tvi.iImage; - TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom,&tvi); - - if (TreeView_GetParent(hWndTree,hti.hItem)) - { - hParent=TreeView_GetParent(hWndTree,hti.hItem); - for(tvi.hItem=TreeView_GetChild(hWndTree,hParent);tvi.hItem;tvi.hItem=TreeView_GetNextSibling(hWndTree,tvi.hItem)) - { - TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom,&tvi); - if (tvi.iImage!=iImage) - { - iSame=0; - break; - } - } - tvi.hItem=hParent; - tvi.iImage=tvi.iSelectedImage=((iSame==1)? iImage:2); - TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom,&tvi); - }else{ - for(tvi.hItem=TreeView_GetChild(hWndTree,hti.hItem);tvi.hItem;tvi.hItem=TreeView_GetNextSibling(hWndTree,tvi.hItem)) - { - TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom,&tvi); - tvi.iImage=tvi.iSelectedImage=iImage; - TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom,&tvi); - } - } - } - } - break; - } - } - break; - case WM_CLOSE: - DeleteObject((HFONT)SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,WM_GETFONT,0,0)); - DeleteObject(psswdWindowData->hBkgBrush); - RemWinHandle(GetDlgItem(hWndDlg,IDC_MESSAGE)); - KillTimer(GetParent(hWndDlg),TIMERID_MSGSEND); - SendSMSWindowRemove(hWndDlg); - break; - } -return(FALSE); -} - -BOOL CALLBACK SMSTimedOutDlgProc(HWND hWndDlg,UINT msg,WPARAM wParam,LPARAM lParam) -{ - switch(msg){ - case WM_INITDIALOG: - { - RECT rc,rcParent; - TranslateDialogDefault(hWndDlg); - GetWindowRect(hWndDlg,&rc); - GetWindowRect(GetParent(hWndDlg),&rcParent); - SetWindowPos(hWndDlg,0,(rcParent.left+rcParent.right-(rc.right-rc.left))/2,(rcParent.top+rcParent.bottom-(rc.bottom-rc.top))/2,0,0,SWP_NOZORDER|SWP_NOSIZE); - KillTimer(GetParent(hWndDlg),TIMERID_MSGSEND); - } - return(TRUE); - case WM_COMMAND: - switch(LOWORD(wParam)){ - case IDOK: - SendMessage(GetParent(hWndDlg),DM_TIMEOUTDECIDED,TIMEDOUT_RETRY,0); - DestroyWindow(hWndDlg); - break; - case IDCANCEL: - SendMessage(GetParent(hWndDlg),DM_TIMEOUTDECIDED,TIMEDOUT_CANCEL,0); - DestroyWindow(hWndDlg); - break; - } - break; - } -return(FALSE); -} - -BOOL CALLBACK SMSAcceptedDlgProc(HWND hWndDlg,UINT msg,WPARAM wParam,LPARAM lParam) -{ - switch(msg){ - case WM_INITDIALOG: - { - RECT rc,rcParent; - TranslateDialogDefault(hWndDlg); - GetWindowRect(hWndDlg,&rc); - GetWindowRect(GetParent(hWndDlg),&rcParent); - SetWindowPos(hWndDlg,0,(rcParent.left+rcParent.right-(rc.right-rc.left))/2,(rcParent.top+rcParent.bottom-(rc.bottom-rc.top))/2,0,0,SWP_NOZORDER|SWP_NOSIZE); - } - return(TRUE); - case WM_COMMAND: - switch(LOWORD(wParam)){ - case IDOK: - SendSMSWindowRemove(GetParent(hWndDlg)); - DestroyWindow(hWndDlg); - break; - } - break; - } -return(FALSE); -} - -//SMS Send window list functions - -//This function create a new SMS send window, and insert it to the list. -//The function gets void and return the window HWND -HWND SendSMSWindowAdd(HANDLE hContact) -{ - HWND hRet=NULL; - SEND_SMS_WINDOW_DATA *psswdWindowData; - - psswdWindowData=(SEND_SMS_WINDOW_DATA*)MEMALLOC(sizeof(SEND_SMS_WINDOW_DATA)); - if (psswdWindowData) - { - psswdWindowData->hMyContact=hContact; - psswdWindowData->hWnd=CreateDialogParam(ssSMSSettings.hInstance,MAKEINTRESOURCE(IDD_SENDSMS),NULL,SendSmsDlgProc,(LPARAM)psswdWindowData); - if (psswdWindowData->hWnd) - { - WCHAR wszTitle[MAX_PATH]; - LPWSTR lpwszContactDisplayName; - - ListMTLock(&ssSMSSettings.lmtSendSMSWindowsListMT); - ListMTItemAdd(&ssSMSSettings.lmtSendSMSWindowsListMT,&psswdWindowData->lmtListMTItem,psswdWindowData); - ListMTUnLock(&ssSMSSettings.lmtSendSMSWindowsListMT); - - lpwszContactDisplayName=GetContactNameW(hContact); - mir_sntprintf(wszTitle,SIZEOF(wszTitle),L"%s - %s",lpwszContactDisplayName,TranslateW(L"Send SMS")); - SendMessageW(psswdWindowData->hWnd,WM_SETTEXT,NULL,(LPARAM)wszTitle); - SEND_DLG_ITEM_MESSAGEW(psswdWindowData->hWnd,IDC_NAME,CB_ADDSTRING,0,(LPARAM)lpwszContactDisplayName); - SEND_DLG_ITEM_MESSAGE(psswdWindowData->hWnd,IDC_NAME,CB_SETCURSEL,0,0); - AddContactPhonesToCombo(psswdWindowData->hWnd,hContact); - SetFocus(GetDlgItem(psswdWindowData->hWnd,IDC_MESSAGE)); - hRet=psswdWindowData->hWnd; - }else{ - MEMFREE(psswdWindowData); - } - } -return(hRet); -} - -//This function close the SMS send window that given, and remove it from the list. -//The function gets the HWND of the window that should be removed and return void -void SendSMSWindowRemove(HWND hWndDlg) -{ - SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); - - if (psswdWindowData) - { - DB_SMS_SetDword(NULL,"LastProto",SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ACCOUNTS,CB_GETCURSEL,0,0)); - SendSMSWindowMultipleSet(hWndDlg,FALSE); - Utils_SaveWindowPosition(hWndDlg,(DB_SMS_GetByte(NULL,"SavePerContact",0)? psswdWindowData->hMyContact:NULL),PROTOCOL_NAMEA,"send"); - - ListMTLock(&ssSMSSettings.lmtSendSMSWindowsListMT); - ListMTItemDelete(&ssSMSSettings.lmtSendSMSWindowsListMT,&psswdWindowData->lmtListMTItem); - ListMTUnLock(&ssSMSSettings.lmtSendSMSWindowsListMT); - SendSMSWindowSMSContactsRemove(hWndDlg); - MEMFREE(psswdWindowData->pdbei); - MEMFREE(psswdWindowData); - } - DestroyWindow(hWndDlg); -} - -//This function return the contact HANDLE for the given to the SMS send window. -//The function gets the HWND of the window and return the HANDLE of the contact. -HANDLE SendSMSWindowHContactGet(HWND hWndDlg) -{ - HANDLE hRet=NULL; - SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); - - if (psswdWindowData) hRet=psswdWindowData->hMyContact; -return(hRet); -} - -//This function set the contact info of the person we send him the in the given to the SMS send window. -//The function gets the HWND of the window and the HANDLE of the contact and return void -void SendSMSWindowHContactSet(HWND hWndDlg,HANDLE hContact) -{ - SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); - if (psswdWindowData) psswdWindowData->hMyContact=hContact; -} - -//This function return the HWND of a SMS send window that have the same process as given. -//The function gets the HANDLE of a process and return the HWND of the SMS send window that has -//the same process -HWND SendSMSWindowHwndByHProcessGet(HANDLE hProcess) -{ - HWND hRet=NULL; - SEND_SMS_WINDOW_DATA *psswdWindowData; - LIST_MT_ITERATOR lmtiIterator; - - ListMTLock(&ssSMSSettings.lmtSendSMSWindowsListMT); - ListMTIteratorMoveFirst(&ssSMSSettings.lmtSendSMSWindowsListMT,&lmtiIterator); - do - {// цикл - if (ListMTIteratorGet(&lmtiIterator,NULL,(LPVOID*)&psswdWindowData)==NO_ERROR) - if (psswdWindowData->hProcess==hProcess) - { - hRet=psswdWindowData->hWnd; - break; - } - }while(ListMTIteratorMoveNext(&lmtiIterator)); - ListMTUnLock(&ssSMSSettings.lmtSendSMSWindowsListMT); -return(hRet); -} - -//This function set the process info of the send procedure we sent with the given SMS send window. -//The function gets the HWND of the window and the HANDLE of the process and return void -void SendSMSWindowHProcessSet(HWND hWndDlg,HANDLE hProcess) -{ - SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); - if (psswdWindowData) psswdWindowData->hProcess=hProcess; -} - -// -BOOL SendSMSWindowMultipleGet(HWND hWndDlg) -{ - BOOL bRet=FALSE; - SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); - - if (psswdWindowData) bRet=psswdWindowData->bMultiple; -return(bRet); -} - -// -void SendSMSWindowMultipleSet(HWND hWndDlg,BOOL bMultiple) -{ - SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); - - if (psswdWindowData) - if (psswdWindowData->bMultiple!=bMultiple) - { - RECT rcWin,rcList; - WINDOWPLACEMENT wp; - - psswdWindowData->bMultiple=bMultiple; - wp.length=sizeof(WINDOWPLACEMENT); - GetWindowRect(hWndDlg,&rcWin); - GetWindowRect(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),&rcList); - GetWindowPlacement(hWndDlg,&wp); - - if (bMultiple) - { - SendSMSWindowFillTreeView(hWndDlg); - - EnableWindow(GetDlgItem(hWndDlg,IDC_SAVENUMBER),FALSE); - SET_DLG_ITEM_TEXTW(hWndDlg,IDC_MULTIPLE,TranslateW(L"<< Single")); - if (wp.showCmd==SW_MAXIMIZE) SetWindowPos(hWndDlg,0,0,0,rcWin.right - rcWin.left - (rcList.right - rcList.left + 11) ,rcWin.bottom - rcWin.top,SWP_NOZORDER|SWP_NOMOVE); - SetWindowPos(hWndDlg,0,rcWin.left,rcWin.top,rcWin.right - rcWin.left + (rcList.right-rcList.left) + 11,rcWin.bottom - rcWin.top,SWP_NOZORDER|SWP_NOMOVE); - }else{ - if (psswdWindowData->hMyContact) AddContactPhonesToCombo(hWndDlg,psswdWindowData->hMyContact); - - EnableWindow(GetDlgItem(hWndDlg,IDC_SAVENUMBER),TRUE); - SET_DLG_ITEM_TEXTW(hWndDlg,IDC_MULTIPLE,TranslateW(L"Multiple >>")); - SetWindowPos(hWndDlg,0,rcWin.left,rcWin.top,rcWin.right-rcWin.left - (rcList.right-rcList.left) - 11,rcWin.bottom - rcWin.top,SWP_NOZORDER|SWP_NOMOVE); - if (wp.showCmd==SW_MAXIMIZE) SetWindowPos(hWndDlg,0,0,0,rcWin.right - rcWin.left + (rcList.right - rcList.left + 11) ,rcWin.bottom - rcWin.top,SWP_NOZORDER|SWP_NOMOVE); - } - } -} - -// -void SendSMSWindowNumberSet(HWND hWndDlg,LPWSTR lpwszPhone,SIZE_T dwPhoneSize) -{ - SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); - - if (psswdWindowData) - if (psswdWindowData->bMultiple) - { - psswdWindowData->hContact=psswdWindowData->hMyContact; - }else{ - psswdWindowData->hContact=HContactFromPhone(lpwszPhone,dwPhoneSize); - } -} - -// -void SendSMSWindowAsSentSet(HWND hWndDlg) -{ -// LVITEM lvi; -// char szPhone[MAX_PHONE_LEN]; -// lvi.mask=LVIF_TEXT|LVIF_IMAGE; -// lvi.iItem=GetSendSMSWindowSMSSend(hWndDlg) - 1; -// lvi.iSubItem=0; -// ListView_GetItemText(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),GetSendSMSWindowSMSSend(hWndDlg) - 1,0,szPhone,sizeof(szPhone)); -// lvi.pszText=szPhone; -// lvi.iImage=2; -// ListView_SetItem(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),&lvi); -// ListView_RedrawItems(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),0,ListView_GetItemCount(GetDlgItem(hWndDlg,IDC_NUMBERSLIST)) - 1); -} - -//This function set the databsae info of the sent message we sent with the SMS send window. -//The function gets the HWND of the window and the DBEI of the database information of the message -//and return void -void SendSMSWindowDbeiSet(HWND hWndDlg,DBEVENTINFO *pdbei) -{ - SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); - if (psswdWindowData) psswdWindowData->pdbei=pdbei; -} - -//This function get a HWND of SMS send window and add its database information into Miranda-IM database -//The function gets the HWND of the window and return void -//and return void -void SendSMSWindowDBAdd(HWND hWndDlg) -{ - SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); - - if (psswdWindowData) - { - psswdWindowData->pdbei->cbSize=sizeof(DBEVENTINFO); - psswdWindowData->pdbei->szModule=GetModuleName(psswdWindowData->hContact); - - CallService(MS_DB_EVENT_ADD,(WPARAM)psswdWindowData->hContact,(LPARAM)psswdWindowData->pdbei); - MEMFREE(psswdWindowData->pdbei); - } -} - -// -void SendSMSWindowHItemSendSet(HWND hWndDlg,HTREEITEM hItemSend) -{ - SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); - if (psswdWindowData) psswdWindowData->hItemSend=hItemSend; -} - -// -HTREEITEM SendSMSWindowHItemSendGet(HWND hWndDlg) -{ - HTREEITEM hRet=NULL; - SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); - - if (psswdWindowData) hRet=psswdWindowData->hItemSend; -return(hRet); -} - -// -HTREEITEM SendSMSWindowNextHItemGet(HWND hWndDlg,HTREEITEM hItem) -{ - int isFound=0; - HWND hWndTree=GetDlgItem(hWndDlg,IDC_NUMBERSLIST); - TVITEM tvi; - HTREEITEM hItemNext,hItemChild; - - if (hItem==TreeView_GetRoot(hWndTree)) isFound=1; - - for(hItemNext=TreeView_GetRoot(hWndTree);hItemNext;hItemNext=TreeView_GetNextSibling(hWndTree,hItemNext)) - { - if ((hItem==hItemNext) && (hItem!=TreeView_GetRoot(hWndTree))) - { - isFound=1; - continue; - } - - tvi.mask=(TVIF_IMAGE|TVIF_SELECTEDIMAGE); - tvi.hItem=hItemNext; - tvi.iImage=0; - tvi.iSelectedImage=0; - TreeView_GetItem(hWndTree,&tvi); - - if (tvi.iImage || tvi.iSelectedImage) - if (TreeView_GetChild(hWndTree,hItemNext)) - { - for (hItemChild=TreeView_GetChild(hWndTree,hItemNext);hItemChild;hItemChild=TreeView_GetNextSibling(hWndTree,hItemChild)) - { - if (hItem==hItemChild) - { - isFound=1; - continue; - } - - tvi.mask=(TVIF_IMAGE|TVIF_SELECTEDIMAGE); - tvi.hItem=hItemChild; - tvi.iImage=0; - tvi.iSelectedImage=0; - TreeView_GetItem(hWndTree,&tvi); - - if (tvi.iImage || tvi.iSelectedImage) - if (isFound) - { - return(hItemChild); - }else{ - continue; - } - } - }else{ - if (isFound) - { - return(hItemNext); - }else{ - continue; - } - } - } -return(NULL); -} - -//This function get the HANDLE of an user. if there is already a SMS send window for this contact -//it return its HWND else the function return NULL. -//The function gets the HANDLE of a contact and return HWND -HWND SendSMSWindowIsOtherInstanceHContact(HANDLE hContact) -{ - HWND hRet=NULL; - SEND_SMS_WINDOW_DATA *psswdWindowData; - LIST_MT_ITERATOR lmtiIterator; - - ListMTLock(&ssSMSSettings.lmtSendSMSWindowsListMT); - ListMTIteratorMoveFirst(&ssSMSSettings.lmtSendSMSWindowsListMT,&lmtiIterator); - do - {// цикл - if (ListMTIteratorGet(&lmtiIterator,NULL,(LPVOID*)&psswdWindowData)==NO_ERROR) - if (psswdWindowData->hMyContact==hContact) - { - hRet=psswdWindowData->hWnd; - break; - } - }while(ListMTIteratorMoveNext(&lmtiIterator)); - ListMTUnLock(&ssSMSSettings.lmtSendSMSWindowsListMT); -return(hRet); -} - - -// -void SendSMSWindowNext(HWND hWndDlg) -{ - WCHAR wszPhone[MAX_PHONE_LEN]; - LPWSTR lpwszMessage; - SIZE_T dwPhoneSize,dwMessageSize; - TVITEM tvi={0}; - - dwMessageSize=GET_DLG_ITEM_TEXT_LENGTH(hWndDlg,IDC_MESSAGE); - lpwszMessage=(LPWSTR)MEMALLOC(((dwMessageSize+4)*sizeof(WCHAR))); - if (lpwszMessage) - { - dwMessageSize=GET_DLG_ITEM_TEXTW(hWndDlg,IDC_MESSAGE,lpwszMessage,(dwMessageSize+2)); - - // if (SendSMSWindowNextHItemGet(hWndDlg,SendSMSWindowHItemSendGet(hWndDlg))==NULL) SendSMSWindowMultipleSet(hWndDlg,FALSE); - tvi.mask=TVIF_TEXT; - tvi.hItem=SendSMSWindowHItemSendGet(hWndDlg); - tvi.pszText=wszPhone; - tvi.cchTextMax=SIZEOF(wszPhone); - TreeView_GetItem(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),&tvi); - TreeView_SelectItem(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),tvi.hItem); - dwPhoneSize=lstrlenW(wszPhone); - SendSMSWindowNumberSet(hWndDlg,wszPhone,dwPhoneSize); - StartSmsSend(hWndDlg,SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ACCOUNTS,CB_GETCURSEL,0,0),wszPhone,dwPhoneSize,lpwszMessage,dwMessageSize); - SetTimer(hWndDlg,TIMERID_MSGSEND,TIMEOUT_MSGSEND,NULL); - MEMFREE(lpwszMessage); - } -} - - -////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////// -//This function gets a HANDLE of a contact and add it to a list. -void SendSMSWindowSMSContactAdd(HWND hWndDlg,HANDLE hContact) -{ - SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); - - if (psswdWindowData) - { - psswdWindowData->dwContactsListCount++; - if (psswdWindowData->phContactsList) - { - psswdWindowData->phContactsList=(HANDLE*)MEMREALLOC(psswdWindowData->phContactsList,(sizeof(HANDLE)*psswdWindowData->dwContactsListCount)); - }else{ - psswdWindowData->phContactsList=(HANDLE*)MEMALLOC((sizeof(HANDLE)*psswdWindowData->dwContactsListCount)); - } - *(psswdWindowData->phContactsList+psswdWindowData->dwContactsListCount-1)=hContact; - } -} - -//This function gets the number of the given contact in the combo list and return its contact. -HANDLE SendSMSWindowSMSContactGet(HWND hWndDlg,SIZE_T iNum) -{ - SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); - - if (psswdWindowData) - { - return(*((psswdWindowData->phContactsList)+iNum)); - } -return(NULL); -} - -void SendSMSWindowSMSContactsRemove(HWND hWndDlg) -{ - SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); - - if (psswdWindowData) - { - MEMFREE(psswdWindowData->phContactsList); - psswdWindowData->dwContactsListCount=0; - } -} - -void SendSMSWindowUpdateAccountList(HWND hWndDlg) -{ - if (ssSMSSettings.ppaSMSAccounts && ssSMSSettings.dwSMSAccountsCount) - { - SIZE_T i,dwCurSel; - - dwCurSel=SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ACCOUNTS,CB_GETCURSEL,0,0); - if (dwCurSel==-1) dwCurSel=DB_SMS_GetDword(NULL,"LastProto",0); - if (dwCurSel==-1) dwCurSel=0; - - SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ACCOUNTS,CB_RESETCONTENT,0,0); - for(i=0;iszModuleName); - } - SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ACCOUNTS,CB_SETCURSEL,(WPARAM)dwCurSel,0); - } -} - - -void SendSMSWindowsUpdateAllAccountLists() -{ - SEND_SMS_WINDOW_DATA *psswdWindowData; - LIST_MT_ITERATOR lmtiIterator; - - ListMTLock(&ssSMSSettings.lmtSendSMSWindowsListMT); - ListMTIteratorMoveFirst(&ssSMSSettings.lmtSendSMSWindowsListMT,&lmtiIterator); - do - {// цикл - if (ListMTIteratorGet(&lmtiIterator,NULL,(LPVOID*)&psswdWindowData)==NO_ERROR) - { - SendSMSWindowUpdateAccountList(psswdWindowData->hWnd); - } - }while(ListMTIteratorMoveNext(&lmtiIterator)); - ListMTUnLock(&ssSMSSettings.lmtSendSMSWindowsListMT); -} -////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////// - - - - -void AddContactPhonesToComboToListParam(HANDLE hContact,LPSTR lpszModule,LPSTR lpszValueName,HWND hWndList) -{ - char szBuff[MAX_PATH]; - WCHAR wszPhone[MAX_PHONE_LEN],wszPhoneRaw[MAX_PHONE_LEN]; - SIZE_T i,dwPhoneSize; - - if (DB_GetStaticStringW(hContact,lpszModule,lpszValueName,wszPhoneRaw,SIZEOF(wszPhoneRaw),&dwPhoneSize)) - { - wszPhone[0]='+'; - dwPhoneSize=CopyNumberW((wszPhone+1),wszPhoneRaw,dwPhoneSize); - if (IsPhoneW(wszPhone,dwPhoneSize)) - { - if (SendMessage(hWndList,CB_FINDSTRING,-1,(LPARAM)wszPhone)==CB_ERR) SendMessage(hWndList,CB_ADDSTRING,0,(LPARAM)wszPhone); - } - } - - for (i=0;TRUE;i++) - { - mir_snprintf(szBuff,sizeof(szBuff),"%s%ld",lpszValueName,i); - if (DB_GetStaticStringW(hContact,lpszModule,szBuff,wszPhoneRaw,SIZEOF(wszPhoneRaw),&dwPhoneSize)) - { - wszPhone[0]='+'; - dwPhoneSize=CopyNumberW((wszPhone+1),wszPhoneRaw,dwPhoneSize); - if (IsPhoneW(wszPhone,dwPhoneSize)) - { - if (SendMessage(hWndList,CB_FINDSTRING,-1,(LPARAM)wszPhone)==CB_ERR) SendMessage(hWndList,CB_ADDSTRING,0,(LPARAM)wszPhone); - } - }else{ - if (i>PHONES_MIN_COUNT) break; - } - } -} - - -void AddContactPhonesToCombo(HWND hWnd,HANDLE hContact) -{ - HWND hWndList; - LPSTR lpszProto; - - hWndList=GetDlgItem(hWnd,IDC_ADDRESS); - SEND_DLG_ITEM_MESSAGE(hWnd,IDC_ADDRESS,CB_RESETCONTENT,0,0); - - lpszProto=(LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0); - if (lpszProto) - { - AddContactPhonesToComboToListParam(hContact,lpszProto,"Phone",hWndList); - AddContactPhonesToComboToListParam(hContact,lpszProto,"Cellular",hWndList); - AddContactPhonesToComboToListParam(hContact,lpszProto,"Fax",hWndList); - } - AddContactPhonesToComboToListParam(hContact,"UserInfo","MyPhone",hWndList); - AddContactPhonesToComboToListParam(hContact,"UserInfo","Phone",hWndList); - AddContactPhonesToComboToListParam(hContact,"UserInfo","Cellular",hWndList); - AddContactPhonesToComboToListParam(hContact,"UserInfo","Fax",hWndList); - - SEND_DLG_ITEM_MESSAGE(hWnd,IDC_ADDRESS,CB_SETCURSEL,0,0); -} - - - -void AddContactPhonesToTreeViewParam(HANDLE hContact,LPSTR lpszModule,LPSTR lpszValueName,HWND hWndList,HTREEITEM *phParent) -{ - char szBuff[MAX_PATH]; - WCHAR wszPhone[MAX_PHONE_LEN],wszPhoneRaw[MAX_PHONE_LEN]; - SIZE_T i,dwPhoneSize; - TVINSERTSTRUCT tvis={0}; - - if (phParent) tvis.hParent=(*phParent); - tvis.item.mask=(TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE); - tvis.hInsertAfter=TVI_SORT; - tvis.item.iImage=tvis.item.iSelectedImage=0; - - if (DB_GetStaticStringW(hContact,lpszModule,lpszValueName,wszPhoneRaw,SIZEOF(wszPhoneRaw),&dwPhoneSize)) - { - wszPhone[0]='+'; - dwPhoneSize=CopyNumberW((wszPhone+1),wszPhoneRaw,dwPhoneSize); - if (IsPhoneW(wszPhone,dwPhoneSize)) - { - if (tvis.hParent==NULL) - { - tvis.item.pszText=GetContactNameW(hContact); - tvis.hParent=TreeView_InsertItem(hWndList,&tvis); - } - tvis.item.pszText=wszPhone; - TreeView_InsertItem(hWndList,&tvis); - } - } - - for (i=0;TRUE;i++) - { - mir_snprintf(szBuff,sizeof(szBuff),"%s%ld",lpszValueName,i); - if (DB_GetStaticStringW(hContact,lpszModule,szBuff,wszPhoneRaw,SIZEOF(wszPhoneRaw),&dwPhoneSize)) - { - wszPhone[0]='+'; - dwPhoneSize=CopyNumberW((wszPhone+1),wszPhoneRaw,dwPhoneSize); - if (IsPhoneW(wszPhone,dwPhoneSize)) - { - if (tvis.hParent==NULL) - { - tvis.item.pszText=GetContactNameW(hContact); - tvis.hParent=TreeView_InsertItem(hWndList,&tvis); - } - tvis.item.pszText=wszPhone; - TreeView_InsertItem(hWndList,&tvis); - } - }else{ - if (i>PHONES_MIN_COUNT) break; - } - } - if (phParent) (*phParent)=tvis.hParent; -} - - -void SendSMSWindowFillTreeView(HWND hWnd) -{ - HWND hWndTreeView; - LPSTR lpszProto; - HTREEITEM hParent; - - hWndTreeView=GetDlgItem(hWnd,IDC_NUMBERSLIST); - TreeView_DeleteAllItems(hWndTreeView); - - for(HANDLE hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);hContact!=NULL;hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)) - { - hParent=NULL; - lpszProto=(LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0); - if (lpszProto) - { - AddContactPhonesToTreeViewParam(hContact,lpszProto,"Phone",hWndTreeView,&hParent); - AddContactPhonesToTreeViewParam(hContact,lpszProto,"Cellular",hWndTreeView,&hParent); - AddContactPhonesToTreeViewParam(hContact,lpszProto,"Fax",hWndTreeView,&hParent); - } - AddContactPhonesToTreeViewParam(hContact,"UserInfo","MyPhone",hWndTreeView,&hParent); - AddContactPhonesToTreeViewParam(hContact,"UserInfo","Phone",hWndTreeView,&hParent); - AddContactPhonesToTreeViewParam(hContact,"UserInfo","Cellular",hWndTreeView,&hParent); - AddContactPhonesToTreeViewParam(hContact,"UserInfo","Fax",hWndTreeView,&hParent); - } -} - - -SIZE_T GetSMSMessageLenMax(HWND hWndDlg) -{ - LPWSTR lpwszMessage; - SIZE_T dwMessageSize,dwLenght=160; - - dwMessageSize=GET_DLG_ITEM_TEXT_LENGTH(hWndDlg,IDC_MESSAGE); - lpwszMessage=(LPWSTR)MEMALLOC(((dwMessageSize+4)*sizeof(WCHAR))); - if (lpwszMessage) - { - dwMessageSize=GET_DLG_ITEM_TEXTW(hWndDlg,IDC_MESSAGE,lpwszMessage,(dwMessageSize+2)); - if (dwMessageSize!=WideCharToMultiByte(CP_UTF8,0,lpwszMessage,dwMessageSize,NULL,0,NULL,NULL)) dwLenght=70; - MEMFREE(lpwszMessage); - } -return(dwLenght); -} - - - - - - - - - - diff --git a/!NotAdopted/SMS/senddlg.h b/!NotAdopted/SMS/senddlg.h deleted file mode 100644 index 225cf80f28..0000000000 --- a/!NotAdopted/SMS/senddlg.h +++ /dev/null @@ -1,40 +0,0 @@ -#if !defined(AFX_SMS_SENDDLG_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_) -#define AFX_SMS_SENDDLG_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_ - - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - - -DWORD SendSMSWindowInitialize (); -void SendSMSWindowDestroy (); - -//Decleration of SMS send window list -BOOL CALLBACK SMSAcceptedDlgProc (HWND hWndDlg,UINT msg,WPARAM wParam,LPARAM lParam); -BOOL CALLBACK SMSTimedOutDlgProc (HWND hWndDlg,UINT msg,WPARAM wParam,LPARAM lParam); -HWND SendSMSWindowAdd (HANDLE hContact); -void SendSMSWindowRemove (HWND hWndDlg); -HANDLE SendSMSWindowHContactGet (HWND hWndDlg); -void SendSMSWindowHContactSet (HWND hWndDlg,HANDLE hContact); -HWND SendSMSWindowHwndByHProcessGet (HANDLE hProcess); -void SendSMSWindowHProcessSet (HWND hWndDlg,HANDLE hProcess); -BOOL SendSMSWindowMultipleGet (HWND hWndDlg); -void SendSMSWindowMultipleSet (HWND hWndDlg,BOOL bMultiple); -void SendSMSWindowNumberSet (HWND hWndDlg,LPWSTR lpwszPhone,SIZE_T dwPhoneSize); -void SendSMSWindowAsSentSet (HWND hWndDlg); -void SendSMSWindowDbeiSet (HWND hWndDlg,DBEVENTINFO *pdbei); -void SendSMSWindowDBAdd (HWND hWndDlg); -void SendSMSWindowHItemSendSet (HWND hWndDlg,HTREEITEM hItemSend); -HTREEITEM SendSMSWindowHItemSendGet (HWND hWndDlg); -HTREEITEM SendSMSWindowNextHItemGet (HWND hWndDlg,HTREEITEM hItem); -HWND SendSMSWindowIsOtherInstanceHContact(HANDLE hContact); -void SendSMSWindowNext (HWND hWndDlg); - -void SendSMSWindowSMSContactAdd (HWND hWndDlg,HANDLE hContact); -HANDLE SendSMSWindowSMSContactGet (HWND hWndDlg,SIZE_T iNum); -void SendSMSWindowSMSContactsRemove (HWND hWndDlg); -void SendSMSWindowUpdateAccountList (HWND hWndDlg); -void SendSMSWindowsUpdateAllAccountLists (); - -#endif // !defined(AFX_SMS_SENDDLG_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_) diff --git a/!NotAdopted/SMS/sms.dsp b/!NotAdopted/SMS/sms.dsp deleted file mode 100644 index 75d75ee5d8..0000000000 --- a/!NotAdopted/SMS/sms.dsp +++ /dev/null @@ -1,231 +0,0 @@ -# Microsoft Developer Studio Project File - Name="sms" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=sms - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "sms.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "sms.mak" CFG="sms - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "sms - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "sms - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "sms - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SMS_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SMS_EXPORTS" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x809 /d "NDEBUG" -# ADD RSC /l 0x809 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 LIBCTINY.LIB kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /base:"0x25000000" /dll /map /machine:I386 /nodefaultlib - -!ELSEIF "$(CFG)" == "sms - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SMS_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SMS_EXPORTS" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x809 /d "_DEBUG" -# ADD RSC /l 0x809 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 LIBCTINY.LIB kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /nodefaultlib /out:"../../Debug/plugins/sms.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "sms - Win32 Release" -# Name "sms - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Group "minicrt" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=.\mincrt\MEMSET.C -# End Source File -# Begin Source File - -SOURCE=.\mincrt\STRCHR.C -# End Source File -# Begin Source File - -SOURCE=.\mincrt\STRDUP.C -# End Source File -# Begin Source File - -SOURCE=.\mincrt\strncmp.c -# End Source File -# Begin Source File - -SOURCE=.\mincrt\STRSPN.C -# End Source File -# Begin Source File - -SOURCE=.\mincrt\time.c -# End Source File -# Begin Source File - -SOURCE=.\mincrt\wsnprintf.c -# End Source File -# End Group -# Begin Source File - -SOURCE=.\main.c -# End Source File -# Begin Source File - -SOURCE=.\options.c -# End Source File -# Begin Source File - -SOURCE=.\receive.c -# End Source File -# Begin Source File - -SOURCE=.\recvdlg.c -# End Source File -# Begin Source File - -SOURCE=.\send.c -# End Source File -# Begin Source File - -SOURCE=.\senddlg.c -# End Source File -# Begin Source File - -SOURCE=.\utf8.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\AggressiveOptimize.h -# End Source File -# Begin Source File - -SOURCE=.\m_autoreplacer.h -# End Source File -# Begin Source File - -SOURCE=.\main.h -# End Source File -# Begin Source File - -SOURCE=.\receive.h -# End Source File -# Begin Source File - -SOURCE=.\resource.h -# End Source File -# Begin Source File - -SOURCE=.\send.h -# End Source File -# Begin Source File - -SOURCE=.\utf8.h -# End Source File -# Begin Source File - -SOURCE=.\mincrt\wsnprintf.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# Begin Source File - -SOURCE=.\halftick.ico -# End Source File -# Begin Source File - -SOURCE=.\history.ico -# End Source File -# Begin Source File - -SOURCE=.\res\history.ico -# End Source File -# Begin Source File - -SOURCE=.\notick.ico -# End Source File -# Begin Source File - -SOURCE=.\resource.rc -# End Source File -# Begin Source File - -SOURCE=.\SMSMSG.ico -# End Source File -# Begin Source File - -SOURCE=.\SMSNOTSENT.ico -# End Source File -# Begin Source File - -SOURCE=.\SMSSENT.ico -# End Source File -# Begin Source File - -SOURCE=.\tick.ico -# End Source File -# End Group -# End Target -# End Project diff --git a/!NotAdopted/SMS/sms.dsw b/!NotAdopted/SMS/sms.dsw deleted file mode 100644 index 2bc1715ec7..0000000000 --- a/!NotAdopted/SMS/sms.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "sms"=.\sms.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/!NotAdopted/SMS/sms.opt b/!NotAdopted/SMS/sms.opt deleted file mode 100644 index d32d04fb8b..0000000000 Binary files a/!NotAdopted/SMS/sms.opt and /dev/null differ diff --git a/!NotAdopted/SMS/sms.vcproj b/!NotAdopted/SMS/sms.vcproj deleted file mode 100644 index 2b5e61d508..0000000000 --- a/!NotAdopted/SMS/sms.vcproj +++ /dev/null @@ -1,388 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/!NotAdopted/Skype/Skript1.aps b/!NotAdopted/Skype/Skript1.aps deleted file mode 100644 index d99f14a71e..0000000000 Binary files a/!NotAdopted/Skype/Skript1.aps and /dev/null differ diff --git a/!NotAdopted/Skype/Skript1.rc b/!NotAdopted/Skype/Skript1.rc deleted file mode 100644 index b2052187b7..0000000000 --- a/!NotAdopted/Skype/Skript1.rc +++ /dev/null @@ -1,484 +0,0 @@ -//Microsoft Developer Studio generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Neutral resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) -#ifdef _WIN32 -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_SETAVATAR DIALOGEX 0, 0, 222, 131 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - PUSHBUTTON "Set",IDC_SETAVATAR,10,108,45,13,WS_GROUP - PUSHBUTTON "Delete",IDC_DELETEAVATAR,57,108,45,13 - CONTROL "",IDC_AVATAR,"Static",SS_BITMAP | SS_CENTERIMAGE | - SS_SUNKEN | WS_GROUP,10,10,96,93 -END - -IDD_OPT_DEFAULT DIALOGEX 0, 0, 310, 223 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "Start Skype with Miranda IM if not running using the following command line options:", - IDC_STARTSKYPE,"Button",BS_AUTOCHECKBOX | WS_GROUP | - WS_TABSTOP,10,4,290,10 - CONTROL "/NOSPLASH - Don't show splash screen on startup", - IDC_NOSPLASH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,17, - 264,12 - CONTROL "/MINIMIZED - Start Skype minimized",IDC_MINIMIZED, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,28,264,12 - CONTROL "/NOTRAY - Skype tray icon becomes grey and is therefore ""invisible""", - IDC_NOTRAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,40, - 264,12 - CONTROL "/REMOVEABLE - For running portable skype", - IDC_REMOVEABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,36, - 51,264,12 - CONTROL "/SECONDARY - This is the second instance",IDC_SECONDARY, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,62,264,12 - CONTROL "/DATAPATH - Specify Skype data folder*",IDC_DATAPATHO, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,74,264,12 - EDITTEXT IDC_DATAPATH,47,88,236,12,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_BROWSEDP,285,87,16,15 - CONTROL "Use custom Skype executable*",IDC_CUSTOMCOMMAND,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,36,103,264,10 - EDITTEXT IDC_COMMANDLINE,47,116,236,12,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_BROWSECMDL,285,115,16,15 - CTEXT "* Relative path root is Miranda IM folder", - IDC_STATIC_PATHINFO,10,136,290,8,NOT WS_GROUP - CONTROL "Shutdown Skype when you close Miranda IM",IDC_SHUTDOWN, - "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,151, - 290,10 - CONTROL "Unload Skype when you change to Offline status", - IDC_UNLOADOFFLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 10,164,290,11 - LTEXT "Try at least",IDC_STATIC,10,185,39,8 - EDITTEXT IDC_CONNATTEMPTS,52,183,21,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "times to connect to Skype API before giving up", - IDC_STATIC,78,185,224,8,NOT WS_GROUP - LTEXT "User name:",IDC_STATIC,10,206,38,8 - EDITTEXT IDC_USERNAME,52,204,79,12,ES_AUTOHSCROLL - LTEXT "Password:",IDC_STATIC,148,206,34,8 - EDITTEXT IDC_PASSWORD,186,204,79,12,ES_PASSWORD | ES_AUTOHSCROLL -END - -IDD_DIAL DIALOGEX 0, 0, 198, 46 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | - WS_SYSMENU -CAPTION "Dial" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Number:",IDC_STATIC,7,8,30,11 - COMBOBOX IDC_NUMBER,41,6,149,13,CBS_DROPDOWN | WS_VSCROLL | - WS_TABSTOP - DEFPUSHBUTTON "Dial",IDDIAL,88,25,50,14,WS_GROUP - PUSHBUTTON "Cancel",IDCANCEL,141,25,50,14 -END - -IDD_CALLSTAT DIALOGEX 0, 0, 220, 67 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "%s is calling" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "Join conference with %s",IDC_JOIN,"Button", - BS_AUTORADIOBUTTON | WS_GROUP,7,7,206,10 - CONTROL "Answer call; set call to %s on hold",IDC_HOLD,"Button", - BS_AUTORADIOBUTTON,7,19,206,10 - CONTROL "Hang up",IDC_HANGUP,"Button",BS_AUTORADIOBUTTON,7,31, - 206,10 - DEFPUSHBUTTON "OK",IDOK,163,46,50,14,WS_GROUP -END - -IDD_INPUTBOX DIALOGEX 0, 0, 221, 46 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Dialog" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - EDITTEXT IDC_TEXT,7,7,207,13,ES_AUTOHSCROLL | WS_GROUP - DEFPUSHBUTTON "OK",IDOK,112,25,50,14,WS_GROUP - PUSHBUTTON "Cancel",IDCANCEL,165,25,50,14 -END - -IDD_OPTIONS DIALOGEX 0, 0, 313, 249 -STYLE DS_FIXEDSYS | DS_CONTROL | DS_CENTER | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "Tab1",IDC_OPTIONSTAB,"SysTabControl32",0x0,0,-1,313,250 -END - -IDD_OPT_PROXY DIALOGEX 0, 0, 310, 223 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "Use Skype proxy connection over network instead of local Skype API", - IDC_USES2S,"Button",BS_AUTOCHECKBOX | WS_GROUP | - WS_TABSTOP,10,4,290,9 - LTEXT "Host:",IDC_STATIC_HOST,20,21,18,10 - EDITTEXT IDC_HOST,41,19,133,12,ES_AUTOHSCROLL - LTEXT "Port:",IDC_STATIC_PORT,180,21,16,10,0,WS_EX_RIGHT - EDITTEXT IDC_PORT,200,19,29,12,ES_AUTOHSCROLL | ES_NUMBER - CTEXT "* You must restart Miranda IM in order to let the settings take effect", - IDC_STATIC_RESTART,10,54,290,8,NOT WS_GROUP - CONTROL "This Skype proxy requires password authentication:", - IDC_REQPASS,"Button",BS_AUTOCHECKBOX | WS_GROUP | - WS_TABSTOP,20,38,176,9 - EDITTEXT IDC_PASSWORD,200,36,82,12,ES_PASSWORD | ES_AUTOHSCROLL -END - -IDD_SETDETAILS DIALOGEX 0, 0, 216, 151 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Name:",IDC_STATIC,7,6,61,9 - EDITTEXT IDC_FULLNAME,73,4,141,12,ES_AUTOHSCROLL - LTEXT "Birthday:",IDC_STATIC,7,20,61,9 - CONTROL "DateTimePicker1",IDC_BIRTHDAY,"SysDateTimePick32", - DTS_RIGHTALIGN | DTS_APPCANPARSE | WS_TABSTOP,73,18,62, - 12 - LTEXT "Sex:",IDC_STATIC,7,34,61,9 - COMBOBOX IDC_SEX,73,32,141,12,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "City:",IDC_STATIC,7,48,61,9 - EDITTEXT IDC_CITY,73,46,141,12,ES_AUTOHSCROLL - LTEXT "Country:",IDC_STATIC,7,62,61,9 - EDITTEXT IDC_COUNTRY,73,60,141,12,ES_AUTOHSCROLL - LTEXT "Province:",IDC_STATIC,7,76,61,9 - EDITTEXT IDC_PROVINCE,73,74,141,12,ES_AUTOHSCROLL - LTEXT "Home phone:",IDC_STATIC,7,90,61,9 - EDITTEXT IDC_HOMEPHONE,73,88,141,12,ES_AUTOHSCROLL - LTEXT "Office phone:",IDC_STATIC,7,104,61,9 - EDITTEXT IDC_OFFICEPHONE,73,102,141,12,ES_AUTOHSCROLL - LTEXT "Homepage:",IDC_STATIC,7,118,61,9 - EDITTEXT IDC_HOMEPAGE,73,116,141,12,ES_AUTOHSCROLL - PUSHBUTTON "Save",IDC_SAVEDETAILS,170,134,45,14,WS_GROUP -END - -IDD_OPT_ADVANCED DIALOGEX 0, 0, 310, 223 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "Enable Skype menu options (currently: Find/Add user)", - IDC_ENABLEMENU,"Button",BS_AUTOCHECKBOX | WS_GROUP | - WS_TABSTOP,10,4,290,9 - CONTROL "Use popup plugin for displaying messages ",IDC_USEPOPUP, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,19,290,9 - CONTROL "Suppress all error messages (not recommended, but if it annoys you... ;)", - IDC_NOERRORS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,34, - 290,9 - CONTROL "Use group chat interface for conversations (requires group chat module)", - IDC_GROUPCHAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10, - 49,290,9 - CONTROL "Mark group chat message as read to avoid notification", - IDC_GROUPCHATREAD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 10,64,290,9 - CONTROL "Keep requested online status on startup under every circumstance", - IDC_KEEPSTATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10, - 79,290,9 - CONTROL "Use time zone patch",IDC_TIMEZONE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,10,94,290,9 - CONTROL "Ignore time zones",IDC_IGNTZ,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,10,109,290,9 - CONTROL "Show default skype avatar for contacts", - IDC_SHOWDEFAULTAVATAR,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,10,124,290,9 - CONTROL "Suppress call summary chat message", - IDC_SUPPRESSCALLSUMMARYMESSAGE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,10,139,290,9 - CONTROL "Disable support for N/A and SkypeMe status (for Skype 4+)", - IDC_NOSKYPE3STATS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 10,154,290,9 - CONTROL "Show full name in contact list instead of nickname", - IDC_SHOWFULLNAME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 10,169,290,9 - LTEXT "SkypeOut contacts are in status:",IDC_STATIC,10,186,108, - 8 - COMBOBOX IDC_SKYPEOUTSTAT,120,184,79,54,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Cleanup Nicknames",IDC_CLEANUP,9,201,80,14,BS_MULTILINE | - WS_GROUP -END - -IDD_OPT_POPUP DIALOGEX 0, 0, 310, 228 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "Skype Popups",IDC_STATIC,0,1,309,227 - GROUPBOX "Incoming Calls",IDC_STATIC,6,16,297,62,WS_GROUP - CONTROL "Show incoming calls",IDC_POPUPINCOMING,"Button", - BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,28,278,8 - EDITTEXT IDC_POPUPTIME,16,41,20,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "seconds",IDC_STATIC,41,43,92,8,NOT WS_GROUP - CONTROL "",IDC_POPUPBACKCOLOR,"ColourPicker",WS_GROUP | - WS_TABSTOP,142,40,39,12 - LTEXT "Background",IDC_STATIC_POPUPBACKCOLOR,186,42,50,8, - SS_CENTERIMAGE | NOT WS_GROUP - CONTROL "Use Windows colors",IDC_USEWINCOLORS,"Button", - BS_AUTOCHECKBOX | BS_NOTIFY | BS_FLAT | WS_TABSTOP,16,58, - 121,8 - CONTROL "",IDC_POPUPTEXTCOLOR,"ColourPicker",WS_TABSTOP,142,55, - 39,12 - LTEXT "Text",IDC_STATIC_POPUPTEXTCOLOR,186,56,50,8, - SS_CENTERIMAGE | NOT WS_GROUP - PUSHBUTTON "Preview",IDC_PREVIEW,247,58,50,14,WS_GROUP - GROUPBOX "Error Messages",IDC_STATIC,6,81,297,62,WS_GROUP - CONTROL "Display error messages",IDC_POPUPERROR,"Button", - BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,94,278,8 - EDITTEXT IDC_POPUPTIMEERR,16,107,20,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "seconds",IDC_STATIC,41,109,92,8,NOT WS_GROUP - CONTROL "",IDC_POPUPBACKCOLORERR,"ColourPicker",WS_GROUP | - WS_TABSTOP,142,106,39,12 - LTEXT "Background",IDC_STATIC_POPUPBACKCOLORERR,186,108,50,8, - SS_CENTERIMAGE | NOT WS_GROUP - CONTROL "Use Windows colors",IDC_USEWINCOLORSERR,"Button", - BS_AUTOCHECKBOX | BS_NOTIFY | BS_FLAT | WS_TABSTOP,16, - 124,121,8 - CONTROL "",IDC_POPUPTEXTCOLORERR,"ColourPicker",WS_TABSTOP,142, - 121,39,12 - LTEXT "Text",IDC_STATIC_POPUPTEXTCOLORERR,186,123,50,8, - SS_CENTERIMAGE | NOT WS_GROUP - PUSHBUTTON "Preview",IDC_PREVIEWERR,247,124,50,14,WS_GROUP -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO MOVEABLE PURE -BEGIN - IDD_SETAVATAR, DIALOG - BEGIN - LEFTMARGIN, 10 - RIGHTMARGIN, 212 - TOPMARGIN, 10 - BOTTOMMARGIN, 121 - END - - IDD_OPT_DEFAULT, DIALOG - BEGIN - LEFTMARGIN, 1 - VERTGUIDE, 10 - VERTGUIDE, 300 - TOPMARGIN, 4 - END - - IDD_DIAL, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 190 - TOPMARGIN, 6 - BOTTOMMARGIN, 39 - END - - IDD_CALLSTAT, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 213 - TOPMARGIN, 7 - BOTTOMMARGIN, 60 - END - - IDD_INPUTBOX, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 214 - TOPMARGIN, 7 - BOTTOMMARGIN, 39 - END - - IDD_OPTIONS, DIALOG - BEGIN - RIGHTMARGIN, 311 - BOTTOMMARGIN, 243 - END - - IDD_OPT_PROXY, DIALOG - BEGIN - LEFTMARGIN, 10 - RIGHTMARGIN, 300 - TOPMARGIN, 4 - BOTTOMMARGIN, 221 - END - - IDD_SETDETAILS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 214 - TOPMARGIN, 4 - BOTTOMMARGIN, 148 - END - - IDD_OPT_ADVANCED, DIALOG - BEGIN - LEFTMARGIN, 10 - RIGHTMARGIN, 300 - TOPMARGIN, 4 - BOTTOMMARGIN, 221 - HORZGUIDE, 4 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_SKYPE ICON DISCARDABLE "res\\skype.ico" -IDI_INVITE ICON DISCARDABLE "res\\Invite.ico" -IDI_ADD ICON DISCARDABLE "res\\add.ico" -IDI_IMPORT ICON DISCARDABLE "res\\import.ico" -IDI_ERRORS ICON DISCARDABLE "res\\error.ico" -IDI_MESSAGE ICON DISCARDABLE "res\\message.ico" -IDI_CALL ICON DISCARDABLE "res\\call.ico" -IDI_CALLSKYPEOUT ICON DISCARDABLE "res\\skypeout.ico" -IDI_HOLD ICON DISCARDABLE "res\\hold.ico" -IDI_RESUME ICON DISCARDABLE "res\\resume.ico" -IDI_HANGUP ICON DISCARDABLE "res\\hang_up.ico" -IDI_ONLINE ICON DISCARDABLE "res\\online.ico" -IDI_CHAT ICON DISCARDABLE "res\\chat.ico" -IDI_AWAY ICON DISCARDABLE "res\\away.ico" -IDI_NA ICON DISCARDABLE "res\\na.ico" -IDI_OCCUPIED ICON DISCARDABLE "res\\occupied.ico" -IDI_DND ICON DISCARDABLE "res\\dnd.ico" -IDI_INVISIBLE ICON DISCARDABLE "res\\invisible.ico" -IDI_OFFLINE ICON DISCARDABLE "res\\offline.ico" -IDI_PHONE ICON DISCARDABLE "res\\phone.ico" - -#ifndef _MAC -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,0,53 - PRODUCTVERSION 0,0,0,53 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000004b0" - BEGIN - VALUE "Comments", "\0" - VALUE "CompanyName", "Miranda IM community\0" - VALUE "FileDescription", "Skype\0" - VALUE "FileVersion", "0, 0, 0, 53\0" - VALUE "InternalName", "Skype\0" - VALUE "LegalCopyright", "Copyright © 2007-2011 leecher - tweety - jls17\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "Skype.dll\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "Skype Protocol for Miranda IM\0" - VALUE "ProductVersion", "0, 0, 0, 53\0" - VALUE "SpecialBuild", "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0, 1200 - END -END - -#endif // !_MAC - - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap -// - -IDB_CALL BITMAP MOVEABLE PURE "res\\call.bmp" -#endif // Neutral resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// Deutsch (Цsterreich) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEA) -#ifdef _WIN32 -LANGUAGE LANG_GERMAN, SUBLANG_GERMAN_AUSTRIAN -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE MOVEABLE PURE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE MOVEABLE PURE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE MOVEABLE PURE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // Deutsch (Цsterreich) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/!NotAdopted/Skype/Skype_protocol.dsp b/!NotAdopted/Skype/Skype_protocol.dsp deleted file mode 100644 index 3c9191838e..0000000000 --- a/!NotAdopted/Skype/Skype_protocol.dsp +++ /dev/null @@ -1,394 +0,0 @@ -# Microsoft Developer Studio Project File - Name="Skype_protocol" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** NICHT BEARBEITEN ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=Skype_protocol - Win32 Debug UNICODE -!MESSAGE Dies ist kein gьltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE -!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fьhren Sie den Befehl -!MESSAGE -!MESSAGE NMAKE /f "Skype_protocol.mak". -!MESSAGE -!MESSAGE Sie kцnnen beim Ausfьhren von NMAKE eine Konfiguration angeben -!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: -!MESSAGE -!MESSAGE NMAKE /f "Skype_protocol.mak" CFG="Skype_protocol - Win32 Debug UNICODE" -!MESSAGE -!MESSAGE Fьr die Konfiguration stehen zur Auswahl: -!MESSAGE -!MESSAGE "Skype_protocol - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library") -!MESSAGE "Skype_protocol - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library") -!MESSAGE "Skype_protocol - Win32 Debug UNICODE" (basierend auf "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=xicl6.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "Skype_protocol - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /YX /FD /c -# SUBTRACT CPP /Fr -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0xc07 /d "NDEBUG" -# ADD RSC /l 0xc07 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib comctl32.lib Rpcrt4.lib /nologo /dll /machine:I386 /out:"../../bin/release/plugins/skype.dll" - -!ELSEIF "$(CFG)" == "Skype_protocol - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /YX /FD /GZ /c -# SUBTRACT CPP /Fr -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0xc07 /d "_DEBUG" -# ADD RSC /l 0xc07 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib comctl32.lib Rpcrt4.lib /nologo /dll /debug /machine:I386 /out:"../../../miranda-testaim/Miranda/plugins/Skype.dll" /pdbtype:sept -# SUBTRACT LINK32 /map - -!ELSEIF "$(CFG)" == "Skype_protocol - Win32 Debug UNICODE" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Skype_protocol___Win32_Debug_UNICODE" -# PROP BASE Intermediate_Dir "Skype_protocol___Win32_Debug_UNICODE" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Skype_protocol___Win32_Debug_UNICODE" -# PROP Intermediate_Dir "Skype_protocol___Win32_Debug_UNICODE" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /YX /FD /GZ /c -# SUBTRACT BASE CPP /Fr -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /D "UNICODE" /D "_UNICODE" /FR /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0xc07 /d "_DEBUG" -# ADD RSC /l 0xc07 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib comctl32.lib Rpcrt4.lib /nologo /dll /debug /machine:I386 /out:"../../bin/debug/plugins/Skype.dll" /pdbtype:sept -# SUBTRACT BASE LINK32 /map -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib comctl32.lib Rpcrt4.lib /nologo /dll /debug /machine:I386 /out:"../../bin/debug Unicode/plugins/Skype.dll" /pdbtype:sept -# SUBTRACT LINK32 /map - -!ENDIF - -# Begin Target - -# Name "Skype_protocol - Win32 Release" -# Name "Skype_protocol - Win32 Debug" -# Name "Skype_protocol - Win32 Debug UNICODE" -# Begin Group "Quellcodedateien" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\alogon.c -# End Source File -# Begin Source File - -SOURCE=.\contacts.c -# End Source File -# Begin Source File - -SOURCE=.\debug.c -# End Source File -# Begin Source File - -SOURCE=.\gchat.c -# End Source File -# Begin Source File - -SOURCE=.\memlist.c -# End Source File -# Begin Source File - -SOURCE=.\msglist.c -# End Source File -# Begin Source File - -SOURCE=.\msgq.c -# End Source File -# Begin Source File - -SOURCE=.\pthread.c -# End Source File -# Begin Source File - -SOURCE=.\skype.c -# End Source File -# Begin Source File - -SOURCE=.\skypeapi.c -# End Source File -# Begin Source File - -SOURCE=.\skypeopt.c -# End Source File -# Begin Source File - -SOURCE=.\skypeprofile.c -# End Source File -# Begin Source File - -SOURCE=.\skypesvc.c -# End Source File -# Begin Source File - -SOURCE=.\utf8.c -# End Source File -# Begin Source File - -SOURCE=.\util.c -# End Source File -# Begin Source File - -SOURCE=.\voiceservice.c -# End Source File -# End Group -# Begin Group "Header-Dateien" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\alogon.h -# End Source File -# Begin Source File - -SOURCE=.\contacts.h -# End Source File -# Begin Source File - -SOURCE=.\debug.h -# End Source File -# Begin Source File - -SOURCE=.\gchat.h -# End Source File -# Begin Source File - -SOURCE=.\m_popup.h -# End Source File -# Begin Source File - -SOURCE=.\m_toptoolbar.h -# End Source File -# Begin Source File - -SOURCE=.\memlist.h -# End Source File -# Begin Source File - -SOURCE=.\msglist.h -# End Source File -# Begin Source File - -SOURCE=.\msgq.h -# End Source File -# Begin Source File - -SOURCE=.\pthread.h -# End Source File -# Begin Source File - -SOURCE=.\skype.h -# End Source File -# Begin Source File - -SOURCE=.\skypeapi.h -# End Source File -# Begin Source File - -SOURCE=.\skypeopt.h -# End Source File -# Begin Source File - -SOURCE=.\skypeprofile.h -# End Source File -# Begin Source File - -SOURCE=.\skypesvc.h -# End Source File -# Begin Source File - -SOURCE=.\utf8.h -# End Source File -# Begin Source File - -SOURCE=.\util.h -# End Source File -# Begin Source File - -SOURCE=.\voiceservice.h -# End Source File -# End Group -# Begin Group "Ressourcendateien" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# Begin Source File - -SOURCE=.\res\add.ico -# End Source File -# Begin Source File - -SOURCE=.\res\away.ico -# End Source File -# Begin Source File - -SOURCE=.\bitmap1.bmp -# End Source File -# Begin Source File - -SOURCE=.\res\call.bmp -# End Source File -# Begin Source File - -SOURCE=.\Call.ico -# End Source File -# Begin Source File - -SOURCE=.\res\call.ico -# End Source File -# Begin Source File - -SOURCE=.\res\chat.ico -# End Source File -# Begin Source File - -SOURCE=.\res\DND.ico -# End Source File -# Begin Source File - -SOURCE=.\res\error.ico -# End Source File -# Begin Source File - -SOURCE=.\res\hang_up.ico -# End Source File -# Begin Source File - -SOURCE=.\Hangup.ico -# End Source File -# Begin Source File - -SOURCE=.\res\hold.ico -# End Source File -# Begin Source File - -SOURCE=.\holdcall.ico -# End Source File -# Begin Source File - -SOURCE=.\icon1.ico -# End Source File -# Begin Source File - -SOURCE=.\icon2.ico -# End Source File -# Begin Source File - -SOURCE=.\res\import.ico -# End Source File -# Begin Source File - -SOURCE=.\res\invisible.ico -# End Source File -# Begin Source File - -SOURCE=.\res\Invite.ico -# End Source File -# Begin Source File - -SOURCE=.\res\message.ico -# End Source File -# Begin Source File - -SOURCE=.\res\NA.ico -# End Source File -# Begin Source File - -SOURCE=.\res\occupied.ico -# End Source File -# Begin Source File - -SOURCE=.\res\offline.ico -# End Source File -# Begin Source File - -SOURCE=.\res\online.ico -# End Source File -# Begin Source File - -SOURCE=.\res\phone.ico -# End Source File -# Begin Source File - -SOURCE=.\res\resume.ico -# End Source File -# Begin Source File - -SOURCE=.\resumecall.ico -# End Source File -# Begin Source File - -SOURCE=.\Skript1.rc -# End Source File -# Begin Source File - -SOURCE=.\res\skype.ico -# End Source File -# Begin Source File - -SOURCE=.\res\skypeout.ico -# End Source File -# End Group -# Begin Source File - -SOURCE=.\changelog.txt -# End Source File -# End Target -# End Project diff --git a/!NotAdopted/Skype/Skype_protocol.dsw b/!NotAdopted/Skype/Skype_protocol.dsw deleted file mode 100644 index 3965e55d3e..0000000000 --- a/!NotAdopted/Skype/Skype_protocol.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELЦSCHT WERDEN! - -############################################################################### - -Project: "Skype_protocol"=.\Skype_protocol.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/!NotAdopted/Skype/Skype_protocol.mak b/!NotAdopted/Skype/Skype_protocol.mak deleted file mode 100644 index cf43334fb3..0000000000 --- a/!NotAdopted/Skype/Skype_protocol.mak +++ /dev/null @@ -1,238 +0,0 @@ -!IF "$(CFG)" == "" -CFG=Win32 Debug -!MESSAGE Keine Konfiguration angegeben. Win32 Debug wird als Standard verwendet. -!ENDIF - -!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug" && "$(CFG)" != "Win64 Release" && "$(CFG)" != "Win64 Debug" && "$(CFG)" != "Win32 UNICODE Release" && "$(CFG)" != "Win32 UNICODE Debug" && "$(CFG)" != "Win64 UNICODE Release" && "$(CFG)" != "Win64 UNICODE Debug" -!MESSAGE Ungьltige Konfiguration "$(CFG)" angegeben. -!MESSAGE Sie kцnnen beim Ausfьhren von NMAKE eine Konfiguration angeben -!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: -!MESSAGE -!MESSAGE NMAKE /f "Skype_protocol.mak" CFG="Win32 Debug" -!MESSAGE -!MESSAGE Fьr die Konfiguration stehen zur Auswahl: -!MESSAGE -!MESSAGE "Win32 Release" -!MESSAGE "Win32 Debug" -!MESSAGE "Win64 Release" -!MESSAGE "Win64 Debug" -!MESSAGE "Win32 UNICODE Release" -!MESSAGE "Win32 UNICODE Debug" -!MESSAGE "Win64 UNICODE Release" -!MESSAGE "Win64 UNICODE Debug" - -!MESSAGE -!ERROR Eine ungьltige Konfiguration wurde angegeben. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe -LINK32=link.exe - -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib wsock32.lib comctl32.lib Rpcrt4.lib /nologo /dll /pdb:"$(INTDIR)\skype.pdb" /out:"$(OUTDIR)/skype.dll" /implib:"$(INTDIR)\skype.lib" - -!IF "$(CFG)" == "Win64 Release" -OUTDIR=.\Release64 -INTDIR=.\Release64 -CPP_PROJ=/nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /Fp"$(INTDIR)\Skype_protocol.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c -LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 -RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\Skript1.res" /d "NDEBUG" -!ELSEIF "$(CFG)" == "Win32 Release" -OUTDIR=.\Release -INTDIR=.\Release -CPP_PROJ=/nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /Fp"$(INTDIR)\Skype_protocol.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c -LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 -RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\Skript1.res" /d "NDEBUG" -!ELSEIF "$(CFG)" == "Win64 Debug" -OUTDIR=Debug64 -INTDIR=$(OUTDIR) -CPP_PROJ=/nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /Fp"$(INTDIR)\Skype_protocol.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c -LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 -RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\Skript1.res" /d "_DEBUG" -!ELSEIF "$(CFG)" == "Win32 Debug" -OUTDIR=.\Debug -INTDIR=$(OUTDIR) -CPP_PROJ=/nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /Fp"$(INTDIR)\Skype_protocol.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c -LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 -RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\Skript1.res" /d "_DEBUG" -!ELSEIF "$(CFG)" == "Win64 UNICODE Release" -OUTDIR=.\Release64-UNICODE -INTDIR=.\Release64-UNICODE -CPP_PROJ=/nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /D "UNICODE" /D "_UNICODE" /Fp"$(INTDIR)\Skype_protocol.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c -LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 -RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\Skript1.res" /d "NDEBUG" -!ELSEIF "$(CFG)" == "Win32 UNICODE Release" -OUTDIR=.\Release-UNICODE -INTDIR=.\Release-UNICODE -CPP_PROJ=/nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /D "UNICODE" /D "_UNICODE" /Fp"$(INTDIR)\Skype_protocol.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c -LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 -RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\Skript1.res" /d "NDEBUG" -!ELSEIF "$(CFG)" == "Win64 UNICODE Debug" -OUTDIR=Debug64-UNICODE -INTDIR=$(OUTDIR) -CPP_PROJ=/nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /D "UNICODE" /D "_UNICODE" /Fp"$(INTDIR)\Skype_protocol.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c -LINK32_FLAGS= $(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 -RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\Skript1.res" /d "_DEBUG" -!ELSEIF "$(CFG)" == "Win32 UNICODE Debug" -OUTDIR=.\Debug-UNICODE -INTDIR=$(OUTDIR) -CPP_PROJ=/nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /D "UNICODE" /D "_UNICODE" /Fp"$(INTDIR)\Skype_protocol.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c -LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 -RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\Skript1.res" /d "_DEBUG" -!ENDIF - -LINK32_OBJS= \ - "$(INTDIR)\contacts.obj" \ - "$(INTDIR)\debug.obj" \ - "$(INTDIR)\gchat.obj" \ - "$(INTDIR)\pthread.obj" \ - "$(INTDIR)\skype.obj" \ - "$(INTDIR)\skypeapi.obj" \ - "$(INTDIR)\skypeopt.obj" \ - "$(INTDIR)\skypeprofile.obj" \ - "$(INTDIR)\skypesvc.obj" \ - "$(INTDIR)\utf8.obj" \ - "$(INTDIR)\voiceservice.obj" \ - "$(INTDIR)\msglist.obj" \ - "$(INTDIR)\memlist.obj" \ - "$(INTDIR)\util.obj" \ - "$(INTDIR)\msgq.obj" \ - "$(INTDIR)\alogon.obj" \ - "$(INTDIR)\Skript1.res" - -ALL : "$(OUTDIR)\skype.dll" - - -CLEAN : - -@erase "$(INTDIR)\contacts.obj" - -@erase "$(INTDIR)\debug.obj" - -@erase "$(INTDIR)\gchat.obj" - -@erase "$(INTDIR)\pthread.obj" - -@erase "$(INTDIR)\Skript1.res" - -@erase "$(INTDIR)\skype.obj" - -@erase "$(INTDIR)\skypeapi.obj" - -@erase "$(INTDIR)\skypeopt.obj" - -@erase "$(INTDIR)\skypeprofile.obj" - -@erase "$(INTDIR)\skypesvc.obj" - -@erase "$(INTDIR)\msglist.obj" - -@erase "$(INTDIR)\memlist.obj" - -@erase "$(INTDIR)\util.obj" - -@erase "$(INTDIR)\msgq.obj" \ - -@erase "$(INTDIR)\alogon.obj" \ - -@erase "$(INTDIR)\utf8.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\voiceservice.obj" - -@erase "$(INTDIR)\skype.exp" - -@erase "$(INTDIR)\skype.pdb" - -@erase "$(INTDIR)\skype.lib" - -@erase "$(OUTDIR)\skype.dll" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - - -"$(OUTDIR)\skype.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("Skype_protocol.dep") -!INCLUDE "Skype_protocol.dep" -!ELSE -!MESSAGE Warning: cannot find "Skype_protocol.dep" -!ENDIF -!ENDIF - - -SOURCE=.\alogon.c - -"$(INTDIR)\alogon.obj" : $(SOURCE) "$(INTDIR)" - - -SOURCE=.\contacts.c - -"$(INTDIR)\contacts.obj" : $(SOURCE) "$(INTDIR)" - - -SOURCE=.\debug.c - -"$(INTDIR)\debug.obj" : $(SOURCE) "$(INTDIR)" - - -SOURCE=.\gchat.c - -"$(INTDIR)\gchat.obj" : $(SOURCE) "$(INTDIR)" - - -SOURCE=.\msgq.c - -"$(INTDIR)\msgq.obj" : $(SOURCE) "$(INTDIR)" - - -SOURCE=.\pthread.c - -"$(INTDIR)\pthread.obj" : $(SOURCE) "$(INTDIR)" - - -SOURCE=.\skype.c - -"$(INTDIR)\skype.obj" : $(SOURCE) "$(INTDIR)" - - -SOURCE=.\skypeapi.c - -"$(INTDIR)\skypeapi.obj" : $(SOURCE) "$(INTDIR)" - - -SOURCE=.\skypeopt.c - -"$(INTDIR)\skypeopt.obj" : $(SOURCE) "$(INTDIR)" - - -SOURCE=.\skypeprofile.c - -"$(INTDIR)\skypeprofile.obj" : $(SOURCE) "$(INTDIR)" - - -SOURCE=.\skypesvc.c - -"$(INTDIR)\skypesvc.obj" : $(SOURCE) "$(INTDIR)" - - -SOURCE=.\utf8.c - -"$(INTDIR)\utf8.obj" : $(SOURCE) "$(INTDIR)" - - -SOURCE=.\voiceservice.c - -"$(INTDIR)\voiceservice.obj" : $(SOURCE) "$(INTDIR)" - - -SOURCE=.\Skript1.rc - -"$(INTDIR)\Skript1.res" : $(SOURCE) "$(INTDIR)" - $(RSC) $(RSC_PROJ) $(SOURCE) - diff --git a/!NotAdopted/Skype/Skype_protocol.sln b/!NotAdopted/Skype/Skype_protocol.sln deleted file mode 100644 index 0ea2547268..0000000000 --- a/!NotAdopted/Skype/Skype_protocol.sln +++ /dev/null @@ -1,44 +0,0 @@ -п»ї -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Skype_protocol", "Skype_protocol.vcproj", "{5F9243AE-C6C9-4F42-B670-67A97767A50B}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - ANSI Debug|Win32 = ANSI Debug|Win32 - ANSI Debug|x64 = ANSI Debug|x64 - ANSI Release|Win32 = ANSI Release|Win32 - ANSI Release|x64 = ANSI Release|x64 - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - x64 Debug|Win32 = x64 Debug|Win32 - x64 Debug|x64 = x64 Debug|x64 - x64 Release|Win32 = x64 Release|Win32 - x64 Release|x64 = x64 Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.ANSI Debug|Win32.ActiveCfg = ANSI Debug|Win32 - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.ANSI Debug|Win32.Build.0 = ANSI Debug|Win32 - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.ANSI Debug|x64.ActiveCfg = ANSI Debug|x64 - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.ANSI Release|Win32.ActiveCfg = ANSI Release|Win32 - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.ANSI Release|Win32.Build.0 = ANSI Release|Win32 - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.ANSI Release|x64.ActiveCfg = ANSI Release|x64 - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.Debug|Win32.ActiveCfg = Debug|Win32 - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.Debug|Win32.Build.0 = Debug|Win32 - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.Debug|x64.ActiveCfg = Debug|x64 - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.Release|Win32.ActiveCfg = Release|Win32 - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.Release|Win32.Build.0 = Release|Win32 - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.Release|x64.ActiveCfg = Release|x64 - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.x64 Debug|Win32.ActiveCfg = x64 Debug|Win32 - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.x64 Debug|x64.ActiveCfg = x64 Debug|x64 - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.x64 Debug|x64.Build.0 = x64 Debug|x64 - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.x64 Release|Win32.ActiveCfg = x64 Release|Win32 - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.x64 Release|x64.ActiveCfg = x64 Release|x64 - {5F9243AE-C6C9-4F42-B670-67A97767A50B}.x64 Release|x64.Build.0 = x64 Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/!NotAdopted/Skype/Skype_protocol.vcproj b/!NotAdopted/Skype/Skype_protocol.vcproj deleted file mode 100644 index 74e7e4bac0..0000000000 --- a/!NotAdopted/Skype/Skype_protocol.vcproj +++ /dev/null @@ -1,2843 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/!NotAdopted/Skype/alogon.c b/!NotAdopted/Skype/alogon.c deleted file mode 100644 index 90c3510944..0000000000 --- a/!NotAdopted/Skype/alogon.c +++ /dev/null @@ -1,129 +0,0 @@ -#include "skype.h" -#include "debug.h" - -extern char g_szProtoName[]; -extern HANDLE SkypeReady; - -/** - * Purpose: Retrieves class name from window - * - * Note: This is some sort of hack to return static local variable, - * but it works :) - */ -static const TCHAR* getClassName(HWND wnd) -{ - static TCHAR className[256]; - - *className=0; - GetClassName(wnd, &className[0], sizeof(className)/sizeof(className[0])); - return className; -} - -/** - * Purpose: Finds a window - * - * Note: This function relies on Skype window placement. - * It should work for Skype 3.x - */ -static HWND findWindow(HWND parent, const TCHAR* childClassName) -{ - // Get child window - // This window is not combo box or edit box - HWND wnd = GetWindow(parent, GW_CHILD); - while(wnd != NULL && _tcscmp(getClassName(wnd), childClassName) != 0) - wnd = GetWindow(wnd, GW_HWNDNEXT); - - return wnd; -} - -static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) -{ - DWORD dwPID; - const TCHAR *lpszClassName; - - - GetWindowThreadProcessId(hWnd,&dwPID); - if (lParam != 0 && dwPID != (DWORD)lParam) return TRUE; - lpszClassName = getClassName(hWnd); - if(_tcscmp(lpszClassName, _T("tSkMainForm.UnicodeClass")) == 0 || - _tcscmp(lpszClassName, _T("TLoginForm.UnicodeClass")) == 0) - { - HWND loginControl = GetWindow(hWnd, GW_CHILD); - - LOG(("setUserNamePasswordThread: Skype window found!")); - - // Sleep for some time, while Skype is loading - // It loads slowly :( - //Sleep(5000); - LOG (("TLoginControl = %S", getClassName(loginControl))); - - // Check for login control - if(_tcscmp(getClassName(loginControl), _T("TLoginControl")) == 0) - { - // Find user name window - HWND userName = findWindow(loginControl, _T("TNavigableTntComboBox.UnicodeClass")); - HWND password = findWindow(loginControl, _T("TNavigableTntEdit.UnicodeClass")); - - LOG (("userName=%08X; password=%08X", userName, password)); - if (userName && password) - { - // Set user name and password - DBVARIANT dbv; - - if(!DBGetContactSettingWString(NULL,SKYPE_PROTONAME,"LoginUserName",&dbv)) - { - SendMessageW(userName, WM_SETTEXT, 0, (LPARAM)dbv.pwszVal); - DBFreeVariant(&dbv); - } - - if(!DBGetContactSettingWString(NULL,SKYPE_PROTONAME,"LoginPassword",&dbv)) - { - SendMessageW(password, WM_SETTEXT, 0, (LPARAM)dbv.pwszVal); - DBFreeVariant(&dbv); - SendMessageW(password, WM_CHAR, 13, 0); - } - - - SendMessageW(hWnd, - WM_COMMAND, - 0x4a8, // sign-in button; WARNING: This ID can change during newer Skype versions - (LPARAM)findWindow(loginControl, _T("TTntButton.UnicodeClass"))); - } - return FALSE; - } - - } - return TRUE; -} - -DWORD WINAPI setUserNamePasswordThread(LPVOID lpDummy) -{ - DWORD dwPid = (DWORD)lpDummy; - HANDLE mutex = CreateMutex(NULL, TRUE, _T("setUserNamePasswordMutex")); - - // Check double entrance - if(GetLastError() == ERROR_ALREADY_EXISTS) - return 0; - - WaitForSingleObject(SkypeReady, 5000); - EnumWindows (EnumWindowsProc, dwPid); - - ReleaseMutex(mutex); - CloseHandle(mutex); - return 0; -} - -/** - * Purpose: Finds Skype window and sets user name and password. - * - * Note: This function relies on Skype window placement. - * It should work for Skype 3.x - */ -void setUserNamePassword(int dwPid) -{ - DWORD threadId; - CreateThread(NULL, 0, &setUserNamePasswordThread, (LPVOID)dwPid, 0, &threadId); - - // Give time to thread - Sleep(100); -} diff --git a/!NotAdopted/Skype/alogon.h b/!NotAdopted/Skype/alogon.h deleted file mode 100644 index 00d2e7e703..0000000000 --- a/!NotAdopted/Skype/alogon.h +++ /dev/null @@ -1 +0,0 @@ -void setUserNamePassword(int dwPid); diff --git a/!NotAdopted/Skype/changelog.txt b/!NotAdopted/Skype/changelog.txt deleted file mode 100644 index 60526b1116..0000000000 --- a/!NotAdopted/Skype/changelog.txt +++ /dev/null @@ -1,330 +0,0 @@ -NOTES ------ - - You have to manually disable popup of messages in SKYPE, as there is - currently no function in the API to do this - Got to File/Options/Instant messages and disable the checkboxes there - - -CODE ----- - Currently a real mess. At least I splitted it up a bit now. - But hey, it kinda works... ;) - -HISTORY -------- - -0.0.0.45 - ! "NA" and "Free for chat" status are available again; NA is supported by skype and Free for chat - uses skypes "Skype Me" status; better leave it that way - ! changes to the mood message of a contact were only visible after a status change - ! plugin was crashing when status changed to offline and a proxy is used - -0.0.0.44 - ! menu item "Hang up (Skype)" was show on none skype contacts - ! fixed serveral bugs in skype startup (including starting skype twice) - ! show connecting state correctly - ! hangup while ringing caused a state where contact isnt callable anymore - * removed "NA" and "Free for chat" status - -0.0.0.43 - + Added option to suppress summary chat message after call is finished (jls17) - ! Fix hangup causes a dial command if opponent hangs up a little bit earlier (jls17) - ! removed empty chat message on incoming call - ! empty mood message is send to skype correctly - - -0.0.0.42 - + Added a trick to identify skype 3 version (fingerprint) -0.0.0.41 - + Added option to enter user name and password. (Patch by NN) - -0.0.0.40 - + Support for new core service: get avatar caps - + Option to show/hide default avatar for contacts - + Hide Skype Avatar page in user details if >= #27 - -0.0.0.39 - + Voice service support in normall calls - no support for SkypeOut yet (pescuma) - ! Made options dialog a little bit smaller, removed frame and set bold frame for popups (pescuma) - + Add more status to manage for away message - -0.0.0.38 - ! Fix the load for pre 0.7.0 #17 build - * Patch by pescuma for avatar. - -0.0.0.37 - ! Avoid empty message from myself on first message received. - + Add the Get user avatar interface - * Change the get user info thread - * code cleanup - + Support for miranda 0.8 - ! Correct use of folder plugin (using "avatar cache folder"\SKYPE). - -0.0.0.36 - ! When settings skype offline, first set proto off then contacts. - * move the broadcast of status change out of if statement in status change. - * Set contacts ofline on plugin load (avoid skype contact to be online if starts skype is not checked) - ! Fix the use of datapath for portable skype - * Allow to choose no splash - no tray - minimized even if start skype with miranda is not checked. - ! Fix bug with timestamp in irc - -0.0.0.35 - * Use unicode nick, status message, city and country in skype profile. - ! Fix for sending status change when offline - * Do not send message to skype if not attached (avoid trying to connect to api at startup) - ! Fix crash on recieving message with groupchat checked. - -0.0.0.34 - + Try to identify if chat message comes from a group chat or not - + Add a option to flag group chat message as read if not using chat.dll for group chat. - ! Fix the check of message type (group chat or normal) - -0.0.0.33 - ! Fix for flags of event and metacontact (thanks SJE) - * Next step to custom popup support (in popup option page) - ! Fix infinite for error popup - -0.0.0.32 - ! Improvemnt of the Action message support. - ! Fix empty message on first chat with a contact. - -0.0.0.31 - + First step to Action Message support ( /me ) - + Updater support for File Listing. - + First step to a custom popup for call notification. - -0.0.0.30 - + Add an option to enable/disable the timezone patch - -0.0.0.29 - ! Try to fix the bug (set skype offline when closing miranda) - -0.0.0.28 - * Improved portable skype integration - -0.0.0.27 - * Try to fix the start using custom command line - + Close skype using custom command line too - -0.0.0.26 - + Add a way to use a custom command line to start skype. - -0.0.0.25 - ! patch from markcs about timezones. - ! shutdown patch by sje - -0.0.0.24 - * Change options dialog (use tabsrmm uxtheme) - -0.0.0.23 - ! Wrong db entry name for cellular (cellucar) - + Set mirver using is video capabale to identify skype 2.0 user - -0.0.0.22 - * Options page redesigned - * Work around to force refresh of avatar in MyDetail (w8 the avatar change service) - * Change Skype protocol to Skype in options->Network - * Free buffer in status message retrieve - * First step to a details info page. - -0.0.0.21 - * Some minor bugfixes - * Severe bugfix: Message sending routine worked incorrectly (no errors were shown - even if there were sending-errors) - * Removed PingPong - thread in favour of WM_TIMER - * Fixed critical section unlocking in skypeapi.c. In certain cases, critical sections - were not left correctly. - * Fixed a bug that caused Miranda to crash on exit with Newstatusnotify plugin - (thanks to TioDuke for reporting) - * Hopefully fixed the nasty bug that caused Miranda to lockup on exit. - -0.0.0.20 - * Split service and options in two new cpp file. - * Put the default attemps number to 10 - -0.0.0.19 - * Add avatar support for own user only (no api to ge contacts avatar) - * Add set status message. - * Add Get status message for contact where viewing contact details - * Change icons (thanks to Faith Healer) - * Updater support (BETA ONLY) - * DBeEditor known module support - * Mods to avoid warning in VC++ 8 - * Implement the MyDetail requested services - -0.0.0.18 - * HOTFIX - Double File-Transfer icon removed. Please note that you can't send files - via drag & drop, because of the nature of Skype API - Skype wants to open its own - "File/Open" dialog, so I cannot supply a path to the file to be sent, therefore I - had to add a seperate File-sending function rather than using Miranda's function. - -0.0.0.17 - * Startup of Skype in a seperate thread was not solved properly. Now it should really - start in background - * The hack for the statusmode-bug is optional in the settings and is turned off - per default. (Thx to Eddie Hung for reporting problems and help) - * Added an ugly hack for the Skype-API offline bug (grr.. ) - * Nickname is now set correctly. To cleanup the existing Nicks, please go to - the options page an push the "Cleanup Nicknames" button. - This will clean out entries where the Nick was set to the Skype handle - * Fixed a bug in the message sending routine that caused errors in communication - (missed messages in Skype that were not fetched..) - * Added "Hold call" feature while calling - * Added support for conference calls (if a second user is calling while you - are in a conversation, you can now choose whether to block the call or let - the user join you in a conference with the existing caller or to put the - other caller on hold) - * Fixed a bug in the code for adding users that were just searched via the - Skype search-window but never have been in contact list. - * Fixed some bugs (memleak, nick error, ..) in the Search-Routine for - Skype-contacts. (thx to Deadman for reporting) - * Fixed a bug with unknown SKYPE_IN contacts - * Added file-sending capability (requires new Skype-version) - * Did a litte code-cleanup - * Adding / Removing contacts can now be done via the Miranda standard-dialogs if - you use the newest Skype-Version - * With the new Skype-version you are able to handle Authorisation-Requests via Miranda - now. - -0.0.0.16 - * Fixed a severe memory-allocation bug in utf8-encoded messages that caused random - crashes (oops :-O) - Thanks to Ary Dvoretz for reporting. - * Bug in SkypeStatusMode-Bug fix from last release fixed (protocol stayed offline) - * Now onlinestatus for SkypeOut-Contacts is configurable - * Made Menu-Options translatable - * Added support for calling SkypeOut-Phonenumbers. You can now dial a PSTN-Number - by calling "Do a SkypeOut call" in the main menu (or top toolbar if the - toptoolbar plugin is installed) and entering a number or - by right-clicking on a non-Skype contact and selecting "Call using SkypeOut", - if there is a phone-Number entry in the User's-Details. - This, of course, is only working if you have SkypeOut privilege - -0.0.0.15 - * Fixed a crash on Miranda-exit when error occured on Skype-Protocol start - * Fixed Bug #0000006: Now user is asked if he wants to enable the Protocol - for the current profile, if he starts with a new profile. - * Fixed Bug #0000002: Now interfacing with Skype is really stopped on going - offline if the option is enabled. (PingPong-thread killed) - - This also applies on closing Skype - * Fixed a memory leak in MsgFetchThread that appeared in the last version because - of the groupchat-implementation (free() within wrong if clause, ooops ;) - * Fixed Bug #0000005: When there is a msg from a user that is not on Skype's contact - list, the user is now added PALF_TEMPORARY and disappears again on next Miranda-start - * Implemented a fix for Skype API's statusmode bug reported by Markus Mьtzel: - If you change the online status while Skype is still connecting, Skype changes to - the FIRST state that it was requested to change to, after going online, instead of - the LAST state. However the bug was not reproducable for me. - * Fixed broken popup-support (I hope) - * CHANGE of behaviour (inspired by Bug #0000007): - If you turn off "Start Skype with Miranda", the plugin wouldn't search for a - running Skype instance anymore. - * Now when going online and Skype is not launched, Skype will be launched via a - seperate thread (in background) so that Miranda isn't blocked while Skype is loading - * Options Dlg. should now be translateable too. - -0.0.0.14 - - * Miranda crash on exit if Skype was not found installed should be - fixed by now. - * Implemented compatibility layer for Skype API Protocol V3 and above. - * Removed some useless code introduced in 0.0.0.12 - * Added some fixes made by TioDuke (thank you!) - - Using your own Nick instead of your Skype-Handle in conversations - - LastName 3rd token & above are not ignored any more - - Status modes "On the phone" and "out to lunch" are mapped now - * Fixed a bug that caused "Skype API not available" messages under high load. - (thanks to Romeo28 for testing!) - * Fixed a bug that caused Message sending thread to wait forever if sending - a message times out (causing dead threads) - * Skype contact list should be synced now when Skype-Status changes. - (thx to Markus Mьtzel for Bugreport) - * Implemented a garbage collector that removes old messages from queue - in order to prevent possible memory exhaustion - * Added option to disable all modal Error-message dialog boxes (as people - keep telling me that they are annoyed by them) - * Added langpack support for error messages - * Added option to increase the time the protocol is waiting for Skype - * Added groupchat functions. WARNING: For testing purposes only! - Currently there is a memleak which I cannot find, but even worse, - Skype API doesn't seem to support sending to a groupchat, inviting etc. - So this is currently only experimental! When you send to a groupchat you - currently send single messages to every user seperately. Skype staff - didn't answer my question about sending to groupchats so far, so it - depends on them when this feature will be available for real use. - -0.0.0.13 - A few minor fixes: - * Logging off users shouldn't flood the StatusNotify-Plugin now. - * Popup-plugin can be enabled/disabled in the options dlg. - * Implemented support for SkypeOut contacts (they caused crashes) - * Now using Nick instead of Skype-Handle as Contact list name on - adding new users, if it is available. - -0.0.0.12 - Bugfixing because of strange Skype API behaviour: - * Adding of contacts that are just searched, but not added in Skype - should be prevented now. - * Version number correct again. - -0.0.0.11 - Only minor bugfixes: - * The gender in user-details is now saved correctly to the DB - (thanks to LeON for the hint!) - * The Apply-Button should now be disabled in the options DLG by default - (thanks to sje for the bug report) - * Contactlist should be reinitialized after a SYNC-Problem now. - * Bug with usernames that contain commas should be fixed - * Protocol messages are now shown as popups if Popup-plugin is installed - -0.0.0.10 - * Hopefully recovery after sync problem works a bit better now - (Sync-Problem Messages are no longer shown) - * Now you can hang up a call directly from a contact's context menu - * Now implemented support for using Skype over a network. You can use - the included skypeproxy service to in/output Skype API messages - on a socket and can connect to it with the plugin. - So you can, for example, launch the skypeproxy service on your - Windows-server (eeek! :P) and control Skype from your workstation - using Miranda. (requested feature by foosmate) - * Now you can accept incoming calls via Miranda (or hang them up) - * The status mode bug (clist status menu was not updated properly) - should be fixed by now. - * The logfile in the dbeug-build should now always be written to the - Miranda directory. - -0.0.0.9 - * Fixed bug with error when starting Skype with Miranda ("Wheee...") - * As Skype seems to use new, UNDOCUMENTED Message types (I think it's - a severe Skype-API bug) I adapted the plugin so that it works - with new API now. This fixes the problem of not being able to receive - messages in new Skype versions. - Skype now sends "MESSAGE TYPE SAID" instead of "MESSAGE TYPE TEXT", - the bug has been reported to Skype forum. - (http://forum.skype.com/viewtopic.php?t=15435) - * Fixed a memory leak in Message-receiving routine - * Added UTF8-support for Contact properties (does this fix something?) - * Fixed a memory leak in Startup-routine - * Finally renamed Plugin from SKYPE_PROTOCOL to SKYPE internally. - Hopefully it will upgrade your existing DB seamlessly. - * Now all threads should be sync with Miranda as I'm using the pthread- - functions "borrowed" from Yahoo protocol. - -0.0.0.8 - * Now there is support for the "Occupied" mode, which is mapped to DND - This is useful for users who do a global statusmodechange so that Skype - gets to "Occupied" state instead of staying online. - * Now the protocol doesn't disable itself when you chose to not start - Skype on startup, instead it stays offline and starts Skype when you - try to go online. - -0.0.0.7 - * Fixed a bug that caused a lockup on Plugin startup (when a Window was not - reacting to the HWND_BROADCAST) (thx to Cool Blue) - * Fixed a bug in the Startup-procedure.. - * Now Skype doesn't go offline when you close Miranda (thx to Egodust) - * Now it should really work unter WIN98 (thx to TioDuke for testing) - * Implemented feature for Shutting down Skype on going offline and - restarting Skype on changing to online mode again, as many people requested. - -0.0.0.6 - * Added feature requests from kreisquadratur: - * Option to disable Skype-Menuitems - * Fixed bug with Apply-Button - * Using a nicer Skype-Icon now - * Now using Skype-Timestamp for messages - * Implementing importing history from skype (see contextmenu of contact) - * Fixed bug with processing first message of MESSAGES - List - * Found out, that RegisterClass() doesn't work for UNICODE-Programs on - non-UNICODE win98, therefore return-value check for RegisterClass removed - * Fixed a bug that caused a "We got a Sync problem :(" - -0.0.0.5 - * Fixed a bug that caused the plugin to crash with bigger contact lists - (Skype API was flooded on startup) - -0.0.0.4 - * Missed messages are fetched now - * User details work now - * More verbose error msgs now (to help Win98 user debugging his problem) - * Added option for starting skype with miranda and shutting down - Skype when closing miranda. - * You can now chose the command line options to pass to Skype on startup - * Hopefully the bug with multiple Call - Entries per user is fixed now - * Protocol name is now "Skype", not "Skype_protocol" - Remember this - when updating, so DELETE skype_protocol.dll first!! - * Secured Message Queue with a Mutex - * Fixed a Message-receiving bug that could cause delays in message-processing - * Adding a Contact in Skype now also adds it to Miranda immediately - (Deleting should also work, but doesn't because of a Skype API bug) - * Added searching for contacts, but this feature seems to be quite useless, - as Skype API doesn't support adding contacts, so you still have to add - your contacts in the Skype program, sorry - In order to do this comfortably, I added a Miranda Menu-Item for adding - Skype-contacts. - -0.0.0.3 - * I hope it's thread-safe now - * Changing the Online-Status should work correctly now - * Fixed "We got a sync problem :(" bug - big thx to Azzie - * Now starts Skype more in the background as proposed by Kreisquadratur - * Implemented PING-PONG with Skype to detect if Connection to Skype API - was lost - * Launching of Skype by Miranda improved diff --git a/!NotAdopted/Skype/contacts.c b/!NotAdopted/Skype/contacts.c deleted file mode 100644 index c83d3294a1..0000000000 --- a/!NotAdopted/Skype/contacts.c +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Contactlist management functions - */ - -#include "skype.h" -#include "skypeapi.h" -#include "debug.h" -#include "pthread.h" -#include "gchat.h" -#include "voiceservice.h" - -#pragma warning (push) -#pragma warning (disable: 4100) // unreferenced formal parameter -#include "../../include/m_langpack.h" -#pragma warning (pop) - -#pragma warning (disable: 4706) // assignment within conditional expression - -// Imported Globals -extern HINSTANCE hInst; -extern BOOL bSkypeOut, bIsImoproxy; -extern char protocol, g_szProtoName[]; - -// Handles -static HANDLE hMenuCallItem, hMenuCallHangup, hMenuSkypeOutCallItem, hMenuHoldCallItem, hMenuFileTransferItem, hMenuChatInitItem; - -// Check if alpha blending icons are supported -// Seems to be not neccessary -/* -BOOL SupportAlphaIcons(void) { - HANDLE hMod; - DLLVERSIONINFO tDVI={0}; - BOOL retval=FALSE; - FARPROC pDllGetVersion; - - if (!(hMod=LoadLibrary("comctl32.dll"))) return FALSE; - if (pDllGetVersion=GetProcAddress(hMod, "DllGetVersion")) { - tDVI.cbSize=sizeof(tDVI); - if (!pDllGetVersion ((DLLVERSIONINFO *)&tDVI)) { - if (GetDeviceCaps(GetDC(NULL), BITSPIXEL)*GetDeviceCaps(GetDC(NULL), PLANES)>=32 && - tDVI.dwMajorVersion>=6) - retval=TRUE; - } - } - FreeLibrary(hMod); - return retval; -} -*/ - -CLISTMENUITEM CallItem(void) { - CLISTMENUITEM mi={0}; - - mi.cbSize=sizeof(mi); - mi.position=-2000005000; - mi.flags=CMIF_NOTOFFLINE|CMIF_TCHAR; - mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALL)); - mi.pszContactOwner=SKYPE_PROTONAME; - mi.ptszName=LPGENT("Call (Skype)"); - mi.pszService=SKYPE_CALL; - - return mi; -} - -CLISTMENUITEM SkypeOutCallItem(void) { - CLISTMENUITEM mi={0}; - - mi.cbSize=sizeof(mi); - mi.position=-2000005000; - mi.flags=CMIF_HIDDEN|CMIF_TCHAR; - mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALLSKYPEOUT)); - mi.ptszName=LPGENT("Call using SkypeOut"); - mi.pszService=SKYPEOUT_CALL; - - return mi; -} - -CLISTMENUITEM HupItem(void) { - CLISTMENUITEM mi={0}; - - mi.cbSize=sizeof(mi); - mi.position=-2000005000; - mi.flags=CMIF_NOTOFFLINE|CMIF_TCHAR; - mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_HANGUP)); - mi.pszContactOwner=SKYPE_PROTONAME; - mi.ptszName=LPGENT("Hang up call (Skype)"); - mi.pszService=SKYPE_CALLHANGUP; - - return mi; -} - -CLISTMENUITEM SkypeOutHupItem(void) { - CLISTMENUITEM mi={0}; - - mi.cbSize=sizeof(mi); - mi.position=-2000005000; - mi.flags=CMIF_TCHAR; - mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_HANGUP)); - mi.ptszName=LPGENT("Hang up SkypeOut call"); - mi.pszService=SKYPEOUT_CALL; - return mi; -} - -CLISTMENUITEM HoldCallItem(void) { - CLISTMENUITEM mi={0}; - - mi.cbSize=sizeof(mi); - mi.position=-2000005000; - mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; - mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_HOLD)); - mi.ptszName=LPGENT("Hold call"); - mi.pszService=SKYPE_HOLDCALL; - return mi; -} - -CLISTMENUITEM ResumeCallItem(void) { - CLISTMENUITEM mi={0}; - - mi.cbSize=sizeof(mi); - mi.position=-2000005000; - mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; - mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_RESUME)); - mi.ptszName=LPGENT("Resume call"); - mi.pszService=SKYPE_HOLDCALL; - return mi; -} - -CLISTMENUITEM FileTransferItem(void) { - CLISTMENUITEM mi={0}; - - // Stolen from file.c of Miranda core - mi.cbSize=sizeof(mi); - mi.position=-2000020000; - mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; - mi.hIcon=LoadSkinnedIcon(SKINICON_EVENT_FILE); - mi.ptszName=LPGENT("&File"); - mi.pszContactOwner=SKYPE_PROTONAME; - mi.pszService=SKYPE_SENDFILE; - return mi; -} - -CLISTMENUITEM ChatInitItem(void) { - CLISTMENUITEM mi={0}; - - mi.cbSize=sizeof(mi); - mi.position=-2000020000; - mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; - mi.hIcon=LoadIcon( hInst, MAKEINTRESOURCE( IDI_INVITE )); - mi.ptszName=LPGENT("&Open groupchat"); - mi.pszContactOwner=SKYPE_PROTONAME; - mi.pszService=SKYPE_CHATNEW; - return mi; -} - -HANDLE add_contextmenu(HANDLE hContact) { - CLISTMENUITEM mi; - - UNREFERENCED_PARAMETER(hContact); - - if (!HasVoiceService()) { - mi=CallItem(); - hMenuCallItem=(HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0,(LPARAM)&mi); - mi=HupItem(); - hMenuCallHangup=(HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi); - } - - mi=SkypeOutCallItem(); - hMenuSkypeOutCallItem=(HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0,(LPARAM)&mi); - - if (!HasVoiceService()) { - mi=HoldCallItem(); - hMenuHoldCallItem=(HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0,(LPARAM)&mi); - } - - // We cannot use flag PF1_FILESEND for sending files, as Skype opens its own - // sendfile-Dialog. - mi=FileTransferItem(); - hMenuFileTransferItem=(HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0,(LPARAM)&mi); - - mi=ChatInitItem(); - hMenuChatInitItem=(HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0,(LPARAM)&mi); - - - ZeroMemory(&mi,sizeof(mi)); - mi.cbSize=sizeof(mi); - mi.position=-2000005000; - mi.flags=CMIF_TCHAR; - mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_IMPORT)); - mi.pszContactOwner=SKYPE_PROTONAME; - mi.ptszName=LPGENT("Import Skype history"); - mi.pszService=SKYPE_IMPORTHISTORY; - return (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0,(LPARAM)&mi); -} - -HANDLE add_mainmenu(void) { - CLISTMENUITEM mi={0}; - - mi.cbSize=sizeof(mi); - mi.position=-2000005000; - mi.flags=CMIF_TCHAR; - mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_ADD)); - mi.pszContactOwner=SKYPE_PROTONAME; - mi.ptszName=LPGENT("Add Skype contact"); - mi.pszService=SKYPE_ADDUSER; - return (HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM, (WPARAM)NULL,(LPARAM)&mi); - -} - -int __cdecl PrebuildContactMenu(WPARAM wParam, LPARAM lParam) { - DBVARIANT dbv; - CLISTMENUITEM mi; - char *szProto; - BOOL callAvailable = FALSE; - BOOL hangupAvailable = FALSE; - - UNREFERENCED_PARAMETER(lParam); - - if (!(szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0))) return 0; - - if (!HasVoiceService()) { - // Clear hold-Item in case it exists - mi=HoldCallItem(); - mi.flags|=CMIM_ALL; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuHoldCallItem,(LPARAM)&mi); - } - - if (!strcmp(szProto, SKYPE_PROTONAME)) { - if (!HasVoiceService()) { - if (!DBGetContactSetting((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { - if (DBGetContactSettingByte((HANDLE)wParam, SKYPE_PROTONAME, "OnHold", 0)) - mi=ResumeCallItem(); else mi=HoldCallItem(); - mi.flags=CMIM_ALL; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuHoldCallItem,(LPARAM)&mi); - - callAvailable = FALSE; - hangupAvailable = TRUE; - - DBFreeVariant(&dbv); - } else { callAvailable = TRUE; hangupAvailable = FALSE; } - - if (DBGetContactSettingByte((HANDLE)wParam, SKYPE_PROTONAME, "ChatRoom", 0)!=0) { - callAvailable = FALSE; - hangupAvailable = FALSE; - } - - mi = CallItem(); - mi.flags |= CMIM_ALL | (!callAvailable?CMIF_HIDDEN:0); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuCallItem,(LPARAM)&mi); - - mi = HupItem(); - mi.flags |= CMIM_ALL | (!hangupAvailable?CMIF_HIDDEN:0); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuCallHangup,(LPARAM)&mi); - } - - // Clear SkypeOut menu in case it exists - mi=SkypeOutCallItem(); - mi.flags|=CMIM_ALL; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuSkypeOutCallItem,(LPARAM)&mi); - - // File sending and groupchat-creation works starting with protocol version 5 - if (protocol>=5) { - mi=FileTransferItem(); - if (DBGetContactSettingByte((HANDLE)wParam, SKYPE_PROTONAME, "ChatRoom", 0)==0) - mi.flags ^= CMIF_HIDDEN; - mi.flags |= CMIM_FLAGS; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuFileTransferItem,(LPARAM)&mi); - - mi=ChatInitItem(); - if (DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseGroupchat", 0) && - DBGetContactSettingByte((HANDLE)wParam, SKYPE_PROTONAME, "ChatRoom", 0)==0) - mi.flags ^= CMIF_HIDDEN; - mi.flags |= CMIM_FLAGS; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuChatInitItem,(LPARAM)&mi); - } - - } else if (bSkypeOut) { - if (!DBGetContactSetting((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { - mi=SkypeOutHupItem(); - DBFreeVariant(&dbv); - } else { - mi=SkypeOutCallItem(); - if(!DBGetContactSetting((HANDLE)wParam,"UserInfo","MyPhone0",&dbv)) { - DBFreeVariant(&dbv); - mi.flags=0; - } - } - mi.flags|=CMIM_ALL; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuSkypeOutCallItem,(LPARAM)&mi); - } - - return 0; -} - -/* -int ClistDblClick(WPARAM wParam, LPARAM lParam) { - char *szProto; - - szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, wParam, 0 ); - if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && - DBGetContactSettingWord((HANDLE)wParam, SKYPE_PROTONAME, "Status", ID_STATUS_OFFLINE)==ID_STATUS_ONTHEPHONE) { - SkypeCall(wParam, 0); - } - - return 0; -} -*/ - -HANDLE find_contact(char *name) { - char *szProto; - int tCompareResult; - HANDLE hContact; - DBVARIANT dbv; - - // already on list? - for (hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);hContact != NULL;hContact=(HANDLE)CallService( MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) - { - szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0 ); - if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && DBGetContactSettingByte(hContact, SKYPE_PROTONAME, "ChatRoom", 0)==0) - { - if (DBGetContactSettingString(hContact, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) continue; - tCompareResult = strcmp(dbv.pszVal, name); - DBFreeVariant(&dbv); - if (tCompareResult) continue; - return hContact; // already there, return handle - } - } - return NULL; -} -HANDLE find_contactT(TCHAR *name) { - char *szProto; - int tCompareResult; - HANDLE hContact; - DBVARIANT dbv; - - // already on list? - for (hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);hContact != NULL;hContact=(HANDLE)CallService( MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) - { - szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0 ); - if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && DBGetContactSettingByte(hContact, SKYPE_PROTONAME, "ChatRoom", 0)==0) - { - if (DBGetContactSettingTString(hContact, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) continue; - tCompareResult = _tcscmp(dbv.ptszVal, name); - DBFreeVariant(&dbv); - if (tCompareResult) continue; - return hContact; // already there, return handle - } - } - return NULL; -} - - -HANDLE add_contact(char *name, DWORD flags) { - HANDLE hContact; - - // already on list? - if (hContact=find_contact(name)) { - if (!(flags & PALF_TEMPORARY) && DBGetContactSettingByte(hContact, "CList", "NotOnList", 1)) { - DBDeleteContactSetting( hContact, "CList", "NotOnList" ); - DBDeleteContactSetting( hContact, "CList", "Hidden" ); - } - LOG(("add_contact: Found %s", name)); - return hContact; // already there, return handle - } - // no, so add - - LOG(("add_contact: Adding %s", name)); - hContact=(HANDLE)CallServiceSync(MS_DB_CONTACT_ADD, 0, 0); - if (hContact) { - if (CallServiceSync(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact,(LPARAM)SKYPE_PROTONAME)!=0) { - LOG(("add_contact: Ouch! MS_PROTO_ADDTOCONTACT failed for some reason")); - CallServiceSync(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0); - return NULL; - } - if (name[0]) DBWriteContactSettingString(hContact, SKYPE_PROTONAME, SKYPE_NAME, name); - - if (flags & PALF_TEMPORARY ) { - DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1); - DBWriteContactSettingByte(hContact, "CList", "Hidden", 1); - } - if (name[0]) { - SkypeSend("GET USER %s DISPLAYNAME", name); - } else {LOG(("add_contact: Info: The contact added has no name."));} - } else {LOG(("add_contact: Ouch! MS_DB_CONTACT_ADD failed for some reason"));} - LOG(("add_contact succeeded")); - return hContact; -} - -void logoff_contacts(BOOL bCleanup) { - HANDLE hContact; - char *szProto; - DBVARIANT dbv={0}; - - LOG(("logoff_contacts: Logging off contacts.")); - for (hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);hContact != NULL;hContact=(HANDLE)CallService( MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) { - szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0 ); - if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME)) - { - if (DBGetContactSettingWord(hContact, SKYPE_PROTONAME, "Status", ID_STATUS_OFFLINE)!=ID_STATUS_OFFLINE) - DBWriteContactSettingWord(hContact, SKYPE_PROTONAME, "Status", ID_STATUS_OFFLINE); - - DBDeleteContactSetting(hContact, SKYPE_PROTONAME, "CallId"); - if (DBGetContactSettingByte(hContact, SKYPE_PROTONAME, "ChatRoom", 0)==1) - { - if (DBGetContactSettingTString(hContact, SKYPE_PROTONAME, "ChatRoomID", &dbv)) continue; - RemChat (dbv.ptszVal); - DBFreeVariant(&dbv); - } - if (DBGetContactSettingString(hContact, SKYPE_PROTONAME, "Typing_Stream", &dbv) == 0) - { - if (bCleanup) SkypeSend ("ALTER APPLICATION libpurple_typing DISCONNECT %s", dbv.pszVal); - DBFreeVariant(&dbv); - DBDeleteContactSetting(hContact, SKYPE_PROTONAME, "Typing_Stream"); - } - - } - } - if (bCleanup && (protocol>=5 || bIsImoproxy)) SkypeSend ("DELETE APPLICATION libpurple_typing"); -} diff --git a/!NotAdopted/Skype/contacts.h b/!NotAdopted/Skype/contacts.h deleted file mode 100644 index 35a400c3e9..0000000000 --- a/!NotAdopted/Skype/contacts.h +++ /dev/null @@ -1,11 +0,0 @@ -// Prototypes -HANDLE add_contextmenu(HANDLE hContact); -HANDLE find_contact(char *name); -HANDLE find_contactT(TCHAR *name); -HANDLE add_contact(char *name, DWORD flags); -HANDLE add_mainmenu(void); -CLISTMENUITEM HupItem(void); -CLISTMENUITEM CallItem(void); -void logoff_contacts(BOOL bCleanup); -int PrebuildContactMenu(WPARAM, LPARAM); -//int ClistDblClick(WPARAM, LPARAM); \ No newline at end of file diff --git a/!NotAdopted/Skype/debug.c b/!NotAdopted/Skype/debug.c deleted file mode 100644 index a1267d8d8a..0000000000 --- a/!NotAdopted/Skype/debug.c +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef _DEBUG -#pragma warning (disable: 4206) // nonstandard extension used : translation unit is empty -#else -#include "debug.h" - -#define WIN32_LEAN_AND_MEAN -//#include -#include -//#include -#include "skype.h" -#include -#include - -#define INITBUF 1024 /* Initial size of buffer */ - -#pragma warning (disable: 4706) // assignment within conditional expression - -extern char g_szProtoName[]; - -static CRITICAL_SECTION m_WriteFileMutex; -static FILE *m_fpLogFile = INVALID_HANDLE_VALUE; -static char *m_szLogBuf = NULL; -static DWORD m_iBufSize = 0; - -void init_debug(void) { - char *p; - char logfile[MAX_PATH]; - - ZeroMemory(logfile, sizeof(logfile)); - p=logfile+GetModuleFileNameA(NULL, logfile, sizeof(logfile)); - if (!(p=strrchr (logfile, '\\'))) p=logfile; else p++; - sprintf (p, "%s_log.txt", SKYPE_PROTONAME); - m_szLogBuf = calloc (1, (m_iBufSize = INITBUF)); - m_fpLogFile = fopen(logfile, "a"); - InitializeCriticalSection(&m_WriteFileMutex); -} - -void end_debug (void) { - if (m_szLogBuf) free (m_szLogBuf); - if (m_fpLogFile) fclose (m_fpLogFile); - DeleteCriticalSection(&m_WriteFileMutex); -} - -void do_log(const char *pszFormat, ...) { - char *ct, *pNewBuf; - va_list ap; - time_t lt; - int iLen; - - if (!m_szLogBuf || !m_fpLogFile) return; - EnterCriticalSection(&m_WriteFileMutex); - time(<); - ct=ctime(<); - ct[strlen(ct)-1]=0; - do - { - va_start(ap, pszFormat); - iLen = _vsnprintf(m_szLogBuf, m_iBufSize, pszFormat, ap); - va_end(ap); - if (iLen == -1) - { - if (!(pNewBuf = (char*)realloc (m_szLogBuf, m_iBufSize*2))) - { - iLen = strlen (m_szLogBuf); - break; - } - m_szLogBuf = pNewBuf; - m_iBufSize*=2; - } - } while (iLen == -1); - fprintf (m_fpLogFile, sizeof(time_t) == sizeof(int) ? "%s (%ld) [%08X] %s\n" : "%s (%lld) [%08X] %s\n", ct, lt, GetCurrentThreadId(), m_szLogBuf); - fflush (m_fpLogFile); - LeaveCriticalSection(&m_WriteFileMutex); -} -#endif \ No newline at end of file diff --git a/!NotAdopted/Skype/debug.h b/!NotAdopted/Skype/debug.h deleted file mode 100644 index 9582246251..0000000000 --- a/!NotAdopted/Skype/debug.h +++ /dev/null @@ -1,23 +0,0 @@ -//#define DEBUG_RELEASE 1 - -#ifdef DEBUG_RELEASE - #define _DEBUG 1 -#endif - -#ifdef _DEBUG - void init_debug(void); - void end_debug (void); - void do_log(const char *pszFormat, ...); - #define DEBUG_OUT(a) OUTPUT(a) - #define TRACE(a) OutputDebugString(a) - #define TRACEA(a) OutputDebugStringA(a) - #define TRACEW(a) OutputDebugStringW(a) - #define LOG(a) do_log a -#else - #define DEBUG_OUT(a) - #define LOG(a) - #define TRACE(a) - #define TRACEA(a) - #define TRACEW(a) -#endif - diff --git a/!NotAdopted/Skype/deploy.bat b/!NotAdopted/Skype/deploy.bat deleted file mode 100644 index eee9e164d1..0000000000 --- a/!NotAdopted/Skype/deploy.bat +++ /dev/null @@ -1,15 +0,0 @@ -@echo off -set PATH=%PATH%;C:\Programme\WinRAR -echo Deploying.. -winrar a -apPlugins -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol.zip Release\skype.dll -rem There is no ANSI x64 Build -rem winrar a -apPlugins -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_x64.zip Release64\skype.dll -winrar a -apPlugins -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_unicode.zip Release-UNICODE\skype.dll -winrar a -apPlugins -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_unicode_x64.zip Release64-UNICODE\skype.dll - -winrar a -apDebug -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_debug.zip Debug\skype.pdb -winrar a -apDebug\Plugins -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_debug.zip Debug\skype.dll -winrar a -apDebug64-UNICODE -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_debug.zip Debug64-UNICODE\skype.pdb -winrar a -apDebug64-UNICODE\Plugins -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_debug.zip Debug64-UNICODE\skype.dll -winrar a -apDebug-UNICODE -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_debug.zip Debug-UNICODE\skype.pdb -winrar a -apDebug-UNICODE\Plugins -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_debug.zip Debug-UNICODE\skype.dll diff --git a/!NotAdopted/Skype/ezxml/ezxml.c b/!NotAdopted/Skype/ezxml/ezxml.c deleted file mode 100644 index 24c02fbd70..0000000000 --- a/!NotAdopted/Skype/ezxml/ezxml.c +++ /dev/null @@ -1,1033 +0,0 @@ -/* ezxml.c - * - * Copyright 2004-2006 Aaron Voisine - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#if defined(WIN32) || defined(_WIN32) -#include -#ifndef EZXML_NOMMAP -#define EZXML_NOMMAP -#endif -#endif - -#include -#include -#include -#include -#include -#if !defined(WIN32) && !defined(_WIN32) -#include -#endif -#include -#ifndef EZXML_NOMMAP -#include -#endif // EZXML_NOMMAP -#include -#include "ezxml.h" - -#if defined(WIN32) || defined(_WIN32) -#define vsnprintf _vsnprintf -#define snprintf _snprintf -#define open _open -#define read _read -#define write _write -#define close _close -#endif - -#define EZXML_WS "\t\r\n " // whitespace -#define EZXML_ERRL 128 // maximum error string length - -typedef struct ezxml_root *ezxml_root_t; -struct ezxml_root { // additional data for the root tag - struct ezxml xml; // is a super-struct built on top of ezxml struct - ezxml_t cur; // current xml tree insertion point - char *m; // original xml string - size_t len; // length of allocated memory for mmap, -1 for malloc - char *u; // UTF-8 conversion of string if original was UTF-16 - char *s; // start of work area - char *e; // end of work area - char **ent; // general entities (ampersand sequences) - char ***attr; // default attributes - char ***pi; // processing instructions - short standalone; // non-zero if - char err[EZXML_ERRL]; // error string -}; - -char *EZXML_NIL[] = { NULL }; // empty, null terminated array of strings - -// returns the first child tag with the given name or NULL if not found -ezxml_t ezxml_child(ezxml_t xml, const char *name) -{ - xml = (xml) ? xml->child : NULL; - while (xml && strcmp(name, xml->name)) xml = xml->sibling; - return xml; -} - -// returns the Nth tag with the same name in the same subsection or NULL if not -// found -ezxml_t ezxml_idx(ezxml_t xml, int idx) -{ - for (; xml && idx; idx--) xml = xml->next; - return xml; -} - -// returns the value of the requested tag attribute or NULL if not found -const char *ezxml_attr(ezxml_t xml, const char *attr) -{ - int i = 0, j = 1; - ezxml_root_t root = (ezxml_root_t)xml; - - if (! xml || ! xml->attr) return NULL; - while (xml->attr[i] && strcmp(attr, xml->attr[i])) i += 2; - if (xml->attr[i]) return xml->attr[i + 1]; // found attribute - - while (root->xml.parent) root = (ezxml_root_t)root->xml.parent; // root tag - for (i = 0; root->attr[i] && strcmp(xml->name, root->attr[i][0]); i++); - if (! root->attr[i]) return NULL; // no matching default attributes - while (root->attr[i][j] && strcmp(attr, root->attr[i][j])) j += 3; - return (root->attr[i][j]) ? root->attr[i][j + 1] : NULL; // found default -} - -// same as ezxml_get but takes an already initialized va_list -ezxml_t ezxml_vget(ezxml_t xml, va_list ap) -{ - char *name = va_arg(ap, char *); - int idx = -1; - - if (name && *name) { - idx = va_arg(ap, int); - xml = ezxml_child(xml, name); - } - return (idx < 0) ? xml : ezxml_vget(ezxml_idx(xml, idx), ap); -} - -// Traverses the xml tree to retrieve a specific subtag. Takes a variable -// length list of tag names and indexes. The argument list must be terminated -// by either an index of -1 or an empty string tag name. Example: -// title = ezxml_get(library, "shelf", 0, "book", 2, "title", -1); -// This retrieves the title of the 3rd book on the 1st shelf of library. -// Returns NULL if not found. -ezxml_t ezxml_get(ezxml_t xml, ...) -{ - va_list ap; - ezxml_t r; - - va_start(ap, xml); - r = ezxml_vget(xml, ap); - va_end(ap); - return r; -} - -// returns a null terminated array of processing instructions for the given -// target -const char **ezxml_pi(ezxml_t xml, const char *target) -{ - ezxml_root_t root = (ezxml_root_t)xml; - int i = 0; - - if (! root) return (const char **)EZXML_NIL; - while (root->xml.parent) root = (ezxml_root_t)root->xml.parent; // root tag - while (root->pi[i] && strcmp(target, root->pi[i][0])) i++; // find target - return (const char **)((root->pi[i]) ? root->pi[i] + 1 : EZXML_NIL); -} - -// set an error string and return root -ezxml_t ezxml_err(ezxml_root_t root, char *s, const char *err, ...) -{ - va_list ap; - int line = 1; - char *t, fmt[EZXML_ERRL]; - - for (t = root->s; t < s; t++) if (*t == '\n') line++; - snprintf(fmt, EZXML_ERRL, "[error near line %d]: %s", line, err); - - va_start(ap, err); - vsnprintf(root->err, EZXML_ERRL, fmt, ap); - va_end(ap); - - return &root->xml; -} - -// Recursively decodes entity and character references and normalizes new lines -// ent is a null terminated array of alternating entity names and values. set t -// to '&' for general entity decoding, '%' for parameter entity decoding, 'c' -// for cdata sections, ' ' for attribute normalization, or '*' for non-cdata -// attribute normalization. Returns s, or if the decoded string is longer than -// s, returns a malloced string that must be freed. -char *ezxml_decode(char *s, char **ent, char t) -{ - char *e, *r = s, *m = s; - long b, c, d, l; - - for (; *s; s++) { // normalize line endings - while (*s == '\r') { - *(s++) = '\n'; - if (*s == '\n') memmove(s, (s + 1), strlen(s)); - } - } - - for (s = r; ; ) { - while (*s && *s != '&' && (*s != '%' || t != '%') && !isspace(*s)) s++; - - if (! *s) break; - else if (t != 'c' && ! strncmp(s, "&#", 2)) { // character reference - if (s[2] == 'x') c = strtol(s + 3, &e, 16); // base 16 - else c = strtol(s + 2, &e, 10); // base 10 - if (! c || *e != ';') { s++; continue; } // not a character ref - - if (c < 0x80) *(s++) = c; // US-ASCII subset - else { // multi-byte UTF-8 sequence - for (b = 0, d = c; d; d /= 2) b++; // number of bits in c - b = (b - 2) / 5; // number of bytes in payload - *(s++) = (0xFF << (7 - b)) | (c >> (6 * b)); // head - while (b) *(s++) = 0x80 | ((c >> (6 * --b)) & 0x3F); // payload - } - - memmove(s, strchr(s, ';') + 1, strlen(strchr(s, ';'))); - } - else if ((*s == '&' && (t == '&' || t == ' ' || t == '*')) || - (*s == '%' && t == '%')) { // entity reference - for (b = 0; ent[b] && strncmp(s + 1, ent[b], strlen(ent[b])); - b += 2); // find entity in entity list - - if (ent[b++]) { // found a match - if ((c = strlen(ent[b])) - 1 > (e = strchr(s, ';')) - s) { - l = (d = (s - r)) + c + strlen(e); // new length - r = (r == m) ? strcpy(malloc(l), r) : realloc(r, l); - e = strchr((s = r + d), ';'); // fix up pointers - } - - memmove(s + c, e + 1, strlen(e)); // shift rest of string - strncpy(s, ent[b], c); // copy in replacement text - } - else s++; // not a known entity - } - else if ((t == ' ' || t == '*') && isspace(*s)) *(s++) = ' '; - else s++; // no decoding needed - } - - if (t == '*') { // normalize spaces for non-cdata attributes - for (s = r; *s; s++) { - if ((l = strspn(s, " "))) memmove(s, s + l, strlen(s + l) + 1); - while (*s && *s != ' ') s++; - } - if (--s >= r && *s == ' ') *s = '\0'; // trim any trailing space - } - return r; -} - -// called when parser finds start of new tag -void ezxml_open_tag(ezxml_root_t root, char *name, char **attr) -{ - ezxml_t xml = root->cur; - - if (xml->name) xml = ezxml_add_child(xml, name, strlen(xml->txt)); - else xml->name = name; // first open tag - - xml->attr = attr; - root->cur = xml; // update tag insertion point -} - -// called when parser finds character content between open and closing tag -void ezxml_char_content(ezxml_root_t root, char *s, size_t len, char t) -{ - ezxml_t xml = root->cur; - char *m = s; - size_t l; - - if (! xml || ! xml->name || ! len) return; // sanity check - - s[len] = '\0'; // null terminate text (calling functions anticipate this) - len = strlen(s = ezxml_decode(s, root->ent, t)) + 1; - - if (! *(xml->txt)) xml->txt = s; // initial character content - else { // allocate our own memory and make a copy - xml->txt = (xml->flags & EZXML_TXTM) // allocate some space - ? realloc(xml->txt, (l = strlen(xml->txt)) + len) - : strcpy(malloc((l = strlen(xml->txt)) + len), xml->txt); - strcpy(xml->txt + l, s); // add new char content - if (s != m) free(s); // free s if it was malloced by ezxml_decode() - } - - if (xml->txt != m) ezxml_set_flag(xml, EZXML_TXTM); -} - -// called when parser finds closing tag -ezxml_t ezxml_close_tag(ezxml_root_t root, char *name, char *s) -{ - if (! root->cur || ! root->cur->name || strcmp(name, root->cur->name)) - return ezxml_err(root, s, "unexpected closing tag ", name); - - root->cur = root->cur->parent; - return NULL; -} - -// checks for circular entity references, returns non-zero if no circular -// references are found, zero otherwise -int ezxml_ent_ok(char *name, char *s, char **ent) -{ - int i; - - for (; ; s++) { - while (*s && *s != '&') s++; // find next entity reference - if (! *s) return 1; - if (! strncmp(s + 1, name, strlen(name))) return 0; // circular ref. - for (i = 0; ent[i] && strncmp(ent[i], s + 1, strlen(ent[i])); i += 2); - if (ent[i] && ! ezxml_ent_ok(name, ent[i + 1], ent)) return 0; - } -} - -// called when the parser finds a processing instruction -void ezxml_proc_inst(ezxml_root_t root, char *s, size_t len) -{ - int i = 0, j = 1; - char *target = s; - - s[len] = '\0'; // null terminate instruction - if (*(s += strcspn(s, EZXML_WS))) { - *s = '\0'; // null terminate target - s += strspn(s + 1, EZXML_WS) + 1; // skip whitespace after target - } - - if (! strcmp(target, "xml")) { // - if ((s = strstr(s, "standalone")) && ! strncmp(s + strspn(s + 10, - EZXML_WS "='\"") + 10, "yes", 3)) root->standalone = 1; - return; - } - - if (! root->pi[0]) *(root->pi = malloc(sizeof(char **))) = NULL; //first pi - - while (root->pi[i] && strcmp(target, root->pi[i][0])) i++; // find target - if (! root->pi[i]) { // new target - root->pi = realloc(root->pi, sizeof(char **) * (i + 2)); - root->pi[i] = malloc(sizeof(char *) * 3); - root->pi[i][0] = target; - root->pi[i][1] = (char *)(root->pi[i + 1] = NULL); // terminate pi list - root->pi[i][2] = strdup(""); // empty document position list - } - - while (root->pi[i][j]) j++; // find end of instruction list for this target - root->pi[i] = realloc(root->pi[i], sizeof(char *) * (j + 3)); - root->pi[i][j + 2] = realloc(root->pi[i][j + 1], j + 1); - strcpy(root->pi[i][j + 2] + j - 1, (root->xml.name) ? ">" : "<"); - root->pi[i][j + 1] = NULL; // null terminate pi list for this target - root->pi[i][j] = s; // set instruction -} - -// called when the parser finds an internal doctype subset -short ezxml_internal_dtd(ezxml_root_t root, char *s, size_t len) -{ - char q, *c, *t, *n = NULL, *v, **ent, **pe; - int i, j; - - pe = memcpy(malloc(sizeof(EZXML_NIL)), EZXML_NIL, sizeof(EZXML_NIL)); - - for (s[len] = '\0'; s; ) { - while (*s && *s != '<' && *s != '%') s++; // find next declaration - - if (! *s) break; - else if (! strncmp(s, "'); - continue; - } - - for (i = 0, ent = (*c == '%') ? pe : root->ent; ent[i]; i++); - ent = realloc(ent, (i + 3) * sizeof(char *)); // space for next ent - if (*c == '%') pe = ent; - else root->ent = ent; - - *(++s) = '\0'; // null terminate name - if ((s = strchr(v, q))) *(s++) = '\0'; // null terminate value - ent[i + 1] = ezxml_decode(v, pe, '%'); // set value - ent[i + 2] = NULL; // null terminate entity list - if (! ezxml_ent_ok(n, ent[i + 1], ent)) { // circular reference - if (ent[i + 1] != v) free(ent[i + 1]); - ezxml_err(root, v, "circular entity declaration &%s", n); - break; - } - else ent[i] = n; // set entity name - } - else if (! strncmp(s, "")) == '>') continue; - else *s = '\0'; // null terminate tag name - for (i = 0; root->attr[i] && strcmp(n, root->attr[i][0]); i++); - - while (*(n = ++s + strspn(s, EZXML_WS)) && *n != '>') { - if (*(s = n + strcspn(n, EZXML_WS))) *s = '\0'; // attr name - else { ezxml_err(root, t, "malformed ") - 1; - if (*c == ' ') continue; // cdata is default, nothing to do - v = NULL; - } - else if ((*s == '"' || *s == '\'') && // default value - (s = strchr(v = s + 1, *s))) *s = '\0'; - else { ezxml_err(root, t, "malformed attr[i]) { // new tag name - root->attr = (! i) ? malloc(2 * sizeof(char **)) - : realloc(root->attr, - (i + 2) * sizeof(char **)); - root->attr[i] = malloc(2 * sizeof(char *)); - root->attr[i][0] = t; // set tag name - root->attr[i][1] = (char *)(root->attr[i + 1] = NULL); - } - - for (j = 1; root->attr[i][j]; j += 3); // find end of list - root->attr[i] = realloc(root->attr[i], - (j + 4) * sizeof(char *)); - - root->attr[i][j + 3] = NULL; // null terminate list - root->attr[i][j + 2] = c; // is it cdata? - root->attr[i][j + 1] = (v) ? ezxml_decode(v, root->ent, *c) - : NULL; - root->attr[i][j] = n; // attribute name - } - } - else if (! strncmp(s, ""); // comments - else if (! strncmp(s, ""))) - ezxml_proc_inst(root, c, s++ - c); - } - else if (*s == '<') s = strchr(s, '>'); // skip other declarations - else if (*(s++) == '%' && ! root->standalone) break; - } - - free(pe); - return ! *root->err; -} - -// Converts a UTF-16 string to UTF-8. Returns a new string that must be freed -// or NULL if no conversion was needed. -char *ezxml_str2utf8(char **s, size_t *len) -{ - char *u; - size_t l = 0, sl, max = *len; - long c, d; - int b, be = (**s == '\xFE') ? 1 : (**s == '\xFF') ? 0 : -1; - - if (be == -1) return NULL; // not UTF-16 - - u = malloc(max); - for (sl = 2; sl < *len - 1; sl += 2) { - c = (be) ? (((*s)[sl] & 0xFF) << 8) | ((*s)[sl + 1] & 0xFF) //UTF-16BE - : (((*s)[sl + 1] & 0xFF) << 8) | ((*s)[sl] & 0xFF); //UTF-16LE - if (c >= 0xD800 && c <= 0xDFFF && (sl += 2) < *len - 1) { // high-half - d = (be) ? (((*s)[sl] & 0xFF) << 8) | ((*s)[sl + 1] & 0xFF) - : (((*s)[sl + 1] & 0xFF) << 8) | ((*s)[sl] & 0xFF); - c = (((c & 0x3FF) << 10) | (d & 0x3FF)) + 0x10000; - } - - while (l + 6 > max) u = realloc(u, max += EZXML_BUFSIZE); - if (c < 0x80) u[l++] = c; // US-ASCII subset - else { // multi-byte UTF-8 sequence - for (b = 0, d = c; d; d /= 2) b++; // bits in c - b = (b - 2) / 5; // bytes in payload - u[l++] = (0xFF << (7 - b)) | (c >> (6 * b)); // head - while (b) u[l++] = 0x80 | ((c >> (6 * --b)) & 0x3F); // payload - } - } - return *s = realloc(u, *len = l); -} - -// frees a tag attribute list -void ezxml_free_attr(char **attr) { - int i = 0; - char *m; - - if (! attr || attr == EZXML_NIL) return; // nothing to free - while (attr[i]) i += 2; // find end of attribute list - m = attr[i + 1]; // list of which names and values are malloced - for (i = 0; m[i]; i++) { - if (m[i] & EZXML_NAMEM) free(attr[i * 2]); - if (m[i] & EZXML_TXTM) free(attr[(i * 2) + 1]); - } - free(m); - free(attr); -} - -// parse the given xml string and return an ezxml structure -ezxml_t ezxml_parse_str(char *s, size_t len) -{ - ezxml_root_t root = (ezxml_root_t)ezxml_new(NULL); - char q, e, *d, **attr, **a = NULL; // initialize a to avoid compile warning - int l, i, j; - - root->m = s; - if (! len) return ezxml_err(root, NULL, "root tag missing"); - root->u = ezxml_str2utf8(&s, &len); // convert utf-16 to utf-8 - root->e = (root->s = s) + len; // record start and end of work area - - e = s[len - 1]; // save end char - s[len - 1] = '\0'; // turn end char into null terminator - - while (*s && *s != '<') s++; // find first tag - if (! *s) return ezxml_err(root, s, "root tag missing"); - - for (; ; ) { - attr = (char **)EZXML_NIL; - d = ++s; - - if (isalpha(*s) || *s == '_' || *s == ':' || *s < '\0') { // new tag - if (! root->cur) - return ezxml_err(root, d, "markup outside of root element"); - - s += strcspn(s, EZXML_WS "/>"); - while (isspace(*s)) *(s++) = '\0'; // null terminate tag name - - if (*s && *s != '/' && *s != '>') // find tag in default attr list - for (i = 0; (a = root->attr[i]) && strcmp(a[0], d); i++); - - for (l = 0; *s && *s != '/' && *s != '>'; l += 2) { // new attrib - attr = (l) ? realloc(attr, (l + 4) * sizeof(char *)) - : malloc(4 * sizeof(char *)); // allocate space - attr[l + 3] = (l) ? realloc(attr[l + 1], (l / 2) + 2) - : malloc(2); // mem for list of maloced vals - strcpy(attr[l + 3] + (l / 2), " "); // value is not malloced - attr[l + 2] = NULL; // null terminate list - attr[l + 1] = ""; // temporary attribute value - attr[l] = s; // set attribute name - - s += strcspn(s, EZXML_WS "=/>"); - if (*s == '=' || isspace(*s)) { - *(s++) = '\0'; // null terminate tag attribute name - q = *(s += strspn(s, EZXML_WS "=")); - if (q == '"' || q == '\'') { // attribute value - attr[l + 1] = ++s; - while (*s && *s != q) s++; - if (*s) *(s++) = '\0'; // null terminate attribute val - else { - ezxml_free_attr(attr); - return ezxml_err(root, d, "missing %c", q); - } - - for (j = 1; a && a[j] && strcmp(a[j], attr[l]); j +=3); - attr[l + 1] = ezxml_decode(attr[l + 1], root->ent, (a - && a[j]) ? *a[j + 2] : ' '); - if (attr[l + 1] < d || attr[l + 1] > s) - attr[l + 3][l / 2] = EZXML_TXTM; // value malloced - } - } - while (isspace(*s)) s++; - } - - if (*s == '/') { // self closing tag - *(s++) = '\0'; - if ((*s && *s != '>') || (! *s && e != '>')) { - if (l) ezxml_free_attr(attr); - return ezxml_err(root, d, "missing >"); - } - ezxml_open_tag(root, d, attr); - ezxml_close_tag(root, d, s); - } - else if ((q = *s) == '>' || (! *s && e == '>')) { // open tag - *s = '\0'; // temporarily null terminate tag name - ezxml_open_tag(root, d, attr); - *s = q; - } - else { - if (l) ezxml_free_attr(attr); - return ezxml_err(root, d, "missing >"); - } - } - else if (*s == '/') { // close tag - s += strcspn(d = s + 1, EZXML_WS ">") + 1; - if (! (q = *s) && e != '>') return ezxml_err(root, d, "missing >"); - *s = '\0'; // temporarily null terminate tag name - if (ezxml_close_tag(root, d, s)) return &root->xml; - if (isspace(*s = q)) s += strspn(s, EZXML_WS); - } - else if (! strncmp(s, "!--", 3)) { // xml comment - if (! (s = strstr(s + 3, "--")) || (*(s += 2) != '>' && *s) || - (! *s && e != '>')) return ezxml_err(root, d, "unclosed Yes -// 0 --> No -int AnySkypeusers(void) -{ - HANDLE hContact; - DBVARIANT dbv; - int tCompareResult; - - // already on list? - for (hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - hContact != NULL; - hContact=(HANDLE)CallService( MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) - { - // GETCONTACTBASEPROTO doesn't work on not loaded protocol, therefore get - // protocol from DB - if (DBGetContactSettingString(hContact, "Protocol", "p", &dbv)) continue; - tCompareResult = !strcmp(dbv.pszVal, SKYPE_PROTONAME); - DBFreeVariant(&dbv); - if (tCompareResult) return 1; - } - return 0; -} - - -void UpgradeName(char *OldName) -{ - DBCONTACTENUMSETTINGS cns; - DBCONTACTWRITESETTING cws; - DBVARIANT dbv; - HANDLE hContact=NULL; - struct PLUGINDI pdi; - - LOG(("Updating old database settings if there are any...")); - cns.pfnEnumProc=EnumOldPluginName; - cns.lParam=(LPARAM)&pdi; - cns.szModule=OldName; - cns.ofsSettings=0; - - hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - - for ( ;; ) { - memset(&pdi,0,sizeof(pdi)); - CallService(MS_DB_CONTACT_ENUMSETTINGS,(WPARAM)hContact,(LPARAM)&cns); - // Upgrade Protocol settings to new string - if (pdi.szSettings) { - int i; - - LOG(("We're currently upgrading...")); - for (i=0;i 0 && !Miranda_Terminated()) { - TranslateMessage (&msg); - DispatchMessage (&msg); - } - UnregisterClass (WndClass.lpszClassName, hInst); - LOG (("Messagepump stopped.")); -} - -// DLL Stuff // - -__declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirVersion) -{ - mirandaVersion = mirVersion; - - pluginInfo.cbSize = sizeof(PLUGININFO); - return (PLUGININFO*) &pluginInfo; -} - -__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirVersion) -{ - mirandaVersion = mirVersion; - - return &pluginInfo; -} - -static const MUUID interfaces[] = {MUUID_SKYPE_CALL, MIID_LAST}; -__declspec(dllexport) const MUUID * MirandaPluginInterfaces(void) -{ - return interfaces; -} - - -BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) -{ - UNREFERENCED_PARAMETER(fdwReason); - UNREFERENCED_PARAMETER(lpvReserved); - - hInst = hinstDLL; - return TRUE; -} - - -int PreShutdown(WPARAM wParam, LPARAM lParam) { - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - - PostThreadMessage(msgPumpThreadId, WM_QUIT, 0, 0); - return 0; -} - -int __declspec(dllexport) Load(PLUGINLINK *link) -{ - PROTOCOLDESCRIPTOR pd; - DWORD Buffsize; - HKEY MyKey; - BOOL SkypeInstalled; - BOOL UseCustomCommand; - WSADATA wsaData; - char path[MAX_PATH]; - - pluginLink = link; - mir_getMMI( &mmi ); - //mir_getLP(&pluginInfo); - - GetModuleFileNameA( hInst, path, sizeof( path )); - _splitpath (path, NULL, NULL, SKYPE_PROTONAME, NULL); - CharUpperA( SKYPE_PROTONAME ); - - InitializeCriticalSection(&RingAndEndcallMutex); - InitializeCriticalSection(&QueryThreadMutex); - InitializeCriticalSection(&TimeMutex); - - -#ifdef _DEBUG - init_debug(); -#endif - - LOG(("Load: Skype Plugin loading...")); - - // We need to upgrade SKYPE_PROTOCOL internal name to Skype if not already done - if (!DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UpgradeDone", 0)) - UpgradeName("SKYPE_PROTOCOL"); - - // Initialisation of Skype MsgQueue must be done because of Cleanup in end and - // Mutex is also initialized here. - LOG(("SkypeMsgInit initializing Skype MSG-queue")); - if (SkypeMsgInit()==-1) { - OUTPUT(_T("Memory allocation error on startup.")); - return 0; - } - - // On first run on new profile, ask user, if he wants to enable the plugin in - // this profile - // --> Fixing Issue #0000006 from bugtracker. - if (!DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "FirstRun", 0)) { - DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "FirstRun", 1); - if (AnySkypeusers()==0) // First run, it seems :) - if (MessageBox(NULL, TranslateT("This seems to be the first time that you're running the Skype protocol plugin. Do you want to enable the protocol for this Miranda-Profile? (If you chose NO, you can always enable it in the plugin options later."), _T("Welcome!"), MB_ICONQUESTION|MB_YESNO)==IDNO) { - char path[MAX_PATH], *filename; - GetModuleFileNameA(hInst, path, sizeof(path)); - if (filename = strrchr(path,'\\')+1) - DBWriteContactSettingByte(NULL,"PluginDisable",filename,1); - return 0; - } - } - - - // Check if Skype is installed - SkypeInstalled=TRUE; - UseCustomCommand = (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseCustomCommand", 0); - UseSockets = (BOOL)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseSkype2Socket", 0); - - if (!UseSockets && !UseCustomCommand) - { - if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Skype\\Phone"), 0, KEY_READ, &MyKey)!=ERROR_SUCCESS) - { - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Skype\\Phone"), 0, KEY_READ, &MyKey)!=ERROR_SUCCESS) - { - SkypeInstalled=FALSE; - } - } - - Buffsize=sizeof(skype_path); - - if (SkypeInstalled==FALSE || RegQueryValueExA(MyKey, "SkypePath", NULL, NULL, (unsigned char *)skype_path, &Buffsize)!=ERROR_SUCCESS) - { - //OUTPUT("Skype was not found installed :( \nMaybe you are using portable skype."); - RegCloseKey(MyKey); - skype_path[0]=0; - //return 0; - } - RegCloseKey(MyKey); - } - WSAStartup(MAKEWORD(2,2), &wsaData); - - // Start Skype connection - if (!(ControlAPIAttach=RegisterWindowMessage(_T("SkypeControlAPIAttach"))) || !(ControlAPIDiscover=RegisterWindowMessage(_T("SkypeControlAPIDiscover")))) - { - OUTPUT(_T("Cannot register Window message.")); - return 0; - } - - SkypeMsgReceived=CreateSemaphore(NULL, 0, MAX_MSGS, NULL); - if (!(SkypeReady=CreateEvent(NULL, TRUE, FALSE, NULL)) || - !(MessagePumpReady=CreateEvent(NULL, FALSE, FALSE, NULL)) || -#ifdef SKYPEBUG_OFFLN - !(GotUserstatus=CreateEvent(NULL, TRUE, FALSE, NULL)) || -#endif - !(hBuddyAdded=CreateEvent(NULL, FALSE, FALSE, NULL)) || - !(FetchMessageEvent=CreateEvent(NULL, FALSE, TRUE, NULL))) { - OUTPUT(_T("Unable to create Mutex!")); - return 0; - } - - /* Register the module */ - ZeroMemory(&pd, sizeof(pd)); - pd.cbSize = sizeof(pd); - pd.szName = SKYPE_PROTONAME; - pd.type = PROTOTYPE_PROTOCOL; - CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd); - - VoiceServiceInit(); - - CreateServices(); - HookEvents(); - InitVSApi(); - MsgList_Init(); - - HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown); - - // Startup Message-pump - pthread_create (( pThreadFunc )MsgPump, NULL); - WaitForSingleObject(MessagePumpReady, INFINITE); - return 0; -} - - - -int __declspec( dllexport ) Unload(void) -{ - BOOL UseCustomCommand = DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseCustomCommand", 0); - BOOL Shutdown = DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "Shutdown", 0); - - LOG (("Unload started")); - - if ( Shutdown && ((skype_path && skype_path[0]) ||UseCustomCommand) ) { - - if(UseCustomCommand) - { - DBVARIANT dbv; - if(!DBGetContactSettingString(NULL,SKYPE_PROTONAME,"CommandLine",&dbv)) - { - char szAbsolutePath[MAX_PATH]; - - TranslateMirandaRelativePathToAbsolute(dbv.pszVal, szAbsolutePath, FALSE); - _spawnl(_P_NOWAIT, szAbsolutePath, szAbsolutePath, "/SHUTDOWN", NULL); - LOG (("Unload Sent /shutdown to %s", szAbsolutePath)); - DBFreeVariant(&dbv); - } - } - else - { - _spawnl(_P_NOWAIT, skype_path, skype_path, "/SHUTDOWN", NULL); - LOG (("Unload Sent /shutdown to %s", skype_path)); - } - - } - SkypeMsgCleanup(); - WSACleanup(); - FreeVSApi(); - UnhookEvents(); - UnhookEvent(hChatEvent); - UnhookEvent (hChatMenu); - UnhookEvent (hEvInitChat); - DestroyHookableEvent(hInitChat); - VoiceServiceExit(); - GCExit(); - MsgList_Exit(); - - CloseHandle(SkypeReady); - CloseHandle(SkypeMsgReceived); -#ifdef SKYPEBUG_OFFLN - CloseHandle(GotUserstatus); -#endif - CloseHandle(MessagePumpReady); - CloseHandle(hBuddyAdded); - CloseHandle(FetchMessageEvent); - - DeleteCriticalSection(&RingAndEndcallMutex); - DeleteCriticalSection(&QueryThreadMutex); - - SkypeRegisterProxy (0, 0); - LOG (("Unload: Shutdown complete")); -#ifdef _DEBUG - end_debug(); -#endif - DeleteCriticalSection(&TimeMutex); - return 0; -} - diff --git a/!NotAdopted/Skype/skype.h b/!NotAdopted/Skype/skype.h deleted file mode 100644 index 6439a24dc8..0000000000 --- a/!NotAdopted/Skype/skype.h +++ /dev/null @@ -1,188 +0,0 @@ -#pragma once - -#define _CRT_SECURE_NO_DEPRECATE 1 -#define TEXT_LEN 1024 -#define CP_ACP 0 - -#define code_page CP_ACP; -#define MIRANDA_CUSTOM_LP - - -// System includes -#include -#include -#include -#include -#include -#include "resource.h" -#include -#include -#include -#include -#include "util.h" - -#pragma warning (push) -#pragma warning (disable: 4100) // unreferenced formal parameter - -// Miranda Includes -#include "../../include/newpluginapi.h" -#include "../../include/m_utils.h" -#include "../../include/m_protosvc.h" -#include "../../include/m_protomod.h" -#include "../../include/m_skin.h" -#include "../../include/m_message.h" -#include "../../include/m_database.h" -#include "../../include/m_clist.h" -#include "../../include/m_system.h" -#include "sdk/m_updater.h" -#include "sdk/m_folders.h" -#include "../../include/m_options.h" -#include "../../include/m_langpack.h" -#include "../../include/m_userinfo.h" -#include "../../include/m_avatars.h" -#include "../../include/m_contacts.h" -#include "../../include/m_popup.h" - -#pragma warning (pop) - -// MyDetails defines - -// wParam=NULL -// lParam=(char *) new nickname - do not free -// return=0 for sucess -#define PS_SETMYNICKNAME "/SetNickname" - -// Optional, default value is 1024 -// wParam=NULL -// lParam=NULL -// return= <=0 for error, >0 the max length of the nick -#define PS_GETMYNICKNAMEMAXLENGTH "/GetMyNicknameMaxLength" - -// wParam=(char *)Buffer to file name -// lParam=(int)Buffer size -// return=0 for sucess -#define PS_GETMYAVATAR "/GetMyAvatar" - -// wParam=0 -// lParam=(const char *)Avatar file name -// return=0 for sucess -#define PS_SETMYAVATAR "/SetMyAvatar" - - -// Program defines -#define SKYPE_NAME "Username" -#define SKYPE_PROTO "PROTOCOL 7" -#define SKYPE_PROTONAME g_szProtoName // Name of our protocol, taken from .DLL name -#define MAX_MSGS 128 // Maximum messages in queue -#define MAX_USERLEN 32 // Maximum length of a username in Skype -#define PING_INTERVAL 10000 // Ping every 10000 msec to see if Skype is still available -#define USEPOPUP 1 // Use the popup-plugin? -#define TIMEOUT_MSGSEND 9000 // Stolen from msgdialog.c -#define MAX_MSG_AGE 30 // Maximum age in seconds before a Message from queue gets trashed -#define SKYPEBUG_OFFLN 1 // Activate fix for the SkypeAPI Offline-Bug - -// Program hooks -typedef struct { - char ChatNew[MAXMODULELABELLENGTH]; - char SetAvatar[MAXMODULELABELLENGTH]; - char SendFile[MAXMODULELABELLENGTH]; - char HoldCall[MAXMODULELABELLENGTH]; - char AnswerCall[MAXMODULELABELLENGTH]; - char ImportHistory[MAXMODULELABELLENGTH]; - char AddUser[MAXMODULELABELLENGTH]; - char SkypeOutCallUser[MAXMODULELABELLENGTH]; - char CallHangupUser[MAXMODULELABELLENGTH]; - char CallUser[MAXMODULELABELLENGTH]; -} SKYPE_SVCNAMES; -#define SKYPE_CALL g_svcNames.CallUser -#define SKYPE_CALLHANGUP g_svcNames.CallHangupUser -#define SKYPEOUT_CALL g_svcNames.SkypeOutCallUser -#define SKYPE_ADDUSER g_svcNames.AddUser -#define SKYPE_IMPORTHISTORY g_svcNames.ImportHistory -#define SKYPE_ANSWERCALL g_svcNames.AnswerCall -#define SKYPE_HOLDCALL g_svcNames.HoldCall -#define SKYPE_SENDFILE g_svcNames.SendFile -#define SKYPE_SETAVATAR g_svcNames.SetAvatar -#define SKYPE_CHATNEW g_svcNames.ChatNew -#define EVENTTYPE_CALL 2000 - -#ifndef __SKYPESVC_C__ -extern SKYPE_SVCNAMES g_svcNames; -#endif - -// Skype API Communication services -#define PSS_SKYPEAPIMSG "/SendSkypeAPIMsg" -#define SKYPE_REGPROXY "/RegisterProxySvc" - -#define MUUID_SKYPE_CALL { 0x245241eb, 0x178c, 0x4b3f, { 0x91, 0xa, 0x4c, 0x4d, 0xf0, 0xa0, 0xc3, 0xb6 } } - - -// Common used code-pieces -#define OUTPUT(a) ShowMessage(IDI_ERRORS, a, 1); -#define OUTPUTA(a) ShowMessageA(IDI_ERRORS, a, 1); - -typedef void ( __cdecl* pThreadFunc )( void* ); - -// Prototypes - -void __cdecl SkypeSystemInit(char *); -void __cdecl MsgPump (char *dummy); -void PingPong(void); -void CheckIfApiIsResponding(char *); -void TellError(DWORD err); -int ShowMessage(int, TCHAR*, int); -#ifdef _UNICODE -int ShowMessageA(int iconID, char *lpzText, int mustShow); -#else -#define ShowMessageA ShowMessage -#endif -void EndCallThread(char *); -void GetInfoThread(HANDLE); -int OnDetailsInit( WPARAM, LPARAM ); -INT_PTR SkypeGetAvatarInfo(WPARAM wParam,LPARAM lParam); -INT_PTR SkypeGetAvatarCaps(WPARAM wParam,LPARAM lParam); -INT_PTR SkypeGetAwayMessage(WPARAM wParam,LPARAM lParam); -int HookContactAdded(WPARAM wParam, LPARAM lParam); -int HookContactDeleted(WPARAM wParam, LPARAM lParam); -INT_PTR ImportHistory(WPARAM wParam, LPARAM lParam); -int CreateTopToolbarButton(WPARAM wParam, LPARAM lParam); -int OnModulesLoaded(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeSetStatus(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeGetStatus(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeGetInfo(WPARAM wParam,LPARAM lParam); -INT_PTR SkypeAddToList(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeBasicSearch(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeSendMessage(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeRecvMessage(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeUserIsTyping(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeSendAuthRequest(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeRecvAuth(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeAuthAllow(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeAuthDeny(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeAddToListByEvent(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeRegisterProxy(WPARAM wParam, LPARAM lParam); -time_t SkypeTime(time_t *timer); -void MessageSendWatchThread(HANDLE hContact); -int OkToExit(WPARAM wParam, LPARAM lParam); -int MirandaExit(WPARAM wParam, LPARAM lParam); -int __stdcall EnterBitmapFileName( char* szDest ); -void CleanupNicknames(char *dummy); -int InitVSApi(); -int FreeVSApi(); -HANDLE GetMetaHandle(DWORD dwId); -void LaunchSkypeAndSetStatusThread(void *newStatus); - -// Write contact setting as UTF-8 for convenience, if possible. Older Miranda IM versions will store it as ANSI -INT_PTR SkypeDBWriteContactSettingUTF8String(HANDLE hContact,const char *szModule,const char *szSetting,const char *val); - -// Structs - -typedef struct { - char *SkypeSetting; - char *MirandaSetting; -} settings_map; - -// Optional includes -#ifdef USEPOPUP - #include "../../include/m_popup.h" -#endif diff --git a/!NotAdopted/Skype/skypeapi.c b/!NotAdopted/Skype/skypeapi.c deleted file mode 100644 index 2a6eb1b76e..0000000000 --- a/!NotAdopted/Skype/skypeapi.c +++ /dev/null @@ -1,1699 +0,0 @@ -/* - * SkypeAPI - All more or less important functions that deal with Skype - */ - -#include "skype.h" -#include "skypeapi.h" -#include "utf8.h" -#include "debug.h" -#include "contacts.h" -#include "skypeproxy.h" -#include "pthread.h" -#include "gchat.h" -#include "alogon.h" -#include "msgq.h" -#pragma warning (push) -#pragma warning (disable: 4100) // unreferenced formal parameter -#include "../../include/m_utils.h" -#include "../../include/m_langpack.h" -#pragma warning (push) -#include "m_toptoolbar.h" - -#pragma warning (disable: 4706) // assignment within conditional expression - -// Imported Globals -extern HWND hSkypeWnd, g_hWnd; -extern BOOL SkypeInitialized, UseSockets, MirandaShuttingDown, bIsImoproxy; -extern int SkypeStatus, receivers; -extern HANDLE SkypeReady, SkypeMsgReceived, httbButton; -extern UINT ControlAPIAttach, ControlAPIDiscover; -extern LONG AttachStatus; -extern HINSTANCE hInst; -extern PLUGININFO pluginInfo; -extern HANDLE hProtocolAvatarsFolder, hHookSkypeApiRcv; -extern char DefaultAvatarsFolder[MAX_PATH+1], *pszProxyCallout, protocol, g_szProtoName[]; - -// -> Skype Message Queue functions // - -static TYP_MSGQ SkypeMsgs, SkypeSendQueue; - -status_map status_codes[] = { - {ID_STATUS_AWAY, "AWAY"}, - {ID_STATUS_NA, "NA"}, - {ID_STATUS_DND, "DND"}, - {ID_STATUS_ONLINE, "ONLINE"}, - {ID_STATUS_FREECHAT, "SKYPEME"}, // Unfortunately Skype API tells us userstatus ONLINE, if we are free for chat - {ID_STATUS_OFFLINE, "OFFLINE"}, - {ID_STATUS_INVISIBLE, "INVISIBLE"}, - {ID_STATUS_CONNECTING, "CONNECTING"}, - {0, NULL} -}; - -//status_map - - -static CRITICAL_SECTION ConnectMutex; -static BOOL rcvThreadRunning=FALSE, isConnecting = FALSE; -static SOCKET ClientSocket=INVALID_SOCKET; -static HANDLE SkypeMsgToSend=NULL; - -static char *m_szSendBuf = NULL; -static DWORD m_iBufSize = 0; - - -static int _ConnectToSkypeAPI(char *path, BOOL bStart); - - -/* SkypeReceivedMessage - * - * Purpose: Hook to be called when a message is received, if some caller is - * using our internal I/O services. - * Params : wParam - Not used - * lParam - COPYDATASTRUCT like in WM_COPYDATA - * Returns: Result from SendMessage - */ -INT_PTR SkypeReceivedAPIMessage(WPARAM wParam, LPARAM lParam) { - return SendMessage(g_hWnd, WM_COPYDATA, (WPARAM)hSkypeWnd, lParam); -} - -/* - * Skype via Socket --> Skype2Socket connection - */ - -void rcvThread(char *dummy) { - unsigned int length; - char *buf; - COPYDATASTRUCT CopyData; - int rcv; - - if (!UseSockets) return; - rcvThreadRunning=TRUE; - for ( ;; ) { - if (ClientSocket==INVALID_SOCKET) { - rcvThreadRunning=FALSE; - return; - } - LOG(("rcvThread Receiving from socket..")); - if ((rcv=recv(ClientSocket, (char *)&length, sizeof(length), 0))==SOCKET_ERROR || rcv==0) { - rcvThreadRunning=FALSE; - if (rcv==SOCKET_ERROR) {LOG(("rcvThread Socket error"));} - else {LOG(("rcvThread lost connection, graceful shutdown"));} - return; - } - LOG(("rcvThread Received length, recieving message..")); - buf=(char *)calloc(1, length+1); - if ((rcv = recv(ClientSocket, buf, length, 0))==SOCKET_ERROR || rcv==0) { - rcvThreadRunning=FALSE; - if (rcv==SOCKET_ERROR) {LOG(("rcvThread Socket error"));} - else {LOG(("rcvThread lost connection, graceful shutdown"));} - free(buf); - return; - } - LOG(("Received message: %s", buf)); - - CopyData.dwData=0; - CopyData.lpData=buf; - CopyData.cbData=(DWORD)strlen(buf)+1; - if (!SendMessage(g_hWnd, WM_COPYDATA, (WPARAM)hSkypeWnd, (LPARAM)&CopyData)) - { - LOG(("SendMessage failed: %08X", GetLastError())); - } - free(buf); - } -} - -void sendThread(char *dummy) { - COPYDATASTRUCT CopyData; - LRESULT SendResult; - int oldstatus; - unsigned int length; - char *szMsg; - - while (SkypeMsgToSend) { - if (WaitForSingleObject(SkypeMsgToSend, INFINITE) != WAIT_OBJECT_0) return; - if (!(szMsg = MsgQ_Get(&SkypeSendQueue))) continue; - length=(unsigned int)strlen(szMsg); - - if (UseSockets) { - if (send(ClientSocket, (char *)&length, sizeof(length), 0) != SOCKET_ERROR && - send(ClientSocket, szMsg, length, 0) != SOCKET_ERROR) { - free (szMsg); - continue; - } - SendResult = 0; - } else { - CopyData.dwData=0; - CopyData.lpData=szMsg; - CopyData.cbData=length+1; - - // Internal comm channel - if (pszProxyCallout) { - CallService (pszProxyCallout, 0, (LPARAM)&CopyData); - free(szMsg); - continue; - } - - // If this didn't work, proceed with normal Skype API - if (!hSkypeWnd) - { - LOG(("SkypeSend: DAMN! No Skype window handle! :(")); - } - SendResult=SendMessage(hSkypeWnd, WM_COPYDATA, (WPARAM)g_hWnd, (LPARAM)&CopyData); - LOG(("SkypeSend: SendMessage returned %d", SendResult)); - free(szMsg); - } - if (!SendResult) { - SkypeInitialized=FALSE; - AttachStatus=-1; - ResetEvent(SkypeReady); - if (g_hWnd) KillTimer (g_hWnd, 1); - if (SkypeStatus!=ID_STATUS_OFFLINE) { - // Go offline - logoff_contacts(FALSE); - oldstatus=SkypeStatus; - InterlockedExchange((long *)&SkypeStatus, (int)ID_STATUS_OFFLINE); - ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldstatus, SkypeStatus); - } - // Reconnect to Skype - ResetEvent(SkypeReady); - pthread_create(LaunchSkypeAndSetStatusThread, (void *)ID_STATUS_ONLINE); - WaitForSingleObject (SkypeReady, 10000); - // SendMessageTimeout(HWND_BROADCAST, ControlAPIDiscover, (WPARAM)g_hWnd, 0, SMTO_ABORTIFHUNG, 3000, NULL); - } - } -} - - -/* - * Skype Messagequeue - Implemented as a linked list - */ - -/* SkypeMsgInit - * - * Purpose: Initializes the Skype Message queue and API - * Returns: 0 - Success - * -1 - Memory allocation failure - */ -int SkypeMsgInit(void) { - - MsgQ_Init(&SkypeMsgs); - MsgQ_Init(&SkypeSendQueue); - InitializeCriticalSection(&ConnectMutex); - if (SkypeMsgToSend=CreateSemaphore(NULL, 0, MAX_MSGS, NULL)) { - if (m_szSendBuf = malloc(m_iBufSize=512)) { - if (_beginthread(( pThreadFunc )sendThread, 0, NULL)!=-1) - return 0; - free(m_szSendBuf); - } - CloseHandle (SkypeMsgToSend); - } - return -1; -} - -/* SkypeMsgAdd - * - * Purpose: Add Message to linked list - * Params : msg - Message to add to queue - * Returns: 0 - Success - * -1 - Memory allocation failure - */ -int SkypeMsgAdd(char *msg) { - return MsgQ_Add(&SkypeMsgs, msg)?0:-1; -} - -/* SkypeMsgCleanup - * - * Purpose: Clean up the whole MESSagequeue - free() all - */ -void SkypeMsgCleanup(void) { - int i; - - LOG(("SkypeMsgCleanup Cleaning up message queue..")); - if (receivers>1) - { - LOG (("SkypeMsgCleanup Releasing %d receivers", receivers)); - for (i=0;i %s", szMsg)); - - // Fake PING-PONG, as PING-PONG is not supported by Skype2Socket - if ((UseSockets || bIsImoproxy) && !strcmp(szMsg, "PING")) { - CopyData.dwData=0; - CopyData.lpData="PONG"; - CopyData.cbData=5; - SendMessage(g_hWnd, WM_COPYDATA, (WPARAM)hSkypeWnd, (LPARAM)&CopyData); - return 0; - } - - if (UseSockets && ClientSocket==INVALID_SOCKET) return -1; - if (!MsgQ_Add(&SkypeSendQueue, szMsg) || !ReleaseSemaphore(SkypeMsgToSend, 1, NULL)) - return -1; - return 0; -} - -/* SkypeSend - * - * Purpose: Sends the specified message to the Skype API. - * If it fails, try to reconnect zu the Skype API - * Params: use like sprintf without first param (dest. buffer) - * Returns: 0 - Success - * -1 - Failure - */ -int SkypeSend(char *szFmt, ...) { - char *pNewBuf; - va_list ap; - size_t iLen; - - // 0.0.0.17+ - Build message-String from supplied parameter list - // so the user doesn't have to care about memory allocation any more. - // 0.0.0.47+ - No more restrictions apply to the format string. - // The temporary buffer remains allocated during the session and gets - // dynamically expanded when needed. This makes sense, as this function - // is used very often and therefore it is faster to not allocate - // memory on every send. - if (!m_szSendBuf && !(m_szSendBuf=malloc(m_iBufSize=512))) return -1; - do - { - va_start(ap, szFmt); - iLen = _vsnprintf(m_szSendBuf, m_iBufSize, szFmt, ap); - va_end(ap); - if (iLen == -1) - { - if (!(pNewBuf = (char*)realloc (m_szSendBuf, m_iBufSize*2))) - { - iLen = strlen (m_szSendBuf); - break; - } - m_szSendBuf = pNewBuf; - m_iBufSize*=2; - } - } while (iLen == -1); - - return __sendMsg(m_szSendBuf); -} - -/* SkypeRcvTime - * - * Purpose: Wait, until either the message "what" is received or maxwait-Time has passed - * or there was an error and return it - * Params : what - Wait for this string-part at the beginning of a received string - * If the first character of the string is NULL, the rest after the NULL - * character will be searched in the entire received message-string. - * You can tokenize the string by using NULL characters. - * You HAVE TO end the string with a extra \0, otherwise the tokenizer - * will run amok in memory! - * st - The message timestamp must be newer or equal to st. - * Set to 0, if you do not need this and want the first message of this - * kind in the queue. - * maxwait - Wait this time before returning, if nothing was received, - * can be INFINITE - * Returns: The received message containing "what" or a ERROR-Message or NULL if - * time is up and nothing was received - * Warning: Don't forget to free() return value! - */ -char *SkypeRcvTime(char *what, time_t st, DWORD maxwait) { - char *msg, *token=NULL; - struct MsgQueue *ptr; - int j; - DWORD dwWaitStat; - BOOL bChatMsg = FALSE, bIsChatMsg = FALSE; - - LOG (("SkypeRcv - Requesting answer: %s", what)); - if (what) bChatMsg = strncmp(what, "CHATMESSAGE", 11)==0; - do { - EnterCriticalSection(&SkypeMsgs.cs); - // First, search for the requested message. On second run, also accept an ERROR - for (j=0; j<2; j++) - { - for (ptr=SkypeMsgs.l.tqh_first; ptr; ptr=ptr->l.tqe_next) { - if (what && what[0]==0) { - // Tokenizer syntax active - token=what+1; - while (*token) { - if (!strstr (ptr->message, token)) { - token=NULL; - break; - } - token+=strlen(token)+1; - } - } - - //if (j==1) {LOG(("SkypeRcv compare %s (%lu) -- %s (%lu)", ptr->message, ptr->tReceived, what, st));} - if ((st == 0 || ptr->tReceived >= st) && - (what==NULL || token || (what[0] && !strncmp(ptr->message, what, strlen(what))) || - (bIsChatMsg = (j==1 && bChatMsg && !strncmp(ptr->message, what+4, strlen(what+4)))) || - (j==1 && !strncmp(ptr->message, "ERROR", 5)))) - { - msg=MsgQ_RemoveMsg(&SkypeMsgs, ptr); - LOG(("1) InterlockedDecrement ((long *)&receivers); // receivers--; - if (receivers>1) {LOG (("SkypeRcv: %d receivers still waiting", receivers));} - - } while(dwWaitStat == WAIT_OBJECT_0 && !MirandaShuttingDown); - InterlockedDecrement ((long *)&receivers); - LOG(("message, what)); - pCurMsg = ptr->message; - bIsError = FALSE; - if (*what && !strncmp(pCurMsg, what, iLenWhat)) { - // Now we received a MESSAGE with an identifier. So this one is definitely for us - // However the status can be SENDING instead of SENT and next message with this number - // isn't using the ID anymore, so we have to save the ID as new identifier for message recognition - pCurMsg+=iLenWhat; - if ((pMsg = strchr (pCurMsg, ' ')) && (pMsg=strchr (pMsg+1, ' '))) - strncpy (msgid, pCurMsg, pMsg-pCurMsg); - else if (strncmp (pCurMsg, "ERROR", 5) == 0) bIsError = TRUE; - } - - if ((*msgid && strncmp (pCurMsg, msgid, strlen(msgid)) == 0) || - (!*what && ptr->tReceived >= st && - (strncmp(pCurMsg, "MESSAGE", 7) == 0 || strncmp(pCurMsg, "CHATMESSAGE", 11) == 0 ) - ) || bIsError || - (ptr->tReceived >= st && ptr->tReceived <=st+1 && - (bIsError=(strncmp(pCurMsg, "ERROR 26", 8)==0 || strncmp(pCurMsg, "ERROR 43", 8)==0)) - ) ) - { - bProcess = bIsError; - if (!bIsError) { - if ((pMsg = strchr (pCurMsg, ' ')) && (pMsg=strchr (pMsg+1, ' '))) { - pMsg++; - if (strncmp (pMsg, "STATUS ", 7) == 0) { - pMsg+=7; - if (strcmp (pMsg, "SENDING") == 0 && - DBGetContactSettingWord(hContact, SKYPE_PROTONAME, "Status", ID_STATUS_OFFLINE)!=ID_STATUS_OFFLINE) { - // Remove dat shit - struct MsgQueue *ptr_=ptr->l.tqe_next; - - free(MsgQ_RemoveMsg(&SkypeMsgs, ptr)); - ptr=ptr_; - continue; - } - bProcess = (strcmp (pMsg, "SENT") == 0 || strcmp (pMsg, "QUEUED") == 0 || - strcmp (pMsg, "FAILED") == 0 || strcmp (pMsg, "IGNORED") == 0 || - strcmp (pMsg, "SENDING") == 0); - } - } - } - if (bProcess) { - msg=MsgQ_RemoveMsg(&SkypeMsgs, ptr); - LOG(("l.tqe_next; - } - LeaveCriticalSection(&SkypeMsgs.cs); - InterlockedIncrement ((long *)&receivers); //receivers++; - dwWaitStat = WaitForSingleObject(SkypeMsgReceived, maxwait); - if (receivers>1) InterlockedDecrement ((long *)&receivers); // receivers--; - if (receivers>1) {LOG (("SkypeRcvMsg: %d receivers still waiting", receivers));} - - } while(dwWaitStat == WAIT_OBJECT_0 && !MirandaShuttingDown); - InterlockedDecrement ((long *)&receivers); - LOG((" Answer %s", str, ptr)); - return ptr; -} - -char *SkypeGetID(char *szWhat, char *szWho, char *szProperty) { - char szID[16]={0}; - static DWORD dwId = 0; - - if (protocol>=4 || bIsImoproxy) sprintf (szID, "#G%d ", dwId++); - return __SkypeGet (szID, szWhat, szWho, szProperty); -} - -char *SkypeGet(char *szWhat, char *szWho, char *szProperty) { - return __SkypeGet ("", szWhat, szWho, szProperty); -} - -#ifdef _UNICODE -WCHAR *SkypeGetW(char *szWhat, WCHAR *szWho, char *szProperty) { - char *ptszWho = (char*)make_utf8_string(szWho); - char *pRet = SkypeGet (szWhat, ptszWho, szProperty); - free (ptszWho); - if (pRet) { - WCHAR *ptr = make_unicode_string((const unsigned char*)pRet); - free (pRet); - return ptr; - } - return NULL; -} -#endif - -char *SkypeGetErr(char *szWhat, char *szWho, char *szProperty) { - char *ret = SkypeGet(szWhat, szWho, szProperty); - if (ret && !strncmp(ret, "ERROR", 5)) { - free (ret); - return NULL; - } - return ret; -} - -#ifdef _UNICODE -WCHAR *SkypeGetErrW(char *szWhat, TCHAR *szWho, char *szProperty) { - WCHAR *ret = SkypeGetW(szWhat, szWho, szProperty); - if (ret && !_tcsncmp(ret, _T("ERROR"), 5)) { - free (ret); - return NULL; - } - return ret; -} -#endif - - -/* SkypeGetProfile - * - * Issues a SET PROFILE szProperty szValue and waits until the answer is received - * Returns the answer or NULL on failure - * BEWARE: Don't forget to free() return value! - * - * For example: SkypeGetProfile("FULLNAME", "Tweety"); -*/ -char *SkypeGetProfile(char *szProperty) { - return SkypeGet ("PROFILE", "", szProperty); -} - -/* SkypeSetProfile - * - * -*/ -int SkypeSetProfile(char *szProperty, char *szValue) { - return SkypeSend("SET PROFILE %s %s", szProperty, szValue); -} - -/* SkypeMsgCollectGarbage - * - * Purpose: Runs the garbage collector on the Skype Message-Queue to throw out old - * messages which may unnecessarily eat up memory. - * Params : age - Time in seconds. Messages older than this value will be - * thrown out. - * Returns: 0 - No messages were thrown out - * >0 - n messages were thrown out - */ -int SkypeMsgCollectGarbage(time_t age) { - return MsgQ_CollectGarbage(&SkypeMsgs, age); -} - - -/* SkypeCall - * - * Purpose: Give a Skype call to the given User in wParam - * or hangs up existing call - * (hangUp is moved over to SkypeCallHangup) - * Params : wParam - Handle to the User to be called - * lParam - Can be NULL - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeCall(WPARAM wParam, LPARAM lParam) { - DBVARIANT dbv; - char *msg=0; - int res; - - if (!DBGetContactSettingString((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { - res = -1; // no direct return, because dbv needs to be freed - } else { - if (DBGetContactSettingString((HANDLE)wParam, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) return -1; - msg=(char *)malloc(strlen(dbv.pszVal)+6); - strcpy(msg, "CALL "); - strcat(msg, dbv.pszVal); - res=SkypeSend(msg); - } - DBFreeVariant(&dbv); - free(msg); - return res; -} - -/* SkypeCallHangup - * - * Prupose: Hangs up the existing call to the given User - * in wParam. - * - * Params : wParam - Handle to the User to be called - * lParam - Can be NULL - * - * Returns: 0 - Success - * -1 - Failure - * - */ -INT_PTR SkypeCallHangup(WPARAM wParam, LPARAM lParam) -{ - DBVARIANT dbv; - char *msg=0; - int res = -1; - - if (!DBGetContactSettingString((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { - msg=(char *)malloc(strlen(dbv.pszVal)+21); - sprintf(msg, "SET %s STATUS FINISHED", dbv.pszVal); - //sprintf(msg, "ALTER CALL %s HANGUP", dbv.pszVal); - res=SkypeSend(msg); -#if _DEBUG - DBDeleteContactSetting((HANDLE)wParam, SKYPE_PROTONAME, "CallId"); -#endif - //} else { - // if (DBGetContactSetting((HANDLE)wParam, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) return -1; - // msg=(char *)malloc(strlen(dbv.pszVal)+6); - // strcpy(msg, "CALL "); - // strcat(msg, dbv.pszVal); - // res=SkypeSend(msg); - } - DBFreeVariant(&dbv); - free(msg); - return res; -} - -/* FixNumber - * - * Purpose: Eliminates all non-numeric chars from the given phonenumber - * Params : p - Pointer to the buffer with the number - */ -static void FixNumber(char *p) { - unsigned int i; - - for (i=0;i<=strlen(p);i++) - if ((p[i]<'0' || p[i]>'9')) - if (p[i]) { - memmove(p+i, p+i+1, strlen(p+i)); - i--; - } else break; -} - - -/* DialDlgProc - * - * Purpose: Dialog procedure for the Dial-Dialog - */ -static BOOL CALLBACK DialDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - static HANDLE hContact; - static unsigned int entries=0; - BOOL TempAdded=FALSE; - char number[64], *msg, *ptr=NULL; - - switch (uMsg){ - case WM_INITDIALOG: - hContact=(HANDLE)lParam; - Utils_RestoreWindowPosition(hwndDlg, NULL, SKYPE_PROTONAME, "DIALdlg"); - TranslateDialogDefault(hwndDlg); - - if (lParam) { - DBVARIANT dbv; - BOOL bDialNow=TRUE; - - if (!DBGetContactSetting(hContact,"UserInfo","MyPhone1",&dbv)) { - int j; - char idstr[16]; - - // Multiple phone numbers, select one - bDialNow=FALSE; - DBFreeVariant(&dbv); - for(j=0;;j++) { - sprintf(idstr,"MyPhone%d",j); - if(DBGetContactSettingString(hContact,"UserInfo",idstr,&dbv)) break; - FixNumber(dbv.pszVal+1); // Leave + alone - SendDlgItemMessage(hwndDlg,IDC_NUMBER,CB_ADDSTRING,0,(LPARAM)dbv.pszVal); - DBFreeVariant(&dbv); - } - } - if (DBGetContactSettingString(hContact,SKYPE_PROTONAME,"SkypeOutNr",&dbv)) { - DBGetContactSettingString(hContact,"UserInfo","MyPhone0",&dbv); - FixNumber(dbv.pszVal+1); - } - SetDlgItemTextA(hwndDlg, IDC_NUMBER, dbv.pszVal); - DBFreeVariant(&dbv); - if (bDialNow) PostMessage(hwndDlg, WM_COMMAND, IDDIAL, 0); - } else { - DBVARIANT dbv; - char number[64]; - - for (entries=0;entriesMAX_ENTRIES) entries=MAX_ENTRIES; - for (i=entries;i>0;i--) { - sprintf(buf, "LastNumber%d", i-1); - if (!DBGetContactSettingString(NULL, SKYPE_PROTONAME, buf, &dbv)) { - sprintf(buf, "LastNumber%d", i); - DBWriteContactSettingString(NULL, SKYPE_PROTONAME, buf, dbv.pszVal); - DBFreeVariant(&dbv); - } else break; - } - DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "LastNumber0", number); - } - TempAdded=TRUE; - } - if (!DBWriteContactSettingString(hContact, SKYPE_PROTONAME, "SkypeOutNr", number)) { - msg=(char *)malloc(strlen(number)+6); - strcpy(msg, "CALL "); - strcat(msg, number); - if (SkypeSend(msg) || (ptr=SkypeRcv("ERROR", 500))) { - DBDeleteContactSetting(hContact, SKYPE_PROTONAME, "SkypeOutNr"); - if (ptr) { - OUTPUTA(ptr); - free(ptr); - } - if (TempAdded) CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0); - } - free(msg); - } - case IDCANCEL: - DestroyWindow(hwndDlg); - break; - } - break; - case WM_DESTROY: - Utils_SaveWindowPosition(hwndDlg, NULL, SKYPE_PROTONAME, "DIALdlg"); - if (httbButton) CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)httbButton, TTBST_RELEASED); - break; - } - return FALSE; -} - -/* CallstatDlgProc - * - * Purpose: Dialog procedure for the CallStatus Dialog - */ -static BOOL CALLBACK CallstatDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - static int selected; - static DBVARIANT dbv, dbv2={0}; - - switch (uMsg){ - case WM_INITDIALOG: - { - HANDLE hContact; - char *szProto; - - if (!DBGetContactSettingString((HANDLE)lParam, SKYPE_PROTONAME, "CallId", &dbv)) { - - // Check, if another call is in progress - for (hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);hContact != NULL;hContact=(HANDLE)CallService( MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) { - szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0 ); - if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && hContact!=(HANDLE)lParam && - DBGetContactSettingByte(hContact, SKYPE_PROTONAME, "ChatRoom", 0) == 0 && - !DBGetContactSettingString(hContact, SKYPE_PROTONAME, "CallId", &dbv2)) - { - if (DBGetContactSettingByte(hContact, SKYPE_PROTONAME, "OnHold", 0)) { - DBFreeVariant(&dbv2); - continue; - } else break; - } - } - - if (dbv2.pszVal) - { - char buf[256], buf2[256]; - char *szOtherCaller=(char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,0); - - Utils_RestoreWindowPosition(hwndDlg, NULL, SKYPE_PROTONAME, "CALLSTATdlg"); - TranslateDialogDefault(hwndDlg); - SendMessage(hwndDlg, WM_COMMAND, IDC_JOIN, 0); - - GetWindowTextA(hwndDlg, buf, sizeof(buf)); - _snprintf(buf2, sizeof(buf), buf, CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)lParam,0)); - SetWindowTextA(hwndDlg, buf2); - - GetDlgItemTextA(hwndDlg, IDC_JOIN, buf, sizeof(buf)); - _snprintf(buf2, sizeof(buf), buf, szOtherCaller); - SetDlgItemTextA(hwndDlg, IDC_JOIN, buf2); - - GetDlgItemTextA(hwndDlg, IDC_HOLD, buf, sizeof(buf)); - _snprintf(buf2, sizeof(buf), buf, szOtherCaller); - SetDlgItemTextA(hwndDlg, IDC_HOLD, buf2); - - return TRUE; - } - - // No other call in progress, no need for this Dlg., just answer the call - SkypeSend("SET %s STATUS INPROGRESS", dbv.pszVal); - testfor ("ERROR", 200); - DBFreeVariant(&dbv); - } - DestroyWindow(hwndDlg); - break; - } - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_JOIN: - case IDC_HOLD: - case IDC_HANGUP: - CheckRadioButton(hwndDlg, IDC_JOIN, IDC_HANGUP, (selected=LOWORD(wParam))); - break; - case IDOK: - { - char *szIdCall2; - - switch (selected) { - case IDC_JOIN: - if (szIdCall2=strchr(dbv2.pszVal, ' ')) - SkypeSend("SET %s JOIN_CONFERENCE%s", dbv.pszVal, szIdCall2); - break; - case IDC_HOLD: - SkypeSend("SET %s STATUS ONHOLD", dbv2.pszVal); - SkypeSend("SET %s STATUS INPROGRESS", dbv.pszVal); - break; - case IDC_HANGUP: - SkypeSend("SET %s STATUS FINISHED", dbv.pszVal); - break; - } - - DBFreeVariant(&dbv); - DBFreeVariant(&dbv2); - DestroyWindow(hwndDlg); - break; - } - } - break; - case WM_DESTROY: - Utils_SaveWindowPosition(hwndDlg, NULL, SKYPE_PROTONAME, "CALLSTATdlg"); - break; - } - return FALSE; -} - - -/* SkypeOutCallErrorCheck - * - * Purpose: Checks, if an error has occured after call and - * if so, hangs up the call - * This procedure is a seperate thread to not block the core - * while waiting for "ERROR" - * Params : szCallId - ID of the call - */ -void SkypeOutCallErrorCheck(char *szCallId) { - if (testfor("ERROR", 500)) EndCallThread(szCallId); -} - -/* SkypeOutCall - * - * Purpose: Give a SkypeOut call to the given User in wParam - * or hangs up existing call - * The user's record is searched for Phone-number entries. - * If there is more than 1 entry, the Dial-Dialog is shown - * Params : wParam - Handle to the User to be called - * If NULL, the dial-dialog is shown - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeOutCall(WPARAM wParam, LPARAM lParam) { - DBVARIANT dbv; - int res = -1; - - if (wParam && !DBGetContactSettingString((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { - res=SkypeSend("SET %s STATUS FINISHED", dbv.pszVal); - pthread_create(( pThreadFunc )SkypeOutCallErrorCheck, _strdup(dbv.pszVal)); - DBFreeVariant(&dbv); - } else if (!CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_DIAL), NULL, DialDlgProc, (LPARAM)wParam)) return -1; - return res; -} - -/* SkypeHoldCall - * - * Purpose: Put the call to the User given in wParam on Hold or Resumes it - * Params : wParam - Handle to the User - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeHoldCall(WPARAM wParam, LPARAM lParam) { - DBVARIANT dbv; - int retval; - - LOG(("SkypeHoldCall started")); - if (!wParam || DBGetContactSettingString((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) - return -1; - retval = SkypeSend ("SET %s STATUS %s", dbv.pszVal, - DBGetContactSettingByte((HANDLE)wParam, SKYPE_PROTONAME, "OnHold", 0)?"INPROGRESS":"ONHOLD"); - DBFreeVariant(&dbv); - return retval; -} - -/* SkypeAnswerCall - * - * Purpose: Answer a Skype-call when a user double-clicks on - * The incoming-call-Symbol. Works for both, Skype and SkypeOut-calls - * Params : wParam - Not used - * lParam - CLISTEVENT* - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeAnswerCall(WPARAM wParam, LPARAM lParam) { - - LOG(("SkypeAnswerCall started")); - CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_CALLSTAT), NULL, CallstatDlgProc, (LPARAM)((CLISTEVENT*)lParam)->hContact); - return 0; -} -/* SkypeSetNick - * - * Purpose: Set Full Name in profile - * Params : wParam=0 - * lParam=(LPARAM)(const char*)Nick text - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeSetNick(WPARAM wParam, LPARAM lParam) { - int retval = -1; - char *Nick = NULL; - - if (wParam & SMNN_UNICODE) - { - DBWriteContactSettingWString(0, SKYPE_PROTONAME, "Nick", (WCHAR*)lParam); - if (AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS && - !(Nick = (char*)make_utf8_string((WCHAR*)lParam))) return -1; - } - else - { - DBWriteContactSettingString(0, SKYPE_PROTONAME, "Nick", (char*)lParam); - if(AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS && - utf8_encode((const char *)lParam, &Nick) == -1 ) return -1; - } - if(AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS) - retval = SkypeSend("SET PROFILE FULLNAME %s", Nick); - if (Nick) free (Nick); - - return retval; - -} -/* SkypeSetAwayMessage - * - * Purpose: Set Mood message in profile - * Params : wParam=status mode - * lParam=(LPARAM)(const char*)message text - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeSetAwayMessage(WPARAM wParam, LPARAM lParam) { - int retval = -1; - char *Mood = NULL; - - if (!lParam) lParam=(LPARAM)""; - if(utf8_encode((const char *)lParam, &Mood) == -1 ) return -1; - DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "MoodText", (const char *)lParam); - - if(AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS) - retval = SkypeSend("SET PROFILE MOOD_TEXT %s", Mood); - free (Mood); - - return retval; -} -INT_PTR SkypeSetAwayMessageW(WPARAM wParam, LPARAM lParam) { - int retval = -1; - char *Mood = NULL; - - if (!lParam) lParam=(LPARAM)""; - if (!(Mood = (char*)make_utf8_string((WCHAR*)lParam))) return -1; - DBWriteContactSettingWString(NULL, SKYPE_PROTONAME, "MoodText", (WCHAR*)lParam); - - if(AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS) - retval = SkypeSend("SET PROFILE MOOD_TEXT %s", Mood); - free (Mood); - - return retval; -} - -/* SkypeSetAvatar - * - * Purpose: Set user avatar in profile - * Params : wParam=0 - * lParam=(LPARAM)(const char*)filename - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeSetAvatar(WPARAM wParam, LPARAM lParam) { - char *filename = (char *) lParam, *ext; - char AvatarFile[MAX_PATH+1], OldAvatarFile[1024]; - char *ptr = NULL; - int ret; - char command[500]; - DBVARIANT dbv = {0}; - BOOL hasOldAvatar = (DBGetContactSettingString(NULL, SKYPE_PROTONAME, "AvatarFile", &dbv) == 0 && dbv.type == DBVT_ASCIIZ); - size_t len; - - if (AttachStatus != SKYPECONTROLAPI_ATTACH_SUCCESS) - return -3; - - if (filename == NULL) - return -1; - len = strlen(filename); - if (len < 4) - return -1; - - ext = &filename[len-4]; - if (_stricmp(ext, ".jpg")==0 || _stricmp(ext-1, ".jpeg")==0) - ext = "jpg"; - else if (_stricmp(ext, ".png")==0) - ext = "png"; - else - return -2; - - FoldersGetCustomPath(hProtocolAvatarsFolder, AvatarFile, sizeof(AvatarFile), DefaultAvatarsFolder); - mir_snprintf(AvatarFile, sizeof(AvatarFile), "%s\\%s avatar.%s", AvatarFile, SKYPE_PROTONAME, ext); - - // Backup old file - if (hasOldAvatar) - { - strncpy(OldAvatarFile, dbv.pszVal, sizeof(OldAvatarFile)-4); - OldAvatarFile[sizeof(OldAvatarFile)-5] = '\0'; - strcat(OldAvatarFile, "_old"); - DeleteFileA(OldAvatarFile); - if (!MoveFileA(dbv.pszVal, OldAvatarFile)) - { - DBFreeVariant(&dbv); - return -3; - } - } - - // Copy new file - if (!CopyFileA(filename, AvatarFile, FALSE)) - { - if (hasOldAvatar) - { - MoveFileA(OldAvatarFile, dbv.pszVal); - DBFreeVariant(&dbv); - } - return -3; - } - - // Try to set with skype - mir_snprintf(command, sizeof(command), "SET AVATAR 1 %s", AvatarFile); - if (SkypeSend(command) || (ptr = SkypeRcv(command+4, INFINITE)) == NULL || !strncmp(ptr, "ERROR", 5)) - { - DeleteFileA(AvatarFile); - - if (hasOldAvatar) - MoveFileA(OldAvatarFile, dbv.pszVal); - - ret = -4; - } - else - { - if (hasOldAvatar) - DeleteFileA(OldAvatarFile); - - DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "AvatarFile", AvatarFile); - - ret = 0; - } - - if (ptr != NULL) - free(ptr); - - if (hasOldAvatar) - DBFreeVariant(&dbv); - - return ret; -} - - -/* SkypeSendFile - * - * Purpose: Opens the Skype-dialog to send a file - * Params : wParam - Handle to the User - * lParam - Not used - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeSendFile(WPARAM wParam, LPARAM lParam) { - DBVARIANT dbv; - int retval; - - if (!wParam || DBGetContactSettingString((HANDLE)wParam, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) - return -1; - retval=SkypeSend("OPEN FILETRANSFER %s", dbv.pszVal); - DBFreeVariant(&dbv); - return retval; -} - -/* SkypeChatCreate - * - * Purpose: Creates a groupchat with the user - * Params : wParam - Handle to the User - * lParam - Not used - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeChatCreate(WPARAM wParam, LPARAM lParam) { - DBVARIANT dbv; - HANDLE hContact=(HANDLE)wParam; - char *ptr, *ptr2; - - if (!hContact || DBGetContactSettingString(hContact, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) - return -1; - // Flush old messages - while (testfor("\0CHAT \0 STATUS \0", 0)); - if (SkypeSend("CHAT CREATE %s", dbv.pszVal) || !(ptr=SkypeRcv ("\0CHAT \0 STATUS \0", INFINITE))) - { - DBFreeVariant(&dbv); - return -1; - } - DBFreeVariant(&dbv); - if (ptr2=strstr (ptr, "STATUS")) { - *(ptr2-1)=0; - ChatStart (ptr+5, FALSE); - } - free(ptr); - return 0; -} - -/* SkypeAdduserDlg - * - * Purpose: Show Skype's Add user Dialog - */ -INT_PTR SkypeAdduserDlg(WPARAM wParam, LPARAM lParam) { - SkypeSend("OPEN ADDAFRIEND"); - return 0; -} - -/* SkypeFlush - * - * Purpose: Flush the Skype Message-List - */ -void SkypeFlush(void) { - char *ptr; - - while ((ptr=SkypeRcv(NULL, 0))!=NULL) free(ptr); -} - -/* SkypeStatusToMiranda - * - * Purpose: Converts the specified Skype-Status mode to the corresponding Miranda-Status mode - * Params : s - Skype Status - * Returns: The correct Status - * 0 - Nothing found - */ -int SkypeStatusToMiranda(char *s) { - int i; - if (!strcmp("SKYPEOUT", s)) return DBGetContactSettingDword(NULL, SKYPE_PROTONAME, "SkypeOutStatusMode", ID_STATUS_ONTHEPHONE); - for(i=0; status_codes[i].szStat; i++) - if (!strcmp(status_codes[i].szStat, s)) - return status_codes[i].id; - return 0; -} - -/* MirandaStatusToSkype - * - * Purpose: Converts the specified Miranda-Status mode to the corresponding Skype-Status mode - * Params : id - Miranda Status - * Returns: The correct Status - * NULL - Nothing found - */ -char *MirandaStatusToSkype(int id) { - int i; - if (DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "NoSkype3Stats", 0)) { - switch (id) - { - case ID_STATUS_NA: return "AWAY"; - case ID_STATUS_FREECHAT: return "ONLINE"; - } - } - for(i=0; status_codes[i].szStat; i++) - if (status_codes[i].id==id) - return status_codes[i].szStat; - return NULL; -} - -/* GetSkypeErrorMsg - * - * Purpose: Get a human-readable Error-Message for the supplied Skype Error-Message - * Params : str - Skype Error-Message string - * Returns: Human-readable Error Message or NULL, if nothing was found - * Warning: Don't forget to free() return value - */ -char *GetSkypeErrorMsg(char *str) { - char *pos, *reason, *msg; - - LOG (("GetSkypeErrorMsg received error: %s", str)); - if (!strncmp(str, "ERROR", 5)) { - reason=_strdup(str); - return reason; - } - if ((pos=strstr(str, "FAILURE")) ) { - switch(atoi(pos+14)) { - case MISC_ERROR: msg="Misc. Error"; break; - case USER_NOT_FOUND: msg="User does not exist, check username"; break; - case USER_NOT_ONLINE: msg="Trying to send IM to an user, who is not online"; break; - case USER_BLOCKED: msg="IM blocked by recipient"; break; - case TYPE_UNSUPPORTED: msg="Type unsupported"; break; - case SENDER_NOT_FRIEND: msg="Sending IM message to user, who has not added you to friendslist and has chosen 'only people in my friendslist can start IM'"; break; - case SENDER_NOT_AUTHORIZED: msg="Sending IM message to user, who has not authorized you and has chosen 'only people whom I have authorized can start IM'"; break; - default: msg="Unknown error"; - } - reason=(char *)malloc(strlen(pos)+strlen(msg)+3); - sprintf (reason, "%s: %s", pos, msg); - return reason; - } - return NULL; -} - -/* testfor - * - * Purpose: Wait, until the given Message-Fragment is received from Skype within - * the given amount of time - * Params : see SkypeRcv - * Returns: TRUE - Message was received within the given amount of time - * FALSE- nope, sorry - */ -BOOL testfor(char *what, DWORD maxwait) { - char *res; - - if ((res=SkypeRcv(what, maxwait))==NULL) return FALSE; - free(res); - return TRUE; -} - -char SendSkypeproxyCommand(char command) { - int length=0; - char reply=0; - BOOL res; - - res = send(ClientSocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR - || send(ClientSocket, (char *)&command, sizeof(command), 0)==SOCKET_ERROR - || recv(ClientSocket, (char *)&reply, sizeof(reply), 0)==SOCKET_ERROR; - if (res) - return -1; - else - return reply; -} - -/* ConnectToSkypeAPI - * - * Purpose: Establish a connection to the Skype API - * Params : path - Path to the Skype application - * iStart - Need to start skype for status change. - * 1 = Normal start if Skype not running - * 2 = Forced startp code execution no matter what - * Returns: 0 - Connecting succeeded - * -1 - Something went wrong - */ -int ConnectToSkypeAPI(char *path, int iStart) { - static int iRet = -1; // last request result - static volatile long newRequest = TRUE; - - InterlockedExchange(&newRequest, TRUE); // place new request - EnterCriticalSection(&ConnectMutex); // Prevent reentrance - if (iRet == -1 || newRequest) - { - iRet = _ConnectToSkypeAPI(path, iStart); - InterlockedExchange(&newRequest, FALSE); // every thread which is waiting for connect mutex will get our result as well.. but subsequent calls will set this value to true and call _Connect again - } - LeaveCriticalSection(&ConnectMutex); - return iRet; -} - -void TranslateMirandaRelativePathToAbsolute(LPCSTR cszPath, LPSTR szAbsolutePath, BOOL fQuoteSpaces) { - *szAbsolutePath = 0; - CallService (MS_UTILS_PATHTOABSOLUTE, (WPARAM)(*cszPath ? cszPath : ".\\"), (LPARAM)szAbsolutePath); - if(fQuoteSpaces && strchr((LPCSTR)szAbsolutePath, ' ')){ - memmove (szAbsolutePath+1, szAbsolutePath, strlen(szAbsolutePath)+1); - *szAbsolutePath='"'; - strcat (szAbsolutePath, "\""); - } - - TRACEA(szAbsolutePath); -} - -static int my_spawnv(const char *cmdname, const char *const *argv, PROCESS_INFORMATION *pi) -{ - int i, iLen=0; - char *CommandLine; - STARTUPINFOA si={0}; - BOOL bRet; - - memset (pi, 0, sizeof(PROCESS_INFORMATION)); - for (i=0; argv[i]; i++) iLen+=strlen(argv[i])+1; - if (!(CommandLine = calloc(1, iLen))) return -1; - for (i=0; argv[i]; i++) { - if (i) strcat (CommandLine, " "); - strcat (CommandLine, argv[i]); - } - si.cb = sizeof(si); - - bRet = CreateProcessA( cmdname,CommandLine,NULL,NULL,FALSE,0,NULL,NULL,&si,pi); - free(CommandLine); - if (!bRet) return -1; - return (DWORD)pi->hProcess; -} - -static int _ConnectToSkypeAPI(char *path, int iStart) { - BOOL SkypeLaunched=FALSE; - BOOL UseCustomCommand = DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseCustomCommand", 0); - int counter=0, i, j, maxattempts=DBGetContactSettingWord(NULL, SKYPE_PROTONAME, "ConnectionAttempts", 10); - char *args[7], *pFree = NULL; - char *SkypeOptions[]={"/notray", "/nosplash", "/minimized", "/removable", "/datapath:", "/secondary"}; - const int SkypeDefaults[]={0, 1, 1, 0, 0}; - - char szAbsolutePath[MAX_PATH]; - - LOG(("ConnectToSkypeAPI started.")); - if (UseSockets) - { - SOCKADDR_IN service; - DBVARIANT dbv; - long inet; - struct hostent *hp; - - LOG(("ConnectToSkypeAPI: Connecting to Skype2socket socket...")); - if ((ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET) return -1; - - if (!DBGetContactSettingString(NULL, SKYPE_PROTONAME, "Host", &dbv)) { - if ((inet=inet_addr(dbv.pszVal))==-1) { - if (hp=gethostbyname(dbv.pszVal)) - memcpy(&inet, hp->h_addr, sizeof(inet)); - else { - OUTPUT(_T("Cannot resolve host!")); - DBFreeVariant(&dbv); - return -1; - } - } - DBFreeVariant(&dbv); - } else { - OUTPUT(_T("Cannot find valid host to connect to.")); - return -1; - } - - service.sin_family = AF_INET; - service.sin_addr.s_addr = inet; - service.sin_port = htons((unsigned short)DBGetContactSettingWord(NULL, SKYPE_PROTONAME, "Port", 1401)); - - if ( connect( ClientSocket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR) return -1; - - if (DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "RequiresPassword", 0) && !DBGetContactSettingString(NULL, SKYPE_PROTONAME, "Password", &dbv)) - { - char reply=0; - - CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM)dbv.pszVal); - if ((reply=SendSkypeproxyCommand(AUTHENTICATE))==-1) - { - DBFreeVariant(&dbv); - return -1; - } - if (!reply) { - OUTPUT(_T("Authentication is not supported/needed for this Skypeproxy server. It will be disabled.")); - DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "RequiresPassword", 0); - } else { - unsigned int length=(unsigned int)strlen(dbv.pszVal); - BOOL res; - res = send(ClientSocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR - || send(ClientSocket, dbv.pszVal, length, 0)==SOCKET_ERROR - || recv(ClientSocket, (char *)&reply, sizeof(reply), 0)==SOCKET_ERROR; - if (res) - { - DBFreeVariant(&dbv); - return -1; - } - if (!reply) - { - OUTPUT(_T("Authentication failed for this server, connection was not successful. Verify that your password is correct!")); - DBFreeVariant(&dbv); - return -1; - } - } - DBFreeVariant(&dbv); - } - else - { - char reply=0; - - if ((reply=SendSkypeproxyCommand(CAPABILITIES))==-1) return -1; - if (reply&USE_AUTHENTICATION) { - OUTPUT(_T("The server you specified requires authentication, but you have not supplied a password for it. Check the Skype plugin settings and try again.")); - return -1; - } - } - - - if (!rcvThreadRunning) - if(_beginthread(( pThreadFunc )rcvThread, 0, NULL)==-1) return -1; - - AttachStatus=SKYPECONTROLAPI_ATTACH_SUCCESS; - return 0; - } - - if (pszProxyCallout) - { - if (SkypeSend("SET USERSTATUS ONLINE")==-1) - { - AttachStatus=SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE; - return -1; - } - for ( ;; ) { - char *ptr = SkypeRcv ("CONNSTATUS", INFINITE); - if (strcmp (ptr+11, "CONNECTING")) - { - free (ptr); - break; - } - free (ptr); - } - - AttachStatus=SKYPECONTROLAPI_ATTACH_SUCCESS; - return 0; - } - - do - { - int retval; - /* To initiate communication, Client should broadcast windows message - ('SkypeControlAPIDiscover') to all windows in the system, specifying its own - window handle in wParam parameter. - */ - if (iStart != 2 || counter) - { - LOG(("ConnectToSkypeAPI sending discover message.. hWnd=%08X", (long)g_hWnd)); - retval=SendMessageTimeout(HWND_BROADCAST, ControlAPIDiscover, (WPARAM)g_hWnd, 0, SMTO_ABORTIFHUNG, 3000, NULL); - LOG(("ConnectToSkypeAPI sent discover message returning %d", retval)); - } - - /* In response, Skype responds with - message 'SkypeControlAPIAttach' to the handle specified, and indicates - connection status - SkypeReady is set if there is an answer by Skype other than API_AVAILABLE. - If there is no answer after 3 seconds, launch Skype as it's propably - not running. - */ - if (iStart == 2 || (WaitForSingleObject(SkypeReady, 3000)==WAIT_TIMEOUT && AttachStatus!=SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION)) - { - if (iStart != 2 && g_hWnd==NULL) - { - LOG(("ConnectToSkypeAPI: hWnd of SkypeDispatchWindow not yet set..")); - continue; - } - if ((iStart == 2 || !SkypeLaunched) && (path || UseCustomCommand)) - { - static PROCESS_INFORMATION pi={0}; - DWORD dwExitStatus = 0; - - if ((!pi.hProcess || !GetExitCodeProcess(pi.hProcess, &dwExitStatus) || dwExitStatus != STILL_ACTIVE) && - (DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "StartSkype", 1) || iStart)) - { - LOG(("ConnectToSkypeAPI Starting Skype, as it's not running")); - - j=1; - for (i=0; i=maxattempts && AttachStatus==-1) - { - int oldstatus=SkypeStatus; - InterlockedExchange((long *)&SkypeStatus, (int)ID_STATUS_OFFLINE); - ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldstatus, SkypeStatus); - OUTPUT(_T("ERROR: Skype not running / too old / working!")); - return -1; - } - } - } - LOG(("Attachstatus %d", AttachStatus)); - } while (AttachStatus==SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE || AttachStatus==SKYPECONTROLAPI_ATTACH_API_AVAILABLE || AttachStatus==-1); - - while (AttachStatus==SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION) Sleep(1000); - LOG(("Attachstatus %d", AttachStatus)); - if (AttachStatus!=SKYPECONTROLAPI_ATTACH_SUCCESS) { - int oldstatus; - - switch(AttachStatus) { - case SKYPECONTROLAPI_ATTACH_REFUSED: - OUTPUT(_T("Skype refused the connection :(")); - break; - case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE: - OUTPUT(_T("The Skype API is not available")); - break; - default: - LOG(("ERROR: AttachStatus: %d", AttachStatus)); - OUTPUT(_T("Wheee, Skype won't let me use the API. :(")); - } - oldstatus=SkypeStatus; - InterlockedExchange((long *)&SkypeStatus, (int)ID_STATUS_OFFLINE); - ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldstatus, SkypeStatus); - return -1; - } - - return 0; -} - -/* CloseSkypeAPI - * Purpose: Closes existing api connection - * Params: path - Path to the Skype application; could be NULL when using proxy - * Returns: always 0 - */ -int CloseSkypeAPI(char *skypePath) -{ - char szAbsolutePath[MAX_PATH]; - - logoff_contacts(TRUE); - if (UseSockets) - { - if (ClientSocket != INVALID_SOCKET) - { - closesocket(ClientSocket); - ClientSocket = INVALID_SOCKET; - } - } - else { - if (!pszProxyCallout) - { - if (AttachStatus!=-1) - { - // it was crashing when the skype-network-proxy is used (imo2sproxy for imo.im) and skype-path is empty - // now, with the "UseSockets" check and the skypePath[0] != 0 check its fixed - if (skypePath != NULL && skypePath[0] != 0) { - TranslateMirandaRelativePathToAbsolute(skypePath, szAbsolutePath, FALSE); - _spawnl(_P_NOWAIT, szAbsolutePath, szAbsolutePath, "/SHUTDOWN", NULL); - } - } - } - } - SkypeInitialized=FALSE; - ResetEvent(SkypeReady); - AttachStatus=-1; - if (g_hWnd) KillTimer (g_hWnd, 1); - return 0; -} -/* ConnectToSkypeAPI - * - * Purpose: Establish a connection to the Skype API - * Params : path - Path to the Skype application - * Returns: 0 - Connecting succeeded - * -1 - Something went wrong - */ -//int __connectAPI(char *path) { -// int retval; -// -// EnterCriticalSection(&ConnectMutex); -// if (AttachStatus!=-1) { -// LeaveCriticalSection(&ConnectMutex); -// return -1; -// } -// InterlockedExchange((long *)&SkypeStatus, ID_STATUS_CONNECTING); -// ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) ID_STATUS_OFFLINE, SkypeStatus); -// retval=__connectAPI(path); -// if (retval==-1) { -// logoff_contacts(); -// InterlockedExchange((long *)&SkypeStatus, ID_STATUS_OFFLINE); -// ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) ID_STATUS_CONNECTING, SkypeStatus); -// } -// LeaveCriticalSection(&ConnectMutex); -// return retval; -//} diff --git a/!NotAdopted/Skype/skypeapi.h b/!NotAdopted/Skype/skypeapi.h deleted file mode 100644 index fa4f5139a1..0000000000 --- a/!NotAdopted/Skype/skypeapi.h +++ /dev/null @@ -1,69 +0,0 @@ -// Skype API defines -#define SKYPECONTROLAPI_ATTACH_SUCCESS 0 -#define SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION 1 -#define SKYPECONTROLAPI_ATTACH_REFUSED 2 -#define SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE 3 -#define SKYPECONTROLAPI_ATTACH_API_AVAILABLE 0x8001 - -#define MISC_ERROR 1 -#define USER_NOT_FOUND 2 -#define USER_NOT_ONLINE 3 -#define USER_BLOCKED 4 -#define TYPE_UNSUPPORTED 5 -#define SENDER_NOT_FRIEND 6 -#define SENDER_NOT_AUTHORIZED 7 - -#define MAX_ENTRIES 128 // Max. 128 number-Entries in Dial-dlg. - -typedef struct { - int id; - char *szStat; -} status_map; - -// Prototypes -int SkypeMsgInit(void); -int SkypeMsgAdd(char *msg); -void SkypeMsgCleanup(void); -char *SkypeMsgGet(void); -int SkypeSend(char*, ...); -char *SkypeRcv(char *what, DWORD maxwait); -char *SkypeRcvTime(char *what, time_t st, DWORD maxwait); -char *SkypeRcvMsg(char *what, time_t st, HANDLE hContact, DWORD maxwait); -INT_PTR SkypeCall(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeCallHangup(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeOutCall(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeHup(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeHoldCall(WPARAM wParam, LPARAM lParam); -void SkypeFlush(void); -int SkypeStatusToMiranda(char *s); -char *MirandaStatusToSkype(int id); -char *GetSkypeErrorMsg(char *str); -BOOL testfor(char *what, DWORD maxwait); -int ConnectToSkypeAPI(char *path, BOOL bStart); -int CloseSkypeAPI(char *skypePath); -INT_PTR SkypeAdduserDlg(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeAnswerCall(WPARAM wParam, LPARAM lParam); -int SkypeMsgCollectGarbage(time_t age); -INT_PTR SkypeSendFile(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeSetAvatar(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeSetAwayMessage(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeSetAwayMessageW(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeSetNick(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeChatCreate(WPARAM wParam, LPARAM lParam); -int SkypeSetProfile(char *szProperty, char *szValue); -char *SkypeGet(char *szWhat, char *szWho, char *szProperty); -char *SkypeGetID(char *szWhat, char *szWho, char *szProperty); -char *SkypeGetErr(char *szWhat, char *szWho, char *szProperty); -#ifdef _UNICODE -WCHAR *SkypeGetW(char *szWhat, WCHAR *szWho, char *szProperty); -WCHAR *SkypeGetErrW(char *szWhat, TCHAR *szWho, char *szProperty); -#define SkypeGetT SkypeGetW -#define SkypeGetErrT SkypeGetErrW -#else -#define SkypeGetT SkypeGet -#define SkypeGetErrT SkypeGetErr -#endif -char *SkypeGetProfile(char *szProperty); -void SetUserNamePassword(); -INT_PTR SkypeAdduserDlg(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeReceivedAPIMessage(WPARAM wParam, LPARAM lParam); diff --git a/!NotAdopted/Skype/skypeopt.c b/!NotAdopted/Skype/skypeopt.c deleted file mode 100644 index 2dfc4faef5..0000000000 --- a/!NotAdopted/Skype/skypeopt.c +++ /dev/null @@ -1,969 +0,0 @@ -#include "skype.h" -#include "skypeopt.h" -#include "pthread.h" -#include "gchat.h" -#include "skypeprofile.h" -#if(WINVER >= 0x0500) -#include "uxtheme.h" -#define HAVE_UXTHEMES -#endif - -#ifdef SKYPE_AUTO_DETECTION -#include "ezxml/ezxml.c" -#endif - -#ifdef UNICODE -#include "utf8.h" -#endif - -#pragma warning (disable: 4706) // assignment within conditional expression - -// VC6 SDK defines -#ifndef BIF_SHAREABLE -#define BIF_SHAREABLE 0x8000 // sharable resources displayed (remote shares, requires BIF_USENEWUI) -#endif -#ifndef BIF_NEWDIALOGSTYLE -#define BIF_NEWDIALOGSTYLE 0x0040 // Use the new dialog layout with the ability to resize -#endif // Caller needs to call OleInitialize() before using this API -#ifndef BIF_NONEWFOLDERBUTTON -#define BIF_NONEWFOLDERBUTTON 0x0200 // Do not add the "New Folder" button to the dialog. Only applicable with BIF_NEWDIALOGSTYLE. -#endif - - -extern HINSTANCE hInst; -extern PLUGININFO pluginInfo; -extern char protocol, g_szProtoName[]; -extern BOOL SkypeInitialized, bProtocolSet, bIsImoproxy; -extern DWORD mirandaVersion; - -BOOL showPopup, showPopupErr, popupWindowColor, popupWindowColorErr; -unsigned int popupBackColor, popupBackColorErr; -unsigned int popupTextColor, popupTextColorErr; -int popupTimeSec, popupTimeSecErr; -POPUPDATAT InCallPopup; -POPUPDATAT ErrorPopup; - -static SkypeProfile myProfile; -static HBITMAP hAvatar = NULL; - -extern BOOL PopupServiceExists; -extern BOOL (WINAPI *MyEnableThemeDialogTexture)(HANDLE, DWORD); - -int RegisterOptions(WPARAM wParam, LPARAM lParam) { - OPTIONSDIALOGPAGE odp; - - UNREFERENCED_PARAMETER(lParam); - - ZeroMemory(&odp, sizeof(odp)); - odp.cbSize = sizeof(odp); - odp.hInstance = hInst; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); - odp.pszGroup = "Network"; - odp.pszTitle = SKYPE_PROTONAME; - odp.pfnDlgProc = OptionsDlgProc; - odp.flags = ODPF_BOLDGROUPS; - CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp); - - if(PopupServiceExists) - { - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_POPUP); - odp.pszGroup = "Popups"; - odp.pfnDlgProc = OptPopupDlgProc; - CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp); - } - - return 0; -} - -INT_PTR CALLBACK OptPopupDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static RECT r; - - switch ( msg ) - { - case WM_INITDIALOG: - TranslateDialogDefault( hwnd ); - // Message Popup - popupTimeSec = DBGetContactSettingDword(NULL, SKYPE_PROTONAME, "popupTimeSec", 4); - popupTextColor = DBGetContactSettingDword(NULL, SKYPE_PROTONAME, "popupTextColor", GetSysColor(COLOR_WINDOWTEXT)); - popupBackColor = DBGetContactSettingDword(NULL, SKYPE_PROTONAME, "popupBackColor", GetSysColor(COLOR_BTNFACE)); - popupWindowColor = DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "popupWindowColor", FALSE); - showPopup = DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "showPopup", TRUE); - // ERROR Message Popup - popupTimeSecErr = DBGetContactSettingDword(NULL, SKYPE_PROTONAME, "popupTimeSecErr", 4); - popupTextColorErr = DBGetContactSettingDword(NULL, SKYPE_PROTONAME, "popupTextColorErr", GetSysColor(COLOR_WINDOWTEXT)); - popupBackColorErr = DBGetContactSettingDword(NULL, SKYPE_PROTONAME, "popupBackColorErr", GetSysColor(COLOR_BTNFACE)); - popupWindowColorErr = DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "popupWindowColorErr", FALSE); - showPopupErr = DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "showPopupErr", TRUE); - - EnableWindow(GetDlgItem(hwnd,IDC_USEWINCOLORS),showPopup); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLOR),showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLOR),showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLOR),showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLOR),showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTIME),showPopup); - EnableWindow(GetDlgItem(hwnd,IDC_PREVIEW),showPopup); - EnableWindow(GetDlgItem(hwnd,IDC_USEWINCOLORSERR),showPopupErr); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLORERR),showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLORERR),showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLORERR),showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLORERR),showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTIMEERR),showPopupErr); - EnableWindow(GetDlgItem(hwnd,IDC_PREVIEWERR),showPopupErr); - CheckDlgButton(hwnd, IDC_POPUPINCOMING, (WPARAM) showPopup); - CheckDlgButton(hwnd, IDC_USEWINCOLORS, (WPARAM) popupWindowColor); - CheckDlgButton(hwnd, IDC_POPUPERROR, (WPARAM) showPopupErr); - CheckDlgButton(hwnd, IDC_USEWINCOLORSERR, (WPARAM) popupWindowColorErr); - SendDlgItemMessage(hwnd, IDC_POPUPTIME, EM_SETLIMITTEXT, 3, 0L); - SetDlgItemInt(hwnd, IDC_POPUPTIME, popupTimeSec,FALSE); - SendDlgItemMessage(hwnd, IDC_POPUPTIMEERR, EM_SETLIMITTEXT, 3, 0L); - SetDlgItemInt(hwnd, IDC_POPUPTIMEERR, popupTimeSecErr,FALSE); - SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLOR, CPM_SETCOLOUR,0, popupBackColor); - SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLOR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_BTNFACE)); - SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLOR, CPM_SETCOLOUR,0, popupTextColor); - SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLOR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_WINDOWTEXT)); - SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLORERR, CPM_SETCOLOUR,0, popupBackColorErr); - SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLORERR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_BTNFACE)); - SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLORERR, CPM_SETCOLOUR,0, popupTextColorErr); - SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLORERR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_WINDOWTEXT)); - - - return TRUE; - break; - - case WM_NOTIFY: - switch(((LPNMHDR)lParam)->idFrom) - { - case 0: - switch (((LPNMHDR)lParam)->code) - { - case PSN_APPLY: - DBWriteContactSettingDword(NULL, SKYPE_PROTONAME, "popupBackColor", popupBackColor); - DBWriteContactSettingDword(NULL, SKYPE_PROTONAME, "popupTextColor", popupTextColor); - DBWriteContactSettingDword(NULL, SKYPE_PROTONAME, "popupTimeSec", popupTimeSec); - DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "popupWindowColor", (BYTE)popupWindowColor); - DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "showPopup", (BYTE)showPopup); - DBWriteContactSettingDword(NULL, SKYPE_PROTONAME, "popupBackColorErr", popupBackColorErr); - DBWriteContactSettingDword(NULL, SKYPE_PROTONAME, "popupTextColorErr", popupTextColorErr); - DBWriteContactSettingDword(NULL, SKYPE_PROTONAME, "popupTimeSecErr", popupTimeSecErr); - DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "popupWindowColorErr", (BYTE)popupWindowColorErr); - DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "showPopupErr", (BYTE)showPopupErr); - break; - } - } - break; - - - - case WM_COMMAND: - switch( LOWORD( wParam )) - { - case IDC_PREVIEW: - { - HANDLE hContact; - TCHAR * lpzContactName; - - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST,0,0); - lpzContactName = (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,GCDNF_TCHAR); - InCallPopup.lchContact = hContact; - InCallPopup.lchIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALL)); - InCallPopup.colorBack = ! popupWindowColor ? popupBackColor : GetSysColor(COLOR_BTNFACE); - InCallPopup.colorText = ! popupWindowColor ? popupTextColor : GetSysColor(COLOR_WINDOWTEXT); - InCallPopup.iSeconds = popupTimeSec; - InCallPopup.PluginData = (void *)1; - - lstrcpy(InCallPopup.lptzText, TranslateT("Incoming Skype Call")); - - lstrcpy(InCallPopup.lptzContactName, lpzContactName); - - CallService(MS_POPUP_ADDPOPUPT,(WPARAM)&InCallPopup,0); - - - break; - } - case IDC_PREVIEWERR: - ErrorPopup.lchContact = NULL; - ErrorPopup.lchIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALL)); - ErrorPopup.colorBack = ! popupWindowColorErr ? popupBackColorErr : GetSysColor(COLOR_BTNFACE); - ErrorPopup.colorText = ! popupWindowColorErr ? popupTextColorErr : GetSysColor(COLOR_WINDOWTEXT); - ErrorPopup.iSeconds = popupTimeSecErr; - ErrorPopup.PluginData = (void *)1; - - lstrcpy(ErrorPopup.lptzText, TranslateT("Preview Error Message")); - - lstrcpy(ErrorPopup.lptzContactName, _T("Error Message")); - - - CallService(MS_POPUP_ADDPOPUPT,(WPARAM)&ErrorPopup,0); - - break; - - case IDC_POPUPTIME: - case IDC_POPUPTIMEERR: - { - BOOL Translated; - popupTimeSec = GetDlgItemInt(hwnd,IDC_POPUPTIME,&Translated,FALSE); - popupTimeSecErr = GetDlgItemInt(hwnd,IDC_POPUPTIMEERR,&Translated,FALSE); - SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); - break; - } - case IDC_POPUPTEXTCOLOR: - case IDC_POPUPBACKCOLOR: - case IDC_POPUPTEXTCOLORERR: - case IDC_POPUPBACKCOLORERR: - popupBackColor = SendDlgItemMessage(hwnd,IDC_POPUPBACKCOLOR,CPM_GETCOLOUR,0,0); - popupTextColor = SendDlgItemMessage(hwnd,IDC_POPUPTEXTCOLOR,CPM_GETCOLOUR,0,0); - popupBackColorErr = SendDlgItemMessage(hwnd,IDC_POPUPBACKCOLORERR,CPM_GETCOLOUR,0,0); - popupTextColorErr = SendDlgItemMessage(hwnd,IDC_POPUPTEXTCOLORERR,CPM_GETCOLOUR,0,0); - SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); - break; - case IDC_USEWINCOLORS: - popupWindowColor = (IsDlgButtonChecked(hwnd,IDC_USEWINCOLORS)==BST_CHECKED); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLOR), showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLOR), showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLOR), showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLOR), showPopup && ! popupWindowColor); - SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); - break; - case IDC_POPUPINCOMING: - showPopup = (IsDlgButtonChecked(hwnd,IDC_POPUPINCOMING)==BST_CHECKED); - EnableWindow(GetDlgItem(hwnd,IDC_USEWINCOLORS),showPopup); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLOR),showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLOR),showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLOR),showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLOR),showPopup && ! popupWindowColor); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTIME),showPopup); - EnableWindow(GetDlgItem(hwnd,IDC_PREVIEW),showPopup); - SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); - break; - case IDC_USEWINCOLORSERR: - popupWindowColorErr = (IsDlgButtonChecked(hwnd,IDC_USEWINCOLORSERR)==BST_CHECKED); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLORERR), showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLORERR), showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLORERR), showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLORERR), showPopupErr && ! popupWindowColorErr); - SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); - break; - case IDC_POPUPERROR: - showPopupErr = (IsDlgButtonChecked(hwnd,IDC_POPUPERROR)==BST_CHECKED); - EnableWindow(GetDlgItem(hwnd,IDC_USEWINCOLORSERR),showPopupErr); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLORERR),showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLORERR),showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLORERR),showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLORERR),showPopupErr && ! popupWindowColorErr); - EnableWindow(GetDlgItem(hwnd,IDC_POPUPTIMEERR),showPopupErr); - EnableWindow(GetDlgItem(hwnd,IDC_PREVIEWERR),showPopupErr); - SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); - break; - } - - break; - - case WM_DESTROY: - break; - } - - return 0; -} - -INT_PTR CALLBACK OptionsDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static int iInit = TRUE; - - UNREFERENCED_PARAMETER(wParam); - - switch(msg) - { - case WM_INITDIALOG: - { - TCITEM tci; - RECT rcClient; - GetClientRect(hwnd, &rcClient); - - iInit = TRUE; - tci.mask = TCIF_PARAM|TCIF_TEXT; - tci.lParam = (LPARAM)CreateDialog(hInst,MAKEINTRESOURCE(IDD_OPT_DEFAULT), hwnd, OptionsDefaultDlgProc); - tci.pszText = TranslateT("Skype default"); - TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 0, &tci); - MoveWindow((HWND)tci.lParam,1,28,rcClient.right-5,rcClient.bottom-31,1); -#ifdef HAVE_UXTHEMES - if(MyEnableThemeDialogTexture) - MyEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB); -#endif - - tci.lParam = (LPARAM)CreateDialog(hInst,MAKEINTRESOURCE(IDD_OPT_ADVANCED),hwnd,OptionsAdvancedDlgProc); - tci.pszText = TranslateT("Skype advanced"); - TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 1, &tci); - MoveWindow((HWND)tci.lParam,1,28,rcClient.right-5,rcClient.bottom-31,1); - ShowWindow((HWND)tci.lParam, SW_HIDE); -#ifdef HAVE_UXTHEMES - if(MyEnableThemeDialogTexture) - MyEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB); -#endif - - tci.lParam = (LPARAM)CreateDialog(hInst,MAKEINTRESOURCE(IDD_OPT_PROXY),hwnd,OptionsProxyDlgProc); - tci.pszText = TranslateT("Skype proxy"); - TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 2, &tci); - MoveWindow((HWND)tci.lParam,1,28,rcClient.right-5,rcClient.bottom-31,1); - ShowWindow((HWND)tci.lParam, SW_HIDE); -#ifdef HAVE_UXTHEMES - if(MyEnableThemeDialogTexture) - MyEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB); -#endif - - iInit = FALSE; - return FALSE; - } - - case PSM_CHANGED: // used so tabs dont have to call SendMessage(GetParent(GetParent(hwnd)), PSM_CHANGED, 0, 0); - if(!iInit) - SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); - break; - case WM_NOTIFY: - switch(((LPNMHDR)lParam)->idFrom) { - case 0: - switch (((LPNMHDR)lParam)->code) - { - case PSN_APPLY: - { - TCITEM tci; - int i,count; - tci.mask = TCIF_PARAM; - count = TabCtrl_GetItemCount(GetDlgItem(hwnd,IDC_OPTIONSTAB)); - for (i=0;icode) - { - case TCN_SELCHANGING: - { - TCITEM tci; - tci.mask = TCIF_PARAM; - TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci); - ShowWindow((HWND)tci.lParam,SW_HIDE); - } - break; - case TCN_SELCHANGE: - { - TCITEM tci; - tci.mask = TCIF_PARAM; - TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci); - ShowWindow((HWND)tci.lParam,SW_SHOW); - } - break; - } - break; - - } - break; - } - return FALSE; -} - -INT_PTR CALLBACK OptionsProxyDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - const int Skype2SocketControls[]={ IDC_STATIC_HOST, IDC_HOST, IDC_STATIC_PORT, IDC_PORT, IDC_REQPASS, IDC_PASSWORD, IDC_STATIC_RESTART }; - static BOOL initDlg=FALSE; - DBVARIANT dbv; - int i; - - switch (uMsg){ - case WM_INITDIALOG: - initDlg=TRUE; - TranslateDialogDefault(hwndDlg); - if (!DBGetContactSettingString(NULL, SKYPE_PROTONAME, "Host", &dbv)) { - SetDlgItemTextA(hwndDlg, IDC_HOST, dbv.pszVal); - DBFreeVariant(&dbv); - } else SetDlgItemText(hwndDlg, IDC_HOST, _T("localhost")); - SendDlgItemMessage(hwndDlg, IDC_PORT, EM_SETLIMITTEXT, 5, 0L); - SetDlgItemInt(hwndDlg, IDC_PORT, DBGetContactSettingWord(NULL, SKYPE_PROTONAME, "Port", 1401), FALSE); - CheckDlgButton(hwndDlg, IDC_REQPASS, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "RequiresPassword", 0)); - CheckDlgButton(hwndDlg, IDC_USES2S, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseSkype2Socket", 0)); - if (!DBGetContactSettingString(NULL, SKYPE_PROTONAME, "Password", &dbv)) { - CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM)dbv.pszVal); - SetDlgItemTextA(hwndDlg, IDC_PASSWORD, dbv.pszVal); - DBFreeVariant(&dbv); - } - SendMessage(hwndDlg, WM_COMMAND, IDC_USES2S, 0); - SendMessage(hwndDlg, WM_COMMAND, IDC_REQPASS, 0); - initDlg=FALSE; - return TRUE; - case WM_NOTIFY: { - NMHDR* nmhdr = (NMHDR*)lParam; - - switch (nmhdr->code){ - case PSN_APPLY: - case PSN_KILLACTIVE: - { - char buf[1024]; - GetDlgItemTextA(hwndDlg, IDC_HOST, buf, sizeof(buf)); - DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "Host", buf); - DBWriteContactSettingWord(NULL, SKYPE_PROTONAME, "Port", (unsigned short)GetDlgItemInt(hwndDlg, IDC_PORT, NULL, FALSE)); - DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "RequiresPassword", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_REQPASS), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "UseSkype2Socket", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_USES2S), BM_GETCHECK,0,0))); - ZeroMemory(buf, sizeof(buf)); - GetDlgItemTextA(hwndDlg, IDC_PASSWORD, buf, sizeof(buf)); - CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(buf), (LPARAM)buf); - DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "Password", buf); - return TRUE; - } - } - break; - } - case WM_COMMAND: { - switch (LOWORD(wParam)) { - case IDC_USES2S: - for (i=0; i=5)) { - CheckDlgButton(hwndDlg, IDC_GROUPCHAT, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseGroupchat", 0)); - CheckDlgButton(hwndDlg, IDC_GROUPCHATREAD, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "MarkGroupchatRead", 0)); - } else { - EnableWindow(GetDlgItem(hwndDlg, IDC_GROUPCHAT), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_GROUPCHATREAD), FALSE); - } - -#ifdef USEPOPUP - if (ServiceExists(MS_POPUP_ADDPOPUP)) - CheckDlgButton(hwndDlg, IDC_USEPOPUP, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UsePopup", 0)); - else -#endif - EnableWindow(GetDlgItem(hwndDlg, IDC_USEPOPUP), FALSE); - - j=DBGetContactSettingDword(NULL, SKYPE_PROTONAME, "SkypeOutStatusMode", ID_STATUS_ONTHEPHONE); - for(i=0;icode){ - case PSN_APPLY: - case PSN_KILLACTIVE: - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "EnableMenu", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_ENABLEMENU), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "UsePopup", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_USEPOPUP), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "UseGroupchat", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_GROUPCHAT), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "MarkGroupchatRead", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_GROUPCHATREAD), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "SuppressErrors", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_NOERRORS), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "KeepState", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_KEEPSTATE), BM_GETCHECK,0,0))); - DBWriteContactSettingDword(NULL, SKYPE_PROTONAME, "SkypeOutStatusMode", SendDlgItemMessage(hwndDlg,IDC_SKYPEOUTSTAT,CB_GETITEMDATA,SendDlgItemMessage(hwndDlg,IDC_SKYPEOUTSTAT,CB_GETCURSEL,0,0),0)); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "UseTimeZonePatch", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_TIMEZONE), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "IgnoreTimeZones", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_IGNTZ), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "ShowDefaultSkypeAvatar", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SHOWDEFAULTAVATAR), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "SuppressCallSummaryMessage", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SUPPRESSCALLSUMMARYMESSAGE), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "NoSkype3Stats", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_NOSKYPE3STATS), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "ShowFullname", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SHOWFULLNAME), BM_GETCHECK,0,0))); - return TRUE; - } - break; - } - case WM_COMMAND: { - switch (LOWORD(wParam)) { - case IDC_CLEANUP: - pthread_create(( pThreadFunc )CleanupNicknames, NULL); - break; - } - if (!initDlg) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - return 0; -} - -static int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData) -{ - UNREFERENCED_PARAMETER(lParam); - - switch (uMsg) - { - case BFFM_INITIALIZED: - { - // Set initial directory. -#ifdef UNICODE - wchar_t* wszInitFolder = make_unicode_string((const unsigned char*)lpData); - SendMessage(hWnd, BFFM_SETSELECTION, TRUE, (LPARAM)wszInitFolder); - free(wszInitFolder); -#else - SendMessage(hWnd, BFFM_SETSELECTION, TRUE, lpData); -#endif - break; - } - } - return 0; -} - -INT_PTR CALLBACK OptionsDefaultDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - static BOOL initDlg=FALSE; - static int skypeLaunchControls[]={IDC_NOSPLASH,IDC_MINIMIZED,IDC_NOTRAY,IDC_REMOVEABLE,IDC_SECONDARY,IDC_DATAPATHO,IDC_CUSTOMCOMMAND,IDC_STATIC_PATHINFO}; - - switch (uMsg){ - case WM_INITDIALOG: - { - DBVARIANT dbv; - BOOL startSkype; - int i; - - initDlg=TRUE; - TranslateDialogDefault(hwndDlg); - - startSkype=DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "StartSkype", 1); - - CheckDlgButton(hwndDlg, IDC_STARTSKYPE, (BYTE)startSkype); - CheckDlgButton(hwndDlg, IDC_NOSPLASH, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "nosplash", 1)); - CheckDlgButton(hwndDlg, IDC_MINIMIZED, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "minimized", 1)); - CheckDlgButton(hwndDlg, IDC_NOTRAY, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "notray", 0)); - CheckDlgButton(hwndDlg, IDC_REMOVEABLE, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "removable", 0)); - CheckDlgButton(hwndDlg, IDC_SECONDARY, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "secondary", 0)); - CheckDlgButton(hwndDlg, IDC_DATAPATHO, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "datapath:", 0)); - CheckDlgButton(hwndDlg, IDC_SHUTDOWN, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "Shutdown", 0)); - CheckDlgButton(hwndDlg, IDC_UNLOADOFFLINE, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UnloadOnOffline", 0)); - - CheckDlgButton(hwndDlg, IDC_CUSTOMCOMMAND, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseCustomCommand", 0)); - SendDlgItemMessage(hwndDlg, IDC_COMMANDLINE, EM_SETLIMITTEXT, MAX_PATH-1, 0L); - if(!DBGetContactSettingString(NULL,SKYPE_PROTONAME,"CommandLine",&dbv)) - { - SetWindowTextA(GetDlgItem(hwndDlg, IDC_COMMANDLINE), dbv.pszVal); - DBFreeVariant(&dbv); - } - - SendDlgItemMessage(hwndDlg, IDC_DATAPATH, EM_SETLIMITTEXT, MAX_PATH-1, 0L); - if(!DBGetContactSettingString(NULL,SKYPE_PROTONAME,"datapath",&dbv)) - { - SetWindowTextA(GetDlgItem(hwndDlg, IDC_DATAPATH), dbv.pszVal); - DBFreeVariant(&dbv); - } - - for(i=0; i < sizeof(skypeLaunchControls)/sizeof(skypeLaunchControls[0]); i++) - EnableWindow(GetDlgItem(hwndDlg, skypeLaunchControls[i]), startSkype); - - EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSECMDL), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); - EnableWindow(GetDlgItem(hwndDlg, IDC_COMMANDLINE), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); - - EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSEDP), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); - EnableWindow(GetDlgItem(hwndDlg, IDC_DATAPATH), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); - - // LoginUserName - if(!DBGetContactSettingWString(NULL,SKYPE_PROTONAME,"LoginUserName",&dbv)) - { - SetWindowTextW(GetDlgItem(hwndDlg, IDC_USERNAME), dbv.pwszVal); - DBFreeVariant(&dbv); - } - - // LoginPassword - if(!DBGetContactSettingWString(NULL,SKYPE_PROTONAME,"LoginPassword",&dbv)) - { - SetWindowTextW(GetDlgItem(hwndDlg, IDC_PASSWORD), dbv.pwszVal); - DBFreeVariant(&dbv); - } - - SendDlgItemMessage(hwndDlg, IDC_CONNATTEMPTS, EM_SETLIMITTEXT, 3, 0L); - SetDlgItemInt (hwndDlg, IDC_CONNATTEMPTS, DBGetContactSettingWord(NULL, SKYPE_PROTONAME, "ConnectionAttempts", 10), FALSE); - SendMessage(hwndDlg, WM_COMMAND, IDC_STARTSKYPE, 0); - initDlg=FALSE; - return TRUE; - } - case WM_NOTIFY: { - NMHDR* nmhdr = (NMHDR*)lParam; - - switch (nmhdr->code){ - case PSN_APPLY: - case PSN_KILLACTIVE: - { - char text[500]; - WCHAR wtext[500]; - char szRelativePath[MAX_PATH]; - - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "StartSkype", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_STARTSKYPE), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "nosplash", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_NOSPLASH), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "minimized", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_MINIMIZED), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "notray", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_NOTRAY), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "Shutdown", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SHUTDOWN), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "UnloadOnOffline", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_UNLOADOFFLINE), BM_GETCHECK,0,0))); - DBWriteContactSettingWord (NULL, SKYPE_PROTONAME, "ConnectionAttempts", (unsigned short)GetDlgItemInt(hwndDlg, IDC_CONNATTEMPTS, NULL, FALSE)); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "UseCustomCommand", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "datapath:", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "removable", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_REMOVEABLE), BM_GETCHECK,0,0))); - DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "secondary", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SECONDARY), BM_GETCHECK,0,0))); - - GetDlgItemTextA(hwndDlg,IDC_COMMANDLINE,text,sizeof(text)); - strncpy(szRelativePath, text, sizeof(szRelativePath)-1); - CallService (MS_UTILS_PATHTORELATIVE, (WPARAM)text, (LPARAM)szRelativePath); - DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "CommandLine", szRelativePath); - - GetDlgItemTextA(hwndDlg,IDC_DATAPATH,text,sizeof(text)); - strncpy(szRelativePath, text, sizeof(szRelativePath)-1); - CallService (MS_UTILS_PATHTORELATIVE, (WPARAM)text, (LPARAM)szRelativePath); - DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "datapath", szRelativePath); - - // LoginUserName - GetDlgItemTextW(hwndDlg,IDC_USERNAME,wtext,sizeof(wtext)/sizeof(WCHAR)); - DBWriteContactSettingWString(NULL, SKYPE_PROTONAME, "LoginUserName", wtext); - - // LoginPassword - GetDlgItemTextW(hwndDlg,IDC_PASSWORD,wtext,sizeof(wtext)/sizeof(WCHAR)); - DBWriteContactSettingWString(NULL, SKYPE_PROTONAME, "LoginPassword", wtext); - - return TRUE; - } - } - break; - } - case WM_COMMAND: { - switch (LOWORD(wParam)) { - BOOL startSkype; - int i; - case IDC_STARTSKYPE: - startSkype=SendMessage(GetDlgItem(hwndDlg, IDC_STARTSKYPE), BM_GETCHECK,0,0); - - for(i=0; i < sizeof(skypeLaunchControls)/sizeof(skypeLaunchControls[0]); i++) - EnableWindow(GetDlgItem(hwndDlg, skypeLaunchControls[i]), startSkype); - - EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSECMDL), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); - EnableWindow(GetDlgItem(hwndDlg, IDC_COMMANDLINE), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); - - EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSEDP), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); - EnableWindow(GetDlgItem(hwndDlg, IDC_DATAPATH), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); - break; - case IDC_CLEANUP: - pthread_create(( pThreadFunc )CleanupNicknames, NULL); - break; - case IDC_DATAPATHO: - EnableWindow(GetDlgItem(hwndDlg, IDC_DATAPATH), SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); - EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSEDP), SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); - break; - case IDC_CUSTOMCOMMAND: - EnableWindow(GetDlgItem(hwndDlg, IDC_COMMANDLINE), SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); - EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSECMDL), SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); - break; - case IDC_BROWSECMDL: - { - OPENFILENAMEA ofn={0}; - BOOL gofnResult; - char szFileName[MAX_PATH]; - char szAbsolutePath[MAX_PATH]; - - ofn.lStructSize=sizeof(ofn); - ofn.hwndOwner=hwndDlg; - ofn.lpstrFilter="Executable files (*.exe)\0*.exe\0All files (*.*)\0*.*\0"; - ofn.nMaxFile=sizeof(szFileName); - ofn.lpstrDefExt="exe"; - ofn.lpstrFile=szFileName; - ofn.Flags=OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ENABLESIZING; - - GetDlgItemTextA(hwndDlg,IDC_COMMANDLINE,szFileName,sizeof(szFileName)); - TranslateMirandaRelativePathToAbsolute(szFileName, szAbsolutePath, FALSE); - strcpy (szFileName, szAbsolutePath); - - if (!(gofnResult = GetOpenFileNameA(&ofn)) && CommDlgExtendedError() == FNERR_INVALIDFILENAME){ - strcpy(szFileName, ".\\Skype.exe"); - TranslateMirandaRelativePathToAbsolute(szFileName, szAbsolutePath, FALSE); - strcpy (szFileName, szAbsolutePath); - gofnResult = GetOpenFileNameA(&ofn); - } - - if(gofnResult) - SetWindowTextA(GetDlgItem(hwndDlg, IDC_COMMANDLINE), szFileName); - - break; - } - case IDC_BROWSEDP: - { - BROWSEINFOA bi={0}; - LPITEMIDLIST pidl; - char szFileName[MAX_PATH]; - char szAbsolutePath[MAX_PATH]; - - GetDlgItemTextA (hwndDlg, IDC_DATAPATH, szFileName, MAX_PATH); - - TranslateMirandaRelativePathToAbsolute(szFileName, szAbsolutePath, FALSE); - bi.hwndOwner = hwndDlg; - bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_SHAREABLE | BIF_NEWDIALOGSTYLE | BIF_NONEWFOLDERBUTTON; - bi.lpfn = BrowseCallbackProc; - bi.lParam = (LPARAM)szAbsolutePath; - - if ( (pidl = SHBrowseForFolderA (&bi)) ) { - if (SHGetPathFromIDListA (pidl, szFileName)) - SetDlgItemTextA (hwndDlg, IDC_DATAPATH, szFileName); - CoTaskMemFree (pidl); - } - break; - } - -#ifdef SKYPE_AUTO_DETECTION - case IDC_AUTODETECTION: - DoAutoDetect(hwndDlg); - break; -#endif - } - if (!initDlg) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// OnDetailsInit - initializes user info dialog pages. - -int OnDetailsInit( WPARAM wParam, LPARAM lParam ) -{ - OPTIONSDIALOGPAGE odp = {0}; - HANDLE hContact = ( HANDLE )lParam; - - odp.cbSize = sizeof(odp); - odp.hIcon = NULL; - odp.hInstance = hInst; - - if ( hContact == NULL ) { - - char szTitle[256]; - - if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 7, 0, 27) && !bIsImoproxy) - { - mir_snprintf( szTitle, sizeof( szTitle ), "%s %s", SKYPE_PROTONAME, Translate( "Avatar" )); - - odp.pfnDlgProc = AvatarDlgProc; - odp.position = 1900000000; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_SETAVATAR); - odp.pszTitle = szTitle; - CallService(MS_USERINFO_ADDPAGE, wParam, (LPARAM)&odp); - } - - mir_snprintf( szTitle, sizeof( szTitle ), "%s %s", SKYPE_PROTONAME, Translate( "Details" )); - - odp.pfnDlgProc = DetailsDlgProc; - odp.position = 1900000000; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_SETDETAILS); - odp.pszTitle = szTitle; - CallService(MS_USERINFO_ADDPAGE, wParam, (LPARAM)&odp); - } - - return 0; -} - -/*AvatarDlgProc -* -* For setting the skype avatar -* -*/ -INT_PTR CALLBACK AvatarDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static RECT r; - - UNREFERENCED_PARAMETER(lParam); - - switch ( msg ) { - case WM_INITDIALOG: - TranslateDialogDefault( hwndDlg ); - - hAvatar = NULL; - if(ServiceExists(MS_AV_GETMYAVATAR)){ - struct avatarCacheEntry *ace = (struct avatarCacheEntry *)CallService(MS_AV_GETMYAVATAR, 0,(LPARAM) SKYPE_PROTONAME); - if (ace!=NULL) { - hAvatar = ( HBITMAP )CallService( MS_UTILS_LOADBITMAP, 0, ( LPARAM )ace->szFilename); - if ( hAvatar != NULL ) - SendDlgItemMessage(hwndDlg, IDC_AVATAR, STM_SETIMAGE, IMAGE_BITMAP, (WPARAM)hAvatar ); - } - } - - - - return TRUE; - - case WM_COMMAND: - if ( HIWORD( wParam ) == BN_CLICKED ) { - switch( LOWORD( wParam )) { - case IDC_SETAVATAR: - { - char szFileName[ MAX_PATH ]; - if ( EnterBitmapFileName( szFileName ) != ERROR_SUCCESS ) - return FALSE; - - hAvatar = ( HBITMAP )CallService( MS_UTILS_LOADBITMAP, 0, ( LPARAM )szFileName); - if ( hAvatar != NULL ){ - SendDlgItemMessage(hwndDlg, IDC_AVATAR, STM_SETIMAGE, IMAGE_BITMAP, (WPARAM)hAvatar ); - CallService(SKYPE_SETAVATAR, 0, ( LPARAM )szFileName); - } - break; - } - case IDC_DELETEAVATAR: - if ( hAvatar != NULL ) { - DeleteObject( hAvatar ); - hAvatar = NULL; - CallService(SKYPE_SETAVATAR, 0, 0); - } - DBDeleteContactSetting( NULL, SKYPE_PROTONAME, "AvatarFile" ); - InvalidateRect( hwndDlg, NULL, TRUE ); - break; - } } - break; - - case WM_DESTROY: - if ( hAvatar != NULL ) - DeleteObject( hAvatar ); - break; - } - - return 0; -} - -/*DetailsDlgProc -* -* For setting the skype infos -* -*/ -INT_PTR CALLBACK DetailsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static int sexM = 0,sexF = 0, sex; - - UNREFERENCED_PARAMETER(lParam); - - switch ( msg ) { - case WM_INITDIALOG: - TranslateDialogDefault( hwndDlg ); - - ZeroMemory (&myProfile, sizeof(myProfile)); - SkypeProfile_Load(&myProfile); - if(SkypeInitialized) - SkypeProfile_LoadFromSkype(&myProfile); - - SendDlgItemMessage(hwndDlg,IDC_SEX,CB_ADDSTRING,0,(LPARAM)_T("")); - sexM = SendDlgItemMessage(hwndDlg,IDC_SEX,CB_ADDSTRING,0,(LPARAM)TranslateT("MALE")); - sexF = SendDlgItemMessage(hwndDlg,IDC_SEX,CB_ADDSTRING,0,(LPARAM)TranslateT("FEMALE")); - - switch(myProfile.Sex) { - case 0x4D: SendDlgItemMessage(hwndDlg,IDC_SEX,CB_SETCURSEL, sexM, 0); break; - case 0x46: SendDlgItemMessage(hwndDlg,IDC_SEX,CB_SETCURSEL, sexF, 0); break; - } - - SetDlgItemText(hwndDlg, IDC_FULLNAME, myProfile.FullName); - SetDlgItemTextA(hwndDlg, IDC_HOMEPAGE, myProfile.HomePage); - SetDlgItemTextA(hwndDlg, IDC_HOMEPHONE, myProfile.HomePhone); - SetDlgItemTextA(hwndDlg, IDC_OFFICEPHONE, myProfile.OfficePhone); - SetDlgItemText(hwndDlg, IDC_CITY, myProfile.City); - SetDlgItemText(hwndDlg, IDC_PROVINCE, myProfile.Province); - DateTime_SetSystemtime (GetDlgItem (hwndDlg, IDC_BIRTHDAY), GDT_VALID, &myProfile.Birthday); - return TRUE; - - case WM_COMMAND: - if ( HIWORD( wParam ) == BN_CLICKED ) { - switch( LOWORD( wParam )) { - case IDC_SAVEDETAILS: - GetDlgItemText(hwndDlg,IDC_FULLNAME,myProfile.FullName,sizeof(myProfile.FullName)/sizeof(TCHAR)); - GetDlgItemTextA(hwndDlg,IDC_HOMEPAGE,myProfile.HomePage,sizeof(myProfile.HomePage)/sizeof(TCHAR)); - GetDlgItemTextA(hwndDlg,IDC_HOMEPHONE,myProfile.HomePhone,sizeof(myProfile.HomePhone)/sizeof(TCHAR)); - GetDlgItemTextA(hwndDlg,IDC_OFFICEPHONE,myProfile.OfficePhone,sizeof(myProfile.OfficePhone)/sizeof(TCHAR)); - GetDlgItemText(hwndDlg,IDC_CITY,myProfile.City,sizeof(myProfile.City)/sizeof(TCHAR)); - GetDlgItemText(hwndDlg,IDC_PROVINCE,myProfile.Province,sizeof(myProfile.Province)/sizeof(TCHAR)); - sex = SendMessage(GetDlgItem(hwndDlg,IDC_SEX),CB_GETCURSEL,0,0); - - myProfile.Sex = 0; - if(sex == sexF) myProfile.Sex = 0x46; else - if(sex == sexM) myProfile.Sex = 0x4D; - DateTime_GetSystemtime (GetDlgItem (hwndDlg, IDC_BIRTHDAY), &myProfile.Birthday); - - SkypeProfile_Save(&myProfile); - if(SkypeInitialized) - SkypeProfile_SaveToSkype(&myProfile); - break; - } - } - break; - - case WM_DESTROY: - if ( hAvatar != NULL ) - DeleteObject( hAvatar ); - break; - } - - return 0; -} - -#ifdef SKYPE_AUTO_DETECTION -/** - * DoAutoDetect - * @param dlg The default option dialog handle - */ -void DoAutoDetect(HWND dlg) -{ - char basePath[MAX_PATH]; - char fileName[MAX_PATH]; - char tmpUser[255]; - ezxml_t f1, acc; - - if (FAILED(SHGetFolderPath(dlg,CSIDL_APPDATA,NULL,0,basePath))) - { - OUTPUT("Error in retrieving appdata path!"); - return; - } - - strcat(basePath,"\\Skype\\"); - sprintf (fileName, "%s\\shared.xml", basePath); - - if (f1 = ezxml_parse_file(fileName)) - { - if (acc = ezxml_get(f1, "Lib", 0, "Account", 0, "Default", -1)) - { - if (GetWindowTextA(GetDlgItem(dlg,IDC_USERNAME),tmpUser,sizeof(tmpUser))) - SetWindowTextA(GetDlgItem(dlg,IDC_USERNAME),acc->txt); - /* Can't find this stuff in current Skype verions?? - sprintf (fileName, "%s\\%s\\config.xml", basePath, acc->txt); - if ((acc = ezxml_get(f1, "UI", 0, "Messages", 0, "OpenWindowInCompactMode", -1)) && *acc->txt!='0') - { - ezxml_set_txt (acc, "0"); - // ezXML doesn't supprot saving yet - } - */ - } - ezxml_free(f1); - } - else - { - OUTPUT("Failed to open skypes configuration files!"); - return; - } -} -#endif diff --git a/!NotAdopted/Skype/skypeopt.h b/!NotAdopted/Skype/skypeopt.h deleted file mode 100644 index 23aa7a5212..0000000000 --- a/!NotAdopted/Skype/skypeopt.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * RegisterOptions - * - * This function tells Miranda to add the configuration section of this plugin in - * the Options-dialog. - */ -int RegisterOptions(WPARAM wParam, LPARAM lParam); -/* - * OptionsDlgProc - * - * This callback function is called, when the options dialog in Miranda is shown - * The function contains all necessary stuff to process the options in the dialog - * and store them in the database, when changed, and fill out the settings-dialog - * correctly according to the current settings - */ -INT_PTR CALLBACK OptionsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - -INT_PTR CALLBACK OptionsDefaultDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK OptionsAdvancedDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK OptionsProxyDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK OptPopupDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - -/* -* Procedure to call when the option page is asked -* -*/ -int OnDetailsInit( WPARAM wParam, LPARAM lParam ); - -/* -* Dialog to change avatar in user details. -* -* -*/ -INT_PTR CALLBACK AvatarDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -/* -* Dialog to change infos in user details. -* -* -*/ -INT_PTR CALLBACK DetailsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -/* - * Helper functions - * - */ -void DoAutoDetect(HWND dlg); - -; \ No newline at end of file diff --git a/!NotAdopted/Skype/skypeprofile.c b/!NotAdopted/Skype/skypeprofile.c deleted file mode 100644 index 3bf3c0b955..0000000000 --- a/!NotAdopted/Skype/skypeprofile.c +++ /dev/null @@ -1,145 +0,0 @@ -#pragma warning (disable: 4706) // assignment within conditional expression - -#include "skypeprofile.h" -#include "skypeapi.h" -#include "utf8.h" - -extern char g_szProtoName[]; - -void SkypeProfile_Save(SkypeProfile *pstProf) -{ - DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "Gender", pstProf->Sex); - DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "HomePhone", pstProf->HomePhone); - DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "OfficePhone", pstProf->OfficePhone); - DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "HomePage", pstProf->HomePage); - DBWriteContactSettingTString(NULL, SKYPE_PROTONAME, "Nick", pstProf->FullName); - DBWriteContactSettingTString(NULL, SKYPE_PROTONAME, "City", pstProf->City); - DBWriteContactSettingTString(NULL, SKYPE_PROTONAME, "Province", pstProf->Province); - DBWriteContactSettingWord(NULL, SKYPE_PROTONAME, "BirthYear", (WORD)pstProf->Birthday.wYear); - DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "BirthMonth", (BYTE)pstProf->Birthday.wMonth); - DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "BirthDay", (BYTE)pstProf->Birthday.wDay); -} - -void SkypeProfile_Load(SkypeProfile *pstProf) -{ - DBVARIANT dbv; - - pstProf->Sex = (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "Gender", 0); - pstProf->Birthday.wYear = (WORD)DBGetContactSettingWord(NULL, SKYPE_PROTONAME, "BirthYear", 1900); - pstProf->Birthday.wMonth = (WORD)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "BirthMonth", 01); - pstProf->Birthday.wDay = (WORD)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "BirthDay", 01); - if(!DBGetContactSettingTString(NULL,SKYPE_PROTONAME,"Nick",&dbv)) - { - _tcsncpy (pstProf->FullName, dbv.ptszVal, sizeof(pstProf->FullName)/sizeof(TCHAR)); - DBFreeVariant(&dbv); - } - if(!DBGetContactSettingString(NULL,SKYPE_PROTONAME,"HomePage",&dbv)) - { - strncpy (pstProf->HomePage, dbv.pszVal, sizeof(pstProf->HomePage)); - DBFreeVariant(&dbv); - } - if(!DBGetContactSettingTString(NULL,SKYPE_PROTONAME,"Province",&dbv)) - { - _tcsncpy (pstProf->Province, dbv.ptszVal, sizeof(pstProf->Province)/sizeof(TCHAR)); - DBFreeVariant(&dbv); - } - if(!DBGetContactSettingTString(NULL,SKYPE_PROTONAME,"City",&dbv)) - { - _tcsncpy (pstProf->City, dbv.ptszVal, sizeof(pstProf->City)/sizeof(TCHAR)); - DBFreeVariant(&dbv); - } - if(!DBGetContactSettingString(NULL,SKYPE_PROTONAME,"OfficePhone",&dbv)) - { - strncpy (pstProf->OfficePhone, dbv.pszVal, sizeof(pstProf->OfficePhone)); - DBFreeVariant(&dbv); - } - if(!DBGetContactSettingString(NULL,SKYPE_PROTONAME,"HomePhone",&dbv)) - { - strncpy (pstProf->HomePhone, dbv.pszVal, sizeof(pstProf->HomePhone)); - DBFreeVariant(&dbv); - } -} - -static void LoadSaveSkype(SkypeProfile *pstProf, BOOL bSet) -{ -#pragma warning (push) -#pragma warning (disable: 4204) // nonstandard extension used : non-constant aggregate initializer -#define ENTRY(x,y) {x, pstProf->y, sizeof(pstProf->y)/sizeof(pstProf->y[0]), sizeof(pstProf->y[0])} - const struct { - char *pszSetting; - LPVOID lpDest; - int iSize; - char cType; - } astSettings[] = { - ENTRY("FULLNAME", FullName), - ENTRY("PHONE_HOME", HomePhone), - ENTRY("PHONE_OFFICE", OfficePhone), - ENTRY("HOMEPAGE", HomePage), - ENTRY("CITY", City), - ENTRY("PROVINCE", Province) - }; -#pragma warning (pop) -#undef ENTRY - char *ptr; - int i; - - if (bSet) { - char *pBuf, szBirthday[16]; - for (i=0; iSex) - { - case 0x4D: SkypeSetProfile ("SEX", "MALE"); break; - case 0x46: SkypeSetProfile ("SEX", "FEMALE"); break; - } - sprintf (szBirthday, "%04d%02d%02d", pstProf->Birthday.wYear, pstProf->Birthday.wMonth, pstProf->Birthday.wDay); - SkypeSetProfile ("BIRTHDAY", szBirthday); - } else { - for (i=0; iSex=0x4D; else - if (!_stricmp(ptr, "FEMALE")) pstProf->Sex=0x46; - free (ptr); - } - if (ptr=SkypeGetProfile("BIRTHDAY")) - { - if (*ptr != '0') - sscanf(ptr, "%04hd%02hd%02hd", &pstProf->Birthday.wYear, &pstProf->Birthday.wMonth, - &pstProf->Birthday.wDay); - free(ptr); - } - } -} - -void SkypeProfile_LoadFromSkype(SkypeProfile *pstProf) -{ - LoadSaveSkype (pstProf, FALSE); -} - -void SkypeProfile_SaveToSkype(SkypeProfile *pstProf) -{ - LoadSaveSkype (pstProf, TRUE); -} \ No newline at end of file diff --git a/!NotAdopted/Skype/skypeprofile.h b/!NotAdopted/Skype/skypeprofile.h deleted file mode 100644 index 60531128d1..0000000000 --- a/!NotAdopted/Skype/skypeprofile.h +++ /dev/null @@ -1,33 +0,0 @@ -// System includes -#include -#include -#include -#include -#include -#include "resource.h" -#include "skype.h" - -#pragma warning (push) -#pragma warning (disable: 4100) // unreferenced formal parameter -// Miranda database access -#include "../../include/newpluginapi.h" -#include "../../include/m_database.h" -#pragma warning (pop) - -typedef struct -{ - TCHAR FullName[256]; - char HomePhone[256]; - char OfficePhone[256]; - char HomePage[256]; - TCHAR City[256]; - TCHAR Province[256]; - BYTE Sex; - SYSTEMTIME Birthday; -} SkypeProfile; - -void SkypeProfile_Load(SkypeProfile *pstProf); -void SkypeProfile_Save(SkypeProfile *pstProf); -void SkypeProfile_Free(SkypeProfile *pstProf); -void SkypeProfile_LoadFromSkype(SkypeProfile *pstProf); -void SkypeProfile_SaveToSkype(SkypeProfile *pstProf); diff --git a/!NotAdopted/Skype/skypeproxy.h b/!NotAdopted/Skype/skypeproxy.h deleted file mode 100644 index 8e1490803e..0000000000 --- a/!NotAdopted/Skype/skypeproxy.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Commands for command mode of Skype proxy */ - -#define AUTHENTICATE 0x01 -#define CAPABILITIES 0x02 - -/* Capabilities flags of Skypeproxy */ -#define USE_AUTHENTICATION 0x01 \ No newline at end of file diff --git a/!NotAdopted/Skype/skypeproxy/skypeproxy.c b/!NotAdopted/Skype/skypeproxy/skypeproxy.c deleted file mode 100644 index fff9c1b916..0000000000 --- a/!NotAdopted/Skype/skypeproxy/skypeproxy.c +++ /dev/null @@ -1,651 +0,0 @@ -/* - -Purpose -======= -This program opens a connection on a local TCP/IP port and sends/ -receives Skype-API calls on it so that you can remote-control -Skype over a network. -Note, that there are currently NO SECURITY mechanisms, so don't -use this over an untrusted network! - -Author -====== -This program was written by leecher in 2005 (mailto:leecher@dose.0wnz.at) -Please give feedback at http://forum.skype.com/viewtopic.php?t=16187 - -Protocol -======== -Basic protocol structure ------------------------- -Sender and receiver have the same protocol: - - [(UINT)Length of message][(char[])Message] - -The Length is so that you can malloc() enough space for the data buffer -to receive the next message. - -A special case is, if the [Length of message] is 0. In this case the -client tells the server that he wants to switch to command mode. - -Command mode ------------- -The server expects - - [(char)Command] - -next. Currently the following commands are supported: - - CAPABILITIES - returns the Server's capabilities - AUTHENTICATE - Starts the authentification process - -CAPABILITIES ------------- -The server returns - - [(char)Capabilities] - -where this currently can be the following: - - USE_AUTHENTICATION - The server supports and requires authentication - -AUTHENTICATE ------------- -The server returns - - [(char)0x01] - -if authentication is supported AND needed (skypeproxy started with -k switch) or - - [(char)0x00] - -if this is not the case. -If 0x01 was returned the server next expects a normal message -(see "Basic protocol structure) containing the password. -If the authentication was successful, the server replies with - - [(char)0x01] - -otherwise with - - [(char)0x00] - -PLEASE NOTE THAT THE AUTHENTICATION CURRENTLY IS PLAIN TEXT. SO DON'T -USE THIS PROGRAM OVER AN UNTRUSTED NETWORK, OTHERWISE THERE MAY BE THE -POSSIBILITY THAT SOMEONE SNIFFS YOUR PASSWORD! - -Code example ------------- - -SOCKET MySocket; - -int SendPacket(char *szSkypeMessage) { - unsigned int length=strlen(szSkypeMsg); - - if (send(MySocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR || - send(MySocket, szSkypeMsg, length, 0)==SOCKET_ERROR) - return -1; - return 0; -} - -// don't forget to free() the return value on my Heap!! -char *ReceivePacket(void) { - unsigned int lenght, received; - char *buf; - - if ((received=recv(MySocket, (char *)&length, sizeof(length), 0))==SOCKET_ERROR || - received==0) - return NULL; - if (!(buf=calloc(1, length+1))) return NULL; - if (recv(MySocket, buf, length, 0)==SOCKET_ERROR) { - free(buf); - return NULL; - } - return buf; -} - - -License -======= -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -History -======== -V1.0alpha - First preview release -V1.0 - Implemented killing & restarting Skype process when it dies - - BUGFIX: SendMessage() is a blocking call, if Skype hangs our app hangs too -> Fixed - - Added command line parsing. - - Renamed from Skype2Socket to skypeproxy - - Added authentication feature. -*/ - -#include -#include -#include -#include -#include "skypeproxy.h" - -UINT ControlAPIAttach, ControlAPIDiscover; -HWND hSkypeWnd=NULL, hWnd; -HANDLE SkypeReady, ServerThreadBye; -LONG AttachStatus=-1; -int exitcode=EXIT_SUCCESS; -char skype_path[MAX_PATH], *password=NULL; -BYTE WatchDog=1; -BOOL WatchDogRunning=FALSE, Authenticated=FALSE; -SOCKET ListenSocket, AcceptSocket; - - -void bail_out(int i) { - OUTPUT("Got termination signal, bailing out."); - if (i==1) exitcode=EXIT_FAILURE; - PostMessage(hWnd, WM_QUIT, 0, 0); -} - -BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ) { - DWORD dwID ; - - GetWindowThreadProcessId(hwnd, &dwID) ; - if(dwID == (DWORD)lParam) - PostMessage(hwnd, WM_CLOSE, 0, 0) ; // May you be so kind to quit, please? - - return TRUE ; -} - -/* ConnectToSkypeAPI - * - * Purpose: Establish a connection to the Skype API - * Params : ForceRestart - Kill Skype if it's running before restarting - * Returns: 0 - Connecting succeeded - * -1 - Something went wrong - */ -void ConnectToSkypeAPI(void *ForceRestart) { - BOOL SkypeLaunched=FALSE; - int counter=0, i, j; - char *args[5]; - char *SkypeOptions[]={"/notray", "/nosplash", "/minimized"}; - char *szFuncName="ConnectToSkypeAPI"; - - ResetEvent(SkypeReady); - AttachStatus=-1; - if ((BOOL)ForceRestart) { - HANDLE hProc; - DWORD dwPID=0; - - if (!hSkypeWnd) { - OUTPUT("I can't kill Skype, as I don't even have its window handle!"); - return; - } - GetWindowThreadProcessId(hSkypeWnd, &dwPID); - LOG(("%s: Shutting down Skype as it was not behaving the way it should...", szFuncName)); - if (hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, dwPID)) { - - // Try to shutdown Skype the nice way by asking it to close - EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM) dwPID); - - if(WaitForSingleObject(hProc, 10000)!=WAIT_OBJECT_0) { - // Try it the hard way by killing it - LOG(("%s: I tried it the nice way, but you were not listening! Now DIIIIEEE!", szFuncName)); - if (!TerminateProcess(hProc,0)) { - OUTPUT("Argh, process refused to die, it's too mighty for me, I've given up"); - CloseHandle(hProc); - return; - } - LOG(("%s: Process killed! >:)", szFuncName)); - } - CloseHandle(hProc); - } - } - do { - /* To initiate communication, Client should broadcast windows message - ('SkypeControlAPIDiscover') to all windows in the system, specifying its own - window handle in wParam parameter. - */ - LOG(("%s: Sending discover message..", szFuncName)); - SendMessageTimeout(HWND_BROADCAST, ControlAPIDiscover, (WPARAM)hWnd, 0, SMTO_ABORTIFHUNG, 3000, NULL); - LOG(("%s: Discover message sent, waiting for Skype to become ready..", szFuncName)); - - /* In response, Skype responds with - message 'SkypeControlAPIAttach' to the handle specified, and indicates - connection status - SkypeReady is set if there is an answer by Skype other than API_AVAILABLE. - If there is no answer after 3 seconds, launch Skype as it's propably - not running. - */ - if (WaitForSingleObject(SkypeReady, 3000)==WAIT_TIMEOUT && - AttachStatus!=SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION) - { - if (hWnd==NULL) { - LOG(("%s: hWnd of SkypeDispatchWindow not yet set..", szFuncName)); - continue; - } - if (!SkypeLaunched && skype_path) { - LOG(("%s: Starting Skype, as it's not running", szFuncName)); - args[0]=skype_path; - j=1; - for (i=0; i<3; i++) { - args[j]=SkypeOptions[i]; - LOG(("%s: Using Skype parameter: ", szFuncName, args[j])); - j++; - } - args[j]=NULL; - _spawnv(_P_NOWAIT, skype_path, args); - ResetEvent(SkypeReady); - SkypeLaunched=TRUE; - LOG(("%s: Skype process started.", szFuncName)); - // Skype launching iniciated, keep sending Discover messages until it responds. - continue; - } else { - LOG(("%s: Check if Skype was launchable..", szFuncName)); - if (!skype_path) { - OUTPUT("There was no correct path for Skype application"); - bail_out(1); - return; - } - LOG("%s: Trying to attach: #%d", szFuncName, counter)); - counter++; - if (counter==5) { - OUTPUT("ERROR: Skype not running / too old / working!"); - bail_out(1); - return; - } - } - } - LOG(("%s: Attachstatus %d", szFuncName, AttachStatus)); - } while (AttachStatus==SKYPECONTROLAPI_ATTACH_API_AVAILABLE || AttachStatus==-1); - - while (AttachStatus==SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION) Sleep(1000); - LOG(("%s: Attachstatus %d", szFuncName, AttachStatus)); - if (AttachStatus!=SKYPECONTROLAPI_ATTACH_SUCCESS) { - switch(AttachStatus) { - case SKYPECONTROLAPI_ATTACH_REFUSED: - OUTPUT("Skype refused the connection :("); - break; - case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE: - OUTPUT("The Skype API is not available"); - break; - default: - LOG(("%s: ERROR: AttachStatus: %d", szFuncName, AttachStatus)); - OUTPUT("Wheee, Skype won't let me use the API. :("); - } - bail_out(1); - return; - } - OUTPUT("Attached to Skype successfully."); - if (!WatchDogRunning) - if (_beginthread(WatchDogTimer, 0, NULL)==-1) { - OUTPUT("Cannot start Watchdog."); - bail_out(1); - } - return; -} - -void SkypeSend(char *szMsg) { - COPYDATASTRUCT CopyData; - int count=0; - - if (!hSkypeWnd) { - LOG(("SkypeSend: DAMN! No Skype window handle! :(")); - return; - } - if (strcmp(szMsg, "PING")) {LOG(("> %s", szMsg));} - CopyData.dwData=0; - CopyData.lpData=szMsg; - CopyData.cbData=strlen(szMsg)+1; - while (!SendMessageTimeout(hSkypeWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&CopyData, SMTO_ABORTIFHUNG, 3000, NULL)) { - count++; - LOG(("SkypeSend: failed, try #%d", count)); - if (count==5) { - OUTPUT("Sending message to Skype failed too often."); - OUTPUT("Skype may have died unexpectedly, I will try to restart it."); - ConnectToSkypeAPI((void *)TRUE); - OUTPUT("Restart complete. Trying to deliver message one more time."); - if (!SendMessageTimeout(hSkypeWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&CopyData, SMTO_ABORTIFHUNG, 3000, NULL)) { - OUTPUT("It still failed. Skype seems to be completely f*cked up. I've given up. Bye.."); - bail_out(1); - break; - } else { - OUTPUT("Now it worked! :)"); - break; - } - } - Sleep(1000); - } -} - -void ServerThread(char *dummy) { - unsigned int length, received; - char *buf, command, reply; - - LOG(("ServerThread started")); - AcceptSocket=INVALID_SOCKET; - while( AcceptSocket == INVALID_SOCKET) { - if ((AcceptSocket = accept( ListenSocket, NULL, NULL ))==INVALID_SOCKET) { - LOG(("ServerThread: Byebye...")); - SetEvent(ServerThreadBye); - bail_out(1); - return; - } - OUTPUT("Connection by client"); - while(1) { - if ((received=recv(AcceptSocket, (char *)&length, sizeof(length), 0))==SOCKET_ERROR || - received==0) - { - OUTPUT("Connection was closed by client. See ya soon! :)"); - break; - } - // Command mode - if (length==0) { - reply=0; - if (recv(AcceptSocket, (char *)&command, 1, 0)==SOCKET_ERROR) { - OUTPUT("Connection to client was lost."); - break; - } -#ifdef USE_AUTHENTICATION - if (command==AUTHENTICATE) - if (password) reply=0x01; // Ok, go ahead - else command=0; -#endif - if (command==CAPABILITIES) - reply=password?USE_AUTHENTICATION:0; - - if (send(AcceptSocket, (char *)&reply, 1, 0)==SOCKET_ERROR) { - OUTPUT("Connection to client was lost."); - break; - } - continue; - } - // Normal Skype API-call - if (!(buf=calloc(1, length+1))) { - OUTPUT("Out of memory error while allocating buffer space."); - break; - } - if (recv(AcceptSocket, buf, length, 0)==SOCKET_ERROR) { - OUTPUT("Connection to client was lost."); - free(buf); - break; - } - switch (command) { -#ifdef USE_AUTHENTICATION - case 0x01: // Compare hash - if (password && !strcmp(password, buf)) Authenticated=TRUE; - else Authenticated=FALSE; - if (Authenticated) { - OUTPUT("User authenticated succesfully."); - reply=1; - } else { - OUTPUT("User authentication failed!! (Intruder?)"); - reply=0; - } - if (send(AcceptSocket, (char *)&reply, 1, 0)==SOCKET_ERROR) { - OUTPUT("Connection to client was lost."); - break; - } - command=0; - break; -#endif - default: -#ifdef USE_AUTHENTICATION - if (password && !Authenticated) break; -#endif - SkypeSend(buf); - } - command=0; - free(buf); - } - AcceptSocket=INVALID_SOCKET; -#ifdef USE_AUTHENTICATION - Authenticated=FALSE; -#endif - } -} - - -void WatchDogTimer(char *dummy) { - LOG(("WatchDogTimer started")); - WatchDogRunning=TRUE; - while (1) { - Sleep(PING_INTERVAL); - if (!WatchDog) { - OUTPUT("Ouch.. It seems that Skype has died unexpectedly. Trying to restart."); - ConnectToSkypeAPI((void *)TRUE); - } - WatchDog=0; - SkypeSend("PING"); - } -} - -LONG APIENTRY WndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam) -{ - PCOPYDATASTRUCT CopyData; - char *szSkypeMsg=NULL; - - switch (message) - { - case WM_COPYDATA: -// LOG("WM_COPYDATA", "start"); - if(hSkypeWnd==(HWND)wParam) { - CopyData=(PCOPYDATASTRUCT)lParam; - szSkypeMsg=strdup(CopyData->lpData); - ReplyMessage(1); - if (!strcmp(szSkypeMsg, "PONG")) { - WatchDog=1; - break; - } // Hide PING-PONG - LOG(("< %s", szSkypeMsg)); - if (!strcmp(szSkypeMsg, "USERSTATUS LOGGEDOUT")) { - OUTPUT("Skype shut down gracefully. I'll leave too, bye.. :)"); - bail_out(1); - } -#ifdef USE_AUTHENTICATION - if (password && !Authenticated) break; -#endif - if (AcceptSocket!=INVALID_SOCKET) { - unsigned int length=strlen(szSkypeMsg); - - if (send(AcceptSocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR || - send(AcceptSocket, szSkypeMsg, length, 0)==SOCKET_ERROR) - OUTPUT("Cannot send to client :("); - } - } - break; - - case WM_DESTROY: - PostQuitMessage(0); - break; - - default: - if(message==ControlAPIAttach) { - // Skype responds with Attach to the discover-message - AttachStatus=lParam; - if (AttachStatus==SKYPECONTROLAPI_ATTACH_SUCCESS) - hSkypeWnd=(HWND)wParam; // Skype gave us the communication window handle - if (AttachStatus!=SKYPECONTROLAPI_ATTACH_API_AVAILABLE) - SetEvent(SkypeReady); - break; - } - return (DefWindowProc(hWnd, message, wParam, lParam)); - } -// LOG("WM_COPYDATA", "exit"); - if (szSkypeMsg) free(szSkypeMsg); - return 1; -} - - -void TellError(DWORD err) { - LPVOID lpMsgBuf; - - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); - MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION ); - LocalFree( lpMsgBuf ); - return; -} - -int main(int argc, char *argv[]) { - DWORD Buffsize; - HKEY MyKey; - BOOL SkypeInstalled=TRUE; - MSG Message; - WNDCLASS WndClass; - SOCKADDR_IN service; - WSADATA wsaData; - int ExitCode=STILL_ACTIVE; - unsigned short BindPort=1401; - char BindIP[16]="0.0.0.0"; - - printf("Skypeproxy V1.0, by leecher 2005 \n\n"); - - if (argc>1) { - int i; - - if (!stricmp(argv[1], "-h") || !stricmp(argv[1], "--help") || !stricmp(argv[1], "/?")) { - printf("Usage: %s [-i BindIP] [-p BindPort]", argv[0]); -#ifdef USE_AUTHENTICATION - printf(" [-k Password]"); -#endif - printf("\n\n"); - return EXIT_SUCCESS; - } - for (i=0;ii+1) - strncpy(BindIP, argv[i+1], sizeof(BindIP)); - if (!stricmp(argv[i], "-p") && argc>i+1) - if (!(BindPort=atoi(argv[i+1]))) { - OUTPUT("ERROR: Cannot convert port to int. bye.."); - return EXIT_FAILURE; - } -#ifdef USE_AUTHENTICATION - if (!stricmp(argv[i], "-k") && argc>i+1) - password=strdup(argv[i+1]); -#endif - } - } - - if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Skype\\Phone", 0, KEY_READ, &MyKey)!=ERROR_SUCCESS || - RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Skype\\Phone", 0, KEY_READ, &MyKey)!=ERROR_SUCCESS) - SkypeInstalled=FALSE; - Buffsize=sizeof(skype_path); - if (SkypeInstalled==FALSE || - RegQueryValueEx(MyKey, "SkypePath", NULL, NULL, skype_path, &Buffsize)!=ERROR_SUCCESS) { - OUTPUT("Skype was not found on this machine :("); - RegCloseKey(MyKey); - skype_path[0]=0; - return EXIT_FAILURE; - } - RegCloseKey(MyKey); - - if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { - OUTPUT("Error at loading windows sockets."); - return EXIT_FAILURE; - } - - if ((ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { - printf("* Error at creating socket(): Error %d", WSAGetLastError()); - return EXIT_FAILURE; - } - - service.sin_family = AF_INET; - service.sin_addr.s_addr = inet_addr(BindIP); - service.sin_port = htons(BindPort); - - printf("* Binding to interface %s, Port %d..", BindIP, BindPort); - if (bind( ListenSocket, (SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR || - listen( ListenSocket, 1 ) == SOCKET_ERROR) - { - OUTPUT("Failed."); - closesocket(ListenSocket); - return EXIT_FAILURE; - } - printf("OK\n"); - - - if (!(ControlAPIAttach=RegisterWindowMessage("SkypeControlAPIAttach")) || - !(ControlAPIDiscover=RegisterWindowMessage("SkypeControlAPIDiscover"))) { - OUTPUT("Cannot register Windows message."); - closesocket(ListenSocket); - return EXIT_FAILURE; - } - - // Create window class - hSkypeWnd=NULL; - WndClass.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS; - WndClass.lpfnWndProc = (WNDPROC)WndProc; - WndClass.cbClsExtra = 0; - WndClass.cbWndExtra = 0; - WndClass.hInstance = NULL; - WndClass.hIcon = NULL; - WndClass.hCursor = NULL; - WndClass.hbrBackground = NULL; - WndClass.lpszMenuName = NULL; - WndClass.lpszClassName = "SkypeApiDispatchWindow"; - RegisterClass(&WndClass); - // Do not check the retval of RegisterClass, because on non-unicode - // win98 it will fail, as it is a stub that returns false() there - - // Create main window - hWnd=CreateWindowEx( WS_EX_APPWINDOW|WS_EX_WINDOWEDGE, - "SkypeApiDispatchWindow", "", WS_BORDER|WS_SYSMENU|WS_MINIMIZEBOX, - CW_USEDEFAULT, CW_USEDEFAULT, 128, 128, NULL, 0, (HINSTANCE)WndClass.hInstance, 0); - - if (!hWnd) { - OUTPUT("Cannot create window."); - TellError(GetLastError()); - closesocket(ListenSocket); - CloseHandle(WndClass.hInstance); - return EXIT_FAILURE; - } - ShowWindow(hWnd, 0); - UpdateWindow(hWnd); - - if (!(SkypeReady=CreateEvent(NULL, TRUE, FALSE, NULL)) || - !(ServerThreadBye=CreateEvent(NULL, TRUE, FALSE, NULL))) { - OUTPUT("Unable to create Mutex!"); - closesocket(ListenSocket); - CloseHandle(WndClass.hInstance); - return EXIT_FAILURE; - } - - if (_beginthread(ConnectToSkypeAPI, 0, (void *)FALSE)==-1 || - _beginthread(ServerThread, 0, NULL)==-1) { - OUTPUT("Cannot create thread. Bye.."); - closesocket(ListenSocket); - CloseHandle(WndClass.hInstance); - CloseHandle(SkypeReady); - return EXIT_FAILURE; - } - - signal(SIGINT, &bail_out); - LOG(("Startup: Messagepump started.\nPress CTRL+C to terminate\n")); - - while (GetMessage(&Message, hWnd, 0, 0)) - { - TranslateMessage(&Message); - DispatchMessage(&Message); - } - - LOG(("Shutdown: Messagepump stopped")); - - if (password) free(password); - if (AcceptSocket != INVALID_SOCKET) closesocket(AcceptSocket); - closesocket(ListenSocket); - LOG(("Shutdown: Waiting for serverthread to quit...")); - if (WaitForSingleObject(ServerThreadBye, 3000)==WAIT_TIMEOUT) - {OUTPUT("Serverthread didn't terminate correctly, shutting down anyway...");} - else - {LOG(("ServerThread terminated"));} - CloseHandle(WndClass.hInstance); - CloseHandle(SkypeReady); - return exitcode; -} \ No newline at end of file diff --git a/!NotAdopted/Skype/skypeproxy/skypeproxy.h b/!NotAdopted/Skype/skypeproxy/skypeproxy.h deleted file mode 100644 index 8ce122990b..0000000000 --- a/!NotAdopted/Skype/skypeproxy/skypeproxy.h +++ /dev/null @@ -1,36 +0,0 @@ -/*** Skype API ***/ -//Messages -#define SKYPECONTROLAPI_ATTACH_SUCCESS 0 -#define SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION 1 -#define SKYPECONTROLAPI_ATTACH_REFUSED 2 -#define SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE 3 -#define SKYPECONTROLAPI_ATTACH_API_AVAILABLE 0x8001 - -// Errors -#define MISC_ERROR 1 -#define USER_NOT_FOUND 2 -#define USER_NOT_ONLINE 3 -#define USER_BLOCKED 4 -#define TYPE_UNSUPPORTED 5 -#define SENDER_NOT_FRIEND 6 -#define SENDER_NOT_AUTHORIZED 7 - - -/*** Debugging macros ***/ -#define OUTPUT(a) printf("* %s\n", a); -#define LOG(a, b) printf("- %s: %s\n", a, b); -#define LOGL(a, b) printf("- %s: %d\n", a, b); - -/*** Program settings ***/ -#define PING_INTERVAL 10000 // Ping every 10000 msec to see if Skype is still available -#define USE_AUTHENTICATION 0x01 // Program supports authentication -> Comment to disable! - -/*** Commands ***/ -#define AUTHENTICATE 0x01 -#define CAPABILITIES 0x02 - -/*** Sockets ***/ -#pragma comment(lib, "ws2_32") - -/*** Prototypes ***/ -void WatchDogTimer(char *); \ No newline at end of file diff --git a/!NotAdopted/Skype/skypesvc.c b/!NotAdopted/Skype/skypesvc.c deleted file mode 100644 index c6d02e6d3a..0000000000 --- a/!NotAdopted/Skype/skypesvc.c +++ /dev/null @@ -1,188 +0,0 @@ -#define __SKYPESVC_C__ -#include "skype.h" -#include "skypesvc.h" -#include "skypeapi.h" -#include "skypeopt.h" -#include "contacts.h" -#include "m_toptoolbar.h" - -// Exports -SKYPE_SVCNAMES g_svcNames; - -//From skype.c -extern char protocol, g_szProtoName[]; -extern HINSTANCE hInst; -extern DWORD mirandaVersion; -static HANDLE m_hPrebuildCMenu=NULL, m_hStatusHookContact=NULL, m_hContactDeleted=NULL, - m_hHookModulesLoaded=NULL, m_hHookOkToExit=NULL, m_hOptHook=NULL, m_hHookMirandaExit=NULL, - m_hTTBModuleLoadedHook = NULL, m_hHookOnUserInfoInit = NULL; - -void CreateProtoService(const char* szService, MIRANDASERVICE svc) -{ - char str[MAXMODULELABELLENGTH]; - _snprintf(str, sizeof(str), "%s%s", SKYPE_PROTONAME, szService); - CreateServiceFunction(str, svc); -} - -#define CreateServiceName(srvce) _snprintf (g_svcNames.##srvce, sizeof(g_svcNames.##srvce), "%s/"#srvce, SKYPE_PROTONAME); - -void CreateServices(void) -{ - CreateServiceName(ChatNew); - CreateServiceName(SetAvatar); - CreateServiceName(SendFile); - CreateServiceName(HoldCall); - CreateServiceName(AnswerCall); - CreateServiceName(ImportHistory); - CreateServiceName(AddUser); - CreateServiceName(SkypeOutCallUser); - CreateServiceName(CallHangupUser); - CreateServiceName(CallUser); - - CreateServiceFunction(SKYPE_CALL, SkypeCall); - CreateServiceFunction(SKYPE_CALLHANGUP, SkypeCallHangup); - CreateServiceFunction(SKYPEOUT_CALL, SkypeOutCall); - CreateServiceFunction(SKYPE_HOLDCALL, SkypeHoldCall); - CreateServiceFunction(SKYPE_ADDUSER, SkypeAdduserDlg); - CreateServiceFunction(SKYPE_IMPORTHISTORY, ImportHistory); - CreateServiceFunction(SKYPE_ANSWERCALL, SkypeAnswerCall); - CreateServiceFunction(SKYPE_SENDFILE, SkypeSendFile); - CreateServiceFunction(SKYPE_SETAVATAR, SkypeSetAvatar); - - CreateProtoService(PS_GETCAPS, SkypeGetCaps); - CreateProtoService(PS_GETNAME, SkypeGetName); - CreateProtoService(PS_LOADICON, SkypeLoadIcon); - CreateProtoService(PS_SETSTATUS, SkypeSetStatus); - CreateProtoService(PS_GETSTATUS, SkypeGetStatus); - CreateProtoService(PS_ADDTOLIST, SkypeAddToList); - CreateProtoService(PS_ADDTOLISTBYEVENT, SkypeAddToListByEvent); - CreateProtoService(PS_BASICSEARCH, SkypeBasicSearch); - - CreateProtoService(PSS_GETINFO, SkypeGetInfo); - CreateProtoService(PSS_MESSAGE, SkypeSendMessage); - CreateProtoService(PSR_MESSAGE, SkypeRecvMessage); - CreateProtoService(PSS_USERISTYPING, SkypeUserIsTyping); - CreateProtoService(PSS_AUTHREQUEST, SkypeSendAuthRequest); - CreateProtoService(PSR_AUTH, SkypeRecvAuth); - CreateProtoService(PS_AUTHALLOW, SkypeAuthAllow); - CreateProtoService(PS_AUTHDENY, SkypeAuthDeny); - - CreateProtoService(PS_GETAVATARINFO, SkypeGetAvatarInfo); - CreateProtoService(PS_GETAVATARCAPS, SkypeGetAvatarCaps); - CreateProtoService(PS_GETMYAVATAR, SkypeGetAvatar); - CreateProtoService(PS_SETMYAVATAR, SkypeSetAvatar); - - CreateProtoService(PS_SETAWAYMSG, SkypeSetAwayMessage); - CreateProtoService(PS_SETAWAYMSGW, SkypeSetAwayMessageW); - CreateProtoService(PSS_GETAWAYMSG, SkypeGetAwayMessage); - CreateProtoService(PS_SETMYNICKNAME, SkypeSetNick); - - CreateProtoService(PSS_SKYPEAPIMSG, SkypeReceivedAPIMessage); - CreateProtoService(SKYPE_REGPROXY, SkypeRegisterProxy); -} - -void HookEvents(void) -{ - m_hPrebuildCMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PrebuildContactMenu); - - //HookEvent(ME_CLIST_DOUBLECLICKED, ClistDblClick); - m_hOptHook = HookEvent(ME_OPT_INITIALISE, RegisterOptions); - m_hStatusHookContact = HookEvent(ME_DB_CONTACT_ADDED,HookContactAdded); - m_hContactDeleted = HookEvent( ME_DB_CONTACT_DELETED, HookContactDeleted ); - m_hHookModulesLoaded = HookEvent( ME_SYSTEM_MODULESLOADED, OnModulesLoaded); - m_hHookMirandaExit = HookEvent(ME_SYSTEM_OKTOEXIT, MirandaExit); - m_hHookOkToExit = HookEvent(ME_SYSTEM_PRESHUTDOWN, OkToExit); -} - -void HookEventsLoaded(void) -{ - // We cannot check for the TTB-service before this event gets fired... :-/ - m_hTTBModuleLoadedHook = HookEvent(ME_TTB_MODULELOADED, CreateTopToolbarButton); - m_hHookOnUserInfoInit = HookEvent( ME_USERINFO_INITIALISE, OnDetailsInit ); -} - -void UnhookEvents(void) -{ - UnhookEvent(m_hOptHook); - UnhookEvent(m_hTTBModuleLoadedHook); - UnhookEvent(m_hHookOnUserInfoInit); - UnhookEvent(m_hStatusHookContact); - UnhookEvent(m_hContactDeleted); - UnhookEvent(m_hHookModulesLoaded); - UnhookEvent(m_hPrebuildCMenu); - UnhookEvent(m_hHookOkToExit); - UnhookEvent(m_hHookMirandaExit); - //UnhookEvent(ClistDblClick); -} - -INT_PTR SkypeGetCaps(WPARAM wParam, LPARAM lParam) { - int ret = 0; - - UNREFERENCED_PARAMETER(lParam); - - switch (wParam) { - case PFLAGNUM_1: - ret = PF1_BASICSEARCH | PF1_IM | PF1_MODEMSG; // | PF1_AUTHREQ; - if (protocol>=5) ret |= PF1_ADDSEARCHRES; - break; - - case PFLAGNUM_2: - ret = PF2_ONLINE | PF2_SHORTAWAY | PF2_INVISIBLE | PF2_HEAVYDND; -#ifdef MAPDND - ret |= PF2_LIGHTDND | PF2_HEAVYDND; -#endif - if (!DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "NoSkype3Stats", 0)) - ret |= PF2_LONGAWAY | PF2_FREECHAT; - break; - - case PFLAGNUM_3: - ret = PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE | PF2_IDLE; - break; - - case PFLAGNUM_4: - ret = PF4_FORCEAUTH | PF4_FORCEADDED | PF4_AVATARS | PF4_SUPPORTTYPING /* Not really, but libgaim compat. */; - if (mirandaVersion >= 0x070000) ret |= PF4_IMSENDUTF; - break; - case PFLAG_UNIQUEIDTEXT: - ret = (INT_PTR) "NAME"; - break; - case PFLAG_UNIQUEIDSETTING: - ret = (INT_PTR) SKYPE_NAME; - break; - } - return ret; - -} - -INT_PTR SkypeGetName(WPARAM wParam, LPARAM lParam) -{ - if (lParam) - { - strncpy((char *)lParam, SKYPE_PROTONAME, wParam); - return 0; // Success - } - return 1; // Failure -} - - -INT_PTR SkypeLoadIcon(WPARAM wParam,LPARAM lParam) -{ - UINT id; - - UNREFERENCED_PARAMETER(lParam); - - switch(wParam&0xFFFF) { - case PLI_PROTOCOL: id=IDI_SKYPE; break; // IDI_MAIN is the main icon for the protocol - default: return (int)(HICON)NULL; - } - return (int)LoadImage(hInst,MAKEINTRESOURCE(id),IMAGE_ICON,GetSystemMetrics(wParam&PLIF_SMALL?SM_CXSMICON:SM_CXICON),GetSystemMetrics(wParam&PLIF_SMALL?SM_CYSMICON:SM_CYICON),0); -} - -INT_PTR SkypeGetAvatar(WPARAM wParam,LPARAM lParam) -{ DBVARIANT dbv; - if (!DBGetContactSettingString(NULL,SKYPE_PROTONAME, "AvatarFile", &dbv)){ - lstrcpynA((char*)wParam, dbv.pszVal, (int)lParam); - DBFreeVariant(&dbv); - } - return 0; -} diff --git a/!NotAdopted/Skype/skypesvc.h b/!NotAdopted/Skype/skypesvc.h deleted file mode 100644 index 74c8cd37bf..0000000000 --- a/!NotAdopted/Skype/skypesvc.h +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include -#include -#include -#include "resource.h" - -void CreateProtoService(const char* szService, MIRANDASERVICE svc); -void HookEvents(void); -void HookEventsLoaded(void); -void UnhookEvents(void); -void CreateServices(void); -INT_PTR SkypeLoadIcon(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeGetName(WPARAM wParam, LPARAM lParam); -INT_PTR SkypeGetCaps(WPARAM wParam, LPARAM lParam); -/* SkypeGetAvatar - * - * Purpose: Return the avatar file name - * Params : wParam=0 - * lParam=0 - * Returns: 0 - Success - * -1 - Failure - */ -INT_PTR SkypeGetAvatar(WPARAM wParam,LPARAM lParam); \ No newline at end of file diff --git a/!NotAdopted/Skype/utf8.c b/!NotAdopted/Skype/utf8.c deleted file mode 100644 index 8ae746e871..0000000000 --- a/!NotAdopted/Skype/utf8.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright (C) 2001 Peter Harris - * Copyright (C) 2001 Edmund Grimley Evans - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Convert a string between UTF-8 and the locale's charset. - */ - -#include -#include - -#include "utf8.h" - -#ifdef _WIN32 - - /* Thanks to Peter Harris for this win32 - * code. - */ - -#include -#include - -unsigned char *make_utf8_string(const wchar_t *unicode) -{ - int size = 0, index = 0, out_index = 0; - unsigned char *out; - unsigned short c; - - /* first calculate the size of the target string */ - c = unicode[index++]; - while(c) { - if(c < 0x0080) { - size += 1; - } else if(c < 0x0800) { - size += 2; - } else { - size += 3; - } - c = unicode[index++]; - } - - out = (unsigned char *) malloc(size + 1); - if (out == NULL) - return NULL; - index = 0; - - c = unicode[index++]; - while(c) - { - if(c < 0x080) { - out[out_index++] = (unsigned char)c; - } else if(c < 0x800) { - #pragma warning (suppress: 4244) // conversion from 'int' to 'unsigned char', possible loss of data - out[out_index++] = 0xc0 | (c >> 6); - out[out_index++] = 0x80 | (c & 0x3f); - } else { - out[out_index++] = 0xe0 | (c >> 12); - out[out_index++] = 0x80 | ((c >> 6) & 0x3f); - out[out_index++] = 0x80 | (c & 0x3f); - } - c = unicode[index++]; - } - out[out_index] = 0x00; - - return out; -} - -wchar_t *make_unicode_string(const unsigned char *utf8) -{ - int size = 0, index = 0, out_index = 0; - wchar_t *out; - unsigned char c; - - /* first calculate the size of the target string */ - c = utf8[index++]; - while(c) { - if((c & 0x80) == 0) { - index += 0; - } else if((c & 0xe0) == 0xe0) { - index += 2; - } else { - index += 1; - } - size += 1; - c = utf8[index++]; - } - - out = (wchar_t *) malloc((size + 1) * sizeof(wchar_t)); - if (out == NULL) - return NULL; - index = 0; - - c = utf8[index++]; - while(c) - { - if((c & 0x80) == 0) { - out[out_index++] = c; - } else if((c & 0xe0) == 0xe0) { - out[out_index] = (c & 0x1F) << 12; - c = utf8[index++]; - out[out_index] |= (c & 0x3F) << 6; - c = utf8[index++]; - out[out_index++] |= (c & 0x3F); - } else { - out[out_index] = (c & 0x3F) << 6; - c = utf8[index++]; - out[out_index++] |= (c & 0x3F); - } - c = utf8[index++]; - } - out[out_index] = 0; - - return out; -} - -int utf8_encode(const char *from, char **to) -{ - wchar_t *unicode; - int wchars, err; - - wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, strlen(from), NULL, 0); - - if(wchars == 0) - { -// fprintf(stderr, "Unicode translation error %d\n"), GetLastError(); - return -1; - } - - unicode = (wchar_t *) calloc(wchars + 1, sizeof(unsigned short)); - if(unicode == NULL) - { -// fprintf(stderr, "Out of memory processing string to UTF8\n"); - return -1; - } - - err = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, strlen(from), unicode, wchars); - if(err != wchars) - { - free(unicode); -// fprintf(stderr, "Unicode translation error %d\n"), GetLastError(); - return -1; - } - - /* On NT-based windows systems, we could use WideCharToMultiByte(), but - * MS doesn't actually have a consistent API across win32. - */ - *to = (char *) make_utf8_string(unicode); - - free(unicode); - return 0; -} - -int utf8_decode(const char *from, char **to) -{ - wchar_t *unicode; - int chars, err; -// LPCPINFO lpCPInfo; - - /* On NT-based windows systems, we could use MultiByteToWideChar(CP_UTF8), but - * MS doesn't actually have a consistent API across win32. - */ - unicode = make_unicode_string( (const unsigned char *)from); - if(unicode == NULL) - { - fprintf(stderr, "Out of memory processing string from UTF8 to UNICODE16\n"); - return -1; - } - - //if(GetCPInfo(CP_ACP,lpCPInfo)) - { - - chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, NULL, 0, NULL, NULL); - } - /*else - { - chars = WideCharToMultiByte(GetConsoleCP(), WC_COMPOSITECHECK, unicode, -1, NULL, 0, NULL, NULL); - }*/ - - if(chars == 0) - { - fprintf(stderr, "Unicode translation error %ld\n", GetLastError()); - free(unicode); - return -1; - } - - *to = (char *) calloc(chars + 1, sizeof(unsigned char)); - if(*to == NULL) - { - fprintf(stderr, "Out of memory processing string to local charset\n"); - free(unicode); - return -1; - } - - //err = WideCharToMultiByte(GetConsoleCP(), WC_COMPOSITECHECK, unicode, -1, *to, chars, NULL, NULL); - err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, *to, chars, NULL, NULL); - if(err != chars) - { - fprintf(stderr, "Unicode translation error %ld\n", GetLastError()); - free(unicode); - free(*to); - *to = NULL; - return -1; - } - - free(unicode); - return 0; -} - -#ifndef _UNICODE -char *make_tchar_string(const unsigned char *utf8) { - char *ret; - if (utf8_decode((const char*)utf8, &ret)==-1) return NULL; - return ret; -} -#endif - -#else /* End win32. Rest is for real operating systems */ - - -#ifdef HAVE_LANGINFO_CODESET -#include -#endif - -int iconvert(const char *fromcode, const char *tocode, - const char *from, size_t fromlen, - char **to, size_t *tolen); - -static char *current_charset = "BIG-5"; /* means "US-ASCII" */ - -void convert_set_charset(const char *charset) -{ - - if (!charset) - charset = getenv("CHARSET"); - -#ifdef HAVE_LANGINFO_CODESET - if (!charset) - charset = nl_langinfo(CODESET); -#endif - - free(current_charset); - current_charset = 0; - if (charset && *charset) - current_charset = _strdup(charset); -} - -static int convert_buffer(const char *fromcode, const char *tocode, - const char *from, size_t fromlen, - char **to, size_t *tolen) -{ - int ret = -1; - -#ifdef HAVE_ICONV - ret = iconvert(fromcode, tocode, from, fromlen, to, tolen); - if (ret != -1) - return ret; -#endif - -#ifndef HAVE_ICONV /* should be ifdef USE_CHARSET_CONVERT */ - ret = charset_convert(fromcode, tocode, from, fromlen, to, tolen); - if (ret != -1) - return ret; -#endif - - return ret; -} - -static int convert_string(const char *fromcode, const char *tocode, - const char *from, char **to, char replace) -{ - int ret; - size_t fromlen; - char *s; - - fromlen = lstrlen(from); - ret = convert_buffer(fromcode, tocode, from, fromlen, to, 0); - if (ret == -2) - return -1; - if (ret != -1) - return ret; - - s = malloc(fromlen + 1); - if (!s) - return -1; - lstrcpy(s, from); - *to = s; - for (; *s; s++) - if (*s & ~0x7f) - *s = replace; - return 3; -} - -int utf8_encode(const char *from, char **to) -{ - char *charset; - - if (!current_charset) - convert_set_charset(0); - charset = current_charset ? current_charset : "US-ASCII"; - return convert_string(charset, "UTF-8", from, to, '#'); -} - -int utf8_decode(const char *from, char **to) -{ - char *charset; - - if(*from == 0) { - *to = malloc(1); - **to = 0; - return 1; - } - - if (!current_charset) - convert_set_charset(0); - charset = current_charset ? current_charset : "US-ASCII"; - return convert_string("UTF-8", charset, from, to, '?'); -} - -#endif diff --git a/!NotAdopted/Skype/utf8.h b/!NotAdopted/Skype/utf8.h deleted file mode 100644 index 70c533deca..0000000000 --- a/!NotAdopted/Skype/utf8.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Convert a string between UTF-8 and the locale's charset. - * Invalid bytes are replaced by '#', and characters that are - * not available in the target encoding are replaced by '?'. - * - * If the locale's charset is not set explicitly then it is - * obtained using nl_langinfo(CODESET), where available, the - * environment variable CHARSET, or assumed to be US-ASCII. - * - * Return value of conversion functions: - * - * -1 : memory allocation failed - * 0 : data was converted exactly - * 1 : valid data was converted approximately (using '?') - * 2 : input was invalid (but still converted, using '#') - * 3 : unknown encoding (but still converted, using '?') - */ - -#ifndef __UTF8_H -#define __UTF8_H - -#ifdef __cplusplus -extern "C" { -#endif - -void convert_set_charset(const char *charset); - -int utf8_encode(const char *from, char **to); -int utf8_decode(const char *from, char **to); -wchar_t *make_unicode_string(const unsigned char *utf8); -unsigned char *make_utf8_string(const wchar_t *unicode); -#ifdef _UNICODE -#define make_tchar_string make_unicode_string -// Helpers for strings that only can contain 7bit chars to not make unneccessary memory allocation -#define make_nonutf_tchar_string(x) make_tchar_string(x) -#define free_nonutf_tchar_string(x) if(x) free(x); -#else -char *make_tchar_string(const unsigned char *utf8); -#define make_nonutf_tchar_string(x) (char*)x -#define free_nonutf_tchar_string(x) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __UTF8_H */ diff --git a/!NotAdopted/Skype/util.c b/!NotAdopted/Skype/util.c deleted file mode 100644 index ce5ad9c756..0000000000 --- a/!NotAdopted/Skype/util.c +++ /dev/null @@ -1,57 +0,0 @@ -#include - -char * __cdecl strtok_r ( - char * string, - const char * control, - char **nextoken - ) -{ - unsigned char *str; - const unsigned char *ctrl = (const unsigned char*)control; - - unsigned char map[32]; - int count; - - /* Clear control map */ - for (count = 0; count < 32; count++) - map[count] = 0; - - /* Set bits in delimiter table */ - do { - map[*ctrl >> 3] |= (1 << (*ctrl & 7)); - } while (*ctrl++); - - /* Initialize str. If string is NULL, set str to the saved - * pointer (i.e., continue breaking tokens out of the string - * from the last strtok call) */ - if (string) - str = (unsigned char*)string; - else - str = (unsigned char*)(*nextoken); - - /* Find beginning of token (skip over leading delimiters). Note that - * there is no token iff this loop sets str to point to the terminal - * null (*str == '\0') */ - while ( (map[*str >> 3] & (1 << (*str & 7))) && *str ) - str++; - - string = (char*)str; - - /* Find the end of the token. If it is not the end of the string, - * put a null there. */ - for ( ; *str ; str++ ) - if ( map[*str >> 3] & (1 << (*str & 7)) ) { - *str++ = '\0'; - break; - } - - /* Update nextoken (or the corresponding field in the per-thread data - * structure */ - *nextoken = (char*)str; - - /* Determine if a token has been found. */ - if ( string == (char*)str ) - return NULL; - else - return string; -} diff --git a/!NotAdopted/Skype/util.h b/!NotAdopted/Skype/util.h deleted file mode 100644 index 181f5d1878..0000000000 --- a/!NotAdopted/Skype/util.h +++ /dev/null @@ -1,7 +0,0 @@ -char * __cdecl strtok_r ( - char * string, - const char * control, - char **nextoken - ); - -void TranslateMirandaRelativePathToAbsolute(LPCSTR cszPath, LPSTR szAbsolutePath, BOOL fQuoteSpaces); diff --git a/!NotAdopted/Skype/voiceservice.c b/!NotAdopted/Skype/voiceservice.c deleted file mode 100644 index b13ac097c1..0000000000 --- a/!NotAdopted/Skype/voiceservice.c +++ /dev/null @@ -1,156 +0,0 @@ -#include "skype.h" -#include "skypeapi.h" -#include "skypesvc.h" -#include "voiceservice.h" -#include "sdk/m_voiceservice.h" - -#pragma warning (push) -#pragma warning (disable: 4100) // unreferenced formal parameter -#include "../../include/m_utils.h" -#pragma warning (pop) - -HANDLE hVoiceNotify = NULL; -BOOL has_voice_service = FALSE; - -extern char g_szProtoName[]; - - -BOOL HasVoiceService() -{ - return has_voice_service; -} - -void NofifyVoiceService(HANDLE hContact, char *callId, int state) -{ - VOICE_CALL vc = {0}; - vc.cbSize = sizeof(vc); - vc.szModule = SKYPE_PROTONAME; - vc.id = callId; - vc.flags = VOICE_CALL_CONTACT; - vc.state = state; - vc.hContact = hContact; - NotifyEventHooks(hVoiceNotify, (WPARAM) &vc, 0); -} - -static INT_PTR VoiceGetInfo(WPARAM wParam, LPARAM lParam) -{ - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - - return VOICE_SUPPORTED | VOICE_CALL_CONTACT | VOICE_CAN_HOLD; -} - -static HANDLE FindContactByCallId(char *callId) -{ - HANDLE hContact; - int iCmpRes; - for (hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - hContact != NULL; - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) - { - char *szProto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - - DBVARIANT dbv; - if (szProto != NULL - && !strcmp(szProto, SKYPE_PROTONAME) - && DBGetContactSettingByte(hContact, SKYPE_PROTONAME, "ChatRoom", 0) == 0 - && !DBGetContactSettingString(hContact, SKYPE_PROTONAME, "CallId", &dbv)) - { - iCmpRes = strcmp(callId, dbv.pszVal); - DBFreeVariant(&dbv); - if (iCmpRes == 0) return hContact; - } - } - - return NULL; -} - -static INT_PTR VoiceCall(WPARAM wParam, LPARAM lParam) -{ - DBVARIANT dbv; - - UNREFERENCED_PARAMETER(lParam); - - if (!wParam) return -1; - - if (DBGetContactSettingString((HANDLE)wParam, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) - return -1; - - SkypeSend("CALL %s", dbv.pszVal); - DBFreeVariant (&dbv); - - return 0; -} - -static INT_PTR VoiceAnswer(WPARAM wParam, LPARAM lParam) -{ - char *callId = (char *) wParam; - - UNREFERENCED_PARAMETER(lParam); - - if (!wParam) return -1; - - if (FindContactByCallId(callId) == NULL) - return -1; - - SkypeSend("SET %s STATUS INPROGRESS", callId); - testfor("ERROR", 200); - - return 0; -} - -static INT_PTR VoiceDrop(WPARAM wParam, LPARAM lParam) -{ - char *callId = (char *) wParam; - - UNREFERENCED_PARAMETER(lParam); - - if (!wParam) return -1; - - if (FindContactByCallId(callId) == NULL) - return -1; - - SkypeSend("SET %s STATUS FINISHED", callId); - - return 0; -} - -static INT_PTR VoiceHold(WPARAM wParam, LPARAM lParam) -{ - char *callId = (char *) wParam; - - UNREFERENCED_PARAMETER(lParam); - - if (!wParam) return -1; - - if (FindContactByCallId(callId) == NULL) - return -1; - - SkypeSend("SET %s STATUS ONHOLD", callId); - - return 0; -} - -void VoiceServiceInit() -{ - // leecher, 26.03.2011: Did this ever work in the old versions?? - char szEvent[MAXMODULELABELLENGTH]; - - _snprintf (szEvent, sizeof(szEvent), "%s%s", SKYPE_PROTONAME, PE_VOICE_CALL_STATE); - hVoiceNotify = CreateHookableEvent( szEvent ); - CreateProtoService( PS_VOICE_GETINFO, VoiceGetInfo ); - CreateProtoService( PS_VOICE_CALL, VoiceCall ); - CreateProtoService( PS_VOICE_ANSWERCALL, VoiceAnswer ); - CreateProtoService( PS_VOICE_DROPCALL, VoiceDrop ); - CreateProtoService( PS_VOICE_HOLDCALL, VoiceHold ); -} - -void VoiceServiceExit() -{ - DestroyHookableEvent(hVoiceNotify); -} - -void VoiceServiceModulesLoaded() -{ - has_voice_service = ServiceExists(MS_VOICESERVICE_REGISTER); -} \ No newline at end of file diff --git a/!NotAdopted/Skype/voiceservice.h b/!NotAdopted/Skype/voiceservice.h deleted file mode 100644 index bbb333ec4b..0000000000 --- a/!NotAdopted/Skype/voiceservice.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _VOICESERVICE_H_ -#define _VOICESERVICE_H_ - -#pragma warning (push) -#pragma warning (disable: 4201) // nonstandard extension used : nameless struct/union -#include "sdk/m_voice.h" -#pragma warning (pop) - -BOOL HasVoiceService(); -void VoiceServiceInit(); -void VoiceServiceExit(); -void VoiceServiceModulesLoaded(); -void NofifyVoiceService(HANDLE hContact, char *callId, int state) ; - - - -#endif // _VOICESERVICE_H_ - diff --git a/!NotAdopted/SmartAutoAway/AggressiveOptimize.h b/!NotAdopted/SmartAutoAway/AggressiveOptimize.h deleted file mode 100644 index 51e5f5de04..0000000000 --- a/!NotAdopted/SmartAutoAway/AggressiveOptimize.h +++ /dev/null @@ -1,166 +0,0 @@ - -////////////////////////////// -// Version 1.40 -// October 22nd, 2002 - .NET (VC7, _MSC_VER=1300) support! -// Version 1.30 -// Nov 24th, 2000 -// Version 1.20 -// Jun 9th, 2000 -// Version 1.10 -// Jan 23rd, 2000 -// Version 1.00 -// May 20th, 1999 -// Todd C. Wilson, Fresh Ground Software -// (todd@nopcode.com) -// This header file will kick in settings for Visual C++ 5 and 6 that will (usually) -// result in smaller exe's. -// The "trick" is to tell the compiler to not pad out the function calls; this is done -// by not using the /O1 or /O2 option - if you do, you implicitly use /Gy, which pads -// out each and every function call. In one single 500k dll, I managed to cut out 120k -// by this alone! -// The other two "tricks" are telling the Linker to merge all data-type segments together -// in the exe file. The relocation, read-only (constants) data, and code section (.text) -// sections can almost always be merged. Each section merged can save 4k in exe space, -// since each section is padded out to 4k chunks. This is very noticeable with smaller -// exes, since you could have only 700 bytes of data, 300 bytes of code, 94 bytes of -// strings - padded out, this could be 12k of runtime, for 1094 bytes of stuff! For larger -// programs, this is less overall, but can save at least 4k. -// Note that if you're using MFC static or some other 3rd party libs, you may get poor -// results with merging the readonly (.rdata) section - the exe may grow larger. -// To use this feature, define _MERGE_DATA_ in your project or before this header is used. -// With Visual C++ 5, the program uses a file alignment of 512 bytes, which results -// in a small exe. Under VC6, the program instead uses 4k, which is the same as the -// section size. The reason (from what I understand) is that 4k is the chunk size of -// the virtual memory manager, and that WinAlign (an end-user tuning tool for Win98) -// will re-align the programs on this boundary. The problem with this is that all of -// Microsoft's system exes and dlls are *NOT* tuned like this, and using 4k causes serious -// exe bloat. This is very noticeable for smaller programs. -// The "trick" for this is to use the undocumented FILEALIGN linker parm to change the -// padding from 4k to 1/2k, which results in a much smaller exe - anywhere from 20%-75% -// depending on the size. Note that this is the same as using /OPT:NOWIN98, which *is* -// a previously documented switch, but was left out of the docs for some reason in VC6 and -// all of the current MSDN's - see KB:Q235956 for more information. -// Microsoft does say that using the 4k alignment will "speed up process loading", -// but I've been unable to notice a difference, even on my P180, with a very large (4meg) exe. -// Please note, however, that this will probably not change the size of the COMPRESSED -// file (either in a .zip file or in an install archive), since this 4k is all zeroes and -// gets compressed away. -// Also, the /ALIGN:4096 switch will "magically" do the same thing, even though this is the -// default setting for this switch. Apparently this sets the same values as the above two -// switches do. We do not use this in this header, since it smacks of a bug and not a feature. -// Thanks to Michael Geary for some additional tips! -// -// Notes about using this header in .NET -// First off, VC7 does not allow a lot of the linker command options in pragma's. There is no -// honest or good reason why Microsoft decided to make this change, it just doesn't. -// So that is why there are a lot of <1300 #if's in the header. -// If you want to take full advantage of the VC7 linker options, you will need to do it on a -// PER PROJECT BASIS; you can no longer use a global header file like this to make it better. -// Items I strongly suggest putting in all your VC7 project linker options command line settings: -// /ignore:4078 /RELEASE -// Compiler options: -// /GL (Whole Program Optimization) -// If you're making an .EXE and not a .DLL, consider adding in: -// /GA (Optimize for Windows Application) -// Some items to consider using in your VC7 projects (not VC6): -// Link-time Code Generation - whole code optimization. Put this in your exe/dll project link settings. -// /LTCG:NOSTATUS -// The classic no-padding and no-bloat compiler C/C++ switch: -// /opt:nowin98 -// -// (C++ command line options: /GL /opt:nowin98 and /GA for .exe files) -// (Link command line options: /ignore:4078 /RELEASE /LTCG:NOSTATUS) -// -// Now, notes on using these options in VC7 vs VC6. -// VC6 consistently, for me, produces smaller code from C++ the exact same sources, -// with or without this header. On average, VC6 produces 5% smaller binaries compared -// to VC7 compiling the exact same project, *without* this header. With this header, VC6 -// will make a 13k file, while VC7 will make a 64k one. VC7 is just bloaty, pure and -// simple - all that managed/unmanaged C++ runtimes, and the CLR stuff must be getting -// in the way of code generation. However, template support is better, so there. -// Both VC6 and VC7 show the same end kind of end result savings - larger binary output -// will shave about 2% off, where as smaller projects (support DLL's, cpl's, -// activex controls, ATL libs, etc) get the best result, since the padding is usually -// more than the actual usable code. But again, VC7 does not compile down as small as VC6. -// -// The argument can be made that doing this is a waste of time, since the "zero bytes" -// will be compressed out in a zip file or install archive. Not really - it doesn't matter -// if the data is a string of zeroes or ones or 85858585 - it will still take room (20 bytes -// in a zip file, 29 bytes if only *4* of them 4k bytes are not the same) and time to -// compress that data and decompress it. Also, 20k of zeros is NOT 20k on disk - it's the -// size of the cluster slop- for Fat32 systems, 20k can be 32k, NTFS could make it 24k if you're -// just 1 byte over (round up). Most end users do not have the dual P4 Xeon systems with -// two gigs of RDram and a Raid 0+1 of Western Digital 120meg Special Editions that all -// worthy developers have (all six of us), so they will need any space and LOADING TIME -// savings they will need; taking an extra 32k or more out of your end user's 64megs of -// ram on Windows 98 is Not a Good Thing. -// -// Now, as a ADDED BONUS at NO EXTRA COST TO YOU! Under VC6, using the /merge:.text=.data -// pragma will cause the output file to be un-disassembleable! (is that a word?) At least, -// with the normal tools - WinDisam, DumpBin, and the like will not work. Try it - use the -// header, compile release, and then use DUMPBIN /DISASM filename.exe - no code! -// Thanks to Gлzim Pani for discovering this gem - for a full writeup on -// this issue and the ramifactions of it, visit www.nopcode.com for the Aggressive Optimize -// article. - -#ifndef _AGGRESSIVEOPTIMIZE_H_ -#define _AGGRESSIVEOPTIMIZE_H_ - -#pragma warning(disable:4711) - -#ifdef NDEBUG -// /Og (global optimizations), /Os (favor small code), /Oy (no frame pointers) -#pragma optimize("gsy",on) - -#if (_MSC_VER<1300) - #pragma comment(linker,"/RELEASE") -#endif - -// Note that merging the .rdata section will result in LARGER exe's if you using -// MFC (esp. static link). If this is desirable, define _MERGE_RDATA_ in your project. -#ifdef _MERGE_RDATA_ -#pragma comment(linker,"/merge:.rdata=.data") -#endif // _MERGE_RDATA_ - -#pragma comment(linker,"/merge:.text=.data") -#if (_MSC_VER<1300) - // In VC7, this causes problems with the relocation and data tables, so best to not merge them - #pragma comment(linker,"/merge:.reloc=.data") -#endif - -// Merging sections with different attributes causes a linker warning, so -// turn off the warning. From Michael Geary. Undocumented, as usual! -#if (_MSC_VER<1300) - // In VC7, you will need to put this in your project settings - #pragma comment(linker,"/ignore:4078") -#endif - -// With Visual C++ 5, you already get the 512-byte alignment, so you will only need -// it for VC6, and maybe later. -#if _MSC_VER >= 1000 - -// Option #1: use /filealign -// Totally undocumented! And if you set it lower than 512 bytes, the program crashes. -// Either leave at 0x200 or 0x1000 -//#pragma comment(linker,"/FILEALIGN:0x200") - -// Option #2: use /opt:nowin98 -// See KB:Q235956 or the READMEVC.htm in your VC directory for info on this one. -// This is our currently preferred option, since it is fully documented and unlikely -// to break in service packs and updates. -#if (_MSC_VER<1300) - // In VC7, you will need to put this in your project settings - #pragma comment(linker,"/opt:nowin98") -#else - -// Option #3: use /align:4096 -// A side effect of using the default align value is that it turns on the above switch. -// Does nothing under Vc7 that /opt:nowin98 doesn't already give you -// #pragma comment(linker,"/ALIGN:512") -#endif - -#endif // _MSC_VER >= 1000 - -#endif // NDEBUG - -#endif // _AGGRESSIVEOPTIMIZE_H_ diff --git a/!NotAdopted/SmartAutoAway/aa_utils.cpp b/!NotAdopted/SmartAutoAway/aa_utils.cpp deleted file mode 100644 index c759cff91c..0000000000 --- a/!NotAdopted/SmartAutoAway/aa_utils.cpp +++ /dev/null @@ -1,396 +0,0 @@ -#include "globals.h" - - -//Proto_Status2Flag - - int OldIndexToStatus(int oldIndex){ - switch (oldIndex){ - case 0 : return ID_STATUS_AWAY; - case 1 : return ID_STATUS_DND; - case 2 : return ID_STATUS_NA; - case 3 : return ID_STATUS_OCCUPIED; - case 4 : return ID_STATUS_INVISIBLE; - case 5 : return ID_STATUS_ONTHEPHONE; - case 6 : return ID_STATUS_OUTTOLUNCH; - case 7 : return ID_STATUS_ONLINE; - case 8 : return ID_STATUS_FREECHAT; - case 9 : return ID_STATUS_OFFLINE; - } - return 0; -} - int StatusToOldIndex(int status){ - switch (status){ - case ID_STATUS_AWAY : return 0; - case ID_STATUS_DND : return 1; - case ID_STATUS_NA : return 2; - case ID_STATUS_OCCUPIED : return 3; - case ID_STATUS_INVISIBLE : return 4; - case ID_STATUS_ONTHEPHONE : return 5; - case ID_STATUS_OUTTOLUNCH : return 6; - case ID_STATUS_ONLINE : return 7; - case ID_STATUS_FREECHAT : return 8; - case ID_STATUS_OFFLINE : return 9; - } - return 0; -} - - unsigned long SetBits (unsigned long target,unsigned long mask,unsigned long value) -{ - int shift = 0; - unsigned long t; - while (!((mask>>shift)&1)) { - shift++; - } - t = mask ^ 0xFFFFFFFF; - target = target & t; - value = value<>shift)&1)) { - shift++; - } - t = source & mask; - return t >> shift; -} - -BOOL isInterestingProto(int j){ - if ( proto[j]->type != PROTOTYPE_PROTOCOL ) return 0; - if (protoModes[j] > 1) return 1; - else return 0; - } - - BOOL IsStatusBitSet(int status, int bits){ - int i=0; - int mask=1; - for (i = numStatuses-1; i>=0; i--){ - if (aa_Status[i]==status) return (mask & bits); - mask <<= 1; - } - return 0; -} - - int StatusByProtoIndex(int modes, int index){ - int i=0; - int indexcount=0; - int mask = (1<<(numStatuses-1)); - for (i = 0; i < numStatuses ; i++){ - BOOL isset = (modes & mask); - if (isset) { - indexcount++; - if (indexcount==index) return aa_Status[i]; - } - mask >>= 1; - } - return 0; -} - - int StatusToProtoIndex(int status, int modes){ - int i=0; - int indexcount=0; - int mask = (1<<(numStatuses-1)); - for (i = 0; i < numStatuses ; i++){ - BOOL isset = (modes & mask); - if (isset) { - indexcount++; - if (status==aa_Status[i]) return indexcount; - } - mask >>= 1; - } - return 0; - -} - BOOL StrikeOut(HWND hWnd, int item, BOOL striked) -{ - LOGFONT lf; - HFONT hFont; - BOOL previous; - - hFont = (HFONT)SendDlgItemMessage(hWnd, item, WM_GETFONT, 0, 0); - GetObject(hFont, sizeof(lf), &lf); - previous = lf.lfItalic; - lf.lfItalic = striked; - SendDlgItemMessage(hWnd, item, WM_SETFONT, (WPARAM)CreateFontIndirect(&lf), TRUE); - return previous; -} - - int GetCourSelProtocol(int sel){ - int j; - int protoindex=0; - int selectedProto = 0; - for (j = 0 ; j < protoCount ; j++) { - if ( !isInterestingProto(j) ) continue; - { - if (protoindex==(sel)){ - return j; - } - } - protoindex++; - } - return -1; -} - -LRESULT SetDlgItems(HWND hwndDlg, int coursel) -{ - SendDlgItemMessage(hwndDlg, IDC_REQSTATUSLABEL, WM_SETTEXT, 0,(LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)reqStatus[coursel], GCMDF_TCHAR)); - SendDlgItemMessage(hwndDlg, IDC_COURSTATUSLABEL, WM_SETTEXT, 0,(LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courStatus[coursel], GCMDF_TCHAR)); - return TRUE; -} - -int GetReconnectDelayFromSlider(int slide) -{ - if (slide < 4) return 6+slide; - else if (slide < 29) return 2+slide* 2; - else if (slide < 53) return -85+slide* 5; - else if (slide < 65) return -350+slide*10; - else if (slide < 85) return-1650+slide*30; - else return -4200+slide*60; -} - -int GetSliderFromReconnectDelay(int delay) -{ - if (delay< 6) return 0; - else if (delay< 10) return -6+delay; - else if (delay< 60) return -1+delay/ 2; - else if (delay< 180) return 17+delay/ 5; - else if (delay< 300) return 35+delay/10; - else if (delay< 900) return 55+delay/30; - else if (delay<1800) return 70+delay/60; - else return 100; -} -BOOL GetStringFromDelay(TCHAR * str, int delay) -{ - int min,sec; - min = (int)delay/60; - sec = delay-min*60; - int pos = _stprintf(str,_T("%s "), TranslateT("Reconnect after")); - if (min) pos += _stprintf(&str[pos],_T("%d %s "),min,TranslateT("min")); - if (sec) pos += _stprintf(&str[pos],_T("%d %s"),sec,TranslateT("sec")); -// if (!min) sprintf(str,"%s (Too fast!)",str); - return (delay<60); -} - - -void GetLastActiveLocalTime(SYSTEMTIME * at, unsigned long Seconds){ - FILETIME ft; - ULARGE_INTEGER t; - - GetSystemTimeAsFileTime(&ft); - t.u.LowPart = ft.dwLowDateTime; - t.u.HighPart = ft.dwHighDateTime; - t.QuadPart -= (__int64)Seconds*10000000; - ft.dwLowDateTime = t.u.LowPart; - ft.dwHighDateTime = t.u.HighPart; - FileTimeToSystemTime(&ft,at); - SystemTimeToTzSpecificLocalTime(NULL,at,at); -} - -int GetTimeZone(TCHAR * name){ - TIME_ZONE_INFORMATION tzi={0}; - DWORD dwSta; - - dwSta= GetTimeZoneInformation( &tzi ); - switch (dwSta) { - case 0: - case TIME_ZONE_ID_STANDARD: -#ifdef UNICODE - wcscpy(name,tzi.StandardName); -#else - _stprintf(name,_T("%S"),tzi.StandardName); -#endif - return -(tzi.Bias+tzi.StandardBias); - break; - case TIME_ZONE_ID_DAYLIGHT: -#ifdef UNICODE - wcscpy(name,tzi.DaylightName); -#else - _stprintf(name,_T("%S"),tzi.DaylightName); -#endif - return -(tzi.Bias+tzi.DaylightBias); - break; - case TIME_ZONE_ID_INVALID: - default: - name[0] = 0; - return 0; - break; - } -} -void my_u2a(const TCHAR* src, char * target, unsigned int max){ -#ifdef UNICODE - int r = WideCharToMultiByte(codePage, 0, src, -1, target, max, NULL, NULL ); - /*if (!r){ - int err=GetLastError(); - WCHAR errBuf[1024]; - int p = wsprintf(errBuf,L"Error %u: \n",err); - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - err, - 0, - &errBuf[p], - 1024-p-1, - NULL); - MessageBoxW(NULL, errBuf, L"Error u2a", MB_OK); - }*/ -#else - strncpy(target,src,max); -#endif - target[ max ] = 0; -} - -void my_a2u(const char* src, TCHAR * target, unsigned int max){ -#ifdef UNICODE - int r = MultiByteToWideChar(codePage, 0, src, -1, target, max); -#else - strncpy(target,src,max); -#endif - target[ max ] = 0; -} - -UINT ParseString(TCHAR *szstring,TCHAR *sztemp, unsigned int MaxOutLen) -{ - UINT loop=0; - TCHAR *weekdays[]={LPGENT("Sunday"),LPGENT("Monday"),LPGENT("Tuesday"),LPGENT("Wednesday"),LPGENT("Thursday"),LPGENT("Friday"),LPGENT("Saturday")}; - TCHAR *wdays_short[]={LPGENT("Sun"),LPGENT("Mon"),LPGENT("Tue"),LPGENT("Wed"),LPGENT("Thu"),LPGENT("Fri"),LPGENT("Sat")}; - TCHAR *monthnames[]={LPGENT("January"),LPGENT("February"),LPGENT("March"),LPGENT("April"),LPGENT("May"),LPGENT("June"),LPGENT("July"),LPGENT("August"),LPGENT("September"),LPGENT("October"),LPGENT("November"),LPGENT("December")}; - TCHAR *mnames_short[]={LPGENT("Jan"),LPGENT("Feb"),LPGENT("Mar"),LPGENT("Apr"),LPGENT("May"),LPGENT("Jun"),LPGENT("Jul"),LPGENT("Aug"),LPGENT("Sep"),LPGENT("Oct"),LPGENT("Nov"),LPGENT("Dec")}; - SYSTEMTIME st = {0}; - BOOL stFilled = FALSE; - BOOL tzFilled = FALSE; - TCHAR tzName[128]; - int tzDrift; - *sztemp = '\0'; - UINT inpLen=_tcsclen(szstring); - UINT pos=0; - for(loop=0;loop12)?12:0)):12); - break; - - case 'p': - res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%s"),TranslateTS((st.wHour>12)?_T("PM"):_T("AM"))); - break; - - case 'M': - res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%02i"),st.wMinute); - break; - - case 'S': - res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%02i"),st.wSecond); - break; - - case 'L': - case 'l': - case 'K': - case 'k': - { - switch (szstring[loop]){ - case 'L': - case 'l': - res = GetDateFormat(localeID, szstring[loop]=='L'?DATE_LONGDATE:DATE_SHORTDATE, &st, NULL, &sztemp[pos], MaxOutLen-pos); - break; - case 'K': - case 'k': - res = GetTimeFormat(localeID, szstring[loop]=='K'?0:TIME_NOSECONDS, &st, NULL, &sztemp[pos], MaxOutLen-pos); - default: - break; - } - if (res>0) res--; - else res=0; - } break; - default: - break; - } - break; - case 'z': case 'Z': - if (!tzFilled) { - tzDrift = GetTimeZone(tzName); - tzFilled = TRUE; - } - if (szstring[loop]=='Z') res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%s"),tzName); - else { - res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%02d:%02d"),div(tzDrift,60).quot,tzDrift<0?-div(tzDrift,60).rem:div(tzDrift,60).rem); - } - break; - case 'b': - res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("\x0D\x0A")); - break; - case 't': - res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%c"),_T('\t')); - break; - default: - res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%%%c"),szstring[loop]); - break; - } - } - if (res<0) break; - else pos += res; - } - //sztemp[MaxOutLen]=sztemp[pos]=0; // Just in case - return pos; -} - - - diff --git a/!NotAdopted/SmartAutoAway/autoaway.cpp b/!NotAdopted/SmartAutoAway/autoaway.cpp deleted file mode 100644 index 18754df9d2..0000000000 --- a/!NotAdopted/SmartAutoAway/autoaway.cpp +++ /dev/null @@ -1,662 +0,0 @@ -/* - -Miranda IM: the free IM client for Microsoft* Windows* - -Copyright 2000-2006 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -#include "globals.h" - - -// globals -//static HANDLE AutoAwayEventHandle = NULL; -//static HANDLE StatusModeChangeEventHandle = NULL; -//static HANDLE ProtoAckEventHandle = NULL; -//static HANDLE AutoAwayShutdownHandle = NULL; -//static HANDLE AutoAwayOptInitialiseHandle = NULL; - - -//#define AA_LASTSTATUS "LastStatus_" -//#define AA_ONLYIF "OnlyIf" -//#define AA_ONLYIF2 "OnlyIf2" - -//#define ME_IDLE_CHANGED "Miranda/SmartIdle/Changed" -//static HANDLE hIdleEvent = NULL; - - -#define allprotomodes 0x03FF //0000 0011 1111 1111; -#define aa_OnlyIfBitsDefault 0x01BB01B8 //2 x 0000 0001 1011 1011; - //1111 0000 0000 0000; -//#define known 0x8000 //1000 0000 0000 0000; - - - - -//static int aa_OnlyIfDefaults[] = {2,2,2,2,1,2,2,2,2,1}; - -extern unsigned long lastIdleEventTime; - - -int AutoAwayOptInitialise(WPARAM wParam,LPARAM lParam) -{ - OPTIONSDIALOGPAGE odp; - - ZeroMemory(&odp,sizeof(odp)); - odp.cbSize=sizeof(odp); - odp.position=1000000000; -#ifdef SAA_PLUGIN - odp.hInstance=g_hInst; -#else - odp.hInstance=GetModuleHandle(NULL); -#endif - odp.pszTemplate=MAKEINTRESOURCEA(IDD_OPT_SMARTAUTOAWAY); - odp.pszTitle=SECTIONNAME; - odp.pszGroup="Status"; - odp.pfnDlgProc=DlgProcAutoAwayOpts; - odp.flags=ODPF_BOLDGROUPS; - CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp); - return 0; -} - -static short int curIdleStatus = -1; //0: NotIdle, 1: Short Idle, 2: Long Idle, -1 Not init yet: Will be inited on AutoAwayEvent; -int AutoAwayEvent(WPARAM wParam, LPARAM lParam) -{ -// char str[MAXMODULELABELLENGTH]; -//#define IDF_ISIDLE 0x1 // idle has become active (if not set, inactive) -//#define IDF_SHORT 0x2 // short idle mode -//#define IDF_LONG 0x4 // long idle mode -//#define IDF_PRIVACY 0x8 // if set, the information provided shouldn't be given to third parties. -//#define IDF_ONFORCE 0x10 // screensaver/onstationlocked,etc cause instant idle - - int j; - -#ifdef AALOG - { - char log[1024]=""; - sprintf(log,"IdleEvent came: %sdle;%s%s%s%sorced.", - lParam & IDF_ISIDLE?"I":"Not i", - lParam & IDF_SHORT?" Short;":"", - lParam & IDF_LONG?" Long;":"", - lParam & IDF_PRIVACY?" Private;":"", - lParam & IDF_ONFORCE?" F":"Not f"); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); - { - MIRANDA_IDLE_INFO mii; - ZeroMemory(&mii, sizeof(mii)); - mii.cbSize = sizeof(mii); - if (CallService(MS_IDLE_GETIDLEINFO, 0, (LPARAM)&mii)==0){ - sprintf(log,"IdleInfo valid: IdleTime:%d; %srivate; Status: %s(%d); aaLock: %s.", - mii.idleTime, - mii.privacy?"P":"Not p", - CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)mii.aaStatus, 0), - mii.aaStatus, - mii.aaLock?"Yes":"No"); - } else { - sprintf(log,"IdleInfo Failed: Size: %d; IdleTime: %d.",mii.cbSize,mii.idleTime); - } - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); - } - } -#endif - if ( lParam & IDF_ISIDLE ) { //going to sleep... - if ( lParam & IDF_LONG ) { //... deeply - if (curIdleStatus > 1) return 0; // we are already deeply sleeping... - curIdleStatus = 2; - } else { //... lite if IDF_LONG is not set - if (curIdleStatus > 0) return 0; // we are already sleeping... - curIdleStatus = 1; - } - } else { // we are going to awake - if (curIdleStatus == 0) return 0; // we are already awake... - curIdleStatus = 0; - } - if (!starting){ - lastIdleEventTime = time(NULL)-secondsAfterLastActivity; - if ((idleOptsPerm&IdleSuppressAutoHere)!=0) { - DBWriteContactSettingByte(NULL,AA_MODULE,AA_LASTIDLESTATUS,(BYTE)curIdleStatus); - DBWriteContactSettingDword(NULL,AA_MODULE,AA_LASTIDLETIME,(DWORD)lastIdleEventTime); - } } - switch (curIdleStatus) { - case 0: - xModifyMenu(0,CMIF_CHECKED); - xModifyMenu(1,0); - xModifyMenu(2,0); - break; - case 1: - xModifyMenu(0,0); - xModifyMenu(1,CMIF_CHECKED); - xModifyMenu(2,0); - break; - case 2: - xModifyMenu(0,0); - xModifyMenu(1,CMIF_GRAYED); - xModifyMenu(2,CMIF_CHECKED); - break; - } - - for (j = 0 ; j < protoCount ; j++) { - if ( proto[j]->type != PROTOTYPE_PROTOCOL ) continue; - { //status mode change - int newStatus = 0; - int reqStatusInd = numStatuses-StatusToProtoIndex(reqStatus[j],allprotomodes); - bool isStatusLocked = DBGetContactSettingByte( NULL, proto[j]->szName, , "LockMainStatus", 0 ) != 0; - if (isStatusLocked) newStatus = reqStatus[j]; - else switch (curIdleStatus) { - case 1 : { //sleeping lite - if ( GetBits(awayStatusesPerm[j],maskIsShortAwayEnabled)){ - int bits = 1<<(reqStatusInd); - BOOL permit = GetBits(onlyIfBitsPerm[j], bits); - if ( permit ) { - // get the index of the status we should use - newStatus = aa_Status[GetBits(awayStatusesPerm[j],maskShortAwayStatus)-1]; - } else { -#ifdef AALOG - { - char log[1024] ; - sprintf(log,"%s: Status Change to short idle was not permitted",proto[j]->szName,0); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); - } -#endif - continue; - } - - } else continue; - break; - } - case 2 : { //sleeping deeply - if ( GetBits(awayStatusesPerm[j],maskIsLongAwayEnabled) ) { - int bits = 1<<(reqStatusInd+16); - BOOL permit = GetBits(onlyIfBitsPerm[j], bits); - if ( permit ) { - // get the index of the status we should use - newStatus = aa_Status[GetBits(awayStatusesPerm[j],maskLongAwayStatus)-1]; - } else { -#ifdef AALOG - { - char log[1024] ; - sprintf(log,"%s: Status Change to long idle was not permitted",proto[j]->szName,0); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); - } -#endif - continue; - } - } else continue; - break; - } - case 0: { //wakening up - newStatus = reqStatus[j]; -#ifdef AALOG - { - char str[256]; - sprintf(str,"%s WakeningUp: %s",proto[j]->szName,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0)); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); - } -#endif - break; - } - } // switch - if (newStatus){ - courAwayStatus[j] = newStatus; - //FatalError? and "dontReconnectOnFatalError"? and we are not just awaken -#ifdef AALOG - { - char str[1000]; - sprintf(str,"%s: Reconnect conditions before change status to %s(%d) are: FatalError did%s happen; DontReconnectOnFatalError is %sabled and we are going to %s.", - proto[j]->szName, - CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0),newStatus, - (protoStatus[j]&2)?"":"n't", - (reconnectOptsPerm[j]&aa_ReconnectNotFatalError)?"En":"Dis", - (curIdleStatus==1)?"take a short nap":((curIdleStatus==2)?"sleep":"awake")); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); - } -#endif - if ((protoStatus[j]&2)&& - (reconnectOptsPerm[j]&aa_ReconnectNotFatalError)&& - (curIdleStatus>0)) { - // do nothing :) but only the log, eventualy -#ifdef AALOG - char str[1000]; - sprintf(str,"%s: we will not change the status to %s(%d).", - proto[j]->szName, - CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0),newStatus); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - } else { -#ifdef AALOG - char str[1000]; - sprintf(str,"%s: we will change the status to %s(%d).", - proto[j]->szName, - CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0),newStatus); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - if ( CallProtoService(proto[j]->szName, PS_GETSTATUS, 0, 0) != newStatus ) { - //if (DBGetContactSettingByte( NULL, proto[j]->szName, , "LockMainStatus", 0 )) - // continue; //szName - - CallProtoService(proto[j]->szName, PS_SETSTATUS, newStatus, 0); -#ifdef AALOG - } else { - char str[256]; - sprintf(str,"%s: %s already set",proto[j]->szName,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0)); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - } - } - if (isStatusLocked) { - // do nothing - log only -#ifdef AALOG - char str[1000]; - sprintf(str,"%s: Protocol Locked to %s(%d). Not touching StatusMessage", - proto[j]->szName, - CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0),newStatus); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - } else if (messCaps[j] && !(lParam&IDF_PRIVACY)){//setting the statusMessage if protocol supports AND privacy is disabled - TCHAR * awayMsg=0; - int specificMsg = messCaps[j] & Proto_Status2Flag(newStatus); - - switch (curIdleStatus) { - case 0 : specificMsg = (specificMsg > 0) && (GetBits(idleMessOpts[j],IdleMessOptsMaskUseHere)>0); break; - case 1 : specificMsg = (specificMsg > 0) && (GetBits(idleMessOpts[j],IdleMessOptsMaskUseShort)>0); break; - case 2 : specificMsg = (specificMsg > 0) && (GetBits(idleMessOpts[j],IdleMessOptsMaskUseLong)>0); break; - } - if (/*!starting &&*/ specificMsg){ - awayMsg = (TCHAR *)mir_alloc((maxMessageLength+1)*sizeof(TCHAR)); - //TCHAR temp[maxMessageLength+1]; - switch (curIdleStatus) { - case 0 : ParseString(mesgHerePerm[j],awayMsg,maxMessageLength); break; - case 1 : ParseString(mesgShortPerm[j],awayMsg,maxMessageLength); break; - case 2 : ParseString(mesgLongPerm[j],awayMsg,maxMessageLength); break; - default: awayMsg[0]=0; - } - //my_u2a(temp, awayMsg, maxMessageLength); - } else { -#ifdef UNICODE - if (HasAwayMessageW){ - awayMsg = (TCHAR *) CallService(MS_AWAYMSG_GETSTATUSMSGW, (WPARAM) newStatus, 0); - } else { - char *temp=(char *)CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) newStatus, 0); - if ((int)temp == CALLSERVICE_NOTFOUND) awayMsg = 0; - else{ - awayMsg = (TCHAR *)mir_alloc((maxMessageLength+1)*sizeof(TCHAR)); - my_a2u(temp,awayMsg,maxMessageLength); - mir_free(temp); - } - } -#else - char *temp=(char *)CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) newStatus, 0); - awayMsg=(char *)CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) newStatus, 0); - if ((int)temp == CALLSERVICE_NOTFOUND) awayMsg = 0; -#endif - } -#ifdef AALOG - { - char str[1000]; - sprintf(str,"%s: Specific Status Message is %s",proto[j]->szName, - specificMsg?"Enabled":"Disabled"); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); - sprintf(str,"%s: Going to %s (%d); StatusMessage is: %s", proto[j]->szName,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0),newStatus, - awayMsg ? awayMsg : "none or private"); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); - } -#endif -#ifdef UNICODE - if (protoHasAwayMessageW[j]) CallProtoService(proto[j]->szName, PS_SETAWAYMSGW, newStatus, (LPARAM) awayMsg); - else { - char temp[maxMessageLength+1]; - my_u2a(awayMsg,temp,maxMessageLength); - CallProtoService(proto[j]->szName, PS_SETAWAYMSG, newStatus, (LPARAM) temp); - } -#else - CallProtoService(proto[j]->szName, PS_SETAWAYMSG, newStatus, (LPARAM) awayMsg); -#endif - if (awayMsg) { -#ifdef AALOG - {char str[1000]; - sprintf(str,"%s: Cleaning after MS_AWAYMSG_GETSTATUSMSG: %s",proto[j]->szName,awayMsg); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);} -#endif - mir_free(awayMsg); - } - if ((curIdleStatus==0) && (GetBits(idleMessOpts[j],IdleMessOptsMaskRstHere)>0) && /*!starting &&*/ specificMsg){ -#ifdef AALOG - char str[1000]; - sprintf(str,"%s: Scheduling \"ResetDefaultStatusMessage\" after %d seconds",proto[j]->szName,GetBits(idleMessOpts[j],IdleMessOptsMaskRstHereDelay)); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - isWaitingForRestoreStatusMessage[j] = GetBits(idleMessOpts[j],IdleMessOptsMaskRstHereDelay)/2+1; - } - } - }//if - } //StatusChange Was done - } //for - if (starting) { -#ifdef AALOG - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"Clearing the \"starting\" flag..."); -#endif - starting = 0; - } - return 0; -} - - - -extern int StatusModeChangeEvent(WPARAM wParam,LPARAM lParam) -{ - int j=0; - char str[256]; - -#ifdef AALOG - { - char log[1024]; - sprintf(log,"Status Mode change event: %s: %s\n\n",lParam,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, wParam, 0)); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); - } -#endif - if (lParam){ - for (j = 0 ; j < protoCount ; j++) { - if ( proto[j]->type != PROTOTYPE_PROTOCOL ) continue; - if (strcmp((char *)lParam,proto[j]->szName)==0) { - sprintf(str,AA_LASTREQUESTEDSTATUS,proto[j]->szName); - reqStatus[j] = wParam; - DBWriteContactSettingWord(NULL,AA_MODULE,str,(WORD)reqStatus[j]); - } - } - } else { - if (idleOptsPerm&KeepMainStatusOffline) { -#ifdef AALOG - { - char log[1024]; - sprintf(log,"Global Status Mode change event: %s. Keep it offline!",CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, wParam, 0)); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); - } -#endif - DBWriteContactSettingWord(NULL,"CList","Status",(WORD)ID_STATUS_OFFLINE); - } - if (starting && (wParam == ID_STATUS_OFFLINE)){ -#ifdef AALOG - { - char log[1024]; - sprintf(log,"Do not set last request status to %s. We are still starting.",CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, wParam, 0)); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); - } -#endif - } else for (j = 0 ; j < protoCount ; j++) { - if ( proto[j]->type != PROTOTYPE_PROTOCOL ) continue; - sprintf(str,AA_LASTREQUESTEDSTATUS,proto[j]->szName); - reqStatus[j] = wParam; - DBWriteContactSettingWord(NULL,AA_MODULE,str,(WORD)reqStatus[j]); - } - } -#ifdef AALOG - { - char log[1024] = {0}; - for (j = 0 ; j < protoCount ; j++) { - sprintf(log,"%s%d:%s: %s\n",log,j,proto[j]->szName,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, reqStatus[j], 0)); - } - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"Status Mode change event: done"); - } -#endif - if (idleOptsPerm&IdleHereOnStatusChange){ - if (curIdleStatus){ - if (wParam!=ID_STATUS_OFFLINE){ -#ifdef AALOG - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"New requested status. Forcing ""Not Idle""."); -#endif - SimulateIdle(0); - } - } - } - -// CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"Keeping Last Requested statuses"); - if (theDialog) SetDlgItems(theDialog, courProtocolSelection); - if (theDialogIdleMessages) SetDlgItemsIdleMessages(theDialogIdleMessages, courProtocolSelection); - return 0; -} - - - -int ProtoAckEvent(WPARAM wParam,LPARAM lParam) -{ -#ifdef AALOG - char log[2048]; -#endif - char str[1024]; - int j = 0; - ACKDATA * ack = (ACKDATA*) lParam; - for (j = 0 ; j < protoCount ; j++) if (proto[j]->type==PROTOTYPE_PROTOCOL) if (strcmp(ack->szModule,proto[j]->szName)==0){ - if (ack->type==ACKTYPE_STATUS) { -// MessageBox( 0,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->lParam, 0),proto[j]->szName,0); - if (!(ack->hContact)) ProtocolsProc(j,ack); - if (ack->result==ACKRESULT_SUCCESS){ - courStatus[j] = ack->lParam; - if (theDialog){ - int coursel = SendDlgItemMessage(theDialog, IDC_AAPROTOCOL, CB_GETCURSEL, 0, 0); - SendDlgItemMessageA(theDialog,IDC_AAPROTOCOL,CB_GETLBTEXT,coursel,(LPARAM)str); - if (strcmp(ack->szModule,str)==0){ - SetDlgItems(theDialog,GetCourSelProtocol(coursel)); -// SendDlgItemMessage(theDialog, IDC_COURSTATUSLABEL, WM_SETTEXT, 0, -// (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courStatus[j], 0)); - } - } - } - } else if (ack->type==ACKTYPE_LOGIN) { - if (!ack->hContact) LoginAck(j,ack); - } - } - -#ifdef AALOG -// if (theDialog) SendDlgItemMessage(theDialog, 40201, WM_SETTEXT, 0,(LPARAM)ack->szModule); - sprintf(log,"ProtoAck: szModule: %s;",ack->szModule); - sprintf(str,"%s",ack->hContact?(char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)ack->hContact,0):"null"); - sprintf(log,"%s hContact: %s;",log,str); -// if (theDialog) SendDlgItemMessage(theDialog, 40202, WM_SETTEXT, 0,(LPARAM)str); - sprintf(str,"%d",ack->type); - sprintf(log,"%stype: %s;",log,str); -// if (theDialog) SendDlgItemMessage(theDialog, 40203, WM_SETTEXT, 0,str); - sprintf(str,"%d",ack->result); - sprintf(log,"%s result: %s;",log,str); -// if (theDialog) SendDlgItemMessage(theDialog, 40204, WM_SETTEXT, 0,str); - sprintf(str,"%d(%s)",ack->hProcess, - CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->hProcess, 0)); - sprintf(log,"%s hProcess: %s;",log,str); -// if (theDialog) SendDlgItemMessage(theDialog, 40205, WM_SETTEXT, 0,str); - sprintf(str,"%d(%s)",ack->lParam, - CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->lParam, 0)); - sprintf(log,"%s lParam: %s;",log,str); -// if (theDialog) SendDlgItemMessage(theDialog, 40206, WM_SETTEXT, 0,str); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); -#endif - return 0; -} - - -int SimulateIdle(int idlstatus) -{ -// MessageBox(theDialog,"ButtonPressed","Button",0); - int flags = IDF_ISIDLE; - switch (idlstatus) - { - case 0: {flags = 0;/*MessageBox(theDialog,"BeHere","Button Pressed",0);*/ break;} - case 1: {flags |= IDF_SHORT; /*MessageBox(theDialog,"BeAway","Button Pressed",0);*/ break;} - case 2: {flags |= IDF_LONG; /*MessageBox(theDialog,"BeNA","Button Pressed",0);*/ break;} - } - if (idleOptsPerm&IdleBitsPrivate) flags |= IDF_PRIVACY; - isCurrentlyIdle = idlstatus; - NotifyEventHooks( hIdleEvent, 0, flags ); - return 0; -} - -LRESULT SetDlgItemsAA(HWND hwndDlg, int coursel){ - int status = awayStatuses[coursel]; - long onlyif = onlyIfBits[coursel]; - BOOL enabledShort = (status & maskIsShortAwayEnabled)>0; - BOOL enabledLong = (status & maskIsLongAwayEnabled)>0; - int i =0; - EnableWindow(GetDlgItem(hwndDlg, IDC_AASTATUS), enabledShort); - EnableWindow(GetDlgItem(hwndDlg, IDC_AALONGSTATUS), enabledLong); - CheckDlgButton(hwndDlg, IDC_AASHORTIDLE, enabledShort?BST_CHECKED:BST_UNCHECKED ); - CheckDlgButton(hwndDlg, IDC_AALONGIDLE, enabledLong?BST_CHECKED:BST_UNCHECKED ); - - SendDlgItemMessage(hwndDlg, IDC_AASTATUS, CB_RESETCONTENT, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_AALONGSTATUS, CB_RESETCONTENT, 0, 0); - for (i=0;i0; - BOOL bitl = IsStatusBitSet(aa_Status[i],onlyif>>16)>0; - BOOL bita = IsStatusBitSet(aa_Status[i],protoModes[coursel])==0; - EnableWindow(GetDlgItem(hwndDlg, aa_Status[i]), enabledShort); - StrikeOut(hwndDlg,aa_Status[i],bita); - CheckDlgButton(hwndDlg, aa_Status[i], bits?BST_CHECKED:BST_UNCHECKED ); - EnableWindow(GetDlgItem(hwndDlg, aa_Status[i]+0x10), enabledLong); - StrikeOut(hwndDlg,aa_Status[i]+0x10,bita); - CheckDlgButton(hwndDlg, aa_Status[i]+0x10, bitl?BST_CHECKED:BST_UNCHECKED ); -// ShowWindow(GetDlgItem(hwndDlg, aa_Status[i]), bita); -// ShowWindow(GetDlgItem(hwndDlg, aa_Status[i]+0x10), bita); - } - } - { - int s = status & 0x000F; - int l = status & 0x00F0; - l = l>>4; - s = StatusToProtoIndex(aa_Status[s-1],protoModes[coursel]); - l = StatusToProtoIndex(aa_Status[l-1],protoModes[coursel]); - SendDlgItemMessage(hwndDlg, IDC_AASTATUS, CB_SETCURSEL, s-1, 0); - SendDlgItemMessage(hwndDlg, IDC_AALONGSTATUS, CB_SETCURSEL, l-1, 0); - } - return TRUE; -} - -BOOL CALLBACK DlgProcOptsAA(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - SetDlgItemsAA(hwndDlg, courProtocolSelection); - return TRUE; - case WM_USER+1: - { - awayStatuses[courProtocolSelection] = (short)SetBits(awayStatuses[courProtocolSelection],maskIsShortAwayEnabled,IsDlgButtonChecked(hwndDlg, IDC_AASHORTIDLE)==BST_CHECKED); - awayStatuses[courProtocolSelection] = (short)SetBits(awayStatuses[courProtocolSelection],maskIsLongAwayEnabled,IsDlgButtonChecked(hwndDlg, IDC_AALONGIDLE)==BST_CHECKED); - SetDlgItemsAA(hwndDlg, courProtocolSelection); - break; - } - case WM_USER+2: - { - int t = HIWORD(lParam)?16:0; - int thebit = numStatuses-StatusToProtoIndex(LOWORD(lParam),allprotomodes); - int value = IsDlgButtonChecked(hwndDlg, LOWORD(lParam)+t)==BST_CHECKED; - thebit = 1<<(thebit+t); - onlyIfBits[courProtocolSelection] = - SetBits(onlyIfBits[courProtocolSelection], - thebit, - value); - break; - } - case WM_USER+3: - { - int awStInd = SendDlgItemMessage(hwndDlg, lParam, CB_GETCURSEL, 0, 0); - awStInd = StatusByProtoIndex(protoModes[courProtocolSelection],awStInd+1); - awStInd = StatusToProtoIndex(awStInd,allprotomodes); - if (lParam == IDC_AASTATUS) { - awayStatuses[courProtocolSelection] = (short)SetBits(awayStatuses[courProtocolSelection],maskShortAwayStatus,awStInd); - } else if (lParam == IDC_AALONGSTATUS) { - awayStatuses[courProtocolSelection] = (short)SetBits(awayStatuses[courProtocolSelection],maskLongAwayStatus,awStInd); - } -#ifdef _DEBUG - else MessageBoxA(hwndDlg,"Came From Long Place","WM_USER+3",0) -#endif //_DEBUG - ; - SetDlgItemsIdleMessages(theDialogIdleMessages, courProtocolSelection); - break; - } - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_AASHORTIDLE: - case IDC_AALONGIDLE: - { - SendMessage(hwndDlg, WM_USER+1,0,0); - break; - } - case ID_STATUS_AWAY: - case ID_STATUS_DND: - case ID_STATUS_NA: - case ID_STATUS_OCCUPIED: - case ID_STATUS_INVISIBLE: - case ID_STATUS_ONTHEPHONE: - case ID_STATUS_OUTTOLUNCH: - case ID_STATUS_ONLINE: - case ID_STATUS_FREECHAT: - case ID_STATUS_OFFLINE: - { - SendMessage(hwndDlg, WM_USER+2,0,wParam); - break; - } - case ID_STATUS_AWAY+16: - case ID_STATUS_DND+16: - case ID_STATUS_NA+16: - case ID_STATUS_OCCUPIED+16: - case ID_STATUS_INVISIBLE+16: - case ID_STATUS_ONTHEPHONE+16: - case ID_STATUS_OUTTOLUNCH+16: - case ID_STATUS_ONLINE+16: - case ID_STATUS_FREECHAT+16: - case ID_STATUS_OFFLINE+16: - { - SendMessage(hwndDlg, WM_USER+2,0,(wParam-16)|0x00010000); - break; - } - case IDC_AASTATUS: - case IDC_AALONGSTATUS: - { - if ( HIWORD(wParam) != CBN_SELCHANGE ) return TRUE; - SendMessage(hwndDlg, WM_USER+3,0,LOWORD(wParam)); - break; - } //case - } - if ((HIWORD(wParam)==BN_CLICKED)||(HIWORD(wParam)==CBN_SELCHANGE)) - { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - break; - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->idFrom) { - case 0: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: { - return TRUE; - } - } - break; - } - break; - case WM_DESTROY: - break; - } - return FALSE; -} - - - diff --git a/!NotAdopted/SmartAutoAway/dlgproc.cpp b/!NotAdopted/SmartAutoAway/dlgproc.cpp deleted file mode 100644 index e37ce72ce9..0000000000 --- a/!NotAdopted/SmartAutoAway/dlgproc.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/* - -Miranda IM: the free IM client for Microsoft* Windows* - -Copyright 2000-2006 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -#include "globals.h" - -BOOL CALLBACK DlgProcAutoAwayOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ -// char str[MAXMODULELABELLENGTH]; - static short int tabprotosel; - switch (msg) - { - case WM_INITDIALOG: - { - short int t,p,protoListed; - TCITEM tci; - RECT theTabSpace; - RECT rcClient; - { - RECT rcTab, rcDlg; - TabCtrl_GetItemRect(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB),0,&rcTab); - theTabSpace.top = rcTab.bottom; // the size of the tab - GetWindowRect(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB), &rcTab); - GetWindowRect(hwndDlg, &rcDlg); - theTabSpace.bottom = rcTab.bottom -rcTab.top -theTabSpace.top; - theTabSpace.top = rcTab.top -rcDlg.top +theTabSpace.top; - theTabSpace.left = rcTab.left - rcDlg.left; - theTabSpace.right = rcTab.right-rcTab.left; - } - theDialog = hwndDlg; - TranslateDialogDefault(hwndDlg); - protoListed = 0; - for (p = 0 ; p < protoCount ;p++) { - int caps=0; - if ( !isInterestingProto(p) ) continue; - caps = CallProtoService(proto[p]->szName, PS_GETCAPS, PFLAGNUM_2, 0); - PROTOACCOUNT* protoAccount=ProtoGetAccount(proto[p]->szName); - if ((int)protoAccount!=CALLSERVICE_NOTFOUND){ - SendDlgItemMessage(hwndDlg, IDC_AAPROTOCOL, CB_ADDSTRING, 0, (LPARAM)protoAccount->tszAccountName ); - } else SendDlgItemMessageA(hwndDlg, IDC_AAPROTOCOL, CB_ADDSTRING, 0, (LPARAM)proto[p]->szName ); - protoListed++; - } - tabprotosel = DBGetContactSettingWord(NULL, AA_MODULE, AA_PROTOSELECTION, 0); - t = (tabprotosel&0x0F00) >> 8; if (t>3) t=3; - p = (tabprotosel&0x00FF); - if ((p>=protoListed)) p= protoListed-1; - SendDlgItemMessage(hwndDlg, IDC_AAPROTOCOL, CB_SETCURSEL, p, 0); - SetDlgItems(hwndDlg, courProtocolSelection = GetCourSelProtocol(p)); - - tci.mask = TCIF_PARAM|TCIF_TEXT; - -#ifdef SAA_PLUGIN - theDialogAA = CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_SAA_AA), hwndDlg, DlgProcOptsAA); -#else - theDialogAA = CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_OPT_SAA_AA), hwndDlg, DlgProcOptsAA); -#endif - tci.lParam = (LPARAM)theDialogAA; - tci.pszText = TranslateT("Statuses"); - GetClientRect(theDialogAA,&rcClient); - SendMessage(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB), TCM_INSERTITEM, (WPARAM)0, (LPARAM)&tci); - MoveWindow((HWND)theDialogAA,theTabSpace.left+(theTabSpace.right-rcClient.right)/2, - theTabSpace.top+(theTabSpace.bottom-rcClient.bottom)/2, - rcClient.right,rcClient.bottom,1); - ShowWindow((HWND)tci.lParam, (t==0)?SW_SHOW:SW_HIDE); - - -#ifdef SAA_PLUGIN - theDialogIdle = CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_SAA_IDLE), hwndDlg, DlgProcOptsIdle); -#else - theDialogIdle = CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_OPT_SAA_IDLE), hwndDlg, DlgProcOptsIdle); -#endif - tci.lParam = (LPARAM)theDialogIdle; - tci.pszText = TranslateT("Idle"); - GetClientRect(theDialogIdle,&rcClient); - SendMessage(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB), TCM_INSERTITEM, (WPARAM)1, (LPARAM)&tci); - MoveWindow((HWND)theDialogIdle,theTabSpace.left+(theTabSpace.right-rcClient.right)/2, - theTabSpace.top+(theTabSpace.bottom-rcClient.bottom)/2, - rcClient.right,rcClient.bottom,1); - ShowWindow((HWND)tci.lParam, (t==1)?SW_SHOW:SW_HIDE); - -#ifdef SAA_PLUGIN - theDialogIdleMessages = CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_SAA_IDLEMESSAGES), hwndDlg, DlgProcOptsIdleMessages); -#else - theDialogIdleMessages = CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_OPT_SAA_IDLEMESSAGES), hwndDlg, DlgProcOptsIdleMessages); -#endif - tci.lParam = (LPARAM)theDialogIdleMessages; - tci.pszText = TranslateT("Status Messages"); - GetClientRect(theDialogIdleMessages,&rcClient); - SendMessage(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB), TCM_INSERTITEM, (WPARAM)2, (LPARAM)&tci); - MoveWindow((HWND)theDialogIdleMessages,theTabSpace.left+(theTabSpace.right-rcClient.right)/2, - theTabSpace.top+(theTabSpace.bottom-rcClient.bottom)/2, - rcClient.right,rcClient.bottom,1); - ShowWindow((HWND)tci.lParam, (t==2)?SW_SHOW:SW_HIDE); - -#ifdef SAA_PLUGIN - theDialogReconnect = CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_SAA_RECONNECT), hwndDlg, DlgProcOptsReconnect); -#else - theDialogReconnect = CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_OPT_SAA_RECONNECT), hwndDlg, DlgProcOptsReconnect); -#endif - tci.lParam = (LPARAM)theDialogReconnect; - tci.pszText = TranslateT("Reconnect"); - GetClientRect(theDialogReconnect,&rcClient); - SendMessage(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB), TCM_INSERTITEM, (WPARAM)3, (LPARAM)&tci); - MoveWindow((HWND)theDialogReconnect,theTabSpace.left+(theTabSpace.right-rcClient.right)/2, - theTabSpace.top+(theTabSpace.bottom-rcClient.bottom)/2, - rcClient.right,rcClient.bottom,1); - ShowWindow((HWND)tci.lParam, (t==3)?SW_SHOW:SW_HIDE); - TabCtrl_SetCurSel(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB),t); - - if(enableThemeDialogTexture) { - enableThemeDialogTexture(theDialogAA, ETDT_ENABLETAB); - enableThemeDialogTexture(theDialogIdle, ETDT_ENABLETAB); - enableThemeDialogTexture(theDialogIdleMessages, ETDT_ENABLETAB); - enableThemeDialogTexture(theDialogReconnect, ETDT_ENABLETAB); - } - return TRUE; - } - - case WM_COMMAND: - { - switch (LOWORD(wParam)) { - case IDC_AAPROTOCOL: - { - int cour = SendDlgItemMessage(hwndDlg, IDC_AAPROTOCOL, CB_GETCURSEL, 0, 0); - courProtocolSelection = GetCourSelProtocol(cour); - if ( HIWORD(wParam) != CBN_SELCHANGE ) return TRUE; - DBWriteContactSettingWord(NULL, AA_MODULE, AA_PROTOSELECTION, - (unsigned short)(tabprotosel=courProtocolSelection|(tabprotosel&0xFF00))); - SetDlgItems(hwndDlg, courProtocolSelection); - SetDlgItemsReconnect(theDialogReconnect,courProtocolSelection); - SetDlgItemsAA(theDialogAA,courProtocolSelection); - SetDlgItemsIdleMessages(theDialogIdleMessages,courProtocolSelection); - break; - } - case IDC_APPLYTOALL: - { - int i; - for (i=0;iidFrom) { - case 0: { - BOOL CommandApply; - if ( (CommandApply = lParam && ((LPNMHDR)lParam)->code == PSN_APPLY) || (lParam && ((LPNMHDR)lParam)->code == PSN_RESET) ) { - int j=0; -#ifdef _DEBUG - //MessageBox(hwndDlg,CommandApply?"Apply":"Cancel","EventHapened",0); -#endif - for (j = 0 ; j < protoCount ; j++) { - if ( isInterestingProto(j) ) { - char str[256]; - if (CommandApply) { - onlyIfBitsPerm[j] = onlyIfBits[j]; - awayStatusesPerm[j] = awayStatuses[j]; - reconnectOptsPerm[j] = reconnectOpts[j]; - sprintf(str,AA_BITSONLYIF,proto[j]->szName); - DBWriteContactSettingDword(NULL,AA_MODULE,str,onlyIfBitsPerm[j]); - sprintf(str,AA_AWAYSTATUSES,proto[j]->szName); - DBWriteContactSettingWord(NULL,AA_MODULE,str,awayStatusesPerm[j]); - sprintf(str,AA_RECONNECTOPTS,proto[j]->szName); - DBWriteContactSettingDword(NULL,AA_MODULE,str,reconnectOptsPerm[j]); - if (messCaps[j]) { - idleMessOptsPerm[j] = idleMessOpts[j]; - sprintf(str,idleMsgOptionsName,proto[j]->szName); - DBWriteContactSettingDword(NULL,AA_MODULE,str,idleMessOptsPerm[j]); - - sprintf(str,idleMsgOptionsTextHere,proto[j]->szName); - _tcscpy(mesgHerePerm[j],mesgHere[j]); - DBWriteContactSettingTString(NULL,AA_MODULE,str,mesgHerePerm[j]); - - sprintf(str,idleMsgOptionsTextShort,proto[j]->szName); - _tcscpy(mesgShortPerm[j],mesgShort[j]); - DBWriteContactSettingTString(NULL,AA_MODULE,str,mesgShortPerm[j]); - - sprintf(str,idleMsgOptionsTextLong,proto[j]->szName); - _tcscpy(mesgLongPerm[j],mesgLong[j]); - DBWriteContactSettingTString(NULL,AA_MODULE,str,mesgLongPerm[j]); - } - } else { - onlyIfBits[j] = onlyIfBitsPerm[j]; - awayStatuses[j] = awayStatusesPerm[j]; - reconnectOpts[j] = reconnectOptsPerm[j]; - idleMessOpts[j] = idleMessOptsPerm[j]; - if (messCaps[j]) { - _tcscpy(mesgHere[j],mesgHerePerm[j]); - _tcscpy(mesgShort[j],mesgShortPerm[j]); - _tcscpy(mesgLong[j],mesgLongPerm[j]); - } - } - } - } - if (CommandApply) { - idleOptsPerm = idleOpts; - DBWriteContactSettingDword(NULL,AA_MODULE,AA_IDLEOPTIONS,idleOptsPerm); - } else { - idleOpts = idleOptsPerm; - } - } //if PSN_APPLY - break; - case IDC_OPT_SAA_TAB: - switch (((LPNMHDR)lParam)->code) - { - case TCN_SELCHANGING: - { - TCITEM tci; - tci.mask = TCIF_PARAM; - TabCtrl_GetItem(GetDlgItem(hwndDlg,IDC_OPT_SAA_TAB),TabCtrl_GetCurSel(GetDlgItem(hwndDlg,IDC_OPT_SAA_TAB)),&tci); - ShowWindow((HWND)tci.lParam,SW_HIDE); - } - break; - case TCN_SELCHANGE: - { - TCITEM tci; - short int t; - tci.mask = TCIF_PARAM; - t = TabCtrl_GetCurSel(GetDlgItem(hwndDlg,IDC_OPT_SAA_TAB)); - TabCtrl_GetItem(GetDlgItem(hwndDlg,IDC_OPT_SAA_TAB),t,&tci); - DBWriteContactSettingWord(NULL, AA_MODULE, AA_PROTOSELECTION, - (unsigned short)(tabprotosel=(t<<8)|(tabprotosel&0xF0FF))); - ShowWindow((HWND)tci.lParam,SW_SHOW); - { BOOL enableW = (tci.lParam!=(long)theDialogIdle); - EnableWindow(GetDlgItem(hwndDlg,IDC_AAPROTOCOL),enableW); - EnableWindow(GetDlgItem(hwndDlg,IDC_APPLYTOALL),enableW); - } - } - break; - } - break; - } - }//end case(LPNMHDR)lParam)->idFrom - - } -//WTF??? if(wParam!=0x12345678) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - } - return FALSE; -} - - - diff --git a/!NotAdopted/SmartAutoAway/globals.cpp b/!NotAdopted/SmartAutoAway/globals.cpp deleted file mode 100644 index 82f2087b3d..0000000000 --- a/!NotAdopted/SmartAutoAway/globals.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - -Miranda IM: the free IM client for Microsoft* Windows* - -Copyright 2000-2006 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -#include "globals.h" - -HANDLE hIdleEvent = NULL; -HANDLE hNetlib; -UINT hIdleTimer = 0; - -BOOL starting=1; // this flag will be cleared later - -#ifdef UNICODE -bool *protoHasAwayMessageW=0; -bool HasAwayMessageW=0; -#endif - -int *isWaitingForRestoreStatusMessage=0; - - int *reqStatus=0; - int *courStatus=0; - int *courAwayStatus=0; - - int *protoModes=0; - - short int *awayStatusesPerm=0; - long *onlyIfBitsPerm=0; - short int *awayStatuses=0; - long *onlyIfBits=0; - - int aa_Status[] = { - ID_STATUS_OFFLINE, - ID_STATUS_ONLINE, - ID_STATUS_AWAY, - ID_STATUS_NA, - ID_STATUS_OCCUPIED, - ID_STATUS_DND, - ID_STATUS_FREECHAT, - ID_STATUS_INVISIBLE, - ID_STATUS_ONTHEPHONE, - ID_STATUS_OUTTOLUNCH -}; - - int numStatuses = sizeof(aa_Status)/sizeof(aa_Status[0]); - -HWND theDialog = 0; -HWND theDialogReconnect=0; -HWND theDialogIdle=0; -HWND theDialogIdleMessages=0; -HWND theDialogAA=0; - - -PROTOCOLDESCRIPTOR **proto=0; -int protoCount=0; -int courProtocolSelection = 0; - -int localeID=0; -int codePage=0; - - -TCHAR *VariableList[][2]={ - {NULL,LPGENT("Date")}, - {_T("Y"),LPGENT("year (4 digits)")}, - {_T("y"),LPGENT("year (2 digits)")}, - {_T("m"),LPGENT("month")}, - {_T("E"),LPGENT("name of month")}, - {_T("e"),LPGENT("short name of month")}, - {_T("d"),LPGENT("day")}, - {_T("W"),LPGENT("weekday (full)")}, - {_T("w"),LPGENT("weekday (abbreviated)")}, - {_T("L"),LPGENT("Localized Date (Long)")}, - {_T("l"),LPGENT("Localized Date (Short)")}, - {NULL,LPGENT("Time")}, - {_T("H"),LPGENT("hours (24)")}, - {_T("h"),LPGENT("hours (12)")}, - {_T("p"),LPGENT("AM/PM")}, - {_T("M"),LPGENT("minutes")}, - {_T("S"),LPGENT("seconds")}, - {_T("K"),LPGENT("Localized Time (Long)")}, - {_T("k"),LPGENT("Localized Time (no Seconds)")}, - {NULL,LPGENT("Time Zone")}, - {_T("z"),LPGENT("total bias")}, - {_T("Z"),LPGENT("time zone name")}, - {NULL,LPGENT("Format")}, - {_T("t"),LPGENT("tabulator")}, - {_T("b"),LPGENT("line break")}, -}; - -HOTKEYDESC hotkeydescs[] = { - {sizeof(HOTKEYDESC), "saa_benotidle", "Not Idle", SECTIONNAME, AA_IDLE_BENOTIDLESERVICE, 0, 0}, - {sizeof(HOTKEYDESC), "saa_beshortidle", "Short Idle", SECTIONNAME, AA_IDLE_BESHORTIDLESERVICE, 0, 0}, - {sizeof(HOTKEYDESC), "saa_belongidle", "Long Idle", SECTIONNAME, AA_IDLE_BELONGIDLESERVICE, 0, 0}, - {sizeof(HOTKEYDESC), "saa_reconnect", "Reconnect", SECTIONNAME, AA_IDLE_RECONNECTSERVICE, 0, 0}, - }; - diff --git a/!NotAdopted/SmartAutoAway/globals.h b/!NotAdopted/SmartAutoAway/globals.h deleted file mode 100644 index 788076a0c2..0000000000 --- a/!NotAdopted/SmartAutoAway/globals.h +++ /dev/null @@ -1,349 +0,0 @@ -#ifdef UNICODE - #ifndef _UNICODE - #define _UNICODE - #endif -#endif - -//#ifdef VCL_VC60 -#include "AggressiveOptimize.h" -//#endif - -//#include - -#ifdef _DEBUG -#ifndef UNICODE - #define AALOG - #define AALOG1 -#endif -#endif - -#define _WIN32_WINNT 0x0700 -#ifndef SAA_PLUGIN - #include "../../src/core/commonheaders.h" -#else - #include - #include - #include - #include - #include - #include "newpluginapi.h" - #include - #include - #include - #include - #include - #include - #include - #include "m_idle.h" - #ifndef time - #include - #endif - #define offsetof(s,m) (size_t)&(((s *)0)->m) - extern BOOL (WINAPI *enableThemeDialogTexture)(HANDLE, DWORD); -#ifdef AALOG - #include -#endif -#endif -#include - - -//#ifdef SAA_PLUGIN -// extern struct MM_INTERFACE memoryManagerInterface; -// #define mir_alloc(n) memoryManagerInterface.mmi_malloc(n) -// #define mir_free(ptr) memoryManagerInterface.mmi_free(ptr) -// #define mir_realloc(ptr,size) memoryManagerInterface.mmi_realloc(ptr,size) -//#endif - -#define SECTIONNAME "Smart Auto Away" - - #include "resource.h" -//#define IDF_ISIDLE 0x1 // idle has become active (if not set, inactive) -#define IDF_SHORT 0x2 // short idle mode -#define IDF_LONG 0x4 // long idle mode -//#define IDF_PRIVACY 0x8 // if set, the information provided shouldn't be given to third parties. -#define IDF_ONFORCE 0x10 // screensaver/onstationlocked,etc cause instant idle - -extern int FirstTick; - -#ifdef UNICODE -extern bool *protoHasAwayMessageW; -extern bool HasAwayMessageW; -#endif - -extern HOTKEYDESC hotkeydescs[]; - -//typedef struct { -// int cbSize; // sizeof() -// unsigned int idleTime; // idle in mins, if zero then disabled -// int privacy; // user doesnt want other people seeing anything more than they are idle -// int aaStatus; // status to go to when user is auto away -//} MIRANDA_IDLE_INFO; -//typedef struct { -// int cbSize; // sizeof() -// int enabled; // monitoring is going on -// int idleShortTime; // short idle in mins, if zero then disabled -// int idleLongTime; // long idle in mins, if zero then disabled -// int privacy; // user doesnt want other people seeing anything more than they are idle -//} MIRANDA_IDLE_INFO; - -//typedef struct{ -// int cbSize; //sizeof //5*sizeof(int) or 4*sizeof(int) -// unsigned int fieldTime; //enabled or idleTime in minutes -// int field1; //idleShortTime or privacy -// int field2; //idleLongTime or aaStatus -// // the "new structure ends here" -// int field3; //privacy or none -//} MYIDLEINFO; -//#define MS_IDLE_GETIDLEINFO "Miranda/Idle/GetInfo" -//#define ME_IDLE_CHANGED "Miranda/Idle/Changed" -extern int isCurrentlyIdle; - -extern unsigned long idleOptsPerm; // CMHG SL S SM P L S --LONG-- --SHORT- -extern unsigned long idleOpts; // C G L S tM P L S --LONG-- --SHORT- -#define idleOptsDefault 0x95851E0A // 1001 0101 1000 0101 00011110 00001010 -#define IdleBitsTimeFirst 0x000000FF // ---- ---- ---- ---- -------- 11111111 -#define IdleBitsTimeSecond 0x0000FF00 // ---- ---- ---- ---- 11111111 -------- -#define IdleBitsCheck 0x80000000 // 1000 0000 0000 0000 00000000 00000000 -#define IdleBitsMethod 0x00400000 // 0000 0000 0100 0000 00000000 00000000 -#define IdleBitsFirstOn 0x00010000 // 0000 0000 0000 0001 00000000 00000000 -#define IdleBitsSecondOn 0x00040000 // 0000 0000 0000 0100 00000000 00000000 -#define IdleBitsOnSaver 0x01000000 // 0000 0001 0000 0000 00000000 00000000 -#define IdleBitsOnLock 0x04000000 // 0000 0100 0000 0000 00000000 00000000 -#define IdleBitsGLI 0x10000000 // 0001 0000 0000 0000 00000000 00000000 -#define IdleBitsPrivate 0x00100000 // 0000 0000 0001 0000 00000000 00000000 -#define IdleSuppressIdleMenu 0x40000000 // 0100 0000 0000 0000 00000000 00000000 -#define IdleSuppressAutoHere 0x20000000 // 0010 0000 0000 0000 00000000 00000000 -#define KeepMainStatusOffline 0x08000000 // 0000 1000 0000 0000 00000000 00000000 -#define IdleHereOnStatusChange 0x00800000// 0000 0000 1000 0000 00000000 00000000 - - - - -#ifdef SAA_PLUGIN - int __cdecl LoadAutoAwayModule(void); - extern HINSTANCE g_hInst; -#endif - - -#define MS_SYSTEM_GETIDLE "Miranda/GetIdle" -#ifdef AALOG - extern HANDLE hNetlib; -#endif -static int InitVariables( WPARAM wParam, LPARAM lParam ); - -extern HANDLE hIdleEvent; -extern UINT hIdleTimer; - -extern BOOL CALLBACK DlgProcAutoAwayOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -extern BOOL CALLBACK DlgProcOptsIdle(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - - -int AutoAwayOptInitialise(WPARAM wParam,LPARAM lParam); -//extern int AutoAwayShutdown(WPARAM wParam,LPARAM lParam); - -#define IDLEMODULE "Idle" -// live settings -//extern int idleCheckPerm; -//extern int idleMethodPerm; -//extern int idleTimeFirstPerm; // this is in mins -//extern int idleTimeSecondPerm; // -//extern int idleTimeFirstOnPerm; -//extern int idleTimeSecondOnPerm; -//extern int idleOnSaverPerm; -//extern int idleOnLockPerm; -//extern int idleGLIPerm; -//extern int idlePrivatePerm; - -//We will not try to import previous Idle settings anymore -// db settings keys -//#define IDL_IDLECHECK "IdleCheck" -//#define IDL_IDLEMETHOD "IdleMethod" -//#define IDL_IDLEGLI "IdleGLI" -//#define IDL_IDLETIME1ST "IdleTime1st" -//#define IDL_IDLETIME2ND "IdleTime2nd" -//#define IDL_IDLEONSAVER "IdleOnSaver" -//#define IDL_IDLEONLOCK "IdleOnLock" -//#define IDL_IDLETIME1STON "IdleTime1stOn" -//#define IDL_IDLETIME2NDON "IdleTime2ndOn" -//#define IDL_IDLEPRIVATE "IdlePrivate" - -extern BOOL (WINAPI * MyGetLastInputInfo)(PLASTINPUTINFO); -extern int IdleGetInfo(WPARAM wParam, LPARAM lParam); - -VOID CALLBACK IdleTimer(HWND hwnd, UINT message, UINT idEvent, DWORD dwTime); -BOOL InitDialogIdlePart(HWND hwndDlg); - - -//AutoAway Module -#define AA_IDLEOPTIONS "IdleOptions" -#define AA_LASTIDLESTATUS "IdleLastStatus" -#define AA_LASTIDLETIME "IdleLastTime" -#define AA_OLDMODULE "AutoAway" -#define AA_USESHORT "IsShortEnabled" -#define AA_USELONG "IsLongEnabled" -#define AA_SHORTSTATUS "ShortStatus" -#define AA_LONGSTATUS "LongStatus" - -#define AA_MODULE "SmartAutoAway" - -#define AA_PROTOSELECTION "ProtoSelection" - -#define AA_AWAYSTATUSES "AwayStatuses_%s" -#define AA_BITSONLYIF "BitsOnlyIf_%s" -#define AA_LASTREQUESTEDSTATUS "LastRequestedStatus_%s" - -//#define AA_SIMULATEIDLESERVICE "SAA/SimulateIdle" -#define AA_IDLE_BENOTIDLESERVICE "SAA/IdleBeNotIdle" -MIRANDASERVICE idleServiceNotIdle(WPARAM w, LPARAM l); -#define AA_IDLE_BESHORTIDLESERVICE "SAA/IdleBeShortIdle" -MIRANDASERVICE idleServiceShortIdle(WPARAM w, LPARAM l); -#define AA_IDLE_BELONGIDLESERVICE "SAA/IdleBeLongIdle" -MIRANDASERVICE idleServiceLongIdle(WPARAM w, LPARAM l); -#define AA_IDLE_RECONNECTSERVICE "SAA/ForceReconnect" -MIRANDASERVICE reconnectService(WPARAM w, LPARAM l); - -//#define aa_AwayStatusesDefault ((StatusToProtoIndex(ID_STATUS_AWAY,allprotomodes)<<8)|StatusToProtoIndex(ID_STATUS_NA,allprotomodes)) | 0x8000 - //K--- --21 LLLL SSSS -#define maskIsShortAwayEnabled 0x0100 -#define maskIsLongAwayEnabled 0x0200 -#define maskShortAwayStatus 0x000F -#define maskLongAwayStatus 0x00F0 - -#define allprotomodes 0x03FF // 0000 0011 1111 1111; -#define aa_OnlyIfBitsDefault 0x01BB01B8 //Short 0001 1011 1000; - //Long 0001 1011 1011 - - -extern HANDLE hStatusModeChangeEvent; - -extern int aa_Status[]; -extern int numStatuses; - -extern int *reqStatus; -extern int *courStatus; -extern int *courAwayStatus; //to be used in reconnect part - -extern int *protoModes; - -extern short int *awayStatusesPerm; -extern long *onlyIfBitsPerm; -extern short int *awayStatuses; -extern long *onlyIfBits; - - -extern HWND theDialog; -extern HWND theDialogReconnect; -extern HWND theDialogIdle; -extern HWND theDialogAA; -extern HWND theDialogIdleMessages; - - -extern PROTOCOLDESCRIPTOR **proto; -extern int protoCount; -extern int courProtocolSelection; - -unsigned long GetBits (unsigned long source,unsigned long mask); -unsigned long SetBits (unsigned long target,unsigned long mask,unsigned long value); -BOOL IsStatusBitSet(int status, int bits); -int StatusByProtoIndex(int modes, int index); -int StatusToProtoIndex(int status, int modes); - -int OldIndexToStatus(int oldIndex); -int StatusToOldIndex(int status); - -LRESULT SetDlgItems(HWND hwndDlg, int coursel); -LRESULT SetDlgItemsReconnect(HWND hwndDlg, int coursel); -LRESULT SetDlgItemsAA(HWND hwndDlg, int coursel); -LRESULT SetDlgItemsIdleMessages(HWND hwndDlg, int coursel); - -int StatusToProtoIndex(int status, int modes); -int GetCourSelProtocol(int sel); -BOOL StrikeOut(HWND hWnd, int item, BOOL striked); - -int AutoAwayShutdown(WPARAM wParam,LPARAM lParam); -int AutoAwayEvent(WPARAM wParam, LPARAM lParam); -//extern int SimulateIdle(HWND theDialog, int button); -int StatusModeChangeEvent(WPARAM wParam,LPARAM lParam); -int ProtoAckEvent(WPARAM wParam,LPARAM lParam); -int SimulateIdle(int idlstatus); - - -//Reconnect Part -int GetReconnectDelayFromSlider(int slide); -BOOL GetStringFromDelay(TCHAR * str, int delay); -int GetSliderFromReconnectDelay(int delay); -void ProtocolsProc(int protoIndex, ACKDATA * ack); -void LoginAck(int protoIndex, ACKDATA * ack); -void TimerProc(); -extern BOOL CALLBACK DlgProcOptsReconnect(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -#define AA_RECONNECTOPTS "ReconnectOptions_%s" -#define aa_ReconnectOptsDefault 0x003CC1AE -//-----60 sec-------- 1100 0001 1010 1110 -//DDDD DDDD DDDD DDDD Rfxx xxFN ANOD FIPL -#define aa_ReconnectBitsDelay 0xFFFF0000 -#define aa_ReconnectBitsEnabled 0x00008000 -#define aa_ReconnectNotFatalError 0x00004000 - -extern BOOL CALLBACK DlgProcOptsAA(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -extern long *reconnectOpts; -extern long *reconnectOptsPerm; -extern unsigned int *protoOfflineTimes; -extern int *protoStatus; //0:OK; :1:couning; 2:fatalError; - -//IdleMessage part -extern BOOL starting; -extern int *isWaitingForRestoreStatusMessage; -extern unsigned long secondsAfterLastActivity; - - -#define idleMsgOptionsTextHere "IdleMsgTextHere_%s" -#define idleMsgOptionsTextShort "IdleMsgTextShort_%s" -#define idleMsgOptionsTextLong "IdleMsgTextLong_%s" -#define messHereDefaultOld _T("I am back") -#define messShortDefaultOld _T("I am distracted") -#define messLongDefaultOld _T("I am sleeping") -#define messHereDefault _T("I came back on %H:%M:%S%b%Z (%z)") -#define messShortDefault _T("I am distracted since %H:%M:%S%b%Z (%z)") -#define messLongDefault _T("I fell asleep on %H:%M:%S %d %E %Y (%W)%b%Z (%z)") -#define maxMessageLength 2047 -extern TCHAR **mesgHere; -extern TCHAR **mesgShort; -extern TCHAR **mesgLong; -extern TCHAR **mesgHerePerm; -extern TCHAR **mesgShortPerm; -extern TCHAR **mesgLongPerm; - -#define idleMsgOptionsName "IdleMsgOpts_%s" -#define idleMsgOptionsDefault 0x0111103C -extern int *messCaps; - -extern BOOL CALLBACK DlgProcOptsIdleMessages(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -extern long *idleMessOptsPerm; -extern long *idleMessOpts; - // xxxx xxxL xxxS xxxH xxxE xxx- RSTHERE- -#define IdleMessOptsMaskRstHereDelay 0x000001FF // 0000 0000 0000 0000 0000 0001 11111111 -#define IdleMessOptsMaskRstHere 0x00001000 // 0000 0000 0000 0000 0001 0000 00000000 -#define IdleMessOptsMaskUseHere 0x00010000 // 0000 0000 0000 0001 0000 0000 00000000 -#define IdleMessOptsMaskUseShort 0x00100000 // 0000 0000 0001 0000 0000 0000 00000000 -#define IdleMessOptsMaskUseLong 0x01000000 // 0000 0001 0000 0000 0000 0000 00000000 - -extern int localeID; -extern int codePage; -void my_u2a(const TCHAR* src, char * target, unsigned int max); -void my_a2u(const char* src, TCHAR * target, unsigned int max); -void GetLastActiveLocalTime(SYSTEMTIME * at, unsigned long miliSeconds); -int GetTimeZone(TCHAR * name); -UINT ParseString(TCHAR *szstring,TCHAR *sztemp, unsigned int MaxOutLen); - -//borrowed from "Last Seen Plugin" -//#define VARIABLE_LIST "%s\n%%Y: \t %s\n%%y: \t %s\n%%m: \t %s\n%%E: \t %s\n%%e: \t %s\n%%d: \t %s\n%%W: \t %s\n%%w: \t %s\n\n%s\n%%H: \t %s\n%%h: \t %s\n%%p: \t %s\n%%M: \t %s\n%%S: \t %s\n\n%s\n%%z: \t %s\n%%Z: \t %s\n\n%s\n%%t: \t %s\n%%b: \t %s",Translate("-- Date --"),Translate("year (4 digits)"),Translate("year (2 digits)"),Translate("month"),Translate("name of month"),Translate("short name of month"),Translate("day"),Translate("weekday (full)"),Translate("weekday (abbreviated)"),Translate("-- Time --"),Translate("hours (24)"),Translate("hours (12)"),Translate("AM/PM"),Translate("minutes"),Translate("seconds"),Translate("-- Time Zone --"),Translate("total bias"),Translate("time zone name"),Translate("-- Format --"),Translate("tabulator"),Translate("line break") -extern TCHAR *VariableList[][2]; - -void AddIdleMenu(); -extern HANDLE hHookIconsChanged; -void xModifyMenu(int menuInd,long flags); -BOOL isInterestingProto(int j); diff --git a/!NotAdopted/SmartAutoAway/here.ico b/!NotAdopted/SmartAutoAway/here.ico deleted file mode 100644 index ab282fba52..0000000000 Binary files a/!NotAdopted/SmartAutoAway/here.ico and /dev/null differ diff --git a/!NotAdopted/SmartAutoAway/idle.cpp b/!NotAdopted/SmartAutoAway/idle.cpp deleted file mode 100644 index 9751bcf0e6..0000000000 --- a/!NotAdopted/SmartAutoAway/idle.cpp +++ /dev/null @@ -1,374 +0,0 @@ -/* - -Miranda IM: the free IM client for Microsoft* Windows* - -Copyright 2000-2006 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -#include "globals.h" -//#include "../../miranda-IM/core/commonheaders.h" - - -//int idleCheckPerm = 0; -//int idleMethodPerm = 0; -//int idleTimeFirstPerm = 5; // this is in mins -//int idleTimeSecondPerm = 10; // -//int idleTimeFirstOnPerm = 0; -//int idleTimeSecondOnPerm = 0; -//int idleOnSaverPerm = 0; -//int idleOnLockPerm = 0; -//int idleGLIPerm = 1; -//int idlePrivatePerm = 0; -BOOL (WINAPI * MyGetLastInputInfo)(PLASTINPUTINFO); -unsigned long idleOptsPerm; // C G L S M P L S --LONG-- --SHORT- -unsigned long idleOpts; // C G L S M P L S --LONG-- --SHORT- -static BOOL idleDialogInInit = FALSE; - BOOL InitDialogIdlePart(HWND hwndDlg) -{ -// TranslateDialogDefault(hwndDlg); - CheckDlgButton(hwndDlg, IDC_IDLECHECK, (idleOpts&IdleBitsCheck) ? BST_CHECKED : BST_UNCHECKED); - // check/uncheck options - CheckDlgButton(hwndDlg, IDC_IDLEONWINDOWS, (idleOpts&IdleBitsMethod) ? BST_UNCHECKED : BST_CHECKED); - CheckDlgButton(hwndDlg, IDC_IDLEONMIRANDA, (idleOpts&IdleBitsMethod) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_IDLEUSEGLI, (idleOpts&IdleBitsGLI) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_SCREENSAVER, (idleOpts&IdleBitsOnSaver) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_LOCKED, (idleOpts&IdleBitsOnLock) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_IDLESHORT, (idleOpts&IdleBitsFirstOn) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_IDLELONG, (idleOpts&IdleBitsSecondOn) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_IDLEPRIVATE, (idleOpts&IdleBitsPrivate) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_DISBABLEAUTOHERE, (idleOpts&IdleSuppressAutoHere) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_DISABLEIDLEMENU, (idleOpts&IdleSuppressIdleMenu) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_HEREONSTATUSCHANGE, (idleOpts&IdleHereOnStatusChange)? BST_CHECKED : BST_UNCHECKED); - // set times - idleDialogInInit = TRUE; - SetDlgItemInt(hwndDlg, IDC_IDLE1STTIME, GetBits(idleOpts,IdleBitsTimeFirst), FALSE); - SetDlgItemInt(hwndDlg, IDC_IDLE2NDTIME, GetBits(idleOpts,IdleBitsTimeSecond), FALSE); - idleDialogInInit = FALSE; - // enable options - SendMessage(hwndDlg, WM_USER+4, (WPARAM)((idleOpts&IdleBitsCheck)!=0), 0); - return TRUE; -} - -// delphi code here http://www.swissdelphicenter.ch/torry/printcode.php?id=2048 - BOOL IsWorkstationLocked(void) -{ - BOOL rc=0; - HDESK hDesk = OpenDesktopA("default", 0, FALSE, DESKTOP_SWITCHDESKTOP); - if ( hDesk != 0 ) { - rc = SwitchDesktop(hDesk) == FALSE; - CloseDesktop(hDesk); - } - return rc; -} - -// ticks every 2 seconds - int FirstTick; - unsigned long secondsAfterLastActivity; - unsigned long lastIdleEventTime = 0; - int isCurrentlyIdle=0; //0 notidle //1 short //2long - VOID CALLBACK IdleTimer(HWND hwnd, UINT message, UINT idEvent, DWORD dwTime) -{ - DWORD dwTick = GetTickCount(); - int isIdle[3] = {0}; - static int isEventFired[3] = {0}; - int j; - - if (FirstTick) { - FirstTick--; - if (FirstTick==0){ - int flags = 0; - starting = 1; - switch (isCurrentlyIdle) - { - default : {flags = 0;/*MessageBox(theDialog,"BeHere","Button Pressed",0);*/ break;} - case 1: {flags = IDF_SHORT|IDF_ISIDLE; /*MessageBox(theDialog,"BeAway","Button Pressed",0);*/ break;} - case 2: {flags = IDF_LONG|IDF_ISIDLE; /*MessageBox(theDialog,"BeNA","Button Pressed",0);*/ break;} - } - if (isCurrentlyIdle) { - lastIdleEventTime = DBGetContactSettingDword(NULL,AA_MODULE,AA_LASTIDLETIME,(DWORD)time(NULL)); - secondsAfterLastActivity = time(NULL) - lastIdleEventTime; - - } else secondsAfterLastActivity = 0; - flags |= idleOpts&IdleBitsPrivate?IDF_PRIVACY:0; - NotifyEventHooks( hIdleEvent, 0, flags ); //Tell everyone we are here - return; - } - } - - for (j = 0 ; j < protoCount ; j++) { - if ( !isInterestingProto(j) ) continue; - if (isWaitingForRestoreStatusMessage[j]) { - isWaitingForRestoreStatusMessage[j]--; - if (!(isWaitingForRestoreStatusMessage[j])) { -#ifdef UNICODE - TCHAR *awayMsg=0; - if (HasAwayMessageW){ - awayMsg = (TCHAR *) CallService(MS_AWAYMSG_GETSTATUSMSGW, (WPARAM) courAwayStatus[j], 0); - } else { - char *temp=(char *)CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) courAwayStatus[j], 0); - if ((int)temp == CALLSERVICE_NOTFOUND) awayMsg = 0; - else{ - awayMsg = (TCHAR *)mir_alloc((maxMessageLength+1)*sizeof(TCHAR)); - my_a2u(temp,awayMsg,maxMessageLength); - mir_free(temp); - } - } -#else - char * awayMsg = (char *) CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) courAwayStatus[j], 0); - if ((int)awayMsg==CALLSERVICE_NOTFOUND) awayMsg = NULL; -#endif - -#ifdef AALOG - { - char str[1000]; - sprintf(str,"%s: Restoring the default \"StatusMessage\": %s",proto[j]->szName,awayMsg ? awayMsg : "none"); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); - } -#endif -#ifdef UNICODE - if (protoHasAwayMessageW[j]) CallProtoService(proto[j]->szName, PS_SETAWAYMSGW, courAwayStatus[j], (LPARAM) awayMsg); - else { - char temp[maxMessageLength+1]; - my_u2a(awayMsg,temp,maxMessageLength); - CallProtoService(proto[j]->szName, PS_SETAWAYMSG, courAwayStatus[j], (LPARAM) temp); - } -#else - CallProtoService(proto[j]->szName, PS_SETAWAYMSG, courAwayStatus[j], (LPARAM) awayMsg); -#endif - if (awayMsg) { -#ifdef AALOG - char str[1000]; - sprintf(str,"%s: Cleaning after MS_AWAYMSG_GETSTATUSMSG: %s",proto[j]->szName,awayMsg); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - mir_free(awayMsg); - } - - } - } - } - - TimerProc(); //for the reconnect - secondsAfterLastActivity = 0; - isCurrentlyIdle = 0; - if ( (idleOptsPerm&IdleBitsCheck) == 0 ) return; - - if ( (idleOptsPerm&IdleBitsMethod) == 0 ) { - // use windows idle time - if ( GetBits(idleOptsPerm,IdleBitsGLI) && (MyGetLastInputInfo != 0) ) { - LASTINPUTINFO ii; - memset(&ii,0,sizeof(ii)); - ii.cbSize=sizeof(ii); - if ( MyGetLastInputInfo(&ii) ) dwTick = ii.dwTime; - } else { - // mouse check - static int mouseIdle = 0; - static POINT lastMousePos = {0}; - POINT pt; - GetCursorPos(&pt); - if ( pt.x != lastMousePos.x || pt.y != lastMousePos.y ) - { - mouseIdle=0; - lastMousePos=pt; - } - else mouseIdle += 2; // interval of timer - if ( mouseIdle ) dwTick = GetTickCount() - (mouseIdle * 1000); - } - } else { - // use miranda idle time - CallService(MS_SYSTEM_GETIDLE, 0, (LPARAM)&dwTick); - } - secondsAfterLastActivity = (GetTickCount() - dwTick)/1000; -#ifdef AALOG - { char log[1024]; - sprintf(log,"%d seconds after last activity",secondsAfterLastActivity); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);} -#endif - // has the first idle elapsed? If not permited FirstIdle time:ignore - isIdle[0] = (idleOptsPerm&IdleBitsFirstOn)? (secondsAfterLastActivity >= (DWORD)( GetBits(idleOptsPerm,IdleBitsTimeFirst) * 60 )):0; - // and the second? if not permited the SecondIdleTime: idnore - isIdle[1] = (idleOptsPerm&IdleBitsSecondOn)?(secondsAfterLastActivity >= (DWORD)( GetBits(idleOptsPerm,IdleBitsTimeSecond) * 60 )):0; - - isIdle[2] = FALSE; - if ( idleOptsPerm&IdleBitsOnSaver ) { // check saver - BOOL isScreenSaverRunning = FALSE; - SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &isScreenSaverRunning, FALSE); - isIdle[2] |= isScreenSaverRunning; - } - - // check workstation? - if ( idleOptsPerm&IdleBitsOnLock ) { // check station locked? - isIdle[2] |= IsWorkstationLocked(); - } - { //check if the new idle is more idle than the previous idle is idle ;) - int temp = isIdle[1]?2:((isIdle[0] || isIdle[2])?1:0); - if (temp>=isCurrentlyIdle) isCurrentlyIdle = temp; - else return; //if we are alredy idle then exit - } - for ( j = 0; j<3; j++ ) - { - int flags = ( idleOptsPerm&IdleBitsPrivate ? IDF_PRIVACY:0 ); - switch (j) { - case 0: flags |= IDF_SHORT; break; - case 1: flags |= IDF_LONG; break; - case 2: flags |= IDF_ONFORCE; break; - } - if ( isIdle[j]==1 && isEventFired[j] == 0 ) { // idle and no one knows - isEventFired[j]=1; - NotifyEventHooks( hIdleEvent, 0, IDF_ISIDLE | flags ); - } - if ( isIdle[j]==0 && isEventFired[j] == 1 ) { // not idle, no one knows - isEventFired[j]=0; - if ( !(idleOptsPerm&IdleSuppressAutoHere) ) NotifyEventHooks( hIdleEvent, 0, flags ); - } - }//for -// { -// int flags = ( idleOptsPerm&IdleBitsPrivate ? IDF_PRIVACY:0 ); -// if (isIdle[0]||isIdle[1]||isIdle[2]) flags |= IDF_ISIDLE; -// if (isIdle[0]) flags |= IDF_SHORT; -// if (isIdle[1]) flags |= IDF_LONG; -// if (isIdle[2]) flags |= IDF_ONFORCE; -// NotifyEventHooks( hIdleEvent, 0, flags ); -// } -} - - int IdleGetInfo(WPARAM wParam, LPARAM lParam) -{ - MIRANDA_IDLE_INFO * mii = (MIRANDA_IDLE_INFO *) lParam; - if (mii) { - int minutesAfterLastActivity = (time(NULL)-lastIdleEventTime)/60; -#ifdef AALOG - char log[1024]; - sprintf(log,"\"%s\": %d came.", - MS_IDLE_GETIDLEINFO, - mii->cbSize/sizeof(mii->cbSize)); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); -#endif - if (minutesAfterLastActivity<=0) minutesAfterLastActivity = 1; - //this is the only field with similar meaning in "old" and "new miranda"; - if (mii->cbSize/sizeof(mii->cbSize)>=2) mii->idleTime = isCurrentlyIdle?minutesAfterLastActivity:0; - if (mii->cbSize/sizeof(mii->cbSize)>=3) mii->privacy = (idleOptsPerm&IdleBitsPrivate) !=0; - if (mii->cbSize/sizeof(mii->cbSize)>=4) mii->aaStatus = isCurrentlyIdle==1?ID_STATUS_AWAY:(isCurrentlyIdle>1?ID_STATUS_NA:ID_STATUS_ONLINE); //dont know what to with that - if (mii->cbSize/sizeof(mii->cbSize)>=5) mii->aaLock = (idleOptsPerm&IdleSuppressAutoHere) !=0; - if (mii->cbSize/sizeof(mii->cbSize)>=6) mii->idleType = isCurrentlyIdle?1:0; - return 0; - } else return 1; -} - -BOOL CALLBACK DlgProcOptsIdle(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - InitDialogIdlePart(hwndDlg); - return TRUE; - case WM_USER+4: - { - DWORD nID[] = { IDC_IDLEONWINDOWS, - IDC_IDLEUSEGLI, - IDC_IDLEONMIRANDA, - IDC_SCREENSAVER, - IDC_LOCKED, - IDC_IDLESHORT, - IDC_IDLE1STTIME, - IDC_IDLELONG, - IDC_IDLE2NDTIME//,IDC_IDLEPRIVATE - }; - int j; - // enable/disable all sub controls, - for (j = 0; j < sizeof(nID) / sizeof(nID[0]); j++) { - int nEnable = wParam; - switch ( nID[j] ) { - case IDC_IDLEUSEGLI: nEnable &= IsDlgButtonChecked(hwndDlg, IDC_IDLEONWINDOWS) == BST_CHECKED ? 1 : 0; break; - case IDC_IDLE1STTIME: nEnable &= IsDlgButtonChecked(hwndDlg, IDC_IDLESHORT) == BST_CHECKED ? 1 : 0; break; - case IDC_IDLE2NDTIME: nEnable &= IsDlgButtonChecked(hwndDlg, IDC_IDLELONG) == BST_CHECKED ? 1 : 0; break; - } - EnableWindow(GetDlgItem(hwndDlg, nID[j]), nEnable); - } - - idleOpts=SetBits(idleOpts,IdleBitsCheck, IsDlgButtonChecked(hwndDlg, IDC_IDLECHECK) == BST_CHECKED); - idleOpts=SetBits(idleOpts,IdleBitsMethod, IsDlgButtonChecked(hwndDlg, IDC_IDLEONMIRANDA) == BST_CHECKED); - idleOpts=SetBits(idleOpts,IdleBitsFirstOn, IsDlgButtonChecked(hwndDlg, IDC_IDLESHORT) == BST_CHECKED); - idleOpts=SetBits(idleOpts,IdleBitsSecondOn, IsDlgButtonChecked(hwndDlg, IDC_IDLELONG) == BST_CHECKED); - idleOpts=SetBits(idleOpts,IdleBitsGLI, IsDlgButtonChecked(hwndDlg, IDC_IDLEUSEGLI) == BST_CHECKED); - idleOpts=SetBits(idleOpts,IdleBitsOnSaver, IsDlgButtonChecked(hwndDlg, IDC_SCREENSAVER) == BST_CHECKED); - idleOpts=SetBits(idleOpts,IdleBitsOnLock, IsDlgButtonChecked(hwndDlg, IDC_LOCKED) == BST_CHECKED); - idleOpts=SetBits(idleOpts,IdleBitsPrivate, IsDlgButtonChecked(hwndDlg, IDC_IDLEPRIVATE) == BST_CHECKED); - idleOpts=SetBits(idleOpts,IdleSuppressAutoHere, IsDlgButtonChecked(hwndDlg, IDC_DISBABLEAUTOHERE) == BST_CHECKED); - idleOpts=SetBits(idleOpts,IdleSuppressIdleMenu, IsDlgButtonChecked(hwndDlg, IDC_DISABLEIDLEMENU) == BST_CHECKED); - idleOpts=SetBits(idleOpts,IdleHereOnStatusChange, IsDlgButtonChecked(hwndDlg, IDC_HEREONSTATUSCHANGE) == BST_CHECKED); - break; - } - case WM_USER+8: - { - if (wParam == IDC_IDLE1STTIME) idleOpts = SetBits(idleOpts,IdleBitsTimeFirst,GetDlgItemInt(hwndDlg, wParam, NULL, FALSE)); - if (wParam == IDC_IDLE2NDTIME) idleOpts = SetBits(idleOpts,IdleBitsTimeSecond,GetDlgItemInt(hwndDlg, wParam, NULL, FALSE)); - break; - } - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_IDLEBUTTON: - case IDC_IDLEBUTTON+1: - case IDC_IDLEBUTTON+2:SimulateIdle(LOWORD(wParam)-IDC_IDLEBUTTON); break; - case IDC_IDLECHECK: - case IDC_IDLEONWINDOWS: - case IDC_IDLEONMIRANDA: - case IDC_IDLESHORT: - case IDC_IDLELONG: - case IDC_IDLEUSEGLI: - case IDC_SCREENSAVER: - case IDC_LOCKED: - case IDC_IDLEPRIVATE: - case IDC_DISBABLEAUTOHERE: - case IDC_HEREONSTATUSCHANGE: - case IDC_DISABLEIDLEMENU: - { - SendMessage(hwndDlg, WM_USER+4, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_IDLECHECK) == BST_CHECKED, 0); - break; - } - case IDC_IDLE1STTIME: - case IDC_IDLE2NDTIME: - { - if ( HIWORD(wParam) != EN_CHANGE ) return TRUE; - SendMessage(hwndDlg, WM_USER+8, LOWORD(wParam), 0); - break; - } - } - if (!idleDialogInInit) if ((HIWORD(wParam)==BN_CLICKED)||(HIWORD(wParam)==EN_CHANGE)) - { - if ((LOWORD(wParam)!=IDC_IDLEBUTTON)&&(LOWORD(wParam)!=IDC_IDLEBUTTON+1)&&(LOWORD(wParam)!=IDC_IDLEBUTTON+2)) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - break; - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->idFrom) { - case 0: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: { - return TRUE; - } - } - break; - } - break; - case WM_DESTROY: - break; - } - return FALSE; -} - diff --git a/!NotAdopted/SmartAutoAway/idleMenu.cpp b/!NotAdopted/SmartAutoAway/idleMenu.cpp deleted file mode 100644 index bc5ad2a255..0000000000 --- a/!NotAdopted/SmartAutoAway/idleMenu.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - -Miranda IM: the free IM client for Microsoft* Windows* - -Copyright 2000-2006 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -#include "globals.h" -#ifdef SAA_PLUGIN -# include "m_icolib.h" -#endif - -HANDLE hIdleMenu[4] = {NULL,NULL,NULL,NULL}; -HANDLE hHookIconsChanged = NULL; -static char *iconDescs[4]={"Not Idle","Short Idle","Long Idle","Reconnect"}; -static int iconInd[4]={IDI_IDLE_HERE,IDI_IDLE_SHORT,IDI_IDLE_LONG,IDI_RECONNECT}; -static char *IdleServices[4]={AA_IDLE_BENOTIDLESERVICE,AA_IDLE_BESHORTIDLESERVICE,AA_IDLE_BELONGIDLESERVICE,AA_IDLE_RECONNECTSERVICE}; - -void xModifyMenu(int menuInd,long flags) -{ if (hIdleMenu[menuInd]){ - CLISTMENUITEM mi = {0}; - - mi.cbSize = sizeof(mi); - mi.flags = CMIM_FLAGS; - mi.flags |= flags; - CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hIdleMenu[menuInd],(LPARAM)&mi); -} } - -static int hasIcoLib = 0; - -static void CListSetMenuItemIcon(HANDLE hMenuItem, HICON hIcon) -{ - CLISTMENUITEM mi = {0}; - - mi.cbSize = sizeof(mi); - mi.flags = CMIM_FLAGS | CMIM_ICON; - - mi.hIcon = hIcon; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuItem, (LPARAM)&mi); -} - -static int IconLibIconsChanged(WPARAM wParam, LPARAM lParam) -{ - int i; - for (i=0;i<4;i++) - { - HICON hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)IdleServices[i]); - CListSetMenuItemIcon(hIdleMenu[i], hIcon); - CallService(MS_SKIN2_RELEASEICON, 0, (LPARAM)IdleServices[i]); - } - return 0; -} - -void AddIdleMenu(){ - CLISTMENUITEM mi; - int i; - if (ServiceExists(MS_SKIN2_GETICON)){ - SKINICONDESC sid = {0}; - hHookIconsChanged = HookEvent(ME_SKIN2_ICONSCHANGED, IconLibIconsChanged); - hasIcoLib = 1; - sid.cbSize = SKINICONDESC_SIZE_V2; - sid.pszSection = SECTIONNAME; - sid.pszDefaultFile = NULL; - sid.iDefaultIndex = 0; - for (i=0;i<4;i++){ - sid.pszDescription = iconDescs[i]; - sid.pszName = IdleServices[i]; - sid.iDefaultIndex = iconInd[i]; - sid.hDefaultIcon = (HICON)LoadImage( - #ifdef SAA_PLUGIN - g_hInst, - #else - GetModuleHandle(NULL), - #endif - MAKEINTRESOURCE( iconInd[i] ), IMAGE_ICON, 0, 0, 0); - CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid); - DestroyIcon(sid.hDefaultIcon); - } - } - - ZeroMemory(&mi,sizeof(mi)); - mi.cbSize=sizeof(mi); - mi.pszPopupName="&Idle"; - mi.popupPosition=1000090000; - for (i=0;i<4;i++) - { - if (hasIcoLib) - mi.hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)IdleServices[i]); - else - mi.hIcon = (HICON)LoadImage( - #ifdef SAA_PLUGIN - g_hInst, - #else - GetModuleHandle(NULL), - #endif - MAKEINTRESOURCE(iconInd[i]), IMAGE_ICON, 0, 0, 0); - - mi.position=i+1; - mi.pszName=iconDescs[i]; - mi.pszService=IdleServices[i]; - if (i==3) mi.position=1000000; - hIdleMenu[i]=(HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi); - - if (hasIcoLib) - CallService(MS_SKIN2_RELEASEICON, 0, (LPARAM)IdleServices[i]); - else - DestroyIcon(mi.hIcon); - } -// return 0; -} - -MIRANDASERVICE idleServiceNotIdle(WPARAM w, LPARAM l){ - SimulateIdle(0); - return 0; -}; -MIRANDASERVICE idleServiceShortIdle(WPARAM w, LPARAM l){ - SimulateIdle(1); - return 0; -}; -MIRANDASERVICE idleServiceLongIdle(WPARAM w, LPARAM l){ - SimulateIdle(2); - return 0; -}; -MIRANDASERVICE reconnectService(WPARAM w, LPARAM l){ - int i; - for (i=0;iszName); - SetDlgItemText(hwndDlg,IDC_PROTODONOTSUPPORT,str); - } - idleDialogInInit = FALSE; - EnableWindow(GetDlgItem(hwndDlg, IDC_VARIABLES), (messCaps[coursel])); -// CheckDlgButton(hwndDlg, IDC_ENABLERECONNECT, enabledReconnect?BST_CHECKED:BST_UNCHECKED ); -// CheckDlgButton(hwndDlg, IDC_NOTFATALERROR, dontReconnectOnFatalError?BST_CHECKED:BST_UNCHECKED ); -// EnableWindow(GetDlgItem(hwndDlg, IDC_RECONNECTSLIDER), enabledReconnect); -// EnableWindow(GetDlgItem(hwndDlg, IDC_NOTFATALERROR), enabledReconnect); - return TRUE; -} - - - -BOOL CALLBACK DlgProcOptsIdleMessages(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - SetDlgItemsIdleMessages(hwndDlg, courProtocolSelection); - return TRUE; - case WM_USER+1: - { - EnableWindow(GetDlgItem(hwndDlg, IDC_RESTOREMSGSLIDER), wParam); - idleMessOpts[courProtocolSelection] = SetBits(idleMessOpts[courProtocolSelection],IdleMessOptsMaskRstHere,wParam); - break; - } - case WM_USER+2: - { - EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEMSGHERE), wParam); - EnableWindow(GetDlgItem(hwndDlg, IDC_RESTOREMSGSLIDER), wParam); - EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLERESTOREMSG), wParam); - idleMessOpts[courProtocolSelection] = SetBits(idleMessOpts[courProtocolSelection],IdleMessOptsMaskUseHere,wParam); - break; - } - case WM_USER+3: - { - EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEMSGSHORT), wParam); - idleMessOpts[courProtocolSelection] = SetBits(idleMessOpts[courProtocolSelection],IdleMessOptsMaskUseShort,wParam); - break; - } - case WM_USER+4: - { - EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEMSGLONG), wParam); - idleMessOpts[courProtocolSelection] = SetBits(idleMessOpts[courProtocolSelection],IdleMessOptsMaskUseLong,wParam); - break; - } - case WM_USER+8: - { - TCHAR temp[maxMessageLength+1]; - ParseString((TCHAR *)lParam,temp,maxMessageLength); -#ifdef UNICODE - if(!protoHasAwayMessageW[courProtocolSelection]) { - char tempa[maxMessageLength+1]; - my_u2a(temp, tempa, maxMessageLength); - my_a2u(tempa,temp,maxMessageLength); - } -#endif - SetDlgItemText(hwndDlg,IDC_PROTODONOTSUPPORT,temp); - break; - } - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_ENABLERESTOREMSG: - { - SendMessage(hwndDlg, WM_USER+1, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_ENABLERESTOREMSG) == BST_CHECKED, 0); - break; - } - case IDC_IDLEMSGHERE_THIS: - { - SendMessage(hwndDlg,WM_USER+2, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_IDLEMSGHERE_THIS) == BST_CHECKED, 0); - break; - } - case IDC_IDLEMSGSHORT_THIS: - { - SendMessage(hwndDlg,WM_USER+3, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_IDLEMSGSHORT_THIS) == BST_CHECKED, 0); - break; - } - case IDC_IDLEMSGLONG_THIS: - { - SendMessage(hwndDlg,WM_USER+4, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_IDLEMSGLONG_THIS) == BST_CHECKED, 0); - break; - } - case IDC_IDLEMSGHERE: - { - if (HIWORD(wParam)==EN_CHANGE || HIWORD(wParam)==EN_SETFOCUS){ - TCHAR str[maxMessageLength+1]; - GetDlgItemText(hwndDlg,IDC_IDLEMSGHERE,str,maxMessageLength+1); - SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)str); - } else if (HIWORD(wParam)==EN_KILLFOCUS) { - GetDlgItemText(hwndDlg,IDC_IDLEMSGHERE,mesgHere[courProtocolSelection],maxMessageLength+1); - SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)""); - } - break; - } - case IDC_IDLEMSGSHORT: - { - if (HIWORD(wParam)==EN_CHANGE || HIWORD(wParam)==EN_SETFOCUS){ - TCHAR str[maxMessageLength+1]; - GetDlgItemText(hwndDlg,IDC_IDLEMSGSHORT,str,maxMessageLength+1); - SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)str); - } else if (HIWORD(wParam)==EN_KILLFOCUS) { - GetDlgItemText(hwndDlg,IDC_IDLEMSGSHORT,mesgShort[courProtocolSelection],maxMessageLength+1); - SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)""); - } - break; - } - case IDC_IDLEMSGLONG: - { - if (HIWORD(wParam)==EN_CHANGE || HIWORD(wParam)==EN_SETFOCUS){ - TCHAR str[maxMessageLength+1]; - GetDlgItemText(hwndDlg,IDC_IDLEMSGLONG,str,maxMessageLength+1); - SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)str); - } else if (HIWORD(wParam)==EN_KILLFOCUS) { - GetDlgItemText(hwndDlg,IDC_IDLEMSGLONG,mesgLong[courProtocolSelection],maxMessageLength+1); - SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)""); - } - break; - } - case IDC_VARIABLES: - { - TCHAR szout[2048]=_T(""); - UINT pos=0; - for (int i=0;i<25;i++){ - if (VariableList[i][0]){ - pos+=_sntprintf(&szout[pos],2048-pos,_T("%%%s \t %s\n"),VariableList[i][0],TranslateTS(VariableList[i][1])); - } else { - pos+=_sntprintf(&szout[pos],2048-pos,_T("-- %s --\n"),TranslateTS(VariableList[i][1])); - } - } - //sprintf(szout,VARIABLE_LIST); - MessageBox(NULL,szout,TranslateT("Variables to use"),MB_OK|MB_TOPMOST); - break; - } - - break; //case WM_COMMAND - } - if (!idleDialogInInit) if ((HIWORD(wParam)==BN_CLICKED)||(HIWORD(wParam)==EN_CHANGE)) - { - if (LOWORD(wParam)!=IDC_VARIABLES) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - break; - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->idFrom) { - case 0: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: { - return TRUE; - } - } - break; - } - break; - case WM_HSCROLL: - if((HWND)lParam == GetDlgItem(hwndDlg, IDC_RESTOREMSGSLIDER)) { - moveScrollBarRestoreMsgEvent(hwndDlg); - if (LOWORD(wParam) == SB_ENDSCROLL) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - break; - case WM_DESTROY: - break; - } - return FALSE; -} diff --git a/!NotAdopted/SmartAutoAway/long.ico b/!NotAdopted/SmartAutoAway/long.ico deleted file mode 100644 index 37845ebbb0..0000000000 Binary files a/!NotAdopted/SmartAutoAway/long.ico and /dev/null differ diff --git a/!NotAdopted/SmartAutoAway/reconnect.cpp b/!NotAdopted/SmartAutoAway/reconnect.cpp deleted file mode 100644 index aad175c2f8..0000000000 --- a/!NotAdopted/SmartAutoAway/reconnect.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/* - -Miranda IM: the free IM client for Microsoft* Windows* - -Copyright 2000-2006 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -#include "globals.h" - -long *reconnectOptsPerm=0; -long *reconnectOpts=0; - -unsigned int *protoOfflineTimes=0; -int *protoStatus=0; //0:OK; :1:couning; 2:fatalError; 4:reconnectForced - - -void LoginAck(int protoIndex, ACKDATA * ack) -{ -#ifdef AALOG - char log[1024]; - sprintf(log,"LoginAck: %s: result: %d; hProcess: %d; lParam: %d;" , - proto[protoIndex]->szName, - ack->result,ack->hProcess,ack->lParam -// CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->hProcess, 0), -// CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->lParam, 0) - ); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); -#endif - if (ack->result == ACKRESULT_FAILED) switch (ack->lParam){ - case LOGINERR_WRONGPASSWORD: - case LOGINERR_BADUSERID: - case LOGINERR_WRONGPROTOCOL: - case LOGINERR_OTHERLOCATION: - { -#ifdef AALOG - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"LoginAck: FatalError occured"); -#endif - protoStatus[protoIndex]|=2; - protoOfflineTimes[protoIndex]=0; - return; - break; - } - } -} - - -void ProtocolsProc(int protoIndex, ACKDATA * ack) -//ProtoProc: ICQ-AUX: result: 0; hProcess: Online; lParam: Offline; -{ -#ifdef AALOG - char log[1024]; - sprintf(log,"ProtoProc: %s: result: %d; hProcess: %s; lParam: %s; RequestedStatus: %s; AutoAwayStatus: %s" , - proto[protoIndex]->szName, - ack->result, - CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->hProcess, 0), - CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->lParam, 0), - CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)reqStatus[protoIndex], 0), - CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courAwayStatus[protoIndex], 0) - ); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); -#endif - protoOfflineTimes[protoIndex]=0; - if (ack->lParam==ID_STATUS_OFFLINE) protoStatus[protoIndex]|=1; //will be counting, keeping eventual "FatalError" Flag - else protoStatus[protoIndex] = 0; //We are not offline or are connecting -> clear counting and "FatalError" -#ifdef AALOG - sprintf(log,"ProtoProc: %s: Result: ProtoStatus: %d", - proto[protoIndex]->szName,protoStatus[protoIndex]); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); -#endif - -} - -#ifdef AALOG -#define AALOG2 -#endif -int IsReconnectForbidden(int protoIndex){ //0 if it permitted -#ifdef AALOG2 - char str[256]; -#endif - if (!(protoStatus[protoIndex]&1)) return 1; //Proto is not counting or is not offline - protoOfflineTimes[protoIndex] += 2; //the timer ticks every 2 seconds - if (protoStatus[protoIndex]&4) { // Reconnect is forced -#ifdef AALOG2 - sprintf(str,"ReconnForbiddden: %s reconnection is forced.",proto[protoIndex]->szName); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - return 0; - } -#ifdef AALOG2 - sprintf(str,"ReconnForbiddden: %s is Offline and counting: %d to %d",proto[protoIndex]->szName,protoOfflineTimes[protoIndex],HIWORD(reconnectOptsPerm[protoIndex])); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - if (protoOfflineTimes[protoIndex] <= HIWORD(reconnectOptsPerm[protoIndex])) return 2; // not yet - if (!(reconnectOptsPerm[protoIndex]&aa_ReconnectBitsEnabled)) return 3; //reconnect is disabled -#ifdef AALOG2 - sprintf(str,"ReconnForbiddden: %s has ReconnectEnabled",proto[protoIndex]->szName); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - if (protoStatus[protoIndex]&2) { //FatalError? -#ifdef AALOG2 - sprintf(str,"ReconnForbiddden: %s has FatalError; ProtoStatus: %d",proto[protoIndex]->szName,protoStatus[protoIndex]); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - if (reconnectOptsPerm[protoIndex]&aa_ReconnectNotFatalError) { -#ifdef AALOG2 - sprintf(str,"ReconnForbiddden: %s has DontReconnectOnFatalError",proto[protoIndex]->szName); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - return 4; //exit if "dontReconnectOnFatalError" enabled -#ifdef AALOG2 - } else { - sprintf(str,"ReconnForbiddden: %s has FatalError but DontReconnectOnFatalError disabled",proto[protoIndex]->szName); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - } - } //if FatalError - if (IsStatusBitSet(courAwayStatus[protoIndex],LOWORD(reconnectOptsPerm[protoIndex]))){ //is reconnect permited on this lastonline status? - //reconnecting... -#ifdef AALOG2 - sprintf(str,"ReconnForbiddden: %s Reconnect permitted",proto[protoIndex]->szName); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - return 0; // reconnect is permitted -#ifdef AALOG2 - } else { - sprintf(str,"ReconnForbiddden: %s Reconnecting to %s(%d) was not permited by %d", - proto[protoIndex]->szName, - CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courAwayStatus[protoIndex], 0), - courAwayStatus[protoIndex], - reconnectOptsPerm[protoIndex]); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - } - return 5; // forbidden because current status is disabled -} -#undef AALOG2 -void TimerProc() -{ -#ifdef AALOG - char str[256]; -#endif - int i; - for (i=0;iszName); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - if (protoStatus[i]&1) { -#ifdef AALOG1 - sprintf(str,"TimerProc: %s is Counting: AwayStatus: %s; reqStatus: %s;", - proto[i]->szName, - CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courAwayStatus[i], 0), - CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)reqStatus[i], 0) - ); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - if ((courAwayStatus[i]==ID_STATUS_OFFLINE)||(reqStatus[i]==ID_STATUS_OFFLINE)){ - protoStatus[i]&=2; //keeping fatalerror if any -#ifdef AALOG - sprintf(str,"TimerProc: %s Counting Cancelled: AwayStatus: %s; reqStatus: %s;", - proto[i]->szName, - CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courAwayStatus[i], 0), - CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)reqStatus[i], 0) - ); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - } - } - switch (IsReconnectForbidden(i)) { -#ifdef AALOG1 - case 1 : sprintf(str,"IsReconnectForbidden: %s is not counting or is not offline",proto[i]->szName); break; - case 2 : sprintf(str,"IsReconnectForbidden: %s it is too early to reconnect",proto[i]->szName); break; - case 3 : sprintf(str,"IsReconnectForbidden: %s has reconnect disabled",proto[i]->szName); break; - case 4 : sprintf(str,"IsReconnectForbidden: %s fatal error and DontReconnect enabled",proto[i]->szName); break; - case 5 : sprintf(str,"IsReconnectForbidden: %s current AAStatus should not be reconnected",proto[i]->szName); break; -#endif - case 0 : -#ifdef AALOG - sprintf(str,"IsReconnectForbidden: %s is permited to reconnect",proto[i]->szName); -#endif - CallProtoService(proto[i]->szName, PS_SETSTATUS, courAwayStatus[i], 0); - break; - default : -#ifdef AALOG - sprintf(str,"IsReconnectForbidden: %s Surprising answer",proto[i]->szName); -#endif - break; - } -#ifdef AALOG1 - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -#endif - }//protoType protocol - }//for -} -void moveScrollBarEvent(HWND hwndDlg){ - TCHAR str[256]; - int slide = SendDlgItemMessage(hwndDlg,IDC_RECONNECTSLIDER,TBM_GETPOS,0,0); - int delay = GetReconnectDelayFromSlider(slide); - ShowWindow(GetDlgItem(hwndDlg, IDC_RECONNECTWARNING),GetStringFromDelay(str, delay)?SW_SHOW:SW_HIDE); - SetDlgItemText(hwndDlg,IDC_ENABLERECONNECT,str); - reconnectOpts[courProtocolSelection] = SetBits(reconnectOpts[courProtocolSelection],aa_ReconnectBitsDelay,delay); -} - -LRESULT SetDlgItemsReconnect(HWND hwndDlg, int coursel){ - BOOL enabledReconnect = GetBits(reconnectOpts[coursel],aa_ReconnectBitsEnabled); - BOOL dontReconnectOnFatalError = GetBits(reconnectOpts[coursel],aa_ReconnectNotFatalError); - int i =0; - - for (i=0;i0; - EnableWindow(GetDlgItem(hwndDlg, aa_Status[i]+0x20), enabledReconnect); - StrikeOut(hwndDlg,aa_Status[i]+0x20,bita); - CheckDlgButton(hwndDlg, aa_Status[i]+0x20, bitr?BST_CHECKED:BST_UNCHECKED ); - } - SendDlgItemMessage(hwndDlg,IDC_RECONNECTSLIDER,TBM_SETPOS,TRUE,GetSliderFromReconnectDelay(GetBits(reconnectOpts[coursel],aa_ReconnectBitsDelay))); - moveScrollBarEvent(hwndDlg); - CheckDlgButton(hwndDlg, IDC_ENABLERECONNECT, enabledReconnect?BST_CHECKED:BST_UNCHECKED ); - CheckDlgButton(hwndDlg, IDC_NOTFATALERROR, dontReconnectOnFatalError?BST_CHECKED:BST_UNCHECKED ); - EnableWindow(GetDlgItem(hwndDlg, IDC_RECONNECTSLIDER), enabledReconnect); - EnableWindow(GetDlgItem(hwndDlg, IDC_NOTFATALERROR), enabledReconnect); - CheckDlgButton(hwndDlg, IDC_KEEPMAINSTATUSOFFLINE, (idleOpts&KeepMainStatusOffline)? BST_CHECKED : BST_UNCHECKED); - return TRUE; -} - - -BOOL CALLBACK DlgProcOptsReconnect(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - SetDlgItemsReconnect(hwndDlg, courProtocolSelection); - return TRUE; - case WM_USER+5: - { - int thebit = numStatuses-StatusToProtoIndex(LOWORD(lParam),allprotomodes); - int value = IsDlgButtonChecked(hwndDlg, LOWORD(lParam)+32)==BST_CHECKED; - thebit = 1<idFrom) { - case 0: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: { - return TRUE; - } - } - break; - } - break; - case WM_HSCROLL: - if((HWND)lParam == GetDlgItem(hwndDlg, IDC_RECONNECTSLIDER)) { - moveScrollBarEvent(hwndDlg); - if (LOWORD(wParam) == SB_ENDSCROLL) SendMessage(GetParent(hwndDlg), PSM_CHANGED, (unsigned int)hwndDlg, 0); - } - break; - case WM_DESTROY: - break; - } - return FALSE; -} diff --git a/!NotAdopted/SmartAutoAway/reconnect.ico b/!NotAdopted/SmartAutoAway/reconnect.ico deleted file mode 100644 index ee4092e593..0000000000 Binary files a/!NotAdopted/SmartAutoAway/reconnect.ico and /dev/null differ diff --git a/!NotAdopted/SmartAutoAway/resource.h b/!NotAdopted/SmartAutoAway/resource.h deleted file mode 100644 index 5473b9529e..0000000000 --- a/!NotAdopted/SmartAutoAway/resource.h +++ /dev/null @@ -1,77 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by saa-res.rc -// -#define IDR_MENUIDLE 101 -#define IDD_OPT_SAA_AA 301 -#define IDD_OPT_SAA_RECONNECT 302 -#define IDD_OPT_SAA_IDLE 303 -#define IDD_OPT_SAA_IDLEMESSAGES 304 -#define IDD_OPT_SMARTAUTOAWAY 202 -#define IDC_OPT_SAA_TAB 1000 -#define IDC_IDLEGROUP_HERE 1001 -#define IDC_IDLEGROUP_SHORT 1002 -#define IDC_IDLEGROUP_LONG 1003 -#define IDC_IDLEMSGHERE_THIS 1004 -#define IDC_IDLEMSGSHORT_THIS 1006 -#define IDC_IDLEMSGHERE 1007 -#define IDC_IDLEMSGSHORT 1008 -#define IDC_IDLEMSGLONG 1009 -#define IDC_IDLEMSGLONG_THIS 1011 -#define IDC_ENABLERESTOREMSG 1012 -#define IDC_RESTOREMSGSLIDER 1013 -#define IDC_PROTODONOTSUPPORT 1014 -#define IDC_VARIABLES 1015 -#define IDC_IDLEBUTTON 1500 -#define IDC_IDLECHECK 1636 -#define IDC_IDLEONWINDOWS 1637 -#define IDC_IDLEONMIRANDA 1638 -#define IDC_IDLEUSEGLI 1639 -#define IDC_DISBABLEAUTOHERE 1640 -#define IDC_SCREENSAVER 1642 -#define IDC_LOCKED 1643 -#define IDC_IDLESHORT 1644 -#define IDC_IDLELONG 1645 -#define IDC_IDLE1STTIME 1646 -#define IDC_IDLE2NDTIME 1647 -#define IDC_IDLEPRIVATE 1649 -#define IDC_AASTATUS 1650 -#define IDC_AASHORTIDLE 1651 -#define IDC_AALONGSTATUS 1652 -#define IDC_AAPROTOCOL 1653 -#define IDC_AALONGIDLE 1656 -#define IDC_COURSTATUSLABEL 1657 -#define IDC_REQSTATUSLABEL 1658 -#define IDC_ENABLERECONNECT 1660 -#define IDC_RECONNECTSLIDER 1663 -#define IDC_NOTFATALERROR 1664 -#define IDC_RECONNECTWARNING 1665 -#define IDC_APPLYTOALL 1667 -#define IDC_KEEPMAINSTATUSOFFLINE 1671 -#define IDC_DISABLEIDLEMENU 1672 -#define IDC_HEREONSTATUSCHANGE 1673 -#define IDI_IDLE_HERE 10101 -#define IDI_IDLE_SHORT 10102 -#define IDI_IDLE_LONG 10103 -#define IDI_RECONNECT 10104 -#define ID_STATUS_OFFLINE 40071 -#define ID_STATUS_ONLINE 40072 -#define ID_STATUS_AWAY 40073 -#define ID_STATUS_DND 40074 -#define ID_STATUS_NA 40075 -#define ID_STATUS_OCCUPIED 40076 -#define ID_STATUS_FREECHAT 40077 -#define ID_STATUS_INVISIBLE 40078 -#define ID_STATUS_ONTHEPHONE 40079 -#define ID_STATUS_OUTTOLUNCH 40080 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 10104 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1016 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/!NotAdopted/SmartAutoAway/saa-res.rc b/!NotAdopted/SmartAutoAway/saa-res.rc deleted file mode 100644 index 98549fa59b..0000000000 --- a/!NotAdopted/SmartAutoAway/saa-res.rc +++ /dev/null @@ -1,238 +0,0 @@ -//Microsoft Developer Studio generated resource script. -// - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "resource.h" -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Neutral resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) -#ifdef _WIN32 -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -#pragma code_page(1251) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_OPT_SMARTAUTOAWAY DIALOGEX 0, 0, 313, 247 -STYLE DS_FIXEDSYS | DS_CENTER | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CTEXT "Static",IDC_REQSTATUSLABEL,246,1,66,9,0,WS_EX_STATICEDGE - RTEXT "Requested Status:",IDC_STATIC,164,1,80,8 - CTEXT "Static",IDC_COURSTATUSLABEL,246,11,66,9,0,WS_EX_STATICEDGE - RTEXT "Current Status:",IDC_STATIC,181,12,63,8 - COMBOBOX IDC_AAPROTOCOL,8,1,65,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "",IDC_OPT_SAA_TAB,"SysTabControl32",0x0,20,23,273,216,0//WS_EX_ACCEPTFILES - PUSHBUTTON "Apply to all protocols",IDC_APPLYTOALL,76,1,81,12 -END - -IDD_OPT_SAA_AA DIALOGEX 0, 0, 256, 191 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "Short Idle",IDC_STATIC,0,0,256,93,BS_CENTER - CONTROL "Change my status mode to:",IDC_AASHORTIDLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,14,116,11 - COMBOBOX IDC_AASTATUS,132,13,75,12,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Only if my requested status is:",IDC_STATIC,0,32,256,61 - CONTROL "Online",ID_STATUS_ONLINE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,47,65,10 - CONTROL "Away",ID_STATUS_AWAY,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,60,65,10 - CONTROL "N/A",ID_STATUS_NA,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,72,65,10 - CONTROL "Invisible",ID_STATUS_INVISIBLE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,47,65,10 - CONTROL "Occupied",ID_STATUS_OCCUPIED,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,60,65,10 - CONTROL "DND",ID_STATUS_DND,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,72,65,13 - CONTROL "On the phone",ID_STATUS_ONTHEPHONE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,39,65,10 - CONTROL "Out to lunch",ID_STATUS_OUTTOLUNCH,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,52,65,10 - CONTROL "Free for chat",ID_STATUS_FREECHAT,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,66,65,10 - CONTROL "Offline",ID_STATUS_OFFLINE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,78,65,10 - GROUPBOX "Long Idle",IDC_STATIC,0,98,256,93,BS_CENTER - CONTROL "Change my status mode to:",IDC_AALONGIDLE,"Button",BS_AUTOCHECKBOX | BS_RIGHT | WS_TABSTOP,9,110,101,11 - COMBOBOX IDC_AALONGSTATUS,132,109,75,16,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Only if my requested status is:",IDC_STATIC,0,130,256,61 - CONTROL "Online",40088,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,145,65,10 - CONTROL "Away",40089,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,158,65,10 - CONTROL "N/A",40091,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,171,65,10 - CONTROL "Invisible",40094,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,145,65,10 - CONTROL "Occupied",40092,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,158,65,10 - CONTROL "DND",40090,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,172,65,10 - CONTROL "On the phone",40095,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,137,65,10 - CONTROL "Out to lunch",40096,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,150,65,10 - CONTROL "Free for chat",40093,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,163,65,10 - CONTROL "Offline",40087,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,176,65,10 -END - -IDD_OPT_SAA_RECONNECT DIALOGEX 0, 0, 256, 164 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "",IDC_STATIC,0,0,256,114,BS_CENTER - CONTROL "reconnect after",IDC_ENABLERECONNECT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,9,150,10 - CONTROL "Slider2",IDC_RECONNECTSLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,1,22,253,10 - GROUPBOX "If my current status is:",IDC_STATIC,0,37,256,52,BS_CENTER - RTEXT "Too Fast!",IDC_RECONNECTWARNING,160,10,91,8,NOT WS_VISIBLE - CONTROL "Online",40104,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,47,65,10 - CONTROL "Away",40105,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,60,65,10 - CONTROL "N/A",40107,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,74,65,10 - CONTROL "Invisible",40110,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,47,65,10 - CONTROL "Occupied",40108,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,60,65,10 - CONTROL "DND",40106,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,74,65,10 - CONTROL "On the phone",40111,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,47,65,10 - CONTROL "Out to lunch",40112,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,60,65,10 - CONTROL "Free for chat",40109,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,74,65,10 - CONTROL "Do not reconnect after fatal error",IDC_NOTFATALERROR,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,96,133,10 - GROUPBOX "",IDC_STATIC,0,126,254,38 - CONTROL "Keep main status offline*",IDC_KEEPMAINSTATUSOFFLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,138,133,10 - LTEXT "* Setting this option may confuse other plugins",IDC_STATIC,9,150,200,8 -END - -IDD_OPT_SAA_IDLE DIALOGEX 0, 0, 256, 196 -STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "Idle",IDC_STATIC,0,0,255,142,BS_CENTER - CONTROL "Enable",IDC_IDLECHECK,"Button",BS_AUTOCHECKBOX |WS_TABSTOP,8,12,43,11 - CONTROL "If Windows is inactive",IDC_IDLEONWINDOWS,"Button",BS_AUTORADIOBUTTON,62,13,110,9 - CONTROL "If Miranda is inactive",IDC_IDLEONMIRANDA,"Button",BS_AUTORADIOBUTTON,62,37,104,9 - CONTROL "Use GetLastInputInfo()",IDC_IDLEUSEGLI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,75,24,87,9 - GROUPBOX "Force short idle if:",IDC_STATIC,0,54,129,38 - CONTROL "Screen Saver is running",IDC_SCREENSAVER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,65,111,9 - CONTROL "Workstation is Locked (2K/XP)",IDC_LOCKED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,78,113,9 - GROUPBOX "Inactivity times:",IDC_STATIC,128,54,127,38 - CONTROL "Short idle after",IDC_IDLESHORT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,137,65,59,9 - EDITTEXT IDC_IDLE1STTIME,206,63,16,12,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "Long idle after",IDC_IDLELONG,"Button",BS_AUTOCHECKBOX |WS_TABSTOP,137,78,59,9 - EDITTEXT IDC_IDLE2NDTIME,206,76,16,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "min.",IDC_STATIC,223,65,24,9 - LTEXT "min.",IDC_STATIC,223,78,23,9 - CONTROL "Do not share my idle info.",IDC_IDLEPRIVATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,63,97,151,10 - CONTROL "Do not set ""Not Idle"" automaticaly",IDC_DISBABLEAUTOHERE,"Button",BS_AUTOCHECKBOX |WS_TABSTOP,63,111,158,10 - CONTROL "Set ""Not Idle"" on manual status change",IDC_HEREONSTATUSCHANGE,"Button",BS_AUTOCHECKBOX |WS_TABSTOP,63,125,158,10 - GROUPBOX "Simulate Idle",IDC_STATIC,0,146,255,50 - PUSHBUTTON "Be Not Idle",IDC_IDLEBUTTON,29,162,55,12 - PUSHBUTTON "Be Short Idle",IDC_IDLEBUTTON+1,95,162,55,12 - PUSHBUTTON "Be Long Idle",IDC_IDLEBUTTON+2,161,162,55,12 - CONTROL "Disable Idle menu. (restart is required)",IDC_DISABLEIDLEMENU,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,63,179,158,10 -END - -IDD_OPT_SAA_IDLEMESSAGES DIALOGEX 0, 0, 251, 166 -STYLE DS_FIXEDSYS | WS_CHILD | WS_VISIBLE -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "",IDC_IDLEGROUP_HERE,6,3,239,63 - CONTROL "Use:",IDC_IDLEMSGHERE_THIS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,14,31,10 - EDITTEXT IDC_IDLEMSGHERE,70,14,169,21,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL - CONTROL "",IDC_ENABLERESTOREMSG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,39,230,10 - CONTROL "Slider2",IDC_RESTOREMSGSLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,8,51,236,10 - GROUPBOX "",IDC_IDLEGROUP_SHORT,6,68,239,36 - CONTROL "Use:",IDC_IDLEMSGSHORT_THIS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,80,31,10 - EDITTEXT IDC_IDLEMSGSHORT,70,79,169,21,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL - GROUPBOX "",IDC_IDLEGROUP_LONG,6,108,239,36 - CONTROL "Use:",IDC_IDLEMSGLONG_THIS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,119,31,10 - EDITTEXT IDC_IDLEMSGLONG,70,119,169,21,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL - LTEXT "",IDC_PROTODONOTSUPPORT,12,148,204,18 - PUSHBUTTON "?",IDC_VARIABLES,223,149,22,14 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO MOVEABLE PURE -BEGIN - IDD_OPT_SMARTAUTOAWAY, DIALOG - BEGIN - BOTTOMMARGIN, 246 - END - - IDD_OPT_SAA_AA, DIALOG - BEGIN - VERTGUIDE, 9 - VERTGUIDE, 84 - VERTGUIDE, 169 - HORZGUIDE, 19 - HORZGUIDE, 32 - HORZGUIDE, 39 - HORZGUIDE, 52 - HORZGUIDE, 65 - HORZGUIDE, 78 - HORZGUIDE, 93 - HORZGUIDE, 98 - HORZGUIDE, 115 - HORZGUIDE, 130 - HORZGUIDE, 137 - HORZGUIDE, 150 - HORZGUIDE, 163 - HORZGUIDE, 176 - END - - IDD_OPT_SAA_RECONNECT, DIALOG - BEGIN - VERTGUIDE, 9 - VERTGUIDE, 84 - VERTGUIDE, 169 - HORZGUIDE, 14 - HORZGUIDE, 37 - HORZGUIDE, 52 - HORZGUIDE, 65 - HORZGUIDE, 79 - END - - IDD_OPT_SAA_IDLE, DIALOG - BEGIN - VERTGUIDE, 8 - HORZGUIDE, 17 - HORZGUIDE, 54 - HORZGUIDE, 67 - END - - IDD_OPT_SAA_IDLEMESSAGES, DIALOG - BEGIN - VERTGUIDE, 6 - VERTGUIDE, 12 - VERTGUIDE, 70 - VERTGUIDE, 245 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_IDLE_HERE ICON DISCARDABLE "here.ico" -IDI_IDLE_SHORT ICON DISCARDABLE "short.ico" -IDI_IDLE_LONG ICON DISCARDABLE "long.ico" -IDI_RECONNECT ICON DISCARDABLE "reconnect.ico" -#endif // Neutral resources -///////////////////////////////////////////////////////////////////////////// -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/!NotAdopted/SmartAutoAway/saa.cpp b/!NotAdopted/SmartAutoAway/saa.cpp deleted file mode 100644 index a36e5b5981..0000000000 --- a/!NotAdopted/SmartAutoAway/saa.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - -Miranda IM: the free IM client for Microsoft* Windows* - -Copyright 2000-2006 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "saa.h" - -int InitVariables( WPARAM wParam, LPARAM lParam ); - - -PLUGINLINK *pluginLink; -HINSTANCE g_hInst; - -PLUGININFOEX pluginInfo = { - sizeof(PLUGININFOEX), -#ifdef AALOG - SECTIONNAME " - Debug", -#else - SECTIONNAME, -#endif -#include "version.txt" - UNICODE_AWARE, - DEFMOD_RNDAUTOAWAY, // replace internal version (if any) -#if defined( _UNICODE ) - {0xec29e895,0x9f97,0x4cb1,{0xac, 0x9b, 0xb1, 0xae, 0x88, 0x25, 0x8b, 0x4a} /* EC29E895-9F97-4cb1-AC9B-B1AE88258B4A */} -#else - {0x19c5be89,0xf7e3,0x4632,{0xa1, 0x25, 0x15, 0xf3, 0x84, 0xcd, 0x0c, 0xd3} /* 19c5be89-f7e3-4632-a125-15f384cd0cd3 */} -#endif -}; - -static HMODULE hUxTheme = 0; -BOOL (WINAPI *enableThemeDialogTexture)(HANDLE, DWORD) = 0; - - -extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - g_hInst = hinstDLL; - return TRUE; -} -static char description[1023]; - -#ifdef AALOG - static BOOL warningShown = 0; -#endif -static bool isNewMiranda = false; -extern "C" __declspec(dllexport) PLUGININFOEX *MirandaPluginInfo(DWORD mirandaVersion) -{ - - sprintf(description,"Highly configurable AutoAway/Idle/Reconnect system"); -#ifdef AALOG - sprintf(description,"%s\r\nThis is the debug version. It will make a lot of noise through Netlib log",description); - if (!warningShown) { - MessageBoxA(0,description,pluginInfo.shortName,MB_ICONINFORMATION); - warningShown = 1; - } -#endif - if ((mirandaVersion>=0x00030400) && (!isNewMiranda)) { - sprintf(description,"%s\r\n%s",description,"Miranda %d.%d.%d.%d has build-in \"Idle\" support and it is highly advisable to suppress it by putting SAANI.dll in plugins directory."); - sprintf(description,description, // Yes, I realize this is strange approach... - mirandaVersion>>24&0xFF, - mirandaVersion>>16&0xFF, - mirandaVersion>>8&0xFF, - mirandaVersion&0xFF - ); - }; - sprintf(description,"%s\r\n[Build %s %s]",description, __DATE__,__TIME__); - pluginInfo.description = description; - if ( mirandaVersion < PLUGIN_MAKE_VERSION( 0,7,0,17 )) pluginInfo.cbSize = sizeof( PLUGININFO ); - return &pluginInfo; -} - -extern "C" __declspec(dllexport) PLUGININFOEX * MirandaPluginInfoEx(DWORD mirandaVersion) -{ - isNewMiranda=true; - return MirandaPluginInfo(mirandaVersion); -} - -extern "C" __declspec(dllexport) const MUUID interfaces[] = {MIID_AUTOAWAY, MIID_IDLE, MIID_LAST}; -extern "C" __declspec(dllexport) const MUUID * MirandaPluginInterfaces(void) -{ - return interfaces; -} - -extern "C" int __declspec(dllexport) Load(PLUGINLINK * link) -{ - pluginLink = link; - LoadAutoAwayModule(); - hUxTheme = GetModuleHandle(_T("uxtheme.dll")); - if(hUxTheme) - enableThemeDialogTexture = (BOOL (WINAPI *)(HANDLE, DWORD))GetProcAddress(hUxTheme, "EnableThemeDialogTexture"); - return 0; -} - -extern "C" int __declspec(dllexport) Unload(void) -{ -// AutoAwayShutdown(0,0); -//#ifdef AALOG -// CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"Killing Timer"); -//#endif -// KillTimer(NULL, hIdleTimer); -//#ifdef AALOG -// CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"DestroyHookableEvent(hIdleEvent)"); -//#endif -// DestroyHookableEvent(hIdleEvent); - - if(hUxTheme != 0) - FreeLibrary(hUxTheme); - - return 1; //if 1 we dont want to shutdown because we have hooked ME_SYSTEM_SHUTDOWN -} - - diff --git a/!NotAdopted/SmartAutoAway/saa.dsp b/!NotAdopted/SmartAutoAway/saa.dsp deleted file mode 100644 index 949d67f78f..0000000000 --- a/!NotAdopted/SmartAutoAway/saa.dsp +++ /dev/null @@ -1,291 +0,0 @@ -# Microsoft Developer Studio Project File - Name="saa" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=saa - Win32 Debug Unicode -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "saa.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "saa.mak" CFG="saa - Win32 Debug Unicode" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "saa - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "saa - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "saa - Win32 Logging" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "saa - Win32 Debug Unicode" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "saa - Win32 Release Unicode" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "saa - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "ReleasePlugin" -# PROP Intermediate_Dir "ReleasePlugin" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SAA_EXPORTS" /YX /FD /c -# ADD CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x402 /d "NDEBUG" -# ADD RSC /l 0x417 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /machine:I386 /out:"../../bin/release/plugins/saa.dll" /FILEALIGN:0x200 -# SUBTRACT LINK32 /pdb:none -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Cmds=upx --best --lzma --force ../../bin/release/plugins/saa.dll -# End Special Build Tool - -!ELSEIF "$(CFG)" == "saa - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "saa___Win32_Debug" -# PROP BASE Intermediate_Dir "saa___Win32_Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "DebugPlugin" -# PROP Intermediate_Dir "DebugPlugin" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SAA_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x402 /d "_DEBUG" -# ADD RSC /l 0x417 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /debug /machine:I386 /out:"../../Bin/debug/Plugins/saa.dll" /pdbtype:sept - -!ELSEIF "$(CFG)" == "saa - Win32 Logging" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "saa___Win32_Logging" -# PROP BASE Intermediate_Dir "saa___Win32_Logging" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Logging" -# PROP Intermediate_Dir "Logging" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O1 /D "SAA_PLUGIN" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O1 /I "../../include" /D "SAA_PLUGIN" /D "AALOG" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x402 /d "NDEBUG" -# ADD RSC /l 0x417 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /machine:I386 /out:"../../bin/release/plugins/saa.dll" -# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /machine:I386 /out:"../../bin/logging/plugins/saa.dll" -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Cmds=upx --best --lzma --force ../../bin/logging/plugins/saa.dll -# End Special Build Tool - -!ELSEIF "$(CFG)" == "saa - Win32 Debug Unicode" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "saa___Win32_Debug_Unicode" -# PROP BASE Intermediate_Dir "saa___Win32_Debug_Unicode" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug_Unicode" -# PROP Intermediate_Dir "Debug_Unicode" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "UNICODE" /D "_USRDLL" /FR /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x417 /d "_DEBUG" -# ADD RSC /l 0x417 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /debug /machine:I386 /out:"../../Bin/debug/Plugins/saa.dll" /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /debug /machine:I386 /out:"../../Bin/debug Unicode/Plugins/saa.dll" /pdbtype:sept - -!ELSEIF "$(CFG)" == "saa - Win32 Release Unicode" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "saa___Win32_Release_Unicode" -# PROP BASE Intermediate_Dir "saa___Win32_Release_Unicode" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release_Unicode" -# PROP Intermediate_Dir "Release_Unicode" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /c -# ADD CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "UNICODE" /D "_USRDLL" /FR /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x417 /d "NDEBUG" -# ADD RSC /l 0x417 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /machine:I386 /out:"../../bin/release/plugins/saa.dll" /FILEALIGN:0x200 -# SUBTRACT BASE LINK32 /pdb:none -# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /machine:I386 /out:"../../bin/Release Unicode/plugins/saa.dll" /FILEALIGN:0x200 -# SUBTRACT LINK32 /pdb:none -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Cmds=upx --best --force ../../bin/"Release Unicode"/plugins/saa.dll -# End Special Build Tool - -!ENDIF - -# Begin Target - -# Name "saa - Win32 Release" -# Name "saa - Win32 Debug" -# Name "saa - Win32 Logging" -# Name "saa - Win32 Debug Unicode" -# Name "saa - Win32 Release Unicode" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\aa_utils.cpp -# End Source File -# Begin Source File - -SOURCE=.\autoaway.cpp -# End Source File -# Begin Source File - -SOURCE=.\dlgproc.cpp -# End Source File -# Begin Source File - -SOURCE=.\globals.cpp -# End Source File -# Begin Source File - -SOURCE=.\idle.cpp - -!IF "$(CFG)" == "saa - Win32 Release" - -!ELSEIF "$(CFG)" == "saa - Win32 Debug" - -# SUBTRACT CPP /YX - -!ELSEIF "$(CFG)" == "saa - Win32 Logging" - -!ELSEIF "$(CFG)" == "saa - Win32 Debug Unicode" - -# SUBTRACT BASE CPP /YX -# SUBTRACT CPP /YX - -!ELSEIF "$(CFG)" == "saa - Win32 Release Unicode" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\idleMenu.cpp -# End Source File -# Begin Source File - -SOURCE=.\idleMessages.cpp -# End Source File -# Begin Source File - -SOURCE=.\reconnect.cpp -# End Source File -# Begin Source File - -SOURCE=.\saa.cpp -# End Source File -# Begin Source File - -SOURCE=.\saamain.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\globals.h -# End Source File -# Begin Source File - -SOURCE=.\resource.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# Begin Source File - -SOURCE=.\here.ico -# End Source File -# Begin Source File - -SOURCE=.\long.ico -# End Source File -# Begin Source File - -SOURCE=.\reconnect.ico -# End Source File -# Begin Source File - -SOURCE=".\saa-res.rc" -# End Source File -# Begin Source File - -SOURCE=.\short.ico -# End Source File -# End Group -# End Target -# End Project diff --git a/!NotAdopted/SmartAutoAway/saa.dsw b/!NotAdopted/SmartAutoAway/saa.dsw deleted file mode 100644 index d39bc38701..0000000000 --- a/!NotAdopted/SmartAutoAway/saa.dsw +++ /dev/null @@ -1,41 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "saa"=".\saa.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "saani"=".\saani.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/!NotAdopted/SmartAutoAway/saa.h b/!NotAdopted/SmartAutoAway/saa.h deleted file mode 100644 index b59f155202..0000000000 --- a/!NotAdopted/SmartAutoAway/saa.h +++ /dev/null @@ -1 +0,0 @@ -#include "globals.h" diff --git a/!NotAdopted/SmartAutoAway/saamain.cpp b/!NotAdopted/SmartAutoAway/saamain.cpp deleted file mode 100644 index 0dee323c28..0000000000 --- a/!NotAdopted/SmartAutoAway/saamain.cpp +++ /dev/null @@ -1,415 +0,0 @@ -/* - -Miranda IM: the free IM client for Microsoft* Windows* - -Copyright 2000-2006 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -#include "globals.h" - -#ifdef SAA_PLUGIN - struct MM_INTERFACE memoryManagerInterface; -#endif - -HANDLE hService[5]; -HANDLE hHooks[6]; - -#ifndef SAA_PLUGIN - int LoadIdleModule(void){return 0;} - int UnloadIdleModule(void){return 0;} -#endif - -int LoadAutoAwayModule(void) -{ - -#ifdef SAA_PLUGIN - memset(&memoryManagerInterface, 0, sizeof(memoryManagerInterface)); - memoryManagerInterface.cbSize = sizeof(memoryManagerInterface); - CallService(MS_SYSTEM_GET_MMI, 0, (LPARAM) &memoryManagerInterface); -#endif - - hHooks[0] = HookEvent(ME_SYSTEM_MODULESLOADED,InitVariables); - hIdleEvent = CreateHookableEvent(ME_IDLE_CHANGED); - hHooks[1] = HookEvent(ME_OPT_INITIALISE,AutoAwayOptInitialise); - MyGetLastInputInfo=(BOOL (WINAPI *)(PLASTINPUTINFO)) GetProcAddress( GetModuleHandleA("user32"),"GetLastInputInfo" ); - // load settings into live ones - idleOpts = idleOptsPerm=DBGetContactSettingDword(NULL, AA_MODULE,AA_IDLEOPTIONS,idleOptsDefault); -// if ((idleOptsPerm&IdleSuppressIdleMenu)==0) AddIdleMenu(); -// idleCheckPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLECHECK, 0); -// idleMethodPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLEMETHOD, 0); -// idleGLIPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLEGLI, 1); -// idleTimeFirstPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLETIME1ST, 10); -// idleTimeSecondPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLETIME2ND, 30); -// idleTimeFirstOnPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLETIME1STON, 0); -// idleTimeSecondOnPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLETIME2NDON, 0); -// idleOnSaverPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLEONSAVER, 0); -// idleOnLockPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLEONLOCK, 0); -// idlePrivatePerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLEPRIVATE, 0); - hService[0] = CreateServiceFunction(MS_IDLE_GETIDLEINFO, IdleGetInfo); - - hHooks[2] = HookEvent(ME_SYSTEM_SHUTDOWN,AutoAwayShutdown); - hHooks[3] = HookEvent(ME_IDLE_CHANGED, AutoAwayEvent); - hHooks[4] = HookEvent(ME_CLIST_STATUSMODECHANGE,StatusModeChangeEvent); - hHooks[5] = HookEvent(ME_PROTO_ACK, ProtoAckEvent); - - hService[1] = CreateServiceFunction(AA_IDLE_BENOTIDLESERVICE,(MIRANDASERVICE)idleServiceNotIdle); - hService[2] = CreateServiceFunction(AA_IDLE_BESHORTIDLESERVICE,(MIRANDASERVICE)idleServiceShortIdle); - hService[3] = CreateServiceFunction(AA_IDLE_BELONGIDLESERVICE,(MIRANDASERVICE)idleServiceLongIdle); - hService[4] = CreateServiceFunction(AA_IDLE_RECONNECTSERVICE,(MIRANDASERVICE)reconnectService); - return 0; -} - -int InitVariables( WPARAM wParam, LPARAM lParam ) -{ - int j=0; - int i=0; - localeID = CallService(MS_LANGPACK_GETLOCALE,0,0); - if (localeID==CALLSERVICE_NOTFOUND) localeID=LOCALE_USER_DEFAULT; - codePage = CallService(MS_LANGPACK_GETCODEPAGE,0,0); - if (codePage==CALLSERVICE_NOTFOUND) codePage=CP_ACP; -#ifdef UNICODE - HasAwayMessageW = (ServiceExists(MS_AWAYMSG_GETSTATUSMSGW)!=0); -#endif - if (ServiceExists(MS_HOTKEY_REGISTER)){ - for (i=0;i<4;i++) { - CallService(MS_HOTKEY_REGISTER, 0, (LPARAM) &hotkeydescs[i]); - } - } - - -#ifdef AALOG - { - NETLIBUSER nlu = { 0 }; - nlu.cbSize = sizeof(nlu); - nlu.szSettingsModule = "SAA"; - nlu.flags=NUF_NOOPTIONS | NUF_NOHTTPSOPTION; - nlu.szDescriptiveName = Translate(SECTIONNAME " Module"); - hNetlib = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) & nlu); - } - { - SYSTEMTIME st={0}; - int drift; - char str[32]; - char log[1024]; - char target[1024]; - drift = GetTimeZone(str); - GetLastActiveLocalTime(&st,0); - sprintf(log,"Now is %02d/%02d/%02d %02d:%02d:%02d %s (%02d:%02d)", - st.wYear, st.wMonth, st.wDay, - st.wHour, st.wMinute, st.wSecond,str, - div(drift,60).quot,drift<0?-div(drift,60).rem:div(drift,60).rem); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); - GetLastActiveLocalTime(&st,24*60*60*1000); - sprintf(log,"1 day ago was %02d/%02d/%02d %02d:%02d:%02d %s (%02d:%02d)", - st.wYear, st.wMonth, st.wDay, - st.wHour, st.wMinute, st.wSecond,str, - div(drift,60).quot,drift<0?-div(drift,60).rem:div(drift,60).rem); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); - ParseString("%Y-%m-%d %H:%M:%S",target,1023); - sprintf(log,"Testing ParseString: %s",target); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); - ParseString("%E/%d/%y %W %h:%M:%S %p",target,1023); - sprintf(log,"Testing ParseString: %s",target); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); - ParseString("%w %% %Z (%z)%n%L%b%l%b%K%b%k",target,1023); - sprintf(log,"Testing ParseString: %s",target); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); - } -#endif - - CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM)&protoCount,(LPARAM)&proto); - reqStatus = (int *)mir_alloc((protoCount)*sizeof(reqStatus[0])); - courStatus = (int *)mir_alloc((protoCount)*sizeof(courStatus[0])); - courAwayStatus = (int *)mir_alloc((protoCount)*sizeof(courStatus[0])); - protoModes = (int *)mir_alloc((protoCount)*sizeof(protoModes[0])); - messCaps = (int *)mir_alloc((protoCount)*sizeof(messCaps[0])); - - awayStatuses=(short int *)mir_alloc((protoCount)*sizeof(awayStatuses[0])); - onlyIfBits=(long int *)mir_alloc((protoCount)*sizeof(onlyIfBits[0])); - awayStatusesPerm=(short int *)mir_alloc((protoCount)*sizeof(awayStatuses[0])); - onlyIfBitsPerm=(long int *)mir_alloc((protoCount)*sizeof(onlyIfBits[0])); - - reconnectOpts=(long int *)mir_alloc((protoCount)*sizeof(reconnectOpts[0])); - reconnectOptsPerm=(long int *)mir_alloc((protoCount)*sizeof(reconnectOptsPerm[0])); - protoOfflineTimes=(unsigned int *)mir_alloc((protoCount)*sizeof(protoOfflineTimes[0])); - protoStatus=(int *)mir_alloc((protoCount)*sizeof(protoStatus[0])); - - idleMessOpts=(long int *)mir_alloc((protoCount)*sizeof(idleMessOpts[0])); - idleMessOptsPerm=(long int *)mir_alloc((protoCount)*sizeof(idleMessOptsPerm[0])); - - mesgHere = (TCHAR**)mir_alloc(protoCount * sizeof(mesgHere[0])); - mesgHerePerm = (TCHAR**)mir_alloc(protoCount * sizeof(mesgHerePerm[0])); - mesgShort = (TCHAR**)mir_alloc(protoCount * sizeof(mesgShort[0])); - mesgShortPerm = (TCHAR**)mir_alloc(protoCount * sizeof(mesgShortPerm[0])); - mesgLong = (TCHAR**)mir_alloc(protoCount * sizeof(mesgLong[0])); - mesgLongPerm = (TCHAR**)mir_alloc(protoCount * sizeof(mesgLongPerm[0])); - - #ifdef UNICODE - protoHasAwayMessageW=(bool *)mir_alloc(protoCount * sizeof(protoHasAwayMessageW[0])); - #endif - - isWaitingForRestoreStatusMessage = (int *)mir_alloc((protoCount)*sizeof(isWaitingForRestoreStatusMessage[0])); - - for (j = 0 ; j < protoCount ; j++) { - int caps=0; -#ifdef AALOG - { - char log[1024]; - sprintf(log,"Checking protocol index %d out of %d...",j+1,protoCount); - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); - } -#endif - reqStatus[j] = 0; - courStatus[j] = ID_STATUS_OFFLINE; - protoModes[j] =0; - isWaitingForRestoreStatusMessage[j] = 0; - caps = CallProtoService(proto[j]->szName, PS_GETCAPS, PFLAGNUM_2, 0); - messCaps[j] = (CallProtoService(proto[j]->szName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)? - CallProtoService(proto[j]->szName, PS_GETCAPS, PFLAGNUM_3, 0):0; -#ifdef AALOG - { - char log[1024]; - if (messCaps[j]){ - int i; - sprintf(log,"StatusMessages Caps for %s:", - proto[j]->szName - ); - for (i=0;i<10;i++){ - int statusFlag = Proto_Status2Flag(aa_Status[i]); - if (statusFlag & messCaps[j]){ - sprintf(log,"%s %s",log,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, aa_Status[i], 0)); - } - } - } else { - sprintf(log,"%s cannot set StatusMessage", - proto[j]->szName); - } - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); - } -#endif - for (i = 0; iszName); -// MessageBox( 0,str,proto[j]->szName,0); - onlyIfBits[j]= DBGetContactSettingDword(NULL,AA_MODULE,str,-1); - if (onlyIfBits[j]==-1){ -// onlyIfBits[j] = (((protoModes[j]<<16)|(protoModes[j])) & aa_OnlyIfBitsDefault); - onlyIfBits[j] = aa_OnlyIfBitsDefault; - DBWriteContactSettingDword(NULL,AA_MODULE,str,onlyIfBits[j]); - } - onlyIfBitsPerm[j]=onlyIfBits[j]; -#ifdef UNICODE - sprintf(str,"%s%s",proto[j]->szName,PS_SETAWAYMSGW); - protoHasAwayMessageW[j]=(ServiceExists(str)!=0); -#endif -// sprintf(str,AA_BITSLONGONLYIF,proto[j]->szName); -//// MessageBox( 0,str,proto[j]->szName,0); -// if (!DBGetContactSettingWord(NULL,AA_MODULE,str,0)) -// DBWriteContactSettingWord(NULL,AA_MODULE,str,(protoModes[j] & aa_OnlyIfBitsDefault)|known); - sprintf(str,AA_AWAYSTATUSES,proto[j]->szName); -// MessageBox( 0,str,proto[j]->szName,0); - awayStatuses[j] = DBGetContactSettingWord(NULL,AA_MODULE,str,-1); - if (awayStatuses[j] ==-1){ - int old = DBGetContactSettingWord(NULL,AA_OLDMODULE,AA_SHORTSTATUS,-1); - int s = StatusToProtoIndex(((old==-1)?ID_STATUS_AWAY:OldIndexToStatus(old)),protoModes[j]); - int l = 0; - int comb = 0; - old = DBGetContactSettingWord(NULL,AA_OLDMODULE,AA_LONGSTATUS,-1); - l = StatusToProtoIndex(((old==-1)?ID_STATUS_NA:OldIndexToStatus(old)),protoModes[j]); - comb = (l<<4)|s; - old = DBGetContactSettingByte(NULL,AA_OLDMODULE,AA_USESHORT,-1); - if (s) comb |= ((old==-1)?1<<8:(old==1)<<8); - old = DBGetContactSettingByte(NULL,AA_OLDMODULE,AA_USELONG,-1); - if (l) comb |= ((old==-1)?1<<9:(old==1)<<9); -// comb |= (1<<15); - awayStatuses[j]=comb; - DBWriteContactSettingWord(NULL,AA_MODULE,str,(WORD)awayStatuses[j]); - } - awayStatusesPerm[j] = awayStatuses[j]; - - sprintf(str,AA_LASTREQUESTEDSTATUS,proto[j]->szName); //get last requested status - reqStatus[j] = DBGetContactSettingWord(NULL,AA_MODULE,str,ID_STATUS_ONLINE); //default: online - - sprintf(str,AA_RECONNECTOPTS,proto[j]->szName); //get reconnect options status - reconnectOpts[j] = DBGetContactSettingDword(NULL,AA_MODULE,str,aa_ReconnectOptsDefault); - reconnectOptsPerm[j] = reconnectOpts[j]; - protoStatus[j] = 0; - protoOfflineTimes[j] = 0; - mesgHere[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1)); - mesgHerePerm[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1)); - mesgShort[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1)); - mesgShortPerm[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1)); - mesgLong[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1)); - mesgLongPerm[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1)); - - if (messCaps[j]){ - DBVARIANT dbv; - sprintf(str,idleMsgOptionsName,proto[j]->szName); - idleMessOptsPerm[j] = idleMessOpts[j] = DBGetContactSettingDword(NULL,AA_MODULE,str,idleMsgOptionsDefault); - - sprintf(str,idleMsgOptionsTextHere,proto[j]->szName); - if(DBGetContactSettingTString(NULL,AA_MODULE,str,&dbv)==0) { - _tcsncpy(mesgHere[j],dbv.ptszVal,maxMessageLength); - mesgHere[j][maxMessageLength]=0; - DBFreeVariant(&dbv); - } else _tcscpy(mesgHere[j],messHereDefault); - if(!_tcscmp(mesgHere[j],messHereDefaultOld)) _tcscpy(mesgHere[j],messHereDefault); - _tcscpy(mesgHerePerm[j],mesgHere[j]); - - sprintf(str,idleMsgOptionsTextShort,proto[j]->szName); - if(DBGetContactSettingTString(NULL,AA_MODULE,str,&dbv)==0) { - _tcsncpy(mesgShort[j],dbv.ptszVal,maxMessageLength); - mesgShort[j][maxMessageLength]=0; - DBFreeVariant(&dbv); - } else _tcscpy(mesgShort[j],messShortDefault); - if(!_tcscmp(mesgShort[j],messShortDefaultOld)) _tcscpy(mesgShort[j],messShortDefault); - _tcscpy(mesgShortPerm[j],mesgShort[j]); - - sprintf(str,idleMsgOptionsTextLong,proto[j]->szName); - if(DBGetContactSettingTString(NULL,AA_MODULE,str,&dbv)==0) { - _tcsncpy(mesgLong[j],dbv.ptszVal,maxMessageLength); - mesgLong[j][maxMessageLength]=0; - DBFreeVariant(&dbv); - } else _tcscpy(mesgLong[j],messLongDefault); - if(!_tcscmp(mesgLong[j],messLongDefaultOld)) _tcsncpy(mesgLong[j],messLongDefault,maxMessageLength); - _tcsncpy(mesgLongPerm[j],mesgLong[j],maxMessageLength); -// sprintf(mesgHere[j],"%d: %s: %s",j,proto[j]->szName,"Test text"); - } else { - idleMessOptsPerm[j] = idleMessOpts[j] = 0; - mesgHerePerm[j] = mesgHere[j] = mesgShortPerm[j] = mesgShort[j] = mesgLongPerm[j] = mesgLong[j] = NULL; - } - } - } -#ifdef AALOG - { - char str[1024]=""; - for (j = 0 ; j < protoCount ; j++) { - int status; - sprintf(str,"%s\n%s Type:%d\nLastReqStatus: %s\n",str,proto[j]->szName,proto[j]->type,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)reqStatus[j], 0)); - i=1; - while(status=StatusByProtoIndex(protoModes[j],i)){ - sprintf(str,"%s %d. %s\n",str,i,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)status, 0)); - i++; - } -// IsStatusBitSet(aa_Status[i],protoModes[j])?"":"not", -// CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)aa_Status[i], 0), -// IsStatusBitSet(aa_Status[i],aa_OnlyIfBitsDefault)?"n":"ff" -// ); - - } - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); - } -#endif -//something is hapaning here on startup, if main status is not offline -//will move Notify hIdleEvent for later in the IdleTimer -// NotifyEventHooks( hIdleEvent, 0, idleOpts&IdleBitsPrivate?IDF_PRIVACY:0 ); //Tell everyone we are here - FirstTick = 1; //we will wait 1 ticks of the timer before Forcing Awake -// FirstTick = 10; //we will wait 20 seconds before Forcing Awake - hIdleTimer=SetTimer(NULL, 0, 2000, IdleTimer); -// { -// char str[20000]=""; -// for (i=0;i<=101;i++){ -// char str1[128]; -// GetStringFromDelay(str1,GetReconnectDelayFromSlider(i)); -// sprintf(str,"%d\t%d\t%s",GetReconnectDelayFromSlider(i),i,str1); -// CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); -// } -// } - if ((idleOptsPerm&IdleSuppressIdleMenu)==0) AddIdleMenu(); - if ((idleOptsPerm&IdleSuppressAutoHere)!=0) isCurrentlyIdle=DBGetContactSettingByte(NULL,AA_MODULE,AA_LASTIDLESTATUS,0);; - return 0; -} - -//#ifndef SAA_PLUGIN -int AutoAwayShutdown(WPARAM wParam,LPARAM lParam) -{ - int i; - -#ifdef AALOG - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"Killing Timer"); -#endif - KillTimer(NULL, hIdleTimer); - if (hHookIconsChanged){ - #ifdef AALOG - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"UnHooking hHookIconsChanged"); - #endif - UnhookEvent(hHookIconsChanged); - } -#ifdef AALOG - CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"DestroyHookableEvent(hIdleEvent)"); -#endif - for (i=0; i -#include - -PLUGININFOEX pluginInfo = { - sizeof(PLUGININFO), - "Smart Auto Away NI", -#include "version.txt" - 0, - DEFMOD_RNDIDLE, // replace internal version (if any) - { 0x91bb7ad7,0x7ed8,0x40b9,{0xb1, 0x50, 0x3f, 0x37, 0x6b, 0x6b, 0x67, 0xfe}/* 91bb7ad7-7ed8-40b9-b150-3f376b6b67fe */} -}; - - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - return TRUE; -} -static char description[1023]; -sprintf(char *, const char *, ...); -__declspec(dllexport) PLUGININFOEX *MirandaPluginInfo(DWORD mirandaVersion) -{ - sprintf(description,"%s","Just to suppress the build-in \"Idle\" module"); - if (mirandaVersion<0x00030400) { - sprintf(description,"%s\r\n%s",description,"Miranda %d.%d.%d.%d has no build-in \"Idle\" support and this plugin is useless"); - sprintf(description,description, // Yes, I realize this is strange approach... - mirandaVersion>>24&0xFF, - mirandaVersion>>16&0xFF, - mirandaVersion>>8&0xFF, - mirandaVersion&0xFF - ); - } - sprintf(description,"%s\r\n[Build %s %s]",description, __DATE__,__TIME__); - pluginInfo.description = description; - return &pluginInfo; -} -__declspec(dllexport) PLUGININFOEX * MirandaPluginInfoEx(DWORD mirandaVersion) -{ - //return 0; - pluginInfo.cbSize = sizeof( PLUGININFOEX ); - return MirandaPluginInfo(mirandaVersion); -} - -extern "C" __declspec(dllexport) const MUUID interfaces[] = {MIID_IDLE, MIID_LAST}; -__declspec(dllexport) const MUUID * MirandaPluginInterfaces(void) -{ - return interfaces; -} - -int __declspec(dllexport) Load(PLUGINLINK * link) -{ - return 0; -} - -int __declspec(dllexport) Unload(void) -{ -// AutoAwayShutdown(0,0); - return 0; //if 1 we dont want to shutdown because we have hooked ME_SYSTEM_SHUTDOWN -} - diff --git a/!NotAdopted/SmartAutoAway/saani.dsp b/!NotAdopted/SmartAutoAway/saani.dsp deleted file mode 100644 index f36ee7738f..0000000000 --- a/!NotAdopted/SmartAutoAway/saani.dsp +++ /dev/null @@ -1,107 +0,0 @@ -# Microsoft Developer Studio Project File - Name="saani" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=saani - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "saani.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "saani.mak" CFG="saani - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "saani - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "saani - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "saani - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ReleasePlugin" -# PROP BASE Intermediate_Dir "ReleasePlugin" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "ReleasePlugin" -# PROP Intermediate_Dir "ReleasePlugin" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SAANI_EXPORTS" /YX /FD /c -# ADD CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AALOG" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x402 /d "NDEBUG" -# ADD RSC /l 0x402 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"../../bin/release/plugins/saani.dll" - -!ELSEIF "$(CFG)" == "saani - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "DebugPlugin" -# PROP BASE Intermediate_Dir "DebugPlugin" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "DebugPlugin" -# PROP Intermediate_Dir "DebugPlugin" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SAANI_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "SAANI_EXPORTS" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x402 /d "_DEBUG" -# ADD RSC /l 0x402 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"../../Bin/debug/Plugins/saani.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "saani - Win32 Release" -# Name "saani - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\saani.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/!NotAdopted/SmartAutoAway/short.ico b/!NotAdopted/SmartAutoAway/short.ico deleted file mode 100644 index 32817713fa..0000000000 Binary files a/!NotAdopted/SmartAutoAway/short.ico and /dev/null differ diff --git a/!NotAdopted/SmartAutoAway/version.txt b/!NotAdopted/SmartAutoAway/version.txt deleted file mode 100644 index ddbd1c8713..0000000000 --- a/!NotAdopted/SmartAutoAway/version.txt +++ /dev/null @@ -1,7 +0,0 @@ - PLUGIN_MAKE_VERSION(0, 0, 3, 3), - "", - "YB", - "y_b" /* these */ "@" /* fucking spammers */ "saaplugin.no-ip.info" /* gather everything */, - "© 2005-2009 YB; 2000-2006 Miranda-IM", - "http://saaplugin.no-ip.info/", - diff --git a/!NotAdopted/SmartAutoReplier/ActionsHandler.cpp b/!NotAdopted/SmartAutoReplier/ActionsHandler.cpp deleted file mode 100644 index 53bf7d2aea..0000000000 --- a/!NotAdopted/SmartAutoReplier/ActionsHandler.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" -#include "actionshandler.h" - -CActionsHandler::CActionsHandler(void) -{ -} - -CActionsHandler::~CActionsHandler(void) -{ -} diff --git a/!NotAdopted/SmartAutoReplier/ActionsHandler.h b/!NotAdopted/SmartAutoReplier/ActionsHandler.h deleted file mode 100644 index cb2e996111..0000000000 --- a/!NotAdopted/SmartAutoReplier/ActionsHandler.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -/// manager that executes actions... -class CActionsHandler -{ -public: - CActionsHandler(void); - ~CActionsHandler(void); -}; diff --git a/!NotAdopted/SmartAutoReplier/AggressiveOptimize.h b/!NotAdopted/SmartAutoReplier/AggressiveOptimize.h deleted file mode 100644 index 076d96d920..0000000000 --- a/!NotAdopted/SmartAutoReplier/AggressiveOptimize.h +++ /dev/null @@ -1,59 +0,0 @@ - -////////////////////////////// -// Version 1.10 -// Jan 23rd, 2000 -// Version 1.00 -// May 20th, 1999 -// Todd C. Wilson, Fresh Ground Software -// (todd@nopcode.com) -// This header file will kick in settings for Visual C++ 5 and 6 that will (usually) -// result in smaller exe's. -// The "trick" is to tell the compiler to not pad out the function calls; this is done -// by not using the /O1 or /O2 option - if you do, you implicitly use /Gy, which pads -// out each and every function call. In one single 500k dll, I managed to cut out 120k -// by this alone! -// The other two "tricks" are telling the Linker to merge all data-type segments together -// in the exe file. The relocation, read-only (constants) data, and code section (.text) -// sections can almost always be merged. Each section merged can save 4k in exe space, -// since each section is padded out to 4k chunks. This is very noticable with smaller -// exes, since you could have only 700 bytes of data, 300 bytes of code, 94 bytes of -// strings - padded out, this could be 12k of runtime, for 1094 bytes of stuff! -// Note that if you're using MFC static or some other 3rd party libs, you may get poor -// results with merging the readonly (.rdata) section - the exe may grow larger. -// To use this feature, define _MERGE_DATA_ in your project or before this header is used. -// With Visual C++ 5, the program uses a file alignement of 512 bytes, which results -// in a small exe. Under VC6, the program instead uses 4k, which is the same as the -// section size. The reason (from what I understand) is that 4k is the chunk size of -// the virtual memory manager, and that WinAlign (an end-user tuning tool for Win98) -// will re-align the programs on this boundary. The problem with this is that all of -// Microsoft's system exes and dlls are not tuned like this, and using 4k causes serious -// exe bloat. Very noticable for smaller programs. -// The "trick" for this is to use the undocumented FILEALIGN linker parm to change the -// padding from 4k to 1/2k, which results in a much smaller exe - anywhere from 20%-75% -// depending on the size. - - -#ifdef NDEBUG -#pragma message( "Using AggressiveOptimise" ) -// /Og (global optimizations), /Os (favor small code), /Oy (no frame pointers) -#pragma optimize("gsy",on) - -#pragma comment(linker,"/RELEASE") - -// Note that merging the .rdata section will result in LARGER exe's if you using -// MFC (esp. static link). If this is desirable, define _MERGE_RDATA_ in your project. -#ifdef _MERGE_RDATA_ -#pragma comment(linker,"/merge:.rdata=.data") -#endif // _MERGE_RDATA_ - -#pragma comment(linker,"/merge:.text=.data") -//#pragma comment(linker,"/merge:.reloc=.data") - -#if _MSC_VER >= 1000 -// Only supported/needed with VC6; VC5 already does 0x200 for release builds. -// Totally undocumented! And if you set it lower than 512 bytes, the program crashes. -// Either leave at 0x200 or 0x1000 -#pragma comment(linker,"/FILEALIGN:0x200") -#endif // _MSC_VER >= 1000 - -#endif // NDEBUG diff --git a/!NotAdopted/SmartAutoReplier/Crc32Static.cpp b/!NotAdopted/SmartAutoReplier/Crc32Static.cpp deleted file mode 100644 index 89646ec0bb..0000000000 --- a/!NotAdopted/SmartAutoReplier/Crc32Static.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" -#include "Crc32Static.h" - -// Static CRC table -DWORD CCrc32Static::s_arrdwCrc32Table[256] = -{ - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, - 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, - 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, - 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, - 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, - 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, - 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, - 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, - 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, - 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, -}; - -/// ctor -CCrc32Static::CCrc32Static() -{ -} - -/// dtor -CCrc32Static::~CCrc32Static() -{ -} - -/// calculating crc32 -inline void CCrc32Static::CalcCrc32(const BYTE byte, DWORD &dwCrc32) -{ - dwCrc32 = ((dwCrc32) >> 8) ^ s_arrdwCrc32Table[(byte) ^ ((dwCrc32) & 0x000000FF)]; -} - -/// getting crc32 for a string -DWORD CCrc32Static::StringCrc32(LPCTSTR szString, DWORD &dwCrc32) -{ - _ASSERTE(szString); - - DWORD dwErrorCode = NO_ERROR; - - dwCrc32 = 0xFFFFFFFF; - - try - { - while(*szString != _T('\0')) - { - CalcCrc32((BYTE)*szString, dwCrc32); - szString++; - } - } - catch(...) - { - // An unknown exception happened - dwErrorCode = ERROR_CRC; - } - - dwCrc32 = ~dwCrc32; - - return dwErrorCode; -} diff --git a/!NotAdopted/SmartAutoReplier/Crc32Static.h b/!NotAdopted/SmartAutoReplier/Crc32Static.h deleted file mode 100644 index 4039822cae..0000000000 --- a/!NotAdopted/SmartAutoReplier/Crc32Static.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -class CCrc32Static -{ -public: - CCrc32Static(); - virtual ~CCrc32Static(); - static DWORD StringCrc32(LPCTSTR szString, DWORD &dwCrc32); -protected: - static inline void CalcCrc32(const BYTE byte, DWORD &dwCrc32); - static DWORD s_arrdwCrc32Table[256]; -}; diff --git a/!NotAdopted/SmartAutoReplier/CrushLog.cpp b/!NotAdopted/SmartAutoReplier/CrushLog.cpp deleted file mode 100644 index 639e4965ff..0000000000 --- a/!NotAdopted/SmartAutoReplier/CrushLog.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" -#include "crushlog.h" -#include "shlobj.h" - -extern HINSTANCE hInst; -extern CCrushLog CRUSHLOGOBJ; - -/// init static members -TCHAR CCrushLog::m_szLogPath[MAX_PATH] = {0}; -CRITICAL_SECTION CCrushLog::m_critSect; - -/// ctor -CCrushLog::CCrushLog(void) -{/// nothing for now -BEGIN_PROTECT_AND_LOG_CODE -END_PROTECT_AND_LOG_CODE -} - -/// d'ctor -CCrushLog::~CCrushLog(void) -{ -BEGIN_PROTECT_AND_LOG_CODE -END_PROTECT_AND_LOG_CODE -} - -/// deinit internal data... -void CCrushLog::DeInit(void) -{ - DeleteCriticalSection(&m_critSect); -} - -/// init internal data... -void CCrushLog::Init(void) -{ - HRESULT hr = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, m_szLogPath); - size_t nLen = _tcslen(m_szLogPath); - - if (m_szLogPath[nLen - 1] != TEXT('\\')) - { - _tcscat(m_szLogPath, TEXT("\\Sar\\")); - } - else - { - _tcscat(m_szLogPath, TEXT("Sar\\")); - } - - CreateDirectory(m_szLogPath, NULL); - - _tcscat(m_szLogPath, LOG_FILENAME); - - /*if (_tcslen(m_szLogPath) == 0) /// let's get path to log file - { - GetModuleFileName(hInst, m_szLogPath, sizeof(m_szLogPath) * sizeof(TCHAR)); - - TCHAR *ptrPos = _tcsrchr(m_szLogPath, '\\'); - if (ptrPos) - { - ptrPos++; - _tcscpy(ptrPos, LOG_FILENAME); - } - else - { - _RPT0(_CRT_WARN, "CCrushLog::CCrushLog - unable to form path"); - } - }*/ - - InitializeCriticalSection(&m_critSect); -} - -/// provides forming data struct and saving it to log -void CCrushLog::InternalProtect(CHAR* FunctionName, CHAR* FileName, - CHAR* CompilationDate, INT LineNumber, - INT LastError) -{ - CRUSHLOG_ITEM item = {0}; - - item.CompilationDate = CompilationDate; - item.FileName = FileName; - item.FunctionName = FunctionName; - item.LineNumber = LineNumber; - item.LastError = LastError; - g_crushLog.SaveToLog(item); - - TCHAR tch[MAX_PATH * 3] = {0}; - _tcscpy(tch, TranslateTS(TEXT("Exception has occured please, analize or just send log file\n\r "))); - _tcscat(tch, CCrushLog::m_szLogPath); - _tcscat(tch, TranslateTS(TEXT("\r\n to developer."))); - - ::MessageBox (NULL, tch, TranslateTS(TEXT("Smart Auto Replier crash. Send the log file to http://shcherbyna.com/forum/viewforum.php?f=8")), MB_OK); -} - -/// saving log information -void CCrushLog::SaveToLog(CRUSHLOG_ITEM & item) -{ - EnterCriticalSection(&m_critSect); - - HANDLE hFile = NULL; - hFile = CreateFile (m_szLogPath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - - if (hFile == INVALID_HANDLE_VALUE) - { - LeaveCriticalSection(&m_critSect); - - return; - } - - { - DWORD dwRetVal = 0; - DWORD dw = GetFileSize(hFile, &dwRetVal); - SetFilePointer(hFile, dw, NULL, FILE_BEGIN); - } - - int nSize = strlen(item.CompilationDate); - nSize += strlen(item.FileName); - nSize += strlen(item.FunctionName); - nSize *= 2; - - CHAR *tsz = new CHAR[nSize]; - - if (tsz) - { - strcpy(tsz, ("******\n")); - strcat(tsz, item.CompilationDate); - strcat(tsz, ("\n")); - strcat(tsz, item.FileName); - strcat(tsz, ("\n")); - strcat(tsz, item.FunctionName); - strcat(tsz, ("\n")); - CHAR tchtemp[MAX_PATH] = {0}; - itoa(item.LineNumber, tchtemp, 10); - strcat(tsz, tchtemp); - strcat(tsz, ("\n")); - itoa(item.LastError, tchtemp, 10); - strcat(tsz, tchtemp); - strcat(tsz, ("\n")); - DWORD dw = 0; - WriteFile (hFile, tsz, strlen(tsz), &dw, NULL); - - delete tsz; - } - - CloseHandle (hFile); - LeaveCriticalSection(&m_critSect); -} diff --git a/!NotAdopted/SmartAutoReplier/CrushLog.h b/!NotAdopted/SmartAutoReplier/CrushLog.h deleted file mode 100644 index 1a595d055b..0000000000 --- a/!NotAdopted/SmartAutoReplier/CrushLog.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -/// crash item that is written in file... -typedef struct _CRUSHLOG_ITEM -{ - CHAR* CompilationDate; /// compilation date of the source file - CHAR* FileName; /// file name where exception has occured - CHAR* FunctionName; /// function name where exception has occured - INT LineNumber; /// line number - INT LastError; /// last error -}CRUSHLOG_ITEM, *PCRUSHLOG_ITEM; - -#define LOG_FILENAME TEXT("sarcrushes.log") - -/// class that handles all crushes -/// occured between BEGIN_LOG_AND_PRO.. and END_LOG.. -class CCrushLog -{ -public: /// ctors, dtors section... - CCrushLog(void); - ~CCrushLog(void); -public: - static void Init(void); /// inits internal data.. - static void DeInit(void); /// deinits internal data.. - static void SaveToLog(CRUSHLOG_ITEM & item); /// saves data to log file - static void InternalProtect(CHAR* FunctionName, CHAR* FileName, - CHAR* CompilationDate, INT LineNumber, - INT LastError); -public: - static TCHAR m_szLogPath[MAX_PATH]; /// path to log file -private: - static CRITICAL_SECTION m_critSect; /// sync object... -}; diff --git a/!NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.cpp b/!NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.cpp deleted file mode 100644 index 0d76db3210..0000000000 --- a/!NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" -#include "../resource.h" -#include "addruledlg.h" -#include "addruledlg.h" -#include "selectuserdlg.h" - -extern LPTSTR g_strPluginName; -extern CMessagesHandler *g_pMessHandler; -extern CCrushLog CRUSHLOGOBJ; - -CAddRuleDlg::CAddRuleDlg(void) : m_dwCRC32(NULL), m_baur2thisMode(false), m_bEditing(false) -{ -BEGIN_PROTECT_AND_LOG_CODE - ZeroMemory(&m_item, sizeof(m_item)); -END_PROTECT_AND_LOG_CODE -} - -CAddRuleDlg::~CAddRuleDlg(void) -{ -BEGIN_PROTECT_AND_LOG_CODE -END_PROTECT_AND_LOG_CODE -} - -LRESULT CAddRuleDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - TranslateDialogDefault(m_hWnd); - m_editRuleName = GetDlgItem(IDC_ED_RULENAME); - m_editContactName = GetDlgItem(IDC_ED_RULECNAME); - m_editReplyText = GetDlgItem(IDC_ED_RULEREPLY); - //m_editReplyAction = GetDlgItem(IDC_ED_RULEACTION); - m_btnSelUser = GetDlgItem(IDC_BTN_SELUSER); - - CenterWindow(); - - if (m_dwCRC32) - { - SetWindowText(TranslateTS(TEXT("Edit rule"))); - m_editRuleName.SetWindowText(m_item.RuleName); - m_editContactName.SetWindowText(m_item.ContactName); - m_editReplyText.SetWindowText(m_item.ReplyText); - //m_editReplyAction.SetWindowText(m_item.ReplyAction); - m_bEditing = true; - } - else if (m_baur2thisMode) - { - m_editRuleName.SetWindowText(m_item.RuleName); - m_editContactName.SetWindowText(m_item.ContactName); - m_editReplyText.SetWindowText(m_item.ReplyText); - //m_editReplyAction.SetWindowText(m_item.ReplyAction); - - m_btnSelUser.EnableWindow(FALSE); - m_editContactName.EnableWindow(FALSE); - m_editReplyText.SetSel(0, _tcslen(m_item.ReplyText), FALSE); - m_editReplyText.SetFocus(); - } - else - { - m_editRuleName.SetWindowText(SETTINGS_DEF_RULE_NAME); - m_editReplyText.SetWindowText(SETTINGS_DEF_MESSAGE_RULE); - } - -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT CAddRuleDlg::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - return FALSE; -END_PROTECT_AND_LOG_CODE -} - -BOOL CAddRuleDlg::PreTranslateMessage(MSG* pMsg) -{ -BEGIN_PROTECT_AND_LOG_CODE - return FALSE; -END_PROTECT_AND_LOG_CODE -} - -LRESULT CAddRuleDlg::OnBtnOKClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE -#define ON_ERROR_1BYTE(x) if (x == 1) { \ - MessageBox(TranslateTS(TEXT("Please, specify longer contact name")), g_strPluginName, MB_OK); \ - return FALSE; } - -#define ON_ERROR(x) MessageBox(TranslateTS(x), g_strPluginName, MB_OK); \ - return FALSE; - - int nLength = m_editRuleName.GetWindowTextLength(); - if (nLength) - { - nLength++; - m_item.RuleName = new TCHAR[nLength]; - - if (m_item.RuleName != NULL) - { - memset(m_item.RuleName, 0, nLength * sizeof(TCHAR)); - m_editRuleName.GetWindowText(m_item.RuleName, nLength); - } - } - else - { - ON_ERROR(TEXT("Please, specify Rule Name")) - } - - nLength = m_editContactName.GetWindowTextLength(); - if (nLength) - { - ON_ERROR_1BYTE(nLength) - nLength++; - m_item.ContactName = new TCHAR[nLength]; - - if (m_item.ContactName != NULL) - { - memset(m_item.ContactName, 0, nLength * sizeof(TCHAR)); - m_editContactName.GetWindowText(m_item.ContactName, nLength); - } - } - else - { - ON_ERROR(TEXT("Please, specify Contact Name")) - } - - nLength = m_editReplyText.GetWindowTextLength(); - if (nLength) - { - if (nLength > SETTINGS_MESSAGE_MAXVALENGTH) - { - MessageBox(TranslateTS(TEXT("header is too big")), g_strPluginName, MB_OK); - return FALSE; - } - - nLength++; - m_item.ReplyText = new TCHAR[nLength]; - - if (m_item.ContactName != NULL) - { - memset(m_item.ReplyText, 0, nLength * sizeof(TCHAR)); - m_editReplyText.GetWindowText(m_item.ReplyText, nLength); - } - } - else - { - ON_ERROR(TEXT("Please, specify Reply Text")) - } - - { - if (m_bEditing) - {/// delete prev item from storage... - g_pMessHandler->getSettings().getStorage().RemReplyAction(m_dwCRC32); - } - - bool b; - DWORD dwCrc = g_pMessHandler->getSettings().AddReplyAction(m_item, b); - if (b) - { - MessageBox(TranslateTS(TEXT("Rule with the same contact name already exists")), g_strPluginName, MB_OK); - return FALSE; - } - - m_bAddedOk = ((b == false) && dwCrc); - m_dwCRC32 = dwCrc; - } - - EndDialog(0); -#undef ON_ERROR -#undef ON_ERROR_1BYTE -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT CAddRuleDlg::OnBtnCancelClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - m_bAddedOk = false; - EndDialog(0); -END_PROTECT_AND_LOG_CODE - return FALSE; -} -LRESULT CAddRuleDlg::OnBnClickedBtnSeluser(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - CSelectUserDlg dlg; - dlg.DoModal(m_hWnd); - if (dlg.m_bAllOk == true) - { - m_editContactName.SetWindowText(dlg.m_szRetVal); - m_editReplyText.SetFocus(); - } - else - { - m_editContactName.SetFocus(); - } -END_PROTECT_AND_LOG_CODE - return 0; -} diff --git a/!NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.h b/!NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.h deleted file mode 100644 index d02fde733c..0000000000 --- a/!NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -#include -#include -#include -#include - -#include "../RuleItem.h" - -class CAddRuleDlg : public CDialogImpl, public CMessageFilter -{ -public: - CAddRuleDlg(void); - virtual ~CAddRuleDlg(void); -public: - enum {IDD = IDD_ADDRULE_DLG}; - BEGIN_MSG_MAP(COptionsDlg) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) - - COMMAND_ID_HANDLER(IDOK, OnBtnOKClicked) - COMMAND_ID_HANDLER(IDCANCEL, OnBtnCancelClicked) - COMMAND_HANDLER(IDC_BTN_SELUSER, BN_CLICKED, OnBnClickedBtnSeluser) - END_MSG_MAP() -protected: - virtual BOOL PreTranslateMessage(MSG* pMsg); - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); - LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); - LRESULT OnBtnOKClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); - LRESULT OnBtnCancelClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); - LRESULT OnBnClickedBtnSeluser(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); -protected: - CEdit m_editRuleName; - CEdit m_editContactName; - CEdit m_editReplyText; - //CEdit m_editReplyAction; - CButton m_btnSelUser; -public: - RULE_ITEM m_item; - bool m_bAddedOk; - DWORD m_dwCRC32; -private: - bool m_bEditing; -public: - bool m_baur2thisMode; -}; diff --git a/!NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.cpp b/!NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.cpp deleted file mode 100644 index 5dbc6989bc..0000000000 --- a/!NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" -#include "editreplydlg.h" - -extern LPTSTR g_strPluginName; - -CEditReplyDlg::CEditReplyDlg(void) -{ -} - -CEditReplyDlg::~CEditReplyDlg(void) -{ -} - -BOOL CEditReplyDlg::PreTranslateMessage(MSG* pMsg) -{ - return IsDialogMessage(pMsg); -} - -LRESULT CEditReplyDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) -{ - TranslateDialogDefault(m_hWnd); - m_editReplyText = GetDlgItem(IDC_ED_TEXT); - - if (m_commRule.Message) - { - m_editReplyText.SetWindowText(m_commRule.Message); - } - - CenterWindow(GetDesktopWindow()); - - return FALSE; -} - -LRESULT CEditReplyDlg::OnBtnOKClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ - int nLength = 0; - - delete m_commRule.Message; - - nLength = m_editReplyText.GetWindowTextLength(); - - if (nLength > SETTINGS_MESSAGE_MAXVALENGTH) - { - MessageBox(TranslateTS(TEXT("message is too big")), g_strPluginName, MB_OK); - - return FALSE; - } - nLength++; - m_commRule.Message = new TCHAR[nLength]; - - if (!m_commRule.Message) - return FALSE; - - memset(m_commRule.Message, 0, nLength * sizeof(TCHAR)); - m_editReplyText.GetWindowText((LPTSTR)m_commRule.Message, nLength); - - m_bAllOk = true; - EndDialog(1); - return FALSE; -} - -LRESULT CEditReplyDlg::OnBtnCancelClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ - m_bAllOk = false; - EndDialog(0); - return FALSE; -} \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.h b/!NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.h deleted file mode 100644 index 0b4a5fb94a..0000000000 --- a/!NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -#include "..\resource.h" - -#include -#include -#include -#include - -class CEditReplyDlg : public CDialogImpl, public CMessageFilter -{ -public: - CEditReplyDlg(void); - ~CEditReplyDlg(void); -public: - enum {IDD = IDD_SET_AURMESSAGEDLG}; - BEGIN_MSG_MAP(CEditReplyDlg) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - COMMAND_ID_HANDLER(IDOK, OnBtnOKClicked) - COMMAND_ID_HANDLER(IDCANCEL, OnBtnCancelClicked) - END_MSG_MAP() -protected: - virtual BOOL PreTranslateMessage(MSG* pMsg); - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); - LRESULT OnBtnOKClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); - LRESULT OnBtnCancelClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); -public: - REPLYER_SETTINGS m_settings; - COMMON_RULE_ITEM m_commRule; - bool m_bAllOk; -protected: - CEdit m_editReplyText; - CEdit m_editReplyHeader; -}; diff --git a/!NotAdopted/SmartAutoReplier/GUI/OptionsDlg.cpp b/!NotAdopted/SmartAutoReplier/GUI/OptionsDlg.cpp deleted file mode 100644 index 1f25812101..0000000000 --- a/!NotAdopted/SmartAutoReplier/GUI/OptionsDlg.cpp +++ /dev/null @@ -1,528 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" -#include "optionsdlg.h" -#include "addruledlg.h" - -/// need ptr to get/set info -extern CMessagesHandler *g_pMessHandler; -extern CCrushLog CRUSHLOGOBJ; -extern LPTSTR g_strPluginName; - -//COptionsDlg g_optionsDlg; - -BOOL CALLBACK COptionsDlg::DlgProcCluiOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ -BEGIN_PROTECT_AND_LOG_CODE - - /*if (g_optionsDlg.m_bDestroying) - return FALSE; - - if (g_optionsDlg.m_hWnd == NULL) - g_optionsDlg.Attach(hwndDlg); - - LRESULT lre = {0}; - DWORD dwId = {0}; - return g_optionsDlg.ProcessWindowMessage(hwndDlg, msg, wParam, lParam, lre, dwId);*/ - -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -COptionsDlg::COptionsDlg(void) : m_bShown(false), m_szMessage(NULL) -{ -BEGIN_PROTECT_AND_LOG_CODE -///g_optionsDlg.m_bDestroying = false; -m_bDestroying = false; -END_PROTECT_AND_LOG_CODE -} - -COptionsDlg::~COptionsDlg(void) -{ -BEGIN_PROTECT_AND_LOG_CODE -END_PROTECT_AND_LOG_CODE -} - -BOOL COptionsDlg::PreTranslateMessage(MSG* pMsg) -{ -BEGIN_PROTECT_AND_LOG_CODE - return ::IsDialogMessage(m_hWnd, pMsg); -END_PROTECT_AND_LOG_CODE -} - -/// process OnInitDialog -LRESULT COptionsDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - TranslateDialogDefault(m_hWnd); - - if (!g_pMessHandler) - return FALSE; - - m_listRules = GetDlgItem(IDC_LIST_RULES); - m_editReplayDelay = GetDlgItem(IDC_EDIT_REPLAYDELAY); -// m_editHeaderMessage = GetDlgItem(IDC_EDIT_HEADER); - m_editMessageText = GetDlgItem(IDC_EDIT_MESSAGE); - m_btnAdd = GetDlgItem(IDC_BTN_ADDRULE); - m_btnDel = GetDlgItem(IDC_BTN_DELRULE); - m_btnChange = GetDlgItem(IDC_BTN_EDITRULE); - m_wndCheckDOnSOn = GetDlgItem(IDC_CHECK_DISABLEWMON); - m_wndCheckModeTypes = GetDlgItem(IDC_CH_ENABLE_WSCH); - m_cbModeTypes = GetDlgItem(IDC_CB_ENWSC); - m_chbShowAurWhmc = GetDlgItem(IDC_CH_SHOWCG); - m_cbDisWMBTypes = GetDlgItem(IDC_CB_DWSB); - m_chDisWMB = GetDlgItem(IDC_CH_DISWHSB); - m_chSaveAURSToHist = GetDlgItem(IDC_CH_SAVE_AURS); - - m_cbModeTypes.AddString(TranslateTS(TEXT("DND/NA/Away/Occupied modes"))); - m_cbModeTypes.AddString(TranslateTS(TEXT("DND mode"))); - m_cbModeTypes.AddString(TranslateTS(TEXT("NA mode"))); - m_cbModeTypes.AddString(TranslateTS(TEXT("Away mode"))); - m_cbModeTypes.AddString(TranslateTS(TEXT("Occupied mode"))); - - m_cbDisWMBTypes.AddString(TranslateTS(TEXT("Online/Free for chat modes"))); - m_cbDisWMBTypes.AddString(TranslateTS(TEXT("Online mode"))); - m_cbDisWMBTypes.AddString(TranslateTS(TEXT("Free for chat mode"))); - - COMMON_RULE_ITEM & commRules = g_pMessHandler->getSettings().getStorage().getCommonRule(); - REPLYER_SETTINGS & settings = g_pMessHandler->getSettings().getSettings(); - - if (settings.ModeValue > m_cbModeTypes.GetCount()) - m_cbModeTypes.SetCurSel(0); - else - m_cbModeTypes.SetCurSel(settings.ModeValue); - if (settings.ModeDisValue > m_cbDisWMBTypes.GetCount()) - m_cbDisWMBTypes.SetCurSel(0); - else - m_cbDisWMBTypes.SetCurSel(settings.ModeDisValue); - - m_cbDisWMBTypes.EnableWindow(settings.bDisableWhenModeIsSet); - - if (settings.bDisableWhenModeIsSet) - { - m_chDisWMB.SendMessage(BM_SETCHECK, BST_CHECKED, 0); - } - else - { - m_chDisWMB.SendMessage(BM_SETCHECK, BST_UNCHECKED, 0); - } - - if (settings.bShowAURDlgWhenModeChanges) - { - m_chbShowAurWhmc.SendMessage(BM_SETCHECK, BST_CHECKED, 0); - } - else - { - m_chbShowAurWhmc.SendMessage(BST_UNCHECKED, BST_CHECKED, 0); - } - - if (settings.bEnableWhenModeIsSet) - { - m_wndCheckModeTypes.SendMessage(BM_SETCHECK, BST_CHECKED, 0); - } - else - { - m_wndCheckModeTypes.SendMessage(BST_UNCHECKED, BST_CHECKED, 0); - } - - if (settings.bSaveToHistory) - { - m_chSaveAURSToHist.SendMessage(BM_SETCHECK, BST_CHECKED, 0); - } - else - { - m_chSaveAURSToHist.SendMessage(BST_UNCHECKED, BST_CHECKED, 0); - } - - m_cbModeTypes.EnableWindow(settings.bEnableWhenModeIsSet); - - int nLength = settings.ReplayDelay; - if (nLength == 0) - nLength = SETTINGS_DEF_COMMON_VALREPDELAY; - - if (settings.bDisableWhenMirandaIsOn) - m_wndCheckDOnSOn.SendMessage(BM_SETCHECK, BST_CHECKED, 0); - else - m_wndCheckDOnSOn.SendMessage(BM_SETCHECK, BST_UNCHECKED, 0); - - TCHAR strNumber[MAX_PATH] = {0}; - m_editReplayDelay.SetWindowText(_itot(nLength, strNumber, 10)); - m_nReplayDelay = nLength; - - TCHAR* str = commRules.Message; - m_editMessageText.SetWindowText(str); - - if (m_szMessage) - { - delete m_szMessage; - m_szMessage = NULL; - } - - m_szMessage = new TCHAR[SETTINGS_MESSAGE_MAXVALENGTH]; - - if (!m_szMessage) - return FALSE; - - memset(m_szMessage, 0, SETTINGS_MESSAGE_MAXVALENGTH * sizeof(TCHAR)); - - m_editMessageText.GetWindowText(m_szMessage, SETTINGS_MESSAGE_MAXVALENGTH); - - { /// filling listbox with rule names... - RulesHash::iterator it; - RulesHash & hash = g_pMessHandler->getSettings().getStorage().getHashTable(); - int nPos = 0; - - bool bAdded = false; - for (it = hash.begin(); it != hash.end(); it++) - { - nPos = m_listRules.AddString(it->second.RuleName); - if (nPos != -1) - { - m_listRules.SetItemData(nPos, it->first); - if (!bAdded) - bAdded = true; - } - } - if (bAdded) - { - OnSetSelInRulesList(0); - } - } -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -/// process WM_DESTROY -LRESULT COptionsDlg::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - m_bDestroying = true; - ///g_optionsDlg.m_bDestroying = true; - ///::DestroyWindow(m_hWnd); - ///g_optionsDlg.m_hWnd = NULL; - //m_hWnd = NULL; - m_szMessage = NULL; - // m_bDestroying = false; - ///g_optionsDlg.m_bDestroying = false; - return FALSE; -END_PROTECT_AND_LOG_CODE -} - -void COptionsDlg::OnNotifyAboutChanges(void) -{ -BEGIN_PROTECT_AND_LOG_CODE - SendMessage(m_hwndHolder, PSM_CHANGED, 0, 0); -END_PROTECT_AND_LOG_CODE -} - -/// handler of typing in replay delay edit box -LRESULT COptionsDlg::OnEditReply(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - if (m_bShown) - { - m_bShown = false; - return FALSE; - } - TCHAR tch[MAX_PATH] = {0}; - GetDlgItemText (IDC_EDIT_REPLAYDELAY, tch, sizeof(tch)); - int nValue = _tstoi(tch); - - if (nValue != m_nReplayDelay) - { - m_nReplayDelay = nValue; - OnNotifyAboutChanges(); - } - -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT COptionsDlg::OnNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - switch (((LPNMHDR)lParam)->code) - { - case PSN_APPLY: - { /// apply our changes... - REPLYER_SETTINGS sett; - COMMON_RULE_ITEM commrule; - - commrule.Message = m_szMessage; - - sett.bEnabled = g_pMessHandler->getSettings().getSettings().bEnabled; - sett.ReplayDelay = m_nReplayDelay; - - LRESULT lres = m_wndCheckDOnSOn.SendMessage(BM_GETCHECK, 0, 0); - sett.bDisableWhenMirandaIsOn = (lres == BST_CHECKED); - lres = m_wndCheckModeTypes.SendMessage(BM_GETCHECK, 0, 0); - sett.bEnableWhenModeIsSet = (lres == BST_CHECKED); - lres = m_chbShowAurWhmc.SendMessage(BM_GETCHECK, 0, 0); - sett.bShowAURDlgWhenModeChanges = (lres == BST_CHECKED); - lres = m_chSaveAURSToHist.SendMessage(BM_GETCHECK, 0, 0); - sett.bSaveToHistory = (lres == BST_CHECKED); - sett.ModeValue = m_cbModeTypes.GetCurSel(); - lres = m_chDisWMB.SendMessage(BM_GETCHECK, 0, 0); - sett.bDisableWhenModeIsSet = (lres == BST_CHECKED); - sett.ModeDisValue = m_cbDisWMBTypes.GetCurSel(); - - CSettingsHandler & handler = g_pMessHandler->getSettings(); - handler.setSettings(sett, &commrule); - //handler.getStorage().Flush(); /// flush all unflushed rules into hdd - } - } - -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT COptionsDlg::OnEditHeader(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT COptionsDlg::OnEditMessage(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - if (!m_szMessage) - return FALSE; - - int nLength = m_editMessageText.GetWindowTextLength(); - - if (nLength > SETTINGS_MESSAGE_MAXVALENGTH) - { - MessageBox(TranslateTS(TEXT("too big size")), g_strPluginName, MB_OK); - m_editMessageText.SetWindowText(m_szMessage); - - return FALSE; - } - nLength++; - LPTSTR str2 = new TCHAR[nLength]; - - if (!str2) - return FALSE; - - memset(str2, 0, nLength * sizeof(TCHAR)); - m_editMessageText.GetWindowText(str2, nLength); - - if (_tcscmp(m_szMessage, str2) != 0) - { - _tcscpy(m_szMessage, str2); - OnNotifyAboutChanges(); - } - - delete str2; -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -void COptionsDlg::OnSetSelInRulesList(int nIndex) -{ -BEGIN_PROTECT_AND_LOG_CODE - m_listRules.SetCurSel(nIndex); - BOOL b; - OnListBoxSelChanged(0, 0, 0, b); -END_PROTECT_AND_LOG_CODE -} - -LRESULT COptionsDlg::OnBtnAddRuleClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - CAddRuleDlg dlg; - dlg.DoModal(m_hWnd, 0); - if (dlg.m_bAddedOk) - { - int npos = m_listRules.AddString(dlg.m_item.RuleName); - if (npos != -1) - { - m_listRules.SetItemData(npos, dlg.m_dwCRC32); - OnSetSelInRulesList(npos); - OnNotifyAboutChanges(); - } - } -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT COptionsDlg::OnBtnEditRuleClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - int nIndex = m_listRules.GetCurSel(); - if (nIndex >= 0) - { - DWORD dwCrc32 = static_cast(m_listRules.GetItemData(nIndex)); - if (dwCrc32) - { - CAddRuleDlg dlgEdit; - RulesHash::iterator it; - RulesHash & hash = g_pMessHandler->getSettings().getStorage().getHashTable(); - it = hash.find(dwCrc32); - if (it != hash.end()) - { - dlgEdit.m_item = it->second; - dlgEdit.m_dwCRC32 = dwCrc32; - dlgEdit.DoModal(); - if (dlgEdit.m_bAddedOk) - {/// the rule is edited... - m_listRules.DeleteString(nIndex); - nIndex = m_listRules.AddString(dlgEdit.m_item.RuleName); - m_listRules.SetItemData(nIndex, dlgEdit.m_dwCRC32); - OnSetSelInRulesList(nIndex); - OnNotifyAboutChanges(); - } - } - } - } -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT COptionsDlg::OnBtnDeleteRuleClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - int nIndex = m_listRules.GetCurSel(); - if (nIndex >= 0) - { - DWORD dwptr = static_cast(m_listRules.GetItemData(nIndex)); - if (dwptr)/// we have ptr - { - if (MessageBox(TranslateTS(TEXT("Do you really want delete selected rule ?")), g_strPluginName, MB_YESNO) == IDNO) - return FALSE; - - CRulesStorage & hash = g_pMessHandler->getSettings().getStorage(); - - if (hash.RemReplyAction(dwptr)) - {/// we found item in storage list... - int nCount = m_listRules.DeleteString(nIndex); - if (nCount != LB_ERR) - { /// set sel to prev one - if (nIndex == 0 && nCount) - OnSetSelInRulesList(0); - else - if ( (nIndex - 1) <= nCount) - { - OnSetSelInRulesList(nIndex - 1); - } - } - - OnNotifyAboutChanges(); - } - } - } - - BOOL b; - OnListBoxSelChanged(0, 0, 0, b); - -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT COptionsDlg::OnListBoxSelChanged(WORD wParam, WORD w2Param, HWND hwnd, BOOL & bHandled) -{ -BEGIN_PROTECT_AND_LOG_CODE - int nCount = m_listRules.GetCurSel(); - //m_btnChange.EnableWindow((nCount >= 0)); - BOOL bEnable = (nCount >= 0); - m_btnDel.EnableWindow(bEnable); - m_btnChange.EnableWindow(bEnable); - -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT COptionsDlg::OnBnClickedCheck(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - OnNotifyAboutChanges(); - - return FALSE; -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT COptionsDlg::OnBnCheckEnableWhenModeIsOn(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - LRESULT lres = m_wndCheckModeTypes.SendMessage(BM_GETCHECK, 0, 0); - m_cbModeTypes.EnableWindow(lres == BST_CHECKED); - OnNotifyAboutChanges(); -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT COptionsDlg::OnCbnSelchangeCbEnwsc(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - OnNotifyAboutChanges(); - -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT COptionsDlg::OnCheckSaveToHistory(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - OnNotifyAboutChanges(); -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT COptionsDlg::OnBnCheckDisableWhenModeIsOn(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - LRESULT lres = m_chDisWMB.SendMessage(BM_GETCHECK, 0, 0); - m_cbDisWMBTypes.EnableWindow(lres == BST_CHECKED); - OnNotifyAboutChanges(); - -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT COptionsDlg::OnCbnSelchangeCbDisnwsc(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - OnNotifyAboutChanges(); - -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -/// options are changed in another place... -/// so just update them all... -LRESULT COptionsDlg::OnRefreshOptions(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - MessageBox (TranslateTS(TEXT("Options are changed in another dialog")), g_strPluginName, MB_OK); - ///OnNotifyAboutChanges(); -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT COptionsDlg::OnLbnDblclkListRules(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) -{ -BEGIN_PROTECT_AND_LOG_CODE - return OnBtnEditRuleClick(wNotifyCode, wID, hWndCtl, bHandled); -END_PROTECT_AND_LOG_CODE -} \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/GUI/OptionsDlg.h b/!NotAdopted/SmartAutoReplier/GUI/OptionsDlg.h deleted file mode 100644 index 0e2e91f191..0000000000 --- a/!NotAdopted/SmartAutoReplier/GUI/OptionsDlg.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -/// #warning: redeclaring....quick programming ;) -/// look at stdafx.h -#ifndef REFRESH_OPTS_MSG - #define REFRESH_OPTS_MSG WM_USER + 666 -#endif - -#include -#include -#include -#include -#include - -/// here is a wrapper on options dlg -class COptionsDlg : public CDialogImpl, public CMessageFilter -{ -public: - COptionsDlg(void); - virtual ~COptionsDlg(void); -public: - enum {IDD = IDD_OPTIONS}; - BEGIN_MSG_MAP(COptionsDlg) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) - MESSAGE_HANDLER(WM_NOTIFY, OnNotify) - MESSAGE_HANDLER(REFRESH_OPTS_MSG, OnRefreshOptions) - COMMAND_ID_HANDLER(IDC_BTN_ADDRULE, OnBtnAddRuleClick) - COMMAND_ID_HANDLER(IDC_BTN_DELRULE, OnBtnDeleteRuleClick) - COMMAND_ID_HANDLER(IDC_BTN_EDITRULE, OnBtnEditRuleClick) - COMMAND_ID_HANDLER(IDC_EDIT_REPLAYDELAY, OnEditReply) - COMMAND_ID_HANDLER(IDC_EDIT_HEADER, OnEditHeader) - COMMAND_ID_HANDLER(IDC_EDIT_MESSAGE, OnEditMessage) - COMMAND_CODE_HANDLER(LBN_SELCHANGE, OnListBoxSelChanged) - COMMAND_HANDLER(IDC_LIST_RULES, LBN_DBLCLK, OnLbnDblclkListRules) - COMMAND_HANDLER(IDC_CHECK_DISABLEWMON, BN_CLICKED, OnBnClickedCheck) - COMMAND_HANDLER(IDC_CH_ENABLE_WSCH, BN_CLICKED, OnBnCheckEnableWhenModeIsOn) - COMMAND_HANDLER(IDC_CH_SHOWCG, BN_CLICKED, OnBnCheckEnableWhenModeIsOn) - COMMAND_HANDLER(IDC_CH_SAVE_AURS, BN_CLICKED, OnCheckSaveToHistory) - COMMAND_HANDLER(IDC_CB_ENWSC, CBN_SELENDOK, OnCbnSelchangeCbEnwsc) - COMMAND_HANDLER(IDC_CH_DISWHSB, BN_CLICKED, OnBnCheckDisableWhenModeIsOn) - COMMAND_HANDLER(IDC_CB_DWSB, CBN_SELENDOK, OnCbnSelchangeCbDisnwsc) - END_MSG_MAP() - virtual BOOL PreTranslateMessage(MSG* pMsg); -protected: - /// messages handlers prototypes - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); - LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); - LRESULT OnNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); - LRESULT OnRefreshOptions(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); - - /// commands handlers prototypes - LRESULT OnBtnAddRuleClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); - LRESULT OnBtnDeleteRuleClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); - LRESULT OnBtnEditRuleClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); - LRESULT OnEditReply(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); - LRESULT OnEditHeader(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); - LRESULT OnEditMessage(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); - LRESULT OnListBoxSelChanged(WORD wParam, WORD wParam2, HWND hwnd, BOOL & bHandled); - LRESULT OnBnClickedCheck(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); - LRESULT OnBnCheckEnableWhenModeIsOn(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); - LRESULT OnCbnSelchangeCbEnwsc(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); - LRESULT OnBnCheckDisableWhenModeIsOn(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); - LRESULT OnCheckSaveToHistory(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); - LRESULT OnCbnSelchangeCbDisnwsc(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); - LRESULT OnLbnDblclkListRules(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); -public: - static BOOL CALLBACK DlgProcCluiOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -private: - void OnNotifyAboutChanges(void); - void OnSetSelInRulesList(int nIndex); -protected: - CEdit m_editReplayDelay; /// edit box where reply delay is specifyed - CEdit m_editMessageText; /// edit box where message text is specifyed - CListBox m_listRules; /// list box where all rules are specifyed - CButton m_btnAdd; /// button add rule - CButton m_btnDel; /// button delete rule - CButton m_btnChange; /// button change rule - CWindow m_wndCheckDOnSOn; /// checkbox that specifyes dis of plug. when mir is on - CComboBox m_cbModeTypes; /// cb mode types - CWindow m_wndCheckModeTypes; /// ch mode types - CWindow m_chbShowAurWhmc; /// ch show edit reply message - CWindow m_chDisWMB; /// ch disable when mode becomes... - CWindow m_chSaveAURSToHist; /// save aurs to history - CComboBox m_cbDisWMBTypes; /// cb disable when mode becomes... -private: - LPTSTR m_szMessage; - int m_nReplayDelay; - bool m_bDestroying; -protected: - bool m_bShown; -public: - HWND m_hwndHolder; -}; - -/// here is static dlg proc for options dialog.. -/// very bad but mirand can accept only this function -BOOL CALLBACK DlgProcCluiOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.cpp b/!NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.cpp deleted file mode 100644 index 6a51ccae19..0000000000 --- a/!NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" -#include "selectuserdlg.h" -#include "selectuserdlg.h" - -extern LPTSTR g_strPluginName; -extern CMessagesHandler * g_pMessHandler; - - -CSelectUserDlg::CSelectUserDlg(void) : m_bAllOk(false) -{ -} - -CSelectUserDlg::~CSelectUserDlg(void) -{ -} - -BOOL CSelectUserDlg::PreTranslateMessage(MSG* pMsg) -{ - return IsDialogMessage(pMsg); -} - -LRESULT CSelectUserDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - TranslateDialogDefault(m_hWnd); - m_listUsers = GetDlgItem(IDC_LIST_USERS); - RebuildCL(); -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -void CSelectUserDlg::RebuildCL() -{ -BEGIN_PROTECT_AND_LOG_CODE - HANDLE hContact= reinterpret_cast (CallService(MS_DB_CONTACT_FINDFIRST, 0, 0)); - TCHAR* szContactName = NULL; - TCHAR* szProto = NULL; - DWORD wId = 0; - while (hContact != NULL) - { - szContactName = g_pMessHandler->GetContactName(hContact); - szProto = (TCHAR*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - if (szProto) - { - size_t nPos = -1; - if (szContactName) - { - nPos = m_listUsers.AddString(szContactName); - } - - /*DBVARIANT db = {0}; - DBGetContactSetting(hContact, szProto, "uin", &db); - DBGetContactSetting(hContact, szProto, "UIN", &db);*/ - //m_listUsers.SetItemData(nPos, ) - } - - hContact = reinterpret_cast (CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM) hContact, 0)); - } -END_PROTECT_AND_LOG_CODE -} - -LRESULT CSelectUserDlg::OnBtnOKClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - INT nsel = m_listUsers.GetCurSel(); - m_bAllOk = (nsel != -1); - if (m_bAllOk == true) - { - m_listUsers.GetText(nsel, m_szRetVal); - EndDialog(0); - } -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT CSelectUserDlg::OnBtnCancelClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - m_bAllOk = false; - EndDialog(0); -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT CSelectUserDlg::OnLbnDblclkListUsers(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) -{ - return OnBtnOKClicked(wNotifyCode, wID, hWndCtl, bHandled); -} diff --git a/!NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.h b/!NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.h deleted file mode 100644 index 1756e7a4b8..0000000000 --- a/!NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -#include "..\resource.h" - -#include -#include -#include -#include - -class CSelectUserDlg : public CDialogImpl, public CMessageFilter -{ -public: - CSelectUserDlg(void); - ~CSelectUserDlg(void); -public: - enum {IDD = IDD_SEL_USER}; - BEGIN_MSG_MAP(CSelectUserDlg) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - COMMAND_ID_HANDLER(IDOK, OnBtnOKClicked) - COMMAND_ID_HANDLER(IDCANCEL, OnBtnCancelClicked) - COMMAND_HANDLER(IDC_LIST_USERS, LBN_DBLCLK, OnLbnDblclkListUsers) - END_MSG_MAP() -protected: - virtual BOOL PreTranslateMessage(MSG* pMsg); - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); - LRESULT OnBtnOKClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); - LRESULT OnBtnCancelClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); -private: - void RebuildCL(); -public: - bool m_bAllOk; - TCHAR m_szRetVal[MAX_PATH]; -protected: - CListBox m_listUsers; -public: - LRESULT OnLbnDblclkListUsers(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); -}; diff --git a/!NotAdopted/SmartAutoReplier/GUI/SettingsDlgHolder.cpp b/!NotAdopted/SmartAutoReplier/GUI/SettingsDlgHolder.cpp deleted file mode 100644 index 4a9eae542a..0000000000 --- a/!NotAdopted/SmartAutoReplier/GUI/SettingsDlgHolder.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" -#include "settingsdlgholder.h" - -/// #warning -/// dont make Translate each time -/// instead once fill list of translated strings -/// and use them - -extern LPTSTR g_strPluginName; -extern CMessagesHandler * g_pMessHandler; -CSettingsDlgHolder * CSettingsDlgHolder::m_pThis = NULL; - -CSettingsDlgHolder::CSettingsDlgHolder(void) : -IMSingeltone(this), -m_bTabSelected(false), -m_bDestroying(false) -{ -} - -CSettingsDlgHolder::~CSettingsDlgHolder(void) -{ -BEGIN_PROTECT_AND_LOG_CODE - BOOL b; - OnDestroy(NULL, NULL, NULL, b); -END_PROTECT_AND_LOG_CODE -} - -BOOL CSettingsDlgHolder::PreTranslateMessage(MSG* pMsg) -{ - return IsDialogMessage(pMsg); -} - -LRESULT CSettingsDlgHolder::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - TranslateDialogDefault(m_hWnd); - - m_tabCtrl = GetDlgItem(IDC_TABSHOLDER); - m_statusMsg = GetDlgItem(IDC_STATUSMSG); - - TCITEM ti = {0}; - ti.mask = TCIF_TEXT; - ti.pszText = TranslateTS(TEXT("General")); - ti.cchTextMax = _tcslen(ti.pszText); - m_tabCtrl.InsertItem(0, &ti); - /*ti.pszText = Translate("About"); - ti.cchTextMax = _tcslen(ti.pszText); - m_tabCtrl.InsertItem(1, &ti);*/ - - m_generalOpt.Create(m_tabCtrl, NULL); - m_generalOpt.m_hwndHolder = this->m_hWnd; - m_tabCtrl.SetCurSel(0); - - /// #warning - /// copy paste from OnNotify(), fix later - /*m_statusMsg.SetWindowText(Translate("General options, provides basic functionality."));*/ - m_statusMsg.SetWindowText(TranslateTS(TEXT(""))); - m_generalOpt.SetWindowPos(NULL, 7, 23, NULL, NULL, SWP_NOSIZE); - m_generalOpt.ShowWindow(SW_SHOW); - -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -void CSettingsDlgHolder::OnNotifyParents(LPNMHDR lpnmhdr, int nCode) -{ -BEGIN_PROTECT_AND_LOG_CODE - lpnmhdr->code = nCode; - m_generalOpt.SendMessage(WM_NOTIFY, 0, reinterpret_cast(lpnmhdr)); -END_PROTECT_AND_LOG_CODE -} - -LRESULT CSettingsDlgHolder::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - LPNMHDR lpnmhdr = NULL; - lpnmhdr = (LPNMHDR)lParam; - if (lpnmhdr == NULL) - { - return FALSE; - } - - if (m_bTabSelected == false) - { - m_bTabSelected = true; - return FALSE; - } - - switch (lpnmhdr->code) - { - case PSN_APPLY: - OnNotifyParents(lpnmhdr, PSN_APPLY); - break; - } - - int nSel = -1; - if (lpnmhdr->hwndFrom == m_tabCtrl) - { - nSel = m_tabCtrl.GetCurSel(); - /// let's make a switch by dialogs... - if (nSel == 0) - { - m_statusMsg.SetWindowText(TranslateTS(TEXT("General options, provides basic functionality."))); - m_generalOpt.ShowWindow(SW_SHOW); - m_generalOpt.SetWindowPos(NULL, 7, 23, NULL, NULL, SWP_NOSIZE); - } - else - m_generalOpt.ShowWindow(SW_HIDE); - } - - m_bTabSelected = false; - -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -BOOL CALLBACK CSettingsDlgHolder::FakeDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ -BEGIN_PROTECT_AND_LOG_CODE - CSettingsDlgHolder *pHandler = CSettingsDlgHolder::GetObject(); - - if (pHandler == NULL) - return FALSE; - - if (pHandler->m_bDestroying == true) - return FALSE; - - if (pHandler->m_hWnd == NULL) - pHandler->Attach(hwndDlg); - - LRESULT lr = 0; - DWORD dwid = 0; - BOOL bRetVal = pHandler->ProcessWindowMessage(hwndDlg, msg, wParam, lParam, lr, dwid); - return bRetVal; - END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT CSettingsDlgHolder::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - m_bDestroying = true; - - if (m_tabCtrl.IsWindow()) - { - m_tabCtrl.DeleteAllItems(); - m_tabCtrl.DestroyWindow(); - } - if (m_statusMsg.IsWindow()) - m_statusMsg.DestroyWindow(); - - if (m_generalOpt.IsWindow()) - { - /*try - {*/ - //OSVERSIONINFO ver = {0}; - //ver.dwOSVersionInfoSize = sizeof(ver); - - //if (GetVersionEx(&ver) == TRUE) - //{ - // if (ver.dwMajorVersion > 4) - // { - NMHDR h = {0}; - h.code = PSN_APPLY; - OnNotifyParents(&h, PSN_APPLY); - // } - //} - m_generalOpt.DestroyWindow(); - //} - //catch (...) - //{/// win9x will die here - //} - } - m_hWnd = NULL; - -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -LRESULT CSettingsDlgHolder::OnSettingsChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) -{ -BEGIN_PROTECT_AND_LOG_CODE - return SendMessage(GetParent(), PSM_CHANGED, 0, 0); -END_PROTECT_AND_LOG_CODE - return FALSE; -} \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/GUI/SettingsDlgHolder.h b/!NotAdopted/SmartAutoReplier/GUI/SettingsDlgHolder.h deleted file mode 100644 index 61fb460e5b..0000000000 --- a/!NotAdopted/SmartAutoReplier/GUI/SettingsDlgHolder.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -#include "..\resource.h" - -#include -#include -#include -#include - -#include "optionsdlg.h" - -/// dialog that holds all -/// gui dialogs.. -class CSettingsDlgHolder : public CDialogImpl, - public CMessageFilter, - public IMSingeltone -{ -public: /// ctors - CSettingsDlgHolder(void); - /// dctors - ~CSettingsDlgHolder(void); -public: - enum {IDD = IDD_SDLGHOLDER}; - BEGIN_MSG_MAP(CSettingsDlgHolder) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - MESSAGE_HANDLER(WM_NOTIFY, OnNotify) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) - MESSAGE_HANDLER(PSM_CHANGED, OnSettingsChanged) - END_MSG_MAP() -protected: - virtual BOOL PreTranslateMessage(MSG* pMsg); - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); - LRESULT OnNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); - LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); - LRESULT OnSettingsChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); -private: - void OnNotifyParents(LPNMHDR lpnmhdr, int nCode); -private: - bool m_bTabSelected; -public: - static BOOL CALLBACK FakeDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -protected: - CTabCtrl m_tabCtrl; /// holder of all settings dlg - CStatic m_statusMsg; - COptionsDlg m_generalOpt; /// general options dlg -public: - bool m_bDestroying; -}; diff --git a/!NotAdopted/SmartAutoReplier/Interfaces/ISettings.h b/!NotAdopted/SmartAutoReplier/Interfaces/ISettings.h deleted file mode 100644 index 4a789be694..0000000000 --- a/!NotAdopted/SmartAutoReplier/Interfaces/ISettings.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -/// base for settings data... -interface ISettingsStream -{ -}; - -/// base interface for settings managers... -interface ISettings -{ - virtual bool Serialize(ISettingsStream *pStream, DWORD & ObjectSize) = NULL; - virtual bool Deserialize(DWORD & ObjectSize) = NULL; -}; \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/Interfaces/ISingletone.h b/!NotAdopted/SmartAutoReplier/Interfaces/ISingletone.h deleted file mode 100644 index 7474127e89..0000000000 --- a/!NotAdopted/SmartAutoReplier/Interfaces/ISingletone.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -/// base class for singletones in plugin -template -class IMSingeltone -{ -public: - IMSingeltone(){}; - IMSingeltone(T * ptclass) {m_pThis = ptclass;} - static void SetObject(T* pObj) {m_pThis = pObj;}; - static T* GetObject(){return m_pThis;}; -protected: - static T* m_pThis; -}; \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/LuaBridge.cpp b/!NotAdopted/SmartAutoReplier/LuaBridge.cpp deleted file mode 100644 index 764dec3381..0000000000 --- a/!NotAdopted/SmartAutoReplier/LuaBridge.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This code is inspired by article of RichardS at http://www.codeproject.com/Articles/11508/Integrating-Lua-into-C - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" -#include "LuaBridge.h" - -CLuaBridge::CLuaBridge(void) : m_pLuaContext(NULL) -{ - m_pLuaContext = lua_open(); - - if (m_pLuaContext != NULL) - { - lua_pushcclosure(m_pLuaContext, LuaDebugMessage, 0); - lua_setglobal(m_pLuaContext, "trace"); - - lua_atpanic(m_pLuaContext, (lua_CFunction)HandleLuaAsssert); - - luaopen_io(m_pLuaContext); - luaopen_math(m_pLuaContext); - luaopen_base(m_pLuaContext); - luaopen_loadlib(m_pLuaContext); - luaopen_table(m_pLuaContext); - luaopen_string(m_pLuaContext); - luaopen_debug(m_pLuaContext); - } -} - -CLuaBridge::~CLuaBridge(void) -{ - if (m_pLuaContext != NULL) - { - lua_close(m_pLuaContext); - } -} - -int CLuaBridge::LuaDebugMessage(lua_State *pContext) -{ - const char *szFunction = NULL; - const char *szMessage = NULL; - lua_Debug LuaDebug = {0}; - - int n = lua_tonumber(pContext, 1); - szMessage = lua_tostring(pContext, 1); - - if (szMessage == NULL) - { - return FALSE; - } - - lua_getstack(pContext, 1, &LuaDebug); - lua_getinfo (pContext, "Snl", &LuaDebug); - - szFunction = LuaDebug.source; - - if (szFunction == NULL) - { - return FALSE; - } - - OutputDebugStringA("Smart Auto Replier : "); - OutputDebugStringA("("); - OutputDebugStringA(szFunction); - OutputDebugStringA("): "); - OutputDebugStringA(szMessage); - OutputDebugStringA("\r\n"); - - return TRUE; -} - -void CLuaBridge::HandleLuaAsssert(lua_State * pContext) -{ - DebugBreak(); -} - -bool CLuaBridge::RunScript(const char *szScript, size_t nLength, const char *szFuncName) -{ - bool bRetVal = false; - - if (szFuncName == NULL) - { - szFuncName = "SarFakeProcedure"; - } - - if (luaL_loadbuffer(m_pLuaContext, szScript, nLength, szFuncName) == 0) - { - bRetVal = (lua_pcall(m_pLuaContext, 0, LUA_MULTRET, 0) == 0); - } - - return bRetVal; -} - -bool CLuaBridge::ExecuteFunction(int nArgs, int nReturns) -{ - bool bRetVal = false; - - if (lua_isfunction(m_pLuaContext, -nArgs - 1)) - { - bRetVal = (lua_pcall(m_pLuaContext, nArgs, nReturns, 0) == FALSE); - } - - return bRetVal; -} - -CLuaBridge::operator lua_State *() -{ - return m_pLuaContext; -} \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/LuaBridge.h b/!NotAdopted/SmartAutoReplier/LuaBridge.h deleted file mode 100644 index f012a55db4..0000000000 --- a/!NotAdopted/SmartAutoReplier/LuaBridge.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This code is inspired by article of RichardS at http://www.codeproject.com/Articles/11508/Integrating-Lua-into-C - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -#include "luainc.h" - -class CLuaBridge -{ -public: - CLuaBridge(void); - ~CLuaBridge(void); - -public: - static int LuaDebugMessage(lua_State * pContext); - static void HandleLuaAsssert(lua_State * pContext); - - bool RunScript(const char *szScript, size_t nLength, const char *szFuncName = NULL); - bool ExecuteFunction(int nArgs, int nReturns = 0); - operator lua_State *(); - -protected: - lua_State *m_pLuaContext; -}; - -class CLuaStack -{ -public: - CLuaStack(CLuaBridge & luaBridge) : m_pState(NULL), m_nTopIndex(0) - { - m_pState = (lua_State*)luaBridge; - m_nTopIndex = lua_gettop(m_pState); - } - - virtual ~CLuaStack() - { - lua_settop(m_pState, m_nTopIndex); - } - -protected: - - lua_State *m_pState; - int m_nTopIndex; -}; - -class CLuaTableThis -{ -public: - CLuaTableThis(CLuaBridge & luaBridge, int nRef) : m_nOldRef(0), m_luaBridge(luaBridge) - { - lua_State *state = (lua_State*)m_luaBridge; - - lua_getglobal(state, "this"); - m_nOldRef = luaL_ref(state, LUA_REGISTRYINDEX); - - lua_rawgeti(state, LUA_REGISTRYINDEX, nRef); - lua_setglobal(state, "this"); - } - - virtual ~CLuaTableThis() - { - lua_State *state = (lua_State*)m_luaBridge; - - if (m_nOldRef > 0) - { - lua_rawgeti(state, LUA_REGISTRYINDEX, m_nOldRef); - lua_setglobal (state, "this"); - luaL_unref(state, LUA_REGISTRYINDEX, m_nOldRef); - } - } - -protected: - int m_nOldRef; - CLuaBridge & m_luaBridge; -}; - diff --git a/!NotAdopted/SmartAutoReplier/LuaScript.cpp b/!NotAdopted/SmartAutoReplier/LuaScript.cpp deleted file mode 100644 index 5ad1508d99..0000000000 --- a/!NotAdopted/SmartAutoReplier/LuaScript.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This code is inspired by article of RichardS at http://www.codeproject.com/Articles/11508/Integrating-Lua-into-C - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" - -#include -#include "luainc.h" -#include "luascript.h" - -#define LUA_CODE_CHUNK_ENTER(luaBridge) lua_State *state = (lua_State*)luaBridge; - -#define LUA_CODE_CHUNK_LEAVE - -CLuaScript::CLuaScript(CLuaBridge & luaBridge) : m_luaBridge(luaBridge), m_nMethods(DEFAULT_INDEX_INITIALIZER), m_nThisRef(DEFAULT_INDEX_INITIALIZER), m_nArgs(DEFAULT_INDEX_INITIALIZER) -{ -LUA_CODE_CHUNK_ENTER(luaBridge) - - lua_newtable(state); - m_nThisRef = luaL_ref(state, LUA_REGISTRYINDEX); - - CLuaStack luaStack(luaBridge); - lua_rawgeti(state, LUA_REGISTRYINDEX, m_nThisRef); - lua_pushlightuserdata(state, reinterpret_cast(this)); - lua_rawseti(state, -2, 0); - -LUA_CODE_CHUNK_LEAVE -} - -CLuaScript::~CLuaScript(void) -{ - CLuaStack luaStack(m_luaBridge); - -LUA_CODE_CHUNK_ENTER(m_luaBridge) - - lua_rawgeti(state, LUA_REGISTRYINDEX, m_nThisRef); - lua_pushnil(state); - lua_rawseti(state, -2, 0); - -LUA_CODE_CHUNK_LEAVE -} - -int CLuaScript::LuaCallback(lua_State *lua) -{ - int iNumberIdx = lua_upvalueindex(1); - int nRetsOnStack = 0; - - bool bRetVal = false; - - if (lua_istable(lua, 1)) - { - lua_rawgeti(lua, 1, 0); - - if (lua_islightuserdata(lua, -1)) - { - CLuaScript *pThis = reinterpret_cast(lua_touserdata(lua, -1)); - int nMethod = static_cast(lua_tonumber(lua, iNumberIdx)); - - assert(!(nMethod > pThis->MethodsCount())); - - lua_remove(lua, 1); lua_remove(lua, -1); - - nRetsOnStack = pThis->ScriptCalling(pThis->Bridge(), nMethod); - - bRetVal = true; - } - } - - if (bRetVal == false) - { - lua_error(lua); - } - - return nRetsOnStack; -} - -bool CLuaScript::CompileScript(const char *szScript, size_t nLength) -{ - CLuaTableThis luaThisTable(m_luaBridge, m_nThisRef); - - return m_luaBridge.RunScript(szScript, nLength); -} - -int CLuaScript::RegisterFunction(const char *szFuncName) -{ - int nMethod = -1; - - CLuaStack luaStack(m_luaBridge); - -LUA_CODE_CHUNK_ENTER(m_luaBridge) - - nMethod = ++m_nMethods; - - lua_rawgeti(state, LUA_REGISTRYINDEX, m_nThisRef); - lua_pushstring(state, szFuncName); - lua_pushnumber(state, (lua_Number)nMethod); - lua_pushcclosure(state, CLuaScript::LuaCallback, 1); - lua_settable(state, -3); - -LUA_CODE_CHUNK_LEAVE - - return nMethod; -} - -bool CLuaScript::SelectScriptFunction(const char *szFunction) -{ - bool bRetVal = true; - -LUA_CODE_CHUNK_ENTER(m_luaBridge) - - lua_rawgeti(state, LUA_REGISTRYINDEX, m_nThisRef); - lua_pushstring(state, szFunction); - lua_rawget(state, -2); - lua_remove(state, -2); - - lua_rawgeti(state, LUA_REGISTRYINDEX, m_nThisRef); - - if (!lua_isfunction(state, -2)) - { - bRetVal = false; - lua_pop(state, 2); - } - else - { - m_nArgs = 0; - m_szFunction = szFunction; - } - -LUA_CODE_CHUNK_LEAVE - - return bRetVal; -} - -bool CLuaScript::ScriptHasFunction(const char * szFunction) -{ - CLuaStack luaStack(m_luaBridge); - - bool bRetVal = false; - -LUA_CODE_CHUNK_ENTER(m_luaBridge) - - lua_rawgeti(state, LUA_REGISTRYINDEX, m_nThisRef); - lua_pushstring(state, szFunction); - lua_rawget(state, -2); - lua_remove(state, -2); - - bRetVal = (lua_isfunction(state, -1) != FALSE); - -LUA_CODE_CHUNK_LEAVE - - return bRetVal; -} - -void CLuaScript::AddParam(char * szValue) -{ -LUA_CODE_CHUNK_ENTER(m_luaBridge) - lua_pushstring(state, szValue); ++m_nArgs; -LUA_CODE_CHUNK_LEAVE -} - -void CLuaScript::AddParam(int nValue) -{ -LUA_CODE_CHUNK_ENTER(m_luaBridge) - lua_pushnumber(state, (lua_Number)nValue); ++m_nArgs; -LUA_CODE_CHUNK_LEAVE -} - -void CLuaScript::AddParam(float fValue) -{ -LUA_CODE_CHUNK_ENTER(m_luaBridge) - lua_pushnumber(state, (lua_Number)fValue); ++m_nArgs; -LUA_CODE_CHUNK_LEAVE -} - -bool CLuaScript::Run(int nRetValues) -{ - bool bRetVal = m_luaBridge.ExecuteFunction((m_nArgs + 1), nRetValues); - - if (bRetVal == true && nRetValues > 0) - { - HandleReturns(m_luaBridge, m_szFunction); - lua_pop(static_cast(m_luaBridge), nRetValues); - } - - return bRetVal; -} - -CLuaBridge & CLuaScript::Bridge() -{ - return m_luaBridge; -} - -int CLuaScript::MethodsCount() -{ - return m_nMethods; -} \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/LuaScript.h b/!NotAdopted/SmartAutoReplier/LuaScript.h deleted file mode 100644 index 73c29c0a3f..0000000000 --- a/!NotAdopted/SmartAutoReplier/LuaScript.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This code is inspired by article of RichardS at http://www.codeproject.com/Articles/11508/Integrating-Lua-into-C - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -#include "luainc.h" -#include "LuaBridge.h" - -/// -#define DEFAULT_INDEX_INITIALIZER 0 - -class CLuaScript -{ -public: - CLuaScript(CLuaBridge & luaBridge); - virtual ~CLuaScript(); - -public: - - static int LuaCallback (lua_State *lua); - bool CompileScript(const char *szScript, size_t nLength); - int RegisterFunction(const char *szFuncName); - bool SelectScriptFunction(const char *szFunction); - bool ScriptHasFunction(const char *szFunction); - bool Run(int nRetValues = 0); - -public: - void AddParam(int nValue); - void AddParam(float fValue); - void AddParam(char *szValue); - CLuaBridge & Bridge(); - - int MethodsCount(); - -public: - virtual int ScriptCalling(CLuaBridge & luaBridge, int nFunction) = 0; - virtual void HandleReturns(CLuaBridge & luaBridge, const char * szFunction) = 0; - -protected: - - CLuaBridge & m_luaBridge; - - const char * m_szFunction; - - int m_nMethods, - m_nThisRef, - m_nArgs; -}; \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/MessagesHandler.cpp b/!NotAdopted/SmartAutoReplier/MessagesHandler.cpp deleted file mode 100644 index 3f3e8e5ad5..0000000000 --- a/!NotAdopted/SmartAutoReplier/MessagesHandler.cpp +++ /dev/null @@ -1,469 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" -#include "messageshandler.h" -#include "SarLuaScript.h" -#include - -extern CCrushLog CRUSHLOGOBJ; - -/// init static members... -CMessagesHandler * CMessagesHandler::m_pThis = NULL; - -/// thread that is checking -/// users that sent messages, -/// analize sent time and if -/// reply delay is greater then -/// difference between current time and -/// sent time thread deletes item. -INT WINAPI ContactsFetcherThread(LPVOID lp) -{ -BEGIN_PROTECT_AND_LOG_CODE -#define SLEEP_TIME 50 - CMessagesHandler *pHolder = CMessagesHandler::GetObject(); - if (pHolder) - { - while (pHolder->m_bShouldWork) - { - WaitForSingleObject(pHolder->m_hEnableEvent, INFINITE); - if (!pHolder->m_bShouldWork) - break; - - EnterCriticalSection(&pHolder->m_critSect); - - if (pHolder->m_contacts.size() == 0) - { - LeaveCriticalSection(&pHolder->m_critSect); - Sleep (SLEEP_TIME); - continue; - } - - SYSTEMTIME sysTime = {0}; - FILETIME ft = {0}; - LARGE_INTEGER liNow = {0}; - - GetLocalTime (&sysTime); - SystemTimeToFileTime(&sysTime, &ft); - memcpy(&liNow, &ft, sizeof(liNow)); - - ContactsMap::iterator it; - - CONTACT_METAINFO rawm = {0}; - LARGE_INTEGER liDiff = {0}; - - for (it = pHolder->m_contacts.begin(); it != pHolder->m_contacts.end(); it++) - { - if (pHolder->m_contacts.size() == 0) - { - break; - } - rawm = it->second; - liDiff.QuadPart = liNow.QuadPart - rawm.StartTime.QuadPart; - if (liDiff.QuadPart >= rawm.DiffTime.QuadPart) - { - if (pHolder->m_contacts.size() == 1) - { - pHolder->m_contacts.clear(); - break; - } - else - pHolder->m_contacts.erase(it); - } - } - - LeaveCriticalSection(&pHolder->m_critSect); - - Sleep (SLEEP_TIME); - } - } -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -/// ctor of main plugin manager -CMessagesHandler::CMessagesHandler(void) : IMSingeltone(this), -m_hFetcherThread(NULL), -m_hEnableEvent(NULL), -m_bShouldWork(true), -m_bInited(false) -{ -BEGIN_PROTECT_AND_LOG_CODE - m_settings.Init(); -END_PROTECT_AND_LOG_CODE -} - -/// dtor of main plugin manager -CMessagesHandler::~CMessagesHandler(void) -{ -BEGIN_PROTECT_AND_LOG_CODE - m_settings.DeInit(); - m_bShouldWork = false; - CMessagesHandler::m_pThis = NULL; -END_PROTECT_AND_LOG_CODE -} - -/// enables or disables feature -void CMessagesHandler::MakeAction(bool bEnable) -{ -BEGIN_PROTECT_AND_LOG_CODE - REPLYER_SETTINGS & s = m_settings.getSettings(); - s.bEnabled = bEnable; - m_settings.setSettings(s); - - if (bEnable) - { - HookEvents(); - SetEvent (m_hEnableEvent); - } - else - UnHookEvents(); -END_PROTECT_AND_LOG_CODE -} - -bool CMessagesHandler::AllowReply(HANDLE hContact) -{ -BEGIN_PROTECT_AND_LOG_CODE - if (!m_settings.getSettings().bEnabled) - return FALSE; - ContactsMap::iterator it; - bool bRetVal = false; - - EnterCriticalSection(&m_critSect); - - it = m_contacts.find(hContact); - - SYSTEMTIME sysTime = {0}; - FILETIME ft = {0}; - GetLocalTime (&sysTime); - SystemTimeToFileTime(&sysTime, &ft); - - if (it == m_contacts.end()) - { /// no such contact... - CONTACT_METAINFO cm = {0}; - - memcpy(&cm.StartTime, &ft, sizeof(cm.StartTime)); - cm.DiffTime.QuadPart = m_settings.getSettings().ReplayDelay * nano100SecInSec; - ContactsPair p(hContact, cm); - - m_contacts.insert(p); - bRetVal = true; - } - else - { /// there is one... - memcpy(&it->second.StartTime, &ft, sizeof(it->second.StartTime)); - } - - LeaveCriticalSection(&m_critSect); - - return bRetVal; -END_PROTECT_AND_LOG_CODE - return false; -} - -void CMessagesHandler::HookEvents(void) -{ -BEGIN_PROTECT_AND_LOG_CODE -#ifdef _DEBUG -#endif - - InitializeCriticalSection(&m_critSect); - m_settings.Init(); -#ifdef _DEBUG - bool bEnabled = m_settings.getSettings().bEnabled; -#endif - m_hEnableEvent = CreateEvent(NULL, TRUE, m_settings.getSettings().bEnabled, NULL); - - DWORD dw = 0; - m_bShouldWork = true; - m_hFetcherThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ContactsFetcherThread, NULL, NULL, &dw); - m_hEvents[0] = HookEvent(ME_DB_EVENT_ADDED, CMessagesHandler::EventAddHook); - m_bInited = true; -END_PROTECT_AND_LOG_CODE -} - -void CMessagesHandler::UnHookEvents(void) -{ -BEGIN_PROTECT_AND_LOG_CODE - m_bShouldWork = false; - if (!m_bInited) - return; - SetEvent(m_hEnableEvent); - - for (size_t i = 0; i < HOOKS_NUM; i++) - UnhookEvent(m_hEvents[i]); - - WaitForSingleObject(m_hFetcherThread, INFINITE); - DeleteCriticalSection(&m_critSect); - CloseHandle(m_hEnableEvent); - //m_settings.DeInit(); - - m_hEnableEvent = NULL; - m_hFetcherThread = NULL; - -END_PROTECT_AND_LOG_CODE -} - -LPTSTR CMessagesHandler::GetContactName(HANDLE hContact) -{ - LPARAM lFlags = GCDNF_NOMYHANDLE; - -#ifdef _UNICODE - lFlags |= GCDNF_UNICODE; -#endif -BEGIN_PROTECT_AND_LOG_CODE - return reinterpret_cast(CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, lFlags)); -END_PROTECT_AND_LOG_CODE - return NULL; -} - -int CMessagesHandler::SendProtoMess(HANDLE hContact, LPCSTR szMess) -{ -BEGIN_PROTECT_AND_LOG_CODE - return CallContactService(hContact, PSS_MESSAGE, 0, reinterpret_cast(szMess)); -END_PROTECT_AND_LOG_CODE - return 0; -} - -/** Convert unicode to ansi (utf16 to utf8) - - * @return ansi string or null -*/ -char* Utf16toUtf8(LPCWSTR lpwszStrIn, UINT & nSize) -{ - LPSTR pszOut = NULL; - - if (lpwszStrIn != NULL) - { - -#define SAFE_DELTA 2 - - int nInputStrLen = (int)wcslen(lpwszStrIn); - int nOutputStrLen = WideCharToMultiByte(CP_UTF8, 0, lpwszStrIn, nInputStrLen, NULL, 0, 0, 0); - - if (nOutputStrLen == 0) - { - return NULL; - } - - nOutputStrLen += SAFE_DELTA; - - pszOut = (LPSTR)malloc(nOutputStrLen); - - if (pszOut) - { - nSize = nOutputStrLen - SAFE_DELTA; - memset(pszOut, 0x00, nOutputStrLen); - - WideCharToMultiByte(CP_UTF8, 0, lpwszStrIn, nInputStrLen, pszOut, nOutputStrLen, 0, 0); - } - } - - return pszOut; -} - -/** Convert unicode to ansi (utf16 to utf8) - - * @return ansi string or null -*/ -wchar_t* Utf8toUtf16(CHAR * szStrIn, UINT & nSize) -{ - wchar_t * pszOut = NULL; - - if (szStrIn != NULL) - { - -#define SAFE_DELTA 2 - - int nInputStrLen = (int)nSize; - int nOutputStrLen = MultiByteToWideChar(CP_UTF8, 0, szStrIn, nInputStrLen, NULL, 0); - - if (nOutputStrLen == 0) - { - return NULL; - } - - nOutputStrLen += SAFE_DELTA; - - pszOut = (wchar_t*)malloc(nOutputStrLen * sizeof(wchar_t)); - - if (pszOut) - { - nSize = nOutputStrLen - SAFE_DELTA; - memset(pszOut, 0x00, nOutputStrLen * sizeof(wchar_t)); - - MultiByteToWideChar(CP_UTF8, 0, szStrIn, nInputStrLen, pszOut, nOutputStrLen); - } - } - - return pszOut; -} - -/// this handle is invoked wnen -/// event is added to db -int CMessagesHandler::EventAddHook(WPARAM wp, LPARAM lp) -{ -BEGIN_PROTECT_AND_LOG_CODE - DWORD dwOffset = static_cast (lp); - HANDLE hContact = reinterpret_cast(wp); - DBEVENTINFO dbei; - - if (!hContact || !dwOffset) - { - return FALSE; /// unspecifyed error - } - - ZeroMemory(&dbei, sizeof(dbei)); - dbei.cbSize = sizeof(dbei); - dbei.cbBlob = 0; - - CallService(MS_DB_EVENT_GET, lp, (LPARAM)&dbei); /// detect size of msg - - if ((dbei.eventType != EVENTTYPE_MESSAGE) || (dbei.flags == DBEF_READ) || (dbei.flags == DBEF_SENT) ) - { - return FALSE; /// we need EVENTTYPE_MESSAGE event.. - } - else - { /// needed event has occured.. - if (!dbei.cbBlob) /// invalid size - { - return FALSE; - } - - dbei.pBlob = new BYTE[dbei.cbBlob]; - - if (dbei.pBlob) - { - LPARAM lParam = GCDNF_NOMYHANDLE; - -#ifdef _UNICODE - lParam |= GCDNF_UNICODE; -#endif - CallService(MS_DB_EVENT_GET, lp, reinterpret_cast(&dbei)); - - TCHAR * szMessage = DbGetEventTextT(&dbei, 0); - - TCHAR * szContactName = reinterpret_cast(CallService(MS_CLIST_GETCONTACTDISPLAYNAME, wp, lParam)); - - CMessagesHandler *ptrHolder = NULL; - ptrHolder = CMessagesHandler::GetObject(); - - if (!szContactName || !ptrHolder) - { - return FALSE; - } - - if (!ptrHolder->AllowReply(hContact)) - { - return FALSE; - } - - TCHAR * lpMessage = NULL; - - { - RULE_METAINFO inf = {0}; - inf.ContactName = szContactName; - - /// analizes all rules and formes autoreply - /// message - it's stored in lpMessage - /// then - just sent it to user - CSettingsHandler & settingsManager = ptrHolder->getSettings(); - settingsManager.getStorage().IsRuleMatch(inf, lpMessage, szMessage); - - { - /// do the lua trick - CLuaBridge luaBridge; - CSarLuaScript script(luaBridge); - - UINT nReplyScriptLength = 0; - CHAR * szReplyScript = NULL; - - szReplyScript = Utf16toUtf8(lpMessage, nReplyScriptLength); - - if (szReplyScript != NULL) - { - UINT nUserMessage = 0; - CHAR * szUserMessage = Utf16toUtf8(szMessage, nUserMessage); - - UINT nUserName = 0; - CHAR * szUserName = Utf16toUtf8(szContactName, nUserName); - - script.CompileScript(szReplyScript, nReplyScriptLength); - - script.SelectScriptFunction("SAR"); - script.AddParam((int)hContact); - script.AddParam(szUserMessage); - script.AddParam(szUserName); - script.AddParam((char*)dbei.szModule); - script.Run(); - - free(szReplyScript); - free(szUserMessage); - free(szUserName); - } - } - - mir_free(szMessage); - - delete lpMessage; - delete dbei.pBlob; - - return FALSE; - } - } - } - -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -void CMessagesHandler::WriteToHistory(LPTSTR lpMsg, HANDLE hContact) -{ - LPTSTR lp1 = TranslateTS(TEXT("Generated autoreply:\r\n")); - - LPTSTR lpszMess = new TCHAR[_tcslen(lpMsg) + _tcslen(lp1)]; - if (lpszMess == NULL) - return; - - memset(lpszMess, 0, (_tcslen(lpMsg) + _tcslen(lp1)) * sizeof(TCHAR)); - _tcscpy(lpszMess, lp1); - _tcscat(lpszMess, lpMsg); - - DBEVENTINFO dbei = {0}; - dbei.cbSize = sizeof(dbei); - dbei.eventType = EVENTTYPE_MESSAGE; - dbei.flags = DBEF_READ; - dbei.szModule = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact, 0); - dbei.timestamp = time(NULL); - dbei.cbBlob = _tcslen(lpszMess) + 1; - dbei.pBlob = (PBYTE)lpszMess; - CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei); - - delete lpszMess; -} - -/// getting settings.. -CSettingsHandler & CMessagesHandler::getSettings(void) -{ -BEGIN_PROTECT_AND_LOG_CODE - return m_settings; -END_PROTECT_AND_LOG_CODE -} \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/MessagesHandler.h b/!NotAdopted/SmartAutoReplier/MessagesHandler.h deleted file mode 100644 index 2d9240f0d5..0000000000 --- a/!NotAdopted/SmartAutoReplier/MessagesHandler.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -#include "settingshandler.h" -#include "interfaces\ISingletone.h" - -#include -using namespace std; - -typedef struct _CONTACT_METAINFO -{ - LARGE_INTEGER StartTime; - LARGE_INTEGER DiffTime; -}CONTACT_METAINFO,*PCONTACT_METAINFO; - -typedef std::map ContactsMap; -typedef std::pair ContactsPair; -const __int64 nano100SecInSec = (__int64)10000000; - -/// hooks def... -#define HOOKS_NUM 1 - -INT WINAPI ContactsFetcherThread(LPVOID lp); - -class CMessagesHandler : public IMSingeltone -{ - friend INT WINAPI ContactsFetcherThread(LPVOID lp); -public: - CMessagesHandler(void); - ~CMessagesHandler(void); -public: - void HookEvents(void); - void UnHookEvents(void); - void WriteToHistory(LPTSTR lpMsg, HANDLE hContact); - CSettingsHandler & getSettings(void); - bool AllowReply(HANDLE hContact); - void MakeAction(bool bEnable); - static LPTSTR GetContactName(HANDLE hContact); - static int SendProtoMess(HANDLE hContact, LPCSTR szMess); -protected: // hooks procs - static int EventAddHook(WPARAM wp, LPARAM lp); -private: - bool m_bInited; -private: - HANDLE m_hEvents[HOOKS_NUM]; - CSettingsHandler m_settings; - ContactsMap m_contacts; - CRITICAL_SECTION m_critSect; - HANDLE m_hFetcherThread; - HANDLE m_hEnableEvent; - bool m_bShouldWork; -}; \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/ModeMessHandler.cpp b/!NotAdopted/SmartAutoReplier/ModeMessHandler.cpp deleted file mode 100644 index 5509bea091..0000000000 --- a/!NotAdopted/SmartAutoReplier/ModeMessHandler.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" -#include "modemesshandler.h" - -/// TODO: add comments and change char* to TCHAR* !!! - -/// ctor -CModeMessHandler::CModeMessHandler(void) -{ -} - -/// dtor -CModeMessHandler::~CModeMessHandler(void) -{ -} - -TCHAR * CModeMessHandler::StatusModeToDbSetting(int status, TCHAR *suffix) -{ - LPTSTR prefix; - static TCHAR str[64] = {0}; - - switch(status) { - case ID_STATUS_AWAY: prefix = TEXT("Away"); break; - case ID_STATUS_NA: prefix = TEXT("Na"); break; - case ID_STATUS_DND: prefix = TEXT("Dnd"); break; - case ID_STATUS_OCCUPIED: prefix = TEXT("Occupied"); break; - case ID_STATUS_FREECHAT: prefix = TEXT("FreeChat"); break; - case ID_STATUS_ONLINE: prefix = TEXT("On"); break; - case ID_STATUS_OFFLINE: prefix = TEXT("Off"); break; - case ID_STATUS_INVISIBLE: prefix = TEXT("Inv"); break; - case ID_STATUS_ONTHEPHONE: prefix = TEXT("Otp"); break; - case ID_STATUS_OUTTOLUNCH: prefix = TEXT("Otl"); break; - default: - return NULL; - } - lstrcpy(str, prefix); - _tcscat(str, suffix); - - return str; -} - -LPTSTR CModeMessHandler::GetDefaultMessage(INT status) -{ - switch (status) - { - case ID_STATUS_AWAY: return TranslateTS(TEXT("I've been away since %time%.")); - case ID_STATUS_NA: return TranslateTS(TEXT("Give it up, I'm not in!")); - case ID_STATUS_OCCUPIED: return TranslateTS(TEXT("Not right now.")); - case ID_STATUS_DND: return TranslateTS(TEXT("Give a guy some peace, would ya?")); - case ID_STATUS_FREECHAT: return TranslateTS(TEXT("Well, I would talk to you if Miranda IM supported chat")); - case ID_STATUS_ONLINE: return TranslateTS(TEXT("Yep, I'm here.")); - case ID_STATUS_OFFLINE: return TranslateTS(TEXT("Nope, not here.")); - case ID_STATUS_INVISIBLE: return TranslateTS(TEXT("I'm hiding from the mafia.")); - case ID_STATUS_ONTHEPHONE: return TranslateTS(TEXT("That'll be the phone.")); - case ID_STATUS_OUTTOLUNCH: return TranslateTS(TEXT("Mmm...food.")); - } - return NULL; -} - -/// returnes mode message -/// looks like ret. val should be free(), but -/// read notes in the place where this func is used -LPTSTR CModeMessHandler::GetModeMessage(INT statusMode) -{ - /*DBVARIANT dbv = {0}; - INT nretVal = {0}; /// suppose failure.. - - nretVal = DBGetContactSetting(NULL, TCHAR("SRAway"), StatusModeToDbSetting(statusMode, TCHAR("Msg")), &dbv); - if (nretVal) /// unable to get away msg... - { - dbv.pszVal = _tcsdup(GetDefaultMessage(statusMode)); - if (dbv.pszVal == NULL) /// maybe will occure ;) - { - DBGetContactSetting(NULL, TCHAR("SRAway"), StatusModeToDbSetting(statusMode, TCHAR("Default")), &dbv); - } - } - - int i; - TCHAR substituteStr[128] = {0}; - for(i = 0; dbv.pszVal[i]; i++) - { - if (dbv.pszVal[i] != '%') - continue; - if (!_tcsncicmp((TCHAR*)dbv.pszVal+i, TEXT("%time%"), 6)) - GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, NULL, NULL, substituteStr, sizeof(substituteStr) / sizeof (TCHAR)); - else if (!_tcsncicmp((TCHAR*)dbv.pszVal+i, TEXT("%date%"), 6)) - GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, substituteStr, sizeof(substituteStr) / sizeof(TCHAR)); - else - continue; - if (_tcslen(substituteStr) > 6) - dbv.pszVal = ((TCHAR*))realloc((TCHAR*)dbv.pszVal, _tcslen((TCHAR*)dbv.pszVal) + 1 + _tcslen(substituteStr) - 6); - MoveMemory(dbv.pszVal + i + _tcslen(substituteStr), dbv.pszVal + i + 6, _tcslen(dbv.pszVal) - i - 5); - CopyMemory(dbv.pszVal + i, substituteStr, _tcslen(substituteStr)); - }*/ - - //return dbv.pszVal; - - return NULL; -} \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/ModeMessHandler.h b/!NotAdopted/SmartAutoReplier/ModeMessHandler.h deleted file mode 100644 index 87931ba487..0000000000 --- a/!NotAdopted/SmartAutoReplier/ModeMessHandler.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -class CModeMessHandler -{ -public: - CModeMessHandler(void); - ~CModeMessHandler(void); -public: - static LPTSTR GetModeMessage(INT nMode); -private: - static LPTSTR GetDefaultMessage(INT status); - static TCHAR *StatusModeToDbSetting(int status, TCHAR *suffix); -}; diff --git a/!NotAdopted/SmartAutoReplier/RuleItem.h b/!NotAdopted/SmartAutoReplier/RuleItem.h deleted file mode 100644 index dd7bfa7549..0000000000 --- a/!NotAdopted/SmartAutoReplier/RuleItem.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -#include "interfaces\isettings.h" - -/// a typical rule item -/// contains info to reply to specific user -typedef struct _RULE_ITEM : ISettingsStream -{ - LPTSTR RuleName, /// item name - ContactName, /// contact name - ReplyText; /// reply text - /*ReplyAction; /// reply action*/ -}RULE_ITEM, *PRULE_ITEM; - -/// common item... - a rule that is -/// applied to all users. -typedef struct _COMMON_RULE_ITEM : ISettingsStream -{ - //LPTSTR Header; - LPTSTR Message; -}COMMON_RULE_ITEM, *P_COMMON_RULE_ITEM; - -typedef struct _RULE_METAINFO -{ - LPTSTR ContactName; -}RULE_METAINFO, *PRULE_METAINFO; diff --git a/!NotAdopted/SmartAutoReplier/RulesStorage.cpp b/!NotAdopted/SmartAutoReplier/RulesStorage.cpp deleted file mode 100644 index 6b4f6a2ab0..0000000000 --- a/!NotAdopted/SmartAutoReplier/RulesStorage.cpp +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" -#include "rulesstorage.h" -#include "crc32static.h" - -extern HINSTANCE hInst; -extern CCrushLog CRUSHLOGOBJ; -extern CMessagesHandler * g_pMessHandler; - -/// ctor... -CRulesStorage::CRulesStorage(void) : m_hFile(NULL) -{ - m_comItem.Message = NULL; -BEGIN_PROTECT_AND_LOG_CODE - MakeFullPath(m_szSettFileName, sizeof(m_szSettFileName), STORAGE_NAME); - InitializeCriticalSection(&m_critSect); -END_PROTECT_AND_LOG_CODE -} - -/// dtor... -CRulesStorage::~CRulesStorage(void) -{ -BEGIN_PROTECT_AND_LOG_CODE - DeleteCriticalSection(&m_critSect); - DeInit(); -END_PROTECT_AND_LOG_CODE -} - -bool CRulesStorage::Serialize(ISettingsStream *pSettings, DWORD & ObjectSize) -{ -BEGIN_PROTECT_AND_LOG_CODE - Flush(); -END_PROTECT_AND_LOG_CODE - return true; -} - -bool CRulesStorage::Deserialize(DWORD & ObjectSize) -{ -BEGIN_PROTECT_AND_LOG_CODE - Init(); -END_PROTECT_AND_LOG_CODE - return false; -} - -/// deiniting... -void CRulesStorage::DeInit(void) -{ -BEGIN_PROTECT_AND_LOG_CODE - if (m_hFile && m_hFile != INVALID_HANDLE_VALUE) - CloseHandle(m_hFile); - - m_hFile = NULL; - - /// now release memory... - for (RulesHash::iterator it = m_hashTable.begin(); it != m_hashTable.end(); it++) - { - RULE_ITEM & i = it->second; - - delete i.ContactName; - delete i.ReplyText; - delete i.RuleName; - } - - m_hashTable.clear(); - - if (m_comItem.Message != NULL) - { - delete m_comItem.Message; - m_comItem.Message = NULL; - } - -END_PROTECT_AND_LOG_CODE -} - -/// writing a string into a file.. -void CRulesStorage::RawWriteDataBufByChunk(LPTSTR str) -{ -BEGIN_PROTECT_AND_LOG_CODE - int nLength = _tcslen(str) * sizeof(TCHAR); - DWORD dwWritten = 0; - BOOL bVal = FALSE; - - bVal = WriteFile(m_hFile, &nLength, sizeof(nLength), &dwWritten, NULL); - - if (!bVal || dwWritten != sizeof(nLength)) - throw bVal; - - bVal = WriteFile(m_hFile, str, nLength, &dwWritten, NULL); - if (!bVal || nLength != dwWritten) - { - throw bVal; - } -END_PROTECT_AND_LOG_CODE -} - -/// flushing all data from memory into a file... -void CRulesStorage::Flush(void) -{ -BEGIN_PROTECT_AND_LOG_CODE - RulesHash::iterator it; - - SetFilePointer(m_hFile, NULL, NULL, FILE_BEGIN); - SetEndOfFile(m_hFile); /// clear old data - - SetCommonMessages(); - - for (it = m_hashTable.begin(); it != m_hashTable.end(); it++) - { - FlushItem(it->second); - } - -END_PROTECT_AND_LOG_CODE -} - -/// n.c. -bool CRulesStorage::IsRuleMatch(RULE_METAINFO & info, LPTSTR & strMess, LPTSTR & lpIncomingMsg) -{ -BEGIN_PROTECT_AND_LOG_CODE - EnterCriticalSection(&m_critSect); - - RulesHash::iterator iter; - bool bExists = false; - DWORD dwCRC32 = 0; - CCrc32Static::StringCrc32(info.ContactName, dwCRC32); - iter = m_hashTable.find(dwCRC32); - - CScriptsReader & screader = g_pMessHandler->getSettings().getScriptsReader(); - - if (iter != m_hashTable.end()) - { - /// I have to make copy of ReplyText, - /// cause GetReturnedMessage will release ptr - /// that is stored rule - /// found this bug after 20 min. of debugging ;( - strMess = new TCHAR[_tcslen(iter->second.ReplyText) + (1 * sizeof(TCHAR))]; - - if (strMess == NULL) /// ooops... - { - //screader.GetReturnMessage(info.ContactName, strMess, lpIncomingMsg); - LeaveCriticalSection(&m_critSect); - - return false; - } - - memset(strMess, 0, _tcslen(iter->second.ReplyText) * sizeof(TCHAR) + (1 * sizeof(TCHAR))); - _tcscpy(strMess, iter->second.ReplyText); - bExists = true; - //screader.GetReturnMessage(iter->second.ContactName, strMess, lpIncomingMsg); - } - else - screader.GetReturnMessage(info.ContactName, strMess, lpIncomingMsg); - - LeaveCriticalSection(&m_critSect); - return bExists; -END_PROTECT_AND_LOG_CODE - return false; -} - -/// adding rule into memory... -DWORD CRulesStorage::AddRuleItem(RULE_ITEM item, bool & bExists) -{ -BEGIN_PROTECT_AND_LOG_CODE - DWORD dwCRC32 = NULL; - CCrc32Static::StringCrc32(item.ContactName, dwCRC32); - RulesHash::iterator iter; - iter = m_hashTable.find(dwCRC32); - - if (iter != m_hashTable.end()) - { - bExists = true; - return 0; - } - - bExists = false; - - m_hashTable.insert(RulesHash::value_type(dwCRC32, item)); - return dwCRC32; -END_PROTECT_AND_LOG_CODE - return 0; -} - -/// flushing item... -void CRulesStorage::FlushItem(RULE_ITEM & item) -{ -BEGIN_PROTECT_AND_LOG_CODE - RawWriteDataBufByChunk(item.RuleName); - RawWriteDataBufByChunk(item.ContactName); - RawWriteDataBufByChunk(item.ReplyText); - //RawWriteDataBufByChunk(item.ReplyAction); -END_PROTECT_AND_LOG_CODE -} - -/// initing rules manager... -void CRulesStorage::Init(void) -{ -#ifdef _DEBUG - //MessageBox (NULL, __FUNCTION__, __FILE__, MB_OK); -#endif -BEGIN_PROTECT_AND_LOG_CODE - if (m_hFile) - CloseHandle (m_hFile); - - bool bFileExists = true; - if (!PathFileExists(m_szSettFileName)) - {/// file does not exists... - /// need to fill it with common rules... - bFileExists = false; - } - - m_hFile = CreateFile (m_szSettFileName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, (bFileExists ? OPEN_ALWAYS : CREATE_ALWAYS), FILE_ATTRIBUTE_NORMAL, NULL); - - if (m_hFile == INVALID_HANDLE_VALUE) - {/// show notification msg to user.. - throw INVALID_HANDLE_VALUE; - } - - if (bFileExists == false) - { - ClearCommonMessages(); - m_comItem.Message = new TCHAR[sizeof(SETTINGS_DEF_MESSAGE) / sizeof(TCHAR) + sizeof(TCHAR)]; - - if (m_comItem.Message != NULL) - { - memset(m_comItem.Message, 0, sizeof(SETTINGS_DEF_MESSAGE) / sizeof(TCHAR) + sizeof(TCHAR)); - _tcscpy(m_comItem.Message, SETTINGS_DEF_MESSAGE); - SetCommonMessages(); - } - } - - DWORD dwSize = 0; - dwSize = GetFileSize(m_hFile, &dwSize); - - DWORD dwReaded = 0, - dwCrc32 = 0; - - int nLength = 0; - - /// suppose that func is failed - BOOL bReaded = FALSE; - bool bFailed = false; - - if (bFileExists) - { - dwSize -= GetCommonMessages(); - } - else - { - dwSize -= _tcslen(SETTINGS_DEF_MESSAGE) * sizeof(TCHAR); - dwSize -= 1 * sizeof(int); - } - - while (dwSize) - { - RULE_ITEM it; - - bReaded = ReadFile(m_hFile, &nLength, sizeof(nLength), &dwReaded, NULL); - - if (bReaded == FALSE || dwReaded != sizeof(nLength)) - { - bFailed = true; - break; - } - - dwSize -= sizeof(nLength); - it.RuleName = new TCHAR[nLength / sizeof(TCHAR) + (1 * sizeof(TCHAR))]; - - if (it.RuleName == NULL) - { - bFailed = true; - break; - } - - memset(it.RuleName, 0, (nLength + (1 * sizeof(TCHAR)))); - - bReaded = ReadFile(m_hFile, it.RuleName, nLength, &dwReaded, NULL); - if (bReaded == FALSE || dwReaded != (nLength)) - { - delete it.RuleName; - bFailed = true; - break; - } - - dwSize -= dwReaded; - bReaded = ReadFile(m_hFile, &nLength, sizeof(nLength), &dwReaded, NULL); - - if (bReaded == FALSE || dwReaded != sizeof(nLength)) - { - delete it.RuleName; - bFailed = true; - break; - } - - dwSize -= sizeof(nLength); - it.ContactName = new TCHAR[nLength / sizeof(TCHAR) + (1 * sizeof(TCHAR))]; - - if (it.ContactName == NULL) - { - delete it.RuleName; - bFailed = true; - break; - } - - memset(it.ContactName, 0, (nLength + (1 * sizeof(TCHAR)))); - bReaded = ReadFile(m_hFile, it.ContactName, nLength, &dwReaded, NULL); - - if (bReaded == FALSE || dwReaded != (nLength)) - { - delete it.RuleName; - delete it.ContactName; - bFailed = true; - break; - } - - dwSize -= dwReaded; - bReaded = ReadFile (m_hFile, &nLength, sizeof(nLength), &dwReaded, NULL); - - if (bReaded == FALSE || dwReaded != sizeof(nLength)) - { - delete it.RuleName; - delete it.ContactName; - bFailed = true; - break; - } - - dwSize -= sizeof(nLength); - it.ReplyText = new TCHAR[nLength / sizeof(TCHAR) + (1 * sizeof(TCHAR))]; - - if (it.ReplyText == NULL) - { - delete it.RuleName; - delete it.ContactName; - bFailed = true; - break; - } - - memset(it.ReplyText, 0, (nLength + (1 * sizeof(TCHAR)))); - bReaded = ReadFile (m_hFile, it.ReplyText, nLength, &dwReaded, NULL); - - if (bReaded == FALSE || dwReaded != (nLength)) - { - delete it.RuleName; - delete it.ContactName; - delete it.ReplyText; - - bFailed = true; - break; - } - - dwSize -= dwReaded; - - dwCrc32 = NULL; - CCrc32Static::StringCrc32(it.ContactName, dwCrc32); - m_hashTable.insert(RulesHash::value_type(dwCrc32, it) ); /// filling list - } - - if (bFailed) - { /// upps... - bool bdelete = NotifyAboutWrongSettings(m_szSettFileName); - - if (bdelete) - { - CloseHandle (m_hFile); - m_hFile = NULL; - DeleteFile (m_szSettFileName); - DeInit(); - Init(); - } - } - -END_PROTECT_AND_LOG_CODE -} - -/// reading an data from file storage... -UINT CRulesStorage::RawReadDataBufByChunk(LPTSTR & szData) -{ -BEGIN_PROTECT_AND_LOG_CODE - UINT nRetVal = 0; - - if (m_hFile == NULL || m_hFile == INVALID_HANDLE_VALUE) - { - return nRetVal; - } - - int nSizeOf = 0; - DWORD dwReaded = 0; - const int nsizeof = sizeof(nSizeOf); - BOOL bReaded = ReadFile(m_hFile, &nSizeOf, nsizeof, &dwReaded, NULL); - nRetVal += dwReaded; - - if (bReaded == FALSE || dwReaded != nsizeof) - { - return nRetVal; - } - - szData = new TCHAR[(nSizeOf / sizeof(TCHAR)) + (1 * sizeof(TCHAR))]; - - if (szData == NULL) - { - return nRetVal + dwReaded; - } - - memset(szData, 0, nSizeOf + (1 * sizeof(TCHAR))); - bReaded = ReadFile(m_hFile, szData, nSizeOf, &dwReaded, NULL); - nRetVal += dwReaded; - - if (bReaded == FALSE || dwReaded != nSizeOf) - { - delete szData; - szData = NULL; - return nRetVal; - } - - return nRetVal; -END_PROTECT_AND_LOG_CODE -} - -/// -void CRulesStorage::SetCommonMessages(void) -{ -BEGIN_PROTECT_AND_LOG_CODE - RawWriteDataBufByChunk(m_comItem.Message); -END_PROTECT_AND_LOG_CODE -} - -void CRulesStorage::ClearCommonMessages(void) -{ - if (m_comItem.Message) - { - delete m_comItem.Message; - m_comItem.Message = NULL; - } -} - -/// reads from storage common rules - header and -/// message that is replyed to all users... -UINT CRulesStorage::GetCommonMessages(void) -{ -BEGIN_PROTECT_AND_LOG_CODE - ClearCommonMessages(); - UINT nRetVal = 0; - - nRetVal += RawReadDataBufByChunk(m_comItem.Message); - - return nRetVal; -END_PROTECT_AND_LOG_CODE -#undef RAW_DATACLEAR - return 0; -} - -void CRulesStorage::setCommonRule(COMMON_RULE_ITEM r) /// n.c. -{ -BEGIN_PROTECT_AND_LOG_CODE - memcpy (&m_comItem, &r, sizeof(COMMON_RULE_ITEM)); -END_PROTECT_AND_LOG_CODE -} - -COMMON_RULE_ITEM & CRulesStorage::getCommonRule(void) /// n.c. -{ -BEGIN_PROTECT_AND_LOG_CODE - return m_comItem; -END_PROTECT_AND_LOG_CODE -} - -/// getting hash table -RulesHash & CRulesStorage::getHashTable(void) -{ -BEGIN_PROTECT_AND_LOG_CODE - return m_hashTable; -END_PROTECT_AND_LOG_CODE -} - -/// remove rule by its id -bool CRulesStorage::RemReplyAction(DWORD dwCrc32) -{ - bool bRetVal = false; -BEGIN_PROTECT_AND_LOG_CODE - EnterCriticalSection(&m_critSect); - RulesHash::iterator it; - it = m_hashTable.find(dwCrc32); - if (it != m_hashTable.end()) - { - delete it->second.ContactName; - delete it->second.ReplyText; - delete it->second.RuleName; - - m_hashTable.erase(it); - bRetVal = true; - } - LeaveCriticalSection(&m_critSect); -END_PROTECT_AND_LOG_CODE - return bRetVal; -} - -bool CRulesStorage::RuleIsRegistered(LPTSTR lpContactName) -{ -BEGIN_PROTECT_AND_LOG_CODE - bool bRetVal = false; - if (lpContactName == NULL) - return bRetVal; - DWORD dwCRC32 = NULL; - CCrc32Static::StringCrc32(lpContactName, dwCRC32); - RulesHash::iterator iter; - - EnterCriticalSection(&m_critSect); - iter = m_hashTable.find(dwCRC32); - - if (iter != m_hashTable.end()) - { - bRetVal = true; - } - LeaveCriticalSection(&m_critSect); - - return bRetVal; -END_PROTECT_AND_LOG_CODE - return false; -} \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/RulesStorage.h b/!NotAdopted/SmartAutoReplier/RulesStorage.h deleted file mode 100644 index 25cbec2942..0000000000 --- a/!NotAdopted/SmartAutoReplier/RulesStorage.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -#include "RuleItem.h" -#include - -#define STORAGE_NAME TEXT("sar.rsu") /// a def. name of a file that is storing settings -typedef std::map RulesHash; /// storage representation in memory - -/// storage manager.. -class CRulesStorage : ISettings -{ -public: /// ctor'rs, dtors.. - CRulesStorage(void); - ~CRulesStorage(void); -public: /// ISettings interface... - bool Serialize(ISettingsStream *pSettings, DWORD & ObjectSize); - bool Deserialize(DWORD & ObjectSize); -public: - void Init(void); /// initing state of an object - void DeInit(void); /// deiniting state of an object - DWORD AddRuleItem(RULE_ITEM item, bool & bExists); /// n.c. - bool RemReplyAction(DWORD dwCrc32); /// n.c. - RulesHash & getHashTable(void); /// n.c. - COMMON_RULE_ITEM & getCommonRule(void); /// n.c. - void setCommonRule(COMMON_RULE_ITEM r); /// n.c. - void Flush(void); /// flushes all from memory to a file - void FlushItem(RULE_ITEM & item); /// flushes an item into file from memory - bool IsRuleMatch(RULE_METAINFO & info, LPTSTR & strMess, LPTSTR & lpIncomingMsg); /// n.c. - void ClearCommonMessages(void); /// releases memory that is commited for comm. rule - bool RuleIsRegistered(LPTSTR lpContactName); -private: - void RawWriteDataBufByChunk(LPTSTR); /// writes string to a file - UINT RawReadDataBufByChunk(LPTSTR & szData); /// reads string from file - UINT GetCommonMessages(void); /// gets common rules from file to memory - void SetCommonMessages(void); /// sets common rules from memory to file -private: - COMMON_RULE_ITEM m_comItem; /// common rule item.. - RulesHash m_hashTable; /// main storage... - HANDLE m_hFile; /// handle to file that is storing data - TCHAR m_szSettFileName[MAX_PATH]; /// path to a file... - CRITICAL_SECTION m_critSect; /// needed for sync -}; \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/SAR.cpp b/!NotAdopted/SmartAutoReplier/SAR.cpp deleted file mode 100644 index a2617b496b..0000000000 --- a/!NotAdopted/SmartAutoReplier/SAR.cpp +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" -#include "resource.h" - -/// these dlg are necessary here.. -#include "gui\settingsdlgholder.h" -#include "gui\EditReplyDlg.h" -#include "gui\addruledlg.h" - -#include "../updater/m_updater.h" - -/// let's advertise myselft and this plugin ;) -#define ICQPROTONAME "SAR" -#if defined( _UNICODE ) -#define ICQPROTODECRSHORT "Smart Auto Replier" -#else -#define ICQPROTODECRSHORT "Smart Auto Replier" -#endif -#define ICQPROTODECR "Plugin is able to reply on all incoming messages, making possible use of rules that are applied to specific contacts. Plugin allows to use Lua scripts as a rules, thus allowing user to make virtually any type of customizations." -#define DEVNAME "Volodymyr M. Shcherbyna" -#define DEVMAIL "volodymyr@shcherbyna.com" -#define DEVCOPYRIGHT "© 2004-2012 Volodymyr M. Shcherbyna, www.shcherbyna.com" -#define DEVWWW "http://www.shcherbyna.com/forum/viewforum.php?f=8" -#define GLOB_HOOKS 3 - -/// global menu items strings... -#define MENU_ITEM_DISABLE_CAPTION TranslateTS(TEXT("Disable Smart Auto Replier")) -#define MENU_ITEM_ENABLE_CAPTION TranslateTS(TEXT("Enable Smart Auto Replier")) - -//#define -/// global data... -HINSTANCE hInst = NULL; /// hinstance -PLUGINLINK *pluginLink = NULL; /// ptr to plugin object -CMessagesHandler *g_pMessHandler = NULL; /// ptr to "main" global manager object -CSettingsDlgHolder *g_pSettingsDlg = NULL; -static HANDLE g_hHook[GLOB_HOOKS] = {NULL}; /// global hooks -CLISTMENUITEM g_mi = {NULL}; /// handle to menu item that is used to switch on/off plugin -CLISTMENUITEM g_miAUR2This = {NULL}; /// handle to menu item that is used to add user to aur -bool g_bEnableMItem = true; /// flag for menu item.. -HANDLE g_hMenuItem; /// global handle to menu service -CCrushLog CRUSHLOGOBJ; /// global object that handles all crushes -LPTSTR g_strPluginName = TEXT(ICQPROTONAME); /// global string that represents plugin name... -INT g_nCurrentMode = 0; /// current mode of a protocol == i duno which exactly protocol... -HANDLE g_hAUR2User = NULL; /// handle to proto service of "autoreply to this user" - -struct MM_INTERFACE mmi; - -/// forming an info structure -PLUGININFOEX pluginInfo = -{ - sizeof(PLUGININFOEX), - ICQPROTODECRSHORT, - PLUGIN_MAKE_VERSION(2, 0, 0, 3), - ICQPROTODECR, - DEVNAME, - DEVMAIL, - DEVCOPYRIGHT, - DEVWWW, - UNICODE_AWARE, - 0, -//#if defined( _UNICODE ) -// // {B9C9AC38-9D81-45D3-A9D7-67A7D8EA9D29} -// { 0xb9c9ac38, 0x9d81, 0x45d3, { 0xa9, 0xd7, 0x67, 0xa7, 0xd8, 0xea, 0x9d, 0x29 } } -//#else - // {9E536082-017E-423B-BF4F-DEDFEB9B3B60} - { 0x9e536082, 0x17e, 0x423b, { 0xbf, 0x4f, 0xde, 0xdf, 0xeb, 0x9b, 0x3b, 0x60 } } -//#endif -}; - -/// mapping into mirandaim.exe -BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) -{ -BEGIN_PROTECT_AND_LOG_CODE - hInst = hinstDLL; - DisableThreadLibraryCalls(hinstDLL); - return TRUE; -END_PROTECT_AND_LOG_CODE -} - -__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) -{ - return &pluginInfo; -} - -extern "C" __declspec(dllexport) const MUUID interfaces[] = {MIID_CHAT, MIID_SRMM, MIID_LAST}; - -__declspec(dllexport) const MUUID * MirandaPluginInterfaces(void) -{ - return interfaces; -} - -/// handler of event when the options are choosed -static int OptionsInitialized(WPARAM wp, LPARAM lp) -{ -BEGIN_PROTECT_AND_LOG_CODE - LPTSTR lpszGroup = TranslateTS(TEXT("Plugins")); - OPTIONSDIALOGPAGE optsDialog = {0}; - optsDialog.cbSize = sizeof(OPTIONSDIALOGPAGE); - optsDialog.hInstance = hInst; - optsDialog.position = 910000000; - optsDialog.pszTemplate = (char*)MAKEINTRESOURCE(IDD_SDLGHOLDER); - TCHAR szMax[MAX_PATH] = {0}; - _tcscpy(szMax, TranslateTS(TEXT(ICQPROTODECRSHORT))); - -#ifdef _UNICODE - optsDialog.ptszGroup = lpszGroup; - optsDialog.ptszTitle = szMax; -#else - optsDialog.pszTitle = (char*)szMax; - optsDialog.pszGroup = lpszGroup; -#endif - optsDialog.pfnDlgProc = (DLGPROC)&CSettingsDlgHolder::FakeDlgProc; - optsDialog.flags = ODPF_BOLDGROUPS/*|ODPF_EXPERTONLY*/; /// some lames are scaring that option... -#ifdef _UNICODE - optsDialog.flags |= ODPF_UNICODE; -#endif - - g_pSettingsDlg->m_bDestroying = false; - CallService(MS_OPT_ADDPAGE, wp, reinterpret_cast(&optsDialog)); -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -/// pre building menu item for a contact.. -static int AURContactPreBuildMenu(WPARAM wParam, LPARAM lParam) -{ - LPTSTR lpContactName = g_pMessHandler->GetContactName(reinterpret_cast(wParam)); - CRulesStorage & storage = g_pMessHandler->getSettings().getStorage(); - bool bval = storage.RuleIsRegistered(lpContactName); - - if (bval) - { - g_miAUR2This.flags = CMIM_FLAGS | CMIF_GRAYED; - } - else - { - g_miAUR2This.flags = CMIM_FLAGS; - } - - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hAUR2User, (LPARAM)&g_miAUR2This); - - return 0; -} - -/// handler of clicking on menu item -/// aur to this user... -static int AUR2User(WPARAM wParam, LPARAM lParam) -{ - CAddRuleDlg dlg; - RULE_ITEM item; - item.ContactName = g_pMessHandler->GetContactName(reinterpret_cast(wParam)); - //item.ReplyAction = " "; - item.ReplyText = SETTINGS_DEF_MESSAGE_RULE; - TCHAR rulename[MAX_PATH * 5] = {0}; - _tcscat(rulename, TEXT("reply to ")); - _tcscat(rulename, item.ContactName); - item.RuleName = rulename; - - dlg.m_baur2thisMode = true; - dlg.m_item = item; - dlg.DoModal(); - if (dlg.m_bAddedOk) - { /// already added... - OnRefreshSettings(); - } - - return 0; -} - -/// handler of clicking on menu item enablr/disable plugin... -static int PluginMenuCommand(WPARAM wParam, LPARAM lParam) -{ -BEGIN_PROTECT_AND_LOG_CODE - if (!g_pMessHandler) - return 0; - - if (g_bEnableMItem) - {/// lets handle enabling of AUR feature - g_pMessHandler->MakeAction(true); /// this will enable plugin - } - else - {/// lets handle disabling of AUR feature - g_pMessHandler->MakeAction(false); /// this will disable plugin - } - - /// put here stuff to do - TCHAR sz[MAX_PATH] = {0}; - _tcscpy(sz, (g_bEnableMItem == true ? MENU_ITEM_DISABLE_CAPTION : MENU_ITEM_ENABLE_CAPTION)); - g_mi.pszName = (char*)TranslateTS(sz); - g_mi.flags = CMIM_NAME; - -#ifdef _UNICODE - g_mi.flags |= CMIF_UNICODE; -#endif - -#ifdef _DEBUG - int nretval = -#endif - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hMenuItem, (LPARAM)&g_mi); - - g_bEnableMItem = !g_bEnableMItem; -END_PROTECT_AND_LOG_CODE - return 0; -} - -/// handler that is invoked when mode is changed -static int OnStatusModeChanged(WPARAM wp, LPARAM lp) -{ -BEGIN_PROTECT_AND_LOG_CODE - g_nCurrentMode = static_cast(wp); - if (!g_pMessHandler) - return FALSE; - - bool bNonOnOffLine = (wp != ID_STATUS_ONLINE && - wp != ID_STATUS_OFFLINE && - wp != ID_STATUS_FREECHAT); - - REPLYER_SETTINGS & s = g_pMessHandler->getSettings().getSettings(); - COMMON_RULE_ITEM & r = g_pMessHandler->getSettings().getStorage().getCommonRule(); - - if (!bNonOnOffLine && s.bDisableWhenModeIsSet) - { - if (s.bEnabled) /// plugin is enabled... we have a chance to disable it - { - bool bDisableIt = false; - - if (s.ModeDisValue == 0) - bDisableIt = true; - else if (s.ModeDisValue == 1 && wp == ID_STATUS_ONLINE) - bDisableIt = true; - else if (s.ModeDisValue == 2 && wp == ID_STATUS_FREECHAT) - bDisableIt = true; - - if (bDisableIt) - { /// disable plugin... - PluginMenuCommand(0, 0); - } - } - return FALSE; - } - - if (s.bShowAURDlgWhenModeChanges) - { - CEditReplyDlg dlg; - dlg.m_commRule = r; - - dlg.DoModal(); - if (dlg.m_bAllOk) - { - r = dlg.m_commRule; - } - } - if (s.bEnableWhenModeIsSet) - { - if (!s.bEnabled) - { - bool bEnable = false; - if (s.ModeValue == 0 && bNonOnOffLine) - bEnable = true; - else if (s.ModeValue == 1 && wp == ID_STATUS_DND) - bEnable = true; - else if (s.ModeValue == 2 && wp == ID_STATUS_NA) - bEnable = true; - else if (s.ModeValue == 3 && wp == ID_STATUS_AWAY) - bEnable = true; - else if (s.ModeValue == 4 && wp == ID_STATUS_OCCUPIED) - bEnable = true; - - if (bEnable) /// enabling plugin... (I realize that enabling and disabling is made via ass but i am lazy today) - PluginMenuCommand(0, 0); - } - } - - return FALSE; -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -#ifndef _DEBUG -LPTOP_LEVEL_EXCEPTION_FILTER UnhandledExceptionFilter( - LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter -) -{ - LPTOP_LEVEL_EXCEPTION_FILTER f = {0}; -BEGIN_PROTECT_AND_LOG_CODE - throw f; /// show msgbox to user and store inf to file -END_PROTECT_AND_LOG_CODE - return f; /// let compiler shut ups... -} -#endif - -int OnModulesLoaded(WPARAM wParam, LPARAM lParam) -{ - Update update = {0}; // for c you'd use memset or ZeroMemory... - char szVersion[16]; - - update.cbSize = sizeof(Update); - - update.szComponentName = pluginInfo.shortName; - update.pbVersion = (BYTE*)CreateVersionStringPluginEx(&pluginInfo, szVersion); - update.cpbVersion = strlen((char*)update.pbVersion); - - // these are the three lines that matter - the archive, the page containing the version string, and the text (or data) - // before the version that we use to locate it on the page - // (note that if the update URL and the version URL point to standard file listing entries, the backend xml - // data will be used to check for updates rather than the actual web page - this is not true for beta urls) - //update.szUpdateURL = "http://www.shcherbyna.com/files/sar/SAR.zip"; - //update.szVersionURL = "http://www.shcherbyna.com/files/sar/SAR.html"; - - update.szUpdateURL = "http://addons.miranda-im.org/details.php?action=viewfile&id=1609"; - - //update.pbVersionPrefix = (BYTE *)"SAR version "; - - //update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix); - - // do the same for the beta versions of the above struct members if you wish to allow beta updates from another URL - - CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update); - - // Alternatively, to register a plugin with e.g. file ID 2254 on the file listing... - // CallService(MS_UPDATE_REGISTERFL, (WPARAM)2254, (LPARAM)&pluginInfo); - - return 0; -} - -/// loading plugin -extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) -{ -#ifndef _DEBUG - SetUnhandledExceptionFilter(UnhandledExceptionFilter); -#endif -#ifdef _DEBUG - //MessageBox (NULL, __FUNCTION__, __FILE__, MB_OK); -#endif - - CCrushLog::Init(); /// crushes manager should be inited first - int nRetVal = 0; -BEGIN_PROTECT_AND_LOG_CODE - pluginLink = link; - -#ifndef _DEBUG - /// creates help file near plugin - /// if it is absent... - /// note: originally help is in recources of plugin - //CheckForHelpFile(); -#endif - /// main manager... - g_pMessHandler = new CMessagesHandler(); - g_pSettingsDlg = new CSettingsDlgHolder(); - - if (g_pMessHandler) - { /// is inited - REPLYER_SETTINGS & s = g_pMessHandler->getSettings().getSettings(); - if (s.bDisableWhenMirandaIsOn) - { - s.bEnabled = false; - } - else - { - if (s.bEnabled) - g_pMessHandler->HookEvents(); - } - - /// hook main events - //HookEvent(MS_AWAYMSG_SHOWAWAYMSG, OnShow - g_hHook[0] = HookEvent(ME_OPT_INITIALISE, OptionsInitialized); - g_hHook[1] = HookEvent(ME_CLIST_STATUSMODECHANGE, OnStatusModeChanged); - g_hHook[2] = HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded); - - /// Yushenko Tak, Yanukovich - Mudak. (Orange revolution) - /// this was written in 2004-2005 in Kiev :) - - /// create menu item for disabling / enabling plugin - CreateServiceFunction("AUR/MenuCommand", PluginMenuCommand); - ZeroMemory(&g_mi, sizeof(g_mi)); - g_mi.cbSize = sizeof(g_mi); - g_mi.position = -0x7FFFFFFF; - g_mi.flags = 0; - g_mi.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_SAR_ICON)); //LoadSkinnedIcon(IDI_AUR_ICON/*SKINICON_OTHER_MIRANDA*/); - bool bVal = g_pMessHandler->getSettings().getSettings().bEnabled; - TCHAR sz[MAX_PATH] = {0}; - _tcscpy(sz, bVal ? MENU_ITEM_DISABLE_CAPTION : MENU_ITEM_ENABLE_CAPTION); -#ifdef _UNICODE - g_mi.ptszName = TranslateTS(sz); - g_mi.flags = CMIF_UNICODE; -#else - g_mi.pszName = (char*)TranslateTS(sz); -#endif - g_mi.pszService = "AUR/MenuCommand"; - - g_hMenuItem = (HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&g_mi); - g_bEnableMItem = !bVal; - - /// creating menu item for a contact - ZeroMemory(&g_miAUR2This, sizeof(g_miAUR2This)); - g_miAUR2This.cbSize = sizeof(g_miAUR2This); - g_miAUR2This.position = -2000010000; - g_miAUR2This.flags = 0; - g_miAUR2This.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_SAR_ICON)); - g_miAUR2This.pszContactOwner = NULL; -#ifdef _UNICODE - g_miAUR2This.ptszName = TranslateTS(TEXT("&Smart Auto Reply to this user ...")); - g_miAUR2This.flags = CMIF_UNICODE; -#else - g_miAUR2This.pszName = TranslateTS(TEXT("&Smart Auto Reply to this user ...")); -#endif - CreateServiceFunction("AUR/AURToThis", AUR2User); - g_miAUR2This.pszService = "AUR/AURToThis"; - g_hAUR2User = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&g_miAUR2This); - HookEvent(ME_CLIST_PREBUILDCONTACTMENU, AURContactPreBuildMenu); - } - - CallService(MS_SYSTEM_GET_MMI, 0, (LPARAM)&mmi); - -END_PROTECT_AND_LOG_CODE - return FALSE; -} - -/// unloading plugin -extern "C" int __declspec(dllexport) Unload(void) -{ -BEGIN_PROTECT_AND_LOG_CODE - for (size_t i = 0; i < GLOB_HOOKS; i++) - UnhookEvent(g_hHook[i]); - - if (g_pSettingsDlg) - { - if (g_pSettingsDlg->IsWindow()) - g_pSettingsDlg->DestroyWindow(); - delete g_pSettingsDlg; - } - if (g_pMessHandler) - { /// unhook manager's events... - g_pMessHandler->UnHookEvents(); - delete g_pMessHandler; /// call dtor - g_pMessHandler = NULL; - } -END_PROTECT_AND_LOG_CODE - - CCrushLog::DeInit(); /// destroy crushes manager obj - return FALSE; -} diff --git a/!NotAdopted/SmartAutoReplier/SAR.rc b/!NotAdopted/SmartAutoReplier/SAR.rc deleted file mode 100644 index 5ae222d012..0000000000 --- a/!NotAdopted/SmartAutoReplier/SAR.rc +++ /dev/null @@ -1,274 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Ukrainian (Ukraine) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_UKR) -LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT -#pragma code_page(1251) - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_OPTIONS DIALOGEX 0, 0, 308, 208 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - EDITTEXT IDC_EDIT_REPLAYDELAY,68,10,29,13,ES_MULTILINE | ES_AUTOHSCROLL | ES_WANTRETURN | ES_NUMBER - EDITTEXT IDC_EDIT_MESSAGE,68,24,232,53,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL - LISTBOX IDC_LIST_RULES,60,84,236,61,LBS_SORT | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Add rule",IDC_BTN_ADDRULE,8,85,50,14 - PUSHBUTTON "Delete rule",IDC_BTN_DELRULE,8,101,50,14,WS_DISABLED - PUSHBUTTON "Edit rule",IDC_BTN_EDITRULE,8,117,50,14,WS_DISABLED - LTEXT "Action script:",IDC_STATIC_MESSAGE_TEXT,8,42,51,10 - GROUPBOX "Auto replier settings",IDC_STATIC,0,0,306,204 - LTEXT "Reply delay:",IDC_STATIC,9,12,41,8 - LTEXT "second(s)",IDC_STATIC,106,13,32,8 - GROUPBOX "Custom rules",IDC_STATIC,5,75,294,73 - CONTROL "Disable when Miranda is switched on",IDC_CHECK_DISABLEWMON, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,149,12,151,11 - CONTROL "Enable when status becomes",IDC_CH_ENABLE_WSCH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,152,125,10 - COMBOBOX IDC_CB_ENWSC,144,151,156,36,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Ask to set autoreply message when mode changes",IDC_CH_SHOWCG, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,180,266,10 - CONTROL "Disable when status becomes",IDC_CH_DISWHSB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,167,129,10 - COMBOBOX IDC_CB_DWSB,143,165,156,40,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Save autoreplies to history",IDC_CH_SAVE_AURS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,193,266,10 -END - -IDD_ADDRULE_DLG DIALOGEX 0, 0, 384, 250 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Add contact specific Smart Auto Replier action script" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - EDITTEXT IDC_ED_RULENAME,68,14,184,12,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL - EDITTEXT IDC_ED_RULECNAME,68,29,168,13,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL - EDITTEXT IDC_ED_RULEREPLY,21,54,342,166,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL - DEFPUSHBUTTON "OK",IDOK,325,231,50,14 - PUSHBUTTON "Cancel",IDCANCEL,273,231,50,14 - PUSHBUTTON "...",IDC_BTN_SELUSER,238,28,13,14 - GROUPBOX "Rule settings",IDC_STATIC,7,3,368,225 - LTEXT "Rule name:",IDC_STATIC,15,16,41,10 - LTEXT "Contact name",IDC_STATIC,15,31,46,10 - GROUPBOX "Action script",IDC_STATIC,14,42,355,182 -END - -IDD_SET_AURMESSAGEDLG DIALOGEX 0, 0, 291, 157 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Set Smart Auto Replier action script" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - EDITTEXT IDC_ED_TEXT,6,10,278,123,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL - DEFPUSHBUTTON "OK",IDOK,239,139,50,14 - PUSHBUTTON "Cancel",IDCANCEL,186,139,50,14 - GROUPBOX "Smart Auto Replier action script",IDC_STATIC,2,0,287,137 -END - -IDD_SEL_USER DIALOGEX 0, 0, 92, 194 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Select user from a list" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - DEFPUSHBUTTON "Select",IDOK,51,178,40,14 - PUSHBUTTON "Exit",IDCANCEL,1,178,38,14 - LISTBOX IDC_LIST_USERS,1,2,89,174,LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP -END - -IDD_HISTORYLOGS DIALOGEX 0, 0, 186, 95 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Dialog" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - DEFPUSHBUTTON "OK",IDOK,129,7,50,14 - PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 -END - -IDD_SDLGHOLDER DIALOGEX 0, 0, 326, 253 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - CONTROL "",IDC_TABSHOLDER,"SysTabControl32",0x0,4,13,316,224 - LTEXT "Static",IDC_STATUSMSG,7,3,300,8 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_OPTIONS, DIALOG - BEGIN - LEFTMARGIN, 7 - TOPMARGIN, 3 - BOTTOMMARGIN, 195 - END - - IDD_ADDRULE_DLG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 377 - TOPMARGIN, 7 - BOTTOMMARGIN, 247 - END - - IDD_SET_AURMESSAGEDLG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 284 - TOPMARGIN, 7 - BOTTOMMARGIN, 150 - END - - IDD_SEL_USER, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 85 - TOPMARGIN, 7 - BOTTOMMARGIN, 187 - END - - IDD_HISTORYLOGS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 179 - TOPMARGIN, 7 - BOTTOMMARGIN, 88 - END - - IDD_SDLGHOLDER, DIALOG - BEGIN - LEFTMARGIN, 2 - RIGHTMARGIN, 302 - TOPMARGIN, 3 - BOTTOMMARGIN, 237 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_SAR_ICON ICON "sar.ico" -#endif // Ukrainian (Ukraine) resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// French (Switzerland) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRS) -LANGUAGE LANG_FRENCH, SUBLANG_FRENCH_SWISS -#pragma code_page(1252) - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,0,0,3 - PRODUCTVERSION 2,0,0,3 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x0L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "042204b0" - BEGIN - VALUE "CompanyName", "Volodymyr Shcherbyna, www.shcherbyna.com" - VALUE "FileDescription", "Smart Auto Replier plugin for Miranda IM, http://shcherbyna.com/forum/viewforum.php?f=8" - VALUE "FileVersion", "2.0.0.3" - VALUE "InternalName", "sar.dll" - VALUE "LegalCopyright", "Copyright (C) 2004 - 2012 by Volodymyr Shcherbyna" - VALUE "OriginalFilename", "sar.dll" - VALUE "ProductName", "sar.dll" - VALUE "ProductVersion", "2.0.0.3" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x422, 1200 - END -END - -#endif // French (Switzerland) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/!NotAdopted/SmartAutoReplier/SAR.vcxproj b/!NotAdopted/SmartAutoReplier/SAR.vcxproj deleted file mode 100644 index 3091d45ae8..0000000000 --- a/!NotAdopted/SmartAutoReplier/SAR.vcxproj +++ /dev/null @@ -1,189 +0,0 @@ -п»ї - - - - Debug - Win32 - - - Release - Win32 - - - Template - Win32 - - - - {C71749EF-EBA8-4317-9F9E-327E1A7366EC} - Win32Proj - SAR - - - - DynamicLibrary - MultiByte - true - - - DynamicLibrary - Static - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - Debug\ - Debug\ - true - Release\ - Release\ - false - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - ..\lualib;..\wtl\Include;$(IncludePath) - ..\wtl\Include;$(IncludePath) - - - - Disabled - C:\Users\vshcherbyna\Downloads\aur\wtl\Include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;SAR_EXPORTS;UNICODE;_UNICODE - true - EnableFastChecks - MultiThreadedDebug - Use - Level3 - EditAndContinue - - - D:\Projects\smart-auto-replier\sar\Debug\lualib.lib;shell32.lib;comctl32.lib;%(AdditionalDependencies) - C:\Program Files (x86)\Miranda IM\Plugins\Sar.dll - true - $(OutDir)SAR.pdb - Windows - 0x40000000 - false - - - $(OutDir)SAR.lib - MachineX86 - sar.def - - - - - MinSpace - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;SAR_EXPORTS;UNICODE;_UNICODE;%(PreprocessorDefinitions) - MultiThreaded - Use - Level3 - ProgramDatabase - - - $(OutDir)$(TargetName)$(TargetExt) - true - Windows - true - true - 0x40000000 - false - - - $(OutDir)SAR.lib - MachineX86 - D:\Projects\smart-auto-replier\sar\Release\lualib.lib;%(AdditionalDependencies) - sar.def - - - - - sar.def - - - - - - - - - - - - - - - - - - Create - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/SAR.vcxproj.filters b/!NotAdopted/SmartAutoReplier/SAR.vcxproj.filters deleted file mode 100644 index 8c8e9d59f4..0000000000 --- a/!NotAdopted/SmartAutoReplier/SAR.vcxproj.filters +++ /dev/null @@ -1,77 +0,0 @@ -п»ї - - - - - - - - - - - - - - - - - - - - Lua - - - Lua - - - Lua - - - - - - - - - - - - - - - - - - - - - - - - - - Lua - - - Lua - - - Lua - - - Lua - - - - - - - - {f3d54a11-21ba-4f12-b8c0-8576228a1625} - - - - - - - \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/SarLuaScript.cpp b/!NotAdopted/SmartAutoReplier/SarLuaScript.cpp deleted file mode 100644 index d83f82c51d..0000000000 --- a/!NotAdopted/SmartAutoReplier/SarLuaScript.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This code is inspired by article of RichardS at http://www.codeproject.com/Articles/11508/Integrating-Lua-into-C - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" -#include "SarLuaScript.h" - -#include "../miranda32/m_protomod.h" -#include "../miranda32/m_protosvc.h" - -extern INT g_nCurrentMode; -extern CMessagesHandler *g_pMessHandler; - -wchar_t* Utf8toUtf16(CHAR * szStrIn, UINT & nSize); -char* Utf16toUtf8(LPCWSTR lpwszStrIn, UINT & nSize); - -CSarLuaScript::CSarLuaScript(CLuaBridge & luaBridge) : CLuaScript(luaBridge) -{ - m_nFuncBaseIndex = RegisterFunction("SendMessage"); - - RegisterFunction("GetMyStatus"); - RegisterFunction("SetMyStatus"); - RegisterFunction("Wait"); - RegisterFunction("FindUser"); - RegisterFunction("SetVariable"); - RegisterFunction("GetVariable"); -} - -CSarLuaScript::~CSarLuaScript(void) -{ -} - -int CSarLuaScript::ScriptCalling(CLuaBridge & luaBridge, int nFncNumber) -{ - switch (nFncNumber - m_nFuncBaseIndex) - { - case 0: - return SendMessage(luaBridge); - - case 1: - return GetMyStatus(luaBridge); - - case 2: - return SetMyStatus(luaBridge); - - case 3: - return Wait(luaBridge); - - case 4: - return FindUser(luaBridge); - - case 5: - return SetVariable(luaBridge); - - case 6: - return GetVariable(luaBridge); - } - - return FALSE; -} - -int CSarLuaScript::SendMessage(CLuaBridge & luaBridge) -{ - lua_State *pFunctionContext = (lua_State*)luaBridge; - - UINT nMessageLen = lua_strlen(pFunctionContext, -1); - const char * szMessage = lua_tostring(pFunctionContext, -1); - int hUserToken = (int)lua_tonumber(pFunctionContext, -2); - - if (szMessage == NULL) - { - return FALSE; - } - - int nRetVal = 0; - -#ifdef _UNICODE - /*/// as I am in unicode, I have to convert all strings from utf8 to utf16 :) - wchar_t * szwMessage = Utf8toUtf16((char*)szMessage, nMessageLen);*/ - - nRetVal = CallContactService((HANDLE)hUserToken, PSS_MESSAGE, PREF_UTF, reinterpret_cast(szMessage)); - - /*free(szwMessage);*/ -#else - nRetVal = CallContactService((HANDLE)hUserToken, PSS_MESSAGE, 0, reinterpret_cast(szMessage)); -#endif - - return FALSE; -} - -int CSarLuaScript::GetMyStatus(CLuaBridge & luaBridge) -{ - lua_State *pFunctionContext = (lua_State*)luaBridge; - int nStatusMode = CallService(MS_CLIST_GETSTATUSMODE, (WPARAM)0, (LPARAM)0); - - nStatusMode = g_nCurrentMode; - - switch (nStatusMode) - { - case ID_STATUS_ONLINE: - AddParam("Online"); - break; - - case ID_STATUS_OFFLINE: - AddParam("Offline"); - break; - - case ID_STATUS_AWAY: - AddParam("Away"); - break; - - case ID_STATUS_DND: - AddParam("DND"); - break; - - case ID_STATUS_NA: - AddParam("NA"); - break; - - case ID_STATUS_OCCUPIED: - AddParam("Occupied"); - break; - - case ID_STATUS_FREECHAT: - AddParam("FreeChat"); - break; - - case ID_STATUS_INVISIBLE: - AddParam("Invisible"); - break; - - case ID_STATUS_ONTHEPHONE: - AddParam("OnThePhone"); - break; - - case ID_STATUS_OUTTOLUNCH: - AddParam("OutToLunch"); - break; - - default: - AddParam("Unknown"); - break; - } - - return TRUE; -} - -int CSarLuaScript::SetMyStatus(CLuaBridge & luaBridge) -{ - int nNewStatus = 0; - lua_State *pFunctionContext = (lua_State*)luaBridge; - - const char * szStatus = lua_tostring(pFunctionContext, -1); - - if (szStatus == NULL) - { - return FALSE; - } - - if (strcmp(szStatus, "Online") == 0) - { - nNewStatus = ID_STATUS_ONLINE; - } - else if (strcmp(szStatus, "Offline") == 0) - { - nNewStatus = ID_STATUS_OFFLINE; - } - else if (strcmp(szStatus, "Away") == 0) - { - nNewStatus = ID_STATUS_AWAY; - } - else if (strcmp(szStatus, "DND") == 0) - { - nNewStatus = ID_STATUS_DND; - } - else if (strcmp(szStatus, "NA") == 0) - { - nNewStatus = ID_STATUS_NA; - } - else if (strcmp(szStatus, "Occupied") == 0) - { - nNewStatus = ID_STATUS_OCCUPIED; - } - else if (strcmp(szStatus, "FreeChat") == 0) - { - nNewStatus = ID_STATUS_FREECHAT; - } - else if (strcmp(szStatus, "Invisible") == 0) - { - nNewStatus = ID_STATUS_INVISIBLE; - } - else if (strcmp(szStatus, "OnThePhone") == 0) - { - nNewStatus = ID_STATUS_ONTHEPHONE; - } - else if (strcmp(szStatus, "OutToLunch") == 0) - { - nNewStatus = ID_STATUS_OUTTOLUNCH; - } - - CallService(MS_CLIST_SETSTATUSMODE, (WPARAM)nNewStatus, (LPARAM)0); - - return FALSE; -} - -typedef map MapOfStrings; - -MapOfStrings g_MapOfVariables; - -int CSarLuaScript::SetVariable(CLuaBridge & luaBridge) -{ - lua_State *pFunctionContext = (lua_State*)luaBridge; - - UINT nNameLength = lua_strlen(pFunctionContext, -2); - const char * szName = lua_tostring(pFunctionContext, -2); - - UINT nVariableLength = lua_strlen(pFunctionContext, -1); - const char * szVariable = lua_tostring(pFunctionContext, -1); - - if (szName == NULL || szVariable == NULL) - { - return FALSE; - } - - wchar_t * szwName = Utf8toUtf16((char*)szName, nNameLength); - wchar_t * szwVariable = Utf8toUtf16((char*)szVariable, nVariableLength); - - if (szwName && szwVariable) - { - g_MapOfVariables[szwName] = szwVariable; - } - - if (szwName) - { - free(szwName); - } - - if (szwVariable) - { - free(szwVariable); - } - - return FALSE; -} - -int CSarLuaScript::GetVariable(CLuaBridge & luaBridge) -{ - lua_State *pFunctionContext = (lua_State*)luaBridge; - - UINT nNameLength = lua_strlen(pFunctionContext, -1); - const char * szName = lua_tostring(pFunctionContext, -1); - - if (szName == NULL) - { - return FALSE; - } - - wchar_t * szwName = Utf8toUtf16((char*)szName, nNameLength); - - if (szwName) - { - MapOfStrings::iterator it = g_MapOfVariables.find(szwName); - - if (it != g_MapOfVariables.end()) - { - UINT nSize = 0; - char * szUtf = Utf16toUtf8(it->second.c_str(), nSize); - - if (szUtf != NULL) - { - AddParam(szUtf); - free(szUtf); - free(szwName); - - return TRUE; - } - } - } - - if (szwName) - { - free(szwName); - } - - return FALSE; -} - -int CSarLuaScript::Wait(CLuaBridge & luaBridge) -{ - lua_State *pFunctionContext = (lua_State*)luaBridge; - - int nSleepInterval = (int)lua_tonumber(pFunctionContext, -1); - - Sleep(1000 * nSleepInterval); - - return FALSE; -} - -int CSarLuaScript::FindUser(CLuaBridge & luaBridge) -{ - lua_State *pFunctionContext = (lua_State*)luaBridge; - - const CHAR * szUser = (CHAR*)lua_tostring(pFunctionContext, -2); - const CHAR * szProtocol = (CHAR*)lua_tostring(pFunctionContext, -1); - - if (szProtocol == NULL || szUser == NULL) - { - return FALSE; - } - - HANDLE hContact = reinterpret_cast(CallService(MS_DB_CONTACT_FINDFIRST, 0, 0)); - CHAR* szContactName = NULL; - CHAR* szProto = NULL; - DWORD wId = 0; - - while (hContact != NULL) - { - szContactName = reinterpret_cast(CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_NOMYHANDLE)); - szProto = (CHAR*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - - if (szProto && szContactName) - { - if ( (strcmp(szUser, szContactName)) == 0 && (strcmp(szProto, szProtocol) == 0)) - { - AddParam((int)hContact); - return TRUE; - } - } - - hContact = reinterpret_cast (CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM) hContact, 0)); - } - - return FALSE; -} - -void CSarLuaScript::HandleReturns(CLuaBridge & luaBridge, const char *szFunc) -{ - -} \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/SarLuaScript.h b/!NotAdopted/SmartAutoReplier/SarLuaScript.h deleted file mode 100644 index 26b9ba1a61..0000000000 --- a/!NotAdopted/SmartAutoReplier/SarLuaScript.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This code is inspired by article of RichardS at http://www.codeproject.com/Articles/11508/Integrating-Lua-into-C - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -#include "LuaBridge.h" -#include "LuaScript.h" - -#include -#include - -using namespace std; - -class CSarLuaScript : public CLuaScript -{ -public: - CSarLuaScript(CLuaBridge & luaBridge); - ~CSarLuaScript(void); - -private: - int SendMessage(CLuaBridge & luaBridge); - int GetMyStatus(CLuaBridge & luaBridge); - int SetMyStatus(CLuaBridge & luaBridge); - int Wait(CLuaBridge & luaBridge); - int FindUser(CLuaBridge & luaBridge); - int SetVariable(CLuaBridge & luaBridge); - int GetVariable(CLuaBridge & luaBridge); - -protected: - int ScriptCalling(CLuaBridge & luaBridge, int nFncNumber); - - void HandleReturns(CLuaBridge & luaBridge, const char *szFunc); - -protected: - int m_nFuncBaseIndex; -}; - diff --git a/!NotAdopted/SmartAutoReplier/ScriptsReader.cpp b/!NotAdopted/SmartAutoReplier/ScriptsReader.cpp deleted file mode 100644 index 4bd45d22e6..0000000000 --- a/!NotAdopted/SmartAutoReplier/ScriptsReader.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" -#include "scriptsreader.h" -#include "messageshandler.h" -#include "modemesshandler.h" - -extern INT g_nCurrentMode; -extern CMessagesHandler * g_pMessHandler; - -/// ctor -CScriptsReader::CScriptsReader(void) -{ -} - -/// dtor -CScriptsReader::~CScriptsReader(void) -{ -} - -/// dtor -void CScriptsReader::InternalInit(void) -{ -} - -ACTIONS CScriptsReader::ParceString(LPTSTR & strMessage) -{ - ACTIONS act; - return act; -} - -bool CScriptsReader::Replace(LPSTR & lpString, LPSTR strReplWhat, LPSTR & strReplWith) -{ -BEGIN_PROTECT_AND_LOG_CODE - if (strcmp(lpString, strReplWhat) == 0) - { - strcpy(lpString, strReplWith); - return true; - } - char * ptr = strstr(lpString, strReplWhat); - if (ptr) - { - int nPos = static_cast(ptr - lpString + 1); - if (!nPos) - return false; - char *szPrev = new char[nPos]; - - if (!szPrev) - return false; - strncpy(szPrev, lpString, nPos - 1); - int nPos2 = static_cast(nPos + strlen(strReplWhat)); - int nLength = static_cast(strlen(lpString)); - int nSize2 = nLength - nPos2 + 1; - if (nSize2 == 0) - nSize2++; - char *szPost = new char[nSize2]; - if (!szPost) - { - delete szPrev; - return false; - } - ptr += strlen(strReplWhat); - if (nPos == 1) - { - ptr++; - } - strncpy(szPost, ptr, nSize2); - strcpy(lpString, szPrev); - strcat(lpString, strReplWith); - if (nPos == 1) - strcat(lpString, " "); - strcat(lpString, szPost); - delete szPrev; - delete szPost; - - return Replace(lpString, strReplWhat, strReplWith); - } - else - return false; -END_PROTECT_AND_LOG_CODE - return false; -} - -/// returnes message that is replied to contact. -/// the core of a plugin ;) (a joke..) -bool CScriptsReader::GetReturnMessage(LPTSTR lpContactName, LPTSTR & lpMsg, LPTSTR & lpIncomingMsg) -{ -BEGIN_PROTECT_AND_LOG_CODE - DWORD dwSizeOfMess = SETTINGS_MESSAGE_MAXVALENGTH + SETTINGS_HEADER_MAXVALENGTH; - dwSizeOfMess += _tcslen(lpIncomingMsg); - LPTSTR szOwnNick = g_pMessHandler->GetContactName(NULL); - if (szOwnNick) - dwSizeOfMess += _tcslen(szOwnNick); - - bool bspecific = (lpMsg != NULL); - dwSizeOfMess = dwSizeOfMess * 3; /// Any replacing can cause increasing size of data - LPTSTR lpPrev = NULL; - if (bspecific) - { - dwSizeOfMess += _tcslen(lpMsg); - lpPrev = lpMsg; - } - - lpMsg = new TCHAR[dwSizeOfMess]; - - memset(lpMsg, 0, dwSizeOfMess * sizeof(TCHAR)); - - COMMON_RULE_ITEM & commRule = g_pMessHandler->getSettings().getStorage().getCommonRule(); - - if (!bspecific) - { - _tcscpy(lpMsg, commRule.Message); - } - else - { - _tcscpy(lpMsg, lpPrev); - VirtualFree (lpPrev, NULL, MEM_RELEASE); - } - - /*TCHAR strDate[0x100] = {0}; - SYSTEMTIME t = {0}; - GetLocalTime(&t); - sprintf(strDate, "[%d-%d-%d %d-%d-%d]", t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond); - LPSTR lp = strDate; - if (!bspecific) - { - _tcscat(lpMsg, "\r\n"); - _tcscat(lpMsg, commRule.Message); - } - - Replace(lpMsg, SETTINGS_SCRIPT_CURRDATA, lp); - Replace(lpMsg, SETTINGS_SCRIPT_USERNAME, lpContactName); - Replace(lpMsg, SETTINGS_SCRIPT_OWNNICKNAME, szOwnNick); - - LPTSTR lptMMess = CModeMessHandler::GetModeMessage(g_nCurrentMode); - - if (lptMMess) - { - Replace(lpMsg, SETTINGS_SCRIPT_MODEMESSAGE, lptMMess); - /// seems like i should free this ptr - /// but when this is done heap is corrupted - /// so better we have a leak of small amount - /// of memory then corrupted heap. (imho).Sad - /// free (lptMMess); - } - - Replace(lpMsg, SETTINGS_SCRIPT_INCOMMINGMESSAGE, lpIncomingMsg);*/ - - if (lpMsg) - return true; - else - return false; - -END_PROTECT_AND_LOG_CODE - return false; -} \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/ScriptsReader.h b/!NotAdopted/SmartAutoReplier/ScriptsReader.h deleted file mode 100644 index c2b89c3d0f..0000000000 --- a/!NotAdopted/SmartAutoReplier/ScriptsReader.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -#include - -/// class that converts all scripts -/// into an actions or raw text - -/// replacing commands -#define SETTINGS_SCRIPT_USERNAME "%username%" -#define SETTINGS_SCRIPT_CURRDATA "%currdate%" -#define SETTINGS_SCRIPT_MODEMESSAGE "%modemessage%" -#define SETTINGS_SCRIPT_INCOMMINGMESSAGE "%incomingmessage%" -#define SETTINGS_SCRIPT_OWNNICKNAME "%ownnickname%" - -/// actios commands - -typedef struct _ACTION -{ - LPTSTR ActionCode; -}ACTION, *PACTION; - -typedef std::list ACTIONS; - -class CScriptsReader -{ -public: - CScriptsReader(void); - ~CScriptsReader(void); -public: - ACTIONS ParceString(LPTSTR & strMessage); - bool GetReturnMessage(LPTSTR lpContactName, LPTSTR & lpMsg, LPTSTR & lpIncomingMsg); - static bool Replace(LPSTR & lpString, LPSTR strReplWhat, LPSTR & strReplWith); -private: - void InternalInit(void); -private: -}; \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/SettingsHandler.cpp b/!NotAdopted/SmartAutoReplier/SettingsHandler.cpp deleted file mode 100644 index c95ea0c539..0000000000 --- a/!NotAdopted/SmartAutoReplier/SettingsHandler.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" -#include "settingshandler.h" -#include "modemesshandler.h" - -/// we need hinst -extern HINSTANCE hInst; -extern CCrushLog CRUSHLOGOBJ; -extern INT g_nCurrentMode; - -/// ctor -CSettingsHandler::CSettingsHandler(void) : m_bResettings(false), -m_replSize(sizeof(REPLYER_SETTINGS)) -{ -BEGIN_PROTECT_AND_LOG_CODE - MakeFullPath(m_szSettFileName, sizeof(m_szSettFileName), SETTINGS_DB); - m_rulesStorage.Init(); -END_PROTECT_AND_LOG_CODE -} - -/// d'ctor -CSettingsHandler::~CSettingsHandler(void) -{ -BEGIN_PROTECT_AND_LOG_CODE - DeInit(); - m_rulesStorage.Flush(); -END_PROTECT_AND_LOG_CODE -} - -/// changing settings... -void CSettingsHandler::setSettings(REPLYER_SETTINGS & settings, COMMON_RULE_ITEM * pcommrule) -{ -BEGIN_PROTECT_AND_LOG_CODE - m_Settings = settings; -#ifdef _DEBUG - bool bflushed = -#endif - Serialize(&m_Settings, m_replSize); - if (pcommrule) - { - m_rulesStorage.setCommonRule(*pcommrule); - DWORD dw = NULL; - m_rulesStorage.Serialize(NULL, dw); - } -END_PROTECT_AND_LOG_CODE -} - -bool CSettingsHandler::Serialize(ISettingsStream *pSettings, DWORD & ObjectSize) -{ -BEGIN_PROTECT_AND_LOG_CODE - bool bRetVal = false; - HANDLE hFile = CreateFile (m_szSettFileName, GENERIC_WRITE, - FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile == NULL || hFile == INVALID_HANDLE_VALUE) - return bRetVal; /// - else - { /// check ptr for null - bool bValid = (pSettings != NULL); - if (bValid) /// for readibility.. - bValid = (IsBadReadPtr(pSettings, sizeof(pSettings)) == TRUE ? false : true); - - DWORD dwWritten = NULL; - bRetVal = (WriteFile (hFile, (bValid ? pSettings : &m_Settings), sizeof(REPLYER_SETTINGS), &dwWritten, NULL) == TRUE ? true : false); - CloseHandle (hFile); - return bRetVal; - } -END_PROTECT_AND_LOG_CODE - return false; -} - -bool CSettingsHandler::Deserialize(DWORD & ObjectSize) -{ -BEGIN_PROTECT_AND_LOG_CODE - bool bRetVal = false; - HANDLE hFile = CreateFile (m_szSettFileName, GENERIC_READ, - FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile == NULL || hFile == INVALID_HANDLE_VALUE) - return bRetVal; /// - else - { - DWORD dwSizeHigh = 0; - DWORD dwSize = GetFileSize(hFile, &dwSizeHigh); - - if (dwSize != ObjectSize) - { - bool bDel = NotifyAboutWrongSettings(m_szSettFileName); - if (bDel) - { - CloseHandle (hFile); - DeleteFile (m_szSettFileName); - m_bResettings = true; - Init(); - m_bResettings = false; - return true; - } - } - DWORD dwReaded = NULL; - bRetVal = (ReadFile (hFile, &m_Settings, ObjectSize, &dwReaded, NULL) == TRUE ? true : false); - CloseHandle (hFile); - - return bRetVal; - } -END_PROTECT_AND_LOG_CODE - return false; -} - -void CSettingsHandler::Init(void) -{ -BEGIN_PROTECT_AND_LOG_CODE - - if (!PathFileExists(m_szSettFileName)) - { /// create file with def settings... - /// create def. configuration and store it to file... - m_Settings.bDisableWhenModeIsSet = SETTINGS_DEF_COMMON_EN_DISONMODEON; - m_Settings.ModeDisValue = SETTINGS_DEF_COMMON_EN_ONMODEDISVAL; - m_Settings.bShowAURDlgWhenModeChanges = false; - m_Settings.bEnableWhenModeIsSet = SETTINGS_DEF_COMMON_EN_ONMODEON; - m_Settings.ModeValue = SETTINGS_DEF_COMMON_EN_ONMODEONVAL; - - m_Settings.bDisableWhenMirandaIsOn = SETTINGS_DEF_COMMON_DWMION; - m_Settings.ReplayDelay = SETTINGS_DEF_COMMON_VALREPDELAY; - m_Settings.bEnabled = true; - m_Settings.bFirstRun = !m_bResettings; - m_Settings.bSaveToHistory = false; - - Serialize(&m_Settings, m_replSize); - - if (m_Settings.bFirstRun) - { /// show only once to user readme file... - m_Settings.bFirstRun = false; - TCHAR * szreadme = NULL; - szreadme = new TCHAR[MAX_PATH + 1]; - if (szreadme) - { - //MakeFullPath(szreadme, MAX_PATH, READMEFILE); - ::ShellExecute(NULL, TEXT("open"), TEXT("http://www.shcherbyna.com/?page_id=1747"), NULL, NULL, SW_SHOW); - //::ShellExecute(NULL, "open", TEXT("http://shcherbyna.com/forum/viewforum.php?f=8"), NULL, NULL, SW_SHOW); - - delete szreadme; - } - } - } - else - { - Deserialize(m_replSize); - } -END_PROTECT_AND_LOG_CODE -} - -void CSettingsHandler::DeInit(void) -{ -BEGIN_PROTECT_AND_LOG_CODE - Serialize(&m_Settings, m_replSize); -END_PROTECT_AND_LOG_CODE -} - -CScriptsReader & CSettingsHandler::getScriptsReader(void) -{ - return m_scriptsReader; -} - -REPLYER_SETTINGS & CSettingsHandler::getSettings(void) -{ -BEGIN_PROTECT_AND_LOG_CODE - return m_Settings; -END_PROTECT_AND_LOG_CODE -} - -DWORD CSettingsHandler::AddReplyAction(RULE_ITEM item, bool & bExists) -{ -BEGIN_PROTECT_AND_LOG_CODE - return m_rulesStorage.AddRuleItem(item, bExists); -END_PROTECT_AND_LOG_CODE - return 0; -} - -CRulesStorage & CSettingsHandler::getStorage(void) -{ -BEGIN_PROTECT_AND_LOG_CODE - return m_rulesStorage; -END_PROTECT_AND_LOG_CODE -} \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/SettingsHandler.h b/!NotAdopted/SmartAutoReplier/SettingsHandler.h deleted file mode 100644 index 9e0a859796..0000000000 --- a/!NotAdopted/SmartAutoReplier/SettingsHandler.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -#include "RuleItem.h" -#include "RulesStorage.h" -#include "interfaces\ISettings.h" -#include "comfunc.h" -#include "scriptsreader.h" - -/// settings defs... -#define SETTINGS_DB TEXT("sar.csu") -#define READMEFILE TEXT("sar.html") - -#define SETTINGS_HEADER_MAXVALENGTH 1024 * 1 /// 1 kb by def -#define SETTINGS_MESSAGE_MAXVALENGTH 1024 * 3 /// 3 kb by def - -#define SETTINGS_DEF_COMMON_DWMION 1 -#define SETTINGS_DEF_COMMVALUE 0 - -#define SETTINGS_DEF_MESSAGE TEXT("function this.SAR(this, hUser, szMessage, szUser, szProtocol)\r\n this:SendMessage(hUser, \"Here is my autoreply!\")\r\nend") -#define SETTINGS_DEF_MESSAGE_RULE TEXT("-- Main handler function written in Lua:\r\n\r\nfunction this.SAR(this, hUser, szMessage, szUser, szProtocol)\r\n this:SendMessage(hUser, \"Here is my specific to user autoreply!\")\r\nend") -#define SETTINGS_DEF_RULE_NAME TEXT("Some generic rule name") - -#define SETTINGS_DEF_COMMON_VALREPDELAY 2 -#define SETTINGS_DEF_COMMON_EN_ONMODEON 0 -#define SETTINGS_DEF_COMMON_EN_DISONMODEON 0 - -#define SETTINGS_DEF_COMMON_EN_ONMODEDISVAL 0 -#define SETTINGS_DEF_COMMON_EN_ONMODEONVAL 0 -#define SETTINGS_DEF_COMMON_SHOWAURDLGWMC 0 - -/// settings that are stored in file... -/// serialized -typedef struct _REPLYER_SETTINGS : ISettingsStream -{ - bool bEnabled; - bool bDisableWhenMirandaIsOn; - int ReplayDelay; - bool bEnableWhenModeIsSet; - bool bDisableWhenModeIsSet; - int ModeValue; - int ModeDisValue; - bool bShowAURDlgWhenModeChanges; - bool bFirstRun; - bool bSaveToHistory; -}REPLYER_SETTINGS, *PREPLYER_SETTINGS; - -#ifndef MAX_PATH - #define MAX_PATH 260 -#endif - -/// manager that handles settings of a plugin... -class CSettingsHandler : ISettings -{ -public: - CSettingsHandler(void); - ~CSettingsHandler(void); -public: /// ISettings interface... - bool Serialize(ISettingsStream *pSettings, DWORD & ObjectSize); - bool Deserialize(DWORD & ObjectSize); -public: - void Init(void); /// deserialize... - void DeInit(void); /// serialize... - REPLYER_SETTINGS & getSettings(void); - CScriptsReader & getScriptsReader(void); - CRulesStorage & getStorage(void); - void setSettings(REPLYER_SETTINGS & settings, COMMON_RULE_ITEM * pcommrule = NULL); - DWORD AddReplyAction(RULE_ITEM item, bool & bExists); -private: - REPLYER_SETTINGS m_Settings; - TCHAR m_szSettFileName[MAX_PATH]; - bool m_bResettings; - CRulesStorage m_rulesStorage; - CScriptsReader m_scriptsReader; - DWORD m_replSize; -}; \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/comfunc.cpp b/!NotAdopted/SmartAutoReplier/comfunc.cpp deleted file mode 100644 index 0f79871fbb..0000000000 --- a/!NotAdopted/SmartAutoReplier/comfunc.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" -#include "comfunc.h" -#include "shlobj.h" - -extern LPTSTR g_strPluginName; -extern HINSTANCE hInst; - -/// show to user msgbox that settings -/// file is corrupted... -bool NotifyAboutWrongSettings(LPTSTR szFile) -{ - TCHAR szTxt[MAX_PATH * 2] = {0}; - _tcscpy(szTxt, TEXT("Settings file: ")); - _tcscat(szTxt, szFile); - _tcscat(szTxt, TEXT(" is corrupted !\n")); - _tcscat(szTxt, TEXT("As a result plugin can crush.\n")); - _tcscat(szTxt, TEXT("Reset settings to default ?")); - - DWORD dw = MessageBox(NULL, TranslateTS(szTxt), g_strPluginName, MB_YESNO); - return (dw == IDYES); -} - -/// forming path -bool MakeFullPath(LPTSTR lpRetval, DWORD dwSize, LPTSTR lpFile) -{ - HRESULT hr = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, lpRetval); - size_t nLen = _tcslen(lpRetval); - - if (lpRetval[nLen - 1] != TEXT('\\')) - { - _tcscat(lpRetval, TEXT("\\Sar\\")); - } - else - { - _tcscat(lpRetval, TEXT("Sar\\")); - } - - _tcscat(lpRetval, lpFile); - - /*GetModuleFileName(hInst, lpRetval, dwSize); - TCHAR *ptrPos = _tcsrchr(lpRetval, '\\'); - if (ptrPos) - { - ptrPos++; - _tcscpy (ptrPos, lpFile); - } - else - { - _RPT0(_CRT_WARN, "MakeFullPath - unable to form path"); - return false; - }*/ - return true; -} \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/comfunc.h b/!NotAdopted/SmartAutoReplier/comfunc.h deleted file mode 100644 index ab74a7e8ca..0000000000 --- a/!NotAdopted/SmartAutoReplier/comfunc.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -bool NotifyAboutWrongSettings(LPTSTR szFile); -bool MakeFullPath(LPTSTR lpRetval, DWORD dwSize, LPTSTR lpFile); -bool CheckForHelpFile(); \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/comlogging.h b/!NotAdopted/SmartAutoReplier/comlogging.h deleted file mode 100644 index ea8482a198..0000000000 --- a/!NotAdopted/SmartAutoReplier/comlogging.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -/// define hlobal object.. -#ifndef CRUSHLOGOBJ - #define CRUSHLOGOBJ g_crushLog -#endif - -/// this macro should be placed at the begining of any func of plugin.. -#ifndef BEGIN_PROTECT_AND_LOG_CODE - #define BEGIN_PROTECT_AND_LOG_CODE try { \ - SetLastError(0); -#endif - -/// this macro should be placed at the end of any func of plugin.. -#ifndef END_PROTECT_AND_LOG_CODE - #define END_PROTECT_AND_LOG_CODE } \ - catch (...) \ - { \ - CCrushLog::InternalProtect(__FUNCTION__, __FILE__, __DATE__, __LINE__, GetLastError());\ - } -#endif diff --git a/!NotAdopted/SmartAutoReplier/luainc.h b/!NotAdopted/SmartAutoReplier/luainc.h deleted file mode 100644 index 276c25bae5..0000000000 --- a/!NotAdopted/SmartAutoReplier/luainc.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This code is inspired by article of RichardS at http://www.codeproject.com/Articles/11508/Integrating-Lua-into-C - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -extern "C" -{ - #include "../lualib/lua.h" - #include "../lualib/lauxlib.h" - #include "../lualib/lualib.h" -} \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/lualib/ReadMe.txt b/!NotAdopted/SmartAutoReplier/lualib/ReadMe.txt deleted file mode 100644 index 457efed27e..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/ReadMe.txt +++ /dev/null @@ -1,37 +0,0 @@ -======================================================================== - STATIC LIBRARY : lualib Project Overview -======================================================================== - -AppWizard has created this lualib library project for you. - -This file contains a summary of what you will find in each of the files that -make up your lualib application. - - -lualib.vcxproj - This is the main project file for VC++ projects generated using an Application Wizard. - It contains information about the version of Visual C++ that generated the file, and - information about the platforms, configurations, and project features selected with the - Application Wizard. - -lualib.vcxproj.filters - This is the filters file for VC++ projects generated using an Application Wizard. - It contains information about the association between the files in your project - and the filters. This association is used in the IDE to show grouping of files with - similar extensions under a specific node (for e.g. ".cpp" files are associated with the - "Source Files" filter). - - -///////////////////////////////////////////////////////////////////////////// - -StdAfx.h, StdAfx.cpp - These files are used to build a precompiled header (PCH) file - named lualib.pch and a precompiled types file named StdAfx.obj. - -///////////////////////////////////////////////////////////////////////////// -Other notes: - -AppWizard uses "TODO:" comments to indicate parts of the source code you -should add to or customize. - -///////////////////////////////////////////////////////////////////////////// diff --git a/!NotAdopted/SmartAutoReplier/lualib/lapi.c b/!NotAdopted/SmartAutoReplier/lualib/lapi.c deleted file mode 100644 index d5dd9ca465..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lapi.c +++ /dev/null @@ -1,922 +0,0 @@ -/* -** $Id: lapi.c,v 1.235 2003/04/07 14:36:08 roberto Exp $ -** Lua API -** See Copyright Notice in lua.h -*/ - - -#include -#include - -#define lapi_c - -#include "lua.h" - -#include "lapi.h" -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "lgc.h" -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "ltm.h" -#include "lundump.h" -#include "lvm.h" - - -const char lua_ident[] = - "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n" - "$Authors: " LUA_AUTHORS " $\n" - "$URL: www.lua.org $\n"; - - - -#ifndef api_check -#define api_check(L, o) /*{ assert(o); }*/ -#endif - -#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) - -#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;} - - - - -static TObject *negindex (lua_State *L, int idx) { - if (idx > LUA_REGISTRYINDEX) { - api_check(L, idx != 0 && -idx <= L->top - L->base); - return L->top+idx; - } - else switch (idx) { /* pseudo-indices */ - case LUA_REGISTRYINDEX: return registry(L); - case LUA_GLOBALSINDEX: return gt(L); - default: { - TObject *func = (L->base - 1); - idx = LUA_GLOBALSINDEX - idx; - lua_assert(iscfunction(func)); - return (idx <= clvalue(func)->c.nupvalues) - ? &clvalue(func)->c.upvalue[idx-1] - : NULL; - } - } -} - - -static TObject *luaA_index (lua_State *L, int idx) { - if (idx > 0) { - api_check(L, idx <= L->top - L->base); - return L->base + idx - 1; - } - else { - TObject *o = negindex(L, idx); - api_check(L, o != NULL); - return o; - } -} - - -static TObject *luaA_indexAcceptable (lua_State *L, int idx) { - if (idx > 0) { - TObject *o = L->base+(idx-1); - api_check(L, idx <= L->stack_last - L->base); - if (o >= L->top) return NULL; - else return o; - } - else - return negindex(L, idx); -} - - -void luaA_pushobject (lua_State *L, const TObject *o) { - setobj2s(L->top, o); - incr_top(L); -} - - -LUA_API int lua_checkstack (lua_State *L, int size) { - int res; - lua_lock(L); - if ((L->top - L->base + size) > LUA_MAXCSTACK) - res = 0; /* stack overflow */ - else { - luaD_checkstack(L, size); - if (L->ci->top < L->top + size) - L->ci->top = L->top + size; - res = 1; - } - lua_unlock(L); - return res; -} - - -LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { - int i; - lua_lock(to); - api_checknelems(from, n); - from->top -= n; - for (i = 0; i < n; i++) { - setobj2s(to->top, from->top + i); - api_incr_top(to); - } - lua_unlock(to); -} - - -LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { - lua_CFunction old; - lua_lock(L); - old = G(L)->panic; - G(L)->panic = panicf; - lua_unlock(L); - return old; -} - - -LUA_API lua_State *lua_newthread (lua_State *L) { - lua_State *L1; - lua_lock(L); - luaC_checkGC(L); - L1 = luaE_newthread(L); - setthvalue(L->top, L1); - api_incr_top(L); - lua_unlock(L); - lua_userstateopen(L1); - return L1; -} - - - -/* -** basic stack manipulation -*/ - - -LUA_API int lua_gettop (lua_State *L) { - return (L->top - L->base); -} - - -LUA_API void lua_settop (lua_State *L, int idx) { - lua_lock(L); - if (idx >= 0) { - api_check(L, idx <= L->stack_last - L->base); - while (L->top < L->base + idx) - setnilvalue(L->top++); - L->top = L->base + idx; - } - else { - api_check(L, -(idx+1) <= (L->top - L->base)); - L->top += idx+1; /* `subtract' index (index is negative) */ - } - lua_unlock(L); -} - - -LUA_API void lua_remove (lua_State *L, int idx) { - StkId p; - lua_lock(L); - p = luaA_index(L, idx); - while (++p < L->top) setobjs2s(p-1, p); - L->top--; - lua_unlock(L); -} - - -LUA_API void lua_insert (lua_State *L, int idx) { - StkId p; - StkId q; - lua_lock(L); - p = luaA_index(L, idx); - for (q = L->top; q>p; q--) setobjs2s(q, q-1); - setobjs2s(p, L->top); - lua_unlock(L); -} - - -LUA_API void lua_replace (lua_State *L, int idx) { - lua_lock(L); - api_checknelems(L, 1); - setobj(luaA_index(L, idx), L->top - 1); /* write barrier */ - L->top--; - lua_unlock(L); -} - - -LUA_API void lua_pushvalue (lua_State *L, int idx) { - lua_lock(L); - setobj2s(L->top, luaA_index(L, idx)); - api_incr_top(L); - lua_unlock(L); -} - - - -/* -** access functions (stack -> C) -*/ - - -LUA_API int lua_type (lua_State *L, int idx) { - StkId o = luaA_indexAcceptable(L, idx); - return (o == NULL) ? LUA_TNONE : ttype(o); -} - - -LUA_API const char *lua_typename (lua_State *L, int t) { - UNUSED(L); - return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; -} - - -LUA_API int lua_iscfunction (lua_State *L, int idx) { - StkId o = luaA_indexAcceptable(L, idx); - return (o == NULL) ? 0 : iscfunction(o); -} - - -LUA_API int lua_isnumber (lua_State *L, int idx) { - TObject n; - const TObject *o = luaA_indexAcceptable(L, idx); - return (o != NULL && tonumber(o, &n)); -} - - -LUA_API int lua_isstring (lua_State *L, int idx) { - int t = lua_type(L, idx); - return (t == LUA_TSTRING || t == LUA_TNUMBER); -} - - -LUA_API int lua_isuserdata (lua_State *L, int idx) { - const TObject *o = luaA_indexAcceptable(L, idx); - return (o != NULL && (ttisuserdata(o) || ttislightuserdata(o))); -} - - -LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { - StkId o1 = luaA_indexAcceptable(L, index1); - StkId o2 = luaA_indexAcceptable(L, index2); - return (o1 == NULL || o2 == NULL) ? 0 /* index out of range */ - : luaO_rawequalObj(o1, o2); -} - - -LUA_API int lua_equal (lua_State *L, int index1, int index2) { - StkId o1, o2; - int i; - lua_lock(L); /* may call tag method */ - o1 = luaA_indexAcceptable(L, index1); - o2 = luaA_indexAcceptable(L, index2); - i = (o1 == NULL || o2 == NULL) ? 0 /* index out of range */ - : equalobj(L, o1, o2); - lua_unlock(L); - return i; -} - - -LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { - StkId o1, o2; - int i; - lua_lock(L); /* may call tag method */ - o1 = luaA_indexAcceptable(L, index1); - o2 = luaA_indexAcceptable(L, index2); - i = (o1 == NULL || o2 == NULL) ? 0 /* index out-of-range */ - : luaV_lessthan(L, o1, o2); - lua_unlock(L); - return i; -} - - - -LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { - TObject n; - const TObject *o = luaA_indexAcceptable(L, idx); - if (o != NULL && tonumber(o, &n)) - return nvalue(o); - else - return 0; -} - - -LUA_API int lua_toboolean (lua_State *L, int idx) { - const TObject *o = luaA_indexAcceptable(L, idx); - return (o != NULL) && !l_isfalse(o); -} - - -LUA_API const char *lua_tostring (lua_State *L, int idx) { - StkId o = luaA_indexAcceptable(L, idx); - if (o == NULL) - return NULL; - else if (ttisstring(o)) - return svalue(o); - else { - const char *s; - lua_lock(L); /* `luaV_tostring' may create a new string */ - s = (luaV_tostring(L, o) ? svalue(o) : NULL); - luaC_checkGC(L); - lua_unlock(L); - return s; - } -} - - -LUA_API size_t lua_strlen (lua_State *L, int idx) { - StkId o = luaA_indexAcceptable(L, idx); - if (o == NULL) - return 0; - else if (ttisstring(o)) - return tsvalue(o)->tsv.len; - else { - size_t l; - lua_lock(L); /* `luaV_tostring' may create a new string */ - l = (luaV_tostring(L, o) ? tsvalue(o)->tsv.len : 0); - lua_unlock(L); - return l; - } -} - - -LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { - StkId o = luaA_indexAcceptable(L, idx); - return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->c.f; -} - - -LUA_API void *lua_touserdata (lua_State *L, int idx) { - StkId o = luaA_indexAcceptable(L, idx); - if (o == NULL) return NULL; - switch (ttype(o)) { - case LUA_TUSERDATA: return (uvalue(o) + 1); - case LUA_TLIGHTUSERDATA: return pvalue(o); - default: return NULL; - } -} - - -LUA_API lua_State *lua_tothread (lua_State *L, int idx) { - StkId o = luaA_indexAcceptable(L, idx); - return (o == NULL || !ttisthread(o)) ? NULL : thvalue(o); -} - - -LUA_API const void *lua_topointer (lua_State *L, int idx) { - StkId o = luaA_indexAcceptable(L, idx); - if (o == NULL) return NULL; - else { - switch (ttype(o)) { - case LUA_TTABLE: return hvalue(o); - case LUA_TFUNCTION: return clvalue(o); - case LUA_TTHREAD: return thvalue(o); - case LUA_TUSERDATA: - case LUA_TLIGHTUSERDATA: - return lua_touserdata(L, idx); - default: return NULL; - } - } -} - - - -/* -** push functions (C -> stack) -*/ - - -LUA_API void lua_pushnil (lua_State *L) { - lua_lock(L); - setnilvalue(L->top); - api_incr_top(L); - lua_unlock(L); -} - - -LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { - lua_lock(L); - setnvalue(L->top, n); - api_incr_top(L); - lua_unlock(L); -} - - -LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { - lua_lock(L); - luaC_checkGC(L); - setsvalue2s(L->top, luaS_newlstr(L, s, len)); - api_incr_top(L); - lua_unlock(L); -} - - -LUA_API void lua_pushstring (lua_State *L, const char *s) { - if (s == NULL) - lua_pushnil(L); - else - lua_pushlstring(L, s, strlen(s)); -} - - -LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, - va_list argp) { - const char *ret; - lua_lock(L); - luaC_checkGC(L); - ret = luaO_pushvfstring(L, fmt, argp); - lua_unlock(L); - return ret; -} - - -LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { - const char *ret; - va_list argp; - lua_lock(L); - luaC_checkGC(L); - va_start(argp, fmt); - ret = luaO_pushvfstring(L, fmt, argp); - va_end(argp); - lua_unlock(L); - return ret; -} - - -LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { - Closure *cl; - lua_lock(L); - luaC_checkGC(L); - api_checknelems(L, n); - cl = luaF_newCclosure(L, n); - cl->c.f = fn; - L->top -= n; - while (n--) - setobj2n(&cl->c.upvalue[n], L->top+n); - setclvalue(L->top, cl); - api_incr_top(L); - lua_unlock(L); -} - - -LUA_API void lua_pushboolean (lua_State *L, int b) { - lua_lock(L); - setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ - api_incr_top(L); - lua_unlock(L); -} - - -LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { - lua_lock(L); - setpvalue(L->top, p); - api_incr_top(L); - lua_unlock(L); -} - - - -/* -** get functions (Lua -> stack) -*/ - - -LUA_API void lua_gettable (lua_State *L, int idx) { - StkId t; - lua_lock(L); - t = luaA_index(L, idx); - setobj2s(L->top - 1, luaV_gettable(L, t, L->top - 1, 0)); - lua_unlock(L); -} - - -LUA_API void lua_rawget (lua_State *L, int idx) { - StkId t; - lua_lock(L); - t = luaA_index(L, idx); - api_check(L, ttistable(t)); - setobj2s(L->top - 1, luaH_get(hvalue(t), L->top - 1)); - lua_unlock(L); -} - - -LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { - StkId o; - lua_lock(L); - o = luaA_index(L, idx); - api_check(L, ttistable(o)); - setobj2s(L->top, luaH_getnum(hvalue(o), n)); - api_incr_top(L); - lua_unlock(L); -} - - -LUA_API void lua_newtable (lua_State *L) { - lua_lock(L); - luaC_checkGC(L); - sethvalue(L->top, luaH_new(L, 0, 0)); - api_incr_top(L); - lua_unlock(L); -} - - -LUA_API int lua_getmetatable (lua_State *L, int objindex) { - const TObject *obj; - Table *mt = NULL; - int res; - lua_lock(L); - obj = luaA_indexAcceptable(L, objindex); - if (obj != NULL) { - switch (ttype(obj)) { - case LUA_TTABLE: - mt = hvalue(obj)->metatable; - break; - case LUA_TUSERDATA: - mt = uvalue(obj)->uv.metatable; - break; - } - } - if (mt == NULL || mt == hvalue(defaultmeta(L))) - res = 0; - else { - sethvalue(L->top, mt); - api_incr_top(L); - res = 1; - } - lua_unlock(L); - return res; -} - - -LUA_API void lua_getfenv (lua_State *L, int idx) { - StkId o; - lua_lock(L); - o = luaA_index(L, idx); - setobj2s(L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L)); - api_incr_top(L); - lua_unlock(L); -} - - -/* -** set functions (stack -> Lua) -*/ - - -LUA_API void lua_settable (lua_State *L, int idx) { - StkId t; - lua_lock(L); - api_checknelems(L, 2); - t = luaA_index(L, idx); - luaV_settable(L, t, L->top - 2, L->top - 1); - L->top -= 2; /* pop index and value */ - lua_unlock(L); -} - - -LUA_API void lua_rawset (lua_State *L, int idx) { - StkId t; - lua_lock(L); - api_checknelems(L, 2); - t = luaA_index(L, idx); - api_check(L, ttistable(t)); - setobj2t(luaH_set(L, hvalue(t), L->top-2), L->top-1); /* write barrier */ - L->top -= 2; - lua_unlock(L); -} - - -LUA_API void lua_rawseti (lua_State *L, int idx, int n) { - StkId o; - lua_lock(L); - api_checknelems(L, 1); - o = luaA_index(L, idx); - api_check(L, ttistable(o)); - setobj2t(luaH_setnum(L, hvalue(o), n), L->top-1); /* write barrier */ - L->top--; - lua_unlock(L); -} - - -LUA_API int lua_setmetatable (lua_State *L, int objindex) { - TObject *obj, *mt; - int res = 1; - lua_lock(L); - api_checknelems(L, 1); - obj = luaA_index(L, objindex); - mt = (!ttisnil(L->top - 1)) ? L->top - 1 : defaultmeta(L); - api_check(L, ttistable(mt)); - switch (ttype(obj)) { - case LUA_TTABLE: { - hvalue(obj)->metatable = hvalue(mt); /* write barrier */ - break; - } - case LUA_TUSERDATA: { - uvalue(obj)->uv.metatable = hvalue(mt); /* write barrier */ - break; - } - default: { - res = 0; /* cannot set */ - break; - } - } - L->top--; - lua_unlock(L); - return res; -} - - -LUA_API int lua_setfenv (lua_State *L, int idx) { - StkId o; - int res = 0; - lua_lock(L); - api_checknelems(L, 1); - o = luaA_index(L, idx); - L->top--; - api_check(L, ttistable(L->top)); - if (isLfunction(o)) { - res = 1; - clvalue(o)->l.g = *(L->top); - } - lua_unlock(L); - return res; -} - - -/* -** `load' and `call' functions (run Lua code) -*/ - -LUA_API void lua_call (lua_State *L, int nargs, int nresults) { - StkId func; - lua_lock(L); - api_checknelems(L, nargs+1); - func = L->top - (nargs+1); - luaD_call(L, func, nresults); - lua_unlock(L); -} - - - -/* -** Execute a protected call. -*/ -struct CallS { /* data to `f_call' */ - StkId func; - int nresults; -}; - - -static void f_call (lua_State *L, void *ud) { - struct CallS *c = cast(struct CallS *, ud); - luaD_call(L, c->func, c->nresults); -} - - - -LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { - struct CallS c; - int status; - ptrdiff_t func; - lua_lock(L); - func = (errfunc == 0) ? 0 : savestack(L, luaA_index(L, errfunc)); - c.func = L->top - (nargs+1); /* function to be called */ - c.nresults = nresults; - status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); - lua_unlock(L); - return status; -} - - -/* -** Execute a protected C call. -*/ -struct CCallS { /* data to `f_Ccall' */ - lua_CFunction func; - void *ud; -}; - - -static void f_Ccall (lua_State *L, void *ud) { - struct CCallS *c = cast(struct CCallS *, ud); - Closure *cl; - cl = luaF_newCclosure(L, 0); - cl->c.f = c->func; - setclvalue(L->top, cl); /* push function */ - incr_top(L); - setpvalue(L->top, c->ud); /* push only argument */ - incr_top(L); - luaD_call(L, L->top - 2, 0); -} - - -LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { - struct CCallS c; - int status; - lua_lock(L); - c.func = func; - c.ud = ud; - status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0); - lua_unlock(L); - return status; -} - - -LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data, - const char *chunkname) { - ZIO z; - int status; - int c; - lua_lock(L); - if (!chunkname) chunkname = "?"; - luaZ_init(&z, reader, data, chunkname); - c = luaZ_lookahead(&z); - status = luaD_protectedparser(L, &z, (c == LUA_SIGNATURE[0])); - lua_unlock(L); - return status; -} - - -LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data) { - int status; - TObject *o; - lua_lock(L); - api_checknelems(L, 1); - o = L->top - 1; - if (isLfunction(o) && clvalue(o)->l.nupvalues == 0) { - luaU_dump(L, clvalue(o)->l.p, writer, data); - status = 1; - } - else - status = 0; - lua_unlock(L); - return status; -} - - -/* -** Garbage-collection functions -*/ - -/* GC values are expressed in Kbytes: #bytes/2^10 */ -#define GCscalel(x) ((x)>>10) -#define GCscale(x) (cast(int, GCscalel(x))) -#define GCunscale(x) (cast(lu_mem, x)<<10) - -LUA_API int lua_getgcthreshold (lua_State *L) { - int threshold; - lua_lock(L); - threshold = GCscale(G(L)->GCthreshold); - lua_unlock(L); - return threshold; -} - -LUA_API int lua_getgccount (lua_State *L) { - int count; - lua_lock(L); - count = GCscale(G(L)->nblocks); - lua_unlock(L); - return count; -} - -LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) { - lua_lock(L); - if (cast(lu_mem, newthreshold) > GCscalel(MAX_LUMEM)) - G(L)->GCthreshold = MAX_LUMEM; - else - G(L)->GCthreshold = GCunscale(newthreshold); - luaC_checkGC(L); - lua_unlock(L); -} - - -/* -** miscellaneous functions -*/ - - -LUA_API const char *lua_version (void) { - return LUA_VERSION; -} - - -LUA_API int lua_error (lua_State *L) { - lua_lock(L); - api_checknelems(L, 1); - luaG_errormsg(L); - lua_unlock(L); - return 0; /* to avoid warnings */ -} - - -LUA_API int lua_next (lua_State *L, int idx) { - StkId t; - int more; - lua_lock(L); - t = luaA_index(L, idx); - api_check(L, ttistable(t)); - more = luaH_next(L, hvalue(t), L->top - 1); - if (more) { - api_incr_top(L); - } - else /* no more elements */ - L->top -= 1; /* remove key */ - lua_unlock(L); - return more; -} - - -LUA_API void lua_concat (lua_State *L, int n) { - lua_lock(L); - luaC_checkGC(L); - api_checknelems(L, n); - if (n >= 2) { - luaV_concat(L, n, L->top - L->base - 1); - L->top -= (n-1); - } - else if (n == 0) { /* push empty string */ - setsvalue2s(L->top, luaS_newlstr(L, NULL, 0)); - api_incr_top(L); - } - /* else n == 1; nothing to do */ - lua_unlock(L); -} - - -LUA_API void *lua_newuserdata (lua_State *L, size_t size) { - Udata *u; - lua_lock(L); - luaC_checkGC(L); - u = luaS_newudata(L, size); - setuvalue(L->top, u); - api_incr_top(L); - lua_unlock(L); - return u + 1; -} - - -LUA_API int lua_pushupvalues (lua_State *L) { - Closure *func; - int n, i; - lua_lock(L); - api_check(L, iscfunction(L->base - 1)); - func = clvalue(L->base - 1); - n = func->c.nupvalues; - luaD_checkstack(L, n + LUA_MINSTACK); - for (i=0; itop, &func->c.upvalue[i]); - L->top++; - } - lua_unlock(L); - return n; -} - - -static const char *aux_upvalue (lua_State *L, int funcindex, int n, - TObject **val) { - Closure *f; - StkId fi = luaA_index(L, funcindex); - if (!ttisfunction(fi)) return NULL; - f = clvalue(fi); - if (f->c.isC) { - if (n > f->c.nupvalues) return NULL; - *val = &f->c.upvalue[n-1]; - return ""; - } - else { - Proto *p = f->l.p; - if (n > p->sizeupvalues) return NULL; - *val = f->l.upvals[n-1]->v; - return getstr(p->upvalues[n-1]); - } -} - - -LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { - const char *name; - TObject *val; - lua_lock(L); - name = aux_upvalue(L, funcindex, n, &val); - if (name) { - setobj2s(L->top, val); - api_incr_top(L); - } - lua_unlock(L); - return name; -} - - -LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { - const char *name; - TObject *val; - lua_lock(L); - api_checknelems(L, 1); - name = aux_upvalue(L, funcindex, n, &val); - if (name) { - L->top--; - setobj(val, L->top); /* write barrier */ - } - lua_unlock(L); - return name; -} - diff --git a/!NotAdopted/SmartAutoReplier/lualib/lapi.h b/!NotAdopted/SmartAutoReplier/lualib/lapi.h deleted file mode 100644 index d12612f304..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lapi.h +++ /dev/null @@ -1,16 +0,0 @@ -/* -** $Id: lapi.h,v 1.21 2002/03/04 21:29:41 roberto Exp $ -** Auxiliary functions from Lua API -** See Copyright Notice in lua.h -*/ - -#ifndef lapi_h -#define lapi_h - - -#include "lobject.h" - - -void luaA_pushobject (lua_State *L, const TObject *o); - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/lauxlib.c b/!NotAdopted/SmartAutoReplier/lualib/lauxlib.c deleted file mode 100644 index ee2d1339b0..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lauxlib.c +++ /dev/null @@ -1,591 +0,0 @@ -/* -** $Id: lauxlib.c,v 1.100 2003/04/07 14:35:00 roberto Exp $ -** Auxiliary functions for building Lua libraries -** See Copyright Notice in lua.h -*/ - - -#include -#include -#include -#include -#include - - -/* This file uses only the official API of Lua. -** Any function declared here could be written as an application function. -*/ - -#define lauxlib_c - -#include "lua.h" - -#include "lauxlib.h" - - -/* number of prereserved references (for internal use) */ -#define RESERVED_REFS 2 - -/* reserved references */ -#define FREELIST_REF 1 /* free list of references */ -#define ARRAYSIZE_REF 2 /* array sizes */ - - -/* convert a stack index to positive */ -#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ - lua_gettop(L) + (i) + 1) - - -/* -** {====================================================== -** Error-report functions -** ======================================================= -*/ - - -LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { - lua_Debug ar; - lua_getstack(L, 0, &ar); - lua_getinfo(L, "n", &ar); - if (strcmp(ar.namewhat, "method") == 0) { - narg--; /* do not count `self' */ - if (narg == 0) /* error is in the self argument itself? */ - return luaL_error(L, "calling `%s' on bad self (%s)", ar.name, extramsg); - } - if (ar.name == NULL) - ar.name = "?"; - return luaL_error(L, "bad argument #%d to `%s' (%s)", - narg, ar.name, extramsg); -} - - -LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { - const char *msg = lua_pushfstring(L, "%s expected, got %s", - tname, lua_typename(L, lua_type(L,narg))); - return luaL_argerror(L, narg, msg); -} - - -static void tag_error (lua_State *L, int narg, int tag) { - luaL_typerror(L, narg, lua_typename(L, tag)); -} - - -LUALIB_API void luaL_where (lua_State *L, int level) { - lua_Debug ar; - if (lua_getstack(L, level, &ar)) { /* check function at level */ - lua_getinfo(L, "Snl", &ar); /* get info about it */ - if (ar.currentline > 0) { /* is there info? */ - lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); - return; - } - } - lua_pushliteral(L, ""); /* else, no information available... */ -} - - -LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { - va_list argp; - va_start(argp, fmt); - luaL_where(L, 1); - lua_pushvfstring(L, fmt, argp); - va_end(argp); - lua_concat(L, 2); - return lua_error(L); -} - -/* }====================================================== */ - - -LUALIB_API int luaL_findstring (const char *name, const char *const list[]) { - int i; - for (i=0; list[i]; i++) - if (strcmp(list[i], name) == 0) - return i; - return -1; /* name not found */ -} - - -LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { - lua_pushstring(L, tname); - lua_rawget(L, LUA_REGISTRYINDEX); /* get registry.name */ - if (!lua_isnil(L, -1)) /* name already in use? */ - return 0; /* leave previous value on top, but return 0 */ - lua_pop(L, 1); - lua_newtable(L); /* create metatable */ - lua_pushstring(L, tname); - lua_pushvalue(L, -2); - lua_rawset(L, LUA_REGISTRYINDEX); /* registry.name = metatable */ - lua_pushvalue(L, -1); - lua_pushstring(L, tname); - lua_rawset(L, LUA_REGISTRYINDEX); /* registry[metatable] = name */ - return 1; -} - - -LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname) { - lua_pushstring(L, tname); - lua_rawget(L, LUA_REGISTRYINDEX); -} - - -LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { - const char *tn; - if (!lua_getmetatable(L, ud)) return NULL; /* no metatable? */ - lua_rawget(L, LUA_REGISTRYINDEX); /* get registry[metatable] */ - tn = lua_tostring(L, -1); - if (tn && (strcmp(tn, tname) == 0)) { - lua_pop(L, 1); - return lua_touserdata(L, ud); - } - else { - lua_pop(L, 1); - return NULL; - } -} - - -LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) { - if (!lua_checkstack(L, space)) - luaL_error(L, "stack overflow (%s)", mes); -} - - -LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { - if (lua_type(L, narg) != t) - tag_error(L, narg, t); -} - - -LUALIB_API void luaL_checkany (lua_State *L, int narg) { - if (lua_type(L, narg) == LUA_TNONE) - luaL_argerror(L, narg, "value expected"); -} - - -LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { - const char *s = lua_tostring(L, narg); - if (!s) tag_error(L, narg, LUA_TSTRING); - if (len) *len = lua_strlen(L, narg); - return s; -} - - -LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, - const char *def, size_t *len) { - if (lua_isnoneornil(L, narg)) { - if (len) - *len = (def ? strlen(def) : 0); - return def; - } - else return luaL_checklstring(L, narg, len); -} - - -LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { - lua_Number d = lua_tonumber(L, narg); - if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ - tag_error(L, narg, LUA_TNUMBER); - return d; -} - - -LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { - if (lua_isnoneornil(L, narg)) return def; - else return luaL_checknumber(L, narg); -} - - -LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { - if (!lua_getmetatable(L, obj)) /* no metatable? */ - return 0; - lua_pushstring(L, event); - lua_rawget(L, -2); - if (lua_isnil(L, -1)) { - lua_pop(L, 2); /* remove metatable and metafield */ - return 0; - } - else { - lua_remove(L, -2); /* remove only metatable */ - return 1; - } -} - - -LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { - obj = abs_index(L, obj); - if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ - return 0; - lua_pushvalue(L, obj); - lua_call(L, 1, 1); - return 1; -} - - -LUALIB_API void luaL_openlib (lua_State *L, const char *libname, - const luaL_reg *l, int nup) { - if (libname) { - lua_pushstring(L, libname); - lua_gettable(L, LUA_GLOBALSINDEX); /* check whether lib already exists */ - if (lua_isnil(L, -1)) { /* no? */ - lua_pop(L, 1); - lua_newtable(L); /* create it */ - lua_pushstring(L, libname); - lua_pushvalue(L, -2); - lua_settable(L, LUA_GLOBALSINDEX); /* register it with given name */ - } - lua_insert(L, -(nup+1)); /* move library table to below upvalues */ - } - for (; l->name; l++) { - int i; - lua_pushstring(L, l->name); - for (i=0; ifunc, nup); - lua_settable(L, -(nup+3)); - } - lua_pop(L, nup); /* remove upvalues */ -} - - - -/* -** {====================================================== -** getn-setn: size for arrays -** ======================================================= -*/ - -static int checkint (lua_State *L, int topop) { - int n = (int)lua_tonumber(L, -1); - if (n == 0 && !lua_isnumber(L, -1)) n = -1; - lua_pop(L, topop); - return n; -} - - -static void getsizes (lua_State *L) { - lua_rawgeti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); - if (lua_isnil(L, -1)) { /* no `size' table? */ - lua_pop(L, 1); /* remove nil */ - lua_newtable(L); /* create it */ - lua_pushvalue(L, -1); /* `size' will be its own metatable */ - lua_setmetatable(L, -2); - lua_pushliteral(L, "__mode"); - lua_pushliteral(L, "k"); - lua_rawset(L, -3); /* metatable(N).__mode = "k" */ - lua_pushvalue(L, -1); - lua_rawseti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); /* store in register */ - } -} - - -void luaL_setn (lua_State *L, int t, int n) { - t = abs_index(L, t); - lua_pushliteral(L, "n"); - lua_rawget(L, t); - if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */ - lua_pushliteral(L, "n"); /* use it */ - lua_pushnumber(L, (lua_Number)n); - lua_rawset(L, t); - } - else { /* use `sizes' */ - getsizes(L); - lua_pushvalue(L, t); - lua_pushnumber(L, (lua_Number)n); - lua_rawset(L, -3); /* sizes[t] = n */ - lua_pop(L, 1); /* remove `sizes' */ - } -} - - -int luaL_getn (lua_State *L, int t) { - int n; - t = abs_index(L, t); - lua_pushliteral(L, "n"); /* try t.n */ - lua_rawget(L, t); - if ((n = checkint(L, 1)) >= 0) return n; - getsizes(L); /* else try sizes[t] */ - lua_pushvalue(L, t); - lua_rawget(L, -2); - if ((n = checkint(L, 2)) >= 0) return n; - for (n = 1; ; n++) { /* else must count elements */ - lua_rawgeti(L, t, n); - if (lua_isnil(L, -1)) break; - lua_pop(L, 1); - } - lua_pop(L, 1); - return n - 1; -} - -/* }====================================================== */ - - - -/* -** {====================================================== -** Generic Buffer manipulation -** ======================================================= -*/ - - -#define bufflen(B) ((B)->p - (B)->buffer) -#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) - -#define LIMIT (LUA_MINSTACK/2) - - -static int emptybuffer (luaL_Buffer *B) { - size_t l = bufflen(B); - if (l == 0) return 0; /* put nothing on stack */ - else { - lua_pushlstring(B->L, B->buffer, l); - B->p = B->buffer; - B->lvl++; - return 1; - } -} - - -static void adjuststack (luaL_Buffer *B) { - if (B->lvl > 1) { - lua_State *L = B->L; - int toget = 1; /* number of levels to concat */ - size_t toplen = lua_strlen(L, -1); - do { - size_t l = lua_strlen(L, -(toget+1)); - if (B->lvl - toget + 1 >= LIMIT || toplen > l) { - toplen += l; - toget++; - } - else break; - } while (toget < B->lvl); - lua_concat(L, toget); - B->lvl = B->lvl - toget + 1; - } -} - - -LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) { - if (emptybuffer(B)) - adjuststack(B); - return B->buffer; -} - - -LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { - while (l--) - luaL_putchar(B, *s++); -} - - -LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { - luaL_addlstring(B, s, strlen(s)); -} - - -LUALIB_API void luaL_pushresult (luaL_Buffer *B) { - emptybuffer(B); - lua_concat(B->L, B->lvl); - B->lvl = 1; -} - - -LUALIB_API void luaL_addvalue (luaL_Buffer *B) { - lua_State *L = B->L; - size_t vl = lua_strlen(L, -1); - if (vl <= bufffree(B)) { /* fit into buffer? */ - memcpy(B->p, lua_tostring(L, -1), vl); /* put it there */ - B->p += vl; - lua_pop(L, 1); /* remove from stack */ - } - else { - if (emptybuffer(B)) - lua_insert(L, -2); /* put buffer before new value */ - B->lvl++; /* add new value into B stack */ - adjuststack(B); - } -} - - -LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { - B->L = L; - B->p = B->buffer; - B->lvl = 0; -} - -/* }====================================================== */ - - -LUALIB_API int luaL_ref (lua_State *L, int t) { - int ref; - t = abs_index(L, t); - if (lua_isnil(L, -1)) { - lua_pop(L, 1); /* remove from stack */ - return LUA_REFNIL; /* `nil' has a unique fixed reference */ - } - lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ - ref = (int)lua_tonumber(L, -1); /* ref = t[FREELIST_REF] */ - lua_pop(L, 1); /* remove it from stack */ - if (ref != 0) { /* any free element? */ - lua_rawgeti(L, t, ref); /* remove it from list */ - lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ - } - else { /* no free elements */ - ref = luaL_getn(L, t); - if (ref < RESERVED_REFS) - ref = RESERVED_REFS; /* skip reserved references */ - ref++; /* create new reference */ - luaL_setn(L, t, ref); - } - lua_rawseti(L, t, ref); - return ref; -} - - -LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { - if (ref >= 0) { - t = abs_index(L, t); - lua_rawgeti(L, t, FREELIST_REF); - lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ - lua_pushnumber(L, (lua_Number)ref); - lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ - } -} - - - -/* -** {====================================================== -** Load functions -** ======================================================= -*/ - -typedef struct LoadF { - FILE *f; - char buff[LUAL_BUFFERSIZE]; -} LoadF; - - -static const char *getF (lua_State *L, void *ud, size_t *size) { - LoadF *lf = (LoadF *)ud; - (void)L; - if (feof(lf->f)) return NULL; - *size = fread(lf->buff, 1, LUAL_BUFFERSIZE, lf->f); - return (*size > 0) ? lf->buff : NULL; -} - - -static int errfile (lua_State *L, int fnameindex) { - const char *filename = lua_tostring(L, fnameindex) + 1; - lua_pushfstring(L, "cannot read %s: %s", filename, strerror(errno)); - lua_remove(L, fnameindex); - return LUA_ERRFILE; -} - - -LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { - LoadF lf; - int status, readstatus; - int c; - int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ - if (filename == NULL) { - lua_pushliteral(L, "=stdin"); - lf.f = stdin; - } - else { - lua_pushfstring(L, "@%s", filename); - lf.f = fopen(filename, "r"); - } - if (lf.f == NULL) return errfile(L, fnameindex); /* unable to open file */ - c = ungetc(getc(lf.f), lf.f); - if (!(isspace(c) || isprint(c)) && lf.f != stdin) { /* binary file? */ - fclose(lf.f); - lf.f = fopen(filename, "rb"); /* reopen in binary mode */ - if (lf.f == NULL) return errfile(L, fnameindex); /* unable to reopen file */ - } - status = lua_load(L, getF, &lf, lua_tostring(L, -1)); - readstatus = ferror(lf.f); - if (lf.f != stdin) fclose(lf.f); /* close file (even in case of errors) */ - if (readstatus) { - lua_settop(L, fnameindex); /* ignore results from `lua_load' */ - return errfile(L, fnameindex); - } - lua_remove(L, fnameindex); - return status; -} - - -typedef struct LoadS { - const char *s; - size_t size; -} LoadS; - - -static const char *getS (lua_State *L, void *ud, size_t *size) { - LoadS *ls = (LoadS *)ud; - (void)L; - if (ls->size == 0) return NULL; - *size = ls->size; - ls->size = 0; - return ls->s; -} - - -LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size, - const char *name) { - LoadS ls; - ls.s = buff; - ls.size = size; - return lua_load(L, getS, &ls, name); -} - -/* }====================================================== */ - - -/* -** {====================================================== -** compatibility code -** ======================================================= -*/ - - -static void callalert (lua_State *L, int status) { - if (status != 0) { - lua_getglobal(L, "_ALERT"); - if (lua_isfunction(L, -1)) { - lua_insert(L, -2); - lua_call(L, 1, 0); - } - else { /* no _ALERT function; print it on stderr */ - fprintf(stderr, "%s\n", lua_tostring(L, -2)); - lua_pop(L, 2); /* remove error message and _ALERT */ - } - } -} - - -static int aux_do (lua_State *L, int status) { - if (status == 0) { /* parse OK? */ - status = lua_pcall(L, 0, LUA_MULTRET, 0); /* call main */ - } - callalert(L, status); - return status; -} - - -LUALIB_API int lua_dofile (lua_State *L, const char *filename) { - return aux_do(L, luaL_loadfile(L, filename)); -} - - -LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, - const char *name) { - return aux_do(L, luaL_loadbuffer(L, buff, size, name)); -} - - -LUALIB_API int lua_dostring (lua_State *L, const char *str) { - return lua_dobuffer(L, str, strlen(str), str); -} - -/* }====================================================== */ diff --git a/!NotAdopted/SmartAutoReplier/lualib/lauxlib.h b/!NotAdopted/SmartAutoReplier/lualib/lauxlib.h deleted file mode 100644 index 450e16c720..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lauxlib.h +++ /dev/null @@ -1,145 +0,0 @@ -/* -** $Id: lauxlib.h,v 1.60 2003/04/03 13:35:34 roberto Exp $ -** Auxiliary functions for building Lua libraries -** See Copyright Notice in lua.h -*/ - - -#ifndef lauxlib_h -#define lauxlib_h - - -#include -#include - -#include "lua.h" - - -#ifndef LUALIB_API -#define LUALIB_API LUA_API -#endif - - - -typedef struct luaL_reg { - const char *name; - lua_CFunction func; -} luaL_reg; - - -LUALIB_API void luaL_openlib (lua_State *L, const char *libname, - const luaL_reg *l, int nup); -LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *e); -LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *e); -LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname); -LUALIB_API int luaL_argerror (lua_State *L, int numarg, const char *extramsg); -LUALIB_API const char *luaL_checklstring (lua_State *L, int numArg, size_t *l); -LUALIB_API const char *luaL_optlstring (lua_State *L, int numArg, - const char *def, size_t *l); -LUALIB_API lua_Number luaL_checknumber (lua_State *L, int numArg); -LUALIB_API lua_Number luaL_optnumber (lua_State *L, int nArg, lua_Number def); - -LUALIB_API void luaL_checkstack (lua_State *L, int sz, const char *msg); -LUALIB_API void luaL_checktype (lua_State *L, int narg, int t); -LUALIB_API void luaL_checkany (lua_State *L, int narg); - -LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname); -LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname); -LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname); - -LUALIB_API void luaL_where (lua_State *L, int lvl); -LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...); - -LUALIB_API int luaL_findstring (const char *st, const char *const lst[]); - -LUALIB_API int luaL_ref (lua_State *L, int t); -LUALIB_API void luaL_unref (lua_State *L, int t, int ref); - -LUALIB_API int luaL_getn (lua_State *L, int t); -LUALIB_API void luaL_setn (lua_State *L, int t, int n); - -LUALIB_API int luaL_loadfile (lua_State *L, const char *filename); -LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz, - const char *name); - - - -/* -** =============================================================== -** some useful macros -** =============================================================== -*/ - -#define luaL_argcheck(L, cond,numarg,extramsg) if (!(cond)) \ - luaL_argerror(L, numarg,extramsg) -#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) -#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) -#define luaL_checkint(L,n) ((int)luaL_checknumber(L, n)) -#define luaL_checklong(L,n) ((long)luaL_checknumber(L, n)) -#define luaL_optint(L,n,d) ((int)luaL_optnumber(L, n,(lua_Number)(d))) -#define luaL_optlong(L,n,d) ((long)luaL_optnumber(L, n,(lua_Number)(d))) - - -/* -** {====================================================== -** Generic Buffer manipulation -** ======================================================= -*/ - - -#ifndef LUAL_BUFFERSIZE -#define LUAL_BUFFERSIZE BUFSIZ -#endif - - -typedef struct luaL_Buffer { - char *p; /* current position in buffer */ - int lvl; /* number of strings in the stack (level) */ - lua_State *L; - char buffer[LUAL_BUFFERSIZE]; -} luaL_Buffer; - -#define luaL_putchar(B,c) \ - ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ - (*(B)->p++ = (char)(c))) - -#define luaL_addsize(B,n) ((B)->p += (n)) - -LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B); -LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B); -LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l); -LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s); -LUALIB_API void luaL_addvalue (luaL_Buffer *B); -LUALIB_API void luaL_pushresult (luaL_Buffer *B); - - -/* }====================================================== */ - - - -/* -** Compatibility macros and functions -*/ - -LUALIB_API int lua_dofile (lua_State *L, const char *filename); -LUALIB_API int lua_dostring (lua_State *L, const char *str); -LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t sz, - const char *n); - - -#define luaL_check_lstr luaL_checklstring -#define luaL_opt_lstr luaL_optlstring -#define luaL_check_number luaL_checknumber -#define luaL_opt_number luaL_optnumber -#define luaL_arg_check luaL_argcheck -#define luaL_check_string luaL_checkstring -#define luaL_opt_string luaL_optstring -#define luaL_check_int luaL_checkint -#define luaL_check_long luaL_checklong -#define luaL_opt_int luaL_optint -#define luaL_opt_long luaL_optlong - - -#endif - - diff --git a/!NotAdopted/SmartAutoReplier/lualib/lbaselib.c b/!NotAdopted/SmartAutoReplier/lualib/lbaselib.c deleted file mode 100644 index 7381cf3357..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lbaselib.c +++ /dev/null @@ -1,674 +0,0 @@ -/* -** $Id: lbaselib.c,v 1.130 2003/04/03 13:35:34 roberto Exp $ -** Basic library -** See Copyright Notice in lua.h -*/ - - - -#include -#include -#include -#include - -#define lbaselib_c - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - - - -/* -** If your system does not support `stdout', you can just remove this function. -** If you need, you can define your own `print' function, following this -** model but changing `fputs' to put the strings at a proper place -** (a console window or a log file, for instance). -*/ -static int luaB_print (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - int i; - lua_getglobal(L, "tostring"); - for (i=1; i<=n; i++) { - const char *s; - lua_pushvalue(L, -1); /* function to be called */ - lua_pushvalue(L, i); /* value to print */ - lua_call(L, 1, 1); - s = lua_tostring(L, -1); /* get result */ - if (s == NULL) - return luaL_error(L, "`tostring' must return a string to `print'"); - if (i>1) fputs("\t", stdout); - fputs(s, stdout); - lua_pop(L, 1); /* pop result */ - } - fputs("\n", stdout); - return 0; -} - - -static int luaB_tonumber (lua_State *L) { - int base = luaL_optint(L, 2, 10); - if (base == 10) { /* standard conversion */ - luaL_checkany(L, 1); - if (lua_isnumber(L, 1)) { - lua_pushnumber(L, lua_tonumber(L, 1)); - return 1; - } - } - else { - const char *s1 = luaL_checkstring(L, 1); - char *s2; - unsigned long n; - luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); - n = strtoul(s1, &s2, base); - if (s1 != s2) { /* at least one valid digit? */ - while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ - if (*s2 == '\0') { /* no invalid trailing characters? */ - lua_pushnumber(L, (lua_Number)n); - return 1; - } - } - } - lua_pushnil(L); /* else not a number */ - return 1; -} - - -static int luaB_error (lua_State *L) { - int level = luaL_optint(L, 2, 1); - luaL_checkany(L, 1); - if (!lua_isstring(L, 1) || level == 0) - lua_pushvalue(L, 1); /* propagate error message without changes */ - else { /* add extra information */ - luaL_where(L, level); - lua_pushvalue(L, 1); - lua_concat(L, 2); - } - return lua_error(L); -} - - -static int luaB_getmetatable (lua_State *L) { - luaL_checkany(L, 1); - if (!lua_getmetatable(L, 1)) { - lua_pushnil(L); - return 1; /* no metatable */ - } - luaL_getmetafield(L, 1, "__metatable"); - return 1; /* returns either __metatable field (if present) or metatable */ -} - - -static int luaB_setmetatable (lua_State *L) { - int t = lua_type(L, 2); - luaL_checktype(L, 1, LUA_TTABLE); - luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, - "nil or table expected"); - if (luaL_getmetafield(L, 1, "__metatable")) - luaL_error(L, "cannot change a protected metatable"); - lua_settop(L, 2); - lua_setmetatable(L, 1); - return 1; -} - - -static void getfunc (lua_State *L) { - if (lua_isfunction(L, 1)) lua_pushvalue(L, 1); - else { - lua_Debug ar; - int level = luaL_optint(L, 1, 1); - luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); - if (lua_getstack(L, level, &ar) == 0) - luaL_argerror(L, 1, "invalid level"); - lua_getinfo(L, "f", &ar); - if (lua_isnil(L, -1)) - luaL_error(L, "no function environment for tail call at level %d", - level); - } -} - - -static int aux_getfenv (lua_State *L) { - lua_getfenv(L, -1); - lua_pushliteral(L, "__fenv"); - lua_rawget(L, -2); - return !lua_isnil(L, -1); -} - - -static int luaB_getfenv (lua_State *L) { - getfunc(L); - if (!aux_getfenv(L)) /* __fenv not defined? */ - lua_pop(L, 1); /* remove it, to return real environment */ - return 1; -} - - -static int luaB_setfenv (lua_State *L) { - luaL_checktype(L, 2, LUA_TTABLE); - getfunc(L); - if (aux_getfenv(L)) /* __fenv defined? */ - luaL_error(L, "`setfenv' cannot change a protected environment"); - else - lua_pop(L, 2); /* remove __fenv and real environment table */ - lua_pushvalue(L, 2); - if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) - lua_replace(L, LUA_GLOBALSINDEX); - else if (lua_setfenv(L, -2) == 0) - luaL_error(L, "`setfenv' cannot change environment of given function"); - return 0; -} - - -static int luaB_rawequal (lua_State *L) { - luaL_checkany(L, 1); - luaL_checkany(L, 2); - lua_pushboolean(L, lua_rawequal(L, 1, 2)); - return 1; -} - - -static int luaB_rawget (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - luaL_checkany(L, 2); - lua_rawget(L, 1); - return 1; -} - -static int luaB_rawset (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - luaL_checkany(L, 2); - luaL_checkany(L, 3); - lua_rawset(L, 1); - return 1; -} - - -static int luaB_gcinfo (lua_State *L) { - lua_pushnumber(L, (lua_Number)lua_getgccount(L)); - lua_pushnumber(L, (lua_Number)lua_getgcthreshold(L)); - return 2; -} - - -static int luaB_collectgarbage (lua_State *L) { - lua_setgcthreshold(L, luaL_optint(L, 1, 0)); - return 0; -} - - -static int luaB_type (lua_State *L) { - luaL_checkany(L, 1); - lua_pushstring(L, lua_typename(L, lua_type(L, 1))); - return 1; -} - - -static int luaB_next (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - lua_settop(L, 2); /* create a 2nd argument if there isn't one */ - if (lua_next(L, 1)) - return 2; - else { - lua_pushnil(L); - return 1; - } -} - - -static int luaB_pairs (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - lua_pushliteral(L, "next"); - lua_rawget(L, LUA_GLOBALSINDEX); /* return generator, */ - lua_pushvalue(L, 1); /* state, */ - lua_pushnil(L); /* and initial value */ - return 3; -} - - -static int luaB_ipairs (lua_State *L) { - lua_Number i = lua_tonumber(L, 2); - luaL_checktype(L, 1, LUA_TTABLE); - if (i == 0 && lua_isnone(L, 2)) { /* `for' start? */ - lua_pushliteral(L, "ipairs"); - lua_rawget(L, LUA_GLOBALSINDEX); /* return generator, */ - lua_pushvalue(L, 1); /* state, */ - lua_pushnumber(L, 0); /* and initial value */ - return 3; - } - else { /* `for' step */ - i++; /* next value */ - lua_pushnumber(L, i); - lua_rawgeti(L, 1, (int)i); - return (lua_isnil(L, -1)) ? 0 : 2; - } -} - - -static int load_aux (lua_State *L, int status) { - if (status == 0) /* OK? */ - return 1; - else { - lua_pushnil(L); - lua_insert(L, -2); /* put before error message */ - return 2; /* return nil plus error message */ - } -} - - -static int luaB_loadstring (lua_State *L) { - size_t l; - const char *s = luaL_checklstring(L, 1, &l); - const char *chunkname = luaL_optstring(L, 2, s); - return load_aux(L, luaL_loadbuffer(L, s, l, chunkname)); -} - - -static int luaB_loadfile (lua_State *L) { - const char *fname = luaL_optstring(L, 1, NULL); - return load_aux(L, luaL_loadfile(L, fname)); -} - - -static int luaB_dofile (lua_State *L) { - const char *fname = luaL_optstring(L, 1, NULL); - int status = luaL_loadfile(L, fname); - if (status != 0) lua_error(L); - lua_call(L, 0, LUA_MULTRET); - return lua_gettop(L) - 1; -} - - -static int luaB_assert (lua_State *L) { - luaL_checkany(L, 1); - if (!lua_toboolean(L, 1)) - return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); - lua_settop(L, 1); - return 1; -} - - -static int luaB_unpack (lua_State *L) { - int n, i; - luaL_checktype(L, 1, LUA_TTABLE); - n = luaL_getn(L, 1); - luaL_checkstack(L, n, "table too big to unpack"); - for (i=1; i<=n; i++) /* push arg[1...n] */ - lua_rawgeti(L, 1, i); - return n; -} - - -static int luaB_pcall (lua_State *L) { - int status; - luaL_checkany(L, 1); - status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); - lua_pushboolean(L, (status == 0)); - lua_insert(L, 1); - return lua_gettop(L); /* return status + all results */ -} - - -static int luaB_xpcall (lua_State *L) { - int status; - luaL_checkany(L, 2); - lua_settop(L, 2); - lua_insert(L, 1); /* put error function under function to be called */ - status = lua_pcall(L, 0, LUA_MULTRET, 1); - lua_pushboolean(L, (status == 0)); - lua_replace(L, 1); - return lua_gettop(L); /* return status + all results */ -} - - -static int luaB_tostring (lua_State *L) { - char buff[64]; - luaL_checkany(L, 1); - if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ - return 1; /* use its value */ - switch (lua_type(L, 1)) { - case LUA_TNUMBER: - lua_pushstring(L, lua_tostring(L, 1)); - return 1; - case LUA_TSTRING: - lua_pushvalue(L, 1); - return 1; - case LUA_TBOOLEAN: - lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false")); - return 1; - case LUA_TTABLE: - sprintf(buff, "table: %p", lua_topointer(L, 1)); - break; - case LUA_TFUNCTION: - sprintf(buff, "function: %p", lua_topointer(L, 1)); - break; - case LUA_TUSERDATA: - case LUA_TLIGHTUSERDATA: - sprintf(buff, "userdata: %p", lua_touserdata(L, 1)); - break; - case LUA_TTHREAD: - sprintf(buff, "thread: %p", (void *)lua_tothread(L, 1)); - break; - case LUA_TNIL: - lua_pushliteral(L, "nil"); - return 1; - } - lua_pushstring(L, buff); - return 1; -} - - -static int luaB_newproxy (lua_State *L) { - lua_settop(L, 1); - lua_newuserdata(L, 0); /* create proxy */ - if (lua_toboolean(L, 1) == 0) - return 1; /* no metatable */ - else if (lua_isboolean(L, 1)) { - lua_newtable(L); /* create a new metatable `m' ... */ - lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ - lua_pushboolean(L, 1); - lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */ - } - else { - int validproxy = 0; /* to check if weaktable[metatable(u)] == true */ - if (lua_getmetatable(L, 1)) { - lua_rawget(L, lua_upvalueindex(1)); - validproxy = lua_toboolean(L, -1); - lua_pop(L, 1); /* remove value */ - } - luaL_argcheck(L, validproxy, 1, "boolean or proxy expected"); - lua_getmetatable(L, 1); /* metatable is valid; get it */ - } - lua_setmetatable(L, 2); - return 1; -} - - -/* -** {====================================================== -** `require' function -** ======================================================= -*/ - - -/* name of global that holds table with loaded packages */ -#define REQTAB "_LOADED" - -/* name of global that holds the search path for packages */ -#define LUA_PATH "LUA_PATH" - -#ifndef LUA_PATH_SEP -#define LUA_PATH_SEP ';' -#endif - -#ifndef LUA_PATH_MARK -#define LUA_PATH_MARK '?' -#endif - -#ifndef LUA_PATH_DEFAULT -#define LUA_PATH_DEFAULT "?;?.lua" -#endif - - -static const char *getpath (lua_State *L) { - const char *path; - lua_getglobal(L, LUA_PATH); /* try global variable */ - path = lua_tostring(L, -1); - lua_pop(L, 1); - if (path) return path; - path = getenv(LUA_PATH); /* else try environment variable */ - if (path) return path; - return LUA_PATH_DEFAULT; /* else use default */ -} - - -static const char *pushnextpath (lua_State *L, const char *path) { - const char *l; - if (*path == '\0') return NULL; /* no more paths */ - if (*path == LUA_PATH_SEP) path++; /* skip separator */ - l = strchr(path, LUA_PATH_SEP); /* find next separator */ - if (l == NULL) l = path+strlen(path); - lua_pushlstring(L, path, l - path); /* directory name */ - return l; -} - - -static void pushcomposename (lua_State *L) { - const char *path = lua_tostring(L, -1); - const char *wild; - int n = 1; - while ((wild = strchr(path, LUA_PATH_MARK)) != NULL) { - /* is there stack space for prefix, name, and eventual last sufix? */ - luaL_checkstack(L, 3, "too many marks in a path component"); - lua_pushlstring(L, path, wild - path); /* push prefix */ - lua_pushvalue(L, 1); /* push package name (in place of MARK) */ - path = wild + 1; /* continue after MARK */ - n += 2; - } - lua_pushstring(L, path); /* push last sufix (`n' already includes this) */ - lua_concat(L, n); -} - - -static int luaB_require (lua_State *L) { - const char *path; - int status = LUA_ERRFILE; /* not found (yet) */ - luaL_checkstring(L, 1); - lua_settop(L, 1); - lua_getglobal(L, REQTAB); - if (!lua_istable(L, 2)) return luaL_error(L, "`" REQTAB "' is not a table"); - path = getpath(L); - lua_pushvalue(L, 1); /* check package's name in book-keeping table */ - lua_rawget(L, 2); - if (lua_toboolean(L, -1)) /* is it there? */ - return 1; /* package is already loaded; return its result */ - else { /* must load it */ - while (status == LUA_ERRFILE) { - lua_settop(L, 3); /* reset stack position */ - if ((path = pushnextpath(L, path)) == NULL) break; - pushcomposename(L); - status = luaL_loadfile(L, lua_tostring(L, -1)); /* try to load it */ - } - } - switch (status) { - case 0: { - lua_getglobal(L, "_REQUIREDNAME"); /* save previous name */ - lua_insert(L, -2); /* put it below function */ - lua_pushvalue(L, 1); - lua_setglobal(L, "_REQUIREDNAME"); /* set new name */ - lua_call(L, 0, 1); /* run loaded module */ - lua_insert(L, -2); /* put result below previous name */ - lua_setglobal(L, "_REQUIREDNAME"); /* reset to previous name */ - if (lua_isnil(L, -1)) { /* no/nil return? */ - lua_pushboolean(L, 1); - lua_replace(L, -2); /* replace to true */ - } - lua_pushvalue(L, 1); - lua_pushvalue(L, -2); - lua_rawset(L, 2); /* mark it as loaded */ - return 1; /* return value */ - } - case LUA_ERRFILE: { /* file not found */ - return luaL_error(L, "could not load package `%s' from path `%s'", - lua_tostring(L, 1), getpath(L)); - } - default: { - return luaL_error(L, "error loading package `%s' (%s)", - lua_tostring(L, 1), lua_tostring(L, -1)); - } - } -} - -/* }====================================================== */ - - -static const luaL_reg base_funcs[] = { - {"error", luaB_error}, - {"getmetatable", luaB_getmetatable}, - {"setmetatable", luaB_setmetatable}, - {"getfenv", luaB_getfenv}, - {"setfenv", luaB_setfenv}, - {"next", luaB_next}, - {"ipairs", luaB_ipairs}, - {"pairs", luaB_pairs}, - {"print", luaB_print}, - {"tonumber", luaB_tonumber}, - {"tostring", luaB_tostring}, - {"type", luaB_type}, - {"assert", luaB_assert}, - {"unpack", luaB_unpack}, - {"rawequal", luaB_rawequal}, - {"rawget", luaB_rawget}, - {"rawset", luaB_rawset}, - {"pcall", luaB_pcall}, - {"xpcall", luaB_xpcall}, - {"collectgarbage", luaB_collectgarbage}, - {"gcinfo", luaB_gcinfo}, - {"loadfile", luaB_loadfile}, - {"dofile", luaB_dofile}, - {"loadstring", luaB_loadstring}, - {"require", luaB_require}, - {NULL, NULL} -}; - - -/* -** {====================================================== -** Coroutine library -** ======================================================= -*/ - -static int auxresume (lua_State *L, lua_State *co, int narg) { - int status; - if (!lua_checkstack(co, narg)) - luaL_error(L, "too many arguments to resume"); - lua_xmove(L, co, narg); - status = lua_resume(co, narg); - if (status == 0) { - int nres = lua_gettop(co); - if (!lua_checkstack(L, nres)) - luaL_error(L, "too many results to resume"); - lua_xmove(co, L, nres); /* move yielded values */ - return nres; - } - else { - lua_xmove(co, L, 1); /* move error message */ - return -1; /* error flag */ - } -} - - -static int luaB_coresume (lua_State *L) { - lua_State *co = lua_tothread(L, 1); - int r; - luaL_argcheck(L, co, 1, "coroutine expected"); - r = auxresume(L, co, lua_gettop(L) - 1); - if (r < 0) { - lua_pushboolean(L, 0); - lua_insert(L, -2); - return 2; /* return false + error message */ - } - else { - lua_pushboolean(L, 1); - lua_insert(L, -(r + 1)); - return r + 1; /* return true + `resume' returns */ - } -} - - -static int luaB_auxwrap (lua_State *L) { - lua_State *co = lua_tothread(L, lua_upvalueindex(1)); - int r = auxresume(L, co, lua_gettop(L)); - if (r < 0) { - if (lua_isstring(L, -1)) { /* error object is a string? */ - luaL_where(L, 1); /* add extra info */ - lua_insert(L, -2); - lua_concat(L, 2); - } - lua_error(L); /* propagate error */ - } - return r; -} - - -static int luaB_cocreate (lua_State *L) { - lua_State *NL = lua_newthread(L); - luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, - "Lua function expected"); - lua_pushvalue(L, 1); /* move function to top */ - lua_xmove(L, NL, 1); /* move function from L to NL */ - return 1; -} - - -static int luaB_cowrap (lua_State *L) { - luaB_cocreate(L); - lua_pushcclosure(L, luaB_auxwrap, 1); - return 1; -} - - -static int luaB_yield (lua_State *L) { - return lua_yield(L, lua_gettop(L)); -} - - -static int luaB_costatus (lua_State *L) { - lua_State *co = lua_tothread(L, 1); - luaL_argcheck(L, co, 1, "coroutine expected"); - if (L == co) lua_pushliteral(L, "running"); - else { - lua_Debug ar; - if (lua_getstack(co, 0, &ar) == 0 && lua_gettop(co) == 0) - lua_pushliteral(L, "dead"); - else - lua_pushliteral(L, "suspended"); - } - return 1; -} - - -static const luaL_reg co_funcs[] = { - {"create", luaB_cocreate}, - {"wrap", luaB_cowrap}, - {"resume", luaB_coresume}, - {"yield", luaB_yield}, - {"status", luaB_costatus}, - {NULL, NULL} -}; - -/* }====================================================== */ - - - -static void base_open (lua_State *L) { - lua_pushliteral(L, "_G"); - lua_pushvalue(L, LUA_GLOBALSINDEX); - luaL_openlib(L, NULL, base_funcs, 0); /* open lib into global table */ - lua_pushliteral(L, "_VERSION"); - lua_pushliteral(L, LUA_VERSION); - lua_rawset(L, -3); /* set global _VERSION */ - /* `newproxy' needs a weaktable as upvalue */ - lua_pushliteral(L, "newproxy"); - lua_newtable(L); /* new table `w' */ - lua_pushvalue(L, -1); /* `w' will be its own metatable */ - lua_setmetatable(L, -2); - lua_pushliteral(L, "__mode"); - lua_pushliteral(L, "k"); - lua_rawset(L, -3); /* metatable(w).__mode = "k" */ - lua_pushcclosure(L, luaB_newproxy, 1); - lua_rawset(L, -3); /* set global `newproxy' */ - lua_rawset(L, -1); /* set global _G */ -} - - -LUALIB_API int luaopen_base (lua_State *L) { - base_open(L); - luaL_openlib(L, LUA_COLIBNAME, co_funcs, 0); - lua_newtable(L); - lua_setglobal(L, REQTAB); - return 0; -} - diff --git a/!NotAdopted/SmartAutoReplier/lualib/lcode.c b/!NotAdopted/SmartAutoReplier/lualib/lcode.c deleted file mode 100644 index d626ecd60e..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lcode.c +++ /dev/null @@ -1,714 +0,0 @@ -/* -** $Id: lcode.c,v 1.117 2003/04/03 13:35:34 roberto Exp $ -** Code generator for Lua -** See Copyright Notice in lua.h -*/ - - -#include - -#define lcode_c - -#include "lua.h" - -#include "lcode.h" -#include "ldebug.h" -#include "ldo.h" -#include "llex.h" -#include "lmem.h" -#include "lobject.h" -#include "lopcodes.h" -#include "lparser.h" -#include "ltable.h" - - -#define hasjumps(e) ((e)->t != (e)->f) - - -void luaK_nil (FuncState *fs, int from, int n) { - Instruction *previous; - if (fs->pc > fs->lasttarget && /* no jumps to current position? */ - GET_OPCODE(*(previous = &fs->f->code[fs->pc-1])) == OP_LOADNIL) { - int pfrom = GETARG_A(*previous); - int pto = GETARG_B(*previous); - if (pfrom <= from && from <= pto+1) { /* can connect both? */ - if (from+n-1 > pto) - SETARG_B(*previous, from+n-1); - return; - } - } - luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */ -} - - -int luaK_jump (FuncState *fs) { - int jpc = fs->jpc; /* save list of jumps to here */ - int j; - fs->jpc = NO_JUMP; - j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); - luaK_concat(fs, &j, jpc); /* keep them on hold */ - return j; -} - - -static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) { - luaK_codeABC(fs, op, A, B, C); - return luaK_jump(fs); -} - - -static void luaK_fixjump (FuncState *fs, int pc, int dest) { - Instruction *jmp = &fs->f->code[pc]; - int offset = dest-(pc+1); - lua_assert(dest != NO_JUMP); - if (abs(offset) > MAXARG_sBx) - luaX_syntaxerror(fs->ls, "control structure too long"); - SETARG_sBx(*jmp, offset); -} - - -/* -** returns current `pc' and marks it as a jump target (to avoid wrong -** optimizations with consecutive instructions not in the same basic block). -*/ -int luaK_getlabel (FuncState *fs) { - fs->lasttarget = fs->pc; - return fs->pc; -} - - -static int luaK_getjump (FuncState *fs, int pc) { - int offset = GETARG_sBx(fs->f->code[pc]); - if (offset == NO_JUMP) /* point to itself represents end of list */ - return NO_JUMP; /* end of list */ - else - return (pc+1)+offset; /* turn offset into absolute position */ -} - - -static Instruction *getjumpcontrol (FuncState *fs, int pc) { - Instruction *pi = &fs->f->code[pc]; - if (pc >= 1 && testOpMode(GET_OPCODE(*(pi-1)), OpModeT)) - return pi-1; - else - return pi; -} - - -/* -** check whether list has any jump that do not produce a value -** (or produce an inverted value) -*/ -static int need_value (FuncState *fs, int list, int cond) { - for (; list != NO_JUMP; list = luaK_getjump(fs, list)) { - Instruction i = *getjumpcontrol(fs, list); - if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1; - } - return 0; /* not found */ -} - - -static void patchtestreg (Instruction *i, int reg) { - if (reg == NO_REG) reg = GETARG_B(*i); - SETARG_A(*i, reg); -} - - -static void luaK_patchlistaux (FuncState *fs, int list, - int ttarget, int treg, int ftarget, int freg, int dtarget) { - while (list != NO_JUMP) { - int next = luaK_getjump(fs, list); - Instruction *i = getjumpcontrol(fs, list); - if (GET_OPCODE(*i) != OP_TEST) { - lua_assert(dtarget != NO_JUMP); - luaK_fixjump(fs, list, dtarget); /* jump to default target */ - } - else { - if (GETARG_C(*i)) { - lua_assert(ttarget != NO_JUMP); - patchtestreg(i, treg); - luaK_fixjump(fs, list, ttarget); - } - else { - lua_assert(ftarget != NO_JUMP); - patchtestreg(i, freg); - luaK_fixjump(fs, list, ftarget); - } - } - list = next; - } -} - - -static void luaK_dischargejpc (FuncState *fs) { - luaK_patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc, NO_REG, fs->pc); - fs->jpc = NO_JUMP; -} - - -void luaK_patchlist (FuncState *fs, int list, int target) { - if (target == fs->pc) - luaK_patchtohere(fs, list); - else { - lua_assert(target < fs->pc); - luaK_patchlistaux(fs, list, target, NO_REG, target, NO_REG, target); - } -} - - -void luaK_patchtohere (FuncState *fs, int list) { - luaK_getlabel(fs); - luaK_concat(fs, &fs->jpc, list); -} - - -void luaK_concat (FuncState *fs, int *l1, int l2) { - if (l2 == NO_JUMP) return; - else if (*l1 == NO_JUMP) - *l1 = l2; - else { - int list = *l1; - int next; - while ((next = luaK_getjump(fs, list)) != NO_JUMP) /* find last element */ - list = next; - luaK_fixjump(fs, list, l2); - } -} - - -void luaK_checkstack (FuncState *fs, int n) { - int newstack = fs->freereg + n; - if (newstack > fs->f->maxstacksize) { - if (newstack >= MAXSTACK) - luaX_syntaxerror(fs->ls, "function or expression too complex"); - fs->f->maxstacksize = cast(lu_byte, newstack); - } -} - - -void luaK_reserveregs (FuncState *fs, int n) { - luaK_checkstack(fs, n); - fs->freereg += n; -} - - -static void freereg (FuncState *fs, int reg) { - if (reg >= fs->nactvar && reg < MAXSTACK) { - fs->freereg--; - lua_assert(reg == fs->freereg); - } -} - - -static void freeexp (FuncState *fs, expdesc *e) { - if (e->k == VNONRELOC) - freereg(fs, e->info); -} - - -static int addk (FuncState *fs, TObject *k, TObject *v) { - const TObject *idx = luaH_get(fs->h, k); - if (ttisnumber(idx)) { - lua_assert(luaO_rawequalObj(&fs->f->k[cast(int, nvalue(idx))], v)); - return cast(int, nvalue(idx)); - } - else { /* constant not found; create a new entry */ - Proto *f = fs->f; - luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject, - MAXARG_Bx, "constant table overflow"); - setobj2n(&f->k[fs->nk], v); - setnvalue(luaH_set(fs->L, fs->h, k), cast(lua_Number, fs->nk)); - return fs->nk++; - } -} - - -int luaK_stringK (FuncState *fs, TString *s) { - TObject o; - setsvalue(&o, s); - return addk(fs, &o, &o); -} - - -int luaK_numberK (FuncState *fs, lua_Number r) { - TObject o; - setnvalue(&o, r); - return addk(fs, &o, &o); -} - - -static int nil_constant (FuncState *fs) { - TObject k, v; - setnilvalue(&v); - sethvalue(&k, fs->h); /* cannot use nil as key; instead use table itself */ - return addk(fs, &k, &v); -} - - -void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) { - if (e->k == VCALL) { /* expression is an open function call? */ - SETARG_C(getcode(fs, e), nresults+1); - if (nresults == 1) { /* `regular' expression? */ - e->k = VNONRELOC; - e->info = GETARG_A(getcode(fs, e)); - } - } -} - - -void luaK_dischargevars (FuncState *fs, expdesc *e) { - switch (e->k) { - case VLOCAL: { - e->k = VNONRELOC; - break; - } - case VUPVAL: { - e->info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->info, 0); - e->k = VRELOCABLE; - break; - } - case VGLOBAL: { - e->info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->info); - e->k = VRELOCABLE; - break; - } - case VINDEXED: { - freereg(fs, e->aux); - freereg(fs, e->info); - e->info = luaK_codeABC(fs, OP_GETTABLE, 0, e->info, e->aux); - e->k = VRELOCABLE; - break; - } - case VCALL: { - luaK_setcallreturns(fs, e, 1); - break; - } - default: break; /* there is one value available (somewhere) */ - } -} - - -static int code_label (FuncState *fs, int A, int b, int jump) { - luaK_getlabel(fs); /* those instructions may be jump targets */ - return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); -} - - -static void discharge2reg (FuncState *fs, expdesc *e, int reg) { - luaK_dischargevars(fs, e); - switch (e->k) { - case VNIL: { - luaK_nil(fs, reg, 1); - break; - } - case VFALSE: case VTRUE: { - luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); - break; - } - case VK: { - luaK_codeABx(fs, OP_LOADK, reg, e->info); - break; - } - case VRELOCABLE: { - Instruction *pc = &getcode(fs, e); - SETARG_A(*pc, reg); - break; - } - case VNONRELOC: { - if (reg != e->info) - luaK_codeABC(fs, OP_MOVE, reg, e->info, 0); - break; - } - default: { - lua_assert(e->k == VVOID || e->k == VJMP); - return; /* nothing to do... */ - } - } - e->info = reg; - e->k = VNONRELOC; -} - - -static void discharge2anyreg (FuncState *fs, expdesc *e) { - if (e->k != VNONRELOC) { - luaK_reserveregs(fs, 1); - discharge2reg(fs, e, fs->freereg-1); - } -} - - -static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) { - discharge2reg(fs, e, reg); - if (e->k == VJMP) - luaK_concat(fs, &e->t, e->info); /* put this jump in `t' list */ - if (hasjumps(e)) { - int final; /* position after whole expression */ - int p_f = NO_JUMP; /* position of an eventual LOAD false */ - int p_t = NO_JUMP; /* position of an eventual LOAD true */ - if (need_value(fs, e->t, 1) || need_value(fs, e->f, 0)) { - int fj = NO_JUMP; /* first jump (over LOAD ops.) */ - if (e->k != VJMP) - fj = luaK_jump(fs); - p_f = code_label(fs, reg, 0, 1); - p_t = code_label(fs, reg, 1, 0); - luaK_patchtohere(fs, fj); - } - final = luaK_getlabel(fs); - luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f); - luaK_patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t); - } - e->f = e->t = NO_JUMP; - e->info = reg; - e->k = VNONRELOC; -} - - -void luaK_exp2nextreg (FuncState *fs, expdesc *e) { - luaK_dischargevars(fs, e); - freeexp(fs, e); - luaK_reserveregs(fs, 1); - luaK_exp2reg(fs, e, fs->freereg - 1); -} - - -int luaK_exp2anyreg (FuncState *fs, expdesc *e) { - luaK_dischargevars(fs, e); - if (e->k == VNONRELOC) { - if (!hasjumps(e)) return e->info; /* exp is already in a register */ - if (e->info >= fs->nactvar) { /* reg. is not a local? */ - luaK_exp2reg(fs, e, e->info); /* put value on it */ - return e->info; - } - } - luaK_exp2nextreg(fs, e); /* default */ - return e->info; -} - - -void luaK_exp2val (FuncState *fs, expdesc *e) { - if (hasjumps(e)) - luaK_exp2anyreg(fs, e); - else - luaK_dischargevars(fs, e); -} - - -int luaK_exp2RK (FuncState *fs, expdesc *e) { - luaK_exp2val(fs, e); - switch (e->k) { - case VNIL: { - if (fs->nk + MAXSTACK <= MAXARG_C) { /* constant fit in argC? */ - e->info = nil_constant(fs); - e->k = VK; - return e->info + MAXSTACK; - } - else break; - } - case VK: { - if (e->info + MAXSTACK <= MAXARG_C) /* constant fit in argC? */ - return e->info + MAXSTACK; - else break; - } - default: break; - } - /* not a constant in the right range: put it in a register */ - return luaK_exp2anyreg(fs, e); -} - - -void luaK_storevar (FuncState *fs, expdesc *var, expdesc *exp) { - switch (var->k) { - case VLOCAL: { - freeexp(fs, exp); - luaK_exp2reg(fs, exp, var->info); - return; - } - case VUPVAL: { - int e = luaK_exp2anyreg(fs, exp); - luaK_codeABC(fs, OP_SETUPVAL, e, var->info, 0); - break; - } - case VGLOBAL: { - int e = luaK_exp2anyreg(fs, exp); - luaK_codeABx(fs, OP_SETGLOBAL, e, var->info); - break; - } - case VINDEXED: { - int e = luaK_exp2RK(fs, exp); - luaK_codeABC(fs, OP_SETTABLE, var->info, var->aux, e); - break; - } - default: { - lua_assert(0); /* invalid var kind to store */ - break; - } - } - freeexp(fs, exp); -} - - -void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { - int func; - luaK_exp2anyreg(fs, e); - freeexp(fs, e); - func = fs->freereg; - luaK_reserveregs(fs, 2); - luaK_codeABC(fs, OP_SELF, func, e->info, luaK_exp2RK(fs, key)); - freeexp(fs, key); - e->info = func; - e->k = VNONRELOC; -} - - -static void invertjump (FuncState *fs, expdesc *e) { - Instruction *pc = getjumpcontrol(fs, e->info); - lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT) && - GET_OPCODE(*pc) != OP_TEST); - SETARG_A(*pc, !(GETARG_A(*pc))); -} - - -static int jumponcond (FuncState *fs, expdesc *e, int cond) { - if (e->k == VRELOCABLE) { - Instruction ie = getcode(fs, e); - if (GET_OPCODE(ie) == OP_NOT) { - fs->pc--; /* remove previous OP_NOT */ - return luaK_condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond); - } - /* else go through */ - } - discharge2anyreg(fs, e); - freeexp(fs, e); - return luaK_condjump(fs, OP_TEST, NO_REG, e->info, cond); -} - - -void luaK_goiftrue (FuncState *fs, expdesc *e) { - int pc; /* pc of last jump */ - luaK_dischargevars(fs, e); - switch (e->k) { - case VK: case VTRUE: { - pc = NO_JUMP; /* always true; do nothing */ - break; - } - case VFALSE: { - pc = luaK_jump(fs); /* always jump */ - break; - } - case VJMP: { - invertjump(fs, e); - pc = e->info; - break; - } - default: { - pc = jumponcond(fs, e, 0); - break; - } - } - luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ -} - - -void luaK_goiffalse (FuncState *fs, expdesc *e) { - int pc; /* pc of last jump */ - luaK_dischargevars(fs, e); - switch (e->k) { - case VNIL: case VFALSE: { - pc = NO_JUMP; /* always false; do nothing */ - break; - } - case VTRUE: { - pc = luaK_jump(fs); /* always jump */ - break; - } - case VJMP: { - pc = e->info; - break; - } - default: { - pc = jumponcond(fs, e, 1); - break; - } - } - luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ -} - - -static void codenot (FuncState *fs, expdesc *e) { - luaK_dischargevars(fs, e); - switch (e->k) { - case VNIL: case VFALSE: { - e->k = VTRUE; - break; - } - case VK: case VTRUE: { - e->k = VFALSE; - break; - } - case VJMP: { - invertjump(fs, e); - break; - } - case VRELOCABLE: - case VNONRELOC: { - discharge2anyreg(fs, e); - freeexp(fs, e); - e->info = luaK_codeABC(fs, OP_NOT, 0, e->info, 0); - e->k = VRELOCABLE; - break; - } - default: { - lua_assert(0); /* cannot happen */ - break; - } - } - /* interchange true and false lists */ - { int temp = e->f; e->f = e->t; e->t = temp; } -} - - -void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { - t->aux = luaK_exp2RK(fs, k); - t->k = VINDEXED; -} - - -void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { - if (op == OPR_MINUS) { - luaK_exp2val(fs, e); - if (e->k == VK && ttisnumber(&fs->f->k[e->info])) - e->info = luaK_numberK(fs, -nvalue(&fs->f->k[e->info])); - else { - luaK_exp2anyreg(fs, e); - freeexp(fs, e); - e->info = luaK_codeABC(fs, OP_UNM, 0, e->info, 0); - e->k = VRELOCABLE; - } - } - else /* op == NOT */ - codenot(fs, e); -} - - -void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { - switch (op) { - case OPR_AND: { - luaK_goiftrue(fs, v); - luaK_patchtohere(fs, v->t); - v->t = NO_JUMP; - break; - } - case OPR_OR: { - luaK_goiffalse(fs, v); - luaK_patchtohere(fs, v->f); - v->f = NO_JUMP; - break; - } - case OPR_CONCAT: { - luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ - break; - } - default: { - luaK_exp2RK(fs, v); - break; - } - } -} - - -static void codebinop (FuncState *fs, expdesc *res, BinOpr op, - int o1, int o2) { - if (op <= OPR_POW) { /* arithmetic operator? */ - OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD); /* ORDER OP */ - res->info = luaK_codeABC(fs, opc, 0, o1, o2); - res->k = VRELOCABLE; - } - else { /* test operator */ - static const OpCode ops[] = {OP_EQ, OP_EQ, OP_LT, OP_LE, OP_LT, OP_LE}; - int cond = 1; - if (op >= OPR_GT) { /* `>' or `>='? */ - int temp; /* exchange args and replace by `<' or `<=' */ - temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ - } - else if (op == OPR_NE) cond = 0; - res->info = luaK_condjump(fs, ops[op - OPR_NE], cond, o1, o2); - res->k = VJMP; - } -} - - -void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { - switch (op) { - case OPR_AND: { - lua_assert(e1->t == NO_JUMP); /* list must be closed */ - luaK_dischargevars(fs, e2); - luaK_concat(fs, &e1->f, e2->f); - e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->t = e2->t; - break; - } - case OPR_OR: { - lua_assert(e1->f == NO_JUMP); /* list must be closed */ - luaK_dischargevars(fs, e2); - luaK_concat(fs, &e1->t, e2->t); - e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->f = e2->f; - break; - } - case OPR_CONCAT: { - luaK_exp2val(fs, e2); - if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { - lua_assert(e1->info == GETARG_B(getcode(fs, e2))-1); - freeexp(fs, e1); - SETARG_B(getcode(fs, e2), e1->info); - e1->k = e2->k; e1->info = e2->info; - } - else { - luaK_exp2nextreg(fs, e2); - freeexp(fs, e2); - freeexp(fs, e1); - e1->info = luaK_codeABC(fs, OP_CONCAT, 0, e1->info, e2->info); - e1->k = VRELOCABLE; - } - break; - } - default: { - int o1 = luaK_exp2RK(fs, e1); - int o2 = luaK_exp2RK(fs, e2); - freeexp(fs, e2); - freeexp(fs, e1); - codebinop(fs, e1, op, o1, o2); - } - } -} - - -void luaK_fixline (FuncState *fs, int line) { - fs->f->lineinfo[fs->pc - 1] = line; -} - - -int luaK_code (FuncState *fs, Instruction i, int line) { - Proto *f = fs->f; - luaK_dischargejpc(fs); /* `pc' will change */ - /* put new instruction in code array */ - luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, - MAX_INT, "code size overflow"); - f->code[fs->pc] = i; - /* save corresponding line information */ - luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, - MAX_INT, "code size overflow"); - f->lineinfo[fs->pc] = line; - return fs->pc++; -} - - -int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { - lua_assert(getOpMode(o) == iABC); - return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline); -} - - -int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { - lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); - return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); -} - diff --git a/!NotAdopted/SmartAutoReplier/lualib/lcode.h b/!NotAdopted/SmartAutoReplier/lualib/lcode.h deleted file mode 100644 index 74908c6580..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lcode.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -** $Id: lcode.h,v 1.38 2002/12/11 12:34:22 roberto Exp $ -** Code generator for Lua -** See Copyright Notice in lua.h -*/ - -#ifndef lcode_h -#define lcode_h - -#include "llex.h" -#include "lobject.h" -#include "lopcodes.h" -#include "lparser.h" - - -/* -** Marks the end of a patch list. It is an invalid value both as an absolute -** address, and as a list link (would link an element to itself). -*/ -#define NO_JUMP (-1) - - -/* -** grep "ORDER OPR" if you change these enums -*/ -typedef enum BinOpr { - OPR_ADD, OPR_SUB, OPR_MULT, OPR_DIV, OPR_POW, - OPR_CONCAT, - OPR_NE, OPR_EQ, - OPR_LT, OPR_LE, OPR_GT, OPR_GE, - OPR_AND, OPR_OR, - OPR_NOBINOPR -} BinOpr; - -#define binopistest(op) ((op) >= OPR_NE) - -typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr; - - -#define getcode(fs,e) ((fs)->f->code[(e)->info]) - -#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) - -int luaK_code (FuncState *fs, Instruction i, int line); -int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); -int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); -void luaK_fixline (FuncState *fs, int line); -void luaK_nil (FuncState *fs, int from, int n); -void luaK_reserveregs (FuncState *fs, int n); -void luaK_checkstack (FuncState *fs, int n); -int luaK_stringK (FuncState *fs, TString *s); -int luaK_numberK (FuncState *fs, lua_Number r); -void luaK_dischargevars (FuncState *fs, expdesc *e); -int luaK_exp2anyreg (FuncState *fs, expdesc *e); -void luaK_exp2nextreg (FuncState *fs, expdesc *e); -void luaK_exp2val (FuncState *fs, expdesc *e); -int luaK_exp2RK (FuncState *fs, expdesc *e); -void luaK_self (FuncState *fs, expdesc *e, expdesc *key); -void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); -void luaK_goiftrue (FuncState *fs, expdesc *e); -void luaK_goiffalse (FuncState *fs, expdesc *e); -void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); -void luaK_setcallreturns (FuncState *fs, expdesc *var, int nresults); -int luaK_jump (FuncState *fs); -void luaK_patchlist (FuncState *fs, int list, int target); -void luaK_patchtohere (FuncState *fs, int list); -void luaK_concat (FuncState *fs, int *l1, int l2); -int luaK_getlabel (FuncState *fs); -void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); -void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); -void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); - - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/ldblib.c b/!NotAdopted/SmartAutoReplier/lualib/ldblib.c deleted file mode 100644 index 6dc9b64cfc..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/ldblib.c +++ /dev/null @@ -1,299 +0,0 @@ -/* -** $Id: ldblib.c,v 1.80 2003/04/03 13:35:34 roberto Exp $ -** Interface from Lua to its debug API -** See Copyright Notice in lua.h -*/ - - -#include -#include -#include - -#define ldblib_c - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - - -static void settabss (lua_State *L, const char *i, const char *v) { - lua_pushstring(L, i); - lua_pushstring(L, v); - lua_rawset(L, -3); -} - - -static void settabsi (lua_State *L, const char *i, int v) { - lua_pushstring(L, i); - lua_pushnumber(L, (lua_Number)v); - lua_rawset(L, -3); -} - - -static int getinfo (lua_State *L) { - lua_Debug ar; - const char *options = luaL_optstring(L, 2, "flnSu"); - if (lua_isnumber(L, 1)) { - if (!lua_getstack(L, (int)(lua_tonumber(L, 1)), &ar)) { - lua_pushnil(L); /* level out of range */ - return 1; - } - } - else if (lua_isfunction(L, 1)) { - lua_pushfstring(L, ">%s", options); - options = lua_tostring(L, -1); - lua_pushvalue(L, 1); - } - else - return luaL_argerror(L, 1, "function or level expected"); - if (!lua_getinfo(L, options, &ar)) - return luaL_argerror(L, 2, "invalid option"); - lua_newtable(L); - for (; *options; options++) { - switch (*options) { - case 'S': - settabss(L, "source", ar.source); - settabss(L, "short_src", ar.short_src); - settabsi(L, "linedefined", ar.linedefined); - settabss(L, "what", ar.what); - break; - case 'l': - settabsi(L, "currentline", ar.currentline); - break; - case 'u': - settabsi(L, "nups", ar.nups); - break; - case 'n': - settabss(L, "name", ar.name); - settabss(L, "namewhat", ar.namewhat); - break; - case 'f': - lua_pushliteral(L, "func"); - lua_pushvalue(L, -3); - lua_rawset(L, -3); - break; - } - } - return 1; /* return table */ -} - - -static int getlocal (lua_State *L) { - lua_Debug ar; - const char *name; - if (!lua_getstack(L, luaL_checkint(L, 1), &ar)) /* level out of range? */ - return luaL_argerror(L, 1, "level out of range"); - name = lua_getlocal(L, &ar, luaL_checkint(L, 2)); - if (name) { - lua_pushstring(L, name); - lua_pushvalue(L, -2); - return 2; - } - else { - lua_pushnil(L); - return 1; - } -} - - -static int setlocal (lua_State *L) { - lua_Debug ar; - if (!lua_getstack(L, luaL_checkint(L, 1), &ar)) /* level out of range? */ - return luaL_argerror(L, 1, "level out of range"); - luaL_checkany(L, 3); - lua_pushstring(L, lua_setlocal(L, &ar, luaL_checkint(L, 2))); - return 1; -} - - -static int auxupvalue (lua_State *L, int get) { - const char *name; - int n = luaL_checkint(L, 2); - luaL_checktype(L, 1, LUA_TFUNCTION); - if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */ - name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); - if (name == NULL) return 0; - lua_pushstring(L, name); - lua_insert(L, -(get+1)); - return get + 1; -} - - -static int getupvalue (lua_State *L) { - return auxupvalue(L, 1); -} - - -static int setupvalue (lua_State *L) { - luaL_checkany(L, 3); - return auxupvalue(L, 0); -} - - - -static const char KEY_HOOK = 'h'; - - -static void hookf (lua_State *L, lua_Debug *ar) { - static const char *const hooknames[] = - {"call", "return", "line", "count", "tail return"}; - lua_pushlightuserdata(L, (void *)&KEY_HOOK); - lua_rawget(L, LUA_REGISTRYINDEX); - if (lua_isfunction(L, -1)) { - lua_pushstring(L, hooknames[(int)ar->event]); - if (ar->currentline >= 0) - lua_pushnumber(L, (lua_Number)ar->currentline); - else lua_pushnil(L); - lua_assert(lua_getinfo(L, "lS", ar)); - lua_call(L, 2, 0); - } - else - lua_pop(L, 1); /* pop result from gettable */ -} - - -static int makemask (const char *smask, int count) { - int mask = 0; - if (strchr(smask, 'c')) mask |= LUA_MASKCALL; - if (strchr(smask, 'r')) mask |= LUA_MASKRET; - if (strchr(smask, 'l')) mask |= LUA_MASKLINE; - if (count > 0) mask |= LUA_MASKCOUNT; - return mask; -} - - -static char *unmakemask (int mask, char *smask) { - int i = 0; - if (mask & LUA_MASKCALL) smask[i++] = 'c'; - if (mask & LUA_MASKRET) smask[i++] = 'r'; - if (mask & LUA_MASKLINE) smask[i++] = 'l'; - smask[i] = '\0'; - return smask; -} - - -static int sethook (lua_State *L) { - if (lua_isnoneornil(L, 1)) { - lua_settop(L, 1); - lua_sethook(L, NULL, 0, 0); /* turn off hooks */ - } - else { - const char *smask = luaL_checkstring(L, 2); - int count = luaL_optint(L, 3, 0); - luaL_checktype(L, 1, LUA_TFUNCTION); - lua_sethook(L, hookf, makemask(smask, count), count); - } - lua_pushlightuserdata(L, (void *)&KEY_HOOK); - lua_pushvalue(L, 1); - lua_rawset(L, LUA_REGISTRYINDEX); /* set new hook */ - return 0; -} - - -static int gethook (lua_State *L) { - char buff[5]; - int mask = lua_gethookmask(L); - lua_Hook hook = lua_gethook(L); - if (hook != NULL && hook != hookf) /* external hook? */ - lua_pushliteral(L, "external hook"); - else { - lua_pushlightuserdata(L, (void *)&KEY_HOOK); - lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */ - } - lua_pushstring(L, unmakemask(mask, buff)); - lua_pushnumber(L, (lua_Number)lua_gethookcount(L)); - return 3; -} - - -static int debug (lua_State *L) { - for (;;) { - char buffer[250]; - fputs("lua_debug> ", stderr); - if (fgets(buffer, sizeof(buffer), stdin) == 0 || - strcmp(buffer, "cont\n") == 0) - return 0; - lua_dostring(L, buffer); - lua_settop(L, 0); /* remove eventual returns */ - } -} - - -#define LEVELS1 12 /* size of the first part of the stack */ -#define LEVELS2 10 /* size of the second part of the stack */ - -static int errorfb (lua_State *L) { - int level = 1; /* skip level 0 (it's this function) */ - int firstpart = 1; /* still before eventual `...' */ - lua_Debug ar; - if (lua_gettop(L) == 0) - lua_pushliteral(L, ""); - else if (!lua_isstring(L, 1)) return 1; /* no string message */ - else lua_pushliteral(L, "\n"); - lua_pushliteral(L, "stack traceback:"); - while (lua_getstack(L, level++, &ar)) { - if (level > LEVELS1 && firstpart) { - /* no more than `LEVELS2' more levels? */ - if (!lua_getstack(L, level+LEVELS2, &ar)) - level--; /* keep going */ - else { - lua_pushliteral(L, "\n\t..."); /* too many levels */ - while (lua_getstack(L, level+LEVELS2, &ar)) /* find last levels */ - level++; - } - firstpart = 0; - continue; - } - lua_pushliteral(L, "\n\t"); - lua_getinfo(L, "Snl", &ar); - lua_pushfstring(L, "%s:", ar.short_src); - if (ar.currentline > 0) - lua_pushfstring(L, "%d:", ar.currentline); - switch (*ar.namewhat) { - case 'g': /* global */ - case 'l': /* local */ - case 'f': /* field */ - case 'm': /* method */ - lua_pushfstring(L, " in function `%s'", ar.name); - break; - default: { - if (*ar.what == 'm') /* main? */ - lua_pushfstring(L, " in main chunk"); - else if (*ar.what == 'C' || *ar.what == 't') - lua_pushliteral(L, " ?"); /* C function or tail call */ - else - lua_pushfstring(L, " in function <%s:%d>", - ar.short_src, ar.linedefined); - } - } - lua_concat(L, lua_gettop(L)); - } - lua_concat(L, lua_gettop(L)); - return 1; -} - - -static const luaL_reg dblib[] = { - {"getlocal", getlocal}, - {"getinfo", getinfo}, - {"gethook", gethook}, - {"getupvalue", getupvalue}, - {"sethook", sethook}, - {"setlocal", setlocal}, - {"setupvalue", setupvalue}, - {"debug", debug}, - {"traceback", errorfb}, - {NULL, NULL} -}; - - -LUALIB_API int luaopen_debug (lua_State *L) { - luaL_openlib(L, LUA_DBLIBNAME, dblib, 0); - lua_pushliteral(L, "_TRACEBACK"); - lua_pushcfunction(L, errorfb); - lua_settable(L, LUA_GLOBALSINDEX); - return 1; -} - diff --git a/!NotAdopted/SmartAutoReplier/lualib/ldebug.c b/!NotAdopted/SmartAutoReplier/lualib/ldebug.c deleted file mode 100644 index 8e511e3bd9..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/ldebug.c +++ /dev/null @@ -1,585 +0,0 @@ -/* -** $Id: ldebug.c,v 1.150 2003/03/19 21:24:04 roberto Exp $ -** Debug Interface -** See Copyright Notice in lua.h -*/ - - -#include -#include - -#define ldebug_c - -#include "lua.h" - -#include "lapi.h" -#include "lcode.h" -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "lobject.h" -#include "lopcodes.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "ltm.h" -#include "lvm.h" - - - -static const char *getfuncname (CallInfo *ci, const char **name); - - -#define isLua(ci) (!((ci)->state & CI_C)) - - -static int currentpc (CallInfo *ci) { - if (!isLua(ci)) return -1; /* function is not a Lua function? */ - if (ci->state & CI_HASFRAME) /* function has a frame? */ - ci->u.l.savedpc = *ci->u.l.pc; /* use `pc' from there */ - /* function's pc is saved */ - return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p); -} - - -static int currentline (CallInfo *ci) { - int pc = currentpc(ci); - if (pc < 0) - return -1; /* only active lua functions have current-line information */ - else - return getline(ci_func(ci)->l.p, pc); -} - - -void luaG_inithooks (lua_State *L) { - CallInfo *ci; - for (ci = L->ci; ci != L->base_ci; ci--) /* update all `savedpc's */ - currentpc(ci); - L->hookinit = 1; -} - - -/* -** this function can be called asynchronous (e.g. during a signal) -*/ -LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { - if (func == NULL || mask == 0) { /* turn off hooks? */ - mask = 0; - func = NULL; - } - L->hook = func; - L->basehookcount = count; - resethookcount(L); - L->hookmask = cast(lu_byte, mask); - L->hookinit = 0; - return 1; -} - - -LUA_API lua_Hook lua_gethook (lua_State *L) { - return L->hook; -} - - -LUA_API int lua_gethookmask (lua_State *L) { - return L->hookmask; -} - - -LUA_API int lua_gethookcount (lua_State *L) { - return L->basehookcount; -} - - -LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { - int status; - CallInfo *ci; - lua_lock(L); - for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { - level--; - if (!(ci->state & CI_C)) /* Lua function? */ - level -= ci->u.l.tailcalls; /* skip lost tail calls */ - } - if (level > 0 || ci == L->base_ci) status = 0; /* there is no such level */ - else if (level < 0) { /* level is of a lost tail call */ - status = 1; - ar->i_ci = 0; - } - else { - status = 1; - ar->i_ci = ci - L->base_ci; - } - lua_unlock(L); - return status; -} - - -static Proto *getluaproto (CallInfo *ci) { - return (isLua(ci) ? ci_func(ci)->l.p : NULL); -} - - -LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { - const char *name; - CallInfo *ci; - Proto *fp; - lua_lock(L); - name = NULL; - ci = L->base_ci + ar->i_ci; - fp = getluaproto(ci); - if (fp) { /* is a Lua function? */ - name = luaF_getlocalname(fp, n, currentpc(ci)); - if (name) - luaA_pushobject(L, ci->base+(n-1)); /* push value */ - } - lua_unlock(L); - return name; -} - - -LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { - const char *name; - CallInfo *ci; - Proto *fp; - lua_lock(L); - name = NULL; - ci = L->base_ci + ar->i_ci; - fp = getluaproto(ci); - L->top--; /* pop new value */ - if (fp) { /* is a Lua function? */ - name = luaF_getlocalname(fp, n, currentpc(ci)); - if (!name || name[0] == '(') /* `(' starts private locals */ - name = NULL; - else - setobjs2s(ci->base+(n-1), L->top); - } - lua_unlock(L); - return name; -} - - -static void funcinfo (lua_Debug *ar, StkId func) { - Closure *cl = clvalue(func); - if (cl->c.isC) { - ar->source = "=[C]"; - ar->linedefined = -1; - ar->what = "C"; - } - else { - ar->source = getstr(cl->l.p->source); - ar->linedefined = cl->l.p->lineDefined; - ar->what = (ar->linedefined == 0) ? "main" : "Lua"; - } - luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); -} - - -static const char *travglobals (lua_State *L, const TObject *o) { - Table *g = hvalue(gt(L)); - int i = sizenode(g); - while (i--) { - Node *n = gnode(g, i); - if (luaO_rawequalObj(o, gval(n)) && ttisstring(gkey(n))) - return getstr(tsvalue(gkey(n))); - } - return NULL; -} - - -static void info_tailcall (lua_State *L, lua_Debug *ar) { - ar->name = ar->namewhat = ""; - ar->what = "tail"; - ar->linedefined = ar->currentline = -1; - ar->source = "=(tail call)"; - luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); - ar->nups = 0; - setnilvalue(L->top); -} - - -static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, - StkId f, CallInfo *ci) { - int status = 1; - for (; *what; what++) { - switch (*what) { - case 'S': { - funcinfo(ar, f); - break; - } - case 'l': { - ar->currentline = (ci) ? currentline(ci) : -1; - break; - } - case 'u': { - ar->nups = clvalue(f)->c.nupvalues; - break; - } - case 'n': { - ar->namewhat = (ci) ? getfuncname(ci, &ar->name) : NULL; - if (ar->namewhat == NULL) { - /* try to find a global name */ - if ((ar->name = travglobals(L, f)) != NULL) - ar->namewhat = "global"; - else ar->namewhat = ""; /* not found */ - } - break; - } - case 'f': { - setobj2s(L->top, f); - break; - } - default: status = 0; /* invalid option */ - } - } - return status; -} - - -LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { - int status = 1; - lua_lock(L); - if (*what == '>') { - StkId f = L->top - 1; - if (!ttisfunction(f)) - luaG_runerror(L, "value for `lua_getinfo' is not a function"); - status = auxgetinfo(L, what + 1, ar, f, NULL); - L->top--; /* pop function */ - } - else if (ar->i_ci != 0) { /* no tail call? */ - CallInfo *ci = L->base_ci + ar->i_ci; - lua_assert(ttisfunction(ci->base - 1)); - status = auxgetinfo(L, what, ar, ci->base - 1, ci); - } - else - info_tailcall(L, ar); - if (strchr(what, 'f')) incr_top(L); - lua_unlock(L); - return status; -} - - -/* -** {====================================================== -** Symbolic Execution and code checker -** ======================================================= -*/ - -#define check(x) if (!(x)) return 0; - -#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode) - -#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) - - - -static int precheck (const Proto *pt) { - check(pt->maxstacksize <= MAXSTACK); - check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); - lua_assert(pt->numparams+pt->is_vararg <= pt->maxstacksize); - check(GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); - return 1; -} - - -static int checkopenop (const Proto *pt, int pc) { - Instruction i = pt->code[pc+1]; - switch (GET_OPCODE(i)) { - case OP_CALL: - case OP_TAILCALL: - case OP_RETURN: { - check(GETARG_B(i) == 0); - return 1; - } - case OP_SETLISTO: return 1; - default: return 0; /* invalid instruction after an open call */ - } -} - - -static int checkRK (const Proto *pt, int r) { - return (r < pt->maxstacksize || (r >= MAXSTACK && r-MAXSTACK < pt->sizek)); -} - - -static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { - int pc; - int last; /* stores position of last instruction that changed `reg' */ - last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ - check(precheck(pt)); - for (pc = 0; pc < lastpc; pc++) { - const Instruction i = pt->code[pc]; - OpCode op = GET_OPCODE(i); - int a = GETARG_A(i); - int b = 0; - int c = 0; - checkreg(pt, a); - switch (getOpMode(op)) { - case iABC: { - b = GETARG_B(i); - c = GETARG_C(i); - if (testOpMode(op, OpModeBreg)) { - checkreg(pt, b); - } - else if (testOpMode(op, OpModeBrk)) - check(checkRK(pt, b)); - if (testOpMode(op, OpModeCrk)) - check(checkRK(pt, c)); - break; - } - case iABx: { - b = GETARG_Bx(i); - if (testOpMode(op, OpModeK)) check(b < pt->sizek); - break; - } - case iAsBx: { - b = GETARG_sBx(i); - break; - } - } - if (testOpMode(op, OpModesetA)) { - if (a == reg) last = pc; /* change register `a' */ - } - if (testOpMode(op, OpModeT)) { - check(pc+2 < pt->sizecode); /* check skip */ - check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); - } - switch (op) { - case OP_LOADBOOL: { - check(c == 0 || pc+2 < pt->sizecode); /* check its jump */ - break; - } - case OP_LOADNIL: { - if (a <= reg && reg <= b) - last = pc; /* set registers from `a' to `b' */ - break; - } - case OP_GETUPVAL: - case OP_SETUPVAL: { - check(b < pt->nups); - break; - } - case OP_GETGLOBAL: - case OP_SETGLOBAL: { - check(ttisstring(&pt->k[b])); - break; - } - case OP_SELF: { - checkreg(pt, a+1); - if (reg == a+1) last = pc; - break; - } - case OP_CONCAT: { - /* `c' is a register, and at least two operands */ - check(c < MAXSTACK && b < c); - break; - } - case OP_TFORLOOP: - checkreg(pt, a+c+5); - if (reg >= a) last = pc; /* affect all registers above base */ - /* go through */ - case OP_FORLOOP: - checkreg(pt, a+2); - /* go through */ - case OP_JMP: { - int dest = pc+1+b; - check(0 <= dest && dest < pt->sizecode); - /* not full check and jump is forward and do not skip `lastpc'? */ - if (reg != NO_REG && pc < dest && dest <= lastpc) - pc += b; /* do the jump */ - break; - } - case OP_CALL: - case OP_TAILCALL: { - if (b != 0) { - checkreg(pt, a+b-1); - } - c--; /* c = num. returns */ - if (c == LUA_MULTRET) { - check(checkopenop(pt, pc)); - } - else if (c != 0) - checkreg(pt, a+c-1); - if (reg >= a) last = pc; /* affect all registers above base */ - break; - } - case OP_RETURN: { - b--; /* b = num. returns */ - if (b > 0) checkreg(pt, a+b-1); - break; - } - case OP_SETLIST: { - checkreg(pt, a + (b&(LFIELDS_PER_FLUSH-1)) + 1); - break; - } - case OP_CLOSURE: { - int nup; - check(b < pt->sizep); - nup = pt->p[b]->nups; - check(pc + nup < pt->sizecode); - for (; nup>0; nup--) { - OpCode op1 = GET_OPCODE(pt->code[pc+nup]); - check(op1 == OP_GETUPVAL || op1 == OP_MOVE); - } - break; - } - default: break; - } - } - return pt->code[last]; -} - -#undef check -#undef checkjump -#undef checkreg - -/* }====================================================== */ - - -int luaG_checkcode (const Proto *pt) { - return luaG_symbexec(pt, pt->sizecode, NO_REG); -} - - -static const char *kname (Proto *p, int c) { - c = c - MAXSTACK; - if (c >= 0 && ttisstring(&p->k[c])) - return svalue(&p->k[c]); - else - return "?"; -} - - -static const char *getobjname (CallInfo *ci, int stackpos, const char **name) { - if (isLua(ci)) { /* a Lua function? */ - Proto *p = ci_func(ci)->l.p; - int pc = currentpc(ci); - Instruction i; - *name = luaF_getlocalname(p, stackpos+1, pc); - if (*name) /* is a local? */ - return "local"; - i = luaG_symbexec(p, pc, stackpos); /* try symbolic execution */ - lua_assert(pc != -1); - switch (GET_OPCODE(i)) { - case OP_GETGLOBAL: { - int g = GETARG_Bx(i); /* global index */ - lua_assert(ttisstring(&p->k[g])); - *name = svalue(&p->k[g]); - return "global"; - } - case OP_MOVE: { - int a = GETARG_A(i); - int b = GETARG_B(i); /* move from `b' to `a' */ - if (b < a) - return getobjname(ci, b, name); /* get name for `b' */ - break; - } - case OP_GETTABLE: { - int k = GETARG_C(i); /* key index */ - *name = kname(p, k); - return "field"; - } - case OP_SELF: { - int k = GETARG_C(i); /* key index */ - *name = kname(p, k); - return "method"; - } - default: break; - } - } - return NULL; /* no useful name found */ -} - - -static const char *getfuncname (CallInfo *ci, const char **name) { - Instruction i; - if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci - 1)) - return NULL; /* calling function is not Lua (or is unknown) */ - ci--; /* calling function */ - i = ci_func(ci)->l.p->code[currentpc(ci)]; - if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL) - return getobjname(ci, GETARG_A(i), name); - else - return NULL; /* no useful name can be found */ -} - - -/* only ANSI way to check whether a pointer points to an array */ -static int isinstack (CallInfo *ci, const TObject *o) { - StkId p; - for (p = ci->base; p < ci->top; p++) - if (o == p) return 1; - return 0; -} - - -void luaG_typeerror (lua_State *L, const TObject *o, const char *op) { - const char *name = NULL; - const char *t = luaT_typenames[ttype(o)]; - const char *kind = (isinstack(L->ci, o)) ? - getobjname(L->ci, o - L->base, &name) : NULL; - if (kind) - luaG_runerror(L, "attempt to %s %s `%s' (a %s value)", - op, kind, name, t); - else - luaG_runerror(L, "attempt to %s a %s value", op, t); -} - - -void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { - if (ttisstring(p1)) p1 = p2; - lua_assert(!ttisstring(p1)); - luaG_typeerror(L, p1, "concatenate"); -} - - -void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2) { - TObject temp; - if (luaV_tonumber(p1, &temp) == NULL) - p2 = p1; /* first operand is wrong */ - luaG_typeerror(L, p2, "perform arithmetic on"); -} - - -int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) { - const char *t1 = luaT_typenames[ttype(p1)]; - const char *t2 = luaT_typenames[ttype(p2)]; - if (t1[2] == t2[2]) - luaG_runerror(L, "attempt to compare two %s values", t1); - else - luaG_runerror(L, "attempt to compare %s with %s", t1, t2); - return 0; -} - - -static void addinfo (lua_State *L, const char *msg) { - CallInfo *ci = L->ci; - if (isLua(ci)) { /* is Lua code? */ - char buff[LUA_IDSIZE]; /* add file:line information */ - int line = currentline(ci); - luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); - luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); - } -} - - -void luaG_errormsg (lua_State *L) { - if (L->errfunc != 0) { /* is there an error handling function? */ - StkId errfunc = restorestack(L, L->errfunc); - if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); - setobjs2s(L->top, L->top - 1); /* move argument */ - setobjs2s(L->top - 1, errfunc); /* push function */ - incr_top(L); - luaD_call(L, L->top - 2, 1); /* call it */ - } - luaD_throw(L, LUA_ERRRUN); -} - - -void luaG_runerror (lua_State *L, const char *fmt, ...) { - va_list argp; - va_start(argp, fmt); - addinfo(L, luaO_pushvfstring(L, fmt, argp)); - va_end(argp); - luaG_errormsg(L); -} - diff --git a/!NotAdopted/SmartAutoReplier/lualib/ldebug.h b/!NotAdopted/SmartAutoReplier/lualib/ldebug.h deleted file mode 100644 index 7ff395839c..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/ldebug.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -** $Id: ldebug.h,v 1.32 2002/11/18 11:01:55 roberto Exp $ -** Auxiliary functions from Debug Interface module -** See Copyright Notice in lua.h -*/ - -#ifndef ldebug_h -#define ldebug_h - - -#include "lstate.h" - - -#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) - -#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) - -#define resethookcount(L) (L->hookcount = L->basehookcount) - - -void luaG_inithooks (lua_State *L); -void luaG_typeerror (lua_State *L, const TObject *o, const char *opname); -void luaG_concaterror (lua_State *L, StkId p1, StkId p2); -void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2); -int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2); -void luaG_runerror (lua_State *L, const char *fmt, ...); -void luaG_errormsg (lua_State *L); -int luaG_checkcode (const Proto *pt); - - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/ldo.c b/!NotAdopted/SmartAutoReplier/lualib/ldo.c deleted file mode 100644 index ae4f22fd44..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/ldo.c +++ /dev/null @@ -1,458 +0,0 @@ -/* -** $Id: ldo.c,v 1.217 2003/04/03 13:35:34 roberto Exp $ -** Stack and Call structure of Lua -** See Copyright Notice in lua.h -*/ - - -#include -#include -#include - -#define ldo_c - -#include "lua.h" - -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "lgc.h" -#include "lmem.h" -#include "lobject.h" -#include "lopcodes.h" -#include "lparser.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "ltm.h" -#include "lundump.h" -#include "lvm.h" -#include "lzio.h" - - - - -/* -** {====================================================== -** Error-recovery functions (based on long jumps) -** ======================================================= -*/ - - -/* chain list of long jump buffers */ -struct lua_longjmp { - struct lua_longjmp *previous; - jmp_buf b; - volatile int status; /* error code */ -}; - - -static void seterrorobj (lua_State *L, int errcode, StkId oldtop) { - switch (errcode) { - case LUA_ERRMEM: { - setsvalue2s(oldtop, luaS_new(L, MEMERRMSG)); - break; - } - case LUA_ERRERR: { - setsvalue2s(oldtop, luaS_new(L, "error in error handling")); - break; - } - case LUA_ERRSYNTAX: - case LUA_ERRRUN: { - setobjs2s(oldtop, L->top - 1); /* error message on current top */ - break; - } - } - L->top = oldtop + 1; -} - - -void luaD_throw (lua_State *L, int errcode) { - if (L->errorJmp) { - L->errorJmp->status = errcode; - longjmp(L->errorJmp->b, 1); - } - else { - G(L)->panic(L); - exit(EXIT_FAILURE); - } -} - - -int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { - struct lua_longjmp lj; - lj.status = 0; - lj.previous = L->errorJmp; /* chain new error handler */ - L->errorJmp = &lj; - if (setjmp(lj.b) == 0) - (*f)(L, ud); - L->errorJmp = lj.previous; /* restore old error handler */ - return lj.status; -} - - -static void restore_stack_limit (lua_State *L) { - L->stack_last = L->stack+L->stacksize-1; - if (L->size_ci > LUA_MAXCALLS) { /* there was an overflow? */ - int inuse = (L->ci - L->base_ci); - if (inuse + 1 < LUA_MAXCALLS) /* can `undo' overflow? */ - luaD_reallocCI(L, LUA_MAXCALLS); - } -} - -/* }====================================================== */ - - -static void correctstack (lua_State *L, TObject *oldstack) { - CallInfo *ci; - GCObject *up; - L->top = (L->top - oldstack) + L->stack; - for (up = L->openupval; up != NULL; up = up->gch.next) - gcotouv(up)->v = (gcotouv(up)->v - oldstack) + L->stack; - for (ci = L->base_ci; ci <= L->ci; ci++) { - ci->top = (ci->top - oldstack) + L->stack; - ci->base = (ci->base - oldstack) + L->stack; - } - L->base = L->ci->base; -} - - -void luaD_reallocstack (lua_State *L, int newsize) { - TObject *oldstack = L->stack; - luaM_reallocvector(L, L->stack, L->stacksize, newsize, TObject); - L->stacksize = newsize; - L->stack_last = L->stack+newsize-1-EXTRA_STACK; - correctstack(L, oldstack); -} - - -void luaD_reallocCI (lua_State *L, int newsize) { - CallInfo *oldci = L->base_ci; - luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); - L->size_ci = cast(unsigned short, newsize); - L->ci = (L->ci - oldci) + L->base_ci; - L->end_ci = L->base_ci + L->size_ci; -} - - -void luaD_growstack (lua_State *L, int n) { - if (n <= L->stacksize) /* double size is enough? */ - luaD_reallocstack(L, 2*L->stacksize); - else - luaD_reallocstack(L, L->stacksize + n + EXTRA_STACK); -} - - -static void luaD_growCI (lua_State *L) { - if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */ - luaD_throw(L, LUA_ERRERR); - else { - luaD_reallocCI(L, 2*L->size_ci); - if (L->size_ci > LUA_MAXCALLS) - luaG_runerror(L, "stack overflow"); - } -} - - -void luaD_callhook (lua_State *L, int event, int line) { - lua_Hook hook = L->hook; - if (hook && L->allowhook) { - ptrdiff_t top = savestack(L, L->top); - ptrdiff_t ci_top = savestack(L, L->ci->top); - lua_Debug ar; - ar.event = event; - ar.currentline = line; - if (event == LUA_HOOKTAILRET) - ar.i_ci = 0; /* tail call; no debug information about it */ - else - ar.i_ci = L->ci - L->base_ci; - luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ - L->ci->top = L->top + LUA_MINSTACK; - L->allowhook = 0; /* cannot call hooks inside a hook */ - lua_unlock(L); - (*hook)(L, &ar); - lua_lock(L); - lua_assert(!L->allowhook); - L->allowhook = 1; - L->ci->top = restorestack(L, ci_top); - L->top = restorestack(L, top); - } -} - - -static void adjust_varargs (lua_State *L, int nfixargs, StkId base) { - int i; - Table *htab; - TObject nname; - int actual = L->top - base; /* actual number of arguments */ - if (actual < nfixargs) { - luaD_checkstack(L, nfixargs - actual); - for (; actual < nfixargs; ++actual) - setnilvalue(L->top++); - } - actual -= nfixargs; /* number of extra arguments */ - htab = luaH_new(L, actual, 1); /* create `arg' table */ - for (i=0; itop - actual + i); - /* store counter in field `n' */ - setsvalue(&nname, luaS_newliteral(L, "n")); - setnvalue(luaH_set(L, htab, &nname), cast(lua_Number, actual)); - L->top -= actual; /* remove extra elements from the stack */ - sethvalue(L->top, htab); - incr_top(L); -} - - -static StkId tryfuncTM (lua_State *L, StkId func) { - const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); - StkId p; - ptrdiff_t funcr = savestack(L, func); - if (!ttisfunction(tm)) - luaG_typeerror(L, func, "call"); - /* Open a hole inside the stack at `func' */ - for (p = L->top; p > func; p--) setobjs2s(p, p-1); - incr_top(L); - func = restorestack(L, funcr); /* previous call may change stack */ - setobj2s(func, tm); /* tag method is the new function to be called */ - return func; -} - - -StkId luaD_precall (lua_State *L, StkId func) { - LClosure *cl; - ptrdiff_t funcr = savestack(L, func); - if (!ttisfunction(func)) /* `func' is not a function? */ - func = tryfuncTM(L, func); /* check the `function' tag method */ - if (L->ci + 1 == L->end_ci) luaD_growCI(L); - else condhardstacktests(luaD_reallocCI(L, L->size_ci)); - cl = &clvalue(func)->l; - if (!cl->isC) { /* Lua function? prepare its call */ - CallInfo *ci; - Proto *p = cl->p; - if (p->is_vararg) /* varargs? */ - adjust_varargs(L, p->numparams, func+1); - luaD_checkstack(L, p->maxstacksize); - ci = ++L->ci; /* now `enter' new function */ - L->base = L->ci->base = restorestack(L, funcr) + 1; - ci->top = L->base + p->maxstacksize; - ci->u.l.savedpc = p->code; /* starting point */ - ci->u.l.tailcalls = 0; - ci->state = CI_SAVEDPC; - while (L->top < ci->top) - setnilvalue(L->top++); - L->top = ci->top; - return NULL; - } - else { /* if is a C function, call it */ - CallInfo *ci; - int n; - luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ - ci = ++L->ci; /* now `enter' new function */ - L->base = L->ci->base = restorestack(L, funcr) + 1; - ci->top = L->top + LUA_MINSTACK; - ci->state = CI_C; /* a C function */ - if (L->hookmask & LUA_MASKCALL) - luaD_callhook(L, LUA_HOOKCALL, -1); - lua_unlock(L); -#ifdef LUA_COMPATUPVALUES - lua_pushupvalues(L); -#endif - n = (*clvalue(L->base - 1)->c.f)(L); /* do the actual call */ - lua_lock(L); - return L->top - n; - } -} - - -static StkId callrethooks (lua_State *L, StkId firstResult) { - ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ - luaD_callhook(L, LUA_HOOKRET, -1); - if (!(L->ci->state & CI_C)) { /* Lua function? */ - while (L->ci->u.l.tailcalls--) /* call hook for eventual tail calls */ - luaD_callhook(L, LUA_HOOKTAILRET, -1); - } - return restorestack(L, fr); -} - - -void luaD_poscall (lua_State *L, int wanted, StkId firstResult) { - StkId res; - if (L->hookmask & LUA_MASKRET) - firstResult = callrethooks(L, firstResult); - res = L->base - 1; /* res == final position of 1st result */ - L->ci--; - L->base = L->ci->base; /* restore base */ - /* move results to correct place */ - while (wanted != 0 && firstResult < L->top) { - setobjs2s(res++, firstResult++); - wanted--; - } - while (wanted-- > 0) - setnilvalue(res++); - L->top = res; -} - - -/* -** Call a function (C or Lua). The function to be called is at *func. -** The arguments are on the stack, right after the function. -** When returns, all the results are on the stack, starting at the original -** function position. -*/ -void luaD_call (lua_State *L, StkId func, int nResults) { - StkId firstResult; - lua_assert(!(L->ci->state & CI_CALLING)); - if (++L->nCcalls >= LUA_MAXCCALLS) { - if (L->nCcalls == LUA_MAXCCALLS) - luaG_runerror(L, "C stack overflow"); - else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3))) - luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ - } - firstResult = luaD_precall(L, func); - if (firstResult == NULL) /* is a Lua function? */ - firstResult = luaV_execute(L); /* call it */ - luaD_poscall(L, nResults, firstResult); - L->nCcalls--; - luaC_checkGC(L); -} - - -static void resume (lua_State *L, void *ud) { - StkId firstResult; - int nargs = *cast(int *, ud); - CallInfo *ci = L->ci; - if (ci == L->base_ci) { /* no activation record? */ - if (nargs >= L->top - L->base) - luaG_runerror(L, "cannot resume dead coroutine"); - luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */ - } - else if (ci->state & CI_YIELD) { /* inside a yield? */ - if (ci->state & CI_C) { /* `common' yield? */ - /* finish interrupted execution of `OP_CALL' */ - int nresults; - lua_assert((ci-1)->state & CI_SAVEDPC); - lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL || - GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL); - nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1; - luaD_poscall(L, nresults, L->top - nargs); /* complete it */ - if (nresults >= 0) L->top = L->ci->top; - } - else { /* yielded inside a hook: just continue its execution */ - ci->state &= ~CI_YIELD; - } - } - else - luaG_runerror(L, "cannot resume non-suspended coroutine"); - firstResult = luaV_execute(L); - if (firstResult != NULL) /* return? */ - luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */ -} - - -LUA_API int lua_resume (lua_State *L, int nargs) { - int status; - lu_byte old_allowhooks; - lua_lock(L); - old_allowhooks = L->allowhook; - lua_assert(L->errfunc == 0 && L->nCcalls == 0); - status = luaD_rawrunprotected(L, resume, &nargs); - if (status != 0) { /* error? */ - L->ci = L->base_ci; /* go back to initial level */ - L->base = L->ci->base; - L->nCcalls = 0; - luaF_close(L, L->base); /* close eventual pending closures */ - seterrorobj(L, status, L->base); - L->allowhook = old_allowhooks; - restore_stack_limit(L); - } - lua_unlock(L); - return status; -} - - -LUA_API int lua_yield (lua_State *L, int nresults) { - CallInfo *ci; - lua_lock(L); - ci = L->ci; - if (L->nCcalls > 0) - luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); - if (ci->state & CI_C) { /* usual yield */ - if ((ci-1)->state & CI_C) - luaG_runerror(L, "cannot yield a C function"); - if (L->top - nresults > L->base) { /* is there garbage in the stack? */ - int i; - for (i=0; ibase + i, L->top - nresults + i); - L->top = L->base + nresults; - } - } /* else it's an yield inside a hook: nothing to do */ - ci->state |= CI_YIELD; - lua_unlock(L); - return -1; -} - - -int luaD_pcall (lua_State *L, Pfunc func, void *u, - ptrdiff_t old_top, ptrdiff_t ef) { - int status; - unsigned short oldnCcalls = L->nCcalls; - ptrdiff_t old_ci = saveci(L, L->ci); - lu_byte old_allowhooks = L->allowhook; - ptrdiff_t old_errfunc = L->errfunc; - L->errfunc = ef; - status = luaD_rawrunprotected(L, func, u); - if (status != 0) { /* an error occurred? */ - StkId oldtop = restorestack(L, old_top); - luaF_close(L, oldtop); /* close eventual pending closures */ - seterrorobj(L, status, oldtop); - L->nCcalls = oldnCcalls; - L->ci = restoreci(L, old_ci); - L->base = L->ci->base; - L->allowhook = old_allowhooks; - restore_stack_limit(L); - } - L->errfunc = old_errfunc; - return status; -} - - - -/* -** Execute a protected parser. -*/ -struct SParser { /* data to `f_parser' */ - ZIO *z; - Mbuffer buff; /* buffer to be used by the scanner */ - int bin; -}; - -static void f_parser (lua_State *L, void *ud) { - struct SParser *p; - Proto *tf; - Closure *cl; - luaC_checkGC(L); - p = cast(struct SParser *, ud); - tf = p->bin ? luaU_undump(L, p->z, &p->buff) : luaY_parser(L, p->z, &p->buff); - cl = luaF_newLclosure(L, 0, gt(L)); - cl->l.p = tf; - setclvalue(L->top, cl); - incr_top(L); -} - - -int luaD_protectedparser (lua_State *L, ZIO *z, int bin) { - struct SParser p; - int status; - ptrdiff_t oldtopr = savestack(L, L->top); /* save current top */ - p.z = z; p.bin = bin; - luaZ_initbuffer(L, &p.buff); - status = luaD_rawrunprotected(L, f_parser, &p); - luaZ_freebuffer(L, &p.buff); - if (status != 0) { /* error? */ - StkId oldtop = restorestack(L, oldtopr); - seterrorobj(L, status, oldtop); - } - return status; -} - - diff --git a/!NotAdopted/SmartAutoReplier/lualib/ldo.h b/!NotAdopted/SmartAutoReplier/lualib/ldo.h deleted file mode 100644 index 2a61bf5bb2..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/ldo.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -** $Id: ldo.h,v 1.56 2002/12/04 17:29:32 roberto Exp $ -** Stack and Call structure of Lua -** See Copyright Notice in lua.h -*/ - -#ifndef ldo_h -#define ldo_h - - -#include "lobject.h" -#include "lstate.h" -#include "lzio.h" - - -/* -** macro to control inclusion of some hard tests on stack reallocation -*/ -#ifndef HARDSTACKTESTS -#define condhardstacktests(x) { /* empty */ } -#else -#define condhardstacktests(x) x -#endif - - -#define luaD_checkstack(L,n) \ - if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TObject)) \ - luaD_growstack(L, n); \ - else condhardstacktests(luaD_reallocstack(L, L->stacksize)); - - -#define incr_top(L) {luaD_checkstack(L,1); L->top++;} - -#define savestack(L,p) ((char *)(p) - (char *)L->stack) -#define restorestack(L,n) ((TObject *)((char *)L->stack + (n))) - -#define saveci(L,p) ((char *)(p) - (char *)L->base_ci) -#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n))) - - -/* type of protected functions, to be ran by `runprotected' */ -typedef void (*Pfunc) (lua_State *L, void *ud); - -void luaD_resetprotection (lua_State *L); -int luaD_protectedparser (lua_State *L, ZIO *z, int bin); -void luaD_callhook (lua_State *L, int event, int line); -StkId luaD_precall (lua_State *L, StkId func); -void luaD_call (lua_State *L, StkId func, int nResults); -int luaD_pcall (lua_State *L, Pfunc func, void *u, - ptrdiff_t oldtop, ptrdiff_t ef); -void luaD_poscall (lua_State *L, int wanted, StkId firstResult); -void luaD_reallocCI (lua_State *L, int newsize); -void luaD_reallocstack (lua_State *L, int newsize); -void luaD_growstack (lua_State *L, int n); - -void luaD_throw (lua_State *L, int errcode); -int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); - - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/ldump.c b/!NotAdopted/SmartAutoReplier/lualib/ldump.c deleted file mode 100644 index 234b011f5f..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/ldump.c +++ /dev/null @@ -1,170 +0,0 @@ -/* -** $Id: ldump.c,v 1.4 2003/02/11 23:52:12 lhf Exp $ -** save bytecodes -** See Copyright Notice in lua.h -*/ - -#include - -#define ldump_c - -#include "lua.h" - -#include "lobject.h" -#include "lopcodes.h" -#include "lstate.h" -#include "lundump.h" - -#define DumpVector(b,n,size,D) DumpBlock(b,(n)*(size),D) -#define DumpLiteral(s,D) DumpBlock("" s,(sizeof(s))-1,D) - -typedef struct { - lua_State* L; - lua_Chunkwriter write; - void* data; -} DumpState; - -static void DumpBlock(const void* b, size_t size, DumpState* D) -{ - lua_unlock(D->L); - (*D->write)(D->L,b,size,D->data); - lua_lock(D->L); -} - -static void DumpByte(int y, DumpState* D) -{ - char x=(char)y; - DumpBlock(&x,sizeof(x),D); -} - -static void DumpInt(int x, DumpState* D) -{ - DumpBlock(&x,sizeof(x),D); -} - -static void DumpSize(size_t x, DumpState* D) -{ - DumpBlock(&x,sizeof(x),D); -} - -static void DumpNumber(lua_Number x, DumpState* D) -{ - DumpBlock(&x,sizeof(x),D); -} - -static void DumpString(TString* s, DumpState* D) -{ - if (s==NULL || getstr(s)==NULL) - DumpSize(0,D); - else - { - size_t size=s->tsv.len+1; /* include trailing '\0' */ - DumpSize(size,D); - DumpBlock(getstr(s),size,D); - } -} - -static void DumpCode(const Proto* f, DumpState* D) -{ - DumpInt(f->sizecode,D); - DumpVector(f->code,f->sizecode,sizeof(*f->code),D); -} - -static void DumpLocals(const Proto* f, DumpState* D) -{ - int i,n=f->sizelocvars; - DumpInt(n,D); - for (i=0; ilocvars[i].varname,D); - DumpInt(f->locvars[i].startpc,D); - DumpInt(f->locvars[i].endpc,D); - } -} - -static void DumpLines(const Proto* f, DumpState* D) -{ - DumpInt(f->sizelineinfo,D); - DumpVector(f->lineinfo,f->sizelineinfo,sizeof(*f->lineinfo),D); -} - -static void DumpUpvalues(const Proto* f, DumpState* D) -{ - int i,n=f->sizeupvalues; - DumpInt(n,D); - for (i=0; iupvalues[i],D); -} - -static void DumpFunction(const Proto* f, const TString* p, DumpState* D); - -static void DumpConstants(const Proto* f, DumpState* D) -{ - int i,n; - DumpInt(n=f->sizek,D); - for (i=0; ik[i]; - DumpByte(ttype(o),D); - switch (ttype(o)) - { - case LUA_TNUMBER: - DumpNumber(nvalue(o),D); - break; - case LUA_TSTRING: - DumpString(tsvalue(o),D); - break; - case LUA_TNIL: - break; - default: - lua_assert(0); /* cannot happen */ - break; - } - } - DumpInt(n=f->sizep,D); - for (i=0; ip[i],f->source,D); -} - -static void DumpFunction(const Proto* f, const TString* p, DumpState* D) -{ - DumpString((f->source==p) ? NULL : f->source,D); - DumpInt(f->lineDefined,D); - DumpByte(f->nups,D); - DumpByte(f->numparams,D); - DumpByte(f->is_vararg,D); - DumpByte(f->maxstacksize,D); - DumpLines(f,D); - DumpLocals(f,D); - DumpUpvalues(f,D); - DumpConstants(f,D); - DumpCode(f,D); -} - -static void DumpHeader(DumpState* D) -{ - DumpLiteral(LUA_SIGNATURE,D); - DumpByte(VERSION,D); - DumpByte(luaU_endianness(),D); - DumpByte(sizeof(int),D); - DumpByte(sizeof(size_t),D); - DumpByte(sizeof(Instruction),D); - DumpByte(SIZE_OP,D); - DumpByte(SIZE_A,D); - DumpByte(SIZE_B,D); - DumpByte(SIZE_C,D); - DumpByte(sizeof(lua_Number),D); - DumpNumber(TEST_NUMBER,D); -} - -/* -** dump function as precompiled chunk -*/ -void luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data) -{ - DumpState D; - D.L=L; - D.write=w; - D.data=data; - DumpHeader(&D); - DumpFunction(Main,NULL,&D); -} - diff --git a/!NotAdopted/SmartAutoReplier/lualib/lfunc.c b/!NotAdopted/SmartAutoReplier/lualib/lfunc.c deleted file mode 100644 index 31044fa56b..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lfunc.c +++ /dev/null @@ -1,135 +0,0 @@ -/* -** $Id: lfunc.c,v 1.67 2003/03/18 12:50:04 roberto Exp $ -** Auxiliary functions to manipulate prototypes and closures -** See Copyright Notice in lua.h -*/ - - -#include - -#define lfunc_c - -#include "lua.h" - -#include "lfunc.h" -#include "lgc.h" -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" - - -#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ - cast(int, sizeof(TObject)*((n)-1))) - -#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ - cast(int, sizeof(TObject *)*((n)-1))) - - - -Closure *luaF_newCclosure (lua_State *L, int nelems) { - Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); - luaC_link(L, valtogco(c), LUA_TFUNCTION); - c->c.isC = 1; - c->c.nupvalues = cast(lu_byte, nelems); - return c; -} - - -Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *e) { - Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); - luaC_link(L, valtogco(c), LUA_TFUNCTION); - c->l.isC = 0; - c->l.g = *e; - c->l.nupvalues = cast(lu_byte, nelems); - return c; -} - - -UpVal *luaF_findupval (lua_State *L, StkId level) { - GCObject **pp = &L->openupval; - UpVal *p; - UpVal *v; - while ((p = ngcotouv(*pp)) != NULL && p->v >= level) { - if (p->v == level) return p; - pp = &p->next; - } - v = luaM_new(L, UpVal); /* not found: create a new one */ - v->tt = LUA_TUPVAL; - v->marked = 1; /* open upvalues should not be collected */ - v->v = level; /* current value lives in the stack */ - v->next = *pp; /* chain it in the proper position */ - *pp = valtogco(v); - return v; -} - - -void luaF_close (lua_State *L, StkId level) { - UpVal *p; - while ((p = ngcotouv(L->openupval)) != NULL && p->v >= level) { - setobj(&p->value, p->v); /* save current value (write barrier) */ - p->v = &p->value; /* now current value lives here */ - L->openupval = p->next; /* remove from `open' list */ - luaC_link(L, valtogco(p), LUA_TUPVAL); - } -} - - -Proto *luaF_newproto (lua_State *L) { - Proto *f = luaM_new(L, Proto); - luaC_link(L, valtogco(f), LUA_TPROTO); - f->k = NULL; - f->sizek = 0; - f->p = NULL; - f->sizep = 0; - f->code = NULL; - f->sizecode = 0; - f->sizelineinfo = 0; - f->sizeupvalues = 0; - f->nups = 0; - f->upvalues = NULL; - f->numparams = 0; - f->is_vararg = 0; - f->maxstacksize = 0; - f->lineinfo = NULL; - f->sizelocvars = 0; - f->locvars = NULL; - f->lineDefined = 0; - f->source = NULL; - return f; -} - - -void luaF_freeproto (lua_State *L, Proto *f) { - luaM_freearray(L, f->code, f->sizecode, Instruction); - luaM_freearray(L, f->p, f->sizep, Proto *); - luaM_freearray(L, f->k, f->sizek, TObject); - luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); - luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); - luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); - luaM_freelem(L, f); -} - - -void luaF_freeclosure (lua_State *L, Closure *c) { - int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : - sizeLclosure(c->l.nupvalues); - luaM_free(L, c, size); -} - - -/* -** Look for n-th local variable at line `line' in function `func'. -** Returns NULL if not found. -*/ -const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { - int i; - for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { - if (pc < f->locvars[i].endpc) { /* is variable active? */ - local_number--; - if (local_number == 0) - return getstr(f->locvars[i].varname); - } - } - return NULL; /* not found */ -} - diff --git a/!NotAdopted/SmartAutoReplier/lualib/lfunc.h b/!NotAdopted/SmartAutoReplier/lualib/lfunc.h deleted file mode 100644 index 5d5325076b..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lfunc.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -** $Id: lfunc.h,v 1.21 2003/03/18 12:50:04 roberto Exp $ -** Auxiliary functions to manipulate prototypes and closures -** See Copyright Notice in lua.h -*/ - -#ifndef lfunc_h -#define lfunc_h - - -#include "lobject.h" - - -Proto *luaF_newproto (lua_State *L); -Closure *luaF_newCclosure (lua_State *L, int nelems); -Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *e); -UpVal *luaF_findupval (lua_State *L, StkId level); -void luaF_close (lua_State *L, StkId level); -void luaF_freeproto (lua_State *L, Proto *f); -void luaF_freeclosure (lua_State *L, Closure *c); - -const char *luaF_getlocalname (const Proto *func, int local_number, int pc); - - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/lgc.c b/!NotAdopted/SmartAutoReplier/lualib/lgc.c deleted file mode 100644 index 4cc45e39d0..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lgc.c +++ /dev/null @@ -1,493 +0,0 @@ -/* -** $Id: lgc.c,v 1.171 2003/04/03 13:35:34 roberto Exp $ -** Garbage Collector -** See Copyright Notice in lua.h -*/ - -#include - -#define lgc_c - -#include "lua.h" - -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "lgc.h" -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "ltm.h" - - -typedef struct GCState { - GCObject *tmark; /* list of marked objects to be traversed */ - GCObject *wk; /* list of traversed key-weak tables (to be cleared) */ - GCObject *wv; /* list of traversed value-weak tables */ - GCObject *wkv; /* list of traversed key-value weak tables */ - global_State *g; -} GCState; - - -/* -** some userful bit tricks -*/ -#define setbit(x,b) ((x) |= (1<<(b))) -#define resetbit(x,b) ((x) &= cast(lu_byte, ~(1<<(b)))) -#define testbit(x,b) ((x) & (1<<(b))) - -#define unmark(x) resetbit((x)->gch.marked, 0) -#define ismarked(x) ((x)->gch.marked & ((1<<4)|1)) - -#define stringmark(s) setbit((s)->tsv.marked, 0) - - -#define isfinalized(u) (!testbit((u)->uv.marked, 1)) -#define markfinalized(u) resetbit((u)->uv.marked, 1) - - -#define KEYWEAKBIT 1 -#define VALUEWEAKBIT 2 -#define KEYWEAK (1<gch.marked, 0); /* mark object */ - switch (o->gch.tt) { - case LUA_TUSERDATA: { - markvalue(st, gcotou(o)->uv.metatable); - break; - } - case LUA_TFUNCTION: { - gcotocl(o)->c.gclist = st->tmark; - st->tmark = o; - break; - } - case LUA_TTABLE: { - gcotoh(o)->gclist = st->tmark; - st->tmark = o; - break; - } - case LUA_TTHREAD: { - gcototh(o)->gclist = st->tmark; - st->tmark = o; - break; - } - case LUA_TPROTO: { - gcotop(o)->gclist = st->tmark; - st->tmark = o; - break; - } - default: lua_assert(o->gch.tt == LUA_TSTRING); - } -} - - -static void marktmu (GCState *st) { - GCObject *u; - for (u = st->g->tmudata; u; u = u->gch.next) { - unmark(u); /* may be marked, if left from previous GC */ - reallymarkobject(st, u); - } -} - - -/* move `dead' udata that need finalization to list `tmudata' */ -void luaC_separateudata (lua_State *L) { - GCObject **p = &G(L)->rootudata; - GCObject *curr; - GCObject *collected = NULL; /* to collect udata with gc event */ - GCObject **lastcollected = &collected; - while ((curr = *p) != NULL) { - lua_assert(curr->gch.tt == LUA_TUSERDATA); - if (ismarked(curr) || isfinalized(gcotou(curr))) - p = &curr->gch.next; /* don't bother with them */ - - else if (fasttm(L, gcotou(curr)->uv.metatable, TM_GC) == NULL) { - markfinalized(gcotou(curr)); /* don't need finalization */ - p = &curr->gch.next; - } - else { /* must call its gc method */ - *p = curr->gch.next; - curr->gch.next = NULL; /* link `curr' at the end of `collected' list */ - *lastcollected = curr; - lastcollected = &curr->gch.next; - } - } - /* insert collected udata with gc event into `tmudata' list */ - *lastcollected = G(L)->tmudata; - G(L)->tmudata = collected; -} - - -static void removekey (Node *n) { - setnilvalue(gval(n)); /* remove corresponding value ... */ - if (iscollectable(gkey(n))) - setttype(gkey(n), LUA_TNONE); /* dead key; remove it */ -} - - -static void traversetable (GCState *st, Table *h) { - int i; - int weakkey = 0; - int weakvalue = 0; - const TObject *mode; - markvalue(st, h->metatable); - lua_assert(h->lsizenode || h->node == st->g->dummynode); - mode = gfasttm(st->g, h->metatable, TM_MODE); - if (mode && ttisstring(mode)) { /* is there a weak mode? */ - weakkey = (strchr(svalue(mode), 'k') != NULL); - weakvalue = (strchr(svalue(mode), 'v') != NULL); - if (weakkey || weakvalue) { /* is really weak? */ - GCObject **weaklist; - h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */ - h->marked |= cast(lu_byte, (weakkey << KEYWEAKBIT) | - (weakvalue << VALUEWEAKBIT)); - weaklist = (weakkey && weakvalue) ? &st->wkv : - (weakkey) ? &st->wk : - &st->wv; - h->gclist = *weaklist; /* must be cleared after GC, ... */ - *weaklist = valtogco(h); /* ... so put in the appropriate list */ - } - } - if (!weakvalue) { - i = h->sizearray; - while (i--) - markobject(st, &h->array[i]); - } - i = sizenode(h); - while (i--) { - Node *n = gnode(h, i); - if (!ttisnil(gval(n))) { - lua_assert(!ttisnil(gkey(n))); - condmarkobject(st, gkey(n), !weakkey); - condmarkobject(st, gval(n), !weakvalue); - } - } -} - - -static void traverseproto (GCState *st, Proto *f) { - int i; - stringmark(f->source); - for (i=0; isizek; i++) { /* mark literal strings */ - if (ttisstring(f->k+i)) - stringmark(tsvalue(f->k+i)); - } - for (i=0; isizeupvalues; i++) /* mark upvalue names */ - stringmark(f->upvalues[i]); - for (i=0; isizep; i++) /* mark nested protos */ - markvalue(st, f->p[i]); - for (i=0; isizelocvars; i++) /* mark local-variable names */ - stringmark(f->locvars[i].varname); - lua_assert(luaG_checkcode(f)); -} - - - -static void traverseclosure (GCState *st, Closure *cl) { - if (cl->c.isC) { - int i; - for (i=0; ic.nupvalues; i++) /* mark its upvalues */ - markobject(st, &cl->c.upvalue[i]); - } - else { - int i; - lua_assert(cl->l.nupvalues == cl->l.p->nups); - markvalue(st, hvalue(&cl->l.g)); - markvalue(st, cl->l.p); - for (i=0; il.nupvalues; i++) { /* mark its upvalues */ - UpVal *u = cl->l.upvals[i]; - if (!u->marked) { - markobject(st, &u->value); - u->marked = 1; - } - } - } -} - - -static void checkstacksizes (lua_State *L, StkId max) { - int used = L->ci - L->base_ci; /* number of `ci' in use */ - if (4*used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci) - luaD_reallocCI(L, L->size_ci/2); /* still big enough... */ - else condhardstacktests(luaD_reallocCI(L, L->size_ci)); - used = max - L->stack; /* part of stack in use */ - if (4*used < L->stacksize && 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize) - luaD_reallocstack(L, L->stacksize/2); /* still big enough... */ - else condhardstacktests(luaD_reallocstack(L, L->stacksize)); -} - - -static void traversestack (GCState *st, lua_State *L1) { - StkId o, lim; - CallInfo *ci; - markobject(st, gt(L1)); - lim = L1->top; - for (ci = L1->base_ci; ci <= L1->ci; ci++) { - lua_assert(ci->top <= L1->stack_last); - lua_assert(ci->state & (CI_C | CI_HASFRAME | CI_SAVEDPC)); - if (!(ci->state & CI_C) && lim < ci->top) - lim = ci->top; - } - for (o = L1->stack; o < L1->top; o++) - markobject(st, o); - for (; o <= lim; o++) - setnilvalue(o); - checkstacksizes(L1, lim); -} - - -static void propagatemarks (GCState *st) { - while (st->tmark) { /* traverse marked objects */ - switch (st->tmark->gch.tt) { - case LUA_TTABLE: { - Table *h = gcotoh(st->tmark); - st->tmark = h->gclist; - traversetable(st, h); - break; - } - case LUA_TFUNCTION: { - Closure *cl = gcotocl(st->tmark); - st->tmark = cl->c.gclist; - traverseclosure(st, cl); - break; - } - case LUA_TTHREAD: { - lua_State *th = gcototh(st->tmark); - st->tmark = th->gclist; - traversestack(st, th); - break; - } - case LUA_TPROTO: { - Proto *p = gcotop(st->tmark); - st->tmark = p->gclist; - traverseproto(st, p); - break; - } - default: lua_assert(0); - } - } -} - - -static int valismarked (const TObject *o) { - if (ttisstring(o)) - stringmark(tsvalue(o)); /* strings are `values', so are never weak */ - return !iscollectable(o) || testbit(o->value.gc->gch.marked, 0); -} - - -/* -** clear collected keys from weaktables -*/ -static void cleartablekeys (GCObject *l) { - while (l) { - Table *h = gcotoh(l); - int i = sizenode(h); - lua_assert(h->marked & KEYWEAK); - while (i--) { - Node *n = gnode(h, i); - if (!valismarked(gkey(n))) /* key was collected? */ - removekey(n); /* remove entry from table */ - } - l = h->gclist; - } -} - - -/* -** clear collected values from weaktables -*/ -static void cleartablevalues (GCObject *l) { - while (l) { - Table *h = gcotoh(l); - int i = h->sizearray; - lua_assert(h->marked & VALUEWEAK); - while (i--) { - TObject *o = &h->array[i]; - if (!valismarked(o)) /* value was collected? */ - setnilvalue(o); /* remove value */ - } - i = sizenode(h); - while (i--) { - Node *n = gnode(h, i); - if (!valismarked(gval(n))) /* value was collected? */ - removekey(n); /* remove entry from table */ - } - l = h->gclist; - } -} - - -static void freeobj (lua_State *L, GCObject *o) { - switch (o->gch.tt) { - case LUA_TPROTO: luaF_freeproto(L, gcotop(o)); break; - case LUA_TFUNCTION: luaF_freeclosure(L, gcotocl(o)); break; - case LUA_TUPVAL: luaM_freelem(L, gcotouv(o)); break; - case LUA_TTABLE: luaH_free(L, gcotoh(o)); break; - case LUA_TTHREAD: { - lua_assert(gcototh(o) != L && gcototh(o) != G(L)->mainthread); - luaE_freethread(L, gcototh(o)); - break; - } - case LUA_TSTRING: { - luaM_free(L, o, sizestring(gcotots(o)->tsv.len)); - break; - } - case LUA_TUSERDATA: { - luaM_free(L, o, sizeudata(gcotou(o)->uv.len)); - break; - } - default: lua_assert(0); - } -} - - -static int sweeplist (lua_State *L, GCObject **p, int limit) { - GCObject *curr; - int count = 0; /* number of collected items */ - while ((curr = *p) != NULL) { - if (curr->gch.marked > limit) { - unmark(curr); - p = &curr->gch.next; - } - else { - count++; - *p = curr->gch.next; - freeobj(L, curr); - } - } - return count; -} - - -static void sweepstrings (lua_State *L, int all) { - int i; - for (i=0; istrt.size; i++) { /* for each list */ - G(L)->strt.nuse -= sweeplist(L, &G(L)->strt.hash[i], all); - } -} - - -static void checkSizes (lua_State *L) { - /* check size of string hash */ - if (G(L)->strt.nuse < cast(ls_nstr, G(L)->strt.size/4) && - G(L)->strt.size > MINSTRTABSIZE*2) - luaS_resize(L, G(L)->strt.size/2); /* table is too big */ - /* check size of buffer */ - if (luaZ_sizebuffer(&G(L)->buff) > LUA_MINBUFFER*2) { /* buffer too big? */ - size_t newsize = luaZ_sizebuffer(&G(L)->buff) / 2; - luaZ_resizebuffer(L, &G(L)->buff, newsize); - } - G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */ -} - - -static void do1gcTM (lua_State *L, Udata *udata) { - const TObject *tm = fasttm(L, udata->uv.metatable, TM_GC); - if (tm != NULL) { - setobj2s(L->top, tm); - setuvalue(L->top+1, udata); - L->top += 2; - luaD_call(L, L->top - 2, 0); - } -} - - -void luaC_callGCTM (lua_State *L) { - lu_byte oldah = L->allowhook; - L->allowhook = 0; /* stop debug hooks during GC tag methods */ - L->top++; /* reserve space to keep udata while runs its gc method */ - while (G(L)->tmudata != NULL) { - GCObject *o = G(L)->tmudata; - Udata *udata = gcotou(o); - G(L)->tmudata = udata->uv.next; /* remove udata from `tmudata' */ - udata->uv.next = G(L)->rootudata; /* return it to `root' list */ - G(L)->rootudata = o; - setuvalue(L->top - 1, udata); /* keep a reference to it */ - unmark(o); - markfinalized(udata); - do1gcTM(L, udata); - } - L->top--; - L->allowhook = oldah; /* restore hooks */ -} - - -void luaC_sweep (lua_State *L, int all) { - if (all) all = 256; /* larger than any mark */ - sweeplist(L, &G(L)->rootudata, all); - sweepstrings(L, all); - sweeplist(L, &G(L)->rootgc, all); -} - - -/* mark root set */ -static void markroot (GCState *st, lua_State *L) { - global_State *g = st->g; - markobject(st, defaultmeta(L)); - markobject(st, registry(L)); - traversestack(st, g->mainthread); - if (L != g->mainthread) /* another thread is running? */ - markvalue(st, L); /* cannot collect it */ -} - - -static void mark (lua_State *L) { - GCState st; - GCObject *wkv; - st.g = G(L); - st.tmark = NULL; - st.wkv = st.wk = st.wv = NULL; - markroot(&st, L); - propagatemarks(&st); /* mark all reachable objects */ - cleartablevalues(st.wkv); - cleartablevalues(st.wv); - wkv = st.wkv; /* keys must be cleared after preserving udata */ - st.wkv = NULL; - st.wv = NULL; - luaC_separateudata(L); /* separate userdata to be preserved */ - marktmu(&st); /* mark `preserved' userdata */ - propagatemarks(&st); /* remark, to propagate `preserveness' */ - cleartablekeys(wkv); - /* `propagatemarks' may resuscitate some weak tables; clear them too */ - cleartablekeys(st.wk); - cleartablevalues(st.wv); - cleartablekeys(st.wkv); - cleartablevalues(st.wkv); -} - - -void luaC_collectgarbage (lua_State *L) { - mark(L); - luaC_sweep(L, 0); - checkSizes(L); - luaC_callGCTM(L); -} - - -void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { - o->gch.next = G(L)->rootgc; - G(L)->rootgc = o; - o->gch.marked = 0; - o->gch.tt = tt; -} - diff --git a/!NotAdopted/SmartAutoReplier/lualib/lgc.h b/!NotAdopted/SmartAutoReplier/lualib/lgc.h deleted file mode 100644 index 6ab6c91749..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lgc.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -** $Id: lgc.h,v 1.19 2003/02/28 19:45:15 roberto Exp $ -** Garbage Collector -** See Copyright Notice in lua.h -*/ - -#ifndef lgc_h -#define lgc_h - - -#include "lobject.h" - - -#define luaC_checkGC(L) { lua_assert(!(L->ci->state & CI_CALLING)); \ - if (G(L)->nblocks >= G(L)->GCthreshold) luaC_collectgarbage(L); } - - -void luaC_separateudata (lua_State *L); -void luaC_callGCTM (lua_State *L); -void luaC_sweep (lua_State *L, int all); -void luaC_collectgarbage (lua_State *L); -void luaC_link (lua_State *L, GCObject *o, lu_byte tt); - - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/liolib.c b/!NotAdopted/SmartAutoReplier/lualib/liolib.c deleted file mode 100644 index 14bd7d9909..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/liolib.c +++ /dev/null @@ -1,750 +0,0 @@ -/* -** $Id: liolib.c,v 2.39 2003/03/19 21:16:12 roberto Exp $ -** Standard I/O (and system) library -** See Copyright Notice in lua.h -*/ - - -#include -#include -#include -#include -#include -#include - -#define liolib_c - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - - -/* -** by default, gcc does not get `tmpname' -*/ -#ifndef USE_TMPNAME -#ifdef __GNUC__ -#define USE_TMPNAME 0 -#else -#define USE_TMPNAME 1 -#endif -#endif - - -/* -** by default, posix systems get `popen' -*/ -#ifndef USE_POPEN -#ifdef _POSIX_C_SOURCE -#if _POSIX_C_SOURCE >= 2 -#define USE_POPEN 1 -#endif -#endif -#endif - -#ifndef USE_POPEN -#define USE_POPEN 0 -#endif - - - - -/* -** {====================================================== -** FILE Operations -** ======================================================= -*/ - - -#if !USE_POPEN -#define pclose(f) (-1) -#endif - - -#define FILEHANDLE "FILE*" - -#define IO_INPUT "_input" -#define IO_OUTPUT "_output" - - -static int pushresult (lua_State *L, int i, const char *filename) { - if (i) { - lua_pushboolean(L, 1); - return 1; - } - else { - lua_pushnil(L); - if (filename) - lua_pushfstring(L, "%s: %s", filename, strerror(errno)); - else - lua_pushfstring(L, "%s", strerror(errno)); - lua_pushnumber(L, errno); - return 3; - } -} - - -static FILE **topfile (lua_State *L, int findex) { - FILE **f = (FILE **)luaL_checkudata(L, findex, FILEHANDLE); - if (f == NULL) luaL_argerror(L, findex, "bad file"); - return f; -} - - -static int io_type (lua_State *L) { - FILE **f = (FILE **)luaL_checkudata(L, 1, FILEHANDLE); - if (f == NULL) lua_pushnil(L); - else if (*f == NULL) - lua_pushliteral(L, "closed file"); - else - lua_pushliteral(L, "file"); - return 1; -} - - -static FILE *tofile (lua_State *L, int findex) { - FILE **f = topfile(L, findex); - if (*f == NULL) - luaL_error(L, "attempt to use a closed file"); - return *f; -} - - - -/* -** When creating file handles, always creates a `closed' file handle -** before opening the actual file; so, if there is a memory error, the -** file is not left opened. -*/ -static FILE **newfile (lua_State *L) { - FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); - *pf = NULL; /* file handle is currently `closed' */ - luaL_getmetatable(L, FILEHANDLE); - lua_setmetatable(L, -2); - return pf; -} - - -/* -** assumes that top of the stack is the `io' library, and next is -** the `io' metatable -*/ -static void registerfile (lua_State *L, FILE *f, const char *name, - const char *impname) { - lua_pushstring(L, name); - *newfile(L) = f; - if (impname) { - lua_pushstring(L, impname); - lua_pushvalue(L, -2); - lua_settable(L, -6); /* metatable[impname] = file */ - } - lua_settable(L, -3); /* io[name] = file */ -} - - -static int aux_close (lua_State *L) { - FILE *f = tofile(L, 1); - if (f == stdin || f == stdout || f == stderr) - return 0; /* file cannot be closed */ - else { - int ok = (pclose(f) != -1) || (fclose(f) == 0); - if (ok) - *(FILE **)lua_touserdata(L, 1) = NULL; /* mark file as closed */ - return ok; - } -} - - -static int io_close (lua_State *L) { - if (lua_isnone(L, 1)) { - lua_pushstring(L, IO_OUTPUT); - lua_rawget(L, lua_upvalueindex(1)); - } - return pushresult(L, aux_close(L), NULL); -} - - -static int io_gc (lua_State *L) { - FILE **f = topfile(L, 1); - if (*f != NULL) /* ignore closed files */ - aux_close(L); - return 0; -} - - -static int io_tostring (lua_State *L) { - char buff[32]; - FILE **f = topfile(L, 1); - if (*f == NULL) - strcpy(buff, "closed"); - else - sprintf(buff, "%p", lua_touserdata(L, 1)); - lua_pushfstring(L, "file (%s)", buff); - return 1; -} - - -static int io_open (lua_State *L) { - const char *filename = luaL_checkstring(L, 1); - const char *mode = luaL_optstring(L, 2, "r"); - FILE **pf = newfile(L); - *pf = fopen(filename, mode); - return (*pf == NULL) ? pushresult(L, 0, filename) : 1; -} - - -static int io_popen (lua_State *L) { -#if !USE_POPEN - luaL_error(L, "`popen' not supported"); - return 0; -#else - const char *filename = luaL_checkstring(L, 1); - const char *mode = luaL_optstring(L, 2, "r"); - FILE **pf = newfile(L); - *pf = popen(filename, mode); - return (*pf == NULL) ? pushresult(L, 0, filename) : 1; -#endif -} - - -static int io_tmpfile (lua_State *L) { - FILE **pf = newfile(L); - *pf = tmpfile(); - return (*pf == NULL) ? pushresult(L, 0, NULL) : 1; -} - - -static FILE *getiofile (lua_State *L, const char *name) { - lua_pushstring(L, name); - lua_rawget(L, lua_upvalueindex(1)); - return tofile(L, -1); -} - - -static int g_iofile (lua_State *L, const char *name, const char *mode) { - if (!lua_isnoneornil(L, 1)) { - const char *filename = lua_tostring(L, 1); - lua_pushstring(L, name); - if (filename) { - FILE **pf = newfile(L); - *pf = fopen(filename, mode); - if (*pf == NULL) { - lua_pushfstring(L, "%s: %s", filename, strerror(errno)); - luaL_argerror(L, 1, lua_tostring(L, -1)); - } - } - else { - tofile(L, 1); /* check that it's a valid file handle */ - lua_pushvalue(L, 1); - } - lua_rawset(L, lua_upvalueindex(1)); - } - /* return current value */ - lua_pushstring(L, name); - lua_rawget(L, lua_upvalueindex(1)); - return 1; -} - - -static int io_input (lua_State *L) { - return g_iofile(L, IO_INPUT, "r"); -} - - -static int io_output (lua_State *L) { - return g_iofile(L, IO_OUTPUT, "w"); -} - - -static int io_readline (lua_State *L); - - -static void aux_lines (lua_State *L, int idx, int close) { - lua_pushliteral(L, FILEHANDLE); - lua_rawget(L, LUA_REGISTRYINDEX); - lua_pushvalue(L, idx); - lua_pushboolean(L, close); /* close/not close file when finished */ - lua_pushcclosure(L, io_readline, 3); -} - - -static int f_lines (lua_State *L) { - tofile(L, 1); /* check that it's a valid file handle */ - aux_lines(L, 1, 0); - return 1; -} - - -static int io_lines (lua_State *L) { - if (lua_isnoneornil(L, 1)) { /* no arguments? */ - lua_pushstring(L, IO_INPUT); - lua_rawget(L, lua_upvalueindex(1)); /* will iterate over default input */ - return f_lines(L); - } - else { - const char *filename = luaL_checkstring(L, 1); - FILE **pf = newfile(L); - *pf = fopen(filename, "r"); - luaL_argcheck(L, *pf, 1, strerror(errno)); - aux_lines(L, lua_gettop(L), 1); - return 1; - } -} - - -/* -** {====================================================== -** READ -** ======================================================= -*/ - - -static int read_number (lua_State *L, FILE *f) { - lua_Number d; - if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { - lua_pushnumber(L, d); - return 1; - } - else return 0; /* read fails */ -} - - -static int test_eof (lua_State *L, FILE *f) { - int c = getc(f); - ungetc(c, f); - lua_pushlstring(L, NULL, 0); - return (c != EOF); -} - - -static int read_line (lua_State *L, FILE *f) { - luaL_Buffer b; - luaL_buffinit(L, &b); - for (;;) { - size_t l; - char *p = luaL_prepbuffer(&b); - if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ - luaL_pushresult(&b); /* close buffer */ - return (lua_strlen(L, -1) > 0); /* check whether read something */ - } - l = strlen(p); - if (p[l-1] != '\n') - luaL_addsize(&b, l); - else { - luaL_addsize(&b, l - 1); /* do not include `eol' */ - luaL_pushresult(&b); /* close buffer */ - return 1; /* read at least an `eol' */ - } - } -} - - -static int read_chars (lua_State *L, FILE *f, size_t n) { - size_t rlen; /* how much to read */ - size_t nr; /* number of chars actually read */ - luaL_Buffer b; - luaL_buffinit(L, &b); - rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ - do { - char *p = luaL_prepbuffer(&b); - if (rlen > n) rlen = n; /* cannot read more than asked */ - nr = fread(p, sizeof(char), rlen, f); - luaL_addsize(&b, nr); - n -= nr; /* still have to read `n' chars */ - } while (n > 0 && nr == rlen); /* until end of count or eof */ - luaL_pushresult(&b); /* close buffer */ - return (n == 0 || lua_strlen(L, -1) > 0); -} - - -static int g_read (lua_State *L, FILE *f, int first) { - int nargs = lua_gettop(L) - 1; - int success; - int n; - if (nargs == 0) { /* no arguments? */ - success = read_line(L, f); - n = first+1; /* to return 1 result */ - } - else { /* ensure stack space for all results and for auxlib's buffer */ - luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); - success = 1; - for (n = first; nargs-- && success; n++) { - if (lua_type(L, n) == LUA_TNUMBER) { - size_t l = (size_t)lua_tonumber(L, n); - success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); - } - else { - const char *p = lua_tostring(L, n); - luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); - switch (p[1]) { - case 'n': /* number */ - success = read_number(L, f); - break; - case 'l': /* line */ - success = read_line(L, f); - break; - case 'a': /* file */ - read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ - success = 1; /* always success */ - break; - case 'w': /* word */ - return luaL_error(L, "obsolete option `*w' to `read'"); - default: - return luaL_argerror(L, n, "invalid format"); - } - } - } - } - if (!success) { - lua_pop(L, 1); /* remove last result */ - lua_pushnil(L); /* push nil instead */ - } - return n - first; -} - - -static int io_read (lua_State *L) { - return g_read(L, getiofile(L, IO_INPUT), 1); -} - - -static int f_read (lua_State *L) { - return g_read(L, tofile(L, 1), 2); -} - - -static int io_readline (lua_State *L) { - FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(2)); - if (f == NULL) /* file is already closed? */ - luaL_error(L, "file is already closed"); - if (read_line(L, f)) return 1; - else { /* EOF */ - if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ - lua_settop(L, 0); - lua_pushvalue(L, lua_upvalueindex(2)); - aux_close(L); /* close it */ - } - return 0; - } -} - -/* }====================================================== */ - - -static int g_write (lua_State *L, FILE *f, int arg) { - int nargs = lua_gettop(L) - 1; - int status = 1; - for (; nargs--; arg++) { - if (lua_type(L, arg) == LUA_TNUMBER) { - /* optimization: could be done exactly as for strings */ - status = status && - fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; - } - else { - size_t l; - const char *s = luaL_checklstring(L, arg, &l); - status = status && (fwrite(s, sizeof(char), l, f) == l); - } - } - return pushresult(L, status, NULL); -} - - -static int io_write (lua_State *L) { - return g_write(L, getiofile(L, IO_OUTPUT), 1); -} - - -static int f_write (lua_State *L) { - return g_write(L, tofile(L, 1), 2); -} - - -static int f_seek (lua_State *L) { - static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; - static const char *const modenames[] = {"set", "cur", "end", NULL}; - FILE *f = tofile(L, 1); - int op = luaL_findstring(luaL_optstring(L, 2, "cur"), modenames); - long offset = luaL_optlong(L, 3, 0); - luaL_argcheck(L, op != -1, 2, "invalid mode"); - op = fseek(f, offset, mode[op]); - if (op) - return pushresult(L, 0, NULL); /* error */ - else { - lua_pushnumber(L, ftell(f)); - return 1; - } -} - - -static int io_flush (lua_State *L) { - return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); -} - - -static int f_flush (lua_State *L) { - return pushresult(L, fflush(tofile(L, 1)) == 0, NULL); -} - - -static const luaL_reg iolib[] = { - {"input", io_input}, - {"output", io_output}, - {"lines", io_lines}, - {"close", io_close}, - {"flush", io_flush}, - {"open", io_open}, - {"popen", io_popen}, - {"read", io_read}, - {"tmpfile", io_tmpfile}, - {"type", io_type}, - {"write", io_write}, - {NULL, NULL} -}; - - -static const luaL_reg flib[] = { - {"flush", f_flush}, - {"read", f_read}, - {"lines", f_lines}, - {"seek", f_seek}, - {"write", f_write}, - {"close", io_close}, - {"__gc", io_gc}, - {"__tostring", io_tostring}, - {NULL, NULL} -}; - - -static void createmeta (lua_State *L) { - luaL_newmetatable(L, FILEHANDLE); /* create new metatable for file handles */ - /* file methods */ - lua_pushliteral(L, "__index"); - lua_pushvalue(L, -2); /* push metatable */ - lua_rawset(L, -3); /* metatable.__index = metatable */ - luaL_openlib(L, NULL, flib, 0); -} - -/* }====================================================== */ - - -/* -** {====================================================== -** Other O.S. Operations -** ======================================================= -*/ - -static int io_execute (lua_State *L) { - lua_pushnumber(L, system(luaL_checkstring(L, 1))); - return 1; -} - - -static int io_remove (lua_State *L) { - const char *filename = luaL_checkstring(L, 1); - return pushresult(L, remove(filename) == 0, filename); -} - - -static int io_rename (lua_State *L) { - const char *fromname = luaL_checkstring(L, 1); - const char *toname = luaL_checkstring(L, 2); - return pushresult(L, rename(fromname, toname) == 0, fromname); -} - - -static int io_tmpname (lua_State *L) { -#if !USE_TMPNAME - luaL_error(L, "`tmpname' not supported"); - return 0; -#else - char buff[L_tmpnam]; - if (tmpnam(buff) != buff) - return luaL_error(L, "unable to generate a unique filename in `tmpname'"); - lua_pushstring(L, buff); - return 1; -#endif -} - - -static int io_getenv (lua_State *L) { - lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ - return 1; -} - - -static int io_clock (lua_State *L) { - lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); - return 1; -} - - -/* -** {====================================================== -** Time/Date operations -** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, -** wday=%w+1, yday=%j, isdst=? } -** ======================================================= -*/ - -static void setfield (lua_State *L, const char *key, int value) { - lua_pushstring(L, key); - lua_pushnumber(L, value); - lua_rawset(L, -3); -} - -static void setboolfield (lua_State *L, const char *key, int value) { - lua_pushstring(L, key); - lua_pushboolean(L, value); - lua_rawset(L, -3); -} - -static int getboolfield (lua_State *L, const char *key) { - int res; - lua_pushstring(L, key); - lua_gettable(L, -2); - res = lua_toboolean(L, -1); - lua_pop(L, 1); - return res; -} - - -static int getfield (lua_State *L, const char *key, int d) { - int res; - lua_pushstring(L, key); - lua_gettable(L, -2); - if (lua_isnumber(L, -1)) - res = (int)(lua_tonumber(L, -1)); - else { - if (d == -2) - return luaL_error(L, "field `%s' missing in date table", key); - res = d; - } - lua_pop(L, 1); - return res; -} - - -static int io_date (lua_State *L) { - const char *s = luaL_optstring(L, 1, "%c"); - time_t t = (time_t)(luaL_optnumber(L, 2, -1)); - struct tm *stm; - if (t == (time_t)(-1)) /* no time given? */ - t = time(NULL); /* use current time */ - if (*s == '!') { /* UTC? */ - stm = gmtime(&t); - s++; /* skip `!' */ - } - else - stm = localtime(&t); - if (stm == NULL) /* invalid date? */ - lua_pushnil(L); - else if (strcmp(s, "*t") == 0) { - lua_newtable(L); - setfield(L, "sec", stm->tm_sec); - setfield(L, "min", stm->tm_min); - setfield(L, "hour", stm->tm_hour); - setfield(L, "day", stm->tm_mday); - setfield(L, "month", stm->tm_mon+1); - setfield(L, "year", stm->tm_year+1900); - setfield(L, "wday", stm->tm_wday+1); - setfield(L, "yday", stm->tm_yday+1); - setboolfield(L, "isdst", stm->tm_isdst); - } - else { - char b[256]; - if (strftime(b, sizeof(b), s, stm)) - lua_pushstring(L, b); - else - return luaL_error(L, "`date' format too long"); - } - return 1; -} - - -static int io_time (lua_State *L) { - if (lua_isnoneornil(L, 1)) /* called without args? */ - lua_pushnumber(L, time(NULL)); /* return current time */ - else { - time_t t; - struct tm ts; - luaL_checktype(L, 1, LUA_TTABLE); - lua_settop(L, 1); /* make sure table is at the top */ - ts.tm_sec = getfield(L, "sec", 0); - ts.tm_min = getfield(L, "min", 0); - ts.tm_hour = getfield(L, "hour", 12); - ts.tm_mday = getfield(L, "day", -2); - ts.tm_mon = getfield(L, "month", -2) - 1; - ts.tm_year = getfield(L, "year", -2) - 1900; - ts.tm_isdst = getboolfield(L, "isdst"); - t = mktime(&ts); - if (t == (time_t)(-1)) - lua_pushnil(L); - else - lua_pushnumber(L, t); - } - return 1; -} - - -static int io_difftime (lua_State *L) { - lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), - (time_t)(luaL_optnumber(L, 2, 0)))); - return 1; -} - -/* }====================================================== */ - - -static int io_setloc (lua_State *L) { - static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, - LC_NUMERIC, LC_TIME}; - static const char *const catnames[] = {"all", "collate", "ctype", "monetary", - "numeric", "time", NULL}; - const char *l = lua_tostring(L, 1); - int op = luaL_findstring(luaL_optstring(L, 2, "all"), catnames); - luaL_argcheck(L, l || lua_isnoneornil(L, 1), 1, "string expected"); - luaL_argcheck(L, op != -1, 2, "invalid option"); - lua_pushstring(L, setlocale(cat[op], l)); - return 1; -} - - -static int io_exit (lua_State *L) { - exit(luaL_optint(L, 1, EXIT_SUCCESS)); - return 0; /* to avoid warnings */ -} - -static const luaL_reg syslib[] = { - {"clock", io_clock}, - {"date", io_date}, - {"difftime", io_difftime}, - {"execute", io_execute}, - {"exit", io_exit}, - {"getenv", io_getenv}, - {"remove", io_remove}, - {"rename", io_rename}, - {"setlocale", io_setloc}, - {"time", io_time}, - {"tmpname", io_tmpname}, - {NULL, NULL} -}; - -/* }====================================================== */ - - - -LUALIB_API int luaopen_io (lua_State *L) { - luaL_openlib(L, LUA_OSLIBNAME, syslib, 0); - createmeta(L); - lua_pushvalue(L, -1); - luaL_openlib(L, LUA_IOLIBNAME, iolib, 1); - /* put predefined file handles into `io' table */ - registerfile(L, stdin, "stdin", IO_INPUT); - registerfile(L, stdout, "stdout", IO_OUTPUT); - registerfile(L, stderr, "stderr", NULL); - return 1; -} - diff --git a/!NotAdopted/SmartAutoReplier/lualib/llex.c b/!NotAdopted/SmartAutoReplier/lualib/llex.c deleted file mode 100644 index 045e999443..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/llex.c +++ /dev/null @@ -1,417 +0,0 @@ -/* -** $Id: llex.c,v 1.119 2003/03/24 12:39:34 roberto Exp $ -** Lexical Analyzer -** See Copyright Notice in lua.h -*/ - - -#include -#include - -#define llex_c - -#include "lua.h" - -#include "ldo.h" -#include "llex.h" -#include "lobject.h" -#include "lparser.h" -#include "lstate.h" -#include "lstring.h" -#include "lzio.h" - - - -#define next(LS) (LS->current = zgetc(LS->z)) - - - -/* ORDER RESERVED */ -static const char *const token2string [] = { - "and", "break", "do", "else", "elseif", - "end", "false", "for", "function", "if", - "in", "local", "nil", "not", "or", "repeat", - "return", "then", "true", "until", "while", "*name", - "..", "...", "==", ">=", "<=", "~=", - "*number", "*string", "" -}; - - -void luaX_init (lua_State *L) { - int i; - for (i=0; itsv.reserved = cast(lu_byte, i+1); /* reserved word */ - } -} - - -#define MAXSRC 80 - - -void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) { - if (val > limit) { - msg = luaO_pushfstring(ls->L, "too many %s (limit=%d)", msg, limit); - luaX_syntaxerror(ls, msg); - } -} - - -void luaX_errorline (LexState *ls, const char *s, const char *token, int line) { - lua_State *L = ls->L; - char buff[MAXSRC]; - luaO_chunkid(buff, getstr(ls->source), MAXSRC); - luaO_pushfstring(L, "%s:%d: %s near `%s'", buff, line, s, token); - luaD_throw(L, LUA_ERRSYNTAX); -} - - -static void luaX_error (LexState *ls, const char *s, const char *token) { - luaX_errorline(ls, s, token, ls->linenumber); -} - - -void luaX_syntaxerror (LexState *ls, const char *msg) { - const char *lasttoken; - switch (ls->t.token) { - case TK_NAME: - lasttoken = getstr(ls->t.seminfo.ts); - break; - case TK_STRING: - case TK_NUMBER: - lasttoken = luaZ_buffer(ls->buff); - break; - default: - lasttoken = luaX_token2str(ls, ls->t.token); - break; - } - luaX_error(ls, msg, lasttoken); -} - - -const char *luaX_token2str (LexState *ls, int token) { - if (token < FIRST_RESERVED) { - lua_assert(token == (unsigned char)token); - return luaO_pushfstring(ls->L, "%c", token); - } - else - return token2string[token-FIRST_RESERVED]; -} - - -static void luaX_lexerror (LexState *ls, const char *s, int token) { - if (token == TK_EOS) - luaX_error(ls, s, luaX_token2str(ls, token)); - else - luaX_error(ls, s, luaZ_buffer(ls->buff)); -} - - -static void inclinenumber (LexState *LS) { - next(LS); /* skip `\n' */ - ++LS->linenumber; - luaX_checklimit(LS, LS->linenumber, MAX_INT, "lines in a chunk"); -} - - -void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) { - LS->L = L; - LS->lookahead.token = TK_EOS; /* no look-ahead token */ - LS->z = z; - LS->fs = NULL; - LS->linenumber = 1; - LS->lastline = 1; - LS->source = source; - next(LS); /* read first char */ - if (LS->current == '#') { - do { /* skip first line */ - next(LS); - } while (LS->current != '\n' && LS->current != EOZ); - } -} - - - -/* -** ======================================================= -** LEXICAL ANALYZER -** ======================================================= -*/ - - -/* use buffer to store names, literal strings and numbers */ - -/* extra space to allocate when growing buffer */ -#define EXTRABUFF 32 - -/* maximum number of chars that can be read without checking buffer size */ -#define MAXNOCHECK 5 - -#define checkbuffer(LS, len) \ - if (((len)+MAXNOCHECK)*sizeof(char) > luaZ_sizebuffer((LS)->buff)) \ - luaZ_openspace((LS)->L, (LS)->buff, (len)+EXTRABUFF) - -#define save(LS, c, l) \ - (luaZ_buffer((LS)->buff)[l++] = cast(char, c)) -#define save_and_next(LS, l) (save(LS, LS->current, l), next(LS)) - - -static size_t readname (LexState *LS) { - size_t l = 0; - checkbuffer(LS, l); - do { - checkbuffer(LS, l); - save_and_next(LS, l); - } while (isalnum(LS->current) || LS->current == '_'); - save(LS, '\0', l); - return l-1; -} - - -/* LUA_NUMBER */ -static void read_numeral (LexState *LS, int comma, SemInfo *seminfo) { - size_t l = 0; - checkbuffer(LS, l); - if (comma) save(LS, '.', l); - while (isdigit(LS->current)) { - checkbuffer(LS, l); - save_and_next(LS, l); - } - if (LS->current == '.') { - save_and_next(LS, l); - if (LS->current == '.') { - save_and_next(LS, l); - save(LS, '\0', l); - luaX_lexerror(LS, - "ambiguous syntax (decimal point x string concatenation)", - TK_NUMBER); - } - } - while (isdigit(LS->current)) { - checkbuffer(LS, l); - save_and_next(LS, l); - } - if (LS->current == 'e' || LS->current == 'E') { - save_and_next(LS, l); /* read `E' */ - if (LS->current == '+' || LS->current == '-') - save_and_next(LS, l); /* optional exponent sign */ - while (isdigit(LS->current)) { - checkbuffer(LS, l); - save_and_next(LS, l); - } - } - save(LS, '\0', l); - if (!luaO_str2d(luaZ_buffer(LS->buff), &seminfo->r)) - luaX_lexerror(LS, "malformed number", TK_NUMBER); -} - - -static void read_long_string (LexState *LS, SemInfo *seminfo) { - int cont = 0; - size_t l = 0; - checkbuffer(LS, l); - save(LS, '[', l); /* save first `[' */ - save_and_next(LS, l); /* pass the second `[' */ - if (LS->current == '\n') /* string starts with a newline? */ - inclinenumber(LS); /* skip it */ - for (;;) { - checkbuffer(LS, l); - switch (LS->current) { - case EOZ: - save(LS, '\0', l); - luaX_lexerror(LS, (seminfo) ? "unfinished long string" : - "unfinished long comment", TK_EOS); - break; /* to avoid warnings */ - case '[': - save_and_next(LS, l); - if (LS->current == '[') { - cont++; - save_and_next(LS, l); - } - continue; - case ']': - save_and_next(LS, l); - if (LS->current == ']') { - if (cont == 0) goto endloop; - cont--; - save_and_next(LS, l); - } - continue; - case '\n': - save(LS, '\n', l); - inclinenumber(LS); - if (!seminfo) l = 0; /* reset buffer to avoid wasting space */ - continue; - default: - save_and_next(LS, l); - } - } endloop: - save_and_next(LS, l); /* skip the second `]' */ - save(LS, '\0', l); - if (seminfo) - seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 2, l - 5); -} - - -static void read_string (LexState *LS, int del, SemInfo *seminfo) { - size_t l = 0; - checkbuffer(LS, l); - save_and_next(LS, l); - while (LS->current != del) { - checkbuffer(LS, l); - switch (LS->current) { - case EOZ: - save(LS, '\0', l); - luaX_lexerror(LS, "unfinished string", TK_EOS); - break; /* to avoid warnings */ - case '\n': - save(LS, '\0', l); - luaX_lexerror(LS, "unfinished string", TK_STRING); - break; /* to avoid warnings */ - case '\\': - next(LS); /* do not save the `\' */ - switch (LS->current) { - case 'a': save(LS, '\a', l); next(LS); break; - case 'b': save(LS, '\b', l); next(LS); break; - case 'f': save(LS, '\f', l); next(LS); break; - case 'n': save(LS, '\n', l); next(LS); break; - case 'r': save(LS, '\r', l); next(LS); break; - case 't': save(LS, '\t', l); next(LS); break; - case 'v': save(LS, '\v', l); next(LS); break; - case '\n': save(LS, '\n', l); inclinenumber(LS); break; - case EOZ: break; /* will raise an error next loop */ - default: { - if (!isdigit(LS->current)) - save_and_next(LS, l); /* handles \\, \", \', and \? */ - else { /* \xxx */ - int c = 0; - int i = 0; - do { - c = 10*c + (LS->current-'0'); - next(LS); - } while (++i<3 && isdigit(LS->current)); - if (c > UCHAR_MAX) { - save(LS, '\0', l); - luaX_lexerror(LS, "escape sequence too large", TK_STRING); - } - save(LS, c, l); - } - } - } - break; - default: - save_and_next(LS, l); - } - } - save_and_next(LS, l); /* skip delimiter */ - save(LS, '\0', l); - seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 1, l - 3); -} - - -int luaX_lex (LexState *LS, SemInfo *seminfo) { - for (;;) { - switch (LS->current) { - - case '\n': { - inclinenumber(LS); - continue; - } - case '-': { - next(LS); - if (LS->current != '-') return '-'; - /* else is a comment */ - next(LS); - if (LS->current == '[' && (next(LS), LS->current == '[')) - read_long_string(LS, NULL); /* long comment */ - else /* short comment */ - while (LS->current != '\n' && LS->current != EOZ) - next(LS); - continue; - } - case '[': { - next(LS); - if (LS->current != '[') return '['; - else { - read_long_string(LS, seminfo); - return TK_STRING; - } - } - case '=': { - next(LS); - if (LS->current != '=') return '='; - else { next(LS); return TK_EQ; } - } - case '<': { - next(LS); - if (LS->current != '=') return '<'; - else { next(LS); return TK_LE; } - } - case '>': { - next(LS); - if (LS->current != '=') return '>'; - else { next(LS); return TK_GE; } - } - case '~': { - next(LS); - if (LS->current != '=') return '~'; - else { next(LS); return TK_NE; } - } - case '"': - case '\'': { - read_string(LS, LS->current, seminfo); - return TK_STRING; - } - case '.': { - next(LS); - if (LS->current == '.') { - next(LS); - if (LS->current == '.') { - next(LS); - return TK_DOTS; /* ... */ - } - else return TK_CONCAT; /* .. */ - } - else if (!isdigit(LS->current)) return '.'; - else { - read_numeral(LS, 1, seminfo); - return TK_NUMBER; - } - } - case EOZ: { - return TK_EOS; - } - default: { - if (isspace(LS->current)) { - next(LS); - continue; - } - else if (isdigit(LS->current)) { - read_numeral(LS, 0, seminfo); - return TK_NUMBER; - } - else if (isalpha(LS->current) || LS->current == '_') { - /* identifier or reserved word */ - size_t l = readname(LS); - TString *ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff), l); - if (ts->tsv.reserved > 0) /* reserved word? */ - return ts->tsv.reserved - 1 + FIRST_RESERVED; - seminfo->ts = ts; - return TK_NAME; - } - else { - int c = LS->current; - if (iscntrl(c)) - luaX_error(LS, "invalid control char", - luaO_pushfstring(LS->L, "char(%d)", c)); - next(LS); - return c; /* single-char tokens (+ - / ...) */ - } - } - } - } -} - -#undef next diff --git a/!NotAdopted/SmartAutoReplier/lualib/llex.h b/!NotAdopted/SmartAutoReplier/lualib/llex.h deleted file mode 100644 index 740e3f6b31..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/llex.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -** $Id: llex.h,v 1.47 2003/02/28 17:19:47 roberto Exp $ -** Lexical Analyzer -** See Copyright Notice in lua.h -*/ - -#ifndef llex_h -#define llex_h - -#include "lobject.h" -#include "lzio.h" - - -#define FIRST_RESERVED 257 - -/* maximum length of a reserved word */ -#define TOKEN_LEN (sizeof("function")/sizeof(char)) - - -/* -* WARNING: if you change the order of this enumeration, -* grep "ORDER RESERVED" -*/ -enum RESERVED { - /* terminal symbols denoted by reserved words */ - TK_AND = FIRST_RESERVED, TK_BREAK, - TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, - TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, - TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, - /* other terminal symbols */ - TK_NAME, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, - TK_STRING, TK_EOS -}; - -/* number of reserved words */ -#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) - - -typedef union { - lua_Number r; - TString *ts; -} SemInfo; /* semantics information */ - - -typedef struct Token { - int token; - SemInfo seminfo; -} Token; - - -typedef struct LexState { - int current; /* current character (charint) */ - int linenumber; /* input line counter */ - int lastline; /* line of last token `consumed' */ - Token t; /* current token */ - Token lookahead; /* look ahead token */ - struct FuncState *fs; /* `FuncState' is private to the parser */ - struct lua_State *L; - ZIO *z; /* input stream */ - Mbuffer *buff; /* buffer for tokens */ - TString *source; /* current source name */ - int nestlevel; /* level of nested non-terminals */ -} LexState; - - -void luaX_init (lua_State *L); -void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source); -int luaX_lex (LexState *LS, SemInfo *seminfo); -void luaX_checklimit (LexState *ls, int val, int limit, const char *msg); -void luaX_syntaxerror (LexState *ls, const char *s); -void luaX_errorline (LexState *ls, const char *s, const char *token, int line); -const char *luaX_token2str (LexState *ls, int token); - - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/llimits.h b/!NotAdopted/SmartAutoReplier/lualib/llimits.h deleted file mode 100644 index 343c922612..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/llimits.h +++ /dev/null @@ -1,185 +0,0 @@ -/* -** $Id: llimits.h,v 1.52 2003/02/20 19:33:23 roberto Exp $ -** Limits, basic types, and some other `installation-dependent' definitions -** See Copyright Notice in lua.h -*/ - -#ifndef llimits_h -#define llimits_h - - -#include -#include - - -#include "lua.h" - - -/* -** try to find number of bits in an integer -*/ -#ifndef BITS_INT -/* avoid overflows in comparison */ -#if INT_MAX-20 < 32760 -#define BITS_INT 16 -#else -#if INT_MAX > 2147483640L -/* machine has at least 32 bits */ -#define BITS_INT 32 -#else -#error "you must define BITS_INT with number of bits in an integer" -#endif -#endif -#endif - - -/* -** the following types define integer types for values that may not -** fit in a `small int' (16 bits), but may waste space in a -** `large long' (64 bits). The current definitions should work in -** any machine, but may not be optimal. -*/ - -/* an unsigned integer to hold hash values */ -typedef unsigned int lu_hash; -/* its signed equivalent */ -typedef int ls_hash; - -/* an unsigned integer big enough to count the total memory used by Lua; */ -/* it should be at least as large as size_t */ -typedef unsigned long lu_mem; - -#define MAX_LUMEM ULONG_MAX - - -/* an integer big enough to count the number of strings in use */ -typedef long ls_nstr; - -/* chars used as small naturals (so that `char' is reserved for characters) */ -typedef unsigned char lu_byte; - - -#define MAX_SIZET ((size_t)(~(size_t)0)-2) - - -#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ - -/* -** conversion of pointer to integer -** this is for hashing only; there is no problem if the integer -** cannot hold the whole pointer value -*/ -#define IntPoint(p) ((lu_hash)(p)) - - - -/* type to ensure maximum alignment */ -#ifndef LUSER_ALIGNMENT_T -typedef union { double u; void *s; long l; } L_Umaxalign; -#else -typedef LUSER_ALIGNMENT_T L_Umaxalign; -#endif - - -/* result of `usual argument conversion' over lua_Number */ -#ifndef LUA_UACNUMBER -typedef double l_uacNumber; -#else -typedef LUA_UACNUMBER l_uacNumber; -#endif - - -#ifndef lua_assert -#define lua_assert(c) /* empty */ -#endif - - -#ifndef check_exp -#define check_exp(c,e) (e) -#endif - - -#ifndef UNUSED -#define UNUSED(x) ((void)(x)) /* to avoid warnings */ -#endif - - -#ifndef cast -#define cast(t, exp) ((t)(exp)) -#endif - - - -/* -** type for virtual-machine instructions -** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) -*/ -typedef unsigned long Instruction; - - -/* maximum depth for calls (unsigned short) */ -#ifndef LUA_MAXCALLS -#define LUA_MAXCALLS 4096 -#endif - - -/* -** maximum depth for C calls (unsigned short): Not too big, or may -** overflow the C stack... -*/ - -#ifndef LUA_MAXCCALLS -#define LUA_MAXCCALLS 200 -#endif - - -/* maximum size for the C stack */ -#ifndef LUA_MAXCSTACK -#define LUA_MAXCSTACK 2048 -#endif - - -/* maximum stack for a Lua function */ -#define MAXSTACK 250 - - -/* maximum number of variables declared in a function */ -#ifndef MAXVARS -#define MAXVARS 200 /* arbitrary limit ( -#include - -#define lmathlib_c - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - -#undef PI -#define PI (3.14159265358979323846) -#define RADIANS_PER_DEGREE (PI/180.0) - - - -/* -** If you want Lua to operate in degrees (instead of radians), -** define USE_DEGREES -*/ -#ifdef USE_DEGREES -#define FROMRAD(a) ((a)/RADIANS_PER_DEGREE) -#define TORAD(a) ((a)*RADIANS_PER_DEGREE) -#else -#define FROMRAD(a) (a) -#define TORAD(a) (a) -#endif - - -static int math_abs (lua_State *L) { - lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); - return 1; -} - -static int math_sin (lua_State *L) { - lua_pushnumber(L, sin(TORAD(luaL_checknumber(L, 1)))); - return 1; -} - -static int math_cos (lua_State *L) { - lua_pushnumber(L, cos(TORAD(luaL_checknumber(L, 1)))); - return 1; -} - -static int math_tan (lua_State *L) { - lua_pushnumber(L, tan(TORAD(luaL_checknumber(L, 1)))); - return 1; -} - -static int math_asin (lua_State *L) { - lua_pushnumber(L, FROMRAD(asin(luaL_checknumber(L, 1)))); - return 1; -} - -static int math_acos (lua_State *L) { - lua_pushnumber(L, FROMRAD(acos(luaL_checknumber(L, 1)))); - return 1; -} - -static int math_atan (lua_State *L) { - lua_pushnumber(L, FROMRAD(atan(luaL_checknumber(L, 1)))); - return 1; -} - -static int math_atan2 (lua_State *L) { - lua_pushnumber(L, FROMRAD(atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2)))); - return 1; -} - -static int math_ceil (lua_State *L) { - lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); - return 1; -} - -static int math_floor (lua_State *L) { - lua_pushnumber(L, floor(luaL_checknumber(L, 1))); - return 1; -} - -static int math_mod (lua_State *L) { - lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); - return 1; -} - -static int math_sqrt (lua_State *L) { - lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); - return 1; -} - -static int math_pow (lua_State *L) { - lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); - return 1; -} - -static int math_log (lua_State *L) { - lua_pushnumber(L, log(luaL_checknumber(L, 1))); - return 1; -} - -static int math_log10 (lua_State *L) { - lua_pushnumber(L, log10(luaL_checknumber(L, 1))); - return 1; -} - -static int math_exp (lua_State *L) { - lua_pushnumber(L, exp(luaL_checknumber(L, 1))); - return 1; -} - -static int math_deg (lua_State *L) { - lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); - return 1; -} - -static int math_rad (lua_State *L) { - lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); - return 1; -} - -static int math_frexp (lua_State *L) { - int e; - lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); - lua_pushnumber(L, e); - return 2; -} - -static int math_ldexp (lua_State *L) { - lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2))); - return 1; -} - - - -static int math_min (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - lua_Number dmin = luaL_checknumber(L, 1); - int i; - for (i=2; i<=n; i++) { - lua_Number d = luaL_checknumber(L, i); - if (d < dmin) - dmin = d; - } - lua_pushnumber(L, dmin); - return 1; -} - - -static int math_max (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - lua_Number dmax = luaL_checknumber(L, 1); - int i; - for (i=2; i<=n; i++) { - lua_Number d = luaL_checknumber(L, i); - if (d > dmax) - dmax = d; - } - lua_pushnumber(L, dmax); - return 1; -} - - -static int math_random (lua_State *L) { - /* the `%' avoids the (rare) case of r==1, and is needed also because on - some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ - lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; - switch (lua_gettop(L)) { /* check number of arguments */ - case 0: { /* no arguments */ - lua_pushnumber(L, r); /* Number between 0 and 1 */ - break; - } - case 1: { /* only upper limit */ - int u = luaL_checkint(L, 1); - luaL_argcheck(L, 1<=u, 1, "interval is empty"); - lua_pushnumber(L, (int)floor(r*u)+1); /* int between 1 and `u' */ - break; - } - case 2: { /* lower and upper limits */ - int l = luaL_checkint(L, 1); - int u = luaL_checkint(L, 2); - luaL_argcheck(L, l<=u, 2, "interval is empty"); - lua_pushnumber(L, (int)floor(r*(u-l+1))+l); /* int between `l' and `u' */ - break; - } - default: return luaL_error(L, "wrong number of arguments"); - } - return 1; -} - - -static int math_randomseed (lua_State *L) { - srand(luaL_checkint(L, 1)); - return 0; -} - - -static const luaL_reg mathlib[] = { - {"abs", math_abs}, - {"sin", math_sin}, - {"cos", math_cos}, - {"tan", math_tan}, - {"asin", math_asin}, - {"acos", math_acos}, - {"atan", math_atan}, - {"atan2", math_atan2}, - {"ceil", math_ceil}, - {"floor", math_floor}, - {"mod", math_mod}, - {"frexp", math_frexp}, - {"ldexp", math_ldexp}, - {"sqrt", math_sqrt}, - {"min", math_min}, - {"max", math_max}, - {"log", math_log}, - {"log10", math_log10}, - {"exp", math_exp}, - {"deg", math_deg}, - {"pow", math_pow}, - {"rad", math_rad}, - {"random", math_random}, - {"randomseed", math_randomseed}, - {NULL, NULL} -}; - - -/* -** Open math library -*/ -LUALIB_API int luaopen_math (lua_State *L) { - luaL_openlib(L, LUA_MATHLIBNAME, mathlib, 0); - lua_pushliteral(L, "pi"); - lua_pushnumber(L, PI); - lua_settable(L, -3); - lua_pushliteral(L, "__pow"); - lua_pushcfunction(L, math_pow); - lua_settable(L, LUA_GLOBALSINDEX); - return 1; -} - diff --git a/!NotAdopted/SmartAutoReplier/lualib/lmem.c b/!NotAdopted/SmartAutoReplier/lualib/lmem.c deleted file mode 100644 index f977770af0..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lmem.c +++ /dev/null @@ -1,91 +0,0 @@ -/* -** $Id: lmem.c,v 1.61 2002/12/04 17:38:31 roberto Exp $ -** Interface to Memory Manager -** See Copyright Notice in lua.h -*/ - - -#include - -#define lmem_c - -#include "lua.h" - -#include "ldebug.h" -#include "ldo.h" -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" - - - -/* -** definition for realloc function. It must assure that l_realloc(NULL, -** 0, x) allocates a new block (ANSI C assures that). (`os' is the old -** block size; some allocators may use that.) -*/ -#ifndef l_realloc -#define l_realloc(b,os,s) realloc(b,s) -#endif - -/* -** definition for free function. (`os' is the old block size; some -** allocators may use that.) -*/ -#ifndef l_free -#define l_free(b,os) free(b) -#endif - - -#define MINSIZEARRAY 4 - - -void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems, - int limit, const char *errormsg) { - void *newblock; - int newsize = (*size)*2; - if (newsize < MINSIZEARRAY) - newsize = MINSIZEARRAY; /* minimum size */ - else if (*size >= limit/2) { /* cannot double it? */ - if (*size < limit - MINSIZEARRAY) /* try something smaller... */ - newsize = limit; /* still have at least MINSIZEARRAY free places */ - else luaG_runerror(L, errormsg); - } - newblock = luaM_realloc(L, block, - cast(lu_mem, *size)*cast(lu_mem, size_elems), - cast(lu_mem, newsize)*cast(lu_mem, size_elems)); - *size = newsize; /* update only when everything else is OK */ - return newblock; -} - - -/* -** generic allocation routine. -*/ -void *luaM_realloc (lua_State *L, void *block, lu_mem oldsize, lu_mem size) { - lua_assert((oldsize == 0) == (block == NULL)); - if (size == 0) { - if (block != NULL) { - l_free(block, oldsize); - block = NULL; - } - else return NULL; /* avoid `nblocks' computations when oldsize==size==0 */ - } - else if (size >= MAX_SIZET) - luaG_runerror(L, "memory allocation error: block too big"); - else { - block = l_realloc(block, oldsize, size); - if (block == NULL) { - if (L) - luaD_throw(L, LUA_ERRMEM); - else return NULL; /* error before creating state! */ - } - } - if (L) { - lua_assert(G(L) != NULL && G(L)->nblocks > 0); - G(L)->nblocks -= oldsize; - G(L)->nblocks += size; - } - return block; -} - diff --git a/!NotAdopted/SmartAutoReplier/lualib/lmem.h b/!NotAdopted/SmartAutoReplier/lualib/lmem.h deleted file mode 100644 index 1bb4fde0b2..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lmem.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -** $Id: lmem.h,v 1.26 2002/05/01 20:40:42 roberto Exp $ -** Interface to Memory Manager -** See Copyright Notice in lua.h -*/ - -#ifndef lmem_h -#define lmem_h - - -#include - -#include "llimits.h" -#include "lua.h" - -#define MEMERRMSG "not enough memory" - - -void *luaM_realloc (lua_State *L, void *oldblock, lu_mem oldsize, lu_mem size); - -void *luaM_growaux (lua_State *L, void *block, int *size, int size_elem, - int limit, const char *errormsg); - -#define luaM_free(L, b, s) luaM_realloc(L, (b), (s), 0) -#define luaM_freelem(L, b) luaM_realloc(L, (b), sizeof(*(b)), 0) -#define luaM_freearray(L, b, n, t) luaM_realloc(L, (b), \ - cast(lu_mem, n)*cast(lu_mem, sizeof(t)), 0) - -#define luaM_malloc(L, t) luaM_realloc(L, NULL, 0, (t)) -#define luaM_new(L, t) cast(t *, luaM_malloc(L, sizeof(t))) -#define luaM_newvector(L, n,t) cast(t *, luaM_malloc(L, \ - cast(lu_mem, n)*cast(lu_mem, sizeof(t)))) - -#define luaM_growvector(L,v,nelems,size,t,limit,e) \ - if (((nelems)+1) > (size)) \ - ((v)=cast(t *, luaM_growaux(L,v,&(size),sizeof(t),limit,e))) - -#define luaM_reallocvector(L, v,oldn,n,t) \ - ((v)=cast(t *, luaM_realloc(L, v,cast(lu_mem, oldn)*cast(lu_mem, sizeof(t)), \ - cast(lu_mem, n)*cast(lu_mem, sizeof(t))))) - - -#endif - diff --git a/!NotAdopted/SmartAutoReplier/lualib/loadlib.c b/!NotAdopted/SmartAutoReplier/lualib/loadlib.c deleted file mode 100644 index ac4d697a68..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/loadlib.c +++ /dev/null @@ -1,205 +0,0 @@ -/* -** $Id: loadlib.c,v 1.4 2003/04/07 20:11:53 roberto Exp $ -** Dynamic library loader for Lua -** See Copyright Notice in lua.h -* -* This Lua library exports a single function, called loadlib, which is -* called from Lua as loadlib(lib,init), where lib is the full name of the -* library to be loaded (including the complete path) and init is the name -* of a function to be called after the library is loaded. Typically, this -* function will register other functions, thus making the complete library -* available to Lua. The init function is *not* automatically called by -* loadlib. Instead, loadlib returns the init function as a Lua function -* that the client can call when it thinks is appropriate. In the case of -* errors, loadlib returns nil and two strings describing the error. -* The first string is supplied by the operating system; it should be -* informative and useful for error messages. The second string is "open", -* "init", or "absent" to identify the error and is meant to be used for -* making decisions without having to look into the first string (whose -* format is system-dependent). -* -* This module contains an implementation of loadlib for Unix systems that -* have dlfcn, an implementation for Windows, and a stub for other systems. -* See the list at the end of this file for some links to available -* implementations of dlfcn and interfaces to other native dynamic loaders -* on top of which loadlib could be implemented. -* -*/ - -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" - - -#undef LOADLIB - - -#ifdef USE_DLOPEN -#define LOADLIB -/* -* This is an implementation of loadlib based on the dlfcn interface. -* The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, -* NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least -* as an emulation layer on top of native functions. -*/ - -#include - -static int loadlib(lua_State *L) -{ - const char *path=luaL_checkstring(L,1); - const char *init=luaL_checkstring(L,2); - void *lib=dlopen(path,RTLD_NOW); - if (lib!=NULL) - { - lua_CFunction f=(lua_CFunction) dlsym(lib,init); - if (f!=NULL) - { - lua_pushlightuserdata(L,lib); - lua_pushcclosure(L,f,1); - return 1; - } - } - /* else return appropriate error messages */ - lua_pushnil(L); - lua_pushstring(L,dlerror()); - lua_pushstring(L,(lib!=NULL) ? "init" : "open"); - if (lib!=NULL) dlclose(lib); - return 3; -} - -#endif - - - -/* -** In Windows, default is to use dll; otherwise, default is not to use dll -*/ -#ifndef USE_DLL -#ifdef _WIN32 -#define USE_DLL 1 -#else -#define USE_DLL 0 -#endif -#endif - - -#if USE_DLL -#define LOADLIB -/* -* This is an implementation of loadlib for Windows using native functions. -*/ - -#include - -static void pusherror(lua_State *L) -{ - int error=GetLastError(); - char buffer[128]; - if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, - 0, error, 0, buffer, sizeof(buffer), 0)) - lua_pushstring(L,buffer); - else - lua_pushfstring(L,"system error %d\n",error); -} - -static int loadlib(lua_State *L) -{ - const char *path=luaL_checkstring(L,1); - const char *init=luaL_checkstring(L,2); - HINSTANCE lib=LoadLibrary(path); - if (lib!=NULL) - { - lua_CFunction f=(lua_CFunction) GetProcAddress(lib,init); - if (f!=NULL) - { - lua_pushlightuserdata(L,lib); - lua_pushcclosure(L,f,1); - return 1; - } - } - lua_pushnil(L); - pusherror(L); - lua_pushstring(L,(lib!=NULL) ? "init" : "open"); - if (lib!=NULL) FreeLibrary(lib); - return 3; -} - -#endif - - - -#ifndef LOADLIB -/* Fallback for other systems */ - -/* -** Those systems support dlopen, so they should have defined USE_DLOPEN. -** The default (no)implementation gives them a special error message. -*/ -#ifdef linux -#define LOADLIB -#endif - -#ifdef sun -#define LOADLIB -#endif - -#ifdef sgi -#define LOADLIB -#endif - -#ifdef BSD -#define LOADLIB -#endif - -#ifdef _WIN32 -#define LOADLIB -#endif - -#ifdef LOADLIB -#undef LOADLIB -#define LOADLIB "`loadlib' not installed (check your Lua configuration)" -#else -#define LOADLIB "`loadlib' not supported" -#endif - -static int loadlib(lua_State *L) -{ - lua_pushnil(L); - lua_pushliteral(L,LOADLIB); - lua_pushliteral(L,"absent"); - return 3; -} -#endif - -LUALIB_API int luaopen_loadlib (lua_State *L) -{ - lua_register(L,"loadlib",loadlib); - return 0; -} - -/* -* Here are some links to available implementations of dlfcn and -* interfaces to other native dynamic loaders on top of which loadlib -* could be implemented. Please send contributions and corrections to us. -* -* AIX -* Starting with AIX 4.2, dlfcn is included in the base OS. -* There is also an emulation package available. -* http://www.faqs.org/faqs/aix-faq/part4/section-21.html -* -* HPUX -* HPUX 11 has dlfcn. For HPUX 10 use shl_*. -* http://www.geda.seul.org/mailinglist/geda-dev37/msg00094.html -* http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html -* -* Macintosh, Windows -* http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html -* -* Mac OS X/Darwin -* http://www.opendarwin.org/projects/dlcompat/ -* -* GLIB has wrapper code for BeOS, OS2, Unix and Windows -* http://cvs.gnome.org/lxr/source/glib/gmodule/ -* -*/ diff --git a/!NotAdopted/SmartAutoReplier/lualib/lobject.c b/!NotAdopted/SmartAutoReplier/lualib/lobject.c deleted file mode 100644 index 9522b6e812..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lobject.c +++ /dev/null @@ -1,195 +0,0 @@ -/* -** $Id: lobject.c,v 1.97 2003/04/03 13:35:34 roberto Exp $ -** Some generic functions over Lua objects -** See Copyright Notice in lua.h -*/ - -#include -#include -#include -#include - -#define lobject_c - -#include "lua.h" - -#include "ldo.h" -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" -#include "lstring.h" -#include "lvm.h" - - -/* function to convert a string to a lua_Number */ -#ifndef lua_str2number -#define lua_str2number(s,p) strtod((s), (p)) -#endif - - -const TObject luaO_nilobject = {LUA_TNIL, {NULL}}; - - -/* -** converts an integer to a "floating point byte", represented as -** (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm) -*/ -int luaO_int2fb (unsigned int x) { - int m = 0; /* mantissa */ - while (x >= (1<<3)) { - x = (x+1) >> 1; - m++; - } - return (m << 3) | cast(int, x); -} - - -int luaO_log2 (unsigned int x) { - static const lu_byte log_8[255] = { - 0, - 1,1, - 2,2,2,2, - 3,3,3,3,3,3,3,3, - 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 - }; - if (x >= 0x00010000) { - if (x >= 0x01000000) return log_8[((x>>24) & 0xff) - 1]+24; - else return log_8[((x>>16) & 0xff) - 1]+16; - } - else { - if (x >= 0x00000100) return log_8[((x>>8) & 0xff) - 1]+8; - else if (x) return log_8[(x & 0xff) - 1]; - return -1; /* special `log' for 0 */ - } -} - - -int luaO_rawequalObj (const TObject *t1, const TObject *t2) { - if (ttype(t1) != ttype(t2)) return 0; - else switch (ttype(t1)) { - case LUA_TNIL: - return 1; - case LUA_TNUMBER: - return nvalue(t1) == nvalue(t2); - case LUA_TBOOLEAN: - return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ - case LUA_TLIGHTUSERDATA: - return pvalue(t1) == pvalue(t2); - default: - lua_assert(iscollectable(t1)); - return gcvalue(t1) == gcvalue(t2); - } -} - - -int luaO_str2d (const char *s, lua_Number *result) { - char *endptr; - lua_Number res = lua_str2number(s, &endptr); - if (endptr == s) return 0; /* no conversion */ - while (isspace((unsigned char)(*endptr))) endptr++; - if (*endptr != '\0') return 0; /* invalid trailing characters? */ - *result = res; - return 1; -} - - - -static void pushstr (lua_State *L, const char *str) { - setsvalue2s(L->top, luaS_new(L, str)); - incr_top(L); -} - - -/* this function handles only `%d', `%c', %f, and `%s' formats */ -const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { - int n = 1; - pushstr(L, ""); - for (;;) { - const char *e = strchr(fmt, '%'); - if (e == NULL) break; - setsvalue2s(L->top, luaS_newlstr(L, fmt, e-fmt)); - incr_top(L); - switch (*(e+1)) { - case 's': - pushstr(L, va_arg(argp, char *)); - break; - case 'c': { - char buff[2]; - buff[0] = cast(char, va_arg(argp, int)); - buff[1] = '\0'; - pushstr(L, buff); - break; - } - case 'd': - setnvalue(L->top, cast(lua_Number, va_arg(argp, int))); - incr_top(L); - break; - case 'f': - setnvalue(L->top, cast(lua_Number, va_arg(argp, l_uacNumber))); - incr_top(L); - break; - case '%': - pushstr(L, "%"); - break; - default: lua_assert(0); - } - n += 2; - fmt = e+2; - } - pushstr(L, fmt); - luaV_concat(L, n+1, L->top - L->base - 1); - L->top -= n; - return svalue(L->top - 1); -} - - -const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { - const char *msg; - va_list argp; - va_start(argp, fmt); - msg = luaO_pushvfstring(L, fmt, argp); - va_end(argp); - return msg; -} - - -void luaO_chunkid (char *out, const char *source, int bufflen) { - if (*source == '=') { - strncpy(out, source+1, bufflen); /* remove first char */ - out[bufflen-1] = '\0'; /* ensures null termination */ - } - else { /* out = "source", or "...source" */ - if (*source == '@') { - int l; - source++; /* skip the `@' */ - bufflen -= sizeof(" `...' "); - l = strlen(source); - strcpy(out, ""); - if (l>bufflen) { - source += (l-bufflen); /* get last part of file name */ - strcat(out, "..."); - } - strcat(out, source); - } - else { /* out = [string "string"] */ - int len = strcspn(source, "\n"); /* stop at first newline */ - bufflen -= sizeof(" [string \"...\"] "); - if (len > bufflen) len = bufflen; - strcpy(out, "[string \""); - if (source[len] != '\0') { /* must truncate? */ - strncat(out, source, len); - strcat(out, "..."); - } - else - strcat(out, source); - strcat(out, "\"]"); - } - } -} diff --git a/!NotAdopted/SmartAutoReplier/lualib/lobject.h b/!NotAdopted/SmartAutoReplier/lualib/lobject.h deleted file mode 100644 index 321a7e06c1..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lobject.h +++ /dev/null @@ -1,336 +0,0 @@ -/* -** $Id: lobject.h,v 1.159 2003/03/18 12:50:04 roberto Exp $ -** Type definitions for Lua objects -** See Copyright Notice in lua.h -*/ - -#ifndef lobject_h -#define lobject_h - - -#include "llimits.h" -#include "lua.h" - - -/* tags for values visible from Lua */ -#define NUM_TAGS LUA_TTHREAD - - -/* -** Extra tags for non-values -*/ -#define LUA_TPROTO (NUM_TAGS+1) -#define LUA_TUPVAL (NUM_TAGS+2) - - -/* -** Union of all collectable objects -*/ -typedef union GCObject GCObject; - - -/* -** Common Header for all collectable objects (in macro form, to be -** included in other objects) -*/ -#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked - - -/* -** Common header in struct form -*/ -typedef struct GCheader { - CommonHeader; -} GCheader; - - - - -/* -** Union of all Lua values -*/ -typedef union { - GCObject *gc; - void *p; - lua_Number n; - int b; -} Value; - - -/* -** Lua values (or `tagged objects') -*/ -typedef struct lua_TObject { - int tt; - Value value; -} TObject; - - -/* Macros to test type */ -#define ttisnil(o) (ttype(o) == LUA_TNIL) -#define ttisnumber(o) (ttype(o) == LUA_TNUMBER) -#define ttisstring(o) (ttype(o) == LUA_TSTRING) -#define ttistable(o) (ttype(o) == LUA_TTABLE) -#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) -#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) -#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) -#define ttisthread(o) (ttype(o) == LUA_TTHREAD) -#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) - -/* Macros to access values */ -#define ttype(o) ((o)->tt) -#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc) -#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) -#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n) -#define tsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts) -#define uvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u) -#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl) -#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h) -#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b) -#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th) - -#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) - -/* Macros to set values */ -#define setnvalue(obj,x) \ - { TObject *i_o=(obj); i_o->tt=LUA_TNUMBER; i_o->value.n=(x); } - -#define chgnvalue(obj,x) \ - check_exp(ttype(obj)==LUA_TNUMBER, (obj)->value.n=(x)) - -#define setpvalue(obj,x) \ - { TObject *i_o=(obj); i_o->tt=LUA_TLIGHTUSERDATA; i_o->value.p=(x); } - -#define setbvalue(obj,x) \ - { TObject *i_o=(obj); i_o->tt=LUA_TBOOLEAN; i_o->value.b=(x); } - -#define setsvalue(obj,x) \ - { TObject *i_o=(obj); i_o->tt=LUA_TSTRING; \ - i_o->value.gc=cast(GCObject *, (x)); \ - lua_assert(i_o->value.gc->gch.tt == LUA_TSTRING); } - -#define setuvalue(obj,x) \ - { TObject *i_o=(obj); i_o->tt=LUA_TUSERDATA; \ - i_o->value.gc=cast(GCObject *, (x)); \ - lua_assert(i_o->value.gc->gch.tt == LUA_TUSERDATA); } - -#define setthvalue(obj,x) \ - { TObject *i_o=(obj); i_o->tt=LUA_TTHREAD; \ - i_o->value.gc=cast(GCObject *, (x)); \ - lua_assert(i_o->value.gc->gch.tt == LUA_TTHREAD); } - -#define setclvalue(obj,x) \ - { TObject *i_o=(obj); i_o->tt=LUA_TFUNCTION; \ - i_o->value.gc=cast(GCObject *, (x)); \ - lua_assert(i_o->value.gc->gch.tt == LUA_TFUNCTION); } - -#define sethvalue(obj,x) \ - { TObject *i_o=(obj); i_o->tt=LUA_TTABLE; \ - i_o->value.gc=cast(GCObject *, (x)); \ - lua_assert(i_o->value.gc->gch.tt == LUA_TTABLE); } - -#define setnilvalue(obj) ((obj)->tt=LUA_TNIL) - - - -/* -** for internal debug only -*/ -#define checkconsistency(obj) \ - lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt)) - - -#define setobj(obj1,obj2) \ - { const TObject *o2=(obj2); TObject *o1=(obj1); \ - checkconsistency(o2); \ - o1->tt=o2->tt; o1->value = o2->value; } - - -/* -** different types of sets, according to destination -*/ - -/* from stack to (same) stack */ -#define setobjs2s setobj -/* to stack (not from same stack) */ -#define setobj2s setobj -#define setsvalue2s setsvalue -/* from table to same table */ -#define setobjt2t setobj -/* to table */ -#define setobj2t setobj -/* to new object */ -#define setobj2n setobj -#define setsvalue2n setsvalue - -#define setttype(obj, tt) (ttype(obj) = (tt)) - - -#define iscollectable(o) (ttype(o) >= LUA_TSTRING) - - - -typedef TObject *StkId; /* index to stack elements */ - - -/* -** String headers for string table -*/ -typedef union TString { - L_Umaxalign dummy; /* ensures maximum alignment for strings */ - struct { - CommonHeader; - lu_byte reserved; - lu_hash hash; - size_t len; - } tsv; -} TString; - - -#define getstr(ts) cast(const char *, (ts) + 1) -#define svalue(o) getstr(tsvalue(o)) - - - -typedef union Udata { - L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ - struct { - CommonHeader; - struct Table *metatable; - size_t len; - } uv; -} Udata; - - - - -/* -** Function Prototypes -*/ -typedef struct Proto { - CommonHeader; - TObject *k; /* constants used by the function */ - Instruction *code; - struct Proto **p; /* functions defined inside the function */ - int *lineinfo; /* map from opcodes to source lines */ - struct LocVar *locvars; /* information about local variables */ - TString **upvalues; /* upvalue names */ - TString *source; - int sizeupvalues; - int sizek; /* size of `k' */ - int sizecode; - int sizelineinfo; - int sizep; /* size of `p' */ - int sizelocvars; - int lineDefined; - GCObject *gclist; - lu_byte nups; /* number of upvalues */ - lu_byte numparams; - lu_byte is_vararg; - lu_byte maxstacksize; -} Proto; - - -typedef struct LocVar { - TString *varname; - int startpc; /* first point where variable is active */ - int endpc; /* first point where variable is dead */ -} LocVar; - - - -/* -** Upvalues -*/ - -typedef struct UpVal { - CommonHeader; - TObject *v; /* points to stack or to its own value */ - TObject value; /* the value (when closed) */ -} UpVal; - - -/* -** Closures -*/ - -#define ClosureHeader \ - CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist - -typedef struct CClosure { - ClosureHeader; - lua_CFunction f; - TObject upvalue[1]; -} CClosure; - - -typedef struct LClosure { - ClosureHeader; - struct Proto *p; - TObject g; /* global table for this closure */ - UpVal *upvals[1]; -} LClosure; - - -typedef union Closure { - CClosure c; - LClosure l; -} Closure; - - -#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC) -#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC) - - -/* -** Tables -*/ - -typedef struct Node { - TObject i_key; - TObject i_val; - struct Node *next; /* for chaining */ -} Node; - - -typedef struct Table { - CommonHeader; - lu_byte flags; /* 1<

lsizenode)) - - - -extern const TObject luaO_nilobject; - -int luaO_log2 (unsigned int x); -int luaO_int2fb (unsigned int x); -#define fb2int(x) (((x) & 7) << ((x) >> 3)) - -int luaO_rawequalObj (const TObject *t1, const TObject *t2); -int luaO_str2d (const char *s, lua_Number *result); - -const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp); -const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); -void luaO_chunkid (char *out, const char *source, int len); - - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/lopcodes.c b/!NotAdopted/SmartAutoReplier/lualib/lopcodes.c deleted file mode 100644 index 993e426d35..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lopcodes.c +++ /dev/null @@ -1,102 +0,0 @@ -/* -** $Id: lopcodes.c,v 1.22 2002/12/04 17:38:31 roberto Exp $ -** extracted automatically from lopcodes.h by mkprint.lua -** DO NOT EDIT -** See Copyright Notice in lua.h -*/ - - -#define lopcodes_c - -#include "lua.h" - -#include "lobject.h" -#include "lopcodes.h" - - -#ifdef LUA_OPNAMES - -const char *const luaP_opnames[] = { - "MOVE", - "LOADK", - "LOADBOOL", - "LOADNIL", - "GETUPVAL", - "GETGLOBAL", - "GETTABLE", - "SETGLOBAL", - "SETUPVAL", - "SETTABLE", - "NEWTABLE", - "SELF", - "ADD", - "SUB", - "MUL", - "DIV", - "POW", - "UNM", - "NOT", - "CONCAT", - "JMP", - "EQ", - "LT", - "LE", - "TEST", - "CALL", - "TAILCALL", - "RETURN", - "FORLOOP", - "TFORLOOP", - "TFORPREP", - "SETLIST", - "SETLISTO", - "CLOSE", - "CLOSURE" -}; - -#endif - -#define opmode(t,b,bk,ck,sa,k,m) (((t)<>1) /* `sBx' is signed */ -#else -#define MAXARG_Bx MAX_INT -#define MAXARG_sBx MAX_INT -#endif - - -#define MAXARG_A ((1<>POS_A)) -#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ - ((cast(Instruction, u)<>POS_B) & MASK1(SIZE_B,0))) -#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ - ((cast(Instruction, b)<>POS_C) & MASK1(SIZE_C,0))) -#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \ - ((cast(Instruction, b)<>POS_Bx) & MASK1(SIZE_Bx,0))) -#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \ - ((cast(Instruction, b)< C) then R(A) := R(B) else pc++ */ - -OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ -OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ -OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ - -OP_FORLOOP,/* A sBx R(A)+=R(A+2); if R(A) =) R(A)*/ -OP_CLOSURE/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ -} OpCode; - - -#define NUM_OPCODES (cast(int, OP_CLOSURE+1)) - - - -/*=========================================================================== - Notes: - (1) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, - and can be 0: OP_CALL then sets `top' to last_result+1, so - next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. - - (2) In OP_RETURN, if (B == 0) then return up to `top' - - (3) For comparisons, B specifies what conditions the test should accept. - - (4) All `skips' (pc++) assume that next instruction is a jump -===========================================================================*/ - - -/* -** masks for instruction properties -*/ -enum OpModeMask { - OpModeBreg = 2, /* B is a register */ - OpModeBrk, /* B is a register/constant */ - OpModeCrk, /* C is a register/constant */ - OpModesetA, /* instruction set register A */ - OpModeK, /* Bx is a constant */ - OpModeT /* operator is a test */ - -}; - - -extern const lu_byte luaP_opmodes[NUM_OPCODES]; - -#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) -#define testOpMode(m, b) (luaP_opmodes[m] & (1 << (b))) - - -#ifdef LUA_OPNAMES -extern const char *const luaP_opnames[]; /* opcode names */ -#endif - - - -/* number of list items to accumulate before a SETLIST instruction */ -/* (must be a power of 2) */ -#define LFIELDS_PER_FLUSH 32 - - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/lparser.c b/!NotAdopted/SmartAutoReplier/lualib/lparser.c deleted file mode 100644 index c1323ecd2a..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lparser.c +++ /dev/null @@ -1,1329 +0,0 @@ -/* -** $Id: lparser.c,v 1.208 2003/04/03 13:35:34 roberto Exp $ -** Lua Parser -** See Copyright Notice in lua.h -*/ - - -#include - -#define lparser_c - -#include "lua.h" - -#include "lcode.h" -#include "ldebug.h" -#include "lfunc.h" -#include "llex.h" -#include "lmem.h" -#include "lobject.h" -#include "lopcodes.h" -#include "lparser.h" -#include "lstate.h" -#include "lstring.h" - - - - -#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) - - -#define enterlevel(ls) if (++(ls)->nestlevel > LUA_MAXPARSERLEVEL) \ - luaX_syntaxerror(ls, "too many syntax levels"); -#define leavelevel(ls) ((ls)->nestlevel--) - - -/* -** nodes for block list (list of active blocks) -*/ -typedef struct BlockCnt { - struct BlockCnt *previous; /* chain */ - int breaklist; /* list of jumps out of this loop */ - int nactvar; /* # active local variables outside the breakable structure */ - int upval; /* true if some variable in the block is an upvalue */ - int isbreakable; /* true if `block' is a loop */ -} BlockCnt; - - - -/* -** prototypes for recursive non-terminal functions -*/ -static void chunk (LexState *ls); -static void expr (LexState *ls, expdesc *v); - - - -static void next (LexState *ls) { - ls->lastline = ls->linenumber; - if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ - ls->t = ls->lookahead; /* use this one */ - ls->lookahead.token = TK_EOS; /* and discharge it */ - } - else - ls->t.token = luaX_lex(ls, &ls->t.seminfo); /* read next token */ -} - - -static void lookahead (LexState *ls) { - lua_assert(ls->lookahead.token == TK_EOS); - ls->lookahead.token = luaX_lex(ls, &ls->lookahead.seminfo); -} - - -static void error_expected (LexState *ls, int token) { - luaX_syntaxerror(ls, - luaO_pushfstring(ls->L, "`%s' expected", luaX_token2str(ls, token))); -} - - -static int testnext (LexState *ls, int c) { - if (ls->t.token == c) { - next(ls); - return 1; - } - else return 0; -} - - -static void check (LexState *ls, int c) { - if (!testnext(ls, c)) - error_expected(ls, c); -} - - -#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } - - - -static void check_match (LexState *ls, int what, int who, int where) { - if (!testnext(ls, what)) { - if (where == ls->linenumber) - error_expected(ls, what); - else { - luaX_syntaxerror(ls, luaO_pushfstring(ls->L, - "`%s' expected (to close `%s' at line %d)", - luaX_token2str(ls, what), luaX_token2str(ls, who), where)); - } - } -} - - -static TString *str_checkname (LexState *ls) { - TString *ts; - check_condition(ls, (ls->t.token == TK_NAME), " expected"); - ts = ls->t.seminfo.ts; - next(ls); - return ts; -} - - -static void init_exp (expdesc *e, expkind k, int i) { - e->f = e->t = NO_JUMP; - e->k = k; - e->info = i; -} - - -static void codestring (LexState *ls, expdesc *e, TString *s) { - init_exp(e, VK, luaK_stringK(ls->fs, s)); -} - - -static void checkname(LexState *ls, expdesc *e) { - codestring(ls, e, str_checkname(ls)); -} - - -static int luaI_registerlocalvar (LexState *ls, TString *varname) { - FuncState *fs = ls->fs; - Proto *f = fs->f; - luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, - LocVar, MAX_INT, ""); - f->locvars[fs->nlocvars].varname = varname; - return fs->nlocvars++; -} - - -static void new_localvar (LexState *ls, TString *name, int n) { - FuncState *fs = ls->fs; - luaX_checklimit(ls, fs->nactvar+n+1, MAXVARS, "local variables"); - fs->actvar[fs->nactvar+n] = luaI_registerlocalvar(ls, name); -} - - -static void adjustlocalvars (LexState *ls, int nvars) { - FuncState *fs = ls->fs; - fs->nactvar += nvars; - for (; nvars; nvars--) { - getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; - } -} - - -static void removevars (LexState *ls, int tolevel) { - FuncState *fs = ls->fs; - while (fs->nactvar > tolevel) - getlocvar(fs, --fs->nactvar).endpc = fs->pc; -} - - -static void new_localvarstr (LexState *ls, const char *name, int n) { - new_localvar(ls, luaS_new(ls->L, name), n); -} - - -static void create_local (LexState *ls, const char *name) { - new_localvarstr(ls, name, 0); - adjustlocalvars(ls, 1); -} - - -static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { - int i; - Proto *f = fs->f; - for (i=0; inups; i++) { - if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) { - lua_assert(fs->f->upvalues[i] == name); - return i; - } - } - /* new one */ - luaX_checklimit(fs->ls, f->nups + 1, MAXUPVALUES, "upvalues"); - luaM_growvector(fs->L, fs->f->upvalues, f->nups, fs->f->sizeupvalues, - TString *, MAX_INT, ""); - fs->f->upvalues[f->nups] = name; - fs->upvalues[f->nups] = *v; - return f->nups++; -} - - -static int searchvar (FuncState *fs, TString *n) { - int i; - for (i=fs->nactvar-1; i >= 0; i--) { - if (n == getlocvar(fs, i).varname) - return i; - } - return -1; /* not found */ -} - - -static void markupval (FuncState *fs, int level) { - BlockCnt *bl = fs->bl; - while (bl && bl->nactvar > level) bl = bl->previous; - if (bl) bl->upval = 1; -} - - -static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { - if (fs == NULL) /* no more levels? */ - init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ - else { - int v = searchvar(fs, n); /* look up at current level */ - if (v >= 0) { - init_exp(var, VLOCAL, v); - if (!base) - markupval(fs, v); /* local will be used as an upval */ - } - else { /* not found at current level; try upper one */ - singlevaraux(fs->prev, n, var, 0); - if (var->k == VGLOBAL) { - if (base) - var->info = luaK_stringK(fs, n); /* info points to global name */ - } - else { /* LOCAL or UPVAL */ - var->info = indexupvalue(fs, n, var); - var->k = VUPVAL; /* upvalue in this level */ - } - } - } -} - - -static TString *singlevar (LexState *ls, expdesc *var, int base) { - TString *varname = str_checkname(ls); - singlevaraux(ls->fs, varname, var, base); - return varname; -} - - -static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { - FuncState *fs = ls->fs; - int extra = nvars - nexps; - if (e->k == VCALL) { - extra++; /* includes call itself */ - if (extra <= 0) extra = 0; - else luaK_reserveregs(fs, extra-1); - luaK_setcallreturns(fs, e, extra); /* call provides the difference */ - } - else { - if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ - if (extra > 0) { - int reg = fs->freereg; - luaK_reserveregs(fs, extra); - luaK_nil(fs, reg, extra); - } - } -} - - -static void code_params (LexState *ls, int nparams, int dots) { - FuncState *fs = ls->fs; - adjustlocalvars(ls, nparams); - luaX_checklimit(ls, fs->nactvar, MAXPARAMS, "parameters"); - fs->f->numparams = cast(lu_byte, fs->nactvar); - fs->f->is_vararg = cast(lu_byte, dots); - if (dots) - create_local(ls, "arg"); - luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ -} - - -static void enterblock (FuncState *fs, BlockCnt *bl, int isbreakable) { - bl->breaklist = NO_JUMP; - bl->isbreakable = isbreakable; - bl->nactvar = fs->nactvar; - bl->upval = 0; - bl->previous = fs->bl; - fs->bl = bl; - lua_assert(fs->freereg == fs->nactvar); -} - - -static void leaveblock (FuncState *fs) { - BlockCnt *bl = fs->bl; - fs->bl = bl->previous; - removevars(fs->ls, bl->nactvar); - if (bl->upval) - luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); - lua_assert(bl->nactvar == fs->nactvar); - fs->freereg = fs->nactvar; /* free registers */ - luaK_patchtohere(fs, bl->breaklist); -} - - -static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { - FuncState *fs = ls->fs; - Proto *f = fs->f; - int i; - luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, - MAXARG_Bx, "constant table overflow"); - f->p[fs->np++] = func->f; - init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); - for (i=0; if->nups; i++) { - OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; - luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); - } -} - - -static void open_func (LexState *ls, FuncState *fs) { - Proto *f = luaF_newproto(ls->L); - fs->f = f; - fs->prev = ls->fs; /* linked list of funcstates */ - fs->ls = ls; - fs->L = ls->L; - ls->fs = fs; - fs->pc = 0; - fs->lasttarget = 0; - fs->jpc = NO_JUMP; - fs->freereg = 0; - fs->nk = 0; - fs->h = luaH_new(ls->L, 0, 0); - fs->np = 0; - fs->nlocvars = 0; - fs->nactvar = 0; - fs->bl = NULL; - f->source = ls->source; - f->maxstacksize = 2; /* registers 0/1 are always valid */ -} - - -static void close_func (LexState *ls) { - lua_State *L = ls->L; - FuncState *fs = ls->fs; - Proto *f = fs->f; - removevars(ls, 0); - luaK_codeABC(fs, OP_RETURN, 0, 1, 0); /* final return */ - luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); - f->sizecode = fs->pc; - luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); - f->sizelineinfo = fs->pc; - luaM_reallocvector(L, f->k, f->sizek, fs->nk, TObject); - f->sizek = fs->nk; - luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); - f->sizep = fs->np; - luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); - f->sizelocvars = fs->nlocvars; - luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *); - f->sizeupvalues = f->nups; - lua_assert(luaG_checkcode(f)); - lua_assert(fs->bl == NULL); - ls->fs = fs->prev; -} - - -Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff) { - struct LexState lexstate; - struct FuncState funcstate; - lexstate.buff = buff; - lexstate.nestlevel = 0; - luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z))); - open_func(&lexstate, &funcstate); - next(&lexstate); /* read first token */ - chunk(&lexstate); - check_condition(&lexstate, (lexstate.t.token == TK_EOS), " expected"); - close_func(&lexstate); - lua_assert(funcstate.prev == NULL); - lua_assert(funcstate.f->nups == 0); - lua_assert(lexstate.nestlevel == 0); - return funcstate.f; -} - - - -/*============================================================*/ -/* GRAMMAR RULES */ -/*============================================================*/ - - -static void luaY_field (LexState *ls, expdesc *v) { - /* field -> ['.' | ':'] NAME */ - FuncState *fs = ls->fs; - expdesc key; - luaK_exp2anyreg(fs, v); - next(ls); /* skip the dot or colon */ - checkname(ls, &key); - luaK_indexed(fs, v, &key); -} - - -static void luaY_index (LexState *ls, expdesc *v) { - /* index -> '[' expr ']' */ - next(ls); /* skip the '[' */ - expr(ls, v); - luaK_exp2val(ls->fs, v); - check(ls, ']'); -} - - -/* -** {====================================================================== -** Rules for Constructors -** ======================================================================= -*/ - - -struct ConsControl { - expdesc v; /* last list item read */ - expdesc *t; /* table descriptor */ - int nh; /* total number of `record' elements */ - int na; /* total number of array elements */ - int tostore; /* number of array elements pending to be stored */ -}; - - -static void recfield (LexState *ls, struct ConsControl *cc) { - /* recfield -> (NAME | `['exp1`]') = exp1 */ - FuncState *fs = ls->fs; - int reg = ls->fs->freereg; - expdesc key, val; - if (ls->t.token == TK_NAME) { - luaX_checklimit(ls, cc->nh, MAX_INT, "items in a constructor"); - cc->nh++; - checkname(ls, &key); - } - else /* ls->t.token == '[' */ - luaY_index(ls, &key); - check(ls, '='); - luaK_exp2RK(fs, &key); - expr(ls, &val); - luaK_codeABC(fs, OP_SETTABLE, cc->t->info, luaK_exp2RK(fs, &key), - luaK_exp2RK(fs, &val)); - fs->freereg = reg; /* free registers */ -} - - -static void closelistfield (FuncState *fs, struct ConsControl *cc) { - if (cc->v.k == VVOID) return; /* there is no list item */ - luaK_exp2nextreg(fs, &cc->v); - cc->v.k = VVOID; - if (cc->tostore == LFIELDS_PER_FLUSH) { - luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1); /* flush */ - cc->tostore = 0; /* no more items pending */ - fs->freereg = cc->t->info + 1; /* free registers */ - } -} - - -static void lastlistfield (FuncState *fs, struct ConsControl *cc) { - if (cc->tostore == 0) return; - if (cc->v.k == VCALL) { - luaK_setcallreturns(fs, &cc->v, LUA_MULTRET); - luaK_codeABx(fs, OP_SETLISTO, cc->t->info, cc->na-1); - } - else { - if (cc->v.k != VVOID) - luaK_exp2nextreg(fs, &cc->v); - luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1); - } - fs->freereg = cc->t->info + 1; /* free registers */ -} - - -static void listfield (LexState *ls, struct ConsControl *cc) { - expr(ls, &cc->v); - luaX_checklimit(ls, cc->na, MAXARG_Bx, "items in a constructor"); - cc->na++; - cc->tostore++; -} - - -static void constructor (LexState *ls, expdesc *t) { - /* constructor -> ?? */ - FuncState *fs = ls->fs; - int line = ls->linenumber; - int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); - struct ConsControl cc; - cc.na = cc.nh = cc.tostore = 0; - cc.t = t; - init_exp(t, VRELOCABLE, pc); - init_exp(&cc.v, VVOID, 0); /* no value (yet) */ - luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ - check(ls, '{'); - do { - lua_assert(cc.v.k == VVOID || cc.tostore > 0); - testnext(ls, ';'); /* compatibility only */ - if (ls->t.token == '}') break; - closelistfield(fs, &cc); - switch(ls->t.token) { - case TK_NAME: { /* may be listfields or recfields */ - lookahead(ls); - if (ls->lookahead.token != '=') /* expression? */ - listfield(ls, &cc); - else - recfield(ls, &cc); - break; - } - case '[': { /* constructor_item -> recfield */ - recfield(ls, &cc); - break; - } - default: { /* constructor_part -> listfield */ - listfield(ls, &cc); - break; - } - } - } while (testnext(ls, ',') || testnext(ls, ';')); - check_match(ls, '}', '{', line); - lastlistfield(fs, &cc); - SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ - SETARG_C(fs->f->code[pc], luaO_log2(cc.nh)+1); /* set initial table size */ -} - -/* }====================================================================== */ - - - -static void parlist (LexState *ls) { - /* parlist -> [ param { `,' param } ] */ - int nparams = 0; - int dots = 0; - if (ls->t.token != ')') { /* is `parlist' not empty? */ - do { - switch (ls->t.token) { - case TK_DOTS: dots = 1; next(ls); break; - case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break; - default: luaX_syntaxerror(ls, " or `...' expected"); - } - } while (!dots && testnext(ls, ',')); - } - code_params(ls, nparams, dots); -} - - -static void body (LexState *ls, expdesc *e, int needself, int line) { - /* body -> `(' parlist `)' chunk END */ - FuncState new_fs; - open_func(ls, &new_fs); - new_fs.f->lineDefined = line; - check(ls, '('); - if (needself) - create_local(ls, "self"); - parlist(ls); - check(ls, ')'); - chunk(ls); - check_match(ls, TK_END, TK_FUNCTION, line); - close_func(ls); - pushclosure(ls, &new_fs, e); -} - - -static int explist1 (LexState *ls, expdesc *v) { - /* explist1 -> expr { `,' expr } */ - int n = 1; /* at least one expression */ - expr(ls, v); - while (testnext(ls, ',')) { - luaK_exp2nextreg(ls->fs, v); - expr(ls, v); - n++; - } - return n; -} - - -static void funcargs (LexState *ls, expdesc *f) { - FuncState *fs = ls->fs; - expdesc args; - int base, nparams; - int line = ls->linenumber; - switch (ls->t.token) { - case '(': { /* funcargs -> `(' [ explist1 ] `)' */ - if (line != ls->lastline) - luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)"); - next(ls); - if (ls->t.token == ')') /* arg list is empty? */ - args.k = VVOID; - else { - explist1(ls, &args); - luaK_setcallreturns(fs, &args, LUA_MULTRET); - } - check_match(ls, ')', '(', line); - break; - } - case '{': { /* funcargs -> constructor */ - constructor(ls, &args); - break; - } - case TK_STRING: { /* funcargs -> STRING */ - codestring(ls, &args, ls->t.seminfo.ts); - next(ls); /* must use `seminfo' before `next' */ - break; - } - default: { - luaX_syntaxerror(ls, "function arguments expected"); - return; - } - } - lua_assert(f->k == VNONRELOC); - base = f->info; /* base register for call */ - if (args.k == VCALL) - nparams = LUA_MULTRET; /* open call */ - else { - if (args.k != VVOID) - luaK_exp2nextreg(fs, &args); /* close last argument */ - nparams = fs->freereg - (base+1); - } - init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); - luaK_fixline(fs, line); - fs->freereg = base+1; /* call remove function and arguments and leaves - (unless changed) one result */ -} - - - - -/* -** {====================================================================== -** Expression parsing -** ======================================================================= -*/ - - -static void prefixexp (LexState *ls, expdesc *v) { - /* prefixexp -> NAME | '(' expr ')' */ - switch (ls->t.token) { - case '(': { - int line = ls->linenumber; - next(ls); - expr(ls, v); - check_match(ls, ')', '(', line); - luaK_dischargevars(ls->fs, v); - return; - } - case TK_NAME: { - singlevar(ls, v, 1); - return; - } -#ifdef LUA_COMPATUPSYNTAX - case '%': { /* for compatibility only */ - TString *varname; - int line = ls->linenumber; - next(ls); /* skip `%' */ - varname = singlevar(ls, v, 1); - if (v->k != VUPVAL) - luaX_errorline(ls, "global upvalues are obsolete", - getstr(varname), line); - return; - } -#endif - default: { - luaX_syntaxerror(ls, "unexpected symbol"); - return; - } - } -} - - -static void primaryexp (LexState *ls, expdesc *v) { - /* primaryexp -> - prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ - FuncState *fs = ls->fs; - prefixexp(ls, v); - for (;;) { - switch (ls->t.token) { - case '.': { /* field */ - luaY_field(ls, v); - break; - } - case '[': { /* `[' exp1 `]' */ - expdesc key; - luaK_exp2anyreg(fs, v); - luaY_index(ls, &key); - luaK_indexed(fs, v, &key); - break; - } - case ':': { /* `:' NAME funcargs */ - expdesc key; - next(ls); - checkname(ls, &key); - luaK_self(fs, v, &key); - funcargs(ls, v); - break; - } - case '(': case TK_STRING: case '{': { /* funcargs */ - luaK_exp2nextreg(fs, v); - funcargs(ls, v); - break; - } - default: return; - } - } -} - - -static void simpleexp (LexState *ls, expdesc *v) { - /* simpleexp -> NUMBER | STRING | NIL | constructor | FUNCTION body - | primaryexp */ - switch (ls->t.token) { - case TK_NUMBER: { - init_exp(v, VK, luaK_numberK(ls->fs, ls->t.seminfo.r)); - next(ls); /* must use `seminfo' before `next' */ - break; - } - case TK_STRING: { - codestring(ls, v, ls->t.seminfo.ts); - next(ls); /* must use `seminfo' before `next' */ - break; - } - case TK_NIL: { - init_exp(v, VNIL, 0); - next(ls); - break; - } - case TK_TRUE: { - init_exp(v, VTRUE, 0); - next(ls); - break; - } - case TK_FALSE: { - init_exp(v, VFALSE, 0); - next(ls); - break; - } - case '{': { /* constructor */ - constructor(ls, v); - break; - } - case TK_FUNCTION: { - next(ls); - body(ls, v, 0, ls->linenumber); - break; - } - default: { - primaryexp(ls, v); - break; - } - } -} - - -static UnOpr getunopr (int op) { - switch (op) { - case TK_NOT: return OPR_NOT; - case '-': return OPR_MINUS; - default: return OPR_NOUNOPR; - } -} - - -static BinOpr getbinopr (int op) { - switch (op) { - case '+': return OPR_ADD; - case '-': return OPR_SUB; - case '*': return OPR_MULT; - case '/': return OPR_DIV; - case '^': return OPR_POW; - case TK_CONCAT: return OPR_CONCAT; - case TK_NE: return OPR_NE; - case TK_EQ: return OPR_EQ; - case '<': return OPR_LT; - case TK_LE: return OPR_LE; - case '>': return OPR_GT; - case TK_GE: return OPR_GE; - case TK_AND: return OPR_AND; - case TK_OR: return OPR_OR; - default: return OPR_NOBINOPR; - } -} - - -static const struct { - lu_byte left; /* left priority for each binary operator */ - lu_byte right; /* right priority */ -} priority[] = { /* ORDER OPR */ - {6, 6}, {6, 6}, {7, 7}, {7, 7}, /* arithmetic */ - {10, 9}, {5, 4}, /* power and concat (right associative) */ - {3, 3}, {3, 3}, /* equality */ - {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ - {2, 2}, {1, 1} /* logical (and/or) */ -}; - -#define UNARY_PRIORITY 8 /* priority for unary operators */ - - -/* -** subexpr -> (simplexep | unop subexpr) { binop subexpr } -** where `binop' is any binary operator with a priority higher than `limit' -*/ -static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { - BinOpr op; - UnOpr uop; - enterlevel(ls); - uop = getunopr(ls->t.token); - if (uop != OPR_NOUNOPR) { - next(ls); - subexpr(ls, v, UNARY_PRIORITY); - luaK_prefix(ls->fs, uop, v); - } - else simpleexp(ls, v); - /* expand while operators have priorities higher than `limit' */ - op = getbinopr(ls->t.token); - while (op != OPR_NOBINOPR && cast(int, priority[op].left) > limit) { - expdesc v2; - BinOpr nextop; - next(ls); - luaK_infix(ls->fs, op, v); - /* read sub-expression with higher priority */ - nextop = subexpr(ls, &v2, cast(int, priority[op].right)); - luaK_posfix(ls->fs, op, v, &v2); - op = nextop; - } - leavelevel(ls); - return op; /* return first untreated operator */ -} - - -static void expr (LexState *ls, expdesc *v) { - subexpr(ls, v, -1); -} - -/* }==================================================================== */ - - - -/* -** {====================================================================== -** Rules for Statements -** ======================================================================= -*/ - - -static int block_follow (int token) { - switch (token) { - case TK_ELSE: case TK_ELSEIF: case TK_END: - case TK_UNTIL: case TK_EOS: - return 1; - default: return 0; - } -} - - -static void block (LexState *ls) { - /* block -> chunk */ - FuncState *fs = ls->fs; - BlockCnt bl; - enterblock(fs, &bl, 0); - chunk(ls); - lua_assert(bl.breaklist == NO_JUMP); - leaveblock(fs); -} - - -/* -** structure to chain all variables in the left-hand side of an -** assignment -*/ -struct LHS_assign { - struct LHS_assign *prev; - expdesc v; /* variable (global, local, upvalue, or indexed) */ -}; - - -/* -** check whether, in an assignment to a local variable, the local variable -** is needed in a previous assignment (to a table). If so, save original -** local value in a safe place and use this safe copy in the previous -** assignment. -*/ -static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { - FuncState *fs = ls->fs; - int extra = fs->freereg; /* eventual position to save local variable */ - int conflict = 0; - for (; lh; lh = lh->prev) { - if (lh->v.k == VINDEXED) { - if (lh->v.info == v->info) { /* conflict? */ - conflict = 1; - lh->v.info = extra; /* previous assignment will use safe copy */ - } - if (lh->v.aux == v->info) { /* conflict? */ - conflict = 1; - lh->v.aux = extra; /* previous assignment will use safe copy */ - } - } - } - if (conflict) { - luaK_codeABC(fs, OP_MOVE, fs->freereg, v->info, 0); /* make copy */ - luaK_reserveregs(fs, 1); - } -} - - -static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { - expdesc e; - check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, - "syntax error"); - if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ - struct LHS_assign nv; - nv.prev = lh; - primaryexp(ls, &nv.v); - if (nv.v.k == VLOCAL) - check_conflict(ls, lh, &nv.v); - assignment(ls, &nv, nvars+1); - } - else { /* assignment -> `=' explist1 */ - int nexps; - check(ls, '='); - nexps = explist1(ls, &e); - if (nexps != nvars) { - adjust_assign(ls, nvars, nexps, &e); - if (nexps > nvars) - ls->fs->freereg -= nexps - nvars; /* remove extra values */ - } - else { - luaK_setcallreturns(ls->fs, &e, 1); /* close last expression */ - luaK_storevar(ls->fs, &lh->v, &e); - return; /* avoid default */ - } - } - init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ - luaK_storevar(ls->fs, &lh->v, &e); -} - - -static void cond (LexState *ls, expdesc *v) { - /* cond -> exp */ - expr(ls, v); /* read condition */ - if (v->k == VNIL) v->k = VFALSE; /* `falses' are all equal here */ - luaK_goiftrue(ls->fs, v); - luaK_patchtohere(ls->fs, v->t); -} - - -/* -** The while statement optimizes its code by coding the condition -** after its body (and thus avoiding one jump in the loop). -*/ - -/* -** maximum size of expressions for optimizing `while' code -*/ -#ifndef MAXEXPWHILE -#define MAXEXPWHILE 100 -#endif - -/* -** the call `luaK_goiffalse' may grow the size of an expression by -** at most this: -*/ -#define EXTRAEXP 5 - -static void whilestat (LexState *ls, int line) { - /* whilestat -> WHILE cond DO block END */ - Instruction codeexp[MAXEXPWHILE + EXTRAEXP]; - int lineexp; - int i; - int sizeexp; - FuncState *fs = ls->fs; - int whileinit, blockinit, expinit; - expdesc v; - BlockCnt bl; - next(ls); /* skip WHILE */ - whileinit = luaK_jump(fs); /* jump to condition (which will be moved) */ - expinit = luaK_getlabel(fs); - expr(ls, &v); /* parse condition */ - if (v.k == VK) v.k = VTRUE; /* `trues' are all equal here */ - lineexp = ls->linenumber; - luaK_goiffalse(fs, &v); - luaK_concat(fs, &v.f, fs->jpc); - fs->jpc = NO_JUMP; - sizeexp = fs->pc - expinit; /* size of expression code */ - if (sizeexp > MAXEXPWHILE) - luaX_syntaxerror(ls, "`while' condition too complex"); - for (i = 0; i < sizeexp; i++) /* save `exp' code */ - codeexp[i] = fs->f->code[expinit + i]; - fs->pc = expinit; /* remove `exp' code */ - enterblock(fs, &bl, 1); - check(ls, TK_DO); - blockinit = luaK_getlabel(fs); - block(ls); - luaK_patchtohere(fs, whileinit); /* initial jump jumps to here */ - /* move `exp' back to code */ - if (v.t != NO_JUMP) v.t += fs->pc - expinit; - if (v.f != NO_JUMP) v.f += fs->pc - expinit; - for (i=0; i REPEAT block UNTIL cond */ - FuncState *fs = ls->fs; - int repeat_init = luaK_getlabel(fs); - expdesc v; - BlockCnt bl; - enterblock(fs, &bl, 1); - next(ls); - block(ls); - check_match(ls, TK_UNTIL, TK_REPEAT, line); - cond(ls, &v); - luaK_patchlist(fs, v.f, repeat_init); - leaveblock(fs); -} - - -static int exp1 (LexState *ls) { - expdesc e; - int k; - expr(ls, &e); - k = e.k; - luaK_exp2nextreg(ls->fs, &e); - return k; -} - - -static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { - BlockCnt bl; - FuncState *fs = ls->fs; - int prep, endfor; - adjustlocalvars(ls, nvars); /* scope for all variables */ - check(ls, TK_DO); - enterblock(fs, &bl, 1); /* loop block */ - prep = luaK_getlabel(fs); - block(ls); - luaK_patchtohere(fs, prep-1); - endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : - luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3); - luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ - luaK_patchlist(fs, (isnum) ? endfor : luaK_jump(fs), prep); - leaveblock(fs); -} - - -static void fornum (LexState *ls, TString *varname, int line) { - /* fornum -> NAME = exp1,exp1[,exp1] DO body */ - FuncState *fs = ls->fs; - int base = fs->freereg; - new_localvar(ls, varname, 0); - new_localvarstr(ls, "(for limit)", 1); - new_localvarstr(ls, "(for step)", 2); - check(ls, '='); - exp1(ls); /* initial value */ - check(ls, ','); - exp1(ls); /* limit */ - if (testnext(ls, ',')) - exp1(ls); /* optional step */ - else { /* default step = 1 */ - luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); - luaK_reserveregs(fs, 1); - } - luaK_codeABC(fs, OP_SUB, fs->freereg - 3, fs->freereg - 3, fs->freereg - 1); - luaK_jump(fs); - forbody(ls, base, line, 3, 1); -} - - -static void forlist (LexState *ls, TString *indexname) { - /* forlist -> NAME {,NAME} IN explist1 DO body */ - FuncState *fs = ls->fs; - expdesc e; - int nvars = 0; - int line; - int base = fs->freereg; - new_localvarstr(ls, "(for generator)", nvars++); - new_localvarstr(ls, "(for state)", nvars++); - new_localvar(ls, indexname, nvars++); - while (testnext(ls, ',')) - new_localvar(ls, str_checkname(ls), nvars++); - check(ls, TK_IN); - line = ls->linenumber; - adjust_assign(ls, nvars, explist1(ls, &e), &e); - luaK_checkstack(fs, 3); /* extra space to call generator */ - luaK_codeAsBx(fs, OP_TFORPREP, base, NO_JUMP); - forbody(ls, base, line, nvars, 0); -} - - -static void forstat (LexState *ls, int line) { - /* forstat -> fornum | forlist */ - FuncState *fs = ls->fs; - TString *varname; - BlockCnt bl; - enterblock(fs, &bl, 0); /* block to control variable scope */ - next(ls); /* skip `for' */ - varname = str_checkname(ls); /* first variable name */ - switch (ls->t.token) { - case '=': fornum(ls, varname, line); break; - case ',': case TK_IN: forlist(ls, varname); break; - default: luaX_syntaxerror(ls, "`=' or `in' expected"); - } - check_match(ls, TK_END, TK_FOR, line); - leaveblock(fs); -} - - -static void test_then_block (LexState *ls, expdesc *v) { - /* test_then_block -> [IF | ELSEIF] cond THEN block */ - next(ls); /* skip IF or ELSEIF */ - cond(ls, v); - check(ls, TK_THEN); - block(ls); /* `then' part */ -} - - -static void ifstat (LexState *ls, int line) { - /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ - FuncState *fs = ls->fs; - expdesc v; - int escapelist = NO_JUMP; - test_then_block(ls, &v); /* IF cond THEN block */ - while (ls->t.token == TK_ELSEIF) { - luaK_concat(fs, &escapelist, luaK_jump(fs)); - luaK_patchtohere(fs, v.f); - test_then_block(ls, &v); /* ELSEIF cond THEN block */ - } - if (ls->t.token == TK_ELSE) { - luaK_concat(fs, &escapelist, luaK_jump(fs)); - luaK_patchtohere(fs, v.f); - next(ls); /* skip ELSE (after patch, for correct line info) */ - block(ls); /* `else' part */ - } - else - luaK_concat(fs, &escapelist, v.f); - luaK_patchtohere(fs, escapelist); - check_match(ls, TK_END, TK_IF, line); -} - - -static void localfunc (LexState *ls) { - expdesc v, b; - new_localvar(ls, str_checkname(ls), 0); - init_exp(&v, VLOCAL, ls->fs->freereg++); - adjustlocalvars(ls, 1); - body(ls, &b, 0, ls->linenumber); - luaK_storevar(ls->fs, &v, &b); -} - - -static void localstat (LexState *ls) { - /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ - int nvars = 0; - int nexps; - expdesc e; - do { - new_localvar(ls, str_checkname(ls), nvars++); - } while (testnext(ls, ',')); - if (testnext(ls, '=')) - nexps = explist1(ls, &e); - else { - e.k = VVOID; - nexps = 0; - } - adjust_assign(ls, nvars, nexps, &e); - adjustlocalvars(ls, nvars); -} - - -static int funcname (LexState *ls, expdesc *v) { - /* funcname -> NAME {field} [`:' NAME] */ - int needself = 0; - singlevar(ls, v, 1); - while (ls->t.token == '.') - luaY_field(ls, v); - if (ls->t.token == ':') { - needself = 1; - luaY_field(ls, v); - } - return needself; -} - - -static void funcstat (LexState *ls, int line) { - /* funcstat -> FUNCTION funcname body */ - int needself; - expdesc v, b; - next(ls); /* skip FUNCTION */ - needself = funcname(ls, &v); - body(ls, &b, needself, line); - luaK_storevar(ls->fs, &v, &b); - luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ -} - - -static void exprstat (LexState *ls) { - /* stat -> func | assignment */ - FuncState *fs = ls->fs; - struct LHS_assign v; - primaryexp(ls, &v.v); - if (v.v.k == VCALL) { /* stat -> func */ - luaK_setcallreturns(fs, &v.v, 0); /* call statement uses no results */ - } - else { /* stat -> assignment */ - v.prev = NULL; - assignment(ls, &v, 1); - } -} - - -static void retstat (LexState *ls) { - /* stat -> RETURN explist */ - FuncState *fs = ls->fs; - expdesc e; - int first, nret; /* registers with returned values */ - next(ls); /* skip RETURN */ - if (block_follow(ls->t.token) || ls->t.token == ';') - first = nret = 0; /* return no values */ - else { - nret = explist1(ls, &e); /* optional return values */ - if (e.k == VCALL) { - luaK_setcallreturns(fs, &e, LUA_MULTRET); - if (nret == 1) { /* tail call? */ - SET_OPCODE(getcode(fs,&e), OP_TAILCALL); - lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); - } - first = fs->nactvar; - nret = LUA_MULTRET; /* return all values */ - } - else { - if (nret == 1) /* only one single value? */ - first = luaK_exp2anyreg(fs, &e); - else { - luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ - first = fs->nactvar; /* return all `active' values */ - lua_assert(nret == fs->freereg - first); - } - } - } - luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); -} - - -static void breakstat (LexState *ls) { - /* stat -> BREAK [NAME] */ - FuncState *fs = ls->fs; - BlockCnt *bl = fs->bl; - int upval = 0; - next(ls); /* skip BREAK */ - while (bl && !bl->isbreakable) { - upval |= bl->upval; - bl = bl->previous; - } - if (!bl) - luaX_syntaxerror(ls, "no loop to break"); - if (upval) - luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); - luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); -} - - -static int statement (LexState *ls) { - int line = ls->linenumber; /* may be needed for error messages */ - switch (ls->t.token) { - case TK_IF: { /* stat -> ifstat */ - ifstat(ls, line); - return 0; - } - case TK_WHILE: { /* stat -> whilestat */ - whilestat(ls, line); - return 0; - } - case TK_DO: { /* stat -> DO block END */ - next(ls); /* skip DO */ - block(ls); - check_match(ls, TK_END, TK_DO, line); - return 0; - } - case TK_FOR: { /* stat -> forstat */ - forstat(ls, line); - return 0; - } - case TK_REPEAT: { /* stat -> repeatstat */ - repeatstat(ls, line); - return 0; - } - case TK_FUNCTION: { - funcstat(ls, line); /* stat -> funcstat */ - return 0; - } - case TK_LOCAL: { /* stat -> localstat */ - next(ls); /* skip LOCAL */ - if (testnext(ls, TK_FUNCTION)) /* local function? */ - localfunc(ls); - else - localstat(ls); - return 0; - } - case TK_RETURN: { /* stat -> retstat */ - retstat(ls); - return 1; /* must be last statement */ - } - case TK_BREAK: { /* stat -> breakstat */ - breakstat(ls); - return 1; /* must be last statement */ - } - default: { - exprstat(ls); - return 0; /* to avoid warnings */ - } - } -} - - -static void chunk (LexState *ls) { - /* chunk -> { stat [`;'] } */ - int islast = 0; - enterlevel(ls); - while (!islast && !block_follow(ls->t.token)) { - islast = statement(ls); - testnext(ls, ';'); - lua_assert(ls->fs->freereg >= ls->fs->nactvar); - ls->fs->freereg = ls->fs->nactvar; /* free registers */ - } - leavelevel(ls); -} - -/* }====================================================================== */ diff --git a/!NotAdopted/SmartAutoReplier/lualib/lparser.h b/!NotAdopted/SmartAutoReplier/lualib/lparser.h deleted file mode 100644 index d6aaaf0e7d..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lparser.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -** $Id: lparser.h,v 1.47 2003/02/11 10:46:24 roberto Exp $ -** Lua Parser -** See Copyright Notice in lua.h -*/ - -#ifndef lparser_h -#define lparser_h - -#include "llimits.h" -#include "lobject.h" -#include "ltable.h" -#include "lzio.h" - - -/* -** Expression descriptor -*/ - -typedef enum { - VVOID, /* no value */ - VNIL, - VTRUE, - VFALSE, - VK, /* info = index of constant in `k' */ - VLOCAL, /* info = local register */ - VUPVAL, /* info = index of upvalue in `upvalues' */ - VGLOBAL, /* info = index of table; aux = index of global name in `k' */ - VINDEXED, /* info = table register; aux = index register (or `k') */ - VJMP, /* info = instruction pc */ - VRELOCABLE, /* info = instruction pc */ - VNONRELOC, /* info = result register */ - VCALL /* info = result register */ -} expkind; - -typedef struct expdesc { - expkind k; - int info, aux; - int t; /* patch list of `exit when true' */ - int f; /* patch list of `exit when false' */ -} expdesc; - - -struct BlockCnt; /* defined in lparser.c */ - - -/* state needed to generate code for a given function */ -typedef struct FuncState { - Proto *f; /* current function header */ - Table *h; /* table to find (and reuse) elements in `k' */ - struct FuncState *prev; /* enclosing function */ - struct LexState *ls; /* lexical state */ - struct lua_State *L; /* copy of the Lua state */ - struct BlockCnt *bl; /* chain of current blocks */ - int pc; /* next position to code (equivalent to `ncode') */ - int lasttarget; /* `pc' of last `jump target' */ - int jpc; /* list of pending jumps to `pc' */ - int freereg; /* first free register */ - int nk; /* number of elements in `k' */ - int np; /* number of elements in `p' */ - int nlocvars; /* number of elements in `locvars' */ - int nactvar; /* number of active local variables */ - expdesc upvalues[MAXUPVALUES]; /* upvalues */ - int actvar[MAXVARS]; /* declared-variable stack */ -} FuncState; - - -Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff); - - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/lstate.c b/!NotAdopted/SmartAutoReplier/lualib/lstate.c deleted file mode 100644 index b593658def..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lstate.c +++ /dev/null @@ -1,220 +0,0 @@ -/* -** $Id: lstate.c,v 1.123 2003/04/03 13:35:34 roberto Exp $ -** Global State -** See Copyright Notice in lua.h -*/ - - -#include - -#define lstate_c - -#include "lua.h" - -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "lgc.h" -#include "llex.h" -#include "lmem.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "ltm.h" - - -/* -** macro to allow the inclusion of user information in Lua state -*/ -#ifndef LUA_USERSTATE -#define EXTRASPACE 0 -#else -union UEXTRASPACE {L_Umaxalign a; LUA_USERSTATE b;}; -#define EXTRASPACE (sizeof(union UEXTRASPACE)) -#endif - - - -/* -** you can change this function through the official API: -** call `lua_setpanicf' -*/ -static int default_panic (lua_State *L) { - UNUSED(L); - return 0; -} - - -static lua_State *mallocstate (lua_State *L) { - lu_byte *block = (lu_byte *)luaM_malloc(L, sizeof(lua_State) + EXTRASPACE); - if (block == NULL) return NULL; - else { - block += EXTRASPACE; - return cast(lua_State *, block); - } -} - - -static void freestate (lua_State *L, lua_State *L1) { - luaM_free(L, cast(lu_byte *, L1) - EXTRASPACE, - sizeof(lua_State) + EXTRASPACE); -} - - -static void stack_init (lua_State *L1, lua_State *L) { - L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TObject); - L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; - L1->top = L1->stack; - L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; - L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); - L1->ci = L1->base_ci; - L1->ci->state = CI_C; /* not a Lua function */ - setnilvalue(L1->top++); /* `function' entry for this `ci' */ - L1->base = L1->ci->base = L1->top; - L1->ci->top = L1->top + LUA_MINSTACK; - L1->size_ci = BASIC_CI_SIZE; - L1->end_ci = L1->base_ci + L1->size_ci; -} - - -static void freestack (lua_State *L, lua_State *L1) { - luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); - luaM_freearray(L, L1->stack, L1->stacksize, TObject); -} - - -/* -** open parts that may cause memory-allocation errors -*/ -static void f_luaopen (lua_State *L, void *ud) { - /* create a new global state */ - global_State *g = luaM_new(NULL, global_State); - UNUSED(ud); - if (g == NULL) luaD_throw(L, LUA_ERRMEM); - L->l_G = g; - g->mainthread = L; - g->GCthreshold = 0; /* mark it as unfinished state */ - g->strt.size = 0; - g->strt.nuse = 0; - g->strt.hash = NULL; - setnilvalue(defaultmeta(L)); - setnilvalue(registry(L)); - luaZ_initbuffer(L, &g->buff); - g->panic = default_panic; - g->rootgc = NULL; - g->rootudata = NULL; - g->tmudata = NULL; - setnilvalue(gkey(g->dummynode)); - setnilvalue(gval(g->dummynode)); - g->dummynode->next = NULL; - g->nblocks = sizeof(lua_State) + sizeof(global_State); - stack_init(L, L); /* init stack */ - /* create default meta table with a dummy table, and then close the loop */ - defaultmeta(L)->tt = LUA_TTABLE; - sethvalue(defaultmeta(L), luaH_new(L, 0, 0)); - hvalue(defaultmeta(L))->metatable = hvalue(defaultmeta(L)); - sethvalue(gt(L), luaH_new(L, 0, 4)); /* table of globals */ - sethvalue(registry(L), luaH_new(L, 4, 4)); /* registry */ - luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ - luaT_init(L); - luaX_init(L); - luaS_fix(luaS_newliteral(L, MEMERRMSG)); - g->GCthreshold = 4*G(L)->nblocks; -} - - -static void preinit_state (lua_State *L) { - L->stack = NULL; - L->stacksize = 0; - L->errorJmp = NULL; - L->hook = NULL; - L->hookmask = L->hookinit = 0; - L->basehookcount = 0; - L->allowhook = 1; - resethookcount(L); - L->openupval = NULL; - L->size_ci = 0; - L->nCcalls = 0; - L->base_ci = L->ci = NULL; - L->errfunc = 0; - setnilvalue(gt(L)); -} - - -static void close_state (lua_State *L) { - luaF_close(L, L->stack); /* close all upvalues for this thread */ - if (G(L)) { /* close global state */ - luaC_sweep(L, 1); /* collect all elements */ - lua_assert(G(L)->rootgc == NULL); - lua_assert(G(L)->rootudata == NULL); - luaS_freeall(L); - luaZ_freebuffer(L, &G(L)->buff); - } - freestack(L, L); - if (G(L)) { - lua_assert(G(L)->nblocks == sizeof(lua_State) + sizeof(global_State)); - luaM_freelem(NULL, G(L)); - } - freestate(NULL, L); -} - - -lua_State *luaE_newthread (lua_State *L) { - lua_State *L1 = mallocstate(L); - luaC_link(L, valtogco(L1), LUA_TTHREAD); - preinit_state(L1); - L1->l_G = L->l_G; - stack_init(L1, L); /* init stack */ - setobj2n(gt(L1), gt(L)); /* share table of globals */ - return L1; -} - - -void luaE_freethread (lua_State *L, lua_State *L1) { - luaF_close(L1, L1->stack); /* close all upvalues for this thread */ - lua_assert(L1->openupval == NULL); - freestack(L, L1); - freestate(L, L1); -} - - -LUA_API lua_State *lua_open (void) { - lua_State *L = mallocstate(NULL); - if (L) { /* allocation OK? */ - L->tt = LUA_TTHREAD; - L->marked = 0; - L->next = L->gclist = NULL; - preinit_state(L); - L->l_G = NULL; - if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { - /* memory allocation error: free partial state */ - close_state(L); - L = NULL; - } - } - lua_userstateopen(L); - return L; -} - - -static void callallgcTM (lua_State *L, void *ud) { - UNUSED(ud); - luaC_callGCTM(L); /* call GC metamethods for all udata */ -} - - -LUA_API void lua_close (lua_State *L) { - lua_lock(L); - L = G(L)->mainthread; /* only the main thread can be closed */ - luaF_close(L, L->stack); /* close all upvalues for this thread */ - luaC_separateudata(L); /* separate udata that have GC metamethods */ - L->errfunc = 0; /* no error function during GC metamethods */ - do { /* repeat until no more errors */ - L->ci = L->base_ci; - L->base = L->top = L->ci->base; - L->nCcalls = 0; - } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); - lua_assert(G(L)->tmudata == NULL); - close_state(L); -} - diff --git a/!NotAdopted/SmartAutoReplier/lualib/lstate.h b/!NotAdopted/SmartAutoReplier/lualib/lstate.h deleted file mode 100644 index 5422f1b196..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lstate.h +++ /dev/null @@ -1,195 +0,0 @@ -/* -** $Id: lstate.h,v 1.109 2003/02/27 11:52:30 roberto Exp $ -** Global State -** See Copyright Notice in lua.h -*/ - -#ifndef lstate_h -#define lstate_h - -#include "lua.h" - -#include "lobject.h" -#include "ltm.h" -#include "lzio.h" - - -/* -** macros for thread synchronization inside Lua core machine: -** all accesses to the global state and to global objects are synchronized. -** Because threads can read the stack of other threads -** (when running garbage collection), -** a thread must also synchronize any write-access to its own stack. -** Unsynchronized accesses are allowed only when reading its own stack, -** or when reading immutable fields from global objects -** (such as string values and udata values). -*/ -#ifndef lua_lock -#define lua_lock(L) ((void) 0) -#endif - -#ifndef lua_unlock -#define lua_unlock(L) ((void) 0) -#endif - - -#ifndef lua_userstateopen -#define lua_userstateopen(l) -#endif - - - -struct lua_longjmp; /* defined in ldo.c */ - - -/* default meta table (both for tables and udata) */ -#define defaultmeta(L) (&G(L)->_defaultmeta) - -/* table of globals */ -#define gt(L) (&L->_gt) - -/* registry */ -#define registry(L) (&G(L)->_registry) - - -/* extra stack space to handle TM calls and some other extras */ -#define EXTRA_STACK 5 - - -#define BASIC_CI_SIZE 8 - -#define BASIC_STACK_SIZE (2*LUA_MINSTACK) - - - -typedef struct stringtable { - GCObject **hash; - ls_nstr nuse; /* number of elements */ - int size; -} stringtable; - - -/* -** informations about a call -*/ -typedef struct CallInfo { - StkId base; /* base for called function */ - StkId top; /* top for this function */ - int state; /* bit fields; see below */ - union { - struct { /* for Lua functions */ - const Instruction *savedpc; - const Instruction **pc; /* points to `pc' variable in `luaV_execute' */ - int tailcalls; /* number of tail calls lost under this entry */ - } l; - struct { /* for C functions */ - int dummy; /* just to avoid an empty struct */ - } c; - } u; -} CallInfo; - - -/* -** bit fields for `CallInfo.state' -*/ -#define CI_C (1<<0) /* 1 if function is a C function */ -/* 1 if (Lua) function has an active `luaV_execute' running it */ -#define CI_HASFRAME (1<<1) -/* 1 if Lua function is calling another Lua function (and therefore its - `pc' is being used by the other, and therefore CI_SAVEDPC is 1 too) */ -#define CI_CALLING (1<<2) -#define CI_SAVEDPC (1<<3) /* 1 if `savedpc' is updated */ -#define CI_YIELD (1<<4) /* 1 if thread is suspended */ - - -#define ci_func(ci) (clvalue((ci)->base - 1)) - - -/* -** `global state', shared by all threads of this state -*/ -typedef struct global_State { - stringtable strt; /* hash table for strings */ - GCObject *rootgc; /* list of (almost) all collectable objects */ - GCObject *rootudata; /* (separated) list of all userdata */ - GCObject *tmudata; /* list of userdata to be GC */ - Mbuffer buff; /* temporary buffer for string concatentation */ - lu_mem GCthreshold; - lu_mem nblocks; /* number of `bytes' currently allocated */ - lua_CFunction panic; /* to be called in unprotected errors */ - TObject _registry; - TObject _defaultmeta; - struct lua_State *mainthread; - Node dummynode[1]; /* common node array for all empty tables */ - TString *tmname[TM_N]; /* array with tag-method names */ -} global_State; - - -/* -** `per thread' state -*/ -struct lua_State { - CommonHeader; - StkId top; /* first free slot in the stack */ - StkId base; /* base of current function */ - global_State *l_G; - CallInfo *ci; /* call info for current function */ - StkId stack_last; /* last free slot in the stack */ - StkId stack; /* stack base */ - int stacksize; - CallInfo *end_ci; /* points after end of ci array*/ - CallInfo *base_ci; /* array of CallInfo's */ - unsigned short size_ci; /* size of array `base_ci' */ - unsigned short nCcalls; /* number of nested C calls */ - lu_byte hookmask; - lu_byte allowhook; - lu_byte hookinit; - int basehookcount; - int hookcount; - lua_Hook hook; - TObject _gt; /* table of globals */ - GCObject *openupval; /* list of open upvalues in this stack */ - GCObject *gclist; - struct lua_longjmp *errorJmp; /* current error recover point */ - ptrdiff_t errfunc; /* current error handling function (stack index) */ -}; - - -#define G(L) (L->l_G) - - -/* -** Union of all collectable objects -*/ -union GCObject { - GCheader gch; - union TString ts; - union Udata u; - union Closure cl; - struct Table h; - struct Proto p; - struct UpVal uv; - struct lua_State th; /* thread */ -}; - - -/* macros to convert a GCObject into a specific value */ -#define gcotots(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) -#define gcotou(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) -#define gcotocl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) -#define gcotoh(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) -#define gcotop(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) -#define gcotouv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) -#define ngcotouv(o) \ - check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv)) -#define gcototh(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) - -/* macro to convert any value into a GCObject */ -#define valtogco(v) (cast(GCObject *, (v))) - - -lua_State *luaE_newthread (lua_State *L); -void luaE_freethread (lua_State *L, lua_State *L1); - -#endif - diff --git a/!NotAdopted/SmartAutoReplier/lualib/lstring.c b/!NotAdopted/SmartAutoReplier/lualib/lstring.c deleted file mode 100644 index 8cbddbd218..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lstring.c +++ /dev/null @@ -1,102 +0,0 @@ -/* -** $Id: lstring.c,v 1.78 2002/12/04 17:38:31 roberto Exp $ -** String table (keeps all strings handled by Lua) -** See Copyright Notice in lua.h -*/ - - -#include - -#define lstring_c - -#include "lua.h" - -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" -#include "lstring.h" - - - -void luaS_freeall (lua_State *L) { - lua_assert(G(L)->strt.nuse==0); - luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); -} - - -void luaS_resize (lua_State *L, int newsize) { - GCObject **newhash = luaM_newvector(L, newsize, GCObject *); - stringtable *tb = &G(L)->strt; - int i; - for (i=0; isize; i++) { - GCObject *p = tb->hash[i]; - while (p) { /* for each node in the list */ - GCObject *next = p->gch.next; /* save next */ - lu_hash h = gcotots(p)->tsv.hash; - int h1 = lmod(h, newsize); /* new position */ - lua_assert(cast(int, h%newsize) == lmod(h, newsize)); - p->gch.next = newhash[h1]; /* chain it */ - newhash[h1] = p; - p = next; - } - } - luaM_freearray(L, tb->hash, tb->size, TString *); - tb->size = newsize; - tb->hash = newhash; -} - - -static TString *newlstr (lua_State *L, const char *str, size_t l, lu_hash h) { - TString *ts = cast(TString *, luaM_malloc(L, sizestring(l))); - stringtable *tb; - ts->tsv.len = l; - ts->tsv.hash = h; - ts->tsv.marked = 0; - ts->tsv.tt = LUA_TSTRING; - ts->tsv.reserved = 0; - memcpy(ts+1, str, l*sizeof(char)); - ((char *)(ts+1))[l] = '\0'; /* ending 0 */ - tb = &G(L)->strt; - h = lmod(h, tb->size); - ts->tsv.next = tb->hash[h]; /* chain new entry */ - tb->hash[h] = valtogco(ts); - tb->nuse++; - if (tb->nuse > cast(ls_nstr, tb->size) && tb->size <= MAX_INT/2) - luaS_resize(L, tb->size*2); /* too crowded */ - return ts; -} - - -TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { - GCObject *o; - lu_hash h = (lu_hash)l; /* seed */ - size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ - size_t l1; - for (l1=l; l1>=step; l1-=step) /* compute hash */ - h = h ^ ((h<<5)+(h>>2)+(unsigned char)(str[l1-1])); - for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; - o != NULL; - o = o->gch.next) { - TString *ts = gcotots(o); - if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) - return ts; - } - return newlstr(L, str, l, h); /* not found */ -} - - -Udata *luaS_newudata (lua_State *L, size_t s) { - Udata *u; - u = cast(Udata *, luaM_malloc(L, sizeudata(s))); - u->uv.marked = (1<<1); /* is not finalized */ - u->uv.tt = LUA_TUSERDATA; - u->uv.len = s; - u->uv.metatable = hvalue(defaultmeta(L)); - /* chain it on udata list */ - u->uv.next = G(L)->rootudata; - G(L)->rootudata = valtogco(u); - return u; -} - diff --git a/!NotAdopted/SmartAutoReplier/lualib/lstring.h b/!NotAdopted/SmartAutoReplier/lualib/lstring.h deleted file mode 100644 index be5a1e3767..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lstring.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -** $Id: lstring.h,v 1.37 2002/08/16 14:45:55 roberto Exp $ -** String table (keep all strings handled by Lua) -** See Copyright Notice in lua.h -*/ - -#ifndef lstring_h -#define lstring_h - - -#include "lobject.h" -#include "lstate.h" - - - -#define sizestring(l) (cast(lu_mem, sizeof(union TString))+ \ - (cast(lu_mem, l)+1)*sizeof(char)) - -#define sizeudata(l) (cast(lu_mem, sizeof(union Udata))+(l)) - -#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) -#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ - (sizeof(s)/sizeof(char))-1)) - -#define luaS_fix(s) ((s)->tsv.marked |= (1<<4)) - -void luaS_resize (lua_State *L, int newsize); -Udata *luaS_newudata (lua_State *L, size_t s); -void luaS_freeall (lua_State *L); -TString *luaS_newlstr (lua_State *L, const char *str, size_t l); - - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/lstrlib.c b/!NotAdopted/SmartAutoReplier/lualib/lstrlib.c deleted file mode 100644 index 8752e3aba3..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lstrlib.c +++ /dev/null @@ -1,770 +0,0 @@ -/* -** $Id: lstrlib.c,v 1.98 2003/04/03 13:35:34 roberto Exp $ -** Standard library for string operations and pattern-matching -** See Copyright Notice in lua.h -*/ - - -#include -#include -#include -#include -#include - -#define lstrlib_c - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - -/* macro to `unsign' a character */ -#ifndef uchar -#define uchar(c) ((unsigned char)(c)) -#endif - - -typedef long sint32; /* a signed version for size_t */ - - -static int str_len (lua_State *L) { - size_t l; - luaL_checklstring(L, 1, &l); - lua_pushnumber(L, (lua_Number)l); - return 1; -} - - -static sint32 posrelat (sint32 pos, size_t len) { - /* relative string position: negative means back from end */ - return (pos>=0) ? pos : (sint32)len+pos+1; -} - - -static int str_sub (lua_State *L) { - size_t l; - const char *s = luaL_checklstring(L, 1, &l); - sint32 start = posrelat(luaL_checklong(L, 2), l); - sint32 end = posrelat(luaL_optlong(L, 3, -1), l); - if (start < 1) start = 1; - if (end > (sint32)l) end = (sint32)l; - if (start <= end) - lua_pushlstring(L, s+start-1, end-start+1); - else lua_pushliteral(L, ""); - return 1; -} - - -static int str_lower (lua_State *L) { - size_t l; - size_t i; - luaL_Buffer b; - const char *s = luaL_checklstring(L, 1, &l); - luaL_buffinit(L, &b); - for (i=0; i 0) - luaL_addlstring(&b, s, l); - luaL_pushresult(&b); - return 1; -} - - -static int str_byte (lua_State *L) { - size_t l; - const char *s = luaL_checklstring(L, 1, &l); - sint32 pos = posrelat(luaL_optlong(L, 2, 1), l); - if (pos <= 0 || (size_t)(pos) > l) /* index out of range? */ - return 0; /* no answer */ - lua_pushnumber(L, uchar(s[pos-1])); - return 1; -} - - -static int str_char (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - int i; - luaL_Buffer b; - luaL_buffinit(L, &b); - for (i=1; i<=n; i++) { - int c = luaL_checkint(L, i); - luaL_argcheck(L, uchar(c) == c, i, "invalid value"); - luaL_putchar(&b, uchar(c)); - } - luaL_pushresult(&b); - return 1; -} - - -static int writer (lua_State *L, const void* b, size_t size, void* B) { - (void)L; - luaL_addlstring((luaL_Buffer*) B, (const char *)b, size); - return 1; -} - - -static int str_dump (lua_State *L) { - luaL_Buffer b; - luaL_checktype(L, 1, LUA_TFUNCTION); - luaL_buffinit(L,&b); - if (!lua_dump(L, writer, &b)) - luaL_error(L, "unable to dump given function"); - luaL_pushresult(&b); - return 1; -} - - - -/* -** {====================================================== -** PATTERN MATCHING -** ======================================================= -*/ - -#ifndef MAX_CAPTURES -#define MAX_CAPTURES 32 /* arbitrary limit */ -#endif - - -#define CAP_UNFINISHED (-1) -#define CAP_POSITION (-2) - -typedef struct MatchState { - const char *src_init; /* init of source string */ - const char *src_end; /* end (`\0') of source string */ - lua_State *L; - int level; /* total number of captures (finished or unfinished) */ - struct { - const char *init; - sint32 len; - } capture[MAX_CAPTURES]; -} MatchState; - - -#define ESC '%' -#define SPECIALS "^$*+?.([%-" - - -static int check_capture (MatchState *ms, int l) { - l -= '1'; - if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) - return luaL_error(ms->L, "invalid capture index"); - return l; -} - - -static int capture_to_close (MatchState *ms) { - int level = ms->level; - for (level--; level>=0; level--) - if (ms->capture[level].len == CAP_UNFINISHED) return level; - return luaL_error(ms->L, "invalid pattern capture"); -} - - -static const char *luaI_classend (MatchState *ms, const char *p) { - switch (*p++) { - case ESC: { - if (*p == '\0') - luaL_error(ms->L, "malformed pattern (ends with `%')"); - return p+1; - } - case '[': { - if (*p == '^') p++; - do { /* look for a `]' */ - if (*p == '\0') - luaL_error(ms->L, "malformed pattern (missing `]')"); - if (*(p++) == ESC && *p != '\0') - p++; /* skip escapes (e.g. `%]') */ - } while (*p != ']'); - return p+1; - } - default: { - return p; - } - } -} - - -static int match_class (int c, int cl) { - int res; - switch (tolower(cl)) { - case 'a' : res = isalpha(c); break; - case 'c' : res = iscntrl(c); break; - case 'd' : res = isdigit(c); break; - case 'l' : res = islower(c); break; - case 'p' : res = ispunct(c); break; - case 's' : res = isspace(c); break; - case 'u' : res = isupper(c); break; - case 'w' : res = isalnum(c); break; - case 'x' : res = isxdigit(c); break; - case 'z' : res = (c == 0); break; - default: return (cl == c); - } - return (islower(cl) ? res : !res); -} - - -static int matchbracketclass (int c, const char *p, const char *ec) { - int sig = 1; - if (*(p+1) == '^') { - sig = 0; - p++; /* skip the `^' */ - } - while (++p < ec) { - if (*p == ESC) { - p++; - if (match_class(c, *p)) - return sig; - } - else if ((*(p+1) == '-') && (p+2 < ec)) { - p+=2; - if (uchar(*(p-2)) <= c && c <= uchar(*p)) - return sig; - } - else if (uchar(*p) == c) return sig; - } - return !sig; -} - - -static int luaI_singlematch (int c, const char *p, const char *ep) { - switch (*p) { - case '.': return 1; /* matches any char */ - case ESC: return match_class(c, *(p+1)); - case '[': return matchbracketclass(c, p, ep-1); - default: return (uchar(*p) == c); - } -} - - -static const char *match (MatchState *ms, const char *s, const char *p); - - -static const char *matchbalance (MatchState *ms, const char *s, - const char *p) { - if (*p == 0 || *(p+1) == 0) - luaL_error(ms->L, "unbalanced pattern"); - if (*s != *p) return NULL; - else { - int b = *p; - int e = *(p+1); - int cont = 1; - while (++s < ms->src_end) { - if (*s == e) { - if (--cont == 0) return s+1; - } - else if (*s == b) cont++; - } - } - return NULL; /* string ends out of balance */ -} - - -static const char *max_expand (MatchState *ms, const char *s, - const char *p, const char *ep) { - sint32 i = 0; /* counts maximum expand for item */ - while ((s+i)src_end && luaI_singlematch(uchar(*(s+i)), p, ep)) - i++; - /* keeps trying to match with the maximum repetitions */ - while (i>=0) { - const char *res = match(ms, (s+i), ep+1); - if (res) return res; - i--; /* else didn't match; reduce 1 repetition to try again */ - } - return NULL; -} - - -static const char *min_expand (MatchState *ms, const char *s, - const char *p, const char *ep) { - for (;;) { - const char *res = match(ms, s, ep+1); - if (res != NULL) - return res; - else if (ssrc_end && luaI_singlematch(uchar(*s), p, ep)) - s++; /* try with one more repetition */ - else return NULL; - } -} - - -static const char *start_capture (MatchState *ms, const char *s, - const char *p, int what) { - const char *res; - int level = ms->level; - if (level >= MAX_CAPTURES) luaL_error(ms->L, "too many captures"); - ms->capture[level].init = s; - ms->capture[level].len = what; - ms->level = level+1; - if ((res=match(ms, s, p)) == NULL) /* match failed? */ - ms->level--; /* undo capture */ - return res; -} - - -static const char *end_capture (MatchState *ms, const char *s, - const char *p) { - int l = capture_to_close(ms); - const char *res; - ms->capture[l].len = s - ms->capture[l].init; /* close capture */ - if ((res = match(ms, s, p)) == NULL) /* match failed? */ - ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ - return res; -} - - -static const char *match_capture (MatchState *ms, const char *s, int l) { - size_t len; - l = check_capture(ms, l); - len = ms->capture[l].len; - if ((size_t)(ms->src_end-s) >= len && - memcmp(ms->capture[l].init, s, len) == 0) - return s+len; - else return NULL; -} - - -static const char *match (MatchState *ms, const char *s, const char *p) { - init: /* using goto's to optimize tail recursion */ - switch (*p) { - case '(': { /* start capture */ - if (*(p+1) == ')') /* position capture? */ - return start_capture(ms, s, p+2, CAP_POSITION); - else - return start_capture(ms, s, p+1, CAP_UNFINISHED); - } - case ')': { /* end capture */ - return end_capture(ms, s, p+1); - } - case ESC: { - switch (*(p+1)) { - case 'b': { /* balanced string? */ - s = matchbalance(ms, s, p+2); - if (s == NULL) return NULL; - p+=4; goto init; /* else return match(ms, s, p+4); */ - } - case 'f': { /* frontier? */ - const char *ep; char previous; - p += 2; - if (*p != '[') - luaL_error(ms->L, "missing `[' after `%%f' in pattern"); - ep = luaI_classend(ms, p); /* points to what is next */ - previous = (s == ms->src_init) ? '\0' : *(s-1); - if (matchbracketclass(uchar(previous), p, ep-1) || - !matchbracketclass(uchar(*s), p, ep-1)) return NULL; - p=ep; goto init; /* else return match(ms, s, ep); */ - } - default: { - if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */ - s = match_capture(ms, s, *(p+1)); - if (s == NULL) return NULL; - p+=2; goto init; /* else return match(ms, s, p+2) */ - } - goto dflt; /* case default */ - } - } - } - case '\0': { /* end of pattern */ - return s; /* match succeeded */ - } - case '$': { - if (*(p+1) == '\0') /* is the `$' the last char in pattern? */ - return (s == ms->src_end) ? s : NULL; /* check end of string */ - else goto dflt; - } - default: dflt: { /* it is a pattern item */ - const char *ep = luaI_classend(ms, p); /* points to what is next */ - int m = ssrc_end && luaI_singlematch(uchar(*s), p, ep); - switch (*ep) { - case '?': { /* optional */ - const char *res; - if (m && ((res=match(ms, s+1, ep+1)) != NULL)) - return res; - p=ep+1; goto init; /* else return match(ms, s, ep+1); */ - } - case '*': { /* 0 or more repetitions */ - return max_expand(ms, s, p, ep); - } - case '+': { /* 1 or more repetitions */ - return (m ? max_expand(ms, s+1, p, ep) : NULL); - } - case '-': { /* 0 or more repetitions (minimum) */ - return min_expand(ms, s, p, ep); - } - default: { - if (!m) return NULL; - s++; p=ep; goto init; /* else return match(ms, s+1, ep); */ - } - } - } - } -} - - - -static const char *lmemfind (const char *s1, size_t l1, - const char *s2, size_t l2) { - if (l2 == 0) return s1; /* empty strings are everywhere */ - else if (l2 > l1) return NULL; /* avoids a negative `l1' */ - else { - const char *init; /* to search for a `*s2' inside `s1' */ - l2--; /* 1st char will be checked by `memchr' */ - l1 = l1-l2; /* `s2' cannot be found after that */ - while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { - init++; /* 1st char is already checked */ - if (memcmp(init, s2+1, l2) == 0) - return init-1; - else { /* correct `l1' and `s1' to try again */ - l1 -= init-s1; - s1 = init; - } - } - return NULL; /* not found */ - } -} - - -static void push_onecapture (MatchState *ms, int i) { - int l = ms->capture[i].len; - if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); - if (l == CAP_POSITION) - lua_pushnumber(ms->L, (lua_Number)(ms->capture[i].init - ms->src_init + 1)); - else - lua_pushlstring(ms->L, ms->capture[i].init, l); -} - - -static int push_captures (MatchState *ms, const char *s, const char *e) { - int i; - luaL_checkstack(ms->L, ms->level, "too many captures"); - if (ms->level == 0 && s) { /* no explicit captures? */ - lua_pushlstring(ms->L, s, e-s); /* return whole match */ - return 1; - } - else { /* return all captures */ - for (i=0; ilevel; i++) - push_onecapture(ms, i); - return ms->level; /* number of strings pushed */ - } -} - - -static int str_find (lua_State *L) { - size_t l1, l2; - const char *s = luaL_checklstring(L, 1, &l1); - const char *p = luaL_checklstring(L, 2, &l2); - sint32 init = posrelat(luaL_optlong(L, 3, 1), l1) - 1; - if (init < 0) init = 0; - else if ((size_t)(init) > l1) init = (sint32)l1; - if (lua_toboolean(L, 4) || /* explicit request? */ - strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */ - /* do a plain search */ - const char *s2 = lmemfind(s+init, l1-init, p, l2); - if (s2) { - lua_pushnumber(L, (lua_Number)(s2-s+1)); - lua_pushnumber(L, (lua_Number)(s2-s+l2)); - return 2; - } - } - else { - MatchState ms; - int anchor = (*p == '^') ? (p++, 1) : 0; - const char *s1=s+init; - ms.L = L; - ms.src_init = s; - ms.src_end = s+l1; - do { - const char *res; - ms.level = 0; - if ((res=match(&ms, s1, p)) != NULL) { - lua_pushnumber(L, (lua_Number)(s1-s+1)); /* start */ - lua_pushnumber(L, (lua_Number)(res-s)); /* end */ - return push_captures(&ms, NULL, 0) + 2; - } - } while (s1++L; - if (lua_isstring(L, 3)) { - const char *news = lua_tostring(L, 3); - size_t l = lua_strlen(L, 3); - size_t i; - for (i=0; i= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)), - 3, "string or function expected"); - luaL_buffinit(L, &b); - ms.L = L; - ms.src_init = src; - ms.src_end = src+srcl; - while (n < max_s) { - const char *e; - ms.level = 0; - e = match(&ms, src, p); - if (e) { - n++; - add_s(&ms, &b, src, e); - } - if (e && e>src) /* non empty match? */ - src = e; /* skip it */ - else if (src < ms.src_end) - luaL_putchar(&b, *src++); - else break; - if (anchor) break; - } - luaL_addlstring(&b, src, ms.src_end-src); - luaL_pushresult(&b); - lua_pushnumber(L, (lua_Number)n); /* number of substitutions */ - return 2; -} - -/* }====================================================== */ - - -/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ -#define MAX_ITEM 512 -/* maximum size of each format specification (such as '%-099.99d') */ -#define MAX_FORMAT 20 - - -static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) { - size_t l; - const char *s = luaL_checklstring(L, arg, &l); - luaL_putchar(b, '"'); - while (l--) { - switch (*s) { - case '"': case '\\': case '\n': { - luaL_putchar(b, '\\'); - luaL_putchar(b, *s); - break; - } - case '\0': { - luaL_addlstring(b, "\\000", 4); - break; - } - default: { - luaL_putchar(b, *s); - break; - } - } - s++; - } - luaL_putchar(b, '"'); -} - - -static const char *scanformat (lua_State *L, const char *strfrmt, - char *form, int *hasprecision) { - const char *p = strfrmt; - while (strchr("-+ #0", *p)) p++; /* skip flags */ - if (isdigit(uchar(*p))) p++; /* skip width */ - if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ - if (*p == '.') { - p++; - *hasprecision = 1; - if (isdigit(uchar(*p))) p++; /* skip precision */ - if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ - } - if (isdigit(uchar(*p))) - luaL_error(L, "invalid format (width or precision too long)"); - if (p-strfrmt+2 > MAX_FORMAT) /* +2 to include `%' and the specifier */ - luaL_error(L, "invalid format (too long)"); - form[0] = '%'; - strncpy(form+1, strfrmt, p-strfrmt+1); - form[p-strfrmt+2] = 0; - return p; -} - - -static int str_format (lua_State *L) { - int arg = 1; - size_t sfl; - const char *strfrmt = luaL_checklstring(L, arg, &sfl); - const char *strfrmt_end = strfrmt+sfl; - luaL_Buffer b; - luaL_buffinit(L, &b); - while (strfrmt < strfrmt_end) { - if (*strfrmt != '%') - luaL_putchar(&b, *strfrmt++); - else if (*++strfrmt == '%') - luaL_putchar(&b, *strfrmt++); /* %% */ - else { /* format item */ - char form[MAX_FORMAT]; /* to store the format (`%...') */ - char buff[MAX_ITEM]; /* to store the formatted item */ - int hasprecision = 0; - if (isdigit(uchar(*strfrmt)) && *(strfrmt+1) == '$') - return luaL_error(L, "obsolete option (d$) to `format'"); - arg++; - strfrmt = scanformat(L, strfrmt, form, &hasprecision); - switch (*strfrmt++) { - case 'c': case 'd': case 'i': { - sprintf(buff, form, luaL_checkint(L, arg)); - break; - } - case 'o': case 'u': case 'x': case 'X': { - sprintf(buff, form, (unsigned int)(luaL_checknumber(L, arg))); - break; - } - case 'e': case 'E': case 'f': - case 'g': case 'G': { - sprintf(buff, form, luaL_checknumber(L, arg)); - break; - } - case 'q': { - luaI_addquoted(L, &b, arg); - continue; /* skip the `addsize' at the end */ - } - case 's': { - size_t l; - const char *s = luaL_checklstring(L, arg, &l); - if (!hasprecision && l >= 100) { - /* no precision and string is too long to be formatted; - keep original string */ - lua_pushvalue(L, arg); - luaL_addvalue(&b); - continue; /* skip the `addsize' at the end */ - } - else { - sprintf(buff, form, s); - break; - } - } - default: { /* also treat cases `pnLlh' */ - return luaL_error(L, "invalid option to `format'"); - } - } - luaL_addlstring(&b, buff, strlen(buff)); - } - } - luaL_pushresult(&b); - return 1; -} - - -static const luaL_reg strlib[] = { - {"len", str_len}, - {"sub", str_sub}, - {"lower", str_lower}, - {"upper", str_upper}, - {"char", str_char}, - {"rep", str_rep}, - {"byte", str_byte}, - {"format", str_format}, - {"dump", str_dump}, - {"find", str_find}, - {"gfind", gfind}, - {"gsub", str_gsub}, - {NULL, NULL} -}; - - -/* -** Open string library -*/ -LUALIB_API int luaopen_string (lua_State *L) { - luaL_openlib(L, LUA_STRLIBNAME, strlib, 0); - return 1; -} - diff --git a/!NotAdopted/SmartAutoReplier/lualib/ltable.c b/!NotAdopted/SmartAutoReplier/lualib/ltable.c deleted file mode 100644 index 0c64adb10a..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/ltable.c +++ /dev/null @@ -1,509 +0,0 @@ -/* -** $Id: ltable.c,v 1.132 2003/04/03 13:35:34 roberto Exp $ -** Lua tables (hash) -** See Copyright Notice in lua.h -*/ - - -/* -** Implementation of tables (aka arrays, objects, or hash tables). -** Tables keep its elements in two parts: an array part and a hash part. -** Non-negative integer keys are all candidates to be kept in the array -** part. The actual size of the array is the largest `n' such that at -** least half the slots between 0 and n are in use. -** Hash uses a mix of chained scatter table with Brent's variation. -** A main invariant of these tables is that, if an element is not -** in its main position (i.e. the `original' position that its hash gives -** to it), then the colliding element is in its own main position. -** In other words, there are collisions only when two elements have the -** same main position (i.e. the same hash values for that table size). -** Because of that, the load factor of these tables can be 100% without -** performance penalties. -*/ - -#include - -#define ltable_c - -#include "lua.h" - -#include "ldebug.h" -#include "ldo.h" -#include "lgc.h" -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" -#include "ltable.h" - - -/* -** max size of array part is 2^MAXBITS -*/ -#if BITS_INT > 26 -#define MAXBITS 24 -#else -#define MAXBITS (BITS_INT-2) -#endif - -/* check whether `x' < 2^MAXBITS */ -#define toobig(x) ((((x)-1) >> MAXBITS) != 0) - - -/* function to convert a lua_Number to int (with any rounding method) */ -#ifndef lua_number2int -#define lua_number2int(i,n) ((i)=(int)(n)) -#endif - - -#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) - -#define hashstr(t,str) hashpow2(t, (str)->tsv.hash) -#define hashboolean(t,p) hashpow2(t, p) - - -/* -** for some types, it is better to avoid modulus by power of 2, as -** they tend to have many 2 factors. -*/ -#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) - - -#define hashpointer(t,p) hashmod(t, IntPoint(p)) - - -/* -** number of ints inside a lua_Number -*/ -#define numints cast(int, sizeof(lua_Number)/sizeof(int)) - - -/* -** hash for lua_Numbers -*/ -static Node *hashnum (const Table *t, lua_Number n) { - unsigned int a[numints]; - int i; - n += 1; /* normalize number (avoid -0) */ - lua_assert(sizeof(a) <= sizeof(n)); - memcpy(a, &n, sizeof(a)); - for (i = 1; i < numints; i++) a[0] += a[i]; - return hashmod(t, cast(lu_hash, a[0])); -} - - - -/* -** returns the `main' position of an element in a table (that is, the index -** of its hash value) -*/ -Node *luaH_mainposition (const Table *t, const TObject *key) { - switch (ttype(key)) { - case LUA_TNUMBER: - return hashnum(t, nvalue(key)); - case LUA_TSTRING: - return hashstr(t, tsvalue(key)); - case LUA_TBOOLEAN: - return hashboolean(t, bvalue(key)); - case LUA_TLIGHTUSERDATA: - return hashpointer(t, pvalue(key)); - default: - return hashpointer(t, gcvalue(key)); - } -} - - -/* -** returns the index for `key' if `key' is an appropriate key to live in -** the array part of the table, -1 otherwise. -*/ -static int arrayindex (const TObject *key) { - if (ttisnumber(key)) { - int k; - lua_number2int(k, (nvalue(key))); - if (cast(lua_Number, k) == nvalue(key) && k >= 1 && !toobig(k)) - return k; - } - return -1; /* `key' did not match some condition */ -} - - -/* -** returns the index of a `key' for table traversals. First goes all -** elements in the array part, then elements in the hash part. The -** beginning and end of a traversal are signalled by -1. -*/ -static int luaH_index (lua_State *L, Table *t, StkId key) { - int i; - if (ttisnil(key)) return -1; /* first iteration */ - i = arrayindex(key); - if (0 <= i && i <= t->sizearray) { /* is `key' inside array part? */ - return i-1; /* yes; that's the index (corrected to C) */ - } - else { - const TObject *v = luaH_get(t, key); - if (v == &luaO_nilobject) - luaG_runerror(L, "invalid key for `next'"); - i = cast(int, (cast(const lu_byte *, v) - - cast(const lu_byte *, gval(gnode(t, 0)))) / sizeof(Node)); - return i + t->sizearray; /* hash elements are numbered after array ones */ - } -} - - -int luaH_next (lua_State *L, Table *t, StkId key) { - int i = luaH_index(L, t, key); /* find original element */ - for (i++; i < t->sizearray; i++) { /* try first array part */ - if (!ttisnil(&t->array[i])) { /* a non-nil value? */ - setnvalue(key, cast(lua_Number, i+1)); - setobj2s(key+1, &t->array[i]); - return 1; - } - } - for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ - if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ - setobj2s(key, gkey(gnode(t, i))); - setobj2s(key+1, gval(gnode(t, i))); - return 1; - } - } - return 0; /* no more elements */ -} - - -/* -** {============================================================= -** Rehash -** ============================================================== -*/ - - -static void computesizes (int nums[], int ntotal, int *narray, int *nhash) { - int i; - int a = nums[0]; /* number of elements smaller than 2^i */ - int na = a; /* number of elements to go to array part */ - int n = (na == 0) ? -1 : 0; /* (log of) optimal size for array part */ - for (i = 1; a < *narray && *narray >= twoto(i-1); i++) { - if (nums[i] > 0) { - a += nums[i]; - if (a >= twoto(i-1)) { /* more than half elements in use? */ - n = i; - na = a; - } - } - } - lua_assert(na <= *narray && *narray <= ntotal); - *nhash = ntotal - na; - *narray = (n == -1) ? 0 : twoto(n); - lua_assert(na <= *narray && na >= *narray/2); -} - - -static void numuse (const Table *t, int *narray, int *nhash) { - int nums[MAXBITS+1]; - int i, lg; - int totaluse = 0; - /* count elements in array part */ - for (i=0, lg=0; lg<=MAXBITS; lg++) { /* for each slice [2^(lg-1) to 2^lg) */ - int ttlg = twoto(lg); /* 2^lg */ - if (ttlg > t->sizearray) { - ttlg = t->sizearray; - if (i >= ttlg) break; - } - nums[lg] = 0; - for (; iarray[i])) { - nums[lg]++; - totaluse++; - } - } - } - for (; lg<=MAXBITS; lg++) nums[lg] = 0; /* reset other counts */ - *narray = totaluse; /* all previous uses were in array part */ - /* count elements in hash part */ - i = sizenode(t); - while (i--) { - Node *n = &t->node[i]; - if (!ttisnil(gval(n))) { - int k = arrayindex(gkey(n)); - if (k >= 0) { /* is `key' an appropriate array index? */ - nums[luaO_log2(k-1)+1]++; /* count as such */ - (*narray)++; - } - totaluse++; - } - } - computesizes(nums, totaluse, narray, nhash); -} - - -static void setarrayvector (lua_State *L, Table *t, int size) { - int i; - luaM_reallocvector(L, t->array, t->sizearray, size, TObject); - for (i=t->sizearray; iarray[i]); - t->sizearray = size; -} - - -static void setnodevector (lua_State *L, Table *t, int lsize) { - int i; - int size = twoto(lsize); - if (lsize > MAXBITS) - luaG_runerror(L, "table overflow"); - if (lsize == 0) { /* no elements to hash part? */ - t->node = G(L)->dummynode; /* use common `dummynode' */ - lua_assert(ttisnil(gkey(t->node))); /* assert invariants: */ - lua_assert(ttisnil(gval(t->node))); - lua_assert(t->node->next == NULL); /* (`dummynode' must be empty) */ - } - else { - t->node = luaM_newvector(L, size, Node); - for (i=0; inode[i].next = NULL; - setnilvalue(gkey(gnode(t, i))); - setnilvalue(gval(gnode(t, i))); - } - } - t->lsizenode = cast(lu_byte, lsize); - t->firstfree = gnode(t, size-1); /* first free position to be used */ -} - - -static void resize (lua_State *L, Table *t, int nasize, int nhsize) { - int i; - int oldasize = t->sizearray; - int oldhsize = t->lsizenode; - Node *nold; - Node temp[1]; - if (oldhsize) - nold = t->node; /* save old hash ... */ - else { /* old hash is `dummynode' */ - lua_assert(t->node == G(L)->dummynode); - temp[0] = t->node[0]; /* copy it to `temp' */ - nold = temp; - setnilvalue(gkey(G(L)->dummynode)); /* restate invariant */ - setnilvalue(gval(G(L)->dummynode)); - lua_assert(G(L)->dummynode->next == NULL); - } - if (nasize > oldasize) /* array part must grow? */ - setarrayvector(L, t, nasize); - /* create new hash part with appropriate size */ - setnodevector(L, t, nhsize); - /* re-insert elements */ - if (nasize < oldasize) { /* array part must shrink? */ - t->sizearray = nasize; - /* re-insert elements from vanishing slice */ - for (i=nasize; iarray[i])) - setobjt2t(luaH_setnum(L, t, i+1), &t->array[i]); - } - /* shrink array */ - luaM_reallocvector(L, t->array, oldasize, nasize, TObject); - } - /* re-insert elements in hash part */ - for (i = twoto(oldhsize) - 1; i >= 0; i--) { - Node *old = nold+i; - if (!ttisnil(gval(old))) - setobjt2t(luaH_set(L, t, gkey(old)), gval(old)); - } - if (oldhsize) - luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */ -} - - -static void rehash (lua_State *L, Table *t) { - int nasize, nhsize; - numuse(t, &nasize, &nhsize); /* compute new sizes for array and hash parts */ - resize(L, t, nasize, luaO_log2(nhsize)+1); -} - - - -/* -** }============================================================= -*/ - - -Table *luaH_new (lua_State *L, int narray, int lnhash) { - Table *t = luaM_new(L, Table); - luaC_link(L, valtogco(t), LUA_TTABLE); - t->metatable = hvalue(defaultmeta(L)); - t->flags = cast(lu_byte, ~0); - /* temporary values (kept only if some malloc fails) */ - t->array = NULL; - t->sizearray = 0; - t->lsizenode = 0; - t->node = NULL; - setarrayvector(L, t, narray); - setnodevector(L, t, lnhash); - return t; -} - - -void luaH_free (lua_State *L, Table *t) { - if (t->lsizenode) - luaM_freearray(L, t->node, sizenode(t), Node); - luaM_freearray(L, t->array, t->sizearray, TObject); - luaM_freelem(L, t); -} - - -#if 0 -/* -** try to remove an element from a hash table; cannot move any element -** (because gc can call `remove' during a table traversal) -*/ -void luaH_remove (Table *t, Node *e) { - Node *mp = luaH_mainposition(t, gkey(e)); - if (e != mp) { /* element not in its main position? */ - while (mp->next != e) mp = mp->next; /* find previous */ - mp->next = e->next; /* remove `e' from its list */ - } - else { - if (e->next != NULL) ?? - } - lua_assert(ttisnil(gval(node))); - setnilvalue(gkey(e)); /* clear node `e' */ - e->next = NULL; -} -#endif - - -/* -** inserts a new key into a hash table; first, check whether key's main -** position is free. If not, check whether colliding node is in its main -** position or not: if it is not, move colliding node to an empty place and -** put new key in its main position; otherwise (colliding node is in its main -** position), new key goes to an empty position. -*/ -static TObject *newkey (lua_State *L, Table *t, const TObject *key) { - TObject *val; - Node *mp = luaH_mainposition(t, key); - if (!ttisnil(gval(mp))) { /* main position is not free? */ - Node *othern = luaH_mainposition(t, gkey(mp)); /* `mp' of colliding node */ - Node *n = t->firstfree; /* get a free place */ - if (othern != mp) { /* is colliding node out of its main position? */ - /* yes; move colliding node into free position */ - while (othern->next != mp) othern = othern->next; /* find previous */ - othern->next = n; /* redo the chain with `n' in place of `mp' */ - *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ - mp->next = NULL; /* now `mp' is free */ - setnilvalue(gval(mp)); - } - else { /* colliding node is in its own main position */ - /* new node will go into free position */ - n->next = mp->next; /* chain new position */ - mp->next = n; - mp = n; - } - } - setobj2t(gkey(mp), key); /* write barrier */ - lua_assert(ttisnil(gval(mp))); - for (;;) { /* correct `firstfree' */ - if (ttisnil(gkey(t->firstfree))) - return gval(mp); /* OK; table still has a free place */ - else if (t->firstfree == t->node) break; /* cannot decrement from here */ - else (t->firstfree)--; - } - /* no more free places; must create one */ - setbvalue(gval(mp), 0); /* avoid new key being removed */ - rehash(L, t); /* grow table */ - val = cast(TObject *, luaH_get(t, key)); /* get new position */ - lua_assert(ttisboolean(val)); - setnilvalue(val); - return val; -} - - -/* -** generic search function -*/ -static const TObject *luaH_getany (Table *t, const TObject *key) { - if (ttisnil(key)) return &luaO_nilobject; - else { - Node *n = luaH_mainposition(t, key); - do { /* check whether `key' is somewhere in the chain */ - if (luaO_rawequalObj(gkey(n), key)) return gval(n); /* that's it */ - else n = n->next; - } while (n); - return &luaO_nilobject; - } -} - - -/* -** search function for integers -*/ -const TObject *luaH_getnum (Table *t, int key) { - if (1 <= key && key <= t->sizearray) - return &t->array[key-1]; - else { - lua_Number nk = cast(lua_Number, key); - Node *n = hashnum(t, nk); - do { /* check whether `key' is somewhere in the chain */ - if (ttisnumber(gkey(n)) && nvalue(gkey(n)) == nk) - return gval(n); /* that's it */ - else n = n->next; - } while (n); - return &luaO_nilobject; - } -} - - -/* -** search function for strings -*/ -const TObject *luaH_getstr (Table *t, TString *key) { - Node *n = hashstr(t, key); - do { /* check whether `key' is somewhere in the chain */ - if (ttisstring(gkey(n)) && tsvalue(gkey(n)) == key) - return gval(n); /* that's it */ - else n = n->next; - } while (n); - return &luaO_nilobject; -} - - -/* -** main search function -*/ -const TObject *luaH_get (Table *t, const TObject *key) { - switch (ttype(key)) { - case LUA_TSTRING: return luaH_getstr(t, tsvalue(key)); - case LUA_TNUMBER: { - int k; - lua_number2int(k, (nvalue(key))); - if (cast(lua_Number, k) == nvalue(key)) /* is an integer index? */ - return luaH_getnum(t, k); /* use specialized version */ - /* else go through */ - } - default: return luaH_getany(t, key); - } -} - - -TObject *luaH_set (lua_State *L, Table *t, const TObject *key) { - const TObject *p = luaH_get(t, key); - t->flags = 0; - if (p != &luaO_nilobject) - return cast(TObject *, p); - else { - if (ttisnil(key)) luaG_runerror(L, "table index is nil"); - else if (ttisnumber(key) && nvalue(key) != nvalue(key)) - luaG_runerror(L, "table index is NaN"); - return newkey(L, t, key); - } -} - - -TObject *luaH_setnum (lua_State *L, Table *t, int key) { - const TObject *p = luaH_getnum(t, key); - if (p != &luaO_nilobject) - return cast(TObject *, p); - else { - TObject k; - setnvalue(&k, cast(lua_Number, key)); - return newkey(L, t, &k); - } -} - diff --git a/!NotAdopted/SmartAutoReplier/lualib/ltable.h b/!NotAdopted/SmartAutoReplier/lualib/ltable.h deleted file mode 100644 index 3d4d753c3c..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/ltable.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -** $Id: ltable.h,v 1.44 2003/03/18 12:50:04 roberto Exp $ -** Lua tables (hash) -** See Copyright Notice in lua.h -*/ - -#ifndef ltable_h -#define ltable_h - -#include "lobject.h" - - -#define gnode(t,i) (&(t)->node[i]) -#define gkey(n) (&(n)->i_key) -#define gval(n) (&(n)->i_val) - - -const TObject *luaH_getnum (Table *t, int key); -TObject *luaH_setnum (lua_State *L, Table *t, int key); -const TObject *luaH_getstr (Table *t, TString *key); -const TObject *luaH_get (Table *t, const TObject *key); -TObject *luaH_set (lua_State *L, Table *t, const TObject *key); -Table *luaH_new (lua_State *L, int narray, int lnhash); -void luaH_free (lua_State *L, Table *t); -int luaH_next (lua_State *L, Table *t, StkId key); - -/* exported only for debugging */ -Node *luaH_mainposition (const Table *t, const TObject *key); - - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/ltablib.c b/!NotAdopted/SmartAutoReplier/lualib/ltablib.c deleted file mode 100644 index c9bb2d1b7e..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/ltablib.c +++ /dev/null @@ -1,250 +0,0 @@ -/* -** $Id: ltablib.c,v 1.21 2003/04/03 13:35:34 roberto Exp $ -** Library for Table Manipulation -** See Copyright Notice in lua.h -*/ - - -#include - -#define ltablib_c - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - -#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) - - -static int luaB_foreachi (lua_State *L) { - int i; - int n = aux_getn(L, 1); - luaL_checktype(L, 2, LUA_TFUNCTION); - for (i=1; i<=n; i++) { - lua_pushvalue(L, 2); /* function */ - lua_pushnumber(L, (lua_Number)i); /* 1st argument */ - lua_rawgeti(L, 1, i); /* 2nd argument */ - lua_call(L, 2, 1); - if (!lua_isnil(L, -1)) - return 1; - lua_pop(L, 1); /* remove nil result */ - } - return 0; -} - - -static int luaB_foreach (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - luaL_checktype(L, 2, LUA_TFUNCTION); - lua_pushnil(L); /* first key */ - for (;;) { - if (lua_next(L, 1) == 0) - return 0; - lua_pushvalue(L, 2); /* function */ - lua_pushvalue(L, -3); /* key */ - lua_pushvalue(L, -3); /* value */ - lua_call(L, 2, 1); - if (!lua_isnil(L, -1)) - return 1; - lua_pop(L, 2); /* remove value and result */ - } -} - - -static int luaB_getn (lua_State *L) { - lua_pushnumber(L, (lua_Number)aux_getn(L, 1)); - return 1; -} - - -static int luaB_setn (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - luaL_setn(L, 1, luaL_checkint(L, 2)); - return 0; -} - - -static int luaB_tinsert (lua_State *L) { - int v = lua_gettop(L); /* number of arguments */ - int n = aux_getn(L, 1) + 1; - int pos; /* where to insert new element */ - if (v == 2) /* called with only 2 arguments */ - pos = n; /* insert new element at the end */ - else { - pos = luaL_checkint(L, 2); /* 2nd argument is the position */ - if (pos > n) n = pos; /* `grow' array if necessary */ - v = 3; /* function may be called with more than 3 args */ - } - luaL_setn(L, 1, n); /* new size */ - while (--n >= pos) { /* move up elements */ - lua_rawgeti(L, 1, n); - lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */ - } - lua_pushvalue(L, v); - lua_rawseti(L, 1, pos); /* t[pos] = v */ - return 0; -} - - -static int luaB_tremove (lua_State *L) { - int n = aux_getn(L, 1); - int pos = luaL_optint(L, 2, n); - if (n <= 0) return 0; /* table is `empty' */ - luaL_setn(L, 1, n-1); /* t.n = n-1 */ - lua_rawgeti(L, 1, pos); /* result = t[pos] */ - for ( ;pos= P */ - while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { - if (i>u) luaL_error(L, "invalid order function for sorting"); - lua_pop(L, 1); /* remove a[i] */ - } - /* repeat --j until a[j] <= P */ - while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { - if (j -#include -#include -#include -#include - -#define ltests_c - -#include "lua.h" - -#include "lapi.h" -#include "lauxlib.h" -#include "lcode.h" -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "lmem.h" -#include "lopcodes.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "lualib.h" - - - -/* -** The whole module only makes sense with LUA_DEBUG on -*/ -#ifdef LUA_DEBUG - - -#define lua_pushintegral(L,i) lua_pushnumber(L, cast(lua_Number, (i))) - - -static lua_State *lua_state = NULL; - -int islocked = 0; - - -#define func_at(L,k) (L->ci->base+(k) - 1) - - -static void setnameval (lua_State *L, const char *name, int val) { - lua_pushstring(L, name); - lua_pushintegral(L, val); - lua_settable(L, -3); -} - - -/* -** {====================================================================== -** Controlled version for realloc. -** ======================================================================= -*/ - -#define MARK 0x55 /* 01010101 (a nice pattern) */ - -#ifndef EXTERNMEMCHECK -/* full memory check */ -#define HEADER (sizeof(L_Umaxalign)) /* ensures maximum alignment for HEADER */ -#define MARKSIZE 16 /* size of marks after each block */ -#define blockhead(b) (cast(char *, b) - HEADER) -#define setsize(newblock, size) (*cast(size_t *, newblock) = size) -#define checkblocksize(b, size) (size == (*cast(size_t *, blockhead(b)))) -#define fillmem(mem,size) memset(mem, -MARK, size) -#else -/* external memory check: don't do it twice */ -#define HEADER 0 -#define MARKSIZE 0 -#define blockhead(b) (b) -#define setsize(newblock, size) /* empty */ -#define checkblocksize(b,size) (1) -#define fillmem(mem,size) /* empty */ -#endif - -unsigned long memdebug_numblocks = 0; -unsigned long memdebug_total = 0; -unsigned long memdebug_maxmem = 0; -unsigned long memdebug_memlimit = ULONG_MAX; - - -static void *checkblock (void *block, size_t size) { - void *b = blockhead(block); - int i; - for (i=0;i 0); - if (size == 0) { - freeblock(block, oldsize); - return NULL; - } - else if (size > oldsize && memdebug_total+size-oldsize > memdebug_memlimit) - return NULL; /* to test memory allocation errors */ - else { - void *newblock; - int i; - size_t realsize = HEADER+size+MARKSIZE; - size_t commonsize = (oldsize < size) ? oldsize : size; - if (realsize < size) return NULL; /* overflow! */ - newblock = malloc(realsize); /* alloc a new block */ - if (newblock == NULL) return NULL; - if (block) { - memcpy(cast(char *, newblock)+HEADER, block, commonsize); - freeblock(block, oldsize); /* erase (and check) old copy */ - } - /* initialize new part of the block with something `weird' */ - fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize); - memdebug_total += size; - if (memdebug_total > memdebug_maxmem) - memdebug_maxmem = memdebug_total; - memdebug_numblocks++; - setsize(newblock, size); - for (i=0;icode[pc]; - OpCode o = GET_OPCODE(i); - const char *name = luaP_opnames[o]; - int line = getline(p, pc); - sprintf(buff, "(%4d) %4d - ", line, pc); - switch (getOpMode(o)) { - case iABC: - sprintf(buff+strlen(buff), "%-12s%4d %4d %4d", name, - GETARG_A(i), GETARG_B(i), GETARG_C(i)); - break; - case iABx: - sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i)); - break; - case iAsBx: - sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_sBx(i)); - break; - } - return buff; -} - - -#if 0 -void luaI_printcode (Proto *pt, int size) { - int pc; - for (pc=0; pcl.p; - lua_newtable(L); - setnameval(L, "maxstack", p->maxstacksize); - setnameval(L, "numparams", p->numparams); - for (pc=0; pcsizecode; pc++) { - char buff[100]; - lua_pushintegral(L, pc+1); - lua_pushstring(L, buildop(p, pc, buff)); - lua_settable(L, -3); - } - return 1; -} - - -static int listk (lua_State *L) { - Proto *p; - int i; - luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), - 1, "Lua function expected"); - p = clvalue(func_at(L, 1))->l.p; - lua_newtable(L); - for (i=0; isizek; i++) { - lua_pushintegral(L, i+1); - luaA_pushobject(L, p->k+i); - lua_settable(L, -3); - } - return 1; -} - - -static int listlocals (lua_State *L) { - Proto *p; - int pc = luaL_checkint(L, 2) - 1; - int i = 0; - const char *name; - luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), - 1, "Lua function expected"); - p = clvalue(func_at(L, 1))->l.p; - while ((name = luaF_getlocalname(p, ++i, pc)) != NULL) - lua_pushstring(L, name); - return i-1; -} - -/* }====================================================== */ - - - - -static int get_limits (lua_State *L) { - lua_newtable(L); - setnameval(L, "BITS_INT", BITS_INT); - setnameval(L, "LFPF", LFIELDS_PER_FLUSH); - setnameval(L, "MAXVARS", MAXVARS); - setnameval(L, "MAXPARAMS", MAXPARAMS); - setnameval(L, "MAXSTACK", MAXSTACK); - setnameval(L, "MAXUPVALUES", MAXUPVALUES); - return 1; -} - - -static int mem_query (lua_State *L) { - if (lua_isnone(L, 1)) { - lua_pushintegral(L, memdebug_total); - lua_pushintegral(L, memdebug_numblocks); - lua_pushintegral(L, memdebug_maxmem); - return 3; - } - else { - memdebug_memlimit = luaL_checkint(L, 1); - return 0; - } -} - - -static int hash_query (lua_State *L) { - if (lua_isnone(L, 2)) { - luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected"); - lua_pushintegral(L, tsvalue(func_at(L, 1))->tsv.hash); - } - else { - TObject *o = func_at(L, 1); - Table *t; - luaL_checktype(L, 2, LUA_TTABLE); - t = hvalue(func_at(L, 2)); - lua_pushintegral(L, luaH_mainposition(t, o) - t->node); - } - return 1; -} - - -static int stacklevel (lua_State *L) { - unsigned long a = 0; - lua_pushintegral(L, (int)(L->top - L->stack)); - lua_pushintegral(L, (int)(L->stack_last - L->stack)); - lua_pushintegral(L, (int)(L->ci - L->base_ci)); - lua_pushintegral(L, (int)(L->end_ci - L->base_ci)); - lua_pushintegral(L, (unsigned long)&a); - return 5; -} - - -static int table_query (lua_State *L) { - const Table *t; - int i = luaL_optint(L, 2, -1); - luaL_checktype(L, 1, LUA_TTABLE); - t = hvalue(func_at(L, 1)); - if (i == -1) { - lua_pushintegral(L, t->sizearray); - lua_pushintegral(L, sizenode(t)); - lua_pushintegral(L, t->firstfree - t->node); - } - else if (i < t->sizearray) { - lua_pushintegral(L, i); - luaA_pushobject(L, &t->array[i]); - lua_pushnil(L); - } - else if ((i -= t->sizearray) < sizenode(t)) { - if (!ttisnil(gval(gnode(t, i))) || - ttisnil(gkey(gnode(t, i))) || - ttisnumber(gkey(gnode(t, i)))) { - luaA_pushobject(L, gkey(gnode(t, i))); - } - else - lua_pushstring(L, ""); - luaA_pushobject(L, gval(gnode(t, i))); - if (t->node[i].next) - lua_pushintegral(L, t->node[i].next - t->node); - else - lua_pushnil(L); - } - return 3; -} - - -static int string_query (lua_State *L) { - stringtable *tb = &G(L)->strt; - int s = luaL_optint(L, 2, 0) - 1; - if (s==-1) { - lua_pushintegral(L ,tb->nuse); - lua_pushintegral(L ,tb->size); - return 2; - } - else if (s < tb->size) { - GCObject *ts; - int n = 0; - for (ts = tb->hash[s]; ts; ts = ts->gch.next) { - setsvalue2s(L->top, gcotots(ts)); - incr_top(L); - n++; - } - return n; - } - return 0; -} - - -static int tref (lua_State *L) { - int level = lua_gettop(L); - int lock = luaL_optint(L, 2, 1); - luaL_checkany(L, 1); - lua_pushvalue(L, 1); - lua_pushintegral(L, lua_ref(L, lock)); - assert(lua_gettop(L) == level+1); /* +1 for result */ - return 1; -} - -static int getref (lua_State *L) { - int level = lua_gettop(L); - lua_getref(L, luaL_checkint(L, 1)); - assert(lua_gettop(L) == level+1); - return 1; -} - -static int unref (lua_State *L) { - int level = lua_gettop(L); - lua_unref(L, luaL_checkint(L, 1)); - assert(lua_gettop(L) == level); - return 0; -} - -static int metatable (lua_State *L) { - luaL_checkany(L, 1); - if (lua_isnone(L, 2)) { - if (lua_getmetatable(L, 1) == 0) - lua_pushnil(L); - } - else { - lua_settop(L, 2); - luaL_checktype(L, 2, LUA_TTABLE); - lua_setmetatable(L, 1); - } - return 1; -} - - -static int upvalue (lua_State *L) { - int n = luaL_checkint(L, 2); - luaL_checktype(L, 1, LUA_TFUNCTION); - if (lua_isnone(L, 3)) { - const char *name = lua_getupvalue(L, 1, n); - if (name == NULL) return 0; - lua_pushstring(L, name); - return 2; - } - else { - const char *name = lua_setupvalue(L, 1, n); - lua_pushstring(L, name); - return 1; - } -} - - -static int newuserdata (lua_State *L) { - size_t size = luaL_checkint(L, 1); - char *p = cast(char *, lua_newuserdata(L, size)); - while (size--) *p++ = '\0'; - return 1; -} - - -static int pushuserdata (lua_State *L) { - lua_pushlightuserdata(L, cast(void *, luaL_checkint(L, 1))); - return 1; -} - - -static int udataval (lua_State *L) { - lua_pushintegral(L, cast(int, lua_touserdata(L, 1))); - return 1; -} - - -static int doonnewstack (lua_State *L) { - lua_State *L1 = lua_newthread(L); - size_t l; - const char *s = luaL_checklstring(L, 1, &l); - int status = luaL_loadbuffer(L1, s, l, s); - if (status == 0) - status = lua_pcall(L1, 0, 0, 0); - lua_pushintegral(L, status); - return 1; -} - - -static int s2d (lua_State *L) { - lua_pushnumber(L, *cast(const double *, luaL_checkstring(L, 1))); - return 1; -} - -static int d2s (lua_State *L) { - double d = luaL_checknumber(L, 1); - lua_pushlstring(L, cast(char *, &d), sizeof(d)); - return 1; -} - - -static int newstate (lua_State *L) { - lua_State *L1 = lua_open(); - if (L1) { - lua_userstateopen(L1); /* init lock */ - lua_pushintegral(L, (unsigned long)L1); - } - else - lua_pushnil(L); - return 1; -} - - -static int loadlib (lua_State *L) { - static const luaL_reg libs[] = { - {"mathlibopen", luaopen_math}, - {"strlibopen", luaopen_string}, - {"iolibopen", luaopen_io}, - {"tablibopen", luaopen_table}, - {"dblibopen", luaopen_debug}, - {"baselibopen", luaopen_base}, - {NULL, NULL} - }; - lua_State *L1 = cast(lua_State *, - cast(unsigned long, luaL_checknumber(L, 1))); - lua_pushvalue(L1, LUA_GLOBALSINDEX); - luaL_openlib(L1, NULL, libs, 0); - return 0; -} - -static int closestate (lua_State *L) { - lua_State *L1 = cast(lua_State *, cast(unsigned long, luaL_checknumber(L, 1))); - lua_close(L1); - lua_unlock(L); /* close cannot unlock that */ - return 0; -} - -static int doremote (lua_State *L) { - lua_State *L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1))); - size_t lcode; - const char *code = luaL_checklstring(L, 2, &lcode); - int status; - lua_settop(L1, 0); - status = luaL_loadbuffer(L1, code, lcode, code); - if (status == 0) - status = lua_pcall(L1, 0, LUA_MULTRET, 0); - if (status != 0) { - lua_pushnil(L); - lua_pushintegral(L, status); - lua_pushstring(L, lua_tostring(L1, -1)); - return 3; - } - else { - int i = 0; - while (!lua_isnone(L1, ++i)) - lua_pushstring(L, lua_tostring(L1, i)); - lua_pop(L1, i-1); - return i-1; - } -} - - -static int log2_aux (lua_State *L) { - lua_pushintegral(L, luaO_log2(luaL_checkint(L, 1))); - return 1; -} - -static int int2fb_aux (lua_State *L) { - int b = luaO_int2fb(luaL_checkint(L, 1)); - lua_pushintegral(L, b); - lua_pushintegral(L, fb2int(b)); - return 2; -} - - -static int test_do (lua_State *L) { - const char *p = luaL_checkstring(L, 1); - if (*p == '@') - lua_dofile(L, p+1); - else - lua_dostring(L, p); - return lua_gettop(L); -} - - - -/* -** {====================================================== -** function to test the API with C. It interprets a kind of assembler -** language with calls to the API, so the test can be driven by Lua code -** ======================================================= -*/ - -static const char *const delimits = " \t\n,;"; - -static void skip (const char **pc) { - while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++; -} - -static int getnum_aux (lua_State *L, const char **pc) { - int res = 0; - int sig = 1; - skip(pc); - if (**pc == '.') { - res = cast(int, lua_tonumber(L, -1)); - lua_pop(L, 1); - (*pc)++; - return res; - } - else if (**pc == '-') { - sig = -1; - (*pc)++; - } - while (isdigit(cast(int, **pc))) res = res*10 + (*(*pc)++) - '0'; - return sig*res; -} - -static const char *getname_aux (char *buff, const char **pc) { - int i = 0; - skip(pc); - while (**pc != '\0' && !strchr(delimits, **pc)) - buff[i++] = *(*pc)++; - buff[i] = '\0'; - return buff; -} - - -#define EQ(s1) (strcmp(s1, inst) == 0) - -#define getnum (getnum_aux(L, &pc)) -#define getname (getname_aux(buff, &pc)) - - -static int testC (lua_State *L) { - char buff[30]; - const char *pc = luaL_checkstring(L, 1); - for (;;) { - const char *inst = getname; - if EQ("") return 0; - else if EQ("isnumber") { - lua_pushintegral(L, lua_isnumber(L, getnum)); - } - else if EQ("isstring") { - lua_pushintegral(L, lua_isstring(L, getnum)); - } - else if EQ("istable") { - lua_pushintegral(L, lua_istable(L, getnum)); - } - else if EQ("iscfunction") { - lua_pushintegral(L, lua_iscfunction(L, getnum)); - } - else if EQ("isfunction") { - lua_pushintegral(L, lua_isfunction(L, getnum)); - } - else if EQ("isuserdata") { - lua_pushintegral(L, lua_isuserdata(L, getnum)); - } - else if EQ("isudataval") { - lua_pushintegral(L, lua_islightuserdata(L, getnum)); - } - else if EQ("isnil") { - lua_pushintegral(L, lua_isnil(L, getnum)); - } - else if EQ("isnull") { - lua_pushintegral(L, lua_isnone(L, getnum)); - } - else if EQ("tonumber") { - lua_pushnumber(L, lua_tonumber(L, getnum)); - } - else if EQ("tostring") { - const char *s = lua_tostring(L, getnum); - lua_pushstring(L, s); - } - else if EQ("strlen") { - lua_pushintegral(L, lua_strlen(L, getnum)); - } - else if EQ("tocfunction") { - lua_pushcfunction(L, lua_tocfunction(L, getnum)); - } - else if EQ("return") { - return getnum; - } - else if EQ("gettop") { - lua_pushintegral(L, lua_gettop(L)); - } - else if EQ("settop") { - lua_settop(L, getnum); - } - else if EQ("pop") { - lua_pop(L, getnum); - } - else if EQ("pushnum") { - lua_pushintegral(L, getnum); - } - else if EQ("pushnil") { - lua_pushnil(L); - } - else if EQ("pushbool") { - lua_pushboolean(L, getnum); - } - else if EQ("tobool") { - lua_pushintegral(L, lua_toboolean(L, getnum)); - } - else if EQ("pushvalue") { - lua_pushvalue(L, getnum); - } - else if EQ("pushcclosure") { - lua_pushcclosure(L, testC, getnum); - } - else if EQ("pushupvalues") { - lua_pushupvalues(L); - } - else if EQ("remove") { - lua_remove(L, getnum); - } - else if EQ("insert") { - lua_insert(L, getnum); - } - else if EQ("replace") { - lua_replace(L, getnum); - } - else if EQ("gettable") { - lua_gettable(L, getnum); - } - else if EQ("settable") { - lua_settable(L, getnum); - } - else if EQ("next") { - lua_next(L, -2); - } - else if EQ("concat") { - lua_concat(L, getnum); - } - else if EQ("lessthan") { - int a = getnum; - lua_pushboolean(L, lua_lessthan(L, a, getnum)); - } - else if EQ("equal") { - int a = getnum; - lua_pushboolean(L, lua_equal(L, a, getnum)); - } - else if EQ("rawcall") { - int narg = getnum; - int nres = getnum; - lua_call(L, narg, nres); - } - else if EQ("call") { - int narg = getnum; - int nres = getnum; - lua_pcall(L, narg, nres, 0); - } - else if EQ("loadstring") { - size_t sl; - const char *s = luaL_checklstring(L, getnum, &sl); - luaL_loadbuffer(L, s, sl, s); - } - else if EQ("loadfile") { - luaL_loadfile(L, luaL_checkstring(L, getnum)); - } - else if EQ("setmetatable") { - lua_setmetatable(L, getnum); - } - else if EQ("getmetatable") { - if (lua_getmetatable(L, getnum) == 0) - lua_pushnil(L); - } - else if EQ("type") { - lua_pushstring(L, lua_typename(L, lua_type(L, getnum))); - } - else if EQ("getn") { - int i = getnum; - lua_pushintegral(L, luaL_getn(L, i)); - } - else if EQ("setn") { - int i = getnum; - int n = cast(int, lua_tonumber(L, -1)); - luaL_setn(L, i, n); - lua_pop(L, 1); - } - else luaL_error(L, "unknown instruction %s", buff); - } - return 0; -} - -/* }====================================================== */ - - -/* -** {====================================================== -** tests for yield inside hooks -** ======================================================= -*/ - -static void yieldf (lua_State *L, lua_Debug *ar) { - lua_yield(L, 0); -} - -static int setyhook (lua_State *L) { - if (lua_isnoneornil(L, 1)) - lua_sethook(L, NULL, 0, 0); /* turn off hooks */ - else { - const char *smask = luaL_checkstring(L, 1); - int count = luaL_optint(L, 2, 0); - int mask = 0; - if (strchr(smask, 'l')) mask |= LUA_MASKLINE; - if (count > 0) mask |= LUA_MASKCOUNT; - lua_sethook(L, yieldf, mask, count); - } - return 0; -} - - -static int coresume (lua_State *L) { - int status; - lua_State *co = lua_tothread(L, 1); - luaL_argcheck(L, co, 1, "coroutine expected"); - status = lua_resume(co, 0); - if (status != 0) { - lua_pushboolean(L, 0); - lua_insert(L, -2); - return 2; /* return false + error message */ - } - else { - lua_pushboolean(L, 1); - return 1; - } -} - -/* }====================================================== */ - - - -static const struct luaL_reg tests_funcs[] = { - {"hash", hash_query}, - {"limits", get_limits}, - {"listcode", listcode}, - {"listk", listk}, - {"listlocals", listlocals}, - {"loadlib", loadlib}, - {"stacklevel", stacklevel}, - {"querystr", string_query}, - {"querytab", table_query}, - {"doit", test_do}, - {"testC", testC}, - {"ref", tref}, - {"getref", getref}, - {"unref", unref}, - {"d2s", d2s}, - {"s2d", s2d}, - {"metatable", metatable}, - {"upvalue", upvalue}, - {"newuserdata", newuserdata}, - {"pushuserdata", pushuserdata}, - {"udataval", udataval}, - {"doonnewstack", doonnewstack}, - {"newstate", newstate}, - {"closestate", closestate}, - {"doremote", doremote}, - {"log2", log2_aux}, - {"int2fb", int2fb_aux}, - {"totalmem", mem_query}, - {"resume", coresume}, - {"setyhook", setyhook}, - {NULL, NULL} -}; - - -static void fim (void) { - if (!islocked) - lua_close(lua_state); - lua_assert(memdebug_numblocks == 0); - lua_assert(memdebug_total == 0); -} - - -static int l_panic (lua_State *L) { - UNUSED(L); - fprintf(stderr, "unable to recover; exiting\n"); - return 0; -} - - -int luaB_opentests (lua_State *L) { - lua_atpanic(L, l_panic); - lua_userstateopen(L); /* init lock */ - lua_state = L; /* keep first state to be opened */ - luaL_openlib(L, "T", tests_funcs, 0); - atexit(fim); - return 0; -} - - -#undef main -int main (int argc, char *argv[]) { - char *limit = getenv("MEMLIMIT"); - if (limit) - memdebug_memlimit = strtoul(limit, NULL, 10); - l_main(argc, argv); - return 0; -} - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/ltm.c b/!NotAdopted/SmartAutoReplier/lualib/ltm.c deleted file mode 100644 index 1b3e515e57..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/ltm.c +++ /dev/null @@ -1,70 +0,0 @@ -/* -** $Id: ltm.c,v 1.106 2003/04/03 13:35:34 roberto Exp $ -** Tag methods -** See Copyright Notice in lua.h -*/ - - -#include - -#define ltm_c - -#include "lua.h" - -#include "lobject.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "ltm.h" - - - -const char *const luaT_typenames[] = { - "nil", "boolean", "userdata", "number", - "string", "table", "function", "userdata", "thread" -}; - - -void luaT_init (lua_State *L) { - static const char *const luaT_eventname[] = { /* ORDER TM */ - "__index", "__newindex", - "__gc", "__mode", "__eq", - "__add", "__sub", "__mul", "__div", - "__pow", "__unm", "__lt", "__le", - "__concat", "__call" - }; - int i; - for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); - luaS_fix(G(L)->tmname[i]); /* never collect these names */ - } -} - - -/* -** function to be used with macro "fasttm": optimized for absence of -** tag methods -*/ -const TObject *luaT_gettm (Table *events, TMS event, TString *ename) { - const TObject *tm = luaH_getstr(events, ename); - lua_assert(event <= TM_EQ); - if (ttisnil(tm)) { /* no tag method? */ - events->flags |= cast(lu_byte, 1u<tmname[event]; - switch (ttype(o)) { - case LUA_TTABLE: - return luaH_getstr(hvalue(o)->metatable, ename); - case LUA_TUSERDATA: - return luaH_getstr(uvalue(o)->uv.metatable, ename); - default: - return &luaO_nilobject; - } -} - diff --git a/!NotAdopted/SmartAutoReplier/lualib/ltm.h b/!NotAdopted/SmartAutoReplier/lualib/ltm.h deleted file mode 100644 index 8eebfd3dc3..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/ltm.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -** $Id: ltm.h,v 1.41 2002/11/14 11:51:50 roberto Exp $ -** Tag methods -** See Copyright Notice in lua.h -*/ - -#ifndef ltm_h -#define ltm_h - - -#include "lobject.h" - - -/* -* WARNING: if you change the order of this enumeration, -* grep "ORDER TM" -*/ -typedef enum { - TM_INDEX, - TM_NEWINDEX, - TM_GC, - TM_MODE, - TM_EQ, /* last tag method with `fast' access */ - TM_ADD, - TM_SUB, - TM_MUL, - TM_DIV, - TM_POW, - TM_UNM, - TM_LT, - TM_LE, - TM_CONCAT, - TM_CALL, - TM_N /* number of elements in the enum */ -} TMS; - - - -#define gfasttm(g,et,e) \ - (((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) - -#define fasttm(l,et,e) gfasttm(G(l), et, e) - - -const TObject *luaT_gettm (Table *events, TMS event, TString *ename); -const TObject *luaT_gettmbyobj (lua_State *L, const TObject *o, TMS event); -void luaT_init (lua_State *L); - -extern const char *const luaT_typenames[]; - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/lua.h b/!NotAdopted/SmartAutoReplier/lualib/lua.h deleted file mode 100644 index 0d827b10c7..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lua.h +++ /dev/null @@ -1,391 +0,0 @@ -/* -** $Id: lua.h,v 1.175 2003/03/18 12:31:39 roberto Exp $ -** Lua - An Extensible Extension Language -** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil -** http://www.lua.org mailto:info@lua.org -** See Copyright Notice at the end of this file -*/ - - -#ifndef lua_h -#define lua_h - -#include -#include - - -#define LUA_VERSION "Lua 5.0" -#define LUA_COPYRIGHT "Copyright (C) 1994-2003 Tecgraf, PUC-Rio" -#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" - - - -/* option for multiple returns in `lua_pcall' and `lua_call' */ -#define LUA_MULTRET (-1) - - -/* -** pseudo-indices -*/ -#define LUA_REGISTRYINDEX (-10000) -#define LUA_GLOBALSINDEX (-10001) -#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) - - -/* error codes for `lua_load' and `lua_pcall' */ -#define LUA_ERRRUN 1 -#define LUA_ERRFILE 2 -#define LUA_ERRSYNTAX 3 -#define LUA_ERRMEM 4 -#define LUA_ERRERR 5 - - -typedef struct lua_State lua_State; - -typedef int (*lua_CFunction) (lua_State *L); - - -/* -** functions that read/write blocks when loading/dumping Lua chunks -*/ -typedef const char * (*lua_Chunkreader) (lua_State *L, void *ud, size_t *sz); - -typedef int (*lua_Chunkwriter) (lua_State *L, const void* p, - size_t sz, void* ud); - - -/* -** basic types -*/ -#define LUA_TNONE (-1) - -#define LUA_TNIL 0 -#define LUA_TBOOLEAN 1 -#define LUA_TLIGHTUSERDATA 2 -#define LUA_TNUMBER 3 -#define LUA_TSTRING 4 -#define LUA_TTABLE 5 -#define LUA_TFUNCTION 6 -#define LUA_TUSERDATA 7 -#define LUA_TTHREAD 8 - - -/* minimum Lua stack available to a C function */ -#define LUA_MINSTACK 20 - - -/* -** generic extra include file -*/ -#ifdef LUA_USER_H -#include LUA_USER_H -#endif - - -/* type of numbers in Lua */ -#ifndef LUA_NUMBER -typedef double lua_Number; -#else -typedef LUA_NUMBER lua_Number; -#endif - - -/* mark for all API functions */ -#ifndef LUA_API -#define LUA_API extern -#endif - - -/* -** state manipulation -*/ -LUA_API lua_State *lua_open (void); -LUA_API void lua_close (lua_State *L); -LUA_API lua_State *lua_newthread (lua_State *L); - -LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf); - - -/* -** basic stack manipulation -*/ -LUA_API int lua_gettop (lua_State *L); -LUA_API void lua_settop (lua_State *L, int idx); -LUA_API void lua_pushvalue (lua_State *L, int idx); -LUA_API void lua_remove (lua_State *L, int idx); -LUA_API void lua_insert (lua_State *L, int idx); -LUA_API void lua_replace (lua_State *L, int idx); -LUA_API int lua_checkstack (lua_State *L, int sz); - -LUA_API void lua_xmove (lua_State *from, lua_State *to, int n); - - -/* -** access functions (stack -> C) -*/ - -LUA_API int lua_isnumber (lua_State *L, int idx); -LUA_API int lua_isstring (lua_State *L, int idx); -LUA_API int lua_iscfunction (lua_State *L, int idx); -LUA_API int lua_isuserdata (lua_State *L, int idx); -LUA_API int lua_type (lua_State *L, int idx); -LUA_API const char *lua_typename (lua_State *L, int tp); - -LUA_API int lua_equal (lua_State *L, int idx1, int idx2); -LUA_API int lua_rawequal (lua_State *L, int idx1, int idx2); -LUA_API int lua_lessthan (lua_State *L, int idx1, int idx2); - -LUA_API lua_Number lua_tonumber (lua_State *L, int idx); -LUA_API int lua_toboolean (lua_State *L, int idx); -LUA_API const char *lua_tostring (lua_State *L, int idx); -LUA_API size_t lua_strlen (lua_State *L, int idx); -LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx); -LUA_API void *lua_touserdata (lua_State *L, int idx); -LUA_API lua_State *lua_tothread (lua_State *L, int idx); -LUA_API const void *lua_topointer (lua_State *L, int idx); - - -/* -** push functions (C -> stack) -*/ -LUA_API void lua_pushnil (lua_State *L); -LUA_API void lua_pushnumber (lua_State *L, lua_Number n); -LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t l); -LUA_API void lua_pushstring (lua_State *L, const char *s); -LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, - va_list argp); -LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...); -LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); -LUA_API void lua_pushboolean (lua_State *L, int b); -LUA_API void lua_pushlightuserdata (lua_State *L, void *p); - - -/* -** get functions (Lua -> stack) -*/ -LUA_API void lua_gettable (lua_State *L, int idx); -LUA_API void lua_rawget (lua_State *L, int idx); -LUA_API void lua_rawgeti (lua_State *L, int idx, int n); -LUA_API void lua_newtable (lua_State *L); -LUA_API void *lua_newuserdata (lua_State *L, size_t sz); -LUA_API int lua_getmetatable (lua_State *L, int objindex); -LUA_API void lua_getfenv (lua_State *L, int idx); - - -/* -** set functions (stack -> Lua) -*/ -LUA_API void lua_settable (lua_State *L, int idx); -LUA_API void lua_rawset (lua_State *L, int idx); -LUA_API void lua_rawseti (lua_State *L, int idx, int n); -LUA_API int lua_setmetatable (lua_State *L, int objindex); -LUA_API int lua_setfenv (lua_State *L, int idx); - - -/* -** `load' and `call' functions (load and run Lua code) -*/ -LUA_API void lua_call (lua_State *L, int nargs, int nresults); -LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc); -LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud); -LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *dt, - const char *chunkname); - -LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data); - - -/* -** coroutine functions -*/ -LUA_API int lua_yield (lua_State *L, int nresults); -LUA_API int lua_resume (lua_State *L, int narg); - -/* -** garbage-collection functions -*/ -LUA_API int lua_getgcthreshold (lua_State *L); -LUA_API int lua_getgccount (lua_State *L); -LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold); - -/* -** miscellaneous functions -*/ - -LUA_API const char *lua_version (void); - -LUA_API int lua_error (lua_State *L); - -LUA_API int lua_next (lua_State *L, int idx); - -LUA_API void lua_concat (lua_State *L, int n); - - - -/* -** =============================================================== -** some useful macros -** =============================================================== -*/ - -#define lua_boxpointer(L,u) \ - (*(void **)(lua_newuserdata(L, sizeof(void *))) = (u)) - -#define lua_unboxpointer(L,i) (*(void **)(lua_touserdata(L, i))) - -#define lua_pop(L,n) lua_settop(L, -(n)-1) - -#define lua_register(L,n,f) \ - (lua_pushstring(L, n), \ - lua_pushcfunction(L, f), \ - lua_settable(L, LUA_GLOBALSINDEX)) - -#define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0) - -#define lua_isfunction(L,n) (lua_type(L,n) == LUA_TFUNCTION) -#define lua_istable(L,n) (lua_type(L,n) == LUA_TTABLE) -#define lua_islightuserdata(L,n) (lua_type(L,n) == LUA_TLIGHTUSERDATA) -#define lua_isnil(L,n) (lua_type(L,n) == LUA_TNIL) -#define lua_isboolean(L,n) (lua_type(L,n) == LUA_TBOOLEAN) -#define lua_isnone(L,n) (lua_type(L,n) == LUA_TNONE) -#define lua_isnoneornil(L, n) (lua_type(L,n) <= 0) - -#define lua_pushliteral(L, s) \ - lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) - - - -/* -** compatibility macros and functions -*/ - - -LUA_API int lua_pushupvalues (lua_State *L); - -#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) -#define lua_setglobal(L,s) \ - (lua_pushstring(L, s), lua_insert(L, -2), lua_settable(L, LUA_GLOBALSINDEX)) - -#define lua_getglobal(L,s) \ - (lua_pushstring(L, s), lua_gettable(L, LUA_GLOBALSINDEX)) - - -/* compatibility with ref system */ - -/* pre-defined references */ -#define LUA_NOREF (-2) -#define LUA_REFNIL (-1) - -#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ - (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) - -#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) - -#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, ref) - - - -/* -** {====================================================================== -** useful definitions for Lua kernel and libraries -** ======================================================================= -*/ - -/* formats for Lua numbers */ -#ifndef LUA_NUMBER_SCAN -#define LUA_NUMBER_SCAN "%lf" -#endif - -#ifndef LUA_NUMBER_FMT -#define LUA_NUMBER_FMT "%.14g" -#endif - -/* }====================================================================== */ - - -/* -** {====================================================================== -** Debug API -** ======================================================================= -*/ - - -/* -** Event codes -*/ -#define LUA_HOOKCALL 0 -#define LUA_HOOKRET 1 -#define LUA_HOOKLINE 2 -#define LUA_HOOKCOUNT 3 -#define LUA_HOOKTAILRET 4 - - -/* -** Event masks -*/ -#define LUA_MASKCALL (1 << LUA_HOOKCALL) -#define LUA_MASKRET (1 << LUA_HOOKRET) -#define LUA_MASKLINE (1 << LUA_HOOKLINE) -#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) - -typedef struct lua_Debug lua_Debug; /* activation record */ - -typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); - - -LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); -LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); -LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); -LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); -LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); -LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); - -LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); -LUA_API lua_Hook lua_gethook (lua_State *L); -LUA_API int lua_gethookmask (lua_State *L); -LUA_API int lua_gethookcount (lua_State *L); - - -#define LUA_IDSIZE 60 - -struct lua_Debug { - int event; - const char *name; /* (n) */ - const char *namewhat; /* (n) `global', `local', `field', `method' */ - const char *what; /* (S) `Lua', `C', `main', `tail' */ - const char *source; /* (S) */ - int currentline; /* (l) */ - int nups; /* (u) number of upvalues */ - int linedefined; /* (S) */ - char short_src[LUA_IDSIZE]; /* (S) */ - /* private part */ - int i_ci; /* active function */ -}; - -/* }====================================================================== */ - - -/****************************************************************************** -* Copyright (C) 1994-2003 Tecgraf, PUC-Rio. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be -* included in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -******************************************************************************/ - - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/luainc.h b/!NotAdopted/SmartAutoReplier/lualib/luainc.h deleted file mode 100644 index 1306197b64..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/luainc.h +++ /dev/null @@ -1,12 +0,0 @@ - -#ifndef __LUA_INC_H__ -#define __LUA_INC_H__ - -extern "C" -{ - #include "lualib/lua.h" - #include "lualib/lauxlib.h" - #include "lualib/lualib.h" -} - -#endif // __LUA_INC_H__ \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/lualib/lualib.h b/!NotAdopted/SmartAutoReplier/lualib/lualib.h deleted file mode 100644 index e22c4c3063..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lualib.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -** $Id: lualib.h,v 1.28 2003/03/18 12:24:26 roberto Exp $ -** Lua standard libraries -** See Copyright Notice in lua.h -*/ - - -#ifndef lualib_h -#define lualib_h - -#include "lua.h" - - -#ifndef LUALIB_API -#define LUALIB_API LUA_API -#endif - - -#define LUA_COLIBNAME "coroutine" -LUALIB_API int luaopen_base (lua_State *L); - -#define LUA_TABLIBNAME "table" -LUALIB_API int luaopen_table (lua_State *L); - -#define LUA_IOLIBNAME "io" -#define LUA_OSLIBNAME "os" -LUALIB_API int luaopen_io (lua_State *L); - -#define LUA_STRLIBNAME "string" -LUALIB_API int luaopen_string (lua_State *L); - -#define LUA_MATHLIBNAME "math" -LUALIB_API int luaopen_math (lua_State *L); - -#define LUA_DBLIBNAME "debug" -LUALIB_API int luaopen_debug (lua_State *L); - - -LUALIB_API int luaopen_loadlib (lua_State *L); - - -/* to help testing the libraries */ -#ifndef lua_assert -#define lua_assert(c) /* empty */ -#endif - - -/* compatibility code */ -#define lua_baselibopen luaopen_base -#define lua_tablibopen luaopen_table -#define lua_iolibopen luaopen_io -#define lua_strlibopen luaopen_string -#define lua_mathlibopen luaopen_math -#define lua_dblibopen luaopen_debug - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/lualib.vcxproj b/!NotAdopted/SmartAutoReplier/lualib/lualib.vcxproj deleted file mode 100644 index b7618412cf..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lualib.vcxproj +++ /dev/null @@ -1,138 +0,0 @@ -п»ї - - - - Debug - Win32 - - - Release - Win32 - - - - {6DB53D29-2EA9-407B-84F3-06E8031F3314} - Win32Proj - lualib - - - - StaticLibrary - true - Unicode - - - StaticLibrary - false - true - Unicode - - - - - - - - - - - - - - - NotUsing - Level3 - Disabled - WIN32;_DEBUG;_LIB - MultiThreadedDebug - - - Windows - true - - - - - Level3 - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreaded - - - Windows - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - - - - - - \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/lualib/lualib.vcxproj.filters b/!NotAdopted/SmartAutoReplier/lualib/lualib.vcxproj.filters deleted file mode 100644 index a224003846..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lualib.vcxproj.filters +++ /dev/null @@ -1,186 +0,0 @@ -п»ї - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/lualib/lundump.c b/!NotAdopted/SmartAutoReplier/lualib/lundump.c deleted file mode 100644 index 151a8507cc..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lundump.c +++ /dev/null @@ -1,286 +0,0 @@ -/* -** $Id: lundump.c,v 1.49 2003/04/07 20:34:20 lhf Exp $ -** load pre-compiled Lua chunks -** See Copyright Notice in lua.h -*/ - -#define lundump_c - -#include "lua.h" - -#include "ldebug.h" -#include "lfunc.h" -#include "lmem.h" -#include "lopcodes.h" -#include "lstring.h" -#include "lundump.h" -#include "lzio.h" - -#define LoadByte (lu_byte) ezgetc - -typedef struct { - lua_State* L; - ZIO* Z; - Mbuffer* b; - int swap; - const char* name; -} LoadState; - -static void unexpectedEOZ (LoadState* S) -{ - luaG_runerror(S->L,"unexpected end of file in %s",S->name); -} - -static int ezgetc (LoadState* S) -{ - int c=zgetc(S->Z); - if (c==EOZ) unexpectedEOZ(S); - return c; -} - -static void ezread (LoadState* S, void* b, int n) -{ - int r=luaZ_read(S->Z,b,n); - if (r!=0) unexpectedEOZ(S); -} - -static void LoadBlock (LoadState* S, void* b, size_t size) -{ - if (S->swap) - { - char* p=(char*) b+size-1; - int n=size; - while (n--) *p--=(char)ezgetc(S); - } - else - ezread(S,b,size); -} - -static void LoadVector (LoadState* S, void* b, int m, size_t size) -{ - if (S->swap) - { - char* q=(char*) b; - while (m--) - { - char* p=q+size-1; - int n=size; - while (n--) *p--=(char)ezgetc(S); - q+=size; - } - } - else - ezread(S,b,m*size); -} - -static int LoadInt (LoadState* S) -{ - int x; - LoadBlock(S,&x,sizeof(x)); - if (x<0) luaG_runerror(S->L,"bad integer in %s",S->name); - return x; -} - -static size_t LoadSize (LoadState* S) -{ - size_t x; - LoadBlock(S,&x,sizeof(x)); - return x; -} - -static lua_Number LoadNumber (LoadState* S) -{ - lua_Number x; - LoadBlock(S,&x,sizeof(x)); - return x; -} - -static TString* LoadString (LoadState* S) -{ - size_t size=LoadSize(S); - if (size==0) - return NULL; - else - { - char* s=luaZ_openspace(S->L,S->b,size); - ezread(S,s,size); - return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ - } -} - -static void LoadCode (LoadState* S, Proto* f) -{ - int size=LoadInt(S); - f->code=luaM_newvector(S->L,size,Instruction); - f->sizecode=size; - LoadVector(S,f->code,size,sizeof(*f->code)); -} - -static void LoadLocals (LoadState* S, Proto* f) -{ - int i,n; - n=LoadInt(S); - f->locvars=luaM_newvector(S->L,n,LocVar); - f->sizelocvars=n; - for (i=0; ilocvars[i].varname=LoadString(S); - f->locvars[i].startpc=LoadInt(S); - f->locvars[i].endpc=LoadInt(S); - } -} - -static void LoadLines (LoadState* S, Proto* f) -{ - int size=LoadInt(S); - f->lineinfo=luaM_newvector(S->L,size,int); - f->sizelineinfo=size; - LoadVector(S,f->lineinfo,size,sizeof(*f->lineinfo)); -} - -static void LoadUpvalues (LoadState* S, Proto* f) -{ - int i,n; - n=LoadInt(S); - if (n!=0 && n!=f->nups) - luaG_runerror(S->L,"bad nupvalues in %s: read %d; expected %d", - S->name,n,f->nups); - f->upvalues=luaM_newvector(S->L,n,TString*); - f->sizeupvalues=n; - for (i=0; iupvalues[i]=LoadString(S); -} - -static Proto* LoadFunction (LoadState* S, TString* p); - -static void LoadConstants (LoadState* S, Proto* f) -{ - int i,n; - n=LoadInt(S); - f->k=luaM_newvector(S->L,n,TObject); - f->sizek=n; - for (i=0; ik[i]; - int t=LoadByte(S); - switch (t) - { - case LUA_TNUMBER: - setnvalue(o,LoadNumber(S)); - break; - case LUA_TSTRING: - setsvalue2n(o,LoadString(S)); - break; - case LUA_TNIL: - setnilvalue(o); - break; - default: - luaG_runerror(S->L,"bad constant type (%d) in %s",t,S->name); - break; - } - } - n=LoadInt(S); - f->p=luaM_newvector(S->L,n,Proto*); - f->sizep=n; - for (i=0; ip[i]=LoadFunction(S,f->source); -} - -static Proto* LoadFunction (LoadState* S, TString* p) -{ - Proto* f=luaF_newproto(S->L); - f->source=LoadString(S); if (f->source==NULL) f->source=p; - f->lineDefined=LoadInt(S); - f->nups=LoadByte(S); - f->numparams=LoadByte(S); - f->is_vararg=LoadByte(S); - f->maxstacksize=LoadByte(S); - LoadLines(S,f); - LoadLocals(S,f); - LoadUpvalues(S,f); - LoadConstants(S,f); - LoadCode(S,f); -#ifndef TRUST_BINARIES - if (!luaG_checkcode(f)) luaG_runerror(S->L,"bad code in %s",S->name); -#endif - return f; -} - -static void LoadSignature (LoadState* S) -{ - const char* s=LUA_SIGNATURE; - while (*s!=0 && ezgetc(S)==*s) - ++s; - if (*s!=0) luaG_runerror(S->L,"bad signature in %s",S->name); -} - -static void TestSize (LoadState* S, int s, const char* what) -{ - int r=LoadByte(S); - if (r!=s) - luaG_runerror(S->L,"virtual machine mismatch in %s: " - "size of %s is %d but read %d",S->name,what,s,r); -} - -#define TESTSIZE(s,w) TestSize(S,s,w) -#define V(v) v/16,v%16 - -static void LoadHeader (LoadState* S) -{ - int version; - lua_Number x,tx=TEST_NUMBER; - LoadSignature(S); - version=LoadByte(S); - if (version>VERSION) - luaG_runerror(S->L,"%s too new: " - "read version %d.%d; expected at most %d.%d", - S->name,V(version),V(VERSION)); - if (versionL,"%s too old: " - "read version %d.%d; expected at least %d.%d", - S->name,V(version),V(VERSION0)); - S->swap=(luaU_endianness()!=LoadByte(S)); /* need to swap bytes? */ - TESTSIZE(sizeof(int),"int"); - TESTSIZE(sizeof(size_t), "size_t"); - TESTSIZE(sizeof(Instruction), "Instruction"); - TESTSIZE(SIZE_OP, "OP"); - TESTSIZE(SIZE_A, "A"); - TESTSIZE(SIZE_B, "B"); - TESTSIZE(SIZE_C, "C"); - TESTSIZE(sizeof(lua_Number), "number"); - x=LoadNumber(S); - if ((long)x!=(long)tx) /* disregard errors in last bits of fraction */ - luaG_runerror(S->L,"unknown number format in %s",S->name); -} - -static Proto* LoadChunk (LoadState* S) -{ - LoadHeader(S); - return LoadFunction(S,NULL); -} - -/* -** load precompiled chunk -*/ -Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff) -{ - LoadState S; - const char* s=zname(Z); - if (*s=='@' || *s=='=') - S.name=s+1; - else if (*s==LUA_SIGNATURE[0]) - S.name="binary string"; - else - S.name=s; - S.L=L; - S.Z=Z; - S.b=buff; - return LoadChunk(&S); -} - -/* -** find byte order -*/ -int luaU_endianness (void) -{ - int x=1; - return *(char*)&x; -} diff --git a/!NotAdopted/SmartAutoReplier/lualib/lundump.h b/!NotAdopted/SmartAutoReplier/lualib/lundump.h deleted file mode 100644 index c7e6959b30..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lundump.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -** $Id: lundump.h,v 1.30 2003/04/07 20:34:20 lhf Exp $ -** load pre-compiled Lua chunks -** See Copyright Notice in lua.h -*/ - -#ifndef lundump_h -#define lundump_h - -#include "lobject.h" -#include "lzio.h" - -/* load one chunk; from lundump.c */ -Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff); - -/* find byte order; from lundump.c */ -int luaU_endianness (void); - -/* dump one chunk; from ldump.c */ -void luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data); - -/* print one chunk; from print.c */ -void luaU_print (const Proto* Main); - -/* definitions for headers of binary files */ -#define LUA_SIGNATURE "\033Lua" /* binary files start with "Lua" */ -#define VERSION 0x50 /* last format change was in 5.0 */ -#define VERSION0 0x50 /* last major change was in 5.0 */ - -/* a multiple of PI for testing native format */ -/* multiplying by 1E7 gives non-trivial integer values */ -#define TEST_NUMBER ((lua_Number)3.14159265358979323846E7) - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/lvm.c b/!NotAdopted/SmartAutoReplier/lualib/lvm.c deleted file mode 100644 index eaa5c700b0..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lvm.c +++ /dev/null @@ -1,780 +0,0 @@ -/* -** $Id: lvm.c,v 1.284 2003/04/03 13:35:34 roberto Exp $ -** Lua virtual machine -** See Copyright Notice in lua.h -*/ - - -#include -#include -#include - -/* needed only when `lua_number2str' uses `sprintf' */ -#include - -#define lvm_c - -#include "lua.h" - -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "lgc.h" -#include "lobject.h" -#include "lopcodes.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "ltm.h" -#include "lvm.h" - - - -/* function to convert a lua_Number to a string */ -#ifndef lua_number2str -#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) -#endif - - -/* limit for table tag-method chains (to avoid loops) */ -#define MAXTAGLOOP 100 - - -const TObject *luaV_tonumber (const TObject *obj, TObject *n) { - lua_Number num; - if (ttisnumber(obj)) return obj; - if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { - setnvalue(n, num); - return n; - } - else - return NULL; -} - - -int luaV_tostring (lua_State *L, StkId obj) { - if (!ttisnumber(obj)) - return 0; - else { - char s[32]; /* 16 digits, sign, point and \0 (+ some extra...) */ - lua_number2str(s, nvalue(obj)); - setsvalue2s(obj, luaS_new(L, s)); - return 1; - } -} - - -static void traceexec (lua_State *L) { - lu_byte mask = L->hookmask; - if (mask > LUA_MASKLINE) { /* instruction-hook set? */ - if (L->hookcount == 0) { - resethookcount(L); - luaD_callhook(L, LUA_HOOKCOUNT, -1); - return; - } - } - if (mask & LUA_MASKLINE) { - CallInfo *ci = L->ci; - Proto *p = ci_func(ci)->l.p; - int newline = getline(p, pcRel(*ci->u.l.pc, p)); - if (!L->hookinit) { - luaG_inithooks(L); - return; - } - lua_assert(ci->state & CI_HASFRAME); - if (pcRel(*ci->u.l.pc, p) == 0) /* tracing may be starting now? */ - ci->u.l.savedpc = *ci->u.l.pc; /* initialize `savedpc' */ - /* calls linehook when enters a new line or jumps back (loop) */ - if (*ci->u.l.pc <= ci->u.l.savedpc || - newline != getline(p, pcRel(ci->u.l.savedpc, p))) { - luaD_callhook(L, LUA_HOOKLINE, newline); - ci = L->ci; /* previous call may reallocate `ci' */ - } - ci->u.l.savedpc = *ci->u.l.pc; - } -} - - -static void callTMres (lua_State *L, const TObject *f, - const TObject *p1, const TObject *p2) { - setobj2s(L->top, f); /* push function */ - setobj2s(L->top+1, p1); /* 1st argument */ - setobj2s(L->top+2, p2); /* 2nd argument */ - luaD_checkstack(L, 3); /* cannot check before (could invalidate p1, p2) */ - L->top += 3; - luaD_call(L, L->top - 3, 1); - L->top--; /* result will be in L->top */ -} - - - -static void callTM (lua_State *L, const TObject *f, - const TObject *p1, const TObject *p2, const TObject *p3) { - setobj2s(L->top, f); /* push function */ - setobj2s(L->top+1, p1); /* 1st argument */ - setobj2s(L->top+2, p2); /* 2nd argument */ - setobj2s(L->top+3, p3); /* 3th argument */ - luaD_checkstack(L, 4); /* cannot check before (could invalidate p1...p3) */ - L->top += 4; - luaD_call(L, L->top - 4, 0); -} - - -static const TObject *luaV_index (lua_State *L, const TObject *t, - TObject *key, int loop) { - const TObject *tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); - if (tm == NULL) return &luaO_nilobject; /* no TM */ - if (ttisfunction(tm)) { - callTMres(L, tm, t, key); - return L->top; - } - else return luaV_gettable(L, tm, key, loop); -} - -static const TObject *luaV_getnotable (lua_State *L, const TObject *t, - TObject *key, int loop) { - const TObject *tm = luaT_gettmbyobj(L, t, TM_INDEX); - if (ttisnil(tm)) - luaG_typeerror(L, t, "index"); - if (ttisfunction(tm)) { - callTMres(L, tm, t, key); - return L->top; - } - else return luaV_gettable(L, tm, key, loop); -} - - -/* -** Function to index a table. -** Receives the table at `t' and the key at `key'. -** leaves the result at `res'. -*/ -const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key, - int loop) { - if (loop > MAXTAGLOOP) - luaG_runerror(L, "loop in gettable"); - if (ttistable(t)) { /* `t' is a table? */ - Table *h = hvalue(t); - const TObject *v = luaH_get(h, key); /* do a primitive get */ - if (!ttisnil(v)) return v; - else return luaV_index(L, t, key, loop+1); - } - else return luaV_getnotable(L, t, key, loop+1); -} - - -/* -** Receives table at `t', key at `key' and value at `val'. -*/ -void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val) { - const TObject *tm; - int loop = 0; - do { - if (ttistable(t)) { /* `t' is a table? */ - Table *h = hvalue(t); - TObject *oldval = luaH_set(L, h, key); /* do a primitive set */ - if (!ttisnil(oldval) || /* result is no nil? */ - (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ - setobj2t(oldval, val); /* write barrier */ - return; - } - /* else will try the tag method */ - } - else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) - luaG_typeerror(L, t, "index"); - if (ttisfunction(tm)) { - callTM(L, tm, t, key, val); - return; - } - t = tm; /* else repeat with `tm' */ - } while (++loop <= MAXTAGLOOP); - luaG_runerror(L, "loop in settable"); -} - - -static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2, - StkId res, TMS event) { - ptrdiff_t result = savestack(L, res); - const TObject *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ - if (ttisnil(tm)) - tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ - if (!ttisfunction(tm)) return 0; - callTMres(L, tm, p1, p2); - res = restorestack(L, result); /* previous call may change stack */ - setobjs2s(res, L->top); - return 1; -} - - -static const TObject *get_compTM (lua_State *L, Table *mt1, Table *mt2, - TMS event) { - const TObject *tm1 = fasttm(L, mt1, event); - const TObject *tm2; - if (tm1 == NULL) return NULL; /* no metamethod */ - if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ - tm2 = fasttm(L, mt2, event); - if (tm2 == NULL) return NULL; /* no metamethod */ - if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */ - return tm1; - return NULL; -} - - -static int call_orderTM (lua_State *L, const TObject *p1, const TObject *p2, - TMS event) { - const TObject *tm1 = luaT_gettmbyobj(L, p1, event); - const TObject *tm2; - if (ttisnil(tm1)) return -1; /* no metamethod? */ - tm2 = luaT_gettmbyobj(L, p2, event); - if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ - return -1; - callTMres(L, tm1, p1, p2); - return !l_isfalse(L->top); -} - - -static int luaV_strcmp (const TString *ls, const TString *rs) { - const char *l = getstr(ls); - size_t ll = ls->tsv.len; - const char *r = getstr(rs); - size_t lr = rs->tsv.len; - for (;;) { - int temp = strcoll(l, r); - if (temp != 0) return temp; - else { /* strings are equal up to a `\0' */ - size_t len = strlen(l); /* index of first `\0' in both strings */ - if (len == lr) /* r is finished? */ - return (len == ll) ? 0 : 1; - else if (len == ll) /* l is finished? */ - return -1; /* l is smaller than r (because r is not finished) */ - /* both strings longer than `len'; go on comparing (after the `\0') */ - len++; - l += len; ll -= len; r += len; lr -= len; - } - } -} - - -int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) { - int res; - if (ttype(l) != ttype(r)) - return luaG_ordererror(L, l, r); - else if (ttisnumber(l)) - return nvalue(l) < nvalue(r); - else if (ttisstring(l)) - return luaV_strcmp(tsvalue(l), tsvalue(r)) < 0; - else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) - return res; - return luaG_ordererror(L, l, r); -} - - -static int luaV_lessequal (lua_State *L, const TObject *l, const TObject *r) { - int res; - if (ttype(l) != ttype(r)) - return luaG_ordererror(L, l, r); - else if (ttisnumber(l)) - return nvalue(l) <= nvalue(r); - else if (ttisstring(l)) - return luaV_strcmp(tsvalue(l), tsvalue(r)) <= 0; - else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ - return res; - else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ - return !res; - return luaG_ordererror(L, l, r); -} - - -int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2) { - const TObject *tm; - lua_assert(ttype(t1) == ttype(t2)); - switch (ttype(t1)) { - case LUA_TNIL: return 1; - case LUA_TNUMBER: return nvalue(t1) == nvalue(t2); - case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ - case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); - case LUA_TUSERDATA: { - if (uvalue(t1) == uvalue(t2)) return 1; - tm = get_compTM(L, uvalue(t1)->uv.metatable, uvalue(t2)->uv.metatable, - TM_EQ); - break; /* will try TM */ - } - case LUA_TTABLE: { - if (hvalue(t1) == hvalue(t2)) return 1; - tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); - break; /* will try TM */ - } - default: return gcvalue(t1) == gcvalue(t2); - } - if (tm == NULL) return 0; /* no TM? */ - callTMres(L, tm, t1, t2); /* call TM */ - return !l_isfalse(L->top); -} - - -void luaV_concat (lua_State *L, int total, int last) { - do { - StkId top = L->base + last + 1; - int n = 2; /* number of elements handled in this pass (at least 2) */ - if (!tostring(L, top-2) || !tostring(L, top-1)) { - if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) - luaG_concaterror(L, top-2, top-1); - } else if (tsvalue(top-1)->tsv.len > 0) { /* if len=0, do nothing */ - /* at least two string values; get as many as possible */ - lu_mem tl = cast(lu_mem, tsvalue(top-1)->tsv.len) + - cast(lu_mem, tsvalue(top-2)->tsv.len); - char *buffer; - int i; - while (n < total && tostring(L, top-n-1)) { /* collect total length */ - tl += tsvalue(top-n-1)->tsv.len; - n++; - } - if (tl > MAX_SIZET) luaG_runerror(L, "string size overflow"); - buffer = luaZ_openspace(L, &G(L)->buff, tl); - tl = 0; - for (i=n; i>0; i--) { /* concat all strings */ - size_t l = tsvalue(top-i)->tsv.len; - memcpy(buffer+tl, svalue(top-i), l); - tl += l; - } - setsvalue2s(top-n, luaS_newlstr(L, buffer, tl)); - } - total -= n-1; /* got `n' strings to create 1 new */ - last -= n-1; - } while (total > 1); /* repeat until only 1 result left */ -} - - -static void Arith (lua_State *L, StkId ra, - const TObject *rb, const TObject *rc, TMS op) { - TObject tempb, tempc; - const TObject *b, *c; - if ((b = luaV_tonumber(rb, &tempb)) != NULL && - (c = luaV_tonumber(rc, &tempc)) != NULL) { - switch (op) { - case TM_ADD: setnvalue(ra, nvalue(b) + nvalue(c)); break; - case TM_SUB: setnvalue(ra, nvalue(b) - nvalue(c)); break; - case TM_MUL: setnvalue(ra, nvalue(b) * nvalue(c)); break; - case TM_DIV: setnvalue(ra, nvalue(b) / nvalue(c)); break; - case TM_POW: { - const TObject *f = luaH_getstr(hvalue(gt(L)), G(L)->tmname[TM_POW]); - ptrdiff_t res = savestack(L, ra); - if (!ttisfunction(f)) - luaG_runerror(L, "`__pow' (`^' operator) is not a function"); - callTMres(L, f, b, c); - ra = restorestack(L, res); /* previous call may change stack */ - setobjs2s(ra, L->top); - break; - } - default: lua_assert(0); break; - } - } - else if (!call_binTM(L, rb, rc, ra, op)) - luaG_aritherror(L, rb, rc); -} - - - -/* -** some macros for common tasks in `luaV_execute' -*/ - -#define runtime_check(L, c) { if (!(c)) return 0; } - -#define RA(i) (base+GETARG_A(i)) -/* to be used after possible stack reallocation */ -#define XRA(i) (L->base+GETARG_A(i)) -#define RB(i) (base+GETARG_B(i)) -#define RKB(i) ((GETARG_B(i) < MAXSTACK) ? RB(i) : k+GETARG_B(i)-MAXSTACK) -#define RC(i) (base+GETARG_C(i)) -#define RKC(i) ((GETARG_C(i) < MAXSTACK) ? RC(i) : k+GETARG_C(i)-MAXSTACK) -#define KBx(i) (k+GETARG_Bx(i)) - - -#define dojump(pc, i) ((pc) += (i)) - - -StkId luaV_execute (lua_State *L) { - LClosure *cl; - TObject *k; - const Instruction *pc; - callentry: /* entry point when calling new functions */ - L->ci->u.l.pc = &pc; - if (L->hookmask & LUA_MASKCALL) - luaD_callhook(L, LUA_HOOKCALL, -1); - retentry: /* entry point when returning to old functions */ - lua_assert(L->ci->state == CI_SAVEDPC || - L->ci->state == (CI_SAVEDPC | CI_CALLING)); - L->ci->state = CI_HASFRAME; /* activate frame */ - pc = L->ci->u.l.savedpc; - cl = &clvalue(L->base - 1)->l; - k = cl->p->k; - /* main loop of interpreter */ - for (;;) { - const Instruction i = *pc++; - StkId base, ra; - if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && - (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { - traceexec(L); - if (L->ci->state & CI_YIELD) { /* did hook yield? */ - L->ci->u.l.savedpc = pc - 1; - L->ci->state = CI_YIELD | CI_SAVEDPC; - return NULL; - } - } - /* warning!! several calls may realloc the stack and invalidate `ra' */ - base = L->base; - ra = RA(i); - lua_assert(L->ci->state & CI_HASFRAME); - lua_assert(base == L->ci->base); - lua_assert(L->top <= L->stack + L->stacksize && L->top >= base); - lua_assert(L->top == L->ci->top || - GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || - GET_OPCODE(i) == OP_RETURN || GET_OPCODE(i) == OP_SETLISTO); - switch (GET_OPCODE(i)) { - case OP_MOVE: { - setobjs2s(ra, RB(i)); - break; - } - case OP_LOADK: { - setobj2s(ra, KBx(i)); - break; - } - case OP_LOADBOOL: { - setbvalue(ra, GETARG_B(i)); - if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ - break; - } - case OP_LOADNIL: { - TObject *rb = RB(i); - do { - setnilvalue(rb--); - } while (rb >= ra); - break; - } - case OP_GETUPVAL: { - int b = GETARG_B(i); - setobj2s(ra, cl->upvals[b]->v); - break; - } - case OP_GETGLOBAL: { - TObject *rb = KBx(i); - const TObject *v; - lua_assert(ttisstring(rb) && ttistable(&cl->g)); - v = luaH_getstr(hvalue(&cl->g), tsvalue(rb)); - if (!ttisnil(v)) { setobj2s(ra, v); } - else - setobj2s(XRA(i), luaV_index(L, &cl->g, rb, 0)); - break; - } - case OP_GETTABLE: { - StkId rb = RB(i); - TObject *rc = RKC(i); - if (ttistable(rb)) { - const TObject *v = luaH_get(hvalue(rb), rc); - if (!ttisnil(v)) { setobj2s(ra, v); } - else - setobj2s(XRA(i), luaV_index(L, rb, rc, 0)); - } - else - setobj2s(XRA(i), luaV_getnotable(L, rb, rc, 0)); - break; - } - case OP_SETGLOBAL: { - lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g)); - luaV_settable(L, &cl->g, KBx(i), ra); - break; - } - case OP_SETUPVAL: { - int b = GETARG_B(i); - setobj(cl->upvals[b]->v, ra); /* write barrier */ - break; - } - case OP_SETTABLE: { - luaV_settable(L, ra, RKB(i), RKC(i)); - break; - } - case OP_NEWTABLE: { - int b = GETARG_B(i); - b = fb2int(b); - sethvalue(ra, luaH_new(L, b, GETARG_C(i))); - luaC_checkGC(L); - break; - } - case OP_SELF: { - StkId rb = RB(i); - TObject *rc = RKC(i); - runtime_check(L, ttisstring(rc)); - setobjs2s(ra+1, rb); - if (ttistable(rb)) { - const TObject *v = luaH_getstr(hvalue(rb), tsvalue(rc)); - if (!ttisnil(v)) { setobj2s(ra, v); } - else - setobj2s(XRA(i), luaV_index(L, rb, rc, 0)); - } - else - setobj2s(XRA(i), luaV_getnotable(L, rb, rc, 0)); - break; - } - case OP_ADD: { - TObject *rb = RKB(i); - TObject *rc = RKC(i); - if (ttisnumber(rb) && ttisnumber(rc)) { - setnvalue(ra, nvalue(rb) + nvalue(rc)); - } - else - Arith(L, ra, rb, rc, TM_ADD); - break; - } - case OP_SUB: { - TObject *rb = RKB(i); - TObject *rc = RKC(i); - if (ttisnumber(rb) && ttisnumber(rc)) { - setnvalue(ra, nvalue(rb) - nvalue(rc)); - } - else - Arith(L, ra, rb, rc, TM_SUB); - break; - } - case OP_MUL: { - TObject *rb = RKB(i); - TObject *rc = RKC(i); - if (ttisnumber(rb) && ttisnumber(rc)) { - setnvalue(ra, nvalue(rb) * nvalue(rc)); - } - else - Arith(L, ra, rb, rc, TM_MUL); - break; - } - case OP_DIV: { - TObject *rb = RKB(i); - TObject *rc = RKC(i); - if (ttisnumber(rb) && ttisnumber(rc)) { - setnvalue(ra, nvalue(rb) / nvalue(rc)); - } - else - Arith(L, ra, rb, rc, TM_DIV); - break; - } - case OP_POW: { - Arith(L, ra, RKB(i), RKC(i), TM_POW); - break; - } - case OP_UNM: { - const TObject *rb = RB(i); - TObject temp; - if (tonumber(rb, &temp)) { - setnvalue(ra, -nvalue(rb)); - } - else { - setnilvalue(&temp); - if (!call_binTM(L, RB(i), &temp, ra, TM_UNM)) - luaG_aritherror(L, RB(i), &temp); - } - break; - } - case OP_NOT: { - int res = l_isfalse(RB(i)); /* next assignment may change this value */ - setbvalue(ra, res); - break; - } - case OP_CONCAT: { - int b = GETARG_B(i); - int c = GETARG_C(i); - luaV_concat(L, c-b+1, c); /* may change `base' (and `ra') */ - base = L->base; - setobjs2s(RA(i), base+b); - luaC_checkGC(L); - break; - } - case OP_JMP: { - dojump(pc, GETARG_sBx(i)); - break; - } - case OP_EQ: { - if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; - else dojump(pc, GETARG_sBx(*pc) + 1); - break; - } - case OP_LT: { - if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; - else dojump(pc, GETARG_sBx(*pc) + 1); - break; - } - case OP_LE: { - if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; - else dojump(pc, GETARG_sBx(*pc) + 1); - break; - } - case OP_TEST: { - TObject *rb = RB(i); - if (l_isfalse(rb) == GETARG_C(i)) pc++; - else { - setobjs2s(ra, rb); - dojump(pc, GETARG_sBx(*pc) + 1); - } - break; - } - case OP_CALL: - case OP_TAILCALL: { - StkId firstResult; - int b = GETARG_B(i); - int nresults; - if (b != 0) L->top = ra+b; /* else previous instruction set top */ - nresults = GETARG_C(i) - 1; - firstResult = luaD_precall(L, ra); - if (firstResult) { - if (firstResult > L->top) { /* yield? */ - lua_assert(L->ci->state == (CI_C | CI_YIELD)); - (L->ci - 1)->u.l.savedpc = pc; - (L->ci - 1)->state = CI_SAVEDPC; - return NULL; - } - /* it was a C function (`precall' called it); adjust results */ - luaD_poscall(L, nresults, firstResult); - if (nresults >= 0) L->top = L->ci->top; - } - else { /* it is a Lua function */ - if (GET_OPCODE(i) == OP_CALL) { /* regular call? */ - (L->ci-1)->u.l.savedpc = pc; /* save `pc' to return later */ - (L->ci-1)->state = (CI_SAVEDPC | CI_CALLING); - } - else { /* tail call: put new frame in place of previous one */ - int aux; - base = (L->ci - 1)->base; /* `luaD_precall' may change the stack */ - ra = RA(i); - if (L->openupval) luaF_close(L, base); - for (aux = 0; ra+aux < L->top; aux++) /* move frame down */ - setobjs2s(base+aux-1, ra+aux); - (L->ci - 1)->top = L->top = base+aux; /* correct top */ - lua_assert(L->ci->state & CI_SAVEDPC); - (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc; - (L->ci - 1)->u.l.tailcalls++; /* one more call lost */ - (L->ci - 1)->state = CI_SAVEDPC; - L->ci--; /* remove new frame */ - L->base = L->ci->base; - } - goto callentry; - } - break; - } - case OP_RETURN: { - CallInfo *ci = L->ci - 1; /* previous function frame */ - int b = GETARG_B(i); - if (b != 0) L->top = ra+b-1; - lua_assert(L->ci->state & CI_HASFRAME); - if (L->openupval) luaF_close(L, base); - L->ci->state = CI_SAVEDPC; /* deactivate current function */ - L->ci->u.l.savedpc = pc; - /* previous function was running `here'? */ - if (!(ci->state & CI_CALLING)) { - lua_assert((ci->state & CI_C) || ci->u.l.pc != &pc); - return ra; /* no: return */ - } - else { /* yes: continue its execution */ - int nresults; - lua_assert(ci->u.l.pc == &pc && - ttisfunction(ci->base - 1) && - (ci->state & CI_SAVEDPC)); - lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL); - nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1; - luaD_poscall(L, nresults, ra); - if (nresults >= 0) L->top = L->ci->top; - goto retentry; - } - } - case OP_FORLOOP: { - lua_Number step, idx, limit; - const TObject *plimit = ra+1; - const TObject *pstep = ra+2; - if (!ttisnumber(ra)) - luaG_runerror(L, "`for' initial value must be a number"); - if (!tonumber(plimit, ra+1)) - luaG_runerror(L, "`for' limit must be a number"); - if (!tonumber(pstep, ra+2)) - luaG_runerror(L, "`for' step must be a number"); - step = nvalue(pstep); - idx = nvalue(ra) + step; /* increment index */ - limit = nvalue(plimit); - if (step > 0 ? idx <= limit : idx >= limit) { - dojump(pc, GETARG_sBx(i)); /* jump back */ - chgnvalue(ra, idx); /* update index */ - } - break; - } - case OP_TFORLOOP: { - int nvar = GETARG_C(i) + 1; - StkId cb = ra + nvar + 2; /* call base */ - setobjs2s(cb, ra); - setobjs2s(cb+1, ra+1); - setobjs2s(cb+2, ra+2); - L->top = cb+3; /* func. + 2 args (state and index) */ - luaD_call(L, cb, nvar); - L->top = L->ci->top; - ra = XRA(i) + 2; /* final position of first result */ - cb = ra + nvar; - do { /* move results to proper positions */ - nvar--; - setobjs2s(ra+nvar, cb+nvar); - } while (nvar > 0); - if (ttisnil(ra)) /* break loop? */ - pc++; /* skip jump (break loop) */ - else - dojump(pc, GETARG_sBx(*pc) + 1); /* jump back */ - break; - } - case OP_TFORPREP: { /* for compatibility only */ - if (ttistable(ra)) { - setobjs2s(ra+1, ra); - setobj2s(ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next"))); - } - dojump(pc, GETARG_sBx(i)); - break; - } - case OP_SETLIST: - case OP_SETLISTO: { - int bc; - int n; - Table *h; - runtime_check(L, ttistable(ra)); - h = hvalue(ra); - bc = GETARG_Bx(i); - if (GET_OPCODE(i) == OP_SETLIST) - n = (bc&(LFIELDS_PER_FLUSH-1)) + 1; - else { - n = L->top - ra - 1; - L->top = L->ci->top; - } - bc &= ~(LFIELDS_PER_FLUSH-1); /* bc = bc - bc%FPF */ - for (; n > 0; n--) - setobj2t(luaH_setnum(L, h, bc+n), ra+n); /* write barrier */ - break; - } - case OP_CLOSE: { - luaF_close(L, ra); - break; - } - case OP_CLOSURE: { - Proto *p; - Closure *ncl; - int nup, j; - p = cl->p->p[GETARG_Bx(i)]; - nup = p->nups; - ncl = luaF_newLclosure(L, nup, &cl->g); - ncl->l.p = p; - for (j=0; jl.upvals[j] = cl->upvals[GETARG_B(*pc)]; - else { - lua_assert(GET_OPCODE(*pc) == OP_MOVE); - ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc)); - } - } - setclvalue(ra, ncl); - luaC_checkGC(L); - break; - } - } - } -} - diff --git a/!NotAdopted/SmartAutoReplier/lualib/lvm.h b/!NotAdopted/SmartAutoReplier/lualib/lvm.h deleted file mode 100644 index 19cce200b6..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lvm.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -** $Id: lvm.h,v 1.47 2002/11/14 16:16:21 roberto Exp $ -** Lua virtual machine -** See Copyright Notice in lua.h -*/ - -#ifndef lvm_h -#define lvm_h - - -#include "ldo.h" -#include "lobject.h" -#include "ltm.h" - - -#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) - -#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \ - (((o) = luaV_tonumber(o,n)) != NULL)) - -#define equalobj(L,o1,o2) \ - (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) - - -int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r); -int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2); -const TObject *luaV_tonumber (const TObject *obj, TObject *n); -int luaV_tostring (lua_State *L, StkId obj); -const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key, - int loop); -void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val); -StkId luaV_execute (lua_State *L); -void luaV_concat (lua_State *L, int total, int last); - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/lzio.c b/!NotAdopted/SmartAutoReplier/lualib/lzio.c deleted file mode 100644 index 3aeca1c588..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lzio.c +++ /dev/null @@ -1,81 +0,0 @@ -/* -** $Id: lzio.c,v 1.24 2003/03/20 16:00:56 roberto Exp $ -** a generic input stream interface -** See Copyright Notice in lua.h -*/ - - -#include - -#define lzio_c - -#include "lua.h" - -#include "llimits.h" -#include "lmem.h" -#include "lzio.h" - - -int luaZ_fill (ZIO *z) { - size_t size; - const char *buff = z->reader(NULL, z->data, &size); - if (buff == NULL || size == 0) return EOZ; - z->n = size - 1; - z->p = buff; - return char2int(*(z->p++)); -} - - -int luaZ_lookahead (ZIO *z) { - if (z->n == 0) { - int c = luaZ_fill(z); - if (c == EOZ) return c; - z->n++; - z->p--; - } - return char2int(*z->p); -} - - -void luaZ_init (ZIO *z, lua_Chunkreader reader, void *data, const char *name) { - z->reader = reader; - z->data = data; - z->name = name; - z->n = 0; - z->p = NULL; -} - - -/* --------------------------------------------------------------- read --- */ -size_t luaZ_read (ZIO *z, void *b, size_t n) { - while (n) { - size_t m; - if (z->n == 0) { - if (luaZ_fill(z) == EOZ) - return n; /* return number of missing bytes */ - else { - ++z->n; /* filbuf removed first byte; put back it */ - --z->p; - } - } - m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ - memcpy(b, z->p, m); - z->n -= m; - z->p += m; - b = (char *)b + m; - n -= m; - } - return 0; -} - -/* ------------------------------------------------------------------------ */ -char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { - if (n > buff->buffsize) { - if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; - luaM_reallocvector(L, buff->buffer, buff->buffsize, n, char); - buff->buffsize = n; - } - return buff->buffer; -} - - diff --git a/!NotAdopted/SmartAutoReplier/lualib/lzio.h b/!NotAdopted/SmartAutoReplier/lualib/lzio.h deleted file mode 100644 index 5e73615cc0..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/lzio.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -** $Id: lzio.h,v 1.15 2003/03/20 16:00:56 roberto Exp $ -** Buffered streams -** See Copyright Notice in lua.h -*/ - - -#ifndef lzio_h -#define lzio_h - -#include "lua.h" - - -#define EOZ (-1) /* end of stream */ - -typedef struct Zio ZIO; - - -#define char2int(c) cast(int, cast(unsigned char, (c))) - -#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z)) - -#define zname(z) ((z)->name) - -void luaZ_init (ZIO *z, lua_Chunkreader reader, void *data, const char *name); -size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ -int luaZ_lookahead (ZIO *z); - - - -typedef struct Mbuffer { - char *buffer; - size_t buffsize; -} Mbuffer; - - -char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); - -#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) - -#define luaZ_sizebuffer(buff) ((buff)->buffsize) -#define luaZ_buffer(buff) ((buff)->buffer) - -#define luaZ_resizebuffer(L, buff, size) \ - (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ - (buff)->buffsize = size) - -#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) - - -/* --------- Private Part ------------------ */ - -struct Zio { - size_t n; /* bytes still unread */ - const char *p; /* current position in buffer */ - lua_Chunkreader reader; - void* data; /* additional data */ - const char *name; -}; - - -int luaZ_fill (ZIO *z); - -#endif diff --git a/!NotAdopted/SmartAutoReplier/lualib/targetver.h b/!NotAdopted/SmartAutoReplier/lualib/targetver.h deleted file mode 100644 index 90e767bfce..0000000000 --- a/!NotAdopted/SmartAutoReplier/lualib/targetver.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include diff --git a/!NotAdopted/SmartAutoReplier/resource.h b/!NotAdopted/SmartAutoReplier/resource.h deleted file mode 100644 index 38765d95fc..0000000000 --- a/!NotAdopted/SmartAutoReplier/resource.h +++ /dev/null @@ -1,52 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by SAR.rc -// -#define IDD_OPTIONS 101 -#define IDD_ADDRULE_DLG 102 -#define IDI_SAR_ICON 103 -#define IDD_SET_AURMESSAGEDLG 104 -#define IDD_SEL_USER 110 -#define IDD_HISTORYLOGS 111 -#define IDD_SDLGHOLDER 113 -#define IDC_STATIC_HEADER_TEXT 1001 -#define IDC_EDIT_HEADER 1002 -#define IDC_STATIC_MESSAGE_TEXT 1003 -#define IDC_EDIT_MESSAGE 1004 -#define IDC_EDIT_REPLAYDELAY 1006 -#define IDC_LIST_RULES 1007 -#define IDC_BTN_ADDRULE 1008 -#define IDC_BTN_DELRULE 1009 -#define IDC_ED_RULENAME 1009 -#define IDC_BTN_EDITRULE 1010 -#define IDC_ED_RULECNAME 1010 -#define IDC_ED_RULEREPLY 1011 -#define IDC_ED_RULEACTION 1012 -#define IDC_BUTTON1 1013 -#define IDC_BTN_SELUSER 1013 -#define IDC_CHECK_DISABLEWMON 1014 -#define IDC_CHECK1 1017 -#define IDC_CH_SHOW_AURDLG_WHMC 1017 -#define IDC_CH_DISWHSB 1017 -#define IDC_ED_TEXT 1019 -#define IDC_CB_DWSB 1020 -#define IDC_LIST_USERS 1021 -#define IDC_TABS 1022 -#define IDC_TABSHOLDER 1022 -#define IDC_STATUSMSG 1023 -#define IDC_CH_ENABLE_WSCH 1115 -#define IDC_CB_ENWSC 1116 -#define IDC_CH_SHOWCG 1117 -#define IDC_CH_SHOWCG2 1118 -#define IDC_CH_SAVE_AURS 1118 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 113 -#define _APS_NEXT_COMMAND_VALUE 40002 -#define _APS_NEXT_CONTROL_VALUE 1024 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/!NotAdopted/SmartAutoReplier/sar.ico b/!NotAdopted/SmartAutoReplier/sar.ico deleted file mode 100644 index 27a5d17bbb..0000000000 Binary files a/!NotAdopted/SmartAutoReplier/sar.ico and /dev/null differ diff --git a/!NotAdopted/SmartAutoReplier/stdafx.cpp b/!NotAdopted/SmartAutoReplier/stdafx.cpp deleted file mode 100644 index 39aa93ac1d..0000000000 --- a/!NotAdopted/SmartAutoReplier/stdafx.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#include "stdafx.h" - -void OnRefreshSettings(void) -{ - SendMessage(HWND_BROADCAST, REFRESH_OPTS_MSG, 0, 0); -} \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/stdafx.h b/!NotAdopted/SmartAutoReplier/stdafx.h deleted file mode 100644 index 76f6c5128c..0000000000 --- a/!NotAdopted/SmartAutoReplier/stdafx.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM - * - * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna - * - * This file is part of SAR. - * - * SAR is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * SAR is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with SAR. If not, see . -*/ - -#pragma once - -#include "AggressiveOptimize.h" - -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0500 - -#define WIN32_LEAN_AND_MEAN -#define _MERGE_RDATA_ - -/// windows and crt headers (win32 api) -#include -#include -#include -#include -#include "resource.h" -#include -#include - -#include - -/// shell's headers... (windows shell) -#include -#include - -#pragma comment(lib, "shlwapi.lib") -#pragma comment(lib, "shell32.lib") - -#pragma warning(disable:4312) -#pragma warning(disable:4267) -#pragma warning(disable:4356) - -/// miranda's headers... -#include "../miranda32/newpluginapi.h" -#include "../miranda32/m_system.h" -#include "../miranda32/m_protomod.h" -#include "../miranda32/m_protosvc.h" -#include "../miranda32/m_clist.h" -#include "../miranda32/m_skin.h" -#include "../miranda32/m_database.h" -#include "../miranda32/m_options.h" -#include "../miranda32/m_langpack.h" - -/// plugin's specific headers... -#include "messageshandler.h" /// messages handler -#include "settingshandler.h" /// settings handler -#include "GUI/optionsDlg.h" /// options handler -#include "comlogging.h" /// common loggin helper macroses -#include "crushlog.h" /// crush log handler - -#define REFRESH_OPTS_MSG WM_USER + 666 - -void OnRefreshSettings(void); \ No newline at end of file diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlapp.h b/!NotAdopted/SmartAutoReplier/wtl/atlapp.h deleted file mode 100644 index e47bcd633b..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlapp.h +++ /dev/null @@ -1,2035 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLAPP_H__ -#define __ATLAPP_H__ - -#pragma once - -#ifndef __cplusplus - #error WTL requires C++ compilation (use a .cpp suffix) -#endif - -#ifndef __ATLBASE_H__ - #error atlapp.h requires atlbase.h to be included first -#endif - -#ifndef _WIN32_WCE - #if (WINVER < 0x0400) - #error WTL requires Windows version 4.0 or higher - #endif - - #if (_WIN32_IE < 0x0300) - #error WTL requires IE version 3.0 or higher - #endif -#endif - -#ifdef _ATL_NO_COMMODULE - #error WTL requires that _ATL_NO_COMMODULE is not defined -#endif - -#if (_ATL_VER >= 0x0900) && defined(_ATL_MIN_CRT) - #error _ATL_MIN_CRT is not supported with ATL 9.0 and higher -#endif - -#if defined(_WIN32_WCE) && defined(_ATL_MIN_CRT) - #pragma message("Warning: WTL for Windows CE doesn't use _ATL_MIN_CRT") -#endif - -#include -#if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE) - #include // for _beginthreadex -#endif - -#if (_ATL_VER < 0x0800) && !defined(_DEBUG) - #include -#endif - -#include -#ifndef _WIN32_WCE - #pragma comment(lib, "comctl32.lib") -#endif - -#ifndef _WIN32_WCE - #include "atlres.h" -#else // CE specific - #include "atlresce.h" -#endif // _WIN32_WCE - -// We need to disable this warning because of template class arguments -#pragma warning(disable: 4127) - -#if (_ATL_VER >= 0x0900) && !defined(_SECURE_ATL) - #define _SECURE_ATL 1 -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// WTL version number - -#define _WTL_VER 0x0810 - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CMessageFilter -// CIdleHandler -// CMessageLoop -// -// CAppModule -// CServerAppModule -// -// CRegKeyEx -// -// Global functions: -// AtlGetDefaultGuiFont() -// AtlCreateControlFont() -// AtlCreateBoldFont() -// AtlInitCommonControls() - - -/////////////////////////////////////////////////////////////////////////////// -// Global support for Windows CE - -#ifdef _WIN32_WCE - -#ifndef SW_SHOWDEFAULT - #define SW_SHOWDEFAULT SW_SHOWNORMAL -#endif // !SW_SHOWDEFAULT - -// These get's OR-ed in a constant and will have no effect. -// Defining them reduces the number of #ifdefs required for CE. -#define LR_DEFAULTSIZE 0 -#define LR_LOADFROMFILE 0 - -#ifndef SM_CXCURSOR - #define SM_CXCURSOR 13 -#endif -#ifndef SM_CYCURSOR - #define SM_CYCURSOR 14 -#endif - -inline BOOL IsMenu(HMENU hMenu) -{ - MENUITEMINFO mii = { sizeof(MENUITEMINFO) }; - ::SetLastError(0); - BOOL bRet = ::GetMenuItemInfo(hMenu, 0, TRUE, &mii); - if(!bRet) - bRet = (::GetLastError() != ERROR_INVALID_MENU_HANDLE) ? TRUE : FALSE; - return bRet; -} - -#if (_WIN32_WCE >= 410) -extern "C" void WINAPI ListView_SetItemSpacing(HWND hwndLV, int iHeight); -#endif // (_WIN32_WCE >= 410) - -inline int MulDiv(IN int nNumber, IN int nNumerator, IN int nDenominator) -{ - __int64 multiple = nNumber * nNumerator; - return static_cast(multiple / nDenominator); -} - -#if (_ATL_VER >= 0x0800) - -#ifndef _WTL_KEEP_WS_OVERLAPPEDWINDOW - #ifdef WS_OVERLAPPEDWINDOW - #undef WS_OVERLAPPEDWINDOW - #define WS_OVERLAPPEDWINDOW 0 - #endif // WS_OVERLAPPEDWINDOW -#endif // !_WTL_KEEP_WS_OVERLAPPEDWINDOW - -#ifndef RDW_FRAME - #define RDW_FRAME 0 -#endif // !RDW_FRAME - -#ifndef WM_WINDOWPOSCHANGING - #define WM_WINDOWPOSCHANGING 0 -#endif // !WM_WINDOWPOSCHANGING - -#define FreeResource(x) -#define UnlockResource(x) - -namespace ATL -{ - inline HRESULT CComModule::RegisterClassObjects(DWORD /*dwClsContext*/, DWORD /*dwFlags*/) throw() - { return E_NOTIMPL; } - inline HRESULT CComModule::RevokeClassObjects() throw() - { return E_NOTIMPL; } -}; // namespace ATL - -#ifndef lstrlenW - #define lstrlenW (int)ATL::lstrlenW -#endif // lstrlenW - -inline int WINAPI lstrlenA(LPCSTR lpszString) -{ return ATL::lstrlenA(lpszString); } - -#ifdef lstrcpyn - #undef lstrcpyn - #define lstrcpyn ATL::lstrcpynW -#endif // lstrcpyn - -#ifndef SetWindowLongPtrW - inline LONG_PTR tmp_SetWindowLongPtrW( HWND hWnd, int nIndex, LONG_PTR dwNewLong ) - { - return( ::SetWindowLongW( hWnd, nIndex, LONG( dwNewLong ) ) ); - } - #define SetWindowLongPtrW tmp_SetWindowLongPtrW -#endif - -#ifndef GetWindowLongPtrW - inline LONG_PTR tmp_GetWindowLongPtrW( HWND hWnd, int nIndex ) - { - return( ::GetWindowLongW( hWnd, nIndex ) ); - } - #define GetWindowLongPtrW tmp_GetWindowLongPtrW -#endif - -#ifndef LongToPtr - #define LongToPtr(x) ((void*)x) -#endif - -#ifndef PtrToInt - #define PtrToInt( p ) ((INT)(INT_PTR) (p) ) -#endif - -#else // !(_ATL_VER >= 0x0800) - -#ifdef lstrlenW - #undef lstrlenW - #define lstrlenW (int)::wcslen -#endif // lstrlenW - -#define lstrlenA (int)strlen - -#ifndef lstrcpyn - inline LPTSTR lstrcpyn(LPTSTR lpstrDest, LPCTSTR lpstrSrc, int nLength) - { - if(lpstrDest == NULL || lpstrSrc == NULL || nLength <= 0) - return NULL; - int nLen = min(lstrlen(lpstrSrc), nLength - 1); - LPTSTR lpstrRet = (LPTSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(TCHAR)); - lpstrDest[nLen] = 0; - return lpstrRet; - } -#endif // !lstrcpyn - -#ifndef lstrcpynW - inline LPWSTR lstrcpynW(LPWSTR lpstrDest, LPCWSTR lpstrSrc, int nLength) - { - return lstrcpyn(lpstrDest, lpstrSrc, nLength); // WinCE is Unicode only - } -#endif // !lstrcpynW - -#ifndef lstrcpynA - inline LPSTR lstrcpynA(LPSTR lpstrDest, LPCSTR lpstrSrc, int nLength) - { - if(lpstrDest == NULL || lpstrSrc == NULL || nLength <= 0) - return NULL; - int nLen = min(lstrlenA(lpstrSrc), nLength - 1); - LPSTR lpstrRet = (LPSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(char)); - lpstrDest[nLen] = 0; - return lpstrRet; - } -#endif // !lstrcpyn - -#ifdef TrackPopupMenu - #undef TrackPopupMenu -#endif // TrackPopupMenu - -#define DECLARE_WND_CLASS_EX(WndClassName, style, bkgnd) \ -static CWndClassInfo& GetWndClassInfo() \ -{ \ - static CWndClassInfo wc = \ - { \ - { style, StartWindowProc, \ - 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName }, \ - NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \ - }; \ - return wc; \ -} - -#ifndef _MAX_FNAME - #define _MAX_FNAME _MAX_PATH -#endif // _MAX_FNAME - -#if (_WIN32_WCE < 400) - #define MAKEINTATOM(i) (LPTSTR)((ULONG_PTR)((WORD)(i))) -#endif // (_WIN32_WCE < 400) - -#if (_WIN32_WCE < 410) - #define WHEEL_PAGESCROLL (UINT_MAX) - #define WHEEL_DELTA 120 -#endif // (_WIN32_WCE < 410) - -#ifdef DrawIcon - #undef DrawIcon -#endif - -#ifndef VARCMP_LT - #define VARCMP_LT 0 -#endif -#ifndef VARCMP_EQ - #define VARCMP_EQ 1 -#endif -#ifndef VARCMP_GT - #define VARCMP_GT 2 -#endif -#ifndef VARCMP_NULL - #define VARCMP_NULL 3 -#endif - -#ifndef RDW_ALLCHILDREN - #define RDW_ALLCHILDREN 0 -#endif - -#endif // !(_ATL_VER >= 0x0800) - -#endif // _WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// Global support for using original VC++ 6.0 headers with WTL - -#ifndef _ATL_NO_OLD_HEADERS_WIN64 -#if !defined(_WIN64) && (_ATL_VER < 0x0700) - - #ifndef PSM_INSERTPAGE - #define PSM_INSERTPAGE (WM_USER + 119) - #endif // !PSM_INSERTPAGE - - #ifndef GetClassLongPtr - #define GetClassLongPtrA GetClassLongA - #define GetClassLongPtrW GetClassLongW - #ifdef UNICODE - #define GetClassLongPtr GetClassLongPtrW - #else - #define GetClassLongPtr GetClassLongPtrA - #endif // !UNICODE - #endif // !GetClassLongPtr - - #ifndef GCLP_HICONSM - #define GCLP_HICONSM (-34) - #endif // !GCLP_HICONSM - - #ifndef GetWindowLongPtr - #define GetWindowLongPtrA GetWindowLongA - #define GetWindowLongPtrW GetWindowLongW - #ifdef UNICODE - #define GetWindowLongPtr GetWindowLongPtrW - #else - #define GetWindowLongPtr GetWindowLongPtrA - #endif // !UNICODE - #endif // !GetWindowLongPtr - - #ifndef SetWindowLongPtr - #define SetWindowLongPtrA SetWindowLongA - #define SetWindowLongPtrW SetWindowLongW - #ifdef UNICODE - #define SetWindowLongPtr SetWindowLongPtrW - #else - #define SetWindowLongPtr SetWindowLongPtrA - #endif // !UNICODE - #endif // !SetWindowLongPtr - - #ifndef GWLP_WNDPROC - #define GWLP_WNDPROC (-4) - #endif - #ifndef GWLP_HINSTANCE - #define GWLP_HINSTANCE (-6) - #endif - #ifndef GWLP_HWNDPARENT - #define GWLP_HWNDPARENT (-8) - #endif - #ifndef GWLP_USERDATA - #define GWLP_USERDATA (-21) - #endif - #ifndef GWLP_ID - #define GWLP_ID (-12) - #endif - - #ifndef DWLP_MSGRESULT - #define DWLP_MSGRESULT 0 - #endif - - typedef long LONG_PTR; - typedef unsigned long ULONG_PTR; - typedef ULONG_PTR DWORD_PTR; - - #ifndef HandleToUlong - #define HandleToUlong( h ) ((ULONG)(ULONG_PTR)(h) ) - #endif - #ifndef HandleToLong - #define HandleToLong( h ) ((LONG)(LONG_PTR) (h) ) - #endif - #ifndef LongToHandle - #define LongToHandle( h) ((HANDLE)(LONG_PTR) (h)) - #endif - #ifndef PtrToUlong - #define PtrToUlong( p ) ((ULONG)(ULONG_PTR) (p) ) - #endif - #ifndef PtrToLong - #define PtrToLong( p ) ((LONG)(LONG_PTR) (p) ) - #endif - #ifndef PtrToUint - #define PtrToUint( p ) ((UINT)(UINT_PTR) (p) ) - #endif - #ifndef PtrToInt - #define PtrToInt( p ) ((INT)(INT_PTR) (p) ) - #endif - #ifndef PtrToUshort - #define PtrToUshort( p ) ((unsigned short)(ULONG_PTR)(p) ) - #endif - #ifndef PtrToShort - #define PtrToShort( p ) ((short)(LONG_PTR)(p) ) - #endif - #ifndef IntToPtr - #define IntToPtr( i ) ((VOID *)(INT_PTR)((int)i)) - #endif - #ifndef UIntToPtr - #define UIntToPtr( ui ) ((VOID *)(UINT_PTR)((unsigned int)ui)) - #endif - #ifndef LongToPtr - #define LongToPtr( l ) ((VOID *)(LONG_PTR)((long)l)) - #endif - #ifndef ULongToPtr - #define ULongToPtr( ul ) ((VOID *)(ULONG_PTR)((unsigned long)ul)) - #endif - -#endif // !defined(_WIN64) && (_ATL_VER < 0x0700) -#endif // !_ATL_NO_OLD_HEADERS_WIN64 - - -/////////////////////////////////////////////////////////////////////////////// -// Global support for SecureHelper functions - -#ifndef _TRUNCATE - #define _TRUNCATE ((size_t)-1) -#endif - -#ifndef _ERRCODE_DEFINED - #define _ERRCODE_DEFINED - typedef int errno_t; -#endif - -#ifndef _SECURECRT_ERRCODE_VALUES_DEFINED - #define _SECURECRT_ERRCODE_VALUES_DEFINED - #define EINVAL 22 - #define STRUNCATE 80 -#endif - -#ifndef _countof - #define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0])) -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// Miscellaneous global support - -// define useful macros from winuser.h -#ifndef IS_INTRESOURCE - #define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0) -#endif // IS_INTRESOURCE - -// protect template members from windowsx.h macros -#ifdef _INC_WINDOWSX - #undef SubclassWindow -#endif // _INC_WINDOWSX - -// define useful macros from windowsx.h -#ifndef GET_X_LPARAM - #define GET_X_LPARAM(lParam) ((int)(short)LOWORD(lParam)) -#endif -#ifndef GET_Y_LPARAM - #define GET_Y_LPARAM(lParam) ((int)(short)HIWORD(lParam)) -#endif - -// Dummy structs for compiling with /CLR -#if (_MSC_VER >= 1300) && defined(_MANAGED) - __if_not_exists(_IMAGELIST::_IMAGELIST) { struct _IMAGELIST { }; } - __if_not_exists(_TREEITEM::_TREEITEM) { struct _TREEITEM { }; } - __if_not_exists(_PSP::_PSP) { struct _PSP { }; } -#endif - -// Define ATLVERIFY macro for ATL3 -#if (_ATL_VER < 0x0700) - #ifndef ATLVERIFY - #ifdef _DEBUG - #define ATLVERIFY(expr) ATLASSERT(expr) - #else - #define ATLVERIFY(expr) (expr) - #endif // DEBUG - #endif // ATLVERIFY -#endif // (_ATL_VER < 0x0700) - -// Forward declaration for ATL3 fix -#if (_ATL_VER < 0x0700) && defined(_ATL_DLL) && !defined(_WIN32_WCE) - namespace ATL { HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor); }; -#endif - - -namespace WTL -{ - -#if (_ATL_VER >= 0x0700) - DECLARE_TRACE_CATEGORY(atlTraceUI); - #ifdef _DEBUG - __declspec(selectany) ATL::CTraceCategory atlTraceUI(_T("atlTraceUI")); - #endif // _DEBUG -#else // !(_ATL_VER >= 0x0700) - enum wtlTraceFlags - { - atlTraceUI = 0x10000000 - }; -#endif // !(_ATL_VER >= 0x0700) - -// Windows version helper -inline bool AtlIsOldWindows() -{ - OSVERSIONINFO ovi = { 0 }; - ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - BOOL bRet = ::GetVersionEx(&ovi); - return (!bRet || !((ovi.dwMajorVersion >= 5) || (ovi.dwMajorVersion == 4 && ovi.dwMinorVersion >= 90))); -} - -// Default GUI font helper - "MS Shell Dlg" stock font -inline HFONT AtlGetDefaultGuiFont() -{ -#ifndef _WIN32_WCE - return (HFONT)::GetStockObject(DEFAULT_GUI_FONT); -#else // CE specific - return (HFONT)::GetStockObject(SYSTEM_FONT); -#endif // _WIN32_WCE -} - -// Control font helper - default font for controls not in a dialog -// (NOTE: Caller owns the font, and should destroy it when it's no longer needed) -inline HFONT AtlCreateControlFont() -{ -#ifndef _WIN32_WCE - LOGFONT lf = { 0 }; - ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE); - HFONT hFont = ::CreateFontIndirect(&lf); - ATLASSERT(hFont != NULL); - return hFont; -#else // CE specific - return (HFONT)::GetStockObject(SYSTEM_FONT); -#endif // _WIN32_WCE -} - -// Bold font helper -// (NOTE: Caller owns the font, and should destroy it when it's no longer needed) -inline HFONT AtlCreateBoldFont(HFONT hFont = NULL) -{ - LOGFONT lf = { 0 }; -#ifndef _WIN32_WCE - if(hFont == NULL) - ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE); - else - ATLVERIFY(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT)); -#else // CE specific - if(hFont == NULL) - hFont = (HFONT)::GetStockObject(SYSTEM_FONT); - ATLVERIFY(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT)); -#endif // _WIN32_WCE - lf.lfWeight = FW_BOLD; - HFONT hFontBold = ::CreateFontIndirect(&lf); - ATLASSERT(hFontBold != NULL); - return hFontBold; -} - -// Common Controls initialization helper -inline BOOL AtlInitCommonControls(DWORD dwFlags) -{ - INITCOMMONCONTROLSEX iccx = { sizeof(INITCOMMONCONTROLSEX), dwFlags }; - BOOL bRet = ::InitCommonControlsEx(&iccx); - ATLASSERT(bRet); - return bRet; -} - - -/////////////////////////////////////////////////////////////////////////////// -// RunTimeHelper - helper functions for Windows version and structure sizes - -// Not for Windows CE -#if defined(_WIN32_WCE) && !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) - #define _WTL_NO_RUNTIME_STRUCT_SIZE -#endif - -#ifndef _WTL_NO_RUNTIME_STRUCT_SIZE - -#ifndef _SIZEOF_STRUCT - #define _SIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member)) -#endif - -#if (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE) - #define REBARBANDINFO_V6_SIZE _SIZEOF_STRUCT(REBARBANDINFO, cxHeader) -#endif // (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE) - -#if (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE) - #define LVGROUP_V5_SIZE _SIZEOF_STRUCT(LVGROUP, uAlign) -#endif // (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE) - -#if (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE) - #define LVTILEINFO_V5_SIZE _SIZEOF_STRUCT(LVTILEINFO, puColumns) -#endif // (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE) - -#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE) - #define MCHITTESTINFO_V1_SIZE _SIZEOF_STRUCT(MCHITTESTINFO, st) -#endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE) - -#if !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE) - #define NONCLIENTMETRICS_V1_SIZE _SIZEOF_STRUCT(NONCLIENTMETRICS, lfMessageFont) -#endif // !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE) - -#endif // !_WTL_NO_RUNTIME_STRUCT_SIZE - -namespace RunTimeHelper -{ -#ifndef _WIN32_WCE - inline bool IsCommCtrl6() - { - DWORD dwMajor = 0, dwMinor = 0; - HRESULT hRet = ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor); - return (SUCCEEDED(hRet) && (dwMajor >= 6)); - } - - inline bool IsVista() - { - OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) }; - BOOL bRet = ::GetVersionEx(&ovi); - return ((bRet != FALSE) && (ovi.dwMajorVersion >= 6)); - } - - inline bool IsThemeAvailable() - { - bool bRet = false; - - if(IsCommCtrl6()) - { - HMODULE hThemeDLL = ::LoadLibrary(_T("uxtheme.dll")); - if(hThemeDLL != NULL) - { - typedef BOOL (STDAPICALLTYPE *PFN_IsThemeActive)(); - PFN_IsThemeActive pfnIsThemeActive = (PFN_IsThemeActive)::GetProcAddress(hThemeDLL, "IsThemeActive"); - ATLASSERT(pfnIsThemeActive != NULL); - bRet = (pfnIsThemeActive != NULL) && (pfnIsThemeActive() != FALSE); - if(bRet) - { - typedef BOOL (STDAPICALLTYPE *PFN_IsAppThemed)(); - PFN_IsAppThemed pfnIsAppThemed = (PFN_IsAppThemed)::GetProcAddress(hThemeDLL, "IsAppThemed"); - ATLASSERT(pfnIsAppThemed != NULL); - bRet = (pfnIsAppThemed != NULL) && (pfnIsAppThemed() != FALSE); - } - - ::FreeLibrary(hThemeDLL); - } - } - - return bRet; - } - - inline bool IsWin7() - { - OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) }; - BOOL bRet = ::GetVersionEx(&ovi); - return ((bRet != FALSE) && (ovi.dwMajorVersion == 6) && (ovi.dwMinorVersion >= 1)); - } - - inline bool IsRibbonUIAvailable() - { - static INT iRibbonUI = -1; - -#if defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7) - if (iRibbonUI == -1) - { - HMODULE hRibbonDLL = ::LoadLibrary(_T("propsys.dll")); - if (hRibbonDLL != NULL) - { - const GUID CLSID_UIRibbonFramework = { 0x926749fa, 0x2615, 0x4987, { 0x88, 0x45, 0xc3, 0x3e, 0x65, 0xf2, 0xb9, 0x57 } }; - // block - create instance - { - ATL::CComPtr pIUIFramework; - iRibbonUI = SUCCEEDED(pIUIFramework.CoCreateInstance(CLSID_UIRibbonFramework)) ? 1 : 0; - } - ::FreeLibrary(hRibbonDLL); - } - else - { - iRibbonUI = 0; - } - } -#endif // defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7) - - return (iRibbonUI == 1); - } - -#endif // !_WIN32_WCE - - inline int SizeOf_REBARBANDINFO() - { - int nSize = sizeof(REBARBANDINFO); -#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) - if(!(IsVista() && IsCommCtrl6())) - nSize = REBARBANDINFO_V6_SIZE; -#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) - return nSize; - } - -#if (_WIN32_WINNT >= 0x501) - inline int SizeOf_LVGROUP() - { - int nSize = sizeof(LVGROUP); -#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) - if(!IsVista()) - nSize = LVGROUP_V5_SIZE; -#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) - return nSize; - } - - inline int SizeOf_LVTILEINFO() - { - int nSize = sizeof(LVTILEINFO); -#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) - if(!IsVista()) - nSize = LVTILEINFO_V5_SIZE; -#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) - return nSize; - } -#endif // (_WIN32_WINNT >= 0x501) - - inline int SizeOf_MCHITTESTINFO() - { - int nSize = sizeof(MCHITTESTINFO); -#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) - if(!(IsVista() && IsCommCtrl6())) - nSize = MCHITTESTINFO_V1_SIZE; -#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) - return nSize; - } - -#ifndef _WIN32_WCE - inline int SizeOf_NONCLIENTMETRICS() - { - int nSize = sizeof(NONCLIENTMETRICS); -#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600) - if(!IsVista()) - nSize = NONCLIENTMETRICS_V1_SIZE; -#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600) - return nSize; - } -#endif // !_WIN32_WCE -}; - - -/////////////////////////////////////////////////////////////////////////////// -// ModuleHelper - helper functions for ATL3 and ATL7 module classes - -namespace ModuleHelper -{ - inline HINSTANCE GetModuleInstance() - { -#if (_ATL_VER >= 0x0700) - return ATL::_AtlBaseModule.GetModuleInstance(); -#else // !(_ATL_VER >= 0x0700) - return ATL::_pModule->GetModuleInstance(); -#endif // !(_ATL_VER >= 0x0700) - } - - inline HINSTANCE GetResourceInstance() - { -#if (_ATL_VER >= 0x0700) - return ATL::_AtlBaseModule.GetResourceInstance(); -#else // !(_ATL_VER >= 0x0700) - return ATL::_pModule->GetResourceInstance(); -#endif // !(_ATL_VER >= 0x0700) - } - - inline void AddCreateWndData(ATL::_AtlCreateWndData* pData, void* pObject) - { -#if (_ATL_VER >= 0x0700) - ATL::_AtlWinModule.AddCreateWndData(pData, pObject); -#else // !(_ATL_VER >= 0x0700) - ATL::_pModule->AddCreateWndData(pData, pObject); -#endif // !(_ATL_VER >= 0x0700) - } - - inline void* ExtractCreateWndData() - { -#if (_ATL_VER >= 0x0700) - return ATL::_AtlWinModule.ExtractCreateWndData(); -#else // !(_ATL_VER >= 0x0700) - return ATL::_pModule->ExtractCreateWndData(); -#endif // !(_ATL_VER >= 0x0700) - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// SecureHelper - helper functions for VS2005 secure CRT - -namespace SecureHelper -{ - inline void strcpyA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc) - { -#if _SECURE_ATL - ATL::Checked::strcpy_s(lpstrDest, cchDest, lpstrSrc); -#else - if(cchDest > (size_t)lstrlenA(lpstrSrc)) - ATLVERIFY(lstrcpyA(lpstrDest, lpstrSrc) != NULL); - else - ATLASSERT(FALSE); -#endif - } - - inline void strcpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc) - { -#if _SECURE_ATL - ATL::Checked::wcscpy_s(lpstrDest, cchDest, lpstrSrc); -#else - if(cchDest > (size_t)lstrlenW(lpstrSrc)) - ATLVERIFY(lstrcpyW(lpstrDest, lpstrSrc) != NULL); - else - ATLASSERT(FALSE); -#endif - } - - inline void strcpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc) - { -#ifdef _UNICODE - strcpyW_x(lpstrDest, cchDest, lpstrSrc); -#else - strcpyA_x(lpstrDest, cchDest, lpstrSrc); -#endif - } - - inline errno_t strncpyA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc, size_t cchCount) - { -#if _SECURE_ATL - return ATL::Checked::strncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount); -#else - errno_t nRet = 0; - if(lpstrDest == NULL || cchDest == 0 || lpstrSrc == NULL) - { - nRet = EINVAL; - } - else if(cchCount == _TRUNCATE) - { - cchCount = min(cchDest - 1, size_t(lstrlenA(lpstrSrc))); - nRet = STRUNCATE; - } - else if(cchDest <= cchCount) - { - lpstrDest[0] = 0; - nRet = EINVAL; - } - if(nRet == 0 || nRet == STRUNCATE) - nRet = (lstrcpynA(lpstrDest, lpstrSrc, (int)cchCount + 1) != NULL) ? nRet : EINVAL; - ATLASSERT(nRet == 0 || nRet == STRUNCATE); - return nRet; -#endif - } - - inline errno_t strncpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc, size_t cchCount) - { -#if _SECURE_ATL - return ATL::Checked::wcsncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount); -#else - errno_t nRet = 0; - if(lpstrDest == NULL || cchDest == 0 || lpstrSrc == NULL) - { - nRet = EINVAL; - } - else if(cchCount == _TRUNCATE) - { - cchCount = min(cchDest - 1, size_t(lstrlenW(lpstrSrc))); - nRet = STRUNCATE; - } - else if(cchDest <= cchCount) - { - lpstrDest[0] = 0; - nRet = EINVAL; - } - if(nRet == 0 || nRet == STRUNCATE) - nRet = (lstrcpynW(lpstrDest, lpstrSrc, (int)cchCount + 1) != NULL) ? nRet : EINVAL; - ATLASSERT(nRet == 0 || nRet == STRUNCATE); - return nRet; -#endif - } - - inline errno_t strncpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc, size_t cchCount) - { -#ifdef _UNICODE - return strncpyW_x(lpstrDest, cchDest, lpstrSrc, cchCount); -#else - return strncpyA_x(lpstrDest, cchDest, lpstrSrc, cchCount); -#endif - } - - inline void strcatA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc) - { -#if _SECURE_ATL - ATL::Checked::strcat_s(lpstrDest, cchDest, lpstrSrc); -#else - if(cchDest > (size_t)lstrlenA(lpstrSrc)) - ATLVERIFY(lstrcatA(lpstrDest, lpstrSrc) != NULL); - else - ATLASSERT(FALSE); -#endif - } - - inline void strcatW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc) - { -#if _SECURE_ATL - ATL::Checked::wcscat_s(lpstrDest, cchDest, lpstrSrc); -#else - if(cchDest > (size_t)lstrlenW(lpstrSrc)) - ATLVERIFY(lstrcatW(lpstrDest, lpstrSrc) != NULL); - else - ATLASSERT(FALSE); -#endif - } - - inline void strcat_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc) - { -#ifdef _UNICODE - strcatW_x(lpstrDest, cchDest, lpstrSrc); -#else - strcatA_x(lpstrDest, cchDest, lpstrSrc); -#endif - } - - inline void memcpy_x(void* pDest, size_t cbDest, const void* pSrc, size_t cbSrc) - { -#if _SECURE_ATL - ATL::Checked::memcpy_s(pDest, cbDest, pSrc, cbSrc); -#else - if(cbDest >= cbSrc) - memcpy(pDest, pSrc, cbSrc); - else - ATLASSERT(FALSE); -#endif - } - - inline void memmove_x(void* pDest, size_t cbDest, const void* pSrc, size_t cbSrc) - { -#if _SECURE_ATL - ATL::Checked::memmove_s(pDest, cbDest, pSrc, cbSrc); -#else - if(cbDest >= cbSrc) - memmove(pDest, pSrc, cbSrc); - else - ATLASSERT(FALSE); -#endif - } - - inline int vsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args) - { -#if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE) - return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args); -#else - cchBuff; // Avoid unused argument warning -#pragma warning(disable: 4996) - return _vstprintf(lpstrBuff, lpstrFormat, args); -#pragma warning(default: 4996) -#endif - } - - inline int wvsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args) - { -#if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE) - return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args); -#else - cchBuff; // Avoid unused argument warning - return ::wvsprintf(lpstrBuff, lpstrFormat, args); -#endif - } - - inline int sprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, ...) - { - va_list args; - va_start(args, lpstrFormat); - int nRes = vsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args); - va_end(args); - return nRes; - } - - inline int wsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, ...) - { - va_list args; - va_start(args, lpstrFormat); - int nRes = wvsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args); - va_end(args); - return nRes; - } -}; // namespace SecureHelper - - -/////////////////////////////////////////////////////////////////////////////// -// CMessageFilter - Interface for message filter support - -class CMessageFilter -{ -public: - virtual BOOL PreTranslateMessage(MSG* pMsg) = 0; -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CIdleHandler - Interface for idle processing - -class CIdleHandler -{ -public: - virtual BOOL OnIdle() = 0; -}; - -#ifndef _ATL_NO_OLD_NAMES - // for compatilibility with old names only - typedef CIdleHandler CUpdateUIObject; - #define DoUpdate OnIdle -#endif // !_ATL_NO_OLD_NAMES - - -/////////////////////////////////////////////////////////////////////////////// -// CMessageLoop - message loop implementation - -class CMessageLoop -{ -public: - ATL::CSimpleArray m_aMsgFilter; - ATL::CSimpleArray m_aIdleHandler; - MSG m_msg; - -// Message filter operations - BOOL AddMessageFilter(CMessageFilter* pMessageFilter) - { - return m_aMsgFilter.Add(pMessageFilter); - } - - BOOL RemoveMessageFilter(CMessageFilter* pMessageFilter) - { - return m_aMsgFilter.Remove(pMessageFilter); - } - -// Idle handler operations - BOOL AddIdleHandler(CIdleHandler* pIdleHandler) - { - return m_aIdleHandler.Add(pIdleHandler); - } - - BOOL RemoveIdleHandler(CIdleHandler* pIdleHandler) - { - return m_aIdleHandler.Remove(pIdleHandler); - } - -#ifndef _ATL_NO_OLD_NAMES - // for compatilibility with old names only - BOOL AddUpdateUI(CIdleHandler* pIdleHandler) - { - ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIObject and AddUpdateUI are deprecated. Please change your code to use CIdleHandler and OnIdle\n")); - return AddIdleHandler(pIdleHandler); - } - - BOOL RemoveUpdateUI(CIdleHandler* pIdleHandler) - { - ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIObject and RemoveUpdateUI are deprecated. Please change your code to use CIdleHandler and OnIdle\n")); - return RemoveIdleHandler(pIdleHandler); - } -#endif // !_ATL_NO_OLD_NAMES - -// message loop - int Run() - { - BOOL bDoIdle = TRUE; - int nIdleCount = 0; - BOOL bRet; - - for(;;) - { - while(bDoIdle && !::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE)) - { - if(!OnIdle(nIdleCount++)) - bDoIdle = FALSE; - } - - bRet = ::GetMessage(&m_msg, NULL, 0, 0); - - if(bRet == -1) - { - ATLTRACE2(atlTraceUI, 0, _T("::GetMessage returned -1 (error)\n")); - continue; // error, don't process - } - else if(!bRet) - { - ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run - exiting\n")); - break; // WM_QUIT, exit message loop - } - - if(!PreTranslateMessage(&m_msg)) - { - ::TranslateMessage(&m_msg); - ::DispatchMessage(&m_msg); - } - - if(IsIdleMessage(&m_msg)) - { - bDoIdle = TRUE; - nIdleCount = 0; - } - } - - return (int)m_msg.wParam; - } - - static BOOL IsIdleMessage(MSG* pMsg) - { - // These messages should NOT cause idle processing - switch(pMsg->message) - { - case WM_MOUSEMOVE: -#ifndef _WIN32_WCE - case WM_NCMOUSEMOVE: -#endif // !_WIN32_WCE - case WM_PAINT: - case 0x0118: // WM_SYSTIMER (caret blink) - return FALSE; - } - - return TRUE; - } - -// Overrideables - // Override to change message filtering - virtual BOOL PreTranslateMessage(MSG* pMsg) - { - // loop backwards - for(int i = m_aMsgFilter.GetSize() - 1; i >= 0; i--) - { - CMessageFilter* pMessageFilter = m_aMsgFilter[i]; - if(pMessageFilter != NULL && pMessageFilter->PreTranslateMessage(pMsg)) - return TRUE; - } - return FALSE; // not translated - } - - // override to change idle processing - virtual BOOL OnIdle(int /*nIdleCount*/) - { - for(int i = 0; i < m_aIdleHandler.GetSize(); i++) - { - CIdleHandler* pIdleHandler = m_aIdleHandler[i]; - if(pIdleHandler != NULL) - pIdleHandler->OnIdle(); - } - return FALSE; // don't continue - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CStaticDataInitCriticalSectionLock and CWindowCreateCriticalSectionLock -// internal classes to manage critical sections for both ATL3 and ATL7 - -class CStaticDataInitCriticalSectionLock -{ -public: -#if (_ATL_VER >= 0x0700) - ATL::CComCritSecLock m_cslock; - - CStaticDataInitCriticalSectionLock() : m_cslock(ATL::_pAtlModule->m_csStaticDataInitAndTypeInfo, false) - { } -#endif // (_ATL_VER >= 0x0700) - - HRESULT Lock() - { -#if (_ATL_VER >= 0x0700) - return m_cslock.Lock(); -#else // !(_ATL_VER >= 0x0700) - ::EnterCriticalSection(&ATL::_pModule->m_csStaticDataInit); - return S_OK; -#endif // !(_ATL_VER >= 0x0700) - } - - void Unlock() - { -#if (_ATL_VER >= 0x0700) - m_cslock.Unlock(); -#else // !(_ATL_VER >= 0x0700) - ::LeaveCriticalSection(&ATL::_pModule->m_csStaticDataInit); -#endif // !(_ATL_VER >= 0x0700) - } -}; - - -class CWindowCreateCriticalSectionLock -{ -public: -#if (_ATL_VER >= 0x0700) - ATL::CComCritSecLock m_cslock; - - CWindowCreateCriticalSectionLock() : m_cslock(ATL::_AtlWinModule.m_csWindowCreate, false) - { } -#endif // (_ATL_VER >= 0x0700) - - HRESULT Lock() - { -#if (_ATL_VER >= 0x0700) - return m_cslock.Lock(); -#else // !(_ATL_VER >= 0x0700) - ::EnterCriticalSection(&ATL::_pModule->m_csWindowCreate); - return S_OK; -#endif // !(_ATL_VER >= 0x0700) - } - - void Unlock() - { -#if (_ATL_VER >= 0x0700) - m_cslock.Unlock(); -#else // !(_ATL_VER >= 0x0700) - ::LeaveCriticalSection(&ATL::_pModule->m_csWindowCreate); -#endif // !(_ATL_VER >= 0x0700) - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CTempBuffer - helper class for stack allocations for ATL3 - -#ifndef _WTL_STACK_ALLOC_THRESHOLD - #define _WTL_STACK_ALLOC_THRESHOLD 512 -#endif - -#if (_ATL_VER >= 0x0700) - -using ATL::CTempBuffer; - -#else // !(_ATL_VER >= 0x0700) - -#ifndef SIZE_MAX - #ifdef _WIN64 - #define SIZE_MAX _UI64_MAX - #else - #define SIZE_MAX UINT_MAX - #endif -#endif - -#pragma warning(disable: 4284) // warning for operator -> - -template -class CTempBuffer -{ -public: - CTempBuffer() : m_p(NULL) - { - } - - CTempBuffer(size_t nElements) : m_p(NULL) - { - Allocate(nElements); - } - - ~CTempBuffer() - { - if(m_p != reinterpret_cast(m_abFixedBuffer)) - free(m_p); - } - - operator T*() const - { - return m_p; - } - - T* operator ->() const - { - ATLASSERT(m_p != NULL); - return m_p; - } - - T* Allocate(size_t nElements) - { - ATLASSERT(nElements <= (SIZE_MAX / sizeof(T))); - return AllocateBytes(nElements * sizeof(T)); - } - - T* AllocateBytes(size_t nBytes) - { - ATLASSERT(m_p == NULL); - if(nBytes > t_nFixedBytes) - m_p = static_cast(malloc(nBytes)); - else - m_p = reinterpret_cast(m_abFixedBuffer); - - return m_p; - } - -private: - T* m_p; - BYTE m_abFixedBuffer[t_nFixedBytes]; -}; - -#pragma warning(default: 4284) - -#endif // !(_ATL_VER >= 0x0700) - - -/////////////////////////////////////////////////////////////////////////////// -// CAppModule - module class for an application - -class CAppModule : public ATL::CComModule -{ -public: - DWORD m_dwMainThreadID; - ATL::CSimpleMap* m_pMsgLoopMap; - ATL::CSimpleArray* m_pSettingChangeNotify; - -// Overrides of CComModule::Init and Term - HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL) - { - HRESULT hRet = CComModule::Init(pObjMap, hInstance, pLibID); - if(FAILED(hRet)) - return hRet; - - m_dwMainThreadID = ::GetCurrentThreadId(); - typedef ATL::CSimpleMap _mapClass; - m_pMsgLoopMap = NULL; - ATLTRY(m_pMsgLoopMap = new _mapClass); - if(m_pMsgLoopMap == NULL) - return E_OUTOFMEMORY; - m_pSettingChangeNotify = NULL; - - return hRet; - } - - void Term() - { - TermSettingChangeNotify(); - delete m_pMsgLoopMap; - CComModule::Term(); - } - -// Message loop map methods - BOOL AddMessageLoop(CMessageLoop* pMsgLoop) - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddMessageLoop.\n")); - ATLASSERT(FALSE); - return FALSE; - } - - ATLASSERT(pMsgLoop != NULL); - ATLASSERT(m_pMsgLoopMap->Lookup(::GetCurrentThreadId()) == NULL); // not in map yet - - BOOL bRet = m_pMsgLoopMap->Add(::GetCurrentThreadId(), pMsgLoop); - - lock.Unlock(); - - return bRet; - } - - BOOL RemoveMessageLoop() - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveMessageLoop.\n")); - ATLASSERT(FALSE); - return FALSE; - } - - BOOL bRet = m_pMsgLoopMap->Remove(::GetCurrentThreadId()); - - lock.Unlock(); - - return bRet; - } - - CMessageLoop* GetMessageLoop(DWORD dwThreadID = ::GetCurrentThreadId()) const - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::GetMessageLoop.\n")); - ATLASSERT(FALSE); - return NULL; - } - - CMessageLoop* pLoop = m_pMsgLoopMap->Lookup(dwThreadID); - - lock.Unlock(); - - return pLoop; - } - -// Setting change notify methods - // Note: Call this from the main thread for MSDI apps - BOOL InitSettingChangeNotify(DLGPROC pfnDlgProc = _SettingChangeDlgProc) - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::InitSettingChangeNotify.\n")); - ATLASSERT(FALSE); - return FALSE; - } - - if(m_pSettingChangeNotify == NULL) - { - typedef ATL::CSimpleArray _notifyClass; - ATLTRY(m_pSettingChangeNotify = new _notifyClass); - ATLASSERT(m_pSettingChangeNotify != NULL); - } - - BOOL bRet = (m_pSettingChangeNotify != NULL); - if(bRet && m_pSettingChangeNotify->GetSize() == 0) - { - // init everything - _ATL_EMPTY_DLGTEMPLATE templ; - HWND hNtfWnd = ::CreateDialogIndirect(GetModuleInstance(), &templ, NULL, pfnDlgProc); - ATLASSERT(::IsWindow(hNtfWnd)); - if(::IsWindow(hNtfWnd)) - { -// need conditional code because types don't match in winuser.h -#ifdef _WIN64 - ::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, (LONG_PTR)this); -#else - ::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, PtrToLong(this)); -#endif - bRet = m_pSettingChangeNotify->Add(hNtfWnd); - } - else - { - bRet = FALSE; - } - } - - lock.Unlock(); - - return bRet; - } - - void TermSettingChangeNotify() - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::TermSettingChangeNotify.\n")); - ATLASSERT(FALSE); - return; - } - - if(m_pSettingChangeNotify != NULL && m_pSettingChangeNotify->GetSize() > 0) - ::DestroyWindow((*m_pSettingChangeNotify)[0]); - delete m_pSettingChangeNotify; - m_pSettingChangeNotify = NULL; - - lock.Unlock(); - } - - BOOL AddSettingChangeNotify(HWND hWnd) - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddSettingChangeNotify.\n")); - ATLASSERT(FALSE); - return FALSE; - } - - ATLASSERT(::IsWindow(hWnd)); - BOOL bRet = FALSE; - if(InitSettingChangeNotify() != FALSE) - bRet = m_pSettingChangeNotify->Add(hWnd); - - lock.Unlock(); - - return bRet; - } - - BOOL RemoveSettingChangeNotify(HWND hWnd) - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveSettingChangeNotify.\n")); - ATLASSERT(FALSE); - return FALSE; - } - - BOOL bRet = FALSE; - if(m_pSettingChangeNotify != NULL) - bRet = m_pSettingChangeNotify->Remove(hWnd); - - lock.Unlock(); - - return bRet; - } - -// Implementation - setting change notify dialog template and dialog procedure - struct _ATL_EMPTY_DLGTEMPLATE : DLGTEMPLATE - { - _ATL_EMPTY_DLGTEMPLATE() - { - memset(this, 0, sizeof(_ATL_EMPTY_DLGTEMPLATE)); - style = WS_POPUP; - } - WORD wMenu, wClass, wTitle; - }; - -#ifdef _WIN64 - static INT_PTR CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -#else - static BOOL CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -#endif - { - if(uMsg == WM_SETTINGCHANGE) - { -// need conditional code because types don't match in winuser.h -#ifdef _WIN64 - CAppModule* pModule = (CAppModule*)::GetWindowLongPtr(hWnd, GWLP_USERDATA); -#else - CAppModule* pModule = (CAppModule*)LongToPtr(::GetWindowLongPtr(hWnd, GWLP_USERDATA)); -#endif - ATLASSERT(pModule != NULL); - ATLASSERT(pModule->m_pSettingChangeNotify != NULL); - const UINT uTimeout = 1500; // ms - for(int i = 1; i < pModule->m_pSettingChangeNotify->GetSize(); i++) - { -#if !defined(_WIN32_WCE) - ::SendMessageTimeout((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam, SMTO_ABORTIFHUNG, uTimeout, NULL); -#elif(_WIN32_WCE >= 400) // CE specific - ::SendMessageTimeout((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam, SMTO_NORMAL, uTimeout, NULL); -#else // _WIN32_WCE < 400 specific - uTimeout; - ::SendMessage((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam); -#endif - } - return TRUE; - } - return FALSE; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CServerAppModule - module class for a COM server application - -class CServerAppModule : public CAppModule -{ -public: - HANDLE m_hEventShutdown; - bool m_bActivity; - DWORD m_dwTimeOut; - DWORD m_dwPause; - -// Override of CAppModule::Init - HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL) - { - m_dwTimeOut = 5000; - m_dwPause = 1000; - return CAppModule::Init(pObjMap, hInstance, pLibID); - } - - void Term() - { - if(m_hEventShutdown != NULL && ::CloseHandle(m_hEventShutdown)) - m_hEventShutdown = NULL; - CAppModule::Term(); - } - -// COM Server methods - LONG Unlock() - { - LONG lRet = CComModule::Unlock(); - if(lRet == 0) - { - m_bActivity = true; - ::SetEvent(m_hEventShutdown); // tell monitor that we transitioned to zero - } - return lRet; - } - - void MonitorShutdown() - { - for(;;) - { - ::WaitForSingleObject(m_hEventShutdown, INFINITE); - DWORD dwWait = 0; - do - { - m_bActivity = false; - dwWait = ::WaitForSingleObject(m_hEventShutdown, m_dwTimeOut); - } - while(dwWait == WAIT_OBJECT_0); - // timed out - if(!m_bActivity && m_nLockCnt == 0) // if no activity let's really bail - { -#if ((_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM)) && defined(_ATL_FREE_THREADED) && !defined(_WIN32_WCE) - ::CoSuspendClassObjects(); - if(!m_bActivity && m_nLockCnt == 0) -#endif - break; - } - } - // This handle should be valid now. If it isn't, - // check if _Module.Term was called first (it shouldn't) - if(::CloseHandle(m_hEventShutdown)) - m_hEventShutdown = NULL; - ::PostThreadMessage(m_dwMainThreadID, WM_QUIT, 0, 0); - } - - bool StartMonitor() - { - m_hEventShutdown = ::CreateEvent(NULL, false, false, NULL); - if(m_hEventShutdown == NULL) - return false; - DWORD dwThreadID = 0; -#if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE) - HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, (UINT (WINAPI*)(void*))MonitorProc, this, 0, (UINT*)&dwThreadID); -#else - HANDLE hThread = ::CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID); -#endif - bool bRet = (hThread != NULL); - if(bRet) - ::CloseHandle(hThread); - return bRet; - } - - static DWORD WINAPI MonitorProc(void* pv) - { - CServerAppModule* p = (CServerAppModule*)pv; - p->MonitorShutdown(); - return 0; - } - -#if (_ATL_VER < 0x0700) - // search for an occurence of string p2 in string p1 - static LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2) - { - while(p1 != NULL && *p1 != NULL) - { - LPCTSTR p = p2; - while(p != NULL && *p != NULL) - { - if(*p1 == *p) - return ::CharNext(p1); - p = ::CharNext(p); - } - p1 = ::CharNext(p1); - } - return NULL; - } -#endif // (_ATL_VER < 0x0700) -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CRegKeyEx - adds type-specific methods to ATL3 CRegKey - -#if (_ATL_VER < 0x0700) - -class CRegKeyEx : public ATL::CRegKey -{ -public: -// Constructors and operators - CRegKeyEx(HKEY hKey = NULL) - { - m_hKey = hKey; - } - - CRegKeyEx(CRegKeyEx& key) - { - Attach(key.Detach()); - } - - CRegKeyEx& operator =(CRegKeyEx& key) - { - Close(); - Attach(key.Detach()); - return *this; - } - -// Methods - LONG SetValue(LPCTSTR pszValueName, DWORD dwType, const void* pValue, ULONG nBytes) - { - ATLASSERT(m_hKey != NULL); - return ::RegSetValueEx(m_hKey, pszValueName, NULL, dwType, static_cast(pValue), nBytes); - } - - LONG SetGUIDValue(LPCTSTR pszValueName, REFGUID guidValue) - { - ATLASSERT(m_hKey != NULL); - - OLECHAR szGUID[64] = { 0 }; - ::StringFromGUID2(guidValue, szGUID, 64); - - USES_CONVERSION; - LPCTSTR lpstr = OLE2CT(szGUID); -#ifndef _UNICODE - if(lpstr == NULL) - return E_OUTOFMEMORY; -#endif - return SetStringValue(pszValueName, lpstr); - } - - LONG SetBinaryValue(LPCTSTR pszValueName, const void* pValue, ULONG nBytes) - { - ATLASSERT(m_hKey != NULL); - return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_BINARY, reinterpret_cast(pValue), nBytes); - } - - LONG SetDWORDValue(LPCTSTR pszValueName, DWORD dwValue) - { - ATLASSERT(m_hKey != NULL); - return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_DWORD, reinterpret_cast(&dwValue), sizeof(DWORD)); - } - -#ifndef _WIN32_WCE - LONG SetQWORDValue(LPCTSTR pszValueName, ULONGLONG qwValue) - { - ATLASSERT(m_hKey != NULL); - return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_QWORD, reinterpret_cast(&qwValue), sizeof(ULONGLONG)); - } -#endif - - LONG SetStringValue(LPCTSTR pszValueName, LPCTSTR pszValue, DWORD dwType = REG_SZ) - { - ATLASSERT(m_hKey != NULL); - if(pszValue == NULL) - { - ATLASSERT(FALSE); - return ERROR_INVALID_DATA; - } - ATLASSERT((dwType == REG_SZ) || (dwType == REG_EXPAND_SZ)); - - return ::RegSetValueEx(m_hKey, pszValueName, NULL, dwType, reinterpret_cast(pszValue), (lstrlen(pszValue) + 1) * sizeof(TCHAR)); - } - - LONG SetMultiStringValue(LPCTSTR pszValueName, LPCTSTR pszValue) - { - ATLASSERT(m_hKey != NULL); - if(pszValue == NULL) - { - ATLASSERT(FALSE); - return ERROR_INVALID_DATA; - } - - ULONG nBytes = 0; - ULONG nLength = 0; - LPCTSTR pszTemp = pszValue; - do - { - nLength = lstrlen(pszTemp) + 1; - pszTemp += nLength; - nBytes += nLength * sizeof(TCHAR); - } while (nLength != 1); - - return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_MULTI_SZ, reinterpret_cast(pszValue), nBytes); - } - - LONG QueryValue(LPCTSTR pszValueName, DWORD* pdwType, void* pData, ULONG* pnBytes) - { - ATLASSERT(m_hKey != NULL); - return ::RegQueryValueEx(m_hKey, pszValueName, NULL, pdwType, static_cast(pData), pnBytes); - } - - LONG QueryGUIDValue(LPCTSTR pszValueName, GUID& guidValue) - { - ATLASSERT(m_hKey != NULL); - - guidValue = GUID_NULL; - - TCHAR szGUID[64] = { 0 }; - ULONG nCount = 64; - LONG lRes = QueryStringValue(pszValueName, szGUID, &nCount); - - if (lRes != ERROR_SUCCESS) - return lRes; - - if(szGUID[0] != _T('{')) - return ERROR_INVALID_DATA; - - USES_CONVERSION; - LPOLESTR lpstr = T2OLE(szGUID); -#ifndef _UNICODE - if(lpstr == NULL) - return E_OUTOFMEMORY; -#endif - - HRESULT hr = ::CLSIDFromString(lpstr, &guidValue); - if (FAILED(hr)) - return ERROR_INVALID_DATA; - - return ERROR_SUCCESS; - } - - LONG QueryBinaryValue(LPCTSTR pszValueName, void* pValue, ULONG* pnBytes) - { - ATLASSERT(pnBytes != NULL); - ATLASSERT(m_hKey != NULL); - - DWORD dwType = 0; - LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast(pValue), pnBytes); - if (lRes != ERROR_SUCCESS) - return lRes; - if (dwType != REG_BINARY) - return ERROR_INVALID_DATA; - - return ERROR_SUCCESS; - } - - LONG QueryDWORDValue(LPCTSTR pszValueName, DWORD& dwValue) - { - ATLASSERT(m_hKey != NULL); - - ULONG nBytes = sizeof(DWORD); - DWORD dwType = 0; - LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast(&dwValue), &nBytes); - if (lRes != ERROR_SUCCESS) - return lRes; - if (dwType != REG_DWORD) - return ERROR_INVALID_DATA; - - return ERROR_SUCCESS; - } - - LONG QueryQWORDValue(LPCTSTR pszValueName, ULONGLONG& qwValue) - { - ATLASSERT(m_hKey != NULL); - - ULONG nBytes = sizeof(ULONGLONG); - DWORD dwType = 0; - LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast(&qwValue), &nBytes); - if (lRes != ERROR_SUCCESS) - return lRes; - if (dwType != REG_QWORD) - return ERROR_INVALID_DATA; - - return ERROR_SUCCESS; - } - - LONG QueryStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG* pnChars) - { - ATLASSERT(m_hKey != NULL); - ATLASSERT(pnChars != NULL); - - ULONG nBytes = (*pnChars) * sizeof(TCHAR); - DWORD dwType = 0; - *pnChars = 0; - LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast(pszValue), &nBytes); - - if (lRes != ERROR_SUCCESS) - { - return lRes; - } - - if(dwType != REG_SZ && dwType != REG_EXPAND_SZ) - { - return ERROR_INVALID_DATA; - } - - if (pszValue != NULL) - { - if(nBytes != 0) - { - if ((nBytes % sizeof(TCHAR) != 0) || (pszValue[nBytes / sizeof(TCHAR) -1] != 0)) - return ERROR_INVALID_DATA; - } - else - { - pszValue[0] = _T('\0'); - } - } - - *pnChars = nBytes / sizeof(TCHAR); - - return ERROR_SUCCESS; - } - - LONG QueryMultiStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG* pnChars) - { - ATLASSERT(m_hKey != NULL); - ATLASSERT(pnChars != NULL); - - if (pszValue != NULL && *pnChars < 2) - return ERROR_INSUFFICIENT_BUFFER; - - ULONG nBytes = (*pnChars) * sizeof(TCHAR); - DWORD dwType = 0; - *pnChars = 0; - LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast(pszValue), &nBytes); - if (lRes != ERROR_SUCCESS) - return lRes; - if (dwType != REG_MULTI_SZ) - return ERROR_INVALID_DATA; - if (pszValue != NULL && (nBytes % sizeof(TCHAR) != 0 || nBytes / sizeof(TCHAR) < 1 || pszValue[nBytes / sizeof(TCHAR) - 1] != 0 || ((nBytes / sizeof(TCHAR)) > 1 && pszValue[nBytes / sizeof(TCHAR) - 2] != 0))) - return ERROR_INVALID_DATA; - - *pnChars = nBytes / sizeof(TCHAR); - - return ERROR_SUCCESS; - } -}; - -#else // !(_ATL_VER < 0x0700) - -typedef ATL::CRegKey CRegKeyEx; - -#endif // !(_ATL_VER < 0x0700) - - -/////////////////////////////////////////////////////////////////////////////// -// CString forward reference (enables CString use in atluser.h and atlgdi.h) - -#if defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING) - #define _WTL_USE_CSTRING -#endif // defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING) - -#ifdef _WTL_USE_CSTRING - class CString; // forward declaration (include atlmisc.h for the whole class) -#endif // _WTL_USE_CSTRING - -// CString namespace -#ifndef _CSTRING_NS - #ifdef __ATLSTR_H__ - #define _CSTRING_NS ATL - #else - #define _CSTRING_NS WTL - #endif -#endif // _CSTRING_NS - -// Type classes namespace -#ifndef _WTYPES_NS - #ifdef __ATLTYPES_H__ - #define _WTYPES_NS - #else - #define _WTYPES_NS WTL - #endif -#endif // _WTYPES_NS - -}; // namespace WTL - - -/////////////////////////////////////////////////////////////////////////////// -// General DLL version helpers (excluded from atlbase.h if _ATL_DLL is defined) - -#if (_ATL_VER < 0x0700) && defined(_ATL_DLL) && !defined(_WIN32_WCE) - -namespace ATL -{ - -inline HRESULT AtlGetDllVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionInfo) -{ - ATLASSERT(pDllVersionInfo != NULL); - if(pDllVersionInfo == NULL) - return E_INVALIDARG; - - // We must get this function explicitly because some DLLs don't implement it. - DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress(hInstDLL, "DllGetVersion"); - if(pfnDllGetVersion == NULL) - return E_NOTIMPL; - - return (*pfnDllGetVersion)(pDllVersionInfo); -} - -inline HRESULT AtlGetDllVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersionInfo) -{ - HINSTANCE hInstDLL = ::LoadLibrary(lpstrDllName); - if(hInstDLL == NULL) - return E_FAIL; - HRESULT hRet = AtlGetDllVersion(hInstDLL, pDllVersionInfo); - ::FreeLibrary(hInstDLL); - return hRet; -} - -// Common Control Versions: -// Win95/WinNT 4.0 maj=4 min=00 -// IE 3.x maj=4 min=70 -// IE 4.0 maj=4 min=71 -inline HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor) -{ - ATLASSERT(pdwMajor != NULL && pdwMinor != NULL); - if(pdwMajor == NULL || pdwMinor == NULL) - return E_INVALIDARG; - - DLLVERSIONINFO dvi; - ::ZeroMemory(&dvi, sizeof(dvi)); - dvi.cbSize = sizeof(dvi); - HRESULT hRet = AtlGetDllVersion(_T("comctl32.dll"), &dvi); - - if(SUCCEEDED(hRet)) - { - *pdwMajor = dvi.dwMajorVersion; - *pdwMinor = dvi.dwMinorVersion; - } - else if(hRet == E_NOTIMPL) - { - // If DllGetVersion is not there, then the DLL is a version - // previous to the one shipped with IE 3.x - *pdwMajor = 4; - *pdwMinor = 0; - hRet = S_OK; - } - - return hRet; -} - -// Shell Versions: -// Win95/WinNT 4.0 maj=4 min=00 -// IE 3.x, IE 4.0 without Web Integrated Desktop maj=4 min=00 -// IE 4.0 with Web Integrated Desktop maj=4 min=71 -// IE 4.01 with Web Integrated Desktop maj=4 min=72 -inline HRESULT AtlGetShellVersion(LPDWORD pdwMajor, LPDWORD pdwMinor) -{ - ATLASSERT(pdwMajor != NULL && pdwMinor != NULL); - if(pdwMajor == NULL || pdwMinor == NULL) - return E_INVALIDARG; - - DLLVERSIONINFO dvi; - ::ZeroMemory(&dvi, sizeof(dvi)); - dvi.cbSize = sizeof(dvi); - HRESULT hRet = AtlGetDllVersion(_T("shell32.dll"), &dvi); - - if(SUCCEEDED(hRet)) - { - *pdwMajor = dvi.dwMajorVersion; - *pdwMinor = dvi.dwMinorVersion; - } - else if(hRet == E_NOTIMPL) - { - // If DllGetVersion is not there, then the DLL is a version - // previous to the one shipped with IE 4.x - *pdwMajor = 4; - *pdwMinor = 0; - hRet = S_OK; - } - - return hRet; -} - -}; // namespace ATL - -#endif // (_ATL_VER < 0x0700) && defined(_ATL_DLL) && !defined(_WIN32_WCE) - - -// These are always included -#include "atlwinx.h" -#include "atluser.h" -#include "atlgdi.h" - -#ifndef _WTL_NO_AUTOMATIC_NAMESPACE -using namespace WTL; -#endif // !_WTL_NO_AUTOMATIC_NAMESPACE - -#endif // __ATLAPP_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlcrack.h b/!NotAdopted/SmartAutoReplier/wtl/atlcrack.h deleted file mode 100644 index b9971b5510..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlcrack.h +++ /dev/null @@ -1,2384 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLCRACK_H__ -#define __ATLCRACK_H__ - -#pragma once - -#ifndef __ATLAPP_H__ - #error atlcrack.h requires atlapp.h to be included first -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// Message map macro for cracked handlers - -// Note about message maps with cracked handlers: -// For ATL 3.0, a message map using cracked handlers MUST use BEGIN_MSG_MAP_EX. -// For ATL 7.0 or higher, you can use BEGIN_MSG_MAP for CWindowImpl/CDialogImpl derived classes, -// but must use BEGIN_MSG_MAP_EX for classes that don't derive from CWindowImpl/CDialogImpl. - -#define BEGIN_MSG_MAP_EX(theClass) \ -public: \ - BOOL m_bMsgHandled; \ - /* "handled" management for cracked handlers */ \ - BOOL IsMsgHandled() const \ - { \ - return m_bMsgHandled; \ - } \ - void SetMsgHandled(BOOL bHandled) \ - { \ - m_bMsgHandled = bHandled; \ - } \ - BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0) \ - { \ - BOOL bOldMsgHandled = m_bMsgHandled; \ - BOOL bRet = _ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, dwMsgMapID); \ - m_bMsgHandled = bOldMsgHandled; \ - return bRet; \ - } \ - BOOL _ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID) \ - { \ - BOOL bHandled = TRUE; \ - hWnd; \ - uMsg; \ - wParam; \ - lParam; \ - lResult; \ - bHandled; \ - switch(dwMsgMapID) \ - { \ - case 0: - - -/////////////////////////////////////////////////////////////////////////////// -// Standard Windows message macros - -// int OnCreate(LPCREATESTRUCT lpCreateStruct) -#define MSG_WM_CREATE(func) \ - if (uMsg == WM_CREATE) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((LPCREATESTRUCT)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam) -#define MSG_WM_INITDIALOG(func) \ - if (uMsg == WM_INITDIALOG) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HWND)wParam, lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// BOOL OnCopyData(CWindow wnd, PCOPYDATASTRUCT pCopyDataStruct) -#define MSG_WM_COPYDATA(func) \ - if (uMsg == WM_COPYDATA) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HWND)wParam, (PCOPYDATASTRUCT)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnDestroy() -#define MSG_WM_DESTROY(func) \ - if (uMsg == WM_DESTROY) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnMove(CPoint ptPos) -#define MSG_WM_MOVE(func) \ - if (uMsg == WM_MOVE) \ - { \ - SetMsgHandled(TRUE); \ - func(_WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnSize(UINT nType, CSize size) -#define MSG_WM_SIZE(func) \ - if (uMsg == WM_SIZE) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnActivate(UINT nState, BOOL bMinimized, CWindow wndOther) -#define MSG_WM_ACTIVATE(func) \ - if (uMsg == WM_ACTIVATE) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)LOWORD(wParam), (BOOL)HIWORD(wParam), (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnSetFocus(CWindow wndOld) -#define MSG_WM_SETFOCUS(func) \ - if (uMsg == WM_SETFOCUS) \ - { \ - SetMsgHandled(TRUE); \ - func((HWND)wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnKillFocus(CWindow wndFocus) -#define MSG_WM_KILLFOCUS(func) \ - if (uMsg == WM_KILLFOCUS) \ - { \ - SetMsgHandled(TRUE); \ - func((HWND)wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnEnable(BOOL bEnable) -#define MSG_WM_ENABLE(func) \ - if (uMsg == WM_ENABLE) \ - { \ - SetMsgHandled(TRUE); \ - func((BOOL)wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnPaint(CDCHandle dc) -#define MSG_WM_PAINT(func) \ - if (uMsg == WM_PAINT) \ - { \ - SetMsgHandled(TRUE); \ - func((HDC)wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnClose() -#define MSG_WM_CLOSE(func) \ - if (uMsg == WM_CLOSE) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// BOOL OnQueryEndSession(UINT nSource, UINT uLogOff) -#define MSG_WM_QUERYENDSESSION(func) \ - if (uMsg == WM_QUERYENDSESSION) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((UINT)wParam, (UINT)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// BOOL OnQueryOpen() -#define MSG_WM_QUERYOPEN(func) \ - if (uMsg == WM_QUERYOPEN) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func(); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// BOOL OnEraseBkgnd(CDCHandle dc) -#define MSG_WM_ERASEBKGND(func) \ - if (uMsg == WM_ERASEBKGND) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HDC)wParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnSysColorChange() -#define MSG_WM_SYSCOLORCHANGE(func) \ - if (uMsg == WM_SYSCOLORCHANGE) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnEndSession(BOOL bEnding, UINT uLogOff) -#define MSG_WM_ENDSESSION(func) \ - if (uMsg == WM_ENDSESSION) \ - { \ - SetMsgHandled(TRUE); \ - func((BOOL)wParam, (UINT)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnShowWindow(BOOL bShow, UINT nStatus) -#define MSG_WM_SHOWWINDOW(func) \ - if (uMsg == WM_SHOWWINDOW) \ - { \ - SetMsgHandled(TRUE); \ - func((BOOL)wParam, (int)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// HBRUSH OnCtlColorEdit(CDCHandle dc, CEdit edit) -#define MSG_WM_CTLCOLOREDIT(func) \ - if (uMsg == WM_CTLCOLOREDIT) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// HBRUSH OnCtlColorListBox(CDCHandle dc, CListBox listBox) -#define MSG_WM_CTLCOLORLISTBOX(func) \ - if (uMsg == WM_CTLCOLORLISTBOX) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// HBRUSH OnCtlColorBtn(CDCHandle dc, CButton button) -#define MSG_WM_CTLCOLORBTN(func) \ - if (uMsg == WM_CTLCOLORBTN) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// HBRUSH OnCtlColorDlg(CDCHandle dc, CWindow wnd) -#define MSG_WM_CTLCOLORDLG(func) \ - if (uMsg == WM_CTLCOLORDLG) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// HBRUSH OnCtlColorScrollBar(CDCHandle dc, CScrollBar scrollBar) -#define MSG_WM_CTLCOLORSCROLLBAR(func) \ - if (uMsg == WM_CTLCOLORSCROLLBAR) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// HBRUSH OnCtlColorStatic(CDCHandle dc, CStatic wndStatic) -#define MSG_WM_CTLCOLORSTATIC(func) \ - if (uMsg == WM_CTLCOLORSTATIC) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnSettingChange(UINT uFlags, LPCTSTR lpszSection) -#define MSG_WM_SETTINGCHANGE(func) \ - if (uMsg == WM_SETTINGCHANGE) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, (LPCTSTR)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnDevModeChange(LPCTSTR lpDeviceName) -#define MSG_WM_DEVMODECHANGE(func) \ - if (uMsg == WM_DEVMODECHANGE) \ - { \ - SetMsgHandled(TRUE); \ - func((LPCTSTR)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnActivateApp(BOOL bActive, DWORD dwThreadID) -#define MSG_WM_ACTIVATEAPP(func) \ - if (uMsg == WM_ACTIVATEAPP) \ - { \ - SetMsgHandled(TRUE); \ - func((BOOL)wParam, (DWORD)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnFontChange() -#define MSG_WM_FONTCHANGE(func) \ - if (uMsg == WM_FONTCHANGE) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnTimeChange() -#define MSG_WM_TIMECHANGE(func) \ - if (uMsg == WM_TIMECHANGE) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnCancelMode() -#define MSG_WM_CANCELMODE(func) \ - if (uMsg == WM_CANCELMODE) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// BOOL OnSetCursor(CWindow wnd, UINT nHitTest, UINT message) -#define MSG_WM_SETCURSOR(func) \ - if (uMsg == WM_SETCURSOR) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HWND)wParam, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// int OnMouseActivate(CWindow wndTopLevel, UINT nHitTest, UINT message) -#define MSG_WM_MOUSEACTIVATE(func) \ - if (uMsg == WM_MOUSEACTIVATE) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HWND)wParam, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnChildActivate() -#define MSG_WM_CHILDACTIVATE(func) \ - if (uMsg == WM_CHILDACTIVATE) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnGetMinMaxInfo(LPMINMAXINFO lpMMI) -#define MSG_WM_GETMINMAXINFO(func) \ - if (uMsg == WM_GETMINMAXINFO) \ - { \ - SetMsgHandled(TRUE); \ - func((LPMINMAXINFO)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnIconEraseBkgnd(CDCHandle dc) -#define MSG_WM_ICONERASEBKGND(func) \ - if (uMsg == WM_ICONERASEBKGND) \ - { \ - SetMsgHandled(TRUE); \ - func((HDC)wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnSpoolerStatus(UINT nStatus, UINT nJobs) -#define MSG_WM_SPOOLERSTATUS(func) \ - if (uMsg == WM_SPOOLERSTATUS) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, (UINT)LOWORD(lParam)); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) -#define MSG_WM_DRAWITEM(func) \ - if (uMsg == WM_DRAWITEM) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, (LPDRAWITEMSTRUCT)lParam); \ - lResult = TRUE; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct) -#define MSG_WM_MEASUREITEM(func) \ - if (uMsg == WM_MEASUREITEM) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, (LPMEASUREITEMSTRUCT)lParam); \ - lResult = TRUE; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnDeleteItem(int nIDCtl, LPDELETEITEMSTRUCT lpDeleteItemStruct) -#define MSG_WM_DELETEITEM(func) \ - if (uMsg == WM_DELETEITEM) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, (LPDELETEITEMSTRUCT)lParam); \ - lResult = TRUE; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -//int OnCharToItem(UINT nChar, UINT nIndex, CListBox listBox) -#define MSG_WM_CHARTOITEM(func) \ - if (uMsg == WM_CHARTOITEM) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), (HWND)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// int OnVKeyToItem(UINT nKey, UINT nIndex, CListBox listBox) -#define MSG_WM_VKEYTOITEM(func) \ - if (uMsg == WM_VKEYTOITEM) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), (HWND)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// HCURSOR OnQueryDragIcon() -#define MSG_WM_QUERYDRAGICON(func) \ - if (uMsg == WM_QUERYDRAGICON) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func(); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// int OnCompareItem(int nIDCtl, LPCOMPAREITEMSTRUCT lpCompareItemStruct) -#define MSG_WM_COMPAREITEM(func) \ - if (uMsg == WM_COMPAREITEM) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((UINT)wParam, (LPCOMPAREITEMSTRUCT)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnCompacting(UINT nCpuTime) -#define MSG_WM_COMPACTING(func) \ - if (uMsg == WM_COMPACTING) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// BOOL OnNcCreate(LPCREATESTRUCT lpCreateStruct) -#define MSG_WM_NCCREATE(func) \ - if (uMsg == WM_NCCREATE) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((LPCREATESTRUCT)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnNcDestroy() -#define MSG_WM_NCDESTROY(func) \ - if (uMsg == WM_NCDESTROY) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnNcCalcSize(BOOL bCalcValidRects, LPARAM lParam) -#define MSG_WM_NCCALCSIZE(func) \ - if (uMsg == WM_NCCALCSIZE) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func((BOOL)wParam, lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// UINT OnNcHitTest(CPoint point) -#define MSG_WM_NCHITTEST(func) \ - if (uMsg == WM_NCHITTEST) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func(_WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnNcPaint(CRgnHandle rgn) -#define MSG_WM_NCPAINT(func) \ - if (uMsg == WM_NCPAINT) \ - { \ - SetMsgHandled(TRUE); \ - func((HRGN)wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// BOOL OnNcActivate(BOOL bActive) -#define MSG_WM_NCACTIVATE(func) \ - if (uMsg == WM_NCACTIVATE) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((BOOL)wParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// UINT OnGetDlgCode(LPMSG lpMsg) -#define MSG_WM_GETDLGCODE(func) \ - if (uMsg == WM_GETDLGCODE) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((LPMSG)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnNcMouseMove(UINT nHitTest, CPoint point) -#define MSG_WM_NCMOUSEMOVE(func) \ - if (uMsg == WM_NCMOUSEMOVE) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnNcLButtonDown(UINT nHitTest, CPoint point) -#define MSG_WM_NCLBUTTONDOWN(func) \ - if (uMsg == WM_NCLBUTTONDOWN) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnNcLButtonUp(UINT nHitTest, CPoint point) -#define MSG_WM_NCLBUTTONUP(func) \ - if (uMsg == WM_NCLBUTTONUP) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnNcLButtonDblClk(UINT nHitTest, CPoint point) -#define MSG_WM_NCLBUTTONDBLCLK(func) \ - if (uMsg == WM_NCLBUTTONDBLCLK) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnNcRButtonDown(UINT nHitTest, CPoint point) -#define MSG_WM_NCRBUTTONDOWN(func) \ - if (uMsg == WM_NCRBUTTONDOWN) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnNcRButtonUp(UINT nHitTest, CPoint point) -#define MSG_WM_NCRBUTTONUP(func) \ - if (uMsg == WM_NCRBUTTONUP) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnNcRButtonDblClk(UINT nHitTest, CPoint point) -#define MSG_WM_NCRBUTTONDBLCLK(func) \ - if (uMsg == WM_NCRBUTTONDBLCLK) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnNcMButtonDown(UINT nHitTest, CPoint point) -#define MSG_WM_NCMBUTTONDOWN(func) \ - if (uMsg == WM_NCMBUTTONDOWN) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnNcMButtonUp(UINT nHitTest, CPoint point) -#define MSG_WM_NCMBUTTONUP(func) \ - if (uMsg == WM_NCMBUTTONUP) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnNcMButtonDblClk(UINT nHitTest, CPoint point) -#define MSG_WM_NCMBUTTONDBLCLK(func) \ - if (uMsg == WM_NCMBUTTONDBLCLK) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -#define MSG_WM_KEYDOWN(func) \ - if (uMsg == WM_KEYDOWN) \ - { \ - SetMsgHandled(TRUE); \ - func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -#define MSG_WM_KEYUP(func) \ - if (uMsg == WM_KEYUP) \ - { \ - SetMsgHandled(TRUE); \ - func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) -#define MSG_WM_CHAR(func) \ - if (uMsg == WM_CHAR) \ - { \ - SetMsgHandled(TRUE); \ - func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnDeadChar(UINT nChar, UINT nRepCnt, UINT nFlags) -#define MSG_WM_DEADCHAR(func) \ - if (uMsg == WM_DEADCHAR) \ - { \ - SetMsgHandled(TRUE); \ - func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) -#define MSG_WM_SYSKEYDOWN(func) \ - if (uMsg == WM_SYSKEYDOWN) \ - { \ - SetMsgHandled(TRUE); \ - func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnSysKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) -#define MSG_WM_SYSKEYUP(func) \ - if (uMsg == WM_SYSKEYUP) \ - { \ - SetMsgHandled(TRUE); \ - func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnSysChar(UINT nChar, UINT nRepCnt, UINT nFlags) -#define MSG_WM_SYSCHAR(func) \ - if (uMsg == WM_SYSCHAR) \ - { \ - SetMsgHandled(TRUE); \ - func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnSysDeadChar(UINT nChar, UINT nRepCnt, UINT nFlags) -#define MSG_WM_SYSDEADCHAR(func) \ - if (uMsg == WM_SYSDEADCHAR) \ - { \ - SetMsgHandled(TRUE); \ - func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnSysCommand(UINT nID, LPARAM lParam) -#define MSG_WM_SYSCOMMAND(func) \ - if (uMsg == WM_SYSCOMMAND) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnTCard(UINT idAction, DWORD dwActionData) -#define MSG_WM_TCARD(func) \ - if (uMsg == WM_TCARD) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, (DWORD)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnTimer(UINT_PTR nIDEvent) -#define MSG_WM_TIMER(func) \ - if (uMsg == WM_TIMER) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT_PTR)wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar) -#define MSG_WM_HSCROLL(func) \ - if (uMsg == WM_HSCROLL) \ - { \ - SetMsgHandled(TRUE); \ - func((int)LOWORD(wParam), (short)HIWORD(wParam), (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar) -#define MSG_WM_VSCROLL(func) \ - if (uMsg == WM_VSCROLL) \ - { \ - SetMsgHandled(TRUE); \ - func((int)LOWORD(wParam), (short)HIWORD(wParam), (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnInitMenu(CMenuHandle menu) -#define MSG_WM_INITMENU(func) \ - if (uMsg == WM_INITMENU) \ - { \ - SetMsgHandled(TRUE); \ - func((HMENU)wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnInitMenuPopup(CMenuHandle menuPopup, UINT nIndex, BOOL bSysMenu) -#define MSG_WM_INITMENUPOPUP(func) \ - if (uMsg == WM_INITMENUPOPUP) \ - { \ - SetMsgHandled(TRUE); \ - func((HMENU)wParam, (UINT)LOWORD(lParam), (BOOL)HIWORD(lParam)); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnMenuSelect(UINT nItemID, UINT nFlags, CMenuHandle menu) -#define MSG_WM_MENUSELECT(func) \ - if (uMsg == WM_MENUSELECT) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), (HMENU)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnMenuChar(UINT nChar, UINT nFlags, CMenuHandle menu) -#define MSG_WM_MENUCHAR(func) \ - if (uMsg == WM_MENUCHAR) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func((TCHAR)LOWORD(wParam), (UINT)HIWORD(wParam), (HMENU)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnNotify(int idCtrl, LPNMHDR pnmh) -#define MSG_WM_NOTIFY(func) \ - if (uMsg == WM_NOTIFY) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func((int)wParam, (LPNMHDR)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnEnterIdle(UINT nWhy, CWindow wndWho) -#define MSG_WM_ENTERIDLE(func) \ - if (uMsg == WM_ENTERIDLE) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnMouseMove(UINT nFlags, CPoint point) -#define MSG_WM_MOUSEMOVE(func) \ - if (uMsg == WM_MOUSEMOVE) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) -#define MSG_WM_MOUSEWHEEL(func) \ - if (uMsg == WM_MOUSEWHEEL) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((UINT)LOWORD(wParam), (short)HIWORD(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnLButtonDown(UINT nFlags, CPoint point) -#define MSG_WM_LBUTTONDOWN(func) \ - if (uMsg == WM_LBUTTONDOWN) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnLButtonUp(UINT nFlags, CPoint point) -#define MSG_WM_LBUTTONUP(func) \ - if (uMsg == WM_LBUTTONUP) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnLButtonDblClk(UINT nFlags, CPoint point) -#define MSG_WM_LBUTTONDBLCLK(func) \ - if (uMsg == WM_LBUTTONDBLCLK) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnRButtonDown(UINT nFlags, CPoint point) -#define MSG_WM_RBUTTONDOWN(func) \ - if (uMsg == WM_RBUTTONDOWN) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnRButtonUp(UINT nFlags, CPoint point) -#define MSG_WM_RBUTTONUP(func) \ - if (uMsg == WM_RBUTTONUP) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnRButtonDblClk(UINT nFlags, CPoint point) -#define MSG_WM_RBUTTONDBLCLK(func) \ - if (uMsg == WM_RBUTTONDBLCLK) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnMButtonDown(UINT nFlags, CPoint point) -#define MSG_WM_MBUTTONDOWN(func) \ - if (uMsg == WM_MBUTTONDOWN) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnMButtonUp(UINT nFlags, CPoint point) -#define MSG_WM_MBUTTONUP(func) \ - if (uMsg == WM_MBUTTONUP) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnMButtonDblClk(UINT nFlags, CPoint point) -#define MSG_WM_MBUTTONDBLCLK(func) \ - if (uMsg == WM_MBUTTONDBLCLK) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnParentNotify(UINT message, UINT nChildID, LPARAM lParam) -#define MSG_WM_PARENTNOTIFY(func) \ - if (uMsg == WM_PARENTNOTIFY) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnMDIActivate(CWindow wndActivate, CWindow wndDeactivate) -#define MSG_WM_MDIACTIVATE(func) \ - if (uMsg == WM_MDIACTIVATE) \ - { \ - SetMsgHandled(TRUE); \ - func((HWND)wParam, (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnRenderFormat(UINT nFormat) -#define MSG_WM_RENDERFORMAT(func) \ - if (uMsg == WM_RENDERFORMAT) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnRenderAllFormats() -#define MSG_WM_RENDERALLFORMATS(func) \ - if (uMsg == WM_RENDERALLFORMATS) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnDestroyClipboard() -#define MSG_WM_DESTROYCLIPBOARD(func) \ - if (uMsg == WM_DESTROYCLIPBOARD) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnDrawClipboard() -#define MSG_WM_DRAWCLIPBOARD(func) \ - if (uMsg == WM_DRAWCLIPBOARD) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnPaintClipboard(CWindow wndViewer, const LPPAINTSTRUCT lpPaintStruct) -#define MSG_WM_PAINTCLIPBOARD(func) \ - if (uMsg == WM_PAINTCLIPBOARD) \ - { \ - SetMsgHandled(TRUE); \ - func((HWND)wParam, (const LPPAINTSTRUCT)::GlobalLock((HGLOBAL)lParam)); \ - ::GlobalUnlock((HGLOBAL)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnVScrollClipboard(CWindow wndViewer, UINT nSBCode, UINT nPos) -#define MSG_WM_VSCROLLCLIPBOARD(func) \ - if (uMsg == WM_VSCROLLCLIPBOARD) \ - { \ - SetMsgHandled(TRUE); \ - func((HWND)wParam, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnContextMenu(CWindow wnd, CPoint point) -#define MSG_WM_CONTEXTMENU(func) \ - if (uMsg == WM_CONTEXTMENU) \ - { \ - SetMsgHandled(TRUE); \ - func((HWND)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnSizeClipboard(CWindow wndViewer, const LPRECT lpRect) -#define MSG_WM_SIZECLIPBOARD(func) \ - if (uMsg == WM_SIZECLIPBOARD) \ - { \ - SetMsgHandled(TRUE); \ - func((HWND)wParam, (const LPRECT)::GlobalLock((HGLOBAL)lParam)); \ - ::GlobalUnlock((HGLOBAL)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnAskCbFormatName(UINT nMaxCount, LPTSTR lpszString) -#define MSG_WM_ASKCBFORMATNAME(func) \ - if (uMsg == WM_ASKCBFORMATNAME) \ - { \ - SetMsgHandled(TRUE); \ - func((DWORD)wParam, (LPTSTR)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnChangeCbChain(CWindow wndRemove, CWindow wndAfter) -#define MSG_WM_CHANGECBCHAIN(func) \ - if (uMsg == WM_CHANGECBCHAIN) \ - { \ - SetMsgHandled(TRUE); \ - func((HWND)wParam, (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnHScrollClipboard(CWindow wndViewer, UINT nSBCode, UINT nPos) -#define MSG_WM_HSCROLLCLIPBOARD(func) \ - if (uMsg == WM_HSCROLLCLIPBOARD) \ - { \ - SetMsgHandled(TRUE); \ - func((HWND)wParam, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// BOOL OnQueryNewPalette() -#define MSG_WM_QUERYNEWPALETTE(func) \ - if (uMsg == WM_QUERYNEWPALETTE) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func(); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnPaletteChanged(CWindow wndFocus) -#define MSG_WM_PALETTECHANGED(func) \ - if (uMsg == WM_PALETTECHANGED) \ - { \ - SetMsgHandled(TRUE); \ - func((HWND)wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnPaletteIsChanging(CWindow wndPalChg) -#define MSG_WM_PALETTEISCHANGING(func) \ - if (uMsg == WM_PALETTEISCHANGING) \ - { \ - SetMsgHandled(TRUE); \ - func((HWND)wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnDropFiles(HDROP hDropInfo) -#define MSG_WM_DROPFILES(func) \ - if (uMsg == WM_DROPFILES) \ - { \ - SetMsgHandled(TRUE); \ - func((HDROP)wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnWindowPosChanging(LPWINDOWPOS lpWndPos) -#define MSG_WM_WINDOWPOSCHANGING(func) \ - if (uMsg == WM_WINDOWPOSCHANGING) \ - { \ - SetMsgHandled(TRUE); \ - func((LPWINDOWPOS)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnWindowPosChanged(LPWINDOWPOS lpWndPos) -#define MSG_WM_WINDOWPOSCHANGED(func) \ - if (uMsg == WM_WINDOWPOSCHANGED) \ - { \ - SetMsgHandled(TRUE); \ - func((LPWINDOWPOS)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnExitMenuLoop(BOOL fIsTrackPopupMenu) -#define MSG_WM_EXITMENULOOP(func) \ - if (uMsg == WM_EXITMENULOOP) \ - { \ - SetMsgHandled(TRUE); \ - func((BOOL)wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnEnterMenuLoop(BOOL fIsTrackPopupMenu) -#define MSG_WM_ENTERMENULOOP(func) \ - if (uMsg == WM_ENTERMENULOOP) \ - { \ - SetMsgHandled(TRUE); \ - func((BOOL)wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnStyleChanged(int nStyleType, LPSTYLESTRUCT lpStyleStruct) -#define MSG_WM_STYLECHANGED(func) \ - if (uMsg == WM_STYLECHANGED) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, (LPSTYLESTRUCT)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnStyleChanging(int nStyleType, LPSTYLESTRUCT lpStyleStruct) -#define MSG_WM_STYLECHANGING(func) \ - if (uMsg == WM_STYLECHANGING) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, (LPSTYLESTRUCT)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnSizing(UINT fwSide, LPRECT pRect) -#define MSG_WM_SIZING(func) \ - if (uMsg == WM_SIZING) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, (LPRECT)lParam); \ - lResult = TRUE; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnMoving(UINT fwSide, LPRECT pRect) -#define MSG_WM_MOVING(func) \ - if (uMsg == WM_MOVING) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, (LPRECT)lParam); \ - lResult = TRUE; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnCaptureChanged(CWindow wnd) -#define MSG_WM_CAPTURECHANGED(func) \ - if (uMsg == WM_CAPTURECHANGED) \ - { \ - SetMsgHandled(TRUE); \ - func((HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// BOOL OnDeviceChange(UINT nEventType, DWORD dwData) -#define MSG_WM_DEVICECHANGE(func) \ - if (uMsg == WM_DEVICECHANGE) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((UINT)wParam, (DWORD)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnCommand(UINT uNotifyCode, int nID, CWindow wndCtl) -#define MSG_WM_COMMAND(func) \ - if (uMsg == WM_COMMAND) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnDisplayChange(UINT uBitsPerPixel, CSize sizeScreen) -#define MSG_WM_DISPLAYCHANGE(func) \ - if (uMsg == WM_DISPLAYCHANGE) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, _WTYPES_NS::CSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnEnterSizeMove() -#define MSG_WM_ENTERSIZEMOVE(func) \ - if (uMsg == WM_ENTERSIZEMOVE) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnExitSizeMove() -#define MSG_WM_EXITSIZEMOVE(func) \ - if (uMsg == WM_EXITSIZEMOVE) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// HFONT OnGetFont() -#define MSG_WM_GETFONT(func) \ - if (uMsg == WM_GETFONT) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func(); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnGetHotKey() -#define MSG_WM_GETHOTKEY(func) \ - if (uMsg == WM_GETHOTKEY) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func(); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// HICON OnGetIcon() -#define MSG_WM_GETICON(func) \ - if (uMsg == WM_GETICON) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((UINT)wParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// int OnGetText(int cchTextMax, LPTSTR lpszText) -#define MSG_WM_GETTEXT(func) \ - if (uMsg == WM_GETTEXT) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((int)wParam, (LPTSTR)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// int OnGetTextLength() -#define MSG_WM_GETTEXTLENGTH(func) \ - if (uMsg == WM_GETTEXTLENGTH) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func(); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnHelp(LPHELPINFO lpHelpInfo) -#define MSG_WM_HELP(func) \ - if (uMsg == WM_HELP) \ - { \ - SetMsgHandled(TRUE); \ - func((LPHELPINFO)lParam); \ - lResult = TRUE; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnHotKey(int nHotKeyID, UINT uModifiers, UINT uVirtKey) -#define MSG_WM_HOTKEY(func) \ - if (uMsg == WM_HOTKEY) \ - { \ - SetMsgHandled(TRUE); \ - func((int)wParam, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnInputLangChange(DWORD dwCharSet, HKL hKbdLayout) -#define MSG_WM_INPUTLANGCHANGE(func) \ - if (uMsg == WM_INPUTLANGCHANGE) \ - { \ - SetMsgHandled(TRUE); \ - func((DWORD)wParam, (HKL)lParam); \ - lResult = TRUE; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnInputLangChangeRequest(BOOL bSysCharSet, HKL hKbdLayout) -#define MSG_WM_INPUTLANGCHANGEREQUEST(func) \ - if (uMsg == WM_INPUTLANGCHANGEREQUEST) \ - { \ - SetMsgHandled(TRUE); \ - func((BOOL)wParam, (HKL)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnNextDlgCtl(BOOL bHandle, WPARAM wCtlFocus) -#define MSG_WM_NEXTDLGCTL(func) \ - if (uMsg == WM_NEXTDLGCTL) \ - { \ - SetMsgHandled(TRUE); \ - func((BOOL)LOWORD(lParam), wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnNextMenu(int nVirtKey, LPMDINEXTMENU lpMdiNextMenu) -#define MSG_WM_NEXTMENU(func) \ - if (uMsg == WM_NEXTMENU) \ - { \ - SetMsgHandled(TRUE); \ - func((int)wParam, (LPMDINEXTMENU)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// int OnNotifyFormat(CWindow wndFrom, int nCommand) -#define MSG_WM_NOTIFYFORMAT(func) \ - if (uMsg == WM_NOTIFYFORMAT) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HWND)wParam, (int)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// BOOL OnPowerBroadcast(DWORD dwPowerEvent, DWORD dwData) -#define MSG_WM_POWERBROADCAST(func) \ - if (uMsg == WM_POWERBROADCAST) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((DWORD)wParam, (DWORD)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnPrint(CDCHandle dc, UINT uFlags) -#define MSG_WM_PRINT(func) \ - if (uMsg == WM_PRINT) \ - { \ - SetMsgHandled(TRUE); \ - func((HDC)wParam, (UINT)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnPrintClient(CDCHandle dc, UINT uFlags) -#define MSG_WM_PRINTCLIENT(func) \ - if (uMsg == WM_PRINTCLIENT) \ - { \ - SetMsgHandled(TRUE); \ - func((HDC)wParam, (UINT)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnRasDialEvent(RASCONNSTATE rasconnstate, DWORD dwError) -#define MSG_WM_RASDIALEVENT(func) \ - if (uMsg == WM_RASDIALEVENT) \ - { \ - SetMsgHandled(TRUE); \ - func((RASCONNSTATE)wParam, (DWORD)lParam); \ - lResult = TRUE; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnSetFont(CFontHandle font, BOOL bRedraw) -#define MSG_WM_SETFONT(func) \ - if (uMsg == WM_SETFONT) \ - { \ - SetMsgHandled(TRUE); \ - func((HFONT)wParam, (BOOL)LOWORD(lParam)); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// int OnSetHotKey(int nVirtKey, UINT uFlags) -#define MSG_WM_SETHOTKEY(func) \ - if (uMsg == WM_SETHOTKEY) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((int)LOBYTE(LOWORD(wParam)), (UINT)HIBYTE(LOWORD(wParam))); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// HICON OnSetIcon(UINT uType, HICON hIcon) -#define MSG_WM_SETICON(func) \ - if (uMsg == WM_SETICON) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((UINT)wParam, (HICON)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnSetRedraw(BOOL bRedraw) -#define MSG_WM_SETREDRAW(func) \ - if (uMsg == WM_SETREDRAW) \ - { \ - SetMsgHandled(TRUE); \ - func((BOOL)wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// int OnSetText(LPCTSTR lpstrText) -#define MSG_WM_SETTEXT(func) \ - if (uMsg == WM_SETTEXT) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((LPCTSTR)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnUserChanged() -#define MSG_WM_USERCHANGED(func) \ - if (uMsg == WM_USERCHANGED) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -/////////////////////////////////////////////////////////////////////////////// -// New NT4 & NT5 messages - -#if(_WIN32_WINNT >= 0x0400) - -// void OnMouseHover(WPARAM wParam, CPoint ptPos) -#define MSG_WM_MOUSEHOVER(func) \ - if (uMsg == WM_MOUSEHOVER) \ - { \ - SetMsgHandled(TRUE); \ - func(wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnMouseLeave() -#define MSG_WM_MOUSELEAVE(func) \ - if (uMsg == WM_MOUSELEAVE) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -#endif /* _WIN32_WINNT >= 0x0400 */ - -#if(WINVER >= 0x0500) - -// void OnMenuRButtonUp(WPARAM wParam, CMenuHandle menu) -#define MSG_WM_MENURBUTTONUP(func) \ - if (uMsg == WM_MENURBUTTONUP) \ - { \ - SetMsgHandled(TRUE); \ - func(wParam, (HMENU)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnMenuDrag(WPARAM wParam, CMenuHandle menu) -#define MSG_WM_MENUDRAG(func) \ - if (uMsg == WM_MENUDRAG) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func(wParam, (HMENU)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnMenuGetObject(PMENUGETOBJECTINFO info) -#define MSG_WM_MENUGETOBJECT(func) \ - if (uMsg == WM_MENUGETOBJECT) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func((PMENUGETOBJECTINFO)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnUnInitMenuPopup(UINT nID, CMenuHandle menu) -#define MSG_WM_UNINITMENUPOPUP(func) \ - if (uMsg == WM_UNINITMENUPOPUP) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)HIWORD(lParam), (HMENU)wParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnMenuCommand(WPARAM nIndex, CMenuHandle menu) -#define MSG_WM_MENUCOMMAND(func) \ - if (uMsg == WM_MENUCOMMAND) \ - { \ - SetMsgHandled(TRUE); \ - func(wParam, (HMENU)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -#endif /* WINVER >= 0x0500 */ - -#if(_WIN32_WINNT >= 0x0500) - -// BOOL OnAppCommand(CWindow wndFocus, short cmd, WORD uDevice, int dwKeys) -#define MSG_WM_APPCOMMAND(func) \ - if (uMsg == WM_APPCOMMAND) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HWND)wParam, GET_APPCOMMAND_LPARAM(lParam), GET_DEVICE_LPARAM(lParam), GET_KEYSTATE_LPARAM(lParam)); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnNCXButtonDown(int fwButton, short nHittest, CPoint ptPos) -#define MSG_WM_NCXBUTTONDOWN(func) \ - if (uMsg == WM_NCXBUTTONDOWN) \ - { \ - SetMsgHandled(TRUE); \ - func(GET_XBUTTON_WPARAM(wParam), GET_NCHITTEST_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnNCXButtonUp(int fwButton, short nHittest, CPoint ptPos) -#define MSG_WM_NCXBUTTONUP(func) \ - if (uMsg == WM_NCXBUTTONUP) \ - { \ - SetMsgHandled(TRUE); \ - func(GET_XBUTTON_WPARAM(wParam), GET_NCHITTEST_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnNCXButtonDblClk(int fwButton, short nHittest, CPoint ptPos) -#define MSG_WM_NCXBUTTONDBLCLK(func) \ - if (uMsg == WM_NCXBUTTONDBLCLK) \ - { \ - SetMsgHandled(TRUE); \ - func(GET_XBUTTON_WPARAM(wParam), GET_NCHITTEST_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnXButtonDown(int fwButton, int dwKeys, CPoint ptPos) -#define MSG_WM_XBUTTONDOWN(func) \ - if (uMsg == WM_XBUTTONDOWN) \ - { \ - SetMsgHandled(TRUE); \ - func(GET_XBUTTON_WPARAM(wParam), GET_KEYSTATE_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnXButtonUp(int fwButton, int dwKeys, CPoint ptPos) -#define MSG_WM_XBUTTONUP(func) \ - if (uMsg == WM_XBUTTONUP) \ - { \ - SetMsgHandled(TRUE); \ - func(GET_XBUTTON_WPARAM(wParam), GET_KEYSTATE_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnXButtonDblClk(int fwButton, int dwKeys, CPoint ptPos) -#define MSG_WM_XBUTTONDBLCLK(func) \ - if (uMsg == WM_XBUTTONDBLCLK) \ - { \ - SetMsgHandled(TRUE); \ - func(GET_XBUTTON_WPARAM(wParam), GET_KEYSTATE_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnChangeUIState(WORD nAction, WORD nState) -#define MSG_WM_CHANGEUISTATE(func) \ - if (uMsg == WM_CHANGEUISTATE) \ - { \ - SetMsgHandled(TRUE); \ - func(LOWORD(wParam), HIWORD(wParam)); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnUpdateUIState(WORD nAction, WORD nState) -#define MSG_WM_UPDATEUISTATE(func) \ - if (uMsg == WM_UPDATEUISTATE) \ - { \ - SetMsgHandled(TRUE); \ - func(LOWORD(wParam), HIWORD(wParam)); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnQueryUIState() -#define MSG_WM_QUERYUISTATE(func) \ - if (uMsg == WM_QUERYUISTATE) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func(); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -#endif // (_WIN32_WINNT >= 0x0500) - -#if(_WIN32_WINNT >= 0x0501) - -// void OnInput(WPARAM RawInputCode, HRAWINPUT hRawInput) -#define MSG_WM_INPUT(func) \ - if (uMsg == WM_INPUT) \ - { \ - SetMsgHandled(TRUE); \ - func(GET_RAWINPUT_CODE_WPARAM(wParam), (HRAWINPUT)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnUniChar(TCHAR nChar, UINT nRepCnt, UINT nFlags) -#define MSG_WM_UNICHAR(func) \ - if (uMsg == WM_UNICHAR) \ - { \ - SetMsgHandled(TRUE); \ - func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ - if(IsMsgHandled()) \ - { \ - lResult = (wParam == UNICODE_NOCHAR) ? TRUE : FALSE; \ - return TRUE; \ - } \ - } - -// void OnWTSSessionChange(WPARAM nStatusCode, PWTSSESSION_NOTIFICATION nSessionID) -#define MSG_WM_WTSSESSION_CHANGE(func) \ - if (uMsg == WM_WTSSESSION_CHANGE) \ - { \ - SetMsgHandled(TRUE); \ - func(wParam, (PWTSSESSION_NOTIFICATION)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// OnThemeChanged() -#define MSG_WM_THEMECHANGED(func) \ - if (uMsg == WM_THEMECHANGED) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -#endif /* _WIN32_WINNT >= 0x0501 */ - -/////////////////////////////////////////////////////////////////////////////// -// ATL defined messages - -// BOOL OnForwardMsg(LPMSG Msg, DWORD nUserData) -#define MSG_WM_FORWARDMSG(func) \ - if (uMsg == WM_FORWARDMSG) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((LPMSG)lParam, (DWORD)wParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -/////////////////////////////////////////////////////////////////////////////// -// Dialog specific messages - -// LRESULT OnDMGetDefID() -#define MSG_DM_GETDEFID(func) \ - if (uMsg == DM_GETDEFID) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func(); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnDMSetDefID(UINT DefID) -#define MSG_DM_SETDEFID(func) \ - if (uMsg == DM_SETDEFID) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam); \ - lResult = TRUE; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnDMReposition() -#define MSG_DM_REPOSITION(func) \ - if (uMsg == DM_REPOSITION) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -/////////////////////////////////////////////////////////////////////////////// -// Reflected messages - -// void OnReflectedCommand(UINT uNotifyCode, int nID, CWindow wndCtl) -#define MSG_OCM_COMMAND(func) \ - if (uMsg == OCM_COMMAND) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnReflectedNotify(int idCtrl, LPNMHDR pnmh) -#define MSG_OCM_NOTIFY(func) \ - if (uMsg == OCM_NOTIFY) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func((int)wParam, (LPNMHDR)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnReflectedParentNotify(UINT message, UINT nChildID, LPARAM lParam) -#define MSG_OCM_PARENTNOTIFY(func) \ - if (uMsg == OCM_PARENTNOTIFY) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnReflectedDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) -#define MSG_OCM_DRAWITEM(func) \ - if (uMsg == OCM_DRAWITEM) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, (LPDRAWITEMSTRUCT)lParam); \ - lResult = TRUE; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnReflectedMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct) -#define MSG_OCM_MEASUREITEM(func) \ - if (uMsg == OCM_MEASUREITEM) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, (LPMEASUREITEMSTRUCT)lParam); \ - lResult = TRUE; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// int OnReflectedCompareItem(int nIDCtl, LPCOMPAREITEMSTRUCT lpCompareItemStruct) -#define MSG_OCM_COMPAREITEM(func) \ - if (uMsg == OCM_COMPAREITEM) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((UINT)wParam, (LPCOMPAREITEMSTRUCT)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnReflectedDeleteItem(int nIDCtl, LPDELETEITEMSTRUCT lpDeleteItemStruct) -#define MSG_OCM_DELETEITEM(func) \ - if (uMsg == OCM_DELETEITEM) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)wParam, (LPDELETEITEMSTRUCT)lParam); \ - lResult = TRUE; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// int OnReflectedVKeyToItem(UINT nKey, UINT nIndex, CListBox listBox) -#define MSG_OCM_VKEYTOITEM(func) \ - if (uMsg == OCM_VKEYTOITEM) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), (HWND)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -//int OnReflectedCharToItem(UINT nChar, UINT nIndex, CListBox listBox) -#define MSG_OCM_CHARTOITEM(func) \ - if (uMsg == OCM_CHARTOITEM) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), (HWND)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnReflectedHScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar) -#define MSG_OCM_HSCROLL(func) \ - if (uMsg == OCM_HSCROLL) \ - { \ - SetMsgHandled(TRUE); \ - func((int)LOWORD(wParam), (short)HIWORD(wParam), (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnReflectedVScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar) -#define MSG_OCM_VSCROLL(func) \ - if (uMsg == OCM_VSCROLL) \ - { \ - SetMsgHandled(TRUE); \ - func((int)LOWORD(wParam), (short)HIWORD(wParam), (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// HBRUSH OnReflectedCtlColorEdit(CDCHandle dc, CEdit edit) -#define MSG_OCM_CTLCOLOREDIT(func) \ - if (uMsg == OCM_CTLCOLOREDIT) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// HBRUSH OnReflectedCtlColorListBox(CDCHandle dc, CListBox listBox) -#define MSG_OCM_CTLCOLORLISTBOX(func) \ - if (uMsg == OCM_CTLCOLORLISTBOX) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// HBRUSH OnReflectedCtlColorBtn(CDCHandle dc, CButton button) -#define MSG_OCM_CTLCOLORBTN(func) \ - if (uMsg == OCM_CTLCOLORBTN) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// HBRUSH OnReflectedCtlColorDlg(CDCHandle dc, CWindow wnd) -#define MSG_OCM_CTLCOLORDLG(func) \ - if (uMsg == OCM_CTLCOLORDLG) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// HBRUSH OnReflectedCtlColorScrollBar(CDCHandle dc, CScrollBar scrollBar) -#define MSG_OCM_CTLCOLORSCROLLBAR(func) \ - if (uMsg == OCM_CTLCOLORSCROLLBAR) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// HBRUSH OnReflectedCtlColorStatic(CDCHandle dc, CStatic wndStatic) -#define MSG_OCM_CTLCOLORSTATIC(func) \ - if (uMsg == OCM_CTLCOLORSTATIC) \ - { \ - SetMsgHandled(TRUE); \ - lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -/////////////////////////////////////////////////////////////////////////////// -// Edit specific messages - -// void OnClear() -#define MSG_WM_CLEAR(func) \ - if (uMsg == WM_CLEAR) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnCopy() -#define MSG_WM_COPY(func) \ - if (uMsg == WM_COPY) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnCut() -#define MSG_WM_CUT(func) \ - if (uMsg == WM_CUT) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnPaste() -#define MSG_WM_PASTE(func) \ - if (uMsg == WM_PASTE) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnUndo() -#define MSG_WM_UNDO(func) \ - if (uMsg == WM_UNDO) \ - { \ - SetMsgHandled(TRUE); \ - func(); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -/////////////////////////////////////////////////////////////////////////////// -// Generic message handlers - -// LRESULT OnMessageHandlerEX(UINT uMsg, WPARAM wParam, LPARAM lParam) -#define MESSAGE_HANDLER_EX(msg, func) \ - if(uMsg == msg) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func(uMsg, wParam, lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnMessageRangeHandlerEX(UINT uMsg, WPARAM wParam, LPARAM lParam) -#define MESSAGE_RANGE_HANDLER_EX(msgFirst, msgLast, func) \ - if(uMsg >= msgFirst && uMsg <= msgLast) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func(uMsg, wParam, lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -/////////////////////////////////////////////////////////////////////////////// -// Commands and notifications - -// void OnCommandHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) -#define COMMAND_HANDLER_EX(id, code, func) \ - if (uMsg == WM_COMMAND && code == HIWORD(wParam) && id == LOWORD(wParam)) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnCommandIDHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) -#define COMMAND_ID_HANDLER_EX(id, func) \ - if (uMsg == WM_COMMAND && id == LOWORD(wParam)) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnCommandCodeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) -#define COMMAND_CODE_HANDLER_EX(code, func) \ - if (uMsg == WM_COMMAND && code == HIWORD(wParam)) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnNotifyHandlerEX(LPNMHDR pnmh) -#define NOTIFY_HANDLER_EX(id, cd, func) \ - if (uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code && id == ((LPNMHDR)lParam)->idFrom) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func((LPNMHDR)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnNotifyIDHandlerEX(LPNMHDR pnmh) -#define NOTIFY_ID_HANDLER_EX(id, func) \ - if (uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func((LPNMHDR)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnNotifyCodeHandlerEX(LPNMHDR pnmh) -#define NOTIFY_CODE_HANDLER_EX(cd, func) \ - if (uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func((LPNMHDR)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnCommandRangeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) -#define COMMAND_RANGE_HANDLER_EX(idFirst, idLast, func) \ - if(uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnCommandRangeCodeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) -#define COMMAND_RANGE_CODE_HANDLER_EX(idFirst, idLast, code, func) \ - if(uMsg == WM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnNotifyRangeHandlerEX(LPNMHDR pnmh) -#define NOTIFY_RANGE_HANDLER_EX(idFirst, idLast, func) \ - if(uMsg == WM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func((LPNMHDR)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnNotifyRangeCodeHandlerEX(LPNMHDR pnmh) -#define NOTIFY_RANGE_CODE_HANDLER_EX(idFirst, idLast, cd, func) \ - if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func((LPNMHDR)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnReflectedCommandHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) -#define REFLECTED_COMMAND_HANDLER_EX(id, code, func) \ - if (uMsg == OCM_COMMAND && code == HIWORD(wParam) && id == LOWORD(wParam)) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnReflectedCommandIDHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) -#define REFLECTED_COMMAND_ID_HANDLER_EX(id, func) \ - if (uMsg == OCM_COMMAND && id == LOWORD(wParam)) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnReflectedCommandCodeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) -#define REFLECTED_COMMAND_CODE_HANDLER_EX(code, func) \ - if (uMsg == OCM_COMMAND && code == HIWORD(wParam)) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnReflectedNotifyHandlerEX(LPNMHDR pnmh) -#define REFLECTED_NOTIFY_HANDLER_EX(id, cd, func) \ - if (uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code && id == ((LPNMHDR)lParam)->idFrom) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func((LPNMHDR)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnReflectedNotifyIDHandlerEX(LPNMHDR pnmh) -#define REFLECTED_NOTIFY_ID_HANDLER_EX(id, func) \ - if (uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func((LPNMHDR)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnReflectedNotifyCodeHandlerEX(LPNMHDR pnmh) -#define REFLECTED_NOTIFY_CODE_HANDLER_EX(cd, func) \ - if (uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func((LPNMHDR)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnReflectedCommandRangeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) -#define REFLECTED_COMMAND_RANGE_HANDLER_EX(idFirst, idLast, func) \ - if(uMsg == OCM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// void OnReflectedCommandRangeCodeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) -#define REFLECTED_COMMAND_RANGE_CODE_HANDLER_EX(idFirst, idLast, code, func) \ - if(uMsg == OCM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ - { \ - SetMsgHandled(TRUE); \ - func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ - lResult = 0; \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnReflectedNotifyRangeHandlerEX(LPNMHDR pnmh) -#define REFLECTED_NOTIFY_RANGE_HANDLER_EX(idFirst, idLast, func) \ - if(uMsg == OCM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func((LPNMHDR)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -// LRESULT OnReflectedNotifyRangeCodeHandlerEX(LPNMHDR pnmh) -#define REFLECTED_NOTIFY_RANGE_CODE_HANDLER_EX(idFirst, idLast, cd, func) \ - if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ - { \ - SetMsgHandled(TRUE); \ - lResult = func((LPNMHDR)lParam); \ - if(IsMsgHandled()) \ - return TRUE; \ - } - -#endif // __ATLCRACK_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlctrls.h b/!NotAdopted/SmartAutoReplier/wtl/atlctrls.h deleted file mode 100644 index 00df403181..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlctrls.h +++ /dev/null @@ -1,10041 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLCTRLS_H__ -#define __ATLCTRLS_H__ - -#pragma once - -#include - -#ifndef __ATLAPP_H__ - #error atlctrls.h requires atlapp.h to be included first -#endif - -#ifndef __ATLWIN_H__ - #error atlctrls.h requires atlwin.h to be included first -#endif - -#ifndef _WIN32_WCE - #include - #include -#elif defined(WIN32_PLATFORM_WFSP) && !defined(_WINUSERM_H_) - #include -#endif // !_WIN32_WCE - -// protect template members from windowsx.h macros -#ifdef _INC_WINDOWSX - #undef GetNextSibling - #undef GetPrevSibling -#endif // _INC_WINDOWSX - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CStaticT - CStatic -// CButtonT - CButton -// CListBoxT - CListBox -// CComboBoxT - CComboBox -// CEditT - CEdit -// CEditCommands -// CScrollBarT - CScrollBar -// -// CImageList -// CListViewCtrlT - CListViewCtrl -// CTreeViewCtrlT - CTreeViewCtrl -// CTreeItemT - CTreeItem -// CTreeViewCtrlExT - CTreeViewCtrlEx -// CHeaderCtrlT - CHeaderCtrl -// CToolBarCtrlT - CToolBarCtrl -// CStatusBarCtrlT - CStatusBarCtrl -// CTabCtrlT - CTabCtrl -// CToolInfo -// CToolTipCtrlT - CToolTipCtrl -// CTrackBarCtrlT - CTrackBarCtrl -// CUpDownCtrlT - CUpDownCtrl -// CProgressBarCtrlT - CProgressBarCtrl -// CHotKeyCtrlT - CHotKeyCtrl -// CAnimateCtrlT - CAnimateCtrl -// CRichEditCtrlT - CRichEditCtrl -// CRichEditCommands -// CDragListBoxT - CDragListBox -// CDragListNotifyImpl -// CReBarCtrlT - CReBarCtrl -// CComboBoxExT - CComboBoxEx -// CDateTimePickerCtrlT - CDateTimePickerCtrl -// CMonthCalendarCtrlT - CMonthCalendarCtrl -// CFlatScrollBarImpl -// CFlatScrollBarT - CFlatScrollBar -// CIPAddressCtrlT - CIPAddressCtrl -// CPagerCtrlT - CPagerCtrl -// CLinkCtrlT - CLinkCtrl -// -// CCustomDraw -// -// CCECommandBarCtrlT - CCECommandBarCtrl -// CCECommandBandsCtrlT - CCECommandBandsCtrl - - -namespace WTL -{ - -// These are wrapper classes for Windows standard and common controls. -// To implement a window based on a control, use following: -// Example: Implementing a window based on a list box -// -// class CMyListBox : CWindowImpl -// { -// public: -// BEGIN_MSG_MAP(CMyListBox) -// // put your message handler entries here -// END_MSG_MAP() -// }; - - - -// --- Standard Windows controls --- - -/////////////////////////////////////////////////////////////////////////////// -// CStatic - client side for a Windows STATIC control - -template -class CStaticT : public TBase -{ -public: -// Constructors - CStaticT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CStaticT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return _T("STATIC"); - } - -#ifndef _WIN32_WCE - HICON GetIcon() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HICON)::SendMessage(m_hWnd, STM_GETICON, 0, 0L); - } - - HICON SetIcon(HICON hIcon) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HICON)::SendMessage(m_hWnd, STM_SETICON, (WPARAM)hIcon, 0L); - } - - HENHMETAFILE GetEnhMetaFile() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HENHMETAFILE)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_ENHMETAFILE, 0L); - } - - HENHMETAFILE SetEnhMetaFile(HENHMETAFILE hMetaFile) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HENHMETAFILE)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_ENHMETAFILE, (LPARAM)hMetaFile); - } -#else // CE specific - HICON GetIcon() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HICON)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_ICON, 0L); - } - - HICON SetIcon(HICON hIcon) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HICON)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); - } -#endif // _WIN32_WCE - - CBitmapHandle GetBitmap() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_BITMAP, 0L)); - } - - CBitmapHandle SetBitmap(HBITMAP hBitmap) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap)); - } - - HCURSOR GetCursor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HCURSOR)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_CURSOR, 0L); - } - - HCURSOR SetCursor(HCURSOR hCursor) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HCURSOR)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_CURSOR, (LPARAM)hCursor); - } -}; - -typedef CStaticT CStatic; - - -/////////////////////////////////////////////////////////////////////////////// -// CButton - client side for a Windows BUTTON control - -template -class CButtonT : public TBase -{ -public: -// Constructors - CButtonT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CButtonT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return _T("BUTTON"); - } - - UINT GetState() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, BM_GETSTATE, 0, 0L); - } - - void SetState(BOOL bHighlight) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, BM_SETSTATE, bHighlight, 0L); - } - - int GetCheck() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, BM_GETCHECK, 0, 0L); - } - - void SetCheck(int nCheck) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, BM_SETCHECK, nCheck, 0L); - } - - UINT GetButtonStyle() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::GetWindowLong(m_hWnd, GWL_STYLE) & 0xFFFF; - } - - void SetButtonStyle(UINT nStyle, BOOL bRedraw = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, BM_SETSTYLE, nStyle, (LPARAM)bRedraw); - } - -#ifndef _WIN32_WCE - HICON GetIcon() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HICON)::SendMessage(m_hWnd, BM_GETIMAGE, IMAGE_ICON, 0L); - } - - HICON SetIcon(HICON hIcon) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HICON)::SendMessage(m_hWnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); - } - - CBitmapHandle GetBitmap() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, BM_GETIMAGE, IMAGE_BITMAP, 0L)); - } - - CBitmapHandle SetBitmap(HBITMAP hBitmap) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap)); - } -#endif // !_WIN32_WCE - -#if (_WIN32_WINNT >= 0x0501) - BOOL GetIdealSize(LPSIZE lpSize) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, BCM_GETIDEALSIZE, 0, (LPARAM)lpSize); - } - - BOOL GetImageList(PBUTTON_IMAGELIST pButtonImagelist) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, BCM_GETIMAGELIST, 0, (LPARAM)pButtonImagelist); - } - - BOOL SetImageList(PBUTTON_IMAGELIST pButtonImagelist) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, BCM_SETIMAGELIST, 0, (LPARAM)pButtonImagelist); - } - - BOOL GetTextMargin(LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, BCM_GETTEXTMARGIN, 0, (LPARAM)lpRect); - } - - BOOL SetTextMargin(LPRECT lpRect) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, BCM_SETTEXTMARGIN, 0, (LPARAM)lpRect); - } -#endif // (_WIN32_WINNT >= 0x0501) - -#if (WINVER >= 0x0600) - void SetDontClick(BOOL bDontClick) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, BM_SETDONTCLICK, (WPARAM)bDontClick, 0L); - } -#endif // (WINVER >= 0x0600) - -#if (_WIN32_WINNT >= 0x0600) - BOOL SetDropDownState(BOOL bDropDown) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & (BS_SPLITBUTTON | BS_DEFSPLITBUTTON)) != 0); - return (BOOL)::SendMessage(m_hWnd, BCM_SETDROPDOWNSTATE, (WPARAM)bDropDown, 0L); - } - - BOOL GetSplitInfo(PBUTTON_SPLITINFO pSplitInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & (BS_SPLITBUTTON | BS_DEFSPLITBUTTON)) != 0); - return (BOOL)::SendMessage(m_hWnd, BCM_GETSPLITINFO, 0, (LPARAM)pSplitInfo); - } - - BOOL SetSplitInfo(PBUTTON_SPLITINFO pSplitInfo) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & (BS_SPLITBUTTON | BS_DEFSPLITBUTTON)) != 0); - return (BOOL)::SendMessage(m_hWnd, BCM_SETSPLITINFO, 0, (LPARAM)pSplitInfo); - } - - int GetNoteLength() const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & (BS_COMMANDLINK | BS_DEFCOMMANDLINK)) != 0); - return (int)::SendMessage(m_hWnd, BCM_GETNOTELENGTH, 0, 0L); - } - - BOOL GetNote(LPWSTR lpstrNoteText, int cchNoteText) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & (BS_COMMANDLINK | BS_DEFCOMMANDLINK)) != 0); - return (BOOL)::SendMessage(m_hWnd, BCM_GETNOTE, cchNoteText, (LPARAM)lpstrNoteText); - } - - BOOL SetNote(LPCWSTR lpstrNoteText) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & (BS_COMMANDLINK | BS_DEFCOMMANDLINK)) != 0); - return (BOOL)::SendMessage(m_hWnd, BCM_SETNOTE, 0, (LPARAM)lpstrNoteText); - } - - LRESULT SetElevationRequiredState(BOOL bSet) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::SendMessage(m_hWnd, BCM_SETSHIELD, 0, (LPARAM)bSet); - } -#endif // (_WIN32_WINNT >= 0x0600) - -// Operations - void Click() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, BM_CLICK, 0, 0L); - } -}; - -typedef CButtonT CButton; - - -/////////////////////////////////////////////////////////////////////////////// -// CListBox - client side for a Windows LISTBOX control - -template -class CListBoxT : public TBase -{ -public: -// Constructors - CListBoxT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CListBoxT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return _T("LISTBOX"); - } - - // for entire listbox - int GetCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_GETCOUNT, 0, 0L); - } - -#ifndef _WIN32_WCE - int SetCount(int cItems) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(((GetStyle() & LBS_NODATA) != 0) && ((GetStyle() & LBS_HASSTRINGS) == 0)); - return (int)::SendMessage(m_hWnd, LB_SETCOUNT, cItems, 0L); - } -#endif // !_WIN32_WCE - - int GetHorizontalExtent() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_GETHORIZONTALEXTENT, 0, 0L); - } - - void SetHorizontalExtent(int cxExtent) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, LB_SETHORIZONTALEXTENT, cxExtent, 0L); - } - - int GetTopIndex() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_GETTOPINDEX, 0, 0L); - } - - int SetTopIndex(int nIndex) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_SETTOPINDEX, nIndex, 0L); - } - - LCID GetLocale() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (LCID)::SendMessage(m_hWnd, LB_GETLOCALE, 0, 0L); - } - - LCID SetLocale(LCID nNewLocale) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (LCID)::SendMessage(m_hWnd, LB_SETLOCALE, (WPARAM)nNewLocale, 0L); - } - -#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) - DWORD GetListBoxInfo() const - { - ATLASSERT(::IsWindow(m_hWnd)); -#if (_WIN32_WINNT >= 0x0501) - return (DWORD)::SendMessage(m_hWnd, LB_GETLISTBOXINFO, 0, 0L); -#else // !(_WIN32_WINNT >= 0x0501) - return ::GetListBoxInfo(m_hWnd); -#endif // !(_WIN32_WINNT >= 0x0501) - } -#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) - - // for single-selection listboxes - int GetCurSel() const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) == 0); - return (int)::SendMessage(m_hWnd, LB_GETCURSEL, 0, 0L); - } - - int SetCurSel(int nSelect) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) == 0); - return (int)::SendMessage(m_hWnd, LB_SETCURSEL, nSelect, 0L); - } - - // for multiple-selection listboxes - int GetSel(int nIndex) const // also works for single-selection - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_GETSEL, nIndex, 0L); - } - - int SetSel(int nIndex, BOOL bSelect = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); - return (int)::SendMessage(m_hWnd, LB_SETSEL, bSelect, nIndex); - } - - int GetSelCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); - return (int)::SendMessage(m_hWnd, LB_GETSELCOUNT, 0, 0L); - } - - int GetSelItems(int nMaxItems, LPINT rgIndex) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); - return (int)::SendMessage(m_hWnd, LB_GETSELITEMS, nMaxItems, (LPARAM)rgIndex); - } - - int GetAnchorIndex() const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); - return (int)::SendMessage(m_hWnd, LB_GETANCHORINDEX, 0, 0L); - } - - void SetAnchorIndex(int nIndex) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); - ::SendMessage(m_hWnd, LB_SETANCHORINDEX, nIndex, 0L); - } - - int GetCaretIndex() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_GETCARETINDEX, 0, 0); - } - - int SetCaretIndex(int nIndex, BOOL bScroll = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_SETCARETINDEX, nIndex, MAKELONG(bScroll, 0)); - } - - // for listbox items - DWORD_PTR GetItemData(int nIndex) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD_PTR)::SendMessage(m_hWnd, LB_GETITEMDATA, nIndex, 0L); - } - - int SetItemData(int nIndex, DWORD_PTR dwItemData) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_SETITEMDATA, nIndex, (LPARAM)dwItemData); - } - - void* GetItemDataPtr(int nIndex) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (void*)::SendMessage(m_hWnd, LB_GETITEMDATA, nIndex, 0L); - } - - int SetItemDataPtr(int nIndex, void* pData) - { - ATLASSERT(::IsWindow(m_hWnd)); - return SetItemData(nIndex, (DWORD_PTR)pData); - } - - int GetItemRect(int nIndex, LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_GETITEMRECT, nIndex, (LPARAM)lpRect); - } - - int GetText(int nIndex, LPTSTR lpszBuffer) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_GETTEXT, nIndex, (LPARAM)lpszBuffer); - } - -#ifndef _ATL_NO_COM -#ifdef _OLEAUTO_H_ - BOOL GetTextBSTR(int nIndex, BSTR& bstrText) const - { - USES_CONVERSION; - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(bstrText == NULL); - - int nLen = GetTextLen(nIndex); - if(nLen == LB_ERR) - return FALSE; - - CTempBuffer buff; - LPTSTR lpstrText = buff.Allocate(nLen + 1); - if(lpstrText == NULL) - return FALSE; - - if(GetText(nIndex, lpstrText) == LB_ERR) - return FALSE; - - bstrText = ::SysAllocString(T2OLE(lpstrText)); - return (bstrText != NULL) ? TRUE : FALSE; - } -#endif // _OLEAUTO_H_ -#endif // !_ATL_NO_COM - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - int GetText(int nIndex, _CSTRING_NS::CString& strText) const - { - ATLASSERT(::IsWindow(m_hWnd)); - int cchLen = GetTextLen(nIndex); - if(cchLen == LB_ERR) - return LB_ERR; - int nRet = LB_ERR; - LPTSTR lpstr = strText.GetBufferSetLength(cchLen); - if(lpstr != NULL) - { - nRet = GetText(nIndex, lpstr); - strText.ReleaseBuffer(); - } - return nRet; - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - - int GetTextLen(int nIndex) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_GETTEXTLEN, nIndex, 0L); - } - - int GetItemHeight(int nIndex) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_GETITEMHEIGHT, nIndex, 0L); - } - - int SetItemHeight(int nIndex, UINT cyItemHeight) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_SETITEMHEIGHT, nIndex, MAKELONG(cyItemHeight, 0)); - } - - // Settable only attributes - void SetColumnWidth(int cxWidth) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, LB_SETCOLUMNWIDTH, cxWidth, 0L); - } - - BOOL SetTabStops(int nTabStops, LPINT rgTabStops) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & LBS_USETABSTOPS) != 0); - return (BOOL)::SendMessage(m_hWnd, LB_SETTABSTOPS, nTabStops, (LPARAM)rgTabStops); - } - - BOOL SetTabStops() - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & LBS_USETABSTOPS) != 0); - return (BOOL)::SendMessage(m_hWnd, LB_SETTABSTOPS, 0, 0L); - } - - BOOL SetTabStops(const int& cxEachStop) // takes an 'int' - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & LBS_USETABSTOPS) != 0); - return (BOOL)::SendMessage(m_hWnd, LB_SETTABSTOPS, 1, (LPARAM)(LPINT)&cxEachStop); - } - -// Operations - int InitStorage(int nItems, UINT nBytes) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_INITSTORAGE, (WPARAM)nItems, nBytes); - } - - void ResetContent() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, LB_RESETCONTENT, 0, 0L); - } - - UINT ItemFromPoint(POINT pt, BOOL& bOutside) const - { - ATLASSERT(::IsWindow(m_hWnd)); - DWORD dw = (DWORD)::SendMessage(m_hWnd, LB_ITEMFROMPOINT, 0, MAKELPARAM(pt.x, pt.y)); - bOutside = (BOOL)HIWORD(dw); - return (UINT)LOWORD(dw); - } - - // manipulating listbox items - int AddString(LPCTSTR lpszItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_ADDSTRING, 0, (LPARAM)lpszItem); - } - - int DeleteString(UINT nIndex) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_DELETESTRING, nIndex, 0L); - } - - int InsertString(int nIndex, LPCTSTR lpszItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_INSERTSTRING, nIndex, (LPARAM)lpszItem); - } - -#ifndef _WIN32_WCE - int Dir(UINT attr, LPCTSTR lpszWildCard) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_DIR, attr, (LPARAM)lpszWildCard); - } - - int AddFile(LPCTSTR lpstrFileName) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_ADDFILE, 0, (LPARAM)lpstrFileName); - } -#endif // !_WIN32_WCE - - // selection helpers - int FindString(int nStartAfter, LPCTSTR lpszItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_FINDSTRING, nStartAfter, (LPARAM)lpszItem); - } - - int FindStringExact(int nIndexStart, LPCTSTR lpszFind) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_FINDSTRINGEXACT, nIndexStart, (LPARAM)lpszFind); - } - - int SelectString(int nStartAfter, LPCTSTR lpszItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LB_SELECTSTRING, nStartAfter, (LPARAM)lpszItem); - } - - int SelItemRange(BOOL bSelect, int nFirstItem, int nLastItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); - ATLASSERT(nFirstItem <= nLastItem); - return bSelect ? (int)::SendMessage(m_hWnd, LB_SELITEMRANGEEX, nFirstItem, nLastItem) : (int)::SendMessage(m_hWnd, LB_SELITEMRANGEEX, nLastItem, nFirstItem); - } - -#ifdef WIN32_PLATFORM_WFSP // SmartPhone only messages - DWORD GetInputMode(BOOL bCurrentMode = TRUE) - { - return SendMessage(LB_GETINPUTMODE, 0, (LPARAM)bCurrentMode); - } - - BOOL SetInputMode(DWORD dwMode) - { - return SendMessage(LB_SETINPUTMODE, 0, (LPARAM)dwMode); - } -#endif // WIN32_PLATFORM_WFSP -}; - -typedef CListBoxT CListBox; - - -/////////////////////////////////////////////////////////////////////////////// -// CComboBox - client side for a Windows COMBOBOX control - -#ifndef WIN32_PLATFORM_WFSP // No COMBOBOX on SmartPhones - -template -class CComboBoxT : public TBase -{ -public: -// Constructors - CComboBoxT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CComboBoxT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return _T("COMBOBOX"); - } - - // for entire combo box - int GetCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_GETCOUNT, 0, 0L); - } - - int GetCurSel() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_GETCURSEL, 0, 0L); - } - - int SetCurSel(int nSelect) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_SETCURSEL, nSelect, 0L); - } - - LCID GetLocale() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (LCID)::SendMessage(m_hWnd, CB_GETLOCALE, 0, 0L); - } - - LCID SetLocale(LCID nNewLocale) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (LCID)::SendMessage(m_hWnd, CB_SETLOCALE, (WPARAM)nNewLocale, 0L); - } - - int GetTopIndex() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_GETTOPINDEX, 0, 0L); - } - - int SetTopIndex(int nIndex) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_SETTOPINDEX, nIndex, 0L); - } - - UINT GetHorizontalExtent() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, CB_GETHORIZONTALEXTENT, 0, 0L); - } - - void SetHorizontalExtent(UINT nExtent) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, CB_SETHORIZONTALEXTENT, nExtent, 0L); - } - - int GetDroppedWidth() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_GETDROPPEDWIDTH, 0, 0L); - } - - int SetDroppedWidth(UINT nWidth) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_SETDROPPEDWIDTH, nWidth, 0L); - } - -#if ((WINVER >= 0x0500) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420)) - BOOL GetComboBoxInfo(PCOMBOBOXINFO pComboBoxInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); -#if ((_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420)) - return (BOOL)::SendMessage(m_hWnd, CB_GETCOMBOBOXINFO, 0, (LPARAM)pComboBoxInfo); -#else // !((_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420)) - return ::GetComboBoxInfo(m_hWnd, pComboBoxInfo); -#endif // !((_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420)) - } -#endif // ((WINVER >= 0x0500) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420)) - - // for edit control - DWORD GetEditSel() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, CB_GETEDITSEL, 0, 0L); - } - - BOOL SetEditSel(int nStartChar, int nEndChar) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, CB_SETEDITSEL, 0, MAKELONG(nStartChar, nEndChar)); - } - - // for combobox item - DWORD_PTR GetItemData(int nIndex) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD_PTR)::SendMessage(m_hWnd, CB_GETITEMDATA, nIndex, 0L); - } - - int SetItemData(int nIndex, DWORD_PTR dwItemData) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_SETITEMDATA, nIndex, (LPARAM)dwItemData); - } - - void* GetItemDataPtr(int nIndex) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (void*)GetItemData(nIndex); - } - - int SetItemDataPtr(int nIndex, void* pData) - { - ATLASSERT(::IsWindow(m_hWnd)); - return SetItemData(nIndex, (DWORD_PTR)pData); - } - - int GetLBText(int nIndex, LPTSTR lpszText) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_GETLBTEXT, nIndex, (LPARAM)lpszText); - } - -#ifndef _ATL_NO_COM - BOOL GetLBTextBSTR(int nIndex, BSTR& bstrText) const - { - USES_CONVERSION; - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(bstrText == NULL); - - int nLen = GetLBTextLen(nIndex); - if(nLen == CB_ERR) - return FALSE; - - CTempBuffer buff; - LPTSTR lpstrText = buff.Allocate(nLen + 1); - if(lpstrText == NULL) - return FALSE; - - if(GetLBText(nIndex, lpstrText) == CB_ERR) - return FALSE; - - bstrText = ::SysAllocString(T2OLE(lpstrText)); - return (bstrText != NULL) ? TRUE : FALSE; - } -#endif // !_ATL_NO_COM - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - int GetLBText(int nIndex, _CSTRING_NS::CString& strText) const - { - ATLASSERT(::IsWindow(m_hWnd)); - int cchLen = GetLBTextLen(nIndex); - if(cchLen == CB_ERR) - return CB_ERR; - int nRet = CB_ERR; - LPTSTR lpstr = strText.GetBufferSetLength(cchLen); - if(lpstr != NULL) - { - nRet = GetLBText(nIndex, lpstr); - strText.ReleaseBuffer(); - } - return nRet; - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - - int GetLBTextLen(int nIndex) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_GETLBTEXTLEN, nIndex, 0L); - } - - int GetItemHeight(int nIndex) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_GETITEMHEIGHT, nIndex, 0L); - } - - int SetItemHeight(int nIndex, UINT cyItemHeight) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_SETITEMHEIGHT, nIndex, MAKELONG(cyItemHeight, 0)); - } - - BOOL GetExtendedUI() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, CB_GETEXTENDEDUI, 0, 0L); - } - - int SetExtendedUI(BOOL bExtended = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_SETEXTENDEDUI, bExtended, 0L); - } - - void GetDroppedControlRect(LPRECT lprect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)lprect); - } - - BOOL GetDroppedState() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, CB_GETDROPPEDSTATE, 0, 0L); - } - -#if (_WIN32_WINNT >= 0x0501) - int GetMinVisible() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_GETMINVISIBLE, 0, 0L); - } - - BOOL SetMinVisible(int nMinVisible) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, CB_SETMINVISIBLE, nMinVisible, 0L); - } - - // Vista only - BOOL GetCueBannerText(LPWSTR lpwText, int cchText) const - { -#ifndef CB_GETCUEBANNER - const UINT CB_GETCUEBANNER = (CBM_FIRST + 4); -#endif - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, CB_GETCUEBANNER, (WPARAM)lpwText, cchText); - } - - // Vista only - BOOL SetCueBannerText(LPCWSTR lpcwText) - { -#ifndef CB_SETCUEBANNER - const UINT CB_SETCUEBANNER = (CBM_FIRST + 3); -#endif - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, CB_SETCUEBANNER, 0, (LPARAM)lpcwText); - } -#endif // (_WIN32_WINNT >= 0x0501) - -// Operations - int InitStorage(int nItems, UINT nBytes) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_INITSTORAGE, (WPARAM)nItems, nBytes); - } - - void ResetContent() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, CB_RESETCONTENT, 0, 0L); - } - - // for edit control - BOOL LimitText(int nMaxChars) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, CB_LIMITTEXT, nMaxChars, 0L); - } - - // for drop-down combo boxes - void ShowDropDown(BOOL bShowIt = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, CB_SHOWDROPDOWN, bShowIt, 0L); - } - - // manipulating listbox items - int AddString(LPCTSTR lpszString) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_ADDSTRING, 0, (LPARAM)lpszString); - } - - int DeleteString(UINT nIndex) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_DELETESTRING, nIndex, 0L); - } - - int InsertString(int nIndex, LPCTSTR lpszString) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_INSERTSTRING, nIndex, (LPARAM)lpszString); - } - -#ifndef _WIN32_WCE - int Dir(UINT attr, LPCTSTR lpszWildCard) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_DIR, attr, (LPARAM)lpszWildCard); - } -#endif // !_WIN32_WCE - - // selection helpers - int FindString(int nStartAfter, LPCTSTR lpszString) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_FINDSTRING, nStartAfter, (LPARAM)lpszString); - } - - int FindStringExact(int nIndexStart, LPCTSTR lpszFind) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_FINDSTRINGEXACT, nIndexStart, (LPARAM)lpszFind); - } - - int SelectString(int nStartAfter, LPCTSTR lpszString) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CB_SELECTSTRING, nStartAfter, (LPARAM)lpszString); - } - - // Clipboard operations - void Clear() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, WM_CLEAR, 0, 0L); - } - - void Copy() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, WM_COPY, 0, 0L); - } - - void Cut() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, WM_CUT, 0, 0L); - } - - void Paste() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, WM_PASTE, 0, 0L); - } -}; - -typedef CComboBoxT CComboBox; - -#endif // !WIN32_PLATFORM_WFSP - -/////////////////////////////////////////////////////////////////////////////// -// CEdit - client side for a Windows EDIT control - -template -class CEditT : public TBase -{ -public: -// Constructors - CEditT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CEditT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return _T("EDIT"); - } - - BOOL CanUndo() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_CANUNDO, 0, 0L); - } - - int GetLineCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_GETLINECOUNT, 0, 0L); - } - - BOOL GetModify() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_GETMODIFY, 0, 0L); - } - - void SetModify(BOOL bModified = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETMODIFY, bModified, 0L); - } - - void GetRect(LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_GETRECT, 0, (LPARAM)lpRect); - } - - DWORD GetSel() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, EM_GETSEL, 0, 0L); - } - - void GetSel(int& nStartChar, int& nEndChar) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar); - } - -#ifndef _WIN32_WCE - HLOCAL GetHandle() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HLOCAL)::SendMessage(m_hWnd, EM_GETHANDLE, 0, 0L); - } - - void SetHandle(HLOCAL hBuffer) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETHANDLE, (WPARAM)hBuffer, 0L); - } -#endif // !_WIN32_WCE - - DWORD GetMargins() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, EM_GETMARGINS, 0, 0L); - } - - void SetMargins(UINT nLeft, UINT nRight) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELONG(nLeft, nRight)); - } - - UINT GetLimitText() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, EM_GETLIMITTEXT, 0, 0L); - } - - void SetLimitText(UINT nMax) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETLIMITTEXT, nMax, 0L); - } - - POINT PosFromChar(UINT nChar) const - { - ATLASSERT(::IsWindow(m_hWnd)); - DWORD dwRet = (DWORD)::SendMessage(m_hWnd, EM_POSFROMCHAR, nChar, 0); - POINT point = { GET_X_LPARAM(dwRet), GET_Y_LPARAM(dwRet) }; - return point; - } - - int CharFromPos(POINT pt, int* pLine = NULL) const - { - ATLASSERT(::IsWindow(m_hWnd)); - DWORD dwRet = (DWORD)::SendMessage(m_hWnd, EM_CHARFROMPOS, 0, MAKELPARAM(pt.x, pt.y)); - if(pLine != NULL) - *pLine = (int)(short)HIWORD(dwRet); - return (int)(short)LOWORD(dwRet); - } - - // NOTE: first word in lpszBuffer must contain the size of the buffer! - int GetLine(int nIndex, LPTSTR lpszBuffer) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer); - } - - int GetLine(int nIndex, LPTSTR lpszBuffer, int nMaxLength) const - { - ATLASSERT(::IsWindow(m_hWnd)); - *(LPWORD)lpszBuffer = (WORD)nMaxLength; - return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer); - } - - TCHAR GetPasswordChar() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (TCHAR)::SendMessage(m_hWnd, EM_GETPASSWORDCHAR, 0, 0L); - } - - void SetPasswordChar(TCHAR ch) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETPASSWORDCHAR, ch, 0L); - } - -#ifndef _WIN32_WCE - EDITWORDBREAKPROC GetWordBreakProc() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (EDITWORDBREAKPROC)::SendMessage(m_hWnd, EM_GETWORDBREAKPROC, 0, 0L); - } - - void SetWordBreakProc(EDITWORDBREAKPROC ewbprc) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETWORDBREAKPROC, 0, (LPARAM)ewbprc); - } -#endif // !_WIN32_WCE - - int GetFirstVisibleLine() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_GETFIRSTVISIBLELINE, 0, 0L); - } - -#ifndef _WIN32_WCE - int GetThumb() const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & ES_MULTILINE) != 0); - return (int)::SendMessage(m_hWnd, EM_GETTHUMB, 0, 0L); - } -#endif // !_WIN32_WCE - - BOOL SetReadOnly(BOOL bReadOnly = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_SETREADONLY, bReadOnly, 0L); - } - -#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) - UINT GetImeStatus(UINT uStatus) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, EM_GETIMESTATUS, uStatus, 0L); - } - - UINT SetImeStatus(UINT uStatus, UINT uData) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, EM_SETIMESTATUS, uStatus, uData); - } -#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) - -#if (_WIN32_WINNT >= 0x0501) - BOOL GetCueBannerText(LPCWSTR lpstrText, int cchText) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_GETCUEBANNER, (WPARAM)lpstrText, cchText); - } - - // bKeepWithFocus - Vista only - BOOL SetCueBannerText(LPCWSTR lpstrText, BOOL bKeepWithFocus = FALSE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_SETCUEBANNER, (WPARAM)bKeepWithFocus, (LPARAM)(lpstrText)); - } -#endif // (_WIN32_WINNT >= 0x0501) - -// Operations - void EmptyUndoBuffer() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_EMPTYUNDOBUFFER, 0, 0L); - } - - BOOL FmtLines(BOOL bAddEOL) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_FMTLINES, bAddEOL, 0L); - } - - void LimitText(int nChars = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_LIMITTEXT, nChars, 0L); - } - - int LineFromChar(int nIndex = -1) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_LINEFROMCHAR, nIndex, 0L); - } - - int LineIndex(int nLine = -1) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_LINEINDEX, nLine, 0L); - } - - int LineLength(int nLine = -1) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_LINELENGTH, nLine, 0L); - } - - void LineScroll(int nLines, int nChars = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_LINESCROLL, nChars, nLines); - } - - void ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo = FALSE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_REPLACESEL, (WPARAM) bCanUndo, (LPARAM)lpszNewText); - } - - void SetRect(LPCRECT lpRect) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETRECT, 0, (LPARAM)lpRect); - } - - void SetRectNP(LPCRECT lpRect) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETRECTNP, 0, (LPARAM)lpRect); - } - - void SetSel(DWORD dwSelection, BOOL bNoScroll = FALSE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETSEL, LOWORD(dwSelection), HIWORD(dwSelection)); - if(!bNoScroll) - ::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L); - } - - void SetSel(int nStartChar, int nEndChar, BOOL bNoScroll = FALSE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETSEL, nStartChar, nEndChar); - if(!bNoScroll) - ::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L); - } - - void SetSelAll(BOOL bNoScroll = FALSE) - { - SetSel(0, -1, bNoScroll); - } - - void SetSelNone(BOOL bNoScroll = FALSE) - { - SetSel(-1, 0, bNoScroll); - } - - BOOL SetTabStops(int nTabStops, LPINT rgTabStops) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, nTabStops, (LPARAM)rgTabStops); - } - - BOOL SetTabStops() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 0, 0L); - } - - BOOL SetTabStops(const int& cxEachStop) // takes an 'int' - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 1, (LPARAM)(LPINT)&cxEachStop); - } - - void ScrollCaret() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L); - } - - int Scroll(int nScrollAction) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & ES_MULTILINE) != 0); - LRESULT lRet = ::SendMessage(m_hWnd, EM_SCROLL, nScrollAction, 0L); - if(!(BOOL)HIWORD(lRet)) - return -1; // failed - return (int)(short)LOWORD(lRet); - - } - - void InsertText(int nInsertAfterChar, LPCTSTR lpstrText, BOOL bNoScroll = FALSE, BOOL bCanUndo = FALSE) - { - SetSel(nInsertAfterChar, nInsertAfterChar, bNoScroll); - ReplaceSel(lpstrText, bCanUndo); - } - - void AppendText(LPCTSTR lpstrText, BOOL bNoScroll = FALSE, BOOL bCanUndo = FALSE) - { - InsertText(GetWindowTextLength(), lpstrText, bNoScroll, bCanUndo); - } - -#if (_WIN32_WINNT >= 0x0501) - BOOL ShowBalloonTip(PEDITBALLOONTIP pEditBaloonTip) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_SHOWBALLOONTIP, 0, (LPARAM)pEditBaloonTip); - } - - BOOL HideBalloonTip() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_HIDEBALLOONTIP, 0, 0L); - } -#endif // (_WIN32_WINNT >= 0x0501) - -#if (_WIN32_WINNT >= 0x0600) - DWORD GetHilite() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, EM_GETHILITE, 0, 0L); - } - - void GetHilite(int& nStartChar, int& nEndChar) const - { - ATLASSERT(::IsWindow(m_hWnd)); - DWORD dwRet = (DWORD)::SendMessage(m_hWnd, EM_GETHILITE, 0, 0L); - nStartChar = (int)(short)LOWORD(dwRet); - nEndChar = (int)(short)HIWORD(dwRet); - } - - void SetHilite(int nStartChar, int nEndChar) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETHILITE, nStartChar, nEndChar); - } -#endif // (_WIN32_WINNT >= 0x0600) - - // Clipboard operations - BOOL Undo() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_UNDO, 0, 0L); - } - - void Clear() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, WM_CLEAR, 0, 0L); - } - - void Copy() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, WM_COPY, 0, 0L); - } - - void Cut() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, WM_CUT, 0, 0L); - } - - void Paste() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, WM_PASTE, 0, 0L); - } - -#ifdef WIN32_PLATFORM_WFSP // SmartPhone only messages - DWORD GetExtendedStyle() - { - return SendMessage(EM_GETEXTENDEDSTYLE); - } - - DWORD SetExtendedStyle(DWORD dwMask, DWORD dwExStyle) - { - return SendMessage(EM_SETEXTENDEDSTYLE, (WPARAM)dwMask, (LPARAM)dwExStyle); - } - - DWORD GetInputMode(BOOL bCurrentMode = TRUE) - { - return SendMessage(EM_GETINPUTMODE, 0, (LPARAM)bCurrentMode); - } - - BOOL SetInputMode(DWORD dwMode) - { - return SendMessage(EM_SETINPUTMODE, 0, (LPARAM)dwMode); - } - - BOOL SetSymbols(LPCTSTR szSymbols) - { - return SendMessage(EM_SETSYMBOLS, 0, (LPARAM)szSymbols); - } - - BOOL ResetSymbols() - { - return SendMessage(EM_SETSYMBOLS); - } -#endif // WIN32_PLATFORM_WFSP -}; - -typedef CEditT CEdit; - - -/////////////////////////////////////////////////////////////////////////////// -// CEditCommands - message handlers for standard EDIT commands - -// Chain to CEditCommands message map. Your class must also derive from CEdit. -// Example: -// class CMyEdit : public CWindowImpl, -// public CEditCommands -// { -// public: -// BEGIN_MSG_MAP(CMyEdit) -// // your handlers... -// CHAIN_MSG_MAP_ALT(CEditCommands, 1) -// END_MSG_MAP() -// // other stuff... -// }; - -template -class CEditCommands -{ -public: - BEGIN_MSG_MAP(CEditCommands< T >) - ALT_MSG_MAP(1) - COMMAND_ID_HANDLER(ID_EDIT_CLEAR, OnEditClear) - COMMAND_ID_HANDLER(ID_EDIT_CLEAR_ALL, OnEditClearAll) - COMMAND_ID_HANDLER(ID_EDIT_COPY, OnEditCopy) - COMMAND_ID_HANDLER(ID_EDIT_CUT, OnEditCut) - COMMAND_ID_HANDLER(ID_EDIT_PASTE, OnEditPaste) - COMMAND_ID_HANDLER(ID_EDIT_SELECT_ALL, OnEditSelectAll) - COMMAND_ID_HANDLER(ID_EDIT_UNDO, OnEditUndo) - END_MSG_MAP() - - LRESULT OnEditClear(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->Clear(); - return 0; - } - - LRESULT OnEditClearAll(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->SetSel(0, -1); - pT->Clear(); - return 0; - } - - LRESULT OnEditCopy(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->Copy(); - return 0; - } - - LRESULT OnEditCut(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->Cut(); - return 0; - } - - LRESULT OnEditPaste(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->Paste(); - return 0; - } - - LRESULT OnEditSelectAll(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->SetSel(0, -1); - return 0; - } - - LRESULT OnEditUndo(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->Undo(); - return 0; - } - -// State (update UI) helpers - BOOL CanCut() const - { return HasSelection(); } - - BOOL CanCopy() const - { return HasSelection(); } - - BOOL CanClear() const - { return HasSelection(); } - - BOOL CanSelectAll() const - { return HasText(); } - - BOOL CanFind() const - { return HasText(); } - - BOOL CanRepeat() const - { return HasText(); } - - BOOL CanReplace() const - { return HasText(); } - - BOOL CanClearAll() const - { return HasText(); } - -// Implementation - BOOL HasSelection() const - { - const T* pT = static_cast(this); - int nMin, nMax; - ::SendMessage(pT->m_hWnd, EM_GETSEL, (WPARAM)&nMin, (LPARAM)&nMax); - return (nMin != nMax); - } - - BOOL HasText() const - { - const T* pT = static_cast(this); - return (pT->GetWindowTextLength() > 0); - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CScrollBar - client side for a Windows SCROLLBAR control - -template -class CScrollBarT : public TBase -{ -public: -// Constructors - CScrollBarT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CScrollBarT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return _T("SCROLLBAR"); - } - -#ifndef _WIN32_WCE - int GetScrollPos() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::GetScrollPos(m_hWnd, SB_CTL); - } -#endif // !_WIN32_WCE - - int SetScrollPos(int nPos, BOOL bRedraw = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::SetScrollPos(m_hWnd, SB_CTL, nPos, bRedraw); - } - -#ifndef _WIN32_WCE - void GetScrollRange(LPINT lpMinPos, LPINT lpMaxPos) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::GetScrollRange(m_hWnd, SB_CTL, lpMinPos, lpMaxPos); - } -#endif // !_WIN32_WCE - - void SetScrollRange(int nMinPos, int nMaxPos, BOOL bRedraw = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SetScrollRange(m_hWnd, SB_CTL, nMinPos, nMaxPos, bRedraw); - } - - BOOL GetScrollInfo(LPSCROLLINFO lpScrollInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::GetScrollInfo(m_hWnd, SB_CTL, lpScrollInfo); - } - - int SetScrollInfo(LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::SetScrollInfo(m_hWnd, SB_CTL, lpScrollInfo, bRedraw); - } - -#ifndef _WIN32_WCE - int GetScrollLimit() const - { - int nMin = 0, nMax = 0; - ::GetScrollRange(m_hWnd, SB_CTL, &nMin, &nMax); - SCROLLINFO info = { 0 }; - info.cbSize = sizeof(SCROLLINFO); - info.fMask = SIF_PAGE; - if(::GetScrollInfo(m_hWnd, SB_CTL, &info)) - nMax -= ((info.nPage - 1) > 0) ? (info.nPage - 1) : 0; - - return nMax; - } - -#if (WINVER >= 0x0500) - BOOL GetScrollBarInfo(PSCROLLBARINFO pScrollBarInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); -#if (_WIN32_WINNT >= 0x0501) - return (BOOL)::SendMessage(m_hWnd, SBM_GETSCROLLBARINFO, 0, (LPARAM)pScrollBarInfo); -#else // !(_WIN32_WINNT >= 0x0501) - return ::GetScrollBarInfo(m_hWnd, OBJID_CLIENT, pScrollBarInfo); -#endif // !(_WIN32_WINNT >= 0x0501) - } -#endif // (WINVER >= 0x0500) - -// Operations - void ShowScrollBar(BOOL bShow = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::ShowScrollBar(m_hWnd, SB_CTL, bShow); - } - - BOOL EnableScrollBar(UINT nArrowFlags = ESB_ENABLE_BOTH) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::EnableScrollBar(m_hWnd, SB_CTL, nArrowFlags); - } -#endif // !_WIN32_WCE -}; - -typedef CScrollBarT CScrollBar; - - -// --- Windows Common Controls --- - -/////////////////////////////////////////////////////////////////////////////// -// CImageList - -class CImageList -{ -public: - HIMAGELIST m_hImageList; - -// Constructor - CImageList(HIMAGELIST hImageList = NULL) : m_hImageList(hImageList) - { } - -// Operators, etc. - CImageList& operator =(HIMAGELIST hImageList) - { - m_hImageList = hImageList; - return *this; - } - - operator HIMAGELIST() const { return m_hImageList; } - - void Attach(HIMAGELIST hImageList) - { - ATLASSERT(m_hImageList == NULL); - ATLASSERT(hImageList != NULL); - m_hImageList = hImageList; - } - - HIMAGELIST Detach() - { - HIMAGELIST hImageList = m_hImageList; - m_hImageList = NULL; - return hImageList; - } - - bool IsNull() const { return (m_hImageList == NULL); } - -// Attributes - int GetImageCount() const - { - ATLASSERT(m_hImageList != NULL); - return ImageList_GetImageCount(m_hImageList); - } - - COLORREF GetBkColor() const - { - ATLASSERT(m_hImageList != NULL); - return ImageList_GetBkColor(m_hImageList); - } - - COLORREF SetBkColor(COLORREF cr) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_SetBkColor(m_hImageList, cr); - } - - BOOL GetImageInfo(int nImage, IMAGEINFO* pImageInfo) const - { - ATLASSERT(m_hImageList != NULL); - return ImageList_GetImageInfo(m_hImageList, nImage, pImageInfo); - } - - HICON GetIcon(int nIndex, UINT uFlags = ILD_NORMAL) const - { - ATLASSERT(m_hImageList != NULL); - return ImageList_GetIcon(m_hImageList, nIndex, uFlags); - } - - BOOL GetIconSize(int& cx, int& cy) const - { - ATLASSERT(m_hImageList != NULL); - return ImageList_GetIconSize(m_hImageList, &cx, &cy); - } - - BOOL GetIconSize(SIZE& size) const - { - ATLASSERT(m_hImageList != NULL); - return ImageList_GetIconSize(m_hImageList, (int*)&size.cx, (int*)&size.cy); - } - - BOOL SetIconSize(int cx, int cy) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_SetIconSize(m_hImageList, cx, cy); - } - - BOOL SetIconSize(SIZE size) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_SetIconSize(m_hImageList, size.cx, size.cy); - } - - BOOL SetImageCount(UINT uNewCount) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_SetImageCount(m_hImageList, uNewCount); - } - - BOOL SetOverlayImage(int nImage, int nOverlay) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_SetOverlayImage(m_hImageList, nImage, nOverlay); - } - -// Operations - BOOL Create(int cx, int cy, UINT nFlags, int nInitial, int nGrow) - { - ATLASSERT(m_hImageList == NULL); - m_hImageList = ImageList_Create(cx, cy, nFlags, nInitial, nGrow); - return (m_hImageList != NULL) ? TRUE : FALSE; - } - - BOOL Create(ATL::_U_STRINGorID bitmap, int cx, int nGrow, COLORREF crMask) - { - ATLASSERT(m_hImageList == NULL); - m_hImageList = ImageList_LoadBitmap(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr, cx, nGrow, crMask); - return (m_hImageList != NULL) ? TRUE : FALSE; - } - - BOOL CreateFromImage(ATL::_U_STRINGorID image, int cx, int nGrow, COLORREF crMask, UINT uType, UINT uFlags = LR_DEFAULTCOLOR | LR_DEFAULTSIZE) - { - ATLASSERT(m_hImageList == NULL); - m_hImageList = ImageList_LoadImage(ModuleHelper::GetResourceInstance(), image.m_lpstr, cx, nGrow, crMask, uType, uFlags); - return (m_hImageList != NULL) ? TRUE : FALSE; - } - - BOOL Merge(HIMAGELIST hImageList1, int nImage1, HIMAGELIST hImageList2, int nImage2, int dx, int dy) - { - ATLASSERT(m_hImageList == NULL); - m_hImageList = ImageList_Merge(hImageList1, nImage1, hImageList2, nImage2, dx, dy); - return (m_hImageList != NULL) ? TRUE : FALSE; - } - -#ifndef _WIN32_WCE -#ifdef __IStream_INTERFACE_DEFINED__ - BOOL CreateFromStream(LPSTREAM lpStream) - { - ATLASSERT(m_hImageList == NULL); - m_hImageList = ImageList_Read(lpStream); - return (m_hImageList != NULL) ? TRUE : FALSE; - } -#endif // __IStream_INTERFACE_DEFINED__ -#endif // !_WIN32_WCE - - BOOL Destroy() - { - if (m_hImageList == NULL) - return FALSE; - BOOL bRet = ImageList_Destroy(m_hImageList); - if(bRet) - m_hImageList = NULL; - return bRet; - } - - int Add(HBITMAP hBitmap, HBITMAP hBitmapMask = NULL) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_Add(m_hImageList, hBitmap, hBitmapMask); - } - - int Add(HBITMAP hBitmap, COLORREF crMask) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_AddMasked(m_hImageList, hBitmap, crMask); - } - - BOOL Remove(int nImage) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_Remove(m_hImageList, nImage); - } - - BOOL RemoveAll() - { - ATLASSERT(m_hImageList != NULL); - return ImageList_RemoveAll(m_hImageList); - } - - BOOL Replace(int nImage, HBITMAP hBitmap, HBITMAP hBitmapMask) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_Replace(m_hImageList, nImage, hBitmap, hBitmapMask); - } - - int AddIcon(HICON hIcon) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_AddIcon(m_hImageList, hIcon); - } - - int ReplaceIcon(int nImage, HICON hIcon) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_ReplaceIcon(m_hImageList, nImage, hIcon); - } - - HICON ExtractIcon(int nImage) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_ExtractIcon(NULL, m_hImageList, nImage); - } - - BOOL Draw(HDC hDC, int nImage, int x, int y, UINT nStyle) - { - ATLASSERT(m_hImageList != NULL); - ATLASSERT(hDC != NULL); - return ImageList_Draw(m_hImageList, nImage, hDC, x, y, nStyle); - } - - BOOL Draw(HDC hDC, int nImage, POINT pt, UINT nStyle) - { - ATLASSERT(m_hImageList != NULL); - ATLASSERT(hDC != NULL); - return ImageList_Draw(m_hImageList, nImage, hDC, pt.x, pt.y, nStyle); - } - - BOOL DrawEx(int nImage, HDC hDC, int x, int y, int dx, int dy, COLORREF rgbBk, COLORREF rgbFg, UINT fStyle) - { - ATLASSERT(m_hImageList != NULL); - ATLASSERT(hDC != NULL); - return ImageList_DrawEx(m_hImageList, nImage, hDC, x, y, dx, dy, rgbBk, rgbFg, fStyle); - } - - BOOL DrawEx(int nImage, HDC hDC, RECT& rect, COLORREF rgbBk, COLORREF rgbFg, UINT fStyle) - { - ATLASSERT(m_hImageList != NULL); - ATLASSERT(hDC != NULL); - return ImageList_DrawEx(m_hImageList, nImage, hDC, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, rgbBk, rgbFg, fStyle); - } - - static BOOL DrawIndirect(IMAGELISTDRAWPARAMS* pimldp) - { - return ImageList_DrawIndirect(pimldp); - } - - BOOL Copy(int nSrc, int nDst, UINT uFlags = ILCF_MOVE) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_Copy(m_hImageList, nDst, m_hImageList, nSrc, uFlags); - } - -#ifdef __IStream_INTERFACE_DEFINED__ -#ifndef _WIN32_WCE - static HIMAGELIST Read(LPSTREAM lpStream) - { - return ImageList_Read(lpStream); - } - - BOOL Write(LPSTREAM lpStream) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_Write(m_hImageList, lpStream); - } -#endif // !_WIN32_WCE - -#if (_WIN32_WINNT >= 0x0501) - static HRESULT ReadEx(DWORD dwFlags, LPSTREAM lpStream, REFIID riid, PVOID* ppv) - { - DebugBreak(); - return NULL; - //return ImageList_ReadEx(dwFlags, lpStream, riid, ppv); - } - - HRESULT WriteEx(DWORD dwFlags, LPSTREAM lpStream) - { - ATLASSERT(m_hImageList != NULL); - DebugBreak(); - return NULL; - //return ImageList_WriteEx(m_hImageList, dwFlags, lpStream); - } -#endif // (_WIN32_WINNT >= 0x0501) -#endif // __IStream_INTERFACE_DEFINED__ - - // Drag operations - BOOL BeginDrag(int nImage, POINT ptHotSpot) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_BeginDrag(m_hImageList, nImage, ptHotSpot.x, ptHotSpot.y); - } - - BOOL BeginDrag(int nImage, int xHotSpot, int yHotSpot) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_BeginDrag(m_hImageList, nImage, xHotSpot, yHotSpot); - } - - static void EndDrag() - { - ImageList_EndDrag(); - } - - static BOOL DragMove(POINT pt) - { - return ImageList_DragMove(pt.x, pt.y); - } - - static BOOL DragMove(int x, int y) - { - return ImageList_DragMove(x, y); - } - - BOOL SetDragCursorImage(int nDrag, POINT ptHotSpot) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_SetDragCursorImage(m_hImageList, nDrag, ptHotSpot.x, ptHotSpot.y); - } - - BOOL SetDragCursorImage(int nDrag, int xHotSpot, int yHotSpot) - { - ATLASSERT(m_hImageList != NULL); - return ImageList_SetDragCursorImage(m_hImageList, nDrag, xHotSpot, yHotSpot); - } - - static BOOL DragShowNolock(BOOL bShow = TRUE) - { - return ImageList_DragShowNolock(bShow); - } - - static CImageList GetDragImage(LPPOINT lpPoint, LPPOINT lpPointHotSpot) - { - return CImageList(ImageList_GetDragImage(lpPoint, lpPointHotSpot)); - } - - static BOOL DragEnter(HWND hWnd, POINT point) - { - return ImageList_DragEnter(hWnd, point.x, point.y); - } - - static BOOL DragEnter(HWND hWnd, int x, int y) - { - return ImageList_DragEnter(hWnd, x, y); - } - - static BOOL DragLeave(HWND hWnd) - { - return ImageList_DragLeave(hWnd); - } - -#if (_WIN32_IE >= 0x0400) - CImageList Duplicate() const - { - ATLASSERT(m_hImageList != NULL); - return CImageList(ImageList_Duplicate(m_hImageList)); - } - - static CImageList Duplicate(HIMAGELIST hImageList) - { - ATLASSERT(hImageList != NULL); - return CImageList(ImageList_Duplicate(hImageList)); - } -#endif // (_WIN32_IE >= 0x0400) -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CToolTipCtrl - -#ifndef _WIN32_WCE - -class CToolInfo : public TOOLINFO -{ -public: - CToolInfo(UINT nFlags, HWND hWnd, UINT nIDTool = 0, LPRECT lpRect = NULL, LPTSTR lpstrText = LPSTR_TEXTCALLBACK, LPARAM lUserParam = NULL) - { - Init(nFlags, hWnd, nIDTool, lpRect, lpstrText, lUserParam); - } - - operator LPTOOLINFO() { return this; } - - operator LPARAM() { return (LPARAM)this; } - - void Init(UINT nFlags, HWND hWnd, UINT nIDTool = 0, LPRECT lpRect = NULL, LPTSTR lpstrText = LPSTR_TEXTCALLBACK, LPARAM lUserParam = NULL) - { - ATLASSERT(::IsWindow(hWnd)); - memset(this, 0, sizeof(TOOLINFO)); - cbSize = sizeof(TOOLINFO); - uFlags = nFlags; - if(nIDTool == 0) - { - hwnd = ::GetParent(hWnd); - uFlags |= TTF_IDISHWND; - uId = (UINT_PTR)hWnd; - } - else - { - hwnd = hWnd; - uId = nIDTool; - } - if(lpRect != NULL) - rect = *lpRect; - hinst = ModuleHelper::GetResourceInstance(); - lpszText = lpstrText; - lParam = lUserParam; - } -}; - -template -class CToolTipCtrlT : public TBase -{ -public: -// Constructors - CToolTipCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CToolTipCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return TOOLTIPS_CLASS; - } - - void GetText(LPTOOLINFO lpToolInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_GETTEXT, 0, (LPARAM)&lpToolInfo); - } - - void GetText(LPTSTR lpstrText, HWND hWnd, UINT nIDTool = 0) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(hWnd != NULL); - CToolInfo ti(0, hWnd, nIDTool, NULL, lpstrText); - ::SendMessage(m_hWnd, TTM_GETTEXT, 0, ti); - } - - BOOL GetToolInfo(LPTOOLINFO lpToolInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TTM_GETTOOLINFO, 0, (LPARAM)lpToolInfo); - } - - BOOL GetToolInfo(HWND hWnd, UINT nIDTool, UINT* puFlags, LPRECT lpRect, LPTSTR lpstrText) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(hWnd != NULL); - ATLASSERT(puFlags != NULL); - ATLASSERT(lpRect != NULL); - CToolInfo ti(0, hWnd, nIDTool, NULL, lpstrText); - BOOL bRet = (BOOL)::SendMessage(m_hWnd, TTM_GETTOOLINFO, 0, ti); - if(bRet != FALSE) - { - *puFlags = ti.uFlags; - *lpRect = ti.rect; - } - return bRet; - } - - void SetToolInfo(LPTOOLINFO lpToolInfo) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_SETTOOLINFO, 0, (LPARAM)lpToolInfo); - } - - void SetToolRect(LPTOOLINFO lpToolInfo) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_NEWTOOLRECT, 0, (LPARAM)lpToolInfo); - } - - void SetToolRect(HWND hWnd, UINT nIDTool, LPCRECT lpRect) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(hWnd != NULL); - ATLASSERT(nIDTool != 0); - - CToolInfo ti(0, hWnd, nIDTool, (LPRECT)lpRect, NULL); - ::SendMessage(m_hWnd, TTM_NEWTOOLRECT, 0, ti); - } - - int GetToolCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TTM_GETTOOLCOUNT, 0, 0L); - } - - int GetDelayTime(DWORD dwType) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TTM_GETDELAYTIME, dwType, 0L); - } - - void SetDelayTime(DWORD dwType, int nTime) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_SETDELAYTIME, dwType, MAKELPARAM(nTime, 0)); - } - - void GetMargin(LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_GETMARGIN, 0, (LPARAM)lpRect); - } - - void SetMargin(LPRECT lpRect) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_SETMARGIN, 0, (LPARAM)lpRect); - } - - int GetMaxTipWidth() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TTM_GETMAXTIPWIDTH, 0, 0L); - } - - int SetMaxTipWidth(int nWidth) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TTM_SETMAXTIPWIDTH, 0, nWidth); - } - - COLORREF GetTipBkColor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, TTM_GETTIPBKCOLOR, 0, 0L); - } - - void SetTipBkColor(COLORREF clr) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_SETTIPBKCOLOR, (WPARAM)clr, 0L); - } - - COLORREF GetTipTextColor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, TTM_GETTIPTEXTCOLOR, 0, 0L); - } - - void SetTipTextColor(COLORREF clr) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_SETTIPTEXTCOLOR, (WPARAM)clr, 0L); - } - - BOOL GetCurrentTool(LPTOOLINFO lpToolInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TTM_GETCURRENTTOOL, 0, (LPARAM)lpToolInfo); - } - -#if (_WIN32_IE >= 0x0500) - SIZE GetBubbleSize(LPTOOLINFO lpToolInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - DWORD dwRet = (DWORD)::SendMessage(m_hWnd, TTM_GETBUBBLESIZE, 0, (LPARAM)lpToolInfo); - SIZE size = { GET_X_LPARAM(dwRet), GET_Y_LPARAM(dwRet) }; - return size; - } - - BOOL SetTitle(UINT uIcon, LPCTSTR lpstrTitle) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TTM_SETTITLE, uIcon, (LPARAM)lpstrTitle); - } -#endif // (_WIN32_IE >= 0x0500) - -#if (_WIN32_WINNT >= 0x0501) - void GetTitle(PTTGETTITLE pTTGetTitle) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_GETTITLE, 0, (LPARAM)pTTGetTitle); - } - - void SetWindowTheme(LPCWSTR lpstrTheme) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_SETWINDOWTHEME, 0, (LPARAM)lpstrTheme); - } -#endif // (_WIN32_WINNT >= 0x0501) - -// Operations - void Activate(BOOL bActivate) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_ACTIVATE, bActivate, 0L); - } - - BOOL AddTool(LPTOOLINFO lpToolInfo) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TTM_ADDTOOL, 0, (LPARAM)lpToolInfo); - } - - BOOL AddTool(HWND hWnd, ATL::_U_STRINGorID text = LPSTR_TEXTCALLBACK, LPCRECT lpRectTool = NULL, UINT nIDTool = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(hWnd != NULL); - // the toolrect and toolid must both be zero or both valid - ATLASSERT((lpRectTool != NULL && nIDTool != 0) || (lpRectTool == NULL && nIDTool == 0)); - - CToolInfo ti(0, hWnd, nIDTool, (LPRECT)lpRectTool, (LPTSTR)text.m_lpstr); - return (BOOL)::SendMessage(m_hWnd, TTM_ADDTOOL, 0, ti); - } - - void DelTool(LPTOOLINFO lpToolInfo) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_DELTOOL, 0, (LPARAM)lpToolInfo); - } - - void DelTool(HWND hWnd, UINT nIDTool = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(hWnd != NULL); - - CToolInfo ti(0, hWnd, nIDTool, NULL, NULL); - ::SendMessage(m_hWnd, TTM_DELTOOL, 0, ti); - } - - BOOL HitTest(LPTTHITTESTINFO lpHitTestInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TTM_HITTEST, 0, (LPARAM)lpHitTestInfo); - } - - BOOL HitTest(HWND hWnd, POINT pt, LPTOOLINFO lpToolInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(hWnd != NULL); - ATLASSERT(lpToolInfo != NULL); - - TTHITTESTINFO hti = { 0 }; - hti.ti.cbSize = sizeof(TOOLINFO); - hti.hwnd = hWnd; - hti.pt.x = pt.x; - hti.pt.y = pt.y; - if((BOOL)::SendMessage(m_hWnd, TTM_HITTEST, 0, (LPARAM)&hti) != FALSE) - { - *lpToolInfo = hti.ti; - return TRUE; - } - return FALSE; - } - - void RelayEvent(LPMSG lpMsg) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_RELAYEVENT, 0, (LPARAM)lpMsg); - } - - void UpdateTipText(LPTOOLINFO lpToolInfo) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_UPDATETIPTEXT, 0, (LPARAM)lpToolInfo); - } - - void UpdateTipText(ATL::_U_STRINGorID text, HWND hWnd, UINT nIDTool = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(hWnd != NULL); - - CToolInfo ti(0, hWnd, nIDTool, NULL, (LPTSTR)text.m_lpstr); - ::SendMessage(m_hWnd, TTM_UPDATETIPTEXT, 0, ti); - } - - BOOL EnumTools(UINT nTool, LPTOOLINFO lpToolInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TTM_ENUMTOOLS, nTool, (LPARAM)lpToolInfo); - } - - void Pop() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_POP, 0, 0L); - } - - void TrackActivate(LPTOOLINFO lpToolInfo, BOOL bActivate) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_TRACKACTIVATE, bActivate, (LPARAM)lpToolInfo); - } - - void TrackPosition(int xPos, int yPos) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_TRACKPOSITION, 0, MAKELPARAM(xPos, yPos)); - } - -#if (_WIN32_IE >= 0x0400) - void Update() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_UPDATE, 0, 0L); - } -#endif // (_WIN32_IE >= 0x0400) - -#if (_WIN32_IE >= 0x0500) - BOOL AdjustRect(LPRECT lpRect, BOOL bLarger /*= TRUE*/) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TTM_ADJUSTRECT, bLarger, (LPARAM)lpRect); - } -#endif // (_WIN32_IE >= 0x0500) - -#if (_WIN32_WINNT >= 0x0501) - void Popup() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TTM_POPUP, 0, 0L); - } -#endif // (_WIN32_WINNT >= 0x0501) -}; - -typedef CToolTipCtrlT CToolTipCtrl; - -#endif // !_WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CHeaderCtrl - -template -class CHeaderCtrlT : public TBase -{ -public: -// Constructors - CHeaderCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CHeaderCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return WC_HEADER; - } - - int GetItemCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, HDM_GETITEMCOUNT, 0, 0L); - } - - BOOL GetItem(int nIndex, LPHDITEM pHeaderItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, HDM_GETITEM, nIndex, (LPARAM)pHeaderItem); - } - - BOOL SetItem(int nIndex, LPHDITEM pHeaderItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, HDM_SETITEM, nIndex, (LPARAM)pHeaderItem); - } - - CImageList GetImageList() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, HDM_GETIMAGELIST, 0, 0L)); - } - - CImageList SetImageList(HIMAGELIST hImageList) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, HDM_SETIMAGELIST, 0, (LPARAM)hImageList)); - } - - BOOL GetOrderArray(int nSize, int* lpnArray) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, HDM_GETORDERARRAY, nSize, (LPARAM)lpnArray); - } - - BOOL SetOrderArray(int nSize, int* lpnArray) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, HDM_SETORDERARRAY, nSize, (LPARAM)lpnArray); - } - - BOOL GetItemRect(int nIndex, LPRECT lpItemRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, HDM_GETITEMRECT, nIndex, (LPARAM)lpItemRect); - } - - int SetHotDivider(BOOL bPos, DWORD dwInputValue) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, HDM_SETHOTDIVIDER, bPos, dwInputValue); - } - -#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - BOOL GetUnicodeFormat() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, HDM_GETUNICODEFORMAT, 0, 0L); - } - - BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, HDM_SETUNICODEFORMAT, bUnicode, 0L); - } -#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - -#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - int GetBitmapMargin() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, HDM_GETBITMAPMARGIN, 0, 0L); - } - - int SetBitmapMargin(int nWidth) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, HDM_SETBITMAPMARGIN, nWidth, 0L); - } - - int SetFilterChangeTimeout(DWORD dwTimeOut) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, HDM_SETFILTERCHANGETIMEOUT, 0, dwTimeOut); - } -#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - -#if (_WIN32_WINNT >= 0x0600) - BOOL GetItemDropDownRect(int nIndex, LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, HDM_GETITEMDROPDOWNRECT, nIndex, (LPARAM)lpRect); - } - - BOOL GetOverflowRect(LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, HDM_GETOVERFLOWRECT, 0, (LPARAM)lpRect); - } - - int GetFocusedItem() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, HDM_GETFOCUSEDITEM, 0, 0L); - } - - BOOL SetFocusedItem(int nIndex) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, HDM_SETFOCUSEDITEM, 0, nIndex); - } -#endif // (_WIN32_WINNT >= 0x0600) - -// Operations - int InsertItem(int nIndex, LPHDITEM phdi) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, HDM_INSERTITEM, nIndex, (LPARAM)phdi); - } - - int AddItem(LPHDITEM phdi) - { - return InsertItem(GetItemCount(), phdi); - } - - BOOL DeleteItem(int nIndex) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, HDM_DELETEITEM, nIndex, 0L); - } - - BOOL Layout(HD_LAYOUT* pHeaderLayout) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, HDM_LAYOUT, 0, (LPARAM)pHeaderLayout); - } - - int HitTest(LPHDHITTESTINFO lpHitTestInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, HDM_HITTEST, 0, (LPARAM)lpHitTestInfo); - } - - int OrderToIndex(int nOrder) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, HDM_ORDERTOINDEX, nOrder, 0L); - } - - CImageList CreateDragImage(int nIndex) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, HDM_CREATEDRAGIMAGE, nIndex, 0L)); - } - -#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - int EditFilter(int nColumn, BOOL bDiscardChanges) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, HDM_EDITFILTER, nColumn, MAKELPARAM(bDiscardChanges, 0)); - } - - int ClearFilter(int nColumn) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, HDM_CLEARFILTER, nColumn, 0L); - } - - int ClearAllFilters() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, HDM_CLEARFILTER, (WPARAM)-1, 0L); - } -#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) -}; - -typedef CHeaderCtrlT CHeaderCtrl; - - -/////////////////////////////////////////////////////////////////////////////// -// CListViewCtrl - -template -class CListViewCtrlT : public TBase -{ -public: -// Constructors - CListViewCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CListViewCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return WC_LISTVIEW; - } - - COLORREF GetBkColor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, LVM_GETBKCOLOR, 0, 0L); - } - - BOOL SetBkColor(COLORREF cr) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETBKCOLOR, 0, cr); - } - - CImageList GetImageList(int nImageListType) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, LVM_GETIMAGELIST, nImageListType, 0L)); - } - - CImageList SetImageList(HIMAGELIST hImageList, int nImageList) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, LVM_SETIMAGELIST, nImageList, (LPARAM)hImageList)); - } - - int GetItemCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_GETITEMCOUNT, 0, 0L); - } - - BOOL SetItemCount(int nItems) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMCOUNT, nItems, 0L); - } - - BOOL GetItem(LPLVITEM pItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETITEM, 0, (LPARAM)pItem); - } - - BOOL SetItem(const LVITEM* pItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETITEM, 0, (LPARAM)pItem); - } - - BOOL SetItem(int nItem, int nSubItem, UINT nMask, LPCTSTR lpszItem, - int nImage, UINT nState, UINT nStateMask, LPARAM lParam) - { - ATLASSERT(::IsWindow(m_hWnd)); - LVITEM lvi = { 0 }; - lvi.mask = nMask; - lvi.iItem = nItem; - lvi.iSubItem = nSubItem; - lvi.stateMask = nStateMask; - lvi.state = nState; - lvi.pszText = (LPTSTR) lpszItem; - lvi.iImage = nImage; - lvi.lParam = lParam; - return (BOOL)::SendMessage(m_hWnd, LVM_SETITEM, 0, (LPARAM)&lvi); - } - - UINT GetItemState(int nItem, UINT nMask) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, LVM_GETITEMSTATE, nItem, nMask); - } - - BOOL SetItemState(int nItem, UINT nState, UINT nStateMask) - { - ATLASSERT(::IsWindow(m_hWnd)); - LVITEM lvi = { 0 }; - lvi.state = nState; - lvi.stateMask = nStateMask; - return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMSTATE, nItem, (LPARAM)&lvi); - } - - BOOL SetItemState(int nItem, LPLVITEM pItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMSTATE, nItem, (LPARAM)pItem); - } - -#ifndef _ATL_NO_COM - BOOL GetItemText(int nItem, int nSubItem, BSTR& bstrText) const - { - USES_CONVERSION; - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(bstrText == NULL); - LVITEM lvi = { 0 }; - lvi.iSubItem = nSubItem; - - LPTSTR lpstrText = NULL; - int nRes = 0; - for(int nLen = 256; ; nLen *= 2) - { - ATLTRY(lpstrText = new TCHAR[nLen]); - if(lpstrText == NULL) - break; - lpstrText[0] = NULL; - lvi.cchTextMax = nLen; - lvi.pszText = lpstrText; - nRes = (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem, (LPARAM)&lvi); - if(nRes < nLen - 1) - break; - delete [] lpstrText; - lpstrText = NULL; - } - - if(lpstrText != NULL) - { - if(nRes != 0) - bstrText = ::SysAllocString(T2OLE(lpstrText)); - delete [] lpstrText; - } - - return (bstrText != NULL) ? TRUE : FALSE; - } -#endif // !_ATL_NO_COM - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - int GetItemText(int nItem, int nSubItem, _CSTRING_NS::CString& strText) const - { - ATLASSERT(::IsWindow(m_hWnd)); - LVITEM lvi = { 0 }; - lvi.iSubItem = nSubItem; - - strText.Empty(); - int nRes = 0; - for(int nLen = 256; ; nLen *= 2) - { - lvi.cchTextMax = nLen; - lvi.pszText = strText.GetBufferSetLength(nLen); - if(lvi.pszText == NULL) - { - nRes = 0; - break; - } - nRes = (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem, (LPARAM)&lvi); - if(nRes < nLen - 1) - break; - } - strText.ReleaseBuffer(); - return nRes; - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - - int GetItemText(int nItem, int nSubItem, LPTSTR lpszText, int nLen) const - { - ATLASSERT(::IsWindow(m_hWnd)); - LVITEM lvi = { 0 }; - lvi.iSubItem = nSubItem; - lvi.cchTextMax = nLen; - lvi.pszText = lpszText; - return (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem, (LPARAM)&lvi); - } - - BOOL SetItemText(int nItem, int nSubItem, LPCTSTR lpszText) - { - ATLASSERT(::IsWindow(m_hWnd)); - return SetItem(nItem, nSubItem, LVIF_TEXT, lpszText, 0, 0, 0, 0); - } - - DWORD_PTR GetItemData(int nItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - LVITEM lvi = { 0 }; - lvi.iItem = nItem; - lvi.mask = LVIF_PARAM; - BOOL bRet = (BOOL)::SendMessage(m_hWnd, LVM_GETITEM, 0, (LPARAM)&lvi); - return (DWORD_PTR)(bRet ? lvi.lParam : NULL); - } - - BOOL SetItemData(int nItem, DWORD_PTR dwData) - { - ATLASSERT(::IsWindow(m_hWnd)); - return SetItem(nItem, 0, LVIF_PARAM, NULL, 0, 0, 0, (LPARAM)dwData); - } - - UINT GetCallbackMask() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, LVM_GETCALLBACKMASK, 0, 0L); - } - - BOOL SetCallbackMask(UINT nMask) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETCALLBACKMASK, nMask, 0L); - } - - BOOL GetItemPosition(int nItem, LPPOINT lpPoint) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETITEMPOSITION, nItem, (LPARAM)lpPoint); - } - - BOOL SetItemPosition(int nItem, POINT pt) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(((GetStyle() & LVS_TYPEMASK) == LVS_ICON) || ((GetStyle() & LVS_TYPEMASK) == LVS_SMALLICON)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMPOSITION32, nItem, (LPARAM)&pt); - } - - BOOL SetItemPosition(int nItem, int x, int y) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(((GetStyle() & LVS_TYPEMASK) == LVS_ICON) || ((GetStyle() & LVS_TYPEMASK) == LVS_SMALLICON)); - POINT pt = { x, y }; - return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMPOSITION32, nItem, (LPARAM)&pt); - } - - int GetStringWidth(LPCTSTR lpsz) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_GETSTRINGWIDTH, 0, (LPARAM)lpsz); - } - - CEdit GetEditControl() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CEdit((HWND)::SendMessage(m_hWnd, LVM_GETEDITCONTROL, 0, 0L)); - } - - BOOL GetColumn(int nCol, LVCOLUMN* pColumn) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETCOLUMN, nCol, (LPARAM)pColumn); - } - - BOOL SetColumn(int nCol, const LVCOLUMN* pColumn) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETCOLUMN, nCol, (LPARAM)pColumn); - } - - int GetColumnWidth(int nCol) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_GETCOLUMNWIDTH, nCol, 0L); - } - - BOOL SetColumnWidth(int nCol, int cx) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETCOLUMNWIDTH, nCol, MAKELPARAM(cx, 0)); - } - - BOOL GetViewRect(LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETVIEWRECT, 0, (LPARAM)lpRect); - } - - COLORREF GetTextColor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, LVM_GETTEXTCOLOR, 0, 0L); - } - - BOOL SetTextColor(COLORREF cr) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETTEXTCOLOR, 0, cr); - } - - COLORREF GetTextBkColor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, LVM_GETTEXTBKCOLOR, 0, 0L); - } - - BOOL SetTextBkColor(COLORREF cr) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETTEXTBKCOLOR, 0, cr); - } - - int GetTopIndex() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_GETTOPINDEX, 0, 0L); - } - - int GetCountPerPage() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_GETCOUNTPERPAGE, 0, 0L); - } - - BOOL GetOrigin(LPPOINT lpPoint) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETORIGIN, 0, (LPARAM)lpPoint); - } - - UINT GetSelectedCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, LVM_GETSELECTEDCOUNT, 0, 0L); - } - - BOOL GetItemRect(int nItem, LPRECT lpRect, UINT nCode) const - { - ATLASSERT(::IsWindow(m_hWnd)); - lpRect->left = nCode; - return (BOOL)::SendMessage(m_hWnd, LVM_GETITEMRECT, (WPARAM)nItem, (LPARAM)lpRect); - } - -#ifndef _WIN32_WCE - HCURSOR GetHotCursor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HCURSOR)::SendMessage(m_hWnd, LVM_GETHOTCURSOR, 0, 0L); - } - - HCURSOR SetHotCursor(HCURSOR hHotCursor) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HCURSOR)::SendMessage(m_hWnd, LVM_SETHOTCURSOR, 0, (LPARAM)hHotCursor); - } - - int GetHotItem() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_GETHOTITEM, 0, 0L); - } - - int SetHotItem(int nIndex) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_SETHOTITEM, nIndex, 0L); - } -#endif // !_WIN32_WCE - - BOOL GetColumnOrderArray(int nCount, int* lpnArray) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETCOLUMNORDERARRAY, nCount, (LPARAM)lpnArray); - } - - BOOL SetColumnOrderArray(int nCount, int* lpnArray) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETCOLUMNORDERARRAY, nCount, (LPARAM)lpnArray); - } - - CHeaderCtrl GetHeader() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CHeaderCtrl((HWND)::SendMessage(m_hWnd, LVM_GETHEADER, 0, 0L)); - } - - BOOL GetSubItemRect(int nItem, int nSubItem, int nFlag, LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & LVS_TYPEMASK) == LVS_REPORT); - ATLASSERT(lpRect != NULL); - lpRect->top = nSubItem; - lpRect->left = nFlag; - return (BOOL)::SendMessage(m_hWnd, LVM_GETSUBITEMRECT, nItem, (LPARAM)lpRect); - } - - DWORD SetIconSpacing(int cx, int cy) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & LVS_TYPEMASK) == LVS_ICON); - return (DWORD)::SendMessage(m_hWnd, LVM_SETICONSPACING, 0, MAKELPARAM(cx, cy)); - } - - int GetISearchString(LPTSTR lpstr) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_GETISEARCHSTRING, 0, (LPARAM)lpstr); - } - - void GetItemSpacing(SIZE& sizeSpacing, BOOL bSmallIconView = FALSE) const - { - ATLASSERT(::IsWindow(m_hWnd)); - DWORD dwRet = (DWORD)::SendMessage(m_hWnd, LVM_GETITEMSPACING, bSmallIconView, 0L); - sizeSpacing.cx = GET_X_LPARAM(dwRet); - sizeSpacing.cy = GET_Y_LPARAM(dwRet); - } - -#if (_WIN32_WCE >= 410) - void SetItemSpacing(INT cySpacing) - { - ATLASSERT(::IsWindow(m_hWnd)); - ListView_SetItemSpacing(m_hWnd, cySpacing); - } -#endif // (_WIN32_WCE >= 410) - - // single-selection only - int GetSelectedIndex() const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & LVS_SINGLESEL) != 0); - return (int)::SendMessage(m_hWnd, LVM_GETNEXTITEM, (WPARAM)-1, MAKELPARAM(LVNI_ALL | LVNI_SELECTED, 0)); - } - - BOOL GetSelectedItem(LPLVITEM pItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & LVS_SINGLESEL) != 0); - ATLASSERT(pItem != NULL); - pItem->iItem = (int)::SendMessage(m_hWnd, LVM_GETNEXTITEM, (WPARAM)-1, MAKELPARAM(LVNI_ALL | LVNI_SELECTED, 0)); - if(pItem->iItem == -1) - return FALSE; - return (BOOL)::SendMessage(m_hWnd, LVM_GETITEM, 0, (LPARAM)pItem); - } - - // extended list view styles - DWORD GetExtendedListViewStyle() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0L); - } - - // dwExMask = 0 means all styles - DWORD SetExtendedListViewStyle(DWORD dwExStyle, DWORD dwExMask = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE, dwExMask, dwExStyle); - } - - // checkboxes only - BOOL GetCheckState(int nIndex) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetExtendedListViewStyle() & LVS_EX_CHECKBOXES) != 0); - UINT uRet = GetItemState(nIndex, LVIS_STATEIMAGEMASK); - return (uRet >> 12) - 1; - } - - BOOL SetCheckState(int nItem, BOOL bCheck) - { - int nCheck = bCheck ? 2 : 1; // one based index - return SetItemState(nItem, INDEXTOSTATEIMAGEMASK(nCheck), LVIS_STATEIMAGEMASK); - } - - // view type - DWORD GetViewType() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (GetStyle() & LVS_TYPEMASK); - } - - DWORD SetViewType(DWORD dwType) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(dwType == LVS_ICON || dwType == LVS_SMALLICON || dwType == LVS_LIST || dwType == LVS_REPORT); - DWORD dwOldType = GetViewType(); - if(dwType != dwOldType) - ModifyStyle(LVS_TYPEMASK, (dwType & LVS_TYPEMASK)); - return dwOldType; - } - -#if (_WIN32_IE >= 0x0400) -#ifndef _WIN32_WCE - BOOL GetBkImage(LPLVBKIMAGE plvbki) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETBKIMAGE, 0, (LPARAM)plvbki); - } - - BOOL SetBkImage(LPLVBKIMAGE plvbki) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETBKIMAGE, 0, (LPARAM)plvbki); - } -#endif // !_WIN32_WCE - - int GetSelectionMark() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_GETSELECTIONMARK, 0, 0L); - } - - int SetSelectionMark(int nIndex) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_SETSELECTIONMARK, 0, nIndex); - } - -#ifndef _WIN32_WCE - BOOL GetWorkAreas(int nWorkAreas, LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETWORKAREAS, nWorkAreas, (LPARAM)lpRect); - } - - BOOL SetWorkAreas(int nWorkAreas, LPRECT lpRect) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETWORKAREAS, nWorkAreas, (LPARAM)lpRect); - } - - DWORD GetHoverTime() const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetExtendedListViewStyle() & (LVS_EX_TRACKSELECT | LVS_EX_ONECLICKACTIVATE | LVS_EX_TWOCLICKACTIVATE)) != 0); - return (DWORD)::SendMessage(m_hWnd, LVM_GETHOVERTIME, 0, 0L); - } - - DWORD SetHoverTime(DWORD dwHoverTime) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetExtendedListViewStyle() & (LVS_EX_TRACKSELECT | LVS_EX_ONECLICKACTIVATE | LVS_EX_TWOCLICKACTIVATE)) != 0); - return (DWORD)::SendMessage(m_hWnd, LVM_SETHOVERTIME, 0, dwHoverTime); - } - - BOOL GetNumberOfWorkAreas(int* pnWorkAreas) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETNUMBEROFWORKAREAS, 0, (LPARAM)pnWorkAreas); - } -#endif // !_WIN32_WCE - - BOOL SetItemCountEx(int nItems, DWORD dwFlags) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(((GetStyle() & LVS_OWNERDATA) != 0) && (((GetStyle() & LVS_TYPEMASK) == LVS_REPORT) || ((GetStyle() & LVS_TYPEMASK) == LVS_LIST))); - return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMCOUNT, nItems, dwFlags); - } - -#ifndef _WIN32_WCE - CToolTipCtrl GetToolTips() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CToolTipCtrl((HWND)::SendMessage(m_hWnd, LVM_GETTOOLTIPS, 0, 0L)); - } - - CToolTipCtrl SetToolTips(HWND hWndTT) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CToolTipCtrl((HWND)::SendMessage(m_hWnd, LVM_SETTOOLTIPS, (WPARAM)hWndTT, 0L)); - } - - BOOL GetUnicodeFormat() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETUNICODEFORMAT, 0, 0L); - } - - BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETUNICODEFORMAT, bUnicode, 0L); - } -#endif // !_WIN32_WCE -#endif // (_WIN32_IE >= 0x0400) - -#if (_WIN32_WINNT >= 0x0501) - int GetSelectedColumn() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_GETSELECTEDCOLUMN, 0, 0L); - } - - void SetSelectedColumn(int nColumn) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, LVM_SETSELECTEDCOLUMN, nColumn, 0L); - } - - DWORD GetView() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, LVM_GETVIEW, 0, 0L); - } - - int SetView(DWORD dwView) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_SETVIEW, dwView, 0L); - } - - BOOL IsGroupViewEnabled() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_ISGROUPVIEWENABLED, 0, 0L); - } - - int GetGroupInfo(int nGroupID, PLVGROUP pGroup) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_GETGROUPINFO, nGroupID, (LPARAM)pGroup); - } - - int SetGroupInfo(int nGroupID, PLVGROUP pGroup) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_SETGROUPINFO, nGroupID, (LPARAM)pGroup); - } - - void GetGroupMetrics(PLVGROUPMETRICS pGroupMetrics) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, LVM_GETGROUPMETRICS, 0, (LPARAM)pGroupMetrics); - } - - void SetGroupMetrics(PLVGROUPMETRICS pGroupMetrics) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, LVM_SETGROUPMETRICS, 0, (LPARAM)pGroupMetrics); - } - - void GetTileViewInfo(PLVTILEVIEWINFO pTileViewInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, LVM_GETTILEVIEWINFO, 0, (LPARAM)pTileViewInfo); - } - - BOOL SetTileViewInfo(PLVTILEVIEWINFO pTileViewInfo) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETTILEVIEWINFO, 0, (LPARAM)pTileViewInfo); - } - - void GetTileInfo(PLVTILEINFO pTileInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, LVM_GETTILEINFO, 0, (LPARAM)pTileInfo); - } - - BOOL SetTileInfo(PLVTILEINFO pTileInfo) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETTILEINFO, 0, (LPARAM)pTileInfo); - } - - BOOL GetInsertMark(LPLVINSERTMARK pInsertMark) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETINSERTMARK, 0, (LPARAM)pInsertMark); - } - - BOOL SetInsertMark(LPLVINSERTMARK pInsertMark) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETINSERTMARK, 0, (LPARAM)pInsertMark); - } - - int GetInsertMarkRect(LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_GETINSERTMARKRECT, 0, (LPARAM)lpRect); - } - - COLORREF GetInsertMarkColor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, LVM_GETINSERTMARKCOLOR, 0, 0L); - } - - COLORREF SetInsertMarkColor(COLORREF clr) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, LVM_SETINSERTMARKCOLOR, 0, clr); - } - - COLORREF GetOutlineColor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, LVM_GETOUTLINECOLOR, 0, 0L); - } - - COLORREF SetOutlineColor(COLORREF clr) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, LVM_SETOUTLINECOLOR, 0, clr); - } -#endif // (_WIN32_WINNT >= 0x0501) - -#if (_WIN32_WINNT >= 0x0600) - int GetGroupCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_GETGROUPCOUNT, 0, 0L); - } - - BOOL GetGroupInfoByIndex(int nIndex, PLVGROUP pGroup) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETGROUPINFOBYINDEX, nIndex, (LPARAM)pGroup); - } - - BOOL GetGroupRect(int nGroupID, int nType, LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(lpRect != NULL); - if(lpRect != NULL) - lpRect->top = nType; - return (BOOL)::SendMessage(m_hWnd, LVM_GETGROUPRECT, nGroupID, (LPARAM)lpRect); - } - - UINT GetGroupState(int nGroupID, UINT uMask) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, LVM_GETGROUPSTATE, nGroupID, (LPARAM)uMask); - } - - int GetFocusedGroup() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_GETFOCUSEDGROUP, 0, 0L); - } - - BOOL GetEmptyText(LPWSTR lpstrText, int cchText) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETEMPTYTEXT, cchText, (LPARAM)lpstrText); - } - - BOOL GetFooterRect(LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETFOOTERRECT, 0, (LPARAM)lpRect); - } - - BOOL GetFooterInfo(LPLVFOOTERINFO lpFooterInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETFOOTERINFO, 0, (LPARAM)lpFooterInfo); - } - - BOOL GetFooterItemRect(int nItem, LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETFOOTERITEMRECT, nItem, (LPARAM)lpRect); - } - - BOOL GetFooterItem(int nItem, LPLVFOOTERITEM lpFooterItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETFOOTERITEM, nItem, (LPARAM)lpFooterItem); - } - - BOOL GetItemIndexRect(PLVITEMINDEX pItemIndex, int nSubItem, int nType, LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pItemIndex != NULL); - ATLASSERT(lpRect != NULL); - if(lpRect != NULL) - { - lpRect->top = nSubItem; - lpRect->left = nType; - } - return (BOOL)::SendMessage(m_hWnd, LVM_GETITEMINDEXRECT, (WPARAM)pItemIndex, (LPARAM)lpRect); - } - - BOOL SetItemIndexState(PLVITEMINDEX pItemIndex, UINT uState, UINT dwMask) - { - ATLASSERT(::IsWindow(m_hWnd)); - LVITEM lvi = { 0 }; - lvi.state = uState; - lvi.stateMask = dwMask; - return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMINDEXSTATE, (WPARAM)pItemIndex, (LPARAM)&lvi); - } - - BOOL GetNextItemIndex(PLVITEMINDEX pItemIndex, WORD wFlags) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_GETNEXTITEMINDEX, (WPARAM)pItemIndex, MAKELPARAM(wFlags, 0)); - } -#endif // (_WIN32_WINNT >= 0x0600) - -// Operations - int InsertColumn(int nCol, const LVCOLUMN* pColumn) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_INSERTCOLUMN, nCol, (LPARAM)pColumn); - } - - int InsertColumn(int nCol, LPCTSTR lpszColumnHeading, int nFormat = LVCFMT_LEFT, - int nWidth = -1, int nSubItem = -1, int iImage = -1, int iOrder = -1) - { - LVCOLUMN column = { 0 }; - column.mask = LVCF_TEXT|LVCF_FMT; - column.pszText = (LPTSTR)lpszColumnHeading; - column.fmt = nFormat; - if (nWidth != -1) - { - column.mask |= LVCF_WIDTH; - column.cx = nWidth; - } - if (nSubItem != -1) - { - column.mask |= LVCF_SUBITEM; - column.iSubItem = nSubItem; - } - if (iImage != -1) - { - column.mask |= LVCF_IMAGE; - column.iImage = iImage; - } - if (iOrder != -1) - { - column.mask |= LVCF_ORDER; - column.iOrder = iOrder; - } - return InsertColumn(nCol, &column); - } - - BOOL DeleteColumn(int nCol) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_DELETECOLUMN, nCol, 0L); - } - - int InsertItem(UINT nMask, int nItem, LPCTSTR lpszItem, UINT nState, UINT nStateMask, int nImage, LPARAM lParam) - { - ATLASSERT(::IsWindow(m_hWnd)); - LVITEM item = { 0 }; - item.mask = nMask; - item.iItem = nItem; - item.iSubItem = 0; - item.pszText = (LPTSTR)lpszItem; - item.state = nState; - item.stateMask = nStateMask; - item.iImage = nImage; - item.lParam = lParam; - return InsertItem(&item); - } - - int InsertItem(const LVITEM* pItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_INSERTITEM, 0, (LPARAM)pItem); - } - - int InsertItem(int nItem, LPCTSTR lpszItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return InsertItem(LVIF_TEXT, nItem, lpszItem, 0, 0, 0, 0); - } - - int InsertItem(int nItem, LPCTSTR lpszItem, int nImage) - { - ATLASSERT(::IsWindow(m_hWnd)); - return InsertItem(LVIF_TEXT|LVIF_IMAGE, nItem, lpszItem, 0, 0, nImage, 0); - } - - int GetNextItem(int nItem, int nFlags) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_GETNEXTITEM, nItem, MAKELPARAM(nFlags, 0)); - } - - BOOL DeleteItem(int nItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_DELETEITEM, nItem, 0L); - } - - BOOL DeleteAllItems() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_DELETEALLITEMS, 0, 0L); - } - - int FindItem(LVFINDINFO* pFindInfo, int nStart) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_FINDITEM, nStart, (LPARAM)pFindInfo); - } - - int HitTest(LVHITTESTINFO* pHitTestInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_HITTEST, 0, (LPARAM)pHitTestInfo); - } - - int HitTest(POINT pt, UINT* pFlags) const - { - ATLASSERT(::IsWindow(m_hWnd)); - LVHITTESTINFO hti = { 0 }; - hti.pt = pt; - int nRes = (int)::SendMessage(m_hWnd, LVM_HITTEST, 0, (LPARAM)&hti); - if (pFlags != NULL) - *pFlags = hti.flags; - return nRes; - } - - BOOL EnsureVisible(int nItem, BOOL bPartialOK) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_ENSUREVISIBLE, nItem, MAKELPARAM(bPartialOK, 0)); - } - - BOOL Scroll(SIZE size) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SCROLL, size.cx, size.cy); - } - - BOOL RedrawItems(int nFirst, int nLast) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_REDRAWITEMS, nFirst, nLast); - } - - BOOL Arrange(UINT nCode) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_ARRANGE, nCode, 0L); - } - - CEdit EditLabel(int nItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CEdit((HWND)::SendMessage(m_hWnd, LVM_EDITLABEL, nItem, 0L)); - } - - BOOL Update(int nItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_UPDATE, nItem, 0L); - } - - BOOL SortItems(PFNLVCOMPARE pfnCompare, LPARAM lParamSort) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SORTITEMS, (WPARAM)lParamSort, (LPARAM)pfnCompare); - } - - CImageList RemoveImageList(int nImageList) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, LVM_SETIMAGELIST, (WPARAM)nImageList, NULL)); - } - - CImageList CreateDragImage(int nItem, LPPOINT lpPoint) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, LVM_CREATEDRAGIMAGE, nItem, (LPARAM)lpPoint)); - } - - DWORD ApproximateViewRect(int cx = -1, int cy = -1, int nCount = -1) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, LVM_APPROXIMATEVIEWRECT, nCount, MAKELPARAM(cx, cy)); - } - - int SubItemHitTest(LPLVHITTESTINFO lpInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_SUBITEMHITTEST, 0, (LPARAM)lpInfo); - } - - int AddColumn(LPCTSTR strItem, int nItem, int nSubItem = -1, - int nMask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM, - int nFmt = LVCFMT_LEFT) - { - const int cxOffset = 15; - ATLASSERT(::IsWindow(m_hWnd)); - LVCOLUMN lvc = { 0 }; - lvc.mask = nMask; - lvc.fmt = nFmt; - lvc.pszText = (LPTSTR)strItem; - lvc.cx = GetStringWidth(lvc.pszText) + cxOffset; - if(nMask & LVCF_SUBITEM) - lvc.iSubItem = (nSubItem != -1) ? nSubItem : nItem; - return InsertColumn(nItem, &lvc); - } - - int AddItem(int nItem, int nSubItem, LPCTSTR strItem, int nImageIndex = -1) - { - ATLASSERT(::IsWindow(m_hWnd)); - LVITEM lvItem = { 0 }; - lvItem.mask = LVIF_TEXT; - lvItem.iItem = nItem; - lvItem.iSubItem = nSubItem; - lvItem.pszText = (LPTSTR)strItem; - if(nImageIndex != -1) - { - lvItem.mask |= LVIF_IMAGE; - lvItem.iImage = nImageIndex; - } - if(nSubItem == 0) - return InsertItem(&lvItem); - return SetItem(&lvItem) ? nItem : -1; - } - -#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - BOOL SortItemsEx(PFNLVCOMPARE pfnCompare, LPARAM lParamSort) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SORTITEMSEX, (WPARAM)lParamSort, (LPARAM)pfnCompare); - } -#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - -#if (_WIN32_WINNT >= 0x0501) - int InsertGroup(int nItem, PLVGROUP pGroup) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_INSERTGROUP, nItem, (LPARAM)pGroup); - } - - int AddGroup(PLVGROUP pGroup) - { - return InsertGroup(-1, pGroup); - } - - int RemoveGroup(int nGroupID) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_REMOVEGROUP, nGroupID, 0L); - } - - void MoveGroup(int nGroupID, int nItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, LVM_MOVEGROUP, nGroupID, nItem); - } - - void MoveItemToGroup(int nItem, int nGroupID) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, LVM_MOVEITEMTOGROUP, nItem, nGroupID); - } - - int EnableGroupView(BOOL bEnable) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_ENABLEGROUPVIEW, bEnable, 0L); - } - - int SortGroups(PFNLVGROUPCOMPARE pCompareFunc, LPVOID lpVoid = NULL) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_SORTGROUPS, (WPARAM)pCompareFunc, (LPARAM)lpVoid); - } - - void InsertGroupSorted(PLVINSERTGROUPSORTED pInsertGroupSorted) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, LVM_INSERTGROUPSORTED, (WPARAM)pInsertGroupSorted, 0L); - } - - void RemoveAllGroups() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, LVM_REMOVEALLGROUPS, 0, 0L); - } - - BOOL HasGroup(int nGroupID) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_HASGROUP, nGroupID, 0L); - } - - BOOL InsertMarkHitTest(LPPOINT lpPoint, LPLVINSERTMARK pInsertMark) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_INSERTMARKHITTEST, (WPARAM)lpPoint, (LPARAM)pInsertMark); - } - - BOOL SetInfoTip(PLVSETINFOTIP pSetInfoTip) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LVM_SETINFOTIP, 0, (LPARAM)pSetInfoTip); - } - - void CancelEditLabel() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, LVM_CANCELEDITLABEL, 0, 0L); - } - - UINT MapIndexToID(int nIndex) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, LVM_MAPINDEXTOID, nIndex, 0L); - } - - int MapIDToIndex(UINT uID) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_MAPIDTOINDEX, uID, 0L); - } -#endif // (_WIN32_WINNT >= 0x0501) - -#if (_WIN32_WINNT >= 0x0600) - int HitTestEx(LPLVHITTESTINFO lpHitTestInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_HITTEST, (WPARAM)-1, (LPARAM)lpHitTestInfo); - } - - int HitTestEx(POINT pt, UINT* pFlags) const - { - ATLASSERT(::IsWindow(m_hWnd)); - LVHITTESTINFO hti = { 0 }; - hti.pt = pt; - int nRes = (int)::SendMessage(m_hWnd, LVM_HITTEST, (WPARAM)-1, (LPARAM)&hti); - if (pFlags != NULL) - *pFlags = hti.flags; - return nRes; - } - - int SubItemHitTestEx(LPLVHITTESTINFO lpHitTestInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LVM_SUBITEMHITTEST, (WPARAM)-1, (LPARAM)lpHitTestInfo); - } -#endif // (_WIN32_WINNT >= 0x0600) - - // Note: selects only one item - BOOL SelectItem(int nIndex) - { - ATLASSERT(::IsWindow(m_hWnd)); - - // multi-selection only: de-select all items - if((GetStyle() & LVS_SINGLESEL) == 0) - SetItemState(-1, 0, LVIS_SELECTED); - - BOOL bRet = SetItemState(nIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); - if(bRet) - bRet = EnsureVisible(nIndex, FALSE); - - return bRet; - } -}; - -typedef CListViewCtrlT CListViewCtrl; - - -/////////////////////////////////////////////////////////////////////////////// -// CTreeViewCtrl - -template -class CTreeViewCtrlT : public TBase -{ -public: -// Constructors - CTreeViewCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CTreeViewCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return WC_TREEVIEW; - } - - UINT GetCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, TVM_GETCOUNT, 0, 0L); - } - - UINT GetIndent() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, TVM_GETINDENT, 0, 0L); - } - - void SetIndent(UINT nIndent) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TVM_SETINDENT, nIndent, 0L); - } - - CImageList GetImageList(int nImageListType = TVSIL_NORMAL) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TVM_GETIMAGELIST, (WPARAM)nImageListType, 0L)); - } - - CImageList SetImageList(HIMAGELIST hImageList, int nImageListType = TVSIL_NORMAL) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TVM_SETIMAGELIST, (WPARAM)nImageListType, (LPARAM)hImageList)); - } - - BOOL GetItem(LPTVITEM pItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)pItem); - } - - BOOL SetItem(LPTVITEM pItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)pItem); - } - - BOOL SetItem(HTREEITEM hItem, UINT nMask, LPCTSTR lpszItem, int nImage, - int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam) - { - ATLASSERT(::IsWindow(m_hWnd)); - TVITEM item = { 0 }; - item.hItem = hItem; - item.mask = nMask; - item.pszText = (LPTSTR) lpszItem; - item.iImage = nImage; - item.iSelectedImage = nSelectedImage; - item.state = nState; - item.stateMask = nStateMask; - item.lParam = lParam; - return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)&item); - } - - BOOL GetItemText(HTREEITEM hItem, LPTSTR lpstrText, int nLen) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(lpstrText != NULL); - - TVITEM item = { 0 }; - item.hItem = hItem; - item.mask = TVIF_TEXT; - item.pszText = lpstrText; - item.cchTextMax = nLen; - - return (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); - } - -#ifndef _ATL_NO_COM - BOOL GetItemText(HTREEITEM hItem, BSTR& bstrText) const - { - USES_CONVERSION; - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(bstrText == NULL); - TVITEM item = { 0 }; - item.hItem = hItem; - item.mask = TVIF_TEXT; - - LPTSTR lpstrText = NULL; - BOOL bRet = FALSE; - for(int nLen = 256; ; nLen *= 2) - { - ATLTRY(lpstrText = new TCHAR[nLen]); - if(lpstrText == NULL) - break; - lpstrText[0] = NULL; - item.pszText = lpstrText; - item.cchTextMax = nLen; - bRet = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); - if(!bRet || (lstrlen(item.pszText) < nLen - 1)) - break; - delete [] lpstrText; - lpstrText = NULL; - } - - if(lpstrText != NULL) - { - if(bRet) - bstrText = ::SysAllocString(T2OLE(lpstrText)); - delete [] lpstrText; - } - - return (bstrText != NULL) ? TRUE : FALSE; - } -#endif // !_ATL_NO_COM - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - BOOL GetItemText(HTREEITEM hItem, _CSTRING_NS::CString& strText) const - { - ATLASSERT(::IsWindow(m_hWnd)); - TVITEM item = { 0 }; - item.hItem = hItem; - item.mask = TVIF_TEXT; - - strText.Empty(); - BOOL bRet = FALSE; - for(int nLen = 256; ; nLen *= 2) - { - item.pszText = strText.GetBufferSetLength(nLen); - if(item.pszText == NULL) - { - bRet = FALSE; - break; - } - item.cchTextMax = nLen; - bRet = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); - if(!bRet || (lstrlen(item.pszText) < nLen - 1)) - break; - } - strText.ReleaseBuffer(); - return bRet; - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - - BOOL SetItemText(HTREEITEM hItem, LPCTSTR lpszItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return SetItem(hItem, TVIF_TEXT, lpszItem, 0, 0, 0, 0, NULL); - } - - BOOL GetItemImage(HTREEITEM hItem, int& nImage, int& nSelectedImage) const - { - ATLASSERT(::IsWindow(m_hWnd)); - TVITEM item = { 0 }; - item.hItem = hItem; - item.mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE; - BOOL bRes = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); - if (bRes) - { - nImage = item.iImage; - nSelectedImage = item.iSelectedImage; - } - return bRes; - } - - BOOL SetItemImage(HTREEITEM hItem, int nImage, int nSelectedImage) - { - ATLASSERT(::IsWindow(m_hWnd)); - return SetItem(hItem, TVIF_IMAGE|TVIF_SELECTEDIMAGE, NULL, nImage, nSelectedImage, 0, 0, NULL); - } - - UINT GetItemState(HTREEITEM hItem, UINT nStateMask) const - { - ATLASSERT(::IsWindow(m_hWnd)); -#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - return (((UINT)::SendMessage(m_hWnd, TVM_GETITEMSTATE, (WPARAM)hItem, (LPARAM)nStateMask)) & nStateMask); -#else // !((_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)) - TVITEM item = { 0 }; - item.hItem = hItem; - item.mask = TVIF_STATE; - item.state = 0; - item.stateMask = nStateMask; - ::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); - return (item.state & nStateMask); -#endif // !((_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)) - } - - BOOL SetItemState(HTREEITEM hItem, UINT nState, UINT nStateMask) - { - ATLASSERT(::IsWindow(m_hWnd)); - return SetItem(hItem, TVIF_STATE, NULL, 0, 0, nState, nStateMask, NULL); - } - - DWORD_PTR GetItemData(HTREEITEM hItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - TVITEM item = { 0 }; - item.hItem = hItem; - item.mask = TVIF_PARAM; - BOOL bRet = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); - return (DWORD_PTR)(bRet ? item.lParam : NULL); - } - - BOOL SetItemData(HTREEITEM hItem, DWORD_PTR dwData) - { - ATLASSERT(::IsWindow(m_hWnd)); - return SetItem(hItem, TVIF_PARAM, NULL, 0, 0, 0, 0, (LPARAM)dwData); - } - - CEdit GetEditControl() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CEdit((HWND)::SendMessage(m_hWnd, TVM_GETEDITCONTROL, 0, 0L)); - } - - UINT GetVisibleCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, TVM_GETVISIBLECOUNT, 0, 0L); - } - - BOOL GetItemRect(HTREEITEM hItem, LPRECT lpRect, BOOL bTextOnly) const - { - ATLASSERT(::IsWindow(m_hWnd)); - *(HTREEITEM*)lpRect = hItem; - return (BOOL)::SendMessage(m_hWnd, TVM_GETITEMRECT, (WPARAM)bTextOnly, (LPARAM)lpRect); - } - - BOOL ItemHasChildren(HTREEITEM hItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - TVITEM item = { 0 }; - item.hItem = hItem; - item.mask = TVIF_CHILDREN; - ::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); - return item.cChildren; - } - -#ifndef _WIN32_WCE - CToolTipCtrl GetToolTips() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TVM_GETTOOLTIPS, 0, 0L)); - } - - CToolTipCtrl SetToolTips(HWND hWndTT) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TVM_SETTOOLTIPS, (WPARAM)hWndTT, 0L)); - } -#endif // !_WIN32_WCE - - int GetISearchString(LPTSTR lpstr) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TVM_GETISEARCHSTRING, 0, (LPARAM)lpstr); - } - - // checkboxes only - BOOL GetCheckState(HTREEITEM hItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & TVS_CHECKBOXES) != 0); - UINT uRet = GetItemState(hItem, TVIS_STATEIMAGEMASK); - return (uRet >> 12) - 1; - } - - BOOL SetCheckState(HTREEITEM hItem, BOOL bCheck) - { - int nCheck = bCheck ? 2 : 1; // one based index - return SetItemState(hItem, INDEXTOSTATEIMAGEMASK(nCheck), TVIS_STATEIMAGEMASK); - } - -#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - COLORREF GetBkColor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, TVM_GETBKCOLOR, 0, 0L); - } - - COLORREF SetBkColor(COLORREF clr) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, TVM_SETBKCOLOR, 0, (LPARAM)clr); - } - - COLORREF GetInsertMarkColor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, TVM_GETINSERTMARKCOLOR, 0, 0L); - } - - COLORREF SetInsertMarkColor(COLORREF clr) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, TVM_SETINSERTMARKCOLOR, 0, (LPARAM)clr); - } - - int GetItemHeight() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TVM_GETITEMHEIGHT, 0, 0L); - } - - int SetItemHeight(int cyHeight) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TVM_SETITEMHEIGHT, cyHeight, 0L); - } - - int GetScrollTime() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TVM_GETSCROLLTIME, 0, 0L); - } - - int SetScrollTime(int nScrollTime) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TVM_SETSCROLLTIME, nScrollTime, 0L); - } - - COLORREF GetTextColor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, TVM_GETTEXTCOLOR, 0, 0L); - } - - COLORREF SetTextColor(COLORREF clr) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, TVM_SETTEXTCOLOR, 0, (LPARAM)clr); - } - - BOOL GetUnicodeFormat() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_GETUNICODEFORMAT, 0, 0L); - } - - BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_SETUNICODEFORMAT, bUnicode, 0L); - } -#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - -#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - COLORREF GetLineColor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, TVM_GETLINECOLOR, 0, 0L); - } - - COLORREF SetLineColor(COLORREF clrNew /*= CLR_DEFAULT*/) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, TVM_SETLINECOLOR, 0, (LPARAM)clrNew); - } -#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - -#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - BOOL GetItem(LPTVITEMEX pItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)pItem); - } - - BOOL SetItem(LPTVITEMEX pItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)pItem); - } -#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - - DWORD GetExtendedStyle() const - { -#ifndef TVM_GETEXTENDEDSTYLE - const UINT TVM_GETEXTENDEDSTYLE = (TV_FIRST + 45); -#endif - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, TVM_GETEXTENDEDSTYLE, 0, 0L); - } - - DWORD SetExtendedStyle(DWORD dwStyle, DWORD dwMask) - { -#ifndef TVM_SETEXTENDEDSTYLE - const UINT TVM_SETEXTENDEDSTYLE = (TV_FIRST + 44); -#endif - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, TVM_SETEXTENDEDSTYLE, dwMask, dwStyle); - } - -#if (_WIN32_WINNT >= 0x0600) - BOOL SetAutoScrollInfo(UINT uPixPerSec, UINT uUpdateTime) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_SETAUTOSCROLLINFO, (WPARAM)uPixPerSec, (LPARAM)uUpdateTime); - } - - DWORD GetSelectedCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, TVM_GETSELECTEDCOUNT, 0, 0L); - } - - BOOL GetItemPartRect(HTREEITEM hItem, TVITEMPART partID, LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - TVGETITEMPARTRECTINFO gipri = { hItem, lpRect, partID }; - return (BOOL)::SendMessage(m_hWnd, TVM_GETITEMPARTRECT, 0, (LPARAM)&gipri); - } -#endif // (_WIN32_WINNT >= 0x0600) - -// Operations - HTREEITEM InsertItem(LPTVINSERTSTRUCT lpInsertStruct) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)lpInsertStruct); - } - - HTREEITEM InsertItem(LPCTSTR lpszItem, int nImage, - int nSelectedImage, HTREEITEM hParent, HTREEITEM hInsertAfter) - { - ATLASSERT(::IsWindow(m_hWnd)); - return InsertItem(TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE, lpszItem, nImage, nSelectedImage, 0, 0, 0, hParent, hInsertAfter); - } - - HTREEITEM InsertItem(LPCTSTR lpszItem, HTREEITEM hParent, HTREEITEM hInsertAfter) - { - ATLASSERT(::IsWindow(m_hWnd)); - return InsertItem(TVIF_TEXT, lpszItem, 0, 0, 0, 0, 0, hParent, hInsertAfter); - } - - HTREEITEM InsertItem(UINT nMask, LPCTSTR lpszItem, int nImage, - int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam, - HTREEITEM hParent, HTREEITEM hInsertAfter) - { - ATLASSERT(::IsWindow(m_hWnd)); - TVINSERTSTRUCT tvis = { 0 }; - tvis.hParent = hParent; - tvis.hInsertAfter = hInsertAfter; - tvis.item.mask = nMask; - tvis.item.pszText = (LPTSTR) lpszItem; - tvis.item.iImage = nImage; - tvis.item.iSelectedImage = nSelectedImage; - tvis.item.state = nState; - tvis.item.stateMask = nStateMask; - tvis.item.lParam = lParam; - return (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)&tvis); - } - - BOOL DeleteItem(HTREEITEM hItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_DELETEITEM, 0, (LPARAM)hItem); - } - - BOOL DeleteAllItems() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT); - } - - BOOL Expand(HTREEITEM hItem, UINT nCode = TVE_EXPAND) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_EXPAND, nCode, (LPARAM)hItem); - } - - HTREEITEM GetNextItem(HTREEITEM hItem, UINT nCode) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, nCode, (LPARAM)hItem); - } - - HTREEITEM GetChildItem(HTREEITEM hItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem); - } - - HTREEITEM GetNextSiblingItem(HTREEITEM hItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem); - } - - HTREEITEM GetPrevSiblingItem(HTREEITEM hItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PREVIOUS, (LPARAM)hItem); - } - - HTREEITEM GetParentItem(HTREEITEM hItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItem); - } - - HTREEITEM GetFirstVisibleItem() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_FIRSTVISIBLE, 0L); - } - - HTREEITEM GetNextVisibleItem(HTREEITEM hItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, (LPARAM)hItem); - } - - HTREEITEM GetPrevVisibleItem(HTREEITEM hItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PREVIOUSVISIBLE, (LPARAM)hItem); - } - - HTREEITEM GetSelectedItem() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CARET, 0L); - } - - HTREEITEM GetDropHilightItem() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_DROPHILITE, 0L); - } - - HTREEITEM GetRootItem() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_ROOT, 0L); - } - -#if !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) - HTREEITEM GetLastVisibleItem() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_LASTVISIBLE, 0L); - } -#endif // !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) - -#if (_WIN32_IE >= 0x0600) - HTREEITEM GetNextSelectedItem() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXTSELECTED, 0L); - } -#endif // (_WIN32_IE >= 0x0600) - - BOOL Select(HTREEITEM hItem, UINT nCode) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_SELECTITEM, nCode, (LPARAM)hItem); - } - - BOOL SelectItem(HTREEITEM hItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hItem); - } - - BOOL SelectDropTarget(HTREEITEM hItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_SELECTITEM, TVGN_DROPHILITE, (LPARAM)hItem); - } - - BOOL SelectSetFirstVisible(HTREEITEM hItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_SELECTITEM, TVGN_FIRSTVISIBLE, (LPARAM)hItem); - } - - CEdit EditLabel(HTREEITEM hItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CEdit((HWND)::SendMessage(m_hWnd, TVM_EDITLABEL, 0, (LPARAM)hItem)); - } - - BOOL EndEditLabelNow(BOOL bCancel) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_ENDEDITLABELNOW, bCancel, 0L); - } - - HTREEITEM HitTest(TVHITTESTINFO* pHitTestInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0, (LPARAM)pHitTestInfo); - } - - HTREEITEM HitTest(POINT pt, UINT* pFlags) const - { - ATLASSERT(::IsWindow(m_hWnd)); - TVHITTESTINFO hti = { 0 }; - hti.pt = pt; - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0, (LPARAM)&hti); - if (pFlags != NULL) - *pFlags = hti.flags; - return hTreeItem; - } - - BOOL SortChildren(HTREEITEM hItem, BOOL bRecurse = FALSE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_SORTCHILDREN, (WPARAM)bRecurse, (LPARAM)hItem); - } - - BOOL EnsureVisible(HTREEITEM hItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_ENSUREVISIBLE, 0, (LPARAM)hItem); - } - - BOOL SortChildrenCB(LPTVSORTCB pSort, BOOL bRecurse = FALSE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_SORTCHILDRENCB, (WPARAM)bRecurse, (LPARAM)pSort); - } - - CImageList RemoveImageList(int nImageList) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TVM_SETIMAGELIST, (WPARAM)nImageList, NULL)); - } - - CImageList CreateDragImage(HTREEITEM hItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TVM_CREATEDRAGIMAGE, 0, (LPARAM)hItem)); - } - -#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - BOOL SetInsertMark(HTREEITEM hTreeItem, BOOL bAfter) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_SETINSERTMARK, bAfter, (LPARAM)hTreeItem); - } - - BOOL RemoveInsertMark() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TVM_SETINSERTMARK, 0, 0L); - } -#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - -#if (_WIN32_WINNT >= 0x0501) - HTREEITEM MapAccIDToHTREEITEM(UINT uID) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HTREEITEM)::SendMessage(m_hWnd, TVM_MAPACCIDTOHTREEITEM, uID, 0L); - } - - UINT MapHTREEITEMToAccID(HTREEITEM hTreeItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, TVM_MAPHTREEITEMTOACCID, (WPARAM)hTreeItem, 0L); - } -#endif // (_WIN32_WINNT >= 0x0501) - -#if (_WIN32_WINNT >= 0x0600) - void ShowInfoTip(HTREEITEM hItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TVM_SHOWINFOTIP, 0, (LPARAM)hItem); - } -#endif // (_WIN32_WINNT >= 0x0600) -}; - -typedef CTreeViewCtrlT CTreeViewCtrl; - - -/////////////////////////////////////////////////////////////////////////////// -// CTreeViewCtrlEx - -// forward declaration -template class CTreeViewCtrlExT; - -// Note: TBase here is for CTreeViewCtrlExT, and not for CTreeItemT itself -template -class CTreeItemT -{ -public: - HTREEITEM m_hTreeItem; - CTreeViewCtrlExT* m_pTreeView; - -// Construction - CTreeItemT(HTREEITEM hTreeItem = NULL, CTreeViewCtrlExT* pTreeView = NULL) : m_hTreeItem(hTreeItem), m_pTreeView(pTreeView) - { } - - CTreeItemT(const CTreeItemT& posSrc) - { - *this = posSrc; - } - - operator HTREEITEM() { return m_hTreeItem; } - - CTreeItemT& operator =(const CTreeItemT& itemSrc) - { - m_hTreeItem = itemSrc.m_hTreeItem; - m_pTreeView = itemSrc.m_pTreeView; - return *this; - } - -// Attributes - CTreeViewCtrlExT* GetTreeView() const { return m_pTreeView; } - - BOOL operator !() const { return m_hTreeItem == NULL; } - - BOOL IsNull() const { return m_hTreeItem == NULL; } - - BOOL GetRect(LPRECT lpRect, BOOL bTextOnly) const; - BOOL GetText(LPTSTR lpstrText, int nLen) const; -#ifndef _ATL_NO_COM - BOOL GetText(BSTR& bstrText) const; -#endif // !_ATL_NO_COM -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - BOOL GetText(_CSTRING_NS::CString& strText) const; -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - BOOL SetText(LPCTSTR lpszItem); - BOOL GetImage(int& nImage, int& nSelectedImage) const; - BOOL SetImage(int nImage, int nSelectedImage); - UINT GetState(UINT nStateMask) const; - BOOL SetState(UINT nState, UINT nStateMask); - DWORD_PTR GetData() const; - BOOL SetData(DWORD_PTR dwData); - BOOL SetItem(UINT nMask, LPCTSTR lpszItem, int nImage, int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam); - -// Operations - CTreeItemT InsertAfter(LPCTSTR lpstrItem, HTREEITEM hItemAfter, int nImageIndex) - { - return _Insert(lpstrItem, nImageIndex, hItemAfter); - } - - CTreeItemT AddHead(LPCTSTR lpstrItem, int nImageIndex) - { - return _Insert(lpstrItem, nImageIndex, TVI_FIRST); - } - - CTreeItemT AddTail(LPCTSTR lpstrItem, int nImageIndex) - { - return _Insert(lpstrItem, nImageIndex, TVI_LAST); - } - - CTreeItemT GetChild() const; - CTreeItemT GetNext(UINT nCode) const; - CTreeItemT GetNextSibling() const; - CTreeItemT GetPrevSibling() const; - CTreeItemT GetParent() const; - CTreeItemT GetFirstVisible() const; - CTreeItemT GetNextVisible() const; - CTreeItemT GetPrevVisible() const; - CTreeItemT GetSelected() const; - CTreeItemT GetDropHilight() const; - CTreeItemT GetRoot() const; -#if !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) - CTreeItemT GetLastVisible() const; -#endif // !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) -#if (_WIN32_IE >= 0x0600) - CTreeItemT GetNextSelected() const; -#endif // (_WIN32_IE >= 0x0600) - BOOL HasChildren() const; - BOOL Delete(); - BOOL Expand(UINT nCode = TVE_EXPAND); - BOOL Select(UINT nCode); - BOOL Select(); - BOOL SelectDropTarget(); - BOOL SelectSetFirstVisible(); - HWND EditLabel(); - HIMAGELIST CreateDragImage(); - BOOL SortChildren(BOOL bRecurse = FALSE); - BOOL EnsureVisible(); - CTreeItemT _Insert(LPCTSTR lpstrItem, int nImageIndex, HTREEITEM hItemAfter); - int GetImageIndex() const; -#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - BOOL SetInsertMark(BOOL bAfter); -#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) -#if (_WIN32_WINNT >= 0x0501) - UINT MapHTREEITEMToAccID() const; -#endif // (_WIN32_WINNT >= 0x0501) -#if (_WIN32_WINNT >= 0x0600) - void ShowInfoTip(); - BOOL GetPartRect(TVITEMPART partID, LPRECT lpRect) const; -#endif // (_WIN32_WINNT >= 0x0600) -}; - -typedef CTreeItemT CTreeItem; - - -template -class CTreeViewCtrlExT : public CTreeViewCtrlT< TBase > -{ -public: -// Constructors - CTreeViewCtrlExT(HWND hWnd = NULL) : CTreeViewCtrlT< TBase >(hWnd) - { } - - CTreeViewCtrlExT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - -// Operations (overides that return CTreeItem) - CTreeItemT InsertItem(LPTVINSERTSTRUCT lpInsertStruct) - { - ATLASSERT(::IsWindow(m_hWnd)); - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)lpInsertStruct); - return CTreeItemT(hTreeItem, this); - } - - CTreeItemT InsertItem(LPCTSTR lpszItem, int nImage, - int nSelectedImage, HTREEITEM hParent, HTREEITEM hInsertAfter) - { - ATLASSERT(::IsWindow(m_hWnd)); - return InsertItem(TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE, lpszItem, nImage, nSelectedImage, 0, 0, 0, hParent, hInsertAfter); - } - - CTreeItemT InsertItem(LPCTSTR lpszItem, HTREEITEM hParent, HTREEITEM hInsertAfter) - { - ATLASSERT(::IsWindow(m_hWnd)); - return InsertItem(TVIF_TEXT, lpszItem, 0, 0, 0, 0, 0, hParent, hInsertAfter); - } - - CTreeItemT GetNextItem(HTREEITEM hItem, UINT nCode) const - { - ATLASSERT(::IsWindow(m_hWnd)); - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, nCode, (LPARAM)hItem); - return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); - } - - CTreeItemT GetChildItem(HTREEITEM hItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem); - return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); - } - - CTreeItemT GetNextSiblingItem(HTREEITEM hItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem); - return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); - } - - CTreeItemT GetPrevSiblingItem(HTREEITEM hItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PREVIOUS, (LPARAM)hItem); - return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); - } - - CTreeItemT GetParentItem(HTREEITEM hItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItem); - return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); - } - - CTreeItemT GetFirstVisibleItem() const - { - ATLASSERT(::IsWindow(m_hWnd)); - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_FIRSTVISIBLE, 0L); - return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); - } - - CTreeItemT GetNextVisibleItem(HTREEITEM hItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, (LPARAM)hItem); - return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); - } - - CTreeItemT GetPrevVisibleItem(HTREEITEM hItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PREVIOUSVISIBLE, (LPARAM)hItem); - return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); - } - - CTreeItemT GetSelectedItem() const - { - ATLASSERT(::IsWindow(m_hWnd)); - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CARET, 0L); - return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); - } - - CTreeItemT GetDropHilightItem() const - { - ATLASSERT(::IsWindow(m_hWnd)); - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_DROPHILITE, 0L); - return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); - } - - CTreeItemT GetRootItem() const - { - ATLASSERT(::IsWindow(m_hWnd)); - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_ROOT, 0L); - return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); - } - -#if !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) - CTreeItemT GetLastVisibleItem() const - { - ATLASSERT(::IsWindow(m_hWnd)); - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_LASTVISIBLE, 0L); - return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); - } -#endif // !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) - -#if (_WIN32_IE >= 0x0600) - CTreeItemT GetNextSelectedItem() const - { - ATLASSERT(::IsWindow(m_hWnd)); - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXTSELECTED, 0L); - return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); - } -#endif // (_WIN32_IE >= 0x0600) - - CTreeItemT HitTest(TVHITTESTINFO* pHitTestInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0, (LPARAM)pHitTestInfo); - return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); - } - - CTreeItemT InsertItem(UINT nMask, LPCTSTR lpszItem, int nImage, - int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam, - HTREEITEM hParent, HTREEITEM hInsertAfter) - { - ATLASSERT(::IsWindow(m_hWnd)); - TVINSERTSTRUCT tvis = { 0 }; - tvis.hParent = hParent; - tvis.hInsertAfter = hInsertAfter; - tvis.item.mask = nMask; - tvis.item.pszText = (LPTSTR) lpszItem; - tvis.item.iImage = nImage; - tvis.item.iSelectedImage = nSelectedImage; - tvis.item.state = nState; - tvis.item.stateMask = nStateMask; - tvis.item.lParam = lParam; - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)&tvis); - return CTreeItemT(hTreeItem, this); - } - - CTreeItemT HitTest(POINT pt, UINT* pFlags) const - { - ATLASSERT(::IsWindow(m_hWnd)); - TVHITTESTINFO hti = { 0 }; - hti.pt = pt; - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0, (LPARAM)&hti); - if (pFlags != NULL) - *pFlags = hti.flags; - return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); - } - -#if (_WIN32_WINNT >= 0x0501) - CTreeItemT MapAccIDToHTREEITEM(UINT uID) const - { - ATLASSERT(::IsWindow(m_hWnd)); - HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_MAPACCIDTOHTREEITEM, uID, 0L); - return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); - } -#endif // (_WIN32_WINNT >= 0x0501) -}; - -typedef CTreeViewCtrlExT CTreeViewCtrlEx; - - -// CTreeItem inline methods -template -inline BOOL CTreeItemT::GetRect(LPRECT lpRect, BOOL bTextOnly) const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetItemRect(m_hTreeItem,lpRect,bTextOnly); -} - -template -inline CTreeItemT CTreeItemT::GetNext(UINT nCode) const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetNextItem(m_hTreeItem,nCode); -} - -template -inline CTreeItemT CTreeItemT::GetChild() const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetChildItem(m_hTreeItem); -} - -template -inline CTreeItemT CTreeItemT::GetNextSibling() const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetNextSiblingItem(m_hTreeItem); -} - -template -inline CTreeItemT CTreeItemT::GetPrevSibling() const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetPrevSiblingItem(m_hTreeItem); -} - -template -inline CTreeItemT CTreeItemT::GetParent() const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetParentItem(m_hTreeItem); -} - -template -inline CTreeItemT CTreeItemT::GetFirstVisible() const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetFirstVisibleItem(); -} - -template -inline CTreeItemT CTreeItemT::GetNextVisible() const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetNextVisibleItem(m_hTreeItem); -} - -template -inline CTreeItemT CTreeItemT::GetPrevVisible() const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetPrevVisibleItem(m_hTreeItem); -} - -template -inline CTreeItemT CTreeItemT::GetSelected() const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetSelectedItem(); -} - -template -inline CTreeItemT CTreeItemT::GetDropHilight() const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetDropHilightItem(); -} - -template -inline CTreeItemT CTreeItemT::GetRoot() const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetRootItem(); -} - -#if !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) -template -inline CTreeItemT CTreeItemT::GetLastVisible() const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetLastVisibleItem(); -} -#endif // !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) - -#if (_WIN32_IE >= 0x0600) -template -inline CTreeItemT CTreeItemT::GetNextSelected() const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetNextSelectedItem(); -} -#endif // (_WIN32_IE >= 0x0600) - -template -inline BOOL CTreeItemT::GetText(LPTSTR lpstrText, int nLen) const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetItemText(m_hTreeItem, lpstrText, nLen); -} - -#ifndef _ATL_NO_COM -#ifdef _OLEAUTO_H_ -template -inline BOOL CTreeItemT::GetText(BSTR& bstrText) const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetItemText(m_hTreeItem, bstrText); -} -#endif // _OLEAUTO_H_ -#endif // !_ATL_NO_COM - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) -template -inline BOOL CTreeItemT::GetText(_CSTRING_NS::CString& strText) const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetItemText(m_hTreeItem, strText); -} -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - -template -inline BOOL CTreeItemT::GetImage(int& nImage, int& nSelectedImage) const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetItemImage(m_hTreeItem,nImage,nSelectedImage); -} - -template -inline UINT CTreeItemT::GetState(UINT nStateMask) const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetItemState(m_hTreeItem,nStateMask); -} - -template -inline DWORD_PTR CTreeItemT::GetData() const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetItemData(m_hTreeItem); -} - -template -inline BOOL CTreeItemT::SetItem(UINT nMask, LPCTSTR lpszItem, int nImage, - int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam) -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->SetItem(m_hTreeItem, nMask, lpszItem, nImage, nSelectedImage, nState, nStateMask, lParam); -} - -template -inline BOOL CTreeItemT::SetText(LPCTSTR lpszItem) -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->SetItemText(m_hTreeItem,lpszItem); -} - -template -inline BOOL CTreeItemT::SetImage(int nImage, int nSelectedImage) -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->SetItemImage(m_hTreeItem,nImage,nSelectedImage); -} - -template -inline BOOL CTreeItemT::SetState(UINT nState, UINT nStateMask) -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->SetItemState(m_hTreeItem,nState,nStateMask); -} - -template -inline BOOL CTreeItemT::SetData(DWORD_PTR dwData) -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->SetItemData(m_hTreeItem,dwData); -} - -template -inline BOOL CTreeItemT::HasChildren() const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->ItemHasChildren(m_hTreeItem); -} - -template -inline BOOL CTreeItemT::Delete() -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->DeleteItem(m_hTreeItem); -} - -template -inline BOOL CTreeItemT::Expand(UINT nCode /*= TVE_EXPAND*/) -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->Expand(m_hTreeItem,nCode); -} - -template -inline BOOL CTreeItemT::Select(UINT nCode) -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->Select(m_hTreeItem,nCode); -} - -template -inline BOOL CTreeItemT::Select() -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->SelectItem(m_hTreeItem); -} - -template -inline BOOL CTreeItemT::SelectDropTarget() -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->SelectDropTarget(m_hTreeItem); -} - -template -inline BOOL CTreeItemT::SelectSetFirstVisible() -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->SelectSetFirstVisible(m_hTreeItem); -} - -template -inline HWND CTreeItemT::EditLabel() -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->EditLabel(m_hTreeItem); -} - -template -inline HIMAGELIST CTreeItemT::CreateDragImage() -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->CreateDragImage(m_hTreeItem); -} - -template -inline BOOL CTreeItemT::SortChildren(BOOL bRecurse /*= FALSE*/) -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->SortChildren(m_hTreeItem, bRecurse); -} - -template -inline BOOL CTreeItemT::EnsureVisible() -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->EnsureVisible(m_hTreeItem); -} - -template -inline CTreeItemT CTreeItemT::_Insert(LPCTSTR lpstrItem, int nImageIndex, HTREEITEM hItemAfter) -{ - ATLASSERT(m_pTreeView != NULL); - TVINSERTSTRUCT ins = { 0 }; - ins.hParent = m_hTreeItem; - ins.hInsertAfter = hItemAfter; - ins.item.mask = TVIF_TEXT; - ins.item.pszText = (LPTSTR)lpstrItem; - if(nImageIndex != -1) - { - ins.item.mask |= TVIF_IMAGE | TVIF_SELECTEDIMAGE; - ins.item.iImage = nImageIndex; - ins.item.iSelectedImage = nImageIndex; - } - return CTreeItemT(m_pTreeView->InsertItem(&ins), m_pTreeView); -} - -template -inline int CTreeItemT::GetImageIndex() const -{ - ATLASSERT(m_pTreeView != NULL); - TVITEM item = { 0 }; - item.mask = TVIF_HANDLE | TVIF_IMAGE; - item.hItem = m_hTreeItem; - m_pTreeView->GetItem(&item); - return item.iImage; -} - -#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) -template -inline BOOL CTreeItemT::SetInsertMark(BOOL bAfter) -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->SetInsertMark(m_hTreeItem, bAfter); -} -#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - -#if (_WIN32_WINNT >= 0x0501) -template -inline UINT CTreeItemT::MapHTREEITEMToAccID() const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->MapHTREEITEMToAccID(m_hTreeItem); -} -#endif // (_WIN32_WINNT >= 0x0501) - -#if (_WIN32_WINNT >= 0x0600) -template -inline void CTreeItemT::ShowInfoTip() -{ - ATLASSERT(m_pTreeView != NULL); - m_pTreeView->ShowInfoTip(m_hTreeItem); -} - -template -inline BOOL CTreeItemT::GetPartRect(TVITEMPART partID, LPRECT lpRect) const -{ - ATLASSERT(m_pTreeView != NULL); - return m_pTreeView->GetItemPartRect(m_hTreeItem, partID, lpRect); -} -#endif // (_WIN32_WINNT >= 0x0600) - - -/////////////////////////////////////////////////////////////////////////////// -// CToolBarCtrl - -template -class CToolBarCtrlT : public TBase -{ -public: -// Construction - CToolBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CToolBarCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return TOOLBARCLASSNAME; - } - - BOOL IsButtonEnabled(int nID) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONENABLED, nID, 0L); - } - - BOOL IsButtonChecked(int nID) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONCHECKED, nID, 0L); - } - - BOOL IsButtonPressed(int nID) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONPRESSED, nID, 0L); - } - - BOOL IsButtonHidden(int nID) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return(BOOL) ::SendMessage(m_hWnd, TB_ISBUTTONHIDDEN, nID, 0L); - } - - BOOL IsButtonIndeterminate(int nID) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONINDETERMINATE, nID, 0L); - } - - int GetState(int nID) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TB_GETSTATE, nID, 0L); - } - - BOOL SetState(int nID, UINT nState) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_SETSTATE, nID, MAKELPARAM(nState, 0)); - } - - BOOL GetButton(int nIndex, LPTBBUTTON lpButton) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_GETBUTTON, nIndex, (LPARAM)lpButton); - } - - int GetButtonCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TB_BUTTONCOUNT, 0, 0L); - } - - BOOL GetItemRect(int nIndex, LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_GETITEMRECT, nIndex, (LPARAM)lpRect); - } - - void SetButtonStructSize(int nSize = sizeof(TBBUTTON)) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TB_BUTTONSTRUCTSIZE, nSize, 0L); - } - - BOOL SetButtonSize(SIZE size) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONSIZE, 0, MAKELPARAM(size.cx, size.cy)); - } - - BOOL SetButtonSize(int cx, int cy) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONSIZE, 0, MAKELPARAM(cx, cy)); - } - - BOOL SetBitmapSize(SIZE size) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_SETBITMAPSIZE, 0, MAKELPARAM(size.cx, size.cy)); - } - - BOOL SetBitmapSize(int cx, int cy) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_SETBITMAPSIZE, 0, MAKELPARAM(cx, cy)); - } - -#ifndef _WIN32_WCE - CToolTipCtrl GetToolTips() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TB_GETTOOLTIPS, 0, 0L)); - } - - void SetToolTips(HWND hWndToolTip) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TB_SETTOOLTIPS, (WPARAM)hWndToolTip, 0L); - } -#endif // !_WIN32_WCE - - void SetNotifyWnd(HWND hWnd) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TB_SETPARENT, (WPARAM)hWnd, 0L); - } - - int GetRows() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TB_GETROWS, 0, 0L); - } - - void SetRows(int nRows, BOOL bLarger, LPRECT lpRect) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TB_SETROWS, MAKELPARAM(nRows, bLarger), (LPARAM)lpRect); - } - - BOOL SetCmdID(int nIndex, UINT nID) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_SETCMDID, nIndex, nID); - } - - DWORD GetBitmapFlags() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, TB_GETBITMAPFLAGS, 0, 0L); - } - - int GetBitmap(int nID) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TB_GETBITMAP, nID, 0L); - } - - int GetButtonText(int nID, LPTSTR lpstrText) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TB_GETBUTTONTEXT, nID, (LPARAM)lpstrText); - } - - // nIndex - IE5 or higher only - CImageList GetImageList(int nIndex = 0) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_GETIMAGELIST, nIndex, 0L)); - } - - // nIndex - IE5 or higher only - CImageList SetImageList(HIMAGELIST hImageList, int nIndex = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_SETIMAGELIST, nIndex, (LPARAM)hImageList)); - } - - // nIndex - IE5 or higher only - CImageList GetDisabledImageList(int nIndex = 0) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_GETDISABLEDIMAGELIST, nIndex, 0L)); - } - - // nIndex - IE5 or higher only - CImageList SetDisabledImageList(HIMAGELIST hImageList, int nIndex = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_SETDISABLEDIMAGELIST, nIndex, (LPARAM)hImageList)); - } - -#ifndef _WIN32_WCE - // nIndex - IE5 or higher only - CImageList GetHotImageList(int nIndex = 0) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_GETHOTIMAGELIST, nIndex, 0L)); - } - - // nIndex - IE5 or higher only - CImageList SetHotImageList(HIMAGELIST hImageList, int nIndex = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_SETHOTIMAGELIST, nIndex, (LPARAM)hImageList)); - } -#endif // !_WIN32_WCE - - DWORD GetStyle() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, TB_GETSTYLE, 0, 0L); - } - - void SetStyle(DWORD dwStyle) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TB_SETSTYLE, 0, dwStyle); - } - - DWORD GetButtonSize() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, TB_GETBUTTONSIZE, 0, 0L); - } - - void GetButtonSize(SIZE& size) const - { - ATLASSERT(::IsWindow(m_hWnd)); - DWORD dwRet = (DWORD)::SendMessage(m_hWnd, TB_GETBUTTONSIZE, 0, 0L); - size.cx = LOWORD(dwRet); - size.cy = HIWORD(dwRet); - } - - BOOL GetRect(int nID, LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_GETRECT, nID, (LPARAM)lpRect); - } - - int GetTextRows() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TB_GETTEXTROWS, 0, 0L); - } - - BOOL SetButtonWidth(int cxMin, int cxMax) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONWIDTH, 0, MAKELPARAM(cxMin, cxMax)); - } - - BOOL SetIndent(int nIndent) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_SETINDENT, nIndent, 0L); - } - - BOOL SetMaxTextRows(int nMaxTextRows) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_SETMAXTEXTROWS, nMaxTextRows, 0L); - } - -#if (_WIN32_IE >= 0x0400) -#ifndef _WIN32_WCE - BOOL GetAnchorHighlight() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_GETANCHORHIGHLIGHT, 0, 0L); - } - - BOOL SetAnchorHighlight(BOOL bEnable = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_SETANCHORHIGHLIGHT, bEnable, 0L); - } -#endif // !_WIN32_WCE - - int GetButtonInfo(int nID, LPTBBUTTONINFO lptbbi) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TB_GETBUTTONINFO, nID, (LPARAM)lptbbi); - } - - BOOL SetButtonInfo(int nID, LPTBBUTTONINFO lptbbi) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONINFO, nID, (LPARAM)lptbbi); - } - - BOOL SetButtonInfo(int nID, DWORD dwMask, BYTE Style, BYTE State, LPCTSTR lpszItem, - int iImage, WORD cx, int iCommand, DWORD_PTR lParam) - { - ATLASSERT(::IsWindow(m_hWnd)); - TBBUTTONINFO tbbi = { 0 }; - tbbi.cbSize = sizeof(TBBUTTONINFO); - tbbi.dwMask = dwMask; - tbbi.idCommand = iCommand; - tbbi.iImage = iImage; - tbbi.fsState = State; - tbbi.fsStyle = Style; - tbbi.cx = cx; - tbbi.pszText = (LPTSTR) lpszItem; - tbbi.lParam = lParam; - return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONINFO, nID, (LPARAM)&tbbi); - } - -#ifndef _WIN32_WCE - int GetHotItem() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TB_GETHOTITEM, 0, 0L); - } - - int SetHotItem(int nItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TB_SETHOTITEM, nItem, 0L); - } -#endif // !_WIN32_WCE - - BOOL IsButtonHighlighted(int nButtonID) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONHIGHLIGHTED, nButtonID, 0L); - } - - DWORD SetDrawTextFlags(DWORD dwMask, DWORD dwFlags) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, TB_SETDRAWTEXTFLAGS, dwMask, dwFlags); - } - -#ifndef _WIN32_WCE - BOOL GetColorScheme(LPCOLORSCHEME lpcs) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_GETCOLORSCHEME, 0, (LPARAM)lpcs); - } - - void SetColorScheme(LPCOLORSCHEME lpcs) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TB_SETCOLORSCHEME, 0, (LPARAM)lpcs); - } - - DWORD GetExtendedStyle() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, TB_GETEXTENDEDSTYLE, 0, 0L); - } - - DWORD SetExtendedStyle(DWORD dwStyle) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, TB_SETEXTENDEDSTYLE, 0, dwStyle); - } - - void GetInsertMark(LPTBINSERTMARK lptbim) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TB_GETINSERTMARK, 0, (LPARAM)lptbim); - } - - void SetInsertMark(LPTBINSERTMARK lptbim) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TB_SETINSERTMARK, 0, (LPARAM)lptbim); - } - - COLORREF GetInsertMarkColor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, TB_GETINSERTMARKCOLOR, 0, 0L); - } - - COLORREF SetInsertMarkColor(COLORREF clr) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, TB_SETINSERTMARKCOLOR, 0, (LPARAM)clr); - } - - BOOL GetMaxSize(LPSIZE lpSize) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_GETMAXSIZE, 0, (LPARAM)lpSize); - } - - void GetPadding(LPSIZE lpSizePadding) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(lpSizePadding != NULL); - DWORD dwRet = (DWORD)::SendMessage(m_hWnd, TB_GETPADDING, 0, 0L); - lpSizePadding->cx = GET_X_LPARAM(dwRet); - lpSizePadding->cy = GET_Y_LPARAM(dwRet); - } - - void SetPadding(int cx, int cy, LPSIZE lpSizePadding = NULL) - { - ATLASSERT(::IsWindow(m_hWnd)); - DWORD dwRet = (DWORD)::SendMessage(m_hWnd, TB_SETPADDING, 0, MAKELPARAM(cx, cy)); - if(lpSizePadding != NULL) - { - lpSizePadding->cx = GET_X_LPARAM(dwRet); - lpSizePadding->cy = GET_Y_LPARAM(dwRet); - } - } - - BOOL GetUnicodeFormat() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_GETUNICODEFORMAT, 0, 0L); - } - - BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_SETUNICODEFORMAT, bUnicode, 0L); - } -#endif // !_WIN32_WCE -#endif // (_WIN32_IE >= 0x0400) - -#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - int GetString(int nString, LPTSTR lpstrString, int cchMaxLen) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(cchMaxLen, nString), (LPARAM)lpstrString); - } - - int GetStringBSTR(int nString, BSTR& bstrString) const - { - USES_CONVERSION; - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(bstrString == NULL); - int nLength = (int)(short)LOWORD(::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(0, nString), NULL)); - if(nLength != -1) - { - CTempBuffer buff; - LPTSTR lpstrText = buff.Allocate(nLength + 1); - if(lpstrText != NULL) - { - nLength = (int)::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(nLength + 1, nString), (LPARAM)lpstrText); - if(nLength != -1) - bstrString = ::SysAllocString(T2OLE(lpstrText)); - } - else - { - nLength = -1; - } - } - - return nLength; - } - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - int GetString(int nString, _CSTRING_NS::CString& str) const - { - ATLASSERT(::IsWindow(m_hWnd)); - int nLength = (int)(short)LOWORD(::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(0, nString), NULL)); - if(nLength != -1) - { - LPTSTR lpstr = str.GetBufferSetLength(nLength + 1); - if(lpstr != NULL) - nLength = (int)::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(nLength + 1, nString), (LPARAM)lpstr); - else - nLength = -1; - str.ReleaseBuffer(); - } - return nLength; - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) -#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - -#if (_WIN32_WINNT >= 0x0501) - void GetMetrics(LPTBMETRICS lptbm) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TB_GETMETRICS, 0, (LPARAM)lptbm); - } - - void SetMetrics(LPTBMETRICS lptbm) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TB_SETMETRICS, 0, (LPARAM)lptbm); - } - - void SetWindowTheme(LPCWSTR lpstrTheme) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TB_SETWINDOWTHEME, 0, (LPARAM)lpstrTheme); - } -#endif // (_WIN32_WINNT >= 0x0501) - -#if (_WIN32_WINNT >= 0x0600) - CImageList GetPressedImageList(int nIndex = 0) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_GETPRESSEDIMAGELIST, nIndex, 0L)); - } - - CImageList SetPressedImageList(HIMAGELIST hImageList, int nIndex = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_SETPRESSEDIMAGELIST, nIndex, (LPARAM)hImageList)); - } -#endif // (_WIN32_WINNT >= 0x0600) - -// Operations - BOOL EnableButton(int nID, BOOL bEnable = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_ENABLEBUTTON, nID, MAKELPARAM(bEnable, 0)); - } - - BOOL CheckButton(int nID, BOOL bCheck = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_CHECKBUTTON, nID, MAKELPARAM(bCheck, 0)); - } - - BOOL PressButton(int nID, BOOL bPress = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_PRESSBUTTON, nID, MAKELPARAM(bPress, 0)); - } - - BOOL HideButton(int nID, BOOL bHide = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_HIDEBUTTON, nID, MAKELPARAM(bHide, 0)); - } - - BOOL Indeterminate(int nID, BOOL bIndeterminate = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_INDETERMINATE, nID, MAKELPARAM(bIndeterminate, 0)); - } - - int AddBitmap(int nNumButtons, UINT nBitmapID) - { - ATLASSERT(::IsWindow(m_hWnd)); - TBADDBITMAP tbab = { 0 }; - tbab.hInst = ModuleHelper::GetResourceInstance(); - ATLASSERT(tbab.hInst != NULL); - tbab.nID = nBitmapID; - return (int)::SendMessage(m_hWnd, TB_ADDBITMAP, (WPARAM)nNumButtons, (LPARAM)&tbab); - } - - int AddBitmap(int nNumButtons, HBITMAP hBitmap) - { - ATLASSERT(::IsWindow(m_hWnd)); - TBADDBITMAP tbab = { 0 }; - tbab.hInst = NULL; - tbab.nID = (UINT_PTR)hBitmap; - return (int)::SendMessage(m_hWnd, TB_ADDBITMAP, (WPARAM)nNumButtons, (LPARAM)&tbab); - } - - BOOL AddButtons(int nNumButtons, LPTBBUTTON lpButtons) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_ADDBUTTONS, nNumButtons, (LPARAM)lpButtons); - } - - BOOL InsertButton(int nIndex, LPTBBUTTON lpButton) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_INSERTBUTTON, nIndex, (LPARAM)lpButton); - } - - BOOL InsertButton(int nIndex, int iCommand, BYTE Style, BYTE State, int iBitmap, - INT_PTR iString, DWORD_PTR lParam) - { - ATLASSERT(::IsWindow(m_hWnd)); - TBBUTTON tbb = { 0 }; - tbb.fsStyle = Style; - tbb.fsState = State; - tbb.idCommand = iCommand; - tbb.iBitmap = iBitmap; - tbb.iString = iString; - tbb.dwData = lParam; - return (BOOL)::SendMessage(m_hWnd, TB_INSERTBUTTON, nIndex, (LPARAM)&tbb); - } - - BOOL InsertButton(int nIndex, int iCommand, BYTE Style, BYTE State, int iBitmap, - LPCTSTR lpszItem, DWORD_PTR lParam) - { - return InsertButton(nIndex, iCommand, Style, State, iBitmap, (INT_PTR)lpszItem, lParam); - } - - BOOL AddButton(LPTBBUTTON lpButton) - { - return InsertButton(-1, lpButton); - } - - BOOL AddButton(int iCommand, BYTE Style, BYTE State, int iBitmap, INT_PTR iString, DWORD_PTR lParam) - { - return InsertButton(-1, iCommand, Style, State, iBitmap, iString, lParam); - } - - BOOL AddButton(int iCommand, BYTE Style, BYTE State, int iBitmap, LPCTSTR lpszItem, DWORD_PTR lParam) - { - return InsertButton(-1, iCommand, Style, State, iBitmap, lpszItem, lParam); - } - - BOOL DeleteButton(int nIndex) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_DELETEBUTTON, nIndex, 0L); - } - - UINT CommandToIndex(UINT nID) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, TB_COMMANDTOINDEX, nID, 0L); - } - -#ifndef _WIN32_WCE - void SaveState(HKEY hKeyRoot, LPCTSTR lpszSubKey, LPCTSTR lpszValueName) - { - ATLASSERT(::IsWindow(m_hWnd)); - TBSAVEPARAMS tbs = { 0 }; - tbs.hkr = hKeyRoot; - tbs.pszSubKey = lpszSubKey; - tbs.pszValueName = lpszValueName; - ::SendMessage(m_hWnd, TB_SAVERESTORE, (WPARAM)TRUE, (LPARAM)&tbs); - } - - void RestoreState(HKEY hKeyRoot, LPCTSTR lpszSubKey, LPCTSTR lpszValueName) - { - ATLASSERT(::IsWindow(m_hWnd)); - TBSAVEPARAMS tbs = { 0 }; - tbs.hkr = hKeyRoot; - tbs.pszSubKey = lpszSubKey; - tbs.pszValueName = lpszValueName; - ::SendMessage(m_hWnd, TB_SAVERESTORE, (WPARAM)FALSE, (LPARAM)&tbs); - } - - void Customize() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TB_CUSTOMIZE, 0, 0L); - } -#endif // !_WIN32_WCE - - int AddString(UINT nStringID) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TB_ADDSTRING, (WPARAM)ModuleHelper::GetResourceInstance(), (LPARAM)nStringID); - } - - int AddStrings(LPCTSTR lpszStrings) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TB_ADDSTRING, 0, (LPARAM)lpszStrings); - } - - void AutoSize() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TB_AUTOSIZE, 0, 0L); - } - - BOOL ChangeBitmap(int nID, int nBitmap) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_CHANGEBITMAP, nID, MAKELPARAM(nBitmap, 0)); - } - - int LoadImages(int nBitmapID) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TB_LOADIMAGES, nBitmapID, (LPARAM)ModuleHelper::GetResourceInstance()); - } - - int LoadStdImages(int nBitmapID) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TB_LOADIMAGES, nBitmapID, (LPARAM)HINST_COMMCTRL); - } - - BOOL ReplaceBitmap(LPTBREPLACEBITMAP ptbrb) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_REPLACEBITMAP, 0, (LPARAM)ptbrb); - } - -#if (_WIN32_IE >= 0x0400) - int HitTest(LPPOINT lpPoint) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TB_HITTEST, 0, (LPARAM)lpPoint); - } - -#ifndef _WIN32_WCE - BOOL InsertMarkHitTest(LPPOINT lpPoint, LPTBINSERTMARK lptbim) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_INSERTMARKHITTEST, (WPARAM)lpPoint, (LPARAM)lptbim); - } - - BOOL InsertMarkHitTest(int x, int y, LPTBINSERTMARK lptbim) const - { - ATLASSERT(::IsWindow(m_hWnd)); - POINT pt = { x, y }; - return (BOOL)::SendMessage(m_hWnd, TB_INSERTMARKHITTEST, (WPARAM)&pt, (LPARAM)lptbim); - } - - BOOL MapAccelerator(TCHAR chAccel, int& nID) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_MAPACCELERATOR, (WPARAM)chAccel, (LPARAM)&nID); - } - - BOOL MarkButton(int nID, BOOL bHighlight = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_MARKBUTTON, nID, MAKELPARAM(bHighlight, 0)); - } - - BOOL MoveButton(int nOldPos, int nNewPos) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TB_MOVEBUTTON, nOldPos, nNewPos); - } - - HRESULT GetObject(REFIID iid, LPVOID* ppvObject) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HRESULT)::SendMessage(m_hWnd, TB_GETOBJECT, (WPARAM)&iid, (LPARAM)ppvObject); - } -#endif // !_WIN32_WCE -#endif // (_WIN32_IE >= 0x0400) -}; - -typedef CToolBarCtrlT CToolBarCtrl; - - -/////////////////////////////////////////////////////////////////////////////// -// CStatusBarCtrl - -template -class CStatusBarCtrlT : public TBase -{ -public: -// Constructors - CStatusBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CStatusBarCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Methods - static LPCTSTR GetWndClassName() - { - return STATUSCLASSNAME; - } - - int GetParts(int nParts, int* pParts) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, SB_GETPARTS, nParts, (LPARAM)pParts); - } - - BOOL SetParts(int nParts, int* pWidths) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, SB_SETPARTS, nParts, (LPARAM)pWidths); - } - - int GetTextLength(int nPane, int* pType = NULL) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(nPane < 256); - DWORD dwRet = (DWORD)::SendMessage(m_hWnd, SB_GETTEXTLENGTH, (WPARAM)nPane, 0L); - if (pType != NULL) - *pType = (int)(short)HIWORD(dwRet); - return (int)(short)LOWORD(dwRet); - } - - int GetText(int nPane, LPTSTR lpszText, int* pType = NULL) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(nPane < 256); - DWORD dwRet = (DWORD)::SendMessage(m_hWnd, SB_GETTEXT, (WPARAM)nPane, (LPARAM)lpszText); - if(pType != NULL) - *pType = (int)(short)HIWORD(dwRet); - return (int)(short)LOWORD(dwRet); - } - -#ifndef _ATL_NO_COM - BOOL GetTextBSTR(int nPane, BSTR& bstrText, int* pType = NULL) const - { - USES_CONVERSION; - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(nPane < 256); - ATLASSERT(bstrText == NULL); - int nLength = (int)(short)LOWORD(::SendMessage(m_hWnd, SB_GETTEXTLENGTH, (WPARAM)nPane, 0L)); - if(nLength == 0) - return FALSE; - - CTempBuffer buff; - LPTSTR lpstrText = buff.Allocate(nLength + 1); - if(lpstrText == NULL) - return FALSE; - - if(!GetText(nPane, lpstrText, pType)) - return FALSE; - - bstrText = ::SysAllocString(T2OLE(lpstrText)); - return (bstrText != NULL) ? TRUE : FALSE; - } -#endif // !_ATL_NO_COM - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - int GetText(int nPane, _CSTRING_NS::CString& strText, int* pType = NULL) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(nPane < 256); - int nLength = (int)(short)LOWORD(::SendMessage(m_hWnd, SB_GETTEXTLENGTH, (WPARAM)nPane, 0L)); - if(nLength == 0) - return 0; - - LPTSTR lpstr = strText.GetBufferSetLength(nLength); - if(lpstr == NULL) - return 0; - return GetText(nPane, lpstr, pType); - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - - BOOL SetText(int nPane, LPCTSTR lpszText, int nType = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(nPane < 256); - return (BOOL)::SendMessage(m_hWnd, SB_SETTEXT, (nPane | nType), (LPARAM)lpszText); - } - - BOOL GetRect(int nPane, LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(nPane < 256); - return (BOOL)::SendMessage(m_hWnd, SB_GETRECT, nPane, (LPARAM)lpRect); - } - - BOOL GetBorders(int* pBorders) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, SB_GETBORDERS, 0, (LPARAM)pBorders); - } - - BOOL GetBorders(int& nHorz, int& nVert, int& nSpacing) const - { - ATLASSERT(::IsWindow(m_hWnd)); - int borders[3] = { 0, 0, 0 }; - BOOL bResult = (BOOL)::SendMessage(m_hWnd, SB_GETBORDERS, 0, (LPARAM)&borders); - if(bResult) - { - nHorz = borders[0]; - nVert = borders[1]; - nSpacing = borders[2]; - } - return bResult; - } - - void SetMinHeight(int nMin) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, SB_SETMINHEIGHT, nMin, 0L); - } - - BOOL SetSimple(BOOL bSimple = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, SB_SIMPLE, bSimple, 0L); - } - - BOOL IsSimple() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, SB_ISSIMPLE, 0, 0L); - } - -#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - BOOL GetUnicodeFormat() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, SB_GETUNICODEFORMAT, 0, 0L); - } - - BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, SB_SETUNICODEFORMAT, bUnicode, 0L); - } - - void GetTipText(int nPane, LPTSTR lpstrText, int nSize) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(nPane < 256); - ::SendMessage(m_hWnd, SB_GETTIPTEXT, MAKEWPARAM(nPane, nSize), (LPARAM)lpstrText); - } - - void SetTipText(int nPane, LPCTSTR lpstrText) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(nPane < 256); - ::SendMessage(m_hWnd, SB_SETTIPTEXT, nPane, (LPARAM)lpstrText); - } -#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - -#if ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500)) - COLORREF SetBkColor(COLORREF clrBk) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, SB_SETBKCOLOR, 0, (LPARAM)clrBk); - } - - HICON GetIcon(int nPane) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(nPane < 256); - return (HICON)::SendMessage(m_hWnd, SB_GETICON, nPane, 0L); - } - - BOOL SetIcon(int nPane, HICON hIcon) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(nPane < 256); - return (BOOL)::SendMessage(m_hWnd, SB_SETICON, nPane, (LPARAM)hIcon); - } -#endif // ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500)) -}; - -typedef CStatusBarCtrlT CStatusBarCtrl; - - -/////////////////////////////////////////////////////////////////////////////// -// CTabCtrl - -template -class CTabCtrlT : public TBase -{ -public: -// Constructors - CTabCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CTabCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return WC_TABCONTROL; - } - - CImageList GetImageList() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TCM_GETIMAGELIST, 0, 0L)); - } - - CImageList SetImageList(HIMAGELIST hImageList) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TCM_SETIMAGELIST, 0, (LPARAM)hImageList)); - } - - int GetItemCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TCM_GETITEMCOUNT, 0, 0L); - } - - BOOL GetItem(int nItem, LPTCITEM pTabCtrlItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TCM_GETITEM, nItem, (LPARAM)pTabCtrlItem); - } - - BOOL SetItem(int nItem, LPTCITEM pTabCtrlItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TCM_SETITEM, nItem, (LPARAM)pTabCtrlItem); - } - - int SetItem(int nItem, UINT mask, LPCTSTR lpszItem, DWORD dwState, DWORD dwStateMask, int iImage, LPARAM lParam) - { - ATLASSERT(::IsWindow(m_hWnd)); - TCITEM tci = { 0 }; - tci.mask = mask; - tci.pszText = (LPTSTR) lpszItem; - tci.dwState = dwState; - tci.dwStateMask = dwStateMask; - tci.iImage = iImage; - tci.lParam = lParam; - return (int)::SendMessage(m_hWnd, TCM_SETITEM, nItem, (LPARAM)&tci); - } - - BOOL GetItemRect(int nItem, LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TCM_GETITEMRECT, nItem, (LPARAM)lpRect); - } - - int GetCurSel() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TCM_GETCURSEL, 0, 0L); - } - - int SetCurSel(int nItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TCM_SETCURSEL, nItem, 0L); - } - - SIZE SetItemSize(SIZE size) - { - ATLASSERT(::IsWindow(m_hWnd)); - DWORD dwSize = (DWORD)::SendMessage(m_hWnd, TCM_SETITEMSIZE, 0, MAKELPARAM(size.cx, size.cy)); - SIZE sizeRet = { GET_X_LPARAM(dwSize), GET_Y_LPARAM(dwSize) }; - return sizeRet; - } - - void SetItemSize(int cx, int cy) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TCM_SETITEMSIZE, 0, MAKELPARAM(cx, cy)); - } - - void SetPadding(SIZE size) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TCM_SETPADDING, 0, MAKELPARAM(size.cx, size.cy)); - } - - int GetRowCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TCM_GETROWCOUNT, 0, 0L); - } - -#ifndef _WIN32_WCE - CToolTipCtrl GetTooltips() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TCM_GETTOOLTIPS, 0, 0L)); - } - - void SetTooltips(HWND hWndToolTip) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TCM_SETTOOLTIPS, (WPARAM)hWndToolTip, 0L); - } -#endif // !_WIN32_WCE - - int GetCurFocus() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TCM_GETCURFOCUS, 0, 0L); - } - - void SetCurFocus(int nItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TCM_SETCURFOCUS, nItem, 0L); - } - - BOOL SetItemExtra(int cbExtra) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(GetItemCount() == 0); // must be empty - return (BOOL)::SendMessage(m_hWnd, TCM_SETITEMEXTRA, cbExtra, 0L); - } - - int SetMinTabWidth(int nWidth = -1) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TCM_SETMINTABWIDTH, 0, nWidth); - } - -#if (_WIN32_IE >= 0x0400) - DWORD GetExtendedStyle() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, TCM_GETEXTENDEDSTYLE, 0, 0L); - } - - DWORD SetExtendedStyle(DWORD dwExMask, DWORD dwExStyle) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, TCM_SETEXTENDEDSTYLE, dwExMask, dwExStyle); - } - -#ifndef _WIN32_WCE - BOOL GetUnicodeFormat() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TCM_GETUNICODEFORMAT, 0, 0L); - } - - BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TCM_SETUNICODEFORMAT, bUnicode, 0L); - } -#endif // !_WIN32_WCE -#endif // (_WIN32_IE >= 0x0400) - -// Operations - int InsertItem(int nItem, LPTCITEM pTabCtrlItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TCM_INSERTITEM, nItem, (LPARAM)pTabCtrlItem); - } - - int InsertItem(int nItem, UINT mask, LPCTSTR lpszItem, int iImage, LPARAM lParam) - { - ATLASSERT(::IsWindow(m_hWnd)); - TCITEM tci = { 0 }; - tci.mask = mask; - tci.pszText = (LPTSTR) lpszItem; - tci.iImage = iImage; - tci.lParam = lParam; - return (int)::SendMessage(m_hWnd, TCM_INSERTITEM, nItem, (LPARAM)&tci); - } - - int InsertItem(int nItem, LPCTSTR lpszItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - TCITEM tci = { 0 }; - tci.mask = TCIF_TEXT; - tci.pszText = (LPTSTR) lpszItem; - return (int)::SendMessage(m_hWnd, TCM_INSERTITEM, nItem, (LPARAM)&tci); - } - - int AddItem(LPTCITEM pTabCtrlItem) - { - return InsertItem(GetItemCount(), pTabCtrlItem); - } - - int AddItem(UINT mask, LPCTSTR lpszItem, int iImage, LPARAM lParam) - { - return InsertItem(GetItemCount(), mask, lpszItem, iImage, lParam); - } - - int AddItem(LPCTSTR lpszItem) - { - return InsertItem(GetItemCount(), lpszItem); - } - - BOOL DeleteItem(int nItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TCM_DELETEITEM, nItem, 0L); - } - - BOOL DeleteAllItems() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TCM_DELETEALLITEMS, 0, 0L); - } - - void AdjustRect(BOOL bLarger, LPRECT lpRect) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TCM_ADJUSTRECT, bLarger, (LPARAM)lpRect); - } - - void RemoveImage(int nImage) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TCM_REMOVEIMAGE, nImage, 0L); - } - - int HitTest(TC_HITTESTINFO* pHitTestInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TCM_HITTEST, 0, (LPARAM)pHitTestInfo); - } - - void DeselectAll(BOOL bExcludeFocus = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TCM_DESELECTALL, bExcludeFocus, 0L); - } - -#if (_WIN32_IE >= 0x0400) - BOOL HighlightItem(int nIndex, BOOL bHighlight = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TCM_HIGHLIGHTITEM, nIndex, MAKELPARAM(bHighlight, 0)); - } -#endif // (_WIN32_IE >= 0x0400) -}; - -typedef CTabCtrlT CTabCtrl; - - -/////////////////////////////////////////////////////////////////////////////// -// CTrackBarCtrl - -template -class CTrackBarCtrlT : public TBase -{ -public: -// Constructors - CTrackBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CTrackBarCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return TRACKBAR_CLASS; - } - - int GetLineSize() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TBM_GETLINESIZE, 0, 0L); - } - - int SetLineSize(int nSize) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TBM_SETLINESIZE, 0, nSize); - } - - int GetPageSize() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TBM_GETPAGESIZE, 0, 0L); - } - - int SetPageSize(int nSize) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TBM_SETPAGESIZE, 0, nSize); - } - - int GetRangeMin() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TBM_GETRANGEMIN, 0, 0L); - } - - void SetRangeMin(int nMin, BOOL bRedraw = FALSE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TBM_SETRANGEMIN, bRedraw, nMin); - } - - int GetRangeMax() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TBM_GETRANGEMAX, 0, 0L); - } - - void SetRangeMax(int nMax, BOOL bRedraw = FALSE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TBM_SETRANGEMAX, bRedraw, nMax); - } - - void GetRange(int& nMin, int& nMax) const - { - nMin = GetRangeMin(); - nMax = GetRangeMax(); - } - - void SetRange(int nMin, int nMax, BOOL bRedraw = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TBM_SETRANGE, bRedraw, MAKELPARAM(nMin, nMax)); - } - - int GetSelStart() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TBM_GETSELSTART, 0, 0L); - } - - void SetSelStart(int nMin) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TBM_SETSELSTART, 0, (LPARAM)nMin); - } - - int GetSelEnd() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TBM_GETSELEND, 0, 0L); - } - - void SetSelEnd(int nMax) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TBM_SETSELEND, 0, (LPARAM)nMax); - } - - void GetSelection(int& nMin, int& nMax) const - { - nMin = GetSelStart(); - nMax = GetSelEnd(); - } - - void SetSelection(int nMin, int nMax) - { - SetSelStart(nMin); - SetSelEnd(nMax); - } - - void GetChannelRect(LPRECT lprc) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TBM_GETCHANNELRECT, 0, (LPARAM)lprc); - } - - void GetThumbRect(LPRECT lprc) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TBM_GETTHUMBRECT, 0, (LPARAM)lprc); - } - - int GetPos() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TBM_GETPOS, 0, 0L); - } - - void SetPos(int nPos) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TBM_SETPOS, TRUE, nPos); - } - - UINT GetNumTics() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, TBM_GETNUMTICS, 0, 0L); - } - - DWORD* GetTicArray() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD*)::SendMessage(m_hWnd, TBM_GETPTICS, 0, 0L); - } - - int GetTic(int nTic) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TBM_GETTIC, nTic, 0L); - } - - BOOL SetTic(int nTic) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TBM_SETTIC, 0, nTic); - } - - int GetTicPos(int nTic) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TBM_GETTICPOS, nTic, 0L); - } - - void SetTicFreq(int nFreq) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TBM_SETTICFREQ, nFreq, 0L); - } - - int GetThumbLength() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TBM_GETTHUMBLENGTH, 0, 0L); - } - - void SetThumbLength(int nLength) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TBM_SETTHUMBLENGTH, nLength, 0L); - } - - void SetSel(int nStart, int nEnd, BOOL bRedraw = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & TBS_ENABLESELRANGE) != 0); - ::SendMessage(m_hWnd, TBM_SETSEL, bRedraw, MAKELPARAM(nStart, nEnd)); - } - - ATL::CWindow GetBuddy(BOOL bLeft = TRUE) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return ATL::CWindow((HWND)::SendMessage(m_hWnd, TBM_GETBUDDY, bLeft, 0L)); - } - - ATL::CWindow SetBuddy(HWND hWndBuddy, BOOL bLeft = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ATL::CWindow((HWND)::SendMessage(m_hWnd, TBM_SETBUDDY, bLeft, (LPARAM)hWndBuddy)); - } - -#ifndef _WIN32_WCE - CToolTipCtrl GetToolTips() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TBM_GETTOOLTIPS, 0, 0L)); - } - - void SetToolTips(HWND hWndTT) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TBM_SETTOOLTIPS, (WPARAM)hWndTT, 0L); - } - - int SetTipSide(int nSide) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, TBM_SETTIPSIDE, nSide, 0L); - } -#endif // !_WIN32_WCE - -#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - BOOL GetUnicodeFormat() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TBM_GETUNICODEFORMAT, 0, 0L); - } - - BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, TBM_SETUNICODEFORMAT, bUnicode, 0L); - } -#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - -// Operations - void ClearSel(BOOL bRedraw = FALSE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TBM_CLEARSEL, bRedraw, 0L); - } - - void VerifyPos() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TBM_SETPOS, FALSE, 0L); - } - - void ClearTics(BOOL bRedraw = FALSE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, TBM_CLEARTICS, bRedraw, 0L); - } -}; - -typedef CTrackBarCtrlT CTrackBarCtrl; - - -/////////////////////////////////////////////////////////////////////////////// -// CUpDownCtrl - -template -class CUpDownCtrlT : public TBase -{ -public: -// Constructors - CUpDownCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CUpDownCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return UPDOWN_CLASS; - } - - UINT GetAccel(int nAccel, UDACCEL* pAccel) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)LOWORD(::SendMessage(m_hWnd, UDM_GETACCEL, nAccel, (LPARAM)pAccel)); - } - - BOOL SetAccel(int nAccel, UDACCEL* pAccel) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)LOWORD(::SendMessage(m_hWnd, UDM_SETACCEL, nAccel, (LPARAM)pAccel)); - } - - UINT GetBase() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)LOWORD(::SendMessage(m_hWnd, UDM_GETBASE, 0, 0L)); - } - - int SetBase(int nBase) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, UDM_SETBASE, nBase, 0L); - } - - ATL::CWindow GetBuddy() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return ATL::CWindow((HWND)::SendMessage(m_hWnd, UDM_GETBUDDY, 0, 0L)); - } - - ATL::CWindow SetBuddy(HWND hWndBuddy) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ATL::CWindow((HWND)::SendMessage(m_hWnd, UDM_SETBUDDY, (WPARAM)hWndBuddy, 0L)); - } - - int GetPos(LPBOOL lpbError = NULL) const - { - ATLASSERT(::IsWindow(m_hWnd)); - DWORD dwRet = (DWORD)::SendMessage(m_hWnd, UDM_GETPOS, 0, 0L); - // Note: Seems that Windows always sets error to TRUE if - // UDS_SETBUDDYINT style is not used - if(lpbError != NULL) - *lpbError = (HIWORD(dwRet) != 0) ? TRUE : FALSE; - return (int)(short)LOWORD(dwRet); - } - - int SetPos(int nPos) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)(short)LOWORD(::SendMessage(m_hWnd, UDM_SETPOS, 0, MAKELPARAM(nPos, 0))); - } - - DWORD GetRange() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, UDM_GETRANGE, 0, 0L); - } - - void GetRange(int& nLower, int& nUpper) const - { - ATLASSERT(::IsWindow(m_hWnd)); - DWORD dwRet = (DWORD)::SendMessage(m_hWnd, UDM_GETRANGE, 0, 0L); - nLower = (int)(short)HIWORD(dwRet); - nUpper = (int)(short)LOWORD(dwRet); - } - - void SetRange(int nLower, int nUpper) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, UDM_SETRANGE, 0, MAKELPARAM(nUpper, nLower)); - } - -#if (_WIN32_IE >= 0x0400) - void SetRange32(int nLower, int nUpper) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, UDM_SETRANGE32, nLower, nUpper); - } - - void GetRange32(int& nLower, int& nUpper) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, UDM_GETRANGE32, (WPARAM)&nLower, (LPARAM)&nUpper); - } - -#ifndef _WIN32_WCE - BOOL GetUnicodeFormat() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, UDM_GETUNICODEFORMAT, 0, 0L); - } - - BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, UDM_SETUNICODEFORMAT, bUnicode, 0L); - } -#endif // !_WIN32_WCE -#endif // (_WIN32_IE >= 0x0400) - -#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - int GetPos32(LPBOOL lpbError = NULL) const - { - ATLASSERT(::IsWindow(m_hWnd)); - // Note: Seems that Windows always sets error to TRUE if - // UDS_SETBUDDYINT style is not used - return (int)::SendMessage(m_hWnd, UDM_GETPOS32, 0, (LPARAM)lpbError); - } - - int SetPos32(int nPos) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, UDM_SETPOS32, 0, (LPARAM)nPos); - } -#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) -}; - -typedef CUpDownCtrlT CUpDownCtrl; - - -/////////////////////////////////////////////////////////////////////////////// -// CProgressBarCtrl - -template -class CProgressBarCtrlT : public TBase -{ -public: -// Constructors - CProgressBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CProgressBarCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return PROGRESS_CLASS; - } - - DWORD SetRange(int nLower, int nUpper) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, PBM_SETRANGE, 0, MAKELPARAM(nLower, nUpper)); - } - - int SetPos(int nPos) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)(short)LOWORD(::SendMessage(m_hWnd, PBM_SETPOS, nPos, 0L)); - } - - int OffsetPos(int nPos) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)(short)LOWORD(::SendMessage(m_hWnd, PBM_DELTAPOS, nPos, 0L)); - } - - int SetStep(int nStep) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)(short)LOWORD(::SendMessage(m_hWnd, PBM_SETSTEP, nStep, 0L)); - } - - UINT GetPos() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, PBM_GETPOS, 0, 0L); - } - - void GetRange(PPBRANGE pPBRange) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pPBRange != NULL); - ::SendMessage(m_hWnd, PBM_GETRANGE, TRUE, (LPARAM)pPBRange); - } - - void GetRange(int& nLower, int& nUpper) const - { - ATLASSERT(::IsWindow(m_hWnd)); - PBRANGE range = { 0 }; - ::SendMessage(m_hWnd, PBM_GETRANGE, TRUE, (LPARAM)&range); - nLower = range.iLow; - nUpper = range.iHigh; - } - - int GetRangeLimit(BOOL bLowLimit) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, PBM_GETRANGE, bLowLimit, (LPARAM)NULL); - } - - DWORD SetRange32(int nMin, int nMax) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, PBM_SETRANGE32, nMin, nMax); - } - -#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - COLORREF SetBarColor(COLORREF clr) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, PBM_SETBARCOLOR, 0, (LPARAM)clr); - } - - COLORREF SetBkColor(COLORREF clr) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, PBM_SETBKCOLOR, 0, (LPARAM)clr); - } -#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - -#if (_WIN32_WINNT >= 0x0501) && defined(PBM_SETMARQUEE) - BOOL SetMarquee(BOOL bMarquee, UINT uUpdateTime = 0U) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, PBM_SETMARQUEE, (WPARAM)bMarquee, (LPARAM)uUpdateTime); - } -#endif // (_WIN32_WINNT >= 0x0501) && defined(PBM_SETMARQUEE) - -#if (_WIN32_WINNT >= 0x0600) - int GetStep() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, PBM_GETSTEP, 0, 0L); - } - - COLORREF GetBkColor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, PBM_GETBKCOLOR, 0, 0L); - } - - COLORREF GetBarColor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, PBM_GETBARCOLOR, 0, 0L); - } - - int GetState() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, PBM_GETSTATE, 0, 0L); - } - - int SetState(int nState) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, PBM_SETSTATE, nState, 0L); - } -#endif // (_WIN32_WINNT >= 0x0600) - -// Operations - int StepIt() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)(short)LOWORD(::SendMessage(m_hWnd, PBM_STEPIT, 0, 0L)); - } -}; - -typedef CProgressBarCtrlT CProgressBarCtrl; - - -/////////////////////////////////////////////////////////////////////////////// -// CHotKeyCtrl - -#ifndef _WIN32_WCE - -template -class CHotKeyCtrlT : public TBase -{ -public: -// Constructors - CHotKeyCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CHotKeyCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return HOTKEY_CLASS; - } - - DWORD GetHotKey() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, HKM_GETHOTKEY, 0, 0L); - } - - void GetHotKey(WORD &wVirtualKeyCode, WORD &wModifiers) const - { - ATLASSERT(::IsWindow(m_hWnd)); - DWORD dw = (DWORD)::SendMessage(m_hWnd, HKM_GETHOTKEY, 0, 0L); - wVirtualKeyCode = LOBYTE(LOWORD(dw)); - wModifiers = HIBYTE(LOWORD(dw)); - } - - void SetHotKey(WORD wVirtualKeyCode, WORD wModifiers) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, HKM_SETHOTKEY, MAKEWORD(wVirtualKeyCode, wModifiers), 0L); - } - - void SetRules(WORD wInvalidComb, WORD wModifiers) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, HKM_SETRULES, wInvalidComb, MAKELPARAM(wModifiers, 0)); - } -}; - -typedef CHotKeyCtrlT CHotKeyCtrl; - -#endif // !_WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CAnimateCtrl - -#ifndef _WIN32_WCE - -template -class CAnimateCtrlT : public TBase -{ -public: -// Constructors - CAnimateCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CAnimateCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return ANIMATE_CLASS; - } - -// Operations - BOOL Open(ATL::_U_STRINGorID FileName) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, ACM_OPEN, 0, (LPARAM)FileName.m_lpstr); - } - - BOOL Play(UINT nFrom, UINT nTo, UINT nRep) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, ACM_PLAY, nRep, MAKELPARAM(nFrom, nTo)); - } - - BOOL Stop() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, ACM_STOP, 0, 0L); - } - - BOOL Close() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, ACM_OPEN, 0, 0L); - } - - BOOL Seek(UINT nTo) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, ACM_PLAY, 0, MAKELPARAM(nTo, nTo)); - } - - // Vista only - BOOL IsPlaying() const - { -#ifndef ACM_ISPLAYING - const UINT ACM_ISPLAYING = (WM_USER+104); -#endif - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, ACM_ISPLAYING, 0, 0L); - } -}; - -typedef CAnimateCtrlT CAnimateCtrl; - -#endif // !_WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CRichEditCtrl - -#ifndef _WIN32_WCE - -#ifdef _UNICODE -#if (_RICHEDIT_VER == 0x0100) -#undef RICHEDIT_CLASS -#define RICHEDIT_CLASS L"RICHEDIT" -#endif // (_RICHEDIT_VER == 0x0100) -#endif // _UNICODE - -template -class CRichEditCtrlT : public TBase -{ -public: -// Constructors - CRichEditCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CRichEditCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return RICHEDIT_CLASS; - } - - static LPCTSTR GetLibraryName() - { -#if (_RICHEDIT_VER >= 0x0200) - return _T("RICHED20.DLL"); -#else - return _T("RICHED32.DLL"); -#endif - } - - int GetLineCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_GETLINECOUNT, 0, 0L); - } - - BOOL GetModify() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_GETMODIFY, 0, 0L); - } - - void SetModify(BOOL bModified = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETMODIFY, bModified, 0L); - } - - void GetRect(LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_GETRECT, 0, (LPARAM)lpRect); - } - - DWORD GetOptions() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, EM_GETOPTIONS, 0, 0L); - } - - DWORD SetOptions(WORD wOperation, DWORD dwOptions) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, EM_SETOPTIONS, wOperation, dwOptions); - } - - // NOTE: first word in lpszBuffer must contain the size of the buffer! - int GetLine(int nIndex, LPTSTR lpszBuffer) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer); - } - - int GetLine(int nIndex, LPTSTR lpszBuffer, int nMaxLength) const - { - ATLASSERT(::IsWindow(m_hWnd)); - *(LPWORD)lpszBuffer = (WORD)nMaxLength; - return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer); - } - - BOOL CanUndo() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_CANUNDO, 0, 0L); - } - - BOOL CanPaste(UINT nFormat = 0) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_CANPASTE, nFormat, 0L); - } - - void GetSel(LONG& nStartChar, LONG& nEndChar) const - { - ATLASSERT(::IsWindow(m_hWnd)); - CHARRANGE cr = { 0, 0 }; - ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr); - nStartChar = cr.cpMin; - nEndChar = cr.cpMax; - } - - void GetSel(CHARRANGE &cr) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr); - } - - int SetSel(LONG nStartChar, LONG nEndChar) - { - ATLASSERT(::IsWindow(m_hWnd)); - CHARRANGE cr = { nStartChar, nEndChar }; - return (int)::SendMessage(m_hWnd, EM_EXSETSEL, 0, (LPARAM)&cr); - } - - int SetSel(CHARRANGE &cr) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_EXSETSEL, 0, (LPARAM)&cr); - } - - int SetSelAll() - { - return SetSel(0, -1); - } - - int SetSelNone() - { - return SetSel(-1, 0); - } - - DWORD GetDefaultCharFormat(CHARFORMAT& cf) const - { - ATLASSERT(::IsWindow(m_hWnd)); - cf.cbSize = sizeof(CHARFORMAT); - return (DWORD)::SendMessage(m_hWnd, EM_GETCHARFORMAT, 0, (LPARAM)&cf); - } - - DWORD GetSelectionCharFormat(CHARFORMAT& cf) const - { - ATLASSERT(::IsWindow(m_hWnd)); - cf.cbSize = sizeof(CHARFORMAT); - return (DWORD)::SendMessage(m_hWnd, EM_GETCHARFORMAT, 1, (LPARAM)&cf); - } - - DWORD GetEventMask() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, EM_GETEVENTMASK, 0, 0L); - } - - LONG GetLimitText() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (LONG)::SendMessage(m_hWnd, EM_GETLIMITTEXT, 0, 0L); - } - - DWORD GetParaFormat(PARAFORMAT& pf) const - { - ATLASSERT(::IsWindow(m_hWnd)); - pf.cbSize = sizeof(PARAFORMAT); - return (DWORD)::SendMessage(m_hWnd, EM_GETPARAFORMAT, 0, (LPARAM)&pf); - } - -#if (_RICHEDIT_VER >= 0x0200) - LONG GetSelText(LPTSTR lpstrBuff) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (LONG)::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrBuff); - } -#else // !(_RICHEDIT_VER >= 0x0200) - // RichEdit 1.0 EM_GETSELTEXT is ANSI only - LONG GetSelText(LPSTR lpstrBuff) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (LONG)::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrBuff); - } -#endif // !(_RICHEDIT_VER >= 0x0200) - -#ifndef _ATL_NO_COM - BOOL GetSelTextBSTR(BSTR& bstrText) const - { - USES_CONVERSION; - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(bstrText == NULL); - - CHARRANGE cr = { 0, 0 }; - ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr); - -#if (_RICHEDIT_VER >= 0x0200) - CTempBuffer buff; - LPTSTR lpstrText = buff.Allocate(cr.cpMax - cr.cpMin + 1); - if(lpstrText == NULL) - return FALSE; - if(::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrText) == 0) - return FALSE; - - bstrText = ::SysAllocString(T2W(lpstrText)); -#else // !(_RICHEDIT_VER >= 0x0200) - CTempBuffer buff; - LPSTR lpstrText = buff.Allocate(cr.cpMax - cr.cpMin + 1); - if(lpstrText == NULL) - return FALSE; - if(::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrText) == 0) - return FALSE; - - bstrText = ::SysAllocString(A2W(lpstrText)); -#endif // !(_RICHEDIT_VER >= 0x0200) - - return (bstrText != NULL) ? TRUE : FALSE; - } -#endif // !_ATL_NO_COM - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - LONG GetSelText(_CSTRING_NS::CString& strText) const - { - ATLASSERT(::IsWindow(m_hWnd)); - - CHARRANGE cr = { 0, 0 }; - ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr); - -#if (_RICHEDIT_VER >= 0x0200) - LONG lLen = 0; - LPTSTR lpstrText = strText.GetBufferSetLength(cr.cpMax - cr.cpMin); - if(lpstrText != NULL) - { - lLen = (LONG)::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrText); - strText.ReleaseBuffer(); - } -#else // !(_RICHEDIT_VER >= 0x0200) - CTempBuffer buff; - LPSTR lpstrText = buff.Allocate(cr.cpMax - cr.cpMin + 1); - if(lpstrText == NULL) - return 0; - LONG lLen = (LONG)::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrText); - if(lLen == 0) - return 0; - - USES_CONVERSION; - strText = A2T(lpstrText); -#endif // !(_RICHEDIT_VER >= 0x0200) - - return lLen; - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - - WORD GetSelectionType() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (WORD)::SendMessage(m_hWnd, EM_SELECTIONTYPE, 0, 0L); - } - - COLORREF SetBackgroundColor(COLORREF cr) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, EM_SETBKGNDCOLOR, 0, cr); - } - - COLORREF SetBackgroundColor() // sets to system background - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, EM_SETBKGNDCOLOR, 1, 0); - } - - BOOL SetCharFormat(CHARFORMAT& cf, WORD wFlags) - { - ATLASSERT(::IsWindow(m_hWnd)); - cf.cbSize = sizeof(CHARFORMAT); - return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, (WPARAM)wFlags, (LPARAM)&cf); - } - - BOOL SetDefaultCharFormat(CHARFORMAT& cf) - { - ATLASSERT(::IsWindow(m_hWnd)); - cf.cbSize = sizeof(CHARFORMAT); - return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, 0, (LPARAM)&cf); - } - - BOOL SetSelectionCharFormat(CHARFORMAT& cf) - { - ATLASSERT(::IsWindow(m_hWnd)); - cf.cbSize = sizeof(CHARFORMAT); - return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); - } - - BOOL SetWordCharFormat(CHARFORMAT& cf) - { - ATLASSERT(::IsWindow(m_hWnd)); - cf.cbSize = sizeof(CHARFORMAT); - return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_SELECTION | SCF_WORD, (LPARAM)&cf); - } - - DWORD SetEventMask(DWORD dwEventMask) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, EM_SETEVENTMASK, 0, dwEventMask); - } - - BOOL SetParaFormat(PARAFORMAT& pf) - { - ATLASSERT(::IsWindow(m_hWnd)); - pf.cbSize = sizeof(PARAFORMAT); - return (BOOL)::SendMessage(m_hWnd, EM_SETPARAFORMAT, 0, (LPARAM)&pf); - } - - BOOL SetTargetDevice(HDC hDC, int cxLineWidth) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_SETTARGETDEVICE, (WPARAM)hDC, cxLineWidth); - } - - int GetTextLength() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, WM_GETTEXTLENGTH, 0, 0L); - } - - BOOL SetReadOnly(BOOL bReadOnly = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_SETREADONLY, bReadOnly, 0L); - } - - int GetFirstVisibleLine() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_GETFIRSTVISIBLELINE, 0, 0L); - } - - EDITWORDBREAKPROCEX GetWordBreakProcEx() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (EDITWORDBREAKPROCEX)::SendMessage(m_hWnd, EM_GETWORDBREAKPROCEX, 0, 0L); - } - - EDITWORDBREAKPROCEX SetWordBreakProcEx(EDITWORDBREAKPROCEX pfnEditWordBreakProcEx) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (EDITWORDBREAKPROCEX)::SendMessage(m_hWnd, EM_SETWORDBREAKPROCEX, 0, (LPARAM)pfnEditWordBreakProcEx); - } - - int GetTextRange(TEXTRANGE* pTextRange) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_GETTEXTRANGE, 0, (LPARAM)pTextRange); - } - -#if (_RICHEDIT_VER >= 0x0200) - int GetTextRange(LONG nStartChar, LONG nEndChar, LPTSTR lpstrText) const - { - ATLASSERT(::IsWindow(m_hWnd)); - TEXTRANGE tr = { 0 }; - tr.chrg.cpMin = nStartChar; - tr.chrg.cpMax = nEndChar; - tr.lpstrText = lpstrText; - return (int)::SendMessage(m_hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr); - } -#else // !(_RICHEDIT_VER >= 0x0200) - - int GetTextRange(LONG nStartChar, LONG nEndChar, LPSTR lpstrText) const - { - ATLASSERT(::IsWindow(m_hWnd)); - TEXTRANGE tr = { 0 }; - tr.chrg.cpMin = nStartChar; - tr.chrg.cpMax = nEndChar; - tr.lpstrText = lpstrText; - return (int)::SendMessage(m_hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr); - } -#endif // !(_RICHEDIT_VER >= 0x0200) - -#if (_RICHEDIT_VER >= 0x0200) - DWORD GetDefaultCharFormat(CHARFORMAT2& cf) const - { - ATLASSERT(::IsWindow(m_hWnd)); - cf.cbSize = sizeof(CHARFORMAT2); - return (DWORD)::SendMessage(m_hWnd, EM_GETCHARFORMAT, 0, (LPARAM)&cf); - } - - BOOL SetCharFormat(CHARFORMAT2& cf, WORD wFlags) - { - ATLASSERT(::IsWindow(m_hWnd)); - cf.cbSize = sizeof(CHARFORMAT2); - return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, (WPARAM)wFlags, (LPARAM)&cf); - } - - BOOL SetDefaultCharFormat(CHARFORMAT2& cf) - { - ATLASSERT(::IsWindow(m_hWnd)); - cf.cbSize = sizeof(CHARFORMAT2); - return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, 0, (LPARAM)&cf); - } - - DWORD GetSelectionCharFormat(CHARFORMAT2& cf) const - { - ATLASSERT(::IsWindow(m_hWnd)); - cf.cbSize = sizeof(CHARFORMAT2); - return (DWORD)::SendMessage(m_hWnd, EM_GETCHARFORMAT, 1, (LPARAM)&cf); - } - - BOOL SetSelectionCharFormat(CHARFORMAT2& cf) - { - ATLASSERT(::IsWindow(m_hWnd)); - cf.cbSize = sizeof(CHARFORMAT2); - return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); - } - - BOOL SetWordCharFormat(CHARFORMAT2& cf) - { - ATLASSERT(::IsWindow(m_hWnd)); - cf.cbSize = sizeof(CHARFORMAT2); - return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_SELECTION | SCF_WORD, (LPARAM)&cf); - } - - DWORD GetParaFormat(PARAFORMAT2& pf) const - { - ATLASSERT(::IsWindow(m_hWnd)); - pf.cbSize = sizeof(PARAFORMAT2); - return (DWORD)::SendMessage(m_hWnd, EM_GETPARAFORMAT, 0, (LPARAM)&pf); - } - - BOOL SetParaFormat(PARAFORMAT2& pf) - { - ATLASSERT(::IsWindow(m_hWnd)); - pf.cbSize = sizeof(PARAFORMAT2); - return (BOOL)::SendMessage(m_hWnd, EM_SETPARAFORMAT, 0, (LPARAM)&pf); - } - - TEXTMODE GetTextMode() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (TEXTMODE)::SendMessage(m_hWnd, EM_GETTEXTMODE, 0, 0L); - } - - BOOL SetTextMode(TEXTMODE enumTextMode) - { - ATLASSERT(::IsWindow(m_hWnd)); - return !(BOOL)::SendMessage(m_hWnd, EM_SETTEXTMODE, enumTextMode, 0L); - } - - UNDONAMEID GetUndoName() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UNDONAMEID)::SendMessage(m_hWnd, EM_GETUNDONAME, 0, 0L); - } - - UNDONAMEID GetRedoName() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UNDONAMEID)::SendMessage(m_hWnd, EM_GETREDONAME, 0, 0L); - } - - BOOL CanRedo() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_CANREDO, 0, 0L); - } - - BOOL GetAutoURLDetect() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_GETAUTOURLDETECT, 0, 0L); - } - - BOOL SetAutoURLDetect(BOOL bAutoDetect = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return !(BOOL)::SendMessage(m_hWnd, EM_AUTOURLDETECT, bAutoDetect, 0L); - } - - // this method is deprecated, please use SetAutoURLDetect - BOOL EnableAutoURLDetect(BOOL bEnable = TRUE) { return SetAutoURLDetect(bEnable); } - - UINT SetUndoLimit(UINT uUndoLimit) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, EM_SETUNDOLIMIT, uUndoLimit, 0L); - } - - void SetPalette(HPALETTE hPalette) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETPALETTE, (WPARAM)hPalette, 0L); - } - - int GetTextEx(GETTEXTEX* pGetTextEx, LPTSTR lpstrText) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_GETTEXTEX, (WPARAM)pGetTextEx, (LPARAM)lpstrText); - } - - int GetTextEx(LPTSTR lpstrText, int nTextLen, DWORD dwFlags = GT_DEFAULT, UINT uCodePage = CP_ACP, LPCSTR lpDefaultChar = NULL, LPBOOL lpUsedDefChar = NULL) const - { - ATLASSERT(::IsWindow(m_hWnd)); - GETTEXTEX gte = { 0 }; - gte.cb = nTextLen * sizeof(TCHAR); - gte.codepage = uCodePage; - gte.flags = dwFlags; - gte.lpDefaultChar = lpDefaultChar; - gte.lpUsedDefChar = lpUsedDefChar; - return (int)::SendMessage(m_hWnd, EM_GETTEXTEX, (WPARAM)>e, (LPARAM)lpstrText); - } - - int GetTextLengthEx(GETTEXTLENGTHEX* pGetTextLengthEx) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_GETTEXTLENGTHEX, (WPARAM)pGetTextLengthEx, 0L); - } - - int GetTextLengthEx(DWORD dwFlags = GTL_DEFAULT, UINT uCodePage = CP_ACP) const - { - ATLASSERT(::IsWindow(m_hWnd)); - GETTEXTLENGTHEX gtle = { 0 }; - gtle.codepage = uCodePage; - gtle.flags = dwFlags; - return (int)::SendMessage(m_hWnd, EM_GETTEXTLENGTHEX, (WPARAM)>le, 0L); - } -#endif // (_RICHEDIT_VER >= 0x0200) - -#if (_RICHEDIT_VER >= 0x0300) - int SetTextEx(SETTEXTEX* pSetTextEx, LPCTSTR lpstrText) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_SETTEXTEX, (WPARAM)pSetTextEx, (LPARAM)lpstrText); - } - - int SetTextEx(LPCTSTR lpstrText, DWORD dwFlags = ST_DEFAULT, UINT uCodePage = CP_ACP) - { - ATLASSERT(::IsWindow(m_hWnd)); - SETTEXTEX ste = { 0 }; - ste.flags = dwFlags; - ste.codepage = uCodePage; - return (int)::SendMessage(m_hWnd, EM_SETTEXTEX, (WPARAM)&ste, (LPARAM)lpstrText); - } - - int GetEditStyle() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_GETEDITSTYLE, 0, 0L); - } - - int SetEditStyle(int nStyle, int nMask = -1) - { - ATLASSERT(::IsWindow(m_hWnd)); - if(nMask == -1) - nMask = nStyle; // set everything specified - return (int)::SendMessage(m_hWnd, EM_SETEDITSTYLE, nStyle, nMask); - } - - BOOL SetFontSize(int nFontSizeDelta) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(nFontSizeDelta >= -1637 && nFontSizeDelta <= 1638); - return (BOOL)::SendMessage(m_hWnd, EM_SETFONTSIZE, nFontSizeDelta, 0L); - } - - void GetScrollPos(LPPOINT lpPoint) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(lpPoint != NULL); - ::SendMessage(m_hWnd, EM_GETSCROLLPOS, 0, (LPARAM)lpPoint); - } - - void SetScrollPos(LPPOINT lpPoint) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(lpPoint != NULL); - ::SendMessage(m_hWnd, EM_SETSCROLLPOS, 0, (LPARAM)lpPoint); - } - - BOOL GetZoom(int& nNum, int& nDen) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_GETZOOM, (WPARAM)&nNum, (LPARAM)&nDen); - } - - BOOL SetZoom(int nNum, int nDen) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(nNum >= 0 && nNum <= 64); - ATLASSERT(nDen >= 0 && nDen <= 64); - return (BOOL)::SendMessage(m_hWnd, EM_SETZOOM, nNum, nDen); - } - - BOOL SetZoomOff() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_SETZOOM, 0, 0L); - } -#endif // (_RICHEDIT_VER >= 0x0300) - -// Operations - void LimitText(LONG nChars = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_EXLIMITTEXT, 0, nChars); - } - - int LineFromChar(LONG nIndex) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_EXLINEFROMCHAR, 0, nIndex); - } - - POINT PosFromChar(LONG nChar) const - { - ATLASSERT(::IsWindow(m_hWnd)); - POINT point = { 0, 0 }; - ::SendMessage(m_hWnd, EM_POSFROMCHAR, (WPARAM)&point, nChar); - return point; - } - - int CharFromPos(POINT pt) const - { - ATLASSERT(::IsWindow(m_hWnd)); - POINTL ptl = { pt.x, pt.y }; - return (int)::SendMessage(m_hWnd, EM_CHARFROMPOS, 0, (LPARAM)&ptl); - } - - void EmptyUndoBuffer() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_EMPTYUNDOBUFFER, 0, 0L); - } - - int LineIndex(int nLine = -1) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_LINEINDEX, nLine, 0L); - } - - int LineLength(int nLine = -1) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, EM_LINELENGTH, nLine, 0L); - } - - BOOL LineScroll(int nLines, int nChars = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_LINESCROLL, nChars, nLines); - } - - void ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo = FALSE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_REPLACESEL, (WPARAM) bCanUndo, (LPARAM)lpszNewText); - } - - void SetRect(LPCRECT lpRect) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETRECT, 0, (LPARAM)lpRect); - } - - BOOL DisplayBand(LPRECT pDisplayRect) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_DISPLAYBAND, 0, (LPARAM)pDisplayRect); - } - - LONG FindText(DWORD dwFlags, FINDTEXT& ft) const - { - ATLASSERT(::IsWindow(m_hWnd)); -#if (_RICHEDIT_VER >= 0x0200) && defined(_UNICODE) - return (LONG)::SendMessage(m_hWnd, EM_FINDTEXTW, dwFlags, (LPARAM)&ft); -#else - return (LONG)::SendMessage(m_hWnd, EM_FINDTEXT, dwFlags, (LPARAM)&ft); -#endif - } - - LONG FindText(DWORD dwFlags, FINDTEXTEX& ft) const - { - ATLASSERT(::IsWindow(m_hWnd)); -#if (_RICHEDIT_VER >= 0x0200) && defined(_UNICODE) - return (LONG)::SendMessage(m_hWnd, EM_FINDTEXTEXW, dwFlags, (LPARAM)&ft); -#else - return (LONG)::SendMessage(m_hWnd, EM_FINDTEXTEX, dwFlags, (LPARAM)&ft); -#endif - } - - LONG FormatRange(FORMATRANGE& fr, BOOL bDisplay = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (LONG)::SendMessage(m_hWnd, EM_FORMATRANGE, bDisplay, (LPARAM)&fr); - } - - LONG FormatRange(FORMATRANGE* pFormatRange, BOOL bDisplay = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (LONG)::SendMessage(m_hWnd, EM_FORMATRANGE, bDisplay, (LPARAM)pFormatRange); - } - - void HideSelection(BOOL bHide = TRUE, BOOL bChangeStyle = FALSE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_HIDESELECTION, bHide, bChangeStyle); - } - - void PasteSpecial(UINT uClipFormat, DWORD dwAspect = 0, HMETAFILE hMF = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - REPASTESPECIAL reps = { dwAspect, (DWORD_PTR)hMF }; - ::SendMessage(m_hWnd, EM_PASTESPECIAL, uClipFormat, (LPARAM)&reps); - } - - void RequestResize() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_REQUESTRESIZE, 0, 0L); - } - - LONG StreamIn(UINT uFormat, EDITSTREAM& es) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (LONG)::SendMessage(m_hWnd, EM_STREAMIN, uFormat, (LPARAM)&es); - } - - LONG StreamOut(UINT uFormat, EDITSTREAM& es) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (LONG)::SendMessage(m_hWnd, EM_STREAMOUT, uFormat, (LPARAM)&es); - } - - DWORD FindWordBreak(int nCode, LONG nStartChar) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, EM_FINDWORDBREAK, nCode, nStartChar); - } - - // Additional operations - void ScrollCaret() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L); - } - - int InsertText(long nInsertAfterChar, LPCTSTR lpstrText, BOOL bCanUndo = FALSE) - { - int nRet = SetSel(nInsertAfterChar, nInsertAfterChar); - ReplaceSel(lpstrText, bCanUndo); - return nRet; - } - - int AppendText(LPCTSTR lpstrText, BOOL bCanUndo = FALSE) - { - return InsertText(GetWindowTextLength(), lpstrText, bCanUndo); - } - - // Clipboard operations - BOOL Undo() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_UNDO, 0, 0L); - } - - void Clear() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, WM_CLEAR, 0, 0L); - } - - void Copy() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, WM_COPY, 0, 0L); - } - - void Cut() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, WM_CUT, 0, 0L); - } - - void Paste() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, WM_PASTE, 0, 0L); - } - - // OLE support - IRichEditOle* GetOleInterface() const - { - ATLASSERT(::IsWindow(m_hWnd)); - IRichEditOle *pRichEditOle = NULL; - ::SendMessage(m_hWnd, EM_GETOLEINTERFACE, 0, (LPARAM)&pRichEditOle); - return pRichEditOle; - } - - BOOL SetOleCallback(IRichEditOleCallback* pCallback) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_SETOLECALLBACK, 0, (LPARAM)pCallback); - } - -#if (_RICHEDIT_VER >= 0x0200) - BOOL Redo() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_REDO, 0, 0L); - } - - void StopGroupTyping() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_STOPGROUPTYPING, 0, 0L); - } - - void ShowScrollBar(int nBarType, BOOL bVisible = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SHOWSCROLLBAR, nBarType, bVisible); - } -#endif // (_RICHEDIT_VER >= 0x0200) - -#if (_RICHEDIT_VER >= 0x0300) - BOOL SetTabStops(int nTabStops, LPINT rgTabStops) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, nTabStops, (LPARAM)rgTabStops); - } - - BOOL SetTabStops() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 0, 0L); - } - - BOOL SetTabStops(const int& cxEachStop) // takes an 'int' - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 1, (LPARAM)(LPINT)&cxEachStop); - } -#endif // (_RICHEDIT_VER >= 0x0300) -}; - -typedef CRichEditCtrlT CRichEditCtrl; - -#endif // !_WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CRichEditCommands - message handlers for standard EDIT commands - -#ifndef _WIN32_WCE - -// Chain to CRichEditCommands message map. Your class must also derive from CRichEditCtrl. -// Example: -// class CMyRichEdit : public CWindowImpl, -// public CRichEditCommands -// { -// public: -// BEGIN_MSG_MAP(CMyRichEdit) -// // your handlers... -// CHAIN_MSG_MAP_ALT(CRichEditCommands, 1) -// END_MSG_MAP() -// // other stuff... -// }; - -template -class CRichEditCommands : public CEditCommands< T > -{ -public: - BEGIN_MSG_MAP(CRichEditCommands< T >) - ALT_MSG_MAP(1) - COMMAND_ID_HANDLER(ID_EDIT_CLEAR, CEditCommands< T >::OnEditClear) - COMMAND_ID_HANDLER(ID_EDIT_CLEAR_ALL, CEditCommands< T >::OnEditClearAll) - COMMAND_ID_HANDLER(ID_EDIT_COPY, CEditCommands< T >::OnEditCopy) - COMMAND_ID_HANDLER(ID_EDIT_CUT, CEditCommands< T >::OnEditCut) - COMMAND_ID_HANDLER(ID_EDIT_PASTE, CEditCommands< T >::OnEditPaste) - COMMAND_ID_HANDLER(ID_EDIT_SELECT_ALL, CEditCommands< T >::OnEditSelectAll) - COMMAND_ID_HANDLER(ID_EDIT_UNDO, CEditCommands< T >::OnEditUndo) -#if (_RICHEDIT_VER >= 0x0200) - COMMAND_ID_HANDLER(ID_EDIT_REDO, OnEditRedo) -#endif // (_RICHEDIT_VER >= 0x0200) - END_MSG_MAP() - -#if (_RICHEDIT_VER >= 0x0200) - LRESULT OnEditRedo(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->Redo(); - return 0; - } -#endif // (_RICHEDIT_VER >= 0x0200) - -// State (update UI) helpers - BOOL CanCut() const - { return HasSelection(); } - - BOOL CanCopy() const - { return HasSelection(); } - - BOOL CanClear() const - { return HasSelection(); } - -// Implementation - BOOL HasSelection() const - { - const T* pT = static_cast(this); - return (pT->GetSelectionType() != SEL_EMPTY); - } -}; - -#endif // _WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CDragListBox - -#ifndef _WIN32_WCE - -template -class CDragListBoxT : public CListBoxT< TBase > -{ -public: -// Constructors - CDragListBoxT(HWND hWnd = NULL) : CListBoxT< TBase >(hWnd) - { } - - CDragListBoxT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - HWND hWnd = TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - if(hWnd != NULL) - MakeDragList(); - return hWnd; - } - -// Operations - BOOL MakeDragList() - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) == 0); - return ::MakeDragList(m_hWnd); - } - - int LBItemFromPt(POINT pt, BOOL bAutoScroll = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::LBItemFromPt(m_hWnd, pt, bAutoScroll); - } - - void DrawInsert(int nItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::DrawInsert(GetParent(), m_hWnd, nItem); - } - - static UINT GetDragListMessage() - { - static UINT uDragListMessage = 0; - if(uDragListMessage == 0) - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CDragListBox::GetDragListMessage.\n")); - ATLASSERT(FALSE); - return 0; - } - - if(uDragListMessage == 0) - uDragListMessage = ::RegisterWindowMessage(DRAGLISTMSGSTRING); - - lock.Unlock(); - } - ATLASSERT(uDragListMessage != 0); - return uDragListMessage; - } -}; - -typedef CDragListBoxT CDragListBox; - -template -class CDragListNotifyImpl -{ -public: - BEGIN_MSG_MAP(CDragListNotifyImpl< T >) - MESSAGE_HANDLER(CDragListBox::GetDragListMessage(), OnDragListNotify) - END_MSG_MAP() - - LRESULT OnDragListNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - uMsg; // avoid level 4 warning - ATLASSERT(uMsg == CDragListBox::GetDragListMessage()); - T* pT = static_cast(this); - LPDRAGLISTINFO lpDragListInfo = (LPDRAGLISTINFO)lParam; - LRESULT lRet = 0; - switch(lpDragListInfo->uNotification) - { - case DL_BEGINDRAG: - lRet = (LPARAM)pT->OnBeginDrag((int)wParam, lpDragListInfo->hWnd, lpDragListInfo->ptCursor); - break; - case DL_CANCELDRAG: - pT->OnCancelDrag((int)wParam, lpDragListInfo->hWnd, lpDragListInfo->ptCursor); - break; - case DL_DRAGGING: - lRet = (LPARAM)pT->OnDragging((int)wParam, lpDragListInfo->hWnd, lpDragListInfo->ptCursor); - break; - case DL_DROPPED: - pT->OnDropped((int)wParam, lpDragListInfo->hWnd, lpDragListInfo->ptCursor); - break; - default: - ATLTRACE2(atlTraceUI, 0, _T("Unknown DragListBox notification\n")); - bHandled = FALSE; // don't handle it - break; - } - return lRet; - } - -// Overrideables - BOOL OnBeginDrag(int /*nCtlID*/, HWND /*hWndDragList*/, POINT /*ptCursor*/) - { - return TRUE; // allow dragging - } - - void OnCancelDrag(int /*nCtlID*/, HWND /*hWndDragList*/, POINT /*ptCursor*/) - { - // nothing to do - } - - int OnDragging(int /*nCtlID*/, HWND /*hWndDragList*/, POINT /*ptCursor*/) - { - return 0; // don't change cursor - } - - void OnDropped(int /*nCtlID*/, HWND /*hWndDragList*/, POINT /*ptCursor*/) - { - // nothing to do - } -}; - -#endif // _WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CReBarCtrl - -template -class CReBarCtrlT : public TBase -{ -public: -// Constructors - CReBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CReBarCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return REBARCLASSNAME; - } - - UINT GetBandCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, RB_GETBANDCOUNT, 0, 0L); - } - - BOOL GetBandInfo(int nBand, LPREBARBANDINFO lprbbi) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, RB_GETBANDINFO, nBand, (LPARAM)lprbbi); - } - - BOOL SetBandInfo(int nBand, LPREBARBANDINFO lprbbi) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, RB_SETBANDINFO, nBand, (LPARAM)lprbbi); - } - - BOOL GetBarInfo(LPREBARINFO lprbi) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, RB_GETBARINFO, 0, (LPARAM)lprbi); - } - - BOOL SetBarInfo(LPREBARINFO lprbi) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, RB_SETBARINFO, 0, (LPARAM)lprbi); - } - - CImageList GetImageList() const - { - ATLASSERT(::IsWindow(m_hWnd)); - REBARINFO rbi = { 0 }; - rbi.cbSize = sizeof(REBARINFO); - rbi.fMask = RBIM_IMAGELIST; - if( (BOOL)::SendMessage(m_hWnd, RB_GETBARINFO, 0, (LPARAM)&rbi) == FALSE ) return CImageList(); - return CImageList(rbi.himl); - } - - BOOL SetImageList(HIMAGELIST hImageList) - { - ATLASSERT(::IsWindow(m_hWnd)); - REBARINFO rbi = { 0 }; - rbi.cbSize = sizeof(REBARINFO); - rbi.fMask = RBIM_IMAGELIST; - rbi.himl = hImageList; - return (BOOL)::SendMessage(m_hWnd, RB_SETBARINFO, 0, (LPARAM)&rbi); - } - - UINT GetRowCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, RB_GETROWCOUNT, 0, 0L); - } - - UINT GetRowHeight(int nBand) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, RB_GETROWHEIGHT, nBand, 0L); - } - -#if (_WIN32_IE >= 0x0400) - COLORREF GetTextColor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, RB_GETTEXTCOLOR, 0, 0L); - } - - COLORREF SetTextColor(COLORREF clr) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, RB_SETTEXTCOLOR, 0, (LPARAM)clr); - } - - COLORREF GetBkColor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, RB_GETBKCOLOR, 0, 0L); - } - - COLORREF SetBkColor(COLORREF clr) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, RB_SETBKCOLOR, 0, (LPARAM)clr); - } - - UINT GetBarHeight() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, RB_GETBARHEIGHT, 0, 0L); - } - - BOOL GetRect(int nBand, LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, RB_GETRECT, nBand, (LPARAM)lpRect); - } - -#ifndef _WIN32_WCE - CToolTipCtrl GetToolTips() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CToolTipCtrl((HWND)::SendMessage(m_hWnd, RB_GETTOOLTIPS, 0, 0L)); - } - - void SetToolTips(HWND hwndToolTip) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, RB_SETTOOLTIPS, (WPARAM)hwndToolTip, 0L); - } -#endif // !_WIN32_WCE - - void GetBandBorders(int nBand, LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(lpRect != NULL); - ::SendMessage(m_hWnd, RB_GETBANDBORDERS, nBand, (LPARAM)lpRect); - } - -#ifndef _WIN32_WCE - BOOL GetColorScheme(LPCOLORSCHEME lpColorScheme) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(lpColorScheme != NULL); - return (BOOL)::SendMessage(m_hWnd, RB_GETCOLORSCHEME, 0, (LPARAM)lpColorScheme); - } - - void SetColorScheme(LPCOLORSCHEME lpColorScheme) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(lpColorScheme != NULL); - ::SendMessage(m_hWnd, RB_SETCOLORSCHEME, 0, (LPARAM)lpColorScheme); - } - - HPALETTE GetPalette() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HPALETTE)::SendMessage(m_hWnd, RB_GETPALETTE, 0, 0L); - } - - HPALETTE SetPalette(HPALETTE hPalette) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HPALETTE)::SendMessage(m_hWnd, RB_SETPALETTE, 0, (LPARAM)hPalette); - } - - BOOL GetUnicodeFormat() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, RB_GETUNICODEFORMAT, 0, 0L); - } - - BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, RB_SETUNICODEFORMAT, bUnicode, 0L); - } -#endif // !_WIN32_WCE -#endif // (_WIN32_IE >= 0x0400) - -#if (_WIN32_WINNT >= 0x0501) - // requires uxtheme.h to be included to use MARGINS struct -#ifndef _UXTHEME_H_ - typedef struct _MARGINS* PMARGINS; -#endif // !_UXTHEME_H_ - void GetBandMargins(PMARGINS pMargins) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, RB_GETBANDMARGINS, 0, (LPARAM)pMargins); - } - - void SetWindowTheme(LPCWSTR lpstrTheme) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, RB_SETWINDOWTHEME, 0, (LPARAM)lpstrTheme); - } -#endif // (_WIN32_WINNT >= 0x0501) - -#if (_WIN32_IE >= 0x0600) - DWORD GetExtendedStyle() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, RB_GETEXTENDEDSTYLE, 0, 0L); - } - - DWORD SetExtendedStyle(DWORD dwStyle, DWORD dwMask) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, RB_SETEXTENDEDSTYLE, dwMask, dwStyle); - } -#endif // (_WIN32_IE >= 0x0600) - -// Operations - BOOL InsertBand(int nBand, LPREBARBANDINFO lprbbi) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, RB_INSERTBAND, nBand, (LPARAM)lprbbi); - } - - BOOL AddBand(LPREBARBANDINFO lprbbi) - { - return InsertBand(-1, lprbbi); - } - - BOOL DeleteBand(int nBand) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, RB_DELETEBAND, nBand, 0L); - } - - ATL::CWindow SetNotifyWnd(HWND hWnd) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ATL::CWindow((HWND)::SendMessage(m_hWnd, RB_SETPARENT, (WPARAM)hWnd, 0L)); - } - -#if (_WIN32_IE >= 0x0400) - void BeginDrag(int nBand, DWORD dwPos) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, RB_BEGINDRAG, nBand, dwPos); - } - - void BeginDrag(int nBand, int xPos, int yPos) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, RB_BEGINDRAG, nBand, MAKELPARAM(xPos, yPos)); - } - - void EndDrag() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, RB_ENDDRAG, 0, 0L); - } - - void DragMove(DWORD dwPos) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, RB_DRAGMOVE, 0, dwPos); - } - - void DragMove(int xPos, int yPos) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, RB_DRAGMOVE, 0, MAKELPARAM(xPos, yPos)); - } - -#ifndef _WIN32_WCE - void GetDropTarget(IDropTarget** ppDropTarget) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, RB_GETDROPTARGET, 0, (LPARAM)ppDropTarget); - } -#endif // !_WIN32_WCE - - void MaximizeBand(int nBand, BOOL bIdeal = FALSE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, RB_MAXIMIZEBAND, nBand, bIdeal); - } - - void MinimizeBand(int nBand) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, RB_MINIMIZEBAND, nBand, 0L); - } - - BOOL SizeToRect(LPRECT lpRect) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, RB_SIZETORECT, 0, (LPARAM)lpRect); - } - - int IdToIndex(UINT uBandID) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, RB_IDTOINDEX, uBandID, 0L); - } - - int HitTest(LPRBHITTESTINFO lprbht) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, RB_HITTEST, 0, (LPARAM)lprbht); - } - - BOOL ShowBand(int nBand, BOOL bShow) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, RB_SHOWBAND, nBand, bShow); - } - -#ifndef _WIN32_WCE - BOOL MoveBand(int nBand, int nNewPos) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(nNewPos >= 0 && nNewPos <= ((int)GetBandCount() - 1)); - return (BOOL)::SendMessage(m_hWnd, RB_MOVEBAND, nBand, nNewPos); - } -#endif // !_WIN32_WCE -#endif // (_WIN32_IE >= 0x0400) - -#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - void PushChevron(int nBand, LPARAM lAppValue) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, RB_PUSHCHEVRON, nBand, lAppValue); - } -#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - -// Extra operations -#if (_WIN32_IE >= 0x0400) - void LockBands(bool bLock) - { - int nBandCount = GetBandCount(); - for(int i =0; i < nBandCount; i++) - { - REBARBANDINFO rbbi = { RunTimeHelper::SizeOf_REBARBANDINFO() }; - rbbi.fMask = RBBIM_STYLE; - BOOL bRet = GetBandInfo(i, &rbbi); - ATLASSERT(bRet); - - if((rbbi.fStyle & RBBS_GRIPPERALWAYS) == 0) - { - rbbi.fStyle |= RBBS_GRIPPERALWAYS; - bRet = SetBandInfo(i, &rbbi); - ATLASSERT(bRet); - rbbi.fStyle &= ~RBBS_GRIPPERALWAYS; - } - - if(bLock) - rbbi.fStyle |= RBBS_NOGRIPPER; - else - rbbi.fStyle &= ~RBBS_NOGRIPPER; - - bRet = SetBandInfo(i, &rbbi); - ATLASSERT(bRet); - } - } -#endif // (_WIN32_IE >= 0x0400) - -#if (_WIN32_WINNT >= 0x0600) - BOOL SetBandWidth(int nBand, int cxWidth) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, RB_SETBANDWIDTH, nBand, cxWidth); - } -#endif // (_WIN32_WINNT >= 0x0600) -}; - -typedef CReBarCtrlT CReBarCtrl; - - -/////////////////////////////////////////////////////////////////////////////// -// CComboBoxEx - -#ifndef _WIN32_WCE - -template -class CComboBoxExT : public CComboBoxT< TBase > -{ -public: -// Constructors - CComboBoxExT(HWND hWnd = NULL) : CComboBoxT< TBase >(hWnd) - { } - - CComboBoxExT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return WC_COMBOBOXEX; - } - - CImageList GetImageList() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, CBEM_GETIMAGELIST, 0, 0L)); - } - - CImageList SetImageList(HIMAGELIST hImageList) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CImageList((HIMAGELIST)::SendMessage(m_hWnd, CBEM_SETIMAGELIST, 0, (LPARAM)hImageList)); - } - -#if (_WIN32_IE >= 0x0400) - DWORD GetExtendedStyle() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, CBEM_GETEXTENDEDSTYLE, 0, 0L); - } - - DWORD SetExtendedStyle(DWORD dwExMask, DWORD dwExStyle) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, CBEM_SETEXTENDEDSTYLE, dwExMask, dwExStyle); - } - - BOOL GetUnicodeFormat() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, CBEM_GETUNICODEFORMAT, 0, 0L); - } - - BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, CBEM_SETUNICODEFORMAT, bUnicode, 0L); - } -#endif // (_WIN32_IE >= 0x0400) - -#if (_WIN32_WINNT >= 0x0501) - void SetWindowTheme(LPCWSTR lpstrTheme) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, CBEM_SETWINDOWTHEME, 0, (LPARAM)lpstrTheme); - } -#endif // (_WIN32_WINNT >= 0x0501) - -// Operations - int InsertItem(const COMBOBOXEXITEM* lpcCBItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CBEM_INSERTITEM, 0, (LPARAM)lpcCBItem); - } - - int InsertItem(UINT nMask, int nIndex, LPCTSTR lpszItem, int nImage, int nSelImage, - int iIndent, int iOverlay, LPARAM lParam) - { - ATLASSERT(::IsWindow(m_hWnd)); - COMBOBOXEXITEM cbex = { 0 }; - cbex.mask = nMask; - cbex.iItem = nIndex; - cbex.pszText = (LPTSTR) lpszItem; - cbex.iImage = nImage; - cbex.iSelectedImage = nSelImage; - cbex.iIndent = iIndent; - cbex.iOverlay = iOverlay; - cbex.lParam = lParam; - return (int)::SendMessage(m_hWnd, CBEM_INSERTITEM, 0, (LPARAM)&cbex); - } - - int InsertItem(int nIndex, LPCTSTR lpszItem, int nImage, int nSelImage, int iIndent, LPARAM lParam = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - COMBOBOXEXITEM cbex = { 0 }; - cbex.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_INDENT | CBEIF_LPARAM; - cbex.iItem = nIndex; - cbex.pszText = (LPTSTR) lpszItem; - cbex.iImage = nImage; - cbex.iSelectedImage = nSelImage; - cbex.iIndent = iIndent; - cbex.lParam = lParam; - return (int)::SendMessage(m_hWnd, CBEM_INSERTITEM, 0, (LPARAM)&cbex); - } - - int AddItem(UINT nMask, LPCTSTR lpszItem, int nImage, int nSelImage, int iIndent, int iOverlay, LPARAM lParam) - { - return InsertItem(nMask, -1, lpszItem, nImage, nSelImage, iIndent, iOverlay, lParam); - } - - int AddItem(LPCTSTR lpszItem, int nImage, int nSelImage, int iIndent, LPARAM lParam = 0) - { - return InsertItem(-1, lpszItem, nImage, nSelImage, iIndent, lParam); - } - - int DeleteItem(int nIndex) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, CBEM_DELETEITEM, nIndex, 0L); - } - - BOOL GetItem(PCOMBOBOXEXITEM pCBItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, CBEM_GETITEM, 0, (LPARAM)pCBItem); - } - - BOOL SetItem(const COMBOBOXEXITEM* lpcCBItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, CBEM_SETITEM, 0, (LPARAM)lpcCBItem); - } - - int SetItem(int nIndex, UINT nMask, LPCTSTR lpszItem, int nImage, int nSelImage, - int iIndent, int iOverlay, LPARAM lParam) - { - ATLASSERT(::IsWindow(m_hWnd)); - COMBOBOXEXITEM cbex = { 0 }; - cbex.mask = nMask; - cbex.iItem = nIndex; - cbex.pszText = (LPTSTR) lpszItem; - cbex.iImage = nImage; - cbex.iSelectedImage = nSelImage; - cbex.iIndent = iIndent; - cbex.iOverlay = iOverlay; - cbex.lParam = lParam; - return (int)::SendMessage(m_hWnd, CBEM_SETITEM, 0, (LPARAM)&cbex); - } - - BOOL GetItemText(int nIndex, LPTSTR lpszItem, int nLen) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(lpszItem != NULL); - - COMBOBOXEXITEM cbex = { 0 }; - cbex.mask = CBEIF_TEXT; - cbex.iItem = nIndex; - cbex.pszText = lpszItem; - cbex.cchTextMax = nLen; - - return (BOOL)::SendMessage(m_hWnd, CBEM_GETITEM, 0, (LPARAM)&cbex); - } - -#ifndef _ATL_NO_COM - BOOL GetItemText(int nIndex, BSTR& bstrText) const - { - USES_CONVERSION; - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(bstrText == NULL); - - COMBOBOXEXITEM cbex = { 0 }; - cbex.mask = CBEIF_TEXT; - cbex.iItem = nIndex; - - LPTSTR lpstrText = NULL; - BOOL bRet = FALSE; - for(int nLen = 256; ; nLen *= 2) - { - ATLTRY(lpstrText = new TCHAR[nLen]); - if(lpstrText == NULL) - break; - lpstrText[0] = NULL; - cbex.pszText = lpstrText; - cbex.cchTextMax = nLen; - bRet = (BOOL)::SendMessage(m_hWnd, CBEM_GETITEM, 0, (LPARAM)&cbex); - if(!bRet || (lstrlen(cbex.pszText) < nLen - 1)) - break; - delete [] lpstrText; - lpstrText = NULL; - } - - if(lpstrText != NULL) - { - if(bRet) - bstrText = ::SysAllocString(T2OLE(lpstrText)); - delete [] lpstrText; - } - - return (bstrText != NULL) ? TRUE : FALSE; - } -#endif // !_ATL_NO_COM - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - BOOL GetItemText(int nIndex, _CSTRING_NS::CString& strText) const - { - ATLASSERT(::IsWindow(m_hWnd)); - - COMBOBOXEXITEM cbex = { 0 }; - cbex.mask = CBEIF_TEXT; - cbex.iItem = nIndex; - - strText.Empty(); - BOOL bRet = FALSE; - for(int nLen = 256; ; nLen *= 2) - { - cbex.pszText = strText.GetBufferSetLength(nLen); - if(cbex.pszText == NULL) - { - bRet = FALSE; - break; - } - cbex.cchTextMax = nLen; - bRet = (BOOL)::SendMessage(m_hWnd, CBEM_GETITEM, 0, (LPARAM)&cbex); - if(!bRet || (lstrlen(cbex.pszText) < nLen - 1)) - break; - } - strText.ReleaseBuffer(); - return bRet; - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - - BOOL SetItemText(int nIndex, LPCTSTR lpszItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return SetItem(nIndex, CBEIF_TEXT, lpszItem, 0, 0, 0, 0, 0); - } - - CComboBox GetComboCtrl() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CComboBox((HWND)::SendMessage(m_hWnd, CBEM_GETCOMBOCONTROL, 0, 0L)); - } - - CEdit GetEditCtrl() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CEdit((HWND)::SendMessage(m_hWnd, CBEM_GETEDITCONTROL, 0, 0L)); - } - - BOOL HasEditChanged() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, CBEM_HASEDITCHANGED, 0, 0L); - } - -// Non-functional - int AddString(LPCTSTR /*lpszItem*/) - { - ATLASSERT(FALSE); // Not available in CComboBoxEx; use InsertItem - return 0; - } - - int InsertString(int /*nIndex*/, LPCTSTR /*lpszString*/) - { - ATLASSERT(FALSE); // Not available in CComboBoxEx; use InsertItem - return 0; - } - - int Dir(UINT /*attr*/, LPCTSTR /*lpszWildCard*/) - { - ATLASSERT(FALSE); // Not available in CComboBoxEx - return 0; - } - - int FindString(int /*nStartAfter*/, LPCTSTR /*lpszString*/) const - { - ATLASSERT(FALSE); // Not available in CComboBoxEx; try FindStringExact - return 0; - } -}; - -typedef CComboBoxExT CComboBoxEx; - -#endif // !_WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CMonthCalendarCtrl - -template -class CMonthCalendarCtrlT : public TBase -{ -public: -// Constructors - CMonthCalendarCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CMonthCalendarCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return MONTHCAL_CLASS; - } - - COLORREF GetColor(int nColorType) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, MCM_GETCOLOR, nColorType, 0L); - } - - COLORREF SetColor(int nColorType, COLORREF clr) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, MCM_SETCOLOR, nColorType, clr); - } - - BOOL GetCurSel(LPSYSTEMTIME lpSysTime) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, MCM_GETCURSEL, 0, (LPARAM)lpSysTime); - } - - BOOL SetCurSel(LPSYSTEMTIME lpSysTime) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, MCM_SETCURSEL, 0, (LPARAM)lpSysTime); - } - - int GetFirstDayOfWeek(BOOL* pbLocaleVal = NULL) const - { - ATLASSERT(::IsWindow(m_hWnd)); - DWORD dwRet = (DWORD)::SendMessage(m_hWnd, MCM_GETFIRSTDAYOFWEEK, 0, 0L); - if(pbLocaleVal != NULL) - *pbLocaleVal = (BOOL)HIWORD(dwRet); - return (int)(short)LOWORD(dwRet); - } - - int SetFirstDayOfWeek(int nDay, BOOL* pbLocaleVal = NULL) - { - ATLASSERT(::IsWindow(m_hWnd)); - DWORD dwRet = (DWORD)::SendMessage(m_hWnd, MCM_SETFIRSTDAYOFWEEK, 0, nDay); - if(pbLocaleVal != NULL) - *pbLocaleVal = (BOOL)HIWORD(dwRet); - return (int)(short)LOWORD(dwRet); - } - - int GetMaxSelCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, MCM_GETMAXSELCOUNT, 0, 0L); - } - - BOOL SetMaxSelCount(int nMax) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, MCM_SETMAXSELCOUNT, nMax, 0L); - } - - int GetMonthDelta() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, MCM_GETMONTHDELTA, 0, 0L); - } - - int SetMonthDelta(int nDelta) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, MCM_SETMONTHDELTA, nDelta, 0L); - } - - DWORD GetRange(LPSYSTEMTIME lprgSysTimeArray) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, MCM_GETRANGE, 0, (LPARAM)lprgSysTimeArray); - } - - BOOL SetRange(DWORD dwFlags, LPSYSTEMTIME lprgSysTimeArray) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, MCM_SETRANGE, dwFlags, (LPARAM)lprgSysTimeArray); - } - - BOOL GetSelRange(LPSYSTEMTIME lprgSysTimeArray) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, MCM_GETSELRANGE, 0, (LPARAM)lprgSysTimeArray); - } - - BOOL SetSelRange(LPSYSTEMTIME lprgSysTimeArray) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, MCM_SETSELRANGE, 0, (LPARAM)lprgSysTimeArray); - } - - BOOL GetToday(LPSYSTEMTIME lpSysTime) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, MCM_GETTODAY, 0, (LPARAM)lpSysTime); - } - - void SetToday(LPSYSTEMTIME lpSysTime) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, MCM_SETTODAY, 0, (LPARAM)lpSysTime); - } - - BOOL GetMinReqRect(LPRECT lpRectInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, MCM_GETMINREQRECT, 0, (LPARAM)lpRectInfo); - } - - int GetMaxTodayWidth() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, MCM_GETMAXTODAYWIDTH, 0, 0L); - } - -#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - BOOL GetUnicodeFormat() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, MCM_GETUNICODEFORMAT, 0, 0L); - } - - BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, MCM_SETUNICODEFORMAT, bUnicode, 0L); - } -#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - -#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) - DWORD GetCurrentView() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, MCM_GETCURRENTVIEW, 0, 0L); - } - - BOOL SetCurrentView(DWORD dwView) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, MCM_SETCURRENTVIEW, 0, dwView); - } - - DWORD GetCalendarCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, MCM_GETCALENDARCOUNT, 0, 0L); - } - - BOOL GetCalendarGridInfo(PMCGRIDINFO pGridInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, MCM_GETCALENDARGRIDINFO, 0, (LPARAM)pGridInfo); - } - - CALID GetCALID() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (CALID)::SendMessage(m_hWnd, MCM_GETCALID, 0, 0L); - } - - void SetCALID(CALID calid) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, MCM_SETCALID, (LPARAM)calid, 0L); - } - - int GetCalendarBorder() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, MCM_GETCALENDARBORDER, 0, 0L); - } - - void SetCalendarBorder(int cxyBorder, BOOL bSet = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, MCM_SETCALENDARBORDER, (WPARAM)bSet, (LPARAM)cxyBorder); - } -#endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) - -// Operations - int GetMonthRange(DWORD dwFlags, LPSYSTEMTIME lprgSysTimeArray) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, MCM_GETMONTHRANGE, dwFlags, (LPARAM)lprgSysTimeArray); - } - - BOOL SetDayState(int nMonths, LPMONTHDAYSTATE lpDayStateArray) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, MCM_SETDAYSTATE, nMonths, (LPARAM)lpDayStateArray); - } - - DWORD HitTest(PMCHITTESTINFO pMCHitTest) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, MCM_HITTEST, 0, (LPARAM)pMCHitTest); - } - -#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) - void SizeRectToMin(LPRECT lpRect) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, MCM_SIZERECTTOMIN, 0, (LPARAM)lpRect); - } -#endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) -}; - -typedef CMonthCalendarCtrlT CMonthCalendarCtrl; - - -/////////////////////////////////////////////////////////////////////////////// -// CDateTimePickerCtrl - -template -class CDateTimePickerCtrlT : public TBase -{ -public: -// Constructors - CDateTimePickerCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CDateTimePickerCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Operations - static LPCTSTR GetWndClassName() - { - return DATETIMEPICK_CLASS; - } - - BOOL SetFormat(LPCTSTR lpszFormat) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, DTM_SETFORMAT, 0, (LPARAM)lpszFormat); - } - - COLORREF GetMonthCalColor(int nColorType) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, DTM_GETMCCOLOR, nColorType, 0L); - } - - COLORREF SetMonthCalColor(int nColorType, COLORREF clr) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, DTM_SETMCCOLOR, nColorType, clr); - } - - DWORD GetRange(LPSYSTEMTIME lpSysTimeArray) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, DTM_GETRANGE, 0, (LPARAM)lpSysTimeArray); - } - - BOOL SetRange(DWORD dwFlags, LPSYSTEMTIME lpSysTimeArray) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, DTM_SETRANGE, dwFlags, (LPARAM)lpSysTimeArray); - } - - DWORD GetSystemTime(LPSYSTEMTIME lpSysTime) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)lpSysTime); - } - - BOOL SetSystemTime(DWORD dwFlags, LPSYSTEMTIME lpSysTime) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, DTM_SETSYSTEMTIME, dwFlags, (LPARAM)lpSysTime); - } - - CMonthCalendarCtrl GetMonthCal() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CMonthCalendarCtrl((HWND)::SendMessage(m_hWnd, DTM_GETMONTHCAL, 0, 0L)); - } - -#if (_WIN32_IE >= 0x0400) - CFontHandle GetMonthCalFont() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CFontHandle((HFONT)::SendMessage(m_hWnd, DTM_GETMCFONT, 0, 0L)); - } - - void SetMonthCalFont(HFONT hFont, BOOL bRedraw = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_SETMCFONT, (WPARAM)hFont, MAKELPARAM(bRedraw, 0)); - } -#endif // (_WIN32_IE >= 0x0400) - -#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) - DWORD GetMonthCalStyle() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, DTM_GETMCSTYLE, 0, 0L); - } - - DWORD SetMonthCalStyle(DWORD dwStyle) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (DWORD)::SendMessage(m_hWnd, DTM_SETMCSTYLE, 0, (LPARAM)dwStyle); - } - - void GetDateTimePickerInfo(LPDATETIMEPICKERINFO lpPickerInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_GETDATETIMEPICKERINFO, 0, (LPARAM)lpPickerInfo); - } - - BOOL GetIdealSize(LPSIZE lpSize) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, DTM_GETIDEALSIZE, 0, (LPARAM)lpSize); - } - - void CloseMonthCal() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_CLOSEMONTHCAL, 0, 0L); - } -#endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) -}; - -typedef CDateTimePickerCtrlT CDateTimePickerCtrl; - - -/////////////////////////////////////////////////////////////////////////////// -// CFlatScrollBarImpl - support for flat scroll bars - -#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - -template -class CFlatScrollBarImpl -{ -public: -// Initialization - BOOL FlatSB_Initialize() - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::InitializeFlatSB(pT->m_hWnd); - } - - HRESULT FlatSB_Uninitialize() - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::UninitializeFlatSB(pT->m_hWnd); - } - -// Flat scroll bar properties - BOOL FlatSB_GetScrollProp(UINT uIndex, LPINT lpnValue) const - { - const T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::FlatSB_GetScrollProp(pT->m_hWnd, uIndex, lpnValue); - } - - BOOL FlatSB_SetScrollProp(UINT uIndex, int nValue, BOOL bRedraw = TRUE) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::FlatSB_SetScrollProp(pT->m_hWnd, uIndex, nValue, bRedraw); - } - -// Attributes - int FlatSB_GetScrollPos(int nBar) const - { - const T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::FlatSB_GetScrollPos(pT->m_hWnd, nBar); - } - - int FlatSB_SetScrollPos(int nBar, int nPos, BOOL bRedraw = TRUE) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::FlatSB_SetScrollPos(pT->m_hWnd, nBar, nPos, bRedraw); - } - - BOOL FlatSB_GetScrollRange(int nBar, LPINT lpMinPos, LPINT lpMaxPos) const - { - const T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::FlatSB_GetScrollRange(pT->m_hWnd, nBar, lpMinPos, lpMaxPos); - } - - BOOL FlatSB_SetScrollRange(int nBar, int nMinPos, int nMaxPos, BOOL bRedraw = TRUE) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::FlatSB_SetScrollRange(pT->m_hWnd, nBar, nMinPos, nMaxPos, bRedraw); - } - - BOOL FlatSB_GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo) const - { - const T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::FlatSB_GetScrollInfo(pT->m_hWnd, nBar, lpScrollInfo); - } - - int FlatSB_SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::FlatSB_SetScrollInfo(pT->m_hWnd, nBar, lpScrollInfo, bRedraw); - } - -// Operations - BOOL FlatSB_ShowScrollBar(UINT nBar, BOOL bShow = TRUE) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::FlatSB_ShowScrollBar(pT->m_hWnd, nBar, bShow); - } - - BOOL FlatSB_EnableScrollBar(UINT uSBFlags, UINT uArrowFlags = ESB_ENABLE_BOTH) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::FlatSB_EnableScrollBar(pT->m_hWnd, uSBFlags, uArrowFlags); - } -}; - -template -class CFlatScrollBarT : public TBase, public CFlatScrollBarImpl > -{ -public: - CFlatScrollBarT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CFlatScrollBarT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } -}; - -typedef CFlatScrollBarT CFlatScrollBar; - -#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - - -/////////////////////////////////////////////////////////////////////////////// -// CIPAddressCtrl - -#if (_WIN32_IE >= 0x0400) - -template -class CIPAddressCtrlT : public TBase -{ -public: -// Constructors - CIPAddressCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CIPAddressCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Atteributes - static LPCTSTR GetWndClassName() - { - return WC_IPADDRESS; - } - - BOOL IsBlank() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, IPM_ISBLANK, 0, 0L); - } - - int GetAddress(LPDWORD lpdwAddress) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, IPM_GETADDRESS, 0, (LPARAM)lpdwAddress); - } - - void SetAddress(DWORD dwAddress) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, IPM_SETADDRESS, 0, dwAddress); - } - - void ClearAddress() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, IPM_CLEARADDRESS, 0, 0L); - } - - void SetRange(int nField, WORD wRange) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, IPM_SETRANGE, nField, wRange); - } - - void SetRange(int nField, BYTE nMin, BYTE nMax) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, IPM_SETRANGE, nField, MAKEIPRANGE(nMin, nMax)); - } - - void SetFocus(int nField) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, IPM_SETFOCUS, nField, 0L); - } -}; - -typedef CIPAddressCtrlT CIPAddressCtrl; - -#endif // (_WIN32_IE >= 0x0400) - - -/////////////////////////////////////////////////////////////////////////////// -// CPagerCtrl - -#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - -template -class CPagerCtrlT : public TBase -{ -public: -// Constructors - CPagerCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CPagerCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return WC_PAGESCROLLER; - } - - int GetButtonSize() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, PGM_GETBUTTONSIZE, 0, 0L); - } - - int SetButtonSize(int nButtonSize) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, PGM_SETBUTTONSIZE, 0, nButtonSize); - } - - DWORD GetButtonState(int nButton) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(nButton == PGB_TOPORLEFT || nButton == PGB_BOTTOMORRIGHT); - return (DWORD)::SendMessage(m_hWnd, PGM_GETBUTTONSTATE, 0, nButton); - } - - COLORREF GetBkColor() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, PGM_GETBKCOLOR, 0, 0L); - } - - COLORREF SetBkColor(COLORREF clrBk) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (COLORREF)::SendMessage(m_hWnd, PGM_SETBKCOLOR, 0, (LPARAM)clrBk); - } - - int GetBorder() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, PGM_GETBORDER, 0, 0L); - } - - int SetBorder(int nBorderSize) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, PGM_SETBORDER, 0, nBorderSize); - } - - int GetPos() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, PGM_GETPOS, 0, 0L); - } - - int SetPos(int nPos) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, PGM_SETPOS, 0, nPos); - } - -// Operations - void SetChild(HWND hWndChild) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, PGM_SETCHILD, 0, (LPARAM)hWndChild); - } - - void ForwardMouse(BOOL bForward = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, PGM_FORWARDMOUSE, bForward, 0L); - } - - void RecalcSize() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, PGM_RECALCSIZE, 0, 0L); - } - - void GetDropTarget(IDropTarget** ppDropTarget) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(ppDropTarget != NULL); - ::SendMessage(m_hWnd, PGM_GETDROPTARGET, 0, (LPARAM)ppDropTarget); - } -}; - -typedef CPagerCtrlT CPagerCtrl; - -#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - - -/////////////////////////////////////////////////////////////////////////////// -// CLinkCtrl - Windows SYSLINK control - -#if (_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE) - -template -class CLinkCtrlT : public TBase -{ -public: -// Constructors - CLinkCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CLinkCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - } - -// Attributes - static LPCTSTR GetWndClassName() - { -#ifdef _UNICODE - return WC_LINK; -#else // !_UNICODE - return "SysLink"; -#endif // !_UNICODE - } - - int GetIdealHeight(int cxMaxWidth = 0) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LM_GETIDEALHEIGHT, cxMaxWidth, 0L); - } - - BOOL GetItem(PLITEM pLItem) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LM_GETITEM, 0, (LPARAM)pLItem); - } - - BOOL SetItem(PLITEM pLItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LM_SETITEM, 0, (LPARAM)pLItem); - } - - // Vista only - int GetIdealSize(SIZE& size, int cxMaxWidth = 0) const - { -#ifndef LM_GETIDEALSIZE - const UINT LM_GETIDEALSIZE = LM_GETIDEALHEIGHT; -#endif - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, LM_GETIDEALSIZE, cxMaxWidth, (LPARAM)&size); - } - -// Operations - BOOL HitTest(PLHITTESTINFO pLHitTestInfo) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, LM_HITTEST, 0, (LPARAM)pLHitTestInfo); - } -}; - -typedef CLinkCtrlT CLinkCtrl; - -#endif // (_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE) - - -/////////////////////////////////////////////////////////////////////////////// -// CCustomDraw - MI class for custom-draw support - -template -class CCustomDraw -{ -public: -#if (_ATL_VER < 0x0700) - BOOL m_bHandledCD; - - BOOL IsMsgHandled() const - { - return m_bHandledCD; - } - - void SetMsgHandled(BOOL bHandled) - { - m_bHandledCD = bHandled; - } -#endif // !(_ATL_VER < 0x0700) - -// Message map and handlers - BEGIN_MSG_MAP(CCustomDraw< T >) - NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw) - ALT_MSG_MAP(1) - REFLECTED_NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw) - END_MSG_MAP() - -// message handler - LRESULT OnCustomDraw(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) - { - T* pT = static_cast(this); - pT->SetMsgHandled(TRUE); - LPNMCUSTOMDRAW lpNMCustomDraw = (LPNMCUSTOMDRAW)pnmh; - DWORD dwRet = 0; - switch(lpNMCustomDraw->dwDrawStage) - { - case CDDS_PREPAINT: - dwRet = pT->OnPrePaint(idCtrl, lpNMCustomDraw); - break; - case CDDS_POSTPAINT: - dwRet = pT->OnPostPaint(idCtrl, lpNMCustomDraw); - break; - case CDDS_PREERASE: - dwRet = pT->OnPreErase(idCtrl, lpNMCustomDraw); - break; - case CDDS_POSTERASE: - dwRet = pT->OnPostErase(idCtrl, lpNMCustomDraw); - break; - case CDDS_ITEMPREPAINT: - dwRet = pT->OnItemPrePaint(idCtrl, lpNMCustomDraw); - break; - case CDDS_ITEMPOSTPAINT: - dwRet = pT->OnItemPostPaint(idCtrl, lpNMCustomDraw); - break; - case CDDS_ITEMPREERASE: - dwRet = pT->OnItemPreErase(idCtrl, lpNMCustomDraw); - break; - case CDDS_ITEMPOSTERASE: - dwRet = pT->OnItemPostErase(idCtrl, lpNMCustomDraw); - break; -#if (_WIN32_IE >= 0x0400) - case (CDDS_ITEMPREPAINT | CDDS_SUBITEM): - dwRet = pT->OnSubItemPrePaint(idCtrl, lpNMCustomDraw); - break; -#endif // (_WIN32_IE >= 0x0400) - default: - pT->SetMsgHandled(FALSE); - break; - } - bHandled = pT->IsMsgHandled(); - return dwRet; - } - -// Overrideables - DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) - { - return CDRF_DODEFAULT; - } - - DWORD OnPostPaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) - { - return CDRF_DODEFAULT; - } - - DWORD OnPreErase(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) - { - return CDRF_DODEFAULT; - } - - DWORD OnPostErase(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) - { - return CDRF_DODEFAULT; - } - - DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) - { - return CDRF_DODEFAULT; - } - - DWORD OnItemPostPaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) - { - return CDRF_DODEFAULT; - } - - DWORD OnItemPreErase(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) - { - return CDRF_DODEFAULT; - } - - DWORD OnItemPostErase(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) - { - return CDRF_DODEFAULT; - } - -#if (_WIN32_IE >= 0x0400) - DWORD OnSubItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) - { - return CDRF_DODEFAULT; - } -#endif // (_WIN32_IE >= 0x0400) -}; - - -// --- Windows CE common controls --- - -#ifdef _WIN32_WCE - -/////////////////////////////////////////////////////////////////////////////// -// CCECommandBarCtrl - -template -class CCECommandBarCtrlT : public TBase -{ -public: -// Constructors - CCECommandBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) { } - - CCECommandBarCtrlT< TBase >& operator=(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - -// Attributes - BOOL IsVisible() const - { - return IsWindowVisible(); - } - - int GetHeight() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::CommandBar_Height(m_hWnd); - } - - HMENU GetMenu(WORD wButton) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::CommandBar_GetMenu(m_hWnd, wButton); - } - -// Operations - HWND Create(HWND hWndParent, int nCmdBarID) - { - m_hWnd = ::CommandBar_Create(ModuleHelper::GetModuleInstance(), hWndParent, nCmdBarID); - ATLASSERT(::IsWindow(m_hWnd)); - return m_hWnd; - } - - void Destroy() - { - DestroyWindow(); - } - - BOOL Show(BOOL bShow = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::CommandBar_Show(m_hWnd, bShow); - } - - BOOL DrawMenuBar(WORD wButton) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::CommandBar_DrawMenuBar(m_hWnd, wButton); - } - - BOOL AddAdornments(DWORD dwFlags = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::CommandBar_AddAdornments(m_hWnd, dwFlags, 0); - } - - int AddBitmap(int nBitmapID, int nNumImages) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::CommandBar_AddBitmap(m_hWnd, ModuleHelper::GetResourceInstance(), nBitmapID, nNumImages, 16, 16); - } - - BOOL AddButtons(UINT uNumButtons, LPTBBUTTON lpButtons) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CommandBar_AddButtons(m_hWnd, uNumButtons, lpButtons); - } - - BOOL AddToolTips(UINT uNumToolTips, LPTSTR lpToolTips) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CommandBar_AddToolTips(m_hWnd, uNumToolTips, lpToolTips); - } - - BOOL InsertButton(int nButton, LPTBBUTTON lpButton) - { - ATLASSERT(::IsWindow(m_hWnd)); - return CommandBar_InsertButton(m_hWnd, nButton, lpButton); - } - - HWND InsertComboBox(int nWidth, UINT dwStyle, WORD wComboBoxID, WORD wButton) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::CommandBar_InsertComboBox(m_hWnd, ModuleHelper::GetModuleInstance(), nWidth, dwStyle, wComboBoxID, wButton); - } - - BOOL InsertMenubar(WORD wMenuID, WORD wButton) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::CommandBar_InsertMenubar(m_hWnd, ModuleHelper::GetResourceInstance(), wMenuID, wButton); - } - - BOOL InsertMenubarEx(ATL::_U_STRINGorID menu, WORD wButton) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::CommandBar_InsertMenubarEx(m_hWnd, ModuleHelper::GetResourceInstance(), (LPTSTR)menu.m_lpstr, wButton); - } - - BOOL IsCommandBarMessage(LPMSG lpMsg) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::IsCommandBarMessage(m_hWnd, lpMsg); - } -}; - -#if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC MenuBar - typedef CCECommandBarCtrlT CMenuBarCtrl; -#else - typedef CCECommandBarCtrlT CCECommandBarCtrl; -#endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) - -/////////////////////////////////////////////////////////////////////////////// -// CCECommandBandsCtrl - -template -class CCECommandBandsCtrlT : public TBase -{ -public: -// Constructors - CCECommandBandsCtrlT(HWND hWnd = NULL) : TBase(hWnd) { } - - CCECommandBandsCtrlT< TBase >& operator=(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - -// Attributes - BOOL IsVisible() const - { - return IsWindowVisible(); - } - -#if (_WIN32_IE >= 0x0400) - UINT GetHeight() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CommandBands_Height(m_hWnd); - } -#endif // (_WIN32_IE >= 0x0400) - - HWND GetCommandBar(UINT uBand) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::CommandBands_GetCommandBar(m_hWnd, uBand); - } - - BOOL GetRestoreInformation(UINT uBand, LPCOMMANDBANDSRESTOREINFO pcbr) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::CommandBands_GetRestoreInformation(m_hWnd, uBand, pcbr); - } - -// Operations - HWND Create(HWND hWndParent, UINT wID, DWORD dwStyles, HIMAGELIST hImageList = NULL) - { - m_hWnd = ::CommandBands_Create(ModuleHelper::GetModuleInstance(), hWndParent, wID, dwStyles, hImageList); - ATLASSERT(::IsWindow(m_hWnd)); - return m_hWnd; - } - - BOOL AddAdornments(DWORD dwFlags = 0, LPREBARBANDINFO prbbi = NULL) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::CommandBands_AddAdornments(m_hWnd, ModuleHelper::GetModuleInstance(), dwFlags, prbbi); - } - - BOOL AddBands(UINT uBandCount, LPREBARBANDINFO prbbi) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::CommandBands_AddBands(m_hWnd, ModuleHelper::GetModuleInstance(), uBandCount, prbbi); - } - - BOOL Show(BOOL bShow = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::CommandBands_Show(m_hWnd, bShow); - } -}; - -typedef CCECommandBandsCtrlT CCECommandBandsCtrl; - -#endif // _WIN32_WCE - -}; // namespace WTL - -#endif // __ATLCTRLS_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlctrlw.h b/!NotAdopted/SmartAutoReplier/wtl/atlctrlw.h deleted file mode 100644 index 7f95bdfda1..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlctrlw.h +++ /dev/null @@ -1,4157 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLCTRLW_H__ -#define __ATLCTRLW_H__ - -#pragma once - -#ifdef _WIN32_WCE - #error atlctrlw.h is not supported on Windows CE -#endif - -#ifndef __ATLAPP_H__ - #error atlctrlw.h requires atlapp.h to be included first -#endif - -#ifndef __ATLCTRLS_H__ - #error atlctrlw.h requires atlctrls.h to be included first -#endif - -#if (_WIN32_IE < 0x0400) - #error atlctrlw.h requires _WIN32_IE >= 0x0400 -#endif - -// Define _WTL_CMDBAR_VISTA_MENUS as 0 to exclude Vista menus support -#if !defined(_WTL_CMDBAR_VISTA_MENUS) && (WINVER >= 0x0500) && (_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501) - #define _WTL_CMDBAR_VISTA_MENUS 1 -#endif - -#if _WTL_CMDBAR_VISTA_MENUS - #if !((_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501)) - #error _WTL_CMDBAR_VISTA_MENUS requires (_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501) - #endif -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CCommandBarCtrlImpl -// CCommandBarCtrl -// CMDICommandBarCtrlImpl -// CMDICommandBarCtrl - - -namespace WTL -{ - -/////////////////////////////////////////////////////////////////////////////// -// Command Bars - -// Window Styles: -#define CBRWS_TOP CCS_TOP -#define CBRWS_BOTTOM CCS_BOTTOM -#define CBRWS_NORESIZE CCS_NORESIZE -#define CBRWS_NOPARENTALIGN CCS_NOPARENTALIGN -#define CBRWS_NODIVIDER CCS_NODIVIDER - -// Extended styles -#define CBR_EX_TRANSPARENT 0x00000001L -#define CBR_EX_SHAREMENU 0x00000002L -#define CBR_EX_ALTFOCUSMODE 0x00000004L -#define CBR_EX_TRACKALWAYS 0x00000008L -#define CBR_EX_NOVISTAMENUS 0x00000010L - -// standard command bar styles -#define ATL_SIMPLE_CMDBAR_PANE_STYLE \ - (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CBRWS_NODIVIDER | CBRWS_NORESIZE | CBRWS_NOPARENTALIGN) - -// Messages - support chevrons for frame windows -#define CBRM_GETCMDBAR (WM_USER + 301) // returns command bar HWND -#define CBRM_GETMENU (WM_USER + 302) // returns loaded or attached menu -#define CBRM_TRACKPOPUPMENU (WM_USER + 303) // displays a popup menu - -typedef struct tagCBRPOPUPMENU -{ - int cbSize; - HMENU hMenu; // popup menu do display - UINT uFlags; // TPM_* flags for ::TrackPopupMenuEx - int x; - int y; - LPTPMPARAMS lptpm; // ptr to TPMPARAMS for ::TrackPopupMenuEx -} CBRPOPUPMENU, *LPCBRPOPUPMENU; - -// helper class -template -class CSimpleStack : public ATL::CSimpleArray< T > -{ -public: - BOOL Push(T t) - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - STACK-PUSH (%8.8X) size = %i\n"), t, GetSize()); -#endif - return Add(t); - } - - T Pop() - { - int nLast = GetSize() - 1; - if(nLast < 0) - return NULL; // must be able to convert to NULL - T t = m_aT[nLast]; -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - STACK-POP (%8.8X) size = %i\n"), t, GetSize()); -#endif - if(!RemoveAt(nLast)) - return NULL; - return t; - } - - T GetCurrent() - { - int nLast = GetSize() - 1; - if(nLast < 0) - return NULL; // must be able to convert to NULL - return m_aT[nLast]; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CCommandBarCtrlBase - base class for the Command Bar implementation - -class CCommandBarCtrlBase : public CToolBarCtrl -{ -public: - struct _MsgHookData - { - HHOOK hMsgHook; - DWORD dwUsage; - - _MsgHookData() : hMsgHook(NULL), dwUsage(0) - { } - }; - - typedef ATL::CSimpleMap CMsgHookMap; - static CMsgHookMap* s_pmapMsgHook; - - static HHOOK s_hCreateHook; - static bool s_bW2K; // For animation flag - static CCommandBarCtrlBase* s_pCurrentBar; - static bool s_bStaticInit; - - CSimpleStack m_stackMenuWnd; - CSimpleStack m_stackMenuHandle; - - HWND m_hWndHook; - DWORD m_dwMagic; - - - CCommandBarCtrlBase() : m_hWndHook(NULL), m_dwMagic(1314) - { - // init static variables - if(!s_bStaticInit) - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlBase::CCommandBarCtrlBase.\n")); - ATLASSERT(FALSE); - return; - } - - if(!s_bStaticInit) - { - // Just in case... - AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES); - // Animation on Win2000 only - s_bW2K = !AtlIsOldWindows(); - // done - s_bStaticInit = true; - } - - lock.Unlock(); - } - } - - bool IsCommandBarBase() const { return m_dwMagic == 1314; } -}; - -__declspec(selectany) CCommandBarCtrlBase::CMsgHookMap* CCommandBarCtrlBase::s_pmapMsgHook = NULL; -__declspec(selectany) HHOOK CCommandBarCtrlBase::s_hCreateHook = NULL; -__declspec(selectany) CCommandBarCtrlBase* CCommandBarCtrlBase::s_pCurrentBar = NULL; -__declspec(selectany) bool CCommandBarCtrlBase::s_bW2K = false; -__declspec(selectany) bool CCommandBarCtrlBase::s_bStaticInit = false; - - -/////////////////////////////////////////////////////////////////////////////// -// CCommandBarCtrl - ATL implementation of Command Bars - -template -class ATL_NO_VTABLE CCommandBarCtrlImpl : public ATL::CWindowImpl< T, TBase, TWinTraits > -{ -public: - DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName()) - -// Declarations - struct _MenuItemData // menu item data - { - DWORD dwMagic; - LPTSTR lpstrText; - UINT fType; - UINT fState; - int iButton; - - _MenuItemData() { dwMagic = 0x1313; } - bool IsCmdBarMenuItem() { return (dwMagic == 0x1313); } - }; - - struct _ToolBarData // toolbar resource data - { - WORD wVersion; - WORD wWidth; - WORD wHeight; - WORD wItemCount; - //WORD aItems[wItemCount] - - WORD* items() - { return (WORD*)(this+1); } - }; - -// Constants - enum _CmdBarDrawConstants - { - s_kcxGap = 1, - s_kcxTextMargin = 2, - s_kcxButtonMargin = 3, - s_kcyButtonMargin = 3 - }; - - enum - { - _nMaxMenuItemTextLength = 100, - _chChevronShortcut = _T('/') - }; - -#ifndef DT_HIDEPREFIX - enum { DT_HIDEPREFIX = 0x00100000 }; -#endif // !DT_HIDEPREFIX - -// Data members - HMENU m_hMenu; - HIMAGELIST m_hImageList; - ATL::CSimpleValArray m_arrCommand; - - DWORD m_dwExtendedStyle; // Command Bar specific extended styles - - ATL::CContainedWindow m_wndParent; - - bool m_bMenuActive:1; - bool m_bAttachedMenu:1; - bool m_bImagesVisible:1; - bool m_bPopupItem:1; - bool m_bContextMenu:1; - bool m_bEscapePressed:1; - bool m_bSkipMsg:1; - bool m_bParentActive:1; - bool m_bFlatMenus:1; - bool m_bUseKeyboardCues:1; - bool m_bShowKeyboardCues:1; - bool m_bAllowKeyboardCues:1; - bool m_bKeyboardInput:1; - bool m_bAlphaImages:1; - bool m_bLayoutRTL:1; - bool m_bSkipPostDown:1; - bool m_bVistaMenus:1; - - int m_nPopBtn; - int m_nNextPopBtn; - - SIZE m_szBitmap; - SIZE m_szButton; - - COLORREF m_clrMask; - CFont m_fontMenu; // used internally, only to measure text - - UINT m_uSysKey; - - HWND m_hWndFocus; // Alternate focus mode - - int m_cxExtraSpacing; - -#if _WTL_CMDBAR_VISTA_MENUS - ATL::CSimpleValArray m_arrVistaBitmap; // Bitmaps for Vista menus -#endif // _WTL_CMDBAR_VISTA_MENUS - -// Constructor/destructor - CCommandBarCtrlImpl() : - m_hMenu(NULL), - m_hImageList(NULL), - m_wndParent(this, 1), - m_bMenuActive(false), - m_bAttachedMenu(false), - m_nPopBtn(-1), - m_nNextPopBtn(-1), - m_bPopupItem(false), - m_bImagesVisible(true), - m_bSkipMsg(false), - m_uSysKey(0), - m_hWndFocus(NULL), - m_bContextMenu(false), - m_bEscapePressed(false), - m_clrMask(RGB(192, 192, 192)), - m_dwExtendedStyle(CBR_EX_TRANSPARENT | CBR_EX_SHAREMENU | CBR_EX_TRACKALWAYS), - m_bParentActive(true), - m_bFlatMenus(false), - m_bUseKeyboardCues(false), - m_bShowKeyboardCues(false), - m_bAllowKeyboardCues(true), - m_bKeyboardInput(false), - m_cxExtraSpacing(0), - m_bAlphaImages(false), - m_bLayoutRTL(false), - m_bSkipPostDown(false), - m_bVistaMenus(false) - { - SetImageSize(16, 15); // default - } - - ~CCommandBarCtrlImpl() - { - if(m_wndParent.IsWindow()) -/*scary!*/ m_wndParent.UnsubclassWindow(); - - if(m_hMenu != NULL && (m_dwExtendedStyle & CBR_EX_SHAREMENU) == 0) - ::DestroyMenu(m_hMenu); - - if(m_hImageList != NULL) - ::ImageList_Destroy(m_hImageList); - } - -// Attributes - DWORD GetCommandBarExtendedStyle() const - { - return m_dwExtendedStyle; - } - - DWORD SetCommandBarExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) - { - DWORD dwPrevStyle = m_dwExtendedStyle; - if(dwMask == 0) - m_dwExtendedStyle = dwExtendedStyle; - else - m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); - return dwPrevStyle; - } - - CMenuHandle GetMenu() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return m_hMenu; - } - - COLORREF GetImageMaskColor() const - { - return m_clrMask; - } - - COLORREF SetImageMaskColor(COLORREF clrMask) - { - COLORREF clrOld = m_clrMask; - m_clrMask = clrMask; - return clrOld; - } - - bool GetImagesVisible() const - { - return m_bImagesVisible; - } - - bool SetImagesVisible(bool bVisible) - { - bool bOld = m_bImagesVisible; - m_bImagesVisible = bVisible; - return bOld; - } - - void GetImageSize(SIZE& size) const - { - size = m_szBitmap; - } - - bool SetImageSize(SIZE& size) - { - return SetImageSize(size.cx, size.cy); - } - - bool SetImageSize(int cx, int cy) - { - if(m_hImageList != NULL) - { - if(::ImageList_GetImageCount(m_hImageList) == 0) // empty - { - ::ImageList_Destroy(m_hImageList); - m_hImageList = NULL; - } - else - { - return false; // can't set, image list exists - } - } - - if(cx == 0 || cy == 0) - return false; - - m_szBitmap.cx = cx; - m_szBitmap.cy = cy; - m_szButton.cx = m_szBitmap.cx + 2 * s_kcxButtonMargin; - m_szButton.cy = m_szBitmap.cy + 2 * s_kcyButtonMargin; - - return true; - } - - bool GetAlphaImages() const - { - return m_bAlphaImages; - } - - bool SetAlphaImages(bool bAlphaImages) - { - if(m_hImageList != NULL) - { - if(::ImageList_GetImageCount(m_hImageList) == 0) // empty - { - ::ImageList_Destroy(m_hImageList); - m_hImageList = NULL; - } - else - { - return false; // can't set, image list exists - } - } - - m_bAlphaImages = bAlphaImages; - return true; - } - - HWND GetCmdBar() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HWND)::SendMessage(m_hWnd, CBRM_GETCMDBAR, 0, 0L); - } - -// Methods - HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - UINT nID = 0, LPVOID lpCreateParam = NULL) - { - // These styles are required for command bars - dwStyle |= TBSTYLE_LIST | TBSTYLE_FLAT; -#if (_MSC_VER >= 1300) - return ATL::CWindowImpl< T, TBase, TWinTraits >::Create(hWndParent, rcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam); -#else // !(_MSC_VER >= 1300) - typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass; - return _baseClass::Create(hWndParent, rcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam); -#endif // !(_MSC_VER >= 1300) - } - - BOOL AttachToWindow(HWND hWnd) - { - ATLASSERT(m_hWnd == NULL); - ATLASSERT(::IsWindow(hWnd)); - BOOL bRet = SubclassWindow(hWnd); - if(bRet) - { - m_bAttachedMenu = true; - T* pT = static_cast(this); - pT->GetSystemSettings(); - } - return bRet; - } - - BOOL LoadMenu(ATL::_U_STRINGorID menu) - { - ATLASSERT(::IsWindow(m_hWnd)); - - if(m_bAttachedMenu) // doesn't work in this mode - return FALSE; - if(menu.m_lpstr == NULL) - return FALSE; - - HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), menu.m_lpstr); - if(hMenu == NULL) - return FALSE; - - return AttachMenu(hMenu); - } - - BOOL AttachMenu(HMENU hMenu) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(hMenu == NULL || ::IsMenu(hMenu)); - if(hMenu != NULL && !::IsMenu(hMenu)) - return FALSE; - -#if _WTL_CMDBAR_VISTA_MENUS - // remove Vista bitmaps if used - if(m_bVistaMenus && (m_hMenu != NULL)) - { - T* pT = static_cast(this); - pT->_RemoveVistaBitmapsFromMenu(); - } -#endif // _WTL_CMDBAR_VISTA_MENUS - - // destroy old menu, if needed, and set new one - if(m_hMenu != NULL && (m_dwExtendedStyle & CBR_EX_SHAREMENU) == 0) - ::DestroyMenu(m_hMenu); - - m_hMenu = hMenu; - - if(m_bAttachedMenu) // Nothing else in this mode - return TRUE; - - // Build buttons according to menu - SetRedraw(FALSE); - - // Clear all buttons - int nCount = GetButtonCount(); - for(int i = 0; i < nCount; i++) - ATLVERIFY(DeleteButton(0) != FALSE); - - // Add buttons for each menu item - if(m_hMenu != NULL) - { - int nItems = ::GetMenuItemCount(m_hMenu); - - T* pT = static_cast(this); - pT; // avoid level 4 warning - TCHAR szString[pT->_nMaxMenuItemTextLength]; - for(int i = 0; i < nItems; i++) - { - CMenuItemInfo mii; - mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU; - mii.fType = MFT_STRING; - mii.dwTypeData = szString; - mii.cch = pT->_nMaxMenuItemTextLength; - BOOL bRet = ::GetMenuItemInfo(m_hMenu, i, TRUE, &mii); - ATLASSERT(bRet); - // If we have more than the buffer, we assume we have bitmaps bits - if(lstrlen(szString) > pT->_nMaxMenuItemTextLength - 1) - { - mii.fType = MFT_BITMAP; - ::SetMenuItemInfo(m_hMenu, i, TRUE, &mii); - szString[0] = 0; - } - - // NOTE: Command Bar currently supports only drop-down menu items - ATLASSERT(mii.hSubMenu != NULL); - - TBBUTTON btn = { 0 }; - btn.iBitmap = 0; - btn.idCommand = i; - btn.fsState = (BYTE)(((mii.fState & MFS_DISABLED) == 0) ? TBSTATE_ENABLED : 0); - btn.fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE | TBSTYLE_DROPDOWN; - btn.dwData = 0; - btn.iString = 0; - - bRet = InsertButton(-1, &btn); - ATLASSERT(bRet); - - TBBUTTONINFO bi = { 0 }; - bi.cbSize = sizeof(TBBUTTONINFO); - bi.dwMask = TBIF_TEXT; - bi.pszText = szString; - - bRet = SetButtonInfo(i, &bi); - ATLASSERT(bRet); - } - } - - SetRedraw(TRUE); - Invalidate(); - UpdateWindow(); - - return TRUE; - } - - BOOL LoadImages(ATL::_U_STRINGorID image) - { - return _LoadImagesHelper(image, false); - } - - BOOL LoadMappedImages(UINT nIDImage, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0) - { - return _LoadImagesHelper(nIDImage, true, nFlags , lpColorMap, nMapSize); - } - - BOOL _LoadImagesHelper(ATL::_U_STRINGorID image, bool bMapped, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - HINSTANCE hInstance = ModuleHelper::GetResourceInstance(); - - HRSRC hRsrc = ::FindResource(hInstance, image.m_lpstr, (LPTSTR)RT_TOOLBAR); - if(hRsrc == NULL) - return FALSE; - - HGLOBAL hGlobal = ::LoadResource(hInstance, hRsrc); - if(hGlobal == NULL) - return FALSE; - - _ToolBarData* pData = (_ToolBarData*)::LockResource(hGlobal); - if(pData == NULL) - return FALSE; - ATLASSERT(pData->wVersion == 1); - - WORD* pItems = pData->items(); - int nItems = pData->wItemCount; - - // Set internal data - SetImageSize(pData->wWidth, pData->wHeight); - - // Create image list if needed - if(m_hImageList == NULL) - { - // Check if the bitmap is 32-bit (alpha channel) bitmap (valid for Windows XP only) - T* pT = static_cast(this); - m_bAlphaImages = AtlIsAlphaBitmapResource(image); - - if(!pT->CreateInternalImageList(pData->wItemCount)) - return FALSE; - } - -#if _WTL_CMDBAR_VISTA_MENUS - int nOldImageCount = ::ImageList_GetImageCount(m_hImageList); -#endif // _WTL_CMDBAR_VISTA_MENUS - - // Add bitmap to our image list - CBitmap bmp; - if(bMapped) - { - ATLASSERT(HIWORD(PtrToUlong(image.m_lpstr)) == 0); // if mapped, must be a numeric ID - int nIDImage = (int)(short)LOWORD(PtrToUlong(image.m_lpstr)); - bmp.LoadMappedBitmap(nIDImage, (WORD)nFlags, lpColorMap, nMapSize); - } - else - { - if(m_bAlphaImages) - bmp = (HBITMAP)::LoadImage(ModuleHelper::GetResourceInstance(), image.m_lpstr, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE); - else - bmp.LoadBitmap(image.m_lpstr); - } - ATLASSERT(bmp.m_hBitmap != NULL); - if(bmp.m_hBitmap == NULL) - return FALSE; - if(::ImageList_AddMasked(m_hImageList, bmp, m_clrMask) == -1) - return FALSE; - - // Fill the array with command IDs - for(int i = 0; i < nItems; i++) - { - if(pItems[i] != 0) - m_arrCommand.Add(pItems[i]); - } - - int nImageCount = ::ImageList_GetImageCount(m_hImageList); - ATLASSERT(nImageCount == m_arrCommand.GetSize()); - if(nImageCount != m_arrCommand.GetSize()) - return FALSE; - -#if _WTL_CMDBAR_VISTA_MENUS - if(RunTimeHelper::IsVista()) - { - T* pT = static_cast(this); - pT->_AddVistaBitmapsFromImageList(nOldImageCount, nImageCount - nOldImageCount); - ATLASSERT(nImageCount == m_arrVistaBitmap.GetSize()); - } -#endif // _WTL_CMDBAR_VISTA_MENUS - - return TRUE; - } - - BOOL AddBitmap(ATL::_U_STRINGorID bitmap, int nCommandID) - { - ATLASSERT(::IsWindow(m_hWnd)); - CBitmap bmp; - bmp.LoadBitmap(bitmap.m_lpstr); - if(bmp.m_hBitmap == NULL) - return FALSE; - return AddBitmap(bmp, nCommandID); - } - - BOOL AddBitmap(HBITMAP hBitmap, UINT nCommandID) - { - ATLASSERT(::IsWindow(m_hWnd)); - T* pT = static_cast(this); - // Create image list if it doesn't exist - if(m_hImageList == NULL) - { - if(!pT->CreateInternalImageList(1)) - return FALSE; - } - // check bitmap size - CBitmapHandle bmp = hBitmap; - SIZE size = { 0, 0 }; - bmp.GetSize(size); - if(size.cx != m_szBitmap.cx || size.cy != m_szBitmap.cy) - { - ATLASSERT(FALSE); // must match size! - return FALSE; - } - // add bitmap - int nRet = ::ImageList_AddMasked(m_hImageList, hBitmap, m_clrMask); - if(nRet == -1) - return FALSE; - BOOL bRet = m_arrCommand.Add((WORD)nCommandID); - ATLASSERT(::ImageList_GetImageCount(m_hImageList) == m_arrCommand.GetSize()); -#if _WTL_CMDBAR_VISTA_MENUS - if(RunTimeHelper::IsVista()) - { - pT->_AddVistaBitmapFromImageList(m_arrCommand.GetSize() - 1); - ATLASSERT(m_arrVistaBitmap.GetSize() == m_arrCommand.GetSize()); - } -#endif // _WTL_CMDBAR_VISTA_MENUS - return bRet; - } - - BOOL AddIcon(ATL::_U_STRINGorID icon, UINT nCommandID) - { - ATLASSERT(::IsWindow(m_hWnd)); - HICON hIcon = ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr); - if(hIcon == NULL) - return FALSE; - return AddIcon(hIcon, nCommandID); - } - - BOOL AddIcon(HICON hIcon, UINT nCommandID) - { - ATLASSERT(::IsWindow(m_hWnd)); - T* pT = static_cast(this); - // create image list if it doesn't exist - if(m_hImageList == NULL) - { - if(!pT->CreateInternalImageList(1)) - return FALSE; - } - - int nRet = ::ImageList_AddIcon(m_hImageList, hIcon); - if(nRet == -1) - return FALSE; - BOOL bRet = m_arrCommand.Add((WORD)nCommandID); - ATLASSERT(::ImageList_GetImageCount(m_hImageList) == m_arrCommand.GetSize()); -#if _WTL_CMDBAR_VISTA_MENUS - if(RunTimeHelper::IsVista()) - { - pT->_AddVistaBitmapFromImageList(m_arrCommand.GetSize() - 1); - ATLASSERT(m_arrVistaBitmap.GetSize() == m_arrCommand.GetSize()); - } -#endif // _WTL_CMDBAR_VISTA_MENUS - return bRet; - } - - BOOL ReplaceBitmap(ATL::_U_STRINGorID bitmap, int nCommandID) - { - ATLASSERT(::IsWindow(m_hWnd)); - CBitmap bmp; - bmp.LoadBitmap(bitmap.m_lpstr); - if(bmp.m_hBitmap == NULL) - return FALSE; - return ReplaceBitmap(bmp, nCommandID); - } - - BOOL ReplaceBitmap(HBITMAP hBitmap, UINT nCommandID) - { - ATLASSERT(::IsWindow(m_hWnd)); - BOOL bRet = FALSE; - for(int i = 0; i < m_arrCommand.GetSize(); i++) - { - if(m_arrCommand[i] == nCommandID) - { - bRet = ::ImageList_Remove(m_hImageList, i); - if(bRet) - { - m_arrCommand.RemoveAt(i); -#if _WTL_CMDBAR_VISTA_MENUS - if(RunTimeHelper::IsVista()) - { - if(m_arrVistaBitmap[i] != NULL) - ::DeleteObject(m_arrVistaBitmap[i]); - m_arrVistaBitmap.RemoveAt(i); - } -#endif // _WTL_CMDBAR_VISTA_MENUS - } - break; - } - } - if(bRet) - bRet = AddBitmap(hBitmap, nCommandID); - return bRet; - } - - BOOL ReplaceIcon(ATL::_U_STRINGorID icon, UINT nCommandID) - { - ATLASSERT(::IsWindow(m_hWnd)); - HICON hIcon = ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr); - if(hIcon == NULL) - return FALSE; - return ReplaceIcon(hIcon, nCommandID); - } - - BOOL ReplaceIcon(HICON hIcon, UINT nCommandID) - { - ATLASSERT(::IsWindow(m_hWnd)); - BOOL bRet = FALSE; - for(int i = 0; i < m_arrCommand.GetSize(); i++) - { - if(m_arrCommand[i] == nCommandID) - { - bRet = (::ImageList_ReplaceIcon(m_hImageList, i, hIcon) != -1); -#if _WTL_CMDBAR_VISTA_MENUS - if(RunTimeHelper::IsVista() && bRet != FALSE) - { - T* pT = static_cast(this); - pT->_ReplaceVistaBitmapFromImageList(i); - } -#endif // _WTL_CMDBAR_VISTA_MENUS - break; - } - } - return bRet; - } - - BOOL RemoveImage(int nCommandID) - { - ATLASSERT(::IsWindow(m_hWnd)); - - BOOL bRet = FALSE; - for(int i = 0; i < m_arrCommand.GetSize(); i++) - { - if(m_arrCommand[i] == nCommandID) - { - bRet = ::ImageList_Remove(m_hImageList, i); - if(bRet) - { - m_arrCommand.RemoveAt(i); -#if _WTL_CMDBAR_VISTA_MENUS - if(RunTimeHelper::IsVista()) - { - if(m_arrVistaBitmap[i] != NULL) - ::DeleteObject(m_arrVistaBitmap[i]); - m_arrVistaBitmap.RemoveAt(i); - } -#endif // _WTL_CMDBAR_VISTA_MENUS - } - break; - } - } - return bRet; - } - - BOOL RemoveAllImages() - { - ATLASSERT(::IsWindow(m_hWnd)); - - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Removing all images\n")); - BOOL bRet = ::ImageList_RemoveAll(m_hImageList); - if(bRet) - { - m_arrCommand.RemoveAll(); -#if _WTL_CMDBAR_VISTA_MENUS - for(int i = 0; i < m_arrVistaBitmap.GetSize(); i++) - { - if(m_arrVistaBitmap[i] != NULL) - ::DeleteObject(m_arrVistaBitmap[i]); - } - m_arrVistaBitmap.RemoveAll(); -#endif // _WTL_CMDBAR_VISTA_MENUS - } - return bRet; - } - - BOOL TrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y, LPTPMPARAMS lpParams = NULL) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(::IsMenu(hMenu)); - if(!::IsMenu(hMenu)) - return FALSE; - m_bContextMenu = true; - if(m_bUseKeyboardCues) - m_bShowKeyboardCues = m_bKeyboardInput; - T* pT = static_cast(this); - return pT->DoTrackPopupMenu(hMenu, uFlags, x, y, lpParams); - } - - BOOL SetMDIClient(HWND /*hWndMDIClient*/) - { - // Use CMDICommandBarCtrl for MDI support - ATLASSERT(FALSE); - return FALSE; - } - -// Message map and handlers - BEGIN_MSG_MAP(CCommandBarCtrlImpl) - MESSAGE_HANDLER(WM_CREATE, OnCreate) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) - MESSAGE_HANDLER(WM_INITMENU, OnInitMenu) - MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup) - MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect) - MESSAGE_HANDLER(GetAutoPopupMessage(), OnInternalAutoPopup) - MESSAGE_HANDLER(GetGetBarMessage(), OnInternalGetBar) - MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) - MESSAGE_HANDLER(WM_MENUCHAR, OnMenuChar) - - MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown) - MESSAGE_HANDLER(WM_KEYUP, OnKeyUp) - MESSAGE_HANDLER(WM_CHAR, OnChar) - MESSAGE_HANDLER(WM_SYSKEYDOWN, OnSysKeyDown) - MESSAGE_HANDLER(WM_SYSKEYUP, OnSysKeyUp) - MESSAGE_HANDLER(WM_SYSCHAR, OnSysChar) -// public API handlers - these stay to support chevrons in atlframe.h - MESSAGE_HANDLER(CBRM_GETMENU, OnAPIGetMenu) - MESSAGE_HANDLER(CBRM_TRACKPOPUPMENU, OnAPITrackPopupMenu) - MESSAGE_HANDLER(CBRM_GETCMDBAR, OnAPIGetCmdBar) - - MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem) - MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem) - - MESSAGE_HANDLER(WM_FORWARDMSG, OnForwardMsg) - ALT_MSG_MAP(1) // Parent window messages - NOTIFY_CODE_HANDLER(TBN_HOTITEMCHANGE, OnParentHotItemChange) - NOTIFY_CODE_HANDLER(TBN_DROPDOWN, OnParentDropDown) - MESSAGE_HANDLER(WM_INITMENUPOPUP, OnParentInitMenuPopup) - MESSAGE_HANDLER(GetGetBarMessage(), OnParentInternalGetBar) - MESSAGE_HANDLER(WM_SYSCOMMAND, OnParentSysCommand) - MESSAGE_HANDLER(CBRM_GETMENU, OnParentAPIGetMenu) - MESSAGE_HANDLER(WM_MENUCHAR, OnParentMenuChar) - MESSAGE_HANDLER(CBRM_TRACKPOPUPMENU, OnParentAPITrackPopupMenu) - MESSAGE_HANDLER(CBRM_GETCMDBAR, OnParentAPIGetCmdBar) - MESSAGE_HANDLER(WM_SETTINGCHANGE, OnParentSettingChange) - - MESSAGE_HANDLER(WM_DRAWITEM, OnParentDrawItem) - MESSAGE_HANDLER(WM_MEASUREITEM, OnParentMeasureItem) - - MESSAGE_HANDLER(WM_ACTIVATE, OnParentActivate) - NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnParentCustomDraw) - ALT_MSG_MAP(2) // MDI client window messages - // Use CMDICommandBarCtrl for MDI support - ALT_MSG_MAP(3) // Message hook messages - MESSAGE_HANDLER(WM_MOUSEMOVE, OnHookMouseMove) - MESSAGE_HANDLER(WM_SYSKEYDOWN, OnHookSysKeyDown) - MESSAGE_HANDLER(WM_SYSKEYUP, OnHookSysKeyUp) - MESSAGE_HANDLER(WM_SYSCHAR, OnHookSysChar) - MESSAGE_HANDLER(WM_KEYDOWN, OnHookKeyDown) - MESSAGE_HANDLER(WM_NEXTMENU, OnHookNextMenu) - MESSAGE_HANDLER(WM_CHAR, OnHookChar) - END_MSG_MAP() - - LRESULT OnForwardMsg(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) - { - LPMSG pMsg = (LPMSG)lParam; - if(pMsg->message >= WM_MOUSEFIRST && pMsg->message <= WM_MOUSELAST) - m_bKeyboardInput = false; - else if(pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST) - m_bKeyboardInput = true; - LRESULT lRet = 0; - ProcessWindowMessage(pMsg->hwnd, pMsg->message, pMsg->wParam, pMsg->lParam, lRet, 3); - return lRet; - } - - LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - // Let the toolbar initialize itself - LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); - // get and use system settings - T* pT = static_cast(this); - pT->GetSystemSettings(); - // Parent init - ATL::CWindow wndParent = GetParent(); - ATL::CWindow wndTopLevelParent = wndParent.GetTopLevelParent(); - m_wndParent.SubclassWindow(wndTopLevelParent); - // Toolbar Init - SetButtonStructSize(); - SetImageList(NULL); - - // Create message hook if needed - CWindowCreateCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::OnCreate.\n")); - ATLASSERT(FALSE); - return -1; - } - - if(s_pmapMsgHook == NULL) - { - ATLTRY(s_pmapMsgHook = new CMsgHookMap); - ATLASSERT(s_pmapMsgHook != NULL); - } - - if(s_pmapMsgHook != NULL) - { - DWORD dwThreadID = ::GetCurrentThreadId(); - _MsgHookData* pData = s_pmapMsgHook->Lookup(dwThreadID); - if(pData == NULL) - { - ATLTRY(pData = new _MsgHookData); - ATLASSERT(pData != NULL); - HHOOK hMsgHook = ::SetWindowsHookEx(WH_GETMESSAGE, MessageHookProc, ModuleHelper::GetModuleInstance(), dwThreadID); - ATLASSERT(hMsgHook != NULL); - if(pData != NULL && hMsgHook != NULL) - { - pData->hMsgHook = hMsgHook; - pData->dwUsage = 1; - BOOL bRet = s_pmapMsgHook->Add(dwThreadID, pData); - bRet; - ATLASSERT(bRet); - } - } - else - { - (pData->dwUsage)++; - } - } - lock.Unlock(); - - // Get layout -#if (WINVER >= 0x0500) - m_bLayoutRTL = ((GetExStyle() & WS_EX_LAYOUTRTL) != 0); -#endif // (WINVER >= 0x0500) - - return lRet; - } - - LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); - -#if _WTL_CMDBAR_VISTA_MENUS - if(m_bVistaMenus && (m_hMenu != NULL)) - { - T* pT = static_cast(this); - pT->_RemoveVistaBitmapsFromMenu(); - } - - for(int i = 0; i < m_arrVistaBitmap.GetSize(); i++) - { - if(m_arrVistaBitmap[i] != NULL) - ::DeleteObject(m_arrVistaBitmap[i]); - } -#endif // _WTL_CMDBAR_VISTA_MENUS - - if(m_bAttachedMenu) // nothing to do in this mode - return lRet; - - CWindowCreateCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::OnDestroy.\n")); - ATLASSERT(FALSE); - return lRet; - } - - if(s_pmapMsgHook != NULL) - { - DWORD dwThreadID = ::GetCurrentThreadId(); - _MsgHookData* pData = s_pmapMsgHook->Lookup(dwThreadID); - if(pData != NULL) - { - (pData->dwUsage)--; - if(pData->dwUsage == 0) - { - BOOL bRet = ::UnhookWindowsHookEx(pData->hMsgHook); - ATLASSERT(bRet); - bRet = s_pmapMsgHook->Remove(dwThreadID); - ATLASSERT(bRet); - if(bRet) - delete pData; - } - - if(s_pmapMsgHook->GetSize() == 0) - { - delete s_pmapMsgHook; - s_pmapMsgHook = NULL; - } - } - } - - lock.Unlock(); - - return lRet; - } - - LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnKeyDown\n")); -#endif - bHandled = FALSE; - // Simulate Alt+Space for the parent - if(wParam == VK_SPACE) - { - m_wndParent.PostMessage(WM_SYSKEYDOWN, wParam, lParam | (1 << 29)); - bHandled = TRUE; - } -#if (_WIN32_IE >= 0x0500) - else if(wParam == VK_LEFT || wParam == VK_RIGHT) - { - WPARAM wpNext = m_bLayoutRTL ? VK_LEFT : VK_RIGHT; - - if(!m_bMenuActive) - { - T* pT = static_cast(this); - int nBtn = GetHotItem(); - int nNextBtn = (wParam == wpNext) ? pT->GetNextMenuItem(nBtn) : pT->GetPreviousMenuItem(nBtn); - if(nNextBtn == -2) - { - SetHotItem(-1); - if(pT->DisplayChevronMenu()) - bHandled = TRUE; - } - } - } -#endif // (_WIN32_IE >= 0x0500) - return 0; - } - - LRESULT OnKeyUp(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnKeyUp\n")); -#endif - if(wParam != VK_SPACE) - bHandled = FALSE; - return 0; - } - - LRESULT OnChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnChar\n")); -#endif - if(wParam != VK_SPACE) - bHandled = FALSE; - else - return 0; - // Security - if(!m_wndParent.IsWindowEnabled() || ::GetFocus() != m_hWnd) - return 0; - - // Handle mnemonic press when we have focus - int nBtn = 0; - if(wParam != VK_RETURN && !MapAccelerator((TCHAR)LOWORD(wParam), nBtn)) - { -#if (_WIN32_IE >= 0x0500) - if((TCHAR)LOWORD(wParam) != _chChevronShortcut) -#endif // (_WIN32_IE >= 0x0500) - ::MessageBeep(0); - } - else - { -#if (_WIN32_IE >= 0x0500) - RECT rcClient = { 0 }; - GetClientRect(&rcClient); - RECT rcBtn = { 0 }; - GetItemRect(nBtn, &rcBtn); - TBBUTTON tbb = { 0 }; - GetButton(nBtn, &tbb); - if((tbb.fsState & TBSTATE_ENABLED) != 0 && (tbb.fsState & TBSTATE_HIDDEN) == 0 && rcBtn.right <= rcClient.right) - { -#endif // (_WIN32_IE >= 0x0500) - PostMessage(WM_KEYDOWN, VK_DOWN, 0L); - if(wParam != VK_RETURN) - SetHotItem(nBtn); -#if (_WIN32_IE >= 0x0500) - } - else - { - ::MessageBeep(0); - bHandled = TRUE; - } -#endif // (_WIN32_IE >= 0x0500) - } - return 0; - } - - LRESULT OnSysKeyDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnSysKeyDown\n")); -#endif - bHandled = FALSE; - return 0; - } - - LRESULT OnSysKeyUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnSysKeyUp\n")); -#endif - bHandled = FALSE; - return 0; - } - - LRESULT OnSysChar(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnSysChar\n")); -#endif - bHandled = FALSE; - return 0; - } - - LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - if(m_bAttachedMenu || (m_dwExtendedStyle & CBR_EX_TRANSPARENT)) - { - bHandled = FALSE; - return 0; - } - - CDCHandle dc = (HDC)wParam; - RECT rect = { 0 }; - GetClientRect(&rect); - dc.FillRect(&rect, COLOR_MENU); - - return 1; // don't do the default erase - } - - LRESULT OnInitMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - int nIndex = GetHotItem(); - SendMessage(WM_MENUSELECT, MAKEWPARAM(nIndex, MF_POPUP|MF_HILITE), (LPARAM)m_hMenu); - bHandled = FALSE; - return 1; - } - - LRESULT OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - if((BOOL)HIWORD(lParam)) // System menu, do nothing - { - bHandled = FALSE; - return 1; - } - - if(!(m_bAttachedMenu || m_bMenuActive)) // Not attached or ours, do nothing - { - bHandled = FALSE; - return 1; - } - -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnInitMenuPopup\n")); -#endif - // forward to the parent or subclassed window, so it can handle update UI - LRESULT lRet = 0; - if(m_bAttachedMenu) - lRet = DefWindowProc(uMsg, wParam, (lParam || m_bContextMenu) ? lParam : GetHotItem()); - else - lRet = m_wndParent.DefWindowProc(uMsg, wParam, (lParam || m_bContextMenu) ? lParam : GetHotItem()); - -#if _WTL_CMDBAR_VISTA_MENUS - // If Vista menus are active, just set bitmaps and return - if(m_bVistaMenus) - { - CMenuHandle menu = (HMENU)wParam; - ATLASSERT(menu.m_hMenu != NULL); - - for(int i = 0; i < menu.GetMenuItemCount(); i++) - { - WORD nID = (WORD)menu.GetMenuItemID(i); - int nIndex = m_arrCommand.Find(nID); - - CMenuItemInfo mii; - mii.fMask = MIIM_BITMAP; - mii.hbmpItem = (m_bImagesVisible && (nIndex != -1)) ? m_arrVistaBitmap[nIndex] : NULL; - menu.SetMenuItemInfo(i, TRUE, &mii); - } - - return lRet; - } -#endif // _WTL_CMDBAR_VISTA_MENUS - - // Convert menu items to ownerdraw, add our data - if(m_bImagesVisible) - { - CMenuHandle menuPopup = (HMENU)wParam; - ATLASSERT(menuPopup.m_hMenu != NULL); - - T* pT = static_cast(this); - pT; // avoid level 4 warning - TCHAR szString[pT->_nMaxMenuItemTextLength]; - BOOL bRet = FALSE; - for(int i = 0; i < menuPopup.GetMenuItemCount(); i++) - { - CMenuItemInfo mii; - mii.cch = pT->_nMaxMenuItemTextLength; - mii.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE; - mii.dwTypeData = szString; - bRet = menuPopup.GetMenuItemInfo(i, TRUE, &mii); - ATLASSERT(bRet); - - if(!(mii.fType & MFT_OWNERDRAW)) // Not already an ownerdraw item - { - mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_STATE; - _MenuItemData* pMI = NULL; - ATLTRY(pMI = new _MenuItemData); - ATLASSERT(pMI != NULL); - if(pMI != NULL) - { - pMI->fType = mii.fType; - pMI->fState = mii.fState; - mii.fType |= MFT_OWNERDRAW; - pMI->iButton = -1; - for(int j = 0; j < m_arrCommand.GetSize(); j++) - { - if(m_arrCommand[j] == mii.wID) - { - pMI->iButton = j; - break; - } - } - int cchLen = lstrlen(szString) + 1; - pMI->lpstrText = NULL; - ATLTRY(pMI->lpstrText = new TCHAR[cchLen]); - ATLASSERT(pMI->lpstrText != NULL); - if(pMI->lpstrText != NULL) - SecureHelper::strcpy_x(pMI->lpstrText, cchLen, szString); - mii.dwItemData = (ULONG_PTR)pMI; - bRet = menuPopup.SetMenuItemInfo(i, TRUE, &mii); - ATLASSERT(bRet); - } - } - } - - // Add it to the list - m_stackMenuHandle.Push(menuPopup.m_hMenu); - } - - return lRet; - } - - LRESULT OnMenuSelect(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - if(!m_bAttachedMenu) // Not attached, do nothing, forward to parent - { - m_bPopupItem = (lParam != NULL) && ((HMENU)lParam != m_hMenu) && (HIWORD(wParam) & MF_POPUP); - if(m_wndParent.IsWindow()) - m_wndParent.SendMessage(uMsg, wParam, lParam); - bHandled = FALSE; - return 1; - } - - // Check if a menu is closing, do a cleanup - if(HIWORD(wParam) == 0xFFFF && lParam == NULL) // Menu closing - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnMenuSelect - CLOSING!!!!\n")); -#endif - ATLASSERT(m_stackMenuWnd.GetSize() == 0); - // Restore the menu items to the previous state for all menus that were converted - if(m_bImagesVisible) - { - HMENU hMenu = NULL; - while((hMenu = m_stackMenuHandle.Pop()) != NULL) - { - CMenuHandle menuPopup = hMenu; - ATLASSERT(menuPopup.m_hMenu != NULL); - // Restore state and delete menu item data - BOOL bRet = FALSE; - for(int i = 0; i < menuPopup.GetMenuItemCount(); i++) - { - CMenuItemInfo mii; - mii.fMask = MIIM_DATA | MIIM_TYPE; - bRet = menuPopup.GetMenuItemInfo(i, TRUE, &mii); - ATLASSERT(bRet); - - _MenuItemData* pMI = (_MenuItemData*)mii.dwItemData; - if(pMI != NULL && pMI->IsCmdBarMenuItem()) - { - mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_STATE; - mii.fType = pMI->fType; - mii.dwTypeData = pMI->lpstrText; - mii.cch = lstrlen(pMI->lpstrText); - mii.dwItemData = NULL; - - bRet = menuPopup.SetMenuItemInfo(i, TRUE, &mii); - ATLASSERT(bRet); - - delete [] pMI->lpstrText; - pMI->dwMagic = 0x6666; - delete pMI; - } - } - } - } - } - - bHandled = FALSE; - return 1; - } - - LRESULT OnInternalAutoPopup(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - int nIndex = (int)wParam; - T* pT = static_cast(this); - pT->DoPopupMenu(nIndex, false); - return 0; - } - - LRESULT OnInternalGetBar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - // Let's make sure we're not embedded in another process - if((LPVOID)wParam != NULL) - *((DWORD*)wParam) = GetCurrentProcessId(); - if(IsWindowVisible()) - return (LRESULT)static_cast(this); - else - return NULL; - } - - LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { -#ifndef SPI_GETKEYBOARDCUES - const UINT SPI_SETKEYBOARDCUES = 0x100B; -#endif // !SPI_GETKEYBOARDCUES -#ifndef SPI_GETFLATMENU - const UINT SPI_SETFLATMENU = 0x1023; -#endif // !SPI_GETFLATMENU - - if(wParam == SPI_SETNONCLIENTMETRICS || wParam == SPI_SETKEYBOARDCUES || wParam == SPI_SETFLATMENU) - { - T* pT = static_cast(this); - pT->GetSystemSettings(); - } - - return 0; - } - - LRESULT OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); - - LPWINDOWPOS lpWP = (LPWINDOWPOS)lParam; - int cyMin = ::GetSystemMetrics(SM_CYMENU); - if(lpWP->cy < cyMin) - lpWP->cy = cyMin; - - return lRet; - } - - LRESULT OnMenuChar(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnMenuChar\n")); -#endif - bHandled = TRUE; - T* pT = static_cast(this); - - LRESULT lRet; - if(m_bMenuActive && LOWORD(wParam) != 0x0D) - lRet = 0; - else - lRet = MAKELRESULT(1, 1); - - if(m_bMenuActive && HIWORD(wParam) == MF_POPUP) - { - // Convert character to lower/uppercase and possibly Unicode, using current keyboard layout - TCHAR ch = (TCHAR)LOWORD(wParam); - CMenuHandle menu = (HMENU)lParam; - int nCount = ::GetMenuItemCount(menu); - int nRetCode = MNC_EXECUTE; - BOOL bRet = FALSE; - TCHAR szString[pT->_nMaxMenuItemTextLength]; - WORD wMnem = 0; - bool bFound = false; - for(int i = 0; i < nCount; i++) - { - CMenuItemInfo mii; - mii.cch = pT->_nMaxMenuItemTextLength; - mii.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE; - mii.dwTypeData = szString; - bRet = menu.GetMenuItemInfo(i, TRUE, &mii); - if(!bRet || (mii.fType & MFT_SEPARATOR)) - continue; - _MenuItemData* pmd = (_MenuItemData*)mii.dwItemData; - if(pmd != NULL && pmd->IsCmdBarMenuItem()) - { - LPTSTR p = pmd->lpstrText; - - if(p != NULL) - { - while(*p && *p != _T('&')) - p = ::CharNext(p); - if(p != NULL && *p) - { - DWORD dwP = MAKELONG(*(++p), 0); - DWORD dwC = MAKELONG(ch, 0); - if(::CharLower((LPTSTR)ULongToPtr(dwP)) == ::CharLower((LPTSTR)ULongToPtr(dwC))) - { - if(!bFound) - { - wMnem = (WORD)i; - bFound = true; - } - else - { - nRetCode = MNC_SELECT; - break; - } - } - } - } - } - } - if(bFound) - { - if(nRetCode == MNC_EXECUTE) - { - PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L); - pT->GiveFocusBack(); - } - bHandled = TRUE; - lRet = MAKELRESULT(wMnem, nRetCode); - } - } - else if(!m_bMenuActive) - { - int nBtn = 0; - if(!MapAccelerator((TCHAR)LOWORD(wParam), nBtn)) - { - bHandled = FALSE; - PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L); - pT->GiveFocusBack(); - -#if (_WIN32_IE >= 0x0500) - // check if we should display chevron menu - if((TCHAR)LOWORD(wParam) == pT->_chChevronShortcut) - { - if(pT->DisplayChevronMenu()) - bHandled = TRUE; - } -#endif // (_WIN32_IE >= 0x0500) - } - else if(m_wndParent.IsWindowEnabled()) - { -#if (_WIN32_IE >= 0x0500) - RECT rcClient = { 0 }; - GetClientRect(&rcClient); - RECT rcBtn = { 0 }; - GetItemRect(nBtn, &rcBtn); - TBBUTTON tbb = { 0 }; - GetButton(nBtn, &tbb); - if((tbb.fsState & TBSTATE_ENABLED) != 0 && (tbb.fsState & TBSTATE_HIDDEN) == 0 && rcBtn.right <= rcClient.right) - { -#endif // (_WIN32_IE >= 0x0500) - if(m_bUseKeyboardCues && !m_bShowKeyboardCues) - { - m_bAllowKeyboardCues = true; - ShowKeyboardCues(true); - } - pT->TakeFocus(); - PostMessage(WM_KEYDOWN, VK_DOWN, 0L); - SetHotItem(nBtn); -#if (_WIN32_IE >= 0x0500) - } - else - { - ::MessageBeep(0); - } -#endif // (_WIN32_IE >= 0x0500) - } - } - - return lRet; - } - - LRESULT OnDrawItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - LPDRAWITEMSTRUCT lpDrawItemStruct = (LPDRAWITEMSTRUCT)lParam; - _MenuItemData* pmd = (_MenuItemData*)lpDrawItemStruct->itemData; - if(lpDrawItemStruct->CtlType == ODT_MENU && pmd != NULL && pmd->IsCmdBarMenuItem()) - { - T* pT = static_cast(this); - pT->DrawItem(lpDrawItemStruct); - } - else - { - bHandled = FALSE; - } - return (LRESULT)TRUE; - } - - LRESULT OnMeasureItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - LPMEASUREITEMSTRUCT lpMeasureItemStruct = (LPMEASUREITEMSTRUCT)lParam; - _MenuItemData* pmd = (_MenuItemData*)lpMeasureItemStruct->itemData; - if(lpMeasureItemStruct->CtlType == ODT_MENU && pmd != NULL && pmd->IsCmdBarMenuItem()) - { - T* pT = static_cast(this); - pT->MeasureItem(lpMeasureItemStruct); - } - else - { - bHandled = FALSE; - } - return (LRESULT)TRUE; - } - -// API message handlers - LRESULT OnAPIGetMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - return (LRESULT)m_hMenu; - } - - LRESULT OnAPITrackPopupMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) - { - if(lParam == NULL) - return FALSE; - LPCBRPOPUPMENU lpCBRPopupMenu = (LPCBRPOPUPMENU)lParam; - if(lpCBRPopupMenu->cbSize != sizeof(CBRPOPUPMENU)) - return FALSE; - - T* pT = static_cast(this); - return pT->TrackPopupMenu(lpCBRPopupMenu->hMenu, lpCBRPopupMenu->uFlags, lpCBRPopupMenu->x, lpCBRPopupMenu->y, lpCBRPopupMenu->lptpm); - } - - LRESULT OnAPIGetCmdBar(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - return (LRESULT)m_hWnd; - } - -// Parent window message handlers - LRESULT OnParentHotItemChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) - { - LPNMTBHOTITEM lpNMHT = (LPNMTBHOTITEM)pnmh; - - // Check if this comes from us - if(pnmh->hwndFrom != m_hWnd) - { - bHandled = FALSE; - return 0; - } - - bool bBlockTracking = false; - if((m_dwExtendedStyle & CBR_EX_TRACKALWAYS) == 0) - { - DWORD dwProcessID; - ::GetWindowThreadProcessId(::GetActiveWindow(), &dwProcessID); - bBlockTracking = (::GetCurrentProcessId() != dwProcessID); - } - - if((!m_wndParent.IsWindowEnabled() || bBlockTracking) && (lpNMHT->dwFlags & HICF_MOUSE)) - { - return 1; - } - else - { -#ifndef HICF_LMOUSE - const DWORD HICF_LMOUSE = 0x00000080; // left mouse button selected -#endif - bHandled = FALSE; - - // Send WM_MENUSELECT to the app if it needs to display a status text - if(!(lpNMHT->dwFlags & HICF_MOUSE) - && !(lpNMHT->dwFlags & HICF_ACCELERATOR) - && !(lpNMHT->dwFlags & HICF_LMOUSE)) - { - if(lpNMHT->dwFlags & HICF_ENTERING) - m_wndParent.SendMessage(WM_MENUSELECT, 0, (LPARAM)m_hMenu); - if(lpNMHT->dwFlags & HICF_LEAVING) - m_wndParent.SendMessage(WM_MENUSELECT, MAKEWPARAM(0, 0xFFFF), NULL); - } - - return 0; - } - } - - LRESULT OnParentDropDown(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) - { - // Check if this comes from us - if(pnmh->hwndFrom != m_hWnd) - { - bHandled = FALSE; - return 1; - } - - T* pT = static_cast(this); - if(::GetFocus() != m_hWnd) - pT->TakeFocus(); - LPNMTOOLBAR pNMToolBar = (LPNMTOOLBAR)pnmh; - int nIndex = CommandToIndex(pNMToolBar->iItem); - m_bContextMenu = false; - m_bEscapePressed = false; - pT->DoPopupMenu(nIndex, true); - - return TBDDRET_DEFAULT; - } - - LRESULT OnParentInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - return OnInitMenuPopup(uMsg, wParam, lParam, bHandled); - } - - LRESULT OnParentInternalGetBar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - return OnInternalGetBar(uMsg, wParam, lParam, bHandled); - } - - LRESULT OnParentSysCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - bHandled = FALSE; - if((m_uSysKey == VK_MENU - || (m_uSysKey == VK_F10 && !(::GetKeyState(VK_SHIFT) & 0x80)) - || m_uSysKey == VK_SPACE) - && wParam == SC_KEYMENU) - { - T* pT = static_cast(this); - if(::GetFocus() == m_hWnd) - { - pT->GiveFocusBack(); // exit menu "loop" - PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L); - } - else if(m_uSysKey != VK_SPACE && !m_bSkipMsg) - { - if(m_bUseKeyboardCues && !m_bShowKeyboardCues && m_bAllowKeyboardCues) - ShowKeyboardCues(true); - - pT->TakeFocus(); // enter menu "loop" - bHandled = TRUE; - } - else if(m_uSysKey != VK_SPACE) - { - bHandled = TRUE; - } - } - m_bSkipMsg = false; - return 0; - } - - LRESULT OnParentAPIGetMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - return OnAPIGetMenu(uMsg, wParam, lParam, bHandled); - } - - LRESULT OnParentMenuChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - return OnMenuChar(uMsg, wParam, lParam, bHandled); - } - - LRESULT OnParentAPITrackPopupMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - return OnAPITrackPopupMenu(uMsg, wParam, lParam, bHandled); - } - - LRESULT OnParentAPIGetCmdBar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - return OnAPIGetCmdBar(uMsg, wParam, lParam, bHandled); - } - - LRESULT OnParentSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - OnSettingChange(uMsg, wParam, lParam, bHandled); - bHandled = FALSE; - return 1; - } - - LRESULT OnParentDrawItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - return OnDrawItem(uMsg, wParam, lParam, bHandled); - } - - LRESULT OnParentMeasureItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - return OnMeasureItem(uMsg, wParam, lParam, bHandled); - } - - LRESULT OnParentActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - m_bParentActive = (LOWORD(wParam) != WA_INACTIVE); - if(!m_bParentActive && m_bUseKeyboardCues && m_bShowKeyboardCues) - { - ShowKeyboardCues(false); // this will repaint our window - } - else - { - Invalidate(); - UpdateWindow(); - } - bHandled = FALSE; - return 1; - } - - LRESULT OnParentCustomDraw(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) - { - LRESULT lRet = CDRF_DODEFAULT; - bHandled = FALSE; - if(pnmh->hwndFrom == m_hWnd) - { - LPNMTBCUSTOMDRAW lpTBCustomDraw = (LPNMTBCUSTOMDRAW)pnmh; - if(lpTBCustomDraw->nmcd.dwDrawStage == CDDS_PREPAINT) - { - lRet = CDRF_NOTIFYITEMDRAW; - bHandled = TRUE; - } - else if(lpTBCustomDraw->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) - { - if(m_bFlatMenus) - { -#ifndef COLOR_MENUHILIGHT - const int COLOR_MENUHILIGHT = 29; -#endif // !COLOR_MENUHILIGHT - bool bDisabled = ((lpTBCustomDraw->nmcd.uItemState & CDIS_DISABLED) == CDIS_DISABLED); - if(!bDisabled && ((lpTBCustomDraw->nmcd.uItemState & CDIS_HOT) == CDIS_HOT || - (lpTBCustomDraw->nmcd.uItemState & CDIS_SELECTED) == CDIS_SELECTED)) - { - ::FillRect(lpTBCustomDraw->nmcd.hdc, &lpTBCustomDraw->nmcd.rc, ::GetSysColorBrush(COLOR_MENUHILIGHT)); - ::FrameRect(lpTBCustomDraw->nmcd.hdc, &lpTBCustomDraw->nmcd.rc, ::GetSysColorBrush(COLOR_HIGHLIGHT)); - lpTBCustomDraw->clrText = ::GetSysColor(m_bParentActive ? COLOR_HIGHLIGHTTEXT : COLOR_GRAYTEXT); - } - else if(bDisabled || !m_bParentActive) - { - lpTBCustomDraw->clrText = ::GetSysColor(COLOR_GRAYTEXT); - } - CDCHandle dc = lpTBCustomDraw->nmcd.hdc; - dc.SetTextColor(lpTBCustomDraw->clrText); - dc.SetBkMode(lpTBCustomDraw->nStringBkMode); - HFONT hFont = GetFont(); - HFONT hFontOld = NULL; - if(hFont != NULL) - hFontOld = dc.SelectFont(hFont); - const int cchText = 200; - TCHAR szText[cchText] = { 0 }; - TBBUTTONINFO tbbi = { 0 }; - tbbi.cbSize = sizeof(TBBUTTONINFO); - tbbi.dwMask = TBIF_TEXT; - tbbi.pszText = szText; - tbbi.cchText = cchText; - GetButtonInfo((int)lpTBCustomDraw->nmcd.dwItemSpec, &tbbi); - dc.DrawText(szText, -1, &lpTBCustomDraw->nmcd.rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER | (m_bShowKeyboardCues ? 0 : DT_HIDEPREFIX)); - if(hFont != NULL) - dc.SelectFont(hFontOld); - lRet = CDRF_SKIPDEFAULT; - bHandled = TRUE; - } - else if(!m_bParentActive) - { - lpTBCustomDraw->clrText = ::GetSysColor(COLOR_GRAYTEXT); - bHandled = TRUE; - } - } - } - return lRet; - } - -// Message hook handlers - LRESULT OnHookMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - static POINT s_point = { -1, -1 }; - DWORD dwPoint = ::GetMessagePos(); - POINT point = { GET_X_LPARAM(dwPoint), GET_Y_LPARAM(dwPoint) }; - - bHandled = FALSE; - if(m_bMenuActive) - { - if(::WindowFromPoint(point) == m_hWnd) - { - ScreenToClient(&point); - int nHit = HitTest(&point); - - if((point.x != s_point.x || point.y != s_point.y) && nHit >= 0 && nHit < ::GetMenuItemCount(m_hMenu) && nHit != m_nPopBtn && m_nPopBtn != -1) - { - TBBUTTON tbb = { 0 }; - GetButton(nHit, &tbb); - if((tbb.fsState & TBSTATE_ENABLED) != 0) - { - m_nNextPopBtn = nHit | 0xFFFF0000; - HWND hWndMenu = m_stackMenuWnd.GetCurrent(); - ATLASSERT(hWndMenu != NULL); - - // this one is needed to close a menu if mouse button was down - ::PostMessage(hWndMenu, WM_LBUTTONUP, 0, MAKELPARAM(point.x, point.y)); - // this one closes a popup menu - ::PostMessage(hWndMenu, WM_KEYDOWN, VK_ESCAPE, 0L); - - bHandled = TRUE; - } - } - } - } - else - { - ScreenToClient(&point); - } - - s_point = point; - return 0; - } - - LRESULT OnHookSysKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - bHandled = FALSE; -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_SYSKEYDOWN (0x%2.2X)\n"), wParam); -#endif - - if(wParam == VK_MENU && m_bParentActive && m_bUseKeyboardCues && !m_bShowKeyboardCues && m_bAllowKeyboardCues) - ShowKeyboardCues(true); - - if(wParam != VK_SPACE && !m_bMenuActive && ::GetFocus() == m_hWnd) - { - m_bAllowKeyboardCues = false; - PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L); - T* pT = static_cast(this); - pT->GiveFocusBack(); - m_bSkipMsg = true; - } - else - { - if(wParam == VK_SPACE && m_bUseKeyboardCues && m_bShowKeyboardCues) - { - m_bAllowKeyboardCues = true; - ShowKeyboardCues(false); - } - m_uSysKey = (UINT)wParam; - } - return 0; - } - - LRESULT OnHookSysKeyUp(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - if(!m_bAllowKeyboardCues) - m_bAllowKeyboardCues = true; - bHandled = FALSE; - wParam; -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_SYSKEYUP (0x%2.2X)\n"), wParam); -#endif - return 0; - } - - LRESULT OnHookSysChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - bHandled = FALSE; -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_SYSCHAR (0x%2.2X)\n"), wParam); -#endif - - if(!m_bMenuActive && m_hWndHook != m_hWnd && wParam != VK_SPACE) - bHandled = TRUE; - return 0; - } - - LRESULT OnHookKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_KEYDOWN (0x%2.2X)\n"), wParam); -#endif - bHandled = FALSE; - T* pT = static_cast(this); - - if(wParam == VK_ESCAPE && m_stackMenuWnd.GetSize() <= 1) - { - if(m_bMenuActive && !m_bContextMenu) - { - int nHot = GetHotItem(); - if(nHot == -1) - nHot = m_nPopBtn; - if(nHot == -1) - nHot = 0; - SetHotItem(nHot); - bHandled = TRUE; - pT->TakeFocus(); - m_bEscapePressed = true; // To keep focus - m_bSkipPostDown = false; - } - else if(::GetFocus() == m_hWnd && m_wndParent.IsWindow()) - { - SetHotItem(-1); - pT->GiveFocusBack(); - bHandled = TRUE; - } - } - else if(wParam == VK_RETURN || wParam == VK_UP || wParam == VK_DOWN) - { - if(!m_bMenuActive && ::GetFocus() == m_hWnd && m_wndParent.IsWindow()) - { - int nHot = GetHotItem(); - if(nHot != -1) - { - if(wParam != VK_RETURN) - { - if(!m_bSkipPostDown) - { -// IE4 only: WM_KEYDOWN doesn't generate TBN_DROPDOWN, we need to simulate a mouse click -#if (_WIN32_IE < 0x0500) - DWORD dwMajor = 0, dwMinor = 0; - ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor); - if(dwMajor <= 4 || (dwMajor == 5 && dwMinor < 80)) - { - RECT rect; - GetItemRect(nHot, &rect); - PostMessage(WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(rect.left, rect.top)); - } -#endif // (_WIN32_IE < 0x0500) - PostMessage(WM_KEYDOWN, VK_DOWN, 0L); - m_bSkipPostDown = true; - } - else - { - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - skipping posting another VK_DOWN\n")); - m_bSkipPostDown = false; - } - } - } - else - { - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Can't find hot button\n")); - } - } - if(wParam == VK_RETURN && m_bMenuActive) - { - PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L); - m_nNextPopBtn = -1; - pT->GiveFocusBack(); - } - } - else if(wParam == VK_LEFT || wParam == VK_RIGHT) - { - WPARAM wpNext = m_bLayoutRTL ? VK_LEFT : VK_RIGHT; - WPARAM wpPrev = m_bLayoutRTL ? VK_RIGHT : VK_LEFT; - - if(m_bMenuActive && !m_bContextMenu && !(wParam == wpNext && m_bPopupItem)) - { - bool bAction = false; - if(wParam == wpPrev && s_pCurrentBar->m_stackMenuWnd.GetSize() == 1) - { - m_nNextPopBtn = pT->GetPreviousMenuItem(m_nPopBtn); - if(m_nNextPopBtn != -1) - bAction = true; - } - else if(wParam == wpNext) - { - m_nNextPopBtn = pT->GetNextMenuItem(m_nPopBtn); - if(m_nNextPopBtn != -1) - bAction = true; - } - HWND hWndMenu = m_stackMenuWnd.GetCurrent(); - ATLASSERT(hWndMenu != NULL); - - // Close the popup menu - if(bAction) - { - ::PostMessage(hWndMenu, WM_KEYDOWN, VK_ESCAPE, 0L); - if(wParam == wpNext) - { - int cItem = m_stackMenuWnd.GetSize() - 1; - while(cItem >= 0) - { - hWndMenu = m_stackMenuWnd[cItem]; - if(hWndMenu != NULL) - ::PostMessage(hWndMenu, WM_KEYDOWN, VK_ESCAPE, 0L); - cItem--; - } - } -#if (_WIN32_IE >= 0x0500) - if(m_nNextPopBtn == -2) - { - m_nNextPopBtn = -1; - pT->DisplayChevronMenu(); - } -#endif // (_WIN32_IE >= 0x0500) - bHandled = TRUE; - } - } - } - return 0; - } - - LRESULT OnHookNextMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_NEXTMENU\n")); -#endif - bHandled = FALSE; - return 1; - } - - LRESULT OnHookChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_CHAR (0x%2.2X)\n"), wParam); -#endif - bHandled = (wParam == VK_ESCAPE); - return 0; - } - -// Implementation - ownerdraw overrideables and helpers - void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) - { - T* pT = static_cast(this); - if(m_bFlatMenus) - pT->DrawItemFlat(lpDrawItemStruct); - else - pT->DrawItem3D(lpDrawItemStruct); - - } - - void DrawItem3D(LPDRAWITEMSTRUCT lpDrawItemStruct) - { - _MenuItemData* pmd = (_MenuItemData*)lpDrawItemStruct->itemData; - CDCHandle dc = lpDrawItemStruct->hDC; - const RECT& rcItem = lpDrawItemStruct->rcItem; - T* pT = static_cast(this); - - if(pmd->fType & MFT_SEPARATOR) - { - // draw separator - RECT rc = rcItem; - rc.top += (rc.bottom - rc.top) / 2; // vertical center - dc.DrawEdge(&rc, EDGE_ETCHED, BF_TOP); // draw separator line - } - else // not a separator - { - BOOL bDisabled = lpDrawItemStruct->itemState & ODS_GRAYED; - BOOL bSelected = lpDrawItemStruct->itemState & ODS_SELECTED; - BOOL bChecked = lpDrawItemStruct->itemState & ODS_CHECKED; - BOOL bHasImage = FALSE; - - if(LOWORD(lpDrawItemStruct->itemID) == (WORD)-1) - bSelected = FALSE; - RECT rcButn = { rcItem.left, rcItem.top, rcItem.left + m_szButton.cx, rcItem.top + m_szButton.cy }; // button rect - ::OffsetRect(&rcButn, 0, ((rcItem.bottom - rcItem.top) - (rcButn.bottom - rcButn.top)) / 2); // center vertically - - int iButton = pmd->iButton; - if(iButton >= 0) - { - bHasImage = TRUE; - - // calc drawing point - SIZE sz = { rcButn.right - rcButn.left - m_szBitmap.cx, rcButn.bottom - rcButn.top - m_szBitmap.cy }; - sz.cx /= 2; - sz.cy /= 2; - POINT point = { rcButn.left + sz.cx, rcButn.top + sz.cy }; - - // fill background depending on state - if(!bChecked || (bSelected && !bDisabled)) - { - if(!bDisabled) - dc.FillRect(&rcButn, (bChecked && !bSelected) ? COLOR_3DLIGHT : COLOR_MENU); - else - dc.FillRect(&rcButn, COLOR_MENU); - } - else - { - COLORREF crTxt = dc.SetTextColor(::GetSysColor(COLOR_BTNFACE)); - COLORREF crBk = dc.SetBkColor(::GetSysColor(COLOR_BTNHILIGHT)); - CBrush hbr(CDCHandle::GetHalftoneBrush()); - dc.SetBrushOrg(rcButn.left, rcButn.top); - dc.FillRect(&rcButn, hbr); - dc.SetTextColor(crTxt); - dc.SetBkColor(crBk); - } - - // draw disabled or normal - if(!bDisabled) - { - // draw pushed-in or popped-out edge - if(bSelected || bChecked) - { - RECT rc2 = rcButn; - dc.DrawEdge(&rc2, bChecked ? BDR_SUNKENOUTER : BDR_RAISEDINNER, BF_RECT); - } - // draw the image - ::ImageList_Draw(m_hImageList, iButton, dc, point.x, point.y, ILD_TRANSPARENT); - } - else - { - HBRUSH hBrushBackground = bChecked ? NULL : ::GetSysColorBrush(COLOR_MENU); - pT->DrawBitmapDisabled(dc, iButton, point, hBrushBackground); - } - } - else - { - // no image - look for custom checked/unchecked bitmaps - CMenuItemInfo info; - info.fMask = MIIM_CHECKMARKS | MIIM_TYPE; - ::GetMenuItemInfo((HMENU)lpDrawItemStruct->hwndItem, lpDrawItemStruct->itemID, MF_BYCOMMAND, &info); - if(bChecked || info.hbmpUnchecked != NULL) - { - BOOL bRadio = ((info.fType & MFT_RADIOCHECK) != 0); - bHasImage = pT->DrawCheckmark(dc, rcButn, bSelected, bDisabled, bRadio, bChecked ? info.hbmpChecked : info.hbmpUnchecked); - } - } - - // draw item text - int cxButn = m_szButton.cx; - COLORREF colorBG = ::GetSysColor(bSelected ? COLOR_HIGHLIGHT : COLOR_MENU); - if(bSelected || lpDrawItemStruct->itemAction == ODA_SELECT) - { - RECT rcBG = rcItem; - if(bHasImage) - rcBG.left += cxButn + s_kcxGap; - dc.FillRect(&rcBG, bSelected ? COLOR_HIGHLIGHT : COLOR_MENU); - } - - // calc text rectangle and colors - RECT rcText = rcItem; - rcText.left += cxButn + s_kcxGap + s_kcxTextMargin; - rcText.right -= cxButn; - dc.SetBkMode(TRANSPARENT); - COLORREF colorText = ::GetSysColor(bDisabled ? (bSelected ? COLOR_GRAYTEXT : COLOR_3DSHADOW) : (bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT)); - - // font already selected by Windows - if(bDisabled && (!bSelected || colorText == colorBG)) - { - // disabled - draw shadow text shifted down and right 1 pixel (unles selected) - RECT rcDisabled = rcText; - ::OffsetRect(&rcDisabled, 1, 1); - pT->DrawMenuText(dc, rcDisabled, pmd->lpstrText, ::GetSysColor(COLOR_3DHILIGHT)); - } - pT->DrawMenuText(dc, rcText, pmd->lpstrText, colorText); // finally! - } - } - - void DrawItemFlat(LPDRAWITEMSTRUCT lpDrawItemStruct) - { - _MenuItemData* pmd = (_MenuItemData*)lpDrawItemStruct->itemData; - CDCHandle dc = lpDrawItemStruct->hDC; - const RECT& rcItem = lpDrawItemStruct->rcItem; - T* pT = static_cast(this); - -#ifndef COLOR_MENUHILIGHT - const int COLOR_MENUHILIGHT = 29; -#endif // !COLOR_MENUHILIGHT - - BOOL bDisabled = lpDrawItemStruct->itemState & ODS_GRAYED; - BOOL bSelected = lpDrawItemStruct->itemState & ODS_SELECTED; - BOOL bChecked = lpDrawItemStruct->itemState & ODS_CHECKED; - - // paint background - if(bSelected || lpDrawItemStruct->itemAction == ODA_SELECT) - { - if(bSelected) - { - dc.FillRect(&rcItem, ::GetSysColorBrush(COLOR_MENUHILIGHT)); - dc.FrameRect(&rcItem, ::GetSysColorBrush(COLOR_HIGHLIGHT)); - } - else - { - dc.FillRect(&rcItem, ::GetSysColorBrush(COLOR_MENU)); - } - } - - if(pmd->fType & MFT_SEPARATOR) - { - // draw separator - RECT rc = rcItem; - rc.top += (rc.bottom - rc.top) / 2; // vertical center - dc.DrawEdge(&rc, EDGE_ETCHED, BF_TOP); // draw separator line - } - else // not a separator - { - if(LOWORD(lpDrawItemStruct->itemID) == (WORD)-1) - bSelected = FALSE; - RECT rcButn = { rcItem.left, rcItem.top, rcItem.left + m_szButton.cx, rcItem.top + m_szButton.cy }; // button rect - ::OffsetRect(&rcButn, 0, ((rcItem.bottom - rcItem.top) - (rcButn.bottom - rcButn.top)) / 2); // center vertically - - // draw background and border for checked items - if(bChecked) - { - RECT rcCheck = rcButn; - ::InflateRect(&rcCheck, -1, -1); - if(bSelected) - dc.FillRect(&rcCheck, ::GetSysColorBrush(COLOR_MENU)); - dc.FrameRect(&rcCheck, ::GetSysColorBrush(COLOR_HIGHLIGHT)); - } - - int iButton = pmd->iButton; - if(iButton >= 0) - { - // calc drawing point - SIZE sz = { rcButn.right - rcButn.left - m_szBitmap.cx, rcButn.bottom - rcButn.top - m_szBitmap.cy }; - sz.cx /= 2; - sz.cy /= 2; - POINT point = { rcButn.left + sz.cx, rcButn.top + sz.cy }; - - // draw disabled or normal - if(!bDisabled) - { - ::ImageList_Draw(m_hImageList, iButton, dc, point.x, point.y, ILD_TRANSPARENT); - } - else - { - HBRUSH hBrushBackground = ::GetSysColorBrush((bSelected && !(bDisabled && bChecked)) ? COLOR_MENUHILIGHT : COLOR_MENU); - HBRUSH hBrushDisabledImage = ::GetSysColorBrush(COLOR_3DSHADOW); - pT->DrawBitmapDisabled(dc, iButton, point, hBrushBackground, hBrushBackground, hBrushDisabledImage); - } - } - else - { - // no image - look for custom checked/unchecked bitmaps - CMenuItemInfo info; - info.fMask = MIIM_CHECKMARKS | MIIM_TYPE; - ::GetMenuItemInfo((HMENU)lpDrawItemStruct->hwndItem, lpDrawItemStruct->itemID, MF_BYCOMMAND, &info); - if(bChecked || info.hbmpUnchecked != NULL) - { - BOOL bRadio = ((info.fType & MFT_RADIOCHECK) != 0); - pT->DrawCheckmark(dc, rcButn, bSelected, bDisabled, bRadio, bChecked ? info.hbmpChecked : info.hbmpUnchecked); - } - } - - // draw item text - int cxButn = m_szButton.cx; - // calc text rectangle and colors - RECT rcText = rcItem; - rcText.left += cxButn + s_kcxGap + s_kcxTextMargin; - rcText.right -= cxButn; - dc.SetBkMode(TRANSPARENT); - COLORREF colorText = ::GetSysColor(bDisabled ? (bSelected ? COLOR_GRAYTEXT : COLOR_3DSHADOW) : (bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT)); - - pT->DrawMenuText(dc, rcText, pmd->lpstrText, colorText); // finally! - } - } - - void DrawMenuText(CDCHandle& dc, RECT& rc, LPCTSTR lpstrText, COLORREF color) - { - int nTab = -1; - for(int i = 0; i < lstrlen(lpstrText); i++) - { - if(lpstrText[i] == _T('\t')) - { - nTab = i; - break; - } - } - dc.SetTextColor(color); - dc.DrawText(lpstrText, nTab, &rc, DT_SINGLELINE | DT_LEFT | DT_VCENTER | (m_bShowKeyboardCues ? 0 : DT_HIDEPREFIX)); - if(nTab != -1) - dc.DrawText(&lpstrText[nTab + 1], -1, &rc, DT_SINGLELINE | DT_RIGHT | DT_VCENTER | (m_bShowKeyboardCues ? 0 : DT_HIDEPREFIX)); - } - - void DrawBitmapDisabled(CDCHandle& dc, int nImage, POINT point, - HBRUSH hBrushBackground = ::GetSysColorBrush(COLOR_3DFACE), - HBRUSH hBrush3DEffect = ::GetSysColorBrush(COLOR_3DHILIGHT), - HBRUSH hBrushDisabledImage = ::GetSysColorBrush(COLOR_3DSHADOW)) - { -#if (_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501) - if(m_bAlphaImages) - { - IMAGELISTDRAWPARAMS ildp = { 0 }; - ildp.cbSize = sizeof(IMAGELISTDRAWPARAMS); - ildp.himl = m_hImageList; - ildp.i = nImage; - ildp.hdcDst = dc; - ildp.x = point.x; - ildp.y = point.y; - ildp.cx = 0; - ildp.cy = 0; - ildp.xBitmap = 0; - ildp.yBitmap = 0; - ildp.fStyle = ILD_TRANSPARENT; - ildp.fState = ILS_SATURATE; - ildp.Frame = 0; - ::ImageList_DrawIndirect(&ildp); - } - else -#endif // (_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501) - { - // create memory DC - CDC dcMem; - dcMem.CreateCompatibleDC(dc); - // create mono or color bitmap - CBitmap bmp; - bmp.CreateCompatibleBitmap(dc, m_szBitmap.cx, m_szBitmap.cy); - ATLASSERT(bmp.m_hBitmap != NULL); - // draw image into memory DC--fill BG white first - HBITMAP hBmpOld = dcMem.SelectBitmap(bmp); - dcMem.PatBlt(0, 0, m_szBitmap.cx, m_szBitmap.cy, WHITENESS); - // If white is the text color, we can't use the normal painting since - // it would blend with the WHITENESS, but the mask is OK - UINT uDrawStyle = (::GetSysColor(COLOR_BTNTEXT) == RGB(255, 255, 255)) ? ILD_MASK : ILD_NORMAL; - ::ImageList_Draw(m_hImageList, nImage, dcMem, 0, 0, uDrawStyle); - dc.DitherBlt(point.x, point.y, m_szBitmap.cx, m_szBitmap.cy, dcMem, NULL, 0, 0, hBrushBackground, hBrush3DEffect, hBrushDisabledImage); - dcMem.SelectBitmap(hBmpOld); // restore - } - } - - // old name - BOOL Draw3DCheckmark(CDCHandle& dc, const RECT& rc, BOOL bSelected, BOOL bDisabled, BOOL bRadio, HBITMAP hBmpCheck) - { - return DrawCheckmark(dc, rc, bSelected, bDisabled, bRadio, hBmpCheck); - } - - BOOL DrawCheckmark(CDCHandle& dc, const RECT& rc, BOOL bSelected, BOOL bDisabled, BOOL bRadio, HBITMAP hBmpCheck) - { - // get checkmark bitmap, if none, use Windows standard - SIZE size = { 0, 0 }; - CBitmapHandle bmp = hBmpCheck; - if(hBmpCheck != NULL) - { - bmp.GetSize(size); - } - else - { - size.cx = ::GetSystemMetrics(SM_CXMENUCHECK); - size.cy = ::GetSystemMetrics(SM_CYMENUCHECK); - bmp.CreateCompatibleBitmap(dc, size.cx, size.cy); - ATLASSERT(bmp.m_hBitmap != NULL); - } - // center bitmap in caller's rectangle - RECT rcDest = rc; - if((rc.right - rc.left) > size.cx) - { - rcDest.left = rc.left + (rc.right - rc.left - size.cx) / 2; - rcDest.right = rcDest.left + size.cx; - } - if((rc.bottom - rc.top) > size.cy) - { - rcDest.top = rc.top + (rc.bottom - rc.top - size.cy) / 2; - rcDest.bottom = rcDest.top + size.cy; - } - // paint background - if(!m_bFlatMenus) - { - if(bSelected && !bDisabled) - { - dc.FillRect(&rcDest, COLOR_MENU); - } - else - { - COLORREF clrTextOld = dc.SetTextColor(::GetSysColor(COLOR_BTNFACE)); - COLORREF clrBkOld = dc.SetBkColor(::GetSysColor(COLOR_BTNHILIGHT)); - CBrush hbr(CDCHandle::GetHalftoneBrush()); - dc.SetBrushOrg(rcDest.left, rcDest.top); - dc.FillRect(&rcDest, hbr); - dc.SetTextColor(clrTextOld); - dc.SetBkColor(clrBkOld); - } - } - - // create source image - CDC dcSource; - dcSource.CreateCompatibleDC(dc); - HBITMAP hBmpOld = dcSource.SelectBitmap(bmp); - // set colors - const COLORREF clrBlack = RGB(0, 0, 0); - const COLORREF clrWhite = RGB(255, 255, 255); - COLORREF clrTextOld = dc.SetTextColor(clrBlack); - COLORREF clrBkOld = dc.SetBkColor(clrWhite); - // create mask - CDC dcMask; - dcMask.CreateCompatibleDC(dc); - CBitmap bmpMask; - bmpMask.CreateBitmap(size.cx, size.cy, 1, 1, NULL); - HBITMAP hBmpOld1 = dcMask.SelectBitmap(bmpMask); - - // draw the checkmark transparently - int cx = rcDest.right - rcDest.left; - int cy = rcDest.bottom - rcDest.top; - if(hBmpCheck != NULL) - { - // build mask based on transparent color - dcSource.SetBkColor(m_clrMask); - dcMask.SetBkColor(clrBlack); - dcMask.SetTextColor(clrWhite); - dcMask.BitBlt(0, 0, size.cx, size.cy, dcSource, 0, 0, SRCCOPY); - // draw bitmap using the mask - dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcSource, 0, 0, SRCINVERT); - dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcMask, 0, 0, SRCAND); - dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcSource, 0, 0, SRCINVERT); - } - else - { - const DWORD ROP_DSno = 0x00BB0226L; - const DWORD ROP_DSa = 0x008800C6L; - const DWORD ROP_DSo = 0x00EE0086L; - const DWORD ROP_DSna = 0x00220326L; - - // draw mask - RECT rcSource = { 0, 0, min(size.cx, rc.right - rc.left), min(size.cy, rc.bottom - rc.top) }; - dcMask.DrawFrameControl(&rcSource, DFC_MENU, bRadio ? DFCS_MENUBULLET : DFCS_MENUCHECK); - - // draw shadow if disabled - if(!m_bFlatMenus && bDisabled) - { - // offset by one pixel - int x = rcDest.left + 1; - int y = rcDest.top + 1; - // paint source bitmap - const int nColor = COLOR_3DHILIGHT; - dcSource.FillRect(&rcSource, nColor); - // draw checkmark - special case black and white colors - COLORREF clrCheck = ::GetSysColor(nColor); - if(clrCheck == clrWhite) - { - dc.BitBlt(x, y, cx, cy, dcMask, 0, 0, ROP_DSno); - dc.BitBlt(x, y, cx, cy, dcSource, 0, 0, ROP_DSa); - } - else - { - if(clrCheck != clrBlack) - { - ATLASSERT(dcSource.GetTextColor() == clrBlack); - ATLASSERT(dcSource.GetBkColor() == clrWhite); - dcSource.BitBlt(0, 0, size.cx, size.cy, dcMask, 0, 0, ROP_DSna); - } - dc.BitBlt(x, y, cx, cy, dcMask, 0, 0, ROP_DSa); - dc.BitBlt(x, y, cx, cy, dcSource, 0, 0, ROP_DSo); - } - } - - // paint source bitmap - const int nColor = bDisabled ? COLOR_BTNSHADOW : COLOR_MENUTEXT; - dcSource.FillRect(&rcSource, nColor); - // draw checkmark - special case black and white colors - COLORREF clrCheck = ::GetSysColor(nColor); - if(clrCheck == clrWhite) - { - dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcMask, 0, 0, ROP_DSno); - dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcSource, 0, 0, ROP_DSa); - } - else - { - if(clrCheck != clrBlack) - { - ATLASSERT(dcSource.GetTextColor() == clrBlack); - ATLASSERT(dcSource.GetBkColor() == clrWhite); - dcSource.BitBlt(0, 0, size.cx, size.cy, dcMask, 0, 0, ROP_DSna); - } - dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcMask, 0, 0, ROP_DSa); - dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcSource, 0, 0, ROP_DSo); - } - } - // restore all - dc.SetTextColor(clrTextOld); - dc.SetBkColor(clrBkOld); - dcSource.SelectBitmap(hBmpOld); - dcMask.SelectBitmap(hBmpOld1); - if(hBmpCheck == NULL) - bmp.DeleteObject(); - // draw pushed-in hilight - if(!m_bFlatMenus && !bDisabled) - { - if(rc.right - rc.left > size.cx) - ::InflateRect(&rcDest, 1,1); // inflate checkmark by one pixel all around - dc.DrawEdge(&rcDest, BDR_SUNKENOUTER, BF_RECT); - } - - return TRUE; - } - - void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) - { - _MenuItemData* pmd = (_MenuItemData*)lpMeasureItemStruct->itemData; - - if(pmd->fType & MFT_SEPARATOR) // separator - use half system height and zero width - { - lpMeasureItemStruct->itemHeight = ::GetSystemMetrics(SM_CYMENU) / 2; - lpMeasureItemStruct->itemWidth = 0; - } - else - { - // compute size of text - use DrawText with DT_CALCRECT - CWindowDC dc(NULL); - CFont fontBold; - HFONT hOldFont = NULL; - if(pmd->fState & MFS_DEFAULT) - { - // need bold version of font - LOGFONT lf = { 0 }; - m_fontMenu.GetLogFont(lf); - lf.lfWeight += 200; - fontBold.CreateFontIndirect(&lf); - ATLASSERT(fontBold.m_hFont != NULL); - hOldFont = dc.SelectFont(fontBold); - } - else - { - hOldFont = dc.SelectFont(m_fontMenu); - } - - RECT rcText = { 0, 0, 0, 0 }; - dc.DrawText(pmd->lpstrText, -1, &rcText, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT); - int cx = rcText.right - rcText.left; - dc.SelectFont(hOldFont); - - LOGFONT lf = { 0 }; - m_fontMenu.GetLogFont(lf); - int cy = lf.lfHeight; - if(cy < 0) - cy = -cy; - const int cyMargin = 8; - cy += cyMargin; - - // height of item is the bigger of these two - lpMeasureItemStruct->itemHeight = max(cy, (int)m_szButton.cy); - - // width is width of text plus a bunch of stuff - cx += 2 * s_kcxTextMargin; // L/R margin for readability - cx += s_kcxGap; // space between button and menu text - cx += 2 * m_szButton.cx; // button width (L=button; R=empty margin) - cx += m_cxExtraSpacing; // extra between item text and accelerator keys - - // Windows adds 1 to returned value - cx -= ::GetSystemMetrics(SM_CXMENUCHECK) - 1; - lpMeasureItemStruct->itemWidth = cx; // done deal - } - } - -// Implementation - Hook procs - static LRESULT CALLBACK CreateHookProc(int nCode, WPARAM wParam, LPARAM lParam) - { - const int cchClassName = 7; - TCHAR szClassName[cchClassName] = { 0 }; - - if(nCode == HCBT_CREATEWND) - { - HWND hWndMenu = (HWND)wParam; -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - HCBT_CREATEWND (HWND = %8.8X)\n"), hWndMenu); -#endif - - ::GetClassName(hWndMenu, szClassName, cchClassName); - if(!lstrcmp(_T("#32768"), szClassName)) - s_pCurrentBar->m_stackMenuWnd.Push(hWndMenu); - } - else if(nCode == HCBT_DESTROYWND) - { - HWND hWndMenu = (HWND)wParam; -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - HCBT_DESTROYWND (HWND = %8.8X)\n"), hWndMenu); -#endif - - ::GetClassName(hWndMenu, szClassName, cchClassName); - if(!lstrcmp(_T("#32768"), szClassName)) - { - ATLASSERT(hWndMenu == s_pCurrentBar->m_stackMenuWnd.GetCurrent()); - s_pCurrentBar->m_stackMenuWnd.Pop(); - } - } - - return ::CallNextHookEx(s_hCreateHook, nCode, wParam, lParam); - } - - static LRESULT CALLBACK MessageHookProc(int nCode, WPARAM wParam, LPARAM lParam) - { - LPMSG pMsg = (LPMSG)lParam; - - if(nCode == HC_ACTION && wParam == PM_REMOVE && pMsg->message != GetGetBarMessage() && pMsg->message != WM_FORWARDMSG) - { - CCommandBarCtrlBase* pCmdBar = NULL; - HWND hWnd = pMsg->hwnd; - DWORD dwPID = 0; - while(pCmdBar == NULL && hWnd != NULL) - { - pCmdBar = (CCommandBarCtrlBase*)::SendMessage(hWnd, GetGetBarMessage(), (WPARAM)&dwPID, 0L); - hWnd = ::GetParent(hWnd); - } - - if(pCmdBar != NULL && dwPID == GetCurrentProcessId()) - { - pCmdBar->m_hWndHook = pMsg->hwnd; - ATLASSERT(pCmdBar->IsCommandBarBase()); - - if(::IsWindow(pCmdBar->m_hWnd)) - pCmdBar->SendMessage(WM_FORWARDMSG, 0, (LPARAM)pMsg); - else - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook skipping message, can't find command bar!\n")); - } - } - - LRESULT lRet = 0; - ATLASSERT(s_pmapMsgHook != NULL); - if(s_pmapMsgHook != NULL) - { - DWORD dwThreadID = ::GetCurrentThreadId(); - _MsgHookData* pData = s_pmapMsgHook->Lookup(dwThreadID); - if(pData != NULL) - { - lRet = ::CallNextHookEx(pData->hMsgHook, nCode, wParam, lParam); - } - } - return lRet; - } - -// Implementation - void DoPopupMenu(int nIndex, bool bAnimate) - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - DoPopupMenu, bAnimate = %s\n"), bAnimate ? "true" : "false"); -#endif - - // Menu animation flags -#ifndef TPM_VERPOSANIMATION - const UINT TPM_VERPOSANIMATION = 0x1000L; -#endif -#ifndef TPM_NOANIMATION - const UINT TPM_NOANIMATION = 0x4000L; -#endif - T* pT = static_cast(this); - - // get popup menu and it's position - RECT rect = { 0 }; - GetItemRect(nIndex, &rect); - POINT pt = { rect.left, rect.bottom }; - MapWindowPoints(NULL, &pt, 1); - MapWindowPoints(NULL, &rect); - TPMPARAMS TPMParams = { 0 }; - TPMParams.cbSize = sizeof(TPMPARAMS); - TPMParams.rcExclude = rect; - HMENU hMenuPopup = ::GetSubMenu(m_hMenu, nIndex); - ATLASSERT(hMenuPopup != NULL); - - // get button ID - TBBUTTON tbb = { 0 }; - GetButton(nIndex, &tbb); - int nCmdID = tbb.idCommand; - - m_nPopBtn = nIndex; // remember current button's index - - // press button and display popup menu - PressButton(nCmdID, TRUE); - SetHotItem(nCmdID); - pT->DoTrackPopupMenu(hMenuPopup, TPM_LEFTBUTTON | TPM_VERTICAL | TPM_LEFTALIGN | TPM_TOPALIGN | - (s_bW2K ? (bAnimate ? TPM_VERPOSANIMATION : TPM_NOANIMATION) : 0), pt.x, pt.y, &TPMParams); - PressButton(nCmdID, FALSE); - if(::GetFocus() != m_hWnd) - SetHotItem(-1); - - m_nPopBtn = -1; // restore - - // eat next message if click is on the same button - MSG msg = { 0 }; - if(::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE) && ::PtInRect(&rect, msg.pt)) - ::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_REMOVE); - - // check if another popup menu should be displayed - if(m_nNextPopBtn != -1) - { - PostMessage(GetAutoPopupMessage(), m_nNextPopBtn & 0xFFFF); - if(!(m_nNextPopBtn & 0xFFFF0000) && !m_bPopupItem) - PostMessage(WM_KEYDOWN, VK_DOWN, 0); - m_nNextPopBtn = -1; - } - else - { - m_bContextMenu = false; - // If user didn't hit escape, give focus back - if(!m_bEscapePressed) - { - if(m_bUseKeyboardCues && m_bShowKeyboardCues) - m_bAllowKeyboardCues = false; - pT->GiveFocusBack(); - } - else - { - SetHotItem(nCmdID); - SetAnchorHighlight(TRUE); - } - } - } - - BOOL DoTrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y, LPTPMPARAMS lpParams = NULL) - { - CMenuHandle menuPopup = hMenu; - - CWindowCreateCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::DoTrackPopupMenu.\n")); - ATLASSERT(FALSE); - return FALSE; - } - - ATLASSERT(s_hCreateHook == NULL); - - s_pCurrentBar = static_cast(this); - - s_hCreateHook = ::SetWindowsHookEx(WH_CBT, CreateHookProc, ModuleHelper::GetModuleInstance(), GetCurrentThreadId()); - ATLASSERT(s_hCreateHook != NULL); - - m_bPopupItem = false; - m_bMenuActive = true; - - BOOL bTrackRet = menuPopup.TrackPopupMenuEx(uFlags, x, y, m_hWnd, lpParams); - m_bMenuActive = false; - - ::UnhookWindowsHookEx(s_hCreateHook); - - s_hCreateHook = NULL; - s_pCurrentBar = NULL; - - lock.Unlock(); - - // cleanup - convert menus back to original state -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - TrackPopupMenu - cleanup\n")); -#endif - - ATLASSERT(m_stackMenuWnd.GetSize() == 0); - - UpdateWindow(); - ATL::CWindow wndTL = GetTopLevelParent(); - wndTL.UpdateWindow(); - - // restore the menu items to the previous state for all menus that were converted - if(m_bImagesVisible) - { - HMENU hMenuSav = NULL; - while((hMenuSav = m_stackMenuHandle.Pop()) != NULL) - { - menuPopup = hMenuSav; - BOOL bRet = FALSE; - // restore state and delete menu item data - for(int i = 0; i < menuPopup.GetMenuItemCount(); i++) - { - CMenuItemInfo mii; - mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_ID; - bRet = menuPopup.GetMenuItemInfo(i, TRUE, &mii); - ATLASSERT(bRet); - - _MenuItemData* pMI = (_MenuItemData*)mii.dwItemData; - if(pMI != NULL && pMI->IsCmdBarMenuItem()) - { - mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_STATE; - mii.fType = pMI->fType; - mii.fState = pMI->fState; - mii.dwTypeData = pMI->lpstrText; - mii.cch = lstrlen(pMI->lpstrText); - mii.dwItemData = NULL; - - bRet = menuPopup.SetMenuItemInfo(i, TRUE, &mii); - // this one triggers WM_MEASUREITEM - menuPopup.ModifyMenu(i, MF_BYPOSITION | mii.fType | mii.fState, mii.wID, pMI->lpstrText); - ATLASSERT(bRet); - - delete [] pMI->lpstrText; - delete pMI; - } - } - } - } - return bTrackRet; - } - - int GetPreviousMenuItem(int nBtn) const - { - if(nBtn == -1) - return -1; -#if (_WIN32_IE >= 0x0500) - RECT rcClient; - GetClientRect(&rcClient); -#endif // (_WIN32_IE >= 0x0500) - int nNextBtn; - for(nNextBtn = nBtn - 1; nNextBtn != nBtn; nNextBtn--) - { - if(nNextBtn < 0) - nNextBtn = ::GetMenuItemCount(m_hMenu) - 1; - TBBUTTON tbb = { 0 }; - GetButton(nNextBtn, &tbb); -#if (_WIN32_IE >= 0x0500) - RECT rcBtn; - GetItemRect(nNextBtn, &rcBtn); - if(rcBtn.right > rcClient.right) - { - nNextBtn = -2; // chevron - break; - } -#endif // (_WIN32_IE >= 0x0500) - if((tbb.fsState & TBSTATE_ENABLED) != 0 && (tbb.fsState & TBSTATE_HIDDEN) == 0) - break; - } - return (nNextBtn != nBtn) ? nNextBtn : -1; - } - - int GetNextMenuItem(int nBtn) const - { - if(nBtn == -1) - return -1; -#if (_WIN32_IE >= 0x0500) - RECT rcClient = { 0 }; - GetClientRect(&rcClient); -#endif // (_WIN32_IE >= 0x0500) - int nNextBtn = 0; - int nCount = ::GetMenuItemCount(m_hMenu); - for(nNextBtn = nBtn + 1; nNextBtn != nBtn; nNextBtn++) - { - if(nNextBtn >= nCount) - nNextBtn = 0; - TBBUTTON tbb = { 0 }; - GetButton(nNextBtn, &tbb); -#if (_WIN32_IE >= 0x0500) - RECT rcBtn = { 0 }; - GetItemRect(nNextBtn, &rcBtn); - if(rcBtn.right > rcClient.right) - { - nNextBtn = -2; // chevron - break; - } -#endif // (_WIN32_IE >= 0x0500) - if((tbb.fsState & TBSTATE_ENABLED) != 0 && (tbb.fsState & TBSTATE_HIDDEN) == 0) - break; - } - return (nNextBtn != nBtn) ? nNextBtn : -1; - } - -#if (_WIN32_IE >= 0x0500) - bool DisplayChevronMenu() - { - // assume we are in a rebar - HWND hWndReBar = GetParent(); - int nCount = (int)::SendMessage(hWndReBar, RB_GETBANDCOUNT, 0, 0L); - bool bRet = false; - for(int i = 0; i < nCount; i++) - { - REBARBANDINFO rbbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_STYLE }; - BOOL bRetBandInfo = (BOOL)::SendMessage(hWndReBar, RB_GETBANDINFO, i, (LPARAM)&rbbi); - if(bRetBandInfo && rbbi.hwndChild == m_hWnd) - { - if((rbbi.fStyle & RBBS_USECHEVRON) != 0) - { - ::PostMessage(hWndReBar, RB_PUSHCHEVRON, i, 0L); - PostMessage(WM_KEYDOWN, VK_DOWN, 0L); - bRet = true; - } - break; - } - } - return bRet; - } -#endif // (_WIN32_IE >= 0x0500) - - void GetSystemSettings() - { - // refresh our font - NONCLIENTMETRICS info = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() }; - BOOL bRet = ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0); - ATLASSERT(bRet); - if(bRet) - { - LOGFONT logfont = { 0 }; - if(m_fontMenu.m_hFont != NULL) - m_fontMenu.GetLogFont(logfont); - if(logfont.lfHeight != info.lfMenuFont.lfHeight || - logfont.lfWidth != info.lfMenuFont.lfWidth || - logfont.lfEscapement != info.lfMenuFont.lfEscapement || - logfont.lfOrientation != info.lfMenuFont.lfOrientation || - logfont.lfWeight != info.lfMenuFont.lfWeight || - logfont.lfItalic != info.lfMenuFont.lfItalic || - logfont.lfUnderline != info.lfMenuFont.lfUnderline || - logfont.lfStrikeOut != info.lfMenuFont.lfStrikeOut || - logfont.lfCharSet != info.lfMenuFont.lfCharSet || - logfont.lfOutPrecision != info.lfMenuFont.lfOutPrecision || - logfont.lfClipPrecision != info.lfMenuFont.lfClipPrecision || - logfont.lfQuality != info.lfMenuFont.lfQuality || - logfont.lfPitchAndFamily != info.lfMenuFont.lfPitchAndFamily || - lstrcmp(logfont.lfFaceName, info.lfMenuFont.lfFaceName) != 0) - { - HFONT hFontMenu = ::CreateFontIndirect(&info.lfMenuFont); - ATLASSERT(hFontMenu != NULL); - if(hFontMenu != NULL) - { - if(m_fontMenu.m_hFont != NULL) - m_fontMenu.DeleteObject(); - m_fontMenu.Attach(hFontMenu); - SetFont(m_fontMenu); - AddStrings(_T("NS\0")); // for proper item height - AutoSize(); - } - } - } - - // check if we need extra spacing for menu item text - CWindowDC dc(m_hWnd); - HFONT hFontOld = dc.SelectFont(m_fontMenu); - RECT rcText = { 0, 0, 0, 0 }; - dc.DrawText(_T("\t"), -1, &rcText, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT); - if((rcText.right - rcText.left) < 4) - { - ::SetRectEmpty(&rcText); - dc.DrawText(_T("x"), -1, &rcText, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT); - m_cxExtraSpacing = rcText.right - rcText.left; - } - else - { - m_cxExtraSpacing = 0; - } - dc.SelectFont(hFontOld); - - // get Windows version - OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) }; - ::GetVersionEx(&ovi); - - // query keyboard cues mode (Windows 2000 or later) - if(ovi.dwMajorVersion >= 5) - { -#ifndef SPI_GETKEYBOARDCUES - const UINT SPI_GETKEYBOARDCUES = 0x100A; -#endif // !SPI_GETKEYBOARDCUES - BOOL bRetVal = TRUE; - bRet = ::SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &bRetVal, 0); - m_bUseKeyboardCues = (bRet && !bRetVal); - m_bAllowKeyboardCues = true; - ShowKeyboardCues(!m_bUseKeyboardCues); - } - - // query flat menu mode (Windows XP or later) - if((ovi.dwMajorVersion == 5 && ovi.dwMinorVersion >= 1) || (ovi.dwMajorVersion > 5)) - { -#ifndef SPI_GETFLATMENU - const UINT SPI_GETFLATMENU = 0x1022; -#endif // !SPI_GETFLATMENU - BOOL bRetVal = FALSE; - bRet = ::SystemParametersInfo(SPI_GETFLATMENU, 0, &bRetVal, 0); - m_bFlatMenus = (bRet && bRetVal); - } - -#if _WTL_CMDBAR_VISTA_MENUS - // check if we should use Vista menus - bool bVistaMenus = (RunTimeHelper::IsVista() && RunTimeHelper::IsCommCtrl6() && ((m_dwExtendedStyle & CBR_EX_NOVISTAMENUS) == 0)); - - if(bVistaMenus) - { - HMODULE hThemeDLL = ::LoadLibrary(_T("uxtheme.dll")); - if(hThemeDLL != NULL) - { - typedef BOOL (STDAPICALLTYPE *PFN_IsThemeActive)(); - PFN_IsThemeActive pfnIsThemeActive = (PFN_IsThemeActive)::GetProcAddress(hThemeDLL, "IsThemeActive"); - ATLASSERT(pfnIsThemeActive != NULL); - bVistaMenus = bVistaMenus && (pfnIsThemeActive != NULL) && (pfnIsThemeActive() != FALSE); - - typedef BOOL (STDAPICALLTYPE *PFN_IsAppThemed)(); - PFN_IsAppThemed pfnIsAppThemed = (PFN_IsAppThemed)::GetProcAddress(hThemeDLL, "IsAppThemed"); - ATLASSERT(pfnIsAppThemed != NULL); - bVistaMenus = bVistaMenus && (pfnIsAppThemed != NULL) && (pfnIsAppThemed() != FALSE); - - ::FreeLibrary(hThemeDLL); - } - } - - if(!bVistaMenus && m_bVistaMenus && (m_hMenu != NULL) && (m_arrCommand.GetSize() > 0)) - { - T* pT = static_cast(this); - pT->_RemoveVistaBitmapsFromMenu(); - } - - m_bVistaMenus = bVistaMenus; -#endif // _WTL_CMDBAR_VISTA_MENUS - -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("CmdBar - GetSystemSettings:\n m_bFlatMenus = %s\n m_bUseKeyboardCues = %s m_bVistaMenus = %s\n"), - m_bFlatMenus ? "true" : "false", m_bUseKeyboardCues ? "true" : "false", m_bVistaMenus ? "true" : "false"); -#endif - } - -// Implementation - alternate focus mode support - void TakeFocus() - { - if((m_dwExtendedStyle & CBR_EX_ALTFOCUSMODE) && m_hWndFocus == NULL) - m_hWndFocus = ::GetFocus(); - SetFocus(); - } - - void GiveFocusBack() - { - if(m_bParentActive) - { - if((m_dwExtendedStyle & CBR_EX_ALTFOCUSMODE) && ::IsWindow(m_hWndFocus)) - ::SetFocus(m_hWndFocus); - else if(!(m_dwExtendedStyle & CBR_EX_ALTFOCUSMODE) && m_wndParent.IsWindow()) - m_wndParent.SetFocus(); - } - m_hWndFocus = NULL; - SetAnchorHighlight(FALSE); - if(m_bUseKeyboardCues && m_bShowKeyboardCues) - ShowKeyboardCues(false); - m_bSkipPostDown = false; - } - - void ShowKeyboardCues(bool bShow) - { - m_bShowKeyboardCues = bShow; - SetDrawTextFlags(DT_HIDEPREFIX, m_bShowKeyboardCues ? 0 : DT_HIDEPREFIX); - Invalidate(); - UpdateWindow(); - } - -// Implementation - internal message helpers - static UINT GetAutoPopupMessage() - { - static UINT uAutoPopupMessage = 0; - if(uAutoPopupMessage == 0) - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::GetAutoPopupMessage.\n")); - ATLASSERT(FALSE); - return 0; - } - - if(uAutoPopupMessage == 0) - uAutoPopupMessage = ::RegisterWindowMessage(_T("WTL_CmdBar_InternalAutoPopupMsg")); - - lock.Unlock(); - } - ATLASSERT(uAutoPopupMessage != 0); - return uAutoPopupMessage; - } - - static UINT GetGetBarMessage() - { - static UINT uGetBarMessage = 0; - if(uGetBarMessage == 0) - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::GetGetBarMessage.\n")); - ATLASSERT(FALSE); - return 0; - } - - if(uGetBarMessage == 0) - uGetBarMessage = ::RegisterWindowMessage(_T("WTL_CmdBar_InternalGetBarMsg")); - - lock.Unlock(); - } - ATLASSERT(uGetBarMessage != 0); - return uGetBarMessage; - } - -// Implementation - bool CreateInternalImageList(int cImages) - { - UINT uFlags = (m_bAlphaImages ? ILC_COLOR32 : ILC_COLOR24) | ILC_MASK; - m_hImageList = ::ImageList_Create(m_szBitmap.cx, m_szBitmap.cy, uFlags, cImages, 1); - ATLASSERT(m_hImageList != NULL); - return (m_hImageList != NULL); - } - -// Implementation - support for Vista menus -#if _WTL_CMDBAR_VISTA_MENUS - void _AddVistaBitmapsFromImageList(int nStartIndex, int nCount) - { - // Create display compatible memory DC - CClientDC dc(NULL); - CDC dcMem; - dcMem.CreateCompatibleDC(dc); - HBITMAP hBitmapSave = dcMem.GetCurrentBitmap(); - - T* pT = static_cast(this); - // Create bitmaps for all menu items - for(int i = 0; i < nCount; i++) - { - HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nStartIndex + i, dc, dcMem); - dcMem.SelectBitmap(hBitmapSave); - m_arrVistaBitmap.Add(hBitmap); - } - } - - void _AddVistaBitmapFromImageList(int nIndex) - { - // Create display compatible memory DC - CClientDC dc(NULL); - CDC dcMem; - dcMem.CreateCompatibleDC(dc); - HBITMAP hBitmapSave = dcMem.GetCurrentBitmap(); - - // Create bitmap for menu item - T* pT = static_cast(this); - HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nIndex, dc, dcMem); - - // Select saved bitmap back and add bitmap to the array - dcMem.SelectBitmap(hBitmapSave); - m_arrVistaBitmap.Add(hBitmap); - } - - void _ReplaceVistaBitmapFromImageList(int nIndex) - { - // Delete existing bitmap - if(m_arrVistaBitmap[nIndex] != NULL) - ::DeleteObject(m_arrVistaBitmap[nIndex]); - - // Create display compatible memory DC - CClientDC dc(NULL); - CDC dcMem; - dcMem.CreateCompatibleDC(dc); - HBITMAP hBitmapSave = dcMem.GetCurrentBitmap(); - - // Create bitmap for menu item - T* pT = static_cast(this); - HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nIndex, dc, dcMem); - - // Select saved bitmap back and replace bitmap in the array - dcMem.SelectBitmap(hBitmapSave); - m_arrVistaBitmap.SetAtIndex(nIndex, hBitmap); - } - - HBITMAP _CreateVistaBitmapHelper(int nIndex, HDC hDCSource, HDC hDCTarget) - { - // Create 32-bit bitmap - BITMAPINFO bi = { 0 }; - bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bi.bmiHeader.biWidth = m_szBitmap.cx; - bi.bmiHeader.biHeight = m_szBitmap.cy; - bi.bmiHeader.biPlanes = 1; - bi.bmiHeader.biBitCount = 32; - bi.bmiHeader.biCompression = BI_RGB; - bi.bmiHeader.biSizeImage = 0; - bi.bmiHeader.biXPelsPerMeter = 0; - bi.bmiHeader.biYPelsPerMeter = 0; - bi.bmiHeader.biClrUsed = 0; - bi.bmiHeader.biClrImportant = 0; - HBITMAP hBitmap = ::CreateDIBSection(hDCSource, &bi, DIB_RGB_COLORS, NULL, NULL, 0); - ATLASSERT(hBitmap != NULL); - - // Select bitmap into target DC and draw from image list to it - if(hBitmap != NULL) - { - ::SelectObject(hDCTarget, hBitmap); - - IMAGELISTDRAWPARAMS ildp = { 0 }; - ildp.cbSize = sizeof(IMAGELISTDRAWPARAMS); - ildp.himl = m_hImageList; - ildp.i = nIndex; - ildp.hdcDst = hDCTarget; - ildp.x = 0; - ildp.y = 0; - ildp.cx = 0; - ildp.cy = 0; - ildp.xBitmap = 0; - ildp.yBitmap = 0; - ildp.fStyle = ILD_TRANSPARENT; - ildp.fState = ILS_ALPHA; - ildp.Frame = 255; - ::ImageList_DrawIndirect(&ildp); - } - - return hBitmap; - } - - void _RemoveVistaBitmapsFromMenu() - { - CMenuHandle menu = m_hMenu; - for(int i = 0; i < m_arrCommand.GetSize(); i++) - { - CMenuItemInfo mii; - mii.fMask = MIIM_BITMAP; - mii.hbmpItem = NULL; - menu.SetMenuItemInfo(m_arrCommand[i], FALSE, &mii); - } - } -#endif // _WTL_CMDBAR_VISTA_MENUS -}; - - -class CCommandBarCtrl : public CCommandBarCtrlImpl -{ -public: - DECLARE_WND_SUPERCLASS(_T("WTL_CommandBar"), GetWndClassName()) -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CMDICommandBarCtrl - ATL implementation of Command Bars for MDI apps - -template -class ATL_NO_VTABLE CMDICommandBarCtrlImpl : public CCommandBarCtrlImpl< T, TBase, TWinTraits> -{ -public: -// Data members - ATL::CContainedWindow m_wndMDIClient; - bool m_bChildMaximized; - HWND m_hWndChildMaximized; - HICON m_hIconChildMaximized; - int m_nBtnPressed; - int m_nBtnWasPressed; - - int m_cxyOffset; // offset between nonclient elements - int m_cxIconWidth; // small icon width - int m_cyIconHeight; // small icon height - int m_cxBtnWidth; // nonclient button width - int m_cyBtnHeight; // nonclient button height - int m_cxLeft; // left nonclient area width - int m_cxRight; // right nonclient area width - -// Theme declarations and data members -#ifndef _WTL_NO_AUTO_THEME -#ifndef _UXTHEME_H_ - typedef HANDLE HTHEME; -#endif // !_UXTHEME_H_ - typedef HTHEME (STDAPICALLTYPE *PFN_OpenThemeData)(HWND hwnd, LPCWSTR pszClassList); - typedef HRESULT (STDAPICALLTYPE *PFN_CloseThemeData)(HTHEME hTheme); - typedef HRESULT (STDAPICALLTYPE *PFN_DrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect); - typedef HRESULT (STDAPICALLTYPE *PFN_DrawThemeParentBackground)(HWND hwnd, HDC hdc, OPTIONAL RECT* prc); - - HMODULE m_hThemeDLL; - HTHEME m_hTheme; - PFN_DrawThemeBackground m_pfnDrawThemeBackground; - PFN_DrawThemeParentBackground m_pfnDrawThemeParentBackground; -#endif // !_WTL_NO_AUTO_THEME - -// Constructor/destructor - CMDICommandBarCtrlImpl() : - m_wndMDIClient(this, 2), m_bChildMaximized(false), - m_hWndChildMaximized(NULL), m_hIconChildMaximized(NULL), - m_nBtnPressed(-1), m_nBtnWasPressed(-1), -#ifndef _WTL_NO_AUTO_THEME - m_hThemeDLL(NULL), m_hTheme(NULL), m_pfnDrawThemeBackground(NULL), m_pfnDrawThemeParentBackground(NULL), -#endif // !_WTL_NO_AUTO_THEME - m_cxyOffset(2), - m_cxIconWidth(16), m_cyIconHeight(16), - m_cxBtnWidth(16), m_cyBtnHeight(14), - m_cxLeft(20), m_cxRight(55) - { } - - ~CMDICommandBarCtrlImpl() - { - if(m_wndMDIClient.IsWindow()) -/*scary!*/ m_wndMDIClient.UnsubclassWindow(); - } - -// Operations - BOOL SetMDIClient(HWND hWndMDIClient) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(::IsWindow(hWndMDIClient)); - if(!::IsWindow(hWndMDIClient)) - return FALSE; - -#ifdef _DEBUG - // BLOCK: Test if the passed window is MDICLIENT - { - LPCTSTR lpszMDIClientClass = _T("MDICLIENT"); - const int nNameLen = 9 + 1; // "MDICLIENT" + NULL - TCHAR szClassName[nNameLen] = { 0 }; - ::GetClassName(hWndMDIClient, szClassName, nNameLen); - ATLASSERT(lstrcmpi(szClassName, lpszMDIClientClass) == 0); - } -#endif // _DEBUG - - if(m_wndMDIClient.IsWindow()) -/*scary!*/ m_wndMDIClient.UnsubclassWindow(); - - return m_wndMDIClient.SubclassWindow(hWndMDIClient); - } - -// Message maps - typedef CCommandBarCtrlImpl< T, TBase, TWinTraits > _baseClass; - BEGIN_MSG_MAP(CMDICommandBarCtrlImpl) - MESSAGE_HANDLER(WM_CREATE, OnCreate) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) -#ifndef _WTL_NO_AUTO_THEME - MESSAGE_HANDLER(_GetThemeChangedMsg(), OnThemeChanged) -#endif // !_WTL_NO_AUTO_THEME - MESSAGE_HANDLER(WM_SIZE, OnSize) - MESSAGE_HANDLER(WM_NCCALCSIZE, OnNcCalcSize) - MESSAGE_HANDLER(WM_NCPAINT, OnNcPaint) - MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest) - MESSAGE_HANDLER(WM_NCLBUTTONDOWN, OnNcLButtonDown) - MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) - MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) - MESSAGE_HANDLER(WM_NCLBUTTONDBLCLK, OnNcLButtonDblClk) - MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged) - CHAIN_MSG_MAP(_baseClass) - ALT_MSG_MAP(1) // Parent window messages - MESSAGE_HANDLER(WM_ACTIVATE, OnParentActivate) - CHAIN_MSG_MAP_ALT(_baseClass, 1) - ALT_MSG_MAP(2) // MDI client window messages - MESSAGE_HANDLER(WM_MDISETMENU, OnMDISetMenu) - // no chaining needed since this was moved from the base class here - ALT_MSG_MAP(3) // Message hook messages - MESSAGE_RANGE_HANDLER(0, 0xFFFF, OnAllHookMessages) - CHAIN_MSG_MAP_ALT(_baseClass, 3) - END_MSG_MAP() - -// Additional MDI message handlers - LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - LRESULT lRet = _baseClass::OnCreate(uMsg, wParam, lParam, bHandled); - if(lRet == (LRESULT)-1) - return lRet; - -#ifndef _WTL_NO_AUTO_THEME - // this will fail if theming is not supported - m_hThemeDLL = ::LoadLibrary(_T("uxtheme.dll")); - if(m_hThemeDLL != NULL) - { - m_pfnDrawThemeBackground = (PFN_DrawThemeBackground)::GetProcAddress(m_hThemeDLL, "DrawThemeBackground"); - ATLASSERT(m_pfnDrawThemeBackground != NULL); - if(m_pfnDrawThemeBackground != NULL) - { - T* pT = static_cast(this); - pT->_OpenThemeData(); - } - else - { - ::FreeLibrary(m_hThemeDLL); - m_hThemeDLL = NULL; - } - m_pfnDrawThemeParentBackground = (PFN_DrawThemeParentBackground)::GetProcAddress(m_hThemeDLL, "DrawThemeParentBackground"); - ATLASSERT(m_pfnDrawThemeParentBackground != NULL); - } -#endif // !_WTL_NO_AUTO_THEME - - return lRet; - } - - LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - LRESULT lRet = _baseClass::OnDestroy(uMsg, wParam, lParam, bHandled); - -#ifndef _WTL_NO_AUTO_THEME - if(m_hThemeDLL != NULL) - { - T* pT = static_cast(this); - pT->_CloseThemeData(); - ::FreeLibrary(m_hThemeDLL); - m_hThemeDLL = NULL; - } -#endif // !_WTL_NO_AUTO_THEME - - return lRet; - } - -#ifndef _WTL_NO_AUTO_THEME - LRESULT OnThemeChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - if(m_hThemeDLL != NULL) - { - T* pT = static_cast(this); - pT->_CloseThemeData(); - pT->_OpenThemeData(); - } - return 0; - } -#endif // !_WTL_NO_AUTO_THEME - - LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); - T* pT = static_cast(this); - pT->_AdjustBtnSize(GET_Y_LPARAM(lParam)); - return lRet; - } - - LRESULT OnNcCalcSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); - - if(m_bChildMaximized && (BOOL)wParam) - { - LPNCCALCSIZE_PARAMS lpParams = (LPNCCALCSIZE_PARAMS)lParam; - if(m_bLayoutRTL) - { - lpParams->rgrc[0].left += m_cxRight; - lpParams->rgrc[0].right -= m_cxLeft; - } - else - { - lpParams->rgrc[0].left += m_cxLeft; - lpParams->rgrc[0].right -= m_cxRight; - } - } - - return lRet; - } - - LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); - - if(!m_bChildMaximized) - return lRet; - - ATLASSERT(m_hWndChildMaximized != NULL && m_hIconChildMaximized != NULL); - - // get DC and window rectangle - CWindowDC dc(m_hWnd); - RECT rect; - GetWindowRect(&rect); - int cxWidth = rect.right - rect.left; - int cyHeight = rect.bottom - rect.top; - - // paint left side nonclient background and draw icon - ::SetRect(&rect, 0, 0, m_cxLeft, cyHeight); -#ifndef _WTL_NO_AUTO_THEME - if(m_hTheme != NULL) - { - if(m_pfnDrawThemeParentBackground != NULL) - m_pfnDrawThemeParentBackground(m_hWnd, dc, &rect); - else - dc.FillRect(&rect, COLOR_WINDOW); - } - else -#endif // !_WTL_NO_AUTO_THEME - { - if((m_dwExtendedStyle & CBR_EX_TRANSPARENT) != 0) - dc.FillRect(&rect, COLOR_3DFACE); - else - dc.FillRect(&rect, COLOR_MENU); - } - - RECT rcIcon = { 0 }; - T* pT = static_cast(this); - pT->_CalcIconRect(cxWidth, cyHeight, rcIcon); - dc.DrawIconEx(rcIcon.left, rcIcon.top, m_hIconChildMaximized, m_cxIconWidth, m_cyIconHeight); - - // paint right side nonclient background - ::SetRect(&rect, cxWidth - m_cxRight, 0, cxWidth, cyHeight); -#ifndef _WTL_NO_AUTO_THEME - if(m_hTheme != NULL) - { - if(m_pfnDrawThemeParentBackground != NULL) - { - // this is to account for the left non-client area - POINT ptOrg = { 0, 0 }; - dc.GetViewportOrg(&ptOrg); - dc.SetViewportOrg(ptOrg.x + m_cxLeft, ptOrg.y); - ::OffsetRect(&rect, -m_cxLeft, 0); - - m_pfnDrawThemeParentBackground(m_hWnd, dc, &rect); - - // restore - dc.SetViewportOrg(ptOrg); - ::OffsetRect(&rect, m_cxLeft, 0); - } - else - { - dc.FillRect(&rect, COLOR_3DFACE); - } - } - else -#endif // !_WTL_NO_AUTO_THEME - { - if((m_dwExtendedStyle & CBR_EX_TRANSPARENT) != 0) - dc.FillRect(&rect, COLOR_3DFACE); - else - dc.FillRect(&rect, COLOR_MENU); - } - - // draw buttons - RECT arrRect[3] = { 0 }; - pT->_CalcBtnRects(cxWidth, cyHeight, arrRect); - pT->_DrawMDIButton(dc, arrRect, -1); // draw all buttons - - return lRet; - } - - LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); - if(m_bChildMaximized) - { - RECT rect = { 0 }; - GetWindowRect(&rect); - POINT pt = { GET_X_LPARAM(lParam) - rect.left, GET_Y_LPARAM(lParam) - rect.top }; - if(m_bLayoutRTL) - { - if((pt.x < m_cxRight) || (pt.x > ((rect.right - rect.left) - m_cxLeft))) - lRet = HTBORDER; - } - else - { - if((pt.x < m_cxLeft) || (pt.x > ((rect.right - rect.left) - m_cxRight))) - lRet = HTBORDER; - } - } - return lRet; - } - - LRESULT OnNcLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - if(!m_bChildMaximized) - { - bHandled = FALSE; - return 1; - } - - ATLASSERT(_DebugCheckChild()); - - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - RECT rect = { 0 }; - GetWindowRect(&rect); - pt.x -= rect.left; - pt.y -= rect.top; - - RECT rcIcon = { 0 }; - T* pT = static_cast(this); - pT->_CalcIconRect(rect.right - rect.left, rect.bottom - rect.top, rcIcon, m_bLayoutRTL); - RECT arrRect[3] = { 0 }; - pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect, m_bLayoutRTL); - - if(::PtInRect(&rcIcon, pt)) - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonDown: icon\n")); -#endif -#ifndef TPM_VERPOSANIMATION - const UINT TPM_VERPOSANIMATION = 0x1000L; // Menu animation flag -#endif - CMenuHandle menu = ::GetSystemMenu(m_hWndChildMaximized, FALSE); - UINT uRet = (UINT)menu.TrackPopupMenu(TPM_LEFTBUTTON | TPM_VERTICAL | TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | - (s_bW2K ? TPM_VERPOSANIMATION : 0), m_bLayoutRTL ? rect.right : rect.left, rect.bottom, m_hWndChildMaximized); - - // eat next message if click is on the same button - ::OffsetRect(&rcIcon, rect.left, rect.top); - MSG msg = { 0 }; - if(::PeekMessage(&msg, m_hWnd, WM_NCLBUTTONDOWN, WM_NCLBUTTONDOWN, PM_NOREMOVE) && ::PtInRect(&rcIcon, msg.pt)) - ::PeekMessage(&msg, m_hWnd, WM_NCLBUTTONDOWN, WM_NCLBUTTONDOWN, PM_REMOVE); - - if(uRet != 0) - ::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, uRet, 0L); - } - else if(::PtInRect(&arrRect[0], pt)) - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonDown: close button\n")); -#endif - m_nBtnWasPressed = m_nBtnPressed = 0; - } - else if(::PtInRect(&arrRect[1], pt)) - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonDown: restore button\n")); -#endif - m_nBtnWasPressed = m_nBtnPressed = 1; - } - else if(::PtInRect(&arrRect[2], pt)) - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonDown: minimize button\n")); -#endif - m_nBtnWasPressed = m_nBtnPressed = 2; - } - else - { - bHandled = FALSE; - } - - // draw the button state if it was pressed - if(m_nBtnPressed != -1) - { - SetCapture(); - CWindowDC dc(m_hWnd); - pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect); - pT->_DrawMDIButton(dc, arrRect, m_nBtnPressed); - } - - return 0; - } - - LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - if(!m_bChildMaximized || ::GetCapture() != m_hWnd || m_nBtnWasPressed == -1) - { - bHandled = FALSE; - return 1; - } - - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - ClientToScreen(&pt); - RECT rect = { 0 }; - GetWindowRect(&rect); - pt.x -= rect.left; - pt.y -= rect.top; - RECT arrRect[3] = { 0 }; - T* pT = static_cast(this); - pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect, m_bLayoutRTL); - int nOldBtnPressed = m_nBtnPressed; - m_nBtnPressed = ::PtInRect(&arrRect[m_nBtnWasPressed], pt) ? m_nBtnWasPressed : -1; - if(nOldBtnPressed != m_nBtnPressed) - { - CWindowDC dc(m_hWnd); - pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect); - pT->_DrawMDIButton(dc, arrRect, (m_nBtnPressed != -1) ? m_nBtnPressed : nOldBtnPressed); - } - - return 0; - } - - LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - if(!m_bChildMaximized || ::GetCapture() != m_hWnd || m_nBtnWasPressed == -1) - { - bHandled = FALSE; - return 1; - } - - ATLASSERT(_DebugCheckChild()); - - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - ClientToScreen(&pt); - RECT rect = { 0 }; - GetWindowRect(&rect); - pt.x -= rect.left; - pt.y -= rect.top; - - int nBtn = m_nBtnWasPressed; - ReleaseCapture(); - - RECT arrRect[3] = { 0 }; - T* pT = static_cast(this); - pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect, m_bLayoutRTL); - if(::PtInRect(&arrRect[nBtn], pt)) - { - switch(nBtn) - { - case 0: // close -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonUp: close button\n")); -#endif - ::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, SC_CLOSE, 0L); - break; - case 1: // restore -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonUp: restore button\n")); -#endif - ::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, SC_RESTORE, 0L); - break; - case 2: // minimize -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonUp: minimize button\n")); -#endif - ::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, SC_MINIMIZE, 0L); - break; - default: - break; - } - } - - return 0; - } - - LRESULT OnNcLButtonDblClk(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - if(!m_bChildMaximized || m_nBtnWasPressed != -1) - { - bHandled = FALSE; - return 1; - } - - ATLASSERT(_DebugCheckChild()); - - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - RECT rect = { 0 }; - GetWindowRect(&rect); - pt.x -= rect.left; - pt.y -= rect.top; - - RECT rcIcon = { 0 }; - T* pT = static_cast(this); - pT->_CalcIconRect(rect.right - rect.left, rect.bottom - rect.top, rcIcon, m_bLayoutRTL); - RECT arrRect[3] = { 0 }; - pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect, m_bLayoutRTL); - - if(::PtInRect(&rcIcon, pt)) - { - CMenuHandle menu = ::GetSystemMenu(m_hWndChildMaximized, FALSE); - UINT uDefID = menu.GetMenuDefaultItem(); - if(uDefID == (UINT)-1) - uDefID = SC_CLOSE; - ::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, uDefID, 0L); - } - - return 0; - } - - LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - if(m_bChildMaximized) - { - if(m_nBtnPressed != -1) - { - ATLASSERT(m_nBtnPressed == m_nBtnWasPressed); // must be - m_nBtnPressed = -1; - RECT rect = { 0 }; - GetWindowRect(&rect); - RECT arrRect[3] = { 0 }; - T* pT = static_cast(this); - pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect); - CWindowDC dc(m_hWnd); - pT->_DrawMDIButton(dc, arrRect, m_nBtnWasPressed); - } - m_nBtnWasPressed = -1; - } - else - { - bHandled = FALSE; - } - return 0; - } - -// Parent window message handlers - LRESULT OnParentActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - m_bParentActive = (LOWORD(wParam) != WA_INACTIVE); - RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW); - bHandled = FALSE; - return 1; - } - -// MDI client window message handlers - LRESULT OnMDISetMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - m_wndMDIClient.DefWindowProc(uMsg, NULL, lParam); - HMENU hOldMenu = GetMenu(); - BOOL bRet = AttachMenu((HMENU)wParam); - bRet; // avoid level 4 warning - ATLASSERT(bRet); - -#if (_WIN32_IE >= 0x0400) - T* pT = static_cast(this); - pT->UpdateRebarBandIdealSize(); -#endif // (_WIN32_IE >= 0x0400) - - return (LRESULT)hOldMenu; - } - -// All messages from the message hook - LRESULT OnAllHookMessages(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - T* pT = static_cast(this); - pT->_ProcessAllHookMessages(uMsg, wParam, lParam); - - bHandled = FALSE; - return 1; - } - -// Overrideables - // override this to provide different ideal size - void UpdateRebarBandIdealSize() - { - // assuming we are in a rebar, change ideal size to our size - // we hope that if we are not in a rebar, nCount will be 0 - int nCount = (int)::SendMessage(GetParent(), RB_GETBANDCOUNT, 0, 0L); - for(int i = 0; i < nCount; i++) - { - REBARBANDINFO rbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE }; - ::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi); - if(rbi.hwndChild == m_hWnd) - { - rbi.fMask = RBBIM_IDEALSIZE; - rbi.cxIdeal = m_bChildMaximized ? m_cxLeft + m_cxRight : 0; - int nBtnCount = GetButtonCount(); - if(nBtnCount > 0) - { - RECT rect = { 0 }; - GetItemRect(nBtnCount - 1, &rect); - rbi.cxIdeal += rect.right; - } - ::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi); - break; - } - } - } - - // all hook messages - check for the maximized MDI child window change - void _ProcessAllHookMessages(UINT uMsg, WPARAM /*wParam*/, LPARAM /*lParam*/) - { - if(uMsg == WM_MDIGETACTIVE || uMsg == WM_MDISETMENU) - return; - - BOOL bMaximized = FALSE; - HWND hWndChild = (HWND)::SendMessage(m_wndMDIClient, WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized); - bool bMaxOld = m_bChildMaximized; - m_bChildMaximized = (hWndChild != NULL && bMaximized); - HICON hIconOld = m_hIconChildMaximized; - - if(m_bChildMaximized) - { - if(m_hWndChildMaximized != hWndChild) - { - ATL::CWindow wnd = m_hWndChildMaximized = hWndChild; - m_hIconChildMaximized = wnd.GetIcon(FALSE); - if(m_hIconChildMaximized == NULL) - { - m_hIconChildMaximized = wnd.GetIcon(TRUE); - if(m_hIconChildMaximized == NULL) - { - // no icon set with WM_SETICON, get the class one -// need conditional code because types don't match in winuser.h -#ifdef _WIN64 - m_hIconChildMaximized = (HICON)::GetClassLongPtr(wnd, GCLP_HICONSM); -#else - m_hIconChildMaximized = (HICON)LongToHandle(::GetClassLongPtr(wnd, GCLP_HICONSM)); -#endif - } - } - } - } - else - { - m_hWndChildMaximized = NULL; - m_hIconChildMaximized = NULL; - } - - if(bMaxOld != m_bChildMaximized) - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - All messages hook change: m_bChildMaximized = %s\n"), m_bChildMaximized ? "true" : "false"); -#endif - // assuming we are in a rebar, change our size to accomodate new state - // we hope that if we are not in a rebar, nCount will be 0 - int nCount = (int)::SendMessage(GetParent(), RB_GETBANDCOUNT, 0, 0L); - int cxDiff = (m_bChildMaximized ? 1 : -1) * (m_cxLeft + m_cxRight); - for(int i = 0; i < nCount; i++) - { -#if (_WIN32_IE >= 0x0500) - REBARBANDINFO rbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_STYLE }; - ::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi); - if(rbi.hwndChild == m_hWnd) - { - if((rbi.fStyle & RBBS_USECHEVRON) != 0) - { - rbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE; - rbi.cxMinChild += cxDiff; - rbi.cxIdeal += cxDiff; - ::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi); - } - break; - } -#elif (_WIN32_IE >= 0x0400) - REBARBANDINFO rbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE }; - ::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi); - if(rbi.hwndChild == m_hWnd) - { - rbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE; - rbi.cxMinChild += cxDiff; - rbi.cxIdeal += cxDiff; - ::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi); - break; - } -#else // (_WIN32_IE < 0x0400) - REBARBANDINFO rbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_CHILDSIZE }; - ::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi); - if(rbi.hwndChild == m_hWnd) - { - rbi.fMask = RBBIM_CHILDSIZE; - rbi.cxMinChild += cxDiff; - ::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi); - break; - } -#endif // (_WIN32_IE < 0x0400) - } - } - - if(bMaxOld != m_bChildMaximized || hIconOld != m_hIconChildMaximized) - { - // force size change and redraw everything - RECT rect = { 0 }; - GetWindowRect(&rect); - ::MapWindowPoints(NULL, GetParent(), (LPPOINT)&rect, 2); - SetRedraw(FALSE); - SetWindowPos(NULL, 0, 0, 1, 1, SWP_NOZORDER | SWP_NOMOVE); - SetWindowPos(NULL, &rect, SWP_NOZORDER | SWP_NOMOVE); - SetRedraw(TRUE); - RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW); - } - } - -// Implementation - void GetSystemSettings() - { -#ifdef _CMDBAR_EXTRA_TRACE - ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - GetSystemSettings\n")); -#endif - _baseClass::GetSystemSettings(); - - NONCLIENTMETRICS info = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() }; - BOOL bRet = ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0); - ATLASSERT(bRet); - if(bRet) - { - m_cxIconWidth = ::GetSystemMetrics(SM_CXSMICON); - m_cyIconHeight = ::GetSystemMetrics(SM_CYSMICON); - m_cxLeft = m_cxIconWidth; - -#ifndef _WTL_NO_AUTO_THEME - if(m_hTheme != NULL) - { - m_cxBtnWidth = info.iCaptionWidth - 2 * m_cxyOffset; - m_cyBtnHeight = info.iCaptionHeight - 2 * m_cxyOffset; - m_cxRight = 3 * m_cxBtnWidth; - } - else -#endif // !_WTL_NO_AUTO_THEME - { - m_cxBtnWidth = info.iCaptionWidth - m_cxyOffset; - m_cyBtnHeight = info.iCaptionHeight - 2 * m_cxyOffset; - m_cxRight = 3 * m_cxBtnWidth + m_cxyOffset; - } - } - - RECT rect = { 0 }; - GetClientRect(&rect); - T* pT = static_cast(this); - pT->_AdjustBtnSize(rect.bottom); - } - - void _AdjustBtnSize(int cyHeight) - { - if(cyHeight > 1 && m_cyBtnHeight > cyHeight) - { -#ifndef _WTL_NO_AUTO_THEME - if(m_hTheme != NULL) - { - m_cyBtnHeight = cyHeight; - m_cxBtnWidth = cyHeight; - m_cxRight = 3 * m_cxBtnWidth; - } - else -#endif // !_WTL_NO_AUTO_THEME - { - m_cyBtnHeight = cyHeight; - m_cxBtnWidth = cyHeight + m_cxyOffset; - m_cxRight = 3 * m_cxBtnWidth + m_cxyOffset; - } - } - } - - void _CalcIconRect(int cxWidth, int cyHeight, RECT& rect, bool bInvertX = false) const - { - int xStart = (m_cxLeft - m_cxIconWidth) / 2; - if(xStart < 0) - xStart = 0; - int yStart = (cyHeight - m_cyIconHeight) / 2; - if(yStart < 0) - yStart = 0; - - if(bInvertX) - ::SetRect(&rect, cxWidth - (xStart + m_cxBtnWidth), yStart, cxWidth - xStart, yStart + m_cyBtnHeight); - else - ::SetRect(&rect, xStart, yStart, xStart + m_cxBtnWidth, yStart + m_cyBtnHeight); - } - - void _CalcBtnRects(int cxWidth, int cyHeight, RECT arrRect[3], bool bInvertX = false) const - { - int yStart = (cyHeight - m_cyBtnHeight) / 2; - if(yStart < 0) - yStart = 0; - - RECT rcBtn = { cxWidth - m_cxBtnWidth, yStart, cxWidth, yStart + m_cyBtnHeight }; - int nDirection = -1; - if(bInvertX) - { - ::SetRect(&rcBtn, 0, yStart, m_cxBtnWidth, yStart + m_cyBtnHeight); - nDirection = 1; - } - - arrRect[0] = rcBtn; -#ifndef _WTL_NO_AUTO_THEME - if(m_hTheme != NULL) - ::OffsetRect(&rcBtn, nDirection * m_cxBtnWidth, 0); - else -#endif // !_WTL_NO_AUTO_THEME - ::OffsetRect(&rcBtn, nDirection * (m_cxBtnWidth + m_cxyOffset), 0); - arrRect[1] = rcBtn; - ::OffsetRect(&rcBtn, nDirection * m_cxBtnWidth, 0); - arrRect[2] = rcBtn; - } - - void _DrawMDIButton(CWindowDC& dc, LPRECT pRects, int nBtn) - { -#ifndef _WTL_NO_AUTO_THEME - if(m_hTheme != NULL) - { -#ifndef TMSCHEMA_H - const int WP_MDICLOSEBUTTON = 20; - const int CBS_NORMAL = 1; - const int CBS_PUSHED = 3; - const int CBS_DISABLED = 4; - const int WP_MDIRESTOREBUTTON = 22; - const int RBS_NORMAL = 1; - const int RBS_PUSHED = 3; - const int RBS_DISABLED = 4; - const int WP_MDIMINBUTTON = 16; - const int MINBS_NORMAL = 1; - const int MINBS_PUSHED = 3; - const int MINBS_DISABLED = 4; -#endif // TMSCHEMA_H - if(nBtn == -1 || nBtn == 0) - m_pfnDrawThemeBackground(m_hTheme, dc, WP_MDICLOSEBUTTON, m_bParentActive ? ((m_nBtnPressed == 0) ? CBS_PUSHED : CBS_NORMAL) : CBS_DISABLED, &pRects[0], NULL); - if(nBtn == -1 || nBtn == 1) - m_pfnDrawThemeBackground(m_hTheme, dc, WP_MDIRESTOREBUTTON, m_bParentActive ? ((m_nBtnPressed == 1) ? RBS_PUSHED : RBS_NORMAL) : RBS_DISABLED, &pRects[1], NULL); - if(nBtn == -1 || nBtn == 2) - m_pfnDrawThemeBackground(m_hTheme, dc, WP_MDIMINBUTTON, m_bParentActive ? ((m_nBtnPressed == 2) ? MINBS_PUSHED : MINBS_NORMAL) : MINBS_DISABLED, &pRects[2], NULL); - } - else -#endif // !_WTL_NO_AUTO_THEME - { - if(nBtn == -1 || nBtn == 0) - dc.DrawFrameControl(&pRects[0], DFC_CAPTION, DFCS_CAPTIONCLOSE | ((m_nBtnPressed == 0) ? DFCS_PUSHED : 0)); - if(nBtn == -1 || nBtn == 1) - dc.DrawFrameControl(&pRects[1], DFC_CAPTION, DFCS_CAPTIONRESTORE | ((m_nBtnPressed == 1) ? DFCS_PUSHED : 0)); - if(nBtn == -1 || nBtn == 2) - dc.DrawFrameControl(&pRects[2], DFC_CAPTION, DFCS_CAPTIONMIN | ((m_nBtnPressed == 2) ? DFCS_PUSHED : 0)); - } - } - -#ifndef _WTL_NO_AUTO_THEME - static UINT _GetThemeChangedMsg() - { -#ifndef WM_THEMECHANGED - static const UINT WM_THEMECHANGED = 0x031A; -#endif // !WM_THEMECHANGED - return WM_THEMECHANGED; - } - - void _OpenThemeData() - { - ATLASSERT(m_hThemeDLL != NULL); - - PFN_OpenThemeData pfnOpenThemeData = (PFN_OpenThemeData)::GetProcAddress(m_hThemeDLL, "OpenThemeData"); - ATLASSERT(pfnOpenThemeData != NULL); - if(pfnOpenThemeData != NULL) - m_hTheme = pfnOpenThemeData(m_hWnd, L"Window"); - } - - void _CloseThemeData() - { - ATLASSERT(m_hThemeDLL != NULL); - - if(m_hTheme == NULL) - return; // nothing to do - - PFN_CloseThemeData pfnCloseThemeData = (PFN_CloseThemeData)::GetProcAddress(m_hThemeDLL, "CloseThemeData"); - ATLASSERT(pfnCloseThemeData != NULL); - if(pfnCloseThemeData != NULL) - { - pfnCloseThemeData(m_hTheme); - m_hTheme = NULL; - } - } -#endif // !_WTL_NO_AUTO_THEME - - bool _DebugCheckChild() - { -#ifdef _DEBUG - BOOL bMaximized = FALSE; - HWND hWndChild = (HWND)::SendMessage(m_wndMDIClient, WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized); - return (bMaximized && hWndChild == m_hWndChildMaximized); -#else // !_DEBUG - return true; -#endif // !_DEBUG - } -}; - -class CMDICommandBarCtrl : public CMDICommandBarCtrlImpl -{ -public: - DECLARE_WND_SUPERCLASS(_T("WTL_MDICommandBar"), GetWndClassName()) -}; - -}; // namespace WTL - -#endif // __ATLCTRLW_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlctrlx.h b/!NotAdopted/SmartAutoReplier/wtl/atlctrlx.h deleted file mode 100644 index 65d8f934a5..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlctrlx.h +++ /dev/null @@ -1,5004 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLCTRLX_H__ -#define __ATLCTRLX_H__ - -#pragma once - -#ifndef __ATLAPP_H__ - #error atlctrlx.h requires atlapp.h to be included first -#endif - -#ifndef __ATLCTRLS_H__ - #error atlctrlx.h requires atlctrls.h to be included first -#endif - -#ifndef WM_UPDATEUISTATE - #define WM_UPDATEUISTATE 0x0128 -#endif // !WM_UPDATEUISTATE - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CBitmapButtonImpl -// CBitmapButton -// CCheckListViewCtrlImpl -// CCheckListViewCtrl -// CHyperLinkImpl -// CHyperLink -// CWaitCursor -// CCustomWaitCursor -// CMultiPaneStatusBarCtrlImpl -// CMultiPaneStatusBarCtrl -// CPaneContainerImpl -// CPaneContainer -// CSortListViewImpl -// CSortListViewCtrlImpl -// CSortListViewCtrl -// CTabViewImpl -// CTabView - -namespace WTL -{ - -/////////////////////////////////////////////////////////////////////////////// -// CBitmapButton - bitmap button implementation - -#ifndef _WIN32_WCE - -// bitmap button extended styles -#define BMPBTN_HOVER 0x00000001 -#define BMPBTN_AUTO3D_SINGLE 0x00000002 -#define BMPBTN_AUTO3D_DOUBLE 0x00000004 -#define BMPBTN_AUTOSIZE 0x00000008 -#define BMPBTN_SHAREIMAGELISTS 0x00000010 -#define BMPBTN_AUTOFIRE 0x00000020 - -template -class ATL_NO_VTABLE CBitmapButtonImpl : public ATL::CWindowImpl< T, TBase, TWinTraits> -{ -public: - DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName()) - - enum - { - _nImageNormal = 0, - _nImagePushed, - _nImageFocusOrHover, - _nImageDisabled, - - _nImageCount = 4, - }; - - enum - { - ID_TIMER_FIRST = 1000, - ID_TIMER_REPEAT = 1001 - }; - - // Bitmap button specific extended styles - DWORD m_dwExtendedStyle; - - CImageList m_ImageList; - int m_nImage[_nImageCount]; - - CToolTipCtrl m_tip; - LPTSTR m_lpstrToolTipText; - - // Internal states - unsigned m_fMouseOver:1; - unsigned m_fFocus:1; - unsigned m_fPressed:1; - - -// Constructor/Destructor - CBitmapButtonImpl(DWORD dwExtendedStyle = BMPBTN_AUTOSIZE, HIMAGELIST hImageList = NULL) : - m_ImageList(hImageList), m_dwExtendedStyle(dwExtendedStyle), - m_lpstrToolTipText(NULL), - m_fMouseOver(0), m_fFocus(0), m_fPressed(0) - { - m_nImage[_nImageNormal] = -1; - m_nImage[_nImagePushed] = -1; - m_nImage[_nImageFocusOrHover] = -1; - m_nImage[_nImageDisabled] = -1; - } - - ~CBitmapButtonImpl() - { - if((m_dwExtendedStyle & BMPBTN_SHAREIMAGELISTS) == 0) - m_ImageList.Destroy(); - delete [] m_lpstrToolTipText; - } - - // overridden to provide proper initialization - BOOL SubclassWindow(HWND hWnd) - { -#if (_MSC_VER >= 1300) - BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits>::SubclassWindow(hWnd); -#else // !(_MSC_VER >= 1300) - typedef ATL::CWindowImpl< T, TBase, TWinTraits> _baseClass; - BOOL bRet = _baseClass::SubclassWindow(hWnd); -#endif // !(_MSC_VER >= 1300) - if(bRet) - Init(); - return bRet; - } - -// Attributes - DWORD GetBitmapButtonExtendedStyle() const - { - return m_dwExtendedStyle; - } - - DWORD SetBitmapButtonExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) - { - DWORD dwPrevStyle = m_dwExtendedStyle; - if(dwMask == 0) - m_dwExtendedStyle = dwExtendedStyle; - else - m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); - return dwPrevStyle; - } - - HIMAGELIST GetImageList() const - { - return m_ImageList; - } - - HIMAGELIST SetImageList(HIMAGELIST hImageList) - { - HIMAGELIST hImageListPrev = m_ImageList; - m_ImageList = hImageList; - if((m_dwExtendedStyle & BMPBTN_AUTOSIZE) != 0 && ::IsWindow(m_hWnd)) - SizeToImage(); - return hImageListPrev; - } - - int GetToolTipTextLength() const - { - return (m_lpstrToolTipText == NULL) ? -1 : lstrlen(m_lpstrToolTipText); - } - - bool GetToolTipText(LPTSTR lpstrText, int nLength) const - { - ATLASSERT(lpstrText != NULL); - if(m_lpstrToolTipText == NULL) - return false; - - errno_t nRet = SecureHelper::strncpy_x(lpstrText, nLength, m_lpstrToolTipText, _TRUNCATE); - - return (nRet == 0 || nRet == STRUNCATE); - } - - bool SetToolTipText(LPCTSTR lpstrText) - { - if(m_lpstrToolTipText != NULL) - { - delete [] m_lpstrToolTipText; - m_lpstrToolTipText = NULL; - } - - if(lpstrText == NULL) - { - if(m_tip.IsWindow()) - m_tip.Activate(FALSE); - return true; - } - - int cchLen = lstrlen(lpstrText) + 1; - ATLTRY(m_lpstrToolTipText = new TCHAR[cchLen]); - if(m_lpstrToolTipText == NULL) - return false; - - SecureHelper::strcpy_x(m_lpstrToolTipText, cchLen, lpstrText); - if(m_tip.IsWindow()) - { - m_tip.Activate(TRUE); - m_tip.AddTool(m_hWnd, m_lpstrToolTipText); - } - - return true; - } - -// Operations - void SetImages(int nNormal, int nPushed = -1, int nFocusOrHover = -1, int nDisabled = -1) - { - if(nNormal != -1) - m_nImage[_nImageNormal] = nNormal; - if(nPushed != -1) - m_nImage[_nImagePushed] = nPushed; - if(nFocusOrHover != -1) - m_nImage[_nImageFocusOrHover] = nFocusOrHover; - if(nDisabled != -1) - m_nImage[_nImageDisabled] = nDisabled; - } - - BOOL SizeToImage() - { - ATLASSERT(::IsWindow(m_hWnd) && m_ImageList.m_hImageList != NULL); - int cx = 0; - int cy = 0; - if(!m_ImageList.GetIconSize(cx, cy)) - return FALSE; - return ResizeClient(cx, cy); - } - -// Overrideables - void DoPaint(CDCHandle dc) - { - ATLASSERT(m_ImageList.m_hImageList != NULL); // image list must be set - ATLASSERT(m_nImage[0] != -1); // main bitmap must be set - - // set bitmap according to the current button state - int nImage = -1; - bool bHover = IsHoverMode(); - if(!IsWindowEnabled()) - nImage = m_nImage[_nImageDisabled]; - else if(m_fPressed == 1) - nImage = m_nImage[_nImagePushed]; - else if((!bHover && m_fFocus == 1) || (bHover && m_fMouseOver == 1)) - nImage = m_nImage[_nImageFocusOrHover]; - if(nImage == -1) // not there, use default one - nImage = m_nImage[_nImageNormal]; - - // draw the button image - int xyPos = 0; - if((m_fPressed == 1) && ((m_dwExtendedStyle & (BMPBTN_AUTO3D_SINGLE | BMPBTN_AUTO3D_DOUBLE)) != 0) && (m_nImage[_nImagePushed] == -1)) - xyPos = 1; - m_ImageList.Draw(dc, nImage, xyPos, xyPos, ILD_NORMAL); - - // draw 3D border if required - if((m_dwExtendedStyle & (BMPBTN_AUTO3D_SINGLE | BMPBTN_AUTO3D_DOUBLE)) != 0) - { - RECT rect; - GetClientRect(&rect); - - if(m_fPressed == 1) - dc.DrawEdge(&rect, ((m_dwExtendedStyle & BMPBTN_AUTO3D_SINGLE) != 0) ? BDR_SUNKENOUTER : EDGE_SUNKEN, BF_RECT); - else if(!bHover || m_fMouseOver == 1) - dc.DrawEdge(&rect, ((m_dwExtendedStyle & BMPBTN_AUTO3D_SINGLE) != 0) ? BDR_RAISEDINNER : EDGE_RAISED, BF_RECT); - - if(!bHover && m_fFocus == 1) - { - ::InflateRect(&rect, -2 * ::GetSystemMetrics(SM_CXEDGE), -2 * ::GetSystemMetrics(SM_CYEDGE)); - dc.DrawFocusRect(&rect); - } - } - } - -// Message map and handlers - BEGIN_MSG_MAP(CBitmapButtonImpl) - MESSAGE_HANDLER(WM_CREATE, OnCreate) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) - MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) - MESSAGE_HANDLER(WM_PAINT, OnPaint) - MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) - MESSAGE_HANDLER(WM_SETFOCUS, OnFocus) - MESSAGE_HANDLER(WM_KILLFOCUS, OnFocus) - MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) - MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDblClk) - MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) - MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged) - MESSAGE_HANDLER(WM_ENABLE, OnEnable) - MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) - MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave) - MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown) - MESSAGE_HANDLER(WM_KEYUP, OnKeyUp) - MESSAGE_HANDLER(WM_TIMER, OnTimer) - MESSAGE_HANDLER(WM_UPDATEUISTATE, OnUpdateUiState) - END_MSG_MAP() - - LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - Init(); - bHandled = FALSE; - return 1; - } - - LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - if(m_tip.IsWindow()) - { - m_tip.DestroyWindow(); - m_tip.m_hWnd = NULL; - } - bHandled = FALSE; - return 1; - } - - LRESULT OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - MSG msg = { m_hWnd, uMsg, wParam, lParam }; - if(m_tip.IsWindow()) - m_tip.RelayEvent(&msg); - bHandled = FALSE; - return 1; - } - - LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - return 1; // no background needed - } - - LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - if(wParam != NULL) - { - pT->DoPaint((HDC)wParam); - } - else - { - CPaintDC dc(m_hWnd); - pT->DoPaint(dc.m_hDC); - } - return 0; - } - - LRESULT OnFocus(UINT uMsg, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - m_fFocus = (uMsg == WM_SETFOCUS) ? 1 : 0; - Invalidate(); - UpdateWindow(); - bHandled = FALSE; - return 1; - } - - LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - LRESULT lRet = 0; - if(IsHoverMode()) - SetCapture(); - else - lRet = DefWindowProc(uMsg, wParam, lParam); - if(::GetCapture() == m_hWnd) - { - m_fPressed = 1; - Invalidate(); - UpdateWindow(); - } - if((m_dwExtendedStyle & BMPBTN_AUTOFIRE) != 0) - { - int nElapse = 250; - int nDelay = 0; - if(::SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &nDelay, 0)) - nElapse += nDelay * 250; // all milli-seconds - SetTimer(ID_TIMER_FIRST, nElapse); - } - return lRet; - } - - LRESULT OnLButtonDblClk(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - LRESULT lRet = 0; - if(!IsHoverMode()) - lRet = DefWindowProc(uMsg, wParam, lParam); - if(::GetCapture() != m_hWnd) - SetCapture(); - if(m_fPressed == 0) - { - m_fPressed = 1; - Invalidate(); - UpdateWindow(); - } - return lRet; - } - - LRESULT OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - LRESULT lRet = 0; - bool bHover = IsHoverMode(); - if(!bHover) - lRet = DefWindowProc(uMsg, wParam, lParam); - if(::GetCapture() == m_hWnd) - { - if(bHover && m_fPressed == 1) - ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd); - ::ReleaseCapture(); - } - return lRet; - } - - LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - if(m_fPressed == 1) - { - m_fPressed = 0; - Invalidate(); - UpdateWindow(); - } - bHandled = FALSE; - return 1; - } - - LRESULT OnEnable(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - Invalidate(); - UpdateWindow(); - bHandled = FALSE; - return 1; - } - - LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - if(::GetCapture() == m_hWnd) - { - POINT ptCursor = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - ClientToScreen(&ptCursor); - RECT rect = { 0 }; - GetWindowRect(&rect); - unsigned int uPressed = ::PtInRect(&rect, ptCursor) ? 1 : 0; - if(m_fPressed != uPressed) - { - m_fPressed = uPressed; - Invalidate(); - UpdateWindow(); - } - } - else if(IsHoverMode() && m_fMouseOver == 0) - { - m_fMouseOver = 1; - Invalidate(); - UpdateWindow(); - StartTrackMouseLeave(); - } - bHandled = FALSE; - return 1; - } - - LRESULT OnMouseLeave(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - if(m_fMouseOver == 1) - { - m_fMouseOver = 0; - Invalidate(); - UpdateWindow(); - } - return 0; - } - - LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - if(wParam == VK_SPACE && IsHoverMode()) - return 0; // ignore if in hover mode - if(wParam == VK_SPACE && m_fPressed == 0) - { - m_fPressed = 1; - Invalidate(); - UpdateWindow(); - } - bHandled = FALSE; - return 1; - } - - LRESULT OnKeyUp(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - if(wParam == VK_SPACE && IsHoverMode()) - return 0; // ignore if in hover mode - if(wParam == VK_SPACE && m_fPressed == 1) - { - m_fPressed = 0; - Invalidate(); - UpdateWindow(); - } - bHandled = FALSE; - return 1; - } - - LRESULT OnTimer(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - ATLASSERT((m_dwExtendedStyle & BMPBTN_AUTOFIRE) != 0); - switch(wParam) // timer ID - { - case ID_TIMER_FIRST: - KillTimer(ID_TIMER_FIRST); - if(m_fPressed == 1) - { - ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd); - int nElapse = 250; - int nRepeat = 40; - if(::SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &nRepeat, 0)) - nElapse = 10000 / (10 * nRepeat + 25); // milli-seconds, approximated - SetTimer(ID_TIMER_REPEAT, nElapse); - } - break; - case ID_TIMER_REPEAT: - if(m_fPressed == 1) - ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd); - else if(::GetCapture() != m_hWnd) - KillTimer(ID_TIMER_REPEAT); - break; - default: // not our timer - break; - } - return 0; - } - - LRESULT OnUpdateUiState(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - // If the control is subclassed or superclassed, this message can cause - // repainting without WM_PAINT. We don't use this state, so just do nothing. - return 0; - } - -// Implementation - void Init() - { - // We need this style to prevent Windows from painting the button - ModifyStyle(0, BS_OWNERDRAW); - - // create a tool tip - m_tip.Create(m_hWnd); - ATLASSERT(m_tip.IsWindow()); - if(m_tip.IsWindow() && m_lpstrToolTipText != NULL) - { - m_tip.Activate(TRUE); - m_tip.AddTool(m_hWnd, m_lpstrToolTipText); - } - - if(m_ImageList.m_hImageList != NULL && (m_dwExtendedStyle & BMPBTN_AUTOSIZE) != 0) - SizeToImage(); - } - - BOOL StartTrackMouseLeave() - { - TRACKMOUSEEVENT tme = { 0 }; - tme.cbSize = sizeof(tme); - tme.dwFlags = TME_LEAVE; - tme.hwndTrack = m_hWnd; - return _TrackMouseEvent(&tme); - } - - bool IsHoverMode() const - { - return ((m_dwExtendedStyle & BMPBTN_HOVER) != 0); - } -}; - -class CBitmapButton : public CBitmapButtonImpl -{ -public: - DECLARE_WND_SUPERCLASS(_T("WTL_BitmapButton"), GetWndClassName()) - - CBitmapButton(DWORD dwExtendedStyle = BMPBTN_AUTOSIZE, HIMAGELIST hImageList = NULL) : - CBitmapButtonImpl(dwExtendedStyle, hImageList) - { } -}; - -#endif // !_WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CCheckListCtrlView - list view control with check boxes - -template -class CCheckListViewCtrlImplTraits -{ -public: - static DWORD GetWndStyle(DWORD dwStyle) - { - return (dwStyle == 0) ? t_dwStyle : dwStyle; - } - - static DWORD GetWndExStyle(DWORD dwExStyle) - { - return (dwExStyle == 0) ? t_dwExStyle : dwExStyle; - } - - static DWORD GetExtendedLVStyle() - { - return t_dwExListViewStyle; - } -}; - -typedef CCheckListViewCtrlImplTraits CCheckListViewCtrlTraits; - -template -class ATL_NO_VTABLE CCheckListViewCtrlImpl : public ATL::CWindowImpl -{ -public: - DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName()) - -// Attributes - static DWORD GetExtendedLVStyle() - { - return TWinTraits::GetExtendedLVStyle(); - } - -// Operations - BOOL SubclassWindow(HWND hWnd) - { -#if (_MSC_VER >= 1300) - BOOL bRet = ATL::CWindowImplBaseT< TBase, TWinTraits>::SubclassWindow(hWnd); -#else // !(_MSC_VER >= 1300) - typedef ATL::CWindowImplBaseT< TBase, TWinTraits> _baseClass; - BOOL bRet = _baseClass::SubclassWindow(hWnd); -#endif // !(_MSC_VER >= 1300) - if(bRet) - { - T* pT = static_cast(this); - pT; - ATLASSERT((pT->GetExtendedLVStyle() & LVS_EX_CHECKBOXES) != 0); - SetExtendedListViewStyle(pT->GetExtendedLVStyle()); - } - return bRet; - } - - void CheckSelectedItems(int nCurrItem) - { - // first check if this item is selected - LVITEM lvi = { 0 }; - lvi.iItem = nCurrItem; - lvi.iSubItem = 0; - lvi.mask = LVIF_STATE; - lvi.stateMask = LVIS_SELECTED; - GetItem(&lvi); - // if item is not selected, don't do anything - if(!(lvi.state & LVIS_SELECTED)) - return; - // new check state will be reverse of the current state, - BOOL bCheck = !GetCheckState(nCurrItem); - int nItem = -1; - int nOldItem = -1; - while((nItem = GetNextItem(nOldItem, LVNI_SELECTED)) != -1) - { - if(nItem != nCurrItem) - SetCheckState(nItem, bCheck); - nOldItem = nItem; - } - } - -// Implementation - BEGIN_MSG_MAP(CCheckListViewCtrlImpl) - MESSAGE_HANDLER(WM_CREATE, OnCreate) - MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) - MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDown) - MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown) - END_MSG_MAP() - - LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - // first let list view control initialize everything - LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); - T* pT = static_cast(this); - pT; - ATLASSERT((pT->GetExtendedLVStyle() & LVS_EX_CHECKBOXES) != 0); - SetExtendedListViewStyle(pT->GetExtendedLVStyle()); - return lRet; - } - - LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - POINT ptMsg = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - LVHITTESTINFO lvh = { 0 }; - lvh.pt = ptMsg; - if(HitTest(&lvh) != -1 && lvh.flags == LVHT_ONITEMSTATEICON && ::GetKeyState(VK_CONTROL) >= 0) - { - T* pT = static_cast(this); - pT->CheckSelectedItems(lvh.iItem); - } - bHandled = FALSE; - return 1; - } - - LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - if(wParam == VK_SPACE) - { - int nCurrItem = GetNextItem(-1, LVNI_FOCUSED); - if(nCurrItem != -1 && ::GetKeyState(VK_CONTROL) >= 0) - { - T* pT = static_cast(this); - pT->CheckSelectedItems(nCurrItem); - } - } - bHandled = FALSE; - return 1; - } -}; - -class CCheckListViewCtrl : public CCheckListViewCtrlImpl -{ -public: - DECLARE_WND_SUPERCLASS(_T("WTL_CheckListView"), GetWndClassName()) -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CHyperLink - hyper link control implementation - -#if (WINVER < 0x0500) && !defined(_WIN32_WCE) -__declspec(selectany) struct -{ - enum { cxWidth = 32, cyHeight = 32 }; - int xHotSpot; - int yHotSpot; - unsigned char arrANDPlane[cxWidth * cyHeight / 8]; - unsigned char arrXORPlane[cxWidth * cyHeight / 8]; -} _AtlHyperLink_CursorData = -{ - 5, 0, - { - 0xF9, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, - 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0xF0, 0x01, 0xFF, 0xFF, - 0xF0, 0x00, 0xFF, 0xFF, 0x10, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, - 0x80, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, - 0xE0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, - 0xF8, 0x01, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF - }, - { - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0xC0, 0x00, 0x00, 0x06, 0xD8, 0x00, 0x00, - 0x06, 0xDA, 0x00, 0x00, 0x06, 0xDB, 0x00, 0x00, 0x67, 0xFB, 0x00, 0x00, 0x77, 0xFF, 0x00, 0x00, - 0x37, 0xFF, 0x00, 0x00, 0x17, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0x00, 0x00, - 0x0F, 0xFE, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, - 0x03, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - } -}; -#endif // (WINVER < 0x0500) && !defined(_WIN32_WCE) - -#define HLINK_UNDERLINED 0x00000000 -#define HLINK_NOTUNDERLINED 0x00000001 -#define HLINK_UNDERLINEHOVER 0x00000002 -#define HLINK_COMMANDBUTTON 0x00000004 -#define HLINK_NOTIFYBUTTON 0x0000000C -#define HLINK_USETAGS 0x00000010 -#define HLINK_USETAGSBOLD 0x00000030 -#define HLINK_NOTOOLTIP 0x00000040 -#define HLINK_AUTOCREATELINKFONT 0x00000080 -#define HLINK_SINGLELINE 0x00000100 - -// Notes: -// - HLINK_USETAGS and HLINK_USETAGSBOLD are always left-aligned -// - When HLINK_USETAGSBOLD is used, the underlined styles will be ignored - -template -class ATL_NO_VTABLE CHyperLinkImpl : public ATL::CWindowImpl< T, TBase, TWinTraits > -{ -public: - LPTSTR m_lpstrLabel; - LPTSTR m_lpstrHyperLink; - - HCURSOR m_hCursor; - HFONT m_hFontLink; - HFONT m_hFontNormal; - - RECT m_rcLink; -#ifndef _WIN32_WCE - CToolTipCtrl m_tip; -#endif // !_WIN32_WCE - - COLORREF m_clrLink; - COLORREF m_clrVisited; - - DWORD m_dwExtendedStyle; // Hyper Link specific extended styles - - bool m_bPaintLabel:1; - bool m_bVisited:1; - bool m_bHover:1; - bool m_bInternalLinkFont:1; - bool m_bInternalNormalFont:1; - - -// Constructor/Destructor - CHyperLinkImpl(DWORD dwExtendedStyle = HLINK_UNDERLINED) : - m_lpstrLabel(NULL), m_lpstrHyperLink(NULL), - m_hCursor(NULL), m_hFontLink(NULL), m_hFontNormal(NULL), - m_clrLink(RGB(0, 0, 255)), m_clrVisited(RGB(128, 0, 128)), - m_dwExtendedStyle(dwExtendedStyle), - m_bPaintLabel(true), m_bVisited(false), - m_bHover(false), m_bInternalLinkFont(false), m_bInternalNormalFont(false) - { - ::SetRectEmpty(&m_rcLink); - } - - ~CHyperLinkImpl() - { - delete [] m_lpstrLabel; - delete [] m_lpstrHyperLink; -#if (WINVER < 0x0500) && !defined(_WIN32_WCE) - // It was created, not loaded, so we have to destroy it - if(m_hCursor != NULL) - ::DestroyCursor(m_hCursor); -#endif // (WINVER < 0x0500) && !defined(_WIN32_WCE) - } - -// Attributes - DWORD GetHyperLinkExtendedStyle() const - { - return m_dwExtendedStyle; - } - - DWORD SetHyperLinkExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) - { - DWORD dwPrevStyle = m_dwExtendedStyle; - if(dwMask == 0) - m_dwExtendedStyle = dwExtendedStyle; - else - m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); - return dwPrevStyle; - } - - bool GetLabel(LPTSTR lpstrBuffer, int nLength) const - { - if(m_lpstrLabel == NULL) - return false; - ATLASSERT(lpstrBuffer != NULL); - if(nLength <= lstrlen(m_lpstrLabel)) - return false; - - SecureHelper::strcpy_x(lpstrBuffer, nLength, m_lpstrLabel); - - return true; - } - - bool SetLabel(LPCTSTR lpstrLabel) - { - delete [] m_lpstrLabel; - m_lpstrLabel = NULL; - int cchLen = lstrlen(lpstrLabel) + 1; - ATLTRY(m_lpstrLabel = new TCHAR[cchLen]); - if(m_lpstrLabel == NULL) - return false; - - SecureHelper::strcpy_x(m_lpstrLabel, cchLen, lpstrLabel); - T* pT = static_cast(this); - pT->CalcLabelRect(); - - if(m_hWnd != NULL) - SetWindowText(lpstrLabel); // Set this for accessibility - - return true; - } - - bool GetHyperLink(LPTSTR lpstrBuffer, int nLength) const - { - if(m_lpstrHyperLink == NULL) - return false; - ATLASSERT(lpstrBuffer != NULL); - if(nLength <= lstrlen(m_lpstrHyperLink)) - return false; - - SecureHelper::strcpy_x(lpstrBuffer, nLength, m_lpstrHyperLink); - - return true; - } - - bool SetHyperLink(LPCTSTR lpstrLink) - { - delete [] m_lpstrHyperLink; - m_lpstrHyperLink = NULL; - int cchLen = lstrlen(lpstrLink) + 1; - ATLTRY(m_lpstrHyperLink = new TCHAR[cchLen]); - if(m_lpstrHyperLink == NULL) - return false; - - SecureHelper::strcpy_x(m_lpstrHyperLink, cchLen, lpstrLink); - if(m_lpstrLabel == NULL) - { - T* pT = static_cast(this); - pT->CalcLabelRect(); - } -#ifndef _WIN32_WCE - if(m_tip.IsWindow()) - { - m_tip.Activate(TRUE); - m_tip.AddTool(m_hWnd, m_lpstrHyperLink, &m_rcLink, 1); - } -#endif // !_WIN32_WCE - return true; - } - - HFONT GetLinkFont() const - { - return m_hFontLink; - } - - void SetLinkFont(HFONT hFont) - { - if(m_bInternalLinkFont) - { - ::DeleteObject(m_hFontLink); - m_bInternalLinkFont = false; - } - - m_hFontLink = hFont; - - T* pT = static_cast(this); - pT->CalcLabelRect(); - } - - int GetIdealHeight() const - { - ATLASSERT(::IsWindow(m_hWnd)); - if(m_lpstrLabel == NULL && m_lpstrHyperLink == NULL) - return -1; - if(!m_bPaintLabel) - return -1; - - UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK; - - CClientDC dc(m_hWnd); - RECT rect = { 0 }; - GetClientRect(&rect); - HFONT hFontOld = dc.SelectFont(m_hFontNormal); - RECT rcText = rect; - dc.DrawText(_T("NS"), -1, &rcText, DT_LEFT | uFormat | DT_CALCRECT); - dc.SelectFont(m_hFontLink); - RECT rcLink = rect; - dc.DrawText(_T("NS"), -1, &rcLink, DT_LEFT | uFormat | DT_CALCRECT); - dc.SelectFont(hFontOld); - return max(rcText.bottom - rcText.top, rcLink.bottom - rcLink.top); - } - - bool GetIdealSize(SIZE& size) const - { - int cx = 0, cy = 0; - bool bRet = GetIdealSize(cx, cy); - if(bRet) - { - size.cx = cx; - size.cy = cy; - } - return bRet; - } - - bool GetIdealSize(int& cx, int& cy) const - { - ATLASSERT(::IsWindow(m_hWnd)); - if(m_lpstrLabel == NULL && m_lpstrHyperLink == NULL) - return false; - if(!m_bPaintLabel) - return false; - - CClientDC dc(m_hWnd); - RECT rcClient = { 0 }; - GetClientRect(&rcClient); - RECT rcAll = rcClient; - - if(IsUsingTags()) - { - // find tags and label parts - LPTSTR lpstrLeft = NULL; - int cchLeft = 0; - LPTSTR lpstrLink = NULL; - int cchLink = 0; - LPTSTR lpstrRight = NULL; - int cchRight = 0; - - const T* pT = static_cast(this); - pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight); - - // get label part rects - UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK; - - HFONT hFontOld = dc.SelectFont(m_hFontNormal); - RECT rcLeft = rcClient; - dc.DrawText(lpstrLeft, cchLeft, &rcLeft, DT_LEFT | uFormat | DT_CALCRECT); - - dc.SelectFont(m_hFontLink); - RECT rcLink = { rcLeft.right, rcLeft.top, rcClient.right, rcClient.bottom }; - dc.DrawText(lpstrLink, cchLink, &rcLink, DT_LEFT | uFormat | DT_CALCRECT); - - dc.SelectFont(m_hFontNormal); - RECT rcRight = { rcLink.right, rcLink.top, rcClient.right, rcClient.bottom }; - dc.DrawText(lpstrRight, cchRight, &rcRight, DT_LEFT | uFormat | DT_CALCRECT); - - dc.SelectFont(hFontOld); - - int cyMax = max(rcLeft.bottom, max(rcLink.bottom, rcRight.bottom)); - ::SetRect(&rcAll, rcLeft.left, rcLeft.top, rcRight.right, cyMax); - } - else - { - HFONT hOldFont = NULL; - if(m_hFontLink != NULL) - hOldFont = dc.SelectFont(m_hFontLink); - LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink; - DWORD dwStyle = GetStyle(); - UINT uFormat = DT_LEFT; - if (dwStyle & SS_CENTER) - uFormat = DT_CENTER; - else if (dwStyle & SS_RIGHT) - uFormat = DT_RIGHT; - uFormat |= IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK; - dc.DrawText(lpstrText, -1, &rcAll, uFormat | DT_CALCRECT); - if(m_hFontLink != NULL) - dc.SelectFont(hOldFont); - if (dwStyle & SS_CENTER) - { - int dx = (rcClient.right - rcAll.right) / 2; - ::OffsetRect(&rcAll, dx, 0); - } - else if (dwStyle & SS_RIGHT) - { - int dx = rcClient.right - rcAll.right; - ::OffsetRect(&rcAll, dx, 0); - } - } - - cx = rcAll.right - rcAll.left; - cy = rcAll.bottom - rcAll.top; - - return true; - } - - // for command buttons only - bool GetToolTipText(LPTSTR lpstrBuffer, int nLength) const - { - ATLASSERT(IsCommandButton()); - return GetHyperLink(lpstrBuffer, nLength); - } - - bool SetToolTipText(LPCTSTR lpstrToolTipText) - { - ATLASSERT(IsCommandButton()); - return SetHyperLink(lpstrToolTipText); - } - -// Operations - BOOL SubclassWindow(HWND hWnd) - { - ATLASSERT(m_hWnd == NULL); - ATLASSERT(::IsWindow(hWnd)); - if(m_hFontNormal == NULL) - m_hFontNormal = (HFONT)::SendMessage(hWnd, WM_GETFONT, 0, 0L); -#if (_MSC_VER >= 1300) - BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits>::SubclassWindow(hWnd); -#else // !(_MSC_VER >= 1300) - typedef ATL::CWindowImpl< T, TBase, TWinTraits> _baseClass; - BOOL bRet = _baseClass::SubclassWindow(hWnd); -#endif // !(_MSC_VER >= 1300) - if(bRet) - { - T* pT = static_cast(this); - pT->Init(); - } - return bRet; - } - - bool Navigate() - { - ATLASSERT(::IsWindow(m_hWnd)); - bool bRet = true; - if(IsNotifyButton()) - { - NMHDR nmhdr = { m_hWnd, GetDlgCtrlID(), NM_CLICK }; - ::SendMessage(GetParent(), WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&nmhdr); - } - else if(IsCommandButton()) - { - ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd); - } - else - { - ATLASSERT(m_lpstrHyperLink != NULL); -#ifndef _WIN32_WCE - DWORD_PTR dwRet = (DWORD_PTR)::ShellExecute(0, _T("open"), m_lpstrHyperLink, 0, 0, SW_SHOWNORMAL); - bRet = (dwRet > 32); -#else // CE specific - SHELLEXECUTEINFO shExeInfo = { sizeof(SHELLEXECUTEINFO), 0, 0, L"open", m_lpstrHyperLink, 0, 0, SW_SHOWNORMAL, 0, 0, 0, 0, 0, 0, 0 }; - ::ShellExecuteEx(&shExeInfo); - DWORD_PTR dwRet = (DWORD_PTR)shExeInfo.hInstApp; - bRet = (dwRet == 0) || (dwRet > 32); -#endif // _WIN32_WCE - ATLASSERT(bRet); - if(bRet) - { - m_bVisited = true; - Invalidate(); - } - } - return bRet; - } - - void CreateLinkFontFromNormal() - { - if(m_bInternalLinkFont) - { - ::DeleteObject(m_hFontLink); - m_bInternalLinkFont = false; - } - - CFontHandle font = (m_hFontNormal != NULL) ? m_hFontNormal : (HFONT)::GetStockObject(SYSTEM_FONT); - LOGFONT lf = { 0 }; - font.GetLogFont(&lf); - - if(IsUsingTagsBold()) - lf.lfWeight = FW_BOLD; - else if(!IsNotUnderlined()) - lf.lfUnderline = TRUE; - - m_hFontLink = ::CreateFontIndirect(&lf); - m_bInternalLinkFont = true; - ATLASSERT(m_hFontLink != NULL); - } - -// Message map and handlers - BEGIN_MSG_MAP(CHyperLinkImpl) - MESSAGE_HANDLER(WM_CREATE, OnCreate) -#ifndef _WIN32_WCE - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) - MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage) -#endif // !_WIN32_WCE - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) - MESSAGE_HANDLER(WM_PAINT, OnPaint) -#ifndef _WIN32_WCE - MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) -#endif // !_WIN32_WCE - MESSAGE_HANDLER(WM_SETFOCUS, OnFocus) - MESSAGE_HANDLER(WM_KILLFOCUS, OnFocus) - MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) -#ifndef _WIN32_WCE - MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave) -#endif // !_WIN32_WCE - MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) - MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) - MESSAGE_HANDLER(WM_CHAR, OnChar) - MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode) - MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor) - MESSAGE_HANDLER(WM_ENABLE, OnEnable) - MESSAGE_HANDLER(WM_GETFONT, OnGetFont) - MESSAGE_HANDLER(WM_SETFONT, OnSetFont) - MESSAGE_HANDLER(WM_UPDATEUISTATE, OnUpdateUiState) - MESSAGE_HANDLER(WM_SIZE, OnSize) - END_MSG_MAP() - - LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->Init(); - return 0; - } - -#ifndef _WIN32_WCE - LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - if(m_tip.IsWindow()) - { - m_tip.DestroyWindow(); - m_tip.m_hWnd = NULL; - } - - if(m_bInternalLinkFont) - { - ::DeleteObject(m_hFontLink); - m_hFontLink = NULL; - m_bInternalLinkFont = false; - } - - if(m_bInternalNormalFont) - { - ::DeleteObject(m_hFontNormal); - m_hFontNormal = NULL; - m_bInternalNormalFont = false; - } - - bHandled = FALSE; - return 1; - } - - LRESULT OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - MSG msg = { m_hWnd, uMsg, wParam, lParam }; - if(m_tip.IsWindow() && IsUsingToolTip()) - m_tip.RelayEvent(&msg); - bHandled = FALSE; - return 1; - } -#endif // !_WIN32_WCE - - LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - return 1; // no background painting needed (we do it all during WM_PAINT) - } - - LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - if(!m_bPaintLabel) - { - bHandled = FALSE; - return 1; - } - - T* pT = static_cast(this); - if(wParam != NULL) - { - pT->DoEraseBackground((HDC)wParam); - pT->DoPaint((HDC)wParam); - } - else - { - CPaintDC dc(m_hWnd); - pT->DoEraseBackground(dc.m_hDC); - pT->DoPaint(dc.m_hDC); - } - - return 0; - } - - LRESULT OnFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - if(m_bPaintLabel) - Invalidate(); - else - bHandled = FALSE; - return 0; - } - - LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - if((m_lpstrHyperLink != NULL || IsCommandButton()) && ::PtInRect(&m_rcLink, pt)) - { - ::SetCursor(m_hCursor); - if(IsUnderlineHover()) - { - if(!m_bHover) - { - m_bHover = true; - InvalidateRect(&m_rcLink); - UpdateWindow(); -#ifndef _WIN32_WCE - StartTrackMouseLeave(); -#endif // !_WIN32_WCE - } - } - } - else - { - if(IsUnderlineHover()) - { - if(m_bHover) - { - m_bHover = false; - InvalidateRect(&m_rcLink); - UpdateWindow(); - } - } - bHandled = FALSE; - } - return 0; - } - -#ifndef _WIN32_WCE - LRESULT OnMouseLeave(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - if(IsUnderlineHover() && m_bHover) - { - m_bHover = false; - InvalidateRect(&m_rcLink); - UpdateWindow(); - } - return 0; - } -#endif // !_WIN32_WCE - - LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) - { - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - if(::PtInRect(&m_rcLink, pt)) - { - SetFocus(); - SetCapture(); - } - return 0; - } - - LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) - { - if(GetCapture() == m_hWnd) - { - ReleaseCapture(); - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - if(::PtInRect(&m_rcLink, pt)) - { - T* pT = static_cast(this); - pT->Navigate(); - } - } - return 0; - } - - LRESULT OnChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - if(wParam == VK_RETURN || wParam == VK_SPACE) - { - T* pT = static_cast(this); - pT->Navigate(); - } - return 0; - } - - LRESULT OnGetDlgCode(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - return DLGC_WANTCHARS; - } - - LRESULT OnSetCursor(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - POINT pt = { 0, 0 }; - GetCursorPos(&pt); - ScreenToClient(&pt); - if((m_lpstrHyperLink != NULL || IsCommandButton()) && ::PtInRect(&m_rcLink, pt)) - { - return TRUE; - } - bHandled = FALSE; - return FALSE; - } - - LRESULT OnEnable(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - Invalidate(); - UpdateWindow(); - return 0; - } - - LRESULT OnGetFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - return (LRESULT)m_hFontNormal; - } - - LRESULT OnSetFont(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - if(m_bInternalNormalFont) - { - ::DeleteObject(m_hFontNormal); - m_bInternalNormalFont = false; - } - - bool bCreateLinkFont = m_bInternalLinkFont; - - m_hFontNormal = (HFONT)wParam; - - if(bCreateLinkFont || IsAutoCreateLinkFont()) - CreateLinkFontFromNormal(); - - T* pT = static_cast(this); - pT->CalcLabelRect(); - - if((BOOL)lParam) - { - Invalidate(); - UpdateWindow(); - } - - return 0; - } - - LRESULT OnUpdateUiState(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - // If the control is subclassed or superclassed, this message can cause - // repainting without WM_PAINT. We don't use this state, so just do nothing. - return 0; - } - - LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->CalcLabelRect(); - pT->Invalidate(); - return 0; - } - -// Implementation - void Init() - { - ATLASSERT(::IsWindow(m_hWnd)); - - // Check if we should paint a label - const int cchBuff = 8; - TCHAR szBuffer[cchBuff] = { 0 }; - if(::GetClassName(m_hWnd, szBuffer, cchBuff)) - { - if(lstrcmpi(szBuffer, _T("static")) == 0) - { - ModifyStyle(0, SS_NOTIFY); // we need this - DWORD dwStyle = GetStyle() & 0x000000FF; -#ifndef _WIN32_WCE - if(dwStyle == SS_ICON || dwStyle == SS_BLACKRECT || dwStyle == SS_GRAYRECT || - dwStyle == SS_WHITERECT || dwStyle == SS_BLACKFRAME || dwStyle == SS_GRAYFRAME || - dwStyle == SS_WHITEFRAME || dwStyle == SS_OWNERDRAW || - dwStyle == SS_BITMAP || dwStyle == SS_ENHMETAFILE) -#else // CE specific - if(dwStyle == SS_ICON || dwStyle == SS_BITMAP) -#endif // _WIN32_WCE - m_bPaintLabel = false; - } - } - - // create or load a cursor -#if (WINVER >= 0x0500) || defined(_WIN32_WCE) - m_hCursor = ::LoadCursor(NULL, IDC_HAND); -#else - m_hCursor = ::CreateCursor(ModuleHelper::GetModuleInstance(), _AtlHyperLink_CursorData.xHotSpot, _AtlHyperLink_CursorData.yHotSpot, _AtlHyperLink_CursorData.cxWidth, _AtlHyperLink_CursorData.cyHeight, _AtlHyperLink_CursorData.arrANDPlane, _AtlHyperLink_CursorData.arrXORPlane); -#endif - ATLASSERT(m_hCursor != NULL); - - // set fonts - if(m_bPaintLabel) - { - if(m_hFontNormal == NULL) - { - m_hFontNormal = AtlCreateControlFont(); - m_bInternalNormalFont = true; - } - - if(m_hFontLink == NULL) - CreateLinkFontFromNormal(); - } - -#ifndef _WIN32_WCE - // create a tool tip - m_tip.Create(m_hWnd); - ATLASSERT(m_tip.IsWindow()); -#endif // !_WIN32_WCE - - // set label (defaults to window text) - if(m_lpstrLabel == NULL) - { - int nLen = GetWindowTextLength(); - if(nLen > 0) - { - ATLTRY(m_lpstrLabel = new TCHAR[nLen + 1]); - if(m_lpstrLabel != NULL) - ATLVERIFY(GetWindowText(m_lpstrLabel, nLen + 1) > 0); - } - } - - T* pT = static_cast(this); - pT->CalcLabelRect(); - - // set hyperlink (defaults to label), or just activate tool tip if already set - if(m_lpstrHyperLink == NULL && !IsCommandButton()) - { - if(m_lpstrLabel != NULL) - SetHyperLink(m_lpstrLabel); - } -#ifndef _WIN32_WCE - else - { - m_tip.Activate(TRUE); - m_tip.AddTool(m_hWnd, m_lpstrHyperLink, &m_rcLink, 1); - } -#endif // !_WIN32_WCE - - // set link colors - if(m_bPaintLabel) - { - CRegKeyEx rk; - LONG lRet = rk.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Internet Explorer\\Settings")); - if(lRet == ERROR_SUCCESS) - { - const int cchValue = 12; - TCHAR szValue[cchValue] = { 0 }; - ULONG ulCount = cchValue; - lRet = rk.QueryStringValue(_T("Anchor Color"), szValue, &ulCount); - if(lRet == ERROR_SUCCESS) - { - COLORREF clr = pT->_ParseColorString(szValue); - ATLASSERT(clr != CLR_INVALID); - if(clr != CLR_INVALID) - m_clrLink = clr; - } - - ulCount = cchValue; - lRet = rk.QueryStringValue(_T("Anchor Color Visited"), szValue, &ulCount); - if(lRet == ERROR_SUCCESS) - { - COLORREF clr = pT->_ParseColorString(szValue); - ATLASSERT(clr != CLR_INVALID); - if(clr != CLR_INVALID) - m_clrVisited = clr; - } - } - } - } - - static COLORREF _ParseColorString(LPTSTR lpstr) - { - int c[3] = { -1, -1, -1 }; - LPTSTR p = NULL; - for(int i = 0; i < 2; i++) - { - for(p = lpstr; *p != _T('\0'); p = ::CharNext(p)) - { - if(*p == _T(',')) - { - *p = _T('\0'); - c[i] = T::_xttoi(lpstr); - lpstr = &p[1]; - break; - } - } - if(c[i] == -1) - return CLR_INVALID; - } - if(*lpstr == _T('\0')) - return CLR_INVALID; - c[2] = T::_xttoi(lpstr); - - return RGB(c[0], c[1], c[2]); - } - - bool CalcLabelRect() - { - if(!::IsWindow(m_hWnd)) - return false; - if(m_lpstrLabel == NULL && m_lpstrHyperLink == NULL) - return false; - - CClientDC dc(m_hWnd); - RECT rcClient = { 0 }; - GetClientRect(&rcClient); - m_rcLink = rcClient; - if(!m_bPaintLabel) - return true; - - if(IsUsingTags()) - { - // find tags and label parts - LPTSTR lpstrLeft = NULL; - int cchLeft = 0; - LPTSTR lpstrLink = NULL; - int cchLink = 0; - LPTSTR lpstrRight = NULL; - int cchRight = 0; - - T* pT = static_cast(this); - pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight); - ATLASSERT(lpstrLink != NULL); - ATLASSERT(cchLink > 0); - - // get label part rects - HFONT hFontOld = dc.SelectFont(m_hFontNormal); - - UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK; - - RECT rcLeft = rcClient; - if(lpstrLeft != NULL) - dc.DrawText(lpstrLeft, cchLeft, &rcLeft, DT_LEFT | uFormat | DT_CALCRECT); - - dc.SelectFont(m_hFontLink); - RECT rcLink = rcClient; - if(lpstrLeft != NULL) - rcLink.left = rcLeft.right; - dc.DrawText(lpstrLink, cchLink, &rcLink, DT_LEFT | uFormat | DT_CALCRECT); - - dc.SelectFont(hFontOld); - - m_rcLink = rcLink; - } - else - { - HFONT hOldFont = NULL; - if(m_hFontLink != NULL) - hOldFont = dc.SelectFont(m_hFontLink); - LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink; - DWORD dwStyle = GetStyle(); - UINT uFormat = DT_LEFT; - if (dwStyle & SS_CENTER) - uFormat = DT_CENTER; - else if (dwStyle & SS_RIGHT) - uFormat = DT_RIGHT; - uFormat |= IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK; - dc.DrawText(lpstrText, -1, &m_rcLink, uFormat | DT_CALCRECT); - if(m_hFontLink != NULL) - dc.SelectFont(hOldFont); - if (dwStyle & SS_CENTER) - { - int dx = (rcClient.right - m_rcLink.right) / 2; - ::OffsetRect(&m_rcLink, dx, 0); - } - else if (dwStyle & SS_RIGHT) - { - int dx = rcClient.right - m_rcLink.right; - ::OffsetRect(&m_rcLink, dx, 0); - } - } - - return true; - } - - void CalcLabelParts(LPTSTR& lpstrLeft, int& cchLeft, LPTSTR& lpstrLink, int& cchLink, LPTSTR& lpstrRight, int& cchRight) const - { - lpstrLeft = NULL; - cchLeft = 0; - lpstrLink = NULL; - cchLink = 0; - lpstrRight = NULL; - cchRight = 0; - - LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink; - int cchText = lstrlen(lpstrText); - bool bOutsideLink = true; - for(int i = 0; i < cchText; i++) - { - if(lpstrText[i] != _T('<')) - continue; - - if(bOutsideLink) - { - if(::CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, &lpstrText[i], 3, _T(""), 3) == CSTR_EQUAL) - { - if(i > 0) - { - lpstrLeft = lpstrText; - cchLeft = i; - } - lpstrLink = &lpstrText[i + 3]; - bOutsideLink = false; - } - } - else - { - if(::CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, &lpstrText[i], 4, _T(""), 4) == CSTR_EQUAL) - { - cchLink = i - 3 - cchLeft; - if(lpstrText[i + 4] != 0) - { - lpstrRight = &lpstrText[i + 4]; - cchRight = cchText - (i + 4); - break; - } - } - } - } - - } - - void DoEraseBackground(CDCHandle dc) - { - HBRUSH hBrush = (HBRUSH)::SendMessage(GetParent(), WM_CTLCOLORSTATIC, (WPARAM)dc.m_hDC, (LPARAM)m_hWnd); - if(hBrush != NULL) - { - RECT rect = { 0 }; - GetClientRect(&rect); - dc.FillRect(&rect, hBrush); - } - } - - void DoPaint(CDCHandle dc) - { - if(IsUsingTags()) - { - // find tags and label parts - LPTSTR lpstrLeft = NULL; - int cchLeft = 0; - LPTSTR lpstrLink = NULL; - int cchLink = 0; - LPTSTR lpstrRight = NULL; - int cchRight = 0; - - T* pT = static_cast(this); - pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight); - - // get label part rects - RECT rcClient = { 0 }; - GetClientRect(&rcClient); - - dc.SetBkMode(TRANSPARENT); - HFONT hFontOld = dc.SelectFont(m_hFontNormal); - - UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK; - - if(lpstrLeft != NULL) - dc.DrawText(lpstrLeft, cchLeft, &rcClient, DT_LEFT | uFormat); - - COLORREF clrOld = dc.SetTextColor(IsWindowEnabled() ? (m_bVisited ? m_clrVisited : m_clrLink) : (::GetSysColor(COLOR_GRAYTEXT))); - if(m_hFontLink != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover))) - dc.SelectFont(m_hFontLink); - else - dc.SelectFont(m_hFontNormal); - - dc.DrawText(lpstrLink, cchLink, &m_rcLink, DT_LEFT | uFormat); - - dc.SetTextColor(clrOld); - dc.SelectFont(m_hFontNormal); - if(lpstrRight != NULL) - { - RECT rcRight = { m_rcLink.right, m_rcLink.top, rcClient.right, rcClient.bottom }; - dc.DrawText(lpstrRight, cchRight, &rcRight, DT_LEFT | uFormat); - } - - if(GetFocus() == m_hWnd) - dc.DrawFocusRect(&m_rcLink); - - dc.SelectFont(hFontOld); - } - else - { - dc.SetBkMode(TRANSPARENT); - COLORREF clrOld = dc.SetTextColor(IsWindowEnabled() ? (m_bVisited ? m_clrVisited : m_clrLink) : (::GetSysColor(COLOR_GRAYTEXT))); - - HFONT hFontOld = NULL; - if(m_hFontLink != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover))) - hFontOld = dc.SelectFont(m_hFontLink); - else - hFontOld = dc.SelectFont(m_hFontNormal); - - LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink; - - DWORD dwStyle = GetStyle(); - UINT uFormat = DT_LEFT; - if (dwStyle & SS_CENTER) - uFormat = DT_CENTER; - else if (dwStyle & SS_RIGHT) - uFormat = DT_RIGHT; - uFormat |= IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK; - - dc.DrawText(lpstrText, -1, &m_rcLink, uFormat); - - if(GetFocus() == m_hWnd) - dc.DrawFocusRect(&m_rcLink); - - dc.SetTextColor(clrOld); - dc.SelectFont(hFontOld); - } - } - -#ifndef _WIN32_WCE - BOOL StartTrackMouseLeave() - { - TRACKMOUSEEVENT tme = { 0 }; - tme.cbSize = sizeof(tme); - tme.dwFlags = TME_LEAVE; - tme.hwndTrack = m_hWnd; - return _TrackMouseEvent(&tme); - } -#endif // !_WIN32_WCE - -// Implementation helpers - bool IsUnderlined() const - { - return ((m_dwExtendedStyle & (HLINK_NOTUNDERLINED | HLINK_UNDERLINEHOVER)) == 0); - } - - bool IsNotUnderlined() const - { - return ((m_dwExtendedStyle & HLINK_NOTUNDERLINED) != 0); - } - - bool IsUnderlineHover() const - { - return ((m_dwExtendedStyle & HLINK_UNDERLINEHOVER) != 0); - } - - bool IsCommandButton() const - { - return ((m_dwExtendedStyle & HLINK_COMMANDBUTTON) != 0); - } - - bool IsNotifyButton() const - { - return ((m_dwExtendedStyle & HLINK_NOTIFYBUTTON) == HLINK_NOTIFYBUTTON); - } - - bool IsUsingTags() const - { - return ((m_dwExtendedStyle & HLINK_USETAGS) != 0); - } - - bool IsUsingTagsBold() const - { - return ((m_dwExtendedStyle & HLINK_USETAGSBOLD) == HLINK_USETAGSBOLD); - } - - bool IsUsingToolTip() const - { - return ((m_dwExtendedStyle & HLINK_NOTOOLTIP) == 0); - } - - bool IsAutoCreateLinkFont() const - { - return ((m_dwExtendedStyle & HLINK_AUTOCREATELINKFONT) == HLINK_AUTOCREATELINKFONT); - } - - bool IsSingleLine() const - { - return ((m_dwExtendedStyle & HLINK_SINGLELINE) == HLINK_SINGLELINE); - } - - static int _xttoi(const TCHAR* nptr) - { -#ifndef _ATL_MIN_CRT - return _ttoi(nptr); -#else // _ATL_MIN_CRT - while(*nptr == _T(' ')) // skip spaces - ++nptr; - - int c = (int)(_TUCHAR)*nptr++; - int sign = c; // save sign indication - if (c == _T('-') || c == _T('+')) - c = (int)(_TUCHAR)*nptr++; // skip sign - - int total = 0; - while((TCHAR)c >= _T('0') && (TCHAR)c <= _T('9')) - { - total = 10 * total + ((TCHAR)c - _T('0')); // accumulate digit - c = (int)(_TUCHAR)*nptr++; // get next char - } - - // return result, negated if necessary - return ((TCHAR)sign != _T('-')) ? total : -total; -#endif // _ATL_MIN_CRT - } -}; - -class CHyperLink : public CHyperLinkImpl -{ -public: - DECLARE_WND_CLASS(_T("WTL_HyperLink")) -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CWaitCursor - displays a wait cursor - -class CWaitCursor -{ -public: -// Data - HCURSOR m_hWaitCursor; - HCURSOR m_hOldCursor; - bool m_bInUse; - -// Constructor/destructor - CWaitCursor(bool bSet = true, LPCTSTR lpstrCursor = IDC_WAIT, bool bSys = true) : m_hOldCursor(NULL), m_bInUse(false) - { - HINSTANCE hInstance = bSys ? NULL : ModuleHelper::GetResourceInstance(); - m_hWaitCursor = ::LoadCursor(hInstance, lpstrCursor); - ATLASSERT(m_hWaitCursor != NULL); - - if(bSet) - Set(); - } - - ~CWaitCursor() - { - Restore(); - } - -// Methods - bool Set() - { - if(m_bInUse) - return false; - m_hOldCursor = ::SetCursor(m_hWaitCursor); - m_bInUse = true; - return true; - } - - bool Restore() - { - if(!m_bInUse) - return false; - ::SetCursor(m_hOldCursor); - m_bInUse = false; - return true; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CCustomWaitCursor - for custom and animated cursors - -class CCustomWaitCursor : public CWaitCursor -{ -public: -// Constructor/destructor - CCustomWaitCursor(ATL::_U_STRINGorID cursor, bool bSet = true, HINSTANCE hInstance = NULL) : - CWaitCursor(false, IDC_WAIT, true) - { - if(hInstance == NULL) - hInstance = ModuleHelper::GetResourceInstance(); - m_hWaitCursor = (HCURSOR)::LoadImage(hInstance, cursor.m_lpstr, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE); - - if(bSet) - Set(); - } - - ~CCustomWaitCursor() - { - Restore(); -#if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))) - ::DestroyCursor(m_hWaitCursor); -#endif // !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))) - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CMultiPaneStatusBarCtrl - Status Bar with multiple panes - -template -class ATL_NO_VTABLE CMultiPaneStatusBarCtrlImpl : public ATL::CWindowImpl< T, TBase > -{ -public: - DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName()) - -// Data - enum { m_cxPaneMargin = 3 }; - - int m_nPanes; - int* m_pPane; - -// Constructor/destructor - CMultiPaneStatusBarCtrlImpl() : m_nPanes(0), m_pPane(NULL) - { } - - ~CMultiPaneStatusBarCtrlImpl() - { - delete [] m_pPane; - } - -// Methods - HWND Create(HWND hWndParent, LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR) - { -#if (_MSC_VER >= 1300) - return ATL::CWindowImpl< T, TBase >::Create(hWndParent, rcDefault, lpstrText, dwStyle, 0, nID); -#else // !(_MSC_VER >= 1300) - typedef ATL::CWindowImpl< T, TBase > _baseClass; - return _baseClass::Create(hWndParent, rcDefault, lpstrText, dwStyle, 0, nID); -#endif // !(_MSC_VER >= 1300) - } - - HWND Create(HWND hWndParent, UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR) - { - const int cchMax = 128; // max text length is 127 for status bars (+1 for null) - TCHAR szText[cchMax]; - szText[0] = 0; - ::LoadString(ModuleHelper::GetResourceInstance(), nTextID, szText, cchMax); - return Create(hWndParent, szText, dwStyle, nID); - } - - BOOL SetPanes(int* pPanes, int nPanes, bool bSetText = true) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(nPanes > 0); - - m_nPanes = nPanes; - delete [] m_pPane; - m_pPane = NULL; - - ATLTRY(m_pPane = new int[nPanes]); - ATLASSERT(m_pPane != NULL); - if(m_pPane == NULL) - return FALSE; - - CTempBuffer buff; - int* pPanesPos = buff.Allocate(nPanes); - ATLASSERT(pPanesPos != NULL); - if(pPanesPos == NULL) - return FALSE; - - SecureHelper::memcpy_x(m_pPane, nPanes * sizeof(int), pPanes, nPanes * sizeof(int)); - - // get status bar DC and set font - CClientDC dc(m_hWnd); - HFONT hOldFont = dc.SelectFont(GetFont()); - - // get status bar borders - int arrBorders[3] = { 0 }; - GetBorders(arrBorders); - - const int cchBuff = 128; - TCHAR szBuff[cchBuff] = { 0 }; - SIZE size = { 0, 0 }; - int cxLeft = arrBorders[0]; - - // calculate right edge of each part - for(int i = 0; i < nPanes; i++) - { - if(pPanes[i] == ID_DEFAULT_PANE) - { - // make very large, will be resized later - pPanesPos[i] = INT_MAX / 2; - } - else - { - ::LoadString(ModuleHelper::GetResourceInstance(), pPanes[i], szBuff, cchBuff); - dc.GetTextExtent(szBuff, lstrlen(szBuff), &size); - T* pT = static_cast(this); - pT; - pPanesPos[i] = cxLeft + size.cx + arrBorders[2] + 2 * pT->m_cxPaneMargin; - } - cxLeft = pPanesPos[i]; - } - - BOOL bRet = SetParts(nPanes, pPanesPos); - - if(bRet && bSetText) - { - for(int i = 0; i < nPanes; i++) - { - if(pPanes[i] != ID_DEFAULT_PANE) - { - ::LoadString(ModuleHelper::GetResourceInstance(), pPanes[i], szBuff, cchBuff); - SetPaneText(m_pPane[i], szBuff); - } - } - } - - dc.SelectFont(hOldFont); - return bRet; - } - - bool GetPaneTextLength(int nPaneID, int* pcchLength = NULL, int* pnType = NULL) const - { - ATLASSERT(::IsWindow(m_hWnd)); - int nIndex = GetPaneIndexFromID(nPaneID); - if(nIndex == -1) - return false; - - int nLength = GetTextLength(nIndex, pnType); - if(pcchLength != NULL) - *pcchLength = nLength; - - return true; - } - - BOOL GetPaneText(int nPaneID, LPTSTR lpstrText, int* pcchLength = NULL, int* pnType = NULL) const - { - ATLASSERT(::IsWindow(m_hWnd)); - int nIndex = GetPaneIndexFromID(nPaneID); - if(nIndex == -1) - return FALSE; - - int nLength = GetText(nIndex, lpstrText, pnType); - if(pcchLength != NULL) - *pcchLength = nLength; - - return TRUE; - } - - BOOL SetPaneText(int nPaneID, LPCTSTR lpstrText, int nType = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - int nIndex = GetPaneIndexFromID(nPaneID); - if(nIndex == -1) - return FALSE; - - return SetText(nIndex, lpstrText, nType); - } - - BOOL GetPaneRect(int nPaneID, LPRECT lpRect) const - { - ATLASSERT(::IsWindow(m_hWnd)); - int nIndex = GetPaneIndexFromID(nPaneID); - if(nIndex == -1) - return FALSE; - - return GetRect(nIndex, lpRect); - } - - BOOL SetPaneWidth(int nPaneID, int cxWidth) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(nPaneID != ID_DEFAULT_PANE); // Can't resize this one - int nIndex = GetPaneIndexFromID(nPaneID); - if(nIndex == -1) - return FALSE; - - // get pane positions - CTempBuffer buff; - int* pPanesPos = buff.Allocate(m_nPanes); - if(pPanesPos == NULL) - return FALSE; - GetParts(m_nPanes, pPanesPos); - // calculate offset - int cxPaneWidth = pPanesPos[nIndex] - ((nIndex == 0) ? 0 : pPanesPos[nIndex - 1]); - int cxOff = cxWidth - cxPaneWidth; - // find variable width pane - int nDef = m_nPanes; - for(int i = 0; i < m_nPanes; i++) - { - if(m_pPane[i] == ID_DEFAULT_PANE) - { - nDef = i; - break; - } - } - // resize - if(nIndex < nDef) // before default pane - { - for(int i = nIndex; i < nDef; i++) - pPanesPos[i] += cxOff; - - } - else // after default one - { - for(int i = nDef; i < nIndex; i++) - pPanesPos[i] -= cxOff; - } - // set pane postions - return SetParts(m_nPanes, pPanesPos); - } - -#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - BOOL GetPaneTipText(int nPaneID, LPTSTR lpstrText, int nSize) const - { - ATLASSERT(::IsWindow(m_hWnd)); - int nIndex = GetPaneIndexFromID(nPaneID); - if(nIndex == -1) - return FALSE; - - GetTipText(nIndex, lpstrText, nSize); - return TRUE; - } - - BOOL SetPaneTipText(int nPaneID, LPCTSTR lpstrText) - { - ATLASSERT(::IsWindow(m_hWnd)); - int nIndex = GetPaneIndexFromID(nPaneID); - if(nIndex == -1) - return FALSE; - - SetTipText(nIndex, lpstrText); - return TRUE; - } -#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - -#if ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500)) - BOOL GetPaneIcon(int nPaneID, HICON& hIcon) const - { - ATLASSERT(::IsWindow(m_hWnd)); - int nIndex = GetPaneIndexFromID(nPaneID); - if(nIndex == -1) - return FALSE; - - hIcon = GetIcon(nIndex); - return TRUE; - } - - BOOL SetPaneIcon(int nPaneID, HICON hIcon) - { - ATLASSERT(::IsWindow(m_hWnd)); - int nIndex = GetPaneIndexFromID(nPaneID); - if(nIndex == -1) - return FALSE; - - return SetIcon(nIndex, hIcon); - } -#endif // ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500)) - -// Message map and handlers - BEGIN_MSG_MAP(CMultiPaneStatusBarCtrlImpl< T >) - MESSAGE_HANDLER(WM_SIZE, OnSize) - END_MSG_MAP() - - LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); - if(wParam != SIZE_MINIMIZED && m_nPanes > 0) - { - T* pT = static_cast(this); - pT->UpdatePanesLayout(); - } - return lRet; - } - -// Implementation - BOOL UpdatePanesLayout() - { - // get pane positions - CTempBuffer buff; - int* pPanesPos = buff.Allocate(m_nPanes); - ATLASSERT(pPanesPos != NULL); - if(pPanesPos == NULL) - return FALSE; - int nRet = GetParts(m_nPanes, pPanesPos); - ATLASSERT(nRet == m_nPanes); - if(nRet != m_nPanes) - return FALSE; - // calculate offset - RECT rcClient = { 0 }; - GetClientRect(&rcClient); - int cxOff = rcClient.right - pPanesPos[m_nPanes - 1]; -#ifndef _WIN32_WCE - // Move panes left if size grip box is present - if((GetStyle() & SBARS_SIZEGRIP) != 0) - cxOff -= ::GetSystemMetrics(SM_CXVSCROLL) + ::GetSystemMetrics(SM_CXEDGE); -#endif // !_WIN32_WCE - // find variable width pane - int i; - for(i = 0; i < m_nPanes; i++) - { - if(m_pPane[i] == ID_DEFAULT_PANE) - break; - } - // resize all panes from the variable one to the right - if((i < m_nPanes) && (pPanesPos[i] + cxOff) > ((i == 0) ? 0 : pPanesPos[i - 1])) - { - for(; i < m_nPanes; i++) - pPanesPos[i] += cxOff; - } - // set pane postions - return SetParts(m_nPanes, pPanesPos); - } - - int GetPaneIndexFromID(int nPaneID) const - { - for(int i = 0; i < m_nPanes; i++) - { - if(m_pPane[i] == nPaneID) - return i; - } - - return -1; // not found - } -}; - -class CMultiPaneStatusBarCtrl : public CMultiPaneStatusBarCtrlImpl -{ -public: - DECLARE_WND_SUPERCLASS(_T("WTL_MultiPaneStatusBar"), GetWndClassName()) -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CPaneContainer - provides header with title and close button for panes - -// pane container extended styles -#define PANECNT_NOCLOSEBUTTON 0x00000001 -#define PANECNT_VERTICAL 0x00000002 -#define PANECNT_FLATBORDER 0x00000004 -#define PANECNT_NOBORDER 0x00000008 - -template -class ATL_NO_VTABLE CPaneContainerImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CCustomDraw< T > -{ -public: - DECLARE_WND_CLASS_EX(NULL, 0, -1) - -// Constants - enum - { - m_cxyBorder = 2, - m_cxyTextOffset = 4, - m_cxyBtnOffset = 1, - - m_cchTitle = 80, - - m_cxImageTB = 13, - m_cyImageTB = 11, - m_cxyBtnAddTB = 7, - - m_cxToolBar = m_cxImageTB + m_cxyBtnAddTB + m_cxyBorder + m_cxyBtnOffset, - - m_xBtnImageLeft = 6, - m_yBtnImageTop = 5, - m_xBtnImageRight = 12, - m_yBtnImageBottom = 11, - - m_nCloseBtnID = ID_PANE_CLOSE - }; - -// Data members - CToolBarCtrl m_tb; - ATL::CWindow m_wndClient; - int m_cxyHeader; - TCHAR m_szTitle[m_cchTitle]; - DWORD m_dwExtendedStyle; // Pane container specific extended styles - HFONT m_hFont; - bool m_bInternalFont; - - -// Constructor - CPaneContainerImpl() : m_cxyHeader(0), m_dwExtendedStyle(0), m_hFont(NULL), m_bInternalFont(false) - { - m_szTitle[0] = 0; - } - -// Attributes - DWORD GetPaneContainerExtendedStyle() const - { - return m_dwExtendedStyle; - } - - DWORD SetPaneContainerExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) - { - DWORD dwPrevStyle = m_dwExtendedStyle; - if(dwMask == 0) - m_dwExtendedStyle = dwExtendedStyle; - else - m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); - if(m_hWnd != NULL) - { - T* pT = static_cast(this); - bool bUpdate = false; - - if(((dwPrevStyle & PANECNT_NOCLOSEBUTTON) != 0) && ((m_dwExtendedStyle & PANECNT_NOCLOSEBUTTON) == 0)) // add close button - { - pT->CreateCloseButton(); - bUpdate = true; - } - else if(((dwPrevStyle & PANECNT_NOCLOSEBUTTON) == 0) && ((m_dwExtendedStyle & PANECNT_NOCLOSEBUTTON) != 0)) // remove close button - { - pT->DestroyCloseButton(); - bUpdate = true; - } - - if((dwPrevStyle & PANECNT_VERTICAL) != (m_dwExtendedStyle & PANECNT_VERTICAL)) // change orientation - { - pT->CalcSize(); - bUpdate = true; - } - - if((dwPrevStyle & (PANECNT_FLATBORDER | PANECNT_NOBORDER)) != - (m_dwExtendedStyle & (PANECNT_FLATBORDER | PANECNT_NOBORDER))) // change border - { - bUpdate = true; - } - - if(bUpdate) - pT->UpdateLayout(); - } - return dwPrevStyle; - } - - HWND GetClient() const - { - return m_wndClient; - } - - HWND SetClient(HWND hWndClient) - { - HWND hWndOldClient = m_wndClient; - m_wndClient = hWndClient; - if(m_hWnd != NULL) - { - T* pT = static_cast(this); - pT->UpdateLayout(); - } - return hWndOldClient; - } - - BOOL GetTitle(LPTSTR lpstrTitle, int cchLength) const - { - ATLASSERT(lpstrTitle != NULL); - - errno_t nRet = SecureHelper::strncpy_x(lpstrTitle, cchLength, m_szTitle, _TRUNCATE); - - return (nRet == 0 || nRet == STRUNCATE); - } - - BOOL SetTitle(LPCTSTR lpstrTitle) - { - ATLASSERT(lpstrTitle != NULL); - - errno_t nRet = SecureHelper::strncpy_x(m_szTitle, m_cchTitle, lpstrTitle, _TRUNCATE); - bool bRet = (nRet == 0 || nRet == STRUNCATE); - if(bRet && m_hWnd != NULL) - { - T* pT = static_cast(this); - pT->UpdateLayout(); - } - - return bRet; - } - - int GetTitleLength() const - { - return lstrlen(m_szTitle); - } - -// Methods - HWND Create(HWND hWndParent, LPCTSTR lpstrTitle = NULL, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, - DWORD dwExStyle = 0, UINT nID = 0, LPVOID lpCreateParam = NULL) - { - if(lpstrTitle != NULL) - SecureHelper::strncpy_x(m_szTitle, m_cchTitle, lpstrTitle, _TRUNCATE); -#if (_MSC_VER >= 1300) - return ATL::CWindowImpl< T, TBase, TWinTraits >::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam); -#else // !(_MSC_VER >= 1300) - typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass; - return _baseClass::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam); -#endif // !(_MSC_VER >= 1300) - } - - HWND Create(HWND hWndParent, UINT uTitleID, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, - DWORD dwExStyle = 0, UINT nID = 0, LPVOID lpCreateParam = NULL) - { - if(uTitleID != 0U) - ::LoadString(ModuleHelper::GetResourceInstance(), uTitleID, m_szTitle, m_cchTitle); -#if (_MSC_VER >= 1300) - return ATL::CWindowImpl< T, TBase, TWinTraits >::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam); -#else // !(_MSC_VER >= 1300) - typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass; - return _baseClass::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam); -#endif // !(_MSC_VER >= 1300) - } - - BOOL EnableCloseButton(BOOL bEnable) - { - ATLASSERT(::IsWindow(m_hWnd)); - T* pT = static_cast(this); - pT; // avoid level 4 warning - return (m_tb.m_hWnd != NULL) ? m_tb.EnableButton(pT->m_nCloseBtnID, bEnable) : FALSE; - } - - void UpdateLayout() - { - RECT rcClient = { 0 }; - GetClientRect(&rcClient); - T* pT = static_cast(this); - pT->UpdateLayout(rcClient.right, rcClient.bottom); - } - -// Message map and handlers - BEGIN_MSG_MAP(CPaneContainerImpl) - MESSAGE_HANDLER(WM_CREATE, OnCreate) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) - MESSAGE_HANDLER(WM_SIZE, OnSize) - MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) - MESSAGE_HANDLER(WM_GETFONT, OnGetFont) - MESSAGE_HANDLER(WM_SETFONT, OnSetFont) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) - MESSAGE_HANDLER(WM_PAINT, OnPaint) -#ifndef _WIN32_WCE - MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) -#endif // !_WIN32_WCE - MESSAGE_HANDLER(WM_NOTIFY, OnNotify) - MESSAGE_HANDLER(WM_COMMAND, OnCommand) - FORWARD_NOTIFICATIONS() - END_MSG_MAP() - - LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - if(m_hFont == NULL) - { - // The same as AtlCreateControlFont() for horizontal pane -#ifndef _WIN32_WCE - LOGFONT lf = { 0 }; - ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE); - if(IsVertical()) - lf.lfEscapement = 900; // 90 degrees - m_hFont = ::CreateFontIndirect(&lf); -#else // CE specific - m_hFont = (HFONT)::GetStockObject(SYSTEM_FONT); - if(IsVertical()) - { - CLogFont lf(m_hFont); - lf.lfEscapement = 900; // 90 degrees - m_hFont = ::CreateFontIndirect(&lf); - } -#endif // _WIN32_WCE - m_bInternalFont = true; - } - - T* pT = static_cast(this); - pT->CalcSize(); - - if((m_dwExtendedStyle & PANECNT_NOCLOSEBUTTON) == 0) - pT->CreateCloseButton(); - - return 0; - } - - LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - if(m_bInternalFont) - { - ::DeleteObject(m_hFont); - m_hFont = NULL; - m_bInternalFont = false; - } - - return 0; - } - - LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->UpdateLayout(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - return 0; - } - - LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - if(m_wndClient.m_hWnd != NULL) - m_wndClient.SetFocus(); - return 0; - } - - LRESULT OnGetFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - return (LRESULT)m_hFont; - } - - LRESULT OnSetFont(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - if(m_bInternalFont) - { - ::DeleteObject(m_hFont); - m_bInternalFont = false; - } - - m_hFont = (HFONT)wParam; - - T* pT = static_cast(this); - pT->CalcSize(); - - if((BOOL)lParam != FALSE) - pT->UpdateLayout(); - - return 0; - } - - LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - return 1; // no background needed - } - - LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - if(wParam != NULL) - { - pT->DrawPaneTitle((HDC)wParam); - - if(m_wndClient.m_hWnd == NULL) // no client window - pT->DrawPane((HDC)wParam); - } - else - { - CPaintDC dc(m_hWnd); - pT->DrawPaneTitle(dc.m_hDC); - - if(m_wndClient.m_hWnd == NULL) // no client window - pT->DrawPane(dc.m_hDC); - } - - return 0; - } - - LRESULT OnNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - if(m_tb.m_hWnd == NULL) - { - bHandled = FALSE; - return 1; - } - - T* pT = static_cast(this); - pT; - LPNMHDR lpnmh = (LPNMHDR)lParam; - LRESULT lRet = 0; - - // pass toolbar custom draw notifications to the base class - if(lpnmh->code == NM_CUSTOMDRAW && lpnmh->hwndFrom == m_tb.m_hWnd) - lRet = CCustomDraw< T >::OnCustomDraw(0, lpnmh, bHandled); -#ifndef _WIN32_WCE - // tooltip notifications come with the tooltip window handle and button ID, - // pass them to the parent if we don't handle them - else if(lpnmh->code == TTN_GETDISPINFO && lpnmh->idFrom == pT->m_nCloseBtnID) - bHandled = pT->GetToolTipText(lpnmh); -#endif // !_WIN32_WCE - // only let notifications not from the toolbar go to the parent - else if(lpnmh->hwndFrom != m_tb.m_hWnd && lpnmh->idFrom != pT->m_nCloseBtnID) - bHandled = FALSE; - - return lRet; - } - - LRESULT OnCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - // if command comes from the close button, substitute HWND of the pane container instead - if(m_tb.m_hWnd != NULL && (HWND)lParam == m_tb.m_hWnd) - return ::SendMessage(GetParent(), WM_COMMAND, wParam, (LPARAM)m_hWnd); - - bHandled = FALSE; - return 1; - } - -// Custom draw overrides - DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) - { - return CDRF_NOTIFYITEMDRAW; // we need per-item notifications - } - - DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw) - { - CDCHandle dc = lpNMCustomDraw->hdc; -#if (_WIN32_IE >= 0x0400) - RECT& rc = lpNMCustomDraw->rc; -#else // !(_WIN32_IE >= 0x0400) - RECT rc; - m_tb.GetItemRect(0, &rc); -#endif // !(_WIN32_IE >= 0x0400) - - dc.FillRect(&rc, COLOR_3DFACE); - - return CDRF_NOTIFYPOSTPAINT; - } - - DWORD OnItemPostPaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw) - { - CDCHandle dc = lpNMCustomDraw->hdc; -#if (_WIN32_IE >= 0x0400) - RECT& rc = lpNMCustomDraw->rc; -#else // !(_WIN32_IE >= 0x0400) - RECT rc = { 0 }; - m_tb.GetItemRect(0, &rc); -#endif // !(_WIN32_IE >= 0x0400) - - RECT rcImage = { m_xBtnImageLeft, m_yBtnImageTop, m_xBtnImageRight + 1, m_yBtnImageBottom + 1 }; - ::OffsetRect(&rcImage, rc.left, rc.top); - T* pT = static_cast(this); - - if((lpNMCustomDraw->uItemState & CDIS_DISABLED) != 0) - { - RECT rcShadow = rcImage; - ::OffsetRect(&rcShadow, 1, 1); - CPen pen1; - pen1.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DHILIGHT)); - pT->DrawButtonImage(dc, rcShadow, pen1); - CPen pen2; - pen2.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DSHADOW)); - pT->DrawButtonImage(dc, rcImage, pen2); - } - else - { - if((lpNMCustomDraw->uItemState & CDIS_SELECTED) != 0) - ::OffsetRect(&rcImage, 1, 1); - CPen pen; - pen.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNTEXT)); - pT->DrawButtonImage(dc, rcImage, pen); - } - - return CDRF_DODEFAULT; // continue with the default item painting - } - -// Implementation - overrideable methods - void UpdateLayout(int cxWidth, int cyHeight) - { - ATLASSERT(::IsWindow(m_hWnd)); - RECT rect = { 0 }; - - if(IsVertical()) - { - ::SetRect(&rect, 0, 0, m_cxyHeader, cyHeight); - if(m_tb.m_hWnd != NULL) - m_tb.SetWindowPos(NULL, m_cxyBorder, m_cxyBorder + m_cxyBtnOffset, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); - - if(m_wndClient.m_hWnd != NULL) - m_wndClient.SetWindowPos(NULL, m_cxyHeader, 0, cxWidth - m_cxyHeader, cyHeight, SWP_NOZORDER); - else - rect.right = cxWidth; - } - else - { - ::SetRect(&rect, 0, 0, cxWidth, m_cxyHeader); - if(m_tb.m_hWnd != NULL) - m_tb.SetWindowPos(NULL, rect.right - m_cxToolBar, m_cxyBorder + m_cxyBtnOffset, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); - - if(m_wndClient.m_hWnd != NULL) - m_wndClient.SetWindowPos(NULL, 0, m_cxyHeader, cxWidth, cyHeight - m_cxyHeader, SWP_NOZORDER); - else - rect.bottom = cyHeight; - } - - InvalidateRect(&rect); - } - - void CreateCloseButton() - { - ATLASSERT(m_tb.m_hWnd == NULL); - // create toolbar for the "x" button - m_tb.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NORESIZE | CCS_NOPARENTALIGN | CCS_NOMOVEY | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT, 0); - ATLASSERT(m_tb.IsWindow()); - - if(m_tb.m_hWnd != NULL) - { - T* pT = static_cast(this); - pT; // avoid level 4 warning - - m_tb.SetButtonStructSize(); - - TBBUTTON tbbtn = { 0 }; - tbbtn.idCommand = pT->m_nCloseBtnID; - tbbtn.fsState = TBSTATE_ENABLED; - tbbtn.fsStyle = TBSTYLE_BUTTON; - m_tb.AddButtons(1, &tbbtn); - - m_tb.SetBitmapSize(m_cxImageTB, m_cyImageTB); - m_tb.SetButtonSize(m_cxImageTB + m_cxyBtnAddTB, m_cyImageTB + m_cxyBtnAddTB); - - if(IsVertical()) - m_tb.SetWindowPos(NULL, m_cxyBorder + m_cxyBtnOffset, m_cxyBorder + m_cxyBtnOffset, m_cxImageTB + m_cxyBtnAddTB, m_cyImageTB + m_cxyBtnAddTB, SWP_NOZORDER | SWP_NOACTIVATE); - else - m_tb.SetWindowPos(NULL, 0, 0, m_cxImageTB + m_cxyBtnAddTB, m_cyImageTB + m_cxyBtnAddTB, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); - } - } - - void DestroyCloseButton() - { - if(m_tb.m_hWnd != NULL) - m_tb.DestroyWindow(); - } - - void CalcSize() - { - T* pT = static_cast(this); - CFontHandle font = pT->GetTitleFont(); - if(font.IsNull()) - font = (HFONT)::GetStockObject(SYSTEM_FONT); - LOGFONT lf = { 0 }; - font.GetLogFont(lf); - if(IsVertical()) - { - m_cxyHeader = m_cxImageTB + m_cxyBtnAddTB + m_cxyBorder; - } - else - { - int cyFont = abs(lf.lfHeight) + m_cxyBorder + 2 * m_cxyTextOffset; - int cyBtn = m_cyImageTB + m_cxyBtnAddTB + m_cxyBorder + 2 * m_cxyBtnOffset; - m_cxyHeader = max(cyFont, cyBtn); - } - } - - HFONT GetTitleFont() const - { - return m_hFont; - } - -#ifndef _WIN32_WCE - BOOL GetToolTipText(LPNMHDR /*lpnmh*/) - { - return FALSE; - } -#endif // !_WIN32_WCE - - void DrawPaneTitle(CDCHandle dc) - { - RECT rect = { 0 }; - GetClientRect(&rect); - - UINT uBorder = BF_LEFT | BF_TOP | BF_ADJUST; - if(IsVertical()) - { - rect.right = rect.left + m_cxyHeader; - uBorder |= BF_BOTTOM; - } - else - { - rect.bottom = rect.top + m_cxyHeader; - uBorder |= BF_RIGHT; - } - - if((m_dwExtendedStyle & PANECNT_NOBORDER) == 0) - { - if((m_dwExtendedStyle & PANECNT_FLATBORDER) != 0) - uBorder |= BF_FLAT; - dc.DrawEdge(&rect, EDGE_ETCHED, uBorder); - } - dc.FillRect(&rect, COLOR_3DFACE); - - // draw title text - dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT)); - dc.SetBkMode(TRANSPARENT); - T* pT = static_cast(this); - HFONT hFontOld = dc.SelectFont(pT->GetTitleFont()); -#ifdef _WIN32_WCE - const UINT DT_END_ELLIPSIS = 0; -#endif // _WIN32_WCE - - if(IsVertical()) - { - rect.top += m_cxyTextOffset; - rect.bottom -= m_cxyTextOffset; - if(m_tb.m_hWnd != NULL) - rect.top += m_cxToolBar;; - - RECT rcCalc = { rect.left, rect.bottom, rect.right, rect.top }; - int cxFont = dc.DrawText(m_szTitle, -1, &rcCalc, DT_TOP | DT_SINGLELINE | DT_END_ELLIPSIS | DT_CALCRECT); - RECT rcText = { 0 }; - rcText.left = (rect.right - rect.left - cxFont) / 2; - rcText.right = rcText.left + (rect.bottom - rect.top); - rcText.top = rect.bottom; - rcText.bottom = rect.top; - dc.DrawText(m_szTitle, -1, &rcText, DT_TOP | DT_SINGLELINE | DT_END_ELLIPSIS); - } - else - { - rect.left += m_cxyTextOffset; - rect.right -= m_cxyTextOffset; - if(m_tb.m_hWnd != NULL) - rect.right -= m_cxToolBar;; - - dc.DrawText(m_szTitle, -1, &rect, DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS); - } - - dc.SelectFont(hFontOld); - } - - // called only if pane is empty - void DrawPane(CDCHandle dc) - { - RECT rect = { 0 }; - GetClientRect(&rect); - if(IsVertical()) - rect.left += m_cxyHeader; - else - rect.top += m_cxyHeader; - if((GetExStyle() & WS_EX_CLIENTEDGE) == 0) - dc.DrawEdge(&rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); - dc.FillRect(&rect, COLOR_APPWORKSPACE); - } - - // drawing helper - draws "x" button image - void DrawButtonImage(CDCHandle dc, RECT& rcImage, HPEN hPen) - { -#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) - HPEN hPenOld = dc.SelectPen(hPen); - - dc.MoveTo(rcImage.left, rcImage.top); - dc.LineTo(rcImage.right, rcImage.bottom); - dc.MoveTo(rcImage.left + 1, rcImage.top); - dc.LineTo(rcImage.right + 1, rcImage.bottom); - - dc.MoveTo(rcImage.left, rcImage.bottom - 1); - dc.LineTo(rcImage.right, rcImage.top - 1); - dc.MoveTo(rcImage.left + 1, rcImage.bottom - 1); - dc.LineTo(rcImage.right + 1, rcImage.top - 1); - - dc.SelectPen(hPenOld); -#else // (_WIN32_WCE < 400) - rcImage; - hPen; - // no support for the "x" button image -#endif // (_WIN32_WCE < 400) - } - - bool IsVertical() const - { - return ((m_dwExtendedStyle & PANECNT_VERTICAL) != 0); - } -}; - -class CPaneContainer : public CPaneContainerImpl -{ -public: - DECLARE_WND_CLASS_EX(_T("WTL_PaneContainer"), 0, -1) -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CSortListViewCtrl - implements sorting for a listview control - -// sort listview extended styles -#define SORTLV_USESHELLBITMAPS 0x00000001 - -// Notification sent to parent when sort column is changed by user clicking header. -#define SLVN_SORTCHANGED LVN_LAST - -// A LPNMSORTLISTVIEW is sent with the SLVN_SORTCHANGED notification -typedef struct tagNMSORTLISTVIEW -{ - NMHDR hdr; - int iNewSortColumn; - int iOldSortColumn; -} NMSORTLISTVIEW, *LPNMSORTLISTVIEW; - -// Column sort types. Can be set on a per-column basis with the SetColumnSortType method. -enum -{ - LVCOLSORT_NONE, - LVCOLSORT_TEXT, // default - LVCOLSORT_TEXTNOCASE, - LVCOLSORT_LONG, - LVCOLSORT_DOUBLE, - LVCOLSORT_DECIMAL, - LVCOLSORT_DATETIME, - LVCOLSORT_DATE, - LVCOLSORT_TIME, - LVCOLSORT_CUSTOM, - LVCOLSORT_LAST = LVCOLSORT_CUSTOM -}; - - -template -class CSortListViewImpl -{ -public: - enum - { - m_cchCmpTextMax = 32, // overrideable - m_cxSortImage = 16, - m_cySortImage = 15, - m_cxSortArrow = 11, - m_cySortArrow = 6, - m_iSortUp = 0, // index of sort bitmaps - m_iSortDown = 1, - m_nShellSortUpID = 133 - }; - - // passed to LVCompare functions as lParam1 and lParam2 - struct LVCompareParam - { - int iItem; - DWORD_PTR dwItemData; - union - { - long lValue; - double dblValue; - DECIMAL decValue; - LPCTSTR pszValue; - }; - }; - - // passed to LVCompare functions as the lParamSort parameter - struct LVSortInfo - { - T* pT; - int iSortCol; - bool bDescending; - }; - - bool m_bSortDescending; - bool m_bCommCtrl6; - int m_iSortColumn; - CBitmap m_bmSort[2]; - int m_fmtOldSortCol; - HBITMAP m_hbmOldSortCol; - DWORD m_dwSortLVExtendedStyle; - ATL::CSimpleArray m_arrColSortType; - bool m_bUseWaitCursor; - - CSortListViewImpl() : - m_bSortDescending(false), - m_bCommCtrl6(false), - m_iSortColumn(-1), - m_fmtOldSortCol(0), - m_hbmOldSortCol(NULL), - m_dwSortLVExtendedStyle(SORTLV_USESHELLBITMAPS), - m_bUseWaitCursor(true) - { -#ifndef _WIN32_WCE - DWORD dwMajor = 0; - DWORD dwMinor = 0; - HRESULT hRet = ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor); - m_bCommCtrl6 = SUCCEEDED(hRet) && dwMajor >= 6; -#endif // !_WIN32_WCE - } - -// Attributes - void SetSortColumn(int iCol) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - CHeaderCtrl header = pT->GetHeader(); - ATLASSERT(header.m_hWnd != NULL); - ATLASSERT(iCol >= -1 && iCol < m_arrColSortType.GetSize()); - - int iOldSortCol = m_iSortColumn; - m_iSortColumn = iCol; - if(m_bCommCtrl6) - { -#ifndef HDF_SORTUP - const int HDF_SORTUP = 0x0400; -#endif // HDF_SORTUP -#ifndef HDF_SORTDOWN - const int HDF_SORTDOWN = 0x0200; -#endif // HDF_SORTDOWN - const int nMask = HDF_SORTUP | HDF_SORTDOWN; - HDITEM hditem = { HDI_FORMAT }; - if(iOldSortCol != iCol && iOldSortCol >= 0 && header.GetItem(iOldSortCol, &hditem)) - { - hditem.fmt &= ~nMask; - header.SetItem(iOldSortCol, &hditem); - } - if(iCol >= 0 && header.GetItem(iCol, &hditem)) - { - hditem.fmt &= ~nMask; - hditem.fmt |= m_bSortDescending ? HDF_SORTDOWN : HDF_SORTUP; - header.SetItem(iCol, &hditem); - } - return; - } - - if(m_bmSort[m_iSortUp].IsNull()) - pT->CreateSortBitmaps(); - - // restore previous sort column's bitmap, if any, and format - HDITEM hditem = { HDI_BITMAP | HDI_FORMAT }; - if(iOldSortCol != iCol && iOldSortCol >= 0) - { - hditem.hbm = m_hbmOldSortCol; - hditem.fmt = m_fmtOldSortCol; - header.SetItem(iOldSortCol, &hditem); - } - - // save new sort column's bitmap and format, and add our sort bitmap - if(iCol >= 0 && header.GetItem(iCol, &hditem)) - { - if(iOldSortCol != iCol) - { - m_fmtOldSortCol = hditem.fmt; - m_hbmOldSortCol = hditem.hbm; - } - hditem.fmt &= ~HDF_IMAGE; - hditem.fmt |= HDF_BITMAP | HDF_BITMAP_ON_RIGHT; - int i = m_bSortDescending ? m_iSortDown : m_iSortUp; - hditem.hbm = m_bmSort[i]; - header.SetItem(iCol, &hditem); - } - } - - int GetSortColumn() const - { - return m_iSortColumn; - } - - void SetColumnSortType(int iCol, WORD wType) - { - ATLASSERT(iCol >= 0 && iCol < m_arrColSortType.GetSize()); - ATLASSERT(wType >= LVCOLSORT_NONE && wType <= LVCOLSORT_LAST); - m_arrColSortType[iCol] = wType; - } - - WORD GetColumnSortType(int iCol) const - { - ATLASSERT((iCol >= 0) && iCol < m_arrColSortType.GetSize()); - return m_arrColSortType[iCol]; - } - - int GetColumnCount() const - { - const T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - CHeaderCtrl header = pT->GetHeader(); - return header.m_hWnd != NULL ? header.GetItemCount() : 0; - } - - bool IsSortDescending() const - { - return m_bSortDescending; - } - - DWORD GetSortListViewExtendedStyle() const - { - return m_dwSortLVExtendedStyle; - } - - DWORD SetSortListViewExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) - { - DWORD dwPrevStyle = m_dwSortLVExtendedStyle; - if(dwMask == 0) - m_dwSortLVExtendedStyle = dwExtendedStyle; - else - m_dwSortLVExtendedStyle = (m_dwSortLVExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); - return dwPrevStyle; - } - -// Operations - bool DoSortItems(int iCol, bool bDescending = false) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - ATLASSERT(iCol >= 0 && iCol < m_arrColSortType.GetSize()); - - WORD wType = m_arrColSortType[iCol]; - if(wType == LVCOLSORT_NONE) - return false; - - int nCount = pT->GetItemCount(); - if(nCount < 2) - { - m_bSortDescending = bDescending; - SetSortColumn(iCol); - return true; - } - - CWaitCursor waitCursor(false); - if(m_bUseWaitCursor) - waitCursor.Set(); - - LVCompareParam* pParam = NULL; - ATLTRY(pParam = new LVCompareParam[nCount]); - PFNLVCOMPARE pFunc = NULL; - TCHAR pszTemp[pT->m_cchCmpTextMax]; - bool bStrValue = false; - - switch(wType) - { - case LVCOLSORT_TEXT: - pFunc = (PFNLVCOMPARE)pT->LVCompareText; - case LVCOLSORT_TEXTNOCASE: - if(pFunc == NULL) - pFunc = (PFNLVCOMPARE)pT->LVCompareTextNoCase; - case LVCOLSORT_CUSTOM: - { - if(pFunc == NULL) - pFunc = (PFNLVCOMPARE)pT->LVCompareCustom; - - for(int i = 0; i < nCount; i++) - { - pParam[i].iItem = i; - pParam[i].dwItemData = pT->GetItemData(i); - pParam[i].pszValue = new TCHAR[pT->m_cchCmpTextMax]; - pT->GetItemText(i, iCol, (LPTSTR)pParam[i].pszValue, pT->m_cchCmpTextMax); - pT->SetItemData(i, (DWORD_PTR)&pParam[i]); - } - bStrValue = true; - } - break; - case LVCOLSORT_LONG: - { - pFunc = (PFNLVCOMPARE)pT->LVCompareLong; - for(int i = 0; i < nCount; i++) - { - pParam[i].iItem = i; - pParam[i].dwItemData = pT->GetItemData(i); - pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax); - pParam[i].lValue = pT->StrToLong(pszTemp); - pT->SetItemData(i, (DWORD_PTR)&pParam[i]); - } - } - break; - case LVCOLSORT_DOUBLE: - { - pFunc = (PFNLVCOMPARE)pT->LVCompareDouble; - for(int i = 0; i < nCount; i++) - { - pParam[i].iItem = i; - pParam[i].dwItemData = pT->GetItemData(i); - pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax); - pParam[i].dblValue = pT->StrToDouble(pszTemp); - pT->SetItemData(i, (DWORD_PTR)&pParam[i]); - } - } - break; - case LVCOLSORT_DECIMAL: - { - pFunc = (PFNLVCOMPARE)pT->LVCompareDecimal; - for(int i = 0; i < nCount; i++) - { - pParam[i].iItem = i; - pParam[i].dwItemData = pT->GetItemData(i); - pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax); - pT->StrToDecimal(pszTemp, &pParam[i].decValue); - pT->SetItemData(i, (DWORD_PTR)&pParam[i]); - } - } - break; - case LVCOLSORT_DATETIME: - case LVCOLSORT_DATE: - case LVCOLSORT_TIME: - { - pFunc = (PFNLVCOMPARE)pT->LVCompareDouble; - DWORD dwFlags = LOCALE_NOUSEROVERRIDE; - if(wType == LVCOLSORT_DATE) - dwFlags |= VAR_DATEVALUEONLY; - else if(wType == LVCOLSORT_TIME) - dwFlags |= VAR_TIMEVALUEONLY; - for(int i = 0; i < nCount; i++) - { - pParam[i].iItem = i; - pParam[i].dwItemData = pT->GetItemData(i); - pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax); - pParam[i].dblValue = pT->DateStrToDouble(pszTemp, dwFlags); - pT->SetItemData(i, (DWORD_PTR)&pParam[i]); - } - } - break; - default: - ATLTRACE2(atlTraceUI, 0, _T("Unknown value for sort type in CSortListViewImpl::DoSortItems()\n")); - break; - } // switch(wType) - - ATLASSERT(pFunc != NULL); - LVSortInfo lvsi = { pT, iCol, bDescending }; - bool bRet = ((BOOL)pT->DefWindowProc(LVM_SORTITEMS, (WPARAM)&lvsi, (LPARAM)pFunc) != FALSE); - for(int i = 0; i < nCount; i++) - { - DWORD_PTR dwItemData = pT->GetItemData(i); - LVCompareParam* p = (LVCompareParam*)dwItemData; - ATLASSERT(p != NULL); - if(bStrValue) - delete [] (TCHAR*)p->pszValue; - pT->SetItemData(i, p->dwItemData); - } - delete [] pParam; - - if(bRet) - { - m_bSortDescending = bDescending; - SetSortColumn(iCol); - } - - if(m_bUseWaitCursor) - waitCursor.Restore(); - - return bRet; - } - - void CreateSortBitmaps() - { - if((m_dwSortLVExtendedStyle & SORTLV_USESHELLBITMAPS) != 0) - { - bool bFree = false; - LPCTSTR pszModule = _T("shell32.dll"); - HINSTANCE hShell = ::GetModuleHandle(pszModule); - - if (hShell == NULL) - { - hShell = ::LoadLibrary(pszModule); - bFree = true; - } - - if (hShell != NULL) - { - bool bSuccess = true; - for(int i = m_iSortUp; i <= m_iSortDown; i++) - { - if(!m_bmSort[i].IsNull()) - m_bmSort[i].DeleteObject(); - m_bmSort[i] = (HBITMAP)::LoadImage(hShell, MAKEINTRESOURCE(m_nShellSortUpID + i), -#ifndef _WIN32_WCE - IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS); -#else // CE specific - IMAGE_BITMAP, 0, 0, 0); -#endif // _WIN32_WCE - if(m_bmSort[i].IsNull()) - { - bSuccess = false; - break; - } - } - if(bFree) - ::FreeLibrary(hShell); - if(bSuccess) - return; - } - } - - T* pT = static_cast(this); - for(int i = m_iSortUp; i <= m_iSortDown; i++) - { - if(!m_bmSort[i].IsNull()) - m_bmSort[i].DeleteObject(); - - CDC dcMem; - CClientDC dc(::GetDesktopWindow()); - dcMem.CreateCompatibleDC(dc.m_hDC); - m_bmSort[i].CreateCompatibleBitmap(dc.m_hDC, m_cxSortImage, m_cySortImage); - HBITMAP hbmOld = dcMem.SelectBitmap(m_bmSort[i]); - RECT rc = {0,0,m_cxSortImage, m_cySortImage}; - pT->DrawSortBitmap(dcMem.m_hDC, i, &rc); - dcMem.SelectBitmap(hbmOld); - dcMem.DeleteDC(); - } - } - - void NotifyParentSortChanged(int iNewSortCol, int iOldSortCol) - { - T* pT = static_cast(this); - int nID = pT->GetDlgCtrlID(); - NMSORTLISTVIEW nm = { { pT->m_hWnd, nID, SLVN_SORTCHANGED }, iNewSortCol, iOldSortCol }; - ::SendMessage(pT->GetParent(), WM_NOTIFY, (WPARAM)nID, (LPARAM)&nm); - } - -// Overrideables - int CompareItemsCustom(LVCompareParam* /*pItem1*/, LVCompareParam* /*pItem2*/, int /*iSortCol*/) - { - // pItem1 and pItem2 contain valid iItem, dwItemData, and pszValue members. - // If item1 > item2 return 1, if item1 < item2 return -1, else return 0. - return 0; - } - - void DrawSortBitmap(CDCHandle dc, int iBitmap, LPRECT prc) - { - dc.FillRect(prc, ::GetSysColorBrush(COLOR_BTNFACE)); - HBRUSH hbrOld = dc.SelectBrush(::GetSysColorBrush(COLOR_BTNSHADOW)); - CPen pen; - pen.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNSHADOW)); - HPEN hpenOld = dc.SelectPen(pen); - POINT ptOrg = { (m_cxSortImage - m_cxSortArrow) / 2, (m_cySortImage - m_cySortArrow) / 2 }; - if(iBitmap == m_iSortUp) - { - POINT pts[3] = - { - { ptOrg.x + m_cxSortArrow / 2, ptOrg.y }, - { ptOrg.x, ptOrg.y + m_cySortArrow - 1 }, - { ptOrg.x + m_cxSortArrow - 1, ptOrg.y + m_cySortArrow - 1 } - }; - dc.Polygon(pts, 3); - } - else - { - POINT pts[3] = - { - { ptOrg.x, ptOrg.y }, - { ptOrg.x + m_cxSortArrow / 2, ptOrg.y + m_cySortArrow - 1 }, - { ptOrg.x + m_cxSortArrow - 1, ptOrg.y } - }; - dc.Polygon(pts, 3); - } - dc.SelectBrush(hbrOld); - dc.SelectPen(hpenOld); - } - - double DateStrToDouble(LPCTSTR lpstr, DWORD dwFlags) - { - ATLASSERT(lpstr != NULL); - if(lpstr == NULL || lpstr[0] == _T('\0')) - return 0; - - USES_CONVERSION; - HRESULT hRet = E_FAIL; - DATE dRet = 0; - if (FAILED(hRet = ::VarDateFromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, dwFlags, &dRet))) - { - ATLTRACE2(atlTraceUI, 0, _T("VarDateFromStr failed with result of 0x%8.8X\n"), hRet); - dRet = 0; - } - return dRet; - } - - long StrToLong(LPCTSTR lpstr) - { - ATLASSERT(lpstr != NULL); - if(lpstr == NULL || lpstr[0] == _T('\0')) - return 0; - - USES_CONVERSION; - HRESULT hRet = E_FAIL; - long lRet = 0; - if (FAILED(hRet = ::VarI4FromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, &lRet))) - { - ATLTRACE2(atlTraceUI, 0, _T("VarI4FromStr failed with result of 0x%8.8X\n"), hRet); - lRet = 0; - } - return lRet; - } - - double StrToDouble(LPCTSTR lpstr) - { - ATLASSERT(lpstr != NULL); - if(lpstr == NULL || lpstr[0] == _T('\0')) - return 0; - - USES_CONVERSION; - HRESULT hRet = E_FAIL; - double dblRet = 0; - if (FAILED(hRet = ::VarR8FromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, &dblRet))) - { - ATLTRACE2(atlTraceUI, 0, _T("VarR8FromStr failed with result of 0x%8.8X\n"), hRet); - dblRet = 0; - } - return dblRet; - } - - bool StrToDecimal(LPCTSTR lpstr, DECIMAL* pDecimal) - { - ATLASSERT(lpstr != NULL); - ATLASSERT(pDecimal != NULL); - if(lpstr == NULL || pDecimal == NULL) - return false; - - USES_CONVERSION; - HRESULT hRet = E_FAIL; - if (FAILED(hRet = ::VarDecFromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, pDecimal))) - { - ATLTRACE2(atlTraceUI, 0, _T("VarDecFromStr failed with result of 0x%8.8X\n"), hRet); - pDecimal->Lo64 = 0; - pDecimal->Hi32 = 0; - pDecimal->signscale = 0; - return false; - } - return true; - } - -// Overrideable PFNLVCOMPARE functions - static int CALLBACK LVCompareText(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) - { - ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); - - LVCompareParam* pParam1 = (LVCompareParam*)lParam1; - LVCompareParam* pParam2 = (LVCompareParam*)lParam2; - LVSortInfo* pInfo = (LVSortInfo*)lParamSort; - - int nRet = lstrcmp(pParam1->pszValue, pParam2->pszValue); - return pInfo->bDescending ? -nRet : nRet; - } - - static int CALLBACK LVCompareTextNoCase(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) - { - ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); - - LVCompareParam* pParam1 = (LVCompareParam*)lParam1; - LVCompareParam* pParam2 = (LVCompareParam*)lParam2; - LVSortInfo* pInfo = (LVSortInfo*)lParamSort; - - int nRet = lstrcmpi(pParam1->pszValue, pParam2->pszValue); - return pInfo->bDescending ? -nRet : nRet; - } - - static int CALLBACK LVCompareLong(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) - { - ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); - - LVCompareParam* pParam1 = (LVCompareParam*)lParam1; - LVCompareParam* pParam2 = (LVCompareParam*)lParam2; - LVSortInfo* pInfo = (LVSortInfo*)lParamSort; - - int nRet = 0; - if(pParam1->lValue > pParam2->lValue) - nRet = 1; - else if(pParam1->lValue < pParam2->lValue) - nRet = -1; - return pInfo->bDescending ? -nRet : nRet; - } - - static int CALLBACK LVCompareDouble(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) - { - ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); - - LVCompareParam* pParam1 = (LVCompareParam*)lParam1; - LVCompareParam* pParam2 = (LVCompareParam*)lParam2; - LVSortInfo* pInfo = (LVSortInfo*)lParamSort; - - int nRet = 0; - if(pParam1->dblValue > pParam2->dblValue) - nRet = 1; - else if(pParam1->dblValue < pParam2->dblValue) - nRet = -1; - return pInfo->bDescending ? -nRet : nRet; - } - - static int CALLBACK LVCompareCustom(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) - { - ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); - - LVCompareParam* pParam1 = (LVCompareParam*)lParam1; - LVCompareParam* pParam2 = (LVCompareParam*)lParam2; - LVSortInfo* pInfo = (LVSortInfo*)lParamSort; - - int nRet = pInfo->pT->CompareItemsCustom(pParam1, pParam2, pInfo->iSortCol); - return pInfo->bDescending ? -nRet : nRet; - } - -#ifndef _WIN32_WCE - static int CALLBACK LVCompareDecimal(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) - { - ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); - - LVCompareParam* pParam1 = (LVCompareParam*)lParam1; - LVCompareParam* pParam2 = (LVCompareParam*)lParam2; - LVSortInfo* pInfo = (LVSortInfo*)lParamSort; - - int nRet = (int)::VarDecCmp(&pParam1->decValue, &pParam2->decValue); - nRet--; - return pInfo->bDescending ? -nRet : nRet; - } -#else - // Compare mantissas, ignore sign and scale - static int CompareMantissas(const DECIMAL& decLeft, const DECIMAL& decRight) - { - if (decLeft.Hi32 < decRight.Hi32) - { - return -1; - } - if (decLeft.Hi32 > decRight.Hi32) - { - return 1; - } - // Here, decLeft.Hi32 == decRight.Hi32 - if (decLeft.Lo64 < decRight.Lo64) - { - return -1; - } - if (decLeft.Lo64 > decRight.Lo64) - { - return 1; - } - return 0; - } - - // return values: VARCMP_LT, VARCMP_EQ, VARCMP_GT, VARCMP_NULL - static HRESULT VarDecCmp(const DECIMAL* pdecLeft, const DECIMAL* pdecRight) - { - static const ULONG powersOfTen[] = - { - 10ul, - 100ul, - 1000ul, - 10000ul, - 100000ul, - 1000000ul, - 10000000ul, - 100000000ul, - 1000000000ul - }; - static const int largestPower = sizeof(powersOfTen) / sizeof(powersOfTen[0]); - if (!pdecLeft || !pdecRight) - { - return VARCMP_NULL; - } - - // Degenerate case - at least one comparand is of the form - // [+-]0*10^N (denormalized zero) - bool bLeftZero = (!pdecLeft->Lo64 && !pdecLeft->Hi32); - bool bRightZero = (!pdecRight->Lo64 && !pdecRight->Hi32); - if (bLeftZero && bRightZero) - { - return VARCMP_EQ; - } - bool bLeftNeg = ((pdecLeft->sign & DECIMAL_NEG) != 0); - bool bRightNeg = ((pdecRight->sign & DECIMAL_NEG) != 0); - if (bLeftZero) - { - return (bRightNeg ? VARCMP_GT : VARCMP_LT); - } - // This also covers the case where the comparands have different signs - if (bRightZero || bLeftNeg != bRightNeg) - { - return (bLeftNeg ? VARCMP_LT : VARCMP_GT); - } - - // Here both comparands have the same sign and need to be compared - // on mantissa and scale. The result is obvious when - // 1. Scales are equal (then compare mantissas) - // 2. A number with smaller scale is also the one with larger mantissa - // (then this number is obviously larger) - // In the remaining case, we would multiply the number with smaller - // scale by 10 and simultaneously increment its scale (which amounts to - // adding trailing zeros after decimal point), until the numbers fall under - // one of the two cases above - DECIMAL temp; - bool bInvert = bLeftNeg; // the final result needs to be inverted - if (pdecLeft->scale < pdecRight->scale) - { - temp = *pdecLeft; - } - else - { - temp = *pdecRight; - pdecRight = pdecLeft; - bInvert = !bInvert; - } - - // Now temp is the number with smaller (or equal) scale, and - // we can modify it freely without touching original parameters - int comp; - while ((comp = CompareMantissas(temp, *pdecRight)) < 0 && - temp.scale < pdecRight->scale) - { - // Multiply by an appropriate power of 10 - int scaleDiff = pdecRight->scale - temp.scale; - if (scaleDiff > largestPower) - { - // Keep the multiplier representable in 32bit - scaleDiff = largestPower; - } - DWORDLONG power = powersOfTen[scaleDiff - 1]; - // Multiply temp's mantissa by power - DWORDLONG product = temp.Lo32 * power; - ULONG carry = static_cast(product >> 32); - temp.Lo32 = static_cast(product); - product = temp.Mid32 * power + carry; - carry = static_cast(product >> 32); - temp.Mid32 = static_cast(product); - product = temp.Hi32 * power + carry; - if (static_cast(product >> 32)) - { - // Multiplication overflowed - pdecLeft is clearly larger - break; - } - temp.Hi32 = static_cast(product); - temp.scale = (BYTE)(temp.scale + scaleDiff); - } - if (temp.scale < pdecRight->scale) - { - comp = 1; - } - if (bInvert) - { - comp = -comp; - } - return (comp > 0 ? VARCMP_GT : comp < 0 ? VARCMP_LT : VARCMP_EQ); - } - - static int CALLBACK LVCompareDecimal(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) - { - ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); - - LVCompareParam* pParam1 = (LVCompareParam*)lParam1; - LVCompareParam* pParam2 = (LVCompareParam*)lParam2; - LVSortInfo* pInfo = (LVSortInfo*)lParamSort; - - int nRet = (int)VarDecCmp(&pParam1->decValue, &pParam2->decValue); - nRet--; - return pInfo->bDescending ? -nRet : nRet; - } -#endif // !_WIN32_WCE - - BEGIN_MSG_MAP(CSortListViewImpl) - MESSAGE_HANDLER(LVM_INSERTCOLUMN, OnInsertColumn) - MESSAGE_HANDLER(LVM_DELETECOLUMN, OnDeleteColumn) - NOTIFY_CODE_HANDLER(HDN_ITEMCLICKA, OnHeaderItemClick) - NOTIFY_CODE_HANDLER(HDN_ITEMCLICKW, OnHeaderItemClick) - MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) - END_MSG_MAP() - - LRESULT OnInsertColumn(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - LRESULT lRet = pT->DefWindowProc(uMsg, wParam, lParam); - if(lRet == -1) - return -1; - - WORD wType = 0; - m_arrColSortType.Add(wType); - int nCount = m_arrColSortType.GetSize(); - ATLASSERT(nCount == GetColumnCount()); - - for(int i = nCount - 1; i > lRet; i--) - m_arrColSortType[i] = m_arrColSortType[i - 1]; - m_arrColSortType[(int)lRet] = LVCOLSORT_TEXT; - - if(lRet <= m_iSortColumn) - m_iSortColumn++; - - return lRet; - } - - LRESULT OnDeleteColumn(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - LRESULT lRet = pT->DefWindowProc(uMsg, wParam, lParam); - if(lRet == 0) - return 0; - - int iCol = (int)wParam; - if(m_iSortColumn == iCol) - m_iSortColumn = -1; - else if(m_iSortColumn > iCol) - m_iSortColumn--; - m_arrColSortType.RemoveAt(iCol); - - return lRet; - } - - LRESULT OnHeaderItemClick(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) - { - LPNMHEADER p = (LPNMHEADER)pnmh; - if(p->iButton == 0) - { - int iOld = m_iSortColumn; - bool bDescending = (m_iSortColumn == p->iItem) ? !m_bSortDescending : false; - if(DoSortItems(p->iItem, bDescending)) - NotifyParentSortChanged(p->iItem, iOld); - } - bHandled = FALSE; - return 0; - } - - LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { -#ifndef _WIN32_WCE - if(wParam == SPI_SETNONCLIENTMETRICS) - GetSystemSettings(); -#else // CE specific - wParam; // avoid level 4 warning - GetSystemSettings(); -#endif // _WIN32_WCE - bHandled = FALSE; - return 0; - } - - void GetSystemSettings() - { - if(!m_bCommCtrl6 && !m_bmSort[m_iSortUp].IsNull()) - { - T* pT = static_cast(this); - pT->CreateSortBitmaps(); - if(m_iSortColumn != -1) - SetSortColumn(m_iSortColumn); - } - } - -}; - - -typedef ATL::CWinTraits CSortListViewCtrlTraits; - -template -class ATL_NO_VTABLE CSortListViewCtrlImpl: public ATL::CWindowImpl, public CSortListViewImpl -{ -public: - DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName()) - - bool SortItems(int iCol, bool bDescending = false) - { - return DoSortItems(iCol, bDescending); - } - - BEGIN_MSG_MAP(CSortListViewCtrlImpl) - MESSAGE_HANDLER(LVM_INSERTCOLUMN, CSortListViewImpl::OnInsertColumn) - MESSAGE_HANDLER(LVM_DELETECOLUMN, CSortListViewImpl::OnDeleteColumn) - NOTIFY_CODE_HANDLER(HDN_ITEMCLICKA, CSortListViewImpl::OnHeaderItemClick) - NOTIFY_CODE_HANDLER(HDN_ITEMCLICKW, CSortListViewImpl::OnHeaderItemClick) - MESSAGE_HANDLER(WM_SETTINGCHANGE, CSortListViewImpl::OnSettingChange) - END_MSG_MAP() -}; - -class CSortListViewCtrl : public CSortListViewCtrlImpl -{ -public: - DECLARE_WND_SUPERCLASS(_T("WTL_SortListViewCtrl"), GetWndClassName()) -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CTabView - implements tab view window - -// TabView Notifications -#define TBVN_PAGEACTIVATED (0U-741) -#define TBVN_CONTEXTMENU (0U-742) - -// Notification data for TBVN_CONTEXTMENU -struct TBVCONTEXTMENUINFO -{ - NMHDR hdr; - POINT pt; -}; - -typedef TBVCONTEXTMENUINFO* LPTBVCONTEXTMENUINFO; - - -template -class ATL_NO_VTABLE CTabViewImpl : public ATL::CWindowImpl -{ -public: - DECLARE_WND_CLASS_EX(NULL, 0, COLOR_APPWORKSPACE) - -// Declarations and enums - struct TABVIEWPAGE - { - HWND hWnd; - LPTSTR lpstrTitle; - LPVOID pData; - }; - - struct TCITEMEXTRA - { - TCITEMHEADER tciheader; - TABVIEWPAGE tvpage; - - operator LPTCITEM() { return (LPTCITEM)this; } - }; - - enum - { - m_nTabID = 1313, - m_cxMoveMark = 6, - m_cyMoveMark = 3, - m_nMenuItemsMax = (ID_WINDOW_TABLAST - ID_WINDOW_TABFIRST + 1) - }; - -// Data members - ATL::CContainedWindowT m_tab; - int m_cyTabHeight; - - int m_nActivePage; - - int m_nInsertItem; - POINT m_ptStartDrag; - - CMenuHandle m_menu; - - int m_cchTabTextLength; - - int m_nMenuItemsCount; - - ATL::CWindow m_wndTitleBar; - LPTSTR m_lpstrTitleBarBase; - int m_cchTitleBarLength; - - CImageList m_ilDrag; - - bool m_bDestroyPageOnRemove:1; - bool m_bDestroyImageList:1; - bool m_bActivePageMenuItem:1; - bool m_bActiveAsDefaultMenuItem:1; - bool m_bEmptyMenuItem:1; - bool m_bWindowsMenuItem:1; - bool m_bNoTabDrag:1; - // internal - bool m_bTabCapture:1; - bool m_bTabDrag:1; - bool m_bInternalFont:1; - -// Constructor/destructor - CTabViewImpl() : - m_nActivePage(-1), - m_cyTabHeight(0), - m_tab(this, 1), - m_nInsertItem(-1), - m_cchTabTextLength(30), - m_nMenuItemsCount(10), - m_lpstrTitleBarBase(NULL), - m_cchTitleBarLength(100), - m_bDestroyPageOnRemove(true), - m_bDestroyImageList(true), - m_bActivePageMenuItem(true), - m_bActiveAsDefaultMenuItem(false), - m_bEmptyMenuItem(false), - m_bWindowsMenuItem(false), - m_bNoTabDrag(false), - m_bTabCapture(false), - m_bTabDrag(false), - m_bInternalFont(false) - { - m_ptStartDrag.x = 0; - m_ptStartDrag.y = 0; - } - - ~CTabViewImpl() - { - delete [] m_lpstrTitleBarBase; - } - -// Message filter function - to be called from PreTranslateMessage of the main window - BOOL PreTranslateMessage(MSG* pMsg) - { - if(IsWindow() == FALSE) - return FALSE; - - BOOL bRet = FALSE; - - // Check for TabView built-in accelerators (Ctrl+Tab/Ctrl+Shift+Tab - next/previous page) - int nCount = GetPageCount(); - if(nCount > 0) - { - bool bControl = (::GetKeyState(VK_CONTROL) < 0); - if((pMsg->message == WM_KEYDOWN) && (pMsg->wParam == VK_TAB) && bControl) - { - if(nCount > 1) - { - int nPage = m_nActivePage; - bool bShift = (::GetKeyState(VK_SHIFT) < 0); - if(bShift) - nPage = (nPage > 0) ? (nPage - 1) : (nCount - 1); - else - nPage = ((nPage >= 0) && (nPage < (nCount - 1))) ? (nPage + 1) : 0; - - SetActivePage(nPage); - T* pT = static_cast(this); - pT->OnPageActivated(m_nActivePage); - } - - bRet = TRUE; - } - } - - // If we are doing drag-drop, check for Escape key that cancels it - if(bRet == FALSE) - { - if(m_bTabCapture && pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) - { - ::ReleaseCapture(); - bRet = TRUE; - } - } - - // Pass the message to the active page - if(bRet == FALSE) - { - if(m_nActivePage != -1) - bRet = (BOOL)::SendMessage(GetPageHWND(m_nActivePage), WM_FORWARDMSG, 0, (LPARAM)pMsg); - } - - return bRet; - } - -// Attributes - int GetPageCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return m_tab.GetItemCount(); - } - - int GetActivePage() const - { - return m_nActivePage; - } - - void SetActivePage(int nPage) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(IsValidPageIndex(nPage)); - - T* pT = static_cast(this); - - SetRedraw(FALSE); - - if(m_nActivePage != -1) - ::ShowWindow(GetPageHWND(m_nActivePage), FALSE); - m_nActivePage = nPage; - m_tab.SetCurSel(m_nActivePage); - ::ShowWindow(GetPageHWND(m_nActivePage), TRUE); - - pT->UpdateLayout(); - - SetRedraw(TRUE); - RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); - - if(::GetFocus() != m_tab.m_hWnd) - ::SetFocus(GetPageHWND(m_nActivePage)); - - pT->UpdateTitleBar(); - pT->UpdateMenu(); - } - - HIMAGELIST GetImageList() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return m_tab.GetImageList(); - } - - HIMAGELIST SetImageList(HIMAGELIST hImageList) - { - ATLASSERT(::IsWindow(m_hWnd)); - return m_tab.SetImageList(hImageList); - } - - void SetWindowMenu(HMENU hMenu) - { - ATLASSERT(::IsWindow(m_hWnd)); - - m_menu = hMenu; - - T* pT = static_cast(this); - pT->UpdateMenu(); - } - - void SetTitleBarWindow(HWND hWnd) - { - ATLASSERT(::IsWindow(m_hWnd)); - - delete [] m_lpstrTitleBarBase; - m_lpstrTitleBarBase = NULL; - - m_wndTitleBar = hWnd; - if(hWnd == NULL) - return; - - int cchLen = m_wndTitleBar.GetWindowTextLength() + 1; - ATLTRY(m_lpstrTitleBarBase = new TCHAR[cchLen]); - if(m_lpstrTitleBarBase != NULL) - { - m_wndTitleBar.GetWindowText(m_lpstrTitleBarBase, cchLen); - T* pT = static_cast(this); - pT->UpdateTitleBar(); - } - } - -// Page attributes - HWND GetPageHWND(int nPage) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(IsValidPageIndex(nPage)); - - TCITEMEXTRA tcix = { 0 }; - tcix.tciheader.mask = TCIF_PARAM; - m_tab.GetItem(nPage, tcix); - - return tcix.tvpage.hWnd; - } - - LPCTSTR GetPageTitle(int nPage) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(IsValidPageIndex(nPage)); - - TCITEMEXTRA tcix = { 0 }; - tcix.tciheader.mask = TCIF_PARAM; - if(m_tab.GetItem(nPage, tcix) == FALSE) - return NULL; - - return tcix.tvpage.lpstrTitle; - } - - bool SetPageTitle(int nPage, LPCTSTR lpstrTitle) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(IsValidPageIndex(nPage)); - - T* pT = static_cast(this); - - int cchBuff = lstrlen(lpstrTitle) + 1; - LPTSTR lpstrBuff = NULL; - ATLTRY(lpstrBuff = new TCHAR[cchBuff]); - if(lpstrBuff == NULL) - return false; - - SecureHelper::strcpy_x(lpstrBuff, cchBuff, lpstrTitle); - TCITEMEXTRA tcix = { 0 }; - tcix.tciheader.mask = TCIF_PARAM; - if(m_tab.GetItem(nPage, tcix) == FALSE) - return false; - - CTempBuffer buff; - LPTSTR lpstrTabText = buff.Allocate(m_cchTabTextLength + 1); - if(lpstrTabText == NULL) - return false; - - delete [] tcix.tvpage.lpstrTitle; - - pT->ShortenTitle(lpstrTitle, lpstrTabText, m_cchTabTextLength + 1); - - tcix.tciheader.mask = TCIF_TEXT | TCIF_PARAM; - tcix.tciheader.pszText = lpstrTabText; - tcix.tvpage.lpstrTitle = lpstrBuff; - if(m_tab.SetItem(nPage, tcix) == FALSE) - return false; - - pT->UpdateTitleBar(); - pT->UpdateMenu(); - - return true; - } - - LPVOID GetPageData(int nPage) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(IsValidPageIndex(nPage)); - - TCITEMEXTRA tcix = { 0 }; - tcix.tciheader.mask = TCIF_PARAM; - m_tab.GetItem(nPage, tcix); - - return tcix.tvpage.pData; - } - - LPVOID SetPageData(int nPage, LPVOID pData) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(IsValidPageIndex(nPage)); - - TCITEMEXTRA tcix = { 0 }; - tcix.tciheader.mask = TCIF_PARAM; - m_tab.GetItem(nPage, tcix); - LPVOID pDataOld = tcix.tvpage.pData; - - tcix.tvpage.pData = pData; - m_tab.SetItem(nPage, tcix); - - return pDataOld; - } - - int GetPageImage(int nPage) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(IsValidPageIndex(nPage)); - - TCITEMEXTRA tcix = { 0 }; - tcix.tciheader.mask = TCIF_IMAGE; - m_tab.GetItem(nPage, tcix); - - return tcix.tciheader.iImage; - } - - int SetPageImage(int nPage, int nImage) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(IsValidPageIndex(nPage)); - - TCITEMEXTRA tcix = { 0 }; - tcix.tciheader.mask = TCIF_IMAGE; - m_tab.GetItem(nPage, tcix); - int nImageOld = tcix.tciheader.iImage; - - tcix.tciheader.iImage = nImage; - m_tab.SetItem(nPage, tcix); - - return nImageOld; - } - -// Operations - bool AddPage(HWND hWndView, LPCTSTR lpstrTitle, int nImage = -1, LPVOID pData = NULL) - { - return InsertPage(GetPageCount(), hWndView, lpstrTitle, nImage, pData); - } - - bool InsertPage(int nPage, HWND hWndView, LPCTSTR lpstrTitle, int nImage = -1, LPVOID pData = NULL) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(nPage == GetPageCount() || IsValidPageIndex(nPage)); - - T* pT = static_cast(this); - - int cchBuff = lstrlen(lpstrTitle) + 1; - LPTSTR lpstrBuff = NULL; - ATLTRY(lpstrBuff = new TCHAR[cchBuff]); - if(lpstrBuff == NULL) - return false; - - SecureHelper::strcpy_x(lpstrBuff, cchBuff, lpstrTitle); - - CTempBuffer buff; - LPTSTR lpstrTabText = buff.Allocate(m_cchTabTextLength + 1); - if(lpstrTabText == NULL) - return false; - - pT->ShortenTitle(lpstrTitle, lpstrTabText, m_cchTabTextLength + 1); - - SetRedraw(FALSE); - - TCITEMEXTRA tcix = { 0 }; - tcix.tciheader.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM; - tcix.tciheader.pszText = lpstrTabText; - tcix.tciheader.iImage = nImage; - tcix.tvpage.hWnd = hWndView; - tcix.tvpage.lpstrTitle = lpstrBuff; - tcix.tvpage.pData = pData; - int nItem = m_tab.InsertItem(nPage, tcix); - if(nItem == -1) - { - delete [] lpstrBuff; - SetRedraw(TRUE); - return false; - } - - SetActivePage(nItem); - pT->OnPageActivated(m_nActivePage); - - if(GetPageCount() == 1) - pT->ShowTabControl(true); - - pT->UpdateLayout(); - - SetRedraw(TRUE); - RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); - - return true; - } - - void RemovePage(int nPage) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(IsValidPageIndex(nPage)); - - T* pT = static_cast(this); - - SetRedraw(FALSE); - - if(GetPageCount() == 1) - pT->ShowTabControl(false); - - if(m_bDestroyPageOnRemove) - ::DestroyWindow(GetPageHWND(nPage)); - else - ::ShowWindow(GetPageHWND(nPage), FALSE); - LPTSTR lpstrTitle = (LPTSTR)GetPageTitle(nPage); - delete [] lpstrTitle; - - ATLVERIFY(m_tab.DeleteItem(nPage) != FALSE); - - if(m_nActivePage == nPage) - { - m_nActivePage = -1; - - if(nPage > 0) - { - SetActivePage(nPage - 1); - } - else if(GetPageCount() > 0) - { - SetActivePage(nPage); - } - else - { - SetRedraw(TRUE); - Invalidate(); - UpdateWindow(); - pT->UpdateTitleBar(); - pT->UpdateMenu(); - } - } - else - { - nPage = (nPage < m_nActivePage) ? (m_nActivePage - 1) : m_nActivePage; - m_nActivePage = -1; - SetActivePage(nPage); - } - - pT->OnPageActivated(m_nActivePage); - } - - void RemoveAllPages() - { - ATLASSERT(::IsWindow(m_hWnd)); - - if(GetPageCount() == 0) - return; - - T* pT = static_cast(this); - - SetRedraw(FALSE); - - pT->ShowTabControl(false); - - for(int i = 0; i < GetPageCount(); i++) - { - if(m_bDestroyPageOnRemove) - ::DestroyWindow(GetPageHWND(i)); - else - ::ShowWindow(GetPageHWND(i), FALSE); - LPTSTR lpstrTitle = (LPTSTR)GetPageTitle(i); - delete [] lpstrTitle; - } - m_tab.DeleteAllItems(); - - m_nActivePage = -1; - pT->OnPageActivated(m_nActivePage); - - SetRedraw(TRUE); - Invalidate(); - UpdateWindow(); - - pT->UpdateTitleBar(); - pT->UpdateMenu(); - } - - int PageIndexFromHwnd(HWND hWnd) const - { - int nIndex = -1; - - for(int i = 0; i < GetPageCount(); i++) - { - if(GetPageHWND(i) == hWnd) - { - nIndex = i; - break; - } - } - - return nIndex; - } - - void BuildWindowMenu(HMENU hMenu, int nMenuItemsCount = 10, bool bEmptyMenuItem = true, bool bWindowsMenuItem = true, bool bActivePageMenuItem = true, bool bActiveAsDefaultMenuItem = false) - { - ATLASSERT(::IsWindow(m_hWnd)); - - CMenuHandle menu = hMenu; - T* pT = static_cast(this); - pT; // avoid level 4 warning - int nFirstPos = 0; - - // Find first menu item in our range -#ifndef _WIN32_WCE - for(nFirstPos = 0; nFirstPos < menu.GetMenuItemCount(); nFirstPos++) - { - UINT nID = menu.GetMenuItemID(nFirstPos); - if((nID >= ID_WINDOW_TABFIRST && nID <= ID_WINDOW_TABLAST) || nID == ID_WINDOW_SHOWTABLIST) - break; - } -#else // CE specific - for(nFirstPos = 0; ; nFirstPos++) - { - CMenuItemInfo mii; - mii.fMask = MIIM_ID; - BOOL bRet = menu.GetMenuItemInfo(nFirstPos, TRUE, &mii); - if(bRet == FALSE) - break; - if((mii.wID >= ID_WINDOW_TABFIRST && mii.wID <= ID_WINDOW_TABLAST) || mii.wID == ID_WINDOW_SHOWTABLIST) - break; - } -#endif // _WIN32_WCE - - // Remove all menu items for tab pages - BOOL bRet = TRUE; - while(bRet != FALSE) - bRet = menu.DeleteMenu(nFirstPos, MF_BYPOSITION); - - // Add separator if it's not already there - int nPageCount = GetPageCount(); - if((bWindowsMenuItem || (nPageCount > 0)) && (nFirstPos > 0)) - { - CMenuItemInfo mii; - mii.fMask = MIIM_TYPE; - menu.GetMenuItemInfo(nFirstPos - 1, TRUE, &mii); - if((nFirstPos <= 0) || ((mii.fType & MFT_SEPARATOR) == 0)) - { - menu.AppendMenu(MF_SEPARATOR); - nFirstPos++; - } - } - - // Add menu items for all pages - if(nPageCount > 0) - { - // Append menu items for all pages - const int cchPrefix = 3; // 2 digits + space - nMenuItemsCount = min(min(nPageCount, nMenuItemsCount), (int)m_nMenuItemsMax); - ATLASSERT(nMenuItemsCount < 100); // 2 digits only - if(nMenuItemsCount >= 100) - nMenuItemsCount = 99; - - for(int i = 0; i < nMenuItemsCount; i++) - { - LPCTSTR lpstrTitle = GetPageTitle(i); - int nLen = lstrlen(lpstrTitle); - CTempBuffer buff; - LPTSTR lpstrText = buff.Allocate(cchPrefix + nLen + 1); - ATLASSERT(lpstrText != NULL); - if(lpstrText != NULL) - { - LPCTSTR lpstrFormat = (i < 9) ? _T("&%i %s") : _T("%i %s"); - SecureHelper::wsprintf_x(lpstrText, cchPrefix + nLen + 1, lpstrFormat, i + 1, lpstrTitle); - menu.AppendMenu(MF_STRING, ID_WINDOW_TABFIRST + i, lpstrText); - } - } - - // Mark active page - if(bActivePageMenuItem && (m_nActivePage != -1)) - { -#ifndef _WIN32_WCE - if(bActiveAsDefaultMenuItem) - { - menu.SetMenuDefaultItem((UINT)-1, TRUE); - menu.SetMenuDefaultItem(nFirstPos + m_nActivePage, TRUE); - } - else -#else // CE specific - bActiveAsDefaultMenuItem; // avoid level 4 warning -#endif // _WIN32_WCE - { - menu.CheckMenuRadioItem(nFirstPos, nFirstPos + nMenuItemsCount, nFirstPos + m_nActivePage, MF_BYPOSITION); - } - } - } - else - { - if(bEmptyMenuItem) - { - menu.AppendMenu(MF_BYPOSITION | MF_STRING, ID_WINDOW_TABFIRST, pT->GetEmptyListText()); - menu.EnableMenuItem(ID_WINDOW_TABFIRST, MF_GRAYED); - } - - // Remove separator if nothing else is there - if(!bEmptyMenuItem && !bWindowsMenuItem && (nFirstPos > 0)) - { - CMenuItemInfo mii; - mii.fMask = MIIM_TYPE; - menu.GetMenuItemInfo(nFirstPos - 1, TRUE, &mii); - if((mii.fType & MFT_SEPARATOR) != 0) - menu.DeleteMenu(nFirstPos - 1, MF_BYPOSITION); - } - } - - // Add "Windows..." menu item - if(bWindowsMenuItem) - menu.AppendMenu(MF_BYPOSITION | MF_STRING, ID_WINDOW_SHOWTABLIST, pT->GetWindowsMenuItemText()); - } - -// Message map and handlers - BEGIN_MSG_MAP(CTabViewImpl) - MESSAGE_HANDLER(WM_CREATE, OnCreate) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) - MESSAGE_HANDLER(WM_SIZE, OnSize) - MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) - MESSAGE_HANDLER(WM_GETFONT, OnGetFont) - MESSAGE_HANDLER(WM_SETFONT, OnSetFont) - NOTIFY_HANDLER(m_nTabID, TCN_SELCHANGE, OnTabChanged) - NOTIFY_ID_HANDLER(m_nTabID, OnTabNotification) -#ifndef _WIN32_WCE - NOTIFY_CODE_HANDLER(TTN_GETDISPINFO, OnTabGetDispInfo) -#endif // !_WIN32_WCE - FORWARD_NOTIFICATIONS() - ALT_MSG_MAP(1) // tab control - MESSAGE_HANDLER(WM_LBUTTONDOWN, OnTabLButtonDown) - MESSAGE_HANDLER(WM_LBUTTONUP, OnTabLButtonUp) - MESSAGE_HANDLER(WM_CAPTURECHANGED, OnTabCaptureChanged) - MESSAGE_HANDLER(WM_MOUSEMOVE, OnTabMouseMove) - MESSAGE_HANDLER(WM_RBUTTONUP, OnTabRButtonUp) - MESSAGE_HANDLER(WM_SYSKEYDOWN, OnTabSysKeyDown) - END_MSG_MAP() - - LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->CreateTabControl(); - - return 0; - } - - LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - RemoveAllPages(); - - if(m_bDestroyImageList) - { - CImageList il = m_tab.SetImageList(NULL); - if(il.m_hImageList != NULL) - il.Destroy(); - } - - if(m_bInternalFont) - { - HFONT hFont = m_tab.GetFont(); - m_tab.SetFont(NULL, FALSE); - ::DeleteObject(hFont); - m_bInternalFont = false; - } - - return 0; - } - - LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->UpdateLayout(); - return 0; - } - - LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - if(m_nActivePage != -1) - ::SetFocus(GetPageHWND(m_nActivePage)); - return 0; - } - - LRESULT OnGetFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - return m_tab.SendMessage(WM_GETFONT); - } - - LRESULT OnSetFont(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - if(m_bInternalFont) - { - HFONT hFont = m_tab.GetFont(); - m_tab.SetFont(NULL, FALSE); - ::DeleteObject(hFont); - m_bInternalFont = false; - } - - m_tab.SendMessage(WM_SETFONT, wParam, lParam); - - T* pT = static_cast(this); - m_cyTabHeight = pT->CalcTabHeight(); - - if((BOOL)lParam != FALSE) - pT->UpdateLayout(); - - return 0; - } - - LRESULT OnTabChanged(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) - { - SetActivePage(m_tab.GetCurSel()); - T* pT = static_cast(this); - pT->OnPageActivated(m_nActivePage); - - return 0; - } - - LRESULT OnTabNotification(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) - { - // nothing to do - this just blocks all tab control - // notifications from being propagated further - return 0; - } - -#ifndef _WIN32_WCE - LRESULT OnTabGetDispInfo(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) - { - LPNMTTDISPINFO pTTDI = (LPNMTTDISPINFO)pnmh; - if(pTTDI->hdr.hwndFrom == m_tab.GetTooltips()) - { - T* pT = static_cast(this); - pT->UpdateTooltipText(pTTDI); - } - else - { - bHandled = FALSE; - } - - return 0; - } -#endif // !_WIN32_WCE - -// Tab control message handlers - LRESULT OnTabLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - if(!m_bNoTabDrag && (m_tab.GetItemCount() > 1)) - { - m_bTabCapture = true; - m_tab.SetCapture(); - - m_ptStartDrag.x = GET_X_LPARAM(lParam); - m_ptStartDrag.y = GET_Y_LPARAM(lParam); - } - - bHandled = FALSE; - return 0; - } - - LRESULT OnTabLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - if(m_bTabCapture) - { - if(m_bTabDrag) - { - TCHITTESTINFO hti = { 0 }; - hti.pt.x = GET_X_LPARAM(lParam); - hti.pt.y = GET_Y_LPARAM(lParam); - int nItem = m_tab.HitTest(&hti); - if(nItem != -1) - MovePage(m_nActivePage, nItem); - } - - ::ReleaseCapture(); - } - - bHandled = FALSE; - return 0; - } - - LRESULT OnTabCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - if(m_bTabCapture) - { - m_bTabCapture = false; - - if(m_bTabDrag) - { - m_bTabDrag = false; - T* pT = static_cast(this); - pT->DrawMoveMark(-1); - -#ifndef _WIN32_WCE - m_ilDrag.DragLeave(GetDesktopWindow()); -#endif // !_WIN32_WCE - m_ilDrag.EndDrag(); - - m_ilDrag.Destroy(); - m_ilDrag.m_hImageList = NULL; - } - } - - bHandled = FALSE; - return 0; - } - - LRESULT OnTabMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - bHandled = FALSE; - - if(m_bTabCapture) - { - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - - if(!m_bTabDrag) - { -#ifndef _WIN32_WCE - if(abs(m_ptStartDrag.x - GET_X_LPARAM(lParam)) >= ::GetSystemMetrics(SM_CXDRAG) || - abs(m_ptStartDrag.y - GET_Y_LPARAM(lParam)) >= ::GetSystemMetrics(SM_CYDRAG)) -#else // CE specific - if(abs(m_ptStartDrag.x - GET_X_LPARAM(lParam)) >= 4 || - abs(m_ptStartDrag.y - GET_Y_LPARAM(lParam)) >= 4) -#endif // _WIN32_WCE - { - T* pT = static_cast(this); - pT->GenerateDragImage(m_nActivePage); - - int cxCursor = ::GetSystemMetrics(SM_CXCURSOR); - int cyCursor = ::GetSystemMetrics(SM_CYCURSOR); - m_ilDrag.BeginDrag(0, -(cxCursor / 2), -(cyCursor / 2)); -#ifndef _WIN32_WCE - POINT ptEnter = m_ptStartDrag; - m_tab.ClientToScreen(&ptEnter); - m_ilDrag.DragEnter(GetDesktopWindow(), ptEnter); -#endif // !_WIN32_WCE - - m_bTabDrag = true; - } - } - - if(m_bTabDrag) - { - TCHITTESTINFO hti = { 0 }; - hti.pt = pt; - int nItem = m_tab.HitTest(&hti); - - T* pT = static_cast(this); - pT->SetMoveCursor(nItem != -1); - - if(m_nInsertItem != nItem) - pT->DrawMoveMark(nItem); - - m_ilDrag.DragShowNolock((nItem != -1) ? TRUE : FALSE); - m_tab.ClientToScreen(&pt); - m_ilDrag.DragMove(pt); - - bHandled = TRUE; - } - } - - return 0; - } - - LRESULT OnTabRButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) - { - TCHITTESTINFO hti = { 0 }; - hti.pt.x = GET_X_LPARAM(lParam); - hti.pt.y = GET_Y_LPARAM(lParam); - int nItem = m_tab.HitTest(&hti); - if(nItem != -1) - { - T* pT = static_cast(this); - pT->OnContextMenu(nItem, hti.pt); - } - - return 0; - } - - LRESULT OnTabSysKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - bool bShift = (::GetKeyState(VK_SHIFT) < 0); - if(wParam == VK_F10 && bShift) - { - if(m_nActivePage != -1) - { - RECT rect = { 0 }; - m_tab.GetItemRect(m_nActivePage, &rect); - POINT pt = { rect.left, rect.bottom }; - T* pT = static_cast(this); - pT->OnContextMenu(m_nActivePage, pt); - } - } - else - { - bHandled = FALSE; - } - - return 0; - } - -// Implementation helpers - bool IsValidPageIndex(int nPage) const - { - return (nPage >= 0 && nPage < GetPageCount()); - } - - bool MovePage(int nMovePage, int nInsertBeforePage) - { - ATLASSERT(IsValidPageIndex(nMovePage)); - ATLASSERT(IsValidPageIndex(nInsertBeforePage)); - - if(!IsValidPageIndex(nMovePage) || !IsValidPageIndex(nInsertBeforePage)) - return false; - - if(nMovePage == nInsertBeforePage) - return true; // nothing to do - - CTempBuffer buff; - LPTSTR lpstrTabText = buff.Allocate(m_cchTabTextLength + 1); - if(lpstrTabText == NULL) - return false; - TCITEMEXTRA tcix = { 0 }; - tcix.tciheader.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM; - tcix.tciheader.pszText = lpstrTabText; - tcix.tciheader.cchTextMax = m_cchTabTextLength + 1; - BOOL bRet = m_tab.GetItem(nMovePage, tcix); - ATLASSERT(bRet != FALSE); - if(bRet == FALSE) - return false; - - int nInsertItem = (nInsertBeforePage > nMovePage) ? nInsertBeforePage + 1 : nInsertBeforePage; - int nNewItem = m_tab.InsertItem(nInsertItem, tcix); - ATLASSERT(nNewItem == nInsertItem); - if(nNewItem != nInsertItem) - { - ATLVERIFY(m_tab.DeleteItem(nNewItem)); - return false; - } - - if(nMovePage > nInsertBeforePage) - ATLVERIFY(m_tab.DeleteItem(nMovePage + 1) != FALSE); - else if(nMovePage < nInsertBeforePage) - ATLVERIFY(m_tab.DeleteItem(nMovePage) != FALSE); - - SetActivePage(nInsertBeforePage); - T* pT = static_cast(this); - pT->OnPageActivated(m_nActivePage); - - return true; - } - -// Implementation overrideables - bool CreateTabControl() - { -#ifndef _WIN32_WCE - m_tab.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_TOOLTIPS, 0, m_nTabID); -#else // CE specific - m_tab.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, m_nTabID); -#endif // _WIN32_WCE - ATLASSERT(m_tab.m_hWnd != NULL); - if(m_tab.m_hWnd == NULL) - return false; - - m_tab.SetFont(AtlCreateControlFont()); - m_bInternalFont = true; - - m_tab.SetItemExtra(sizeof(TABVIEWPAGE)); - - T* pT = static_cast(this); - m_cyTabHeight = pT->CalcTabHeight(); - - return true; - } - - int CalcTabHeight() - { - int nCount = m_tab.GetItemCount(); - TCITEMEXTRA tcix = { 0 }; - tcix.tciheader.mask = TCIF_TEXT; - tcix.tciheader.pszText = _T("NS"); - int nIndex = m_tab.InsertItem(nCount, tcix); - - RECT rect = { 0, 0, 1000, 1000 }; - m_tab.AdjustRect(FALSE, &rect); - - RECT rcWnd = { 0, 0, 1000, rect.top }; - ::AdjustWindowRectEx(&rcWnd, m_tab.GetStyle(), FALSE, m_tab.GetExStyle()); - - int nHeight = rcWnd.bottom - rcWnd.top; - - m_tab.DeleteItem(nIndex); - - return nHeight; - } - - void ShowTabControl(bool bShow) - { - m_tab.ShowWindow(bShow ? SW_SHOWNOACTIVATE : SW_HIDE); - } - - void UpdateLayout() - { - RECT rect; - GetClientRect(&rect); - - if(m_tab.IsWindow() && ((m_tab.GetStyle() & WS_VISIBLE) != 0)) - m_tab.SetWindowPos(NULL, 0, 0, rect.right - rect.left, m_cyTabHeight, SWP_NOZORDER); - - if(m_nActivePage != -1) - ::SetWindowPos(GetPageHWND(m_nActivePage), NULL, 0, m_cyTabHeight, rect.right - rect.left, rect.bottom - rect.top - m_cyTabHeight, SWP_NOZORDER); - } - - void UpdateMenu() - { - if(m_menu.m_hMenu != NULL) - BuildWindowMenu(m_menu, m_nMenuItemsCount, m_bEmptyMenuItem, m_bWindowsMenuItem, m_bActivePageMenuItem, m_bActiveAsDefaultMenuItem); - } - - void UpdateTitleBar() - { - if(!m_wndTitleBar.IsWindow() || m_lpstrTitleBarBase == NULL) - return; // nothing to do - - if(m_nActivePage != -1) - { - T* pT = static_cast(this); - LPCTSTR lpstrTitle = pT->GetPageTitle(m_nActivePage); - LPCTSTR lpstrDivider = pT->GetTitleDividerText(); - int cchBuffer = m_cchTitleBarLength + lstrlen(lpstrDivider) + lstrlen(m_lpstrTitleBarBase) + 1; - CTempBuffer buff; - LPTSTR lpstrPageTitle = buff.Allocate(cchBuffer); - ATLASSERT(lpstrPageTitle != NULL); - if(lpstrPageTitle != NULL) - { - pT->ShortenTitle(lpstrTitle, lpstrPageTitle, m_cchTitleBarLength + 1); - SecureHelper::strcat_x(lpstrPageTitle, cchBuffer, lpstrDivider); - SecureHelper::strcat_x(lpstrPageTitle, cchBuffer, m_lpstrTitleBarBase); - } - else - { - lpstrPageTitle = m_lpstrTitleBarBase; - } - - m_wndTitleBar.SetWindowText(lpstrPageTitle); - } - else - { - m_wndTitleBar.SetWindowText(m_lpstrTitleBarBase); - } - } - - void DrawMoveMark(int nItem) - { - T* pT = static_cast(this); - - if(m_nInsertItem != -1) - { - RECT rect = { 0 }; - pT->GetMoveMarkRect(rect); - m_tab.InvalidateRect(&rect); - } - - m_nInsertItem = nItem; - - if(m_nInsertItem != -1) - { - CClientDC dc(m_tab.m_hWnd); - - RECT rect = { 0 }; - pT->GetMoveMarkRect(rect); - - CPen pen; - pen.CreatePen(PS_SOLID, 1, ::GetSysColor(COLOR_WINDOWTEXT)); - CBrush brush; - brush.CreateSolidBrush(::GetSysColor(COLOR_WINDOWTEXT)); - - HPEN hPenOld = dc.SelectPen(pen); - HBRUSH hBrushOld = dc.SelectBrush(brush); - - int x = rect.left; - int y = rect.top; - POINT ptsTop[3] = { { x, y }, { x + m_cxMoveMark, y }, { x + (m_cxMoveMark / 2), y + m_cyMoveMark } }; - dc.Polygon(ptsTop, 3); - - y = rect.bottom - 1; - POINT ptsBottom[3] = { { x, y }, { x + m_cxMoveMark, y }, { x + (m_cxMoveMark / 2), y - m_cyMoveMark } }; - dc.Polygon(ptsBottom, 3); - - dc.SelectPen(hPenOld); - dc.SelectBrush(hBrushOld); - } - } - - void GetMoveMarkRect(RECT& rect) const - { - m_tab.GetClientRect(&rect); - - RECT rcItem = { 0 }; - m_tab.GetItemRect(m_nInsertItem, &rcItem); - - if(m_nInsertItem <= m_nActivePage) - { - rect.left = rcItem.left - m_cxMoveMark / 2 - 1; - rect.right = rcItem.left + m_cxMoveMark / 2; - } - else - { - rect.left = rcItem.right - m_cxMoveMark / 2 - 1; - rect.right = rcItem.right + m_cxMoveMark / 2; - } - } - - void SetMoveCursor(bool bCanMove) - { - ::SetCursor(::LoadCursor(NULL, bCanMove ? IDC_ARROW : IDC_NO)); - } - - void GenerateDragImage(int nItem) - { - ATLASSERT(IsValidPageIndex(nItem)); - -#ifndef _WIN32_WCE - RECT rcItem = { 0 }; - m_tab.GetItemRect(nItem, &rcItem); - ::InflateRect(&rcItem, 2, 2); // make bigger to cover selected item -#else // CE specific - nItem; // avoid level 4 warning - RECT rcItem = { 0, 0, 40, 20 }; -#endif // _WIN32_WCE - - ATLASSERT(m_ilDrag.m_hImageList == NULL); - m_ilDrag.Create(rcItem.right - rcItem.left, rcItem.bottom - rcItem.top, ILC_COLORDDB | ILC_MASK, 1, 1); - - CClientDC dc(m_hWnd); - CDC dcMem; - dcMem.CreateCompatibleDC(dc); - ATLASSERT(dcMem.m_hDC != NULL); - dcMem.SetViewportOrg(-rcItem.left, -rcItem.top); - - CBitmap bmp; - bmp.CreateCompatibleBitmap(dc, rcItem.right - rcItem.left, rcItem.bottom - rcItem.top); - ATLASSERT(bmp.m_hBitmap != NULL); - - HBITMAP hBmpOld = dcMem.SelectBitmap(bmp); -#ifndef _WIN32_WCE - m_tab.SendMessage(WM_PRINTCLIENT, (WPARAM)dcMem.m_hDC); -#else // CE specific - dcMem.Rectangle(&rcItem); -#endif // _WIN32_WCE - dcMem.SelectBitmap(hBmpOld); - - ATLVERIFY(m_ilDrag.Add(bmp.m_hBitmap, RGB(255, 0, 255)) != -1); - } - - void ShortenTitle(LPCTSTR lpstrTitle, LPTSTR lpstrShortTitle, int cchShortTitle) - { - if(lstrlen(lpstrTitle) >= cchShortTitle) - { - LPCTSTR lpstrEllipsis = _T("..."); - int cchEllipsis = lstrlen(lpstrEllipsis); - SecureHelper::strncpy_x(lpstrShortTitle, cchShortTitle, lpstrTitle, cchShortTitle - cchEllipsis - 1); - SecureHelper::strcat_x(lpstrShortTitle, cchShortTitle, lpstrEllipsis); - } - else - { - SecureHelper::strcpy_x(lpstrShortTitle, cchShortTitle, lpstrTitle); - } - } - -#ifndef _WIN32_WCE - void UpdateTooltipText(LPNMTTDISPINFO pTTDI) - { - ATLASSERT(pTTDI != NULL); - pTTDI->lpszText = (LPTSTR)GetPageTitle((int)pTTDI->hdr.idFrom); - } -#endif // !_WIN32_WCE - -// Text for menu items and title bar - override to provide different strings - static LPCTSTR GetEmptyListText() - { - return _T("(Empty)"); - } - - static LPCTSTR GetWindowsMenuItemText() - { - return _T("&Windows..."); - } - - static LPCTSTR GetTitleDividerText() - { - return _T(" - "); - } - -// Notifications - override to provide different behavior - void OnPageActivated(int nPage) - { - NMHDR nmhdr = { 0 }; - nmhdr.hwndFrom = m_hWnd; - nmhdr.idFrom = nPage; - nmhdr.code = TBVN_PAGEACTIVATED; - ::SendMessage(GetParent(), WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&nmhdr); - } - - void OnContextMenu(int nPage, POINT pt) - { - m_tab.ClientToScreen(&pt); - - TBVCONTEXTMENUINFO cmi = { 0 }; - cmi.hdr.hwndFrom = m_hWnd; - cmi.hdr.idFrom = nPage; - cmi.hdr.code = TBVN_CONTEXTMENU; - cmi.pt = pt; - ::SendMessage(GetParent(), WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&cmi); - } -}; - -class CTabView : public CTabViewImpl -{ -public: - DECLARE_WND_CLASS_EX(_T("WTL_TabView"), 0, COLOR_APPWORKSPACE) -}; - -}; // namespace WTL - -#endif // __ATLCTRLX_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlddx.h b/!NotAdopted/SmartAutoReplier/wtl/atlddx.h deleted file mode 100644 index ecaf0adb01..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlddx.h +++ /dev/null @@ -1,679 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLDDX_H__ -#define __ATLDDX_H__ - -#pragma once - -#ifndef __ATLAPP_H__ - #error atlddx.h requires atlapp.h to be included first -#endif - -#if defined(_ATL_USE_DDX_FLOAT) && defined(_ATL_MIN_CRT) - #error Cannot use floating point DDX with _ATL_MIN_CRT defined -#endif // defined(_ATL_USE_DDX_FLOAT) && defined(_ATL_MIN_CRT) - -#ifdef _ATL_USE_DDX_FLOAT - #include -#endif // _ATL_USE_DDX_FLOAT - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CWinDataExchange - - -namespace WTL -{ - -// Constants -#define DDX_LOAD FALSE -#define DDX_SAVE TRUE - -// DDX map macros -#define BEGIN_DDX_MAP(thisClass) \ - BOOL DoDataExchange(BOOL bSaveAndValidate = FALSE, UINT nCtlID = (UINT)-1) \ - { \ - bSaveAndValidate; \ - nCtlID; - -#define DDX_TEXT(nID, var) \ - if(nCtlID == (UINT)-1 || nCtlID == nID) \ - { \ - if(!DDX_Text(nID, var, sizeof(var), bSaveAndValidate)) \ - return FALSE; \ - } - -#define DDX_TEXT_LEN(nID, var, len) \ - if(nCtlID == (UINT)-1 || nCtlID == nID) \ - { \ - if(!DDX_Text(nID, var, sizeof(var), bSaveAndValidate, TRUE, len)) \ - return FALSE; \ - } - -#define DDX_INT(nID, var) \ - if(nCtlID == (UINT)-1 || nCtlID == nID) \ - { \ - if(!DDX_Int(nID, var, TRUE, bSaveAndValidate)) \ - return FALSE; \ - } - -#define DDX_INT_RANGE(nID, var, min, max) \ - if(nCtlID == (UINT)-1 || nCtlID == nID) \ - { \ - if(!DDX_Int(nID, var, TRUE, bSaveAndValidate, TRUE, min, max)) \ - return FALSE; \ - } - -#define DDX_UINT(nID, var) \ - if(nCtlID == (UINT)-1 || nCtlID == nID) \ - { \ - if(!DDX_Int(nID, var, FALSE, bSaveAndValidate)) \ - return FALSE; \ - } - -#define DDX_UINT_RANGE(nID, var, min, max) \ - if(nCtlID == (UINT)-1 || nCtlID == nID) \ - { \ - if(!DDX_Int(nID, var, FALSE, bSaveAndValidate, TRUE, min, max)) \ - return FALSE; \ - } - -#ifdef _ATL_USE_DDX_FLOAT -#define DDX_FLOAT(nID, var) \ - if(nCtlID == (UINT)-1 || nCtlID == nID) \ - { \ - if(!DDX_Float(nID, var, bSaveAndValidate)) \ - return FALSE; \ - } - -#define DDX_FLOAT_RANGE(nID, var, min, max) \ - if(nCtlID == (UINT)-1 || nCtlID == nID) \ - { \ - if(!DDX_Float(nID, var, bSaveAndValidate, TRUE, min, max)) \ - return FALSE; \ - } -#define DDX_FLOAT_P(nID, var, precision) \ - if(nCtlID == (UINT)-1 || nCtlID == nID) \ - { \ - if(!DDX_Float(nID, var, bSaveAndValidate, FALSE, 0, 0, precision)) \ - return FALSE; \ - } - -#define DDX_FLOAT_P_RANGE(nID, var, min, max, precision) \ - if(nCtlID == (UINT)-1 || nCtlID == nID) \ - { \ - if(!DDX_Float(nID, var, bSaveAndValidate, TRUE, min, max, precision)) \ - return FALSE; \ - } -#endif // _ATL_USE_DDX_FLOAT - -#define DDX_CONTROL(nID, obj) \ - if(nCtlID == (UINT)-1 || nCtlID == nID) \ - DDX_Control(nID, obj, bSaveAndValidate); - -#define DDX_CONTROL_HANDLE(nID, obj) \ - if(nCtlID == (UINT)-1 || nCtlID == nID) \ - DDX_Control_Handle(nID, obj, bSaveAndValidate); - -#define DDX_CHECK(nID, var) \ - if(nCtlID == (UINT)-1 || nCtlID == nID) \ - DDX_Check(nID, var, bSaveAndValidate); - -#define DDX_RADIO(nID, var) \ - if(nCtlID == (UINT)-1 || nCtlID == nID) \ - DDX_Radio(nID, var, bSaveAndValidate); - -#define END_DDX_MAP() \ - return TRUE; \ - } - -// DDX support for Tab, Combo, ListBox and ListView selection index -// Note: Specialized versions require atlctrls.h to be included first -#define DDX_INDEX(CtrlClass, nID, var) \ - if(nCtlID == (UINT)-1 || nCtlID == nID) \ - DDX_Index(nID, var, bSaveAndValidate); - -#ifdef __ATLCTRLS_H__ - #define DDX_TAB_INDEX(nID, var) DDX_INDEX(WTL::CTabCtrl, nID, var) - #define DDX_COMBO_INDEX(nID, var) DDX_INDEX(WTL::CComboBox, nID, var) - #define DDX_LISTBOX_INDEX(nID, var) DDX_INDEX(WTL::CListBox, nID, var) - #define DDX_LISTVIEW_INDEX(nID, var) DDX_INDEX(WTL::CListViewCtrl, nID, var) -#endif // __ATLCTRLS_H__ - - -/////////////////////////////////////////////////////////////////////////////// -// CWinDataExchange - provides support for DDX - -template -class CWinDataExchange -{ -public: -// Data exchange method - override in your derived class - BOOL DoDataExchange(BOOL /*bSaveAndValidate*/ = FALSE, UINT /*nCtlID*/ = (UINT)-1) - { - // this one should never be called, override it in - // your derived class by implementing DDX map - ATLASSERT(FALSE); - return FALSE; - } - -// Helpers for validation error reporting - enum _XDataType - { - ddxDataNull = 0, - ddxDataText = 1, - ddxDataInt = 2, - ddxDataFloat = 3, - ddxDataDouble = 4 - }; - - struct _XTextData - { - int nLength; - int nMaxLength; - }; - - struct _XIntData - { - long nVal; - long nMin; - long nMax; - }; - - struct _XFloatData - { - double nVal; - double nMin; - double nMax; - }; - - struct _XData - { - _XDataType nDataType; - union - { - _XTextData textData; - _XIntData intData; - _XFloatData floatData; - }; - }; - -// Text exchange - BOOL DDX_Text(UINT nID, LPTSTR lpstrText, int cbSize, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0) - { - T* pT = static_cast(this); - BOOL bSuccess = TRUE; - - if(bSave) - { - HWND hWndCtrl = pT->GetDlgItem(nID); - int nRetLen = ::GetWindowText(hWndCtrl, lpstrText, cbSize / sizeof(TCHAR)); - if(nRetLen < ::GetWindowTextLength(hWndCtrl)) - bSuccess = FALSE; - } - else - { - ATLASSERT(!bValidate || lstrlen(lpstrText) <= nLength); - bSuccess = pT->SetDlgItemText(nID, lpstrText); - } - - if(!bSuccess) - { - pT->OnDataExchangeError(nID, bSave); - } - else if(bSave && bValidate) // validation - { - ATLASSERT(nLength > 0); - if(lstrlen(lpstrText) > nLength) - { - _XData data = { ddxDataText }; - data.textData.nLength = lstrlen(lpstrText); - data.textData.nMaxLength = nLength; - pT->OnDataValidateError(nID, bSave, data); - bSuccess = FALSE; - } - } - return bSuccess; - } - - BOOL DDX_Text(UINT nID, BSTR& bstrText, int /*cbSize*/, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0) - { - T* pT = static_cast(this); - BOOL bSuccess = TRUE; - - if(bSave) - { - bSuccess = pT->GetDlgItemText(nID, bstrText); - } - else - { - USES_CONVERSION; - LPTSTR lpstrText = OLE2T(bstrText); - ATLASSERT(!bValidate || lstrlen(lpstrText) <= nLength); - bSuccess = pT->SetDlgItemText(nID, lpstrText); - } - - if(!bSuccess) - { - pT->OnDataExchangeError(nID, bSave); - } - else if(bSave && bValidate) // validation - { - ATLASSERT(nLength > 0); - if((int)::SysStringLen(bstrText) > nLength) - { - _XData data = { ddxDataText }; - data.textData.nLength = (int)::SysStringLen(bstrText); - data.textData.nMaxLength = nLength; - pT->OnDataValidateError(nID, bSave, data); - bSuccess = FALSE; - } - } - return bSuccess; - } - - BOOL DDX_Text(UINT nID, ATL::CComBSTR& bstrText, int /*cbSize*/, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0) - { - T* pT = static_cast(this); - BOOL bSuccess = TRUE; - - if(bSave) - { - bSuccess = pT->GetDlgItemText(nID, (BSTR&)bstrText); - } - else - { - USES_CONVERSION; - LPTSTR lpstrText = OLE2T(bstrText); - ATLASSERT(!bValidate || lstrlen(lpstrText) <= nLength); - bSuccess = pT->SetDlgItemText(nID, lpstrText); - } - - if(!bSuccess) - { - pT->OnDataExchangeError(nID, bSave); - } - else if(bSave && bValidate) // validation - { - ATLASSERT(nLength > 0); - if((int)bstrText.Length() > nLength) - { - _XData data = { ddxDataText }; - data.textData.nLength = (int)bstrText.Length(); - data.textData.nMaxLength = nLength; - pT->OnDataValidateError(nID, bSave, data); - bSuccess = FALSE; - } - } - return bSuccess; - } - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - BOOL DDX_Text(UINT nID, _CSTRING_NS::CString& strText, int /*cbSize*/, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0) - { - T* pT = static_cast(this); - BOOL bSuccess = TRUE; - - if(bSave) - { - HWND hWndCtrl = pT->GetDlgItem(nID); - int nLen = ::GetWindowTextLength(hWndCtrl); - int nRetLen = -1; - LPTSTR lpstr = strText.GetBufferSetLength(nLen); - if(lpstr != NULL) - { - nRetLen = ::GetWindowText(hWndCtrl, lpstr, nLen + 1); - strText.ReleaseBuffer(); - } - if(nRetLen < nLen) - bSuccess = FALSE; - } - else - { - bSuccess = pT->SetDlgItemText(nID, strText); - } - - if(!bSuccess) - { - pT->OnDataExchangeError(nID, bSave); - } - else if(bSave && bValidate) // validation - { - ATLASSERT(nLength > 0); - if(strText.GetLength() > nLength) - { - _XData data = { ddxDataText }; - data.textData.nLength = strText.GetLength(); - data.textData.nMaxLength = nLength; - pT->OnDataValidateError(nID, bSave, data); - bSuccess = FALSE; - } - } - return bSuccess; - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - -// Numeric exchange - template - BOOL DDX_Int(UINT nID, Type& nVal, BOOL bSigned, BOOL bSave, BOOL bValidate = FALSE, Type nMin = 0, Type nMax = 0) - { - T* pT = static_cast(this); - BOOL bSuccess = TRUE; - - if(bSave) - { - nVal = (Type)pT->GetDlgItemInt(nID, &bSuccess, bSigned); - } - else - { - ATLASSERT(!bValidate || nVal >= nMin && nVal <= nMax); - bSuccess = pT->SetDlgItemInt(nID, nVal, bSigned); - } - - if(!bSuccess) - { - pT->OnDataExchangeError(nID, bSave); - } - else if(bSave && bValidate) // validation - { - ATLASSERT(nMin != nMax); - if(nVal < nMin || nVal > nMax) - { - _XData data = { ddxDataInt }; - data.intData.nVal = (long)nVal; - data.intData.nMin = (long)nMin; - data.intData.nMax = (long)nMax; - pT->OnDataValidateError(nID, bSave, data); - bSuccess = FALSE; - } - } - return bSuccess; - } - -// Float exchange -#ifdef _ATL_USE_DDX_FLOAT - static BOOL _AtlSimpleFloatParse(LPCTSTR lpszText, double& d) - { - ATLASSERT(lpszText != NULL); - while (*lpszText == _T(' ') || *lpszText == _T('\t')) - lpszText++; - - TCHAR chFirst = lpszText[0]; - d = _tcstod(lpszText, (LPTSTR*)&lpszText); - if (d == 0.0 && chFirst != _T('0')) - return FALSE; // could not convert - while (*lpszText == _T(' ') || *lpszText == _T('\t')) - lpszText++; - - if (*lpszText != _T('\0')) - return FALSE; // not terminated properly - - return TRUE; - } - - BOOL DDX_Float(UINT nID, float& nVal, BOOL bSave, BOOL bValidate = FALSE, float nMin = 0.F, float nMax = 0.F, int nPrecision = FLT_DIG) - { - T* pT = static_cast(this); - BOOL bSuccess = TRUE; - const int cchBuff = 32; - TCHAR szBuff[cchBuff] = { 0 }; - - if(bSave) - { - pT->GetDlgItemText(nID, szBuff, cchBuff); - double d = 0; - if(_AtlSimpleFloatParse(szBuff, d)) - nVal = (float)d; - else - bSuccess = FALSE; - } - else - { - ATLASSERT(!bValidate || nVal >= nMin && nVal <= nMax); - SecureHelper::sprintf_x(szBuff, cchBuff, _T("%.*g"), nPrecision, nVal); - bSuccess = pT->SetDlgItemText(nID, szBuff); - } - - if(!bSuccess) - { - pT->OnDataExchangeError(nID, bSave); - } - else if(bSave && bValidate) // validation - { - ATLASSERT(nMin != nMax); - if(nVal < nMin || nVal > nMax) - { - _XData data = { ddxDataFloat }; - data.floatData.nVal = (double)nVal; - data.floatData.nMin = (double)nMin; - data.floatData.nMax = (double)nMax; - pT->OnDataValidateError(nID, bSave, data); - bSuccess = FALSE; - } - } - return bSuccess; - } - - BOOL DDX_Float(UINT nID, double& nVal, BOOL bSave, BOOL bValidate = FALSE, double nMin = 0., double nMax = 0., int nPrecision = DBL_DIG) - { - T* pT = static_cast(this); - BOOL bSuccess = TRUE; - const int cchBuff = 32; - TCHAR szBuff[cchBuff] = { 0 }; - - if(bSave) - { - pT->GetDlgItemText(nID, szBuff, cchBuff); - double d = 0; - if(_AtlSimpleFloatParse(szBuff, d)) - nVal = d; - else - bSuccess = FALSE; - } - else - { - ATLASSERT(!bValidate || nVal >= nMin && nVal <= nMax); - SecureHelper::sprintf_x(szBuff, cchBuff, _T("%.*g"), nPrecision, nVal); - bSuccess = pT->SetDlgItemText(nID, szBuff); - } - - if(!bSuccess) - { - pT->OnDataExchangeError(nID, bSave); - } - else if(bSave && bValidate) // validation - { - ATLASSERT(nMin != nMax); - if(nVal < nMin || nVal > nMax) - { - _XData data = { ddxDataFloat }; - data.floatData.nVal = nVal; - data.floatData.nMin = nMin; - data.floatData.nMax = nMax; - pT->OnDataValidateError(nID, bSave, data); - bSuccess = FALSE; - } - } - return bSuccess; - } -#endif // _ATL_USE_DDX_FLOAT - -// Full control subclassing (for CWindowImpl derived controls) - template - void DDX_Control(UINT nID, TControl& ctrl, BOOL bSave) - { - if(!bSave && ctrl.m_hWnd == NULL) - { - T* pT = static_cast(this); - ctrl.SubclassWindow(pT->GetDlgItem(nID)); - } - } - -// Simple control attaching (for HWND wrapper controls) - template - void DDX_Control_Handle(UINT nID, TControl& ctrl, BOOL bSave) - { - if(!bSave && ctrl.m_hWnd == NULL) - { - T* pT = static_cast(this); - ctrl = pT->GetDlgItem(nID); - } - } - -// Control state - void DDX_Check(UINT nID, int& nValue, BOOL bSave) - { - T* pT = static_cast(this); - HWND hWndCtrl = pT->GetDlgItem(nID); - if(bSave) - { - nValue = (int)::SendMessage(hWndCtrl, BM_GETCHECK, 0, 0L); - ATLASSERT(nValue >= 0 && nValue <= 2); - } - else - { - if(nValue < 0 || nValue > 2) - { - ATLTRACE2(atlTraceUI, 0, _T("ATL: Warning - dialog data checkbox value (%d) out of range.\n"), nValue); - nValue = 0; // default to off - } - ::SendMessage(hWndCtrl, BM_SETCHECK, nValue, 0L); - } - } - - // variant that supports bool (checked/not-checked, no intermediate state) - void DDX_Check(UINT nID, bool& bCheck, BOOL bSave) - { - int nValue = bCheck ? 1 : 0; - DDX_Check(nID, nValue, bSave); - - if(bSave) - { - if(nValue == 2) - ATLTRACE2(atlTraceUI, 0, _T("ATL: Warning - checkbox state (%d) out of supported range.\n"), nValue); - bCheck = (nValue == 1); - } - } - - void DDX_Radio(UINT nID, int& nValue, BOOL bSave) - { - T* pT = static_cast(this); - HWND hWndCtrl = pT->GetDlgItem(nID); - ATLASSERT(hWndCtrl != NULL); - - // must be first in a group of auto radio buttons - ATLASSERT(::GetWindowLong(hWndCtrl, GWL_STYLE) & WS_GROUP); - ATLASSERT(::SendMessage(hWndCtrl, WM_GETDLGCODE, 0, 0L) & DLGC_RADIOBUTTON); - - if(bSave) - nValue = -1; // value if none found - - // walk all children in group - int nButton = 0; - do - { - if(::SendMessage(hWndCtrl, WM_GETDLGCODE, 0, 0L) & DLGC_RADIOBUTTON) - { - // control in group is a radio button - if(bSave) - { - if(::SendMessage(hWndCtrl, BM_GETCHECK, 0, 0L) != 0) - { - ATLASSERT(nValue == -1); // only set once - nValue = nButton; - } - } - else - { - // select button - ::SendMessage(hWndCtrl, BM_SETCHECK, (nButton == nValue), 0L); - } - nButton++; - } - else - { - ATLTRACE2(atlTraceUI, 0, _T("ATL: Warning - skipping non-radio button in group.\n")); - } - hWndCtrl = ::GetWindow(hWndCtrl, GW_HWNDNEXT); - } - while (hWndCtrl != NULL && !(GetWindowLong(hWndCtrl, GWL_STYLE) & WS_GROUP)); - } - -// DDX support for Tab, Combo, ListBox and ListView selection index - template - INT _getSel(TCtrl& tCtrl) - { - return tCtrl.GetCurSel(); - } - - template - void _setSel(TCtrl& tCtrl, INT iSel) - { - if(iSel < 0) - tCtrl.SetCurSel(-1); - else - tCtrl.SetCurSel(iSel); - } - -#ifdef __ATLCTRLS_H__ - // ListViewCtrl specialization - template <> - INT _getSel(WTL::CListViewCtrl& tCtrl) - { - return tCtrl.GetSelectedIndex(); - } - - template <> - void _setSel(WTL::CListViewCtrl& tCtrl, INT iSel) - { - if(iSel < 0) - tCtrl.SelectItem(-1); - else - tCtrl.SelectItem(iSel); - } -#endif // __ATLCTRLS_H__ - - template - void DDX_Index(UINT nID, INT& nVal, BOOL bSave) - { - T* pT = static_cast(this); - TCtrl ctrl(pT->GetDlgItem(nID)); - - if(bSave) - nVal = _getSel(ctrl); - else - _setSel(ctrl, nVal); - } - -// Overrideables - void OnDataExchangeError(UINT nCtrlID, BOOL /*bSave*/) - { - // Override to display an error message - ::MessageBeep((UINT)-1); - T* pT = static_cast(this); - ::SetFocus(pT->GetDlgItem(nCtrlID)); - } - - void OnDataValidateError(UINT nCtrlID, BOOL /*bSave*/, _XData& /*data*/) - { - // Override to display an error message - ::MessageBeep((UINT)-1); - T* pT = static_cast(this); - ::SetFocus(pT->GetDlgItem(nCtrlID)); - } -}; - -}; // namespace WTL - -#endif // __ATLDDX_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atldlgs.h b/!NotAdopted/SmartAutoReplier/wtl/atldlgs.h deleted file mode 100644 index a55fed4cb5..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atldlgs.h +++ /dev/null @@ -1,6403 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLDLGS_H__ -#define __ATLDLGS_H__ - -#pragma once - -#ifndef __ATLAPP_H__ - #error atldlgs.h requires atlapp.h to be included first -#endif - -#ifndef __ATLWIN_H__ - #error atldlgs.h requires atlwin.h to be included first -#endif - -#include -#include - -#if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) - #include -#endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CFileDialogImpl -// CFileDialog -// CFileDialogEx -// CMultiFileDialogImpl -// CMultiFileDialog -// CShellFileDialogImpl -// CShellFileOpenDialogImpl -// CShellFileOpenDialog -// CShellFileSaveDialogImpl -// CShellFileSaveDialog -// CFolderDialogImpl -// CFolderDialog -// CFontDialogImpl -// CFontDialog -// CRichEditFontDialogImpl -// CRichEditFontDialog -// CColorDialogImpl -// CColorDialog -// CPrintDialogImpl -// CPrintDialog -// CPrintDialogExImpl -// CPrintDialogEx -// CPageSetupDialogImpl -// CPageSetupDialog -// CFindReplaceDialogImpl -// CFindReplaceDialog -// -// CDialogBaseUnits -// CMemDlgTemplate -// CIndirectDialogImpl -// -// CPropertySheetWindow -// CPropertySheetImpl -// CPropertySheet -// CPropertyPageWindow -// CPropertyPageImpl -// CPropertyPage -// CAxPropertyPageImpl -// CAxPropertyPage -// -// CWizard97SheetWindow -// CWizard97SheetImpl -// CWizard97Sheet -// CWizard97PageWindow -// CWizard97PageImpl -// CWizard97ExteriorPageImpl -// CWizard97InteriorPageImpl -// -// CAeroWizardFrameWindow -// CAeroWizardFrameImpl -// CAeroWizardFrame -// CAeroWizardPageWindow -// CAeroWizardPageImpl -// CAeroWizardPage -// CAeroWizardAxPageImpl -// CAeroWizardAxPage -// -// CTaskDialogConfig -// CTaskDialogImpl -// CTaskDialog -// -// Global functions: -// AtlTaskDialog() - - -namespace WTL -{ - -/////////////////////////////////////////////////////////////////////////////// -// CFileDialogImpl - used for File Open or File Save As - -// compatibility with the old (vc6.0) headers -#if (_WIN32_WINNT >= 0x0500) && !defined(OPENFILENAME_SIZE_VERSION_400) - #ifndef CDSIZEOF_STRUCT - #define CDSIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member)) - #endif - #define OPENFILENAME_SIZE_VERSION_400A CDSIZEOF_STRUCT(OPENFILENAMEA,lpTemplateName) - #define OPENFILENAME_SIZE_VERSION_400W CDSIZEOF_STRUCT(OPENFILENAMEW,lpTemplateName) - #ifdef UNICODE - #define OPENFILENAME_SIZE_VERSION_400 OPENFILENAME_SIZE_VERSION_400W - #else - #define OPENFILENAME_SIZE_VERSION_400 OPENFILENAME_SIZE_VERSION_400A - #endif // !UNICODE -#endif // (_WIN32_WINNT >= 0x0500) && !defined(OPENFILENAME_SIZE_VERSION_400) - -#if !defined(_WIN32_WCE) && !defined(CDN_INCLUDEITEM) - #define CDN_INCLUDEITEM (CDN_FIRST - 0x0007) -#endif - -template -class ATL_NO_VTABLE CFileDialogImpl : public ATL::CDialogImplBase -{ -public: -#if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501) - OPENFILENAMEEX m_ofn; -#else - OPENFILENAME m_ofn; -#endif - BOOL m_bOpenFileDialog; // TRUE for file open, FALSE for file save - TCHAR m_szFileTitle[_MAX_FNAME]; // contains file title after return - TCHAR m_szFileName[_MAX_PATH]; // contains full path name after return - - CFileDialogImpl(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs - LPCTSTR lpszDefExt = NULL, - LPCTSTR lpszFileName = NULL, - DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, - LPCTSTR lpszFilter = NULL, - HWND hWndParent = NULL) - { - memset(&m_ofn, 0, sizeof(m_ofn)); // initialize structure to 0/NULL - m_szFileName[0] = _T('\0'); - m_szFileTitle[0] = _T('\0'); - - m_bOpenFileDialog = bOpenFileDialog; - -#if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501) - m_ofn.lStructSize = bOpenFileDialog ? sizeof(m_ofn) : sizeof(OPENFILENAME); -#else - m_ofn.lStructSize = sizeof(m_ofn); -#endif - -#if (_WIN32_WINNT >= 0x0500) - // adjust struct size if running on older version of Windows - if(AtlIsOldWindows()) - { - ATLASSERT(sizeof(m_ofn) > OPENFILENAME_SIZE_VERSION_400); // must be - m_ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; - } -#endif // (_WIN32_WINNT >= 0x0500) - m_ofn.lpstrFile = m_szFileName; - m_ofn.nMaxFile = _MAX_PATH; - m_ofn.lpstrDefExt = lpszDefExt; - m_ofn.lpstrFileTitle = (LPTSTR)m_szFileTitle; - m_ofn.nMaxFileTitle = _MAX_FNAME; -#ifndef _WIN32_WCE - m_ofn.Flags = dwFlags | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLESIZING; -#else // CE specific - m_ofn.Flags = dwFlags | OFN_EXPLORER | OFN_ENABLEHOOK; -#endif // !_WIN32_WCE - m_ofn.lpstrFilter = lpszFilter; - m_ofn.hInstance = ModuleHelper::GetResourceInstance(); - m_ofn.lpfnHook = (LPOFNHOOKPROC)T::StartDialogProc; - m_ofn.hwndOwner = hWndParent; - - // setup initial file name - if(lpszFileName != NULL) - SecureHelper::strncpy_x(m_szFileName, _countof(m_szFileName), lpszFileName, _TRUNCATE); - } - - INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) - { - ATLASSERT((m_ofn.Flags & OFN_ENABLEHOOK) != 0); - ATLASSERT(m_ofn.lpfnHook != NULL); // can still be a user hook - - ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); - - if(m_ofn.hwndOwner == NULL) // set only if not specified before - m_ofn.hwndOwner = hWndParent; - - ATLASSERT(m_hWnd == NULL); - ModuleHelper::AddCreateWndData(&m_thunk.cd, (ATL::CDialogImplBase*)this); - - BOOL bRet; - if(m_bOpenFileDialog) -#if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501) - bRet = ::GetOpenFileNameEx(&m_ofn); - else - bRet = ::GetSaveFileName((LPOPENFILENAME)&m_ofn); -#else - bRet = ::GetOpenFileName(&m_ofn); - else - bRet = ::GetSaveFileName(&m_ofn); -#endif - - m_hWnd = NULL; - - return bRet ? IDOK : IDCANCEL; - } - -// Attributes - ATL::CWindow GetFileDialogWindow() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return ATL::CWindow(GetParent()); - } - - int GetFilePath(LPTSTR lpstrFilePath, int nLength) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); - - return (int)GetFileDialogWindow().SendMessage(CDM_GETFILEPATH, nLength, (LPARAM)lpstrFilePath); - } - - int GetFolderIDList(LPVOID lpBuff, int nLength) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); - - return (int)GetFileDialogWindow().SendMessage(CDM_GETFOLDERIDLIST, nLength, (LPARAM)lpBuff); - } - - int GetFolderPath(LPTSTR lpstrFolderPath, int nLength) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); - - return (int)GetFileDialogWindow().SendMessage(CDM_GETFOLDERPATH, nLength, (LPARAM)lpstrFolderPath); - } - - int GetSpec(LPTSTR lpstrSpec, int nLength) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); - - return (int)GetFileDialogWindow().SendMessage(CDM_GETSPEC, nLength, (LPARAM)lpstrSpec); - } - - void SetControlText(int nCtrlID, LPCTSTR lpstrText) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); - - GetFileDialogWindow().SendMessage(CDM_SETCONTROLTEXT, nCtrlID, (LPARAM)lpstrText); - } - - void SetDefExt(LPCTSTR lpstrExt) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); - - GetFileDialogWindow().SendMessage(CDM_SETDEFEXT, 0, (LPARAM)lpstrExt); - } - - BOOL GetReadOnlyPref() const // return TRUE if readonly checked - { - return ((m_ofn.Flags & OFN_READONLY) != 0) ? TRUE : FALSE; - } - -// Operations - void HideControl(int nCtrlID) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); - - GetFileDialogWindow().SendMessage(CDM_HIDECONTROL, nCtrlID); - } - -// Special override for common dialogs - BOOL EndDialog(INT_PTR /*nRetCode*/ = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - GetFileDialogWindow().SendMessage(WM_COMMAND, MAKEWPARAM(IDCANCEL, 0)); - return TRUE; - } - -// Message map and handlers - BEGIN_MSG_MAP(CFileDialogImpl) - NOTIFY_CODE_HANDLER(CDN_FILEOK, _OnFileOK) - NOTIFY_CODE_HANDLER(CDN_FOLDERCHANGE, _OnFolderChange) - NOTIFY_CODE_HANDLER(CDN_HELP, _OnHelp) - NOTIFY_CODE_HANDLER(CDN_INITDONE, _OnInitDone) - NOTIFY_CODE_HANDLER(CDN_SELCHANGE, _OnSelChange) - NOTIFY_CODE_HANDLER(CDN_SHAREVIOLATION, _OnShareViolation) - NOTIFY_CODE_HANDLER(CDN_TYPECHANGE, _OnTypeChange) -#ifndef _WIN32_WCE - NOTIFY_CODE_HANDLER(CDN_INCLUDEITEM, _OnIncludeItem) -#endif // !_WIN32_WCE - END_MSG_MAP() - - LRESULT _OnFileOK(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) - { - ATLASSERT(::IsWindow(m_hWnd)); - T* pT = static_cast(this); - return !pT->OnFileOK((LPOFNOTIFY)pnmh); - } - - LRESULT _OnFolderChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) - { - ATLASSERT(::IsWindow(m_hWnd)); - T* pT = static_cast(this); - pT->OnFolderChange((LPOFNOTIFY)pnmh); - return 0; - } - - LRESULT _OnHelp(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) - { - ATLASSERT(::IsWindow(m_hWnd)); - T* pT = static_cast(this); - pT->OnHelp((LPOFNOTIFY)pnmh); - return 0; - } - - LRESULT _OnInitDone(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) - { - ATLASSERT(::IsWindow(m_hWnd)); - T* pT = static_cast(this); - pT->OnInitDone((LPOFNOTIFY)pnmh); - return 0; - } - - LRESULT _OnSelChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) - { - ATLASSERT(::IsWindow(m_hWnd)); - T* pT = static_cast(this); - pT->OnSelChange((LPOFNOTIFY)pnmh); - return 0; - } - - LRESULT _OnShareViolation(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) - { - ATLASSERT(::IsWindow(m_hWnd)); - T* pT = static_cast(this); - return pT->OnShareViolation((LPOFNOTIFY)pnmh); - } - - LRESULT _OnTypeChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) - { - ATLASSERT(::IsWindow(m_hWnd)); - T* pT = static_cast(this); - pT->OnTypeChange((LPOFNOTIFY)pnmh); - return 0; - } - -#ifndef _WIN32_WCE - LRESULT _OnIncludeItem(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) - { - ATLASSERT(::IsWindow(m_hWnd)); - T* pT = static_cast(this); - return pT->OnIncludeItem((LPOFNOTIFYEX)pnmh); - } -#endif // !_WIN32_WCE - -// Overrideables - BOOL OnFileOK(LPOFNOTIFY /*lpon*/) - { - return TRUE; - } - - void OnFolderChange(LPOFNOTIFY /*lpon*/) - { - } - - void OnHelp(LPOFNOTIFY /*lpon*/) - { - } - - void OnInitDone(LPOFNOTIFY /*lpon*/) - { - } - - void OnSelChange(LPOFNOTIFY /*lpon*/) - { - } - - int OnShareViolation(LPOFNOTIFY /*lpon*/) - { - return 0; - } - - void OnTypeChange(LPOFNOTIFY /*lpon*/) - { - } - -#ifndef _WIN32_WCE - BOOL OnIncludeItem(LPOFNOTIFYEX /*lponex*/) - { - return TRUE; // include item - } -#endif // !_WIN32_WCE -}; - -class CFileDialog : public CFileDialogImpl -{ -public: - CFileDialog(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs - LPCTSTR lpszDefExt = NULL, - LPCTSTR lpszFileName = NULL, - DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, - LPCTSTR lpszFilter = NULL, - HWND hWndParent = NULL) - : CFileDialogImpl(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, hWndParent) - { } - - // override base class map and references to handlers - DECLARE_EMPTY_MSG_MAP() -}; - -#if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501) -class CFileDialogEx : public CFileDialogImpl -{ -public: - CFileDialogEx( // Supports only FileOpen - LPCTSTR lpszDefExt = NULL, - LPCTSTR lpszFileName = NULL, - DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, - OFN_EXFLAG ExFlags = OFN_EXFLAG_THUMBNAILVIEW, - OFN_SORTORDER dwSortOrder = OFN_SORTORDER_AUTO, - LPCTSTR lpszFilter = NULL, - HWND hWndParent = NULL) - : CFileDialogImpl(TRUE, lpszDefExt, lpszFileName, dwFlags, lpszFilter, hWndParent) - { - m_ofn.ExFlags = ExFlags; - m_ofn.dwSortOrder = dwSortOrder; - } - - // override base class map and references to handlers - DECLARE_EMPTY_MSG_MAP() -}; -#endif // defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501) - - -/////////////////////////////////////////////////////////////////////////////// -// Multi File Dialog - Multi-select File Open dialog - -#ifndef _WIN32_WCE - -// The class dynamically resizes the buffer as the file selection changes -// (as described in Knowledge Base article 131462). It also expands selected -// shortcut files to take into account the full path of the target file. -// Note that this doesn't work on Win9x for the old style dialogs, as well as -// on NT for non-Unicode builds. - -#ifndef _WTL_FIXED_OFN_BUFFER_LENGTH - #define _WTL_FIXED_OFN_BUFFER_LENGTH 0x10000 -#endif - -template -class ATL_NO_VTABLE CMultiFileDialogImpl : public CFileDialogImpl< T > -{ -public: - mutable LPCTSTR m_pNextFile; -#ifndef _UNICODE - bool m_bIsNT; -#endif - - CMultiFileDialogImpl( - LPCTSTR lpszDefExt = NULL, - LPCTSTR lpszFileName = NULL, - DWORD dwFlags = OFN_HIDEREADONLY, - LPCTSTR lpszFilter = NULL, - HWND hWndParent = NULL) - : CFileDialogImpl(TRUE, lpszDefExt, lpszFileName, dwFlags, lpszFilter, hWndParent), - m_pNextFile(NULL) - { - m_ofn.Flags |= OFN_ALLOWMULTISELECT; // Force multiple selection mode - -#ifndef _UNICODE - OSVERSIONINFO ovi = { sizeof(ovi) }; - ::GetVersionEx(&ovi); - m_bIsNT = (ovi.dwPlatformId == VER_PLATFORM_WIN32_NT); - if (m_bIsNT) - { - // On NT platforms, GetOpenFileNameA thunks to GetOpenFileNameW and there - // is absolutely nothing we can do except to start off with a large buffer. - ATLVERIFY(ResizeFilenameBuffer(_WTL_FIXED_OFN_BUFFER_LENGTH)); - } -#endif - } - - ~CMultiFileDialogImpl() - { - if (m_ofn.lpstrFile != m_szFileName) // Free the buffer if we allocated it - delete[] m_ofn.lpstrFile; - } - -// Operations - // Get the directory that the files were chosen from. - // The function returns the number of characters copied, not including the terminating zero. - // If the buffer is NULL, the function returns the required size, in characters, including the terminating zero. - // If the function fails, the return value is zero. - int GetDirectory(LPTSTR pBuffer, int nBufLen) const - { - if (m_ofn.lpstrFile == NULL) - return 0; - - LPCTSTR pStr = m_ofn.lpstrFile; - int nLength = lstrlen(pStr); - if (pStr[nLength + 1] == 0) - { - // The OFN buffer contains a single item so extract its path. - LPCTSTR pSep = _strrchr(pStr, _T('\\')); - if (pSep != NULL) - nLength = (int)(DWORD_PTR)(pSep - pStr); - } - - int nRet = 0; - if (pBuffer == NULL) // If the buffer is NULL, return the required length - { - nRet = nLength + 1; - } - else if (nBufLen > nLength) - { - SecureHelper::strncpy_x(pBuffer, nBufLen, pStr, nLength); - nRet = nLength; - } - - return nRet; - } - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - bool GetDirectory(_CSTRING_NS::CString& strDir) const - { - bool bRet = false; - - int nLength = GetDirectory(NULL, 0); - if (nLength > 0) - { - bRet = (GetDirectory(strDir.GetBuffer(nLength), nLength) > 0); - strDir.ReleaseBuffer(nLength - 1); - } - - return bRet; - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - - // Get the first filename as a pointer into the buffer. - LPCTSTR GetFirstFileName() const - { - if (m_ofn.lpstrFile == NULL) - return NULL; - - m_pNextFile = NULL; // Reset internal buffer pointer - - LPCTSTR pStr = m_ofn.lpstrFile; - int nLength = lstrlen(pStr); - if (pStr[nLength + 1] != 0) - { - // Multiple items were selected. The first string is the directory, - // so skip forwards to the second string. - pStr += nLength + 1; - - // Set up m_pNext so it points to the second item (or null). - m_pNextFile = pStr; - GetNextFileName(); - } - else - { - // A single item was selected. Skip forward past the path. - LPCTSTR pSep = _strrchr(pStr, _T('\\')); - if (pSep != NULL) - pStr = pSep + 1; - } - - return pStr; - } - - // Get the next filename as a pointer into the buffer. - LPCTSTR GetNextFileName() const - { - if (m_pNextFile == NULL) - return NULL; - - LPCTSTR pStr = m_pNextFile; - // Set "m_pNextFile" to point to the next file name, or null if we - // have reached the last file in the list. - int nLength = lstrlen(pStr); - m_pNextFile = (pStr[nLength + 1] != 0) ? &pStr[nLength + 1] : NULL; - - return pStr; - } - - // Get the first filename as a full path. - // The function returns the number of characters copied, not including the terminating zero. - // If the buffer is NULL, the function returns the required size, in characters, including the terminating zero. - // If the function fails, the return value is zero. - int GetFirstPathName(LPTSTR pBuffer, int nBufLen) const - { - LPCTSTR pStr = GetFirstFileName(); - int nLengthDir = GetDirectory(NULL, 0); - if((pStr == NULL) || (nLengthDir == 0)) - return 0; - - // Figure out the required length. - int nLengthTotal = nLengthDir + lstrlen(pStr); - - int nRet = 0; - if(pBuffer == NULL) // If the buffer is NULL, return the required length - { - nRet = nLengthTotal + 1; - } - else if (nBufLen > nLengthTotal) // If the buffer is big enough, go ahead and construct the path - { - GetDirectory(pBuffer, nBufLen); - SecureHelper::strcat_x(pBuffer, nBufLen, _T("\\")); - SecureHelper::strcat_x(pBuffer, nBufLen, pStr); - nRet = nLengthTotal; - } - - return nRet; - } - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - bool GetFirstPathName(_CSTRING_NS::CString& strPath) const - { - bool bRet = false; - - int nLength = GetFirstPathName(NULL, 0); - if (nLength > 0) - { - bRet = (GetFirstPathName(strPath.GetBuffer(nLength), nLength) > 0); - strPath.ReleaseBuffer(nLength - 1); - } - - return bRet; - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - - // Get the next filename as a full path. - // The function returns the number of characters copied, not including the terminating zero. - // If the buffer is NULL, the function returns the required size, in characters, including the terminating zero. - // If the function fails, the return value is zero. - // The internal position marker is moved forward only if the function succeeds and the buffer was large enough. - int GetNextPathName(LPTSTR pBuffer, int nBufLen) const - { - if (m_pNextFile == NULL) - return 0; - - int nRet = 0; - LPCTSTR pStr = m_pNextFile; - // Does the filename contain a backslash? - if (_strrchr(pStr, _T('\\')) != NULL) - { - // Yes, so we'll assume it's a full path. - int nLength = lstrlen(pStr); - - if (pBuffer == NULL) // If the buffer is NULL, return the required length - { - nRet = nLength + 1; - } - else if (nBufLen > nLength) // The buffer is big enough, so go ahead and copy the filename - { - SecureHelper::strcpy_x(pBuffer, nBufLen, GetNextFileName()); - nRet = nBufLen; - } - } - else - { - // The filename is relative, so construct the full path. - int nLengthDir = GetDirectory(NULL, 0); - if (nLengthDir > 0) - { - // Calculate the required space. - int nLengthTotal = nLengthDir + lstrlen(pStr); - - if(pBuffer == NULL) // If the buffer is NULL, return the required length - { - nRet = nLengthTotal + 1; - } - else if (nBufLen > nLengthTotal) // If the buffer is big enough, go ahead and construct the path - { - GetDirectory(pBuffer, nBufLen); - SecureHelper::strcat_x(pBuffer, nBufLen, _T("\\")); - SecureHelper::strcat_x(pBuffer, nBufLen, GetNextFileName()); - nRet = nLengthTotal; - } - } - } - - return nRet; - } - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - bool GetNextPathName(_CSTRING_NS::CString& strPath) const - { - bool bRet = false; - - int nLength = GetNextPathName(NULL, 0); - if (nLength > 0) - { - bRet = (GetNextPathName(strPath.GetBuffer(nLength), nLength) > 0); - strPath.ReleaseBuffer(nLength - 1); - } - - return bRet; - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - -// Implementation - bool ResizeFilenameBuffer(DWORD dwLength) - { - if (dwLength > m_ofn.nMaxFile) - { - // Free the old buffer. - if (m_ofn.lpstrFile != m_szFileName) - { - delete[] m_ofn.lpstrFile; - m_ofn.lpstrFile = NULL; - m_ofn.nMaxFile = 0; - } - - // Allocate the new buffer. - LPTSTR lpstrBuff = NULL; - ATLTRY(lpstrBuff = new TCHAR[dwLength]); - if (lpstrBuff != NULL) - { - m_ofn.lpstrFile = lpstrBuff; - m_ofn.lpstrFile[0] = 0; - m_ofn.nMaxFile = dwLength; - } - } - - return (m_ofn.lpstrFile != NULL); - } - - void OnSelChange(LPOFNOTIFY /*lpon*/) - { -#ifndef _UNICODE - // There is no point resizing the buffer in ANSI builds running on NT. - if (m_bIsNT) - return; -#endif - - // Get the buffer length required to hold the spec. - int nLength = GetSpec(NULL, 0); - if (nLength <= 1) - return; // no files are selected, presumably - - // Add room for the directory, and an extra terminating zero. - nLength += GetFolderPath(NULL, 0) + 1; - - if (!ResizeFilenameBuffer(nLength)) - { - ATLASSERT(FALSE); - return; - } - - // If we are not following links then our work is done. - if ((m_ofn.Flags & OFN_NODEREFERENCELINKS) != 0) - return; - - // Get the file spec, which is the text in the edit control. - if (GetSpec(m_ofn.lpstrFile, m_ofn.nMaxFile) <= 0) - return; - - // Get the ID-list of the current folder. - int nBytes = GetFolderIDList(NULL, 0); - CTempBuffer idlist; - idlist.AllocateBytes(nBytes); - if ((nBytes <= 0) || (GetFolderIDList(idlist, nBytes) <= 0)) - return; - - // First bind to the desktop folder, then to the current folder. - ATL::CComPtr pDesktop, pFolder; - if (FAILED(::SHGetDesktopFolder(&pDesktop))) - return; - if (FAILED(pDesktop->BindToObject(idlist, NULL, IID_IShellFolder, (void**)&pFolder))) - return; - - // Work through the file spec, looking for quoted filenames. If we find a shortcut file, then - // we need to add enough extra buffer space to hold its target path. - DWORD nExtraChars = 0; - bool bInsideQuotes = false; - LPCTSTR pAnchor = m_ofn.lpstrFile; - LPCTSTR pChar = m_ofn.lpstrFile; - for ( ; *pChar; ++pChar) - { - // Look for quotation marks. - if (*pChar == _T('\"')) - { - // We are either entering or leaving a passage of quoted text. - bInsideQuotes = !bInsideQuotes; - - // Is it an opening or closing quote? - if (bInsideQuotes) - { - // We found an opening quote, so set "pAnchor" to the following character. - pAnchor = pChar + 1; - } - else // closing quote - { - // Each quoted entity should be shorter than MAX_PATH. - if (pChar - pAnchor >= MAX_PATH) - return; - - // Get the ID-list and attributes of the file. - USES_CONVERSION; - int nFileNameLength = (int)(DWORD_PTR)(pChar - pAnchor); - TCHAR szFileName[MAX_PATH]; - SecureHelper::strncpy_x(szFileName, MAX_PATH, pAnchor, nFileNameLength); - LPITEMIDLIST pidl = NULL; - DWORD dwAttrib = SFGAO_LINK; - if (SUCCEEDED(pFolder->ParseDisplayName(NULL, NULL, T2W(szFileName), NULL, &pidl, &dwAttrib))) - { - // Is it a shortcut file? - if (dwAttrib & SFGAO_LINK) - { - // Bind to its IShellLink interface. - ATL::CComPtr pLink; - if (SUCCEEDED(pFolder->BindToObject(pidl, NULL, IID_IShellLink, (void**)&pLink))) - { - // Get the shortcut's target path. - TCHAR szPath[MAX_PATH]; - if (SUCCEEDED(pLink->GetPath(szPath, MAX_PATH, NULL, 0))) - { - // If the target path is longer than the shortcut name, then add on the number - // of extra characters that are required. - int nNewLength = lstrlen(szPath); - if (nNewLength > nFileNameLength) - nExtraChars += nNewLength - nFileNameLength; - } - } - } - - // Free the ID-list returned by ParseDisplayName. - ::CoTaskMemFree(pidl); - } - } - } - } - - // If we need more space for shortcut targets, then reallocate. - if (nExtraChars > 0) - ATLVERIFY(ResizeFilenameBuffer(m_ofn.nMaxFile + nExtraChars)); - } - - // Helper for _ATL_MIN_CRT - static const TCHAR* _strrchr(const TCHAR* p, TCHAR ch) - { -#ifndef _ATL_MIN_CRT - return _tcsrchr(p, ch); -#else // _ATL_MIN_CRT - const TCHAR* lpsz = NULL; - while (*p != 0) - { - if (*p == ch) - lpsz = p; - p = ::CharNext(p); - } - return lpsz; -#endif // _ATL_MIN_CRT - } -}; - -class CMultiFileDialog : public CMultiFileDialogImpl -{ -public: - CMultiFileDialog( - LPCTSTR lpszDefExt = NULL, - LPCTSTR lpszFileName = NULL, - DWORD dwFlags = OFN_HIDEREADONLY, - LPCTSTR lpszFilter = NULL, - HWND hWndParent = NULL) - : CMultiFileDialogImpl(lpszDefExt, lpszFileName, dwFlags, lpszFilter, hWndParent) - { } - - BEGIN_MSG_MAP(CMultiFileDialog) - CHAIN_MSG_MAP(CMultiFileDialogImpl) - END_MSG_MAP() -}; - -#endif // !_WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// Shell File Dialog - new Shell File Open and Save dialogs in Vista - -// Note: Use GetPtr() to access dialog interface methods. -// Example: -// CShellFileOpenDialog dlg; -// dlg.GetPtr()->SetTitle(L"MyFileOpenDialog"); - -#if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) - -/////////////////////////////////////////////////////////////////////////////// -// CShellFileDialogImpl - base class for CShellFileOpenDialogImpl and CShellFileSaveDialogImpl - -template -class ATL_NO_VTABLE CShellFileDialogImpl : public IFileDialogEvents -{ -public: -// Operations - INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) - { - INT_PTR nRet = -1; - - T* pT = static_cast(this); - if(pT->m_spFileDlg == NULL) - { - ATLASSERT(FALSE); - return nRet; - } - - DWORD dwCookie = 0; - pT->_Advise(dwCookie); - - HRESULT hRet = pT->m_spFileDlg->Show(hWndParent); - if(SUCCEEDED(hRet)) - nRet = IDOK; - else if(hRet == HRESULT_FROM_WIN32(ERROR_CANCELLED)) - nRet = IDCANCEL; - else - ATLASSERT(FALSE); // error - - pT->_Unadvise(dwCookie); - - return nRet; - } - - bool IsNull() const - { - const T* pT = static_cast(this); - return (pT->m_spFileDlg == NULL); - } - -// Operations - get file path after dialog returns - HRESULT GetFilePath(LPWSTR lpstrFilePath, int cchLength) - { - T* pT = static_cast(this); - ATLASSERT(pT->m_spFileDlg != NULL); - - ATL::CComPtr spItem; - HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem); - - if(SUCCEEDED(hRet)) - hRet = GetFileNameFromShellItem(spItem, SIGDN_FILESYSPATH, lpstrFilePath, cchLength); - - return hRet; - } - - HRESULT GetFileTitle(LPWSTR lpstrFileTitle, int cchLength) - { - T* pT = static_cast(this); - ATLASSERT(pT->m_spFileDlg != NULL); - - ATL::CComPtr spItem; - HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem); - - if(SUCCEEDED(hRet)) - hRet = GetFileNameFromShellItem(spItem, SIGDN_NORMALDISPLAY, lpstrFileTitle, cchLength); - - return hRet; - } - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - HRESULT GetFilePath(_CSTRING_NS::CString& strFilePath) - { - T* pT = static_cast(this); - ATLASSERT(pT->m_spFileDlg != NULL); - - ATL::CComPtr spItem; - HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem); - - if(SUCCEEDED(hRet)) - hRet = GetFileNameFromShellItem(spItem, SIGDN_FILESYSPATH, strFilePath); - - return hRet; - } - - HRESULT GetFileTitle(_CSTRING_NS::CString& strFileTitle) - { - T* pT = static_cast(this); - ATLASSERT(pT->m_spFileDlg != NULL); - - ATL::CComPtr spItem; - HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem); - - if(SUCCEEDED(hRet)) - hRet = GetFileNameFromShellItem(spItem, SIGDN_NORMALDISPLAY, strFileTitle); - - return hRet; - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - -// Helpers for IShellItem - static HRESULT GetFileNameFromShellItem(IShellItem* pShellItem, SIGDN type, LPWSTR lpstr, int cchLength) - { - ATLASSERT(pShellItem != NULL); - - LPWSTR lpstrName = NULL; - HRESULT hRet = pShellItem->GetDisplayName(type, &lpstrName); - - if(SUCCEEDED(hRet)) - { - if(lstrlenW(lpstrName) < cchLength) - { - SecureHelper::strcpyW_x(lpstr, cchLength, lpstrName); - } - else - { - ATLASSERT(FALSE); - hRet = DISP_E_BUFFERTOOSMALL; - } - - ::CoTaskMemFree(lpstrName); - } - - return hRet; - } - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - static HRESULT GetFileNameFromShellItem(IShellItem* pShellItem, SIGDN type, _CSTRING_NS::CString& str) - { - ATLASSERT(pShellItem != NULL); - - LPWSTR lpstrName = NULL; - HRESULT hRet = pShellItem->GetDisplayName(type, &lpstrName); - - if(SUCCEEDED(hRet)) - { - str = lpstrName; - ::CoTaskMemFree(lpstrName); - } - - return hRet; - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - -// Implementation - void _Advise(DWORD& dwCookie) - { - T* pT = static_cast(this); - ATLASSERT(pT->m_spFileDlg != NULL); - HRESULT hRet = pT->m_spFileDlg->Advise((IFileDialogEvents*)this, &dwCookie); - ATLVERIFY(SUCCEEDED(hRet)); - } - - void _Unadvise(DWORD dwCookie) - { - T* pT = static_cast(this); - ATLASSERT(pT->m_spFileDlg != NULL); - HRESULT hRet = pT->m_spFileDlg->Unadvise(dwCookie); - ATLVERIFY(SUCCEEDED(hRet)); - } - - void _Init(LPCWSTR lpszFileName, DWORD dwOptions, LPCWSTR lpszDefExt, const COMDLG_FILTERSPEC* arrFilterSpec, UINT uFilterSpecCount) - { - T* pT = static_cast(this); - ATLASSERT(pT->m_spFileDlg != NULL); - - HRESULT hRet = E_FAIL; - - if(lpszFileName != NULL) - { - hRet = pT->m_spFileDlg->SetFileName(lpszFileName); - ATLASSERT(SUCCEEDED(hRet)); - } - - hRet = pT->m_spFileDlg->SetOptions(dwOptions); - ATLASSERT(SUCCEEDED(hRet)); - - if(lpszDefExt != NULL) - { - hRet = pT->m_spFileDlg->SetDefaultExtension(lpszDefExt); - ATLASSERT(SUCCEEDED(hRet)); - } - - if(arrFilterSpec != NULL && uFilterSpecCount != 0U) - { - hRet = pT->m_spFileDlg->SetFileTypes(uFilterSpecCount, arrFilterSpec); - ATLASSERT(SUCCEEDED(hRet)); - } - } - -// Implementation - IUnknown interface - STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject) - { - if(ppvObject == NULL) - return E_POINTER; - - T* pT = static_cast(this); - if(IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IFileDialogEvents)) - { - *ppvObject = (IFileDialogEvents*)pT; - // AddRef() not needed - return S_OK; - } - - return E_NOINTERFACE; - } - - virtual ULONG STDMETHODCALLTYPE AddRef() - { - return 1; - } - - virtual ULONG STDMETHODCALLTYPE Release() - { - return 1; - } - -// Implementation - IFileDialogEvents interface - virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFileOk(IFileDialog* pfd) - { - T* pT = static_cast(this); - ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); - pfd; // avoid level 4 warning - return pT->OnFileOk(); - } - - virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFolderChanging(IFileDialog* pfd, IShellItem* psiFolder) - { - T* pT = static_cast(this); - ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); - pfd; // avoid level 4 warning - return pT->OnFolderChanging(psiFolder); - } - - virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFolderChange(IFileDialog* pfd) - { - T* pT = static_cast(this); - ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); - pfd; // avoid level 4 warning - return pT->OnFolderChange(); - } - - virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnSelectionChange(IFileDialog* pfd) - { - T* pT = static_cast(this); - ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); - pfd; // avoid level 4 warning - return pT->OnSelectionChange(); - } - - virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnShareViolation(IFileDialog* pfd, IShellItem* psi, FDE_SHAREVIOLATION_RESPONSE* pResponse) - { - T* pT = static_cast(this); - ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); - pfd; // avoid level 4 warning - return pT->OnShareViolation(psi, pResponse); - } - - virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnTypeChange(IFileDialog* pfd) - { - T* pT = static_cast(this); - ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); - pfd; // avoid level 4 warning - return pT->OnTypeChange(); - } - - virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnOverwrite(IFileDialog* pfd, IShellItem* psi, FDE_OVERWRITE_RESPONSE* pResponse) - { - T* pT = static_cast(this); - ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); - pfd; // avoid level 4 warning - return pT->OnOverwrite(psi, pResponse); - } - -// Overrideables - Event handlers - HRESULT OnFileOk() - { - return E_NOTIMPL; - } - - HRESULT OnFolderChanging(IShellItem* /*psiFolder*/) - { - return E_NOTIMPL; - } - - HRESULT OnFolderChange() - { - return E_NOTIMPL; - } - - HRESULT OnSelectionChange() - { - return E_NOTIMPL; - } - - HRESULT OnShareViolation(IShellItem* /*psi*/, FDE_SHAREVIOLATION_RESPONSE* /*pResponse*/) - { - return E_NOTIMPL; - } - - HRESULT OnTypeChange() - { - return E_NOTIMPL; - } - - HRESULT OnOverwrite(IShellItem* /*psi*/, FDE_OVERWRITE_RESPONSE* /*pResponse*/) - { - return E_NOTIMPL; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CShellFileOpenDialogImpl - implements new Shell File Open dialog - -template -class ATL_NO_VTABLE CShellFileOpenDialogImpl : public CShellFileDialogImpl< T > -{ -public: - ATL::CComPtr m_spFileDlg; - - CShellFileOpenDialogImpl(LPCWSTR lpszFileName = NULL, - DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST, - LPCWSTR lpszDefExt = NULL, - const COMDLG_FILTERSPEC* arrFilterSpec = NULL, - UINT uFilterSpecCount = 0U) - { - HRESULT hRet = m_spFileDlg.CoCreateInstance(CLSID_FileOpenDialog); - - if(SUCCEEDED(hRet)) - _Init(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount); - } - - IFileOpenDialog* GetPtr() - { - return m_spFileDlg; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CShellFileOpenDialog - new Shell File Open dialog without events - -class CShellFileOpenDialog : public CShellFileOpenDialogImpl -{ -public: - CShellFileOpenDialog(LPCWSTR lpszFileName = NULL, - DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST, - LPCWSTR lpszDefExt = NULL, - const COMDLG_FILTERSPEC* arrFilterSpec = NULL, - UINT uFilterSpecCount = 0U) : CShellFileOpenDialogImpl(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount) - { } - -// Implementation (remove _Advise/_Unadvise code using template magic) - void _Advise(DWORD& /*dwCookie*/) - { } - - void _Unadvise(DWORD /*dwCookie*/) - { } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CShellFileSaveDialogImpl - implements new Shell File Save dialog - -template -class ATL_NO_VTABLE CShellFileSaveDialogImpl : public CShellFileDialogImpl< T > -{ -public: - ATL::CComPtr m_spFileDlg; - - CShellFileSaveDialogImpl(LPCWSTR lpszFileName = NULL, - DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT, - LPCWSTR lpszDefExt = NULL, - const COMDLG_FILTERSPEC* arrFilterSpec = NULL, - UINT uFilterSpecCount = 0U) - { - HRESULT hRet = m_spFileDlg.CoCreateInstance(CLSID_FileSaveDialog); - - if(SUCCEEDED(hRet)) - _Init(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount); - } - - IFileSaveDialog* GetPtr() - { - return m_spFileDlg; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CShellFileSaveDialog - new Shell File Save dialog without events - -class CShellFileSaveDialog : public CShellFileSaveDialogImpl -{ -public: - CShellFileSaveDialog(LPCWSTR lpszFileName = NULL, - DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT, - LPCWSTR lpszDefExt = NULL, - const COMDLG_FILTERSPEC* arrFilterSpec = NULL, - UINT uFilterSpecCount = 0U) : CShellFileSaveDialogImpl(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount) - { } - -// Implementation (remove _Advise/_Unadvise code using template magic) - void _Advise(DWORD& /*dwCookie*/) - { } - - void _Unadvise(DWORD /*dwCookie*/) - { } -}; - -#endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) - - -/////////////////////////////////////////////////////////////////////////////// -// CFolderDialogImpl - used for browsing for a folder - -#ifndef _WIN32_WCE - -template -class ATL_NO_VTABLE CFolderDialogImpl -{ -public: - BROWSEINFO m_bi; - LPCTSTR m_lpstrInitialFolder; - LPCITEMIDLIST m_pidlInitialSelection; - bool m_bExpandInitialSelection; - TCHAR m_szFolderDisplayName[MAX_PATH]; - TCHAR m_szFolderPath[MAX_PATH]; - LPITEMIDLIST m_pidlSelected; - HWND m_hWnd; // used only in the callback function - -// Constructor - CFolderDialogImpl(HWND hWndParent = NULL, LPCTSTR lpstrTitle = NULL, UINT uFlags = BIF_RETURNONLYFSDIRS) : - m_lpstrInitialFolder(NULL), m_pidlInitialSelection(NULL), m_bExpandInitialSelection(false), m_pidlSelected(NULL), m_hWnd(NULL) - { - memset(&m_bi, 0, sizeof(m_bi)); // initialize structure to 0/NULL - - m_bi.hwndOwner = hWndParent; - m_bi.pidlRoot = NULL; - m_bi.pszDisplayName = m_szFolderDisplayName; - m_bi.lpszTitle = lpstrTitle; - m_bi.ulFlags = uFlags; - m_bi.lpfn = BrowseCallbackProc; - m_bi.lParam = (LPARAM)static_cast(this); - - m_szFolderPath[0] = 0; - m_szFolderDisplayName[0] = 0; - } - - ~CFolderDialogImpl() - { - ::CoTaskMemFree(m_pidlSelected); - } - -// Operations - INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) - { - if(m_bi.hwndOwner == NULL) // set only if not specified before - m_bi.hwndOwner = hWndParent; - - // Clear out any previous results - m_szFolderPath[0] = 0; - m_szFolderDisplayName[0] = 0; - ::CoTaskMemFree(m_pidlSelected); - - INT_PTR nRet = IDCANCEL; - m_pidlSelected = ::SHBrowseForFolder(&m_bi); - - if(m_pidlSelected != NULL) - { - nRet = IDOK; - - // If BIF_RETURNONLYFSDIRS is set, we try to get the filesystem path. - // Otherwise, the caller must handle the ID-list directly. - if((m_bi.ulFlags & BIF_RETURNONLYFSDIRS) != 0) - { - if(::SHGetPathFromIDList(m_pidlSelected, m_szFolderPath) == FALSE) - nRet = IDCANCEL; - } - } - - return nRet; - } - - // Methods to call before DoModal - void SetInitialFolder(LPCTSTR lpstrInitialFolder, bool bExpand = true) - { - // lpstrInitialFolder may be a file if BIF_BROWSEINCLUDEFILES is specified - m_lpstrInitialFolder = lpstrInitialFolder; - m_bExpandInitialSelection = bExpand; - } - - void SetInitialSelection(LPCITEMIDLIST pidl, bool bExpand = true) - { - m_pidlInitialSelection = pidl; - m_bExpandInitialSelection = bExpand; - } - - // Methods to call after DoModal - LPITEMIDLIST GetSelectedItem(bool bDetach = false) - { - LPITEMIDLIST pidl = m_pidlSelected; - if(bDetach) - m_pidlSelected = NULL; - - return pidl; - } - - LPCTSTR GetFolderPath() const - { - return m_szFolderPath; - } - - LPCTSTR GetFolderDisplayName() const - { - return m_szFolderDisplayName; - } - - int GetFolderImageIndex() const - { - return m_bi.iImage; - } - -// Callback function and overrideables - static int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData) - { -#ifndef BFFM_VALIDATEFAILED - #ifdef UNICODE - const int BFFM_VALIDATEFAILED = 4; - #else - const int BFFM_VALIDATEFAILED = 3; - #endif -#endif // !BFFM_VALIDATEFAILED -#ifndef BFFM_IUNKNOWN - const int BFFM_IUNKNOWN = 5; -#endif // !BFFM_IUNKNOWN -#ifndef BIF_NEWDIALOGSTYLE - const UINT BIF_NEWDIALOGSTYLE = 0x0040; -#endif // !BIF_NEWDIALOGSTYLE - - int nRet = 0; - T* pT = (T*)lpData; - bool bClear = false; - if(pT->m_hWnd == NULL) - { - pT->m_hWnd = hWnd; - bClear = true; - } - else - { - ATLASSERT(pT->m_hWnd == hWnd); - } - - switch(uMsg) - { - case BFFM_INITIALIZED: - // Set initial selection - // Note that m_pidlInitialSelection, if set, takes precedence over m_lpstrInitialFolder - if(pT->m_pidlInitialSelection != NULL) - pT->SetSelection(pT->m_pidlInitialSelection); - else if(pT->m_lpstrInitialFolder != NULL) - pT->SetSelection(pT->m_lpstrInitialFolder); - - // Expand initial selection if appropriate - if(pT->m_bExpandInitialSelection && ((pT->m_bi.ulFlags & BIF_NEWDIALOGSTYLE) != 0)) - { - if(pT->m_pidlInitialSelection != NULL) - pT->SetExpanded(pT->m_pidlInitialSelection); - else if(pT->m_lpstrInitialFolder != NULL) - pT->SetExpanded(pT->m_lpstrInitialFolder); - } - pT->OnInitialized(); - break; - case BFFM_SELCHANGED: - pT->OnSelChanged((LPITEMIDLIST)lParam); - break; - case BFFM_VALIDATEFAILED: - nRet = pT->OnValidateFailed((LPCTSTR)lParam); - break; - case BFFM_IUNKNOWN: - pT->OnIUnknown((IUnknown*)lParam); - break; - default: - ATLTRACE2(atlTraceUI, 0, _T("Unknown message received in CFolderDialogImpl::BrowseCallbackProc\n")); - break; - } - - if(bClear) - pT->m_hWnd = NULL; - return nRet; - } - - void OnInitialized() - { - } - - void OnSelChanged(LPITEMIDLIST /*pItemIDList*/) - { - } - - int OnValidateFailed(LPCTSTR /*lpstrFolderPath*/) - { - return 1; // 1=continue, 0=EndDialog - } - - void OnIUnknown(IUnknown* /*pUnknown*/) - { - } - - // Commands - valid to call only from handlers - void EnableOK(BOOL bEnable) - { - ATLASSERT(m_hWnd != NULL); - ::SendMessage(m_hWnd, BFFM_ENABLEOK, 0, bEnable); - } - - void SetSelection(LPCITEMIDLIST pItemIDList) - { - ATLASSERT(m_hWnd != NULL); - ::SendMessage(m_hWnd, BFFM_SETSELECTION, FALSE, (LPARAM)pItemIDList); - } - - void SetSelection(LPCTSTR lpstrFolderPath) - { - ATLASSERT(m_hWnd != NULL); - ::SendMessage(m_hWnd, BFFM_SETSELECTION, TRUE, (LPARAM)lpstrFolderPath); - } - - void SetStatusText(LPCTSTR lpstrText) - { - ATLASSERT(m_hWnd != NULL); - ::SendMessage(m_hWnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)lpstrText); - } - - void SetOKText(LPCTSTR lpstrOKText) - { -#ifndef BFFM_SETOKTEXT - const UINT BFFM_SETOKTEXT = WM_USER + 105; -#endif - ATLASSERT(m_hWnd != NULL); - USES_CONVERSION; - LPCWSTR lpstr = T2CW(lpstrOKText); - ::SendMessage(m_hWnd, BFFM_SETOKTEXT, 0, (LPARAM)lpstr); - } - - void SetExpanded(LPCITEMIDLIST pItemIDList) - { -#ifndef BFFM_SETEXPANDED - const UINT BFFM_SETEXPANDED = WM_USER + 106; -#endif - ATLASSERT(m_hWnd != NULL); - ::SendMessage(m_hWnd, BFFM_SETEXPANDED, FALSE, (LPARAM)pItemIDList); - } - - void SetExpanded(LPCTSTR lpstrFolderPath) - { -#ifndef BFFM_SETEXPANDED - const UINT BFFM_SETEXPANDED = WM_USER + 106; -#endif - ATLASSERT(m_hWnd != NULL); - USES_CONVERSION; - LPCWSTR lpstr = T2CW(lpstrFolderPath); - ::SendMessage(m_hWnd, BFFM_SETEXPANDED, TRUE, (LPARAM)lpstr); - } -}; - -class CFolderDialog : public CFolderDialogImpl -{ -public: - CFolderDialog(HWND hWndParent = NULL, LPCTSTR lpstrTitle = NULL, UINT uFlags = BIF_RETURNONLYFSDIRS) - : CFolderDialogImpl(hWndParent, lpstrTitle, uFlags) - { } -}; - -#endif // !_WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CCommonDialogImplBase - base class for common dialog classes - -class ATL_NO_VTABLE CCommonDialogImplBase : public ATL::CWindowImplBase -{ -public: - static UINT_PTR APIENTRY HookProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) - { - if(uMsg != WM_INITDIALOG) - return 0; - CCommonDialogImplBase* pT = (CCommonDialogImplBase*)ModuleHelper::ExtractCreateWndData(); - ATLASSERT(pT != NULL); - ATLASSERT(pT->m_hWnd == NULL); - ATLASSERT(::IsWindow(hWnd)); - // subclass dialog's window - if(!pT->SubclassWindow(hWnd)) - { - ATLTRACE2(atlTraceUI, 0, _T("Subclassing a common dialog failed\n")); - return 0; - } - // check message map for WM_INITDIALOG handler - LRESULT lRes = 0; - if(pT->ProcessWindowMessage(pT->m_hWnd, uMsg, wParam, lParam, lRes, 0) == FALSE) - return 0; - return lRes; - } - -// Special override for common dialogs - BOOL EndDialog(INT_PTR /*nRetCode*/ = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - SendMessage(WM_COMMAND, MAKEWPARAM(IDABORT, 0)); - return TRUE; - } - -// Implementation - try to override these, to prevent errors - HWND Create(HWND, ATL::_U_RECT, LPCTSTR, DWORD, DWORD, ATL::_U_MENUorID, ATOM, LPVOID) - { - ATLASSERT(FALSE); // should not be called - return NULL; - } - - static LRESULT CALLBACK StartWindowProc(HWND /*hWnd*/, UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/) - { - ATLASSERT(FALSE); // should not be called - return 0; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CFontDialogImpl - font selection dialog - -#ifndef _WIN32_WCE - -template -class ATL_NO_VTABLE CFontDialogImpl : public CCommonDialogImplBase -{ -public: - enum { _cchStyleName = 64 }; - - CHOOSEFONT m_cf; - TCHAR m_szStyleName[_cchStyleName]; // contains style name after return - LOGFONT m_lf; // default LOGFONT to store the info - -// Constructors - CFontDialogImpl(LPLOGFONT lplfInitial = NULL, - DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS, - HDC hDCPrinter = NULL, - HWND hWndParent = NULL) - { - memset(&m_cf, 0, sizeof(m_cf)); - memset(&m_lf, 0, sizeof(m_lf)); - memset(&m_szStyleName, 0, sizeof(m_szStyleName)); - - m_cf.lStructSize = sizeof(m_cf); - m_cf.hwndOwner = hWndParent; - m_cf.rgbColors = RGB(0, 0, 0); - m_cf.lpszStyle = (LPTSTR)&m_szStyleName; - m_cf.Flags = dwFlags | CF_ENABLEHOOK; - m_cf.lpfnHook = (LPCFHOOKPROC)T::HookProc; - - if(lplfInitial != NULL) - { - m_cf.lpLogFont = lplfInitial; - m_cf.Flags |= CF_INITTOLOGFONTSTRUCT; - m_lf = *lplfInitial; - } - else - { - m_cf.lpLogFont = &m_lf; - } - - if(hDCPrinter != NULL) - { - m_cf.hDC = hDCPrinter; - m_cf.Flags |= CF_PRINTERFONTS; - } - } - -// Operations - INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) - { - ATLASSERT((m_cf.Flags & CF_ENABLEHOOK) != 0); - ATLASSERT(m_cf.lpfnHook != NULL); // can still be a user hook - - if(m_cf.hwndOwner == NULL) // set only if not specified before - m_cf.hwndOwner = hWndParent; - - ATLASSERT(m_hWnd == NULL); - ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this); - - BOOL bRet = ::ChooseFont(&m_cf); - - m_hWnd = NULL; - - if(bRet) // copy logical font from user's initialization buffer (if needed) - SecureHelper::memcpy_x(&m_lf, sizeof(m_lf), m_cf.lpLogFont, sizeof(m_lf)); - - return bRet ? IDOK : IDCANCEL; - } - - // works only when the dialog is dislayed or after - void GetCurrentFont(LPLOGFONT lplf) const - { - ATLASSERT(lplf != NULL); - - if(m_hWnd != NULL) - ::SendMessage(m_hWnd, WM_CHOOSEFONT_GETLOGFONT, 0, (LPARAM)lplf); - else - *lplf = m_lf; - } - - // works only when the dialog is dislayed or before -#ifndef _WIN32_WCE - void SetLogFont(LPLOGFONT lplf) - { - ATLASSERT(lplf != NULL); -#ifndef WM_CHOOSEFONT_SETLOGFONT - const UINT WM_CHOOSEFONT_SETLOGFONT = (WM_USER + 101); -#endif - if(m_hWnd != NULL) - { - ::SendMessage(m_hWnd, WM_CHOOSEFONT_SETLOGFONT, 0, (LPARAM)lplf); - } - else - { - m_lf = *lplf; - m_cf.Flags |= CF_INITTOLOGFONTSTRUCT; - } - } - - void SetFlags(DWORD dwFlags) - { -#ifndef WM_CHOOSEFONT_SETFLAGS - const UINT WM_CHOOSEFONT_SETFLAGS = (WM_USER + 102); -#endif - if(m_hWnd != NULL) - { - CHOOSEFONT cf = { sizeof(CHOOSEFONT) }; - cf.Flags = dwFlags; - ::SendMessage(m_hWnd, WM_CHOOSEFONT_SETFLAGS, 0, (LPARAM)&cf); - } - else - { - m_cf.Flags = dwFlags; - } - } -#endif // !_WIN32_WCE - - // Helpers for parsing information after successful return - LPCTSTR GetFaceName() const // return the face name of the font - { - return (LPCTSTR)m_cf.lpLogFont->lfFaceName; - } - - LPCTSTR GetStyleName() const // return the style name of the font - { - return m_cf.lpszStyle; - } - - int GetSize() const // return the pt size of the font - { - return m_cf.iPointSize; - } - - COLORREF GetColor() const // return the color of the font - { - return m_cf.rgbColors; - } - - int GetWeight() const // return the chosen font weight - { - return (int)m_cf.lpLogFont->lfWeight; - } - - BOOL IsStrikeOut() const // return TRUE if strikeout - { - return (m_cf.lpLogFont->lfStrikeOut) ? TRUE : FALSE; - } - - BOOL IsUnderline() const // return TRUE if underline - { - return (m_cf.lpLogFont->lfUnderline) ? TRUE : FALSE; - } - - BOOL IsBold() const // return TRUE if bold font - { - return (m_cf.lpLogFont->lfWeight == FW_BOLD) ? TRUE : FALSE; - } - - BOOL IsItalic() const // return TRUE if italic font - { - return m_cf.lpLogFont->lfItalic ? TRUE : FALSE; - } -}; - -class CFontDialog : public CFontDialogImpl -{ -public: - CFontDialog(LPLOGFONT lplfInitial = NULL, - DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS, - HDC hDCPrinter = NULL, - HWND hWndParent = NULL) - : CFontDialogImpl(lplfInitial, dwFlags, hDCPrinter, hWndParent) - { } - - DECLARE_EMPTY_MSG_MAP() -}; - -#endif // _WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CRichEditFontDialogImpl - font selection for the Rich Edit ctrl - -#if defined(_RICHEDIT_) && !defined(_WIN32_WCE) - -template -class ATL_NO_VTABLE CRichEditFontDialogImpl : public CFontDialogImpl< T > -{ -public: - CRichEditFontDialogImpl(const CHARFORMAT& charformat, - DWORD dwFlags = CF_SCREENFONTS, - HDC hDCPrinter = NULL, - HWND hWndParent = NULL) - : CFontDialogImpl< T >(NULL, dwFlags, hDCPrinter, hWndParent) - { - m_cf.Flags |= CF_INITTOLOGFONTSTRUCT; - m_cf.Flags |= FillInLogFont(charformat); - m_cf.lpLogFont = &m_lf; - - if((charformat.dwMask & CFM_COLOR) != 0) - m_cf.rgbColors = charformat.crTextColor; - } - - void GetCharFormat(CHARFORMAT& cf) const - { - USES_CONVERSION; - cf.dwEffects = 0; - cf.dwMask = 0; - if((m_cf.Flags & CF_NOSTYLESEL) == 0) - { - cf.dwMask |= CFM_BOLD | CFM_ITALIC; - cf.dwEffects |= IsBold() ? CFE_BOLD : 0; - cf.dwEffects |= IsItalic() ? CFE_ITALIC : 0; - } - if((m_cf.Flags & CF_NOSIZESEL) == 0) - { - cf.dwMask |= CFM_SIZE; - // GetSize() returns in tenths of points so mulitply by 2 to get twips - cf.yHeight = GetSize() * 2; - } - - if((m_cf.Flags & CF_NOFACESEL) == 0) - { - cf.dwMask |= CFM_FACE; - cf.bPitchAndFamily = m_cf.lpLogFont->lfPitchAndFamily; -#if (_RICHEDIT_VER >= 0x0200) - SecureHelper::strcpy_x(cf.szFaceName, _countof(cf.szFaceName), GetFaceName()); -#else // !(_RICHEDIT_VER >= 0x0200) - SecureHelper::strcpyA_x(cf.szFaceName, _countof(cf.szFaceName), T2A((LPTSTR)(LPCTSTR)GetFaceName())); -#endif // !(_RICHEDIT_VER >= 0x0200) - } - - if((m_cf.Flags & CF_EFFECTS) != 0) - { - cf.dwMask |= CFM_UNDERLINE | CFM_STRIKEOUT | CFM_COLOR; - cf.dwEffects |= IsUnderline() ? CFE_UNDERLINE : 0; - cf.dwEffects |= IsStrikeOut() ? CFE_STRIKEOUT : 0; - cf.crTextColor = GetColor(); - } - if((m_cf.Flags & CF_NOSCRIPTSEL) == 0) - { - cf.bCharSet = m_cf.lpLogFont->lfCharSet; - cf.dwMask |= CFM_CHARSET; - } - cf.yOffset = 0; - } - - DWORD FillInLogFont(const CHARFORMAT& cf) - { - USES_CONVERSION; - DWORD dwFlags = 0; - if((cf.dwMask & CFM_SIZE) != 0) - { - HDC hDC = ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL); - LONG yPerInch = ::GetDeviceCaps(hDC, LOGPIXELSY); - m_lf.lfHeight = -(int)((cf.yHeight * yPerInch) / 1440); - } - else - m_lf.lfHeight = 0; - - m_lf.lfWidth = 0; - m_lf.lfEscapement = 0; - m_lf.lfOrientation = 0; - - if((cf.dwMask & (CFM_ITALIC | CFM_BOLD)) == (CFM_ITALIC | CFM_BOLD)) - { - m_lf.lfWeight = ((cf.dwEffects & CFE_BOLD) != 0) ? FW_BOLD : FW_NORMAL; - m_lf.lfItalic = (BYTE)(((cf.dwEffects & CFE_ITALIC) != 0) ? TRUE : FALSE); - } - else - { - dwFlags |= CF_NOSTYLESEL; - m_lf.lfWeight = FW_DONTCARE; - m_lf.lfItalic = FALSE; - } - - if((cf.dwMask & (CFM_UNDERLINE | CFM_STRIKEOUT | CFM_COLOR)) == (CFM_UNDERLINE|CFM_STRIKEOUT|CFM_COLOR)) - { - dwFlags |= CF_EFFECTS; - m_lf.lfUnderline = (BYTE)(((cf.dwEffects & CFE_UNDERLINE) != 0) ? TRUE : FALSE); - m_lf.lfStrikeOut = (BYTE)(((cf.dwEffects & CFE_STRIKEOUT) != 0) ? TRUE : FALSE); - } - else - { - m_lf.lfUnderline = (BYTE)FALSE; - m_lf.lfStrikeOut = (BYTE)FALSE; - } - - if((cf.dwMask & CFM_CHARSET) != 0) - m_lf.lfCharSet = cf.bCharSet; - else - dwFlags |= CF_NOSCRIPTSEL; - m_lf.lfOutPrecision = OUT_DEFAULT_PRECIS; - m_lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; - m_lf.lfQuality = DEFAULT_QUALITY; - if((cf.dwMask & CFM_FACE) != 0) - { - m_lf.lfPitchAndFamily = cf.bPitchAndFamily; -#if (_RICHEDIT_VER >= 0x0200) - SecureHelper::strcpy_x(m_lf.lfFaceName, _countof(m_lf.lfFaceName), cf.szFaceName); -#else // !(_RICHEDIT_VER >= 0x0200) - SecureHelper::strcpy_x(m_lf.lfFaceName, _countof(m_lf.lfFaceName), A2T((LPSTR)cf.szFaceName)); -#endif // !(_RICHEDIT_VER >= 0x0200) - } - else - { - m_lf.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE; - m_lf.lfFaceName[0] = (TCHAR)0; - } - return dwFlags; - } -}; - -class CRichEditFontDialog : public CRichEditFontDialogImpl -{ -public: - CRichEditFontDialog(const CHARFORMAT& charformat, - DWORD dwFlags = CF_SCREENFONTS, - HDC hDCPrinter = NULL, - HWND hWndParent = NULL) - : CRichEditFontDialogImpl(charformat, dwFlags, hDCPrinter, hWndParent) - { } - - DECLARE_EMPTY_MSG_MAP() -}; - -#endif // defined(_RICHEDIT_) && !defined(_WIN32_WCE) - - -/////////////////////////////////////////////////////////////////////////////// -// CColorDialogImpl - color selection - -#if !defined(_WIN32_WCE) || ((_WIN32_WCE > 420) && !(defined(WIN32_PLATFORM_WFSP) && (_WIN32_WCE > 0x0500))) - -#ifdef _WIN32_WCE - #pragma comment(lib, "commdlg.lib") - - #ifndef SETRGBSTRING - #define SETRGBSTRING _T("commdlg_SetRGBColor") - #endif - - #ifndef COLOROKSTRING - #define COLOROKSTRING _T("commdlg_ColorOK") - #endif -#endif - -template -class ATL_NO_VTABLE CColorDialogImpl : public CCommonDialogImplBase -{ -public: - CHOOSECOLOR m_cc; - -// Constructor - CColorDialogImpl(COLORREF clrInit = 0, DWORD dwFlags = 0, HWND hWndParent = NULL) - { - memset(&m_cc, 0, sizeof(m_cc)); - - m_cc.lStructSize = sizeof(m_cc); - m_cc.lpCustColors = GetCustomColors(); - m_cc.hwndOwner = hWndParent; - m_cc.Flags = dwFlags | CC_ENABLEHOOK; - m_cc.lpfnHook = (LPCCHOOKPROC)T::HookProc; - - if(clrInit != 0) - { - m_cc.rgbResult = clrInit; - m_cc.Flags |= CC_RGBINIT; - } - } - -// Operations - INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) - { - ATLASSERT((m_cc.Flags & CC_ENABLEHOOK) != 0); - ATLASSERT(m_cc.lpfnHook != NULL); // can still be a user hook - - if(m_cc.hwndOwner == NULL) // set only if not specified before - m_cc.hwndOwner = hWndParent; - - ATLASSERT(m_hWnd == NULL); - ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this); - - BOOL bRet = ::ChooseColor(&m_cc); - - m_hWnd = NULL; - - return bRet ? IDOK : IDCANCEL; - } - - // Set the current color while dialog is displayed - void SetCurrentColor(COLORREF clr) - { - ATLASSERT(::IsWindow(m_hWnd)); - SendMessage(_GetSetRGBMessage(), 0, (LPARAM)clr); - } - - // Get the selected color after DoModal returns, or in OnColorOK - COLORREF GetColor() const - { - return m_cc.rgbResult; - } - -// Special override for the color dialog - static UINT_PTR APIENTRY HookProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) - { - if(uMsg != WM_INITDIALOG && uMsg != _GetColorOKMessage()) - return 0; - - LPCHOOSECOLOR lpCC = (LPCHOOSECOLOR)lParam; - CCommonDialogImplBase* pT = NULL; - - if(uMsg == WM_INITDIALOG) - { - pT = (CCommonDialogImplBase*)ModuleHelper::ExtractCreateWndData(); - lpCC->lCustData = (LPARAM)pT; - ATLASSERT(pT != NULL); - ATLASSERT(pT->m_hWnd == NULL); - ATLASSERT(::IsWindow(hWnd)); - // subclass dialog's window - if(!pT->SubclassWindow(hWnd)) - { - ATLTRACE2(atlTraceUI, 0, _T("Subclassing a Color common dialog failed\n")); - return 0; - } - } - else if(uMsg == _GetColorOKMessage()) - { - pT = (CCommonDialogImplBase*)lpCC->lCustData; - ATLASSERT(pT != NULL); - ATLASSERT(::IsWindow(pT->m_hWnd)); - } - - // pass to the message map - LRESULT lRes; - if(pT->ProcessWindowMessage(pT->m_hWnd, uMsg, wParam, lParam, lRes, 0) == FALSE) - return 0; - return lRes; - } - -// Helpers - static COLORREF* GetCustomColors() - { - static COLORREF rgbCustomColors[16] = - { - RGB(255, 255, 255), RGB(255, 255, 255), - RGB(255, 255, 255), RGB(255, 255, 255), - RGB(255, 255, 255), RGB(255, 255, 255), - RGB(255, 255, 255), RGB(255, 255, 255), - RGB(255, 255, 255), RGB(255, 255, 255), - RGB(255, 255, 255), RGB(255, 255, 255), - RGB(255, 255, 255), RGB(255, 255, 255), - RGB(255, 255, 255), RGB(255, 255, 255), - }; - - return rgbCustomColors; - } - - static UINT _GetSetRGBMessage() - { - static UINT uSetRGBMessage = 0; - if(uSetRGBMessage == 0) - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CColorDialogImpl::_GetSetRGBMessage.\n")); - ATLASSERT(FALSE); - return 0; - } - - if(uSetRGBMessage == 0) - uSetRGBMessage = ::RegisterWindowMessage(SETRGBSTRING); - - lock.Unlock(); - } - ATLASSERT(uSetRGBMessage != 0); - return uSetRGBMessage; - } - - static UINT _GetColorOKMessage() - { - static UINT uColorOKMessage = 0; - if(uColorOKMessage == 0) - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CColorDialogImpl::_GetColorOKMessage.\n")); - ATLASSERT(FALSE); - return 0; - } - - if(uColorOKMessage == 0) - uColorOKMessage = ::RegisterWindowMessage(COLOROKSTRING); - - lock.Unlock(); - } - ATLASSERT(uColorOKMessage != 0); - return uColorOKMessage; - } - -// Message map and handlers - BEGIN_MSG_MAP(CColorDialogImpl) - MESSAGE_HANDLER(_GetColorOKMessage(), _OnColorOK) - END_MSG_MAP() - - LRESULT _OnColorOK(UINT, WPARAM, LPARAM, BOOL&) - { - T* pT = static_cast(this); - return pT->OnColorOK(); - } - -// Overrideable - BOOL OnColorOK() // validate color - { - return FALSE; - } -}; - -class CColorDialog : public CColorDialogImpl -{ -public: - CColorDialog(COLORREF clrInit = 0, DWORD dwFlags = 0, HWND hWndParent = NULL) - : CColorDialogImpl(clrInit, dwFlags, hWndParent) - { } - - // override base class map and references to handlers - DECLARE_EMPTY_MSG_MAP() -}; - -#endif // !defined(_WIN32_WCE) || ((_WIN32_WCE > 420) && !(defined(WIN32_PLATFORM_WFSP) && (_WIN32_WCE > 0x0500))) - - -/////////////////////////////////////////////////////////////////////////////// -// CPrintDialogImpl - used for Print... and PrintSetup... - -#ifndef _WIN32_WCE - -// global helper -static HDC _AtlCreateDC(HGLOBAL hDevNames, HGLOBAL hDevMode) -{ - if(hDevNames == NULL) - return NULL; - - LPDEVNAMES lpDevNames = (LPDEVNAMES)::GlobalLock(hDevNames); - LPDEVMODE lpDevMode = (hDevMode != NULL) ? (LPDEVMODE)::GlobalLock(hDevMode) : NULL; - - if(lpDevNames == NULL) - return NULL; - - HDC hDC = ::CreateDC((LPCTSTR)lpDevNames + lpDevNames->wDriverOffset, - (LPCTSTR)lpDevNames + lpDevNames->wDeviceOffset, - (LPCTSTR)lpDevNames + lpDevNames->wOutputOffset, - lpDevMode); - - ::GlobalUnlock(hDevNames); - if(hDevMode != NULL) - ::GlobalUnlock(hDevMode); - return hDC; -} - -template -class ATL_NO_VTABLE CPrintDialogImpl : public CCommonDialogImplBase -{ -public: - // print dialog parameter block (note this is a reference) - PRINTDLG& m_pd; - -// Constructors - CPrintDialogImpl(BOOL bPrintSetupOnly = FALSE, // TRUE for Print Setup, FALSE for Print Dialog - DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_NOSELECTION, - HWND hWndParent = NULL) - : m_pd(m_pdActual) - { - memset(&m_pdActual, 0, sizeof(m_pdActual)); - - m_pd.lStructSize = sizeof(m_pdActual); - m_pd.hwndOwner = hWndParent; - m_pd.Flags = (dwFlags | PD_ENABLEPRINTHOOK | PD_ENABLESETUPHOOK); - m_pd.lpfnPrintHook = (LPPRINTHOOKPROC)T::HookProc; - m_pd.lpfnSetupHook = (LPSETUPHOOKPROC)T::HookProc; - - if(bPrintSetupOnly) - m_pd.Flags |= PD_PRINTSETUP; - else - m_pd.Flags |= PD_RETURNDC; - - m_pd.Flags &= ~PD_RETURNIC; // do not support information context - } - -// Operations - INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) - { - ATLASSERT((m_pd.Flags & PD_ENABLEPRINTHOOK) != 0); - ATLASSERT((m_pd.Flags & PD_ENABLESETUPHOOK) != 0); - ATLASSERT(m_pd.lpfnPrintHook != NULL); // can still be a user hook - ATLASSERT(m_pd.lpfnSetupHook != NULL); // can still be a user hook - ATLASSERT((m_pd.Flags & PD_RETURNDEFAULT) == 0); // use GetDefaults for this - - if(m_pd.hwndOwner == NULL) // set only if not specified before - m_pd.hwndOwner = hWndParent; - - ATLASSERT(m_hWnd == NULL); - ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this); - - BOOL bRet = ::PrintDlg(&m_pd); - - m_hWnd = NULL; - - return bRet ? IDOK : IDCANCEL; - } - - // GetDefaults will not display a dialog but will get device defaults - BOOL GetDefaults() - { - m_pd.Flags |= PD_RETURNDEFAULT; - ATLASSERT(m_pd.hDevMode == NULL); // must be NULL - ATLASSERT(m_pd.hDevNames == NULL); // must be NULL - - return ::PrintDlg(&m_pd); - } - - // Helpers for parsing information after successful return num. copies requested - int GetCopies() const - { - if((m_pd.Flags & PD_USEDEVMODECOPIES) != 0) - { - LPDEVMODE lpDevMode = GetDevMode(); - return (lpDevMode != NULL) ? lpDevMode->dmCopies : -1; - } - - return m_pd.nCopies; - } - - BOOL PrintCollate() const // TRUE if collate checked - { - return ((m_pd.Flags & PD_COLLATE) != 0) ? TRUE : FALSE; - } - - BOOL PrintSelection() const // TRUE if printing selection - { - return ((m_pd.Flags & PD_SELECTION) != 0) ? TRUE : FALSE; - } - - BOOL PrintAll() const // TRUE if printing all pages - { - return (!PrintRange() && !PrintSelection()) ? TRUE : FALSE; - } - - BOOL PrintRange() const // TRUE if printing page range - { - return ((m_pd.Flags & PD_PAGENUMS) != 0) ? TRUE : FALSE; - } - - BOOL PrintToFile() const // TRUE if printing to a file - { - return ((m_pd.Flags & PD_PRINTTOFILE) != 0) ? TRUE : FALSE; - } - - int GetFromPage() const // starting page if valid - { - return PrintRange() ? m_pd.nFromPage : -1; - } - - int GetToPage() const // ending page if valid - { - return PrintRange() ? m_pd.nToPage : -1; - } - - LPDEVMODE GetDevMode() const // return DEVMODE - { - if(m_pd.hDevMode == NULL) - return NULL; - - return (LPDEVMODE)::GlobalLock(m_pd.hDevMode); - } - - LPCTSTR GetDriverName() const // return driver name - { - if(m_pd.hDevNames == NULL) - return NULL; - - LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pd.hDevNames); - if(lpDev == NULL) - return NULL; - - return (LPCTSTR)lpDev + lpDev->wDriverOffset; - } - - LPCTSTR GetDeviceName() const // return device name - { - if(m_pd.hDevNames == NULL) - return NULL; - - LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pd.hDevNames); - if(lpDev == NULL) - return NULL; - - return (LPCTSTR)lpDev + lpDev->wDeviceOffset; - } - - LPCTSTR GetPortName() const // return output port name - { - if(m_pd.hDevNames == NULL) - return NULL; - - LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pd.hDevNames); - if(lpDev == NULL) - return NULL; - - return (LPCTSTR)lpDev + lpDev->wOutputOffset; - } - - HDC GetPrinterDC() const // return HDC (caller must delete) - { - ATLASSERT((m_pd.Flags & PD_RETURNDC) != 0); - return m_pd.hDC; - } - - // This helper creates a DC based on the DEVNAMES and DEVMODE structures. - // This DC is returned, but also stored in m_pd.hDC as though it had been - // returned by CommDlg. It is assumed that any previously obtained DC - // has been/will be deleted by the user. This may be - // used without ever invoking the print/print setup dialogs. - HDC CreatePrinterDC() - { - m_pd.hDC = _AtlCreateDC(m_pd.hDevNames, m_pd.hDevMode); - return m_pd.hDC; - } - -// Implementation - PRINTDLG m_pdActual; // the Print/Print Setup need to share this - - // The following handle the case of print setup... from the print dialog - CPrintDialogImpl(PRINTDLG& pdInit) : m_pd(pdInit) - { } - - BEGIN_MSG_MAP(CPrintDialogImpl) -#ifdef psh1 - COMMAND_ID_HANDLER(psh1, OnPrintSetup) // print setup button when print is displayed -#else // !psh1 - COMMAND_ID_HANDLER(0x0400, OnPrintSetup) // value from dlgs.h -#endif // !psh1 - END_MSG_MAP() - - LRESULT OnPrintSetup(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& /*bHandled*/) - { - T dlgSetup(m_pd); - ModuleHelper::AddCreateWndData(&dlgSetup.m_thunk.cd, (CCommonDialogImplBase*)&dlgSetup); - return DefWindowProc(WM_COMMAND, MAKEWPARAM(wID, wNotifyCode), (LPARAM)hWndCtl); - } -}; - -class CPrintDialog : public CPrintDialogImpl -{ -public: - CPrintDialog(BOOL bPrintSetupOnly = FALSE, - DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_NOSELECTION, - HWND hWndParent = NULL) - : CPrintDialogImpl(bPrintSetupOnly, dwFlags, hWndParent) - { } - - CPrintDialog(PRINTDLG& pdInit) : CPrintDialogImpl(pdInit) - { } -}; - -#endif // _WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CPrintDialogExImpl - new print dialog for Windows 2000 - -#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) - -}; // namespace WTL - -#include - -extern "C" const __declspec(selectany) IID IID_IPrintDialogCallback = {0x5852a2c3, 0x6530, 0x11d1, {0xb6, 0xa3, 0x0, 0x0, 0xf8, 0x75, 0x7b, 0xf9}}; -extern "C" const __declspec(selectany) IID IID_IPrintDialogServices = {0x509aaeda, 0x5639, 0x11d1, {0xb6, 0xa1, 0x0, 0x0, 0xf8, 0x75, 0x7b, 0xf9}}; - -namespace WTL -{ - -template -class ATL_NO_VTABLE CPrintDialogExImpl : - public ATL::CWindow, - public ATL::CMessageMap, - public IPrintDialogCallback, - public ATL::IObjectWithSiteImpl< T > -{ -public: - PRINTDLGEX m_pdex; - -// Constructor - CPrintDialogExImpl(DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_NOSELECTION | PD_NOCURRENTPAGE, - HWND hWndParent = NULL) - { - memset(&m_pdex, 0, sizeof(m_pdex)); - - m_pdex.lStructSize = sizeof(PRINTDLGEX); - m_pdex.hwndOwner = hWndParent; - m_pdex.Flags = dwFlags; - m_pdex.nStartPage = START_PAGE_GENERAL; - // callback object will be set in DoModal - - m_pdex.Flags &= ~PD_RETURNIC; // do not support information context - } - -// Operations - HRESULT DoModal(HWND hWndParent = ::GetActiveWindow()) - { - ATLASSERT(m_hWnd == NULL); - ATLASSERT((m_pdex.Flags & PD_RETURNDEFAULT) == 0); // use GetDefaults for this - - if(m_pdex.hwndOwner == NULL) // set only if not specified before - m_pdex.hwndOwner = hWndParent; - - T* pT = static_cast(this); - m_pdex.lpCallback = (IUnknown*)(IPrintDialogCallback*)pT; - - HRESULT hResult = ::PrintDlgEx(&m_pdex); - - m_hWnd = NULL; - - return hResult; - } - - BOOL EndDialog(INT_PTR /*nRetCode*/ = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - SendMessage(WM_COMMAND, MAKEWPARAM(IDABORT, 0)); - return TRUE; - } - - // GetDefaults will not display a dialog but will get device defaults - HRESULT GetDefaults() - { - m_pdex.Flags |= PD_RETURNDEFAULT; - ATLASSERT(m_pdex.hDevMode == NULL); // must be NULL - ATLASSERT(m_pdex.hDevNames == NULL); // must be NULL - - return ::PrintDlgEx(&m_pdex); - } - - // Helpers for parsing information after successful return num. copies requested - int GetCopies() const - { - if((m_pdex.Flags & PD_USEDEVMODECOPIES) != 0) - { - LPDEVMODE lpDevMode = GetDevMode(); - return (lpDevMode != NULL) ? lpDevMode->dmCopies : -1; - } - - return m_pdex.nCopies; - } - - BOOL PrintCollate() const // TRUE if collate checked - { - return ((m_pdex.Flags & PD_COLLATE) != 0) ? TRUE : FALSE; - } - - BOOL PrintSelection() const // TRUE if printing selection - { - return ((m_pdex.Flags & PD_SELECTION) != 0) ? TRUE : FALSE; - } - - BOOL PrintAll() const // TRUE if printing all pages - { - return (!PrintRange() && !PrintSelection()) ? TRUE : FALSE; - } - - BOOL PrintRange() const // TRUE if printing page range - { - return ((m_pdex.Flags & PD_PAGENUMS) != 0) ? TRUE : FALSE; - } - - BOOL PrintToFile() const // TRUE if printing to a file - { - return ((m_pdex.Flags & PD_PRINTTOFILE) != 0) ? TRUE : FALSE; - } - - LPDEVMODE GetDevMode() const // return DEVMODE - { - if(m_pdex.hDevMode == NULL) - return NULL; - - return (LPDEVMODE)::GlobalLock(m_pdex.hDevMode); - } - - LPCTSTR GetDriverName() const // return driver name - { - if(m_pdex.hDevNames == NULL) - return NULL; - - LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pdex.hDevNames); - if(lpDev == NULL) - return NULL; - - return (LPCTSTR)lpDev + lpDev->wDriverOffset; - } - - LPCTSTR GetDeviceName() const // return device name - { - if(m_pdex.hDevNames == NULL) - return NULL; - - LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pdex.hDevNames); - if(lpDev == NULL) - return NULL; - - return (LPCTSTR)lpDev + lpDev->wDeviceOffset; - } - - LPCTSTR GetPortName() const // return output port name - { - if(m_pdex.hDevNames == NULL) - return NULL; - - LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pdex.hDevNames); - if(lpDev == NULL) - return NULL; - - return (LPCTSTR)lpDev + lpDev->wOutputOffset; - } - - HDC GetPrinterDC() const // return HDC (caller must delete) - { - ATLASSERT((m_pdex.Flags & PD_RETURNDC) != 0); - return m_pdex.hDC; - } - - // This helper creates a DC based on the DEVNAMES and DEVMODE structures. - // This DC is returned, but also stored in m_pdex.hDC as though it had been - // returned by CommDlg. It is assumed that any previously obtained DC - // has been/will be deleted by the user. This may be - // used without ever invoking the print/print setup dialogs. - HDC CreatePrinterDC() - { - m_pdex.hDC = _AtlCreateDC(m_pdex.hDevNames, m_pdex.hDevMode); - return m_pdex.hDC; - } - -// Implementation - interfaces - -// IUnknown - STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject) - { - if(ppvObject == NULL) - return E_POINTER; - - T* pT = static_cast(this); - if(IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IPrintDialogCallback)) - { - *ppvObject = (IPrintDialogCallback*)pT; - // AddRef() not needed - return S_OK; - } - else if(IsEqualGUID(riid, IID_IObjectWithSite)) - { - *ppvObject = (IObjectWithSite*)pT; - // AddRef() not needed - return S_OK; - } - - return E_NOINTERFACE; - } - - virtual ULONG STDMETHODCALLTYPE AddRef() - { - return 1; - } - - virtual ULONG STDMETHODCALLTYPE Release() - { - return 1; - } - -// IPrintDialogCallback - STDMETHOD(InitDone)() - { - return S_FALSE; - } - - STDMETHOD(SelectionChange)() - { - return S_FALSE; - } - - STDMETHOD(HandleMessage)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* plResult) - { - // set up m_hWnd the first time - if(m_hWnd == NULL) - Attach(hWnd); - - // call message map - HRESULT hRet = ProcessWindowMessage(hWnd, uMsg, wParam, lParam, *plResult, 0) ? S_OK : S_FALSE; - if(hRet == S_OK && uMsg == WM_NOTIFY) // return in DWLP_MSGRESULT - ::SetWindowLongPtr(GetParent(), DWLP_MSGRESULT, (LONG_PTR)*plResult); - - if(uMsg == WM_INITDIALOG && hRet == S_OK && (BOOL)*plResult != FALSE) - hRet = S_FALSE; - - return hRet; - } -}; - -class CPrintDialogEx : public CPrintDialogExImpl -{ -public: - CPrintDialogEx( - DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_NOSELECTION | PD_NOCURRENTPAGE, - HWND hWndParent = NULL) - : CPrintDialogExImpl(dwFlags, hWndParent) - { } - - DECLARE_EMPTY_MSG_MAP() -}; - -#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) - - -/////////////////////////////////////////////////////////////////////////////// -// CPageSetupDialogImpl - Page Setup dialog - -#ifndef _WIN32_WCE - -template -class ATL_NO_VTABLE CPageSetupDialogImpl : public CCommonDialogImplBase -{ -public: - PAGESETUPDLG m_psd; - ATL::CWndProcThunk m_thunkPaint; - -// Constructors - CPageSetupDialogImpl(DWORD dwFlags = PSD_MARGINS | PSD_INWININIINTLMEASURE, HWND hWndParent = NULL) - { - memset(&m_psd, 0, sizeof(m_psd)); - - m_psd.lStructSize = sizeof(m_psd); - m_psd.hwndOwner = hWndParent; - m_psd.Flags = (dwFlags | PSD_ENABLEPAGESETUPHOOK | PSD_ENABLEPAGEPAINTHOOK); - m_psd.lpfnPageSetupHook = (LPPAGESETUPHOOK)T::HookProc; - m_thunkPaint.Init((WNDPROC)T::PaintHookProc, this); -#if (_ATL_VER >= 0x0700) - m_psd.lpfnPagePaintHook = (LPPAGEPAINTHOOK)m_thunkPaint.GetWNDPROC(); -#else - m_psd.lpfnPagePaintHook = (LPPAGEPAINTHOOK)&(m_thunkPaint.thunk); -#endif - } - - DECLARE_EMPTY_MSG_MAP() - -// Attributes - LPDEVMODE GetDevMode() const // return DEVMODE - { - if(m_psd.hDevMode == NULL) - return NULL; - - return (LPDEVMODE)::GlobalLock(m_psd.hDevMode); - } - - LPCTSTR GetDriverName() const // return driver name - { - if(m_psd.hDevNames == NULL) - return NULL; - - LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_psd.hDevNames); - return (LPCTSTR)lpDev + lpDev->wDriverOffset; - } - - LPCTSTR GetDeviceName() const // return device name - { - if(m_psd.hDevNames == NULL) - return NULL; - - LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_psd.hDevNames); - return (LPCTSTR)lpDev + lpDev->wDeviceOffset; - } - - LPCTSTR GetPortName() const // return output port name - { - if(m_psd.hDevNames == NULL) - return NULL; - - LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_psd.hDevNames); - return (LPCTSTR)lpDev + lpDev->wOutputOffset; - } - - HDC CreatePrinterDC() - { - return _AtlCreateDC(m_psd.hDevNames, m_psd.hDevMode); - } - - SIZE GetPaperSize() const - { - SIZE size; - size.cx = m_psd.ptPaperSize.x; - size.cy = m_psd.ptPaperSize.y; - return size; - } - - void GetMargins(LPRECT lpRectMargins, LPRECT lpRectMinMargins) const - { - if(lpRectMargins != NULL) - *lpRectMargins = m_psd.rtMargin; - if(lpRectMinMargins != NULL) - *lpRectMinMargins = m_psd.rtMinMargin; - } - -// Operations - INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) - { - ATLASSERT((m_psd.Flags & PSD_ENABLEPAGESETUPHOOK) != 0); - ATLASSERT((m_psd.Flags & PSD_ENABLEPAGEPAINTHOOK) != 0); - ATLASSERT(m_psd.lpfnPageSetupHook != NULL); // can still be a user hook - ATLASSERT(m_psd.lpfnPagePaintHook != NULL); // can still be a user hook - - if(m_psd.hwndOwner == NULL) // set only if not specified before - m_psd.hwndOwner = hWndParent; - - ATLASSERT(m_hWnd == NULL); - ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this); - - BOOL bRet = ::PageSetupDlg(&m_psd); - - m_hWnd = NULL; - - return bRet ? IDOK : IDCANCEL; - } - -// Implementation - static UINT_PTR CALLBACK PaintHookProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) - { - T* pT = (T*)hWnd; - UINT_PTR uRet = 0; - switch(uMsg) - { - case WM_PSD_PAGESETUPDLG: - uRet = pT->PreDrawPage(LOWORD(wParam), HIWORD(wParam), (LPPAGESETUPDLG)lParam); - break; - case WM_PSD_FULLPAGERECT: - case WM_PSD_MINMARGINRECT: - case WM_PSD_MARGINRECT: - case WM_PSD_GREEKTEXTRECT: - case WM_PSD_ENVSTAMPRECT: - case WM_PSD_YAFULLPAGERECT: - uRet = pT->OnDrawPage(uMsg, (HDC)wParam, (LPRECT)lParam); - break; - default: - ATLTRACE2(atlTraceUI, 0, _T("CPageSetupDialogImpl::PaintHookProc - unknown message received\n")); - break; - } - return uRet; - } - -// Overridables - UINT_PTR PreDrawPage(WORD /*wPaper*/, WORD /*wFlags*/, LPPAGESETUPDLG /*pPSD*/) - { - // return 1 to prevent any more drawing - return 0; - } - - UINT_PTR OnDrawPage(UINT /*uMsg*/, HDC /*hDC*/, LPRECT /*lpRect*/) - { - return 0; // do the default - } -}; - -class CPageSetupDialog : public CPageSetupDialogImpl -{ -public: - CPageSetupDialog(DWORD dwFlags = PSD_MARGINS | PSD_INWININIINTLMEASURE, HWND hWndParent = NULL) - : CPageSetupDialogImpl(dwFlags, hWndParent) - { } - - // override PaintHookProc and references to handlers - static UINT_PTR CALLBACK PaintHookProc(HWND, UINT, WPARAM, LPARAM) - { - return 0; - } -}; - -#endif // _WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CFindReplaceDialogImpl - Find/FindReplace modeless dialogs - -#ifndef _WIN32_WCE - -template -class ATL_NO_VTABLE CFindReplaceDialogImpl : public CCommonDialogImplBase -{ -public: - enum { _cchFindReplaceBuffer = 128 }; - - FINDREPLACE m_fr; - TCHAR m_szFindWhat[_cchFindReplaceBuffer]; - TCHAR m_szReplaceWith[_cchFindReplaceBuffer]; - -// Constructors - CFindReplaceDialogImpl() - { - memset(&m_fr, 0, sizeof(m_fr)); - m_szFindWhat[0] = _T('\0'); - m_szReplaceWith[0] = _T('\0'); - - m_fr.lStructSize = sizeof(m_fr); - m_fr.Flags = FR_ENABLEHOOK; - m_fr.lpfnHook = (LPFRHOOKPROC)T::HookProc; - m_fr.lpstrFindWhat = (LPTSTR)m_szFindWhat; - m_fr.wFindWhatLen = _cchFindReplaceBuffer; - m_fr.lpstrReplaceWith = (LPTSTR)m_szReplaceWith; - m_fr.wReplaceWithLen = _cchFindReplaceBuffer; - } - - // Note: You must allocate the object on the heap. - // If you do not, you must override OnFinalMessage() - virtual void OnFinalMessage(HWND /*hWnd*/) - { - delete this; - } - - HWND Create(BOOL bFindDialogOnly, // TRUE for Find, FALSE for FindReplace - LPCTSTR lpszFindWhat, - LPCTSTR lpszReplaceWith = NULL, - DWORD dwFlags = FR_DOWN, - HWND hWndParent = NULL) - { - ATLASSERT((m_fr.Flags & FR_ENABLEHOOK) != 0); - ATLASSERT(m_fr.lpfnHook != NULL); - - m_fr.Flags |= dwFlags; - - if(hWndParent == NULL) - m_fr.hwndOwner = ::GetActiveWindow(); - else - m_fr.hwndOwner = hWndParent; - ATLASSERT(m_fr.hwndOwner != NULL); // must have an owner for modeless dialog - - if(lpszFindWhat != NULL) - SecureHelper::strncpy_x(m_szFindWhat, _countof(m_szFindWhat), lpszFindWhat, _TRUNCATE); - - if(lpszReplaceWith != NULL) - SecureHelper::strncpy_x(m_szReplaceWith, _countof(m_szReplaceWith), lpszReplaceWith, _TRUNCATE); - - ATLASSERT(m_hWnd == NULL); - ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this); - - HWND hWnd = NULL; - if(bFindDialogOnly) - hWnd = ::FindText(&m_fr); - else - hWnd = ::ReplaceText(&m_fr); - - ATLASSERT(m_hWnd == hWnd); - return hWnd; - } - - static const UINT GetFindReplaceMsg() - { - static const UINT nMsgFindReplace = ::RegisterWindowMessage(FINDMSGSTRING); - return nMsgFindReplace; - } - // call while handling FINDMSGSTRING registered message - // to retreive the object - static T* PASCAL GetNotifier(LPARAM lParam) - { - ATLASSERT(lParam != NULL); - T* pDlg = (T*)(lParam - offsetof(T, m_fr)); - return pDlg; - } - -// Operations - // Helpers for parsing information after successful return - LPCTSTR GetFindString() const // get find string - { - return (LPCTSTR)m_fr.lpstrFindWhat; - } - - LPCTSTR GetReplaceString() const // get replacement string - { - return (LPCTSTR)m_fr.lpstrReplaceWith; - } - - BOOL SearchDown() const // TRUE if search down, FALSE is up - { - return ((m_fr.Flags & FR_DOWN) != 0) ? TRUE : FALSE; - } - - BOOL FindNext() const // TRUE if command is find next - { - return ((m_fr.Flags & FR_FINDNEXT) != 0) ? TRUE : FALSE; - } - - BOOL MatchCase() const // TRUE if matching case - { - return ((m_fr.Flags & FR_MATCHCASE) != 0) ? TRUE : FALSE; - } - - BOOL MatchWholeWord() const // TRUE if matching whole words only - { - return ((m_fr.Flags & FR_WHOLEWORD) != 0) ? TRUE : FALSE; - } - - BOOL ReplaceCurrent() const // TRUE if replacing current string - { - return ((m_fr. Flags & FR_REPLACE) != 0) ? TRUE : FALSE; - } - - BOOL ReplaceAll() const // TRUE if replacing all occurrences - { - return ((m_fr.Flags & FR_REPLACEALL) != 0) ? TRUE : FALSE; - } - - BOOL IsTerminating() const // TRUE if terminating dialog - { - return ((m_fr.Flags & FR_DIALOGTERM) != 0) ? TRUE : FALSE ; - } -}; - -class CFindReplaceDialog : public CFindReplaceDialogImpl -{ -public: - DECLARE_EMPTY_MSG_MAP() -}; - -#endif // !_WIN32_WCE - - -///////////////////////////////////////////////////////////////////////// -// CDialogBaseUnits - Dialog Units helper -// - -class CDialogBaseUnits -{ -public: - SIZE m_sizeUnits; - -// Constructors - CDialogBaseUnits() - { - // The base units of the out-dated System Font - LONG nDlgBaseUnits = ::GetDialogBaseUnits(); - m_sizeUnits.cx = LOWORD(nDlgBaseUnits); - m_sizeUnits.cy = HIWORD(nDlgBaseUnits); - } - - CDialogBaseUnits(HWND hWnd) - { - if(!InitDialogBaseUnits(hWnd)) { - LONG nDlgBaseUnits = ::GetDialogBaseUnits(); - m_sizeUnits.cx = LOWORD(nDlgBaseUnits); - m_sizeUnits.cy = HIWORD(nDlgBaseUnits); - } - } - - CDialogBaseUnits(HFONT hFont, HWND hWnd = NULL) - { - if(!InitDialogBaseUnits(hFont, hWnd)) { - LONG nDlgBaseUnits = ::GetDialogBaseUnits(); - m_sizeUnits.cx = LOWORD(nDlgBaseUnits); - m_sizeUnits.cy = HIWORD(nDlgBaseUnits); - } - } - - CDialogBaseUnits(LOGFONT lf, HWND hWnd = NULL) - { - if(!InitDialogBaseUnits(lf, hWnd)) { - LONG nDlgBaseUnits = ::GetDialogBaseUnits(); - m_sizeUnits.cx = LOWORD(nDlgBaseUnits); - m_sizeUnits.cy = HIWORD(nDlgBaseUnits); - } - } - -// Operations - BOOL InitDialogBaseUnits(HWND hWnd) - { - ATLASSERT(::IsWindow(hWnd)); - RECT rc = { 0, 0, 4, 8 }; - if(!::MapDialogRect(hWnd, &rc)) return FALSE; - m_sizeUnits.cx = rc.right; - m_sizeUnits.cy = rc.bottom; - return TRUE; - } - - BOOL InitDialogBaseUnits(LOGFONT lf, HWND hWnd = NULL) - { - CFont font; - font.CreateFontIndirect(&lf); - if(font.IsNull()) return FALSE; - return InitDialogBaseUnits(font, hWnd); - } - - BOOL InitDialogBaseUnits(HFONT hFont, HWND hWnd = NULL) - { - ATLASSERT(hFont != NULL); - CWindowDC dc = hWnd; - TEXTMETRIC tmText = { 0 }; - SIZE sizeText = { 0 }; - HFONT hFontOld = dc.SelectFont(hFont); - dc.GetTextMetrics(&tmText); - m_sizeUnits.cy = tmText.tmHeight + tmText.tmExternalLeading; - dc.GetTextExtent(_T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), 52, &sizeText); - m_sizeUnits.cx = (sizeText.cx + 26) / 52; - dc.SelectFont(hFontOld); - return TRUE; - } - - SIZE GetDialogBaseUnits() const - { - return m_sizeUnits; - } - - INT MapDialogPixelsX(INT x) const - { - return ::MulDiv(x, 4, m_sizeUnits.cx); // Pixels X to DLU - } - - INT MapDialogPixelsY(INT y) const - { - return ::MulDiv(y, 8, m_sizeUnits.cy); // Pixels Y to DLU - } - - POINT MapDialogPixels(POINT pt) const - { - POINT out = { MapDialogPixelsX(pt.x), MapDialogPixelsY(pt.y) }; - return out; - } - - SIZE MapDialogPixels(SIZE input) const - { - SIZE out = { MapDialogPixelsX(input.cx), MapDialogPixelsY(input.cy) }; - return out; - } - - RECT MapDialogPixels(RECT input) const - { - RECT out = { MapDialogPixelsX(input.left), MapDialogPixelsY(input.top), MapDialogPixelsX(input.right), MapDialogPixelsY(input.bottom) }; - return out; - } - - INT MapDialogUnitsX(INT x) const - { - return ::MulDiv(x, m_sizeUnits.cx, 4); // DLU to Pixels X - } - - INT MapDialogUnitsY(INT y) const - { - return ::MulDiv(y, m_sizeUnits.cx, 8); // DLU to Pixels Y - } - - POINT MapDialogUnits(POINT pt) const - { - POINT out = { MapDialogUnitsX(pt.x), MapDialogUnitsY(pt.y) }; - return out; - } - - SIZE MapDialogUnits(SIZE input) const - { - SIZE out = { MapDialogUnitsX(input.cx), MapDialogUnitsY(input.cy) }; - return out; - } - - RECT MapDialogUnits(RECT input) const - { - RECT out = { MapDialogUnitsX(input.left), MapDialogUnitsY(input.top), MapDialogUnitsX(input.right), MapDialogUnitsY(input.bottom) }; - return out; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CMemDlgTemplate - in-memory dialog template - DLGTEMPLATE or DLGTEMPLATEEX - -#if (_ATL_VER >= 0x800) - typedef ATL::_DialogSplitHelper::DLGTEMPLATEEX DLGTEMPLATEEX; - typedef ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX DLGITEMTEMPLATEEX; -#else // (_ATL_VER >= 0x800) - typedef ATL::_DialogSizeHelper::_ATL_DLGTEMPLATEEX DLGTEMPLATEEX; - #pragma pack(push, 4) - struct DLGITEMTEMPLATEEX - { - DWORD helpID; - DWORD exStyle; - DWORD style; - short x; - short y; - short cx; - short cy; - DWORD id; - }; - #pragma pack(pop) -#endif // (_ATL_VER >= 0x800) - - -class CMemDlgTemplate -{ -public: - enum StdCtrlType - { - CTRL_BUTTON = 0x0080, - CTRL_EDIT = 0x0081, - CTRL_STATIC = 0x0082, - CTRL_LISTBOX = 0x0083, - CTRL_SCROLLBAR = 0x0084, - CTRL_COMBOBOX = 0x0085 - }; - - CMemDlgTemplate() : m_hData(NULL), m_pData(NULL), m_pPtr(NULL), m_cAllocated(0) - { } - - ~CMemDlgTemplate() - { - Reset(); - } - - bool IsValid() const - { - return (m_pData != NULL); - } - - bool IsTemplateEx() const - { - return (IsValid() && ((DLGTEMPLATEEX*)m_pData)->signature == 0xFFFF); - } - - LPDLGTEMPLATE GetTemplatePtr() - { - return reinterpret_cast(m_pData); - } - - DLGTEMPLATEEX* GetTemplateExPtr() - { - return reinterpret_cast(m_pData); - } - - void Reset() - { - if (IsValid()) { -#ifndef UNDER_CE - ::GlobalUnlock(m_pData); -#endif - ATLVERIFY(::GlobalFree(m_hData) == NULL); - } - - m_hData = NULL; - m_pData = NULL; - m_pPtr = NULL; - m_cAllocated = 0; - } - - void Create(bool bDlgEx, LPCTSTR lpszCaption, RECT rc, DWORD dwStyle = 0, DWORD dwExStyle = 0, - LPCTSTR lpstrFontName = NULL, WORD wFontSize = 0, WORD wWeight = 0, BYTE bItalic = 0, BYTE bCharset = 0, DWORD dwHelpID = 0, - ATL::_U_STRINGorID ClassName = 0U, ATL::_U_STRINGorID Menu = 0U) - { - Create(bDlgEx, lpszCaption, (short) rc.left, (short) rc.top, (short) (rc.right - rc.left), (short) (rc.bottom - rc.top), dwStyle, dwExStyle, - lpstrFontName, wFontSize, wWeight, bItalic, bCharset, dwHelpID, ClassName.m_lpstr, Menu.m_lpstr); - } - - void Create(bool bDlgEx, LPCTSTR lpszCaption, short nX, short nY, short nWidth, short nHeight, DWORD dwStyle = 0, DWORD dwExStyle = 0, - LPCTSTR lpstrFontName = NULL, WORD wFontSize = 0, WORD wWeight = 0, BYTE bItalic = 0, BYTE bCharset = 0, DWORD dwHelpID = 0, - ATL::_U_STRINGorID ClassName = 0U, ATL::_U_STRINGorID Menu = 0U) - { - // Should have DS_SETFONT style to set the dialog font name and size - if (lpstrFontName != NULL) - { - dwStyle |= DS_SETFONT; - } - else - { - dwStyle &= ~DS_SETFONT; - } - - if (bDlgEx) - { - DLGTEMPLATEEX dlg = {1, 0xFFFF, dwHelpID, dwExStyle, dwStyle, 0, nX, nY, nWidth, nHeight}; - AddData(&dlg, sizeof(dlg)); - } - else - { - DLGTEMPLATE dlg = {dwStyle, dwExStyle, 0, nX, nY, nWidth, nHeight}; - AddData(&dlg, sizeof(dlg)); - } - -#ifndef _WIN32_WCE - if (Menu.m_lpstr == NULL) - { - WORD menuData = 0; - AddData(&menuData, sizeof(WORD)); - } - else if (IS_INTRESOURCE(Menu.m_lpstr)) - { - WORD menuData[] = {0xFFFF, (WORD)Menu.m_lpstr}; - AddData(menuData, sizeof(menuData)); - } - else - { - AddString(Menu.m_lpstr); - } -#else // _WIN32_WCE - // Windows CE doesn't support the addition of menus to a dialog box - ATLASSERT(Menu.m_lpstr == NULL); - Menu.m_lpstr; // avoid level 4 warning - WORD menuData = 0; - AddData(&menuData, sizeof(WORD)); -#endif // _WIN32_WCE - - if (ClassName.m_lpstr == NULL) - { - WORD classData = 0; - AddData(&classData, sizeof(WORD)); - } - else if (IS_INTRESOURCE(ClassName.m_lpstr)) - { - WORD classData[] = {0xFFFF, (WORD)ClassName.m_lpstr}; - AddData(classData, sizeof(classData)); - } - else - { - AddString(ClassName.m_lpstr); - } - - // Set dialog caption - AddString(lpszCaption); - - if (lpstrFontName != NULL) - { - AddData(&wFontSize, sizeof(wFontSize)); - - if (bDlgEx) - { - AddData(&wWeight, sizeof(wWeight)); - AddData(&bItalic, sizeof(bItalic)); - AddData(&bCharset, sizeof(bCharset)); - } - - AddString(lpstrFontName); - } - } - - void AddControl(ATL::_U_STRINGorID ClassName, WORD wId, RECT rc, DWORD dwStyle, DWORD dwExStyle, - ATL::_U_STRINGorID Text, const WORD* pCreationData = NULL, WORD nCreationData = 0, DWORD dwHelpID = 0) - { - AddControl(ClassName.m_lpstr, wId, (short) rc.left, (short) rc.top, (short) (rc.right - rc.left), (short) (rc.bottom - rc.top), dwStyle, dwExStyle, - Text.m_lpstr, pCreationData, nCreationData, dwHelpID); - } - - void AddControl(ATL::_U_STRINGorID ClassName, WORD wId, short nX, short nY, short nWidth, short nHeight, DWORD dwStyle, DWORD dwExStyle, - ATL::_U_STRINGorID Text, const WORD* pCreationData = NULL, WORD nCreationData = 0, DWORD dwHelpID = 0) - { - ATLASSERT(IsValid()); - - // DWORD align data - m_pPtr = (LPBYTE)(DWORD_PTR)((DWORD)(DWORD_PTR)(m_pPtr + 3) & (~3)); - - if (IsTemplateEx()) - { - DLGTEMPLATEEX* dlg = (DLGTEMPLATEEX*)m_pData; - dlg->cDlgItems++; - - DLGITEMTEMPLATEEX item = {dwHelpID, ATL::CControlWinTraits::GetWndExStyle(0) | dwExStyle, ATL::CControlWinTraits::GetWndStyle(0) | dwStyle, nX, nY, nWidth, nHeight, wId}; - AddData(&item, sizeof(item)); - } - else - { - LPDLGTEMPLATE dlg = (LPDLGTEMPLATE)m_pData; - dlg->cdit++; - - DLGITEMTEMPLATE item = {ATL::CControlWinTraits::GetWndStyle(0) | dwStyle, ATL::CControlWinTraits::GetWndExStyle(0) | dwExStyle, nX, nY, nWidth, nHeight, wId}; - AddData(&item, sizeof(item)); - } - - ATLASSERT(ClassName.m_lpstr != NULL); - if (IS_INTRESOURCE(ClassName.m_lpstr)) - { - WORD wData[] = {0xFFFF, (WORD)ClassName.m_lpstr}; - AddData(wData, sizeof(wData)); - } - else - { - AddString(ClassName.m_lpstr); - } - - if (Text.m_lpstr == NULL) - { - WORD classData = 0; - AddData(&classData, sizeof(WORD)); - } - else if (IS_INTRESOURCE(Text.m_lpstr)) - { - WORD wData[] = {0xFFFF, (WORD)Text.m_lpstr}; - AddData(wData, sizeof(wData)); - } - else - { - AddString(Text.m_lpstr); - } - - AddData(&nCreationData, sizeof(nCreationData)); - - if ((nCreationData != 0)) - { - ATLASSERT(pCreationData != NULL); - AddData(pCreationData, nCreationData * sizeof(WORD)); - } - } - - void AddStdControl(StdCtrlType CtrlType, WORD wId, short nX, short nY, short nWidth, short nHeight, - DWORD dwStyle, DWORD dwExStyle, ATL::_U_STRINGorID Text, const WORD* pCreationData = NULL, WORD nCreationData = 0, DWORD dwHelpID = 0) - { - AddControl(CtrlType, wId, nX, nY, nWidth, nHeight, dwStyle, dwExStyle, Text, pCreationData, nCreationData, dwHelpID); - } - - void AddData(LPCVOID pData, size_t nData) - { - ATLASSERT(pData != NULL); - - const SIZE_T ALLOCATION_INCREMENT = 1024; - - if (m_pData == NULL) - { - m_cAllocated = ((nData / ALLOCATION_INCREMENT) + 1) * ALLOCATION_INCREMENT; - m_hData = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, m_cAllocated); - ATLASSERT(m_hData != NULL); -#ifndef UNDER_CE - m_pPtr = m_pData = static_cast(::GlobalLock(m_hData)); -#else - m_pPtr = m_pData = static_cast(m_hData); -#endif - ATLASSERT(m_pData != NULL); - } - else if (((m_pPtr - m_pData) + nData) > m_cAllocated) - { - SIZE_T ptrPos = (m_pPtr - m_pData); - m_cAllocated += ((nData / ALLOCATION_INCREMENT) + 1) * ALLOCATION_INCREMENT; -#ifndef UNDER_CE - ::GlobalUnlock(m_pData); -#endif - m_hData = ::GlobalReAlloc(m_hData, m_cAllocated, GMEM_MOVEABLE | GMEM_ZEROINIT); - ATLASSERT(m_hData != NULL); -#ifndef UNDER_CE - m_pData = static_cast(::GlobalLock(m_hData)); -#else - m_pData = static_cast(m_hData); -#endif - ATLASSERT(m_pData != NULL); - m_pPtr = m_pData + ptrPos; - } - - SecureHelper::memcpy_x(m_pPtr, m_cAllocated - (m_pPtr - m_pData), pData, nData); - - m_pPtr += nData; - } - - void AddString(LPCTSTR lpszStr) - { - if (lpszStr == NULL) - { - WCHAR szEmpty = 0; - AddData(&szEmpty, sizeof(szEmpty)); - } - else - { - USES_CONVERSION; - LPCWSTR lpstr = T2CW(lpszStr); - int nSize = lstrlenW(lpstr) + 1; - AddData(lpstr, nSize * sizeof(WCHAR)); - } - } - - HANDLE m_hData; - LPBYTE m_pData; - LPBYTE m_pPtr; - SIZE_T m_cAllocated; -}; - - -/////////////////////////////////////////////////////////////////////////////// -// Dialog and control macros for indirect dialogs - -// for DLGTEMPLATE -#define BEGIN_DIALOG(x, y, width, height) \ - void DoInitTemplate() \ - { \ - bool bExTemplate = false; \ - short nX = x, nY = y, nWidth = width, nHeight = height; \ - LPCTSTR szCaption = NULL; \ - DWORD dwStyle = WS_POPUP | WS_BORDER | WS_SYSMENU; \ - DWORD dwExStyle = 0; \ - LPCTSTR szFontName = NULL; \ - WORD wFontSize = 0; \ - WORD wWeight = 0; \ - BYTE bItalic = 0; \ - BYTE bCharset = 0; \ - DWORD dwHelpID = 0; \ - ATL::_U_STRINGorID Menu = 0U; \ - ATL::_U_STRINGorID ClassName = 0U; - -// for DLGTEMPLATEEX -#define BEGIN_DIALOG_EX(x, y, width, height, helpID) \ - void DoInitTemplate() \ - { \ - bool bExTemplate = true; \ - short nX = x, nY = y, nWidth = width, nHeight = height; \ - LPCTSTR szCaption = NULL; \ - DWORD dwStyle = WS_POPUP | WS_BORDER | WS_SYSMENU; \ - DWORD dwExStyle = 0; \ - LPCTSTR szFontName = NULL; \ - WORD wFontSize = 0; \ - WORD wWeight = 0; \ - BYTE bItalic = 0; \ - BYTE bCharset = 0; \ - DWORD dwHelpID = helpID; \ - ATL::_U_STRINGorID Menu = 0U; \ - ATL::_U_STRINGorID ClassName = 0U; - -#define END_DIALOG() \ - m_Template.Create(bExTemplate, szCaption, nX, nY, nWidth, nHeight, dwStyle, dwExStyle, szFontName, wFontSize, wWeight, bItalic, bCharset, dwHelpID, ClassName, Menu); \ - }; - -#define DIALOG_CAPTION(caption) \ - szCaption = caption; -#define DIALOG_STYLE(style) \ - dwStyle = style; -#define DIALOG_EXSTYLE(exStyle) \ - dwExStyle = exStyle; -#define DIALOG_FONT(pointSize, typeFace) \ - wFontSize = pointSize; \ - szFontName = typeFace; -#define DIALOG_FONT_EX(pointsize, typeface, weight, italic, charset) \ - ATLASSERT(bExTemplate); \ - wFontSize = pointsize; \ - szFontName = typeface; \ - wWeight = weight; \ - bItalic = italic; \ - bCharset = charset; -#define DIALOG_MENU(menuName) \ - Menu = menuName; -#define DIALOG_CLASS(className) \ - ClassName = className; - -#define BEGIN_CONTROLS_MAP() \ - void DoInitControls() \ - { - -#define END_CONTROLS_MAP() \ - }; - - -#define CONTROL_LTEXT(text, id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_LEFT | WS_GROUP, exStyle, text, NULL, 0); -#define CONTROL_CTEXT(text, id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_CENTER | WS_GROUP, exStyle, text, NULL, 0); -#define CONTROL_RTEXT(text, id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_RIGHT | WS_GROUP, exStyle, text, NULL, 0); -#define CONTROL_PUSHBUTTON(text, id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_PUSHBUTTON | WS_TABSTOP, exStyle, text, NULL, 0); -#define CONTROL_DEFPUSHBUTTON(text, id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_DEFPUSHBUTTON | WS_TABSTOP, exStyle, text, NULL, 0); -#ifndef _WIN32_WCE -#define CONTROL_PUSHBOX(text, id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_PUSHBOX | WS_TABSTOP, exStyle, text, NULL, 0); -#endif // !_WIN32_WCE -#define CONTROL_STATE3(text, id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_3STATE | WS_TABSTOP, exStyle, text, NULL, 0); -#define CONTROL_AUTO3STATE(text, id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_AUTO3STATE | WS_TABSTOP, exStyle, text, NULL, 0); -#define CONTROL_CHECKBOX(text, id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_CHECKBOX | WS_TABSTOP, exStyle, text, NULL, 0); -#define CONTROL_AUTOCHECKBOX(text, id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_AUTOCHECKBOX | WS_TABSTOP, exStyle, text, NULL, 0); -#define CONTROL_RADIOBUTTON(text, id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_RADIOBUTTON | WS_TABSTOP, exStyle, text, NULL, 0); -#define CONTROL_AUTORADIOBUTTON(text, id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_AUTORADIOBUTTON | WS_TABSTOP, exStyle, text, NULL, 0); -#define CONTROL_COMBOBOX(id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_COMBOBOX, (WORD)id, x, y, width, height, style | CBS_DROPDOWN | WS_TABSTOP, exStyle, (LPCTSTR)NULL, NULL, 0); -#define CONTROL_EDITTEXT(id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_EDIT, (WORD)id, x, y, width, height, style | ES_LEFT | WS_BORDER | WS_TABSTOP, exStyle, (LPCTSTR)NULL, NULL, 0); -#define CONTROL_GROUPBOX(text, id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_GROUPBOX, exStyle, text, NULL, 0); -#define CONTROL_LISTBOX(id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_LISTBOX, (WORD)id, x, y, width, height, style | LBS_NOTIFY | WS_BORDER, exStyle, (LPCTSTR)NULL, NULL, 0); -#define CONTROL_SCROLLBAR(id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_SCROLLBAR, (WORD)id, x, y, width, height, style | SBS_HORZ, exStyle, (LPCTSTR)NULL, NULL, 0); -#define CONTROL_ICON(text, id, x, y, width, height, style, exStyle) \ - m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_ICON, exStyle, text, NULL, 0); -#define CONTROL_CONTROL(text, id, className, style, x, y, width, height, exStyle) \ - m_Template.AddControl(className, (WORD)id, x, y, width, height, style, exStyle, text, NULL, 0); - - -/////////////////////////////////////////////////////////////////////////////// -// CIndirectDialogImpl - dialogs with template in memory - -template > -class ATL_NO_VTABLE CIndirectDialogImpl : public TBase -{ -public: - enum { IDD = 0 }; // no dialog template resource - - TDlgTemplate m_Template; - - void CreateTemplate() - { - T* pT = static_cast(this); - pT->DoInitTemplate(); - pT->DoInitControls(); - } - - INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow(), LPARAM dwInitParam = NULL) - { - T* pT = static_cast(this); - ATLASSERT(pT->m_hWnd == NULL); - - if (!m_Template.IsValid()) - CreateTemplate(); - -#if (_ATL_VER >= 0x0800) - // Allocate the thunk structure here, where we can fail gracefully. - BOOL result = m_thunk.Init(NULL, NULL); - if (result == FALSE) - { - SetLastError(ERROR_OUTOFMEMORY); - return -1; - } -#endif // (_ATL_VER >= 0x0800) - - ModuleHelper::AddCreateWndData(&m_thunk.cd, pT); - -#ifdef _DEBUG - m_bModal = true; -#endif // _DEBUG - - return ::DialogBoxIndirectParam(ModuleHelper::GetResourceInstance(), m_Template.GetTemplatePtr(), hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam); - } - - HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL) - { - T* pT = static_cast(this); - ATLASSERT(pT->m_hWnd == NULL); - - if (!m_Template.IsValid()) - CreateTemplate(); - -#if (_ATL_VER >= 0x0800) - // Allocate the thunk structure here, where we can fail gracefully. - BOOL result = m_thunk.Init(NULL, NULL); - if (result == FALSE) - { - SetLastError(ERROR_OUTOFMEMORY); - return NULL; - } -#endif // (_ATL_VER >= 0x0800) - - ModuleHelper::AddCreateWndData(&m_thunk.cd, pT); - -#ifdef _DEBUG - m_bModal = false; -#endif // _DEBUG - - HWND hWnd = ::CreateDialogIndirectParam(ModuleHelper::GetResourceInstance(), (LPCDLGTEMPLATE)m_Template.GetTemplatePtr(), hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam); - ATLASSERT(m_hWnd == hWnd); - - return hWnd; - } - - // for CComControl - HWND Create(HWND hWndParent, RECT&, LPARAM dwInitParam = NULL) - { - return Create(hWndParent, dwInitParam); - } - - void DoInitTemplate() - { - ATLASSERT(FALSE); // MUST be defined in derived class - } - - void DoInitControls() - { - ATLASSERT(FALSE); // MUST be defined in derived class - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// CPropertySheetWindow - client side for a property sheet - -class CPropertySheetWindow : public ATL::CWindow -{ -public: -// Constructors - CPropertySheetWindow(HWND hWnd = NULL) : ATL::CWindow(hWnd) - { } - - CPropertySheetWindow& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - -// Attributes - int GetPageCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - HWND hWndTabCtrl = GetTabControl(); - ATLASSERT(hWndTabCtrl != NULL); - return (int)::SendMessage(hWndTabCtrl, TCM_GETITEMCOUNT, 0, 0L); - } - - HWND GetActivePage() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HWND)::SendMessage(m_hWnd, PSM_GETCURRENTPAGEHWND, 0, 0L); - } - - int GetActiveIndex() const - { - ATLASSERT(::IsWindow(m_hWnd)); - HWND hWndTabCtrl = GetTabControl(); - ATLASSERT(hWndTabCtrl != NULL); - return (int)::SendMessage(hWndTabCtrl, TCM_GETCURSEL, 0, 0L); - } - - BOOL SetActivePage(int nPageIndex) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, PSM_SETCURSEL, nPageIndex, 0L); - } - - BOOL SetActivePage(HPROPSHEETPAGE hPage) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(hPage != NULL); - return (BOOL)::SendMessage(m_hWnd, PSM_SETCURSEL, 0, (LPARAM)hPage); - } - - BOOL SetActivePageByID(int nPageID) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, PSM_SETCURSELID, 0, nPageID); - } - - void SetTitle(LPCTSTR lpszText, UINT nStyle = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT((nStyle & ~PSH_PROPTITLE) == 0); // only PSH_PROPTITLE is valid - ATLASSERT(lpszText != NULL); - ::SendMessage(m_hWnd, PSM_SETTITLE, nStyle, (LPARAM)lpszText); - } - - HWND GetTabControl() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HWND)::SendMessage(m_hWnd, PSM_GETTABCONTROL, 0, 0L); - } - - void SetFinishText(LPCTSTR lpszText) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, PSM_SETFINISHTEXT, 0, (LPARAM)lpszText); - } - - void SetWizardButtons(DWORD dwFlags) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::PostMessage(m_hWnd, PSM_SETWIZBUTTONS, 0, dwFlags); - } - -// Operations - BOOL AddPage(HPROPSHEETPAGE hPage) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(hPage != NULL); - return (BOOL)::SendMessage(m_hWnd, PSM_ADDPAGE, 0, (LPARAM)hPage); - } - - BOOL AddPage(LPCPROPSHEETPAGE pPage) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pPage != NULL); - HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage); - if(hPage == NULL) - return FALSE; - return (BOOL)::SendMessage(m_hWnd, PSM_ADDPAGE, 0, (LPARAM)hPage); - } - -#ifndef _WIN32_WCE - BOOL InsertPage(int nNewPageIndex, HPROPSHEETPAGE hPage) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(hPage != NULL); - return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, nNewPageIndex, (LPARAM)hPage); - } - - BOOL InsertPage(int nNewPageIndex, LPCPROPSHEETPAGE pPage) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pPage != NULL); - HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage); - if(hPage == NULL) - return FALSE; - return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, nNewPageIndex, (LPARAM)hPage); - } - - BOOL InsertPage(HPROPSHEETPAGE hPageInsertAfter, HPROPSHEETPAGE hPage) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(hPage != NULL); - return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, (WPARAM)hPageInsertAfter, (LPARAM)hPage); - } - - BOOL InsertPage(HPROPSHEETPAGE hPageInsertAfter, LPCPROPSHEETPAGE pPage) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pPage != NULL); - HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage); - if(hPage == NULL) - return FALSE; - return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, (WPARAM)hPageInsertAfter, (LPARAM)hPage); - } -#endif // !_WIN32_WCE - - void RemovePage(int nPageIndex) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, PSM_REMOVEPAGE, nPageIndex, 0L); - } - - void RemovePage(HPROPSHEETPAGE hPage) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(hPage != NULL); - ::SendMessage(m_hWnd, PSM_REMOVEPAGE, 0, (LPARAM)hPage); - } - - BOOL PressButton(int nButton) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, PSM_PRESSBUTTON, nButton, 0L); - } - - BOOL Apply() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, PSM_APPLY, 0, 0L); - } - - void CancelToClose() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, PSM_CANCELTOCLOSE, 0, 0L); - } - - void SetModified(HWND hWndPage, BOOL bChanged = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(::IsWindow(hWndPage)); - UINT uMsg = bChanged ? PSM_CHANGED : PSM_UNCHANGED; - ::SendMessage(m_hWnd, uMsg, (WPARAM)hWndPage, 0L); - } - - LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam) - { - ATLASSERT(::IsWindow(m_hWnd)); - return ::SendMessage(m_hWnd, PSM_QUERYSIBLINGS, wParam, lParam); - } - - void RebootSystem() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, PSM_REBOOTSYSTEM, 0, 0L); - } - - void RestartWindows() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, PSM_RESTARTWINDOWS, 0, 0L); - } - - BOOL IsDialogMessage(LPMSG lpMsg) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, PSM_ISDIALOGMESSAGE, 0, (LPARAM)lpMsg); - } - -#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - int HwndToIndex(HWND hWnd) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, PSM_HWNDTOINDEX, (WPARAM)hWnd, 0L); - } - - HWND IndexToHwnd(int nIndex) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HWND)::SendMessage(m_hWnd, PSM_INDEXTOHWND, nIndex, 0L); - } - - int PageToIndex(HPROPSHEETPAGE hPage) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, PSM_PAGETOINDEX, 0, (LPARAM)hPage); - } - - HPROPSHEETPAGE IndexToPage(int nIndex) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HPROPSHEETPAGE)::SendMessage(m_hWnd, PSM_INDEXTOPAGE, nIndex, 0L); - } - - int IdToIndex(int nID) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, PSM_IDTOINDEX, 0, nID); - } - - int IndexToId(int nIndex) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, PSM_INDEXTOID, nIndex, 0L); - } - - int GetResult() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, PSM_GETRESULT, 0, 0L); - } - - BOOL RecalcPageSizes() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, PSM_RECALCPAGESIZES, 0, 0L); - } - - void SetHeaderTitle(int nIndex, LPCTSTR lpstrHeaderTitle) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, PSM_SETHEADERTITLE, nIndex, (LPARAM)lpstrHeaderTitle); - } - - void SetHeaderSubTitle(int nIndex, LPCTSTR lpstrHeaderSubTitle) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, PSM_SETHEADERSUBTITLE, nIndex, (LPARAM)lpstrHeaderSubTitle); - } -#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - -// Implementation - override to prevent usage - HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL) - { - ATLASSERT(FALSE); - return NULL; - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// CPropertySheetImpl - implements a property sheet - -template -class ATL_NO_VTABLE CPropertySheetImpl : public ATL::CWindowImplBaseT< TBase > -{ -public: - PROPSHEETHEADER m_psh; - ATL::CSimpleArray m_arrPages; - -#if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific - #ifndef PROPSHEET_LINK_SIZE - #define PROPSHEET_LINK_SIZE 128 - #endif // PROPSHEET_LINK_SIZE - TCHAR m_szLink[PROPSHEET_LINK_SIZE]; - static LPCTSTR m_pszTitle; - static LPCTSTR m_pszLink; -#endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) - -// Construction/Destruction - CPropertySheetImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL) - { - memset(&m_psh, 0, sizeof(PROPSHEETHEADER)); - m_psh.dwSize = sizeof(PROPSHEETHEADER); - m_psh.dwFlags = PSH_USECALLBACK; - m_psh.hInstance = ModuleHelper::GetResourceInstance(); - m_psh.phpage = NULL; // will be set later - m_psh.nPages = 0; // will be set later - m_psh.pszCaption = title.m_lpstr; - m_psh.nStartPage = uStartPage; - m_psh.hwndParent = hWndParent; // if NULL, will be set in DoModal/Create - m_psh.pfnCallback = T::PropSheetCallback; - -#if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific - m_psh.dwFlags |= PSH_MAXIMIZE; - m_szLink[0] = 0; -#endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) - } - - ~CPropertySheetImpl() - { - if(m_arrPages.GetSize() > 0) // sheet never created, destroy all pages - { - for(int i = 0; i < m_arrPages.GetSize(); i++) - ::DestroyPropertySheetPage((HPROPSHEETPAGE)m_arrPages[i]); - } - } - -// Callback function and overrideables - static int CALLBACK PropSheetCallback(HWND hWnd, UINT uMsg, LPARAM lParam) - { - lParam; // avoid level 4 warning - int nRet = 0; - - if(uMsg == PSCB_INITIALIZED) - { - ATLASSERT(hWnd != NULL); - T* pT = (T*)ModuleHelper::ExtractCreateWndData(); - // subclass the sheet window - pT->SubclassWindow(hWnd); - // remove page handles array - pT->_CleanUpPages(); - -#if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific - m_pszTitle = pT->m_psh.pszCaption; - if(*pT->m_szLink != 0) - m_pszLink = pT->m_szLink; -#endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific - - pT->OnSheetInitialized(); - } -#if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific uMsg - else - { - switch(uMsg) - { - case PSCB_GETVERSION : - nRet = COMCTL32_VERSION; - break; - case PSCB_GETTITLE : - if(m_pszTitle != NULL) - { - lstrcpy((LPTSTR)lParam, m_pszTitle); - m_pszTitle = NULL; - } - break; - case PSCB_GETLINKTEXT: - if(m_pszLink != NULL) - { - lstrcpy((LPTSTR)lParam, m_pszLink); - m_pszLink = NULL; - } - break; - default: - break; - } - } -#endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) - - return nRet; - } - - void OnSheetInitialized() - { - } - -// Create method - HWND Create(HWND hWndParent = NULL) - { - ATLASSERT(m_hWnd == NULL); - - m_psh.dwFlags |= PSH_MODELESS; - if(m_psh.hwndParent == NULL) - m_psh.hwndParent = hWndParent; - m_psh.phpage = (HPROPSHEETPAGE*)m_arrPages.GetData(); - m_psh.nPages = m_arrPages.GetSize(); - - T* pT = static_cast(this); - ModuleHelper::AddCreateWndData(&pT->m_thunk.cd, pT); - - HWND hWnd = (HWND)::PropertySheet(&m_psh); - _CleanUpPages(); // ensure clean-up, required if call failed - - ATLASSERT(m_hWnd == hWnd); - - return hWnd; - } - - INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) - { - ATLASSERT(m_hWnd == NULL); - - m_psh.dwFlags &= ~PSH_MODELESS; - if(m_psh.hwndParent == NULL) - m_psh.hwndParent = hWndParent; - m_psh.phpage = (HPROPSHEETPAGE*)m_arrPages.GetData(); - m_psh.nPages = m_arrPages.GetSize(); - - T* pT = static_cast(this); - ModuleHelper::AddCreateWndData(&pT->m_thunk.cd, pT); - - INT_PTR nRet = ::PropertySheet(&m_psh); - _CleanUpPages(); // ensure clean-up, required if call failed - - return nRet; - } - - // implementation helper - clean up pages array - void _CleanUpPages() - { - m_psh.nPages = 0; - m_psh.phpage = NULL; - m_arrPages.RemoveAll(); - } - -// Attributes (extended overrides of client class methods) -// These now can be called before the sheet is created -// Note: Calling these after the sheet is created gives unpredictable results - int GetPageCount() const - { - if(m_hWnd == NULL) // not created yet - return m_arrPages.GetSize(); - return TBase::GetPageCount(); - } - - int GetActiveIndex() const - { - if(m_hWnd == NULL) // not created yet - return m_psh.nStartPage; - return TBase::GetActiveIndex(); - } - - HPROPSHEETPAGE GetPage(int nPageIndex) const - { - ATLASSERT(m_hWnd == NULL); // can't do this after it's created - return (HPROPSHEETPAGE)m_arrPages[nPageIndex]; - } - - int GetPageIndex(HPROPSHEETPAGE hPage) const - { - ATLASSERT(m_hWnd == NULL); // can't do this after it's created - return m_arrPages.Find((HPROPSHEETPAGE&)hPage); - } - - BOOL SetActivePage(int nPageIndex) - { - if(m_hWnd == NULL) // not created yet - { - ATLASSERT(nPageIndex >= 0 && nPageIndex < m_arrPages.GetSize()); - m_psh.nStartPage = nPageIndex; - return TRUE; - } - return TBase::SetActivePage(nPageIndex); - } - - BOOL SetActivePage(HPROPSHEETPAGE hPage) - { - ATLASSERT(hPage != NULL); - if (m_hWnd == NULL) // not created yet - { - int nPageIndex = GetPageIndex(hPage); - if(nPageIndex == -1) - return FALSE; - - return SetActivePage(nPageIndex); - } - return TBase::SetActivePage(hPage); - - } - - void SetTitle(LPCTSTR lpszText, UINT nStyle = 0) - { - ATLASSERT((nStyle & ~PSH_PROPTITLE) == 0); // only PSH_PROPTITLE is valid - ATLASSERT(lpszText != NULL); - - if(m_hWnd == NULL) - { - // set internal state - m_psh.pszCaption = lpszText; // must exist until sheet is created - m_psh.dwFlags &= ~PSH_PROPTITLE; - m_psh.dwFlags |= nStyle; - } - else - { - // set external state - TBase::SetTitle(lpszText, nStyle); - } - } - -#if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific Link field - void SetLinkText(LPCTSTR lpszText) - { - ATLASSERT(lpszText != NULL); - ATLASSERT(lstrlen(lpszText) < PROPSHEET_LINK_SIZE); - lstrcpy(m_szLink, lpszText); - } -#endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) - - void SetWizardMode() - { - m_psh.dwFlags |= PSH_WIZARD; - } - - void EnableHelp() - { - m_psh.dwFlags |= PSH_HASHELP; - } - -// Operations - BOOL AddPage(HPROPSHEETPAGE hPage) - { - ATLASSERT(hPage != NULL); - BOOL bRet = FALSE; - if(m_hWnd != NULL) - bRet = TBase::AddPage(hPage); - else // sheet not created yet, use internal data - bRet = m_arrPages.Add((HPROPSHEETPAGE&)hPage); - return bRet; - } - - BOOL AddPage(LPCPROPSHEETPAGE pPage) - { - ATLASSERT(pPage != NULL); - HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage); - if(hPage == NULL) - return FALSE; - BOOL bRet = AddPage(hPage); - if(!bRet) - ::DestroyPropertySheetPage(hPage); - return bRet; - } - - BOOL RemovePage(HPROPSHEETPAGE hPage) - { - ATLASSERT(hPage != NULL); - if (m_hWnd == NULL) // not created yet - { - int nPage = GetPageIndex(hPage); - if(nPage == -1) - return FALSE; - return RemovePage(nPage); - } - TBase::RemovePage(hPage); - return TRUE; - - } - - BOOL RemovePage(int nPageIndex) - { - BOOL bRet = TRUE; - if(m_hWnd != NULL) - TBase::RemovePage(nPageIndex); - else // sheet not created yet, use internal data - bRet = m_arrPages.RemoveAt(nPageIndex); - return bRet; - } - -#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - void SetHeader(LPCTSTR szbmHeader) - { - ATLASSERT(m_hWnd == NULL); // can't do this after it's created - - m_psh.dwFlags &= ~PSH_WIZARD; - m_psh.dwFlags |= (PSH_HEADER | PSH_WIZARD97); - m_psh.pszbmHeader = szbmHeader; - } - - void SetHeader(HBITMAP hbmHeader) - { - ATLASSERT(m_hWnd == NULL); // can't do this after it's created - - m_psh.dwFlags &= ~PSH_WIZARD; - m_psh.dwFlags |= (PSH_HEADER | PSH_USEHBMHEADER | PSH_WIZARD97); - m_psh.hbmHeader = hbmHeader; - } - - void SetWatermark(LPCTSTR szbmWatermark, HPALETTE hplWatermark = NULL) - { - ATLASSERT(m_hWnd == NULL); // can't do this after it's created - - m_psh.dwFlags &= ~PSH_WIZARD; - m_psh.dwFlags |= PSH_WATERMARK | PSH_WIZARD97; - m_psh.pszbmWatermark = szbmWatermark; - - if (hplWatermark != NULL) - { - m_psh.dwFlags |= PSH_USEHPLWATERMARK; - m_psh.hplWatermark = hplWatermark; - } - } - - void SetWatermark(HBITMAP hbmWatermark, HPALETTE hplWatermark = NULL) - { - ATLASSERT(m_hWnd == NULL); // can't do this after it's created - - m_psh.dwFlags &= ~PSH_WIZARD; - m_psh.dwFlags |= (PSH_WATERMARK | PSH_USEHBMWATERMARK | PSH_WIZARD97); - m_psh.hbmWatermark = hbmWatermark; - - if (hplWatermark != NULL) - { - m_psh.dwFlags |= PSH_USEHPLWATERMARK; - m_psh.hplWatermark = hplWatermark; - } - } - - void StretchWatermark(bool bStretchWatermark) - { - ATLASSERT(m_hWnd == NULL); // can't do this after it's created - if (bStretchWatermark) - m_psh.dwFlags |= PSH_STRETCHWATERMARK; - else - m_psh.dwFlags &= ~PSH_STRETCHWATERMARK; - } -#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - -// Message map and handlers - BEGIN_MSG_MAP(CPropertySheetImpl) - MESSAGE_HANDLER(WM_COMMAND, OnCommand) - MESSAGE_HANDLER(WM_SYSCOMMAND, OnSysCommand) - END_MSG_MAP() - - LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); - if(HIWORD(wParam) == BN_CLICKED && (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) && - ((m_psh.dwFlags & PSH_MODELESS) != 0) && (GetActivePage() == NULL)) - DestroyWindow(); - return lRet; - } - - LRESULT OnSysCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - if(((m_psh.dwFlags & PSH_MODELESS) == PSH_MODELESS) && ((wParam & 0xFFF0) == SC_CLOSE)) - SendMessage(WM_CLOSE); - else - bHandled = FALSE; - return 0; - } -}; - -#if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC static pointers -template < class T, class TBase > -LPCWSTR CPropertySheetImpl::m_pszTitle = NULL; -template < class T, class TBase> -LPCWSTR CPropertySheetImpl::m_pszLink = NULL; -#endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) - -// for non-customized sheets -class CPropertySheet : public CPropertySheetImpl -{ -public: - CPropertySheet(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL) - : CPropertySheetImpl(title, uStartPage, hWndParent) - { } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CPropertyPageWindow - client side for a property page - -class CPropertyPageWindow : public ATL::CWindow -{ -public: -// Constructors - CPropertyPageWindow(HWND hWnd = NULL) : ATL::CWindow(hWnd) - { } - - CPropertyPageWindow& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - -// Attributes - CPropertySheetWindow GetPropertySheet() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CPropertySheetWindow(GetParent()); - } - -// Operations - BOOL Apply() - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(GetParent() != NULL); - return GetPropertySheet().Apply(); - } - - void CancelToClose() - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(GetParent() != NULL); - GetPropertySheet().CancelToClose(); - } - - void SetModified(BOOL bChanged = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(GetParent() != NULL); - GetPropertySheet().SetModified(m_hWnd, bChanged); - } - - LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(GetParent() != NULL); - return GetPropertySheet().QuerySiblings(wParam, lParam); - } - - void RebootSystem() - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(GetParent() != NULL); - GetPropertySheet().RebootSystem(); - } - - void RestartWindows() - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(GetParent() != NULL); - GetPropertySheet().RestartWindows(); - } - - void SetWizardButtons(DWORD dwFlags) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(GetParent() != NULL); - GetPropertySheet().SetWizardButtons(dwFlags); - } - -// Implementation - overrides to prevent usage - HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL) - { - ATLASSERT(FALSE); - return NULL; - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// CPropertyPageImpl - implements a property page - -template -class ATL_NO_VTABLE CPropertyPageImpl : public ATL::CDialogImplBaseT< TBase > -{ -public: - PROPSHEETPAGE m_psp; - - operator PROPSHEETPAGE*() { return &m_psp; } - -// Construction - CPropertyPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) - { - // initialize PROPSHEETPAGE struct - memset(&m_psp, 0, sizeof(PROPSHEETPAGE)); - m_psp.dwSize = sizeof(PROPSHEETPAGE); - m_psp.dwFlags = PSP_USECALLBACK; - m_psp.hInstance = ModuleHelper::GetResourceInstance(); - T* pT = static_cast(this); - m_psp.pszTemplate = MAKEINTRESOURCE(pT->IDD); - m_psp.pfnDlgProc = (DLGPROC)T::StartDialogProc; - m_psp.pfnCallback = T::PropPageCallback; - m_psp.lParam = (LPARAM)pT; - - if(title.m_lpstr != NULL) - SetTitle(title); - } - -// Callback function and overrideables - static UINT CALLBACK PropPageCallback(HWND hWnd, UINT uMsg, LPPROPSHEETPAGE ppsp) - { - hWnd; // avoid level 4 warning - ATLASSERT(hWnd == NULL); - T* pT = (T*)ppsp->lParam; - UINT uRet = 0; - - switch(uMsg) - { - case PSPCB_CREATE: - { - ATL::CDialogImplBaseT< TBase >* pPage = (ATL::CDialogImplBaseT< TBase >*)pT; - ModuleHelper::AddCreateWndData(&pPage->m_thunk.cd, pPage); - uRet = pT->OnPageCreate() ? 1 : 0; - } - break; -#if (_WIN32_IE >= 0x0500) - case PSPCB_ADDREF: - pT->OnPageAddRef(); - break; -#endif // (_WIN32_IE >= 0x0500) - case PSPCB_RELEASE: - pT->OnPageRelease(); - break; - default: - break; - } - - return uRet; - } - - bool OnPageCreate() - { - return true; // true - allow page to be created, false - prevent creation - } - -#if (_WIN32_IE >= 0x0500) - void OnPageAddRef() - { - } -#endif // (_WIN32_IE >= 0x0500) - - void OnPageRelease() - { - } - -// Create method - HPROPSHEETPAGE Create() - { - return ::CreatePropertySheetPage(&m_psp); - } - -// Attributes - void SetTitle(ATL::_U_STRINGorID title) - { - m_psp.pszTitle = title.m_lpstr; - m_psp.dwFlags |= PSP_USETITLE; - } - -#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - void SetHeaderTitle(LPCTSTR lpstrHeaderTitle) - { - ATLASSERT(m_hWnd == NULL); // can't do this after it's created - m_psp.dwFlags |= PSP_USEHEADERTITLE; - m_psp.pszHeaderTitle = lpstrHeaderTitle; - } - - void SetHeaderSubTitle(LPCTSTR lpstrHeaderSubTitle) - { - ATLASSERT(m_hWnd == NULL); // can't do this after it's created - m_psp.dwFlags |= PSP_USEHEADERSUBTITLE; - m_psp.pszHeaderSubTitle = lpstrHeaderSubTitle; - } -#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - -// Operations - void EnableHelp() - { - m_psp.dwFlags |= PSP_HASHELP; - } - -// Message map and handlers - BEGIN_MSG_MAP(CPropertyPageImpl) - MESSAGE_HANDLER(WM_NOTIFY, OnNotify) - END_MSG_MAP() - - // NOTE: Define _WTL_NEW_PAGE_NOTIFY_HANDLERS to use new notification - // handlers that return direct values without any restrictions - LRESULT OnNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { -#ifndef _WIN32_WCE - // This notification is sometimes received on Windows CE after the window is already destroyed - ATLASSERT(::IsWindow(m_hWnd)); -#endif - NMHDR* pNMHDR = (NMHDR*)lParam; - - // don't handle messages not from the page/sheet itself - if(pNMHDR->hwndFrom != m_hWnd && pNMHDR->hwndFrom != ::GetParent(m_hWnd)) - { - bHandled = FALSE; - return 1; - } -#ifdef _WIN32_WCE - ATLASSERT(::IsWindow(m_hWnd)); -#endif - - T* pT = static_cast(this); - LRESULT lResult = 0; - switch(pNMHDR->code) - { -#ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS - case PSN_SETACTIVE: - lResult = pT->OnSetActive(); - break; - case PSN_KILLACTIVE: - lResult = pT->OnKillActive(); - break; - case PSN_APPLY: - lResult = pT->OnApply(); - break; - case PSN_RESET: - pT->OnReset(); - break; - case PSN_QUERYCANCEL: - lResult = pT->OnQueryCancel(); - break; - case PSN_WIZNEXT: - lResult = pT->OnWizardNext(); - break; - case PSN_WIZBACK: - lResult = pT->OnWizardBack(); - break; - case PSN_WIZFINISH: - lResult = pT->OnWizardFinish(); - break; - case PSN_HELP: - pT->OnHelp(); - break; -#ifndef _WIN32_WCE -#if (_WIN32_IE >= 0x0400) - case PSN_GETOBJECT: - if(!pT->OnGetObject((LPNMOBJECTNOTIFY)lParam)) - bHandled = FALSE; - break; -#endif // (_WIN32_IE >= 0x0400) -#if (_WIN32_IE >= 0x0500) - case PSN_TRANSLATEACCELERATOR: - { - LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam; - lResult = pT->OnTranslateAccelerator((LPMSG)lpPSHNotify->lParam); - } - break; - case PSN_QUERYINITIALFOCUS: - { - LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam; - lResult = (LRESULT)pT->OnQueryInitialFocus((HWND)lpPSHNotify->lParam); - } - break; -#endif // (_WIN32_IE >= 0x0500) -#endif // !_WIN32_WCE - -#else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS - case PSN_SETACTIVE: - lResult = pT->OnSetActive() ? 0 : -1; - break; - case PSN_KILLACTIVE: - lResult = !pT->OnKillActive(); - break; - case PSN_APPLY: - lResult = pT->OnApply() ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE; - break; - case PSN_RESET: - pT->OnReset(); - break; - case PSN_QUERYCANCEL: - lResult = !pT->OnQueryCancel(); - break; - case PSN_WIZNEXT: - lResult = pT->OnWizardNext(); - break; - case PSN_WIZBACK: - lResult = pT->OnWizardBack(); - break; - case PSN_WIZFINISH: - lResult = !pT->OnWizardFinish(); - break; - case PSN_HELP: - pT->OnHelp(); - break; -#ifndef _WIN32_WCE -#if (_WIN32_IE >= 0x0400) - case PSN_GETOBJECT: - if(!pT->OnGetObject((LPNMOBJECTNOTIFY)lParam)) - bHandled = FALSE; - break; -#endif // (_WIN32_IE >= 0x0400) -#if (_WIN32_IE >= 0x0500) - case PSN_TRANSLATEACCELERATOR: - { - LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam; - lResult = pT->OnTranslateAccelerator((LPMSG)lpPSHNotify->lParam) ? PSNRET_MESSAGEHANDLED : PSNRET_NOERROR; - } - break; - case PSN_QUERYINITIALFOCUS: - { - LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam; - lResult = (LRESULT)pT->OnQueryInitialFocus((HWND)lpPSHNotify->lParam); - } - break; -#endif // (_WIN32_IE >= 0x0500) -#endif // !_WIN32_WCE - -#endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS - default: - bHandled = FALSE; // not handled - } - - return lResult; - } - -// Overridables - // NOTE: Define _WTL_NEW_PAGE_NOTIFY_HANDLERS to use new notification - // handlers that return direct values without any restrictions -#ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS - int OnSetActive() - { - // 0 = allow activate - // -1 = go back that was active - // page ID = jump to page - return 0; - } - - BOOL OnKillActive() - { - // FALSE = allow deactivate - // TRUE = prevent deactivation - return FALSE; - } - - int OnApply() - { - // PSNRET_NOERROR = apply OK - // PSNRET_INVALID = apply not OK, return to this page - // PSNRET_INVALID_NOCHANGEPAGE = apply not OK, don't change focus - return PSNRET_NOERROR; - } - - void OnReset() - { - } - - BOOL OnQueryCancel() - { - // FALSE = allow cancel - // TRUE = prevent cancel - return FALSE; - } - - int OnWizardBack() - { - // 0 = goto previous page - // -1 = prevent page change - // >0 = jump to page by dlg ID - return 0; - } - - int OnWizardNext() - { - // 0 = goto next page - // -1 = prevent page change - // >0 = jump to page by dlg ID - return 0; - } - - INT_PTR OnWizardFinish() - { - // FALSE = allow finish - // TRUE = prevent finish - // HWND = prevent finish and set focus to HWND (CommCtrl 5.80 only) - return FALSE; - } - - void OnHelp() - { - } - -#ifndef _WIN32_WCE -#if (_WIN32_IE >= 0x0400) - BOOL OnGetObject(LPNMOBJECTNOTIFY /*lpObjectNotify*/) - { - return FALSE; // not processed - } -#endif // (_WIN32_IE >= 0x0400) - -#if (_WIN32_IE >= 0x0500) - int OnTranslateAccelerator(LPMSG /*lpMsg*/) - { - // PSNRET_NOERROR - message not handled - // PSNRET_MESSAGEHANDLED - message handled - return PSNRET_NOERROR; - } - - HWND OnQueryInitialFocus(HWND /*hWndFocus*/) - { - // NULL = set focus to default control - // HWND = set focus to HWND - return NULL; - } -#endif // (_WIN32_IE >= 0x0500) -#endif // !_WIN32_WCE - -#else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS - BOOL OnSetActive() - { - return TRUE; - } - - BOOL OnKillActive() - { - return TRUE; - } - - BOOL OnApply() - { - return TRUE; - } - - void OnReset() - { - } - - BOOL OnQueryCancel() - { - return TRUE; // ok to cancel - } - - int OnWizardBack() - { - // 0 = goto previous page - // -1 = prevent page change - // >0 = jump to page by dlg ID - return 0; - } - - int OnWizardNext() - { - // 0 = goto next page - // -1 = prevent page change - // >0 = jump to page by dlg ID - return 0; - } - - BOOL OnWizardFinish() - { - return TRUE; - } - - void OnHelp() - { - } - -#ifndef _WIN32_WCE -#if (_WIN32_IE >= 0x0400) - BOOL OnGetObject(LPNMOBJECTNOTIFY /*lpObjectNotify*/) - { - return FALSE; // not processed - } -#endif // (_WIN32_IE >= 0x0400) - -#if (_WIN32_IE >= 0x0500) - BOOL OnTranslateAccelerator(LPMSG /*lpMsg*/) - { - return FALSE; // not translated - } - - HWND OnQueryInitialFocus(HWND /*hWndFocus*/) - { - return NULL; // default - } -#endif // (_WIN32_IE >= 0x0500) -#endif // !_WIN32_WCE - -#endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS -}; - -// for non-customized pages -template -class CPropertyPage : public CPropertyPageImpl > -{ -public: - enum { IDD = t_wDlgTemplateID }; - - CPropertyPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CPropertyPageImpl(title) - { } - - DECLARE_EMPTY_MSG_MAP() -}; - -/////////////////////////////////////////////////////////////////////////////// -// CAxPropertyPageImpl - property page that hosts ActiveX controls - -#ifndef _ATL_NO_HOSTING - -// Note: You must #include to use these classes - -template -class ATL_NO_VTABLE CAxPropertyPageImpl : public CPropertyPageImpl< T, TBase > -{ -public: -// Data members - HGLOBAL m_hInitData; - HGLOBAL m_hDlgRes; - HGLOBAL m_hDlgResSplit; - -// Constructor/destructor - CAxPropertyPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : - CPropertyPageImpl< T, TBase >(title), - m_hInitData(NULL), m_hDlgRes(NULL), m_hDlgResSplit(NULL) - { - T* pT = static_cast(this); - pT; // avoid level 4 warning - - // initialize ActiveX hosting and modify dialog template - ATL::AtlAxWinInit(); - - HINSTANCE hInstance = ModuleHelper::GetResourceInstance(); - LPCTSTR lpTemplateName = MAKEINTRESOURCE(pT->IDD); - HRSRC hDlg = ::FindResource(hInstance, lpTemplateName, (LPTSTR)RT_DIALOG); - if(hDlg != NULL) - { - HRSRC hDlgInit = ::FindResource(hInstance, lpTemplateName, (LPTSTR)_ATL_RT_DLGINIT); - - BYTE* pInitData = NULL; - if(hDlgInit != NULL) - { - m_hInitData = ::LoadResource(hInstance, hDlgInit); - pInitData = (BYTE*)::LockResource(m_hInitData); - } - - m_hDlgRes = ::LoadResource(hInstance, hDlg); - DLGTEMPLATE* pDlg = (DLGTEMPLATE*)::LockResource(m_hDlgRes); - LPCDLGTEMPLATE lpDialogTemplate = ATL::_DialogSplitHelper::SplitDialogTemplate(pDlg, pInitData); - if(lpDialogTemplate != pDlg) - m_hDlgResSplit = GlobalHandle(lpDialogTemplate); - - // set up property page to use in-memory dialog template - if(lpDialogTemplate != NULL) - { - m_psp.dwFlags |= PSP_DLGINDIRECT; - m_psp.pResource = lpDialogTemplate; - } - else - { - ATLASSERT(FALSE && _T("CAxPropertyPageImpl - ActiveX initializtion failed!")); - } - } - else - { - ATLASSERT(FALSE && _T("CAxPropertyPageImpl - Cannot find dialog template!")); - } - } - - ~CAxPropertyPageImpl() - { - if(m_hInitData != NULL) - { - UnlockResource(m_hInitData); - FreeResource(m_hInitData); - } - if(m_hDlgRes != NULL) - { - UnlockResource(m_hDlgRes); - FreeResource(m_hDlgRes); - } - if(m_hDlgResSplit != NULL) - { - ::GlobalFree(m_hDlgResSplit); - } - } - -// Methods - // call this one to handle keyboard message for ActiveX controls - BOOL PreTranslateMessage(LPMSG pMsg) - { - if ((pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST) && - (pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAST)) - return FALSE; - // find a direct child of the dialog from the window that has focus - HWND hWndCtl = ::GetFocus(); - if (IsChild(hWndCtl) && ::GetParent(hWndCtl) != m_hWnd) - { - do - { - hWndCtl = ::GetParent(hWndCtl); - } - while (::GetParent(hWndCtl) != m_hWnd); - } - // give controls a chance to translate this message - return (BOOL)::SendMessage(hWndCtl, WM_FORWARDMSG, 0, (LPARAM)pMsg); - } - -// Overridables -#if (_WIN32_IE >= 0x0500) - // new default implementation for ActiveX hosting pages -#ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS - int OnTranslateAccelerator(LPMSG lpMsg) - { - T* pT = static_cast(this); - return (pT->PreTranslateMessage(lpMsg) != FALSE) ? PSNRET_MESSAGEHANDLED : PSNRET_NOERROR; - } -#else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS - BOOL OnTranslateAccelerator(LPMSG lpMsg) - { - T* pT = static_cast(this); - return pT->PreTranslateMessage(lpMsg); - } -#endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS -#endif // (_WIN32_IE >= 0x0500) - -// Support for new stuff in ATL7 -#if (_ATL_VER >= 0x0700) - int GetIDD() - { - return( static_cast(this)->IDD ); - } - - virtual DLGPROC GetDialogProc() - { - return DialogProc; - } - - static INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) - { - CAxPropertyPageImpl< T, TBase >* pThis = (CAxPropertyPageImpl< T, TBase >*)hWnd; - if (uMsg == WM_INITDIALOG) - { - HRESULT hr; - if (FAILED(hr = pThis->CreateActiveXControls(pThis->GetIDD()))) - { - ATLASSERT(FALSE); - return FALSE; - } - } - return CPropertyPageImpl< T, TBase >::DialogProc(hWnd, uMsg, wParam, lParam); - } - -// ActiveX controls creation - virtual HRESULT CreateActiveXControls(UINT nID) - { - // Load dialog template and InitData - HRSRC hDlgInit = ::FindResource(ATL::_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(nID), (LPTSTR)_ATL_RT_DLGINIT); - BYTE* pInitData = NULL; - HGLOBAL hData = NULL; - HRESULT hr = S_OK; - if (hDlgInit != NULL) - { - hData = ::LoadResource(ATL::_AtlBaseModule.GetResourceInstance(), hDlgInit); - if (hData != NULL) - pInitData = (BYTE*) ::LockResource(hData); - } - - HRSRC hDlg = ::FindResource(ATL::_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(nID), (LPTSTR)RT_DIALOG); - if (hDlg != NULL) - { - HGLOBAL hResource = ::LoadResource(ATL::_AtlBaseModule.GetResourceInstance(), hDlg); - DLGTEMPLATE* pDlg = NULL; - if (hResource != NULL) - { - pDlg = (DLGTEMPLATE*) ::LockResource(hResource); - if (pDlg != NULL) - { - // Get first control on the template - BOOL bDialogEx = ATL::_DialogSplitHelper::IsDialogEx(pDlg); - WORD nItems = ATL::_DialogSplitHelper::DlgTemplateItemCount(pDlg); - - // Get first control on the dialog - DLGITEMTEMPLATE* pItem = ATL::_DialogSplitHelper::FindFirstDlgItem(pDlg); - HWND hWndPrev = GetWindow(GW_CHILD); - - // Create all ActiveX cotnrols in the dialog template and place them in the correct tab order (z-order) - for (WORD nItem = 0; nItem < nItems; nItem++) - { - DWORD wID = bDialogEx ? ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->id : pItem->id; - if (ATL::_DialogSplitHelper::IsActiveXControl(pItem, bDialogEx)) - { - BYTE* pData = NULL; - DWORD dwLen = ATL::_DialogSplitHelper::FindCreateData(wID, pInitData, &pData); - ATL::CComPtr spStream; - if (dwLen != 0) - { - HGLOBAL h = GlobalAlloc(GHND, dwLen); - if (h != NULL) - { - BYTE* pBytes = (BYTE*) GlobalLock(h); - BYTE* pSource = pData; - SecureHelper::memcpy_x(pBytes, dwLen, pSource, dwLen); - GlobalUnlock(h); - CreateStreamOnHGlobal(h, TRUE, &spStream); - } - else - { - hr = E_OUTOFMEMORY; - break; - } - } - - ATL::CComBSTR bstrLicKey; - hr = ATL::_DialogSplitHelper::ParseInitData(spStream, &bstrLicKey.m_str); - if (SUCCEEDED(hr)) - { - ATL::CAxWindow2 wnd; - // Get control caption. - LPWSTR pszClassName = - bDialogEx ? - (LPWSTR)(((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem) + 1) : - (LPWSTR)(pItem + 1); - // Get control rect. - RECT rect; - rect.left = - bDialogEx ? - ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->x : - pItem->x; - rect.top = - bDialogEx ? - ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->y : - pItem->y; - rect.right = rect.left + - (bDialogEx ? - ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->cx : - pItem->cx); - rect.bottom = rect.top + - (bDialogEx ? - ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->cy : - pItem->cy); - - // Convert from dialog units to screen units - MapDialogRect(&rect); - - // Create AxWindow with a NULL caption. - wnd.Create(m_hWnd, - &rect, - NULL, - (bDialogEx ? - ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->style : - pItem->style) | WS_TABSTOP, - bDialogEx ? - ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->exStyle : - 0, - bDialogEx ? - ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->id : - pItem->id, - NULL); - - if (wnd != NULL) - { -#ifndef _WIN32_WCE - // Set the Help ID - if (bDialogEx && ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->helpID != 0) - wnd.SetWindowContextHelpId(((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->helpID); -#endif // !_WIN32_WCE - // Try to create the ActiveX control. - hr = wnd.CreateControlLic(pszClassName, spStream, NULL, bstrLicKey); - if (FAILED(hr)) - break; - // Set the correct tab position. - if (nItem == 0) - hWndPrev = HWND_TOP; - wnd.SetWindowPos(hWndPrev, 0,0,0,0,SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); - hWndPrev = wnd; - } - else - { - hr = ATL::AtlHresultFromLastError(); - } - } - } - else - { - if (nItem != 0) - hWndPrev = ::GetWindow(hWndPrev, GW_HWNDNEXT); - } - pItem = ATL::_DialogSplitHelper::FindNextDlgItem(pItem, bDialogEx); - } - } - else - hr = ATL::AtlHresultFromLastError(); - } - else - hr = ATL::AtlHresultFromLastError(); - } - return hr; - } - -// Event handling support - HRESULT AdviseSinkMap(bool bAdvise) - { - if(!bAdvise && m_hWnd == NULL) - { - // window is gone, controls are already unadvised - ATLTRACE2(atlTraceUI, 0, _T("CAxPropertyPageImpl::AdviseSinkMap called after the window was destroyed\n")); - return S_OK; - } - HRESULT hRet = E_NOTIMPL; - __if_exists(T::_GetSinkMapFinder) - { - T* pT = static_cast(this); - hRet = AtlAdviseSinkMap(pT, bAdvise); - } - return hRet; - } - -// Message map and handlers - typedef CPropertyPageImpl< T, TBase> _baseClass; - BEGIN_MSG_MAP(CAxPropertyPageImpl) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) - CHAIN_MSG_MAP(_baseClass) - END_MSG_MAP() - - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - // initialize controls in dialog with DLGINIT resource section - ExecuteDlgInit(static_cast(this)->IDD); - AdviseSinkMap(true); - bHandled = FALSE; - return 1; - } - - LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - AdviseSinkMap(false); - bHandled = FALSE; - return 1; - } -#endif // (_ATL_VER >= 0x0700) -}; - -// for non-customized pages -template -class CAxPropertyPage : public CAxPropertyPageImpl > -{ -public: - enum { IDD = t_wDlgTemplateID }; - - CAxPropertyPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAxPropertyPageImpl(title) - { } - -#if (_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700) - // not empty so we handle accelerators/create controls - BEGIN_MSG_MAP(CAxPropertyPage) - CHAIN_MSG_MAP(CAxPropertyPageImpl >) - END_MSG_MAP() -#else // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)) - DECLARE_EMPTY_MSG_MAP() -#endif // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)) -}; - -#endif // _ATL_NO_HOSTING - - -/////////////////////////////////////////////////////////////////////////////// -// Wizard97 Support - -#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - -// Sample wizard dialog resources: -// -// IDD_WIZ97_INTERIOR_BLANK DIALOG 0, 0, 317, 143 -// STYLE DS_SETFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -// CAPTION "Wizard97 Property Page - Interior" -// FONT 8, "MS Shell Dlg" -// BEGIN -// END -// -// IDD_WIZ97_EXTERIOR_BLANK DIALOGEX 0, 0, 317, 193 -// STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION -// CAPTION "Wizard97 Property Page - Welcome/Complete" -// FONT 8, "MS Shell Dlg", 0, 0, 0x0 -// BEGIN -// LTEXT "Welcome to the X Wizard",IDC_WIZ97_EXTERIOR_TITLE,115,8, -// 195,24 -// LTEXT "Wizard Explanation\r\n(The height of the static text should be in multiples of 8 dlus)", -// IDC_STATIC,115,40,195,16 -// LTEXT "h",IDC_WIZ97_BULLET1,118,64,8,8 -// LTEXT "List Item 1 (the h is turned into a bullet)",IDC_STATIC, -// 127,63,122,8 -// LTEXT "h",IDC_WIZ97_BULLET2,118,79,8,8 -// LTEXT "List Item 2. Keep 7 dlus between paragraphs",IDC_STATIC, -// 127,78,33,8 -// CONTROL "&Do not show this Welcome page again", -// IDC_WIZ97_WELCOME_NOTAGAIN,"Button",BS_AUTOCHECKBOX | -// WS_TABSTOP,115,169,138,10 -// END -// -// GUIDELINES DESIGNINFO -// BEGIN -// IDD_WIZ97_INTERIOR_BLANK, DIALOG -// BEGIN -// LEFTMARGIN, 7 -// RIGHTMARGIN, 310 -// VERTGUIDE, 21 -// VERTGUIDE, 31 -// VERTGUIDE, 286 -// VERTGUIDE, 296 -// TOPMARGIN, 7 -// BOTTOMMARGIN, 136 -// HORZGUIDE, 8 -// END -// -// IDD_WIZ97_EXTERIOR_BLANK, DIALOG -// BEGIN -// RIGHTMARGIN, 310 -// VERTGUIDE, 115 -// VERTGUIDE, 118 -// VERTGUIDE, 127 -// TOPMARGIN, 7 -// BOTTOMMARGIN, 186 -// HORZGUIDE, 8 -// HORZGUIDE, 32 -// HORZGUIDE, 40 -// HORZGUIDE, 169 -// END -// END - -/////////////////////////////////////////////////////////////////////////////// -// CWizard97SheetWindow - client side for a Wizard 97 style wizard sheet - -class CWizard97SheetWindow : public CPropertySheetWindow -{ -public: -// Constructors - CWizard97SheetWindow(HWND hWnd = NULL) : CPropertySheetWindow(hWnd) - { } - - CWizard97SheetWindow& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - -// Operations - HFONT GetExteriorPageTitleFont(void) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HFONT)::SendMessage(m_hWnd, GetMessage_GetExteriorPageTitleFont(), 0, 0L); - } - - HFONT GetBulletFont(void) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HFONT)::SendMessage(m_hWnd, GetMessage_GetBulletFont(), 0, 0L); - } - -// Helpers - static UINT GetMessage_GetExteriorPageTitleFont() - { - static UINT uGetExteriorPageTitleFont = 0; - if(uGetExteriorPageTitleFont == 0) - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CWizard97SheetWindow::GetMessage_GetExteriorPageTitleFont().\n")); - ATLASSERT(FALSE); - return 0; - } - - if(uGetExteriorPageTitleFont == 0) - uGetExteriorPageTitleFont = ::RegisterWindowMessage(_T("GetExteriorPageTitleFont_531AF056-B8BE-4c4c-B786-AC608DF0DF12")); - - lock.Unlock(); - } - ATLASSERT(uGetExteriorPageTitleFont != 0); - return uGetExteriorPageTitleFont; - } - - static UINT GetMessage_GetBulletFont() - { - static UINT uGetBulletFont = 0; - if(uGetBulletFont == 0) - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CWizard97SheetWindow::GetMessage_GetBulletFont().\n")); - ATLASSERT(FALSE); - return 0; - } - - if(uGetBulletFont == 0) - uGetBulletFont = ::RegisterWindowMessage(_T("GetBulletFont_AD347D08-8F65-45ef-982E-6352E8218AD5")); - - lock.Unlock(); - } - ATLASSERT(uGetBulletFont != 0); - return uGetBulletFont; - } - -// Implementation - override to prevent usage - HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL) - { - ATLASSERT(FALSE); - return NULL; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CWizard97SheetImpl - implements a Wizard 97 style wizard sheet - -template -class ATL_NO_VTABLE CWizard97SheetImpl : public CPropertySheetImpl< T, TBase > -{ -protected: -// Typedefs - typedef CWizard97SheetImpl< T, TBase > thisClass; - typedef CPropertySheetImpl< T, TBase > baseClass; - -// Member variables - CFont m_fontExteriorPageTitle; // Welcome and Completion page title font - CFont m_fontBullet; // Bullet font (used on static text 'h' to produce a small bullet) - bool m_bReceivedFirstSizeMessage; - -public: - CWizard97SheetImpl(ATL::_U_STRINGorID title, ATL::_U_STRINGorID headerBitmap, ATL::_U_STRINGorID watermarkBitmap, UINT uStartPage = 0, HWND hWndParent = NULL) : - baseClass(title, uStartPage, hWndParent), - m_bReceivedFirstSizeMessage(false) - { - m_psh.dwFlags &= ~(PSH_NOCONTEXTHELP); - m_psh.dwFlags &= ~(PSH_WIZARD | PSH_WIZARD_LITE); - - m_psh.dwFlags |= (PSH_HASHELP | PSH_WIZARDCONTEXTHELP); - m_psh.dwFlags |= PSH_WIZARD97; - - baseClass::SetHeader(headerBitmap.m_lpstr); - baseClass::SetWatermark(watermarkBitmap.m_lpstr); - } - -// Overrides from base class - void OnSheetInitialized() - { - T* pT = static_cast(this); - pT->_InitializeFonts(); - - // We'd like to center the wizard here, but its too early. - // Instead, we'll do CenterWindow upon our first WM_SIZE message - } - -// Initialization - void _InitializeFonts() - { - // Setup the Title and Bullet Font - // (Property pages can send the "get external page title font" and "get bullet font" messages) - // The derived class needs to do the actual SetFont for the dialog items) - - CFontHandle fontThisDialog = this->GetFont(); - CClientDC dcScreen(NULL); - - LOGFONT titleLogFont = {0}; - LOGFONT bulletLogFont = {0}; - fontThisDialog.GetLogFont(&titleLogFont); - fontThisDialog.GetLogFont(&bulletLogFont); - - // The Wizard 97 Spec recommends to do the Title Font - // as Verdana Bold, 12pt. - titleLogFont.lfCharSet = DEFAULT_CHARSET; - titleLogFont.lfWeight = FW_BOLD; - SecureHelper::strcpy_x(titleLogFont.lfFaceName, _countof(titleLogFont.lfFaceName), _T("Verdana Bold")); - INT titleFontPointSize = 12; - titleLogFont.lfHeight = -::MulDiv(titleFontPointSize, dcScreen.GetDeviceCaps(LOGPIXELSY), 72); - m_fontExteriorPageTitle.CreateFontIndirect(&titleLogFont); - - // The Wizard 97 Spec recommends to do Bullets by having - // static text of "h" in the Marlett font. - bulletLogFont.lfCharSet = DEFAULT_CHARSET; - bulletLogFont.lfWeight = FW_NORMAL; - SecureHelper::strcpy_x(bulletLogFont.lfFaceName, _countof(bulletLogFont.lfFaceName), _T("Marlett")); - INT bulletFontSize = 8; - bulletLogFont.lfHeight = -::MulDiv(bulletFontSize, dcScreen.GetDeviceCaps(LOGPIXELSY), 72); - m_fontBullet.CreateFontIndirect(&bulletLogFont); - } - -// Message Handling - BEGIN_MSG_MAP(thisClass) - MESSAGE_HANDLER(CWizard97SheetWindow::GetMessage_GetExteriorPageTitleFont(), OnGetExteriorPageTitleFont) - MESSAGE_HANDLER(CWizard97SheetWindow::GetMessage_GetBulletFont(), OnGetBulletFont) - MESSAGE_HANDLER(WM_SIZE, OnSize) - CHAIN_MSG_MAP(baseClass) - END_MSG_MAP() - - LRESULT OnGetExteriorPageTitleFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - return (LRESULT)(HFONT)m_fontExteriorPageTitle; - } - - LRESULT OnGetBulletFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - return (LRESULT)(HFONT)m_fontBullet; - } - - LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - if(!m_bReceivedFirstSizeMessage) - { - m_bReceivedFirstSizeMessage = true; - this->CenterWindow(); - } - - bHandled = FALSE; - return 0; - } -}; - -// for non-customized sheets -class CWizard97Sheet : public CWizard97SheetImpl -{ -protected: -// Typedefs - typedef CWizard97Sheet thisClass; - typedef CWizard97SheetImpl baseClass; - -public: - CWizard97Sheet(ATL::_U_STRINGorID title, ATL::_U_STRINGorID headerBitmap, ATL::_U_STRINGorID watermarkBitmap, UINT uStartPage = 0, HWND hWndParent = NULL) : - baseClass(title, headerBitmap, watermarkBitmap, uStartPage, hWndParent) - { } - - BEGIN_MSG_MAP(thisClass) - CHAIN_MSG_MAP(baseClass) - END_MSG_MAP() -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CWizard97PageWindow - client side for a Wizard 97 style wizard page - -#define WIZARD97_EXTERIOR_CXDLG 317 -#define WIZARD97_EXTERIOR_CYDLG 193 - -#define WIZARD97_INTERIOR_CXDLG 317 -#define WIZARD97_INTERIOR_CYDLG 143 - -class CWizard97PageWindow : public CPropertyPageWindow -{ -public: -// Constructors - CWizard97PageWindow(HWND hWnd = NULL) : CPropertyPageWindow(hWnd) - { } - - CWizard97PageWindow& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - -// Attributes - CWizard97SheetWindow GetPropertySheet() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return CWizard97SheetWindow(GetParent()); - } - -// Operations - HFONT GetExteriorPageTitleFont(void) - { - ATLASSERT(::IsWindow(m_hWnd)); - return GetPropertySheet().GetExteriorPageTitleFont(); - } - - HFONT GetBulletFont(void) - { - ATLASSERT(::IsWindow(m_hWnd)); - return GetPropertySheet().GetBulletFont(); - } - -// Implementation - overrides to prevent usage - HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL) - { - ATLASSERT(FALSE); - return NULL; - } - -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CWizard97PageImpl - implements a Wizard 97 style wizard page - -template -class ATL_NO_VTABLE CWizard97PageImpl : public CPropertyPageImpl< T, TBase > -{ -protected: -// Typedefs - typedef CWizard97PageImpl< T, TBase > thisClass; - typedef CPropertyPageImpl< T, TBase > baseClass; - -public: - CWizard97PageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : baseClass(title) - { } - -// Message Handling - BEGIN_MSG_MAP(thisClass) - CHAIN_MSG_MAP(baseClass) - END_MSG_MAP() -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CWizard97ExteriorPageImpl - implements a Wizard 97 style exterior wizard page - -template -class ATL_NO_VTABLE CWizard97ExteriorPageImpl : public CPropertyPageImpl< T, TBase > -{ -protected: -// Typedefs - typedef CWizard97ExteriorPageImpl< T, TBase > thisClass; - typedef CPropertyPageImpl< T, TBase > baseClass; - -public: -// Constructors - CWizard97ExteriorPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : baseClass(title) - { - m_psp.dwFlags |= PSP_HASHELP; - m_psp.dwFlags |= PSP_HIDEHEADER; - } - -// Message Handling - BEGIN_MSG_MAP(thisClass) - CHAIN_MSG_MAP(baseClass) - END_MSG_MAP() -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CWizard97InteriorPageImpl - implements a Wizard 97 style interior wizard page - -template -class ATL_NO_VTABLE CWizard97InteriorPageImpl : public CPropertyPageImpl< T, TBase > -{ -protected: -// Typedefs - typedef CWizard97InteriorPageImpl< T, TBase > thisClass; - typedef CPropertyPageImpl< T, TBase > baseClass; - -public: -// Constructors - CWizard97InteriorPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : baseClass(title) - { - m_psp.dwFlags |= PSP_HASHELP; - m_psp.dwFlags &= ~PSP_HIDEHEADER; - m_psp.dwFlags |= PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; - - // Be sure to have the derived class define this in the constructor. - // We'll default it to something obvious in case its forgotten. - baseClass::SetHeaderTitle(_T("Call SetHeaderTitle in Derived Class")); - baseClass::SetHeaderSubTitle(_T("Call SetHeaderSubTitle in the constructor of the Derived Class.")); - } - -// Message Handling - BEGIN_MSG_MAP(thisClass) - CHAIN_MSG_MAP(baseClass) - END_MSG_MAP() -}; - -#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - - -/////////////////////////////////////////////////////////////////////////////// -// Aero Wizard support - -#if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) - -/////////////////////////////////////////////////////////////////////////////// -// CAeroWizardFrameWindow - client side for an Aero Wizard frame window - -class CAeroWizardFrameWindow : public CPropertySheetWindow -{ -public: -// Constructors - CAeroWizardFrameWindow(HWND hWnd = NULL) : CPropertySheetWindow(hWnd) - { } - - CAeroWizardFrameWindow& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - -// Operations - new, Aero Wizard only - void SetNextText(LPCWSTR lpszText) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, PSM_SETNEXTTEXT, 0, (LPARAM)lpszText); - } - - void ShowWizardButtons(DWORD dwButtons, DWORD dwStates) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::PostMessage(m_hWnd, PSM_SHOWWIZBUTTONS, (WPARAM)dwStates, (LPARAM)dwButtons); - } - - void EnableWizardButtons(DWORD dwButtons, DWORD dwStates) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::PostMessage(m_hWnd, PSM_ENABLEWIZBUTTONS, (WPARAM)dwStates, (LPARAM)dwButtons); - } - - void SetButtonText(DWORD dwButton, LPCWSTR lpszText) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, PSM_SETBUTTONTEXT, (WPARAM)dwButton, (LPARAM)lpszText); - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CAeroWizardFrameImpl - implements an Aero Wizard frame - -template -class ATL_NO_VTABLE CAeroWizardFrameImpl : public CPropertySheetImpl -{ -public: -// Constructor - CAeroWizardFrameImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL) : - CPropertySheetImpl(title, uStartPage, hWndParent) - { - m_psh.dwFlags |= PSH_WIZARD | PSH_AEROWIZARD; - } - -// Operations - void EnableResizing() - { - ATLASSERT(m_hWnd == NULL); // can't do this after it's created - m_psh.dwFlags |= PSH_RESIZABLE; - } - - void UseHeaderBitmap() - { - ATLASSERT(m_hWnd == NULL); // can't do this after it's created - m_psh.dwFlags |= PSH_HEADERBITMAP; - } - - void SetNoMargin() - { - ATLASSERT(m_hWnd == NULL); // can't do this after it's created - m_psh.dwFlags |= PSH_NOMARGIN; - } - -// Override to prevent use - HWND Create(HWND /*hWndParent*/ = NULL) - { - ATLASSERT(FALSE); // not supported for Aero Wizard - return NULL; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CAeroWizardFrame - for non-customized frames - -class CAeroWizardFrame : public CAeroWizardFrameImpl -{ -public: - CAeroWizardFrame(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL) - : CAeroWizardFrameImpl(title, uStartPage, hWndParent) - { } - - BEGIN_MSG_MAP(CAeroWizardFrame) - MESSAGE_HANDLER(WM_COMMAND, CAeroWizardFrameImpl::OnCommand) - END_MSG_MAP() -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CAeroWizardPageWindow - client side for an Aero Wizard page - -class CAeroWizardPageWindow : public CPropertyPageWindow -{ -public: -// Constructors - CAeroWizardPageWindow(HWND hWnd = NULL) : CPropertyPageWindow(hWnd) - { } - - CAeroWizardPageWindow& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - -// Attributes - CAeroWizardFrameWindow GetAeroWizardFrame() const - { - ATLASSERT(::IsWindow(m_hWnd)); - // This is not really top-level frame window, but it processes all frame messages - return CAeroWizardFrameWindow(GetParent()); - } - -// Operations - new, Aero Wizard only - void SetNextText(LPCWSTR lpszText) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(GetParent() != NULL); - GetAeroWizardFrame().SetNextText(lpszText); - } - - void ShowWizardButtons(DWORD dwButtons, DWORD dwStates) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(GetParent() != NULL); - GetAeroWizardFrame().ShowWizardButtons(dwButtons, dwStates); - } - - void EnableWizardButtons(DWORD dwButtons, DWORD dwStates) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(GetParent() != NULL); - GetAeroWizardFrame().EnableWizardButtons(dwButtons, dwStates); - } - - void SetButtonText(DWORD dwButton, LPCWSTR lpszText) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(GetParent() != NULL); - GetAeroWizardFrame().SetButtonText(dwButton, lpszText); - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CAeroWizardPageImpl - implements an Aero Wizard page - -template -class ATL_NO_VTABLE CAeroWizardPageImpl : public CPropertyPageImpl -{ -public: - CAeroWizardPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CPropertyPageImpl(title) - { } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CAeroWizardPage - for non-customized pages - -template -class CAeroWizardPage : public CAeroWizardPageImpl > -{ -public: - enum { IDD = t_wDlgTemplateID }; - - CAeroWizardPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAeroWizardPageImpl(title) - { } - - DECLARE_EMPTY_MSG_MAP() -}; - - -#ifndef _ATL_NO_HOSTING - -// Note: You must #include to use these classes - -/////////////////////////////////////////////////////////////////////////////// -// CAeroWizardAxPageImpl - Aero Wizard page that hosts ActiveX controls - -template -class ATL_NO_VTABLE CAeroWizardAxPageImpl : public CAxPropertyPageImpl< T, TBase > -{ -public: - CAeroWizardAxPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAxPropertyPageImpl< T, TBase >(title) - { } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CAeroWizardAxPage - for non-customized pages - -template -class CAeroWizardAxPage : public CAeroWizardAxPageImpl > -{ -public: - enum { IDD = t_wDlgTemplateID }; - - CAeroWizardAxPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAeroWizardAxPageImpl(title) - { } - -#if (_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700) - // not empty so we handle accelerators/create controls - BEGIN_MSG_MAP(CAeroWizardAxPage) - CHAIN_MSG_MAP(CAeroWizardAxPageImpl >) - END_MSG_MAP() -#else // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)) - DECLARE_EMPTY_MSG_MAP() -#endif // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)) -}; - -#endif // _ATL_NO_HOSTING - -#endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) - - -/////////////////////////////////////////////////////////////////////////////// -// TaskDialog support - -#if ((_WIN32_WINNT >= 0x0600) || defined(_WTL_TASKDIALOG)) && !defined(_WIN32_WCE) - -/////////////////////////////////////////////////////////////////////////////// -// AtlTaskDialog - support for TaskDialog() function - -inline int AtlTaskDialog(HWND hWndParent, - ATL::_U_STRINGorID WindowTitle, ATL::_U_STRINGorID MainInstructionText, ATL::_U_STRINGorID ContentText, - TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons = 0U, ATL::_U_STRINGorID Icon = (LPCTSTR)NULL) -{ - int nRet = -1; - -#ifdef _WTL_TASKDIALOG_DIRECT - USES_CONVERSION; - HRESULT hRet = ::TaskDialog(hWndParent, ModuleHelper::GetResourceInstance(), - IS_INTRESOURCE(WindowTitle.m_lpstr) ? (LPCWSTR) WindowTitle.m_lpstr : T2CW(WindowTitle.m_lpstr), - IS_INTRESOURCE(MainInstructionText.m_lpstr) ? (LPCWSTR) MainInstructionText.m_lpstr : T2CW(MainInstructionText.m_lpstr), - IS_INTRESOURCE(ContentText.m_lpstr) ? (LPCWSTR) ContentText.m_lpstr : T2CW(ContentText.m_lpstr), - dwCommonButtons, - IS_INTRESOURCE(Icon.m_lpstr) ? (LPCWSTR) Icon.m_lpstr : T2CW(Icon.m_lpstr), - &nRet); - ATLVERIFY(SUCCEEDED(hRet)); -#else - // This allows apps to run on older versions of Windows - typedef HRESULT (STDAPICALLTYPE *PFN_TaskDialog)(HWND hwndParent, HINSTANCE hInstance, PCWSTR pszWindowTitle, PCWSTR pszMainInstruction, PCWSTR pszContent, TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons, PCWSTR pszIcon, int* pnButton); - - HMODULE m_hCommCtrlDLL = ::LoadLibrary(_T("comctl32.dll")); - if(m_hCommCtrlDLL != NULL) - { - PFN_TaskDialog pfnTaskDialog = (PFN_TaskDialog)::GetProcAddress(m_hCommCtrlDLL, "TaskDialog"); - if(pfnTaskDialog != NULL) - { - USES_CONVERSION; - HRESULT hRet = pfnTaskDialog(hWndParent, ModuleHelper::GetResourceInstance(), - IS_INTRESOURCE(WindowTitle.m_lpstr) ? (LPCWSTR) WindowTitle.m_lpstr : T2CW(WindowTitle.m_lpstr), - IS_INTRESOURCE(MainInstructionText.m_lpstr) ? (LPCWSTR) MainInstructionText.m_lpstr : T2CW(MainInstructionText.m_lpstr), - IS_INTRESOURCE(ContentText.m_lpstr) ? (LPCWSTR) ContentText.m_lpstr : T2CW(ContentText.m_lpstr), - dwCommonButtons, - IS_INTRESOURCE(Icon.m_lpstr) ? (LPCWSTR) Icon.m_lpstr : T2CW(Icon.m_lpstr), - &nRet); - ATLVERIFY(SUCCEEDED(hRet)); - } - - ::FreeLibrary(m_hCommCtrlDLL); - } -#endif - - return nRet; -} - - -/////////////////////////////////////////////////////////////////////////////// -// CTaskDialogConfig - TASKDIALOGCONFIG wrapper - -class CTaskDialogConfig : public TASKDIALOGCONFIG -{ -public: -// Constructor - CTaskDialogConfig() - { - Init(); - } - - void Init() - { - memset(this, 0, sizeof(TASKDIALOGCONFIG)); // initialize structure to 0/NULL - this->cbSize = sizeof(TASKDIALOGCONFIG); - this->hInstance = ModuleHelper::GetResourceInstance(); - } - -// Operations - setting values - // common buttons - void SetCommonButtons(TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons) - { - this->dwCommonButtons = dwCommonButtons; - } - - // window title text - void SetWindowTitle(UINT nID) - { - this->pszWindowTitle = MAKEINTRESOURCEW(nID); - } - - void SetWindowTitle(LPCWSTR lpstrWindowTitle) - { - this->pszWindowTitle = lpstrWindowTitle; - } - - // main icon - void SetMainIcon(HICON hIcon) - { - this->dwFlags |= TDF_USE_HICON_MAIN; - this->hMainIcon = hIcon; - } - - void SetMainIcon(UINT nID) - { - this->dwFlags &= ~TDF_USE_HICON_MAIN; - this->pszMainIcon = MAKEINTRESOURCEW(nID); - } - - void SetMainIcon(LPCWSTR lpstrMainIcon) - { - this->dwFlags &= ~TDF_USE_HICON_MAIN; - this->pszMainIcon = lpstrMainIcon; - } - - // main instruction text - void SetMainInstructionText(UINT nID) - { - this->pszMainInstruction = MAKEINTRESOURCEW(nID); - } - - void SetMainInstructionText(LPCWSTR lpstrMainInstruction) - { - this->pszMainInstruction = lpstrMainInstruction; - } - - // content text - void SetContentText(UINT nID) - { - this->pszContent = MAKEINTRESOURCEW(nID); - } - - void SetContentText(LPCWSTR lpstrContent) - { - this->pszContent = lpstrContent; - } - - // buttons - void SetButtons(const TASKDIALOG_BUTTON* pButtons, UINT cButtons, int nDefaultButton = 0) - { - this->pButtons = pButtons; - this->cButtons = cButtons; - if(nDefaultButton != 0) - this->nDefaultButton = nDefaultButton; - } - - void SetDefaultButton(int nDefaultButton) - { - this->nDefaultButton = nDefaultButton; - } - - // radio buttons - void SetRadioButtons(const TASKDIALOG_BUTTON* pRadioButtons, UINT cRadioButtons, int nDefaultRadioButton = 0) - { - this->pRadioButtons = pRadioButtons; - this->cRadioButtons = cRadioButtons; - if(nDefaultRadioButton != 0) - this->nDefaultRadioButton = nDefaultRadioButton; - } - - void SetDefaultRadioButton(int nDefaultRadioButton) - { - this->nDefaultRadioButton = nDefaultRadioButton; - } - - // verification text - void SetVerificationText(UINT nID) - { - this->pszVerificationText = MAKEINTRESOURCEW(nID); - } - - void SetVerificationText(LPCWSTR lpstrVerificationText) - { - this->pszVerificationText = lpstrVerificationText; - } - - // expanded information text - void SetExpandedInformationText(UINT nID) - { - this->pszExpandedInformation = MAKEINTRESOURCEW(nID); - } - - void SetExpandedInformationText(LPCWSTR lpstrExpandedInformation) - { - this->pszExpandedInformation = lpstrExpandedInformation; - } - - // expanded control text - void SetExpandedControlText(UINT nID) - { - this->pszExpandedControlText = MAKEINTRESOURCEW(nID); - } - - void SetExpandedControlText(LPCWSTR lpstrExpandedControlText) - { - this->pszExpandedControlText = lpstrExpandedControlText; - } - - // collapsed control text - void SetCollapsedControlText(UINT nID) - { - this->pszCollapsedControlText = MAKEINTRESOURCEW(nID); - } - - void SetCollapsedControlText(LPCWSTR lpstrCollapsedControlText) - { - this->pszCollapsedControlText = lpstrCollapsedControlText; - } - - // footer icon - void SetFooterIcon(HICON hIcon) - { - this->dwFlags |= TDF_USE_HICON_FOOTER; - this->hFooterIcon = hIcon; - } - - void SetFooterIcon(UINT nID) - { - this->dwFlags &= ~TDF_USE_HICON_FOOTER; - this->pszFooterIcon = MAKEINTRESOURCEW(nID); - } - - void SetFooterIcon(LPCWSTR lpstrFooterIcon) - { - this->dwFlags &= ~TDF_USE_HICON_FOOTER; - this->pszFooterIcon = lpstrFooterIcon; - } - - // footer text - void SetFooterText(UINT nID) - { - this->pszFooter = MAKEINTRESOURCEW(nID); - } - - void SetFooterText(LPCWSTR lpstrFooterText) - { - this->pszFooter = lpstrFooterText; - } - - // width (in DLUs) - void SetWidth(UINT cxWidth) - { - this->cxWidth = cxWidth; - } - - // modify flags - void ModifyFlags(DWORD dwRemove, DWORD dwAdd) - { - this->dwFlags = (this->dwFlags & ~dwRemove) | dwAdd; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CTaskDialogImpl - implements a Task Dialog - -template -class ATL_NO_VTABLE CTaskDialogImpl -{ -public: - CTaskDialogConfig m_tdc; - HWND m_hWnd; // used only in callback functions - -// Constructor - CTaskDialogImpl(HWND hWndParent = NULL) : m_hWnd(NULL) - { - m_tdc.hwndParent = hWndParent; - m_tdc.pfCallback = T::TaskDialogCallback; - m_tdc.lpCallbackData = (LONG_PTR)static_cast(this); - } - -// Operations - HRESULT DoModal(HWND hWndParent = ::GetActiveWindow(), int* pnButton = NULL, int* pnRadioButton = NULL, BOOL* pfVerificationFlagChecked = NULL) - { - if(m_tdc.hwndParent == NULL) - m_tdc.hwndParent = hWndParent; - -#ifdef _WTL_TASKDIALOG_DIRECT - return ::TaskDialogIndirect(&m_tdc, pnButton, pnRadioButton, pfVerificationFlagChecked); -#else - - // This allows apps to run on older versions of Windows - typedef HRESULT (STDAPICALLTYPE *PFN_TaskDialogIndirect)(const TASKDIALOGCONFIG* pTaskConfig, int* pnButton, int* pnRadioButton, BOOL* pfVerificationFlagChecked); - - HRESULT hRet = E_UNEXPECTED; - HMODULE m_hCommCtrlDLL = ::LoadLibrary(_T("comctl32.dll")); - if(m_hCommCtrlDLL != NULL) - { - PFN_TaskDialogIndirect pfnTaskDialogIndirect = (PFN_TaskDialogIndirect)::GetProcAddress(m_hCommCtrlDLL, "TaskDialogIndirect"); - if(pfnTaskDialogIndirect != NULL) - hRet = pfnTaskDialogIndirect(&m_tdc, pnButton, pnRadioButton, pfVerificationFlagChecked); - - ::FreeLibrary(m_hCommCtrlDLL); - } - - return hRet; -#endif - } - -// Operations - setting values of TASKDIALOGCONFIG - // common buttons - void SetCommonButtons(TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons) - { m_tdc.SetCommonButtons(dwCommonButtons); } - // window title text - void SetWindowTitle(UINT nID) - { m_tdc.SetWindowTitle(nID); } - void SetWindowTitle(LPCWSTR lpstrWindowTitle) - { m_tdc.SetWindowTitle(lpstrWindowTitle); } - // main icon - void SetMainIcon(HICON hIcon) - { m_tdc.SetMainIcon(hIcon); } - void SetMainIcon(UINT nID) - { m_tdc.SetMainIcon(nID); } - void SetMainIcon(LPCWSTR lpstrMainIcon) - { m_tdc.SetMainIcon(lpstrMainIcon); } - // main instruction text - void SetMainInstructionText(UINT nID) - { m_tdc.SetMainInstructionText(nID); } - void SetMainInstructionText(LPCWSTR lpstrMainInstruction) - { m_tdc.SetMainInstructionText(lpstrMainInstruction); } - // content text - void SetContentText(UINT nID) - { m_tdc.SetContentText(nID); } - void SetContentText(LPCWSTR lpstrContent) - { m_tdc.SetContentText(lpstrContent); } - // buttons - void SetButtons(const TASKDIALOG_BUTTON* pButtons, UINT cButtons, int nDefaultButton = 0) - { m_tdc.SetButtons(pButtons, cButtons, nDefaultButton); } - void SetDefaultButton(int nDefaultButton) - { m_tdc.SetDefaultButton(nDefaultButton); } - // radio buttons - void SetRadioButtons(const TASKDIALOG_BUTTON* pRadioButtons, UINT cRadioButtons, int nDefaultRadioButton = 0) - { m_tdc.SetRadioButtons(pRadioButtons, cRadioButtons, nDefaultRadioButton); } - void SetDefaultRadioButton(int nDefaultRadioButton) - { m_tdc.SetDefaultRadioButton(nDefaultRadioButton); } - // verification text - void SetVerificationText(UINT nID) - { m_tdc.SetVerificationText(nID); } - void SetVerificationText(LPCWSTR lpstrVerificationText) - { m_tdc.SetVerificationText(lpstrVerificationText); } - // expanded information text - void SetExpandedInformationText(UINT nID) - { m_tdc.SetExpandedInformationText(nID); } - void SetExpandedInformationText(LPCWSTR lpstrExpandedInformation) - { m_tdc.SetExpandedInformationText(lpstrExpandedInformation); } - // expanded control text - void SetExpandedControlText(UINT nID) - { m_tdc.SetExpandedControlText(nID); } - void SetExpandedControlText(LPCWSTR lpstrExpandedControlText) - { m_tdc.SetExpandedControlText(lpstrExpandedControlText); } - // collapsed control text - void SetCollapsedControlText(UINT nID) - { m_tdc.SetCollapsedControlText(nID); } - void SetCollapsedControlText(LPCWSTR lpstrCollapsedControlText) - { m_tdc.SetCollapsedControlText(lpstrCollapsedControlText); } - // footer icon - void SetFooterIcon(HICON hIcon) - { m_tdc.SetFooterIcon(hIcon); } - void SetFooterIcon(UINT nID) - { m_tdc.SetFooterIcon(nID); } - void SetFooterIcon(LPCWSTR lpstrFooterIcon) - { m_tdc.SetFooterIcon(lpstrFooterIcon); } - // footer text - void SetFooterText(UINT nID) - { m_tdc.SetFooterText(nID); } - void SetFooterText(LPCWSTR lpstrFooterText) - { m_tdc.SetFooterText(lpstrFooterText); } - // width (in DLUs) - void SetWidth(UINT cxWidth) - { m_tdc.SetWidth(cxWidth); } - // modify flags - void ModifyFlags(DWORD dwRemove, DWORD dwAdd) - { m_tdc.ModifyFlags(dwRemove, dwAdd); } - -// Implementation - static HRESULT CALLBACK TaskDialogCallback(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData) - { - T* pT = (T*)lpRefData; - ATLASSERT(pT->m_hWnd == NULL || pT->m_hWnd == hWnd); - - BOOL bRet = FALSE; - switch(uMsg) - { - case TDN_DIALOG_CONSTRUCTED: - pT->m_hWnd = hWnd; - pT->OnDialogConstructed(); - break; - case TDN_CREATED: - pT->OnCreated(); - break; - case TDN_BUTTON_CLICKED: - bRet = pT->OnButtonClicked((int)wParam); - break; - case TDN_RADIO_BUTTON_CLICKED: - pT->OnRadioButtonClicked((int)wParam); - break; - case TDN_HYPERLINK_CLICKED: - pT->OnHyperlinkClicked((LPCWSTR)lParam); - break; - case TDN_EXPANDO_BUTTON_CLICKED: - pT->OnExpandoButtonClicked((wParam != 0)); - break; - case TDN_VERIFICATION_CLICKED: - pT->OnVerificationClicked((wParam != 0)); - break; - case TDN_HELP: - pT->OnHelp(); - break; - case TDN_TIMER: - bRet = pT->OnTimer((DWORD)wParam); - break; - case TDN_NAVIGATED: - pT->OnNavigated(); - break; - case TDN_DESTROYED: - pT->OnDestroyed(); - pT->m_hWnd = NULL; - break; - default: - ATLTRACE2(atlTraceUI, 0, _T("Unknown notification received in CTaskDialogImpl::TaskDialogCallback\n")); - break; - } - - return (HRESULT)bRet; - } - -// Overrideables - notification handlers - void OnDialogConstructed() - { - } - - void OnCreated() - { - } - - BOOL OnButtonClicked(int /*nButton*/) - { - return FALSE; // don't prevent dialog to close - } - - void OnRadioButtonClicked(int /*nRadioButton*/) - { - } - - void OnHyperlinkClicked(LPCWSTR /*pszHREF*/) - { - } - - void OnExpandoButtonClicked(bool /*bExpanded*/) - { - } - - void OnVerificationClicked(bool /*bChecked*/) - { - } - - void OnHelp() - { - } - - BOOL OnTimer(DWORD /*dwTickCount*/) - { - return FALSE; // don't reset counter - } - - void OnNavigated() - { - } - - void OnDestroyed() - { - } - -// Commands - valid to call only from handlers - void NavigatePage(TASKDIALOGCONFIG& tdc) - { - ATLASSERT(m_hWnd != NULL); - - tdc.cbSize = sizeof(TASKDIALOGCONFIG); - if(tdc.hwndParent == NULL) - tdc.hwndParent = m_tdc.hwndParent; - tdc.pfCallback = m_tdc.pfCallback; - tdc.lpCallbackData = m_tdc.lpCallbackData; - (TASKDIALOGCONFIG)m_tdc = tdc; - - ::SendMessage(m_hWnd, TDM_NAVIGATE_PAGE, 0, (LPARAM)&tdc); - } - - // modify TASKDIALOGCONFIG values, then call this to update task dialog - void NavigatePage() - { - ATLASSERT(m_hWnd != NULL); - ::SendMessage(m_hWnd, TDM_NAVIGATE_PAGE, 0, (LPARAM)&m_tdc); - } - - void ClickButton(int nButton) - { - ATLASSERT(m_hWnd != NULL); - ::SendMessage(m_hWnd, TDM_CLICK_BUTTON, nButton, 0L); - } - - void SetMarqueeProgressBar(BOOL bMarquee) - { - ATLASSERT(m_hWnd != NULL); - ::SendMessage(m_hWnd, TDM_SET_MARQUEE_PROGRESS_BAR, bMarquee, 0L); - } - - BOOL SetProgressBarState(int nNewState) - { - ATLASSERT(m_hWnd != NULL); - return (BOOL)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_STATE, nNewState, 0L); - } - - DWORD SetProgressBarRange(int nMinRange, int nMaxRange) - { - ATLASSERT(m_hWnd != NULL); - return (DWORD)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_RANGE, 0, MAKELPARAM(nMinRange, nMaxRange)); - } - - int SetProgressBarPos(int nNewPos) - { - ATLASSERT(m_hWnd != NULL); - return (int)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_POS, nNewPos, 0L); - } - - BOOL SetProgressBarMarquee(BOOL bMarquee, UINT uSpeed) - { - ATLASSERT(m_hWnd != NULL); - return (BOOL)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_MARQUEE, bMarquee, uSpeed); - } - - void SetElementText(TASKDIALOG_ELEMENTS element, LPCWSTR lpstrText) - { - ATLASSERT(m_hWnd != NULL); - ::SendMessage(m_hWnd, TDM_SET_ELEMENT_TEXT, element, (LPARAM)lpstrText); - } - - void ClickRadioButton(int nRadioButton) - { - ATLASSERT(m_hWnd != NULL); - ::SendMessage(m_hWnd, TDM_CLICK_RADIO_BUTTON, nRadioButton, 0L); - } - - void EnableButton(int nButton, BOOL bEnable) - { - ATLASSERT(m_hWnd != NULL); - ::SendMessage(m_hWnd, TDM_ENABLE_BUTTON, nButton, bEnable); - } - - void EnableRadioButton(int nButton, BOOL bEnable) - { - ATLASSERT(m_hWnd != NULL); - ::SendMessage(m_hWnd, TDM_ENABLE_RADIO_BUTTON, nButton, bEnable); - } - - void ClickVerification(BOOL bCheck, BOOL bFocus) - { - ATLASSERT(m_hWnd != NULL); - ::SendMessage(m_hWnd, TDM_CLICK_VERIFICATION, bCheck, bFocus); - } - - void UpdateElementText(TASKDIALOG_ELEMENTS element, LPCWSTR lpstrText) - { - ATLASSERT(m_hWnd != NULL); - ::SendMessage(m_hWnd, TDM_UPDATE_ELEMENT_TEXT, element, (LPARAM)lpstrText); - } - - void SetButtonElevationRequiredState(int nButton, BOOL bElevation) - { - ATLASSERT(m_hWnd != NULL); - ::SendMessage(m_hWnd, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, nButton, bElevation); - } - - void UpdateIcon(TASKDIALOG_ICON_ELEMENTS element, HICON hIcon) - { - ATLASSERT(m_hWnd != NULL); -#ifdef _DEBUG - if(element == TDIE_ICON_MAIN) - ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_MAIN) != 0); - else if(element == TDIE_ICON_FOOTER) - ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_FOOTER) != 0); -#endif // _DEBUG - ::SendMessage(m_hWnd, TDM_UPDATE_ICON, element, (LPARAM)hIcon); - } - - void UpdateIcon(TASKDIALOG_ICON_ELEMENTS element, LPCWSTR lpstrIcon) - { - ATLASSERT(m_hWnd != NULL); -#ifdef _DEBUG - if(element == TDIE_ICON_MAIN) - ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_MAIN) == 0); - else if(element == TDIE_ICON_FOOTER) - ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_FOOTER) == 0); -#endif // _DEBUG - ::SendMessage(m_hWnd, TDM_UPDATE_ICON, element, (LPARAM)lpstrIcon); - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CTaskDialog - for non-customized task dialogs - -class CTaskDialog : public CTaskDialogImpl -{ -public: - CTaskDialog(HWND hWndParent = NULL) : CTaskDialogImpl(hWndParent) - { - m_tdc.pfCallback = NULL; - } -}; - -#endif // ((_WIN32_WINNT >= 0x0600) || defined(_WTL_TASKDIALOG)) && !defined(_WIN32_WCE) - -}; // namespace WTL - -#endif // __ATLDLGS_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atldwm.h b/!NotAdopted/SmartAutoReplier/wtl/atldwm.h deleted file mode 100644 index fea8254827..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atldwm.h +++ /dev/null @@ -1,461 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLDWM_H__ -#define __ATLDWM_H__ - -#pragma once - -#ifdef _WIN32_WCE - #error atldwm.h is not supported on Windows CE -#endif - -#ifndef __ATLAPP_H__ - #error atldwm.h requires atlapp.h to be included first -#endif - -#ifndef __ATLWIN_H__ - #error atldwm.h requires atlwin.h to be included first -#endif - -#if (_WIN32_WINNT < 0x0600) - #error atldwm.h requires _WIN32_WINNT >= 0x0600 -#endif // (_WIN32_WINNT < 0x0600) - -#ifndef _DWMAPI_H_ -#include -#endif // _DWMAPI_H_ -#pragma comment(lib, "dwmapi.lib") - -// Note: To create an application that also runs on older versions of Windows, -// use delay load of dwmapi.dll and ensure that no calls to the DWM API are -// Delay load is NOT AUTOMATIC for VC++ 7, you have to link to delayimp.lib, -// and add dwmapi.dll in the Linker.Input.Delay Loaded DLLs section of the -// project properties. -#if (_MSC_VER < 1300) && !defined(_WTL_NO_DWMAPI_DELAYLOAD) - #pragma comment(lib, "delayimp.lib") - #pragma comment(linker, "/delayload:dwmapi.dll") -#endif // (_MSC_VER < 1300) && !defined(_WTL_NO_DWMAPI_DELAYLOAD) - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CDwm -// CDwmImpl -// CDwmWindowT - CDwmWindow -// CDwmThumbnailT -// CDwmThumbnail -// CDwmThumbnailHandle -// CAeroControlImpl - - -namespace WTL -{ - -/////////////////////////////////////////////////////////////////////////////// -// CDwm - wrapper for DWM handle - -class CDwm -{ -public: -// Data members - static int m_nIsDwmSupported; - -// Constructor - CDwm() - { - IsDwmSupported(); - } - -// Dwm support helper - static bool IsDwmSupported() - { - if(m_nIsDwmSupported == -1) - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CDwm::IsDwmSupported.\n")); - ATLASSERT(FALSE); - return false; - } - - if(m_nIsDwmSupported == -1) - { - HMODULE hDwmDLL = ::LoadLibrary(_T("dwmapi.dll")); - m_nIsDwmSupported = (hDwmDLL != NULL) ? 1 : 0; - if(hDwmDLL != NULL) - ::FreeLibrary(hDwmDLL); - } - - lock.Unlock(); - } - - ATLASSERT(m_nIsDwmSupported != -1); - return (m_nIsDwmSupported == 1); - } - -// Operations - BOOL DwmIsCompositionEnabled() const - { - if(!IsDwmSupported()) return FALSE; - BOOL bRes = FALSE; - return SUCCEEDED(::DwmIsCompositionEnabled(&bRes)) && bRes; - } - - BOOL DwmEnableComposition(UINT fEnable) - { - if(!IsDwmSupported()) return FALSE; - return SUCCEEDED(::DwmEnableComposition(fEnable)); - } - - BOOL DwmEnableMMCSS(BOOL fEnableMMCSS) - { - if(!IsDwmSupported()) return FALSE; - return SUCCEEDED(::DwmEnableMMCSS(fEnableMMCSS)); - } - - HRESULT DwmGetColorizationColor(DWORD* pcrColorization, BOOL* pfOpaqueBlend) - { - if(!IsDwmSupported()) return E_NOTIMPL; - return ::DwmGetColorizationColor(pcrColorization, pfOpaqueBlend); - } - - HRESULT DwmFlush() - { - if(!IsDwmSupported()) return E_NOTIMPL; - return ::DwmFlush(); - } -}; - -__declspec(selectany) int CDwm::m_nIsDwmSupported = -1; - - -/////////////////////////////////////////////////////////////////////////////// -// CDwmImpl - DWM window support - -template -class CDwmImpl : public TBase -{ -public: - HRESULT DwmEnableBlurBehindWindow(const DWM_BLURBEHIND* pBB) - { - if(!IsDwmSupported()) return E_NOTIMPL; - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::DwmEnableBlurBehindWindow(pT->m_hWnd, pBB); - } - - HRESULT DwmExtendFrameIntoClientArea(const MARGINS* pMargins) - { - if(!IsDwmSupported()) return E_NOTIMPL; - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::DwmExtendFrameIntoClientArea(pT->m_hWnd, pMargins); - } - - HRESULT DwmExtendFrameIntoEntireClientArea() - { - MARGINS margins = { -1 }; - return DwmExtendFrameIntoClientArea(&margins); - } - - HRESULT DwmGetCompositionTimingInfo(DWM_TIMING_INFO* pTimingInfo) - { - if(!IsDwmSupported()) return E_NOTIMPL; - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::DwmGetCompositionTimingInfo(pT->m_hWnd, pTimingInfo); - } - - HRESULT DwmGetWindowAttribute(DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute) - { - if(!IsDwmSupported()) return E_NOTIMPL; - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::DwmGetWindowAttribute(pT->m_hWnd, dwAttribute, pvAttribute, cbAttribute); - } - - HRESULT DwmModifyPreviousDxFrameDuration(INT cRefreshes, BOOL fRelative) - { - if(!IsDwmSupported()) return E_NOTIMPL; - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::DwmModifyPreviousDxFrameDuration(pT->m_hWnd, cRefreshes, fRelative); - } - - HRESULT DwmSetDxFrameDuration(INT cRefreshes) - { - if(!IsDwmSupported()) return E_NOTIMPL; - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::DwmSetDxFrameDuration(pT->m_hWnd, cRefreshes); - } - - HRESULT DwmSetPresentParameters(DWM_PRESENT_PARAMETERS* pPresentParams) - { - if(!IsDwmSupported()) return E_NOTIMPL; - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::DwmSetPresentParameters(pT->m_hWnd, pPresentParams); - } - - HRESULT DwmSetWindowAttribute(DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute) - { - if(!IsDwmSupported()) return E_NOTIMPL; - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::DwmSetWindowAttribute(pT->m_hWnd, dwAttribute, pvAttribute, cbAttribute); - } - - HRESULT DwmAttachMilContent() - { - if(!IsDwmSupported()) return E_NOTIMPL; - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::DwmAttachMilContent(pT->m_hWnd); - } - - HRESULT DwmDetachMilContent() - { - if(!IsDwmSupported()) return E_NOTIMPL; - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::DwmDetachMilContent(pT->m_hWnd); - } -}; - -template -class CDwmWindowT : public TBase, public CDwmImpl > -{ -public: - CDwmWindowT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CDwmWindowT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } -}; - -typedef CDwmWindowT CDwmWindow; - - -/////////////////////////////////////////////////////////////////////////////// -// CDwmThumbnail - provides DWM thumbnail support - -template -class CDwmThumbnailT : public TBase -{ -public: -// Data members - HTHUMBNAIL m_hThumbnail; - -// Constructor - CDwmThumbnailT(HTHUMBNAIL hThumbnail = NULL) : m_hThumbnail(hThumbnail) - { - } - - ~CDwmThumbnailT() - { - if(t_bManaged && m_hThumbnail != NULL) - Unregister(); - } - -// Operations - CDwmThumbnailT& operator =(HTHUMBNAIL hThumbnail) - { - Attach(hThumbnail); - return *this; - } - - void Attach(HTHUMBNAIL hThumbnailNew) - { - if(t_bManaged && m_hThumbnail != NULL && m_hThumbnail != hThumbnailNew) - Unregister(); - m_hThumbnail = hThumbnailNew; - } - - HTHUMBNAIL Detach() - { - HTHUMBNAIL hThumbnail = m_hThumbnail; - m_hThumbnail = NULL; - return hThumbnail; - } - - HRESULT Register(HWND hwndDestination, HWND hwndSource) - { - ATLASSERT(::IsWindow(hwndDestination)); - ATLASSERT(::IsWindow(hwndSource)); - ATLASSERT(m_hThumbnail==NULL); - if(!IsDwmSupported()) return E_NOTIMPL; - return ::DwmRegisterThumbnail(hwndDestination, hwndSource, &m_hThumbnail); - } - - HRESULT Unregister() - { - if(!IsDwmSupported()) return E_NOTIMPL; - if(m_hThumbnail == NULL) return S_FALSE; - HRESULT Hr = ::DwmUnregisterThumbnail(m_hThumbnail); - if(SUCCEEDED(Hr)) m_hThumbnail = NULL; - return Hr; - } - - operator HTHUMBNAIL() const { return m_hThumbnail; } - - bool IsNull() const { return (m_hThumbnail == NULL); } - - HRESULT UpdateProperties(const DWM_THUMBNAIL_PROPERTIES* ptnProperties) - { - if(!IsDwmSupported()) return E_NOTIMPL; - ATLASSERT(m_hThumbnail != NULL); - return ::DwmUpdateThumbnailProperties(m_hThumbnail, ptnProperties); - } - -// Attributes - HRESULT QuerySourceSize(PSIZE pSize) - { - if(!IsDwmSupported()) return E_NOTIMPL; - ATLASSERT(m_hThumbnail != NULL); - return ::DwmQueryThumbnailSourceSize(m_hThumbnail, pSize); - } -}; - -typedef CDwmThumbnailT CDwmThumbnail; -typedef CDwmThumbnailT CDwmThumbnailHandle; - - -#ifdef __ATLTHEME_H__ - -/////////////////////////////////////////////////////////////////////////////// -// CAeroControlImpl - Base class for controls on Glass - -template -class CAeroControlImpl : - public CThemeImpl, - public CBufferedPaintImpl, - public ATL::CWindowImpl -{ -public: - typedef CThemeImpl _themeClass; - typedef CBufferedPaintImpl _baseClass; - typedef ATL::CWindowImpl _windowClass; - - CAeroControlImpl() - { - m_PaintParams.dwFlags = BPPF_ERASE; - } - - static LPCWSTR GetThemeName() - { -#ifdef _UNICODE - return TBase::GetWndClassName(); -#else - ATLASSERT(!_T("Return UNICODE string of window classname / theme class")); - return NULL; -#endif // _UNICODE - } - -// Message map and handlers - BEGIN_MSG_MAP(CAeroControlImpl) - MESSAGE_HANDLER(WM_CREATE, OnCreate) - MESSAGE_HANDLER(WM_ACTIVATE, OnActivate) - CHAIN_MSG_MAP(_themeClass) - CHAIN_MSG_MAP(_baseClass) - END_MSG_MAP() - - LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - T* pT = static_cast(this); - pT->Init(); - bHandled = FALSE; - return 0; - } - - LRESULT OnActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - if(IsThemingSupported()) Invalidate(FALSE); - bHandled = FALSE; - return 0; - } - -// Operations - BOOL SubclassWindow(HWND hWnd) - { - ATLASSERT(m_hWnd == NULL); - ATLASSERT(::IsWindow(hWnd)); - BOOL bRet = _windowClass::SubclassWindow(hWnd); - if(bRet) { - T* pT = static_cast(this); - pT->Init(); - } - return bRet; - } - -// Implementation - LRESULT DefWindowProc() - { - const _ATL_MSG* pMsg = m_pCurrentMsg; - LRESULT lRes = 0; - if(pMsg != NULL) - lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg->lParam); - return lRes; - } - - LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) - { - T* pT = static_cast(this); - LRESULT lRes = 0; - if( ::DwmDefWindowProc(pT->m_hWnd, uMsg, wParam, lParam, &lRes) ) return lRes; - return _windowClass::DefWindowProc(uMsg, wParam, lParam); - } - - void DoBufferedPaint(HDC hDC, RECT& rcPaint) - { - T* pT = static_cast(this); - HDC hDCPaint = NULL; - RECT rcClient = { 0 }; - GetClientRect(&rcClient); - m_BufferedPaint.Begin(hDC, &rcClient, m_dwFormat, &m_PaintParams, &hDCPaint); - ATLASSERT(hDCPaint != NULL); - pT->DoAeroPaint(hDCPaint, rcClient, rcPaint); - m_BufferedPaint.End(); - } - - void DoPaint(HDC /*hdc*/, RECT& /*rcClient*/) - { - DefWindowProc(); - } - -// Overridables - void Init() - { - T* pT = static_cast(this); - SetThemeClassList(pT->GetThemeName()); - if(m_lpstrThemeClassList != NULL) - OpenThemeData(); - } - - void DoAeroPaint(HDC hDC, RECT& /*rcClient*/, RECT& rcPaint) - { - DefWindowProc(WM_PAINT, (WPARAM) hDC, 0L); - m_BufferedPaint.MakeOpaque(&rcPaint); - } -}; - -#endif // __ATLTHEME_H__ - - -}; // namespace WTL - - -#endif // __ATLDWM_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlfind.h b/!NotAdopted/SmartAutoReplier/wtl/atlfind.h deleted file mode 100644 index 832aba204e..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlfind.h +++ /dev/null @@ -1,1032 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLFIND_H__ -#define __ATLFIND_H__ - -#pragma once - -#ifdef _WIN32_WCE - #error atlfind.h is not supported on Windows CE -#endif - -#ifndef __ATLCTRLS_H__ - #error atlfind.h requires atlctrls.h to be included first -#endif - -#ifndef __ATLDLGS_H__ - #error atlfind.h requires atldlgs.h to be included first -#endif - -#if !((defined(__ATLMISC_H__) && defined(_WTL_USE_CSTRING)) || defined(__ATLSTR_H__)) - #error atlfind.h requires CString (either from ATL's atlstr.h or WTL's atlmisc.h with _WTL_USE_CSTRING) -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CEditFindReplaceImplBase -// CEditFindReplaceImpl -// CRichEditFindReplaceImpl - - -namespace WTL -{ - -/////////////////////////////////////////////////////////////////////////////// -// CEditFindReplaceImplBase - Base class for mixin classes that -// help implement Find/Replace for CEdit or CRichEditCtrl based window classes. - -template -class CEditFindReplaceImplBase -{ -protected: -// Typedefs - typedef CEditFindReplaceImplBase thisClass; - -// Data members - TFindReplaceDialog* m_pFindReplaceDialog; - _CSTRING_NS::CString m_sFindNext, m_sReplaceWith; - BOOL m_bFindOnly, m_bFirstSearch, m_bMatchCase, m_bWholeWord, m_bFindDown; - LONG m_nInitialSearchPos; - HCURSOR m_hOldCursor; - -// Enumerations - enum TranslationTextItem - { - eText_OnReplaceAllMessage = 0, - eText_OnReplaceAllTitle = 1, - eText_OnTextNotFoundMessage = 2, - eText_OnTextNotFoundTitle = 3 - }; - -public: -// Constructors - CEditFindReplaceImplBase() : - m_pFindReplaceDialog(NULL), - m_bFindOnly(TRUE), - m_bFirstSearch(TRUE), - m_bMatchCase(FALSE), - m_bWholeWord(FALSE), - m_bFindDown(TRUE), - m_nInitialSearchPos(0), - m_hOldCursor(NULL) - { - } - -// Message Handlers - BEGIN_MSG_MAP(thisClass) - ALT_MSG_MAP(1) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) - MESSAGE_HANDLER(TFindReplaceDialog::GetFindReplaceMsg(), OnFindReplaceCmd) - COMMAND_ID_HANDLER(ID_EDIT_FIND, OnEditFind) - COMMAND_ID_HANDLER(ID_EDIT_REPEAT, OnEditRepeat) - COMMAND_ID_HANDLER(ID_EDIT_REPLACE, OnEditReplace) - END_MSG_MAP() - - LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - if(m_pFindReplaceDialog != NULL) - { - m_pFindReplaceDialog->SendMessage(WM_CLOSE); - ATLASSERT(m_pFindReplaceDialog == NULL); - } - - bHandled = FALSE; - return 0; - } - - LRESULT OnFindReplaceCmd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - - TFindReplaceDialog* pDialog = TFindReplaceDialog::GetNotifier(lParam); - if(pDialog == NULL) - { - ATLASSERT(FALSE); - ::MessageBeep(MB_ICONERROR); - return 1; - } - ATLASSERT(pDialog == m_pFindReplaceDialog); - - LPFINDREPLACE findReplace = (LPFINDREPLACE)lParam; - if((m_pFindReplaceDialog != NULL) && (findReplace != NULL)) - { - if(pDialog->FindNext()) - { - pT->OnFindNext(pDialog->GetFindString(), pDialog->SearchDown(), - pDialog->MatchCase(), pDialog->MatchWholeWord()); - } - else if(pDialog->ReplaceCurrent()) - { - pT->OnReplaceSel(pDialog->GetFindString(), - pDialog->SearchDown(), pDialog->MatchCase(), pDialog->MatchWholeWord(), - pDialog->GetReplaceString()); - } - else if(pDialog->ReplaceAll()) - { - pT->OnReplaceAll(pDialog->GetFindString(), pDialog->GetReplaceString(), - pDialog->MatchCase(), pDialog->MatchWholeWord()); - } - else if(pDialog->IsTerminating()) - { - // Dialog is going away (but hasn't gone away yet) - // OnFinalMessage will "delete this" - pT->OnTerminatingFindReplaceDialog(m_pFindReplaceDialog); - m_pFindReplaceDialog = NULL; - } - } - - return 0; - } - - LRESULT OnEditFind(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->FindReplace(TRUE); - - return 0; - } - - LRESULT OnEditRepeat(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - - // If the user is holding down SHIFT when hitting F3, we'll - // search in reverse. Otherwise, we'll search forward. - // (be sure to have an accelerator mapped to ID_EDIT_REPEAT - // for both F3 and Shift+F3) - m_bFindDown = !((::GetKeyState(VK_SHIFT) & 0x8000) == 0x8000); - - if(m_sFindNext.IsEmpty()) - { - pT->FindReplace(TRUE); - } - else - { - if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown)) - pT->TextNotFound(m_sFindNext); - } - - return 0; - } - - LRESULT OnEditReplace(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& bHandled) - { - T* pT = static_cast(this); - - DWORD style = pT->GetStyle(); - if((style & ES_READONLY) != ES_READONLY) - { - pT->FindReplace(FALSE); - } - else - { - // Don't allow replace when the edit control is read only - bHandled = FALSE; - } - - return 0; - } - -// Operations (overrideable) - TFindReplaceDialog* CreateFindReplaceDialog(BOOL bFindOnly, // TRUE for Find, FALSE for FindReplace - LPCTSTR lpszFindWhat, - LPCTSTR lpszReplaceWith = NULL, - DWORD dwFlags = FR_DOWN, - HWND hWndParent = NULL) - { - // You can override all of this in a derived class - - TFindReplaceDialog* findReplaceDialog = new TFindReplaceDialog(); - if(findReplaceDialog == NULL) - { - ::MessageBeep(MB_ICONHAND); - } - else - { - HWND hWndFindReplace = findReplaceDialog->Create(bFindOnly, - lpszFindWhat, lpszReplaceWith, dwFlags, hWndParent); - if(hWndFindReplace == NULL) - { - delete findReplaceDialog; - findReplaceDialog = NULL; - } - else - { - findReplaceDialog->SetActiveWindow(); - findReplaceDialog->ShowWindow(SW_SHOW); - } - } - - return findReplaceDialog; - } - - void AdjustDialogPosition(HWND hWndDialog) - { - ATLASSERT((hWndDialog != NULL) && ::IsWindow(hWndDialog)); - - T* pT = static_cast(this); - LONG nStartChar = 0, nEndChar = 0; - // Send EM_GETSEL so we can use both Edit and RichEdit - // (CEdit::GetSel uses int&, and CRichEditCtrlT::GetSel uses LONG&) - ::SendMessage(pT->m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar); - POINT point = pT->PosFromChar(nStartChar); - ::ClientToScreen(pT->GetParent(), &point); - CRect rect; - ::GetWindowRect(hWndDialog, &rect); - if(rect.PtInRect(point)) - { - if(point.y > rect.Height()) - { - rect.OffsetRect(0, point.y - rect.bottom - 20); - } - else - { - int nVertExt = GetSystemMetrics(SM_CYSCREEN); - if(point.y + rect.Height() < nVertExt) - rect.OffsetRect(0, 40 + point.y - rect.top); - } - - ::MoveWindow(hWndDialog, rect.left, rect.top, rect.Width(), rect.Height(), TRUE); - } - } - - DWORD GetFindReplaceDialogFlags(void) const - { - DWORD dwFlags = 0; - - if(m_bFindDown) - dwFlags |= FR_DOWN; - if(m_bMatchCase) - dwFlags |= FR_MATCHCASE; - if(m_bWholeWord) - dwFlags |= FR_WHOLEWORD; - - return dwFlags; - } - - void FindReplace(BOOL bFindOnly) - { - T* pT = static_cast(this); - m_bFirstSearch = TRUE; - if(m_pFindReplaceDialog != NULL) - { - if(m_bFindOnly == bFindOnly) - { - m_pFindReplaceDialog->SetActiveWindow(); - m_pFindReplaceDialog->ShowWindow(SW_SHOW); - return; - } - else - { - m_pFindReplaceDialog->SendMessage(WM_CLOSE); - ATLASSERT(m_pFindReplaceDialog == NULL); - } - } - - ATLASSERT(m_pFindReplaceDialog == NULL); - - _CSTRING_NS::CString findNext; - pT->GetSelText(findNext); - // if selection is empty or spans multiple lines use old find text - if(findNext.IsEmpty() || (findNext.FindOneOf(_T("\n\r")) != -1)) - findNext = m_sFindNext; - _CSTRING_NS::CString replaceWith = m_sReplaceWith; - DWORD dwFlags = pT->GetFindReplaceDialogFlags(); - - m_pFindReplaceDialog = pT->CreateFindReplaceDialog(bFindOnly, - findNext, replaceWith, dwFlags, pT->operator HWND()); - ATLASSERT(m_pFindReplaceDialog != NULL); - if(m_pFindReplaceDialog != NULL) - m_bFindOnly = bFindOnly; - } - - BOOL SameAsSelected(LPCTSTR lpszCompare, BOOL bMatchCase, BOOL /*bWholeWord*/) - { - T* pT = static_cast(this); - - // check length first - size_t nLen = lstrlen(lpszCompare); - LONG nStartChar = 0, nEndChar = 0; - // Send EM_GETSEL so we can use both Edit and RichEdit - // (CEdit::GetSel uses int&, and CRichEditCtrlT::GetSel uses LONG&) - ::SendMessage(pT->m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar); - if(nLen != (size_t)(nEndChar - nStartChar)) - return FALSE; - - // length is the same, check contents - _CSTRING_NS::CString selectedText; - pT->GetSelText(selectedText); - - return (bMatchCase && selectedText.Compare(lpszCompare) == 0) || - (!bMatchCase && selectedText.CompareNoCase(lpszCompare) == 0); - } - - void TextNotFound(LPCTSTR lpszFind) - { - T* pT = static_cast(this); - m_bFirstSearch = TRUE; - pT->OnTextNotFound(lpszFind); - } - - _CSTRING_NS::CString GetTranslationText(enum TranslationTextItem eItem) const - { - _CSTRING_NS::CString text; - switch(eItem) - { - case eText_OnReplaceAllMessage: - text = _T("Replaced %d occurances of \"%s\" with \"%s\""); - break; - case eText_OnReplaceAllTitle: - text = _T("Replace All"); - break; - case eText_OnTextNotFoundMessage: - text = _T("Unable to find the text \"%s\""); - break; - case eText_OnTextNotFoundTitle: - text = _T("Text not found"); - break; - } - - return text; - } - -// Overrideable Handlers - void OnFindNext(LPCTSTR lpszFind, BOOL bFindDown, BOOL bMatchCase, BOOL bWholeWord) - { - T* pT = static_cast(this); - - m_sFindNext = lpszFind; - m_bMatchCase = bMatchCase; - m_bWholeWord = bWholeWord; - m_bFindDown = bFindDown; - - if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown)) - pT->TextNotFound(m_sFindNext); - else - pT->AdjustDialogPosition(m_pFindReplaceDialog->operator HWND()); - } - - void OnReplaceSel(LPCTSTR lpszFind, BOOL bFindDown, BOOL bMatchCase, BOOL bWholeWord, LPCTSTR lpszReplace) - { - T* pT = static_cast(this); - - m_sFindNext = lpszFind; - m_sReplaceWith = lpszReplace; - m_bMatchCase = bMatchCase; - m_bWholeWord = bWholeWord; - m_bFindDown = bFindDown; - - if(pT->SameAsSelected(m_sFindNext, m_bMatchCase, m_bWholeWord)) - pT->ReplaceSel(m_sReplaceWith); - - if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown)) - pT->TextNotFound(m_sFindNext); - else - pT->AdjustDialogPosition(m_pFindReplaceDialog->operator HWND()); - } - - void OnReplaceAll(LPCTSTR lpszFind, LPCTSTR lpszReplace, BOOL bMatchCase, BOOL bWholeWord) - { - T* pT = static_cast(this); - - m_sFindNext = lpszFind; - m_sReplaceWith = lpszReplace; - m_bMatchCase = bMatchCase; - m_bWholeWord = bWholeWord; - m_bFindDown = TRUE; - - // no selection or different than what looking for - if(!pT->SameAsSelected(m_sFindNext, m_bMatchCase, m_bWholeWord)) - { - if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown)) - { - pT->TextNotFound(m_sFindNext); - return; - } - } - - pT->OnReplaceAllCoreBegin(); - - int replaceCount=0; - do - { - ++replaceCount; - pT->ReplaceSel(m_sReplaceWith); - } while(pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown)); - - pT->OnReplaceAllCoreEnd(replaceCount); - } - - void OnReplaceAllCoreBegin() - { - T* pT = static_cast(this); - - m_hOldCursor = ::SetCursor(::LoadCursor(NULL, IDC_WAIT)); - - pT->HideSelection(TRUE, FALSE); - - } - - void OnReplaceAllCoreEnd(int replaceCount) - { - T* pT = static_cast(this); - pT->HideSelection(FALSE, FALSE); - - ::SetCursor(m_hOldCursor); - - _CSTRING_NS::CString message = pT->GetTranslationText(eText_OnReplaceAllMessage); - if(message.GetLength() > 0) - { - _CSTRING_NS::CString formattedMessage; - formattedMessage.Format(message, - replaceCount, m_sFindNext, m_sReplaceWith); - if(m_pFindReplaceDialog != NULL) - { - m_pFindReplaceDialog->MessageBox(formattedMessage, - pT->GetTranslationText(eText_OnReplaceAllTitle), - MB_OK | MB_ICONINFORMATION | MB_APPLMODAL); - } - else - { - pT->MessageBox(formattedMessage, - pT->GetTranslationText(eText_OnReplaceAllTitle), - MB_OK | MB_ICONINFORMATION | MB_APPLMODAL); - } - } - } - - void OnTextNotFound(LPCTSTR lpszFind) - { - T* pT = static_cast(this); - _CSTRING_NS::CString message = pT->GetTranslationText(eText_OnTextNotFoundMessage); - if(message.GetLength() > 0) - { - _CSTRING_NS::CString formattedMessage; - formattedMessage.Format(message, lpszFind); - if(m_pFindReplaceDialog != NULL) - { - m_pFindReplaceDialog->MessageBox(formattedMessage, - pT->GetTranslationText(eText_OnTextNotFoundTitle), - MB_OK | MB_ICONINFORMATION | MB_APPLMODAL); - } - else - { - pT->MessageBox(formattedMessage, - pT->GetTranslationText(eText_OnTextNotFoundTitle), - MB_OK | MB_ICONINFORMATION | MB_APPLMODAL); - } - } - else - { - ::MessageBeep(MB_ICONHAND); - } - } - - void OnTerminatingFindReplaceDialog(TFindReplaceDialog*& /*findReplaceDialog*/) - { - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CEditFindReplaceImpl - Mixin class for implementing Find/Replace for CEdit -// based window classes. - -// Chain to CEditFindReplaceImpl message map. Your class must also derive from CEdit. -// Example: -// class CMyEdit : public CWindowImpl, -// public CEditFindReplaceImpl -// { -// public: -// BEGIN_MSG_MAP(CMyEdit) -// // your handlers... -// CHAIN_MSG_MAP_ALT(CEditFindReplaceImpl, 1) -// END_MSG_MAP() -// // other stuff... -// }; - -template -class CEditFindReplaceImpl : public CEditFindReplaceImplBase -{ -protected: - typedef CEditFindReplaceImpl thisClass; - typedef CEditFindReplaceImplBase baseClass; - -// Data members - LPTSTR m_pShadowBuffer; // Special shadow buffer only used in some cases. - UINT m_nShadowSize; - int m_bShadowBufferNeeded; // TRUE, FALSE, < 0 => Need to check - -public: -// Constructors - CEditFindReplaceImpl() : - m_pShadowBuffer(NULL), - m_nShadowSize(0), - m_bShadowBufferNeeded(-1) - { - } - - virtual ~CEditFindReplaceImpl() - { - if(m_pShadowBuffer != NULL) - { - delete [] m_pShadowBuffer; - m_pShadowBuffer = NULL; - } - } - -// Message Handlers - BEGIN_MSG_MAP(thisClass) - ALT_MSG_MAP(1) - CHAIN_MSG_MAP_ALT(baseClass, 1) - END_MSG_MAP() - -// Operations - // Supported only for RichEdit, so this does nothing for Edit - void HideSelection(BOOL /*bHide*/ = TRUE, BOOL /*bChangeStyle*/ = FALSE) - { - } - -// Operations (overrideable) - BOOL FindTextSimple(LPCTSTR lpszFind, BOOL bMatchCase, BOOL bWholeWord, BOOL bFindDown = TRUE) - { - T* pT = static_cast(this); - - ATLASSERT(lpszFind != NULL); - ATLASSERT(*lpszFind != _T('\0')); - - UINT nLen = pT->GetBufferLength(); - int nStartChar = 0, nEndChar = 0; - pT->GetSel(nStartChar, nEndChar); - UINT nStart = nStartChar; - int iDir = bFindDown ? +1 : -1; - - // can't find a match before the first character - if(nStart == 0 && iDir < 0) - return FALSE; - - LPCTSTR lpszText = pT->LockBuffer(); - - bool isDBCS = false; -#ifdef _MBCS - CPINFO info = { 0 }; - ::GetCPInfo(::GetOEMCP(), &info); - isDBCS = (info.MaxCharSize > 1); -#endif - - if(iDir < 0) - { - // always go back one for search backwards - nStart -= int((lpszText + nStart) - ::CharPrev(lpszText, lpszText + nStart)); - } - else if(nStartChar != nEndChar && pT->SameAsSelected(lpszFind, bMatchCase, bWholeWord)) - { - // easy to go backward/forward with SBCS -#ifndef _UNICODE - if(::IsDBCSLeadByte(lpszText[nStart])) - nStart++; -#endif - nStart += iDir; - } - - // handle search with nStart past end of buffer - UINT nLenFind = ::lstrlen(lpszFind); - if(nStart + nLenFind - 1 >= nLen) - { - if(iDir < 0 && nLen >= nLenFind) - { - if(isDBCS) - { - // walk back to previous character n times - nStart = nLen; - int n = nLenFind; - while(n--) - { - nStart -= int((lpszText + nStart) - ::CharPrev(lpszText, lpszText + nStart)); - } - } - else - { - // single-byte character set is easy and fast - nStart = nLen - nLenFind; - } - ATLASSERT(nStart + nLenFind - 1 <= nLen); - } - else - { - pT->UnlockBuffer(); - return FALSE; - } - } - - // start the search at nStart - LPCTSTR lpsz = lpszText + nStart; - typedef int (WINAPI* CompareProc)(LPCTSTR str1, LPCTSTR str2); - CompareProc pfnCompare = bMatchCase ? lstrcmp : lstrcmpi; - - if(isDBCS) - { - // double-byte string search - LPCTSTR lpszStop = NULL; - if(iDir > 0) - { - // start at current and find _first_ occurrance - lpszStop = lpszText + nLen - nLenFind + 1; - } - else - { - // start at top and find _last_ occurrance - lpszStop = lpsz; - lpsz = lpszText; - } - - LPCTSTR lpszFound = NULL; - while(lpsz <= lpszStop) - { -#ifndef _UNICODE - if(!bMatchCase || (*lpsz == *lpszFind && (!::IsDBCSLeadByte(*lpsz) || lpsz[1] == lpszFind[1]))) -#else - if(!bMatchCase || (*lpsz == *lpszFind && lpsz[1] == lpszFind[1])) -#endif - { - LPTSTR lpch = (LPTSTR)(lpsz + nLenFind); - TCHAR chSave = *lpch; - *lpch = _T('\0'); - int nResult = (*pfnCompare)(lpsz, lpszFind); - *lpch = chSave; - if(nResult == 0) - { - lpszFound = lpsz; - if(iDir > 0) - break; - } - } - lpsz = ::CharNext(lpsz); - } - pT->UnlockBuffer(); - - if(lpszFound != NULL) - { - int n = (int)(lpszFound - lpszText); - pT->SetSel(n, n + nLenFind); - return TRUE; - } - } - else - { - // single-byte string search - UINT nCompare; - if(iDir < 0) - nCompare = (UINT)(lpsz - lpszText) + 1; - else - nCompare = nLen - (UINT)(lpsz - lpszText) - nLenFind + 1; - - while(nCompare > 0) - { - ATLASSERT(lpsz >= lpszText); - ATLASSERT(lpsz + nLenFind - 1 <= lpszText + nLen - 1); - - LPSTR lpch = (LPSTR)(lpsz + nLenFind); - char chSave = *lpch; - *lpch = '\0'; - int nResult = (*pfnCompare)(lpsz, lpszFind); - *lpch = chSave; - if(nResult == 0) - { - pT->UnlockBuffer(); - int n = (int)(lpsz - lpszText); - pT->SetSel(n, n + nLenFind); - return TRUE; - } - - // restore character at end of search - *lpch = chSave; - - // move on to next substring - nCompare--; - lpsz += iDir; - } - pT->UnlockBuffer(); - } - - return FALSE; - } - - LPCTSTR LockBuffer() const - { - const T* pT = static_cast(this); - - ATLASSERT(pT->m_hWnd != NULL); - - BOOL useShadowBuffer = pT->UseShadowBuffer(); - if(useShadowBuffer) - { - if(m_pShadowBuffer == NULL || pT->GetModify()) - { - ATLASSERT(m_pShadowBuffer != NULL || m_nShadowSize == 0); - UINT nSize = pT->GetWindowTextLength() + 1; - if(nSize > m_nShadowSize) - { - // need more room for shadow buffer - T* pThisNoConst = const_cast(pT); - delete[] m_pShadowBuffer; - pThisNoConst->m_pShadowBuffer = NULL; - pThisNoConst->m_nShadowSize = 0; - pThisNoConst->m_pShadowBuffer = new TCHAR[nSize]; - pThisNoConst->m_nShadowSize = nSize; - } - - // update the shadow buffer with GetWindowText - ATLASSERT(m_nShadowSize >= nSize); - ATLASSERT(m_pShadowBuffer != NULL); - pT->GetWindowText(m_pShadowBuffer, nSize); - } - - return m_pShadowBuffer; - } - - HLOCAL hLocal = pT->GetHandle(); - ATLASSERT(hLocal != NULL); - LPCTSTR lpszText = (LPCTSTR)::LocalLock(hLocal); - ATLASSERT(lpszText != NULL); - - return lpszText; - } - - void UnlockBuffer() const - { - const T* pT = static_cast(this); - - ATLASSERT(pT->m_hWnd != NULL); - - BOOL useShadowBuffer = pT->UseShadowBuffer(); - if(!useShadowBuffer) - { - HLOCAL hLocal = pT->GetHandle(); - ATLASSERT(hLocal != NULL); - ::LocalUnlock(hLocal); - } - } - - UINT GetBufferLength() const - { - const T* pT = static_cast(this); - - ATLASSERT(pT->m_hWnd != NULL); - UINT nLen = 0; - LPCTSTR lpszText = pT->LockBuffer(); - if(lpszText != NULL) - nLen = ::lstrlen(lpszText); - pT->UnlockBuffer(); - - return nLen; - } - - LONG EndOfLine(LPCTSTR lpszText, UINT nLen, UINT nIndex) const - { - LPCTSTR lpsz = lpszText + nIndex; - LPCTSTR lpszStop = lpszText + nLen; - while(lpsz < lpszStop && *lpsz != _T('\r')) - ++lpsz; - return LONG(lpsz - lpszText); - } - - LONG GetSelText(_CSTRING_NS::CString& strText) const - { - const T* pT = static_cast(this); - - int nStartChar = 0, nEndChar = 0; - pT->GetSel(nStartChar, nEndChar); - ATLASSERT((UINT)nEndChar <= pT->GetBufferLength()); - LPCTSTR lpszText = pT->LockBuffer(); - LONG nLen = pT->EndOfLine(lpszText, nEndChar, nStartChar) - nStartChar; - SecureHelper::memcpy_x(strText.GetBuffer(nLen), nLen * sizeof(TCHAR), lpszText + nStartChar, nLen * sizeof(TCHAR)); - strText.ReleaseBuffer(nLen); - pT->UnlockBuffer(); - - return nLen; - } - - BOOL UseShadowBuffer(void) const - { - const T* pT = static_cast(this); - - if(pT->m_bShadowBufferNeeded < 0) - { - T* pThisNoConst = const_cast(pT); - - OSVERSIONINFO ovi = { 0 }; - ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - ::GetVersionEx(&ovi); - - bool bWin9x = (ovi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); - if(bWin9x) - { - // Windows 95, 98, ME - // Under Win9x, it is necessary to maintain a shadow buffer. - // It is only updated when the control contents have been changed. - pThisNoConst->m_bShadowBufferNeeded = TRUE; - } - else - { - // Windows NT, 2000, XP, etc. - pThisNoConst->m_bShadowBufferNeeded = FALSE; - -#ifndef _UNICODE - // On Windows XP (or later), if common controls version 6 is in use - // (such as via theming), then EM_GETHANDLE will always return a UNICODE string. - // If theming is enabled and Common Controls version 6 is in use, - // you're really not suppose to superclass or subclass common controls - // with an ANSI windows procedure (so its best to only theme if you use UNICODE). - // Using a shadow buffer uses GetWindowText instead, so it solves - // this problem for us (although it makes it a little less efficient). - - if((ovi.dwMajorVersion == 5 && ovi.dwMinorVersion >= 1) || (ovi.dwMajorVersion > 5)) - { - // We use DLLVERSIONINFO_private so we don't have to depend on shlwapi.h - typedef struct _DLLVERSIONINFO_private - { - DWORD cbSize; - DWORD dwMajorVersion; - DWORD dwMinorVersion; - DWORD dwBuildNumber; - DWORD dwPlatformID; - } DLLVERSIONINFO_private; - - HMODULE hModule = ::LoadLibrary("comctl32.dll"); - if(hModule != NULL) - { - typedef HRESULT (CALLBACK *LPFN_DllGetVersion)(DLLVERSIONINFO_private *); - LPFN_DllGetVersion fnDllGetVersion = (LPFN_DllGetVersion)::GetProcAddress(hModule, "DllGetVersion"); - if(fnDllGetVersion != NULL) - { - DLLVERSIONINFO_private version = { 0 }; - version.cbSize = sizeof(DLLVERSIONINFO_private); - if(SUCCEEDED(fnDllGetVersion(&version))) - { - if(version.dwMajorVersion >= 6) - { - pThisNoConst->m_bShadowBufferNeeded = TRUE; - - ATLTRACE2(atlTraceUI, 0, _T("Warning: You have compiled for MBCS/ANSI but are using common controls version 6 or later (likely through a manifest file).\r\n")); - ATLTRACE2(atlTraceUI, 0, _T("If you use common controls version 6 or later, you should only do so for UNICODE builds.\r\n")); - } - } - } - - ::FreeLibrary(hModule); - hModule = NULL; - } - } -#endif // !_UNICODE - } - } - - return (pT->m_bShadowBufferNeeded != FALSE); - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CRichEditFindReplaceImpl - Mixin class for implementing Find/Replace for CRichEditCtrl -// based window classes. - -// Chain to CRichEditFindReplaceImpl message map. Your class must also derive from CRichEditCtrl. -// Example: -// class CMyRichEdit : public CWindowImpl, -// public CRichEditFindReplaceImpl -// { -// public: -// BEGIN_MSG_MAP(CMyRichEdit) -// // your handlers... -// CHAIN_MSG_MAP_ALT(CRichEditFindReplaceImpl, 1) -// END_MSG_MAP() -// // other stuff... -// }; - -template -class CRichEditFindReplaceImpl : public CEditFindReplaceImplBase -{ -protected: - typedef CRichEditFindReplaceImpl thisClass; - typedef CEditFindReplaceImplBase baseClass; - -public: - BEGIN_MSG_MAP(thisClass) - ALT_MSG_MAP(1) - CHAIN_MSG_MAP_ALT(baseClass, 1) - END_MSG_MAP() - -// Operations (overrideable) - BOOL FindTextSimple(LPCTSTR lpszFind, BOOL bMatchCase, BOOL bWholeWord, BOOL bFindDown = TRUE) - { - T* pT = static_cast(this); - - ATLASSERT(lpszFind != NULL); - FINDTEXTEX ft = { 0 }; - - pT->GetSel(ft.chrg); - if(m_bFirstSearch) - { - if(bFindDown) - m_nInitialSearchPos = ft.chrg.cpMin; - else - m_nInitialSearchPos = ft.chrg.cpMax; - m_bFirstSearch = FALSE; - } - -#if (_RICHEDIT_VER >= 0x0200) - ft.lpstrText = (LPTSTR)lpszFind; -#else // !(_RICHEDIT_VER >= 0x0200) - USES_CONVERSION; - ft.lpstrText = T2A((LPTSTR)lpszFind); -#endif // !(_RICHEDIT_VER >= 0x0200) - - if(ft.chrg.cpMin != ft.chrg.cpMax) // i.e. there is a selection - { - if(bFindDown) - { - ft.chrg.cpMin++; - } - else - { - // won't wraparound backwards - ft.chrg.cpMin = max(ft.chrg.cpMin, 0); - } - } - - DWORD dwFlags = bMatchCase ? FR_MATCHCASE : 0; - dwFlags |= bWholeWord ? FR_WHOLEWORD : 0; - - ft.chrg.cpMax = pT->GetTextLength() + m_nInitialSearchPos; - - if(bFindDown) - { - if(m_nInitialSearchPos >= 0) - ft.chrg.cpMax = pT->GetTextLength(); - - dwFlags |= FR_DOWN; - ATLASSERT(ft.chrg.cpMax >= ft.chrg.cpMin); - } - else - { - if(m_nInitialSearchPos >= 0) - ft.chrg.cpMax = 0; - - dwFlags &= ~FR_DOWN; - ATLASSERT(ft.chrg.cpMax <= ft.chrg.cpMin); - } - - BOOL bRet = FALSE; - - if(pT->FindAndSelect(dwFlags, ft) != -1) - { - bRet = TRUE; // we found the text - } - else if(m_nInitialSearchPos > 0) - { - // if the original starting point was not the beginning - // of the buffer and we haven't already been here - if(bFindDown) - { - ft.chrg.cpMin = 0; - ft.chrg.cpMax = m_nInitialSearchPos; - } - else - { - ft.chrg.cpMin = pT->GetTextLength(); - ft.chrg.cpMax = m_nInitialSearchPos; - } - m_nInitialSearchPos = m_nInitialSearchPos - pT->GetTextLength(); - - bRet = (pT->FindAndSelect(dwFlags, ft) != -1) ? TRUE : FALSE; - } - - return bRet; - } - - long FindAndSelect(DWORD dwFlags, FINDTEXTEX& ft) - { - T* pT = static_cast(this); - LONG index = pT->FindText(dwFlags, ft); - if(index != -1) // i.e. we found something - pT->SetSel(ft.chrgText); - - return index; - } -}; - -}; // namespace WTL - -#endif // __ATLFIND_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlframe.h b/!NotAdopted/SmartAutoReplier/wtl/atlframe.h deleted file mode 100644 index 252e50e902..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlframe.h +++ /dev/null @@ -1,3688 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLFRAME_H__ -#define __ATLFRAME_H__ - -#pragma once - -#ifndef __ATLAPP_H__ - #error atlframe.h requires atlapp.h to be included first -#endif - -#ifndef __ATLWIN_H__ - #error atlframe.h requires atlwin.h to be included first -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CFrameWindowImpl -// CMDIWindow -// CMDIFrameWindowImpl -// CMDIChildWindowImpl -// COwnerDraw -// CUpdateUIBase -// CUpdateUI -// CDynamicUpdateUI -// CAutoUpdateUI -// CDialogResize -// CDoubleBufferImpl -// CDoubleBufferWindowImpl -// -// Global functions: -// AtlCreateSimpleToolBar() - - -namespace WTL -{ - -/////////////////////////////////////////////////////////////////////////////// -// CFrameWndClassInfo - Manages frame window Windows class information - -class CFrameWndClassInfo -{ -public: -#ifndef _WIN32_WCE - enum { cchAutoName = 5 + sizeof(void*) * 2 }; // sizeof(void*) * 2 is the number of digits %p outputs - WNDCLASSEX m_wc; -#else // CE specific - enum { cchAutoName = MAX_PATH }; // MAX_PATH because this can be set in the wizard generated CMainFrame::ActivatePreviousInstance to a user defined string. - WNDCLASS m_wc; -#endif // !_WIN32_WCE - LPCTSTR m_lpszOrigName; - WNDPROC pWndProc; - LPCTSTR m_lpszCursorID; - BOOL m_bSystemCursor; - ATOM m_atom; - TCHAR m_szAutoName[cchAutoName]; - UINT m_uCommonResourceID; - -#ifndef _WIN32_WCE - ATOM Register(WNDPROC* pProc) - { - if (m_atom == 0) - { - CWindowCreateCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CFrameWndClassInfo::Register.\n")); - ATLASSERT(FALSE); - return 0; - } - - if(m_atom == 0) - { - HINSTANCE hInst = ModuleHelper::GetModuleInstance(); - - if (m_lpszOrigName != NULL) - { - ATLASSERT(pProc != NULL); - LPCTSTR lpsz = m_wc.lpszClassName; - WNDPROC proc = m_wc.lpfnWndProc; - - WNDCLASSEX wc = { 0 }; - wc.cbSize = sizeof(WNDCLASSEX); - // try process local class first - if(!::GetClassInfoEx(ModuleHelper::GetModuleInstance(), m_lpszOrigName, &wc)) - { - // try global class - if(!::GetClassInfoEx(NULL, m_lpszOrigName, &wc)) - { - lock.Unlock(); - return 0; - } - } - m_wc = wc; - pWndProc = m_wc.lpfnWndProc; - m_wc.lpszClassName = lpsz; - m_wc.lpfnWndProc = proc; - } - else - { - m_wc.hCursor = ::LoadCursor(m_bSystemCursor ? NULL : hInst, m_lpszCursorID); - } - - m_wc.hInstance = hInst; - m_wc.style &= ~CS_GLOBALCLASS; // we don't register global classes - if (m_wc.lpszClassName == NULL) - { -#if (_WIN32_WINNT >= 0x0500) || defined(_WIN64) - SecureHelper::wsprintf_x(m_szAutoName, cchAutoName, _T("ATL:%p"), &m_wc); -#else // !((_WIN32_WINNT >= 0x0500) || defined(_WIN64)) - SecureHelper::wsprintf_x(m_szAutoName, cchAutoName, _T("ATL:%8.8X"), (DWORD_PTR)&m_wc); -#endif // !((_WIN32_WINNT >= 0x0500) || defined(_WIN64)) - m_wc.lpszClassName = m_szAutoName; - } - - WNDCLASSEX wcTemp = m_wc; - m_atom = (ATOM)::GetClassInfoEx(m_wc.hInstance, m_wc.lpszClassName, &wcTemp); - if (m_atom == 0) - { - if(m_uCommonResourceID != 0) // use it if not zero - { - m_wc.hIcon = (HICON)::LoadImage(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(m_uCommonResourceID), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR); - m_wc.hIconSm = (HICON)::LoadImage(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(m_uCommonResourceID), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); - } - m_atom = ::RegisterClassEx(&m_wc); - } - } - - lock.Unlock(); - } - - if (m_lpszOrigName != NULL) - { - ATLASSERT(pProc != NULL); - ATLASSERT(pWndProc != NULL); - *pProc = pWndProc; - } - - return m_atom; - } -#else // CE specific - ATOM Register(WNDPROC* pProc) - { - if (m_atom == 0) - { - CWindowCreateCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CFrameWndClassInfo::Register.\n")); - ATLASSERT(FALSE); - return 0; - } - - if(m_atom == 0) - { - HINSTANCE hInst = ModuleHelper::GetModuleInstance(); - - if (m_lpszOrigName != NULL) - { - ATLASSERT(pProc != NULL); - LPCTSTR lpsz = m_wc.lpszClassName; - WNDPROC proc = m_wc.lpfnWndProc; - - WNDCLASS wc = { 0 }; - // try process local class first - if(!::GetClassInfo(ModuleHelper::GetModuleInstance(), m_lpszOrigName, &wc)) - { - // try global class - if(!::GetClassInfo(NULL, m_lpszOrigName, &wc)) - { - lock.Unlock(); - return 0; - } - } - m_wc = wc; - pWndProc = m_wc.lpfnWndProc; - m_wc.lpszClassName = lpsz; - m_wc.lpfnWndProc = proc; - } - else - { -#if defined(GWES_CURSOR) || defined(GWES_MCURSOR) - m_wc.hCursor = ::LoadCursor(m_bSystemCursor ? NULL : hInst, m_lpszCursorID); -#else // !(defined(GWES_CURSOR) || defined(GWES_MCURSOR)) - m_wc.hCursor = NULL; -#endif // !(defined(GWES_CURSOR) || defined(GWES_MCURSOR)) - } - - m_wc.hInstance = hInst; - m_wc.style &= ~CS_GLOBALCLASS; // we don't register global classes - if (m_wc.lpszClassName == NULL) - { - wsprintf(m_szAutoName, _T("ATL:%8.8X"), (DWORD_PTR)&m_wc); - m_wc.lpszClassName = m_szAutoName; - } - - WNDCLASS wcTemp = m_wc; - m_atom = (ATOM)::GetClassInfo(m_wc.hInstance, m_wc.lpszClassName, &wcTemp); - if (m_atom == 0) - { - if(m_uCommonResourceID != 0) // use it if not zero - m_wc.hIcon = (HICON)::LoadImage(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(m_uCommonResourceID), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR); - m_atom = ::RegisterClass(&m_wc); - } - } - - lock.Unlock(); - } - - if (m_lpszOrigName != NULL) - { - ATLASSERT(pProc != NULL); - ATLASSERT(pWndProc != NULL); - *pProc = pWndProc; - } - - return m_atom; - } -#endif // _WIN32_WCE -}; - - -/////////////////////////////////////////////////////////////////////////////// -// Macros for declaring frame window WNDCLASS - -#ifndef _WIN32_WCE - -#define DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) \ -static WTL::CFrameWndClassInfo& GetWndClassInfo() \ -{ \ - static WTL::CFrameWndClassInfo wc = \ - { \ - { sizeof(WNDCLASSEX), 0, StartWindowProc, \ - 0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndClassName, NULL }, \ - NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \ - }; \ - return wc; \ -} - -#define DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd) \ -static WTL::CFrameWndClassInfo& GetWndClassInfo() \ -{ \ - static WTL::CFrameWndClassInfo wc = \ - { \ - { sizeof(WNDCLASSEX), style, StartWindowProc, \ - 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName, NULL }, \ - NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \ - }; \ - return wc; \ -} - -#define DECLARE_FRAME_WND_SUPERCLASS(WndClassName, OrigWndClassName, uCommonResourceID) \ -static WTL::CFrameWndClassInfo& GetWndClassInfo() \ -{ \ - static WTL::CFrameWndClassInfo wc = \ - { \ - { sizeof(WNDCLASSEX), 0, StartWindowProc, \ - 0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName, NULL }, \ - OrigWndClassName, NULL, NULL, TRUE, 0, _T(""), uCommonResourceID \ - }; \ - return wc; \ -} - -#else // CE specific - -#define DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) \ -static WTL::CFrameWndClassInfo& GetWndClassInfo() \ -{ \ - static WTL::CFrameWndClassInfo wc = \ - { \ - { 0, StartWindowProc, \ - 0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndClassName }, \ - NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \ - }; \ - return wc; \ -} - -#define DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd) \ -static WTL::CFrameWndClassInfo& GetWndClassInfo() \ -{ \ - static WTL::CFrameWndClassInfo wc = \ - { \ - { style, StartWindowProc, \ - 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName }, \ - NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \ - }; \ - return wc; \ -} - -#define DECLARE_FRAME_WND_SUPERCLASS(WndClassName, OrigWndClassName, uCommonResourceID) \ -static WTL::CFrameWndClassInfo& GetWndClassInfo() \ -{ \ - static WTL::CFrameWndClassInfo wc = \ - { \ - { NULL, StartWindowProc, \ - 0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName }, \ - OrigWndClassName, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \ - }; \ - return wc; \ -} - -#endif // !_WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CFrameWindowImpl - -// Client window command chaining macro (only for frame windows) -#define CHAIN_CLIENT_COMMANDS() \ - if(uMsg == WM_COMMAND && m_hWndClient != NULL) \ - ::SendMessage(m_hWndClient, uMsg, wParam, lParam); - -// standard toolbar styles -#define ATL_SIMPLE_TOOLBAR_STYLE \ - (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS) -// toolbar in a rebar pane -#define ATL_SIMPLE_TOOLBAR_PANE_STYLE \ - (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NORESIZE | CCS_NOPARENTALIGN | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT) -// standard rebar styles -#if (_WIN32_IE >= 0x0400) - #define ATL_SIMPLE_REBAR_STYLE \ - (WS_CHILD | WS_VISIBLE | WS_BORDER | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_AUTOSIZE) -#else - #define ATL_SIMPLE_REBAR_STYLE \ - (WS_CHILD | WS_VISIBLE | WS_BORDER | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS) -#endif // !(_WIN32_IE >= 0x0400) -// rebar without borders -#if (_WIN32_IE >= 0x0400) - #define ATL_SIMPLE_REBAR_NOBORDER_STYLE \ - (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_AUTOSIZE | CCS_NODIVIDER) -#else - #define ATL_SIMPLE_REBAR_NOBORDER_STYLE \ - (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS | CCS_NODIVIDER) -#endif // !(_WIN32_IE >= 0x0400) - -// command bar support -#if !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE) - -#define CBRM_GETCMDBAR (WM_USER + 301) // returns command bar HWND -#define CBRM_GETMENU (WM_USER + 302) // returns loaded or attached menu -#define CBRM_TRACKPOPUPMENU (WM_USER + 303) // displays a popup menu - -struct _AtlFrameWnd_CmdBarPopupMenu -{ - int cbSize; - HMENU hMenu; - UINT uFlags; - int x; - int y; - LPTPMPARAMS lptpm; -}; - -#define CBRPOPUPMENU _AtlFrameWnd_CmdBarPopupMenu - -#endif // !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE) - - -template -class ATL_NO_VTABLE CFrameWindowImplBase : public ATL::CWindowImplBaseT< TBase, TWinTraits > -{ -public: - DECLARE_FRAME_WND_CLASS(NULL, 0) - -#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - struct _ChevronMenuInfo - { - HMENU hMenu; - LPNMREBARCHEVRON lpnm; - bool bCmdBar; - }; -#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - -// Data members - HWND m_hWndToolBar; - HWND m_hWndStatusBar; - HWND m_hWndClient; - -#ifdef _WIN32_WCE - HWND m_hWndCECommandBar; -#endif // _WIN32_WCE - - HACCEL m_hAccel; - -// Constructor - CFrameWindowImplBase() : - m_hWndToolBar(NULL), - m_hWndStatusBar(NULL), - m_hWndClient(NULL), -#ifdef _WIN32_WCE - m_hWndCECommandBar(NULL), -#endif // _WIN32_WCE - m_hAccel(NULL) - { } - -// Methods - HWND Create(HWND hWndParent, ATL::_U_RECT rect, LPCTSTR szWindowName, DWORD dwStyle, DWORD dwExStyle, ATL::_U_MENUorID MenuOrID, ATOM atom, LPVOID lpCreateParam) - { - ATLASSERT(m_hWnd == NULL); - - if(atom == 0) - return NULL; - - ModuleHelper::AddCreateWndData(&m_thunk.cd, this); - - if(MenuOrID.m_hMenu == NULL && (dwStyle & WS_CHILD)) - MenuOrID.m_hMenu = (HMENU)(UINT_PTR)this; - if(rect.m_lpRect == NULL) - rect.m_lpRect = &TBase::rcDefault; - - HWND hWnd = ::CreateWindowEx(dwExStyle, MAKEINTATOM(atom), szWindowName, - dwStyle, rect.m_lpRect->left, rect.m_lpRect->top, rect.m_lpRect->right - rect.m_lpRect->left, - rect.m_lpRect->bottom - rect.m_lpRect->top, hWndParent, MenuOrID.m_hMenu, - ModuleHelper::GetModuleInstance(), lpCreateParam); - - ATLASSERT(hWnd == NULL || m_hWnd == hWnd); - - return hWnd; - } - - static HWND CreateSimpleToolBarCtrl(HWND hWndParent, UINT nResourceID, BOOL bInitialSeparator = FALSE, - DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) - { - HINSTANCE hInst = ModuleHelper::GetResourceInstance(); - HRSRC hRsrc = ::FindResource(hInst, MAKEINTRESOURCE(nResourceID), RT_TOOLBAR); - if (hRsrc == NULL) - return NULL; - - HGLOBAL hGlobal = ::LoadResource(hInst, hRsrc); - if (hGlobal == NULL) - return NULL; - - _AtlToolBarData* pData = (_AtlToolBarData*)::LockResource(hGlobal); - if (pData == NULL) - return NULL; - ATLASSERT(pData->wVersion == 1); - - WORD* pItems = pData->items(); - int nItems = pData->wItemCount + (bInitialSeparator ? 1 : 0); - CTempBuffer buff; - TBBUTTON* pTBBtn = buff.Allocate(nItems); - ATLASSERT(pTBBtn != NULL); - if(pTBBtn == NULL) - return NULL; - - const int cxSeparator = 8; - - // set initial separator (half width) - if(bInitialSeparator) - { - pTBBtn[0].iBitmap = cxSeparator / 2; - pTBBtn[0].idCommand = 0; - pTBBtn[0].fsState = 0; - pTBBtn[0].fsStyle = TBSTYLE_SEP; - pTBBtn[0].dwData = 0; - pTBBtn[0].iString = 0; - } - - int nBmp = 0; - for(int i = 0, j = bInitialSeparator ? 1 : 0; i < pData->wItemCount; i++, j++) - { - if(pItems[i] != 0) - { - pTBBtn[j].iBitmap = nBmp++; - pTBBtn[j].idCommand = pItems[i]; - pTBBtn[j].fsState = TBSTATE_ENABLED; - pTBBtn[j].fsStyle = TBSTYLE_BUTTON; - pTBBtn[j].dwData = 0; - pTBBtn[j].iString = 0; - } - else - { - pTBBtn[j].iBitmap = cxSeparator; - pTBBtn[j].idCommand = 0; - pTBBtn[j].fsState = 0; - pTBBtn[j].fsStyle = TBSTYLE_SEP; - pTBBtn[j].dwData = 0; - pTBBtn[j].iString = 0; - } - } - -#ifndef _WIN32_WCE - HWND hWnd = ::CreateWindowEx(0, TOOLBARCLASSNAME, NULL, dwStyle, 0, 0, 100, 100, hWndParent, (HMENU)LongToHandle(nID), ModuleHelper::GetModuleInstance(), NULL); - if(hWnd == NULL) - { - ATLASSERT(FALSE); - return NULL; - } -#else // CE specific - dwStyle; - nID; - // The toolbar must go onto the existing CommandBar or MenuBar - HWND hWnd = hWndParent; -#endif // _WIN32_WCE - - ::SendMessage(hWnd, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0L); - - // check if font is taller than our bitmaps - CFontHandle font = (HFONT)::SendMessage(hWnd, WM_GETFONT, 0, 0L); - if(font.IsNull()) - font = (HFONT)::GetStockObject(SYSTEM_FONT); - LOGFONT lf = { 0 }; - font.GetLogFont(lf); - WORD cyFontHeight = (WORD)abs(lf.lfHeight); - -#ifndef _WIN32_WCE - WORD bitsPerPixel = AtlGetBitmapResourceBitsPerPixel(nResourceID); - if(bitsPerPixel > 4) - { - COLORREF crMask = CLR_DEFAULT; - if(bitsPerPixel == 32) - { - // 32-bit color bitmap with alpha channel (valid for Windows XP and later) - crMask = CLR_NONE; - } - HIMAGELIST hImageList = ImageList_LoadImage(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(nResourceID), pData->wWidth, 1, crMask, IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_DEFAULTSIZE); - ATLASSERT(hImageList != NULL); - ::SendMessage(hWnd, TB_SETIMAGELIST, 0, (LPARAM)hImageList); - } - else -#endif // !_WIN32_WCE - { - TBADDBITMAP tbab = { 0 }; - tbab.hInst = hInst; - tbab.nID = nResourceID; - ::SendMessage(hWnd, TB_ADDBITMAP, nBmp, (LPARAM)&tbab); - } - - ::SendMessage(hWnd, TB_ADDBUTTONS, nItems, (LPARAM)pTBBtn); - ::SendMessage(hWnd, TB_SETBITMAPSIZE, 0, MAKELONG(pData->wWidth, max(pData->wHeight, cyFontHeight))); - const int cxyButtonMargin = 7; - ::SendMessage(hWnd, TB_SETBUTTONSIZE, 0, MAKELONG(pData->wWidth + cxyButtonMargin, max(pData->wHeight, cyFontHeight) + cxyButtonMargin)); - - return hWnd; - } - -#ifndef _WIN32_WCE - static HWND CreateSimpleReBarCtrl(HWND hWndParent, DWORD dwStyle = ATL_SIMPLE_REBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) - { - // Ensure style combinations for proper rebar painting - if(dwStyle & CCS_NODIVIDER && dwStyle & WS_BORDER) - dwStyle &= ~WS_BORDER; - else if(!(dwStyle & WS_BORDER) && !(dwStyle & CCS_NODIVIDER)) - dwStyle |= CCS_NODIVIDER; - - // Create rebar window - HWND hWndReBar = ::CreateWindowEx(0, REBARCLASSNAME, NULL, dwStyle, 0, 0, 100, 100, hWndParent, (HMENU)LongToHandle(nID), ModuleHelper::GetModuleInstance(), NULL); - if(hWndReBar == NULL) - { - ATLTRACE2(atlTraceUI, 0, _T("Failed to create rebar.\n")); - return NULL; - } - - // Initialize and send the REBARINFO structure - REBARINFO rbi = { 0 }; - rbi.cbSize = sizeof(REBARINFO); - rbi.fMask = 0; - if(!::SendMessage(hWndReBar, RB_SETBARINFO, 0, (LPARAM)&rbi)) - { - ATLTRACE2(atlTraceUI, 0, _T("Failed to initialize rebar.\n")); - ::DestroyWindow(hWndReBar); - return NULL; - } - - return hWndReBar; - } - - BOOL CreateSimpleReBar(DWORD dwStyle = ATL_SIMPLE_REBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) - { - ATLASSERT(!::IsWindow(m_hWndToolBar)); - m_hWndToolBar = CreateSimpleReBarCtrl(m_hWnd, dwStyle, nID); - return (m_hWndToolBar != NULL); - } - - static BOOL AddSimpleReBarBandCtrl(HWND hWndReBar, HWND hWndBand, int nID = 0, LPCTSTR lpstrTitle = NULL, BOOL bNewRow = FALSE, int cxWidth = 0, BOOL bFullWidthAlways = FALSE) - { - ATLASSERT(::IsWindow(hWndReBar)); // must be already created -#ifdef _DEBUG - // block - check if this is really a rebar - { - TCHAR lpszClassName[sizeof(REBARCLASSNAME)] = { 0 }; - ::GetClassName(hWndReBar, lpszClassName, sizeof(REBARCLASSNAME)); - ATLASSERT(lstrcmp(lpszClassName, REBARCLASSNAME) == 0); - } -#endif // _DEBUG - ATLASSERT(::IsWindow(hWndBand)); // must be already created - - // Get number of buttons on the toolbar - int nBtnCount = (int)::SendMessage(hWndBand, TB_BUTTONCOUNT, 0, 0L); - - // Set band info structure - REBARBANDINFO rbBand = { RunTimeHelper::SizeOf_REBARBANDINFO() }; -#if (_WIN32_IE >= 0x0400) - rbBand.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_ID | RBBIM_SIZE | RBBIM_IDEALSIZE; -#else - rbBand.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_ID | RBBIM_SIZE; -#endif // !(_WIN32_IE >= 0x0400) - if(lpstrTitle != NULL) - rbBand.fMask |= RBBIM_TEXT; - rbBand.fStyle = RBBS_CHILDEDGE; -#if (_WIN32_IE >= 0x0500) - if(nBtnCount > 0) // add chevron style for toolbar with buttons - rbBand.fStyle |= RBBS_USECHEVRON; -#endif // (_WIN32_IE >= 0x0500) - if(bNewRow) - rbBand.fStyle |= RBBS_BREAK; - - rbBand.lpText = (LPTSTR)lpstrTitle; - rbBand.hwndChild = hWndBand; - if(nID == 0) // calc band ID - nID = ATL_IDW_BAND_FIRST + (int)::SendMessage(hWndReBar, RB_GETBANDCOUNT, 0, 0L); - rbBand.wID = nID; - - // Calculate the size of the band - BOOL bRet = FALSE; - RECT rcTmp = { 0 }; - if(nBtnCount > 0) - { - bRet = (BOOL)::SendMessage(hWndBand, TB_GETITEMRECT, nBtnCount - 1, (LPARAM)&rcTmp); - ATLASSERT(bRet); - rbBand.cx = (cxWidth != 0) ? cxWidth : rcTmp.right; - rbBand.cyMinChild = rcTmp.bottom - rcTmp.top; - if(bFullWidthAlways) - { - rbBand.cxMinChild = rbBand.cx; - } - else if(lpstrTitle == NULL) - { - bRet = (BOOL)::SendMessage(hWndBand, TB_GETITEMRECT, 0, (LPARAM)&rcTmp); - ATLASSERT(bRet); - rbBand.cxMinChild = rcTmp.right; - } - else - { - rbBand.cxMinChild = 0; - } - } - else // no buttons, either not a toolbar or really has no buttons - { - bRet = ::GetWindowRect(hWndBand, &rcTmp); - ATLASSERT(bRet); - rbBand.cx = (cxWidth != 0) ? cxWidth : (rcTmp.right - rcTmp.left); - rbBand.cxMinChild = bFullWidthAlways ? rbBand.cx : 0; - rbBand.cyMinChild = rcTmp.bottom - rcTmp.top; - } - -#if (_WIN32_IE >= 0x0400) - rbBand.cxIdeal = rbBand.cx; -#endif // (_WIN32_IE >= 0x0400) - - // Add the band - LRESULT lRes = ::SendMessage(hWndReBar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand); - if(lRes == 0) - { - ATLTRACE2(atlTraceUI, 0, _T("Failed to add a band to the rebar.\n")); - return FALSE; - } - -#if (_WIN32_IE >= 0x0501) - DWORD dwExStyle = (DWORD)::SendMessage(hWndBand, TB_GETEXTENDEDSTYLE, 0, 0L); - ::SendMessage(hWndBand, TB_SETEXTENDEDSTYLE, 0, dwExStyle | TBSTYLE_EX_HIDECLIPPEDBUTTONS); -#endif // (_WIN32_IE >= 0x0501) - - return TRUE; - } - - BOOL AddSimpleReBarBand(HWND hWndBand, LPCTSTR lpstrTitle = NULL, BOOL bNewRow = FALSE, int cxWidth = 0, BOOL bFullWidthAlways = FALSE) - { - ATLASSERT(::IsWindow(m_hWndToolBar)); // must be an existing rebar - ATLASSERT(::IsWindow(hWndBand)); // must be created - return AddSimpleReBarBandCtrl(m_hWndToolBar, hWndBand, 0, lpstrTitle, bNewRow, cxWidth, bFullWidthAlways); - } - -#if (_WIN32_IE >= 0x0400) - void SizeSimpleReBarBands() - { - ATLASSERT(::IsWindow(m_hWndToolBar)); // must be an existing rebar - - int nCount = (int)::SendMessage(m_hWndToolBar, RB_GETBANDCOUNT, 0, 0L); - - for(int i = 0; i < nCount; i++) - { - REBARBANDINFO rbBand = { RunTimeHelper::SizeOf_REBARBANDINFO() }; - rbBand.fMask = RBBIM_SIZE; - BOOL bRet = (BOOL)::SendMessage(m_hWndToolBar, RB_GETBANDINFO, i, (LPARAM)&rbBand); - ATLASSERT(bRet); - RECT rect = { 0, 0, 0, 0 }; - ::SendMessage(m_hWndToolBar, RB_GETBANDBORDERS, i, (LPARAM)&rect); - rbBand.cx += rect.left + rect.right; - bRet = (BOOL)::SendMessage(m_hWndToolBar, RB_SETBANDINFO, i, (LPARAM)&rbBand); - ATLASSERT(bRet); - } - } -#endif // (_WIN32_IE >= 0x0400) -#endif // _WIN32_WCE - -#ifndef _WIN32_WCE - BOOL CreateSimpleStatusBar(LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR) -#else // CE specific - BOOL CreateSimpleStatusBar(LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, UINT nID = ATL_IDW_STATUS_BAR) -#endif // _WIN32_WCE - { - ATLASSERT(!::IsWindow(m_hWndStatusBar)); - m_hWndStatusBar = ::CreateStatusWindow(dwStyle, lpstrText, m_hWnd, nID); - return (m_hWndStatusBar != NULL); - } - -#ifndef _WIN32_WCE - BOOL CreateSimpleStatusBar(UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR) -#else // CE specific - BOOL CreateSimpleStatusBar(UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, UINT nID = ATL_IDW_STATUS_BAR) -#endif // _WIN32_WCE - { - const int cchMax = 128; // max text length is 127 for status bars (+1 for null) - TCHAR szText[cchMax]; - szText[0] = 0; - ::LoadString(ModuleHelper::GetResourceInstance(), nTextID, szText, cchMax); - return CreateSimpleStatusBar(szText, dwStyle, nID); - } - -#ifdef _WIN32_WCE - BOOL CreateSimpleCECommandBar(LPTSTR pszMenu = NULL, WORD iButton = 0, DWORD dwFlags = 0, int nCmdBarID = 1) - { - ATLASSERT(m_hWndCECommandBar == NULL); - ATLASSERT(m_hWndToolBar == NULL); - - m_hWndCECommandBar = ::CommandBar_Create(ModuleHelper::GetModuleInstance(), m_hWnd, nCmdBarID); - if(m_hWndCECommandBar == NULL) - return FALSE; - - m_hWndToolBar = m_hWndCECommandBar; - - BOOL bRet = TRUE; - - if(pszMenu != NULL) - bRet &= ::CommandBar_InsertMenubarEx(m_hWndCECommandBar, IS_INTRESOURCE(pszMenu) ? ModuleHelper::GetResourceInstance() : NULL, pszMenu, iButton); - - bRet &= ::CommandBar_AddAdornments(m_hWndCECommandBar, dwFlags, 0); - - return bRet; - } - -#if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) - BOOL CreateSimpleCEMenuBar(UINT nToolBarId = ATL_IDW_MENU_BAR, DWORD dwFlags = 0, int nBmpId = 0, int cBmpImages = 0) - { - ATLASSERT(m_hWndCECommandBar == NULL); - - SHMENUBARINFO mbi = { 0 }; - mbi.cbSize = sizeof(mbi); - mbi.hwndParent = m_hWnd; - mbi.dwFlags = dwFlags; - mbi.nToolBarId = nToolBarId; - mbi.hInstRes = ModuleHelper::GetResourceInstance(); - mbi.nBmpId = nBmpId; - mbi.cBmpImages = cBmpImages; - mbi.hwndMB = NULL; // This gets set by SHCreateMenuBar - - BOOL bRet = ::SHCreateMenuBar(&mbi); - if(bRet != FALSE) - { - m_hWndCECommandBar = mbi.hwndMB; - SizeToMenuBar(); - } - - return bRet; - } - - void SizeToMenuBar() // for menu bar only - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(::IsWindow(m_hWndCECommandBar)); - - RECT rect = { 0 }; - GetWindowRect(&rect); - RECT rectMB = { 0 }; - ::GetWindowRect(m_hWndCECommandBar, &rectMB); - int cy = ::IsWindowVisible(m_hWndCECommandBar) ? rectMB.top - rect.top : rectMB.bottom - rect.top; - SetWindowPos(NULL, 0, 0, rect.right - rect.left, cy, SWP_NOZORDER | SWP_NOMOVE); - } -#endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) -#endif // _WIN32_WCE - - void UpdateLayout(BOOL bResizeBars = TRUE) - { - RECT rect = { 0 }; - GetClientRect(&rect); - - // position bars and offset their dimensions - UpdateBarsPosition(rect, bResizeBars); - - // resize client window - if(m_hWndClient != NULL) - ::SetWindowPos(m_hWndClient, NULL, rect.left, rect.top, - rect.right - rect.left, rect.bottom - rect.top, - SWP_NOZORDER | SWP_NOACTIVATE); - } - - void UpdateBarsPosition(RECT& rect, BOOL bResizeBars = TRUE) - { - // resize toolbar - if(m_hWndToolBar != NULL && ((DWORD)::GetWindowLong(m_hWndToolBar, GWL_STYLE) & WS_VISIBLE)) - { - if(bResizeBars != FALSE) - { - ::SendMessage(m_hWndToolBar, WM_SIZE, 0, 0); - ::InvalidateRect(m_hWndToolBar, NULL, TRUE); - } - RECT rectTB = { 0 }; - ::GetWindowRect(m_hWndToolBar, &rectTB); - rect.top += rectTB.bottom - rectTB.top; - } - - // resize status bar - if(m_hWndStatusBar != NULL && ((DWORD)::GetWindowLong(m_hWndStatusBar, GWL_STYLE) & WS_VISIBLE)) - { - if(bResizeBars != FALSE) - ::SendMessage(m_hWndStatusBar, WM_SIZE, 0, 0); - RECT rectSB = { 0 }; - ::GetWindowRect(m_hWndStatusBar, &rectSB); - rect.bottom -= rectSB.bottom - rectSB.top; - } - } - - BOOL PreTranslateMessage(MSG* pMsg) - { - if(m_hAccel != NULL && ::TranslateAccelerator(m_hWnd, m_hAccel, pMsg)) - return TRUE; - return FALSE; - } - - BEGIN_MSG_MAP(CFrameWindowImplBase) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) -#ifndef _WIN32_WCE - MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect) -#endif // !_WIN32_WCE - MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) -#ifndef _WIN32_WCE - NOTIFY_CODE_HANDLER(TTN_GETDISPINFOA, OnToolTipTextA) - NOTIFY_CODE_HANDLER(TTN_GETDISPINFOW, OnToolTipTextW) -#endif // !_WIN32_WCE - END_MSG_MAP() - - LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - if(m_hWndClient != NULL) // view will paint itself instead - return 1; - - bHandled = FALSE; - return 0; - } - -#ifndef _WIN32_WCE - LRESULT OnMenuSelect(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - bHandled = FALSE; - - if(m_hWndStatusBar == NULL) - return 1; - - WORD wFlags = HIWORD(wParam); - if(wFlags == 0xFFFF && lParam == NULL) // menu closing - { - ::SendMessage(m_hWndStatusBar, SB_SIMPLE, FALSE, 0L); - } - else - { - const int cchBuff = 256; - TCHAR szBuff[cchBuff]; - szBuff[0] = 0; - if(!(wFlags & MF_POPUP)) - { - WORD wID = LOWORD(wParam); - // check for special cases - if(wID >= 0xF000 && wID < 0xF1F0) // system menu IDs - wID = (WORD)(((wID - 0xF000) >> 4) + ATL_IDS_SCFIRST); - else if(wID >= ID_FILE_MRU_FIRST && wID <= ID_FILE_MRU_LAST) // MRU items - wID = ATL_IDS_MRU_FILE; - else if(wID >= ATL_IDM_FIRST_MDICHILD && wID <= ATL_IDM_LAST_MDICHILD) // MDI child windows - wID = ATL_IDS_MDICHILD; - - int nRet = ::LoadString(ModuleHelper::GetResourceInstance(), wID, szBuff, cchBuff); - for(int i = 0; i < nRet; i++) - { - if(szBuff[i] == _T('\n')) - { - szBuff[i] = 0; - break; - } - } - } - ::SendMessage(m_hWndStatusBar, SB_SIMPLE, TRUE, 0L); - ::SendMessage(m_hWndStatusBar, SB_SETTEXT, (255 | SBT_NOBORDERS), (LPARAM)szBuff); - } - - return 1; - } -#endif // !_WIN32_WCE - - LRESULT OnSetFocus(UINT, WPARAM, LPARAM, BOOL& bHandled) - { - if(m_hWndClient != NULL) - ::SetFocus(m_hWndClient); - - bHandled = FALSE; - return 1; - } - - LRESULT OnDestroy(UINT, WPARAM, LPARAM, BOOL& bHandled) - { - if((GetStyle() & (WS_CHILD | WS_POPUP)) == 0) - ::PostQuitMessage(1); - - bHandled = FALSE; - return 1; - } - -#ifndef _WIN32_WCE - LRESULT OnToolTipTextA(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/) - { - LPNMTTDISPINFOA pDispInfo = (LPNMTTDISPINFOA)pnmh; - pDispInfo->szText[0] = 0; - - if((idCtrl != 0) && !(pDispInfo->uFlags & TTF_IDISHWND)) - { - const int cchBuff = 256; - char szBuff[cchBuff]; - szBuff[0] = 0; - int nRet = ::LoadStringA(ModuleHelper::GetResourceInstance(), idCtrl, szBuff, cchBuff); - for(int i = 0; i < nRet; i++) - { - if(szBuff[i] == '\n') - { - SecureHelper::strncpyA_x(pDispInfo->szText, _countof(pDispInfo->szText), &szBuff[i + 1], _TRUNCATE); - break; - } - } -#if (_WIN32_IE >= 0x0300) - if(nRet > 0) // string was loaded, save it - pDispInfo->uFlags |= TTF_DI_SETITEM; -#endif // (_WIN32_IE >= 0x0300) - } - - return 0; - } - - LRESULT OnToolTipTextW(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/) - { - LPNMTTDISPINFOW pDispInfo = (LPNMTTDISPINFOW)pnmh; - pDispInfo->szText[0] = 0; - - if((idCtrl != 0) && !(pDispInfo->uFlags & TTF_IDISHWND)) - { - const int cchBuff = 256; - wchar_t szBuff[cchBuff]; - szBuff[0] = 0; - int nRet = ::LoadStringW(ModuleHelper::GetResourceInstance(), idCtrl, szBuff, cchBuff); - for(int i = 0; i < nRet; i++) - { - if(szBuff[i] == L'\n') - { - SecureHelper::strncpyW_x(pDispInfo->szText, _countof(pDispInfo->szText), &szBuff[i + 1], _TRUNCATE); - break; - } - } -#if (_WIN32_IE >= 0x0300) - if(nRet > 0) // string was loaded, save it - pDispInfo->uFlags |= TTF_DI_SETITEM; -#endif // (_WIN32_IE >= 0x0300) - } - - return 0; - } -#endif // !_WIN32_WCE - -// Implementation - chevron menu support -#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - bool PrepareChevronMenu(_ChevronMenuInfo& cmi) - { - // get rebar and toolbar - REBARBANDINFO rbbi = { RunTimeHelper::SizeOf_REBARBANDINFO() }; - rbbi.fMask = RBBIM_CHILD; - BOOL bRet = (BOOL)::SendMessage(cmi.lpnm->hdr.hwndFrom, RB_GETBANDINFO, cmi.lpnm->uBand, (LPARAM)&rbbi); - ATLASSERT(bRet); - - // assume the band is a toolbar - ATL::CWindow wnd = rbbi.hwndChild; - int nCount = (int)wnd.SendMessage(TB_BUTTONCOUNT); - if(nCount <= 0) // probably not a toolbar - return false; - - // check if it's a command bar - CMenuHandle menuCmdBar = (HMENU)wnd.SendMessage(CBRM_GETMENU); - cmi.bCmdBar = (menuCmdBar.m_hMenu != NULL); - - // build a menu from hidden items - CMenuHandle menu; - bRet = menu.CreatePopupMenu(); - ATLASSERT(bRet); - RECT rcClient = { 0 }; - bRet = wnd.GetClientRect(&rcClient); - ATLASSERT(bRet); - for(int i = 0; i < nCount; i++) - { - TBBUTTON tbb = { 0 }; - bRet = (BOOL)wnd.SendMessage(TB_GETBUTTON, i, (LPARAM)&tbb); - ATLASSERT(bRet); - // skip hidden buttons - if((tbb.fsState & TBSTATE_HIDDEN) != 0) - continue; - RECT rcButton = { 0 }; - bRet = (BOOL)wnd.SendMessage(TB_GETITEMRECT, i, (LPARAM)&rcButton); - ATLASSERT(bRet); - bool bEnabled = ((tbb.fsState & TBSTATE_ENABLED) != 0); - if(rcButton.right > rcClient.right) - { - if(tbb.fsStyle & BTNS_SEP) - { - if(menu.GetMenuItemCount() > 0) - menu.AppendMenu(MF_SEPARATOR); - } - else if(cmi.bCmdBar) - { - const int cchBuff = 200; - TCHAR szBuff[cchBuff] = { 0 }; - CMenuItemInfo mii; - mii.fMask = MIIM_TYPE | MIIM_SUBMENU; - mii.dwTypeData = szBuff; - mii.cch = cchBuff; - bRet = menuCmdBar.GetMenuItemInfo(i, TRUE, &mii); - ATLASSERT(bRet); - // Note: CmdBar currently supports only drop-down items - ATLASSERT(::IsMenu(mii.hSubMenu)); - bRet = menu.AppendMenu(MF_STRING | MF_POPUP | (bEnabled ? MF_ENABLED : MF_GRAYED), (UINT_PTR)mii.hSubMenu, mii.dwTypeData); - ATLASSERT(bRet); - } - else - { - // get button's text - const int cchBuff = 200; - TCHAR szBuff[cchBuff] = { 0 }; - LPTSTR lpstrText = szBuff; - TBBUTTONINFO tbbi = { 0 }; - tbbi.cbSize = sizeof(TBBUTTONINFO); - tbbi.dwMask = TBIF_TEXT; - tbbi.pszText = szBuff; - tbbi.cchText = cchBuff; - if(wnd.SendMessage(TB_GETBUTTONINFO, tbb.idCommand, (LPARAM)&tbbi) == -1 || lstrlen(szBuff) == 0) - { - // no text for this button, try a resource string - lpstrText = _T(""); - int nRet = ::LoadString(ModuleHelper::GetResourceInstance(), tbb.idCommand, szBuff, cchBuff); - for(int n = 0; n < nRet; n++) - { - if(szBuff[n] == _T('\n')) - { - lpstrText = &szBuff[n + 1]; - break; - } - } - } - bRet = menu.AppendMenu(MF_STRING | (bEnabled ? MF_ENABLED : MF_GRAYED), tbb.idCommand, lpstrText); - ATLASSERT(bRet); - } - } - } - - if(menu.GetMenuItemCount() == 0) // no hidden buttons after all - { - menu.DestroyMenu(); - ::MessageBeep((UINT)-1); - return false; - } - - cmi.hMenu = menu; - return true; - } - - void DisplayChevronMenu(_ChevronMenuInfo& cmi) - { -#ifndef TPM_VERPOSANIMATION - const UINT TPM_VERPOSANIMATION = 0x1000L; // Menu animation flag -#endif - // convert chevron rect to screen coordinates - ATL::CWindow wndFrom = cmi.lpnm->hdr.hwndFrom; - POINT pt = { cmi.lpnm->rc.left, cmi.lpnm->rc.bottom }; - wndFrom.MapWindowPoints(NULL, &pt, 1); - RECT rc = cmi.lpnm->rc; - wndFrom.MapWindowPoints(NULL, &rc); - // set up flags and rect - UINT uMenuFlags = TPM_LEFTBUTTON | TPM_VERTICAL | TPM_LEFTALIGN | TPM_TOPALIGN | (!AtlIsOldWindows() ? TPM_VERPOSANIMATION : 0); - TPMPARAMS TPMParams = { 0 }; - TPMParams.cbSize = sizeof(TPMPARAMS); - TPMParams.rcExclude = rc; - // check if this window has a command bar - HWND hWndCmdBar = (HWND)::SendMessage(m_hWnd, CBRM_GETCMDBAR, 0, 0L); - if(::IsWindow(hWndCmdBar)) - { - CBRPOPUPMENU CBRPopupMenu = { sizeof(CBRPOPUPMENU), cmi.hMenu, uMenuFlags, pt.x, pt.y, &TPMParams }; - ::SendMessage(hWndCmdBar, CBRM_TRACKPOPUPMENU, 0, (LPARAM)&CBRPopupMenu); - } - else - { - CMenuHandle menu = cmi.hMenu; - menu.TrackPopupMenuEx(uMenuFlags, pt.x, pt.y, m_hWnd, &TPMParams); - } - } - - void CleanupChevronMenu(_ChevronMenuInfo& cmi) - { - CMenuHandle menu = cmi.hMenu; - // if menu is from a command bar, detach submenus so they are not destroyed - if(cmi.bCmdBar) - { - for(int i = menu.GetMenuItemCount() - 1; i >=0; i--) - menu.RemoveMenu(i, MF_BYPOSITION); - } - // destroy menu - menu.DestroyMenu(); - // convert chevron rect to screen coordinates - ATL::CWindow wndFrom = cmi.lpnm->hdr.hwndFrom; - RECT rc = cmi.lpnm->rc; - wndFrom.MapWindowPoints(NULL, &rc); - // eat next message if click is on the same button - MSG msg = { 0 }; - if(::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE) && ::PtInRect(&rc, msg.pt)) - ::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_REMOVE); - } -#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) -}; - - -template -class ATL_NO_VTABLE CFrameWindowImpl : public CFrameWindowImplBase< TBase, TWinTraits > -{ -public: - HWND Create(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - HMENU hMenu = NULL, LPVOID lpCreateParam = NULL) - { - ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc); - - dwStyle = T::GetWndStyle(dwStyle); - dwExStyle = T::GetWndExStyle(dwExStyle); - - if(rect.m_lpRect == NULL) - rect.m_lpRect = &TBase::rcDefault; - - return CFrameWindowImplBase< TBase, TWinTraits >::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, hMenu, atom, lpCreateParam); - } - - HWND CreateEx(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL) - { - const int cchName = 256; - TCHAR szWindowName[cchName]; - szWindowName[0] = 0; -#ifndef _WIN32_WCE - ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName); - HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID)); -#else // CE specific - ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName); - - // This always needs to be NULL for Windows CE. - // Frame Window menus have to go onto the CommandBar. - // Use CreateSimpleCECommandBar - HMENU hMenu = NULL; -#endif // _WIN32_WCE - - T* pT = static_cast(this); - HWND hWnd = pT->Create(hWndParent, rect, szWindowName, dwStyle, dwExStyle, hMenu, lpCreateParam); - - if(hWnd != NULL) - m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID)); - - return hWnd; - } - - BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) - { - if(nResourceID == 0) - nResourceID = T::GetWndClassInfo().m_uCommonResourceID; -#ifndef _WIN32_WCE - ATLASSERT(!::IsWindow(m_hWndToolBar)); - m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE, dwStyle, nID); - return (m_hWndToolBar != NULL); -#else // CE specific - HWND hWnd= T::CreateSimpleToolBarCtrl(m_hWndCECommandBar, nResourceID, TRUE, dwStyle, nID); - return (hWnd != NULL); -#endif // _WIN32_WCE - } - -#ifdef _WIN32_WCE - // CE specific variant that returns the handle of the toolbar - HWND CreateSimpleCEToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) - { - if(nResourceID == 0) - nResourceID = T::GetWndClassInfo().m_uCommonResourceID; - - return T::CreateSimpleToolBarCtrl(m_hWndCECommandBar, nResourceID, TRUE, dwStyle, nID); - } -#endif // _WIN32_WCE - -// message map and handlers - typedef CFrameWindowImplBase< TBase, TWinTraits > _baseClass; - - BEGIN_MSG_MAP(CFrameWindowImpl) - MESSAGE_HANDLER(WM_SIZE, OnSize) -#ifndef _ATL_NO_REBAR_SUPPORT -#if (_WIN32_IE >= 0x0400) - NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize) -#endif // (_WIN32_IE >= 0x0400) -#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed) -#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) -#endif // !_ATL_NO_REBAR_SUPPORT - CHAIN_MSG_MAP(_baseClass) - END_MSG_MAP() - - LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - if(wParam != SIZE_MINIMIZED) - { - T* pT = static_cast(this); - pT->UpdateLayout(); - } - bHandled = FALSE; - return 1; - } - -#ifndef _ATL_NO_REBAR_SUPPORT -#if (_WIN32_IE >= 0x0400) - LRESULT OnReBarAutoSize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->UpdateLayout(FALSE); - return 0; - } -#endif // (_WIN32_IE >= 0x0400) - -#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) - LRESULT OnChevronPushed(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) - { - T* pT = static_cast(this); - _ChevronMenuInfo cmi = { NULL, (LPNMREBARCHEVRON)pnmh, false }; - if(!pT->PrepareChevronMenu(cmi)) - { - bHandled = FALSE; - return 1; - } - // display a popup menu with hidden items - pT->DisplayChevronMenu(cmi); - // cleanup - pT->CleanupChevronMenu(cmi); - return 0; - } -#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) -#endif // !_ATL_NO_REBAR_SUPPORT -}; - - -/////////////////////////////////////////////////////////////////////////////// -// AtlCreateSimpleToolBar - helper for creating simple toolbars - -#ifndef _WIN32_WCE - -inline HWND AtlCreateSimpleToolBar(HWND hWndParent, UINT nResourceID, BOOL bInitialSeparator = FALSE, - DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) -{ - return CFrameWindowImplBase<>::CreateSimpleToolBarCtrl(hWndParent, nResourceID, bInitialSeparator, dwStyle, nID); -} - -#endif // !_WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CMDIWindow - -#ifndef _WIN32_WCE - -#ifndef _WTL_MDIWINDOWMENU_TEXT -#define _WTL_MDIWINDOWMENU_TEXT _T("&Window") -#endif - -class CMDIWindow : public ATL::CWindow -{ -public: -// Data members - HWND m_hWndMDIClient; - HMENU m_hMenu; - -// Constructors - CMDIWindow(HWND hWnd = NULL) : ATL::CWindow(hWnd), m_hWndMDIClient(NULL), m_hMenu(NULL) - { } - - CMDIWindow& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - -// Operations - HWND MDIGetActive(BOOL* lpbMaximized = NULL) - { - ATLASSERT(::IsWindow(m_hWndMDIClient)); - return (HWND)::SendMessage(m_hWndMDIClient, WM_MDIGETACTIVE, 0, (LPARAM)lpbMaximized); - } - - void MDIActivate(HWND hWndChildToActivate) - { - ATLASSERT(::IsWindow(m_hWndMDIClient)); - ATLASSERT(::IsWindow(hWndChildToActivate)); - ::SendMessage(m_hWndMDIClient, WM_MDIACTIVATE, (WPARAM)hWndChildToActivate, 0); - } - - void MDINext(HWND hWndChild, BOOL bPrevious = FALSE) - { - ATLASSERT(::IsWindow(m_hWndMDIClient)); - ATLASSERT(hWndChild == NULL || ::IsWindow(hWndChild)); - ::SendMessage(m_hWndMDIClient, WM_MDINEXT, (WPARAM)hWndChild, (LPARAM)bPrevious); - } - - void MDIMaximize(HWND hWndChildToMaximize) - { - ATLASSERT(::IsWindow(m_hWndMDIClient)); - ATLASSERT(::IsWindow(hWndChildToMaximize)); - ::SendMessage(m_hWndMDIClient, WM_MDIMAXIMIZE, (WPARAM)hWndChildToMaximize, 0); - } - - void MDIRestore(HWND hWndChildToRestore) - { - ATLASSERT(::IsWindow(m_hWndMDIClient)); - ATLASSERT(::IsWindow(hWndChildToRestore)); - ::SendMessage(m_hWndMDIClient, WM_MDIRESTORE, (WPARAM)hWndChildToRestore, 0); - } - - void MDIDestroy(HWND hWndChildToDestroy) - { - ATLASSERT(::IsWindow(m_hWndMDIClient)); - ATLASSERT(::IsWindow(hWndChildToDestroy)); - ::SendMessage(m_hWndMDIClient, WM_MDIDESTROY, (WPARAM)hWndChildToDestroy, 0); - } - - BOOL MDICascade(UINT uFlags = 0) - { - ATLASSERT(::IsWindow(m_hWndMDIClient)); - return (BOOL)::SendMessage(m_hWndMDIClient, WM_MDICASCADE, (WPARAM)uFlags, 0); - } - - BOOL MDITile(UINT uFlags = MDITILE_HORIZONTAL) - { - ATLASSERT(::IsWindow(m_hWndMDIClient)); - return (BOOL)::SendMessage(m_hWndMDIClient, WM_MDITILE, (WPARAM)uFlags, 0); - } - - void MDIIconArrange() - { - ATLASSERT(::IsWindow(m_hWndMDIClient)); - ::SendMessage(m_hWndMDIClient, WM_MDIICONARRANGE, 0, 0); - } - - HMENU MDISetMenu(HMENU hMenuFrame, HMENU hMenuWindow) - { - ATLASSERT(::IsWindow(m_hWndMDIClient)); - return (HMENU)::SendMessage(m_hWndMDIClient, WM_MDISETMENU, (WPARAM)hMenuFrame, (LPARAM)hMenuWindow); - } - - HMENU MDIRefreshMenu() - { - ATLASSERT(::IsWindow(m_hWndMDIClient)); - return (HMENU)::SendMessage(m_hWndMDIClient, WM_MDIREFRESHMENU, 0, 0); - } - -// Additional operations - static HMENU GetStandardWindowMenu(HMENU hMenu) - { - int nCount = ::GetMenuItemCount(hMenu); - if(nCount == -1) - return NULL; - int nLen = ::GetMenuString(hMenu, nCount - 2, NULL, 0, MF_BYPOSITION); - if(nLen == 0) - return NULL; - CTempBuffer buff; - LPTSTR lpszText = buff.Allocate(nLen + 1); - if(lpszText == NULL) - return NULL; - if(::GetMenuString(hMenu, nCount - 2, lpszText, nLen + 1, MF_BYPOSITION) != nLen) - return NULL; - if(lstrcmp(lpszText, _WTL_MDIWINDOWMENU_TEXT) != 0) - return NULL; - return ::GetSubMenu(hMenu, nCount - 2); - } - - void SetMDIFrameMenu() - { - HMENU hWindowMenu = GetStandardWindowMenu(m_hMenu); - MDISetMenu(m_hMenu, hWindowMenu); - MDIRefreshMenu(); - ::DrawMenuBar(GetMDIFrame()); - } - - HWND GetMDIFrame() const - { - return ::GetParent(m_hWndMDIClient); - } -}; - -#endif // !_WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CMDIFrameWindowImpl - -#ifndef _WIN32_WCE - -// MDI child command chaining macro (only for MDI frame windows) -#define CHAIN_MDI_CHILD_COMMANDS() \ - if(uMsg == WM_COMMAND) \ - { \ - HWND hWndChild = MDIGetActive(); \ - if(hWndChild != NULL) \ - ::SendMessage(hWndChild, uMsg, wParam, lParam); \ - } - -template -class ATL_NO_VTABLE CMDIFrameWindowImpl : public CFrameWindowImplBase -{ -public: - HWND Create(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - HMENU hMenu = NULL, LPVOID lpCreateParam = NULL) - { - m_hMenu = hMenu; - ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc); - - dwStyle = T::GetWndStyle(dwStyle); - dwExStyle = T::GetWndExStyle(dwExStyle); - - if(rect.m_lpRect == NULL) - rect.m_lpRect = &TBase::rcDefault; - - return CFrameWindowImplBase::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, hMenu, atom, lpCreateParam); - } - - HWND CreateEx(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL) - { - const int cchName = 256; - TCHAR szWindowName[cchName]; - szWindowName[0] = 0; - ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName); - HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID)); - - T* pT = static_cast(this); - HWND hWnd = pT->Create(hWndParent, rect, szWindowName, dwStyle, dwExStyle, hMenu, lpCreateParam); - - if(hWnd != NULL) - m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID)); - - return hWnd; - } - - BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) - { - ATLASSERT(!::IsWindow(m_hWndToolBar)); - if(nResourceID == 0) - nResourceID = T::GetWndClassInfo().m_uCommonResourceID; - m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE, dwStyle, nID); - return (m_hWndToolBar != NULL); - } - - virtual WNDPROC GetWindowProc() - { - return MDIFrameWindowProc; - } - - static LRESULT CALLBACK MDIFrameWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) - { - CMDIFrameWindowImpl< T, TBase, TWinTraits >* pThis = (CMDIFrameWindowImpl< T, TBase, TWinTraits >*)hWnd; - // set a ptr to this message and save the old value -#if (_ATL_VER >= 0x0700) - ATL::_ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam); - const ATL::_ATL_MSG* pOldMsg = pThis->m_pCurrentMsg; -#else // !(_ATL_VER >= 0x0700) - MSG msg = { pThis->m_hWnd, uMsg, wParam, lParam, 0, { 0, 0 } }; - const MSG* pOldMsg = pThis->m_pCurrentMsg; -#endif // !(_ATL_VER >= 0x0700) - pThis->m_pCurrentMsg = &msg; - // pass to the message map to process - LRESULT lRes = 0; - BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0); - // restore saved value for the current message - ATLASSERT(pThis->m_pCurrentMsg == &msg); - pThis->m_pCurrentMsg = pOldMsg; - // do the default processing if message was not handled - if(!bRet) - { - if(uMsg != WM_NCDESTROY) - lRes = pThis->DefWindowProc(uMsg, wParam, lParam); - else - { - // unsubclass, if needed - LONG_PTR pfnWndProc = ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC); - lRes = pThis->DefWindowProc(uMsg, wParam, lParam); - if(pThis->m_pfnSuperWindowProc != ::DefWindowProc && ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC) == pfnWndProc) - ::SetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC, (LONG_PTR)pThis->m_pfnSuperWindowProc); -#if (_ATL_VER >= 0x0700) - // mark window as destryed - pThis->m_dwState |= WINSTATE_DESTROYED; -#else // !(_ATL_VER >= 0x0700) - // clear out window handle - HWND hWnd = pThis->m_hWnd; - pThis->m_hWnd = NULL; - // clean up after window is destroyed - pThis->OnFinalMessage(hWnd); -#endif // !(_ATL_VER >= 0x0700) - } - } -#if (_ATL_VER >= 0x0700) - if(pThis->m_dwState & WINSTATE_DESTROYED && pThis->m_pCurrentMsg == NULL) - { - // clear out window handle - HWND hWnd = pThis->m_hWnd; - pThis->m_hWnd = NULL; - pThis->m_dwState &= ~WINSTATE_DESTROYED; - // clean up after window is destroyed - pThis->OnFinalMessage(hWnd); - } -#endif // (_ATL_VER >= 0x0700) - return lRes; - } - - // Overriden to call DefWindowProc which uses DefFrameProc - LRESULT DefWindowProc() - { - const MSG* pMsg = m_pCurrentMsg; - LRESULT lRes = 0; - if (pMsg != NULL) - lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg->lParam); - return lRes; - } - - LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) - { - return ::DefFrameProc(m_hWnd, m_hWndMDIClient, uMsg, wParam, lParam); - } - - BOOL PreTranslateMessage(MSG* pMsg) - { - if(CFrameWindowImplBase::PreTranslateMessage(pMsg)) - return TRUE; - return ::TranslateMDISysAccel(m_hWndMDIClient, pMsg); - } - - HWND CreateMDIClient(HMENU hWindowMenu = NULL, UINT nID = ATL_IDW_CLIENT, UINT nFirstChildID = ATL_IDM_FIRST_MDICHILD) - { - DWORD dwStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | MDIS_ALLCHILDSTYLES; - DWORD dwExStyle = WS_EX_CLIENTEDGE; - - CLIENTCREATESTRUCT ccs = { 0 }; - ccs.hWindowMenu = hWindowMenu; - ccs.idFirstChild = nFirstChildID; - - if((GetStyle() & (WS_HSCROLL | WS_VSCROLL)) != 0) - { - // parent MDI frame's scroll styles move to the MDICLIENT - dwStyle |= (GetStyle() & (WS_HSCROLL | WS_VSCROLL)); - - // fast way to turn off the scrollbar bits (without a resize) - ModifyStyle(WS_HSCROLL | WS_VSCROLL, 0, SWP_NOREDRAW | SWP_FRAMECHANGED); - } - - // Create MDICLIENT window - m_hWndClient = ::CreateWindowEx(dwExStyle, _T("MDIClient"), NULL, - dwStyle, 0, 0, 1, 1, m_hWnd, (HMENU)LongToHandle(nID), - ModuleHelper::GetModuleInstance(), (LPVOID)&ccs); - if (m_hWndClient == NULL) - { - ATLTRACE2(atlTraceUI, 0, _T("MDI Frame failed to create MDICLIENT.\n")); - return NULL; - } - - // Move it to the top of z-order - ::BringWindowToTop(m_hWndClient); - - // set as MDI client window - m_hWndMDIClient = m_hWndClient; - - // update to proper size - T* pT = static_cast(this); - pT->UpdateLayout(); - - return m_hWndClient; - } - - typedef CFrameWindowImplBase _baseClass; - - BEGIN_MSG_MAP(CMDIFrameWindowImpl) - MESSAGE_HANDLER(WM_SIZE, OnSize) - MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) - MESSAGE_HANDLER(WM_MDISETMENU, OnMDISetMenu) -#ifndef _ATL_NO_REBAR_SUPPORT -#if (_WIN32_IE >= 0x0400) - NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize) -#endif // (_WIN32_IE >= 0x0400) -#if (_WIN32_IE >= 0x0500) - NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed) -#endif // (_WIN32_IE >= 0x0500) -#endif // !_ATL_NO_REBAR_SUPPORT - CHAIN_MSG_MAP(_baseClass) - END_MSG_MAP() - - LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - if(wParam != SIZE_MINIMIZED) - { - T* pT = static_cast(this); - pT->UpdateLayout(); - } - // message must be handled, otherwise DefFrameProc would resize the client again - return 0; - } - - LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - // don't allow CFrameWindowImplBase to handle this one - return DefWindowProc(uMsg, wParam, lParam); - } - - LRESULT OnMDISetMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - SetMDIFrameMenu(); - return 0; - } - -#ifndef _ATL_NO_REBAR_SUPPORT -#if (_WIN32_IE >= 0x0400) - LRESULT OnReBarAutoSize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->UpdateLayout(FALSE); - return 0; - } -#endif // (_WIN32_IE >= 0x0400) - -#if (_WIN32_IE >= 0x0500) - LRESULT OnChevronPushed(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) - { - T* pT = static_cast(this); - _ChevronMenuInfo cmi = { NULL, (LPNMREBARCHEVRON)pnmh, false }; - if(!pT->PrepareChevronMenu(cmi)) - { - bHandled = FALSE; - return 1; - } - // display a popup menu with hidden items - pT->DisplayChevronMenu(cmi); - // cleanup - pT->CleanupChevronMenu(cmi); - return 0; - } -#endif // (_WIN32_IE >= 0x0500) -#endif // !_ATL_NO_REBAR_SUPPORT -}; - -#endif // !_WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CMDIChildWindowImpl - -#ifndef _WIN32_WCE - -template -class ATL_NO_VTABLE CMDIChildWindowImpl : public CFrameWindowImplBase -{ -public: - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - UINT nMenuID = 0, LPVOID lpCreateParam = NULL) - { - ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc); - - if(nMenuID != 0) - m_hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(nMenuID)); - - dwStyle = T::GetWndStyle(dwStyle); - dwExStyle = T::GetWndExStyle(dwExStyle); - - dwExStyle |= WS_EX_MDICHILD; // force this one - m_pfnSuperWindowProc = ::DefMDIChildProc; - m_hWndMDIClient = hWndParent; - ATLASSERT(::IsWindow(m_hWndMDIClient)); - - if(rect.m_lpRect == NULL) - rect.m_lpRect = &TBase::rcDefault; - - // If the currently active MDI child is maximized, we want to create this one maximized too - ATL::CWindow wndParent = hWndParent; - BOOL bMaximized = FALSE; - wndParent.SendMessage(WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized); - if(bMaximized) - wndParent.SetRedraw(FALSE); - - HWND hWnd = CFrameWindowImplBase::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, (UINT)0U, atom, lpCreateParam); - - if(bMaximized) - { - // Maximize and redraw everything - if(hWnd != NULL) - MDIMaximize(hWnd); - wndParent.SetRedraw(TRUE); - wndParent.RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); - ::SetFocus(GetMDIFrame()); // focus will be set back to this window - } - else if(hWnd != NULL && ::IsWindowVisible(m_hWnd) && !::IsChild(hWnd, ::GetFocus())) - { - ::SetFocus(hWnd); - } - - return hWnd; - } - - HWND CreateEx(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR lpcstrWindowName = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL) - { - const int cchName = 256; - TCHAR szWindowName[cchName]; - szWindowName[0] = 0; - if(lpcstrWindowName == NULL) - { - ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName); - lpcstrWindowName = szWindowName; - } - - T* pT = static_cast(this); - HWND hWnd = pT->Create(hWndParent, rect, lpcstrWindowName, dwStyle, dwExStyle, T::GetWndClassInfo().m_uCommonResourceID, lpCreateParam); - - if(hWnd != NULL) - m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID)); - - return hWnd; - } - - BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) - { - ATLASSERT(!::IsWindow(m_hWndToolBar)); - if(nResourceID == 0) - nResourceID = T::GetWndClassInfo().m_uCommonResourceID; - m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE, dwStyle, nID); - return (m_hWndToolBar != NULL); - } - - BOOL UpdateClientEdge(LPRECT lpRect = NULL) - { - // only adjust for active MDI child window - HWND hWndChild = MDIGetActive(); - if(hWndChild != NULL && hWndChild != m_hWnd) - return FALSE; - - // need to adjust the client edge style as max/restore happens - DWORD dwStyle = ::GetWindowLong(m_hWndMDIClient, GWL_EXSTYLE); - DWORD dwNewStyle = dwStyle; - if(hWndChild != NULL && ((GetExStyle() & WS_EX_CLIENTEDGE) == 0) && ((GetStyle() & WS_MAXIMIZE) != 0)) - dwNewStyle &= ~(WS_EX_CLIENTEDGE); - else - dwNewStyle |= WS_EX_CLIENTEDGE; - - if(dwStyle != dwNewStyle) - { - // SetWindowPos will not move invalid bits - ::RedrawWindow(m_hWndMDIClient, NULL, NULL, - RDW_INVALIDATE | RDW_ALLCHILDREN); - // remove/add WS_EX_CLIENTEDGE to MDI client area - ::SetWindowLong(m_hWndMDIClient, GWL_EXSTYLE, dwNewStyle); - ::SetWindowPos(m_hWndMDIClient, NULL, 0, 0, 0, 0, - SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | - SWP_NOZORDER | SWP_NOCOPYBITS); - - // return new client area - if (lpRect != NULL) - ::GetClientRect(m_hWndMDIClient, lpRect); - - return TRUE; - } - - return FALSE; - } - - typedef CFrameWindowImplBase _baseClass; - BEGIN_MSG_MAP(CMDIChildWindowImpl) - MESSAGE_HANDLER(WM_SIZE, OnSize) - MESSAGE_HANDLER(WM_WINDOWPOSCHANGED, OnWindowPosChanged) - MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate) - MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect) - MESSAGE_HANDLER(WM_MDIACTIVATE, OnMDIActivate) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) -#ifndef _ATL_NO_REBAR_SUPPORT -#if (_WIN32_IE >= 0x0400) - NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize) -#endif // (_WIN32_IE >= 0x0400) -#if (_WIN32_IE >= 0x0500) - NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed) -#endif // (_WIN32_IE >= 0x0500) -#endif // !_ATL_NO_REBAR_SUPPORT - CHAIN_MSG_MAP(_baseClass) - END_MSG_MAP() - - LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - DefWindowProc(uMsg, wParam, lParam); // needed for MDI children - if(wParam != SIZE_MINIMIZED) - { - T* pT = static_cast(this); - pT->UpdateLayout(); - } - return 0; - } - - LRESULT OnWindowPosChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - // update MDI client edge and adjust MDI child rect - LPWINDOWPOS lpWndPos = (LPWINDOWPOS)lParam; - - if(!(lpWndPos->flags & SWP_NOSIZE)) - { - RECT rectClient; - if(UpdateClientEdge(&rectClient) && ((GetStyle() & WS_MAXIMIZE) != 0)) - { - ::AdjustWindowRectEx(&rectClient, GetStyle(), FALSE, GetExStyle()); - lpWndPos->x = rectClient.left; - lpWndPos->y = rectClient.top; - lpWndPos->cx = rectClient.right - rectClient.left; - lpWndPos->cy = rectClient.bottom - rectClient.top; - } - } - - bHandled = FALSE; - return 1; - } - - LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - LRESULT lRes = DefWindowProc(uMsg, wParam, lParam); - - // Activate this MDI window if needed - if(lRes == MA_ACTIVATE || lRes == MA_ACTIVATEANDEAT) - { - if(MDIGetActive() != m_hWnd) - MDIActivate(m_hWnd); - } - - return lRes; - } - - LRESULT OnMenuSelect(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - return ::SendMessage(GetMDIFrame(), uMsg, wParam, lParam); - } - - LRESULT OnMDIActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - if((HWND)lParam == m_hWnd && m_hMenu != NULL) - SetMDIFrameMenu(); - else if((HWND)lParam == NULL) - ::SendMessage(GetMDIFrame(), WM_MDISETMENU, 0, 0); - - bHandled = FALSE; - return 1; - } - - LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - if(m_hMenu != NULL) - { - ::DestroyMenu(m_hMenu); - m_hMenu = NULL; - } - UpdateClientEdge(); - bHandled = FALSE; - return 1; - } - -#ifndef _ATL_NO_REBAR_SUPPORT -#if (_WIN32_IE >= 0x0400) - LRESULT OnReBarAutoSize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->UpdateLayout(FALSE); - return 0; - } -#endif // (_WIN32_IE >= 0x0400) - -#if (_WIN32_IE >= 0x0500) - LRESULT OnChevronPushed(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) - { - T* pT = static_cast(this); - _ChevronMenuInfo cmi = { NULL, (LPNMREBARCHEVRON)pnmh, false }; - if(!pT->PrepareChevronMenu(cmi)) - { - bHandled = FALSE; - return 1; - } - // display a popup menu with hidden items - pT->DisplayChevronMenu(cmi); - // cleanup - pT->CleanupChevronMenu(cmi); - return 0; - } -#endif // (_WIN32_IE >= 0x0500) -#endif // !_ATL_NO_REBAR_SUPPORT -}; - -#endif // !_WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// COwnerDraw - MI class for owner-draw support - -template -class COwnerDraw -{ -public: -#if (_ATL_VER < 0x0700) - BOOL m_bHandledOD; - - BOOL IsMsgHandled() const - { - return m_bHandledOD; - } - void SetMsgHandled(BOOL bHandled) - { - m_bHandledOD = bHandled; - } -#endif // (_ATL_VER < 0x0700) - -// Message map and handlers - BEGIN_MSG_MAP(COwnerDraw< T >) - MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem) - MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem) - MESSAGE_HANDLER(WM_COMPAREITEM, OnCompareItem) - MESSAGE_HANDLER(WM_DELETEITEM, OnDeleteItem) - ALT_MSG_MAP(1) - MESSAGE_HANDLER(OCM_DRAWITEM, OnDrawItem) - MESSAGE_HANDLER(OCM_MEASUREITEM, OnMeasureItem) - MESSAGE_HANDLER(OCM_COMPAREITEM, OnCompareItem) - MESSAGE_HANDLER(OCM_DELETEITEM, OnDeleteItem) - END_MSG_MAP() - - LRESULT OnDrawItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - T* pT = static_cast(this); - pT->SetMsgHandled(TRUE); - pT->DrawItem((LPDRAWITEMSTRUCT)lParam); - bHandled = pT->IsMsgHandled(); - return (LRESULT)TRUE; - } - - LRESULT OnMeasureItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - T* pT = static_cast(this); - pT->SetMsgHandled(TRUE); - pT->MeasureItem((LPMEASUREITEMSTRUCT)lParam); - bHandled = pT->IsMsgHandled(); - return (LRESULT)TRUE; - } - - LRESULT OnCompareItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - T* pT = static_cast(this); - pT->SetMsgHandled(TRUE); - bHandled = pT->IsMsgHandled(); - return (LRESULT)pT->CompareItem((LPCOMPAREITEMSTRUCT)lParam); - } - - LRESULT OnDeleteItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - T* pT = static_cast(this); - pT->SetMsgHandled(TRUE); - pT->DeleteItem((LPDELETEITEMSTRUCT)lParam); - bHandled = pT->IsMsgHandled(); - return (LRESULT)TRUE; - } - -// Overrideables - void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/) - { - // must be implemented - ATLASSERT(FALSE); - } - - void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) - { - if(lpMeasureItemStruct->CtlType != ODT_MENU) - { - // return default height for a system font - T* pT = static_cast(this); - HWND hWnd = pT->GetDlgItem(lpMeasureItemStruct->CtlID); - CClientDC dc(hWnd); - TEXTMETRIC tm = { 0 }; - dc.GetTextMetrics(&tm); - - lpMeasureItemStruct->itemHeight = tm.tmHeight; - } - else - lpMeasureItemStruct->itemHeight = ::GetSystemMetrics(SM_CYMENU); - } - - int CompareItem(LPCOMPAREITEMSTRUCT /*lpCompareItemStruct*/) - { - // all items are equal - return 0; - } - - void DeleteItem(LPDELETEITEMSTRUCT /*lpDeleteItemStruct*/) - { - // default - nothing - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// Update UI macros - -// these build the Update UI map inside a class definition -#define BEGIN_UPDATE_UI_MAP(thisClass) \ - static const CUpdateUIBase::_AtlUpdateUIMap* GetUpdateUIMap() \ - { \ - static const _AtlUpdateUIMap theMap[] = \ - { - -#define UPDATE_ELEMENT(nID, wType) \ - { nID, wType }, - -#define END_UPDATE_UI_MAP() \ - { (WORD)-1, 0 } \ - }; \ - return theMap; \ - } - -/////////////////////////////////////////////////////////////////////////////// -// CUpdateUI - manages UI elements updating - -class CUpdateUIBase -{ -public: - // constants - enum - { - // UI element type - UPDUI_MENUPOPUP = 0x0001, - UPDUI_MENUBAR = 0x0002, - UPDUI_CHILDWINDOW = 0x0004, - UPDUI_TOOLBAR = 0x0008, - UPDUI_STATUSBAR = 0x0010, - // state - UPDUI_ENABLED = 0x0000, - UPDUI_DISABLED = 0x0100, - UPDUI_CHECKED = 0x0200, - UPDUI_CHECKED2 = 0x0400, - UPDUI_RADIO = 0x0800, - UPDUI_DEFAULT = 0x1000, - UPDUI_TEXT = 0x2000, - // internal state - UPDUI_CLEARDEFAULT = 0x4000, - }; - - // element data - struct _AtlUpdateUIElement - { - HWND m_hWnd; - WORD m_wType; - - bool operator ==(const _AtlUpdateUIElement& e) const - { return (m_hWnd == e.m_hWnd && m_wType == e.m_wType); } - }; - - // map data - struct _AtlUpdateUIMap - { - WORD m_nID; - WORD m_wType; - - bool operator ==(const _AtlUpdateUIMap& e) const - { return (m_nID == e.m_nID && m_wType == e.m_wType); } - }; - - // instance data - struct _AtlUpdateUIData - { - WORD m_wState; - union - { - void* m_lpData; - LPTSTR m_lpstrText; - struct - { - WORD m_nIDFirst; - WORD m_nIDLast; - }; - }; - - bool operator ==(const _AtlUpdateUIData& e) const - { return (m_wState == e.m_wState && m_lpData == e.m_lpData); } - }; - - ATL::CSimpleArray<_AtlUpdateUIElement> m_UIElements; // elements data - const _AtlUpdateUIMap* m_pUIMap; // static UI data - _AtlUpdateUIData* m_pUIData; // instance UI data - WORD m_wDirtyType; // global dirty flag - - bool m_bBlockAccelerators; - - -// Constructor, destructor - CUpdateUIBase() : m_pUIMap(NULL), m_pUIData(NULL), m_wDirtyType(0), m_bBlockAccelerators(false) - { } - - ~CUpdateUIBase() - { - if(m_pUIMap != NULL && m_pUIData != NULL) - { - const _AtlUpdateUIMap* pUIMap = m_pUIMap; - _AtlUpdateUIData* pUIData = m_pUIData; - while(pUIMap->m_nID != (WORD)-1) - { - if(pUIData->m_wState & UPDUI_TEXT) - delete [] pUIData->m_lpstrText; - pUIMap++; - pUIData++; - } - delete [] m_pUIData; - } - } - -// Check for disabled commands - bool UIGetBlockAccelerators() const - { - return m_bBlockAccelerators; - } - - bool UISetBlockAccelerators(bool bBlock) - { - bool bOld = m_bBlockAccelerators; - m_bBlockAccelerators = bBlock; - return bOld; - } - -// Add elements - BOOL UIAddMenuBar(HWND hWnd) // menu bar (main menu) - { - if(hWnd == NULL) - return FALSE; - _AtlUpdateUIElement e; - e.m_hWnd = hWnd; - e.m_wType = UPDUI_MENUBAR; - return m_UIElements.Add(e); - } - - BOOL UIAddToolBar(HWND hWnd) // toolbar - { - if(hWnd == NULL) - return FALSE; - _AtlUpdateUIElement e; - e.m_hWnd = hWnd; - e.m_wType = UPDUI_TOOLBAR; - return m_UIElements.Add(e); - } - - BOOL UIAddStatusBar(HWND hWnd) // status bar - { - if(hWnd == NULL) - return FALSE; - _AtlUpdateUIElement e; - e.m_hWnd = hWnd; - e.m_wType = UPDUI_STATUSBAR; - return m_UIElements.Add(e); - } - - BOOL UIAddChildWindowContainer(HWND hWnd) // child window - { - if(hWnd == NULL) - return FALSE; - _AtlUpdateUIElement e; - e.m_hWnd = hWnd; - e.m_wType = UPDUI_CHILDWINDOW; - return m_UIElements.Add(e); - } - -// Message map for popup menu updates and accelerator blocking - BEGIN_MSG_MAP(CUpdateUIBase) - MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup) - MESSAGE_HANDLER(WM_COMMAND, OnCommand) - END_MSG_MAP() - - LRESULT OnInitMenuPopup(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - bHandled = FALSE; - HMENU hMenu = (HMENU)wParam; - if(hMenu == NULL) - return 1; - _AtlUpdateUIData* pUIData = m_pUIData; - if(pUIData == NULL) - return 1; - const _AtlUpdateUIMap* pMap = m_pUIMap; - while(pMap->m_nID != (WORD)-1) - { - if(pMap->m_wType & UPDUI_MENUPOPUP) - { - UIUpdateMenuBarElement(pMap->m_nID, pUIData, hMenu); - - if((pUIData->m_wState & UPDUI_RADIO) != 0) - ::CheckMenuRadioItem(hMenu, pUIData->m_nIDFirst, pUIData->m_nIDLast, pMap->m_nID, MF_BYCOMMAND); - } - pMap++; - pUIData++; - } - return 0; - } - - LRESULT OnCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - bHandled = FALSE; - if(m_bBlockAccelerators && HIWORD(wParam) == 1) // accelerators only - { - int nID = LOWORD(wParam); - if((UIGetState(nID) & UPDUI_DISABLED) == UPDUI_DISABLED) - { - ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIBase::OnCommand - blocked disabled command 0x%4.4X\n"), nID); - bHandled = TRUE; // eat the command, UI item is disabled - } - } - return 0; - } - -// methods for setting UI element state - BOOL UIEnable(int nID, BOOL bEnable, BOOL bForceUpdate = FALSE) - { - const _AtlUpdateUIMap* pMap = m_pUIMap; - _AtlUpdateUIData* pUIData = m_pUIData; - if(pUIData == NULL) - return FALSE; - - for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) - { - if(nID == (int)pMap->m_nID) - { - if(bEnable) - { - if(pUIData->m_wState & UPDUI_DISABLED) - { - pUIData->m_wState |= pMap->m_wType; - pUIData->m_wState &= ~UPDUI_DISABLED; - } - } - else - { - if(!(pUIData->m_wState & UPDUI_DISABLED)) - { - pUIData->m_wState |= pMap->m_wType; - pUIData->m_wState |= UPDUI_DISABLED; - } - } - - if(bForceUpdate) - pUIData->m_wState |= pMap->m_wType; - if(pUIData->m_wState & pMap->m_wType) - m_wDirtyType |= pMap->m_wType; - - break; // found - } - } - - return TRUE; - } - - BOOL UISetCheck(int nID, int nCheck, BOOL bForceUpdate = FALSE) - { - const _AtlUpdateUIMap* pMap = m_pUIMap; - _AtlUpdateUIData* pUIData = m_pUIData; - if(pUIData == NULL) - return FALSE; - - for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) - { - if(nID == (int)pMap->m_nID) - { - switch(nCheck) - { - case 0: - if((pUIData->m_wState & UPDUI_CHECKED) || (pUIData->m_wState & UPDUI_CHECKED2)) - { - pUIData->m_wState |= pMap->m_wType; - pUIData->m_wState &= ~(UPDUI_CHECKED | UPDUI_CHECKED2); - } - break; - case 1: - if(!(pUIData->m_wState & UPDUI_CHECKED)) - { - pUIData->m_wState |= pMap->m_wType; - pUIData->m_wState &= ~UPDUI_CHECKED2; - pUIData->m_wState |= UPDUI_CHECKED; - } - break; - case 2: - if(!(pUIData->m_wState & UPDUI_CHECKED2)) - { - pUIData->m_wState |= pMap->m_wType; - pUIData->m_wState &= ~UPDUI_CHECKED; - pUIData->m_wState |= UPDUI_CHECKED2; - } - break; - } - - if(bForceUpdate) - pUIData->m_wState |= pMap->m_wType; - if(pUIData->m_wState & pMap->m_wType) - m_wDirtyType |= pMap->m_wType; - - break; // found - } - } - - return TRUE; - } - - // variant that supports bool (checked/not-checked, no intermediate state) - BOOL UISetCheck(int nID, bool bCheck, BOOL bForceUpdate = FALSE) - { - return UISetCheck(nID, bCheck ? 1 : 0, bForceUpdate); - } - - BOOL UISetRadio(int nID, BOOL bRadio, BOOL bForceUpdate = FALSE) - { - const _AtlUpdateUIMap* pMap = m_pUIMap; - _AtlUpdateUIData* pUIData = m_pUIData; - if(pUIData == NULL) - return FALSE; - - for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) - { - if(nID == (int)pMap->m_nID) - { - if(bRadio) - { - if(!(pUIData->m_wState & UPDUI_RADIO)) - { - pUIData->m_wState |= pMap->m_wType; - pUIData->m_wState |= UPDUI_RADIO; - } - } - else - { - if(pUIData->m_wState & UPDUI_RADIO) - { - pUIData->m_wState |= pMap->m_wType; - pUIData->m_wState &= ~UPDUI_RADIO; - } - } - - if(bForceUpdate) - pUIData->m_wState |= pMap->m_wType; - if(pUIData->m_wState & pMap->m_wType) - m_wDirtyType |= pMap->m_wType; - - break; // found - } - } - - return TRUE; - } - - // for menu items - BOOL UISetRadioMenuItem(int nID, int nIDFirst, int nIDLast, BOOL bForceUpdate = FALSE) - { - const _AtlUpdateUIMap* pMap = m_pUIMap; - _AtlUpdateUIData* pUIData = m_pUIData; - if(pUIData == NULL) - return FALSE; - - for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) - { - if(nID == (int)pMap->m_nID) - { - pUIData->m_wState |= pMap->m_wType; - pUIData->m_wState |= UPDUI_RADIO; - pUIData->m_nIDFirst = (WORD)nIDFirst; - pUIData->m_nIDLast = (WORD)nIDLast; - - if(bForceUpdate) - pUIData->m_wState |= pMap->m_wType; - if(pUIData->m_wState & pMap->m_wType) - m_wDirtyType |= pMap->m_wType; - } - else if(pMap->m_nID >= nIDFirst && pMap->m_nID <= nIDLast) - { - if(pUIData->m_wState & UPDUI_RADIO) - { - pUIData->m_wState &= ~pMap->m_wType; - pUIData->m_wState &= ~UPDUI_RADIO; - pUIData->m_nIDFirst = 0; - pUIData->m_nIDLast = 0; - } - } - - if(pMap->m_nID == nIDLast) - break; - } - - return TRUE; - } - - BOOL UISetText(int nID, LPCTSTR lpstrText, BOOL bForceUpdate = FALSE) - { - const _AtlUpdateUIMap* pMap = m_pUIMap; - _AtlUpdateUIData* pUIData = m_pUIData; - if(pUIData == NULL) - return FALSE; - if(lpstrText == NULL) - lpstrText = _T(""); - - for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) - { - if(nID == (int)pMap->m_nID) - { - if(pUIData->m_lpstrText == NULL || lstrcmp(pUIData->m_lpstrText, lpstrText)) - { - delete [] pUIData->m_lpstrText; - pUIData->m_lpstrText = NULL; - int nStrLen = lstrlen(lpstrText); - ATLTRY(pUIData->m_lpstrText = new TCHAR[nStrLen + 1]); - if(pUIData->m_lpstrText == NULL) - { - ATLTRACE2(atlTraceUI, 0, _T("UISetText - memory allocation failed\n")); - break; - } - SecureHelper::strcpy_x(pUIData->m_lpstrText, nStrLen + 1, lpstrText); - pUIData->m_wState |= (UPDUI_TEXT | pMap->m_wType); - } - - if(bForceUpdate) - pUIData->m_wState |= (UPDUI_TEXT | pMap->m_wType); - if(pUIData->m_wState & pMap->m_wType) - m_wDirtyType |= pMap->m_wType; - - break; // found - } - } - - return TRUE; - } - - BOOL UISetDefault(int nID, BOOL bDefault, BOOL bForceUpdate = FALSE) - { - const _AtlUpdateUIMap* pMap = m_pUIMap; - _AtlUpdateUIData* pUIData = m_pUIData; - if(pUIData == NULL) - return FALSE; - - for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) - { - if(nID == (int)pMap->m_nID) - { - if(bDefault) - { - if((pUIData->m_wState & UPDUI_DEFAULT) == 0) - { - pUIData->m_wState |= pMap->m_wType; - pUIData->m_wState |= UPDUI_DEFAULT; - } - } - else - { - if((pUIData->m_wState & UPDUI_DEFAULT) != 0) - { - pUIData->m_wState |= pMap->m_wType; - pUIData->m_wState &= ~UPDUI_DEFAULT; - pUIData->m_wState |= UPDUI_CLEARDEFAULT; - } - } - - if(bForceUpdate) - pUIData->m_wState |= pMap->m_wType; - if(pUIData->m_wState & pMap->m_wType) - m_wDirtyType |= pMap->m_wType; - - break; // found - } - } - - return TRUE; - } - -// methods for complete state set/get - BOOL UISetState(int nID, DWORD dwState) - { - const _AtlUpdateUIMap* pMap = m_pUIMap; - _AtlUpdateUIData* pUIData = m_pUIData; - if(pUIData == NULL) - return FALSE; - for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) - { - if(nID == (int)pMap->m_nID) - { - pUIData->m_wState = (WORD)(dwState | pMap->m_wType); - m_wDirtyType |= pMap->m_wType; - break; // found - } - } - return TRUE; - } - - DWORD UIGetState(int nID) - { - const _AtlUpdateUIMap* pMap = m_pUIMap; - _AtlUpdateUIData* pUIData = m_pUIData; - if(pUIData == NULL) - return 0; - for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) - { - if(nID == (int)pMap->m_nID) - return pUIData->m_wState; - } - return 0; - } - -// methods for updating UI -#ifndef _WIN32_WCE - BOOL UIUpdateMenuBar(BOOL bForceUpdate = FALSE, BOOL bMainMenu = FALSE) - { - if(!(m_wDirtyType & UPDUI_MENUBAR) && !bForceUpdate) - return TRUE; - - const _AtlUpdateUIMap* pMap = m_pUIMap; - _AtlUpdateUIData* pUIData = m_pUIData; - if(pUIData == NULL) - return FALSE; - - while(pMap->m_nID != (WORD)-1) - { - for(int i = 0; i < m_UIElements.GetSize(); i++) - { - if(m_UIElements[i].m_wType == UPDUI_MENUBAR) - { - HMENU hMenu = ::GetMenu(m_UIElements[i].m_hWnd); - if(hMenu != NULL && (pUIData->m_wState & UPDUI_MENUBAR) && (pMap->m_wType & UPDUI_MENUBAR)) - UIUpdateMenuBarElement(pMap->m_nID, pUIData, hMenu); - } - if(bMainMenu) - ::DrawMenuBar(m_UIElements[i].m_hWnd); - } - pMap++; - pUIData->m_wState &= ~UPDUI_MENUBAR; - if(pUIData->m_wState & UPDUI_TEXT) - { - delete [] pUIData->m_lpstrText; - pUIData->m_lpstrText = NULL; - pUIData->m_wState &= ~UPDUI_TEXT; - } - pUIData++; - } - - m_wDirtyType &= ~UPDUI_MENUBAR; - return TRUE; - } -#endif // !_WIN32_WCE - - BOOL UIUpdateToolBar(BOOL bForceUpdate = FALSE) - { - if(!(m_wDirtyType & UPDUI_TOOLBAR) && !bForceUpdate) - return TRUE; - - const _AtlUpdateUIMap* pMap = m_pUIMap; - _AtlUpdateUIData* pUIData = m_pUIData; - if(pUIData == NULL) - return FALSE; - - while(pMap->m_nID != (WORD)-1) - { - for(int i = 0; i < m_UIElements.GetSize(); i++) - { - if(m_UIElements[i].m_wType == UPDUI_TOOLBAR) - { - if((pUIData->m_wState & UPDUI_TOOLBAR) && (pMap->m_wType & UPDUI_TOOLBAR)) - UIUpdateToolBarElement(pMap->m_nID, pUIData, m_UIElements[i].m_hWnd); - } - } - pMap++; - pUIData->m_wState &= ~UPDUI_TOOLBAR; - pUIData++; - } - - m_wDirtyType &= ~UPDUI_TOOLBAR; - return TRUE; - } - - BOOL UIUpdateStatusBar(BOOL bForceUpdate = FALSE) - { - if(!(m_wDirtyType & UPDUI_STATUSBAR) && !bForceUpdate) - return TRUE; - - const _AtlUpdateUIMap* pMap = m_pUIMap; - _AtlUpdateUIData* pUIData = m_pUIData; - if(pUIData == NULL) - return FALSE; - - while(pMap->m_nID != (WORD)-1) - { - for(int i = 0; i < m_UIElements.GetSize(); i++) - { - if(m_UIElements[i].m_wType == UPDUI_STATUSBAR) - { - if((pUIData->m_wState & UPDUI_STATUSBAR) && (pMap->m_wType & UPDUI_STATUSBAR)) - UIUpdateStatusBarElement(pMap->m_nID, pUIData, m_UIElements[i].m_hWnd); - } - } - pMap++; - pUIData->m_wState &= ~UPDUI_STATUSBAR; - if(pUIData->m_wState & UPDUI_TEXT) - { - delete [] pUIData->m_lpstrText; - pUIData->m_lpstrText = NULL; - pUIData->m_wState &= ~UPDUI_TEXT; - } - pUIData++; - } - - m_wDirtyType &= ~UPDUI_STATUSBAR; - return TRUE; - } - - BOOL UIUpdateChildWindows(BOOL bForceUpdate = FALSE) - { - if(!(m_wDirtyType & UPDUI_CHILDWINDOW) && !bForceUpdate) - return TRUE; - - const _AtlUpdateUIMap* pMap = m_pUIMap; - _AtlUpdateUIData* pUIData = m_pUIData; - if(pUIData == NULL) - return FALSE; - - while(pMap->m_nID != (WORD)-1) - { - for(int i = 0; i < m_UIElements.GetSize(); i++) - { - if(m_UIElements[i].m_wType == UPDUI_CHILDWINDOW) - { - if((pUIData->m_wState & UPDUI_CHILDWINDOW) && (pMap->m_wType & UPDUI_CHILDWINDOW)) - UIUpdateChildWindow(pMap->m_nID, pUIData, m_UIElements[i].m_hWnd); - } - } - pMap++; - pUIData->m_wState &= ~UPDUI_CHILDWINDOW; - if(pUIData->m_wState & UPDUI_TEXT) - { - delete [] pUIData->m_lpstrText; - pUIData->m_lpstrText = NULL; - pUIData->m_wState &= ~UPDUI_TEXT; - } - pUIData++; - } - - m_wDirtyType &= ~UPDUI_CHILDWINDOW; - return TRUE; - } - -// internal element specific methods - static void UIUpdateMenuBarElement(int nID, _AtlUpdateUIData* pUIData, HMENU hMenu) - { -#ifndef _WIN32_WCE - if((pUIData->m_wState & UPDUI_CLEARDEFAULT) != 0) - { - ::SetMenuDefaultItem(hMenu, (UINT)-1, 0); - pUIData->m_wState &= ~UPDUI_CLEARDEFAULT; - } -#endif // !_WIN32_WCE - - CMenuItemInfo mii; - mii.fMask = MIIM_STATE; - mii.wID = nID; - -#ifndef _WIN32_WCE - if((pUIData->m_wState & UPDUI_DISABLED) != 0) - mii.fState |= MFS_DISABLED | MFS_GRAYED; - else - mii.fState |= MFS_ENABLED; - - if((pUIData->m_wState & UPDUI_CHECKED) != 0) - mii.fState |= MFS_CHECKED; - else - mii.fState |= MFS_UNCHECKED; - - if((pUIData->m_wState & UPDUI_DEFAULT) != 0) - mii.fState |= MFS_DEFAULT; -#else // CE specific - // ::SetMenuItemInfo() can't disable or check menu items - // on Windows CE, so we have to do that directly - UINT uEnable = MF_BYCOMMAND; - if((pUIData->m_wState & UPDUI_DISABLED) != 0) - uEnable |= MF_GRAYED; - else - uEnable |= MF_ENABLED; - ::EnableMenuItem(hMenu, nID, uEnable); - - UINT uCheck = MF_BYCOMMAND; - if((pUIData->m_wState & UPDUI_CHECKED) != 0) - uCheck |= MF_CHECKED; - else - uCheck |= MF_UNCHECKED; - ::CheckMenuItem(hMenu, nID, uCheck); -#endif // _WIN32_WCE - - if((pUIData->m_wState & UPDUI_TEXT) != 0) - { - CMenuItemInfo miiNow; - miiNow.fMask = MIIM_TYPE; - miiNow.wID = nID; - if(::GetMenuItemInfo(hMenu, nID, FALSE, &miiNow)) - { - mii.fMask |= MIIM_TYPE; - // MFT_BITMAP and MFT_SEPARATOR don't go together with MFT_STRING -#ifndef _WIN32_WCE - mii.fType |= (miiNow.fType & ~(MFT_BITMAP | MFT_SEPARATOR)) | MFT_STRING; -#else // CE specific - mii.fType |= (miiNow.fType & ~(MFT_SEPARATOR)) | MFT_STRING; -#endif // _WIN32_WCE - mii.dwTypeData = pUIData->m_lpstrText; - } - } - - ::SetMenuItemInfo(hMenu, nID, FALSE, &mii); - } - - static void UIUpdateToolBarElement(int nID, _AtlUpdateUIData* pUIData, HWND hWndToolBar) - { - // Note: only handles enabled/disabled, checked state, and radio (press) - ::SendMessage(hWndToolBar, TB_ENABLEBUTTON, nID, (LPARAM)(pUIData->m_wState & UPDUI_DISABLED) ? FALSE : TRUE); - ::SendMessage(hWndToolBar, TB_CHECKBUTTON, nID, (LPARAM)(pUIData->m_wState & UPDUI_CHECKED) ? TRUE : FALSE); - ::SendMessage(hWndToolBar, TB_INDETERMINATE, nID, (LPARAM)(pUIData->m_wState & UPDUI_CHECKED2) ? TRUE : FALSE); - ::SendMessage(hWndToolBar, TB_PRESSBUTTON, nID, (LPARAM)(pUIData->m_wState & UPDUI_RADIO) ? TRUE : FALSE); - } - - static void UIUpdateStatusBarElement(int nID, _AtlUpdateUIData* pUIData, HWND hWndStatusBar) - { - // Note: only handles text - if(pUIData->m_wState & UPDUI_TEXT) - ::SendMessage(hWndStatusBar, SB_SETTEXT, nID, (LPARAM)pUIData->m_lpstrText); - } - - static void UIUpdateChildWindow(int nID, _AtlUpdateUIData* pUIData, HWND hWnd) - { - HWND hChild = ::GetDlgItem(hWnd, nID); - - ::EnableWindow(hChild, (pUIData->m_wState & UPDUI_DISABLED) ? FALSE : TRUE); - // for check and radio, assume that window is a button - int nCheck = BST_UNCHECKED; - if(pUIData->m_wState & UPDUI_CHECKED || pUIData->m_wState & UPDUI_RADIO) - nCheck = BST_CHECKED; - else if(pUIData->m_wState & UPDUI_CHECKED2) - nCheck = BST_INDETERMINATE; - ::SendMessage(hChild, BM_SETCHECK, nCheck, 0L); - if(pUIData->m_wState & UPDUI_DEFAULT) - { - DWORD dwRet = (DWORD)::SendMessage(hWnd, DM_GETDEFID, 0, 0L); - if(HIWORD(dwRet) == DC_HASDEFID) - { - HWND hOldDef = ::GetDlgItem(hWnd, (int)(short)LOWORD(dwRet)); - // remove BS_DEFPUSHBUTTON - ::SendMessage(hOldDef, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0)); - } - ::SendMessage(hWnd, DM_SETDEFID, nID, 0L); - } - if(pUIData->m_wState & UPDUI_TEXT) - ::SetWindowText(hChild, pUIData->m_lpstrText); - } -}; - -template -class CUpdateUI : public CUpdateUIBase -{ -public: - CUpdateUI() - { - T* pT = static_cast(this); - pT; - const _AtlUpdateUIMap* pMap = pT->GetUpdateUIMap(); - m_pUIMap = pMap; - ATLASSERT(m_pUIMap != NULL); - int nCount; - for(nCount = 1; pMap->m_nID != (WORD)-1; nCount++) - pMap++; - - // check for duplicates (debug only) -#ifdef _DEBUG - for(int i = 0; i < nCount; i++) - { - for(int j = 0; j < nCount; j++) - { - // shouldn't have duplicates in the update UI map - if(i != j) - ATLASSERT(m_pUIMap[j].m_nID != m_pUIMap[i].m_nID); - } - } -#endif // _DEBUG - - ATLTRY(m_pUIData = new _AtlUpdateUIData[nCount]); - ATLASSERT(m_pUIData != NULL); - - if(m_pUIData != NULL) - memset(m_pUIData, 0, sizeof(_AtlUpdateUIData) * nCount); - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CDynamicUpdateUI - allows update elements to dynamically added and removed -// in addition to a static update UI map - -template -class CDynamicUpdateUI : public CUpdateUIBase -{ -public: -// Data members - ATL::CSimpleArray<_AtlUpdateUIMap> m_arrUIMap; // copy of the static UI data - ATL::CSimpleArray<_AtlUpdateUIData> m_arrUIData; // instance UI data - -// Constructor/destructor - CDynamicUpdateUI() - { - T* pT = static_cast(this); - pT; - const _AtlUpdateUIMap* pMap = pT->GetUpdateUIMap(); - ATLASSERT(pMap != NULL); - - for(;;) - { - BOOL bRet = m_arrUIMap.Add(*(_AtlUpdateUIMap*)pMap); - ATLASSERT(bRet); - - if(bRet != FALSE) - { - _AtlUpdateUIData data = { 0, NULL }; - bRet = m_arrUIData.Add(data); - ATLASSERT(bRet); - } - - if(pMap->m_nID == (WORD)-1) - break; - - pMap++; - } - - ATLASSERT(m_arrUIMap.GetSize() == m_arrUIData.GetSize()); - -#ifdef _DEBUG - // check for duplicates (debug only) - for(int i = 0; i < m_arrUIMap.GetSize(); i++) - { - for(int j = 0; j < m_arrUIMap.GetSize(); j++) - { - // shouldn't have duplicates in the update UI map - if(i != j) - ATLASSERT(m_arrUIMap[j].m_nID != m_arrUIMap[i].m_nID); - } - } -#endif // _DEBUG - - // Set internal data pointers to point to the new data arrays - m_pUIMap = m_arrUIMap.m_aT; - m_pUIData = m_arrUIData.m_aT; - } - - ~CDynamicUpdateUI() - { - for(int i = 0; i < m_arrUIData.GetSize(); i++) - { - if((m_arrUIData[i].m_wState & UPDUI_TEXT) != 0) - delete [] m_arrUIData[i].m_lpstrText; - } - - // Reset internal data pointers (memory will be released by CSimpleArray d-tor) - m_pUIMap = NULL; - m_pUIData = NULL; - } - -// Methods for dynamically adding and removing update elements - bool UIAddUpdateElement(WORD nID, WORD wType) - { - // check for duplicates - for(int i = 0; i < m_arrUIMap.GetSize(); i++) - { - // shouldn't have duplicates in the update UI map - ATLASSERT(m_arrUIMap[i].m_nID != nID); - if(m_arrUIMap[i].m_nID == nID) - return false; - } - - bool bRetVal = false; - - // Add new end element - _AtlUpdateUIMap uumEnd = { (WORD)-1, 0 }; - BOOL bRet = m_arrUIMap.Add(uumEnd); - ATLASSERT(bRet); - - if(bRet != FALSE) - { - _AtlUpdateUIData uud = { 0, NULL }; - bRet = m_arrUIData.Add(uud); - ATLASSERT(bRet); - - // Set new data to the previous end element - if(bRet != FALSE) - { - int nSize = m_arrUIMap.GetSize(); - _AtlUpdateUIMap uum = { nID, wType }; - m_arrUIMap.SetAtIndex(nSize - 2, uum); - m_arrUIData.SetAtIndex(nSize - 2, uud); - - // Set internal data pointers again, just in case that memory moved - m_pUIMap = m_arrUIMap.m_aT; - m_pUIData = m_arrUIData.m_aT; - - bRetVal = true; - } - } - - return bRetVal; - } - - bool UIRemoveUpdateElement(WORD nID) - { - bool bRetVal = false; - - for(int i = 0; i < m_arrUIMap.GetSize(); i++) - { - if(m_arrUIMap[i].m_nID == nID) - { - BOOL bRet = m_arrUIMap.RemoveAt(i); - ATLASSERT(bRet); - bRet = m_arrUIData.RemoveAt(i); - ATLASSERT(bRet); - - bRetVal = true; - break; - } - } - - return bRetVal; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CAutoUpdateUI : Automatic mapping of UI elements - -template -class CAutoUpdateUI : public CDynamicUpdateUI -{ -public: - LPCTSTR UIGetText(int nID) - { - for(int i = 0; i < m_arrUIMap.GetSize(); i++) - { - if(m_arrUIMap[i].m_nID == nID) - return m_arrUIData[i].m_lpstrText; - } - - return NULL; - } - -// Element - template - bool UIAddElement(UINT nID) - { - // check for existing UI map element - for(int i = 0; i < m_arrUIMap.GetSize(); i++) - { - if(m_arrUIMap[i].m_nID == nID) - { - // set requested type - m_arrUIMap[i].m_wType |= t_wType; - return true; - } - } - - // Add element to UI map with requested type - return UIAddUpdateElement((WORD)nID, t_wType); - } - - template - bool UIRemoveElement(UINT nID) - { - for(int i = 0; i < m_arrUIMap.GetSize(); i++) - { - if(m_arrUIMap[i].m_nID == nID) // matching UI map element - { - WORD wType = m_arrUIMap[i].m_wType & ~t_wType; - if (wType) // has other types - { - m_arrUIMap[i].m_wType = wType; // keep other types - return true; - } - else - { - return UIRemoveUpdateElement((WORD)nID); - } - } - } - - return false; - } - -// Menu - bool UIAddMenu(HMENU hMenu, bool bSetText = false) - { -#if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) - using ATL::GetMenuString; -#endif - ATLASSERT(::IsMenu(hMenu)); - MENUITEMINFO mii = {sizeof(MENUITEMINFO), MIIM_TYPE | MIIM_ID | MIIM_SUBMENU}; - - // Complete the UI map - for (INT uItem = 0; CMenuHandle(hMenu).GetMenuItemInfo(uItem, TRUE, &mii); uItem++) - { - if(mii.hSubMenu) - { - // Add submenu to UI map - UIAddMenu(mii.hSubMenu, bSetText); - } - else if (mii.wID) - { - // Add element to UI map - UIAddElement(mii.wID); -#if !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800) - if (bSetText) - { - TCHAR sText[64] = { 0 }; - if (GetMenuString(hMenu, uItem, sText, 64, MF_BYPOSITION)) - UISetText(mii.wID, sText); - } -#else - bSetText; -#endif // !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800) - } - } - - return true; - } - - bool UIAddMenu(UINT uID, bool bSetText = false) - { - CMenu menu; - ATLVERIFY(menu.LoadMenu(uID)); - return UIAddMenu(menu, bSetText); - } - -// ToolBar -#ifndef BTNS_SEP - #define BTNS_SEP TBSTYLE_SEP -#endif // BTNS_SEP compatibility - -#if !defined(_WIN32_WCE) || (defined(_AUTOUI_CE_TOOLBAR) && defined(TBIF_BYINDEX)) - bool UIAddToolBar(HWND hWndToolBar) - { - ATLASSERT(::IsWindow(hWndToolBar)); - TBBUTTONINFO tbbi = {sizeof TBBUTTONINFO, TBIF_COMMAND | TBIF_STYLE | TBIF_BYINDEX}; - - // Add toolbar buttons - for (int uItem = 0; ::SendMessage(hWndToolBar, TB_GETBUTTONINFO, uItem, (LPARAM)&tbbi) != -1; uItem++) - { - if (tbbi.fsStyle ^ BTNS_SEP) - UIAddElement(tbbi.idCommand); - } - - // Add embedded controls if any - if (::GetWindow(hWndToolBar, GW_CHILD)) - UIAddChildWindowContainer(hWndToolBar); - - return (CUpdateUIBase::UIAddToolBar(hWndToolBar) != FALSE); - } -#endif // !defined(_WIN32_WCE) || (defined(_AUTOUI_CE_TOOLBAR) && defined(TBIF_BYINDEX)) - -// Container - bool UIAddChildWindowContainer(HWND hWnd) - { - ATLASSERT(::IsWindow(hWnd)); - - // Add children controls if any - for (ATL::CWindow wCtl = ::GetWindow(hWnd, GW_CHILD); wCtl.IsWindow(); wCtl = wCtl.GetWindow(GW_HWNDNEXT)) - { - if (int id = wCtl.GetDlgCtrlID()) - UIAddElement(id); - } - - return (CUpdateUIBase::UIAddChildWindowContainer(hWnd) != FALSE); - } - -// StatusBar - BOOL UIUpdateStatusBar(BOOL bForceUpdate = FALSE) - { - if(!(m_wDirtyType & UPDUI_STATUSBAR) && !bForceUpdate) - return TRUE; - - for(int i = 0; i < m_arrUIMap.GetSize(); i++) - { - for(int e = 0; e < m_UIElements.GetSize(); e++) - { - if((m_UIElements[e].m_wType == UPDUI_STATUSBAR) && - (m_arrUIMap[i].m_wType & UPDUI_STATUSBAR) && - (m_arrUIData[i].m_wState & UPDUI_STATUSBAR)) - { - UIUpdateStatusBarElement(m_arrUIMap[i].m_nID, &m_arrUIData[i], m_UIElements[e].m_hWnd); - m_arrUIData[i].m_wState &= ~UPDUI_STATUSBAR; - if(m_arrUIData[i].m_wState & UPDUI_TEXT) - m_arrUIData[i].m_wState &= ~UPDUI_TEXT; - } - } - } - - m_wDirtyType &= ~UPDUI_STATUSBAR; - return TRUE; - } - - bool UIAddStatusBar(HWND hWndStatusBar, INT nPanes = 1) - { - ATLASSERT(::IsWindow(hWndStatusBar)); - - // Add StatusBar panes - for (int iPane = 0; iPane < nPanes; iPane++) - UIAddElement(ID_DEFAULT_PANE + iPane); - - return (CUpdateUIBase::UIAddStatusBar(hWndStatusBar) != FALSE); - } - -// UI Map used if derived class has none - BEGIN_UPDATE_UI_MAP(CAutoUpdateUI) - END_UPDATE_UI_MAP() -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CDialogResize - provides support for resizing dialog controls -// (works for any window that has child controls) - -// Put CDialogResize in the list of base classes for a dialog (or even plain window), -// then implement DLGRESIZE map by specifying controls and groups of control -// and using DLSZ_* values to specify how are they supposed to be resized. -// -// Notes: -// - Resizeable border (WS_THICKFRAME style) should be set in the dialog template -// for top level dialogs (popup or overlapped), so that users can resize the dialog. -// - Some flags cannot be combined; for instance DLSZ_CENTER_X overrides DLSZ_SIZE_X, -// DLSZ_SIZE_X overrides DLSZ_MOVE_X. X and Y flags can be combined. -// - Order of controls is important - group controls are resized and moved based -// on the position of the previous control in a group. - -// dialog resize map macros -#define BEGIN_DLGRESIZE_MAP(thisClass) \ - static const _AtlDlgResizeMap* GetDlgResizeMap() \ - { \ - static const _AtlDlgResizeMap theMap[] = \ - { - -#define END_DLGRESIZE_MAP() \ - { -1, 0 }, \ - }; \ - return theMap; \ - } - -#define DLGRESIZE_CONTROL(id, flags) \ - { id, flags }, - -#define BEGIN_DLGRESIZE_GROUP() \ - { -1, _DLSZ_BEGIN_GROUP }, - -#define END_DLGRESIZE_GROUP() \ - { -1, _DLSZ_END_GROUP }, - - -template -class CDialogResize -{ -public: -// Data declarations and members - enum - { - DLSZ_SIZE_X = 0x00000001, - DLSZ_SIZE_Y = 0x00000002, - DLSZ_MOVE_X = 0x00000004, - DLSZ_MOVE_Y = 0x00000008, - DLSZ_REPAINT = 0x00000010, - DLSZ_CENTER_X = 0x00000020, - DLSZ_CENTER_Y = 0x00000040, - - // internal use only - _DLSZ_BEGIN_GROUP = 0x00001000, - _DLSZ_END_GROUP = 0x00002000, - _DLSZ_GRIPPER = 0x00004000 - }; - - struct _AtlDlgResizeMap - { - int m_nCtlID; - DWORD m_dwResizeFlags; - }; - - struct _AtlDlgResizeData - { - int m_nCtlID; - DWORD m_dwResizeFlags; - RECT m_rect; - - int GetGroupCount() const - { - return (int)LOBYTE(HIWORD(m_dwResizeFlags)); - } - - void SetGroupCount(int nCount) - { - ATLASSERT(nCount > 0 && nCount < 256); - DWORD dwCount = (DWORD)MAKELONG(0, MAKEWORD(nCount, 0)); - m_dwResizeFlags &= 0xFF00FFFF; - m_dwResizeFlags |= dwCount; - } - - bool operator ==(const _AtlDlgResizeData& r) const - { return (m_nCtlID == r.m_nCtlID && m_dwResizeFlags == r.m_dwResizeFlags); } - }; - - ATL::CSimpleArray<_AtlDlgResizeData> m_arrData; - SIZE m_sizeDialog; - POINT m_ptMinTrackSize; - bool m_bGripper; - - -// Constructor - CDialogResize() : m_bGripper(false) - { - m_sizeDialog.cx = 0; - m_sizeDialog.cy = 0; - m_ptMinTrackSize.x = -1; - m_ptMinTrackSize.y = -1; - } - -// Operations - void DlgResize_Init(bool bAddGripper = true, bool bUseMinTrackSize = true, DWORD dwForceStyle = WS_CLIPCHILDREN) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - - DWORD dwStyle = pT->GetStyle(); - -#ifdef _DEBUG - // Debug only: Check if top level dialogs have a resizeable border. - if(((dwStyle & WS_CHILD) == 0) && ((dwStyle & WS_THICKFRAME) == 0)) - ATLTRACE2(atlTraceUI, 0, _T("DlgResize_Init - warning: top level dialog without the WS_THICKFRAME style - user cannot resize it\n")); -#endif // _DEBUG - - // Force specified styles (default WS_CLIPCHILDREN reduces flicker) - if((dwStyle & dwForceStyle) != dwForceStyle) - pT->ModifyStyle(0, dwForceStyle); - - // Adding this style removes an empty icon that dialogs with WS_THICKFRAME have. - // Setting icon to NULL is required when XP themes are active. - // Note: This will not prevent adding an icon for the dialog using SetIcon() - if((dwStyle & WS_CHILD) == 0) - { - pT->ModifyStyleEx(0, WS_EX_DLGMODALFRAME); - if(pT->GetIcon(FALSE) == NULL) - pT->SetIcon(NULL, FALSE); - } - - // Cleanup in case of multiple initialization - // block: first check for the gripper control, destroy it if needed - { - ATL::CWindow wndGripper = pT->GetDlgItem(ATL_IDW_STATUS_BAR); - if(wndGripper.IsWindow() && m_arrData.GetSize() > 0 && (m_arrData[0].m_dwResizeFlags & _DLSZ_GRIPPER) != 0) - wndGripper.DestroyWindow(); - } - // clear out everything else - m_arrData.RemoveAll(); - m_sizeDialog.cx = 0; - m_sizeDialog.cy = 0; - m_ptMinTrackSize.x = -1; - m_ptMinTrackSize.y = -1; - - // Get initial dialog client size - RECT rectDlg = { 0 }; - pT->GetClientRect(&rectDlg); - m_sizeDialog.cx = rectDlg.right; - m_sizeDialog.cy = rectDlg.bottom; - -#ifndef _WIN32_WCE - // Create gripper if requested - m_bGripper = false; - if(bAddGripper) - { - // shouldn't exist already - ATLASSERT(!::IsWindow(pT->GetDlgItem(ATL_IDW_STATUS_BAR))); - if(!::IsWindow(pT->GetDlgItem(ATL_IDW_STATUS_BAR))) - { - ATL::CWindow wndGripper; - wndGripper.Create(_T("SCROLLBAR"), pT->m_hWnd, rectDlg, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SBS_SIZEBOX | SBS_SIZEGRIP | SBS_SIZEBOXBOTTOMRIGHTALIGN, 0, ATL_IDW_STATUS_BAR); - ATLASSERT(wndGripper.IsWindow()); - if(wndGripper.IsWindow()) - { - m_bGripper = true; - RECT rectCtl = { 0 }; - wndGripper.GetWindowRect(&rectCtl); - ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rectCtl, 2); - _AtlDlgResizeData data = { ATL_IDW_STATUS_BAR, DLSZ_MOVE_X | DLSZ_MOVE_Y | DLSZ_REPAINT | _DLSZ_GRIPPER, { rectCtl.left, rectCtl.top, rectCtl.right, rectCtl.bottom } }; - m_arrData.Add(data); - } - } - } -#else // CE specific - bAddGripper; // avoid level 4 warning -#endif // _WIN32_WCE - - // Get min track position if requested - if(bUseMinTrackSize) - { - if((dwStyle & WS_CHILD) != 0) - { - RECT rect = { 0 }; - pT->GetClientRect(&rect); - m_ptMinTrackSize.x = rect.right - rect.left; - m_ptMinTrackSize.y = rect.bottom - rect.top; - } - else - { - RECT rect = { 0 }; - pT->GetWindowRect(&rect); - m_ptMinTrackSize.x = rect.right - rect.left; - m_ptMinTrackSize.y = rect.bottom - rect.top; - } - } - - // Walk the map and initialize data - const _AtlDlgResizeMap* pMap = pT->GetDlgResizeMap(); - ATLASSERT(pMap != NULL); - int nGroupStart = -1; - for(int nCount = 1; !(pMap->m_nCtlID == -1 && pMap->m_dwResizeFlags == 0); nCount++, pMap++) - { - if(pMap->m_nCtlID == -1) - { - switch(pMap->m_dwResizeFlags) - { - case _DLSZ_BEGIN_GROUP: - ATLASSERT(nGroupStart == -1); - nGroupStart = m_arrData.GetSize(); - break; - case _DLSZ_END_GROUP: - { - ATLASSERT(nGroupStart != -1); - int nGroupCount = m_arrData.GetSize() - nGroupStart; - m_arrData[nGroupStart].SetGroupCount(nGroupCount); - nGroupStart = -1; - } - break; - default: - ATLASSERT(FALSE && _T("Invalid DLGRESIZE Map Entry")); - break; - } - } - else - { - // this ID conflicts with the default gripper one - ATLASSERT(m_bGripper ? (pMap->m_nCtlID != ATL_IDW_STATUS_BAR) : TRUE); - - ATL::CWindow ctl = pT->GetDlgItem(pMap->m_nCtlID); - ATLASSERT(ctl.IsWindow()); - RECT rectCtl = { 0 }; - ctl.GetWindowRect(&rectCtl); - ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rectCtl, 2); - - DWORD dwGroupFlag = (nGroupStart != -1 && m_arrData.GetSize() == nGroupStart) ? _DLSZ_BEGIN_GROUP : 0; - _AtlDlgResizeData data = { pMap->m_nCtlID, pMap->m_dwResizeFlags | dwGroupFlag, { rectCtl.left, rectCtl.top, rectCtl.right, rectCtl.bottom } }; - m_arrData.Add(data); - } - } - ATLASSERT((nGroupStart == -1) && _T("No End Group Entry in the DLGRESIZE Map")); - } - - void DlgResize_UpdateLayout(int cxWidth, int cyHeight) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - - // Restrict minimum size if requested - if(((pT->GetStyle() & WS_CHILD) != 0) && m_ptMinTrackSize.x != -1 && m_ptMinTrackSize.y != -1) - { - if(cxWidth < m_ptMinTrackSize.x) - cxWidth = m_ptMinTrackSize.x; - if(cyHeight < m_ptMinTrackSize.y) - cyHeight = m_ptMinTrackSize.y; - } - - BOOL bVisible = pT->IsWindowVisible(); - if(bVisible) - pT->SetRedraw(FALSE); - - for(int i = 0; i < m_arrData.GetSize(); i++) - { - if((m_arrData[i].m_dwResizeFlags & _DLSZ_BEGIN_GROUP) != 0) // start of a group - { - int nGroupCount = m_arrData[i].GetGroupCount(); - ATLASSERT(nGroupCount > 0 && i + nGroupCount - 1 < m_arrData.GetSize()); - RECT rectGroup = m_arrData[i].m_rect; - - int j = 1; - for(j = 1; j < nGroupCount; j++) - { - rectGroup.left = min(rectGroup.left, m_arrData[i + j].m_rect.left); - rectGroup.top = min(rectGroup.top, m_arrData[i + j].m_rect.top); - rectGroup.right = max(rectGroup.right, m_arrData[i + j].m_rect.right); - rectGroup.bottom = max(rectGroup.bottom, m_arrData[i + j].m_rect.bottom); - } - - for(j = 0; j < nGroupCount; j++) - { - _AtlDlgResizeData* pDataPrev = NULL; - if(j > 0) - pDataPrev = &(m_arrData[i + j - 1]); - pT->DlgResize_PositionControl(cxWidth, cyHeight, rectGroup, m_arrData[i + j], true, pDataPrev); - } - - i += nGroupCount - 1; // increment to skip all group controls - } - else // one control entry - { - RECT rectGroup = { 0, 0, 0, 0 }; - pT->DlgResize_PositionControl(cxWidth, cyHeight, rectGroup, m_arrData[i], false); - } - } - - if(bVisible) - pT->SetRedraw(TRUE); - - pT->RedrawWindow(NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); - } - -// Message map and handlers - BEGIN_MSG_MAP(CDialogResize) - MESSAGE_HANDLER(WM_SIZE, OnSize) -#ifndef _WIN32_WCE - MESSAGE_HANDLER(WM_GETMINMAXINFO, OnGetMinMaxInfo) -#endif // _WIN32_WCE - END_MSG_MAP() - - LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); -#ifndef _WIN32_WCE - if(m_bGripper) - { - ATL::CWindow wndGripper = pT->GetDlgItem(ATL_IDW_STATUS_BAR); - if(wParam == SIZE_MAXIMIZED) - wndGripper.ShowWindow(SW_HIDE); - else if(wParam == SIZE_RESTORED) - wndGripper.ShowWindow(SW_SHOW); - } -#endif // _WIN32_WCE - if(wParam != SIZE_MINIMIZED) - { - ATLASSERT(::IsWindow(pT->m_hWnd)); - pT->DlgResize_UpdateLayout(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - } - return 0; - } - -#ifndef _WIN32_WCE - LRESULT OnGetMinMaxInfo(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) - { - if(m_ptMinTrackSize.x != -1 && m_ptMinTrackSize.y != -1) - { - LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam; - lpMMI->ptMinTrackSize = m_ptMinTrackSize; - } - return 0; - } -#endif // _WIN32_WCE - -// Implementation - bool DlgResize_PositionControl(int cxWidth, int cyHeight, RECT& rectGroup, _AtlDlgResizeData& data, bool bGroup, - _AtlDlgResizeData* pDataPrev = NULL) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - ATL::CWindow ctl; - RECT rectCtl = { 0 }; - - ctl = pT->GetDlgItem(data.m_nCtlID); - if(!ctl.GetWindowRect(&rectCtl)) - return false; - ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rectCtl, 2); - - if(bGroup) - { - if((data.m_dwResizeFlags & DLSZ_CENTER_X) != 0) - { - int cxRight = rectGroup.right + cxWidth - m_sizeDialog.cx; - int cxCtl = data.m_rect.right - data.m_rect.left; - rectCtl.left = rectGroup.left + (cxRight - rectGroup.left - cxCtl) / 2; - rectCtl.right = rectCtl.left + cxCtl; - } - else if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_MOVE_X)) != 0) - { - rectCtl.left = rectGroup.left + ::MulDiv(data.m_rect.left - rectGroup.left, rectGroup.right - rectGroup.left + (cxWidth - m_sizeDialog.cx), rectGroup.right - rectGroup.left); - - if((data.m_dwResizeFlags & DLSZ_SIZE_X) != 0) - { - rectCtl.right = rectGroup.left + ::MulDiv(data.m_rect.right - rectGroup.left, rectGroup.right - rectGroup.left + (cxWidth - m_sizeDialog.cx), rectGroup.right - rectGroup.left); - - if(pDataPrev != NULL) - { - ATL::CWindow ctlPrev = pT->GetDlgItem(pDataPrev->m_nCtlID); - RECT rcPrev = { 0 }; - ctlPrev.GetWindowRect(&rcPrev); - ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rcPrev, 2); - int dxAdjust = (rectCtl.left - rcPrev.right) - (data.m_rect.left - pDataPrev->m_rect.right); - rcPrev.right += dxAdjust; - ctlPrev.SetWindowPos(NULL, &rcPrev, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE); - } - } - else - { - rectCtl.right = rectCtl.left + (data.m_rect.right - data.m_rect.left); - } - } - - if((data.m_dwResizeFlags & DLSZ_CENTER_Y) != 0) - { - int cyBottom = rectGroup.bottom + cyHeight - m_sizeDialog.cy; - int cyCtl = data.m_rect.bottom - data.m_rect.top; - rectCtl.top = rectGroup.top + (cyBottom - rectGroup.top - cyCtl) / 2; - rectCtl.bottom = rectCtl.top + cyCtl; - } - else if((data.m_dwResizeFlags & (DLSZ_SIZE_Y | DLSZ_MOVE_Y)) != 0) - { - rectCtl.top = rectGroup.top + ::MulDiv(data.m_rect.top - rectGroup.top, rectGroup.bottom - rectGroup.top + (cyHeight - m_sizeDialog.cy), rectGroup.bottom - rectGroup.top); - - if((data.m_dwResizeFlags & DLSZ_SIZE_Y) != 0) - { - rectCtl.bottom = rectGroup.top + ::MulDiv(data.m_rect.bottom - rectGroup.top, rectGroup.bottom - rectGroup.top + (cyHeight - m_sizeDialog.cy), rectGroup.bottom - rectGroup.top); - - if(pDataPrev != NULL) - { - ATL::CWindow ctlPrev = pT->GetDlgItem(pDataPrev->m_nCtlID); - RECT rcPrev = { 0 }; - ctlPrev.GetWindowRect(&rcPrev); - ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rcPrev, 2); - int dxAdjust = (rectCtl.top - rcPrev.bottom) - (data.m_rect.top - pDataPrev->m_rect.bottom); - rcPrev.bottom += dxAdjust; - ctlPrev.SetWindowPos(NULL, &rcPrev, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE); - } - } - else - { - rectCtl.bottom = rectCtl.top + (data.m_rect.bottom - data.m_rect.top); - } - } - } - else // no group - { - if((data.m_dwResizeFlags & DLSZ_CENTER_X) != 0) - { - int cxCtl = data.m_rect.right - data.m_rect.left; - rectCtl.left = (cxWidth - cxCtl) / 2; - rectCtl.right = rectCtl.left + cxCtl; - } - else if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_MOVE_X)) != 0) - { - rectCtl.right = data.m_rect.right + (cxWidth - m_sizeDialog.cx); - - if((data.m_dwResizeFlags & DLSZ_MOVE_X) != 0) - rectCtl.left = rectCtl.right - (data.m_rect.right - data.m_rect.left); - } - - if((data.m_dwResizeFlags & DLSZ_CENTER_Y) != 0) - { - int cyCtl = data.m_rect.bottom - data.m_rect.top; - rectCtl.top = (cyHeight - cyCtl) / 2; - rectCtl.bottom = rectCtl.top + cyCtl; - } - else if((data.m_dwResizeFlags & (DLSZ_SIZE_Y | DLSZ_MOVE_Y)) != 0) - { - rectCtl.bottom = data.m_rect.bottom + (cyHeight - m_sizeDialog.cy); - - if((data.m_dwResizeFlags & DLSZ_MOVE_Y) != 0) - rectCtl.top = rectCtl.bottom - (data.m_rect.bottom - data.m_rect.top); - } - } - - if((data.m_dwResizeFlags & DLSZ_REPAINT) != 0) - ctl.Invalidate(); - - if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_SIZE_Y | DLSZ_MOVE_X | DLSZ_MOVE_Y | DLSZ_REPAINT | DLSZ_CENTER_X | DLSZ_CENTER_Y)) != 0) - ctl.SetWindowPos(NULL, &rectCtl, SWP_NOZORDER | SWP_NOACTIVATE); - - return true; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CDoubleBufferImpl - Provides double-buffer painting support to any window - -template -class CDoubleBufferImpl -{ -public: -// Overrideables - void DoPaint(CDCHandle /*dc*/) - { - // must be implemented in a derived class - ATLASSERT(FALSE); - } - -// Message map and handlers - BEGIN_MSG_MAP(CDoubleBufferImpl) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) - MESSAGE_HANDLER(WM_PAINT, OnPaint) -#ifndef _WIN32_WCE - MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) -#endif // !_WIN32_WCE - END_MSG_MAP() - - LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - return 1; // no background painting needed - } - - LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - - if(wParam != NULL) - { - RECT rect = { 0 }; - pT->GetClientRect(&rect); - CMemoryDC dcMem((HDC)wParam, rect); - pT->DoPaint(dcMem.m_hDC); - } - else - { - CPaintDC dc(pT->m_hWnd); - CMemoryDC dcMem(dc.m_hDC, dc.m_ps.rcPaint); - pT->DoPaint(dcMem.m_hDC); - } - - return 0; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CDoubleBufferWindowImpl - Implements a double-buffer painting window - -template -class ATL_NO_VTABLE CDoubleBufferWindowImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CDoubleBufferImpl< T > -{ -public: - BEGIN_MSG_MAP(CDoubleBufferWindowImpl) - CHAIN_MSG_MAP(CDoubleBufferImpl< T >) - END_MSG_MAP() -}; - - -// command bar support -#if !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE) - #undef CBRM_GETMENU - #undef CBRM_TRACKPOPUPMENU - #undef CBRM_GETCMDBAR - #undef CBRPOPUPMENU -#endif // !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE) - -}; // namespace WTL - -#endif // __ATLFRAME_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlgdi.h b/!NotAdopted/SmartAutoReplier/wtl/atlgdi.h deleted file mode 100644 index 1e452c4d9b..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlgdi.h +++ /dev/null @@ -1,3891 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLGDI_H__ -#define __ATLGDI_H__ - -#pragma once - -#ifndef __ATLAPP_H__ - #error atlgdi.h requires atlapp.h to be included first -#endif - - -// protect template members from windowsx.h macros -#ifdef _INC_WINDOWSX - #undef CopyRgn - #undef CreateBrush - #undef CreatePen - #undef SelectBrush - #undef SelectPen - #undef SelectFont - #undef SelectBitmap -#endif // _INC_WINDOWSX - -// required libraries -#if !defined(_ATL_NO_MSIMG) && !defined(_WIN32_WCE) - #pragma comment(lib, "msimg32.lib") -#endif // !defined(_ATL_NO_MSIMG) && !defined(_WIN32_WCE) -#if !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE) - #pragma comment(lib, "opengl32.lib") -#endif // !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE) - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CPenT -// CBrushT -// CLogFont -// CFontT -// CBitmapT -// CPaletteT -// CRgnT -// CDCT -// CPaintDC -// CClientDC -// CWindowDC -// CMemoryDC -// CEnhMetaFileInfo -// CEnhMetaFileT -// CEnhMetaFileDC -// -// Global functions: -// AtlGetBitmapResourceInfo() -// AtlGetBitmapResourceBitsPerPixel() -// AtlIsAlphaBitmapResource() -// AtlIsDib16() -// AtlGetDibColorTableSize() -// AtlGetDibNumColors(), -// AtlGetDibBitmap() -// AtlCopyBitmap() -// AtlCreatePackedDib16() -// AtlSetClipboardDib16() -// AtlGetClipboardDib() - - -namespace WTL -{ - -/////////////////////////////////////////////////////////////////////////////// -// Bitmap resource helpers to extract bitmap information for a bitmap resource - -inline LPBITMAPINFOHEADER AtlGetBitmapResourceInfo(HMODULE hModule, ATL::_U_STRINGorID image) -{ - HRSRC hResource = ::FindResource(hModule, image.m_lpstr, RT_BITMAP); - ATLASSERT(hResource != NULL); - HGLOBAL hGlobal = ::LoadResource(hModule, hResource); - ATLASSERT(hGlobal != NULL); - LPBITMAPINFOHEADER pBitmapInfoHeader = (LPBITMAPINFOHEADER)::LockResource(hGlobal); - ATLASSERT(pBitmapInfoHeader != NULL); - return pBitmapInfoHeader; -} - -inline WORD AtlGetBitmapResourceBitsPerPixel(HMODULE hModule, ATL::_U_STRINGorID image) -{ - LPBITMAPINFOHEADER pBitmapInfoHeader = AtlGetBitmapResourceInfo(hModule, image); - ATLASSERT(pBitmapInfoHeader != NULL); - return pBitmapInfoHeader->biBitCount; -} - -inline WORD AtlGetBitmapResourceBitsPerPixel(ATL::_U_STRINGorID image) -{ - return AtlGetBitmapResourceBitsPerPixel(ModuleHelper::GetResourceInstance(), image); -} - -/////////////////////////////////////////////////////////////////////////////// -// 32-bit (alpha channel) bitmap resource helper - -// Note: 32-bit (alpha channel) images work only on Windows XP with Common Controls version 6. -// If you want your app to work on older version of Windows, load non-alpha images if Common -// Controls version is less than 6. - -inline bool AtlIsAlphaBitmapResource(ATL::_U_STRINGorID image) -{ - return (AtlGetBitmapResourceBitsPerPixel(image) == 32); -} - - -/////////////////////////////////////////////////////////////////////////////// -// CPen - -template -class CPenT -{ -public: -// Data members - HPEN m_hPen; - -// Constructor/destructor/operators - CPenT(HPEN hPen = NULL) : m_hPen(hPen) - { } - - ~CPenT() - { - if(t_bManaged && m_hPen != NULL) - DeleteObject(); - } - - CPenT& operator =(HPEN hPen) - { - Attach(hPen); - return *this; - } - - void Attach(HPEN hPen) - { - if(t_bManaged && m_hPen != NULL && m_hPen != hPen) - ::DeleteObject(m_hPen); - m_hPen = hPen; - } - - HPEN Detach() - { - HPEN hPen = m_hPen; - m_hPen = NULL; - return hPen; - } - - operator HPEN() const { return m_hPen; } - - bool IsNull() const { return (m_hPen == NULL); } - -// Create methods - HPEN CreatePen(int nPenStyle, int nWidth, COLORREF crColor) - { - ATLASSERT(m_hPen == NULL); - m_hPen = ::CreatePen(nPenStyle, nWidth, crColor); - return m_hPen; - } - -#ifndef _WIN32_WCE - HPEN CreatePen(int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush, int nStyleCount = 0, const DWORD* lpStyle = NULL) - { - ATLASSERT(m_hPen == NULL); - m_hPen = ::ExtCreatePen(nPenStyle, nWidth, pLogBrush, nStyleCount, lpStyle); - return m_hPen; - } -#endif // !_WIN32_WCE - - HPEN CreatePenIndirect(LPLOGPEN lpLogPen) - { - ATLASSERT(m_hPen == NULL); - m_hPen = ::CreatePenIndirect(lpLogPen); - return m_hPen; - } - - BOOL DeleteObject() - { - ATLASSERT(m_hPen != NULL); - BOOL bRet = ::DeleteObject(m_hPen); - if(bRet) - m_hPen = NULL; - return bRet; - } - -// Attributes - int GetLogPen(LOGPEN* pLogPen) const - { - ATLASSERT(m_hPen != NULL); - return ::GetObject(m_hPen, sizeof(LOGPEN), pLogPen); - } - - bool GetLogPen(LOGPEN& LogPen) const - { - ATLASSERT(m_hPen != NULL); - return (::GetObject(m_hPen, sizeof(LOGPEN), &LogPen) == sizeof(LOGPEN)); - } - -#ifndef _WIN32_WCE - int GetExtLogPen(EXTLOGPEN* pLogPen) const - { - ATLASSERT(m_hPen != NULL); - return ::GetObject(m_hPen, sizeof(EXTLOGPEN), pLogPen); - } - - bool GetExtLogPen(EXTLOGPEN& ExtLogPen) const - { - ATLASSERT(m_hPen != NULL); - return (::GetObject(m_hPen, sizeof(EXTLOGPEN), &ExtLogPen) == sizeof(EXTLOGPEN)); - } -#endif // !_WIN32_WCE -}; - -typedef CPenT CPenHandle; -typedef CPenT CPen; - - -/////////////////////////////////////////////////////////////////////////////// -// CBrush - -template -class CBrushT -{ -public: -// Data members - HBRUSH m_hBrush; - -// Constructor/destructor/operators - CBrushT(HBRUSH hBrush = NULL) : m_hBrush(hBrush) - { } - - ~CBrushT() - { - if(t_bManaged && m_hBrush != NULL) - DeleteObject(); - } - - CBrushT& operator =(HBRUSH hBrush) - { - Attach(hBrush); - return *this; - } - - void Attach(HBRUSH hBrush) - { - if(t_bManaged && m_hBrush != NULL && m_hBrush != hBrush) - ::DeleteObject(m_hBrush); - m_hBrush = hBrush; - } - - HBRUSH Detach() - { - HBRUSH hBrush = m_hBrush; - m_hBrush = NULL; - return hBrush; - } - - operator HBRUSH() const { return m_hBrush; } - - bool IsNull() const { return (m_hBrush == NULL); } - -// Create methods - HBRUSH CreateSolidBrush(COLORREF crColor) - { - ATLASSERT(m_hBrush == NULL); - m_hBrush = ::CreateSolidBrush(crColor); - return m_hBrush; - } - -#ifndef _WIN32_WCE - HBRUSH CreateHatchBrush(int nIndex, COLORREF crColor) - { - ATLASSERT(m_hBrush == NULL); - m_hBrush = ::CreateHatchBrush(nIndex, crColor); - return m_hBrush; - } -#endif // !_WIN32_WCE - -#if !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800) - HBRUSH CreateBrushIndirect(const LOGBRUSH* lpLogBrush) - { - ATLASSERT(m_hBrush == NULL); -#ifndef _WIN32_WCE - m_hBrush = ::CreateBrushIndirect(lpLogBrush); -#else // CE specific - m_hBrush = ATL::CreateBrushIndirect(lpLogBrush); -#endif // _WIN32_WCE - return m_hBrush; - } -#endif // !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800) - - HBRUSH CreatePatternBrush(HBITMAP hBitmap) - { - ATLASSERT(m_hBrush == NULL); - m_hBrush = ::CreatePatternBrush(hBitmap); - return m_hBrush; - } - - HBRUSH CreateDIBPatternBrush(HGLOBAL hPackedDIB, UINT nUsage) - { - ATLASSERT(hPackedDIB != NULL); - const void* lpPackedDIB = GlobalLock(hPackedDIB); - ATLASSERT(lpPackedDIB != NULL); - m_hBrush = ::CreateDIBPatternBrushPt(lpPackedDIB, nUsage); - GlobalUnlock(hPackedDIB); - return m_hBrush; - } - - HBRUSH CreateDIBPatternBrush(const void* lpPackedDIB, UINT nUsage) - { - ATLASSERT(m_hBrush == NULL); - m_hBrush = ::CreateDIBPatternBrushPt(lpPackedDIB, nUsage); - return m_hBrush; - } - - HBRUSH CreateSysColorBrush(int nIndex) - { - ATLASSERT(m_hBrush == NULL); - m_hBrush = ::GetSysColorBrush(nIndex); - return m_hBrush; - } - - BOOL DeleteObject() - { - ATLASSERT(m_hBrush != NULL); - BOOL bRet = ::DeleteObject(m_hBrush); - if(bRet) - m_hBrush = NULL; - return bRet; - } - -// Attributes - int GetLogBrush(LOGBRUSH* pLogBrush) const - { - ATLASSERT(m_hBrush != NULL); - return ::GetObject(m_hBrush, sizeof(LOGBRUSH), pLogBrush); - } - - bool GetLogBrush(LOGBRUSH& LogBrush) const - { - ATLASSERT(m_hBrush != NULL); - return (::GetObject(m_hBrush, sizeof(LOGBRUSH), &LogBrush) == sizeof(LOGBRUSH)); - } -}; - -typedef CBrushT CBrushHandle; -typedef CBrushT CBrush; - - -/////////////////////////////////////////////////////////////////////////////// -// CFont - -class CLogFont : public LOGFONT -{ -public: - CLogFont() - { - memset(this, 0, sizeof(LOGFONT)); - } - - CLogFont(const LOGFONT& lf) - { - Copy(&lf); - } - - CLogFont(HFONT hFont) - { - ATLASSERT(::GetObjectType(hFont) == OBJ_FONT); - ::GetObject(hFont, sizeof(LOGFONT), (LOGFONT*)this); - } - - HFONT CreateFontIndirect() - { - return ::CreateFontIndirect(this); - } - - void SetBold() - { - lfWeight = FW_BOLD; - } - - bool IsBold() const - { - return (lfWeight >= FW_BOLD); - } - - void MakeBolder(int iScale = 1) - { - lfWeight += FW_BOLD * iScale; - } - - void MakeLarger(int iScale) - { - if(lfHeight > 0) - lfHeight += iScale; - else - lfHeight -= iScale; - } - - void SetHeight(LONG nPointSize, HDC hDC = NULL) - { - HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL); - // For MM_TEXT mapping mode - lfHeight = -::MulDiv(nPointSize, ::GetDeviceCaps(hDC1, LOGPIXELSY), 72); - if(hDC == NULL) - ::ReleaseDC(NULL, hDC1); - } - - LONG GetHeight(HDC hDC = NULL) const - { - HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL); - // For MM_TEXT mapping mode - LONG nPointSize = ::MulDiv(-lfHeight, 72, ::GetDeviceCaps(hDC1, LOGPIXELSY)); - if(hDC == NULL) - ::ReleaseDC(NULL, hDC1); - - return nPointSize; - } - - LONG GetDeciPointHeight(HDC hDC = NULL) const - { - HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL); -#ifndef _WIN32_WCE - POINT ptOrg = { 0, 0 }; - ::DPtoLP(hDC1, &ptOrg, 1); - POINT pt = { 0, 0 }; - pt.y = abs(lfHeight) + ptOrg.y; - ::LPtoDP(hDC1, &pt,1); - LONG nDeciPoint = ::MulDiv(pt.y, 720, ::GetDeviceCaps(hDC1, LOGPIXELSY)); // 72 points/inch, 10 decipoints/point -#else // CE specific - // DP and LP are always the same on CE - LONG nDeciPoint = ::MulDiv(abs(lfHeight), 720, ::GetDeviceCaps(hDC1, LOGPIXELSY)); // 72 points/inch, 10 decipoints/point -#endif // _WIN32_WCE - if(hDC == NULL) - ::ReleaseDC(NULL, hDC1); - - return nDeciPoint; - } - - void SetHeightFromDeciPoint(LONG nDeciPtHeight, HDC hDC = NULL) - { - HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL); -#ifndef _WIN32_WCE - POINT pt = { 0, 0 }; - pt.y = ::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), nDeciPtHeight, 720); // 72 points/inch, 10 decipoints/point - ::DPtoLP(hDC1, &pt, 1); - POINT ptOrg = { 0, 0 }; - ::DPtoLP(hDC1, &ptOrg, 1); - lfHeight = -abs(pt.y - ptOrg.y); -#else // CE specific - // DP and LP are always the same on CE - lfHeight = -abs(::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), nDeciPtHeight, 720)); // 72 points/inch, 10 decipoints/point -#endif // _WIN32_WCE - if(hDC == NULL) - ::ReleaseDC(NULL, hDC1); - } - -#ifndef _WIN32_WCE - void SetCaptionFont() - { - NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() }; - ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)); - Copy(&ncm.lfCaptionFont); - } - - void SetMenuFont() - { - NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() }; - ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)); - Copy(&ncm.lfMenuFont); - } - - void SetStatusFont() - { - NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() }; - ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)); - Copy(&ncm.lfStatusFont); - } - - void SetMessageBoxFont() - { - NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() }; - ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)); - Copy(&ncm.lfMessageFont); - } -#endif // !_WIN32_WCE - - void Copy(const LOGFONT* pLogFont) - { - ATLASSERT(pLogFont != NULL); - *(LOGFONT*)this = *pLogFont; - } - - CLogFont& operator =(const CLogFont& src) - { - Copy(&src); - return *this; - } - - CLogFont& operator =(const LOGFONT& src) - { - Copy(&src); - return *this; - } - - CLogFont& operator =(HFONT hFont) - { - ATLASSERT(::GetObjectType(hFont) == OBJ_FONT); - ::GetObject(hFont, sizeof(LOGFONT), (LOGFONT*)this); - return *this; - } - - bool operator ==(const LOGFONT& logfont) const - { - return(logfont.lfHeight == lfHeight && - logfont.lfWidth == lfWidth && - logfont.lfEscapement == lfEscapement && - logfont.lfOrientation == lfOrientation && - logfont.lfWeight == lfWeight && - logfont.lfItalic == lfItalic && - logfont.lfUnderline == lfUnderline && - logfont.lfStrikeOut == lfStrikeOut && - logfont.lfCharSet == lfCharSet && - logfont.lfOutPrecision == lfOutPrecision && - logfont.lfClipPrecision == lfClipPrecision && - logfont.lfQuality == lfQuality && - logfont.lfPitchAndFamily == lfPitchAndFamily && - lstrcmp(logfont.lfFaceName, lfFaceName) == 0); - } -}; - - -template -class CFontT -{ -public: -// Data members - HFONT m_hFont; - -// Constructor/destructor/operators - CFontT(HFONT hFont = NULL) : m_hFont(hFont) - { } - - ~CFontT() - { - if(t_bManaged && m_hFont != NULL) - DeleteObject(); - } - - CFontT& operator =(HFONT hFont) - { - Attach(hFont); - return *this; - } - - void Attach(HFONT hFont) - { - if(t_bManaged && m_hFont != NULL && m_hFont != hFont) - ::DeleteObject(m_hFont); - m_hFont = hFont; - } - - HFONT Detach() - { - HFONT hFont = m_hFont; - m_hFont = NULL; - return hFont; - } - - operator HFONT() const { return m_hFont; } - - bool IsNull() const { return (m_hFont == NULL); } - -// Create methods - HFONT CreateFontIndirect(const LOGFONT* lpLogFont) - { - ATLASSERT(m_hFont == NULL); - m_hFont = ::CreateFontIndirect(lpLogFont); - return m_hFont; - } - -#if !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0500) - HFONT CreateFontIndirectEx(CONST ENUMLOGFONTEXDV* penumlfex) - { - ATLASSERT(m_hFont == NULL); - m_hFont = ::CreateFontIndirectEx(penumlfex); - return m_hFont; - } -#endif // !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0500) - -#if !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800) - HFONT CreateFont(int nHeight, int nWidth, int nEscapement, - int nOrientation, int nWeight, BYTE bItalic, BYTE bUnderline, - BYTE cStrikeOut, BYTE nCharSet, BYTE nOutPrecision, - BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily, - LPCTSTR lpszFacename) - { - ATLASSERT(m_hFont == NULL); -#ifndef _WIN32_WCE - m_hFont = ::CreateFont(nHeight, nWidth, nEscapement, - nOrientation, nWeight, bItalic, bUnderline, cStrikeOut, - nCharSet, nOutPrecision, nClipPrecision, nQuality, - nPitchAndFamily, lpszFacename); -#else // CE specific - m_hFont = ATL::CreateFont(nHeight, nWidth, nEscapement, - nOrientation, nWeight, bItalic, bUnderline, cStrikeOut, - nCharSet, nOutPrecision, nClipPrecision, nQuality, - nPitchAndFamily, lpszFacename); -#endif // _WIN32_WCE - return m_hFont; - } -#endif // !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800) - - HFONT CreatePointFont(int nPointSize, LPCTSTR lpszFaceName, HDC hDC = NULL, bool bBold = false, bool bItalic = false) - { - LOGFONT logFont = { 0 }; - logFont.lfCharSet = DEFAULT_CHARSET; - logFont.lfHeight = nPointSize; - SecureHelper::strncpy_x(logFont.lfFaceName, _countof(logFont.lfFaceName), lpszFaceName, _TRUNCATE); - - if(bBold) - logFont.lfWeight = FW_BOLD; - if(bItalic) - logFont.lfItalic = (BYTE)TRUE; - - return CreatePointFontIndirect(&logFont, hDC); - } - - HFONT CreatePointFontIndirect(const LOGFONT* lpLogFont, HDC hDC = NULL) - { - HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL); - - // convert nPointSize to logical units based on hDC - LOGFONT logFont = *lpLogFont; -#ifndef _WIN32_WCE - POINT pt = { 0, 0 }; - pt.y = ::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), logFont.lfHeight, 720); // 72 points/inch, 10 decipoints/point - ::DPtoLP(hDC1, &pt, 1); - POINT ptOrg = { 0, 0 }; - ::DPtoLP(hDC1, &ptOrg, 1); - logFont.lfHeight = -abs(pt.y - ptOrg.y); -#else // CE specific - // DP and LP are always the same on CE - logFont.lfHeight = -abs(::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), logFont.lfHeight, 720)); // 72 points/inch, 10 decipoints/point -#endif // _WIN32_WCE - - if(hDC == NULL) - ::ReleaseDC(NULL, hDC1); - - return CreateFontIndirect(&logFont); - } - - BOOL DeleteObject() - { - ATLASSERT(m_hFont != NULL); - BOOL bRet = ::DeleteObject(m_hFont); - if(bRet) - m_hFont = NULL; - return bRet; - } - -// Attributes - int GetLogFont(LOGFONT* pLogFont) const - { - ATLASSERT(m_hFont != NULL); - return ::GetObject(m_hFont, sizeof(LOGFONT), pLogFont); - } - - bool GetLogFont(LOGFONT& LogFont) const - { - ATLASSERT(m_hFont != NULL); - return (::GetObject(m_hFont, sizeof(LOGFONT), &LogFont) == sizeof(LOGFONT)); - } -}; - -typedef CFontT CFontHandle; -typedef CFontT CFont; - - -/////////////////////////////////////////////////////////////////////////////// -// CBitmap - -template -class CBitmapT -{ -public: -// Data members - HBITMAP m_hBitmap; - -// Constructor/destructor/operators - CBitmapT(HBITMAP hBitmap = NULL) : m_hBitmap(hBitmap) - { } - - ~CBitmapT() - { - if(t_bManaged && m_hBitmap != NULL) - DeleteObject(); - } - - CBitmapT& operator =(HBITMAP hBitmap) - { - Attach(hBitmap); - return *this; - } - - void Attach(HBITMAP hBitmap) - { - if(t_bManaged && m_hBitmap != NULL&& m_hBitmap != hBitmap) - ::DeleteObject(m_hBitmap); - m_hBitmap = hBitmap; - } - - HBITMAP Detach() - { - HBITMAP hBitmap = m_hBitmap; - m_hBitmap = NULL; - return hBitmap; - } - - operator HBITMAP() const { return m_hBitmap; } - - bool IsNull() const { return (m_hBitmap == NULL); } - -// Create and load methods - HBITMAP LoadBitmap(ATL::_U_STRINGorID bitmap) - { - ATLASSERT(m_hBitmap == NULL); - m_hBitmap = ::LoadBitmap(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr); - return m_hBitmap; - } - - HBITMAP LoadOEMBitmap(UINT nIDBitmap) // for OBM_/OCR_/OIC_ - { - ATLASSERT(m_hBitmap == NULL); - m_hBitmap = ::LoadBitmap(NULL, MAKEINTRESOURCE(nIDBitmap)); - return m_hBitmap; - } - -#ifndef _WIN32_WCE - HBITMAP LoadMappedBitmap(UINT nIDBitmap, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0) - { - ATLASSERT(m_hBitmap == NULL); - m_hBitmap = ::CreateMappedBitmap(ModuleHelper::GetResourceInstance(), nIDBitmap, (WORD)nFlags, lpColorMap, nMapSize); - return m_hBitmap; - } -#endif // !_WIN32_WCE - - HBITMAP CreateBitmap(int nWidth, int nHeight, UINT nPlanes, UINT nBitsPerPixel, const void* lpBits) - { - ATLASSERT(m_hBitmap == NULL); - m_hBitmap = ::CreateBitmap(nWidth, nHeight, nPlanes, nBitsPerPixel, lpBits); - return m_hBitmap; - } - -#ifndef _WIN32_WCE - HBITMAP CreateBitmapIndirect(LPBITMAP lpBitmap) - { - ATLASSERT(m_hBitmap == NULL); - m_hBitmap = ::CreateBitmapIndirect(lpBitmap); - return m_hBitmap; - } -#endif // !_WIN32_WCE - - HBITMAP CreateCompatibleBitmap(HDC hDC, int nWidth, int nHeight) - { - ATLASSERT(m_hBitmap == NULL); - m_hBitmap = ::CreateCompatibleBitmap(hDC, nWidth, nHeight); - return m_hBitmap; - } - -#ifndef _WIN32_WCE - HBITMAP CreateDiscardableBitmap(HDC hDC, int nWidth, int nHeight) - { - ATLASSERT(m_hBitmap == NULL); - m_hBitmap = ::CreateDiscardableBitmap(hDC, nWidth, nHeight); - return m_hBitmap; - } -#endif // !_WIN32_WCE - - BOOL DeleteObject() - { - ATLASSERT(m_hBitmap != NULL); - BOOL bRet = ::DeleteObject(m_hBitmap); - if(bRet) - m_hBitmap = NULL; - return bRet; - } - -// Attributes - int GetBitmap(BITMAP* pBitMap) const - { - ATLASSERT(m_hBitmap != NULL); - return ::GetObject(m_hBitmap, sizeof(BITMAP), pBitMap); - } - - bool GetBitmap(BITMAP& bm) const - { - ATLASSERT(m_hBitmap != NULL); - return (::GetObject(m_hBitmap, sizeof(BITMAP), &bm) == sizeof(BITMAP)); - } - - bool GetSize(SIZE& size) const - { - ATLASSERT(m_hBitmap != NULL); - BITMAP bm = { 0 }; - if(!GetBitmap(&bm)) - return false; - size.cx = bm.bmWidth; - size.cy = bm.bmHeight; - return true; - } - -#ifndef _WIN32_WCE - DWORD GetBitmapBits(DWORD dwCount, LPVOID lpBits) const - { - ATLASSERT(m_hBitmap != NULL); - return ::GetBitmapBits(m_hBitmap, dwCount, lpBits); - } -#endif // !_WIN32_WCE - -#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 410) - DWORD SetBitmapBits(DWORD dwCount, const void* lpBits) - { - ATLASSERT(m_hBitmap != NULL); - return ::SetBitmapBits(m_hBitmap, dwCount, lpBits); - } -#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 410) - -#ifndef _WIN32_WCE - BOOL GetBitmapDimension(LPSIZE lpSize) const - { - ATLASSERT(m_hBitmap != NULL); - return ::GetBitmapDimensionEx(m_hBitmap, lpSize); - } - - BOOL SetBitmapDimension(int nWidth, int nHeight, LPSIZE lpSize = NULL) - { - ATLASSERT(m_hBitmap != NULL); - return ::SetBitmapDimensionEx(m_hBitmap, nWidth, nHeight, lpSize); - } - -// DIB support - HBITMAP CreateDIBitmap(HDC hDC, CONST BITMAPINFOHEADER* lpbmih, DWORD dwInit, CONST VOID* lpbInit, CONST BITMAPINFO* lpbmi, UINT uColorUse) - { - ATLASSERT(m_hBitmap == NULL); - m_hBitmap = ::CreateDIBitmap(hDC, lpbmih, dwInit, lpbInit, lpbmi, uColorUse); - return m_hBitmap; - } -#endif // !_WIN32_WCE - - HBITMAP CreateDIBSection(HDC hDC, CONST BITMAPINFO* lpbmi, UINT uColorUse, VOID** ppvBits, HANDLE hSection, DWORD dwOffset) - { - ATLASSERT(m_hBitmap == NULL); - m_hBitmap = ::CreateDIBSection(hDC, lpbmi, uColorUse, ppvBits, hSection, dwOffset); - return m_hBitmap; - } - -#ifndef _WIN32_WCE - int GetDIBits(HDC hDC, UINT uStartScan, UINT cScanLines, LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT uColorUse) const - { - ATLASSERT(m_hBitmap != NULL); - return ::GetDIBits(hDC, m_hBitmap, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse); - } - - int SetDIBits(HDC hDC, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse) - { - ATLASSERT(m_hBitmap != NULL); - return ::SetDIBits(hDC, m_hBitmap, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse); - } -#endif // !_WIN32_WCE -}; - -typedef CBitmapT CBitmapHandle; -typedef CBitmapT CBitmap; - - -/////////////////////////////////////////////////////////////////////////////// -// CPalette - -template -class CPaletteT -{ -public: -// Data members - HPALETTE m_hPalette; - -// Constructor/destructor/operators - CPaletteT(HPALETTE hPalette = NULL) : m_hPalette(hPalette) - { } - - ~CPaletteT() - { - if(t_bManaged && m_hPalette != NULL) - DeleteObject(); - } - - CPaletteT& operator =(HPALETTE hPalette) - { - Attach(hPalette); - return *this; - } - - void Attach(HPALETTE hPalette) - { - if(t_bManaged && m_hPalette != NULL && m_hPalette != hPalette) - ::DeleteObject(m_hPalette); - m_hPalette = hPalette; - } - - HPALETTE Detach() - { - HPALETTE hPalette = m_hPalette; - m_hPalette = NULL; - return hPalette; - } - - operator HPALETTE() const { return m_hPalette; } - - bool IsNull() const { return (m_hPalette == NULL); } - -// Create methods - HPALETTE CreatePalette(LPLOGPALETTE lpLogPalette) - { - ATLASSERT(m_hPalette == NULL); - m_hPalette = ::CreatePalette(lpLogPalette); - return m_hPalette; - } - -#ifndef _WIN32_WCE - HPALETTE CreateHalftonePalette(HDC hDC) - { - ATLASSERT(m_hPalette == NULL); - ATLASSERT(hDC != NULL); - m_hPalette = ::CreateHalftonePalette(hDC); - return m_hPalette; - } -#endif // !_WIN32_WCE - - BOOL DeleteObject() - { - ATLASSERT(m_hPalette != NULL); - BOOL bRet = ::DeleteObject(m_hPalette); - if(bRet) - m_hPalette = NULL; - return bRet; - } - -// Attributes - int GetEntryCount() const - { - ATLASSERT(m_hPalette != NULL); - WORD nEntries = 0; - ::GetObject(m_hPalette, sizeof(WORD), &nEntries); - return (int)nEntries; - } - - UINT GetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors) const - { - ATLASSERT(m_hPalette != NULL); - return ::GetPaletteEntries(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors); - } - - UINT SetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors) - { - ATLASSERT(m_hPalette != NULL); - return ::SetPaletteEntries(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors); - } - -// Operations -#ifndef _WIN32_WCE - void AnimatePalette(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors) - { - ATLASSERT(m_hPalette != NULL); - ::AnimatePalette(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors); - } - - BOOL ResizePalette(UINT nNumEntries) - { - ATLASSERT(m_hPalette != NULL); - return ::ResizePalette(m_hPalette, nNumEntries); - } -#endif // !_WIN32_WCE - - UINT GetNearestPaletteIndex(COLORREF crColor) const - { - ATLASSERT(m_hPalette != NULL); - return ::GetNearestPaletteIndex(m_hPalette, crColor); - } -}; - -typedef CPaletteT CPaletteHandle; -typedef CPaletteT CPalette; - - -/////////////////////////////////////////////////////////////////////////////// -// CRgn - -template -class CRgnT -{ -public: -// Data members - HRGN m_hRgn; - -// Constructor/destructor/operators - CRgnT(HRGN hRgn = NULL) : m_hRgn(hRgn) - { } - - ~CRgnT() - { - if(t_bManaged && m_hRgn != NULL) - DeleteObject(); - } - - CRgnT& operator =(HRGN hRgn) - { - Attach(hRgn); - return *this; - } - - void Attach(HRGN hRgn) - { - if(t_bManaged && m_hRgn != NULL && m_hRgn != hRgn) - ::DeleteObject(m_hRgn); - m_hRgn = hRgn; - } - - HRGN Detach() - { - HRGN hRgn = m_hRgn; - m_hRgn = NULL; - return hRgn; - } - - operator HRGN() const { return m_hRgn; } - - bool IsNull() const { return (m_hRgn == NULL); } - -// Create methods - HRGN CreateRectRgn(int x1, int y1, int x2, int y2) - { - ATLASSERT(m_hRgn == NULL); - m_hRgn = ::CreateRectRgn(x1, y1, x2, y2); - return m_hRgn; - } - - HRGN CreateRectRgnIndirect(LPCRECT lpRect) - { - ATLASSERT(m_hRgn == NULL); - m_hRgn = ::CreateRectRgnIndirect(lpRect); - return m_hRgn; - } - -#ifndef _WIN32_WCE - HRGN CreateEllipticRgn(int x1, int y1, int x2, int y2) - { - ATLASSERT(m_hRgn == NULL); - m_hRgn = ::CreateEllipticRgn(x1, y1, x2, y2); - return m_hRgn; - } - - HRGN CreateEllipticRgnIndirect(LPCRECT lpRect) - { - ATLASSERT(m_hRgn == NULL); - m_hRgn = ::CreateEllipticRgnIndirect(lpRect); - return m_hRgn; - } - - HRGN CreatePolygonRgn(LPPOINT lpPoints, int nCount, int nMode) - { - ATLASSERT(m_hRgn == NULL); - m_hRgn = ::CreatePolygonRgn(lpPoints, nCount, nMode); - return m_hRgn; - } - - HRGN CreatePolyPolygonRgn(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount, int nPolyFillMode) - { - ATLASSERT(m_hRgn == NULL); - m_hRgn = ::CreatePolyPolygonRgn(lpPoints, lpPolyCounts, nCount, nPolyFillMode); - return m_hRgn; - } - - HRGN CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3) - { - ATLASSERT(m_hRgn == NULL); - m_hRgn = ::CreateRoundRectRgn(x1, y1, x2, y2, x3, y3); - return m_hRgn; - } - - HRGN CreateFromPath(HDC hDC) - { - ATLASSERT(m_hRgn == NULL); - ATLASSERT(hDC != NULL); - m_hRgn = ::PathToRegion(hDC); - return m_hRgn; - } - - HRGN CreateFromData(const XFORM* lpXForm, int nCount, const RGNDATA* pRgnData) - { - ATLASSERT(m_hRgn == NULL); - m_hRgn = ::ExtCreateRegion(lpXForm, nCount, pRgnData); - return m_hRgn; - } -#endif // !_WIN32_WCE - - BOOL DeleteObject() - { - ATLASSERT(m_hRgn != NULL); - BOOL bRet = ::DeleteObject(m_hRgn); - if(bRet) - m_hRgn = NULL; - return bRet; - } - -// Operations - void SetRectRgn(int x1, int y1, int x2, int y2) - { - ATLASSERT(m_hRgn != NULL); - ::SetRectRgn(m_hRgn, x1, y1, x2, y2); - } - - void SetRectRgn(LPCRECT lpRect) - { - ATLASSERT(m_hRgn != NULL); - ::SetRectRgn(m_hRgn, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - } - - int CombineRgn(HRGN hRgnSrc1, HRGN hRgnSrc2, int nCombineMode) - { - ATLASSERT(m_hRgn != NULL); - return ::CombineRgn(m_hRgn, hRgnSrc1, hRgnSrc2, nCombineMode); - } - - int CombineRgn(HRGN hRgnSrc, int nCombineMode) - { - ATLASSERT(m_hRgn != NULL); - return ::CombineRgn(m_hRgn, m_hRgn, hRgnSrc, nCombineMode); - } - - int CopyRgn(HRGN hRgnSrc) - { - ATLASSERT(m_hRgn != NULL); - return ::CombineRgn(m_hRgn, hRgnSrc, NULL, RGN_COPY); - } - - BOOL EqualRgn(HRGN hRgn) const - { - ATLASSERT(m_hRgn != NULL); - return ::EqualRgn(m_hRgn, hRgn); - } - - int OffsetRgn(int x, int y) - { - ATLASSERT(m_hRgn != NULL); - return ::OffsetRgn(m_hRgn, x, y); - } - - int OffsetRgn(POINT point) - { - ATLASSERT(m_hRgn != NULL); - return ::OffsetRgn(m_hRgn, point.x, point.y); - } - - int GetRgnBox(LPRECT lpRect) const - { - ATLASSERT(m_hRgn != NULL); - return ::GetRgnBox(m_hRgn, lpRect); - } - - BOOL PtInRegion(int x, int y) const - { - ATLASSERT(m_hRgn != NULL); - return ::PtInRegion(m_hRgn, x, y); - } - - BOOL PtInRegion(POINT point) const - { - ATLASSERT(m_hRgn != NULL); - return ::PtInRegion(m_hRgn, point.x, point.y); - } - - BOOL RectInRegion(LPCRECT lpRect) const - { - ATLASSERT(m_hRgn != NULL); - return ::RectInRegion(m_hRgn, lpRect); - } - - int GetRegionData(LPRGNDATA lpRgnData, int nDataSize) const - { - ATLASSERT(m_hRgn != NULL); - return (int)::GetRegionData(m_hRgn, nDataSize, lpRgnData); - } -}; - -typedef CRgnT CRgnHandle; -typedef CRgnT CRgn; - - -/////////////////////////////////////////////////////////////////////////////// -// CDC - The device context class - -template -class CDCT -{ -public: -// Data members - HDC m_hDC; - -// Constructor/destructor/operators - CDCT(HDC hDC = NULL) : m_hDC(hDC) - { - } - - ~CDCT() - { - if(t_bManaged && m_hDC != NULL) - ::DeleteDC(Detach()); - } - - CDCT& operator =(HDC hDC) - { - Attach(hDC); - return *this; - } - - void Attach(HDC hDC) - { - if(t_bManaged && m_hDC != NULL && m_hDC != hDC) - ::DeleteDC(m_hDC); - m_hDC = hDC; - } - - HDC Detach() - { - HDC hDC = m_hDC; - m_hDC = NULL; - return hDC; - } - - operator HDC() const { return m_hDC; } - - bool IsNull() const { return (m_hDC == NULL); } - -// Operations -#ifndef _WIN32_WCE - HWND WindowFromDC() const - { - ATLASSERT(m_hDC != NULL); - return ::WindowFromDC(m_hDC); - } -#endif // !_WIN32_WCE - - CPenHandle GetCurrentPen() const - { - ATLASSERT(m_hDC != NULL); - return CPenHandle((HPEN)::GetCurrentObject(m_hDC, OBJ_PEN)); - } - - CBrushHandle GetCurrentBrush() const - { - ATLASSERT(m_hDC != NULL); - return CBrushHandle((HBRUSH)::GetCurrentObject(m_hDC, OBJ_BRUSH)); - } - - CPaletteHandle GetCurrentPalette() const - { - ATLASSERT(m_hDC != NULL); - return CPaletteHandle((HPALETTE)::GetCurrentObject(m_hDC, OBJ_PAL)); - } - - CFontHandle GetCurrentFont() const - { - ATLASSERT(m_hDC != NULL); - return CFontHandle((HFONT)::GetCurrentObject(m_hDC, OBJ_FONT)); - } - - CBitmapHandle GetCurrentBitmap() const - { - ATLASSERT(m_hDC != NULL); - return CBitmapHandle((HBITMAP)::GetCurrentObject(m_hDC, OBJ_BITMAP)); - } - - HDC CreateDC(LPCTSTR lpszDriverName, LPCTSTR lpszDeviceName, LPCTSTR lpszOutput, const DEVMODE* lpInitData) - { - ATLASSERT(m_hDC == NULL); - m_hDC = ::CreateDC(lpszDriverName, lpszDeviceName, lpszOutput, lpInitData); - return m_hDC; - } - - HDC CreateCompatibleDC(HDC hDC = NULL) - { - ATLASSERT(m_hDC == NULL); - m_hDC = ::CreateCompatibleDC(hDC); - return m_hDC; - } - - BOOL DeleteDC() - { - if(m_hDC == NULL) - return FALSE; - BOOL bRet = ::DeleteDC(m_hDC); - if(bRet) - m_hDC = NULL; - return bRet; - } - -// Device-Context Functions - int SaveDC() - { - ATLASSERT(m_hDC != NULL); - return ::SaveDC(m_hDC); - } - - BOOL RestoreDC(int nSavedDC) - { - ATLASSERT(m_hDC != NULL); - return ::RestoreDC(m_hDC, nSavedDC); - } - - int GetDeviceCaps(int nIndex) const - { - ATLASSERT(m_hDC != NULL); - return ::GetDeviceCaps(m_hDC, nIndex); - } - -#ifndef _WIN32_WCE - UINT SetBoundsRect(LPCRECT lpRectBounds, UINT flags) - { - ATLASSERT(m_hDC != NULL); - return ::SetBoundsRect(m_hDC, lpRectBounds, flags); - } - - UINT GetBoundsRect(LPRECT lpRectBounds, UINT flags) const - { - ATLASSERT(m_hDC != NULL); - return ::GetBoundsRect(m_hDC, lpRectBounds, flags); - } - - BOOL ResetDC(const DEVMODE* lpDevMode) - { - ATLASSERT(m_hDC != NULL); - return ::ResetDC(m_hDC, lpDevMode) != NULL; - } - -// Drawing-Tool Functions - BOOL GetBrushOrg(LPPOINT lpPoint) const - { - ATLASSERT(m_hDC != NULL); - return ::GetBrushOrgEx(m_hDC, lpPoint); - } -#endif // !_WIN32_WCE - - BOOL SetBrushOrg(int x, int y, LPPOINT lpPoint = NULL) - { - ATLASSERT(m_hDC != NULL); - return ::SetBrushOrgEx(m_hDC, x, y, lpPoint); - } - - BOOL SetBrushOrg(POINT point, LPPOINT lpPointRet = NULL) - { - ATLASSERT(m_hDC != NULL); - return ::SetBrushOrgEx(m_hDC, point.x, point.y, lpPointRet); - } - -#ifndef _WIN32_WCE - int EnumObjects(int nObjectType, int (CALLBACK* lpfn)(LPVOID, LPARAM), LPARAM lpData) - { - ATLASSERT(m_hDC != NULL); -#ifdef STRICT - return ::EnumObjects(m_hDC, nObjectType, (GOBJENUMPROC)lpfn, lpData); -#else - return ::EnumObjects(m_hDC, nObjectType, (GOBJENUMPROC)lpfn, (LPVOID)lpData); -#endif - } -#endif // !_WIN32_WCE - -// Type-safe selection helpers - HPEN SelectPen(HPEN hPen) - { - ATLASSERT(m_hDC != NULL); -#ifndef _WIN32_WCE - ATLASSERT(hPen == NULL || ::GetObjectType(hPen) == OBJ_PEN || ::GetObjectType(hPen) == OBJ_EXTPEN); -#else // CE specific - ATLASSERT(hPen == NULL || ::GetObjectType(hPen) == OBJ_PEN); -#endif // _WIN32_WCE - return (HPEN)::SelectObject(m_hDC, hPen); - } - - HBRUSH SelectBrush(HBRUSH hBrush) - { - ATLASSERT(m_hDC != NULL); - ATLASSERT(hBrush == NULL || ::GetObjectType(hBrush) == OBJ_BRUSH); - return (HBRUSH)::SelectObject(m_hDC, hBrush); - } - - HFONT SelectFont(HFONT hFont) - { - ATLASSERT(m_hDC != NULL); - ATLASSERT(hFont == NULL || ::GetObjectType(hFont) == OBJ_FONT); - return (HFONT)::SelectObject(m_hDC, hFont); - } - - HBITMAP SelectBitmap(HBITMAP hBitmap) - { - ATLASSERT(m_hDC != NULL); - ATLASSERT(hBitmap == NULL || ::GetObjectType(hBitmap) == OBJ_BITMAP); - return (HBITMAP)::SelectObject(m_hDC, hBitmap); - } - - int SelectRgn(HRGN hRgn) // special return for regions - { - ATLASSERT(m_hDC != NULL); - ATLASSERT(hRgn == NULL || ::GetObjectType(hRgn) == OBJ_REGION); - return PtrToInt(::SelectObject(m_hDC, hRgn)); - } - -// Type-safe selection helpers for stock objects - HPEN SelectStockPen(int nPen) - { - ATLASSERT(m_hDC != NULL); -#if (_WIN32_WINNT >= 0x0500) - ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN || nPen == DC_PEN); -#else - ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN); -#endif // !(_WIN32_WINNT >= 0x0500) - return SelectPen((HPEN)::GetStockObject(nPen)); - } - - HBRUSH SelectStockBrush(int nBrush) - { -#if (_WIN32_WINNT >= 0x0500) - ATLASSERT((nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH) || nBrush == DC_BRUSH); -#else - ATLASSERT(nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH); -#endif // !(_WIN32_WINNT >= 0x0500) - return SelectBrush((HBRUSH)::GetStockObject(nBrush)); - } - - HFONT SelectStockFont(int nFont) - { -#ifndef _WIN32_WCE - ATLASSERT((nFont >= OEM_FIXED_FONT && nFont <= SYSTEM_FIXED_FONT) || nFont == DEFAULT_GUI_FONT); -#else // CE specific - ATLASSERT(nFont == SYSTEM_FONT); -#endif // _WIN32_WCE - return SelectFont((HFONT)::GetStockObject(nFont)); - } - - HPALETTE SelectStockPalette(int nPalette, BOOL bForceBackground) - { - ATLASSERT(nPalette == DEFAULT_PALETTE); // the only one supported - return SelectPalette((HPALETTE)::GetStockObject(nPalette), bForceBackground); - } - -// Color and Color Palette Functions - COLORREF GetNearestColor(COLORREF crColor) const - { - ATLASSERT(m_hDC != NULL); - return ::GetNearestColor(m_hDC, crColor); - } - - HPALETTE SelectPalette(HPALETTE hPalette, BOOL bForceBackground) - { - ATLASSERT(m_hDC != NULL); - - return ::SelectPalette(m_hDC, hPalette, bForceBackground); - } - - UINT RealizePalette() - { - ATLASSERT(m_hDC != NULL); - return ::RealizePalette(m_hDC); - } - -#ifndef _WIN32_WCE - void UpdateColors() - { - ATLASSERT(m_hDC != NULL); - ::UpdateColors(m_hDC); - } -#endif // !_WIN32_WCE - -// Drawing-Attribute Functions - COLORREF GetBkColor() const - { - ATLASSERT(m_hDC != NULL); - return ::GetBkColor(m_hDC); - } - - int GetBkMode() const - { - ATLASSERT(m_hDC != NULL); - return ::GetBkMode(m_hDC); - } - -#ifndef _WIN32_WCE - int GetPolyFillMode() const - { - ATLASSERT(m_hDC != NULL); - return ::GetPolyFillMode(m_hDC); - } - - int GetROP2() const - { - ATLASSERT(m_hDC != NULL); - return ::GetROP2(m_hDC); - } - - int GetStretchBltMode() const - { - ATLASSERT(m_hDC != NULL); - return ::GetStretchBltMode(m_hDC); - } -#endif // !_WIN32_WCE - - COLORREF GetTextColor() const - { - ATLASSERT(m_hDC != NULL); - return ::GetTextColor(m_hDC); - } - - COLORREF SetBkColor(COLORREF crColor) - { - ATLASSERT(m_hDC != NULL); - return ::SetBkColor(m_hDC, crColor); - } - - int SetBkMode(int nBkMode) - { - ATLASSERT(m_hDC != NULL); - return ::SetBkMode(m_hDC, nBkMode); - } - -#ifndef _WIN32_WCE - int SetPolyFillMode(int nPolyFillMode) - { - ATLASSERT(m_hDC != NULL); - return ::SetPolyFillMode(m_hDC, nPolyFillMode); - } -#endif // !_WIN32_WCE - - int SetROP2(int nDrawMode) - { - ATLASSERT(m_hDC != NULL); - return ::SetROP2(m_hDC, nDrawMode); - } - -#ifndef _WIN32_WCE - int SetStretchBltMode(int nStretchMode) - { - ATLASSERT(m_hDC != NULL); - return ::SetStretchBltMode(m_hDC, nStretchMode); - } -#endif // !_WIN32_WCE - - COLORREF SetTextColor(COLORREF crColor) - { - ATLASSERT(m_hDC != NULL); - return ::SetTextColor(m_hDC, crColor); - } - -#ifndef _WIN32_WCE - BOOL GetColorAdjustment(LPCOLORADJUSTMENT lpColorAdjust) const - { - ATLASSERT(m_hDC != NULL); - return ::GetColorAdjustment(m_hDC, lpColorAdjust); - } - - BOOL SetColorAdjustment(const COLORADJUSTMENT* lpColorAdjust) - { - ATLASSERT(m_hDC != NULL); - return ::SetColorAdjustment(m_hDC, lpColorAdjust); - } - -// Mapping Functions - int GetMapMode() const - { - ATLASSERT(m_hDC != NULL); - return ::GetMapMode(m_hDC); - } - - BOOL GetViewportOrg(LPPOINT lpPoint) const - { - ATLASSERT(m_hDC != NULL); - return ::GetViewportOrgEx(m_hDC, lpPoint); - } - - int SetMapMode(int nMapMode) - { - ATLASSERT(m_hDC != NULL); - return ::SetMapMode(m_hDC, nMapMode); - } -#endif // !_WIN32_WCE - - // Viewport Origin - BOOL SetViewportOrg(int x, int y, LPPOINT lpPoint = NULL) - { - ATLASSERT(m_hDC != NULL); - return ::SetViewportOrgEx(m_hDC, x, y, lpPoint); - } - - BOOL SetViewportOrg(POINT point, LPPOINT lpPointRet = NULL) - { - ATLASSERT(m_hDC != NULL); - return SetViewportOrg(point.x, point.y, lpPointRet); - } - -#ifndef _WIN32_WCE - BOOL OffsetViewportOrg(int nWidth, int nHeight, LPPOINT lpPoint = NULL) - { - ATLASSERT(m_hDC != NULL); - return ::OffsetViewportOrgEx(m_hDC, nWidth, nHeight, lpPoint); - } - - // Viewport Extent - BOOL GetViewportExt(LPSIZE lpSize) const - { - ATLASSERT(m_hDC != NULL); - return ::GetViewportExtEx(m_hDC, lpSize); - } - - BOOL SetViewportExt(int x, int y, LPSIZE lpSize = NULL) - { - ATLASSERT(m_hDC != NULL); - return ::SetViewportExtEx(m_hDC, x, y, lpSize); - } - - BOOL SetViewportExt(SIZE size, LPSIZE lpSizeRet = NULL) - { - ATLASSERT(m_hDC != NULL); - return SetViewportExt(size.cx, size.cy, lpSizeRet); - } - - BOOL ScaleViewportExt(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize = NULL) - { - ATLASSERT(m_hDC != NULL); - return ::ScaleViewportExtEx(m_hDC, xNum, xDenom, yNum, yDenom, lpSize); - } -#endif // !_WIN32_WCE - - // Window Origin -#ifndef _WIN32_WCE - BOOL GetWindowOrg(LPPOINT lpPoint) const - { - ATLASSERT(m_hDC != NULL); - return ::GetWindowOrgEx(m_hDC, lpPoint); - } - - BOOL SetWindowOrg(int x, int y, LPPOINT lpPoint = NULL) - { - ATLASSERT(m_hDC != NULL); - return ::SetWindowOrgEx(m_hDC, x, y, lpPoint); - } - - BOOL SetWindowOrg(POINT point, LPPOINT lpPointRet = NULL) - { - ATLASSERT(m_hDC != NULL); - return SetWindowOrg(point.x, point.y, lpPointRet); - } - - BOOL OffsetWindowOrg(int nWidth, int nHeight, LPPOINT lpPoint = NULL) - { - ATLASSERT(m_hDC != NULL); - return ::OffsetWindowOrgEx(m_hDC, nWidth, nHeight, lpPoint); - } - - // Window extent - BOOL GetWindowExt(LPSIZE lpSize) const - { - ATLASSERT(m_hDC != NULL); - return ::GetWindowExtEx(m_hDC, lpSize); - } - - BOOL SetWindowExt(int x, int y, LPSIZE lpSize = NULL) - { - ATLASSERT(m_hDC != NULL); - return ::SetWindowExtEx(m_hDC, x, y, lpSize); - } - - BOOL SetWindowExt(SIZE size, LPSIZE lpSizeRet = NULL) - { - ATLASSERT(m_hDC != NULL); - return SetWindowExt(size.cx, size.cy, lpSizeRet); - } - - BOOL ScaleWindowExt(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize = NULL) - { - ATLASSERT(m_hDC != NULL); - return ::ScaleWindowExtEx(m_hDC, xNum, xDenom, yNum, yDenom, lpSize); - } - -// Coordinate Functions - BOOL DPtoLP(LPPOINT lpPoints, int nCount = 1) const - { - ATLASSERT(m_hDC != NULL); - return ::DPtoLP(m_hDC, lpPoints, nCount); - } - - BOOL DPtoLP(LPRECT lpRect) const - { - ATLASSERT(m_hDC != NULL); - return ::DPtoLP(m_hDC, (LPPOINT)lpRect, 2); - } - - BOOL DPtoLP(LPSIZE lpSize) const - { - SIZE sizeWinExt = { 0, 0 }; - if(!GetWindowExt(&sizeWinExt)) - return FALSE; - SIZE sizeVpExt = { 0, 0 }; - if(!GetViewportExt(&sizeVpExt)) - return FALSE; - lpSize->cx = ::MulDiv(lpSize->cx, abs(sizeWinExt.cx), abs(sizeVpExt.cx)); - lpSize->cy = ::MulDiv(lpSize->cy, abs(sizeWinExt.cy), abs(sizeVpExt.cy)); - return TRUE; - } - - BOOL LPtoDP(LPPOINT lpPoints, int nCount = 1) const - { - ATLASSERT(m_hDC != NULL); - return ::LPtoDP(m_hDC, lpPoints, nCount); - } - - BOOL LPtoDP(LPRECT lpRect) const - { - ATLASSERT(m_hDC != NULL); - return ::LPtoDP(m_hDC, (LPPOINT)lpRect, 2); - } - - BOOL LPtoDP(LPSIZE lpSize) const - { - SIZE sizeWinExt = { 0, 0 }; - if(!GetWindowExt(&sizeWinExt)) - return FALSE; - SIZE sizeVpExt = { 0, 0 }; - if(!GetViewportExt(&sizeVpExt)) - return FALSE; - lpSize->cx = ::MulDiv(lpSize->cx, abs(sizeVpExt.cx), abs(sizeWinExt.cx)); - lpSize->cy = ::MulDiv(lpSize->cy, abs(sizeVpExt.cy), abs(sizeWinExt.cy)); - return TRUE; - } - -// Special Coordinate Functions (useful for dealing with metafiles and OLE) - #define HIMETRIC_INCH 2540 // HIMETRIC units per inch - - void DPtoHIMETRIC(LPSIZE lpSize) const - { - ATLASSERT(m_hDC != NULL); - int nMapMode; - if((nMapMode = GetMapMode()) < MM_ISOTROPIC && nMapMode != MM_TEXT) - { - // when using a constrained map mode, map against physical inch - ((CDCHandle*)this)->SetMapMode(MM_HIMETRIC); - DPtoLP(lpSize); - ((CDCHandle*)this)->SetMapMode(nMapMode); - } - else - { - // map against logical inch for non-constrained mapping modes - int cxPerInch = GetDeviceCaps(LOGPIXELSX); - int cyPerInch = GetDeviceCaps(LOGPIXELSY); - ATLASSERT(cxPerInch != 0 && cyPerInch != 0); - lpSize->cx = ::MulDiv(lpSize->cx, HIMETRIC_INCH, cxPerInch); - lpSize->cy = ::MulDiv(lpSize->cy, HIMETRIC_INCH, cyPerInch); - } - } - - void HIMETRICtoDP(LPSIZE lpSize) const - { - ATLASSERT(m_hDC != NULL); - int nMapMode; - if((nMapMode = GetMapMode()) < MM_ISOTROPIC && nMapMode != MM_TEXT) - { - // when using a constrained map mode, map against physical inch - ((CDCHandle*)this)->SetMapMode(MM_HIMETRIC); - LPtoDP(lpSize); - ((CDCHandle*)this)->SetMapMode(nMapMode); - } - else - { - // map against logical inch for non-constrained mapping modes - int cxPerInch = GetDeviceCaps(LOGPIXELSX); - int cyPerInch = GetDeviceCaps(LOGPIXELSY); - ATLASSERT(cxPerInch != 0 && cyPerInch != 0); - lpSize->cx = ::MulDiv(lpSize->cx, cxPerInch, HIMETRIC_INCH); - lpSize->cy = ::MulDiv(lpSize->cy, cyPerInch, HIMETRIC_INCH); - } - } - - void LPtoHIMETRIC(LPSIZE lpSize) const - { - LPtoDP(lpSize); - DPtoHIMETRIC(lpSize); - } - - void HIMETRICtoLP(LPSIZE lpSize) const - { - HIMETRICtoDP(lpSize); - DPtoLP(lpSize); - } -#endif // !_WIN32_WCE - -// Region Functions - BOOL FillRgn(HRGN hRgn, HBRUSH hBrush) - { - ATLASSERT(m_hDC != NULL); - return ::FillRgn(m_hDC, hRgn, hBrush); - } - -#ifndef _WIN32_WCE - BOOL FrameRgn(HRGN hRgn, HBRUSH hBrush, int nWidth, int nHeight) - { - ATLASSERT(m_hDC != NULL); - return ::FrameRgn(m_hDC, hRgn, hBrush, nWidth, nHeight); - } - - BOOL InvertRgn(HRGN hRgn) - { - ATLASSERT(m_hDC != NULL); - return ::InvertRgn(m_hDC, hRgn); - } - - BOOL PaintRgn(HRGN hRgn) - { - ATLASSERT(m_hDC != NULL); - return ::PaintRgn(m_hDC, hRgn); - } -#endif // !_WIN32_WCE - -// Clipping Functions - int GetClipBox(LPRECT lpRect) const - { - ATLASSERT(m_hDC != NULL); - return ::GetClipBox(m_hDC, lpRect); - } - - int GetClipRgn(CRgn& region) const - { - ATLASSERT(m_hDC != NULL); - if(region.IsNull()) - region.CreateRectRgn(0, 0, 0, 0); - - int nRet = ::GetClipRgn(m_hDC, region); - if(nRet != 1) - region.DeleteObject(); - - return nRet; - } - -#ifndef _WIN32_WCE - BOOL PtVisible(int x, int y) const - { - ATLASSERT(m_hDC != NULL); - return ::PtVisible(m_hDC, x, y); - } - - BOOL PtVisible(POINT point) const - { - ATLASSERT(m_hDC != NULL); - return ::PtVisible(m_hDC, point.x, point.y); - } -#endif // !_WIN32_WCE - - BOOL RectVisible(LPCRECT lpRect) const - { - ATLASSERT(m_hDC != NULL); - return ::RectVisible(m_hDC, lpRect); - } - - int SelectClipRgn(HRGN hRgn) - { - ATLASSERT(m_hDC != NULL); - return ::SelectClipRgn(m_hDC, (HRGN)hRgn); - } - - int ExcludeClipRect(int x1, int y1, int x2, int y2) - { - ATLASSERT(m_hDC != NULL); - return ::ExcludeClipRect(m_hDC, x1, y1, x2, y2); - } - - int ExcludeClipRect(LPCRECT lpRect) - { - ATLASSERT(m_hDC != NULL); - return ::ExcludeClipRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - } - -#ifndef _WIN32_WCE - int ExcludeUpdateRgn(HWND hWnd) - { - ATLASSERT(m_hDC != NULL); - return ::ExcludeUpdateRgn(m_hDC, hWnd); - } -#endif // !_WIN32_WCE - - int IntersectClipRect(int x1, int y1, int x2, int y2) - { - ATLASSERT(m_hDC != NULL); - return ::IntersectClipRect(m_hDC, x1, y1, x2, y2); - } - - int IntersectClipRect(LPCRECT lpRect) - { - ATLASSERT(m_hDC != NULL); - return ::IntersectClipRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - } - -#ifndef _WIN32_WCE - int OffsetClipRgn(int x, int y) - { - ATLASSERT(m_hDC != NULL); - return ::OffsetClipRgn(m_hDC, x, y); - } - - int OffsetClipRgn(SIZE size) - { - ATLASSERT(m_hDC != NULL); - return ::OffsetClipRgn(m_hDC, size.cx, size.cy); - } - - int SelectClipRgn(HRGN hRgn, int nMode) - { - ATLASSERT(m_hDC != NULL); - return ::ExtSelectClipRgn(m_hDC, hRgn, nMode); - } -#endif // !_WIN32_WCE - -// Line-Output Functions -#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) - BOOL GetCurrentPosition(LPPOINT lpPoint) const - { - ATLASSERT(m_hDC != NULL); - return ::GetCurrentPositionEx(m_hDC, lpPoint); - } - - BOOL MoveTo(int x, int y, LPPOINT lpPoint = NULL) - { - ATLASSERT(m_hDC != NULL); - return ::MoveToEx(m_hDC, x, y, lpPoint); - } - - BOOL MoveTo(POINT point, LPPOINT lpPointRet = NULL) - { - ATLASSERT(m_hDC != NULL); - return MoveTo(point.x, point.y, lpPointRet); - } - - BOOL LineTo(int x, int y) - { - ATLASSERT(m_hDC != NULL); - return ::LineTo(m_hDC, x, y); - } - - BOOL LineTo(POINT point) - { - ATLASSERT(m_hDC != NULL); - return LineTo(point.x, point.y); - } -#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) - -#ifndef _WIN32_WCE - BOOL Arc(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) - { - ATLASSERT(m_hDC != NULL); - return ::Arc(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4); - } - - BOOL Arc(LPCRECT lpRect, POINT ptStart, POINT ptEnd) - { - ATLASSERT(m_hDC != NULL); - return ::Arc(m_hDC, lpRect->left, lpRect->top, - lpRect->right, lpRect->bottom, ptStart.x, ptStart.y, - ptEnd.x, ptEnd.y); - } -#endif // !_WIN32_WCE - - BOOL Polyline(LPPOINT lpPoints, int nCount) - { - ATLASSERT(m_hDC != NULL); - return ::Polyline(m_hDC, lpPoints, nCount); - } - -#ifndef _WIN32_WCE - BOOL AngleArc(int x, int y, int nRadius, float fStartAngle, float fSweepAngle) - { - ATLASSERT(m_hDC != NULL); - return ::AngleArc(m_hDC, x, y, nRadius, fStartAngle, fSweepAngle); - } - - BOOL ArcTo(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) - { - ATLASSERT(m_hDC != NULL); - return ::ArcTo(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4); - } - - BOOL ArcTo(LPCRECT lpRect, POINT ptStart, POINT ptEnd) - { - ATLASSERT(m_hDC != NULL); - return ArcTo(lpRect->left, lpRect->top, lpRect->right, - lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y); - } - - int GetArcDirection() const - { - ATLASSERT(m_hDC != NULL); - return ::GetArcDirection(m_hDC); - } - - int SetArcDirection(int nArcDirection) - { - ATLASSERT(m_hDC != NULL); - return ::SetArcDirection(m_hDC, nArcDirection); - } - - BOOL PolyDraw(const POINT* lpPoints, const BYTE* lpTypes, int nCount) - { - ATLASSERT(m_hDC != NULL); - return ::PolyDraw(m_hDC, lpPoints, lpTypes, nCount); - } - - BOOL PolylineTo(const POINT* lpPoints, int nCount) - { - ATLASSERT(m_hDC != NULL); - return ::PolylineTo(m_hDC, lpPoints, nCount); - } - - BOOL PolyPolyline(const POINT* lpPoints, - const DWORD* lpPolyPoints, int nCount) - { - ATLASSERT(m_hDC != NULL); - return ::PolyPolyline(m_hDC, lpPoints, lpPolyPoints, nCount); - } - - BOOL PolyBezier(const POINT* lpPoints, int nCount) - { - ATLASSERT(m_hDC != NULL); - return ::PolyBezier(m_hDC, lpPoints, nCount); - } - - BOOL PolyBezierTo(const POINT* lpPoints, int nCount) - { - ATLASSERT(m_hDC != NULL); - return ::PolyBezierTo(m_hDC, lpPoints, nCount); - } -#endif // !_WIN32_WCE - -// Simple Drawing Functions - BOOL FillRect(LPCRECT lpRect, HBRUSH hBrush) - { - ATLASSERT(m_hDC != NULL); - return ::FillRect(m_hDC, lpRect, hBrush); - } - - BOOL FillRect(LPCRECT lpRect, int nColorIndex) - { - ATLASSERT(m_hDC != NULL); -#ifndef _WIN32_WCE - return ::FillRect(m_hDC, lpRect, (HBRUSH)LongToPtr(nColorIndex + 1)); -#else // CE specific - return ::FillRect(m_hDC, lpRect, ::GetSysColorBrush(nColorIndex)); -#endif // _WIN32_WCE - } - -#ifndef _WIN32_WCE - BOOL FrameRect(LPCRECT lpRect, HBRUSH hBrush) - { - ATLASSERT(m_hDC != NULL); - return ::FrameRect(m_hDC, lpRect, hBrush); - } -#endif // !_WIN32_WCE - -#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 420) - BOOL InvertRect(LPCRECT lpRect) - { - ATLASSERT(m_hDC != NULL); - return ::InvertRect(m_hDC, lpRect); - } -#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 420) - - BOOL DrawIcon(int x, int y, HICON hIcon) - { - ATLASSERT(m_hDC != NULL); -#ifndef _WIN32_WCE - return ::DrawIcon(m_hDC, x, y, hIcon); -#else // CE specific - return ::DrawIconEx(m_hDC, x, y, hIcon, 0, 0, 0, NULL, DI_NORMAL); -#endif // _WIN32_WCE - } - - BOOL DrawIcon(POINT point, HICON hIcon) - { - ATLASSERT(m_hDC != NULL); -#ifndef _WIN32_WCE - return ::DrawIcon(m_hDC, point.x, point.y, hIcon); -#else // CE specific - return ::DrawIconEx(m_hDC, point.x, point.y, hIcon, 0, 0, 0, NULL, DI_NORMAL); -#endif // _WIN32_WCE - } - - BOOL DrawIconEx(int x, int y, HICON hIcon, int cxWidth, int cyWidth, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL) - { - ATLASSERT(m_hDC != NULL); - return ::DrawIconEx(m_hDC, x, y, hIcon, cxWidth, cyWidth, uStepIfAniCur, hbrFlickerFreeDraw, uFlags); - } - - BOOL DrawIconEx(POINT point, HICON hIcon, SIZE size, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL) - { - ATLASSERT(m_hDC != NULL); - return ::DrawIconEx(m_hDC, point.x, point.y, hIcon, size.cx, size.cy, uStepIfAniCur, hbrFlickerFreeDraw, uFlags); - } - -#ifndef _WIN32_WCE - BOOL DrawState(POINT pt, SIZE size, HBITMAP hBitmap, UINT nFlags, HBRUSH hBrush = NULL) - { - ATLASSERT(m_hDC != NULL); - return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)hBitmap, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_BITMAP); - } - - BOOL DrawState(POINT pt, SIZE size, HICON hIcon, UINT nFlags, HBRUSH hBrush = NULL) - { - ATLASSERT(m_hDC != NULL); - return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)hIcon, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_ICON); - } - - BOOL DrawState(POINT pt, SIZE size, LPCTSTR lpszText, UINT nFlags, BOOL bPrefixText = TRUE, int nTextLen = 0, HBRUSH hBrush = NULL) - { - ATLASSERT(m_hDC != NULL); - return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)lpszText, (WPARAM)nTextLen, pt.x, pt.y, size.cx, size.cy, nFlags | (bPrefixText ? DST_PREFIXTEXT : DST_TEXT)); - } - - BOOL DrawState(POINT pt, SIZE size, DRAWSTATEPROC lpDrawProc, LPARAM lData, UINT nFlags, HBRUSH hBrush = NULL) - { - ATLASSERT(m_hDC != NULL); - return ::DrawState(m_hDC, hBrush, lpDrawProc, lData, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_COMPLEX); - } -#endif // !_WIN32_WCE - -// Ellipse and Polygon Functions -#ifndef _WIN32_WCE - BOOL Chord(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) - { - ATLASSERT(m_hDC != NULL); - return ::Chord(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4); - } - - BOOL Chord(LPCRECT lpRect, POINT ptStart, POINT ptEnd) - { - ATLASSERT(m_hDC != NULL); - return ::Chord(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y); - } -#endif // !_WIN32_WCE - - void DrawFocusRect(LPCRECT lpRect) - { - ATLASSERT(m_hDC != NULL); - ::DrawFocusRect(m_hDC, lpRect); - } - - BOOL Ellipse(int x1, int y1, int x2, int y2) - { - ATLASSERT(m_hDC != NULL); - return ::Ellipse(m_hDC, x1, y1, x2, y2); - } - - BOOL Ellipse(LPCRECT lpRect) - { - ATLASSERT(m_hDC != NULL); - return ::Ellipse(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - } - -#ifndef _WIN32_WCE - BOOL Pie(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) - { - ATLASSERT(m_hDC != NULL); - return ::Pie(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4); - } - - BOOL Pie(LPCRECT lpRect, POINT ptStart, POINT ptEnd) - { - ATLASSERT(m_hDC != NULL); - return ::Pie(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y); - } -#endif // !_WIN32_WCE - - BOOL Polygon(LPPOINT lpPoints, int nCount) - { - ATLASSERT(m_hDC != NULL); - return ::Polygon(m_hDC, lpPoints, nCount); - } - -#ifndef _WIN32_WCE - BOOL PolyPolygon(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount) - { - ATLASSERT(m_hDC != NULL); - return ::PolyPolygon(m_hDC, lpPoints, lpPolyCounts, nCount); - } -#endif // !_WIN32_WCE - - BOOL Rectangle(int x1, int y1, int x2, int y2) - { - ATLASSERT(m_hDC != NULL); - return ::Rectangle(m_hDC, x1, y1, x2, y2); - } - - BOOL Rectangle(LPCRECT lpRect) - { - ATLASSERT(m_hDC != NULL); - return ::Rectangle(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); - } - - BOOL RoundRect(int x1, int y1, int x2, int y2, int x3, int y3) - { - ATLASSERT(m_hDC != NULL); - return ::RoundRect(m_hDC, x1, y1, x2, y2, x3, y3); - } - - BOOL RoundRect(LPCRECT lpRect, POINT point) - { - ATLASSERT(m_hDC != NULL); - return ::RoundRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, point.x, point.y); - } - -// Bitmap Functions - BOOL PatBlt(int x, int y, int nWidth, int nHeight, DWORD dwRop) - { - ATLASSERT(m_hDC != NULL); - return ::PatBlt(m_hDC, x, y, nWidth, nHeight, dwRop); - } - - BOOL BitBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, - int xSrc, int ySrc, DWORD dwRop) - { - ATLASSERT(m_hDC != NULL); - return ::BitBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, dwRop); - } - - BOOL StretchBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop) - { - ATLASSERT(m_hDC != NULL); - return ::StretchBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, dwRop); - } - - COLORREF GetPixel(int x, int y) const - { - ATLASSERT(m_hDC != NULL); - return ::GetPixel(m_hDC, x, y); - } - - COLORREF GetPixel(POINT point) const - { - ATLASSERT(m_hDC != NULL); - return ::GetPixel(m_hDC, point.x, point.y); - } - - COLORREF SetPixel(int x, int y, COLORREF crColor) - { - ATLASSERT(m_hDC != NULL); - return ::SetPixel(m_hDC, x, y, crColor); - } - - COLORREF SetPixel(POINT point, COLORREF crColor) - { - ATLASSERT(m_hDC != NULL); - return ::SetPixel(m_hDC, point.x, point.y, crColor); - } - -#ifndef _WIN32_WCE - BOOL FloodFill(int x, int y, COLORREF crColor) - { - ATLASSERT(m_hDC != NULL); - return ::FloodFill(m_hDC, x, y, crColor); - } - - BOOL ExtFloodFill(int x, int y, COLORREF crColor, UINT nFillType) - { - ATLASSERT(m_hDC != NULL); - return ::ExtFloodFill(m_hDC, x, y, crColor, nFillType); - } -#endif // !_WIN32_WCE - - BOOL MaskBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, HBITMAP hMaskBitmap, int xMask, int yMask, DWORD dwRop) - { - ATLASSERT(m_hDC != NULL); - return ::MaskBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, hMaskBitmap, xMask, yMask, dwRop); - } - -#ifndef _WIN32_WCE - BOOL PlgBlt(LPPOINT lpPoint, HDC hSrcDC, int xSrc, int ySrc, int nWidth, int nHeight, HBITMAP hMaskBitmap, int xMask, int yMask) - { - ATLASSERT(m_hDC != NULL); - return ::PlgBlt(m_hDC, lpPoint, hSrcDC, xSrc, ySrc, nWidth, nHeight, hMaskBitmap, xMask, yMask); - } - - BOOL SetPixelV(int x, int y, COLORREF crColor) - { - ATLASSERT(m_hDC != NULL); - return ::SetPixelV(m_hDC, x, y, crColor); - } - - BOOL SetPixelV(POINT point, COLORREF crColor) - { - ATLASSERT(m_hDC != NULL); - return ::SetPixelV(m_hDC, point.x, point.y, crColor); - } -#endif // !_WIN32_WCE - -#if !defined(_ATL_NO_MSIMG) || defined(_WIN32_WCE) -#ifndef _WIN32_WCE - BOOL TransparentBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, UINT crTransparent) - { - ATLASSERT(m_hDC != NULL); - return ::TransparentBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, crTransparent); - } -#else // CE specific - BOOL TransparentImage(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, UINT crTransparent) - { - ATLASSERT(m_hDC != NULL); - return ::TransparentImage(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, crTransparent); - } -#endif // _WIN32_WCE - -#if (!defined(_WIN32_WCE) || (_WIN32_WCE >= 420)) - BOOL GradientFill(const PTRIVERTEX pVertices, DWORD nVertices, void* pMeshElements, DWORD nMeshElements, DWORD dwMode) - { - ATLASSERT(m_hDC != NULL); - return ::GradientFill(m_hDC, pVertices, nVertices, pMeshElements, nMeshElements, dwMode); - } - - BOOL GradientFillRect(RECT& rect, COLORREF clr1, COLORREF clr2, bool bHorizontal) - { - ATLASSERT(m_hDC != NULL); - - TRIVERTEX arrTvx[2] = { { 0 }, { 0 } }; - - arrTvx[0].x = rect.left; - arrTvx[0].y = rect.top; - arrTvx[0].Red = MAKEWORD(0, GetRValue(clr1)); - arrTvx[0].Green = MAKEWORD(0, GetGValue(clr1)); - arrTvx[0].Blue = MAKEWORD(0, GetBValue(clr1)); - arrTvx[0].Alpha = 0; - - arrTvx[1].x = rect.right; - arrTvx[1].y = rect.bottom; - arrTvx[1].Red = MAKEWORD(0, GetRValue(clr2)); - arrTvx[1].Green = MAKEWORD(0, GetGValue(clr2)); - arrTvx[1].Blue = MAKEWORD(0, GetBValue(clr2)); - arrTvx[1].Alpha = 0; - - GRADIENT_RECT gr = { 0, 1 }; - - return ::GradientFill(m_hDC, arrTvx, 2, &gr, 1, bHorizontal ? GRADIENT_FILL_RECT_H : GRADIENT_FILL_RECT_V); - } -#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 420) - -#if !defined(_WIN32_WCE) || (_WIN32_WCE > 0x500) - BOOL AlphaBlend(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, BLENDFUNCTION bf) - { - ATLASSERT(m_hDC != NULL); - return ::AlphaBlend(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, bf); - } -#endif // !defined(_WIN32_WCE) || (_WIN32_WCE > 0x500) -#endif // !defined(_ATL_NO_MSIMG) || defined(_WIN32_WCE) - -// Extra bitmap functions - // Helper function for painting a disabled toolbar or menu bitmap - // This function can take either an HBITMAP (for SS) or a DC with - // the bitmap already painted (for cmdbar) - BOOL DitherBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, HBITMAP hBitmap, int xSrc, int ySrc, - HBRUSH hBrushBackground = ::GetSysColorBrush(COLOR_3DFACE), - HBRUSH hBrush3DEffect = ::GetSysColorBrush(COLOR_3DHILIGHT), - HBRUSH hBrushDisabledImage = ::GetSysColorBrush(COLOR_3DSHADOW)) - { - ATLASSERT(m_hDC != NULL || hBitmap != NULL); - ATLASSERT(nWidth > 0 && nHeight > 0); - - // Create a generic DC for all BitBlts - CDCHandle dc = (hSrcDC != NULL) ? hSrcDC : ::CreateCompatibleDC(m_hDC); - ATLASSERT(dc.m_hDC != NULL); - if(dc.m_hDC == NULL) - return FALSE; - - // Create a DC for the monochrome DIB section - CDC dcBW = ::CreateCompatibleDC(m_hDC); - ATLASSERT(dcBW.m_hDC != NULL); - if(dcBW.m_hDC == NULL) - { - if(hSrcDC == NULL) - dc.DeleteDC(); - return FALSE; - } - - // Create the monochrome DIB section with a black and white palette - struct RGBBWBITMAPINFO - { - BITMAPINFOHEADER bmiHeader; - RGBQUAD bmiColors[2]; - }; - - RGBBWBITMAPINFO rgbBWBitmapInfo = - { - { sizeof(BITMAPINFOHEADER), nWidth, nHeight, 1, 1, BI_RGB, 0, 0, 0, 0, 0 }, - { { 0x00, 0x00, 0x00, 0x00 }, { 0xFF, 0xFF, 0xFF, 0x00 } } - }; - - VOID* pbitsBW; - CBitmap bmpBW = ::CreateDIBSection(dcBW, (LPBITMAPINFO)&rgbBWBitmapInfo, DIB_RGB_COLORS, &pbitsBW, NULL, 0); - ATLASSERT(bmpBW.m_hBitmap != NULL); - if(bmpBW.m_hBitmap == NULL) - { - if(hSrcDC == NULL) - dc.DeleteDC(); - return FALSE; - } - - // Attach the monochrome DIB section and the bitmap to the DCs - HBITMAP hbmOldBW = dcBW.SelectBitmap(bmpBW); - HBITMAP hbmOldDC = NULL; - if(hBitmap != NULL) - hbmOldDC = dc.SelectBitmap(hBitmap); - - // Block: Dark gray removal: we want (128, 128, 128) pixels to become black and not white - { - CDC dcTemp1 = ::CreateCompatibleDC(m_hDC); - CDC dcTemp2 = ::CreateCompatibleDC(m_hDC); - CBitmap bmpTemp1; - bmpTemp1.CreateCompatibleBitmap(dc, nWidth, nHeight); - CBitmap bmpTemp2; - bmpTemp2.CreateBitmap(nWidth, nHeight, 1, 1, NULL); - HBITMAP hOldBmp1 = dcTemp1.SelectBitmap(bmpTemp1); - HBITMAP hOldBmp2 = dcTemp2.SelectBitmap(bmpTemp2); - // Let's copy our image, it will be altered - dcTemp1.BitBlt(0, 0, nWidth, nHeight, dc, xSrc, ySrc, SRCCOPY); - - // All dark gray pixels will become white, the others black - dcTemp1.SetBkColor(RGB(128, 128, 128)); - dcTemp2.BitBlt(0, 0, nWidth, nHeight, dcTemp1, 0, 0, SRCCOPY); - // Do an XOR to set to black these white pixels - dcTemp1.BitBlt(0, 0, nWidth, nHeight, dcTemp2, 0, 0, SRCINVERT); - - // BitBlt the bitmap into the monochrome DIB section - // The DIB section will do a true monochrome conversion - // The magenta background being closer to white will become white - dcBW.BitBlt(0, 0, nWidth, nHeight, dcTemp1, 0, 0, SRCCOPY); - - // Cleanup - dcTemp1.SelectBitmap(hOldBmp1); - dcTemp2.SelectBitmap(hOldBmp2); - } - - // Paint the destination rectangle using hBrushBackground - if(hBrushBackground != NULL) - { - RECT rc = { x, y, x + nWidth, y + nHeight }; - FillRect(&rc, hBrushBackground); - } - - // BitBlt the black bits in the monochrome bitmap into hBrush3DEffect color in the destination DC - // The magic ROP comes from the Charles Petzold's book - HBRUSH hOldBrush = SelectBrush(hBrush3DEffect); - BitBlt(x + 1, y + 1, nWidth, nHeight, dcBW, 0, 0, 0xB8074A); - - // BitBlt the black bits in the monochrome bitmap into hBrushDisabledImage color in the destination DC - SelectBrush(hBrushDisabledImage); - BitBlt(x, y, nWidth, nHeight, dcBW, 0, 0, 0xB8074A); - - SelectBrush(hOldBrush); - dcBW.SelectBitmap(hbmOldBW); - dc.SelectBitmap(hbmOldDC); - - if(hSrcDC == NULL) - dc.DeleteDC(); - - return TRUE; - } - -// Text Functions -#ifndef _WIN32_WCE - BOOL TextOut(int x, int y, LPCTSTR lpszString, int nCount = -1) - { - ATLASSERT(m_hDC != NULL); - if(nCount == -1) - nCount = lstrlen(lpszString); - return ::TextOut(m_hDC, x, y, lpszString, nCount); - } -#endif // !_WIN32_WCE - - BOOL ExtTextOut(int x, int y, UINT nOptions, LPCRECT lpRect, LPCTSTR lpszString, UINT nCount = -1, LPINT lpDxWidths = NULL) - { - ATLASSERT(m_hDC != NULL); - if(nCount == -1) - nCount = lstrlen(lpszString); - return ::ExtTextOut(m_hDC, x, y, nOptions, lpRect, lpszString, nCount, lpDxWidths); - } - -#ifndef _WIN32_WCE - SIZE TabbedTextOut(int x, int y, LPCTSTR lpszString, int nCount = -1, int nTabPositions = 0, LPINT lpnTabStopPositions = NULL, int nTabOrigin = 0) - { - ATLASSERT(m_hDC != NULL); - if(nCount == -1) - nCount = lstrlen(lpszString); - LONG lRes = ::TabbedTextOut(m_hDC, x, y, lpszString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin); - SIZE size = { GET_X_LPARAM(lRes), GET_Y_LPARAM(lRes) }; - return size; - } -#endif // !_WIN32_WCE - - int DrawText(LPCTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat) - { - ATLASSERT(m_hDC != NULL); -#ifndef _WIN32_WCE - ATLASSERT((uFormat & DT_MODIFYSTRING) == 0); -#endif // !_WIN32_WCE - return ::DrawText(m_hDC, lpstrText, cchText, lpRect, uFormat); - } - - int DrawText(LPTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat) - { - ATLASSERT(m_hDC != NULL); - return ::DrawText(m_hDC, lpstrText, cchText, lpRect, uFormat); - } - -#ifndef _WIN32_WCE - int DrawTextEx(LPTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat, LPDRAWTEXTPARAMS lpDTParams = NULL) - { - ATLASSERT(m_hDC != NULL); - return ::DrawTextEx(m_hDC, lpstrText, cchText, lpRect, uFormat, lpDTParams); - } -#endif // !_WIN32_WCE - -#if (_WIN32_WINNT >= 0x0501) - int DrawShadowText(LPCWSTR lpstrText, int cchText, LPRECT lpRect, DWORD dwFlags, COLORREF clrText, COLORREF clrShadow, int xOffset, int yOffset) - { - ATLASSERT(m_hDC != NULL); - // This function is present only if comctl32.dll version 6 is loaded; - // we use LoadLibrary/GetProcAddress to allow apps compiled with - // _WIN32_WINNT >= 0x0501 to run on older Windows/CommCtrl - int nRet = 0; - HMODULE hCommCtrlDLL = ::LoadLibrary(_T("comctl32.dll")); - ATLASSERT(hCommCtrlDLL != NULL); - if(hCommCtrlDLL != NULL) - { - typedef int (WINAPI *PFN_DrawShadowText)(HDC hDC, LPCWSTR lpstrText, UINT cchText, LPRECT lpRect, DWORD dwFlags, COLORREF clrText, COLORREF clrShadow, int xOffset, int yOffset); - PFN_DrawShadowText pfnDrawShadowText = (PFN_DrawShadowText)::GetProcAddress(hCommCtrlDLL, "DrawShadowText"); - ATLASSERT(pfnDrawShadowText != NULL); // this function requires CommCtrl6 - if(pfnDrawShadowText != NULL) - nRet = pfnDrawShadowText(m_hDC, lpstrText, cchText, lpRect, dwFlags, clrText, clrShadow, xOffset, yOffset); - ::FreeLibrary(hCommCtrlDLL); - } - return nRet; - } -#endif // (_WIN32_WINNT >= 0x0501) - - BOOL GetTextExtent(LPCTSTR lpszString, int nCount, LPSIZE lpSize) const - { - ATLASSERT(m_hDC != NULL); - if(nCount == -1) - nCount = lstrlen(lpszString); - return ::GetTextExtentPoint32(m_hDC, lpszString, nCount, lpSize); - } - - BOOL GetTextExtentExPoint(LPCTSTR lpszString, int cchString, LPSIZE lpSize, int nMaxExtent, LPINT lpnFit = NULL, LPINT alpDx = NULL) - { - ATLASSERT(m_hDC != NULL); - return ::GetTextExtentExPoint(m_hDC, lpszString, cchString, nMaxExtent, lpnFit, alpDx, lpSize); - } - -#ifndef _WIN32_WCE - DWORD GetTabbedTextExtent(LPCTSTR lpszString, int nCount = -1, int nTabPositions = 0, LPINT lpnTabStopPositions = NULL) const - { - ATLASSERT(m_hDC != NULL); - if(nCount == -1) - nCount = lstrlen(lpszString); - return ::GetTabbedTextExtent(m_hDC, lpszString, nCount, nTabPositions, lpnTabStopPositions); - } - - BOOL GrayString(HBRUSH hBrush, BOOL (CALLBACK* lpfnOutput)(HDC, LPARAM, int), LPARAM lpData, int nCount, int x, int y, int nWidth, int nHeight) - { - ATLASSERT(m_hDC != NULL); - return ::GrayString(m_hDC, hBrush, (GRAYSTRINGPROC)lpfnOutput, lpData, nCount, x, y, nWidth, nHeight); - } -#endif // !_WIN32_WCE - -#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) - UINT GetTextAlign() const - { - ATLASSERT(m_hDC != NULL); - return ::GetTextAlign(m_hDC); - } - - UINT SetTextAlign(UINT nFlags) - { - ATLASSERT(m_hDC != NULL); - return ::SetTextAlign(m_hDC, nFlags); - } -#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) - - int GetTextFace(LPTSTR lpszFacename, int nCount) const - { - ATLASSERT(m_hDC != NULL); - return ::GetTextFace(m_hDC, nCount, lpszFacename); - } - - int GetTextFaceLen() const - { - ATLASSERT(m_hDC != NULL); - return ::GetTextFace(m_hDC, 0, NULL); - } - -#ifndef _ATL_NO_COM -#ifdef _OLEAUTO_H_ - BOOL GetTextFace(BSTR& bstrFace) const - { - USES_CONVERSION; - ATLASSERT(m_hDC != NULL); - ATLASSERT(bstrFace == NULL); - - int nLen = GetTextFaceLen(); - if(nLen == 0) - return FALSE; - - CTempBuffer buff; - LPTSTR lpszText = buff.Allocate(nLen); - if(lpszText == NULL) - return FALSE; - - if(!GetTextFace(lpszText, nLen)) - return FALSE; - - bstrFace = ::SysAllocString(T2OLE(lpszText)); - return (bstrFace != NULL) ? TRUE : FALSE; - } -#endif -#endif // !_ATL_NO_COM - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - int GetTextFace(_CSTRING_NS::CString& strFace) const - { - ATLASSERT(m_hDC != NULL); - - int nLen = GetTextFaceLen(); - if(nLen == 0) - return 0; - - LPTSTR lpstr = strFace.GetBufferSetLength(nLen); - if(lpstr == NULL) - return 0; - int nRet = GetTextFace(lpstr, nLen); - strFace.ReleaseBuffer(); - return nRet; - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - - BOOL GetTextMetrics(LPTEXTMETRIC lpMetrics) const - { - ATLASSERT(m_hDC != NULL); - return ::GetTextMetrics(m_hDC, lpMetrics); - } - -#ifndef _WIN32_WCE - int SetTextJustification(int nBreakExtra, int nBreakCount) - { - ATLASSERT(m_hDC != NULL); - return ::SetTextJustification(m_hDC, nBreakExtra, nBreakCount); - } - - int GetTextCharacterExtra() const - { - ATLASSERT(m_hDC != NULL); - return ::GetTextCharacterExtra(m_hDC); - } - - int SetTextCharacterExtra(int nCharExtra) - { - ATLASSERT(m_hDC != NULL); - return ::SetTextCharacterExtra(m_hDC, nCharExtra); - } -#endif // !_WIN32_WCE - -// Advanced Drawing - BOOL DrawEdge(LPRECT lpRect, UINT nEdge, UINT nFlags) - { - ATLASSERT(m_hDC != NULL); - return ::DrawEdge(m_hDC, lpRect, nEdge, nFlags); - } - - BOOL DrawFrameControl(LPRECT lpRect, UINT nType, UINT nState) - { - ATLASSERT(m_hDC != NULL); - return ::DrawFrameControl(m_hDC, lpRect, nType, nState); - } - -// Scrolling Functions - BOOL ScrollDC(int dx, int dy, LPCRECT lpRectScroll, LPCRECT lpRectClip, HRGN hRgnUpdate, LPRECT lpRectUpdate) - { - ATLASSERT(m_hDC != NULL); - return ::ScrollDC(m_hDC, dx, dy, lpRectScroll, lpRectClip, hRgnUpdate, lpRectUpdate); - } - -// Font Functions -#ifndef _WIN32_WCE - BOOL GetCharWidth(UINT nFirstChar, UINT nLastChar, LPINT lpBuffer) const - { - ATLASSERT(m_hDC != NULL); - return ::GetCharWidth(m_hDC, nFirstChar, nLastChar, lpBuffer); - } - - // GetCharWidth32 is not supported under Win9x - BOOL GetCharWidth32(UINT nFirstChar, UINT nLastChar, LPINT lpBuffer) const - { - ATLASSERT(m_hDC != NULL); - return ::GetCharWidth32(m_hDC, nFirstChar, nLastChar, lpBuffer); - } - - DWORD SetMapperFlags(DWORD dwFlag) - { - ATLASSERT(m_hDC != NULL); - return ::SetMapperFlags(m_hDC, dwFlag); - } - - BOOL GetAspectRatioFilter(LPSIZE lpSize) const - { - ATLASSERT(m_hDC != NULL); - return ::GetAspectRatioFilterEx(m_hDC, lpSize); - } - - BOOL GetCharABCWidths(UINT nFirstChar, UINT nLastChar, LPABC lpabc) const - { - ATLASSERT(m_hDC != NULL); - return ::GetCharABCWidths(m_hDC, nFirstChar, nLastChar, lpabc); - } - - DWORD GetFontData(DWORD dwTable, DWORD dwOffset, LPVOID lpData, DWORD cbData) const - { - ATLASSERT(m_hDC != NULL); - return ::GetFontData(m_hDC, dwTable, dwOffset, lpData, cbData); - } - - int GetKerningPairs(int nPairs, LPKERNINGPAIR lpkrnpair) const - { - ATLASSERT(m_hDC != NULL); - return ::GetKerningPairs(m_hDC, nPairs, lpkrnpair); - } - - UINT GetOutlineTextMetrics(UINT cbData, LPOUTLINETEXTMETRIC lpotm) const - { - ATLASSERT(m_hDC != NULL); - return ::GetOutlineTextMetrics(m_hDC, cbData, lpotm); - } - - DWORD GetGlyphOutline(UINT nChar, UINT nFormat, LPGLYPHMETRICS lpgm, DWORD cbBuffer, LPVOID lpBuffer, const MAT2* lpmat2) const - { - ATLASSERT(m_hDC != NULL); - return ::GetGlyphOutline(m_hDC, nChar, nFormat, lpgm, cbBuffer, lpBuffer, lpmat2); - } - - BOOL GetCharABCWidths(UINT nFirstChar, UINT nLastChar, LPABCFLOAT lpABCF) const - { - ATLASSERT(m_hDC != NULL); - return ::GetCharABCWidthsFloat(m_hDC, nFirstChar, nLastChar, lpABCF); - } - - BOOL GetCharWidth(UINT nFirstChar, UINT nLastChar, float* lpFloatBuffer) const - { - ATLASSERT(m_hDC != NULL); - return ::GetCharWidthFloat(m_hDC, nFirstChar, nLastChar, lpFloatBuffer); - } -#endif // !_WIN32_WCE - -// Printer/Device Escape Functions -#ifndef _WIN32_WCE - int Escape(int nEscape, int nCount, LPCSTR lpszInData, LPVOID lpOutData) - { - ATLASSERT(m_hDC != NULL); - return ::Escape(m_hDC, nEscape, nCount, lpszInData, lpOutData); - } -#endif // !_WIN32_WCE - - int Escape(int nEscape, int nInputSize, LPCSTR lpszInputData, - int nOutputSize, LPSTR lpszOutputData) - { - ATLASSERT(m_hDC != NULL); - return ::ExtEscape(m_hDC, nEscape, nInputSize, lpszInputData, nOutputSize, lpszOutputData); - } - -#ifndef _WIN32_WCE - int DrawEscape(int nEscape, int nInputSize, LPCSTR lpszInputData) - { - ATLASSERT(m_hDC != NULL); - return ::DrawEscape(m_hDC, nEscape, nInputSize, lpszInputData); - } -#endif // !_WIN32_WCE - - // Escape helpers -#if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 200) && defined(StartDoc)) - int StartDoc(LPCTSTR lpszDocName) // old Win3.0 version - { - DOCINFO di = { 0 }; - di.cbSize = sizeof(DOCINFO); - di.lpszDocName = lpszDocName; - return StartDoc(&di); - } - - int StartDoc(LPDOCINFO lpDocInfo) - { - ATLASSERT(m_hDC != NULL); - return ::StartDoc(m_hDC, lpDocInfo); - } - - int StartPage() - { - ATLASSERT(m_hDC != NULL); - return ::StartPage(m_hDC); - } - - int EndPage() - { - ATLASSERT(m_hDC != NULL); - return ::EndPage(m_hDC); - } - - int SetAbortProc(BOOL (CALLBACK* lpfn)(HDC, int)) - { - ATLASSERT(m_hDC != NULL); - return ::SetAbortProc(m_hDC, (ABORTPROC)lpfn); - } - - int AbortDoc() - { - ATLASSERT(m_hDC != NULL); - return ::AbortDoc(m_hDC); - } - - int EndDoc() - { - ATLASSERT(m_hDC != NULL); - return ::EndDoc(m_hDC); - } -#endif // !defined(_WIN32_WCE) || ((_WIN32_WCE >= 200) && defined(StartDoc)) - -// MetaFile Functions -#ifndef _WIN32_WCE - BOOL PlayMetaFile(HMETAFILE hMF) - { - ATLASSERT(m_hDC != NULL); - if(::GetDeviceCaps(m_hDC, TECHNOLOGY) == DT_METAFILE) - { - // playing metafile in metafile, just use core windows API - return ::PlayMetaFile(m_hDC, hMF); - } - - // for special playback, lParam == pDC - return ::EnumMetaFile(m_hDC, hMF, EnumMetaFileProc, (LPARAM)this); - } - - BOOL PlayMetaFile(HENHMETAFILE hEnhMetaFile, LPCRECT lpBounds) - { - ATLASSERT(m_hDC != NULL); - return ::PlayEnhMetaFile(m_hDC, hEnhMetaFile, lpBounds); - } - - BOOL AddMetaFileComment(UINT nDataSize, const BYTE* pCommentData) // can be used for enhanced metafiles only - { - ATLASSERT(m_hDC != NULL); - return ::GdiComment(m_hDC, nDataSize, pCommentData); - } - - // Special handling for metafile playback - static int CALLBACK EnumMetaFileProc(HDC hDC, HANDLETABLE* pHandleTable, METARECORD* pMetaRec, int nHandles, LPARAM lParam) - { - CDCHandle* pDC = (CDCHandle*)lParam; - - switch (pMetaRec->rdFunction) - { - case META_SETMAPMODE: - pDC->SetMapMode((int)(short)pMetaRec->rdParm[0]); - break; - case META_SETWINDOWEXT: - pDC->SetWindowExt((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); - break; - case META_SETWINDOWORG: - pDC->SetWindowOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); - break; - case META_SETVIEWPORTEXT: - pDC->SetViewportExt((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); - break; - case META_SETVIEWPORTORG: - pDC->SetViewportOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); - break; - case META_SCALEWINDOWEXT: - pDC->ScaleWindowExt((int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2], - (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); - break; - case META_SCALEVIEWPORTEXT: - pDC->ScaleViewportExt((int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2], - (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); - break; - case META_OFFSETVIEWPORTORG: - pDC->OffsetViewportOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); - break; - case META_SAVEDC: - pDC->SaveDC(); - break; - case META_RESTOREDC: - pDC->RestoreDC((int)(short)pMetaRec->rdParm[0]); - break; - case META_SETBKCOLOR: - pDC->SetBkColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]); - break; - case META_SETTEXTCOLOR: - pDC->SetTextColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]); - break; - - // need to watch out for SelectObject(HFONT), for custom font mapping - case META_SELECTOBJECT: - { - HGDIOBJ hObject = pHandleTable->objectHandle[pMetaRec->rdParm[0]]; - UINT nObjType = ::GetObjectType(hObject); - if(nObjType == 0) - { - // object type is unknown, determine if it is a font - HFONT hStockFont = (HFONT)::GetStockObject(SYSTEM_FONT); - HFONT hFontOld = (HFONT)::SelectObject(pDC->m_hDC, hStockFont); - HGDIOBJ hObjOld = ::SelectObject(pDC->m_hDC, hObject); - if(hObjOld == hStockFont) - { - // got the stock object back, so must be selecting a font - pDC->SelectFont((HFONT)hObject); - break; // don't play the default record - } - else - { - // didn't get the stock object back, so restore everything - ::SelectObject(pDC->m_hDC, hFontOld); - ::SelectObject(pDC->m_hDC, hObjOld); - } - // and fall through to PlayMetaFileRecord... - } - else if(nObjType == OBJ_FONT) - { - // play back as CDCHandle::SelectFont(HFONT) - pDC->SelectFont((HFONT)hObject); - break; // don't play the default record - } - } - // fall through... - - default: - ::PlayMetaFileRecord(hDC, pHandleTable, pMetaRec, nHandles); - break; - } - - return 1; - } -#endif // !_WIN32_WCE - -// Path Functions -#ifndef _WIN32_WCE - BOOL AbortPath() - { - ATLASSERT(m_hDC != NULL); - return ::AbortPath(m_hDC); - } - - BOOL BeginPath() - { - ATLASSERT(m_hDC != NULL); - return ::BeginPath(m_hDC); - } - - BOOL CloseFigure() - { - ATLASSERT(m_hDC != NULL); - return ::CloseFigure(m_hDC); - } - - BOOL EndPath() - { - ATLASSERT(m_hDC != NULL); - return ::EndPath(m_hDC); - } - - BOOL FillPath() - { - ATLASSERT(m_hDC != NULL); - return ::FillPath(m_hDC); - } - - BOOL FlattenPath() - { - ATLASSERT(m_hDC != NULL); - return ::FlattenPath(m_hDC); - } - - BOOL StrokeAndFillPath() - { - ATLASSERT(m_hDC != NULL); - return ::StrokeAndFillPath(m_hDC); - } - - BOOL StrokePath() - { - ATLASSERT(m_hDC != NULL); - return ::StrokePath(m_hDC); - } - - BOOL WidenPath() - { - ATLASSERT(m_hDC != NULL); - return ::WidenPath(m_hDC); - } - - BOOL GetMiterLimit(PFLOAT pfMiterLimit) const - { - ATLASSERT(m_hDC != NULL); - return ::GetMiterLimit(m_hDC, pfMiterLimit); - } - - BOOL SetMiterLimit(float fMiterLimit) - { - ATLASSERT(m_hDC != NULL); - return ::SetMiterLimit(m_hDC, fMiterLimit, NULL); - } - - int GetPath(LPPOINT lpPoints, LPBYTE lpTypes, int nCount) const - { - ATLASSERT(m_hDC != NULL); - return ::GetPath(m_hDC, lpPoints, lpTypes, nCount); - } - - BOOL SelectClipPath(int nMode) - { - ATLASSERT(m_hDC != NULL); - return ::SelectClipPath(m_hDC, nMode); - } -#endif // !_WIN32_WCE - -// Misc Helper Functions - static CBrushHandle PASCAL GetHalftoneBrush() - { - HBRUSH halftoneBrush = NULL; - WORD grayPattern[8]; - for(int i = 0; i < 8; i++) - grayPattern[i] = (WORD)(0x5555 << (i & 1)); - HBITMAP grayBitmap = CreateBitmap(8, 8, 1, 1, &grayPattern); - if(grayBitmap != NULL) - { - halftoneBrush = ::CreatePatternBrush(grayBitmap); - DeleteObject(grayBitmap); - } - return CBrushHandle(halftoneBrush); - } - - void DrawDragRect(LPCRECT lpRect, SIZE size, LPCRECT lpRectLast, SIZE sizeLast, HBRUSH hBrush = NULL, HBRUSH hBrushLast = NULL) - { - // first, determine the update region and select it - CRgn rgnOutside; - rgnOutside.CreateRectRgnIndirect(lpRect); - RECT rect = *lpRect; - ::InflateRect(&rect, -size.cx, -size.cy); - ::IntersectRect(&rect, &rect, lpRect); - CRgn rgnInside; - rgnInside.CreateRectRgnIndirect(&rect); - CRgn rgnNew; - rgnNew.CreateRectRgn(0, 0, 0, 0); - rgnNew.CombineRgn(rgnOutside, rgnInside, RGN_XOR); - - HBRUSH hBrushOld = NULL; - CBrush brushHalftone; - if(hBrush == NULL) - brushHalftone = hBrush = CDCHandle::GetHalftoneBrush(); - if(hBrushLast == NULL) - hBrushLast = hBrush; - - CRgn rgnLast; - CRgn rgnUpdate; - if(lpRectLast != NULL) - { - // find difference between new region and old region - rgnLast.CreateRectRgn(0, 0, 0, 0); - rgnOutside.SetRectRgn(lpRectLast->left, lpRectLast->top, lpRectLast->right, lpRectLast->bottom); - rect = *lpRectLast; - ::InflateRect(&rect, -sizeLast.cx, -sizeLast.cy); - ::IntersectRect(&rect, &rect, lpRectLast); - rgnInside.SetRectRgn(rect.left, rect.top, rect.right, rect.bottom); - rgnLast.CombineRgn(rgnOutside, rgnInside, RGN_XOR); - - // only diff them if brushes are the same - if(hBrush == hBrushLast) - { - rgnUpdate.CreateRectRgn(0, 0, 0, 0); - rgnUpdate.CombineRgn(rgnLast, rgnNew, RGN_XOR); - } - } - if(hBrush != hBrushLast && lpRectLast != NULL) - { - // brushes are different -- erase old region first - SelectClipRgn(rgnLast); - GetClipBox(&rect); - hBrushOld = SelectBrush(hBrushLast); - PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT); - SelectBrush(hBrushOld); - hBrushOld = NULL; - } - - // draw into the update/new region - SelectClipRgn(rgnUpdate.IsNull() ? rgnNew : rgnUpdate); - GetClipBox(&rect); - hBrushOld = SelectBrush(hBrush); - PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT); - - // cleanup DC - if(hBrushOld != NULL) - SelectBrush(hBrushOld); - SelectClipRgn(NULL); - } - - void FillSolidRect(LPCRECT lpRect, COLORREF clr) - { - ATLASSERT(m_hDC != NULL); - - COLORREF clrOld = ::SetBkColor(m_hDC, clr); - ATLASSERT(clrOld != CLR_INVALID); - if(clrOld != CLR_INVALID) - { - ::ExtTextOut(m_hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL); - ::SetBkColor(m_hDC, clrOld); - } - } - - void FillSolidRect(int x, int y, int cx, int cy, COLORREF clr) - { - ATLASSERT(m_hDC != NULL); - - RECT rect = { x, y, x + cx, y + cy }; - FillSolidRect(&rect, clr); - } - - void Draw3dRect(LPCRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight) - { - Draw3dRect(lpRect->left, lpRect->top, lpRect->right - lpRect->left, - lpRect->bottom - lpRect->top, clrTopLeft, clrBottomRight); - } - - void Draw3dRect(int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight) - { - FillSolidRect(x, y, cx - 1, 1, clrTopLeft); - FillSolidRect(x, y, 1, cy - 1, clrTopLeft); - FillSolidRect(x + cx, y, -1, cy, clrBottomRight); - FillSolidRect(x, y + cy, cx, -1, clrBottomRight); - } - -// DIB support -#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 410) - int SetDIBitsToDevice(int x, int y, DWORD dwWidth, DWORD dwHeight, int xSrc, int ySrc, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse) - { - ATLASSERT(m_hDC != NULL); - return ::SetDIBitsToDevice(m_hDC, x, y, dwWidth, dwHeight, xSrc, ySrc, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse); - } -#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 410) - -#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) - int StretchDIBits(int x, int y, int nWidth, int nHeight, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse, DWORD dwRop) - { - ATLASSERT(m_hDC != NULL); - return ::StretchDIBits(m_hDC, x, y, nWidth, nHeight, xSrc, ySrc, nSrcWidth, nSrcHeight, lpvBits, lpbmi, uColorUse, dwRop); - } - - UINT GetDIBColorTable(UINT uStartIndex, UINT cEntries, RGBQUAD* pColors) const - { - ATLASSERT(m_hDC != NULL); - return ::GetDIBColorTable(m_hDC, uStartIndex, cEntries, pColors); - } - - UINT SetDIBColorTable(UINT uStartIndex, UINT cEntries, CONST RGBQUAD* pColors) - { - ATLASSERT(m_hDC != NULL); - return ::SetDIBColorTable(m_hDC, uStartIndex, cEntries, pColors); - } -#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) - -// OpenGL support -#if !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE) - int ChoosePixelFormat(CONST PIXELFORMATDESCRIPTOR* ppfd) - { - ATLASSERT(m_hDC != NULL); - return ::ChoosePixelFormat(m_hDC, ppfd); - } - - int DescribePixelFormat(int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd) - { - ATLASSERT(m_hDC != NULL); - return ::DescribePixelFormat(m_hDC, iPixelFormat, nBytes, ppfd); - } - - int GetPixelFormat() const - { - ATLASSERT(m_hDC != NULL); - return ::GetPixelFormat(m_hDC); - } - - BOOL SetPixelFormat(int iPixelFormat, CONST PIXELFORMATDESCRIPTOR* ppfd) - { - ATLASSERT(m_hDC != NULL); - return ::SetPixelFormat(m_hDC, iPixelFormat, ppfd); - } - - BOOL SwapBuffers() - { - ATLASSERT(m_hDC != NULL); - return ::SwapBuffers(m_hDC); - } - - HGLRC wglCreateContext() - { - ATLASSERT(m_hDC != NULL); - return ::wglCreateContext(m_hDC); - } - - HGLRC wglCreateLayerContext(int iLayerPlane) - { - ATLASSERT(m_hDC != NULL); - return ::wglCreateLayerContext(m_hDC, iLayerPlane); - } - - BOOL wglMakeCurrent(HGLRC hglrc) - { - ATLASSERT(m_hDC != NULL); - return ::wglMakeCurrent(m_hDC, hglrc); - } - - BOOL wglUseFontBitmaps(DWORD dwFirst, DWORD dwCount, DWORD listBase) - { - ATLASSERT(m_hDC != NULL); - return ::wglUseFontBitmaps(m_hDC, dwFirst, dwCount, listBase); - } - - BOOL wglUseFontOutlines(DWORD dwFirst, DWORD dwCount, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf) - { - ATLASSERT(m_hDC != NULL); - return ::wglUseFontOutlines(m_hDC, dwFirst, dwCount, listBase, deviation, extrusion, format, lpgmf); - } - - BOOL wglDescribeLayerPlane(int iPixelFormat, int iLayerPlane, UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd) - { - ATLASSERT(m_hDC != NULL); - return ::wglDescribeLayerPlane(m_hDC, iPixelFormat, iLayerPlane, nBytes, plpd); - } - - int wglSetLayerPaletteEntries(int iLayerPlane, int iStart, int cEntries, CONST COLORREF* pclr) - { - ATLASSERT(m_hDC != NULL); - return ::wglSetLayerPaletteEntries(m_hDC, iLayerPlane, iStart, cEntries, pclr); - } - - int wglGetLayerPaletteEntries(int iLayerPlane, int iStart, int cEntries, COLORREF* pclr) - { - ATLASSERT(m_hDC != NULL); - return ::wglGetLayerPaletteEntries(m_hDC, iLayerPlane, iStart, cEntries, pclr); - } - - BOOL wglRealizeLayerPalette(int iLayerPlane, BOOL bRealize) - { - ATLASSERT(m_hDC != NULL); - return ::wglRealizeLayerPalette(m_hDC, iLayerPlane, bRealize); - } - - BOOL wglSwapLayerBuffers(UINT uPlanes) - { - ATLASSERT(m_hDC != NULL); - return ::wglSwapLayerBuffers(m_hDC, uPlanes); - } -#endif // !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE) - -// New for Windows 2000 only -#if (_WIN32_WINNT >= 0x0500) - COLORREF GetDCPenColor() const - { - ATLASSERT(m_hDC != NULL); - return ::GetDCPenColor(m_hDC); - } - - COLORREF SetDCPenColor(COLORREF clr) - { - ATLASSERT(m_hDC != NULL); - return ::SetDCPenColor(m_hDC, clr); - } - - COLORREF GetDCBrushColor() const - { - ATLASSERT(m_hDC != NULL); - return ::GetDCBrushColor(m_hDC); - } - - COLORREF SetDCBrushColor(COLORREF clr) - { - ATLASSERT(m_hDC != NULL); - return ::SetDCBrushColor(m_hDC, clr); - } - -#ifndef _WIN32_WCE - DWORD GetFontUnicodeRanges(LPGLYPHSET lpgs) const - { - ATLASSERT(m_hDC != NULL); - return ::GetFontUnicodeRanges(m_hDC, lpgs); - } -#endif // !_WIN32_WCE - - DWORD GetGlyphIndices(LPCTSTR lpstr, int cch, LPWORD pgi, DWORD dwFlags) const - { - ATLASSERT(m_hDC != NULL); - return ::GetGlyphIndices(m_hDC, lpstr, cch, pgi, dwFlags); - } - - BOOL GetTextExtentPointI(LPWORD pgiIn, int cgi, LPSIZE lpSize) const - { - ATLASSERT(m_hDC != NULL); - return ::GetTextExtentPointI(m_hDC, pgiIn, cgi, lpSize); - } - - BOOL GetTextExtentExPointI(LPWORD pgiIn, int cgi, int nMaxExtent, LPINT lpnFit, LPINT alpDx, LPSIZE lpSize) const - { - ATLASSERT(m_hDC != NULL); - return ::GetTextExtentExPointI(m_hDC, pgiIn, cgi, nMaxExtent, lpnFit, alpDx, lpSize); - } - - BOOL GetCharWidthI(UINT giFirst, UINT cgi, LPWORD pgi, LPINT lpBuffer) const - { - ATLASSERT(m_hDC != NULL); - return ::GetCharWidthI(m_hDC, giFirst, cgi, pgi, lpBuffer); - } - - BOOL GetCharABCWidthsI(UINT giFirst, UINT cgi, LPWORD pgi, LPABC lpabc) const - { - ATLASSERT(m_hDC != NULL); - return ::GetCharABCWidthsI(m_hDC, giFirst, cgi, pgi, lpabc); - } -#endif // (_WIN32_WINNT >= 0x0500) - -// New for Windows 2000 and Windows 98 -#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) - BOOL ColorCorrectPalette(HPALETTE hPalette, DWORD dwFirstEntry, DWORD dwNumOfEntries) - { - ATLASSERT(m_hDC != NULL); - return ::ColorCorrectPalette(m_hDC, hPalette, dwFirstEntry, dwNumOfEntries); - } -#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) -}; - -typedef CDCT CDCHandle; -typedef CDCT CDC; - - -/////////////////////////////////////////////////////////////////////////////// -// CDC Helpers - -class CPaintDC : public CDC -{ -public: -// Data members - HWND m_hWnd; - PAINTSTRUCT m_ps; - -// Constructor/destructor - CPaintDC(HWND hWnd) - { - ATLASSERT(::IsWindow(hWnd)); - m_hWnd = hWnd; - m_hDC = ::BeginPaint(hWnd, &m_ps); - } - - ~CPaintDC() - { - ATLASSERT(m_hDC != NULL); - ATLASSERT(::IsWindow(m_hWnd)); - ::EndPaint(m_hWnd, &m_ps); - Detach(); - } -}; - -class CClientDC : public CDC -{ -public: -// Data members - HWND m_hWnd; - -// Constructor/destructor - CClientDC(HWND hWnd) - { - ATLASSERT(hWnd == NULL || ::IsWindow(hWnd)); - m_hWnd = hWnd; - m_hDC = ::GetDC(hWnd); - } - - ~CClientDC() - { - ATLASSERT(m_hDC != NULL); - ::ReleaseDC(m_hWnd, Detach()); - } -}; - -class CWindowDC : public CDC -{ -public: -// Data members - HWND m_hWnd; - -// Constructor/destructor - CWindowDC(HWND hWnd) - { - ATLASSERT(hWnd == NULL || ::IsWindow(hWnd)); - m_hWnd = hWnd; - m_hDC = ::GetWindowDC(hWnd); - } - - ~CWindowDC() - { - ATLASSERT(m_hDC != NULL); - ::ReleaseDC(m_hWnd, Detach()); - } -}; - -class CMemoryDC : public CDC -{ -public: -// Data members - HDC m_hDCOriginal; - RECT m_rcPaint; - CBitmap m_bmp; - HBITMAP m_hBmpOld; - -// Constructor/destructor - CMemoryDC(HDC hDC, RECT& rcPaint) : m_hDCOriginal(hDC), m_hBmpOld(NULL) - { - m_rcPaint = rcPaint; - CreateCompatibleDC(m_hDCOriginal); - ATLASSERT(m_hDC != NULL); - m_bmp.CreateCompatibleBitmap(m_hDCOriginal, m_rcPaint.right - m_rcPaint.left, m_rcPaint.bottom - m_rcPaint.top); - ATLASSERT(m_bmp.m_hBitmap != NULL); - m_hBmpOld = SelectBitmap(m_bmp); - SetViewportOrg(-m_rcPaint.left, -m_rcPaint.top); - } - - ~CMemoryDC() - { - ::BitBlt(m_hDCOriginal, m_rcPaint.left, m_rcPaint.top, m_rcPaint.right - m_rcPaint.left, m_rcPaint.bottom - m_rcPaint.top, m_hDC, m_rcPaint.left, m_rcPaint.top, SRCCOPY); - SelectBitmap(m_hBmpOld); - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// Enhanced metafile support - -#ifndef _WIN32_WCE - -class CEnhMetaFileInfo -{ -public: -// Data members - HENHMETAFILE m_hEMF; - BYTE* m_pBits; - TCHAR* m_pDesc; - ENHMETAHEADER m_header; - PIXELFORMATDESCRIPTOR m_pfd; - -// Constructor/destructor - CEnhMetaFileInfo(HENHMETAFILE hEMF) : m_pBits(NULL), m_pDesc(NULL), m_hEMF(hEMF) - { } - - ~CEnhMetaFileInfo() - { - delete [] m_pBits; - delete [] m_pDesc; - } - -// Operations - BYTE* GetEnhMetaFileBits() - { - ATLASSERT(m_hEMF != NULL); - UINT nBytes = ::GetEnhMetaFileBits(m_hEMF, 0, NULL); - delete [] m_pBits; - m_pBits = NULL; - ATLTRY(m_pBits = new BYTE[nBytes]); - if (m_pBits != NULL) - ::GetEnhMetaFileBits(m_hEMF, nBytes, m_pBits); - return m_pBits; - } - - LPTSTR GetEnhMetaFileDescription() - { - ATLASSERT(m_hEMF != NULL); - UINT nLen = ::GetEnhMetaFileDescription(m_hEMF, 0, NULL); - delete [] m_pDesc; - m_pDesc = NULL; - ATLTRY(m_pDesc = new TCHAR[nLen]); - if (m_pDesc != NULL) - nLen = ::GetEnhMetaFileDescription(m_hEMF, nLen, m_pDesc); - return m_pDesc; - } - - ENHMETAHEADER* GetEnhMetaFileHeader() - { - ATLASSERT(m_hEMF != NULL); - memset(&m_header, 0, sizeof(m_header)); - m_header.iType = EMR_HEADER; - m_header.nSize = sizeof(ENHMETAHEADER); - UINT n = ::GetEnhMetaFileHeader(m_hEMF, sizeof(ENHMETAHEADER), &m_header); - return (n != 0) ? &m_header : NULL; - } - - PIXELFORMATDESCRIPTOR* GetEnhMetaFilePixelFormat() - { - ATLASSERT(m_hEMF != NULL); - memset(&m_pfd, 0, sizeof(m_pfd)); - UINT n = ::GetEnhMetaFilePixelFormat(m_hEMF, sizeof(m_pfd), &m_pfd); - return (n != 0) ? &m_pfd : NULL; - } -}; - - -template -class CEnhMetaFileT -{ -public: -// Data members - HENHMETAFILE m_hEMF; - -// Constructor/destructor - CEnhMetaFileT(HENHMETAFILE hEMF = NULL) : m_hEMF(hEMF) - { - } - - ~CEnhMetaFileT() - { - if(t_bManaged && m_hEMF != NULL) - DeleteObject(); - } - -// Operations - CEnhMetaFileT& operator =(HENHMETAFILE hEMF) - { - Attach(hEMF); - return *this; - } - - void Attach(HENHMETAFILE hEMF) - { - if(t_bManaged && m_hEMF != NULL && m_hEMF != hEMF) - DeleteObject(); - m_hEMF = hEMF; - } - - HENHMETAFILE Detach() - { - HENHMETAFILE hEMF = m_hEMF; - m_hEMF = NULL; - return hEMF; - } - - operator HENHMETAFILE() const { return m_hEMF; } - - bool IsNull() const { return (m_hEMF == NULL); } - - BOOL DeleteObject() - { - ATLASSERT(m_hEMF != NULL); - BOOL bRet = ::DeleteEnhMetaFile(m_hEMF); - m_hEMF = NULL; - return bRet; - } - - UINT GetEnhMetaFileBits(UINT cbBuffer, LPBYTE lpbBuffer) const - { - ATLASSERT(m_hEMF != NULL); - return ::GetEnhMetaFileBits(m_hEMF, cbBuffer, lpbBuffer); - } - - UINT GetEnhMetaFileDescription(UINT cchBuffer, LPTSTR lpszDescription) const - { - ATLASSERT(m_hEMF != NULL); - return ::GetEnhMetaFileDescription(m_hEMF, cchBuffer, lpszDescription); - } - - UINT GetEnhMetaFileHeader(LPENHMETAHEADER lpemh) const - { - ATLASSERT(m_hEMF != NULL); - lpemh->iType = EMR_HEADER; - lpemh->nSize = sizeof(ENHMETAHEADER); - return ::GetEnhMetaFileHeader(m_hEMF, sizeof(ENHMETAHEADER), lpemh); - } - - UINT GetEnhMetaFilePaletteEntries(UINT cEntries, LPPALETTEENTRY lppe) const - { - ATLASSERT(m_hEMF != NULL); - return ::GetEnhMetaFilePaletteEntries(m_hEMF, cEntries, lppe); - } - - UINT GetEnhMetaFilePixelFormat(DWORD cbBuffer, PIXELFORMATDESCRIPTOR* ppfd) const - { - ATLASSERT(m_hEMF != NULL); - return ::GetEnhMetaFilePixelFormat(m_hEMF, cbBuffer, ppfd); - } -}; - -typedef CEnhMetaFileT CEnhMetaFileHandle; -typedef CEnhMetaFileT CEnhMetaFile; - - -class CEnhMetaFileDC : public CDC -{ -public: -// Constructor/destructor - CEnhMetaFileDC() - { - } - - CEnhMetaFileDC(HDC hdc, LPCRECT lpRect) - { - Create(hdc, NULL, lpRect, NULL); - ATLASSERT(m_hDC != NULL); - } - - CEnhMetaFileDC(HDC hdcRef, LPCTSTR lpFilename, LPCRECT lpRect, LPCTSTR lpDescription) - { - Create(hdcRef, lpFilename, lpRect, lpDescription); - ATLASSERT(m_hDC != NULL); - } - - ~CEnhMetaFileDC() - { - HENHMETAFILE hEMF = Close(); - if (hEMF != NULL) - ::DeleteEnhMetaFile(hEMF); - } - -// Operations - void Create(HDC hdcRef, LPCTSTR lpFilename, LPCRECT lpRect, LPCTSTR lpDescription) - { - ATLASSERT(m_hDC == NULL); - m_hDC = ::CreateEnhMetaFile(hdcRef, lpFilename, lpRect, lpDescription); - } - - HENHMETAFILE Close() - { - HENHMETAFILE hEMF = NULL; - if (m_hDC != NULL) - { - hEMF = ::CloseEnhMetaFile(m_hDC); - m_hDC = NULL; - } - return hEMF; - } -}; - -#endif // !_WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// WinCE compatible clipboard CF_DIB format support functions - -#ifndef _WTL_NO_DIB16 - -#define DIBINFO16_BITFIELDS { 31744, 992, 31 } - -// DIBINFO16 - To avoid color table problems in WinCE we only create this type of Dib -struct DIBINFO16 // a BITMAPINFO with 2 additional color bitfields -{ - BITMAPINFOHEADER bmiHeader; - RGBQUAD bmiColors[3]; - - DIBINFO16(SIZE size) - { - BITMAPINFOHEADER bmih = { sizeof(BITMAPINFOHEADER), size.cx, size.cy, - 1, 16, BI_BITFIELDS, 2 * size.cx * size.cy , 0, 0, 3 }; - DWORD dw[3] = DIBINFO16_BITFIELDS ; - - bmiHeader = bmih; - SecureHelper::memcpy_x(bmiColors, sizeof(bmiColors), dw, 3 * sizeof(DWORD)); - } -}; - - -// AtlxxxDibxxx minimal packed DIB implementation and helpers to copy and paste CF_DIB - -inline bool AtlIsDib16(LPBITMAPINFOHEADER pbmih) -{ - return (pbmih->biBitCount == 16) && (pbmih->biCompression == BI_BITFIELDS); -} - -inline int AtlGetDibColorTableSize(LPBITMAPINFOHEADER pbmih) -{ - switch (pbmih->biBitCount) - { - case 2: - case 4: - case 8: - return pbmih->biClrUsed ? pbmih->biClrUsed : 1 << pbmih->biBitCount; - case 24: - break; - case 16: - case 32: - return pbmih->biCompression == BI_BITFIELDS ? 3 : 0; - default: - ATLASSERT(FALSE); // should never come here - } - - return 0; -} - -inline int AtlGetDibNumColors(LPBITMAPINFOHEADER pbmih) -{ - switch (pbmih->biBitCount) - { - case 2: - case 4: - case 8: - if (pbmih->biClrUsed) - return pbmih->biClrUsed; - else - break; - case 16: - if (pbmih->biCompression == BI_BITFIELDS ) - return 1 << 15; - else - break; - case 24: - break; - case 32: - if (pbmih->biCompression == BI_BITFIELDS ) - return 1 << 24; - else - break; - default: - ATLASSERT(FALSE); - } - - return 1 << pbmih->biBitCount; -} - -inline HBITMAP AtlGetDibBitmap(LPBITMAPINFO pbmi) -{ - CDC dc(NULL); - void* pBits = NULL; - - LPBYTE pDibBits = (LPBYTE)pbmi + sizeof(BITMAPINFOHEADER) + AtlGetDibColorTableSize(&pbmi->bmiHeader) * sizeof(RGBQUAD); - HBITMAP hbm = CreateDIBSection(dc, pbmi, DIB_RGB_COLORS, &pBits, NULL, NULL); - if (hbm != NULL) - { - int cbBits = pbmi->bmiHeader.biWidth * pbmi->bmiHeader.biHeight * pbmi->bmiHeader.biBitCount / 8; - SecureHelper::memcpy_x(pBits, cbBits, pDibBits, pbmi->bmiHeader.biSizeImage); - } - - return hbm; -} - -inline HBITMAP AtlCopyBitmap(HBITMAP hbm, SIZE sizeDst, bool bAsBitmap = false) -{ - CDC hdcSrc = CreateCompatibleDC(NULL); - CDC hdcDst = CreateCompatibleDC(NULL); - - CBitmapHandle hbmOld = NULL, hbmOld2 = NULL, bmSrc = hbm; - - CBitmap bmNew = NULL; - - SIZE sizeSrc = { 0 }; - bmSrc.GetSize(sizeSrc); - - hbmOld = hdcSrc.SelectBitmap(bmSrc); - - if (bAsBitmap) - { - bmNew.CreateCompatibleBitmap(hdcSrc, sizeDst.cx, sizeDst.cy); - } - else - { - DIBINFO16 dib16(sizeDst); - LPVOID pBits = NULL; - bmNew = CreateDIBSection(hdcDst, (const BITMAPINFO*)&dib16, DIB_RGB_COLORS, &pBits, NULL, NULL); - } - - ATLASSERT(!bmNew.IsNull()); - - hbmOld2 = hdcDst.SelectBitmap(bmNew); - BOOL bOK = FALSE; - - if ((sizeDst.cx == sizeSrc.cx) && (sizeDst.cy == sizeSrc.cy)) - bOK = hdcDst.BitBlt(0, 0, sizeDst.cx, sizeDst.cy, hdcSrc, 0, 0, SRCCOPY); - else - bOK = hdcDst.StretchBlt(0, 0, sizeDst.cx, sizeDst.cy, hdcSrc, 0, 0, sizeSrc.cx, sizeSrc.cy, SRCCOPY); - - hdcSrc.SelectBitmap(hbmOld); - hdcDst.SelectBitmap(hbmOld2); - - if (bOK == FALSE) - bmNew.DeleteObject(); - - return bmNew.Detach(); -} - -inline HLOCAL AtlCreatePackedDib16(HBITMAP hbm, SIZE size) -{ - DIBSECTION ds = { 0 }; - LPBYTE pDib = NULL; - bool bCopied = false; - - bool bOK = GetObject(hbm, sizeof(ds), &ds) == sizeof(ds); - if ((bOK == FALSE) || (ds.dsBm.bmBits == NULL) || (AtlIsDib16(&ds.dsBmih) == FALSE) || - (ds.dsBmih.biWidth != size.cx ) || (ds.dsBmih.biHeight != size.cy )) - { - if ((hbm = AtlCopyBitmap(hbm, size)) != NULL) - { - bCopied = true; - bOK = GetObject(hbm, sizeof(ds), &ds) == sizeof(ds); - } - else - { - bOK = FALSE; - } - } - - if((bOK != FALSE) && (AtlIsDib16(&ds.dsBmih) != FALSE) && (ds.dsBm.bmBits != NULL)) - { - pDib = (LPBYTE)LocalAlloc(LMEM_ZEROINIT, sizeof(DIBINFO16) + ds.dsBmih.biSizeImage); - if (pDib != NULL) - { - SecureHelper::memcpy_x(pDib, sizeof(DIBINFO16) + ds.dsBmih.biSizeImage, &ds.dsBmih, sizeof(DIBINFO16)); - SecureHelper::memcpy_x(pDib + sizeof(DIBINFO16), ds.dsBmih.biSizeImage, ds.dsBm.bmBits, ds.dsBmih.biSizeImage); - } - } - - if (bCopied == true) - DeleteObject(hbm); - - return (HLOCAL)pDib; -} - -inline bool AtlSetClipboardDib16(HBITMAP hbm, SIZE size, HWND hWnd) -{ - ATLASSERT(::IsWindow(hWnd)); - BOOL bOK = OpenClipboard(hWnd); - if (bOK != FALSE) - { - bOK = EmptyClipboard(); - if (bOK != FALSE) - { - HLOCAL hDib = AtlCreatePackedDib16(hbm, size); - if (hDib != NULL) - { - bOK = SetClipboardData(CF_DIB, hDib) != NULL; - if (bOK == FALSE) - LocalFree(hDib); - } - else - { - bOK = FALSE; - } - } - CloseClipboard(); - } - - return (bOK != FALSE); -} - -inline HBITMAP AtlGetClipboardDib(HWND hWnd) -{ - ATLASSERT(::IsWindow(hWnd) != FALSE); - HBITMAP hbm = NULL; - if (OpenClipboard(hWnd) != FALSE) - { - LPBITMAPINFO pbmi = (LPBITMAPINFO)GetClipboardData(CF_DIB); - if (pbmi != NULL) - hbm = AtlGetDibBitmap(pbmi); - CloseClipboard(); - } - - return hbm; -} - -#endif // _WTL_NO_DIB16 - -}; // namespace WTL - -#endif // __ATLGDI_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlmisc.h b/!NotAdopted/SmartAutoReplier/wtl/atlmisc.h deleted file mode 100644 index 3519b348fd..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlmisc.h +++ /dev/null @@ -1,3817 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLMISC_H__ -#define __ATLMISC_H__ - -#pragma once - -#ifndef __ATLAPP_H__ - #error atlmisc.h requires atlapp.h to be included first -#endif - - -#ifdef _ATL_TMP_NO_CSTRING - #define _WTL_NO_CSTRING -#endif - -#if defined(_WTL_USE_CSTRING) && defined(_WTL_NO_CSTRING) - #error Conflicting options - both _WTL_USE_CSTRING and _WTL_NO_CSTRING are defined -#endif // defined(_WTL_USE_CSTRING) && defined(_WTL_NO_CSTRING) - -#if !defined(_WTL_USE_CSTRING) && !defined(_WTL_NO_CSTRING) - #define _WTL_USE_CSTRING -#endif // !defined(_WTL_USE_CSTRING) && !defined(_WTL_NO_CSTRING) - -#ifndef _WTL_NO_CSTRING - #if defined(_ATL_USE_CSTRING_FLOAT) && defined(_ATL_MIN_CRT) - #error Cannot use CString floating point formatting with _ATL_MIN_CRT defined - #endif // defined(_ATL_USE_CSTRING_FLOAT) && defined(_ATL_MIN_CRT) -#endif // !_WTL_NO_CSTRING - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CSize -// CPoint -// CRect -// CString -// -// CRecentDocumentListBase -// CRecentDocumentList -// CFindFile -// -// Global functions: -// AtlGetStockPen() -// AtlGetStockBrush() -// AtlGetStockFont() -// AtlGetStockPalette() -// -// AtlCompactPath() - - -namespace WTL -{ - -#ifndef _WTL_NO_WTYPES - -// forward declarations -class CSize; -class CPoint; -class CRect; - -/////////////////////////////////////////////////////////////////////////////// -// CSize - Wrapper for Windows SIZE structure. - -class CSize : public SIZE -{ -public: -// Constructors - CSize() - { - cx = 0; - cy = 0; - } - - CSize(int initCX, int initCY) - { - cx = initCX; - cy = initCY; - } - - CSize(SIZE initSize) - { - *(SIZE*)this = initSize; - } - - CSize(POINT initPt) - { - *(POINT*)this = initPt; - } - - CSize(DWORD dwSize) - { - cx = (short)LOWORD(dwSize); - cy = (short)HIWORD(dwSize); - } - -// Operations - BOOL operator ==(SIZE size) const - { - return (cx == size.cx && cy == size.cy); - } - - BOOL operator !=(SIZE size) const - { - return (cx != size.cx || cy != size.cy); - } - - void operator +=(SIZE size) - { - cx += size.cx; - cy += size.cy; - } - - void operator -=(SIZE size) - { - cx -= size.cx; - cy -= size.cy; - } - - void SetSize(int CX, int CY) - { - cx = CX; - cy = CY; - } - -// Operators returning CSize values - CSize operator +(SIZE size) const - { - return CSize(cx + size.cx, cy + size.cy); - } - - CSize operator -(SIZE size) const - { - return CSize(cx - size.cx, cy - size.cy); - } - - CSize operator -() const - { - return CSize(-cx, -cy); - } - -// Operators returning CPoint values - CPoint operator +(POINT point) const; - CPoint operator -(POINT point) const; - -// Operators returning CRect values - CRect operator +(const RECT* lpRect) const; - CRect operator -(const RECT* lpRect) const; -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CPoint - Wrapper for Windows POINT structure. - -class CPoint : public POINT -{ -public: -// Constructors - CPoint() - { - x = 0; - y = 0; - } - - CPoint(int initX, int initY) - { - x = initX; - y = initY; - } - - CPoint(POINT initPt) - { - *(POINT*)this = initPt; - } - - CPoint(SIZE initSize) - { - *(SIZE*)this = initSize; - } - - CPoint(DWORD dwPoint) - { - x = (short)LOWORD(dwPoint); - y = (short)HIWORD(dwPoint); - } - -// Operations - void Offset(int xOffset, int yOffset) - { - x += xOffset; - y += yOffset; - } - - void Offset(POINT point) - { - x += point.x; - y += point.y; - } - - void Offset(SIZE size) - { - x += size.cx; - y += size.cy; - } - - BOOL operator ==(POINT point) const - { - return (x == point.x && y == point.y); - } - - BOOL operator !=(POINT point) const - { - return (x != point.x || y != point.y); - } - - void operator +=(SIZE size) - { - x += size.cx; - y += size.cy; - } - - void operator -=(SIZE size) - { - x -= size.cx; - y -= size.cy; - } - - void operator +=(POINT point) - { - x += point.x; - y += point.y; - } - - void operator -=(POINT point) - { - x -= point.x; - y -= point.y; - } - - void SetPoint(int X, int Y) - { - x = X; - y = Y; - } - -// Operators returning CPoint values - CPoint operator +(SIZE size) const - { - return CPoint(x + size.cx, y + size.cy); - } - - CPoint operator -(SIZE size) const - { - return CPoint(x - size.cx, y - size.cy); - } - - CPoint operator -() const - { - return CPoint(-x, -y); - } - - CPoint operator +(POINT point) const - { - return CPoint(x + point.x, y + point.y); - } - -// Operators returning CSize values - CSize operator -(POINT point) const - { - return CSize(x - point.x, y - point.y); - } - -// Operators returning CRect values - CRect operator +(const RECT* lpRect) const; - CRect operator -(const RECT* lpRect) const; -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CRect - Wrapper for Windows RECT structure. - -class CRect : public RECT -{ -public: -// Constructors - CRect() - { - left = 0; - top = 0; - right = 0; - bottom = 0; - } - - CRect(int l, int t, int r, int b) - { - left = l; - top = t; - right = r; - bottom = b; - } - - CRect(const RECT& srcRect) - { - ::CopyRect(this, &srcRect); - } - - CRect(LPCRECT lpSrcRect) - { - ::CopyRect(this, lpSrcRect); - } - - CRect(POINT point, SIZE size) - { - right = (left = point.x) + size.cx; - bottom = (top = point.y) + size.cy; - } - - CRect(POINT topLeft, POINT bottomRight) - { - left = topLeft.x; - top = topLeft.y; - right = bottomRight.x; - bottom = bottomRight.y; - } - -// Attributes (in addition to RECT members) - int Width() const - { - return right - left; - } - - int Height() const - { - return bottom - top; - } - - CSize Size() const - { - return CSize(right - left, bottom - top); - } - - CPoint& TopLeft() - { - return *((CPoint*)this); - } - - CPoint& BottomRight() - { - return *((CPoint*)this + 1); - } - - const CPoint& TopLeft() const - { - return *((CPoint*)this); - } - - const CPoint& BottomRight() const - { - return *((CPoint*)this + 1); - } - - CPoint CenterPoint() const - { - return CPoint((left + right) / 2, (top + bottom) / 2); - } - - // convert between CRect and LPRECT/LPCRECT (no need for &) - operator LPRECT() - { - return this; - } - - operator LPCRECT() const - { - return this; - } - - BOOL IsRectEmpty() const - { - return ::IsRectEmpty(this); - } - - BOOL IsRectNull() const - { - return (left == 0 && right == 0 && top == 0 && bottom == 0); - } - - BOOL PtInRect(POINT point) const - { - return ::PtInRect(this, point); - } - -// Operations - void SetRect(int x1, int y1, int x2, int y2) - { - ::SetRect(this, x1, y1, x2, y2); - } - - void SetRect(POINT topLeft, POINT bottomRight) - { - ::SetRect(this, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y); - } - - void SetRectEmpty() - { - ::SetRectEmpty(this); - } - - void CopyRect(LPCRECT lpSrcRect) - { - ::CopyRect(this, lpSrcRect); - } - - BOOL EqualRect(LPCRECT lpRect) const - { - return ::EqualRect(this, lpRect); - } - - void InflateRect(int x, int y) - { - ::InflateRect(this, x, y); - } - - void InflateRect(SIZE size) - { - ::InflateRect(this, size.cx, size.cy); - } - - void InflateRect(LPCRECT lpRect) - { - left -= lpRect->left; - top -= lpRect->top; - right += lpRect->right; - bottom += lpRect->bottom; - } - - void InflateRect(int l, int t, int r, int b) - { - left -= l; - top -= t; - right += r; - bottom += b; - } - - void DeflateRect(int x, int y) - { - ::InflateRect(this, -x, -y); - } - - void DeflateRect(SIZE size) - { - ::InflateRect(this, -size.cx, -size.cy); - } - - void DeflateRect(LPCRECT lpRect) - { - left += lpRect->left; - top += lpRect->top; - right -= lpRect->right; - bottom -= lpRect->bottom; - } - - void DeflateRect(int l, int t, int r, int b) - { - left += l; - top += t; - right -= r; - bottom -= b; - } - - void OffsetRect(int x, int y) - { - ::OffsetRect(this, x, y); - } - void OffsetRect(SIZE size) - { - ::OffsetRect(this, size.cx, size.cy); - } - - void OffsetRect(POINT point) - { - ::OffsetRect(this, point.x, point.y); - } - - void NormalizeRect() - { - int nTemp; - if (left > right) - { - nTemp = left; - left = right; - right = nTemp; - } - if (top > bottom) - { - nTemp = top; - top = bottom; - bottom = nTemp; - } - } - - // absolute position of rectangle - void MoveToY(int y) - { - bottom = Height() + y; - top = y; - } - - void MoveToX(int x) - { - right = Width() + x; - left = x; - } - - void MoveToXY(int x, int y) - { - MoveToX(x); - MoveToY(y); - } - - void MoveToXY(POINT pt) - { - MoveToX(pt.x); - MoveToY(pt.y); - } - - // operations that fill '*this' with result - BOOL IntersectRect(LPCRECT lpRect1, LPCRECT lpRect2) - { - return ::IntersectRect(this, lpRect1, lpRect2); - } - - BOOL UnionRect(LPCRECT lpRect1, LPCRECT lpRect2) - { - return ::UnionRect(this, lpRect1, lpRect2); - } - - BOOL SubtractRect(LPCRECT lpRectSrc1, LPCRECT lpRectSrc2) - { - return ::SubtractRect(this, lpRectSrc1, lpRectSrc2); - } - -// Additional Operations - void operator =(const RECT& srcRect) - { - ::CopyRect(this, &srcRect); - } - - BOOL operator ==(const RECT& rect) const - { - return ::EqualRect(this, &rect); - } - - BOOL operator !=(const RECT& rect) const - { - return !::EqualRect(this, &rect); - } - - void operator +=(POINT point) - { - ::OffsetRect(this, point.x, point.y); - } - - void operator +=(SIZE size) - { - ::OffsetRect(this, size.cx, size.cy); - } - - void operator +=(LPCRECT lpRect) - { - InflateRect(lpRect); - } - - void operator -=(POINT point) - { - ::OffsetRect(this, -point.x, -point.y); - } - - void operator -=(SIZE size) - { - ::OffsetRect(this, -size.cx, -size.cy); - } - - void operator -=(LPCRECT lpRect) - { - DeflateRect(lpRect); - } - - void operator &=(const RECT& rect) - { - ::IntersectRect(this, this, &rect); - } - - void operator |=(const RECT& rect) - { - ::UnionRect(this, this, &rect); - } - -// Operators returning CRect values - CRect operator +(POINT pt) const - { - CRect rect(*this); - ::OffsetRect(&rect, pt.x, pt.y); - return rect; - } - - CRect operator -(POINT pt) const - { - CRect rect(*this); - ::OffsetRect(&rect, -pt.x, -pt.y); - return rect; - } - - CRect operator +(LPCRECT lpRect) const - { - CRect rect(this); - rect.InflateRect(lpRect); - return rect; - } - - CRect operator +(SIZE size) const - { - CRect rect(*this); - ::OffsetRect(&rect, size.cx, size.cy); - return rect; - } - - CRect operator -(SIZE size) const - { - CRect rect(*this); - ::OffsetRect(&rect, -size.cx, -size.cy); - return rect; - } - - CRect operator -(LPCRECT lpRect) const - { - CRect rect(this); - rect.DeflateRect(lpRect); - return rect; - } - - CRect operator &(const RECT& rect2) const - { - CRect rect; - ::IntersectRect(&rect, this, &rect2); - return rect; - } - - CRect operator |(const RECT& rect2) const - { - CRect rect; - ::UnionRect(&rect, this, &rect2); - return rect; - } - - CRect MulDiv(int nMultiplier, int nDivisor) const - { - return CRect( - ::MulDiv(left, nMultiplier, nDivisor), - ::MulDiv(top, nMultiplier, nDivisor), - ::MulDiv(right, nMultiplier, nDivisor), - ::MulDiv(bottom, nMultiplier, nDivisor)); - } -}; - - -// CSize implementation - -inline CPoint CSize::operator +(POINT point) const -{ return CPoint(cx + point.x, cy + point.y); } - -inline CPoint CSize::operator -(POINT point) const -{ return CPoint(cx - point.x, cy - point.y); } - -inline CRect CSize::operator +(const RECT* lpRect) const -{ return CRect(lpRect) + *this; } - -inline CRect CSize::operator -(const RECT* lpRect) const -{ return CRect(lpRect) - *this; } - - -// CPoint implementation - -inline CRect CPoint::operator +(const RECT* lpRect) const -{ return CRect(lpRect) + *this; } - -inline CRect CPoint::operator -(const RECT* lpRect) const -{ return CRect(lpRect) - *this; } - -#endif // !_WTL_NO_WTYPES - - -// WTL::CSize or ATL::CSize scalar operators - -#if !defined(_WTL_NO_SIZE_SCALAR) && (!defined(_WTL_NO_WTYPES) || defined(__ATLTYPES_H__)) - -template -inline CSize operator *(SIZE s, Num n) -{ - return CSize((int)(s.cx * n), (int)(s.cy * n)); -}; - -template -inline void operator *=(SIZE & s, Num n) -{ - s = s * n; -}; - -template -inline CSize operator /(SIZE s, Num n) -{ - return CSize((int)(s.cx / n), (int)(s.cy / n)); -}; - -template -inline void operator /=(SIZE & s, Num n) -{ - s = s / n; -}; - -#endif // !defined(_WTL_NO_SIZE_SCALAR) && (!defined(_WTL_NO_WTYPES) || defined(__ATLTYPES_H__)) - - -/////////////////////////////////////////////////////////////////////////////// -// CString - String class - -#ifndef _WTL_NO_CSTRING - -struct CStringData -{ - long nRefs; // reference count - int nDataLength; - int nAllocLength; - // TCHAR data[nAllocLength] - - TCHAR* data() - { return (TCHAR*)(this + 1); } -}; - -// Globals - -// For an empty string, m_pchData will point here -// (note: avoids special case of checking for NULL m_pchData) -// empty string data (and locked) -_declspec(selectany) int rgInitData[] = { -1, 0, 0, 0 }; -_declspec(selectany) CStringData* _atltmpDataNil = (CStringData*)&rgInitData; -_declspec(selectany) LPCTSTR _atltmpPchNil = (LPCTSTR)(((BYTE*)&rgInitData) + sizeof(CStringData)); - - -class CString -{ -public: -// Constructors - CString() - { - Init(); - } - - CString(const CString& stringSrc) - { - ATLASSERT(stringSrc.GetData()->nRefs != 0); - if (stringSrc.GetData()->nRefs >= 0) - { - ATLASSERT(stringSrc.GetData() != _atltmpDataNil); - m_pchData = stringSrc.m_pchData; - InterlockedIncrement(&GetData()->nRefs); - } - else - { - Init(); - *this = stringSrc.m_pchData; - } - } - - CString(TCHAR ch, int nRepeat = 1) - { - ATLASSERT(!_istlead(ch)); // can't create a lead byte string - Init(); - if (nRepeat >= 1) - { - if(AllocBuffer(nRepeat)) - { -#ifdef _UNICODE - for (int i = 0; i < nRepeat; i++) - m_pchData[i] = ch; -#else - memset(m_pchData, ch, nRepeat); -#endif - } - } - } - - CString(LPCTSTR lpsz) - { - Init(); - if (lpsz != NULL && HIWORD(lpsz) == NULL) - { - UINT nID = LOWORD((DWORD_PTR)lpsz); - if (!LoadString(nID)) - ATLTRACE2(atlTraceUI, 0, _T("Warning: implicit LoadString(%u) in CString failed\n"), nID); - } - else - { - int nLen = SafeStrlen(lpsz); - if (nLen != 0) - { - if(AllocBuffer(nLen)) - SecureHelper::memcpy_x(m_pchData, (nLen + 1) * sizeof(TCHAR), lpsz, nLen * sizeof(TCHAR)); - } - } - } - -#ifdef _UNICODE - CString(LPCSTR lpsz) - { - Init(); -#if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) - int nSrcLen = (lpsz != NULL) ? ATL::lstrlenA(lpsz) : 0; -#else - int nSrcLen = (lpsz != NULL) ? lstrlenA(lpsz) : 0; -#endif - if (nSrcLen != 0) - { - if(AllocBuffer(nSrcLen)) - { - _mbstowcsz(m_pchData, lpsz, nSrcLen + 1); - ReleaseBuffer(); - } - } - } -#else // !_UNICODE - CString(LPCWSTR lpsz) - { - Init(); - int nSrcLen = (lpsz != NULL) ? (int)wcslen(lpsz) : 0; - if (nSrcLen != 0) - { - if(AllocBuffer(nSrcLen * 2)) - { - _wcstombsz(m_pchData, lpsz, (nSrcLen * 2) + 1); - ReleaseBuffer(); - } - } - } -#endif // !_UNICODE - - CString(LPCTSTR lpch, int nLength) - { - Init(); - if (nLength != 0) - { - if(AllocBuffer(nLength)) - SecureHelper::memcpy_x(m_pchData, (nLength + 1) * sizeof(TCHAR), lpch, nLength * sizeof(TCHAR)); - } - } - -#ifdef _UNICODE - CString(LPCSTR lpsz, int nLength) - { - Init(); - if (nLength != 0) - { - if(AllocBuffer(nLength)) - { - int n = ::MultiByteToWideChar(CP_ACP, 0, lpsz, nLength, m_pchData, nLength + 1); - ReleaseBuffer((n >= 0) ? n : -1); - } - } - } -#else // !_UNICODE - CString(LPCWSTR lpsz, int nLength) - { - Init(); - if (nLength != 0) - { - if(((nLength * 2) > nLength) && AllocBuffer(nLength * 2)) - { - int n = ::WideCharToMultiByte(CP_ACP, 0, lpsz, nLength, m_pchData, (nLength * 2) + 1, NULL, NULL); - ReleaseBuffer((n >= 0) ? n : -1); - } - } - } -#endif // !_UNICODE - - CString(const unsigned char* lpsz) - { - Init(); - *this = (LPCSTR)lpsz; - } - -// Attributes & Operations - int GetLength() const // as an array of characters - { - return GetData()->nDataLength; - } - - BOOL IsEmpty() const - { - return GetData()->nDataLength == 0; - } - - void Empty() // free up the data - { - if (GetData()->nDataLength == 0) - return; - - if (GetData()->nRefs >= 0) - Release(); - else - *this = _T(""); - - ATLASSERT(GetData()->nDataLength == 0); - ATLASSERT(GetData()->nRefs < 0 || GetData()->nAllocLength == 0); - } - - TCHAR GetAt(int nIndex) const // 0 based - { - ATLASSERT(nIndex >= 0); - ATLASSERT(nIndex < GetData()->nDataLength); - return m_pchData[nIndex]; - } - - TCHAR operator [](int nIndex) const // same as GetAt - { - // same as GetAt - ATLASSERT(nIndex >= 0); - ATLASSERT(nIndex < GetData()->nDataLength); - return m_pchData[nIndex]; - } - - void SetAt(int nIndex, TCHAR ch) - { - ATLASSERT(nIndex >= 0); - ATLASSERT(nIndex < GetData()->nDataLength); - - CopyBeforeWrite(); - m_pchData[nIndex] = ch; - } - - operator LPCTSTR() const // as a C string - { - return m_pchData; - } - - // overloaded assignment - CString& operator =(const CString& stringSrc) - { - if (m_pchData != stringSrc.m_pchData) - { - if ((GetData()->nRefs < 0 && GetData() != _atltmpDataNil) || stringSrc.GetData()->nRefs < 0) - { - // actual copy necessary since one of the strings is locked - AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData); - } - else - { - // can just copy references around - Release(); - ATLASSERT(stringSrc.GetData() != _atltmpDataNil); - m_pchData = stringSrc.m_pchData; - InterlockedIncrement(&GetData()->nRefs); - } - } - return *this; - } - - CString& operator =(TCHAR ch) - { - ATLASSERT(!_istlead(ch)); // can't set single lead byte - AssignCopy(1, &ch); - return *this; - } - -#ifdef _UNICODE - CString& operator =(char ch) - { - *this = (TCHAR)ch; - return *this; - } -#endif - - CString& operator =(LPCTSTR lpsz) - { - ATLASSERT(lpsz == NULL || _IsValidString(lpsz)); - AssignCopy(SafeStrlen(lpsz), lpsz); - return *this; - } - -#ifdef _UNICODE - CString& operator =(LPCSTR lpsz) - { -#if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) - int nSrcLen = (lpsz != NULL) ? ATL::lstrlenA(lpsz) : 0; -#else - int nSrcLen = (lpsz != NULL) ? lstrlenA(lpsz) : 0; -#endif - if(AllocBeforeWrite(nSrcLen)) - { - _mbstowcsz(m_pchData, lpsz, nSrcLen + 1); - ReleaseBuffer(); - } - return *this; - } -#else // !_UNICODE - CString& operator =(LPCWSTR lpsz) - { - int nSrcLen = (lpsz != NULL) ? (int)wcslen(lpsz) : 0; - if(AllocBeforeWrite(nSrcLen * 2)) - { - _wcstombsz(m_pchData, lpsz, (nSrcLen * 2) + 1); - ReleaseBuffer(); - } - return *this; - } -#endif // !_UNICODE - - CString& operator =(const unsigned char* lpsz) - { - *this = (LPCSTR)lpsz; - return *this; - } - - // string concatenation - CString& operator +=(const CString& string) - { - ConcatInPlace(string.GetData()->nDataLength, string.m_pchData); - return *this; - } - - CString& operator +=(TCHAR ch) - { - ConcatInPlace(1, &ch); - return *this; - } - -#ifdef _UNICODE - CString& operator +=(char ch) - { - *this += (TCHAR)ch; - return *this; - } -#endif - - CString& operator +=(LPCTSTR lpsz) - { - ATLASSERT(lpsz == NULL || _IsValidString(lpsz)); - ConcatInPlace(SafeStrlen(lpsz), lpsz); - return *this; - } - - friend CString __stdcall operator +(const CString& string1, const CString& string2); - friend CString __stdcall operator +(const CString& string, TCHAR ch); - friend CString __stdcall operator +(TCHAR ch, const CString& string); -#ifdef _UNICODE - friend CString __stdcall operator +(const CString& string, char ch); - friend CString __stdcall operator +(char ch, const CString& string); -#endif - friend CString __stdcall operator +(const CString& string, LPCTSTR lpsz); - friend CString __stdcall operator +(LPCTSTR lpsz, const CString& string); - - // string comparison - int Compare(LPCTSTR lpsz) const // straight character (MBCS/Unicode aware) - { - return _cstrcmp(m_pchData, lpsz); - } - - int CompareNoCase(LPCTSTR lpsz) const // ignore case (MBCS/Unicode aware) - { - return _cstrcmpi(m_pchData, lpsz); - } - -#ifndef _WIN32_WCE - // CString::Collate is often slower than Compare but is MBSC/Unicode - // aware as well as locale-sensitive with respect to sort order. - int Collate(LPCTSTR lpsz) const // NLS aware - { - return _cstrcoll(m_pchData, lpsz); - } - - int CollateNoCase(LPCTSTR lpsz) const // ignore case - { - return _cstrcolli(m_pchData, lpsz); - } -#endif // !_WIN32_WCE - - // simple sub-string extraction - CString Mid(int nFirst, int nCount) const - { - // out-of-bounds requests return sensible things - if (nFirst < 0) - nFirst = 0; - if (nCount < 0) - nCount = 0; - - if (nFirst + nCount > GetData()->nDataLength) - nCount = GetData()->nDataLength - nFirst; - if (nFirst > GetData()->nDataLength) - nCount = 0; - - CString dest; - AllocCopy(dest, nCount, nFirst, 0); - return dest; - } - - CString Mid(int nFirst) const - { - return Mid(nFirst, GetData()->nDataLength - nFirst); - } - - CString Left(int nCount) const - { - if (nCount < 0) - nCount = 0; - else if (nCount > GetData()->nDataLength) - nCount = GetData()->nDataLength; - - CString dest; - AllocCopy(dest, nCount, 0, 0); - return dest; - } - - CString Right(int nCount) const - { - if (nCount < 0) - nCount = 0; - else if (nCount > GetData()->nDataLength) - nCount = GetData()->nDataLength; - - CString dest; - AllocCopy(dest, nCount, GetData()->nDataLength-nCount, 0); - return dest; - } - - CString SpanIncluding(LPCTSTR lpszCharSet) const // strspn equivalent - { - ATLASSERT(_IsValidString(lpszCharSet)); - return Left(_cstrspn(m_pchData, lpszCharSet)); - } - - CString SpanExcluding(LPCTSTR lpszCharSet) const // strcspn equivalent - { - ATLASSERT(_IsValidString(lpszCharSet)); - return Left(_cstrcspn(m_pchData, lpszCharSet)); - } - - // upper/lower/reverse conversion - void MakeUpper() - { - CopyBeforeWrite(); - CharUpper(m_pchData); - } - - void MakeLower() - { - CopyBeforeWrite(); - CharLower(m_pchData); - } - - void MakeReverse() - { - CopyBeforeWrite(); - _cstrrev(m_pchData); - } - - // trimming whitespace (either side) - void TrimRight() - { - CopyBeforeWrite(); - - // find beginning of trailing spaces by starting at beginning (DBCS aware) - LPTSTR lpsz = m_pchData; - LPTSTR lpszLast = NULL; - while (*lpsz != _T('\0')) - { - if (_cstrisspace(*lpsz)) - { - if (lpszLast == NULL) - lpszLast = lpsz; - } - else - { - lpszLast = NULL; - } - lpsz = ::CharNext(lpsz); - } - - if (lpszLast != NULL) - { - // truncate at trailing space start - *lpszLast = _T('\0'); - GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData); - } - } - - void TrimLeft() - { - CopyBeforeWrite(); - - // find first non-space character - LPCTSTR lpsz = m_pchData; - while (_cstrisspace(*lpsz)) - lpsz = ::CharNext(lpsz); - - // fix up data and length - int nDataLength = GetData()->nDataLength - (int)(DWORD_PTR)(lpsz - m_pchData); - SecureHelper::memmove_x(m_pchData, (GetData()->nAllocLength + 1) * sizeof(TCHAR), lpsz, (nDataLength + 1) * sizeof(TCHAR)); - GetData()->nDataLength = nDataLength; - } - - // remove continuous occurrences of chTarget starting from right - void TrimRight(TCHAR chTarget) - { - // find beginning of trailing matches - // by starting at beginning (DBCS aware) - - CopyBeforeWrite(); - LPTSTR lpsz = m_pchData; - LPTSTR lpszLast = NULL; - - while (*lpsz != _T('\0')) - { - if (*lpsz == chTarget) - { - if (lpszLast == NULL) - lpszLast = lpsz; - } - else - lpszLast = NULL; - lpsz = ::CharNext(lpsz); - } - - if (lpszLast != NULL) - { - // truncate at left-most matching character - *lpszLast = _T('\0'); - GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData); - } - } - - // remove continuous occcurrences of characters in passed string, starting from right - void TrimRight(LPCTSTR lpszTargetList) - { - // find beginning of trailing matches by starting at beginning (DBCS aware) - - CopyBeforeWrite(); - LPTSTR lpsz = m_pchData; - LPTSTR lpszLast = NULL; - - while (*lpsz != _T('\0')) - { - TCHAR* pNext = ::CharNext(lpsz); - if(pNext > lpsz + 1) - { - if (_cstrchr_db(lpszTargetList, *lpsz, *(lpsz + 1)) != NULL) - { - if (lpszLast == NULL) - lpszLast = lpsz; - } - else - { - lpszLast = NULL; - } - } - else - { - if (_cstrchr(lpszTargetList, *lpsz) != NULL) - { - if (lpszLast == NULL) - lpszLast = lpsz; - } - else - { - lpszLast = NULL; - } - } - - lpsz = pNext; - } - - if (lpszLast != NULL) - { - // truncate at left-most matching character - *lpszLast = _T('\0'); - GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData); - } - } - - // remove continuous occurrences of chTarget starting from left - void TrimLeft(TCHAR chTarget) - { - // find first non-matching character - - CopyBeforeWrite(); - LPCTSTR lpsz = m_pchData; - - while (chTarget == *lpsz) - lpsz = ::CharNext(lpsz); - - if (lpsz != m_pchData) - { - // fix up data and length - int nDataLength = GetData()->nDataLength - (int)(DWORD_PTR)(lpsz - m_pchData); - SecureHelper::memmove_x(m_pchData, (GetData()->nAllocLength + 1) * sizeof(TCHAR), lpsz, (nDataLength + 1) * sizeof(TCHAR)); - GetData()->nDataLength = nDataLength; - } - } - - // remove continuous occcurrences of characters in passed string, starting from left - void TrimLeft(LPCTSTR lpszTargets) - { - // if we're not trimming anything, we're not doing any work - if (SafeStrlen(lpszTargets) == 0) - return; - - CopyBeforeWrite(); - LPCTSTR lpsz = m_pchData; - - while (*lpsz != _T('\0')) - { - TCHAR* pNext = ::CharNext(lpsz); - if(pNext > lpsz + 1) - { - if (_cstrchr_db(lpszTargets, *lpsz, *(lpsz + 1)) == NULL) - break; - } - else - { - if (_cstrchr(lpszTargets, *lpsz) == NULL) - break; - } - lpsz = pNext; - } - - if (lpsz != m_pchData) - { - // fix up data and length - int nDataLength = GetData()->nDataLength - (int)(DWORD_PTR)(lpsz - m_pchData); - SecureHelper::memmove_x(m_pchData, (GetData()->nAllocLength + 1) * sizeof(TCHAR), lpsz, (nDataLength + 1) * sizeof(TCHAR)); - GetData()->nDataLength = nDataLength; - } - } - - // advanced manipulation - // replace occurrences of chOld with chNew - int Replace(TCHAR chOld, TCHAR chNew) - { - int nCount = 0; - - // short-circuit the nop case - if (chOld != chNew) - { - // otherwise modify each character that matches in the string - CopyBeforeWrite(); - LPTSTR psz = m_pchData; - LPTSTR pszEnd = psz + GetData()->nDataLength; - while (psz < pszEnd) - { - // replace instances of the specified character only - if (*psz == chOld) - { - *psz = chNew; - nCount++; - } - psz = ::CharNext(psz); - } - } - return nCount; - } - - // replace occurrences of substring lpszOld with lpszNew; - // empty lpszNew removes instances of lpszOld - int Replace(LPCTSTR lpszOld, LPCTSTR lpszNew) - { - // can't have empty or NULL lpszOld - - int nSourceLen = SafeStrlen(lpszOld); - if (nSourceLen == 0) - return 0; - int nReplacementLen = SafeStrlen(lpszNew); - - // loop once to figure out the size of the result string - int nCount = 0; - LPTSTR lpszStart = m_pchData; - LPTSTR lpszEnd = m_pchData + GetData()->nDataLength; - LPTSTR lpszTarget = NULL; - while (lpszStart < lpszEnd) - { - while ((lpszTarget = (TCHAR*)_cstrstr(lpszStart, lpszOld)) != NULL) - { - nCount++; - lpszStart = lpszTarget + nSourceLen; - } - lpszStart += lstrlen(lpszStart) + 1; - } - - // if any changes were made, make them - if (nCount > 0) - { - CopyBeforeWrite(); - - // if the buffer is too small, just allocate a new buffer (slow but sure) - int nOldLength = GetData()->nDataLength; - int nNewLength = nOldLength + (nReplacementLen - nSourceLen) * nCount; - if (GetData()->nAllocLength < nNewLength || GetData()->nRefs > 1) - { - CStringData* pOldData = GetData(); - LPTSTR pstr = m_pchData; - if(!AllocBuffer(nNewLength)) - return -1; - SecureHelper::memcpy_x(m_pchData, (nNewLength + 1) * sizeof(TCHAR), pstr, pOldData->nDataLength * sizeof(TCHAR)); - CString::Release(pOldData); - } - // else, we just do it in-place - lpszStart = m_pchData; - lpszEnd = m_pchData + GetData()->nDataLength; - - // loop again to actually do the work - while (lpszStart < lpszEnd) - { - while ((lpszTarget = (TCHAR*)_cstrstr(lpszStart, lpszOld)) != NULL) - { - int nBalance = nOldLength - ((int)(DWORD_PTR)(lpszTarget - m_pchData) + nSourceLen); - int cchBuffLen = GetData()->nAllocLength - (int)(DWORD_PTR)(lpszTarget - m_pchData); - SecureHelper::memmove_x(lpszTarget + nReplacementLen, (cchBuffLen - nReplacementLen + 1) * sizeof(TCHAR), lpszTarget + nSourceLen, nBalance * sizeof(TCHAR)); - SecureHelper::memcpy_x(lpszTarget, (cchBuffLen + 1) * sizeof(TCHAR), lpszNew, nReplacementLen * sizeof(TCHAR)); - lpszStart = lpszTarget + nReplacementLen; - lpszStart[nBalance] = _T('\0'); - nOldLength += (nReplacementLen - nSourceLen); - } - lpszStart += lstrlen(lpszStart) + 1; - } - ATLASSERT(m_pchData[nNewLength] == _T('\0')); - GetData()->nDataLength = nNewLength; - } - - return nCount; - } - - // remove occurrences of chRemove - int Remove(TCHAR chRemove) - { - CopyBeforeWrite(); - - LPTSTR pstrSource = m_pchData; - LPTSTR pstrDest = m_pchData; - LPTSTR pstrEnd = m_pchData + GetData()->nDataLength; - - while (pstrSource < pstrEnd) - { - if (*pstrSource != chRemove) - { - *pstrDest = *pstrSource; - pstrDest = ::CharNext(pstrDest); - } - pstrSource = ::CharNext(pstrSource); - } - *pstrDest = _T('\0'); - int nCount = (int)(DWORD_PTR)(pstrSource - pstrDest); - GetData()->nDataLength -= nCount; - - return nCount; - } - - // insert character at zero-based index; concatenates if index is past end of string - int Insert(int nIndex, TCHAR ch) - { - CopyBeforeWrite(); - - if (nIndex < 0) - nIndex = 0; - - int nNewLength = GetData()->nDataLength; - if (nIndex > nNewLength) - nIndex = nNewLength; - nNewLength++; - - if (GetData()->nAllocLength < nNewLength) - { - CStringData* pOldData = GetData(); - LPTSTR pstr = m_pchData; - if(!AllocBuffer(nNewLength)) - return -1; - SecureHelper::memcpy_x(m_pchData, (nNewLength + 1) * sizeof(TCHAR), pstr, (pOldData->nDataLength + 1) * sizeof(TCHAR)); - CString::Release(pOldData); - } - - // move existing bytes down - SecureHelper::memmove_x(m_pchData + nIndex + 1, (GetData()->nAllocLength - nIndex) * sizeof(TCHAR), m_pchData + nIndex, (nNewLength - nIndex) * sizeof(TCHAR)); - m_pchData[nIndex] = ch; - GetData()->nDataLength = nNewLength; - - return nNewLength; - } - - // insert substring at zero-based index; concatenates if index is past end of string - int Insert(int nIndex, LPCTSTR pstr) - { - if (nIndex < 0) - nIndex = 0; - - int nInsertLength = SafeStrlen(pstr); - int nNewLength = GetData()->nDataLength; - if (nInsertLength > 0) - { - CopyBeforeWrite(); - if (nIndex > nNewLength) - nIndex = nNewLength; - nNewLength += nInsertLength; - - if (GetData()->nAllocLength < nNewLength) - { - CStringData* pOldData = GetData(); - LPTSTR pstr = m_pchData; - if(!AllocBuffer(nNewLength)) - return -1; - SecureHelper::memcpy_x(m_pchData, (nNewLength + 1) * sizeof(TCHAR), pstr, (pOldData->nDataLength + 1) * sizeof(TCHAR)); - CString::Release(pOldData); - } - - // move existing bytes down - SecureHelper::memmove_x(m_pchData + nIndex + nInsertLength, (GetData()->nAllocLength + 1 - nIndex - nInsertLength) * sizeof(TCHAR), m_pchData + nIndex, (nNewLength - nIndex - nInsertLength + 1) * sizeof(TCHAR)); - SecureHelper::memcpy_x(m_pchData + nIndex, (GetData()->nAllocLength + 1 - nIndex) * sizeof(TCHAR), pstr, nInsertLength * sizeof(TCHAR)); - GetData()->nDataLength = nNewLength; - } - - return nNewLength; - } - - // delete nCount characters starting at zero-based index - int Delete(int nIndex, int nCount = 1) - { - if (nIndex < 0) - nIndex = 0; - int nLength = GetData()->nDataLength; - if (nCount > 0 && nIndex < nLength) - { - if((nIndex + nCount) > nLength) - nCount = nLength - nIndex; - CopyBeforeWrite(); - int nBytesToCopy = nLength - (nIndex + nCount) + 1; - - SecureHelper::memmove_x(m_pchData + nIndex, (GetData()->nAllocLength + 1 - nIndex) * sizeof(TCHAR), m_pchData + nIndex + nCount, nBytesToCopy * sizeof(TCHAR)); - nLength -= nCount; - GetData()->nDataLength = nLength; - } - - return nLength; - } - - // searching (return starting index, or -1 if not found) - // look for a single character match - int Find(TCHAR ch) const // like "C" strchr - { - return Find(ch, 0); - } - - int ReverseFind(TCHAR ch) const - { - // find last single character - LPCTSTR lpsz = _cstrrchr(m_pchData, (_TUCHAR)ch); - - // return -1 if not found, distance from beginning otherwise - return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData); - } - - int Find(TCHAR ch, int nStart) const // starting at index - { - int nLength = GetData()->nDataLength; - if (nStart < 0 || nStart >= nLength) - return -1; - - // find first single character - LPCTSTR lpsz = _cstrchr(m_pchData + nStart, (_TUCHAR)ch); - - // return -1 if not found and index otherwise - return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData); - } - - int FindOneOf(LPCTSTR lpszCharSet) const - { - ATLASSERT(_IsValidString(lpszCharSet)); - LPCTSTR lpsz = _cstrpbrk(m_pchData, lpszCharSet); - return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData); - } - - // look for a specific sub-string - // find a sub-string (like strstr) - int Find(LPCTSTR lpszSub) const // like "C" strstr - { - return Find(lpszSub, 0); - } - - int Find(LPCTSTR lpszSub, int nStart) const // starting at index - { - ATLASSERT(_IsValidString(lpszSub)); - - int nLength = GetData()->nDataLength; - if (nStart < 0 || nStart > nLength) - return -1; - - // find first matching substring - LPCTSTR lpsz = _cstrstr(m_pchData + nStart, lpszSub); - - // return -1 for not found, distance from beginning otherwise - return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData); - } - - // Concatentation for non strings - CString& Append(int n) - { - const int cchBuff = 12; - TCHAR szBuffer[cchBuff] = { 0 }; - SecureHelper::wsprintf_x(szBuffer, cchBuff, _T("%d"), n); - ConcatInPlace(SafeStrlen(szBuffer), szBuffer); - return *this; - } - - // simple formatting - // formatting (using wsprintf style formatting) - BOOL __cdecl Format(LPCTSTR lpszFormat, ...) - { - ATLASSERT(_IsValidString(lpszFormat)); - - va_list argList; - va_start(argList, lpszFormat); - BOOL bRet = FormatV(lpszFormat, argList); - va_end(argList); - return bRet; - } - - BOOL __cdecl Format(UINT nFormatID, ...) - { - CString strFormat; - BOOL bRet = strFormat.LoadString(nFormatID); - ATLASSERT(bRet != 0); - - va_list argList; - va_start(argList, nFormatID); - bRet = FormatV(strFormat, argList); - va_end(argList); - return bRet; - } - - BOOL FormatV(LPCTSTR lpszFormat, va_list argList) - { - ATLASSERT(_IsValidString(lpszFormat)); - - enum _FormatModifiers - { - FORCE_ANSI = 0x10000, - FORCE_UNICODE = 0x20000, - FORCE_INT64 = 0x40000 - }; - - va_list argListSave = argList; - - // make a guess at the maximum length of the resulting string - int nMaxLen = 0; - for (LPCTSTR lpsz = lpszFormat; *lpsz != _T('\0'); lpsz = ::CharNext(lpsz)) - { - // handle '%' character, but watch out for '%%' - if (*lpsz != _T('%') || *(lpsz = ::CharNext(lpsz)) == _T('%')) - { - nMaxLen += (int)(::CharNext(lpsz) - lpsz); - continue; - } - - int nItemLen = 0; - - // handle '%' character with format - int nWidth = 0; - for (; *lpsz != _T('\0'); lpsz = ::CharNext(lpsz)) - { - // check for valid flags - if (*lpsz == _T('#')) - nMaxLen += 2; // for '0x' - else if (*lpsz == _T('*')) - nWidth = va_arg(argList, int); - else if (*lpsz == _T('-') || *lpsz == _T('+') || *lpsz == _T('0') || *lpsz == _T(' ')) - ; - else // hit non-flag character - break; - } - // get width and skip it - if (nWidth == 0) - { - // width indicated by - nWidth = _cstrtoi(lpsz); - for (; *lpsz != _T('\0') && _cstrisdigit(*lpsz); lpsz = ::CharNext(lpsz)) - ; - } - ATLASSERT(nWidth >= 0); - - int nPrecision = 0; - if (*lpsz == _T('.')) - { - // skip past '.' separator (width.precision) - lpsz = ::CharNext(lpsz); - - // get precision and skip it - if (*lpsz == _T('*')) - { - nPrecision = va_arg(argList, int); - lpsz = ::CharNext(lpsz); - } - else - { - nPrecision = _cstrtoi(lpsz); - for (; *lpsz != _T('\0') && _cstrisdigit(*lpsz); lpsz = ::CharNext(lpsz)) - ; - } - ATLASSERT(nPrecision >= 0); - } - - // should be on type modifier or specifier - int nModifier = 0; - if(lpsz[0] == _T('I') && lpsz[1] == _T('6') && lpsz[2] == _T('4')) - { - lpsz += 3; - nModifier = FORCE_INT64; - } - else - { - switch (*lpsz) - { - // modifiers that affect size - case _T('h'): - nModifier = FORCE_ANSI; - lpsz = ::CharNext(lpsz); - break; - case _T('l'): - nModifier = FORCE_UNICODE; - lpsz = ::CharNext(lpsz); - break; - - // modifiers that do not affect size - case _T('F'): - case _T('N'): - case _T('L'): - lpsz = ::CharNext(lpsz); - break; - } - } - - // now should be on specifier - switch (*lpsz | nModifier) - { - // single characters - case _T('c'): - case _T('C'): - nItemLen = 2; - va_arg(argList, TCHAR); - break; - case _T('c') | FORCE_ANSI: - case _T('C') | FORCE_ANSI: - nItemLen = 2; - va_arg(argList, char); - break; - case _T('c') | FORCE_UNICODE: - case _T('C') | FORCE_UNICODE: - nItemLen = 2; - va_arg(argList, WCHAR); - break; - - // strings - case _T('s'): - { - LPCTSTR pstrNextArg = va_arg(argList, LPCTSTR); - if (pstrNextArg == NULL) - { - nItemLen = 6; // "(null)" - } - else - { - nItemLen = lstrlen(pstrNextArg); - nItemLen = max(1, nItemLen); - } - break; - } - - case _T('S'): - { -#ifndef _UNICODE - LPWSTR pstrNextArg = va_arg(argList, LPWSTR); - if (pstrNextArg == NULL) - { - nItemLen = 6; // "(null)" - } - else - { - nItemLen = (int)wcslen(pstrNextArg); - nItemLen = max(1, nItemLen); - } -#else // _UNICODE - LPCSTR pstrNextArg = va_arg(argList, LPCSTR); - if (pstrNextArg == NULL) - { - nItemLen = 6; // "(null)" - } - else - { -#if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) - nItemLen = ATL::lstrlenA(pstrNextArg); -#else - nItemLen = lstrlenA(pstrNextArg); -#endif - nItemLen = max(1, nItemLen); - } -#endif // _UNICODE - break; - } - - case _T('s') | FORCE_ANSI: - case _T('S') | FORCE_ANSI: - { - LPCSTR pstrNextArg = va_arg(argList, LPCSTR); - if (pstrNextArg == NULL) - { - nItemLen = 6; // "(null)" - } - else - { -#if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) - nItemLen = ATL::lstrlenA(pstrNextArg); -#else - nItemLen = lstrlenA(pstrNextArg); -#endif - nItemLen = max(1, nItemLen); - } - break; - } - - case _T('s') | FORCE_UNICODE: - case _T('S') | FORCE_UNICODE: - { - LPWSTR pstrNextArg = va_arg(argList, LPWSTR); - if (pstrNextArg == NULL) - { - nItemLen = 6; // "(null)" - } - else - { - nItemLen = (int)wcslen(pstrNextArg); - nItemLen = max(1, nItemLen); - } - break; - } - } - - // adjust nItemLen for strings - if (nItemLen != 0) - { - nItemLen = max(nItemLen, nWidth); - if (nPrecision != 0) - nItemLen = min(nItemLen, nPrecision); - } - else - { - switch (*lpsz) - { - // integers - case _T('d'): - case _T('i'): - case _T('u'): - case _T('x'): - case _T('X'): - case _T('o'): - if (nModifier & FORCE_INT64) - va_arg(argList, __int64); - else - va_arg(argList, int); - nItemLen = 32; - nItemLen = max(nItemLen, nWidth + nPrecision); - break; - -#ifndef _ATL_USE_CSTRING_FLOAT - case _T('e'): - case _T('E'): - case _T('f'): - case _T('g'): - case _T('G'): - ATLASSERT(!"Floating point (%%e, %%E, %%f, %%g, and %%G) is not supported by the WTL::CString class."); -#ifndef _DEBUG - ::OutputDebugString(_T("Floating point (%%e, %%f, %%g, and %%G) is not supported by the WTL::CString class.")); -#ifndef _WIN32_WCE - ::DebugBreak(); -#else // CE specific - DebugBreak(); -#endif // _WIN32_WCE -#endif // !_DEBUG - break; -#else // _ATL_USE_CSTRING_FLOAT - case _T('e'): - case _T('E'): - case _T('g'): - case _T('G'): - va_arg(argList, double); - nItemLen = 128; - nItemLen = max(nItemLen, nWidth + nPrecision); - break; - case _T('f'): - { - double f = va_arg(argList, double); - // 312 == strlen("-1+(309 zeroes).") - // 309 zeroes == max precision of a double - // 6 == adjustment in case precision is not specified, - // which means that the precision defaults to 6 - int cchLen = max(nWidth, 312 + nPrecision + 6); - CTempBuffer buff; - LPTSTR pszTemp = buff.Allocate(cchLen); - if(pszTemp != NULL) - { - SecureHelper::sprintf_x(pszTemp, cchLen, _T("%*.*f"), nWidth, nPrecision + 6, f); - nItemLen = (int)_tcslen(pszTemp); - } - else - { - nItemLen = cchLen; - } - } - break; -#endif // _ATL_USE_CSTRING_FLOAT - - case _T('p'): - va_arg(argList, void*); - nItemLen = 32; - nItemLen = max(nItemLen, nWidth + nPrecision); - break; - - // no output - case _T('n'): - va_arg(argList, int*); - break; - - default: - ATLASSERT(FALSE); // unknown formatting option - } - } - - // adjust nMaxLen for output nItemLen - nMaxLen += nItemLen; - } - - if(GetBuffer(nMaxLen) == NULL) - return FALSE; -#ifndef _ATL_USE_CSTRING_FLOAT - int nRet = SecureHelper::wvsprintf_x(m_pchData, GetAllocLength() + 1, lpszFormat, argListSave); -#else // _ATL_USE_CSTRING_FLOAT - int nRet = SecureHelper::vsprintf_x(m_pchData, GetAllocLength() + 1, lpszFormat, argListSave); -#endif // _ATL_USE_CSTRING_FLOAT - nRet; // ref - ATLASSERT(nRet <= GetAllocLength()); - ReleaseBuffer(); - - va_end(argListSave); - return TRUE; - } - - // formatting for localization (uses FormatMessage API) - // formatting (using FormatMessage style formatting) - BOOL __cdecl FormatMessage(LPCTSTR lpszFormat, ...) - { - // format message into temporary buffer lpszTemp - va_list argList; - va_start(argList, lpszFormat); - LPTSTR lpszTemp; - BOOL bRet = TRUE; - - if (::FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, - lpszFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0 || lpszTemp == NULL) - bRet = FALSE; - - // assign lpszTemp into the resulting string and free the temporary - *this = lpszTemp; - LocalFree(lpszTemp); - va_end(argList); - return bRet; - } - - BOOL __cdecl FormatMessage(UINT nFormatID, ...) - { - // get format string from string table - CString strFormat; - BOOL bRetTmp = strFormat.LoadString(nFormatID); - bRetTmp; // ref - ATLASSERT(bRetTmp != 0); - - // format message into temporary buffer lpszTemp - va_list argList; - va_start(argList, nFormatID); - LPTSTR lpszTemp; - BOOL bRet = TRUE; - - if (::FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, - strFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0 || lpszTemp == NULL) - bRet = FALSE; - - // assign lpszTemp into the resulting string and free lpszTemp - *this = lpszTemp; - LocalFree(lpszTemp); - va_end(argList); - return bRet; - } - - // Windows support - BOOL LoadString(UINT nID) // load from string resource (255 chars max.) - { -#ifdef _UNICODE - const int CHAR_FUDGE = 1; // one TCHAR unused is good enough -#else - const int CHAR_FUDGE = 2; // two BYTES unused for case of DBC last char -#endif - - // try fixed buffer first (to avoid wasting space in the heap) - TCHAR szTemp[256]; - int nCount = sizeof(szTemp) / sizeof(szTemp[0]); - int nLen = _LoadString(nID, szTemp, nCount); - if (nCount - nLen > CHAR_FUDGE) - { - *this = szTemp; - return (nLen > 0); - } - - // try buffer size of 512, then larger size until entire string is retrieved - int nSize = 256; - do - { - nSize += 256; - LPTSTR lpstr = GetBuffer(nSize - 1); - if(lpstr == NULL) - { - nLen = 0; - break; - } - nLen = _LoadString(nID, lpstr, nSize); - } while (nSize - nLen <= CHAR_FUDGE); - ReleaseBuffer(); - - return (nLen > 0); - } - -#ifndef _UNICODE - // ANSI <-> OEM support (convert string in place) - void AnsiToOem() - { - CopyBeforeWrite(); - ::AnsiToOem(m_pchData, m_pchData); - } - - void OemToAnsi() - { - CopyBeforeWrite(); - ::OemToAnsi(m_pchData, m_pchData); - } -#endif - -#ifndef _ATL_NO_COM - // OLE BSTR support (use for OLE automation) - BSTR AllocSysString() const - { -#if defined(_UNICODE) || defined(OLE2ANSI) - BSTR bstr = ::SysAllocStringLen(m_pchData, GetData()->nDataLength); -#else - int nLen = MultiByteToWideChar(CP_ACP, 0, m_pchData, - GetData()->nDataLength, NULL, NULL); - BSTR bstr = ::SysAllocStringLen(NULL, nLen); - if(bstr != NULL) - MultiByteToWideChar(CP_ACP, 0, m_pchData, GetData()->nDataLength, bstr, nLen); -#endif - return bstr; - } - - BSTR SetSysString(BSTR* pbstr) const - { -#if defined(_UNICODE) || defined(OLE2ANSI) - ::SysReAllocStringLen(pbstr, m_pchData, GetData()->nDataLength); -#else - int nLen = MultiByteToWideChar(CP_ACP, 0, m_pchData, - GetData()->nDataLength, NULL, NULL); - if(::SysReAllocStringLen(pbstr, NULL, nLen)) - MultiByteToWideChar(CP_ACP, 0, m_pchData, GetData()->nDataLength, *pbstr, nLen); -#endif - ATLASSERT(*pbstr != NULL); - return *pbstr; - } -#endif // !_ATL_NO_COM - - // Access to string implementation buffer as "C" character array - LPTSTR GetBuffer(int nMinBufLength) - { - ATLASSERT(nMinBufLength >= 0); - - if (GetData()->nRefs > 1 || nMinBufLength > GetData()->nAllocLength) - { - // we have to grow the buffer - CStringData* pOldData = GetData(); - int nOldLen = GetData()->nDataLength; // AllocBuffer will tromp it - if (nMinBufLength < nOldLen) - nMinBufLength = nOldLen; - - if(!AllocBuffer(nMinBufLength)) - return NULL; - - SecureHelper::memcpy_x(m_pchData, (nMinBufLength + 1) * sizeof(TCHAR), pOldData->data(), (nOldLen + 1) * sizeof(TCHAR)); - GetData()->nDataLength = nOldLen; - CString::Release(pOldData); - } - ATLASSERT(GetData()->nRefs <= 1); - - // return a pointer to the character storage for this string - ATLASSERT(m_pchData != NULL); - return m_pchData; - } - - void ReleaseBuffer(int nNewLength = -1) - { - CopyBeforeWrite(); // just in case GetBuffer was not called - - if (nNewLength == -1) - nNewLength = lstrlen(m_pchData); // zero terminated - - ATLASSERT(nNewLength <= GetData()->nAllocLength); - GetData()->nDataLength = nNewLength; - m_pchData[nNewLength] = _T('\0'); - } - - LPTSTR GetBufferSetLength(int nNewLength) - { - ATLASSERT(nNewLength >= 0); - - if(GetBuffer(nNewLength) == NULL) - return NULL; - - GetData()->nDataLength = nNewLength; - m_pchData[nNewLength] = _T('\0'); - return m_pchData; - } - - void FreeExtra() - { - ATLASSERT(GetData()->nDataLength <= GetData()->nAllocLength); - if (GetData()->nDataLength != GetData()->nAllocLength) - { - CStringData* pOldData = GetData(); - if(AllocBuffer(GetData()->nDataLength)) - { - SecureHelper::memcpy_x(m_pchData, (GetData()->nAllocLength + 1) * sizeof(TCHAR), pOldData->data(), pOldData->nDataLength * sizeof(TCHAR)); - ATLASSERT(m_pchData[GetData()->nDataLength] == _T('\0')); - CString::Release(pOldData); - } - } - ATLASSERT(GetData() != NULL); - } - - // Use LockBuffer/UnlockBuffer to turn refcounting off - LPTSTR LockBuffer() - { - LPTSTR lpsz = GetBuffer(0); - if(lpsz != NULL) - GetData()->nRefs = -1; - return lpsz; - } - - void UnlockBuffer() - { - ATLASSERT(GetData()->nRefs == -1); - if (GetData() != _atltmpDataNil) - GetData()->nRefs = 1; - } - -// Implementation -public: - ~CString() // free any attached data - { - if (GetData() != _atltmpDataNil) - { - if (InterlockedDecrement(&GetData()->nRefs) <= 0) - delete[] (BYTE*)GetData(); - } - } - - int GetAllocLength() const - { - return GetData()->nAllocLength; - } - - static BOOL __stdcall _IsValidString(LPCTSTR lpsz, int /*nLength*/ = -1) - { - return (lpsz != NULL) ? TRUE : FALSE; - } - -protected: - LPTSTR m_pchData; // pointer to ref counted string data - - // implementation helpers - CStringData* GetData() const - { - ATLASSERT(m_pchData != NULL); - return ((CStringData*)m_pchData) - 1; - } - - void Init() - { - m_pchData = _GetEmptyString().m_pchData; - } - - BOOL AllocCopy(CString& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const - { - // will clone the data attached to this string - // allocating 'nExtraLen' characters - // Places results in uninitialized string 'dest' - // Will copy the part or all of original data to start of new string - - BOOL bRet = FALSE; - int nNewLen = nCopyLen + nExtraLen; - if (nNewLen == 0) - { - dest.Init(); - bRet = TRUE; - } - else if(nNewLen >= nCopyLen) - { - if(dest.AllocBuffer(nNewLen)) - { - SecureHelper::memcpy_x(dest.m_pchData, (nNewLen + 1) * sizeof(TCHAR), m_pchData + nCopyIndex, nCopyLen * sizeof(TCHAR)); - bRet = TRUE; - } - } - - return bRet; - } - - // always allocate one extra character for '\0' termination - // assumes [optimistically] that data length will equal allocation length - BOOL AllocBuffer(int nLen) - { - ATLASSERT(nLen >= 0); - ATLASSERT(nLen <= INT_MAX - 1); // max size (enough room for 1 extra) - - if (nLen == 0) - { - Init(); - } - else - { - CStringData* pData = NULL; - ATLTRY(pData = (CStringData*)new BYTE[sizeof(CStringData) + (nLen + 1) * sizeof(TCHAR)]); - if(pData == NULL) - return FALSE; - - pData->nRefs = 1; - pData->data()[nLen] = _T('\0'); - pData->nDataLength = nLen; - pData->nAllocLength = nLen; - m_pchData = pData->data(); - } - - return TRUE; - } - - // Assignment operators - // All assign a new value to the string - // (a) first see if the buffer is big enough - // (b) if enough room, copy on top of old buffer, set size and type - // (c) otherwise free old string data, and create a new one - // - // All routines return the new string (but as a 'const CString&' so that - // assigning it again will cause a copy, eg: s1 = s2 = "hi there". - // - void AssignCopy(int nSrcLen, LPCTSTR lpszSrcData) - { - if(AllocBeforeWrite(nSrcLen)) - { - SecureHelper::memcpy_x(m_pchData, (nSrcLen + 1) * sizeof(TCHAR), lpszSrcData, nSrcLen * sizeof(TCHAR)); - GetData()->nDataLength = nSrcLen; - m_pchData[nSrcLen] = _T('\0'); - } - } - - // Concatenation - // NOTE: "operator +" is done as friend functions for simplicity - // There are three variants: - // CString + CString - // and for ? = TCHAR, LPCTSTR - // CString + ? - // ? + CString - BOOL ConcatCopy(int nSrc1Len, LPCTSTR lpszSrc1Data, int nSrc2Len, LPCTSTR lpszSrc2Data) - { - // -- master concatenation routine - // Concatenate two sources - // -- assume that 'this' is a new CString object - - BOOL bRet = TRUE; - int nNewLen = nSrc1Len + nSrc2Len; - if(nNewLen < nSrc1Len || nNewLen < nSrc2Len) - { - bRet = FALSE; - } - else if(nNewLen != 0) - { - bRet = AllocBuffer(nNewLen); - if (bRet) - { - SecureHelper::memcpy_x(m_pchData, (nNewLen + 1) * sizeof(TCHAR), lpszSrc1Data, nSrc1Len * sizeof(TCHAR)); - SecureHelper::memcpy_x(m_pchData + nSrc1Len, (nNewLen + 1 - nSrc1Len) * sizeof(TCHAR), lpszSrc2Data, nSrc2Len * sizeof(TCHAR)); - } - } - return bRet; - } - - void ConcatInPlace(int nSrcLen, LPCTSTR lpszSrcData) - { - // -- the main routine for += operators - - // concatenating an empty string is a no-op! - if (nSrcLen == 0) - return; - - // if the buffer is too small, or we have a width mis-match, just - // allocate a new buffer (slow but sure) - if (GetData()->nRefs > 1 || GetData()->nDataLength + nSrcLen > GetData()->nAllocLength) - { - // we have to grow the buffer, use the ConcatCopy routine - CStringData* pOldData = GetData(); - if (ConcatCopy(GetData()->nDataLength, m_pchData, nSrcLen, lpszSrcData)) - { - ATLASSERT(pOldData != NULL); - CString::Release(pOldData); - } - } - else - { - // fast concatenation when buffer big enough - SecureHelper::memcpy_x(m_pchData + GetData()->nDataLength, (GetData()->nAllocLength + 1) * sizeof(TCHAR), lpszSrcData, nSrcLen * sizeof(TCHAR)); - GetData()->nDataLength += nSrcLen; - ATLASSERT(GetData()->nDataLength <= GetData()->nAllocLength); - m_pchData[GetData()->nDataLength] = _T('\0'); - } - } - - void CopyBeforeWrite() - { - if (GetData()->nRefs > 1) - { - CStringData* pData = GetData(); - Release(); - if(AllocBuffer(pData->nDataLength)) - SecureHelper::memcpy_x(m_pchData, (GetData()->nAllocLength + 1) * sizeof(TCHAR), pData->data(), (pData->nDataLength + 1) * sizeof(TCHAR)); - } - ATLASSERT(GetData()->nRefs <= 1); - } - - BOOL AllocBeforeWrite(int nLen) - { - BOOL bRet = TRUE; - if (GetData()->nRefs > 1 || nLen > GetData()->nAllocLength) - { - Release(); - bRet = AllocBuffer(nLen); - } - ATLASSERT(GetData()->nRefs <= 1); - return bRet; - } - - void Release() - { - if (GetData() != _atltmpDataNil) - { - ATLASSERT(GetData()->nRefs != 0); - if (InterlockedDecrement(&GetData()->nRefs) <= 0) - delete[] (BYTE*)GetData(); - Init(); - } - } - - static void PASCAL Release(CStringData* pData) - { - if (pData != _atltmpDataNil) - { - ATLASSERT(pData->nRefs != 0); - if (InterlockedDecrement(&pData->nRefs) <= 0) - delete[] (BYTE*)pData; - } - } - - static int PASCAL SafeStrlen(LPCTSTR lpsz) - { - return (lpsz == NULL) ? 0 : lstrlen(lpsz); - } - - static int __stdcall _LoadString(UINT nID, LPTSTR lpszBuf, UINT nMaxBuf) - { -#ifdef _DEBUG - // LoadString without annoying warning from the Debug kernel if the - // segment containing the string is not present - if (::FindResource(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE((nID >> 4) + 1), RT_STRING) == NULL) - { - lpszBuf[0] = _T('\0'); - return 0; // not found - } -#endif // _DEBUG - - int nLen = ::LoadString(ModuleHelper::GetResourceInstance(), nID, lpszBuf, nMaxBuf); - if (nLen == 0) - lpszBuf[0] = _T('\0'); - - return nLen; - } - - static const CString& __stdcall _GetEmptyString() - { - return *(CString*)&_atltmpPchNil; - } - -// CString conversion helpers - static int __cdecl _wcstombsz(char* mbstr, const wchar_t* wcstr, size_t count) - { - if (count == 0 && mbstr != NULL) - return 0; - - int result = ::WideCharToMultiByte(CP_ACP, 0, wcstr, -1, mbstr, (int)count, NULL, NULL); - ATLASSERT(mbstr == NULL || result <= (int)count); - if (result > 0) - mbstr[result - 1] = 0; - return result; - } - - static int __cdecl _mbstowcsz(wchar_t* wcstr, const char* mbstr, size_t count) - { - if (count == 0 && wcstr != NULL) - return 0; - - int result = ::MultiByteToWideChar(CP_ACP, 0, mbstr, -1, wcstr, (int)count); - ATLASSERT(wcstr == NULL || result <= (int)count); - if (result > 0) - wcstr[result - 1] = 0; - return result; - } - -// Helpers to avoid CRT startup code -#ifdef _ATL_MIN_CRT - static const TCHAR* _cstrchr(const TCHAR* p, TCHAR ch) - { - // strchr for '\0' should succeed - while (*p != 0) - { - if (*p == ch) - break; - p = ::CharNext(p); - } - return (*p == ch) ? p : NULL; - } - - static const TCHAR* _cstrrchr(const TCHAR* p, TCHAR ch) - { - const TCHAR* lpsz = NULL; - while (*p != 0) - { - if (*p == ch) - lpsz = p; - p = ::CharNext(p); - } - return lpsz; - } - - static TCHAR* _cstrrev(TCHAR* pStr) - { - // optimize NULL, zero-length, and single-char case - if ((pStr == NULL) || (pStr[0] == _T('\0')) || (pStr[1] == _T('\0'))) - return pStr; - - TCHAR* p = pStr; - - while (*p != 0) - { - TCHAR* pNext = ::CharNext(p); - if(pNext > p + 1) - { - char p1 = *(char*)p; - *(char*)p = *(char*)(p + 1); - *(char*)(p + 1) = p1; - } - p = pNext; - } - - p--; - TCHAR* q = pStr; - - while (q < p) - { - TCHAR t = *q; - *q = *p; - *p = t; - q++; - p--; - } - return pStr; - } - - static const TCHAR* _cstrstr(const TCHAR* pStr, const TCHAR* pCharSet) - { - int nLen = lstrlen(pCharSet); - if (nLen == 0) - return (TCHAR*)pStr; - - const TCHAR* pRet = NULL; - const TCHAR* pCur = pStr; - while((pCur = _cstrchr(pCur, *pCharSet)) != NULL) - { - if(memcmp(pCur, pCharSet, nLen * sizeof(TCHAR)) == 0) - { - pRet = pCur; - break; - } - pCur = ::CharNext(pCur); - } - return pRet; - } - - static int _cstrspn(const TCHAR* pStr, const TCHAR* pCharSet) - { - int nRet = 0; - const TCHAR* p = pStr; - while (*p != 0) - { - const TCHAR* pNext = ::CharNext(p); - if(pNext > p + 1) - { - if(_cstrchr_db(pCharSet, *p, *(p + 1)) == NULL) - break; - nRet += 2; - } - else - { - if(_cstrchr(pCharSet, *p) == NULL) - break; - nRet++; - } - p = pNext; - } - return nRet; - } - - static int _cstrcspn(const TCHAR* pStr, const TCHAR* pCharSet) - { - int nRet = 0; - TCHAR* p = (TCHAR*)pStr; - while (*p != 0) - { - TCHAR* pNext = ::CharNext(p); - if(pNext > p + 1) - { - if(_cstrchr_db(pCharSet, *p, *(p + 1)) != NULL) - break; - nRet += 2; - } - else - { - if(_cstrchr(pCharSet, *p) != NULL) - break; - nRet++; - } - p = pNext; - } - return nRet; - } - - static const TCHAR* _cstrpbrk(const TCHAR* p, const TCHAR* lpszCharSet) - { - int n = _cstrcspn(p, lpszCharSet); - return (p[n] != 0) ? &p[n] : NULL; - } - - static int _cstrisdigit(TCHAR ch) - { - WORD type; - GetStringTypeEx(GetThreadLocale(), CT_CTYPE1, &ch, 1, &type); - return (type & C1_DIGIT) == C1_DIGIT; - } - - static int _cstrisspace(TCHAR ch) - { - WORD type; - GetStringTypeEx(GetThreadLocale(), CT_CTYPE1, &ch, 1, &type); - return (type & C1_SPACE) == C1_SPACE; - } - - static int _cstrcmp(const TCHAR* pstrOne, const TCHAR* pstrOther) - { - return lstrcmp(pstrOne, pstrOther); - } - - static int _cstrcmpi(const TCHAR* pstrOne, const TCHAR* pstrOther) - { - return lstrcmpi(pstrOne, pstrOther); - } - - static int _cstrcoll(const TCHAR* pstrOne, const TCHAR* pstrOther) - { - int nRet = CompareString(GetThreadLocale(), 0, pstrOne, -1, pstrOther, -1); - ATLASSERT(nRet != 0); - return nRet - 2; // convert to strcmp convention - } - - static int _cstrcolli(const TCHAR* pstrOne, const TCHAR* pstrOther) - { - int nRet = CompareString(GetThreadLocale(), NORM_IGNORECASE, pstrOne, -1, pstrOther, -1); - ATLASSERT(nRet != 0); - return nRet - 2; // convert to strcmp convention - } - - static int _cstrtoi(const TCHAR* nptr) - { - int c; // current char - int total; // current total - int sign; // if '-', then negative, otherwise positive - - while (_cstrisspace(*nptr)) - ++nptr; - - c = (int)(_TUCHAR)*nptr++; - sign = c; // save sign indication - if (c == _T('-') || c == _T('+')) - c = (int)(_TUCHAR)*nptr++; // skip sign - - total = 0; - - while (_cstrisdigit((TCHAR)c)) - { - total = 10 * total + (c - '0'); // accumulate digit - c = (int)(_TUCHAR)*nptr++; // get next char - } - - if (sign == '-') - return -total; - else - return total; // return result, negated if necessary - } -#else // !_ATL_MIN_CRT - static const TCHAR* _cstrchr(const TCHAR* p, TCHAR ch) - { - return _tcschr(p, ch); - } - - static const TCHAR* _cstrrchr(const TCHAR* p, TCHAR ch) - { - return _tcsrchr(p, ch); - } - - static TCHAR* _cstrrev(TCHAR* pStr) - { - return _tcsrev(pStr); - } - - static const TCHAR* _cstrstr(const TCHAR* pStr, const TCHAR* pCharSet) - { - return _tcsstr(pStr, pCharSet); - } - - static int _cstrspn(const TCHAR* pStr, const TCHAR* pCharSet) - { - return (int)_tcsspn(pStr, pCharSet); - } - - static int _cstrcspn(const TCHAR* pStr, const TCHAR* pCharSet) - { - return (int)_tcscspn(pStr, pCharSet); - } - - static const TCHAR* _cstrpbrk(const TCHAR* p, const TCHAR* lpszCharSet) - { - return _tcspbrk(p, lpszCharSet); - } - - static int _cstrisdigit(TCHAR ch) - { - return _istdigit(ch); - } - - static int _cstrisspace(TCHAR ch) - { - return _istspace((_TUCHAR)ch); - } - - static int _cstrcmp(const TCHAR* pstrOne, const TCHAR* pstrOther) - { - return _tcscmp(pstrOne, pstrOther); - } - - static int _cstrcmpi(const TCHAR* pstrOne, const TCHAR* pstrOther) - { - return _tcsicmp(pstrOne, pstrOther); - } - -#ifndef _WIN32_WCE - static int _cstrcoll(const TCHAR* pstrOne, const TCHAR* pstrOther) - { - return _tcscoll(pstrOne, pstrOther); - } - - static int _cstrcolli(const TCHAR* pstrOne, const TCHAR* pstrOther) - { - return _tcsicoll(pstrOne, pstrOther); - } -#endif // !_WIN32_WCE - - static int _cstrtoi(const TCHAR* nptr) - { - return _ttoi(nptr); - } -#endif // !_ATL_MIN_CRT - - static const TCHAR* _cstrchr_db(const TCHAR* p, TCHAR ch1, TCHAR ch2) - { - const TCHAR* lpsz = NULL; - while (*p != 0) - { - if (*p == ch1 && *(p + 1) == ch2) - { - lpsz = p; - break; - } - p = ::CharNext(p); - } - return lpsz; - } -}; - - -// Compare helpers - -inline bool __stdcall operator ==(const CString& s1, const CString& s2) -{ return s1.Compare(s2) == 0; } - -inline bool __stdcall operator ==(const CString& s1, LPCTSTR s2) -{ return s1.Compare(s2) == 0; } - -inline bool __stdcall operator ==(LPCTSTR s1, const CString& s2) -{ return s2.Compare(s1) == 0; } - -inline bool __stdcall operator !=(const CString& s1, const CString& s2) -{ return s1.Compare(s2) != 0; } - -inline bool __stdcall operator !=(const CString& s1, LPCTSTR s2) -{ return s1.Compare(s2) != 0; } - -inline bool __stdcall operator !=(LPCTSTR s1, const CString& s2) -{ return s2.Compare(s1) != 0; } - -inline bool __stdcall operator <(const CString& s1, const CString& s2) -{ return s1.Compare(s2) < 0; } - -inline bool __stdcall operator <(const CString& s1, LPCTSTR s2) -{ return s1.Compare(s2) < 0; } - -inline bool __stdcall operator <(LPCTSTR s1, const CString& s2) -{ return s2.Compare(s1) > 0; } - -inline bool __stdcall operator >(const CString& s1, const CString& s2) -{ return s1.Compare(s2) > 0; } - -inline bool __stdcall operator >(const CString& s1, LPCTSTR s2) -{ return s1.Compare(s2) > 0; } - -inline bool __stdcall operator >(LPCTSTR s1, const CString& s2) -{ return s2.Compare(s1) < 0; } - -inline bool __stdcall operator <=(const CString& s1, const CString& s2) -{ return s1.Compare(s2) <= 0; } - -inline bool __stdcall operator <=(const CString& s1, LPCTSTR s2) -{ return s1.Compare(s2) <= 0; } - -inline bool __stdcall operator <=(LPCTSTR s1, const CString& s2) -{ return s2.Compare(s1) >= 0; } - -inline bool __stdcall operator >=(const CString& s1, const CString& s2) -{ return s1.Compare(s2) >= 0; } - -inline bool __stdcall operator >=(const CString& s1, LPCTSTR s2) -{ return s1.Compare(s2) >= 0; } - -inline bool __stdcall operator >=(LPCTSTR s1, const CString& s2) -{ return s2.Compare(s1) <= 0; } - - -// CString "operator +" functions - -inline CString __stdcall operator +(const CString& string1, const CString& string2) -{ - CString s; - s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, string2.GetData()->nDataLength, string2.m_pchData); - return s; -} - -inline CString __stdcall operator +(const CString& string, TCHAR ch) -{ - CString s; - s.ConcatCopy(string.GetData()->nDataLength, string.m_pchData, 1, &ch); - return s; -} - -inline CString __stdcall operator +(TCHAR ch, const CString& string) -{ - CString s; - s.ConcatCopy(1, &ch, string.GetData()->nDataLength, string.m_pchData); - return s; -} - -#ifdef _UNICODE -inline CString __stdcall operator +(const CString& string, char ch) -{ - return string + (TCHAR)ch; -} - -inline CString __stdcall operator +(char ch, const CString& string) -{ - return (TCHAR)ch + string; -} -#endif // _UNICODE - -inline CString __stdcall operator +(const CString& string, LPCTSTR lpsz) -{ - ATLASSERT(lpsz == NULL || CString::_IsValidString(lpsz)); - CString s; - s.ConcatCopy(string.GetData()->nDataLength, string.m_pchData, CString::SafeStrlen(lpsz), lpsz); - return s; -} - -inline CString __stdcall operator +(LPCTSTR lpsz, const CString& string) -{ - ATLASSERT(lpsz == NULL || CString::_IsValidString(lpsz)); - CString s; - s.ConcatCopy(CString::SafeStrlen(lpsz), lpsz, string.GetData()->nDataLength, string.m_pchData); - return s; -} - -#endif // !_WTL_NO_CSTRING - - -/////////////////////////////////////////////////////////////////////////////// -// CRecentDocumentList - MRU List Support - -#ifndef _WIN32_WCE - -#ifndef _WTL_MRUEMPTY_TEXT - #define _WTL_MRUEMPTY_TEXT _T("(empty)") -#endif - -// forward declaration -inline bool AtlCompactPath(LPTSTR lpstrOut, LPCTSTR lpstrIn, int cchLen); - -template -class CRecentDocumentListBase -{ -public: -// Declarations - struct _DocEntry - { - TCHAR szDocName[t_cchItemLen]; - bool operator ==(const _DocEntry& de) const - { return (lstrcmpi(szDocName, de.szDocName) == 0); } - }; - - enum - { - m_nMaxEntries_Min = 2, - m_nMaxEntries_Max = t_nLastID - t_nFirstID + 1, - m_cchMaxItemLen_Min = 6, - m_cchMaxItemLen_Max = t_cchItemLen, - m_cchItemNameLen = 11 - }; - -// Data members - ATL::CSimpleArray<_DocEntry> m_arrDocs; - int m_nMaxEntries; // default is 4 - HMENU m_hMenu; - - TCHAR m_szNoEntries[t_cchItemLen]; - - int m_cchMaxItemLen; - -// Constructor - CRecentDocumentListBase() : m_hMenu(NULL), m_nMaxEntries(4), m_cchMaxItemLen(-1) - { - // These ASSERTs verify values of the template arguments - ATLASSERT(t_cchItemLen > m_cchMaxItemLen_Min); - ATLASSERT(m_nMaxEntries_Max > m_nMaxEntries_Min); - } - -// Attributes - HMENU GetMenuHandle() const - { - return m_hMenu; - } - - void SetMenuHandle(HMENU hMenu) - { - ATLASSERT(hMenu == NULL || ::IsMenu(hMenu)); - m_hMenu = hMenu; - if(m_hMenu == NULL || (::GetMenuString(m_hMenu, t_nFirstID, m_szNoEntries, t_cchItemLen, MF_BYCOMMAND) == 0)) - { - T* pT = static_cast(this); - pT; // avoid level 4 warning - SecureHelper::strncpy_x(m_szNoEntries, _countof(m_szNoEntries), pT->GetMRUEmptyText(), _TRUNCATE); - } - } - - int GetMaxEntries() const - { - return m_nMaxEntries; - } - - void SetMaxEntries(int nMaxEntries) - { - ATLASSERT(nMaxEntries >= m_nMaxEntries_Min && nMaxEntries <= m_nMaxEntries_Max); - if(nMaxEntries < m_nMaxEntries_Min) - nMaxEntries = m_nMaxEntries_Min; - else if(nMaxEntries > m_nMaxEntries_Max) - nMaxEntries = m_nMaxEntries_Max; - m_nMaxEntries = nMaxEntries; - } - - int GetMaxItemLength() const - { - return m_cchMaxItemLen; - } - - void SetMaxItemLength(int cchMaxLen) - { - ATLASSERT((cchMaxLen >= m_cchMaxItemLen_Min && cchMaxLen <= m_cchMaxItemLen_Max) || cchMaxLen == -1); - if(cchMaxLen != -1) - { - if(cchMaxLen < m_cchMaxItemLen_Min) - cchMaxLen = m_cchMaxItemLen_Min; - else if(cchMaxLen > m_cchMaxItemLen_Max) - cchMaxLen = m_cchMaxItemLen_Max; - } - m_cchMaxItemLen = cchMaxLen; - T* pT = static_cast(this); - pT->UpdateMenu(); - } - -// Operations - BOOL AddToList(LPCTSTR lpstrDocName) - { - _DocEntry de; - errno_t nRet = SecureHelper::strncpy_x(de.szDocName, _countof(de.szDocName), lpstrDocName, _TRUNCATE); - if(nRet != 0 && nRet != STRUNCATE) - return FALSE; - - for(int i = 0; i < m_arrDocs.GetSize(); i++) - { - if(lstrcmpi(m_arrDocs[i].szDocName, lpstrDocName) == 0) - { - m_arrDocs.RemoveAt(i); - break; - } - } - - if(m_arrDocs.GetSize() == m_nMaxEntries) - m_arrDocs.RemoveAt(0); - - BOOL bRet = m_arrDocs.Add(de); - if(bRet) - { - T* pT = static_cast(this); - bRet = pT->UpdateMenu(); - } - return bRet; - } - - // This function is deprecated because it is not safe. - // Use the version below that accepts the buffer length. -#if (_MSC_VER >= 1300) - __declspec(deprecated) -#endif - BOOL GetFromList(int /*nItemID*/, LPTSTR /*lpstrDocName*/) - { - ATLASSERT(FALSE); - return FALSE; - } - - BOOL GetFromList(int nItemID, LPTSTR lpstrDocName, int cchLength) - { - int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1; - if(nIndex < 0 || nIndex >= m_arrDocs.GetSize()) - return FALSE; - if(lstrlen(m_arrDocs[nIndex].szDocName) >= cchLength) - return FALSE; - SecureHelper::strcpy_x(lpstrDocName, cchLength, m_arrDocs[nIndex].szDocName); - - return TRUE; - } - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - BOOL GetFromList(int nItemID, _CSTRING_NS::CString& strDocName) - { - int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1; - if(nIndex < 0 || nIndex >= m_arrDocs.GetSize()) - return FALSE; - strDocName = m_arrDocs[nIndex].szDocName; - return TRUE; - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - - BOOL RemoveFromList(int nItemID) - { - int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1; - BOOL bRet = m_arrDocs.RemoveAt(nIndex); - if(bRet) - { - T* pT = static_cast(this); - bRet = pT->UpdateMenu(); - } - return bRet; - } - - BOOL MoveToTop(int nItemID) - { - int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1; - if(nIndex < 0 || nIndex >= m_arrDocs.GetSize()) - return FALSE; - _DocEntry de; - de = m_arrDocs[nIndex]; - m_arrDocs.RemoveAt(nIndex); - BOOL bRet = m_arrDocs.Add(de); - if(bRet) - { - T* pT = static_cast(this); - bRet = pT->UpdateMenu(); - } - return bRet; - } - - BOOL ReadFromRegistry(LPCTSTR lpstrRegKey) - { - T* pT = static_cast(this); - CRegKeyEx rkParent; - CRegKeyEx rk; - - LONG lRet = rkParent.Open(HKEY_CURRENT_USER, lpstrRegKey); - if(lRet != ERROR_SUCCESS) - return FALSE; - lRet = rk.Open(rkParent, pT->GetRegKeyName()); - if(lRet != ERROR_SUCCESS) - return FALSE; - - DWORD dwRet = 0; - lRet = rk.QueryDWORDValue(pT->GetRegCountName(), dwRet); - if(lRet != ERROR_SUCCESS) - return FALSE; - SetMaxEntries(dwRet); - - m_arrDocs.RemoveAll(); - - TCHAR szRetString[t_cchItemLen] = { 0 }; - _DocEntry de; - - for(int nItem = m_nMaxEntries; nItem > 0; nItem--) - { - TCHAR szBuff[m_cchItemNameLen] = { 0 }; - SecureHelper::wsprintf_x(szBuff, m_cchItemNameLen, pT->GetRegItemName(), nItem); - ULONG ulCount = t_cchItemLen; - lRet = rk.QueryStringValue(szBuff, szRetString, &ulCount); - if(lRet == ERROR_SUCCESS) - { - SecureHelper::strcpy_x(de.szDocName, _countof(de.szDocName), szRetString); - m_arrDocs.Add(de); - } - } - - rk.Close(); - rkParent.Close(); - - return pT->UpdateMenu(); - } - - BOOL WriteToRegistry(LPCTSTR lpstrRegKey) - { - T* pT = static_cast(this); - pT; // avoid level 4 warning - CRegKeyEx rkParent; - CRegKeyEx rk; - - LONG lRet = rkParent.Create(HKEY_CURRENT_USER, lpstrRegKey); - if(lRet != ERROR_SUCCESS) - return FALSE; - lRet = rk.Create(rkParent, pT->GetRegKeyName()); - if(lRet != ERROR_SUCCESS) - return FALSE; - - lRet = rk.SetDWORDValue(pT->GetRegCountName(), m_nMaxEntries); - ATLASSERT(lRet == ERROR_SUCCESS); - - // set new values - int nItem; - for(nItem = m_arrDocs.GetSize(); nItem > 0; nItem--) - { - TCHAR szBuff[m_cchItemNameLen] = { 0 }; - SecureHelper::wsprintf_x(szBuff, m_cchItemNameLen, pT->GetRegItemName(), nItem); - TCHAR szDocName[t_cchItemLen] = { 0 }; - GetFromList(t_nFirstID + nItem - 1, szDocName, t_cchItemLen); - lRet = rk.SetStringValue(szBuff, szDocName); - ATLASSERT(lRet == ERROR_SUCCESS); - } - - // delete unused keys - for(nItem = m_arrDocs.GetSize() + 1; nItem < m_nMaxEntries_Max; nItem++) - { - TCHAR szBuff[m_cchItemNameLen] = { 0 }; - SecureHelper::wsprintf_x(szBuff, m_cchItemNameLen, pT->GetRegItemName(), nItem); - rk.DeleteValue(szBuff); - } - - rk.Close(); - rkParent.Close(); - - return TRUE; - } - -// Implementation - BOOL UpdateMenu() - { - if(m_hMenu == NULL) - return FALSE; - ATLASSERT(::IsMenu(m_hMenu)); - - int nItems = ::GetMenuItemCount(m_hMenu); - int nInsertPoint; - for(nInsertPoint = 0; nInsertPoint < nItems; nInsertPoint++) - { - CMenuItemInfo mi; - mi.fMask = MIIM_ID; - ::GetMenuItemInfo(m_hMenu, nInsertPoint, TRUE, &mi); - if (mi.wID == t_nFirstID) - break; - } - ATLASSERT(nInsertPoint < nItems && "You need a menu item with an ID = t_nFirstID"); - - int nItem; - for(nItem = t_nFirstID; nItem < t_nFirstID + m_nMaxEntries; nItem++) - { - // keep the first one as an insertion point - if (nItem != t_nFirstID) - ::DeleteMenu(m_hMenu, nItem, MF_BYCOMMAND); - } - - TCHAR szItemText[t_cchItemLen + 6] = { 0 }; // add space for &, 2 digits, and a space - int nSize = m_arrDocs.GetSize(); - nItem = 0; - if(nSize > 0) - { - for(nItem = 0; nItem < nSize; nItem++) - { - if(m_cchMaxItemLen == -1) - { - SecureHelper::wsprintf_x(szItemText, t_cchItemLen + 6, _T("&%i %s"), nItem + 1, m_arrDocs[nSize - 1 - nItem].szDocName); - } - else - { - TCHAR szBuff[t_cchItemLen] = { 0 }; - T* pT = static_cast(this); - pT; // avoid level 4 warning - bool bRet = pT->CompactDocumentName(szBuff, m_arrDocs[nSize - 1 - nItem].szDocName, m_cchMaxItemLen); - bRet; // avoid level 4 warning - ATLASSERT(bRet); - SecureHelper::wsprintf_x(szItemText, t_cchItemLen + 6, _T("&%i %s"), nItem + 1, szBuff); - } - ::InsertMenu(m_hMenu, nInsertPoint + nItem, MF_BYPOSITION | MF_STRING, t_nFirstID + nItem, szItemText); - } - } - else // empty - { - ::InsertMenu(m_hMenu, nInsertPoint, MF_BYPOSITION | MF_STRING, t_nFirstID, m_szNoEntries); - ::EnableMenuItem(m_hMenu, t_nFirstID, MF_GRAYED); - nItem++; - } - ::DeleteMenu(m_hMenu, nInsertPoint + nItem, MF_BYPOSITION); - - return TRUE; - } - -// Overrideables - // override to provide a different method of compacting document names - static bool CompactDocumentName(LPTSTR lpstrOut, LPCTSTR lpstrIn, int cchLen) - { - return AtlCompactPath(lpstrOut, lpstrIn, cchLen); - } - - static LPCTSTR GetRegKeyName() - { - return _T("Recent Document List"); - } - - static LPCTSTR GetRegCountName() - { - return _T("DocumentCount"); - } - - static LPCTSTR GetRegItemName() - { - // Note: This string is a format string used with wsprintf(). - // Resulting formatted string must be m_cchItemNameLen or less - // characters long, including the terminating null character. - return _T("Document%i"); - } - - static LPCTSTR GetMRUEmptyText() - { - return _WTL_MRUEMPTY_TEXT; - } -}; - -class CRecentDocumentList : public CRecentDocumentListBase -{ -public: -// nothing here -}; - -#endif // _WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CFindFile - file search helper class - -class CFindFile -{ -public: -// Data members - WIN32_FIND_DATA m_fd; - TCHAR m_lpszRoot[MAX_PATH]; - TCHAR m_chDirSeparator; - HANDLE m_hFind; - BOOL m_bFound; - -// Constructor/destructor - CFindFile() : m_hFind(NULL), m_chDirSeparator(_T('\\')), m_bFound(FALSE) - { } - - ~CFindFile() - { - Close(); - } - -// Attributes - ULONGLONG GetFileSize() const - { - ATLASSERT(m_hFind != NULL); - - ULARGE_INTEGER nFileSize = { 0 }; - - if(m_bFound) - { - nFileSize.LowPart = m_fd.nFileSizeLow; - nFileSize.HighPart = m_fd.nFileSizeHigh; - } - else - { - nFileSize.QuadPart = 0; - } - - return nFileSize.QuadPart; - } - - BOOL GetFileName(LPTSTR lpstrFileName, int cchLength) const - { - ATLASSERT(m_hFind != NULL); - if(lstrlen(m_fd.cFileName) >= cchLength) - return FALSE; - - if(m_bFound) - SecureHelper::strcpy_x(lpstrFileName, cchLength, m_fd.cFileName); - - return m_bFound; - } - - BOOL GetFilePath(LPTSTR lpstrFilePath, int cchLength) const - { - ATLASSERT(m_hFind != NULL); - - int nLen = lstrlen(m_lpszRoot); -#ifndef _WIN32_WCE - ATLASSERT(nLen > 0); - if(nLen == 0) - return FALSE; - - bool bAddSep = (m_lpszRoot[nLen - 1] != _T('\\') && m_lpszRoot[nLen - 1] !=_T('/')); -#else // CE specific - // allow diskless devices (nLen == 0) - bool bAddSep = ((nLen == 0) || (m_lpszRoot[nLen - 1] != _T('\\') && m_lpszRoot[nLen - 1] !=_T('/'))); -#endif // _WIN32_WCE - - if((lstrlen(m_lpszRoot) + (bAddSep ? 1 : 0)) >= cchLength) - return FALSE; - - SecureHelper::strcpy_x(lpstrFilePath, cchLength, m_lpszRoot); - - if(bAddSep) - { - TCHAR szSeparator[2] = { m_chDirSeparator, 0 }; - SecureHelper::strcat_x(lpstrFilePath, cchLength, szSeparator); - } - - SecureHelper::strcat_x(lpstrFilePath, cchLength, m_fd.cFileName); - - return TRUE; - } - -#ifndef _WIN32_WCE - BOOL GetFileTitle(LPTSTR lpstrFileTitle, int cchLength) const - { - ATLASSERT(m_hFind != NULL); - - TCHAR szBuff[MAX_PATH] = { 0 }; - if(!GetFileName(szBuff, MAX_PATH)) - return FALSE; - - if(lstrlen(szBuff) >= cchLength || cchLength < 1) - return FALSE; - - // find the last dot - LPTSTR pstrDot = (LPTSTR)_cstrrchr(szBuff, _T('.')); - if(pstrDot != NULL) - *pstrDot = 0; - - SecureHelper::strcpy_x(lpstrFileTitle, cchLength, szBuff); - - return TRUE; - } -#endif // !_WIN32_WCE - - BOOL GetFileURL(LPTSTR lpstrFileURL, int cchLength) const - { - ATLASSERT(m_hFind != NULL); - - TCHAR szBuff[MAX_PATH] = { 0 }; - if(!GetFilePath(szBuff, MAX_PATH)) - return FALSE; - LPCTSTR lpstrFileURLPrefix = _T("file://"); - if(lstrlen(szBuff) + lstrlen(lpstrFileURLPrefix) >= cchLength) - return FALSE; - SecureHelper::strcpy_x(lpstrFileURL, cchLength, lpstrFileURLPrefix); - SecureHelper::strcat_x(lpstrFileURL, cchLength, szBuff); - - return TRUE; - } - - BOOL GetRoot(LPTSTR lpstrRoot, int cchLength) const - { - ATLASSERT(m_hFind != NULL); - if(lstrlen(m_lpszRoot) >= cchLength) - return FALSE; - - SecureHelper::strcpy_x(lpstrRoot, cchLength, m_lpszRoot); - - return TRUE; - } - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - _CSTRING_NS::CString GetFileName() const - { - ATLASSERT(m_hFind != NULL); - - _CSTRING_NS::CString ret; - - if(m_bFound) - ret = m_fd.cFileName; - return ret; - } - - _CSTRING_NS::CString GetFilePath() const - { - ATLASSERT(m_hFind != NULL); - - _CSTRING_NS::CString strResult = m_lpszRoot; - int nLen = strResult.GetLength(); -#ifndef _WIN32_WCE - ATLASSERT(nLen > 0); - if(nLen == 0) - return strResult; - - if((strResult[nLen - 1] != _T('\\')) && (strResult[nLen - 1] != _T('/'))) -#else // CE specific - // allow diskless devices (nLen == 0) - if((nLen == 0) || ((strResult[nLen - 1] != _T('\\')) && (strResult[nLen - 1] != _T('/')))) -#endif // _WIN32_WCE - strResult += m_chDirSeparator; - strResult += GetFileName(); - return strResult; - } - -#ifndef _WIN32_WCE - _CSTRING_NS::CString GetFileTitle() const - { - ATLASSERT(m_hFind != NULL); - - _CSTRING_NS::CString strResult; - GetFileTitle(strResult.GetBuffer(MAX_PATH), MAX_PATH); - strResult.ReleaseBuffer(); - - return strResult; - } -#endif // !_WIN32_WCE - - _CSTRING_NS::CString GetFileURL() const - { - ATLASSERT(m_hFind != NULL); - - _CSTRING_NS::CString strResult("file://"); - strResult += GetFilePath(); - return strResult; - } - - _CSTRING_NS::CString GetRoot() const - { - ATLASSERT(m_hFind != NULL); - - _CSTRING_NS::CString str = m_lpszRoot; - return str; - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - - BOOL GetLastWriteTime(FILETIME* pTimeStamp) const - { - ATLASSERT(m_hFind != NULL); - ATLASSERT(pTimeStamp != NULL); - - if(m_bFound && pTimeStamp != NULL) - { - *pTimeStamp = m_fd.ftLastWriteTime; - return TRUE; - } - - return FALSE; - } - - BOOL GetLastAccessTime(FILETIME* pTimeStamp) const - { - ATLASSERT(m_hFind != NULL); - ATLASSERT(pTimeStamp != NULL); - - if(m_bFound && pTimeStamp != NULL) - { - *pTimeStamp = m_fd.ftLastAccessTime; - return TRUE; - } - - return FALSE; - } - - BOOL GetCreationTime(FILETIME* pTimeStamp) const - { - ATLASSERT(m_hFind != NULL); - - if(m_bFound && pTimeStamp != NULL) - { - *pTimeStamp = m_fd.ftCreationTime; - return TRUE; - } - - return FALSE; - } - - BOOL MatchesMask(DWORD dwMask) const - { - ATLASSERT(m_hFind != NULL); - - if(m_bFound) - return ((m_fd.dwFileAttributes & dwMask) != 0); - - return FALSE; - } - - BOOL IsDots() const - { - ATLASSERT(m_hFind != NULL); - - // return TRUE if the file name is "." or ".." and - // the file is a directory - - BOOL bResult = FALSE; - if(m_bFound && IsDirectory()) - { - if(m_fd.cFileName[0] == _T('.') && (m_fd.cFileName[1] == _T('\0') || (m_fd.cFileName[1] == _T('.') && m_fd.cFileName[2] == _T('\0')))) - bResult = TRUE; - } - - return bResult; - } - - BOOL IsReadOnly() const - { - return MatchesMask(FILE_ATTRIBUTE_READONLY); - } - - BOOL IsDirectory() const - { - return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); - } - - BOOL IsCompressed() const - { - return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); - } - - BOOL IsSystem() const - { - return MatchesMask(FILE_ATTRIBUTE_SYSTEM); - } - - BOOL IsHidden() const - { - return MatchesMask(FILE_ATTRIBUTE_HIDDEN); - } - - BOOL IsTemporary() const - { - return MatchesMask(FILE_ATTRIBUTE_TEMPORARY); - } - - BOOL IsNormal() const - { - return MatchesMask(FILE_ATTRIBUTE_NORMAL); - } - - BOOL IsArchived() const - { - return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); - } - -// Operations - BOOL FindFile(LPCTSTR pstrName = NULL) - { - Close(); - - if(pstrName == NULL) - { - pstrName = _T("*.*"); - } - else if(lstrlen(pstrName) >= MAX_PATH) - { - ATLASSERT(FALSE); - return FALSE; - } - - SecureHelper::strcpy_x(m_fd.cFileName, _countof(m_fd.cFileName), pstrName); - - m_hFind = ::FindFirstFile(pstrName, &m_fd); - - if(m_hFind == INVALID_HANDLE_VALUE) - return FALSE; - -#ifndef _WIN32_WCE - bool bFullPath = (::GetFullPathName(pstrName, MAX_PATH, m_lpszRoot, NULL) != 0); -#else // CE specific - errno_t nRet = SecureHelper::strncpy_x(m_lpszRoot, _countof(m_lpszRoot), pstrName, _TRUNCATE); - bool bFullPath = (nRet == 0 || nRet == STRUNCATE); -#endif // _WIN32_WCE - - // passed name isn't a valid path but was found by the API - ATLASSERT(bFullPath); - if(!bFullPath) - { - Close(); - ::SetLastError(ERROR_INVALID_NAME); - return FALSE; - } - else - { - // find the last forward or backward whack - LPTSTR pstrBack = (LPTSTR)_cstrrchr(m_lpszRoot, _T('\\')); - LPTSTR pstrFront = (LPTSTR)_cstrrchr(m_lpszRoot, _T('/')); - - if(pstrFront != NULL || pstrBack != NULL) - { - if(pstrFront == NULL) - pstrFront = m_lpszRoot; - if(pstrBack == NULL) - pstrBack = m_lpszRoot; - - // from the start to the last whack is the root - - if(pstrFront >= pstrBack) - *pstrFront = _T('\0'); - else - *pstrBack = _T('\0'); - } - } - - m_bFound = TRUE; - - return TRUE; - } - - BOOL FindNextFile() - { - ATLASSERT(m_hFind != NULL); - - if(m_hFind == NULL) - return FALSE; - - if(!m_bFound) - return FALSE; - - m_bFound = ::FindNextFile(m_hFind, &m_fd); - - return m_bFound; - } - - void Close() - { - m_bFound = FALSE; - - if(m_hFind != NULL && m_hFind != INVALID_HANDLE_VALUE) - { - ::FindClose(m_hFind); - m_hFind = NULL; - } - } - -// Helper - static const TCHAR* _cstrrchr(const TCHAR* p, TCHAR ch) - { -#ifdef _ATL_MIN_CRT - const TCHAR* lpsz = NULL; - while (*p != 0) - { - if (*p == ch) - lpsz = p; - p = ::CharNext(p); - } - return lpsz; -#else // !_ATL_MIN_CRT - return _tcsrchr(p, ch); -#endif // !_ATL_MIN_CRT - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// Global functions for stock GDI objects - -inline HPEN AtlGetStockPen(int nPen) -{ -#if (_WIN32_WINNT >= 0x0500) && !defined(_WIN32_WCE) - ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN || nPen == DC_PEN); -#else - ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN); -#endif - return (HPEN)::GetStockObject(nPen); -} - -inline HBRUSH AtlGetStockBrush(int nBrush) -{ -#if (_WIN32_WINNT >= 0x0500) && !defined(_WIN32_WCE) - ATLASSERT((nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH) || nBrush == DC_BRUSH); -#else - ATLASSERT(nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH); -#endif - return (HBRUSH)::GetStockObject(nBrush); -} - -inline HFONT AtlGetStockFont(int nFont) -{ -#ifndef _WIN32_WCE - ATLASSERT((nFont >= OEM_FIXED_FONT && nFont <= SYSTEM_FIXED_FONT) || nFont == DEFAULT_GUI_FONT); -#else // CE specific - ATLASSERT(nFont == SYSTEM_FONT); -#endif // _WIN32_WCE - return (HFONT)::GetStockObject(nFont); -} - -inline HPALETTE AtlGetStockPalette(int nPalette) -{ - ATLASSERT(nPalette == DEFAULT_PALETTE); // the only one supported - return (HPALETTE)::GetStockObject(nPalette); -} - - -/////////////////////////////////////////////////////////////////////////////// -// Global function for compacting a path by replacing parts with ellipsis - -// helper for multi-byte character sets -inline bool _IsDBCSTrailByte(LPCTSTR lpstr, int nChar) -{ -#ifndef _UNICODE - int i = nChar; - for( ; i > 0; i--) - { - if(!::IsDBCSLeadByte(lpstr[i - 1])) - break; - } - return ((nChar > 0) && (((nChar - i) & 1) != 0)); -#else // _UNICODE - lpstr; nChar; - return false; -#endif // _UNICODE -} - -inline bool AtlCompactPath(LPTSTR lpstrOut, LPCTSTR lpstrIn, int cchLen) -{ - ATLASSERT(lpstrOut != NULL); - ATLASSERT(lpstrIn != NULL); - ATLASSERT(cchLen > 0); - - LPCTSTR szEllipsis = _T("..."); - const int cchEndEllipsis = 3; - const int cchMidEllipsis = 4; - - if(lstrlen(lpstrIn) < cchLen) - { - SecureHelper::strcpy_x(lpstrOut, cchLen, lpstrIn); - return true; - } - - lpstrOut[0] = 0; - - // check if the separator is a slash or a backslash - TCHAR chSlash = _T('\\'); - for(LPTSTR lpstr = (LPTSTR)lpstrIn; *lpstr != 0; lpstr = ::CharNext(lpstr)) - { - if((*lpstr == _T('/')) || (*lpstr == _T('\\'))) - chSlash = *lpstr; - } - - // find the filename portion of the path - LPCTSTR lpstrFileName = lpstrIn; - for(LPCTSTR pPath = lpstrIn; *pPath; pPath = ::CharNext(pPath)) - { - if((pPath[0] == _T('\\') || pPath[0] == _T(':') || pPath[0] == _T('/')) - && pPath[1] && pPath[1] != _T('\\') && pPath[1] != _T('/')) - lpstrFileName = pPath + 1; - } - int cchFileName = lstrlen(lpstrFileName); - - // handle just the filename without a path - if(lpstrFileName == lpstrIn && cchLen > cchEndEllipsis) - { - bool bRet = (SecureHelper::strncpy_x(lpstrOut, cchLen, lpstrIn, cchLen - cchEndEllipsis - 1) == 0); - if(bRet) - { -#ifndef _UNICODE - if(_IsDBCSTrailByte(lpstrIn, cchLen - cchEndEllipsis)) - lpstrOut[cchLen - cchEndEllipsis - 1] = 0; -#endif // _UNICODE - SecureHelper::strcat_x(lpstrOut, cchLen, szEllipsis); - } - return bRet; - } - - // handle just ellipsis - if((cchLen < (cchMidEllipsis + cchEndEllipsis))) - { - for(int i = 0; i < cchLen - 1; i++) - lpstrOut[i] = ((i + 1) == cchMidEllipsis) ? chSlash : _T('.'); - lpstrOut[cchLen - 1] = 0; - return true; - } - - // calc how much we have to copy - int cchToCopy = cchLen - (cchMidEllipsis + cchFileName) - 1; - - if(cchToCopy < 0) - cchToCopy = 0; - -#ifndef _UNICODE - if(cchToCopy > 0 && _IsDBCSTrailByte(lpstrIn, cchToCopy)) - cchToCopy--; -#endif // _UNICODE - - bool bRet = (SecureHelper::strncpy_x(lpstrOut, cchLen, lpstrIn, cchToCopy) == 0); - if(!bRet) - return false; - - // add ellipsis - SecureHelper::strcat_x(lpstrOut, cchLen, szEllipsis); - if(!bRet) - return false; - TCHAR szSlash[2] = { chSlash, 0 }; - SecureHelper::strcat_x(lpstrOut, cchLen, szSlash); - if(!bRet) - return false; - - // add filename (and ellipsis, if needed) - if(cchLen > (cchMidEllipsis + cchFileName)) - { - SecureHelper::strcat_x(lpstrOut, cchLen, lpstrFileName); - } - else - { - cchToCopy = cchLen - cchMidEllipsis - cchEndEllipsis - 1; -#ifndef _UNICODE - if(cchToCopy > 0 && _IsDBCSTrailByte(lpstrFileName, cchToCopy)) - cchToCopy--; -#endif // _UNICODE - bRet = (SecureHelper::strncpy_x(&lpstrOut[cchMidEllipsis], cchLen - cchMidEllipsis, lpstrFileName, cchToCopy) == 0); - if(bRet) - SecureHelper::strcat_x(lpstrOut, cchLen, szEllipsis); - } - - return bRet; -} - -}; // namespace WTL - -#endif // __ATLMISC_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlprint.h b/!NotAdopted/SmartAutoReplier/wtl/atlprint.h deleted file mode 100644 index 50a7fb17dc..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlprint.h +++ /dev/null @@ -1,1109 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLPRINT_H__ -#define __ATLPRINT_H__ - -#pragma once - -#ifdef _WIN32_WCE - #error atlprint.h is not supported on Windows CE -#endif - -#ifndef __ATLAPP_H__ - #error atlprint.h requires atlapp.h to be included first -#endif - -#ifndef __ATLWIN_H__ - #error atlprint.h requires atlwin.h to be included first -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CPrinterInfo -// CPrinterT -// CDevModeT -// CPrinterDC -// CPrintJobInfo -// CPrintJob -// CPrintPreview -// CPrintPreviewWindowImpl -// CPrintPreviewWindow -// CZoomPrintPreviewWindowImpl -// CZoomPrintPreviewWindow - -namespace WTL -{ - -/////////////////////////////////////////////////////////////////////////////// -// CPrinterInfo - This class wraps all of the PRINTER_INFO_* structures -// and provided by ::GetPrinter. - -template -class _printer_info -{ -public: - typedef void infotype; -}; - -template <> class _printer_info<1> { public: typedef PRINTER_INFO_1 infotype; }; -template <> class _printer_info<2> { public: typedef PRINTER_INFO_2 infotype; }; -template <> class _printer_info<3> { public: typedef PRINTER_INFO_3 infotype; }; -template <> class _printer_info<4> { public: typedef PRINTER_INFO_4 infotype; }; -template <> class _printer_info<5> { public: typedef PRINTER_INFO_5 infotype; }; -template <> class _printer_info<6> { public: typedef PRINTER_INFO_6 infotype; }; -template <> class _printer_info<7> { public: typedef PRINTER_INFO_7 infotype; }; -// these are not in the old (vc6.0) headers -#ifdef _ATL_USE_NEW_PRINTER_INFO -template <> class _printer_info<8> { public: typedef PRINTER_INFO_8 infotype; }; -template <> class _printer_info<9> { public: typedef PRINTER_INFO_9 infotype; }; -#endif // _ATL_USE_NEW_PRINTER_INFO - - -template -class CPrinterInfo -{ -public: -// Data members - typename _printer_info::infotype* m_pi; - -// Constructor/destructor - CPrinterInfo() : m_pi(NULL) - { } - - CPrinterInfo(HANDLE hPrinter) : m_pi(NULL) - { - GetPrinterInfo(hPrinter); - } - - ~CPrinterInfo() - { - Cleanup(); - } - -// Operations - bool GetPrinterInfo(HANDLE hPrinter) - { - Cleanup(); - return GetPrinterInfoHelper(hPrinter, (BYTE**)&m_pi, t_nInfo); - } - -// Implementation - void Cleanup() - { - delete [] (BYTE*)m_pi; - m_pi = NULL; - } - - static bool GetPrinterInfoHelper(HANDLE hPrinter, BYTE** pi, int nIndex) - { - ATLASSERT(pi != NULL); - DWORD dw = 0; - BYTE* pb = NULL; - ::GetPrinter(hPrinter, nIndex, NULL, 0, &dw); - if (dw > 0) - { - ATLTRY(pb = new BYTE[dw]); - if (pb != NULL) - { - memset(pb, 0, dw); - DWORD dwNew; - if (!::GetPrinter(hPrinter, nIndex, pb, dw, &dwNew)) - { - delete [] pb; - pb = NULL; - } - } - } - *pi = pb; - return (pb != NULL); - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CPrinter - Wrapper class for a HANDLE to a printer - -template -class CPrinterT -{ -public: -// Data members - HANDLE m_hPrinter; - -// Constructor/destructor - CPrinterT(HANDLE hPrinter = NULL) : m_hPrinter(hPrinter) - { } - - ~CPrinterT() - { - ClosePrinter(); - } - -// Operations - CPrinterT& operator =(HANDLE hPrinter) - { - if (hPrinter != m_hPrinter) - { - ClosePrinter(); - m_hPrinter = hPrinter; - } - return *this; - } - - bool IsNull() const { return (m_hPrinter == NULL); } - - bool OpenPrinter(HANDLE hDevNames, const DEVMODE* pDevMode = NULL) - { - bool b = false; - DEVNAMES* pdn = (DEVNAMES*)::GlobalLock(hDevNames); - if (pdn != NULL) - { - LPTSTR lpszPrinterName = (LPTSTR)pdn + pdn->wDeviceOffset; - b = OpenPrinter(lpszPrinterName, pDevMode); - ::GlobalUnlock(hDevNames); - } - return b; - } - - bool OpenPrinter(LPCTSTR lpszPrinterName, const DEVMODE* pDevMode = NULL) - { - ClosePrinter(); - PRINTER_DEFAULTS pdefs = { NULL, (DEVMODE*)pDevMode, PRINTER_ACCESS_USE }; - ::OpenPrinter((LPTSTR) lpszPrinterName, &m_hPrinter, (pDevMode == NULL) ? NULL : &pdefs); - - return (m_hPrinter != NULL); - } - - bool OpenPrinter(LPCTSTR lpszPrinterName, PRINTER_DEFAULTS* pprintdefs) - { - ClosePrinter(); - ::OpenPrinter((LPTSTR) lpszPrinterName, &m_hPrinter, pprintdefs); - return (m_hPrinter != NULL); - } - - bool OpenDefaultPrinter(const DEVMODE* pDevMode = NULL) - { - ClosePrinter(); - const int cchBuff = 512; - TCHAR buffer[cchBuff]; - buffer[0] = 0; - ::GetProfileString(_T("windows"), _T("device"), _T(",,,"), buffer, cchBuff); - int nLen = lstrlen(buffer); - if (nLen != 0) - { - LPTSTR lpsz = buffer; - while (*lpsz) - { - if (*lpsz == _T(',')) - { - *lpsz = 0; - break; - } - lpsz = CharNext(lpsz); - } - PRINTER_DEFAULTS pdefs = { NULL, (DEVMODE*)pDevMode, PRINTER_ACCESS_USE }; - ::OpenPrinter(buffer, &m_hPrinter, (pDevMode == NULL) ? NULL : &pdefs); - } - return m_hPrinter != NULL; - } - - void ClosePrinter() - { - if (m_hPrinter != NULL) - { - if (t_bManaged) - ::ClosePrinter(m_hPrinter); - m_hPrinter = NULL; - } - } - - bool PrinterProperties(HWND hWnd = NULL) - { - if (hWnd == NULL) - hWnd = ::GetActiveWindow(); - return !!::PrinterProperties(hWnd, m_hPrinter); - } - - HANDLE CopyToHDEVNAMES() const - { - HANDLE h = NULL; - CPrinterInfo<5> pinfon5; - CPrinterInfo<2> pinfon2; - LPTSTR lpszPrinterName = NULL; - // Some printers fail for PRINTER_INFO_5 in some situations - if (pinfon5.GetPrinterInfo(m_hPrinter)) - lpszPrinterName = pinfon5.m_pi->pPrinterName; - else if (pinfon2.GetPrinterInfo(m_hPrinter)) - lpszPrinterName = pinfon2.m_pi->pPrinterName; - if (lpszPrinterName != NULL) - { - int nLen = sizeof(DEVNAMES) + (lstrlen(lpszPrinterName) + 1) * sizeof(TCHAR); - h = ::GlobalAlloc(GMEM_MOVEABLE, nLen); - BYTE* pv = (BYTE*)::GlobalLock(h); - DEVNAMES* pdev = (DEVNAMES*)pv; - if (pv != NULL) - { - memset(pv, 0, nLen); - pdev->wDeviceOffset = sizeof(DEVNAMES) / sizeof(TCHAR); - pv = pv + sizeof(DEVNAMES); // now points to end - SecureHelper::strcpy_x((LPTSTR)pv, lstrlen(lpszPrinterName) + 1, lpszPrinterName); - ::GlobalUnlock(h); - } - } - return h; - } - - HDC CreatePrinterDC(const DEVMODE* pdm = NULL) const - { - CPrinterInfo<5> pinfo5; - CPrinterInfo<2> pinfo2; - HDC hDC = NULL; - LPTSTR lpszPrinterName = NULL; - // Some printers fail for PRINTER_INFO_5 in some situations - if (pinfo5.GetPrinterInfo(m_hPrinter)) - lpszPrinterName = pinfo5.m_pi->pPrinterName; - else if (pinfo2.GetPrinterInfo(m_hPrinter)) - lpszPrinterName = pinfo2.m_pi->pPrinterName; - if (lpszPrinterName != NULL) - hDC = ::CreateDC(NULL, lpszPrinterName, NULL, pdm); - return hDC; - } - - HDC CreatePrinterIC(const DEVMODE* pdm = NULL) const - { - CPrinterInfo<5> pinfo5; - CPrinterInfo<2> pinfo2; - HDC hDC = NULL; - LPTSTR lpszPrinterName = NULL; - // Some printers fail for PRINTER_INFO_5 in some situations - if (pinfo5.GetPrinterInfo(m_hPrinter)) - lpszPrinterName = pinfo5.m_pi->pPrinterName; - else if (pinfo2.GetPrinterInfo(m_hPrinter)) - lpszPrinterName = pinfo2.m_pi->pPrinterName; - if (lpszPrinterName != NULL) - hDC = ::CreateIC(NULL, lpszPrinterName, NULL, pdm); - return hDC; - } - - void Attach(HANDLE hPrinter) - { - ClosePrinter(); - m_hPrinter = hPrinter; - } - - HANDLE Detach() - { - HANDLE hPrinter = m_hPrinter; - m_hPrinter = NULL; - return hPrinter; - } - - operator HANDLE() const { return m_hPrinter; } -}; - -typedef CPrinterT CPrinterHandle; -typedef CPrinterT CPrinter; - - -/////////////////////////////////////////////////////////////////////////////// -// CDevMode - Wrapper class for DEVMODE - -template -class CDevModeT -{ -public: -// Data members - HANDLE m_hDevMode; - DEVMODE* m_pDevMode; - -// Constructor/destructor - CDevModeT(HANDLE hDevMode = NULL) : m_hDevMode(hDevMode) - { - m_pDevMode = (m_hDevMode != NULL) ? (DEVMODE*)::GlobalLock(m_hDevMode) : NULL; - } - - ~CDevModeT() - { - Cleanup(); - } - -// Operations - CDevModeT& operator =(HANDLE hDevMode) - { - Attach(hDevMode); - return *this; - } - - void Attach(HANDLE hDevModeNew) - { - Cleanup(); - m_hDevMode = hDevModeNew; - m_pDevMode = (m_hDevMode != NULL) ? (DEVMODE*)::GlobalLock(m_hDevMode) : NULL; - } - - HANDLE Detach() - { - if (m_hDevMode != NULL) - ::GlobalUnlock(m_hDevMode); - HANDLE hDevMode = m_hDevMode; - m_hDevMode = NULL; - return hDevMode; - } - - bool IsNull() const { return (m_hDevMode == NULL); } - - bool CopyFromPrinter(HANDLE hPrinter) - { - CPrinterInfo<2> pinfo; - bool b = pinfo.GetPrinterInfo(hPrinter); - if (b) - b = CopyFromDEVMODE(pinfo.m_pi->pDevMode); - return b; - } - - bool CopyFromDEVMODE(const DEVMODE* pdm) - { - if (pdm == NULL) - return false; - int nSize = pdm->dmSize + pdm->dmDriverExtra; - HANDLE h = ::GlobalAlloc(GMEM_MOVEABLE, nSize); - if (h != NULL) - { - void* p = ::GlobalLock(h); - SecureHelper::memcpy_x(p, nSize, pdm, nSize); - ::GlobalUnlock(h); - } - Attach(h); - return (h != NULL); - } - - bool CopyFromHDEVMODE(HANDLE hdm) - { - bool b = false; - if (hdm != NULL) - { - DEVMODE* pdm = (DEVMODE*)::GlobalLock(hdm); - b = CopyFromDEVMODE(pdm); - ::GlobalUnlock(hdm); - } - return b; - } - - HANDLE CopyToHDEVMODE() - { - if ((m_hDevMode == NULL) || (m_pDevMode == NULL)) - return NULL; - int nSize = m_pDevMode->dmSize + m_pDevMode->dmDriverExtra; - HANDLE h = ::GlobalAlloc(GMEM_MOVEABLE, nSize); - if (h != NULL) - { - void* p = ::GlobalLock(h); - SecureHelper::memcpy_x(p, nSize, m_pDevMode, nSize); - ::GlobalUnlock(h); - } - return h; - } - - // If this devmode was for another printer, this will create a new devmode - // based on the existing devmode, but retargeted at the new printer - bool UpdateForNewPrinter(HANDLE hPrinter) - { - bool bRet = false; - LONG nLen = ::DocumentProperties(NULL, hPrinter, NULL, NULL, NULL, 0); - CTempBuffer buff; - DEVMODE* pdm = buff.AllocateBytes(nLen); - if(pdm != NULL) - { - memset(pdm, 0, nLen); - LONG l = ::DocumentProperties(NULL, hPrinter, NULL, pdm, m_pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER); - if (l == IDOK) - bRet = CopyFromDEVMODE(pdm); - } - - return bRet; - } - - bool DocumentProperties(HANDLE hPrinter, HWND hWnd = NULL) - { - CPrinterInfo<1> pi; - pi.GetPrinterInfo(hPrinter); - if (hWnd == NULL) - hWnd = ::GetActiveWindow(); - - bool bRet = false; - LONG nLen = ::DocumentProperties(hWnd, hPrinter, pi.m_pi->pName, NULL, NULL, 0); - CTempBuffer buff; - DEVMODE* pdm = buff.AllocateBytes(nLen); - if(pdm != NULL) - { - memset(pdm, 0, nLen); - LONG l = ::DocumentProperties(hWnd, hPrinter, pi.m_pi->pName, pdm, m_pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER | DM_PROMPT); - if (l == IDOK) - bRet = CopyFromDEVMODE(pdm); - } - - return bRet; - } - - operator HANDLE() const { return m_hDevMode; } - - operator DEVMODE*() const { return m_pDevMode; } - -// Implementation - void Cleanup() - { - if (m_hDevMode != NULL) - { - ::GlobalUnlock(m_hDevMode); - if(t_bManaged) - ::GlobalFree(m_hDevMode); - m_hDevMode = NULL; - } - } -}; - -typedef CDevModeT CDevModeHandle; -typedef CDevModeT CDevMode; - - -/////////////////////////////////////////////////////////////////////////////// -// CPrinterDC - -class CPrinterDC : public CDC -{ -public: -// Constructors/destructor - CPrinterDC() - { - CPrinter printer; - printer.OpenDefaultPrinter(); - Attach(printer.CreatePrinterDC()); - ATLASSERT(m_hDC != NULL); - } - - CPrinterDC(HANDLE hPrinter, const DEVMODE* pdm = NULL) - { - CPrinterHandle p; - p.Attach(hPrinter); - Attach(p.CreatePrinterDC(pdm)); - ATLASSERT(m_hDC != NULL); - } - - ~CPrinterDC() - { - DeleteDC(); - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CPrintJob - Wraps a set of tasks for a specific printer (StartDoc/EndDoc) -// Handles aborting, background printing - -// Defines callbacks used by CPrintJob (not a COM interface) -class ATL_NO_VTABLE IPrintJobInfo -{ -public: - virtual void BeginPrintJob(HDC hDC) = 0; // allocate handles needed, etc. - virtual void EndPrintJob(HDC hDC, bool bAborted) = 0; // free handles, etc. - virtual void PrePrintPage(UINT nPage, HDC hDC) = 0; - virtual bool PrintPage(UINT nPage, HDC hDC) = 0; - virtual void PostPrintPage(UINT nPage, HDC hDC) = 0; - // If you want per page devmodes, return the DEVMODE* to use for nPage. - // You can optimize by only returning a new DEVMODE* when it is different - // from the one for nLastPage, otherwise return NULL. - // When nLastPage==0, the current DEVMODE* will be the default passed to - // StartPrintJob. - // Note: During print preview, nLastPage will always be "0". - virtual DEVMODE* GetNewDevModeForPage(UINT nLastPage, UINT nPage) = 0; - virtual bool IsValidPage(UINT nPage) = 0; -}; - -// Provides a default implementatin for IPrintJobInfo -// Typically, MI'd into a document or view class -class ATL_NO_VTABLE CPrintJobInfo : public IPrintJobInfo -{ -public: - virtual void BeginPrintJob(HDC /*hDC*/) // allocate handles needed, etc - { - } - - virtual void EndPrintJob(HDC /*hDC*/, bool /*bAborted*/) // free handles, etc - { - } - - virtual void PrePrintPage(UINT /*nPage*/, HDC hDC) - { - m_nPJState = ::SaveDC(hDC); - } - - virtual bool PrintPage(UINT /*nPage*/, HDC /*hDC*/) = 0; - - virtual void PostPrintPage(UINT /*nPage*/, HDC hDC) - { - RestoreDC(hDC, m_nPJState); - } - - virtual DEVMODE* GetNewDevModeForPage(UINT /*nLastPage*/, UINT /*nPage*/) - { - return NULL; - } - - virtual bool IsValidPage(UINT /*nPage*/) - { - return true; - } - -// Implementation - data - int m_nPJState; -}; - - -class CPrintJob -{ -public: -// Data members - CPrinterHandle m_printer; - IPrintJobInfo* m_pInfo; - DEVMODE* m_pDefDevMode; - DOCINFO m_docinfo; - int m_nJobID; - bool m_bCancel; - bool m_bComplete; - unsigned long m_nStartPage; - unsigned long m_nEndPage; - -// Constructor/destructor - CPrintJob() : m_nJobID(0), m_bCancel(false), m_bComplete(true) - { } - - ~CPrintJob() - { - ATLASSERT(IsJobComplete()); // premature destruction? - } - -// Operations - bool IsJobComplete() const - { - return m_bComplete; - } - - bool StartPrintJob(bool bBackground, HANDLE hPrinter, DEVMODE* pDefaultDevMode, - IPrintJobInfo* pInfo, LPCTSTR lpszDocName, - unsigned long nStartPage, unsigned long nEndPage, - bool bPrintToFile = false, LPCTSTR lpstrOutputFile = NULL) - { - ATLASSERT(m_bComplete); // previous job not done yet? - if (pInfo == NULL) - return false; - - memset(&m_docinfo, 0, sizeof(m_docinfo)); - m_docinfo.cbSize = sizeof(m_docinfo); - m_docinfo.lpszDocName = lpszDocName; - m_pInfo = pInfo; - m_nStartPage = nStartPage; - m_nEndPage = nEndPage; - m_printer.Attach(hPrinter); - m_pDefDevMode = pDefaultDevMode; - m_bComplete = false; - - if(bPrintToFile) - m_docinfo.lpszOutput = (lpstrOutputFile != NULL) ? lpstrOutputFile : _T("FILE:"); - - if (!bBackground) - { - m_bComplete = true; - return StartHelper(); - } - - // Create a thread and return - DWORD dwThreadID = 0; -#if !defined(_ATL_MIN_CRT) && defined(_MT) - HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, (UINT (WINAPI*)(void*))StartProc, this, 0, (UINT*)&dwThreadID); -#else - HANDLE hThread = ::CreateThread(NULL, 0, StartProc, (void*)this, 0, &dwThreadID); -#endif - if (hThread == NULL) - return false; - - ::CloseHandle(hThread); - - return true; - } - -// Implementation - static DWORD WINAPI StartProc(void* p) - { - CPrintJob* pThis = (CPrintJob*)p; - pThis->StartHelper(); - pThis->m_bComplete = true; - return 0; - } - - bool StartHelper() - { - CDC dcPrinter; - dcPrinter.Attach(m_printer.CreatePrinterDC(m_pDefDevMode)); - if (dcPrinter.IsNull()) - return false; - - m_nJobID = ::StartDoc(dcPrinter, &m_docinfo); - if (m_nJobID <= 0) - return false; - - m_pInfo->BeginPrintJob(dcPrinter); - - // print all the pages now - unsigned long nLastPage = 0; - for (unsigned long nPage = m_nStartPage; nPage <= m_nEndPage; nPage++) - { - if (!m_pInfo->IsValidPage(nPage)) - break; - DEVMODE* pdm = m_pInfo->GetNewDevModeForPage(nLastPage, nPage); - if (pdm != NULL) - dcPrinter.ResetDC(pdm); - dcPrinter.StartPage(); - m_pInfo->PrePrintPage(nPage, dcPrinter); - if (!m_pInfo->PrintPage(nPage, dcPrinter)) - m_bCancel = true; - m_pInfo->PostPrintPage(nPage, dcPrinter); - dcPrinter.EndPage(); - if (m_bCancel) - break; - nLastPage = nPage; - } - - m_pInfo->EndPrintJob(dcPrinter, m_bCancel); - if (m_bCancel) - ::AbortDoc(dcPrinter); - else - ::EndDoc(dcPrinter); - m_nJobID = 0; - return true; - } - - // Cancels a print job. Can be called asynchronously. - void CancelPrintJob() - { - m_bCancel = true; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CPrintPreview - Adds print preview support to an existing window - -class CPrintPreview -{ -public: -// Data members - IPrintJobInfo* m_pInfo; - CPrinterHandle m_printer; - CEnhMetaFile m_meta; - DEVMODE* m_pDefDevMode; - DEVMODE* m_pCurDevMode; - SIZE m_sizeCurPhysOffset; - -// Constructor - CPrintPreview() : m_pInfo(NULL), m_pDefDevMode(NULL), m_pCurDevMode(NULL) - { - m_sizeCurPhysOffset.cx = 0; - m_sizeCurPhysOffset.cy = 0; - } - -// Operations - void SetPrintPreviewInfo(HANDLE hPrinter, DEVMODE* pDefaultDevMode, IPrintJobInfo* pji) - { - m_printer.Attach(hPrinter); - m_pDefDevMode = pDefaultDevMode; - m_pInfo = pji; - m_nCurPage = 0; - m_pCurDevMode = NULL; - } - - void SetEnhMetaFile(HENHMETAFILE hEMF) - { - m_meta = hEMF; - } - - void SetPage(int nPage) - { - if (!m_pInfo->IsValidPage(nPage)) - return; - m_nCurPage = nPage; - m_pCurDevMode = m_pInfo->GetNewDevModeForPage(0, nPage); - if (m_pCurDevMode == NULL) - m_pCurDevMode = m_pDefDevMode; - CDC dcPrinter = m_printer.CreatePrinterDC(m_pCurDevMode); - - int iWidth = dcPrinter.GetDeviceCaps(PHYSICALWIDTH); - int iHeight = dcPrinter.GetDeviceCaps(PHYSICALHEIGHT); - int nLogx = dcPrinter.GetDeviceCaps(LOGPIXELSX); - int nLogy = dcPrinter.GetDeviceCaps(LOGPIXELSY); - - RECT rcMM = { 0, 0, ::MulDiv(iWidth, 2540, nLogx), ::MulDiv(iHeight, 2540, nLogy) }; - - m_sizeCurPhysOffset.cx = dcPrinter.GetDeviceCaps(PHYSICALOFFSETX); - m_sizeCurPhysOffset.cy = dcPrinter.GetDeviceCaps(PHYSICALOFFSETY); - - CEnhMetaFileDC dcMeta(dcPrinter, &rcMM); - m_pInfo->PrePrintPage(nPage, dcMeta); - m_pInfo->PrintPage(nPage, dcMeta); - m_pInfo->PostPrintPage(nPage, dcMeta); - m_meta.Attach(dcMeta.Close()); - } - - void GetPageRect(RECT& rc, LPRECT prc) - { - int x1 = rc.right-rc.left; - int y1 = rc.bottom - rc.top; - if ((x1 < 0) || (y1 < 0)) - return; - - CEnhMetaFileInfo emfinfo(m_meta); - ENHMETAHEADER* pmh = emfinfo.GetEnhMetaFileHeader(); - - // Compute whether we are OK vertically or horizontally - int x2 = pmh->szlDevice.cx; - int y2 = pmh->szlDevice.cy; - int y1p = MulDiv(x1, y2, x2); - int x1p = MulDiv(y1, x2, y2); - ATLASSERT((x1p <= x1) || (y1p <= y1)); - if (x1p <= x1) - { - prc->left = rc.left + (x1 - x1p) / 2; - prc->right = prc->left + x1p; - prc->top = rc.top; - prc->bottom = rc.bottom; - } - else - { - prc->left = rc.left; - prc->right = rc.right; - prc->top = rc.top + (y1 - y1p) / 2; - prc->bottom = prc->top + y1p; - } - } - -// Painting helpers - void DoPaint(CDCHandle dc) - { - // this one is not used - } - - void DoPaint(CDCHandle dc, RECT& rc) - { - CEnhMetaFileInfo emfinfo(m_meta); - ENHMETAHEADER* pmh = emfinfo.GetEnhMetaFileHeader(); - int nOffsetX = MulDiv(m_sizeCurPhysOffset.cx, rc.right-rc.left, pmh->szlDevice.cx); - int nOffsetY = MulDiv(m_sizeCurPhysOffset.cy, rc.bottom-rc.top, pmh->szlDevice.cy); - - dc.OffsetWindowOrg(-nOffsetX, -nOffsetY); - dc.PlayMetaFile(m_meta, &rc); - } - -// Implementation - data - int m_nCurPage; -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CPrintPreviewWindow - Implements a print preview window - -template -class ATL_NO_VTABLE CPrintPreviewWindowImpl : public ATL::CWindowImpl, public CPrintPreview -{ -public: - DECLARE_WND_CLASS_EX(NULL, CS_VREDRAW | CS_HREDRAW, -1) - - enum { m_cxOffset = 10, m_cyOffset = 10 }; - -// Constructor - CPrintPreviewWindowImpl() : m_nMaxPage(0), m_nMinPage(0) - { } - -// Operations - void SetPrintPreviewInfo(HANDLE hPrinter, DEVMODE* pDefaultDevMode, - IPrintJobInfo* pji, int nMinPage, int nMaxPage) - { - CPrintPreview::SetPrintPreviewInfo(hPrinter, pDefaultDevMode, pji); - m_nMinPage = nMinPage; - m_nMaxPage = nMaxPage; - } - - bool NextPage() - { - if (m_nCurPage == m_nMaxPage) - return false; - SetPage(m_nCurPage + 1); - Invalidate(); - return true; - } - - bool PrevPage() - { - if (m_nCurPage == m_nMinPage) - return false; - if (m_nCurPage == 0) - return false; - SetPage(m_nCurPage - 1); - Invalidate(); - return true; - } - -// Message map and handlers - BEGIN_MSG_MAP(CPrintPreviewWindowImpl) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd) - MESSAGE_HANDLER(WM_PAINT, OnPaint) - MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) - END_MSG_MAP() - - LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - return 1; // no need for the background - } - - LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - RECT rc = { 0 }; - - if(wParam != NULL) - { - pT->DoPrePaint((HDC)wParam, rc); - pT->DoPaint((HDC)wParam, rc); - } - else - { - CPaintDC dc(m_hWnd); - pT->DoPrePaint(dc.m_hDC, rc); - pT->DoPaint(dc.m_hDC, rc); - } - - return 0; - } - -// Painting helper - void DoPrePaint(CDCHandle dc, RECT& rc) - { - RECT rcClient = { 0 }; - GetClientRect(&rcClient); - RECT rcArea = rcClient; - T* pT = static_cast(this); - pT; // avoid level 4 warning - ::InflateRect(&rcArea, -pT->m_cxOffset, -pT->m_cyOffset); - if (rcArea.left > rcArea.right) - rcArea.right = rcArea.left; - if (rcArea.top > rcArea.bottom) - rcArea.bottom = rcArea.top; - GetPageRect(rcArea, &rc); - CRgn rgn1, rgn2; - rgn1.CreateRectRgnIndirect(&rc); - rgn2.CreateRectRgnIndirect(&rcClient); - rgn2.CombineRgn(rgn1, RGN_DIFF); - dc.SelectClipRgn(rgn2); - dc.FillRect(&rcClient, COLOR_BTNSHADOW); - dc.SelectClipRgn(NULL); - dc.FillRect(&rc, (HBRUSH)::GetStockObject(WHITE_BRUSH)); - } - -// Implementation - data - int m_nMinPage; - int m_nMaxPage; -}; - - -class CPrintPreviewWindow : public CPrintPreviewWindowImpl -{ -public: - DECLARE_WND_CLASS_EX(_T("WTL_PrintPreview"), CS_VREDRAW | CS_HREDRAW, -1) -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CZoomPrintPreviewWindowImpl - Implements print preview window with zooming - -#ifdef __ATLSCRL_H__ - -template -class ATL_NO_VTABLE CZoomPrintPreviewWindowImpl : public CPrintPreviewWindowImpl< T, TBase, TWinTraits >, public CZoomScrollImpl< T > -{ -public: - bool m_bSized; - - CZoomPrintPreviewWindowImpl() - { - SetScrollExtendedStyle(SCRL_DISABLENOSCROLL); - InitZoom(); - } - - // should be called to reset data members before recreating window - void InitZoom() - { - m_bSized = false; - m_nZoomMode = ZOOMMODE_OFF; - m_fZoomScaleMin = 1.0; - m_fZoomScale = 1.0; - } - - BEGIN_MSG_MAP(CZoomPrintPreviewWindowImpl) - MESSAGE_HANDLER(WM_SETCURSOR, CZoomScrollImpl< T >::OnSetCursor) - MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll) - MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll) - MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel) -#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) - MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel) -#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) - MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange) - MESSAGE_HANDLER(WM_LBUTTONDOWN, CZoomScrollImpl< T >::OnLButtonDown) - MESSAGE_HANDLER(WM_MOUSEMOVE, CZoomScrollImpl< T >::OnMouseMove) - MESSAGE_HANDLER(WM_LBUTTONUP, CZoomScrollImpl< T >::OnLButtonUp) - MESSAGE_HANDLER(WM_CAPTURECHANGED, CZoomScrollImpl< T >::OnCaptureChanged) - MESSAGE_HANDLER(WM_SIZE, OnSize) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd) - MESSAGE_HANDLER(WM_PAINT, OnPaint) - MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) - ALT_MSG_MAP(1) - COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp) - COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown) - COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop) - COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom) - COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft) - COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight) - COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft) - COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight) - END_MSG_MAP() - - LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - SIZE sizeClient = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)}; - POINT ptOffset = m_ptOffset; - SIZE sizeAll = m_sizeAll; - SetScrollSize(sizeClient); - if(sizeAll.cx > 0) - ptOffset.x = ::MulDiv(ptOffset.x, m_sizeAll.cx, sizeAll.cx); - if(sizeAll.cy > 0) - ptOffset.y = ::MulDiv(ptOffset.y, m_sizeAll.cy, sizeAll.cy); - SetScrollOffset(ptOffset); - CScrollImpl< T >::OnSize(uMsg, wParam, lParam, bHandled); - if(!m_bSized) - { - m_bSized = true; - T* pT = static_cast(this); - pT->ShowScrollBar(SB_HORZ, TRUE); - pT->ShowScrollBar(SB_VERT, TRUE); - } - return 0; - } - - LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - return 1; - } - - LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - RECT rc = { 0 }; - - if(wParam != NULL) - { - CDCHandle dc = (HDC)wParam; - int nMapModeSav = dc.GetMapMode(); - dc.SetMapMode(MM_ANISOTROPIC); - SIZE szWindowExt = { 0, 0 }; - dc.SetWindowExt(m_sizeLogAll, &szWindowExt); - SIZE szViewportExt = { 0, 0 }; - dc.SetViewportExt(m_sizeAll, &szViewportExt); - POINT ptViewportOrg = { 0, 0 }; - dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewportOrg); - - pT->DoPrePaint(dc, rc); - pT->DoPaint(dc, rc); - - dc.SetMapMode(nMapModeSav); - dc.SetWindowExt(szWindowExt); - dc.SetViewportExt(szViewportExt); - dc.SetViewportOrg(ptViewportOrg); - } - else - { - CPaintDC dc(pT->m_hWnd); - pT->PrepareDC(dc.m_hDC); - pT->DoPrePaint(dc.m_hDC, rc); - pT->DoPaint(dc.m_hDC, rc); - } - - return 0; - } - - // Painting helpers - void DoPaint(CDCHandle dc) - { - // this one is not used - } - - void DoPrePaint(CDCHandle dc, RECT& rc) - { - RECT rcClient; - GetClientRect(&rcClient); - RECT rcArea = rcClient; - T* pT = static_cast(this); - pT; // avoid level 4 warning - ::InflateRect(&rcArea, -pT->m_cxOffset, -pT->m_cyOffset); - if (rcArea.left > rcArea.right) - rcArea.right = rcArea.left; - if (rcArea.top > rcArea.bottom) - rcArea.bottom = rcArea.top; - GetPageRect(rcArea, &rc); - HBRUSH hbrOld = dc.SelectBrush(::GetSysColorBrush(COLOR_BTNSHADOW)); - dc.PatBlt(rcClient.left, rcClient.top, rc.left - rcClient.left, rcClient.bottom - rcClient.top, PATCOPY); - dc.PatBlt(rc.left, rcClient.top, rc.right - rc.left, rc.top - rcClient.top, PATCOPY); - dc.PatBlt(rc.right, rcClient.top, rcClient.right - rc.right, rcClient.bottom - rcClient.top, PATCOPY); - dc.PatBlt(rc.left, rc.bottom, rc.right - rc.left, rcClient.bottom - rc.bottom, PATCOPY); - dc.SelectBrush((HBRUSH)::GetStockObject(WHITE_BRUSH)); - dc.PatBlt(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); - dc.SelectBrush(::GetSysColorBrush(COLOR_3DDKSHADOW)); - dc.PatBlt(rc.right, rc.top + 4, 4, rc.bottom - rc.top, PATCOPY); - dc.PatBlt(rc.left + 4, rc.bottom, rc.right - rc.left, 4, PATCOPY); - dc.SelectBrush(hbrOld); - } - - void DoPaint(CDCHandle dc, RECT& rc) - { - CEnhMetaFileInfo emfinfo(m_meta); - ENHMETAHEADER* pmh = emfinfo.GetEnhMetaFileHeader(); - int nOffsetX = MulDiv(m_sizeCurPhysOffset.cx, rc.right-rc.left, pmh->szlDevice.cx); - int nOffsetY = MulDiv(m_sizeCurPhysOffset.cy, rc.bottom-rc.top, pmh->szlDevice.cy); - - dc.OffsetWindowOrg(-nOffsetX, -nOffsetY); - dc.PlayMetaFile(m_meta, &rc); - } -}; - -class CZoomPrintPreviewWindow : public CZoomPrintPreviewWindowImpl -{ -public: - DECLARE_WND_CLASS_EX(_T("WTL_ZoomPrintPreview"), CS_VREDRAW | CS_HREDRAW, -1) -}; - -#endif // __ATLSCRL_H__ - -}; // namespace WTL - -#endif // __ATLPRINT_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlres.h b/!NotAdopted/SmartAutoReplier/wtl/atlres.h deleted file mode 100644 index 22fb3e6fdd..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlres.h +++ /dev/null @@ -1,263 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLRES_H__ -#define __ATLRES_H__ - -#pragma once - -#if defined(_WIN32_WCE) && !defined(__ATLRESCE_H__) - #error Use atlresCE.h instead of atlres.h for Windows CE -#endif - - -#ifdef RC_INVOKED -#ifndef _INC_WINDOWS - - #define _INC_WINDOWS - - #ifndef _WIN32_WCE - #define VS_VERSION_INFO 1 - - #ifdef APSTUDIO_INVOKED - #define APSTUDIO_HIDDEN_SYMBOLS // Ignore following symbols - #endif // APSTUDIO_INVOKED - - #ifndef WINVER - #define WINVER 0x0400 // default to Windows Version 4.0 - #endif // !WINVER - - #include - - // operation messages sent to DLGINIT - #define LB_ADDSTRING (WM_USER+1) - #define CB_ADDSTRING (WM_USER+3) - #endif // !_WIN32_WCE - - #ifdef APSTUDIO_INVOKED - #undef APSTUDIO_HIDDEN_SYMBOLS - #endif // APSTUDIO_INVOKED - - #ifdef IDC_STATIC - #undef IDC_STATIC - #endif // IDC_STATIC - #define IDC_STATIC (-1) - -#endif // !_INC_WINDOWS -#endif // RC_INVOKED - -#ifdef APSTUDIO_INVOKED - #define APSTUDIO_HIDDEN_SYMBOLS -#endif // APSTUDIO_INVOKED - -/////////////////////////////////////////////////////////////////////////////// -// ATL resource types - -#ifndef RC_INVOKED - #define RT_DLGINIT MAKEINTRESOURCE(240) - #define RT_TOOLBAR MAKEINTRESOURCE(241) -#endif // RC_INVOKED - -/////////////////////////////////////////////////////////////////////////////// - -#ifdef APSTUDIO_INVOKED - #undef APSTUDIO_HIDDEN_SYMBOLS -#endif // APSTUDIO_INVOKED - -/////////////////////////////////////////////////////////////////////////////// -// Standard window components - -#define ID_SEPARATOR 0 // special separator value -#define ID_DEFAULT_PANE 0 // default status bar pane - -#ifndef RC_INVOKED // code only -// standard control bars (IDW = window ID) - #define ATL_IDW_TOOLBAR 0xE800 // main Toolbar for window - #define ATL_IDW_STATUS_BAR 0xE801 // Status bar window - #define ATL_IDW_COMMAND_BAR 0xE802 // Command bar window - -// parts of a frame window - #define ATL_IDW_CLIENT 0xE900 - #define ATL_IDW_PANE_FIRST 0xE900 // first pane (256 max) - #define ATL_IDW_PANE_LAST 0xE9FF - #define ATL_IDW_HSCROLL_FIRST 0xEA00 // first Horz scrollbar (16 max) - #define ATL_IDW_VSCROLL_FIRST 0xEA10 // first Vert scrollbar (16 max) - - #define ATL_IDW_SIZE_BOX 0xEA20 // size box for splitters - #define ATL_IDW_PANE_SAVE 0xEA21 // to shift ATL_IDW_PANE_FIRST - -// bands for a rebar - #define ATL_IDW_BAND_FIRST 0xEB00 - #define ATL_IDW_BAND_LAST 0xEBFF -#endif // !RC_INVOKED - -/////////////////////////////////////////////////////////////////////////////// -// Standard Commands - -// File commands -#define ID_FILE_NEW 0xE100 -#define ID_FILE_OPEN 0xE101 -#define ID_FILE_CLOSE 0xE102 -#define ID_FILE_SAVE 0xE103 -#define ID_FILE_SAVE_AS 0xE104 -#define ID_FILE_PAGE_SETUP 0xE105 -#define ID_FILE_PRINT_SETUP 0xE106 -#define ID_FILE_PRINT 0xE107 -#define ID_FILE_PRINT_DIRECT 0xE108 -#define ID_FILE_PRINT_PREVIEW 0xE109 -#define ID_FILE_UPDATE 0xE10A -#define ID_FILE_SAVE_COPY_AS 0xE10B -#define ID_FILE_SEND_MAIL 0xE10C - -#define ID_FILE_MRU_FIRST 0xE110 -#define ID_FILE_MRU_FILE1 0xE110 // range - 16 max -#define ID_FILE_MRU_FILE2 0xE111 -#define ID_FILE_MRU_FILE3 0xE112 -#define ID_FILE_MRU_FILE4 0xE113 -#define ID_FILE_MRU_FILE5 0xE114 -#define ID_FILE_MRU_FILE6 0xE115 -#define ID_FILE_MRU_FILE7 0xE116 -#define ID_FILE_MRU_FILE8 0xE117 -#define ID_FILE_MRU_FILE9 0xE118 -#define ID_FILE_MRU_FILE10 0xE119 -#define ID_FILE_MRU_FILE11 0xE11A -#define ID_FILE_MRU_FILE12 0xE11B -#define ID_FILE_MRU_FILE13 0xE11C -#define ID_FILE_MRU_FILE14 0xE11D -#define ID_FILE_MRU_FILE15 0xE11E -#define ID_FILE_MRU_FILE16 0xE11F -#define ID_FILE_MRU_LAST 0xE11F - -// Edit commands -#define ID_EDIT_CLEAR 0xE120 -#define ID_EDIT_CLEAR_ALL 0xE121 -#define ID_EDIT_COPY 0xE122 -#define ID_EDIT_CUT 0xE123 -#define ID_EDIT_FIND 0xE124 -#define ID_EDIT_PASTE 0xE125 -#define ID_EDIT_PASTE_LINK 0xE126 -#define ID_EDIT_PASTE_SPECIAL 0xE127 -#define ID_EDIT_REPEAT 0xE128 -#define ID_EDIT_REPLACE 0xE129 -#define ID_EDIT_SELECT_ALL 0xE12A -#define ID_EDIT_UNDO 0xE12B -#define ID_EDIT_REDO 0xE12C - -// Window commands -#define ID_WINDOW_NEW 0xE130 -#define ID_WINDOW_ARRANGE 0xE131 -#define ID_WINDOW_CASCADE 0xE132 -#define ID_WINDOW_TILE_HORZ 0xE133 -#define ID_WINDOW_TILE_VERT 0xE134 -#define ID_WINDOW_SPLIT 0xE135 -#ifndef RC_INVOKED // code only - #define ATL_IDM_WINDOW_FIRST 0xE130 - #define ATL_IDM_WINDOW_LAST 0xE13F - #define ATL_IDM_FIRST_MDICHILD 0xFF00 // window list starts here - #define ATL_IDM_LAST_MDICHILD 0xFFFD -#endif // !RC_INVOKED -// TabView -#define ID_WINDOW_TABFIRST 0xFF00 // = ATL_IDM_FIRST_MDICHILD -#define ID_WINDOW_TABLAST 0xFFFD -#define ID_WINDOW_SHOWTABLIST 0xFFFE - -// Help and App commands -#define ID_APP_ABOUT 0xE140 -#define ID_APP_EXIT 0xE141 -#define ID_HELP_INDEX 0xE142 -#define ID_HELP_FINDER 0xE143 -#define ID_HELP_USING 0xE144 -#define ID_CONTEXT_HELP 0xE145 // shift-F1 -// special commands for processing help -#define ID_HELP 0xE146 // first attempt for F1 -#define ID_DEFAULT_HELP 0xE147 // last attempt - -// Misc -#define ID_NEXT_PANE 0xE150 -#define ID_PREV_PANE 0xE151 -#define ID_PANE_CLOSE 0xE152 - -// Format -#define ID_FORMAT_FONT 0xE160 - -// Scroll -#define ID_SCROLL_UP 0xE170 -#define ID_SCROLL_DOWN 0xE171 -#define ID_SCROLL_PAGE_UP 0xE172 -#define ID_SCROLL_PAGE_DOWN 0xE173 -#define ID_SCROLL_TOP 0xE174 -#define ID_SCROLL_BOTTOM 0xE175 -#define ID_SCROLL_LEFT 0xE176 -#define ID_SCROLL_RIGHT 0xE177 -#define ID_SCROLL_PAGE_LEFT 0xE178 -#define ID_SCROLL_PAGE_RIGHT 0xE179 -#define ID_SCROLL_ALL_LEFT 0xE17A -#define ID_SCROLL_ALL_RIGHT 0xE17B - -// OLE commands -#define ID_OLE_INSERT_NEW 0xE200 -#define ID_OLE_EDIT_LINKS 0xE201 -#define ID_OLE_EDIT_CONVERT 0xE202 -#define ID_OLE_EDIT_CHANGE_ICON 0xE203 -#define ID_OLE_EDIT_PROPERTIES 0xE204 -#define ID_OLE_VERB_FIRST 0xE210 // range - 16 max -#ifndef RC_INVOKED // code only - #define ID_OLE_VERB_LAST 0xE21F -#endif // !RC_INVOKED - -// View commands (same number used as IDW used for toolbar and status bar) -#define ID_VIEW_TOOLBAR 0xE800 -#define ID_VIEW_STATUS_BAR 0xE801 -#define ID_VIEW_REFRESH 0xE803 -#define ID_VIEW_RIBBON 0xE804 // Ribbon - -/////////////////////////////////////////////////////////////////////////////// -// Standard control IDs - -#ifdef IDC_STATIC - #undef IDC_STATIC -#endif // IDC_STATIC -#define IDC_STATIC (-1) // all static controls - -/////////////////////////////////////////////////////////////////////////////// -// Standard string error/warnings - -// idle status bar message -#define ATL_IDS_IDLEMESSAGE 0xE001 - -#ifndef RC_INVOKED // code only - #define ATL_IDS_SCFIRST 0xEF00 -#endif // !RC_INVOKED - -#define ATL_IDS_SCSIZE 0xEF00 -#define ATL_IDS_SCMOVE 0xEF01 -#define ATL_IDS_SCMINIMIZE 0xEF02 -#define ATL_IDS_SCMAXIMIZE 0xEF03 -#define ATL_IDS_SCNEXTWINDOW 0xEF04 -#define ATL_IDS_SCPREVWINDOW 0xEF05 -#define ATL_IDS_SCCLOSE 0xEF06 -#define ATL_IDS_SCRESTORE 0xEF12 -#define ATL_IDS_SCTASKLIST 0xEF13 - -#define ATL_IDS_MDICHILD 0xEF1F -#define ATL_IDS_MRU_FILE 0xEFDA - -/////////////////////////////////////////////////////////////////////////////// -// Misc. control IDs - -// Property Sheet control id's (determined with Spy++) -#define ID_APPLY_NOW 0x3021 -#define ID_WIZBACK 0x3023 -#define ID_WIZNEXT 0x3024 -#define ID_WIZFINISH 0x3025 -#define ATL_IDC_TAB_CONTROL 0x3020 - -#endif // __ATLRES_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlresce.h b/!NotAdopted/SmartAutoReplier/wtl/atlresce.h deleted file mode 100644 index 3b2b93388f..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlresce.h +++ /dev/null @@ -1,93 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLRESCE_H__ -#define __ATLRESCE_H__ - -#pragma once - -#ifndef _WIN32_WCE - #error atlresCE.h is only for Windows CE -#endif - - -#ifdef RC_INVOKED -#ifndef _INC_WINDOWS - - #define VS_VERSION_INFO 1 - - #ifdef APSTUDIO_INVOKED - #define APSTUDIO_HIDDEN_SYMBOLS // Ignore following symbols - #endif // APSTUDIO_INVOKED - - #ifndef WINVER - #define WINVER 0x0400 // default to Windows Version 4.0 - #endif // !WINVER - - #if !defined(WCEOLE_ENABLE_DIALOGEX) - #define DIALOGEX DIALOG DISCARDABLE - #endif - - #include - #define SHMENUBAR RCDATA - - #if defined(SHELLSDK_MODULES_AYGSHELL) - #include - #else - #define NOMENU 0xFFFF - #define IDS_SHNEW 1 - #define IDM_SHAREDNEW 10 - #define IDM_SHAREDNEWDEFAULT 11 - #endif - #ifndef I_IMAGENONE - #define I_IMAGENONE (-2) - #endif - - #include - -#endif // !_INC_WINDOWS -#endif // RC_INVOKED - -#include "atlres.h" - -#ifdef APSTUDIO_INVOKED - #undef APSTUDIO_HIDDEN_SYMBOLS -#endif // APSTUDIO_INVOKED - -// Visual Studio dialog editor bug fix -#ifndef DS_FIXEDSYS - #define DS_FIXEDSYS 0 -#endif - -#define IDC_INFOSTATIC 0xFFFE // == IDC_STATIC -1 - -/////////////////////////////////////////////////////////////////////////////// -// Smartphone and PPC 2005 Resource IDs - -// Command and associated string resource IDs -#define ID_MENU_OK 0xE790 -#define ID_MENU_CANCEL 0xE791 -#define ID_MENU 0xE792 -#define ID_ACTION 0xE793 -#define ID_VIEW_FULLSCREEN 0xE802 - -// MenuBar resource IDs -#define ATL_IDM_MENU_DONE 0xE701 -#define ATL_IDM_MENU_CANCEL 0xE702 -#define ATL_IDM_MENU_DONECANCEL 0xE703 - -// Default device MenuBar control ID and MenuBar resource ID -#define ATL_IDW_MENU_BAR 0xE802 - -// SmartPhone spinned controls ID offset for CSpinCtrl -#define ATL_IDW_SPIN_ID 9999 - -#endif // __ATLRESCE_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlribbon.h b/!NotAdopted/SmartAutoReplier/wtl/atlribbon.h deleted file mode 100644 index 2b21026441..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlribbon.h +++ /dev/null @@ -1,3446 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLRIBBON_H__ -#define __ATLRIBBON_H__ - -#pragma once - -#if (_MSC_VER < 1500) - #error atlribbon.h requires Visual C++ 2008 compiler or higher -#endif - -#ifndef _UNICODE - #error atlribbon.h requires the Unicode character set -#endif - -#if !defined(NTDDI_WIN7) || (NTDDI_VERSION < NTDDI_WIN7) - #error atlribbon.h requires the Windows 7 SDK or higher -#endif - -#ifdef _WIN32_WCE - #error atlribbon.h is not supported on Windows CE -#endif - -#ifndef __ATLAPP_H__ - #error atlribbon.h requires atlapp.h to be included first -#endif - -#if (_ATL_VER < 0x0700) - #include - #pragma comment(lib, "shlwapi.lib") -#endif - -#include // for RecentDocumentList classes -#include // for Frame and UpdateUI classes -#include // required for atlctrlw.h -#include // for CCommandBarCtrl - -#if !defined(_WTL_USE_CSTRING) && !defined(__ATLSTR_H__) - #pragma warning(disable : 4530) // unwind semantics not enabled - #include - #pragma warning(default : 4530) -#endif - -#include -#pragma comment(lib, "dwmapi.lib") - -#include -#include -#pragma comment(lib, "propsys.lib") - -#include // for CHARFORMAT2 - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CRibbonUpdateUI : Automatic mapping of ribbon UI elements -// -// RibbonUI::Text -// RibbonUI::CharFormat -// RibbonUI::ICtrl -// RibbonUI::CtrlImpl -// RibbonUI::CommandCtrlImpl -// RibbonUI::ItemProperty -// RibbonUI::CollectionImplBase -// RibbonUI::CollectionImpl -// RibbonUI::TextCollectionImpl -// RibbonUI::ItemCollectionImpl -// RibbonUI::ComboCollectionImpl -// RibbonUI::CommandCollectionImpl -// RibbonUI::ToolbarCollectionImpl -// RibbonUI::SimpleCollectionImpl -// RibbonUI::CollectionCtrlImpl -// RibbonUI::ToolbarGalleryCtrlImpl -// RibbonUI::SimpleCollectionCtrlImpl -// RibbonUI::RecentItemsCtrlImpl -// RibbonUI::FontCtrlImpl -// RibbonUI::ColorCtrlImpl -// RibbonUI::SpinnerCtrlImpl -// -// RibbonUI::CRibbonImpl -// CRibbonImpl::CRibbonComboCtrl -// CRibbonImpl::CRibbonItemGalleryCtrl -// CRibbonImpl::CRibbonCommandGalleryCtrl -// CRibbonImpl::CRibbonToolbarGalleryCtrl -// CRibbonImpl::CRibbonSimpleComboCtrl -// CRibbonImpl::CRibbonSimpleGalleryCtrl -// CRibbonImpl::CRibbonRecentItemsCtrl -// CRibbonImpl::CRibbonColorCtrl -// CRibbonImpl::CRibbonFontCtrl -// CRibbonImpl::CRibbonSpinnerCtrl -// CRibbonImpl::CRibbonFloatSpinnerCtrl -// CRibbonImpl::CRibbonCommandCtrl -// -// CRibbonFrameWindowImplBase -// CRibbonFrameWindowImpl -// CRibbonMDIFrameWindowImpl -// CRibbonPersist -// -// Global functions: -// RibbonUI::SetPropertyVal() -// RibbonUI::GetImage() - - -// Constants - -#ifndef RIBBONUI_MAX_TEXT - #define RIBBONUI_MAX_TEXT 128 -#endif - -#define TWIPS_PER_POINT 20 // For font size - - -namespace WTL -{ - -/////////////////////////////////////////////////////////////////////////////// -// CRibbonUpdateUI : Automatic mapping of ribbon UI elements - -template -class CRibbonUpdateUI : public CAutoUpdateUI -{ -public: - enum - { - UPDUI_RIBBON = 0x0080, - UPDUI_PERSIST = 0x0020 - }; - - bool IsRibbonElement(const _AtlUpdateUIMap& UIMap) - { - return (UIMap.m_wType & UPDUI_RIBBON) != 0; - } - - bool IsRibbonID(UINT nID) - { - for(int i = 0; i < m_arrUIMap.GetSize(); i++) - { - if(m_arrUIMap[i].m_nID == nID) - return IsRibbonElement(m_arrUIMap[i]); - } - - return false; - } - -// Element - bool UIAddRibbonElement(UINT nID) - { - return UIAddElement(nID); - } - - bool UIRemoveRibbonElement(UINT nID) - { - return UIRemoveElement(nID); - } - - bool UIPersistElement(UINT nID, bool bPersist = true) - { - return bPersist ? - UIAddElement(nID) : - UIRemoveElement(nID); - } - -// methods for Ribbon elements - BOOL UISetText(int nID, LPCWSTR sText, BOOL bForceUpdate = FALSE) - { - T* pT = static_cast(this); - BOOL bRes = CUpdateUIBase::UISetText(nID, sText, bForceUpdate); - if (pT->IsRibbonUI() && IsRibbonID(nID)) - bRes = SUCCEEDED(pT->InvalidateProperty(nID, UI_PKEY_Label)); - return bRes; - } - - BOOL UISetText(int nID, UINT uIdResource, BOOL bForceUpdate = FALSE) - { - CTempBuffer sText(RIBBONUI_MAX_TEXT); - return AtlLoadString(uIdResource, sText, RIBBONUI_MAX_TEXT) ? - UISetText(nID, sText, bForceUpdate) : - E_FAIL; - } - - LPCTSTR UIGetText(int nID) - { - T* pT = static_cast(this); - LPCTSTR sUI = CAutoUpdateUI::UIGetText(nID); - - // replace 'tab' by 'space' for RibbonUI elements - if (sUI && pT->IsRibbonUI() && IsRibbonID(nID) && wcschr(sUI, L'\t')) - { - static WCHAR sText[RIBBONUI_MAX_TEXT] = { 0 }; - wcscpy_s(sText, sUI); - *wcschr(sText, L'\t') = L' '; - return sText; - } - else - { - return sUI; - } - } - - BOOL UIEnable(int nID, BOOL bEnable, BOOL bForceUpdate = FALSE) - { - T* pT = static_cast(this); - BOOL bRes = CUpdateUIBase::UIEnable(nID, bEnable, bForceUpdate); - if (pT->IsRibbonUI() && IsRibbonID(nID)) - bRes = SUCCEEDED(pT->SetProperty((WORD)nID, UI_PKEY_Enabled, bEnable)); - return bRes; - } - - BOOL UISetCheck(int nID, INT nCheck, BOOL bForceUpdate = FALSE) - { - if ((nCheck == 0) || (nCheck == 1)) - return UISetCheck(nID, nCheck != 0, bForceUpdate); - else - return CUpdateUIBase::UISetCheck(nID, nCheck, bForceUpdate); - } - - BOOL UISetCheck(int nID, bool bCheck, BOOL bForceUpdate = FALSE) - { - T* pT = static_cast(this); - BOOL bRes = CUpdateUIBase::UISetCheck(nID, bCheck, bForceUpdate); - if (bRes && pT->IsRibbonUI() && IsRibbonID(nID)) - bRes = SUCCEEDED(pT->SetProperty((WORD)nID, UI_PKEY_BooleanValue, bCheck)); - return bRes; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// RibbonUI namespace -// - -namespace RibbonUI -{ - -// Minimal string allocation support for various PROPERTYKEY values -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - typedef _CSTRING_NS::CString Text; -#else - class Text : public std::wstring - { - public: - Text(std::wstring& s) : std::wstring(s) - { } - Text(LPCWSTR s) : std::wstring(s) - { } - Text() - { } - bool IsEmpty() - { - return empty(); - } - operator LPCWSTR() - { - return c_str(); - } - Text& operator =(LPCWSTR s) - { - return static_cast(std::wstring::operator =(s)); - } - }; -#endif - -// PROPERTYKEY enum and helpers -enum k_KEY -{ - // state - k_Enabled = 1, k_BooleanValue = 200, - // text properties - k_LabelDescription = 2, k_Keytip = 3, k_Label = 4, k_TooltipDescription = 5, k_TooltipTitle = 6, - // image properties - k_LargeImage = 7, k_LargeHighContrastImage = 8, k_SmallImage = 9, k_SmallHighContrastImage = 10, - // collection properties - k_ItemsSource = 101, k_Categories = 102, k_SelectedItem = 104, - // collection item properties - k_CommandId = 100, k_CategoryId = 103, k_CommandType = 105, k_ItemImage = 106, - // combo control property - k_StringValue = 202, - // spinner control properties - k_DecimalValue = 201, k_MaxValue = 203, k_MinValue, k_Increment, k_DecimalPlaces, k_FormatString, k_RepresentativeString = 208, - // font control properties - k_FontProperties = 300, k_FontProperties_Family, k_FontProperties_Size, k_FontProperties_Bold, k_FontProperties_Italic = 304, - k_FontProperties_Underline = 305, k_FontProperties_Strikethrough, k_FontProperties_VerticalPositioning, k_FontProperties_ForegroundColor = 308, - k_FontProperties_BackgroundColor = 309, k_FontProperties_ForegroundColorType, k_FontProperties_BackgroundColorType, k_FontProperties_ChangedProperties = 312, - k_FontProperties_DeltaSize = 313, - // recent items properties - k_RecentItems = 350, k_Pinned = 351, - // color control properties - k_Color = 400, k_ColorType = 401, k_ColorMode, - k_ThemeColorsCategoryLabel = 403, k_StandardColorsCategoryLabel, k_RecentColorsCategoryLabel = 405, k_AutomaticColorLabel = 406, - k_NoColorLabel = 407, k_MoreColorsLabel = 408, - k_ThemeColors = 409, k_StandardColors = 410, k_ThemeColorsTooltips = 411, k_StandardColorsTooltips = 412, - // Ribbon state - k_Viewable = 1000, k_Minimized = 1001, k_QuickAccessToolbarDock = 1002, k_ContextAvailable = 1100, - // Ribbon UI colors - k_GlobalBackgroundColor = 2000, k_GlobalHighlightColor, k_GlobalTextColor = 2002 -}; - -inline k_KEY k_(REFPROPERTYKEY key) -{ - return (k_KEY)key.fmtid.Data1; -} - -// PROPERTYKEY value assignment and specializations -// -template -HRESULT SetPropertyVal(REFPROPERTYKEY key, V val, PROPVARIANT* ppv) -{ - switch (k_(key)) - { - case k_Enabled: - case k_BooleanValue: - return InitPropVariantFromBoolean(val, ppv); - default: - return UIInitPropertyFromUInt32(key, val, ppv); - } -} - -inline HRESULT SetPropertyVal(REFPROPERTYKEY key, DOUBLE val, PROPVARIANT* ppv) -{ - return SetPropertyVal(key, (LONG)val, ppv); -} - -inline HRESULT SetPropertyVal(REFPROPERTYKEY key, IUIImage* val, PROPVARIANT* ppv) -{ - HRESULT hr = UIInitPropertyFromImage(key, val, ppv); - ATLVERIFY(val->Release() == 1); - return hr; -} - -inline HRESULT SetPropertyVal(REFPROPERTYKEY key, IUnknown* val, PROPVARIANT* ppv) -{ - return UIInitPropertyFromInterface(key, val, ppv); -} - -inline HRESULT SetPropertyVal(REFPROPERTYKEY key, IPropertyStore* val, PROPVARIANT* ppv) -{ - return UIInitPropertyFromInterface(key, val, ppv); -} - -inline HRESULT SetPropertyVal(REFPROPERTYKEY key, SAFEARRAY* val, PROPVARIANT* ppv) -{ - return UIInitPropertyFromIUnknownArray(key, val, ppv); -} - -inline HRESULT SetPropertyVal(REFPROPERTYKEY key, DECIMAL* val, PROPVARIANT* ppv) -{ - return UIInitPropertyFromDecimal(key, *val, ppv); -} - -inline HRESULT SetPropertyVal(REFPROPERTYKEY key, bool val, PROPVARIANT* ppv) -{ - return UIInitPropertyFromBoolean(key, val, ppv); -} - -inline HRESULT SetPropertyVal(REFPROPERTYKEY key, LPCWSTR val, PROPVARIANT* ppv) -{ - return UIInitPropertyFromString(key, val, ppv); -} - -// CharFormat helper struct for RibbonUI font control -// -struct CharFormat : CHARFORMAT2 -{ - // Default constructor - CharFormat() - { - cbSize = sizeof CHARFORMAT2; - Reset(); - } - - // Copy constructor - CharFormat(const CharFormat& cf) - { - CopyMemory(this, &cf, sizeof CHARFORMAT2); - } - - // Assign operator - CharFormat& operator =(const CharFormat& cf) - { - CopyMemory(this, &cf, sizeof CHARFORMAT2); - return (*this); - } - - void Reset() - { - uValue = dwMask = dwEffects = 0; - PropVariantInit(&propvar); - } - - void operator <<(IPropertyStore* pStore) - { - if (pStore == NULL) - { - ATLASSERT(FALSE); - return; - } - - static void (CharFormat::*Getk_[])(IPropertyStore*) = - { - &CharFormat::Getk_Family, - &CharFormat::Getk_FontProperties_Size, - &CharFormat::Getk_MaskEffect, - &CharFormat::Getk_MaskEffect, - &CharFormat::Getk_MaskEffect, - &CharFormat::Getk_MaskEffect, - &CharFormat::Getk_VerticalPositioning, - &CharFormat::Getk_Color, - &CharFormat::Getk_Color, - &CharFormat::Getk_ColorType, - &CharFormat::Getk_ColorType, - }; - - DWORD nProps = 0; - Reset(); - - ATLVERIFY(SUCCEEDED(pStore->GetCount(&nProps))); - for (DWORD iProp = 0; iProp < nProps; iProp++) - { - PROPERTYKEY key; - ATLVERIFY(SUCCEEDED(pStore->GetAt(iProp, &key))); - ATLASSERT(k_(key) >= k_FontProperties_Family); - - if (k_(key) <= k_FontProperties_BackgroundColorType) - (this->*Getk_[k_(key) - k_FontProperties_Family])(pStore); - } - } - - void operator >>(IPropertyStore* pStore) - { - if (pStore == NULL) - { - ATLASSERT(FALSE); - return; - } - - PutFace(pStore); - PutSize(pStore); - PutMaskEffect(CFM_BOLD, CFE_BOLD, UI_PKEY_FontProperties_Bold, pStore); - PutMaskEffect(CFM_ITALIC, CFE_ITALIC, UI_PKEY_FontProperties_Italic, pStore); - PutMaskEffect(CFM_UNDERLINE, CFE_UNDERLINE, UI_PKEY_FontProperties_Underline, pStore); - PutMaskEffect(CFM_STRIKEOUT, CFE_STRIKEOUT, UI_PKEY_FontProperties_Strikethrough, pStore); - PutVerticalPos(pStore); - PutColor(pStore); - PutBackColor(pStore); - } - -private: - PROPVARIANT propvar; - UINT uValue; - - // Getk_ functions - void Getk_Family(IPropertyStore* pStore) - { - if (SUCCEEDED(pStore->GetValue(UI_PKEY_FontProperties_Family, &propvar))) - { - PropVariantToString(propvar, szFaceName, LF_FACESIZE); - if (*szFaceName) - dwMask |= CFM_FACE; - } - } - - void Getk_FontProperties_Size(IPropertyStore* pStore) - { - if (SUCCEEDED(pStore->GetValue(UI_PKEY_FontProperties_Size, &propvar))) - { - DECIMAL decSize; - UIPropertyToDecimal(UI_PKEY_FontProperties_Size, propvar, &decSize); - DOUBLE dSize; - VarR8FromDec(&decSize, &dSize); - if (dSize > 0) - { - dwMask |= CFM_SIZE; - yHeight = (LONG)(dSize * TWIPS_PER_POINT); - } - } - } - - template - void Getk_MaskEffect(IPropertyStore* pStore) - { - if (SUCCEEDED(pStore->GetValue(key, &propvar))) - { - UIPropertyToUInt32(key, propvar, &uValue); - if ((UI_FONTPROPERTIES)uValue != UI_FONTPROPERTIES_NOTAVAILABLE) - { - dwMask |= t_dwMask; - dwEffects |= ((UI_FONTPROPERTIES) uValue == UI_FONTPROPERTIES_SET) ? t_dwEffects : 0; - } - } - } - - void Getk_VerticalPositioning(IPropertyStore* pStore) - { - if (SUCCEEDED(pStore->GetValue(UI_PKEY_FontProperties_VerticalPositioning, &propvar))) - { - UIPropertyToUInt32(UI_PKEY_FontProperties_VerticalPositioning, propvar, &uValue); - UI_FONTVERTICALPOSITION uVerticalPosition = (UI_FONTVERTICALPOSITION) uValue; - if ((uVerticalPosition != UI_FONTVERTICALPOSITION_NOTAVAILABLE)) - { - dwMask |= (CFM_SUPERSCRIPT | CFM_SUBSCRIPT); - if (uVerticalPosition != UI_FONTVERTICALPOSITION_NOTSET) - { - dwEffects |= (uVerticalPosition == UI_FONTVERTICALPOSITION_SUPERSCRIPT) ? CFE_SUPERSCRIPT : CFE_SUBSCRIPT; - } - } - } - } - - template - void Getk_Color(IPropertyStore* pStore) - { - UINT32 color; - if (SUCCEEDED(pStore->GetValue(key, &propvar))) - { - UIPropertyToUInt32(key, propvar, &color); - dwMask |= t_dwMask; - - if (t_dwMask == CFM_COLOR) - crTextColor = color; - else - crBackColor = color; - } - } - - template - void Getk_ColorType(IPropertyStore* pStore) - { - if (SUCCEEDED(pStore->GetValue(key, &propvar))) - { - UIPropertyToUInt32(key, propvar, &uValue); - if (t_type == (UI_SWATCHCOLORTYPE)uValue) - { - dwMask |= t_dwMask; - dwEffects |= t_dwEffects; - } - } - } - - // Put functions - void PutMaskEffect(WORD dwMaskVal, WORD dwEffectVal, REFPROPERTYKEY key, IPropertyStore* pStore) - { - PROPVARIANT propvar; - UI_FONTPROPERTIES uProp = UI_FONTPROPERTIES_NOTAVAILABLE; - if ((dwMask & dwMaskVal) != 0) - uProp = dwEffects & dwEffectVal ? UI_FONTPROPERTIES_SET : UI_FONTPROPERTIES_NOTSET; - SetPropertyVal(key, uProp, &propvar); - pStore->SetValue(key, propvar); - } - - void PutVerticalPos(IPropertyStore* pStore) - { - PROPVARIANT propvar; - UI_FONTVERTICALPOSITION uProp = UI_FONTVERTICALPOSITION_NOTAVAILABLE; - - if ((dwMask & CFE_SUBSCRIPT) != 0) - { - if ((dwMask & CFM_SUBSCRIPT) && (dwEffects & CFE_SUBSCRIPT)) - uProp = UI_FONTVERTICALPOSITION_SUBSCRIPT; - else - uProp = UI_FONTVERTICALPOSITION_SUPERSCRIPT; - } - else if ((dwMask & CFM_OFFSET) != 0) - { - if (yOffset > 0) - uProp = UI_FONTVERTICALPOSITION_SUPERSCRIPT; - else if (yOffset < 0) - uProp = UI_FONTVERTICALPOSITION_SUBSCRIPT; - } - - SetPropertyVal(UI_PKEY_FontProperties_VerticalPositioning, uProp, &propvar); - pStore->SetValue(UI_PKEY_FontProperties_VerticalPositioning, propvar); - } - - void PutFace(IPropertyStore* pStore) - { - PROPVARIANT propvar; - SetPropertyVal(UI_PKEY_FontProperties_Family, - dwMask & CFM_FACE ? szFaceName : L"", &propvar); - pStore->SetValue(UI_PKEY_FontProperties_Family, propvar); - } - - void PutSize(IPropertyStore* pStore) - { - PROPVARIANT propvar; - DECIMAL decVal; - - if ((dwMask & CFM_SIZE) != 0) - VarDecFromR8((DOUBLE)yHeight / TWIPS_PER_POINT, &decVal); - else - VarDecFromI4(0, &decVal); - - SetPropertyVal(UI_PKEY_FontProperties_Size, &decVal, &propvar); - pStore->SetValue(UI_PKEY_FontProperties_Size, propvar); - } - - void PutColor(IPropertyStore* pStore) - { - if ((dwMask & CFM_COLOR) != 0) - if ((dwEffects & CFE_AUTOCOLOR) == 0) - { - SetPropertyVal(UI_PKEY_FontProperties_ForegroundColorType, UI_SWATCHCOLORTYPE_RGB, &propvar); - pStore->SetValue(UI_PKEY_FontProperties_ForegroundColorType, propvar); - - SetPropertyVal(UI_PKEY_FontProperties_ForegroundColor, crTextColor, &propvar); - pStore->SetValue(UI_PKEY_FontProperties_ForegroundColor, propvar); - } - else - { - SetPropertyVal(UI_PKEY_FontProperties_ForegroundColorType, UI_SWATCHCOLORTYPE_AUTOMATIC, &propvar); - pStore->SetValue(UI_PKEY_FontProperties_ForegroundColorType, propvar); - } - } - - void PutBackColor(IPropertyStore* pStore) - { - if (((dwMask & CFM_BACKCOLOR) != 0) && ((dwEffects & CFE_AUTOBACKCOLOR) == 0)) - { - SetPropertyVal(UI_PKEY_FontProperties_BackgroundColorType, UI_SWATCHCOLORTYPE_RGB, &propvar); - pStore->SetValue(UI_PKEY_FontProperties_BackgroundColorType, propvar); - - SetPropertyVal(UI_PKEY_FontProperties_BackgroundColor, crBackColor, &propvar); - pStore->SetValue(UI_PKEY_FontProperties_BackgroundColor, propvar); - } - else - { - SetPropertyVal(UI_PKEY_FontProperties_BackgroundColorType, UI_SWATCHCOLORTYPE_NOCOLOR, &propvar); - pStore->SetValue(UI_PKEY_FontProperties_BackgroundColorType, propvar); - } - } -}; - -// IUIImage helper -// -inline IUIImage* GetImage(HBITMAP hbm, UI_OWNERSHIP owner) -{ - ATLASSERT(hbm); - IUIImage* pIUII = NULL; - ATL::CComPtr pIFB; - - if SUCCEEDED(pIFB.CoCreateInstance(CLSID_UIRibbonImageFromBitmapFactory)) - ATLVERIFY(SUCCEEDED(pIFB->CreateImage(hbm, owner, &pIUII))); - - return pIUII; -} - - -/////////////////////////////////////////////////////////////////////////////// -// Ribbon control classes - -// RibbonUI::ICtrl abstract interface of RibbonUI::CRibbonImpl and all RibbonUI control classes -// -struct ICtrl -{ - virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, - const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, - IUISimplePropertySet* pCommandExecutionProperties) = 0; - - virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, - const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) = 0; -}; - -// RibbonUI::CtrlImpl base class for all ribbon controls -// -template -class ATL_NO_VTABLE CtrlImpl : public ICtrl -{ -protected: - T* m_pWndRibbon; - -public: - typedef T WndRibbon; - - CtrlImpl() : m_pWndRibbon(T::pWndRibbon) - { } - - WndRibbon& GetWndRibbon() - { - return *m_pWndRibbon; - } - - static WORD GetID() - { - return t_ID; - } - - Text m_sTxt[5]; - - // Operations - HRESULT Invalidate() - { - return GetWndRibbon().InvalidateCtrl(GetID()); - } - - HRESULT Invalidate(REFPROPERTYKEY key, UI_INVALIDATIONS flags = UI_INVALIDATIONS_PROPERTY) - { - return GetWndRibbon().InvalidateProperty(GetID(), key, flags); - } - - HRESULT SetText(REFPROPERTYKEY key, LPCWSTR sTxt, bool bUpdate = false) - { - ATLASSERT((k_(key) <= k_TooltipTitle) && (k_(key) >= k_LabelDescription)); - - m_sTxt[k_(key) - k_LabelDescription] = sTxt; - - return bUpdate ? - GetWndRibbon().InvalidateProperty(GetID(), key) : - S_OK; - } - - // Implementation - template - HRESULT SetProperty(REFPROPERTYKEY key, V val) - { - return GetWndRibbon().SetProperty(GetID(), key, val); - } - - HRESULT OnGetText(REFPROPERTYKEY key, PROPVARIANT* ppv) - { - ATLASSERT((k_(key) <= k_TooltipTitle) && (k_(key) >= k_LabelDescription)); - - const INT iText = k_(key) - k_LabelDescription; - if (m_sTxt[iText].IsEmpty()) - if (LPCWSTR sText = GetWndRibbon().OnRibbonQueryText(GetID(), key)) - m_sTxt[iText] = sText; - - return !m_sTxt[iText].IsEmpty() ? - SetPropertyVal(key, (LPCWSTR)m_sTxt[iText], ppv) : - S_OK; - } - - virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, - const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, - IUISimplePropertySet* pCommandExecutionProperties) - { - ATLASSERT(nCmdID == t_ID); - return GetWndRibbon().DoExecute(nCmdID, verb, key, ppropvarValue, pCommandExecutionProperties); - } - - virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, - const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) - { - ATLASSERT(nCmdID == t_ID); - - const INT iMax = k_TooltipTitle - k_LabelDescription; - const INT iVal = k_(key) - k_LabelDescription; - - return (iVal <= iMax) && (iVal >= 0) ? - OnGetText(key, ppropvarNewValue) : - GetWndRibbon().DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); - } -}; - -// CommandCtrlImpl base class for most ribbon controls -// -template -class CommandCtrlImpl : public CtrlImpl -{ -public: - CBitmap m_hbm[4]; - - HRESULT SetImage(REFPROPERTYKEY key, HBITMAP hbm, bool bUpdate = false) - { - ATLASSERT((k_(key) <= k_SmallHighContrastImage) && (k_(key) >= k_LargeImage)); - - m_hbm[k_(key) - k_LargeImage].Attach(hbm); - - return bUpdate ? - GetWndRibbon().InvalidateProperty(GetID(), key) : - S_OK; - } - - HRESULT OnGetImage(REFPROPERTYKEY key, PROPVARIANT* ppv) - { - ATLASSERT((k_(key) <= k_SmallHighContrastImage) && (k_(key) >= k_LargeImage)); - - const INT iImage = k_(key) - k_LargeImage; - - if (m_hbm[iImage].IsNull()) - m_hbm[iImage] = GetWndRibbon().OnRibbonQueryImage(GetID(), key); - - return m_hbm[iImage].IsNull() ? - E_NOTIMPL : - SetPropertyVal(key, GetImage(m_hbm[iImage], UI_OWNERSHIP_COPY), ppv); - } - - virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, - const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) - { - ATLASSERT (nCmdID == GetID()); - - return (k_(key) <= k_SmallHighContrastImage) && (k_(key) >= k_LargeImage) ? - OnGetImage(key, ppropvarNewValue) : - CtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// Ribbon collection base classes - -// ItemProperty class: ribbon callback for each item in a collection -// -template -class ItemProperty : public IUISimplePropertySet -{ -public: - ItemProperty(UINT i, TCollection* pCollection) : m_Index(i), m_pCollection(pCollection) - { } - - const UINT m_Index; - TCollection* m_pCollection; - - // IUISimplePropertySet method. - STDMETHODIMP GetValue(REFPROPERTYKEY key, PROPVARIANT *value) - { - return m_pCollection->OnGetItem(m_Index, key, value); - } - - // IUnknown methods. - STDMETHODIMP_(ULONG) AddRef() - { - return 1; - } - - STDMETHODIMP_(ULONG) Release() - { - return 1; - } - - STDMETHODIMP QueryInterface(REFIID iid, void** ppv) - { - if ((iid == __uuidof(IUnknown)) || (iid == __uuidof(IUISimplePropertySet))) - { - *ppv = this; - return S_OK; - } - else - { - return E_NOINTERFACE; - } - } -}; - - -// CollectionImplBase: base class for all RibbonUI collections -// -template -class CollectionImplBase -{ - typedef CollectionImplBase thisClass; - -public: - CollectionImplBase() - { - for (int i = 0; i < t_size; i++) - m_apItems[i] = new ItemProperty(i, static_cast(this)); - } - - ~CollectionImplBase() - { - for (int i = 0; i < t_size; i++) - delete m_apItems[i]; - } - -// Data members - ItemProperty* m_apItems[t_size]; -}; - -// CollectionImpl: handles categories and collecton resizing -// -template -class CollectionImpl : public CollectionImplBase, t_items + t_categories> -{ - typedef CollectionImpl thisClass; -public: - typedef thisClass Collection; - - CollectionImpl() : m_size(t_items) - { - FillMemory(m_auItemCat, sizeof m_auItemCat, 0xff); // UI_COLLECTION_INVALIDINDEX - } - - UINT32 m_auItemCat[t_items]; - Text m_asCatName[max(t_categories, 1)]; - size_t m_size; - -// Operations - HRESULT SetItemCategory(UINT uItem, UINT uCat, bool bUpdate = false) - { - ATLASSERT((uItem < t_items) && (uCat < t_categories)); - - m_auItemCat[uItem] = uCat; - - return bUpdate ? InvalidateItems() : S_OK; - } - - HRESULT SetCategoryText(UINT uCat, LPCWSTR sText, bool bUpdate = false) - { - ATLASSERT(uCat < t_categories); - - m_asCatName[uCat] = sText; - - return bUpdate ? InvalidateCategories() : S_OK; - } - - HRESULT Resize(size_t size, bool bUpdate = false) - { - ATLASSERT(size <= t_items); - - m_size = size; - - return bUpdate ? InvalidateItems() : S_OK; - } - -// Implementation - HRESULT OnGetItem(UINT uIndex, REFPROPERTYKEY key, PROPVARIANT *value) - { - ATLASSERT(uIndex < t_items + t_categories); - TCtrl* pCtrl = static_cast(this); - - return uIndex < t_items ? - pCtrl->DoGetItem(uIndex, key, value) : - pCtrl->DoGetCategory(uIndex - t_items, key, value); - } - - HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) - { - ATLASSERT(k_(key) == k_CategoryId); - UINT32 uCat = UI_COLLECTION_INVALIDINDEX; - - if (t_categories != 0) - { - if (m_auItemCat[uItem] == UI_COLLECTION_INVALIDINDEX) - { - TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); - m_auItemCat[uItem] = ribbon.OnRibbonQueryItemCategory(TCtrl::GetID(), uItem); - } - uCat = m_auItemCat[uItem]; - } - - return SetPropertyVal(key, uCat, value); - } - - HRESULT DoGetCategory(UINT uCat, REFPROPERTYKEY key, PROPVARIANT *value) - { - HRESULT hr = S_OK; - - switch (k_(key)) - { - case k_Label: - if (m_asCatName[uCat].IsEmpty()) - { - TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); - m_asCatName[uCat] = ribbon.OnRibbonQueryCategoryText(TCtrl::GetID(), uCat); - } - hr = SetPropertyVal(key, (LPCWSTR)m_asCatName[uCat], value); - break; - case k_CategoryId: - hr = SetPropertyVal(key, uCat, value); - break; - default: - ATLASSERT(FALSE); - break; - } - - return hr; - } - - HRESULT InvalidateItems() - { - return static_cast(this)->Invalidate(UI_PKEY_ItemsSource); - } - - HRESULT InvalidateCategories() - { - return static_cast(this)->Invalidate(UI_PKEY_Categories); - } - - HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, - const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* /*ppropvarNewValue*/) - { - ATLASSERT(nCmdID == TCtrl::GetID()); - nCmdID; // avoid level 4 warning - - HRESULT hr = E_NOTIMPL; - switch (k_(key)) - { - case k_ItemsSource: - { - ATL::CComQIPtr pIUICollection(ppropvarCurrentValue->punkVal); - ATLASSERT(pIUICollection); - hr = pIUICollection->Clear(); - for (UINT i = 0; i < m_size; i++) - { - if FAILED(hr = pIUICollection->Add(m_apItems[i])) - break; - } - ATLASSERT(SUCCEEDED(hr)); - } - break; - case k_Categories: - if (t_categories != 0) - { - ATL::CComQIPtr pIUICategory(ppropvarCurrentValue->punkVal); - ATLASSERT(pIUICategory.p); - hr = pIUICategory->Clear(); - for (UINT i = t_items; i < t_items + t_categories; i++) - { - if FAILED(hr = pIUICategory->Add(m_apItems[i])) - break; - } - ATLASSERT(SUCCEEDED(hr)); - } - break; - } - - return hr; - } -}; - -// TextCollectionImpl: handles item labels and selection -// -template -class TextCollectionImpl : public CollectionImpl -{ - typedef TextCollectionImpl thisClass; -public: - typedef thisClass TextCollection; - - TextCollectionImpl() : m_uSelected(UI_COLLECTION_INVALIDINDEX) - { } - - Text m_asText[t_items]; - UINT m_uSelected; - - // Operations - HRESULT SetItemText(UINT uItem, LPCWSTR sText, bool bUpdate = false) - { - ATLASSERT(uItem < t_items); - - m_asText[uItem] = sText; - - return bUpdate ? InvalidateItems() : S_OK; - } - - UINT GetSelected() - { - return m_uSelected; - } - - HRESULT Select(UINT uItem, bool bUpdate = false) - { - ATLASSERT((uItem < t_items) || (uItem == UI_COLLECTION_INVALIDINDEX)); - - m_uSelected = uItem; - - TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); - return bUpdate ? - ribbon.SetProperty(TCtrl::GetID(), UI_PKEY_SelectedItem, uItem) : - S_OK; - } - -// Implementation - HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) - { - ATLASSERT(uItem < t_items); - - if (k_(key) == k_Label) - { - if (m_asText[uItem].IsEmpty()) - { - TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); - m_asText[uItem] = ribbon.OnRibbonQueryItemText(TCtrl::GetID(), uItem); - } - return SetPropertyVal(key, (LPCWSTR)m_asText[uItem], value); - } - else - { - return Collection::DoGetItem(uItem, key, value); - } - } - - HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, - const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) - { - ATLASSERT(nCmdID == TCtrl::GetID()); - - if (k_(key) == k_SelectedItem) - { - TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); - UINT uSel = UI_COLLECTION_INVALIDINDEX; - if ((m_uSelected == UI_COLLECTION_INVALIDINDEX) && - ribbon.OnRibbonQuerySelectedItem(TCtrl::GetID(), uSel)) - m_uSelected = uSel; - - return SetPropertyVal(key, m_uSelected, ppropvarNewValue); - } - else - { - return Collection::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); - } - } -}; - -// ItemCollectionImpl: handles item image -// -template -class ItemCollectionImpl : public TextCollectionImpl -{ - typedef ItemCollectionImpl thisClass; -public: - typedef thisClass ItemCollection; - - ItemCollectionImpl() - { - ZeroMemory(m_aBitmap, sizeof m_aBitmap); - } - - CBitmap m_aBitmap[t_items]; - - // Operations - HRESULT SetItemImage(UINT uIndex, HBITMAP hbm, bool bUpdate = false) - { - ATLASSERT(uIndex < t_items); - - m_aBitmap[uIndex] = hbm; - - return bUpdate ? InvalidateItems() : S_OK; - } - -// Implementation - HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) - { - ATLASSERT(uItem < t_items); - - if (k_(key) == k_ItemImage) - { - if (m_aBitmap[uItem].IsNull()) - { - TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); - m_aBitmap[uItem] = ribbon.OnRibbonQueryItemImage(TCtrl::GetID(), uItem); - } - return m_aBitmap[uItem].IsNull() ? - E_NOTIMPL : - SetPropertyVal(key, GetImage(m_aBitmap[uItem], UI_OWNERSHIP_COPY), value); - } - else - { - return TextCollection::DoGetItem(uItem, key, value); - } - } -}; - -// ComboCollectionImpl: handles combo text -// -template -class ComboCollectionImpl : public ItemCollectionImpl -{ - typedef ComboCollectionImpl thisClass; -public: - typedef thisClass ComboCollection; - - // Operations - HRESULT SetComboText(LPCWSTR sText) - { - TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); - return ribbon.IsRibbonUI() ? - ribbon.SetProperty(TCtrl::GetID(), UI_PKEY_StringValue, sText) : - S_OK; - } - - LPCWSTR GetComboText() - { - static WCHAR sCombo[RIBBONUI_MAX_TEXT] = { 0 }; - TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); - PROPVARIANT var; - if (ribbon.IsRibbonUI()) - { - HRESULT hr = ribbon.GetIUIFrameworkPtr()->GetUICommandProperty(TCtrl::GetID(), UI_PKEY_StringValue, &var); - hr = PropVariantToString(var, sCombo, RIBBONUI_MAX_TEXT); - return sCombo; - } - return NULL; - } -}; - -// CommandCollectionImpl: handles RibbonUI command collection controls -// -template -class CommandCollectionImpl : public CollectionImpl -{ - typedef CommandCollectionImpl thisClass; -public: - typedef thisClass CommandCollection; - - CommandCollectionImpl() - { - ZeroMemory(m_auCmd, sizeof m_auCmd); - ZeroMemory(m_aCmdType, sizeof m_aCmdType); - } - - UINT32 m_auCmd[t_items]; - BYTE m_aCmdType[t_items]; - - // Operations - HRESULT SetItemCommand(UINT uItem, UINT32 uCommandID, bool bUpdate = false) - { - ATLASSERT(uItem < t_items); - - if (uCommandID == m_auCmd[uItem]) - return S_OK; - - TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); - - m_auCmd[uItem] = uCommandID; - if (uCommandID != 0) - ribbon.UIAddRibbonElement(uCommandID); - - return bUpdate ? InvalidateItems() : S_OK; - } - - HRESULT SetItemCommandType(UINT uItem, UI_COMMANDTYPE type, bool bUpdate = false) - { - ATLASSERT(uItem < t_items); - - m_aCmdType[uItem] = (BYTE)type; - - return bUpdate ? InvalidateItems() : S_OK; - } - -// Implementation - HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) - { - ATLASSERT(uItem < t_items); - TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); - - HRESULT hr = E_FAIL; - switch (k_(key)) - { - case k_CommandId: - if (m_auCmd[uItem] == 0) - SetItemCommand(uItem, ribbon.OnRibbonQueryItemCommand(TCtrl::GetID(), uItem)); - hr = SetPropertyVal(key, m_auCmd[uItem], value); - break; - case k_CommandType: - if (m_aCmdType[uItem] == UI_COMMANDTYPE_UNKNOWN) - SetItemCommandType(uItem, ribbon.OnRibbonQueryItemCommandType(TCtrl::GetID(), uItem)); - hr = SetPropertyVal(key, UINT32(m_aCmdType[uItem]), value); - break; - case k_CategoryId: - default: - hr = Collection::DoGetItem(uItem, key, value); - break; - } - - return hr; - } - - HRESULT Select(UINT /*uItem*/, bool /*bUpdate*/ = false) - { - ATLASSERT(FALSE); - return S_OK; - } -}; - -// SimpleCollectionImpl: collection class for ribbon simple collection controls -// -template -class SimpleCollectionImpl : public CollectionImplBase, t_size> -{ - typedef SimpleCollectionImpl thisClass; -public: - typedef CollectionImplBase CollectionBase; - typedef thisClass SimpleCollection; - -// Implementation - HRESULT OnGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) - { - ATLASSERT(uItem < t_size); - TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); - - HRESULT hr = E_NOTIMPL; - switch (k_(key)) - { - case k_ItemImage: - if (HBITMAP hbm = ribbon.DefRibbonQueryItemImage(TCtrl::GetID(), uItem)) - hr = SetPropertyVal(key, GetImage(hbm, UI_OWNERSHIP_TRANSFER), value); - break; - case k_Label: - if (LPCWSTR sText = ribbon.DefRibbonQueryItemText(TCtrl::GetID(), uItem)) - hr = SetPropertyVal(key, (LPCWSTR)sText, value); - break; - case k_CommandType: - hr = SetPropertyVal(key, t_CommandType, value); - break; - case k_CommandId: - hr = SetPropertyVal(key, ribbon.DefRibbonQueryItemCommand(TCtrl::GetID(), uItem), value); - break; - case k_CategoryId: - hr = SetPropertyVal(key, UI_COLLECTION_INVALIDINDEX, value); - break; - default: - ATLASSERT(FALSE); - break; - } - - return hr; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// Ribbon collection control classes - -// CollectionCtrlImpl: specializable class for ribbon collection controls -// -template -class CollectionCtrlImpl : public CommandCtrlImpl, public TCollection -{ - typedef CollectionCtrlImpl thisClass; -public: - typedef CommandCtrlImpl CommandCtrl; - typedef TCollection Collection; - - // Implementation - virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, - const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) - { - ATLASSERT(nCmdID == GetID()); - ATLASSERT(ppropvarNewValue); - - HRESULT hr = Collection::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); - if FAILED(hr) - hr = CommandCtrl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); - - return hr; - } - - virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, - const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, - IUISimplePropertySet* /*pCommandExecutionProperties*/) - { - ATLASSERT (nCmdID == GetID()); - nCmdID; // avoid level4 warning - - if (key == NULL) // gallery button pressed - { - GetWndRibbon().OnRibbonItemSelected(GetID(), UI_EXECUTIONVERB_EXECUTE, UI_COLLECTION_INVALIDINDEX); - return S_OK; - } - - ATLASSERT(k_(*key) == k_SelectedItem); - ATLASSERT(ppropvarValue); - - HRESULT hr = S_OK; - UINT32 uSel = 0xffff; - hr = UIPropertyToUInt32(*key, *ppropvarValue, &uSel); - - if (SUCCEEDED(hr)) - { - if (GetWndRibbon().OnRibbonItemSelected(GetID(), verb, uSel)) - TCollection::Select(uSel); - } - - return hr; - } -}; - -// ToolbarGalleryCtrlImpl: base class for ribbon toolbar gallery controls -// -template -class ToolbarGalleryCtrlImpl : public CollectionCtrlImpl, t_size>> -{ -public: - ToolbarGalleryCtrlImpl() - { - CResource tbres; - ATLVERIFY(tbres.Load(RT_TOOLBAR, t_idTB)); - _AtlToolBarData* pData = (_AtlToolBarData*)tbres.Lock(); - ATLASSERT(pData); - ATLASSERT(pData->wVersion == 1); - - WORD* pItems = pData->items(); - INT j = 0; - for (int i = 0; (i < pData->wItemCount) && (j < t_size); i++) - { - if (pItems[i] != 0) - { - m_aCmdType[j] = UI_COMMANDTYPE_ACTION; - m_auCmd[j++] = pItems[i]; - } - } - - if (j < t_size) - Resize(j); - } - - HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) - { - ATLASSERT(uItem < m_size); - ATLASSERT(m_auCmd[uItem]); - - HRESULT hr = E_FAIL; - switch (k_(key)) - { - case k_CommandId: - hr = SetPropertyVal(key, m_auCmd[uItem], value); - break; - case k_CommandType: - hr = SetPropertyVal(key, UINT32(m_aCmdType[uItem]), value); - break; - case k_CategoryId: - hr = SetPropertyVal(key, UI_COLLECTION_INVALIDINDEX, value); - break; - default: - ATLASSERT(FALSE); - break; - } - - return hr; - } -}; - - -// SimpleCollectionCtrlImpl: base class for simple gallery and listbox controls -// -template -class SimpleCollectionCtrlImpl : - public CommandCtrlImpl, - public SimpleCollectionImpl, t_size, t_CommandType> -{ - typedef SimpleCollectionCtrlImpl thisClass; -public: - typedef thisClass SimpleCollection; - - SimpleCollectionCtrlImpl() : m_uSelected(0) - { } - - UINT m_uSelected; - - HRESULT Select(UINT uItem, bool bUpdate = false) - { - ATLASSERT((uItem < t_size) || (uItem == UI_COLLECTION_INVALIDINDEX)); - - m_uSelected = uItem; - - return bUpdate ? - GetWndRibbon().SetProperty(GetID(), UI_PKEY_SelectedItem, uItem) : - S_OK; - } - - // Implementation - virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, - const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) - { - ATLASSERT(nCmdID == GetID()); - ATLASSERT(ppropvarNewValue != NULL); - - HRESULT hr = S_OK; - switch (k_(key)) - { - case k_ItemsSource: - { - ATL::CComQIPtr pIUICollection(ppropvarCurrentValue->punkVal); - ATLASSERT(pIUICollection.p); - hr = pIUICollection->Clear(); - for (UINT i = 0; i < t_size; i++) - { - if FAILED(hr = pIUICollection->Add(m_apItems[i])) - break; - } - ATLASSERT(SUCCEEDED(hr)); - } - break; - case k_SelectedItem: - hr = SetPropertyVal(UI_PKEY_SelectedItem, m_uSelected, ppropvarNewValue); - break; - default: - hr = CommandCtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); - break; - } - - return hr; - } - - virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, - const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, - IUISimplePropertySet* /*pCommandExecutionProperties*/) - { - ATLASSERT (nCmdID == GetID()); - nCmdID; // avoid level 4 warning - - HRESULT hr = S_OK; - if (key == NULL) // gallery button pressed - { - GetWndRibbon().OnRibbonItemSelected(GetID(), UI_EXECUTIONVERB_EXECUTE, UI_COLLECTION_INVALIDINDEX); - return hr; - } - ATLASSERT(k_(*key) == k_SelectedItem); - ATLASSERT(ppropvarValue); - - if SUCCEEDED(hr = UIPropertyToUInt32(*key, *ppropvarValue, &m_uSelected)) - GetWndRibbon().OnRibbonItemSelected(GetID(), verb, m_uSelected); - - return hr; - } -}; - -// RecentItemsCtrlImpl -// -template -class RecentItemsCtrlImpl : - public CtrlImpl, - public CollectionImplBase, TDocList::m_nMaxEntries_Max>, - public TDocList -{ - typedef RecentItemsCtrlImpl thisClass; -public: - typedef thisClass RecentItems; - - // Implementation - HRESULT OnGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) - { - ATLASSERT((INT)uItem < GetMaxEntries()); - - LPCWSTR sPath = m_arrDocs[uItem].szDocName; - HRESULT hr = E_NOTIMPL; - switch (k_(key)) - { - case k_Label: - hr = SetPropertyVal(key, GetWndRibbon().OnRibbonQueryRecentItemName(sPath), value); - break; - case k_LabelDescription: - hr = SetPropertyVal(key, sPath, value); - break; - default: - ATLASSERT(FALSE); - break; - } - - return hr; - } - - virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, - const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) - { - ATLASSERT(nCmdID == GetID()); - ATLASSERT(ppropvarNewValue); - - HRESULT hr = S_OK; - switch (k_(key)) - { - case k_RecentItems: - if (SAFEARRAY* psa = SafeArrayCreateVector(VT_UNKNOWN, 0, m_arrDocs.GetSize())) - { - const int iLastIndex = m_arrDocs.GetSize() - 1; - for (LONG i = 0; i <= iLastIndex; i++) - SafeArrayPutElement(psa, &i, m_apItems[iLastIndex - i]); // reverse order - - hr = SetPropertyVal(key, psa, ppropvarNewValue); - SafeArrayDestroy(psa); - } - break; - default: - hr = CtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); - break; - } - - return hr; - } - - virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, - const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, - IUISimplePropertySet* /*pCommandExecutionProperties*/) - { - ATLASSERT(nCmdID == GetID()); - nCmdID; // avoid level 4 warning - ATLASSERT(verb == UI_EXECUTIONVERB_EXECUTE); - verb; // avoid level 4 warning - ATLASSERT((key) && (k_(*key) == k_SelectedItem)); - ATLASSERT(ppropvarValue); - - UINT32 uSel = 0xffff; - HRESULT hr = UIPropertyToUInt32(*key, *ppropvarValue, &uSel); - if SUCCEEDED(hr) - { - ATLASSERT(uSel < (UINT)GetMaxEntries()); - GetWndRibbon().DefCommandExecute(ID_FILE_MRU_FIRST + uSel); - } - - return hr; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// Ribbon stand-alone control classes - -// FontCtrlImpl -// -template -class FontCtrlImpl : public CtrlImpl -{ -public: - - CharFormat m_cf; - -// Implementation - virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, - const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, - IUISimplePropertySet* pCommandExecutionProperties) - { - ATLASSERT (nCmdID == GetID()); - nCmdID; // avoid level 4 warning - ATLASSERT ((key) && (k_(*key) == k_FontProperties)); - key; // avoid level 4 warning - - HRESULT hr = E_INVALIDARG; - switch (verb) - { - case UI_EXECUTIONVERB_PREVIEW: - case UI_EXECUTIONVERB_EXECUTE: - ATLASSERT(pCommandExecutionProperties); - PROPVARIANT propvar; - - if (SUCCEEDED(hr = pCommandExecutionProperties->GetValue(UI_PKEY_FontProperties_ChangedProperties, &propvar))) - m_cf << ATL::CComQIPtr(propvar.punkVal); - break; - - case UI_EXECUTIONVERB_CANCELPREVIEW: - ATLASSERT(ppropvarValue); - ATL::CComPtr pStore; - - if (SUCCEEDED(hr = UIPropertyToInterface(UI_PKEY_FontProperties, *ppropvarValue, &pStore))) - m_cf << pStore; - break; - } - - if (SUCCEEDED(hr)) - GetWndRibbon().OnRibbonFontCtrlExecute(GetID(), verb, &m_cf); - else - ATLASSERT(FALSE); - - return hr; - } - - virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, - const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) - { - if ((k_(key) == k_FontProperties) && (GetWndRibbon().OnRibbonQueryFont(t_ID, m_cf))) - { - ATL::CComQIPtr pStore(ppropvarCurrentValue->punkVal); - m_cf >> pStore; - return SetPropertyVal(key, pStore.p, ppropvarNewValue); - } - else - { - return CtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); - } - } -}; - -// ColorCtrlImpl -// -template -class ColorCtrlImpl : public CommandCtrlImpl -{ -public: - ColorCtrlImpl() : m_colorType(UI_SWATCHCOLORTYPE_NOCOLOR), m_color(0x800080) /*MAGENTA*/ - { } - - COLORREF m_color; - UINT32 m_colorType; // value in UI_SWATCHCOLORTYPE - Text m_sLabels[6]; // k_MoreColorsLabel to k_ThemeColorsCategoryLabel - ATL::CSimpleArray m_aColors[2]; - ATL::CSimpleArray m_aTooltips[2]; - - // Operations - HRESULT SetColor(COLORREF color, bool bUpdate = false) - { - if (m_colorType != UI_SWATCHCOLORTYPE_RGB) - SetColorType(UI_SWATCHCOLORTYPE_RGB, bUpdate); - m_color = color; - return bUpdate ? SetProperty(UI_PKEY_Color, color) : S_OK; - } - - HRESULT SetColorType(UI_SWATCHCOLORTYPE type, bool bUpdate = false) - { - m_colorType = type; - return bUpdate ? SetProperty(UI_PKEY_ColorType, type) : S_OK; - } - - HRESULT SetColorLabel(REFPROPERTYKEY key, LPCWSTR sLabel, bool bUpdate = false) - { - ATLASSERT((k_(key) >= k_ThemeColorsCategoryLabel) && (k_(key) <= k_MoreColorsLabel)); - m_sLabels[k_(key) - k_ThemeColorsCategoryLabel] = sLabel; - return bUpdate ? SetProperty(key, sLabel) : S_OK; - } - - HRESULT SetColorArray(REFPROPERTYKEY key, COLORREF* pColor, bool bUpdate = false) - { - ATLASSERT((k_(key) == k_ThemeColors) || (k_(key) == k_StandardColors)); - - const INT ic = k_(key) - k_ThemeColors; - m_aColors[ic].RemoveAll(); - while (*pColor != 0x800080) /*MAGENTA*/ - m_aColors[ic].Add(*pColor++); - - if (bUpdate) - { - PROPVARIANT var; - if SUCCEEDED(InitPropVariantFromUInt32Vector(m_aColors[ic].GetData(), m_aColors[ic].GetSize(), &var)) - return SetProperty(key, var); - else - return E_INVALIDARG; - } - else - { - return S_OK; - } - } - - HRESULT SetColorTooltips(REFPROPERTYKEY key, LPCWSTR* ppsTT, bool bUpdate = false) - { - ATLASSERT((k_(key) == k_ThemeColorsTooltips) || (k_(key) == k_StandardColorsTooltips)); - - const INT ic = k_(key) - k_ThemeColorsTooltips; - m_aTooltips[ic].RemoveAll(); - while (*ppsTT) - m_aTooltips[ic].Add(*ppsTT++); - - if (bUpdate) - { - PROPVARIANT var; - if SUCCEEDED(InitPropVariantFromStringVector(m_aTooltips[ic].GetData(), m_aTooltips[ic].GetSize(), &var)) - return SetProperty(key, var); - else - return E_INVALIDARG; - } - else - { - return S_OK; - } - } - - // Implementation - virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, - const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, - IUISimplePropertySet* pCommandExecutionProperties) - { - ATLASSERT (nCmdID == GetID()); - nCmdID; // avoid level 4 warning - ATLASSERT (key && (k_(*key) == k_ColorType)); - key; // avoid level 4 warning - ATLASSERT (ppropvarValue); - - HRESULT hr = PropVariantToUInt32(*ppropvarValue, &m_colorType); - ATLASSERT(SUCCEEDED(hr)); - - if (SUCCEEDED(hr) && (m_colorType == UI_SWATCHCOLORTYPE_RGB)) - { - ATLASSERT(pCommandExecutionProperties); - PROPVARIANT var; - if SUCCEEDED(hr = pCommandExecutionProperties->GetValue(UI_PKEY_Color, &var)) - hr = PropVariantToUInt32(var, &m_color); - } - - if SUCCEEDED(hr) - GetWndRibbon().OnRibbonColorCtrlExecute(GetID(), verb, (UI_SWATCHCOLORTYPE)m_colorType/*uType*/, m_color); - else - ATLASSERT(FALSE); // something was wrong - - return hr; - } - - virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, - const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) - { - ATLASSERT (nCmdID == GetID()); - - HRESULT hr = E_NOTIMPL; - - switch (k_(key)) - { - case k_ColorType: - hr = SetPropertyVal(key, m_colorType, ppropvarNewValue); - break; - case k_Color: - if (m_color == 0x800080) /*MAGENTA*/ - m_color = GetWndRibbon().OnRibbonQueryColor(GetID()); - hr = SetPropertyVal(key, m_color, ppropvarNewValue); - break; - case k_ColorMode: - break; - case k_ThemeColorsCategoryLabel: - case k_StandardColorsCategoryLabel: - case k_RecentColorsCategoryLabel: - case k_AutomaticColorLabel: - case k_NoColorLabel: - case k_MoreColorsLabel: - { - const UINT iLabel = k_(key) - k_ThemeColorsCategoryLabel; - if (m_sLabels[iLabel].IsEmpty()) - if (LPCWSTR psLabel = GetWndRibbon().OnRibbonQueryColorLabel(GetID(), key)) - m_sLabels[iLabel] = psLabel; - if (!m_sLabels[iLabel].IsEmpty()) - hr = SetPropertyVal(key, (LPCWSTR)m_sLabels[iLabel], ppropvarNewValue); - } - break; - case k_ThemeColors: - case k_StandardColors: - { - const INT ic = k_(key) - k_ThemeColors; - if (!m_aColors[ic].GetSize()) - if (COLORREF* pColor = GetWndRibbon().OnRibbonQueryColorArray(GetID(), key)) - SetColorArray(key, pColor); - if (INT iMax = m_aColors[ic].GetSize()) - hr = InitPropVariantFromUInt32Vector(m_aColors[ic].GetData(), iMax, ppropvarNewValue); - } - break; - case k_ThemeColorsTooltips: - case k_StandardColorsTooltips: - { - const INT ic = k_(key) - k_ThemeColorsTooltips; - if (m_aTooltips[ic].GetSize() == 0) - if (LPCWSTR* ppsTT = GetWndRibbon().OnRibbonQueryColorTooltips(GetID(), key)) - SetColorTooltips(key, ppsTT); - if (INT iMax = m_aTooltips[ic].GetSize()) - hr = InitPropVariantFromStringVector(m_aTooltips[ic].GetData(), iMax, ppropvarNewValue); - } - break; - default: - hr = CommandCtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); - break; - } - - return hr; - } -}; - -// SpinnerCtrlImpl -// -template -class SpinnerCtrlImpl : public CtrlImpl -{ -public: - SpinnerCtrlImpl() - { - m_Values[0] = m_Values[2] = m_Values[4] = 0; - m_Values[1] = 100; - m_Values[3] = 1; - } - - V m_Values[5]; - // k_DecimalValue = 201, k_MaxValue = 203, k_MinValue, k_Increment, k_DecimalPlaces - - Text m_FormatString; - Text m_RepresentativeString; - - // Operations - HRESULT SetDecimalPlaces(V vPlaces, bool bUpdate = false) - { - return SetValue(UI_PKEY_DecimalPlaces, vPlaces, bUpdate); - } - - HRESULT SetMin(V vMin, bool bUpdate = false) - { - return SetValue(UI_PKEY_MinValue, vMin, bUpdate); - } - - HRESULT SetMax(V vMax, bool bUpdate = false) - { - return SetValue(UI_PKEY_MaxValue, vMax, bUpdate); - } - - HRESULT SetVal(V vVal, bool bUpdate = false) - { - return SetValue(UI_PKEY_DecimalValue, vVal, bUpdate); - } - - HRESULT SetIncrement(V vIncrement, bool bUpdate = false) - { - return SetValue(UI_PKEY_Increment, vIncrement, bUpdate); - } - - HRESULT SetFormatString(LPCWSTR sFormat, bool bUpdate = false) - { - return SetText(UI_PKEY_FormatString, sFormat, bUpdate); - } - - HRESULT SetRepresentativeString(LPCWSTR sRepresentative, bool bUpdate = false) - { - return SetText(UI_PKEY_RepresentativeString, sRepresentative, bUpdate); - } - - // Implementation - HRESULT SetText(REFPROPERTYKEY key, LPCWSTR sText, bool bUpdate = false) - { - switch (k_(key)) - { - case k_FormatString: - m_FormatString = sText; - break; - case k_RepresentativeString: - m_RepresentativeString = sText; - break; - default: - return CtrlImpl::SetText(key, sText, bUpdate); - } - - return bUpdate ? - GetWndRibbon().InvalidateProperty(GetID(), key) : - S_OK; - } - - HRESULT SetValue(REFPROPERTYKEY key, V val, bool bUpdate = false) - { - ATLASSERT((k_(key) <= k_DecimalPlaces) && (k_(key) >= k_DecimalValue)); - - const INT iVal = k_(key) == k_DecimalValue ? 0 : k_(key) - k_StringValue; - m_Values[iVal] = val; - - if (bUpdate) - { - if(k_(key) == k_DecimalValue) - { - DECIMAL decVal; - InitDecimal(val, &decVal); - return SetProperty(key, &decVal); - } - else - { - return GetWndRibbon().InvalidateProperty(GetID(), key); - } - } - else - { - return S_OK; - } - } - - HRESULT QueryValue(REFPROPERTYKEY key, LONG* plVal) - { - return GetWndRibbon().OnRibbonQuerySpinnerValue(GetID(), key, plVal); - } - - HRESULT QueryValue(REFPROPERTYKEY key, DOUBLE* pdVal) - { - return GetWndRibbon().OnRibbonQueryFloatSpinnerValue(GetID(), key, pdVal); - } - - HRESULT OnGetValue(REFPROPERTYKEY key, PROPVARIANT* ppv) - { - ATLASSERT((k_(key) <= k_DecimalPlaces) && (k_(key) >= k_DecimalValue)); - - const INT iVal = k_(key) == k_DecimalValue ? 0 : k_(key) - k_StringValue; - - QueryValue(key, m_Values + iVal); - - if (k_(key) == k_DecimalPlaces) - { - return SetPropertyVal(key, m_Values[iVal], ppv); - } - else - { - DECIMAL decVal; - InitDecimal(m_Values[iVal], &decVal); - return SetPropertyVal(key, &decVal, ppv); - } - } - - HRESULT OnGetText(REFPROPERTYKEY key, Text& sVal, PROPVARIANT* ppv) - { - if (LPCWSTR sNew = GetWndRibbon().OnRibbonQueryText(GetID(), key)) - sVal = sNew; - return SetPropertyVal(key, (LPCWSTR)sVal, ppv); - } - - virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, - const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, - IUISimplePropertySet* /*pCommandExecutionProperties*/) - { - ATLASSERT (nCmdID == GetID()); - nCmdID; // avoid level 4 warning - ATLASSERT (key && (k_(*key) == k_DecimalValue)); - key; // avoid level 4 warning - ATLASSERT (verb == UI_EXECUTIONVERB_EXECUTE); - verb; // avoid level 4 warning - - DECIMAL decVal; - - HRESULT hr = UIPropertyToDecimal(UI_PKEY_DecimalValue, *ppropvarValue, &decVal); - hr = InitVal(m_Values[0], &decVal); - - GetWndRibbon().OnRibbonSpinnerCtrlExecute(GetID(), &m_Values[0]); - - return hr; - } - - virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, - const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) - { - ATLASSERT (nCmdID == GetID()); - - HRESULT hr = E_NOTIMPL; - switch (k_(key)) - { - case k_DecimalPlaces: - case k_DecimalValue: - case k_Increment: - case k_MaxValue: - case k_MinValue: - hr = OnGetValue(key, ppropvarNewValue); - break; - case k_FormatString: - if (m_FormatString.IsEmpty()) - return OnGetText(key, m_FormatString, ppropvarNewValue); - break; - case k_RepresentativeString: - if (m_RepresentativeString.IsEmpty()) - return OnGetText(key, m_RepresentativeString, ppropvarNewValue); - break; - default: - hr = CtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); - break; - } - - return hr; - } - - // decimal conversion helpers - static HRESULT InitDecimal(LONG& val, DECIMAL* pDecimal) - { - return ::VarDecFromI4(val, pDecimal); - } - - static HRESULT InitDecimal(DOUBLE& val, DECIMAL* pDecimal) - { - return ::VarDecFromR8(val, pDecimal); - } - - static HRESULT InitVal(LONG& val, const DECIMAL* pDecimal) - { - return ::VarI4FromDec(pDecimal, &val); - } - - static HRESULT InitVal(DOUBLE& val, const DECIMAL* pDecimal) - { - return ::VarR8FromDec(pDecimal, &val); - } -}; - -// CRibbonImpl Ribbon implementation class -// -template -class CRibbonImpl : - public CRibbonUpdateUI, - public ICtrl, - public IUIApplication, - public IUICommandHandler -{ - typedef CRibbonImpl thisClass; -public: - typedef thisClass Ribbon; - typedef T WndRibbon; - - CRibbonImpl() : m_bRibbonUI(false), m_hgRibbonSettings(NULL) - { -#ifdef _DEBUG - m_cRef = 1; -#endif - pWndRibbon = static_cast(this); - HRESULT hr = ::CoInitialize(NULL); - if(SUCCEEDED(hr)) - if (RunTimeHelper::IsRibbonUIAvailable()) - hr = m_pIUIFramework.CoCreateInstance(CLSID_UIRibbonFramework); - else - ATLTRACE(L"Ribbon UI not available\n"); - - if FAILED(hr) - ATLTRACE(L"Ribbon construction failed\n"); - - ATLASSERT(SUCCEEDED(hr)); - } - - ~CRibbonImpl() - { - ::GlobalFree(m_hgRibbonSettings); - m_pIUIFramework.Release(); - ::CoUninitialize(); - } - - ICtrl& GetRibbonCtrl(UINT) - { - return static_cast(*this); - } - - ATL::CComPtr m_pIUIFramework; - HGLOBAL m_hgRibbonSettings; - bool m_bRibbonUI; - - bool IsRibbonUI() - { - return m_bRibbonUI; - } - - IUIFramework* GetIUIFrameworkPtr() - { - return m_pIUIFramework; - } - - template - I* GetRibbonViewPtr(UINT32 uID) - { - ATLASSERT(m_pIUIFramework); - ATL::CComPtr pI; - return m_pIUIFramework->GetView(uID, __uuidof(I), (void**) &pI) == S_OK ? - pI : - NULL; - } - - IUIRibbon* GetRibbonPtr() - { - return GetRibbonViewPtr(0); - } - - IUIContextualUI* GetMenuPtr(UINT32 uID) - { - ATLASSERT(uID); - return GetRibbonViewPtr(uID); - } - - UINT GetRibbonHeight() - { - ATLASSERT(IsRibbonUI()); - - UINT32 cy = 0; - if (ATL::CComPtr pIUIRibbon = GetRibbonPtr()) - pIUIRibbon->GetHeight(&cy); - return cy; - } - - HRESULT CreateRibbon(LPCWSTR sResName = L"APPLICATION_RIBBON") - { - T* pT = static_cast(this); - ATLASSERT(GetIUIFrameworkPtr() && !IsRibbonUI()); - ATLASSERT(pT->IsWindow()); - - HRESULT hr = m_pIUIFramework->Initialize(pT->m_hWnd, this); - - if (hr == S_OK) - hr = m_pIUIFramework->LoadUI(ModuleHelper::GetResourceInstance(), sResName); - - return hr; - } - - HRESULT DestroyRibbon() - { - T* pT = static_cast(this); - ATLASSERT(GetIUIFrameworkPtr() && IsRibbonUI()); - ATLASSERT(pT->IsWindow()); - - HRESULT hRes = m_pIUIFramework->Destroy(); - if (!RunTimeHelper::IsWin7()) - pT->SetWindowRgn(NULL, TRUE); // Vista Basic bug workaround - return hRes; - } - -// Ribbon persistency - HRESULT operator >>(IStream* pIStream) - { - ATLASSERT(GetIUIFrameworkPtr()); - ATLASSERT(pIStream); - - HRESULT hr = E_FAIL; - if (ATL::CComPtr pIUIRibbon = GetRibbonPtr()) - { - const LARGE_INTEGER li0 = { 0 }; - pIStream->Seek(li0, STREAM_SEEK_SET, NULL); - hr = pIUIRibbon->SaveSettingsToStream(pIStream); - pIStream->Commit(STGC_DEFAULT); - } - - return hr; - } - - HRESULT operator <<(IStream* pIStream) - { - ATLASSERT(GetIUIFrameworkPtr()); - ATLASSERT(pIStream); - - HRESULT hr = E_FAIL; - if (ATL::CComPtr pIUIRibbon = GetRibbonPtr()) - { - const LARGE_INTEGER li0 = { 0 }; - pIStream->Seek(li0, STREAM_SEEK_SET, NULL); - hr = pIUIRibbon->LoadSettingsFromStream(pIStream); - } - - return hr; - } - - void ResetRibbonSettings() - { - if (m_hgRibbonSettings != NULL) - { - ::GlobalFree(m_hgRibbonSettings); - m_hgRibbonSettings = NULL; - } - } - - HRESULT SaveRibbonSettings() - { - ATLASSERT(GetIUIFrameworkPtr()); - ATLASSERT(static_cast(this)->IsWindow()); - - HRESULT hr = E_FAIL; - ATL::CComPtr pIStream; - - if SUCCEEDED(hr = ::CreateStreamOnHGlobal(m_hgRibbonSettings, FALSE, &pIStream)) - hr = *this >> pIStream; - - if (SUCCEEDED(hr) && (m_hgRibbonSettings == NULL)) - hr = ::GetHGlobalFromStream(pIStream, &m_hgRibbonSettings); - - if FAILED(hr) - ResetRibbonSettings(); - - return hr; - } - - HRESULT RestoreRibbonSettings() - { - ATLASSERT(GetIUIFrameworkPtr()); - ATLASSERT(m_hgRibbonSettings); - ATLASSERT(static_cast(this)->IsWindow()); - - HRESULT hr = E_FAIL; - ATL::CComPtr pIStream; - - if SUCCEEDED(hr = ::CreateStreamOnHGlobal(m_hgRibbonSettings, FALSE, &pIStream)) - hr = *this << pIStream; - - if FAILED(hr) - ResetRibbonSettings(); - - return hr; - } - -// QAT dock states - UI_CONTROLDOCK GetQATDock() - { - ATLASSERT(GetIUIFrameworkPtr()); - ATLASSERT(IsRibbonUI()); - - UINT32 uDock = 0; - PROPVARIANT propvar; - ATL::CComQIPtrpIPS(GetRibbonPtr()); - - if ((pIPS != NULL) && SUCCEEDED(pIPS->GetValue(UI_PKEY_QuickAccessToolbarDock, &propvar)) && - SUCCEEDED(UIPropertyToUInt32(UI_PKEY_QuickAccessToolbarDock, propvar, &uDock))) - return (UI_CONTROLDOCK)uDock; - - ATLASSERT(FALSE); // something was wrong - return (UI_CONTROLDOCK)0; - } - - bool SetQATDock(UI_CONTROLDOCK dockState) - { - ATLASSERT(GetIUIFrameworkPtr()); - ATLASSERT(IsRibbonUI()); - - PROPVARIANT propvar; - ATLVERIFY(SUCCEEDED(SetPropertyVal(UI_PKEY_QuickAccessToolbarDock, dockState, &propvar))); - - ATL::CComQIPtrpIPS(GetRibbonPtr()); - if ((pIPS != NULL) && SUCCEEDED(pIPS->SetValue(UI_PKEY_QuickAccessToolbarDock, propvar))) - { - pIPS->Commit(); - return true; - } - - ATLASSERT(FALSE); // something was wrong - return false; - } - -// Ribbon display states - bool GetRibbonDisplayState(REFPROPERTYKEY key) - { - ATLASSERT(GetIUIFrameworkPtr()); - ATLASSERT(IsRibbonUI()); - ATLASSERT((k_(key) == k_Viewable) || (k_(key) == k_Minimized)); - - PROPVARIANT propvar; - ATL::CComQIPtrpIPS(GetRibbonPtr()); - - if ((pIPS != NULL) && SUCCEEDED(pIPS->GetValue(key, &propvar))) - { - BOOL bState = FALSE; - if SUCCEEDED(UIPropertyToBoolean(key, propvar, &bState)) - return (bState != FALSE); - } - - ATLASSERT(FALSE); // something was wrong - return false; - } - - bool SetRibbonDisplayState(REFPROPERTYKEY key, bool bState = true) - { - ATLASSERT(GetIUIFrameworkPtr()); - ATLASSERT(IsRibbonUI()); - ATLASSERT((k_(key) == k_Viewable) || (k_(key) == k_Minimized)); - - PROPVARIANT propvar; - ATLVERIFY(SUCCEEDED(SetPropertyVal(key, bState, &propvar))); - - ATL::CComQIPtrpIPS(GetRibbonPtr()); - - if ((pIPS != NULL) && SUCCEEDED(pIPS->SetValue(key, propvar))) - { - pIPS->Commit(); - return true; - } - - ATLASSERT(FALSE); // something was wrong - return false; - } - - bool IsRibbonMinimized() - { - return GetRibbonDisplayState(UI_PKEY_Minimized); - } - - bool MinimizeRibbon(bool bMinimize = true) - { - return SetRibbonDisplayState(UI_PKEY_Minimized, bMinimize); - } - - bool IsRibbonHidden() - { - return !GetRibbonDisplayState(UI_PKEY_Viewable); - } - - bool HideRibbon(bool bHide = true) - { - return SetRibbonDisplayState(UI_PKEY_Viewable, !bHide); - } - -// Ribbon colors - UI_HSBCOLOR GetRibbonColor(REFPROPERTYKEY key) - { - ATLASSERT(GetIUIFrameworkPtr()); - ATLASSERT(IsRibbonUI()); - ATLASSERT((k_(key) >= k_GlobalBackgroundColor) && (k_(key) <= k_GlobalTextColor)); - - PROPVARIANT propvar; - ATL::CComQIPtrpIPS(GetIUIFrameworkPtr()); - - if ((pIPS != NULL) && SUCCEEDED(pIPS->GetValue(key, &propvar))) - { - UINT32 color = 0; - if SUCCEEDED(UIPropertyToUInt32(key, propvar, &color)) - return color; - } - - ATLASSERT(FALSE); // something was wrong - return 0; - } - - bool SetRibbonColor(REFPROPERTYKEY key, UI_HSBCOLOR color) - { - ATLASSERT(GetIUIFrameworkPtr()); - ATLASSERT(IsRibbonUI()); - ATLASSERT((k_(key) >= k_GlobalBackgroundColor) && (k_(key) <= k_GlobalTextColor)); - - PROPVARIANT propvar; - ATLVERIFY(SUCCEEDED(SetPropertyVal(key, color, &propvar))); - - ATL::CComQIPtrpIPS(GetIUIFrameworkPtr()); - - if ((pIPS != NULL) && SUCCEEDED(pIPS->SetValue(key, propvar))) - { - pIPS->Commit(); - return true; - } - - ATLASSERT(FALSE); // something was wrong - return false; - } - -// Ribbon modes - HRESULT SetRibbonModes(INT32 iModes) - { - ATLASSERT(IsRibbonUI()); - return GetIUIFrameworkPtr()->SetModes(iModes); - } - -// Ribbon contextual tab - UI_CONTEXTAVAILABILITY GetRibbonContextAvail(UINT32 uID) - { - ATLASSERT(GetIUIFrameworkPtr()); - - PROPVARIANT propvar; - if (IsRibbonUI() && - SUCCEEDED(GetIUIFrameworkPtr()->GetUICommandProperty(uID, UI_PKEY_ContextAvailable, &propvar))) - { - UINT uav; - if (SUCCEEDED(PropVariantToUInt32(propvar, &uav))) - { - CUpdateUIBase::UIEnable(uID, uav != UI_CONTEXTAVAILABILITY_NOTAVAILABLE); - CUpdateUIBase::UISetCheck(uID, uav == UI_CONTEXTAVAILABILITY_ACTIVE); - return (UI_CONTEXTAVAILABILITY)uav; - } - } - - return UI_CONTEXTAVAILABILITY_NOTAVAILABLE; - } - - HRESULT SetRibbonContextAvail(UINT32 uID, UI_CONTEXTAVAILABILITY cav) - { - CUpdateUIBase::UIEnable(uID, cav != UI_CONTEXTAVAILABILITY_NOTAVAILABLE); - CUpdateUIBase::UISetCheck(uID, cav == UI_CONTEXTAVAILABILITY_ACTIVE); - - return SetProperty((WORD)uID, UI_PKEY_ContextAvailable, UINT32(cav)); - } - -// Ribbon context menu - bool HasRibbonMenu(UINT32 uID) - { - ATL::CComPtr pI = GetMenuPtr(uID); - return pI != NULL; - } - - HRESULT TrackRibbonMenu(UINT32 uID, INT32 x, INT32 y) - { - ATLASSERT(HasRibbonMenu(uID)); - - return IsRibbonUI() ? - ATL::CComPtr(GetMenuPtr(uID))->ShowAtLocation(x, y) : - E_FAIL; - } - - HRESULT TrackRibbonMenu(UINT32 uID, LPARAM lParam) - { - return TrackRibbonMenu(uID, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - } - -// Overrideables - HBITMAP OnRibbonQueryImage(UINT nCmdID, REFPROPERTYKEY /*key*/) - { - return DefRibbonQueryImage(nCmdID); - } - - LPCWSTR OnRibbonQueryText(UINT nCmdID, REFPROPERTYKEY key) - { - return DefRibbonQueryText(nCmdID, key); - } - - bool OnRibbonQueryState(UINT nCmdID, REFPROPERTYKEY key) - { - return DefRibbonQueryState(nCmdID, key); - } - - UI_CONTEXTAVAILABILITY OnRibbonQueryTabAvail(UINT nCmdID) - { - DWORD dwState = UIGetState(nCmdID); - return ((dwState & UPDUI_DISABLED) == UPDUI_DISABLED) ? - UI_CONTEXTAVAILABILITY_NOTAVAILABLE : - (((dwState & UPDUI_CHECKED) == UPDUI_CHECKED) ? - UI_CONTEXTAVAILABILITY_ACTIVE : - UI_CONTEXTAVAILABILITY_AVAILABLE); - } - - LPCWSTR OnRibbonQueryComboText(UINT32 /*uCtrlID*/) - { - return NULL; - } - - LPCWSTR OnRibbonQueryCategoryText(UINT32 /*uCtrlID*/, UINT32 /*uCat*/) - { - return L"Category"; - } - - UINT32 OnRibbonQueryItemCategory(UINT32 /*uCtrlID*/, UINT32 /*uItem*/) - { - return 0; - } - - LPCWSTR OnRibbonQueryItemText(UINT32 uCtrlID, UINT32 uItem) - { - return DefRibbonQueryItemText(uCtrlID, uItem); - } - - bool OnRibbonQuerySelectedItem(UINT32 /*uCtrlID*/, UINT32& /*uSel*/) - { - return false; - } - - HBITMAP OnRibbonQueryItemImage(UINT32 uCtrlID, UINT32 uItem) - { - return DefRibbonQueryItemImage(uCtrlID, uItem); - } - - UINT32 OnRibbonQueryItemCommand(UINT32 uCtrlID, UINT32 uItem) - { - return DefRibbonQueryItemCommand(uCtrlID, uItem); - } - - UI_COMMANDTYPE OnRibbonQueryItemCommandType(UINT32 /*uCtrlID*/, UINT32 /*uItem*/) - { - return UI_COMMANDTYPE_ACTION; - } - - LPCWSTR OnRibbonQueryRecentItemName(LPCWSTR sPath) - { - return ::PathFindFileName(sPath); - } - - bool OnRibbonQueryFont(UINT /*nId*/, CHARFORMAT2& /*cf*/) - { - return false; - } - - bool OnRibbonQuerySpinnerValue(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/, LONG* /*pVal*/) - { - return false; - } - - bool OnRibbonQueryFloatSpinnerValue(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/, DOUBLE* /*pVal*/) - { - return false; - } - - COLORREF OnRibbonQueryColor(UINT /*nCmdID*/) - { - return 0x800080; /*MAGENTA*/ - } - - LPCWSTR OnRibbonQueryColorLabel(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/) - { - return NULL; - } - - COLORREF* OnRibbonQueryColorArray(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/) - { - return NULL; - } - - LPCWSTR* OnRibbonQueryColorTooltips(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/) - { - return NULL; - } - - bool OnRibbonItemSelected(UINT32 uCtrlID, UI_EXECUTIONVERB verb, UINT32 uItem) - { - DefCommandExecute(MAKELONG(uCtrlID, verb), uItem); - return true; - } - - void OnRibbonColorCtrlExecute(UINT32 uCtrlID, UI_EXECUTIONVERB verb, UI_SWATCHCOLORTYPE uType, COLORREF color) - { - DefRibbonColorCtrlExecute(uCtrlID, verb, uType, color); - } - - void OnRibbonFontCtrlExecute(UINT32 uCtrlID, UI_EXECUTIONVERB verb, CHARFORMAT2* pcf) - { - DefCommandExecute(MAKELONG(uCtrlID, verb), (LPARAM)pcf); - } - - void OnRibbonSpinnerCtrlExecute(UINT32 uCtrlID, LONG* pVal) - { - DefCommandExecute(uCtrlID, *pVal); - } - - void OnRibbonSpinnerCtrlExecute(UINT32 uCtrlID, DOUBLE* pVal) - { - DefCommandExecute(uCtrlID, (LPARAM)pVal); - } - - void OnRibbonCommandExecute(UINT32 uCmdID) - { - DefCommandExecute(uCmdID); - } - -// Default implementations - HBITMAP DefRibbonQueryImage(UINT nCmdID) - { - return AtlLoadBitmapImage(nCmdID, LR_CREATEDIBSECTION); - } - - bool DefRibbonQueryState(UINT nCmdID, REFPROPERTYKEY key) - { - DWORD dwState = UIGetState(nCmdID); - bool bRet = false; - switch (k_(key)) - { - case k_BooleanValue: - bRet = (dwState & UPDUI_CHECKED) == UPDUI_CHECKED; - break; - case k_Enabled: - bRet = (dwState & UPDUI_DISABLED) != UPDUI_DISABLED; - break; - default: - ATLASSERT(FALSE); - break; - } - - return bRet; - } - - LPCTSTR DefRibbonQueryText(UINT nCmdID, REFPROPERTYKEY key) - { - static WCHAR sText[RIBBONUI_MAX_TEXT] = { 0 }; - - if (k_(key) == k_Label) - return UIGetText(nCmdID); - - if (AtlLoadString(nCmdID, sText, RIBBONUI_MAX_TEXT)) - { - PWCHAR pTitle = wcschr(sText, L'\n'); - switch (k_(key)) - { - case k_Keytip: - if (PWCHAR pAmp = wcschr(sText, L'&')) - pTitle = pAmp; - if (pTitle != NULL) - *(pTitle + 2) = NULL; // fall through - case k_TooltipTitle: - return pTitle ? ++pTitle : NULL; - case k_TooltipDescription: - case k_LabelDescription: - if (pTitle != NULL) - *pTitle = NULL; - return sText; - } - } - - return NULL; - } - - LPCWSTR DefRibbonQueryItemText(UINT32 uCtrlID, UINT32 uItem) - { - return DefRibbonQueryText(uCtrlID + 1 + uItem, UI_PKEY_LabelDescription); - } - - HBITMAP DefRibbonQueryItemImage(UINT32 uCtrlID, UINT32 uItem) - { - return DefRibbonQueryImage(uCtrlID + 1 + uItem); - } - - UINT32 DefRibbonQueryItemCommand(UINT32 uCtrlID, UINT32 uItem) - { - return uCtrlID + 1 + uItem; - } - - void DefRibbonColorCtrlExecute(UINT32 uCtrlID, UI_EXECUTIONVERB verb, UI_SWATCHCOLORTYPE uType, COLORREF color) - { - switch(uType) - { - case UI_SWATCHCOLORTYPE_RGB: - break; - case UI_SWATCHCOLORTYPE_AUTOMATIC: - color = ::GetSysColor(COLOR_WINDOWTEXT); - break; - case UI_SWATCHCOLORTYPE_NOCOLOR: - color = ::GetSysColor(COLOR_WINDOW); - break; - default: - ATLASSERT(FALSE); - break; - } - - DefCommandExecute(MAKELONG(uCtrlID, verb), color); - } - - void DefCommandExecute(UINT32 uCmd, LPARAM lParam = 0) - { - static_cast(this)->PostMessage(WM_COMMAND, uCmd, lParam); - } - -// Elements setting helpers - HRESULT InvalidateCtrl(UINT32 nID) - { - return IsRibbonUI() ? - GetIUIFrameworkPtr()->InvalidateUICommand(nID, UI_INVALIDATIONS_ALLPROPERTIES, NULL) : - E_FAIL; - } - - HRESULT InvalidateProperty(UINT32 nID, REFPROPERTYKEY key, UI_INVALIDATIONS flags = UI_INVALIDATIONS_PROPERTY) - { - return IsRibbonUI() ? - GetIUIFrameworkPtr()->InvalidateUICommand(nID, flags, &key) : - E_FAIL; - } - - template - HRESULT SetProperty(WORD wID, REFPROPERTYKEY key, V val) - { - if (IsRibbonUI()) - { - PROPVARIANT var; - if (SUCCEEDED(RibbonUI::SetPropertyVal(key, val, &var))) - { - return SetProperty(wID, key, var); - } - return E_INVALIDARG; - } - else - { - return E_FAIL; - } - } - - template <> - HRESULT SetProperty(WORD nID, REFPROPERTYKEY key, PROPVARIANT var) - { - return IsRibbonUI() ? - GetIUIFrameworkPtr()->SetUICommandProperty(nID, key, var) : - E_FAIL; - } - -// Interfaces - // IUIApplication - STDMETHODIMP OnViewChanged(UINT32, UI_VIEWTYPE, IUnknown*, UI_VIEWVERB verb, INT32) - { - switch (verb) - { - case UI_VIEWVERB_CREATE: - m_bRibbonUI = true; - if (m_hgRibbonSettings != NULL) - RestoreRibbonSettings(); - break; - case UI_VIEWVERB_SIZE: - static_cast(this)->UpdateLayout(FALSE); - break; - case UI_VIEWVERB_DESTROY: - SaveRibbonSettings(); - m_bRibbonUI = false; - break; - } - - return S_OK; - } - - STDMETHODIMP OnCreateUICommand(UINT32 nCmdID, UI_COMMANDTYPE typeID, IUICommandHandler** ppCommandHandler) - { - UIAddRibbonElement(nCmdID); - if (typeID == UI_COMMANDTYPE_CONTEXT) - CUpdateUIBase::UIEnable(nCmdID, false); - *ppCommandHandler = this; - return S_OK; - } - - STDMETHODIMP OnDestroyUICommand(UINT32 nCmdID, UI_COMMANDTYPE, IUICommandHandler*) - { - UIRemoveRibbonElement(nCmdID); - return S_OK; - } - - // IUICommandHandler - STDMETHODIMP Execute(UINT nCmdID, - UI_EXECUTIONVERB verb, - const PROPERTYKEY* key, - const PROPVARIANT* ppropvarValue, - IUISimplePropertySet* pCommandExecutionProperties) - { - T* pT =static_cast(this); - return pT->GetRibbonCtrl(nCmdID).DoExecute(nCmdID, verb, key, ppropvarValue, pCommandExecutionProperties); - } - - STDMETHODIMP UpdateProperty(UINT nCmdID, REFPROPERTYKEY key, - const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) - { - T* pT =static_cast(this); - return pT->GetRibbonCtrl(nCmdID).DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); - } - -#ifdef _DEBUG - // IUnknown methods (heavyweight) - STDMETHODIMP_(ULONG) AddRef() - { - return InterlockedIncrement(&m_cRef); - } - - STDMETHODIMP_(ULONG) Release() - { - LONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) // NoOp for breakpoint - { - cRef = 0; - } - - return cRef; - } - - STDMETHODIMP QueryInterface(REFIID iid, void** ppv) - { - if (ppv == NULL) - { - return E_POINTER; - } - else if ((iid == __uuidof(IUnknown)) || - (iid == __uuidof(IUICommandHandler)) || - (iid == __uuidof(IUIApplication))) - { - *ppv = this; - AddRef(); - return S_OK; - } - else - { - return E_NOINTERFACE; - } - } - - LONG m_cRef; -#else - // IUnknown methods (lightweight) - STDMETHODIMP QueryInterface(REFIID iid, void** ppv) - { - if ((iid == __uuidof(IUnknown)) || - (iid == __uuidof(IUICommandHandler)) || - (iid == __uuidof(IUIApplication))) - { - *ppv = this; - return S_OK; - } - return E_NOINTERFACE; - } - ULONG STDMETHODCALLTYPE AddRef() - { - return 1; - } - ULONG STDMETHODCALLTYPE Release() - { - return 1; - } -#endif - -// CRibbonImpl ICtrl implementation - virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, - const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, - IUISimplePropertySet* /*pCommandExecutionProperties*/) - { - if (key != NULL) - { - if(k_(*key) != k_BooleanValue) - { - ATLTRACE(L"Control ID %d is not handled\n", nCmdID); - return E_NOTIMPL; - } - BOOL bChecked = FALSE; - ATLVERIFY(SUCCEEDED(PropVariantToBoolean(*ppropvarValue, &bChecked))); - CUpdateUIBase::UISetCheck(nCmdID, bChecked); - } - - ATLASSERT(verb == UI_EXECUTIONVERB_EXECUTE); - verb; // avoid level 4 warning - - static_cast(this)->OnRibbonCommandExecute(nCmdID); - - return S_OK; - } - - virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, - const PROPVARIANT* /*ppropvarCurrentValue*/, PROPVARIANT* ppropvarNewValue) - { - T* pT = static_cast(this); - HRESULT hr = E_NOTIMPL; - switch (k_(key)) - { - case k_LargeImage: - case k_LargeHighContrastImage: - case k_SmallImage: - case k_SmallHighContrastImage: - if (HBITMAP hbm = pT->OnRibbonQueryImage(nCmdID, key)) - hr = SetPropertyVal(key, GetImage(hbm, UI_OWNERSHIP_TRANSFER), ppropvarNewValue); - break; - case k_Label: - case k_Keytip: - case k_TooltipTitle: - case k_TooltipDescription: - case k_LabelDescription: - if (LPCWSTR sText = pT->OnRibbonQueryText(nCmdID, key)) - hr = SetPropertyVal(key, sText, ppropvarNewValue); - break; - case k_BooleanValue: - case k_Enabled: - hr = SetPropertyVal(key, pT->OnRibbonQueryState(nCmdID, key), ppropvarNewValue); - break; - case k_ContextAvailable: - hr = SetPropertyVal(key, pT->OnRibbonQueryTabAvail(nCmdID), ppropvarNewValue); - break; - } - - return hr; - } - -// CRibbonImpl::CRibbonXXXCtrl specialized classes - //CRibbonComboCtrl - template - class CRibbonComboCtrl : public CollectionCtrlImpl, t_items, t_categories>> - { - public: - CRibbonComboCtrl() - { } - }; - - // CRibbonItemGalleryCtrl - template - class CRibbonItemGalleryCtrl : public CollectionCtrlImpl, t_items, t_categories>> - { - public: - CRibbonItemGalleryCtrl() - { } - }; - - // CRibbonCommandGalleryCtrl - template - class CRibbonCommandGalleryCtrl : public CollectionCtrlImpl, t_items, t_categories>> - { - public: - CRibbonCommandGalleryCtrl() - { } - }; - - // CRibbonToolbarGalleryCtrl - template - class CRibbonToolbarGalleryCtrl : public ToolbarGalleryCtrlImpl - { }; - - // CRibbonSimpleComboCtrl - template - class CRibbonSimpleComboCtrl : public SimpleCollectionCtrlImpl - { }; - - // CRibbonSimpleGalleryCtrl - template - class CRibbonSimpleGalleryCtrl : public SimpleCollectionCtrlImpl - { }; - - //CRibbonRecentItemsCtrl - template - class CRibbonRecentItemsCtrl : public RecentItemsCtrlImpl - { - public: - CRibbonRecentItemsCtrl() - { } - }; - - // CRibbonColorCtrl - template - class CRibbonColorCtrl : public ColorCtrlImpl - { - public: - CRibbonColorCtrl() - { } - }; - - //CRibbonFontCtrl - template - class CRibbonFontCtrl : public FontCtrlImpl - { - public: - CRibbonFontCtrl() - { } - }; - - // CRibbonSpinnerCtrl - template - class CRibbonSpinnerCtrl : public SpinnerCtrlImpl - { - public: - CRibbonSpinnerCtrl() - { } - }; - - // CRibbonFloatSpinnerCtrl - template - class CRibbonFloatSpinnerCtrl : public SpinnerCtrlImpl - { - public: - CRibbonFloatSpinnerCtrl() - { - m_Values[4] = 1; // 1 decimal - } - }; - - // CRibbonCommandCtrl - template - class CRibbonCommandCtrl : public CommandCtrlImpl - { - public: - CRibbonCommandCtrl() - { } - }; - -// Control classes access to T instance (re-initialized in constructor) - static T* pWndRibbon; -}; - -template -__declspec(selectany) T* CRibbonImpl::pWndRibbon; - -// Control map element -#pragma warning (disable : 4510 610) // missing default constructor -typedef struct -{ - UINT uID; - ICtrl& ctrl; -} _ribbonCtrl; -#pragma warning (default : 4510 610) // missing default constructor - -}; // namespace RibbonUI - - -/////////////////////////////////////////////////////////////////////////////// -// RibbonUI Control map - -// Control map macros -#define BEGIN_RIBBON_CONTROL_MAP(theClass) \ - RibbonUI::ICtrl& GetRibbonCtrl(UINT id) \ - { \ - RibbonUI::_ribbonCtrl _ctrls[] = \ - { - -#define RIBBON_CONTROL(member) {member.GetID(), static_cast(member)}, - -#define END_RIBBON_CONTROL_MAP() \ - {0, *this} \ - }; \ - int i = 0; \ - for(; i < _countof(_ctrls) - 1; i++) \ - if (_ctrls[i].uID == id) \ - break; \ - return _ctrls[i].ctrl; \ -} - -// Control message map macros -#define RIBBON_GALLERY_CONTROL_HANDLER(id, func) \ - if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \ - { \ - bHandled = TRUE; \ - lResult = func((UI_EXECUTIONVERB)HIWORD(wParam), LOWORD(wParam), (UINT)lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define RIBBON_COMBO_CONTROL_HANDLER(id, func) \ - RIBBON_GALLERY_CONTROL_HANDLER(id, func) - -#define RIBBON_FONT_CONTROL_HANDLER(id, func) \ - if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \ - { \ - bHandled = TRUE; \ - lResult = func((UI_EXECUTIONVERB)HIWORD(wParam), LOWORD(wParam), (CHARFORMAT2*)lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define RIBBON_COLOR_CONTROL_HANDLER(id, func) \ - if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \ - { \ - bHandled = TRUE; \ - lResult = func((UI_EXECUTIONVERB)HIWORD(wParam), LOWORD(wParam), (COLORREF)lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define RIBBON_SPINNER_CONTROL_HANDLER(id, func) \ - if(uMsg == WM_COMMAND && id == wParam) \ - { \ - bHandled = TRUE; \ - lResult = func((WORD)wParam, (LONG)lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define RIBBON_FLOATSPINNER_CONTROL_HANDLER(id, func) \ - if(uMsg == WM_COMMAND && id == wParam) \ - { \ - bHandled = TRUE; \ - lResult = func((WORD)wParam, (DOUBLE*)lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -// Handler prototypes -/* - LRESULT OnRibbonGalleryCtrl(UI_EXECUTIONVERB verb, WORD wID, UINT uSel, BOOL& bHandled); - LRESULT OnRibbonComboCtrl(UI_EXECUTIONVERB verb, WORD wID, UINT uSel, BOOL& bHandled); - LRESULT OnRibbonFontCtrl(UI_EXECUTIONVERB verb, WORD wID, CHARFORMAT2* pcf, BOOL& bHandled); - LRESULT OnRibbonColorCtrl(UI_EXECUTIONVERB verb, WORD wID, COLORREF color, BOOL& bHandled); - LRESULT OnRibbonSpinnerCtrl(WORD wID, LONG lVal, BOOL& bHandled); - LRESULT OnRibbonFloatSpinnerCtrl(WORD wID, DOUBLE* pdVal, BOOL& bHandled); -*/ - - -/////////////////////////////////////////////////////////////////////////////// -// Ribbon frame classes - -// CRibbonFrameWindowImplBase -// -template -class ATL_NO_VTABLE CRibbonFrameWindowImplBase : public TFrameImpl, public RibbonUI::CRibbonImpl -{ - typedef TFrameImpl baseFrame; - bool m_bUseCommandBarBitmaps; - bool m_bWin7Fix; - -public: -// Construction - CRibbonFrameWindowImplBase(bool bUseCommandBarBitmaps = true) : - m_bUseCommandBarBitmaps(bUseCommandBarBitmaps), m_bWin7Fix(false) - { - __if_not_exists(T::m_CmdBar) - { - m_bUseCommandBarBitmaps = false; - } - } - -// Win7 Aero fix helpers - void ResetFrame() - { - const MARGINS margins = { 0 }; - ::DwmExtendFrameIntoClientArea(m_hWnd, &margins); - } - - INT CalcWin7Fix() - { - ResetFrame(); - RECT rc = { 0 }; - ::AdjustWindowRectEx(&rc, T::GetWndStyle(0), GetMenu() != NULL, T::GetWndExStyle(0)); - return -rc.top; - } - - bool NeedWin7Fix() - { - BOOL bComp = FALSE; - return m_bWin7Fix && RunTimeHelper::IsWin7() && SUCCEEDED(DwmIsCompositionEnabled(&bComp)) && bComp; - } - -// Operations - bool UseCommandBarBitmaps(bool bUse) - { - __if_exists(T::m_CmdBar) - { - return m_bUseCommandBarBitmaps = bUse; - } - __if_not_exists(T::m_CmdBar) - { - bUse; // avoid level 4 warning - return false; - } - } - - bool ShowRibbonUI(bool bShow, INT32 imodes = UI_MAKEAPPMODE(0), LPCWSTR sResName = L"APPLICATION_RIBBON") - { - if (!RunTimeHelper::IsRibbonUIAvailable()) - return false; - - ATLASSERT(GetIUIFrameworkPtr()); - - if (IsRibbonUI() == bShow) - return bShow; - - bool bVisible = (IsWindowVisible() != FALSE); - if(bVisible && !bShow) - SetRedraw(FALSE); - - if (bShow && ::IsWindow(m_hWndToolBar)) - { - ::ShowWindow(m_hWndToolBar, SW_HIDE); - UpdateLayout(); - } - - m_bWin7Fix = !bShow; - - HRESULT hr = bShow ? CreateRibbon(sResName) : DestroyRibbon(); - - m_bWin7Fix = SUCCEEDED(hr) && !bShow; - - if (SUCCEEDED(hr)) - { - if(::IsWindow(m_hWndToolBar) && !bShow) - { - ::ShowWindow(m_hWndToolBar, SW_SHOWNA); - UpdateLayout(); - } - else if (bShow) - { - PostMessage(WM_SIZE); - SetRibbonModes(imodes); - } - } - - if(bVisible && !bShow) - { - SetRedraw(TRUE); - RedrawWindow(NULL, NULL, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); - } - - return SUCCEEDED(hr) ? bShow : !bShow; - } - -// Overrideables - HBITMAP OnRibbonQueryImage(UINT nCmdID, REFPROPERTYKEY key) - { - if ((key == UI_PKEY_SmallImage) && m_bUseCommandBarBitmaps) - { - if (HBITMAP hbm = GetCommandBarBitmap(nCmdID)) - return (HBITMAP)::CopyImage(hbm, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); - } - - return DefRibbonQueryImage(nCmdID); - } - - BEGIN_MSG_MAP(CRibbonFrameWindowImplBase) - if (!IsRibbonUI() && NeedWin7Fix()) - { - MESSAGE_HANDLER(WM_SIZING, OnSizing) - MESSAGE_HANDLER(WM_SIZE, OnSize) - MESSAGE_HANDLER(WM_ACTIVATE, OnActivate) - MESSAGE_HANDLER(WM_NCCALCSIZE, OnNCCalcSize) - } - CHAIN_MSG_MAP(CRibbonUpdateUI) - CHAIN_MSG_MAP(baseFrame) - END_MSG_MAP() - -// Message handlers for Win7 Aero - LRESULT OnSizing(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - switch (wParam) - { - case WMSZ_TOP: - case WMSZ_TOPLEFT: - case WMSZ_TOPRIGHT: - SetWindowPos(NULL, (LPRECT)lParam, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED); - break; - default: - DefWindowProc(); - break; - } - - return 1; // handled - } - - LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - if (wParam != SIZE_MINIMIZED) - SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); - - bHandled = FALSE; - return 1; - } - - LRESULT OnActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - if(wParam != WA_INACTIVE) - SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); - - bHandled = FALSE; - return 1; - } - - LRESULT OnNCCalcSize(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - ATLASSERT(!IsRibbonUI() && NeedWin7Fix()); - - LRESULT lRet = DefWindowProc(); - - if(wParam) - { - LPNCCALCSIZE_PARAMS pParams = (LPNCCALCSIZE_PARAMS)lParam; - pParams->rgrc[0].top = pParams->rgrc[1].top + CalcWin7Fix(); - } - - return lRet; - } - -// Overrides - void UpdateLayout(BOOL bResizeBars = TRUE) - { - RECT rect = { 0 }; - GetClientRect(&rect); - - if (IsRibbonUI() && !IsRibbonHidden()) - { - rect.top += GetRibbonHeight(); - } - else if (!IsRibbonUI() && NeedWin7Fix()) - { - ResetFrame(); - } - - // position bars and offset their dimensions - UpdateBarsPosition(rect, bResizeBars); - - // resize client window - if(m_hWndClient != NULL) - ::SetWindowPos(m_hWndClient, NULL, rect.left, rect.top, - rect.right - rect.left, rect.bottom - rect.top, - SWP_NOZORDER | SWP_NOACTIVATE); - } - - // Implementation - HBITMAP GetCommandBarBitmap(UINT nCmdID) - { - __if_exists (T::m_CmdBar) - { - ATLASSERT(RunTimeHelper::IsVista()); - T* pT =static_cast(this); - int nIndex = pT->m_CmdBar.m_arrCommand.Find((WORD&)nCmdID); - return (nIndex == -1) ? NULL : pT->m_CmdBar.m_arrVistaBitmap[nIndex]; - } - __if_not_exists (T::m_CmdBar) - { - nCmdID; // avoid level 4 warning - return NULL; - } - } -}; - -// CRibbonFrameWindowImpl -// -template -class ATL_NO_VTABLE CRibbonFrameWindowImpl : public CRibbonFrameWindowImplBase> -{ }; - -// CRibbonMDIFrameWindowImpl -// -template -class ATL_NO_VTABLE CRibbonMDIFrameWindowImpl : public CRibbonFrameWindowImplBase> -{ }; - - -/////////////////////////////////////////////////////////////////////////////// -// CRibbonPersist helper for RibbonUI persistency - -class CRibbonPersist -{ -public: - CRibbonPersist(LPCWSTR sAppKey) - { - ATLASSERT(sAppKey && *sAppKey); - m_Key.Create(HKEY_CURRENT_USER, sAppKey); - ATLASSERT(m_Key.m_hKey); - } - - CRegKeyEx m_Key; - - LONG Save(bool bRibbonUI, HGLOBAL hgSettings = NULL) - { - CRegKeyEx key; - const DWORD dwUI = bRibbonUI; - - LONG lRet = key.Create(m_Key, L"Ribbon"); - if(lRet != ERROR_SUCCESS) - return lRet; - - lRet = key.SetDWORDValue(L"UI", dwUI); - if(lRet != ERROR_SUCCESS) - return lRet; - - if (hgSettings != NULL) - { - LPBYTE pVal = (LPBYTE)::GlobalLock(hgSettings); - if (pVal != NULL) - { - lRet = key.SetBinaryValue(L"Settings", pVal, ::GlobalSize(hgSettings)); - ::GlobalUnlock(hgSettings); - } - else - { - lRet = GetLastError(); - } - } - - return lRet; - } - - LONG Restore(bool& bRibbonUI, HGLOBAL& hgSettings) - { - ATLASSERT(hgSettings == NULL); - - CRegKeyEx key; - - LONG lRet = key.Open(m_Key, L"Ribbon"); - if(lRet != ERROR_SUCCESS) - return lRet; - - DWORD dwUI = 0xffff; - lRet = key.QueryDWORDValue(L"UI", dwUI); - if(lRet == ERROR_SUCCESS) - bRibbonUI = dwUI == 1; - else - return lRet; - - ULONG ulSize = 0; - lRet = key.QueryBinaryValue(L"Settings", NULL, &ulSize); - if (lRet == ERROR_SUCCESS) - { - ATLASSERT(ulSize != 0); - - hgSettings = ::GlobalAlloc(GHND, ulSize); - if (hgSettings != NULL) - { - LPBYTE pData = (LPBYTE)::GlobalLock(hgSettings); - if (pData != NULL) - { - lRet = key.QueryBinaryValue(L"Settings", pData, &ulSize); - } - else - { - lRet = GetLastError(); - ::GlobalFree(hgSettings); - hgSettings = NULL; - } - } - else - { - lRet = GetLastError(); - } - } - return lRet; - } - - LONG Delete() - { - return m_Key.DeleteSubKey(L"Ribbon"); - } -}; - -} // namespace WTL - -#endif // __ATLRIBBON_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlscrl.h b/!NotAdopted/SmartAutoReplier/wtl/atlscrl.h deleted file mode 100644 index 0f59c9dd58..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlscrl.h +++ /dev/null @@ -1,2011 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLSCRL_H__ -#define __ATLSCRL_H__ - -#pragma once - -#ifndef __ATLAPP_H__ - #error atlscrl.h requires atlapp.h to be included first -#endif - -#ifndef __ATLWIN_H__ - #error atlscrl.h requires atlwin.h to be included first -#endif - -#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) - #include -#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) - -#ifndef GET_WHEEL_DELTA_WPARAM - #define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam)) -#endif - -#ifndef WM_MOUSEHWHEEL - #define WM_MOUSEHWHEEL 0x020E -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CScrollImpl -// CScrollWindowImpl -// CMapScrollImpl -// CMapScrollWindowImpl -// CFSBWindowT -// CZoomScrollImpl -// CZoomScrollWindowImpl -// CScrollContainerImpl -// CScrollContainer - -namespace WTL -{ - -/////////////////////////////////////////////////////////////////////////////// -// CScrollImpl - Provides scrolling support to any window - -// Scroll extended styles -#define SCRL_SCROLLCHILDREN 0x00000001 -#define SCRL_ERASEBACKGROUND 0x00000002 -#define SCRL_NOTHUMBTRACKING 0x00000004 -#if (WINVER >= 0x0500) -#define SCRL_SMOOTHSCROLL 0x00000008 -#endif // (WINVER >= 0x0500) -#define SCRL_DISABLENOSCROLLV 0x00000010 -#define SCRL_DISABLENOSCROLLH 0x00000020 -#define SCRL_DISABLENOSCROLL (SCRL_DISABLENOSCROLLV | SCRL_DISABLENOSCROLLH) - - -template -class CScrollImpl -{ -public: - enum { uSCROLL_FLAGS = SW_INVALIDATE }; - - POINT m_ptOffset; - SIZE m_sizeAll; - SIZE m_sizeLine; - SIZE m_sizePage; - SIZE m_sizeClient; - int m_zDelta; // current wheel value - int m_nWheelLines; // number of lines to scroll on wheel -#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) - // Note that this message must be forwarded from a top level window - UINT m_uMsgMouseWheel; // MSH_MOUSEWHEEL -#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) - int m_zHDelta; // current horizontal wheel value - int m_nHWheelChars; // number of chars to scroll on horizontal wheel - UINT m_uScrollFlags; - DWORD m_dwExtendedStyle; // scroll specific extended styles - -// Constructor - CScrollImpl() : m_zDelta(0), m_nWheelLines(3), -#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) - m_uMsgMouseWheel(0U), -#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) - m_zHDelta(0), m_nHWheelChars(3), - m_uScrollFlags(0U), m_dwExtendedStyle(0) - { - m_ptOffset.x = 0; - m_ptOffset.y = 0; - m_sizeAll.cx = 0; - m_sizeAll.cy = 0; - m_sizePage.cx = 0; - m_sizePage.cy = 0; - m_sizeLine.cx = 0; - m_sizeLine.cy = 0; - m_sizeClient.cx = 0; - m_sizeClient.cy = 0; - - SetScrollExtendedStyle(SCRL_SCROLLCHILDREN | SCRL_ERASEBACKGROUND); - } - -// Attributes & Operations - DWORD GetScrollExtendedStyle() const - { - return m_dwExtendedStyle; - } - - DWORD SetScrollExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) - { - DWORD dwPrevStyle = m_dwExtendedStyle; - if(dwMask == 0) - m_dwExtendedStyle = dwExtendedStyle; - else - m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); - // cache scroll flags - T* pT = static_cast(this); - pT; // avoid level 4 warning - m_uScrollFlags = pT->uSCROLL_FLAGS | (IsScrollingChildren() ? SW_SCROLLCHILDREN : 0) | (IsErasingBackground() ? SW_ERASE : 0); -#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) - m_uScrollFlags |= (IsSmoothScroll() ? SW_SMOOTHSCROLL : 0); -#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) - return dwPrevStyle; - } - - // offset operations - void SetScrollOffset(int x, int y, BOOL bRedraw = TRUE) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - - pT->AdjustScrollOffset(x, y); - - int dx = m_ptOffset.x - x; - int dy = m_ptOffset.y - y; - m_ptOffset.x = x; - m_ptOffset.y = y; - - // block: set horizontal scroll bar - { - SCROLLINFO si = { sizeof(SCROLLINFO) }; - si.fMask = SIF_POS; - if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLH) != 0) - si.fMask |= SIF_DISABLENOSCROLL; - si.nPos = m_ptOffset.x; - pT->SetScrollInfo(SB_HORZ, &si, bRedraw); - } - - // block: set vertical scroll bar - { - SCROLLINFO si = { sizeof(SCROLLINFO) }; - si.fMask = SIF_POS; - if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLV) != 0) - si.fMask |= SIF_DISABLENOSCROLL; - si.nPos = m_ptOffset.y; - pT->SetScrollInfo(SB_VERT, &si, bRedraw); - } - - // Move all children if needed - if(IsScrollingChildren() && (dx != 0 || dy != 0)) - { - for(HWND hWndChild = ::GetWindow(pT->m_hWnd, GW_CHILD); hWndChild != NULL; hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT)) - { - RECT rect = { 0 }; - ::GetWindowRect(hWndChild, &rect); - ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rect, 1); - ::SetWindowPos(hWndChild, NULL, rect.left + dx, rect.top + dy, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); - } - } - - if(bRedraw) - pT->Invalidate(); - } - - void SetScrollOffset(POINT ptOffset, BOOL bRedraw = TRUE) - { - SetScrollOffset(ptOffset.x, ptOffset.y, bRedraw); - } - - void GetScrollOffset(POINT& ptOffset) const - { - ptOffset = m_ptOffset; - } - - // size operations - void SetScrollSize(int cx, int cy, BOOL bRedraw = TRUE, bool bResetOffset = true) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - - m_sizeAll.cx = cx; - m_sizeAll.cy = cy; - - int x = 0; - int y = 0; - if(!bResetOffset) - { - x = m_ptOffset.x; - y = m_ptOffset.y; - pT->AdjustScrollOffset(x, y); - } - - int dx = m_ptOffset.x - x; - int dy = m_ptOffset.y - y; - m_ptOffset.x = x; - m_ptOffset.y = y; - - // block: set horizontal scroll bar - { - SCROLLINFO si = { sizeof(SCROLLINFO) }; - si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; - if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLH) != 0) - si.fMask |= SIF_DISABLENOSCROLL; - si.nMin = 0; - si.nMax = m_sizeAll.cx - 1; - si.nPage = m_sizeClient.cx; - si.nPos = m_ptOffset.x; - pT->SetScrollInfo(SB_HORZ, &si, bRedraw); - } - - // block: set vertical scroll bar - { - SCROLLINFO si = { sizeof(SCROLLINFO) }; - si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; - if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLV) != 0) - si.fMask |= SIF_DISABLENOSCROLL; - si.nMin = 0; - si.nMax = m_sizeAll.cy - 1; - si.nPage = m_sizeClient.cy; - si.nPos = m_ptOffset.y; - pT->SetScrollInfo(SB_VERT, &si, bRedraw); - } - - // Move all children if needed - if(IsScrollingChildren() && (dx != 0 || dy != 0)) - { - for(HWND hWndChild = ::GetWindow(pT->m_hWnd, GW_CHILD); hWndChild != NULL; hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT)) - { - RECT rect = { 0 }; - ::GetWindowRect(hWndChild, &rect); - ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rect, 1); - ::SetWindowPos(hWndChild, NULL, rect.left + dx, rect.top + dy, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); - } - } - - SetScrollLine(0, 0); - SetScrollPage(0, 0); - - if(bRedraw) - pT->Invalidate(); - } - - void SetScrollSize(SIZE size, BOOL bRedraw = TRUE, bool bResetOffset = true) - { - SetScrollSize(size.cx, size.cy, bRedraw, bResetOffset); - } - - void GetScrollSize(SIZE& sizeWnd) const - { - sizeWnd = m_sizeAll; - } - - // line operations - void SetScrollLine(int cxLine, int cyLine) - { - ATLASSERT(cxLine >= 0 && cyLine >= 0); - ATLASSERT(m_sizeAll.cx != 0 && m_sizeAll.cy != 0); - - m_sizeLine.cx = T::CalcLineOrPage(cxLine, m_sizeAll.cx, 100); - m_sizeLine.cy = T::CalcLineOrPage(cyLine, m_sizeAll.cy, 100); - } - - void SetScrollLine(SIZE sizeLine) - { - SetScrollLine(sizeLine.cx, sizeLine.cy); - } - - void GetScrollLine(SIZE& sizeLine) const - { - sizeLine = m_sizeLine; - } - - // page operations - void SetScrollPage(int cxPage, int cyPage) - { - ATLASSERT(cxPage >= 0 && cyPage >= 0); - ATLASSERT(m_sizeAll.cx != 0 && m_sizeAll.cy != 0); - - m_sizePage.cx = T::CalcLineOrPage(cxPage, m_sizeAll.cx, 10); - m_sizePage.cy = T::CalcLineOrPage(cyPage, m_sizeAll.cy, 10); - } - - void SetScrollPage(SIZE sizePage) - { - SetScrollPage(sizePage.cx, sizePage.cy); - } - - void GetScrollPage(SIZE& sizePage) const - { - sizePage = m_sizePage; - } - - // commands - void ScrollLineDown() - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - pT->DoScroll(SB_VERT, SB_LINEDOWN, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy); - } - - void ScrollLineUp() - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - pT->DoScroll(SB_VERT, SB_LINEUP, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy); - } - - void ScrollPageDown() - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - pT->DoScroll(SB_VERT, SB_PAGEDOWN, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy); - } - - void ScrollPageUp() - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - pT->DoScroll(SB_VERT, SB_PAGEUP, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy); - } - - void ScrollTop() - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - pT->DoScroll(SB_VERT, SB_TOP, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy); - } - - void ScrollBottom() - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - pT->DoScroll(SB_VERT, SB_BOTTOM, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy); - } - - void ScrollLineRight() - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - pT->DoScroll(SB_HORZ, SB_LINEDOWN, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); - } - - void ScrollLineLeft() - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - pT->DoScroll(SB_HORZ, SB_LINEUP, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); - } - - void ScrollPageRight() - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - pT->DoScroll(SB_HORZ, SB_PAGEDOWN, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); - } - - void ScrollPageLeft() - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - pT->DoScroll(SB_HORZ, SB_PAGEUP, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); - } - - void ScrollAllLeft() - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - pT->DoScroll(SB_HORZ, SB_TOP, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); - } - - void ScrollAllRight() - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - pT->DoScroll(SB_HORZ, SB_BOTTOM, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); - } - - // scroll to make point/view/window visible - void ScrollToView(POINT pt) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - RECT rect = { pt.x, pt.y, pt.x, pt.y }; - pT->ScrollToView(rect); - } - - void ScrollToView(RECT& rect) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - - RECT rcClient = { 0 }; - pT->GetClientRect(&rcClient); - - int x = m_ptOffset.x; - if(rect.left < m_ptOffset.x) - x = rect.left; - else if(rect.right > (m_ptOffset.x + rcClient.right)) - x = rect.right - rcClient.right; - - int y = m_ptOffset.y; - if(rect.top < m_ptOffset.y) - y = rect.top; - else if(rect.bottom > (m_ptOffset.y + rcClient.bottom)) - y = rect.bottom - rcClient.bottom; - - SetScrollOffset(x, y); - } - - void ScrollToView(HWND hWnd) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - - RECT rect = { 0 }; - ::GetWindowRect(hWnd, &rect); - ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rect, 2); - ScrollToView(rect); - } - - BEGIN_MSG_MAP(CScrollImpl) - MESSAGE_HANDLER(WM_CREATE, OnCreate) - MESSAGE_HANDLER(WM_VSCROLL, OnVScroll) - MESSAGE_HANDLER(WM_HSCROLL, OnHScroll) - MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel) -#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) - MESSAGE_HANDLER(m_uMsgMouseWheel, OnMouseWheel) -#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) - MESSAGE_HANDLER(WM_MOUSEHWHEEL, OnMouseHWheel) - MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) - MESSAGE_HANDLER(WM_SIZE, OnSize) - MESSAGE_HANDLER(WM_PAINT, OnPaint) -#ifndef _WIN32_WCE - MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) -#endif // !_WIN32_WCE - // standard scroll commands - ALT_MSG_MAP(1) - COMMAND_ID_HANDLER(ID_SCROLL_UP, OnScrollUp) - COMMAND_ID_HANDLER(ID_SCROLL_DOWN, OnScrollDown) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, OnScrollPageUp) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, OnScrollPageDown) - COMMAND_ID_HANDLER(ID_SCROLL_TOP, OnScrollTop) - COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, OnScrollBottom) - COMMAND_ID_HANDLER(ID_SCROLL_LEFT, OnScrollLeft) - COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, OnScrollRight) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, OnScrollPageLeft) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, OnScrollPageRight) - COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, OnScrollAllLeft) - COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, OnScrollAllRight) - END_MSG_MAP() - - LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - GetSystemSettings(); - bHandled = FALSE; - return 1; - } - - LRESULT OnVScroll(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - pT->DoScroll(SB_VERT, (int)(short)LOWORD(wParam), (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy); - return 0; - } - - LRESULT OnHScroll(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - pT->DoScroll(SB_HORZ, (int)(short)LOWORD(wParam), (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); - return 0; - } - - LRESULT OnMouseWheel(UINT uMsg, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - -#if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400) || defined(_WIN32_WCE) - uMsg; - int zDelta = (int)GET_WHEEL_DELTA_WPARAM(wParam); -#else - int zDelta = (uMsg == WM_MOUSEWHEEL) ? (int)GET_WHEEL_DELTA_WPARAM(wParam) : (int)wParam; -#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400) || defined(_WIN32_WCE)) - int nScrollCode = (m_nWheelLines == WHEEL_PAGESCROLL) ? ((zDelta > 0) ? SB_PAGEUP : SB_PAGEDOWN) : ((zDelta > 0) ? SB_LINEUP : SB_LINEDOWN); - m_zDelta += zDelta; // cumulative - int zTotal = (m_nWheelLines == WHEEL_PAGESCROLL) ? abs(m_zDelta) : abs(m_zDelta) * m_nWheelLines; - if(m_sizeAll.cy > m_sizeClient.cy) - { - for(int i = 0; i < zTotal; i += WHEEL_DELTA) - { - pT->DoScroll(SB_VERT, nScrollCode, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy); - pT->UpdateWindow(); - } - } - else // can't scroll vertically, scroll horizontally - { - for(int i = 0; i < zTotal; i += WHEEL_DELTA) - { - pT->DoScroll(SB_HORZ, nScrollCode, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); - pT->UpdateWindow(); - } - } - m_zDelta %= WHEEL_DELTA; - - return 0; - } - - LRESULT OnMouseHWheel(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - - int zDelta = (int)GET_WHEEL_DELTA_WPARAM(wParam); - int nScrollCode = (m_nHWheelChars == WHEEL_PAGESCROLL) ? ((zDelta > 0) ? SB_PAGERIGHT : SB_PAGELEFT) : ((zDelta > 0) ? SB_LINERIGHT : SB_LINELEFT); - m_zHDelta += zDelta; // cumulative - int zTotal = (m_nHWheelChars == WHEEL_PAGESCROLL) ? abs(m_zHDelta) : abs(m_zHDelta) * m_nHWheelChars; - if(m_sizeAll.cx > m_sizeClient.cx) - { - for(int i = 0; i < zTotal; i += WHEEL_DELTA) - { - pT->DoScroll(SB_HORZ, nScrollCode, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); - pT->UpdateWindow(); - } - } - m_zHDelta %= WHEEL_DELTA; - - return 0; - } - - LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - GetSystemSettings(); - return 0; - } - - LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - - m_sizeClient.cx = GET_X_LPARAM(lParam); - m_sizeClient.cy = GET_Y_LPARAM(lParam); - - // block: set horizontal scroll bar - { - SCROLLINFO si = { sizeof(SCROLLINFO) }; - si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; - si.nMin = 0; - si.nMax = m_sizeAll.cx - 1; - if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLH) != 0) - si.fMask |= SIF_DISABLENOSCROLL; - si.nPage = m_sizeClient.cx; - si.nPos = m_ptOffset.x; - pT->SetScrollInfo(SB_HORZ, &si, TRUE); - } - - // block: set vertical scroll bar - { - SCROLLINFO si = { sizeof(SCROLLINFO) }; - si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; - si.nMin = 0; - si.nMax = m_sizeAll.cy - 1; - if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLV) != 0) - si.fMask |= SIF_DISABLENOSCROLL; - si.nPage = m_sizeClient.cy; - si.nPos = m_ptOffset.y; - pT->SetScrollInfo(SB_VERT, &si, TRUE); - } - - int x = m_ptOffset.x; - int y = m_ptOffset.y; - if(pT->AdjustScrollOffset(x, y)) - { - // Children will be moved in SetScrollOffset, if needed - pT->ScrollWindowEx(m_ptOffset.x - x, m_ptOffset.y - y, (m_uScrollFlags & ~SCRL_SCROLLCHILDREN)); - SetScrollOffset(x, y, FALSE); - } - - bHandled = FALSE; - return 1; - } - - LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - if(wParam != NULL) - { - CDCHandle dc = (HDC)wParam; - POINT ptViewportOrg = { 0, 0 }; - dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewportOrg); - pT->DoPaint(dc); - dc.SetViewportOrg(ptViewportOrg); - } - else - { - CPaintDC dc(pT->m_hWnd); - dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y); - pT->DoPaint(dc.m_hDC); - } - return 0; - } - - // scrolling handlers - LRESULT OnScrollUp(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - ScrollLineUp(); - return 0; - } - - LRESULT OnScrollDown(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - ScrollLineDown(); - return 0; - } - - LRESULT OnScrollPageUp(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - ScrollPageUp(); - return 0; - } - - LRESULT OnScrollPageDown(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - ScrollPageDown(); - return 0; - } - - LRESULT OnScrollTop(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - ScrollTop(); - return 0; - } - - LRESULT OnScrollBottom(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - ScrollBottom(); - return 0; - } - - LRESULT OnScrollLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - ScrollLineLeft(); - return 0; - } - - LRESULT OnScrollRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - ScrollLineRight(); - return 0; - } - - LRESULT OnScrollPageLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - ScrollPageLeft(); - return 0; - } - - LRESULT OnScrollPageRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - ScrollPageRight(); - return 0; - } - - LRESULT OnScrollAllLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - ScrollAllLeft(); - return 0; - } - - LRESULT OnScrollAllRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - ScrollAllRight(); - return 0; - } - -// Overrideables - void DoPaint(CDCHandle /*dc*/) - { - // must be implemented in a derived class - ATLASSERT(FALSE); - } - -// Implementation - void DoScroll(int nType, int nScrollCode, int& cxyOffset, int cxySizeAll, int cxySizePage, int cxySizeLine) - { - T* pT = static_cast(this); - RECT rect = { 0 }; - pT->GetClientRect(&rect); - int cxyClient = (nType == SB_VERT) ? rect.bottom : rect.right; - int cxyMax = cxySizeAll - cxyClient; - - if(cxyMax < 0) // can't scroll, client area is bigger - return; - - bool bUpdate = true; - int cxyScroll = 0; - - switch(nScrollCode) - { - case SB_TOP: // top or all left - cxyScroll = cxyOffset; - cxyOffset = 0; - break; - case SB_BOTTOM: // bottom or all right - cxyScroll = cxyOffset - cxyMax; - cxyOffset = cxyMax; - break; - case SB_LINEUP: // line up or line left - if(cxyOffset >= cxySizeLine) - { - cxyScroll = cxySizeLine; - cxyOffset -= cxySizeLine; - } - else - { - cxyScroll = cxyOffset; - cxyOffset = 0; - } - break; - case SB_LINEDOWN: // line down or line right - if(cxyOffset < cxyMax - cxySizeLine) - { - cxyScroll = -cxySizeLine; - cxyOffset += cxySizeLine; - } - else - { - cxyScroll = cxyOffset - cxyMax; - cxyOffset = cxyMax; - } - break; - case SB_PAGEUP: // page up or page left - if(cxyOffset >= cxySizePage) - { - cxyScroll = cxySizePage; - cxyOffset -= cxySizePage; - } - else - { - cxyScroll = cxyOffset; - cxyOffset = 0; - } - break; - case SB_PAGEDOWN: // page down or page right - if(cxyOffset < cxyMax - cxySizePage) - { - cxyScroll = -cxySizePage; - cxyOffset += cxySizePage; - } - else - { - cxyScroll = cxyOffset - cxyMax; - cxyOffset = cxyMax; - } - break; - case SB_THUMBTRACK: - if(IsNoThumbTracking()) - break; - // else fall through - case SB_THUMBPOSITION: - { - SCROLLINFO si = { sizeof(SCROLLINFO), SIF_TRACKPOS }; - if(pT->GetScrollInfo(nType, &si)) - { - cxyScroll = cxyOffset - si.nTrackPos; - cxyOffset = si.nTrackPos; - } - } - break; - case SB_ENDSCROLL: - default: - bUpdate = false; - break; - } - - if(bUpdate && cxyScroll != 0) - { - pT->SetScrollPos(nType, cxyOffset, TRUE); - if(nType == SB_VERT) - pT->ScrollWindowEx(0, cxyScroll, m_uScrollFlags); - else - pT->ScrollWindowEx(cxyScroll, 0, m_uScrollFlags); - } - } - - static int CalcLineOrPage(int nVal, int nMax, int nDiv) - { - if(nVal == 0) - { - nVal = nMax / nDiv; - if(nVal < 1) - nVal = 1; - } - else if(nVal > nMax) - { - nVal = nMax; - } - - return nVal; - } - - bool AdjustScrollOffset(int& x, int& y) - { - int xOld = x; - int yOld = y; - - int cxMax = m_sizeAll.cx - m_sizeClient.cx; - if(x > cxMax) - x = (cxMax >= 0) ? cxMax : 0; - else if(x < 0) - x = 0; - - int cyMax = m_sizeAll.cy - m_sizeClient.cy; - if(y > cyMax) - y = (cyMax >= 0) ? cyMax : 0; - else if(y < 0) - y = 0; - - return (x != xOld || y != yOld); - } - - void GetSystemSettings() - { -#ifndef _WIN32_WCE -#ifndef SPI_GETWHEELSCROLLLINES - const UINT SPI_GETWHEELSCROLLLINES = 104; -#endif // !SPI_GETWHEELSCROLLLINES - ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &m_nWheelLines, 0); - -#ifndef SPI_GETWHEELSCROLLCHARS - const UINT SPI_GETWHEELSCROLLCHARS = 0x006C; -#endif // !SPI_GETWHEELSCROLLCHARS - ::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &m_nHWheelChars, 0); - -#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) - if(m_uMsgMouseWheel != 0) - m_uMsgMouseWheel = ::RegisterWindowMessage(MSH_MOUSEWHEEL); - - HWND hWndWheel = FindWindow(MSH_WHEELMODULE_CLASS, MSH_WHEELMODULE_TITLE); - if(::IsWindow(hWndWheel)) - { - UINT uMsgScrollLines = ::RegisterWindowMessage(MSH_SCROLL_LINES); - if(uMsgScrollLines != 0) - m_nWheelLines = (int)::SendMessage(hWndWheel, uMsgScrollLines, 0, 0L); - } -#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) -#endif // !_WIN32_WCE - } - - bool IsScrollingChildren() const - { - return (m_dwExtendedStyle & SCRL_SCROLLCHILDREN) != 0; - } - - bool IsErasingBackground() const - { - return (m_dwExtendedStyle & SCRL_ERASEBACKGROUND) != 0; - } - - bool IsNoThumbTracking() const - { - return (m_dwExtendedStyle & SCRL_NOTHUMBTRACKING) != 0; - } - -#if (WINVER >= 0x0500) - bool IsSmoothScroll() const - { - return (m_dwExtendedStyle & SCRL_SMOOTHSCROLL) != 0; - } -#endif // (WINVER >= 0x0500) -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CScrollWindowImpl - Implements a scrollable window - -template -class ATL_NO_VTABLE CScrollWindowImpl : public ATL::CWindowImpl, public CScrollImpl< T > -{ -public: - BEGIN_MSG_MAP(CScrollWindowImpl) - MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll) - MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll) - MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel) -#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) - MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel) -#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) - MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel) - MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange) - MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize) - MESSAGE_HANDLER(WM_PAINT, CScrollImpl< T >::OnPaint) -#ifndef _WIN32_WCE - MESSAGE_HANDLER(WM_PRINTCLIENT, CScrollImpl< T >::OnPaint) -#endif // !_WIN32_WCE - ALT_MSG_MAP(1) - COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp) - COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown) - COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop) - COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom) - COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft) - COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight) - COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft) - COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight) - END_MSG_MAP() -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CMapScrollImpl - Provides mapping and scrolling support to any window - -#ifndef _WIN32_WCE - -template -class CMapScrollImpl : public CScrollImpl< T > -{ -public: - int m_nMapMode; - RECT m_rectLogAll; - SIZE m_sizeLogLine; - SIZE m_sizeLogPage; - -// Constructor - CMapScrollImpl() : m_nMapMode(MM_TEXT) - { - ::SetRectEmpty(&m_rectLogAll); - m_sizeLogPage.cx = 0; - m_sizeLogPage.cy = 0; - m_sizeLogLine.cx = 0; - m_sizeLogLine.cy = 0; - } - -// Attributes & Operations - // mapping mode operations - void SetScrollMapMode(int nMapMode) - { - ATLASSERT(nMapMode >= MM_MIN && nMapMode <= MM_MAX_FIXEDSCALE); - m_nMapMode = nMapMode; - } - - int GetScrollMapMode() const - { - ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); - return m_nMapMode; - } - - // offset operations - void SetScrollOffset(int x, int y, BOOL bRedraw = TRUE) - { - ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); - POINT ptOff = { x, y }; - // block: convert logical to device units - { - CWindowDC dc(NULL); - dc.SetMapMode(m_nMapMode); - dc.LPtoDP(&ptOff); - } - CScrollImpl< T >::SetScrollOffset(ptOff, bRedraw); - } - - void SetScrollOffset(POINT ptOffset, BOOL bRedraw = TRUE) - { - SetScrollOffset(ptOffset.x, ptOffset.y, bRedraw); - } - - void GetScrollOffset(POINT& ptOffset) const - { - ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); - ptOffset = m_ptOffset; - // block: convert device to logical units - { - CWindowDC dc(NULL); - dc.SetMapMode(m_nMapMode); - dc.DPtoLP(&ptOffset); - } - } - - // size operations - void SetScrollSize(int xMin, int yMin, int xMax, int yMax, BOOL bRedraw = TRUE, bool bResetOffset = true) - { - ATLASSERT(xMax > xMin && yMax > yMin); - ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); - - ::SetRect(&m_rectLogAll, xMin, yMin, xMax, yMax); - - SIZE sizeAll = { 0 }; - sizeAll.cx = xMax - xMin + 1; - sizeAll.cy = yMax - yMin + 1; - // block: convert logical to device units - { - CWindowDC dc(NULL); - dc.SetMapMode(m_nMapMode); - dc.LPtoDP(&sizeAll); - } - CScrollImpl< T >::SetScrollSize(sizeAll, bRedraw, bResetOffset); - SetScrollLine(0, 0); - SetScrollPage(0, 0); - } - - void SetScrollSize(RECT& rcScroll, BOOL bRedraw = TRUE, bool bResetOffset = true) - { - SetScrollSize(rcScroll.left, rcScroll.top, rcScroll.right, rcScroll.bottom, bRedraw, bResetOffset); - } - - void SetScrollSize(int cx, int cy, BOOL bRedraw = TRUE, bool bResetOffset = true) - { - SetScrollSize(0, 0, cx, cy, bRedraw, bResetOffset); - } - - void SetScrollSize(SIZE size, BOOL bRedraw = TRUE, bool bResetOffset = true) - { - SetScrollSize(0, 0, size.cx, size.cy, bRedraw, bResetOffset); - } - - void GetScrollSize(RECT& rcScroll) const - { - ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); - rcScroll = m_rectLogAll; - } - - // line operations - void SetScrollLine(int cxLine, int cyLine) - { - ATLASSERT(cxLine >= 0 && cyLine >= 0); - ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); - - m_sizeLogLine.cx = cxLine; - m_sizeLogLine.cy = cyLine; - SIZE sizeLine = m_sizeLogLine; - // block: convert logical to device units - { - CWindowDC dc(NULL); - dc.SetMapMode(m_nMapMode); - dc.LPtoDP(&sizeLine); - } - CScrollImpl< T >::SetScrollLine(sizeLine); - } - - void SetScrollLine(SIZE sizeLine) - { - SetScrollLine(sizeLine.cx, sizeLine.cy); - } - - void GetScrollLine(SIZE& sizeLine) const - { - ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); - sizeLine = m_sizeLogLine; - } - - // page operations - void SetScrollPage(int cxPage, int cyPage) - { - ATLASSERT(cxPage >= 0 && cyPage >= 0); - ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); - - m_sizeLogPage.cx = cxPage; - m_sizeLogPage.cy = cyPage; - SIZE sizePage = m_sizeLogPage; - // block: convert logical to device units - { - CWindowDC dc(NULL); - dc.SetMapMode(m_nMapMode); - dc.LPtoDP(&sizePage); - } - CScrollImpl< T >::SetScrollPage(sizePage); - } - - void SetScrollPage(SIZE sizePage) - { - SetScrollPage(sizePage.cx, sizePage.cy); - } - - void GetScrollPage(SIZE& sizePage) const - { - ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); - sizePage = m_sizeLogPage; - } - - BEGIN_MSG_MAP(CMapScrollImpl) - MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll) - MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll) - MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel) -#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) - MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel) -#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) - MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel) - MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange) - MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize) - MESSAGE_HANDLER(WM_PAINT, OnPaint) - MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) - ALT_MSG_MAP(1) - COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp) - COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown) - COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop) - COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom) - COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft) - COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight) - COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft) - COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight) - END_MSG_MAP() - - LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - if(wParam != NULL) - { - CDCHandle dc = (HDC)wParam; - int nMapModeSav = dc.GetMapMode(); - dc.SetMapMode(m_nMapMode); - POINT ptViewportOrg = { 0, 0 }; - if(m_nMapMode == MM_TEXT) - dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewportOrg); - else - dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y + m_sizeAll.cy, &ptViewportOrg); - POINT ptWindowOrg = { 0, 0 }; - dc.SetWindowOrg(m_rectLogAll.left, m_rectLogAll.top, &ptWindowOrg); - - pT->DoPaint(dc); - - dc.SetMapMode(nMapModeSav); - dc.SetViewportOrg(ptViewportOrg); - dc.SetWindowOrg(ptWindowOrg); - } - else - { - CPaintDC dc(pT->m_hWnd); - dc.SetMapMode(m_nMapMode); - if(m_nMapMode == MM_TEXT) - dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y); - else - dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y + m_sizeAll.cy); - dc.SetWindowOrg(m_rectLogAll.left, m_rectLogAll.top); - pT->DoPaint(dc.m_hDC); - } - return 0; - } -}; - -#endif // !_WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CMapScrollWindowImpl - Implements scrolling window with mapping - -#ifndef _WIN32_WCE - -template -class ATL_NO_VTABLE CMapScrollWindowImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CMapScrollImpl< T > -{ -public: - BEGIN_MSG_MAP(CMapScrollWindowImpl) - MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll) - MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll) - MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel) -#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) - MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel) -#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) - MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel) - MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange) - MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize) - MESSAGE_HANDLER(WM_PAINT, CMapScrollImpl< T >::OnPaint) - MESSAGE_HANDLER(WM_PRINTCLIENT, CMapScrollImpl< T >::OnPaint) - ALT_MSG_MAP(1) - COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp) - COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown) - COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop) - COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom) - COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft) - COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight) - COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft) - COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight) - END_MSG_MAP() -}; - -#endif // !_WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CFSBWindow - Use as a base instead of CWindow to get flat scroll bar support - -#if defined(__ATLCTRLS_H__) && (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - -template -class CFSBWindowT : public TBase, public CFlatScrollBarImpl > -{ -public: -// Constructors - CFSBWindowT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CFSBWindowT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - -// CWindow overrides that use flat scroll bar API -// (only those methods that are used by scroll window classes) - int SetScrollPos(int nBar, int nPos, BOOL bRedraw = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return FlatSB_SetScrollPos(nBar, nPos, bRedraw); - } - - BOOL GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo) - { - ATLASSERT(::IsWindow(m_hWnd)); - return FlatSB_GetScrollInfo(nBar, lpScrollInfo); - } - - BOOL SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - return FlatSB_SetScrollInfo(nBar, lpScrollInfo, bRedraw); - } -}; - -typedef CFSBWindowT CFSBWindow; - -#endif // defined(__ATLCTRLS_H__) && (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) - - -/////////////////////////////////////////////////////////////////////////////// -// CZoomScrollImpl - Provides zooming and scrolling support to any window - -#ifndef _WIN32_WCE - -// The zoom modes that can be set with the SetZoomMode method -enum -{ - ZOOMMODE_OFF, - ZOOMMODE_IN, // If left mouse button is clicked or dragged, zoom in on point clicked or rectangle dragged. - ZOOMMODE_OUT // If left mouse button clicked, zoom out on point clicked. -}; - -// Notification to parent that zoom scale changed as a result of user mouse action. -#define ZSN_ZOOMCHANGED (NM_FIRST - 50) - -template -class CZoomScrollImpl : public CScrollImpl< T > -{ -public: - enum { m_cxyMinZoomRect = 12 }; // min rect size to zoom in on rect. - -// Data members - SIZE m_sizeLogAll; - SIZE m_sizeLogLine; - SIZE m_sizeLogPage; - float m_fZoomScale; - float m_fZoomScaleMin; - float m_fZoomDelta; // Used in ZOOMMODE_IN and ZOOMMODE_OUT on left-button click. - int m_nZoomMode; - RECT m_rcTrack; - bool m_bTracking; - -// Constructor - CZoomScrollImpl(): - m_fZoomScale(1.0), - m_fZoomScaleMin(0.5), - m_fZoomDelta(0.5), - m_nZoomMode(ZOOMMODE_OFF), - m_bTracking(false) - { - m_sizeLogAll.cx = 0; - m_sizeLogAll.cy = 0; - m_sizeLogPage.cx = 0; - m_sizeLogPage.cy = 0; - m_sizeLogLine.cx = 0; - m_sizeLogLine.cy = 0; - ::SetRectEmpty(&m_rcTrack); - } - -// Attributes & Operations - - // size operations - void SetScrollSize(int cxLog, int cyLog, BOOL bRedraw = TRUE, bool bResetOffset = true) - { - ATLASSERT(cxLog >= 0 && cyLog >= 0); - - // Set up the defaults - if (cxLog == 0 && cyLog == 0) - { - cxLog = 1; - cyLog = 1; - } - - m_sizeLogAll.cx = cxLog; - m_sizeLogAll.cy = cyLog; - SIZE sizeAll = { 0 }; - sizeAll.cx = (int)((float)m_sizeLogAll.cx * m_fZoomScale); - sizeAll.cy = (int)((float)m_sizeLogAll.cy * m_fZoomScale); - - CScrollImpl< T >::SetScrollSize(sizeAll, bRedraw, bResetOffset); - } - - void SetScrollSize(SIZE sizeLog, BOOL bRedraw = TRUE, bool bResetOffset = true) - { - SetScrollSize(sizeLog.cx, sizeLog.cy, bRedraw, bResetOffset); - } - - void GetScrollSize(SIZE& sizeLog) const - { - sizeLog = m_sizeLogAll; - } - - // line operations - void SetScrollLine(int cxLogLine, int cyLogLine) - { - ATLASSERT(cxLogLine >= 0 && cyLogLine >= 0); - - m_sizeLogLine.cx = cxLogLine; - m_sizeLogLine.cy = cyLogLine; - - SIZE sizeLine = { 0 }; - sizeLine.cx = (int)((float)m_sizeLogLine.cx * m_fZoomScale); - sizeLine.cy = (int)((float)m_sizeLogLine.cy * m_fZoomScale); - CScrollImpl< T >::SetScrollLine(sizeLine); - } - - void SetScrollLine(SIZE sizeLogLine) - { - SetScrollLine(sizeLogLine.cx, sizeLogLine.cy); - } - - void GetScrollLine(SIZE& sizeLogLine) const - { - sizeLogLine = m_sizeLogLine; - } - - // page operations - void SetScrollPage(int cxLogPage, int cyLogPage) - { - ATLASSERT(cxLogPage >= 0 && cyLogPage >= 0); - - m_sizeLogPage.cx = cxLogPage; - m_sizeLogPage.cy = cyLogPage; - - SIZE sizePage = { 0 }; - sizePage.cx = (int)((float)m_sizeLogPage.cx * m_fZoomScale); - sizePage.cy = (int)((float)m_sizeLogPage.cy * m_fZoomScale); - - CScrollImpl< T >::SetScrollPage(sizePage); - } - - void SetScrollPage(SIZE sizeLogPage) - { - SetScrollPage(sizeLogPage.cx, sizeLogPage.cy); - } - - void GetScrollPage(SIZE& sizeLogPage) const - { - sizeLogPage = m_sizeLogPage; - } - - void SetZoomScale(float fZoomScale) - { - ATLASSERT(fZoomScale > 0); - - if(fZoomScale > 0 && fZoomScale >= m_fZoomScaleMin) - m_fZoomScale = fZoomScale; - } - - float GetZoomScale() const - { - return m_fZoomScale; - } - - void SetZoomScaleMin(float fZoomScaleMin) - { - m_fZoomScaleMin = fZoomScaleMin; - } - - float GetZoomScaleMin() const - { - return m_fZoomScaleMin; - } - - void SetZoomDelta(float fZoomDelta) - { - ATLASSERT(fZoomDelta >= 0); - - if(fZoomDelta >= 0) - m_fZoomDelta = fZoomDelta; - } - - float GetZoomDelta() const - { - return m_fZoomDelta; - } - - void SetZoomMode(int nZoomMode) - { - m_nZoomMode = nZoomMode; - } - - int GetZoomMode() const - { - return m_nZoomMode; - } - - void Zoom(int x, int y, float fZoomScale) - { - if(fZoomScale <= 0) - return; - - fZoomScale = max(fZoomScale, m_fZoomScaleMin); - - T* pT = static_cast(this); - POINT pt = { x, y }; - if(!pT->PtInDevRect(pt)) - return; - - pT->ViewDPtoLP(&pt); - pT->Zoom(fZoomScale, false); - pT->CenterOnLogicalPoint(pt); - } - - void Zoom(POINT pt, float fZoomScale) - { - T* pT = static_cast(this); - pT->Zoom(pt.x, pt.y, fZoomScale); - } - - void Zoom(RECT& rc) - { - T* pT = static_cast(this); - RECT rcZoom = rc; - pT->NormalizeRect(rcZoom); - SIZE size = { rcZoom.right - rcZoom.left, rcZoom.bottom - rcZoom.top }; - POINT pt = { rcZoom.left + size.cx / 2, rcZoom.top + size.cy / 2 }; - if(size.cx < m_cxyMinZoomRect || size.cy < m_cxyMinZoomRect) - { - pT->Zoom(pt, m_fZoomScale + m_fZoomDelta); - return; - } - - ATLASSERT(size.cx > 0 && size.cy > 0); - - float fScaleH = (float)(m_sizeClient.cx + 1) / (float)size.cx; - float fScaleV = (float)(m_sizeClient.cy + 1) / (float)size.cy; - float fZoomScale = min(fScaleH, fScaleV) * m_fZoomScale; - pT->Zoom(pt, fZoomScale); - } - - void Zoom(float fZoomScale, bool bCenter = true) - { - if(fZoomScale <= 0) - return; - - fZoomScale = max(fZoomScale, m_fZoomScaleMin); - - - T* pT = static_cast(this); - POINT pt = { 0 }; - if(bCenter) - { - RECT rc; - ::GetClientRect(pT->m_hWnd, &rc); - pt.x = rc.right / 2; - pt.y = rc.bottom / 2; - pT->ViewDPtoLP(&pt); - } - - // Modify the Viewport extent - m_fZoomScale = fZoomScale; - SIZE sizeAll = { 0 }; - sizeAll.cx = (int)((float)m_sizeLogAll.cx * fZoomScale); - sizeAll.cy = (int)((float)m_sizeLogAll.cy * fZoomScale); - - // Update scroll bars and window - CScrollImpl< T >::SetScrollSize(sizeAll); - - if(bCenter) - pT->CenterOnLogicalPoint(pt); - } - - // Helper functions - void PrepareDC(CDCHandle dc) - { - ATLASSERT(m_sizeAll.cx >= 0 && m_sizeAll.cy >= 0); - dc.SetMapMode(MM_ANISOTROPIC); - dc.SetWindowExt(m_sizeLogAll); - dc.SetViewportExt(m_sizeAll); - dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y); - } - - void ViewDPtoLP(LPPOINT lpPoints, int nCount = 1) - { - ATLASSERT(lpPoints); - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - - CWindowDC dc(pT->m_hWnd); - pT->PrepareDC(dc.m_hDC); - dc.DPtoLP(lpPoints, nCount); - } - - void ViewLPtoDP(LPPOINT lpPoints, int nCount = 1) - { - ATLASSERT(lpPoints); - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - - CWindowDC dc(pT->m_hWnd); - pT->PrepareDC(dc.m_hDC); - dc.LPtoDP(lpPoints, nCount); - } - - void ClientToDevice(POINT &pt) - { - pt.x += m_ptOffset.x; - pt.y += m_ptOffset.y; - } - - void DeviceToClient(POINT &pt) - { - pt.x -= m_ptOffset.x; - pt.y -= m_ptOffset.y; - } - - void CenterOnPoint(POINT pt) - { - T* pT = static_cast(this); - RECT rect; - pT->GetClientRect(&rect); - - int xOfs = pt.x - (rect.right / 2) + m_ptOffset.x; - if(xOfs < 0) - { - xOfs = 0; - } - else - { - int xMax = max((int)(m_sizeAll.cx - rect.right), 0); - if(xOfs > xMax) - xOfs = xMax; - } - - int yOfs = pt.y - (rect.bottom / 2) + m_ptOffset.y; - if(yOfs < 0) - { - yOfs = 0; - } - else - { - int yMax = max((int)(m_sizeAll.cy - rect.bottom), 0); - if(yOfs > yMax) - yOfs = yMax; - } - - CScrollImpl< T >::SetScrollOffset(xOfs, yOfs); - } - - void CenterOnLogicalPoint(POINT ptLog) - { - T* pT = static_cast(this); - pT->ViewLPtoDP(&ptLog); - pT->DeviceToClient(ptLog); - pT->CenterOnPoint(ptLog); - } - - BOOL PtInDevRect(POINT pt) - { - RECT rc = { 0, 0, m_sizeAll.cx, m_sizeAll.cy }; - ::OffsetRect(&rc, -m_ptOffset.x, -m_ptOffset.y); - return ::PtInRect(&rc, pt); - } - - void NormalizeRect(RECT& rc) - { - if(rc.left > rc.right) - { - int r = rc.right; - rc.right = rc.left; - rc.left = r; - } - if(rc.top > rc.bottom) - { - int b = rc.bottom; - rc.bottom = rc.top; - rc.top = b; - } - } - - void DrawTrackRect() - { - T* pT = static_cast(this); - const SIZE sizeLines = { 2, 2 }; - RECT rc = m_rcTrack; - pT->NormalizeRect(rc); - if(!::IsRectEmpty(&rc)) - { - ::MapWindowPoints(pT->m_hWnd, NULL, (LPPOINT)&rc, 2); - CWindowDC dc(NULL); - dc.DrawDragRect(&rc, sizeLines, NULL, sizeLines); - } - } - - void NotifyParentZoomChanged() - { - T* pT = static_cast(this); - int nId = pT->GetDlgCtrlID(); - NMHDR nmhdr = { pT->m_hWnd, nId, ZSN_ZOOMCHANGED }; - ::SendMessage(pT->GetParent(), WM_NOTIFY, (WPARAM)nId, (LPARAM)&nmhdr); - } - - BEGIN_MSG_MAP(CZoomScrollImpl) - MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor) - MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll) - MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll) - MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel) -#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) - MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel) -#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) - MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel) - MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange) - MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize) - MESSAGE_HANDLER(WM_PAINT, OnPaint) - MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) - MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) - MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) - MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) - MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged) - ALT_MSG_MAP(1) - COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp) - COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown) - COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop) - COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom) - COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft) - COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight) - COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft) - COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight) - END_MSG_MAP() - - LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - ATLASSERT(m_sizeLogAll.cx >= 0 && m_sizeLogAll.cy >= 0); - ATLASSERT(m_sizeAll.cx >= 0 && m_sizeAll.cy >= 0); - - if(wParam != NULL) - { - CDCHandle dc = (HDC)wParam; - int nMapModeSav = dc.GetMapMode(); - dc.SetMapMode(MM_ANISOTROPIC); - SIZE szWindowExt = { 0, 0 }; - dc.SetWindowExt(m_sizeLogAll, &szWindowExt); - SIZE szViewportExt = { 0, 0 }; - dc.SetViewportExt(m_sizeAll, &szViewportExt); - POINT ptViewportOrg = { 0, 0 }; - dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewportOrg); - - pT->DoPaint(dc); - - dc.SetMapMode(nMapModeSav); - dc.SetWindowExt(szWindowExt); - dc.SetViewportExt(szViewportExt); - dc.SetViewportOrg(ptViewportOrg); - } - else - { - CPaintDC dc(pT->m_hWnd); - pT->PrepareDC(dc.m_hDC); - pT->DoPaint(dc.m_hDC); - } - return 0; - } - - LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - if(m_nZoomMode == ZOOMMODE_IN && !m_bTracking) - { - T* pT = static_cast(this); - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - if(pT->PtInDevRect(pt)) - { - pT->SetCapture(); - m_bTracking = true; - ::SetRect(&m_rcTrack, pt.x, pt.y, pt.x, pt.y); - } - } - bHandled = FALSE; - return 0; - } - - LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - if(m_bTracking) - { - T* pT = static_cast(this); - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - if(pT->PtInDevRect(pt)) - { - pT->DrawTrackRect(); - m_rcTrack.right = pt.x; - m_rcTrack.bottom = pt.y; - pT->DrawTrackRect(); - } - } - bHandled = FALSE; - return 0; - } - - LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - ::ReleaseCapture(); - if(m_nZoomMode == ZOOMMODE_OUT) - { - T* pT = static_cast(this); - pT->Zoom(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), m_fZoomScale - m_fZoomDelta); - pT->NotifyParentZoomChanged(); - } - bHandled = FALSE; - return 0; - } - - LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - if(m_bTracking) - { - m_bTracking = false; - T* pT = static_cast(this); - pT->DrawTrackRect(); - pT->Zoom(m_rcTrack); - pT->NotifyParentZoomChanged(); - ::SetRectEmpty(&m_rcTrack); - } - bHandled = FALSE; - return 0; - } - - LRESULT OnSetCursor(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - if(LOWORD(lParam) == HTCLIENT && m_nZoomMode != ZOOMMODE_OFF) - { - T* pT = static_cast(this); - if((HWND)wParam == pT->m_hWnd) - { - DWORD dwPos = ::GetMessagePos(); - POINT pt = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos) }; - pT->ScreenToClient(&pt); - if(pT->PtInDevRect(pt)) - { - ::SetCursor(::LoadCursor(NULL, IDC_CROSS)); - return 1; - } - } - } - bHandled = FALSE; - return 0; - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// CZoomScrollWindowImpl - Implements scrolling window with zooming - -template -class ATL_NO_VTABLE CZoomScrollWindowImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CZoomScrollImpl< T > -{ -public: - BEGIN_MSG_MAP(CZoomScrollWindowImpl) - MESSAGE_HANDLER(WM_SETCURSOR, CZoomScrollImpl< T >::OnSetCursor) - MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll) - MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll) - MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel) -#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) - MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel) -#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) - MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel) - MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange) - MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize) - MESSAGE_HANDLER(WM_PAINT, CZoomScrollImpl< T >::OnPaint) - MESSAGE_HANDLER(WM_PRINTCLIENT, CZoomScrollImpl< T >::OnPaint) - MESSAGE_HANDLER(WM_LBUTTONDOWN, CZoomScrollImpl< T >::OnLButtonDown) - MESSAGE_HANDLER(WM_MOUSEMOVE, CZoomScrollImpl< T >::OnMouseMove) - MESSAGE_HANDLER(WM_LBUTTONUP, CZoomScrollImpl< T >::OnLButtonUp) - MESSAGE_HANDLER(WM_CAPTURECHANGED, CZoomScrollImpl< T >::OnCaptureChanged) - ALT_MSG_MAP(1) - COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp) - COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown) - COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop) - COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom) - COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft) - COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft) - COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight) - COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft) - COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight) - END_MSG_MAP() -}; - -#endif // !_WIN32_WCE - - -/////////////////////////////////////////////////////////////////////////////// -// CScrollContainer - -template -class ATL_NO_VTABLE CScrollContainerImpl : public CScrollWindowImpl< T, TBase, TWinTraits > -{ -public: - DECLARE_WND_CLASS_EX(NULL, 0, -1) - - typedef CScrollWindowImpl< T, TBase, TWinTraits > _baseClass; - -// Data members - ATL::CWindow m_wndClient; - bool m_bAutoSizeClient; - bool m_bDrawEdgeIfEmpty; - -// Constructor - CScrollContainerImpl() : m_bAutoSizeClient(true), m_bDrawEdgeIfEmpty(false) - { - // Set CScrollWindowImpl extended style - SetScrollExtendedStyle(SCRL_SCROLLCHILDREN); - } - -// Attributes - HWND GetClient() const - { - return m_wndClient; - } - - HWND SetClient(HWND hWndClient, bool bClientSizeAsMin = true) - { - ATLASSERT(::IsWindow(m_hWnd)); - - HWND hWndOldClient = m_wndClient; - m_wndClient = hWndClient; - - SetRedraw(FALSE); - SetScrollSize(1, 1, FALSE); - - if(m_wndClient.m_hWnd != NULL) - { - m_wndClient.SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE); - - if(bClientSizeAsMin) - { - RECT rect = { 0 }; - m_wndClient.GetWindowRect(&rect); - if((rect.right - rect.left) > 0 && (rect.bottom - rect.top) > 0) - SetScrollSize(rect.right - rect.left, rect.bottom - rect.top, FALSE); - } - - T* pT = static_cast(this); - pT->UpdateLayout(); - } - - SetRedraw(TRUE); - RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN); - - return hWndOldClient; - } - -// Message map and handlers - BEGIN_MSG_MAP(CScrollContainerImpl) - MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) - MESSAGE_HANDLER(WM_SIZE, OnSize) - CHAIN_MSG_MAP(_baseClass) - FORWARD_NOTIFICATIONS() - ALT_MSG_MAP(1) - CHAIN_MSG_MAP_ALT(_baseClass, 1) - END_MSG_MAP() - - LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - if(m_wndClient.m_hWnd != NULL) - m_wndClient.SetFocus(); - - return 0; - } - - LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - return 1; // no background needed - } - - LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - BOOL bTmp = TRUE; - LRESULT lRet = _baseClass::OnSize(uMsg, wParam, lParam, bTmp); - - T* pT = static_cast(this); - pT->UpdateLayout(); - - return lRet; - } - -// Overrides for CScrollWindowImpl - void DoPaint(CDCHandle dc) - { - if(!m_bAutoSizeClient || m_wndClient.m_hWnd == NULL) - { - T* pT = static_cast(this); - RECT rect = { 0 }; - pT->GetContainerRect(rect); - - if(m_bDrawEdgeIfEmpty && m_wndClient.m_hWnd == NULL) - dc.DrawEdge(&rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); - - dc.FillRect(&rect, COLOR_APPWORKSPACE); - } - } - - void ScrollToView(POINT pt) - { - CScrollWindowImpl< T, TBase, TWinTraits >::ScrollToView(pt); - } - - void ScrollToView(RECT& rect) - { - CScrollWindowImpl< T, TBase, TWinTraits >::ScrollToView(rect); - } - - void ScrollToView(HWND hWnd) // client window coordinates - { - T* pT = static_cast(this); - pT; // avoid level 4 warning - ATLASSERT(::IsWindow(pT->m_hWnd)); - ATLASSERT(m_wndClient.IsWindow()); - - RECT rect = { 0 }; - ::GetWindowRect(hWnd, &rect); - ::MapWindowPoints(NULL, m_wndClient.m_hWnd, (LPPOINT)&rect, 2); - ScrollToView(rect); - } - -// Implementation - overrideable methods - void UpdateLayout() - { - ATLASSERT(::IsWindow(m_hWnd)); - - if(m_bAutoSizeClient && m_wndClient.m_hWnd != NULL) - { - T* pT = static_cast(this); - RECT rect = { 0 }; - pT->GetContainerRect(rect); - - m_wndClient.SetWindowPos(NULL, &rect, SWP_NOZORDER | SWP_NOMOVE); - } - else - { - Invalidate(); - } - } - - void GetContainerRect(RECT& rect) - { - GetClientRect(&rect); - - if(rect.right < m_sizeAll.cx) - rect.right = m_sizeAll.cx; - - if(rect.bottom < m_sizeAll.cy) - rect.bottom = m_sizeAll.cy; - } -}; - -class CScrollContainer : public CScrollContainerImpl -{ -public: - DECLARE_WND_CLASS_EX(_T("WTL_ScrollContainer"), 0, -1) -}; - -}; // namespace WTL - -#endif // __ATLSCRL_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlsplit.h b/!NotAdopted/SmartAutoReplier/wtl/atlsplit.h deleted file mode 100644 index f94fa099e9..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlsplit.h +++ /dev/null @@ -1,917 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLSPLIT_H__ -#define __ATLSPLIT_H__ - -#pragma once - -#ifndef __ATLAPP_H__ - #error atlsplit.h requires atlapp.h to be included first -#endif - -#ifndef __ATLWIN_H__ - #error atlsplit.h requires atlwin.h to be included first -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CSplitterImpl -// CSplitterWindowImpl -// CSplitterWindowT - - -namespace WTL -{ - -/////////////////////////////////////////////////////////////////////////////// -// CSplitterImpl - Provides splitter support to any window - -// Splitter panes constants -#define SPLIT_PANE_LEFT 0 -#define SPLIT_PANE_RIGHT 1 -#define SPLIT_PANE_TOP SPLIT_PANE_LEFT -#define SPLIT_PANE_BOTTOM SPLIT_PANE_RIGHT -#define SPLIT_PANE_NONE -1 - -// Splitter extended styles -#define SPLIT_PROPORTIONAL 0x00000001 -#define SPLIT_NONINTERACTIVE 0x00000002 -#define SPLIT_RIGHTALIGNED 0x00000004 -#define SPLIT_BOTTOMALIGNED SPLIT_RIGHTALIGNED -#define SPLIT_GRADIENTBAR 0x00000008 -#define SPLIT_FIXEDBARSIZE 0x00000010 - -// Note: SPLIT_PROPORTIONAL and SPLIT_RIGHTALIGNED/SPLIT_BOTTOMALIGNED are -// mutually exclusive. If both are set, splitter defaults to SPLIT_PROPORTIONAL - - -template -class CSplitterImpl -{ -public: - enum { m_nPanesCount = 2, m_nPropMax = 10000 }; - - HWND m_hWndPane[m_nPanesCount]; - RECT m_rcSplitter; - int m_xySplitterPos; - int m_nDefActivePane; - int m_cxySplitBar; // splitter bar width/height - static HCURSOR m_hCursor; - int m_cxyMin; // minimum pane size - int m_cxyBarEdge; // splitter bar edge - bool m_bFullDrag; - int m_cxyDragOffset; - int m_nProportionalPos; - bool m_bUpdateProportionalPos; - DWORD m_dwExtendedStyle; // splitter specific extended styles - int m_nSinglePane; // single pane mode - -// Constructor - CSplitterImpl() : - m_xySplitterPos(-1), m_nDefActivePane(SPLIT_PANE_NONE), - m_cxySplitBar(4), m_cxyMin(0), m_cxyBarEdge(0), m_bFullDrag(true), - m_cxyDragOffset(0), m_nProportionalPos(0), m_bUpdateProportionalPos(true), - m_dwExtendedStyle(SPLIT_PROPORTIONAL), - m_nSinglePane(SPLIT_PANE_NONE) - { - m_hWndPane[SPLIT_PANE_LEFT] = NULL; - m_hWndPane[SPLIT_PANE_RIGHT] = NULL; - - ::SetRectEmpty(&m_rcSplitter); - - if(m_hCursor == NULL) - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CSplitterImpl::CSplitterImpl.\n")); - ATLASSERT(FALSE); - return; - } - - if(m_hCursor == NULL) - m_hCursor = ::LoadCursor(NULL, t_bVertical ? IDC_SIZEWE : IDC_SIZENS); - - lock.Unlock(); - } - } - -// Attributes - void SetSplitterRect(LPRECT lpRect = NULL, bool bUpdate = true) - { - if(lpRect == NULL) - { - T* pT = static_cast(this); - pT->GetClientRect(&m_rcSplitter); - } - else - { - m_rcSplitter = *lpRect; - } - - if(IsProportional()) - UpdateProportionalPos(); - else if(IsRightAligned()) - UpdateRightAlignPos(); - - if(bUpdate) - UpdateSplitterLayout(); - } - - void GetSplitterRect(LPRECT lpRect) const - { - ATLASSERT(lpRect != NULL); - *lpRect = m_rcSplitter; - } - - bool SetSplitterPos(int xyPos = -1, bool bUpdate = true) - { - if(xyPos == -1) // -1 == middle - { - if(t_bVertical) - xyPos = (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) / 2; - else - xyPos = (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge) / 2; - } - - // Adjust if out of valid range - int cxyMax = 0; - if(t_bVertical) - cxyMax = m_rcSplitter.right - m_rcSplitter.left; - else - cxyMax = m_rcSplitter.bottom - m_rcSplitter.top; - - if(xyPos < m_cxyMin + m_cxyBarEdge) - xyPos = m_cxyMin; - else if(xyPos > (cxyMax - m_cxySplitBar - m_cxyBarEdge - m_cxyMin)) - xyPos = cxyMax - m_cxySplitBar - m_cxyBarEdge - m_cxyMin; - - // Set new position and update if requested - bool bRet = (m_xySplitterPos != xyPos); - m_xySplitterPos = xyPos; - - if(m_bUpdateProportionalPos) - { - if(IsProportional()) - StoreProportionalPos(); - else if(IsRightAligned()) - StoreRightAlignPos(); - } - else - { - m_bUpdateProportionalPos = true; - } - - if(bUpdate && bRet) - UpdateSplitterLayout(); - - return bRet; - } - - void SetSplitterPosPct(int nPct, bool bUpdate = true) - { - ATLASSERT(nPct >= 0 && nPct <= 100); - - m_nProportionalPos = ::MulDiv(nPct, m_nPropMax, 100); - UpdateProportionalPos(); - - if(bUpdate) - UpdateSplitterLayout(); - } - - int GetSplitterPos() const - { - return m_xySplitterPos; - } - - bool SetSinglePaneMode(int nPane = SPLIT_PANE_NONE) - { - ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT || nPane == SPLIT_PANE_NONE); - if(!(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT || nPane == SPLIT_PANE_NONE)) - return false; - - if(nPane != SPLIT_PANE_NONE) - { - if(!::IsWindowVisible(m_hWndPane[nPane])) - ::ShowWindow(m_hWndPane[nPane], SW_SHOW); - int nOtherPane = (nPane == SPLIT_PANE_LEFT) ? SPLIT_PANE_RIGHT : SPLIT_PANE_LEFT; - ::ShowWindow(m_hWndPane[nOtherPane], SW_HIDE); - if(m_nDefActivePane != nPane) - m_nDefActivePane = nPane; - } - else if(m_nSinglePane != SPLIT_PANE_NONE) - { - int nOtherPane = (m_nSinglePane == SPLIT_PANE_LEFT) ? SPLIT_PANE_RIGHT : SPLIT_PANE_LEFT; - ::ShowWindow(m_hWndPane[nOtherPane], SW_SHOW); - } - - m_nSinglePane = nPane; - UpdateSplitterLayout(); - return true; - } - - int GetSinglePaneMode() const - { - return m_nSinglePane; - } - - DWORD GetSplitterExtendedStyle() const - { - return m_dwExtendedStyle; - } - - DWORD SetSplitterExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) - { - DWORD dwPrevStyle = m_dwExtendedStyle; - if(dwMask == 0) - m_dwExtendedStyle = dwExtendedStyle; - else - m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); -#ifdef _DEBUG - if(IsProportional() && IsRightAligned()) - ATLTRACE2(atlTraceUI, 0, _T("CSplitterImpl::SetSplitterExtendedStyle - SPLIT_PROPORTIONAL and SPLIT_RIGHTALIGNED are mutually exclusive, defaulting to SPLIT_PROPORTIONAL.\n")); -#endif // _DEBUG - return dwPrevStyle; - } - -// Splitter operations - void SetSplitterPanes(HWND hWndLeftTop, HWND hWndRightBottom, bool bUpdate = true) - { - m_hWndPane[SPLIT_PANE_LEFT] = hWndLeftTop; - m_hWndPane[SPLIT_PANE_RIGHT] = hWndRightBottom; - ATLASSERT(m_hWndPane[SPLIT_PANE_LEFT] == NULL || m_hWndPane[SPLIT_PANE_RIGHT] == NULL || m_hWndPane[SPLIT_PANE_LEFT] != m_hWndPane[SPLIT_PANE_RIGHT]); - if(bUpdate) - UpdateSplitterLayout(); - } - - bool SetSplitterPane(int nPane, HWND hWnd, bool bUpdate = true) - { - ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT); - - if(nPane != SPLIT_PANE_LEFT && nPane != SPLIT_PANE_RIGHT) - return false; - m_hWndPane[nPane] = hWnd; - ATLASSERT(m_hWndPane[SPLIT_PANE_LEFT] == NULL || m_hWndPane[SPLIT_PANE_RIGHT] == NULL || m_hWndPane[SPLIT_PANE_LEFT] != m_hWndPane[SPLIT_PANE_RIGHT]); - if(bUpdate) - UpdateSplitterLayout(); - return true; - } - - HWND GetSplitterPane(int nPane) const - { - ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT); - - if(nPane != SPLIT_PANE_LEFT && nPane != SPLIT_PANE_RIGHT) - return false; - return m_hWndPane[nPane]; - } - - bool SetActivePane(int nPane) - { - ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT); - - if(nPane != SPLIT_PANE_LEFT && nPane != SPLIT_PANE_RIGHT) - return false; - if(m_nSinglePane != SPLIT_PANE_NONE && nPane != m_nSinglePane) - return false; - ::SetFocus(m_hWndPane[nPane]); - m_nDefActivePane = nPane; - return true; - } - - int GetActivePane() const - { - int nRet = SPLIT_PANE_NONE; - HWND hWndFocus = ::GetFocus(); - if(hWndFocus != NULL) - { - for(int nPane = 0; nPane < m_nPanesCount; nPane++) - { - if(hWndFocus == m_hWndPane[nPane] || ::IsChild(m_hWndPane[nPane], hWndFocus)) - { - nRet = nPane; - break; - } - } - } - return nRet; - } - - bool ActivateNextPane(bool bNext = true) - { - int nPane = m_nSinglePane; - if(nPane == SPLIT_PANE_NONE) - { - switch(GetActivePane()) - { - case SPLIT_PANE_LEFT: - nPane = SPLIT_PANE_RIGHT; - break; - case SPLIT_PANE_RIGHT: - nPane = SPLIT_PANE_LEFT; - break; - default: - nPane = bNext ? SPLIT_PANE_LEFT : SPLIT_PANE_RIGHT; - break; - } - } - return SetActivePane(nPane); - } - - bool SetDefaultActivePane(int nPane) - { - ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT); - - if(nPane != SPLIT_PANE_LEFT && nPane != SPLIT_PANE_RIGHT) - return false; - m_nDefActivePane = nPane; - return true; - } - - bool SetDefaultActivePane(HWND hWnd) - { - for(int nPane = 0; nPane < m_nPanesCount; nPane++) - { - if(hWnd == m_hWndPane[nPane]) - { - m_nDefActivePane = nPane; - return true; - } - } - return false; // not found - } - - int GetDefaultActivePane() const - { - return m_nDefActivePane; - } - - void DrawSplitter(CDCHandle dc) - { - ATLASSERT(dc.m_hDC != NULL); - if(m_nSinglePane == SPLIT_PANE_NONE && m_xySplitterPos == -1) - return; - - T* pT = static_cast(this); - if(m_nSinglePane == SPLIT_PANE_NONE) - { - pT->DrawSplitterBar(dc); - - for(int nPane = 0; nPane < m_nPanesCount; nPane++) - { - if(m_hWndPane[nPane] == NULL) - pT->DrawSplitterPane(dc, nPane); - } - } - else - { - if(m_hWndPane[m_nSinglePane] == NULL) - pT->DrawSplitterPane(dc, m_nSinglePane); - } - } - -// Overrideables - void DrawSplitterBar(CDCHandle dc) - { - RECT rect = { 0 }; - if(GetSplitterBarRect(&rect)) - { - dc.FillRect(&rect, COLOR_3DFACE); - -#if (!defined(_WIN32_WCE) || (_WIN32_WCE >= 420)) - if((m_dwExtendedStyle & SPLIT_GRADIENTBAR) != 0) - { - RECT rect2 = rect; - if(t_bVertical) - rect2.left = (rect.left + rect.right) / 2 - 1; - else - rect2.top = (rect.top + rect.bottom) / 2 - 1; - - dc.GradientFillRect(rect2, ::GetSysColor(COLOR_3DFACE), ::GetSysColor(COLOR_3DSHADOW), t_bVertical); - } -#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 420) - - // draw 3D edge if needed - T* pT = static_cast(this); - if((pT->GetExStyle() & WS_EX_CLIENTEDGE) != 0) - dc.DrawEdge(&rect, EDGE_RAISED, t_bVertical ? (BF_LEFT | BF_RIGHT) : (BF_TOP | BF_BOTTOM)); - } - } - - // called only if pane is empty - void DrawSplitterPane(CDCHandle dc, int nPane) - { - RECT rect = { 0 }; - if(GetSplitterPaneRect(nPane, &rect)) - { - T* pT = static_cast(this); - if((pT->GetExStyle() & WS_EX_CLIENTEDGE) == 0) - dc.DrawEdge(&rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); - dc.FillRect(&rect, COLOR_APPWORKSPACE); - } - } - -// Message map and handlers - BEGIN_MSG_MAP(CSplitterImpl) - MESSAGE_HANDLER(WM_CREATE, OnCreate) - MESSAGE_HANDLER(WM_PAINT, OnPaint) -#ifndef _WIN32_WCE - MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) -#endif // !_WIN32_WCE - if(IsInteractive()) - { - MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor) - MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) - MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) - MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) - MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDoubleClick) - MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged) - } - MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) -#ifndef _WIN32_WCE - MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate) -#endif // !_WIN32_WCE - MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) - END_MSG_MAP() - - LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - T* pT = static_cast(this); - pT->GetSystemSettings(false); - - bHandled = FALSE; - return 1; - } - - LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - // try setting position if not set - if(m_nSinglePane == SPLIT_PANE_NONE && m_xySplitterPos == -1) - pT->SetSplitterPos(); - // do painting - CPaintDC dc(pT->m_hWnd); - pT->DrawSplitter(dc.m_hDC); - return 0; - } - - LRESULT OnSetCursor(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - T* pT = static_cast(this); - if((HWND)wParam == pT->m_hWnd && LOWORD(lParam) == HTCLIENT) - { - DWORD dwPos = ::GetMessagePos(); - POINT ptPos = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos) }; - pT->ScreenToClient(&ptPos); - if(IsOverSplitterBar(ptPos.x, ptPos.y)) - return 1; - } - - bHandled = FALSE; - return 0; - } - - LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - T* pT = static_cast(this); - int xPos = GET_X_LPARAM(lParam); - int yPos = GET_Y_LPARAM(lParam); - if((wParam & MK_LBUTTON) && ::GetCapture() == pT->m_hWnd) - { - int xyNewSplitPos = 0; - if(t_bVertical) - xyNewSplitPos = xPos - m_rcSplitter.left - m_cxyDragOffset; - else - xyNewSplitPos = yPos - m_rcSplitter.top - m_cxyDragOffset; - - if(xyNewSplitPos == -1) // avoid -1, that means middle - xyNewSplitPos = -2; - - if(m_xySplitterPos != xyNewSplitPos) - { - if(m_bFullDrag) - { - if(pT->SetSplitterPos(xyNewSplitPos, true)) - pT->UpdateWindow(); - } - else - { - DrawGhostBar(); - pT->SetSplitterPos(xyNewSplitPos, false); - DrawGhostBar(); - } - } - } - else // not dragging, just set cursor - { - if(IsOverSplitterBar(xPos, yPos)) - ::SetCursor(m_hCursor); - bHandled = FALSE; - } - - return 0; - } - - LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) - { - int xPos = GET_X_LPARAM(lParam); - int yPos = GET_Y_LPARAM(lParam); - if(IsOverSplitterBar(xPos, yPos)) - { - T* pT = static_cast(this); - pT->SetCapture(); - ::SetCursor(m_hCursor); - if(!m_bFullDrag) - DrawGhostBar(); - if(t_bVertical) - m_cxyDragOffset = xPos - m_rcSplitter.left - m_xySplitterPos; - else - m_cxyDragOffset = yPos - m_rcSplitter.top - m_xySplitterPos; - } - bHandled = FALSE; - return 1; - } - - LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - ::ReleaseCapture(); - bHandled = FALSE; - return 1; - } - - LRESULT OnLButtonDoubleClick(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->SetSplitterPos(); // middle - return 0; - } - - LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - if(!m_bFullDrag) - { - DrawGhostBar(); - UpdateSplitterLayout(); - T* pT = static_cast(this); - pT->UpdateWindow(); - } - return 0; - } - - LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM, BOOL& bHandled) - { - if(m_nSinglePane == SPLIT_PANE_NONE) - { - if(m_nDefActivePane == SPLIT_PANE_LEFT || m_nDefActivePane == SPLIT_PANE_RIGHT) - ::SetFocus(m_hWndPane[m_nDefActivePane]); - } - else - { - ::SetFocus(m_hWndPane[m_nSinglePane]); - } - bHandled = FALSE; - return 1; - } - -#ifndef _WIN32_WCE - LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - LRESULT lRet = pT->DefWindowProc(uMsg, wParam, lParam); - if(lRet == MA_ACTIVATE || lRet == MA_ACTIVATEANDEAT) - { - DWORD dwPos = ::GetMessagePos(); - POINT pt = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos) }; - pT->ScreenToClient(&pt); - RECT rcPane = { 0 }; - for(int nPane = 0; nPane < m_nPanesCount; nPane++) - { - if(GetSplitterPaneRect(nPane, &rcPane) && ::PtInRect(&rcPane, pt)) - { - m_nDefActivePane = nPane; - break; - } - } - } - return lRet; - } -#endif // !_WIN32_WCE - - LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->GetSystemSettings(true); - - return 0; - } - -// Implementation - internal helpers - void UpdateSplitterLayout() - { - if(m_nSinglePane == SPLIT_PANE_NONE && m_xySplitterPos == -1) - return; - - T* pT = static_cast(this); - RECT rect = { 0 }; - if(m_nSinglePane == SPLIT_PANE_NONE) - { - if(GetSplitterBarRect(&rect)) - pT->InvalidateRect(&rect); - - for(int nPane = 0; nPane < m_nPanesCount; nPane++) - { - if(GetSplitterPaneRect(nPane, &rect)) - { - if(m_hWndPane[nPane] != NULL) - ::SetWindowPos(m_hWndPane[nPane], NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER); - else - pT->InvalidateRect(&rect); - } - } - } - else - { - if(GetSplitterPaneRect(m_nSinglePane, &rect)) - { - if(m_hWndPane[m_nSinglePane] != NULL) - ::SetWindowPos(m_hWndPane[m_nSinglePane], NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER); - else - pT->InvalidateRect(&rect); - } - } - } - - bool GetSplitterBarRect(LPRECT lpRect) const - { - ATLASSERT(lpRect != NULL); - if(m_nSinglePane != SPLIT_PANE_NONE || m_xySplitterPos == -1) - return false; - - if(t_bVertical) - { - lpRect->left = m_rcSplitter.left + m_xySplitterPos; - lpRect->top = m_rcSplitter.top; - lpRect->right = m_rcSplitter.left + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge; - lpRect->bottom = m_rcSplitter.bottom; - } - else - { - lpRect->left = m_rcSplitter.left; - lpRect->top = m_rcSplitter.top + m_xySplitterPos; - lpRect->right = m_rcSplitter.right; - lpRect->bottom = m_rcSplitter.top + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge; - } - - return true; - } - - bool GetSplitterPaneRect(int nPane, LPRECT lpRect) const - { - ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT); - ATLASSERT(lpRect != NULL); - bool bRet = true; - if(m_nSinglePane != SPLIT_PANE_NONE) - { - if(nPane == m_nSinglePane) - *lpRect = m_rcSplitter; - else - bRet = false; - } - else if(nPane == SPLIT_PANE_LEFT) - { - if(t_bVertical) - { - lpRect->left = m_rcSplitter.left; - lpRect->top = m_rcSplitter.top; - lpRect->right = m_rcSplitter.left + m_xySplitterPos; - lpRect->bottom = m_rcSplitter.bottom; - } - else - { - lpRect->left = m_rcSplitter.left; - lpRect->top = m_rcSplitter.top; - lpRect->right = m_rcSplitter.right; - lpRect->bottom = m_rcSplitter.top + m_xySplitterPos; - } - } - else if(nPane == SPLIT_PANE_RIGHT) - { - if(t_bVertical) - { - lpRect->left = m_rcSplitter.left + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge; - lpRect->top = m_rcSplitter.top; - lpRect->right = m_rcSplitter.right; - lpRect->bottom = m_rcSplitter.bottom; - } - else - { - lpRect->left = m_rcSplitter.left; - lpRect->top = m_rcSplitter.top + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge; - lpRect->right = m_rcSplitter.right; - lpRect->bottom = m_rcSplitter.bottom; - } - } - else - { - bRet = false; - } - return bRet; - } - - bool IsOverSplitterRect(int x, int y) const - { - // -1 == don't check - return ((x == -1 || (x >= m_rcSplitter.left && x <= m_rcSplitter.right)) && - (y == -1 || (y >= m_rcSplitter.top && y <= m_rcSplitter.bottom))); - } - - bool IsOverSplitterBar(int x, int y) const - { - if(m_nSinglePane != SPLIT_PANE_NONE) - return false; - if(m_xySplitterPos == -1 || !IsOverSplitterRect(x, y)) - return false; - int xy = t_bVertical ? x : y; - int xyOff = t_bVertical ? m_rcSplitter.left : m_rcSplitter.top; - return ((xy >= (xyOff + m_xySplitterPos)) && (xy < xyOff + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge)); - } - - void DrawGhostBar() - { - RECT rect = { 0 }; - if(GetSplitterBarRect(&rect)) - { - // convert client to window coordinates - T* pT = static_cast(this); - RECT rcWnd = { 0 }; - pT->GetWindowRect(&rcWnd); - ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rcWnd, 2); - ::OffsetRect(&rect, -rcWnd.left, -rcWnd.top); - - // invert the brush pattern (looks just like frame window sizing) - CWindowDC dc(pT->m_hWnd); - CBrush brush = CDCHandle::GetHalftoneBrush(); - if(brush.m_hBrush != NULL) - { - CBrushHandle brushOld = dc.SelectBrush(brush); - dc.PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT); - dc.SelectBrush(brushOld); - } - } - } - - void GetSystemSettings(bool bUpdate) - { - if((m_dwExtendedStyle & SPLIT_FIXEDBARSIZE) == 0) - { -#ifndef _WIN32_WCE - m_cxySplitBar = ::GetSystemMetrics(t_bVertical ? SM_CXSIZEFRAME : SM_CYSIZEFRAME); -#else // CE specific - m_cxySplitBar = 2 * ::GetSystemMetrics(t_bVertical ? SM_CXEDGE : SM_CYEDGE); -#endif // _WIN32_WCE - } - - T* pT = static_cast(this); - if((pT->GetExStyle() & WS_EX_CLIENTEDGE)) - { - m_cxyBarEdge = 2 * ::GetSystemMetrics(t_bVertical ? SM_CXEDGE : SM_CYEDGE); - m_cxyMin = 0; - } - else - { - m_cxyBarEdge = 0; - m_cxyMin = 2 * ::GetSystemMetrics(t_bVertical ? SM_CXEDGE : SM_CYEDGE); - } - -#ifndef _WIN32_WCE - ::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &m_bFullDrag, 0); -#endif // !_WIN32_WCE - - if(bUpdate) - UpdateSplitterLayout(); - } - - bool IsProportional() const - { - return ((m_dwExtendedStyle & SPLIT_PROPORTIONAL) != 0); - } - - void StoreProportionalPos() - { - int cxyTotal = t_bVertical ? (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge); - if(cxyTotal > 0) - m_nProportionalPos = ::MulDiv(m_xySplitterPos, m_nPropMax, cxyTotal); - else - m_nProportionalPos = 0; - ATLTRACE2(atlTraceUI, 0, _T("CSplitterImpl::StoreProportionalPos - %i\n"), m_nProportionalPos); - } - - void UpdateProportionalPos() - { - int cxyTotal = t_bVertical ? (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge); - if(cxyTotal > 0) - { - int xyNewPos = ::MulDiv(m_nProportionalPos, cxyTotal, m_nPropMax); - m_bUpdateProportionalPos = false; - T* pT = static_cast(this); - pT->SetSplitterPos(xyNewPos, false); - } - } - - bool IsRightAligned() const - { - return ((m_dwExtendedStyle & SPLIT_RIGHTALIGNED) != 0); - } - - void StoreRightAlignPos() - { - int cxyTotal = t_bVertical ? (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge); - if(cxyTotal > 0) - m_nProportionalPos = cxyTotal - m_xySplitterPos; - else - m_nProportionalPos = 0; - ATLTRACE2(atlTraceUI, 0, _T("CSplitterImpl::StoreRightAlignPos - %i\n"), m_nProportionalPos); - } - - void UpdateRightAlignPos() - { - int cxyTotal = t_bVertical ? (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge); - if(cxyTotal > 0) - { - m_bUpdateProportionalPos = false; - T* pT = static_cast(this); - pT->SetSplitterPos(cxyTotal - m_nProportionalPos, false); - } - } - - bool IsInteractive() const - { - return ((m_dwExtendedStyle & SPLIT_NONINTERACTIVE) == 0); - } -}; - -template HCURSOR CSplitterImpl< T, t_bVertical>::m_hCursor = NULL; - - -/////////////////////////////////////////////////////////////////////////////// -// CSplitterWindowImpl - Implements a splitter window - -template -class ATL_NO_VTABLE CSplitterWindowImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CSplitterImpl< T , t_bVertical > -{ -public: - DECLARE_WND_CLASS_EX(NULL, CS_DBLCLKS, COLOR_WINDOW) - - typedef CSplitterImpl< T , t_bVertical > _baseClass; - - BEGIN_MSG_MAP(CSplitterWindowImpl) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) - MESSAGE_HANDLER(WM_SIZE, OnSize) - CHAIN_MSG_MAP(_baseClass) - FORWARD_NOTIFICATIONS() - END_MSG_MAP() - - LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - // handled, no background painting needed - return 1; - } - - LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - if(wParam != SIZE_MINIMIZED) - SetSplitterRect(); - - bHandled = FALSE; - return 1; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CSplitterWindow - Implements a splitter window to be used as is - -template -class CSplitterWindowT : public CSplitterWindowImpl, t_bVertical> -{ -public: - DECLARE_WND_CLASS_EX(_T("WTL_SplitterWindow"), CS_DBLCLKS, COLOR_WINDOW) -}; - -typedef CSplitterWindowT CSplitterWindow; -typedef CSplitterWindowT CHorSplitterWindow; - -}; // namespace WTL - -#endif // __ATLSPLIT_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atltheme.h b/!NotAdopted/SmartAutoReplier/wtl/atltheme.h deleted file mode 100644 index ff7ee59817..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atltheme.h +++ /dev/null @@ -1,1218 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLTHEME_H__ -#define __ATLTHEME_H__ - -#pragma once - -#ifdef _WIN32_WCE - #error atltheme.h is not supported on Windows CE -#endif - -#ifndef __ATLAPP_H__ - #error atltheme.h requires atlapp.h to be included first -#endif - -#ifndef __ATLWIN_H__ - #error atltheme.h requires atlwin.h to be included first -#endif - -#if (_WIN32_WINNT < 0x0501) - #error atltheme.h requires _WIN32_WINNT >= 0x0501 -#endif // (_WIN32_WINNT < 0x0501) - -#if defined(_WTL_USE_VSSYM32) || (defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)) - #include -#else - #ifndef TMSCHEMA_H - #include - #endif -#endif - -#ifndef _UXTHEME_H_ -#include -#endif -#pragma comment(lib, "uxtheme.lib") - -// Note: To create an application that also runs on older versions of Windows, -// use delay load of uxtheme.dll and ensure that no calls to the Theme API are -// made if theming is not supported. It is enough to check if m_hTheme is NULL. -// Example: -// if(m_hTheme != NULL) -// { -// DrawThemeBackground(dc, BP_PUSHBUTTON, PBS_NORMAL, &rect, NULL); -// DrawThemeText(dc, BP_PUSHBUTTON, PBS_NORMAL, L"Button", -1, DT_SINGLELINE | DT_CENTER | DT_VCENTER, 0, &rect); -// } -// else -// { -// dc.DrawFrameControl(&rect, DFC_BUTTON, DFCS_BUTTONPUSH); -// dc.DrawText(_T("Button"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); -// } -// -// Delay load is NOT AUTOMATIC for VC++ 7, you have to link to delayimp.lib, -// and add uxtheme.dll in the Linker.Input.Delay Loaded DLLs section of the -// project properties. -#if (_MSC_VER < 1300) && !defined(_WTL_NO_THEME_DELAYLOAD) - #pragma comment(lib, "delayimp.lib") - #pragma comment(linker, "/delayload:uxtheme.dll") -#endif // (_MSC_VER < 1300) && !defined(_WTL_NO_THEME_DELAYLOAD) - -// Hack: Signatures in uxtheme.h changed - the only way to check which variant of uxtheme.h -// is included is to check for presence of new defines MAX_THEMECOLOR and MAX_THEMESIZE -#ifndef _WTL_NEW_UXTHEME - #if defined(MAX_THEMECOLOR) && defined(MAX_THEMESIZE) - #define _WTL_NEW_UXTHEME - #endif // defined(MAX_THEMECOLOR) && defined(MAX_THEMESIZE) -#endif // _WTL_NEW_UXTHEME - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CTheme -// CThemeImpl -// -// CBufferedPaint -// CBufferedPaintImpl -// CBufferedPaintWindowImpl -// CBufferedAnimation -// CBufferedAnimationImpl -// CBufferedAnimationWindowImpl -// -// Global functions: -// AtlDrawThemeClientEdge() - - -namespace WTL -{ - -/////////////////////////////////////////////////////////////////////////////// -// CTheme - wrapper for theme handle - -class CTheme -{ -public: -// Data members - HTHEME m_hTheme; - static int m_nIsThemingSupported; - -// Constructor - CTheme(HTHEME hTheme = NULL) : m_hTheme(hTheme) - { - IsThemingSupported(); - } - -// Operators and helpers - bool IsThemeNull() const - { - return (m_hTheme == NULL); - } - - CTheme& operator =(HTHEME hTheme) - { - m_hTheme = hTheme; - return *this; - } - - operator HTHEME() const - { - return m_hTheme; - } - - void Attach(HTHEME hTheme) - { - m_hTheme = hTheme; - } - - HTHEME Detach() - { - HTHEME hTheme = m_hTheme; - m_hTheme = NULL; - return hTheme; - } - -// Theme support helper - static bool IsThemingSupported() - { - if(m_nIsThemingSupported == -1) - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CTheme::IsThemingSupported.\n")); - ATLASSERT(FALSE); - return false; - } - - if(m_nIsThemingSupported == -1) - { - HMODULE hThemeDLL = ::LoadLibrary(_T("uxtheme.dll")); - m_nIsThemingSupported = (hThemeDLL != NULL) ? 1 : 0; - if(hThemeDLL != NULL) - ::FreeLibrary(hThemeDLL); - } - - lock.Unlock(); - } - - ATLASSERT(m_nIsThemingSupported != -1); - return (m_nIsThemingSupported == 1); - } - -// Operations and theme properties - HTHEME OpenThemeData(HWND hWnd, LPCWSTR pszClassList) - { - if(!IsThemingSupported()) - return NULL; - - ATLASSERT(m_hTheme == NULL); - m_hTheme = ::OpenThemeData(hWnd, pszClassList); - return m_hTheme; - } - - HRESULT CloseThemeData() - { - HRESULT hRet = S_FALSE; - if(m_hTheme != NULL) - { - hRet = ::CloseThemeData(m_hTheme); - if(SUCCEEDED(hRet)) - m_hTheme = NULL; - } - return hRet; - } - - HRESULT DrawThemeBackground(HDC hDC, int nPartID, int nStateID, LPCRECT pRect, LPCRECT pClipRect = NULL) - { - ATLASSERT(m_hTheme != NULL); - return ::DrawThemeBackground(m_hTheme, hDC, nPartID, nStateID, pRect, pClipRect); - } - - HRESULT DrawThemeBackgroundEx(HDC hDC, int nPartID, int nStateID, LPCRECT pRect, const DTBGOPTS* pOptions = NULL) - { - ATLASSERT(m_hTheme != NULL); - return ::DrawThemeBackgroundEx(m_hTheme, hDC, nPartID, nStateID, pRect, pOptions); - } - - HRESULT DrawThemeText(HDC hDC, int nPartID, int nStateID, LPCWSTR pszText, int nCharCount, DWORD dwTextFlags, DWORD dwTextFlags2, LPCRECT pRect) - { - ATLASSERT(m_hTheme != NULL); - return ::DrawThemeText(m_hTheme, hDC, nPartID, nStateID, pszText, nCharCount, dwTextFlags, dwTextFlags2, pRect); - } - - HRESULT GetThemeBackgroundContentRect(HDC hDC, int nPartID, int nStateID, LPCRECT pBoundingRect, LPRECT pContentRect) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeBackgroundContentRect(m_hTheme, hDC, nPartID, nStateID, pBoundingRect, pContentRect); - } - - HRESULT GetThemeBackgroundExtent(HDC hDC, int nPartID, int nStateID, LPCRECT pContentRect, LPRECT pExtentRect) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeBackgroundExtent(m_hTheme, hDC, nPartID, nStateID, pContentRect, pExtentRect); - } - - HRESULT GetThemePartSize(HDC hDC, int nPartID, int nStateID, LPRECT pRect, enum THEMESIZE eSize, LPSIZE pSize) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemePartSize(m_hTheme, hDC, nPartID, nStateID, pRect, eSize, pSize); - } - - HRESULT GetThemeTextExtent(HDC hDC, int nPartID, int nStateID, LPCWSTR pszText, int nCharCount, DWORD dwTextFlags, LPCRECT pBoundingRect, LPRECT pExtentRect) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeTextExtent(m_hTheme, hDC, nPartID, nStateID, pszText, nCharCount, dwTextFlags, pBoundingRect, pExtentRect); - } - - HRESULT GetThemeTextMetrics(HDC hDC, int nPartID, int nStateID, PTEXTMETRICW pTextMetric) const - { - ATLASSERT(m_hTheme != NULL); -#ifdef _WTL_NEW_UXTHEME - return ::GetThemeTextMetrics(m_hTheme, hDC, nPartID, nStateID, pTextMetric); -#else // !_WTL_NEW_UXTHEME - // Note: The cast to PTEXTMETRIC is because uxtheme.h incorrectly uses it instead of PTEXTMETRICW - return ::GetThemeTextMetrics(m_hTheme, hDC, nPartID, nStateID, (PTEXTMETRIC)pTextMetric); -#endif // !_WTL_NEW_UXTHEME - } - - HRESULT GetThemeBackgroundRegion(HDC hDC, int nPartID, int nStateID, LPCRECT pRect, HRGN* pRegion) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeBackgroundRegion(m_hTheme, hDC, nPartID, nStateID, pRect, pRegion); - } - - HRESULT HitTestThemeBackground(HDC hDC, int nPartID, int nStateID, DWORD dwOptions, LPCRECT pRect, HRGN hrgn, POINT ptTest, WORD* pwHitTestCode) const - { - ATLASSERT(m_hTheme != NULL); - return ::HitTestThemeBackground(m_hTheme, hDC, nPartID, nStateID, dwOptions, pRect, hrgn, ptTest, pwHitTestCode); - } - - HRESULT DrawThemeEdge(HDC hDC, int nPartID, int nStateID, LPCRECT pDestRect, UINT uEdge, UINT uFlags, LPRECT pContentRect = NULL) - { - ATLASSERT(m_hTheme != NULL); - return ::DrawThemeEdge(m_hTheme, hDC, nPartID, nStateID, pDestRect, uEdge, uFlags, pContentRect); - } - - HRESULT DrawThemeIcon(HDC hDC, int nPartID, int nStateID, LPCRECT pRect, HIMAGELIST himl, int nImageIndex) - { - ATLASSERT(m_hTheme != NULL); - return ::DrawThemeIcon(m_hTheme, hDC, nPartID, nStateID, pRect, himl, nImageIndex); - } - - BOOL IsThemePartDefined(int nPartID, int nStateID) const - { - ATLASSERT(m_hTheme != NULL); - return ::IsThemePartDefined(m_hTheme, nPartID, nStateID); - } - - BOOL IsThemeBackgroundPartiallyTransparent(int nPartID, int nStateID) const - { - ATLASSERT(m_hTheme != NULL); - return ::IsThemeBackgroundPartiallyTransparent(m_hTheme, nPartID, nStateID); - } - - HRESULT GetThemeColor(int nPartID, int nStateID, int nPropID, COLORREF* pColor) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeColor(m_hTheme, nPartID, nStateID, nPropID, pColor); - } - - HRESULT GetThemeMetric(HDC hDC, int nPartID, int nStateID, int nPropID, int* pnVal) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeMetric(m_hTheme, hDC, nPartID, nStateID, nPropID, pnVal); - } - - HRESULT GetThemeString(int nPartID, int nStateID, int nPropID, LPWSTR pszBuff, int cchMaxBuffChars) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeString(m_hTheme, nPartID, nStateID, nPropID, pszBuff, cchMaxBuffChars); - } - - HRESULT GetThemeBool(int nPartID, int nStateID, int nPropID, BOOL* pfVal) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeBool(m_hTheme, nPartID, nStateID, nPropID, pfVal); - } - - HRESULT GetThemeInt(int nPartID, int nStateID, int nPropID, int* pnVal) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeInt(m_hTheme, nPartID, nStateID, nPropID, pnVal); - } - - HRESULT GetThemeEnumValue(int nPartID, int nStateID, int nPropID, int* pnVal) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeEnumValue(m_hTheme, nPartID, nStateID, nPropID, pnVal); - } - - HRESULT GetThemePosition(int nPartID, int nStateID, int nPropID, LPPOINT pPoint) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemePosition(m_hTheme, nPartID, nStateID, nPropID, pPoint); - } - - // deprecated - HRESULT GetThemeFont(int nPartID, HDC hDC, int nStateID, int nPropID, LOGFONTW* pFont) const - { - ATLASSERT(m_hTheme != NULL); -#ifdef _WTL_NEW_UXTHEME - return ::GetThemeFont(m_hTheme, hDC, nPartID, nStateID, nPropID, pFont); -#else // !_WTL_NEW_UXTHEME - // Note: The cast to LOGFONT* is because uxtheme.h incorrectly uses it instead of LOGFONTW* - return ::GetThemeFont(m_hTheme, hDC, nPartID, nStateID, nPropID, (LOGFONT*)pFont); -#endif // !_WTL_NEW_UXTHEME - } - - HRESULT GetThemeFont(HDC hDC, int nPartID, int nStateID, int nPropID, LOGFONTW* pFont) const - { - ATLASSERT(m_hTheme != NULL); -#ifdef _WTL_NEW_UXTHEME - return ::GetThemeFont(m_hTheme, hDC, nPartID, nStateID, nPropID, pFont); -#else // !_WTL_NEW_UXTHEME - // Note: The cast to LOGFONT* is because uxtheme.h incorrectly uses it instead of LOGFONTW* - return ::GetThemeFont(m_hTheme, hDC, nPartID, nStateID, nPropID, (LOGFONT*)pFont); -#endif // !_WTL_NEW_UXTHEME - } - - HRESULT GetThemeRect(int nPartID, int nStateID, int nPropID, LPRECT pRect) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeRect(m_hTheme, nPartID, nStateID, nPropID, pRect); - } - - HRESULT GetThemeMargins(HDC hDC, int nPartID, int nStateID, int nPropID, LPRECT pRect, PMARGINS pMargins) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeMargins(m_hTheme, hDC, nPartID, nStateID, nPropID, pRect, pMargins); - } - - HRESULT GetThemeIntList(int nPartID, int nStateID, int nPropID, INTLIST* pIntList) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeIntList(m_hTheme, nPartID, nStateID, nPropID, pIntList); - } - - HRESULT GetThemePropertyOrigin(int nPartID, int nStateID, int nPropID, enum PROPERTYORIGIN* pOrigin) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemePropertyOrigin(m_hTheme, nPartID, nStateID, nPropID, pOrigin); - } - - HRESULT GetThemeFilename(int nPartID, int nStateID, int nPropID, LPWSTR pszThemeFileName, int cchMaxBuffChars) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeFilename(m_hTheme, nPartID, nStateID, nPropID, pszThemeFileName, cchMaxBuffChars); - } - - COLORREF GetThemeSysColor(int nColorID) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeSysColor(m_hTheme, nColorID); - } - - HBRUSH GetThemeSysColorBrush(int nColorID) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeSysColorBrush(m_hTheme, nColorID); - } - - int GetThemeSysSize(int nSizeID) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeSysSize(m_hTheme, nSizeID); - } - - BOOL GetThemeSysBool(int nBoolID) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeSysBool(m_hTheme, nBoolID); - } - - HRESULT GetThemeSysFont(int nFontID, LOGFONTW* plf) const - { - ATLASSERT(m_hTheme != NULL); -#ifdef _WTL_NEW_UXTHEME - return ::GetThemeSysFont(m_hTheme, nFontID, plf); -#else // !_WTL_NEW_UXTHEME - // Note: The cast to LOGFONT* is because uxtheme.h incorrectly uses it instead of LOGFONTW* - return ::GetThemeSysFont(m_hTheme, nFontID, (LOGFONT*)plf); -#endif // !_WTL_NEW_UXTHEME - } - - HRESULT GetThemeSysString(int nStringID, LPWSTR pszStringBuff, int cchMaxStringChars) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeSysString(m_hTheme, nStringID, pszStringBuff, cchMaxStringChars); - } - - HRESULT GetThemeSysInt(int nIntID, int* pnValue) const - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeSysInt(m_hTheme, nIntID, pnValue); - } - -#ifdef _WTL_NEW_UXTHEME - HTHEME OpenThemeDataEx(HWND hWnd, LPCWSTR pszClassList, DWORD dwFlags) - { - if(!IsThemingSupported()) - return NULL; - - ATLASSERT(m_hTheme == NULL); - m_hTheme = ::OpenThemeDataEx(hWnd, pszClassList, dwFlags); - return m_hTheme; - } - - HRESULT DrawThemeTextEx(HDC hDC, int nPartID, int nStateID, LPCWSTR pszText, int cchText, DWORD dwTextFlags, LPRECT lpRect, const DTTOPTS* pOptions) - { - ATLASSERT(m_hTheme != NULL); - return ::DrawThemeTextEx(m_hTheme, hDC, nPartID, nStateID, pszText, cchText, dwTextFlags, lpRect, pOptions); - } - - HRESULT GetThemeTransitionDuration(int nPartID, int nFromStateID, int nToStateID, int nPropID, DWORD& dwDuration) - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeTransitionDuration(m_hTheme, nPartID, nFromStateID, nToStateID, nPropID, &dwDuration); - } -#endif // _WTL_NEW_UXTHEME - -#if (_WIN32_WINNT >= 0x0600) - HRESULT GetThemeBitmap(int nPartID, int nStateID, int nPropID, ULONG uFlags, HBITMAP& hBitmap) - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeBitmap(m_hTheme, nPartID, nStateID, nPropID, uFlags, &hBitmap); - } - - HRESULT GetThemeStream(int nPartID, int nStateID, int nPropID, VOID** ppvStream, DWORD* pcbStream, HINSTANCE hInstance) - { - ATLASSERT(m_hTheme != NULL); - return ::GetThemeStream(m_hTheme, nPartID, nStateID, nPropID, ppvStream, pcbStream, hInstance); - } -#endif // (_WIN32_WINNT >= 0x0600) -}; - -__declspec(selectany) int CTheme::m_nIsThemingSupported = -1; - - -/////////////////////////////////////////////////////////////////////////////// -// CThemeImpl - theme support implementation - -// Derive from this class to implement window with theme support. -// Example: -// class CMyThemeWindow : public CWindowImpl, public CThemeImpl -// { -// ... -// BEGIN_MSG_MAP(CMyThemeWindow) -// CHAIN_MSG_MAP(CThemeImpl) -// ... -// END_MSG_MAP() -// ... -// }; -// -// If you set theme class list, the class will automaticaly open/close/reopen theme data. - - -// Helper for drawing theme client edge -inline bool AtlDrawThemeClientEdge(HTHEME hTheme, HWND hWnd, HRGN hRgnUpdate = NULL, HBRUSH hBrush = NULL, int nPartID = 0, int nStateID = 0) -{ - ATLASSERT(hTheme != NULL); - ATLASSERT(::IsWindow(hWnd)); - - CWindowDC dc(hWnd); - if(dc.IsNull()) - return false; - - // Get border size - int cxBorder = GetSystemMetrics(SM_CXBORDER); - int cyBorder = GetSystemMetrics(SM_CYBORDER); - if(SUCCEEDED(::GetThemeInt(hTheme, nPartID, nStateID, TMT_SIZINGBORDERWIDTH, &cxBorder))) - cyBorder = cxBorder; - - RECT rect; - ::GetWindowRect(hWnd, &rect); - - // Remove the client edge from the update region - int cxEdge = GetSystemMetrics(SM_CXEDGE); - int cyEdge = GetSystemMetrics(SM_CYEDGE); - ::InflateRect(&rect, -cxEdge, -cyEdge); - CRgn rgn; - rgn.CreateRectRgnIndirect(&rect); - if(rgn.IsNull()) - return false; - - if(hRgnUpdate != NULL) - rgn.CombineRgn(hRgnUpdate, rgn, RGN_AND); - - ::OffsetRect(&rect, -rect.left, -rect.top); - - ::OffsetRect(&rect, cxEdge, cyEdge); - dc.ExcludeClipRect(&rect); - ::InflateRect(&rect, cxEdge, cyEdge); - - ::DrawThemeBackground(hTheme, dc, nPartID, nStateID, &rect, NULL); - - // Use background brush too, since theme border might not cover everything - if(cxBorder < cxEdge && cyBorder < cyEdge) - { - if(hBrush == NULL) -// need conditional code because types don't match in winuser.h -#ifdef _WIN64 - hBrush = (HBRUSH)::GetClassLongPtr(hWnd, GCLP_HBRBACKGROUND); -#else - hBrush = (HBRUSH)UlongToPtr(::GetClassLongPtr(hWnd, GCLP_HBRBACKGROUND)); -#endif - - ::InflateRect(&rect, cxBorder - cxEdge, cyBorder - cyEdge); - dc.FillRect(&rect, hBrush); - } - - ::DefWindowProc(hWnd, WM_NCPAINT, (WPARAM)rgn.m_hRgn, 0L); - - return true; -} - - -// Theme extended styles -#define THEME_EX_3DCLIENTEDGE 0x00000001 -#define THEME_EX_THEMECLIENTEDGE 0x00000002 - -template -class CThemeImpl : public TBase -{ -public: -// Data members - LPWSTR m_lpstrThemeClassList; - DWORD m_dwExtendedStyle; // theme specific extended styles - -// Constructor & destructor - CThemeImpl() : m_lpstrThemeClassList(NULL), m_dwExtendedStyle(0) - { } - - ~CThemeImpl() - { - delete [] m_lpstrThemeClassList; - } - -// Attributes - bool SetThemeClassList(LPCWSTR lpstrThemeClassList) - { - if(m_lpstrThemeClassList != NULL) - { - delete [] m_lpstrThemeClassList; - m_lpstrThemeClassList = NULL; - } - - if(lpstrThemeClassList == NULL) - return true; - - int cchLen = lstrlenW(lpstrThemeClassList) + 1; - ATLTRY(m_lpstrThemeClassList = new WCHAR[cchLen]); - if(m_lpstrThemeClassList == NULL) - return false; - - SecureHelper::strcpyW_x(m_lpstrThemeClassList, cchLen, lpstrThemeClassList); - - return true; - } - - bool GetThemeClassList(LPWSTR lpstrThemeClassList, int cchListBuffer) const - { - int cchLen = lstrlenW(m_lpstrThemeClassList) + 1; - if(cchListBuffer < cchLen) - return false; - - SecureHelper::strcpyW_x(lpstrThemeClassList, cchListBuffer, m_lpstrThemeClassList); - - return true; - } - - LPCWSTR GetThemeClassList() const - { - return m_lpstrThemeClassList; - } - - DWORD SetThemeExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) - { - DWORD dwPrevStyle = m_dwExtendedStyle; - if(dwMask == 0) - m_dwExtendedStyle = dwExtendedStyle; - else - m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); - return dwPrevStyle; - } - - DWORD GetThemeExtendedStyle() const - { - return m_dwExtendedStyle; - } - -// Operations - HTHEME OpenThemeData() - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - ATLASSERT(m_lpstrThemeClassList != NULL); - if(m_lpstrThemeClassList == NULL) - return NULL; - CloseThemeData(); - return TBase::OpenThemeData(pT->m_hWnd, m_lpstrThemeClassList); - } - - HTHEME OpenThemeData(LPCWSTR pszClassList) - { - if(!SetThemeClassList(pszClassList)) - return NULL; - return OpenThemeData(); - } - - HRESULT SetWindowTheme(LPCWSTR pszSubAppName, LPCWSTR pszSubIDList) - { - if(!IsThemingSupported()) - return S_FALSE; - - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::SetWindowTheme(pT->m_hWnd, pszSubAppName, pszSubIDList); - } - - HTHEME GetWindowTheme() const - { - if(!IsThemingSupported()) - return NULL; - - const T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::GetWindowTheme(pT->m_hWnd); - } - - HRESULT EnableThemeDialogTexture(DWORD dwFlags) - { - if(!IsThemingSupported()) - return S_FALSE; - - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::EnableThemeDialogTexture(pT->m_hWnd, dwFlags); - } - - BOOL IsThemeDialogTextureEnabled() const - { - if(!IsThemingSupported()) - return FALSE; - - const T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::IsThemeDialogTextureEnabled(pT->m_hWnd); - } - - HRESULT DrawThemeParentBackground(HDC hDC, const RECT* pRect = NULL) - { - if(!IsThemingSupported()) - return S_FALSE; - - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); -#ifdef _WTL_NEW_UXTHEME - return ::DrawThemeParentBackground(pT->m_hWnd, hDC, pRect); -#else - return ::DrawThemeParentBackground(pT->m_hWnd, hDC, (RECT*)pRect); -#endif - } - -#ifdef _WTL_NEW_UXTHEME - HRESULT SetWindowThemeAttribute(WINDOWTHEMEATTRIBUTETYPE type, PVOID pvAttribute, DWORD cbAttribute) - { - if(!IsThemingSupported()) - return S_FALSE; - - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::SetWindowThemeAttribute(pT->m_hWnd, type, pvAttribute, cbAttribute); - } - - HRESULT SetWindowThemeNonClientAttributes(DWORD dwAttributes, DWORD dwMask) - { - if(!IsThemingSupported()) - return S_FALSE; - - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - WTA_OPTIONS opt = { dwAttributes, dwMask }; - return ::SetWindowThemeAttribute(pT->m_hWnd, WTA_NONCLIENT, (PVOID)&opt, sizeof(opt)); - } - - HRESULT DrawThemeParentBackgroundEx(HDC hDC, DWORD dwFlags, const RECT* lpRect = NULL) - { - if(!IsThemingSupported()) - return S_FALSE; - - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - return ::DrawThemeParentBackgroundEx(pT->m_hWnd, hDC, dwFlags, lpRect); - } -#endif // _WTL_NEW_UXTHEME - -// Message map and handlers - // Note: If you handle any of these messages in your derived class, - // it is better to put CHAIN_MSG_MAP at the start of your message map. - BEGIN_MSG_MAP(CThemeImpl) - MESSAGE_HANDLER(WM_CREATE, OnCreate) - MESSAGE_HANDLER(WM_DESTROY, OnDestroy) - MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged) - MESSAGE_HANDLER(WM_NCPAINT, OnNcPaint) - END_MSG_MAP() - - LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - if(m_lpstrThemeClassList != NULL) - OpenThemeData(); - bHandled = FALSE; - return 1; - } - - LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - CloseThemeData(); - bHandled = FALSE; - return 1; - } - - LRESULT OnThemeChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - CloseThemeData(); - if(m_lpstrThemeClassList != NULL) - OpenThemeData(); - bHandled = FALSE; - return 1; - } - - LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - LRESULT lRet = 0; - bHandled = FALSE; - if(IsThemingSupported() && ((pT->GetExStyle() & WS_EX_CLIENTEDGE) != 0)) - { - if((m_dwExtendedStyle & THEME_EX_3DCLIENTEDGE) != 0) - { - lRet = ::DefWindowProc(pT->m_hWnd, uMsg, wParam, lParam); - bHandled = TRUE; - } - else if((m_hTheme != NULL) && ((m_dwExtendedStyle & THEME_EX_THEMECLIENTEDGE) != 0)) - { - HRGN hRgn = (wParam != 1) ? (HRGN)wParam : NULL; - if(pT->DrawThemeClientEdge(hRgn)) - bHandled = TRUE; - } - } - return lRet; - } - -// Drawing helper - bool DrawThemeClientEdge(HRGN hRgnUpdate) - { - T* pT = static_cast(this); - return AtlDrawThemeClientEdge(m_hTheme, pT->m_hWnd, hRgnUpdate, NULL, 0, 0); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// Buffered Paint and Animation - -#ifdef _WTL_NEW_UXTHEME - -/////////////////////////////////////////////////////////////////////////////// -// CBufferedPaintBase - Buffered Paint support for othe classes - -class CBufferedPaintBase -{ -public: - static int m_nIsBufferedPaintSupported; - - CBufferedPaintBase() - { - if(IsBufferedPaintSupported()) - ATLVERIFY(SUCCEEDED(::BufferedPaintInit())); - } - - ~CBufferedPaintBase() - { - if(IsBufferedPaintSupported()) - ATLVERIFY(SUCCEEDED(::BufferedPaintUnInit())); - } - - static bool IsBufferedPaintSupported() - { - if(m_nIsBufferedPaintSupported == -1) - { - CStaticDataInitCriticalSectionLock lock; - if(FAILED(lock.Lock())) - { - ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CBufferedPaintBase::IsBufferedPaintSupported.\n")); - ATLASSERT(FALSE); - return false; - } - - if(m_nIsBufferedPaintSupported == -1) - m_nIsBufferedPaintSupported = RunTimeHelper::IsVista() ? 1 : 0; - - lock.Unlock(); - } - - ATLASSERT(m_nIsBufferedPaintSupported != -1); - return (m_nIsBufferedPaintSupported == 1); - } -}; - -__declspec(selectany) int CBufferedPaintBase::m_nIsBufferedPaintSupported = -1; - - -/////////////////////////////////////////////////////////////////////////////// -// CBufferedPaint - support for buffered paint functions - -class CBufferedPaint -{ -public: - HPAINTBUFFER m_hPaintBuffer; - - CBufferedPaint() : m_hPaintBuffer(NULL) - { } - - ~CBufferedPaint() - { - ATLVERIFY(SUCCEEDED(End())); - } - - bool IsNull() const - { - return (m_hPaintBuffer == NULL); - } - - HPAINTBUFFER Begin(HDC hdcTarget, const RECT* prcTarget, BP_BUFFERFORMAT dwFormat, BP_PAINTPARAMS* pPaintParams, HDC* phdcPaint) - { - ATLASSERT(m_hPaintBuffer == NULL); - m_hPaintBuffer = ::BeginBufferedPaint(hdcTarget, prcTarget, dwFormat, pPaintParams, phdcPaint); - return m_hPaintBuffer; - } - - HRESULT End(BOOL bUpdate = TRUE) - { - HRESULT hRet = S_FALSE; - if(m_hPaintBuffer != NULL) - { - hRet = ::EndBufferedPaint(m_hPaintBuffer, bUpdate); - m_hPaintBuffer = NULL; - } - return hRet; - } - - HRESULT GetTargetRect(LPRECT pRect) const - { - ATLASSERT(m_hPaintBuffer != NULL); - return ::GetBufferedPaintTargetRect(m_hPaintBuffer, pRect); - } - - HDC GetTargetDC() const - { - ATLASSERT(m_hPaintBuffer != NULL); - return ::GetBufferedPaintTargetDC(m_hPaintBuffer); - } - - HDC GetPaintDC() const - { - ATLASSERT(m_hPaintBuffer != NULL); - return ::GetBufferedPaintDC(m_hPaintBuffer); - } - - HRESULT GetBits(RGBQUAD** ppbBuffer, int* pcxRow) const - { - ATLASSERT(m_hPaintBuffer != NULL); - return ::GetBufferedPaintBits(m_hPaintBuffer, ppbBuffer, pcxRow); - } - - HRESULT Clear(const RECT* pRect = NULL) - { - ATLASSERT(m_hPaintBuffer != NULL); - return ::BufferedPaintClear(m_hPaintBuffer, pRect); - } - - HRESULT SetAlpha(BYTE alpha, const RECT* pRect = NULL) - { - ATLASSERT(m_hPaintBuffer != NULL); - return ::BufferedPaintSetAlpha(m_hPaintBuffer, pRect, alpha); - } - - HRESULT MakeOpaque(const RECT* pRect = NULL) - { - ATLASSERT(m_hPaintBuffer != NULL); - return ::BufferedPaintSetAlpha(m_hPaintBuffer, pRect, 255); - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CBufferedPaintImpl - provides buffered paint for any window - -template -class ATL_NO_VTABLE CBufferedPaintImpl : public CBufferedPaintBase -{ -public: - CBufferedPaint m_BufferedPaint; - BP_BUFFERFORMAT m_dwFormat; - BP_PAINTPARAMS m_PaintParams; - - CBufferedPaintImpl() : m_dwFormat(BPBF_TOPDOWNDIB) - { - memset(&m_PaintParams, 0, sizeof(BP_PAINTPARAMS)); - m_PaintParams.cbSize = sizeof(BP_PAINTPARAMS); - } - -// Message map and handlers - BEGIN_MSG_MAP(CBufferedPaintImpl) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) - MESSAGE_HANDLER(WM_PAINT, OnPaint) - MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) - END_MSG_MAP() - - LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - return 1; // no background needed - } - - LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - if(wParam != NULL) - { - RECT rect = { 0 }; - pT->GetClientRect(&rect); - pT->DoPaint((HDC)wParam, rect); - } - else - { - CPaintDC dc(pT->m_hWnd); - pT->DoBufferedPaint(dc.m_hDC, dc.m_ps.rcPaint); - } - - return 0; - } - -// Overrideables - void DoBufferedPaint(CDCHandle dc, RECT& rect) - { - HDC hDCPaint = NULL; - if(IsBufferedPaintSupported()) - m_BufferedPaint.Begin(dc, &rect, m_dwFormat, &m_PaintParams, &hDCPaint); - - T* pT = static_cast(this); - if(hDCPaint != NULL) - pT->DoPaint(hDCPaint, rect); - else - pT->DoPaint(dc.m_hDC, rect); - - if(IsBufferedPaintSupported()) - m_BufferedPaint.End(); - } - - void DoPaint(CDCHandle /*dc*/, RECT& /*rect*/) - { - // must be implemented in a derived class - ATLASSERT(FALSE); - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CBufferedPaintWindowImpl - implements a window that uses buffered paint - -template -class ATL_NO_VTABLE CBufferedPaintWindowImpl : - public ATL::CWindowImpl, - public CBufferedPaintImpl< T > -{ -public: - BEGIN_MSG_MAP(CBufferedPaintWindowImpl) - CHAIN_MSG_MAP(CBufferedPaintImpl< T >) - END_MSG_MAP() -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CBufferedAnimation - support for buffered animation - -class CBufferedAnimation -{ -public: - HANIMATIONBUFFER m_hAnimationBuffer; - - CBufferedAnimation() : m_hAnimationBuffer(NULL) - { } - - ~CBufferedAnimation() - { - ATLVERIFY(SUCCEEDED(End())); - } - - bool IsNull() const - { - return (m_hAnimationBuffer == NULL); - } - - HANIMATIONBUFFER Begin(HWND hWnd, HDC hDCTarget, const RECT* pRectTarget, BP_BUFFERFORMAT dwFormat, BP_PAINTPARAMS* pPaintParams, BP_ANIMATIONPARAMS* pAnimationParams, HDC* phdcFrom, HDC* phdcTo) - { - ATLASSERT(m_hAnimationBuffer == NULL); - m_hAnimationBuffer = ::BeginBufferedAnimation(hWnd, hDCTarget, pRectTarget, dwFormat, pPaintParams, pAnimationParams, phdcFrom, phdcTo); - return m_hAnimationBuffer; - } - - HRESULT End(BOOL bUpdate = TRUE) - { - HRESULT hRet = S_FALSE; - if(m_hAnimationBuffer != NULL) - { - hRet = ::EndBufferedAnimation(m_hAnimationBuffer, bUpdate); - m_hAnimationBuffer = NULL; - } - return hRet; - } - - static bool IsRendering(HWND hWnd, HDC hDC) - { - return (::BufferedPaintRenderAnimation(hWnd, hDC) != FALSE); - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CBufferedAnimationImpl - provides buffered animation support for any window - -// Note: You can either use m_State and m_NewState to store the state information -// for the animation change, or map your state to those data members. DoPaint() -// should only rely on the state information that is passed to it. - -template -class ATL_NO_VTABLE CBufferedAnimationImpl : public CBufferedPaintBase -{ -public: - BP_BUFFERFORMAT m_dwFormat; - BP_PAINTPARAMS m_PaintParams; - BP_ANIMATIONPARAMS m_AnimationParams; - - TState m_State; - TState m_NewState; - - CBufferedAnimationImpl(TState InitialState) : m_dwFormat(BPBF_TOPDOWNDIB) - { - memset(&m_PaintParams, 0, sizeof(BP_PAINTPARAMS)); - m_PaintParams.cbSize = sizeof(BP_PAINTPARAMS); - - memset(&m_AnimationParams, 0, sizeof(BP_ANIMATIONPARAMS)); - m_AnimationParams.cbSize = sizeof(BP_ANIMATIONPARAMS); - m_AnimationParams.style = BPAS_LINEAR; - m_AnimationParams.dwDuration = 500; - - T* pT = static_cast(this); - pT->SetState(InitialState); - pT->SetNewState(InitialState); - } - - DWORD GetDuration() const - { - return m_AnimationParams.dwDuration; - } - - void SetDuration(DWORD dwDuration) - { - m_AnimationParams.dwDuration = dwDuration; - } - - void DoAnimation(TState NewState, const RECT* pRect = NULL) - { - T* pT = static_cast(this); - pT->SetNewState(NewState); - - pT->InvalidateRect(pRect, FALSE); - pT->UpdateWindow(); - - pT->SetState(NewState); - } - -// Message map and handlers - BEGIN_MSG_MAP(CBufferedAnimationImpl) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) - MESSAGE_HANDLER(WM_PAINT, OnPaint) - MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) - END_MSG_MAP() - - LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - return 1; // no background needed - } - - LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - if(wParam != NULL) - { - RECT rect = { 0 }; - pT->GetClientRect(&rect); - pT->DoPaint((HDC)wParam, rect, m_NewState); - } - else - { - CPaintDC dc(pT->m_hWnd); - pT->DoAnimationPaint(dc.m_hDC, dc.m_ps.rcPaint); - } - - return 0; - } - -// Overrideables - void SetState(TState State) - { - m_State = State; - } - - void SetNewState(TState State) - { - m_NewState = State; - } - - bool AreStatesEqual() const - { - return (m_State == m_NewState); - } - - void DoAnimationPaint(CDCHandle dc, RECT& rect) - { - T* pT = static_cast(this); - if(IsBufferedPaintSupported() && CBufferedAnimation::IsRendering(pT->m_hWnd, dc)) - return; - - DWORD dwDurationSave = m_AnimationParams.dwDuration; - if(pT->AreStatesEqual()) - m_AnimationParams.dwDuration = 0; - - HDC hdcFrom = NULL, hdcTo = NULL; - CBufferedAnimation ba; - if(IsBufferedPaintSupported()) - ba.Begin(pT->m_hWnd, dc, &rect, m_dwFormat, &m_PaintParams, &m_AnimationParams, &hdcFrom, &hdcTo); - - if(!ba.IsNull()) - { - if(hdcFrom != NULL) - pT->DoPaint(hdcFrom, rect, m_State); - - if (hdcTo != NULL) - pT->DoPaint(hdcTo, rect, m_NewState); - } - else - { - pT->DoPaint(dc.m_hDC, rect, m_NewState); - } - - m_AnimationParams.dwDuration = dwDurationSave; - } - - void DoPaint(CDCHandle /*dc*/, RECT& /*rect*/, TState /*State*/) - { - // must be implemented in a derived class - ATLASSERT(FALSE); - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CBufferedAnimationWindowImpl - implements a window that uses buffered animation - -template -class ATL_NO_VTABLE CBufferedAnimationWindowImpl : - public ATL::CWindowImpl, - public CBufferedAnimationImpl< T, TState > -{ -public: - CBufferedAnimationWindowImpl(TState InitialState) : CBufferedAnimationImpl< T, TState >(InitialState) - { } - - typedef CBufferedAnimationImpl< T, TState > _baseBufferedAnimation; - BEGIN_MSG_MAP(CBufferedAnimationWindowImpl) - CHAIN_MSG_MAP(_baseBufferedAnimation) - END_MSG_MAP() -}; - -#endif // _WTL_NEW_UXTHEME - -}; // namespace WTL - -#endif // __ATLTHEME_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atluser.h b/!NotAdopted/SmartAutoReplier/wtl/atluser.h deleted file mode 100644 index 6cd8205a73..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atluser.h +++ /dev/null @@ -1,1391 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLUSER_H__ -#define __ATLUSER_H__ - -#pragma once - -#ifndef __ATLAPP_H__ - #error atluser.h requires atlapp.h to be included first -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CMenuItemInfo -// CMenuT -// CAcceleratorT -// CIconT -// CCursorT -// CResource -// -// Global functions: -// AtlMessageBox() -// -// AtlLoadAccelerators() -// AtlLoadMenu() -// AtlLoadBitmap() -// AtlLoadSysBitmap() -// AtlLoadCursor() -// AtlLoadSysCursor() -// AtlLoadIcon() -// AtlLoadSysIcon() -// AtlLoadBitmapImage() -// AtlLoadCursorImage() -// AtlLoadIconImage() -// AtlLoadSysBitmapImage() -// AtlLoadSysCursorImage() -// AtlLoadSysIconImage() -// AtlLoadString() - - -namespace WTL -{ - -/////////////////////////////////////////////////////////////////////////////// -// AtlMessageBox - accepts both memory and resource based strings - -inline int AtlMessageBox(HWND hWndOwner, ATL::_U_STRINGorID message, ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uType = MB_OK | MB_ICONINFORMATION) -{ - ATLASSERT(hWndOwner == NULL || ::IsWindow(hWndOwner)); - - LPTSTR lpstrMessage = NULL; - if(IS_INTRESOURCE(message.m_lpstr)) - { - for(int nLen = 256; ; nLen *= 2) - { - ATLTRY(lpstrMessage = new TCHAR[nLen]); - if(lpstrMessage == NULL) - { - ATLASSERT(FALSE); - return 0; - } - int nRes = ::LoadString(ModuleHelper::GetResourceInstance(), LOWORD(message.m_lpstr), lpstrMessage, nLen); - if(nRes < nLen - 1) - break; - delete [] lpstrMessage; - lpstrMessage = NULL; - } - - message.m_lpstr = lpstrMessage; - } - - LPTSTR lpstrTitle = NULL; - if(IS_INTRESOURCE(title.m_lpstr) && LOWORD(title.m_lpstr) != 0) - { - for(int nLen = 256; ; nLen *= 2) - { - ATLTRY(lpstrTitle = new TCHAR[nLen]); - if(lpstrTitle == NULL) - { - ATLASSERT(FALSE); - return 0; - } - int nRes = ::LoadString(ModuleHelper::GetResourceInstance(), LOWORD(title.m_lpstr), lpstrTitle, nLen); - if(nRes < nLen - 1) - break; - delete [] lpstrTitle; - lpstrTitle = NULL; - } - - title.m_lpstr = lpstrTitle; - } - - int nRet = ::MessageBox(hWndOwner, message.m_lpstr, title.m_lpstr, uType); - - delete [] lpstrMessage; - delete [] lpstrTitle; - - return nRet; -} - - -/////////////////////////////////////////////////////////////////////////////// -// CMenu - -#if (WINVER >= 0x0500) - #ifndef MII_SIZEOF_STRUCT - #define MII_SIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member)) - #endif - #define MENUITEMINFO_SIZE_VERSION_400A MII_SIZEOF_STRUCT(MENUITEMINFOA, cch) - #define MENUITEMINFO_SIZE_VERSION_400W MII_SIZEOF_STRUCT(MENUITEMINFOW, cch) - #ifdef UNICODE - #define MENUITEMINFO_SIZE_VERSION_400 MENUITEMINFO_SIZE_VERSION_400W - #else - #define MENUITEMINFO_SIZE_VERSION_400 MENUITEMINFO_SIZE_VERSION_400A - #endif // !UNICODE -#endif // (WINVER >= 0x0500) - -class CMenuItemInfo : public MENUITEMINFO -{ -public: - CMenuItemInfo() - { - memset(this, 0, sizeof(MENUITEMINFO)); - cbSize = sizeof(MENUITEMINFO); -#if (WINVER >= 0x0500) - // adjust struct size if running on older version of Windows - if(AtlIsOldWindows()) - { - ATLASSERT(cbSize > MENUITEMINFO_SIZE_VERSION_400); // must be - cbSize = MENUITEMINFO_SIZE_VERSION_400; - } -#endif // (WINVER >= 0x0500) - } -}; - - -// forward declarations -template class CMenuT; -typedef CMenuT CMenuHandle; -typedef CMenuT CMenu; - - -template -class CMenuT -{ -public: -// Data members - HMENU m_hMenu; - -// Constructor/destructor/operators - CMenuT(HMENU hMenu = NULL) : m_hMenu(hMenu) - { } - - ~CMenuT() - { - if(t_bManaged && m_hMenu != NULL) - DestroyMenu(); - } - - CMenuT& operator =(HMENU hMenu) - { - Attach(hMenu); - return *this; - } - - void Attach(HMENU hMenuNew) - { - ATLASSERT(::IsMenu(hMenuNew)); - if(t_bManaged && m_hMenu != NULL && m_hMenu != hMenuNew) - ::DestroyMenu(m_hMenu); - m_hMenu = hMenuNew; - } - - HMENU Detach() - { - HMENU hMenu = m_hMenu; - m_hMenu = NULL; - return hMenu; - } - - operator HMENU() const { return m_hMenu; } - - bool IsNull() const { return (m_hMenu == NULL); } - - BOOL IsMenu() const - { - return ::IsMenu(m_hMenu); - } - -// Create/destroy methods - BOOL CreateMenu() - { - ATLASSERT(m_hMenu == NULL); - m_hMenu = ::CreateMenu(); - return (m_hMenu != NULL) ? TRUE : FALSE; - } - - BOOL CreatePopupMenu() - { - ATLASSERT(m_hMenu == NULL); - m_hMenu = ::CreatePopupMenu(); - return (m_hMenu != NULL) ? TRUE : FALSE; - } - - BOOL LoadMenu(ATL::_U_STRINGorID menu) - { - ATLASSERT(m_hMenu == NULL); - m_hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), menu.m_lpstr); - return (m_hMenu != NULL) ? TRUE : FALSE; - } - -#ifndef _WIN32_WCE - BOOL LoadMenuIndirect(const void* lpMenuTemplate) - { - ATLASSERT(m_hMenu == NULL); - m_hMenu = ::LoadMenuIndirect(lpMenuTemplate); - return (m_hMenu != NULL) ? TRUE : FALSE; - } -#endif // !_WIN32_WCE - - BOOL DestroyMenu() - { - if (m_hMenu == NULL) - return FALSE; - BOOL bRet = ::DestroyMenu(m_hMenu); - if(bRet) - m_hMenu = NULL; - return bRet; - } - -// Menu Operations - BOOL DeleteMenu(UINT nPosition, UINT nFlags) - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::DeleteMenu(m_hMenu, nPosition, nFlags); - } - - BOOL TrackPopupMenu(UINT nFlags, int x, int y, HWND hWnd, LPCRECT lpRect = NULL) - { - ATLASSERT(::IsMenu(m_hMenu)); -#ifndef _WIN32_WCE -#if (WINVER >= 0x0500) - x = _FixTrackMenuPopupX(x, y); -#endif // !(WINVER >= 0x0500) - return ::TrackPopupMenu(m_hMenu, nFlags, x, y, 0, hWnd, lpRect); -#else // CE specific - lpRect; - return ::TrackPopupMenuEx(m_hMenu, nFlags, x, y, hWnd, NULL); -#endif // _WIN32_WCE - } - - BOOL TrackPopupMenuEx(UINT uFlags, int x, int y, HWND hWnd, LPTPMPARAMS lptpm = NULL) - { - ATLASSERT(::IsMenu(m_hMenu)); -#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) - x = _FixTrackMenuPopupX(x, y); -#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) - return ::TrackPopupMenuEx(m_hMenu, uFlags, x, y, hWnd, lptpm); - } - -#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) - // helper that fixes popup menu X position when it's off-screen - static int _FixTrackMenuPopupX(int x, int y) - { - POINT pt = { x, y }; - HMONITOR hMonitor = ::MonitorFromPoint(pt, MONITOR_DEFAULTTONULL); - if(hMonitor == NULL) - { - HMONITOR hMonitorNear = ::MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); - if(hMonitorNear != NULL) - { - MONITORINFO mi = { 0 }; - mi.cbSize = sizeof(MONITORINFO); - if(::GetMonitorInfo(hMonitorNear, &mi) != FALSE) - { - if(x < mi.rcWork.left) - x = mi.rcWork.left; - else if(x > mi.rcWork.right) - x = mi.rcWork.right; - } - } - } - - return x; - } - - BOOL GetMenuInfo(LPMENUINFO lpMenuInfo) const - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::GetMenuInfo(m_hMenu, lpMenuInfo); - } - - BOOL SetMenuInfo(LPCMENUINFO lpMenuInfo) - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::SetMenuInfo(m_hMenu, lpMenuInfo); - } -#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) - -// Menu Item Operations - BOOL AppendMenu(UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL) - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::AppendMenu(m_hMenu, nFlags, nIDNewItem, lpszNewItem); - } - - BOOL AppendMenu(UINT nFlags, HMENU hSubMenu, LPCTSTR lpszNewItem) - { - ATLASSERT(::IsMenu(m_hMenu)); - ATLASSERT(::IsMenu(hSubMenu)); - return ::AppendMenu(m_hMenu, nFlags | MF_POPUP, (UINT_PTR)hSubMenu, lpszNewItem); - } - -#ifndef _WIN32_WCE - BOOL AppendMenu(UINT nFlags, UINT_PTR nIDNewItem, HBITMAP hBmp) - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::AppendMenu(m_hMenu, nFlags | MF_BITMAP, nIDNewItem, (LPCTSTR)hBmp); - } - - BOOL AppendMenu(UINT nFlags, HMENU hSubMenu, HBITMAP hBmp) - { - ATLASSERT(::IsMenu(m_hMenu)); - ATLASSERT(::IsMenu(hSubMenu)); - return ::AppendMenu(m_hMenu, nFlags | (MF_BITMAP | MF_POPUP), (UINT_PTR)hSubMenu, (LPCTSTR)hBmp); - } -#endif // !_WIN32_WCE - - UINT CheckMenuItem(UINT nIDCheckItem, UINT nCheck) - { - ATLASSERT(::IsMenu(m_hMenu)); - return (UINT)::CheckMenuItem(m_hMenu, nIDCheckItem, nCheck); - } - - UINT EnableMenuItem(UINT nIDEnableItem, UINT nEnable) - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::EnableMenuItem(m_hMenu, nIDEnableItem, nEnable); - } - -#ifndef _WIN32_WCE - BOOL HiliteMenuItem(HWND hWnd, UINT uIDHiliteItem, UINT uHilite) - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::HiliteMenuItem(hWnd, m_hMenu, uIDHiliteItem, uHilite); - } - - int GetMenuItemCount() const - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::GetMenuItemCount(m_hMenu); - } - - UINT GetMenuItemID(int nPos) const - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::GetMenuItemID(m_hMenu, nPos); - } - - UINT GetMenuState(UINT nID, UINT nFlags) const - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::GetMenuState(m_hMenu, nID, nFlags); - } - - int GetMenuString(UINT nIDItem, LPTSTR lpString, int nMaxCount, UINT nFlags) const - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::GetMenuString(m_hMenu, nIDItem, lpString, nMaxCount, nFlags); - } - - int GetMenuStringLen(UINT nIDItem, UINT nFlags) const - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::GetMenuString(m_hMenu, nIDItem, NULL, 0, nFlags); - } - -#ifndef _ATL_NO_COM - BOOL GetMenuString(UINT nIDItem, BSTR& bstrText, UINT nFlags) const - { - USES_CONVERSION; - ATLASSERT(::IsMenu(m_hMenu)); - ATLASSERT(bstrText == NULL); - - int nLen = GetMenuStringLen(nIDItem, nFlags); - if(nLen == 0) - { - bstrText = ::SysAllocString(OLESTR("")); - return (bstrText != NULL) ? TRUE : FALSE; - } - - nLen++; // increment to include terminating NULL char - CTempBuffer buff; - LPTSTR lpszText = buff.Allocate(nLen); - if(lpszText == NULL) - return FALSE; - - if(!GetMenuString(nIDItem, lpszText, nLen, nFlags)) - return FALSE; - - bstrText = ::SysAllocString(T2OLE(lpszText)); - return (bstrText != NULL) ? TRUE : FALSE; - } -#endif // !_ATL_NO_COM - -#elif (_ATL_VER >= 0x0800) - int GetMenuItemCount() const - { - ATLASSERT(::IsMenu(m_hMenu)); - return ATL::GetMenuItemCount(m_hMenu); - } - - UINT GetMenuItemID(int nPos) const - { - ATLASSERT(::IsMenu(m_hMenu)); - return ATL::GetMenuItemID(m_hMenu, nPos); - } - - UINT GetMenuState(UINT nID, UINT nFlags) const - { - ATLASSERT(::IsMenu(m_hMenu)); - return ATL::GetMenuState(m_hMenu, nID, nFlags); - } - - int GetMenuString(UINT nIDItem, LPTSTR lpString, int nMaxCount, UINT nFlags) const - { - ATLASSERT(::IsMenu(m_hMenu)); - return ATL::GetMenuString(m_hMenu, nIDItem, lpString, nMaxCount, nFlags); - } - - int GetMenuStringLen(UINT nIDItem, UINT nFlags) const - { - ATLASSERT(::IsMenu(m_hMenu)); - return ATL::GetMenuString(m_hMenu, nIDItem, NULL, 0, nFlags); - } -#endif // (_ATL_VER >= 0x0800) - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - int GetMenuString(UINT nIDItem, _CSTRING_NS::CString& strText, UINT nFlags) const - { - ATLASSERT(::IsMenu(m_hMenu)); - - int nLen = GetMenuStringLen(nIDItem, nFlags); - if(nLen == 0) - return 0; - - nLen++; // increment to include terminating NULL char - LPTSTR lpstr = strText.GetBufferSetLength(nLen); - if(lpstr == NULL) - return 0; - int nRet = GetMenuString(nIDItem, lpstr, nLen, nFlags); - strText.ReleaseBuffer(); - return nRet; - } -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - - CMenuHandle GetSubMenu(int nPos) const - { - ATLASSERT(::IsMenu(m_hMenu)); - return CMenuHandle(::GetSubMenu(m_hMenu, nPos)); - } - - BOOL InsertMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL) - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::InsertMenu(m_hMenu, nPosition, nFlags, nIDNewItem, lpszNewItem); - } - - BOOL InsertMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, LPCTSTR lpszNewItem) - { - ATLASSERT(::IsMenu(m_hMenu)); - ATLASSERT(::IsMenu(hSubMenu)); - return ::InsertMenu(m_hMenu, nPosition, nFlags | MF_POPUP, (UINT_PTR)hSubMenu, lpszNewItem); - } - -#ifndef _WIN32_WCE - BOOL InsertMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem, HBITMAP hBmp) - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::InsertMenu(m_hMenu, nPosition, nFlags | MF_BITMAP, nIDNewItem, (LPCTSTR)hBmp); - } - - BOOL InsertMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, HBITMAP hBmp) - { - ATLASSERT(::IsMenu(m_hMenu)); - ATLASSERT(::IsMenu(hSubMenu)); - return ::InsertMenu(m_hMenu, nPosition, nFlags | (MF_BITMAP | MF_POPUP), (UINT_PTR)hSubMenu, (LPCTSTR)hBmp); - } - - BOOL ModifyMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL) - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::ModifyMenu(m_hMenu, nPosition, nFlags, nIDNewItem, lpszNewItem); - } - - BOOL ModifyMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, LPCTSTR lpszNewItem) - { - ATLASSERT(::IsMenu(m_hMenu)); - ATLASSERT(::IsMenu(hSubMenu)); - return ::ModifyMenu(m_hMenu, nPosition, nFlags | MF_POPUP, (UINT_PTR)hSubMenu, lpszNewItem); - } - - BOOL ModifyMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem, HBITMAP hBmp) - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::ModifyMenu(m_hMenu, nPosition, nFlags | MF_BITMAP, nIDNewItem, (LPCTSTR)hBmp); - } - - BOOL ModifyMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, HBITMAP hBmp) - { - ATLASSERT(::IsMenu(m_hMenu)); - ATLASSERT(::IsMenu(hSubMenu)); - return ::ModifyMenu(m_hMenu, nPosition, nFlags | (MF_BITMAP | MF_POPUP), (UINT_PTR)hSubMenu, (LPCTSTR)hBmp); - } -#endif // !_WIN32_WCE - - BOOL RemoveMenu(UINT nPosition, UINT nFlags) - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::RemoveMenu(m_hMenu, nPosition, nFlags); - } - -#ifndef _WIN32_WCE - BOOL SetMenuItemBitmaps(UINT nPosition, UINT nFlags, HBITMAP hBmpUnchecked, HBITMAP hBmpChecked) - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::SetMenuItemBitmaps(m_hMenu, nPosition, nFlags, hBmpUnchecked, hBmpChecked); - } -#endif // !_WIN32_WCE - - BOOL CheckMenuRadioItem(UINT nIDFirst, UINT nIDLast, UINT nIDItem, UINT nFlags) - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::CheckMenuRadioItem(m_hMenu, nIDFirst, nIDLast, nIDItem, nFlags); - } - - BOOL GetMenuItemInfo(UINT uItem, BOOL bByPosition, LPMENUITEMINFO lpmii) const - { - ATLASSERT(::IsMenu(m_hMenu)); - return (BOOL)::GetMenuItemInfo(m_hMenu, uItem, bByPosition, lpmii); - } - - BOOL SetMenuItemInfo(UINT uItem, BOOL bByPosition, LPMENUITEMINFO lpmii) - { - ATLASSERT(::IsMenu(m_hMenu)); - return (BOOL)::SetMenuItemInfo(m_hMenu, uItem, bByPosition, lpmii); - } - -#ifndef _WIN32_WCE - BOOL InsertMenuItem(UINT uItem, BOOL bByPosition, LPMENUITEMINFO lpmii) - { - ATLASSERT(::IsMenu(m_hMenu)); - return (BOOL)::InsertMenuItem(m_hMenu, uItem, bByPosition, lpmii); - } - - UINT GetMenuDefaultItem(BOOL bByPosition = FALSE, UINT uFlags = 0U) const - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::GetMenuDefaultItem(m_hMenu, (UINT)bByPosition, uFlags); - } - - BOOL SetMenuDefaultItem(UINT uItem = (UINT)-1, BOOL bByPosition = FALSE) - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::SetMenuDefaultItem(m_hMenu, uItem, (UINT)bByPosition); - } - - BOOL GetMenuItemRect(HWND hWnd, UINT uItem, LPRECT lprcItem) const - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::GetMenuItemRect(hWnd, m_hMenu, uItem, lprcItem); - } - - int MenuItemFromPoint(HWND hWnd, POINT point) const - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::MenuItemFromPoint(hWnd, m_hMenu, point); - } - -// Context Help Functions - BOOL SetMenuContextHelpId(DWORD dwContextHelpId) - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::SetMenuContextHelpId(m_hMenu, dwContextHelpId); - } - - DWORD GetMenuContextHelpId() const - { - ATLASSERT(::IsMenu(m_hMenu)); - return ::GetMenuContextHelpId(m_hMenu); - } -#endif // !_WIN32_WCE -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CAccelerator - -template -class CAcceleratorT -{ -public: - HACCEL m_hAccel; - -// Constructor/destructor/operators - CAcceleratorT(HACCEL hAccel = NULL) : m_hAccel(hAccel) - { } - - ~CAcceleratorT() - { - if(t_bManaged && m_hAccel != NULL) - ::DestroyAcceleratorTable(m_hAccel); - } - - CAcceleratorT& operator =(HACCEL hAccel) - { - Attach(hAccel); - return *this; - } - - void Attach(HACCEL hAccel) - { - if(t_bManaged && m_hAccel != NULL) - ::DestroyAcceleratorTable(m_hAccel); - m_hAccel = hAccel; - } - - HACCEL Detach() - { - HACCEL hAccel = m_hAccel; - m_hAccel = NULL; - return hAccel; - } - - operator HACCEL() const { return m_hAccel; } - - bool IsNull() const { return m_hAccel == NULL; } - -// Create/destroy methods - HACCEL LoadAccelerators(ATL::_U_STRINGorID accel) - { - ATLASSERT(m_hAccel == NULL); - m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), accel.m_lpstr); - return m_hAccel; - } - - HACCEL CreateAcceleratorTable(LPACCEL pAccel, int cEntries) - { - ATLASSERT(m_hAccel == NULL); - ATLASSERT(pAccel != NULL); - m_hAccel = ::CreateAcceleratorTable(pAccel, cEntries); - return m_hAccel; - } - - void DestroyObject() - { - if(m_hAccel != NULL) - { - ::DestroyAcceleratorTable(m_hAccel); - m_hAccel = NULL; - } - } - -// Operations -#ifndef _WIN32_WCE - int CopyAcceleratorTable(LPACCEL lpAccelDst, int cEntries) - { - ATLASSERT(m_hAccel != NULL); - ATLASSERT(lpAccelDst != NULL); - return ::CopyAcceleratorTable(m_hAccel, lpAccelDst, cEntries); - } - - int GetEntriesCount() const - { - ATLASSERT(m_hAccel != NULL); - return ::CopyAcceleratorTable(m_hAccel, NULL, 0); - } -#endif // !_WIN32_WCE - - BOOL TranslateAccelerator(HWND hWnd, LPMSG pMsg) - { - ATLASSERT(m_hAccel != NULL); - ATLASSERT(::IsWindow(hWnd)); - ATLASSERT(pMsg != NULL); - return ::TranslateAccelerator(hWnd, m_hAccel, pMsg); - } -}; - -typedef CAcceleratorT CAcceleratorHandle; -typedef CAcceleratorT CAccelerator; - - -/////////////////////////////////////////////////////////////////////////////// -// CIcon - -template -class CIconT -{ -public: - HICON m_hIcon; - -// Constructor/destructor/operators - CIconT(HICON hIcon = NULL) : m_hIcon(hIcon) - { } - - ~CIconT() - { - if(t_bManaged && m_hIcon != NULL) - ::DestroyIcon(m_hIcon); - } - - CIconT& operator =(HICON hIcon) - { - Attach(hIcon); - return *this; - } - - void Attach(HICON hIcon) - { - if(t_bManaged && m_hIcon != NULL) - ::DestroyIcon(m_hIcon); - m_hIcon = hIcon; - } - - HICON Detach() - { - HICON hIcon = m_hIcon; - m_hIcon = NULL; - return hIcon; - } - - operator HICON() const { return m_hIcon; } - - bool IsNull() const { return m_hIcon == NULL; } - -// Create/destroy methods - HICON LoadIcon(ATL::_U_STRINGorID icon) - { - ATLASSERT(m_hIcon == NULL); - m_hIcon = ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr); - return m_hIcon; - } - - HICON LoadIcon(ATL::_U_STRINGorID icon, int cxDesired, int cyDesired, UINT fuLoad = 0) - { - ATLASSERT(m_hIcon == NULL); - m_hIcon = (HICON) ::LoadImage(ModuleHelper::GetResourceInstance(), icon.m_lpstr, IMAGE_ICON, cxDesired, cyDesired, fuLoad); - return m_hIcon; - } - -#ifndef _WIN32_WCE - HICON LoadOEMIcon(LPCTSTR lpstrIconName) - { - ATLASSERT(m_hIcon == NULL); - ATLASSERT(IsOEMIcon(lpstrIconName)); - m_hIcon = ::LoadIcon(NULL, lpstrIconName); - return m_hIcon; - } - - HICON CreateIcon(int nWidth, int nHeight, BYTE cPlanes, BYTE cBitsPixel, CONST BYTE* lpbANDbits, CONST BYTE *lpbXORbits) - { - ATLASSERT(m_hIcon == NULL); - ATLASSERT(lpbANDbits != NULL); - ATLASSERT(lpbXORbits != NULL); - m_hIcon = ::CreateIcon(ModuleHelper::GetResourceInstance(), nWidth, nHeight, cPlanes, cBitsPixel, lpbANDbits, lpbXORbits); - return m_hIcon; - } - - HICON CreateIconFromResource(PBYTE pBits, DWORD dwResSize, DWORD dwVersion = 0x00030000) - { - ATLASSERT(m_hIcon == NULL); - ATLASSERT(pBits != NULL); - m_hIcon = ::CreateIconFromResource(pBits, dwResSize, TRUE, dwVersion); - return m_hIcon; - } - - HICON CreateIconFromResourceEx(PBYTE pbBits, DWORD cbBits, DWORD dwVersion = 0x00030000, int cxDesired = 0, int cyDesired = 0, UINT uFlags = LR_DEFAULTCOLOR) - { - ATLASSERT(m_hIcon == NULL); - ATLASSERT(pbBits != NULL); - ATLASSERT(cbBits > 0); - m_hIcon = ::CreateIconFromResourceEx(pbBits, cbBits, TRUE, dwVersion, cxDesired, cyDesired, uFlags); - return m_hIcon; - } -#endif // !_WIN32_WCE - - HICON CreateIconIndirect(PICONINFO pIconInfo) - { - ATLASSERT(m_hIcon == NULL); - ATLASSERT(pIconInfo != NULL); - m_hIcon = ::CreateIconIndirect(pIconInfo); - return m_hIcon; - } - -#ifndef _WIN32_WCE - HICON ExtractIcon(LPCTSTR lpszExeFileName, UINT nIconIndex) - { - ATLASSERT(m_hIcon == NULL); - ATLASSERT(lpszExeFileName != NULL); - m_hIcon = ::ExtractIcon(ModuleHelper::GetModuleInstance(), lpszExeFileName, nIconIndex); - return m_hIcon; - } - - HICON ExtractAssociatedIcon(HINSTANCE hInst, LPTSTR lpIconPath, LPWORD lpiIcon) - { - ATLASSERT(m_hIcon == NULL); - ATLASSERT(lpIconPath != NULL); - ATLASSERT(lpiIcon != NULL); - m_hIcon = ::ExtractAssociatedIcon(hInst, lpIconPath, lpiIcon); - return m_hIcon; - } -#endif // !_WIN32_WCE - - BOOL DestroyIcon() - { - ATLASSERT(m_hIcon != NULL); - BOOL bRet = ::DestroyIcon(m_hIcon); - if(bRet != FALSE) - m_hIcon = NULL; - return bRet; - } - -// Operations -#ifndef _WIN32_WCE - HICON CopyIcon() - { - ATLASSERT(m_hIcon != NULL); - return ::CopyIcon(m_hIcon); - } - - HICON DuplicateIcon() - { - ATLASSERT(m_hIcon != NULL); - return ::DuplicateIcon(NULL, m_hIcon); - } -#endif // !_WIN32_WCE - - BOOL DrawIcon(HDC hDC, int x, int y) - { - ATLASSERT(m_hIcon != NULL); -#ifndef _WIN32_WCE - return ::DrawIcon(hDC, x, y, m_hIcon); -#else // CE specific - return ::DrawIconEx(hDC, x, y, m_hIcon, 0, 0, 0, NULL, DI_NORMAL); -#endif // _WIN32_WCE - } - - BOOL DrawIcon(HDC hDC, POINT pt) - { - ATLASSERT(m_hIcon != NULL); -#ifndef _WIN32_WCE - return ::DrawIcon(hDC, pt.x, pt.y, m_hIcon); -#else // CE specific - return ::DrawIconEx(hDC, pt.x, pt.y, m_hIcon, 0, 0, 0, NULL, DI_NORMAL); -#endif // _WIN32_WCE - } - - BOOL DrawIconEx(HDC hDC, int x, int y, int cxWidth, int cyWidth, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL) - { - ATLASSERT(m_hIcon != NULL); - return ::DrawIconEx(hDC, x, y, m_hIcon, cxWidth, cyWidth, uStepIfAniCur, hbrFlickerFreeDraw, uFlags); - } - - BOOL DrawIconEx(HDC hDC, POINT pt, SIZE size, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL) - { - ATLASSERT(m_hIcon != NULL); - return ::DrawIconEx(hDC, pt.x, pt.y, m_hIcon, size.cx, size.cy, uStepIfAniCur, hbrFlickerFreeDraw, uFlags); - } - -#ifndef _WIN32_WCE - BOOL GetIconInfo(PICONINFO pIconInfo) const - { - ATLASSERT(m_hIcon != NULL); - ATLASSERT(pIconInfo != NULL); - return ::GetIconInfo(m_hIcon, pIconInfo); - } - -#if (_WIN32_WINNT >= 0x0600) - BOOL GetIconInfoEx(PICONINFOEX pIconInfo) const - { - ATLASSERT(m_hIcon != NULL); - ATLASSERT(pIconInfo != NULL); - return ::GetIconInfoEx(m_hIcon, pIconInfo); - } -#endif // (_WIN32_WINNT >= 0x0600) - -#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) - HRESULT LoadIconMetric(ATL::_U_STRINGorID icon, int lims) - { - ATLASSERT(m_hIcon == NULL); - USES_CONVERSION; - return ::LoadIconMetric(ModuleHelper::GetResourceInstance(), T2CW(icon.m_lpstr), lims, &m_hIcon); - } - - HRESULT LoadIconWithScaleDown(ATL::_U_STRINGorID icon, int cx, int cy) - { - ATLASSERT(m_hIcon == NULL); - USES_CONVERSION; - return ::LoadIconWithScaleDown(ModuleHelper::GetResourceInstance(), T2CW(icon.m_lpstr), cx, cy, &m_hIcon); - } - - HRESULT LoadOEMIconMetric(LPCTSTR lpstrIconName, int lims) - { - ATLASSERT(m_hIcon == NULL); - ATLASSERT(IsOEMIcon(lpstrIconName)); - return ::LoadIconMetric(NULL, (LPCWSTR)lpstrIconName, lims, &m_hIcon); - } - - HRESULT LoadOEMIconWithScaleDown(LPCTSTR lpstrIconName, int cx, int cy) - { - ATLASSERT(m_hIcon == NULL); - ATLASSERT(IsOEMIcon(lpstrIconName)); - USES_CONVERSION; - return ::LoadIconWithScaleDown(NULL, (LPCWSTR)lpstrIconName, cx, cy, &m_hIcon); - } -#endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) -#endif // !_WIN32_WCE - - // Helper -#ifndef _WIN32_WCE - static bool IsOEMIcon(LPCTSTR lpstrIconName) - { -#if (WINVER >= 0x0600) - return (lpstrIconName == IDI_APPLICATION || lpstrIconName == IDI_ASTERISK || lpstrIconName == IDI_EXCLAMATION || - lpstrIconName == IDI_HAND || lpstrIconName == IDI_QUESTION || lpstrIconName == IDI_WINLOGO || - lpstrIconName == IDI_SHIELD); -#else // !(WINVER >= 0x0600) - return (lpstrIconName == IDI_APPLICATION || lpstrIconName == IDI_ASTERISK || lpstrIconName == IDI_EXCLAMATION || - lpstrIconName == IDI_HAND || lpstrIconName == IDI_QUESTION || lpstrIconName == IDI_WINLOGO); -#endif // !(WINVER >= 0x0600) - } -#endif // !_WIN32_WCE -}; - -typedef CIconT CIconHandle; -typedef CIconT CIcon; - - -/////////////////////////////////////////////////////////////////////////////// -// CCursor - -// protect template member from a winuser.h macro -#ifdef CopyCursor - #undef CopyCursor -#endif - -template -class CCursorT -{ -public: - HCURSOR m_hCursor; - -// Constructor/destructor/operators - CCursorT(HCURSOR hCursor = NULL) : m_hCursor(hCursor) - { } - - ~CCursorT() - { - if(t_bManaged && m_hCursor != NULL) - DestroyCursor(); - } - - CCursorT& operator =(HCURSOR hCursor) - { - Attach(hCursor); - return *this; - } - - void Attach(HCURSOR hCursor) - { - if(t_bManaged && m_hCursor != NULL) - DestroyCursor(); - m_hCursor = hCursor; - } - - HCURSOR Detach() - { - HCURSOR hCursor = m_hCursor; - m_hCursor = NULL; - return hCursor; - } - - operator HCURSOR() const { return m_hCursor; } - - bool IsNull() const { return m_hCursor == NULL; } - -// Create/destroy methods - HCURSOR LoadCursor(ATL::_U_STRINGorID cursor) - { - ATLASSERT(m_hCursor == NULL); - m_hCursor = ::LoadCursor(ModuleHelper::GetResourceInstance(), cursor.m_lpstr); - return m_hCursor; - } - - HCURSOR LoadSysCursor(LPCTSTR lpstrCursorName) - { - ATLASSERT(m_hCursor == NULL); -#if (WINVER >= 0x0500) - ATLASSERT(lpstrCursorName == IDC_ARROW || lpstrCursorName == IDC_IBEAM || lpstrCursorName == IDC_WAIT || - lpstrCursorName == IDC_CROSS || lpstrCursorName == IDC_UPARROW || lpstrCursorName == IDC_SIZE || - lpstrCursorName == IDC_ICON || lpstrCursorName == IDC_SIZENWSE || lpstrCursorName == IDC_SIZENESW || - lpstrCursorName == IDC_SIZEWE || lpstrCursorName == IDC_SIZENS || lpstrCursorName == IDC_SIZEALL || - lpstrCursorName == IDC_NO || lpstrCursorName == IDC_APPSTARTING || lpstrCursorName == IDC_HELP || - lpstrCursorName == IDC_HAND); -#else // !(WINVER >= 0x0500) - ATLASSERT(lpstrCursorName == IDC_ARROW || lpstrCursorName == IDC_IBEAM || lpstrCursorName == IDC_WAIT || - lpstrCursorName == IDC_CROSS || lpstrCursorName == IDC_UPARROW || lpstrCursorName == IDC_SIZE || - lpstrCursorName == IDC_ICON || lpstrCursorName == IDC_SIZENWSE || lpstrCursorName == IDC_SIZENESW || - lpstrCursorName == IDC_SIZEWE || lpstrCursorName == IDC_SIZENS || lpstrCursorName == IDC_SIZEALL || - lpstrCursorName == IDC_NO || lpstrCursorName == IDC_APPSTARTING || lpstrCursorName == IDC_HELP); -#endif // !(WINVER >= 0x0500) - m_hCursor = ::LoadCursor(NULL, lpstrCursorName); - return m_hCursor; - } - - // deprecated - HCURSOR LoadOEMCursor(LPCTSTR lpstrCursorName) - { - return LoadSysCursor(lpstrCursorName); - } - - HCURSOR LoadCursor(ATL::_U_STRINGorID cursor, int cxDesired, int cyDesired, UINT fuLoad = 0) - { - ATLASSERT(m_hCursor == NULL); - m_hCursor = (HCURSOR) ::LoadImage(ModuleHelper::GetResourceInstance(), cursor.m_lpstr, IMAGE_CURSOR, cxDesired, cyDesired, fuLoad); - return m_hCursor; - } - -#ifndef _WIN32_WCE - HCURSOR LoadCursorFromFile(LPCTSTR pstrFilename) - { - ATLASSERT(m_hCursor == NULL); - ATLASSERT(pstrFilename != NULL); - m_hCursor = ::LoadCursorFromFile(pstrFilename); - return m_hCursor; - } -#endif // !_WIN32_WCE - -#if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))) - HCURSOR CreateCursor(int xHotSpot, int yHotSpot, int nWidth, int nHeight, CONST VOID *pvANDPlane, CONST VOID *pvXORPlane) - { - ATLASSERT(m_hCursor == NULL); - m_hCursor = ::CreateCursor(ModuleHelper::GetResourceInstance(), xHotSpot, yHotSpot, nWidth, nHeight, pvANDPlane, pvXORPlane); - return m_hCursor; - } -#endif // !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))) - -#ifndef _WIN32_WCE - HCURSOR CreateCursorFromResource(PBYTE pBits, DWORD dwResSize, DWORD dwVersion = 0x00030000) - { - ATLASSERT(m_hCursor == NULL); - ATLASSERT(pBits != NULL); - m_hCursor = (HCURSOR)::CreateIconFromResource(pBits, dwResSize, FALSE, dwVersion); - return m_hCursor; - } - - HCURSOR CreateCursorFromResourceEx(PBYTE pbBits, DWORD cbBits, DWORD dwVersion = 0x00030000, int cxDesired = 0, int cyDesired = 0, UINT uFlags = LR_DEFAULTCOLOR) - { - ATLASSERT(m_hCursor == NULL); - ATLASSERT(pbBits != NULL); - ATLASSERT(cbBits > 0); - m_hCursor = (HCURSOR)::CreateIconFromResourceEx(pbBits, cbBits, FALSE, dwVersion, cxDesired, cyDesired, uFlags); - return m_hCursor; - } -#endif // !_WIN32_WCE - - BOOL DestroyCursor() - { - ATLASSERT(m_hCursor != NULL); -#if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))) - BOOL bRet = ::DestroyCursor(m_hCursor); - if(bRet != FALSE) - m_hCursor = NULL; - return bRet; -#else // !(!defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)))) - ATLTRACE2(atlTraceUI, 0, _T("Warning: This version of Windows CE does not have ::DestroyCursor()\n")); - return FALSE; -#endif // !(!defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)))) - } - -// Operations -#ifndef _WIN32_WCE - HCURSOR CopyCursor() - { - ATLASSERT(m_hCursor != NULL); - return (HCURSOR)::CopyIcon((HICON)m_hCursor); - } -#endif // !_WIN32_WCE - -#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) - BOOL GetCursorInfo(LPCURSORINFO pCursorInfo) - { - ATLASSERT(m_hCursor != NULL); - ATLASSERT(pCursorInfo != NULL); - return ::GetCursorInfo(pCursorInfo); - } -#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) -}; - -typedef CCursorT CCursorHandle; -typedef CCursorT CCursor; - - -/////////////////////////////////////////////////////////////////////////////// -// CResource - Wraps a generic Windows resource. -// Use it with custom resource types other than the -// standard RT_CURSOR, RT_BITMAP, etc. - -class CResource -{ -public: - HGLOBAL m_hGlobal; - HRSRC m_hResource; - -// Constructor/destructor - CResource() : m_hGlobal(NULL), m_hResource(NULL) - { } - - ~CResource() - { - Release(); - } - -// Load methods - bool Load(ATL::_U_STRINGorID Type, ATL::_U_STRINGorID ID) - { - ATLASSERT(m_hResource == NULL); - ATLASSERT(m_hGlobal == NULL); - - m_hResource = ::FindResource(ModuleHelper::GetResourceInstance(), ID.m_lpstr, Type.m_lpstr); - if(m_hResource == NULL) - return false; - - m_hGlobal = ::LoadResource(ModuleHelper::GetResourceInstance(), m_hResource); - if(m_hGlobal == NULL) - { - m_hResource = NULL; - return false; - } - - return true; - } - -#ifndef _WIN32_WCE - bool LoadEx(ATL::_U_STRINGorID Type, ATL::_U_STRINGorID ID, WORD wLanguage) - { - ATLASSERT(m_hResource == NULL); - ATLASSERT(m_hGlobal == NULL); - - m_hResource = ::FindResourceEx(ModuleHelper::GetResourceInstance(), ID.m_lpstr, Type.m_lpstr, wLanguage); - if(m_hResource == NULL) - return false; - - m_hGlobal = ::LoadResource(ModuleHelper::GetResourceInstance(), m_hResource); - if(m_hGlobal == NULL) - { - m_hResource = NULL; - return false; - } - - return true; - } -#endif // !_WIN32_WCE - -// Misc. operations - DWORD GetSize() const - { - ATLASSERT(m_hResource != NULL); - return ::SizeofResource(ModuleHelper::GetResourceInstance(), m_hResource); - } - - LPVOID Lock() - { - ATLASSERT(m_hResource != NULL); - ATLASSERT(m_hGlobal != NULL); - LPVOID pVoid = ::LockResource(m_hGlobal); - ATLASSERT(pVoid != NULL); - return pVoid; - } - - void Release() - { - if(m_hGlobal != NULL) - { - FreeResource(m_hGlobal); - m_hGlobal = NULL; - m_hResource = NULL; - } - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// Toolbar resource descriptor - -struct _AtlToolBarData -{ - WORD wVersion; - WORD wWidth; - WORD wHeight; - WORD wItemCount; - - WORD* items() - { return (WORD*)(this+1); } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// Global functions for loading resources - -inline HACCEL AtlLoadAccelerators(ATL::_U_STRINGorID table) -{ - return ::LoadAccelerators(ModuleHelper::GetResourceInstance(), table.m_lpstr); -} - -inline HMENU AtlLoadMenu(ATL::_U_STRINGorID menu) -{ - return ::LoadMenu(ModuleHelper::GetResourceInstance(), menu.m_lpstr); -} - -inline HBITMAP AtlLoadBitmap(ATL::_U_STRINGorID bitmap) -{ - return ::LoadBitmap(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr); -} - -#ifdef OEMRESOURCE -inline HBITMAP AtlLoadSysBitmap(ATL::_U_STRINGorID bitmap) -{ -#ifdef _DEBUG - WORD wID = (WORD)bitmap.m_lpstr; - ATLASSERT(wID >= 32734 && wID <= 32767); -#endif // _DEBUG - return ::LoadBitmap(NULL, bitmap.m_lpstr); -} -#endif // OEMRESOURCE - -inline HCURSOR AtlLoadCursor(ATL::_U_STRINGorID cursor) -{ - return ::LoadCursor(ModuleHelper::GetResourceInstance(), cursor.m_lpstr); -} - -inline HCURSOR AtlLoadSysCursor(LPCTSTR lpCursorName) -{ -#if (WINVER >= 0x0500) - ATLASSERT(lpCursorName == IDC_ARROW || lpCursorName == IDC_IBEAM || lpCursorName == IDC_WAIT || - lpCursorName == IDC_CROSS || lpCursorName == IDC_UPARROW || lpCursorName == IDC_SIZE || - lpCursorName == IDC_ICON || lpCursorName == IDC_SIZENWSE || lpCursorName == IDC_SIZENESW || - lpCursorName == IDC_SIZEWE || lpCursorName == IDC_SIZENS || lpCursorName == IDC_SIZEALL || - lpCursorName == IDC_NO || lpCursorName == IDC_APPSTARTING || lpCursorName == IDC_HELP || - lpCursorName == IDC_HAND); -#else // !(WINVER >= 0x0500) - ATLASSERT(lpCursorName == IDC_ARROW || lpCursorName == IDC_IBEAM || lpCursorName == IDC_WAIT || - lpCursorName == IDC_CROSS || lpCursorName == IDC_UPARROW || lpCursorName == IDC_SIZE || - lpCursorName == IDC_ICON || lpCursorName == IDC_SIZENWSE || lpCursorName == IDC_SIZENESW || - lpCursorName == IDC_SIZEWE || lpCursorName == IDC_SIZENS || lpCursorName == IDC_SIZEALL || - lpCursorName == IDC_NO || lpCursorName == IDC_APPSTARTING || lpCursorName == IDC_HELP); -#endif // !(WINVER >= 0x0500) - return ::LoadCursor(NULL, lpCursorName); -} - -inline HICON AtlLoadIcon(ATL::_U_STRINGorID icon) -{ - return ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr); -} - -#ifndef _WIN32_WCE -inline HICON AtlLoadSysIcon(LPCTSTR lpIconName) -{ -#if (WINVER >= 0x0600) - ATLASSERT(lpIconName == IDI_APPLICATION || lpIconName == IDI_ASTERISK || lpIconName == IDI_EXCLAMATION || - lpIconName == IDI_HAND || lpIconName == IDI_QUESTION || lpIconName == IDI_WINLOGO || - lpIconName == IDI_SHIELD); -#else // !(WINVER >= 0x0600) - ATLASSERT(lpIconName == IDI_APPLICATION || lpIconName == IDI_ASTERISK || lpIconName == IDI_EXCLAMATION || - lpIconName == IDI_HAND || lpIconName == IDI_QUESTION || lpIconName == IDI_WINLOGO); -#endif // !(WINVER >= 0x0600) - return ::LoadIcon(NULL, lpIconName); -} -#endif // !_WIN32_WCE - -inline HBITMAP AtlLoadBitmapImage(ATL::_U_STRINGorID bitmap, UINT fuLoad = LR_DEFAULTCOLOR) -{ - return (HBITMAP)::LoadImage(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr, IMAGE_BITMAP, 0, 0, fuLoad); -} - -inline HCURSOR AtlLoadCursorImage(ATL::_U_STRINGorID cursor, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0) -{ - return (HCURSOR)::LoadImage(ModuleHelper::GetResourceInstance(), cursor.m_lpstr, IMAGE_CURSOR, cxDesired, cyDesired, fuLoad); -} - -inline HICON AtlLoadIconImage(ATL::_U_STRINGorID icon, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0) -{ - return (HICON)::LoadImage(ModuleHelper::GetResourceInstance(), icon.m_lpstr, IMAGE_ICON, cxDesired, cyDesired, fuLoad); -} - -#ifdef OEMRESOURCE -inline HBITMAP AtlLoadSysBitmapImage(WORD wBitmapID, UINT fuLoad = LR_DEFAULTCOLOR) -{ - ATLASSERT(wBitmapID >= 32734 && wBitmapID <= 32767); - ATLASSERT((fuLoad & LR_LOADFROMFILE) == 0); // this one doesn't load from a file - return (HBITMAP)::LoadImage(NULL, MAKEINTRESOURCE(wBitmapID), IMAGE_BITMAP, 0, 0, fuLoad); -} -#endif // OEMRESOURCE - -inline HCURSOR AtlLoadSysCursorImage(ATL::_U_STRINGorID cursor, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0) -{ -#ifdef _DEBUG - WORD wID = (WORD)cursor.m_lpstr; - ATLASSERT((wID >= 32512 && wID <= 32516) || (wID >= 32640 && wID <= 32648) || (wID == 32650) || (wID == 32651)); - ATLASSERT((fuLoad & LR_LOADFROMFILE) == 0); // this one doesn't load from a file -#endif // _DEBUG - return (HCURSOR)::LoadImage(NULL, cursor.m_lpstr, IMAGE_CURSOR, cxDesired, cyDesired, fuLoad); -} - -inline HICON AtlLoadSysIconImage(ATL::_U_STRINGorID icon, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0) -{ -#ifdef _DEBUG - WORD wID = (WORD)icon.m_lpstr; - ATLASSERT(wID >= 32512 && wID <= 32517); - ATLASSERT((fuLoad & LR_LOADFROMFILE) == 0); // this one doesn't load from a file -#endif // _DEBUG - return (HICON)::LoadImage(NULL, icon.m_lpstr, IMAGE_ICON, cxDesired, cyDesired, fuLoad); -} - -#if (_ATL_VER < 0x0700) -inline int AtlLoadString(UINT uID, LPTSTR lpBuffer, int nBufferMax) -{ - return ::LoadString(ModuleHelper::GetResourceInstance(), uID, lpBuffer, nBufferMax); -} -#else - -using ATL::AtlLoadString; - -#endif // (_ATL_VER < 0x0700) - -#ifdef _WIN32_WCE // CE only direct access to the resource -inline LPCTSTR AtlLoadString(UINT uID) -{ - LPCTSTR s = (LPCTSTR)::LoadString(ModuleHelper::GetResourceInstance(), uID, NULL, 0); -#ifdef DEBUG // Check for null-termination - if(s != NULL) - // Note: RC -n compiles null-terminated resource strings - ATLASSERT(s[*((WORD*)s -1) - 1] == L'\0'); -#endif - return s; -} -#endif // _WIN32_WCE - -inline bool AtlLoadString(UINT uID, BSTR& bstrText) -{ - USES_CONVERSION; - ATLASSERT(bstrText == NULL); - - LPTSTR lpstrText = NULL; - int nRes = 0; - for(int nLen = 256; ; nLen *= 2) - { - ATLTRY(lpstrText = new TCHAR[nLen]); - if(lpstrText == NULL) - break; - nRes = ::LoadString(ModuleHelper::GetResourceInstance(), uID, lpstrText, nLen); - if(nRes < nLen - 1) - break; - delete [] lpstrText; - lpstrText = NULL; - } - - if(lpstrText != NULL) - { - if(nRes != 0) - bstrText = ::SysAllocString(T2OLE(lpstrText)); - delete [] lpstrText; - } - - return (bstrText != NULL) ? true : false; -} - -}; // namespace WTL - -#endif // __ATLUSER_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlwince.h b/!NotAdopted/SmartAutoReplier/wtl/atlwince.h deleted file mode 100644 index a845949217..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlwince.h +++ /dev/null @@ -1,2987 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLWINCE_H__ -#define __ATLWINCE_H__ - -#pragma once - -#ifndef __ATLAPP_H__ - #error atlwince.h requires atlapp.h to be included first -#endif - -#ifndef __ATLWIN_H__ - #error atlwince.h requires atlwin.h to be included first -#endif - -#ifndef _WIN32_WCE - #error atlwince.h compiles under Windows CE only -#endif - -#if (_WIN32_WCE < 300) - #error atlwince.h requires Windows CE 3.0 or higher. -#endif - -#if defined(WIN32_PLATFORM_WFSP) && _MSC_VER < 1400 // EVC compiling SmartPhone code - #if (WIN32_PLATFORM_WFSP < 200) - #error atlwince.h requires Smartphone 2003 or higher - #endif -#endif // WIN32_PLATFORM_WFSP - -#if defined(WIN32_PLATFORM_PSPC) && _MSC_VER < 1400 // EVC compiling Pocket PC code - #if (WIN32_PLATFORM_PSPC < 310) - #error atlwince.h requires Pocket PC 2002 or higher - #endif -#endif // WIN32_PLATFORM_PSPC - -#if !defined(_AYGSHELL_H_) && !defined(__AYGSHELL_H__) - #error atlwince.h requires aygshell.h to be included first -#else - #if defined(WIN32_PLATFORM_WFSP) && !defined(_TPCSHELL_H_) - #error SmartPhone dialog classes require tpcshell.h to be included first - #endif -#endif - -#if (_MSC_VER >= 1400) // VS2005 - #include - #define _WTL_CE_DRA -#endif // (_MSC_VER >= 1400) - -#if !defined(_WTL_CE_NO_DIALOGS) && !defined(__ATLFRAME_H__) - #error Orientation aware dialog classes require atlframe.h to be included first -#endif - -#if !defined(_WTL_CE_NO_APPWINDOW) && !defined(__ATLFRAME_H__) - #error Application window class require atlframe.h to be included first -#endif - -#if !defined(_WTL_CE_NO_ZOOMSCROLL) && !defined(__ATLSCRL_H__) - #error ZoomScroll implementation requires atlscrl.h to be included first -#endif - -#if !defined(_WTL_CE_NO_ZOOMSCROLL) - #if !(defined(__ATLTYPES_H__) || (defined(__ATLMISC_H__) && !defined(_WTL_NO_WTYPES))) - #error ZoomScroll requires _WTL_NO_WTYPES not to be defined and either atlmisc.h or atltypes.h to be included first - #endif // !(defined(__ATLTYPES_H__) || (defined(__ATLMISC_H__) && !defined(_WTL_NO_WTYPES))) -#endif // !defined(_WTL_CE_NO_ZOOMSCROLL) - -#if !defined(WIN32_PLATFORM_WFSP) && !defined(WIN32_PLATFORM_PSPC) - #define _WTL_CE_NO_CONTROLS -#endif // !defined(WIN32_PLATFORM_WFSP) && !defined(WIN32_PLATFORM_PSPC) - -#ifndef _WTL_CE_NO_CONTROLS - #ifndef __ATLCTRLS_H__ - #error The PPC/SmartPhone controls classes require atlctrls.h to be included first - #endif - - #include - #pragma comment(lib, "htmlview.lib") - - #include - #pragma comment(lib, "voicectl.lib") - - #ifdef WIN32_PLATFORM_PSPC - #include - #pragma comment(lib, "richink.lib") - - #include - #pragma comment(lib, "inkx.lib") - - #include - #pragma comment(lib, "doclist.lib") - #endif -#endif - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// CStdDialogBase : Standard PPC/SmartPhone dialog base class -// CStdDialogImplBase - Base implementation of standard dialog -// CStdDialogImpl : Standard dialog implementation -// CStdIndirectDialogImpl - implementation of standard indirect PPC/SmartPhone dialog -// CStdAxDialogImpl : Standard AxDialog implementation -// CStdSimpleDialog : Standard simple dialog -// CStdDialogResizeImplBase - Base implementation of orientation resizing standard dialog -// CStdDialogResizeImpl : Orientation resizing standard dialog implementation -// CStdAxDialogResizeImpl - implementation of orientation resizing standard AxDialog -// CStdSimpleDialogResizeImpl : Standard resizing simple dialog implementation -// CStdOrientedDialogBase - Oriented PPC standard dialog base class -// CStdOrientedDialogImplBase - Oriented PPC standard dialog base implementation -// CStdOrientedDialogImpl : Oriented PPC standard dialog implementation -// CStdAxOrientedDialogImpl - Oriented PPC standard AxDialog implementation -// CStdSimpleOrientedDialog : Standard simple orientable dialog -// -// CAppInfoBase : Helper for application state save/restore to registry -// CAppInfoT : CAppInfoBase constructed from a CAppWindow -// CAppWindowBase : Base class for PPC/SmartPhone well-behaved application window or dialog -// CAppWindow : PPC/SmartPhone well-behaved application window class -// CAppDialog : PPC/SmartPhone well-behaved application dialog class -// CAppStdDialogImplBase - Base implementation of standard application dialogs -// CAppStdDialogImpl : Implementation of standard application dialog -// CAppStdDialogResizeImpl - implementation of orientation resizing standard application dialog -// CAppStdAxDialogImpl - Implementation of standard application AxDialog -// CAppStdAxDialogResizeImpl - implementation of orientation resizing standard application AxDialog -// CAppStdOrientedDialogImpl - implementation of oriented PPC standard application dialog -// CAppStdAxOrientedDialogImpl - implementation of oriented PPC standard application AxDialog -// -// CFullScreenFrame : Full screen frame class -// -// CZoomScrollImpl : WinCE zooming implementation -// -// CBottomTabViewImpl - CBottomTabView -// CHtmlCtrlT - CHtmlCtrl -// CRichInkCtrlT - CRichInkCtrl -// CInkXCtrlT - CInkXCtrl -// CVoiceRecorderCtrlT - CVoiceRecorderCtrl -// CDocListCtrlT - CDocListCtrl -// CCapEditT - CCapEdit -// CTTStaticT - CTTStatic -// CTTButtonT - CTTButton -// -// CSpinCtrlT - CSpinCtrl : SmartPhone specific UpDown control -// CSpinned : SmartPhone association of control and Spin -// CSpinListBox : SmartPhone spinned ListBox control -// CExpandListBox : SmartPhone expandable ListBox control -// CExpandEdit : SmartPhone expandable Edit control -// CExpandCapEdit : SmartPhone expandable CapEdit control -// -// Global functions: -// AtlCreateMenuBar() -// AtlCreateEmptyMenuBar() -// AtlIsEditFocus() -// AtlActivateBackKey() - -namespace WTL -{ - -/////////////////////////////////////////////////////////////////////////////// -// MenuBar creation functions for property sheets and dialogs -// Frame windows use CreateSimpleCEMenuBar - -inline HWND AtlCreateMenuBar(SHMENUBARINFO& mbi) -{ - ATLASSERT(::IsWindow(mbi.hwndParent)); - ATLVERIFY(::SHCreateMenuBar(&mbi) != FALSE); - return mbi.hwndMB; -}; - -inline HWND AtlCreateMenuBar(HWND hWnd, UINT nToolBarId = ATL_IDW_TOOLBAR, DWORD dwFlags = 0, int nBmpId = 0, int cBmpImages = 0, COLORREF clrBk = 0) -{ - SHMENUBARINFO mbi = { sizeof(mbi), hWnd, dwFlags, nToolBarId, ModuleHelper::GetResourceInstance(), nBmpId, cBmpImages, 0, clrBk }; - return AtlCreateMenuBar(mbi); -} - -inline HWND AtlCreateEmptyMenuBar(HWND hWnd, bool bSip = true) -{ - SHMENUBARINFO embi = { sizeof(SHMENUBARINFO), hWnd, SHCMBF_EMPTYBAR }; - if (!bSip) - embi.dwFlags |= SHCMBF_HIDESIPBUTTON; - - return AtlCreateMenuBar(embi); -} - -/////////////////////////////////////////////////////////////////////////////// -// Helper functions for SmartPhone back key handling - -inline bool AtlIsEditFocus() -{ - ATL::CWindow wCtrl = GetFocus(); - if (wCtrl.IsWindow()) - { - TCHAR szClassName[8] = {0}; - ATLVERIFY(::GetClassName(wCtrl.m_hWnd, szClassName, 8)); - return !_tcscmp(szClassName, _T("Edit")) || !_tcscmp(szClassName, WC_CAPEDIT); - } - return false; -} - -#if defined WIN32_PLATFORM_WFSP -inline void AtlActivateBackKey(HWND hMenuBar) -{ - ATLASSERT(::IsWindow(hMenuBar)); - ::SendMessage(hMenuBar, SHCMBM_OVERRIDEKEY, VK_TBACK, - MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, SHMBOF_NODEFAULT | SHMBOF_NOTIFY)); -} -#endif // WIN32_PLATFORM_WFSP - -// --- Standard PPC/SmartPhone dialogs --- - -#ifndef _WTL_CE_NO_DIALOGS - -/////////////////////////////////////////////////////////////////////////////// -// CStdDialogBase - base class for standard PPC/SmartPhone dialogs - -#define WTL_STD_SHIDIF SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN -#define WTL_SP_SHIDIF SHIDIF_SIZEDLGFULLSCREEN - -// Title setting macros -#define WTL_DLG_TITLEHEIGHT(iHeight) static const int GetTitleHeight(){return iHeight;} -#define WTL_DLG_NOTITLE WTL_DLG_TITLEHEIGHT(0) - -/////////////////////////////////////////////////////////////////////////////// -// CStdDialogBase - Base class for standard PPC/SmartPhone dialog - -template -class CStdDialogBase -{ -public: -#ifdef WIN32_PLATFORM_PSPC -// Pocket PC only Dialog title handling - const int nTitleHeight; - - CStdDialogBase() : nTitleHeight(T::GetTitleHeight()) - { } - -// Overloads - BOOL GetClientRect(LPRECT lpRect) - { - T* pT = static_cast(this); - ATLASSERT(pT->IsWindow()); - BOOL bRes = ::GetClientRect(pT->m_hWnd, lpRect); - if (nTitleHeight) - lpRect->top += nTitleHeight + 1; - return bRes; - } - - BOOL SetWindowText(LPCTSTR lpszString) - { - T* pT = static_cast(this); - ATLASSERT(pT->IsWindow()); - BOOL bRes = ::SetWindowText(pT->m_hWnd, lpszString); - if (nTitleHeight != 0) - pT->DoPaintTitle(); - return bRes; - } - -// Overrideables - static const int GetTitleHeight() - { - #ifdef _WTL_CE_DRA - return DRA::SCALEY(24); - #else // !_WTL_CE_DRA - CWindowDC dc(NULL); - return dc.GetDeviceCaps(LOGPIXELSY) >> 2; // LOGPIXELSY * 24 / 96, - #endif // !_WTL_CE_DRA - } - - // Title painting - bool DoPaintTitle() - { - T* pT = static_cast(this); - ATLASSERT(pT->IsWindow()); - TCHAR sTitle[48]; - - // Preparation - CPaintDC dc(pT->m_hWnd); - CFont fontTitle = AtlCreateBoldFont(); - CFontHandle fontOld = dc.SelectFont(fontTitle); - dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHT)); - int nLen = pT->GetWindowText(sTitle, 48); - int nWidth = dc.GetDeviceCaps(HORZRES); - - // Display title text - RECT rTitle = { 0, 0, nWidth, nTitleHeight }; - dc.FillRect(&rTitle, COLOR_3DHIGHLIGHT); - #ifdef _WTL_CE_DRA - rTitle.left = DRA::SCALEX(8); - #else // !_WTL_CE_DRA - rTitle.left = nTitleHeight / 3; // 8 == 24 / 3 - #endif // !_WTL_CE_DRA - dc.DrawText(sTitle, nLen, &rTitle, DT_VCENTER | DT_SINGLELINE); - dc.SelectFont(fontOld); - - // Draw bottom line, 2 pixels thick if HI_RES_AWARE - CPenHandle penOld = dc.SelectStockPen(BLACK_PEN); - POINT line[4] = {{0, nTitleHeight}, {nWidth, nTitleHeight}, {0, nTitleHeight - 1}, {nWidth, nTitleHeight - 1}}; - - #ifdef _WTL_CE_DRA - int nSeg = DRA::SCALEY(1); - #else // !_WTL_CE_DRA - int nSeg = nTitleHeight / 24; - #endif // !_WTL_CE_DRA - - dc.Polyline(line, nSeg <= 2 ? nSeg * 2 : 4); - dc.SelectPen(penOld); - - return false; - } - - // Title preparation: move the dialog controls down to make room for title - void DialogTitleInit() - { - T* pT = static_cast(this); - ATLASSERT(pT->IsWindow()); - - ATL::CWindow wCtl = pT->GetWindow(GW_CHILD); - while (wCtl.IsWindow()) - { - RECT rCtl = { 0 }; - wCtl.GetWindowRect(&rCtl); - ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rCtl, 2); - ::OffsetRect(&rCtl, 0, nTitleHeight); - wCtl.MoveWindow(&rCtl, FALSE); - wCtl = wCtl.GetWindow(GW_HWNDNEXT); - } - } - - // SIP management - void DoSipInfo() - { - T* pT = static_cast(this); - ATLASSERT(pT->IsWindow()); - - SIPINFO si = {sizeof(SIPINFO)}; - SipGetInfo(&si); - if ((si.fdwFlags & SIPF_ON) ^ SIPF_ON) - si.rcVisibleDesktop.bottom = si.rcSipRect.bottom; - pT->MoveWindow(&si.rcVisibleDesktop, FALSE); - } - -// Title painting handler - LRESULT OnPaintTitle(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - T* pT = static_cast(this); - return bHandled = nTitleHeight ? pT->DoPaintTitle() : FALSE; - } - -// SIP handler - LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - T* pT = static_cast(this); - if (wParam == SPI_SETSIPINFO) - { - pT->DoSipInfo(); - return TRUE; - } - return bHandled = FALSE; - } - -#elif defined WIN32_PLATFORM_WFSP -// SmartPhone VK_TBACK key standard management - LRESULT OnHotKey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - const UINT uModif = (UINT)LOWORD(lParam); - const UINT uVirtKey = (UINT)HIWORD(lParam); - - if(uVirtKey == VK_TBACK) - if (AtlIsEditFocus()) - ::SHSendBackToFocusWindow(uMsg, wParam, lParam); - else if (uModif & MOD_KEYUP) - pT->StdCloseDialog(IDCANCEL); - return 1; - } - - // SmartPhone MenuBar and VK_TBACK key initialization - void StdSPInit() - { - T* pT = static_cast(this); - HWND hMenuBar = ::SHFindMenuBar(pT->m_hWnd); - - if (!hMenuBar && (t_shidiFlags & SHIDIF_DONEBUTTON)) - hMenuBar = CreateMenuBar(ATL_IDM_MENU_DONE); - - if(hMenuBar != NULL) - AtlActivateBackKey(hMenuBar); - } - - void SetStaticBold() - { - T* pT = static_cast(this); - ATLASSERT(pT->IsWindow()); - - CFontHandle fontBold = AtlCreateBoldFont(pT->GetFont()); - - ATL::CWindow wCtl = pT->GetWindow(GW_CHILD); - - while (wCtl.IsWindow()) - { - if ((short int)wCtl.GetDlgCtrlID() == IDC_STATIC) - wCtl.SetFont(fontBold); - wCtl = wCtl.GetWindow(GW_HWNDNEXT); - } - } -#endif // WIN32_PLATFORM_WFSP - -// Platform dependant initialization - void StdPlatformInit() - { - T* pT = static_cast(this); -#ifdef WIN32_PLATFORM_PSPC // Pocket PC title initialization - if (nTitleHeight != 0) - pT->DialogTitleInit(); -#elif defined(WIN32_PLATFORM_WFSP) - pT->StdSPInit(); - SetStaticBold(); -#endif // WIN32_PLATFORM_WFSP - } - - // Menu bar creation - HWND CreateMenuBar(UINT uiMB = T::IDD, int nBmpImages = 0) - { - T* pT = static_cast(this); - return AtlCreateMenuBar(pT->m_hWnd, uiMB, 0, nBmpImages ? uiMB : 0, nBmpImages); - } - - // Dialog closing - void StdCloseDialog(WORD wID) - { - T* pT = static_cast(this); - if (t_bModal) - ::EndDialog(pT->m_hWnd, wID); - else - pT->DestroyWindow(); - } - - // Shell dialog layout initialization - void StdShidInit() - { - T* pT = static_cast(this); - SHINITDLGINFO shidi = { SHIDIM_FLAGS, pT->m_hWnd, t_shidiFlags }; - ::SHInitDialog(&shidi); - } - -// IDC_INFOSTATIC background setting - LRESULT OnColorStatic(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - if (::GetDlgCtrlID((HWND)lParam) == IDC_INFOSTATIC) - { - ::SetBkMode((HDC)wParam, TRANSPARENT); - return (LRESULT)::GetSysColorBrush(COLOR_INFOBK); - } - return bHandled = FALSE; - } - -// Menu dialog ending - LRESULT OnMenuClose(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->StdCloseDialog((WORD)(wID - ID_MENU_OK + IDOK)); - return 0; - } - -// Standard dialog ending: may be used with any command - LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->StdCloseDialog(wID); - return 0; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CStdDialogImplBase - Base implementation of standard PPC/SmartPhone dialog - -template > -class ATL_NO_VTABLE CStdDialogImplBase : - public TBase, - public CStdDialogBase -{ -public: -#ifdef WIN32_PLATFORM_PSPC - BOOL GetClientRect(LPRECT lpRect) - { - return CStdDialogBase::GetClientRect(lpRect); - } - - BOOL SetWindowText(LPCTSTR lpszString) - { - return CStdDialogBase::SetWindowText(lpszString); - } -#endif - - BEGIN_MSG_MAP(CStdDialogImplBase) -#ifdef WIN32_PLATFORM_PSPC // Pocket PC title and SIP - MESSAGE_HANDLER(WM_PAINT, OnPaintTitle) - MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) -#elif defined(WIN32_PLATFORM_WFSP) // SmartPhone VK_TBACK key - MESSAGE_HANDLER(WM_HOTKEY, OnHotKey) -#endif - MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, OnCloseCmd) - COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose) - END_MSG_MAP() - - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { -#ifdef _DEBUG - T* pT = static_cast(this); - ATLASSERT(t_bModal == pT->m_bModal); -#endif - StdPlatformInit(); - StdShidInit(); - return bHandled = FALSE; - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// CStdDialogImpl - implementation of standard PPC/SmartPhone dialog - -template -class ATL_NO_VTABLE CStdDialogImpl : public CStdDialogImplBase< T, t_shidiFlags, t_bModal> -{}; - -/////////////////////////////////////////////////////////////////////////////// -// CStdIndirectDialogImpl - implementation of standard indirect PPC/SmartPhone dialog - -#if defined __ATLDLGS_H__ - -template -class ATL_NO_VTABLE CStdIndirectDialogImpl : - public CIndirectDialogImpl< T, CMemDlgTemplate, CStdDialogImpl > -{ -public: - typedef CIndirectDialogImpl< T, CMemDlgTemplate, CStdDialogImpl > _baseClass; - typedef CStdDialogImpl _baseStd; - - void CheckStyle() - { - // Mobile devices don't support DLGTEMPLATEEX - ATLASSERT(!m_Template.IsTemplateEx()); - - // Standard dialogs need only DS_CENTER - DWORD &dwStyle = m_Template.GetTemplatePtr()->style; - if (dwStyle & DS_CENTER) - if(t_bModal) - { - ATLASSERT((dwStyle & WS_CHILD) != WS_CHILD); - dwStyle |= WS_POPUP; - } - else - { - if((dwStyle & WS_CHILD) != WS_CHILD) - dwStyle |= WS_POPUP; - } - } - - INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow(), LPARAM dwInitParam = NULL) - { - ATLASSERT(t_bModal); - - if (!m_Template.IsValid()) - CreateTemplate(); - - CheckStyle(); - - return _baseClass::DoModal(hWndParent, dwInitParam); - } - - HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL) - { - ATLASSERT(!t_bModal); - - if (!m_Template.IsValid()) - CreateTemplate(); - - CheckStyle(); - - return _baseClass::Create(hWndParent, dwInitParam); - } - - BEGIN_MSG_MAP(CStdIndirectDialogImpl) - CHAIN_MSG_MAP(_baseStd) - END_MSG_MAP() - -}; - -#endif // defined __ATLDLGS_H__ - -#ifndef _ATL_NO_HOSTING - -/////////////////////////////////////////////////////////////////////////////// -// CStdAxDialogImpl - implementation of standard PPC/SmartPhone AxDialog - -template -class ATL_NO_VTABLE CStdAxDialogImpl : public CStdDialogImplBase< T, t_shidiFlags, t_bModal, ATL::CAxDialogImpl< T > > -{}; -#endif // _ATL_NO_HOSTING - -/////////////////////////////////////////////////////////////////////////////// -// CStdSimpleDialog - standard PPC/SmartPhone simple dialog with SHIDIF_xxx flags - -template -class CStdSimpleDialog : - public ATL::CSimpleDialog, - public CStdDialogBase, t_shidiFlags> -{ -public: - typedef CStdDialogBase, t_shidiFlags> baseClass; - -#ifdef WIN32_PLATFORM_PSPC - BOOL GetClientRect(LPRECT lpRect) - { - return baseClass::GetClientRect(lpRect); - } - - BOOL SetWindowText(LPCTSTR lpszString) - { - return baseClass::SetWindowText(lpszString); - } -#endif - - BEGIN_MSG_MAP(CStdSimpleDialog) -#ifdef WIN32_PLATFORM_PSPC // Pocket PC title and SIP - MESSAGE_HANDLER(WM_PAINT, OnPaintTitle) - MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) -#elif defined(WIN32_PLATFORM_WFSP) // SmartPhone VK_TBACK key - MESSAGE_HANDLER(WM_HOTKEY, OnHotKey) -#endif - MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose) - COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, baseClass::OnCloseCmd) - END_MSG_MAP() - - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - StdPlatformInit(); - StdShidInit(); - return bHandled = FALSE; - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// CStdDialogResizeImplBase - Base implementation of orientation resizing standard PPC/SmartPhone dialog - -template > -class ATL_NO_VTABLE CStdDialogResizeImplBase : - public CStdDialogImplBase< T, t_shidiFlags, t_bModal, TBase>, - public CDialogResize -{ -public: - // Note: BEGIN_DLGRESIZE_MAP is required in the derived class. - - BEGIN_MSG_MAP(CStdResizeDialogImplBase) -#ifdef WIN32_PLATFORM_PSPC // Pocket PC title - MESSAGE_HANDLER(WM_PAINT, OnPaintTitle) -#elif defined(WIN32_PLATFORM_WFSP) // SmartPhone VK_TBACK key - MESSAGE_HANDLER(WM_HOTKEY, OnHotKey) -#endif - MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, OnCloseCmd) - COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose) - CHAIN_MSG_MAP(CDialogResize< T >) - END_MSG_MAP() - - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { -#ifdef _DEBUG - T* pT = static_cast(this); - ATLASSERT(t_bModal == pT->m_bModal); -#endif - StdPlatformInit(); - DlgResize_Init(FALSE); - StdShidInit(); - return bHandled = FALSE; - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// CStdDialogResizeImpl - implementation of orientation resizing standard PPC/SmartPhone dialog - -template -class ATL_NO_VTABLE CStdDialogResizeImpl : public CStdDialogResizeImplBase< T, t_shidiFlags, t_bModal> -{}; - -#ifndef _ATL_NO_HOSTING - -/////////////////////////////////////////////////////////////////////////////// -// CStdAxDialogResizeImpl - implementation of orientation resizing standard PPC/SmartPhone AxDialog - -template -class ATL_NO_VTABLE CStdAxDialogResizeImpl : public CStdDialogResizeImplBase< T, t_shidiFlags, t_bModal, ATL::CAxDialogImpl > -{}; -#endif // _ATL_NO_HOSTING - -/////////////////////////////////////////////////////////////////////////////// -// CStdSimpleDialogResizeImpl - implementation of standard resizing simple dialog with SHIDIF_xxx flags - -// Usage: -// class CMyDlg : public CStdSimpleDialogResize -// { -// public: -// BEGIN_DLGRESIZE_MAP(CMyDlg) -// ... -// END_DLGRESIZE_MAP() -// }; - -template -class ATL_NO_VTABLE CStdSimpleDialogResizeImpl : - public CStdSimpleDialog, - public CDialogResize< T > -{ -public: - typedef CStdSimpleDialog::baseClass baseClass; - - BEGIN_MSG_MAP(CStdSimpleDialogResizeImpl) -#ifdef WIN32_PLATFORM_PSPC // Pocket PC title - MESSAGE_HANDLER(WM_PAINT, OnPaintTitle) -#elif defined(WIN32_PLATFORM_WFSP) // SmartPhone VK_TBACK key - MESSAGE_HANDLER(WM_HOTKEY, OnHotKey) -#endif - MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, baseClass::OnCloseCmd) - COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose) - CHAIN_MSG_MAP(CDialogResize< T >) - END_MSG_MAP() - - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - StdPlatformInit(); - DlgResize_Init(FALSE); - StdShidInit(); - return bHandled = FALSE; - } -}; - -#if defined(_WTL_CE_DRA) && defined(WIN32_PLATFORM_PSPC) - -/////////////////////////////////////////////////////////////////////////////// -// CStdOrientedDialogBase - Oriented PPC standard dialog base class - -template -class CStdOrientedDialogBase -{ -public: -// Operation - BOOL SetOrientation(DRA::DisplayMode mode) - { - T* pT = static_cast(this); - ATLASSERT(pT->IsWindow()); - ATLASSERT(mode == DRA::GetDisplayMode()); - - // Derived dialog must enumerate TWO dialog templates with the same control ids and types ie: - // enum { IDD = IDD_MYDLG, IDD_LANDSCAPE = IDD_MYDLG_L }; - UINT iResource = (mode == DRA::Landscape)? T::IDD_LANDSCAPE : T::IDD; - - BOOL bRes = DRA::RelayoutDialog(ModuleHelper::GetResourceInstance(), pT->m_hWnd, MAKEINTRESOURCE(iResource)); - pT->OnOrientation(mode); - return bRes; - } - -// Override - void OnOrientation(DRA::DisplayMode /*mode*/) - {} - -// Message handlers - LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - T* pT = static_cast(this); - ATLASSERT(pT->IsWindow()); - if (wParam == SETTINGCHANGE_RESET) - { - SetOrientation(DRA::GetDisplayMode()); - pT->StdPlatformInit(); - pT->StdShidInit(); - } - else if (wParam == SPI_SETSIPINFO) - { - pT->DoSipInfo(); - return TRUE; - } - return bHandled = FALSE; - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// CStdOrientedDialogImplBase - Oriented PPC standard dialog base implementation - -template > -class ATL_NO_VTABLE CStdOrientedDialogImplBase : - public CStdDialogImplBase< T, t_shidiFlags, t_bModal, TBase>, - public CStdOrientedDialogBase -{ -public: - BEGIN_MSG_MAP(CStdOrientedDialogImpl) - MESSAGE_HANDLER(WM_PAINT, OnPaintTitle) - MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic) - MESSAGE_HANDLER(WM_SETTINGCHANGE, CStdOrientedDialogBase::OnSettingChange) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, OnCloseCmd) - COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose) - END_MSG_MAP() - - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - T* pT = static_cast(this); -#ifdef _DEBUG - ATLASSERT(t_bModal == pT->m_bModal); -#endif - if (DRA::GetDisplayMode() == DRA::Landscape) - SetOrientation(DRA::Landscape); - pT->StdPlatformInit(); - pT->StdShidInit(); - return bHandled = FALSE; - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// CStdOrientedDialogImpl - Oriented PPC standard dialog implementation - -template -class ATL_NO_VTABLE CStdOrientedDialogImpl : public CStdOrientedDialogImplBase< T, t_shidiFlags, t_bModal> -{}; - -#ifndef _ATL_NO_HOSTING -/////////////////////////////////////////////////////////////////////////////// -// CStdAxOrientedDialogImpl - Oriented PPC standard AxDialog implementation - -template -class ATL_NO_VTABLE CStdAxOrientedDialogImpl : public CStdOrientedDialogImplBase< T, t_shidiFlags, t_bModal, ATL::CAxDialogImpl > -{}; -#endif // _ATL_NO_HOSTING - -/////////////////////////////////////////////////////////////////////////////// -// CStdSimpleOrientedDialog - Standard simple orientable dialog - -template -class CStdSimpleOrientedDialog : - public CStdSimpleDialog, - public CStdOrientedDialogBase > -{ -public: - typedef CStdSimpleDialog::baseClass baseClass; - typedef CStdOrientedDialogBase > baseOriented; - - enum {IDD = t_wDlgTemplateID, IDD_LANDSCAPE = t_wDlgLandscapeID}; - - BEGIN_MSG_MAP(CStdSimpleDialog) - MESSAGE_HANDLER(WM_PAINT, OnPaintTitle) - MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic) - MESSAGE_HANDLER(WM_SETTINGCHANGE, baseOriented::OnSettingChange) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, baseClass::OnCloseCmd) - COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose) - END_MSG_MAP() - - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - if (DRA::GetDisplayMode() == DRA::Landscape) - SetOrientation(DRA::Landscape); - StdPlatformInit(); - StdShidInit(); - return bHandled = FALSE; - } -}; - -#endif // _WTL_CE_DRA - - -#endif // _WTL_CE_NO_DIALOGS - - -// --- PPC/SmartPhone application window and helpers --- - -#ifndef _WTL_CE_NO_APPWINDOW - -/////////////////////////////////////////////////////////////////////////////// -// CAppInfoBase - Helper for application state save/restore to registry - -class CAppInfoBase -{ -public: - CRegKeyEx m_Key; - - CAppInfoBase(ATL::_U_STRINGorID sAppKey) - { - m_Key.Create(HKEY_CURRENT_USER, sAppKey.m_lpstr); - ATLASSERT(m_Key.m_hKey); - } - - template - LONG Save(V& val, ATL::_U_STRINGorID sName) - { - return m_Key.SetBinaryValue(sName.m_lpstr, &val, sizeof(V)); - } - - template - LONG Save(int nb, V& val0, ATL::_U_STRINGorID sName) - { - return m_Key.SetBinaryValue(sName.m_lpstr, &val0, nb * sizeof(V)); - } - - template - LONG Restore(V& val, ATL::_U_STRINGorID sName) - { - ULONG bufSize = sizeof(V); - return m_Key.QueryBinaryValue(sName.m_lpstr, &val, &bufSize); - } - - template - LONG Restore(int nb, V& val0, ATL::_U_STRINGorID sName) - { - ULONG bufSize = nb * sizeof(V); - return m_Key.QueryBinaryValue(sName.m_lpstr, &val0, &bufSize); - } - -#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - LONG Save(_CSTRING_NS::CString& sval, ATL::_U_STRINGorID sName) - { - return m_Key.SetStringValue(sName.m_lpstr, sval); - } - - LONG Restore(_CSTRING_NS::CString& sval, ATL::_U_STRINGorID sName) - { - DWORD size = MAX_PATH; - LONG res = m_Key.QueryStringValue(sName.m_lpstr, sval.GetBuffer(size), &size); - sval.ReleaseBuffer(); - return res; - } -#else - #pragma message("Warning: CAppInfoBase compiles without CString support. Do not use CString in Save or Restore.") -#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) - - LONG Save(LPCTSTR sval, ATL::_U_STRINGorID sName) - { - return m_Key.SetStringValue(sName.m_lpstr, sval); - } - - LONG Restore(LPTSTR sval, ATL::_U_STRINGorID sName, DWORD *plength) - { - return m_Key.QueryStringValue(sName.m_lpstr, sval, plength); - } - - LONG Delete(ATL::_U_STRINGorID sName) - { - return m_Key.DeleteValue(sName.m_lpstr); - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CAppInfoT - CAppInfoBase constructed from a class with T::GetAppKey() - -// Macro for declaring AppKey -#define DECLARE_APPKEY(uAppKey) \ - static LPCTSTR GetAppKey() \ - { \ - static LPCTSTR sAppKey = ATL::_U_STRINGorID(uAppKey).m_lpstr; \ - return sAppKey; \ - } - -template -class CAppInfoT : public CAppInfoBase -{ -public: - CAppInfoT() : CAppInfoBase(T::GetAppKey()){} -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CAppWindowBase - Base class for PPC/SmartPhone "well-behaved" application window or dialog - -// Macros for declaring frame WNDCLASS and AppKey -#define DECLARE_APP_FRAME_CLASS(WndClassName, uCommonResourceID, uAppKey) \ - DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) \ - DECLARE_APPKEY(uAppKey) - -#define DECLARE_APP_FRAME_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd, uAppKey) \ - DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd) \ - DECLARE_APPKEY(uAppKey) - -template -class CAppWindowBase -{ -public: - typedef class CAppInfoT< T > CAppInfo; - -#ifndef WIN32_PLATFORM_WFSP - SHACTIVATEINFO m_sai; // NoOp on SmartPhones -#endif // WIN32_PLATFORM_WFSP - - bool m_bHibernate; - - CAppWindowBase< T >() : m_bHibernate(false) - { -#ifndef WIN32_PLATFORM_WFSP - SHACTIVATEINFO sai = { sizeof(SHACTIVATEINFO) }; - m_sai = sai; -#endif // WIN32_PLATFORM_WFSP - }; - - // Same as WTL 7.1 AppWizard generated ActivatePreviousInstance + SendMessage WM_COPYDATA - static HRESULT ActivatePreviousInstance(HINSTANCE hInstance, LPCTSTR lpstrCmdLine, bool bDialog) - { - // requires T does DECLARE_APP_FRAME_CLASS, DECLARE_APP_FRAME_CLASS_EX or DECLARE_APP_DLG_CLASS - CFrameWndClassInfo& classInfo = T::GetWndClassInfo(); - - ATLVERIFY(::LoadString(hInstance, classInfo.m_uCommonResourceID, classInfo.m_szAutoName, sizeof(classInfo.m_szAutoName)/sizeof(classInfo.m_szAutoName[0])) != 0); - - classInfo.m_wc.lpszClassName = classInfo.m_szAutoName; - - const TCHAR* pszClass = classInfo.m_wc.lpszClassName; - - if(NULL == pszClass || '\0' == *pszClass) - { - return E_FAIL; - } - - const DWORD dRetryInterval = 100; - const int iMaxRetries = 25; - - for(int i = 0; i < iMaxRetries; ++i) - { - HANDLE hMutex = CreateMutex(NULL, FALSE, pszClass); - - DWORD dw = GetLastError(); - - if(NULL == hMutex) - { - HRESULT hr; - - switch(dw) - { - case ERROR_INVALID_HANDLE: - // A non-mutext object with this name already exists. - hr = E_INVALIDARG; - break; - default: - // This should never happen... - hr = E_FAIL; - } - - return hr; - } - - // If the mutex already exists, then there should be another instance running - if(dw == ERROR_ALREADY_EXISTS) - { - CloseHandle(hMutex); - - HWND hwnd = NULL; - if (bDialog) - hwnd = FindWindow(NULL, pszClass); - else - hwnd = FindWindow(pszClass, NULL); - - if(hwnd == NULL) - { - Sleep(dRetryInterval); - continue; - } - else - { - // Transmit our params to previous instance - if (lpstrCmdLine && *lpstrCmdLine) - { - COPYDATASTRUCT cd = { NULL, sizeof(TCHAR) * (wcslen(lpstrCmdLine) + 1), (PVOID)lpstrCmdLine }; - ::SendMessage(hwnd, WM_COPYDATA, NULL, (LPARAM)&cd); - } - // Set the previous instance as the foreground window - if(0 != SetForegroundWindow(reinterpret_cast(reinterpret_cast(hwnd) | 0x1))) - return S_FALSE; - } - } - else - { - return S_OK; - } - } - return S_OK; - } - -// Operations overriden in derived class - bool AppHibernate(bool /*bHibernate*/) - { - return false; - } - - bool AppNewInstance(LPCTSTR /*lpstrCmdLine*/) - { - return false; - } - - void AppSave() - { - } - -#ifdef WIN32_PLATFORM_WFSP - void AppBackKey() - { - ::SHNavigateBack(); - } -#endif - -// Message map and handlers - BEGIN_MSG_MAP(CAppWindowBase) - MESSAGE_HANDLER(WM_ACTIVATE, OnActivate) -#ifdef WIN32_PLATFORM_WFSP - MESSAGE_HANDLER(WM_HOTKEY, OnHotKey) -#else - MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) -#endif // WIN32_PLATFORM_WFSP - MESSAGE_HANDLER(WM_HIBERNATE, OnHibernate) - MESSAGE_HANDLER(WM_COPYDATA, OnNewInstance) - MESSAGE_HANDLER(WM_CLOSE, OnClose) - END_MSG_MAP() - - LRESULT OnActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - T* pT = static_cast(this); - if (m_bHibernate) - m_bHibernate = pT->AppHibernate(false); -#ifndef WIN32_PLATFORM_WFSP - ::SHHandleWMActivate(pT->m_hWnd, wParam, lParam, &m_sai, 0); -#else - wParam; - lParam; -#endif // WIN32_PLATFORM_WFSP - return bHandled = FALSE; - } - -#ifdef WIN32_PLATFORM_WFSP -// SmartPhone VK_TBACK key standard management - LRESULT OnHotKey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - const UINT uModif = (UINT)LOWORD(lParam); - const UINT uVirtKey = (UINT)HIWORD(lParam); - if(uVirtKey == VK_TBACK) - if (AtlIsEditFocus()) - ::SHSendBackToFocusWindow(uMsg, wParam, lParam); - else if (uModif & MOD_KEYUP) - pT->AppBackKey(); - return 1; - } - -#else // !WIN32_PLATFORM_WFSP -// PPC SIP handling - LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) - { - T* pT = static_cast(this); - bHandled = FALSE; - return ::SHHandleWMSettingChange(pT->m_hWnd, wParam, lParam, &m_sai); - } -#endif // !WIN32_PLATFORM_WFSP - - LRESULT OnHibernate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - return m_bHibernate = pT->AppHibernate(true); - } - - LRESULT OnNewInstance(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - PCOPYDATASTRUCT pcds = (PCOPYDATASTRUCT)lParam; - return pT->AppNewInstance((LPCTSTR)pcds->lpData); - } - - LRESULT OnClose(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) - { - T* pT = static_cast(this); - pT->AppSave(); - bHandled = FALSE; - return 1; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CAppWindow - PPC/SmartPhone "well-behaved" application window class - -template -class CAppWindow : public CAppWindowBase< T > -{ -public: - // Same as WTL 7.1 AppWizard generated Run + lpstrCmdLine in CreateEx - static int AppRun(LPTSTR lpstrCmdLine = NULL, int nCmdShow = SW_SHOWNORMAL) - { - CMessageLoop theLoop; - _Module.AddMessageLoop(&theLoop); - - T wndMain; - - if(wndMain.CreateEx(NULL, NULL, 0, 0, lpstrCmdLine) == NULL) - { - ATLTRACE2(atlTraceUI, 0, _T("Main window creation failed!\n")); - return 0; - } - - wndMain.ShowWindow(nCmdShow); - - int nRet = theLoop.Run(); - - _Module.RemoveMessageLoop(); - return nRet; - } - - static HRESULT ActivatePreviousInstance(HINSTANCE hInstance, LPCTSTR lpstrCmdLine) - { - return CAppWindowBase< T >::ActivatePreviousInstance(hInstance, lpstrCmdLine, false); - } -}; - - -#ifndef _WTL_CE_NO_DIALOGS - -/////////////////////////////////////////////////////////////////////////////// -// CAppDialog - PPC/SmartPhone "well-behaved" dialog application class - -// Macro for declaring dialog WNDCLASS and AppKey -#define DECLARE_APP_DLG_CLASS(WndClassName, uCommonResourceID, uAppKey) \ - static WTL::CFrameWndClassInfo& GetWndClassInfo() \ - { \ - static WTL::CFrameWndClassInfo wc = \ - { \ - { 0, (WNDPROC)StartDialogProc, \ - 0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndClassName }, \ - NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \ - }; \ - return wc; \ - }; \ - DECLARE_APPKEY(uAppKey) - -template -class CAppDialog : public CAppWindowBase< T > -{ -public: - static int AppRun(LPTSTR lpstrCmdLine = NULL, int nCmdShow = SW_SHOWNORMAL) - { - CMessageLoop theLoop; - _Module.AddMessageLoop(&theLoop); - - T dlgMain; - - if(dlgMain.Create(NULL, (LPARAM)lpstrCmdLine) == NULL) - { - ATLTRACE2(atlTraceUI, 0, _T("Main dialog creation failed!\n")); - return 0; - } - - dlgMain.ShowWindow(nCmdShow); - - int nRet = theLoop.Run(); - - _Module.RemoveMessageLoop(); - return nRet; - } - - static HRESULT ActivatePreviousInstance(HINSTANCE hInstance, LPCTSTR lpstrCmdLine) - { - return CAppWindowBase< T >::ActivatePreviousInstance(hInstance, lpstrCmdLine, true); - }; -}; - -// PPC/SmartPhone standard application dialogs - -#ifdef WIN32_PLATFORM_WFSP -#define WTL_APP_SHIDIF WTL_SP_SHIDIF -#else -#define WTL_APP_SHIDIF WTL_STD_SHIDIF -#endif - -/////////////////////////////////////////////////////////////////////////////// -// CAppStdDialogImplBase - Base implementation of standard application dialogs - -template -class ATL_NO_VTABLE CAppStdDialogImplBase : - public TImplBase, - public CAppDialog< T > -{ -public: - WTL_DLG_NOTITLE; - - void StdCloseDialog(int nVal) - { - T* pT = static_cast(this); - if (nVal != IDCANCEL) - pT->AppSave(); - if (t_bModal == false) - { - pT->DestroyWindow(); - ::PostQuitMessage(nVal); - } - else - ::EndDialog(pT->m_hWnd, nVal); - } - - BEGIN_MSG_MAP(CAppStdDialogImplBase) - MESSAGE_HANDLER(WM_CLOSE, OnSystemClose) - CHAIN_MSG_MAP(TImplBase) - CHAIN_MSG_MAP(CAppDialog< T >) - END_MSG_MAP() - - LRESULT OnSystemClose(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - { - T* pT = static_cast(this); - pT->StdCloseDialog(IDCANCEL); - return 0; - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// CAppStdDialogImpl - Implementation of standard application dialog - -template -class ATL_NO_VTABLE CAppStdDialogImpl : - public CAppStdDialogImplBase, t_shidiFlags, t_bModal> -{}; - -/////////////////////////////////////////////////////////////////////////////// -// CAppStdDialogResizeImpl - implementation of orientation resizing standard application dialog - -template -class ATL_NO_VTABLE CAppStdDialogResizeImpl : - public CAppStdDialogImplBase, t_shidiFlags, t_bModal> -{}; - -#ifndef _ATL_NO_HOSTING -/////////////////////////////////////////////////////////////////////////////// -// CAppStdAxDialogImpl - Implementation of standard application AxDialog - -template -class ATL_NO_VTABLE CAppStdAxDialogImpl : - public CAppStdDialogImplBase, t_shidiFlags, t_bModal> -{}; - -/////////////////////////////////////////////////////////////////////////////// -// CAppStdAxDialogResizeImpl - implementation of orientation resizing standard application AxDialog - -template -class ATL_NO_VTABLE CAppStdAxDialogResizeImpl : - public CAppStdDialogImplBase, t_shidiFlags, t_bModal> -{}; -#endif // _ATL_NO_HOSTING - -#if defined(_WTL_CE_DRA) && defined(WIN32_PLATFORM_PSPC) -/////////////////////////////////////////////////////////////////////////////// -// CAppStdOrientedDialogImpl - implementation of oriented PPC standard application dialog - -template -class ATL_NO_VTABLE CAppStdOrientedDialogImpl : - public CAppStdDialogImplBase, t_shidiFlags, t_bModal> -{}; - -#ifndef _ATL_NO_HOSTING -/////////////////////////////////////////////////////////////////////////////// -// CAppStdAxOrientedDialogImpl - implementation of oriented PPC standard application AxDialog - -template -class ATL_NO_VTABLE CAppStdAxOrientedDialogImpl : - public CAppStdDialogImplBase, t_shidiFlags, t_bModal> -{}; -#endif // _ATL_NO_HOSTING - -#endif // defined(_WTL_CE_DRA) && defined(WIN32_PLATFORM_PSPC) - -#endif // _WTL_CE_NO_DIALOGS - -#endif // _WTL_CE_NO_APPWINDOW - - -// --- Full screen support --- - -#ifndef _WTL_CE_NO_FULLSCREEN - -/////////////////////////////////////////////////////////////////////////////// -// CFullScreenFrame - full screen frame implementation - -template -class CFullScreenFrame -{ -public: - bool m_bFullScreen; - - CFullScreenFrame() : m_bFullScreen(false) - { } - -// Operation - void SetFullScreen(bool bFull) - { - m_bFullScreen = bFull; - ShowTaskBar(!bFull, false); - ShowMenuBar(!bFull); - } - -// Manage TaskBar for modal dialogs and property sheets - template - int FSDoModal(D& dlg) - { - T* pT = static_cast(this); - pT; // avoid level 4 warning - ATLASSERT(pT->IsWindow()); - if (m_bFullScreen) // Show taskbar if hidden - ShowTaskBar(true, false); - int iRet = dlg.DoModal(); - if (m_bFullScreen) // Hide taskbar if restored - ShowTaskBar(false); - return iRet; - } - -// Implementation - void ShowMenuBar(bool bShow) - { - T* pT = static_cast(this); - ATLASSERT(pT->IsWindow()); - ATL::CWindow MenuBar = pT->m_hWndCECommandBar; - ATLASSERT(MenuBar.IsWindow()); - MenuBar.ShowWindow(bShow ? SW_SHOWNORMAL : SW_HIDE); - pT->SizeToMenuBar(); - } - - void ShowTaskBar(bool bShow, bool bRepaint = true) - { - T* pT = static_cast(this); - ATLASSERT(pT->IsWindow()); - RECT rect = { 0 }; - SystemParametersInfo(SPI_GETWORKAREA, NULL, &rect, FALSE); - if (!bShow) - rect.top = 0; - -#ifdef WIN32_PLATFORM_PSPC // Pocket PC code - UINT uShow = t_bHasSip ? SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON : SHFS_SHOWTASKBAR | SHFS_HIDESIPBUTTON; - SHFullScreen(pT->m_hWnd, bShow ? uShow : SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON); -#elif _WIN32_WCE > 0x500 // Smartphone 2005 code - SHFullScreen(pT->m_hWnd, bShow ? SHFS_SHOWTASKBAR : SHFS_HIDETASKBAR); -#else // Smartphone 2003 - HWND hTaskBar = FindWindow(_T("tray"), NULL); - ATLASSERT(::IsWindow(hTaskBar)); - ::ShowWindow(hTaskBar, bShow ? SW_SHOW : SW_HIDE); -#endif // WIN32_PLATFORM_PSPC - - pT->MoveWindow(&rect, bRepaint); - } - -// Message map and handler - BEGIN_MSG_MAP(CFullScreenFrame) - MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) - MESSAGE_HANDLER(WM_ACTIVATE, OnActivate) - END_MSG_MAP() - - LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { -#ifndef SETTINGCHANGE_RESET // not defined for PPC 2002 - #define SETTINGCHANGE_RESET SPI_SETWORKAREA -#endif - if (m_bFullScreen && (wParam == SETTINGCHANGE_RESET)) - SetFullScreen(m_bFullScreen); - return bHandled = FALSE; - } - - LRESULT OnActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - if (m_bFullScreen) - { - ShowTaskBar(!wParam); - ShowMenuBar(!wParam); - } - return bHandled = FALSE; - } -}; - -#endif // _WTL_CE_NO_FULLSCREEN - - -// --- WinCE zoom support --- - -#ifndef _WTL_CE_NO_ZOOMSCROLL - -/////////////////////////////////////////////////////////////////////////////// -// CZoomScrollImpl - WinCE zooming implementation on top of CScrollImpl - -template -class CZoomScrollImpl: public CScrollImpl< T > -{ -public: -// Data members - _WTYPES_NS::CSize m_sizeTrue; - double m_fzoom; - -// Creation - CZoomScrollImpl() : m_sizeTrue(0), m_fzoom(1.) - { } - -// Zoom operations and access - void SetZoomScrollSize(_WTYPES_NS::CSize sizeTrue, double fzoom = 1., BOOL bRedraw = TRUE) - { - ATLASSERT(fzoom > 0.); - m_sizeTrue = sizeTrue; - m_fzoom = fzoom; - - CScrollImpl< T >::SetScrollSize(sizeTrue / fzoom, bRedraw); - } - - void SetZoomScrollSize(int cx, int cy, double fzoom=1., BOOL bRedraw = TRUE) - { - SetZoomScrollSize(_WTYPES_NS::CSize(cx, cy), fzoom, bRedraw); - } - - void SetZoom(double fzoom, BOOL bRedraw = TRUE) - { - _WTYPES_NS::CPoint ptCenter = WndtoTrue(m_sizeClient / 2); - _WTYPES_NS::CSize sizePage = GetScrollPage(); - _WTYPES_NS::CSize sizeLine = GetScrollLine(); - - SetZoomScrollSize(GetScrollSize(), fzoom, bRedraw); - - SetScrollLine(sizeLine); - SetScrollPage(sizePage); - _WTYPES_NS::CPoint ptOffset = ptCenter - (m_sizeClient / 2) * fzoom; - SetScrollOffset(ptOffset, bRedraw); - } - - double GetZoom() - { - return m_fzoom; - } - -// CScrollImpl overrides - void SetScrollOffset(int x, int y, BOOL bRedraw = TRUE) - { - CScrollImpl< T >::SetScrollOffset((int)(x / m_fzoom), (int)(y / m_fzoom), bRedraw); - } - - void SetScrollOffset(POINT ptOffset, BOOL bRedraw = TRUE) - { - SetScrollOffset(ptOffset.x, ptOffset.y, bRedraw); - } - - void GetScrollOffset(POINT& ptOffset) - { - ptOffset.x = (LONG)(m_ptOffset.x * m_fzoom); - ptOffset.y = (LONG)(m_ptOffset.y * m_fzoom); - } - - void SetScrollSize(int cx, int cy, BOOL bRedraw = TRUE) - { - SetZoomScrollSize(cx, cy, GetZoom(), bRedraw); - } - - void SetScrollSize(SIZE sizeTrue, BOOL bRedraw = TRUE) - { - SetZoomScrollSize(sizeTrue, GetZoom(), bRedraw); - } - - void GetScrollSize(SIZE& sizeTrue) const - { - sizeTrue = m_sizeTrue; - } - - void SetScrollPage(int cxPage, int cyPage) - { - SetScrollPage(_WTYPES_NS::CSize(cxPage, cyPage)); - } - - void SetScrollPage(SIZE sizePage) - { - CScrollImpl< T >::SetScrollPage(sizePage / m_fzoom); - } - - void GetScrollPage(SIZE& sizePage) const - { - sizePage = m_sizePage * m_fzoom; - } - - void SetScrollLine(int cxLine, int cyLine) - { - SetScrollLine(_WTYPES_NS::CSize(cxLine, cyLine)); - } - - void SetScrollLine(SIZE sizeLine) - { - CScrollImpl< T >::SetScrollLine(sizeLine / m_fzoom); - } - - void GetScrollLine(SIZE& sizeLine) const - { - sizeLine = m_sizeLine * m_fzoom; - } - -// Data access complements - _WTYPES_NS::CSize GetScrollSize() - { - return m_sizeTrue; - } - - _WTYPES_NS::CSize GetScrollPage() - { - return m_sizePage * m_fzoom; - } - - _WTYPES_NS::CSize GetScrollLine() - { - return m_sizeLine * m_fzoom; - } - - _WTYPES_NS::CPoint GetScrollOffset() - { - return (_WTYPES_NS::CSize)m_ptOffset * m_fzoom; - } - -// Helper coordinate functions - _WTYPES_NS::CPoint WndtoTrue(CPoint ptW) - { - return (_WTYPES_NS::CSize)ptW * GetZoom() + GetScrollOffset(); - } - - void WndtoTrue(LPPOINT aptW, int nPts) // in place coord transformation - { - for (int i = 0 ; i < nPts ; i++) - aptW[i] = WndtoTrue(aptW[i]); - } - - void WndtoTrue(LPRECT prectW) // in place coord transformation - { - WndtoTrue((LPPOINT)prectW, 2); - } - - _WTYPES_NS::CPoint TruetoWnd(CPoint ptT) - { - return (ptT - GetScrollOffset()) / GetZoom(); - } - - void TruetoWnd(LPPOINT aptT, int nPts) // in place coord transformation - { - for (int i = 0 ; i < nPts ; i++) - aptT[i] = TruetoWnd(aptT[i]); - } - - void TruetoWnd(LPRECT prectT) // in place coord transformation - { - TruetoWnd((LPPOINT)prectT, 2); - } - -// Drawing operations : assume adequate setting of data members - BOOL Draw(HBITMAP hbm, HDC hdestDC, DWORD dwROP = SRCCOPY) - { - CDC memDC = CreateCompatibleDC(hdestDC); - CBitmapHandle bmpOld = memDC.SelectBitmap(hbm); - BOOL bRes = Draw(memDC, hdestDC, dwROP); - memDC.SelectBitmap(bmpOld); - return bRes; - } - - BOOL Draw(HDC hsourceDC, HDC hdestDC, DWORD dwROP = SRCCOPY) - { - CDCHandle destDC = hdestDC; - destDC.SetViewportOrg(0,0); - _WTYPES_NS::CPoint ptOffset = GetScrollOffset(); - _WTYPES_NS::CSize sizeZClient = m_sizeClient * GetZoom(); - return destDC.StretchBlt(0, 0, m_sizeClient.cx, m_sizeClient.cy, hsourceDC, ptOffset.x, ptOffset.y, sizeZClient.cx, sizeZClient.cy, dwROP); - } - -#ifdef _IMAGING_H - BOOL Draw(IImage* pIImage, HDC hdestDC) - { - CDCHandle destDC = hdestDC; - destDC.SetViewportOrg(0,0); - return SUCCEEDED(pIImage->Draw(destDC, _WTYPES_NS::CRect(-_WTYPES_NS::CPoint(m_ptOffset), m_sizeAll), NULL)); - } -#endif - -// Message map and handlers - BEGIN_MSG_MAP(CZoomScrollImpl< T >) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd) - CHAIN_MSG_MAP(CScrollImpl< T >) - END_MSG_MAP() - - LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) - { - T* pT = static_cast(this); - ATLASSERT(::IsWindow(pT->m_hWnd)); - if ((GetScrollExtendedStyle() & SCRL_ERASEBACKGROUND)) - { - _WTYPES_NS::CRect rect; - pT->GetClientRect(rect); - _WTYPES_NS::CSize sizeClient=rect.Size(); - - if (m_sizeAll.cx < sizeClient.cx || m_sizeAll.cy < sizeClient.cy) - { - CDCHandle hdc = (HDC)wParam; - HBRUSH hbr = GetSysColorBrush((int)T::GetWndClassInfo().m_wc.hbrBackground - 1); - - if (m_sizeAll.cx < sizeClient.cx) - { - _WTYPES_NS::CRect rectBG(_WTYPES_NS::CPoint(m_sizeAll.cx, 0), sizeClient); - hdc.FillRect(rectBG, hbr); - } - - if (m_sizeAll.cy < sizeClient.cy) - { - _WTYPES_NS::CRect rectBG(_WTYPES_NS::CPoint(0, m_sizeAll.cy), sizeClient); - hdc.FillRect(rectBG, hbr); - } - } - } - else - { - bHandled = FALSE; - } - - return 1; - } -}; - -#endif // _WTL_CE_NO_ZOOMSCROLL - -#ifndef _WTL_CE_NO_CONTROLS - -// --- PPC bottom TabView control --- - -#if defined(__ATLCTRLX_H__) && defined(WIN32_PLATFORM_PSPC) - -/////////////////////////////////////////////////////////////////////////////// -// CBottomTabViewImpl - -template -class ATL_NO_VTABLE CBottomTabViewImpl : public CTabViewImpl -{ -public: - DECLARE_WND_CLASS_EX(NULL, 0, COLOR_APPWORKSPACE) - -// Implementation overrideables - bool CreateTabControl() - { - m_tab.Create(m_hWnd, rcDefault, NULL, WS_CHILD | TCS_BOTTOM, 0, m_nTabID); - - ATLASSERT(m_tab.m_hWnd != NULL); - if(m_tab.m_hWnd == NULL) - return false; - - m_tab.SendMessage(CCM_SETVERSION, COMCTL32_VERSION); - m_tab.SetItemExtra(sizeof(TABVIEWPAGE)); - - T* pT = static_cast(this); - m_cyTabHeight = pT->CalcTabHeight(); - - return true; - } - - int CalcTabHeight() - { - int nCount = m_tab.GetItemCount(); - TCITEMEXTRA tcix = { 0 }; - tcix.tciheader.mask = TCIF_TEXT; - tcix.tciheader.pszText = _T("NS"); - int nIndex = m_tab.InsertItem(nCount, tcix); - - RECT rect = { 0 }; - SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0); - RECT rcWnd = rect; - - m_tab.AdjustRect(FALSE, &rect); - rcWnd.top = rect.bottom; - ::AdjustWindowRectEx(&rcWnd, m_tab.GetStyle(), FALSE, m_tab.GetExStyle()); - m_tab.DeleteItem(nIndex); - - return rcWnd.bottom - rcWnd.top; - } - - void UpdateLayout() - { - RECT rect; - GetClientRect(&rect); - - if(m_tab.IsWindow() && ((m_tab.GetStyle() & WS_VISIBLE) != 0)) - m_tab.SetWindowPos(NULL, 0, rect.bottom - m_cyTabHeight, rect.right - rect.left, m_cyTabHeight, SWP_NOZORDER /*| SWP_SHOWWINDOW*/); - - if(m_nActivePage != -1) - ::SetWindowPos(GetPageHWND(m_nActivePage), NULL, 0, 0, rect.right - rect.left, rect.bottom - m_cyTabHeight, SWP_NOZORDER); - } - -}; - -class CBottomTabView : public CBottomTabViewImpl -{ -public: - DECLARE_WND_CLASS_EX(_T("WTL_BottomTabView"), 0, COLOR_APPWORKSPACE) -}; - -#endif // defined(__ATLCTRLX_H__) && defined(WIN32_PLATFORM_PSPC) - - -// --- PPC/SmartPhone controls --- - -//////////////////////////////////////////////////////////////////////////////// -// These are wrapper classes for the Pocket PC 2002/2003 and SmartPhone 2003 controls -// To implement a window based on a control, use following: -// Example: Implementing a window based on a Html control -// -// class CMyHtml : CWindowImpl -// { -// public: -// BEGIN_MSG_MAP(CMyHtml) -// // put your message handler entries here -// END_MSG_MAP() -// }; -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// CHtmlCtrl - -template -class CHtmlCtrlT : public TBase -{ -public: -// Constructors - CHtmlCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CHtmlCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - HWND hWnd = TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - ATLASSERT(hWnd != NULL); // Did you remember to call InitHTMLControl(hInstance) ?? - return hWnd; - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return WC_HTML; - } - -#if (_WIN32_WCE >= 400) - void AddStyle(LPCWSTR pszStyle) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_ADDSTYLE, 0, (LPARAM)pszStyle); - } -#endif // (_WIN32_WCE >= 400) - - void AddText(BOOL bPlainText, LPCSTR pszText) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_ADDTEXT, (WPARAM)bPlainText, (LPARAM)pszText); - } - - void AddHTML(LPCSTR pszHTML) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_ADDTEXT, (WPARAM)FALSE, (LPARAM)pszHTML); - } - - void AddText(BOOL bPlainText, LPCWSTR pszText) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_ADDTEXTW, (WPARAM)bPlainText, (LPARAM)pszText); - } - - void AddHTML(LPCWSTR pszHTML) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_ADDTEXTW, (WPARAM)FALSE, (LPARAM)pszHTML); - } - - void Anchor(LPCSTR pszAnchor) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_ANCHOR, 0, (LPARAM)pszAnchor); - } - - void Anchor(LPCWSTR pszAnchor) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_ANCHORW, 0, (LPARAM)pszAnchor); - } - -#if (_WIN32_WCE >= 420) - void GetBrowserDispatch(IDispatch** ppDispatch) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(ppDispatch); - ATLASSERT(*ppDispatch==NULL); - ::SendMessage(m_hWnd, DTM_BROWSERDISPATCH, 0, (LPARAM)ppDispatch); - } - void GetDocumentDispatch(IDispatch** ppDispatch) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(ppDispatch); - ATLASSERT(*ppDispatch==NULL); - ::SendMessage(m_hWnd, DTM_DOCUMENTDISPATCH , 0, (LPARAM)ppDispatch); - } -#endif // (_WIN32_WCE >= 420) - - void Clear() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_CLEAR, 0, 0L); - } - - void EnableClearType(BOOL bEnable = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_ENABLECLEARTYPE, 0, (LPARAM)bEnable); - } - - void EnableContextMenu(BOOL bEnable = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_ENABLECONTEXTMENU, 0, (LPARAM)bEnable); - } - - void EnableScripting(BOOL bEnable = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_ENABLESCRIPTING, 0, (LPARAM)bEnable); - } - - void EnableShrink(BOOL bEnable = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_ENABLESHRINK, 0, (LPARAM)bEnable); - } - - void EndOfSource() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_ENDOFSOURCE, 0, 0L); - } - - void ImageFail(DWORD dwCookie) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_IMAGEFAIL, 0, (LPARAM)dwCookie); - } - - int GetLayoutHeight() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, DTM_LAYOUTHEIGHT, 0, 0L); - } - - int GetLayoutWidth() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, DTM_LAYOUTWIDTH, 0, 0L); - } - - void Navigate(LPCTSTR pstrURL, UINT uFlags = 0) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pstrURL); - ::SendMessage(m_hWnd, DTM_NAVIGATE, (WPARAM)uFlags, (LPARAM)pstrURL); - } - - void SelectAll() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_SELECTALL, 0, 0L); - } - - void SetImage(INLINEIMAGEINFO* pImageInfo) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pImageInfo); - ::SendMessage(m_hWnd, DTM_SETIMAGE, 0, (LPARAM)pImageInfo); - } - - void ZoomLevel(int iLevel) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_ZOOMLEVEL, 0, (LPARAM)iLevel); - } - -#if (_WIN32_WCE >= 400) - void Stop() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DTM_STOP, 0, 0L); - } -#endif // (_WIN32_WCE >= 400) - - void GetScriptDispatch(IDispatch** ppDispatch) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(ppDispatch); - ATLASSERT(*ppDispatch==NULL); - ::SendMessage(m_hWnd, DTM_SCRIPTDISPATCH, 0, (LPARAM)ppDispatch); - } -}; - -typedef CHtmlCtrlT CHtmlCtrl; - - -#ifdef WIN32_PLATFORM_PSPC - -/////////////////////////////////////////////////////////////////////////////// -// CRichInkCtrl - -template -class CRichInkCtrlT : public TBase -{ -public: -// Constructors - CRichInkCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CRichInkCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - HWND hWnd = TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - ATLASSERT(hWnd != NULL); // Did you remember to call InitRichInkDLL() ?? - return hWnd; - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return WC_RICHINK; - } - - BOOL CanPaste(UINT uFormat = 0) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_CANPASTE, (WPARAM)uFormat, 0L); - } - - BOOL CanRedo() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_CANREDO, 0, 0L); - } - - BOOL CanUndo() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_CANUNDO, 0, 0L); - } - - void ClearAll(BOOL bRepaint = TRUE) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_CLEARALL, (WPARAM)bRepaint, 0L); - } - - BOOL GetModify() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, EM_GETMODIFY, 0, 0L); - } - - UINT GetPageStyle() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, EM_GETPAGESTYLE, 0, 0L); - } - - UINT GetPenMode() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, EM_GETPENMODE, 0, 0L); - } - - UINT GetViewStyle() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, EM_GETVIEW, 0, 0L); - } - - UINT GetWrapMode() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, EM_GETWRAPMODE, 0, 0L); - } - - UINT GetZoomPercent() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, EM_GETZOOMPERCENT, 0, 0L); - } - - void InsertLinks(LPWSTR lpString, int cchLength = -1) - { - ATLASSERT(::IsWindow(m_hWnd)); - if(cchLength == -1) - cchLength = lstrlen(lpString); - ::SendMessage(m_hWnd, EM_INSERTLINKS, (WPARAM)cchLength, (LPARAM)lpString); - } - - void RedoEvent() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_REDOEVENT, 0, 0L); - } - - UINT SetInkLayer(UINT uLayer) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (UINT)::SendMessage(m_hWnd, EM_SETINKLAYER, (WPARAM)uLayer, 0L); - } - - void SetPageStyle(UINT uStyle) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETPAGESTYLE, (WPARAM)uStyle, 0L); - } - - void SetPenMode(UINT uMode) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETPENMODE, (WPARAM)uMode, 0L); - } - - void SetViewStyle(UINT uStyle) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETVIEW, (WPARAM)uStyle, 0L); - } - - void SetViewAttributes(VIEWATTRIBUTES* pAttribs) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pAttribs); - ::SendMessage(m_hWnd, EM_SETVIEWATTRIBUTES, 0, (LPARAM)pAttribs); - } - - void SetWrapMode(UINT uMode) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETWRAPMODE, (WPARAM)uMode, 0L); - } - - void SetZoomPercent(UINT uPercent) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETZOOMPERCENT, (WPARAM)uPercent, 0L); - } - - LONG StreamIn(UINT uFormat, EDITSTREAM& es) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (LONG)::SendMessage(m_hWnd, EM_STREAMIN, (WPARAM)uFormat, (LPARAM)&es); - } - - LONG StreamOut(UINT uFormat, EDITSTREAM& es) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (LONG)::SendMessage(m_hWnd, EM_STREAMOUT, (WPARAM)uFormat, (LPARAM)&es); - } - - void UndoEvent() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_UNDOEVENT, 0, 0L); - } - - void Undo() - { - UndoEvent(); - } - -// Standard EM_xxx messages - DWORD GetSel() const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(GetViewStyle() != VT_DRAWINGVIEW); - return (DWORD)::SendMessage(m_hWnd, EM_GETSEL, 0, 0L); - } - - void GetSel(int& nStartChar, int& nEndChar) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(GetViewStyle() != VT_DRAWINGVIEW); - ::SendMessage(m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar); - } - - void SetSel(int nStartChar, int nEndChar) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(GetViewStyle() != VT_DRAWINGVIEW); - ::SendMessage(m_hWnd, EM_SETSEL, nStartChar, nEndChar); - } - - void ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo = FALSE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(GetViewStyle() != VT_DRAWINGVIEW); - ::SendMessage(m_hWnd, EM_REPLACESEL, (WPARAM)bCanUndo, (LPARAM)lpszNewText); - } - - void SetModify(BOOL bModified = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, EM_SETMODIFY, (WPARAM)bModified, 0L); - } - - int GetTextLength() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, WM_GETTEXTLENGTH, 0, 0L); - } - -// Clipboard operations - void Clear() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, WM_CLEAR, 0, 0L); - } - - void Copy() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, WM_COPY, 0, 0L); - } - - void Cut() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, WM_CUT, 0, 0L); - } - - void Paste() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, WM_PASTE, 0, 0L); - } -}; - -typedef CRichInkCtrlT CRichInkCtrl; - - -/////////////////////////////////////////////////////////////////////////////// -// CInkXCtrl - -template -class CInkXCtrlT : public TBase -{ -public: -// Constructors - CInkXCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CInkXCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - HWND hWnd = TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - ATLASSERT(hWnd != NULL); // Did you remember to call InitInkX() ?? - return hWnd; - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return WC_INKX; - } - - static UINT GetHotRecordingMessage() - { - return ::RegisterWindowMessage(szHotRecording); - } - - void ClearAll() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, IM_CLEARALL, 0, 0L); - } - - int GetData(BYTE* lpBuffer, INT cbBuffer) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(lpBuffer); - return (int)::SendMessage(m_hWnd, IM_GETDATA, (WPARAM)cbBuffer, (LPARAM)lpBuffer); - } - - int GetDataLen() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, IM_GETDATALEN, 0, 0L); - } - - CRichInkCtrl GetRichInk() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HWND)::SendMessage(m_hWnd, IM_GETRICHINK, 0, 0L); - } - - BOOL IsRecording() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, IM_RECORDING, 0, 0L); - } - - void ReInit() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, IM_REINIT, 0, 0L); - } - - void SetData(const BYTE* lpInkData, INT cbInkData) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(lpInkData); - ::SendMessage(m_hWnd, IM_SETDATA, (WPARAM)cbInkData, (LPARAM)lpInkData); - } - - void VoicePlay() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, IM_VOICE_PLAY, 0, 0L); - } - - BOOL IsVoicePlaying() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, IM_VOICE_PLAYING, 0, 0L); - } - - BOOL VoiceRecord() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, IM_VOICE_RECORD, 0, 0L); - } - - void VoiceStop() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, IM_VOICE_STOP, 0, 0L); - } - - void ShowVoiceBar(BOOL bShow = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, IM_VOICEBAR, (WPARAM)bShow, 0L); - } -}; - -typedef CInkXCtrlT CInkXCtrl; - -#endif // WIN32_PLATFORM_PSPC - - -/////////////////////////////////////////////////////////////////////////////// -// CVoiceRecorderCtrl - -template -class CVoiceRecorderCtrlT : public TBase -{ -public: -// Constructors - CVoiceRecorderCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CVoiceRecorderCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, const POINT pt, LPTSTR pstrFileName, UINT nID, DWORD dwStyle = 0) - { - ATLASSERT(pstrFileName != NULL); - CM_VOICE_RECORDER cmvr = { 0 }; - cmvr.cb = sizeof(CM_VOICE_RECORDER); - cmvr.dwStyle = dwStyle; - cmvr.xPos = pt.x; - cmvr.yPos = pt.y; - cmvr.hwndParent = hWndParent; - cmvr.id = nID; - cmvr.lpszRecordFileName = pstrFileName; - m_hWnd = VoiceRecorder_Create(&cmvr); - return m_hWnd; - } - - HWND Create(LPCM_VOICE_RECORDER pAttribs) - { - ATLASSERT(pAttribs); - m_hWnd = VoiceRecorder_Create(pAttribs); - return m_hWnd; - } - -// Attributes - void Record() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, VRM_RECORD, 0, 0L); - } - - void Play() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, VRM_PLAY, 0, 0L); - } - - void Stop() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, VRM_STOP, 0, 0L); - } - - void Cancel() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, VRM_CANCEL, 0, 0L); - } - - void Done() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, VRM_OK, 0, 0L); - } -}; - -typedef CVoiceRecorderCtrlT CVoiceRecorderCtrl; - - -#ifdef WIN32_PLATFORM_PSPC - -/////////////////////////////////////////////////////////////////////////////// -// CDocListCtrl - -template -class CDocListCtrlT : public TBase -{ -public: -// Attributes - DOCLISTCREATE m_dlc; - TCHAR m_szPath[MAX_PATH]; - -// Constructors - CDocListCtrlT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CDocListCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, WORD wId, LPCTSTR pszFolder = NULL, LPCTSTR pstrFilter = NULL, - WORD wFilterIndex = 0, DWORD dwFlags = DLF_SHOWEXTENSION) - { - ATLASSERT(pstrFilter != NULL); // It seems to need a filter badly!! - ::ZeroMemory(&m_dlc, sizeof(DOCLISTCREATE)); - ::ZeroMemory(m_szPath, sizeof(m_szPath)); - if(pszFolder != NULL) - SecureHelper::strncpy_x(m_szPath, MAX_PATH, pszFolder, MAX_PATH - 1); - m_dlc.dwStructSize = sizeof(DOCLISTCREATE); - m_dlc.hwndParent = hWndParent; - m_dlc.pszFolder = m_szPath; - m_dlc.pstrFilter = pstrFilter; - m_dlc.wFilterIndex = wFilterIndex; - m_dlc.wId = wId; - m_dlc.dwFlags = dwFlags; - m_hWnd = DocList_Create(&m_dlc); - return m_hWnd; - } - - HWND Create(DOCLISTCREATE* pDlc) - { - m_dlc = *pDlc; - m_hWnd = DocList_Create(&m_dlc); - return m_hWnd; - } - -// Attributes - void DeleteSel() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DLM_DELETESEL, 0, 0L); - } - - void DisableUpdates() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DLM_DISABLEUPDATES, 0, 0L); - } - - void EnableUpdates() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DLM_ENABLEUPDATES, 0, 0L); - } - - int GetFilterIndex() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, DLM_GETFILTERINDEX, 0, 0L); - } - - int GetItemCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, DLM_GETITEMCOUNT, 0, 0L); - } - - int GetNextItem(int iIndex, DWORD dwRelation = LVNI_ALL) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, DLM_GETNEXTITEM, (WPARAM)iIndex, (LPARAM)dwRelation); - } - - int GetFirstItem(DWORD dwRelation = LVNI_ALL) const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, DLM_GETNEXTITEM, (WPARAM)-1, (LPARAM)dwRelation); - } - - BOOL GetNextWave(int* pIndex) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pIndex); - return (BOOL)::SendMessage(m_hWnd, DLM_GETNEXTWAVE, 0, (LPARAM)pIndex); - } - - BOOL GetPrevWave(int* pIndex) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pIndex); - return (BOOL)::SendMessage(m_hWnd, DLM_GETPREVWAVE, 0, (LPARAM)pIndex); - } - - int GetSelCount() const - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, DLM_GETSELCOUNT, 0, 0L); - } - - BOOL GetSelPathName(LPTSTR pstrPath, int cchMax) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pstrPath); - return (BOOL)::SendMessage(m_hWnd, DLM_GETSELPATHNAME, (WPARAM)cchMax, (LPARAM)pstrPath); - } - - void ReceiveIR(LPCTSTR pstrPath) const - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pstrPath); - ::SendMessage(m_hWnd, DLM_RECEIVEIR, 0, (LPARAM)pstrPath); - } - - void Refresh() - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DLM_REFRESH, 0, 0L); - } - - BOOL RenameMoveSelectedItems() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, DLM_RENAMEMOVE, 0, 0L); - } - - int SelectAll() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (int)::SendMessage(m_hWnd, DLM_SELECTALL, 0, 0L); - } - - HRESULT SelectItem(LPCTSTR pstrPath, BOOL bVisible = TRUE) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pstrPath); - return (HRESULT)::SendMessage(m_hWnd, DLM_SELECTITEM, (WPARAM)bVisible, (LPARAM)pstrPath); - } - - void SendEMail(LPCTSTR pstrAttachment) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DLM_SENDEMAIL, 0, (LPARAM)pstrAttachment); - } - - void SendIR(LPCTSTR pstrPath) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DLM_SENDIR, 0, (LPARAM)pstrPath); - } - - HRESULT SetFilterIndex(int iIndex) - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HRESULT)::SendMessage(m_hWnd, DLM_SETFILTERINDEX, (WPARAM)iIndex, 0L); - } - - void SetFolder(LPCTSTR pstrPath) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pstrPath); - ::SendMessage(m_hWnd, DLM_SETFOLDER, 0, (LPARAM)pstrPath); - } - - BOOL SetItemState(int iIndex, const LVITEM* pItem) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pItem); - return (BOOL)::SendMessage(m_hWnd, DLM_SETITEMSTATE, (WPARAM)iIndex, (LPARAM)pItem); - } - - BOOL SetItemState(int iIndex, UINT uState, UINT uMask) - { - ATLASSERT(::IsWindow(m_hWnd)); - LV_ITEM lvi = { 0 }; - lvi.stateMask = uMask; - lvi.state = uState; - return (BOOL)::SendMessage(m_hWnd, DLM_SETITEMSTATE, (WPARAM)iIndex, (LPARAM)&lvi); - } - - void SetOneItem(int iIndex, LPCVOID pPA) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DLM_SETONEITEM, (WPARAM)iIndex, (LPARAM)pPA); - } - - void SetSelect(int iIndex) - { - ATLASSERT(::IsWindow(m_hWnd)); - ::SendMessage(m_hWnd, DLM_SETSELECT, (WPARAM)iIndex, 0L); - } - - void SetSelPathName(LPCTSTR pstrPath) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pstrPath); - ::SendMessage(m_hWnd, DLM_SETSELPATHNAME, 0, (LPARAM)pstrPath); - } - - BOOL SetSortOrder() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, DLM_SETSORTORDER, 0, 0L); - } - - HRESULT Update() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (HRESULT)::SendMessage(m_hWnd, DLM_UPDATE, 0, 0L); - } - - BOOL ValidateFolder() - { - ATLASSERT(::IsWindow(m_hWnd)); - return (BOOL)::SendMessage(m_hWnd, DLM_VALIDATEFOLDER, 0, 0L); - } - -// Functions - BOOL GetFirstSelectedWaveFile(int* pIndex, LPTSTR szPath, const size_t cchPath) - { - ATLASSERT(::IsWindow(m_hWnd)); - return DocList_GetFirstSelectedWaveFile(m_hWnd, pIndex, szPath, cchPath); - } - - BOOL GetNextSelectedWaveFile(int* pIndex, LPTSTR szPath, const size_t cchPath) - { - ATLASSERT(::IsWindow(m_hWnd)); - return DocList_GetNextSelectedWaveFile(m_hWnd, pIndex, szPath, cchPath); - } -}; - -typedef CDocListCtrlT CDocListCtrl; - -#endif // WIN32_PLATFORM_PSPC - - -/////////////////////////////////////////////////////////////////////////////// -// CCapEdit - -template -class CCapEditT : public TBase -{ -public: -// Constructors - CCapEditT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CCapEditT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - HWND hWnd = /*TBase*/CWindow::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - ATLASSERT(hWnd != NULL); // Did you remember to call SHInitExtraControls() ?? - return hWnd; - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return WC_CAPEDIT; - } -}; - -typedef CCapEditT CCapEdit; - -/////////////////////////////////////////////////////////////////////////////// -// CTTStatic - -#ifndef WIN32_PLATFORM_WFSP // Tooltips not supported on SmartPhone - -template -class CTTStaticT : public TBase -{ -public: -// Constructors - CTTStaticT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CTTStaticT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - HWND hWnd = TBase::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - ATLASSERT(hWnd != NULL); // Did you remember to call SHInitExtraControls() ?? - return hWnd; - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return WC_TSTATIC; - } - -// Operations - BOOL SetToolTipText(LPCTSTR pstrTipText) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pstrTipText); - ATLASSERT(lstrlen(pstrTipText) <= 253); - CTempBuffer buff; - int cchLen = lstrlen(pstrTipText) + 3; - LPTSTR pstr = buff.Allocate(cchLen); - if(pstr == NULL) - return FALSE; - SecureHelper::strcpy_x(pstr, cchLen, _T("~~")); - SecureHelper::strcat_x(pstr, cchLen, pstrTipText); - return SetWindowText(pstr); - } -}; - -typedef CTTStaticT CTTStatic; - - -/////////////////////////////////////////////////////////////////////////////// -// CTTButton - -template -class CTTButtonT : public TBase -{ -public: -// Constructors - CTTButtonT(HWND hWnd = NULL) : TBase(hWnd) - { } - - CTTButtonT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - HWND hWnd = TBase::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); - ATLASSERT(hWnd != NULL); // Did you remember to call SHInitExtraControls() ?? - return hWnd; - } - -// Attributes - static LPCTSTR GetWndClassName() - { - return WC_TBUTTON; - } - -// Operations - BOOL SetToolTipText(LPCTSTR pstrTipText) - { - ATLASSERT(::IsWindow(m_hWnd)); - ATLASSERT(pstrTipText); - ATLASSERT(lstrlen(pstrTipText) <= 253); - CTempBuffer buff; - int cchLen = lstrlen(pstrTipText) + 3; - LPTSTR pstr = buff.Allocate(cchLen); - if(pstr == NULL) - return FALSE; - SecureHelper::strcpy_x(pstr, cchLen, _T("~~")); - SecureHelper::strcat_x(pstr, cchLen, pstrTipText); - return SetWindowText(pstr); - } -}; - -typedef CTTButtonT CTTButton; - -#endif // !WIN32_PLATFORM_WFSP - - -// --- SmartPhone specific controls --- - -#ifdef WIN32_PLATFORM_WFSP - -/////////////////////////////////////////////////////////////////////////////// -// CSpinCtrlT - CSpinCtrl : SmartPhone adapted UpDown control - -template -class CSpinCtrlT : public CUpDownCtrlT< TBase > -{ -public: -// Constructors - CSpinCtrlT(HWND hWnd = NULL) : CUpDownCtrlT< TBase >(hWnd) - { } - - CSpinCtrlT< TBase >& operator =(HWND hWnd) - { - m_hWnd = hWnd; - return *this; - } - - HWND Create(HWND hWndParent, HWND hBuddy, DWORD dwStyle, int nID, LPCTSTR szExpandedName = NULL) - { - ATLASSERT(::IsWindow(hWndParent)); - CUpDownCtrlT< TBase >::Create(hWndParent, NULL, szExpandedName, dwStyle, 0, nID, NULL); - ATLASSERT(m_hWnd != NULL); // Did you remember to call AtlInitCommonControls(ICC_UPDOWN_CLASS)? - if (hBuddy != NULL) - { - ATLASSERT(::IsWindow(hBuddy)); - SetBuddy(hBuddy); - } - return m_hWnd; - } -}; - -typedef CSpinCtrlT CSpinCtrl; - - -/////////////////////////////////////////////////////////////////////////////// -// CSpinned - SmartPhone association of control and Spin - -template -class CSpinned : public TBase -{ -public: - CSpinCtrl m_SpinCtrl; - DWORD m_dwSpinnedStyle; - -// Constructors - CSpinned(HWND hWnd = NULL) : TBase(hWnd) - { - m_dwSpinnedStyle = WS_VISIBLE | UDS_ALIGNRIGHT | UDS_EXPANDABLE; - - if (t_bExpandOnly == true) - m_dwSpinnedStyle |= UDS_NOSCROLL; - else - m_dwSpinnedStyle |= UDS_HORZ | UDS_ARROWKEYS | UDS_SETBUDDYINT | UDS_WRAP; - - if (hWnd != NULL) - AttachOrCreateSpinCtrl(); - } - - CSpinned& operator =(HWND hWnd) - { - Attach(hWnd); - return *this; - } - - void Attach(HWND hWnd) - { - ATLASSERT(!IsWindow()); - TBase* pT = static_cast(this); - pT->m_hWnd = hWnd; - if (hWnd != NULL) - AttachOrCreateSpinCtrl(); - } - - HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szExpandedName = NULL, - DWORD dwStyle = 0, DWORD dwExStyle = 0, - ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) - { - - TBase* pT = static_cast(this); - TBase::Create(hWndParent, rect, NULL, dwStyle, dwExStyle, MenuOrID, lpCreateParam); - ATLASSERT(pT->m_hWnd != NULL); - - m_SpinCtrl.Create(hWndParent, pT->m_hWnd, m_dwSpinnedStyle, ATL_IDW_SPIN_ID + (int)MenuOrID.m_hMenu, szExpandedName); - - ATLASSERT(m_SpinCtrl.m_hWnd != NULL); // Did you remember to call AtlInitCommonControls(ICC_UPDOWN_CLASS)? - - return pT->m_hWnd; - } - -// Attributes - CSpinCtrl& GetSpinCtrl() - { - return m_SpinCtrl; - } - -// Implementation - // Attach our existing SpinCtrl or create one - bool AttachOrCreateSpinCtrl() - { - TBase* pT = static_cast(this); - - HWND hSpin = ::GetDlgItem(pT->GetParent(), ATL_IDW_SPIN_ID + pT->GetDlgCtrlID()); - - if (hSpin != NULL) - { - m_SpinCtrl.Attach(hSpin); -#ifdef DEBUG - TCHAR sClassName[16]; - ::GetClassName(hSpin, sClassName, 16); - ATLASSERT(!_tcscmp(sClassName, UPDOWN_CLASS)); - ATLASSERT(m_SpinCtrl.GetBuddy().m_hWnd == pT->m_hWnd); -#endif // DEBUG - } - else - { - m_SpinCtrl.Create(pT->GetParent(), pT->m_hWnd, m_dwSpinnedStyle, ATL_IDW_SPIN_ID + pT->GetDlgCtrlID()); - } - - return m_SpinCtrl.m_hWnd != NULL; - } -}; - - -/////////////////////////////////////////////////////////////////////////////// -// CSpinListBox - SmartPhone spinned ListBox control -// CExpandListBox - SmartPhone expandable ListBox control -// CExpandEdit - SmartPhone expandable Edit control -// CExpandCapEdit - SmartPhone expandable CapEdit control - -typedef CSpinned CSpinListBox; -typedef CSpinned CExpandListBox; -typedef CSpinned CExpandEdit; -typedef CSpinned CExpandCapEdit; - -#endif // WIN32_PLATFORM_WFSP - -#endif // _WTL_CE_NO_CONTROLS - -}; // namespace WTL - -#endif // __ATLWINCE_H__ diff --git a/!NotAdopted/SmartAutoReplier/wtl/atlwinx.h b/!NotAdopted/SmartAutoReplier/wtl/atlwinx.h deleted file mode 100644 index 629d29778f..0000000000 --- a/!NotAdopted/SmartAutoReplier/wtl/atlwinx.h +++ /dev/null @@ -1,525 +0,0 @@ -// Windows Template Library - WTL version 8.1 -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// This file is a part of the Windows Template Library. -// The use and distribution terms for this software are covered by the -// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) -// which can be found in the file CPL.TXT at the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by -// the terms of this license. You must not remove this notice, or -// any other, from this software. - -#ifndef __ATLWINX_H__ -#define __ATLWINX_H__ - -#pragma once - -#ifndef __ATLAPP_H__ - #error atlwinx.h requires atlapp.h to be included first -#endif - -#if (_ATL_VER >= 0x0700) - #include -#endif // (_ATL_VER >= 0x0700) - - -/////////////////////////////////////////////////////////////////////////////// -// Classes in this file: -// -// _U_RECT -// _U_MENUorID -// _U_STRINGorID - - -/////////////////////////////////////////////////////////////////////////////// -// Command Chaining Macros - -#define CHAIN_COMMANDS(theChainClass) \ - if(uMsg == WM_COMMAND) \ - CHAIN_MSG_MAP(theChainClass) - -#define CHAIN_COMMANDS_ALT(theChainClass, msgMapID) \ - if(uMsg == WM_COMMAND) \ - CHAIN_MSG_MAP_ALT(theChainClass, msgMapID) - -#define CHAIN_COMMANDS_MEMBER(theChainMember) \ - if(uMsg == WM_COMMAND) \ - CHAIN_MSG_MAP_MEMBER(theChainMember) - -#define CHAIN_COMMANDS_ALT_MEMBER(theChainMember, msgMapID) \ - if(uMsg == WM_COMMAND) \ - CHAIN_MSG_MAP_ALT_MEMBER(theChainMember, msgMapID) - - -/////////////////////////////////////////////////////////////////////////////// -// Macros for parent message map to selectively reflect control messages - -// NOTE: ReflectNotifications is a member of ATL's CWindowImplRoot -// (and overridden in 2 cases - CContainedWindowT and CAxHostWindow) -// Since we can't modify ATL, we'll provide the needed additions -// in a separate function (that is not a member of CWindowImplRoot) - -namespace WTL -{ - -inline LRESULT WtlReflectNotificationsFiltered(HWND hWndParent, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled, - UINT uMsgFilter = WM_NULL, UINT_PTR idFromFilter = 0, HWND hWndChildFilter = NULL) -{ - if((uMsgFilter != WM_NULL) && (uMsgFilter != uMsg)) - { - // The notification message doesn't match the filter. - bHandled = FALSE; - return 1; - } - - HWND hWndChild = NULL; - UINT_PTR idFrom = 0; - - switch(uMsg) - { - case WM_COMMAND: - if(lParam != NULL) // not from a menu - { - hWndChild = (HWND)lParam; - idFrom = (UINT_PTR)LOWORD(wParam); - } - break; - case WM_NOTIFY: - hWndChild = ((LPNMHDR)lParam)->hwndFrom; - idFrom = ((LPNMHDR)lParam)->idFrom; - break; -#ifndef _WIN32_WCE - case WM_PARENTNOTIFY: - switch(LOWORD(wParam)) - { - case WM_CREATE: - case WM_DESTROY: - hWndChild = (HWND)lParam; - idFrom = (UINT_PTR)HIWORD(wParam); - break; - default: - hWndChild = ::GetDlgItem(hWndParent, HIWORD(wParam)); - idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild); - break; - } - break; -#endif // !_WIN32_WCE - case WM_DRAWITEM: - if(wParam) // not from a menu - { - hWndChild = ((LPDRAWITEMSTRUCT)lParam)->hwndItem; - idFrom = (UINT_PTR)wParam; - } - break; - case WM_MEASUREITEM: - if(wParam) // not from a menu - { - hWndChild = ::GetDlgItem(hWndParent, ((LPMEASUREITEMSTRUCT)lParam)->CtlID); - idFrom = (UINT_PTR)wParam; - } - break; - case WM_COMPAREITEM: - if(wParam) // not from a menu - { - hWndChild = ((LPCOMPAREITEMSTRUCT)lParam)->hwndItem; - idFrom = (UINT_PTR)wParam; - } - break; - case WM_DELETEITEM: - if(wParam) // not from a menu - { - hWndChild = ((LPDELETEITEMSTRUCT)lParam)->hwndItem; - idFrom = (UINT_PTR)wParam; - } - break; - case WM_VKEYTOITEM: - case WM_CHARTOITEM: - case WM_HSCROLL: - case WM_VSCROLL: - hWndChild = (HWND)lParam; - idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild); - break; - case WM_CTLCOLORBTN: - case WM_CTLCOLORDLG: - case WM_CTLCOLOREDIT: - case WM_CTLCOLORLISTBOX: - case WM_CTLCOLORMSGBOX: - case WM_CTLCOLORSCROLLBAR: - case WM_CTLCOLORSTATIC: - hWndChild = (HWND)lParam; - idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild); - break; - default: - break; - } - - if((hWndChild == NULL) || - ((hWndChildFilter != NULL) && (hWndChildFilter != hWndChild))) - { - // Either hWndChild isn't valid, or - // hWndChild doesn't match the filter. - bHandled = FALSE; - return 1; - } - - if((idFromFilter != 0) && (idFromFilter != idFrom)) - { - // The dialog control id doesn't match the filter. - bHandled = FALSE; - return 1; - } - - ATLASSERT(::IsWindow(hWndChild)); - LRESULT lResult = ::SendMessage(hWndChild, OCM__BASE + uMsg, wParam, lParam); - if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC)) - { - // Try to prevent problems with WM_CTLCOLOR* messages when - // the message wasn't really handled - bHandled = FALSE; - } - - return lResult; -} - -}; // namespace WTL - -// Try to prevent problems with WM_CTLCOLOR* messages when -// the message wasn't really handled -#define REFLECT_NOTIFICATIONS_EX() \ -{ \ - bHandled = TRUE; \ - lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ - if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC)) \ - bHandled = FALSE; \ - if(bHandled) \ - return TRUE; \ -} - -#define REFLECT_NOTIFICATIONS_MSG_FILTERED(uMsgFilter) \ - { \ - bHandled = TRUE; \ - lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, NULL); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECT_NOTIFICATIONS_ID_FILTERED(idFromFilter) \ - { \ - bHandled = TRUE; \ - lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, idFromFilter, NULL); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECT_NOTIFICATIONS_HWND_FILTERED(hWndChildFilter) \ - { \ - bHandled = TRUE; \ - lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, 0, hWndChildFilter); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECT_NOTIFICATIONS_MSG_ID_FILTERED(uMsgFilter, idFromFilter) \ - { \ - bHandled = TRUE; \ - lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, idFromFilter, NULL); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECT_NOTIFICATIONS_MSG_HWND_FILTERED(uMsgFilter, hWndChildFilter) \ - { \ - bHandled = TRUE; \ - lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, hWndChildFilter); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECT_COMMAND(id, code) \ - if(uMsg == WM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \ - { \ - bHandled = TRUE; \ - lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECT_COMMAND_ID(id) \ - if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \ - { \ - bHandled = TRUE; \ - lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECT_COMMAND_CODE(code) \ - if(uMsg == WM_COMMAND && code == HIWORD(wParam)) \ - { \ - bHandled = TRUE; \ - lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECT_COMMAND_RANGE(idFirst, idLast) \ - if(uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ - { \ - bHandled = TRUE; \ - lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECT_COMMAND_RANGE_CODE(idFirst, idLast, code) \ - if(uMsg == WM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ - { \ - bHandled = TRUE; \ - lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECT_NOTIFY(id, cd) \ - if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \ - { \ - bHandled = TRUE; \ - lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECT_NOTIFY_ID(id) \ - if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \ - { \ - bHandled = TRUE; \ - lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECT_NOTIFY_CODE(cd) \ - if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \ - { \ - bHandled = TRUE; \ - lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECT_NOTIFY_RANGE(idFirst, idLast) \ - if(uMsg == WM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ - { \ - bHandled = TRUE; \ - lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECT_NOTIFY_RANGE_CODE(idFirst, idLast, cd) \ - if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ - { \ - bHandled = TRUE; \ - lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - - -/////////////////////////////////////////////////////////////////////////////// -// Reflected message handler macros for message maps (for ATL 3.0) - -#if (_ATL_VER < 0x0700) - -#define REFLECTED_COMMAND_HANDLER(id, code, func) \ - if(uMsg == OCM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \ - { \ - bHandled = TRUE; \ - lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECTED_COMMAND_ID_HANDLER(id, func) \ - if(uMsg == OCM_COMMAND && id == LOWORD(wParam)) \ - { \ - bHandled = TRUE; \ - lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECTED_COMMAND_CODE_HANDLER(code, func) \ - if(uMsg == OCM_COMMAND && code == HIWORD(wParam)) \ - { \ - bHandled = TRUE; \ - lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECTED_COMMAND_RANGE_HANDLER(idFirst, idLast, func) \ - if(uMsg == OCM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ - { \ - bHandled = TRUE; \ - lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECTED_COMMAND_RANGE_CODE_HANDLER(idFirst, idLast, code, func) \ - if(uMsg == OCM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ - { \ - bHandled = TRUE; \ - lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECTED_NOTIFY_HANDLER(id, cd, func) \ - if(uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \ - { \ - bHandled = TRUE; \ - lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECTED_NOTIFY_ID_HANDLER(id, func) \ - if(uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \ - { \ - bHandled = TRUE; \ - lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECTED_NOTIFY_CODE_HANDLER(cd, func) \ - if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \ - { \ - bHandled = TRUE; \ - lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECTED_NOTIFY_RANGE_HANDLER(idFirst, idLast, func) \ - if(uMsg == OCM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ - { \ - bHandled = TRUE; \ - lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#define REFLECTED_NOTIFY_RANGE_CODE_HANDLER(idFirst, idLast, cd, func) \ - if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ - { \ - bHandled = TRUE; \ - lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -#endif // (_ATL_VER < 0x0700) - - -/////////////////////////////////////////////////////////////////////////////// -// Dual argument helper classes (for ATL 3.0) - -#if (_ATL_VER < 0x0700) - -namespace ATL -{ - -class _U_RECT -{ -public: - _U_RECT(LPRECT lpRect) : m_lpRect(lpRect) - { } - _U_RECT(RECT& rc) : m_lpRect(&rc) - { } - LPRECT m_lpRect; -}; - -class _U_MENUorID -{ -public: - _U_MENUorID(HMENU hMenu) : m_hMenu(hMenu) - { } - _U_MENUorID(UINT nID) : m_hMenu((HMENU)LongToHandle(nID)) - { } - HMENU m_hMenu; -}; - -class _U_STRINGorID -{ -public: - _U_STRINGorID(LPCTSTR lpString) : m_lpstr(lpString) - { } - _U_STRINGorID(UINT nID) : m_lpstr(MAKEINTRESOURCE(nID)) - { } - LPCTSTR m_lpstr; -}; - -}; // namespace ATL - -#endif // (_ATL_VER < 0x0700) - - -namespace WTL -{ - -/////////////////////////////////////////////////////////////////////////////// -// Forward notifications support for message maps (for ATL 3.0) - -#if (_ATL_VER < 0x0700) - -// forward notifications support -#define FORWARD_NOTIFICATIONS() \ - { \ - bHandled = TRUE; \ - lResult = WTL::Atl3ForwardNotifications(m_hWnd, uMsg, wParam, lParam, bHandled); \ - if(bHandled) \ - return TRUE; \ - } - -static LRESULT Atl3ForwardNotifications(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - LRESULT lResult = 0; - switch(uMsg) - { - case WM_COMMAND: - case WM_NOTIFY: -#ifndef _WIN32_WCE - case WM_PARENTNOTIFY: -#endif // !_WIN32_WCE - case WM_DRAWITEM: - case WM_MEASUREITEM: - case WM_COMPAREITEM: - case WM_DELETEITEM: - case WM_VKEYTOITEM: - case WM_CHARTOITEM: - case WM_HSCROLL: - case WM_VSCROLL: - case WM_CTLCOLORBTN: - case WM_CTLCOLORDLG: - case WM_CTLCOLOREDIT: - case WM_CTLCOLORLISTBOX: - case WM_CTLCOLORMSGBOX: - case WM_CTLCOLORSCROLLBAR: - case WM_CTLCOLORSTATIC: - lResult = ::SendMessage(::GetParent(hWnd), uMsg, wParam, lParam); - break; - default: - bHandled = FALSE; - break; - } - return lResult; -} - -#endif // (_ATL_VER < 0x0700) - -}; // namespace WTL - -#endif // __ATLWINX_H__ diff --git a/!NotAdopted/Tlen/codec/gsm.h b/!NotAdopted/Tlen/codec/gsm.h deleted file mode 100644 index fba1bcb1ac..0000000000 --- a/!NotAdopted/Tlen/codec/gsm.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is based on GSM 06.10 source code developed by -Jutta Degener and Carsten Bormann, -Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, -Technische Universitaet Berlin - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#include - -#define P_MAX 8 /* order p of LPC analysis, typically 8..14 */ - -typedef struct { - int LARpp[2][8]; /* LAR coefficients for previous and current frame */ - int j; /* current frame index in LARpp[j][] */ - int qLARs[8]; /* quantized LARs for current frame */ - int u[8]; /* used by short term analysis filter */ - int v[9]; /* used by short term synthesis filter */ - int subframe; /* subframe index (0..3)*/ - short dp0[ 280 ]; /* previous short-term filter output/prediction, used by long term analysis*/ - int e[160]; /* errors (residuals) */ - int nrp; /* long term synthesis */ - int Nc[4], bc[4]; /* long-term lag and gain for current frame */ - int Mc[4]; /* RPE grid index (0..3) */ - int xMaxc[4]; /* RPE maximum error quantized and encoded (mantissa + exp) */ - int xMc[52]; /* quantized residuals (errors) 4 * 13 */ - - int z1; /* preprocessing.c, Offset_com. */ - int z2; /* Offset_com. */ - int mp; /* Preemphasis */ - int msr; /* decoder.c, Postprocessing */ - - unsigned char gsmFrame[33]; -}gsm_state; - -extern gsm_state * gsm_create() ; -extern void gsm_release(gsm_state *ptr); -extern void gsm_encode(gsm_state *state, short *in); -extern void gsm_decode(gsm_state *state, short *out); - -extern void gsm_preprocessing( gsm_state *state, short *in, short *out); -extern void shortTermAnalysis(gsm_state *state, short *in); -extern void longTermAnalysis(gsm_state *state, short *in); -extern void encodeRPE(gsm_state *state); -extern void decodeRPE(gsm_state *state); -extern void longTermSynthesis(gsm_state *state); -extern void shortTermSynthesis(gsm_state *state, short *in, short *out); -extern void gsm_postprocessing( gsm_state *state, short *in, short *out); diff --git a/!NotAdopted/Tlen/codec/gsm_codec.c b/!NotAdopted/Tlen/codec/gsm_codec.c deleted file mode 100644 index 1d0a08a41e..0000000000 --- a/!NotAdopted/Tlen/codec/gsm_codec.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2004-2007 Piotr Piastucki - -This program is based on GSM 06.10 source code developed by -Jutta Degener and Carsten Bormann, -Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, -Technische Universitaet Berlin - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "gsm.h" -#include -#include -#include -#define GSM_MAGIC 0xD - -gsm_state * gsm_create() -{ - gsm_state * state = (gsm_state *)malloc(sizeof(gsm_state)); - memset(state, 0, sizeof(gsm_state)); - state->nrp = 40; - return state; -} - -void gsm_release(gsm_state *ptr) -{ - free(ptr); -} - -void gsm_encode(gsm_state *state, short *in) -{ int i, j; - unsigned char *c = state->gsmFrame; - short temp_in[160]; - - gsm_preprocessing(state, in, temp_in); - shortTermAnalysis(state, temp_in); - for (i = 0; i < 4; i++) { - state->subframe = i; - longTermAnalysis(state, temp_in + 40 * i); - encodeRPE(state); - for (j = 0; j < 40; j++) { - int ii = (int) state->dp0[120 + i * 40 + j] + state->e[i * 40 + j]; - if (ii<-32768) ii = -32768; - else if (ii>32767) ii=32767; - state->dp0[120 + i * 40 + j] = ii; - } - } - memcpy(state->dp0, state->dp0 + 160, 120 * sizeof(short)); - state->j ^= 1; - *c++ = ((GSM_MAGIC & 0xF) << 4) - | ((state->qLARs[0] >> 2) & 0xF); - *c++ = ((state->qLARs[0] & 0x3) << 6) - | (state->qLARs[1] & 0x3F); - *c++ = ((state->qLARs[2] & 0x1F) << 3) - | ((state->qLARs[3] >> 2) & 0x7); - *c++ = ((state->qLARs[3] & 0x3) << 6) - | ((state->qLARs[4] & 0xF) << 2) - | ((state->qLARs[5] >> 2) & 0x3); - *c++ = ((state->qLARs[5] & 0x3) << 6) - | ((state->qLARs[6] & 0x7) << 3) - | (state->qLARs[7] & 0x7); - *c++ = ((state->Nc[0] & 0x7F) << 1) - | ((state->bc[0] >> 1) & 0x1); - *c++ = ((state->bc[0] & 0x1) << 7) - | ((state->Mc[0] & 0x3) << 5) - | ((state->xMaxc[0] >> 1) & 0x1F); - *c++ = ((state->xMaxc[0] & 0x1) << 7) - | ((state->xMc[0] & 0x7) << 4) - | ((state->xMc[1] & 0x7) << 1) - | ((state->xMc[2] >> 2) & 0x1); - *c++ = ((state->xMc[2] & 0x3) << 6) - | ((state->xMc[3] & 0x7) << 3) - | (state->xMc[4] & 0x7); - *c++ = ((state->xMc[5] & 0x7) << 5) - | ((state->xMc[6] & 0x7) << 2) - | ((state->xMc[7] >> 1) & 0x3); - *c++ = ((state->xMc[7] & 0x1) << 7) - | ((state->xMc[8] & 0x7) << 4) - | ((state->xMc[9] & 0x7) << 1) - | ((state->xMc[10] >> 2) & 0x1); - *c++ = ((state->xMc[10] & 0x3) << 6) - | ((state->xMc[11] & 0x7) << 3) - | (state->xMc[12] & 0x7); - *c++ = ((state->Nc[1] & 0x7F) << 1) - | ((state->bc[1] >> 1) & 0x1); - *c++ = ((state->bc[1] & 0x1) << 7) - | ((state->Mc[1] & 0x3) << 5) - | ((state->xMaxc[1] >> 1) & 0x1F); - *c++ = ((state->xMaxc[1] & 0x1) << 7) - | ((state->xMc[13] & 0x7) << 4) - | ((state->xMc[14] & 0x7) << 1) - | ((state->xMc[15] >> 2) & 0x1); - *c++ = ((state->xMc[15] & 0x3) << 6) - | ((state->xMc[16] & 0x7) << 3) - | (state->xMc[17] & 0x7); - *c++ = ((state->xMc[18] & 0x7) << 5) - | ((state->xMc[19] & 0x7) << 2) - | ((state->xMc[20] >> 1) & 0x3); - *c++ = ((state->xMc[20] & 0x1) << 7) - | ((state->xMc[21] & 0x7) << 4) - | ((state->xMc[22] & 0x7) << 1) - | ((state->xMc[23] >> 2) & 0x1); - *c++ = ((state->xMc[23] & 0x3) << 6) - | ((state->xMc[24] & 0x7) << 3) - | (state->xMc[25] & 0x7); - *c++ = ((state->Nc[2] & 0x7F) << 1) - | ((state->bc[2] >> 1) & 0x1); - *c++ = ((state->bc[2] & 0x1) << 7) - | ((state->Mc[2] & 0x3) << 5) - | ((state->xMaxc[2] >> 1) & 0x1F); - *c++ = ((state->xMaxc[2] & 0x1) << 7) - | ((state->xMc[26] & 0x7) << 4) - | ((state->xMc[27] & 0x7) << 1) - | ((state->xMc[28] >> 2) & 0x1); - *c++ = ((state->xMc[28] & 0x3) << 6) - | ((state->xMc[29] & 0x7) << 3) - | (state->xMc[30] & 0x7); - *c++ = ((state->xMc[31] & 0x7) << 5) - | ((state->xMc[32] & 0x7) << 2) - | ((state->xMc[33] >> 1) & 0x3); - *c++ = ((state->xMc[33] & 0x1) << 7) - | ((state->xMc[34] & 0x7) << 4) - | ((state->xMc[35] & 0x7) << 1) - | ((state->xMc[36] >> 2) & 0x1); - *c++ = ((state->xMc[36] & 0x3) << 6) - | ((state->xMc[37] & 0x7) << 3) - | (state->xMc[38] & 0x7); - *c++ = ((state->Nc[3] & 0x7F) << 1) - | ((state->bc[3] >> 1) & 0x1); - *c++ = ((state->bc[3] & 0x1) << 7) - | ((state->Mc[3] & 0x3) << 5) - | ((state->xMaxc[3] >> 1) & 0x1F); - *c++ = ((state->xMaxc[3] & 0x1) << 7) - | ((state->xMc[39] & 0x7) << 4) - | ((state->xMc[40] & 0x7) << 1) - | ((state->xMc[41] >> 2) & 0x1); - *c++ = ((state->xMc[41] & 0x3) << 6) - | ((state->xMc[42] & 0x7) << 3) - | (state->xMc[43] & 0x7); - *c++ = ((state->xMc[44] & 0x7) << 5) - | ((state->xMc[45] & 0x7) << 2) - | ((state->xMc[46] >> 1) & 0x3); - *c++ = ((state->xMc[46] & 0x1) << 7) - | ((state->xMc[47] & 0x7) << 4) - | ((state->xMc[48] & 0x7) << 1) - | ((state->xMc[49] >> 2) & 0x1); - *c++ = ((state->xMc[49] & 0x3) << 6) - | ((state->xMc[50] & 0x7) << 3) - | (state->xMc[51] & 0x7); -} - -void gsm_decode(gsm_state *state, short *out) -{ - int i; - unsigned char *c = state->gsmFrame; - - if (((*c >> 4) & 0x0F) != GSM_MAGIC) return ; - state->qLARs[0] = (*c++ & 0xF) << 2; - state->qLARs[0] |= (*c >> 6) & 0x3; - state->qLARs[1] = *c++ & 0x3F; - state->qLARs[2] = (*c >> 3) & 0x1F; - state->qLARs[3] = (*c++ & 0x7) << 2; - state->qLARs[3] |= (*c >> 6) & 0x3; - state->qLARs[4] = (*c >> 2) & 0xF; - state->qLARs[5] = (*c++ & 0x3) << 2; - state->qLARs[5] |= (*c >> 6) & 0x3; - state->qLARs[6] = (*c >> 3) & 0x7; - state->qLARs[7] = *c++ & 0x7; - state->Nc[0] = (*c >> 1) & 0x7F; - state->bc[0] = (*c++ & 0x1) << 1; - state->bc[0] |= (*c >> 7) & 0x1; - state->Mc[0] = (*c >> 5) & 0x3; - state->xMaxc[0] = (*c++ & 0x1F) << 1; - state->xMaxc[0] |= (*c >> 7) & 0x1; - state->xMc[0] = (*c >> 4) & 0x7; - state->xMc[1] = (*c >> 1) & 0x7; - state->xMc[2] = (*c++ & 0x1) << 2; - state->xMc[2] |= (*c >> 6) & 0x3; - state->xMc[3] = (*c >> 3) & 0x7; - state->xMc[4] = *c++ & 0x7; - state->xMc[5] = (*c >> 5) & 0x7; - state->xMc[6] = (*c >> 2) & 0x7; - state->xMc[7] = (*c++ & 0x3) << 1; - state->xMc[7] |= (*c >> 7) & 0x1; - state->xMc[8] = (*c >> 4) & 0x7; - state->xMc[9] = (*c >> 1) & 0x7; - state->xMc[10] = (*c++ & 0x1) << 2; - state->xMc[10] |= (*c >> 6) & 0x3; - state->xMc[11] = (*c >> 3) & 0x7; - state->xMc[12] = *c++ & 0x7; - state->Nc[1] = (*c >> 1) & 0x7F; - state->bc[1] = (*c++ & 0x1) << 1; - state->bc[1] |= (*c >> 7) & 0x1; - state->Mc[1] = (*c >> 5) & 0x3; - state->xMaxc[1] = (*c++ & 0x1F) << 1; - state->xMaxc[1] |= (*c >> 7) & 0x1; - state->xMc[13] = (*c >> 4) & 0x7; - state->xMc[14] = (*c >> 1) & 0x7; - state->xMc[15] = (*c++ & 0x1) << 2; - state->xMc[15] |= (*c >> 6) & 0x3; - state->xMc[16] = (*c >> 3) & 0x7; - state->xMc[17] = *c++ & 0x7; - state->xMc[18] = (*c >> 5) & 0x7; - state->xMc[19] = (*c >> 2) & 0x7; - state->xMc[20] = (*c++ & 0x3) << 1; - state->xMc[20] |= (*c >> 7) & 0x1; - state->xMc[21] = (*c >> 4) & 0x7; - state->xMc[22] = (*c >> 1) & 0x7; - state->xMc[23] = (*c++ & 0x1) << 2; - state->xMc[23] |= (*c >> 6) & 0x3; - state->xMc[24] = (*c >> 3) & 0x7; - state->xMc[25] = *c++ & 0x7; - state->Nc[2] = (*c >> 1) & 0x7F; - state->bc[2] = (*c++ & 0x1) << 1; - state->bc[2] |= (*c >> 7) & 0x1; - state->Mc[2] = (*c >> 5) & 0x3; - state->xMaxc[2] = (*c++ & 0x1F) << 1; - state->xMaxc[2] |= (*c >> 7) & 0x1; - state->xMc[26] = (*c >> 4) & 0x7; - state->xMc[27] = (*c >> 1) & 0x7; - state->xMc[28] = (*c++ & 0x1) << 2; - state->xMc[28] |= (*c >> 6) & 0x3; - state->xMc[29] = (*c >> 3) & 0x7; - state->xMc[30] = *c++ & 0x7; - state->xMc[31] = (*c >> 5) & 0x7; - state->xMc[32] = (*c >> 2) & 0x7; - state->xMc[33] = (*c++ & 0x3) << 1; - state->xMc[33] |= (*c >> 7) & 0x1; - state->xMc[34] = (*c >> 4) & 0x7; - state->xMc[35] = (*c >> 1) & 0x7; - state->xMc[36] = (*c++ & 0x1) << 2; - state->xMc[36] |= (*c >> 6) & 0x3; - state->xMc[37] = (*c >> 3) & 0x7; - state->xMc[38] = *c++ & 0x7; - state->Nc[3] = (*c >> 1) & 0x7F; - state->bc[3] = (*c++ & 0x1) << 1; - state->bc[3] |= (*c >> 7) & 0x1; - state->Mc[3] = (*c >> 5) & 0x3; - state->xMaxc[3] = (*c++ & 0x1F) << 1; - state->xMaxc[3] |= (*c >> 7) & 0x1; - state->xMc[39] = (*c >> 4) & 0x7; - state->xMc[40] = (*c >> 1) & 0x7; - state->xMc[41] = (*c++ & 0x1) << 2; - state->xMc[41] |= (*c >> 6) & 0x3; - state->xMc[42] = (*c >> 3) & 0x7; - state->xMc[43] = *c++ & 0x7; - state->xMc[44] = (*c >> 5) & 0x7; - state->xMc[45] = (*c >> 2) & 0x7; - state->xMc[46] = (*c++ & 0x3) << 1; - state->xMc[46] |= (*c >> 7) & 0x1; - state->xMc[47] = (*c >> 4) & 0x7; - state->xMc[48] = (*c >> 1) & 0x7; - state->xMc[49] = (*c++ & 0x1) << 2; - state->xMc[49] |= (*c >> 6) & 0x3; - state->xMc[50] = (*c >> 3) & 0x7; - state->xMc[51] = *c & 0x7; - - for (i = 0; i < 4; i++) { - state->subframe = i; - decodeRPE(state); - longTermSynthesis(state); - } - memcpy(state->dp0, state->dp0 + 160, 120 * sizeof(short)); - shortTermSynthesis(state, &state->dp0[120], out); - gsm_postprocessing(state, out, out); - state->j ^= 1; -} diff --git a/!NotAdopted/Tlen/codec/gsm_long.c b/!NotAdopted/Tlen/codec/gsm_long.c deleted file mode 100644 index 7d9148061c..0000000000 --- a/!NotAdopted/Tlen/codec/gsm_long.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2004-2007 Piotr Piastucki - -This program is based on GSM 06.10 source code developed by -Jutta Degener and Carsten Bormann, -Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, -Technische Universitaet Berlin - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#include "gsm.h" -#include -#include -#include - -/* Decision levels */ -const static int gsm_DLB[4] = { 6554, 16384, 26214, 32767 }; -/* Quantization levels */ -const static int gsm_QLB[4] = { 3277, 11469, 21299, 32767 }; - -/* - * Long term parameters calculation - lag (Nc) and gain (bc). - */ -static void longTermLTPCalculation(gsm_state *state, short *in, short *in_1) -{ - int k, lambda; - int Nc, bc; - float in_1_float_base[120], * in_1_float = in_1_float_base + 120; - float in_float[40]; - float L_result, L_max, L_power; - - for (k = -120; k < 0; k++) in_1_float[k] = (float)in_1[k]; - for (k = 0; k < 40; k++) in_float[k] = (float)in[k]; - - /* Search for the maximum cross-correlation and coding of the LTP lag */ - - L_max = 0; - Nc = 40; /* index for the maximum cross-correlation */ - - for (lambda = 40; lambda < 121; lambda++) { - for (L_result = 0, L_power = 0, k = 0; k < 40; k++) { - L_result += in_float[k] * in_1_float[k - lambda]; -// L_power += in_1_float[k - lambda] * in_1_float[k - lambda]; - } -// L_result = L_result / L_power; - if (L_result > L_max) { - Nc = lambda; - L_max = L_result; - } - } - state->Nc[state->subframe] = Nc; - if (L_max <= 0.) { - state->bc[state->subframe] = 0; - return; - } - /* Compute the power of the reconstructed short term residual signal dp[..] */ - in_1_float -= Nc; - L_power = 0; - for (k = 0; k < 40; k++) { - float f = in_1_float[k]; - L_power += f * f; - } - if (L_max >= L_power) { //1.0 - state->bc[state->subframe] = 3; - return; - } - /* Coding of the LTP gain - * Table gsm_DLB must be used to obtain the level DLB[i] for the - * quantization of the LTP gain b to get the coded version bc. - */ -// lambda = L_max * 32768.; - lambda = (int)(L_max * 32768. / L_power); - for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break; - state->bc[state->subframe] = bc; -} - -/* - * Here we decode the bc parameter and compute samples of the estimate out[0..39]. - * The decoding of bc needs the gsm_QLB table. - * The long term residual signal e[0..39] is then calculated to be fed to the - * RPE encoding section. - */ -static void longTermAnalysisFilter(int Nc, int bc, short *in, short *in_1, short *out, int *e) -{ - int gain, k, l; - gain = gsm_QLB[bc]; - for (k = 0; k < 40; k++) { - l = (gain * (int)in_1[k - Nc] + 16384) >> 15; - if (l < -32768) l = -32768; - else if (l > 32767) l = 32767; - out[k] = l; - e[k] = in[k] - l; - } -} - -/* - * This procedure uses the bcr and Ncr parameter to realize the - * long term synthesis filtering. The decoding of bcr needs table gsm_QLB. - */ -static void longTermSynthesisFilter(gsm_state * state, int Ncr, int bcr, int *e, short *out) -{ - int k; - int brp, Nr; - - /* Check the limits of Nr. */ - Nr = Ncr < 40 || Ncr > 120 ? state->nrp : Ncr; - state->nrp = Nr; - /* Decoding of the LTP gain bcr */ - brp = gsm_QLB[ bcr ]; - - /* Computation of the reconstructed short term residual - * signal drp[0..39] - */ - for (k = 0; k < 40; k++) { - int temp = (brp * (int)out[ k-Nr ] + 16384) >> 15; - out[k] = e[k] + temp; - } -} - -/* - * This procedure performs long term analysis. - */ -void longTermAnalysis(gsm_state *state, short *in) -{ - short *in_1 = state->dp0 + 120 + state->subframe * 40; - short *out = state->dp0 + 120 + state->subframe * 40; - int *e = state->e + state->subframe * 40; -/* - - int i; - printf("Long-term in: \n"); - for (i=0;i<40;i++) { - printf("%7d ", in[i]); - } - printf("\n"); - */ - longTermLTPCalculation(state, in, in_1); - /* printf("Nc: %d, bc: %d \n", state->Nc[state->subframe], state->bc[state->subframe]); - */ - longTermAnalysisFilter(state->Nc[state->subframe], state->bc[state->subframe], in, in_1, out, e); -/* - printf("Long-term out: \n"); - for (i=0;i<40;i++) { - printf("%7d ", out[i]); - } - printf("\n"); - */ -} - -/* - * This procedure performs long term synthesis. - */ -void longTermSynthesis(gsm_state *state) -{ - int Nc = state->Nc[state->subframe]; - int bc = state->bc[state->subframe]; - int *e = state->e + state->subframe * 40; - short *out = state->dp0 + 120 + state->subframe * 40; - //int i; - longTermSynthesisFilter(state, Nc, bc, e, out); - /* - printf("Long-term reconstructed: \n"); - for (i=0;i<160;i++) { - printf("%7d ", state->dp0[i]); - } - printf("\n"); - */ -} diff --git a/!NotAdopted/Tlen/codec/gsm_lpc.c b/!NotAdopted/Tlen/codec/gsm_lpc.c deleted file mode 100644 index 519612baff..0000000000 --- a/!NotAdopted/Tlen/codec/gsm_lpc.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2004-2007 Piotr Piastucki - -This program is based on GSM 06.10 source code developed by -Jutta Degener and Carsten Bormann, -Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, -Technische Universitaet Berlin - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -/* LPC- and Reflection Coefficients - * The next two functions calculate linear prediction coefficients - * and/or the related reflection coefficients from the first P_MAX+1 - * values of the autocorrelation function. - */ -#include "gsm.h" /* for P_MAX */ -#include -#include -#include - -/* Compute the autocorrelation - * ,--, - * ac(l) = > x(i) * x(i-l) for all i - * `--' - * for lags l between 0 and lag-1, and x(i) == 0 for i < 0 or i >= n - * @param n: number of samples - * @param lax: max lag (order) - * @param in: [0...n-1] samples x - * @param out: [0...lag-1] autocorrelation - */ -static void autocorrelation(int n, float const *x, int lag, float *ac) -{ - float d; - int i, j; - for (j = 0; j < lag; j++) { - for (i = j, d = 0; i < n; i++) d += x[i] * x[i-j]; - ac[j] = d; - } - d = (float)fabs(ac[0]); - if (d != 0) { - for (j = 0; j < lag; j++) ac[j] /= d; - } -} - -/* The Levinson-Durbin algorithm was invented by N. Levinson in 1947 - * and modified by J. Durbin in 1959. - * @param in: [0...p] autocorrelation values - * @param out: [0...p-1] reflection coefficients - * @param lpc: [0...p-1] LPC coefficients - * @return minimum mean square error - */ -/* -static float levinson_durbin (float const *ac, float *ref, float *lpc) -{ - int i, j; - float r, error = ac[0]; - - if (ac[0] == 0) { - for (i = 0; i < P_MAX; i++) ref[i] = 0; - return 0; - } - - for (i = 0; i < P_MAX; i++) { - - r = -ac[i + 1]; - for (j = 0; j < i; j++) r -= lpc[j] * ac[i - j]; - ref[i] = r /= error; - - // Update LPC coefficients and total error. - lpc[i] = r; - for (j = 0; j < i / 2; j++) { - float tmp = lpc[j]; - lpc[j] = r * lpc[i - 1 - j]; - lpc[i - 1 - j] += r * tmp; - } - if (i % 2) lpc[j] += lpc[j] * r; - - error *= 1 - r * r; - } - return error; -} -*/ -/* I. Schur's recursion from 1917 is related to the Levinson-Durbin method, - * but faster on parallel architectures; where Levinson-Durbin would take time - * proportional to p * log(p), Schur only requires time proportional to p. The - * GSM coder uses an integer version of the Schur recursion. - * @param in: [0...p] autocorrelation values - * @param out: [0...p-1] reflection coefficients - * @return the minimum mean square error - */ -static float schur(float const *ac, float *ref) -{ - int i, m; - float error=ac[0], r, G[2][P_MAX]; - - if (ac[0] == 0.0) { - for (i = 0; i < P_MAX; i++) ref[i] = 0; - return 0; - } - - /* Initialize the rows of the generator matrix G to ac[1...p]. */ - for (i = 0; i < P_MAX; i++) G[0][i] = G[1][i] = ac[i + 1]; - - for (i = 0;;) { - /* Calculate this iteration's reflection coefficient and error. */ - ref[i] = r = -G[1][0] / error; - error += G[1][0] * r; - - if (++i >= P_MAX) return error; - - /* Update the generator matrix. Unlike Levinson-Durbin's summing of - * reflection coefficients, this loop could be executed in parallel - * by p processors in constant time. - */ - for (m = 0; m < P_MAX - i; m++) { - G[1][m] = G[1][m + 1] + r * G[0][m]; - G[0][m] = G[1][m + 1] * r + G[0][m]; - } - } -} - - - /* 0..7 IN/OUT */ -static void rToLAR(int *r) -/* - * The following scaling for r[..] and LAR[..] has been used: - * - * r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1. - * LAR[..] = integer( real_LAR[..] * 16384 ); - * with -1.625 <= real_LAR <= 1.625 - */ -{ - int temp; - int i; - - /* Computation of the LAR[0..7] from the r[0..7] - */ - for (i = 0; i < 8; i++) { - temp = abs(r[i]); //GSM_ABS(temp); - if (temp < 22118) { - temp >>= 1; - } else if (temp < 31130) { - temp -= 11059; - } else { - temp -= 26112; - temp <<= 2; - } - r[i] = r[i] < 0 ? -temp : temp; - } -} - -static void quantizeLARs(int *LARs, int *qLARs) -{ int qA[]={20480, 20480, 20480, 20480, 13964, 15360, 8534, 9036}; - int qB[]={0, 0, 2048, -2560, 94, -1792, -341, -1144}; - int qMin[]={-32, -32, -16, -16, -8, -8, -4, -4}; - int qMax[]={31, 31, 15, 15, 7, 7, 3, 3}; - int i; - for (i = 0; i < 8; i++) { - int temp; - temp = (((LARs[i] * qA[i]) >> 15) + qB[i] + 256) >> 9; - if (temp < qMin[i]) temp = 0; - else if (temp > qMax[i]) temp = qMax[i] - qMin[i]; - else temp = temp - qMin[i]; - qLARs[i] = temp; - } -} - -void lpcAnalysis(gsm_state *state, short *in) -{ float error; - float samples[160]; - float ac[9]; - float ref[8]; - int i; - int * qLARs = state->qLARs; - for (i = 0; i < 160; i++) { - samples[i] = in[i]; - } - autocorrelation(160, samples, 9, ac); - error=schur(ac, ref); - /* - printf("reff: "); - for (i=0;i<8;i++) { - printf("%5.5f ", ref[i]);//((float)i_lpc[i])/32768.0f); - } - printf("\n"); - */ - for (i = 0; i < 8; i++) { - qLARs[i] = (int) (32768 * ref[i]); - } - rToLAR(qLARs); - quantizeLARs(qLARs, qLARs); -} diff --git a/!NotAdopted/Tlen/codec/gsm_preprocess.c b/!NotAdopted/Tlen/codec/gsm_preprocess.c deleted file mode 100644 index b3d11bb7b1..0000000000 --- a/!NotAdopted/Tlen/codec/gsm_preprocess.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2004-2007 Piotr Piastucki - -This program is based on GSM 06.10 source code developed by -Jutta Degener and Carsten Bormann, -Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, -Technische Universitaet Berlin - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#include "gsm.h" -#include - -/* 4.2.0 .. 4.2.3 PREPROCESSING SECTION - * - * After A-law to linear conversion (or directly from the - * Ato D converter) the following scaling is assumed for - * input to the RPE-LTP algorithm: - * - * - * Where S is the sign bit, v a valid bit, and * a "don't care" bit. - * The original signal is called sop[..] - * - */ - - -void gsm_preprocessing( gsm_state *state, short *in, short *out) -{ - int z1 = state->z1; - int z2 = state->z2; - int mp = state->mp; - int so, s1; - int msp, lsp; - - int k = 160; - - while (k--) { - /* Downscaling of the input signal - * in: 0.1.....................12 - * S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.* - * out: 0.1................... 12 - * S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0 - */ - so = (*in >> 3) << 2; - in++; - /* 4.2.2 Offset compensation - * - * This part implements a high-pass filter and requires extended - * arithmetic precision for the recursive part of this filter. - * The input of this procedure is the array so[0...159] and the - * output the array sof[ 0...159 ]. - */ - /* Compute the non-recursive part - */ - s1 = (so - z1) << 15; - z1 = so; - msp = z2 >> 15; - lsp = z2 - (msp << 15); - s1 += ((lsp * 32735) + 16384) >> 15; - z2 = msp * 32735 + s1; - /* 4.2.3 Preemphasis - */ - msp = (-28180 * mp + 16384) >> 15; - mp = (z2 + 16384) >> 15; - *out++ = mp + msp; - } - state->z1 = z1; - state->z2 = z2; - state->mp = mp; -/* - printf("preprocessed: \n"); - for (k=0;k<160;k++) { - printf("%7d ", out[k]);//((float)i_lpc[i])/32768.0f); - } - printf("\n"); - */ -} - -void gsm_postprocessing( gsm_state *state, short *in, short *out) -{ - int k; - int msr = state->msr; - for (k = 160; k--; in++, out++) { - msr = *in + ((msr * 28180 + 16384) >>15); /* Deemphasis */ - *out = (msr + msr ) & 0xFFF8; /* Truncation & Upscaling */ - } - state->msr = msr; -} diff --git a/!NotAdopted/Tlen/codec/gsm_rpe.c b/!NotAdopted/Tlen/codec/gsm_rpe.c deleted file mode 100644 index ad7234e606..0000000000 --- a/!NotAdopted/Tlen/codec/gsm_rpe.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2004-2007 Piotr Piastucki - -This program is based on GSM 06.10 source code developed by -Jutta Degener and Carsten Bormann, -Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, -Technische Universitaet Berlin - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#include "gsm.h" -#include -#include -#include - -static const int gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 }; -static const int gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 }; -static const int gsm_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 }; -/* - * The coefficients of the weighting filter are stored in the gsm_H table. - * The following scaling is used: - * - * gsm_H[0..10] = integer( real_H[ 0..10] * 8192 ); - */ -static void weightingFilter (int *e, int *x) -{ - int L_result; - int k, i; - for (k = 0; k < 40; k++) { - L_result = 4096; - for (i = 0; i < 11; i++) { - int ix = i + k; - if (ix>4 && ix<45) L_result += e[ix - 5] * gsm_H[i]; - } - L_result >>= 13; - x[k] = (L_result < -32768 ? -32768 : (L_result > 32767 ? 32767 : L_result)); - } -} - -/* - * The signal x[0..39] is used to select the RPE grid which is - * represented by Mc. - */ -static void gridSelection( int *x, int *xM, int *Mc_out) -{ - int m, i; - int L_result, L_temp; - int EM, Mc; - - EM = 0; - Mc = 0; - - for (m = 0; m < 4; m++) { - L_result = 0; - for (i = 0; i < 13; i++) { - int temp = x[m + 3*i] >> 2; - L_temp = temp * temp << 1; - L_result += L_temp; - } - if (L_result > EM) { - Mc = m; - EM = L_result; - } - } - /* Down-sampling by a factor 3 to get the selected xM[0..12] - * RPE sequence. - */ - for (i = 0; i < 13; i ++) xM[i] = x[Mc + 3*i]; - *Mc_out = Mc; -} - -/* - * This procedure computes the reconstructed long term residual signal - * ep[0..39] for the LTP analysis filter. The inputs are the Mc - * which is the grid position selection and the xMp[0..12] decoded - * RPE samples which are upsampled by a factor of 3 by inserting zero - * values. - */ -static void gridPositioning (int Mc, int *xMp, int *ep) -{ - int i, k; - for (k = 0; k < 40; k++) ep[k] = 0; - for (i = 0; i < 13; i++) { - ep[ Mc + (3*i) ] = xMp[i]; - } -} - -static void APCMXmaxcToExpMant (int xmaxc, int *exp_out, int *mant_out ) -{ - int exp, mant; - /* Compute exponent and mantissa of the decoded version of xmaxc - */ - exp = 0; - if (xmaxc > 15) exp = (xmaxc >> 3) - 1; - mant = xmaxc - (exp << 3); - - if (mant == 0) { - exp = -4; - mant = 7; - } - else { - while (mant < 8) { - mant = mant << 1 | 1; - exp--; - } - mant -= 8; - } - - *exp_out = exp; - *mant_out = mant; -} - -static void APCMQuantization (int *xM, int *xMc, int *mant_out, int *exp_out, int *xmaxc_out) -{ - int i, itest; - int xmax, xmaxc, temp, temp1, temp2; - int exp, mant; - - - /* Find the maximum absolute value xmax of xM[0..12]. - */ - - xmax = 0; - for (i = 0; i < 13; i++) { - temp = abs(xM[i]); - if (temp > xmax) xmax = temp; - } - if (xmax > 32767) xmax = 32767; - /* Qantizing and coding of xmax to get xmaxc. - */ - - exp = 0; - temp = xmax >> 9; - itest = 0; - - for (i = 0; i < 6; i++) { - if (temp != 0) exp++; - temp = temp >> 1; - } - - temp = exp + 5; - - xmaxc = (xmax >> temp) + (exp << 3); - - /* Quantizing and coding of the xM[0..12] RPE sequence - * to get the xMc[0..12] - */ - APCMXmaxcToExpMant( xmaxc, &exp, &mant ); - - /* This computation uses the fact that the decoded version of xmaxc - * can be calculated by using the exponent and the mantissa part of - * xmaxc (logarithmic table). - * So, this method avoids any division and uses only a scaling - * of the RPE samples by a function of the exponent. A direct - * multiplication by the inverse of the mantissa (NRFAC[0..7] - * found in table 4.5) gives the 3 bit coded version xMc[0..12] - * of the RPE samples. - */ - - /* Direct computation of xMc[0..12] using table 4.5 - */ - temp = (mant|8)<<(5+exp); - temp1 = 6 - exp; - temp2 = gsm_NRFAC[ mant ]; - for (i = 0; i < 13; i++) { - xMc[i] = ((xM[i] << temp1) * temp2 >> 27) + 4; - } - - /* NOTE: This equation is used to make all the xMc[i] positive. - */ - - *mant_out = mant; - *exp_out = exp; - *xmaxc_out = xmaxc; -} - -static void APCMDequantization (int *xMc, int mant, int exp, int *xMp) -{ - int i, temp1, temp2, temp3; - temp1 = gsm_FAC[ mant ]; - temp2 = 6 - exp; - if (temp2 <= 0) { - temp3 = 1 >> (1 - temp2); - } else { - temp3 = 1 << (temp2 - 1); - } - for (i = 0; i < 13; i++) { - xMp[i] = ((((((xMc[i]<<1)-7)<<12)*temp1+16384)>>15)+temp3)>>temp2; - } -} - -void encodeRPE(gsm_state *state) -{ int x[40]; - int xM[13], xMp[13]; - int mant, exp; - int *Mc = state->Mc + state->subframe; - int *xMaxc = state->xMaxc + state->subframe; - int *xMc = state->xMc + state->subframe * 13; - int *e = state->e + state->subframe * 40; - //int i; - /* - printf("RPE in: \n"); - for (i=0;i<40;i++) { - printf("%7d ", e[i]); - } - printf("\n"); - */ - weightingFilter(e, x); - /* - printf("RPE weighting filter: \n"); - for (i=0;i<40;i++) { - printf("%7d ", x[i]); - } - printf("\n"); - */ - gridSelection(x, xM, Mc); - APCMQuantization(xM, xMc, &mant, &exp, xMaxc); - /* printf("RPE Mc(grid #)=%d xmaxc=%d mant=%d exp=%d \n", *Mc, *xMaxc, mant, exp); */ - APCMDequantization(xMc, mant, exp, xMp); - gridPositioning(*Mc, xMp, e); -} - -void decodeRPE(gsm_state *state) -{ - int exp, mant; - int xMp[ 13 ]; - int *xMc = state->xMc + state->subframe * 13; - int *e = state->e + state->subframe * 40; - - APCMXmaxcToExpMant(state->xMaxc[state->subframe], &exp, &mant); - APCMDequantization(xMc, mant, exp, xMp); - gridPositioning(state->Mc[state->subframe], xMp, e); -} diff --git a/!NotAdopted/Tlen/codec/gsm_short.c b/!NotAdopted/Tlen/codec/gsm_short.c deleted file mode 100644 index c461484639..0000000000 --- a/!NotAdopted/Tlen/codec/gsm_short.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2004-2007 Piotr Piastucki - -This program is based on GSM 06.10 source code developed by -Jutta Degener and Carsten Bormann, -Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, -Technische Universitaet Berlin - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#include "gsm.h" -#include -#include -#include -extern void lpcAnalysis(gsm_state *state, short *in); - -/* - * Dequantize LAR coefficients - */ -static void dequantizeLARs(int *qLARs, int *LARs) -{ - int dqA[]={13107, 13107, 13107, 13107, 19223, 17476, 31454, 29708}; - int dqB[]={0, 0, 2048, -2560, 94, -1792, -341, -1144}; - int dqMin[]={-32, -32, -16, -16, -8, -8, -4, -4}; - int i; - for (i = 0; i < 8; i++) { - int temp; - temp = ((((qLARs[i] + dqMin[i]) << 10) - (dqB[i] << 1)) * dqA[i] + 16384) >> 15; - LARs[i] = temp + temp; - } -} -/* - * Interpolate LAR coefficients (samples 0..12) - */ -static void interpolateLARs_0_12 (int *LARpp_j_1, int *LARpp_j, int *LARp) -{ int i; - for (i = 0; i < 8; i++) { - LARp[i] = (LARpp_j_1[i] >> 1) + (LARpp_j_1[i] >> 2) + (LARpp_j[i] >> 2); - } -} -/* - * Interpolate LAR coefficients (samples 13..26) - */ -static void interpolateLARs_13_26 (int *LARpp_j_1, int *LARpp_j, int *LARp) -{ int i; - for (i = 0; i < 8; i++) { - LARp[i] = (LARpp_j_1[i] >> 1) + (LARpp_j[i] >> 1); - } -} -/* - * Interpolate LAR coefficients (samples 27..39) - */ -static void interpolateLARs_27_39 (int *LARpp_j_1, int *LARpp_j, int *LARp) -{ int i; - for (i = 0; i < 8; i++) { - LARp[i] = (LARpp_j[i] >> 1) + (LARpp_j_1[i] >> 2) + (LARpp_j[i] >> 2); - } -} -/* - * Interpolate LAR coefficients (samples 40..159) - */ -static void interpolateLARs_40_159 (int *LARpp_j_1, int *LARpp_j, int *LARp) -{ int i; - for (i = 0; i < 8; i++) { - LARp[i] = LARpp_j[i]; - } -} -/* - * Convert LAR coefficients to reflection coefficients - */ -static void LARToR( int * LARp) -{ - int i; - int temp; - for (i = 0; i < 8; i++) { - temp = abs(LARp[i]); - if (temp < 11059) temp <<= 1; - else if (temp < 20070) temp += 11059; - else temp = (temp >> 2) + 26112; - LARp[i] = LARp[i] < 0 ? -temp : temp; - } -} - -/* - * This procedure computes the short term residual signal d[..] to be fed - * to the RPE-LTP loop from the s[..] signal and from the local rp[..] - * array (quantized reflection coefficients). As the call of this - * procedure can be done in many ways (see the interpolation of the LAR - * coefficient), it is assumed that the computation begins with index - * k_start (for arrays d[..] and s[..]) and stops with index k_end - * (k_start and k_end are defined in 4.2.9.1). This procedure also - * needs to keep the array u[0..7] in memory for each call. - */ -static void shortTermAnalysisFilter (gsm_state * state, int * rp, int len, short * in) -{ - int * u = state->u; - int i; - int di, ui, sav, rpi; - for (; len--; in++) { - di = sav = *in; - for (i = 0; i < 8; i++) { - ui = u[i]; - rpi = rp[i]; - u[i] = sav; - sav = ui + ((rpi * di + 16384) >> 15); - di = di + ((rpi * ui + 16384) >> 15); - } - *in = di; - } -} - -static void shortTermSynthesisFilter(gsm_state * state, int * rrp, int len, short * in, short *out) -{ - int * v = state->v; - int i; - int sri; - for (; len--; in++, out++) { - sri = *in; - for (i = 8; i--;) { - sri -= (rrp[i] * v[i] + 16384) >> 15; - if (sri < -32768) sri = -32768; - else if (sri > 32767) sri = 32767; - v[i+1] = v[i] + ((rrp[i] * sri + 16384) >> 15); - if (v[i+1] < -32768) v[i+1] = -32768; - else if (v[i+1] > 32767) v[i+1] = 32767; - } - *out = v[0] = sri; - } -} - -void shortTermAnalysis(gsm_state *state, short *in) -{ - int * qLARs = state->qLARs; - int * LARpp_j = state->LARpp[state->j]; - int * LARpp_j_1 = state->LARpp[state->j ^1]; - int LARp[8]; -// int i; - - lpcAnalysis(state, in);//i_samples); -/* - printf("short term in: \n"); - for (i=0;i<160;i++) { - printf("%7d ", in[i]);//((float)i_lpc[i])/32768.0f); - } - printf("\n"); - */ - dequantizeLARs(qLARs, LARpp_j); - interpolateLARs_0_12(LARpp_j_1, LARpp_j, LARp); - LARToR(LARp); - shortTermAnalysisFilter(state, LARp, 13, in); - interpolateLARs_13_26(LARpp_j_1, LARpp_j, LARp); - LARToR(LARp); - shortTermAnalysisFilter(state, LARp, 14, in+13); - interpolateLARs_27_39(LARpp_j_1, LARpp_j, LARp); - LARToR(LARp); - shortTermAnalysisFilter(state, LARp, 13, in+27); - interpolateLARs_40_159(LARpp_j_1, LARpp_j, LARp); - LARToR(LARp); - shortTermAnalysisFilter(state, LARp, 120, in+40); - /* - printf("short-term residuals: \n"); - for (i=0;i<160;i++) { - printf("%7d ", in[i]);//((float)i_lpc[i])/32768.0f); - } - printf("\n"); - */ -} - -void shortTermSynthesis(gsm_state *state, short *in, short *out) -{ - int * qLARs = state->qLARs; - int * LARpp_j = state->LARpp[state->j]; - int * LARpp_j_1 = state->LARpp[state->j ^1]; - int LARp[8]; -// int i; - - dequantizeLARs(qLARs, LARpp_j); - interpolateLARs_0_12(LARpp_j_1, LARpp_j, LARp); - LARToR(LARp); - shortTermSynthesisFilter(state, LARp, 13, in, out); - interpolateLARs_13_26(LARpp_j_1, LARpp_j, LARp); - LARToR(LARp); - shortTermSynthesisFilter(state, LARp, 14, in+13, out+13); - interpolateLARs_27_39(LARpp_j_1, LARpp_j, LARp); - LARToR(LARp); - shortTermSynthesisFilter(state, LARp, 13, in+27, out+27); - interpolateLARs_40_159(LARpp_j_1, LARpp_j, LARp); - LARToR(LARp); - shortTermSynthesisFilter(state, LARp, 120, in+40, out+40); - /* - printf("samples[reconstructed]: \n"); - for (i=0;i<160;i++) { - printf("%7d ", out[i]); - } - */ -} diff --git a/!NotAdopted/Tlen/commons.h b/!NotAdopted/Tlen/commons.h deleted file mode 100644 index af5a9bbcd7..0000000000 --- a/!NotAdopted/Tlen/commons.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _TLENCOMMONS_INC -#define _TLENCOMMONS_INC - - -#define TLENMUCC_MAJOR_VERSION 2 -#define TLENMUCC_MINOR_VERSION 0 -#define TLENMUCC_RELEASE_NUM 5 -#define TLENMUCC_BUILD_NUM 0 -#define TLENMUCC_VERSION_STRING "2.0.5.0" - - - -//consts for tlen.dll -#define TLEN_MAJOR_VERSION TLENMUCC_MAJOR_VERSION -#define TLEN_MINOR_VERSION TLENMUCC_MINOR_VERSION -#define TLEN_RELEASE_NUM TLENMUCC_RELEASE_NUM -#define TLEN_BUILD_NUM TLENMUCC_BUILD_NUM - -#define TLEN_FILEVERSION_STRING TLEN_MAJOR_VERSION,TLEN_MINOR_VERSION,TLEN_RELEASE_NUM,TLEN_BUILD_NUM -#define TLEN_VERSION_STRING TLENMUCC_VERSION_STRING - -//consts for tlen_czaty.dll -#define MUCC_MAJOR_VERSION TLENMUCC_MAJOR_VERSION -#define MUCC_MINOR_VERSION TLENMUCC_MINOR_VERSION -#define MUCC_RELEASE_NUM TLENMUCC_RELEASE_NUM -#define MUCC_BUILD_NUM TLENMUCC_BUILD_NUM - -#define MUCC_FILEVERSION_STRING MUCC_MAJOR_VERSION,MUCC_MINOR_VERSION,MUCC_RELEASE_NUM,MUCC_BUILD_NUM -#define MUCC_VERSION_STRING TLENMUCC_VERSION_STRING - - -#endif //ifndef _TLENCOMMONS_INC diff --git a/!NotAdopted/Tlen/crypto/aes.c b/!NotAdopted/Tlen/crypto/aes.c deleted file mode 100644 index 7bccdf93a1..0000000000 --- a/!NotAdopted/Tlen/crypto/aes.c +++ /dev/null @@ -1,1336 +0,0 @@ -/* - * FIPS-197 compliant AES implementation - * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* - * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. - * - * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf - * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf - */ - -#include "polarssl/config.h" - -#if defined(POLARSSL_AES_C) - -#include "polarssl/aes.h" -#include "polarssl/padlock.h" - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_ULONG_LE -#define GET_ULONG_LE(n,b,i) \ -{ \ - (n) = ( (unsigned long) (b)[(i) ] ) \ - | ( (unsigned long) (b)[(i) + 1] << 8 ) \ - | ( (unsigned long) (b)[(i) + 2] << 16 ) \ - | ( (unsigned long) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_ULONG_LE -#define PUT_ULONG_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ -} -#endif - -#if defined(POLARSSL_AES_ROM_TABLES) -/* - * Forward S-box - */ -static const unsigned char FSb[256] = -{ - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, - 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, - 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, - 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, - 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, - 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, - 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, - 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, - 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, - 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, - 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, - 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, - 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, - 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, - 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, - 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, - 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, - 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, - 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, - 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, - 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, - 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, - 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, - 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, - 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, - 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, - 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 -}; - -/* - * Forward tables - */ -#define FT \ -\ - V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \ - V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \ - V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \ - V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \ - V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \ - V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \ - V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \ - V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \ - V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \ - V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \ - V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \ - V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \ - V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \ - V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \ - V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \ - V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \ - V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \ - V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \ - V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \ - V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \ - V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \ - V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \ - V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \ - V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \ - V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \ - V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \ - V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \ - V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \ - V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \ - V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \ - V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \ - V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \ - V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \ - V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \ - V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \ - V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \ - V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \ - V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \ - V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \ - V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \ - V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \ - V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \ - V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \ - V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \ - V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \ - V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \ - V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \ - V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \ - V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \ - V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \ - V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \ - V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \ - V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \ - V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \ - V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \ - V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \ - V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \ - V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \ - V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \ - V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \ - V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \ - V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \ - V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \ - V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C) - -#define V(a,b,c,d) 0x##a##b##c##d -static const unsigned long FT0[256] = { FT }; -#undef V - -#define V(a,b,c,d) 0x##b##c##d##a -static const unsigned long FT1[256] = { FT }; -#undef V - -#define V(a,b,c,d) 0x##c##d##a##b -static const unsigned long FT2[256] = { FT }; -#undef V - -#define V(a,b,c,d) 0x##d##a##b##c -static const unsigned long FT3[256] = { FT }; -#undef V - -#undef FT - -/* - * Reverse S-box - */ -static const unsigned char RSb[256] = -{ - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, - 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, - 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, - 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, - 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, - 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, - 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, - 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, - 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, - 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, - 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, - 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, - 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, - 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, - 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, - 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, - 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, - 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, - 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, - 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, - 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, - 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, - 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, - 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, - 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, - 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D -}; - -/* - * Reverse tables - */ -#define RT \ -\ - V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \ - V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \ - V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \ - V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \ - V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \ - V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \ - V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \ - V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \ - V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \ - V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \ - V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \ - V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \ - V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \ - V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \ - V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \ - V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \ - V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \ - V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \ - V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \ - V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \ - V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \ - V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \ - V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \ - V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \ - V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \ - V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \ - V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \ - V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \ - V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \ - V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \ - V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \ - V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \ - V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \ - V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \ - V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \ - V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \ - V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \ - V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \ - V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \ - V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \ - V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \ - V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \ - V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \ - V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \ - V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \ - V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \ - V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \ - V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \ - V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \ - V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \ - V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \ - V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \ - V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \ - V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \ - V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \ - V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \ - V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \ - V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \ - V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \ - V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \ - V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \ - V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \ - V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \ - V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0) - -#define V(a,b,c,d) 0x##a##b##c##d -static const unsigned long RT0[256] = { RT }; -#undef V - -#define V(a,b,c,d) 0x##b##c##d##a -static const unsigned long RT1[256] = { RT }; -#undef V - -#define V(a,b,c,d) 0x##c##d##a##b -static const unsigned long RT2[256] = { RT }; -#undef V - -#define V(a,b,c,d) 0x##d##a##b##c -static const unsigned long RT3[256] = { RT }; -#undef V - -#undef RT - -/* - * Round constants - */ -static const unsigned long RCON[10] = -{ - 0x00000001, 0x00000002, 0x00000004, 0x00000008, - 0x00000010, 0x00000020, 0x00000040, 0x00000080, - 0x0000001B, 0x00000036 -}; - -#else - -/* - * Forward S-box & tables - */ -static unsigned char FSb[256]; -static unsigned long FT0[256]; -static unsigned long FT1[256]; -static unsigned long FT2[256]; -static unsigned long FT3[256]; - -/* - * Reverse S-box & tables - */ -static unsigned char RSb[256]; -static unsigned long RT0[256]; -static unsigned long RT1[256]; -static unsigned long RT2[256]; -static unsigned long RT3[256]; - -/* - * Round constants - */ -static unsigned long RCON[10]; - -/* - * Tables generation code - */ -#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 ) -#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) -#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 ) - -static int aes_init_done = 0; - -static void aes_gen_tables( void ) -{ - int i, x, y, z; - int pow[256]; - int log[256]; - - /* - * compute pow and log tables over GF(2^8) - */ - for( i = 0, x = 1; i < 256; i++ ) - { - pow[i] = x; - log[x] = i; - x = ( x ^ XTIME( x ) ) & 0xFF; - } - - /* - * calculate the round constants - */ - for( i = 0, x = 1; i < 10; i++ ) - { - RCON[i] = (unsigned long) x; - x = XTIME( x ) & 0xFF; - } - - /* - * generate the forward and reverse S-boxes - */ - FSb[0x00] = 0x63; - RSb[0x63] = 0x00; - - for( i = 1; i < 256; i++ ) - { - x = pow[255 - log[i]]; - - y = x; y = ( (y << 1) | (y >> 7) ) & 0xFF; - x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF; - x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF; - x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF; - x ^= y ^ 0x63; - - FSb[i] = (unsigned char) x; - RSb[x] = (unsigned char) i; - } - - /* - * generate the forward and reverse tables - */ - for( i = 0; i < 256; i++ ) - { - x = FSb[i]; - y = XTIME( x ) & 0xFF; - z = ( y ^ x ) & 0xFF; - - FT0[i] = ( (unsigned long) y ) ^ - ( (unsigned long) x << 8 ) ^ - ( (unsigned long) x << 16 ) ^ - ( (unsigned long) z << 24 ); - - FT1[i] = ROTL8( FT0[i] ); - FT2[i] = ROTL8( FT1[i] ); - FT3[i] = ROTL8( FT2[i] ); - - x = RSb[i]; - - RT0[i] = ( (unsigned long) MUL( 0x0E, x ) ) ^ - ( (unsigned long) MUL( 0x09, x ) << 8 ) ^ - ( (unsigned long) MUL( 0x0D, x ) << 16 ) ^ - ( (unsigned long) MUL( 0x0B, x ) << 24 ); - - RT1[i] = ROTL8( RT0[i] ); - RT2[i] = ROTL8( RT1[i] ); - RT3[i] = ROTL8( RT2[i] ); - } -} - -#endif - -/* - * AES key schedule (encryption) - */ -int aes_setkey_enc( aes_context *ctx, const unsigned char *key, unsigned int keysize ) -{ - unsigned int i; - unsigned long *RK; - -#if !defined(POLARSSL_AES_ROM_TABLES) - if( aes_init_done == 0 ) - { - aes_gen_tables(); - aes_init_done = 1; - } -#endif - - switch( keysize ) - { - case 128: ctx->nr = 10; break; - case 192: ctx->nr = 12; break; - case 256: ctx->nr = 14; break; - default : return( POLARSSL_ERR_AES_INVALID_KEY_LENGTH ); - } - -#if defined(PADLOCK_ALIGN16) - ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf ); -#else - ctx->rk = RK = ctx->buf; -#endif - - for( i = 0; i < (keysize >> 5); i++ ) - { - GET_ULONG_LE( RK[i], key, i << 2 ); - } - - switch( ctx->nr ) - { - case 10: - - for( i = 0; i < 10; i++, RK += 4 ) - { - RK[4] = RK[0] ^ RCON[i] ^ - ( (unsigned long) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^ - ( (unsigned long) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^ - ( (unsigned long) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^ - ( (unsigned long) FSb[ ( RK[3] ) & 0xFF ] << 24 ); - - RK[5] = RK[1] ^ RK[4]; - RK[6] = RK[2] ^ RK[5]; - RK[7] = RK[3] ^ RK[6]; - } - break; - - case 12: - - for( i = 0; i < 8; i++, RK += 6 ) - { - RK[6] = RK[0] ^ RCON[i] ^ - ( (unsigned long) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^ - ( (unsigned long) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^ - ( (unsigned long) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^ - ( (unsigned long) FSb[ ( RK[5] ) & 0xFF ] << 24 ); - - RK[7] = RK[1] ^ RK[6]; - RK[8] = RK[2] ^ RK[7]; - RK[9] = RK[3] ^ RK[8]; - RK[10] = RK[4] ^ RK[9]; - RK[11] = RK[5] ^ RK[10]; - } - break; - - case 14: - - for( i = 0; i < 7; i++, RK += 8 ) - { - RK[8] = RK[0] ^ RCON[i] ^ - ( (unsigned long) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^ - ( (unsigned long) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^ - ( (unsigned long) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^ - ( (unsigned long) FSb[ ( RK[7] ) & 0xFF ] << 24 ); - - RK[9] = RK[1] ^ RK[8]; - RK[10] = RK[2] ^ RK[9]; - RK[11] = RK[3] ^ RK[10]; - - RK[12] = RK[4] ^ - ( (unsigned long) FSb[ ( RK[11] ) & 0xFF ] ) ^ - ( (unsigned long) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^ - ( (unsigned long) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^ - ( (unsigned long) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 ); - - RK[13] = RK[5] ^ RK[12]; - RK[14] = RK[6] ^ RK[13]; - RK[15] = RK[7] ^ RK[14]; - } - break; - - default: - - break; - } - - return( 0 ); -} - -/* - * AES key schedule (decryption) - */ -int aes_setkey_dec( aes_context *ctx, const unsigned char *key, unsigned int keysize ) -{ - int i, j; - aes_context cty; - unsigned long *RK; - unsigned long *SK; - int ret; - - switch( keysize ) - { - case 128: ctx->nr = 10; break; - case 192: ctx->nr = 12; break; - case 256: ctx->nr = 14; break; - default : return( POLARSSL_ERR_AES_INVALID_KEY_LENGTH ); - } - -#if defined(PADLOCK_ALIGN16) - ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf ); -#else - ctx->rk = RK = ctx->buf; -#endif - - ret = aes_setkey_enc( &cty, key, keysize ); - if( ret != 0 ) - return( ret ); - - SK = cty.rk + cty.nr * 4; - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - - for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 ) - { - for( j = 0; j < 4; j++, SK++ ) - { - *RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^ - RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^ - RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^ - RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ]; - } - } - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - - memset( &cty, 0, sizeof( aes_context ) ); - - return( 0 ); -} - -#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ -{ \ - X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \ - FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ - FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ - FT3[ ( Y3 >> 24 ) & 0xFF ]; \ - \ - X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \ - FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ - FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ - FT3[ ( Y0 >> 24 ) & 0xFF ]; \ - \ - X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \ - FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ - FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ - FT3[ ( Y1 >> 24 ) & 0xFF ]; \ - \ - X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \ - FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ - FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ - FT3[ ( Y2 >> 24 ) & 0xFF ]; \ -} - -#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ -{ \ - X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \ - RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ - RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ - RT3[ ( Y1 >> 24 ) & 0xFF ]; \ - \ - X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \ - RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ - RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ - RT3[ ( Y2 >> 24 ) & 0xFF ]; \ - \ - X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \ - RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ - RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ - RT3[ ( Y3 >> 24 ) & 0xFF ]; \ - \ - X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \ - RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ - RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ - RT3[ ( Y0 >> 24 ) & 0xFF ]; \ -} - -/* - * AES-ECB block encryption/decryption - */ -int aes_crypt_ecb( aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ) -{ - int i; - unsigned long *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; - -#if defined(POLARSSL_PADLOCK_C) && defined(POLARSSL_HAVE_X86) - if( padlock_supports( PADLOCK_ACE ) ) - { - if( padlock_xcryptecb( ctx, mode, input, output ) == 0 ) - return( 0 ); - - // If padlock data misaligned, we just fall back to - // unaccelerated mode - // - } -#endif - - RK = ctx->rk; - - GET_ULONG_LE( X0, input, 0 ); X0 ^= *RK++; - GET_ULONG_LE( X1, input, 4 ); X1 ^= *RK++; - GET_ULONG_LE( X2, input, 8 ); X2 ^= *RK++; - GET_ULONG_LE( X3, input, 12 ); X3 ^= *RK++; - - if( mode == AES_DECRYPT ) - { - for( i = (ctx->nr >> 1) - 1; i > 0; i-- ) - { - AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); - } - - AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - - X0 = *RK++ ^ \ - ( (unsigned long) RSb[ ( Y0 ) & 0xFF ] ) ^ - ( (unsigned long) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ - ( (unsigned long) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ - ( (unsigned long) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); - - X1 = *RK++ ^ \ - ( (unsigned long) RSb[ ( Y1 ) & 0xFF ] ) ^ - ( (unsigned long) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ - ( (unsigned long) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ - ( (unsigned long) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); - - X2 = *RK++ ^ \ - ( (unsigned long) RSb[ ( Y2 ) & 0xFF ] ) ^ - ( (unsigned long) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ - ( (unsigned long) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ - ( (unsigned long) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); - - X3 = *RK++ ^ \ - ( (unsigned long) RSb[ ( Y3 ) & 0xFF ] ) ^ - ( (unsigned long) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ - ( (unsigned long) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ - ( (unsigned long) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); - } - else /* AES_ENCRYPT */ - { - for( i = (ctx->nr >> 1) - 1; i > 0; i-- ) - { - AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); - } - - AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - - X0 = *RK++ ^ \ - ( (unsigned long) FSb[ ( Y0 ) & 0xFF ] ) ^ - ( (unsigned long) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ - ( (unsigned long) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ - ( (unsigned long) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); - - X1 = *RK++ ^ \ - ( (unsigned long) FSb[ ( Y1 ) & 0xFF ] ) ^ - ( (unsigned long) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ - ( (unsigned long) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ - ( (unsigned long) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); - - X2 = *RK++ ^ \ - ( (unsigned long) FSb[ ( Y2 ) & 0xFF ] ) ^ - ( (unsigned long) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ - ( (unsigned long) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ - ( (unsigned long) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); - - X3 = *RK++ ^ \ - ( (unsigned long) FSb[ ( Y3 ) & 0xFF ] ) ^ - ( (unsigned long) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ - ( (unsigned long) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ - ( (unsigned long) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); - } - - PUT_ULONG_LE( X0, output, 0 ); - PUT_ULONG_LE( X1, output, 4 ); - PUT_ULONG_LE( X2, output, 8 ); - PUT_ULONG_LE( X3, output, 12 ); - - return( 0 ); -} - -/* - * AES-CBC buffer encryption/decryption - */ -int aes_crypt_cbc( aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int i; - unsigned char temp[16]; - - if( length % 16 ) - return( POLARSSL_ERR_AES_INVALID_INPUT_LENGTH ); - -#if defined(POLARSSL_PADLOCK_C) && defined(POLARSSL_HAVE_X86) - if( padlock_supports( PADLOCK_ACE ) ) - { - if( padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 ) - return( 0 ); - - // If padlock data misaligned, we just fall back to - // unaccelerated mode - // - } -#endif - - if( mode == AES_DECRYPT ) - { - while( length > 0 ) - { - memcpy( temp, input, 16 ); - aes_crypt_ecb( ctx, mode, input, output ); - - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); - - memcpy( iv, temp, 16 ); - - input += 16; - output += 16; - length -= 16; - } - } - else - { - while( length > 0 ) - { - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - aes_crypt_ecb( ctx, mode, output, output ); - memcpy( iv, output, 16 ); - - input += 16; - output += 16; - length -= 16; - } - } - - return( 0 ); -} - -#if defined(POLARSSL_CIPHER_MODE_CFB) -/* - * AES-CFB128 buffer encryption/decryption - */ -int aes_crypt_cfb128( aes_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int c; - size_t n = *iv_off; - - if( mode == AES_DECRYPT ) - { - while( length-- ) - { - if( n == 0 ) - aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv ); - - c = *input++; - *output++ = (unsigned char)( c ^ iv[n] ); - iv[n] = (unsigned char) c; - - n = (n + 1) & 0x0F; - } - } - else - { - while( length-- ) - { - if( n == 0 ) - aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv ); - - iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); - - n = (n + 1) & 0x0F; - } - } - - *iv_off = n; - - return( 0 ); -} -#endif /*POLARSSL_CIPHER_MODE_CFB */ - -#if defined(POLARSSL_CIPHER_MODE_CTR) -/* - * AES-CTR buffer encryption/decryption - */ -int aes_crypt_ctr( aes_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[16], - unsigned char stream_block[16], - const unsigned char *input, - unsigned char *output ) -{ - int c, i, cb; - size_t n = *nc_off; - - while( length-- ) - { - if( n == 0 ) { - aes_crypt_ecb( ctx, AES_ENCRYPT, nonce_counter, stream_block ); - - i = 15; - do { - nonce_counter[i]++; - cb = nonce_counter[i] == 0; - } while( i-- && cb ); - - } - c = *input++; - *output++ = (unsigned char)( c ^ stream_block[n] ); - - n = (n + 1) & 0x0F; - } - - *nc_off = n; - - return( 0 ); -} -#endif /* POLARSSL_CIPHER_MODE_CTR */ - -#if defined(POLARSSL_SELF_TEST) - -#include - -/* - * AES test vectors from: - * - * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip - */ -static const unsigned char aes_test_ecb_dec[3][16] = -{ - { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58, - 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 }, - { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, - 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 }, - { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, - 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE } -}; - -static const unsigned char aes_test_ecb_enc[3][16] = -{ - { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73, - 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F }, - { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11, - 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 }, - { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D, - 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 } -}; - -static const unsigned char aes_test_cbc_dec[3][16] = -{ - { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73, - 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 }, - { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75, - 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B }, - { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75, - 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 } -}; - -static const unsigned char aes_test_cbc_enc[3][16] = -{ - { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84, - 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D }, - { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB, - 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 }, - { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5, - 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 } -}; - -#if defined(POLARSSL_CIPHER_MODE_CFB) -/* - * AES-CFB128 test vectors from: - * - * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf - */ -static const unsigned char aes_test_cfb128_key[3][32] = -{ - { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, - { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, - 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, - 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, - { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } -}; - -static const unsigned char aes_test_cfb128_iv[16] = -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F -}; - -static const unsigned char aes_test_cfb128_pt[64] = -{ - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 -}; - -static const unsigned char aes_test_cfb128_ct[3][64] = -{ - { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, - 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, - 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F, - 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B, - 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40, - 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF, - 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E, - 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 }, - { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, - 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, - 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21, - 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A, - 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1, - 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9, - 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0, - 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF }, - { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, - 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, - 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8, - 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B, - 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92, - 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9, - 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8, - 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 } -}; -#endif /* POLARSSL_CIPHER_MODE_CFB */ - -#if defined(POLARSSL_CIPHER_MODE_CTR) -/* - * AES-CTR test vectors from: - * - * http://www.faqs.org/rfcs/rfc3686.html - */ - -static const unsigned char aes_test_ctr_key[3][16] = -{ - { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, - 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, - { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, - 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, - { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, - 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } -}; - -static const unsigned char aes_test_ctr_nonce_counter[3][16] = -{ - { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, - 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, - 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } -}; - -static const unsigned char aes_test_ctr_pt[3][48] = -{ - { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, - 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x20, 0x21, 0x22, 0x23 } -}; - -static const unsigned char aes_test_ctr_ct[3][48] = -{ - { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, - 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 }, - { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, - 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, - 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, - 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 }, - { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, - 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, - 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, - 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, - 0x25, 0xB2, 0x07, 0x2F } -}; - -static const int aes_test_ctr_len[3] = - { 16, 32, 36 }; -#endif /* POLARSSL_CIPHER_MODE_CTR */ - -/* - * Checkup routine - */ -int aes_self_test( int verbose ) -{ - int i, j, u, v; - unsigned char key[32]; - unsigned char buf[64]; - unsigned char prv[16]; - unsigned char iv[16]; -#if defined(POLARSSL_CIPHER_MODE_CTR) || defined(POLARSSL_CIPHER_MODE_CFB) - size_t offset; -#endif -#if defined(POLARSSL_CIPHER_MODE_CTR) - int len; - unsigned char nonce_counter[16]; - unsigned char stream_block[16]; -#endif - aes_context ctx; - - memset( key, 0, 32 ); - - /* - * ECB mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - v = i & 1; - - if( verbose != 0 ) - printf( " AES-ECB-%3d (%s): ", 128 + u * 64, - ( v == AES_DECRYPT ) ? "dec" : "enc" ); - - memset( buf, 0, 16 ); - - if( v == AES_DECRYPT ) - { - aes_setkey_dec( &ctx, key, 128 + u * 64 ); - - for( j = 0; j < 10000; j++ ) - aes_crypt_ecb( &ctx, v, buf, buf ); - - if( memcmp( buf, aes_test_ecb_dec[u], 16 ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - } - else - { - aes_setkey_enc( &ctx, key, 128 + u * 64 ); - - for( j = 0; j < 10000; j++ ) - aes_crypt_ecb( &ctx, v, buf, buf ); - - if( memcmp( buf, aes_test_ecb_enc[u], 16 ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - } - - if( verbose != 0 ) - printf( "passed\n" ); - } - - if( verbose != 0 ) - printf( "\n" ); - - /* - * CBC mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - v = i & 1; - - if( verbose != 0 ) - printf( " AES-CBC-%3d (%s): ", 128 + u * 64, - ( v == AES_DECRYPT ) ? "dec" : "enc" ); - - memset( iv , 0, 16 ); - memset( prv, 0, 16 ); - memset( buf, 0, 16 ); - - if( v == AES_DECRYPT ) - { - aes_setkey_dec( &ctx, key, 128 + u * 64 ); - - for( j = 0; j < 10000; j++ ) - aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); - - if( memcmp( buf, aes_test_cbc_dec[u], 16 ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - } - else - { - aes_setkey_enc( &ctx, key, 128 + u * 64 ); - - for( j = 0; j < 10000; j++ ) - { - unsigned char tmp[16]; - - aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); - - memcpy( tmp, prv, 16 ); - memcpy( prv, buf, 16 ); - memcpy( buf, tmp, 16 ); - } - - if( memcmp( prv, aes_test_cbc_enc[u], 16 ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - } - - if( verbose != 0 ) - printf( "passed\n" ); - } - - if( verbose != 0 ) - printf( "\n" ); - -#if defined(POLARSSL_CIPHER_MODE_CFB) - /* - * CFB128 mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - v = i & 1; - - if( verbose != 0 ) - printf( " AES-CFB128-%3d (%s): ", 128 + u * 64, - ( v == AES_DECRYPT ) ? "dec" : "enc" ); - - memcpy( iv, aes_test_cfb128_iv, 16 ); - memcpy( key, aes_test_cfb128_key[u], 16 + u * 8 ); - - offset = 0; - aes_setkey_enc( &ctx, key, 128 + u * 64 ); - - if( v == AES_DECRYPT ) - { - memcpy( buf, aes_test_cfb128_ct[u], 64 ); - aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); - - if( memcmp( buf, aes_test_cfb128_pt, 64 ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - } - else - { - memcpy( buf, aes_test_cfb128_pt, 64 ); - aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); - - if( memcmp( buf, aes_test_cfb128_ct[u], 64 ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - } - - if( verbose != 0 ) - printf( "passed\n" ); - } - - if( verbose != 0 ) - printf( "\n" ); -#endif /* POLARSSL_CIPHER_MODE_CFB */ - -#if defined(POLARSSL_CIPHER_MODE_CTR) - /* - * CTR mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - v = i & 1; - - if( verbose != 0 ) - printf( " AES-CTR-128 (%s): ", - ( v == AES_DECRYPT ) ? "dec" : "enc" ); - - memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); - memcpy( key, aes_test_ctr_key[u], 16 ); - - offset = 0; - aes_setkey_enc( &ctx, key, 128 ); - - if( v == AES_DECRYPT ) - { - len = aes_test_ctr_len[u]; - memcpy( buf, aes_test_ctr_ct[u], len ); - - aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, buf, buf ); - - if( memcmp( buf, aes_test_ctr_pt[u], len ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - } - else - { - len = aes_test_ctr_len[u]; - memcpy( buf, aes_test_ctr_pt[u], len ); - - aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, buf, buf ); - - if( memcmp( buf, aes_test_ctr_ct[u], len ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - } - - if( verbose != 0 ) - printf( "passed\n" ); - } - - if( verbose != 0 ) - printf( "\n" ); -#endif /* POLARSSL_CIPHER_MODE_CTR */ - - return( 0 ); -} - -#endif - -#endif diff --git a/!NotAdopted/Tlen/crypto/bignum.c b/!NotAdopted/Tlen/crypto/bignum.c deleted file mode 100644 index eabfbfe6f9..0000000000 --- a/!NotAdopted/Tlen/crypto/bignum.c +++ /dev/null @@ -1,2097 +0,0 @@ -/* - * Multi-precision integer library - * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* - * This MPI implementation is based on: - * - * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf - * http://www.stillhq.com/extracted/gnupg-api/mpi/ - * http://math.libtomcrypt.com/files/tommath.pdf - */ - -#include "polarssl/config.h" - -#if defined(POLARSSL_BIGNUM_C) - -#include "polarssl/bignum.h" -#include "polarssl/bn_mul.h" - -#include - -#define ciL (sizeof(t_uint)) /* chars in limb */ -#define biL (ciL << 3) /* bits in limb */ -#define biH (ciL << 2) /* half limb size */ - -/* - * Convert between bits/chars and number of limbs - */ -#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL) -#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL) - -/* - * Initialize one MPI - */ -void mpi_init( mpi *X ) -{ - if( X == NULL ) - return; - - X->s = 1; - X->n = 0; - X->p = NULL; -} - -/* - * Unallocate one MPI - */ -void mpi_free( mpi *X ) -{ - if( X == NULL ) - return; - - if( X->p != NULL ) - { - memset( X->p, 0, X->n * ciL ); - free( X->p ); - } - - X->s = 1; - X->n = 0; - X->p = NULL; -} - -/* - * Enlarge to the specified number of limbs - */ -int mpi_grow( mpi *X, size_t nblimbs ) -{ - t_uint *p; - - if( nblimbs > POLARSSL_MPI_MAX_LIMBS ) - return( 1 ); - - if( X->n < nblimbs ) - { - if( ( p = (t_uint *) malloc( nblimbs * ciL ) ) == NULL ) - return( 1 ); - - memset( p, 0, nblimbs * ciL ); - - if( X->p != NULL ) - { - memcpy( p, X->p, X->n * ciL ); - memset( X->p, 0, X->n * ciL ); - free( X->p ); - } - - X->n = nblimbs; - X->p = p; - } - - return( 0 ); -} - -/* - * Copy the contents of Y into X - */ -int mpi_copy( mpi *X, const mpi *Y ) -{ - int ret; - size_t i; - - if( X == Y ) - return( 0 ); - - for( i = Y->n - 1; i > 0; i-- ) - if( Y->p[i] != 0 ) - break; - i++; - - X->s = Y->s; - - MPI_CHK( mpi_grow( X, i ) ); - - memset( X->p, 0, X->n * ciL ); - memcpy( X->p, Y->p, i * ciL ); - -cleanup: - - return( ret ); -} - -/* - * Swap the contents of X and Y - */ -void mpi_swap( mpi *X, mpi *Y ) -{ - mpi T; - - memcpy( &T, X, sizeof( mpi ) ); - memcpy( X, Y, sizeof( mpi ) ); - memcpy( Y, &T, sizeof( mpi ) ); -} - -/* - * Set value from integer - */ -int mpi_lset( mpi *X, t_sint z ) -{ - int ret; - - MPI_CHK( mpi_grow( X, 1 ) ); - memset( X->p, 0, X->n * ciL ); - - X->p[0] = ( z < 0 ) ? -z : z; - X->s = ( z < 0 ) ? -1 : 1; - -cleanup: - - return( ret ); -} - -/* - * Get a specific bit - */ -int mpi_get_bit( mpi *X, size_t pos ) -{ - if( X->n * biL <= pos ) - return( 0 ); - - return ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01; -} - -/* - * Set a bit to a specific value of 0 or 1 - */ -int mpi_set_bit( mpi *X, size_t pos, unsigned char val ) -{ - int ret = 0; - size_t off = pos / biL; - size_t idx = pos % biL; - - if( val != 0 && val != 1 ) - return POLARSSL_ERR_MPI_BAD_INPUT_DATA; - - if( X->n * biL <= pos ) - { - if( val == 0 ) - return ( 0 ); - - MPI_CHK( mpi_grow( X, off + 1 ) ); - } - - X->p[off] = ( X->p[off] & ~( 0x01 << idx ) ) | ( val << idx ); - -cleanup: - - return( ret ); -} - -/* - * Return the number of least significant bits - */ -size_t mpi_lsb( const mpi *X ) -{ - size_t i, j, count = 0; - - for( i = 0; i < X->n; i++ ) - for( j = 0; j < biL; j++, count++ ) - if( ( ( X->p[i] >> j ) & 1 ) != 0 ) - return( count ); - - return( 0 ); -} - -/* - * Return the number of most significant bits - */ -size_t mpi_msb( const mpi *X ) -{ - size_t i, j; - - for( i = X->n - 1; i > 0; i-- ) - if( X->p[i] != 0 ) - break; - - for( j = biL; j > 0; j-- ) - if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 ) - break; - - return( ( i * biL ) + j ); -} - -/* - * Return the total size in bytes - */ -size_t mpi_size( const mpi *X ) -{ - return( ( mpi_msb( X ) + 7 ) >> 3 ); -} - -/* - * Convert an ASCII character to digit value - */ -static int mpi_get_digit( t_uint *d, int radix, char c ) -{ - *d = 255; - - if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30; - if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37; - if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57; - - if( *d >= (t_uint) radix ) - return( POLARSSL_ERR_MPI_INVALID_CHARACTER ); - - return( 0 ); -} - -/* - * Import from an ASCII string - */ -int mpi_read_string( mpi *X, int radix, const char *s ) -{ - int ret; - size_t i, j, slen, n; - t_uint d; - mpi T; - - if( radix < 2 || radix > 16 ) - return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); - - mpi_init( &T ); - - slen = strlen( s ); - - if( radix == 16 ) - { - n = BITS_TO_LIMBS( slen << 2 ); - - MPI_CHK( mpi_grow( X, n ) ); - MPI_CHK( mpi_lset( X, 0 ) ); - - for( i = slen, j = 0; i > 0; i--, j++ ) - { - if( i == 1 && s[i - 1] == '-' ) - { - X->s = -1; - break; - } - - MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) ); - X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 ); - } - } - else - { - MPI_CHK( mpi_lset( X, 0 ) ); - - for( i = 0; i < slen; i++ ) - { - if( i == 0 && s[i] == '-' ) - { - X->s = -1; - continue; - } - - MPI_CHK( mpi_get_digit( &d, radix, s[i] ) ); - MPI_CHK( mpi_mul_int( &T, X, radix ) ); - - if( X->s == 1 ) - { - MPI_CHK( mpi_add_int( X, &T, d ) ); - } - else - { - MPI_CHK( mpi_sub_int( X, &T, d ) ); - } - } - } - -cleanup: - - mpi_free( &T ); - - return( ret ); -} - -/* - * Helper to write the digits high-order first - */ -static int mpi_write_hlp( mpi *X, int radix, char **p ) -{ - int ret; - t_uint r; - - if( radix < 2 || radix > 16 ) - return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); - - MPI_CHK( mpi_mod_int( &r, X, radix ) ); - MPI_CHK( mpi_div_int( X, NULL, X, radix ) ); - - if( mpi_cmp_int( X, 0 ) != 0 ) - MPI_CHK( mpi_write_hlp( X, radix, p ) ); - - if( r < 10 ) - *(*p)++ = (char)( r + 0x30 ); - else - *(*p)++ = (char)( r + 0x37 ); - -cleanup: - - return( ret ); -} - -/* - * Export into an ASCII string - */ -int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen ) -{ - int ret = 0; - size_t n; - char *p; - mpi T; - - if( radix < 2 || radix > 16 ) - return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); - - n = mpi_msb( X ); - if( radix >= 4 ) n >>= 1; - if( radix >= 16 ) n >>= 1; - n += 3; - - if( *slen < n ) - { - *slen = n; - return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL ); - } - - p = s; - mpi_init( &T ); - - if( X->s == -1 ) - *p++ = '-'; - - if( radix == 16 ) - { - int c; - size_t i, j, k; - - for( i = X->n, k = 0; i > 0; i-- ) - { - for( j = ciL; j > 0; j-- ) - { - c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF; - - if( c == 0 && k == 0 && ( i + j + 3 ) != 0 ) - continue; - - p += sprintf( p, "%02X", c ); - k = 1; - } - } - } - else - { - MPI_CHK( mpi_copy( &T, X ) ); - - if( T.s == -1 ) - T.s = 1; - - MPI_CHK( mpi_write_hlp( &T, radix, &p ) ); - } - - *p++ = '\0'; - *slen = p - s; - -cleanup: - - mpi_free( &T ); - - return( ret ); -} - -#if defined(POLARSSL_FS_IO) -/* - * Read X from an opened file - */ -int mpi_read_file( mpi *X, int radix, FILE *fin ) -{ - t_uint d; - size_t slen; - char *p; - char s[1024]; - - memset( s, 0, sizeof( s ) ); - if( fgets( s, sizeof( s ) - 1, fin ) == NULL ) - return( POLARSSL_ERR_MPI_FILE_IO_ERROR ); - - slen = strlen( s ); - if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; } - if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; } - - p = s + slen; - while( --p >= s ) - if( mpi_get_digit( &d, radix, *p ) != 0 ) - break; - - return( mpi_read_string( X, radix, p + 1 ) ); -} - -/* - * Write X into an opened file (or stdout if fout == NULL) - */ -int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout ) -{ - int ret; - size_t n, slen, plen; - char s[2048]; - - n = sizeof( s ); - memset( s, 0, n ); - n -= 2; - - MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) ); - - if( p == NULL ) p = ""; - - plen = strlen( p ); - slen = strlen( s ); - s[slen++] = '\r'; - s[slen++] = '\n'; - - if( fout != NULL ) - { - if( fwrite( p, 1, plen, fout ) != plen || - fwrite( s, 1, slen, fout ) != slen ) - return( POLARSSL_ERR_MPI_FILE_IO_ERROR ); - } - else - printf( "%s%s", p, s ); - -cleanup: - - return( ret ); -} -#endif /* POLARSSL_FS_IO */ - -/* - * Import X from unsigned binary data, big endian - */ -int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen ) -{ - int ret; - size_t i, j, n; - - for( n = 0; n < buflen; n++ ) - if( buf[n] != 0 ) - break; - - MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) ); - MPI_CHK( mpi_lset( X, 0 ) ); - - for( i = buflen, j = 0; i > n; i--, j++ ) - X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3); - -cleanup: - - return( ret ); -} - -/* - * Export X into unsigned binary data, big endian - */ -int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen ) -{ - size_t i, j, n; - - n = mpi_size( X ); - - if( buflen < n ) - return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL ); - - memset( buf, 0, buflen ); - - for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- ) - buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) ); - - return( 0 ); -} - -/* - * Left-shift: X <<= count - */ -int mpi_shift_l( mpi *X, size_t count ) -{ - int ret; - size_t i, v0, t1; - t_uint r0 = 0, r1; - - v0 = count / (biL ); - t1 = count & (biL - 1); - - i = mpi_msb( X ) + count; - - if( X->n * biL < i ) - MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) ); - - ret = 0; - - /* - * shift by count / limb_size - */ - if( v0 > 0 ) - { - for( i = X->n; i > v0; i-- ) - X->p[i - 1] = X->p[i - v0 - 1]; - - for( ; i > 0; i-- ) - X->p[i - 1] = 0; - } - - /* - * shift by count % limb_size - */ - if( t1 > 0 ) - { - for( i = v0; i < X->n; i++ ) - { - r1 = X->p[i] >> (biL - t1); - X->p[i] <<= t1; - X->p[i] |= r0; - r0 = r1; - } - } - -cleanup: - - return( ret ); -} - -/* - * Right-shift: X >>= count - */ -int mpi_shift_r( mpi *X, size_t count ) -{ - size_t i, v0, v1; - t_uint r0 = 0, r1; - - v0 = count / biL; - v1 = count & (biL - 1); - - /* - * shift by count / limb_size - */ - if( v0 > 0 ) - { - for( i = 0; i < X->n - v0; i++ ) - X->p[i] = X->p[i + v0]; - - for( ; i < X->n; i++ ) - X->p[i] = 0; - } - - /* - * shift by count % limb_size - */ - if( v1 > 0 ) - { - for( i = X->n; i > 0; i-- ) - { - r1 = X->p[i - 1] << (biL - v1); - X->p[i - 1] >>= v1; - X->p[i - 1] |= r0; - r0 = r1; - } - } - - return( 0 ); -} - -/* - * Compare unsigned values - */ -int mpi_cmp_abs( const mpi *X, const mpi *Y ) -{ - size_t i, j; - - for( i = X->n; i > 0; i-- ) - if( X->p[i - 1] != 0 ) - break; - - for( j = Y->n; j > 0; j-- ) - if( Y->p[j - 1] != 0 ) - break; - - if( i == 0 && j == 0 ) - return( 0 ); - - if( i > j ) return( 1 ); - if( j > i ) return( -1 ); - - for( ; i > 0; i-- ) - { - if( X->p[i - 1] > Y->p[i - 1] ) return( 1 ); - if( X->p[i - 1] < Y->p[i - 1] ) return( -1 ); - } - - return( 0 ); -} - -/* - * Compare signed values - */ -int mpi_cmp_mpi( const mpi *X, const mpi *Y ) -{ - size_t i, j; - - for( i = X->n; i > 0; i-- ) - if( X->p[i - 1] != 0 ) - break; - - for( j = Y->n; j > 0; j-- ) - if( Y->p[j - 1] != 0 ) - break; - - if( i == 0 && j == 0 ) - return( 0 ); - - if( i > j ) return( X->s ); - if( j > i ) return( -X->s ); - - if( X->s > 0 && Y->s < 0 ) return( 1 ); - if( Y->s > 0 && X->s < 0 ) return( -1 ); - - for( ; i > 0; i-- ) - { - if( X->p[i - 1] > Y->p[i - 1] ) return( X->s ); - if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s ); - } - - return( 0 ); -} - -/* - * Compare signed values - */ -int mpi_cmp_int( const mpi *X, t_sint z ) -{ - mpi Y; - t_uint p[1]; - - *p = ( z < 0 ) ? -z : z; - Y.s = ( z < 0 ) ? -1 : 1; - Y.n = 1; - Y.p = p; - - return( mpi_cmp_mpi( X, &Y ) ); -} - -/* - * Unsigned addition: X = |A| + |B| (HAC 14.7) - */ -int mpi_add_abs( mpi *X, const mpi *A, const mpi *B ) -{ - int ret; - size_t i, j; - t_uint *o, *p, c; - - if( X == B ) - { - const mpi *T = A; A = X; B = T; - } - - if( X != A ) - MPI_CHK( mpi_copy( X, A ) ); - - /* - * X should always be positive as a result of unsigned additions. - */ - X->s = 1; - - for( j = B->n; j > 0; j-- ) - if( B->p[j - 1] != 0 ) - break; - - MPI_CHK( mpi_grow( X, j ) ); - - o = B->p; p = X->p; c = 0; - - for( i = 0; i < j; i++, o++, p++ ) - { - *p += c; c = ( *p < c ); - *p += *o; c += ( *p < *o ); - } - - while( c != 0 ) - { - if( i >= X->n ) - { - MPI_CHK( mpi_grow( X, i + 1 ) ); - p = X->p + i; - } - - *p += c; c = ( *p < c ); i++; - } - -cleanup: - - return( ret ); -} - -/* - * Helper for mpi substraction - */ -static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d ) -{ - size_t i; - t_uint c, z; - - for( i = c = 0; i < n; i++, s++, d++ ) - { - z = ( *d < c ); *d -= c; - c = ( *d < *s ) + z; *d -= *s; - } - - while( c != 0 ) - { - z = ( *d < c ); *d -= c; - c = z; i++; d++; - } -} - -/* - * Unsigned substraction: X = |A| - |B| (HAC 14.9) - */ -int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B ) -{ - mpi TB; - int ret; - size_t n; - - if( mpi_cmp_abs( A, B ) < 0 ) - return( POLARSSL_ERR_MPI_NEGATIVE_VALUE ); - - mpi_init( &TB ); - - if( X == B ) - { - MPI_CHK( mpi_copy( &TB, B ) ); - B = &TB; - } - - if( X != A ) - MPI_CHK( mpi_copy( X, A ) ); - - /* - * X should always be positive as a result of unsigned substractions. - */ - X->s = 1; - - ret = 0; - - for( n = B->n; n > 0; n-- ) - if( B->p[n - 1] != 0 ) - break; - - mpi_sub_hlp( n, B->p, X->p ); - -cleanup: - - mpi_free( &TB ); - - return( ret ); -} - -/* - * Signed addition: X = A + B - */ -int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B ) -{ - int ret, s = A->s; - - if( A->s * B->s < 0 ) - { - if( mpi_cmp_abs( A, B ) >= 0 ) - { - MPI_CHK( mpi_sub_abs( X, A, B ) ); - X->s = s; - } - else - { - MPI_CHK( mpi_sub_abs( X, B, A ) ); - X->s = -s; - } - } - else - { - MPI_CHK( mpi_add_abs( X, A, B ) ); - X->s = s; - } - -cleanup: - - return( ret ); -} - -/* - * Signed substraction: X = A - B - */ -int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B ) -{ - int ret, s = A->s; - - if( A->s * B->s > 0 ) - { - if( mpi_cmp_abs( A, B ) >= 0 ) - { - MPI_CHK( mpi_sub_abs( X, A, B ) ); - X->s = s; - } - else - { - MPI_CHK( mpi_sub_abs( X, B, A ) ); - X->s = -s; - } - } - else - { - MPI_CHK( mpi_add_abs( X, A, B ) ); - X->s = s; - } - -cleanup: - - return( ret ); -} - -/* - * Signed addition: X = A + b - */ -int mpi_add_int( mpi *X, const mpi *A, t_sint b ) -{ - mpi _B; - t_uint p[1]; - - p[0] = ( b < 0 ) ? -b : b; - _B.s = ( b < 0 ) ? -1 : 1; - _B.n = 1; - _B.p = p; - - return( mpi_add_mpi( X, A, &_B ) ); -} - -/* - * Signed substraction: X = A - b - */ -int mpi_sub_int( mpi *X, const mpi *A, t_sint b ) -{ - mpi _B; - t_uint p[1]; - - p[0] = ( b < 0 ) ? -b : b; - _B.s = ( b < 0 ) ? -1 : 1; - _B.n = 1; - _B.p = p; - - return( mpi_sub_mpi( X, A, &_B ) ); -} - -/* - * Helper for mpi multiplication - */ -static void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b ) -{ - t_uint c = 0, t = 0; - -#if defined(MULADDC_HUIT) - for( ; i >= 8; i -= 8 ) - { - MULADDC_INIT - MULADDC_HUIT - MULADDC_STOP - } - - for( ; i > 0; i-- ) - { - MULADDC_INIT - MULADDC_CORE - MULADDC_STOP - } -#else - for( ; i >= 16; i -= 16 ) - { - MULADDC_INIT - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_STOP - } - - for( ; i >= 8; i -= 8 ) - { - MULADDC_INIT - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - - MULADDC_CORE MULADDC_CORE - MULADDC_CORE MULADDC_CORE - MULADDC_STOP - } - - for( ; i > 0; i-- ) - { - MULADDC_INIT - MULADDC_CORE - MULADDC_STOP - } -#endif - - t++; - - do { - *d += c; c = ( *d < c ); d++; - } - while( c != 0 ); -} - -/* - * Baseline multiplication: X = A * B (HAC 14.12) - */ -int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B ) -{ - int ret; - size_t i, j; - mpi TA, TB; - - mpi_init( &TA ); mpi_init( &TB ); - - if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; } - if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; } - - for( i = A->n; i > 0; i-- ) - if( A->p[i - 1] != 0 ) - break; - - for( j = B->n; j > 0; j-- ) - if( B->p[j - 1] != 0 ) - break; - - MPI_CHK( mpi_grow( X, i + j ) ); - MPI_CHK( mpi_lset( X, 0 ) ); - - for( i++; j > 0; j-- ) - mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] ); - - X->s = A->s * B->s; - -cleanup: - - mpi_free( &TB ); mpi_free( &TA ); - - return( ret ); -} - -/* - * Baseline multiplication: X = A * b - */ -int mpi_mul_int( mpi *X, const mpi *A, t_sint b ) -{ - mpi _B; - t_uint p[1]; - - _B.s = 1; - _B.n = 1; - _B.p = p; - p[0] = b; - - return( mpi_mul_mpi( X, A, &_B ) ); -} - -/* - * Division by mpi: A = Q * B + R (HAC 14.20) - */ -int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ) -{ - int ret; - size_t i, n, t, k; - mpi X, Y, Z, T1, T2; - - if( mpi_cmp_int( B, 0 ) == 0 ) - return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO ); - - mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z ); - mpi_init( &T1 ); mpi_init( &T2 ); - - if( mpi_cmp_abs( A, B ) < 0 ) - { - if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) ); - if( R != NULL ) MPI_CHK( mpi_copy( R, A ) ); - return( 0 ); - } - - MPI_CHK( mpi_copy( &X, A ) ); - MPI_CHK( mpi_copy( &Y, B ) ); - X.s = Y.s = 1; - - MPI_CHK( mpi_grow( &Z, A->n + 2 ) ); - MPI_CHK( mpi_lset( &Z, 0 ) ); - MPI_CHK( mpi_grow( &T1, 2 ) ); - MPI_CHK( mpi_grow( &T2, 3 ) ); - - k = mpi_msb( &Y ) % biL; - if( k < biL - 1 ) - { - k = biL - 1 - k; - MPI_CHK( mpi_shift_l( &X, k ) ); - MPI_CHK( mpi_shift_l( &Y, k ) ); - } - else k = 0; - - n = X.n - 1; - t = Y.n - 1; - mpi_shift_l( &Y, biL * (n - t) ); - - while( mpi_cmp_mpi( &X, &Y ) >= 0 ) - { - Z.p[n - t]++; - mpi_sub_mpi( &X, &X, &Y ); - } - mpi_shift_r( &Y, biL * (n - t) ); - - for( i = n; i > t ; i-- ) - { - if( X.p[i] >= Y.p[t] ) - Z.p[i - t - 1] = ~0; - else - { -#if defined(POLARSSL_HAVE_LONGLONG) - t_dbl r; - - r = (t_dbl) X.p[i] << biL; - r |= (t_dbl) X.p[i - 1]; - r /= Y.p[t]; - if( r > ((t_dbl) 1 << biL) - 1) - r = ((t_dbl) 1 << biL) - 1; - - Z.p[i - t - 1] = (t_uint) r; -#else - /* - * __udiv_qrnnd_c, from gmp/longlong.h - */ - t_uint q0, q1, r0, r1; - t_uint d0, d1, d, m; - - d = Y.p[t]; - d0 = ( d << biH ) >> biH; - d1 = ( d >> biH ); - - q1 = X.p[i] / d1; - r1 = X.p[i] - d1 * q1; - r1 <<= biH; - r1 |= ( X.p[i - 1] >> biH ); - - m = q1 * d0; - if( r1 < m ) - { - q1--, r1 += d; - while( r1 >= d && r1 < m ) - q1--, r1 += d; - } - r1 -= m; - - q0 = r1 / d1; - r0 = r1 - d1 * q0; - r0 <<= biH; - r0 |= ( X.p[i - 1] << biH ) >> biH; - - m = q0 * d0; - if( r0 < m ) - { - q0--, r0 += d; - while( r0 >= d && r0 < m ) - q0--, r0 += d; - } - r0 -= m; - - Z.p[i - t - 1] = ( q1 << biH ) | q0; -#endif - } - - Z.p[i - t - 1]++; - do - { - Z.p[i - t - 1]--; - - MPI_CHK( mpi_lset( &T1, 0 ) ); - T1.p[0] = (t < 1) ? 0 : Y.p[t - 1]; - T1.p[1] = Y.p[t]; - MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) ); - - MPI_CHK( mpi_lset( &T2, 0 ) ); - T2.p[0] = (i < 2) ? 0 : X.p[i - 2]; - T2.p[1] = (i < 1) ? 0 : X.p[i - 1]; - T2.p[2] = X.p[i]; - } - while( mpi_cmp_mpi( &T1, &T2 ) > 0 ); - - MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) ); - MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) ); - MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) ); - - if( mpi_cmp_int( &X, 0 ) < 0 ) - { - MPI_CHK( mpi_copy( &T1, &Y ) ); - MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) ); - MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) ); - Z.p[i - t - 1]--; - } - } - - if( Q != NULL ) - { - mpi_copy( Q, &Z ); - Q->s = A->s * B->s; - } - - if( R != NULL ) - { - mpi_shift_r( &X, k ); - mpi_copy( R, &X ); - - R->s = A->s; - if( mpi_cmp_int( R, 0 ) == 0 ) - R->s = 1; - } - -cleanup: - - mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z ); - mpi_free( &T1 ); mpi_free( &T2 ); - - return( ret ); -} - -/* - * Division by int: A = Q * b + R - * - * Returns 0 if successful - * 1 if memory allocation failed - * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0 - */ -int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b ) -{ - mpi _B; - t_uint p[1]; - - p[0] = ( b < 0 ) ? -b : b; - _B.s = ( b < 0 ) ? -1 : 1; - _B.n = 1; - _B.p = p; - - return( mpi_div_mpi( Q, R, A, &_B ) ); -} - -/* - * Modulo: R = A mod B - */ -int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B ) -{ - int ret; - - if( mpi_cmp_int( B, 0 ) < 0 ) - return POLARSSL_ERR_MPI_NEGATIVE_VALUE; - - MPI_CHK( mpi_div_mpi( NULL, R, A, B ) ); - - while( mpi_cmp_int( R, 0 ) < 0 ) - MPI_CHK( mpi_add_mpi( R, R, B ) ); - - while( mpi_cmp_mpi( R, B ) >= 0 ) - MPI_CHK( mpi_sub_mpi( R, R, B ) ); - -cleanup: - - return( ret ); -} - -/* - * Modulo: r = A mod b - */ -int mpi_mod_int( t_uint *r, const mpi *A, t_sint b ) -{ - size_t i; - t_uint x, y, z; - - if( b == 0 ) - return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO ); - - if( b < 0 ) - return POLARSSL_ERR_MPI_NEGATIVE_VALUE; - - /* - * handle trivial cases - */ - if( b == 1 ) - { - *r = 0; - return( 0 ); - } - - if( b == 2 ) - { - *r = A->p[0] & 1; - return( 0 ); - } - - /* - * general case - */ - for( i = A->n, y = 0; i > 0; i-- ) - { - x = A->p[i - 1]; - y = ( y << biH ) | ( x >> biH ); - z = y / b; - y -= z * b; - - x <<= biH; - y = ( y << biH ) | ( x >> biH ); - z = y / b; - y -= z * b; - } - - /* - * If A is negative, then the current y represents a negative value. - * Flipping it to the positive side. - */ - if( A->s < 0 && y != 0 ) - y = b - y; - - *r = y; - - return( 0 ); -} - -/* - * Fast Montgomery initialization (thanks to Tom St Denis) - */ -static void mpi_montg_init( t_uint *mm, const mpi *N ) -{ - t_uint x, m0 = N->p[0]; - - x = m0; - x += ( ( m0 + 2 ) & 4 ) << 1; - x *= ( 2 - ( m0 * x ) ); - - if( biL >= 16 ) x *= ( 2 - ( m0 * x ) ); - if( biL >= 32 ) x *= ( 2 - ( m0 * x ) ); - if( biL >= 64 ) x *= ( 2 - ( m0 * x ) ); - - *mm = ~x + 1; -} - -/* - * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) - */ -static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, const mpi *T ) -{ - size_t i, n, m; - t_uint u0, u1, *d; - - memset( T->p, 0, T->n * ciL ); - - d = T->p; - n = N->n; - m = ( B->n < n ) ? B->n : n; - - for( i = 0; i < n; i++ ) - { - /* - * T = (T + u0*B + u1*N) / 2^biL - */ - u0 = A->p[i]; - u1 = ( d[0] + u0 * B->p[0] ) * mm; - - mpi_mul_hlp( m, B->p, d, u0 ); - mpi_mul_hlp( n, N->p, d, u1 ); - - *d++ = u0; d[n + 1] = 0; - } - - memcpy( A->p, d, (n + 1) * ciL ); - - if( mpi_cmp_abs( A, N ) >= 0 ) - mpi_sub_hlp( n, N->p, A->p ); - else - /* prevent timing attacks */ - mpi_sub_hlp( n, A->p, T->p ); -} - -/* - * Montgomery reduction: A = A * R^-1 mod N - */ -static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T ) -{ - t_uint z = 1; - mpi U; - - U.n = U.s = z; - U.p = &z; - - mpi_montmul( A, &U, N, mm, T ); -} - -/* - * Sliding-window exponentiation: X = A^E mod N (HAC 14.85) - */ -int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ) -{ - int ret; - size_t wbits, wsize, one = 1; - size_t i, j, nblimbs; - size_t bufsize, nbits; - t_uint ei, mm, state; - mpi RR, T, W[64]; - - if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 ) - return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); - - /* - * Init temps and window size - */ - mpi_montg_init( &mm, N ); - mpi_init( &RR ); mpi_init( &T ); - memset( W, 0, sizeof( W ) ); - - i = mpi_msb( E ); - - wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 : - ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1; - - j = N->n + 1; - MPI_CHK( mpi_grow( X, j ) ); - MPI_CHK( mpi_grow( &W[1], j ) ); - MPI_CHK( mpi_grow( &T, j * 2 ) ); - - /* - * If 1st call, pre-compute R^2 mod N - */ - if( _RR == NULL || _RR->p == NULL ) - { - MPI_CHK( mpi_lset( &RR, 1 ) ); - MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) ); - MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) ); - - if( _RR != NULL ) - memcpy( _RR, &RR, sizeof( mpi ) ); - } - else - memcpy( &RR, _RR, sizeof( mpi ) ); - - /* - * W[1] = A * R^2 * R^-1 mod N = A * R mod N - */ - if( mpi_cmp_mpi( A, N ) >= 0 ) - mpi_mod_mpi( &W[1], A, N ); - else mpi_copy( &W[1], A ); - - mpi_montmul( &W[1], &RR, N, mm, &T ); - - /* - * X = R^2 * R^-1 mod N = R mod N - */ - MPI_CHK( mpi_copy( X, &RR ) ); - mpi_montred( X, N, mm, &T ); - - if( wsize > 1 ) - { - /* - * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1) - */ - j = one << (wsize - 1); - - MPI_CHK( mpi_grow( &W[j], N->n + 1 ) ); - MPI_CHK( mpi_copy( &W[j], &W[1] ) ); - - for( i = 0; i < wsize - 1; i++ ) - mpi_montmul( &W[j], &W[j], N, mm, &T ); - - /* - * W[i] = W[i - 1] * W[1] - */ - for( i = j + 1; i < (one << wsize); i++ ) - { - MPI_CHK( mpi_grow( &W[i], N->n + 1 ) ); - MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) ); - - mpi_montmul( &W[i], &W[1], N, mm, &T ); - } - } - - nblimbs = E->n; - bufsize = 0; - nbits = 0; - wbits = 0; - state = 0; - - while( 1 ) - { - if( bufsize == 0 ) - { - if( nblimbs-- == 0 ) - break; - - bufsize = sizeof( t_uint ) << 3; - } - - bufsize--; - - ei = (E->p[nblimbs] >> bufsize) & 1; - - /* - * skip leading 0s - */ - if( ei == 0 && state == 0 ) - continue; - - if( ei == 0 && state == 1 ) - { - /* - * out of window, square X - */ - mpi_montmul( X, X, N, mm, &T ); - continue; - } - - /* - * add ei to current window - */ - state = 2; - - nbits++; - wbits |= (ei << (wsize - nbits)); - - if( nbits == wsize ) - { - /* - * X = X^wsize R^-1 mod N - */ - for( i = 0; i < wsize; i++ ) - mpi_montmul( X, X, N, mm, &T ); - - /* - * X = X * W[wbits] R^-1 mod N - */ - mpi_montmul( X, &W[wbits], N, mm, &T ); - - state--; - nbits = 0; - wbits = 0; - } - } - - /* - * process the remaining bits - */ - for( i = 0; i < nbits; i++ ) - { - mpi_montmul( X, X, N, mm, &T ); - - wbits <<= 1; - - if( (wbits & (one << wsize)) != 0 ) - mpi_montmul( X, &W[1], N, mm, &T ); - } - - /* - * X = A^E * R * R^-1 mod N = A^E mod N - */ - mpi_montred( X, N, mm, &T ); - -cleanup: - - for( i = (one << (wsize - 1)); i < (one << wsize); i++ ) - mpi_free( &W[i] ); - - mpi_free( &W[1] ); mpi_free( &T ); - - if( _RR == NULL ) - mpi_free( &RR ); - - return( ret ); -} - -/* - * Greatest common divisor: G = gcd(A, B) (HAC 14.54) - */ -int mpi_gcd( mpi *G, const mpi *A, const mpi *B ) -{ - int ret; - size_t lz, lzt; - mpi TG, TA, TB; - - mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB ); - - MPI_CHK( mpi_copy( &TA, A ) ); - MPI_CHK( mpi_copy( &TB, B ) ); - - lz = mpi_lsb( &TA ); - lzt = mpi_lsb( &TB ); - - if ( lzt < lz ) - lz = lzt; - - MPI_CHK( mpi_shift_r( &TA, lz ) ); - MPI_CHK( mpi_shift_r( &TB, lz ) ); - - TA.s = TB.s = 1; - - while( mpi_cmp_int( &TA, 0 ) != 0 ) - { - MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) ); - MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) ); - - if( mpi_cmp_mpi( &TA, &TB ) >= 0 ) - { - MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) ); - MPI_CHK( mpi_shift_r( &TA, 1 ) ); - } - else - { - MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) ); - MPI_CHK( mpi_shift_r( &TB, 1 ) ); - } - } - - MPI_CHK( mpi_shift_l( &TB, lz ) ); - MPI_CHK( mpi_copy( G, &TB ) ); - -cleanup: - - mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB ); - - return( ret ); -} - -int mpi_fill_random( mpi *X, size_t size, int (*f_rng)(void *), void *p_rng ) -{ - int ret; - size_t k; - unsigned char *p; - - MPI_CHK( mpi_grow( X, size ) ); - MPI_CHK( mpi_lset( X, 0 ) ); - - p = (unsigned char *) X->p; - for( k = 0; k < X->n * ciL; k++ ) - *p++ = (unsigned char) f_rng( p_rng ); - -cleanup: - return( ret ); -} - -#if defined(POLARSSL_GENPRIME) - -/* - * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64) - */ -int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N ) -{ - int ret; - mpi G, TA, TU, U1, U2, TB, TV, V1, V2; - - if( mpi_cmp_int( N, 0 ) <= 0 ) - return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); - - mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 ); - mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV ); - mpi_init( &V1 ); mpi_init( &V2 ); - - MPI_CHK( mpi_gcd( &G, A, N ) ); - - if( mpi_cmp_int( &G, 1 ) != 0 ) - { - ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE; - goto cleanup; - } - - MPI_CHK( mpi_mod_mpi( &TA, A, N ) ); - MPI_CHK( mpi_copy( &TU, &TA ) ); - MPI_CHK( mpi_copy( &TB, N ) ); - MPI_CHK( mpi_copy( &TV, N ) ); - - MPI_CHK( mpi_lset( &U1, 1 ) ); - MPI_CHK( mpi_lset( &U2, 0 ) ); - MPI_CHK( mpi_lset( &V1, 0 ) ); - MPI_CHK( mpi_lset( &V2, 1 ) ); - - do - { - while( ( TU.p[0] & 1 ) == 0 ) - { - MPI_CHK( mpi_shift_r( &TU, 1 ) ); - - if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 ) - { - MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) ); - MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) ); - } - - MPI_CHK( mpi_shift_r( &U1, 1 ) ); - MPI_CHK( mpi_shift_r( &U2, 1 ) ); - } - - while( ( TV.p[0] & 1 ) == 0 ) - { - MPI_CHK( mpi_shift_r( &TV, 1 ) ); - - if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 ) - { - MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) ); - MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) ); - } - - MPI_CHK( mpi_shift_r( &V1, 1 ) ); - MPI_CHK( mpi_shift_r( &V2, 1 ) ); - } - - if( mpi_cmp_mpi( &TU, &TV ) >= 0 ) - { - MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) ); - MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) ); - MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) ); - } - else - { - MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) ); - MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) ); - MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) ); - } - } - while( mpi_cmp_int( &TU, 0 ) != 0 ); - - while( mpi_cmp_int( &V1, 0 ) < 0 ) - MPI_CHK( mpi_add_mpi( &V1, &V1, N ) ); - - while( mpi_cmp_mpi( &V1, N ) >= 0 ) - MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) ); - - MPI_CHK( mpi_copy( X, &V1 ) ); - -cleanup: - - mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 ); - mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV ); - mpi_free( &V1 ); mpi_free( &V2 ); - - return( ret ); -} - -static const int small_prime[] = -{ - 3, 5, 7, 11, 13, 17, 19, 23, - 29, 31, 37, 41, 43, 47, 53, 59, - 61, 67, 71, 73, 79, 83, 89, 97, - 101, 103, 107, 109, 113, 127, 131, 137, - 139, 149, 151, 157, 163, 167, 173, 179, - 181, 191, 193, 197, 199, 211, 223, 227, - 229, 233, 239, 241, 251, 257, 263, 269, - 271, 277, 281, 283, 293, 307, 311, 313, - 317, 331, 337, 347, 349, 353, 359, 367, - 373, 379, 383, 389, 397, 401, 409, 419, - 421, 431, 433, 439, 443, 449, 457, 461, - 463, 467, 479, 487, 491, 499, 503, 509, - 521, 523, 541, 547, 557, 563, 569, 571, - 577, 587, 593, 599, 601, 607, 613, 617, - 619, 631, 641, 643, 647, 653, 659, 661, - 673, 677, 683, 691, 701, 709, 719, 727, - 733, 739, 743, 751, 757, 761, 769, 773, - 787, 797, 809, 811, 821, 823, 827, 829, - 839, 853, 857, 859, 863, 877, 881, 883, - 887, 907, 911, 919, 929, 937, 941, 947, - 953, 967, 971, 977, 983, 991, 997, -103 -}; - -/* - * Miller-Rabin primality test (HAC 4.24) - */ -int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng ) -{ - int ret, xs; - size_t i, j, n, s; - mpi W, R, T, A, RR; - - if( mpi_cmp_int( X, 0 ) == 0 || - mpi_cmp_int( X, 1 ) == 0 ) - return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); - - if( mpi_cmp_int( X, 2 ) == 0 ) - return( 0 ); - - mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A ); - mpi_init( &RR ); - - xs = X->s; X->s = 1; - - /* - * test trivial factors first - */ - if( ( X->p[0] & 1 ) == 0 ) - return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); - - for( i = 0; small_prime[i] > 0; i++ ) - { - t_uint r; - - if( mpi_cmp_int( X, small_prime[i] ) <= 0 ) - return( 0 ); - - MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) ); - - if( r == 0 ) - return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); - } - - /* - * W = |X| - 1 - * R = W >> lsb( W ) - */ - MPI_CHK( mpi_sub_int( &W, X, 1 ) ); - s = mpi_lsb( &W ); - MPI_CHK( mpi_copy( &R, &W ) ); - MPI_CHK( mpi_shift_r( &R, s ) ); - - i = mpi_msb( X ); - /* - * HAC, table 4.4 - */ - n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 : - ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 : - ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 ); - - for( i = 0; i < n; i++ ) - { - /* - * pick a random A, 1 < A < |X| - 1 - */ - mpi_fill_random( &A, X->n, f_rng, p_rng ); - - if( mpi_cmp_mpi( &A, &W ) >= 0 ) - { - j = mpi_msb( &A ) - mpi_msb( &W ); - MPI_CHK( mpi_shift_r( &A, j + 1 ) ); - } - A.p[0] |= 3; - - /* - * A = A^R mod |X| - */ - MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) ); - - if( mpi_cmp_mpi( &A, &W ) == 0 || - mpi_cmp_int( &A, 1 ) == 0 ) - continue; - - j = 1; - while( j < s && mpi_cmp_mpi( &A, &W ) != 0 ) - { - /* - * A = A * A mod |X| - */ - MPI_CHK( mpi_mul_mpi( &T, &A, &A ) ); - MPI_CHK( mpi_mod_mpi( &A, &T, X ) ); - - if( mpi_cmp_int( &A, 1 ) == 0 ) - break; - - j++; - } - - /* - * not prime if A != |X| - 1 or A == 1 - */ - if( mpi_cmp_mpi( &A, &W ) != 0 || - mpi_cmp_int( &A, 1 ) == 0 ) - { - ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE; - break; - } - } - -cleanup: - - X->s = xs; - - mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A ); - mpi_free( &RR ); - - return( ret ); -} - -/* - * Prime number generation - */ -int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag, - int (*f_rng)(void *), void *p_rng ) -{ - int ret; - size_t k, n; - mpi Y; - - if( nbits < 3 || nbits > 4096 ) - return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); - - mpi_init( &Y ); - - n = BITS_TO_LIMBS( nbits ); - - mpi_fill_random( X, n, f_rng, p_rng ); - - k = mpi_msb( X ); - if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) ); - if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) ); - - X->p[0] |= 3; - - if( dh_flag == 0 ) - { - while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 ) - { - if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) - goto cleanup; - - MPI_CHK( mpi_add_int( X, X, 2 ) ); - } - } - else - { - MPI_CHK( mpi_sub_int( &Y, X, 1 ) ); - MPI_CHK( mpi_shift_r( &Y, 1 ) ); - - while( 1 ) - { - if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 ) - { - if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 ) - break; - - if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) - goto cleanup; - } - - if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) - goto cleanup; - - MPI_CHK( mpi_add_int( &Y, X, 1 ) ); - MPI_CHK( mpi_add_int( X, X, 2 ) ); - MPI_CHK( mpi_shift_r( &Y, 1 ) ); - } - } - -cleanup: - - mpi_free( &Y ); - - return( ret ); -} - -#endif - -#if defined(POLARSSL_SELF_TEST) - -#define GCD_PAIR_COUNT 3 - -static const int gcd_pairs[GCD_PAIR_COUNT][3] = -{ - { 693, 609, 21 }, - { 1764, 868, 28 }, - { 768454923, 542167814, 1 } -}; - -/* - * Checkup routine - */ -int mpi_self_test( int verbose ) -{ - int ret, i; - mpi A, E, N, X, Y, U, V; - - mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X ); - mpi_init( &Y ); mpi_init( &U ); mpi_init( &V ); - - MPI_CHK( mpi_read_string( &A, 16, - "EFE021C2645FD1DC586E69184AF4A31E" \ - "D5F53E93B5F123FA41680867BA110131" \ - "944FE7952E2517337780CB0DB80E61AA" \ - "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) ); - - MPI_CHK( mpi_read_string( &E, 16, - "B2E7EFD37075B9F03FF989C7C5051C20" \ - "34D2A323810251127E7BF8625A4F49A5" \ - "F3E27F4DA8BD59C47D6DAABA4C8127BD" \ - "5B5C25763222FEFCCFC38B832366C29E" ) ); - - MPI_CHK( mpi_read_string( &N, 16, - "0066A198186C18C10B2F5ED9B522752A" \ - "9830B69916E535C8F047518A889A43A5" \ - "94B6BED27A168D31D4A52F88925AA8F5" ) ); - - MPI_CHK( mpi_mul_mpi( &X, &A, &N ) ); - - MPI_CHK( mpi_read_string( &U, 16, - "602AB7ECA597A3D6B56FF9829A5E8B85" \ - "9E857EA95A03512E2BAE7391688D264A" \ - "A5663B0341DB9CCFD2C4C5F421FEC814" \ - "8001B72E848A38CAE1C65F78E56ABDEF" \ - "E12D3C039B8A02D6BE593F0BBBDA56F1" \ - "ECF677152EF804370C1A305CAF3B5BF1" \ - "30879B56C61DE584A0F53A2447A51E" ) ); - - if( verbose != 0 ) - printf( " MPI test #1 (mul_mpi): " ); - - if( mpi_cmp_mpi( &X, &U ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - - MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) ); - - MPI_CHK( mpi_read_string( &U, 16, - "256567336059E52CAE22925474705F39A94" ) ); - - MPI_CHK( mpi_read_string( &V, 16, - "6613F26162223DF488E9CD48CC132C7A" \ - "0AC93C701B001B092E4E5B9F73BCD27B" \ - "9EE50D0657C77F374E903CDFA4C642" ) ); - - if( verbose != 0 ) - printf( " MPI test #2 (div_mpi): " ); - - if( mpi_cmp_mpi( &X, &U ) != 0 || - mpi_cmp_mpi( &Y, &V ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - - MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) ); - - MPI_CHK( mpi_read_string( &U, 16, - "36E139AEA55215609D2816998ED020BB" \ - "BD96C37890F65171D948E9BC7CBAA4D9" \ - "325D24D6A3C12710F10A09FA08AB87" ) ); - - if( verbose != 0 ) - printf( " MPI test #3 (exp_mod): " ); - - if( mpi_cmp_mpi( &X, &U ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - -#if defined(POLARSSL_GENPRIME) - MPI_CHK( mpi_inv_mod( &X, &A, &N ) ); - - MPI_CHK( mpi_read_string( &U, 16, - "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \ - "C3DBA76456363A10869622EAC2DD84EC" \ - "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) ); - - if( verbose != 0 ) - printf( " MPI test #4 (inv_mod): " ); - - if( mpi_cmp_mpi( &X, &U ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); -#endif - - if( verbose != 0 ) - printf( " MPI test #5 (simple gcd): " ); - - for ( i = 0; i < GCD_PAIR_COUNT; i++) - { - MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) ); - MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) ); - - MPI_CHK( mpi_gcd( &A, &X, &Y ) ); - - if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 ) - { - if( verbose != 0 ) - printf( "failed at %d\n", i ); - - return( 1 ); - } - } - - if( verbose != 0 ) - printf( "passed\n" ); - -cleanup: - - if( ret != 0 && verbose != 0 ) - printf( "Unexpected error, return code = %08X\n", ret ); - - mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X ); - mpi_free( &Y ); mpi_free( &U ); mpi_free( &V ); - - if( verbose != 0 ) - printf( "\n" ); - - return( ret ); -} - -#endif - -#endif diff --git a/!NotAdopted/Tlen/crypto/padlock.c b/!NotAdopted/Tlen/crypto/padlock.c deleted file mode 100644 index 2e2e4775ff..0000000000 --- a/!NotAdopted/Tlen/crypto/padlock.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * VIA PadLock support functions - * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* - * This implementation is based on the VIA PadLock Programming Guide: - * - * http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/ - * programming_guide.pdf - */ - -#include "polarssl/config.h" - -#if defined(POLARSSL_PADLOCK_C) - -#include "polarssl/padlock.h" - -#if defined(POLARSSL_HAVE_X86) - -/* - * PadLock detection routine - */ -int padlock_supports( int feature ) -{ - static int flags = -1; - int ebx, edx; - - if( flags == -1 ) - { - asm( "movl %%ebx, %0 \n" \ - "movl $0xC0000000, %%eax \n" \ - "cpuid \n" \ - "cmpl $0xC0000001, %%eax \n" \ - "movl $0, %%edx \n" \ - "jb unsupported \n" \ - "movl $0xC0000001, %%eax \n" \ - "cpuid \n" \ - "unsupported: \n" \ - "movl %%edx, %1 \n" \ - "movl %2, %%ebx \n" - : "=m" (ebx), "=m" (edx) - : "m" (ebx) - : "eax", "ecx", "edx" ); - - flags = edx; - } - - return( flags & feature ); -} - -/* - * PadLock AES-ECB block en(de)cryption - */ -int padlock_xcryptecb( aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ) -{ - int ebx; - unsigned long *rk; - unsigned long *blk; - unsigned long *ctrl; - unsigned char buf[256]; - - rk = ctx->rk; - blk = PADLOCK_ALIGN16( buf ); - memcpy( blk, input, 16 ); - - ctrl = blk + 4; - *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 ); - - asm( "pushfl; popfl \n" \ - "movl %%ebx, %0 \n" \ - "movl $1, %%ecx \n" \ - "movl %2, %%edx \n" \ - "movl %3, %%ebx \n" \ - "movl %4, %%esi \n" \ - "movl %4, %%edi \n" \ - ".byte 0xf3,0x0f,0xa7,0xc8\n" \ - "movl %1, %%ebx \n" - : "=m" (ebx) - : "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk) - : "ecx", "edx", "esi", "edi" ); - - memcpy( output, blk, 16 ); - - return( 0 ); -} - -/* - * PadLock AES-CBC buffer en(de)cryption - */ -int padlock_xcryptcbc( aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int ebx; - size_t count; - unsigned long *rk; - unsigned long *iw; - unsigned long *ctrl; - unsigned char buf[256]; - - if( ( (long) input & 15 ) != 0 || - ( (long) output & 15 ) != 0 ) - return( POLARSSL_ERR_PADLOCK_DATA_MISALIGNED ); - - rk = ctx->rk; - iw = PADLOCK_ALIGN16( buf ); - memcpy( iw, iv, 16 ); - - ctrl = iw + 4; - *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + (mode^1) - 10 ) << 9 ); - - count = (length + 15) >> 4; - - asm( "pushfl; popfl \n" \ - "movl %%ebx, %0 \n" \ - "movl %2, %%ecx \n" \ - "movl %3, %%edx \n" \ - "movl %4, %%ebx \n" \ - "movl %5, %%esi \n" \ - "movl %6, %%edi \n" \ - "movl %7, %%eax \n" \ - ".byte 0xf3,0x0f,0xa7,0xd0\n" \ - "movl %1, %%ebx \n" - : "=m" (ebx) - : "m" (ebx), "m" (count), "m" (ctrl), - "m" (rk), "m" (input), "m" (output), "m" (iw) - : "eax", "ecx", "edx", "esi", "edi" ); - - memcpy( iv, iw, 16 ); - - return( 0 ); -} - -#endif - -#endif diff --git a/!NotAdopted/Tlen/crypto/polarssl/aes.h b/!NotAdopted/Tlen/crypto/polarssl/aes.h deleted file mode 100644 index efc13daf5b..0000000000 --- a/!NotAdopted/Tlen/crypto/polarssl/aes.h +++ /dev/null @@ -1,167 +0,0 @@ -/** - * \file aes.h - * - * \brief AES block cipher - * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef POLARSSL_AES_H -#define POLARSSL_AES_H - -#include - -#define AES_ENCRYPT 1 -#define AES_DECRYPT 0 - -#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */ -#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */ - -/** - * \brief AES context structure - */ -typedef struct -{ - int nr; /*!< number of rounds */ - unsigned long *rk; /*!< AES round keys */ - unsigned long buf[68]; /*!< unaligned data */ -} -aes_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief AES key schedule (encryption) - * - * \param ctx AES context to be initialized - * \param key encryption key - * \param keysize must be 128, 192 or 256 - * - * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH - */ -int aes_setkey_enc( aes_context *ctx, const unsigned char *key, unsigned int keysize ); - -/** - * \brief AES key schedule (decryption) - * - * \param ctx AES context to be initialized - * \param key decryption key - * \param keysize must be 128, 192 or 256 - * - * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH - */ -int aes_setkey_dec( aes_context *ctx, const unsigned char *key, unsigned int keysize ); - -/** - * \brief AES-ECB block encryption/decryption - * - * \param ctx AES context - * \param mode AES_ENCRYPT or AES_DECRYPT - * \param input 16-byte input block - * \param output 16-byte output block - * - * \return 0 if successful - */ -int aes_crypt_ecb( aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ); - -/** - * \brief AES-CBC buffer encryption/decryption - * Length should be a multiple of the block - * size (16 bytes) - * - * \param ctx AES context - * \param mode AES_ENCRYPT or AES_DECRYPT - * \param length length of the input data - * \param iv initialization vector (updated after use) - * \param input buffer holding the input data - * \param output buffer holding the output data - * - * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH - */ -int aes_crypt_cbc( aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); - -/** - * \brief AES-CFB128 buffer encryption/decryption. - * - * \param ctx AES context - * \param mode AES_ENCRYPT or AES_DECRYPT - * \param length length of the input data - * \param iv_off offset in IV (updated after use) - * \param iv initialization vector (updated after use) - * \param input buffer holding the input data - * \param output buffer holding the output data - * - * \return 0 if successful - */ -int aes_crypt_cfb128( aes_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); - -/* - * \brief AES-CTR buffer encryption/decryption - * - * Warning: You have to keep the maximum use of your counter in mind! - * - * \param length The length of the data - * \param nc_off The offset in the current stream_block (for resuming - * within current cipher stream). The offset pointer to - * should be 0 at the start of a stream. - * \param nonce_counter The 128-bit nonce and counter. - * \param stream_block The saved stream-block for resuming. Is overwritten - * by the function. - * \param input The input data stream - * \param output The output data stream - * - * \return 0 if successful - */ -int aes_crypt_ctr( aes_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[16], - unsigned char stream_block[16], - const unsigned char *input, - unsigned char *output ); -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int aes_self_test( int verbose ); - -#ifdef __cplusplus -} -#endif - -#endif /* aes.h */ diff --git a/!NotAdopted/Tlen/crypto/polarssl/bignum.h b/!NotAdopted/Tlen/crypto/polarssl/bignum.h deleted file mode 100644 index 7938406708..0000000000 --- a/!NotAdopted/Tlen/crypto/polarssl/bignum.h +++ /dev/null @@ -1,587 +0,0 @@ -/** - * \file bignum.h - * - * \brief Multi-precision integer library - * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef POLARSSL_BIGNUM_H -#define POLARSSL_BIGNUM_H - -#include -#include - -#define POLARSSL_ERR_MPI_FILE_IO_ERROR -0x0002 /**< An error occurred while reading from or writing to a file. */ -#define POLARSSL_ERR_MPI_BAD_INPUT_DATA -0x0004 /**< Bad input parameters to function. */ -#define POLARSSL_ERR_MPI_INVALID_CHARACTER -0x0006 /**< There is an invalid character in the digit string. */ -#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL -0x0008 /**< The output buffer is too small to write too. */ -#define POLARSSL_ERR_MPI_NEGATIVE_VALUE -0x000A /**< The input arguments are negative or result in illegal output. */ -#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO -0x000C /**< The input argument for division is zero, which is not allowed. */ -#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */ - -#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup - -/* - * Maximum size MPIs are allowed to grow to in number of limbs. - */ -#define POLARSSL_MPI_MAX_LIMBS 10000 - -/* - * Define the base integer type, architecture-wise - */ -#if defined(POLARSSL_HAVE_INT8) -typedef signed char t_sint; -typedef unsigned char t_uint; -typedef unsigned short t_udbl; -#else -#if defined(POLARSSL_HAVE_INT16) -typedef signed short t_sint; -typedef unsigned short t_uint; -typedef unsigned long t_udbl; -#else - typedef signed long t_sint; - typedef unsigned long t_uint; - #if defined(_MSC_VER) && defined(_M_IX86) - typedef unsigned __int64 t_udbl; - #else - #if defined(__amd64__) || defined(__x86_64__) || \ - defined(__ppc64__) || defined(__powerpc64__) || \ - defined(__ia64__) || defined(__alpha__) - typedef unsigned int t_udbl __attribute__((mode(TI))); - #else - #if defined(POLARSSL_HAVE_LONGLONG) - typedef unsigned long long t_udbl; - #endif - #endif - #endif -#endif -#endif - -/** - * \brief MPI structure - */ -typedef struct -{ - int s; /*!< integer sign */ - size_t n; /*!< total # of limbs */ - t_uint *p; /*!< pointer to limbs */ -} -mpi; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Initialize one MPI - * - * \param X One MPI to initialize. - */ -void mpi_init( mpi *X ); - -/** - * \brief Unallocate one MPI - * - * \param X One MPI to unallocate. - */ -void mpi_free( mpi *X ); - -/** - * \brief Enlarge to the specified number of limbs - * - * \param X MPI to grow - * \param nblimbs The target number of limbs - * - * \return 0 if successful, - * 1 if memory allocation failed - */ -int mpi_grow( mpi *X, size_t nblimbs ); - -/** - * \brief Copy the contents of Y into X - * - * \param X Destination MPI - * \param Y Source MPI - * - * \return 0 if successful, - * 1 if memory allocation failed - */ -int mpi_copy( mpi *X, const mpi *Y ); - -/** - * \brief Swap the contents of X and Y - * - * \param X First MPI value - * \param Y Second MPI value - */ -void mpi_swap( mpi *X, mpi *Y ); - -/** - * \brief Set value from integer - * - * \param X MPI to set - * \param z Value to use - * - * \return 0 if successful, - * 1 if memory allocation failed - */ -int mpi_lset( mpi *X, t_sint z ); - -/* - * \brief Get a specific bit from X - * - * \param X MPI to use - * \param pos Zero-based index of the bit in X - * - * \return Either a 0 or a 1 - */ -int mpi_get_bit( mpi *X, size_t pos ); - -/* - * \brief Set a bit of X to a specific value of 0 or 1 - * - * \note Will grow X if necessary to set a bit to 1 in a not yet - * existing limb. Will not grow if bit should be set to 0 - * - * \param X MPI to use - * \param pos Zero-based index of the bit in X - * \param val The value to set the bit to (0 or 1) - * - * \return 0 if successful, - * 1 if memory allocation failed, - * POLARSSL_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1 - */ -int mpi_set_bit( mpi *X, size_t pos, unsigned char val ); - -/** - * \brief Return the number of least significant bits - * - * \param X MPI to use - */ -size_t mpi_lsb( const mpi *X ); - -/** - * \brief Return the number of most significant bits - * - * \param X MPI to use - */ -size_t mpi_msb( const mpi *X ); - -/** - * \brief Return the total size in bytes - * - * \param X MPI to use - */ -size_t mpi_size( const mpi *X ); - -/** - * \brief Import from an ASCII string - * - * \param X Destination MPI - * \param radix Input numeric base - * \param s Null-terminated string buffer - * - * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code - */ -int mpi_read_string( mpi *X, int radix, const char *s ); - -/** - * \brief Export into an ASCII string - * - * \param X Source MPI - * \param radix Output numeric base - * \param s String buffer - * \param slen String buffer size - * - * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code. - * *slen is always updated to reflect the amount - * of data that has (or would have) been written. - * - * \note Call this function with *slen = 0 to obtain the - * minimum required buffer size in *slen. - */ -int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen ); - -/** - * \brief Read X from an opened file - * - * \param X Destination MPI - * \param radix Input numeric base - * \param fin Input file handle - * - * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code - */ -int mpi_read_file( mpi *X, int radix, FILE *fin ); - -/** - * \brief Write X into an opened file, or stdout if fout is NULL - * - * \param p Prefix, can be NULL - * \param X Source MPI - * \param radix Output numeric base - * \param fout Output file handle (can be NULL) - * - * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code - * - * \note Set fout == NULL to print X on the console. - */ -int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout ); - -/** - * \brief Import X from unsigned binary data, big endian - * - * \param X Destination MPI - * \param buf Input buffer - * \param buflen Input buffer size - * - * \return 0 if successful, - * 1 if memory allocation failed - */ -int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen ); - -/** - * \brief Export X into unsigned binary data, big endian - * - * \param X Source MPI - * \param buf Output buffer - * \param buflen Output buffer size - * - * \return 0 if successful, - * POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough - */ -int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen ); - -/** - * \brief Left-shift: X <<= count - * - * \param X MPI to shift - * \param count Amount to shift - * - * \return 0 if successful, - * 1 if memory allocation failed - */ -int mpi_shift_l( mpi *X, size_t count ); - -/** - * \brief Right-shift: X >>= count - * - * \param X MPI to shift - * \param count Amount to shift - * - * \return 0 if successful, - * 1 if memory allocation failed - */ -int mpi_shift_r( mpi *X, size_t count ); - -/** - * \brief Compare unsigned values - * - * \param X Left-hand MPI - * \param Y Right-hand MPI - * - * \return 1 if |X| is greater than |Y|, - * -1 if |X| is lesser than |Y| or - * 0 if |X| is equal to |Y| - */ -int mpi_cmp_abs( const mpi *X, const mpi *Y ); - -/** - * \brief Compare signed values - * - * \param X Left-hand MPI - * \param Y Right-hand MPI - * - * \return 1 if X is greater than Y, - * -1 if X is lesser than Y or - * 0 if X is equal to Y - */ -int mpi_cmp_mpi( const mpi *X, const mpi *Y ); - -/** - * \brief Compare signed values - * - * \param X Left-hand MPI - * \param z The integer value to compare to - * - * \return 1 if X is greater than z, - * -1 if X is lesser than z or - * 0 if X is equal to z - */ -int mpi_cmp_int( const mpi *X, t_sint z ); - -/** - * \brief Unsigned addition: X = |A| + |B| - * - * \param X Destination MPI - * \param A Left-hand MPI - * \param B Right-hand MPI - * - * \return 0 if successful, - * 1 if memory allocation failed - */ -int mpi_add_abs( mpi *X, const mpi *A, const mpi *B ); - -/** - * \brief Unsigned substraction: X = |A| - |B| - * - * \param X Destination MPI - * \param A Left-hand MPI - * \param B Right-hand MPI - * - * \return 0 if successful, - * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A - */ -int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B ); - -/** - * \brief Signed addition: X = A + B - * - * \param X Destination MPI - * \param A Left-hand MPI - * \param B Right-hand MPI - * - * \return 0 if successful, - * 1 if memory allocation failed - */ -int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B ); - -/** - * \brief Signed substraction: X = A - B - * - * \param X Destination MPI - * \param A Left-hand MPI - * \param B Right-hand MPI - * - * \return 0 if successful, - * 1 if memory allocation failed - */ -int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B ); - -/** - * \brief Signed addition: X = A + b - * - * \param X Destination MPI - * \param A Left-hand MPI - * \param b The integer value to add - * - * \return 0 if successful, - * 1 if memory allocation failed - */ -int mpi_add_int( mpi *X, const mpi *A, t_sint b ); - -/** - * \brief Signed substraction: X = A - b - * - * \param X Destination MPI - * \param A Left-hand MPI - * \param b The integer value to subtract - * - * \return 0 if successful, - * 1 if memory allocation failed - */ -int mpi_sub_int( mpi *X, const mpi *A, t_sint b ); - -/** - * \brief Baseline multiplication: X = A * B - * - * \param X Destination MPI - * \param A Left-hand MPI - * \param B Right-hand MPI - * - * \return 0 if successful, - * 1 if memory allocation failed - */ -int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B ); - -/** - * \brief Baseline multiplication: X = A * b - * Note: b is an unsigned integer type, thus - * Negative values of b are ignored. - * - * \param X Destination MPI - * \param A Left-hand MPI - * \param b The integer value to multiply with - * - * \return 0 if successful, - * 1 if memory allocation failed - */ -int mpi_mul_int( mpi *X, const mpi *A, t_sint b ); - -/** - * \brief Division by mpi: A = Q * B + R - * - * \param Q Destination MPI for the quotient - * \param R Destination MPI for the rest value - * \param A Left-hand MPI - * \param B Right-hand MPI - * - * \return 0 if successful, - * 1 if memory allocation failed, - * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0 - * - * \note Either Q or R can be NULL. - */ -int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ); - -/** - * \brief Division by int: A = Q * b + R - * - * \param Q Destination MPI for the quotient - * \param R Destination MPI for the rest value - * \param A Left-hand MPI - * \param b Integer to divide by - * - * \return 0 if successful, - * 1 if memory allocation failed, - * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0 - * - * \note Either Q or R can be NULL. - */ -int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b ); - -/** - * \brief Modulo: R = A mod B - * - * \param R Destination MPI for the rest value - * \param A Left-hand MPI - * \param B Right-hand MPI - * - * \return 0 if successful, - * 1 if memory allocation failed, - * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0, - * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0 - */ -int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B ); - -/** - * \brief Modulo: r = A mod b - * - * \param r Destination t_uint - * \param A Left-hand MPI - * \param b Integer to divide by - * - * \return 0 if successful, - * 1 if memory allocation failed, - * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0, - * POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0 - */ -int mpi_mod_int( t_uint *r, const mpi *A, t_sint b ); - -/** - * \brief Sliding-window exponentiation: X = A^E mod N - * - * \param X Destination MPI - * \param A Left-hand MPI - * \param E Exponent MPI - * \param N Modular MPI - * \param _RR Speed-up MPI used for recalculations - * - * \return 0 if successful, - * 1 if memory allocation failed, - * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even - * - * \note _RR is used to avoid re-computing R*R mod N across - * multiple calls, which speeds up things a bit. It can - * be set to NULL if the extra performance is unneeded. - */ -int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ); - -/** - * \brief Fill an MPI X with size bytes of random - * - * \param X Destination MPI - * \param size Size in bytes - * \param f_rng RNG function - * \param p_rng RNG parameter - * - * \return 0 if successful, - * 1 if memory allocation failed - */ -int mpi_fill_random( mpi *X, size_t size, int (*f_rng)(void *), void *p_rng ); - -/** - * \brief Greatest common divisor: G = gcd(A, B) - * - * \param G Destination MPI - * \param A Left-hand MPI - * \param B Right-hand MPI - * - * \return 0 if successful, - * 1 if memory allocation failed - */ -int mpi_gcd( mpi *G, const mpi *A, const mpi *B ); - -/** - * \brief Modular inverse: X = A^-1 mod N - * - * \param X Destination MPI - * \param A Left-hand MPI - * \param N Right-hand MPI - * - * \return 0 if successful, - * 1 if memory allocation failed, - * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil - POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N - */ -int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N ); - -/** - * \brief Miller-Rabin primality test - * - * \param X MPI to check - * \param f_rng RNG function - * \param p_rng RNG parameter - * - * \return 0 if successful (probably prime), - * 1 if memory allocation failed, - * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime - */ -int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng ); - -/** - * \brief Prime number generation - * - * \param X Destination MPI - * \param nbits Required size of X in bits ( 3 <= nbits <= 4096 ) - * \param dh_flag If 1, then (X-1)/2 will be prime too - * \param f_rng RNG function - * \param p_rng RNG parameter - * - * \return 0 if successful (probably prime), - * 1 if memory allocation failed, - * POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3 - */ -int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag, - int (*f_rng)(void *), void *p_rng ); - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mpi_self_test( int verbose ); - -#ifdef __cplusplus -} -#endif - -#endif /* bignum.h */ diff --git a/!NotAdopted/Tlen/crypto/polarssl/bn_mul.h b/!NotAdopted/Tlen/crypto/polarssl/bn_mul.h deleted file mode 100644 index 59a32857cb..0000000000 --- a/!NotAdopted/Tlen/crypto/polarssl/bn_mul.h +++ /dev/null @@ -1,738 +0,0 @@ -/** - * \file bn_mul.h - * - * \brief Multi-precision integer library - * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* - * Multiply source vector [s] with b, add result - * to destination vector [d] and set carry c. - * - * Currently supports: - * - * . IA-32 (386+) . AMD64 / EM64T - * . IA-32 (SSE2) . Motorola 68000 - * . PowerPC, 32-bit . MicroBlaze - * . PowerPC, 64-bit . TriCore - * . SPARC v8 . ARM v3+ - * . Alpha . MIPS32 - * . C, longlong . C, generic - */ -#ifndef POLARSSL_BN_MUL_H -#define POLARSSL_BN_MUL_H - -#include "polarssl/config.h" - -#if defined(POLARSSL_HAVE_ASM) - -#if defined(__GNUC__) -#if defined(__i386__) - -#define MULADDC_INIT \ - asm( " \ - movl %%ebx, %0; \ - movl %5, %%esi; \ - movl %6, %%edi; \ - movl %7, %%ecx; \ - movl %8, %%ebx; \ - " - -#define MULADDC_CORE \ - " \ - lodsl; \ - mull %%ebx; \ - addl %%ecx, %%eax; \ - adcl $0, %%edx; \ - addl (%%edi), %%eax; \ - adcl $0, %%edx; \ - movl %%edx, %%ecx; \ - stosl; \ - " - -#if defined(POLARSSL_HAVE_SSE2) - -#define MULADDC_HUIT \ - " \ - movd %%ecx, %%mm1; \ - movd %%ebx, %%mm0; \ - movd (%%edi), %%mm3; \ - paddq %%mm3, %%mm1; \ - movd (%%esi), %%mm2; \ - pmuludq %%mm0, %%mm2; \ - movd 4(%%esi), %%mm4; \ - pmuludq %%mm0, %%mm4; \ - movd 8(%%esi), %%mm6; \ - pmuludq %%mm0, %%mm6; \ - movd 12(%%esi), %%mm7; \ - pmuludq %%mm0, %%mm7; \ - paddq %%mm2, %%mm1; \ - movd 4(%%edi), %%mm3; \ - paddq %%mm4, %%mm3; \ - movd 8(%%edi), %%mm5; \ - paddq %%mm6, %%mm5; \ - movd 12(%%edi), %%mm4; \ - paddq %%mm4, %%mm7; \ - movd %%mm1, (%%edi); \ - movd 16(%%esi), %%mm2; \ - pmuludq %%mm0, %%mm2; \ - psrlq $32, %%mm1; \ - movd 20(%%esi), %%mm4; \ - pmuludq %%mm0, %%mm4; \ - paddq %%mm3, %%mm1; \ - movd 24(%%esi), %%mm6; \ - pmuludq %%mm0, %%mm6; \ - movd %%mm1, 4(%%edi); \ - psrlq $32, %%mm1; \ - movd 28(%%esi), %%mm3; \ - pmuludq %%mm0, %%mm3; \ - paddq %%mm5, %%mm1; \ - movd 16(%%edi), %%mm5; \ - paddq %%mm5, %%mm2; \ - movd %%mm1, 8(%%edi); \ - psrlq $32, %%mm1; \ - paddq %%mm7, %%mm1; \ - movd 20(%%edi), %%mm5; \ - paddq %%mm5, %%mm4; \ - movd %%mm1, 12(%%edi); \ - psrlq $32, %%mm1; \ - paddq %%mm2, %%mm1; \ - movd 24(%%edi), %%mm5; \ - paddq %%mm5, %%mm6; \ - movd %%mm1, 16(%%edi); \ - psrlq $32, %%mm1; \ - paddq %%mm4, %%mm1; \ - movd 28(%%edi), %%mm5; \ - paddq %%mm5, %%mm3; \ - movd %%mm1, 20(%%edi); \ - psrlq $32, %%mm1; \ - paddq %%mm6, %%mm1; \ - movd %%mm1, 24(%%edi); \ - psrlq $32, %%mm1; \ - paddq %%mm3, %%mm1; \ - movd %%mm1, 28(%%edi); \ - addl $32, %%edi; \ - addl $32, %%esi; \ - psrlq $32, %%mm1; \ - movd %%mm1, %%ecx; \ - " - -#define MULADDC_STOP \ - " \ - emms; \ - movl %4, %%ebx; \ - movl %%ecx, %1; \ - movl %%edi, %2; \ - movl %%esi, %3; \ - " \ - : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ - : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ - : "eax", "ecx", "edx", "esi", "edi" \ - ); - -#else - -#define MULADDC_STOP \ - " \ - movl %4, %%ebx; \ - movl %%ecx, %1; \ - movl %%edi, %2; \ - movl %%esi, %3; \ - " \ - : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ - : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ - : "eax", "ecx", "edx", "esi", "edi" \ - ); -#endif /* SSE2 */ -#endif /* i386 */ - -#if defined(__amd64__) || defined (__x86_64__) - -#define MULADDC_INIT \ - asm( "movq %0, %%rsi " :: "m" (s)); \ - asm( "movq %0, %%rdi " :: "m" (d)); \ - asm( "movq %0, %%rcx " :: "m" (c)); \ - asm( "movq %0, %%rbx " :: "m" (b)); \ - asm( "xorq %r8, %r8 " ); - -#define MULADDC_CORE \ - asm( "movq (%rsi),%rax " ); \ - asm( "mulq %rbx " ); \ - asm( "addq $8, %rsi " ); \ - asm( "addq %rcx, %rax " ); \ - asm( "movq %r8, %rcx " ); \ - asm( "adcq $0, %rdx " ); \ - asm( "nop " ); \ - asm( "addq %rax, (%rdi) " ); \ - asm( "adcq %rdx, %rcx " ); \ - asm( "addq $8, %rdi " ); - -#define MULADDC_STOP \ - asm( "movq %%rcx, %0 " : "=m" (c)); \ - asm( "movq %%rdi, %0 " : "=m" (d)); \ - asm( "movq %%rsi, %0 " : "=m" (s) :: \ - "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" ); - -#endif /* AMD64 */ - -#if defined(__mc68020__) || defined(__mcpu32__) - -#define MULADDC_INIT \ - asm( "movl %0, %%a2 " :: "m" (s)); \ - asm( "movl %0, %%a3 " :: "m" (d)); \ - asm( "movl %0, %%d3 " :: "m" (c)); \ - asm( "movl %0, %%d2 " :: "m" (b)); \ - asm( "moveq #0, %d0 " ); - -#define MULADDC_CORE \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d4:%d1 " ); \ - asm( "addl %d3, %d1 " ); \ - asm( "addxl %d0, %d4 " ); \ - asm( "moveq #0, %d3 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "addxl %d4, %d3 " ); - -#define MULADDC_STOP \ - asm( "movl %%d3, %0 " : "=m" (c)); \ - asm( "movl %%a3, %0 " : "=m" (d)); \ - asm( "movl %%a2, %0 " : "=m" (s) :: \ - "d0", "d1", "d2", "d3", "d4", "a2", "a3" ); - -#define MULADDC_HUIT \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d4:%d1 " ); \ - asm( "addxl %d3, %d1 " ); \ - asm( "addxl %d0, %d4 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d3:%d1 " ); \ - asm( "addxl %d4, %d1 " ); \ - asm( "addxl %d0, %d3 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d4:%d1 " ); \ - asm( "addxl %d3, %d1 " ); \ - asm( "addxl %d0, %d4 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d3:%d1 " ); \ - asm( "addxl %d4, %d1 " ); \ - asm( "addxl %d0, %d3 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d4:%d1 " ); \ - asm( "addxl %d3, %d1 " ); \ - asm( "addxl %d0, %d4 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d3:%d1 " ); \ - asm( "addxl %d4, %d1 " ); \ - asm( "addxl %d0, %d3 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d4:%d1 " ); \ - asm( "addxl %d3, %d1 " ); \ - asm( "addxl %d0, %d4 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "movel %a2@+, %d1 " ); \ - asm( "mulul %d2, %d3:%d1 " ); \ - asm( "addxl %d4, %d1 " ); \ - asm( "addxl %d0, %d3 " ); \ - asm( "addl %d1, %a3@+ " ); \ - asm( "addxl %d0, %d3 " ); - -#endif /* MC68000 */ - -#if defined(__powerpc__) || defined(__ppc__) -#if defined(__powerpc64__) || defined(__ppc64__) - -#if defined(__MACH__) && defined(__APPLE__) - -#define MULADDC_INIT \ - asm( "ld r3, %0 " :: "m" (s)); \ - asm( "ld r4, %0 " :: "m" (d)); \ - asm( "ld r5, %0 " :: "m" (c)); \ - asm( "ld r6, %0 " :: "m" (b)); \ - asm( "addi r3, r3, -8 " ); \ - asm( "addi r4, r4, -8 " ); \ - asm( "addic r5, r5, 0 " ); - -#define MULADDC_CORE \ - asm( "ldu r7, 8(r3) " ); \ - asm( "mulld r8, r7, r6 " ); \ - asm( "mulhdu r9, r7, r6 " ); \ - asm( "adde r8, r8, r5 " ); \ - asm( "ld r7, 8(r4) " ); \ - asm( "addze r5, r9 " ); \ - asm( "addc r8, r8, r7 " ); \ - asm( "stdu r8, 8(r4) " ); - -#define MULADDC_STOP \ - asm( "addze r5, r5 " ); \ - asm( "addi r4, r4, 8 " ); \ - asm( "addi r3, r3, 8 " ); \ - asm( "std r5, %0 " : "=m" (c)); \ - asm( "std r4, %0 " : "=m" (d)); \ - asm( "std r3, %0 " : "=m" (s) :: \ - "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); - -#else - -#define MULADDC_INIT \ - asm( "ld %%r3, %0 " :: "m" (s)); \ - asm( "ld %%r4, %0 " :: "m" (d)); \ - asm( "ld %%r5, %0 " :: "m" (c)); \ - asm( "ld %%r6, %0 " :: "m" (b)); \ - asm( "addi %r3, %r3, -8 " ); \ - asm( "addi %r4, %r4, -8 " ); \ - asm( "addic %r5, %r5, 0 " ); - -#define MULADDC_CORE \ - asm( "ldu %r7, 8(%r3) " ); \ - asm( "mulld %r8, %r7, %r6 " ); \ - asm( "mulhdu %r9, %r7, %r6 " ); \ - asm( "adde %r8, %r8, %r5 " ); \ - asm( "ld %r7, 8(%r4) " ); \ - asm( "addze %r5, %r9 " ); \ - asm( "addc %r8, %r8, %r7 " ); \ - asm( "stdu %r8, 8(%r4) " ); - -#define MULADDC_STOP \ - asm( "addze %r5, %r5 " ); \ - asm( "addi %r4, %r4, 8 " ); \ - asm( "addi %r3, %r3, 8 " ); \ - asm( "std %%r5, %0 " : "=m" (c)); \ - asm( "std %%r4, %0 " : "=m" (d)); \ - asm( "std %%r3, %0 " : "=m" (s) :: \ - "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); - -#endif - -#else /* PPC32 */ - -#if defined(__MACH__) && defined(__APPLE__) - -#define MULADDC_INIT \ - asm( "lwz r3, %0 " :: "m" (s)); \ - asm( "lwz r4, %0 " :: "m" (d)); \ - asm( "lwz r5, %0 " :: "m" (c)); \ - asm( "lwz r6, %0 " :: "m" (b)); \ - asm( "addi r3, r3, -4 " ); \ - asm( "addi r4, r4, -4 " ); \ - asm( "addic r5, r5, 0 " ); - -#define MULADDC_CORE \ - asm( "lwzu r7, 4(r3) " ); \ - asm( "mullw r8, r7, r6 " ); \ - asm( "mulhwu r9, r7, r6 " ); \ - asm( "adde r8, r8, r5 " ); \ - asm( "lwz r7, 4(r4) " ); \ - asm( "addze r5, r9 " ); \ - asm( "addc r8, r8, r7 " ); \ - asm( "stwu r8, 4(r4) " ); - -#define MULADDC_STOP \ - asm( "addze r5, r5 " ); \ - asm( "addi r4, r4, 4 " ); \ - asm( "addi r3, r3, 4 " ); \ - asm( "stw r5, %0 " : "=m" (c)); \ - asm( "stw r4, %0 " : "=m" (d)); \ - asm( "stw r3, %0 " : "=m" (s) :: \ - "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); - -#else - -#define MULADDC_INIT \ - asm( "lwz %%r3, %0 " :: "m" (s)); \ - asm( "lwz %%r4, %0 " :: "m" (d)); \ - asm( "lwz %%r5, %0 " :: "m" (c)); \ - asm( "lwz %%r6, %0 " :: "m" (b)); \ - asm( "addi %r3, %r3, -4 " ); \ - asm( "addi %r4, %r4, -4 " ); \ - asm( "addic %r5, %r5, 0 " ); - -#define MULADDC_CORE \ - asm( "lwzu %r7, 4(%r3) " ); \ - asm( "mullw %r8, %r7, %r6 " ); \ - asm( "mulhwu %r9, %r7, %r6 " ); \ - asm( "adde %r8, %r8, %r5 " ); \ - asm( "lwz %r7, 4(%r4) " ); \ - asm( "addze %r5, %r9 " ); \ - asm( "addc %r8, %r8, %r7 " ); \ - asm( "stwu %r8, 4(%r4) " ); - -#define MULADDC_STOP \ - asm( "addze %r5, %r5 " ); \ - asm( "addi %r4, %r4, 4 " ); \ - asm( "addi %r3, %r3, 4 " ); \ - asm( "stw %%r5, %0 " : "=m" (c)); \ - asm( "stw %%r4, %0 " : "=m" (d)); \ - asm( "stw %%r3, %0 " : "=m" (s) :: \ - "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); - -#endif - -#endif /* PPC32 */ -#endif /* PPC64 */ - -#if defined(__sparc__) - -#define MULADDC_INIT \ - asm( "ld %0, %%o0 " :: "m" (s)); \ - asm( "ld %0, %%o1 " :: "m" (d)); \ - asm( "ld %0, %%o2 " :: "m" (c)); \ - asm( "ld %0, %%o3 " :: "m" (b)); - -#define MULADDC_CORE \ - asm( "ld [%o0], %o4 " ); \ - asm( "inc 4, %o0 " ); \ - asm( "ld [%o1], %o5 " ); \ - asm( "umul %o3, %o4, %o4 " ); \ - asm( "addcc %o4, %o2, %o4 " ); \ - asm( "rd %y, %g1 " ); \ - asm( "addx %g1, 0, %g1 " ); \ - asm( "addcc %o4, %o5, %o4 " ); \ - asm( "st %o4, [%o1] " ); \ - asm( "addx %g1, 0, %o2 " ); \ - asm( "inc 4, %o1 " ); - -#define MULADDC_STOP \ - asm( "st %%o2, %0 " : "=m" (c)); \ - asm( "st %%o1, %0 " : "=m" (d)); \ - asm( "st %%o0, %0 " : "=m" (s) :: \ - "g1", "o0", "o1", "o2", "o3", "o4", "o5" ); - -#endif /* SPARCv8 */ - -#if defined(__microblaze__) || defined(microblaze) - -#define MULADDC_INIT \ - asm( "lwi r3, %0 " :: "m" (s)); \ - asm( "lwi r4, %0 " :: "m" (d)); \ - asm( "lwi r5, %0 " :: "m" (c)); \ - asm( "lwi r6, %0 " :: "m" (b)); \ - asm( "andi r7, r6, 0xffff" ); \ - asm( "bsrli r6, r6, 16 " ); - -#define MULADDC_CORE \ - asm( "lhui r8, r3, 0 " ); \ - asm( "addi r3, r3, 2 " ); \ - asm( "lhui r9, r3, 0 " ); \ - asm( "addi r3, r3, 2 " ); \ - asm( "mul r10, r9, r6 " ); \ - asm( "mul r11, r8, r7 " ); \ - asm( "mul r12, r9, r7 " ); \ - asm( "mul r13, r8, r6 " ); \ - asm( "bsrli r8, r10, 16 " ); \ - asm( "bsrli r9, r11, 16 " ); \ - asm( "add r13, r13, r8 " ); \ - asm( "add r13, r13, r9 " ); \ - asm( "bslli r10, r10, 16 " ); \ - asm( "bslli r11, r11, 16 " ); \ - asm( "add r12, r12, r10 " ); \ - asm( "addc r13, r13, r0 " ); \ - asm( "add r12, r12, r11 " ); \ - asm( "addc r13, r13, r0 " ); \ - asm( "lwi r10, r4, 0 " ); \ - asm( "add r12, r12, r10 " ); \ - asm( "addc r13, r13, r0 " ); \ - asm( "add r12, r12, r5 " ); \ - asm( "addc r5, r13, r0 " ); \ - asm( "swi r12, r4, 0 " ); \ - asm( "addi r4, r4, 4 " ); - -#define MULADDC_STOP \ - asm( "swi r5, %0 " : "=m" (c)); \ - asm( "swi r4, %0 " : "=m" (d)); \ - asm( "swi r3, %0 " : "=m" (s) :: \ - "r3", "r4" , "r5" , "r6" , "r7" , "r8" , \ - "r9", "r10", "r11", "r12", "r13" ); - -#endif /* MicroBlaze */ - -#if defined(__tricore__) - -#define MULADDC_INIT \ - asm( "ld.a %%a2, %0 " :: "m" (s)); \ - asm( "ld.a %%a3, %0 " :: "m" (d)); \ - asm( "ld.w %%d4, %0 " :: "m" (c)); \ - asm( "ld.w %%d1, %0 " :: "m" (b)); \ - asm( "xor %d5, %d5 " ); - -#define MULADDC_CORE \ - asm( "ld.w %d0, [%a2+] " ); \ - asm( "madd.u %e2, %e4, %d0, %d1 " ); \ - asm( "ld.w %d0, [%a3] " ); \ - asm( "addx %d2, %d2, %d0 " ); \ - asm( "addc %d3, %d3, 0 " ); \ - asm( "mov %d4, %d3 " ); \ - asm( "st.w [%a3+], %d2 " ); - -#define MULADDC_STOP \ - asm( "st.w %0, %%d4 " : "=m" (c)); \ - asm( "st.a %0, %%a3 " : "=m" (d)); \ - asm( "st.a %0, %%a2 " : "=m" (s) :: \ - "d0", "d1", "e2", "d4", "a2", "a3" ); - -#endif /* TriCore */ - -#if defined(__arm__) - -#define MULADDC_INIT \ - asm( "ldr r0, %0 " :: "m" (s)); \ - asm( "ldr r1, %0 " :: "m" (d)); \ - asm( "ldr r2, %0 " :: "m" (c)); \ - asm( "ldr r3, %0 " :: "m" (b)); - -#define MULADDC_CORE \ - asm( "ldr r4, [r0], #4 " ); \ - asm( "mov r5, #0 " ); \ - asm( "ldr r6, [r1] " ); \ - asm( "umlal r2, r5, r3, r4 " ); \ - asm( "adds r7, r6, r2 " ); \ - asm( "adc r2, r5, #0 " ); \ - asm( "str r7, [r1], #4 " ); - -#define MULADDC_STOP \ - asm( "str r2, %0 " : "=m" (c)); \ - asm( "str r1, %0 " : "=m" (d)); \ - asm( "str r0, %0 " : "=m" (s) :: \ - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" ); - -#endif /* ARMv3 */ - -#if defined(__alpha__) - -#define MULADDC_INIT \ - asm( "ldq $1, %0 " :: "m" (s)); \ - asm( "ldq $2, %0 " :: "m" (d)); \ - asm( "ldq $3, %0 " :: "m" (c)); \ - asm( "ldq $4, %0 " :: "m" (b)); - -#define MULADDC_CORE \ - asm( "ldq $6, 0($1) " ); \ - asm( "addq $1, 8, $1 " ); \ - asm( "mulq $6, $4, $7 " ); \ - asm( "umulh $6, $4, $6 " ); \ - asm( "addq $7, $3, $7 " ); \ - asm( "cmpult $7, $3, $3 " ); \ - asm( "ldq $5, 0($2) " ); \ - asm( "addq $7, $5, $7 " ); \ - asm( "cmpult $7, $5, $5 " ); \ - asm( "stq $7, 0($2) " ); \ - asm( "addq $2, 8, $2 " ); \ - asm( "addq $6, $3, $3 " ); \ - asm( "addq $5, $3, $3 " ); - -#define MULADDC_STOP \ - asm( "stq $3, %0 " : "=m" (c)); \ - asm( "stq $2, %0 " : "=m" (d)); \ - asm( "stq $1, %0 " : "=m" (s) :: \ - "$1", "$2", "$3", "$4", "$5", "$6", "$7" ); - -#endif /* Alpha */ - -#if defined(__mips__) - -#define MULADDC_INIT \ - asm( "lw $10, %0 " :: "m" (s)); \ - asm( "lw $11, %0 " :: "m" (d)); \ - asm( "lw $12, %0 " :: "m" (c)); \ - asm( "lw $13, %0 " :: "m" (b)); - -#define MULADDC_CORE \ - asm( "lw $14, 0($10) " ); \ - asm( "multu $13, $14 " ); \ - asm( "addi $10, $10, 4 " ); \ - asm( "mflo $14 " ); \ - asm( "mfhi $9 " ); \ - asm( "addu $14, $12, $14 " ); \ - asm( "lw $15, 0($11) " ); \ - asm( "sltu $12, $14, $12 " ); \ - asm( "addu $15, $14, $15 " ); \ - asm( "sltu $14, $15, $14 " ); \ - asm( "addu $12, $12, $9 " ); \ - asm( "sw $15, 0($11) " ); \ - asm( "addu $12, $12, $14 " ); \ - asm( "addi $11, $11, 4 " ); - -#define MULADDC_STOP \ - asm( "sw $12, %0 " : "=m" (c)); \ - asm( "sw $11, %0 " : "=m" (d)); \ - asm( "sw $10, %0 " : "=m" (s) :: \ - "$9", "$10", "$11", "$12", "$13", "$14", "$15" ); - -#endif /* MIPS */ -#endif /* GNUC */ - -#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) - -#define MULADDC_INIT \ - __asm mov esi, s \ - __asm mov edi, d \ - __asm mov ecx, c \ - __asm mov ebx, b - -#define MULADDC_CORE \ - __asm lodsd \ - __asm mul ebx \ - __asm add eax, ecx \ - __asm adc edx, 0 \ - __asm add eax, [edi] \ - __asm adc edx, 0 \ - __asm mov ecx, edx \ - __asm stosd - -#if defined(POLARSSL_HAVE_SSE2) - -#define EMIT __asm _emit - -#define MULADDC_HUIT \ - EMIT 0x0F EMIT 0x6E EMIT 0xC9 \ - EMIT 0x0F EMIT 0x6E EMIT 0xC3 \ - EMIT 0x0F EMIT 0x6E EMIT 0x1F \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ - EMIT 0x0F EMIT 0x6E EMIT 0x16 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ - EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ - EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ - EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \ - EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ - EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xDC \ - EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xEE \ - EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \ - EMIT 0x0F EMIT 0xD4 EMIT 0xFC \ - EMIT 0x0F EMIT 0x7E EMIT 0x0F \ - EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ - EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \ - EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \ - EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCD \ - EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCF \ - EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ - EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCC \ - EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \ - EMIT 0x0F EMIT 0xD4 EMIT 0xDD \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCE \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ - EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \ - EMIT 0x83 EMIT 0xC7 EMIT 0x20 \ - EMIT 0x83 EMIT 0xC6 EMIT 0x20 \ - EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ - EMIT 0x0F EMIT 0x7E EMIT 0xC9 - -#define MULADDC_STOP \ - EMIT 0x0F EMIT 0x77 \ - __asm mov c, ecx \ - __asm mov d, edi \ - __asm mov s, esi \ - -#else - -#define MULADDC_STOP \ - __asm mov c, ecx \ - __asm mov d, edi \ - __asm mov s, esi \ - -#endif /* SSE2 */ -#endif /* MSVC */ - -#endif /* POLARSSL_HAVE_ASM */ - -#if !defined(MULADDC_CORE) -#if defined(POLARSSL_HAVE_LONGLONG) - -#define MULADDC_INIT \ -{ \ - t_udbl r; \ - t_uint r0, r1; - -#define MULADDC_CORE \ - r = *(s++) * (t_udbl) b; \ - r0 = r; \ - r1 = r >> biL; \ - r0 += c; r1 += (r0 < c); \ - r0 += *d; r1 += (r0 < *d); \ - c = r1; *(d++) = r0; - -#define MULADDC_STOP \ -} - -#else -#define MULADDC_INIT \ -{ \ - t_uint s0, s1, b0, b1; \ - t_uint r0, r1, rx, ry; \ - b0 = ( b << biH ) >> biH; \ - b1 = ( b >> biH ); - -#define MULADDC_CORE \ - s0 = ( *s << biH ) >> biH; \ - s1 = ( *s >> biH ); s++; \ - rx = s0 * b1; r0 = s0 * b0; \ - ry = s1 * b0; r1 = s1 * b1; \ - r1 += ( rx >> biH ); \ - r1 += ( ry >> biH ); \ - rx <<= biH; ry <<= biH; \ - r0 += rx; r1 += (r0 < rx); \ - r0 += ry; r1 += (r0 < ry); \ - r0 += c; r1 += (r0 < c); \ - r0 += *d; r1 += (r0 < *d); \ - c = r1; *(d++) = r0; - -#define MULADDC_STOP \ -} - -#endif /* C (generic) */ -#endif /* C (longlong) */ - -#endif /* bn_mul.h */ diff --git a/!NotAdopted/Tlen/crypto/polarssl/config.h b/!NotAdopted/Tlen/crypto/polarssl/config.h deleted file mode 100644 index 61500a75ee..0000000000 --- a/!NotAdopted/Tlen/crypto/polarssl/config.h +++ /dev/null @@ -1,625 +0,0 @@ -/** - * \file config.h - * - * \brief Configuration options (set of defines) - * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * This set of compile-time options may be used to enable - * or disable features selectively, and reduce the global - * memory footprint. - */ -#ifndef POLARSSL_CONFIG_H -#define POLARSSL_CONFIG_H - -#ifndef _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_DEPRECATE 1 -#endif - -/** - * \name SECTION: System support - * - * This section sets system specific settings. - * \{ - */ - -/** - * \def POLARSSL_HAVE_INT8 - * - * The system uses 8-bit wide native integers. - * - * Uncomment if native integers are 8-bit wide. -#define POLARSSL_HAVE_INT8 - */ - -/** - * \def POLARSSL_HAVE_INT16 - * - * The system uses 16-bit wide native integers. - * - * Uncomment if native integers are 16-bit wide. -#define POLARSSL_HAVE_INT16 - */ - -/** - * \def POLARSSL_HAVE_LONGLONG - * - * The compiler supports the use of long long. - * - * Uncomment if the compiler supports long long. -#define POLARSSL_HAVE_LONGLONG - */ - -/** - * \def POLARSSL_HAVE_ASM - * - * The compiler has support for asm() - * - * Uncomment to enable the use of assembly code. - * - * Requires support for asm() in compiler. - * - * Used in: - * library/timing.c - * library/padlock.c - * include/polarssl/bn_mul.h - * - */ -#define POLARSSL_HAVE_ASM - -/** - * \def POLARSSL_HAVE_SSE2 - * - * CPI supports SSE2 instruction set. - * - * Uncomment if the CPU supports SSE2 (IA-32 specific). - * -#define POLARSSL_HAVE_SSE2 - */ -/* \} name */ - -/** - * \name SECTION: PolarSSL feature support - * - * This section sets support for features that are or are not needed - * within the modules that are enabled. - * \{ - */ - -/** - * \def POLARSSL_AES_ROM_TABLES - * - * Store the AES tables in ROM. - * - * Uncomment this macro to store the AES tables in ROM. - * -#define POLARSSL_AES_ROM_TABLES - */ - -/** - * \def POLARSSL_CIPHER_MODE_CFB - * - * Enable Cipher Feedback mode (CFB) for symmetric ciphers. - */ -#define POLARSSL_CIPHER_MODE_CFB - -/** - * \def POLARSSL_CIPHER_MODE_CTR - * - * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. - */ -#define POLARSSL_CIPHER_MODE_CTR - -/** - * \def POLARSSL_DEBUG_MSG - * - * Requires: POLARSSL_DEBUG_C - * - * Enable all SSL/TLS debugging messages. - */ -#define POLARSSL_DEBUG_MSG - -/** - * \def POLARSSL_GENPRIME - * - * Requires: POLARSSL_BIGNUM_C, POLARSSL_RSA_C - * - * Enable the RSA prime-number generation code. - */ -#define POLARSSL_GENPRIME - -/** - * \def POLARSSL_FS_IO - * - * Enable functions that use the filesystem. - */ -#define POLARSSL_FS_IO - -/** - * \def POLARSSL_PKCS1_V21 - * - * Requires: POLARSSL_MD_C, POLARSSL_RSA_C - * - * Enable support for PKCS#1 v2.1 encoding. - * This enables support for RSAES-OAEP and RSASSA-PSS operations. - */ -#define POLARSSL_PKCS1_V21 - -/** - * \def POLARSSL_RSA_NO_CRT - * - * Do not use the Chinese Remainder Theorem for the RSA private operation. - * - * Uncomment this macro to disable the use of CRT in RSA. - * -#define POLARSSL_RSA_NO_CRT - */ - -/** - * \def POLARSSL_SELF_TEST - * - * Enable the checkup functions (*_self_test). - */ -#define POLARSSL_SELF_TEST - -/** - * \def POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION - * - * If set, the X509 parser will not break-off when parsing an X509 certificate - * and encountering an unknown critical extension. - * - * Uncomment to prevent an error. - * -#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION - */ -/* \} name */ - -/** - * \name SECTION: PolarSSL modules - * - * This section enables or disables entire modules in PolarSSL - * \{ - */ - -/** - * \def POLARSSL_AES_C - * - * Enable the AES block cipher. - * - * Module: library/aes.c - * Caller: library/ssl_tls.c - * library/pem.c - * - * This module enables the following ciphersuites: - * SSL_RSA_AES_128_SHA - * SSL_RSA_AES_256_SHA - * SSL_EDH_RSA_AES_256_SHA - */ -#define POLARSSL_AES_C - -/** - * \def POLARSSL_ARC4_C - * - * Enable the ARCFOUR stream cipher. - * - * Module: library/arc4.c - * Caller: library/ssl_tls.c - * - * This module enables the following ciphersuites: - * SSL_RSA_RC4_128_MD5 - * SSL_RSA_RC4_128_SHA - */ -#define POLARSSL_ARC4_C - -/** - * \def POLARSSL_BASE64_C - * - * Enable the Base64 module. - * - * Module: library/base64.c - * Caller: library/pem.c - * - * This module is required for PEM support (required by X.509). - */ -#define POLARSSL_BASE64_C - -/** - * \def POLARSSL_BIGNUM_C - * - * Enable the multo-precision integer library. - * - * Module: library/bignum.c - * Caller: library/dhm.c - * library/rsa.c - * library/ssl_tls.c - * library/x509parse.c - * - * This module is required for RSA and DHM support. - */ -#define POLARSSL_BIGNUM_C - -/** - * \def POLARSSL_CAMELLIA_C - * - * Enable the Camellia block cipher. - * - * Module: library/camellia.c - * Caller: library/ssl_tls.c - * - * This module enabled the following cipher suites: - * SSL_RSA_CAMELLIA_128_SHA - * SSL_RSA_CAMELLIA_256_SHA - * SSL_EDH_RSA_CAMELLIA_256_SHA - */ -#define POLARSSL_CAMELLIA_C - -/** - * \def POLARSSL_CERTS_C - * - * Enable the test certificates. - * - * Module: library/certs.c - * Caller: - * - * This module is used for testing (ssl_client/server). - */ -#define POLARSSL_CERTS_C - -/** - * \def POLARSSL_CIPHER_C - * - * Enable the generic cipher layer. - * - * Module: library/cipher.c - * Caller: - * - * Uncomment to enable generic cipher wrappers. - */ -#define POLARSSL_CIPHER_C - -/** - * \def POLARSSL_DEBUG_C - * - * Enable the debug functions. - * - * Module: library/debug.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * - * This module provides debugging functions. - */ -#define POLARSSL_DEBUG_C - -/** - * \def POLARSSL_DES_C - * - * Enable the DES block cipher. - * - * Module: library/des.c - * Caller: library/ssl_tls.c - * - * This module enables the following ciphersuites: - * SSL_RSA_DES_168_SHA - * SSL_EDH_RSA_DES_168_SHA - */ -#define POLARSSL_DES_C - -/** - * \def POLARSSL_DHM_C - * - * Enable the Diffie-Hellman-Merkle key exchange. - * - * Module: library/dhm.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * This module enables the following ciphersuites: - * SSL_EDH_RSA_DES_168_SHA - * SSL_EDH_RSA_AES_256_SHA - * SSL_EDH_RSA_CAMELLIA_256_SHA - */ -#define POLARSSL_DHM_C - -/** - * \def POLARSSL_ERROR_C - * - * Enable error code to error string conversion. - * - * Module: library/error.c - * Caller: - * - * This module enables err_strerror(). - */ -#define POLARSSL_ERROR_C - -/** - * \def POLARSSL_HAVEGE_C - * - * Enable the HAVEGE random generator. - * - * Module: library/havege.c - * Caller: - * - * Requires: POLARSSL_TIMING_C - * - * This module enables the HAVEGE random number generator. - */ -#define POLARSSL_HAVEGE_C - -/** - * \def POLARSSL_MD_C - * - * Enable the generic message digest layer. - * - * Module: library/md.c - * Caller: - * - * Uncomment to enable generic message digest wrappers. - */ -#define POLARSSL_MD_C - -/** - * \def POLARSSL_MD2_C - * - * Enable the MD2 hash algorithm - * - * Module: library/md2.c - * Caller: library/x509parse.c - * - * Uncomment to enable support for (rare) MD2-signed X.509 certs. - * -#define POLARSSL_MD2_C - */ - -/** - * \def POLARSSL_MD4_C - * - * Enable the MD4 hash algorithm - * - * Module: library/md4.c - * Caller: library/x509parse.c - * - * Uncomment to enable support for (rare) MD4-signed X.509 certs. - * -#define POLARSSL_MD4_C - */ - -/** - * \def POLARSSL_MD5_C - * - * Enable the MD5 hash algorithm - * - * Module: library/md5.c - * Caller: library/ssl_tls.c - * library/x509parse.c - * - * This module is required for SSL/TLS and X.509. - */ -#define POLARSSL_MD5_C - -/** - * \def POLARSSL_NET_C - * - * Enable the TCP/IP networking routines. - * - * Module: library/net.c - * Caller: - * - * This module provides TCP/IP networking routines. - */ -#define POLARSSL_NET_C - -/** - * \def POLARSSL_PADLOCK_C - * - * Enable VIA Padlock support on x86. - * - * Module: library/padlock.c - * Caller: library/aes.c - * - * This modules adds support for the VIA PadLock on x86. - */ -#define POLARSSL_PADLOCK_C - -/** - * \def POLARSSL_PEM_C - * - * Enable PEM decoding - * - * Module: library/pem.c - * Caller: library/x509parse.c - * - * Requires: POLARSSL_BASE64_C - * - * This modules adds support for decoding PEM files. - */ -#define POLARSSL_PEM_C - -/** - * \def POLARSSL_PKCS11_C - * - * Enable support for PKCS#11 smartcard support. - * - * Module: library/ssl_srv.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * Requires: POLARSSL_SSL_TLS_C - * - * This module is required for SSL/TLS PKCS #11 smartcard support. - * Requires the presence of the PKCS#11 helper library (libpkcs11-helper) -#define POLARSSL_PKCS11_C - */ - -/** - * \def POLARSSL_RSA_C - * - * Enable the RSA public-key cryptosystem. - * - * Module: library/rsa.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * library/x509.c - * - * Requires: POLARSSL_BIGNUM_C - * - * This module is required for SSL/TLS and MD5-signed certificates. - */ -#define POLARSSL_RSA_C - -/** - * \def POLARSSL_SHA1_C - * - * Enable the SHA1 cryptographic hash algorithm. - * - * Module: library/sha1.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * library/x509parse.c - * - * This module is required for SSL/TLS and SHA1-signed certificates. - */ -#define POLARSSL_SHA1_C - -/** - * \def POLARSSL_SHA2_C - * - * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. - * - * Module: library/sha2.c - * Caller: library/md_wrap.c - * library/x509parse.c - * - * This module adds support for SHA-224 and SHA-256. - */ -#define POLARSSL_SHA2_C - -/** - * \def POLARSSL_SHA4_C - * - * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. - * - * Module: library/sha4.c - * Caller: library/md_wrap.c - * library/x509parse.c - * - * This module adds support for SHA-384 and SHA-512. - */ -#define POLARSSL_SHA4_C - -/** - * \def POLARSSL_SSL_CLI_C - * - * Enable the SSL/TLS client code. - * - * Module: library/ssl_cli.c - * Caller: - * - * Requires: POLARSSL_SSL_TLS_C - * - * This module is required for SSL/TLS client support. - */ -#define POLARSSL_SSL_CLI_C - -/* - * \def POLARSSL_SSL_SRV_C - * - * Enable the SSL/TLS server code. - * - * Module: library/ssl_srv.c - * Caller: - * - * Requires: POLARSSL_SSL_TLS_C - * - * This module is required for SSL/TLS server support. - */ -#define POLARSSL_SSL_SRV_C - -/** - * \def POLARSSL_SSL_TLS_C - * - * Enable the generic SSL/TLS code. - * - * Module: library/ssl_tls.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * Requires: POLARSSL_MD5_C, POLARSSL_SHA1_C, POLARSSL_X509_PARSE_C - * - * This module is required for SSL/TLS. - */ -#define POLARSSL_SSL_TLS_C - -/** - * \def POLARSSL_TIMING_C - * - * Enable the portable timing interface. - * - * Module: library/timing.c - * Caller: library/havege.c - * - * This module is used by the HAVEGE random number generator. - */ -#define POLARSSL_TIMING_C - -/** - * \def POLARSSL_VERSION_C - * - * Enable run-time version information. - * - * Module: library/version.c - * - * This module provides run-time version information. - */ -#define POLARSSL_VERSION_C - -/** - * \def POLARSSL_X509_PARSE_C - * - * Enable X.509 certificate parsing. - * - * Module: library/x509parse.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * - * Requires: POLARSSL_BIGNUM_C, POLARSSL_RSA_C - * - * This module is required for X.509 certificate parsing. - */ -#define POLARSSL_X509_PARSE_C - -/** - * \def POLARSSL_XTEA_C - * - * Enable the XTEA block cipher. - * - * Module: library/xtea.c - * Caller: - */ -#define POLARSSL_XTEA_C -/* \} name */ - -#endif /* config.h */ diff --git a/!NotAdopted/Tlen/crypto/polarssl/padlock.h b/!NotAdopted/Tlen/crypto/polarssl/padlock.h deleted file mode 100644 index 08fbe825c9..0000000000 --- a/!NotAdopted/Tlen/crypto/polarssl/padlock.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * \file padlock.h - * - * \brief VIA PadLock ACE for HW encryption/decryption supported by some processors - * - * Copyright (C) 2006-2010, Brainspark B.V. - * - * This file is part of PolarSSL (http://www.polarssl.org) - * Lead Maintainer: Paul Bakker - * - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef POLARSSL_PADLOCK_H -#define POLARSSL_PADLOCK_H - -#include "polarssl/aes.h" - -#define POLARSSL_ERR_PADLOCK_DATA_MISALIGNED -0x0030 /**< Input data should be aligned. */ - -#if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && defined(__i386__) - -#ifndef POLARSSL_HAVE_X86 -#define POLARSSL_HAVE_X86 -#endif - -#define PADLOCK_RNG 0x000C -#define PADLOCK_ACE 0x00C0 -#define PADLOCK_PHE 0x0C00 -#define PADLOCK_PMM 0x3000 - -#define PADLOCK_ALIGN16(x) (unsigned long *) (16 + ((long) x & ~15)) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief PadLock detection routine - * - * \param The feature to detect - * - * \return 1 if CPU has support for the feature, 0 otherwise - */ -int padlock_supports( int feature ); - -/** - * \brief PadLock AES-ECB block en(de)cryption - * - * \param ctx AES context - * \param mode AES_ENCRYPT or AES_DECRYPT - * \param input 16-byte input block - * \param output 16-byte output block - * - * \return 0 if success, 1 if operation failed - */ -int padlock_xcryptecb( aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ); - -/** - * \brief PadLock AES-CBC buffer en(de)cryption - * - * \param ctx AES context - * \param mode AES_ENCRYPT or AES_DECRYPT - * \param length length of the input data - * \param iv initialization vector (updated after use) - * \param input buffer holding the input data - * \param output buffer holding the output data - * - * \return 0 if success, 1 if operation failed - */ -int padlock_xcryptcbc( aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); - -#ifdef __cplusplus -} -#endif - -#endif /* HAVE_X86 */ - -#endif /* padlock.h */ diff --git a/!NotAdopted/Tlen/docs/InstallScript.xml b/!NotAdopted/Tlen/docs/InstallScript.xml deleted file mode 100644 index 7d8a8f28fe..0000000000 --- a/!NotAdopted/Tlen/docs/InstallScript.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - Tlen Protocol - Santithorn Bunchua - 0.1.0.2 - Plugin - - - - Main Files - tlen.dll - tlen_czaty.dll - - - - - Documentation - readme_tlen.txt - - - - - readme_tlen.txt - - - diff --git a/!NotAdopted/Tlen/docs/changelog_tlen.txt b/!NotAdopted/Tlen/docs/changelog_tlen.txt deleted file mode 100644 index b2c05c760a..0000000000 --- a/!NotAdopted/Tlen/docs/changelog_tlen.txt +++ /dev/null @@ -1,269 +0,0 @@ -Version 2.0.5.0 -------- -* Project cleanup - + change mucc.dll to tlen_czaty.dll - + compile tlen_czaty in Unicode and x64 -* fix warnings, project files changes -Version 2.0.4.1 -------- -- fix accounts... dialog -Version 2.0.4.0 -------- -+ x64 version -* set timeout to NETLIBOPENCONNECTION (patch by piotrw) -* fix for display texts at comboboxes in unicode (patch by piotrw) -* fixes in Find/Add Contacts search (by piotrw, dezeath and wsx22) -* fix warnings, project files changes (add VS2010) -Version 2.0.3.2 -------- -* update PolarSSL library to polarssl-1.0.0 -* change compile options to not require microsoft visual studio runtime libs on user system, (100KB larger file but no problems with msvcr90.dll not found on user system) -Version 2.0.2.0 -------- -* "Leave status message after disconnection", "Send and receive client version information" and "Log alerts as messages" options enabled by default (AL|EN suggestion) -Version 2.0.1.0 -------- -merge changes from wsx22 mod -* fix in typing notify message handling -* fix in logging to server message -Version 2.0.0.0 -------- -+ Image transfer -* other bug fixes and improvements -Version 1.8.0.2 -------- -improved icons handling -minor fixes on account unloading -1.8.0.1 -------- -* bugfix: removed ME_SYSTEM_MODULESLOADED hook -1.8.0.0 -------- -+ support for account manager (requires MIM 0.8) -* many bugfixes and small improvements -1.1.0.0 -------- -* avatar support improvements -1.0.9.2 -------- -* avatar management UI changes -* user info page changes -* some clean-up and bugfixes -* fix for advertisement blocking -* fix for file transfers -1.0.9.1 -------- -* avatar management improvements -1.0.9.0 -------- -+ message encryption -* improved search (up to 200 results displayed) -* some avatar-related fixes -* MIM 0.7 compatibility -1.0.7.7 -------- -* new icons by Angelika -1.0.7.6 -------- -+ support for Tlen avatars -1.0.7.5 -------- -* bugfix: settings changes were not loaded properly -1.0.7.4 -------- -* p2p connections refactoring -* UPnP support -* managed services/hooks -* support for IcoLib -* new icons -* support for Miranda Memory Manager -1.0.7.3 --------- -* bugfix: offline status message -1.0.7.2 --------- -! fixed compatibility issues with new versions of IEView (1.0.9.0 or higher) -+ support for Nudge plugin -* improved avatar support -* improved sending/receiving client version info -1.0.7.1 ---------- -* bugfix: sending/receiving client version info -1.0.7.0 ---------- -+ full support for avatars (compatible with tAvatar 0.0.2.1 or higher) -+ sending and receiving full client version info -* optimized DB usage -* code cleanup -1.0.6.9 ---------- -+ experimental client recognition -+ voice chat notification sound -* bugfix: offline message timestamp -* code clean-up -1.0.6.8 ---------- -* bugfix: compatibility with Unicode contact lists -* bugfix: user login is always converted to lower case -* bugfix: typing notifications -* other bugfixes -1.0.6.7 ---------- -+ possibility to send files to offline users -+ public status visibility settings -* bugfixes -1.0.6.6 ---------- -* fixed IEView support (text scrolling issue) -* code cleanup -1.0.6.5 ---------- -+ option to ignore advertisements -* bugfixes -1.0.6.4 ---------- -+ alert, voice chat and group chat policies -+ received alerts are logged as messages -* offline message timestamp improvements (thanks to Atay for the idea) -* removed obsolete, Jabber-specific code -* a lot of more or less important bugfixes -1.0.6.3 ---------- -+ group names encoding -+ log saving in IEView mode -* simplified option page -1.0.6.2 ---------- -+ support for IEView group chats (IEView 1.0.3.0 or later) -+ improvements of group chats in RichEdit mode (context menu, better scrolling) -1.0.6.1 ---------- -* bugfix: proper filename encoding -* options page rearranged -* code cleanup, other fixes and improvements -1.0.6.0 ---------- -+ group chat window flashing -+ message icons in tabbed mode -+ web messages grouped as a single contact -* offline message timestamp handling fixed (again) -1.0.5.10 RC2 ---------- -+ tabbed mode available in group chat window -+ saving chat log to file -+ smiley selection button in group chat window -+ new shortcuts: ctrl+w (close), ctrl+a (select all) -+ saving chat fonts setting -+ new menu items: request and grant authorization -* several bugfixes in MUCC plugin, better MUCC architecture -1.0.5.9 RC ---------- -+ voice chat improvements (better sound quality and smarter delay reduction, bugfixes) -+ separate group for Global Owners in chat user list -* bugfix: web messages receiving (fix by MoMaT) -1.0.5.8 ---------- -+ playback and recording device selection -+ sending and receiving alerts (use to send) -+ enabling/disabling Always Visible support -* bugfixes -1.0.5.7 ---------- -+ chat room administration window (user administration and browser) -+ unban option -+ dynamic user groups -+ voice chat p2p connection negotiation -+ voice chat status display -+ incoming voice chat invitation dialog -+ removing contacts from roster on authorization denial -+ offline status message selection -* a lot of fixes in group chats interface -1.0.5.6 ---------- -+ voice chats ! (experimental) -+ chat room administration: destroying room, changing users' roles, kick & ban -+ MUCC option: send on Enter -+ status messages of offline contacts (use mToolTip to read them) -* bugfix: contact name encoding when adding new contact -* bugfix: offline messages time ('more inteligent' Daylight Saving Time handling) -* bugfix: closing all file transfers at shutdown -* other minor fixes -1.0.5.5 ---------- -+ improved file transfer (p2p connection negotiation, error notification) -+ MUCC options page (fonts, colors, default filters) -+ chat room events logging (user has joined etc.) -+ registering and uregistering nick names -+ creating chat rooms -+ chat room topic displaying and setting -+ improved errors handling -* look & feel improvements -* bugfix: correct chat room name returned by search -* bugfix: removing users from contact list groups -* source code refactoring -1.0.5.4 ---------- -+ group chats error handling -+ message log formatting options -+ chat room searching -+ list of contacts in 'invite to group chat' dialog -+ Multi-User Conference item in contact menu -+ some look & feel improvements (better resizing, new icons) -+ internal history of messages -* a lot of bugfixes and code improvements -* code clean-up -1.0.5.3 ---------- -+ full text formatting (font name, font size) -+ private messaging sessions -+ displaying user details (administrator/moderator/registered nickname) -+ displaying chat room details icons (moderated/members only/anonymous nicknames not allowed) -+ browsing own chat rooms/registered nicknames -* code clean-up -* bugfixes -1.0.5.2 ---------- -+ text formatting (bold, italic, underline, text color for now) -+ chat rooms browsing page by page -* bugfixes and code clean-up -1.0.5.1 ---------- -+ initial multi-user conferences and chats support -+ MUCC plugin responsible for chats GUI (manager window (groups/rooms), messanging window, helper dialogs) - -2004-09-23 Version 1.0.4.0 - Jabber and Tlen now have separate source trees (Tlen plugin is compliant with GCC now) - File transfer with forwarding and SOCKS4/5 proxy support - vCard viewing and editing - Web messages receiving - Incoming email notification through the popup plugin and sounds - User typing notification (patch by Adam Libura) - Searching users by login - New user details page - Invisible status message - Option to leave offline status message - Option to show offline users with status message as invisible - Link to create new account - Fixed bug: adjust offline message time - A lot of other fixes and improvements - -2003-08-19 Version 0.1.0.2 - Fixed bug: crash when receiving some invisible presence - Fixed bug: incorrect newline encoding/decoding (tlen uses \r\n while jabber uses \n) - Fixed bug: User detail text is not decoded - Use new invisible presence (now conform to Jabber invisible presence) - Advanced search - Based on Jabber plugin 0.1.1.2 - -2003-05-12 Version 0.1.0.1 - Fixed bug: slightly incorrect online presence - Based on Jabber plugin 0.1.1.0 - -2003-01-19 Version 0.1.0.0 - Based on Jabber plugin 0.1.0.7 - Tlen basic user info - Tlen invisible status - Tlen visible/invisible list - Option to show invisible users as invisible - Find/add users using tlen user database - Rebase DLL to 0x32600000 diff --git a/!NotAdopted/Tlen/docs/gpl.txt b/!NotAdopted/Tlen/docs/gpl.txt deleted file mode 100644 index 45645b4b53..0000000000 --- a/!NotAdopted/Tlen/docs/gpl.txt +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/!NotAdopted/Tlen/docs/gpl_comment.txt b/!NotAdopted/Tlen/docs/gpl_comment.txt deleted file mode 100644 index ecacc17720..0000000000 --- a/!NotAdopted/Tlen/docs/gpl_comment.txt +++ /dev/null @@ -1,20 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2012 Santithorn Bunchua, Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ diff --git a/!NotAdopted/Tlen/docs/readme_tlen.txt b/!NotAdopted/Tlen/docs/readme_tlen.txt deleted file mode 100644 index 234e9b098b..0000000000 --- a/!NotAdopted/Tlen/docs/readme_tlen.txt +++ /dev/null @@ -1,60 +0,0 @@ -Tlen Protocol Plugin for Miranda IM -=================================== - -Introduction: - Tlen is a protocol used by a propritary instant messaging network - at tlen.pl. It is based on Jabber, and, therefore, this plugin - is very much based on Jabber protocol plugin for Miranda. All - necessary helps to create this Tlen plugin are from Adam Strzelecki. - -Installation: - Copy tlen.dll and (optional) tlen_czaty.dll to Miranda's plugins directory. - - If you want to have multiple Tlen accounts online at the same time, - you need to have multiple copies of tlen.dll, each with different name, - all in Miranda's plugins directory. Note that all configurations for a - Tlen account (including your contact list) are associated with the - DLL's name. In addition, it is highly recommended that you do NOT choose - the name that is in conflict with other plugins or any database categories - used by Miranda core (use DatabaseViewer or DatabaseEditor to see what - database categories are already in use). - -More information: - Web: http://mtlen.berlios.de - E-mail: the_leech@users.berlios.de - -Copyright (c) 2002-2012 Santithorn Bunchua (keh@au.edu), Piotr Piastucki - -Acknowledgement: - We would like to thank the following people for their helps and/or comments - (alphabetically listed): - Dmitry Balabanov - Nikola Dachev - Sam Kothari - Adam Libura - Jцrgen Persson - Robert Rainwater - Adam Strzelecki - Michal Wojciechowski - Szymon Tokarz (wsx22) - -================================================================ - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2012 Santithorn Bunchua, Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -================================================================ diff --git a/!NotAdopted/Tlen/docs/tlen-translation.txt b/!NotAdopted/Tlen/docs/tlen-translation.txt deleted file mode 100644 index 6406f204c7..0000000000 --- a/!NotAdopted/Tlen/docs/tlen-translation.txt +++ /dev/null @@ -1,153 +0,0 @@ -;*********************************** -;******* Tlen language by raq ****** - -[Tlen czaty] -;[Authentication failed for] -;[Tlen Authentication] -[Network] -[Advanced] -[PopUps] -[Accept all alerts] -[Ignore alerts from unauthorized contacts] -[Ignore all alerts] -[Always ask me] -[Accept invitations from authorized contacts] -[Accept all invitations] -[Ignore invitations from unauthorized contacts] -[Ignore all invitation] -[Always ask me] -[] -[] -[Online] -[Away] -[NA] -[DND] -[Free for chat] -[Invisible] -[These changes will take effect the next time you connect to the Tlen network.] -[Tlen Protocol Option] -[Forwarding] -;[SOCKS4] -;[SOCKS5] -;[Tlen login] -[Enter password for] -[Error: Not enough memory] -[Error: Cannot connect to the server] -[The connection requires an OpenSSL library, which is not installed.] -;[Jabber Connection Error] -[%s Web Messages] -[Web message] -[From] -;[E-mail] -[An alert has been received.] -[Private conference] -[New mail] -[Subject] -;[both] -[to] -[from] -[none] -;[not on roster] -[Error] -[Unknown error message] -[connection] -[Incoming mail] -;[Alert] -[Multi-User Conference] -[Tlen Chats...] -[Voice Chat] -[Voice chat] -[Request authorization] -[Grant authorization] -[You have been kicked. Reason: %s ] -[You cannot join this chat room, because you are banned.] -[Chat room not found.] -[This is a private chat room and you are not one of the members.] -[You cannot send any message unless you join this chat room.] -[Chat room with already created.] -[Nickname '%s' is already registered.] -[Nickname already in use, please try another one. Hint: '%s' is free.] -[You cannot register more than %s nicknames.] -[You cannot create more than %s chat rooms.] -[You cannot join more than %s chat rooms.] -[Anonymous nicknames are not allowed in this chat room.] -[Unknown error code : %d] -[Default] - -;tlen.rc - -[Username:] -[Create a new account] -[Password:] -[Save password] -[Use SSL] -[Options] -[Automatically reconnect after unintentional disconnection] -[Leave status message after disconnection] -[Ignore advertisements] -[Automatically delete contacts not in my roster] -[Show offline users with status messages as invisible in contact list] -[Enable avatars] -[Send and receive version information] -[Use Nudge plugin] -[Log alerts as messages] -[Alert policy] -[Group chat policy] -[Voice Chats] -[Voice chat policy] -[Recording device:] -[Playback device:] -[Expert Options] -[Login server:] -[Connection Host:] -;[Port:] -[Keep connection alive] -[Enable Always Visible and Never Visible] -[File Transfer and Voice Chats] -[Use proxy for incoming connections] -[Proxy type:] -[Proxy server:] -[Proxy requires authorization] -[Delay] -[&From PopUp plugin] -[&Custom] -[P&ermanent] -[Colours] -[Background] -[Text] -[General Options] -[Preview] -[Enable incoming mail notification] -;[OK] -[Cancel] -[Nick name:] -[First name:] -[Last name:] -;[E-mail:] -[Gender:] -[Year of birth:] -[City:] -[School:] -[Occupation:] -[Looking for:] -[Voice chats] -[Save changes] -;[Subscription:] -[Age:] -[Personal Information] -;[Status:] -[Plan:] -[&Accept] -[From:] -[Software:] -[Version:] -[System:] -[The following invitation to join a voice chat is received.] -[Current Avatar] -[New Avatar] -[Public] -[Browse...] -[Set] -[Delete] -[Note: Image size max. 64x64] -[Enable encryption] diff --git a/!NotAdopted/Tlen/icos/auth_grant.ico b/!NotAdopted/Tlen/icos/auth_grant.ico deleted file mode 100644 index 8d1ba94308..0000000000 Binary files a/!NotAdopted/Tlen/icos/auth_grant.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/icos/auth_request.ico b/!NotAdopted/Tlen/icos/auth_request.ico deleted file mode 100644 index 116ed47baf..0000000000 Binary files a/!NotAdopted/Tlen/icos/auth_request.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/icos/groupchats.ico b/!NotAdopted/Tlen/icos/groupchats.ico deleted file mode 100644 index ecd2070d20..0000000000 Binary files a/!NotAdopted/Tlen/icos/groupchats.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/icos/image.ico b/!NotAdopted/Tlen/icos/image.ico deleted file mode 100644 index 832b9a8b69..0000000000 Binary files a/!NotAdopted/Tlen/icos/image.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/icos/mail.ico b/!NotAdopted/Tlen/icos/mail.ico deleted file mode 100644 index c5ded81702..0000000000 Binary files a/!NotAdopted/Tlen/icos/mail.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/icos/microphone.ico b/!NotAdopted/Tlen/icos/microphone.ico deleted file mode 100644 index 1edeb90d1f..0000000000 Binary files a/!NotAdopted/Tlen/icos/microphone.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/icos/speaker.ico b/!NotAdopted/Tlen/icos/speaker.ico deleted file mode 100644 index 77545c0598..0000000000 Binary files a/!NotAdopted/Tlen/icos/speaker.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/icos/tlen.ico b/!NotAdopted/Tlen/icos/tlen.ico deleted file mode 100644 index a166dd4c5b..0000000000 Binary files a/!NotAdopted/Tlen/icos/tlen.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/icos/tlenchats.ico b/!NotAdopted/Tlen/icos/tlenchats.ico deleted file mode 100644 index 52ab77ff63..0000000000 Binary files a/!NotAdopted/Tlen/icos/tlenchats.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/icos/voicechat.ico b/!NotAdopted/Tlen/icos/voicechat.ico deleted file mode 100644 index f989d5b212..0000000000 Binary files a/!NotAdopted/Tlen/icos/voicechat.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/jabber.h b/!NotAdopted/Tlen/jabber.h deleted file mode 100644 index fdaabf5e43..0000000000 --- a/!NotAdopted/Tlen/jabber.h +++ /dev/null @@ -1,438 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#ifndef _JABBER_H_ -#define _JABBER_H_ - -#if defined(UNICODE) - #ifndef _UNICODE - #define _UNICODE - #endif -#endif - -#define MIRANDA_VER 0x0800 - -#undef _WIN32_WINNT -#undef _WIN32_IE -#define _WIN32_WINNT 0x0501 -#define _WIN32_IE 0x0501 - -#define __try -#define __except(x) if (0) -#define __finally - -#define _try __try -#define _except __except -#define _finally __finally - -#ifdef _DEBUG -#define _CRTDBG_MAP_ALLOC -#include -#include -#endif -#define ENABLE_LOGGING - -/******************************************************************* - * Global compilation flags - *******************************************************************/ - -/******************************************************************* - * Global header files - *******************************************************************/ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "jabber_xml.h" -#include "crypto/polarssl/aes.h" -#include "crypto/polarssl/bignum.h" - -/******************************************************************* - * Global constants - *******************************************************************/ -#define TLEN_DEFAULT_PORT 443 -#define JABBER_IQID "mim_" -#define TLEN_REGISTER "http://reg.tlen.pl/" -#define TLEN_MAX_SEARCH_RESULTS_PER_PAGE 20 - -// User-defined message -#define WM_TLEN_REFRESH (WM_USER + 100) -// Error code -#define JABBER_ERROR_REDIRECT 302 -#define JABBER_ERROR_BAD_REQUEST 400 -#define JABBER_ERROR_UNAUTHORIZED 401 -#define JABBER_ERROR_PAYMENT_REQUIRED 402 -#define JABBER_ERROR_FORBIDDEN 403 -#define JABBER_ERROR_NOT_FOUND 404 -#define JABBER_ERROR_NOT_ALLOWED 405 -#define JABBER_ERROR_NOT_ACCEPTABLE 406 -#define JABBER_ERROR_REGISTRATION_REQUIRED 407 -#define JABBER_ERROR_REQUEST_TIMEOUT 408 -#define JABBER_ERROR_CONFLICT 409 -#define JABBER_ERROR_INTERNAL_SERVER_ERROR 500 -#define JABBER_ERROR_NOT_IMPLEMENTED 501 -#define JABBER_ERROR_REMOTE_SERVER_ERROR 502 -#define JABBER_ERROR_SERVICE_UNAVAILABLE 503 -#define JABBER_ERROR_REMOTE_SERVER_TIMEOUT 504 - -#define TLEN_ALERTS_ACCEPT_ALL 0 -#define TLEN_ALERTS_IGNORE_NIR 1 -#define TLEN_ALERTS_IGNORE_ALL 2 - -#define TLEN_IMAGES_ACCEPT_ALL 0 -#define TLEN_IMAGES_IGNORE_NIR 1 -#define TLEN_IMAGES_IGNORE_ALL 2 - -#define TLEN_MUC_ASK 0 -#define TLEN_MUC_ACCEPT_IR 1 -#define TLEN_MUC_ACCEPT_ALL 2 -#define TLEN_MUC_IGNORE_NIR 3 -#define TLEN_MUC_IGNORE_ALL 4 - -#define IDC_STATIC (-1) - -/******************************************************************* - * Global data structures and data type definitions - *******************************************************************/ -typedef HANDLE JABBER_SOCKET; - -typedef enum { - LIST_ROSTER, // Roster list - LIST_CHATROOM, // Groupchat room currently joined - LIST_FILE, // Current file transfer session - LIST_INVITATIONS,// Invitations to be sent - LIST_SEARCH, // Rooms names being searched - LIST_VOICE, - LIST_PICTURE -} JABBER_LIST; - -typedef enum { - IQ_PROC_NONE, - IQ_PROC_GETSEARCH -} JABBER_IQ_PROCID; - -typedef enum { - SUB_NONE, - SUB_TO, - SUB_FROM, - SUB_BOTH -} JABBER_SUBSCRIPTION; - -typedef struct { - char *szOnline; - char *szAway; - char *szNa; - char *szDnd; - char *szFreechat; - char *szInvisible; -} JABBER_MODEMSGS; - -typedef struct { - char mailBase[256]; - char mailMsg[256]; - int mailMsgMthd; - char mailIndex[256]; - int mailIndexMthd; - char mailLogin[256]; - int mailLoginMthd; - char mailCompose[256]; - int mailComposeMthd; - char avatarGet[256]; - int avatarGetMthd; - char avatarUpload[256]; - int avatarUploadMthd; - char avatarRemove[256]; - int avatarRemoveMthd; -} TlenConfiguration; - -typedef struct { - BOOL useEncryption; - BOOL reconnect; - BOOL rosterSync; - BOOL offlineAsInvisible; - BOOL leaveOfflineMessage; - int offlineMessageOption; - BOOL ignoreAdvertisements; - int alertPolicy; - int groupChatPolicy; - int voiceChatPolicy; - int imagePolicy; - BOOL enableAvatars; - BOOL enableVersion; - BOOL useNudge; - BOOL logAlerts; - BOOL useNewP2P; - BOOL sendKeepAlive; - BOOL savePassword; -} TlenOptions; - -struct JABBER_IQ_FUNC_STRUCT; -struct JABBER_LIST_ITEM_STRUCT; -struct TLEN_VOICE_CONTROL_STRUCT; - -typedef struct { - PROTO_INTERFACE iface; - HANDLE hNetlibUser; - HANDLE hFileNetlibUser; - - JABBER_MODEMSGS modeMsgs; - - struct ThreadDataStruct *threadData; - HANDLE hTlenNudge; - HANDLE hMenuMUC; - HANDLE hMenuChats; - HANDLE hMenuInbox; - HANDLE hMenuContactMUC; - HANDLE hMenuContactVoice; - HANDLE hMenuContactGrantAuth; - HANDLE hMenuContactRequestAuth; - HANDLE hMenuPicture; - - HANDLE* hServices; - unsigned serviceNum; - HANDLE* hHooks; - unsigned hookNum; - - int listsCount; - struct JABBER_LIST_ITEM_STRUCT *lists; - CRITICAL_SECTION csLists; - - int iqCount; - int iqAlloced; - struct JABBER_IQ_FUNC_STRUCT *iqList; - CRITICAL_SECTION csIqList; - - CRITICAL_SECTION csSerial; - unsigned int serial; - BOOL isOnline; - BOOL isConnected; - - CRITICAL_SECTION modeMsgMutex; - - HANDLE hMenuRoot; - - char *searchJID; - int searchID; - int searchIndex; - char *searchQuery; - int searchQueryLen; - - CRITICAL_SECTION csSend; - - HWND voiceDlgHWND; - struct TLEN_VOICE_CONTROL_STRUCT *playbackControl; - struct TLEN_VOICE_CONTROL_STRUCT *recordingControl; - int framesAvailableForPlayback; - int availOverrunValue; - - TlenOptions tlenOptions; -} TlenProtocol; - - -typedef struct ThreadDataStruct{ - HANDLE hThread; - char *streamId; - char username[128]; - char password[128]; - char server[128]; - char manualHost[128]; - char avatarToken[128]; - char avatarHash[64]; - int avatarFormat; - WORD port; - BOOL useEncryption; - - JABBER_SOCKET s; //HANDLE from CallService(MS_NETLIB_OPENCONNECTION (jabber_ws.c:68) - aes_context aes_in_context; - aes_context aes_out_context; - unsigned char aes_in_iv[16]; - unsigned char aes_out_iv[16]; - - BOOL useAES; - TlenConfiguration tlenConfig; - TlenProtocol *proto; -} ThreadData; - - -typedef enum { FT_CONNECTING, FT_INITIALIZING, FT_RECEIVING, FT_DONE, FT_ERROR, FT_DENIED, FT_SWITCH } JABBER_FILE_STATE; -typedef enum { FT_RECV, FT_SEND} JABBER_FILE_MODE; -typedef struct TLEN_FILE_TRANSFER_STRUCT{ - HANDLE hContact; - JABBER_SOCKET s; - NETLIBNEWCONNECTIONPROC_V2 pfnNewConnectionV2; - JABBER_FILE_STATE state; - char *jid; - int fileId; - char *iqId; - int mode; - - // Used by file receiving only - char *hostName; - WORD wPort; - char *localName; - WORD wLocalPort; - char *szSavePath; - long fileReceivedBytes; - long fileTotalSize; - - // Used by file sending only - HANDLE hFileEvent; - int fileCount; - char **files; - long *filesSize; - //long fileTotalSize; // Size of the current file (file being sent) - long allFileTotalSize; - long allFileReceivedBytes; - char *szDescription; - int currentFile; - - // New p2p - BOOL newP2P; - char *id2; - SOCKET udps; - aes_context aes_context; - unsigned char aes_iv[16]; - TlenProtocol *proto; - -} TLEN_FILE_TRANSFER; - -typedef struct { - PROTOSEARCHRESULT hdr; - char jid[256]; -} JABBER_SEARCH_RESULT; - -typedef struct { - char *iqId; - PROTOSEARCHRESULT hdr; - char jid[256]; -} TLEN_CONFERENCE; - - -typedef struct { - int id; - TCHAR *name; -} JABBER_FIELD_MAP; - - -/******************************************************************* - * Global variables - *******************************************************************/ -extern HINSTANCE hInst; -extern HANDLE hMainThread; - -/******************************************************************* - * Function declarations - *******************************************************************/ -HICON GetIcolibIcon(int iconId); -void ReleaseIcolibIcon(HICON hIcon); - -void JabberLog(TlenProtocol *proto, const char *fmt, ...); -void __cdecl JabberServerThread(ThreadData *info); -// jabber_ws.c -BOOL JabberWsInit(TlenProtocol *proto); -void JabberWsUninit(TlenProtocol *proto); -JABBER_SOCKET JabberWsConnect(TlenProtocol *proto, char *host, WORD port); -int JabberWsSend(TlenProtocol *proto, JABBER_SOCKET s, char *data, int datalen); -int JabberWsRecv(TlenProtocol *proto, JABBER_SOCKET s, char *data, long datalen); -int JabberWsSendAES(TlenProtocol *proto, char *data, int datalen, aes_context *aes_ctx, unsigned char *aes_iv); -int JabberWsRecvAES(TlenProtocol *proto, char *data, long datalen, aes_context *aes_ctx, unsigned char *aes_iv); -// jabber_util.c -HANDLE HookEventObj_Ex(const char *name, TlenProtocol *proto, MIRANDAHOOKOBJ hook); -HANDLE CreateServiceFunction_Ex(const char *name, TlenProtocol *proto, MIRANDASERVICEOBJ service); -void UnhookEvents_Ex(TlenProtocol *proto); -void DestroyServices_Ex(TlenProtocol *proto); -void JabberSerialInit(TlenProtocol *proto); -void JabberSerialUninit(TlenProtocol *proto); -unsigned int JabberSerialNext(TlenProtocol *proto); -int JabberSend(TlenProtocol *proto, const char *fmt, ...); -HANDLE JabberHContactFromJID(TlenProtocol *proto, const char *jid); -char *JabberJIDFromHContact(TlenProtocol *proto, HANDLE hContact); -char *JabberLoginFromJID(const char *jid); -char *JabberResourceFromJID(const char *jid); -char *JabberNickFromJID(const char *jid); -char *JabberLocalNickFromJID(const char *jid); -char *TlenGroupEncode(const char *str); -char *TlenGroupDecode(const char *str); -char *JabberSha1(char *str); -char *TlenSha1(char *str, int len); -char *TlenPasswordHash(const char *str); -void TlenUrlDecode(char *str); -char *TlenUrlEncode(const char *str); -char *JabberTextEncode(const char *str); -char *JabberTextDecode(const char *str); -char *JabberBase64Encode(const char *buffer, int bufferLen); -char *JabberBase64Decode(const char *buffer, int *resultLen); -int JabberGetPictureType(const char* buf); -void TlenLogMessage(TlenProtocol *proto, HANDLE hContact, DWORD flags, const char *message); -BOOL IsAuthorized(TlenProtocol *proto, const char *jid); -//char *JabberGetVersionText(); -time_t JabberIsoToUnixTime(char *stamp); -time_t TlenTimeToUTC(time_t time); -void JabberSendPresence(TlenProtocol *proto,int status); -void JabberStringAppend(char **str, int *sizeAlloced, const char *fmt, ...); -//char *JabberGetClientJID(char *jid); -// jabber_misc.c -void JabberDBAddEvent(TlenProtocol *proto, HANDLE hContact, int eventType, DWORD flags, PBYTE pBlob, DWORD cbBlob); -void JabberDBAddAuthRequest(TlenProtocol *proto, char *jid, char *nick); -HANDLE JabberDBCreateContact(TlenProtocol *proto, char *jid, char *nick, BOOL temporary); -void JabberContactListCreateGroup(char *groupName); -unsigned long JabberForkThread(void (__cdecl *threadcode)(void*), unsigned long stacksize, void *arg); -// jabber_svc.c -int JabberGetInfo(PROTO_INTERFACE *ptr, HANDLE hContact, int infoType); -int TlenRunSearch(TlenProtocol *proto); -// jabber_advsearch.c -extern JABBER_FIELD_MAP tlenFieldGender[]; -extern JABBER_FIELD_MAP tlenFieldLookfor[]; -extern JABBER_FIELD_MAP tlenFieldStatus[]; -extern JABBER_FIELD_MAP tlenFieldOccupation[]; -extern JABBER_FIELD_MAP tlenFieldPlan[]; - -INT_PTR CALLBACK TlenAdvSearchDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -char *TlenAdvSearchCreateQuery(HWND hwndDlg, int iqId); - - -#endif - diff --git a/!NotAdopted/Tlen/jabber_iq.c b/!NotAdopted/Tlen/jabber_iq.c deleted file mode 100644 index 219f60e53d..0000000000 --- a/!NotAdopted/Tlen/jabber_iq.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include "jabber_iq.h" - - -void JabberIqInit(TlenProtocol *proto) -{ - InitializeCriticalSection(&proto->csIqList); - proto->iqList = NULL; - proto->iqCount = 0; - proto->iqAlloced = 0; -} - -void JabberIqUninit(TlenProtocol *proto) -{ - if (proto->iqList) mir_free(proto->iqList); - proto->iqList = NULL; - proto->iqCount = 0; - proto->iqAlloced = 0; - DeleteCriticalSection(&proto->csIqList); -} - -static void JabberIqRemove(TlenProtocol *proto, int index) -{ - EnterCriticalSection(&proto->csIqList); - if (index>=0 && indexiqCount) { - memmove(proto->iqList+index, proto->iqList+index+1, sizeof(JABBER_IQ_FUNC)*(proto->iqCount-index-1)); - proto->iqCount--; - } - LeaveCriticalSection(&proto->csIqList); -} - -static void JabberIqExpire(TlenProtocol *proto) -{ - int i; - time_t expire; - - EnterCriticalSection(&proto->csIqList); - expire = time(NULL) - 120; // 2 minute - i = 0; - while (i < proto->iqCount) { - if (proto->iqList[i].requestTime < expire) - JabberIqRemove(proto, i); - else - i++; - } - LeaveCriticalSection(&proto->csIqList); -} - -JABBER_IQ_PFUNC JabberIqFetchFunc(TlenProtocol *proto, int iqId) -{ - int i; - JABBER_IQ_PFUNC res; - - EnterCriticalSection(&proto->csIqList); - JabberIqExpire(proto); - for (i=0; iiqCount && proto->iqList[i].iqId!=iqId; i++); - if (i < proto->iqCount) { - res = proto->iqList[i].func; - JabberIqRemove(proto, i); - } - else { - res = (JABBER_IQ_PFUNC) NULL; - } - LeaveCriticalSection(&proto->csIqList); - return res; -} - -void JabberIqAdd(TlenProtocol *proto, unsigned int iqId, JABBER_IQ_PROCID procId, JABBER_IQ_PFUNC func) -{ - int i; - - EnterCriticalSection(&proto->csIqList); - if (procId == IQ_PROC_NONE) - i = proto->iqCount; - else - for (i=0; iiqCount && proto->iqList[i].procId!=procId; i++); - - if (i>=proto->iqCount && proto->iqCount>=proto->iqAlloced) { - proto->iqAlloced = proto->iqCount + 8; - proto->iqList = mir_realloc(proto->iqList, sizeof(JABBER_IQ_FUNC)*proto->iqAlloced); - } - - if (proto->iqList != NULL) { - proto->iqList[i].iqId = iqId; - proto->iqList[i].procId = procId; - proto->iqList[i].func = func; - proto->iqList[i].requestTime = time(NULL); - if (i == proto->iqCount) proto->iqCount++; - } - LeaveCriticalSection(&proto->csIqList); -} - diff --git a/!NotAdopted/Tlen/jabber_iq.h b/!NotAdopted/Tlen/jabber_iq.h deleted file mode 100644 index dfdcf9e91a..0000000000 --- a/!NotAdopted/Tlen/jabber_iq.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#ifndef _JABBER_IQ_H_ -#define _JABBER_IQ_H_ - -#include "jabber_xml.h" -#include "jabber.h" - -typedef void (*JABBER_IQ_PFUNC)(TlenProtocol *proto, XmlNode *iqNode); - -typedef struct JABBER_IQ_FUNC_STRUCT { - int iqId; // id to match IQ get/set with IQ result - JABBER_IQ_PROCID procId; // must be unique in the list, except for IQ_PROC_NONE which can have multiple entries - JABBER_IQ_PFUNC func; // callback function - time_t requestTime; // time the request was sent, used to remove relinquent entries -} JABBER_IQ_FUNC; - -void JabberIqInit(TlenProtocol *proto); -void JabberIqUninit(TlenProtocol *proto); -JABBER_IQ_PFUNC JabberIqFetchFunc(TlenProtocol *proto, int iqId); -void JabberIqAdd(TlenProtocol *proto, unsigned int iqId, JABBER_IQ_PROCID procId, JABBER_IQ_PFUNC func); - -void JabberIqResultAuth(TlenProtocol *proto, XmlNode *iqNode); -void JabberIqResultRoster(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultVcard(TlenProtocol *proto, XmlNode *iqNode); -void JabberIqResultSearch(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultVersion(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultInfo(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultTcfg(TlenProtocol *proto, XmlNode *iqNode); - -void TlenIqResultChatGroups(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultChatRooms(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultUserRooms(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultUserNicks(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultRoomSearch(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultRoomInfo(TlenProtocol *proto, XmlNode *iqNode); -void TlenIqResultChatRoomUsers(TlenProtocol *proto, XmlNode *iqNode); -//void JabberIqResultSetPassword(XmlNode *iqNode, void *userdata); - -#endif - diff --git a/!NotAdopted/Tlen/jabber_iqid.c b/!NotAdopted/Tlen/jabber_iqid.c deleted file mode 100644 index 2c16054038..0000000000 --- a/!NotAdopted/Tlen/jabber_iqid.c +++ /dev/null @@ -1,629 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include "resource.h" -#include "jabber_list.h" -#include "jabber_iq.h" -#include "tlen_muc.h" - -void JabberIqResultAuth(TlenProtocol *proto, XmlNode *iqNode) -{ - char *type; - - // RECVED: authentication result - // ACTION: if successfully logged in, continue by requesting roster list and set my initial status - if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; - - if (!strcmp(type, "result")) { - DBVARIANT dbv; - - if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "Nick", &dbv)) - DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "Nick", proto->threadData->username); - else - DBFreeVariant(&dbv); -// iqId = JabberSerialNext(); -// JabberIqAdd(iqId, IQ_PROC_NONE, JabberIqResultGetRoster); -// JabberSend(info, "", iqId); - - JabberSend(proto, ""); - JabberSend(proto, ""); - } - // What to do if password error? etc... - else if (!strcmp(type, "error")) { - char text[128]; - - JabberSend(proto, ""); - _snprintf(text, sizeof(text), "%s %s@%s.", TranslateT("Authentication failed for"), proto->threadData->username, proto->threadData->server); - MessageBoxA(NULL, text, Translate("Tlen Authentication"), MB_OK|MB_ICONSTOP|MB_SETFOREGROUND); - ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGINERR_WRONGPASSWORD); - proto->threadData = NULL; // To disallow auto reconnect - } -} - -void JabberResultSetRoster(TlenProtocol *proto, XmlNode *queryNode) { - DBVARIANT dbv; - XmlNode *itemNode, *groupNode; - JABBER_LIST_ITEM *item; - HANDLE hContact; - char *jid, *name, *nick; - int i; - char *str; - - for (i=0; inumChild; i++) { - itemNode = queryNode->child[i]; - if (!strcmp(itemNode->name, "item")) { - if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { - str = JabberXmlGetAttrValue(itemNode, "subscription"); - if (!strcmp(str, "remove")) { - if ((hContact=JabberHContactFromJID(proto, jid)) != NULL) { - if (DBGetContactSettingWord(hContact, proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) - DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE); - } - JabberListRemove(proto, LIST_ROSTER, jid); - } else { - item = JabberListAdd(proto, LIST_ROSTER, jid); - if (item != NULL) { - if (str == NULL) item->subscription = SUB_NONE; - else if (!strcmp(str, "both")) item->subscription = SUB_BOTH; - else if (!strcmp(str, "to")) item->subscription = SUB_TO; - else if (!strcmp(str, "from")) item->subscription = SUB_FROM; - else item->subscription = SUB_NONE; - if ((name=JabberXmlGetAttrValue(itemNode, "name")) != NULL) { - nick = JabberTextDecode(name); - } else { - nick = JabberLocalNickFromJID(jid); - } - if (nick != NULL) { - if (item->nick) mir_free(item->nick); - item->nick = nick; - - if ((hContact=JabberHContactFromJID(proto, jid)) == NULL) { - // Received roster has a new JID. - // Add the jid (with empty resource) to Miranda contact list. - hContact = JabberDBCreateContact(proto, jid, nick, FALSE); - } - DBWriteContactSettingString(hContact, "CList", "MyHandle", nick); - if (item->group) mir_free(item->group); - if ((groupNode=JabberXmlGetChild(itemNode, "group"))!=NULL && groupNode->text!=NULL) { - item->group = TlenGroupDecode(groupNode->text); - JabberContactListCreateGroup(item->group); - // Don't set group again if already correct, or Miranda may show wrong group count in some case - if (!DBGetContactSetting(hContact, "CList", "Group", &dbv)) { - if (strcmp(dbv.pszVal, item->group)) - DBWriteContactSettingString(hContact, "CList", "Group", item->group); - DBFreeVariant(&dbv); - } else - DBWriteContactSettingString(hContact, "CList", "Group", item->group); - } else { - item->group = NULL; - DBDeleteContactSetting(hContact, "CList", "Group"); - } - } - } - } - } - } - } -} - -void JabberIqResultRoster(TlenProtocol *proto, XmlNode *iqNode) -{ - XmlNode *queryNode; - char *type; - char *str; - - // RECVED: roster information - // ACTION: populate LIST_ROSTER and create contact for any new rosters - if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; - if ((queryNode=JabberXmlGetChild(iqNode, "query")) == NULL) return; - - if (!strcmp(type, "result")) { - str = JabberXmlGetAttrValue(queryNode, "xmlns"); - if (str!=NULL && !strcmp(str, "jabber:iq:roster")) { - DBVARIANT dbv; - XmlNode *itemNode, *groupNode; - JABBER_SUBSCRIPTION sub; - JABBER_LIST_ITEM *item; - HANDLE hContact; - char *jid, *name, *nick; - int i, oldStatus; - - for (i=0; inumChild; i++) { - itemNode = queryNode->child[i]; - if (!strcmp(itemNode->name, "item")) { - str = JabberXmlGetAttrValue(itemNode, "subscription"); - if (str==NULL) sub = SUB_NONE; - else if (!strcmp(str, "both")) sub = SUB_BOTH; - else if (!strcmp(str, "to")) sub = SUB_TO; - else if (!strcmp(str, "from")) sub = SUB_FROM; - else sub = SUB_NONE; - //if (str!=NULL && (!strcmp(str, "to") || !strcmp(str, "both"))) { - if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { - if ((name=JabberXmlGetAttrValue(itemNode, "name")) != NULL) { - nick = JabberTextDecode(name); - } else { - nick = JabberLocalNickFromJID(jid); - } - if (nick != NULL) { - item = JabberListAdd(proto, LIST_ROSTER, jid); - if (item->nick) mir_free(item->nick); - item->nick = nick; - item->subscription = sub; - if ((hContact=JabberHContactFromJID(proto, jid)) == NULL) { - // Received roster has a new JID. - // Add the jid (with empty resource) to Miranda contact list. - hContact = JabberDBCreateContact(proto, jid, nick, FALSE); - } - DBWriteContactSettingString(hContact, "CList", "MyHandle", nick); - if (item->group) mir_free(item->group); - if ((groupNode=JabberXmlGetChild(itemNode, "group"))!=NULL && groupNode->text!=NULL) { - item->group = TlenGroupDecode(groupNode->text); - JabberContactListCreateGroup(item->group); - // Don't set group again if already correct, or Miranda may show wrong group count in some case - if (!DBGetContactSetting(hContact, "CList", "Group", &dbv)) { - if (strcmp(dbv.pszVal, item->group)) - DBWriteContactSettingString(hContact, "CList", "Group", item->group); - DBFreeVariant(&dbv); - } - else - DBWriteContactSettingString(hContact, "CList", "Group", item->group); - } - else { - item->group = NULL; - DBDeleteContactSetting(hContact, "CList", "Group"); - } - if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "AvatarHash", &dbv)) { - if (item->avatarHash) mir_free(item->avatarHash); - item->avatarHash = mir_strdup(dbv.pszVal); - JabberLog(proto, "Setting hash [%s] = %s", nick, item->avatarHash); - DBFreeVariant(&dbv); - } - item->avatarFormat = DBGetContactSettingDword(hContact, proto->iface.m_szModuleName, "AvatarFormat", PA_FORMAT_UNKNOWN); - } - } - } - } - // Delete orphaned contacts (if roster sync is enabled) - if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "RosterSync", FALSE) == TRUE) { - HANDLE *list; - int listSize, listAllocSize; - - listSize = listAllocSize = 0; - list = NULL; - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - while (hContact != NULL) { - str = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); - if(str!=NULL && !strcmp(str, proto->iface.m_szModuleName)) { - if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { - if (!JabberListExist(proto, LIST_ROSTER, dbv.pszVal)) { - JabberLog(proto, "Syncing roster: preparing to delete %s (hContact=0x%x)", dbv.pszVal, hContact); - if (listSize >= listAllocSize) { - listAllocSize = listSize + 100; - if ((list=(HANDLE *) mir_realloc(list, listAllocSize)) == NULL) { - listSize = 0; - break; - } - } - list[listSize++] = hContact; - } - DBFreeVariant(&dbv); - } - } - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); - } - for (i=0; ihMenuMUC, (LPARAM) &clmi); - if (proto->hMenuChats != NULL){ - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuChats, (LPARAM) &clmi); - } - } - - proto->isOnline = TRUE; - JabberLog(proto, "Status changed via THREADSTART"); - oldStatus = proto->iface.m_iStatus; - JabberSendPresence(proto, proto->iface.m_iDesiredStatus); - ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, proto->iface.m_iStatus); - ////////////////////////////////// - } - } -} - - -// Tlen actually use jabber:iq:search for other users vCard or jabber:iq:register for own vCard -void TlenIqResultVcard(TlenProtocol *proto, XmlNode *iqNode) -{ - XmlNode *queryNode, *itemNode, *n; - char *type, *jid; - char text[128]; - HANDLE hContact; - char *nText; - -// JabberLog(" iqIdGetVcard (tlen)"); - if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; - - if (!strcmp(type, "result")) { - BOOL hasFirst, hasLast, hasNick, hasEmail, hasCity, hasAge, hasGender, hasSchool, hasLookFor, hasOccupation; - DBVARIANT dbv; - int i; - - if ((queryNode=JabberXmlGetChild(iqNode, "query")) == NULL) return; - if ((itemNode=JabberXmlGetChild(queryNode, "item")) == NULL) return; - if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { - if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) return; - if (strchr(jid, '@') != NULL) { - sprintf(text, "%s", jid); - } else { - sprintf(text, "%s@%s", jid, dbv.pszVal); // Add @tlen.pl - } - DBFreeVariant(&dbv); - if ((hContact=JabberHContactFromJID(proto, text)) == NULL) { - if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginName", &dbv)) return; - if (strcmp(dbv.pszVal, jid)) { - DBFreeVariant(&dbv); - return; - } - DBFreeVariant(&dbv); - } - } else { - hContact = NULL; - } - hasFirst = hasLast = hasNick = hasEmail = hasCity = hasAge = hasGender = hasOccupation = hasLookFor = hasSchool = FALSE; - for (i=0; inumChild; i++) { - n = itemNode->child[i]; - if (n==NULL || n->name==NULL) continue; - if (!strcmp(n->name, "first")) { - if (n->text != NULL) { - hasFirst = TRUE; - nText = JabberTextDecode(n->text); - DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "FirstName", nText); - mir_free(nText); - } - } - else if (!strcmp(n->name, "last")) { - if (n->text != NULL) { - hasLast = TRUE; - nText = JabberTextDecode(n->text); - DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "LastName", nText); - mir_free(nText); - } - } - else if (!strcmp(n->name, "nick")) { - if (n->text != NULL) { - hasNick = TRUE; - nText = JabberTextDecode(n->text); - DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "Nick", nText); - mir_free(nText); - } - } - else if (!strcmp(n->name, "email")) { - if (n->text != NULL) { - hasEmail = TRUE; - nText = JabberTextDecode(n->text); - DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "e-mail", nText); - mir_free(nText); - } - } - else if (!strcmp(n->name, "c")) { - if (n->text != NULL) { - hasCity = TRUE; - nText = JabberTextDecode(n->text); - DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "City", nText); - mir_free(nText); - } - } - else if (!strcmp(n->name, "b")) { - if (n->text != NULL) { - WORD nAge; - hasAge = TRUE; - nAge = atoi(n->text); - DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "Age", nAge); - } - } - else if (!strcmp(n->name, "s")) { - if (n->text!=NULL && n->text[1]=='\0' && (n->text[0]=='1' || n->text[0]=='2')) { - hasGender = TRUE; - DBWriteContactSettingByte(hContact, proto->iface.m_szModuleName, "Gender", (BYTE) (n->text[0]=='1'?'M':'F')); - } - } - else if (!strcmp(n->name, "e")) { - if (n->text != NULL) { - hasSchool = TRUE; - nText = JabberTextDecode(n->text); - DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "School", nText); - mir_free(nText); - } - } - else if (!strcmp(n->name, "j")) { - if (n->text != NULL) { - WORD nOccupation; - hasOccupation = TRUE; - nOccupation = atoi(n->text); - DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "Occupation", nOccupation); - } - } - else if (!strcmp(n->name, "r")) { - if (n->text != NULL) { - WORD nLookFor; - hasLookFor = TRUE; - nLookFor = atoi(n->text); - DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "LookingFor", nLookFor); - } - } - else if (!strcmp(n->name, "g")) { // voice chat enabled - if (n->text != NULL) { - BYTE bVoice; - bVoice = atoi(n->text); - DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "VoiceChat", bVoice); - } - } - else if (!strcmp(n->name, "v")) { // status visibility - if (n->text != NULL) { - BYTE bPublic; - bPublic = atoi(n->text); - DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "PublicStatus", bPublic); - } - } - } - if (!hasFirst) - DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "FirstName"); - if (!hasLast) - DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "LastName"); - // We are not removing "Nick" -// if (!hasNick) -// DBDeleteContactSetting(hContact, iface.m_szModuleName, "Nick"); - if (!hasEmail) - DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "e-mail"); - if (!hasCity) - DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "City"); - if (!hasAge) - DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "Age"); - if (!hasGender) - DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "Gender"); - if (!hasSchool) - DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "School"); - if (!hasOccupation) - DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "Occupation"); - if (!hasLookFor) - DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "LookingFor"); - ProtoBroadcastAck(proto->iface.m_szModuleName, hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE) 1, 0); - } -} - -void JabberIqResultSearch(TlenProtocol *proto, XmlNode *iqNode) -{ - XmlNode *queryNode, *itemNode, *n; - char *type, *jid, *str; - int id, i, found; - JABBER_SEARCH_RESULT jsr = {0}; - DBVARIANT dbv = {0}; - - found = 0; -// JabberLog(" iqIdGetSearch"); - if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; - if ((str=JabberXmlGetAttrValue(iqNode, "id")) == NULL) return; - id = atoi(str+strlen(JABBER_IQID)); - - if (!strcmp(type, "result")) { - if ((queryNode=JabberXmlGetChild(iqNode, "query")) == NULL) return; - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { - jsr.hdr.cbSize = sizeof(JABBER_SEARCH_RESULT); - for (i=0; inumChild; i++) { - itemNode = queryNode->child[i]; - if (!strcmp(itemNode->name, "item")) { - if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { - if (strchr(jid, '@') != NULL) { - _snprintf(jsr.jid, sizeof(jsr.jid), "%s", jid); - } else { - _snprintf(jsr.jid, sizeof(jsr.jid), "%s@%s", jid, dbv.pszVal); - } - jsr.jid[sizeof(jsr.jid)-1] = '\0'; - jsr.hdr.id = jid; - jsr.hdr.flags = 0; //results are ansi - if ((n=JabberXmlGetChild(itemNode, "nick"))!=NULL && n->text!=NULL) - jsr.hdr.nick = JabberTextDecode(n->text); - else - jsr.hdr.nick = mir_strdup(""); - if ((n=JabberXmlGetChild(itemNode, "first"))!=NULL && n->text!=NULL) - jsr.hdr.firstName = JabberTextDecode(n->text); - else - jsr.hdr.firstName = mir_strdup(""); - if ((n=JabberXmlGetChild(itemNode, "last"))!=NULL && n->text!=NULL) - jsr.hdr.lastName = JabberTextDecode(n->text); - else - jsr.hdr.lastName = mir_strdup(""); - if ((n=JabberXmlGetChild(itemNode, "email"))!=NULL && n->text!=NULL) - jsr.hdr.email = JabberTextDecode(n->text); - else - jsr.hdr.email = mir_strdup(""); - - ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE) id, (LPARAM) &jsr); - found = 1; - mir_free(jsr.hdr.nick); - mir_free(jsr.hdr.firstName); - mir_free(jsr.hdr.lastName); - mir_free(jsr.hdr.email); - } - } - } - if (proto->searchJID!=NULL) { - if (!found) { - if (strchr(proto->searchJID, '@') != NULL) { - _snprintf(jsr.jid, sizeof(jsr.jid), "%s", proto->searchJID); - } else { - _snprintf(jsr.jid, sizeof(jsr.jid), "%s@%s", proto->searchJID, dbv.pszVal); - } - jsr.jid[sizeof(jsr.jid)-1] = '\0'; - jsr.hdr.nick = mir_strdup(""); - jsr.hdr.firstName = mir_strdup(""); - jsr.hdr.lastName = mir_strdup(""); - jsr.hdr.email = mir_strdup(""); - jsr.hdr.id = mir_strdup(""); - ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE) id, (LPARAM) &jsr); - mir_free(jsr.hdr.nick); - mir_free(jsr.hdr.firstName); - mir_free(jsr.hdr.lastName); - mir_free(jsr.hdr.email); - } - mir_free(proto->searchJID); - proto->searchJID = NULL; - } - DBFreeVariant(&dbv); - } - found = 0; - if (queryNode->numChild == TLEN_MAX_SEARCH_RESULTS_PER_PAGE) { - found = TlenRunSearch(proto); - } - if (!found) { - ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE) id, 0); - } - } else if (!strcmp(type, "error")) { - // ProtoBroadcastAck(iface.m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HANDLE) id, 0); - // There is no ACKRESULT_FAILED for ACKTYPE_SEARCH :) look at findadd.c - // So we will just send a SUCCESS - ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE) id, 0); - } -} - - -void GetConfigItem(XmlNode *node, char *dest, BOOL bMethod, int *methodDest) { - strcpy(dest, node->text); - TlenUrlDecode(dest); - if (bMethod) { - char *method = JabberXmlGetAttrValue(node, "method"); - if (method != NULL && !strcmpi(method, "POST")) { - *methodDest = REQUEST_POST; - } else { - *methodDest = REQUEST_GET; - } - } -} - -void TlenIqResultTcfg(TlenProtocol *proto, XmlNode *iqNode) -{ - XmlNode *queryNode, *miniMailNode, *node; - char *type; - - if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; - if (!strcmp(type, "result")) { - if ((queryNode=JabberXmlGetChild(iqNode, "query")) == NULL) return; - if ((miniMailNode=JabberXmlGetChild(queryNode, "mini-mail")) == NULL) return; - if ((node=JabberXmlGetChild(miniMailNode, "base")) != NULL) { - GetConfigItem(node, proto->threadData->tlenConfig.mailBase, FALSE, NULL); - } - if ((node=JabberXmlGetChild(miniMailNode, "msg")) != NULL) { - GetConfigItem(node, proto->threadData->tlenConfig.mailMsg, TRUE, &proto->threadData->tlenConfig.mailMsgMthd); - } - if ((node=JabberXmlGetChild(miniMailNode, "index")) != NULL) { - GetConfigItem(node, proto->threadData->tlenConfig.mailIndex, TRUE, &proto->threadData->tlenConfig.mailIndexMthd); - } - if ((node=JabberXmlGetChild(miniMailNode, "login")) != NULL) { - GetConfigItem(node, proto->threadData->tlenConfig.mailLogin, TRUE, &proto->threadData->tlenConfig.mailLoginMthd); - } - if ((node=JabberXmlGetChild(miniMailNode, "compose")) != NULL) { - GetConfigItem(node, proto->threadData->tlenConfig.mailCompose, TRUE, &proto->threadData->tlenConfig.mailComposeMthd); - } - if ((node=JabberXmlGetChild(miniMailNode, "avatar-get")) != NULL) { - GetConfigItem(node, proto->threadData->tlenConfig.avatarGet, TRUE, &proto->threadData->tlenConfig.avatarGetMthd); - } - if ((node=JabberXmlGetChild(miniMailNode, "avatar-upload")) != NULL) { - GetConfigItem(node, proto->threadData->tlenConfig.avatarUpload, TRUE, &proto->threadData->tlenConfig.avatarUploadMthd); - } - if ((node=JabberXmlGetChild(miniMailNode, "avatar-remove")) != NULL) { - GetConfigItem(node, proto->threadData->tlenConfig.avatarRemove, TRUE, &proto->threadData->tlenConfig.avatarRemoveMthd); - } - } -} - -void TlenIqResultVersion(TlenProtocol *proto, XmlNode *iqNode) -{ - XmlNode *queryNode = JabberXmlGetChild(iqNode, "query"); - if (queryNode != NULL) { - char* from; - if (( from=JabberXmlGetAttrValue( iqNode, "from" )) != NULL ) { - JABBER_LIST_ITEM *item; - if (( item=JabberListGetItemPtr( proto, LIST_ROSTER, from ))!=NULL) { - HANDLE hContact; - XmlNode *n; - if ( item->software ) mir_free( item->software ); - if ( item->version ) mir_free( item->version ); - if ( item->system ) mir_free( item->system ); - if (( n=JabberXmlGetChild( queryNode, "name" ))!=NULL && n->text ) { - item->software = JabberTextDecode( n->text ); - } else - item->software = NULL; - if (( n=JabberXmlGetChild( queryNode, "version" ))!=NULL && n->text ) - item->version = JabberTextDecode( n->text ); - else - item->version = NULL; - if (( n=JabberXmlGetChild( queryNode, "os" ))!=NULL && n->text ) - item->system = JabberTextDecode( n->text ); - else - item->system = NULL; - if (( hContact=JabberHContactFromJID(proto, item->jid )) != NULL ) { - if (item->software != NULL) { - DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "MirVer", item->software); - } else { - DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "MirVer"); - } - } - } - } - } -} - -void TlenIqResultInfo(TlenProtocol *proto, XmlNode *iqNode) -{ - XmlNode *queryNode = JabberXmlGetChild(iqNode, "query"); - if (queryNode != NULL) { - char* from; - if (( from=JabberXmlGetAttrValue( queryNode, "from" )) != NULL ) { - JABBER_LIST_ITEM *item; - if (( item=JabberListGetItemPtr( proto, LIST_ROSTER, from ))!=NULL) { - HANDLE hContact; - XmlNode *version = JabberXmlGetChild(queryNode, "version"); - item->protocolVersion = JabberTextDecode(version->text); - if (( hContact=JabberHContactFromJID(proto, item->jid )) != NULL ) { - if (item->software == NULL) { - char str[128]; - mir_snprintf(str, sizeof(str), "Tlen Protocol %s", item->protocolVersion); - DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "MirVer", str); - } - } - } - } - } -} - diff --git a/!NotAdopted/Tlen/jabber_list.c b/!NotAdopted/Tlen/jabber_list.c deleted file mode 100644 index 8b916b6584..0000000000 --- a/!NotAdopted/Tlen/jabber_list.c +++ /dev/null @@ -1,314 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include "jabber_list.h" - - -static void JabberListFreeItemInternal(JABBER_LIST_ITEM *item); - -void JabberListInit(TlenProtocol *proto) -{ - proto->lists = NULL; - proto->listsCount = 0; - InitializeCriticalSection(&proto->csLists); -} - -void JabberListUninit(TlenProtocol *proto) -{ - JabberListWipe(proto); - DeleteCriticalSection(&proto->csLists); -} - -void JabberListWipe(TlenProtocol *proto) -{ - int i; - - EnterCriticalSection(&proto->csLists); - for(i=0; ilistsCount; i++) - JabberListFreeItemInternal(&(proto->lists[i])); - if (proto->lists != NULL) { - mir_free(proto->lists); - proto->lists = NULL; - } - proto->listsCount=0; - LeaveCriticalSection(&proto->csLists); -} - -void JabberListWipeSpecial(TlenProtocol *proto) -{ - int i; - EnterCriticalSection(&proto->csLists); - for(i=0; ilistsCount; i++) { - if (proto->lists[i].list != LIST_FILE && proto->lists[i].list != LIST_VOICE) { - JabberListFreeItemInternal(&(proto->lists[i])); - proto->listsCount--; - memmove(proto->lists+i, proto->lists+i+1, sizeof(JABBER_LIST_ITEM)*(proto->listsCount-i)); - i--; - } - } - proto->lists = (JABBER_LIST_ITEM *) mir_realloc(proto->lists, sizeof(JABBER_LIST_ITEM)*proto->listsCount); - LeaveCriticalSection(&proto->csLists); -} - -static void JabberListFreeItemInternal(JABBER_LIST_ITEM *item) -{ - if (item == NULL) - return; - - if (item->jid) mir_free(item->jid); - if (item->nick) mir_free(item->nick); - if (item->statusMessage) mir_free(item->statusMessage); - if (item->group) mir_free(item->group); - if (item->messageEventIdStr) mir_free(item->messageEventIdStr); -// if (item->type) mir_free(item->type); - //if (item->ft) JabberFileFreeFt(item->ft); // No need to free (it is always free when exit from JabberFileServerThread()) - if (item->roomName) mir_free(item->roomName); - if (item->version) mir_free(item->version); - if (item->software) mir_free(item->software); - if (item->system) mir_free(item->system); - if (item->avatarHash) mir_free(item->avatarHash); - - if (item->protocolVersion) mir_free(item->protocolVersion); - if (item->id2) mir_free(item->id2); -} - -static char * GetItemId(JABBER_LIST list, const char *jid) -{ - char *s, *p, *q; - s = mir_strdup(jid); - if (list != LIST_PICTURE) { - _strlwr(s); - // strip resouce name if any - if ((p=strchr(s, '@')) != NULL) { - if ((q=strchr(p, '/')) != NULL) - *q = '\0'; - } - } - return s; -} - -int JabberListExist(TlenProtocol *proto, JABBER_LIST list, const char *jid) -{ - int i; - size_t len; - char *s, *p; - s = GetItemId(list, jid); - len = strlen(s); - - EnterCriticalSection(&proto->csLists); - for(i=0; ilistsCount; i++) - if (proto->lists[i].list==list) { - p = proto->lists[i].jid; - if (p && strlen(p)>=len && (p[(int)len]=='\0'||p[(int)len]=='/') && !strncmp(p, s, len)) { - LeaveCriticalSection(&proto->csLists); - mir_free(s); - return i+1; - } - } - LeaveCriticalSection(&proto->csLists); - mir_free(s); - return 0; -} - -JABBER_LIST_ITEM *JabberListAdd(TlenProtocol *proto, JABBER_LIST list, const char *jid) -{ - char *s; - JABBER_LIST_ITEM *item; - - EnterCriticalSection(&proto->csLists); - if ((item=JabberListGetItemPtr(proto, list, jid)) != NULL) { - LeaveCriticalSection(&proto->csLists); - return item; - } - - s = GetItemId(list, jid); - proto->lists = (JABBER_LIST_ITEM *) mir_realloc(proto->lists, sizeof(JABBER_LIST_ITEM)*(proto->listsCount+1)); - item = &(proto->lists[proto->listsCount]); - memset(item, 0, sizeof(JABBER_LIST_ITEM)); - item->list = list; - item->jid = s; - item->nick = NULL; - item->status = ID_STATUS_OFFLINE; - item->statusMessage = NULL; - item->group = NULL; - item->messageEventIdStr = NULL; - item->wantComposingEvent = FALSE; - item->isTyping = FALSE; -// item->type = NULL; - item->ft = NULL; - item->roomName = NULL; - item->version = NULL; - item->software = NULL; - item->system = NULL; - item->avatarHash = NULL; - item->avatarFormat = PA_FORMAT_UNKNOWN; - item->newAvatarDownloading = FALSE; - item->versionRequested = FALSE; - item->infoRequested = FALSE; - proto->listsCount++; - LeaveCriticalSection(&proto->csLists); - - return item; -} - -void JabberListRemove(TlenProtocol *proto, JABBER_LIST list, const char *jid) -{ - int i; - - EnterCriticalSection(&proto->csLists); - i = JabberListExist(proto, list, jid); - if (!i) { - LeaveCriticalSection(&proto->csLists); - return; - } - i--; - JabberListFreeItemInternal(&(proto->lists[i])); - proto->listsCount--; - memmove(proto->lists+i, proto->lists+i+1, sizeof(JABBER_LIST_ITEM)*(proto->listsCount-i)); - proto->lists = (JABBER_LIST_ITEM *) mir_realloc(proto->lists, sizeof(JABBER_LIST_ITEM)*proto->listsCount); - LeaveCriticalSection(&proto->csLists); -} - -void JabberListRemoveList(TlenProtocol *proto, JABBER_LIST list) -{ - int i; - - i = 0; - while ((i=JabberListFindNext(proto, list, i)) >= 0) { - JabberListRemoveByIndex(proto, i); - } -} - -void JabberListRemoveByIndex(TlenProtocol *proto, int index) -{ - EnterCriticalSection(&proto->csLists); - if (index>=0 && indexlistsCount) { - JabberListFreeItemInternal(&(proto->lists[index])); - proto->listsCount--; - memmove(proto->lists+index, proto->lists+index+1, sizeof(JABBER_LIST_ITEM)*(proto->listsCount-index)); - proto->lists = (JABBER_LIST_ITEM *) mir_realloc(proto->lists, sizeof(JABBER_LIST_ITEM)*proto->listsCount); - } - LeaveCriticalSection(&proto->csLists); -} - -void JabberListAddResource(TlenProtocol *proto, JABBER_LIST list, const char *jid, int status, const char *statusMessage) -{ - int i; - - EnterCriticalSection(&proto->csLists); - i = JabberListExist(proto, list, jid); - if (!i) { - LeaveCriticalSection(&proto->csLists); - return; - } - i--; - - if (proto->lists[i].statusMessage != NULL) - mir_free(proto->lists[i].statusMessage); - if (statusMessage) - proto->lists[i].statusMessage = mir_strdup(statusMessage); - else - proto->lists[i].statusMessage = NULL; - LeaveCriticalSection(&proto->csLists); -} - -void JabberListRemoveResource(TlenProtocol *proto, JABBER_LIST list, const char *jid) -{ - int i; - EnterCriticalSection(&proto->csLists); - i = JabberListExist(proto, list, jid); - if (!i) { - LeaveCriticalSection(&proto->csLists); - return; - } - i--; - LeaveCriticalSection(&proto->csLists); -} - -int JabberListFindNext(TlenProtocol *proto, JABBER_LIST list, int fromOffset) -{ - int i; - - EnterCriticalSection(&proto->csLists); - i = (fromOffset>=0) ? fromOffset : 0; - for(; ilistsCount; i++) - if (proto->lists[i].list == list) { - LeaveCriticalSection(&proto->csLists); - return i; - } - LeaveCriticalSection(&proto->csLists); - return -1; -} - -JABBER_LIST_ITEM *JabberListGetItemPtr(TlenProtocol *proto, JABBER_LIST list, const char *jid) -{ - int i; - - EnterCriticalSection(&proto->csLists); - i = JabberListExist(proto, list, jid); - if (!i) { - LeaveCriticalSection(&proto->csLists); - return NULL; - } - i--; - LeaveCriticalSection(&proto->csLists); - return &(proto->lists[i]); -} - -JABBER_LIST_ITEM *JabberListFindItemPtrById2(TlenProtocol *proto, JABBER_LIST list, const char *id) -{ - - int i; - size_t len; - char *p; - - len = strlen(id); - - EnterCriticalSection(&proto->csLists); - for(i=0; ilistsCount; i++) { - if (proto->lists[i].list==list) { - p = proto->lists[i].id2; - if (p != NULL) { - if (!strncmp(p, id, len)) { - LeaveCriticalSection(&proto->csLists); - return &(proto->lists[i]); - } - } - } - } - LeaveCriticalSection(&proto->csLists); - return NULL; -} - -JABBER_LIST_ITEM *JabberListGetItemPtrFromIndex(TlenProtocol *proto, int index) -{ - EnterCriticalSection(&proto->csLists); - if (index>=0 && indexlistsCount) { - LeaveCriticalSection(&proto->csLists); - return &(proto->lists[index]); - } - LeaveCriticalSection(&proto->csLists); - return NULL; -} - diff --git a/!NotAdopted/Tlen/jabber_list.h b/!NotAdopted/Tlen/jabber_list.h deleted file mode 100644 index 116440a6a1..0000000000 --- a/!NotAdopted/Tlen/jabber_list.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" - -#ifndef _JABBER_LIST_H_ -#define _JABBER_LIST_H_ - -typedef struct JABBER_LIST_ITEM_STRUCT { - JABBER_LIST list; - char *jid; - char *id2; - - // LIST_ROSTER - // jid = jid of the contact - char *nick; - int status; // Main status, currently useful for transport where no resource information is kept. - // On normal contact, this is the same status as shown on contact list. - JABBER_SUBSCRIPTION subscription; - char *statusMessage; // Status message when the update is to JID with no resource specified (e.g. transport user) - char *software; - char *version; - char *system; - char *group; - char *protocolVersion; - int avatarFormat; - char *avatarHash; - BOOL newAvatarDownloading; - BOOL versionRequested; - BOOL infoRequested; - int idMsgAckPending; - char *messageEventIdStr; - BOOL wantComposingEvent; - BOOL isTyping; - - // LIST_ROOM - // jid = room JID - // char *name; // room name - //char *type; // room type - - // LIST_CHATROOM - // jid = room JID - // char *nick; // my nick in this chat room (SPECIAL: in UTF8) - // JABBER_RESOURCE_STATUS *resource; // participant nicks in this room - char *roomName; - - // LIST_FILE - struct TLEN_FILE_TRANSFER_STRUCT *ft; -} JABBER_LIST_ITEM; - - -void JabberListInit(TlenProtocol *proto); -void JabberListUninit(TlenProtocol *proto); -void JabberListWipe(TlenProtocol *proto); -void JabberListWipeSpecial(TlenProtocol *proto); -int JabberListExist(TlenProtocol *proto, JABBER_LIST list, const char *jid); -JABBER_LIST_ITEM *JabberListAdd(TlenProtocol *proto, JABBER_LIST list, const char *jid); -void JabberListRemove(TlenProtocol *proto, JABBER_LIST list, const char *jid); -void JabberListRemoveList(TlenProtocol *proto, JABBER_LIST list); -void JabberListRemoveByIndex(TlenProtocol *proto, int index); -int JabberListFindNext(TlenProtocol *proto, JABBER_LIST list, int fromOffset); -JABBER_LIST_ITEM *JabberListGetItemPtr(TlenProtocol *proto, JABBER_LIST list, const char *jid); -JABBER_LIST_ITEM *JabberListGetItemPtrFromIndex(TlenProtocol *proto, int index); -JABBER_LIST_ITEM *JabberListFindItemPtrById2(TlenProtocol *proto, JABBER_LIST list, const char *id); - -void JabberListAddResource(TlenProtocol *proto, JABBER_LIST list, const char *jid, int status, const char *statusMessage); -void JabberListRemoveResource(TlenProtocol *proto, JABBER_LIST list, const char *jid); - -#endif - diff --git a/!NotAdopted/Tlen/jabber_misc.c b/!NotAdopted/Tlen/jabber_misc.c deleted file mode 100644 index 33ddf80f1e..0000000000 --- a/!NotAdopted/Tlen/jabber_misc.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include "jabber_list.h" - -void JabberDBAddEvent(TlenProtocol *proto, HANDLE hContact, int eventType, DWORD flags, PBYTE pBlob, DWORD cbBlob) -{ - DBEVENTINFO dbei = {0}; - dbei.cbSize = sizeof(DBEVENTINFO); - dbei.szModule = proto->iface.m_szModuleName; - dbei.timestamp = (DWORD) time(NULL); - dbei.flags = flags; - dbei.eventType = eventType; - dbei.cbBlob = cbBlob; - dbei.pBlob = pBlob; - CallService(MS_DB_EVENT_ADD, (WPARAM) hContact, (LPARAM) &dbei); -} -void JabberDBAddAuthRequest(TlenProtocol *proto, char *jid, char *nick) -{ - char *s; - PBYTE pCurBlob; - PBYTE pBlob; - DWORD cbBlob; - HANDLE hContact; - - if ((hContact=JabberHContactFromJID(proto, jid)) == NULL) { - hContact = (HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0); - CallService(MS_PROTO_ADDTOCONTACT, (WPARAM) hContact, (LPARAM) proto->iface.m_szModuleName); - // strip resource if present - s = JabberLoginFromJID(jid); - _strlwr(s); - DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "jid", s); - mir_free(s); - } - else { - DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "Hidden"); - } - DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "Nick", nick); - JabberLog(proto, "auth request: %s, %s", jid, nick); - //blob is: uin(DWORD), hContact(HANDLE), nick(ASCIIZ), first(ASCIIZ), last(ASCIIZ), email(ASCIIZ), reason(ASCIIZ) - //blob is: 0(DWORD), hContact(HANDLE), nick(ASCIIZ), ""(ASCIIZ), ""(ASCIIZ), email(ASCIIZ), ""(ASCIIZ) - cbBlob = sizeof(DWORD) + sizeof(HANDLE) + (int)strlen(nick) + (int)strlen(jid) + 5; - pBlob = pCurBlob = (PBYTE) mir_alloc(cbBlob); - *((PDWORD) pCurBlob) = 0; pCurBlob += sizeof(DWORD); - *((PHANDLE) pCurBlob) = hContact; pCurBlob += sizeof(HANDLE); - strcpy((char *) pCurBlob, nick); pCurBlob += strlen(nick)+1; - *pCurBlob = '\0'; pCurBlob++; //firstName - *pCurBlob = '\0'; pCurBlob++; //lastName - strcpy((char *) pCurBlob, jid); pCurBlob += strlen(jid)+1; - *pCurBlob = '\0'; //reason - JabberDBAddEvent(proto, NULL, EVENTTYPE_AUTHREQUEST, 0, pBlob, cbBlob); -} - -char *JabberJIDFromHContact(TlenProtocol *proto, HANDLE hContact) -{ - char *p = NULL; - DBVARIANT dbv; - if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { - p = mir_strdup(dbv.pszVal); - DBFreeVariant(&dbv); - } - return p; -} - - -HANDLE JabberHContactFromJID(TlenProtocol *proto, const char *jid) -{ - HANDLE hContact, hContactMatched; - DBVARIANT dbv; - char *szProto; - char *p; - if (jid == NULL) return (HANDLE) NULL; - hContactMatched = NULL; - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - while (hContact != NULL) { - szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); - if (szProto!=NULL && !strcmp(proto->iface.m_szModuleName, szProto)) { - if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { - if ((p=dbv.pszVal) != NULL) { - if (!stricmp(p, jid)) { // exact match (node@domain/resource) - hContactMatched = hContact; - DBFreeVariant(&dbv); - break; - } - } - DBFreeVariant(&dbv); - } - } - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); - } - if (hContactMatched != NULL) { - return hContactMatched; - } - return NULL; -} - -HANDLE JabberDBCreateContact(TlenProtocol *proto, char *jid, char *nick, BOOL temporary) -{ - HANDLE hContact; - if (jid==NULL || jid[0]=='\0') - return NULL; - - if ((hContact=JabberHContactFromJID(proto, jid)) == NULL) { - hContact = (HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0); - CallService(MS_PROTO_ADDTOCONTACT, (WPARAM) hContact, (LPARAM) proto->iface.m_szModuleName); - DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "jid", jid); - if (nick!=NULL && nick[0]!='\0') - DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "Nick", nick); - if (temporary) - DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1); - } - return hContact; -} - -static void JabberContactListCreateClistGroup(char *groupName) -{ - char str[33], newName[128]; - int i; - DBVARIANT dbv; - char *name; - - for (i=0;;i++) { - itoa(i, str, 10); - if (DBGetContactSetting(NULL, "CListGroups", str, &dbv)) - break; - name = dbv.pszVal; - if (name[0]!='\0' && !strcmp(name+1, groupName)) { - // Already exist, no need to create - DBFreeVariant(&dbv); - return; - } - DBFreeVariant(&dbv); - } - - // Create new group with id = i (str is the text representation of i) - newName[0] = 1 | GROUPF_EXPANDED; - strncpy(newName+1, groupName, sizeof(newName)-1); - newName[sizeof(newName)-1] = '\0'; - DBWriteContactSettingString(NULL, "CListGroups", str, newName); - CallService(MS_CLUI_GROUPADDED, i+1, 0); -} - -void JabberContactListCreateGroup(char *groupName) -{ - char name[128]; - char *p; - - if (groupName==NULL || groupName[0]=='\0' || groupName[0]=='\\') return; - - strncpy(name, groupName, sizeof(name)); - name[sizeof(name)-1] = '\0'; - for (p=name; *p!='\0'; p++) { - if (*p == '\\') { - *p = '\0'; - JabberContactListCreateClistGroup(name); - *p = '\\'; - } - } - JabberContactListCreateClistGroup(name); -} - - -struct FORK_ARG { - HANDLE hEvent; - void (__cdecl *threadcode)(void*); - void *arg; -}; - -static void __cdecl forkthread_r(struct FORK_ARG *fa) -{ - void (*callercode)(void*) = fa->threadcode; - void *arg = fa->arg; - CallService(MS_SYSTEM_THREAD_PUSH, 0, 0); - SetEvent(fa->hEvent); - callercode(arg); - CallService(MS_SYSTEM_THREAD_POP, 0, 0); - return; -} - -unsigned long JabberForkThread( - void (__cdecl *threadcode)(void*), - unsigned long stacksize, - void *arg -) -{ - unsigned long rc; - struct FORK_ARG fa; - - fa.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - fa.threadcode = threadcode; - fa.arg = arg; - rc = _beginthread((void (__cdecl *)(void*))forkthread_r, stacksize, &fa); - if ((unsigned long) -1L != rc) { - WaitForSingleObject(fa.hEvent, INFINITE); - } - CloseHandle(fa.hEvent); - return rc; -} diff --git a/!NotAdopted/Tlen/jabber_opt.c b/!NotAdopted/Tlen/jabber_opt.c deleted file mode 100644 index 3ef45e4289..0000000000 --- a/!NotAdopted/Tlen/jabber_opt.c +++ /dev/null @@ -1,708 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include "jabber_list.h" -#include "tlen_voice.h" -#include -#include "resource.h" - -static INT_PTR CALLBACK TlenBasicOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -static INT_PTR CALLBACK TlenVoiceOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -static INT_PTR CALLBACK TlenAdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -static INT_PTR CALLBACK TlenPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -typedef struct TabDefStruct { - DLGPROC dlgProc; - DWORD dlgId; - TCHAR *tabName; -} TabDef; - -static TabDef tabPages[] = { - {TlenBasicOptDlgProc, IDD_OPTIONS_BASIC, _T("General")}, - {TlenVoiceOptDlgProc, IDD_OPTIONS_VOICE, _T("Voice Chats")}, - {TlenAdvOptDlgProc, IDD_OPTIONS_ADVANCED, _T("Advanced")}, - {TlenPopupsDlgProc, IDD_OPTIONS_POPUPS, _T("Notifications")} - }; - -void TlenLoadOptions(TlenProtocol *proto) -{ - proto->tlenOptions.savePassword = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "SavePassword", TRUE); - proto->tlenOptions.useEncryption = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "UseEncryption", TRUE); - proto->tlenOptions.reconnect = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "Reconnect", TRUE); - proto->tlenOptions.alertPolicy = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "AlertPolicy", TLEN_ALERTS_IGNORE_NIR); - proto->tlenOptions.rosterSync = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "RosterSync", FALSE); - proto->tlenOptions.offlineAsInvisible = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "OfflineAsInvisible", FALSE); - proto->tlenOptions.leaveOfflineMessage = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "LeaveOfflineMessage", TRUE); - proto->tlenOptions.offlineMessageOption = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "OfflineMessageOption", 0); - proto->tlenOptions.ignoreAdvertisements = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "IgnoreAdvertisements", TRUE); - proto->tlenOptions.groupChatPolicy = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "GroupChatPolicy", TLEN_MUC_ASK); - proto->tlenOptions.voiceChatPolicy = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "VoiceChatPolicy", TLEN_MUC_ASK); - proto->tlenOptions.imagePolicy = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "ImagePolicy",TLEN_IMAGES_IGNORE_NIR); - proto->tlenOptions.enableAvatars = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "EnableAvatars", TRUE); - proto->tlenOptions.enableVersion = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "EnableVersion", TRUE); - proto->tlenOptions.useNudge = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "UseNudge", FALSE); - proto->tlenOptions.logAlerts = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "LogAlerts", TRUE); - proto->tlenOptions.sendKeepAlive = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "KeepAlive", TRUE); - proto->tlenOptions.useNewP2P = TRUE; -} - -static int changed = 0; - -static void ApplyChanges(TlenProtocol *proto, int i) { - changed &= ~i; - if (changed == 0) { - TlenLoadOptions(proto); - } -} - -static void MarkChanges(int i, HWND hWnd) { - SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0); - changed |= i; -} - - -int TlenOptionsInit(TlenProtocol *proto, WPARAM wParam, LPARAM lParam) -{ - int i; - OPTIONSDIALOGPAGE odp = { 0 }; - odp.cbSize = sizeof(odp); - odp.hInstance = hInst; - odp.ptszGroup = TranslateT("Network"); - odp.ptszTitle = proto->iface.m_tszUserName; - odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR; - odp.dwInitParam = (LPARAM)proto; - for (i = 0; i < SIZEOF(tabPages); i++) { - odp.pszTemplate = MAKEINTRESOURCEA(tabPages[i].dlgId); - odp.pfnDlgProc = tabPages[i].dlgProc; - odp.ptszTab = tabPages[i].tabName; - CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) & odp); - } -/* - if (ServiceExists(MS_POPUP_ADDPOPUP)) { - ZeroMemory(&odp,sizeof(odp)); - odp.cbSize = sizeof(odp); - odp.position = 100000000; - odp.hInstance = hInst; - odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR; - odp.ptszGroup = TranslateT("PopUps"); - odp.ptszTitle = proto->iface.m_tszUserName; - odp.dwInitParam = (LPARAM)proto; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS_POPUPS); - odp.pfnDlgProc = TlenPopupsDlgProc; - CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp); - } - */ - return 0; -} - -static LRESULT CALLBACK JabberValidateUsernameWndProc(HWND hwndEdit, UINT msg, WPARAM wParam, LPARAM lParam) -{ - WNDPROC oldProc = (WNDPROC) GetWindowLongPtr(hwndEdit, GWLP_USERDATA); - - switch (msg) { - case WM_CHAR: - if (strchr("\"&'/:<>@", wParam&0xff) != NULL) - return 0; - break; - } - return CallWindowProc(oldProc, hwndEdit, msg, wParam, lParam); -} - -INT_PTR CALLBACK TlenAccMgrUIDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - char text[256]; - WNDPROC oldProc; - - TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - { - DBVARIANT dbv; - proto = (TlenProtocol *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); - TranslateDialogDefault(hwndDlg); - if (!DBGetContactSettingTString(NULL, proto->iface.m_szModuleName, "LoginName", &dbv)) { - SetDlgItemText(hwndDlg, IDC_EDIT_USERNAME, dbv.ptszVal); - DBFreeVariant(&dbv); - } - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "Password", &dbv)) { - CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); - SetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, dbv.pszVal); - DBFreeVariant(&dbv); - } - CheckDlgButton(hwndDlg, IDC_SAVEPASSWORD, DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "SavePassword", TRUE)); - - oldProc = (WNDPROC) GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_WNDPROC); - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_USERDATA, (LONG_PTR) oldProc); - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_WNDPROC, (LONG_PTR) JabberValidateUsernameWndProc); - return TRUE; - } - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_EDIT_USERNAME: - case IDC_EDIT_PASSWORD: - if ((HWND)lParam==GetFocus() && HIWORD(wParam)==EN_CHANGE) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - case IDC_SAVEPASSWORD: - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - case IDC_REGISTERACCOUNT: - CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) TLEN_REGISTER); - break; - } - break; - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: - { - BOOL reconnectRequired = FALSE; - DBVARIANT dbv; - - GetDlgItemTextA(hwndDlg, IDC_EDIT_USERNAME, text, sizeof(text)); - if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginName", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) DBFreeVariant(&dbv); - DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "LoginName", strlwr(text)); - - if (IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)) { - GetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, text, sizeof(text)); - CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(text), (LPARAM) text); - if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "Password", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) DBFreeVariant(&dbv); - DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "Password", text); - } - else - DBDeleteContactSetting(NULL, proto->iface.m_szModuleName, "Password"); - - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "SavePassword", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)); - if (reconnectRequired && proto->isConnected) - MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); - TlenLoadOptions(proto); - return TRUE; - } - } - break; - } - return FALSE; -} - -static INT_PTR CALLBACK TlenBasicOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - char text[256]; - WNDPROC oldProc; - - TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - { - DBVARIANT dbv; - proto = (TlenProtocol *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); - TranslateDialogDefault(hwndDlg); - if (!DBGetContactSettingTString(NULL, proto->iface.m_szModuleName, "LoginName", &dbv)) { - SetDlgItemText(hwndDlg, IDC_EDIT_USERNAME, dbv.ptszVal); - DBFreeVariant(&dbv); - } - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "Password", &dbv)) { - CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); - SetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, dbv.pszVal); - DBFreeVariant(&dbv); - } - CheckDlgButton(hwndDlg, IDC_SAVEPASSWORD, DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "SavePassword", TRUE)); - - CheckDlgButton(hwndDlg, IDC_RECONNECT, proto->tlenOptions.reconnect); - CheckDlgButton(hwndDlg, IDC_ROSTER_SYNC, proto->tlenOptions.rosterSync); - CheckDlgButton(hwndDlg, IDC_SHOW_OFFLINE, proto->tlenOptions.offlineAsInvisible); - CheckDlgButton(hwndDlg, IDC_OFFLINE_MESSAGE, proto->tlenOptions.leaveOfflineMessage); - CheckDlgButton(hwndDlg, IDC_IGNORE_ADVERTISEMENTS, proto->tlenOptions.ignoreAdvertisements); - CheckDlgButton(hwndDlg, IDC_AVATARS, proto->tlenOptions.enableAvatars); - CheckDlgButton(hwndDlg, IDC_VERSIONINFO, proto->tlenOptions.enableVersion); - CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, proto->tlenOptions.useNudge); - CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, proto->tlenOptions.logAlerts); - - SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all alerts")); - SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore alerts from unauthorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all alerts")); - SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_SETCURSEL, proto->tlenOptions.alertPolicy, 0); - - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Always ask me")); - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept invitations from authorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all invitations")); - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore invitations from unauthorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all invitation")); - SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_SETCURSEL, proto->tlenOptions.groupChatPolicy, 0); - - SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all images")); - SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore images from unauthorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all images")); - SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_SETCURSEL, proto->tlenOptions.imagePolicy, 0); - - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("")); - //SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("")); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("Online")); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("Away")); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("NA")); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("DND")); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("Free for chat")); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("Invisible")); - SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_SETCURSEL, proto->tlenOptions.offlineMessageOption, 0); - - oldProc = (WNDPROC) GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_WNDPROC); - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_USERDATA, (LONG_PTR) oldProc); - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_WNDPROC, (LONG_PTR) JabberValidateUsernameWndProc); - return TRUE; - } - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_EDIT_USERNAME: - case IDC_EDIT_PASSWORD: - if ((HWND)lParam==GetFocus() && HIWORD(wParam)==EN_CHANGE) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - // Fall through - case IDC_SAVEPASSWORD: - case IDC_RECONNECT: - case IDC_ROSTER_SYNC: - case IDC_IGNORE_ADVERTISEMENTS: - case IDC_SHOW_OFFLINE: - case IDC_OFFLINE_MESSAGE: - MarkChanges(1, hwndDlg); - break; - case IDC_LOG_ALERTS: - CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, BST_UNCHECKED); - MarkChanges(1, hwndDlg); - break; - case IDC_NUDGE_SUPPORT: - CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, BST_UNCHECKED); - MarkChanges(1, hwndDlg); - break; - case IDC_REGISTERACCOUNT: - CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) TLEN_REGISTER); - break; - case IDC_OFFLINE_MESSAGE_OPTION: - case IDC_ALERT_POLICY: - case IDC_MUC_POLICY: - if (HIWORD(wParam) == CBN_SELCHANGE) - MarkChanges(1, hwndDlg); - break; - default: - MarkChanges(1, hwndDlg); - break; - } - break; - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: - { - BOOL reconnectRequired = FALSE; - DBVARIANT dbv; - - GetDlgItemTextA(hwndDlg, IDC_EDIT_USERNAME, text, sizeof(text)); - if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginName", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) DBFreeVariant(&dbv); - DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "LoginName", strlwr(text)); - - if (IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)) { - GetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, text, sizeof(text)); - CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(text), (LPARAM) text); - if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "Password", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) DBFreeVariant(&dbv); - DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "Password", text); - } - else - DBDeleteContactSetting(NULL, proto->iface.m_szModuleName, "Password"); - - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "SavePassword", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)); - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "Reconnect", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_RECONNECT)); - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "RosterSync", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ROSTER_SYNC)); - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "OfflineAsInvisible", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOW_OFFLINE)); - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "IgnoreAdvertisements", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_IGNORE_ADVERTISEMENTS)); - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "LeaveOfflineMessage", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_OFFLINE_MESSAGE)); - DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "OfflineMessageOption", (WORD) SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_GETCURSEL, 0, 0)); - DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "AlertPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_GETCURSEL, 0, 0)); - DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "GroupChatPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_GETCURSEL, 0, 0)); - DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "ImagePolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_GETCURSEL, 0, 0)); - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "EnableAvatars", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AVATARS)); - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "EnableVersion", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VERSIONINFO)); - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "UseNudge", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_NUDGE_SUPPORT)); - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "LogAlerts", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_LOG_ALERTS)); - if (reconnectRequired && proto->isConnected) - MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); - ApplyChanges(proto, 1); - return TRUE; - } - } - break; - } - return FALSE; -} - -static INT_PTR CALLBACK TlenVoiceOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - { - proto = (TlenProtocol *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Always ask me")); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept invitations from authorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all invitations")); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore invitations from unauthorized contacts")); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all invitation")); - SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_SETCURSEL, proto->tlenOptions.voiceChatPolicy, 0); - TlenVoiceBuildInDeviceList(proto, GetDlgItem(hwndDlg, IDC_VOICE_DEVICE_IN)); - TlenVoiceBuildOutDeviceList(proto, GetDlgItem(hwndDlg, IDC_VOICE_DEVICE_OUT)); - return TRUE; - } - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_VOICE_POLICY: - case IDC_VOICE_DEVICE_IN: - case IDC_VOICE_DEVICE_OUT: - if (HIWORD(wParam) == CBN_SELCHANGE) - MarkChanges(2, hwndDlg); - break; - } - break; - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: - { - DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "VoiceChatPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_GETCURSEL, 0, 0)); - DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "VoiceDeviceIn", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_DEVICE_IN, CB_GETCURSEL, 0, 0)); - DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "VoiceDeviceOut", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_DEVICE_OUT, CB_GETCURSEL, 0, 0)); - ApplyChanges(proto, 2); - return TRUE; - } - } - break; - } - - return FALSE; -} - -static INT_PTR CALLBACK TlenAdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - char text[256]; - BOOL bChecked; - TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - - switch (msg) { - case WM_INITDIALOG: - { - DBVARIANT dbv; - proto = (TlenProtocol *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); - TranslateDialogDefault(hwndDlg); - if (!DBGetContactSettingTString(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { - SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, dbv.ptszVal); - DBFreeVariant(&dbv); - } else { - SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, _T("tlen.pl")); - } - - EnableWindow(GetDlgItem(hwndDlg, IDC_HOST), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_HOSTPORT), TRUE); - - if (!DBGetContactSettingTString(NULL, proto->iface.m_szModuleName, "ManualHost", &dbv)) { - SetDlgItemText(hwndDlg, IDC_HOST, dbv.ptszVal); - DBFreeVariant(&dbv); - } else - SetDlgItemText(hwndDlg, IDC_HOST, _T("s1.tlen.pl")); - SetDlgItemInt(hwndDlg, IDC_HOSTPORT, DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT), FALSE); - - CheckDlgButton(hwndDlg, IDC_KEEPALIVE, DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "KeepAlive", TRUE)); - - CheckDlgButton(hwndDlg, IDC_USE_SSL, DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "UseEncryption", TRUE)); - - CheckDlgButton(hwndDlg, IDC_VISIBILITY_SUPPORT, DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "VisibilitySupport", FALSE)); - // File transfer options - bChecked = FALSE; - if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "UseFileProxy", FALSE) == TRUE) { - bChecked = TRUE; - CheckDlgButton(hwndDlg, IDC_FILE_USE_PROXY, TRUE); - } - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked); - if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "FileProxyAuth", FALSE) == TRUE) { - CheckDlgButton(hwndDlg, IDC_FILE_PROXY_USE_AUTH, TRUE); - } else { - bChecked = FALSE; - } - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked); - - SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateT("Forwarding")); - SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateT("SOCKS4")); - SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateT("SOCKS5")); - SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_SETCURSEL, DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "FileProxyType", 0), 0); - if (!DBGetContactSettingTString(NULL, proto->iface.m_szModuleName, "FileProxyHost", &dbv)) { - SetDlgItemText(hwndDlg, IDC_FILE_PROXY_HOST, dbv.ptszVal); - DBFreeVariant(&dbv); - } - SetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "FileProxyPort", 0), FALSE); - if (!DBGetContactSettingTString(NULL, proto->iface.m_szModuleName, "FileProxyUsername", &dbv)) { - SetDlgItemText(hwndDlg, IDC_FILE_PROXY_USER, dbv.ptszVal); - DBFreeVariant(&dbv); - } - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "FileProxyPassword", &dbv)) { - CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); - SetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, dbv.pszVal); - DBFreeVariant(&dbv); - } - return TRUE; - } - case WM_COMMAND: - { - switch (LOWORD(wParam)) { - case IDC_FILE_PROXY_TYPE: - if (HIWORD(wParam) == CBN_SELCHANGE) - MarkChanges(4, hwndDlg); - break; - case IDC_EDIT_LOGIN_SERVER: - case IDC_HOST: - case IDC_HOSTPORT: - case IDC_FILE_PROXY_HOST: - case IDC_FILE_PROXY_PORT: - case IDC_FILE_PROXY_USER: - case IDC_FILE_PROXY_PASSWORD: - if ((HWND)lParam==GetFocus() && HIWORD(wParam)==EN_CHANGE) - MarkChanges(4, hwndDlg); - break; - case IDC_FILE_USE_PROXY: - bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked); - case IDC_FILE_PROXY_USE_AUTH: - bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH) & IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked); - EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked); - MarkChanges(4, hwndDlg); - break; - case IDC_KEEPALIVE: - case IDC_VISIBILITY_SUPPORT: - case IDC_USE_SSL: - MarkChanges(4, hwndDlg); - break; - } - } - break; - case WM_NOTIFY: - { - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: - { - WORD port; - BOOL useEncryption; - BOOL reconnectRequired = FALSE; - DBVARIANT dbv; - GetDlgItemTextA(hwndDlg, IDC_EDIT_LOGIN_SERVER, text, sizeof(text)); - if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) DBFreeVariant(&dbv); - DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "LoginServer", strlwr(text)); - - GetDlgItemTextA(hwndDlg, IDC_HOST, text, sizeof(text)); - if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "ManualHost", &dbv) || strcmp(text, dbv.pszVal)) - reconnectRequired = TRUE; - if (dbv.pszVal != NULL) DBFreeVariant(&dbv); - DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "ManualHost", text); - - port = (WORD) GetDlgItemInt(hwndDlg, IDC_HOSTPORT, NULL, FALSE); - if (DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT) != port) - reconnectRequired = TRUE; - DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "ManualPort", port); - - proto->tlenOptions.sendKeepAlive = IsDlgButtonChecked(hwndDlg, IDC_KEEPALIVE); - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "KeepAlive", (BYTE) proto->tlenOptions.sendKeepAlive); - - useEncryption = IsDlgButtonChecked(hwndDlg, IDC_USE_SSL); - if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "UseEncryption", TRUE) != useEncryption) - reconnectRequired = TRUE; - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "UseEncryption", (BYTE) useEncryption); - - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "VisibilitySupport", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VISIBILITY_SUPPORT)); - // File transfer options - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "UseFileProxy", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY)); - DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "FileProxyType", (WORD) SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_GETCURSEL, 0, 0)); - GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_HOST, text, sizeof(text)); - DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "FileProxyHost", text); - DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "FileProxyPort", (WORD) GetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, NULL, FALSE)); - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "FileProxyAuth", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH)); - GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_USER, text, sizeof(text)); - DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "FileProxyUsername", text); - GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, text, sizeof(text)); - CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(text), (LPARAM) text); - DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "FileProxyPassword", text); - if (reconnectRequired && proto->isConnected) - MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); - ApplyChanges(proto, 4); - return TRUE; - } - } - } - break; - case WM_DESTROY: - break; - } - - return FALSE; -} - -#define POPUP_DEFAULT_COLORBKG 0xDCBDA5 -#define POPUP_DEFAULT_COLORTXT 0x000000 - -static void MailPopupPreview(DWORD colorBack, DWORD colorText, char *title, char *emailInfo, int delay) -{ - POPUPDATAEX ppd; - char * lpzContactName; - char * lpzText; - HICON hIcon; - lpzContactName = title; - lpzText = emailInfo; - ZeroMemory(&ppd, sizeof(ppd)); - ppd.lchContact = NULL; - hIcon = GetIcolibIcon(IDI_MAIL); - ppd.lchIcon = CopyIcon(hIcon); - ReleaseIcolibIcon(hIcon); - strcpy(ppd.lpzContactName, lpzContactName); - strcpy(ppd.lpzText, lpzText); - ppd.colorBack = colorBack; - ppd.colorText = colorText; - ppd.PluginWindowProc = NULL; - ppd.PluginData=NULL; - if ( ServiceExists( MS_POPUP_ADDPOPUPEX )) { - ppd.iSeconds = delay; - CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0); - - } - else if ( ServiceExists( MS_POPUP_ADDPOPUP )) { - CallService(MS_POPUP_ADDPOPUP, (WPARAM)&ppd, 0); - } -} - -static INT_PTR CALLBACK TlenPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - { - BYTE delayMode; - proto = (TlenProtocol *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); - TranslateDialogDefault(hwndDlg); - CheckDlgButton(hwndDlg, IDC_ENABLEPOPUP, DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "MailPopupEnabled", TRUE)); - SendDlgItemMessage(hwndDlg, IDC_COLORBKG, CPM_SETCOLOUR, 0, DBGetContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupBack", POPUP_DEFAULT_COLORBKG)); - SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETCOLOUR, 0, DBGetContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupText", POPUP_DEFAULT_COLORTXT)); - SetDlgItemInt(hwndDlg, IDC_DELAY, DBGetContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupDelay", 4), FALSE); - delayMode = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "MailPopupDelayMode", 0); - if (delayMode==1) { - CheckDlgButton(hwndDlg, IDC_DELAY_CUSTOM, TRUE); - } else if (delayMode==2) { - CheckDlgButton(hwndDlg, IDC_DELAY_PERMANENT, TRUE); - } else { - CheckDlgButton(hwndDlg, IDC_DELAY_POPUP, TRUE); - } - return TRUE; - } - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COLORTXT: - case IDC_COLORBKG: - case IDC_ENABLEPOPUP: - case IDC_DELAY: - case IDC_DELAY_POPUP: - case IDC_DELAY_CUSTOM: - case IDC_DELAY_PERMANENT: - MarkChanges(8, hwndDlg); - break; - case IDC_PREVIEW: - { - int delay; - char title[256]; - if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_POPUP)) { - delay=0; - } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) { - delay=-1; - } else { - delay=GetDlgItemInt(hwndDlg, IDC_DELAY, NULL, FALSE); - } - _snprintf(title, sizeof(title), Translate("%s mail"), proto->iface.m_szProtoName); - MailPopupPreview((DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0), - (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0), - title, - "From: test@test.test\nSubject: test", - delay); - } - - } - break; - - - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: - { - BYTE delayMode; - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "MailPopupEnabled", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ENABLEPOPUP)); - DBWriteContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupBack", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0)); - DBWriteContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupText", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0)); - DBWriteContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupDelay", (DWORD) GetDlgItemInt(hwndDlg,IDC_DELAY, NULL, FALSE)); - delayMode=0; - if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_CUSTOM)) { - delayMode=1; - } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) { - delayMode=2; - - } - DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "MailPopupDelayMode", delayMode); - ApplyChanges(proto, 8); - return TRUE; - } - } - break; - - } - return FALSE; -} - diff --git a/!NotAdopted/Tlen/jabber_svc.c b/!NotAdopted/Tlen/jabber_svc.c deleted file mode 100644 index ecc3b26bfb..0000000000 --- a/!NotAdopted/Tlen/jabber_svc.c +++ /dev/null @@ -1,1300 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include -#include -#include -#include -#include "resource.h" -#include "jabber_list.h" -#include "jabber_iq.h" -#include "tlen_p2p_old.h" -#include "tlen_avatar.h" -#include "tlen_file.h" - -extern int TlenOnModulesLoaded(void *ptr, WPARAM wParam, LPARAM lParam); -extern int TlenOptionsInit(void *ptr, WPARAM wParam, LPARAM lParam); -extern int TlenPreShutdown(void *ptr, WPARAM wParam, LPARAM lParam); -DWORD_PTR TlenGetCaps(PROTO_INTERFACE *ptr, int type, HANDLE hContact) -{ - if (type == PFLAGNUM_1) - return PF1_IM|PF1_AUTHREQ|PF1_SERVERCLIST|PF1_MODEMSG|PF1_BASICSEARCH|PF1_SEARCHBYEMAIL|PF1_EXTSEARCH|PF1_EXTSEARCHUI|PF1_SEARCHBYNAME|PF1_FILE;//|PF1_VISLIST|PF1_INVISLIST; - if (type == PFLAGNUM_2) - return PF2_ONLINE|PF2_INVISIBLE|PF2_SHORTAWAY|PF2_LONGAWAY|PF2_HEAVYDND|PF2_FREECHAT; - if (type == PFLAGNUM_3) - return PF2_ONLINE|PF2_INVISIBLE|PF2_SHORTAWAY|PF2_LONGAWAY|PF2_HEAVYDND|PF2_FREECHAT; - if (type == PFLAGNUM_4) - return PF4_FORCEAUTH|PF4_NOCUSTOMAUTH|PF4_SUPPORTTYPING|PF4_AVATARS|PF4_IMSENDOFFLINE|PF4_OFFLINEFILES; - if (type == PFLAG_UNIQUEIDTEXT) - return (DWORD_PTR) Translate("Tlen login"); - if (type == PFLAG_UNIQUEIDSETTING) - return (DWORD_PTR) "jid"; - return 0; -} - -INT_PTR TlenGetName(void *ptr, WPARAM wParam, LPARAM lParam) -{ - TlenProtocol *proto = (TlenProtocol *)ptr; - strncpy((char *) lParam, proto->iface.m_szProtoName, wParam); - return 0; -} - -HICON TlenGetIcon(PROTO_INTERFACE *ptr, int iconIndex) -{ - if ((iconIndex&0xffff) == PLI_PROTOCOL) { - HICON hIcon = GetIcolibIcon(IDI_TLEN); - HICON hIconCopy = CopyIcon(hIcon); - ReleaseIcolibIcon(hIcon); - return hIconCopy; - } - return (HICON) NULL; -} - -int TlenRunSearch(TlenProtocol *proto) { - int iqId = 0; - if (!proto->isOnline) return 0; - if (proto->searchQuery != NULL && proto->searchIndex < 10) { - iqId = proto->searchID; - JabberIqAdd(proto, iqId, IQ_PROC_GETSEARCH, JabberIqResultSearch); - if (proto->searchIndex == 0) { - JabberSend(proto, "%s", iqId, proto->searchQuery); - } else { - JabberSend(proto, "%s%d", iqId, proto->searchQuery, proto->searchIndex * TLEN_MAX_SEARCH_RESULTS_PER_PAGE); - } - proto->searchIndex ++; - } - return iqId; -} - -void TlenResetSearchQuery(TlenProtocol *proto) { - if (proto->searchQuery != NULL) { - mir_free(proto->searchQuery); - proto->searchQuery = NULL; - } - proto->searchQueryLen = 0; - proto->searchIndex = 0; - proto->searchID = JabberSerialNext(proto); -} - -HANDLE TlenBasicSearch(PROTO_INTERFACE *ptr, const char *id) -{ - char *jid; - int iqId = 0; - TlenProtocol *proto = (TlenProtocol *)ptr; - if (!proto->isOnline) return 0; - if (id == NULL) return 0; - if ((jid=JabberTextEncode(id)) != NULL) { - proto->searchJID = mir_strdup(id); - TlenResetSearchQuery(proto); - JabberStringAppend(&proto->searchQuery, &proto->searchQueryLen, "%s", jid); - iqId = TlenRunSearch(proto); - mir_free(jid); - } - return (HANDLE)iqId; -} - -HANDLE TlenSearchByEmail(PROTO_INTERFACE *ptr, const char* email) -{ - char *emailEnc; - int iqId = 0; - TlenProtocol *proto = (TlenProtocol *)ptr; - - if (!proto->isOnline) return 0; - if (email == NULL) return 0; - - if ((emailEnc=JabberTextEncode(email)) != NULL) { - TlenResetSearchQuery(proto); - JabberStringAppend(&proto->searchQuery, &proto->searchQueryLen, "%s", emailEnc); - iqId = TlenRunSearch(proto); - mir_free(emailEnc); - } - return (HANDLE)iqId; -} - -HANDLE TlenSearchByName(PROTO_INTERFACE *ptr, const char* nick, const char* firstName, const char* lastName) -{ - char *p; - int iqId = 0; - - TlenProtocol *proto = (TlenProtocol *)ptr; - if (!proto->isOnline) return 0; - - TlenResetSearchQuery(proto); - - if (nick != NULL && nick[0] != '\0') { - if ((p=JabberTextEncode(nick)) != NULL) { - JabberStringAppend(&proto->searchQuery, &proto->searchQueryLen, "%s", p); - mir_free(p); - } - } - if (firstName != NULL && firstName[0] != '\0') { - if ((p=JabberTextEncode(firstName)) != NULL) { - JabberStringAppend(&proto->searchQuery, &proto->searchQueryLen, "%s", p); - mir_free(p); - } - } - if (lastName != NULL && lastName[0] != '\0') { - if ((p=JabberTextEncode(lastName)) != NULL) { - JabberStringAppend(&proto->searchQuery, &proto->searchQueryLen, "%s", p); - mir_free(p); - } - } - - iqId = TlenRunSearch(proto); - return (HANDLE)iqId; -} - -HWND TlenCreateAdvSearchUI(PROTO_INTERFACE *ptr, HWND owner) -{ - return (HWND) CreateDialog(hInst, MAKEINTRESOURCE(IDD_ADVSEARCH), owner, TlenAdvSearchDlgProc); -} - -HWND TlenSearchAdvanced(PROTO_INTERFACE *ptr, HWND owner) -{ - int iqId; - TlenProtocol *proto = (TlenProtocol *)ptr; - if (!proto->isOnline) return 0; - - TlenResetSearchQuery(proto); - iqId = JabberSerialNext(proto); - if ((proto->searchQuery = TlenAdvSearchCreateQuery(owner, iqId)) != NULL) { - iqId = TlenRunSearch(proto); - } - return (HWND)iqId; -} - -static HANDLE AddToListByJID(TlenProtocol *proto, const char *newJid, DWORD flags) -{ - HANDLE hContact; - char *jid, *nick; - - if ((hContact=JabberHContactFromJID(proto, newJid)) == NULL) { - // not already there: add - jid = mir_strdup(newJid); _strlwr(jid); - hContact = (HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0); - CallService(MS_PROTO_ADDTOCONTACT, (WPARAM) hContact, (LPARAM) proto->iface.m_szModuleName); - DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "jid", jid); - if ((nick=JabberNickFromJID(newJid)) == NULL) - nick = mir_strdup(newJid); - DBWriteContactSettingString(hContact, "CList", "MyHandle", nick); - mir_free(nick); - mir_free(jid); - - // Note that by removing or disable the "NotOnList" will trigger - // the plugin to add a particular contact to the roster list. - // See DBSettingChanged hook at the bottom part of this source file. - // But the add module will delete "NotOnList". So we will not do it here. - // Also because we need "MyHandle" and "Group" info, which are set after - // PS_ADDTOLIST is called but before the add dialog issue deletion of - // "NotOnList". - // If temporary add, "NotOnList" won't be deleted, and that's expected. - DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1); - if (flags & PALF_TEMPORARY) - DBWriteContactSettingByte(hContact, "CList", "Hidden", 1); - } - else { - // already exist - // Set up a dummy "NotOnList" when adding permanently only - if (!(flags&PALF_TEMPORARY)) - DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1); - } - - return hContact; -} - -HANDLE TlenAddToList(PROTO_INTERFACE *ptr, int flags, PROTOSEARCHRESULT *psr) -{ - HANDLE hContact; - TlenProtocol *proto = (TlenProtocol *)ptr; - JABBER_SEARCH_RESULT *jsr = (JABBER_SEARCH_RESULT*)psr; - if (jsr->hdr.cbSize != sizeof(JABBER_SEARCH_RESULT)) - return (int) NULL; - hContact = AddToListByJID(proto, jsr->jid, flags); // wParam is flag e.g. PALF_TEMPORARY - return hContact; -} - -HANDLE TlenAddToListByEvent(PROTO_INTERFACE *ptr, int flags, int iContact, HANDLE hDbEvent) -{ - DBEVENTINFO dbei; - HANDLE hContact; - char *nick, *firstName, *lastName, *jid; - TlenProtocol *proto = (TlenProtocol *)ptr; - - ZeroMemory(&dbei, sizeof(dbei)); - dbei.cbSize = sizeof(dbei); - if ((dbei.cbBlob=CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0)) == (DWORD)(-1)) - return (int)(HANDLE) NULL; - if ((dbei.pBlob=(PBYTE) mir_alloc(dbei.cbBlob)) == NULL) - return (int)(HANDLE) NULL; - if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM) &dbei)) { - mir_free(dbei.pBlob); - return (int)(HANDLE) NULL; - } - if (strcmp(dbei.szModule, proto->iface.m_szModuleName)) { - mir_free(dbei.pBlob); - return (int)(HANDLE) NULL; - } - -/* - // EVENTTYPE_CONTACTS is when adding from when we receive contact list (not used in Jabber) - // EVENTTYPE_ADDED is when adding from when we receive "You are added" (also not used in Jabber) - // Jabber will only handle the case of EVENTTYPE_AUTHREQUEST - // EVENTTYPE_AUTHREQUEST is when adding from the authorization request dialog -*/ - - if (dbei.eventType != EVENTTYPE_AUTHREQUEST) { - mir_free(dbei.pBlob); - return (int)(HANDLE) NULL; - } - - nick = (char *) (dbei.pBlob + sizeof(DWORD) + sizeof(HANDLE)); - firstName = nick + strlen(nick) + 1; - lastName = firstName + strlen(firstName) + 1; - jid = lastName + strlen(lastName) + 1; - - hContact = (HANDLE) AddToListByJID(proto, jid, flags); - mir_free(dbei.pBlob); - - return hContact; -} - -int TlenAuthAllow(PROTO_INTERFACE *ptr, HANDLE hContact) -{ - DBEVENTINFO dbei; - char *nick, *firstName, *lastName, *jid; - TlenProtocol *proto = (TlenProtocol *)ptr; - - if (!proto->isOnline) - return 1; - - memset(&dbei, sizeof(dbei), 0); - dbei.cbSize = sizeof(dbei); - if ((dbei.cbBlob=CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hContact, 0)) == (DWORD)(-1)) - return 1; - if ((dbei.pBlob=(PBYTE) mir_alloc(dbei.cbBlob)) == NULL) - return 1; - if (CallService(MS_DB_EVENT_GET, (WPARAM)hContact, (LPARAM) &dbei)) { - mir_free(dbei.pBlob); - return 1; - } - if (dbei.eventType != EVENTTYPE_AUTHREQUEST) { - mir_free(dbei.pBlob); - return 1; - } - if (strcmp(dbei.szModule, proto->iface.m_szModuleName)) { - mir_free(dbei.pBlob); - return 1; - } - - nick = (char *) (dbei.pBlob + sizeof(DWORD) + sizeof(HANDLE)); - firstName = nick + strlen(nick) + 1; - lastName = firstName + strlen(firstName) + 1; - jid = lastName + strlen(lastName) + 1; - - JabberSend(proto, "", jid); - - // Automatically add this user to my roster if option is enabled - if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "AutoAdd", TRUE) == TRUE) { - HANDLE hContact; - JABBER_LIST_ITEM *item; - - if ((item=JabberListGetItemPtr(proto, LIST_ROSTER, jid))==NULL || (item->subscription!=SUB_BOTH && item->subscription!=SUB_TO)) { - JabberLog(proto, "Try adding contact automatically jid=%s", jid); - if ((hContact=AddToListByJID(proto, jid, 0)) != NULL) { - // Trigger actual add by removing the "NotOnList" added by AddToListByJID() - // See AddToListByJID() and JabberDbSettingChanged(). - DBDeleteContactSetting(hContact, "CList", "NotOnList"); - } - } - } - - mir_free(dbei.pBlob); - return 0; -} - -int TlenAuthDeny(PROTO_INTERFACE *ptr, HANDLE hContact, const TCHAR* szReason) -{ - DBEVENTINFO dbei; - char *nick, *firstName, *lastName, *jid; - TlenProtocol *proto = (TlenProtocol *)ptr; - - if (!proto->isOnline) - return 1; - - memset(&dbei, sizeof(dbei), 0); - dbei.cbSize = sizeof(dbei); - if ((dbei.cbBlob=CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hContact, 0)) == (DWORD)(-1)) - return 1; - if ((dbei.pBlob=(PBYTE) mir_alloc(dbei.cbBlob)) == NULL) - return 1; - if (CallService(MS_DB_EVENT_GET, (WPARAM)hContact, (LPARAM) &dbei)) { - mir_free(dbei.pBlob); - return 1; - } - if (dbei.eventType != EVENTTYPE_AUTHREQUEST) { - mir_free(dbei.pBlob); - return 1; - } - if (strcmp(dbei.szModule, proto->iface.m_szModuleName)) { - mir_free(dbei.pBlob); - return 1; - } - - nick = (char *) (dbei.pBlob + sizeof(DWORD) + sizeof(HANDLE)); - firstName = nick + strlen(nick) + 1; - lastName = firstName + strlen(firstName) + 1; - jid = lastName + strlen(lastName) + 1; - - JabberSend(proto, "", jid); - JabberSend(proto, "", jid); - mir_free(dbei.pBlob); - return 0; -} - -static void TlenConnect(TlenProtocol *proto, int initialStatus) -{ - if (!proto->isConnected) { - ThreadData *thread; - int oldStatus; - - thread = (ThreadData *) mir_alloc(sizeof(ThreadData)); - memset(thread, 0, sizeof(ThreadData)); - thread->proto = proto; - proto->iface.m_iDesiredStatus = initialStatus; - - oldStatus = proto->iface.m_iStatus; - proto->iface.m_iStatus = ID_STATUS_CONNECTING; - ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, proto->iface.m_iStatus); - thread->hThread = (HANDLE) JabberForkThread((void (__cdecl *)(void*))JabberServerThread, 0, thread); - } -} - -int TlenSetStatus(PROTO_INTERFACE *ptr, int iNewStatus) -{ - int oldStatus; - HANDLE s; - TlenProtocol *proto = (TlenProtocol *)ptr; - - proto->iface.m_iDesiredStatus = iNewStatus; - - if (iNewStatus == ID_STATUS_OFFLINE) { - if (proto->threadData) { - if (proto->isConnected) { - JabberSendPresence(proto, ID_STATUS_OFFLINE); - } - s = proto; - proto->threadData = NULL; - if (proto->isConnected) { - Sleep(200); -// JabberSend(s, ""); - // Force closing connection - proto->isConnected = FALSE; - proto->isOnline = FALSE; - Netlib_CloseHandle(s); - } - } - else { - if (proto->iface.m_iStatus != ID_STATUS_OFFLINE) { - oldStatus = proto->iface.m_iStatus; - proto->iface.m_iStatus = ID_STATUS_OFFLINE; - ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, proto->iface.m_iStatus); - } - } - } - else if (iNewStatus != proto->iface.m_iStatus) { - if (!proto->isConnected) - TlenConnect(proto, iNewStatus); - else { - // change status - oldStatus = proto->iface.m_iStatus; - // send presence update - JabberSendPresence(proto, iNewStatus); - ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, proto->iface.m_iStatus); - } - } - return 0; -} - -INT_PTR TlenGetStatus(void *ptr, WPARAM wParam, LPARAM lParam) -{ - TlenProtocol *proto = (TlenProtocol *)ptr; - return proto->iface.m_iStatus; -} - - -int TlenSetAwayMsg(PROTO_INTERFACE *ptr, int iStatus, const char* msg ) -{ - char **szMsg; - char *newModeMsg; - TlenProtocol *proto = (TlenProtocol *)ptr; - - JabberLog(proto, "SetAwayMsg called, wParam=%d lParam=%s", iStatus, msg); - - newModeMsg = JabberTextEncode(msg); - - EnterCriticalSection(&proto->modeMsgMutex); - - switch (iStatus) { - case ID_STATUS_ONLINE: - szMsg = &proto->modeMsgs.szOnline; - break; - case ID_STATUS_AWAY: - case ID_STATUS_ONTHEPHONE: - case ID_STATUS_OUTTOLUNCH: - szMsg = &proto->modeMsgs.szAway; - break; - case ID_STATUS_NA: - szMsg = &proto->modeMsgs.szNa; - break; - case ID_STATUS_DND: - case ID_STATUS_OCCUPIED: - szMsg = &proto->modeMsgs.szDnd; - break; - case ID_STATUS_FREECHAT: - szMsg = &proto->modeMsgs.szFreechat; - break; - case ID_STATUS_INVISIBLE: - szMsg = &proto->modeMsgs.szInvisible; - break; - default: - LeaveCriticalSection(&proto->modeMsgMutex); - return 1; - } - - if ((*szMsg==NULL && newModeMsg==NULL) || - (*szMsg!=NULL && newModeMsg!=NULL && !strcmp(*szMsg, newModeMsg))) { - // Message is the same, no update needed - if (newModeMsg != NULL) mir_free(newModeMsg); - } - else { - // Update with the new mode message - if (*szMsg != NULL) mir_free(*szMsg); - *szMsg = newModeMsg; - // Send a presence update if needed - if (iStatus == proto->iface.m_iStatus) { - JabberSendPresence(proto, proto->iface.m_iStatus); - } - } - - LeaveCriticalSection(&proto->modeMsgMutex); - return 0; -} - -int JabberGetInfo(PROTO_INTERFACE *ptr, HANDLE hContact, int infoType) -{ - DBVARIANT dbv; - int iqId; - char *nick, *pNick; - TlenProtocol *proto = (TlenProtocol *)ptr; - - if (!proto->isOnline) return 1; - if (hContact==NULL) { - iqId = JabberSerialNext(proto); - JabberIqAdd(proto, iqId, IQ_PROC_NONE, TlenIqResultVcard); - JabberSend(proto, "", iqId); - } else { - if (DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) return 1; - if ((nick=JabberNickFromJID(dbv.pszVal)) != NULL) { - if ((pNick=JabberTextEncode(nick)) != NULL) { - iqId = JabberSerialNext(proto); - JabberIqAdd(proto, iqId, IQ_PROC_NONE, TlenIqResultVcard); - JabberSend(proto, "%s", iqId, pNick); - mir_free(pNick); - } - mir_free(nick); - } - DBFreeVariant(&dbv); - } - return 0; -} - -int TlenSetApparentMode(PROTO_INTERFACE *ptr, HANDLE hContact, int mode) -{ - DBVARIANT dbv; - int oldMode; - char *jid; - TlenProtocol *proto = (TlenProtocol *)ptr; - - if (!proto->isOnline) return 0; - if (!DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "VisibilitySupport", FALSE)) return 0; - if (mode!=0 && mode!=ID_STATUS_ONLINE && mode!=ID_STATUS_OFFLINE) return 1; - oldMode = DBGetContactSettingWord(hContact, proto->iface.m_szModuleName, "ApparentMode", 0); - if ((int) mode == oldMode) return 1; - DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "ApparentMode", (WORD) mode); - if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { - jid = dbv.pszVal; - switch (mode) { - case ID_STATUS_ONLINE: - if (proto->iface.m_iStatus==ID_STATUS_INVISIBLE || oldMode==ID_STATUS_OFFLINE) - JabberSend(proto, "available", jid); - break; - case ID_STATUS_OFFLINE: - if (proto->iface.m_iStatus!=ID_STATUS_INVISIBLE || oldMode==ID_STATUS_ONLINE) - JabberSend(proto, "", jid); - break; - case 0: - if (oldMode==ID_STATUS_ONLINE && proto->iface.m_iStatus==ID_STATUS_INVISIBLE) - JabberSend(proto, "", jid); - else if (oldMode==ID_STATUS_OFFLINE && proto->iface.m_iStatus!=ID_STATUS_INVISIBLE) - JabberSend(proto, "available", jid); - break; - } - DBFreeVariant(&dbv); - } - return 0; -} - -typedef struct{ - TlenProtocol *proto; - HANDLE hContact; -} SENDACKTHREADDATA; - -static void __cdecl JabberSendMessageAckThread(void *ptr) -{ - SENDACKTHREADDATA *data = (SENDACKTHREADDATA *)ptr; - SleepEx(10, TRUE); - ProtoBroadcastAck(data->proto->iface.m_szModuleName, data->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE) 1, 0); - mir_free(data); -} - -static void __cdecl TlenSendMessageFailedThread(void *ptr) -{ - SENDACKTHREADDATA *data = (SENDACKTHREADDATA *)ptr; - SleepEx(10, TRUE); - ProtoBroadcastAck(data->proto->iface.m_szModuleName, data->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE) 2, 0); - mir_free(data); -} - -static void __cdecl TlenGetAwayMsgThread(void *ptr) -{ - DBVARIANT dbv; - JABBER_LIST_ITEM *item; - SENDACKTHREADDATA *data = (SENDACKTHREADDATA *)ptr; - if (!DBGetContactSetting(data->hContact, data->proto->iface.m_szModuleName, "jid", &dbv)) { - if ((item=JabberListGetItemPtr(data->proto, LIST_ROSTER, dbv.pszVal)) != NULL) { - DBFreeVariant(&dbv); - if (item->statusMessage != NULL) { - ProtoBroadcastAck(data->proto->iface.m_szModuleName, data->hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE) 1, (LPARAM) item->statusMessage); - return; - } - } - else { - DBFreeVariant(&dbv); - } - } - ProtoBroadcastAck(data->proto->iface.m_szModuleName, data->hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE) 1, (LPARAM) ""); - mir_free(data); -} - -INT_PTR TlenSendAlert(void *ptr, WPARAM wParam, LPARAM lParam) -{ - HANDLE hContact = ( HANDLE )wParam; - DBVARIANT dbv; - TlenProtocol *proto = (TlenProtocol *)ptr; - if (proto->isOnline && !DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { - JabberSend(proto, "", dbv.pszVal); - - DBFreeVariant(&dbv); - } - return 0; -} - - -int TlenSendMessage(PROTO_INTERFACE *ptr, HANDLE hContact, int flags, const char* msg) -{ - DBVARIANT dbv; - char *msgEnc; - JABBER_LIST_ITEM *item; - int id; - char msgType[16]; - TlenProtocol *proto = (TlenProtocol *)ptr; - - if (!proto->isOnline || DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { - SENDACKTHREADDATA *tdata = (SENDACKTHREADDATA*) mir_alloc(sizeof(SENDACKTHREADDATA)); - tdata->proto = proto; - tdata->hContact = hContact; - JabberForkThread(TlenSendMessageFailedThread, 0, (void *) tdata); - return 2; - } - if (!strcmp(msg, "")) { - SENDACKTHREADDATA *tdata = (SENDACKTHREADDATA*) mir_alloc(sizeof(SENDACKTHREADDATA)); - tdata->proto = proto; - tdata->hContact = hContact; - JabberSend(proto, "", dbv.pszVal); - JabberForkThread(JabberSendMessageAckThread, 0, (void *) tdata); - } else if (!strcmp(msg, "")) { - SENDACKTHREADDATA *tdata = (SENDACKTHREADDATA*) mir_alloc(sizeof(SENDACKTHREADDATA)); - tdata->proto = proto; - tdata->hContact = hContact; - id = JabberSerialNext(proto); - JabberSend(proto, "", dbv.pszVal, "pic", 0x757f044, id); - JabberForkThread(JabberSendMessageAckThread, 0, (void *) tdata); - } else { - if ((msgEnc=JabberTextEncode(msg)) != NULL) { - if (JabberListExist(proto, LIST_CHATROOM, dbv.pszVal) && strchr(dbv.pszVal, '/')==NULL) { - strcpy(msgType, "groupchat"); - } else if (DBGetContactSettingByte(hContact, proto->iface.m_szModuleName, "bChat", FALSE)) { - strcpy(msgType, "privchat"); - } else { - strcpy(msgType, "chat"); - } - if (!strcmp(msgType, "groupchat") || DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "MsgAck", FALSE) == FALSE) { - SENDACKTHREADDATA *tdata = (SENDACKTHREADDATA*) mir_alloc(sizeof(SENDACKTHREADDATA)); - tdata->proto = proto; - tdata->hContact = hContact; - if (!strcmp(msgType, "groupchat")) { - JabberSend(proto, "%s", dbv.pszVal, msgType, msgEnc); - } else if (!strcmp(msgType, "privchat")) { - JabberSend(proto, "%s", dbv.pszVal, msgEnc); - } else { - id = JabberSerialNext(proto); - JabberSend(proto, "%s", dbv.pszVal, msgType, id, msgEnc); - } - JabberForkThread(JabberSendMessageAckThread, 0, (void *) tdata); - } - else { - id = JabberSerialNext(proto); - if ((item=JabberListGetItemPtr(proto, LIST_ROSTER, dbv.pszVal)) != NULL) - item->idMsgAckPending = id; - JabberSend(proto, "%s", dbv.pszVal, msgType, id, msgEnc); - } - } - mir_free(msgEnc); - } - DBFreeVariant(&dbv); - return 1; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// JabberGetAvatarInfo - retrieves the avatar info - -static INT_PTR TlenGetAvatarInfo(void *ptr, WPARAM wParam, LPARAM lParam) -{ - BOOL downloadingAvatar = FALSE; - char *avatarHash = NULL; - JABBER_LIST_ITEM *item = NULL; - DBVARIANT dbv; - TlenProtocol *proto = (TlenProtocol *)ptr; - PROTO_AVATAR_INFORMATION* AI = ( PROTO_AVATAR_INFORMATION* )lParam; - if (!proto->tlenOptions.enableAvatars) return GAIR_NOAVATAR; - - if (AI->hContact != NULL) { - if (!DBGetContactSetting(AI->hContact, proto->iface.m_szModuleName, "jid", &dbv)) { - item = JabberListGetItemPtr(proto, LIST_ROSTER, dbv.pszVal); - DBFreeVariant(&dbv); - if (item != NULL) { - downloadingAvatar = item->newAvatarDownloading; - avatarHash = item->avatarHash; - } - } - } else { - if (proto->threadData != NULL) { - avatarHash = proto->threadData->avatarHash; - } - } - if ((avatarHash == NULL || avatarHash[0] == '\0') && !downloadingAvatar) { - return GAIR_NOAVATAR; - } - if (avatarHash != NULL && !downloadingAvatar) { - TlenGetAvatarFileName(proto, item, AI->filename, sizeof(AI->filename)); - AI->format = ( AI->hContact == NULL ) ? proto->threadData->avatarFormat : item->avatarFormat; - return GAIR_SUCCESS; - } - if (( wParam & GAIF_FORCE ) != 0 && AI->hContact != NULL && proto->isOnline) { - /* get avatar */ - return GAIR_WAITFOR; - } - return GAIR_NOAVATAR; -} - -HANDLE TlenGetAwayMsg(PROTO_INTERFACE *ptr, HANDLE hContact) -{ - TlenProtocol *proto = (TlenProtocol *)ptr; - SENDACKTHREADDATA *tdata = (SENDACKTHREADDATA*) mir_alloc(sizeof(SENDACKTHREADDATA)); - tdata->proto = proto; - tdata->hContact = hContact; - JabberForkThread((void (__cdecl *)(void*))TlenGetAwayMsgThread, 0, (void *) tdata); - return (HANDLE)1; -} - -HANDLE TlenFileAllow(PROTO_INTERFACE *ptr, HANDLE hContact, HANDLE hTransfer, const char* szPath) -{ - TLEN_FILE_TRANSFER *ft; - JABBER_LIST_ITEM *item; - char *nick; - TlenProtocol *proto = (TlenProtocol *)ptr; - - if (!proto->isOnline) return 0; - - ft = (TLEN_FILE_TRANSFER *) hTransfer; - ft->szSavePath = mir_strdup(szPath); - if ((item=JabberListAdd(proto, LIST_FILE, ft->iqId)) != NULL) { - item->ft = ft; - } - nick = JabberNickFromJID(ft->jid); - if (ft->newP2P) { - JabberSend(proto, "", ft->jid, ft->jid, ft->iqId); - } else { - JabberSend(proto, "", nick, ft->iqId); - } - mir_free(nick); - return (HANDLE)hTransfer; -} - -int TlenFileDeny(PROTO_INTERFACE *ptr, HANDLE hContact, HANDLE hTransfer, const char* szReason) -{ - TLEN_FILE_TRANSFER *ft; - char *nick; - TlenProtocol *proto = (TlenProtocol *)ptr; - - if (!proto->isOnline) return 1; - - ft = (TLEN_FILE_TRANSFER *) hTransfer; - nick = JabberNickFromJID(ft->jid); - if (ft->newP2P) { - JabberSend(proto, "", ft->iqId, nick);\ - } else { - JabberSend(proto, "", ft->iqId, nick);\ - } - mir_free(nick); - TlenP2PFreeFileTransfer(ft); - return 0; -} - -int TlenFileCancel(PROTO_INTERFACE *ptr, HANDLE hContact, HANDLE hTransfer) -{ - TLEN_FILE_TRANSFER *ft = (TLEN_FILE_TRANSFER *) hTransfer; - TlenProtocol *proto = (TlenProtocol *)ptr; - JabberLog(proto, "Invoking FileCancel()"); - if (ft->s != NULL) { - ft->state = FT_ERROR; - Netlib_CloseHandle(ft->s); - ft->s = NULL; - if (ft->hFileEvent != NULL) { - HANDLE hEvent = ft->hFileEvent; - ft->hFileEvent = NULL; - SetEvent(hEvent); - } - } else { - TlenP2PFreeFileTransfer(ft); - } - return 0; -} - -HANDLE TlenSendFile(PROTO_INTERFACE *ptr, HANDLE hContact, const char* szDescription, char** ppszFiles) -{ - TLEN_FILE_TRANSFER *ft; - int i, j; - struct _stat statbuf; - DBVARIANT dbv; - char *nick, *p, idStr[10]; - JABBER_LIST_ITEM *item; - int id; - TlenProtocol *proto = (TlenProtocol *)ptr; - - if (!proto->isOnline) return 0; -// if (DBGetContactSettingWord(ccs->hContact, iface.m_szModuleName, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE) return 0; - if (DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) return 0; - ft = TlenFileCreateFT(proto, dbv.pszVal); - for(ft->fileCount=0; ppszFiles[ft->fileCount]; ft->fileCount++); - ft->files = (char **) mir_alloc(sizeof(char *) * ft->fileCount); - ft->filesSize = (long *) mir_alloc(sizeof(long) * ft->fileCount); - ft->allFileTotalSize = 0; - for(i=j=0; ifileCount; i++) { - if (_stat(ppszFiles[i], &statbuf)) - JabberLog(proto, "'%s' is an invalid filename", ppszFiles[i]); - else { - ft->filesSize[j] = statbuf.st_size; - ft->files[j++] = mir_strdup(ppszFiles[i]); - ft->allFileTotalSize += statbuf.st_size; - } - } - ft->fileCount = j; - ft->szDescription = mir_strdup(szDescription); - ft->hContact = hContact; - ft->currentFile = 0; - DBFreeVariant(&dbv); - - id = JabberSerialNext(proto); - _snprintf(idStr, sizeof(idStr), "%d", id); - if ((item=JabberListAdd(proto, LIST_FILE, idStr)) != NULL) { - ft->iqId = mir_strdup(idStr); - nick = JabberNickFromJID(ft->jid); - item->ft = ft; - if (proto->tlenOptions.useNewP2P) { - JabberSend(proto, "", - ft->jid, ft->jid, idStr, ft->fileCount, ft->allFileTotalSize, ft->fileCount); - - ft->newP2P = TRUE; - } else { - if (ft->fileCount == 1) { - if ((p=strrchr(ppszFiles[0], '\\')) != NULL) - p++; - else - p = ppszFiles[0]; - p = JabberTextEncode(p); - JabberSend(proto, "", nick, p, idStr, ft->allFileTotalSize); - mir_free(p); - } - else - JabberSend(proto, "", nick, idStr, ft->fileCount, ft->allFileTotalSize); - } - mir_free(nick); - } - - return (HANDLE) ft; -} - -int TlenRecvMessage(PROTO_INTERFACE *ptr, HANDLE hContact, PROTORECVEVENT* evt) -{ - CCSDATA ccs = { hContact, PSR_MESSAGE, 0, ( LPARAM )evt }; - return CallService( MS_PROTO_RECVMSG, 0, ( LPARAM )&ccs ); -} - -int TlenRecvFile(PROTO_INTERFACE *ptr, HANDLE hContact, PROTORECVFILE* evt) -{ - CCSDATA ccs = { hContact, PSR_FILE, 0, ( LPARAM )evt }; - return CallService( MS_PROTO_RECVFILE, 0, ( LPARAM )&ccs ); -} - - -static char* settingToChar( DBCONTACTWRITESETTING* cws ) -{ - switch( cws->value.type ) { - case DBVT_ASCIIZ: - return mir_strdup( cws->value.pszVal ); - case DBVT_UTF8: - return mir_utf8decode(mir_strdup(cws->value.pszVal), NULL); - } - return NULL; -} - -int JabberDbSettingChanged(void *ptr, WPARAM wParam, LPARAM lParam) -{ - DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *) lParam; - TlenProtocol *proto = (TlenProtocol *)ptr; - // no action for hContact == NULL or when offline - if ((HANDLE) wParam == NULL) return 0; - if (!proto->isConnected) return 0; - - if (!strcmp(cws->szModule, "CList")) { - HANDLE hContact; - DBVARIANT dbv; - JABBER_LIST_ITEM *item; - char *szProto, *nick, *jid, *group; - - hContact = (HANDLE) wParam; - szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); - if (szProto==NULL || strcmp(szProto, proto->iface.m_szModuleName)) return 0; -// if (DBGetContactSettingByte(hContact, iface.m_szModuleName, "ChatRoom", 0) != 0) return 0; - // A contact's group is changed - if (!strcmp(cws->szSetting, "Group")) { - if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { - if ((item=JabberListGetItemPtr(proto, LIST_ROSTER, dbv.pszVal)) != NULL) { - DBFreeVariant(&dbv); - if (!DBGetContactSetting(hContact, "CList", "MyHandle", &dbv)) { - nick = JabberTextEncode(dbv.pszVal); - DBFreeVariant(&dbv); - } else if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "Nick", &dbv)) { - nick = JabberTextEncode(dbv.pszVal); - DBFreeVariant(&dbv); - } else { - nick = JabberNickFromJID(item->jid); - } - if (nick != NULL) { - // Note: we need to compare with item->group to prevent infinite loop - if (cws->value.type==DBVT_DELETED && item->group!=NULL) { - JabberLog(proto, "Group set to nothing"); - JabberSend(proto, "", nick, item->jid); - } else if (cws->value.pszVal != NULL) { - char *newGroup = settingToChar(cws); - if (item->group==NULL || strcmp(newGroup, item->group)) { - JabberLog(proto, "Group set to %s", newGroup); - if ((group=TlenGroupEncode(newGroup)) != NULL) { - JabberSend(proto, "%s", nick, item->jid, group); - mir_free(group); - } - } - mir_free(newGroup); - } - mir_free(nick); - } - } - else { - DBFreeVariant(&dbv); - } - } - } - // A contact is renamed - else if (!strcmp(cws->szSetting, "MyHandle")) { - char *newNick; - -// hContact = (HANDLE) wParam; -// szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); -// if (szProto==NULL || strcmp(szProto, iface.m_szModuleName)) return 0; - - if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { - jid = dbv.pszVal; - if ((item=JabberListGetItemPtr(proto, LIST_ROSTER, dbv.pszVal)) != NULL) { - if (cws->value.type == DBVT_DELETED) { - newNick = mir_strdup((char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_NOMYHANDLE)); - } else if (cws->value.pszVal!=NULL) { - newNick = settingToChar(cws); - } else { - newNick = NULL; - } - // Note: we need to compare with item->nick to prevent infinite loop - if (newNick!=NULL && (item->nick==NULL || (item->nick!=NULL && strcmp(item->nick, newNick)))) { - if ((nick=JabberTextEncode(newNick)) != NULL) { - JabberLog(proto, "Nick set to %s", newNick); - if (item->group!=NULL && (group=TlenGroupEncode(item->group))!=NULL) { - JabberSend(proto, "%s", nick, jid, group); - mir_free(group); - } else { - JabberSend(proto, "", nick, jid); - } - mir_free(nick); - } - } - if (newNick != NULL) mir_free(newNick); - } - DBFreeVariant(&dbv); - } - } - // A temporary contact has been added permanently - else if (!strcmp(cws->szSetting, "NotOnList")) { - char *jid, *nick, *pGroup; - - if (cws->value.type==DBVT_DELETED || (cws->value.type==DBVT_BYTE && cws->value.bVal==0)) { - if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { - jid = mir_strdup(dbv.pszVal); - DBFreeVariant(&dbv); - JabberLog(proto, "Add %s permanently to list", jid); - if (!DBGetContactSetting(hContact, "CList", "MyHandle", &dbv)) { - nick = JabberTextEncode(dbv.pszVal); //Utf8Encode - DBFreeVariant(&dbv); - } - else { - nick = JabberNickFromJID(jid); - } - if (nick != NULL) { - JabberLog(proto, "jid=%s nick=%s", jid, nick); - if (!DBGetContactSetting(hContact, "CList", "Group", &dbv)) { - if ((pGroup=TlenGroupEncode(dbv.pszVal)) != NULL) { - JabberSend(proto, "%s", nick, jid, pGroup); - JabberSend(proto, "", jid); - mir_free(pGroup); - } - DBFreeVariant(&dbv); - } - else { - JabberSend(proto, "", nick, jid); - JabberSend(proto, "", jid); - } - mir_free(nick); - DBDeleteContactSetting(hContact, "CList", "Hidden"); - } - mir_free(jid); - } - } - } - } - - return 0; -} - -int JabberContactDeleted(void *ptr, WPARAM wParam, LPARAM lParam) -{ - char *szProto; - DBVARIANT dbv; - TlenProtocol *proto = (TlenProtocol *)ptr; - - if(!proto->isOnline) // should never happen - return 0; - szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0); - if (szProto==NULL || strcmp(szProto, proto->iface.m_szModuleName)) - return 0; - if (!DBGetContactSetting((HANDLE) wParam, proto->iface.m_szModuleName, "jid", &dbv)) { - char *jid, *p, *q; - - jid = dbv.pszVal; - if ((p=strchr(jid, '@')) != NULL) { - if ((q=strchr(p, '/')) != NULL) - *q = '\0'; - } - if (JabberListExist(proto, LIST_ROSTER, jid)) { - // Remove from roster, server also handles the presence unsubscription process. - JabberSend(proto, "", jid); - } - - DBFreeVariant(&dbv); - } - return 0; -} - -int TlenUserIsTyping(PROTO_INTERFACE *ptr, HANDLE hContact, int type) -{ - DBVARIANT dbv; - JABBER_LIST_ITEM *item; - TlenProtocol *proto = (TlenProtocol *)ptr; - - if (!proto->isOnline) return 0; - if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { - if ((item=JabberListGetItemPtr(proto, LIST_ROSTER, dbv.pszVal))!=NULL /*&& item->wantComposingEvent==TRUE*/) { - switch (type) { - case PROTOTYPE_SELFTYPING_OFF: - JabberSend(proto, "", dbv.pszVal); - break; - case PROTOTYPE_SELFTYPING_ON: - JabberSend(proto, "", dbv.pszVal); - break; - } - } - DBFreeVariant(&dbv); - } - return 0; -} - -INT_PTR TlenGetMyAvatar(void *ptr, WPARAM wParam, LPARAM lParam) -{ - char* buf = ( char* )wParam; - int size = ( int )lParam; - TlenProtocol *proto = (TlenProtocol *)ptr; - - if ( buf == NULL || size <= 0 ) - return -1; - - TlenGetAvatarFileName( proto, NULL, buf, size ); - return 0; -} - -static INT_PTR CALLBACK TlenChangeAvatarDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam ) -{ - switch ( msg ) { - case WM_INITDIALOG: - TranslateDialogDefault( hwndDlg ); - { - HICON hIcon = GetIcolibIcon(IDI_TLEN); - SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) hIcon); - ReleaseIcolibIcon(hIcon); - } - CheckDlgButton(hwndDlg, IDC_PUBLICAVATAR, TRUE); - return TRUE; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - { - int result = LOWORD(wParam); - if (IsDlgButtonChecked(hwndDlg, IDC_PUBLICAVATAR)) { - result |= 0x10000; - } - EndDialog(hwndDlg, result); - } - return TRUE; - } - break; - } - return 0; -} - -INT_PTR TlenSetMyAvatar(void *ptr, WPARAM wParam, LPARAM lParam) -{ - char* szFileName = ( char* )lParam; - char tFileName[ MAX_PATH ]; - int fileIn; - TlenProtocol *proto = (TlenProtocol *)ptr; - if(!proto->isOnline) return 1; - if (szFileName != NULL) { - int result = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_USER_CHANGEAVATAR), NULL, TlenChangeAvatarDlgProc, (LPARAM) NULL); - TlenGetAvatarFileName( proto, NULL, tFileName, MAX_PATH); - if ( CopyFileA( szFileName, tFileName, FALSE ) == FALSE ) { - return 1; - } - fileIn = open( tFileName, O_RDWR | O_BINARY, S_IREAD | S_IWRITE ); - if ( fileIn != -1 ) { - long dwPngSize = filelength(fileIn); - BYTE* pResult = (BYTE *)mir_alloc(dwPngSize); - if (pResult != NULL) { - read( fileIn, pResult, dwPngSize ); - close( fileIn ); - TlenUploadAvatar(proto, pResult, dwPngSize, (result & 0x10000) != 0); - mir_free(pResult); - } - } - } else { - TlenRemoveAvatar(proto); - } - return 0; -} - -INT_PTR TlenGetAvatarCaps(void *ptr, WPARAM wParam, LPARAM lParam) -{ - TlenProtocol *proto = (TlenProtocol *)ptr; - switch (wParam) { - case AF_MAXSIZE: - { - POINT* size = (POINT*)lParam; - if ( size ) - size->x = size->y = 64; - } - return 0; - case AF_PROPORTION: - return PIP_SQUARE; - case AF_FORMATSUPPORTED: - return (lParam == PA_FORMAT_PNG) ? 1 : 0; - case AF_ENABLED: - return (proto->tlenOptions.enableAvatars && proto->isOnline) ? 1 : 0; - case AF_DONTNEEDDELAYS: - return 1; - case AF_MAXFILESIZE: - return 10 * 1024; - case AF_DELAYAFTERFAIL: - return 0; - } - return 0; -} - - -int TlenOnEvent( PROTO_INTERFACE *ptr, PROTOEVENTTYPE eventType, WPARAM wParam, LPARAM lParam ) -{ - TlenProtocol *proto = (TlenProtocol *)ptr; - switch( eventType ) { - case EV_PROTO_ONLOAD: return TlenOnModulesLoaded(proto, 0, 0 ); - case EV_PROTO_ONOPTIONS: return TlenOptionsInit(proto, wParam, lParam ); - case EV_PROTO_ONEXIT: return TlenPreShutdown(proto, 0, 0 ); - case EV_PROTO_ONRENAME: - { - CLISTMENUITEM clmi = { 0 }; - clmi.cbSize = sizeof( CLISTMENUITEM ); - clmi.flags = CMIM_NAME | CMIF_TCHAR; - clmi.ptszName = proto->iface.m_tszUserName; - CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )proto->hMenuRoot, ( LPARAM )&clmi ); - /* FIXME: Rename network user as well */ - } - } - return 1; -} - -// PSS_ADDED -int TlenAuthRecv(PROTO_INTERFACE *ptr, HANDLE hContact, PROTORECVEVENT* evt ) -{ - return 1; -} - -// PSS_AUTHREQUEST -int TlenAuthRequest(PROTO_INTERFACE *ptr, HANDLE hContact, const TCHAR* szMessage ) -{ - return 1; -} - -HANDLE TlenChangeInfo(PROTO_INTERFACE *ptr, int iInfoType, void* pInfoData ) -{ - return NULL; -} - -int TlenRecvContacts(PROTO_INTERFACE *ptr, HANDLE hContact, PROTORECVEVENT* evt) -{ - return 1; -} - - -extern INT_PTR CALLBACK TlenAccMgrUIDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -INT_PTR TlenAccMgrUI(void *ptr, WPARAM wParam, LPARAM lParam) -{ - return (INT_PTR) CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_ACCMGRUI), (HWND)lParam, TlenAccMgrUIDlgProc, (LPARAM) ptr); -} - -void TlenInitServicesVTbl(TlenProtocol *proto) { - char s[128]; - proto->iface.vtbl = (PROTO_INTERFACE_VTBL*) mir_alloc(sizeof(PROTO_INTERFACE_VTBL)); - proto->iface.vtbl->AddToList = TlenAddToList; - proto->iface.vtbl->AddToListByEvent = TlenAddToListByEvent; - proto->iface.vtbl->AuthDeny = TlenAuthDeny; - proto->iface.vtbl->AuthRecv = TlenAuthRecv; - proto->iface.vtbl->AuthRequest = TlenAuthRequest; - proto->iface.vtbl->Authorize = TlenAuthAllow; - proto->iface.vtbl->ChangeInfo = TlenChangeInfo; - proto->iface.vtbl->FileAllow = TlenFileAllow; - proto->iface.vtbl->FileCancel = TlenFileCancel; - proto->iface.vtbl->FileDeny = TlenFileDeny; - proto->iface.vtbl->FileResume = NULL; - proto->iface.vtbl->SearchBasic = TlenBasicSearch; - proto->iface.vtbl->SearchByEmail = TlenSearchByEmail; - proto->iface.vtbl->SearchByName = TlenSearchByName; - proto->iface.vtbl->SearchAdvanced = TlenSearchAdvanced; - proto->iface.vtbl->CreateExtendedSearchUI = TlenCreateAdvSearchUI; - - proto->iface.vtbl->RecvContacts = TlenRecvContacts; - proto->iface.vtbl->RecvFile = TlenRecvFile; - proto->iface.vtbl->RecvMsg = TlenRecvMessage; - proto->iface.vtbl->RecvUrl = NULL; - - proto->iface.vtbl->SendContacts = NULL; - proto->iface.vtbl->SendFile = TlenSendFile; - proto->iface.vtbl->SendMsg = TlenSendMessage; - proto->iface.vtbl->SendUrl = NULL; - - proto->iface.vtbl->GetCaps = TlenGetCaps; - proto->iface.vtbl->GetIcon = TlenGetIcon; - proto->iface.vtbl->GetInfo = JabberGetInfo; - proto->iface.vtbl->SetApparentMode = TlenSetApparentMode; - proto->iface.vtbl->SetStatus = TlenSetStatus; - - - proto->iface.vtbl->GetAwayMsg = TlenGetAwayMsg; - proto->iface.vtbl->RecvAwayMsg = NULL; - proto->iface.vtbl->SendAwayMsg = NULL; - proto->iface.vtbl->SetAwayMsg = TlenSetAwayMsg; - - proto->iface.vtbl->UserIsTyping = TlenUserIsTyping; - - proto->iface.vtbl->OnEvent = TlenOnEvent; - - sprintf(s, "%s%s", proto->iface.m_szModuleName, PS_GETNAME); - CreateServiceFunction_Ex(s, proto, TlenGetName); - - sprintf(s, "%s%s", proto->iface.m_szModuleName, PS_GETAVATARINFO); - CreateServiceFunction_Ex(s, proto, TlenGetAvatarInfo); - - sprintf(s, "%s%s", proto->iface.m_szModuleName, "/SendNudge"); - CreateServiceFunction_Ex(s, proto, TlenSendAlert); - - sprintf(s, "%s%s", proto->iface.m_szModuleName, PS_GETAVATARCAPS); - CreateServiceFunction_Ex(s, proto, TlenGetAvatarCaps); - - sprintf(s, "%s%s", proto->iface.m_szModuleName, PS_SETMYAVATAR); - CreateServiceFunction_Ex(s, proto, TlenSetMyAvatar); - - sprintf(s, "%s%s", proto->iface.m_szModuleName, PS_GETMYAVATAR); - CreateServiceFunction_Ex(s, proto, TlenGetMyAvatar); - - sprintf(s, "%s%s", proto->iface.m_szModuleName, PS_GETSTATUS); - CreateServiceFunction_Ex(s, proto, TlenGetStatus); - - sprintf(s, "%s%s", proto->iface.m_szModuleName, PS_CREATEACCMGRUI); - CreateServiceFunction_Ex(s, proto, TlenAccMgrUI); - -} - diff --git a/!NotAdopted/Tlen/jabber_thread.c b/!NotAdopted/Tlen/jabber_thread.c deleted file mode 100644 index b78cb1e9b5..0000000000 --- a/!NotAdopted/Tlen/jabber_thread.c +++ /dev/null @@ -1,1465 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" - -#include "commons.h" -#include "jabber_list.h" -#include "jabber_iq.h" -#include "resource.h" -#include "tlen_p2p_old.h" -#include "tlen_file.h" -#include "tlen_muc.h" -#include "tlen_voice.h" -#include "tlen_avatar.h" -#include "tlen_presence.h" -#include "tlen_picture.h" -#include -#include -#include - -extern void TlenProcessP2P(XmlNode *node, void *userdata); - -//static void __cdecl TlenProcessInvitation(struct ThreadData *info); -static void __cdecl JabberKeepAliveThread(void *ptr); -static void JabberProcessStreamOpening(XmlNode *node, ThreadData *info); -static void JabberProcessStreamClosing(XmlNode *node, ThreadData *info); -static void JabberProcessProtocol(XmlNode *node, ThreadData *info); -static void JabberProcessMessage(XmlNode *node, ThreadData *info); -static void JabberProcessIq(XmlNode *node, ThreadData *info); -static void TlenProcessW(XmlNode *node, ThreadData *info); -static void TlenProcessM(XmlNode *node, ThreadData *info); -static void TlenProcessN(XmlNode *node, ThreadData *info); -static void TlenProcessP(XmlNode *node, ThreadData *info); -static void TlenProcessV(XmlNode *node, ThreadData *info); -static void TlenProcessAvatar(XmlNode* node, ThreadData *info); -static void TlenProcessCipher(XmlNode *node, ThreadData *info); - -static VOID NTAPI JabberDummyApcFunc(ULONG_PTR param) -{ - return; -} - -static char onlinePassword[128]; -static HANDLE hEventPasswdDlg; - -static INT_PTR CALLBACK JabberPasswordDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - char text[128]; - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - sprintf(text, "%s %s", Translate("Enter password for"), (char *) lParam); - SetDlgItemTextA(hwndDlg, IDC_JID, text); - return TRUE; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - GetDlgItemTextA(hwndDlg, IDC_PASSWORD, onlinePassword, sizeof(onlinePassword)); - //EndDialog(hwndDlg, (int) onlinePassword); - //return TRUE; - // Fall through - case IDCANCEL: - //EndDialog(hwndDlg, 0); - SetEvent(hEventPasswdDlg); - DestroyWindow(hwndDlg); - return TRUE; - } - break; - } - - return FALSE; -} - -static VOID NTAPI JabberPasswordCreateDialogApcProc(ULONG_PTR param) -{ - CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_PASSWORD), NULL, JabberPasswordDlgProc, (LPARAM) param); -} - -void __cdecl JabberServerThread(ThreadData *info) -{ - DBVARIANT dbv; - char jidStr[128]; - char *connectHost; - char *buffer; - int datalen; - XmlState xmlState; - HANDLE hContact; - int jabberNetworkBufferSize; - int oldStatus = ID_STATUS_OFFLINE; - int reconnectMaxTime; - int numRetry; - int reconnectTime; - char *str; - CLISTMENUITEM clmi; - int loginErr = 0; - JabberLog(info->proto, "Thread started"); - - - // Normal server connection, we will fetch all connection parameters - // e.g. username, password, etc. from the database. - - if (info->proto->threadData != NULL) { - // Will not start another connection thread if a thread is already running. - // Make APC call to the main thread. This will immediately wake the thread up - // in case it is asleep in the reconnect loop so that it will immediately - // reconnect. - QueueUserAPC(JabberDummyApcFunc, info->proto->threadData->hThread, 0); - JabberLog(info->proto, "Thread ended, another normal thread is running"); - mir_free(info); - return; - } - - info->proto->threadData = info; - - if (!DBGetContactSetting(NULL, info->proto->iface.m_szModuleName, "LoginName", &dbv)) { - strncpy(info->username, dbv.pszVal, sizeof(info->username)); - info->username[sizeof(info->username)-1] = '\0'; - _strlwr(info->username); - DBWriteContactSettingString(NULL, info->proto->iface.m_szModuleName, "LoginName", info->username); - DBFreeVariant(&dbv); - - } else { - JabberLog(info->proto, "Thread ended, login name is not configured"); - loginErr = LOGINERR_BADUSERID; - } - - if (loginErr == 0) { - if (!DBGetContactSetting(NULL, info->proto->iface.m_szModuleName, "LoginServer", &dbv)) { - strncpy(info->server, dbv.pszVal, sizeof(info->server)); - info->server[sizeof(info->server)-1] = '\0'; - _strlwr(info->server); - DBWriteContactSettingString(NULL, info->proto->iface.m_szModuleName, "LoginServer", info->server); - DBFreeVariant(&dbv); - } else { - JabberLog(info->proto, "Thread ended, login server is not configured"); - loginErr = LOGINERR_NONETWORK; - } - } - - if (loginErr == 0) { - if (!info->proto->tlenOptions.savePassword) { - // Ugly hack: continue logging on only the return value is &(onlinePassword[0]) - // because if WM_QUIT while dialog box is still visible, p is returned with some - // exit code which may not be NULL. - // Should be better with modeless. - onlinePassword[0] = (char) -1; - hEventPasswdDlg = CreateEvent(NULL, FALSE, FALSE, NULL); - QueueUserAPC(JabberPasswordCreateDialogApcProc, hMainThread, (DWORD) jidStr); - WaitForSingleObject(hEventPasswdDlg, INFINITE); - CloseHandle(hEventPasswdDlg); - //if ((p=(char *)DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_PASSWORD), NULL, JabberPasswordDlgProc, (LPARAM) jidStr)) != onlinePassword) { - if (onlinePassword[0] != (char) -1) { - strncpy(info->password, onlinePassword, sizeof(info->password)); - info->password[sizeof(info->password)-1] = '\0'; - } else { - JabberLog(info->proto, "Thread ended, password request dialog was canceled"); - loginErr = LOGINERR_BADUSERID; - } - } else { - if (!DBGetContactSetting(NULL, info->proto->iface.m_szModuleName, "Password", &dbv)) { - CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); - strncpy(info->password, dbv.pszVal, sizeof(info->password)); - info->password[sizeof(info->password)-1] = '\0'; - DBFreeVariant(&dbv); - } else { - JabberLog(info->proto, "Thread ended, password is not configured"); - loginErr = LOGINERR_BADUSERID; - } - } - } - - jabberNetworkBufferSize = 2048; - if ((buffer=(char *) mir_alloc(jabberNetworkBufferSize+1)) == NULL) { // +1 is for '\0' when debug logging this buffer - JabberLog(info->proto, "Thread ended, network buffer cannot be allocated"); - loginErr = LOGINERR_NONETWORK; - } - - if (loginErr != 0) { - info->proto->threadData = NULL; - oldStatus = info->proto->iface.m_iStatus; - info->proto->iface.m_iStatus = ID_STATUS_OFFLINE; - ProtoBroadcastAck(info->proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->iface.m_iStatus); - ProtoBroadcastAck(info->proto->iface.m_szModuleName, NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, loginErr); - mir_free(info); - return; - } - - _snprintf(jidStr, sizeof(jidStr), "%s@%s", info->username, info->server); - DBWriteContactSettingString(NULL, info->proto->iface.m_szModuleName, "jid", jidStr); - - if (!DBGetContactSetting(NULL, info->proto->iface.m_szModuleName, "ManualHost", &dbv)) { - strncpy(info->manualHost, dbv.pszVal, sizeof(info->manualHost)); - info->manualHost[sizeof(info->manualHost)-1] = '\0'; - DBFreeVariant(&dbv); - } - info->port = DBGetContactSettingWord(NULL, info->proto->iface.m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT); - info->useEncryption = info->proto->tlenOptions.useEncryption; - - if (info->manualHost[0]) - connectHost = info->manualHost; - else - connectHost = info->server; - - JabberLog(info->proto, "Thread server='%s' port='%d'", connectHost, info->port); - - - if (!DBGetContactSetting(NULL, info->proto->iface.m_szModuleName, "AvatarHash", &dbv)) { - strcpy(info->proto->threadData->avatarHash, dbv.pszVal); - DBFreeVariant(&dbv); - } - info->avatarFormat = DBGetContactSettingDword(NULL, info->proto->iface.m_szModuleName, "AvatarFormat", PA_FORMAT_UNKNOWN); - - - reconnectMaxTime = 10; - numRetry = 0; - - for (;;) { // Reconnect loop - - info->s = JabberWsConnect(info->proto, connectHost, info->port); - if (info->s == NULL) { - JabberLog(info->proto, "Connection failed (%d)", WSAGetLastError()); - if (info->proto->threadData == info) { - oldStatus = info->proto->iface.m_iStatus; - info->proto->iface.m_iStatus = ID_STATUS_OFFLINE; - ProtoBroadcastAck(info->proto->iface.m_szModuleName, NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGINERR_NONETWORK); - ProtoBroadcastAck(info->proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->iface.m_iStatus); - if (info->proto->tlenOptions.reconnect == TRUE) { - reconnectTime = rand() % reconnectMaxTime; - JabberLog(info->proto, "Sleeping %d seconds before automatic reconnecting...", reconnectTime); - SleepEx(reconnectTime * 1000, TRUE); - if (reconnectMaxTime < 10*60) // Maximum is 10 minutes - reconnectMaxTime *= 2; - if (info->proto->threadData == info) { // Make sure this is still the active thread for the main Jabber connection - JabberLog(info->proto, "Reconnecting to the network..."); - if (numRetry < MAX_CONNECT_RETRIES) - numRetry++; - oldStatus = info->proto->iface.m_iStatus; - info->proto->iface.m_iStatus = ID_STATUS_CONNECTING + numRetry; - ProtoBroadcastAck(info->proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->iface.m_iStatus); - continue; - } - else { - JabberLog(info->proto, "Thread ended, connection failed"); - mir_free(buffer); - mir_free(info); - return; - } - } - info->proto->threadData = NULL; - } - JabberLog(info->proto, "Thread ended, connection failed"); - mir_free(buffer); - mir_free(info); - return; - } - - // Determine local IP - /* - socket = CallService(MS_NETLIB_GETSOCKET, (WPARAM) proto, 0); - struct sockaddr_in saddr; - int len; - - len = sizeof(saddr); - getsockname(socket, (struct sockaddr *) &saddr, &len); - jabberLocalIP = saddr.sin_addr.S_un.S_addr; - JabberLog("Local IP = %s", inet_ntoa(saddr.sin_addr)); - */ - - // User may change status to OFFLINE while we are connecting above - if (info->proto->iface.m_iDesiredStatus!=ID_STATUS_OFFLINE) { - - info->proto->isConnected = TRUE; - JabberForkThread(JabberKeepAliveThread, 0, info->proto); - - JabberXmlInitState(&xmlState); - JabberXmlSetCallback(&xmlState, 1, ELEM_OPEN, JabberProcessStreamOpening, info); - JabberXmlSetCallback(&xmlState, 1, ELEM_CLOSE, JabberProcessStreamClosing, info); - JabberXmlSetCallback(&xmlState, 2, ELEM_CLOSE, JabberProcessProtocol, info); - - info->useAES = FALSE; - - if (info->useEncryption) { - JabberSend(info->proto, ""); - - } else { - JabberSend(info->proto, ""); - } - - JabberLog(info->proto, "Entering main recv loop"); - datalen = 0; - - for (;;) { - int recvResult, bytesParsed; - - if (info->useAES) { - recvResult = JabberWsRecvAES(info->proto, buffer+datalen, jabberNetworkBufferSize-datalen, &info->aes_in_context, info->aes_in_iv); - } else { - recvResult = JabberWsRecv(info->proto, info->s, buffer+datalen, jabberNetworkBufferSize-datalen); - } - - if (recvResult <= 0) - break; - datalen += recvResult; - - buffer[datalen] = '\0'; - JabberLog(info->proto, "RECV:%s", buffer); - - bytesParsed = JabberXmlParse(&xmlState, buffer, datalen); - JabberLog(info->proto, "bytesParsed = %d", bytesParsed); - if (bytesParsed > 0) { - if (bytesParsed < datalen) - memmove(buffer, buffer+bytesParsed, datalen-bytesParsed); - datalen -= bytesParsed; - } - else if (datalen == jabberNetworkBufferSize) { - jabberNetworkBufferSize += 2048; - JabberLog(info->proto, "Increasing network buffer size to %d", jabberNetworkBufferSize); - if ((buffer=(char *) mir_realloc(buffer, jabberNetworkBufferSize+1)) == NULL) { - JabberLog(info->proto, "Cannot reallocate more network buffer, go offline now"); - break; - } - } - else { - JabberLog(info->proto, "Unknown state: bytesParsed=%d, datalen=%d, jabberNetworkBufferSize=%d", bytesParsed, datalen, jabberNetworkBufferSize); - } - } - - JabberXmlDestroyState(&xmlState); - - info->proto->isOnline = FALSE; - info->proto->isConnected = FALSE; - - memset(&clmi, 0, sizeof(CLISTMENUITEM)); - clmi.cbSize = sizeof(CLISTMENUITEM); - clmi.flags = CMIM_FLAGS | CMIF_GRAYED; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) info->proto->hMenuMUC, (LPARAM) &clmi); - if (info->proto->hMenuChats != NULL){ - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) info->proto->hMenuChats, (LPARAM) &clmi); - } - - // Set status to offline - oldStatus = info->proto->iface.m_iStatus; - info->proto->iface.m_iStatus = ID_STATUS_OFFLINE; - ProtoBroadcastAck(info->proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->iface.m_iStatus); - - // Set all contacts to offline - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - while (hContact != NULL) { - str = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); - if(str!=NULL && !strcmp(str, info->proto->iface.m_szModuleName)) { - if (DBGetContactSettingWord(hContact, info->proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) { - DBWriteContactSettingWord(hContact, info->proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE); - } - } - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); - } - - JabberListWipeSpecial(info->proto); - } - else { - oldStatus = info->proto->iface.m_iStatus; - info->proto->iface.m_iStatus = ID_STATUS_OFFLINE; - ProtoBroadcastAck(info->proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->iface.m_iStatus); - } - - Netlib_CloseHandle(info->s); - - if (info->proto->tlenOptions.reconnect==FALSE) - break; - - if (info->proto->threadData != info) // Make sure this is still the main Jabber connection thread - break; - reconnectTime = rand() % 10; - JabberLog(info->proto, "Sleeping %d seconds before automatic reconnecting...", reconnectTime); - SleepEx(reconnectTime * 1000, TRUE); - reconnectMaxTime = 20; - if (info->proto->threadData != info) // Make sure this is still the main Jabber connection thread - break; - JabberLog(info->proto, "Reconnecting to the network..."); - info->proto->iface.m_iDesiredStatus = oldStatus; // Reconnect to my last status - oldStatus = info->proto->iface.m_iStatus; - info->proto->iface.m_iStatus = ID_STATUS_CONNECTING; - numRetry = 1; - ProtoBroadcastAck(info->proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->iface.m_iStatus); - } - - JabberLog(info->proto, "Thread ended: server='%s'", info->server); - - if (info->proto->threadData==info) { - info->proto->threadData = NULL; - } - - mir_free(buffer); - if (info->streamId) mir_free(info->streamId); - JabberLog(info->proto, "Exiting ServerThread"); - mir_free(info); -} - -static void TlenSendAuth(TlenProtocol *proto) { - int iqId; - char *p; - char *str; - char text[128]; - str = TlenPasswordHash(proto->threadData->password); - sprintf(text, "%s%s", proto->threadData->streamId, str); - mir_free(str); - str = JabberSha1(text); - if ((p=JabberTextEncode(proto->threadData->username)) != NULL) { - iqId = JabberSerialNext(proto->threadData->proto); - JabberIqAdd(proto, iqId, IQ_PROC_NONE, JabberIqResultAuth); - JabberSend(proto, "%s%sttlen.pl", iqId, p /*info->username*/, str); - mir_free(p); - } - mir_free(str); -} - -static void JabberProcessStreamOpening(XmlNode *node, ThreadData *info) -{ - char *sid, *s; - - if (node->name==NULL || strcmp(node->name, "s")) - return; - - if ((sid=JabberXmlGetAttrValue(node, "i")) != NULL) { - if (info->streamId) mir_free(info->streamId); - info->streamId = mir_strdup(sid); - } - if ((s=JabberXmlGetAttrValue(node, "s")) != NULL && !strcmp(s, "1")) { - int i; - char *k1, *k2, *k3; - unsigned char aes_key[32]; - char aes_key_str[140], aes_iv_str[40]; - mpi k1_mpi, k2_mpi, aes_mpi; - size_t slen; - - k1=JabberXmlGetAttrValue(node, "k1"); - k2=JabberXmlGetAttrValue(node, "k2"); - k3=JabberXmlGetAttrValue(node, "k3"); - - memset(&info->aes_in_context, 0, sizeof (aes_context)); - memset(&info->aes_out_context, 0, sizeof (aes_context)); - memset(&aes_mpi, 0, sizeof (mpi)); - mpi_read_string(&aes_mpi, 16, k3); - mpi_write_binary(&aes_mpi, info->aes_in_iv, 16); - for (i = 0; i < 16; i++) { - info->aes_out_iv[i] = rand(); - aes_key[i] = rand(); - } - memset(&aes_mpi, 0, sizeof (mpi)); - mpi_read_binary(&aes_mpi, info->aes_out_iv, 16); - slen = 40; - mpi_write_string(&aes_mpi, 16, aes_iv_str, &slen); - aes_setkey_dec(&info->aes_in_context, aes_key, 128); - aes_setkey_enc(&info->aes_out_context, aes_key, 128); - memset(&aes_mpi, 0, sizeof (mpi)); - mpi_read_binary(&aes_mpi, aes_key, 16); - memset(&k1_mpi, 0, sizeof (mpi)); - mpi_read_string( &k1_mpi, 16, k1 ); - memset(&k2_mpi, 0, sizeof (mpi)); - mpi_read_string( &k2_mpi, 16, k2 ); - memset(&aes_mpi, 0, sizeof (mpi)); - mpi_read_binary(&aes_mpi, (unsigned char *)aes_key, 16); - mpi_exp_mod( &aes_mpi, &aes_mpi, &k1_mpi, &k2_mpi, NULL ); - slen = 140; - mpi_write_string(&aes_mpi, 16, aes_key_str, &slen); - JabberSend(info->proto, "", aes_key_str, aes_iv_str); - } else { - TlenSendAuth(info->proto); - } -} - -static void JabberProcessStreamClosing(XmlNode *node, ThreadData *info) -{ - Netlib_CloseHandle(info->proto); - if (node->name && !strcmp(node->name, "stream:error") && node->text) - MessageBoxA(NULL, Translate(node->text), Translate("Jabber Connection Error"), MB_OK|MB_ICONERROR|MB_SETFOREGROUND); -} - -static void JabberProcessProtocol(XmlNode *node, ThreadData *info) -{ - if (!strcmp(node->name, "message")) - JabberProcessMessage(node, info); - else if (!strcmp(node->name, "presence")) - TlenProcessPresence(node, info->proto); - else if (!strcmp(node->name, "iq")) - JabberProcessIq(node, info); - else if (!strcmp(node->name, "f")) - TlenProcessF(node, info); - else if (!strcmp(node->name, "w")) - TlenProcessW(node, info); - else if (!strcmp(node->name, "m")) - TlenProcessM(node, info); - else if (!strcmp(node->name, "n")) - TlenProcessN(node, info); - else if (!strcmp(node->name, "p")) - TlenProcessP(node, info); - else if (!strcmp(node->name, "v")) - TlenProcessV(node, info); - else if (!strcmp(node->name, "avatar")) - TlenProcessAvatar(node, info); - else if (!strcmp(node->name, "cipher")) - TlenProcessCipher(node, info); - else - JabberLog(info->proto, "Invalid top-level tag (only

and allowed)"); - -} - -static void TlenProcessCipher(XmlNode *node, ThreadData *info) -{ - char *type; - type=JabberXmlGetAttrValue(node, "type"); - info->useAES = TRUE; - JabberSend(info->proto, ""); - TlenSendAuth(info->proto); -} - -static void TlenProcessIqGetVersion(TlenProtocol *proto, XmlNode* node) -{ - OSVERSIONINFO osvi = { 0 }; - char mversion[256]; - char* from, *version, *mver; - char* os = NULL; - JABBER_LIST_ITEM *item; - - if (proto->iface.m_iStatus == ID_STATUS_INVISIBLE) return; - if (!proto->tlenOptions.enableVersion) return; - if (( from=JabberXmlGetAttrValue( node, "from" )) == NULL ) return; - if (( item=JabberListGetItemPtr( proto, LIST_ROSTER, from )) ==NULL) return; - version = JabberTextEncode( TLEN_VERSION_STRING ); - osvi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); - if ( GetVersionEx( &osvi )) { - switch ( osvi.dwPlatformId ) { - case VER_PLATFORM_WIN32_NT: - if ( osvi.dwMajorVersion == 5 ) { - if ( osvi.dwMinorVersion == 2 ) os = JabberTextEncode( Translate( "Windows Server 2003" )); - else if ( osvi.dwMinorVersion == 1 ) os = JabberTextEncode( Translate( "Windows XP" )); - else if ( osvi.dwMinorVersion == 0 ) os = JabberTextEncode( Translate( "Windows 2000" )); - } - else if ( osvi.dwMajorVersion <= 4 ) { - os = JabberTextEncode( Translate( "Windows NT" )); - } - break; - case VER_PLATFORM_WIN32_WINDOWS: - if ( osvi.dwMajorVersion == 4 ) { - if ( osvi.dwMinorVersion == 0 ) os = JabberTextEncode( Translate( "Windows 95" )); - if ( osvi.dwMinorVersion == 10 ) os = JabberTextEncode( Translate( "Windows 98" )); - if ( osvi.dwMinorVersion == 90 ) os = JabberTextEncode( Translate( "Windows ME" )); - } - break; - } } - - if ( os == NULL ) os = JabberTextEncode( Translate( "Windows" )); - - strcpy(mversion, "Miranda IM "); - CallService( MS_SYSTEM_GETVERSIONTEXT, sizeof( mversion ) - 11, ( LPARAM )mversion + 11 ); - strcat(mversion, " (Tlen v."); - strcat(mversion, TLEN_VERSION_STRING); - strcat(mversion, ")"); - mver = JabberTextEncode( mversion ); - JabberSend( proto, "%s%s%s", from, mver?mver:"", version?version:"", os?os:"" ); - if (!item->versionRequested) { - item->versionRequested = TRUE; - JabberSend(proto, "", from); - } - - if ( mver ) mir_free( mver ); - if ( version ) mir_free( version ); - if ( os ) mir_free( os ); -} - -// Support for Tlen avatars - avatar token used to access web interface -static void TlenProcessAvatar(XmlNode* node, ThreadData *info) -{ - XmlNode *tokenNode, *aNode; - tokenNode = JabberXmlGetChild(node, "token"); - aNode = JabberXmlGetChild(node, "a"); - if (tokenNode != NULL) { - char *token = tokenNode->text; - strcpy(info->avatarToken, token); - } - if (aNode != NULL) { - if (TlenProcessAvatarNode(info->proto, node, NULL)) { - } - } -} - -static void JabberProcessMessage(XmlNode *node, ThreadData *info) -{ - HANDLE hContact; - CCSDATA ccs; - PROTORECVEVENT recv; - XmlNode *bodyNode, *subjectNode, *xNode, *n; - char *from, *type, *nick, *p, *localMessage, *idStr; - DWORD msgTime; - BOOL delivered, composing; - int i; - JABBER_LIST_ITEM *item; - BOOL isChatRoomJid; - - if (!node->name || strcmp(node->name, "message")) return; - - if ((type=JabberXmlGetAttrValue(node, "type"))!=NULL && !strcmp(type, "error")) { - } - else { - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - char *fromJid = JabberLoginFromJID(from); - if (info->proto->tlenOptions.ignoreAdvertisements && strstr(from, "b73@tlen.pl") == from) { - return; - } - // If message is from a stranger (not in roster), item is NULL - item = JabberListGetItemPtr(info->proto, LIST_ROSTER, fromJid); - isChatRoomJid = JabberListExist(info->proto, LIST_CHATROOM, from); - - if (isChatRoomJid && type!=NULL && !strcmp(type, "groupchat")) { - //JabberGroupchatProcessMessage(node, userdata); - } else if (type!=NULL && !strcmp(type, "pic")) { - TlenProcessPic(node, info->proto); - } else if (type!=NULL && !strcmp(type, "iq")) { - XmlNode *iqNode; - // Jabber-compatible iq - if ((iqNode=JabberXmlGetChild(node, "iq")) != NULL) { - JabberXmlAddAttr(iqNode, "from", from); - JabberProcessIq(iqNode, info); - } - } else { - if ((bodyNode=JabberXmlGetChild(node, "body")) != NULL) { - if (bodyNode->text != NULL) { - if ((subjectNode=JabberXmlGetChild(node, "subject"))!=NULL && subjectNode->text!=NULL && subjectNode->text[0]!='\0') { - p = (char *) mir_alloc(strlen(subjectNode->text)+strlen(bodyNode->text)+5); - sprintf(p, "%s\r\n%s", subjectNode->text, bodyNode->text); - localMessage = JabberTextDecode(p); - mir_free(p); - } else { - localMessage = JabberTextDecode(bodyNode->text); - } - - msgTime = 0; - delivered = composing = FALSE; - i = 1; - while ((xNode=JabberXmlGetNthChild(node, "x", i)) != NULL) { - if ((p=JabberXmlGetAttrValue(xNode, "xmlns")) != NULL) { - if (!strcmp(p, "jabber:x:delay") && msgTime==0) { - if ((p=JabberXmlGetAttrValue(xNode, "stamp")) != NULL) { - msgTime = JabberIsoToUnixTime(p); - } - } - else if (!strcmp(p, "jabber:x:event")) { - // Check whether any event is requested - if (!delivered && (n=JabberXmlGetChild(xNode, "delivered"))!=NULL) { - delivered = TRUE; - idStr = JabberXmlGetAttrValue(node, "id"); - JabberSend(info->proto, "%s", from, (idStr!=NULL)?idStr:""); - } - if (item!=NULL && JabberXmlGetChild(xNode, "composing")!=NULL) { - composing = TRUE; - if (item->messageEventIdStr) - mir_free(item->messageEventIdStr); - idStr = JabberXmlGetAttrValue(node, "id"); - item->messageEventIdStr = (idStr==NULL)?NULL:mir_strdup(idStr); - } - } - } - i++; - } - - if (item != NULL) { - item->wantComposingEvent = composing; - if (item->isTyping) { - item->isTyping = FALSE; - if ((hContact=JabberHContactFromJID(info->proto, fromJid)) != NULL) - CallService(MS_PROTO_CONTACTISTYPING, (WPARAM) hContact, PROTOTYPE_CONTACTTYPING_OFF); - } - } - - if ((hContact=JabberHContactFromJID(info->proto, fromJid)) == NULL) { - // Create a temporary contact - if (isChatRoomJid) { - if ((p=strchr(from, '/'))!=NULL && p[1]!='\0') - p++; - else - p = from; - nick = JabberTextEncode(p); - hContact = JabberDBCreateContact(info->proto, from, nick, TRUE); - } - else { - nick = JabberLocalNickFromJID(from); - hContact = JabberDBCreateContact(info->proto, from, nick, TRUE); - } - mir_free(nick); - } - - if (msgTime == 0) { - msgTime = time(NULL); - } else { - HANDLE hDbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDLAST, (WPARAM) hContact, 0); - if (hDbEvent != NULL) { - DBEVENTINFO dbei = { 0 }; - dbei.cbSize = sizeof(dbei); - CallService(MS_DB_EVENT_GET, (WPARAM) hDbEvent, (LPARAM) &dbei); - if (msgTime < dbei.timestamp) { - msgTime = dbei.timestamp + 1; - } - } - if (msgTime > (DWORD)time(NULL)) { - msgTime = time(NULL); - } - } - recv.flags = 0; - recv.timestamp = (DWORD) msgTime; - recv.szMessage = localMessage; - recv.lParam = 0; - ccs.hContact = hContact; - ccs.wParam = 0; - ccs.szProtoService = PSR_MESSAGE; - ccs.lParam = (LPARAM) &recv; - CallService(MS_PROTO_CHAINRECV, 0, (LPARAM) &ccs); - - mir_free(localMessage); - } - } - } - mir_free(fromJid); - } - } -} - -static void JabberProcessIq(XmlNode *node, ThreadData *info) -{ - HANDLE hContact; - XmlNode *queryNode = NULL; - char *type, *jid, *nick; - char *xmlns = NULL; - char *idStr, *str; - int id; - int i; - JABBER_IQ_PFUNC pfunc; - - if (!node->name || strcmp(node->name, "iq")) return; - type=JabberXmlGetAttrValue(node, "type"); -// if ((type=JabberXmlGetAttrValue(node, "type")) == NULL) return; - - id = -1; - if ((idStr=JabberXmlGetAttrValue(node, "id")) != NULL) { - if (!strncmp(idStr, JABBER_IQID, strlen(JABBER_IQID))) - id = atoi(idStr+strlen(JABBER_IQID)); - } - - queryNode = JabberXmlGetChild(node, "query"); - if (queryNode != NULL) { - xmlns = JabberXmlGetAttrValue(queryNode, "xmlns"); - } - - - ///////////////////////////////////////////////////////////////////////// - // MATCH BY ID - ///////////////////////////////////////////////////////////////////////// - if ((pfunc=JabberIqFetchFunc(info->proto, id)) != NULL) { - JabberLog(info->proto, "Handling iq request for id=%d", id); - pfunc(info->proto, node); - ///////////////////////////////////////////////////////////////////////// - // MORE GENERAL ROUTINES, WHEN ID DOES NOT MATCH - ///////////////////////////////////////////////////////////////////////// - // new p2p connections - } else if (xmlns != NULL && !strcmp(xmlns, "p2p")) { - if (info->proto->tlenOptions.useNewP2P) { - TlenProcessP2P(node, info); - } - } - // RECVED: proto, " Got roster push, query has %d children", queryNode->numChild); - for (i=0; inumChild; i++) { - itemNode = queryNode->child[i]; - if (!strcmp(itemNode->name, "item")) { - if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { - if ((str=JabberXmlGetAttrValue(itemNode, "subscription")) != NULL) { - // we will not add new account when subscription=remove - if (!strcmp(str, "to") || !strcmp(str, "both") || !strcmp(str, "from") || !strcmp(str, "none")) { - if ((name=JabberXmlGetAttrValue(itemNode, "name")) != NULL) { - nick = JabberTextDecode(name); - } else { - nick = JabberLocalNickFromJID(jid); - } - if (nick != NULL) { - if ((item=JabberListAdd(info->proto, LIST_ROSTER, jid)) != NULL) { - if (item->nick) mir_free(item->nick); - item->nick = nick; - if ((hContact=JabberHContactFromJID(info->proto, jid)) == NULL) { - // Received roster has a new JID. - // Add the jid (with empty resource) to Miranda contact list. - hContact = JabberDBCreateContact(info->proto, jid, nick, FALSE); - } - DBWriteContactSettingString(hContact, "CList", "MyHandle", nick); - if (item->group) mir_free(item->group); - if ((groupNode=JabberXmlGetChild(itemNode, "group"))!=NULL && groupNode->text!=NULL) { - item->group = TlenGroupDecode(groupNode->text); - JabberContactListCreateGroup(item->group); - DBWriteContactSettingString(hContact, "CList", "Group", item->group); - } - else { - item->group = NULL; - DBDeleteContactSetting(hContact, "CList", "Group"); - } - if (!strcmp(str, "none") || (!strcmp(str, "from") && strchr(jid, '@')!=NULL)) { - if (DBGetContactSettingWord(hContact, info->proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) - DBWriteContactSettingWord(hContact, info->proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE); - } - } - else { - mir_free(nick); - } - } - } - if ((item=JabberListGetItemPtr(info->proto, LIST_ROSTER, jid)) != NULL) { - if (!strcmp(str, "both")) item->subscription = SUB_BOTH; - else if (!strcmp(str, "to")) item->subscription = SUB_TO; - else if (!strcmp(str, "from")) item->subscription = SUB_FROM; - else item->subscription = SUB_NONE; - JabberLog(info->proto, "Roster push for jid=%s, set subscription to %s", jid, str); - // subscription = remove is to remove from roster list - // but we will just set the contact to offline and not actually - // remove, so that history will be retained. - if (!strcmp(str, "remove")) { - if ((hContact=JabberHContactFromJID(info->proto, jid)) != NULL) { - if (DBGetContactSettingWord(hContact, info->proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) - DBWriteContactSettingWord(hContact, info->proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE); - JabberListRemove(info->proto, LIST_ROSTER, jid); - } - } - } - } - } - } - } - } - - } - // RECVED: proto, node); - } - // RECVED: proto, node); - } else if ( !strcmp( xmlns, "jabber:iq:version" )) { - TlenIqResultVersion(info->proto, node); - } else if ( !strcmp( xmlns, "jabber:iq:info" )) { - TlenIqResultInfo(info->proto, node); - } - } else { - char *from; - if (( from=JabberXmlGetAttrValue( node, "from" )) != NULL ) { - if ( !strcmp(from, "tcfg" )) { - TlenIqResultTcfg(info->proto, node); - } - } - } - } - // RECVED: ... - else if (!strcmp(type, "error")) { - JABBER_LIST_ITEM *item; - // Check for multi-user chat errors - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strstr(from, "@c")!=NULL || !strcmp(from, "c")) { - TlenMUCRecvError(info->proto, from, node); - return; - } - } - - // Check for file transfer deny by comparing idStr with ft->iqId - i = 0; - while ((i=JabberListFindNext(info->proto, LIST_FILE, i)) >= 0) { - item = JabberListGetItemPtrFromIndex(info->proto,i); - if (item->ft->state==FT_CONNECTING && !strcmp(idStr, item->ft->iqId)) { - item->ft->state = FT_DENIED; - if (item->ft->hFileEvent != NULL) - SetEvent(item->ft->hFileEvent); // Simulate the termination of file server connection - } - i++; - } - } - // RECVED: ... - else if (!strcmp(type, "1")) { // Chat groups list result - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strcmp(from, "c")==0) { - TlenIqResultChatGroups(info->proto, node); - } - } - } - else if (!strcmp(type, "2")) { // Chat rooms list result - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strcmp(from, "c")==0) { - TlenIqResultChatRooms(info->proto, node); - } - } - } else if (!strcmp(type, "3")) { // room search result - result to iq type 3 query - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strcmp(from, "c")==0) { - TlenIqResultRoomSearch(info->proto, node); - } - } - } else if (!strcmp(type, "4")) { // chat room users list - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strstr(from, "@c")!=NULL) { - TlenIqResultChatRoomUsers(info->proto, node); - } - } - } else if (!strcmp(type, "5")) { // room name & group & flags info - sent on joining the room - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strstr(from, "@c")!=NULL) { - TlenIqResultRoomInfo(info->proto, node); - } - } - } else if (!strcmp(type, "6")) { // new nick registered - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strcmp(from, "c")==0) { - TlenIqResultUserNicks(info->proto, node); - } - } - } else if (!strcmp(type, "7")) { // user nicknames list - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strcmp(from, "c")==0) { - TlenIqResultUserNicks(info->proto, node); - } - } - } else if (!strcmp(type, "8")) { // user chat rooms list - char *from; - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (strcmp(from, "c")==0) { - TlenIqResultUserRooms(info->proto, node); - } - } - } -} - -/* - * Web messages - */ -static void TlenProcessW(XmlNode *node, ThreadData *info) -{ - HANDLE hContact; - CCSDATA ccs; - PROTORECVEVENT recv; - char *f, *e, *s, *body; - char *str, *localMessage; - int strSize; - - if (!node->name || strcmp(node->name, "w")) return; - if ((body=node->text) == NULL) return; - - if ((f=JabberXmlGetAttrValue(node, "f")) != NULL) { - - char webContactName[128]; - sprintf(webContactName, Translate("%s Web Messages"), info->proto->iface.m_szProtoName); - if ((hContact=JabberHContactFromJID(info->proto, webContactName)) == NULL) { - hContact = JabberDBCreateContact(info->proto, webContactName, webContactName, TRUE); - } - - s = JabberXmlGetAttrValue(node, "s"); - e = JabberXmlGetAttrValue(node, "e"); - - str = NULL; - strSize = 0; - JabberStringAppend(&str, &strSize, "%s\r\n%s: ", Translate("Web message"), Translate("From")); - - if (f != NULL) - JabberStringAppend(&str, &strSize, "%s", f); - JabberStringAppend(&str, &strSize, "\r\n%s: ", Translate("E-mail")); - if (e != NULL) - JabberStringAppend(&str, &strSize, "%s", e); - JabberStringAppend(&str, &strSize, "\r\n\r\n%s", body); - - localMessage = JabberTextDecode(str); - - recv.flags = 0; - recv.timestamp = (DWORD) time(NULL); - recv.szMessage = localMessage; - recv.lParam = 0; - ccs.hContact = hContact; - ccs.wParam = 0; - ccs.szProtoService = PSR_MESSAGE; - ccs.lParam = (LPARAM) &recv; - CallService(MS_PROTO_CHAINRECV, 0, (LPARAM) &ccs); - - mir_free(localMessage); - mir_free(str); - } -} - -/* - * Typing notification, multi-user conference messages and invitations - */ -static void TlenProcessM(XmlNode *node, ThreadData *info) -{ - HANDLE hContact; - CCSDATA ccs; - PROTORECVEVENT recv; - char *f;//, *from;//username - char *tp;//typing start/stop - char *p, *n, *r, *s, *str, *localMessage; - int i; - XmlNode *xNode, *invNode, *bNode, *subjectNode; - - if (!node->name || strcmp(node->name, "m")) return; - - if ((f=JabberXmlGetAttrValue(node, "f")) != NULL) { - char *fLogin = JabberLoginFromJID(f); - if ((hContact=JabberHContactFromJID(info->proto, fLogin)) != NULL) { - if ((tp=JabberXmlGetAttrValue(node, "tp")) != NULL) { - JABBER_LIST_ITEM *item = JabberListGetItemPtr(info->proto, LIST_ROSTER, fLogin); - if(!strcmp(tp, "t")) { //contact is writing - if (item!=NULL ) { - item->isTyping = TRUE; - CallService(MS_PROTO_CONTACTISTYPING, (WPARAM)hContact, (LPARAM)PROTOTYPE_CONTACTTYPING_INFINITE); - } - } - else if(!strcmp(tp, "u")) {//contact stopped writing - if (item!=NULL) { - item->isTyping = FALSE; - CallService(MS_PROTO_CONTACTISTYPING, (WPARAM)hContact, (LPARAM)PROTOTYPE_CONTACTTYPING_OFF); - } - } - else if(!strcmp(tp, "a")) {//alert was received - int bAlert = TRUE; - if (info->proto->tlenOptions.alertPolicy == TLEN_ALERTS_IGNORE_ALL) { - bAlert = FALSE; - } else if (info->proto->tlenOptions.alertPolicy == TLEN_ALERTS_IGNORE_NIR) { - bAlert = IsAuthorized(info->proto, fLogin); - } - if (bAlert) { - if (info->proto->tlenOptions.useNudge) { - NotifyEventHooks(info->proto->hTlenNudge,(WPARAM) hContact,0); - } else { - if (info->proto->tlenOptions.logAlerts) { - TlenLogMessage(info->proto, hContact, 0, Translate("An alert has been received.")); - } - SkinPlaySound("TlenAlertNotify"); - } - } - } - } - } - mir_free(fLogin); - if ((p=strchr(f, '@')) != NULL) { - if ((p=strchr(p, '/'))!=NULL && p[1]!='\0') { // message from user - time_t timestamp; - s = JabberXmlGetAttrValue(node, "s"); - if (s != NULL) { - timestamp = TlenTimeToUTC(atol(s)); - if (timestamp > time(NULL)) { - timestamp = time(NULL); - } - } else { - timestamp = time(NULL); - } - tp=JabberXmlGetAttrValue(node, "tp"); - bNode = JabberXmlGetChild(node, "b"); - f = JabberTextDecode(f); - if (bNode != NULL && bNode->text != NULL) { - if (tp != NULL && !strcmp(tp, "p")) { - /* MUC private message */ - str = JabberResourceFromJID(f); - hContact = JabberDBCreateContact(info->proto, f, str, TRUE); - DBWriteContactSettingByte(hContact, info->proto->iface.m_szModuleName, "bChat", TRUE); - mir_free(str); - localMessage = JabberTextDecode(bNode->text); - recv.flags = 0; - recv.timestamp = (DWORD) timestamp; - recv.szMessage = localMessage; - recv.lParam = 0; - ccs.hContact = hContact; - ccs.wParam = 0; - ccs.szProtoService = PSR_MESSAGE; - ccs.lParam = (LPARAM) &recv; - CallService(MS_PROTO_CHAINRECV, 0, (LPARAM) &ccs); - mir_free(localMessage); - } else { - /* MUC message */ - TlenMUCRecvMessage(info->proto, f, timestamp, bNode); - } - } - mir_free(f); - } else { // message from chat room (system) - subjectNode = JabberXmlGetChild(node, "subject"); - if (subjectNode != NULL) { - f = JabberTextDecode(f); - localMessage = ""; - if (subjectNode->text!=NULL) { - localMessage = subjectNode->text; - } - localMessage = JabberTextDecode(localMessage); - TlenMUCRecvTopic(info->proto, f, localMessage); - mir_free(localMessage); - mir_free(f); - } - } - } - i=1; - while ((xNode=JabberXmlGetNthChild(node, "x", i)) != NULL) { - invNode=JabberXmlGetChild(xNode, "inv"); - if (invNode != NULL) { - r = JabberTextDecode(f); - f = JabberXmlGetAttrValue(invNode, "f"); - f = JabberTextDecode(f); - n = JabberXmlGetAttrValue(invNode, "n"); - if (n!=NULL && strstr(r, n)!=r) { - n = JabberTextDecode(n); - } else { - n = mir_strdup(Translate("Private conference")); - //n = JabberNickFromJID(r); - } - TlenMUCRecvInvitation(info->proto, r, n, f, ""); - mir_free(n); - mir_free(r); - mir_free(f); - break; - } - i++; - } - } -} - -static void TlenMailPopup(TlenProtocol *proto, char *title, char *emailInfo) -{ - POPUPDATAEX ppd; - char * lpzContactName; - char * lpzText; - - if (!DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "MailPopupEnabled", TRUE)) { - return; - } - lpzContactName = title; - lpzText = emailInfo; - ZeroMemory(&ppd, sizeof(ppd)); - ppd.lchContact = NULL; - ppd.lchIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_MAIL)); - strcpy(ppd.lpzContactName, lpzContactName); - strcpy(ppd.lpzText, lpzText); - ppd.colorBack = DBGetContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupBack", 0); - ppd.colorText = DBGetContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupText", 0); - ppd.PluginWindowProc = NULL; - ppd.PluginData=NULL; - if ( ServiceExists( MS_POPUP_ADDPOPUPEX )) { - BYTE delayMode; - int delay; - delayMode = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "MailPopupDelayMode", 0); - delay = 0; - if (delayMode==1) { - delay = DBGetContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupDelay", 4); - } else if (delayMode==2) { - delay = -1; - } - ppd.iSeconds = delay; - CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0); - - } - else if ( ServiceExists( MS_POPUP_ADDPOPUP )) { - CallService(MS_POPUP_ADDPOPUP, (WPARAM)&ppd, 0); - } -} -/* - * Incoming e-mail notification - */ -static void TlenProcessN(XmlNode *node, ThreadData *info) -{ - char *f, *s; - char *str, *popupTitle, *popupText; - int strSize; - - if (!node->name || strcmp(node->name, "n")) return; - - s = JabberXmlGetAttrValue(node, "s"); - f = JabberXmlGetAttrValue(node, "f"); - if (s != NULL && f!=NULL) { - str = NULL; - strSize = 0; - - JabberStringAppend(&str, &strSize, Translate("%s mail"), info->proto->iface.m_szProtoName); - popupTitle = JabberTextDecode(str); - mir_free(str); - - str = NULL; - strSize = 0; - - JabberStringAppend(&str, &strSize, "%s: %s\n", Translate("From"), f); - JabberStringAppend(&str, &strSize, "%s: %s", Translate("Subject"), s); - popupText = JabberTextDecode(str); - TlenMailPopup(info->proto, popupTitle, popupText); - SkinPlaySound("TlenMailNotify"); - - mir_free(popupTitle); - mir_free(popupText); - mir_free(str); - } -} - -/* - * Presence is chat rooms - */ -static void TlenProcessP(XmlNode *node, ThreadData *info) -{ - char jid[512]; - char *f, *id, *tp, *a, *n, *k; - XmlNode *sNode, *xNode, *iNode, *kNode; - int status, flags; - - if (!node->name || strcmp(node->name, "p")) return; - - // presence from users in chat room - flags = 0; - status = ID_STATUS_ONLINE; - f = JabberXmlGetAttrValue(node, "f"); - xNode = JabberXmlGetChild(node, "x"); - if (xNode != NULL) { // x subtag present (message from chat room) - change user rights only - char *temp, *iStr; - iNode = JabberXmlGetChild(xNode, "i"); - if (iNode != NULL) { - iStr = JabberXmlGetAttrValue(iNode, "i"); - temp = mir_alloc(strlen(f)+strlen(iStr)+2); - strcpy(temp, f); - strcat(temp, "/"); - strcat(temp, iStr); - f = JabberTextDecode(temp); - mir_free(temp); - node = iNode; - status = 0; - } else { - f = JabberTextDecode(f); - } - } else { - f = JabberTextDecode(f); - } - a = JabberXmlGetAttrValue(node, "z"); - if (a!=NULL) { - if (atoi(a) &1 ) { - flags |= USER_FLAGS_REGISTERED; - } - } - a = JabberXmlGetAttrValue(node, "a"); - if (a!=NULL) { - if (atoi(a) == 2) { - flags |= USER_FLAGS_ADMIN; - } - if (atoi(a) == 1) { - flags |= USER_FLAGS_OWNER; - } - if (atoi(a) == 3) { - //flags |= USER_FLAGS_MEMBER; - } - if (atoi(a) == 5) { - flags |= USER_FLAGS_GLOBALOWNER; - } - } - sNode = JabberXmlGetChild(node, "s"); - if (sNode != NULL) { - if (!strcmp(sNode->text, "unavailable")) { - status = ID_STATUS_OFFLINE; - } - } - kNode = JabberXmlGetChild(node, "kick"); - k = NULL; - if (kNode != NULL) { - k = JabberXmlGetAttrValue(kNode, "r"); - if (k==NULL) { - k = ""; - } - k = JabberTextDecode(k); - } - tp = JabberXmlGetAttrValue(node, "tp"); - if (tp!=NULL && !strcmp(tp, "c")) { // new chat room has just been created - id = JabberXmlGetAttrValue(node, "id"); - if (id != NULL) { - n = JabberXmlGetAttrValue(node, "n"); - if (n!=NULL) { - n = JabberTextDecode(n); - } else { - n = mir_strdup(Translate("Private conference"));// JabberNickFromJID(f); - } - sprintf(jid, "%s/%s", f, info->username); -// if (!DBGetContactSetting(NULL, iface.m_szModuleName, "LoginName", &dbv)) { - // always real username -// sprintf(jid, "%s/%s", f, dbv.pszVal); - TlenMUCCreateWindow(info->proto, f, n, 0, NULL, id); - TlenMUCRecvPresence(info->proto, jid, ID_STATUS_ONLINE, flags, k); -// DBFreeVariant(&dbv); -// } - mir_free(n); - } - } else { - TlenMUCRecvPresence(info->proto, f, status, flags, k); // user presence - } - if (k!=NULL) { - mir_free(k); - } - mir_free(f); -} -/* - * Voice chat - */ -static void TlenProcessV(XmlNode *node, ThreadData *info) -{ - char jid[128]; - JABBER_LIST_ITEM *item; - char *from, *id, *e, *p; -// if (!node->name || strcmp(node->name, "v")) return; - - if ((from=JabberXmlGetAttrValue(node, "f")) != NULL) { - if (strchr(from, '@') == NULL) { - _snprintf(jid, sizeof(jid), "%s@%s", from, info->server); - } else { - _snprintf(jid, sizeof(jid), "%s", from); - } - if ((e=JabberXmlGetAttrValue(node, "e")) != NULL) { - if (!strcmp(e, "1")) { - if ((id=JabberXmlGetAttrValue(node, "i")) != NULL) { - SkinPlaySound("TlenVoiceNotify"); - TlenVoiceAccept(info->proto, id, from); - } - } else if (!strcmp(e, "3")) { - // FILE_RECV : e='3' : invalid transfer error - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { - if (item->ft != NULL) { - HANDLE hEvent = item->ft->hFileEvent; - item->ft->hFileEvent = NULL; - item->ft->state = FT_ERROR; - if (item->ft->s != NULL) { - Netlib_CloseHandle(item->ft->s); - item->ft->s = NULL; - if (hEvent != NULL) { - SetEvent(hEvent); - } - } else { - TlenP2PFreeFileTransfer(item->ft); - } - } else { - JabberListRemove(info->proto, LIST_VOICE, p); - } - } - } - } else if (!strcmp(e, "4")) { - // FILE_SEND : e='4' : File sending request was denied by the remote client - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { - if (!strcmp(item->ft->jid, jid)) { - TlenVoiceCancelAll(info->proto); - //JabberListRemove(info->proto, LIST_VOICE, p); - } - } - } - } else if (!strcmp(e, "5")) { - // FILE_SEND : e='5' : Voice request was accepted - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { - JabberLog(info->proto, "should start voice 1 ? %s ?? %s", jid, item->ft->jid); - if (!strcmp(item->ft->jid, jid)) { - JabberLog(info->proto, "starting voice 1"); - TlenVoiceStart(item->ft, 1); - } - } - } - } else if (!strcmp(e, "6")) { - // FILE_RECV : e='6' : IP and port information to connect to get file - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { - if ((p=JabberXmlGetAttrValue(node, "a")) != NULL) { - item->ft->hostName = mir_strdup(p); - if ((p=JabberXmlGetAttrValue(node, "p")) != NULL) { - item->ft->wPort = atoi(p); - TlenVoiceStart(item->ft, 0); - //JabberForkThread((void (__cdecl *)(void*))TlenVoiceReceiveThread, 0, item->ft); - } - } - } - } - } - else if (!strcmp(e, "7")) { - // FILE_RECV : e='7' : IP and port information to connect to send file - // in case the conection to the given server was not successful - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { - if ((p=JabberXmlGetAttrValue(node, "a")) != NULL) { - if (item->ft->hostName!=NULL) mir_free(item->ft->hostName); - item->ft->hostName = mir_strdup(p); - if ((p=JabberXmlGetAttrValue(node, "p")) != NULL) { - item->ft->wPort = atoi(p); - item->ft->state = FT_SWITCH; - SetEvent(item->ft->hFileEvent); - } - } - } - } - } - else if (!strcmp(e, "8")) { - // FILE_RECV : e='8' : transfer error - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { - item->ft->state = FT_ERROR; - SetEvent(item->ft->hFileEvent); - } - } - } - - } - } -} - -static void __cdecl JabberKeepAliveThread(void *ptr) -{ - NETLIBSELECT nls = {0}; - - TlenProtocol *proto = (TlenProtocol *)ptr; - nls.cbSize = sizeof(NETLIBSELECT); - nls.dwTimeout = 60000; // 60000 millisecond (1 minute) - nls.hExceptConns[0] = proto->threadData->s; - for (;;) { - if (CallService(MS_NETLIB_SELECT, 0, (LPARAM) &nls) != 0) - break; - if (proto->tlenOptions.sendKeepAlive) - JabberSend(proto, " \t "); - } - JabberLog(proto, "Exiting KeepAliveThread"); -} - diff --git a/!NotAdopted/Tlen/jabber_util.c b/!NotAdopted/Tlen/jabber_util.c deleted file mode 100644 index 1caa390f10..0000000000 --- a/!NotAdopted/Tlen/jabber_util.c +++ /dev/null @@ -1,635 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include "jabber_list.h" -#include -#include - -HANDLE HookEventObj_Ex(const char *name, TlenProtocol *proto, MIRANDAHOOKOBJ hook) { - proto->hookNum ++; - proto->hHooks = (HANDLE *) mir_realloc(proto->hHooks, sizeof(HANDLE) * (proto->hookNum)); - proto->hHooks[proto->hookNum - 1] = HookEventObj(name, hook, proto); - return proto->hHooks[proto->hookNum - 1] ; -} - -HANDLE CreateServiceFunction_Ex(const char *name, TlenProtocol *proto, MIRANDASERVICEOBJ service) { - proto->serviceNum++; - proto->hServices = (HANDLE *) mir_realloc(proto->hServices, sizeof(HANDLE) * (proto->serviceNum)); - proto->hServices[proto->serviceNum - 1] = CreateServiceFunctionObj(name, service, proto); - return proto->hServices[proto->serviceNum - 1] ; -} - -void UnhookEvents_Ex(TlenProtocol *proto) { - unsigned int i; - for (i=0; ihookNum; ++i) { - if (proto->hHooks[i] != NULL) { - UnhookEvent(proto->hHooks[i]); - } - } - mir_free(proto->hHooks); - proto->hookNum = 0; - proto->hHooks = NULL; -} - -void DestroyServices_Ex(TlenProtocol *proto) { - unsigned int i; - for (i=0; iserviceNum; ++i) { - if (proto->hServices[i] != NULL) { - DestroyServiceFunction(proto->hServices[i]); - } - } - mir_free(proto->hServices); - proto->serviceNum = 0; - proto->hServices = NULL; -} - -void JabberSerialInit(TlenProtocol *proto) -{ - InitializeCriticalSection(&proto->csSerial); - proto->serial = 0; -} - -void JabberSerialUninit(TlenProtocol *proto) -{ - DeleteCriticalSection(&proto->csSerial); -} - -unsigned int JabberSerialNext(TlenProtocol *proto) -{ - unsigned int ret; - - EnterCriticalSection(&proto->csSerial); - ret = proto->serial; - proto->serial++; - LeaveCriticalSection(&proto->csSerial); - return ret; -} - -void JabberLog(TlenProtocol *proto, const char *fmt, ...) -{ -#ifdef ENABLE_LOGGING - char *str; - va_list vararg; - int strsize; - char *text; - char *p, *q; - int extra; - - va_start(vararg, fmt); - str = (char *) mir_alloc(strsize=2048); - while (_vsnprintf(str, strsize, fmt, vararg) == -1) - str = (char *) mir_realloc(str, strsize+=2048); - va_end(vararg); - - extra = 0; - for (p=str; *p!='\0'; p++) - if (*p=='\n' || *p=='\r') - extra++; - text = (char *) mir_alloc(strlen("TLEN")+2+strlen(str)+2+extra); - sprintf(text, "[%s]", "TLEN"); - for (p=str,q=text+strlen(text); *p!='\0'; p++,q++) { - if (*p == '\r') { - *q = '\\'; - *(q+1) = 'r'; - q++; - } - else if (*p == '\n') { - *q = '\\'; - *(q+1) = 'n'; - q++; - } - else - *q = *p; - } - *q = '\n'; - *(q+1) = '\0'; - if (proto->hNetlibUser!=NULL) { - CallService(MS_NETLIB_LOG, (WPARAM) proto->hNetlibUser, (LPARAM) text); - } - //OutputDebugString(text); - mir_free(text); - mir_free(str); -#endif -} - -// Caution: DO NOT use JabberSend() to send binary (non-string) data -int JabberSend(TlenProtocol *proto, const char *fmt, ...) -{ - char *str; - int size; - va_list vararg; - int result = 0; - - EnterCriticalSection(&proto->csSend); - - va_start(vararg,fmt); - size = 512; - str = (char *) mir_alloc(size); - while (_vsnprintf(str, size, fmt, vararg) == -1) { - size += 512; - str = (char *) mir_realloc(str, size); - } - va_end(vararg); - - JabberLog(proto, "SEND:%s", str); - size = (int)strlen(str); - if (proto->threadData != NULL) { - if (proto->threadData->useAES) { - result = JabberWsSendAES(proto, str, size, &proto->threadData->aes_out_context, proto->threadData->aes_out_iv); - } else { - result = JabberWsSend(proto, proto->threadData->s, str, size); - } - } - LeaveCriticalSection(&proto->csSend); - - mir_free(str); - return result; -} - - -char *JabberResourceFromJID(const char *jid) -{ - char *p; - char *nick; - - p=strchr(jid, '/'); - if (p != NULL && p[1]!='\0') { - p++; - if ((nick=(char *) mir_alloc(1+strlen(jid)-(p-jid))) != NULL) { - strncpy(nick, p, strlen(jid)-(p-jid)); - nick[strlen(jid)-(p-jid)] = '\0'; - } - } - else { - nick = mir_strdup(jid); - } - - return nick; -} - -char *JabberNickFromJID(const char *jid) -{ - char *p; - char *nick; - - if ((p=strchr(jid, '@')) == NULL) - p = strchr(jid, '/'); - if (p != NULL) { - if ((nick=(char *) mir_alloc((p-jid)+1)) != NULL) { - strncpy(nick, jid, p-jid); - nick[p-jid] = '\0'; - } - } - else { - nick = mir_strdup(jid); - } - - return nick; -} - -char *JabberLoginFromJID(const char *jid) -{ - char *p; - char *nick; - - p = strchr(jid, '/'); - if (p != NULL) { - if ((nick=(char *) mir_alloc((p-jid)+1)) != NULL) { - strncpy(nick, jid, p-jid); - nick[p-jid] = '\0'; - } - } - else { - nick = mir_strdup(jid); - } - return nick; -} - -char *JabberLocalNickFromJID(const char *jid) -{ - char *p; - char *localNick; - - p = JabberNickFromJID(jid); - localNick = JabberTextDecode(p); - mir_free(p); - return localNick; -} - -char *JabberSha1(char *str) -{ - mir_sha1_ctx sha; - DWORD digest[5]; - char* result; - - if ( str == NULL ) - return NULL; - - mir_sha1_init( &sha ); - mir_sha1_append( &sha, (mir_sha1_byte_t* )str, (int)strlen( str )); - mir_sha1_finish( &sha, (mir_sha1_byte_t* )digest ); - if ((result=(char *)mir_alloc(41)) == NULL) - return NULL; - sprintf(result, "%08x%08x%08x%08x%08x", (int)htonl(digest[0]), (int)htonl(digest[1]), (int)htonl(digest[2]), (int)htonl(digest[3]), (int)htonl(digest[4])); - return result; -} - -char *TlenSha1(char *str, int len) -{ - mir_sha1_ctx sha; - mir_sha1_byte_t digest[20]; - char* result; - int i; - - if ( str == NULL ) - return NULL; - - mir_sha1_init( &sha ); - mir_sha1_append( &sha, (mir_sha1_byte_t* )str, len); - mir_sha1_finish( &sha, digest ); - if (( result=( char* )mir_alloc( 20 )) == NULL ) - return NULL; - for (i=0; i<20; i++) - result[i]=digest[4*(i>>2)+(3-(i&0x3))]; - return result; -} - -char *TlenPasswordHash(const char *str) -{ - int magic1 = 0x50305735, magic2 = 0x12345671, sum = 7; - char *p, *res; - - if (str == NULL) return NULL; - for (p=(char *)str; *p!='\0'; p++) { - if (*p!=' ' && *p!='\t') { - magic1 ^= (((magic1 & 0x3f) + sum) * ((char) *p)) + (magic1 << 8); - magic2 += (magic2 << 8) ^ magic1; - sum += ((char) *p); - } - } - magic1 &= 0x7fffffff; - magic2 &= 0x7fffffff; - res = (char *) mir_alloc(17); - sprintf(res, "%08x%08x", magic1, magic2); - return res; -} - -char *TlenUrlEncode(const char *str) -{ - char *p, *q, *res; - unsigned char c; - - if (str == NULL) return NULL; - res = (char *) mir_alloc(3*strlen(str) + 1); - for (p=(char *)str,q=res; *p!='\0'; p++,q++) { - if (*p == ' ') { - *q = '+'; - } - else if (*p<0x20 || *p>=0x7f || strchr("%&+:'<>\"", *p)!=NULL) { - // Convert first from CP1252 to ISO8859-2 - switch ((unsigned char) *p) { - case 0xa5: c = (unsigned char) 0xa1; break; - case 0x8c: c = (unsigned char) 0xa6; break; - case 0x8f: c = (unsigned char) 0xac; break; - case 0xb9: c = (unsigned char) 0xb1; break; - case 0x9c: c = (unsigned char) 0xb6; break; - case 0x9f: c = (unsigned char) 0xbc; break; - default: c = (unsigned char) *p; break; - } - sprintf(q, "%%%02X", c); - q += 2; - } - else { - *q = *p; - } - } - *q = '\0'; - return res; -} - -void TlenUrlDecode(char *str) -{ - char *p, *q; - unsigned int code; - - if (str == NULL) return; - for (p=q=str; *p!='\0'; p++,q++) { - if (*p == '+') { - *q = ' '; - } - else if (*p=='%' && *(p+1)!='\0' && isxdigit(*(p+1)) && *(p+2)!='\0' && isxdigit(*(p+2))) { - sscanf(p+1, "%2x", &code); - *q = (char) code; - // Convert from ISO8859-2 to CP1252 - switch ((unsigned char) *q) { - case 0xa1: *q = (char) 0xa5; break; - case 0xa6: *q = (char) 0x8c; break; - case 0xac: *q = (char) 0x8f; break; - case 0xb1: *q = (char) 0xb9; break; - case 0xb6: *q = (char) 0x9c; break; - case 0xbc: *q = (char) 0x9f; break; - } - p += 2; - } - else { - *q = *p; - } - } - *q = '\0'; -} - -char * TlenGroupDecode(const char *str) -{ - char *p, *q; - if (str == NULL) return NULL; - p = q = JabberTextDecode(str); - for (; *p!='\0'; p++) { - if (*p == '/') { - *p = '\\'; - } - } - return q; -} - -char * TlenGroupEncode(const char *str) -{ - char *p, *q; - if (str == NULL) return NULL; - p = q = mir_strdup(str); - for (; *p!='\0'; p++) { - if (*p == '\\') { - *p = '/'; - } - } - p = JabberTextEncode(q); - mir_free(q); - return p; -} - -char *JabberTextEncode(const char *str) -{ - char *s1; - - if (str == NULL) return NULL; - if ((s1=TlenUrlEncode(str)) == NULL) - return NULL; - return s1; -} - -char *JabberTextDecode(const char *str) -{ - char *s1; - - if (str == NULL) return NULL; - s1 = mir_strdup(str); - TlenUrlDecode(s1); - return s1; -} - -static char b64table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -char *JabberBase64Encode(const char *buffer, int bufferLen) -{ - int n; - unsigned char igroup[3]; - char *p, *peob; - char *res, *r; - - if (buffer==NULL || bufferLen<=0) return NULL; - if ((res=(char *) mir_alloc((((bufferLen+2)/3)*4) + 1)) == NULL) return NULL; - - for (p=(char*)buffer,peob=p+bufferLen,r=res; p= peob) break; - igroup[n] = (unsigned char) *p; - p++; - } - if (n > 0) { - r[0] = b64table[ igroup[0]>>2 ]; - r[1] = b64table[ ((igroup[0]&3)<<4) | (igroup[1]>>4) ]; - r[2] = b64table[ ((igroup[1]&0xf)<<2) | (igroup[2]>>6) ]; - r[3] = b64table[ igroup[2]&0x3f ]; - if (n < 3) { - r[3] = '='; - if (n < 2) - r[2] = '='; - } - r += 4; - } - } - *r = '\0'; - - return res; -} - -static unsigned char b64rtable[256]; - -char *JabberBase64Decode(const char *str, int *resultLen) -{ - char *res; - unsigned char *p, *r, igroup[4], a[4]; - int n, num, count; - - if (str==NULL || resultLen==NULL) return NULL; - if ((res=(char *) mir_alloc(((strlen(str)+3)/4)*3)) == NULL) return NULL; - - for (n=0; n<256; n++) - b64rtable[n] = (unsigned char) 0x80; - for (n=0; n<26; n++) - b64rtable['A'+n] = n; - for (n=0; n<26; n++) - b64rtable['a'+n] = n + 26; - for (n=0; n<10; n++) - b64rtable['0'+n] = n + 52; - b64rtable['+'] = 62; - b64rtable['/'] = 63; - b64rtable['='] = 0; - count = 0; - for (p=(unsigned char *)str,r=(unsigned char *)res; *p!='\0';) { - for (n=0; n<4; n++) { - if ( *p == '\r' || *p == '\n' ) { - n--; p++; - continue; - } - - if ( *p=='\0' ) { - if ( n == 0 ) - goto LBL_Exit; - mir_free( res ); - return NULL; - } - - if ( b64rtable[*p]==0x80 ) { - mir_free( res ); - return NULL; - } - - a[n] = *p; - igroup[n] = b64rtable[*p]; - p++; - } - r[0] = igroup[0]<<2 | igroup[1]>>4; - r[1] = igroup[1]<<4 | igroup[2]>>2; - r[2] = igroup[2]<<6 | igroup[3]; - r += 3; - num = ( a[2]=='='?1:( a[3]=='='?2:3 )); - count += num; - if ( num < 3 ) break; - } -LBL_Exit: - *resultLen = count; - return res; -} - -/* - * Apply Polish Daylight Saving Time rules to get "DST-unbiased" timestamp - */ - -time_t TlenTimeToUTC(time_t time) { - struct tm *timestamp; - timestamp = gmtime(&time); - if ( (timestamp->tm_mon > 2 && timestamp->tm_mon < 9) || - (timestamp->tm_mon == 2 && timestamp->tm_mday - timestamp->tm_wday >= 25) || - (timestamp->tm_mon == 9 && timestamp->tm_mday - timestamp->tm_wday < 25)) { - //time -= 3600; - } else { - //time += 3600; - } - return time; -} - -time_t JabberIsoToUnixTime(char *stamp) -{ - struct tm timestamp; - char date[9]; - char *p; - int i, y; - time_t t; - - if (stamp == NULL) return (time_t) 0; - - p = stamp; - - // Get the date part - for (i=0; *p!='\0' && i<8 && isdigit(*p); p++,i++) - date[i] = *p; - - // Parse year - if (i == 6) { - // 2-digit year (1970-2069) - y = (date[0]-'0')*10 + (date[1]-'0'); - if (y < 70) y += 100; - } - else if (i == 8) { - // 4-digit year - y = (date[0]-'0')*1000 + (date[1]-'0')*100 + (date[2]-'0')*10 + date[3]-'0'; - y -= 1900; - } - else - return (time_t) 0; - timestamp.tm_year = y; - // Parse month - timestamp.tm_mon = (date[i-4]-'0')*10 + date[i-3]-'0' - 1; - // Parse date - timestamp.tm_mday = (date[i-2]-'0')*10 + date[i-1]-'0'; - - // Skip any date/time delimiter - for (; *p!='\0' && !isdigit(*p); p++); - - // Parse time - if (sscanf(p, "%d:%d:%d", &(timestamp.tm_hour), &(timestamp.tm_min), &(timestamp.tm_sec)) != 3) - return (time_t) 0; - - timestamp.tm_isdst = 0; // DST is already present in _timezone below - _tzset(); - t = mktime(×tamp); - t -= _timezone; - t = TlenTimeToUTC(t); - - if (t >= 0) - return t; - else - return (time_t) 0; -} - -void JabberStringAppend(char **str, int *sizeAlloced, const char *fmt, ...) -{ - va_list vararg; - char *p; - int size, len; - - if (str == NULL) return; - - if (*str==NULL || *sizeAlloced<=0) { - *sizeAlloced = size = 2048; - *str = (char *) mir_alloc(size); - len = 0; - } - else { - len = (int)strlen(*str); - size = *sizeAlloced - (int)strlen(*str); - } - - p = *str + len; - va_start(vararg, fmt); - while (_vsnprintf(p, size, fmt, vararg) == -1) { - size += 2048; - (*sizeAlloced) += 2048; - *str = (char *) mir_realloc(*str, *sizeAlloced); - p = *str + len; - } - va_end(vararg); -} - -int JabberGetPictureType( const char* buf ) -{ - if ( buf != NULL ) { - if ( memcmp( buf, "GIF89", 5 ) == 0 ) return PA_FORMAT_GIF; - if ( memcmp( buf, "\x89PNG", 4 ) == 0 ) return PA_FORMAT_PNG; - if ( memcmp( buf, "BM", 2 ) == 0 ) return PA_FORMAT_BMP; - if ( memcmp( buf, "\xFF\xD8", 2 ) == 0 ) return PA_FORMAT_JPEG; - } - return PA_FORMAT_UNKNOWN; -} - -BOOL IsAuthorized(TlenProtocol *proto, const char *jid) -{ - JABBER_LIST_ITEM *item = JabberListGetItemPtr(proto, LIST_ROSTER, jid); - if (item != NULL) { - return item->subscription == SUB_BOTH || item->subscription == SUB_FROM; - } - return FALSE; -} - - -void TlenLogMessage(TlenProtocol *proto, HANDLE hContact, DWORD flags, const char *message) -{ - int size = (int)strlen(message) + 2; - char *localMessage = (char *)mir_alloc(size); - strcpy(localMessage, message); - localMessage[size - 1] = '\0'; - JabberDBAddEvent(proto, hContact, EVENTTYPE_MESSAGE, flags, (PBYTE)message, (DWORD)size); - mir_free(localMessage); -} diff --git a/!NotAdopted/Tlen/jabber_ws.c b/!NotAdopted/Tlen/jabber_ws.c deleted file mode 100644 index 49599fa0e3..0000000000 --- a/!NotAdopted/Tlen/jabber_ws.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" - -BOOL JabberWsInit(TlenProtocol *proto) -{ - NETLIBUSER nlu = {0}; - NETLIBUSERSETTINGS nlus = {0}; - TCHAR name[128]; - - - nlu.cbSize = sizeof(nlu); - nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_HTTPCONNS | NUF_TCHAR; // | NUF_HTTPGATEWAY; - mir_sntprintf( name, SIZEOF(name), TranslateT("%s connection"), proto->iface.m_tszUserName); - nlu.ptszDescriptiveName = name; - nlu.szSettingsModule = proto->iface.m_szModuleName; - proto->hNetlibUser = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) &nlu); - - nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_NOOPTIONS | NUF_TCHAR; - mir_sntprintf( name, SIZEOF(name), TranslateT("%s SOCKS connection"), proto->iface.m_tszUserName); - nlu.ptszDescriptiveName = name; - proto->hFileNetlibUser = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) &nlu); - nlus.cbSize = sizeof(nlus); - nlus.useProxy = 0; - CallService(MS_NETLIB_SETUSERSETTINGS, (WPARAM) proto->hFileNetlibUser, (LPARAM) &nlus); - - return (proto->hNetlibUser!=NULL)?TRUE:FALSE; -} - -void JabberWsUninit(TlenProtocol *proto) -{ - if (proto->hNetlibUser!=NULL) Netlib_CloseHandle(proto->hNetlibUser); - if (proto->hFileNetlibUser!=NULL) Netlib_CloseHandle(proto->hFileNetlibUser); - proto->hNetlibUser = NULL; - proto->hFileNetlibUser = NULL; -} - -JABBER_SOCKET JabberWsConnect(TlenProtocol *proto, char *host, WORD port) -{ - NETLIBOPENCONNECTION nloc = {0}; - - nloc.cbSize = sizeof(NETLIBOPENCONNECTION); //NETLIBOPENCONNECTION_V1_SIZE; - nloc.szHost = host; - nloc.wPort = port; - nloc.flags = 0; - nloc.timeout = 6; - return (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, (WPARAM) proto->hNetlibUser, (LPARAM) &nloc); -} - -int JabberWsSend(TlenProtocol *proto, JABBER_SOCKET s, char *data, int datalen) -{ - int len; - if ((len=Netlib_Send(s, data, datalen, /*MSG_NODUMP|*/MSG_DUMPASTEXT))==SOCKET_ERROR || len!=datalen) { - JabberLog(proto, "Netlib_Send() failed, error=%d", WSAGetLastError()); - return FALSE; - } - return TRUE; -} - -int JabberWsRecv(TlenProtocol *proto, JABBER_SOCKET s, char *data, long datalen) -{ - int ret; - ret = Netlib_Recv(s, data, datalen, /*MSG_NODUMP|*/MSG_DUMPASTEXT); - if(ret == SOCKET_ERROR) { - JabberLog(proto, "Netlib_Recv() failed, error=%d", WSAGetLastError()); - return 0; - } - if(ret == 0) { - JabberLog(proto, "Connection closed gracefully"); - return 0; - } - return ret; -} - - -int JabberWsSendAES(TlenProtocol *proto, char *data, int datalen, aes_context *aes_ctx, unsigned char *aes_iv) -{ - int len, sendlen; - unsigned char aes_input[16]; - unsigned char aes_output[256]; - if (proto->threadData == NULL) { - return FALSE; - } - while (datalen > 0) { - len = 0; - while (datalen > 0 && len < 256) { - int pad = datalen < 16 ? 16 - datalen : 0; - memcpy(aes_input, data, datalen < 16 ? datalen : 16); - memset(aes_input + 16 - pad, ' ', pad); - aes_crypt_cbc(aes_ctx, AES_ENCRYPT, 16, aes_iv, aes_input, aes_output + len); - datalen -= 16; - data += 16; - len += 16; - } - if (len > 0) { - JabberLog(proto, "Sending %d bytes", len); - if ((sendlen=Netlib_Send(proto->threadData->s, (char *)aes_output, len, MSG_NODUMP))==SOCKET_ERROR || len!=sendlen) { - JabberLog(proto, "Netlib_Send() failed, error=%d", WSAGetLastError()); - return FALSE; - } - } - } - return TRUE; -} - -int JabberWsRecvAES(TlenProtocol *proto, char *data, long datalen, aes_context *aes_ctx, unsigned char *aes_iv) -{ - int ret, len = 0, maxlen = datalen; - unsigned char aes_input[16]; - unsigned char *aes_output = (unsigned char *)data; - if (proto->threadData == NULL) { - return 0; - } - for (maxlen = maxlen & ~0xF; maxlen != 0; maxlen = maxlen & 0xF) { - ret = Netlib_Recv(proto->threadData->s, data, maxlen, MSG_NODUMP); - if(ret == SOCKET_ERROR) { - JabberLog(proto, "Netlib_Recv() failed, error=%d", WSAGetLastError()); - return 0; - } - if(ret == 0) { - JabberLog(proto, "Connection closed gracefully"); - return 0; - } - data += ret; - len += ret; - maxlen -= ret; - } - - ret = len; - while (len > 15) { - memcpy(aes_input, aes_output, 16); - aes_crypt_cbc(aes_ctx, AES_DECRYPT, 16, aes_iv, aes_input, aes_output); - aes_output += 16; - len -= 16; - } - return ret; -} - diff --git a/!NotAdopted/Tlen/jabber_xml.c b/!NotAdopted/Tlen/jabber_xml.c deleted file mode 100644 index 6925e60eb1..0000000000 --- a/!NotAdopted/Tlen/jabber_xml.c +++ /dev/null @@ -1,568 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include - -static BOOL JabberXmlProcessElem(XmlState *xmlState, XmlElemType elemType, char *elemText, char *elemAttr); -static void JabberXmlRemoveChild(XmlNode *node, XmlNode *child); - -void JabberXmlInitState(XmlState *xmlState) -{ - if (xmlState == NULL) return; - xmlState->root.name = NULL; - xmlState->root.depth = 0; - xmlState->root.numAttr = 0; - xmlState->root.maxNumAttr = 0; - xmlState->root.attr = NULL; - xmlState->root.numChild = 0; - xmlState->root.maxNumChild = 0; - xmlState->root.child = NULL; - xmlState->root.text = NULL; - xmlState->root.state = NODE_OPEN; - xmlState->callback1_open = NULL; - xmlState->callback1_close = NULL; - xmlState->callback2_open = NULL; - xmlState->callback2_close = NULL; - xmlState->userdata1_open = NULL; - xmlState->userdata1_close = NULL; - xmlState->userdata2_open = NULL; - xmlState->userdata2_close = NULL; -} - -void JabberXmlDestroyState(XmlState *xmlState) -{ - int i; - XmlNode *node; - - if (xmlState == NULL) return; - // Note: cannot use JabberXmlFreeNode() to free xmlState->root - // because it will do mir_free(xmlState->root) which is not freeable. - node = &(xmlState->root); - // Free all children first - for (i=0; inumChild; i++) - JabberXmlFreeNode(node->child[i]); - if (node->child) mir_free(node->child); - // Free all attributes - for (i=0; inumAttr; i++) { - if (node->attr[i]->name) mir_free(node->attr[i]->name); - if (node->attr[i]->value) mir_free(node->attr[i]->value); - mir_free(node->attr[i]); - } - if (node->attr) mir_free(node->attr); - // Free string field - if (node->text) mir_free(node->text); - if (node->name) mir_free(node->name); -} - -BOOL JabberXmlSetCallback(XmlState *xmlState, int depth, XmlElemType type, void (*callback)(), void *userdata) -{ - if (depth==1 && type==ELEM_OPEN) { - xmlState->callback1_open = callback; - xmlState->userdata1_open = userdata; - } - else if (depth==1 && type==ELEM_CLOSE) { - xmlState->callback1_close = callback; - xmlState->userdata1_close = userdata; - } - else if (depth==2 && type==ELEM_OPEN) { - xmlState->callback2_open = callback; - xmlState->userdata2_open = userdata; - } - else if (depth==2 && type==ELEM_CLOSE) { - xmlState->callback2_close = callback; - xmlState->userdata2_close = userdata; - } - else - return FALSE; - - return TRUE; -} - -#define TAG_MAX_LEN 50 -#define ATTR_MAX_LEN 1024 -int JabberXmlParse(XmlState *xmlState, char *buffer, int datalen) -{ - char *p, *q, *r, *eob; - char *str; - int num; - char tag[TAG_MAX_LEN]; - char attr[ATTR_MAX_LEN]; - XmlElemType elemType = 0; - - eob = buffer + datalen; - num = 0; - // Skip leading whitespaces - for (p=buffer; p TAG_MAX_LEN) { -// JabberLog("TAG_MAX_LEN too small, ignore current tag"); - } - else { - if (*(p+1) == '/') { // closing tag - strncpy(tag, p+2, r-(p+2)); - tag[r-(p+2)] = '\0'; - elemType = ELEM_CLOSE; - } - else { - if (*(r-1) == '/') { // single open/close tag - strncpy(tag, p+1, r-(p+1)-1); - tag[r-(p+1)-1] = '\0'; - elemType = ELEM_OPENCLOSE; - } - else { - strncpy(tag, p+1, r-(p+1)); - tag[r-(p+1)] = '\0'; - elemType = ELEM_OPEN; - } - } - for (;r ATTR_MAX_LEN) { -// JabberLog("ATTR_MAX_LEN too small, ignore current tag"); - } - else { - strncpy(attr, r, q-r); - if ((q-r)>0 && attr[q-r-1]=='/') { - attr[q-r-1] = '\0'; - elemType = ELEM_OPENCLOSE; - } - else - attr[q-r] = '\0'; - JabberXmlProcessElem(xmlState, elemType, tag, attr); - } - } - num += (q-p+1); - p = q + 1; - if (elemType==ELEM_CLOSE || elemType==ELEM_OPENCLOSE) { - // Skip whitespaces after end tags - for (; pnumAttr >= node->maxNumAttr) { - node->maxNumAttr = node->numAttr + 20; - node->attr = (XmlAttr **) mir_realloc(node->attr, node->maxNumAttr*sizeof(XmlAttr *)); - } - a = node->attr[node->numAttr] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); - node->numAttr++; - - // Skip possible whitespaces between key and '=' - for (;*p!='\0' && (*p==' ' || *p=='\t'); p++); - - if (*p == '\0') { - a->name = (char *) mir_alloc(klen+1); - strncpy(a->name, kstart, klen); - a->name[klen] = '\0'; - a->value = mir_strdup(""); - break; - } - - if (*p != '=') { - a->name = (char *) mir_alloc(klen+1); - strncpy(a->name, kstart, klen); - a->name[klen] = '\0'; - a->value = mir_strdup(""); - continue; - } - - // Found '=' - p++; - - // Skip possible whitespaces between '=' and value - for (;*p!='\0' && (*p==' ' || *p=='\t'); p++); - - if (*p == '\0') { - a->name = (char *) mir_alloc(klen+1); - strncpy(a->name, kstart, klen); - a->name[klen] = '\0'; - a->value = mir_strdup(""); - break; - } - - // Fetch value - if (*p=='\'' || *p=='"') { - p++; - vstart = p; - for (;*p!='\0' && *p!=*(vstart-1); p++); - vlen = p-vstart; - if (*p != '\0') p++; - } - else { - vstart = p; - for (;*p!='\0' && *p!=' ' && *p!='\t'; p++); - vlen = p-vstart; - } - - a->name = (char *) mir_alloc(klen+1); - strncpy(a->name, kstart, klen); - a->name[klen] = '\0'; - a->value = (char *) mir_alloc(vlen+1); - strncpy(a->value, vstart, vlen); - a->value[vlen] = '\0'; - } -} - -static BOOL JabberXmlProcessElem(XmlState *xmlState, XmlElemType elemType, char *elemText, char *elemAttr) -{ - XmlNode *node, *parentNode, *n; - //BOOL activateCallback = FALSE; - char *text, *attr; - - if (elemText == NULL) return FALSE; - - if (elemType==ELEM_OPEN && !strcmp(elemText, "?xml")) { -// JabberLog("XML: skip tag"); - return TRUE; - } - - // Find active node - node = &(xmlState->root); - parentNode = NULL; - while (node->numChild>0 && node->child[node->numChild-1]->state==NODE_OPEN) { - parentNode = node; - node = node->child[node->numChild-1]; - } - - if (node->state != NODE_OPEN) return FALSE; - - text = mir_strdup(elemText); - - if (elemAttr) - attr = mir_strdup(elemAttr); - else - attr = NULL; - - switch (elemType) { - case ELEM_OPEN: - if (node->numChild >= node->maxNumChild) { - node->maxNumChild = node->numChild + 20; - node->child = (XmlNode **) mir_realloc(node->child, node->maxNumChild*sizeof(XmlNode *)); - } - n = node->child[node->numChild] = (XmlNode *) mir_alloc(sizeof(XmlNode)); - node->numChild++; - n->name = text; - n->depth = node->depth + 1; - n->state = NODE_OPEN; - n->numChild = n->maxNumChild = 0; - n->child = NULL; - n->numAttr = n->maxNumAttr = 0; - n->attr = NULL; - JabberXmlParseAttr(n, attr); - n->text = NULL; - if (n->depth==1 && xmlState->callback1_open!=NULL) - (*(xmlState->callback1_open))(n, xmlState->userdata1_open); - if (n->depth==2 && xmlState->callback2_open!=NULL) - (*xmlState->callback2_open)(n, xmlState->userdata2_open); - break; - case ELEM_OPENCLOSE: - if (node->numChild >= node->maxNumChild) { - node->maxNumChild = node->numChild + 20; - node->child = (XmlNode **) mir_realloc(node->child, node->maxNumChild*sizeof(XmlNode *)); - } - n = node->child[node->numChild] = (XmlNode *) mir_alloc(sizeof(XmlNode)); - node->numChild++; - n->name = text; - n->depth = node->depth + 1; - n->state = NODE_CLOSE; - n->numChild = n->maxNumAttr = 0; - n->child = NULL; - n->numAttr = n->maxNumAttr = 0; - n->attr = NULL; - JabberXmlParseAttr(n, attr); - n->text = NULL; - if (n->depth==1 && xmlState->callback1_close!=NULL) { - (*(xmlState->callback1_close))(n, xmlState->userdata1_close); - JabberXmlRemoveChild(node, n); - } - if (n->depth==2 && xmlState->callback2_close!=NULL) { - (*xmlState->callback2_close)(n, xmlState->userdata2_close); - JabberXmlRemoveChild(node, n); - } - break; - case ELEM_CLOSE: - if (node->name!=NULL && !strcmp(node->name, text)) { - node->state = NODE_CLOSE; - if (node->depth==1 && xmlState->callback1_close!=NULL) { - (*(xmlState->callback1_close))(node, xmlState->userdata1_close); - JabberXmlRemoveChild(parentNode, node); - } - if (node->depth==2 && xmlState->callback2_close!=NULL) { - (*xmlState->callback2_close)(node, xmlState->userdata2_close); - JabberXmlRemoveChild(parentNode, node); - } - mir_free(text); - } - else { -// JabberLog("XML: Closing without opening tag", text); - mir_free(text); - if (attr) mir_free(attr); - return FALSE; - } - break; - case ELEM_TEXT: - node->text = text; - break; - default: - mir_free(text); - if (attr) mir_free(attr); - return FALSE; - } - - if (attr) mir_free(attr); - - return TRUE; -} - -char *JabberXmlGetAttrValue(XmlNode *node, char *key) -{ - int i; - - if (node==NULL || node->numAttr<=0 || key==NULL || strlen(key)<=0) - return NULL; - for (i=0; inumAttr; i++) { - if (node->attr[i]->name && !strcmp(key, node->attr[i]->name)) - return node->attr[i]->value; - } - return NULL; -} - -XmlNode *JabberXmlGetChild(XmlNode *node, char *tag) -{ - return JabberXmlGetNthChild(node, tag, 1); -} - -XmlNode *JabberXmlGetNthChild(XmlNode *node, char *tag, int nth) -{ - int i, num; - - if (node==NULL || node->numChild<=0 || tag==NULL || strlen(tag)<=0 || nth<1) - return NULL; - num = 1; - for (i=0; inumChild; i++) { - if (node->child[i]->name && !strcmp(tag, node->child[i]->name)) { - if (num == nth) { - return node->child[i]; - } - num++; - } - } - return NULL; -} - -XmlNode *JabberXmlGetChildWithGivenAttrValue(XmlNode *node, char *tag, char *attrKey, char *attrValue) -{ - int i; - char *str; - - if (node==NULL || node->numChild<=0 || tag==NULL || strlen(tag)<=0 || attrKey==NULL || strlen(attrKey)<=0 || attrValue==NULL || strlen(attrValue)<=0) - return NULL; - for (i=0; inumChild; i++) { - if (node->child[i]->name && !strcmp(tag, node->child[i]->name)) { - if ((str=JabberXmlGetAttrValue(node->child[i], attrKey)) != NULL) - if (!strcmp(str, attrValue)) - return node->child[i]; - } - } - return NULL; -} - -static void JabberXmlRemoveChild(XmlNode *node, XmlNode *child) -{ - int i; - - if (node==NULL || child==NULL || node->numChild<=0) return; - for (i=0; inumChild; i++) { - if (node->child[i] == child) - break; - } - if (i < node->numChild) { - for (++i; inumChild; i++) - node->child[i-1] = node->child[i]; - node->numChild--; - JabberXmlFreeNode(child); - } -} - -void JabberXmlFreeNode(XmlNode *node) -{ - int i; - - if (node == NULL) return; - // Free all children first - for (i=0; inumChild; i++) - JabberXmlFreeNode(node->child[i]); - if (node->child) mir_free(node->child); - // Free all attributes - for (i=0; inumAttr; i++) { - if (node->attr[i]->name) mir_free(node->attr[i]->name); - if (node->attr[i]->value) mir_free(node->attr[i]->value); - mir_free(node->attr[i]); - } - if (node->attr) mir_free(node->attr); - // Free string field - if (node->text) mir_free(node->text); - if (node->name) mir_free(node->name); - // Free the node itself - mir_free(node); -} - -XmlNode *JabberXmlCopyNode(XmlNode *node) -{ - XmlNode *n; - int i; - - if (node == NULL) return NULL; - n = (XmlNode *) mir_alloc(sizeof(XmlNode)); - // Copy attributes - if (node->numAttr > 0) { - n->attr = (XmlAttr **) mir_alloc(node->numAttr*sizeof(XmlAttr *)); - for (i=0; inumAttr; i++) { - n->attr[i] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); - if (node->attr[i]->name) n->attr[i]->name = mir_strdup(node->attr[i]->name); - else n->attr[i]->name = NULL; - if (node->attr[i]->value) n->attr[i]->value = mir_strdup(node->attr[i]->value); - else n->attr[i]->value = NULL; - } - } - else - n->attr = NULL; - // Recursively copy children - if (node->numChild > 0) { - n->child = (XmlNode **) mir_alloc(node->numChild*sizeof(XmlNode *)); - for (i=0; inumChild; i++) - n->child[i] = JabberXmlCopyNode(node->child[i]); - } - else - n->child = NULL; - // Copy other fields - n->numAttr = node->numAttr; - n->maxNumAttr = node->numAttr; - n->numChild = node->numChild; - n->maxNumChild = node->numChild; - n->depth = node->depth; - n->state = node->state; - n->name = (node->name)?mir_strdup(node->name):NULL; - n->text = (node->text)?mir_strdup(node->text):NULL; - - return n; -} - -XmlNode *JabberXmlCreateNode(char *name) -{ - XmlNode *n; - - if (name == NULL) - return NULL; - - n = (XmlNode *) mir_alloc(sizeof(XmlNode)); - memset(n, 0, sizeof(XmlNode)); - n->name = mir_strdup(name); - return n; -} - -void JabberXmlAddAttr(XmlNode *n, char *name, char *value) -{ - int i; - - if (n==NULL || name==NULL || value==NULL) - return; - - i = n->numAttr; - (n->numAttr)++; - n->attr = (XmlAttr **) mir_realloc(n->attr, sizeof(XmlAttr *) * n->numAttr); - n->attr[i] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); - n->attr[i]->name = mir_strdup(name); - n->attr[i]->value = mir_strdup(value); -} - -XmlNode *JabberXmlAddChild(XmlNode *n, char *name) -{ - int i; - - if (n==NULL || name==NULL) - return NULL; - - i = n->numChild; - n->numChild++; - n->child = (XmlNode **) mir_realloc(n->child, sizeof(XmlNode *) * n->numChild); - n->child[i] = (XmlNode *) mir_alloc(sizeof(XmlNode)); - memset(n->child[i], 0, sizeof(XmlNode)); - n->child[i]->name = mir_strdup(name); - return n->child[i]; -} - -void JabberXmlAddText(XmlNode *n, char *text) -{ - if (n!=NULL && text!=NULL) { - if (n->text) mir_free(n->text); - n->text = mir_strdup(text); - } -} - diff --git a/!NotAdopted/Tlen/jabber_xml.h b/!NotAdopted/Tlen/jabber_xml.h deleted file mode 100644 index 98949b92f6..0000000000 --- a/!NotAdopted/Tlen/jabber_xml.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#ifndef _JABBER_XML_H_ -#define _JABBER_XML_H_ - -typedef enum { ELEM_OPEN, ELEM_CLOSE, ELEM_OPENCLOSE, ELEM_TEXT } XmlElemType; -typedef enum { NODE_OPEN, NODE_CLOSE } XmlNodeType; - -typedef struct tagXmlAttr { - char *name; - char *value; -} XmlAttr; - -typedef struct tagXmlNode { - int depth; // depth of the current node (1=root) - char *name; // tag name of the current node - int numAttr; // number of attributes - int maxNumAttr; // internal use (num of slots currently allocated to attr) - XmlAttr **attr; // attribute list - int numChild; // number of direct child nodes - int maxNumChild; // internal use (num of slots currently allocated to child) - struct tagXmlNode **child; // child node list - char *text; - XmlNodeType state; // internal use by parser -} XmlNode; - -typedef struct tagXmlState { - XmlNode root; // root is the document (depth = 0); - // callback for depth=n element on opening/closing - void (*callback1_open)(); - void (*callback1_close)(); - void (*callback2_open)(); - void (*callback2_close)(); - void *userdata1_open; - void *userdata1_close; - void *userdata2_open; - void *userdata2_close; -} XmlState; - -void JabberXmlInitState(XmlState *xmlState); -void JabberXmlDestroyState(XmlState *xmlState); -BOOL JabberXmlSetCallback(XmlState *xmlState, int depth, XmlElemType type, void (*callback)(), void *userdata); -int JabberXmlParse(XmlState *xmlState, char *buffer, int datalen); -char *JabberXmlGetAttrValue(XmlNode *node, char *key); -XmlNode *JabberXmlGetChild(XmlNode *node, char *tag); -XmlNode *JabberXmlGetNthChild(XmlNode *node, char *tag, int nth); -XmlNode *JabberXmlGetChildWithGivenAttrValue(XmlNode *node, char *tag, char *attrKey, char *attrValue); -void JabberXmlFreeNode(XmlNode *node); -XmlNode *JabberXmlCopyNode(XmlNode *node); - -XmlNode *JabberXmlCreateNode(char *name); -void JabberXmlAddAttr(XmlNode *n, char *name, char *value); -XmlNode *JabberXmlAddChild(XmlNode *n, char *name); -void JabberXmlAddText(XmlNode *n, char *text); - -#endif - diff --git a/!NotAdopted/Tlen/resource.h b/!NotAdopted/Tlen/resource.h deleted file mode 100644 index f3a350630e..0000000000 --- a/!NotAdopted/Tlen/resource.h +++ /dev/null @@ -1,147 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Tlen.rc -// - -#define IDI_TLEN 100 -#define IDI_MAIL 101 -#define IDI_MUC 102 -#define IDI_CHATS 103 -#define IDI_GRANT 104 -#define IDI_REQUEST 105 -#define IDI_VOICE 106 -#define IDI_MICROPHONE 107 -#define IDI_SPEAKER 108 -#define IDI_IMAGE 109 - -#define IDD_OPTIONS_BASIC 151 -#define IDD_OPTIONS_VOICE 152 -#define IDD_OPTIONS_POPUPS 153 -#define IDD_OPTIONS_ADVANCED 154 -#define IDD_USER_INFO 155 -#define IDD_USER_VCARD 156 -#define IDD_PASSWORD 157 -#define IDD_ADVSEARCH 158 -#define IDD_VOICE 159 -#define IDD_ACCEPT_VOICE 160 -#define IDD_USER_CHANGEAVATAR 161 -#define IDD_ACCMGRUI 162 - -#define IDC_TABS 1000 -#define IDC_EDIT_USERNAME 1001 -#define IDC_SAVE 1002 -#define IDC_EDIT_PASSWORD 1003 -#define IDC_EDIT_LOGIN_SERVER 1004 -#define IDC_INFO_JID 1007 -#define IDC_INFO_RESOURCE 1008 -#define IDC_SHOW_OFFLINE 1012 -#define IDC_OFFLINE_MESSAGE 1013 -#define IDC_OFFLINE_MESSAGE_OPTION 1014 -#define IDC_VISIBILITY_SUPPORT 1015 -#define IDC_NUDGE_SUPPORT 1016 -#define IDC_LOG_ALERTS 1017 - -#define IDC_SUBSCRIPTION 1039 -#define IDC_REGISTERACCOUNT 1040 -#define IDC_SIMPLE 1041 -#define IDC_KEEPALIVE 1042 -#define IDC_HOST 1043 -#define IDC_HOSTPORT 1044 -#define IDC_USE_SSL 1045 -#define IDC_SAVEPASSWORD 1048 -#define IDC_ROSTER_ALERTS 1049 -#define IDC_PASSWORD 1050 -#define IDC_RECONNECT 1050 -#define IDC_JID 1051 -#define IDC_ROSTER_SYNC 1052 -#define IDC_ALERT_POLICY 1053 -#define IDC_MUC_POLICY 1054 -#define IDC_VOICE_POLICY 1055 -#define IDC_IGNORE_ADVERTISEMENTS 1056 -#define IDC_AVATARS 1057 -#define IDC_VERSIONINFO 1058 -#define IDC_IMAGE_POLICY 1059 -#define IDC_CITY 1060 -#define IDC_FULLNAME 1061 -#define IDC_NICKNAME 1062 -#define IDC_FIRSTNAME 1063 -#define IDC_LASTNAME 1064 -#define IDC_BIRTH 1065 -#define IDC_AGE 1065 -#define IDC_OCCUPATION 1066 -#define IDC_EMAIL 1073 -#define IDC_GENDER 1096 -#define IDC_VOICECONVERSATIONS 1097 -#define IDC_PUBLICSTATUS 1098 -#define IDC_VCQUALITY 1100 -#define IDC_VUMETERIN 1101 -#define IDC_VUMETEROUT 1102 -#define IDC_BYTESIN 1103 -#define IDC_BYTESOUT 1104 -#define IDC_MICROPHONE 1105 -#define IDC_SPEAKER 1106 -#define IDC_ACCEPT 1107 - -#define IDC_FILE_PROXY_TYPE_LABEL 1108 -#define IDC_FILE_PROXY_TYPE 1109 -#define IDC_FILE_PROXY_HOST_LABEL 1110 -#define IDC_FILE_PROXY_HOST 1111 -#define IDC_FILE_PROXY_PORT_LABEL 1112 -#define IDC_FILE_PROXY_PORT 1113 -#define IDC_FILE_PROXY_USE_AUTH 1114 -#define IDC_FILE_PROXY_USER 1115 -#define IDC_FILE_PROXY_USER_LABEL 1116 -#define IDC_FILE_PROXY_PASSWORD_LABEL 1117 -#define IDC_FILE_PROXY_PASSWORD 1118 -#define IDC_FILE_USE_PROXY 1119 -#define IDC_VOICE_DEVICE_IN 1120 -#define IDC_VOICE_DEVICE_OUT 1121 - -#define IDC_MSG_ACK 1124 -#define IDC_SERVER 1125 -#define IDC_NICK 1129 -#define IDC_LIST 1133 -#define IDC_ENTER 1144 -#define IDC_AGEFROM 1152 -#define IDC_AGETO 1153 -#define IDC_LOOKFOR 1154 -#define IDC_SCHOOL 1155 -#define IDC_FROM 1175 -#define IDC_DELAY 1180 -#define IDC_COLORBKG 1181 -#define IDC_COLORTXT 1182 -#define IDC_PREVIEW 1183 -#define IDC_ENABLEPOPUP 1184 -#define IDC_DELAY_PERMANENT 1185 -#define IDC_DELAY_CUSTOM 1186 -#define IDC_DELAY_POPUP 1187 -#define IDC_TLEN 1190 -#define IDC_GENDER_TEXT 1195 -#define IDC_OCCUPATION_TEXT 1199 -#define IDC_LOOKFOR_TEXT 1200 -#define IDC_GROUP 1203 -#define IDC_SOFTWARE 1204 -#define IDC_VERSION 1205 -#define IDC_SYSTEM 1206 -#define IDC_AVATAR 1210 -#define IDC_SETAVATAR 1211 -#define IDC_DELETEAVATAR 1212 -#define IDC_AVATAR_LIST 1213 -#define IDC_OLD_AVATAR 1214 -#define IDC_BROWSEAVATAR 1215 -#define IDC_PUBLICAVATAR 1216 - -#define IDC_STATUS 1414 -#define IDC_PLAN 1415 -#define IDC_PERSONALGROUP 1434 -#define IDC_EXTRAGROUP 1435 -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 190 -#define _APS_NEXT_COMMAND_VALUE 40017 -#define _APS_NEXT_CONTROL_VALUE 1204 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/!NotAdopted/Tlen/tlen.c b/!NotAdopted/Tlen/tlen.c deleted file mode 100644 index 2f8d860a64..0000000000 --- a/!NotAdopted/Tlen/tlen.c +++ /dev/null @@ -1,636 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "commons.h" -#include "jabber.h" -#include "tlen_muc.h" -#include "tlen_file.h" -#include "tlen_voice.h" -#include "jabber_list.h" -#include "jabber_iq.h" -#include "resource.h" -#include "tlen_picture.h" -#include -#include -#include -#include -#include -#include "m_mucc.h" -#include "m_updater.h" - - -struct MM_INTERFACE mmi; -struct SHA1_INTERFACE sha1i; -struct MD5_INTERFACE md5i; -struct UTF8_INTERFACE utfi; -HINSTANCE hInst; -PLUGINLINK *pluginLink; -HANDLE hMainThread; - -PLUGININFOEX pluginInfoEx = { - sizeof(PLUGININFOEX), -#ifdef _UNICODE -#ifdef _X64 - "Tlen Protocol (x64, Unicode)", -#else - "Tlen Protocol (Unicode)", -#endif -#else - "Tlen Protocol", -#endif - PLUGIN_MAKE_VERSION(TLEN_MAJOR_VERSION,TLEN_MINOR_VERSION,TLEN_RELEASE_NUM,TLEN_BUILD_NUM), - "Tlen protocol plugin for Miranda IM (version: "TLEN_VERSION_STRING" ; compiled: "__DATE__" "__TIME__")", - "Santithorn Bunchua, Adam Strzelecki, Piotr Piastucki", - "the_leech@users.berlios.de", - "(c) 2002-2012 Santithorn Bunchua, Piotr Piastucki", - "http://mtlen.berlios.de", - 0, - 0, -#if defined( _UNICODE ) -#ifdef _X64 - {0x3ba4a3c6, 0x27b5, 0x4c78, { 0x92, 0x8c, 0x38, 0x2a, 0xe1, 0xd3, 0x2a, 0xb5 }} -#else - {0x748f8934, 0x781a, 0x528d, { 0x52, 0x08, 0x00, 0x12, 0x65, 0x40, 0x4a, 0xb3 }} -#endif -#else - {0x11fc3484, 0x475c, 0x11dc, { 0x83, 0x14, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 }} -#endif -}; - -// Main jabber server connection thread global variables - -void TlenLoadOptions(TlenProtocol *proto); -int TlenOptionsInit(void *ptr, WPARAM wParam, LPARAM lParam); -int TlenUserInfoInit(void *ptr, WPARAM wParam, LPARAM lParam); -int TlenSystemModulesLoaded(void *ptr, WPARAM wParam, LPARAM lParam); -extern void TlenInitServicesVTbl(TlenProtocol *proto); -extern int JabberContactDeleted(void *ptr, WPARAM wParam, LPARAM lParam); -extern int JabberDbSettingChanged(void *ptr, WPARAM wParam, LPARAM lParam); - -BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpvReserved) -{ -#ifdef _DEBUG - _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); -#endif - - hInst = hModule; - return TRUE; -} - -__declspec(dllexport) PLUGININFOEX *MirandaPluginInfoEx( DWORD mirandaVersion ) -{ - if ( mirandaVersion < PLUGIN_MAKE_VERSION( 0,8,0,15 )) { - MessageBox( NULL, TranslateT("The Tlen protocol plugin cannot be loaded. It requires Miranda IM 0.8.0.15 or later."), TranslateT("Tlen Protocol Plugin"), MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_TOPMOST ); - return NULL; - } - - return &pluginInfoEx; -} - -extern "C" __declspec(dllexport) const MUUID interfaces[] = {MIID_PROTOCOL, MIID_LAST}; -__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} - -struct -{ - TCHAR* szDescr; - char* szName; - int defIconID; - HANDLE hIconLibItem; -} -static iconList[] = -{ - { _T("Protocol icon"), "PROTO", IDI_TLEN }, - { _T("Tlen inbox"), "MAIL", IDI_MAIL }, - { _T("Group chats"), "MUC", IDI_MUC }, - { _T("Tlen chats"), "CHATS", IDI_CHATS }, - { _T("Grant authorization"), "GRANT", IDI_GRANT }, - { _T("Request authorization"),"REQUEST", IDI_REQUEST }, - { _T("Voice chat"), "VOICE", IDI_VOICE }, - { _T("Microphone"), "MICROPHONE", IDI_MICROPHONE }, - { _T("Speaker"), "SPEAKER", IDI_SPEAKER }, - { _T("Send image"), "IMAGE", IDI_IMAGE } -}; - -static HANDLE GetIconHandle(int iconId) { - int i; - for(i = 0; i < SIZEOF(iconList); i++) - if(iconList[i].defIconID == iconId) - return iconList[i].hIconLibItem; - return NULL; -} - -HICON GetIcolibIcon(int iconId) { - HANDLE handle = GetIconHandle(iconId); - if (handle != NULL) { - return (HICON) CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)handle); - } - return NULL; -} - -void ReleaseIcolibIcon(HICON hIcon) { - CallService( MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0 ); -} - -/* -static int TlenIconsChanged(void *ptr, WPARAM wParam, LPARAM lParam) -{ - return 0; -} -*/ - -static void TlenRegisterIcons() -{ - SKINICONDESC sid = { 0 }; - char path[MAX_PATH]; - TCHAR szSectionName[100]; - int i; - mir_sntprintf(szSectionName, SIZEOF( szSectionName ), _T("%s/%s"), _T("Protocols"), _T("Tlen")); - - GetModuleFileNameA(hInst, path, MAX_PATH); - sid.cbSize = sizeof(SKINICONDESC); - sid.cx = sid.cy = 16; - sid.ptszSection = szSectionName; - sid.pszDefaultFile = path; - sid.flags = SIDF_TCHAR; - - for ( i = 0; i < SIZEOF(iconList); i++ ) { - char szSettingName[100]; - mir_snprintf( szSettingName, sizeof( szSettingName ), "TLEN_%s", iconList[i].szName ); - sid.pszName = szSettingName; - sid.pszDescription = (char*)iconList[i].szDescr; - sid.iDefaultIndex = -iconList[i].defIconID; - iconList[i].hIconLibItem = ( HANDLE )CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid); - } -} - -static int TlenPrebuildContactMenu(void *ptr, WPARAM wParam, LPARAM lParam) -{ - HANDLE hContact; - DBVARIANT dbv; - CLISTMENUITEM clmi = {0}; - JABBER_LIST_ITEM *item; - TlenProtocol *proto = (TlenProtocol *)ptr; - clmi.cbSize = sizeof(CLISTMENUITEM); - if ((hContact=(HANDLE) wParam)!=NULL && proto->isOnline) { - if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { - if ((item=JabberListGetItemPtr(proto, LIST_ROSTER, dbv.pszVal)) != NULL) { - if (item->subscription==SUB_NONE || item->subscription==SUB_FROM) - clmi.flags = CMIM_FLAGS; - else - clmi.flags = CMIM_FLAGS|CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuContactRequestAuth, (LPARAM) &clmi); - - if (item->subscription==SUB_NONE || item->subscription==SUB_TO) - clmi.flags = CMIM_FLAGS; - else - clmi.flags = CMIM_FLAGS|CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuContactGrantAuth, (LPARAM) &clmi); - - if (item->status!=ID_STATUS_OFFLINE) - clmi.flags = CMIM_FLAGS; - else - clmi.flags = CMIM_FLAGS|CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuContactMUC, (LPARAM) &clmi); - - if (item->status!=ID_STATUS_OFFLINE && !TlenVoiceIsInUse(proto)) - clmi.flags = CMIM_FLAGS; - else - clmi.flags = CMIM_FLAGS|CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuContactVoice, (LPARAM) &clmi); - - if (item->status!=ID_STATUS_OFFLINE) - clmi.flags = CMIM_FLAGS; - else - clmi.flags = CMIM_FLAGS|CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuPicture, (LPARAM) &clmi); - - DBFreeVariant(&dbv); - return 0; - } - DBFreeVariant(&dbv); - } - } - clmi.flags = CMIM_FLAGS|CMIF_HIDDEN; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuContactMUC, (LPARAM) &clmi); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuContactVoice, (LPARAM) &clmi); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuContactRequestAuth, (LPARAM) &clmi); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuContactGrantAuth, (LPARAM) &clmi); - return 0; -} - -INT_PTR TlenContactMenuHandleRequestAuth(void *ptr, WPARAM wParam, LPARAM lParam) -{ - HANDLE hContact; - DBVARIANT dbv; - TlenProtocol *proto = (TlenProtocol *)ptr; - if ((hContact=(HANDLE) wParam)!=NULL && proto->isOnline) { - if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { - JabberSend(proto, "", dbv.pszVal); - DBFreeVariant(&dbv); - } - } - return 0; -} - -INT_PTR TlenContactMenuHandleGrantAuth(void *ptr, WPARAM wParam, LPARAM lParam) -{ - HANDLE hContact; - DBVARIANT dbv; - TlenProtocol *proto = (TlenProtocol *)ptr; - if ((hContact=(HANDLE) wParam)!=NULL && proto->isOnline) { - if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { - JabberSend(proto, "", dbv.pszVal); - DBFreeVariant(&dbv); - } - } - return 0; -} - -INT_PTR TlenContactMenuHandleSendPicture(void *ptr, WPARAM wParam, LPARAM lParam) -{ - HANDLE hContact; - TlenProtocol *proto = (TlenProtocol *)ptr; - if ((hContact=(HANDLE) wParam)!=NULL && proto->isOnline) { - SendPicture(proto, hContact); - } - return 0; -} - -INT_PTR TlenMenuHandleInbox(void *ptr, WPARAM wParam, LPARAM lParam) -{ - char szFileName[ MAX_PATH ]; - DBVARIANT dbv; - NETLIBHTTPREQUEST req; - NETLIBHTTPHEADER headers[2]; - NETLIBHTTPREQUEST *resp; - char *login = NULL, *password = NULL; - char form[1024]; - char cookie[1024]; - TlenProtocol *proto = (TlenProtocol *)ptr; - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginName", &dbv)) { - login = mir_strdup(dbv.pszVal); - DBFreeVariant(&dbv); - } - if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "SavePassword", TRUE) == TRUE) { - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "Password", &dbv)) { - CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); - password = mir_strdup(dbv.pszVal); - DBFreeVariant(&dbv); - } - } else if (proto->threadData != NULL && strlen(proto->threadData->password) > 0) { - password = mir_strdup(proto->threadData->password); - } - - ZeroMemory(&cookie, sizeof(cookie)); - if (login != NULL && password != NULL) { - mir_snprintf( form, SIZEOF(form), "username=%s&password=%s", login, password); - headers[0].szName = "Content-Type"; - headers[0].szValue = "application/x-www-form-urlencoded"; - ZeroMemory(&req, sizeof(req)); - req.cbSize = sizeof(req); - req.requestType = REQUEST_POST; - req.flags = 0; - req.headersCount = 1; - req.headers = headers; - req.pData = form; - req.dataLength = (int)strlen(form); - req.szUrl = "http://poczta.o2.pl/login.html"; - resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)proto->hNetlibUser, (LPARAM)&req); - if (resp != NULL) { - if (resp->resultCode/100==2 || resp->resultCode == 302) { - int i; - for (i=0; iheadersCount; i++ ) { - if (strcmpi(resp->headers[i].szName, "Set-Cookie")==0) { - char *start = strstr(resp->headers[i].szValue, "ssid="); - if (start != NULL) { - char *end = strstr(resp->headers[i].szValue, ";"); - start = start + 5; - if (end == NULL) { - end = resp->headers[i].szValue + strlen(resp->headers[i].szValue); - } - strncpy(cookie, start, (end - start)); - break; - } - } - } - } - CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); - } - } - mir_free(login); - mir_free(password); - _snprintf(szFileName, sizeof(szFileName), "http://poczta.o2.pl/login.html?sid=%s", cookie); - CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) szFileName); - return 0; -} - -int TlenOnModulesLoaded(void *ptr, WPARAM wParam, LPARAM lParam) { - - char str[128]; - TlenProtocol *proto = (TlenProtocol *)ptr; - /* Set all contacts to offline */ - HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - while (hContact != NULL) { - char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); - if(szProto!=NULL && !strcmp(szProto, proto->iface.m_szModuleName)) { - if (DBGetContactSettingWord(hContact, proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) { - DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE); - } - } - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); - } - TlenMUCInit(proto); - sprintf(str, "%s", Translate("Incoming mail")); - SkinAddNewSoundEx("TlenMailNotify", proto->iface.m_szProtoName, str); - sprintf(str, "%s", Translate("Alert")); - SkinAddNewSoundEx("TlenAlertNotify", proto->iface.m_szProtoName, str); - sprintf(str, "%s", Translate("Voice chat")); - SkinAddNewSoundEx("TlenVoiceNotify", proto->iface.m_szProtoName, str); - - HookEventObj_Ex(ME_USERINFO_INITIALISE, proto, TlenUserInfoInit); - - return 0; -} - -int TlenPreShutdown(void *ptr, WPARAM wParam, LPARAM lParam) -{ - JabberLog(ptr, "TLEN TlenPreShutdown"); - //TlenProtocol *proto = (TlenProtocol *)ptr; - return 0; -} - - -static void initMenuItems(TlenProtocol *proto) -{ - - char text[_MAX_PATH]; - CLISTMENUITEM mi, clmi; - memset(&mi, 0, sizeof(CLISTMENUITEM)); - mi.cbSize = sizeof(CLISTMENUITEM); - memset(&clmi, 0, sizeof(CLISTMENUITEM)); - clmi.cbSize = sizeof(CLISTMENUITEM); - clmi.flags = CMIM_FLAGS | CMIF_GRAYED; - - mi.pszContactOwner = proto->iface.m_szModuleName; - mi.popupPosition = 500090000; - - strcpy(text, proto->iface.m_szModuleName); - mi.pszService = text; - mi.ptszName = proto->iface.m_tszUserName; - mi.position = -1999901009; - mi.pszPopupName = (char *)-1; - mi.flags = CMIF_ROOTPOPUP | CMIF_TCHAR | CMIF_ICONFROMICOLIB; - mi.icolibItem = GetIconHandle(IDI_TLEN); - proto->hMenuRoot = (HANDLE)CallService( MS_CLIST_ADDMAINMENUITEM, (WPARAM)0, (LPARAM)&mi); - - mi.flags = CMIF_CHILDPOPUP | CMIF_ICONFROMICOLIB; - //mi.pszPopupName = (char *)proto->hMenuRoot; - mi.hParentMenu = (HGENMENU)proto->hMenuRoot; - - proto->hMenuChats = NULL; - if(ServiceExists(MS_MUCC_NEW_WINDOW)) - { - sprintf(text, "%s/MainMenuChats", proto->iface.m_szModuleName); - CreateServiceFunction_Ex(text, proto, TlenMUCMenuHandleChats); - mi.pszName = "Tlen Chats"; - mi.position = 2000050001; - mi.icolibItem = GetIconHandle(IDI_CHATS); - mi.pszService = text; - proto->hMenuChats = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) &mi); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuChats, (LPARAM) &clmi); - } - - // "Multi-User Conference" - sprintf(text, "%s/MainMenuMUC", proto->iface.m_szModuleName); - CreateServiceFunction_Ex(text, proto, TlenMUCMenuHandleMUC); - mi.pszName = "Multi-User Conference"; - mi.position = 2000050002; - mi.icolibItem = GetIconHandle(IDI_MUC); - mi.pszService = text; - proto->hMenuMUC = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) &mi); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuMUC, (LPARAM) &clmi); - - sprintf(text, "%s/MainMenuInbox", proto->iface.m_szModuleName); - CreateServiceFunction_Ex(text, proto, TlenMenuHandleInbox); - mi.pszName = "Tlen Mail"; - mi.position = 2000050003; - mi.icolibItem = GetIconHandle(IDI_MAIL); - mi.pszService = text; - proto->hMenuInbox = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) &mi); - - mi.hParentMenu = NULL; - - - // "Send picture" - sprintf(text, "%s/SendPicture", proto->iface.m_szModuleName); - CreateServiceFunction_Ex(text, proto, TlenContactMenuHandleSendPicture); - mi.flags = CMIF_ICONFROMICOLIB; - mi.pszName = "Send picture"; - mi.position = -2000019030; - mi.icolibItem = GetIconHandle(IDI_IMAGE); - mi.pszService = text; - proto->hMenuPicture = (HANDLE) CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM) &mi); - - // "Invite to MUC" - sprintf(text, "%s/ContactMenuMUC", proto->iface.m_szModuleName); - CreateServiceFunction_Ex(text, proto, TlenMUCContactMenuHandleMUC); - mi.pszName = "Multi-User Conference"; - mi.position = -2000019020; - mi.icolibItem = GetIconHandle(IDI_MUC); - mi.pszService = text; - proto->hMenuContactMUC = (HANDLE) CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM) &mi); - - // "Invite to voice chat" - sprintf(text, "%s/ContactMenuVoice", proto->iface.m_szModuleName); - CreateServiceFunction_Ex(text, proto, TlenVoiceContactMenuHandleVoice); - mi.pszName = "Voice Chat"; - mi.position = -2000019010; - mi.icolibItem = GetIconHandle(IDI_VOICE); - mi.pszService = text; - proto->hMenuContactVoice = (HANDLE) CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM) &mi); - - // "Request authorization" - sprintf(text, "%s/RequestAuth", proto->iface.m_szModuleName); - CreateServiceFunction_Ex(text, proto, TlenContactMenuHandleRequestAuth); - mi.pszName = "Request authorization"; - mi.position = -2000001001; - mi.icolibItem = GetIconHandle(IDI_REQUEST); - mi.pszService = text; - proto->hMenuContactRequestAuth = (HANDLE) CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM) &mi); - - // "Grant authorization" - sprintf(text, "%s/GrantAuth", proto->iface.m_szModuleName); - CreateServiceFunction_Ex(text, proto, TlenContactMenuHandleGrantAuth); - mi.pszName = "Grant authorization"; - mi.position = -2000001000; - mi.icolibItem = GetIconHandle(IDI_GRANT); - mi.pszService = text; - proto->hMenuContactGrantAuth = (HANDLE) CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM) &mi); -} - -static void uninitMenuItems(TlenProtocol *proto) { - CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM)proto->hMenuChats, (LPARAM) 0); - CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM)proto->hMenuMUC, (LPARAM) 0); - CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM)proto->hMenuInbox, (LPARAM) 0); - CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM)proto->hMenuRoot, (LPARAM) 0); - CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)proto->hMenuContactMUC, (LPARAM) 0); - CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)proto->hMenuPicture, (LPARAM) 0); - CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)proto->hMenuContactVoice, (LPARAM) 0); - CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)proto->hMenuContactRequestAuth, (LPARAM) 0); - CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)proto->hMenuContactGrantAuth, (LPARAM) 0); -} - - -static TlenProtocol *tlenProtoInit( const char* pszProtoName, const TCHAR* tszUserName ) -{ - DBVARIANT dbv; - char text[_MAX_PATH]; - TlenProtocol *proto = (TlenProtocol *)mir_alloc(sizeof(TlenProtocol)); - memset(proto, 0, sizeof(TlenProtocol)); - proto->iface.m_tszUserName = mir_tstrdup( tszUserName ); - proto->iface.m_szModuleName = mir_strdup(pszProtoName); - proto->iface.m_szProtoName = mir_strdup(pszProtoName); - _strlwr( proto->iface.m_szProtoName ); - proto->iface.m_szProtoName[0] = toupper( proto->iface.m_szProtoName[0] ); - proto->iface.m_iStatus = ID_STATUS_OFFLINE; - TlenInitServicesVTbl(proto); - - InitializeCriticalSection(&proto->modeMsgMutex); - InitializeCriticalSection(&proto->csSend); - - sprintf(text, "%s/%s", proto->iface.m_szModuleName, "Nudge"); - proto->hTlenNudge = CreateHookableEvent(text); - - HookEventObj_Ex(ME_SYSTEM_MODULESLOADED, proto, TlenSystemModulesLoaded); - HookEventObj_Ex(ME_OPT_INITIALISE, proto, TlenOptionsInit); - HookEventObj_Ex(ME_DB_CONTACT_SETTINGCHANGED, proto, JabberDbSettingChanged); - HookEventObj_Ex(ME_DB_CONTACT_DELETED, proto, JabberContactDeleted); - HookEventObj_Ex(ME_CLIST_PREBUILDCONTACTMENU, proto, TlenPrebuildContactMenu); -// HookEventObj_Ex(ME_SKIN2_ICONSCHANGED, proto, TlenIconsChanged); - HookEventObj_Ex(ME_SYSTEM_PRESHUTDOWN, proto, TlenPreShutdown); - - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { - DBFreeVariant(&dbv); - } else { - DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "LoginServer", "tlen.pl"); - } - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "ManualHost", &dbv)) { - DBFreeVariant(&dbv); - } else { - DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "ManualHost", "s1.tlen.pl"); - } - - TlenLoadOptions(proto); - - JabberWsInit(proto); - JabberSerialInit(proto); - JabberIqInit(proto); - JabberListInit(proto); - - return proto; -} - -int TlenSystemModulesLoaded(void *ptr, WPARAM wParam, LPARAM lParam) -{ - - TlenProtocol *proto = (TlenProtocol *)ptr; - initMenuItems(proto); - - // updater plugin support - if(ServiceExists(MS_UPDATE_REGISTERFL)) - { - PLUGININFO* pluginInfoPtr = (PLUGININFO*)&pluginInfoEx; - #ifdef _UNICODE - #ifdef _X64 - CallService(MS_UPDATE_REGISTERFL, (WPARAM)4435, (LPARAM)pluginInfoPtr); //x64 version - #else - CallService(MS_UPDATE_REGISTERFL, (WPARAM)4405, (LPARAM)pluginInfoPtr); //Unicode version - #endif - #else - CallService(MS_UPDATE_REGISTERFL, (WPARAM)4404, (LPARAM)pluginInfoPtr); //ANSI version - #endif - } - - return 0; -} - -static int tlenProtoUninit( TlenProtocol *proto ) -{ - uninitMenuItems(proto); - TlenVoiceCancelAll(proto); - TlenFileCancelAll(proto); - if (proto->hTlenNudge) - DestroyHookableEvent(proto->hTlenNudge); - UnhookEvents_Ex(proto); - JabberListUninit(proto); - JabberIqUninit(proto); - JabberSerialUninit(proto); - DeleteCriticalSection(&proto->modeMsgMutex); - DeleteCriticalSection(&proto->csSend); - //DestroyServices_Ex(proto); - JabberWsUninit(proto); - mir_free(proto->modeMsgs.szOnline); - mir_free(proto->modeMsgs.szAway); - mir_free(proto->modeMsgs.szNa); - mir_free(proto->modeMsgs.szDnd); - mir_free(proto->modeMsgs.szFreechat); - mir_free(proto->modeMsgs.szInvisible); - mir_free(proto); - return 0; -} - -int __declspec(dllexport) Load(PLUGINLINK *link) -{ - PROTOCOLDESCRIPTOR pd; - - pluginLink = link; - mir_getMMI( &mmi ); - mir_getMD5I( &md5i ); - mir_getSHA1I( &sha1i ); - mir_getUTFI( &utfi ); - - DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hMainThread, THREAD_SET_CONTEXT, FALSE, 0); - - srand((unsigned) time(NULL)); - - TlenRegisterIcons(); - - // Register protocol module - ZeroMemory(&pd, sizeof(PROTOCOLDESCRIPTOR)); - pd.cbSize = sizeof(PROTOCOLDESCRIPTOR); - pd.szName = "TLEN"; - pd.fnInit = ( pfnInitProto )tlenProtoInit; - pd.fnUninit = ( pfnUninitProto )tlenProtoUninit; - pd.type = PROTOTYPE_PROTOCOL; - CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM) &pd); - - return 0; -} - -int __declspec(dllexport) Unload(void) -{ - return 0; -} - diff --git a/!NotAdopted/Tlen/tlen.rc b/!NotAdopted/Tlen/tlen.rc deleted file mode 100644 index ba930c75be..0000000000 --- a/!NotAdopted/Tlen/tlen.rc +++ /dev/null @@ -1,439 +0,0 @@ -#include "resource.h" -#include "commons.h" -#ifdef __MINGW32__ - #define WINVER 0x500 - #define _WIN32_IE 0x500 -#endif -#include -#ifndef IDC_STATIC -#define IDC_STATIC (-1) -#endif -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif -#ifdef APSTUDIO_INVOKED - -1 TEXTINCLUDE DISCARDABLE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE DISCARDABLE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE DISCARDABLE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_ACCMGRUI DIALOGEX 0, 0, 186, 134 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Username:",IDC_STATIC,0,14,38,12,SS_CENTERIMAGE - EDITTEXT IDC_EDIT_USERNAME,65,14,115,12,ES_AUTOHSCROLL - LTEXT "Password:",IDC_STATIC,0,30,38,12,SS_CENTERIMAGE - EDITTEXT IDC_EDIT_PASSWORD,65,30,115,12,ES_PASSWORD | ES_AUTOHSCROLL - CONTROL "Save password",IDC_SAVEPASSWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,46,115,10 - CONTROL "Create new account",IDC_REGISTERACCOUNT,"Hyperlink", - 0x0,0,62,100,8 -END - - -IDD_OPTIONS_BASIC DIALOGEX 0, 0, 304, 200 -STYLE DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg" -BEGIN - GROUPBOX "Tlen",IDC_TLEN,0,0,304,42 - LTEXT "Username:",IDC_STATIC,8,12,52,8 - EDITTEXT IDC_EDIT_USERNAME,70,10,86,12,ES_AUTOHSCROLL - CONTROL "Create new account",IDC_REGISTERACCOUNT,"Hyperlink", - 0x0,170,12,100,8 - LTEXT "Password:",IDC_STATIC,8,26,52,8 - EDITTEXT IDC_EDIT_PASSWORD,70,24,86,12,ES_PASSWORD | - ES_AUTOHSCROLL - CONTROL "Save password",IDC_SAVEPASSWORD,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,170,26,100,10 - GROUPBOX "Options",IDC_SIMPLE,0,44,304,156 - CONTROL "Automatically reconnect after unintentional disconnection", - IDC_RECONNECT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8, 56,239,10 - CONTROL "Leave status message after disconnection", - IDC_OFFLINE_MESSAGE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,8,68,168,10 - COMBOBOX IDC_OFFLINE_MESSAGE_OPTION,190,67,75,140, - CBS_DROPDOWNLIST | WS_TABSTOP - CONTROL "Ignore advertisements", - IDC_IGNORE_ADVERTISEMENTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8, 80,250,10 - CONTROL "Automatically delete contacts not in my roster", - IDC_ROSTER_SYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8, 92,250,10 - CONTROL "Show offline users with status messages as invisible in contact list", - IDC_SHOW_OFFLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 8,104,250,10 - CONTROL "Enable avatars", - IDC_AVATARS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 8,116,250,10 - CONTROL "Send and receive client version information", - IDC_VERSIONINFO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 8,128,250,10 - LTEXT "Alert policy",IDC_STATIC,8,140,70,8 - COMBOBOX IDC_ALERT_POLICY,95,139,190,100, - CBS_DROPDOWNLIST | WS_TABSTOP - CONTROL "Use Nudge plugin", - IDC_NUDGE_SUPPORT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 24,153,120,10 - CONTROL "Log alerts as messages", - IDC_LOG_ALERTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 150,153,130,10 - LTEXT "Group chat policy",IDC_STATIC,8,168,70,8 - COMBOBOX IDC_MUC_POLICY,95,166,190,100, - CBS_DROPDOWNLIST | WS_TABSTOP - LTEXT "Image transfer policy",IDC_STATIC,8,183,70,8 - COMBOBOX IDC_IMAGE_POLICY,95,181,190,100, - CBS_DROPDOWNLIST | WS_TABSTOP -END - - -IDD_OPTIONS_VOICE DIALOGEX 0, 0, 304, 200 -STYLE DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg" -BEGIN - GROUPBOX "Voice Chats",IDC_STATIC,0,0,304,57 - LTEXT "Voice chat policy",IDC_STATIC,8,12,70,8 - COMBOBOX IDC_VOICE_POLICY,95,10,190,100, - CBS_DROPDOWNLIST | WS_TABSTOP - LTEXT "Recording device:",IDC_STATIC,8,26,105,8 - COMBOBOX IDC_VOICE_DEVICE_IN,120,24,110,100,CBS_DROPDOWNLIST | - WS_TABSTOP - LTEXT "Playback device:",IDC_STATIC,8,40,105,8 - COMBOBOX IDC_VOICE_DEVICE_OUT,120,38,110,100,CBS_DROPDOWNLIST | - WS_TABSTOP -END - -IDD_OPTIONS_ADVANCED DIALOGEX 0, 0, 304, 200 -STYLE DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg" -BEGIN - GROUPBOX "Expert Options",IDC_STATIC,0,0,304,74 - LTEXT "Login server:",IDC_STATIC,8,18,75,8 - EDITTEXT IDC_EDIT_LOGIN_SERVER,90,16,90,12,ES_AUTOHSCROLL - LTEXT "Connection Host:",IDC_STATIC,8,32,75,8 - EDITTEXT IDC_HOST,90,30,90,12,ES_AUTOHSCROLL | WS_DISABLED - LTEXT "Port:",IDC_STATIC,194,32,35,8 - EDITTEXT IDC_HOSTPORT,230,30,26,12,ES_AUTOHSCROLL | ES_NUMBER | - WS_DISABLED - CONTROL "Keep connection alive",IDC_KEEPALIVE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,8,47,250,10 - CONTROL "Enable encryption",IDC_USE_SSL,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,8,60,250,10 - - CONTROL "Enable Always Visible and Never Visible", - IDC_VISIBILITY_SUPPORT,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | - WS_TABSTOP,8,60,250,10 - - GROUPBOX "P2P Connections",IDC_STATIC,0,100,304,98 - CONTROL "Use proxy for incoming connections",IDC_FILE_USE_PROXY, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,114,271,10 - LTEXT "Proxy type:",IDC_FILE_PROXY_TYPE_LABEL,10,130,48,8, - WS_DISABLED - COMBOBOX IDC_FILE_PROXY_TYPE,68,128,80,48,CBS_DROPDOWNLIST | - WS_DISABLED | WS_VSCROLL | WS_TABSTOP - LTEXT "Proxy server:",IDC_FILE_PROXY_HOST_LABEL,10,145,48,8, - WS_DISABLED - EDITTEXT IDC_FILE_PROXY_HOST,68,143,80,12,ES_AUTOHSCROLL | - WS_DISABLED | WS_GROUP - LTEXT "Port:",IDC_FILE_PROXY_PORT_LABEL,174,145,25,8, - WS_DISABLED - EDITTEXT IDC_FILE_PROXY_PORT,204,143,30,12,ES_AUTOHSCROLL | - ES_NUMBER | WS_DISABLED - CONTROL "Proxy requires authorization",IDC_FILE_PROXY_USE_AUTH, - "Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,8, - 160,271,10 - LTEXT "Username:",IDC_FILE_PROXY_USER_LABEL,10,176,47,8, - WS_DISABLED - EDITTEXT IDC_FILE_PROXY_USER,68,175,80,12,ES_AUTOHSCROLL | - WS_DISABLED - LTEXT "Password:",IDC_FILE_PROXY_PASSWORD_LABEL,153,176,45,8, - WS_DISABLED - EDITTEXT IDC_FILE_PROXY_PASSWORD,204,175,81,12,ES_PASSWORD | - ES_AUTOHSCROLL | WS_DISABLED - - -END - -IDD_OPTIONS_POPUPS DIALOG DISCARDABLE 0, 0, 304, 143 -STYLE WS_CHILD -FONT 8, "MS Sans Serif" -BEGIN - - GROUPBOX "Mail Notification",IDC_STATIC,0,0,304,110 - CONTROL "Enable incoming mail notification",IDC_ENABLEPOPUP, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,12,267,10 - GROUPBOX "Colours",IDC_STATIC,8,26,140,55 - LTEXT "Background",IDC_STATIC,47,43,95,8 - LTEXT "Text",IDC_STATIC,47,62,96,8 - CONTROL "",IDC_COLORBKG,"ColourPicker",WS_TABSTOP,17,41,24,12 - CONTROL "",IDC_COLORTXT,"ColourPicker",WS_TABSTOP,17,59,24,12 - GROUPBOX "Delay",IDC_STATIC,157,26,140,55 - CONTROL "&From PopUp plugin",IDC_DELAY_POPUP,"Button", - BS_AUTORADIOBUTTON,164,40,125,10 - CONTROL "&Custom",IDC_DELAY_CUSTOM,"Button",BS_AUTORADIOBUTTON, - 164,53,98,10 - EDITTEXT IDC_DELAY,267,51,21,14,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "P&ermanent",IDC_DELAY_PERMANENT,"Button", - BS_AUTORADIOBUTTON,164,67,123,10 - PUSHBUTTON "Preview",IDC_PREVIEW,119,90,70,14 -END - -IDD_PASSWORD DIALOG DISCARDABLE 0, 0, 151, 63 -STYLE DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | - WS_VISIBLE | WS_CAPTION -CAPTION "Jabber Password" -FONT 8, "MS Shell Dlg" -BEGIN - EDITTEXT IDC_JID,7,7,137,12,ES_READONLY | NOT WS_BORDER | NOT - WS_TABSTOP - EDITTEXT IDC_PASSWORD,7,22,137,12,ES_PASSWORD | ES_AUTOHSCROLL - DEFPUSHBUTTON "OK",IDOK,23,42,50,14 - PUSHBUTTON "Cancel",IDCANCEL,77,42,50,14 -END - -IDD_USER_VCARD DIALOGEX 0, 0, 222, 140 -STYLE DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Nick name:",IDC_STATIC,5,8,51,8 - EDITTEXT IDC_NICKNAME,58,6,102,12,ES_AUTOHSCROLL - LTEXT "First name:",IDC_STATIC,5,21,51,8 - EDITTEXT IDC_FIRSTNAME,58,19,102,12,ES_AUTOHSCROLL - LTEXT "Last name:",IDC_STATIC,5,34,51,8 - EDITTEXT IDC_LASTNAME,58,32,102,12,ES_AUTOHSCROLL - LTEXT "E-mail:",IDC_STATIC,5,47,51,8 - EDITTEXT IDC_EMAIL,58,45,102,12,ES_AUTOHSCROLL - LTEXT "Gender:",IDC_STATIC,5,61,51,8 - COMBOBOX IDC_GENDER,58,59,55,52,CBS_DROPDOWN | WS_VSCROLL | - WS_TABSTOP - LTEXT "Year of birth:",IDC_STATIC,120,61,53,8 - EDITTEXT IDC_AGE,176,59,27,12,ES_AUTOHSCROLL - LTEXT "City:",IDC_STATIC,6,75,51,8 - EDITTEXT IDC_CITY,58,73,102,12,ES_AUTOHSCROLL - LTEXT "School:",IDC_STATIC,5,88,51,8 - EDITTEXT IDC_SCHOOL,58,86,102,12,ES_AUTOHSCROLL - LTEXT "Occupation:",IDC_STATIC,5,102,51,8 - COMBOBOX IDC_OCCUPATION,57,100,102,96,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Looking for:",IDC_STATIC,5,116,51,8 - COMBOBOX IDC_LOOKFOR,57,114,102,96,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - CONTROL "Voice chats",IDC_VOICECONVERSATIONS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,5,130,107,10 - CONTROL "Publicly visible status",IDC_PUBLICSTATUS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,112,130,107,10 - PUSHBUTTON "Save changes",IDC_SAVE,164,111,53,16 -END - -IDD_USER_CHANGEAVATAR DIALOGEX 0, 0, 180, 80 -STYLE DS_SETFONT | DS_3DLOOK | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -CAPTION "Avatar" -BEGIN - GROUPBOX "Avatar Options",IDC_STATIC,5,2,170,55 - CONTROL "Public avatar",IDC_PUBLICAVATAR,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,15,15,150,13 - PUSHBUTTON "OK",IDOK,115,62,60,13 -END - - -IDD_USER_INFO DIALOG DISCARDABLE 0, 0, 222, 146 -STYLE DS_FIXEDSYS | WS_CHILD -FONT 8, "MS Shell Dlg" -BEGIN - LTEXT "Tlen login:",IDC_STATIC,5,2,48,8 - EDITTEXT IDC_INFO_JID,53,2,73,12,ES_AUTOHSCROLL | ES_READONLY | - NOT WS_BORDER - LTEXT "Subscription:",IDC_STATIC,5,14,48,8,NOT WS_GROUP - EDITTEXT IDC_SUBSCRIPTION,53,14,131,12,ES_READONLY | NOT WS_BORDER | - NOT WS_TABSTOP - LTEXT "School:",IDC_STATIC,5,44,48,8 - EDITTEXT IDC_SCHOOL,53,44,131,12,ES_AUTOHSCROLL | ES_READONLY | - NOT WS_BORDER - LTEXT "Occupation:",IDC_STATIC,5,56,48,8 - EDITTEXT IDC_OCCUPATION_TEXT,53,56,135,12,ES_AUTOHSCROLL | - ES_READONLY | NOT WS_BORDER - LTEXT "Looking for:",IDC_STATIC,5,68,48,8 - EDITTEXT IDC_LOOKFOR_TEXT,53,68,136,12,ES_AUTOHSCROLL | - ES_READONLY | NOT WS_BORDER - LTEXT "Software:",IDC_STATIC,5,100,48,8 - EDITTEXT IDC_SOFTWARE,54,100,140,12,ES_AUTOHSCROLL | ES_READONLY | - NOT WS_BORDER | NOT WS_TABSTOP - LTEXT "Version:",IDC_STATIC,5,112,48,8 - EDITTEXT IDC_VERSION,54,112,140,12,ES_AUTOHSCROLL | ES_READONLY | - NOT WS_BORDER | NOT WS_TABSTOP - LTEXT "System:",IDC_STATIC,5,124,48,8 - EDITTEXT IDC_SYSTEM,54,124,140,12,ES_AUTOHSCROLL | ES_READONLY | - NOT WS_BORDER | NOT WS_TABSTOP -END - -IDD_ADVSEARCH DIALOGEX 0, 0, 334, 178 -STYLE DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_BORDER -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "Personal Information",IDC_PERSONALGROUP,7,7,156,164 - LTEXT "First name:",IDC_STATIC,15,22,50,8 - EDITTEXT IDC_FIRSTNAME,65,20,91,12,ES_AUTOHSCROLL - LTEXT "Last name:",IDC_STATIC,15,37,50,8 - EDITTEXT IDC_LASTNAME,65,35,91,12,ES_AUTOHSCROLL - LTEXT "Nickname:",IDC_STATIC,15,52,50,8 - EDITTEXT IDC_NICK,65,50,91,12,ES_AUTOHSCROLL - LTEXT "E-mail:",IDC_STATIC,15,67,50,8 - EDITTEXT IDC_EMAIL,65,65,91,12,ES_AUTOHSCROLL - LTEXT "Gender:",IDC_STATIC,15,85,50,8 - COMBOBOX IDC_GENDER,65,83,91,51,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "Age:",IDC_STATIC,15,100,50,8 - EDITTEXT IDC_AGEFROM,65,98,27,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "to",IDC_STATIC,98,100,21,8 - EDITTEXT IDC_AGETO,123,98,27,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "City:",IDC_STATIC,15,118,50,8 - EDITTEXT IDC_CITY,65,116,91,12,ES_AUTOHSCROLL - LTEXT "Occupation:",IDC_STATIC,15,135,50,8 - COMBOBOX IDC_OCCUPATION,65,133,91,93,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "School:",IDC_STATIC,15,150,50,8 - EDITTEXT IDC_SCHOOL,65,148,91,12,ES_AUTOHSCROLL - GROUPBOX "Extra Search Criterias",IDC_EXTRAGROUP,171,7,156,67 - LTEXT "Status:",IDC_STATIC,177,22,50,8 - COMBOBOX IDC_STATUS,227,20,91,113,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "Looking for:",IDC_STATIC,177,37,50,8 - COMBOBOX IDC_LOOKFOR,227,35,91,172,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "Plan:",IDC_STATIC,177,52,50,8,WS_DISABLED - COMBOBOX IDC_PLAN,227,50,91,113,CBS_DROPDOWNLIST | WS_DISABLED | - WS_VSCROLL | WS_TABSTOP -END - -IDD_VOICE DIALOG DISCARDABLE 0, 0, 151, 122 -STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | - WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Tlen Voice Chat" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "",IDC_MICROPHONE,"MButtonClass",0x0,12,7,16,16, - 0x18000000L - CONTROL "",IDC_VUMETERIN,"Static",SS_OWNERDRAW,47,10,120,8 - CONTROL "",IDC_SPEAKER,"MButtonClass",0x0,12,29,16,16, - 0x18000000L - CONTROL "",IDC_VUMETEROUT,"Static",SS_OWNERDRAW,47,31,120,8 - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,7,53,140,4 - LTEXT "Quality",IDC_STATIC,10,64,45,8 - COMBOBOX IDC_VCQUALITY,55,62,88,100,CBS_DROPDOWNLIST | WS_VSCROLL - LTEXT "In",IDC_STATIC,10,80,25,8 - LTEXT "",IDC_BYTESIN,35,80,30,8 - LTEXT "Out",IDC_STATIC,90,80,25,8 - LTEXT "",IDC_BYTESOUT,115,80,30,8 - EDITTEXT IDC_STATUS,10,91,131,8,ES_CENTER | ES_AUTOHSCROLL | - WS_DISABLED | NOT WS_BORDER - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,7,100,140,4 - PUSHBUTTON "Finish",IDCANCEL,50,106,50,14 -END - -IDD_ACCEPT_VOICE DIALOG DISCARDABLE 0, 0, 210, 70 -STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | - WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Tlen Voice Chat Invitation" -FONT 8, "MS Shell Dlg" -BEGIN - DEFPUSHBUTTON "&Accept",IDC_ACCEPT,98,50,50,14 - PUSHBUTTON "Cancel",IDCANCEL,155,50,50,14 - LTEXT "From:",IDC_STATIC,25,24,60,8 - LTEXT "The following invitation to join a voice chat is received.", - IDC_STATIC,3,4,204,8 - EDITTEXT IDC_FROM,85,20,100,12,ES_AUTOHSCROLL | ES_READONLY - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,3,40,203,4 -END - - -#ifndef _MAC -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION TLEN_FILEVERSION_STRING - PRODUCTVERSION TLEN_FILEVERSION_STRING - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "041504e3" - BEGIN - VALUE "Comments", "\0" - VALUE "CompanyName", "http://mtlen.berlios.de\0" - VALUE "FileDescription", "Tlen Protocol Plugin for Miranda IM\0" - VALUE "FileVersion", TLEN_VERSION_STRING - VALUE "InternalName", "tlen\0" - VALUE "LegalCopyright", "Copyright (c) 2002-2011 Santithorn Bunchua, Piotr Piastucki\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "tlen.dll\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "Tlen Protocol Plugin\0" - VALUE "ProductVersion", TLEN_VERSION_STRING - VALUE "SpecialBuild", "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x415, 1251 - END -END - -#endif // !_MAC - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_TLEN ICON DISCARDABLE "icos/tlen.ico" -IDI_MAIL ICON DISCARDABLE "icos/mail.ico" -IDI_MUC ICON DISCARDABLE "icos/groupchats.ico" -IDI_CHATS ICON DISCARDABLE "icos/tlenchats.ico" -IDI_GRANT ICON DISCARDABLE "icos/auth_grant.ico" -IDI_REQUEST ICON DISCARDABLE "icos/auth_request.ico" -IDI_VOICE ICON DISCARDABLE "icos/voicechat.ico" -IDI_MICROPHONE ICON DISCARDABLE "icos/microphone.ico" -IDI_SPEAKER ICON DISCARDABLE "icos/speaker.ico" -IDI_IMAGE ICON DISCARDABLE "icos/image.ico" -#endif // English (U.S.) resources - - - diff --git a/!NotAdopted/Tlen/tlen_10.vcxproj b/!NotAdopted/Tlen/tlen_10.vcxproj deleted file mode 100644 index 606d56b8d8..0000000000 --- a/!NotAdopted/Tlen/tlen_10.vcxproj +++ /dev/null @@ -1,928 +0,0 @@ -п»ї - - - - Debug Ansi - x64 - - - Debug Unicode - Win32 - - - Debug Unicode - x64 - - - Debug x64 - Win32 - - - Debug Ansi - Win32 - - - Debug x64 - x64 - - - Release Ansi - x64 - - - Release Unicode - Win32 - - - Release Unicode - x64 - - - Release x64 - Win32 - - - Release Ansi - Win32 - - - Release x64 - x64 - - - - tlen - {33276462-8313-4192-8306-13717ECCA60A} - jabber - - - - DynamicLibrary - false - Unicode - Windows7.1SDK - - - DynamicLibrary - false - Unicode - Windows7.1SDK - - - DynamicLibrary - false - Unicode - Windows7.1SDK - - - DynamicLibrary - false - Unicode - Windows7.1SDK - - - DynamicLibrary - false - Unicode - true - Windows7.1SDK - - - DynamicLibrary - false - Unicode - true - Windows7.1SDK - - - DynamicLibrary - false - Unicode - true - Windows7.1SDK - - - DynamicLibrary - false - Unicode - true - Windows7.1SDK - - - DynamicLibrary - false - MultiByte - true - Windows7.1SDK - - - DynamicLibrary - false - MultiByte - true - Windows7.1SDK - - - DynamicLibrary - false - MultiByte - Windows7.1SDK - - - DynamicLibrary - false - MultiByte - Windows7.1SDK - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)$(Configuration)/Plugins\ - $(SolutionDir)$(Configuration)/Plugins\ - $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ - $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ - true - true - $(SolutionDir)$(Configuration)/Plugins\ - $(SolutionDir)$(Configuration)/Plugins\ - $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ - $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ - true - true - $(SolutionDir)$(Configuration)/Plugins\ - $(SolutionDir)$(Configuration)/Plugins\ - $(SolutionDir)$(Configuration)/Plugins\ - $(SolutionDir)$(Configuration)/Plugins\ - $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ - $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ - $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ - $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ - true - true - true - true - $(SolutionDir)$(Configuration)/Plugins\ - $(SolutionDir)$(Configuration)/Plugins\ - $(SolutionDir)$(Configuration)/Plugins\ - $(SolutionDir)$(Configuration)/Plugins\ - $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ - $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ - $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ - $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ - true - true - true - true - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Debug/jabber.tlb - - - - - Disabled - ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) - - - EnableFastChecks - MultiThreadedDebugDLL - true - - - jabber.h - - - - - Level3 - true - EditAndContinue - Default - 4996;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) - true - true - false - - - 0x32500000 - false - - - $(IntDir)$(TargetName).lib - MachineX86 - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - .\Debug/jabber.tlb - - - - - Disabled - ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) - - - EnableFastChecks - MultiThreadedDebugDLL - true - - - jabber.h - - - - - Level3 - true - ProgramDatabase - Default - 4996;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) - true - true - false - - - 0x32500000 - false - - - $(IntDir)$(TargetName).lib - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Release/jabber.tlb - - - - - Full - OnlyExplicitInline - Size - true - ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) - true - - - MultiThreaded - true - - - jabber.h - - - - - Level3 - true - ProgramDatabase - Default - 4996;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - /ALIGN:4096 /ignore:4108 %(AdditionalOptions) - wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) - true - true - false - - - true - true - UseLinkTimeCodeGeneration - 0x32500000 - false - - - $(IntDir)$(TargetName).lib - MachineX86 - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - .\Release/jabber.tlb - - - - - Full - OnlyExplicitInline - Size - true - ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) - true - - - MultiThreaded - true - - - jabber.h - - - - - Level3 - true - ProgramDatabase - Default - 4996;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - /ALIGN:4096 /ignore:4108 %(AdditionalOptions) - wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) - true - true - false - - - true - true - UseLinkTimeCodeGeneration - 0x32500000 - false - - - $(IntDir)$(TargetName).lib - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Release/jabber.tlb - - - - - Full - OnlyExplicitInline - Size - true - ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) - true - - - MultiThreaded - true - - - jabber.h - AssemblyAndSourceCode - - - Level3 - true - ProgramDatabase - Default - 4996;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - /ALIGN:4096 /ignore:4108 %(AdditionalOptions) - wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) - type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27X86%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies) - true - true - true - UseLinkTimeCodeGeneration - 0x32500000 - false - - - $(IntDir)$(TargetName).lib - MachineX86 - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - .\Release/jabber.tlb - - - - - Full - OnlyExplicitInline - Size - true - ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) - true - - - MultiThreaded - true - - - jabber.h - AssemblyAndSourceCode - - - Level3 - true - ProgramDatabase - Default - 4996;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - /ALIGN:4096 /ignore:4108 %(AdditionalOptions) - wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) - type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27X86%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies) - true - true - true - UseLinkTimeCodeGeneration - 0x32500000 - false - - - $(IntDir)$(TargetName).lib - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Release/jabber.tlb - - - - - Full - OnlyExplicitInline - Size - true - ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_X64;X64;NDEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) - true - - - MultiThreaded - true - - - jabber.h - AssemblyAndSourceCode - - - Level3 - true - ProgramDatabase - Default - 4996;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - /ALIGN:4096 /ignore:4108 %(AdditionalOptions) - wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) - type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27X86%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies) - true - true - true - UseLinkTimeCodeGeneration - 0x32500000 - false - - - $(IntDir)$(TargetName).lib - MachineX64 - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - .\Release/jabber.tlb - - - - - Full - OnlyExplicitInline - Size - true - ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_X64;X64;NDEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) - true - - - MultiThreaded - true - - - jabber.h - AssemblyAndSourceCode - - - Level3 - true - ProgramDatabase - Default - 4996;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - /ALIGN:4096 /ignore:4108 %(AdditionalOptions) - wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) - type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27X86%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies) - true - true - true - UseLinkTimeCodeGeneration - 0x32500000 - false - - - $(IntDir)$(TargetName).lib - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Debug/jabber.tlb - - - - - Disabled - ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) - false - - - EnableFastChecks - MultiThreadedDebugDLL - true - Precise - - - jabber.h - - - - - Level3 - true - EditAndContinue - Default - 4996;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) - true - true - $(TargetDir)$(TargetName).pdb - false - - - 0x32500000 - false - - - $(IntDir)$(TargetName).lib - MachineX86 - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - .\Debug/jabber.tlb - - - - - Disabled - ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) - false - - - EnableFastChecks - MultiThreadedDebugDLL - true - Precise - - - jabber.h - - - - - Level3 - true - ProgramDatabase - Default - 4996;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) - true - true - $(TargetDir)$(TargetName).pdb - false - - - 0x32500000 - false - - - $(IntDir)$(TargetName).lib - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Debug/jabber.tlb - - - - - Disabled - ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_X64;X64;_DEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) - false - - - EnableFastChecks - MultiThreadedDebugDLL - true - Precise - - - jabber.h - - - - - Level3 - true - ProgramDatabase - Default - 4996;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) - true - true - $(TargetDir)$(TargetName).pdb - false - - - 0x32500000 - false - - - $(IntDir)$(TargetName).lib - MachineX64 - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - .\Debug/jabber.tlb - - - - - Disabled - ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_X64;X64;_DEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) - false - - - EnableFastChecks - MultiThreadedDebugDLL - true - Precise - - - jabber.h - - - - - Level3 - true - ProgramDatabase - Default - 4996;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) - true - true - $(TargetDir)$(TargetName).pdb - false - - - 0x32500000 - false - - - $(IntDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/!NotAdopted/Tlen/tlen_advsearch.c b/!NotAdopted/Tlen/tlen_advsearch.c deleted file mode 100644 index 5e3d5465b8..0000000000 --- a/!NotAdopted/Tlen/tlen_advsearch.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include "resource.h" - -static void InitComboBox(HWND hwndCombo, JABBER_FIELD_MAP *fieldMap) -{ - int i, n; - - n = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)_T("")); - SendMessage(hwndCombo, CB_SETITEMDATA, n, 0); - SendMessage(hwndCombo, CB_SETCURSEL, n, 0); - for(i=0;;i++) { - if (fieldMap[i].name == NULL) - break; - n = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) TranslateTS(fieldMap[i].name)); - SendMessage(hwndCombo, CB_SETITEMDATA, n, fieldMap[i].id); - } -} - -INT_PTR CALLBACK TlenAdvSearchDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - InitComboBox(GetDlgItem(hwndDlg, IDC_GENDER), tlenFieldGender); - InitComboBox(GetDlgItem(hwndDlg, IDC_LOOKFOR), tlenFieldLookfor); - InitComboBox(GetDlgItem(hwndDlg, IDC_STATUS), tlenFieldStatus); - InitComboBox(GetDlgItem(hwndDlg, IDC_OCCUPATION), tlenFieldOccupation); - InitComboBox(GetDlgItem(hwndDlg, IDC_PLAN), tlenFieldPlan); - return TRUE; - } - return FALSE; -} - -static void FetchField(HWND hwndDlg, UINT idCtrl, char *fieldName, char **str, int *strSize) -{ - char text[512]; - char *localFieldName, *localText; - - if (hwndDlg==NULL || fieldName==NULL || str==NULL || strSize==NULL) - return; - GetDlgItemTextA(hwndDlg, idCtrl, text, sizeof(text)); - if (text[0]) { - if ((localFieldName=JabberTextEncode(fieldName)) != NULL) { - if ((localText=JabberTextEncode(text)) != NULL) { - JabberStringAppend(str, strSize, "<%s>%s", localFieldName, localText, localFieldName); - mir_free(localText); - } - mir_free(localFieldName); - } - } -} - -static void FetchCombo(HWND hwndDlg, UINT idCtrl, char *fieldName, char **str, int *strSize) -{ - int value; - char *localFieldName; - - if (hwndDlg==NULL || fieldName==NULL || str==NULL || strSize==NULL) - return; - value = (int) SendDlgItemMessage(hwndDlg, idCtrl, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, idCtrl, CB_GETCURSEL, 0, 0), 0); - if (value > 0) { - if ((localFieldName=JabberTextEncode(fieldName)) != NULL) { - JabberStringAppend(str, strSize, "<%s>%d", localFieldName, value, localFieldName); - mir_free(localFieldName); - } - } -} - -char *TlenAdvSearchCreateQuery(HWND hwndDlg, int iqId) -{ - char *str; - int strSize; - - if (hwndDlg == NULL) return NULL; - str = NULL; - FetchField(hwndDlg, IDC_FIRSTNAME, "first", &str, &strSize); - FetchField(hwndDlg, IDC_LASTNAME, "last", &str, &strSize); - FetchField(hwndDlg, IDC_NICK, "nick", &str, &strSize); - FetchField(hwndDlg, IDC_EMAIL, "email", &str, &strSize); - FetchCombo(hwndDlg, IDC_GENDER, "s", &str, &strSize); - FetchField(hwndDlg, IDC_AGEFROM, "d", &str, &strSize); - FetchField(hwndDlg, IDC_AGETO, "u", &str, &strSize); - FetchField(hwndDlg, IDC_CITY, "c", &str, &strSize); - FetchCombo(hwndDlg, IDC_OCCUPATION, "j", &str, &strSize); - FetchField(hwndDlg, IDC_SCHOOL, "e", &str, &strSize); - FetchCombo(hwndDlg, IDC_STATUS, "m", &str, &strSize); - FetchCombo(hwndDlg, IDC_LOOKFOR, "r", &str, &strSize); - FetchCombo(hwndDlg, IDC_PLAN, "p", &str, &strSize); - return str; -} diff --git a/!NotAdopted/Tlen/tlen_avatar.c b/!NotAdopted/Tlen/tlen_avatar.c deleted file mode 100644 index e06c793344..0000000000 --- a/!NotAdopted/Tlen/tlen_avatar.c +++ /dev/null @@ -1,422 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include -#include "jabber.h" -#include "jabber_list.h" -#include "tlen_avatar.h" -#include -#include -#include -#include - -/* TlenGetAvatarFileName() - gets a file name for the avatar image */ - -void TlenGetAvatarFileName(TlenProtocol *proto, JABBER_LIST_ITEM *item, char* pszDest, int cbLen) -{ - DWORD dwAttributes; - int tPathLen; - int format = PA_FORMAT_PNG; - char* szFileType; - char *tmpPath = Utils_ReplaceVars( "%miranda_avatarcache%" ); - tPathLen = mir_snprintf( pszDest, cbLen, "%s\\Tlen", tmpPath ); - mir_free(tmpPath); - dwAttributes = GetFileAttributesA( pszDest ); - if ( dwAttributes == 0xffffffff || ( dwAttributes & FILE_ATTRIBUTE_DIRECTORY ) == 0 ) { - CallService( MS_UTILS_CREATEDIRTREE, 0, ( LPARAM )pszDest ); - } - pszDest[ tPathLen++ ] = '\\'; - if (item != NULL) { - format = item->avatarFormat; - } else if (proto->threadData != NULL) { - format = proto->threadData->avatarFormat; - } else { - format = DBGetContactSettingDword(NULL, proto->iface.m_szModuleName, "AvatarFormat", PA_FORMAT_UNKNOWN); - } - szFileType = "png"; - switch(format) { - case PA_FORMAT_JPEG: szFileType = "jpg"; break; - case PA_FORMAT_ICON: szFileType = "ico"; break; - case PA_FORMAT_PNG: szFileType = "png"; break; - case PA_FORMAT_GIF: szFileType = "gif"; break; - case PA_FORMAT_BMP: szFileType = "bmp"; break; - } - if ( item != NULL ) { - char* hash; - hash = JabberSha1(item->jid); - mir_snprintf( pszDest + tPathLen, MAX_PATH - tPathLen, "%s.%s", hash, szFileType ); - mir_free( hash ); - } else { - mir_snprintf( pszDest + tPathLen, MAX_PATH - tPathLen, "%s_avatar.%s", proto->iface.m_szModuleName, szFileType ); - } -} - -static void RemoveAvatar(TlenProtocol *proto, HANDLE hContact) { - char tFileName[ MAX_PATH ]; - if (hContact == NULL) { - proto->threadData->avatarHash[0] = '\0'; - } - TlenGetAvatarFileName( proto, NULL, tFileName, sizeof tFileName ); - DeleteFileA(tFileName); - DBDeleteContactSetting(hContact, "ContactPhoto", "File"); - DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "AvatarHash"); - DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "AvatarFormat"); - ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_AVATAR, ACKRESULT_STATUS, NULL, 0); -} - -static void SetAvatar(TlenProtocol *proto, HANDLE hContact, JABBER_LIST_ITEM *item, char *data, int len, DWORD format) { - FILE* out; - char filename[MAX_PATH]; - char md5[33]; - mir_md5_state_t ctx; - DWORD digest[4]; - - if (format == PA_FORMAT_UNKNOWN && len > 4) { - format = JabberGetPictureType(data); - } - - mir_md5_init( &ctx ); - mir_md5_append( &ctx, ( BYTE* )data, len); - mir_md5_finish( &ctx, ( BYTE* )digest ); - - sprintf( md5, "%08x%08x%08x%08x", (int)htonl(digest[0]), (int)htonl(digest[1]), (int)htonl(digest[2]), (int)htonl(digest[3])); - if (item != NULL) { - char *hash = item->avatarHash; - item->avatarFormat = format; - item->avatarHash = mir_strdup(md5); - mir_free(hash); - } else { - proto->threadData->avatarFormat = format; - strcpy(proto->threadData->avatarHash, md5); - } - TlenGetAvatarFileName(proto, item, filename, sizeof filename ); - DeleteFileA(filename); - out = fopen( filename, "wb" ); - if ( out != NULL ) { - fwrite( data, len, 1, out ); - fclose( out ); - DBWriteContactSettingString(hContact, "ContactPhoto", "File", filename ); - DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "AvatarHash", md5); - DBWriteContactSettingDword(hContact, proto->iface.m_szModuleName, "AvatarFormat", format); - } - ProtoBroadcastAck( proto->iface.m_szModuleName, hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, NULL , 0); -} - -int TlenProcessAvatarNode(TlenProtocol *proto, XmlNode *avatarNode, JABBER_LIST_ITEM *item) { - XmlNode *aNode; - char *oldHash = NULL; - char *md5 = NULL, *type = NULL; - HANDLE hContact; - hContact = NULL; - if (item != NULL) { - if ((hContact=JabberHContactFromJID(proto, item->jid)) == NULL) return 0; - } - if (item == NULL) { - oldHash = proto->threadData->avatarHash; - } else { - oldHash = item->avatarHash; - } - if (avatarNode != NULL) { - aNode = JabberXmlGetChild(avatarNode, "a"); - if (aNode != NULL) { - type = JabberXmlGetAttrValue(aNode, "type"); - md5 = JabberXmlGetAttrValue(aNode, "md5"); - } - } - if (md5 != NULL) { - /* check contact's avatar hash - md5 */ - if (oldHash == NULL || strcmp(oldHash, md5)) { - if (item != NULL) { - item->newAvatarDownloading = TRUE; - } - TlenGetAvatar(proto, hContact); - return 1; - } - } else { - /* remove avatar */ - if (oldHash != NULL) { - if (item != NULL) { - item->avatarHash = NULL; - mir_free(oldHash); - item->newAvatarDownloading = FALSE; - } - RemoveAvatar(proto, hContact); - return 1; - } - } - return 0; -} - -void TlenProcessPresenceAvatar(TlenProtocol *proto, XmlNode *node, JABBER_LIST_ITEM *item) { - HANDLE hContact; - if ((hContact=JabberHContactFromJID(proto, item->jid)) == NULL) return; - TlenProcessAvatarNode(proto, JabberXmlGetChild(node, "avatar"), item); -} - - -static char *replaceTokens(const char *base, const char *uri, const char *login, const char* token, int type, int access) { - char *result; - int i, l, size; - l = (int)strlen(uri); - size = (int)strlen(base); - for (i = 0; i < l; ) { - if (!strncmp(uri + i, "^login^", 7)) { - size += (int)strlen(login); - i += 7; - } else if (!strncmp(uri + i, "^type^", 6)) { - size++; - i += 6; - } else if (!strncmp(uri + i, "^token^", 7)) { - size += (int)strlen(token); - i += 7; - } else if (!strncmp(uri + i, "^access^", 8)) { - size++; - i += 8; - } else { - size++; - i++; - } - } - result = (char *)mir_alloc(size +1); - strcpy(result, base); - size = (int)strlen(base); - for (i = 0; i < l; ) { - if (!strncmp(uri + i, "^login^", 7)) { - strcpy(result + size, login); - size += (int)strlen(login); - i += 7; - } else if (!strncmp(uri + i, "^type^", 6)) { - result[size++] = '0' + type; - i += 6; - } else if (!strncmp(uri + i, "^token^", 7)) { - strcpy(result + size, token); - size += (int)strlen(token); - i += 7; - } else if (!strncmp(uri + i, "^access^", 8)) { - result[size++] = '0' + access; - i += 8; - } else { - result[size++] = uri[i++]; - } - } - result[size] = '\0'; - return result; -} - - -static int getAvatarMutex = 0; - -typedef struct { - TlenProtocol *proto; - HANDLE hContact; -} TLENGETAVATARTHREADDATA; - -static void TlenGetAvatarThread(void *ptr) { - - JABBER_LIST_ITEM *item = NULL; - NETLIBHTTPREQUEST req; - NETLIBHTTPREQUEST *resp; - TLENGETAVATARTHREADDATA *data = (TLENGETAVATARTHREADDATA *)ptr; - HANDLE hContact = data->hContact; - char *request; - char *login = NULL; - if (hContact != NULL) { - char *jid = JabberJIDFromHContact(data->proto, hContact); - login = JabberNickFromJID(jid); - item = JabberListGetItemPtr(data->proto, LIST_ROSTER, jid); - mir_free(jid); - } else { - login = mir_strdup(data->proto->threadData->username); - } - if ((data->proto->threadData != NULL && hContact == NULL) || item != NULL) { - DWORD format = PA_FORMAT_UNKNOWN; - if (item!= NULL) { - item->newAvatarDownloading = TRUE; - } - request = replaceTokens(data->proto->threadData->tlenConfig.mailBase, data->proto->threadData->tlenConfig.avatarGet, login, data->proto->threadData->avatarToken, 0, 0); - ZeroMemory(&req, sizeof(req)); - req.cbSize = sizeof(req); - req.requestType = data->proto->threadData->tlenConfig.avatarGetMthd; - req.flags = 0; - req.headersCount = 0; - req.headers = NULL; - req.dataLength = 0; - req.szUrl = request; - resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->hNetlibUser, (LPARAM)&req); - if (item!= NULL) { - item->newAvatarDownloading = FALSE; - } - if (resp != NULL) { - if (resp->resultCode/100==2) { - if (resp->dataLength > 0) { - int i; - for (i=0; iheadersCount; i++ ) { - if (strcmpi(resp->headers[i].szName, "Content-Type")==0) { - if (strcmpi(resp->headers[i].szValue, "image/png")==0) { - format = PA_FORMAT_PNG; - } else if (strcmpi(resp->headers[i].szValue, "image/x-png")==0) { - format = PA_FORMAT_PNG; - } else if (strcmpi(resp->headers[i].szValue, "image/jpeg")==0) { - format = PA_FORMAT_JPEG; - } else if (strcmpi(resp->headers[i].szValue, "image/jpg")==0) { - format = PA_FORMAT_JPEG; - } else if (strcmpi(resp->headers[i].szValue, "image/gif")==0) { - format = PA_FORMAT_GIF; - } else if (strcmpi(resp->headers[i].szValue, "image/bmp")==0) { - format = PA_FORMAT_BMP; - } - break; - } - } - SetAvatar(data->proto, hContact, item, resp->pData, resp->dataLength, format); - } else { - RemoveAvatar(data->proto, hContact); - } - } - CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); - } - mir_free(request); - mir_free(login); - } - if (hContact == NULL) { - getAvatarMutex = 0; - } - mir_free(data); -} - -void TlenGetAvatar(TlenProtocol *proto, HANDLE hContact) { - if (hContact == NULL) { - if (getAvatarMutex != 0) { - return; - } - getAvatarMutex = 1; - } - { - TLENGETAVATARTHREADDATA *data = (TLENGETAVATARTHREADDATA *)mir_alloc(sizeof(TLENGETAVATARTHREADDATA)); - data->proto = proto; - data->hContact = hContact; - JabberForkThread(TlenGetAvatarThread, 0, data); - } -} - -typedef struct { - TlenProtocol *proto; - NETLIBHTTPREQUEST *req; -}TLENREMOVEAVATARTHREADDATA; - -static void TlenRemoveAvatarRequestThread(void *ptr) { - NETLIBHTTPREQUEST *resp; - TLENREMOVEAVATARTHREADDATA *data = ptr; - NETLIBHTTPREQUEST *req = (NETLIBHTTPREQUEST *)data->req; - resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->hNetlibUser, (LPARAM)req); - mir_free(req->szUrl); - mir_free(req->headers); - mir_free(req->pData); - mir_free(req); - if (resp != NULL) { - CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, (WPARAM)0, (LPARAM)resp); - RemoveAvatar(data->proto, NULL); - } - mir_free(data); - -} - -typedef struct { - TlenProtocol *proto; - NETLIBHTTPREQUEST *req; - char *data; - int length; -}TLENUPLOADAVATARTHREADDATA; - -static void TlenUploadAvatarRequestThread(void *ptr) { - NETLIBHTTPREQUEST *resp; - TLENUPLOADAVATARTHREADDATA * data = (TLENUPLOADAVATARTHREADDATA *) ptr; - NETLIBHTTPREQUEST *req = data->req; - resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->hNetlibUser, (LPARAM)req); - if (resp != NULL) { - CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, (WPARAM)0, (LPARAM)resp); - SetAvatar(data->proto, NULL, NULL, data->data, data->length, PA_FORMAT_PNG); - } - mir_free(req->szUrl); - mir_free(req->headers); - mir_free(req->pData); - mir_free(req); - mir_free(data->data); - mir_free(data); -} - -void TlenRemoveAvatar(TlenProtocol *proto) { - NETLIBHTTPREQUEST *req; - char *request; - if (proto->threadData != NULL) { - TLENREMOVEAVATARTHREADDATA *data = (TLENREMOVEAVATARTHREADDATA *)mir_alloc(sizeof(TLENREMOVEAVATARTHREADDATA)); - req = (NETLIBHTTPREQUEST *)mir_alloc(sizeof(NETLIBHTTPREQUEST)); - data->proto =proto; - data->req = req; - request = replaceTokens(proto->threadData->tlenConfig.mailBase, proto->threadData->tlenConfig.avatarRemove, "", proto->threadData->avatarToken, 0, 0); - ZeroMemory(req, sizeof(NETLIBHTTPREQUEST)); - req->cbSize = sizeof(NETLIBHTTPREQUEST); - req->requestType = proto->threadData->tlenConfig.avatarGetMthd; - req->szUrl = request; - JabberForkThread(TlenRemoveAvatarRequestThread, 0, data); - } -} - - -void TlenUploadAvatar(TlenProtocol *proto, unsigned char *data, int dataLen, int access) { - NETLIBHTTPREQUEST *req; - NETLIBHTTPHEADER *headers; - TLENUPLOADAVATARTHREADDATA *threadData; - char *request; - unsigned char *buffer; - if (proto->threadData != NULL && dataLen > 0 && data != NULL) { - char *mpartHead = "--AaB03x\r\nContent-Disposition: form-data; name=\"filename\"; filename=\"plik.png\"\r\nContent-Type: image/png\r\n\r\n"; - char *mpartTail = "\r\n--AaB03x--\r\n"; - int size, sizeHead = (int)strlen(mpartHead), sizeTail = (int)strlen(mpartTail); - request = replaceTokens(proto->threadData->tlenConfig.mailBase, proto->threadData->tlenConfig.avatarUpload, "", proto->threadData->avatarToken, 0, access); - threadData = (TLENUPLOADAVATARTHREADDATA *)mir_alloc(sizeof(TLENUPLOADAVATARTHREADDATA)); - threadData->proto = proto; - req = (NETLIBHTTPREQUEST *)mir_alloc(sizeof(NETLIBHTTPREQUEST)); - headers = (NETLIBHTTPHEADER *)mir_alloc(sizeof(NETLIBHTTPHEADER)); - ZeroMemory(req, sizeof(NETLIBHTTPREQUEST)); - req->cbSize = sizeof(NETLIBHTTPREQUEST); - req->requestType = proto->threadData->tlenConfig.avatarUploadMthd; - req->szUrl = request; - req->flags = 0; - headers[0].szName = "Content-Type"; - headers[0].szValue = "multipart/form-data; boundary=AaB03x"; - req->headersCount = 1; - req->headers = headers; - size = dataLen + sizeHead + sizeTail; - buffer = mir_alloc(size); - memcpy(buffer, mpartHead, sizeHead); - memcpy(buffer + sizeHead, data, dataLen); - memcpy(buffer + sizeHead + dataLen, mpartTail, sizeTail); - req->dataLength = size; - req->pData = buffer; - threadData->req = req; - threadData->data = (char *) mir_alloc(dataLen); - memcpy(threadData->data, data, dataLen); - threadData->length = dataLen; - JabberForkThread(TlenUploadAvatarRequestThread, 0, threadData); - } -} - diff --git a/!NotAdopted/Tlen/tlen_avatar.h b/!NotAdopted/Tlen/tlen_avatar.h deleted file mode 100644 index 48a258ed38..0000000000 --- a/!NotAdopted/Tlen/tlen_avatar.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#ifndef _TLEN_AVATAR_H_ -#define _TLEN_AVATAR_H_ - -void TlenProcessPresenceAvatar(TlenProtocol *proto, XmlNode *node, JABBER_LIST_ITEM *item); -int TlenProcessAvatarNode(TlenProtocol *proto, XmlNode *avatarNode, JABBER_LIST_ITEM *item); -void TlenGetAvatarFileName(TlenProtocol *proto, JABBER_LIST_ITEM *item, char* pszDest, int cbLen); -void TlenGetAvatar(TlenProtocol *proto, HANDLE hContact); -void TlenUploadAvatar(TlenProtocol *proto, unsigned char *data, int dataLen, int access); -void TlenRemoveAvatar(TlenProtocol *proto); - -#endif // TLEN_AVATAR_H_INCLUDED diff --git a/!NotAdopted/Tlen/tlen_czaty/AdminWindow.cpp b/!NotAdopted/Tlen/tlen_czaty/AdminWindow.cpp deleted file mode 100644 index a29c6fa2f2..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/AdminWindow.cpp +++ /dev/null @@ -1,490 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "AdminWindow.h" -#include "Utils.h" - - -static INT_PTR CALLBACK UserKickDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - int i; - const char *banOptions[]={"No ban", "1 minute", "5 minutes", "15 minutes", "30 minutes", - "1 hour", "6 hours", "1 day", "3 days", "1 week", "2 weeks", "4 weeks"}; - const int banTime[] = {0, 1, 5, 15, 30, 60, 360, 1440, 4320, 10080, 20160, 40320}; - const char *roleOptions[]={"No role", "Member", "Admin", "Moderator"}; - const int roleMask[] = {0, MUCC_EF_USER_MEMBER, MUCC_EF_USER_ADMIN, MUCC_EF_USER_MODERATOR}; - AdminWindow *adminWindow; - adminWindow = (AdminWindow *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - adminWindow = (AdminWindow *) lParam; - TranslateDialogDefault(hwndDlg); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) adminWindow); - adminWindow->setKickTabHWND(hwndDlg); - for (i=0;i<12;i++) { - SendDlgItemMessage(hwndDlg, IDC_KICK_OPTIONS, CB_ADDSTRING, 0, (LPARAM) banOptions[i]); - } - SendDlgItemMessage(hwndDlg, IDC_KICK_OPTIONS, CB_SETCURSEL, 0, 0); - for (i=0;i<3;i++) { - SendDlgItemMessage(hwndDlg, IDC_ROLE_OPTIONS, CB_ADDSTRING, 0, (LPARAM) roleOptions[i]); - } - SendDlgItemMessage(hwndDlg, IDC_ROLE_OPTIONS, CB_SETCURSEL, 0, 0); - SetDlgItemTextA(hwndDlg, IDC_NICK, adminWindow->getNick()); - return FALSE; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - { - char nick[256], reason[256]; - GetDlgItemTextA(hwndDlg, IDC_NICK, nick, sizeof(nick)); - GetDlgItemTextA(hwndDlg, IDC_REASON, reason, sizeof(reason)); - if (strlen(nick)>0) { - int iSel = SendDlgItemMessage(hwndDlg, IDC_KICK_OPTIONS, CB_GETCURSEL, 0, 0); - if (iSel>=0 && iSel<12) { - adminWindow->getParent()->kickAndBan(nick, banTime[iSel] * 60, reason); - } - } - } -// EndDialog(hwndDlg, 1); -// return TRUE; - break; - case IDC_SET_ROLE: - { - char nick[256]; - GetDlgItemTextA(hwndDlg, IDC_NICK, nick, sizeof(nick)); - if (strlen(nick)>0) { - int iSel = SendDlgItemMessage(hwndDlg, IDC_ROLE_OPTIONS, CB_GETCURSEL, 0, 0); - if (iSel>=0 && iSel<3) { - adminWindow->getParent()->setRights(nick, roleMask[iSel]); - } - } - } - break; -// EndDialog(hwndDlg, 1); -// return TRUE; - case IDCANCEL: -// EndDialog(hwndDlg, 0); - return TRUE; - } - break; - case WM_CLOSE: -// EndDialog(hwndDlg, 0); - break; - } - return FALSE; -} - -static INT_PTR CALLBACK UserBrowserDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ int i; - const char *browseOptions[]={"Banned", "Owners", "Administrators", "Members", "Moderators"}; - const int browserFlags[]={MUCC_EF_USER_BANNED, MUCC_EF_USER_OWNER, MUCC_EF_USER_ADMIN, MUCC_EF_USER_MEMBER, MUCC_EF_USER_MODERATOR}; - LVCOLUMN lvCol; - HWND lv; - AdminWindow *adminWindow; - adminWindow = (AdminWindow *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - adminWindow = (AdminWindow *) lParam; - TranslateDialogDefault(hwndDlg); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) adminWindow); - adminWindow->setBrowserTabHWND(hwndDlg); - lv = GetDlgItem(hwndDlg, IDC_LIST); - ListView_SetExtendedListViewStyle(lv, LVS_EX_FULLROWSELECT); - lvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; - lvCol.pszText = TranslateT("Login"); - lvCol.cx = 80; - lvCol.iSubItem = 0; - ListView_InsertColumn(lv, 0, &lvCol); - lvCol.pszText = TranslateT("Nick name"); - lvCol.cx = 80; - lvCol.iSubItem = 1; - ListView_InsertColumn(lv, 1, &lvCol); - lvCol.pszText = TranslateT("When"); - lvCol.cx = 95; - lvCol.iSubItem = 2; - ListView_InsertColumn(lv, 2, &lvCol); - lvCol.pszText = TranslateT("Admin"); - lvCol.cx = 80; - lvCol.iSubItem = 2; - ListView_InsertColumn(lv, 3, &lvCol); - lvCol.pszText = TranslateT("Reason"); - lvCol.cx = 70; - lvCol.iSubItem = 2; - ListView_InsertColumn(lv, 5, &lvCol); - lvCol.pszText = TranslateT("Remaining"); - lvCol.cx = 80; - lvCol.iSubItem = 2; - ListView_InsertColumn(lv, 4, &lvCol); - for (i=0;i<(adminWindow->getParent()->getRoomFlags() & MUCC_EF_ROOM_MEMBERS_ONLY ? 4 : 3);i++) { - SendDlgItemMessage(hwndDlg, IDC_OPTIONS, CB_ADDSTRING, 0, (LPARAM) browseOptions[i]); - } - SendDlgItemMessage(hwndDlg, IDC_OPTIONS, CB_SETCURSEL, 0, 0); - return FALSE; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_SHOW: - int iSel; - iSel = SendDlgItemMessage(hwndDlg, IDC_OPTIONS, CB_GETCURSEL, 0, 0); - if (iSel< 5) { - adminWindow->queryUsers(browserFlags[iSel]); - } - break; -// return TRUE; - case IDCANCEL: -// EndDialog(hwndDlg, 0); - return TRUE; - } - break; - case WM_CLOSE: -// EndDialog(hwndDlg, 0); - break; - case WM_MEASUREITEM: - if (wParam == IDC_LIST) { - MEASUREITEMSTRUCT *lpMis = (MEASUREITEMSTRUCT *) lParam; - lpMis->itemHeight = 16;//GetSystemMetrics(SM_CYSMICON); - return TRUE; - } - break; - case WM_DRAWITEM: - if (wParam == IDC_LIST) { - RECT rc; - int x, w; - TCHAR text[256]; - DRAWITEMSTRUCT *lpDis = (DRAWITEMSTRUCT *) lParam; - switch (lpDis->itemAction) { - default: - case ODA_SELECT: - case ODA_DRAWENTIRE: - if (lpDis->itemState & ODS_SELECTED) { - HBRUSH hBrush = CreateSolidBrush(RGB(0xC2, 0xC8, 0xDA));//0xDAC8C2); - FillRect(lpDis->hDC, &(lpDis->rcItem), hBrush);//(HBRUSH) (COLOR_HIGHLIGHT+1)); - DeleteObject(hBrush); - SetTextColor(lpDis->hDC, 0); - SetBkMode(lpDis->hDC, TRANSPARENT); - } - else { - FillRect(lpDis->hDC, &(lpDis->rcItem), (HBRUSH) (COLOR_WINDOW+1)); - SetTextColor(lpDis->hDC, RGB(0, 0, 0));//GetSysColor(COLOR_WINDOWTEXT)); - SetBkMode(lpDis->hDC, TRANSPARENT); - } - x = lpDis->rcItem.left + 1; - for (int col=0;col<6;col++) { - w = ListView_GetColumnWidth(GetDlgItem(hwndDlg, IDC_LIST), col); - rc.left = x; - rc.top = lpDis->rcItem.top; - rc.bottom = lpDis->rcItem.bottom; - rc.right = x+w-2; - ListView_GetItemText(GetDlgItem(hwndDlg, IDC_LIST), lpDis->itemID, col, text, sizeof(text)/sizeof(TCHAR)); - if (_tcslen(text)==0) { - _tcscpy(text, _TEXT("-")); - } - DrawText(lpDis->hDC, text, (int)_tcslen(text), &rc, DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER); - x+=w; - } - break; - } - } - break; - case WM_NOTIFY: - LPNMHDR pNmhdr; - pNmhdr = (LPNMHDR)lParam; - if (pNmhdr->idFrom == IDC_LIST && adminWindow->getBrowserMode() == MUCC_EF_USER_BANNED) { - switch (pNmhdr->code) { - case NM_RCLICK: - { - LVHITTESTINFO hti; - int hitItem; - hti.pt.x=(short)LOWORD(GetMessagePos()); - hti.pt.y=(short)HIWORD(GetMessagePos()); - ScreenToClient(pNmhdr->hwndFrom, &hti.pt); - if ((hitItem = ListView_HitTest(pNmhdr->hwndFrom,&hti)) !=-1) { - LVITEM lvi = {0}; - HMENU hMenu; - int iSelection; - TCHAR nick[256]; - lvi.mask = TVIF_TEXT; - lvi.iItem = hitItem; - lvi.iSubItem = 0; - lvi.pszText = nick; - lvi.cchTextMax = sizeof(nick)/sizeof(TCHAR); - ListView_GetItem(pNmhdr->hwndFrom, &lvi); - hMenu=GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(IDR_CHATOPTIONS)), 3); - CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)hMenu,0); - iSelection = TrackPopupMenu(hMenu, TPM_RETURNCMD | TPM_TOPALIGN | TPM_LEFTALIGN, (short)LOWORD(GetMessagePos()), (short)HIWORD(GetMessagePos()), 0, hwndDlg, NULL); - DestroyMenu(hMenu); - if (iSelection == ID_USERMENU_UNBAN) { - char* lps1 = Utils::mucc_mir_t2a(nick); - adminWindow->getParent()->unban(lps1); - Utils::mucc_mir_free(lps1); - } - } - - } - break; - } - } - - } - return FALSE; -} - -static INT_PTR CALLBACK AdminDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - HWND hwnd; - TCITEM tci; - HWND tc; - AdminWindow *adminWindow; - adminWindow = (AdminWindow *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - adminWindow = (AdminWindow *) lParam; - TranslateDialogDefault(hwndDlg); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) adminWindow); - SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) muccIcon[MUCC_IDI_ADMINISTRATION]); - - hwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_USER_KICK), hwndDlg, UserKickDlgProc, (LPARAM) adminWindow); - SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - ShowWindow(hwnd, SW_SHOW); - - hwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_USER_BROWSER), hwndDlg, UserBrowserDlgProc, (LPARAM) adminWindow); - SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - adminWindow->setCurrentTab(0); - adminWindow->setHWND(hwndDlg); - - tc = GetDlgItem(hwndDlg, IDC_TABS); - tci.mask = TCIF_TEXT; - tci.pszText = TranslateT("Administration"); - TabCtrl_InsertItem(tc, 0, &tci); - tci.pszText = TranslateT("Browser"); - TabCtrl_InsertItem(tc, 1, &tci); - - return FALSE; - case WM_NOTIFY: - switch (wParam) { - case IDC_TABS: - switch (((LPNMHDR) lParam)->code) { - case TCN_SELCHANGE: - switch (adminWindow->getCurrentTab()) { - case 0: - ShowWindow(adminWindow->getKickTabHWND(), SW_HIDE); - break; - case 1: - ShowWindow(adminWindow->getBrowserTabHWND(), SW_HIDE); - break; - } - adminWindow->setCurrentTab(TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_TABS))); - switch (adminWindow->getCurrentTab()) { - case 0: - ShowWindow(adminWindow->getKickTabHWND(), SW_SHOW); - break; - case 1: - ShowWindow(adminWindow->getBrowserTabHWND(), SW_SHOW); - break; - } - break; - } - break; - } - break; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDCANCEL: - delete adminWindow; - // EndDialog(hwndDlg, 0); - return TRUE; - } - break; - case WM_CLOSE: - delete adminWindow; - // EndDialog(hwndDlg, 0); - break; - } - return FALSE; -} - - - -AdminWindow::AdminWindow(ChatWindow *parent, const char *nick, int mode) { - this->parent = parent; - hWnd = NULL; - browserMode = 0; - this->nick = NULL; - Utils::copyString(&this->nick, nick); -} - -AdminWindow::~AdminWindow() { - - if (hWnd != NULL) { - EndDialog(hWnd, 0); - } - if (parent != NULL) { - parent->setAdminWindow(NULL); - } - if (nick != NULL) { - delete nick; - } -} - -void AdminWindow::start() { - DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_USER_ADMIN), NULL, AdminDlgProc, (LPARAM) this); -} - -void AdminWindow::setHWND(HWND hWnd) { - this->hWnd = hWnd; -} - -void AdminWindow::setCurrentTab(int t) { - currentTab = t; -} - -int AdminWindow::getCurrentTab() { - return currentTab; -} - - -void AdminWindow::setKickTabHWND(HWND hWnd) { - hKickTabWnd = hWnd; -} - -void AdminWindow::setBrowserTabHWND(HWND hWnd) { - hBrowserTabWnd = hWnd; -} - -HWND AdminWindow::getKickTabHWND() { - return hKickTabWnd; -} - -HWND AdminWindow::getBrowserTabHWND() { - return hBrowserTabWnd; -} - -void AdminWindow::queryUsers(int queryType) { - MUCCEVENT muce; - EnableWindow(GetDlgItem(getBrowserTabHWND(), IDC_SHOW), FALSE); - muce.cbSize = sizeof(MUCCEVENT); - muce.iType = MUCC_EVENT_QUERY_USERS; - muce.pszModule = parent->getModule(); - muce.pszID = parent->getRoomId(); - muce.dwFlags = queryType; - browserMode = queryType; - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); -} - -ChatWindow * AdminWindow::getParent() { - return parent; -} - -void AdminWindow::queryResultUsers(MUCCQUERYRESULT *queryResult) { - ListView_DeleteAllItems(GetDlgItem(getBrowserTabHWND(), IDC_LIST)); - for (int i=0;iiItemsNum;i++) { - - char timestampStr[100]; - DBTIMETOSTRING dbtts; - LVITEM lvItem; - - lvItem.mask = LVIF_TEXT;// | LVIF_PARAM; - lvItem.iSubItem = 0; - lvItem.iItem = ListView_GetItemCount(GetDlgItem(getBrowserTabHWND(), IDC_LIST)); - lvItem.pszText = Utils::mucc_mir_a2t(queryResult->pItems[i].pszID); - if (lvItem.pszText == NULL) lvItem.pszText = _TEXT(""); -// lvItem.lParam = (LPARAM) room; - ListView_InsertItem(GetDlgItem(getBrowserTabHWND(), IDC_LIST), &lvItem); - Utils::mucc_mir_free(lvItem.pszText); - - lvItem.iSubItem = 1; - lvItem.pszText = Utils::mucc_mir_a2t(queryResult->pItems[i].pszName); - if (lvItem.pszText == NULL) lvItem.pszText = _TEXT(""); - ListView_InsertItem(GetDlgItem(getBrowserTabHWND(), IDC_LIST), &lvItem); - ListView_SetItemText(GetDlgItem(getBrowserTabHWND(), IDC_LIST), lvItem.iItem, lvItem.iSubItem, lvItem.pszText); - Utils::mucc_mir_free(lvItem.pszText); - - lvItem.iSubItem = 2; - dbtts.cbDest = 90; - dbtts.szDest = timestampStr; - dbtts.szFormat = (char *)"d t"; - timestampStr[0]='\0'; - if (queryResult->pItems[i].dwFlags) { - CallService(MS_DB_TIME_TIMESTAMPTOSTRING, (WPARAM)queryResult->pItems[i].dwFlags, (LPARAM) & dbtts); - } - lvItem.pszText = Utils::mucc_mir_a2t(timestampStr); - if (lvItem.pszText == NULL) lvItem.pszText = _TEXT(""); - ListView_InsertItem(GetDlgItem(getBrowserTabHWND(), IDC_LIST), &lvItem); - ListView_SetItemText(GetDlgItem(getBrowserTabHWND(), IDC_LIST), lvItem.iItem, lvItem.iSubItem, lvItem.pszText); - Utils::mucc_mir_free(lvItem.pszText); - - lvItem.iSubItem = 3; - lvItem.pszText = Utils::mucc_mir_a2t(queryResult->pItems[i].pszNick); - if (lvItem.pszText == NULL) lvItem.pszText = _TEXT(""); - ListView_InsertItem(GetDlgItem(getBrowserTabHWND(), IDC_LIST), &lvItem); - ListView_SetItemText(GetDlgItem(getBrowserTabHWND(), IDC_LIST), lvItem.iItem, lvItem.iSubItem, lvItem.pszText); - Utils::mucc_mir_free(lvItem.pszText); - - lvItem.iSubItem = 4; - timestampStr[0] = '\0'; - if (queryResult->pItems[i].iCount > 0) { - int days = queryResult->pItems[i].iCount / (60*60*24); - int hours = (queryResult->pItems[i].iCount % (60*60*24)) / (60*60); - int minutes = (queryResult->pItems[i].iCount % (60*60)) / 60; - int seconds = queryResult->pItems[i].iCount % 60; - if (days != 0) { - sprintf(timestampStr, "%dd%dh%dm%ds", days, hours, minutes, seconds); - } else if (hours != 0) { - sprintf(timestampStr, "%dh%dm%ds", hours, minutes, seconds); - } else if (minutes != 0) { - sprintf(timestampStr, "%dm%ds", minutes, seconds); - } else { - sprintf(timestampStr, "%ds", seconds); - } - } - lvItem.pszText = Utils::mucc_mir_a2t(timestampStr); - if (lvItem.pszText == NULL) lvItem.pszText = _TEXT(""); - ListView_InsertItem(GetDlgItem(getBrowserTabHWND(), IDC_LIST), &lvItem); - ListView_SetItemText(GetDlgItem(getBrowserTabHWND(), IDC_LIST), lvItem.iItem, lvItem.iSubItem, lvItem.pszText); - Utils::mucc_mir_free(lvItem.pszText); - - lvItem.iSubItem = 5; - lvItem.pszText = Utils::mucc_mir_a2t(queryResult->pItems[i].pszText); - if (lvItem.pszText == NULL) lvItem.pszText = _TEXT(""); - ListView_InsertItem(GetDlgItem(getBrowserTabHWND(), IDC_LIST), &lvItem); - ListView_SetItemText(GetDlgItem(getBrowserTabHWND(), IDC_LIST), lvItem.iItem, lvItem.iSubItem, lvItem.pszText); - Utils::mucc_mir_free(lvItem.pszText); - -/* - ptr = new HelperContact(queryResult->pItems[i].pszID, queryResult->pItems[i].pszName); - if (lastptr !=NULL) { - lastptr->setNext(ptr); - } else { - contactList=ptr; - } - lastptr=ptr; - - */ - } - EnableWindow(GetDlgItem(getBrowserTabHWND(), IDC_SHOW), TRUE); -} - -const char *AdminWindow::getNick() { - return nick; -} - -int AdminWindow::getBrowserMode() { - return browserMode; -} diff --git a/!NotAdopted/Tlen/tlen_czaty/AdminWindow.h b/!NotAdopted/Tlen/tlen_czaty/AdminWindow.h deleted file mode 100644 index a73cdb9285..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/AdminWindow.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -class AdminWindow; -#ifndef ADMINWINDOW_INCLUDED -#define ADMINWINDOW_INCLUDED - -#include "mucc.h" -#include "ChatWindow.h" - -class AdminWindow { -private: - HWND hWnd; - HWND hKickTabWnd, hBrowserTabWnd; - int currentTab; - int browserMode; - ChatWindow *parent; - char *nick; -public: - enum BROWSER_MODE { - BROWSE_BANNED = 1, - BROWSE_OWNERS = 2, - BROWSE_ADMINS = 3, - BROWSE_MEMBERS = 4, - BROWSE_MODERATORS = 5 - }; - AdminWindow (ChatWindow *parent, const char *nick, int mode); - ~AdminWindow(); - void start(); - void setHWND(HWND); - void setKickTabHWND(HWND); - void setBrowserTabHWND(HWND); - HWND getKickTabHWND(); - HWND getBrowserTabHWND(); - int getCurrentTab(); - int getBrowserMode(); - void setCurrentTab(int); - void queryUsers(int); - ChatWindow* getParent(); - const char *getNick(); - void queryResultUsers(MUCCQUERYRESULT *queryResult); -}; - -#endif - diff --git a/!NotAdopted/Tlen/tlen_czaty/ChatContainer.cpp b/!NotAdopted/Tlen/tlen_czaty/ChatContainer.cpp deleted file mode 100644 index 11e523e337..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/ChatContainer.cpp +++ /dev/null @@ -1,480 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "ChatContainer.h" -#include "Utils.h" -#include "Options.h" - -#define DM_CREATECHILD (WM_USER+10) -#define DM_ADDCHILD (WM_USER+11) -#define DM_ACTIVATECHILD (WM_USER+12) -#define DM_CHANGECHILDDATA (WM_USER+13) -#define DM_REMOVECHILD (WM_USER+14) - -#define DM_SETUNREAD (WM_USER+15) -#define DM_FLASHWINDOW (WM_USER+16) - -#define TIMERID_FLASHWND 1 -#define TIMEOUT_FLASHWND 900 - -ChatContainer * ChatContainer::list = NULL; -bool ChatContainer::released = false; -CRITICAL_SECTION ChatContainer::mutex; - -//BOOL CALLBACK ContainerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -static void __cdecl StartThread(void *vContainer); - -void ChatContainer::release() { - released = true; - for (ChatContainer *ptr2, *ptr = list; ptr!=NULL; ptr=ptr2) { - ptr2 = ptr->getNext(); - SendMessage(ptr->getHWND(), WM_CLOSE, 0, 0); - } - DeleteCriticalSection(&mutex); -} - -void ChatContainer::init() { - released = false; - InitializeCriticalSection(&mutex); -} - -int ChatContainer::getDefaultOptions() { - return FLAG_USE_TABS; -} - -ChatContainer * ChatContainer::getWindow() { - ChatContainer *ptr; - EnterCriticalSection(&mutex); - if (list == NULL || !(Options::getChatContainerOptions() & ChatContainer::FLAG_USE_TABS)) { - ptr = new ChatContainer(); - } else { - ptr = list; - } - LeaveCriticalSection(&mutex); - return ptr; -} - -ChatContainer::ChatContainer() { - hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - hWnd = NULL; - prev = next =NULL; - active = NULL; - childCount = 0; - nFlash = 0; - nFlashMax = 3; - Utils::forkThread((void (__cdecl *)(void *))StartThread, 0, (void *) this); - WaitForSingleObject(hEvent, INFINITE); - EnterCriticalSection(&mutex); - setNext(list); - if (next!=NULL) { - next->setPrev(this); - } - list = this; - LeaveCriticalSection(&mutex); -} - -ChatContainer::~ChatContainer() { - if (!released) { - EnterCriticalSection(&mutex); - if (getPrev()!=NULL) { - getPrev()->setNext(next); - } else if (list==this) { - list = getNext(); - } - if (getNext()!=NULL) { - getNext()->setPrev(prev); - } - LeaveCriticalSection(&mutex); - } - if (hEvent!=NULL) { - CloseHandle(hEvent); - } -} - -void ChatContainer::setHWND(HWND hWnd) { - this->hWnd = hWnd; -} - -HWND ChatContainer::getHWND() { - return hWnd; -} - -HANDLE ChatContainer::getEvent() { - return hEvent; -} - -ChatContainer * ChatContainer::getNext() { - return next; -} - -void ChatContainer::setNext(ChatContainer * next) { - this->next = next; -} - -ChatContainer * ChatContainer::getPrev() { - return prev; -} - -void ChatContainer::setPrev(ChatContainer * prev) { - this->prev = prev; -} - -void ChatContainer::show(bool bShow) { - ShowWindow(hWnd, bShow ? SW_SHOW : SW_HIDE); -} - -ChatWindow * ChatContainer::getActive() { - return active; -} - -int ChatContainer::getFlash() { - return nFlash; -} - -int ChatContainer::getFlashMax() { - return nFlashMax; -} - -int ChatContainer::getFlashTimeout() { - return TIMEOUT_FLASHWND; -} - -void ChatContainer::setFlash(int n) { - nFlash = n; -} - -void ChatContainer::activateChild(ChatWindow *window) { - RECT rcChild; - getChildWindowRect(&rcChild); - if (window!=NULL) { - SetWindowPos(window->getHWND(), HWND_TOP, rcChild.left, rcChild.top, rcChild.right-rcChild.left, rcChild.bottom - rcChild.top, SWP_NOSIZE); - } - if(window != active) { - ChatWindow *prev = active; - active = window; - SendMessage(hWnd, WM_SIZE, 0, 0); - ShowWindow(active->getHWND(), SW_SHOW); -// SendMessage(active->getHWND(), DM_UPDATETITLE, 0, 0); - if (prev!=NULL) { - ShowWindow(prev->getHWND(), SW_HIDE); - } - SetWindowTextA(hWnd, window->getRoomName()); - } - TCITEM tci; - tci.mask = TCIF_IMAGE; - tci.iImage = -1; - TabCtrl_SetItem(GetDlgItem(hWnd, IDC_TABS), getChildTab(window), &tci); - SendMessage(active->getHWND(), WM_ACTIVATE, WA_ACTIVE, 0); - SetFocus(active->getHWND()); -} - - -void ChatContainer::addChild(ChatWindow *child) { - TCITEM tci; - int tabId; - HWND hwndTabs = GetDlgItem(hWnd, IDC_TABS); - childCount++; - tci.mask = TCIF_TEXT | TCIF_PARAM; - LPTSTR lps1 = Utils::mucc_mir_a2t(child->getRoomName()); - tci.pszText = lps1; - tci.lParam = (LPARAM) child; - tabId = TabCtrl_InsertItem(hwndTabs, childCount-1, &tci); - TabCtrl_SetCurSel(hwndTabs, tabId); - Utils::mucc_mir_free(lps1); - activateChild(child); - SendMessage(hWnd, WM_SIZE, 0, 0); - ShowWindow(hWnd, SW_SHOWNORMAL); - SetForegroundWindow(hWnd); -} - -void ChatContainer::changeChildData(ChatWindow *child) { - int tabId; - HWND hwndTabs = GetDlgItem(hWnd, IDC_TABS); - tabId = getChildTab(child); - if (tabId >=0) { - TCITEM tci; - tci.mask = TCIF_TEXT; - LPTSTR lps1 = Utils::mucc_mir_a2t(child->getRoomName()); - tci.pszText = lps1; - TabCtrl_SetItem(hwndTabs, childCount-1, &tci); - Utils::mucc_mir_free(lps1); - } - if (child == active) { - SetWindowTextA(hWnd, child->getRoomName()); - } -} - - -void ChatContainer::removeChild(ChatWindow *child) { - HWND hwndTabs = GetDlgItem(hWnd, IDC_TABS); - int iSel = getChildTab(child); - if (iSel >= 0) { - TabCtrl_DeleteItem(hwndTabs, iSel); - } - childCount--; - if (childCount > 0) { - TCITEM tci; - if (iSel == childCount) iSel--; - TabCtrl_SetCurSel(hwndTabs, iSel); - tci.mask = TCIF_PARAM; - if (TabCtrl_GetItem(hwndTabs, iSel, &tci)) { - child = (ChatWindow *)tci.lParam; - activateChild(child); - } - } else {//if (!released) { - SendMessage(hWnd, WM_CLOSE, 0, 0); - } -} - -void ChatContainer::setUnread(ChatWindow *child, int unread) { - if (!unread || child != active) { - TCITEM tci; - tci.mask = TCIF_IMAGE; - if (unread) { - tci.iImage = 0; - } else { - tci.iImage = -1; - } - TabCtrl_SetItem(GetDlgItem(hWnd, IDC_TABS), getChildTab(child), &tci); - } -} - - -void ChatContainer::getChildWindowRect(RECT *rcChild) -{ - RECT rc, rcTabs; //rcStatus, - HWND hwndTabs = GetDlgItem(hWnd, IDC_TABS); - int l = TabCtrl_GetItemCount(hwndTabs); - GetClientRect(hWnd, &rc); - GetClientRect(hwndTabs, &rcTabs); - TabCtrl_AdjustRect(hwndTabs, FALSE, &rcTabs); -// GetWindowRect(dat->hwndStatus, &rcStatus); - rcChild->left = 0; - rcChild->right = rc.right; - if (l > 1) { - rcChild->top = rcTabs.top - 1; - } else { - rcChild->top = 0; - } - rcChild->bottom = rc.bottom - rc.top;// - (rcStatus.bottom - rcStatus.top); -} - -ChatWindow * ChatContainer::getChildFromTab(int tabId) { - TCITEM tci; - tci.mask = TCIF_PARAM; - TabCtrl_GetItem(GetDlgItem(hWnd, IDC_TABS), tabId, &tci); - return (ChatWindow *)tci.lParam; -} - -int ChatContainer::getChildTab(ChatWindow *child) { - TCITEM tci; - int l, i; - HWND hwndTabs = GetDlgItem(hWnd, IDC_TABS); - l = TabCtrl_GetItemCount(hwndTabs); - for (i = 0; i < l; i++) { - tci.mask = TCIF_PARAM; - TabCtrl_GetItem(hwndTabs, i, &tci); - if (child == (ChatWindow *) tci.lParam) { - return i; - } - } - return -1; - -} - -HWND ChatContainer::remoteCreateChild(DLGPROC proc, ChatWindow *ptr) { - return (HWND) SendMessage(hWnd, DM_CREATECHILD, (WPARAM)proc, (LPARAM) ptr); -} - -void ChatContainer::remoteAddChild(ChatWindow *ptr) { - SendMessage(hWnd, DM_ADDCHILD, (WPARAM)0, (LPARAM) ptr); -} - -void ChatContainer::remoteChangeChildData(ChatWindow *ptr) { - SendMessage(hWnd, DM_CHANGECHILDDATA, (WPARAM)0, (LPARAM) ptr); -} - -void ChatContainer::remoteRemoveChild(ChatWindow *ptr) { - SendMessage(hWnd, DM_REMOVECHILD, (WPARAM)0, (LPARAM) ptr); -} - -void ChatContainer::remoteSetUnread(ChatWindow *ptr, int unread) { - SendMessage(hWnd, DM_SETUNREAD, (WPARAM)unread, (LPARAM) ptr); -} - -void ChatContainer::remoteFlashWindow() { - SendMessage(hWnd, DM_FLASHWINDOW, 0, 0); -} - -INT_PTR CALLBACK ContainerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - ChatContainer *container; - container = (ChatContainer *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - if (container==NULL && msg!=WM_INITDIALOG) return FALSE; - switch (msg) { - case WM_INITDIALOG: - SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) muccIcon[MUCC_IDI_CHAT]); - container = (ChatContainer *) lParam; - container->setHWND(hwndDlg); - TabCtrl_SetImageList(GetDlgItem(hwndDlg, IDC_TABS), hImageList); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) container); - ShowWindow(hwndDlg, SW_SHOW); - SetEvent(container->getEvent()); - return TRUE; - case WM_GETMINMAXINFO: - MINMAXINFO *mmi; - RECT rcChild, rcWindow; - mmi = (MINMAXINFO *) lParam; - GetWindowRect(hwndDlg, &rcWindow); - container->getChildWindowRect(&rcChild); - mmi->ptMinTrackSize.x = 380; - mmi->ptMinTrackSize.y = 130 + (rcWindow.bottom - rcWindow.top) - (rcChild.bottom - rcChild.top); - return FALSE; - case WM_SIZE: - if (IsIconic(hwndDlg) || wParam == SIZE_MINIMIZED) break; - { - RECT rc, rcChild, rcWindow; - GetClientRect(hwndDlg, &rc); - HWND hwndTabs = GetDlgItem(hwndDlg, IDC_TABS); - MoveWindow(hwndTabs, 0, 0, (rc.right - rc.left), (rc.bottom - rc.top) - 0, FALSE); - RedrawWindow(hwndTabs, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE); - container->getChildWindowRect(&rcChild); - if ((rcChild.bottom-rcChild.top) < 130 || (rcChild.right-rcChild.left) < 380) { - GetWindowRect(hwndDlg, &rcWindow); - if ((rcChild.bottom-rcChild.top) < 130) { - rcWindow.bottom = rcWindow.top + 130 + (rcWindow.bottom - rcWindow.top) - (rcChild.bottom - rcChild.top); - } - if ((rcChild.right-rcChild.left) < 380) { - rcWindow.right = rcWindow.left + 380; - } - MoveWindow(hwndDlg, rcWindow.left, rcWindow.top, rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top, TRUE); - container->getChildWindowRect(&rcChild); - } - if (container->getActive()!=NULL) { - MoveWindow(container->getActive()->getHWND(), rcChild.left, rcChild.top, rcChild.right-rcChild.left, rcChild.bottom - rcChild.top, TRUE); - } - } - return TRUE; - case DM_CREATECHILD: - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_GROUPCHAT_LOG), hwndDlg, (DLGPROC) wParam, (LPARAM) lParam)); - return TRUE; - case DM_ADDCHILD: - container->addChild((ChatWindow *) lParam); - return TRUE; - case DM_REMOVECHILD: - container->removeChild((ChatWindow *) lParam); - return TRUE; - case DM_CHANGECHILDDATA: - container->removeChild((ChatWindow *) lParam); - return TRUE; - case DM_SETUNREAD: - container->setUnread((ChatWindow *) lParam, (int)wParam); - return TRUE; - case DM_FLASHWINDOW: - if (GetActiveWindow() != hwndDlg && GetForegroundWindow() != hwndDlg) { - container->setFlash(0); - SetTimer(hwndDlg, TIMERID_FLASHWND, container->getFlashTimeout(), NULL); - } - return TRUE; - case WM_NOTIFY: - { - NMHDR* pNMHDR = (NMHDR*) lParam; - switch (pNMHDR->code) { - case TCN_SELCHANGE: - { - TCITEM tci = {0}; - HWND hwndTabs = GetDlgItem(hwndDlg, IDC_TABS); - int iSel = TabCtrl_GetCurSel(hwndTabs); - tci.mask = TCIF_PARAM; - if (TabCtrl_GetItem(hwndTabs, iSel, &tci)) { - ChatWindow * chatWindow = (ChatWindow *) tci.lParam; - container->activateChild(chatWindow); - } - } - break; - case NM_CLICK: - { - FILETIME ft; - TCHITTESTINFO thinfo; - int tabId; - HWND hwndTabs = GetDlgItem(hwndDlg, IDC_TABS); - GetSystemTimeAsFileTime(&ft); - GetCursorPos(&thinfo.pt); - ScreenToClient(hwndTabs, &thinfo.pt); - tabId = TabCtrl_HitTest(hwndTabs, &thinfo); - if (tabId != -1 && tabId == container->lastClickTab && - (ft.dwLowDateTime - container->lastClickTime) < (GetDoubleClickTime() * 10000)) { - SendMessage(container->getChildFromTab(tabId)->getHWND(), WM_CLOSE, 0, 0); - container->lastClickTab = -1; - } else { - container->lastClickTab = tabId; - } - container->lastClickTime = ft.dwLowDateTime; - } - break; - } - - } - break; - case WM_ACTIVATE: - if (LOWORD(wParam) != WA_ACTIVE) - break; - case WM_MOUSEACTIVATE: - if (KillTimer(hwndDlg, TIMERID_FLASHWND)) { - FlashWindow(hwndDlg, FALSE); - } - /* - if (container->getActive()!=NULL) { - container->setUnread(container->getActive(), 0); - SendMessage(container->getActive()->getHWND(), WM_ACTIVATE, WA_ACTIVE, 0); - }*/ - break; - case WM_CLOSE: - EndDialog(hwndDlg, 0); - return FALSE; - case WM_TIMER: - if (wParam == TIMERID_FLASHWND) { - if ((container->getFlash() > container->getFlashMax()) || (GetActiveWindow() == hwndDlg) || (GetForegroundWindow() == hwndDlg)) { - KillTimer(hwndDlg, TIMERID_FLASHWND); - FlashWindow(hwndDlg, FALSE); - } else if (container->getFlash() < container->getFlashMax()) { - FlashWindow(hwndDlg, TRUE); - container->setFlash(container->getFlash()+1); - } - } - break; - case WM_DESTROY: - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)0); - delete container; - return TRUE; - - } - return FALSE; -} - - -static void __cdecl StartThread(void *vContainer) { - OleInitialize(NULL); - DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_GROUPCHAT_CONTAINER), NULL, ContainerDlgProc, (LPARAM) vContainer); - //MessageBox(NULL, "ChatContainer dies.", "MW", MB_OK); - OleUninitialize(); - -} diff --git a/!NotAdopted/Tlen/tlen_czaty/ChatContainer.h b/!NotAdopted/Tlen/tlen_czaty/ChatContainer.h deleted file mode 100644 index 4414068033..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/ChatContainer.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -class ChatContainer; - -#ifndef CHATCONTAINER_INCLUDED -#define CHATCONTAINER_INCLUDED -#include "mucc.h" -#include "ChatEvent.h" -#include "ChatUser.h" -#include "AdminWindow.h" - -class ChatContainerChild { -public: - ChatWindow *window; - ChatContainerChild *next; - ChatContainerChild *prev; -}; - -class ChatContainer{ - -private: - static ChatContainer * list; - static bool released; - static CRITICAL_SECTION mutex; - HWND hWnd; - HANDLE hEvent; - int childCount; - int width, height; - int nFlash, nFlashMax; - ChatContainer *next, *prev; - ChatWindow * active; - ChatContainer(); -protected: - friend INT_PTR CALLBACK ContainerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - void addChild(ChatWindow *); - void activateChild(ChatWindow *); - void changeChildData(ChatWindow *); - void removeChild(ChatWindow *); - void setUnread(ChatWindow *child, int unread); - void getChildWindowRect(RECT *rcChild); - ChatWindow * getChildFromTab(int tabId); - int getChildTab(ChatWindow *); - int getChildCount(); - void setChildCount(int); - ChatWindow * getActive(); - ChatContainerChild *getChildren(); - ChatContainer * getNext(); - void setNext(ChatContainer *); - ChatContainer * getPrev(); - void setPrev(ChatContainer *); - int lastClickTime; - int lastClickTab; - HANDLE getEvent(); - void setHWND(HWND); - int getFlash(); - int getFlashMax(); - int getFlashTimeout(); - void setFlash(int); -public: - enum FLAGS { - FLAG_USE_TABS = 0x00000001, - }; - - ~ChatContainer(); - static void init(); - static void release(); - static ChatContainer * getWindow(); - static int getDefaultOptions(); - void show(bool bShow); - HWND getHWND(); - - HWND remoteCreateChild(DLGPROC proc, ChatWindow *); - void remoteAddChild(ChatWindow *); - void remoteChangeChildData(ChatWindow *); - void remoteRemoveChild(ChatWindow *); - void remoteSetUnread(ChatWindow *ptr, int unread); - void remoteFlashWindow(); -}; - - -#endif diff --git a/!NotAdopted/Tlen/tlen_czaty/ChatEvent.cpp b/!NotAdopted/Tlen/tlen_czaty/ChatEvent.cpp deleted file mode 100644 index 246c168f22..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/ChatEvent.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "ChatEvent.h" -#include "Options.h" -#include "Utils.h" -#include - -ChatEvent::ChatEvent() { - - next = prev = NULL; - event.cbSize = sizeof(MUCCEVENT); - event.iType = 0; - event.pszID = NULL; - event.pszModule = NULL; - event.pszName = NULL; - event.pszNick = NULL; - event.pszText = NULL; - event.pszUID = NULL; -} - -ChatEvent::ChatEvent(const MUCCEVENT *e) { - - event.cbSize = sizeof(MUCCEVENT); - event.iType = e->iType; - event.bIsMe = e->bIsMe; - event.color = e->color; - event.dwData = e->dwData; - event.dwFlags = e->dwFlags; - event.iFont = e->iFont; - event.iFontSize = e->iFontSize; - event.time = e->time; - event.pszID = NULL; - event.pszModule = NULL; - event.pszName = NULL; - event.pszNick = NULL; - event.pszText = NULL; - event.pszUID = NULL; -// Utils::copyString((char **)&(event.pszID), e->pszID); -// Utils::copyString((char **)&(event.pszModule), e->pszModule); -// Utils::copyString((char **)&(event.pszName), e->pszName); - if (e->iType == MUCC_EVENT_STATUS || e->iType == MUCC_EVENT_MESSAGE) { - Utils::copyString((char **)&(event.pszNick), e->pszNick); - } - if (e->iType == MUCC_EVENT_ERROR || e->iType == MUCC_EVENT_MESSAGE || e->iType == MUCC_EVENT_TOPIC) { - Utils::copyString((char **)&(event.pszText), e->pszText); - } -// Utils::copyString((char **)&(event.pszUID), e->pszUID); - next = prev = NULL; -} - -ChatEvent::~ChatEvent() { - - if (event.pszID != NULL) { - delete (char *)event.pszID; - } - if (event.pszModule != NULL) { - delete (char *)event.pszModule; - } - if (event.pszName != NULL) { - delete (char *)event.pszName; - } - if (event.pszNick != NULL) { - delete (char *)event.pszNick; - } - if (event.pszText != NULL) { - delete (char *)event.pszText; - } - if (event.pszUID != NULL) { - delete (char *)event.pszUID; - } - if (next != NULL) { - next->setPrev(prev); - } - if (prev != NULL) { - prev->setNext(next); - } -} - -ChatEvent * ChatEvent::getNext() { - return next; -} - -ChatEvent * ChatEvent::getPrev() { - return prev; -} - -void ChatEvent::setNext(ChatEvent *next) { - this->next = next; -} - -void ChatEvent::setPrev(ChatEvent * prev) { - this->prev = prev; -} - -const MUCCEVENT * ChatEvent::getEvent() { - return &event; -} - -ChatEventList::ChatEventList() { - eventListEnd = &eventListRoot; - setMaxSize(DEFAULT_MAX_SIZE); - currentSize = 0; -} - -ChatEventList::~ChatEventList() { - while (eventListRoot.getNext()!=NULL) { - delete eventListRoot.getNext(); - } -} - -int ChatEventList::addEvent(const MUCCEVENT *muccevent) { - int trimmed = 0; - ChatEvent *event = new ChatEvent(muccevent); - event->setPrev(eventListEnd); - eventListEnd->setNext(event); - eventListEnd=event; - currentSize++; - if (currentSize>hiMaxSize) { - while (currentSize>loMaxSize && eventListRoot.getNext()!=NULL) { - delete eventListRoot.getNext(); - currentSize--; - trimmed = 1; - } - } - return trimmed; -} - -ChatEvent * ChatEventList::getEvents() { - return eventListRoot.getNext(); -} - -void ChatEventList::setMaxSize(int s) { - loMaxSize = s; - if (s>200) { - hiMaxSize = s + s/10; - } else { - hiMaxSize = s + 20; - } -} - -void ChatEventList::clear() { - ChatEvent *event = eventListRoot.getNext(); - eventListRoot.setNext(NULL); - eventListEnd = &eventListRoot; - currentSize = 0; - if (event!=NULL) { - event->setPrev(NULL); - while (event->getNext()!=NULL) { - delete event->getNext(); - } - delete event; - } -} - - diff --git a/!NotAdopted/Tlen/tlen_czaty/ChatEvent.h b/!NotAdopted/Tlen/tlen_czaty/ChatEvent.h deleted file mode 100644 index 37e045380f..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/ChatEvent.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#ifndef CHATEVENT_INCLUDED -#define CHATEVENT_INCLUDED -#include "mucc.h" - -class ChatEvent { -private: - ChatEvent * prev; - ChatEvent * next; - MUCCEVENT event; -public: - ChatEvent(); - ChatEvent(const MUCCEVENT *); - ~ChatEvent(); - ChatEvent * getPrev(); - ChatEvent * getNext(); - void setPrev(ChatEvent *); - void setNext(ChatEvent *); - const MUCCEVENT *getEvent(); -}; - -class ChatEventList { -private: - ChatEvent eventListRoot; - ChatEvent * eventListEnd; - int loMaxSize; - int hiMaxSize; - int currentSize; -public: - enum { - DEFAULT_MAX_SIZE = 100 - }; - ChatEventList(); - ~ChatEventList(); - ChatEvent * getEvents(); - int addEvent(const MUCCEVENT *); - void clear(); - void setMaxSize(int s); -}; - -#endif diff --git a/!NotAdopted/Tlen/tlen_czaty/ChatGroup.cpp b/!NotAdopted/Tlen/tlen_czaty/ChatGroup.cpp deleted file mode 100644 index a5c47d724f..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/ChatGroup.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "ChatGroup.h" -#include "Utils.h" - -ChatGroup::ChatGroup() { - prev = next = NULL; - parent = child =NULL; - name = NULL; - id = 0; -} - -ChatGroup::~ChatGroup() { - if (name!=NULL) delete name; - if (id!=NULL) delete id; -} -ChatGroup * ChatGroup::getNext() { - return next; -} - -void ChatGroup::setNext(ChatGroup *next) { - this->next = next; -} - -ChatGroup * ChatGroup::getPrev() { - return prev; -} - -void ChatGroup::setPrev(ChatGroup *prev) { - this->prev = prev; -} - -ChatGroup * ChatGroup::getChild() { - return child; -} - -void ChatGroup::addChild(ChatGroup *child) { - ChatGroup *group; - for (group=getChild();group!=NULL && group->getNext()!=NULL;group=group->getNext()) { - } - if (group==NULL) this->child = child; - else { - group->setNext(child); - } - child->setPrev(group); - child->setNext(NULL); -} - -ChatGroup * ChatGroup::getListNext() { - return listNext; -} - -void ChatGroup::setListNext(ChatGroup *next) { - this->listNext = next; -} - -const char *ChatGroup::getId() { - return id; -} - -void ChatGroup::setId(const char *id) { - Utils::copyString(&this->id, id); -} - -HTREEITEM ChatGroup::getTreeItem() { - return hItem; -} - -void ChatGroup::setTreeItem(HTREEITEM hItem) { - this->hItem=hItem; -} - -const char *ChatGroup::getName() { - return name; -} - -void ChatGroup::setName(const char *name) { - Utils::copyString(&this->name, name); -} - diff --git a/!NotAdopted/Tlen/tlen_czaty/ChatGroup.h b/!NotAdopted/Tlen/tlen_czaty/ChatGroup.h deleted file mode 100644 index c04abf81ba..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/ChatGroup.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#ifndef CHATGROUP_INCLUDED -#define CHATGROUP_INCLUDED -#include "mucc.h" - -class ChatGroup { -private: - HTREEITEM hItem; - ChatGroup * parent; - ChatGroup * child; - ChatGroup * prev; - ChatGroup * next; - ChatGroup * listNext; - char * name; - char * id; -public: - ChatGroup(); - ~ChatGroup(); - ChatGroup * getPrev(); - ChatGroup * getNext(); - ChatGroup * getListNext(); - ChatGroup * getChild(); - ChatGroup * getParent(); - HTREEITEM getTreeItem(); - const char * getName(); - const char * getId(); - void setPrev(ChatGroup *); - void setNext(ChatGroup *); - void setListNext(ChatGroup *); - void addChild(ChatGroup *); - void setParent(ChatGroup *); - void setName(const char *); - void setTreeItem(HTREEITEM ); - void setId(const char *); -}; -#endif diff --git a/!NotAdopted/Tlen/tlen_czaty/ChatRoom.cpp b/!NotAdopted/Tlen/tlen_czaty/ChatRoom.cpp deleted file mode 100644 index 2f9c1389c2..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/ChatRoom.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "ChatRoom.h" -#include "Utils.h" - - -ChatRoom::ChatRoom() { - next = prev = NULL; - name = NULL; - id = NULL; -} - -ChatRoom::~ChatRoom() { - if (name!=NULL) delete name; - if (id!=NULL) delete id; -} - -void ChatRoom::setId(const char *id) { - Utils::copyString(&this->id, id); -} - -void ChatRoom::setName(const char *name) { - Utils::copyString(&this->name, name); -} - -const char* ChatRoom::getId() { - return id; -} - -const char* ChatRoom::getName() { - return name; -} - -ChatRoom *ChatRoom::getNext() { - return next; -} - -void ChatRoom::setNext(ChatRoom *next) { - this->next = next; -} - -void ChatRoom::setFlags(int flags) { - this->flags = flags; -} - -int ChatRoom::getFlags() { - return flags; -} - diff --git a/!NotAdopted/Tlen/tlen_czaty/ChatRoom.h b/!NotAdopted/Tlen/tlen_czaty/ChatRoom.h deleted file mode 100644 index 51593f00c2..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/ChatRoom.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#ifndef CHATROOM_INCLUDED -#define CHATROOM_INCLUDED -#include "mucc.h" - - -class ChatRoom { -private: - HTREEITEM hItem; - ChatRoom * prev; - ChatRoom * next; - char * name; - char * id; - int flags; -public: - ChatRoom(); - ~ChatRoom(); - ChatRoom * getPrev(); - ChatRoom * getNext(); - HTREEITEM getTreeItem(); - const char * getName(); - const char * getId(); - int getFlags(); - void setPrev(ChatRoom *); - void setNext(ChatRoom *); - void setName(const char *); - void setTreeItem(HTREEITEM ); - void setId(const char *); - void setFlags(int); -}; - -#endif diff --git a/!NotAdopted/Tlen/tlen_czaty/ChatUser.cpp b/!NotAdopted/Tlen/tlen_czaty/ChatUser.cpp deleted file mode 100644 index cb5baea1a8..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/ChatUser.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "ChatUser.h" -#include "Utils.h" - -ChatUser::ChatUser() { - id = NULL; - nick = NULL; - hTreeItem = NULL; - me = 0; -} - -ChatUser::~ChatUser() { - if (id!=NULL) delete id; - if (nick!=NULL) delete nick; -} - -void ChatUser::setNick(const char *nick) { - Utils::copyString(&this->nick, nick); -} - -void ChatUser::setId(const char *id) { - Utils::copyString(&this->id, id); -} - -const char *ChatUser::getNick() { - return nick; -} - -const char *ChatUser::getId() { - return id; -} - -void ChatUser::setNext(ChatUser *next) { - this->next = next; -} - -ChatUser * ChatUser::getNext() { - return next; -} - -void ChatUser::setFlags(int flags) { - this->flags = flags; -} - -int ChatUser::getFlags() { - return flags; -} - -void ChatUser::setMe(int me) { - this->me = me; -} - -int ChatUser::isMe() { - return me; -} - -void ChatUser::setHTreeItem(HTREEITEM hti) { - hTreeItem = hti; -} - -HTREEITEM ChatUser::getHTreeItem() { - return hTreeItem; -} diff --git a/!NotAdopted/Tlen/tlen_czaty/ChatUser.h b/!NotAdopted/Tlen/tlen_czaty/ChatUser.h deleted file mode 100644 index 0084a14608..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/ChatUser.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#ifndef CHATUSER_INCLUDED -#define CHATUSER_INCLUDED -#include "mucc.h" - -class ChatUser { -private: - char * nick; - char * id; - int flags; - int me; - ChatUser * next; - HTREEITEM hTreeItem; -public: - ChatUser(); - ~ChatUser(); - void setNick(const char *); - void setId(const char *); - const char * getNick(); - const char * getId(); - void setNext(ChatUser *); - int getFlags(); - void setFlags(int ); - HTREEITEM getHTreeItem(); - void setHTreeItem(HTREEITEM); - ChatUser * getNext(); - void setMe(int); - int isMe(); -}; -#endif diff --git a/!NotAdopted/Tlen/tlen_czaty/ChatWindow.cpp b/!NotAdopted/Tlen/tlen_czaty/ChatWindow.cpp deleted file mode 100644 index 97dc986381..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/ChatWindow.cpp +++ /dev/null @@ -1,2108 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "ChatWindow.h" -#include "HelperDialog.h" -#include "Utils.h" -#include "Options.h" -#include "m_smileyadd.h" -#include "m_ieview.h" -//#include "m_chat.h" - -static int logPixelSY; -static INT_PTR CALLBACK LogDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -static void JabberStringAppend(char **str, int *sizeAlloced, const char *fmt, ...); -static char *JabberRtfEscape(char *str); -//static DWORD CALLBACK Log_StreamCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb); - -COLORREF ChatWindow::colorListBg, ChatWindow::colorListText, ChatWindow::colorListGroupText; -HFONT ChatWindow::hListGroupFont=NULL; -HFONT ChatWindow::hListFont=NULL; - -ChatWindow * ChatWindow::list = NULL; -bool ChatWindow::released = false; -CRITICAL_SECTION ChatWindow::mutex; - -static WNDPROC oldSplitterWndProc, oldEditWndProc; -static HCURSOR hCurSplitNS, hCurSplitWE, hCurHyperlinkHand; - -void ChatWindow::release() { - released = true; - for (ChatWindow *ptr2, *ptr = list; ptr!=NULL; ptr=ptr2) { - ptr2 = ptr->getNext(); - //SendMessage(ptr->getHWND(), WM_CLOSE, 0, 0); - } - DeleteCriticalSection(&mutex); - DestroyCursor(hCurSplitNS); - DestroyCursor(hCurSplitWE); - DestroyCursor(hCurHyperlinkHand); -} - -void ChatWindow::init() { - hCurSplitNS = LoadCursor(NULL, IDC_SIZENS); - hCurSplitWE = LoadCursor(NULL, IDC_SIZEWE); - hCurHyperlinkHand = LoadCursor(NULL, IDC_HAND); - if (hCurHyperlinkHand == NULL) { - hCurHyperlinkHand = LoadCursor(NULL, IDC_ARROW); - } - released = false; - InitializeCriticalSection(&mutex); -} - -/* chat.dll mod*/ -/* -static bool gcRegistered = false; - -static void __stdcall StartThread(void *vChat) { //__cdecl - ChatWindow *chat = (ChatWindow *)vChat; - if (!gcRegistered) { - gcRegistered = true; - GCREGISTER gcr = {0}; - gcr.cbSize = sizeof(GCREGISTER); - gcr.dwFlags = 0; - gcr.iMaxText = 0; - gcr.nColors = 0; - gcr.pColors = 0; - gcr.pszModuleDispName = chat->getModule(); - gcr.pszModule = chat->getModule(); - if (CallService(MS_GC_REGISTER, 0, (LPARAM)&gcr)) { - MessageBox(NULL, "cannot register", "CHAT", MB_OK); - } - } - GCWINDOW gcw = {0}; - gcw.cbSize = sizeof(GCWINDOW); - gcw.iType = GCW_CHATROOM; - gcw.pszModule = chat->getModule(); - gcw.pszName = chat->getRoomName(); - gcw.pszID = chat->getRoomId(); - gcw.pszStatusbarText = "status"; - gcw.bDisableNickList = FALSE; - gcw.dwItemData = (DWORD) chat; - if(CallService(MS_GC_NEWCHAT, 0, (LPARAM) &gcw)) { - MessageBox(NULL, "cannot create", "CHAT", MB_OK); - } - - GCDEST gcdest; - GCEVENT gcevent = {sizeof(GCEVENT), &gcdest}; - const char *groupNames[] = {"Global Owners", "Owners", "Admins", "Moderators", "Users"}; - gcdest.pszModule = (char *)chat->getModule(); - gcdest.pszID = (char *)chat->getRoomId(); - gcevent.bAddToLog = FALSE; - gcevent.time = 0; - gcdest.iType = GC_EVENT_ADDGROUP; - for (int i=0;i<5;i++) { - gcevent.pszStatus = Translate(groupNames[i]); - CallService(MS_GC_EVENT, 0, (LPARAM)&gcevent); - } - - - gcdest.iType = GC_EVENT_CONTROL; - CallService(MS_GC_EVENT, WINDOW_INITDONE, (LPARAM)&gcevent); - CallService(MS_GC_EVENT, WINDOW_ONLINE, (LPARAM)&gcevent); -} -*/ - -ChatWindow::ChatWindow(MUCCWINDOW *mucw) { - prev = next = NULL; - adminWindow = NULL; - hWnd = NULL; - hWndLog = NULL; - module = roomId = roomName = topic = NULL; - hSplitterPos = 0; - vSplitterPos = 0; - wasFirstMessage = 0; - isEmpty = true; - isStarted = 0; - options = Options::getChatWindowOptions(); - bBold = bItalic = bUnderline = 0; - hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - hEditFont = NULL; - userMe = NULL; - users = NULL; - for (int i=0;i<5;i++) { - hUserGroups[i] = NULL; - } - setModule(mucw->pszModule); - setRoomId(mucw->pszID); - setRoomName(mucw->pszName); - EnterCriticalSection(&mutex); - setNext(list); - if (next!=NULL) { - next->setPrev(this); - } - list = this; - LeaveCriticalSection(&mutex); - container = ChatContainer::getWindow(); - hWnd = container->remoteCreateChild(LogDlgProc, this); - container->remoteAddChild(this); - /* chat.dll mod*/ -/* CallFunctionAsync(StartThread, (void *)this);*/ -} - -ChatWindow::~ChatWindow () { - if (!released) { - EnterCriticalSection(&mutex); - if (getPrev()!=NULL) { - getPrev()->setNext(next); - } else if (list==this) { - list = getNext(); - } - if (getNext()!=NULL) { - getNext()->setPrev(prev); - } - LeaveCriticalSection(&mutex); - } - if (adminWindow!=NULL) { - delete adminWindow; - } - if (hEvent!=NULL) { - CloseHandle(hEvent); - } - while (users!=NULL) { - ChatUser *user = users; - users = users->getNext(); - delete user; - } - if (module!=NULL) { - delete module; - } - if (roomId!=NULL) { - delete roomId; - } - if (roomName!=NULL) { - delete roomName; - } - if (topic!=NULL) { - delete topic; - } - container->remoteRemoveChild(this); -}; - - -void ChatWindow::setPrev(ChatWindow *prev) { - this->prev = prev; -} - -ChatWindow * ChatWindow::getPrev() { - return prev; -} - -void ChatWindow::setNext(ChatWindow *next) { - this->next = next; -} - -ChatWindow * ChatWindow::getNext() { - return next; -} - -void ChatWindow::setHWND(HWND hWnd) { - this->hWnd = hWnd; -} - -HWND ChatWindow::getHWND() { - return hWnd; -} - -void ChatWindow::setHWNDLog(HWND hWnd) { - this->hWndLog = hWnd; -} - -HWND ChatWindow::getHWNDLog() { - return hWndLog; -} - -HANDLE ChatWindow::getEvent() { - return hEvent; -} - -ChatContainer * ChatWindow::getContainer() { - return container; -} - -void ChatWindow::setAdminWindow(AdminWindow *aw) { - this->adminWindow = aw; -} - -AdminWindow* ChatWindow::getAdminWindow() { - return adminWindow; -} - -void ChatWindow::setModule(const char *module) { - Utils::copyString(&this->module, module); -} - -const char * ChatWindow::getModule() { - return module; -} - -void ChatWindow::setRoomId(const char *roomId) { - Utils::copyString(&this->roomId, roomId); -} - -const char * ChatWindow::getRoomId() { - return roomId; -} - -void ChatWindow::setRoomName(const char *roomName) { -// char str[300]; - Utils::copyString(&this->roomName, roomName); -// sprintf(str, "%s %08X", roomName, roomFlags); -// SetWindowText(hWnd, str); - SetWindowTextA(hWnd, roomName); -} - -void ChatWindow::setRoomFlags(int flags) { -// char str[300]; - roomFlags = flags; -// sprintf(str, "%s %08X", roomName, roomFlags); -// SetWindowText(hWnd, str); -} - -int ChatWindow::getRoomFlags() { - return roomFlags; -} - -const char * ChatWindow::getRoomName() { - return roomName; -} - -void ChatWindow::setOptions(int options) { - if (options != this->options) { - this->options = options; - rebuildLog(); - } -} - -int ChatWindow::getOptions() { - return options; -} - -static void __cdecl StartAdminThread(void *vChat) { - ChatWindow *chat = (ChatWindow *)vChat; - chat->getAdminWindow()->start(); -} - -void ChatWindow::startAdminDialog(int mode) { - if (adminWindow==NULL) { - ChatUser *user = getSelectedUser(); - if (user != NULL) { - adminWindow = new AdminWindow(this, user->getId(), mode); - } else { - adminWindow = new AdminWindow(this, "", mode); - } - Utils::forkThread((void (__cdecl *)(void *))StartAdminThread, 0, (void *) this); - } -} -void ChatWindow::addUser(ChatUser *user) { - user->setNext(users); - users = user; -} -void ChatWindow::removeUser(ChatUser *user) { - ChatUser *user2; - for (user2=users;user2!=NULL;user2=user2->getNext()) { - if (user2->getNext()==user) break; - } - if (user2!=NULL) { - user2->setNext(user->getNext()); - } else if (users==user) { - users = user->getNext(); - } -} - -ChatUser * ChatWindow::getMe() { - return userMe; -} - -ChatUser * ChatWindow::findUser(const char *userId) { - ChatUser *user; - for (user=users;user!=NULL;user=user->getNext()) { - if (!(strcmp(user->getId(), userId))) break; - } - return user; -} - -ChatUser * ChatWindow::findUserByNick(const char *nick) { - ChatUser *user; - for (user=users;user!=NULL;user=user->getNext()) { - if (!(strcmp(user->getNick(), nick))) break; - } - return user; -} - -ChatUser *ChatWindow::getSelectedUser() { - HTREEITEM hTreeItem = TreeView_GetSelection(GetDlgItem(hWnd, IDC_TREELIST)); - if (hTreeItem!=NULL) { - TVITEM tvi; - tvi.mask = TVIF_PARAM; - tvi.hItem = hTreeItem; - TreeView_GetItem(GetDlgItem(hWnd, IDC_TREELIST), &tvi); - return (ChatUser *) tvi.lParam; - } - return NULL; -} - -int ChatWindow::startPriv() { - ChatUser *user = getSelectedUser(); - if (user!=NULL) { - MUCCEVENT mucce; - mucce.cbSize = sizeof(MUCCEVENT); - mucce.iType = MUCC_EVENT_START_PRIV; - mucce.pszModule = getModule(); - mucce.pszID = getRoomId(); - mucce.pszUID = user->getId(); - NotifyEventHooks(hHookEvent, 0,(WPARAM)&mucce); - } - return 0; -} - -int ChatWindow::unban(const char *id) { - if (id!=NULL) { - MUCCEVENT mucce; - mucce.cbSize = sizeof(MUCCEVENT); - mucce.iType = MUCC_EVENT_UNBAN; - mucce.pszModule = getModule(); - mucce.pszID = getRoomId(); - mucce.pszUID = id; - NotifyEventHooks(hHookEvent, 0,(WPARAM)&mucce); - } - return 0; -} - - -int ChatWindow::kickAndBan(const char *id, int time, const char *reason) { - if (id!=NULL) { - MUCCEVENT mucce; - mucce.cbSize = sizeof(MUCCEVENT); - mucce.iType = MUCC_EVENT_KICK_BAN; - mucce.pszModule = getModule(); - mucce.pszID = getRoomId(); - mucce.pszUID = id; - mucce.dwData = time; - mucce.pszText = reason; - NotifyEventHooks(hHookEvent, 0,(WPARAM)&mucce); - } - return 0; -} - -int ChatWindow::kickAndBan(int time) { - ChatUser *user = getSelectedUser(); - if (user!=NULL) { - kickAndBan(user->getId(), time, ""); - } - return 0; -} - -int ChatWindow::setRights(const char *id, int flags) { - if (id!=NULL) { - MUCCEVENT mucce; - mucce.cbSize = sizeof(MUCCEVENT); - mucce.iType = MUCC_EVENT_SET_USER_ROLE; - mucce.pszModule = getModule(); - mucce.pszID = getRoomId(); - mucce.pszUID = id; - mucce.dwFlags = flags; - NotifyEventHooks(hHookEvent, 0,(WPARAM)&mucce); - } - return 0; -} - -int ChatWindow::setRights(int flags) { - ChatUser *user = getSelectedUser(); - if (user!=NULL) { - setRights(user->getId(), flags); - } - return 0; -} - -int ChatWindow::getUserGroup(ChatUser *user) { - int group = 4; - if (user->getFlags()&MUCC_EF_USER_GLOBALOWNER) { - group = 0; - } else if (user->getFlags()&MUCC_EF_USER_OWNER) { - group = 1; - } else if (user->getFlags()&MUCC_EF_USER_ADMIN) { - group = 2; - } else if (user->getFlags()&MUCC_EF_USER_MODERATOR) { - group = 3; - } - return group; -} - -int ChatWindow::changePresence(const MUCCEVENT *event) { - int i, group, bLogEvent = FALSE; - const char *groupNames[] = {"Global Owners", "Owners", "Admins", "Moderators", "Users"}; - ChatUser *user = findUser(event->pszUID); - if (event->dwData == ID_STATUS_ONLINE || (user!=NULL && event->dwData!=ID_STATUS_OFFLINE)) { - if (user == NULL) { - user = new ChatUser(); - user->setId(event->pszUID); - user->setNick(event->pszNick); - user->setFlags(event->dwFlags); - user->setMe(event->bIsMe); - addUser(user); - if (user->isMe()) { - userMe = user; - } - bLogEvent = TRUE; - } else { - group = getUserGroup(user); - user->setFlags(event->dwFlags); - TreeView_DeleteItem(GetDlgItem(hWnd, IDC_TREELIST), user->getHTreeItem()); - if (TreeView_GetChild(GetDlgItem(hWnd, IDC_TREELIST), getTreeItem(group))==NULL) { - TreeView_DeleteItem(GetDlgItem(hWnd, IDC_TREELIST), getTreeItem(group)); - setTreeItem(group, NULL); - } - } - if (user->isMe()) { - if (user->getFlags() & MUCC_EF_USER_OWNER || user->getFlags() & MUCC_EF_USER_ADMIN) { - EnableWindow(GetDlgItem(hWnd, IDC_TOPIC_BUTTON), TRUE); - } else { - EnableWindow(GetDlgItem(hWnd, IDC_TOPIC_BUTTON), FALSE); - } - } - group = getUserGroup(user); - TVINSERTSTRUCT tvis; - if (getTreeItem(group)==NULL) { - for (i=group-1;i>=0;i--) { - if (getTreeItem(i)!=NULL) break; - } - tvis.hParent = NULL; - if (i>=0) { - tvis.hInsertAfter = getTreeItem(i); - } else { - tvis.hInsertAfter = TVI_FIRST; - } - tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_CHILDREN; - tvis.item.lParam = (LPARAM) NULL; - tvis.item.cChildren = 1; - LPTSTR lps1 = Utils::mucc_mir_a2t(Translate(groupNames[group])); - tvis.item.pszText = lps1; - //tvis.item.state = INDEXTOSTATEIMAGEMASK(1); - //tvis.item.stateMask = TVIS_STATEIMAGEMASK ; - setTreeItem(group, TreeView_InsertItem(GetDlgItem(hWnd, IDC_TREELIST), &tvis)); - Utils::mucc_mir_free(lps1); - } - tvis.hParent = getTreeItem(group); - tvis.hInsertAfter = TVI_SORT; - tvis.item.mask = TVIF_TEXT | TVIF_PARAM; - LPTSTR lps2 = Utils::mucc_mir_a2t(user->getNick()); - tvis.item.pszText = lps2; - tvis.item.lParam = (LPARAM) user; - user->setHTreeItem(TreeView_InsertItem(GetDlgItem(hWnd, IDC_TREELIST), &tvis)); - TreeView_Expand(GetDlgItem(hWnd, IDC_TREELIST), getTreeItem(group), TVE_EXPAND); - Utils::mucc_mir_free(lps2); - } - else { - if (user != NULL) { - group = getUserGroup(user); - TreeView_DeleteItem(GetDlgItem(hWnd, IDC_TREELIST), user->getHTreeItem()); - if (TreeView_GetChild(GetDlgItem(hWnd, IDC_TREELIST), getTreeItem(group))==NULL) { - TreeView_DeleteItem(GetDlgItem(hWnd, IDC_TREELIST), getTreeItem(group)); - setTreeItem(group, NULL); - } - removeUser(user); - delete user; - bLogEvent = TRUE; - } - } - if (bLogEvent && wasFirstMessage) { - logEvent(event); - } - return 1; -} -int ChatWindow::changeTopic(const MUCCEVENT *event) { - - SetDlgItemTextA(hWnd, IDC_TOPIC, event->pszText); -//if (wasFirstMessage) { - logEvent(event); -// } - return 1; -} - -int ChatWindow::changeRoomInfo(const MUCCEVENT *event) { - - Utils::log("setting room info !"); - setRoomName(event->pszName); - setRoomFlags(event->dwFlags); - return 1; -} - -const char * ChatWindow::getFontName(int index) { - const char *fontNames[] = {"Arial", - "Comic Sans MS", - "Courier New", - "Impact", - "Lucida Console", - "MS Sans Serif", - "Tahoma", - "Times New Roman", - "Trebuchet MS", - "Verdana"}; - if (index>9 || index<0) index = 0; - return fontNames[index]; -} -int ChatWindow::getFontNameNum() { - return 10; -} -int ChatWindow::getFontSize(int index) { - return index+7; -} -int ChatWindow::getFontSizeNum() { - return 10; -} - -void ChatWindow::refreshSettings() { - SendDlgItemMessage(hWnd, IDC_LOG, EM_SETBKGNDCOLOR , 0, Options::getLogBgColor()); - SendDlgItemMessage(hWnd, IDC_TREELIST, TVM_SETBKCOLOR, 0, Options::getListBgColor()); - eventList.setMaxSize(Options::getLogLimit()); -} - -void ChatWindow::refreshSettings(int force) { - - if (hListFont!=NULL && !force) { - return; - } - EnterCriticalSection(&mutex); - if (hListFont!=NULL) { - DeleteObject(hListFont); - } - if (hListGroupFont!=NULL) { - DeleteObject(hListGroupFont); - } - Font * font = Options::getFont(Options::FONT_USERLIST); - colorListText = font->getColor(); - hListFont = CreateFontA(font->getSize(), 0, 0, 0, - font->getStyle() & Font::BOLD ? FW_BOLD : FW_NORMAL, - font->getStyle() & Font::ITALIC ? 1 : 0, - font->getStyle() & Font::UNDERLINE ? 1 : 0, 0, - font->getCharSet(), - OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_ROMAN, - font->getFace()); - font = Options::getFont(Options::FONT_USERLISTGROUP); - colorListGroupText = font->getColor(); - hListGroupFont = CreateFontA(font->getSize(), 0, 0, 0, - font->getStyle() & Font::BOLD ? FW_BOLD : FW_NORMAL, - font->getStyle() & Font::ITALIC ? 1 : 0, - font->getStyle() & Font::UNDERLINE ? 1 : 0, 0, - font->getCharSet(), - OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_ROMAN, - font->getFace()); - - for (ChatWindow *ptr=list;ptr!=NULL;ptr=ptr->getNext()) { - ptr->refreshSettings(); - InvalidateRect(ptr->getHWND(), NULL, FALSE); - } - LeaveCriticalSection(&mutex); -} -HFONT ChatWindow::getListFont() { - return hListFont; -} - -HFONT ChatWindow::getListGroupFont() { - return hListGroupFont; -} - -COLORREF ChatWindow::getListTextColor() { - return colorListText; -} - -COLORREF ChatWindow::getListGroupTextColor() { - return colorListGroupText; -} - -HTREEITEM ChatWindow::getTreeItem(int index) { - return hUserGroups[index]; -} - -void ChatWindow::setTreeItem(int index, HTREEITEM hTreeItem) { - hUserGroups[index]=hTreeItem; -} - -int ChatWindow::getDefaultOptions() { - return FLAG_SHOW_NICKNAMES | FLAG_SHOW_TIMESTAMP | FLAG_FORMAT_ALL | FLAG_LOG_MESSAGES | FLAG_OPT_SENDONENTER; -} - -void ChatWindow::clearLog() { - if (getHWNDLog()!=NULL) { - IEVIEWEVENT iee; - ZeroMemory(&iee, sizeof(iee)); - iee.cbSize = sizeof(iee); - iee.iType = IEE_CLEAR_LOG; - iee.dwFlags = IEEF_NO_UNICODE; - iee.hwnd = hWndLog; - iee.hContact = NULL; - iee.codepage = CP_ACP; - iee.pszProto = getModule(); - CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&iee); - } else { - SetDlgItemTextA(getHWND(), IDC_LOG, ""); - } - isEmpty = true; - eventList.clear(); -} - -void ChatWindow::rebuildLog() { - int nMin, nMax; - HWND hwndLog; - if (getHWNDLog()!=NULL) { - IEVIEWEVENT iee; - ZeroMemory(&iee, sizeof(iee)); - iee.cbSize = sizeof(iee); - iee.iType = IEE_CLEAR_LOG; - iee.dwFlags = IEEF_NO_UNICODE; - iee.hwnd = hWndLog; - iee.hContact = NULL; - iee.codepage = CP_ACP; - iee.pszProto = getModule(); - CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&iee); - } else { - SetDlgItemTextA(getHWND(), IDC_LOG, ""); - } - isEmpty = true; - for (ChatEvent* event=eventList.getEvents();event!=NULL;event=event->getNext()) { - appendMessage(event->getEvent()); - } - if (getHWNDLog()==NULL) { - if (ServiceExists(MS_SMILEYADD_REPLACESMILEYS)) PostMessage(getHWND(), WM_TLEN_SMILEY, 0, 0); - hwndLog = GetDlgItem(getHWND(), IDC_LOG); - int len = GetWindowTextLengthA(hwndLog); - SendMessage(hwndLog, EM_SETSEL, len - 1, len - 1); - GetScrollRange(hwndLog, SB_VERT, &nMin, &nMax); - SetScrollPos(hwndLog, SB_VERT, nMax, TRUE); - PostMessage(hwndLog, WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, nMax), (LPARAM) NULL); - } -} - -int ChatWindow::logEvent(const MUCCEVENT *event) { - /* chat.dll mod*/ - /* - if (event->iType == MUCC_EVENT_MESSAGE) { - GCDEST gcdest; - GCEVENT gcevent = {sizeof(GCEVENT), &gcdest}; - gcdest.pszModule = (char *)this->getModule(); - gcdest.pszID = (char *)this->getRoomId(); - gcdest.iType = GC_EVENT_MESSAGE; - gcevent.pszText = event->pszText; - gcevent.pszNick = event->pszNick; - gcevent.pszUID = event->pszUID; - gcevent.bIsMe = event->bIsMe; - gcevent.bAddToLog = TRUE; - gcevent.time = event->time; - CallService(MS_GC_EVENT, 0, (LPARAM)&gcevent); - - } - if (event->iType == MUCC_EVENT_STATUS) { - const char *groupNames[] = {"Global Owners", "Owners", "Admins", "Moderators", "Users"}; - GCDEST gcdest; - GCEVENT gcevent = {sizeof(GCEVENT), &gcdest}; - gcdest.pszModule = (char *)this->getModule(); - gcdest.pszID = (char *)this->getRoomId(); - gcevent.pszText = event->pszText; - gcevent.pszNick = event->pszNick; - int group = 4; - if (event->dwFlags&MUCC_EF_USER_GLOBALOWNER) { - group = 0; - } else if (event->dwFlags&MUCC_EF_USER_OWNER) { - group = 1; - } else if (event->dwFlags&MUCC_EF_USER_ADMIN) { - group = 2; - } else if (event->dwFlags&MUCC_EF_USER_MODERATOR) { - group = 3; - } - gcevent.pszStatus = Translate(groupNames[group]); - gcevent.pszUID = event->pszUID; - gcevent.bIsMe = event->bIsMe; - gcevent.bAddToLog = TRUE; - gcevent.time = event->time; - if (event->dwData == ID_STATUS_ONLINE) { - gcdest.iType = GC_EVENT_JOIN; - } else { - gcdest.iType = GC_EVENT_PART; - } - CallService(MS_GC_EVENT, 0, (LPARAM)&gcevent); - } - */ - /* chat.dll mod*/ - - int nMin, nMax; - HWND hwndLog; - if (event->iType != MUCC_EVENT_ERROR) { - if (eventList.addEvent(event)) { - rebuildLog(); - return 1; - } - } - if (event->iType == MUCC_EVENT_MESSAGE) { - wasFirstMessage = 1; - appendMessage(event); - container->remoteSetUnread(this, 1); - } else { - appendMessage(event); - } - if (event->iType==MUCC_EVENT_MESSAGE && getOptions() & FLAG_FLASH_MESSAGES) { - container->remoteFlashWindow(); - } else if (event->iType==MUCC_EVENT_STATUS && event->dwData==ID_STATUS_ONLINE && getOptions() & FLAG_FLASH_JOINED) { - container->remoteFlashWindow(); - } else if (event->iType==MUCC_EVENT_STATUS && event->dwData==ID_STATUS_OFFLINE && getOptions() & FLAG_FLASH_LEFT) { - container->remoteFlashWindow(); - } else if (event->iType==MUCC_EVENT_TOPIC && getOptions() & FLAG_FLASH_TOPIC) { - container->remoteFlashWindow(); - } - if (getHWNDLog()==NULL) { - if (ServiceExists(MS_SMILEYADD_REPLACESMILEYS)) PostMessage(getHWND(), WM_TLEN_SMILEY, 0, 0); - hwndLog = GetDlgItem(getHWND(), IDC_LOG); - int len = GetWindowTextLengthA(hwndLog); - SendMessage(hwndLog, EM_SETSEL, len - 1, len - 1); - GetScrollRange(hwndLog, SB_VERT, &nMin, &nMax); - SetScrollPos(hwndLog, SB_VERT, nMax, TRUE); - PostMessage(hwndLog, WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, nMax), (LPARAM) NULL); - } - return 1; -} - -void ChatWindow::createRTFHeader() { - char *rtf; - int i, msgSize; - //, , iFontSize, bItalic, bBold, bUnderline; - rtf = NULL; - JabberStringAppend(&rtf, &msgSize, "{\\rtf1\\ansi\\deff0{\\fonttbl"); - - for (i=0;igetCharSet(), font->getFace()); - } - JabberStringAppend(&rtf, &msgSize, "}{\\colortbl "); - for (i=0;igetColor(); - JabberStringAppend(&rtf, &msgSize, "\\red%d\\green%d\\blue%d;", color&0xFF, (color>>8)&0xFF, (color>>16)&0xFF); - } - JabberStringAppend(&rtf, &msgSize, "}"); -} - - -int ChatWindow::appendMessage(const MUCCEVENT *event) { - char timestampStr[100], str[512]; - char *rtf, *escapedStr = NULL, *escapedNick = NULL; - Font *fontTimestamp, *fontName, *fontMessage; //*fontColon, - int msgSize; - DWORD color; - int iFontSize, bItalic, bBold, bUnderline; - HWND hwndLog; - DBTIMETOSTRING dbtts; - CHARRANGE sel; - SETTEXTEX stt; - //tm *ltime; - - if (event->iType!=MUCC_EVENT_STATUS && event->iType!=MUCC_EVENT_STATUS && event->iType!=MUCC_EVENT_ERROR - && event->iType!=MUCC_EVENT_TOPIC && event->iType != MUCC_EVENT_MESSAGE) { - return 0; - } - if (event->iType==MUCC_EVENT_MESSAGE && !(getOptions() & FLAG_LOG_MESSAGES)) { - return 0; - } else if (event->iType==MUCC_EVENT_STATUS && event->dwData==ID_STATUS_ONLINE && !(getOptions() & FLAG_LOG_JOINED)) { - return 0; - } else if (event->iType==MUCC_EVENT_STATUS && event->dwData==ID_STATUS_OFFLINE && !(getOptions() & FLAG_LOG_LEFT)) { - return 0; - } else if (event->iType==MUCC_EVENT_TOPIC && !(getOptions() & FLAG_LOG_TOPIC)) { - return 0; - } - - if (getHWNDLog()!=NULL) { - IEVIEWEVENTDATA ied; - IEVIEWEVENT iee; - IEVIEWWINDOW iew; - ZeroMemory(&iee, sizeof(iee)); - iee.cbSize = sizeof(iee); - iee.dwFlags = IEEF_NO_UNICODE; - iee.hwnd = hWndLog; - iee.hContact = NULL; - iee.iType = IEE_LOG_MEM_EVENTS; - iee.codepage = CP_ACP; - iee.pszProto = getModule(); - iee.eventData = &ied; - iee.count = 1; - - ied.cbSize = sizeof(IEVIEWEVENTDATA); - if (event->iType==MUCC_EVENT_MESSAGE) { - ied.iType = IEED_MUCC_EVENT_MESSAGE; - } else if (event->iType==MUCC_EVENT_STATUS && event->dwData==ID_STATUS_ONLINE) { - ied.iType = IEED_MUCC_EVENT_JOINED; - } else if (event->iType==MUCC_EVENT_STATUS && event->dwData==ID_STATUS_OFFLINE) { - ied.iType = IEED_MUCC_EVENT_LEFT; - } else if (event->iType==MUCC_EVENT_TOPIC) { - ied.iType = IEED_MUCC_EVENT_TOPIC; - } else if (event->iType==MUCC_EVENT_ERROR) { - ied.iType = IEED_MUCC_EVENT_ERROR; - } - ied.dwFlags = getOptions() & FLAG_FORMAT_ALL; - ied.next = NULL; - ied.color = event->color; - ied.fontSize = event->iFontSize; - ied.fontStyle = event->dwFlags; - ied.fontName = getFontName(event->iFont); - ied.pszNick = event->pszNick; - ied.pszText = event->pszText; - ied.time = event->time; - ied.dwData = getOptions(); // event->dwData; - ied.bIsMe = event->bIsMe; - CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&iee); - - iew.cbSize = sizeof(IEVIEWWINDOW); - iew.iType = IEW_SCROLLBOTTOM; - iew.hwnd = hWndLog; - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&iew); - return 1; - } - rtf = NULL; - fontTimestamp = FontList::getFont(FontList::FONT_TIMESTAMP); -// fontColon = FontList::getFont(FontList::FONT_COLON); - if (event->iType == MUCC_EVENT_MESSAGE) { - escapedStr=JabberRtfEscape((char *)event->pszText); - escapedNick=JabberRtfEscape((char *)event->pszNick); - if (event->bIsMe) { - fontName = FontList::getFont(FontList::FONT_MYNAME); - fontMessage = FontList::getFont(FontList::FONT_OUTMESSAGE); - } else { - fontName = FontList::getFont(FontList::FONT_OTHERSNAMES); - fontMessage = FontList::getFont(FontList::FONT_INMESSAGE); - } - } else { - fontName = FontList::getFont(FontList::FONT_ERROR); - if (event->iType == MUCC_EVENT_ERROR) { - escapedStr = JabberRtfEscape((char *)event->pszText); - fontMessage = FontList::getFont(FontList::FONT_ERROR); - } else if (event->iType == MUCC_EVENT_STATUS) { - if (event->dwData == ID_STATUS_ONLINE) { - fontMessage = FontList::getFont(FontList::FONT_JOINED); - _snprintf(str, sizeof(str), Translate("%s has joined."), event->pszNick); - } else { - fontMessage = FontList::getFont(FontList::FONT_LEFT); - _snprintf(str, sizeof(str), Translate("%s has left."), event->pszNick); - } - escapedStr = JabberRtfEscape(str); - } else if (event->iType == MUCC_EVENT_TOPIC) { - fontMessage = FontList::getFont(FontList::FONT_TOPIC); - _snprintf(str, sizeof(str), Translate("The topic is %s."), event->pszText); - escapedStr = JabberRtfEscape(str); - } - } - //ltime = localtime(&event->time); - JabberStringAppend(&rtf, &msgSize, "{\\rtf1\\ansi\\deff0{\\fonttbl"); - JabberStringAppend(&rtf, &msgSize, "{\\f0\\fnil\\fcharset%u %s;}", fontTimestamp->getCharSet(), fontTimestamp->getFace()); - JabberStringAppend(&rtf, &msgSize, "{\\f1\\fnil\\fcharset%u %s;}", fontName->getCharSet(), fontName->getFace()); - if (event->iType == MUCC_EVENT_MESSAGE && getOptions()&FLAG_FORMAT_FONT) { - JabberStringAppend(&rtf, &msgSize, "{\\f2\\fnil\\fcharset%u %s;}", fontMessage->getCharSet(), getFontName(event->iFont)); - } else { - JabberStringAppend(&rtf, &msgSize, "{\\f2\\fnil\\fcharset%u %s;}", fontMessage->getCharSet(), fontMessage->getFace()); - } - JabberStringAppend(&rtf, &msgSize, "}{\\colortbl "); - color = fontTimestamp->getColor(); - JabberStringAppend(&rtf, &msgSize, "\\red%d\\green%d\\blue%d;", color&0xFF, (color>>8)&0xFF, (color>>16)&0xFF); - color = fontName->getColor(); - JabberStringAppend(&rtf, &msgSize, "\\red%d\\green%d\\blue%d;", color&0xFF, (color>>8)&0xFF, (color>>16)&0xFF); - if (event->iType == MUCC_EVENT_MESSAGE && getOptions()&FLAG_FORMAT_COLOR && event->color!=0xFFFFFFFF) { - color = event->color; - } else { - color = fontMessage->getColor(); - } - JabberStringAppend(&rtf, &msgSize, "\\red%d\\green%d\\blue%d;", color&0xFF, (color>>8)&0xFF, (color>>16)&0xFF); - JabberStringAppend(&rtf, &msgSize, "}\\pard"); - if (!isEmpty) { - JabberStringAppend(&rtf, &msgSize, "\\par"); - } - isEmpty = false; - if (event->iType == MUCC_EVENT_MESSAGE) { - if (getOptions()&FLAG_SHOW_DATE || getOptions()&FLAG_SHOW_TIMESTAMP) { - bBold = fontTimestamp->getStyle() & Font::BOLD ? 1 : 0; - bItalic = fontTimestamp->getStyle() & Font::ITALIC ? 1 : 0; - bUnderline = fontTimestamp->getStyle() & Font::UNDERLINE ? 1 : 0; - iFontSize = fontTimestamp->getSize(); - iFontSize = 2 * abs((signed char)iFontSize) * 74 / logPixelSY; - dbtts.cbDest = 90; - dbtts.szDest = timestampStr; - timestampStr[0]='\0'; - //time_t time = time - if (getOptions()&FLAG_SHOW_DATE && getOptions()&FLAG_SHOW_TIMESTAMP) { - if (getOptions()&FLAG_LONG_DATE) { - dbtts.szFormat = getOptions()&FLAG_SHOW_SECONDS ? (char *)"D s" : (char *)"D t"; - } else { - dbtts.szFormat = getOptions()&FLAG_SHOW_SECONDS ? (char *)"d s" : (char *)"d t"; - } - } else if (getOptions()&FLAG_SHOW_DATE) { - dbtts.szFormat = getOptions()&FLAG_LONG_DATE ? (char *)"D" : (char *)"d"; - } else if (getOptions()&FLAG_SHOW_TIMESTAMP) { - dbtts.szFormat = getOptions()&FLAG_SHOW_SECONDS ? (char *)"s" : (char *)"t"; - } else { - dbtts.szFormat = (char *)""; - } - CallService(MS_DB_TIME_TIMESTAMPTOSTRING, (WPARAM)event->time, (LPARAM) & dbtts); - JabberStringAppend(&rtf, &msgSize, "\\f0\\cf0\\fs%d\\b%d\\i%d%s %s ", - iFontSize, - bBold, - bItalic, - bUnderline?"\\ul":"", - timestampStr); - } - bBold = fontName->getStyle() & Font::BOLD ? 1 : 0; - bItalic = fontName->getStyle() & Font::ITALIC ? 1 : 0; - bUnderline = fontName->getStyle() & Font::UNDERLINE ? 1 : 0; - iFontSize = fontName->getSize(); - iFontSize = 2 * abs((signed char)iFontSize) * 74 / logPixelSY; - if (getOptions()&FLAG_SHOW_NICKNAMES) { - JabberStringAppend(&rtf, &msgSize, "\\f1\\cf1\\fs%d\\b%d\\i%d%s %s: ", - iFontSize, - bBold, - bItalic, - bUnderline?"\\ul":"", - escapedNick); - } - bBold = fontMessage->getStyle() & Font::BOLD ? 1 : 0; - bItalic = fontMessage->getStyle() & Font::ITALIC ? 1 : 0; - bUnderline = fontMessage->getStyle() & Font::UNDERLINE ? 1 : 0; - iFontSize = fontMessage->getSize(); - iFontSize = 2 * abs((signed char)iFontSize) * 74 / logPixelSY; - if (getOptions()&FLAG_FORMAT_STYLE) { - bBold = bItalic = bUnderline = 0; - if (event->dwFlags & MUCC_EF_FONT_BOLD) bBold = 1; - if (event->dwFlags & MUCC_EF_FONT_ITALIC) bItalic = 1; - if (event->dwFlags & MUCC_EF_FONT_UNDERLINE) bUnderline = 1; - } - if (getOptions()&FLAG_FORMAT_SIZE) { - if (event->iFontSize != 0) iFontSize = 2 * event->iFontSize; - } - if (getOptions()&FLAG_MSGINNEWLINE) { - JabberStringAppend(&rtf, &msgSize, "\\line"); - } - JabberStringAppend(&rtf, &msgSize, "\\f2\\cf2\\fs%d\\b%d\\i%d%s %s", - iFontSize, - bBold, - bItalic, - bUnderline?"\\ul":"", - escapedStr); - } else { - if (event->iType == MUCC_EVENT_ERROR) { - bBold = fontName->getStyle() & Font::BOLD ? 1 : 0; - bItalic = fontName->getStyle() & Font::ITALIC ? 1 : 0; - bUnderline = fontName->getStyle() & Font::UNDERLINE ? 1 : 0; - iFontSize = fontName->getSize(); - iFontSize = 2 * abs((signed char)iFontSize) * 74 / logPixelSY; - JabberStringAppend(&rtf, &msgSize, "\\f1\\cf1\\fs%d\\b%d\\i%d%s %s: ", - iFontSize, - bBold, - bItalic, - bUnderline?"\\ul":"", - Translate("Error")); - } else { - if (getOptions()&FLAG_SHOW_DATE || getOptions()&FLAG_SHOW_TIMESTAMP) { - bBold = fontTimestamp->getStyle() & Font::BOLD ? 1 : 0; - bItalic = fontTimestamp->getStyle() & Font::ITALIC ? 1 : 0; - bUnderline = fontTimestamp->getStyle() & Font::UNDERLINE ? 1 : 0; - iFontSize = fontTimestamp->getSize(); - iFontSize = 2 * abs((signed char)iFontSize) * 74 / logPixelSY; - dbtts.cbDest = 90; - dbtts.szDest = timestampStr; - timestampStr[0]='\0'; - //time_t time = time - if (getOptions()&FLAG_SHOW_DATE && getOptions()&FLAG_SHOW_TIMESTAMP) { - if (getOptions()&FLAG_LONG_DATE) { - dbtts.szFormat = getOptions()&FLAG_SHOW_SECONDS ? (char *)"D s" : (char *)"D t"; - } else { - dbtts.szFormat = getOptions()&FLAG_SHOW_SECONDS ? (char *)"d s" : (char *)"d t"; - } - } else if (getOptions()&FLAG_SHOW_DATE) { - dbtts.szFormat = getOptions()&FLAG_LONG_DATE ? (char *)"D" : (char *)"d"; - } else if (getOptions()&FLAG_SHOW_TIMESTAMP) { - dbtts.szFormat = getOptions()&FLAG_SHOW_SECONDS ? (char *)"s" : (char *)"t"; - } else { - dbtts.szFormat = (char *)""; - } - CallService(MS_DB_TIME_TIMESTAMPTOSTRING, (WPARAM)event->time, (LPARAM) & dbtts); - JabberStringAppend(&rtf, &msgSize, "\\f0\\cf0\\fs%d\\b%d\\i%d%s %s ", - iFontSize, - bBold, - bItalic, - bUnderline?"\\ul":"", - timestampStr); - } - } - bBold = fontMessage->getStyle() & Font::BOLD ? 1 : 0; - bItalic = fontMessage->getStyle() & Font::ITALIC ? 1 : 0; - bUnderline = fontMessage->getStyle() & Font::UNDERLINE ? 1 : 0; - iFontSize = fontMessage->getSize(); - iFontSize = 2 * abs((signed char)iFontSize) * 74 / logPixelSY; - JabberStringAppend(&rtf, &msgSize, "\\f2\\cf2\\fs%d\\b%d\\i%d%s %s", - iFontSize, - bBold, - bItalic, - bUnderline?"\\ul":"", - escapedStr); - } - JabberStringAppend(&rtf, &msgSize, "}"); - hwndLog = GetDlgItem(getHWND(), IDC_LOG); - sel.cpMin = sel.cpMax = GetWindowTextLength(hwndLog); - SendMessage(hwndLog, EM_EXSETSEL, 0, (LPARAM) &sel); - stt.flags = ST_SELECTION; - stt.codepage = CP_ACP; - SendMessage(hwndLog, EM_SETTEXTEX, (WPARAM) &stt, (LPARAM) rtf); - free(rtf); - if (escapedStr!=NULL) free(escapedStr); - if (escapedNick!=NULL) free(escapedNick); - return 1; -} - -void ChatWindow::setFont(int font, int size, int bBold, int bItalic, int bUnderline, COLORREF color) { - if (hEditFont!=NULL) { - DeleteObject(hEditFont); - } - hEditFont = CreateFontA(MulDiv(-size, logPixelSY, 74), 0, 0, 0, bBold?FW_BOLD:FW_NORMAL, - bItalic, bUnderline, 0, 238, OUT_DEFAULT_PRECIS, - CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, - FIXED_PITCH | FF_ROMAN, - getFontName(font)); - SendDlgItemMessage(hWnd, IDC_EDIT, WM_SETFONT, (WPARAM) hEditFont, TRUE); - this->font = font; - this->fontSize = size; - this->bBold = bBold; - this->bItalic = bItalic; - this->bUnderline = bUnderline; - this->fontColor = color; -} - -int ChatWindow::getFontStyle() { - int style = 0; - if (bBold) style |= MUCC_EF_FONT_BOLD; - if (bItalic) style |= MUCC_EF_FONT_ITALIC; - if (bUnderline) style |= MUCC_EF_FONT_UNDERLINE; - return style; -} - -int ChatWindow::getFont() { - return font; -} - -int ChatWindow::getFontSize() { - return fontSize; -} - -COLORREF ChatWindow::getFontColor() { - return fontColor; -} - -void ChatWindow ::queryResultContacts(MUCCQUERYRESULT *queryResult) { - HelperDialog::inviteDlg(this, queryResult); -} - -void ChatWindow ::queryResultUsers(MUCCQUERYRESULT *queryResult) { - if (adminWindow!=NULL) { - adminWindow->queryResultUsers(queryResult); - } -} - -ChatWindow * ChatWindow::getWindow(const char *module, const char *roomId) { - ChatWindow *ptr; - EnterCriticalSection(&mutex); - for (ptr=list;ptr!=NULL;ptr=ptr->getNext()) { - if (strcmp(ptr->getRoomId(), roomId)==0 && strcmp(ptr->getModule(), module)==0) { - break; - } - } - LeaveCriticalSection(&mutex); - return ptr; -} - - -static DWORD CALLBACK EditStreamCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb) -{ - char *szFilename = (char *)dwCookie; - FILE *file; - file = fopen(szFilename, "ab"); - if (file != NULL) { - *pcb = (LONG)fwrite(pbBuff, (size_t)cb, (size_t)1, file); - fclose(file); - return 0; - } - return 1; -} - -static BOOL CALLBACK EditWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - ChatWindow *chat; - chat = (ChatWindow *) GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); - switch (msg) { -// case WM_GETDLGCODE: -// return DLGC_WANTALLKEYS; //DLGC_WANTARROWS|DLGC_WANTCHARS|DLGC_HASSETSEL|DLGC_WANTALLKEYS; - case WM_CHAR: - if (wParam=='\r' || wParam=='\n') { - if (((GetKeyState(VK_CONTROL)&0x8000)==0) == ((Options::getChatWindowOptions() & ChatWindow::FLAG_OPT_SENDONENTER) != 0)) { - PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0); - return FALSE; - } - } - if (wParam == 1 && GetKeyState(VK_CONTROL) & 0x8000) { //ctrl-a - SendMessage(hwnd, EM_SETSEL, 0, -1); - return 0; - } - if (wParam == 23 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-w - SendMessage(GetParent(hwnd), WM_CLOSE, 0, 0); - return 0; - } - break; - } - return CallWindowProc(oldEditWndProc, hwnd, msg, wParam, lParam); -} - -static BOOL CALLBACK SplitterWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - ChatWindow *chat; - chat = (ChatWindow *) GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); - switch (msg) { - case WM_NCHITTEST: - return HTCLIENT; - case WM_SETCURSOR: - RECT rc; - GetClientRect(hwnd, &rc); - SetCursor(rc.right > rc.bottom ? hCurSplitNS : hCurSplitWE); - return TRUE; - case WM_LBUTTONDOWN: - SetCapture(hwnd); - return 0; - case WM_MOUSEMOVE: - if (GetCapture() == hwnd) { - HWND hParent; - RECT rc; - POINT pt; - hParent = GetParent(hwnd); - GetClientRect(hwnd, &rc); - if (rc.right < rc.bottom) { - pt.x = LOWORD(GetMessagePos()); - GetClientRect(hParent, &rc); - ScreenToClient(hParent, &pt); - if (pt.x < chat->vSplitterMinLeft) - pt.x = chat->vSplitterMinLeft; - if (rc.right-pt.x < chat->vSplitterMinRight) - pt.x = rc.right-chat->vSplitterMinRight; - if (chat->vSplitterPos != rc.right-pt.x) { - chat->vSplitterPos = rc.right-pt.x; - SendMessage(hParent, WM_SIZE, SIZE_RESTORED, (rc.bottom<<16)+rc.right); - } - } else { - pt.y = HIWORD(GetMessagePos()); - GetClientRect(hParent, &rc); - ScreenToClient(hParent, &pt); - if (pt.y < chat->hSplitterMinTop) - pt.y = chat->hSplitterMinTop; - if (rc.bottom-pt.y < chat->hSplitterMinBottom) - pt.y = rc.bottom-chat->hSplitterMinBottom; - if (chat->hSplitterPos != rc.bottom-pt.y) { - chat->hSplitterPos = rc.bottom-pt.y; - SendMessage(hParent, WM_SIZE, SIZE_RESTORED, (rc.bottom<<16)+rc.right); - } - } - } - return 0; - case WM_LBUTTONUP: - ReleaseCapture(); - return 0; - } - return CallWindowProc(oldSplitterWndProc, hwnd, msg, wParam, lParam); -} - - - - -static INT_PTR CALLBACK LogDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - int i; - ChatWindow *chatWindow; - chatWindow = (ChatWindow *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - if (msg!=WM_INITDIALOG && chatWindow==NULL) { - return FALSE; - } - switch (msg) { - case WM_INITDIALOG: - HDC hdc; - TranslateDialogDefault(hwndDlg); - hdc = GetDC(NULL); - logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY); - ReleaseDC(NULL, hdc); - SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) muccIcon[MUCC_IDI_CHAT]); - - chatWindow = (ChatWindow *) lParam; - chatWindow->setHWND(hwndDlg); - ChatWindow::refreshSettings(0); - oldSplitterWndProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_HSPLIT), GWLP_WNDPROC, (LONG_PTR) SplitterWndProc); - oldSplitterWndProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_VSPLIT), GWLP_WNDPROC, (LONG_PTR) SplitterWndProc); - oldEditWndProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT), GWLP_WNDPROC, (LONG_PTR) EditWndProc); - ShowWindow(GetDlgItem(hwndDlg, IDC_LIST), SW_HIDE); - chatWindow->hSplitterMinTop = 90; - chatWindow->hSplitterMinBottom = 40; - chatWindow->hSplitterPos=50; - chatWindow->vSplitterMinLeft = 100; - chatWindow->vSplitterMinRight = 80; - chatWindow->vSplitterPos=110; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) chatWindow); - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT), GWLP_USERDATA, (LONG_PTR) chatWindow); - chatWindow->refreshSettings(); - - SetWindowTextA(hwndDlg, chatWindow->getRoomName()); - SendDlgItemMessage(hwndDlg, IDC_BOLD, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_BOLD]); - SendDlgItemMessage(hwndDlg, IDC_ITALIC, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_ITALIC]); - SendDlgItemMessage(hwndDlg, IDC_UNDERLINE, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_UNDERLINE]); - SendDlgItemMessage(hwndDlg, IDC_SMILEYBTN, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_SMILEY]); - - SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_LINK); - SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETUNDOLIMIT, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_LOG, EM_AUTOURLDETECT, (WPARAM) TRUE, 0); - - // LoadImage(hInst, smadd_iconinfo.SmileyIcon, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0)); - SendDlgItemMessage(hwndDlg, IDC_OPTIONS, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_OPTIONS]); - SendDlgItemMessage(hwndDlg, IDC_INVITE, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_INVITE]); - - SendDlgItemMessage(hwndDlg, IDC_TOPIC_BUTTON, BUTTONSETASFLATBTN, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_INVITE, BUTTONSETASFLATBTN, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_BOLD, BUTTONSETASFLATBTN, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_BOLD, BUTTONSETASPUSHBTN, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_ITALIC, BUTTONSETASFLATBTN, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_ITALIC, BUTTONSETASPUSHBTN, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_UNDERLINE, BUTTONSETASFLATBTN, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_UNDERLINE, BUTTONSETASPUSHBTN, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_OPTIONS, BUTTONSETASFLATBTN, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_SMILEYBTN, BUTTONSETASFLATBTN, 0, 0); - - SetWindowLong(GetDlgItem(hwndDlg,IDC_TREELIST),GWL_STYLE,GetWindowLong(GetDlgItem(hwndDlg,IDC_TREELIST),GWL_STYLE)|TVS_NOHSCROLL); - SendDlgItemMessage(hwndDlg,IDC_TREELIST, CCM_SETVERSION,(WPARAM)5,0); - //TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_TREELIST), hImageList, TVSIL_STATE); - TreeView_SetItemHeight(GetDlgItem(hwndDlg, IDC_TREELIST), 16); - TreeView_SetIndent(GetDlgItem(hwndDlg, IDC_TREELIST), 16); - for(i=0;igetFontSizeNum();i++) { - char str[10]; - sprintf(str, "%d", chatWindow->getFontSize(i)); - int n = SendDlgItemMessageA(hwndDlg, IDC_FONTSIZE, CB_ADDSTRING, 0, (LPARAM) str); - SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_SETITEMDATA, n, chatWindow->getFontSize(i)); - } - SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_SETCURSEL, Options::getChatWindowFontSize(), 0); - for(i=0;igetFontNameNum();i++) { - int n = SendDlgItemMessageA(hwndDlg, IDC_FONT, CB_ADDSTRING, 0, (LPARAM) chatWindow->getFontName(i)); - SendDlgItemMessage(hwndDlg, IDC_FONT, CB_SETITEMDATA, n, i); - } - SendDlgItemMessage(hwndDlg, IDC_FONT, CB_SETCURSEL, Options::getChatWindowFont(), 0); - CheckDlgButton(hwndDlg, IDC_BOLD, Options::getChatWindowFontStyle()&Font::BOLD ? TRUE : FALSE); - CheckDlgButton(hwndDlg, IDC_ITALIC, Options::getChatWindowFontStyle()&Font::ITALIC ? TRUE : FALSE); - CheckDlgButton(hwndDlg, IDC_UNDERLINE, Options::getChatWindowFontStyle()&Font::UNDERLINE ? TRUE : FALSE); - SendDlgItemMessage(hwndDlg, IDC_COLOR, CPM_SETCOLOUR, 0, (LPARAM)Options::getChatWindowFontColor()); - chatWindow->setFont(Options::getChatWindowFont(), - chatWindow->getFontSize(Options::getChatWindowFontSize()), - Options::getChatWindowFontStyle()&Font::BOLD ? 1 : 0, - Options::getChatWindowFontStyle()&Font::ITALIC ? 1 : 0, - Options::getChatWindowFontStyle()&Font::UNDERLINE ? 1 : 0, - Options::getChatWindowFontColor()); - if (ServiceExists(MS_IEVIEW_WINDOW) && Options::getChatWindowOptions() & ChatWindow::FLAG_OPT_ENABLEIEVIEW) { - IEVIEWWINDOW ieWindow; - ieWindow.cbSize = sizeof(IEVIEWWINDOW); - ieWindow.iType = IEW_CREATE; - ieWindow.dwFlags = 0; - ieWindow.dwMode = IEWM_MUCC; - ieWindow.parent = hwndDlg; - ieWindow.x = 0; - ieWindow.y = 0; - ieWindow.cx = 200; - ieWindow.cy = 300; - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); - chatWindow->setHWNDLog(ieWindow.hwnd); - ShowWindow(GetDlgItem(hwndDlg, IDC_LOG), SW_HIDE); - } - SetWindowPos(hwndDlg, HWND_TOP, 0, 0, 540, 370, SWP_NOMOVE | SWP_SHOWWINDOW); - SetFocus(GetDlgItem(hwndDlg, IDC_EDIT)); - chatWindow->clearLog(); - SetEvent(chatWindow->getEvent()); - return TRUE; - break; - case DM_CHAT_EVENT: - MUCCEVENT *mucEvent; - mucEvent = (MUCCEVENT *) lParam; - switch (mucEvent->iType) { - case MUCC_EVENT_MESSAGE: - chatWindow->logEvent(mucEvent); - break; - case MUCC_EVENT_TOPIC: - chatWindow->changeTopic(mucEvent); - break; - case MUCC_EVENT_STATUS: - chatWindow->changePresence(mucEvent); - break; - case MUCC_EVENT_ERROR: - chatWindow->logEvent(mucEvent); - break; - //case MUCC_EVENT_LEAVE: - // DestroyWindow(hwndDlg); - // break; - case MUCC_EVENT_ROOM_INFO: - chatWindow->changeRoomInfo(mucEvent); - break; - } - return TRUE; - case DM_CHAT_QUERY: - MUCCQUERYRESULT *queryResult; - queryResult = (MUCCQUERYRESULT *)lParam; - switch (queryResult->iType) { - case MUCC_EVENT_QUERY_CONTACTS: - chatWindow->queryResultContacts(queryResult); - break; - case MUCC_EVENT_QUERY_USERS: - chatWindow->queryResultUsers(queryResult); - break; - - } - return TRUE; - case WM_SETFOCUS: - SetFocus(GetDlgItem(hwndDlg, IDC_EDIT)); - return TRUE; - case WM_GETMINMAXINFO: - MINMAXINFO *mmi; - mmi = (MINMAXINFO *) lParam; - mmi->ptMinTrackSize.x = 370; - mmi->ptMinTrackSize.y = 130; - return FALSE; - case WM_SIZE: - if (wParam!=SIZE_MINIMIZED) { - int dlgWidth, dlgHeight; - RECT rc; - HDWP hdwp; - GetClientRect(hwndDlg, &rc); - dlgWidth = rc.right-rc.left; - dlgHeight = rc.bottom-rc.top; - if (dlgHeight-chatWindow->hSplitterPos < chatWindow->hSplitterMinTop) { - chatWindow->hSplitterPos = dlgHeight-chatWindow->hSplitterMinTop; - } - if (chatWindow->hSplitterPos < chatWindow->hSplitterMinBottom) { - chatWindow->hSplitterPos = chatWindow->hSplitterMinBottom; - } - if (dlgWidth-chatWindow->vSplitterPos < chatWindow->vSplitterMinLeft) { - chatWindow->vSplitterPos = dlgWidth-chatWindow->vSplitterMinLeft; - } - if (chatWindow->vSplitterPos < chatWindow->vSplitterMinRight) { - chatWindow->vSplitterPos = chatWindow->vSplitterMinRight; - } - - hdwp = BeginDeferWindowPos(15); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_TOPIC), 0, 70, 7, dlgWidth-140, 18, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_LOG), 0, 0, 30, dlgWidth-(chatWindow->vSplitterPos)-2, dlgHeight-(chatWindow->hSplitterPos)-30-26-2, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_TREELIST), 0, dlgWidth-(chatWindow->vSplitterPos)+2, 30, (chatWindow->vSplitterPos)-2, dlgHeight-(chatWindow->hSplitterPos)-30-26-2, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_EDIT), 0, 0, dlgHeight-(chatWindow->hSplitterPos)+2, dlgWidth, (chatWindow->hSplitterPos)-5, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_INVITE), 0, dlgWidth-31, dlgHeight-(chatWindow->hSplitterPos)-26, 31, 24, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_BOLD), 0, 0, dlgHeight-(chatWindow->hSplitterPos)-26, 24, 24, SWP_NOZORDER ); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_ITALIC), 0, 24, dlgHeight-(chatWindow->hSplitterPos)-26, 24, 24, SWP_NOZORDER ); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_UNDERLINE), 0, 48, dlgHeight-(chatWindow->hSplitterPos)-26, 24, 24, SWP_NOZORDER ); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_COLOR), 0, 73, dlgHeight-(chatWindow->hSplitterPos)-25, 22, 22, SWP_NOZORDER ); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_FONT), 0, 98, dlgHeight-(chatWindow->hSplitterPos)-24, 110, 13, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_FONTSIZE), 0, 213, dlgHeight-(chatWindow->hSplitterPos)-24, 38, 13, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_SMILEYBTN), 0, 265, dlgHeight-(chatWindow->hSplitterPos)-26, 24, 24, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_OPTIONS), 0, dlgWidth-79, dlgHeight-(chatWindow->hSplitterPos)-26, 24, 24, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_VSPLIT), 0, dlgWidth-(chatWindow->vSplitterPos)-2, 30, 4, dlgHeight-(chatWindow->hSplitterPos)-30-26-2, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_HSPLIT), 0, 0, dlgHeight-(chatWindow->hSplitterPos)-2, dlgWidth-8, 4, SWP_NOZORDER); - EndDeferWindowPos(hdwp); - if (chatWindow->getHWNDLog()!=NULL) { - IEVIEWWINDOW ieWindow; - ieWindow.cbSize = sizeof(IEVIEWWINDOW); - ieWindow.iType = IEW_SETPOS; - ieWindow.parent = hwndDlg; - ieWindow.hwnd = chatWindow->getHWNDLog(); - ieWindow.x = 0; - ieWindow.y = 30; - ieWindow.cx = dlgWidth-(chatWindow->vSplitterPos)-2; - ieWindow.cy = dlgHeight-(chatWindow->hSplitterPos)-30-26-2; - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); - } - } - break; - /* - case WM_SYSCOMMAND: - if (wParam == SC_CLOSE) { - SendMessage(hwndDlg, WM_CLOSE, 1, 0); -// muce.iType = MUCC_EVENT_LEAVE; -// muce.pszModule = chatWindow->getModule(); -// muce.pszID = chatWindow->getRoomId(); -// NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); -// delete chatWindow; - return TRUE; - } - break; - */ - case WM_CLOSE: - //if (wParam != 1) { // esc - //return FALSE; - //} - DestroyWindow(hwndDlg); - return TRUE; - case WM_DESTROY: - { - MUCCEVENT muce; - muce.cbSize = sizeof(MUCCEVENT); - muce.iType = MUCC_EVENT_LEAVE; - muce.pszModule = chatWindow->getModule(); - muce.pszID = chatWindow->getRoomId(); - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - if (chatWindow->getHWNDLog()!=NULL) { - IEVIEWWINDOW ieWindow; - ieWindow.cbSize = sizeof(IEVIEWWINDOW); - ieWindow.iType = IEW_DESTROY; - ieWindow.hwnd = chatWindow->getHWNDLog(); - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); - } - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) NULL); - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_HSPLIT), GWLP_WNDPROC, (LONG_PTR) oldSplitterWndProc); - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_VSPLIT), GWLP_WNDPROC, (LONG_PTR) oldSplitterWndProc); - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT), GWLP_WNDPROC, (LONG_PTR) oldEditWndProc); - delete chatWindow; - break; - } - case WM_TLEN_SMILEY: - if (ServiceExists(MS_SMILEYADD_REPLACESMILEYS)) { - SMADD_RICHEDIT2 smre; - smre.cbSize = sizeof(SMADD_RICHEDIT2); - smre.hwndRichEditControl = GetDlgItem(hwndDlg, IDC_LOG); - smre.Protocolname = (char *)chatWindow->getModule(); - smre.rangeToReplace = NULL; - smre.useSounds = FALSE; - smre.disableRedraw = FALSE; - CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM) &smre); - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_OPTIONS: - { - MUCCEVENT muce; - HMENU hMenu; - RECT rc; - int iSelection; - hMenu=GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(IDR_CHATOPTIONS)),0); - CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)hMenu,0); - GetWindowRect(GetDlgItem(hwndDlg, IDC_OPTIONS), &rc); - CheckMenuItem(hMenu, ID_OPTIONMENU_SHOWNICKNAMES, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_SHOW_NICKNAMES ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hMenu, ID_OPTIONMENU_MSGINNEWLINE, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_MSGINNEWLINE ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hMenu, ID_OPTIONMENU_SHOWDATE, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_SHOW_DATE ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hMenu, ID_OPTIONMENU_SHOWTIMESTAMP, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_SHOW_TIMESTAMP ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hMenu, ID_OPTIONMENU_SHOWSECONDS, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_SHOW_SECONDS ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hMenu, ID_OPTIONMENU_USELONGDATE, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_LONG_DATE ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hMenu, ID_OPTIONMENU_FORMATFONT, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_FORMAT_FONT ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hMenu, ID_OPTIONMENU_FORMATSIZE, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_FORMAT_SIZE ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hMenu, ID_OPTIONMENU_FORMATCOLOR, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_FORMAT_COLOR ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hMenu, ID_OPTIONMENU_FORMATSTYLE, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_FORMAT_STYLE ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hMenu, ID_OPTIONMENU_LOGMESSAGES, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_LOG_MESSAGES ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hMenu, ID_OPTIONMENU_LOGJOINED, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_LOG_JOINED ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hMenu, ID_OPTIONMENU_LOGLEFT, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_LOG_LEFT ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hMenu, ID_OPTIONMENU_LOGTOPIC, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_LOG_TOPIC ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hMenu, ID_OPTIONMENU_FLASHMESSAGES, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_FLASH_MESSAGES ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hMenu, ID_OPTIONMENU_FLASHJOINED, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_FLASH_JOINED ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hMenu, ID_OPTIONMENU_FLASHLEFT, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_FLASH_LEFT ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hMenu, ID_OPTIONMENU_FLASHTOPIC, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_FLASH_TOPIC ? MF_CHECKED : MF_UNCHECKED); - if (chatWindow->getMe()!=NULL) { - if (chatWindow->getMe()->getFlags() & (MUCC_EF_USER_OWNER | MUCC_EF_USER_ADMIN)) { - EnableMenuItem(hMenu, ID_ADMINMENU_ADMIN, MF_BYCOMMAND | MF_ENABLED); - EnableMenuItem(hMenu, ID_ADMINMENU_BROWSE, MF_BYCOMMAND | MF_ENABLED); - } - if (chatWindow->getMe()->getFlags() & MUCC_EF_USER_OWNER) { - EnableMenuItem(hMenu, ID_ADMINMENU_DESTROY, MF_BYCOMMAND | MF_ENABLED); - } - } - iSelection = TrackPopupMenu(hMenu, TPM_RETURNCMD | TPM_TOPALIGN | TPM_LEFTALIGN, rc.left, rc.bottom, 0, hwndDlg, NULL); - DestroyMenu(hMenu); - switch (iSelection) { - case ID_OPTIONMENU_SHOWNICKNAMES: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_SHOW_NICKNAMES); - break; - case ID_OPTIONMENU_MSGINNEWLINE: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_MSGINNEWLINE); - break; - case ID_OPTIONMENU_SHOWDATE: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_SHOW_DATE); - break; - case ID_OPTIONMENU_SHOWTIMESTAMP: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_SHOW_TIMESTAMP); - break; - case ID_OPTIONMENU_SHOWSECONDS: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_SHOW_SECONDS); - break; - case ID_OPTIONMENU_USELONGDATE: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_LONG_DATE); - break; - case ID_OPTIONMENU_FORMATFONT: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_FORMAT_FONT); - break; - case ID_OPTIONMENU_FORMATSIZE: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_FORMAT_SIZE); - break; - case ID_OPTIONMENU_FORMATCOLOR: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_FORMAT_COLOR); - break; - case ID_OPTIONMENU_FORMATSTYLE: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_FORMAT_STYLE); - break; - case ID_OPTIONMENU_LOGMESSAGES: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_LOG_MESSAGES); - break; - case ID_OPTIONMENU_LOGJOINED: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_LOG_JOINED); - break; - case ID_OPTIONMENU_LOGLEFT: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_LOG_LEFT); - break; - case ID_OPTIONMENU_LOGTOPIC: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_LOG_TOPIC); - break; - case ID_OPTIONMENU_FLASHMESSAGES: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_FLASH_MESSAGES); - break; - case ID_OPTIONMENU_FLASHJOINED: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_FLASH_JOINED); - break; - case ID_OPTIONMENU_FLASHLEFT: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_FLASH_LEFT); - break; - case ID_OPTIONMENU_FLASHTOPIC: - chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_FLASH_TOPIC); - break; - case ID_OPTIONMENU_SAVEDEFAULT: - Options::setChatWindowOptions(chatWindow->getOptions()); - Options::setChatWindowFont((int)SendDlgItemMessage(hwndDlg, IDC_FONT, CB_GETCURSEL, 0, 0)); - Options::setChatWindowFontSize((int)SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_GETCURSEL, 0, 0)); - Options::setChatWindowFontStyle( - (IsDlgButtonChecked(hwndDlg, IDC_BOLD) ? Font::BOLD : 0) | - (IsDlgButtonChecked(hwndDlg, IDC_ITALIC) ? Font::ITALIC : 0) | - (IsDlgButtonChecked(hwndDlg, IDC_UNDERLINE) ? Font::UNDERLINE : 0) - ); - Options::setChatWindowFontColor((COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLOR, CPM_GETCOLOUR,0,0)); - Options::saveSettings(); - break; - case ID_ADMINMENU_DESTROY: - muce.cbSize = sizeof(MUCCEVENT); - muce.iType = MUCC_EVENT_REMOVE_ROOM; - muce.pszModule = chatWindow->getModule(); - muce.pszID = chatWindow->getRoomId(); - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - DestroyWindow(hwndDlg); - break; - case ID_ADMINMENU_ADMIN: - chatWindow->startAdminDialog(ChatWindow::ADMIN_MODE_KICK); - break; - case ID_ADMINMENU_BROWSE: - chatWindow->startAdminDialog(ChatWindow::ADMIN_MODE_ROLE); - break; - case ID_ADMINMENU_SAVELOG: - if (chatWindow->getHWNDLog()!=NULL) { - IEVIEWEVENT iee; - ZeroMemory(&iee, sizeof(iee)); - iee.cbSize = sizeof(iee); - iee.dwFlags = 0; - iee.hwnd = chatWindow->getHWNDLog(); - iee.hContact = NULL; - iee.iType = IEE_SAVE_DOCUMENT; - CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&iee); - } else { - char szFilename[MAX_PATH]; - strcpy(szFilename, ""); - OPENFILENAMEA ofn={0}; - ofn.lStructSize=sizeof(OPENFILENAME); - ofn.hwndOwner=hwndDlg; - ofn.lpstrFile = szFilename; - ofn.lpstrFilter = "Rich Text File\0*.rtf\0\0"; - ofn.nMaxFile = MAX_PATH; - ofn.nMaxFileTitle = MAX_PATH; - ofn.Flags = OFN_HIDEREADONLY; - ofn.lpstrDefExt = "rtf"; - if (GetSaveFileNameA(&ofn)) { - //remove(szFilename); - EDITSTREAM stream = { 0 }; - stream.dwCookie = (DWORD_PTR)szFilename; - stream.dwError = 0; - stream.pfnCallback = EditStreamCallback; - SendDlgItemMessage(hwndDlg, IDC_LOG, EM_STREAMOUT, SF_RTF | SF_USECODEPAGE, (LPARAM) & stream); - } - } - break; - } - } - break; - case IDC_SMILEYBTN: - SMADD_SHOWSEL smaddInfo; - RECT rc; - smaddInfo.cbSize = sizeof(SMADD_SHOWSEL); - smaddInfo.hwndTarget = GetDlgItem(hwndDlg, IDC_EDIT); - smaddInfo.targetMessage = EM_REPLACESEL; - smaddInfo.targetWParam = TRUE; - smaddInfo.Protocolname = chatWindow->getModule(); - GetWindowRect(GetDlgItem(hwndDlg, IDC_SMILEYBTN), &rc); - smaddInfo.Direction = 0; - smaddInfo.xPosition = rc.left; - smaddInfo.yPosition = rc.top + 24; - if (chatWindow->getHWNDLog() != NULL) { - CallService(MS_IEVIEW_SHOWSMILEYSELECTION, 0, (LPARAM) &smaddInfo); - } else { - CallService(MS_SMILEYADD_SHOWSELECTION, 0, (LPARAM) &smaddInfo); - } - break; - case IDC_INVITE: - { - MUCCEVENT muce; - muce.cbSize = sizeof(MUCCEVENT); - muce.iType = MUCC_EVENT_QUERY_CONTACTS; - muce.pszModule = chatWindow->getModule(); - muce.pszID = chatWindow->getRoomId(); - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - } - break; - case IDC_TOPIC_BUTTON: - HelperDialog::topicDlg(chatWindow); - break; - case IDCANCEL: - DestroyWindow(hwndDlg); - return TRUE; - case IDOK: - { - MUCCEVENT muce; - char text[2048]; - GetDlgItemTextA(hwndDlg, IDC_EDIT, text, sizeof(text)); - SetDlgItemTextA(hwndDlg, IDC_EDIT, ""); - muce.cbSize = sizeof(MUCCEVENT); - muce.iType = MUCC_EVENT_MESSAGE; - muce.pszModule = chatWindow->getModule(); - muce.pszID = chatWindow->getRoomId(); - muce.pszText = text; - muce.iFont = chatWindow->getFont(); - muce.iFontSize = chatWindow->getFontSize(); - muce.dwFlags = chatWindow->getFontStyle(); - muce.color = chatWindow->getFontColor(); - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - } - break; - case IDC_BOLD: - case IDC_ITALIC: - case IDC_UNDERLINE: - if (HIWORD(wParam)==BN_CLICKED) { - chatWindow->setFont((int) SendDlgItemMessage(hwndDlg, IDC_FONT, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONT, CB_GETCURSEL, 0, 0), 0), - (int) SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_GETCURSEL, 0, 0), 0), - IsDlgButtonChecked(hwndDlg, IDC_BOLD), - IsDlgButtonChecked(hwndDlg, IDC_ITALIC), - IsDlgButtonChecked(hwndDlg, IDC_UNDERLINE), - (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLOR, CPM_GETCOLOUR,0,0)); - } - case IDC_FONT: - case IDC_FONTSIZE: - if (HIWORD(wParam)==CBN_SELCHANGE) { - chatWindow->setFont((int) SendDlgItemMessage(hwndDlg, IDC_FONT, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONT, CB_GETCURSEL, 0, 0), 0), - (int) SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_GETCURSEL, 0, 0), 0), - IsDlgButtonChecked(hwndDlg, IDC_BOLD), - IsDlgButtonChecked(hwndDlg, IDC_ITALIC), - IsDlgButtonChecked(hwndDlg, IDC_UNDERLINE), - (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLOR, CPM_GETCOLOUR,0,0)); - } - break; - case IDC_COLOR: - if (HIWORD(wParam)==CPN_COLOURCHANGED) { - InvalidateRect(GetDlgItem(hwndDlg, IDC_EDIT), NULL, FALSE); - chatWindow->setFont((int) SendDlgItemMessage(hwndDlg, IDC_FONT, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONT, CB_GETCURSEL, 0, 0), 0), - (int) SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_GETCURSEL, 0, 0), 0), - IsDlgButtonChecked(hwndDlg, IDC_BOLD), - IsDlgButtonChecked(hwndDlg, IDC_ITALIC), - IsDlgButtonChecked(hwndDlg, IDC_UNDERLINE), - (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLOR, CPM_GETCOLOUR,0,0)); - } - break; - - } - break; - case WM_CTLCOLOREDIT: - if ((HWND) lParam == GetDlgItem(hwndDlg, IDC_EDIT)) { - SetTextColor((HDC) wParam, (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLOR, CPM_GETCOLOUR,0,0)); - SetBkColor((HDC) wParam, Options::getInputBgColor()); - //SelectObject((HDC) wParam, Options::getInputBgBrush()); - return (BOOL) Options::getInputBgBrush(); - } - - break; - case WM_NOTIFY: - LPNMHDR pNmhdr; - pNmhdr = (LPNMHDR)lParam; - if (pNmhdr->idFrom == IDC_TREELIST) { - switch (pNmhdr->code) { - case TVN_ITEMEXPANDING: - { - LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) lParam; - if (pnmtv->action==TVE_COLLAPSE) { - SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT, TRUE); - return TRUE; - } - } - break; - case NM_RCLICK: - { - TVHITTESTINFO hti; - hti.pt.x=(short)LOWORD(GetMessagePos()); - hti.pt.y=(short)HIWORD(GetMessagePos()); - ScreenToClient(pNmhdr->hwndFrom,&hti.pt); - if(TreeView_HitTest(pNmhdr->hwndFrom, &hti) && hti.flags&TVHT_ONITEM) { - TVITEM tvi = {0}; - tvi.mask = TVIF_PARAM|TVIF_HANDLE; - tvi.hItem = hti.hItem; - TreeView_GetItem(pNmhdr->hwndFrom, &tvi); - ChatUser *user = (ChatUser *) tvi.lParam; - if (user!=NULL) { - TreeView_Select(pNmhdr->hwndFrom, tvi.hItem, TVGN_CARET); - if (!user->isMe()) { - HMENU hMenu; - int iSelection; - hMenu = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(IDR_CHATOPTIONS)),1); - CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)hMenu,0); - if (chatWindow->getMe()!=NULL) { - if (chatWindow->getMe()->getFlags() & MUCC_EF_USER_OWNER) { - EnableMenuItem(hMenu, 2, MF_BYPOSITION | MF_ENABLED); - EnableMenuItem(hMenu, 3, MF_BYPOSITION | MF_ENABLED); - EnableMenuItem(hMenu, ID_USERMENU_ADMINISTRATION, MF_BYCOMMAND | MF_ENABLED); - - } else if (chatWindow->getMe()->getFlags() & MUCC_EF_USER_ADMIN) { - if (!(user->getFlags() & (MUCC_EF_USER_OWNER | MUCC_EF_USER_OWNER))) { - EnableMenuItem(hMenu, 2, MF_BYPOSITION | MF_ENABLED); - //EnableMenuItem(hMenu, 3, MF_BYPOSITION | MF_ENABLED); - EnableMenuItem(hMenu, ID_USERMENU_ADMINISTRATION, MF_BYCOMMAND | MF_ENABLED); - } - } - } - //CheckMenuItem(hMenu, ID_USERMENU_MESSAGE, MF_BYCOMMAND | MF_CHECKED : MF_UNCHECKED); - //EnableMenuItem(hMenu, ID_USERMENU_MESSAGE, MF_BYCOMMAND | MF_GRAYED); - iSelection = TrackPopupMenu(hMenu, TPM_RETURNCMD | TPM_TOPALIGN | TPM_LEFTALIGN, (short)LOWORD(GetMessagePos()), (short)HIWORD(GetMessagePos()), 0, hwndDlg, NULL); - DestroyMenu(hMenu); - if (iSelection == ID_USERMENU_MESSAGE) { - chatWindow->startPriv(); - } else if (iSelection >= ID_USERMENU_KICK_NO_BAN && iSelection <= ID_USERMENU_KICK_BAN_4_W) { - int banTime[] = {0, 1, 5, 15, 30, 60, 360, 1440, 4320, 10080, 20160, 40320}; - chatWindow->kickAndBan(banTime[iSelection-ID_USERMENU_KICK_NO_BAN] *60); - } else if (iSelection == ID_USERMENU_RIGHTS_MEMBER) { - chatWindow->setRights(MUCC_EF_USER_MEMBER); - } else if (iSelection == ID_USERMENU_RIGHTS_ADMIN) { - chatWindow->setRights(MUCC_EF_USER_ADMIN); - } else if (iSelection == ID_USERMENU_RIGHTS_NO) { - chatWindow->setRights(0); - } else if (iSelection == ID_USERMENU_ADMINISTRATION) { - chatWindow->startAdminDialog(ChatWindow::ADMIN_MODE_KICK); - } - } - } - } - - } - break; - case NM_CUSTOMDRAW: - LPNMTVCUSTOMDRAW pCustomDraw = (LPNMTVCUSTOMDRAW)lParam; - switch (pCustomDraw->nmcd.dwDrawStage) { - case CDDS_PREPAINT: - SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT,CDRF_NOTIFYITEMDRAW); - return TRUE; - case CDDS_ITEMPREPAINT: - { - TVITEM tvi;; - HICON hIcon; - TCHAR str[200]; - RECT rc = pCustomDraw->nmcd.rc; - tvi.mask = TVIF_HANDLE | TVIF_STATE | TVIF_TEXT | TVIF_PARAM; - tvi.pszText = str; - tvi.cchTextMax = sizeof(str)/sizeof(TCHAR); - tvi.hItem = (HTREEITEM)pCustomDraw->nmcd.dwItemSpec; - TreeView_GetItem(pCustomDraw->nmcd.hdr.hwndFrom, &tvi); - ChatUser * user= (ChatUser *)pCustomDraw->nmcd.lItemlParam; - hIcon = NULL; - pCustomDraw->clrTextBk = Options::getListBgColor(); - switch (pCustomDraw->iLevel) { - case 0: - pCustomDraw->clrText = ChatWindow::getListGroupTextColor(); - SelectObject(pCustomDraw->nmcd.hdc, ChatWindow::getListGroupFont()); - break; - case 1: - pCustomDraw->clrText = ChatWindow::getListTextColor(); - if (pCustomDraw->nmcd.uItemState & CDIS_SELECTED) { // selected (CDIS_FOCUS | - pCustomDraw->clrTextBk = 0xDAC8C2; - } else { - pCustomDraw->clrTextBk = Options::getListBgColor(); - } - if (user!=NULL) { - if (user->getFlags()&MUCC_EF_USER_GLOBALOWNER) { - hIcon = muccIcon[MUCC_IDI_U_GLOBALOWNER]; - } else if (user->getFlags()&MUCC_EF_USER_OWNER) { - hIcon = muccIcon[MUCC_IDI_U_OWNER]; - } else if (user->getFlags()&MUCC_EF_USER_ADMIN) { - hIcon = muccIcon[MUCC_IDI_U_ADMIN]; - } else if (user->getFlags()&MUCC_EF_USER_REGISTERED) { - hIcon = muccIcon[MUCC_IDI_U_REGISTERED]; - } - } - SelectObject(pCustomDraw->nmcd.hdc, ChatWindow::getListFont()); - break; - } - if (rc.bottom-rc.top!=0 && rc.right-rc.left!=0) { - HBRUSH hBr; - hBr = CreateSolidBrush(pCustomDraw->clrTextBk); - FillRect(pCustomDraw->nmcd.hdc, &rc, hBr); - DeleteObject(hBr); - if (hIcon!=NULL) { - DrawIconEx(pCustomDraw->nmcd.hdc, rc.left, rc.top, hIcon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL); - } - SetBkMode(pCustomDraw->nmcd.hdc, TRANSPARENT); - SetTextColor(pCustomDraw->nmcd.hdc, pCustomDraw->clrText); - TextOut(pCustomDraw->nmcd.hdc, - rc.left+pCustomDraw->iLevel*GetSystemMetrics(SM_CXSMICON)+2, - rc.top, tvi.pszText, (int)_tcslen(tvi.pszText)); - } - SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT, CDRF_SKIPDEFAULT ); - return TRUE; - } - } - break; - } - } else if (pNmhdr->idFrom == IDC_LOG) { - switch (((NMHDR *) lParam)->code) { - case EN_MSGFILTER: - switch (((MSGFILTER *) lParam)->msg) { - /* - case WM_LBUTTONDOWN: - { - HCURSOR hCur = GetCursor(); - if (hCur == LoadCursor(NULL, IDC_SIZENS) || hCur == LoadCursor(NULL, IDC_SIZEWE) - || hCur == LoadCursor(NULL, IDC_SIZENESW) || hCur == LoadCursor(NULL, IDC_SIZENWSE)) { - SetWindowLong(hwndDlg, DWL_MSGRESULT, TRUE); - return TRUE; - } - break; - } - case WM_MOUSEMOVE: - { - HCURSOR hCur = GetCursor(); - if (hCur == LoadCursor(NULL, IDC_SIZENS) || hCur == LoadCursor(NULL, IDC_SIZEWE) - || hCur == LoadCursor(NULL, IDC_SIZENESW) || hCur == LoadCursor(NULL, IDC_SIZENWSE)) - SetCursor(LoadCursor(NULL, IDC_ARROW)); - break; - } - */ - case WM_RBUTTONUP: - { - HMENU hMenu, hSubMenu; - POINT pt; - CHARRANGE sel, all = { 0, -1 }; - - hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXT)); - hSubMenu = GetSubMenu(hMenu, 0); - CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM) hSubMenu, 0); - SendMessage(((NMHDR *) lParam)->hwndFrom, EM_EXGETSEL, 0, (LPARAM) & sel); - if (sel.cpMin == sel.cpMax) - EnableMenuItem(hSubMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED); - pt.x = (short) LOWORD(((ENLINK *) lParam)->lParam); - pt.y = (short) HIWORD(((ENLINK *) lParam)->lParam); - ClientToScreen(((NMHDR *) lParam)->hwndFrom, &pt); - switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL)) { - case IDM_COPY: - SendMessage(((NMHDR *) lParam)->hwndFrom, WM_COPY, 0, 0); - break; - case IDM_COPYALL: - SendMessage(((NMHDR *) lParam)->hwndFrom, EM_EXSETSEL, 0, (LPARAM) & all); - SendMessage(((NMHDR *) lParam)->hwndFrom, WM_COPY, 0, 0); - SendMessage(((NMHDR *) lParam)->hwndFrom, EM_EXSETSEL, 0, (LPARAM) & sel); - break; - case IDM_SELECTALL: - SendMessage(((NMHDR *) lParam)->hwndFrom, EM_EXSETSEL, 0, (LPARAM) & all); - break; - case IDM_CLEAR: - chatWindow->clearLog(); - break; - } - DestroyMenu(hMenu); - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); - return TRUE; - } - } - break; - case EN_LINK: - switch (((ENLINK *) lParam)->msg) { - case WM_SETCURSOR: - SetCursor(hCurHyperlinkHand); - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); - return TRUE; - case WM_RBUTTONDOWN: - case WM_LBUTTONUP: - { - TEXTRANGEA tr; - CHARRANGE sel; - - SendDlgItemMessage(hwndDlg, IDC_LOG, EM_EXGETSEL, 0, (LPARAM) & sel); - if (sel.cpMin != sel.cpMax) - break; - tr.chrg = ((ENLINK *) lParam)->chrg; - tr.lpstrText = (char *)malloc(tr.chrg.cpMax - tr.chrg.cpMin + 8); - SendDlgItemMessageA(hwndDlg, IDC_LOG, EM_GETTEXTRANGE, 0, (LPARAM) & tr); - if (strchr(tr.lpstrText, '@') != NULL && strchr(tr.lpstrText, ':') == NULL && strchr(tr.lpstrText, '/') == NULL) { - MoveMemory(tr.lpstrText + 7, tr.lpstrText, tr.chrg.cpMax - tr.chrg.cpMin + 1); - CopyMemory(tr.lpstrText, "mailto:", 7); - } - if (((ENLINK *) lParam)->msg == WM_RBUTTONDOWN) { - HMENU hMenu, hSubMenu; - POINT pt; - - hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXT)); - hSubMenu = GetSubMenu(hMenu, 1); - CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM) hSubMenu, 0); - pt.x = (short) LOWORD(((ENLINK *) lParam)->lParam); - pt.y = (short) HIWORD(((ENLINK *) lParam)->lParam); - ClientToScreen(((NMHDR *) lParam)->hwndFrom, &pt); - switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL)) { - case IDM_OPENNEW: - CallService(MS_UTILS_OPENURL, 1, (LPARAM) tr.lpstrText); - break; - case IDM_OPENEXISTING: - CallService(MS_UTILS_OPENURL, 0, (LPARAM) tr.lpstrText); - break; - case IDM_COPYLINK: - { - HGLOBAL hData; - if (!OpenClipboard(hwndDlg)) - break; - EmptyClipboard(); - hData = GlobalAlloc(GMEM_MOVEABLE, lstrlenA(tr.lpstrText) + 1); - lstrcpyA((char *)GlobalLock(hData), tr.lpstrText); - GlobalUnlock(hData); - SetClipboardData(CF_TEXT, hData); - CloseClipboard(); - break; - } - } - free(tr.lpstrText); - DestroyMenu(hMenu); - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); - return TRUE; - } - else { - CallService(MS_UTILS_OPENURL, 1, (LPARAM) tr.lpstrText); - SetFocus(GetDlgItem(hwndDlg, IDC_EDIT)); - } - free(tr.lpstrText); - break; - } - } - break; - } - } - break; - } - return FALSE; -} - -static char *JabberRtfEscape(char *str) { - char *escapedStr; - int size; - char *p, *q; - - if (str == NULL) - return NULL; - - for (p=str,size=0; *p!='\0'; p++) { - if (*p=='\\' || *p=='{' || *p=='}') - size += 2; - else if (*p=='\n' || *p=='\t') - size += 5; - else - size++; - } - - if ((escapedStr=(char *)malloc(size+1)) == NULL) - return NULL; - - for (p=str,q=escapedStr; *p!='\0'; p++) { - if (strchr("\\{}", *p) != NULL) { - *q++ = '\\'; - *q++ = *p; - } - else if (*p == '\n') { - strcpy(q, "\\par "); - q += 5; - } - else if (*p == '\t') { - strcpy(q, "\\tab "); - q += 5; - } - else { - *q++ = *p; - } - } - *q = '\0'; - - return escapedStr; -} - -static void JabberStringAppend(char **str, int *sizeAlloced, const char *fmt, ...) { - va_list vararg; - char *p; - int size, len; - - if (str == NULL) return; - - if (*str==NULL || *sizeAlloced<=0) { - *sizeAlloced = size = 2048; - *str = (char *) malloc(size); - len = 0; - } - else { - len = (int)strlen(*str); - size = *sizeAlloced - (int)strlen(*str); - } - - p = *str + len; - va_start(vararg, fmt); - while (_vsnprintf(p, size, fmt, vararg) == -1) { - size += 2048; - (*sizeAlloced) += 2048; - *str = (char *) realloc(*str, *sizeAlloced); - p = *str + len; - } - va_end(vararg); -} - - -//static DWORD CALLBACK Log_StreamCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb) -//{ -// StreamData *stream = (StreamData *) dwCookie; -/* - if (lstrdat->buffer == NULL) - { - lstrdat->iColCount = 4; - lstrdat->bufferOffset = 0; - lstrdat->buffer = Log_CreateBody(lstrdat); - lstrdat->bufferLen = lstrlen(lstrdat->buffer); - } - *pcb = min(cb, lstrdat->bufferLen - lstrdat->bufferOffset); - CopyMemory(pbBuff, lstrdat->buffer + lstrdat->bufferOffset, *pcb); - lstrdat->bufferOffset += *pcb; - if (lstrdat->bufferOffset == lstrdat->bufferLen) - { - free(lstrdat->buffer); - lstrdat->buffer = NULL; - } -*/ -// return 0; -//} diff --git a/!NotAdopted/Tlen/tlen_czaty/ChatWindow.h b/!NotAdopted/Tlen/tlen_czaty/ChatWindow.h deleted file mode 100644 index 37b0b29d6e..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/ChatWindow.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -class ChatWindow; - -#ifndef CHATWINDOW_INCLUDED -#define CHATWINDOW_INCLUDED -#include "mucc.h" -#include "ChatEvent.h" -#include "ChatUser.h" -#include "AdminWindow.h" -#include "ChatContainer.h" - -#define DM_CHAT_EVENT (WM_USER+1) -#define DM_CHAT_QUERY (WM_USER+2) -#define WM_TLEN_SMILEY (WM_USER+200) - - -class StreamData { -public: - ChatWindow *chat; - MUCCEVENT *event; -}; - -class ChatWindow{ -private: - static ChatWindow * list; - static CRITICAL_SECTION mutex; - static bool released; - static HFONT hListGroupFont, hListFont; - static COLORREF colorListBg, colorListText, colorListGroupText; - static COLORREF colorInputBg, colorLogBg; - ChatContainer * container; - HANDLE hEvent; - HWND hWnd; - HWND hWndLog; - HFONT hEditFont; - HTREEITEM hUserGroups[5]; - char * module; - char * roomId; - char * roomName; - char * topic; - int options; - int roomFlags; - int font, fontSize; - int bBold, bItalic, bUnderline; - int wasFirstMessage; - bool isEmpty; - COLORREF fontColor; - int isStarted; - ChatWindow * prev; - ChatWindow * next; - int adminDialogMode; - AdminWindow * adminWindow; - ChatUser * users; - ChatUser * userMe; - void addUser(ChatUser *); - void removeUser(ChatUser *); - ChatUser * findUser(const char *); - int getUserGroup(ChatUser *); - ChatUser * getSelectedUser(); - ChatEventList eventList; - void createRTFHeader(); - int appendMessage(const MUCCEVENT *event); - int logMessage(const MUCCEVENT *event); -public: - enum LOGFLAGS { - FLAG_SHOW_NICKNAMES = 0x00000001, - FLAG_MSGINNEWLINE = 0x00000002, - FLAG_OPT_SENDONENTER= 0x00000004, - FLAG_OPT_ENABLEIEVIEW=0x00000008, - - FLAG_SHOW_DATE = 0x00000010, - FLAG_SHOW_TIMESTAMP = 0x00000020, - FLAG_SHOW_SECONDS = 0x00000040, - FLAG_LONG_DATE = 0x00000080, - - FLAG_FORMAT_FONT = 0x00000100, - FLAG_FORMAT_SIZE = 0x00000200, - FLAG_FORMAT_COLOR = 0x00000400, - FLAG_FORMAT_STYLE = 0x00000800, - FLAG_FORMAT_ALL = 0x00000F00, - - FLAG_LOG_MESSAGES = 0x00001000, - FLAG_LOG_JOINED = 0x00002000, - FLAG_LOG_LEFT = 0x00004000, - FLAG_LOG_TOPIC = 0x00008000, - FLAG_LOG_ALL = 0x0000F000, - - FLAG_FLASH_MESSAGES = 0x00010000, - FLAG_FLASH_JOINED = 0x00020000, - FLAG_FLASH_LEFT = 0x00040000, - FLAG_FLASH_TOPIC = 0x00080000, - FLAG_FLASH_ALL = 0x000F0000, - - - }; - - enum ADMINMODES { - ADMIN_MODE_KICK = 1, - ADMIN_MODE_ROLE = 2, - ADMIN_MODE_BROWSER = 3 - }; - int hSplitterPos; - int vSplitterPos; - int hSplitterMinBottom; - int hSplitterMinTop; - int vSplitterMinLeft; - int vSplitterMinRight; - ChatWindow (MUCCWINDOW *); - ~ChatWindow (); - ChatWindow * getNext(); - void setNext(ChatWindow *); - ChatWindow * getPrev(); - ChatContainer* getContainer(); - void setPrev(ChatWindow *); - void setHWND(HWND); - HWND getHWND(); - void setHWNDLog(HWND); - HWND getHWNDLog(); - HANDLE getEvent(); - const char * getModule(); - void setModule(const char *); - const char * getRoomId(); - void setRoomId(const char *); - const char * getRoomName(); - void setRoomName(const char *); - void setOptions(int); - int getOptions(); - void setRoomFlags(int); - int getRoomFlags(); - int getFontSizeNum(); - int getFontSize(int); - int getFontNameNum(); - const char * getFontName(int); - void setFont(int font, int size, int bBold, int bItalic, int bUnderline, COLORREF color); - int getFont(); - int getFontSize(); - int getFontStyle(); - COLORREF getFontColor(); - int start(); - int startPriv(); - void startAdminDialog(int mode); - int kickAndBan(int time); - int kickAndBan(const char *id, int time, const char *); - int unban(const char *id); - int setRights(int flags); - int setRights(const char *id, int flags); - void queryResultContacts(MUCCQUERYRESULT *queryResult); - void queryResultUsers(MUCCQUERYRESULT *queryResult); - void setTreeItem(int, HTREEITEM); - HTREEITEM getTreeItem(int); - ChatUser * findUserByNick(const char *); - ChatUser * getMe(); - void refreshSettings(); - void setAdminWindow(AdminWindow *); - AdminWindow * getAdminWindow(); - void rebuildLog(); - void clearLog(); - int logEvent(const MUCCEVENT *event); - int changePresence(const MUCCEVENT *event); - int changeTopic(const MUCCEVENT *event); - int changeRoomInfo(const MUCCEVENT *event); - int leave(); - - static void refreshSettings(int force); - static HFONT getListGroupFont(); - static HFONT getListFont(); - static COLORREF getListTextColor(); - static COLORREF getListGroupTextColor(); - static int getDefaultOptions(); - - static void init(); - static void release(); - static ChatWindow * getWindow(const char *module, const char *roomId); - -}; -#endif diff --git a/!NotAdopted/Tlen/tlen_czaty/FontList.cpp b/!NotAdopted/Tlen/tlen_czaty/FontList.cpp deleted file mode 100644 index 4d57617013..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/FontList.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#include "FontList.h" -#include "Utils.h" - -#define FONTCOUNT 12 -static Font defFonts[] = { - Font("Timestamp","Verdana", DEFAULT_CHARSET, -9, Font::BOLD, 0x000000), -// Font("Colon","Verdana", DEFAULT_CHARSET, -13, 0, 0x808080), - Font("Others names","Verdana", DEFAULT_CHARSET, -13, 0, 0x723732), - Font("Your name","Verdana", DEFAULT_CHARSET, -13, 0, 0x4453A4), - Font("Incoming message","Verdana", DEFAULT_CHARSET, -13, 0, 0x000000), - Font("Outgoing message","Verdana", DEFAULT_CHARSET, -13, 0, 0x505080), - Font("User has joined","Verdana", DEFAULT_CHARSET, -11, Font::ITALIC, 0x0F880F), - Font("User has left","Verdana", DEFAULT_CHARSET, -11, Font::ITALIC, 0x1313B9), - Font("The topic is ...","Verdana", DEFAULT_CHARSET, -13, Font::ITALIC, 0x991A53), - Font("Error","Verdana", DEFAULT_CHARSET, -13, Font::BOLD, 0x1010D0), - Font("Message typing area","Verdana", DEFAULT_CHARSET, -13, 0, 0x000000), - Font("User list","Tahoma", DEFAULT_CHARSET, -11, 0, 0x000000), - Font("User list group","Tahoma", DEFAULT_CHARSET, -11, Font::BOLD, 0x000000) - -}; - -Font::Font() { - name = NULL; - face = NULL; - size = 0; - style = 0; - color = 0; - charSet = DEFAULT_CHARSET; -} - -Font::Font(const char *n, const char *f, int cs, int s, int st, COLORREF c) { - name = NULL; - face = NULL; - size = 0; - style = 0; - color = 0; - setName(n); - setFace(f); - setCharSet(cs); - setSize(s); - setStyle(st); - setColor(c); -} - - -COLORREF Font::getColor() { - return color; -} - -void Font::setColor(COLORREF c) { - color = c; -} - -int Font::getSize() { - return size; -} - -void Font::setSize(int s) { - size = s; -} - -int Font::getStyle() { - return style; -} - -void Font::setStyle(int s) { - style = s; -} - -int Font::getCharSet() { - return charSet; -} - -void Font::setCharSet(int s) { - charSet = s; -} - -void Font::setName(const char *s) { - Utils::copyString(&name, s); -} - -const char *Font::getName() { - return name; -} - -void Font::setFace(const char *s) { - Utils::copyString(&face, s); -} - -const char *Font::getFace() { - return face; -} - -Font *FontList::fonts = NULL; -Font *FontList::fontsSettings = NULL; - -Font *FontList::getFont(int index) { - if (index < FONTCOUNT) return &fonts[index]; - else return NULL; -} - -Font *FontList::getFontSettings(int index) { - if (index < FONTCOUNT) return &fontsSettings[index]; - else return NULL; -} - -void FontList::loadSettings() { - char fontParam[512]; - for (int i=0;iid = NULL; - this->name = NULL; - next = NULL; - Utils::copyString(&this->id, id); - Utils::copyString(&this->name, name); -} -HelperDialog::HelperContact::~HelperContact() { - if (id != NULL) delete id; - if (name != NULL) delete name; -} - -void HelperDialog::HelperContact::setNext(HelperContact *next) { - this->next = next; -} - -const char *HelperDialog::HelperContact::getId() { - return id; -} - -const char *HelperDialog::HelperContact::getName() { - return name; -} - -HelperDialog::HelperContact* HelperDialog::HelperContact::getNext() { - return next; -} - -void HelperDialog::init() { - InitializeCriticalSection(&mutex); -} - -void HelperDialog::release() { - while (list!=NULL) { - delete list; - } - DeleteCriticalSection(&mutex); -} - -HelperDialog::HelperDialog() { - module = nick = reason = roomId = roomName = NULL; - prev = next = NULL; - contactList = NULL; - hWnd = NULL; - hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - EnterCriticalSection(&mutex); - setNext(list); - if (next!=NULL) { - next->setPrev(this); - } - list = this; - LeaveCriticalSection(&mutex); -} - -HelperDialog::HelperDialog(ChatWindow *chat) { - module = nick = reason = roomId = roomName = NULL; - prev = next = NULL; - contactList = NULL; - hWnd = NULL; - hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - setModule(chat->getModule()); - setRoomId(chat->getRoomId()); - setRoomName(chat->getRoomName()); - setRoomFlags(chat->getRoomFlags()); - EnterCriticalSection(&mutex); - setNext(list); - if (next!=NULL) { - next->setPrev(this); - } - list = this; - LeaveCriticalSection(&mutex); -} - -HelperDialog::~HelperDialog() -{ - EnterCriticalSection(&mutex); - if (getPrev()!=NULL) { - getPrev()->setNext(next); - } else { - list = getNext(); - } - if (getNext()!=NULL) { - getNext()->setPrev(prev); - } - LeaveCriticalSection(&mutex); - if (hEvent!=NULL) CloseHandle(hEvent); - if (module!=NULL) delete module; - if (roomId!=NULL) delete roomId; - if (roomName!=NULL) delete roomName; - if (nick!=NULL) delete nick; - if (reason!=NULL) delete reason; - for (HelperContact *ptr2, *ptr=contactList;ptr!=NULL;ptr=ptr2) { - ptr2 = ptr->getNext(); - delete ptr; - } -} -void HelperDialog::setHWND(HWND hWnd) { - this->hWnd = hWnd; -} -HWND HelperDialog::getHWND() { - return hWnd; -} -void HelperDialog::setPrev(HelperDialog *prev) { - this->prev = prev; -} -void HelperDialog::setNext(HelperDialog *next) { - this->next = next; -} -HelperDialog * HelperDialog::getPrev() { - return prev; -} -HelperDialog * HelperDialog::getNext() { - return next; -} -const char *HelperDialog::getModule() -{ - return module; -} -const char *HelperDialog::getRoomId() -{ - return roomId; -} -const char *HelperDialog::getRoomName() -{ - return roomName; -} -const char *HelperDialog::getNick() -{ - return nick; -} -const char *HelperDialog::getReason() -{ - return reason; -} -void HelperDialog::setModule(const char *module) -{ - Utils::copyString(&this->module, module); -} -void HelperDialog::setRoomId(const char *roomId) -{ - Utils::copyString(&this->roomId, roomId); -} -void HelperDialog::setRoomName(const char *roomName) -{ - Utils::copyString(&this->roomName, roomName); -} -void HelperDialog::setNick(const char *nick) -{ - Utils::copyString(&this->nick, nick); -} -void HelperDialog::setReason(const char *reason) -{ - Utils::copyString(&this->reason, reason); -} -void HelperDialog::setRoomFlags(DWORD flags) -{ - this->roomFlags = flags; -} -void HelperDialog::setContactList(MUCCQUERYRESULT *queryResult) { - HelperContact *ptr, *lastptr; - for (ptr=contactList;ptr!=NULL;ptr=ptr->getNext()) { - delete ptr; - } - contactList = NULL; - lastptr = NULL; - for (int i=0;iiItemsNum;i++) { - ptr = new HelperContact(queryResult->pItems[i].pszID, queryResult->pItems[i].pszName); - if (lastptr != NULL) { - lastptr->setNext(ptr); - } else { - contactList = ptr; - } - lastptr = ptr; - } -} - -HelperDialog::HelperContact * HelperDialog::getContactList() { - return contactList; -} - -DWORD HelperDialog::getRoomFlags() { - return roomFlags; -} - -void HelperDialog::inviteDlg(ChatWindow *chat, MUCCQUERYRESULT *queryResult) { - HelperDialog *dialog=new HelperDialog(chat); - dialog->setContactList(queryResult); - Utils::forkThread((void (__cdecl *)(void *))InviteDlgThread, 0, (void *) dialog); - //WaitForSingleObject(dialog->getEvent(), INFINITE); -} - -void HelperDialog::acceptDlg(MUCCEVENT *event) { - HelperDialog *dialog=new HelperDialog(); - dialog->setModule(event->pszModule); - dialog->setRoomId(event->pszID); - dialog->setRoomName(event->pszName); - dialog->setRoomFlags(event->dwFlags); - dialog->setNick(event->pszNick); - // dialog->setReason(event->pszText); - Utils::forkThread((void (__cdecl *)(void *))AcceptInvitationDlgThread, 0, (void *) dialog); -// WaitForSingleObject(hEvent, INFINITE); -} - -void HelperDialog::joinDlg(MUCCEVENT *event) { - HelperDialog *dialog=new HelperDialog(); - dialog->setModule(event->pszModule); - dialog->setRoomId(event->pszID); - dialog->setRoomName(event->pszName); - dialog->setRoomFlags(event->dwFlags); - dialog->setNick(event->pszNick); - Utils::forkThread((void (__cdecl *)(void *))JoinDlgThread, 0, (void *) dialog); - //WaitForSingleObject(dialog->getEvent(), INFINITE); -} - -void HelperDialog::errorDlg(MUCCEVENT *event) { - HelperDialog *dialog=new HelperDialog(); - dialog->setReason(event->pszText); - Utils::forkThread((void (__cdecl *)(void *))ErrorDlgThread, 0, (void *) dialog); - //WaitForSingleObject(dialog->getEvent(), INFINITE); -} - -void HelperDialog::topicDlg(ChatWindow *chat) -{ - HelperDialog *dialog=new HelperDialog(); - dialog->setModule(chat->getModule()); - dialog->setRoomId(chat->getRoomId()); - Utils::forkThread((void (__cdecl *)(void *))TopicDlgThread, 0, (void *) dialog); -} - -static void __cdecl InviteDlgThread(void *vDialog) -{ - DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HELPER_INVITE), NULL, InviteDlgProc, (LPARAM) vDialog); -} - -static void __cdecl AcceptInvitationDlgThread(void *vDialog) -{ - DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HELPER_INVITE_ACCEPT), NULL, AcceptInvitationDlgProc, (LPARAM) vDialog); -} - -static void __cdecl JoinDlgThread(void *vDialog) -{ - DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HELPER_JOIN), NULL, JoinDlgProc, (LPARAM) vDialog); -} - -static void __cdecl TopicDlgThread(void *vDialog) -{ - DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HELPER_TOPIC), NULL, TopicDlgProc, (LPARAM) vDialog); -} - -static INT_PTR CALLBACK InviteDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - char str[256]; - HelperDialog::HelperContact *contactList; - HelperDialog *dialog = (HelperDialog *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - dialog = (HelperDialog *) lParam; - TranslateDialogDefault(hwndDlg); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) dialog); - dialog->setHWND(hwndDlg); - SendDlgItemMessage(hwndDlg, IDC_REASON, EM_SETREADONLY, (WPARAM)TRUE, 0); - for (contactList = dialog->getContactList();contactList!=NULL;contactList=contactList->getNext()) { - SendDlgItemMessage(hwndDlg, IDC_USER, CB_ADDSTRING, 0, (LPARAM)contactList->getName()); - } - return TRUE; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_INVITE: - MUCCEVENT muce; - GetDlgItemTextA(hwndDlg, IDC_USER, str, 255); - if (strlen(str)>0) { - for (contactList = dialog->getContactList();contactList!=NULL;contactList=contactList->getNext()) { - if (!strcmp(str, contactList->getName())) { - dialog->setNick(contactList->getId()); - break; - } - } - if (contactList==NULL) { - dialog->setNick(str); - } - } - muce.iType = MUCC_EVENT_INVITE; - muce.pszModule = dialog->getModule(); - muce.pszID = dialog->getRoomId(); - muce.pszNick = dialog->getNick(); - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - case IDCANCEL: - case IDCLOSE: - EndDialog(hwndDlg, 0); - return TRUE; - } - break; - case WM_CLOSE: - EndDialog(hwndDlg, 0); - break; - case WM_DESTROY: - delete dialog; - break; - } - return FALSE; -} - - - - -static INT_PTR CALLBACK AcceptInvitationDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - char str[256]; - HelperDialog *dialog; - dialog = (HelperDialog *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - { - dialog = (HelperDialog *) lParam; - TranslateDialogDefault(hwndDlg); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) dialog); - dialog->setHWND(hwndDlg); - if (dialog->getNick() != NULL) { - SetDlgItemTextA(hwndDlg, IDC_FROM, dialog->getNick()); - } - if (dialog->getRoomName() != NULL) { - SetDlgItemTextA(hwndDlg, IDC_ROOM, dialog->getRoomName()); - } - if (dialog->getReason() != NULL) { - SetDlgItemTextA(hwndDlg, IDC_REASON, dialog->getReason()); - } - -// if (!DBGetContactSetting(NULL, jabberProtoName, "LoginName", &dbv)) { -// SetDlgItemText(hwndDlg, IDC_NICK, dbv.pszVal); -// DBFreeVariant(&dbv); -// } - - /* - SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) LoadIcon(hInst, MAKEINTRESOURCE(IDI_GROUP))); -*/ - } - return TRUE; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_ACCEPT: - GetDlgItemTextA(hwndDlg, IDC_NICK, str, 255); - dialog->setNick(str); - MUCCEVENT muce; - muce.iType = MUCC_EVENT_JOIN; - muce.pszModule = dialog->getModule(); - muce.pszID = dialog->getRoomId(); - muce.pszName = dialog->getRoomName(); - muce.dwFlags = dialog->getRoomFlags(); - muce.pszNick = NULL; - if (strlen(dialog->getNick())>0) { - muce.pszNick = dialog->getNick(); - } else { - muce.pszNick = NULL; - } - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - case IDCANCEL: - case IDCLOSE: - EndDialog(hwndDlg, 0); - return TRUE; - } - break; - case WM_CLOSE: - EndDialog(hwndDlg, 0); - break; - case WM_DESTROY: - delete dialog; - break; - } - - return FALSE; -} - - -static INT_PTR CALLBACK JoinDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - char str[256]; - HelperDialog *dialog; - dialog = (HelperDialog *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - dialog = (HelperDialog *) lParam; - TranslateDialogDefault(hwndDlg); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) dialog); - dialog->setHWND(hwndDlg); - SetFocus(GetDlgItem(hwndDlg, IDOK)); - if (dialog->getRoomFlags() & MUCC_EF_ROOM_NAME) { - SetFocus(GetDlgItem(hwndDlg, IDC_ROOM)); - } else { - SendDlgItemMessage(hwndDlg, IDC_ROOM, EM_SETREADONLY, (WPARAM)TRUE, 0); - } - if (dialog->getRoomFlags() & MUCC_EF_ROOM_NICKNAMES) { - SetFocus(GetDlgItem(hwndDlg, IDC_NICK)); - } else { - SendDlgItemMessage(hwndDlg, IDC_NICK, EM_SETREADONLY, (WPARAM)TRUE, 0); - } - if (dialog->getRoomName()!=NULL) { - SetDlgItemTextA(hwndDlg, IDC_ROOM, dialog->getRoomName()); - } - if (dialog->getNick()!=NULL) { - SetDlgItemTextA(hwndDlg, IDC_NICK, dialog->getNick()); - } - return FALSE; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - MUCCEVENT muce; - if (dialog->getRoomId()==NULL) { - GetDlgItemTextA(hwndDlg, IDC_ROOM, str, 255); - if (strlen(str)>0) { - //dialog->setRoomId(str); - dialog->setRoomName(str); - } - } - GetDlgItemTextA(hwndDlg, IDC_NICK, str, 255); - if (strlen(str)>0) { - dialog->setNick(str); - } else { - dialog->setNick(NULL); - } - muce.iType = MUCC_EVENT_JOIN; - muce.pszModule = dialog->getModule(); - muce.pszID = dialog->getRoomId(); - muce.pszName = dialog->getRoomName(); - muce.pszNick = dialog->getNick(); - muce.dwFlags = dialog->getRoomFlags(); - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - case IDCANCEL: - EndDialog(hwndDlg, 0); - return TRUE; - } - break; - case WM_CLOSE: - EndDialog(hwndDlg, 0); - break; - case WM_DESTROY: - delete dialog; - break; - } - return FALSE; -} - -static void __cdecl ErrorDlgThread(void *vDialog) -{ - HelperDialog *dialog=(HelperDialog *)vDialog; - MessageBoxA(NULL, dialog->getReason(), Translate("Error"), MB_OK | MB_ICONERROR); - /* - int result = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_GROUPCHAT_JOIN), NULL, JoinDlgProc, (LPARAM) dialog); - if (result!=0) { - MUCCEVENT muce; - muce.iType = MUCC_EVENT_JOIN; - muce.pszModule = dialog->getModule(); - muce.pszID = dialog->getRoomId(); - muce.pszName = dialog->getRoomName(); - muce.pszNick = dialog->getNick(); - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - } - */ - delete dialog; -} - -/* -static INT_PTR CALLBACK ErrorDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - char str[256]; - HelperDialog *dialog; - dialog = (HelperDialog *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - dialog = (HelperDialog *) lParam; - TranslateDialogDefault(hwndDlg); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) dialog); - dialog->setHWND(hwndDlg); - SetFocus(GetDlgItem(hwndDlg, IDOK)); - if (dialog->getRoomName()!=NULL) { - SetDlgItemTextA(hwndDlg, IDC_ROOM, dialog->getRoomName()); - } - if (dialog->getNick()!=NULL) { - SetDlgItemTextA(hwndDlg, IDC_NICK, dialog->getNick()); - } - return FALSE; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - if (dialog->getRoomId()==NULL) { - GetDlgItemTextA(hwndDlg, IDC_ROOM, str, 255); - if (strlen(str)>0) { - //dialog->setRoomId(str); - dialog->setRoomName(str); - } - } - GetDlgItemTextA(hwndDlg, IDC_NICK, str, 255); - if (strlen(str)>0) { - dialog->setNick(str); - } else { - dialog->setNick(NULL); - } - case IDCANCEL: - EndDialog(hwndDlg, 0); - return TRUE; - } - break; - case WM_CLOSE: - EndDialog(hwndDlg, 0); - break; - case WM_DESTROY: - delete dialog; - break; - } - return FALSE; -} -*/ - -static INT_PTR CALLBACK TopicDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - char str[256]; - HelperDialog *dialog; - dialog = (HelperDialog *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - dialog = (HelperDialog *) lParam; - TranslateDialogDefault(hwndDlg); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) dialog); - dialog->setHWND(hwndDlg); - return FALSE; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - MUCCEVENT muce; - GetDlgItemTextA(hwndDlg, IDC_TOPIC, str, 255); - dialog->setReason(str); - muce.cbSize = sizeof(MUCCEVENT); - muce.iType = MUCC_EVENT_TOPIC; - muce.pszID = dialog->getRoomId(); - muce.pszModule = dialog->getModule(); - muce.pszText = dialog->getReason(); - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - case IDCANCEL: - EndDialog(hwndDlg, 0); - return TRUE; - } - break; - case WM_CLOSE: - EndDialog(hwndDlg, 0); - break; - case WM_DESTROY: - delete dialog; - break; - } - return FALSE; -} - diff --git a/!NotAdopted/Tlen/tlen_czaty/HelperDialog.h b/!NotAdopted/Tlen/tlen_czaty/HelperDialog.h deleted file mode 100644 index 08f856c3a9..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/HelperDialog.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#ifndef DIALOGS_INCLUDED -#define DIALOGS_INCLUDED - -#include "mucc.h" -#include "m_mucc.h" -#include "ChatWindow.h" - - -class HelperDialog { -public: - class HelperContact { - private: - char *id; - char *name; - HelperContact *next; - public: - HelperContact(const char *id, const char *name); - ~HelperContact(); - void setNext(HelperContact *); - HelperContact* getNext(); - const char * getId(); - const char * getName(); - }; - -private: - static HelperDialog * list; - static CRITICAL_SECTION mutex; - char * module; - char * roomId; - char * roomName; - DWORD roomFlags; - HelperContact * contactList; - HelperDialog * prev; - HelperDialog * next; - char * nick; - char * reason; - HANDLE hEvent; - HWND hWnd; -public: - HelperDialog(); - HelperDialog(ChatWindow *); - ~HelperDialog(); - void setModule(const char *); - void setRoomId(const char *); - void setRoomName(const char *); - void setRoomFlags(DWORD); - void setNick(const char *); - void setReason(const char *); - void setPrev(HelperDialog *); - HelperDialog* getPrev(); - void setNext(HelperDialog *); - HelperDialog* getNext(); - HWND getHWND(); - void setHWND(HWND hWnd); - void setContactList(MUCCQUERYRESULT *queryResult); - HelperContact* getContactList(); - const char * getModule(); - const char * getRoomId(); - const char * getRoomName(); - DWORD getRoomFlags(); - const char * getNick(); - const char * getReason(); - HANDLE getEvent(); - static void init(); - static void release(); - static void inviteDlg(ChatWindow *chat, MUCCQUERYRESULT *queryResult); - static void acceptDlg(MUCCEVENT *event); - static void joinDlg(MUCCEVENT *event); - static void errorDlg(MUCCEVENT *event); - static void topicDlg(ChatWindow *chat); -}; - - - -#endif diff --git a/!NotAdopted/Tlen/tlen_czaty/ManagerWindow.cpp b/!NotAdopted/Tlen/tlen_czaty/ManagerWindow.cpp deleted file mode 100644 index a01caebc15..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/ManagerWindow.cpp +++ /dev/null @@ -1,1067 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#include "ManagerWindow.h" -#include "Utils.h" -#include "HelperDialog.h" - -static INT_PTR CALLBACK ManagerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -static INT_PTR CALLBACK ChatRoomsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -static INT_PTR CALLBACK MyRoomsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -ManagerWindow * ManagerWindow::list = NULL; -bool ManagerWindow::released = false; -CRITICAL_SECTION ManagerWindow::mutex; - -void ManagerWindow::init() { - released = false; - InitializeCriticalSection(&mutex); -} - -void ManagerWindow::release() { - released = true; - for (ManagerWindow *ptr2, *ptr = list; ptr!=NULL; ptr=ptr2) { - ptr2 = ptr->getNext(); - delete ptr; -// SendMessage(ptr->getHWND(), WM_CLOSE, 0, 0); - } - DeleteCriticalSection(&mutex); -} - -ManagerWindow::ManagerWindow(const char *module) -{ - next = prev = NULL; - groups = NULL; - rooms = NULL; - myRooms = NULL; - currentGroup = NULL; - isStarted = 0; - currentTab = 0; - currentRoomsPage = 0; - lastRoomsPage = 0; - userNickList = userRoomList = 0; - this->module = NULL; - this->moduleName = NULL; - Utils::copyString(&this->module, module); - hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - EnterCriticalSection(&mutex); - setNext(list); - if (next!=NULL) { - next->setPrev(this); - } - list = this; - LeaveCriticalSection(&mutex); -} - -ManagerWindow::~ManagerWindow() -{ - if (!released) { - EnterCriticalSection(&mutex); - if (getPrev()!=NULL) { - getPrev()->setNext(next); - } else { - list = getNext(); - } - if (getNext()!=NULL) { - getNext()->setPrev(prev); - } - LeaveCriticalSection(&mutex); - } - if (hWnd!=NULL) { - EndDialog(hWnd, 0); - } - if (hEvent!=NULL) { - CloseHandle(hEvent); - } - while (groups!=NULL) { - ChatGroup *group = groups; - groups = groups->getListNext(); - delete group; - } - while (rooms!=NULL) { - ChatRoom *room = rooms; - rooms = rooms->getNext(); - delete room; - } - while (myRooms!=NULL) { - ChatRoom *room = myRooms; - myRooms = myRooms->getNext(); - delete room; - } - if (module!=NULL) { - delete module; - } - if (moduleName!=NULL) { - delete moduleName; - } -} -void ManagerWindow::setPrev(ManagerWindow *prev) -{ - this->prev = prev; -} -ManagerWindow * ManagerWindow::getPrev() -{ - return prev; -} -void ManagerWindow::setNext(ManagerWindow *next) -{ - this->next = next; -} -ManagerWindow * ManagerWindow::getNext() -{ - return next; -} -void ManagerWindow::setHWND(HWND h) -{ - hWnd=h; -} -HWND ManagerWindow::getHWND() -{ - return hWnd; -} -void ManagerWindow::setChatRoomsTabHWND(HWND h) -{ - hChatRoomsTabWnd=h; -} -HWND ManagerWindow::getChatRoomsTabHWND() -{ - return hChatRoomsTabWnd; -} -void ManagerWindow::setMyRoomsTabHWND(HWND h) -{ - hMyRoomsTabWnd=h; -} -HWND ManagerWindow::getMyRoomsTabHWND() -{ - return hMyRoomsTabWnd; -} -void ManagerWindow::setMyNicksTabHWND(HWND h) -{ - hMyNicksTabWnd=h; -} -HWND ManagerWindow::getMyNicksTabHWND() -{ - return hMyNicksTabWnd; -} -const char *ManagerWindow::getModule() -{ - return module; -} -const char *ManagerWindow::getModuleName() -{ - return moduleName; -} -void ManagerWindow::setModuleName(const char *moduleName) -{ - Utils::copyString(&this->moduleName, moduleName); -} -ChatGroup *ManagerWindow::getCurrentGroup() -{ - return currentGroup; -} -void ManagerWindow::setCurrentGroup(ChatGroup *group) -{ - currentGroup = group; -} -HANDLE ManagerWindow::getEvent() -{ - return hEvent; -} -int ManagerWindow::getCurrentTab() -{ - return currentTab; -} -void ManagerWindow::setCurrentRoomsPage(int currentRoomsPage) -{ - this->currentRoomsPage = currentRoomsPage; -} -int ManagerWindow::getCurrentRoomsPage() -{ - return currentRoomsPage; -} -void ManagerWindow::setCurrentTab(int currentTab) -{ - this->currentTab = currentTab; -} -void ManagerWindow::setLastRoomsPage(int lastRoomsPage) -{ - this->lastRoomsPage = lastRoomsPage; -} -int ManagerWindow::isLastRoomsPage() -{ - return lastRoomsPage; -} -int ManagerWindow::isUserNickListReceived() -{ - return userNickList; -} -int ManagerWindow::isUserRoomListReceived() -{ - return userRoomList; -} -static void __cdecl StartThread(void *vManager) -{ - OleInitialize(NULL); - DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_CHATMANAGER), NULL, ManagerDlgProc, (LPARAM) vManager); - OleUninitialize(); -} -int ManagerWindow::start() -{ - if (isStarted) { - ShowWindow(hWnd, SW_SHOW); - return 0; - } - isStarted = 1; - Utils::forkThread((void (__cdecl *)(void *))StartThread, 0, (void *) this); - WaitForSingleObject(hEvent, INFINITE); - return 0; -} -void ManagerWindow::queryResultGroups(MUCCQUERYRESULT *queryResult) -{ - TVINSERTSTRUCT tvis; - ChatGroup * par = NULL; - ChatGroup * group; - if (queryResult->pszParent != NULL) { - par = findGroup(queryResult->pszParent); - if (par!=NULL) { - if (par->getChild()!=NULL) return; - } - } - for (int i=0; iiItemsNum; i++) { - group = new ChatGroup(); - group->setId(queryResult->pItems[i].pszID); - group->setName(queryResult->pItems[i].pszName); - if (par!=NULL) { - par->addChild(group); - //group->setParent(par); - tvis.hParent = par->getTreeItem(); - } else { - tvis.hParent = NULL; - } - tvis.hInsertAfter = TVI_SORT; - tvis.item.mask = TVIF_TEXT | TVIF_CHILDREN | TVIF_PARAM; - LPTSTR lps1 = Utils::mucc_mir_a2t(queryResult->pItems[i].pszName); - tvis.item.pszText = lps1; - tvis.item.cChildren = queryResult->pItems[i].iCount; - tvis.item.lParam = (LPARAM) group; - group->setTreeItem(TreeView_InsertItem(GetDlgItem(hWnd, IDC_GROUP), &tvis)); - group->setListNext(groups); - groups = group; - if (par != NULL) { - TreeView_Expand(GetDlgItem(hWnd, IDC_GROUP), par->getTreeItem(), TVE_EXPAND); - } - Utils::mucc_mir_free(lps1); - } -} - -void ManagerWindow::queryResultRooms(MUCCQUERYRESULT *queryResult) -{ - ChatRoom *room; - while (rooms!=NULL) { - room = rooms; - rooms = rooms->getNext(); - delete room; - } - TCHAR str[100]; - if (getCurrentGroup()==NULL || strcmp(getCurrentGroup()->getId(), queryResult->pszParent) || queryResult->iPage!=getCurrentRoomsPage()) return; - setLastRoomsPage(queryResult->iLastPage); - if (queryResult->iLastPage) { - EnableWindow(GetDlgItem(getChatRoomsTabHWND(), IDC_NEXT), FALSE); - } else { - EnableWindow(GetDlgItem(getChatRoomsTabHWND(), IDC_NEXT), TRUE); - } - if (queryResult->iPage>0) { - EnableWindow(GetDlgItem(getChatRoomsTabHWND(), IDC_PREV), TRUE); - } else { - EnableWindow(GetDlgItem(getChatRoomsTabHWND(), IDC_PREV), FALSE); - } - for (int i=0; iiItemsNum; i++) { - LVITEM lvItem; - room = new ChatRoom(); - room->setId(queryResult->pItems[i].pszID); - room->setName(queryResult->pItems[i].pszName); - room->setFlags(queryResult->pItems[i].dwFlags); - room->setNext(rooms); - rooms=room; - lvItem.mask = LVIF_TEXT | LVIF_PARAM; - lvItem.iSubItem = 0; - lvItem.iItem = ListView_GetItemCount(GetDlgItem(getChatRoomsTabHWND(), IDC_ROOM)); - LPTSTR lps1 = Utils::mucc_mir_a2t(queryResult->pItems[i].pszName); - lvItem.pszText = lps1; - lvItem.lParam = (LPARAM) room; - ListView_InsertItem(GetDlgItem(getChatRoomsTabHWND(), IDC_ROOM), &lvItem); - lvItem.iSubItem = 1; - ListView_InsertItem(GetDlgItem(getChatRoomsTabHWND(), IDC_ROOM), &lvItem); - _stprintf(str, _TEXT("%d"), queryResult->pItems[i].iCount); - ListView_SetItemText(GetDlgItem(getChatRoomsTabHWND(), IDC_ROOM), lvItem.iItem, 1, str); - Utils::mucc_mir_free(lps1); - } -} - -void ManagerWindow::queryResultUserRooms(MUCCQUERYRESULT *queryResult) -{ - ChatRoom *room; - ListView_DeleteAllItems(GetDlgItem(getMyRoomsTabHWND(), IDC_LIST)); - while (myRooms!=NULL) { - room = myRooms; - myRooms = myRooms->getNext(); - delete room; - } - for (int i=0; iiItemsNum; i++) { - LVITEM lvItem; - room = new ChatRoom(); - room->setId(queryResult->pItems[i].pszID); - room->setName(queryResult->pItems[i].pszName); - room->setNext(myRooms); - myRooms=room; - lvItem.mask = LVIF_TEXT | LVIF_PARAM; - lvItem.iSubItem = 0; - lvItem.iItem = ListView_GetItemCount(GetDlgItem(getMyRoomsTabHWND(), IDC_LIST)); - LPTSTR lps1 = Utils::mucc_mir_a2t(queryResult->pItems[i].pszName); - lvItem.pszText = lps1; - lvItem.lParam = (LPARAM) room; - ListView_InsertItem(GetDlgItem(getMyRoomsTabHWND(), IDC_LIST), &lvItem); - Utils::mucc_mir_free(lps1); - } - userRoomList = 1; -} - -void ManagerWindow::queryResultUserNick(MUCCQUERYRESULT *queryResult) -{ - ListView_DeleteAllItems(GetDlgItem(getMyNicksTabHWND(), IDC_LIST)); - for (int i=0; iiItemsNum; i++) { - LVITEM lvItem; - lvItem.mask = LVIF_TEXT; - lvItem.iSubItem = 0; - lvItem.iItem = ListView_GetItemCount(GetDlgItem(getMyNicksTabHWND(), IDC_LIST)); - LPTSTR lps1 = Utils::mucc_mir_a2t(queryResult->pItems[i].pszName); - lvItem.pszText = lps1; - ListView_InsertItem(GetDlgItem(getMyNicksTabHWND(), IDC_LIST), &lvItem); - Utils::mucc_mir_free(lps1); - } - userNickList = 1; -} - -ChatGroup *ManagerWindow::findGroup(const char *id) -{ - ChatGroup *group; - for (group = groups;group!=NULL;group=group->getListNext()) { - if (!strcmp(group->getId(), id)) break; - } - return group; -} - - -static INT_PTR CALLBACK ChatRoomsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - HWND lv; - LVCOLUMN lvCol; - ManagerWindow *manager; - manager = (ManagerWindow *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - manager = (ManagerWindow *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) manager); - TranslateDialogDefault(hwndDlg); - manager->setChatRoomsTabHWND(hwndDlg); - SendDlgItemMessage(hwndDlg, IDC_PREV, BUTTONSETASFLATBTN, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_NEXT, BUTTONSETASFLATBTN, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_SEARCH, BUTTONSETASFLATBTN, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_PREV, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_PREV]); - SendDlgItemMessage(hwndDlg, IDC_NEXT, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_NEXT]); - SendDlgItemMessage(hwndDlg, IDC_SEARCH, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_SEARCH]); - - lv = GetDlgItem(hwndDlg, IDC_ROOM); - ListView_SetExtendedListViewStyle(lv, LVS_EX_FULLROWSELECT); - lvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; - lvCol.pszText = TranslateT("Name"); - lvCol.cx = 270; - lvCol.iSubItem = 0; - ListView_InsertColumn(lv, 0, &lvCol); - lvCol.pszText = TranslateT("Persons"); - lvCol.cx = 50; - lvCol.iSubItem = 1; - ListView_InsertColumn(lv, 1, &lvCol); - lvCol.pszText = _TEXT("");//Translate(""); - lvCol.cx = 46; - lvCol.iSubItem = 2; - ListView_InsertColumn(lv, 2, &lvCol); - return TRUE; - case WM_NOTIFY: - switch (wParam) { - case IDC_ROOM: - switch (((LPNMHDR)lParam)->code) { - case LVN_COLUMNCLICK: - { - LPNMLISTVIEW pnmlv = (LPNMLISTVIEW) lParam; - if (pnmlv->iSubItem>=0 && pnmlv->iSubItem<=1) { - // if (pnmlv->iSubItem == sortColumn) - // sortAscending = !sortAscending; - // else { - // sortAscending = TRUE; - // sortColumn = pnmlv->iSubItem; - // } - // ListView_SortItems(GetDlgItem(hwndDlg, IDC_ROOM), GroupchatCompare, sortColumn); - } - } - break; - case NM_DBLCLK: - { - LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE) lParam; - LVITEM item; - item.iItem = lpnmitem->iItem; - item.iSubItem = 0; - item.mask = LVIF_PARAM; - if (ListView_GetItem(GetDlgItem(hwndDlg, IDC_ROOM), &item)) { - MUCCEVENT event; - ChatRoom *room = (ChatRoom *)item.lParam; - Utils::log("entering room %s ", room->getId()); - event.cbSize = sizeof(MUCCEVENT); - event.iType = MUCC_EVENT_JOIN; - event.pszModule = manager->getModule(); - event.pszID = room->getId(); - event.pszName = room->getName(); - event.dwFlags = room->getFlags(); - event.pszNick = NULL; - HelperDialog::joinDlg(&event); - } - } - break; - } - break; - } - break; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_NEXT: - if (!manager->isLastRoomsPage()) { - EnableWindow(GetDlgItem(hwndDlg, IDC_PREV), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_NEXT), FALSE); - manager->setCurrentRoomsPage(manager->getCurrentRoomsPage()+1); - SendMessage(GetParent(hwndDlg), WM_MUCC_REFRESH_ROOMS, 0, 0); - } - break; - case IDC_PREV: - if (manager->getCurrentRoomsPage()>0) { - EnableWindow(GetDlgItem(hwndDlg, IDC_PREV), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_NEXT), FALSE); - manager->setCurrentRoomsPage(manager->getCurrentRoomsPage()-1); - } - SendMessage(GetParent(hwndDlg), WM_MUCC_REFRESH_ROOMS, 0, 0); - break; - case IDC_SEARCH: - { - MUCCEVENT event; - event.cbSize = sizeof(MUCCEVENT); - event.iType = MUCC_EVENT_JOIN; - event.dwFlags = MUCC_EF_ROOM_NAME; - event.pszModule = manager->getModule(); - event.pszID = NULL; - event.pszName = NULL; - event.pszNick = NULL; - HelperDialog::joinDlg(&event); - break; - } - } - break; - case WM_MEASUREITEM: - if (wParam == IDC_ROOM) { - MEASUREITEMSTRUCT *lpMis = (MEASUREITEMSTRUCT *) lParam; - lpMis->itemHeight = GetSystemMetrics(SM_CYSMICON); - return TRUE; - } - break; - case WM_DRAWITEM: - if (wParam == IDC_ROOM) { - RECT rc; - int w, x, col; - DRAWITEMSTRUCT *lpDis = (DRAWITEMSTRUCT *) lParam; - ChatRoom *room = NULL; -// if (ListView_GetItem(GetDlgItem(hwndDlg, IDC_ROOM), &item)) { - room = (ChatRoom *)lpDis->itemData;// (ChatRoom *)item.lParam; -// } - TCHAR text[256]; - switch (lpDis->itemAction) { - default: - case ODA_SELECT: - case ODA_DRAWENTIRE: - if (lpDis->itemState & ODS_SELECTED) { - HBRUSH hBrush = CreateSolidBrush(RGB(0xC2, 0xC8, 0xDA));//0xDAC8C2); - FillRect(lpDis->hDC, &(lpDis->rcItem), hBrush);//(HBRUSH) (COLOR_HIGHLIGHT+1)); - DeleteObject(hBrush); - SetTextColor(lpDis->hDC, 0); - SetBkMode(lpDis->hDC, TRANSPARENT); - } - else { -// HBRUSH hBrush = CreateSolidBrush(RGB(0xC2, 0xC8, 0xDA));//0xDAC8C2); - FillRect(lpDis->hDC, &(lpDis->rcItem), (HBRUSH) (COLOR_WINDOW+1)); -// DeleteObject(hBrush); - SetTextColor(lpDis->hDC, RGB(0, 0, 0));//GetSysColor(COLOR_WINDOWTEXT)); -// SetBkColor(lpDis->hDC, GetSysColor(COLOR_WINDOW+1)); - SetBkMode(lpDis->hDC, TRANSPARENT); - } - x = lpDis->rcItem.left; - for (col=0;col<3;col++) { - ListView_GetItemText(GetDlgItem(hwndDlg, IDC_ROOM), lpDis->itemID, col, text, sizeof(text)/sizeof(TCHAR)); - w = ListView_GetColumnWidth(GetDlgItem(hwndDlg, IDC_ROOM), col); - rc.left = x; - rc.top = lpDis->rcItem.top; - rc.bottom = lpDis->rcItem.bottom; - rc.right = x+w; - if (col==0) { - rc.left+=2; - rc.right-=2; - DrawText(lpDis->hDC, text, (int)_tcslen(text), &rc, DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER); - } - else if (col<2) { - DrawText(lpDis->hDC, text, (int)_tcslen(text), &rc, DT_CENTER|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER); - } else { - if (room->getFlags()&MUCC_EF_ROOM_MODERATED) { - DrawIconEx(lpDis->hDC, x, rc.top, muccIcon[MUCC_IDI_R_MODERATED], GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL); - } - if (room->getFlags()&MUCC_EF_ROOM_MEMBERS_ONLY) { - DrawIconEx(lpDis->hDC, x+12+0*GetSystemMetrics(SM_CXSMICON), rc.top, muccIcon[MUCC_IDI_R_MEMBERS], GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL); - } - if (!(room->getFlags()&MUCC_EF_ROOM_NICKNAMES)) { - DrawIconEx(lpDis->hDC, x+24+0*GetSystemMetrics(SM_CXSMICON), rc.top, muccIcon[MUCC_IDI_R_ANONYMOUS], GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL); - } - } - x += w; - } - break; - } - } - break; - } - return FALSE; -} - -static INT_PTR CALLBACK MyRoomsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - RECT rc; - HWND lv; - LVCOLUMN lvCol; - ManagerWindow *manager; - manager = (ManagerWindow *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - manager = (ManagerWindow *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) manager); - TranslateDialogDefault(hwndDlg); - manager->setMyRoomsTabHWND(hwndDlg); - lv = GetDlgItem(hwndDlg, IDC_LIST); - ListView_SetExtendedListViewStyle(lv, LVS_EX_FULLROWSELECT); - GetClientRect(lv, &rc); - lvCol.mask = LVCF_WIDTH; - lvCol.cx = rc.right - rc.left; - ListView_InsertColumn(lv, 0, &lvCol); - return TRUE; - case WM_NOTIFY: - switch (wParam) { - case IDC_LIST: - switch (((LPNMHDR)lParam)->code) { - case NM_DBLCLK: - { - LVITEM item; - item.iItem = ListView_GetSelectionMark(GetDlgItem(hwndDlg, IDC_LIST)); - if (item.iItem >= 0) { - item.iSubItem = 0; - item.mask = LVIF_PARAM; - if (ListView_GetItem(GetDlgItem(hwndDlg, IDC_LIST), &item)) { - ChatRoom *room = (ChatRoom *)item.lParam; - Utils::log("entering room %s (%s)", room->getId(), room->getId()); - MUCCEVENT muce; - muce.cbSize = sizeof(MUCCEVENT); - muce.iType = MUCC_EVENT_JOIN; - muce.pszModule = manager->getModule(); - muce.pszID = room->getId(); - muce.pszName = room->getName(); - muce.dwFlags = MUCC_EF_ROOM_NICKNAMES; - muce.pszNick = NULL; - HelperDialog::joinDlg(&muce); - } - } - } - break; - } - break; - } - break; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_REFRESH: - SendMessage(GetParent(hwndDlg), WM_MUCC_REFRESH_USER_ROOMS, 0, 0); - break; - case IDC_REGISTER: - { - MUCCEVENT muce; - if (manager->getCurrentGroup()!=NULL) { - TCHAR name[256]; - GetDlgItemText(hwndDlg, IDC_NAME, name, 255); - if (_tcslen(name)!=0) { - int flags = 0; - if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_PUBLIC)) { - flags |= MUCC_EF_ROOM_PUBLIC; - } - if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_PERMANENT)) { - flags |= MUCC_EF_ROOM_PERMANENT; - } - if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_MEMBERS)) { - flags |= MUCC_EF_ROOM_MEMBERS_ONLY; - } - if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_NICKNAMES)) { - flags |= MUCC_EF_ROOM_NICKNAMES; - } - muce.cbSize = sizeof(MUCCEVENT); - muce.iType = MUCC_EVENT_REGISTER_ROOM; - muce.pszModule = manager->getModule(); - muce.pszID = manager->getCurrentGroup()->getId(); - char* lps1 = Utils::mucc_mir_t2a(name); - muce.pszName = lps1; - muce.pszNick = NULL; - muce.dwFlags = flags; - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - Utils::mucc_mir_free(lps1); - } - } else { - muce.pszText = "Please select a group first."; - HelperDialog::errorDlg(&muce); - } - } - break; - } - break; - case WM_MEASUREITEM: - if (wParam == IDC_LIST) { - MEASUREITEMSTRUCT *lpMis = (MEASUREITEMSTRUCT *) lParam; - lpMis->itemHeight = 16;//GetSystemMetrics(SM_CYSMICON); - return TRUE; - } - break; - case WM_DRAWITEM: - if (wParam == IDC_LIST) { - TCHAR text[256]; - DRAWITEMSTRUCT *lpDis = (DRAWITEMSTRUCT *) lParam; - switch (lpDis->itemAction) { - default: - case ODA_SELECT: - case ODA_DRAWENTIRE: - if (lpDis->itemState & ODS_SELECTED) { - HBRUSH hBrush = CreateSolidBrush(RGB(0xC2, 0xC8, 0xDA));//0xDAC8C2); - FillRect(lpDis->hDC, &(lpDis->rcItem), hBrush);//(HBRUSH) (COLOR_HIGHLIGHT+1)); - DeleteObject(hBrush); - SetTextColor(lpDis->hDC, 0); - SetBkMode(lpDis->hDC, TRANSPARENT); - } - else { - FillRect(lpDis->hDC, &(lpDis->rcItem), (HBRUSH) (COLOR_WINDOW+1)); - SetTextColor(lpDis->hDC, RGB(0, 0, 0));//GetSysColor(COLOR_WINDOWTEXT)); - SetBkMode(lpDis->hDC, TRANSPARENT); - } - ListView_GetItemText(GetDlgItem(hwndDlg, IDC_LIST), lpDis->itemID, 0, text, sizeof(text)/sizeof(TCHAR)); - DrawText(lpDis->hDC, text, (int)_tcslen(text), &(lpDis->rcItem), DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER); - break; - } - } - break; - - } - return FALSE; -} - -static INT_PTR CALLBACK MyNicksDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - RECT rc; - HWND lv; - LVCOLUMN lvCol; - ManagerWindow *manager; - manager = (ManagerWindow *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - manager = (ManagerWindow *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) manager); - TranslateDialogDefault(hwndDlg); - manager->setMyNicksTabHWND(hwndDlg); - lv = GetDlgItem(hwndDlg, IDC_LIST); - ListView_SetExtendedListViewStyle(lv, LVS_EX_FULLROWSELECT); - GetClientRect(lv, &rc); - lvCol.mask = LVCF_WIDTH; - lvCol.cx = rc.right - rc.left; - ListView_InsertColumn(lv, 0, &lvCol); - return TRUE; - case WM_NOTIFY: - switch (wParam) { - case IDC_LIST: - break; - - } - break; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_REFRESH: - SendMessage(GetParent(hwndDlg), WM_MUCC_REFRESH_USER_NICKS, 0, 0); - break; - case IDC_REGISTER: - { - char nick[256]; - GetDlgItemTextA(hwndDlg, IDC_NICK, nick, 255); - if (strlen(nick)!=0) { - MUCCEVENT muce; - muce.cbSize = sizeof(MUCCEVENT); - muce.iType = MUCC_EVENT_REGISTER_NICK; - muce.pszModule = manager->getModule(); - muce.pszNick = nick; - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - } - } - break; - case IDC_REMOVE: - { - LVITEM item; - item.iItem = ListView_GetSelectionMark(GetDlgItem(hwndDlg, IDC_LIST)); - if (item.iItem >= 0) { - TCHAR text[256]; - item.iSubItem = 0; - item.mask = LVIF_TEXT; - item.pszText = text; - item.cchTextMax = sizeof(text); - if (ListView_GetItem(GetDlgItem(hwndDlg, IDC_LIST), &item)) { - MUCCEVENT muce; - muce.cbSize = sizeof(MUCCEVENT); - muce.iType = MUCC_EVENT_REMOVE_NICK; - muce.pszModule = manager->getModule(); - char* lps2 = Utils::mucc_mir_t2a(text); - muce.pszNick = lps2; - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - Utils::mucc_mir_free(lps2); - } - } - } - } - break; - case WM_MEASUREITEM: - if (wParam == IDC_LIST) { - MEASUREITEMSTRUCT *lpMis = (MEASUREITEMSTRUCT *) lParam; - lpMis->itemHeight = 16;//GetSystemMetrics(SM_CYSMICON); - return TRUE; - } - break; - case WM_DRAWITEM: - if (wParam == IDC_LIST) { - TCHAR text[256]; - DRAWITEMSTRUCT *lpDis = (DRAWITEMSTRUCT *) lParam; - switch (lpDis->itemAction) { - default: - case ODA_SELECT: - case ODA_DRAWENTIRE: - if (lpDis->itemState & ODS_SELECTED) { - HBRUSH hBrush = CreateSolidBrush(RGB(0xC2, 0xC8, 0xDA));//0xDAC8C2); - FillRect(lpDis->hDC, &(lpDis->rcItem), hBrush);//(HBRUSH) (COLOR_HIGHLIGHT+1)); - DeleteObject(hBrush); - SetTextColor(lpDis->hDC, 0); - SetBkMode(lpDis->hDC, TRANSPARENT); - } - else { - FillRect(lpDis->hDC, &(lpDis->rcItem), (HBRUSH) (COLOR_WINDOW+1)); - SetTextColor(lpDis->hDC, RGB(0, 0, 0));//GetSysColor(COLOR_WINDOWTEXT)); - SetBkMode(lpDis->hDC, TRANSPARENT); - } - ListView_GetItemText(GetDlgItem(hwndDlg, IDC_LIST), lpDis->itemID, 0, text, sizeof(text)/sizeof(TCHAR)); - DrawText(lpDis->hDC, text, (int)_tcslen(text), &(lpDis->rcItem), DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER); - break; - } - } - break; - } - return FALSE; -} - -static INT_PTR CALLBACK ManagerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - HWND hwnd, tc; - TCITEM tci; - char text[128]; -// HIMAGELIST hImageList; - ManagerWindow *manager; - MUCCEVENT muce; - int dlgWidth, dlgHeight, tabPos; - RECT rc2; - - manager = (ManagerWindow *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - if (manager==NULL && msg!=WM_INITDIALOG) return FALSE; - switch (msg) { - case WM_INITDIALOG: - // lParam is the initial conference server (if any) - manager = (ManagerWindow *)lParam; - manager->setHWND(hwndDlg); - sprintf(text, "%s Chats", manager->getModuleName()); - SetWindowTextA(hwndDlg, text); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) manager); - SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) muccIcon[MUCC_IDI_CHAT]); - - TranslateDialogDefault(hwndDlg); -// sortColumn = -1; - manager->setCurrentTab(0); - tc = GetDlgItem(hwndDlg, IDC_TABS); - tci.mask = TCIF_TEXT; - // Public rooms tab - tci.pszText = TranslateT("Chat rooms"); - TabCtrl_InsertItem(tc, 0, &tci); - // Create room tab - tci.pszText = TranslateT("My rooms"); - TabCtrl_InsertItem(tc, 1, &tci); - tci.pszText = TranslateT("My nicknames"); - TabCtrl_InsertItem(tc, 2, &tci); - hwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_TAB_CHATROOMS), hwndDlg, ChatRoomsDlgProc, (LPARAM) manager); - SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - ShowWindow(hwnd, SW_SHOW); - hwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_TAB_MYROOMS), hwndDlg, MyRoomsDlgProc, (LPARAM) manager); - SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - hwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_TAB_MYNICKNAMES), hwndDlg, MyNicksDlgProc, (LPARAM) manager); - SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - EnableWindow(GetDlgItem(manager->getChatRoomsTabHWND(), IDC_PREV), FALSE); - EnableWindow(GetDlgItem(manager->getChatRoomsTabHWND(), IDC_NEXT), FALSE); - - GetWindowRect(manager->getMyRoomsTabHWND(), &rc2); - rc2.right-=rc2.left; - rc2.bottom-=rc2.top; - SetWindowPos(hwndDlg, NULL, 0, 0, rc2.right+300, 118+rc2.bottom, SWP_NOMOVE | SWP_NOZORDER); - TreeView_SetItemHeight(GetDlgItem(hwndDlg, IDC_GROUP), 16); -// hImageList=ImageList_Create(100, 100, ILC_COLOR32, 0, 10); -// ListView_SetImageList(GetDlgItem(hwndDlg, IDC_ROOM), hImageList, LVSIL_SMALL); - SetEvent(manager->getEvent()); - muce.cbSize = sizeof(MUCCEVENT); - muce.iType = MUCC_EVENT_QUERY_GROUPS; - muce.pszModule = manager->getModule(); - muce.pszID = NULL; - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - return TRUE; - case WM_SIZING: - RECT *rc, rc2; - rc = (RECT *)lParam; - GetWindowRect(manager->getMyRoomsTabHWND(), &rc2); - rc2.right-=rc2.left; - rc2.bottom-=rc2.top; - if (rc->right-rc->left<(rc2.right+80)) { - if (wParam == WMSZ_RIGHT || wParam == WMSZ_BOTTOMRIGHT || wParam == WMSZ_TOPRIGHT) { - rc->right=rc->left+rc2.right+80; - } else { - rc->left=rc->right-rc2.right-80; - } - } - if (rc->bottom-rc->top<118+rc2.bottom || rc->bottom-rc->top>118+rc2.bottom) { - if (wParam == WMSZ_BOTTOM || wParam == WMSZ_BOTTOMLEFT || wParam == WMSZ_BOTTOMRIGHT) { - rc->bottom=rc->top+118+rc2.bottom; - } else { - rc->top=rc->bottom-118-rc2.bottom; - } - } - return TRUE; - case WM_SIZE: - if (wParam==SIZE_RESTORED || wParam==SIZE_MAXIMIZED) { - HDWP hdwp; - dlgWidth = LOWORD(lParam); - dlgHeight = HIWORD(lParam); - GetWindowRect(manager->getMyRoomsTabHWND(), &rc2); - rc2.right-=rc2.left; - rc2.bottom-=rc2.top; - tabPos = dlgWidth - rc2.right - 15; - hdwp = BeginDeferWindowPos(6); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_TABS), 0, tabPos, 10, 0, 0, SWP_NOZORDER | SWP_NOSIZE); - hdwp = DeferWindowPos(hdwp, manager->getChatRoomsTabHWND(), 0, tabPos+3, 45, 371, 292, SWP_NOZORDER | SWP_NOSIZE); - hdwp = DeferWindowPos(hdwp, manager->getMyRoomsTabHWND() , 0, tabPos+3, 45, 371, 292, SWP_NOZORDER | SWP_NOSIZE); - hdwp = DeferWindowPos(hdwp, manager->getMyNicksTabHWND() , 0, tabPos+3, 45, 371, 292, SWP_NOZORDER | SWP_NOSIZE); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_GROUP), 0, 0, 0, tabPos-16, dlgHeight-40, SWP_NOZORDER | SWP_NOMOVE); - hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDCLOSE), 0, dlgWidth-88, dlgHeight-34, 0, 0 , SWP_NOZORDER | SWP_NOSIZE); - EndDeferWindowPos(hdwp); - } - break; - case WM_NOTIFY: - switch (wParam) { - case IDC_GROUP: - switch (((LPNMHDR)lParam)->code) { - case TVN_ITEMEXPANDING: - { - LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) lParam; - if (pnmtv->action==TVE_EXPAND) { - TVITEM item = (TVITEM) pnmtv->itemNew; - ChatGroup *group = (ChatGroup *) item.lParam;// manager->findGroup(item.hItem); - if (group!=NULL) { - if (group->getChild()==NULL) { - muce.cbSize = sizeof(MUCCEVENT); - muce.iType = MUCC_EVENT_QUERY_GROUPS; - muce.pszModule = manager->getModule(); - muce.pszID = group->getId(); - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - } - } - } - } - break; - case TVN_SELCHANGED: - { - LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) lParam; - TVITEM item = (TVITEM) pnmtv->itemNew; - ChatGroup *group = (ChatGroup *) item.lParam;// manager->findGroup(item.hItem); - if (group!=NULL) { - EnableWindow(GetDlgItem(manager->getChatRoomsTabHWND(), IDC_PREV), FALSE); - EnableWindow(GetDlgItem(manager->getChatRoomsTabHWND(), IDC_NEXT), FALSE); - ListView_DeleteAllItems(GetDlgItem(manager->getChatRoomsTabHWND(), IDC_ROOM)); - manager->setCurrentGroup(group); - manager->setCurrentRoomsPage(0); - muce.cbSize = sizeof(MUCCEVENT); - muce.iType = MUCC_EVENT_QUERY_ROOMS; - muce.pszModule = manager->getModule(); - muce.pszID = (char *)group->getId(); - muce.dwData = 0; - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - } - } - break; - case NM_CUSTOMDRAW: - { - if (((LPNMHDR)lParam)->idFrom == IDC_GROUP) { - LPNMTVCUSTOMDRAW pCustomDraw = (LPNMTVCUSTOMDRAW)lParam; - switch (pCustomDraw->nmcd.dwDrawStage) { - case CDDS_PREPAINT: - SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT,CDRF_NOTIFYITEMDRAW); - return TRUE; - case CDDS_ITEMPREPAINT: - { - if (pCustomDraw->nmcd.uItemState & CDIS_FOCUS) { // selected (CDIS_FOCUS | CDIS_SELECTED - pCustomDraw->clrText = 0; - pCustomDraw->clrTextBk = 0xDAC8C2; - } - else { - pCustomDraw->clrText = 0; - } - // HBRUSH hBr; - // hBr = CreateSolidBrush(pCustomDraw->clrTextBk);//g_LogOptions.crUserListBGColor ) ; - // FillRect(pCustomDraw->nmcd.hdc, &rc, hBr); - // DeleteObject(hBr); - SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT, CDRF_NEWFONT); - return TRUE; - } - } - } - } - break; - } - break; - case IDC_TABS: - switch (((LPNMHDR) lParam)->code) { - case TCN_SELCHANGE: - switch (manager->getCurrentTab()) { - case 0: - ShowWindow(manager->getChatRoomsTabHWND(), SW_HIDE); - break; - case 1: - ShowWindow(manager->getMyRoomsTabHWND(), SW_HIDE); - break; - case 2: - ShowWindow(manager->getMyNicksTabHWND(), SW_HIDE); - break; - } - manager->setCurrentTab(TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_TABS))); - switch (manager->getCurrentTab()) { - case 0: - ShowWindow(manager->getChatRoomsTabHWND(), SW_SHOW); - break; - case 1: - ShowWindow(manager->getMyRoomsTabHWND(), SW_SHOW); - if (!manager->isUserRoomListReceived()) { - SendMessage(hwndDlg, WM_MUCC_REFRESH_USER_ROOMS, 0, 0); - } - break; - case 2: - ShowWindow(manager->getMyNicksTabHWND(), SW_SHOW); - if (!manager->isUserNickListReceived()) { - SendMessage(hwndDlg, WM_MUCC_REFRESH_USER_NICKS, 0, 0); - } - break; - } - break; - } - break; - } - break; - case WM_MUCC_REFRESH_USER_ROOMS: - muce.cbSize = sizeof(MUCCEVENT); - muce.iType = MUCC_EVENT_QUERY_USER_ROOMS; - muce.pszModule = manager->getModule(); - muce.pszID = NULL; - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - break; - case WM_MUCC_REFRESH_USER_NICKS: - muce.cbSize = sizeof(MUCCEVENT); - muce.iType = MUCC_EVENT_QUERY_USER_NICKS; - muce.pszModule = manager->getModule(); - muce.pszID = NULL; - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - break; - case WM_MUCC_REFRESH_ROOMS: - { - ChatGroup *group = manager->getCurrentGroup(); - if (manager->getCurrentGroup()!=NULL) { - EnableWindow(GetDlgItem(manager->getChatRoomsTabHWND(), IDC_PREV), FALSE); - EnableWindow(GetDlgItem(manager->getChatRoomsTabHWND(), IDC_NEXT), FALSE); - ListView_DeleteAllItems(GetDlgItem(manager->getChatRoomsTabHWND(), IDC_ROOM)); - /* - * TODO: delete rooms here !!! - */ - muce.cbSize = sizeof(MUCCEVENT); - muce.iType = MUCC_EVENT_QUERY_ROOMS; - muce.pszModule = manager->getModule(); - muce.pszID = (char *)group->getId(); - muce.dwData = manager->getCurrentRoomsPage(); - NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); - } - } - break; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDCLOSE: - ShowWindow(hwndDlg, SW_HIDE); - break; - } - break; - case WM_CLOSE: - ShowWindow(hwndDlg, SW_HIDE); - break; - - } - return FALSE; -} - -ManagerWindow* ManagerWindow::getWindow(const char *module) { - ManagerWindow *ptr; - EnterCriticalSection(&mutex); - for (ptr=list;ptr!=NULL;ptr=ptr->getNext()) { - if (strcmp(ptr->getModule(), module)==0) { - break; - } - } - LeaveCriticalSection(&mutex); - if (ptr==NULL) { - ptr = new ManagerWindow(module); - } - return ptr; -} - diff --git a/!NotAdopted/Tlen/tlen_czaty/ManagerWindow.h b/!NotAdopted/Tlen/tlen_czaty/ManagerWindow.h deleted file mode 100644 index f57d1c1057..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/ManagerWindow.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#ifndef MANAGERWINDOW_INCLUDED -#define MANAGERWINDOW_INCLUDED -#include "mucc.h" -#include "ChatGroup.h" -#include "ChatRoom.h" - -class ManagerWindow{ - -private: - static CRITICAL_SECTION mutex; - static bool released; - static ManagerWindow * list; - HWND hWnd; - HWND hChatRoomsTabWnd; - HWND hMyRoomsTabWnd; - HWND hMyNicksTabWnd; - HANDLE hEvent; - ManagerWindow * prev; - ManagerWindow * next; - ChatGroup * groups; - ChatRoom * rooms; - ChatRoom * myRooms; - char * module; - char * moduleName; - ChatGroup * currentGroup; - int isStarted; - int userNickList, userRoomList; - int currentTab; - int currentRoomsPage; - int lastRoomsPage; -public: - ManagerWindow (const char *module); - ~ManagerWindow (); - int start(); - ChatGroup * findGroup(const char *id); - void queryResultGroups(MUCCQUERYRESULT *queryResult); - void queryResultRooms(MUCCQUERYRESULT *queryResult); - void queryResultUserRooms(MUCCQUERYRESULT *queryResult); - void queryResultUserNick(MUCCQUERYRESULT *queryResult); - ManagerWindow * getNext(); - void setNext(ManagerWindow *); - ManagerWindow * getPrev(); - void setPrev(ManagerWindow *); - void setHWND(HWND); - HWND getHWND(); - HANDLE getEvent(); - void setChatRoomsTabHWND(HWND); - HWND getChatRoomsTabHWND(); - void setMyNicksTabHWND(HWND); - HWND getMyNicksTabHWND(); - void setMyRoomsTabHWND(HWND); - HWND getMyRoomsTabHWND(); - void setModuleName(const char *moduleName); - void setCurrentTab(int); - int getCurrentTab(); - const char * getModule(); - const char * getModuleName(); - void setCurrentGroup(ChatGroup *); - ChatGroup * getCurrentGroup(); - void setCurrentRoomsPage(int); - int getCurrentRoomsPage(); - void setLastRoomsPage(int); - int isLastRoomsPage(); - int isUserRoomListReceived(); - int isUserNickListReceived(); - - static ManagerWindow* getWindow(const char *module); - static void release(); - static void init(); - -}; -#endif - diff --git a/!NotAdopted/Tlen/tlen_czaty/Options.cpp b/!NotAdopted/Tlen/tlen_czaty/Options.cpp deleted file mode 100644 index 8e0f093ddd..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/Options.cpp +++ /dev/null @@ -1,789 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "mucc.h" -#include "Options.h" -#include "ChatWindow.h" -#include "Utils.h" -#include "resource.h" -#include -#include "m_ieview.h" - -static INT_PTR CALLBACK MUCCOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -//static INT_PTR CALLBACK MUCCLogOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -//static INT_PTR CALLBACK MUCCPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - - -COLORREF Options::colorListBg, Options::colorInputBg, Options::colorLogBg, Options::chatWindowFontColor; -HBRUSH Options::brushListBg=NULL, Options::brushInputBg=NULL, Options::brushLogBg=NULL; -int Options::logLimit, Options::chatWindowOptions, Options::chatContainerOptions; -int Options::chatWindowFont, Options::chatWindowFontSize, Options::chatWindowFontStyle; - -void Options::setListBgColor(COLORREF c) { - colorListBg = c; - if (brushListBg != NULL) { - DeleteObject(brushListBg); - } - brushListBg = CreateSolidBrush(colorListBg); -} - -void Options::setInputBgColor(COLORREF c) { - colorInputBg = c; - if (brushInputBg!= NULL) { - DeleteObject(brushInputBg); - } - brushInputBg = CreateSolidBrush(colorInputBg); -} - -void Options::setLogBgColor(COLORREF c) { - colorLogBg = c; - if (brushLogBg!= NULL) { - DeleteObject(brushLogBg); - } - brushLogBg = CreateSolidBrush(colorLogBg); -} - -COLORREF Options::getListBgColor() { - return colorListBg; -} - -COLORREF Options::getInputBgColor() { - return colorInputBg; -} - -COLORREF Options::getLogBgColor() { - return colorLogBg; -} - -HBRUSH Options::getListBgBrush() { - return brushListBg; -} - -HBRUSH Options::getInputBgBrush() { - return brushInputBg; -} - -HBRUSH Options::getLogBgBrush() { - return brushLogBg; -} - -void Options::setLogLimit(int l) { - logLimit = l; -} - -int Options::getLogLimit() { - return logLimit; -} - -void Options::setChatWindowFont(int o) { - chatWindowFont = o; -} - -int Options::getChatWindowFont() { - return chatWindowFont; -} - -void Options::setChatWindowFontSize(int o) { - chatWindowFontSize = o; -} - -int Options::getChatWindowFontSize() { - return chatWindowFontSize; -} - -void Options::setChatWindowFontStyle(int o) { - chatWindowFontStyle = o; -} - -int Options::getChatWindowFontStyle() { - return chatWindowFontStyle; -} - -void Options::setChatWindowFontColor(COLORREF o) { - chatWindowFontColor = o; -} - -COLORREF Options::getChatWindowFontColor() { - return chatWindowFontColor; -} - -void Options::setChatWindowOptions(int o) { - chatWindowOptions = o; -} - -int Options::getChatWindowOptions() { - return chatWindowOptions; -} - -void Options::setChatContainerOptions(int o) { - chatContainerOptions = o; -} - -int Options::getChatContainerOptions() { - return chatContainerOptions; -} - -void Options::setExpandFlags(int o) { - DBWriteContactSettingDword(NULL, muccModuleName, "ExpandFlags", o); -} - -int Options::getExpandFlags() { - return DBGetContactSettingDword(NULL, muccModuleName, "ExpandFlags", 0xFFFFFFFF); -} - -void Options::loadSettings() { - FontList::loadSettings(); - setLogBgColor((COLORREF)DBGetContactSettingDword(NULL, muccModuleName, "BackgroundLog", 0xFFFFFF)); - setListBgColor((COLORREF)DBGetContactSettingDword(NULL, muccModuleName, "BackgroundList", 0xFFFFFF)); - setInputBgColor((COLORREF)DBGetContactSettingDword(NULL, muccModuleName, "BackgroundTyping", 0xFFFFFF)); - setLogLimit(DBGetContactSettingDword(NULL, muccModuleName, "LogSizeLimit", 100)); - setChatContainerOptions(DBGetContactSettingDword(NULL, muccModuleName, "ChatContainerOptions", ChatContainer::getDefaultOptions())); - setChatWindowOptions(DBGetContactSettingDword(NULL, muccModuleName, "ChatWindowOptions", ChatWindow::getDefaultOptions())); - setChatWindowFont(DBGetContactSettingDword(NULL, muccModuleName, "ChatWindowFont", 0)); - setChatWindowFontSize(DBGetContactSettingDword(NULL, muccModuleName, "ChatWindowFontSize", 5)); - setChatWindowFontStyle(DBGetContactSettingDword(NULL, muccModuleName, "ChatWindowFontStyle", 0)); - setChatWindowFontColor(DBGetContactSettingDword(NULL, muccModuleName, "ChatWindowFontColor", 0)); -} - -void Options::saveSettings() { - FontList::saveSettings(); - DBWriteContactSettingDword(NULL, muccModuleName, "BackgroundLog", colorLogBg); - DBWriteContactSettingDword(NULL, muccModuleName, "BackgroundList", colorListBg); - DBWriteContactSettingDword(NULL, muccModuleName, "BackgroundTyping", colorInputBg); - DBWriteContactSettingDword(NULL, muccModuleName, "LogSizeLimit", logLimit); - DBWriteContactSettingDword(NULL, muccModuleName, "ChatContainerOptions", chatContainerOptions); - DBWriteContactSettingDword(NULL, muccModuleName, "ChatWindowOptions", chatWindowOptions); - DBWriteContactSettingDword(NULL, muccModuleName, "ChatWindowFont", chatWindowFont); - DBWriteContactSettingDword(NULL, muccModuleName, "ChatWindowFontSize", chatWindowFontSize); - DBWriteContactSettingDword(NULL, muccModuleName, "ChatWindowFontStyle", chatWindowFontStyle); - DBWriteContactSettingDword(NULL, muccModuleName, "ChatWindowFontColor", chatWindowFontColor); -} - -void Options::init() -{ - FontList::init(); - loadSettings(); -} - -int MUCCOptInit(WPARAM wParam, LPARAM lParam) -{ - OPTIONSDIALOGPAGE odp; - - ZeroMemory(&odp, sizeof(odp)); - odp.cbSize = sizeof(odp); - odp.position = 0; - odp.hInstance = hInst; - odp.pszGroup = Translate("Network"); - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); -// odp.pszTitle = muccModuleName; - odp.pszTitle = "Tlen czaty"; - odp.flags = ODPF_BOLDGROUPS; - odp.pfnDlgProc = MUCCOptDlgProc; - odp.nIDBottomSimpleControl = 0; - CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) &odp); - - /* - odp.pszTemplate = MAKEINTRESOURCE(IDD_OPTIONS_LOG); - _snprintf(str, sizeof(str), "%s %s", muccModuleName, Translate("Log")); - str[sizeof(str)-1] = '\0'; - odp.pszTitle = str; - odp.pfnDlgProc = MUCCLLogOptDlgProc; - odp.flags = ODPF_BOLDGROUPS|ODPF_EXPERTONLY; - odp.nIDBottomSimpleControl = 0; - CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) &odp); - if (ServiceExists(MS_POPUP_ADDPOPUP)) { - ZeroMemory(&odp,sizeof(odp)); - odp.cbSize = sizeof(odp); - odp.position = 100000000; - odp.hInstance = hInst; - odp.pszGroup = Translate("PopUps"); - odp.pszTemplate = MAKEINTRESOURCE(IDD_OPTIONS_POPUPS); - odp.pszTitle = jabberModuleName; - odp.flags=ODPF_BOLDGROUPS; - odp.pfnDlgProc = TlenPopupsDlgProc; - odp.nIDBottomSimpleControl = 0; - CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp); - } - -*/ - return 0; -} - - -static int getOptions(HWND hTreeControl, HTREEITEM hItem, int flags) { - TVITEM tvi = {0}; - tvi.mask = TVIF_HANDLE | TVIF_STATE | TVIF_PARAM; - tvi.stateMask = TVIS_STATEIMAGEMASK; - tvi.hItem = hItem; - TreeView_GetItem(hTreeControl, &tvi); - if ((tvi.state>>12) == 2) { - flags |= tvi.lParam; - } else { - flags &= ~tvi.lParam; - } - tvi.hItem = TreeView_GetChild(hTreeControl, hItem); - if (tvi.hItem != NULL) { - flags = getOptions(hTreeControl, tvi.hItem, flags); - } - tvi.hItem=TreeView_GetNextSibling(hTreeControl, hItem); - if (tvi.hItem != NULL) { - flags = getOptions(hTreeControl, tvi.hItem, flags); - } - return flags; - -} - -static int getExpandFlags(HWND hTreeControl) { - TVITEM tvi = {0}; - int flags =0, mask = 1; - tvi.mask = TVIF_HANDLE | TVIF_STATE; - tvi.stateMask = TVIS_EXPANDED; - tvi.hItem = TreeView_GetRoot(hTreeControl); - while (tvi.hItem != NULL) { - TreeView_GetItem(hTreeControl, &tvi); - if (tvi.state & TVIS_EXPANDED) { - flags |= mask; - } - mask <<= 1; - tvi.hItem=TreeView_GetNextSibling(hTreeControl, tvi.hItem); - } - return flags; -} - - -static int addOption(HWND hTreeControl, HTREEITEM hParent, const char *text, int flag) { - TVINSERTSTRUCT tvis; - tvis.hInsertAfter = TVI_LAST; - tvis.hParent = hParent; - tvis.item.mask = TVIF_TEXT | TVIF_STATE | TVIF_PARAM; - char* textA = Translate(text); - LPTSTR textT = Utils::mucc_mir_a2t(textA); - tvis.item.pszText = textT; - tvis.item.lParam = flag; - tvis.item.stateMask = TVIS_STATEIMAGEMASK; - tvis.item.state = Options::getChatWindowOptions() & flag ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1); - TreeView_InsertItem(hTreeControl, &tvis); - Utils::mucc_mir_free(textT); - return (Options::getChatWindowOptions() & flag) != 0; - -} - -static INT_PTR CALLBACK MUCCOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - int i; - char *pszText; - switch (msg) { - case WM_INITDIALOG: - { - TVINSERTSTRUCT tvis; - TVITEM tvi; - HWND hTreeControl; - HTREEITEM hItem; - int bCheckParent, expandFlags; - - TranslateDialogDefault(hwndDlg); - Options::loadSettings(); - for (i=0;igetColor()); - SendDlgItemMessage(hwndDlg, IDC_COLORBKG, CPM_SETCOLOUR, 0, Options::getLogBgColor()); - SendDlgItemMessage(hwndDlg, IDC_COLORLIST, CPM_SETCOLOUR, 0, Options::getListBgColor()); - SendDlgItemMessage(hwndDlg, IDC_COLORINPUT, CPM_SETCOLOUR, 0, Options::getInputBgColor()); - SendDlgItemMessage(hwndDlg, IDC_LOGLIMITSPIN, UDM_SETRANGE, 0, MAKELONG(1000,20)); - SendDlgItemMessage(hwndDlg, IDC_LOGLIMITSPIN, UDM_SETPOS, 0, MAKELONG(Options::getLogLimit(), 0)); - - SetWindowLong(GetDlgItem(hwndDlg,IDC_TREELIST),GWL_STYLE,GetWindowLong(GetDlgItem(hwndDlg,IDC_TREELIST),GWL_STYLE)|TVS_NOHSCROLL|TVS_CHECKBOXES); - - - hTreeControl = GetDlgItem(hwndDlg, IDC_TREELIST); - expandFlags = Options::getExpandFlags(); - tvis.hInsertAfter = TVI_LAST; - tvis.item.mask = TVIF_TEXT | TVIF_PARAM; - tvis.hParent = NULL; - tvis.item.lParam = 0; - - tvi.mask = TVIF_HANDLE | TVIF_STATE; - tvi.stateMask = TVIS_STATEIMAGEMASK; - - tvis.item.pszText = TranslateT("Default Log Appearence"); - hItem = TreeView_InsertItem(hTreeControl, &tvis); - bCheckParent = 1; - bCheckParent &= addOption(hTreeControl, hItem, "Show nicknames", ChatWindow::FLAG_SHOW_NICKNAMES); - bCheckParent &= addOption(hTreeControl, hItem, "Show message on a new line", ChatWindow::FLAG_MSGINNEWLINE); - tvi.state = (bCheckParent ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1)); - tvi.hItem = hItem; - TreeView_SetItem(hTreeControl, &tvi); - if (expandFlags & 1) { - TreeView_Expand(hTreeControl, hItem, TVE_EXPAND); - } - - tvis.item.pszText = TranslateT("Default Timestamp Settings"); - hItem = TreeView_InsertItem(hTreeControl, &tvis); - bCheckParent = 1; - bCheckParent &= addOption(hTreeControl, hItem, "Show date", ChatWindow::FLAG_SHOW_DATE); - bCheckParent &= addOption(hTreeControl, hItem, "Show timestamp", ChatWindow::FLAG_SHOW_TIMESTAMP); - bCheckParent &= addOption(hTreeControl, hItem, "Show seconds", ChatWindow::FLAG_SHOW_SECONDS); - bCheckParent &= addOption(hTreeControl, hItem, "Use long date format", ChatWindow::FLAG_LONG_DATE); - tvi.state = (bCheckParent ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1)); - tvi.hItem = hItem; - TreeView_SetItem(hTreeControl, &tvi); - if (expandFlags & 2) { - TreeView_Expand(hTreeControl, hItem, TVE_EXPAND); - } - - tvis.item.pszText = TranslateT("Default Text Formatting Filter"); - hItem = TreeView_InsertItem(hTreeControl, &tvis); - bCheckParent = 1; - bCheckParent &= addOption(hTreeControl, hItem, "Font name", ChatWindow::FLAG_FORMAT_FONT); - bCheckParent &= addOption(hTreeControl, hItem, "Font size", ChatWindow::FLAG_FORMAT_SIZE); - bCheckParent &= addOption(hTreeControl, hItem, "Font style", ChatWindow::FLAG_FORMAT_STYLE); - bCheckParent &= addOption(hTreeControl, hItem, "Font color", ChatWindow::FLAG_FORMAT_COLOR); - tvi.state = (bCheckParent ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1)); - tvi.hItem = hItem; - TreeView_SetItem(hTreeControl, &tvi); - if (expandFlags & 4) { - TreeView_Expand(hTreeControl, hItem, TVE_EXPAND); - } - - tvis.item.pszText = TranslateT("Default Event Filter"); - hItem = TreeView_InsertItem(hTreeControl, &tvis); - bCheckParent = 1; - bCheckParent &= addOption(hTreeControl, hItem, "Messages", ChatWindow::FLAG_LOG_MESSAGES); - bCheckParent &= addOption(hTreeControl, hItem, "User has joined", ChatWindow::FLAG_LOG_JOINED); - bCheckParent &= addOption(hTreeControl, hItem, "User has left", ChatWindow::FLAG_LOG_LEFT); - bCheckParent &= addOption(hTreeControl, hItem, "Topic changes", ChatWindow::FLAG_LOG_TOPIC); - tvi.state = (bCheckParent ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1)); - tvi.hItem = hItem; - TreeView_SetItem(hTreeControl, &tvi); - if (expandFlags & 8) { - TreeView_Expand(hTreeControl, hItem, TVE_EXPAND); - } - - tvis.item.pszText = TranslateT("Default Window Flashing"); - hItem = TreeView_InsertItem(hTreeControl, &tvis); - bCheckParent = 1; - bCheckParent &= addOption(hTreeControl, hItem, "Messages", ChatWindow::FLAG_FLASH_MESSAGES); - bCheckParent &= addOption(hTreeControl, hItem, "User has joined", ChatWindow::FLAG_FLASH_JOINED); - bCheckParent &= addOption(hTreeControl, hItem, "User has left", ChatWindow::FLAG_FLASH_LEFT); - bCheckParent &= addOption(hTreeControl, hItem, "Topic changes", ChatWindow::FLAG_FLASH_TOPIC); - tvi.state = (bCheckParent ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1)); - tvi.hItem = hItem; - TreeView_SetItem(hTreeControl, &tvi); - if (expandFlags & 16) { - TreeView_Expand(hTreeControl, hItem, TVE_EXPAND); - } - - CheckDlgButton(hwndDlg, IDC_SENDONENTER, Options::getChatWindowOptions() & ChatWindow::FLAG_OPT_SENDONENTER); - CheckDlgButton(hwndDlg, IDC_ENABLEIEVIEW, Options::getChatWindowOptions() & ChatWindow::FLAG_OPT_ENABLEIEVIEW); - if (!ServiceExists(MS_IEVIEW_WINDOW)) { - EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLEIEVIEW), FALSE); - } - CheckDlgButton(hwndDlg, IDC_USETABS, Options::getChatContainerOptions() & ChatContainer::FLAG_USE_TABS); - - } - case WM_MEASUREITEM: - if (wParam == IDC_FONTLIST) { - MEASUREITEMSTRUCT *lpMis = (MEASUREITEMSTRUCT *) lParam; - HFONT hFont, hoFont; - HDC hDC; - SIZE fontSize; - int iItem = lpMis->itemData - 1; - Font *font = Options::getFontSettings(iItem); - if (font != NULL) { - - LPTSTR lps1 = Utils::mucc_mir_a2t(font->getFace()); - hFont = CreateFont(font->getSize(), 0, 0, 0, - font->getStyle() & Font::BOLD ? FW_BOLD : FW_NORMAL, - font->getStyle() & Font::ITALIC ? 1 : 0, 0, 0, - font->getCharSet(), - OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, lps1); - Utils::mucc_mir_free(lps1); - - hDC = GetDC(GetDlgItem(hwndDlg, lpMis->CtlID)); - hoFont = (HFONT) SelectObject(hDC, hFont); - pszText = Translate(Options::getFontSettings(iItem)->getName()); - LPTSTR pszTextT1 = Utils::mucc_mir_a2t(pszText); - GetTextExtentPoint32(hDC, pszTextT1, lstrlen(pszTextT1), &fontSize); - Utils::mucc_mir_free(pszTextT1); - SelectObject(hDC, hoFont); - ReleaseDC(GetDlgItem(hwndDlg, lpMis->CtlID), hDC); - DeleteObject(hFont); - lpMis->itemWidth = fontSize.cx; - lpMis->itemHeight = fontSize.cy; - return TRUE; - } - break; - } - case WM_DRAWITEM: - if (wParam == IDC_FONTLIST) { - DRAWITEMSTRUCT *lpDis = (DRAWITEMSTRUCT *) lParam; - HFONT hFont; - HBRUSH hBrush; - int iItem = lpDis->itemData - 1; - Font *font = Options::getFontSettings(iItem); - if (font != NULL) { - COLORREF color = (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLORBKG, CPM_GETCOLOUR, 0, 0); - if (iItem == Options::FONT_USERLIST || iItem == Options::FONT_USERLISTGROUP) { - color = (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLORLIST, CPM_GETCOLOUR, 0, 0); - } else if (iItem == Options::FONT_TYPING) { - color = (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLORINPUT, CPM_GETCOLOUR, 0, 0); - } - hBrush = CreateSolidBrush(color); - - LPTSTR lps2 = Utils::mucc_mir_a2t(font->getFace()); - hFont = CreateFont(font->getSize(), 0, 0, 0, - font->getStyle() & Font::BOLD ? FW_BOLD : FW_NORMAL, - font->getStyle() & Font::ITALIC ? 1 : 0, - font->getStyle() & Font::UNDERLINE ? 1 : 0, 0, - font->getCharSet(), - OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, - lps2); - Utils::mucc_mir_free(lps2); - - hFont = (HFONT) SelectObject(lpDis->hDC, hFont); - SetBkMode(lpDis->hDC, TRANSPARENT); - FillRect(lpDis->hDC, &lpDis->rcItem, hBrush); - if (lpDis->itemState & ODS_SELECTED) { - FrameRect(lpDis->hDC, &lpDis->rcItem, GetSysColorBrush(COLOR_HIGHLIGHT)); - } - SetTextColor(lpDis->hDC, font->getColor()); - pszText = Translate(font->getName()); - LPTSTR pszTextT2 = Utils::mucc_mir_a2t(pszText); - TextOut(lpDis->hDC, lpDis->rcItem.left, lpDis->rcItem.top, pszTextT2, lstrlen(pszTextT2)); - Utils::mucc_mir_free(pszTextT2); - hFont = (HFONT) SelectObject(lpDis->hDC, hFont); - DeleteObject(hBrush); - DeleteObject(hFont); - } - return TRUE; - } - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COLORTXT: - { - int totalCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETCOUNT, 0, 0); - int *selItems= new int[totalCount]; - int selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, totalCount, (LPARAM) selItems); - COLORREF color = (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_GETCOLOUR, 0, 0); - for (int i=0; isetColor(color); - } - } - delete selItems; - InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, FALSE); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - } - break; - case IDC_LOGLIMIT: - if (HIWORD(wParam) == EN_CHANGE && (HWND)lParam==GetFocus()) { - i = GetDlgItemInt(hwndDlg, IDC_LOGLIMIT, NULL, FALSE); - // if (i>1000) { - // i = 1000; - // SetDlgItemInt(hwndDlg, IDC_LOGLIMIT, i, FALSE); - // } - if (i!=Options::getLogLimit()) { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - break; - case IDC_COLORBKG: - case IDC_COLORLIST: - case IDC_COLORINPUT: - InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, FALSE); - case IDC_SENDONENTER: - case IDC_USETABS: - case IDC_ENABLEIEVIEW: - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - case IDC_FONTLIST: - if (HIWORD(wParam) == LBN_SELCHANGE) { - if (SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELCOUNT, 0, 0) > 1) { - SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETCOLOUR, 0, GetSysColor(COLOR_3DFACE)); - SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_WINDOWTEXT)); - } - else { - int iItem = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, - SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETCURSEL, 0, 0), 0) - 1; - Font *font = Options::getFontSettings(iItem); - if (font != NULL) { - SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETCOLOUR, 0, font->getColor()); - SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETDEFAULTCOLOUR, 0, font->getColor()); - } - } - } - if (HIWORD(wParam) != LBN_DBLCLK) { - return TRUE; - } - case IDC_CHOOSEFONT: - { - CHOOSEFONT cf; - LOGFONT lf; - int iItem = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETCURSEL, 0, 0), 0) - 1; - ZeroMemory(&cf, sizeof(cf)); - ZeroMemory(&lf, sizeof(lf)); - Font *font = Options::getFontSettings(iItem); - if (font != NULL) { - lf.lfHeight = font->getSize(); - lf.lfWeight = font->getStyle() & Font::BOLD ? FW_BOLD : FW_NORMAL; - lf.lfItalic = font->getStyle() & Font::ITALIC ? 1 : 0; - lf.lfCharSet = DEFAULT_CHARSET; - lf.lfOutPrecision = OUT_DEFAULT_PRECIS; - lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; - lf.lfQuality = DEFAULT_QUALITY; - lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; - LPTSTR lps3 = Utils::mucc_mir_a2t(font->getFace()); - lstrcpy(lf.lfFaceName, lps3); - Utils::mucc_mir_free(lps3); - cf.lStructSize = sizeof(cf); - cf.hwndOwner = hwndDlg; - cf.lpLogFont = &lf; - cf.Flags = CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS; - if (ChooseFont(&cf)) { - int totalCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETCOUNT, 0, 0); - int *selItems= new int[totalCount]; - int selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, totalCount, (LPARAM) selItems); - for (int i=0; isetStyle((lf.lfWeight >= FW_BOLD ? Font::BOLD : 0) | (lf.lfItalic ? Font::ITALIC : 0)); - font2->setCharSet(lf.lfCharSet); - font2->setSize(lf.lfHeight); - char* lps4 = Utils::mucc_mir_t2a(lf.lfFaceName); - font2->setFace(lps4); - Utils::mucc_mir_free(lps4); - MEASUREITEMSTRUCT mis; - ZeroMemory(&mis, sizeof(mis)); - mis.CtlID = IDC_FONTLIST; - mis.itemData = iItem + 1; - SendMessage(hwndDlg, WM_MEASUREITEM, (WPARAM)IDC_FONTLIST, (LPARAM) & mis); - SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_SETITEMHEIGHT, selItems[i], mis.itemHeight); - } - } - delete selItems; - InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, TRUE); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - } - } - return TRUE; - } - break; - } - break; - case WM_DESTROY: - Options::setExpandFlags(getExpandFlags(GetDlgItem(hwndDlg, IDC_TREELIST))); - break; - case WM_NOTIFY: - { - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: - COLORREF color; - color = (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLORLIST, CPM_GETCOLOUR, 0, 0); - Options::setListBgColor(color); - color = (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLORINPUT, CPM_GETCOLOUR, 0, 0); - Options::setInputBgColor(color); - color = (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLORBKG, CPM_GETCOLOUR, 0, 0); - Options::setLogBgColor(color); - Options::setLogLimit(SendDlgItemMessage(hwndDlg, IDC_LOGLIMITSPIN, UDM_GETPOS, 0, 0)); - Options::setChatWindowOptions(getOptions(GetDlgItem(hwndDlg, IDC_TREELIST), TreeView_GetRoot(GetDlgItem(hwndDlg, IDC_TREELIST)), 0)); - Options::setChatWindowOptions(Options::getChatWindowOptions() | (IsDlgButtonChecked(hwndDlg, IDC_SENDONENTER) ? ChatWindow::FLAG_OPT_SENDONENTER : 0)); - Options::setChatWindowOptions(Options::getChatWindowOptions() | (IsDlgButtonChecked(hwndDlg, IDC_ENABLEIEVIEW) ? ChatWindow::FLAG_OPT_ENABLEIEVIEW : 0)); - Options::setChatContainerOptions(IsDlgButtonChecked(hwndDlg, IDC_USETABS) ? ChatContainer::FLAG_USE_TABS : 0); - Options::saveSettings(); - ChatWindow::refreshSettings(1); - break; - case NM_CLICK: - /* Handle checking/unchecking options here - update children and parent appropriately */ - if(((LPNMHDR)lParam)->idFrom == IDC_TREELIST) { - TVHITTESTINFO hti; - hti.pt.x = (short)LOWORD(GetMessagePos()); - hti.pt.y = (short)HIWORD(GetMessagePos()); - ScreenToClient(((LPNMHDR)lParam)->hwndFrom, &hti.pt); - if(TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom, &hti)) { - if(hti.flags&TVHT_ONITEMSTATEICON) { - TVITEM tvi = {0}; - tvi.mask = TVIF_HANDLE | TVIF_STATE; - tvi.stateMask = TVIS_STATEIMAGEMASK; - tvi.hItem = hti.hItem; - TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &tvi); - tvi.state ^= INDEXTOSTATEIMAGEMASK(3); - tvi.hItem = TreeView_GetChild(((LPNMHDR)lParam)->hwndFrom, hti.hItem); - if (tvi.hItem!=NULL) { - while(tvi.hItem != NULL) { - TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom, &tvi); - tvi.hItem=TreeView_GetNextSibling(((LPNMHDR)lParam)->hwndFrom, tvi.hItem); - } - } else { - HTREEITEM hParent = TreeView_GetParent(((LPNMHDR)lParam)->hwndFrom, hti.hItem); - if (hParent != NULL) { - if ((tvi.state>>12) == 2) { - tvi.hItem = TreeView_GetNextSibling(((LPNMHDR)lParam)->hwndFrom, hti.hItem); - while(tvi.hItem != NULL) { - TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &tvi); - if ((tvi.state>>12) != 2) { - break; - } - tvi.hItem = TreeView_GetNextSibling(((LPNMHDR)lParam)->hwndFrom, tvi.hItem); - } - if ((tvi.state>>12) == 2) { - tvi.hItem = TreeView_GetPrevSibling(((LPNMHDR)lParam)->hwndFrom, hti.hItem); - while(tvi.hItem != NULL) { - TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &tvi); - if ((tvi.state>>12) != 2) { - break; - } - tvi.hItem = TreeView_GetPrevSibling(((LPNMHDR)lParam)->hwndFrom, tvi.hItem); - } - } - } - tvi.hItem = hParent; - TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom, &tvi); - } - } - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - } - } - } - break; - } - } - break; - } - return FALSE; -} - -/* -#define POPUP_DEFAULT_COLORBKG 0xDCBDA5 -#define POPUP_DEFAULT_COLORTXT 0x000000 -static void MailPopupPreview(DWORD colorBack, DWORD colorText, char *title, char *emailInfo, int delay) -{ - POPUPDATAEX ppd; - char * lpzContactName; - char * lpzText; - - lpzContactName = title; - lpzText = emailInfo; - ZeroMemory(&ppd, sizeof(ppd)); - ppd.lchContact = NULL; - ppd.lchIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_MAIL)); - lstrcpy(ppd.lpzContactName, lpzContactName); - lstrcpy(ppd.lpzText, lpzText); - ppd.colorBack = colorBack; - ppd.colorText = colorText; - ppd.PluginWindowProc = NULL; - ppd.PluginData=NULL; - if ( ServiceExists( MS_POPUP_ADDPOPUPEX )) { - ppd.iSeconds = delay; - CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0); - - } - else if ( ServiceExists( MS_POPUP_ADDPOPUP )) { - CallService(MS_POPUP_ADDPOPUP, (WPARAM)&ppd, 0); - } -} -*/ -//static INT_PTR CALLBACK MUCCPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -//{ - /* - switch (msg) { - case WM_INITDIALOG: - { - BYTE delayMode; - CheckDlgButton(hwndDlg, IDC_ENABLEPOPUP, DBGetContactSettingByte(NULL, jabberProtoName, "MailPopupEnabled", TRUE)); - SendDlgItemMessage(hwndDlg, IDC_COLORBKG, CPM_SETCOLOUR, 0, DBGetContactSettingDword(NULL, jabberProtoName, "MailPopupBack", POPUP_DEFAULT_COLORBKG)); - SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETCOLOUR, 0, DBGetContactSettingDword(NULL, jabberProtoName, "MailPopupText", POPUP_DEFAULT_COLORTXT)); - SetDlgItemInt(hwndDlg, IDC_DELAY, DBGetContactSettingDword(NULL, jabberProtoName, "MailPopupDelay", 4), FALSE); - delayMode = DBGetContactSettingByte(NULL, jabberProtoName, "MailPopupDelayMode", 0); - if (delayMode==1) { - CheckDlgButton(hwndDlg, IDC_DELAY_CUSTOM, TRUE); - } else if (delayMode==2) { - CheckDlgButton(hwndDlg, IDC_DELAY_PERMANENT, TRUE); - } else { - CheckDlgButton(hwndDlg, IDC_DELAY_POPUP, TRUE); - } - return TRUE; - } - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_COLORTXT: - case IDC_COLORBKG: - case IDC_ENABLEPOPUP: - case IDC_DELAY: - case IDC_DELAY_POPUP: - case IDC_DELAY_CUSTOM: - case IDC_DELAY_PERMANENT: - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - case IDC_PREVIEW: - { - int delay; - if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_POPUP)) { - delay=0; - } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) { - delay=-1; - } else { - delay=GetDlgItemInt(hwndDlg, IDC_DELAY, NULL, FALSE); - } - MailPopupPreview((DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0), - (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0), - "New mail", - "From: test@test.test\nSubject: test", - delay); - } - - } - break; - - - case WM_NOTIFY: - switch (((LPNMHDR) lParam)->code) { - case PSN_APPLY: - { - BYTE delayMode; - DBWriteContactSettingByte(NULL, jabberProtoName, "MailPopupEnabled", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ENABLEPOPUP)); - DBWriteContactSettingDword(NULL, jabberProtoName, "MailPopupBack", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0)); - DBWriteContactSettingDword(NULL, jabberProtoName, "MailPopupText", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0)); - DBWriteContactSettingDword(NULL, jabberProtoName, "MailPopupDelay", (DWORD) GetDlgItemInt(hwndDlg,IDC_DELAY, NULL, FALSE)); - delayMode=0; - if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_CUSTOM)) { - delayMode=1; - } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) { - delayMode=2; - - } - DBWriteContactSettingByte(NULL, jabberProtoName, "MailPopupDelayMode", delayMode); - return TRUE; - } - } - break; - - }*/ -// return FALSE; -//} - diff --git a/!NotAdopted/Tlen/tlen_czaty/Options.h b/!NotAdopted/Tlen/tlen_czaty/Options.h deleted file mode 100644 index 90c57099d0..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/Options.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#ifndef OPTIONS_INCLUDED -#define OPTIONS_INCLUDED -#include "FontList.h" -#include "mucc.h" - -extern int MUCCOptInit(WPARAM wParam, LPARAM lParam); - -class Options:public FontList { -private: - static COLORREF colorInputBg; - static COLORREF colorLogBg; - static COLORREF colorListBg; - static HBRUSH brushInputBg; - static HBRUSH brushLogBg; - static HBRUSH brushListBg; - static int logLimit; - static int chatContainerOptions; - static int chatWindowOptions; - static COLORREF chatWindowFontColor; - static int chatWindowFont; - static int chatWindowFontSize; - static int chatWindowFontStyle; -public: - static void setListBgColor(COLORREF c); - static void setLogBgColor(COLORREF c); - static void setInputBgColor(COLORREF c); - static COLORREF getListBgColor(); - static COLORREF getLogBgColor(); - static COLORREF getInputBgColor(); - static HBRUSH getListBgBrush(); - static HBRUSH getInputBgBrush(); - static HBRUSH getLogBgBrush(); - static void setLogLimit(int l); - static int getLogLimit(); - static void setChatContainerOptions(int o); - static int getChatContainerOptions(); - static void setChatWindowOptions(int o); - static int getChatWindowOptions(); - static void setChatWindowFontColor(COLORREF o); - static COLORREF getChatWindowFontColor(); - static void setChatWindowFont(int o); - static int getChatWindowFont(); - static void setChatWindowFontSize(int o); - static int getChatWindowFontSize(); - static void setChatWindowFontStyle(int o); - static int getChatWindowFontStyle(); - static void setExpandFlags(int l); - static int getExpandFlags(); - static void init(); - static void loadSettings(); - static void saveSettings(); - -}; - -#endif diff --git a/!NotAdopted/Tlen/tlen_czaty/Utils.cpp b/!NotAdopted/Tlen/tlen_czaty/Utils.cpp deleted file mode 100644 index 53bddf4488..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/Utils.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#include "Utils.h" - -struct FORK_ARG { - HANDLE hEvent; - void (__cdecl *threadcode)(void*); - void *arg; -}; - -static void __cdecl forkthread_r(struct FORK_ARG *fa) -{ - void (*callercode)(void*) = fa->threadcode; - void *arg = fa->arg; - CallService(MS_SYSTEM_THREAD_PUSH, 0, 0); - SetEvent(fa->hEvent); - callercode(arg); - CallService(MS_SYSTEM_THREAD_POP, 0, 0); - return; -} - -unsigned long Utils::forkThread(void (__cdecl *threadcode)(void*), unsigned long stacksize, void *arg) { - - unsigned long rc; - struct FORK_ARG fa; - - fa.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - fa.threadcode = threadcode; - fa.arg = arg; - rc = _beginthread((void (__cdecl *)(void*))forkthread_r, stacksize, &fa); - if ((unsigned long) -1L != rc) { - WaitForSingleObject(fa.hEvent, INFINITE); - } - CloseHandle(fa.hEvent); - return rc; -} - -void Utils::copyString(char **a, const char *b) { - char *oldA; - char *newA; - oldA = *a; - if (b!=NULL) { - newA = new char[strlen(b)+1]; - strcpy(newA, b); - } else { - newA = NULL; - } - *a = newA; - if (oldA!=NULL) { - delete oldA; - } - -} - - - -MM_INTERFACE Utils::mmi; - -void Utils::mucc_mir_free(void* ptr) -{ - mir_free(ptr); -} - -char* Utils::mucc_mir_t2a(LPCTSTR src) -{ - return mir_t2a(src); -} - -LPTSTR Utils::mucc_mir_a2t(const char* src) -{ - return mir_a2t(src); -} - - - -void Utils::log(const char *fmt, ...) -{ -#ifdef ENABLE_LOGGING - char *str; - va_list vararg; - int strsize; - char *text; - char *p, *q; - int extra; - - va_start(vararg, fmt); - str = (char *) malloc(strsize=2048); - while (_vsnprintf(str, strsize, fmt, vararg) == -1) - str = (char *) realloc(str, strsize+=2048); - va_end(vararg); - - extra = 0; - for (p=str; *p!='\0'; p++) - if (*p=='\n' || *p=='\r') - extra++; - text = (char *) malloc(strlen(muccModuleName)+2+strlen(str)+2+extra); - wsprintf(text, "[%s]", muccModuleName); - for (p=str,q=text+strlen(text); *p!='\0'; p++,q++) { - if (*p == '\r') { - *q = '\\'; - *(q+1) = 'r'; - q++; - } - else if (*p == '\n') { - *q = '\\'; - *(q+1) = 'n'; - q++; - } - else - *q = *p; - } - *q = '\n'; - *(q+1) = '\0'; -// CallService(MS_NETLIB_LOG, (WPARAM) NULL, (LPARAM) text); - //OutputDebugString(text); - free(text); - free(str); -#endif -} - diff --git a/!NotAdopted/Tlen/tlen_czaty/Utils.h b/!NotAdopted/Tlen/tlen_czaty/Utils.h deleted file mode 100644 index 6ae4e2a44c..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/Utils.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#ifndef UTILS_INCLUDED -#define UTILS_INCLUDED -#include "mucc.h" - -class Utils { -public: - static unsigned long forkThread(void (__cdecl *threadcode)(void*),unsigned long stacksize,void *arg); - static void copyString(char **, const char *b); - static void log(const char *fmt, ...); - - static MM_INTERFACE mmi; - static void mucc_mir_free(void*); - static char* mucc_mir_t2a(LPCTSTR); - static LPTSTR mucc_mir_a2t(const char* ); - -}; - -#endif diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/admin.ico b/!NotAdopted/Tlen/tlen_czaty/icos/admin.ico deleted file mode 100644 index 9699f55d6f..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/admin.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/administration.ico b/!NotAdopted/Tlen/tlen_czaty/icos/administration.ico deleted file mode 100644 index e57884857e..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/administration.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/blank.ico b/!NotAdopted/Tlen/tlen_czaty/icos/blank.ico deleted file mode 100644 index 7845f62fed..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/blank.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/bold.ico b/!NotAdopted/Tlen/tlen_czaty/icos/bold.ico deleted file mode 100644 index 01d5adda1d..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/bold.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/chat.ico b/!NotAdopted/Tlen/tlen_czaty/icos/chat.ico deleted file mode 100644 index 0b388d8f9d..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/chat.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/delete.ico b/!NotAdopted/Tlen/tlen_czaty/icos/delete.ico deleted file mode 100644 index 59408c5337..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/delete.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/glowner.ico b/!NotAdopted/Tlen/tlen_czaty/icos/glowner.ico deleted file mode 100644 index 86fdf534e9..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/glowner.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/invite.ico b/!NotAdopted/Tlen/tlen_czaty/icos/invite.ico deleted file mode 100644 index bf7dbc4d7a..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/invite.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/italic.ico b/!NotAdopted/Tlen/tlen_czaty/icos/italic.ico deleted file mode 100644 index d34418be24..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/italic.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/message.ico b/!NotAdopted/Tlen/tlen_czaty/icos/message.ico deleted file mode 100644 index 40d183b7b3..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/message.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/next.ico b/!NotAdopted/Tlen/tlen_czaty/icos/next.ico deleted file mode 100644 index d817b06cc6..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/next.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/options.ico b/!NotAdopted/Tlen/tlen_czaty/icos/options.ico deleted file mode 100644 index 2fd2d902d9..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/options.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/owner.ico b/!NotAdopted/Tlen/tlen_czaty/icos/owner.ico deleted file mode 100644 index 27bea391f0..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/owner.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/prev.ico b/!NotAdopted/Tlen/tlen_czaty/icos/prev.ico deleted file mode 100644 index 2f171e5783..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/prev.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/r_anon.ico b/!NotAdopted/Tlen/tlen_czaty/icos/r_anon.ico deleted file mode 100644 index b5ebd0289e..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/r_anon.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/r_memb.ico b/!NotAdopted/Tlen/tlen_czaty/icos/r_memb.ico deleted file mode 100644 index 418fd9abf5..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/r_memb.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/r_mod.ico b/!NotAdopted/Tlen/tlen_czaty/icos/r_mod.ico deleted file mode 100644 index 3b9fa47f60..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/r_mod.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/registered.ico b/!NotAdopted/Tlen/tlen_czaty/icos/registered.ico deleted file mode 100644 index 3a5182b5d6..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/registered.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/save.ico b/!NotAdopted/Tlen/tlen_czaty/icos/save.ico deleted file mode 100644 index 48b0581fd5..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/save.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/search.ico b/!NotAdopted/Tlen/tlen_czaty/icos/search.ico deleted file mode 100644 index 065468e272..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/search.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/sendmail.ico b/!NotAdopted/Tlen/tlen_czaty/icos/sendmail.ico deleted file mode 100644 index 0b60bf950e..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/sendmail.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/smile.ico b/!NotAdopted/Tlen/tlen_czaty/icos/smile.ico deleted file mode 100644 index d4aea87249..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/smile.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/tlenbig.ico b/!NotAdopted/Tlen/tlen_czaty/icos/tlenbig.ico deleted file mode 100644 index 4d09293560..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/tlenbig.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/tlensmall.ico b/!NotAdopted/Tlen/tlen_czaty/icos/tlensmall.ico deleted file mode 100644 index 5204d39d21..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/tlensmall.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/icos/underline.ico b/!NotAdopted/Tlen/tlen_czaty/icos/underline.ico deleted file mode 100644 index 7709f5f7f4..0000000000 Binary files a/!NotAdopted/Tlen/tlen_czaty/icos/underline.ico and /dev/null differ diff --git a/!NotAdopted/Tlen/tlen_czaty/mucc.cpp b/!NotAdopted/Tlen/tlen_czaty/mucc.cpp deleted file mode 100644 index e5c35c070a..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/mucc.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "../commons.h" -#include "mucc.h" -#include "mucc_services.h" -#include "HelperDialog.h" -#include "Options.h" -#include "Utils.h" - -char *muccModuleName; -HINSTANCE hInst; -PLUGINLINK *pluginLink; -HANDLE hHookEvent = NULL; -HIMAGELIST hImageList = NULL; -HICON muccIcon[MUCC_ICON_TOTAL]; -static int ModulesLoaded(WPARAM wParam, LPARAM lParam); -static int PreShutdown(WPARAM wParam, LPARAM lParam); - -PLUGININFOEX pluginInfoEx = { - sizeof(PLUGININFOEX), -#ifdef _UNICODE -#ifdef _X64 - "Tlen Czaty (x64, Unicode)", -#else - "Tlen Czaty (Unicode)", -#endif -#else - "Tlen Czaty", -#endif - PLUGIN_MAKE_VERSION(MUCC_MAJOR_VERSION,MUCC_MINOR_VERSION,MUCC_RELEASE_NUM,MUCC_BUILD_NUM), - "Group chats GUI plugin for Miranda IM (formerly known as mucc.dll) (version: "MUCC_VERSION_STRING" ; compiled: "__DATE__" "__TIME__")", - "Piotr Piastucki", - "the_leech@users.berlios.de", - "(c) 2004-2012 Piotr Piastucki", - "http://mtlen.berlios.de", - 0, - 0, -#if defined( _UNICODE ) -#ifdef _X64 - {0x9061ae31, 0x3d33, 0x49ce, { 0xaf, 0x00, 0x78, 0x9c, 0xbc, 0x25, 0xd9, 0xba }} -#else - {0xadd9390c, 0x1dd4, 0x4c0d, { 0x9b, 0xa9, 0xcc, 0x76, 0x5d, 0x3d, 0xe5, 0x97 }} -#endif -#else - {0x5cf4792c, 0xa050, 0x46b6, { 0xaf, 0xd0, 0x03, 0x2d, 0x6e, 0xfc, 0xd3, 0x9c }} -#endif -}; - -extern "C" BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpvReserved) -{ - hInst = hModule; - return TRUE; -} - -extern "C" __declspec(dllexport) PLUGININFOEX *MirandaPluginInfoEx(DWORD mirandaVersion) -{ - if (mirandaVersion < PLUGIN_MAKE_VERSION(0,8,0,15)) { - MessageBox(NULL, _TEXT("The Tlen Czaty plugin cannot be loaded. It requires Miranda IM 0.8.15 or later."), _TEXT("Tlen Czaty plugin (MUCC)"), MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_TOPMOST); - return NULL; - } - return &pluginInfoEx; -} - -#ifndef MIID_TLEN_MUCC -#define MIID_TLEN_MUCC { 0xba658997, 0x0bce, 0x4f96, { 0xba, 0x48, 0x54, 0x55, 0x34, 0x16, 0x73, 0xea } } -#endif - -extern "C" __declspec(dllexport) const MUUID interfaces[] = { - MIID_TLEN_MUCC, - MIID_LAST - }; - -extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} - - -static void LoadIcons() { - int i; - static int iconList[] = { - IDI_CHAT, - IDI_GLOBALOWNER, - IDI_OWNER, - IDI_ADMIN, - IDI_REGISTERED, - IDI_R_MODERATED, - IDI_R_MEMBERS, - IDI_R_ANONYMOUS, - IDI_PREV, - IDI_NEXT, - IDI_SEARCH, - IDI_BOLD, - IDI_ITALIC, - IDI_UNDERLINE, - IDI_OPTIONS, - IDI_INVITE, - IDI_ADMINISTRATION, - IDI_SMILEY, - IDI_MESSAGE - - }; - for (i=0; i -#include -#include -#include -#include -#include -#include -#include - -#ifdef __MINGW32__ -#define EM_SETTEXTEX (WM_USER + 97) -#define ST_DEFAULT 0 -#define ST_KEEPUNDO 1 -#define ST_SELECTION 2 -#define ST_NEWCHARS 4 -#else -#include -#endif - -#define MIRANDA_VER 0x0700 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "resource.h" - -enum { - MUCC_IDI_CHAT = 0, - MUCC_IDI_U_GLOBALOWNER, - MUCC_IDI_U_OWNER, - MUCC_IDI_U_ADMIN, - MUCC_IDI_U_REGISTERED, - MUCC_IDI_R_MODERATED, - MUCC_IDI_R_MEMBERS, - MUCC_IDI_R_ANONYMOUS, - MUCC_IDI_PREV, - MUCC_IDI_NEXT, - MUCC_IDI_SEARCH, - MUCC_IDI_BOLD, - MUCC_IDI_ITALIC, - MUCC_IDI_UNDERLINE, - MUCC_IDI_OPTIONS, - MUCC_IDI_INVITE, - MUCC_IDI_ADMINISTRATION, - MUCC_IDI_SMILEY, - MUCC_IDI_MESSAGE, - MUCC_ICON_TOTAL - -}; - -extern PLUGINLINK * pluginLink; -extern char *muccModuleName; -extern HINSTANCE hInst; -extern HANDLE hHookEvent; -extern HIMAGELIST hImageList; -extern HICON muccIcon[MUCC_ICON_TOTAL]; - -#include "m_mucc.h" - -#define WM_MUCC_REFRESH_ROOMS (WM_USER+101) -#define WM_MUCC_REFRESH_USER_ROOMS (WM_USER+102) -#define WM_MUCC_REFRESH_USER_NICKS (WM_USER+103) - -#endif - diff --git a/!NotAdopted/Tlen/tlen_czaty/mucc.rc b/!NotAdopted/Tlen/tlen_czaty/mucc.rc deleted file mode 100644 index d50a834649..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/mucc.rc +++ /dev/null @@ -1,579 +0,0 @@ -#include "resource.h" -#include "../commons.h" -#ifdef __MINGW32__ - #define WINVER 0x500 - #define _WIN32_IE 0x500 - #include - #ifndef IDC_STATIC - #define IDC_STATIC (-1) -#endif -#else -// #define APSTUDIO_READONLY_SYMBOLS -// #include "winres.h" -// #undef APSTUDIO_READONLY_SYMBOLS - #include - #ifndef IDC_STATIC - #define IDC_STATIC (-1) - #endif -#endif -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif -#ifdef APSTUDIO_INVOKED - -1 TEXTINCLUDE DISCARDABLE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE DISCARDABLE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE DISCARDABLE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -IDR_CHATOPTIONS MENU DISCARDABLE -BEGIN - POPUP "", MENUBREAK - BEGIN - POPUP "Log Appearance" - BEGIN - MENUITEM "Show Nicknames", ID_OPTIONMENU_SHOWNICKNAMES - MENUITEM "Show Message On A New Line", ID_OPTIONMENU_MSGINNEWLINE - END - POPUP "Timestamp Settings" - BEGIN - MENUITEM "Show Date", ID_OPTIONMENU_SHOWDATE - MENUITEM "Show Timestamp", ID_OPTIONMENU_SHOWTIMESTAMP - MENUITEM "Show Seconds", ID_OPTIONMENU_SHOWSECONDS - MENUITEM "Use Long Date Format", ID_OPTIONMENU_USELONGDATE - - END - POPUP "Text Formatting Filter" - BEGIN - MENUITEM "Font Name", ID_OPTIONMENU_FORMATFONT - MENUITEM "Font Size", ID_OPTIONMENU_FORMATSIZE - MENUITEM "Font Style", ID_OPTIONMENU_FORMATSTYLE - MENUITEM "Font Color", ID_OPTIONMENU_FORMATCOLOR - END - POPUP "Event Filter" - BEGIN - MENUITEM "Messages", ID_OPTIONMENU_LOGMESSAGES - MENUITEM "User Has Joined", ID_OPTIONMENU_LOGJOINED - MENUITEM "User Has Left", ID_OPTIONMENU_LOGLEFT - MENUITEM "Topic Changes", ID_OPTIONMENU_LOGTOPIC - END - POPUP "Window Flashing" - BEGIN - MENUITEM "Messages", ID_OPTIONMENU_FLASHMESSAGES - MENUITEM "User Has Joined", ID_OPTIONMENU_FLASHJOINED - MENUITEM "User Has Left", ID_OPTIONMENU_FLASHLEFT - MENUITEM "Topic Changes", ID_OPTIONMENU_FLASHTOPIC - END - MENUITEM SEPARATOR - MENUITEM "Save Settings As Default", ID_OPTIONMENU_SAVEDEFAULT - MENUITEM SEPARATOR - MENUITEM "User Administration", ID_ADMINMENU_ADMIN, GRAYED - MENUITEM "Destroy Chat Room", ID_ADMINMENU_DESTROY, GRAYED - MENUITEM SEPARATOR - MENUITEM "Save Log", ID_ADMINMENU_SAVELOG - END - POPUP "", MENUBREAK - BEGIN - MENUITEM "Message", ID_USERMENU_MESSAGE - MENUITEM SEPARATOR - POPUP "Kick && Ban", GRAYED - BEGIN - MENUITEM "No Ban", ID_USERMENU_KICK_NO_BAN - MENUITEM "Ban For 1 Minute", ID_USERMENU_KICK_BAN_1_MIN - MENUITEM "Ban For 5 Minutes", ID_USERMENU_KICK_BAN_5_MIN - MENUITEM "Ban For 15 Minutes", ID_USERMENU_KICK_BAN_15_MIN - MENUITEM "Ban For 30 Minutes", ID_USERMENU_KICK_BAN_15_MIN - MENUITEM "Ban For 1 Hour", ID_USERMENU_KICK_BAN_1_H - MENUITEM "Ban For 6 Hours", ID_USERMENU_KICK_BAN_6_H - MENUITEM "Ban For 1 Day", ID_USERMENU_KICK_BAN_1_D - MENUITEM "Ban For 3 Days", ID_USERMENU_KICK_BAN_3_D - MENUITEM "Ban For 1 Week", ID_USERMENU_KICK_BAN_1_W - MENUITEM "Ban For 2 Weeks", ID_USERMENU_KICK_BAN_2_W - MENUITEM "Ban For 4 Weeks", ID_USERMENU_KICK_BAN_4_W - END - POPUP "Change User Role", GRAYED - BEGIN - MENUITEM "No Role", ID_USERMENU_RIGHTS_NO - MENUITEM "Member", ID_USERMENU_RIGHTS_MEMBER - - MENUITEM "Admin", ID_USERMENU_RIGHTS_ADMIN - END - MENUITEM "User Administration", ID_USERMENU_ADMINISTRATION, GRAYED - END - POPUP "", MENUBREAK - BEGIN - MENUITEM "Unban", ID_USERMENU_UNBAN - END -END - -IDR_CONTEXT MENU DISCARDABLE -BEGIN - POPUP "Log" - BEGIN - MENUITEM "&Copy", IDM_COPY - MENUITEM "Co&py All", IDM_COPYALL - MENUITEM SEPARATOR - MENUITEM "Select &All", IDM_SELECTALL - MENUITEM SEPARATOR - MENUITEM "C&lear Log", IDM_CLEAR - END - POPUP "LogLink" - BEGIN - MENUITEM "Open in &new window", IDM_OPENNEW - MENUITEM "&Open in existing window", IDM_OPENEXISTING - MENUITEM "&Copy link", IDM_COPYLINK - END - POPUP "Message" - BEGIN - MENUITEM "Undo", IDM_UNDO - MENUITEM "Redo", IDM_REDO - MENUITEM SEPARATOR - MENUITEM "Cut", IDM_CUT - MENUITEM "Copy", IDM_COPY - MENUITEM "Paste", IDM_PASTE - MENUITEM "Delete", IDM_DELETE - MENUITEM SEPARATOR - MENUITEM "Select &All", IDM_SELECTALL - END -END - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_OPTIONS DIALOGEX 0, 0, 320, 260 -STYLE DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "Fonts",IDC_FONTSGB,169,10,143,182 - LTEXT "Background color",IDC_STATIC,175,23,100,8 - CONTROL "",IDC_COLORBKG,"ColourPicker",WS_TABSTOP,277,21,29,12 - LTEXT "Input area background",IDC_STATIC,175,38,100,8 - CONTROL "",IDC_COLORINPUT,"ColourPicker",WS_TABSTOP,277,36,29,12 - LTEXT "User list background",IDC_STATIC,175,53,100,8 - CONTROL "",IDC_COLORLIST,"ColourPicker",WS_TABSTOP,277,51,29,12 - LISTBOX IDC_FONTLIST,175,69,131,95,LBS_OWNERDRAWVARIABLE | - LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL | - WS_TABSTOP - CONTROL "",IDC_COLORTXT,"ColourPicker",WS_TABSTOP,175,170,55,15 - PUSHBUTTON "Choose font",IDC_CHOOSEFONT,251,170,55,15 - GROUPBOX "Options",IDC_OPTIONSGB,5,10,158,182 - CONTROL "",IDC_TREELIST,"SysTreeView32",TVS_HASBUTTONS | - TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP,11, - 23,146,162,WS_EX_STATICEDGE - GROUPBOX "Other",IDC_SIMPLE,5,193,310,57 - CONTROL "Use tabbed mode",IDC_USETABS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,13,206,140,10 - CONTROL "Enable IEView",IDC_ENABLEIEVIEW,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,13,219,140,10 - CONTROL "Send message on 'Enter'",IDC_SENDONENTER,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,13,232,140,10 - LTEXT "Limit log history to (events):",IDC_STATIC,153,234,110,8 - EDITTEXT IDC_LOGLIMIT,263,232,40,14,ES_RIGHT | ES_NUMBER - CONTROL "",IDC_LOGLIMITSPIN,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | - UDS_NOTHOUSANDS | UDS_HOTTRACK,390,218,11,14 -END - -IDD_CHATMANAGER DIALOGEX 0, 0, 473, 234 -STYLE DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | - WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | - WS_THICKFRAME -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Chats" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "Tab1",IDC_TABS,"SysTabControl32",TCS_BUTTONS | - TCS_FIXEDWIDTH | 0x8,214,7,252,20 - PUSHBUTTON "Close",IDCLOSE,416,215,50,14 - CONTROL "Tree1",IDC_GROUP,"SysTreeView32",TVS_HASBUTTONS | - TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | - TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS,5,20,203,209, - WS_EX_STATICEDGE - LTEXT "Groups",IDC_STATIC,7,9,24,8 -END - -IDD_GROUPCHAT_CONTAINER DIALOGEX 0, 0, 300, 200 -STYLE DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | - WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | - WS_THICKFRAME -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Tlen Group Chat" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "",IDC_TABS,"SysTabControl32", WS_CLIPSIBLINGS | TCS_MULTILINE | TCS_FOCUSNEVER | 0x8,0,0,300,200 -END - -IDD_GROUPCHAT_LOG DIALOGEX 0, 0, 294, 178 -STYLE DS_FIXEDSYS | WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN -/* -STYLE DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | - WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | - WS_THICKFRAME - */ -//EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "",IDC_VSPLIT,"Static",SS_ENHMETAFILE,237,20,3,117 - CONTROL "",IDC_HSPLIT,"Static",SS_ENHMETAFILE,156,285,2,0 - CONTROL "",IDC_LOG,"RichEdit20A",WS_VSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS | 0x844, - 3,21,233,117,WS_EX_STATICEDGE - CONTROL "",IDC_TREELIST,"SysTreeView32",TVS_DISABLEDRAGDROP | - TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS | TVS_NONEVENHEIGHT,5, - 20,203,209,WS_EX_STATICEDGE - EDITTEXT IDC_EDIT,3,158,285,13,ES_MULTILINE | ES_AUTOVSCROLL | - NOT WS_BORDER | WS_VSCROLL | ES_WANTRETURN,WS_EX_STATICEDGE - CONTROL "Topic",IDC_TOPIC_BUTTON,"MButtonClass",WS_DISABLED | - WS_TABSTOP,3,3,34,12,0x18000000L - CONTROL "",IDC_BOLD,"MButtonClass",WS_TABSTOP,3,140,16,16, - 0x18000000L - CONTROL "",IDC_ITALIC,"MButtonClass",WS_TABSTOP,21,140,16,16, - 0x18000000L - CONTROL "",IDC_UNDERLINE,"MButtonClass",WS_TABSTOP,39,140,16,16, - 0x18000000L - CONTROL "",IDC_COLOR,"ColourPicker",WS_TABSTOP,57,140,16,16 - COMBOBOX IDC_FONTSIZE,154,142,27,80,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - CONTROL "",IDC_SMILEYBTN,"MButtonClass", WS_TABSTOP,185,140,16,16, - 0x18000000L - CONTROL "Invite",IDC_INVITE,"MButtonClass",WS_TABSTOP,259,141,16, - 16,0x18000000L - EDITTEXT IDC_TOPIC,70,19,86,12,ES_AUTOHSCROLL | ES_READONLY | NOT - WS_BORDER - CONTROL "",IDC_OPTIONS,"MButtonClass",WS_TABSTOP,208,140,16,16, - 0x18000000L - COMBOBOX IDC_FONT,77,142,74,90,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - PUSHBUTTON "Close",IDCANCEL,0,0,20,20,NOT WS_VISIBLE - //,NOT WS_VISIBLE -END - -IDD_HELPER_JOIN DIALOGEX 0, 0, 186, 79 -STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | - WS_POPUP | WS_VISIBLE | WS_CAPTION -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Join Tlen Multi-User Conference Room" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Room:",IDC_ROOM_LABEL,10,13,43,8 - EDITTEXT IDC_ROOM,54,12,119,12,ES_AUTOHSCROLL - LTEXT "Nickname:",IDC_NICK_LABEL,10,30,40,8 - EDITTEXT IDC_NICK,54,29,119,12,ES_AUTOHSCROLL - DEFPUSHBUTTON "&Join",IDOK,75,59,50,14 - PUSHBUTTON "Cancel",IDCANCEL,129,59,50,14 - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,7,50,172,4 -END - -IDD_HELPER_INVITE DIALOG DISCARDABLE 0, 0, 186, 79 -STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | - WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Invite a User" -FONT 8, "MS Shell Dlg" -BEGIN - LTEXT "User:",IDC_STATIC,10,13,43,8 - COMBOBOX IDC_USER,54,10,119,120,CBS_DROPDOWN | CBS_AUTOHSCROLL | - CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Reason:",IDC_STATIC,10,30,40,8 - EDITTEXT IDC_REASON,54,29,119,12,ES_AUTOHSCROLL - DEFPUSHBUTTON "&Invite",IDC_INVITE,75,59,50,14 - PUSHBUTTON "Cancel",IDCANCEL,129,59,50,14 - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,7,50,172,4 -END - -IDD_HELPER_INVITE_ACCEPT DIALOG DISCARDABLE 0, 0, 232, 112 -STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | - WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Multi-User Conference Invitation" -FONT 8, "MS Shell Dlg" -BEGIN - DEFPUSHBUTTON "&Accept",IDC_ACCEPT,124,93,50,14 - PUSHBUTTON "Cancel",IDCANCEL,178,93,50,14 - LTEXT "From:",IDC_STATIC,33,24,63,8 - LTEXT "Room:",IDC_STATIC,33,38,63,8 - LTEXT "Reason:",IDC_STATIC,33,52,63,8 - LTEXT "Nickname:",IDC_STATIC,33,76,62,8 - LTEXT "The following invitation to join a multi-user conference is received.", - IDC_STATIC,3,4,225,8 - EDITTEXT IDC_FROM,99,22,105,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_ROOM,99,36,105,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_REASON,99,50,105,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_NICK,99,74,105,12,ES_AUTOHSCROLL - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,3,65,225,4 -END - -IDD_HELPER_TOPIC DIALOGEX 0, 0, 223, 44 -STYLE DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | - WS_VISIBLE | WS_CAPTION -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Change Chat Room Topic" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "New topic:",IDC_STATIC,10,8,43,8 - EDITTEXT IDC_TOPIC,54,7,160,12,ES_AUTOHSCROLL - DEFPUSHBUTTON "OK",IDOK,108,26,50,14 - PUSHBUTTON "Cancel",IDCANCEL,164,26,50,14 -END - -IDD_USER_ADMIN DIALOG DISCARDABLE 0, 0, 300, 180 -STYLE DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | - WS_VISIBLE | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Chat Room Administration" -FONT 8, "MS Sans Serif" -BEGIN - CONTROL "Tab1",IDC_TABS,"SysTabControl32",TCS_BUTTONS | - TCS_FIXEDWIDTH | 0x8,0,5,220,20 - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,20,300,4 - PUSHBUTTON "Close",IDCANCEL,230,162,60,16 - -END - -IDD_USER_KICK DIALOGEX 0, 30, 300, 130 -STYLE WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Nickname:",IDC_STATIC,30,6,70,10 - EDITTEXT IDC_NICK,100,6,100,12,ES_AUTOHSCROLL | WS_TABSTOP - LTEXT "Ban for:",IDC_STATIC,30,35,70,10 - COMBOBOX IDC_KICK_OPTIONS,100,35,90,150,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "Reason:",IDC_STATIC,30,51,70,10 - EDITTEXT IDC_REASON,100,51,100,12,ES_AUTOHSCROLL | WS_TABSTOP - CONTROL "Kick && Ban",IDOK,"MButtonClass",WS_TABSTOP,210,65,60,16 - - LTEXT "User role:",IDC_STATIC,30,90,70,10 - COMBOBOX IDC_ROLE_OPTIONS,100,90,90,60,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - CONTROL "Set Role",IDC_SET_ROLE,"MButtonClass",WS_TABSTOP,210,104,60,16 - - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,128,300,4 -END - -IDD_USER_ROLE DIALOGEX 0, 30, 300, 130 -STYLE WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Nickname:",IDC_STATIC,30,25,70,10 - EDITTEXT IDC_NICK,100,25,100,12,ES_AUTOHSCROLL | WS_TABSTOP - LTEXT "User role:",IDC_STATIC,30,41,70,10 - COMBOBOX IDC_OPTIONS,100,41,90,60,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - CONTROL "Set Role",IDOK,"MButtonClass",WS_TABSTOP,120,90,60,16 - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,128,300,4 -END - -IDD_USER_BROWSER DIALOGEX 0, 30, 300, 130 -STYLE WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - COMBOBOX IDC_OPTIONS,50,0,90,60,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - CONTROL "Show",IDC_SHOW,"MButtonClass",WS_TABSTOP,160,0,50,14 - CONTROL "List1",IDC_LIST,"SysListView32",LVS_REPORT | - LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_AUTOARRANGE | - LVS_OWNERDRAWFIXED | WS_TABSTOP,0,20,299,110, - WS_EX_CLIENTEDGE -END - -IDD_OPT_POPUPS DIALOG DISCARDABLE 0, 0, 317, 141 -STYLE WS_CHILD -FONT 8, "MS Sans Serif" -BEGIN - GROUPBOX "Delay",IDC_STATIC,160,46,137,55 - CONTROL "&From PopUp plugin",IDC_DELAY_POPUP,"Button", - BS_AUTORADIOBUTTON,167,60,125,10 - CONTROL "&Custom",IDC_DELAY_CUSTOM,"Button",BS_AUTORADIOBUTTON, - 167,73,98,10 - CONTROL "P&ermanent",IDC_DELAY_PERMANENT,"Button", - BS_AUTORADIOBUTTON,167,87,123,10 - EDITTEXT IDC_DELAY,270,71,21,14,ES_AUTOHSCROLL | ES_NUMBER - GROUPBOX "Colours",IDC_STATIC,15,46,137,55 - LTEXT "Background",IDC_STATIC,53,63,95,8 - LTEXT "Text",IDC_STATIC,53,82,96,8 - CONTROL "",IDC_COLORBKG,"ColourPicker",WS_TABSTOP,23,61,24,12 - GROUPBOX "General Options",IDC_STATIC,15,15,282,26 - CONTROL "",IDC_COLORTXT,"ColourPicker",WS_TABSTOP,23,79,24,12 - PUSHBUTTON "Preview",IDC_PREVIEW,132,112,50,14 - CONTROL "Enable incoming mail notification",IDC_ENABLEPOPUP, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,26,130,10 -END - -IDD_TAB_CHATROOMS DIALOGEX 216, 28, 247, 180 -STYLE WS_CHILD -FONT 8, "MS Sans Serif", 0, 0, 0x1 -BEGIN - CONTROL "List1",IDC_ROOM,"SysListView32",LVS_REPORT | - LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_AUTOARRANGE | - LVS_OWNERDRAWFIXED | WS_TABSTOP,0,26,247,154, - WS_EX_CLIENTEDGE - CONTROL "prev",IDC_PREV,"MButtonClass",WS_TABSTOP,5,6,20,16 - CONTROL "next",IDC_NEXT,"MButtonClass",WS_TABSTOP,35,6,20,16 - CONTROL "find",IDC_SEARCH,"MButtonClass",WS_TABSTOP,65,6,20,16 -END - -IDD_TAB_MYROOMS DIALOGEX 216, 28, 244, 180 -STYLE WS_CHILD -FONT 8, "MS Sans Serif", 0, 0, 0x1 -BEGIN - CONTROL "Create",IDC_REGISTER,"MButtonClass",WS_TABSTOP,186,62, - 50,14,0x18000000L - EDITTEXT IDC_NAME,84,20,149,14,ES_AUTOHSCROLL - LTEXT "Room name:",IDC_STATIC,14,23,60,8 - CONTROL "Permanent",IDC_CHECK_PERMANENT,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,111,40,89,10 - CONTROL "Nicknames",IDC_CHECK_NICKNAMES,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,13,52,89,10 - CONTROL "Public",IDC_CHECK_PUBLIC,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,13,40,89,10 - CONTROL "Members only",IDC_CHECK_MEMBERS,"Button", - BS_AUTOCHECKBOX,111,52,89,10 - LTEXT "Chat rooms:",IDC_STATIC,2,90,100,8 - /* - CONTROL "Tree1",IDC_LIST,"SysTreeView32",TVS_DISABLEDRAGDROP | - TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS | TVS_FULLROWSELECT | - TVS_NONEVENHEIGHT,0,100,177,80,WS_EX_STATICEDGE - */ - CONTROL "Refresh",IDC_REFRESH,"MButtonClass",WS_TABSTOP,186,160, - 50,14,0x18000000L - GROUPBOX "New chat room",IDC_STATIC,0,5,244,78 - CONTROL "List1",IDC_LIST,"SysListView32",LVS_REPORT | - LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_AUTOARRANGE | - LVS_NOCOLUMNHEADER | LVS_OWNERDRAWFIXED | WS_TABSTOP,0,100,177,80, - WS_EX_CLIENTEDGE -END - -IDD_TAB_MYNICKNAMES DIALOG DISCARDABLE 216, 28, 244, 180 -STYLE WS_CHILD -FONT 8, "MS Sans Serif" -BEGIN - CONTROL "Register",IDC_REGISTER,"MButtonClass",WS_TABSTOP,186,62, - 50,14,0x18000000L - EDITTEXT IDC_NICK,84,20,149,14,ES_AUTOHSCROLL - LTEXT "Nickname:",IDC_STATIC,14,23,60,8 - LTEXT "Nicknames:",IDC_STATIC,2,90,100,8 - CONTROL "Remove",IDC_REMOVE,"MButtonClass",WS_TABSTOP,186,110,50, - 14,0x18000000L - CONTROL "Refresh",IDC_REFRESH,"MButtonClass",WS_TABSTOP,186,160, - 50,14,0x18000000L - GROUPBOX "New nickname",IDC_STATIC,0,5,244,78 - CONTROL "List1",IDC_LIST,"SysListView32",LVS_REPORT | - LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_AUTOARRANGE | - LVS_NOCOLUMNHEADER | LVS_OWNERDRAWFIXED | WS_TABSTOP,0,100,177,80, - WS_EX_CLIENTEDGE - /* - CONTROL "Tree1",IDC_LIST,"SysTreeView32",TVS_DISABLEDRAGDROP | - TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS | TVS_FULLROWSELECT | - TVS_NONEVENHEIGHT,0,100,177,80,WS_EX_STATICEDGE - */ -END - - -#ifndef _MAC -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION MUCC_FILEVERSION_STRING - PRODUCTVERSION MUCC_FILEVERSION_STRING - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "041504e3" - BEGIN - VALUE "Comments", "\0" - VALUE "CompanyName", "http://mtlen.berlios.de\0" - VALUE "FileDescription", "Group Chats GUI Plugin for Miranda IM\0" - VALUE "FileVersion", MUCC_VERSION_STRING - VALUE "InternalName", "tlen_chat\0" - VALUE "LegalCopyright", "Copyright (c) 2004-2006 Piotr Piastucki\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "tlen_chat.dll\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "Tlen Chat Plugin\0" - VALUE "ProductVersion", MUCC_VERSION_STRING - VALUE "SpecialBuild", "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x415, 1251 - END -END - -#endif // !_MAC - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_CHAT ICON DISCARDABLE "icos\\chat.ico" -IDI_BLANK ICON DISCARDABLE "icos\\blank.ico" -IDI_ITALIC ICON DISCARDABLE "icos\\italic.ico" -IDI_BOLD ICON DISCARDABLE "icos\\bold.ico" -IDI_UNDERLINE ICON DISCARDABLE "icos\\underline.ico" -IDI_OPTIONS ICON DISCARDABLE "icos\\options.ico" -IDI_OWNER ICON DISCARDABLE "icos\\owner.ico" -IDI_GLOBALOWNER ICON DISCARDABLE "icos\\glowner.ico" -IDI_ADMIN ICON DISCARDABLE "icos\\admin.ico" -IDI_REGISTERED ICON DISCARDABLE "icos\\registered.ico" -IDI_R_MODERATED ICON DISCARDABLE "icos\\r_mod.ico" -IDI_R_MEMBERS ICON DISCARDABLE "icos\\r_memb.ico" -IDI_R_ANONYMOUS ICON DISCARDABLE "icos\\r_anon.ico" -IDI_SEARCH ICON DISCARDABLE "icos\\search.ico" -IDI_PREV ICON DISCARDABLE "icos\\prev.ico" -IDI_NEXT ICON DISCARDABLE "icos\\next.ico" -IDI_INVITE ICON DISCARDABLE "icos\\invite.ico" -IDI_ADMINISTRATION ICON DISCARDABLE "icos\\administration.ico" -IDI_SMILEY ICON DISCARDABLE "icos\\smile.ico" -IDI_MESSAGE ICON DISCARDABLE "icos\\message.ico" -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/!NotAdopted/Tlen/tlen_czaty/mucc.vcxproj b/!NotAdopted/Tlen/tlen_czaty/mucc.vcxproj deleted file mode 100644 index c2fe6e7b70..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/mucc.vcxproj +++ /dev/null @@ -1,1245 +0,0 @@ -п»ї - - - - Debug Ansi - Win32 - - - Debug Ansi - x64 - - - Debug Unicode - Win32 - - - Debug Unicode - x64 - - - Debug x64 - Win32 - - - Debug x64 - x64 - - - Release Ansi - Win32 - - - Release Ansi - x64 - - - Release Unicode - Win32 - - - Release Unicode - x64 - - - Release x64 - Win32 - - - Release x64 - x64 - - - - {BD1D155A-7A47-4414-80A3-CCCC3C5C583B} - - - - DynamicLibrary - false - Unicode - Windows7.1SDK - - - DynamicLibrary - false - Unicode - Windows7.1SDK - - - DynamicLibrary - false - Unicode - Windows7.1SDK - - - DynamicLibrary - false - Unicode - Windows7.1SDK - - - DynamicLibrary - false - MultiByte - Windows7.1SDK - - - DynamicLibrary - false - MultiByte - Windows7.1SDK - - - DynamicLibrary - false - Unicode - Windows7.1SDK - true - - - DynamicLibrary - false - Unicode - Windows7.1SDK - true - - - DynamicLibrary - false - Unicode - Windows7.1SDK - true - - - DynamicLibrary - false - Unicode - Windows7.1SDK - true - - - DynamicLibrary - false - MultiByte - Windows7.1SDK - true - - - DynamicLibrary - false - MultiByte - Windows7.1SDK - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\Obj\ - $(Configuration)\Obj\ - $(Configuration)\Obj\ - $(Configuration)\Obj\ - $(Configuration)\Obj\ - $(Configuration)\Obj\ - true - true - true - true - true - true - false - false - false - false - false - false - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\Obj\ - $(Configuration)\Obj\ - $(Configuration)\Obj\ - $(Configuration)\Obj\ - $(Configuration)\Obj\ - $(Configuration)\Obj\ - true - true - true - true - true - true - true - true - true - true - true - true - tlen_czaty - tlen_czaty - tlen_czaty - tlen_czaty - tlen_czaty - tlen_czaty - tlen_czaty - tlen_czaty - tlen_czaty - tlen_czaty - tlen_czaty - tlen_czaty - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Release/mucc.tlb - - - - - MaxSpeed - OnlyExplicitInline - ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;_X64;X64;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - $(IntDir)$(TargetName).pch - - - $(IntDir) - $(IntDir)vc$(PlatformToolsetVersion).pdb - Level3 - true - 4996;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0415 - - - odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - $(TargetDir)tlen_czaty.pdb - 0x32600000 - false - - - $(IntDir)$(TargetName).lib - MachineX86 - true - - - true - $(OutDir)$(TargetName).bsc - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - .\Release/mucc.tlb - - - - - MaxSpeed - OnlyExplicitInline - ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;UNICODE;_UNICODE;_X64;X64;%(PreprocessorDefinitions) - true - MultiThreaded - true - $(IntDir)$(TargetName).pch - - - $(IntDir) - $(IntDir)vc$(PlatformToolsetVersion).pdb - Level3 - true - 4996;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0415 - - - odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - $(TargetDir)tlen_czaty.pdb - 0x32600000 - false - - - $(IntDir)$(TargetName).lib - true - - - true - $(OutDir)$(TargetName).bsc - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Release/mucc.tlb - - - - - MaxSpeed - OnlyExplicitInline - ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;%(PreprocessorDefinitions) - true - MultiThreaded - true - $(IntDir)$(TargetName).pch - - - $(IntDir) - $(IntDir)vc$(PlatformToolsetVersion).pdb - Level3 - true - 4996;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0415 - - - odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - $(TargetDir)tlen_czaty.pdb - 0x32600000 - false - - - $(IntDir)$(TargetName).lib - MachineX86 - true - - - true - $(OutDir)$(TargetName).bsc - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - .\Release/mucc.tlb - - - - - MaxSpeed - OnlyExplicitInline - ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;UNICODE;_UNICODE;%(PreprocessorDefinitions) - true - MultiThreaded - true - $(IntDir)$(TargetName).pch - - - $(IntDir) - $(IntDir)vc$(PlatformToolsetVersion).pdb - Level3 - true - 4996;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0415 - - - odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - $(TargetDir)tlen_czaty.pdb - 0x32600000 - false - - - $(IntDir)$(TargetName).lib - true - - - true - $(OutDir)$(TargetName).bsc - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Release/mucc.tlb - - - - - MaxSpeed - OnlyExplicitInline - ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;%(PreprocessorDefinitions) - true - MultiThreaded - true - $(IntDir)$(TargetName).pch - - - $(IntDir) - $(IntDir)vc$(PlatformToolsetVersion).pdb - Level3 - true - ProgramDatabase - 4996;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0415 - - - odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - $(TargetDir)tlen_czaty.pdb - 0x32600000 - false - - - $(IntDir)$(TargetName).lib - MachineX86 - true - - - true - $(OutDir)$(TargetName).bsc - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - .\Release/mucc.tlb - - - - - MaxSpeed - OnlyExplicitInline - ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;%(PreprocessorDefinitions) - true - MultiThreaded - true - $(IntDir)$(TargetName).pch - - - $(IntDir) - $(IntDir)vc$(PlatformToolsetVersion).pdb - Level3 - true - ProgramDatabase - 4996;%(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0415 - - - odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - $(TargetDir)tlen_czaty.pdb - 0x32600000 - false - - - $(IntDir)$(TargetName).lib - true - - - true - $(OutDir)$(TargetName).bsc - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Debug/mucc.tlb - - - - - Disabled - ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;X64;_X64;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - $(IntDir)$(TargetName).pch - - - $(IntDir) - $(IntDir)vc$(PlatformToolsetVersion).pdb - Level3 - true - EditAndContinue - 4996;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0415 - - - odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - true - $(TargetDir)tlen_czaty.pdb - false - - - $(IntDir)$(TargetName).lib - MachineX86 - - - true - $(OutDir)$(TargetName).bsc - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - .\Debug/mucc.tlb - - - - - Disabled - ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;UNICODE;_UNICODE;X64;_X64;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - $(IntDir)$(TargetName).pch - - - $(IntDir) - $(IntDir)vc$(PlatformToolsetVersion).pdb - Level3 - true - ProgramDatabase - 4996;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0415 - - - odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - true - $(TargetDir)tlen_czaty.pdb - false - - - $(IntDir)$(TargetName).lib - - - true - $(OutDir)$(TargetName).bsc - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Debug/mucc.tlb - - - - - Disabled - ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - $(IntDir)$(TargetName).pch - - - $(IntDir) - $(IntDir)vc$(PlatformToolsetVersion).pdb - Level3 - true - EditAndContinue - 4996;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0415 - - - odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - true - $(TargetDir)tlen_czaty.pdb - false - - - $(IntDir)$(TargetName).lib - MachineX86 - - - true - $(OutDir)$(TargetName).bsc - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - .\Debug/mucc.tlb - - - - - Disabled - ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;UNICODE;_UNICODE;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - $(IntDir)$(TargetName).pch - - - $(IntDir) - $(IntDir)vc$(PlatformToolsetVersion).pdb - Level3 - true - ProgramDatabase - 4996;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0415 - - - odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - true - $(TargetDir)tlen_czaty.pdb - false - - - $(IntDir)$(TargetName).lib - - - true - $(OutDir)$(TargetName).bsc - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\Debug/mucc.tlb - - - - - Disabled - ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - $(IntDir)$(TargetName).pch - - - $(IntDir) - $(IntDir)vc$(PlatformToolsetVersion).pdb - Level3 - true - EditAndContinue - 4996;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0415 - - - odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - true - $(TargetDir)tlen_czaty.pdb - false - - - $(IntDir)$(TargetName).lib - MachineX86 - - - true - $(OutDir)$(TargetName).bsc - - - - - _DEBUG;%(PreprocessorDefinitions) - true - true - .\Debug/mucc.tlb - - - - - Disabled - ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - $(IntDir)$(TargetName).pch - - - $(IntDir) - $(IntDir)vc$(PlatformToolsetVersion).pdb - Level3 - true - ProgramDatabase - 4996;%(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0415 - - - odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - true - true - $(TargetDir)tlen_czaty.pdb - false - - - $(IntDir)$(TargetName).lib - - - true - $(OutDir)$(TargetName).bsc - - - - - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - %(PreprocessorDefinitions) - - - - - - \ No newline at end of file diff --git a/!NotAdopted/Tlen/tlen_czaty/mucc_services.cpp b/!NotAdopted/Tlen/tlen_czaty/mucc_services.cpp deleted file mode 100644 index 0d4571a633..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/mucc_services.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#include "mucc_services.h" -#include "Utils.h" -#include "HelperDialog.h" - -int MUCCQueryChatGroups(MUCCQUERYRESULT *queryResult) -{ - ManagerWindow *managerWnd=ManagerWindow::getWindow(queryResult->pszModule); - if (managerWnd!=NULL) { - managerWnd->queryResultGroups(queryResult); - } - return 1; -} - -int MUCCQueryChatRooms(MUCCQUERYRESULT *queryResult) -{ - ManagerWindow *managerWnd=ManagerWindow::getWindow(queryResult->pszModule); - if (managerWnd!=NULL) { - managerWnd->queryResultRooms(queryResult); - } - return 1; -} - -int MUCCQueryUserRooms(MUCCQUERYRESULT *queryResult) -{ - ManagerWindow *managerWnd=ManagerWindow::getWindow(queryResult->pszModule); - if (managerWnd!=NULL) { - managerWnd->queryResultUserRooms(queryResult); - } - return 1; -} - -int MUCCQueryUserNicks(MUCCQUERYRESULT *queryResult) -{ - ManagerWindow *managerWnd=ManagerWindow::getWindow(queryResult->pszModule); - if (managerWnd!=NULL) { - managerWnd->queryResultUserNick(queryResult); - } - return 1; -} - -INT_PTR MUCCQueryResult(WPARAM wParam, LPARAM lParam) -{ - MUCCQUERYRESULT *queryResult=(MUCCQUERYRESULT *)lParam; - ChatWindow * chatWindow = NULL; - switch (queryResult->iType) { - case MUCC_EVENT_QUERY_GROUPS: - MUCCQueryChatGroups(queryResult); - break; - case MUCC_EVENT_QUERY_ROOMS: - MUCCQueryChatRooms(queryResult); - break; - case MUCC_EVENT_QUERY_USER_ROOMS: - MUCCQueryUserRooms(queryResult); - break; - case MUCC_EVENT_QUERY_USER_NICKS: - MUCCQueryUserNicks(queryResult); - break; - case MUCC_EVENT_QUERY_CONTACTS: - case MUCC_EVENT_QUERY_USERS: - chatWindow=ChatWindow::getWindow(queryResult->pszModule, queryResult->pszParent); - if (chatWindow!=NULL) { - SendMessage(chatWindow->getHWND(), DM_CHAT_QUERY, (WPARAM) 0, (LPARAM) queryResult); - } - break; - } - return 0; -} - -INT_PTR MUCCNewWindow(WPARAM wParam, LPARAM lParam) -{ - MUCCWINDOW *mucWindow = (MUCCWINDOW *) lParam; - if (mucWindow->iType == MUCC_WINDOW_CHATROOM) { - ChatWindow *chat = ChatWindow::getWindow(mucWindow->pszModule, mucWindow->pszID); - if (chat == NULL) { - chat = new ChatWindow(mucWindow); - } - } else if (mucWindow->iType == MUCC_WINDOW_CHATLIST) { - ManagerWindow *manager = ManagerWindow::getWindow(mucWindow->pszModule); - if (manager == NULL) { - - } - //Utils::log("setting name: %s", mucWindow->pszModuleName); - manager->setModuleName(mucWindow->pszModuleName); - manager->start(); - } - return 0; -} - -INT_PTR MUCCEvent(WPARAM wParam, LPARAM lParam) -{ - MUCCEVENT* mucEvent = (MUCCEVENT *) lParam; - ChatWindow * chatWindow = NULL; - switch (mucEvent->iType) { - case MUCC_EVENT_STATUS: - case MUCC_EVENT_MESSAGE: - case MUCC_EVENT_ROOM_INFO: - case MUCC_EVENT_LEAVE: - case MUCC_EVENT_TOPIC: - chatWindow = ChatWindow::getWindow(mucEvent->pszModule, mucEvent->pszID); - if (chatWindow!=NULL) { - SendMessage(chatWindow->getHWND(), DM_CHAT_EVENT, (WPARAM) 0, (LPARAM) mucEvent); - } - break; - case MUCC_EVENT_ERROR: - chatWindow = ChatWindow::getWindow(mucEvent->pszModule, mucEvent->pszID); - if (chatWindow!=NULL) { - SendMessage(chatWindow->getHWND(), DM_CHAT_EVENT, (WPARAM) 0, (LPARAM) mucEvent); - } else { - HelperDialog::errorDlg(mucEvent); - } - break; - case MUCC_EVENT_INVITATION: - HelperDialog::acceptDlg(mucEvent); - break; - case MUCC_EVENT_JOIN: - HelperDialog::joinDlg(mucEvent); - break; - } - return 0; -} diff --git a/!NotAdopted/Tlen/tlen_czaty/mucc_services.h b/!NotAdopted/Tlen/tlen_czaty/mucc_services.h deleted file mode 100644 index f1db38274b..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/mucc_services.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#ifndef MUCCSERVICES_INCLUDED -#define MUCCSERVICES_INCLUDED - -#include "mucc.h" -#include "ManagerWindow.h" -#include "ChatWindow.h" - -extern int MUCCServicesInit(WPARAM wParam, LPARAM lParam); - -extern INT_PTR MUCCQueryResult(WPARAM wParam, LPARAM lParam) ; -extern INT_PTR MUCCNewWindow(WPARAM wParam, LPARAM lParam) ; -extern INT_PTR MUCCEvent(WPARAM wParam, LPARAM lParam) ; - -#endif - diff --git a/!NotAdopted/Tlen/tlen_czaty/resource.h b/!NotAdopted/Tlen/tlen_czaty/resource.h deleted file mode 100644 index c4d2f1945c..0000000000 --- a/!NotAdopted/Tlen/tlen_czaty/resource.h +++ /dev/null @@ -1,218 +0,0 @@ -/* - -MUCC Group Chat GUI Plugin for Miranda IM -Copyright (C) 2004 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#define IDI_CHAT 100 -#define IDI_ITALIC 101 -#define IDI_BOLD 102 -#define IDI_UNDERLINE 103 -#define IDI_OPTIONS 104 -#define IDI_OWNER 105 -#define IDI_ADMIN 106 -#define IDI_REGISTERED 107 -#define IDI_R_MODERATED 108 -#define IDI_R_MEMBERS 109 -#define IDI_R_ANONYMOUS 110 -#define IDI_SEARCH 111 -#define IDI_PREV 112 -#define IDI_NEXT 113 -#define IDI_BLANK 114 -#define IDI_INVITE 115 -#define IDI_ADMINISTRATION 116 -#define IDI_GLOBALOWNER 117 -#define IDI_SMILEY 118 -#define IDI_MESSAGE 119 - -#define IDD_CHATMANAGER 150 -#define IDD_GROUPCHAT_LOG 151 -#define IDD_HELPER_JOIN 152 -#define IDD_HELPER_INPUT 153 -#define IDD_HELPER_INVITE 154 -#define IDD_HELPER_INVITE_ACCEPT 155 -#define IDD_HELPER_TOPIC 156 -#define IDD_OPTIONS 157 -#define IDD_OPT_POPUPS 158 -#define IDD_TAB_CHATROOMS 159 -#define IDD_TAB_MYROOMS 160 -#define IDD_TAB_MYNICKNAMES 161 -#define IDD_USER_ADMIN 162 -#define IDD_USER_KICK 163 -#define IDD_USER_ROLE 164 -#define IDD_USER_BROWSER 165 -#define IDD_GROUPCHAT_CONTAINER 166 - -#define IDR_CHATOPTIONS 200 -#define IDR_CONTEXT 201 - -#define IDC_FONTLIST 1000 -#define IDC_COLORINPUT 1001 -#define IDC_COLORBKG 1002 -#define IDC_COLORLIST 1003 -#define IDC_COLORTXT 1004 -#define IDC_CHOOSEFONT 1005 -#define IDC_FONTSGB 1006 -#define IDC_OPTIONSGB 1007 -#define IDC_LOGLIMITSPIN 1008 -#define IDC_LOGLIMIT 1009 -#define IDC_SENDONENTER 1010 -#define IDC_USETABS 1011 -#define IDC_ENABLEIEVIEW 1012 -#define IDC_REGISTER 1020 -#define IDC_NAME 1021 -#define IDC_FRAME 1037 -#define IDC_SIMPLE 1041 -#define IDC_PASSWORD 1050 -#define IDC_JID 1051 -#define IDC_COUNTRY 1060 -#define IDC_NICKNAME 1062 -#define IDC_MSG 1084 -#define IDC_TITLE 1089 -#define IDC_DESC 1090 -#define IDC_DELETE 1092 -#define IDC_LOAD 1093 -#define IDC_JOIN 1123 -#define IDC_ROOM 1124 -#define IDC_ROOM_LABEL 1125 -#define IDC_BROWSE 1126 -#define IDC_VSCROLL 1128 -#define IDC_NICK 1129 -#define IDC_NICK_LABEL 1130 -#define IDC_EDIT 1131 -#define IDC_TREELIST 1132 -#define IDC_LIST 1133 -#define IDC_HSPLIT 1134 -#define IDC_LOG 1136 -#define IDC_VSPLIT 1137 -#define IDC_SET 1140 -#define IDC_TABS 1141 -#define IDC_TOPIC 1141 -#define IDC_TOPIC_BUTTON 1142 -#define IDC_FONT 1143 -#define IDC_ENTER 1144 -#define IDC_CTRLENTER 1145 -#define IDC_FLASH 1148 -#define IDC_TIME 1156 -#define IDC_DATE 1157 -#define IDC_REASON 1171 -#define IDC_USER 1172 -#define IDC_INVITE 1173 -#define IDC_ACCEPT 1174 -#define IDC_FROM 1175 -#define IDC_DELAY 1180 -#define IDC_PREVIEW 1183 -#define IDC_ENABLEPOPUP 1184 -#define IDC_DELAY_PERMANENT 1185 -#define IDC_DELAY_CUSTOM 1186 -#define IDC_DELAY_POPUP 1187 -#define IDC_GROUP 1203 -#define IDC_BOLD 1204 -#define IDC_SMILEY 1205 -#define IDC_UNDERLINE 1205 -#define IDC_ITALIC 1206 -#define IDC_COLOR 1207 -#define IDC_OPTIONS 1208 -#define IDC_SMILEYBTN 1209 -#define IDC_CHECK_PERMANENT 1210 -#define IDC_CHECK_PUBLIC 1211 -#define IDC_CHECK_NICKNAMES 1212 -#define IDC_CHECK_MEMBERS 1213 -#define IDC_NEXT 1214 -#define IDC_PREV 1215 -#define IDC_FONTSIZE 1215 -#define IDC_SEARCH 1216 -#define IDC_REFRESH 1216 -#define IDC_REMOVE 1217 -#define IDC_KICK_OPTIONS 1218 -#define IDC_ROLE_OPTIONS 1219 -#define IDC_KICK 1220 -#define IDC_SET_ROLE 1221 -#define IDC_UPDATE 1313 -#define IDC_STATUS 1414 -#define IDC_PLAN 1415 -#define IDC_SHOW 1416 - -#define IDC_PERSONALGROUP 1434 -#define IDC_EXTRAGROUP 1436 - -#define ID_OPTIONMENU_SHOWNICKNAMES 40001 -#define ID_OPTIONMENU_MSGINNEWLINE 40002 -#define ID_OPTIONMENU_SHOWTIMESTAMP 40011 -#define ID_OPTIONMENU_SHOWDATE 40012 -#define ID_OPTIONMENU_SHOWSECONDS 40013 -#define ID_OPTIONMENU_USELONGDATE 40014 -#define ID_OPTIONMENU_FORMATFONT 40021 -#define ID_OPTIONMENU_FORMATSIZE 40022 -#define ID_OPTIONMENU_FORMATCOLOR 40023 -#define ID_OPTIONMENU_FORMATSTYLE 40024 -#define ID_OPTIONMENU_LOGMESSAGES 40031 -#define ID_OPTIONMENU_LOGJOINED 40032 -#define ID_OPTIONMENU_LOGLEFT 40033 -#define ID_OPTIONMENU_LOGTOPIC 40034 -#define ID_OPTIONMENU_FLASHMESSAGES 40035 -#define ID_OPTIONMENU_FLASHJOINED 40036 -#define ID_OPTIONMENU_FLASHLEFT 40037 -#define ID_OPTIONMENU_FLASHTOPIC 40038 -#define ID_OPTIONMENU_SAVEDEFAULT 40040 -#define ID_USERMENU_MESSAGE 40050 -#define ID_USERMENU_KICK_POPUP 40051 -#define ID_USERMENU_KICK_NO_BAN 40052 -#define ID_USERMENU_KICK_BAN_1_MIN 40053 -#define ID_USERMENU_KICK_BAN_5_MIN 40054 -#define ID_USERMENU_KICK_BAN_15_MIN 40055 -#define ID_USERMENU_KICK_BAN_30_MIN 40056 -#define ID_USERMENU_KICK_BAN_1_H 40057 -#define ID_USERMENU_KICK_BAN_6_H 40058 -#define ID_USERMENU_KICK_BAN_1_D 40059 -#define ID_USERMENU_KICK_BAN_3_D 40060 -#define ID_USERMENU_KICK_BAN_1_W 40061 -#define ID_USERMENU_KICK_BAN_2_W 40062 -#define ID_USERMENU_KICK_BAN_4_W 40063 -#define ID_USERMENU_RIGHTS_NO 40065 -#define ID_USERMENU_RIGHTS_MEMBER 40066 -#define ID_USERMENU_RIGHTS_ADMIN 40067 -#define ID_USERMENU_ADMINISTRATION 40070 -#define ID_USERMENU_UNBAN 40071 -#define ID_ADMINMENU_DESTROY 40080 -#define ID_ADMINMENU_ADMIN 40081 -#define ID_ADMINMENU_BROWSE 40082 -#define ID_ADMINMENU_SAVELOG 40083 - -#define IDM_CUT 40000 -#define IDM_COPY 40001 -#define IDM_PASTE 40002 -#define IDM_UNDO 40003 -#define IDM_DELETE 40004 -#define IDM_REDO 40005 -#define IDM_COPYALL 40011 -#define IDM_SELECTALL 40012 -#define IDM_CLEAR 40013 -#define IDM_OPENNEW 40014 -#define IDM_OPENEXISTING 40015 -#define IDM_COPYLINK 40016 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 205 -#define _APS_NEXT_COMMAND_VALUE 40090 -#define _APS_NEXT_CONTROL_VALUE 1217 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/!NotAdopted/Tlen/tlen_file.c b/!NotAdopted/Tlen/tlen_file.c deleted file mode 100644 index 9926a09aa6..0000000000 --- a/!NotAdopted/Tlen/tlen_file.c +++ /dev/null @@ -1,718 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include -#include -#include -#include -#include "jabber_list.h" -#include "tlen_p2p_old.h" - -extern int TlenFileCancel(PROTO_INTERFACE *ptr, HANDLE hContact, HANDLE hTransfer); - - -static void TlenFileReceiveParse(TLEN_FILE_TRANSFER *ft) -{ - int i; - char *p; - TLEN_FILE_PACKET *rpacket, *packet; - - rpacket = NULL; - if (ft->state == FT_CONNECTING) { - rpacket = TlenP2PPacketReceive(ft->s); - if (rpacket != NULL) { - p = rpacket->packet; - if (rpacket->type == TLEN_FILE_PACKET_FILE_LIST) { // list of files (length & name) - ft->fileCount = (int)(*((DWORD*)p)); - ft->files = (char **) mir_alloc(sizeof(char *) * ft->fileCount); - ft->filesSize = (long *) mir_alloc(sizeof(long) * ft->fileCount); - ft->currentFile = 0; - ft->allFileTotalSize = 0; - ft->allFileReceivedBytes = 0; - p += sizeof(DWORD); - for (i=0;ifileCount;i++) { - ft->filesSize[i] = (long)(*((DWORD*)p)); - ft->allFileTotalSize += ft->filesSize[i]; - p += sizeof(DWORD); - ft->files[i] = (char *)mir_alloc(256); - memcpy(ft->files[i], p, 256); - p += 256; - } - if ((packet=TlenP2PPacketCreate(3*sizeof(DWORD))) == NULL) { - ft->state = FT_ERROR; - } - else { - TlenP2PPacketSetType(packet, TLEN_FILE_PACKET_FILE_LIST_ACK); - TlenP2PPacketSend(ft->s, packet); - TlenP2PPacketFree(packet); - ft->state = FT_INITIALIZING; - JabberLog(ft->proto, "Change to FT_INITIALIZING"); - } - } - TlenP2PPacketFree(rpacket); - } - else { - ft->state = FT_ERROR; - } - } - else if (ft->state == FT_INITIALIZING) { - char *fullFileName; - if ((packet=TlenP2PPacketCreate(3*sizeof(DWORD))) != NULL) { - TlenP2PPacketSetType(packet, TLEN_FILE_PACKET_FILE_REQUEST); // file request - TlenP2PPacketPackDword(packet, ft->currentFile); - TlenP2PPacketPackDword(packet, 0); - TlenP2PPacketPackDword(packet, 0); - TlenP2PPacketSend(ft->s, packet); - TlenP2PPacketFree(packet); - - fullFileName = (char *) mir_alloc(strlen(ft->szSavePath) + strlen(ft->files[ft->currentFile]) + 2); - strcpy(fullFileName, ft->szSavePath); - if (fullFileName[strlen(fullFileName)-1] != '\\') - strcat(fullFileName, "\\"); - strcat(fullFileName, ft->files[ft->currentFile]); - ft->fileId = _open(fullFileName, _O_BINARY|_O_WRONLY|_O_CREAT|_O_TRUNC, _S_IREAD|_S_IWRITE); - ft->fileReceivedBytes = 0; - ft->fileTotalSize = ft->filesSize[ft->currentFile]; - JabberLog(ft->proto, "Saving to [%s] [%d]", fullFileName, ft->filesSize[ft->currentFile]); - mir_free(fullFileName); - ft->state = FT_RECEIVING; - JabberLog(ft->proto, "Change to FT_RECEIVING"); - } - else { - ft->state = FT_ERROR; - } - } - else if (ft->state == FT_RECEIVING) { - PROTOFILETRANSFERSTATUS pfts; - memset(&pfts, 0, sizeof(PROTOFILETRANSFERSTATUS)); - pfts.cbSize = sizeof(PROTOFILETRANSFERSTATUS); - pfts.hContact = ft->hContact; - pfts.sending = FALSE; - pfts.files = ft->files; - pfts.totalFiles = ft->fileCount; - pfts.currentFileNumber = ft->currentFile; - pfts.totalBytes = ft->allFileTotalSize; - pfts.workingDir = NULL; - pfts.currentFile = ft->files[ft->currentFile]; - pfts.currentFileSize = ft->filesSize[ft->currentFile]; - pfts.currentFileTime = 0; - JabberLog(ft->proto, "Receiving data..."); - while (ft->state == FT_RECEIVING) { - rpacket = TlenP2PPacketReceive(ft->s); - if (rpacket != NULL) { - p = rpacket->packet; - if (rpacket->type == TLEN_FILE_PACKET_FILE_DATA) { // file data - int writeSize; - writeSize = rpacket->len - 2 * sizeof(DWORD) ; // skip file offset - if (_write(ft->fileId, p + 2 * sizeof(DWORD), writeSize) != writeSize) { - ft->state = FT_ERROR; - } - else { - ft->fileReceivedBytes += writeSize; - ft->allFileReceivedBytes += writeSize; - pfts.totalProgress = ft->allFileReceivedBytes; - pfts.currentFileProgress = ft->fileReceivedBytes; - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM) &pfts); - } - } - else if (rpacket->type == TLEN_FILE_PACKET_END_OF_FILE) { // end of file - _close(ft->fileId); - JabberLog(ft->proto, "Finishing this file..."); - if (ft->currentFile >= ft->fileCount-1) { - ft->state = FT_DONE; - } - else { - ft->currentFile++; - ft->state = FT_INITIALIZING; - JabberLog(ft->proto, "File received, advancing to the next file..."); - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0); - } - } - TlenP2PPacketFree(rpacket); - } - else { - ft->state = FT_ERROR; - } - } - } -} - -static void TlenFileReceivingConnection(JABBER_SOCKET hConnection, DWORD dwRemoteIP, void * pExtra) -{ - JABBER_SOCKET slisten; - TLEN_FILE_TRANSFER *ft; - - TlenProtocol *proto = (TlenProtocol *)pExtra; - ft = TlenP2PEstablishIncomingConnection(proto, hConnection, LIST_FILE, TRUE); - if (ft != NULL) { - slisten = ft->s; - ft->s = hConnection; - JabberLog(ft->proto, "Set ft->s to %d (saving %d)", hConnection, slisten); - JabberLog(ft->proto, "Entering send loop for this file connection... (ft->s is hConnection)"); - while (ft->state!=FT_DONE && ft->state!=FT_ERROR) { - TlenFileReceiveParse(ft); - } - if (ft->state==FT_DONE) - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); - else - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - JabberLog(ft->proto, "Closing connection for this file transfer... (ft->s is now hBind)"); - ft->s = slisten; - JabberLog(ft->proto, "ft->s is restored to %d", ft->s); - if (ft->s != hConnection) { - Netlib_CloseHandle(hConnection); - } - if (ft->hFileEvent != NULL) - SetEvent(ft->hFileEvent); - } else { - Netlib_CloseHandle(hConnection); - } -} - - -static void __cdecl TlenFileReceiveThread(TLEN_FILE_TRANSFER *ft) -{ - NETLIBOPENCONNECTION nloc; - JABBER_SOCKET s; - JabberLog(ft->proto, "Thread started: type=file_receive server='%s' port='%d'", ft->hostName, ft->wPort); - ft->mode = FT_RECV; - nloc.cbSize = NETLIBOPENCONNECTION_V1_SIZE;//sizeof(NETLIBOPENCONNECTION); - nloc.szHost = ft->hostName; - nloc.wPort = ft->wPort; - nloc.flags = 0; - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, ft, 0); - s = (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, (WPARAM) ft->proto->hNetlibUser, (LPARAM) &nloc); - if (s != NULL) { - ft->s = s; - JabberLog(ft->proto, "Entering file receive loop"); - TlenP2PEstablishOutgoingConnection(ft, TRUE); - while (ft->state!=FT_DONE && ft->state!=FT_ERROR) { - TlenFileReceiveParse(ft); - } - if (ft->s) { - Netlib_CloseHandle(s); - } - ft->s = NULL; - } else { - ft->pfnNewConnectionV2 = TlenFileReceivingConnection; - JabberLog(ft->proto, "Connection failed - receiving as server"); - s = TlenP2PListen(ft); - if (s != NULL) { - HANDLE hEvent; - char *nick; - ft->s = s; - hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - ft->hFileEvent = hEvent; - ft->currentFile = 0; - ft->state = FT_CONNECTING; - nick = JabberNickFromJID(ft->jid); - JabberSend(ft->proto, "", nick, ft->iqId, ft->localName, ft->wLocalPort); - mir_free(nick); - JabberLog(ft->proto, "Waiting for the file to be received..."); - WaitForSingleObject(hEvent, INFINITE); - ft->hFileEvent = NULL; - CloseHandle(hEvent); - JabberLog(ft->proto, "Finish all files"); - Netlib_CloseHandle(s); - } else { - ft->state = FT_ERROR; - } - } - JabberListRemove(ft->proto, LIST_FILE, ft->iqId); - if (ft->state==FT_DONE) - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); - else { - char *nick; - nick = JabberNickFromJID(ft->jid); - JabberSend(ft->proto, "", nick, ft->iqId); - mir_free(nick); - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - } - - JabberLog(ft->proto, "Thread ended: type=file_receive server='%s'", ft->hostName); - TlenP2PFreeFileTransfer(ft); -} - - - -static void TlenFileSendParse(TLEN_FILE_TRANSFER *ft) -{ - int i; - char *p, *t; - int currentFile, numRead; - char *fileBuffer; - TLEN_FILE_PACKET *rpacket, *packet; - - - if (ft->state == FT_CONNECTING) { - char filename[256]; // Must be 256 (0x100) - if ((packet=TlenP2PPacketCreate(sizeof(DWORD)+(ft->fileCount*(sizeof(filename)+sizeof(DWORD))))) != NULL) { - // Must pause a bit, sending these two packets back to back - // will break the session because the receiver cannot take it :) - SleepEx(1000, TRUE); - TlenP2PPacketSetLen(packet, 0); // Reuse packet - TlenP2PPacketSetType(packet, TLEN_FILE_PACKET_FILE_LIST); - TlenP2PPacketPackDword(packet, (DWORD) ft->fileCount); - for (i=0; ifileCount; i++) { -// struct _stat statbuf; -// _stat(ft->files[i], &statbuf); -// TlenP2PPacketPackDword(packet, statbuf.st_size); - TlenP2PPacketPackDword(packet, ft->filesSize[i]); - memset(filename, 0, sizeof(filename)); - if ((t=strrchr(ft->files[i], '\\')) != NULL) - t++; - else - t = ft->files[i]; - _snprintf(filename, sizeof(filename)-1, t); - TlenP2PPacketPackBuffer(packet, filename, sizeof(filename)); - } - TlenP2PPacketSend(ft->s, packet); - TlenP2PPacketFree(packet); - - ft->allFileReceivedBytes = 0; - ft->state = FT_INITIALIZING; - JabberLog(ft->proto, "Change to FT_INITIALIZING"); - } - else { - ft->state = FT_ERROR; - } - } - else if (ft->state == FT_INITIALIZING) { // FT_INITIALIZING - rpacket = TlenP2PPacketReceive(ft->s); - JabberLog(ft->proto, "FT_INITIALIZING: recv %d", rpacket); - if (rpacket == NULL) { - ft->state = FT_ERROR; - return; - } - JabberLog(ft->proto, "FT_INITIALIZING: recv type %d", rpacket->type); - p = rpacket->packet; - // TYPE: TLEN_FILE_PACKET_FILE_LIST_ACK will be ignored - // LEN: 0 - if (rpacket->type == TLEN_FILE_PACKET_FILE_LIST_ACK) { - - } - // Then the receiver will request each file - // TYPE: TLEN_FILE_PACKET_REQUEST - // LEN: - // (DWORD) file number - // (DWORD) 0 - // (DWORD) 0 - else if (rpacket->type == TLEN_FILE_PACKET_FILE_REQUEST) { - PROTOFILETRANSFERSTATUS pfts; - //struct _stat statbuf; - - currentFile = *((DWORD*)p); - if (currentFile != ft->currentFile) { - JabberLog(ft->proto, "Requested file (#%d) is invalid (must be %d)", currentFile, ft->currentFile); - ft->state = FT_ERROR; - } - else { - // _stat(ft->files[currentFile], &statbuf); // file size in statbuf.st_size - JabberLog(ft->proto, "Sending [%s] [%d]", ft->files[currentFile], ft->filesSize[currentFile]); - if ((ft->fileId=_open(ft->files[currentFile], _O_BINARY|_O_RDONLY)) < 0) { - JabberLog(ft->proto, "File cannot be opened"); - ft->state = FT_ERROR; - } - else { - memset(&pfts, 0, sizeof(PROTOFILETRANSFERSTATUS)); - pfts.cbSize = sizeof(PROTOFILETRANSFERSTATUS); - pfts.hContact = ft->hContact; - pfts.sending = TRUE; - pfts.files = ft->files; - pfts.totalFiles = ft->fileCount; - pfts.currentFileNumber = ft->currentFile; - pfts.totalBytes = ft->allFileTotalSize; - pfts.workingDir = NULL; - pfts.currentFile = ft->files[ft->currentFile]; - pfts.currentFileSize = ft->filesSize[ft->currentFile]; //statbuf.st_size; - pfts.currentFileTime = 0; - ft->fileReceivedBytes = 0; - if ((packet = TlenP2PPacketCreate(2*sizeof(DWORD)+2048)) == NULL) { - ft->state = FT_ERROR; - } - else { - TlenP2PPacketSetType(packet, TLEN_FILE_PACKET_FILE_DATA); - fileBuffer = (char *) mir_alloc(2048); - JabberLog(ft->proto, "Sending file data..."); - while ((numRead=_read(ft->fileId, fileBuffer, 2048)) > 0) { - TlenP2PPacketSetLen(packet, 0); // Reuse packet - TlenP2PPacketPackDword(packet, (DWORD) ft->fileReceivedBytes); - TlenP2PPacketPackDword(packet, 0); - TlenP2PPacketPackBuffer(packet, fileBuffer, numRead); - if (TlenP2PPacketSend(ft->s, packet)) { - ft->fileReceivedBytes += numRead; - ft->allFileReceivedBytes += numRead; - pfts.totalProgress = ft->allFileReceivedBytes; - pfts.currentFileProgress = ft->fileReceivedBytes; - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM) &pfts); - } - else { - ft->state = FT_ERROR; - break; - } - } - mir_free(fileBuffer); - _close(ft->fileId); - if (ft->state != FT_ERROR) { - if (ft->currentFile >= ft->fileCount-1) - ft->state = FT_DONE; - else { - ft->currentFile++; - ft->state = FT_INITIALIZING; - JabberLog(ft->proto, "File sent, advancing to the next file..."); - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0); - } - } - JabberLog(ft->proto, "Finishing this file..."); - TlenP2PPacketSetLen(packet, 0); // Reuse packet - TlenP2PPacketSetType(packet, TLEN_FILE_PACKET_END_OF_FILE); - TlenP2PPacketPackDword(packet, currentFile); - TlenP2PPacketSend(ft->s, packet); - TlenP2PPacketFree(packet); - } - } - } - TlenP2PPacketFree(rpacket); - } - else { - ft->state = FT_ERROR; - } - } -} - -static void TlenFileSendingConnection(JABBER_SOCKET hConnection, DWORD dwRemoteIP, void * pExtra) -{ - JABBER_SOCKET slisten; - TLEN_FILE_TRANSFER *ft; - TlenProtocol *proto = (TlenProtocol *)pExtra; - - ft = TlenP2PEstablishIncomingConnection(proto, hConnection, LIST_FILE, TRUE); - if (ft != NULL) { - slisten = ft->s; - ft->s = hConnection; - JabberLog(ft->proto, "Set ft->s to %d (saving %d)", hConnection, slisten); - - JabberLog(ft->proto, "Entering send loop for this file connection... (ft->s is hConnection)"); - while (ft->state!=FT_DONE && ft->state!=FT_ERROR) { - TlenFileSendParse(ft); - } - if (ft->state==FT_DONE) - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); - else - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - JabberLog(ft->proto, "Closing connection for this file transfer... (ft->s is now hBind)"); - ft->s = slisten; - JabberLog(ft->proto, "ft->s is restored to %d", ft->s); - if (ft->s != hConnection) { - Netlib_CloseHandle(hConnection); - } - if (ft->hFileEvent != NULL) - SetEvent(ft->hFileEvent); - } else { - Netlib_CloseHandle(hConnection); - } -} - -int TlenFileCancelAll(TlenProtocol *proto) -{ - JABBER_LIST_ITEM *item; - HANDLE hEvent; - int i = 0; - - while ((i=JabberListFindNext(proto, LIST_FILE, 0)) >=0 ) { - if ((item=JabberListGetItemPtrFromIndex(proto, i)) != NULL) { - TLEN_FILE_TRANSFER *ft = item->ft; - JabberListRemoveByIndex(proto, i); - if (ft != NULL) { - if (ft->s) { - //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - JabberLog(ft->proto, "Closing ft->s = %d", ft->s); - ft->state = FT_ERROR; - Netlib_CloseHandle(ft->s); - ft->s = NULL; - if (ft->hFileEvent != NULL) { - hEvent = ft->hFileEvent; - ft->hFileEvent = NULL; - SetEvent(hEvent); - } - } else { - JabberLog(ft->proto, "freeing ft struct"); - TlenP2PFreeFileTransfer(ft); - } - } - } - } - return 0; -} - -static void __cdecl TlenFileSendingThread(TLEN_FILE_TRANSFER *ft) -{ - JABBER_SOCKET s = NULL; - HANDLE hEvent; - char *nick; - - JabberLog(ft->proto, "Thread started: type=tlen_file_send"); - ft->mode = FT_SEND; - ft->pfnNewConnectionV2 = TlenFileSendingConnection; - s = TlenP2PListen(ft); - if (s != NULL) { - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, ft, 0); - ft->s = s; - //JabberLog("ft->s = %d", s); - //JabberLog("fileCount = %d", ft->fileCount); - - hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - ft->hFileEvent = hEvent; - ft->currentFile = 0; - ft->state = FT_CONNECTING; - - nick = JabberNickFromJID(ft->jid); - JabberSend(ft->proto, "", nick, ft->iqId, ft->localName, ft->wLocalPort); - mir_free(nick); - JabberLog(ft->proto, "Waiting for the file to be sent..."); - WaitForSingleObject(hEvent, INFINITE); - ft->hFileEvent = NULL; - CloseHandle(hEvent); - JabberLog(ft->proto, "Finish all files"); - Netlib_CloseHandle(s); - ft->s = NULL; - JabberLog(ft->proto, "ft->s is NULL"); - - if (ft->state == FT_SWITCH) { - NETLIBOPENCONNECTION nloc; - JABBER_SOCKET s; - JabberLog(ft->proto, "Sending as client..."); - ft->state = FT_CONNECTING; - nloc.cbSize = NETLIBOPENCONNECTION_V1_SIZE;//sizeof(NETLIBOPENCONNECTION); - nloc.szHost = ft->hostName; - nloc.wPort = ft->wPort; - nloc.flags = 0; - s = (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, (WPARAM) ft->proto->hNetlibUser, (LPARAM) &nloc); - if (s != NULL) { - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, ft, 0); - ft->s = s; - TlenP2PEstablishOutgoingConnection(ft, TRUE); - JabberLog(ft->proto, "Entering send loop for this file connection..."); - while (ft->state!=FT_DONE && ft->state!=FT_ERROR) { - TlenFileSendParse(ft); - } - if (ft->state==FT_DONE) - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); - else - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - JabberLog(ft->proto, "Closing connection for this file transfer... "); - Netlib_CloseHandle(s); - } else { - ft->state = FT_ERROR; - } - } - } else { - JabberLog(ft->proto, "Cannot allocate port to bind for file server thread, thread ended."); - ft->state = FT_ERROR; - } - JabberListRemove(ft->proto, LIST_FILE, ft->iqId); - switch (ft->state) { - case FT_DONE: - JabberLog(ft->proto, "Finish successfully"); - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); - break; - case FT_DENIED: - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_DENIED, ft, 0); - break; - default: // FT_ERROR: - nick = JabberNickFromJID(ft->jid); - JabberSend(ft->proto, "", nick, ft->iqId); - mir_free(nick); - JabberLog(ft->proto, "Finish with errors"); - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - break; - } - JabberLog(ft->proto, "Thread ended: type=file_send"); - TlenP2PFreeFileTransfer(ft); -} - - -TLEN_FILE_TRANSFER *TlenFileCreateFT(TlenProtocol *proto, const char *jid) { - TLEN_FILE_TRANSFER *ft; - ft = (TLEN_FILE_TRANSFER *) mir_alloc(sizeof(TLEN_FILE_TRANSFER)); - memset(ft, 0, sizeof(TLEN_FILE_TRANSFER)); - ft->proto = proto; - ft->jid = mir_strdup(jid); - return ft; -} - -/* - * File transfer - */ -void TlenProcessF(XmlNode *node, ThreadData *info) -{ - TLEN_FILE_TRANSFER *ft; - CCSDATA ccs; - PROTORECVEVENT pre; - char *szBlob, *from, *p, *e; - char jid[128], szFilename[MAX_PATH]; - int numFiles; - JABBER_LIST_ITEM *item; - -// if (!node->name || strcmp(node->name, "f")) return; - if (info == NULL) return; - - if ((from=JabberXmlGetAttrValue(node, "f")) != NULL) { - - if (strchr(from, '@') == NULL) { - _snprintf(jid, sizeof(jid), "%s@%s", from, info->server); - } else { - _snprintf(jid, sizeof(jid), "%s", from); - } - if ((e=JabberXmlGetAttrValue(node, "e")) != NULL) { - - if (!strcmp(e, "1")) { - // FILE_RECV : e='1' : File transfer request - ft = TlenFileCreateFT(info->proto, jid); - ft->hContact = JabberHContactFromJID(info->proto, jid); - - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) - ft->iqId = mir_strdup(p); - - szFilename[0] = '\0'; - if ((p=JabberXmlGetAttrValue(node, "c")) != NULL) { - numFiles = atoi(p); - if (numFiles == 1) { - if ((p=JabberXmlGetAttrValue(node, "n")) != NULL) { - p = JabberTextDecode(p); - strncpy(szFilename, p, sizeof(szFilename)); - mir_free(p); - } else { - strcpy(szFilename, Translate("1 File")); - } - } - else if (numFiles > 1) { - _snprintf(szFilename, sizeof(szFilename), Translate("%d Files"), numFiles); - } - } - - if (szFilename[0]!='\0' && ft->iqId!=NULL) { - // blob is DWORD(*ft), ASCIIZ(filenames), ASCIIZ(description) - szBlob = (char *) mir_alloc(sizeof(DWORD) + strlen(szFilename) + 2); - *((PDWORD) szBlob) = (DWORD) ft; - strcpy(szBlob + sizeof(DWORD), szFilename); - szBlob[sizeof(DWORD) + strlen(szFilename) + 1] = '\0'; - pre.flags = 0; - pre.timestamp = time(NULL); - pre.szMessage = szBlob; - pre.lParam = 0; - ccs.szProtoService = PSR_FILE; - ccs.hContact = ft->hContact; - ccs.wParam = 0; - ccs.lParam = (LPARAM) ⪯ - JabberLog(ft->proto, "sending chainrecv"); - CallService(MS_PROTO_CHAINRECV, 0, (LPARAM) &ccs); - mir_free(szBlob); - } - else { - // malformed request, reject - if (ft->iqId) - JabberSend(ft->proto, "", ft->iqId, from); - else - JabberSend(ft->proto, "", from); - TlenP2PFreeFileTransfer(ft); - } - } - else if (!strcmp(e, "3")) { - // FILE_RECV : e='3' : invalid transfer error - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_FILE, p)) != NULL) { - if (item->ft != NULL) { - ProtoBroadcastAck(info->proto->iface.m_szModuleName, item->ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, item->ft, 0); - TlenFileCancel((PROTO_INTERFACE *)info->proto, NULL, item->ft); - } - JabberListRemove(info->proto, LIST_FILE, p); - } - } - } - else if (!strcmp(e, "4")) { - // FILE_SEND : e='4' : File sending request was denied by the remote client - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_FILE, p)) != NULL) { - if (!strcmp(item->ft->jid, jid)) { - ProtoBroadcastAck(info->proto->iface.m_szModuleName, item->ft->hContact, ACKTYPE_FILE, ACKRESULT_DENIED, item->ft, 0); - JabberListRemove(info->proto, LIST_FILE, p); - } - } - } - } - else if (!strcmp(e, "5")) { - // FILE_SEND : e='5' : File sending request was accepted - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_FILE, p)) != NULL) { - if (!strcmp(item->ft->jid, jid)) - JabberForkThread((void (__cdecl *)(void*))TlenFileSendingThread, 0, item->ft); - } - } - } - else if (!strcmp(e, "6")) { - // FILE_RECV : e='6' : IP and port information to connect to get file - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_FILE, p)) != NULL) { - if ((p=JabberXmlGetAttrValue(node, "a")) != NULL) { - item->ft->hostName = mir_strdup(p); - if ((p=JabberXmlGetAttrValue(node, "p")) != NULL) { - item->ft->wPort = atoi(p); - JabberForkThread((void (__cdecl *)(void*))TlenFileReceiveThread, 0, item->ft); - } - } - } - } - } - else if (!strcmp(e, "7")) { - // FILE_RECV : e='7' : IP and port information to connect to send file - // in case the conection to the given server was not successful - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_FILE, p)) != NULL) { - if ((p=JabberXmlGetAttrValue(node, "a")) != NULL) { - if (item->ft->hostName!=NULL) mir_free(item->ft->hostName); - item->ft->hostName = mir_strdup(p); - if ((p=JabberXmlGetAttrValue(node, "p")) != NULL) { - item->ft->wPort = atoi(p); - item->ft->state = FT_SWITCH; - SetEvent(item->ft->hFileEvent); - } - } - } - } - } - else if (!strcmp(e, "8")) { - // FILE_RECV : e='8' : transfer error - if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { - if ((item=JabberListGetItemPtr(info->proto, LIST_FILE, p)) != NULL) { - item->ft->state = FT_ERROR; - if (item->ft->hFileEvent != NULL) { - SetEvent(item->ft->hFileEvent); - } else { - ProtoBroadcastAck(info->proto->iface.m_szModuleName, item->ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, item->ft, 0); - } - } - } - } - } - } -} diff --git a/!NotAdopted/Tlen/tlen_file.h b/!NotAdopted/Tlen/tlen_file.h deleted file mode 100644 index 40527a2bcb..0000000000 --- a/!NotAdopted/Tlen/tlen_file.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#ifndef _TLEN_FILE_H_ -#define _TLEN_FILE_H_ - -#include -#include "jabber.h" - -extern int TlenFileCancelAll(TlenProtocol *proto); -extern void TlenProcessF(XmlNode *node, ThreadData *userdata); -extern TLEN_FILE_TRANSFER *TlenFileCreateFT(TlenProtocol *proto, const char *jid); -#endif - diff --git a/!NotAdopted/Tlen/tlen_muc.c b/!NotAdopted/Tlen/tlen_muc.c deleted file mode 100644 index 0b8e7534f5..0000000000 --- a/!NotAdopted/Tlen/tlen_muc.c +++ /dev/null @@ -1,1071 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include "jabber_list.h" -#include "jabber_iq.h" -#include "resource.h" -#include "tlen_muc.h" - -static int TlenMUCHandleEvent(void *ptr, WPARAM wParam, LPARAM lParam); -static int TlenMUCQueryContacts(TlenProtocol *proto, const char *roomId); -static int TlenMUCSendInvitation(TlenProtocol *proto, const char *roomID, const char *user); -static int TlenMUCSendPresence(TlenProtocol *proto, const char *roomID, const char *nick, int desiredStatus); -static int TlenMUCSendMessage(TlenProtocol *proto, MUCCEVENT *event); -static int TlenMUCSendTopic(TlenProtocol *proto, MUCCEVENT *event); -static int TlenMUCSendQuery(TlenProtocol *proto, int type, const char *parent, int page); - -static int isSelf(TlenProtocol *proto, const char *roomID, const char *nick) -{ - JABBER_LIST_ITEM *item; - int result; - result=0; - item = JabberListGetItemPtr(proto, LIST_CHATROOM, roomID); - if (item!=NULL) { - if (item->nick==NULL) { - if (!strcmp(nick, proto->threadData->username)) result = 1; - } else if (nick[0]=='~') { - if (!strcmp(nick+1, item->nick)) { - result = 1; - } - } - } - return result; -} - -static int stringToHex(const char *str) -{ - int i, val; - val = 0; - for (i=0;i<2;i++) { - val <<= 4; - if (str[i]>='A' && str[i]<='F') { - val += 10 + str[i]-'A'; - } else if (str[i]>='0' && str[i]<='9') { - val += str[i]-'0'; - } - } - return val; - -} -static char *getDisplayName(TlenProtocol *proto, const char *id) -{ - CONTACTINFO ci; - char jid[256]; - HANDLE hContact; - DBVARIANT dbv; - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { - _snprintf(jid, sizeof(jid), "%s@%s", id, dbv.pszVal); - DBFreeVariant(&dbv); - if (((hContact=JabberHContactFromJID(proto, jid)) != NULL) || !strcmp(id, proto->threadData->username)) { - ZeroMemory(&ci, sizeof(ci)); - ci.cbSize = sizeof(ci); - ci.hContact = hContact; - ci.szProto = (char *)proto->iface.m_szModuleName; - ci.dwFlag = CNF_DISPLAY; - if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) { - if (ci.type == CNFT_ASCIIZ) { - if (ci.pszVal) { - char * str = mir_strdup((char *)ci.pszVal); - miranda_sys_free(ci.pszVal); - return str; - } - } - } - } - } - return mir_strdup(id); -} - -BOOL TlenMUCInit(TlenProtocol *proto) -{ - HookEventObj_Ex(ME_MUCC_EVENT, proto, TlenMUCHandleEvent); - return 0; -} -static int TlenMUCHandleEvent(void *ptr, WPARAM wParam, LPARAM lParam) -{ - HANDLE hContact; - int id; - MUCCEVENT *mucce=(MUCCEVENT *) lParam; - TlenProtocol *proto = (TlenProtocol *)ptr; - if (!strcmp(mucce->pszModule, proto->iface.m_szModuleName)) { - switch (mucce->iType) { - case MUCC_EVENT_INVITE: - TlenMUCSendInvitation(proto, mucce->pszID, mucce->pszNick); - break; - case MUCC_EVENT_MESSAGE: - TlenMUCSendMessage(proto, mucce); - break; - case MUCC_EVENT_TOPIC: - TlenMUCSendTopic(proto, mucce); - break; - case MUCC_EVENT_LEAVE: - TlenMUCSendPresence(proto, mucce->pszID, NULL, ID_STATUS_OFFLINE); - break; - case MUCC_EVENT_QUERY_GROUPS: - TlenMUCSendQuery(proto, 1, mucce->pszID, 0); - break; - case MUCC_EVENT_QUERY_ROOMS: - TlenMUCSendQuery(proto, 2, mucce->pszID, mucce->dwData); - break; - case MUCC_EVENT_QUERY_SEARCH: - TlenMUCSendQuery(proto, 3, mucce->pszName, 0); - break; - case MUCC_EVENT_QUERY_USERS: - switch (mucce->dwFlags) { - case MUCC_EF_USER_OWNER: - id = 1; - break; - case MUCC_EF_USER_ADMIN: - id = 2; - break; - case MUCC_EF_USER_MEMBER: - id = 3; - break; - case MUCC_EF_USER_BANNED: - id = 4; - break; - case MUCC_EF_USER_MODERATOR: - id = 6; - break; - default: - id = 0; - } - TlenMUCSendQuery(proto, 4, mucce->pszID, id); - break; - case MUCC_EVENT_REGISTER_NICK: - TlenMUCSendQuery(proto, 6, mucce->pszNick, 0); - break; - case MUCC_EVENT_REMOVE_NICK: - TlenMUCSendQuery(proto, 6, mucce->pszNick, 1); - break; - case MUCC_EVENT_REGISTER_ROOM: - id = JabberSerialNext(proto); - if (proto->isOnline) { - if (mucce->pszNick!=NULL) { - JabberSend(proto, "

", id, mucce->dwFlags | 0x10, mucce->pszName, mucce->pszID); - } else { - JabberSend(proto, "

", id, mucce->dwFlags | 0x10, mucce->pszName, mucce->pszID); - } - } - break; - case MUCC_EVENT_REMOVE_ROOM: - if (proto->isOnline) { - JabberSend(proto, "

", mucce->pszID); - JabberListRemove(proto, LIST_CHATROOM, mucce->pszID); - // TlenMUCSendPresence(mucce->pszID, NULL, ID_STATUS_OFFLINE); - } - break; - case MUCC_EVENT_KICK_BAN: - if (proto->isOnline) { - char *nick; - nick = JabberResourceFromJID(mucce->pszUID); - if (!isSelf(proto, mucce->pszID, nick)) { - char *reason = JabberTextEncode(mucce->pszText); - JabberSend(proto, "

", mucce->pszID, nick, mucce->dwData, reason); - mir_free(reason); - } - mir_free(nick); - } - break; - case MUCC_EVENT_UNBAN: - if (proto->isOnline) { - char *nick; - nick = JabberResourceFromJID(mucce->pszUID); - if (!isSelf(proto, mucce->pszID, nick)) { - JabberSend(proto, "

", mucce->pszID, nick); - } - mir_free(nick); - } - break; - case MUCC_EVENT_SET_USER_ROLE: - if (proto->isOnline) { - char *nick; - nick = JabberResourceFromJID(mucce->pszUID); - if (!isSelf(proto, mucce->pszID, nick)) { - if (mucce->dwFlags == MUCC_EF_USER_ADMIN) { - id = 2; - } else if (mucce->dwFlags == MUCC_EF_USER_MEMBER) { - id = 3; - } else { - id = 0; - } - JabberSend(proto, "

", mucce->pszID, nick, id); - } - mir_free(nick); - } - break; - case MUCC_EVENT_QUERY_USER_NICKS: - TlenMUCSendQuery(proto, 7, mucce->pszID, 0); - break; - case MUCC_EVENT_QUERY_USER_ROOMS: - TlenMUCSendQuery(proto, 8, mucce->pszID, 0); - break; - case MUCC_EVENT_QUERY_CONTACTS: - TlenMUCQueryContacts(proto, mucce->pszID); - break; - case MUCC_EVENT_JOIN: - if (proto->isOnline) { - if (mucce->pszID==NULL || strlen(mucce->pszID)==0) { - if (mucce->pszName==NULL || strlen(mucce->pszName)==0) { // create a new chat room - id = JabberSerialNext(proto); - JabberSend(proto, "

", id); - } else { // find a chat room by name - TlenMUCSendQuery(proto, 3, mucce->pszName, 0); - } - } else { // join existing chat room - if (!TlenMUCCreateWindow(proto, mucce->pszID, mucce->pszName, mucce->dwFlags, mucce->pszNick, NULL)) { - TlenMUCSendPresence(proto, mucce->pszID, mucce->pszNick, ID_STATUS_ONLINE); - } - } - } - break; - case MUCC_EVENT_START_PRIV: - if (proto->isOnline) { - JABBER_LIST_ITEM *item; - item = JabberListGetItemPtr(proto, LIST_CHATROOM, mucce->pszID); - if (item!=NULL) { - char *nick; - nick = JabberResourceFromJID(mucce->pszUID); - if (!isSelf(proto, mucce->pszID, nick)) { - if (nick[0]=='~' || item->nick!=NULL) { - char str[256]; - sprintf(str, "%s/%s", mucce->pszID, nick); - hContact = JabberDBCreateContact(proto, str, nick, TRUE); //(char *)mucce->pszUID - DBWriteContactSettingByte(hContact, proto->iface.m_szModuleName, "bChat", TRUE); - CallService(MS_MSG_SENDMESSAGE, (WPARAM) hContact, (LPARAM) NULL); - } else { - DBVARIANT dbv; - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { - char str[512]; - _snprintf(str, sizeof(str), "%s@%s", nick, dbv.pszVal); - DBFreeVariant(&dbv); - hContact = JabberDBCreateContact(proto, str, nick, TRUE); - CallService(MS_MSG_SENDMESSAGE, (WPARAM) hContact, (LPARAM) NULL); - } - } - } - mir_free(nick); - } - } - break; - } - } - return 0; -} - -int TlenMUCRecvInvitation(TlenProtocol *proto, const char *roomId, const char *roomName, const char *from, const char *reason) -{ - char *nick; - int ignore, ask, groupChatPolicy; - if (roomId == NULL) return 1; - groupChatPolicy = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "GroupChatPolicy", 0); - ask = TRUE; - ignore = FALSE; - if (groupChatPolicy == TLEN_MUC_ASK) { - ignore = FALSE; - ask = TRUE; - } else if (groupChatPolicy == TLEN_MUC_IGNORE_ALL) { - ignore = TRUE; - } else if (groupChatPolicy == TLEN_MUC_IGNORE_NIR) { - char jid[256]; - JABBER_LIST_ITEM *item; - DBVARIANT dbv; - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { - _snprintf(jid, sizeof(jid), "%s@%s", from, dbv.pszVal); - DBFreeVariant(&dbv); - } else { - strcpy(jid, from); - } - ignore = !IsAuthorized(proto, jid); - ask = TRUE; - } else if (groupChatPolicy == TLEN_MUC_ACCEPT_IR) { - char jid[256]; - JABBER_LIST_ITEM *item; - DBVARIANT dbv; - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { - _snprintf(jid, sizeof(jid), "%s@%s", from, dbv.pszVal); - DBFreeVariant(&dbv); - } else { - strcpy(jid, from); - } - item = JabberListGetItemPtr(proto, LIST_ROSTER, jid); - ask = !IsAuthorized(proto, jid); - ignore = FALSE; - } else if (groupChatPolicy == TLEN_MUC_ACCEPT_ALL) { - ask = FALSE; - ignore = FALSE; - } - if (!ignore) { - if (ask) { - MUCCEVENT mucce; - mucce.cbSize = sizeof(MUCCEVENT); - mucce.pszModule = proto->iface.m_szModuleName; - mucce.pszID = roomId; - mucce.pszName = roomName; - mucce.iType = MUCC_EVENT_INVITATION; - mucce.pszUID = from; - nick = getDisplayName(proto, from); - mucce.pszNick = nick; - mucce.pszText = reason; - CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); - mir_free(nick); - } else { - if (!TlenMUCCreateWindow(proto, roomId, roomName, 0, NULL, NULL)) { - TlenMUCSendPresence(proto, roomId, NULL, ID_STATUS_ONLINE); - } - } - } - return 0; -} - -int TlenMUCRecvPresence(TlenProtocol *proto, const char *from, int status, int flags, const char *kick) -{ - char str[512]; -// if (JabberListExist(LIST_CHATROOM, from)) { - char *nick, *roomId, *userId; - MUCCEVENT mucce; - roomId = JabberLoginFromJID(from); - userId = JabberResourceFromJID(from); - nick = getDisplayName(proto, userId); - mucce.cbSize = sizeof(MUCCEVENT); - mucce.pszModule = proto->iface.m_szModuleName; - mucce.pszID = roomId; - mucce.iType = MUCC_EVENT_STATUS; - mucce.pszUID = userId;//from; - mucce.pszNick = nick; - mucce.time = time(NULL); - mucce.bIsMe = isSelf(proto, roomId, userId); - mucce.dwData = status; - mucce.dwFlags = 0; - if (flags & USER_FLAGS_GLOBALOWNER) mucce.dwFlags |= MUCC_EF_USER_GLOBALOWNER; - if (flags & USER_FLAGS_OWNER) mucce.dwFlags |= MUCC_EF_USER_OWNER; - if (flags & USER_FLAGS_ADMIN) mucce.dwFlags |= MUCC_EF_USER_ADMIN; - if (flags & USER_FLAGS_REGISTERED) mucce.dwFlags |= MUCC_EF_USER_REGISTERED; - if (status == ID_STATUS_OFFLINE && mucce.bIsMe && kick!=NULL) { - mucce.iType = MUCC_EVENT_ERROR; - sprintf(str, Translate("You have been kicked. Reason: %s "), kick); - mucce.pszText = str; - } - CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); - mir_free(roomId); - mir_free(userId); - mir_free(nick); -// } - return 0; -} - -int TlenMUCRecvMessage(TlenProtocol *proto, const char *from, long timestamp, XmlNode *bodyNode) -{ -// if (JabberListExist(LIST_CHATROOM, from)) { - char *localMessage; - char *nick, *style, *roomId, *userId; - int iStyle; - MUCCEVENT mucce; - roomId = JabberLoginFromJID(from); - userId = JabberResourceFromJID(from); - nick = getDisplayName(proto, userId); - localMessage = JabberTextDecode(bodyNode->text); - mucce.cbSize = sizeof(MUCCEVENT); - mucce.iType = MUCC_EVENT_MESSAGE; - mucce.pszID = roomId; - mucce.pszModule = proto->iface.m_szModuleName; - mucce.pszText = localMessage; - mucce.pszUID = userId;//from; - mucce.pszNick = nick; - mucce.time = timestamp; - mucce.bIsMe = isSelf(proto, roomId, userId); - mucce.dwFlags = 0; - mucce.iFontSize = 0; - style = JabberXmlGetAttrValue(bodyNode, "f"); - if (style!=NULL) { - iStyle = atoi(style); - if (iStyle & 1) mucce.dwFlags |= MUCC_EF_FONT_BOLD; - if (iStyle & 2) mucce.dwFlags |= MUCC_EF_FONT_ITALIC; - if (iStyle & 4) mucce.dwFlags |= MUCC_EF_FONT_UNDERLINE; - } - style = JabberXmlGetAttrValue(bodyNode, "c"); - if (style!=NULL && strlen(style)>5) { - iStyle = (stringToHex(style)<<16) | (stringToHex(style+2)<<8) | stringToHex(style+4); - } else { - iStyle = 0xFFFFFFFF; - } - mucce.color = (COLORREF) iStyle; - style = JabberXmlGetAttrValue(bodyNode, "s"); - if (style!=NULL) { - iStyle = atoi(style); - } else { - iStyle = 0; - } - mucce.iFontSize = iStyle; - style = JabberXmlGetAttrValue(bodyNode, "n"); - if (style!=NULL) { - iStyle = atoi(style)-1; - } else { - iStyle = 0; - } - mucce.iFont = iStyle; - CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); - mir_free(roomId); - mir_free(userId); - mir_free(nick); - mir_free(localMessage); -// } - return 0; -} -int TlenMUCRecvTopic(TlenProtocol *proto, const char *from, const char *subject) -{ -// if (JabberListExist(LIST_CHATROOM, from)) { - MUCCEVENT mucce; - mucce.cbSize = sizeof(MUCCEVENT); - mucce.iType = MUCC_EVENT_TOPIC; - mucce.pszID = from; - mucce.pszModule = proto->iface.m_szModuleName; - mucce.pszText = subject; - mucce.time = time(NULL); - CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); -// } - return 0; -} - -int TlenMUCRecvError(TlenProtocol *proto, const char *from, XmlNode *errorNode) -{ - int errCode; - char str[512]; - JABBER_LIST_ITEM *item; - MUCCEVENT mucce; - mucce.cbSize = sizeof(MUCCEVENT); - mucce.iType = MUCC_EVENT_ERROR; - mucce.pszID = from; - mucce.pszModule = proto->iface.m_szModuleName; - errCode = atoi(JabberXmlGetAttrValue(errorNode, "code")); - switch (errCode) { - case 403: - sprintf(str, Translate("You cannot join this chat room, because you are banned.")); - break; - case 404: - sprintf(str, Translate("Chat room not found.")); - break; - case 407: - sprintf(str, Translate("This is a private chat room and you are not one of the members.")); - break; - case 408: - sprintf(str, Translate("You cannot send any message unless you join this chat room.")); - break; - case 410: - sprintf(str, Translate("Chat room with already created.")); - break; - case 411: - sprintf(str, Translate("Nickname '%s' is already registered."), - JabberXmlGetAttrValue(errorNode, "n")); - break; - case 412: - sprintf(str, Translate("Nickname already in use, please try another one. Hint: '%s' is free."), - JabberXmlGetAttrValue(errorNode, "free")); - break; - case 413: - sprintf(str, Translate("You cannot register more than %s nicknames."), - JabberXmlGetAttrValue(errorNode, "num")); - break; - case 414: - sprintf(str, Translate("You cannot create more than %s chat rooms."), - JabberXmlGetAttrValue(errorNode, "num")); - break; - case 415: - sprintf(str, Translate("You cannot join more than %s chat rooms."), - JabberXmlGetAttrValue(errorNode, "num")); - break; - case 601: - sprintf(str, Translate("Anonymous nicknames are not allowed in this chat room.")); - break; - default: - sprintf(str, Translate("Unknown error code : %d"), errCode); - break; - } - mucce.pszText = str; - CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); - if (proto->isOnline) { - switch (errCode) { - case 412: - item = JabberListGetItemPtr(proto, LIST_CHATROOM, from); - if (item!=NULL) { - mucce.iType = MUCC_EVENT_JOIN; - mucce.dwFlags = MUCC_EF_ROOM_NICKNAMES; - mucce.pszModule = proto->iface.m_szModuleName; - mucce.pszID = from; - mucce.pszName = item->roomName; - mucce.pszNick = JabberXmlGetAttrValue(errorNode, "free"); - CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); - } - break; - case 601: - item = JabberListGetItemPtr(proto, LIST_CHATROOM, from); - if (item!=NULL) { - mucce.iType = MUCC_EVENT_JOIN; - mucce.dwFlags = 0; - mucce.pszModule = proto->iface.m_szModuleName; - mucce.pszID = from; - mucce.pszName = item->roomName; - mucce.pszNick = NULL; - CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); - } - break; - } - } - return 1; -} -static int TlenMUCSendInvitation(TlenProtocol *proto, const char *roomID, const char *user) -{ - if (!proto->isOnline) { - return 1; - } - JabberSend(proto, "", roomID, user); - return 0; -} - -static int TlenMUCSendPresence(TlenProtocol *proto, const char *roomID, const char *nick, int desiredStatus) -{ - char str[512]; - char *jid; - JABBER_LIST_ITEM *item; - if (!proto->isOnline) { - return 1; - } - if (nick!=NULL) { - _snprintf(str, sizeof(str), "%s/%s", roomID, nick); - } else { - _snprintf(str, sizeof(str), "%s", roomID); - } - if ((jid = JabberTextEncode(str))!=NULL) { - switch (desiredStatus) { - case ID_STATUS_ONLINE: - JabberSend(proto, "

", jid); - item = JabberListGetItemPtr(proto, LIST_CHATROOM, roomID); - if (item!=NULL) { - if (item->nick!=NULL) mir_free(item->nick); - item->nick = NULL; - if (nick!=NULL) { - item->nick = mir_strdup(nick); - } - } - break; - default: - item = JabberListGetItemPtr(proto, LIST_CHATROOM, roomID); - if (item!=NULL) { - JabberSend(proto, "

unavailable

", jid); - JabberListRemove(proto, LIST_CHATROOM, roomID); - } - break; - } - mir_free(jid); - } - return 0; -} - -static int TlenMUCSendMessage(TlenProtocol *proto, MUCCEVENT *event) -{ - char *msg, *jid; - int style; - - if (!proto->isOnline) { - return 1; - } - if ((msg = JabberTextEncode(event->pszText))!=NULL) { - if ((jid = JabberTextEncode(event->pszID))!=NULL) { - style = 0; - if (event->dwFlags & MUCC_EF_FONT_BOLD) style |=1; - if (event->dwFlags & MUCC_EF_FONT_ITALIC) style |=2; - if (event->dwFlags & MUCC_EF_FONT_UNDERLINE) style |=4; - JabberSend(proto, "%s", jid, event->iFont+1, event->iFontSize, style, event->color, msg); - mir_free(jid); - } - mir_free(msg); - } - return 0; -} - -static int TlenMUCSendTopic(TlenProtocol *proto, MUCCEVENT *event) -{ - char *msg, *jid; - if (!proto->isOnline) { - return 1; - } - if ((msg = JabberTextEncode(event->pszText))!=NULL) { - if ((jid = JabberTextEncode(event->pszID))!=NULL) { - JabberSend(proto, "%s", jid, msg); - mir_free(jid); - } - mir_free(msg); - } - return 0; -} - -static int TlenMUCSendQuery(TlenProtocol *proto, int type, const char *parent, int page) -{ - if (!proto->isOnline) { - return 1; - } - if (type==3) { // find chat room by name - char serialId[32]; - JABBER_LIST_ITEM *item; - sprintf(serialId, JABBER_IQID"%d", JabberSerialNext(proto)); - item = JabberListAdd(proto, LIST_SEARCH, serialId); - item->roomName = mir_strdup(parent); - JabberSend(proto, "", parent, serialId); - } else { - if (parent==NULL) { - JabberSend(proto, "", type); - } else { // 1 - groups, 2 - chat rooms, 7 - user nicks, 8 - user rooms - if (type==1 || (type==2 && page==0) || type==7 || type==8) { - JabberSend(proto, "", type, parent); - } else if (type==2) { - JabberSend(proto, "", type, parent, page); - } else if (type==6) { - if (page) { - JabberSend(proto, "", type, parent); - } else { - JabberSend(proto, "", type, parent); - } - } else if (type==4) { // list of users, admins etc. - JabberSend(proto, "", parent, type, page); - } - } - } - return 0; -} - -int TlenMUCCreateWindow(TlenProtocol *proto, const char *roomID, const char *roomName, int roomFlags, const char *nick, const char *iqId) -{ - JABBER_LIST_ITEM *item; - MUCCWINDOW mucw; - if (!proto->isOnline || roomID==NULL) { - return 1; - } - if (JabberListExist(proto, LIST_CHATROOM, roomID)) { - return 0; - } - item = JabberListAdd(proto, LIST_CHATROOM, roomID); - if (roomName!=NULL) { - item->roomName = mir_strdup(roomName); - } - if (nick!=NULL) { - item->nick = mir_strdup(nick); - } - mucw.cbSize = sizeof(MUCCWINDOW); - mucw.iType = MUCC_WINDOW_CHATROOM; - mucw.pszModule = proto->iface.m_szModuleName; - mucw.pszModuleName = proto->iface.m_szProtoName; - mucw.pszID = roomID; - mucw.pszName = roomName; - mucw.pszNick = nick; - mucw.dwFlags = roomFlags; - mucw.pszStatusbarText = "hello"; - CallService(MS_MUCC_NEW_WINDOW, 0, (LPARAM) &mucw); - if (iqId != NULL) { - item = JabberListGetItemPtr(proto, LIST_INVITATIONS, iqId); - if (item !=NULL) { - TlenMUCSendInvitation(proto, roomID, item->nick); - } - JabberListRemove(proto, LIST_INVITATIONS, iqId); - } - return 0; -} - -static void TlenMUCFreeQueryResult(MUCCQUERYRESULT *result) -{ int i; - for (i=0; iiItemsNum; i++) { - if (result->pItems[i].pszID != NULL) { - mir_free((char *) result->pItems[i].pszID); - } - if (result->pItems[i].pszName != NULL) { - mir_free((char *) result->pItems[i].pszName); - } - if (result->pItems[i].pszNick != NULL) { - mir_free((char *) result->pItems[i].pszNick); - } - if (result->pItems[i].pszText != NULL) { - mir_free((char *) result->pItems[i].pszText); - } - } - mir_free((MUCCQUERYITEM *)result->pItems); -} - -void TlenIqResultChatGroups(TlenProtocol *proto, XmlNode *iqNode) -{ - XmlNode *lNode, *itemNode; - char *p, *n, *id, *f; - int i, j; - MUCCQUERYRESULT queryResult; - - if ((lNode=JabberXmlGetChild(iqNode, "l")) == NULL) return; - p = JabberXmlGetAttrValue(iqNode, "p"); - if (p==NULL) { - p=""; - } - p = JabberTextDecode(p); - queryResult.cbSize = sizeof (MUCCQUERYRESULT); - queryResult.iType = MUCC_EVENT_QUERY_GROUPS; - queryResult.pszModule = proto->iface.m_szModuleName; - queryResult.pszParent = p; - queryResult.pItems = mir_alloc(sizeof(MUCCQUERYITEM) * lNode->numChild); - memset(queryResult.pItems, 0, sizeof(MUCCQUERYITEM) * lNode->numChild); - for (i=j=0; inumChild; i++) { - itemNode = lNode->child[i]; - if (!strcmp(itemNode->name, "i")) { - queryResult.pItems[j].iCount = 0; - if ((f = JabberXmlGetAttrValue(itemNode, "f")) != NULL) { - queryResult.pItems[j].iCount = !strcmp(f, "3"); - } - n = JabberXmlGetAttrValue(itemNode, "n"); - id = JabberXmlGetAttrValue(itemNode, "i"); - if (n != NULL && id != NULL) { - queryResult.pItems[j].pszID = JabberTextDecode(id); - queryResult.pItems[j].pszName = JabberTextDecode(n); - j++; - } - } - } - queryResult.iItemsNum = j; - CallService(MS_MUCC_QUERY_RESULT, 0, (LPARAM) &queryResult); - TlenMUCFreeQueryResult(&queryResult); - mir_free(p); -} - -void TlenIqResultChatRooms(TlenProtocol *proto, XmlNode *iqNode) -{ - XmlNode *lNode, *itemNode; - char *id, *c, *n, *x, *p, *px, *pn; - int i, j; - MUCCQUERYRESULT queryResult; - - if ((lNode=JabberXmlGetChild(iqNode, "l")) == NULL) return; - if ((p = JabberXmlGetAttrValue(iqNode, "p")) == NULL) return; - pn = JabberXmlGetAttrValue(lNode, "n"); - if (pn == NULL) pn = "0"; - px = JabberXmlGetAttrValue(lNode, "x"); - if (px == NULL) px = "0"; - p = JabberTextDecode(p); - queryResult.cbSize = sizeof (MUCCQUERYRESULT); - queryResult.iType = MUCC_EVENT_QUERY_ROOMS; - queryResult.pszModule = proto->iface.m_szModuleName; - queryResult.pszParent = p; - queryResult.pItems = mir_alloc(sizeof(MUCCQUERYITEM) * lNode->numChild); - memset(queryResult.pItems, 0, sizeof(MUCCQUERYITEM) * lNode->numChild); - queryResult.iPage = atoi(pn); - queryResult.iLastPage = atoi(px)&2?1:0; - for (i=j=0; inumChild; i++) { - itemNode = lNode->child[i]; - if (!strcmp(itemNode->name, "i")) { - n = JabberXmlGetAttrValue(itemNode, "n"); - c = JabberXmlGetAttrValue(itemNode, "c"); - x = JabberXmlGetAttrValue(itemNode, "x"); - if ((id=JabberXmlGetAttrValue(itemNode, "i")) != NULL) { - queryResult.pItems[j].pszID = JabberTextDecode(id); - queryResult.pItems[j].pszName = JabberTextDecode(n); - queryResult.pItems[j].iCount = atoi(c); - queryResult.pItems[j].dwFlags = atoi(x); - j++; - } - } - } - queryResult.iItemsNum = j; - CallService(MS_MUCC_QUERY_RESULT, 0, (LPARAM) &queryResult); - TlenMUCFreeQueryResult(&queryResult); - mir_free(p); -} -void TlenIqResultUserRooms(TlenProtocol *proto, XmlNode *iqNode) -{ - XmlNode *lNode, *itemNode; - char *id, *n; - int i, j; - MUCCQUERYRESULT queryResult; - if ((lNode=JabberXmlGetChild(iqNode, "l")) == NULL) return; - queryResult.cbSize = sizeof (MUCCQUERYRESULT); - queryResult.iType = MUCC_EVENT_QUERY_USER_ROOMS; - queryResult.pszModule = proto->iface.m_szModuleName; - queryResult.pItems = mir_alloc(sizeof(MUCCQUERYITEM) * lNode->numChild); - memset(queryResult.pItems, 0, sizeof(MUCCQUERYITEM) * lNode->numChild); - for (i=j=0; inumChild; i++) { - itemNode = lNode->child[i]; - if (!strcmp(itemNode->name, "i")) { - n = JabberXmlGetAttrValue(itemNode, "n"); - id = JabberXmlGetAttrValue(itemNode, "i"); - if (n != NULL && id != NULL) { - queryResult.pItems[j].pszID = JabberTextDecode(id); - queryResult.pItems[j].pszName = JabberTextDecode(n); - j++; - } - } - } - queryResult.iItemsNum = j; - CallService(MS_MUCC_QUERY_RESULT, 0, (LPARAM) &queryResult); - TlenMUCFreeQueryResult(&queryResult); -} -void TlenIqResultUserNicks(TlenProtocol *proto, XmlNode *iqNode) -{ - XmlNode *lNode, *itemNode; - char *n; - int i, j; - MUCCQUERYRESULT queryResult; - if ((lNode=JabberXmlGetChild(iqNode, "l")) == NULL) return; - queryResult.cbSize = sizeof (MUCCQUERYRESULT); - queryResult.iType = MUCC_EVENT_QUERY_USER_NICKS; - queryResult.pszModule = proto->iface.m_szModuleName; - queryResult.pItems = mir_alloc(sizeof(MUCCQUERYITEM) * lNode->numChild); - memset(queryResult.pItems, 0, sizeof(MUCCQUERYITEM) * lNode->numChild); - for (i=j=0; inumChild; i++) { - itemNode = lNode->child[i]; - if (!strcmp(itemNode->name, "i")) { - n = JabberXmlGetAttrValue(itemNode, "n"); - queryResult.pItems[j].pszID = NULL;//JabberTextDecode(n); - queryResult.pItems[j].pszName = JabberTextDecode(n); - j++; - } - } - queryResult.iItemsNum = j; - CallService(MS_MUCC_QUERY_RESULT, 0, (LPARAM) &queryResult); - TlenMUCFreeQueryResult(&queryResult); -} -void TlenIqResultChatRoomUsers(TlenProtocol *proto, XmlNode *iqNode) -{ - XmlNode *lNode, *itemNode; - char *id, *n; - int i, j; - MUCCQUERYRESULT queryResult; - if ((lNode=JabberXmlGetChild(iqNode, "l")) == NULL) return; - if ((id=JabberXmlGetAttrValue(iqNode, "from")) == NULL) return; - queryResult.cbSize = sizeof (MUCCQUERYRESULT); - queryResult.iType = MUCC_EVENT_QUERY_USERS; - queryResult.pszModule = proto->iface.m_szModuleName; - queryResult.pszParent = id; - queryResult.pItems = mir_alloc(sizeof(MUCCQUERYITEM) * lNode->numChild); - memset(queryResult.pItems, 0, sizeof(MUCCQUERYITEM) * lNode->numChild); - for (i=j=0; inumChild; i++) { - itemNode = lNode->child[i]; - if (!strcmp(itemNode->name, "i")) { - id = JabberXmlGetAttrValue(itemNode, "i"); - if (id != NULL) { - queryResult.pItems[j].pszID = JabberTextDecode(id); - n = JabberXmlGetAttrValue(itemNode, "n"); - if (n!=NULL) { - queryResult.pItems[j].pszName = JabberTextDecode(n); - } - n = JabberXmlGetAttrValue(itemNode, "a"); - if (n!=NULL) { - queryResult.pItems[j].pszNick = JabberTextDecode(n); - } - n = JabberXmlGetAttrValue(itemNode, "r"); - if (n!=NULL) { - queryResult.pItems[j].pszText = JabberTextDecode(n); - } - n = JabberXmlGetAttrValue(itemNode, "e"); - if (n!=NULL) { - queryResult.pItems[j].iCount = atoi(n); - } - n = JabberXmlGetAttrValue(itemNode, "s"); - if (n!=NULL) { - queryResult.pItems[j].dwFlags = atoi(n); - } - j++; - } - } - } - queryResult.iItemsNum = j; - CallService(MS_MUCC_QUERY_RESULT, 0, (LPARAM) &queryResult); - TlenMUCFreeQueryResult(&queryResult); -} - -void TlenIqResultRoomSearch(TlenProtocol *proto, XmlNode *iqNode) -{ - char *iqId, *id; - JABBER_LIST_ITEM *item; - iqId=JabberXmlGetAttrValue(iqNode, "id"); - item=JabberListGetItemPtr(proto, LIST_SEARCH, iqId); - if ((id=JabberXmlGetAttrValue(iqNode, "i")) != NULL) { - MUCCEVENT mucce; - id = JabberTextDecode(id); - mucce.cbSize = sizeof(MUCCEVENT); - mucce.iType = MUCC_EVENT_JOIN; - mucce.pszModule = proto->iface.m_szModuleName; - mucce.pszID = id; - mucce.pszName = id; - if (item!=NULL) { - mucce.pszName = item->roomName; - } - mucce.pszNick = NULL; - mucce.dwFlags = MUCC_EF_ROOM_NICKNAMES; - CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); - mir_free(id); - } - JabberListRemove(proto, LIST_SEARCH, iqId); -} - -void TlenIqResultRoomInfo(TlenProtocol *proto, XmlNode *iqNode) -{ - char *id, *name, *group, *flags; - if ((id=JabberXmlGetAttrValue(iqNode, "from")) != NULL) { - if ((name=JabberXmlGetAttrValue(iqNode, "n")) != NULL) { - MUCCEVENT mucce; - group = JabberXmlGetAttrValue(iqNode, "cn"); - flags = JabberXmlGetAttrValue(iqNode, "x"); - id = JabberTextDecode(id); - name = JabberTextDecode(name); - mucce.cbSize = sizeof(MUCCEVENT); - mucce.iType = MUCC_EVENT_ROOM_INFO; - mucce.pszModule = proto->iface.m_szModuleName; - mucce.pszID = id; - mucce.pszName = name; - mucce.dwFlags = atoi(flags); - CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); - mir_free(id); - mir_free(name); - } - } -} - - -typedef struct { - TlenProtocol *proto; - char *roomId; -} MUCSENDQUERYTHREADDATA; - -static void __cdecl TlenMUCCSendQueryResultThread(void *ptr) -{ - HANDLE hContact; - MUCCQUERYRESULT queryResult; - DBVARIANT dbv; - MUCSENDQUERYTHREADDATA* threadData = (MUCSENDQUERYTHREADDATA*)ptr; - queryResult.cbSize = sizeof (MUCCQUERYRESULT); - queryResult.iType = MUCC_EVENT_QUERY_CONTACTS; - queryResult.pszModule = threadData->proto->iface.m_szModuleName; - queryResult.pszParent = threadData->roomId; - queryResult.iItemsNum = 0; - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - while (hContact != NULL) { - char *str = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); - if(str!=NULL && !strcmp(str, threadData->proto->iface.m_szModuleName)) { - if (!DBGetContactSettingByte(hContact, threadData->proto->iface.m_szModuleName, "bChat", FALSE)) { - if (!DBGetContactSetting(hContact, threadData->proto->iface.m_szModuleName, "jid", &dbv)) { - if (strcmp(dbv.pszVal, "b73@tlen.pl")) { - queryResult.iItemsNum++; - } - DBFreeVariant(&dbv); - } - } - } - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); - } - queryResult.pItems = mir_alloc(sizeof(MUCCQUERYITEM) * queryResult.iItemsNum); - memset(queryResult.pItems, 0, sizeof(MUCCQUERYITEM) * queryResult.iItemsNum); - queryResult.iItemsNum = 0; - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - while (hContact != NULL) { - char *baseProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); - if(baseProto!=NULL && !strcmp(baseProto, threadData->proto->iface.m_szModuleName)) { - if (!DBGetContactSettingByte(hContact, threadData->proto->iface.m_szModuleName, "bChat", FALSE)) { - if (!DBGetContactSetting(hContact, threadData->proto->iface.m_szModuleName, "jid", &dbv)) { - if (strcmp(dbv.pszVal, "b73@tlen.pl")) { - queryResult.pItems[queryResult.iItemsNum].pszID = mir_strdup(dbv.pszVal); - queryResult.pItems[queryResult.iItemsNum].pszName = mir_strdup((char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, 0)); - queryResult.iItemsNum++; - } - DBFreeVariant(&dbv); - } - } - } - hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); - } - CallService(MS_MUCC_QUERY_RESULT, 0, (LPARAM) &queryResult); - TlenMUCFreeQueryResult(&queryResult); - mir_free(threadData->roomId); - mir_free(threadData); -} - - -static int TlenMUCQueryContacts(TlenProtocol *proto, const char *roomId) { - - MUCSENDQUERYTHREADDATA *threadData = (MUCSENDQUERYTHREADDATA *)mir_alloc(sizeof(MUCSENDQUERYTHREADDATA)); - threadData->proto = proto; - threadData->roomId = mir_strdup(roomId); - JabberForkThread(TlenMUCCSendQueryResultThread, 0, (void *)threadData); - return 1; -} - - -INT_PTR TlenMUCMenuHandleMUC(void *ptr, WPARAM wParam, LPARAM lParam) -{ - TlenProtocol *proto = (TlenProtocol *)ptr; - if (!proto->isOnline) { - return 1; - } - JabberSend(proto, "

", JabberSerialNext(proto)); - /* - MUCCEVENT *mucce; - mucce = (MUCCEVENT *) mir_alloc (sizeof(MUCCEVENT)); - mucce->cbSize = sizeof(MUCCEVENT); - mucce->iType = MUCC_EVENT_JOIN; - mucce->dwFlags = 0; - mucce->pszModule = iface.m_szModuleName; - mucce->pszID = NULL; - mucce->pszName = NULL; - mucce->pszNick = NULL; - CallService(MS_MUCC_EVENT, 0, (LPARAM) mucce); - mir_free(mucce); - */ - return 0; -} - -INT_PTR TlenMUCMenuHandleChats(void *ptr, WPARAM wParam, LPARAM lParam) -{ - MUCCWINDOW mucw; - TlenProtocol *proto = (TlenProtocol *)ptr; - if (!proto->isOnline) { - return 1; - } - mucw.cbSize = sizeof(MUCCWINDOW); - mucw.iType = MUCC_WINDOW_CHATLIST; - mucw.pszModule = proto->iface.m_szModuleName; - mucw.pszModuleName = proto->iface.m_szProtoName; - CallService(MS_MUCC_NEW_WINDOW, 0, (LPARAM) &mucw); - return 0; -} - -INT_PTR TlenMUCContactMenuHandleMUC(void *ptr, WPARAM wParam, LPARAM lParam) -{ - HANDLE hContact; - DBVARIANT dbv; - JABBER_LIST_ITEM *item; - TlenProtocol *proto = (TlenProtocol *)ptr; - if (!proto->isOnline) { - return 1; - } - if ((hContact=(HANDLE) wParam)!=NULL && proto->isOnline) { - if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { - char serialId[32]; - sprintf(serialId, JABBER_IQID"%d", JabberSerialNext(proto)); - item = JabberListAdd(proto, LIST_INVITATIONS, serialId); - item->nick = mir_strdup(dbv.pszVal); - JabberSend(proto, "

", serialId); - DBFreeVariant(&dbv); - } - } - return 0; -} diff --git a/!NotAdopted/Tlen/tlen_muc.h b/!NotAdopted/Tlen/tlen_muc.h deleted file mode 100644 index fc1713a837..0000000000 --- a/!NotAdopted/Tlen/tlen_muc.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#ifndef _TLEN_MUC_H_ -#define _TLEN_MUC_H_ - -#include -#include "m_mucc.h" - -#define USER_FLAGS_OWNER 0x01 -#define USER_FLAGS_ADMIN 0x02 -#define USER_FLAGS_REGISTERED 0x04 -#define USER_FLAGS_GLOBALOWNER 0x08 -#define USER_FLAGS_KICKED 0x80 - -extern BOOL TlenMUCInit(TlenProtocol *proto); -extern INT_PTR TlenMUCMenuHandleMUC(void *ptr, WPARAM wParam, LPARAM lParam); -extern INT_PTR TlenMUCMenuHandleChats(void *ptr, WPARAM wParam, LPARAM lParam); -extern INT_PTR TlenMUCContactMenuHandleMUC(void *ptr, WPARAM wParam, LPARAM lParam); -extern int TlenMUCCreateWindow(TlenProtocol *proto, const char *roomID, const char *roomName, int roomFlags, const char *nick, const char *iqId); -extern int TlenMUCRecvInvitation(TlenProtocol *proto, const char *roomJid, const char *roomName, const char *from, const char *reason); -extern int TlenMUCRecvPresence(TlenProtocol *proto, const char *from, int status, int flags, const char *kick); -extern int TlenMUCRecvMessage(TlenProtocol *proto, const char *from, long timestamp, XmlNode *bodyNode); -extern int TlenMUCRecvTopic(TlenProtocol *proto, const char *from, const char *subject); -extern int TlenMUCRecvError(TlenProtocol *proto, const char *from, XmlNode *errorNode); - -#endif diff --git a/!NotAdopted/Tlen/tlen_p2p_new.c b/!NotAdopted/Tlen/tlen_p2p_new.c deleted file mode 100644 index 7d9c959a42..0000000000 --- a/!NotAdopted/Tlen/tlen_p2p_new.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include -#include -#include -#include -#include "jabber_list.h" -#include "tlen_p2p_old.h" - - -static void logInfo(const char *filename, const char *fmt, ...) { - SYSTEMTIME time; - char *str; - va_list vararg; - int strsize; - FILE *flog=fopen(filename,"at"); - if (flog!=NULL) { - GetLocalTime(&time); - va_start(vararg, fmt); - str = (char *) mir_alloc(strsize=2048); - while (_vsnprintf(str, strsize, fmt, vararg) == -1) - str = (char *) realloc(str, strsize+=2048); - va_end(vararg); - fprintf(flog,"%04d-%02d-%02d %02d:%02d:%02d,%03d [%s]",time.wYear,time.wMonth,time.wDay,time.wHour,time.wMinute,time.wSecond,time.wMilliseconds, "INFO"); - fprintf(flog," %s\n",str); - mir_free(str); - fclose(flog); - } -} - -void __cdecl TlenNewFileReceiveThread(TLEN_FILE_TRANSFER *ft) -{ - JabberLog(ft->proto, "P2P receive thread started"); - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, ft, 0); -// ft->mode = FT_RECV; -// ft->currentFile = 0; -// ft->state = FT_CONNECTING; - { - FILE * fout = fopen("tlen_recv.dxx", "wt"); - SOCKADDR_IN toad; - toad.sin_family = AF_INET; - toad.sin_addr.s_addr = inet_addr(ft->hostName); - toad.sin_port = htons(ft->wPort); - if (fout != NULL) { - fprintf(fout, "START:\n"); - } - if (fout != NULL) { - fclose(fout); - } - while (ft->udps != INVALID_SOCKET) { - SOCKADDR_IN cad; - int alen; - int j, n; - unsigned char buff[1024]; - alen = sizeof(struct sockaddr); - n=recvfrom(ft->udps, (char*)buff,sizeof(buff),0, (struct sockaddr *) &cad, &alen); - if (n<0) { - break; - } - logInfo("tlen_recv.dxx", "UDP"); - fout = fopen("tlen_recv.dxx", "at"); - if (fout != NULL) { - fprintf(fout, "\n|RECV %d bytes from %s:%d|",n, inet_ntoa(cad.sin_addr), cad.sin_port); - for (j = 0; j < n; j++) { - fprintf(fout, "%02X-", buff[j]); - } - } - if (n == 1) { - alen = sizeof(struct sockaddr); - n = sendto(ft->udps, (char*)buff, n, 0,(struct sockaddr *) &toad, alen); - if (fout != NULL) { - fprintf(fout, "\n|SEND |"); - for (j = 0; j < n; j++) { - fprintf(fout, "%02X-", buff[j]); - } - } - } - if (fout != NULL) { - fprintf(fout, "\n"); - fclose(fout); - } - } - } - if (ft->udps != INVALID_SOCKET) { - closesocket(ft->udps); - } - - JabberListRemove(ft->proto, LIST_FILE, ft->iqId); - if (ft->state==FT_DONE) - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); - else { - ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - } - JabberLog(ft->proto, "P2P receive thread ended"); - TlenP2PFreeFileTransfer(ft); -} - -void __cdecl TlenNewFileSendThread(TLEN_FILE_TRANSFER *ft) -{ - JabberLog(ft->proto, "P2P send thread started"); -// ft->mode = FT_RECV; -// ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, ft, 0); -// ft->currentFile = 0; -// ft->state = FT_CONNECTING; - { - FILE * fout = fopen("tlen_send.gxx", "wt"); - int step = 0; - SOCKADDR_IN toad; - toad.sin_family = AF_INET; - toad.sin_addr.s_addr = inet_addr(ft->hostName); - toad.sin_port = htons(ft->wPort); - - if (fout != NULL) { - fprintf(fout, "START:"); - } - if (fout != NULL) { - fclose(fout); - } - for (step = 0; step < 10; step ++) { -// while (ft->udps != INVALID_SOCKET) { - int alen; - int j, n; - unsigned char buff[1024]; - alen = sizeof(struct sockaddr); - if (step < 3 || step > 5) { - buff[0] = 1; - n = 1; - } else { - buff[0] = '$'; - buff[1] = '^'; - buff[2] = '&'; - buff[3] = '%'; - n = 4; - } - n=sendto(ft->udps, (char*)buff, n, 0, (struct sockaddr *)&toad, alen); - logInfo("tlen_send.dxx", "UDP"); - if (fout != NULL) { - fprintf(fout, "|send: %d %s %d|",n, inet_ntoa(toad.sin_addr), toad.sin_port); - for (j = 0; j < n; j++) { - fprintf(fout, "%02X-", buff[j]); - } - } - if (fout != NULL) { - fprintf(fout, "\n"); - fclose(fout); - } - SleepEx(1000, TRUE); - } - } - JabberLog(ft->proto, "P2P send thread ended"); -} - -void TlenBindUDPSocket(TLEN_FILE_TRANSFER *ft) -{ - JabberLog(ft->proto, "Binding UDP socket"); - ft->udps = socket(PF_INET, SOCK_DGRAM, 0); - if (ft->udps != INVALID_SOCKET) { - SOCKADDR_IN sin; - int len = sizeof(struct sockaddr); - memset((char *)&sin,0,sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = htonl(INADDR_ANY);; - sin.sin_port = 0; - if (bind(ft->udps, (struct sockaddr *)&sin, sizeof(sin)) >= 0) { - if(!getsockname((SOCKET)ft->udps,(SOCKADDR *)&sin,&len)) { - struct hostent *hp; - char host_name[256]; - gethostname(host_name, sizeof(host_name)); - hp = gethostbyname(host_name); - mir_snprintf(host_name, sizeof(host_name), "%u.%u.%u.%u", (unsigned char)hp->h_addr_list[0][0], - (unsigned char)hp->h_addr_list[0][1], - (unsigned char)hp->h_addr_list[0][2], - (unsigned char)hp->h_addr_list[0][3]); - - ft->wLocalPort = ntohs(sin.sin_port); - ft->localName= mir_strdup(host_name); - JabberLog(ft->proto, "UDP socket bound to %s:%d", ft->localName, ft->wLocalPort); - } - } - } -} - - -/* -aaa sends a file to bbb: - -1) aaa wants to SEND bbb a file -A SEND: -B RECV: - -2) bbb ACCEPTs -B SEND: -A RECV: - -3) aaa tries to establish p2p connection: -A SEND: -B SEND: - -3) bbb sends IP/port details -B SEND: - -*/ - -void TlenProcessP2P(XmlNode *node, ThreadData *info) { - XmlNode *queryNode; - JABBER_LIST_ITEM *item; - char *from; - - if (info == NULL) return; - - queryNode = JabberXmlGetChild(node, "query"); - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - XmlNode *fs , *vs, *dcng, *dc; - /* file send */ - fs = JabberXmlGetChild(queryNode, "fs"); - /* voice send */ - vs = JabberXmlGetChild(queryNode, "vs"); - dcng = JabberXmlGetChild(queryNode, "dcng"); - dc = JabberXmlGetChild(queryNode, "dc"); - if (fs != NULL) { - char *e, *id; - /* e - step in the process (starting with 1)*/ - /* i - id of the file */ - /* s - size of the file */ - /* c - number of files */ - /* v - ??? */ - e = JabberXmlGetAttrValue(fs, "e"); - id = JabberXmlGetAttrValue(fs, "i"); - if (e != NULL) { - if (!strcmp(e, "1")) { - CCSDATA ccs; - PROTORECVEVENT pre; - char *c, *s; - TLEN_FILE_TRANSFER * ft = (TLEN_FILE_TRANSFER *) mir_alloc(sizeof(TLEN_FILE_TRANSFER)); - memset(ft, 0, sizeof(TLEN_FILE_TRANSFER)); - c = JabberXmlGetAttrValue(fs, "c"); - s = JabberXmlGetAttrValue(fs, "s"); - ft->jid = mir_strdup(from); - ft->proto = info->proto; - ft->hContact = JabberHContactFromJID(info->proto, from); - ft->iqId = mir_strdup(id); - ft->fileTotalSize = atoi(s); - ft->newP2P = TRUE; - if ((item=JabberListAdd(ft->proto, LIST_FILE, ft->iqId)) != NULL) { - char *szBlob; - char fileInfo[128]; - item->ft = ft; - mir_snprintf(fileInfo, sizeof(fileInfo), "%s file(s), %s bytes", c, s); - // blob is DWORD(*ft), ASCIIZ(filenames), ASCIIZ(description) - szBlob = (char *) mir_alloc(sizeof(DWORD) + strlen(fileInfo) + 2); - *((PDWORD) szBlob) = (DWORD) ft; - strcpy(szBlob + sizeof(DWORD), fileInfo); - szBlob[sizeof(DWORD) + strlen(fileInfo) + 1] = '\0'; - pre.flags = 0; - pre.timestamp = time(NULL); - pre.szMessage = szBlob; - pre.lParam = 0; - ccs.szProtoService = PSR_FILE; - ccs.hContact = ft->hContact; - ccs.wParam = 0; - ccs.lParam = (LPARAM) ⪯ - JabberLog(ft->proto, "sending chainrecv"); - CallService(MS_PROTO_CHAINRECV, 0, (LPARAM) &ccs); - mir_free(szBlob); - } - } else if (!strcmp(e, "3")) { - /* transfer error */ - } else if (!strcmp(e, "4")) { - /* transfer denied */ - } else if (!strcmp(e, "5")) { - /* transfer accepted */ - if ((item=JabberListGetItemPtr(info->proto, LIST_FILE, id)) != NULL) { - item->id2 = mir_strdup("84273372"); - item->ft->id2 = mir_strdup("84273372"); - JabberSend(info->proto, "", from, item->id2, id); - } - } - } - } else if (vs != NULL) { - - } else if (dcng != NULL) { - char *s, *id, *id2; - JabberLog(info->proto, "DCNG"); - s = JabberXmlGetAttrValue(dcng, "s"); - id2 = JabberXmlGetAttrValue(dcng, "i"); - id = JabberXmlGetAttrValue(dcng, "mi"); - if (!strcmp(s, "1")) { - /* Keys */ - /* n - name (file_send) */ - /* k - ??? */ - /* v - ??? */ - /* s - step */ - /* i - id of the file */ - /* ck - aes key */ - /* ks - key size (in bytes) */ - /* iv - aes initial vector */ - /* mi - p2p connection id */ - char *n, *k, *v, *ck, *ks, *iv; - n = JabberXmlGetAttrValue(dcng, "n"); - k = JabberXmlGetAttrValue(dcng, "k"); - v = JabberXmlGetAttrValue(dcng, "v"); - ck = JabberXmlGetAttrValue(dcng, "ck"); - iv = JabberXmlGetAttrValue(dcng, "iv"); - if (!strcmp(n, "file_send")) { - if ((item=JabberListGetItemPtr(info->proto, LIST_FILE, id)) != NULL) { - item->id2 = mir_strdup(id2); - item->ft->id2 = mir_strdup(id2); - TlenBindUDPSocket(item->ft); - JabberSend(info->proto, "", - item->ft->jid, item->ft->localName, item->ft->wLocalPort, item->ft->localName, item->ft->wLocalPort, item->ft->id2); - } - } - } else if (!strcmp(s, "2")) { - JabberLog(info->proto, "step = 2"); - JabberLog(info->proto, "%s",from); - JabberLog(info->proto, "%s",id2); - /* IP and port */ - if ((item=JabberListFindItemPtrById2(info->proto, LIST_FILE, id2)) != NULL) { - item->ft->hostName = mir_strdup(JabberXmlGetAttrValue(dcng, "pa")); - item->ft->wPort = atoi(JabberXmlGetAttrValue(dcng, "pp")); - TlenBindUDPSocket(item->ft); - JabberSend(info->proto, "", - item->ft->jid, item->ft->localName, item->ft->wLocalPort, item->ft->localName, item->ft->wLocalPort, item->ft->id2); - JabberForkThread((void (__cdecl *)(void*))TlenNewFileReceiveThread, 0, item->ft); - JabberForkThread((void (__cdecl *)(void*))TlenNewFileSendThread, 0, item->ft); - } - } else if (!strcmp(s, "4")) { - /* IP and port */ - if ((item=JabberListFindItemPtrById2(info->proto, LIST_FILE, id2)) != NULL) { - JabberLog(info->proto, "step = 4"); - item->ft->hostName = mir_strdup(JabberXmlGetAttrValue(dcng, "pa")); - item->ft->wPort = atoi(JabberXmlGetAttrValue(dcng, "pp")); - JabberForkThread((void (__cdecl *)(void*))TlenNewFileReceiveThread, 0, item->ft); - } - } - - } else if (dc != NULL) { - - } - } -} diff --git a/!NotAdopted/Tlen/tlen_p2p_old.c b/!NotAdopted/Tlen/tlen_p2p_old.c deleted file mode 100644 index 0d5c121535..0000000000 --- a/!NotAdopted/Tlen/tlen_p2p_old.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include -#include -#include -#include -#include "jabber_list.h" -#include "tlen_p2p_old.h" - -void TlenP2PFreeFileTransfer(TLEN_FILE_TRANSFER *ft) -{ - int i; - if (ft->jid) mir_free(ft->jid); - if (ft->iqId) mir_free(ft->iqId); - if (ft->id2) mir_free(ft->id2); - if (ft->hostName) mir_free(ft->hostName); - if (ft->localName) mir_free(ft->localName); - if (ft->szSavePath) mir_free(ft->szSavePath); - if (ft->szDescription) mir_free(ft->szDescription); - if (ft->filesSize) mir_free(ft->filesSize); - if (ft->files) { - for (i=0; ifileCount; i++) { - if (ft->files[i]) mir_free(ft->files[i]); - } - mir_free(ft->files); - } - mir_free(ft); -} - -TLEN_FILE_PACKET *TlenP2PPacketCreate(int datalen) -{ - TLEN_FILE_PACKET *packet; - - if ((packet=(TLEN_FILE_PACKET *) mir_alloc(sizeof(TLEN_FILE_PACKET))) == NULL) - return NULL; - packet->packet = NULL; - if (datalen > 0) { - if ((packet->packet=(char *) mir_alloc(datalen)) == NULL) { - mir_free(packet); - return NULL; - } - } - packet->maxDataLen = datalen; - packet->type=0; - packet->len=0; - return packet; -} - -void TlenP2PPacketFree(TLEN_FILE_PACKET *packet) -{ - if (packet != NULL) { - if (packet->packet != NULL) - mir_free(packet->packet); - mir_free(packet); - } -} - -void TlenP2PPacketSetType(TLEN_FILE_PACKET *packet, DWORD type) -{ - if (packet!=NULL) { - packet->type = type; - } -} - -void TlenP2PPacketSetLen(TLEN_FILE_PACKET *packet, DWORD len) -{ - if (packet!=NULL) { - packet->len = len; - } -} - -void TlenP2PPacketPackDword(TLEN_FILE_PACKET *packet, DWORD data) -{ - if (packet!=NULL && packet->packet!=NULL) { - if (packet->len + sizeof(DWORD) <= packet->maxDataLen) { - (*((DWORD*)((packet->packet)+(packet->len)))) = data; - packet->len += sizeof(DWORD); - } - } -} - -void TlenP2PPacketPackBuffer(TLEN_FILE_PACKET *packet, char *buffer, int len) -{ - if (packet!=NULL && packet->packet!=NULL) { - if (packet->len + len <= packet->maxDataLen) { - memcpy((packet->packet)+(packet->len), buffer, len); - packet->len += len; - } - } -} - -void TlenP2PInit() { -} - -void TlenP2PUninit() { -} - -int TlenP2PPacketSend(JABBER_SOCKET s, TLEN_FILE_PACKET *packet) -{ - DWORD sendResult; - if (packet!=NULL && packet->packet!=NULL) { - Netlib_Send(s, (char *)&packet->type, 4, MSG_NODUMP); - Netlib_Send(s, (char *)&packet->len, 4, MSG_NODUMP); - sendResult=Netlib_Send(s, packet->packet, packet->len, MSG_NODUMP); - if (sendResult==SOCKET_ERROR || sendResult!=packet->len) return 0; - } - return 1; -} - -TLEN_FILE_PACKET* TlenP2PPacketReceive(JABBER_SOCKET s) -{ - TLEN_FILE_PACKET *packet; - DWORD recvResult; - DWORD type, len, pos; - recvResult = Netlib_Recv(s, (char *)&type, 4, MSG_NODUMP); - if (recvResult==0 || recvResult==SOCKET_ERROR) return NULL; - recvResult = Netlib_Recv(s, (char *)&len, 4, MSG_NODUMP); - if (recvResult==0 || recvResult==SOCKET_ERROR) return NULL; - packet = TlenP2PPacketCreate(len); - TlenP2PPacketSetType(packet, type); - TlenP2PPacketSetLen(packet, len); - pos = 0; - while (len > 0) { - recvResult = Netlib_Recv(s, packet->packet+pos, len, MSG_NODUMP); - if (recvResult==0 || recvResult==SOCKET_ERROR) { - TlenP2PPacketFree(packet); - return NULL; - } - len -= recvResult; - pos += recvResult; - } - return packet; -} - -void TlenP2PEstablishOutgoingConnection(TLEN_FILE_TRANSFER *ft, BOOL sendAck) -{ - char *hash; - char str[300]; - TLEN_FILE_PACKET *packet; - TlenProtocol *proto = ft->proto; - - JabberLog(proto, "Establishing outgoing connection."); - ft->state = FT_ERROR; - if ((packet = TlenP2PPacketCreate(2*sizeof(DWORD) + 20))!=NULL) { - TlenP2PPacketSetType(packet, TLEN_FILE_PACKET_CONNECTION_REQUEST); - TlenP2PPacketPackDword(packet, 1); - TlenP2PPacketPackDword(packet, (DWORD) atoi(ft->iqId)); - _snprintf(str, sizeof(str), "%08X%s%d", atoi(ft->iqId), proto->threadData->username, atoi(ft->iqId)); - hash = TlenSha1(str, (int)strlen(str)); - TlenP2PPacketPackBuffer(packet, hash, 20); - mir_free(hash); - TlenP2PPacketSend(ft->s, packet); - TlenP2PPacketFree(packet); - packet = TlenP2PPacketReceive(ft->s); - if (packet != NULL) { - if (packet->type == TLEN_FILE_PACKET_CONNECTION_REQUEST_ACK) { // acknowledge - if ((int)(*((DWORD*)packet->packet)) == atoi(ft->iqId)) { - ft->state = FT_CONNECTING; - if (sendAck) { - ProtoBroadcastAck(proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, ft, 0); - } - } - } - TlenP2PPacketFree(packet); - } - } -} - -TLEN_FILE_TRANSFER* TlenP2PEstablishIncomingConnection(TlenProtocol *proto, JABBER_SOCKET s, int list, BOOL sendAck) -{ - JABBER_LIST_ITEM *item = NULL; - TLEN_FILE_PACKET *packet; - int i; - char str[300]; - DWORD iqId; - // TYPE: 0x1 - // LEN: - // (DWORD) 0x1 - // (DWORD) id - // (BYTE) hash[20] - packet = TlenP2PPacketReceive(s); - if (packet == NULL || packet->type != TLEN_FILE_PACKET_CONNECTION_REQUEST || packet->len<28) { - if (packet!=NULL) { - TlenP2PPacketFree(packet); - } - return NULL; - } - iqId = *((DWORD *)(packet->packet+sizeof(DWORD))); - i = 0; - while ((i=JabberListFindNext(proto, list, i)) >= 0) { - if ((item=JabberListGetItemPtrFromIndex(proto, i))!=NULL) { - _snprintf(str, sizeof(str), "%d", iqId); - if (!strcmp(item->ft->iqId, str)) { - char *hash, *nick; - int j; - nick = JabberNickFromJID(item->ft->jid); - _snprintf(str, sizeof(str), "%08X%s%d", iqId, nick, iqId); - mir_free(nick); - hash = TlenSha1(str, (int)strlen(str)); - for (j=0;j<20;j++) { - if (hash[j]!=packet->packet[2*sizeof(DWORD)+j]) break; - } - mir_free(hash); - if (j==20) break; - } - } - i++; - } - TlenP2PPacketFree(packet); - if (i >=0) { - if ((packet=TlenP2PPacketCreate(sizeof(DWORD))) != NULL) { - // Send connection establishment acknowledgement - TlenP2PPacketSetType(packet, TLEN_FILE_PACKET_CONNECTION_REQUEST_ACK); - TlenP2PPacketPackDword(packet, (DWORD) atoi(item->ft->iqId)); - TlenP2PPacketSend(s, packet); - TlenP2PPacketFree(packet); - item->ft->state = FT_CONNECTING; - if (sendAck) { - ProtoBroadcastAck(item->ft->proto->iface.m_szModuleName, item->ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, item->ft, 0); - } - return item->ft; - } - } - return NULL; -} - -static void __cdecl TlenFileBindSocks4Thread(TLEN_FILE_TRANSFER* ft) -{ - BYTE buf[8]; - int status; - -// JabberLog("Waiting for the file to be sent via SOCKS..."); - status = Netlib_Recv(ft->s, (char*)buf, 8, MSG_NODUMP); -// JabberLog("accepted connection !!!"); - if ( status == SOCKET_ERROR || status<8 || buf[1]!=90) { - status = 1; - } else { - status = 0; - } - if (!status) { - ft->pfnNewConnectionV2(ft->s, 0, NULL); - } else { - if (ft->state!=FT_SWITCH) { - ft->state = FT_ERROR; - } - } - JabberLog(ft->proto, "Closing connection for this file transfer..."); -// Netlib_CloseHandle(ft->s); - if (ft->hFileEvent != NULL) - SetEvent(ft->hFileEvent); - -} -static void __cdecl TlenFileBindSocks5Thread(TLEN_FILE_TRANSFER* ft) -{ - BYTE buf[256]; - int status; - -// JabberLog("Waiting for the file to be sent via SOCKS..."); - status = Netlib_Recv(ft->s, (char*)buf, sizeof(buf), MSG_NODUMP); -// JabberLog("accepted connection !!!"); - if ( status == SOCKET_ERROR || status<7 || buf[1]!=0) { - status = 1; - } else { - status = 0; - } - if (!status) { - ft->pfnNewConnectionV2(ft->s, 0, NULL); - } else { - if (ft->state!=FT_SWITCH) { - ft->state = FT_ERROR; - } - } -// JabberLog("Closing connection for this file transfer..."); -// Netlib_CloseHandle(ft->s); - if (ft->hFileEvent != NULL) - SetEvent(ft->hFileEvent); - -} - -static JABBER_SOCKET TlenP2PBindSocks4(SOCKSBIND * sb, TLEN_FILE_TRANSFER *ft) -{ //rfc1928 - int len; - BYTE buf[256]; - int status; - struct in_addr in; - NETLIBOPENCONNECTION nloc; - JABBER_SOCKET s; - - nloc.cbSize = NETLIBOPENCONNECTION_V1_SIZE;//sizeof(NETLIBOPENCONNECTION); - nloc.szHost = sb->szHost; - nloc.wPort = sb->wPort; - nloc.flags = 0; - s = (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, (WPARAM) ft->proto->hFileNetlibUser, (LPARAM) &nloc); - if (s==NULL) { -// JabberLog("Connection failed (%d), thread ended", WSAGetLastError()); - return NULL; - } - buf[0] = 4; //socks4 - buf[1] = 2; //2-bind, 1-connect - *(PWORD)(buf+2) = htons(0); // port - *(PDWORD)(buf+4) = INADDR_ANY; - if (sb->useAuth) { - strcpy((char*)buf+8, sb->szUser); - len = (int)strlen(sb->szUser); - } else { - buf[8] = 0; - len = 0; - } - len += 9; - status = Netlib_Send(s, (char*)buf, len, MSG_NODUMP); - if (status==SOCKET_ERROR || statusszHost, inet_ntoa(in)); - sb->wPort = htons(*(PWORD)(buf+2)); - ft->s = s; - JabberForkThread((void (__cdecl *)(void*))TlenFileBindSocks4Thread, 0, ft); - return s; -} - -static JABBER_SOCKET TlenP2PBindSocks5(SOCKSBIND * sb, TLEN_FILE_TRANSFER *ft) -{ //rfc1928 - BYTE buf[512]; - int len, status; - NETLIBOPENCONNECTION nloc; - struct in_addr in; - JABBER_SOCKET s; - - nloc.cbSize = NETLIBOPENCONNECTION_V1_SIZE;//sizeof(NETLIBOPENCONNECTION); - nloc.szHost = sb->szHost; - nloc.wPort = sb->wPort; - nloc.flags = 0; - s = (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, (WPARAM) ft->proto->hFileNetlibUser, (LPARAM) &nloc); - if (s==NULL) { - JabberLog(ft->proto, "Connection failed (%d), thread ended", WSAGetLastError()); - return NULL; - } - buf[0] = 5; //yep, socks5 - buf[1] = 1; //one auth method - buf[2] = sb->useAuth?2:0; // authorization - status = Netlib_Send(s, (char*)buf, 3, MSG_NODUMP); - if (status==SOCKET_ERROR || status<3) { - JabberLog(ft->proto, "Send failed (%d), thread ended", WSAGetLastError()); - Netlib_CloseHandle(s); - return NULL; - } - status = Netlib_Recv(s, (char*)buf, 2, MSG_NODUMP); - if (status==SOCKET_ERROR || status<2 || (buf[1]!=0 && buf[1]!=2)) { - JabberLog(ft->proto, "SOCKS5 negotiation failed"); - Netlib_CloseHandle(s); - return NULL; - } - if(buf[1]==2) { //rfc1929 - int nUserLen, nPassLen; - PBYTE pAuthBuf; - - nUserLen = (int)strlen(sb->szUser); - nPassLen = (int)strlen(sb->szPassword); - pAuthBuf = (PBYTE)mir_alloc(3+nUserLen+nPassLen); - pAuthBuf[0] = 1; //auth version - pAuthBuf[1] = nUserLen; - memcpy(pAuthBuf+2, sb->szUser, nUserLen); - pAuthBuf[2+nUserLen]=nPassLen; - memcpy(pAuthBuf+3+nUserLen,sb->szPassword,nPassLen); - status = Netlib_Send(s, (char*)pAuthBuf, 3+nUserLen+nPassLen, MSG_NODUMP); - mir_free(pAuthBuf); - if (status==SOCKET_ERROR || status<3+nUserLen+nPassLen) { - JabberLog(ft->proto, "Send failed (%d), thread ended", WSAGetLastError()); - Netlib_CloseHandle(s); - return NULL; - } - status = Netlib_Recv(s, (char*)buf, sizeof(buf), MSG_NODUMP); - if (status==SOCKET_ERROR || status<2 || buf[1]!=0) { - JabberLog(ft->proto, "SOCKS5 sub-negotiation failed"); - Netlib_CloseHandle(s); - return NULL; - } - } - - { PBYTE pInit; - int nHostLen=4; - DWORD hostIP=INADDR_ANY; - pInit=(PBYTE)mir_alloc(6+nHostLen); - pInit[0]=5; //SOCKS5 - pInit[1]=2; //bind - pInit[2]=0; //reserved - pInit[3]=1; - *(PDWORD)(pInit+4)=hostIP; - *(PWORD)(pInit+4+nHostLen)=htons(0); - status = Netlib_Send(s, (char*)pInit, 6+nHostLen, MSG_NODUMP); - mir_free(pInit); - if (status==SOCKET_ERROR || status<6+nHostLen) { -// JabberLog("Send failed (%d), thread ended", WSAGetLastError()); - Netlib_CloseHandle(s); - return NULL; - } - } - status = Netlib_Recv(s, (char*)buf, sizeof(buf), MSG_NODUMP); - if ( status == SOCKET_ERROR || status<7 || buf[0]!=5 || buf[1]!=0) { -// JabberLog("SOCKS5 request failed"); - Netlib_CloseHandle(s); - return NULL; - } - if (buf[2]==1) { // domain - len = buf[4]; - memcpy(sb->szHost, buf+5, len); - sb->szHost[len]=0; - len += 4; - } else { // ip address - in.S_un.S_addr = *(PDWORD)(buf+4); - strcpy(sb->szHost, inet_ntoa(in)); - len = 8; - } - sb->wPort = htons(*(PWORD)(buf+len)); - ft->s = s; - - JabberForkThread((void (__cdecl *)(void*))TlenFileBindSocks5Thread, 0, ft); - return s; -} - - -JABBER_SOCKET TlenP2PListen(TLEN_FILE_TRANSFER *ft) -{ - NETLIBBIND nlb = {0}; - JABBER_SOCKET s = NULL; - int useProxy; - DBVARIANT dbv; - SOCKSBIND sb; - struct in_addr in; - TlenProtocol *proto = ft->proto; - useProxy=0; - if (ft->localName!= NULL) mir_free(ft->localName); - ft->localName = NULL; - ft->wPort = 0; - if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "UseFileProxy", FALSE)) { - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "FileProxyHost", &dbv)) { - strcpy(sb.szHost, dbv.pszVal); - DBFreeVariant(&dbv); - sb.wPort = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "FileProxyPort", 0); - sb.useAuth = FALSE; - strcpy(sb.szUser, ""); - strcpy(sb.szPassword, ""); - if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "FileProxyAuth", FALSE)) { - sb.useAuth = TRUE; - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "FileProxyUsername", &dbv)) { - strcpy(sb.szUser, dbv.pszVal); - DBFreeVariant(&dbv); - } - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "FileProxyPassword", &dbv)) { - CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); - strcpy(sb.szPassword, dbv.pszVal); - DBFreeVariant(&dbv); - } - } - switch (DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "FileProxyType", 0)) { - case 0: // forwarding - useProxy = 1; - break; - case 1: // socks4 - s = TlenP2PBindSocks4(&sb, ft); - useProxy = 2; - break; - case 2: // socks5 - s = TlenP2PBindSocks5(&sb, ft); - useProxy = 2; - break; - } - ft->localName = mir_strdup(sb.szHost); - ft->wPort = sb.wPort; - ft->wLocalPort = sb.wPort; - } - } - if (useProxy<2) { - nlb.cbSize = sizeof(NETLIBBIND); - nlb.pfnNewConnectionV2 = ft->pfnNewConnectionV2; - nlb.wPort = 0; // Use user-specified incoming port ranges, if available - nlb.pExtra = proto; - JabberLog(ft->proto, "Calling MS_NETLIB_BINDPORT"); - s = (HANDLE) CallService(MS_NETLIB_BINDPORT, (WPARAM) ft->proto->hNetlibUser, (LPARAM) &nlb); - JabberLog(ft->proto, "listening on %d",s); - } - if (useProxy==0) { - in.S_un.S_addr = htonl(nlb.dwExternalIP); - ft->localName = mir_strdup(inet_ntoa(in)); - ft->wPort = nlb.wPort; - ft->wLocalPort = nlb.wExPort; - } - if (s != NULL) { -// listenCount++; - } - return s; -} - -void TlenP2PStopListening(JABBER_SOCKET s) { - if (s != NULL) { -// listenCount--; -// if (listenCount <= 0) { -// Netlib_CloseHandle(s); -// } - } -} diff --git a/!NotAdopted/Tlen/tlen_p2p_old.h b/!NotAdopted/Tlen/tlen_p2p_old.h deleted file mode 100644 index d6405a378e..0000000000 --- a/!NotAdopted/Tlen/tlen_p2p_old.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" - -#ifndef _TLEN_P2P_OLD_H_ -#define _TLEN_P2P_OLD_H_ - -enum { - TLEN_FILE_PACKET_CONNECTION_REQUEST = 0x01, - TLEN_FILE_PACKET_CONNECTION_REQUEST_ACK = 0x02, - TLEN_FILE_PACKET_FILE_LIST = 0x32, - TLEN_FILE_PACKET_FILE_LIST_ACK = 0x33, - TLEN_FILE_PACKET_FILE_REQUEST = 0x34, - TLEN_FILE_PACKET_FILE_DATA = 0x35, - TLEN_FILE_PACKET_END_OF_FILE = 0x37, - TLEN_VOICE_PACKET = 0x96 -}; - -typedef struct { - unsigned int maxDataLen; - char *packet; - DWORD type; - DWORD len; -} TLEN_FILE_PACKET; - -typedef struct { - char szHost[256]; - int wPort; - int useAuth; - char szUser[256]; - char szPassword[256]; -}SOCKSBIND; - -extern void TlenP2PFreeFileTransfer(TLEN_FILE_TRANSFER *ft); -extern TLEN_FILE_PACKET *TlenP2PPacketCreate(int datalen); -extern void TlenP2PPacketFree(TLEN_FILE_PACKET *packet); -extern void TlenP2PPacketSetType(TLEN_FILE_PACKET *packet, DWORD type); -extern void TlenP2PPacketSetLen(TLEN_FILE_PACKET *packet, DWORD len); -extern void TlenP2PPacketPackDword(TLEN_FILE_PACKET *packet, DWORD data); -extern void TlenP2PPacketPackBuffer(TLEN_FILE_PACKET *packet, char *buffer, int len); -extern int TlenP2PPacketSend(JABBER_SOCKET s, TLEN_FILE_PACKET *packet); -extern TLEN_FILE_PACKET* TlenP2PPacketReceive(JABBER_SOCKET s); -extern void TlenP2PEstablishOutgoingConnection(TLEN_FILE_TRANSFER *ft, BOOL sendAck); -extern TLEN_FILE_TRANSFER* TlenP2PEstablishIncomingConnection(TlenProtocol *proto, JABBER_SOCKET s, int list, BOOL sendAck); -extern JABBER_SOCKET TlenP2PListen(TLEN_FILE_TRANSFER *ft); -extern void TlenP2PStopListening(JABBER_SOCKET s); -#endif diff --git a/!NotAdopted/Tlen/tlen_picture.c b/!NotAdopted/Tlen/tlen_picture.c deleted file mode 100644 index c8f8d6f3e2..0000000000 --- a/!NotAdopted/Tlen/tlen_picture.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2009 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include "jabber_list.h" -#include "tlen_file.h" -#include "tlen_p2p_old.h" - -typedef struct { - TlenProtocol *proto; - JABBER_LIST_ITEM *item; -} TLENPSREQUESTTHREADDATA; - -static void LogPictureMessage(TlenProtocol *proto, const char *jid, const char *filename, BOOL isSent) -{ - char message[1024]; - const char *msg = isSent ? "Image sent file://%s" : "Image received file://%s"; - _snprintf(message, sizeof(message), Translate(msg), filename); - TlenLogMessage(proto, JabberHContactFromJID(proto, jid), isSent ? DBEF_SENT : 0, message); -} - -static void TlenPsPostThread(void *ptr) { - TLENPSREQUESTTHREADDATA *data = (TLENPSREQUESTTHREADDATA *)ptr; - TlenProtocol *proto = data->proto; - JABBER_LIST_ITEM *item = data->item; - JABBER_SOCKET socket = JabberWsConnect(proto, "ps.tlen.pl", 443); - BOOL bSent = FALSE; - if (socket != NULL) { - char header[512]; - DWORD ret; - item->ft->s = socket; - item->ft->hFileEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - _snprintf(header, sizeof(header), "", proto->threadData->username, item->ft->jid, item->ft->fileTotalSize, item->jid); - JabberWsSend(proto, socket, header, (int)strlen(header)); - ret = WaitForSingleObject(item->ft->hFileEvent, 1000 * 60 * 5); - if (ret == WAIT_OBJECT_0) { - FILE *fp = fopen( item->ft->files[0], "rb" ); - if (fp) { - int i; - char header[512]; - char fileBuffer[2048]; - _snprintf(header, sizeof(header), "", item->ft->iqId, item->jid); - JabberWsSend(proto, socket, header, (int)strlen(header)); - JabberLog(proto, "Sending picture data..."); - for (i = item->ft->filesSize[0]; i > 0; ) { - int toread = min(2048, i); - int readcount = (int)fread(fileBuffer, (size_t)1, (size_t)toread, fp); - i -= readcount; - if (readcount > 0) { - JabberWsSend(proto, socket, fileBuffer, readcount); - } - if (toread != readcount) { - break; - } - } - fclose(fp); - SleepEx(3000, TRUE); - bSent = TRUE; - } else { - /* picture not found */ - } - } else { - /* 5 minutes passed */ - } - Netlib_CloseHandle(socket); - if (bSent) { - JabberSend(proto, "", item->ft->jid, item->jid, item->ft->id2); - LogPictureMessage(proto, item->ft->jid, item->ft->files[0], TRUE); - } - TlenP2PFreeFileTransfer(item->ft); - JabberListRemove(proto, LIST_PICTURE, item->jid); - } else { - /* cannot connect to ps server */ - } - mir_free(data); -} - -static void TlenPsPost(TlenProtocol *proto, JABBER_LIST_ITEM *item) { - TLENPSREQUESTTHREADDATA *threadData = (TLENPSREQUESTTHREADDATA *)mir_alloc(sizeof(TLENPSREQUESTTHREADDATA)); - threadData->proto = proto; - threadData->item = item; - JabberForkThread(TlenPsPostThread, 0, threadData); -} - -static void TlenPsGetThread(void *ptr) { - TLENPSREQUESTTHREADDATA *data = (TLENPSREQUESTTHREADDATA *)ptr; - TlenProtocol *proto = data->proto; - JABBER_LIST_ITEM *item = data->item; - FILE *fp; - fp = fopen( item->ft->files[0], "wb" ); - if (fp) { - JABBER_SOCKET socket = JabberWsConnect(proto, "ps.tlen.pl", 443); - if (socket != NULL) { - XmlState xmlState; - char header[512]; - char fileBuffer[2048]; - JabberXmlInitState(&xmlState); - _snprintf(header, sizeof(header), "", proto->threadData->username, item->ft->jid, item->jid, item->ft->id2); - JabberWsSend(proto, socket, header, (int)strlen(header)); - JabberLog(proto, "Reveiving picture data..."); - { - int totalcount = 0; - int size = item->ft->filesSize[0]; - BOOL bHeader = TRUE; - while (TRUE) { - int readcount = JabberWsRecv(proto, socket, fileBuffer, 2048 - totalcount); - if (readcount == 0) { - break; - } - totalcount += readcount; - if (bHeader) { - char * tagend = memchr(fileBuffer, '/', totalcount); - tagend = memchr(tagend + 1, '>', totalcount - (tagend - fileBuffer) - 1); - if (tagend != NULL) { - int parsed = JabberXmlParse(&xmlState, fileBuffer, tagend - fileBuffer + 1); - if (parsed == 0) { - continue; - } - bHeader = FALSE; - totalcount -= parsed; - memmove(fileBuffer, fileBuffer+parsed, totalcount); - } - } - if (!bHeader) { - if (totalcount > 0) { - fwrite(fileBuffer, 1, totalcount, fp); - size -= totalcount; - totalcount = 0; - } - if (size == 0) { - break; - } - } - } - } - Netlib_CloseHandle(socket); - JabberLog(proto, "Picture received..."); - LogPictureMessage(proto, item->ft->jid, item->ft->files[0], FALSE); - } else { - /* cannot connect to ps server */ - } - fclose(fp); - } else { - /* cannot create file */ - } - TlenP2PFreeFileTransfer(item->ft); - JabberListRemove(proto, LIST_PICTURE, item->jid); - mir_free(data); -} - -static void TlenPsGet(TlenProtocol *proto, JABBER_LIST_ITEM *item) { - TLENPSREQUESTTHREADDATA *threadData = (TLENPSREQUESTTHREADDATA *)mir_alloc(sizeof(TLENPSREQUESTTHREADDATA)); - threadData->proto = proto; - threadData->item = item; - JabberForkThread(TlenPsGetThread, 0, threadData); -} - -void TlenProcessPic(XmlNode *node, TlenProtocol *proto) { - JABBER_LIST_ITEM *item = NULL; - char *crc, *crc_c, *idt, *size, *from, *fromRaw, *rt; - from = JabberXmlGetAttrValue(node, "from"); - fromRaw = JabberLoginFromJID(from); - idt = JabberXmlGetAttrValue(node, "idt"); - size = JabberXmlGetAttrValue(node, "size"); - crc_c = JabberXmlGetAttrValue(node, "crc_c"); - crc = JabberXmlGetAttrValue(node, "crc"); - rt = JabberXmlGetAttrValue(node, "rt"); - if (idt != NULL) { - item = JabberListGetItemPtr(proto, LIST_PICTURE, idt); - } - if (item != NULL) { - if (!strcmp(from, "ps")) { - char *st = JabberXmlGetAttrValue(node, "st"); - if (st != NULL) { - item->ft->iqId = mir_strdup(st); - item->ft->id2 = mir_strdup(rt); - if (item->ft->hFileEvent != NULL) { - SetEvent(item->ft->hFileEvent); - item->ft->hFileEvent = NULL; - } - } - } else if (!strcmp(item->ft->jid, fromRaw)) { - if (crc_c != NULL) { - if (!strcmp(crc_c, "n")) { - /* crc_c = n, picture transfer accepted */ - TlenPsPost(proto, item); - } else if (!strcmp(crc_c, "f")) { - /* crc_c = f, picture cached, no need to transfer again */ - LogPictureMessage(proto, item->ft->jid, item->ft->files[0], TRUE); - TlenP2PFreeFileTransfer(item->ft); - JabberListRemove(proto, LIST_PICTURE, idt); - } - } else if (rt != NULL) { - item->ft->id2 = mir_strdup(rt); - TlenPsGet(proto, item); - } - } - } else if (crc != NULL) { - BOOL bAccept = proto->tlenOptions.imagePolicy == TLEN_IMAGES_ACCEPT_ALL || (proto->tlenOptions.imagePolicy == TLEN_IMAGES_IGNORE_NIR && IsAuthorized(proto, from)); - if (bAccept) { - FILE* fp; - char fileName[MAX_PATH]; - char *ext = JabberXmlGetAttrValue(node, "ext"); - char *tmpPath = Utils_ReplaceVars( "%miranda_userdata%" ); - int tPathLen = mir_snprintf( fileName, MAX_PATH, "%s\\Images\\Tlen", tmpPath ); - long oldSize = 0, lSize = atol(size); - DWORD dwAttributes = GetFileAttributesA( fileName ); - if ( dwAttributes == 0xffffffff || ( dwAttributes & FILE_ATTRIBUTE_DIRECTORY ) == 0 ) { - CallService( MS_UTILS_CREATEDIRTREE, 0, ( LPARAM )fileName ); - } - mir_free(tmpPath); - fileName[ tPathLen++ ] = '\\'; - mir_snprintf( fileName + tPathLen, MAX_PATH - tPathLen, "%s.%s", crc, ext ); - fp = fopen( fileName, "rb" ); - if (fp) { - fseek(fp, 0, SEEK_END); - oldSize = ftell(fp); - fclose(fp); - } - if (oldSize != lSize) { - item = JabberListAdd(proto, LIST_PICTURE, idt); - item->ft = TlenFileCreateFT(proto, from); - item->ft->files = (char **) mir_alloc(sizeof(char *)); - item->ft->filesSize = (long *) mir_alloc(sizeof(long)); - item->ft->files[0] = mir_strdup(fileName); - item->ft->filesSize[0] = lSize; - item->ft->fileTotalSize = item->ft->filesSize[0]; - JabberSend(proto, "", from, idt); - } else { - JabberSend(proto, "", from, idt); - LogPictureMessage(proto, from, fileName, FALSE); - } - } - } - mir_free(fromRaw); -} - -BOOL SendPicture(TlenProtocol *proto, HANDLE hContact) { - DBVARIANT dbv; - if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { - char *jid = dbv.pszVal; - char szFilter[512]; - char *szFileName = (char*) mir_alloc(_MAX_PATH); - OPENFILENAMEA ofn = {0}; - CallService( MS_UTILS_GETBITMAPFILTERSTRINGS, ( WPARAM ) sizeof( szFilter ), ( LPARAM )szFilter ); - ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; - ofn.hwndOwner = NULL; - ofn.lpstrFilter = szFilter; - ofn.lpstrCustomFilter = NULL; - ofn.lpstrFile = szFileName; - ofn.nMaxFile = _MAX_PATH; - ofn.Flags = OFN_FILEMUSTEXIST; - szFileName[0] = '\0'; - if ( GetOpenFileNameA( &ofn )) { - long size; - FILE* fp = fopen( szFileName, "rb" ); - if (fp) { - fseek(fp, 0, SEEK_END); - size = ftell(fp); - if (size > 0 && size < 256*1024) { - JABBER_LIST_ITEM *item; - mir_sha1_ctx sha; - DWORD digest[5]; - int i; - char idStr[10]; - char fileBuffer[2048]; - int id = JabberSerialNext(proto); - _snprintf(idStr, sizeof(idStr), "%d", id); - item = JabberListAdd(proto, LIST_PICTURE, idStr); - item->ft = TlenFileCreateFT(proto, jid); - item->ft->files = (char **) mir_alloc(sizeof(char *)); - item->ft->filesSize = (long *) mir_alloc(sizeof(long)); - item->ft->files[0] = szFileName; - item->ft->filesSize[0] = size; - item->ft->fileTotalSize = size; - fseek(fp, 0, SEEK_SET); - mir_sha1_init( &sha ); - for (i = item->ft->filesSize[0]; i > 0; ) { - int toread = min(2048, i); - int readcount = (int)fread(fileBuffer, (size_t)1, (size_t)toread, fp); - i -= readcount; - if (readcount > 0) { - mir_sha1_append( &sha, (mir_sha1_byte_t* )fileBuffer, readcount); - } - if (toread != readcount) { - break; - } - } - mir_sha1_finish( &sha, (mir_sha1_byte_t* )digest ); - JabberSend(proto, "", jid, - (int)htonl(digest[0]), (int)htonl(digest[1]), (int)htonl(digest[2]), (int)htonl(digest[3]), (int)htonl(digest[4]), idStr, item->ft->filesSize[0], "jpg"); - } else { - /* file too big */ - } - fclose(fp); - } - } - DBFreeVariant(&dbv); - } - return FALSE; -} diff --git a/!NotAdopted/Tlen/tlen_picture.h b/!NotAdopted/Tlen/tlen_picture.h deleted file mode 100644 index e4836444ee..0000000000 --- a/!NotAdopted/Tlen/tlen_picture.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2009 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#ifndef _TLEN_PICTURE_H -#define _TLEN_PICTURE_H - -#include -#include "jabber.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern void TlenProcessPic(XmlNode *node, TlenProtocol *proto); -extern BOOL SendPicture(TlenProtocol *, HANDLE hContact); - -#ifdef __cplusplus -} -#endif - -#endif /* _TLEN_PICTURE_H */ - diff --git a/!NotAdopted/Tlen/tlen_presence.c b/!NotAdopted/Tlen/tlen_presence.c deleted file mode 100644 index ca1f14e23c..0000000000 --- a/!NotAdopted/Tlen/tlen_presence.c +++ /dev/null @@ -1,314 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2009 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include "jabber_list.h" -#include "tlen_avatar.h" - -void TlenProcessPresence(XmlNode *node, TlenProtocol *proto) -{ - HANDLE hContact; - XmlNode *showNode, *statusNode; - JABBER_LIST_ITEM *item; - char *from, *type, *nick, *show; - int status, laststatus = ID_STATUS_OFFLINE; - char *p; - - if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { - if (JabberListExist(proto, LIST_CHATROOM, from)); //JabberGroupchatProcessPresence(node, userdata); - - else { - type = JabberXmlGetAttrValue(node, "type"); - item = JabberListGetItemPtr(proto, LIST_ROSTER, from); - if (item != NULL) { - if (proto->tlenOptions.enableAvatars) { - TlenProcessPresenceAvatar(proto, node, item); - } - } - if (type==NULL || (!strcmp(type, "available"))) { - if ((nick=JabberLocalNickFromJID(from)) != NULL) { - if ((hContact=JabberHContactFromJID(proto, from)) == NULL) - hContact = JabberDBCreateContact(proto, from, nick, FALSE); - if (!JabberListExist(proto, LIST_ROSTER, from)) { - JabberLog(proto, "Receive presence online from %s (who is not in my roster)", from); - JabberListAdd(proto, LIST_ROSTER, from); - } - status = ID_STATUS_ONLINE; - if ((showNode=JabberXmlGetChild(node, "show")) != NULL) { - if ((show=showNode->text) != NULL) { - if (!strcmp(show, "away")) status = ID_STATUS_AWAY; - else if (!strcmp(show, "xa")) status = ID_STATUS_NA; - else if (!strcmp(show, "dnd")) status = ID_STATUS_DND; - else if (!strcmp(show, "chat")) status = ID_STATUS_FREECHAT; - else if (!strcmp(show, "unavailable")) { - // Always show invisible (on old Tlen client) as invisible (not offline) - status = ID_STATUS_OFFLINE; - } - } - } - - statusNode = JabberXmlGetChild(node, "status"); - if (statusNode) - p = JabberTextDecode(statusNode->text); - else - p = NULL; - JabberListAddResource(proto, LIST_ROSTER, from, status, statusNode?p:NULL); - if (p) { - DBWriteContactSettingString(hContact, "CList", "StatusMsg", p); - mir_free(p); - } else { - DBDeleteContactSetting(hContact, "CList", "StatusMsg"); - } - // Determine status to show for the contact and request version information - if (item != NULL) { - laststatus = item->status; - item->status = status; - } - if (strchr(from, '@')!=NULL || DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "ShowTransport", TRUE)==TRUE) { - if (DBGetContactSettingWord(hContact, proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE) != status) - DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "Status", (WORD) status); - } - if (item != NULL) { - if (!item->infoRequested) { - int iqId = JabberSerialNext(proto); - item->infoRequested = TRUE; - JabberSend( proto, "", iqId, from); - } - if (proto->tlenOptions.enableVersion && !item->versionRequested) { - item->versionRequested = TRUE; - if (proto->iface.m_iStatus != ID_STATUS_INVISIBLE) { - JabberSend( proto, "", from ); - } - } - } - JabberLog(proto, "%s (%s) online, set contact status to %d", nick, from, status); - mir_free(nick); - } - } - else if (!strcmp(type, "unavailable")) { - if (!JabberListExist(proto, LIST_ROSTER, from)) { - JabberLog(proto, "Receive presence offline from %s (who is not in my roster)", from); - JabberListAdd(proto, LIST_ROSTER, from); - } - else { - JabberListRemoveResource(proto, LIST_ROSTER, from); - } - status = ID_STATUS_OFFLINE; - statusNode = JabberXmlGetChild(node, "status"); - if (statusNode) { - if (proto->tlenOptions.offlineAsInvisible) { - status = ID_STATUS_INVISIBLE; - } - p = JabberTextDecode(statusNode->text); - JabberListAddResource(proto, LIST_ROSTER, from, status, p); - if ((hContact=JabberHContactFromJID(proto, from)) != NULL) { - if (p) { - DBWriteContactSettingString(hContact, "CList", "StatusMsg", p); - } else { - DBDeleteContactSetting(hContact, "CList", "StatusMsg"); - } - } - if (p) mir_free(p); - } - if ((item=JabberListGetItemPtr(proto, LIST_ROSTER, from)) != NULL) { - // Determine status to show for the contact based on the remaining resources - item->status = status; - item->versionRequested = FALSE; - item->infoRequested = FALSE; - } - if ((hContact=JabberHContactFromJID(proto, from)) != NULL) { - if (strchr(from, '@')!=NULL || DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "ShowTransport", TRUE)==TRUE) { - if (DBGetContactSettingWord(hContact, proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE) != status) - DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "Status", (WORD) status); - } - if (item != NULL && item->isTyping) { - item->isTyping = FALSE; - CallService(MS_PROTO_CONTACTISTYPING, (WPARAM) hContact, PROTOTYPE_CONTACTTYPING_OFF); - } - JabberLog(proto, "%s offline, set contact status to %d", from, status); - } - } - else if (!strcmp(type, "subscribe")) { - if (strchr(from, '@') == NULL) { - // automatically send authorization allowed to agent/transport - JabberSend(proto, "", from); - } - else if ((nick=JabberNickFromJID(from)) != NULL) { - JabberLog(proto, "%s (%s) requests authorization", nick, from); - JabberDBAddAuthRequest(proto, from, nick); - mir_free(nick); - } - } - else if (!strcmp(type, "subscribed")) { - if ((item=JabberListGetItemPtr(proto, LIST_ROSTER, from)) != NULL) { - if (item->subscription == SUB_FROM) item->subscription = SUB_BOTH; - else if (item->subscription == SUB_NONE) { - item->subscription = SUB_TO; - } - } - } - } - } -} - -static void JabberSendPresenceTo(TlenProtocol *proto, int status, char *to) -{ - char *showBody, *statusMsg, *presenceType; - char *ptr = NULL; - - if (!proto->isOnline) return; - - // Send update for status (we won't handle ID_STATUS_OFFLINE here) - // Note: jabberModeMsg is already encoded using JabberTextEncode() - EnterCriticalSection(&proto->modeMsgMutex); - - showBody = NULL; - statusMsg = NULL; - presenceType = NULL; - switch (status) { - case ID_STATUS_ONLINE: - showBody = "available"; - statusMsg = proto->modeMsgs.szOnline; - break; - case ID_STATUS_AWAY: - case ID_STATUS_ONTHEPHONE: - case ID_STATUS_OUTTOLUNCH: - showBody = "away"; - statusMsg = proto->modeMsgs.szAway; - break; - case ID_STATUS_NA: - showBody = "xa"; - statusMsg = proto->modeMsgs.szNa; - break; - case ID_STATUS_DND: - case ID_STATUS_OCCUPIED: - showBody = "dnd"; - statusMsg = proto->modeMsgs.szDnd; - break; - case ID_STATUS_FREECHAT: - showBody = "chat"; - statusMsg = proto->modeMsgs.szFreechat; - break; - case ID_STATUS_INVISIBLE: - presenceType = "invisible"; - statusMsg = proto->modeMsgs.szInvisible; - break; - case ID_STATUS_OFFLINE: - presenceType = "unavailable"; - if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "LeaveOfflineMessage", FALSE)) { - int offlineMessageOption = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "OfflineMessageOption", 0); - if (offlineMessageOption == 0) { - switch (proto->iface.m_iStatus) { - case ID_STATUS_ONLINE: - ptr = mir_strdup(proto->modeMsgs.szOnline); - break; - case ID_STATUS_AWAY: - case ID_STATUS_ONTHEPHONE: - case ID_STATUS_OUTTOLUNCH: - ptr = mir_strdup(proto->modeMsgs.szAway); - break; - case ID_STATUS_NA: - ptr = mir_strdup(proto->modeMsgs.szNa); - break; - case ID_STATUS_DND: - case ID_STATUS_OCCUPIED: - ptr = mir_strdup(proto->modeMsgs.szDnd); - break; - case ID_STATUS_FREECHAT: - ptr = mir_strdup(proto->modeMsgs.szFreechat); - break; - case ID_STATUS_INVISIBLE: - ptr = mir_strdup(proto->modeMsgs.szInvisible); - break; - } - } else if (offlineMessageOption == 99) { - - } else if (offlineMessageOption < 7) { - DBVARIANT dbv; - const char *statusNames[] = {"OnDefault", "AwayDefault", "NaDefault", "DndDefault", "FreeChatDefault", "InvDefault"}; - if (!DBGetContactSetting(NULL, "SRAway", statusNames[offlineMessageOption-1], &dbv)) { - int i; - char substituteStr[128]; - ptr = mir_strdup(dbv.pszVal); - DBFreeVariant(&dbv); - for(i=0;ptr[i];i++) { - if(ptr[i]!='%') continue; - if(!_strnicmp(ptr+i,"%time%",6)) - GetTimeFormatA(LOCALE_USER_DEFAULT,TIME_NOSECONDS,NULL,NULL,substituteStr,sizeof(substituteStr)); - else if(!_strnicmp(ptr+i,"%date%",6)) - GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,NULL,NULL,substituteStr,sizeof(substituteStr)); - else continue; - if(strlen(substituteStr)>6) ptr=(char*)mir_realloc(ptr,strlen(ptr)+1+strlen(substituteStr)-6); - MoveMemory(ptr+i+strlen(substituteStr),ptr+i+6,strlen(ptr)-i-5); - CopyMemory(ptr+i,substituteStr,strlen(substituteStr)); - } - } - } - } - statusMsg = ptr; - break; - default: - // Should not reach here - break; - } - proto->iface.m_iStatus = status; - if (presenceType) { - if (statusMsg) - JabberSend(proto, "%s", presenceType, statusMsg); - else - JabberSend(proto, "", presenceType); - } else { - if (statusMsg) - JabberSend(proto, "%s%s", showBody, statusMsg); - else - JabberSend(proto, "%s", showBody); - } - if (ptr) { - mir_free(ptr); - } - LeaveCriticalSection(&proto->modeMsgMutex); -} - -void JabberSendPresence(TlenProtocol *proto, int statusIn) -{ - int statusOut; - switch (statusIn) { - case ID_STATUS_ONLINE: - case ID_STATUS_OFFLINE: - case ID_STATUS_NA: - case ID_STATUS_FREECHAT: - case ID_STATUS_INVISIBLE: - statusOut = statusIn; - break; - case ID_STATUS_AWAY: - case ID_STATUS_ONTHEPHONE: - case ID_STATUS_OUTTOLUNCH: - default: - statusOut = ID_STATUS_AWAY; - break; - case ID_STATUS_DND: - case ID_STATUS_OCCUPIED: - statusOut = ID_STATUS_DND; - break; - } - JabberSendPresenceTo(proto, statusOut, NULL); -} diff --git a/!NotAdopted/Tlen/tlen_presence.h b/!NotAdopted/Tlen/tlen_presence.h deleted file mode 100644 index fdc3ea642e..0000000000 --- a/!NotAdopted/Tlen/tlen_presence.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2009 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#ifndef _TLEN_PRESENCE_H -#define _TLEN_PRESENCE_H - -#ifdef __cplusplus -extern "C" { -#endif - -void TlenProcessPresence(XmlNode *node, TlenProtocol *proto); - -#ifdef __cplusplus -} -#endif - -#endif /* _TLEN_PRESENCE_H */ - diff --git a/!NotAdopted/Tlen/tlen_userinfo.c b/!NotAdopted/Tlen/tlen_userinfo.c deleted file mode 100644 index 50345282a9..0000000000 --- a/!NotAdopted/Tlen/tlen_userinfo.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - -Jabber Protocol Plugin for Miranda IM -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2002-2004 Santithorn Bunchua -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include -#include -#include -#include -#include -#include "jabber_list.h" -#include "resource.h" -#include "tlen_avatar.h" - -JABBER_FIELD_MAP tlenFieldGender[] = { - { 1, _T("Male") }, - { 2, _T("Female") }, - { 0, NULL } -}; -JABBER_FIELD_MAP tlenFieldLookfor[] = { - { 1, _T("Somebody to talk") }, - { 2, _T("Friendship") }, - { 3, _T("Flirt/romance") }, - { 4, _T("Love") }, - { 5, _T("Nothing") }, - { 0, NULL } -}; -JABBER_FIELD_MAP tlenFieldStatus[] = { - { 1, _T("All") }, - { 2, _T("Available") }, - { 3, _T("Free for chat") }, - { 0, NULL } -}; -JABBER_FIELD_MAP tlenFieldOccupation[] = { - { 1, _T("Student") }, - { 2, _T("College student") }, - { 3, _T("Farmer") }, - { 4, _T("Manager") }, - { 5, _T("Specialist") }, - { 6, _T("Clerk") }, - { 7, _T("Unemployed") }, - { 8, _T("Pensioner") }, - { 9, _T("Housekeeper") }, - { 10, _T("Teacher") }, - { 11, _T("Doctor") }, - { 12, _T("Other") }, - { 0, NULL } -}; -JABBER_FIELD_MAP tlenFieldPlan[] = { - { 1, _T("I'd like to go downtown") }, - { 2, _T("I'd like to go to the cinema") }, - { 3, _T("I'd like to take a walk") }, - { 4, _T("I'd like to go to the disco") }, - { 5, _T("I'd like to go on a blind date") }, - { 6, _T("Waiting for suggestion") }, - { 0, NULL } -}; - -static INT_PTR CALLBACK TlenUserInfoDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -static void InitComboBox(HWND hwndCombo, JABBER_FIELD_MAP *fieldMap) -{ - int i, n; - - n = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)_T("")); - SendMessage(hwndCombo, CB_SETITEMDATA, n, 0); - SendMessage(hwndCombo, CB_SETCURSEL, n, 0); - for(i=0;;i++) { - if (fieldMap[i].name == NULL) - break; - n = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) TranslateTS(fieldMap[i].name)); - SendMessage(hwndCombo, CB_SETITEMDATA, n, fieldMap[i].id); - } -} - -static void FetchField(HWND hwndDlg, UINT idCtrl, char *fieldName, char **str, int *strSize) -{ - char text[512]; - char *localFieldName, *localText; - - if (hwndDlg==NULL || fieldName==NULL || str==NULL || strSize==NULL) - return; - GetDlgItemTextA(hwndDlg, idCtrl, text, sizeof(text)); - if (text[0]) { - if ((localFieldName=JabberTextEncode(fieldName)) != NULL) { - if ((localText=JabberTextEncode(text)) != NULL) { - JabberStringAppend(str, strSize, "<%s>%s", localFieldName, localText, localFieldName); - mir_free(localText); - } - mir_free(localFieldName); - } - } -} - -static void FetchCombo(HWND hwndDlg, UINT idCtrl, char *fieldName, char **str, int *strSize) -{ - int value; - char *localFieldName; - - if (hwndDlg==NULL || fieldName==NULL || str==NULL || strSize==NULL) - return; - value = (int) SendDlgItemMessage(hwndDlg, idCtrl, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, idCtrl, CB_GETCURSEL, 0, 0), 0); - if (value > 0) { - if ((localFieldName=JabberTextEncode(fieldName)) != NULL) { - JabberStringAppend(str, strSize, "<%s>%d", localFieldName, value, localFieldName); - mir_free(localFieldName); - } - } -} - - -int TlenUserInfoInit(void *ptr, WPARAM wParam, LPARAM lParam) -{ - char *szProto; - HANDLE hContact; - OPTIONSDIALOGPAGE odp = {0}; - TlenProtocol *proto = (TlenProtocol *)ptr; - - if (!CallService(MS_PROTO_ISPROTOCOLLOADED, 0, (LPARAM) proto->iface.m_szModuleName)) - return 0; - hContact = (HANDLE) lParam; - szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); - if ((szProto!=NULL && !strcmp(szProto, proto->iface.m_szModuleName)) || !lParam) { - odp.cbSize = sizeof(odp); - odp.hInstance = hInst; - odp.flags = ODPF_TCHAR; - odp.pfnDlgProc = TlenUserInfoDlgProc; - odp.position = -2000000000; - odp.pszTemplate = ((HANDLE)lParam!=NULL) ? MAKEINTRESOURCEA(IDD_USER_INFO):MAKEINTRESOURCEA(IDD_USER_VCARD); - odp.ptszTitle = (hContact != NULL) ? TranslateT("Account") : proto->iface.m_tszUserName; - odp.dwInitParam = (LPARAM)proto; - CallService(MS_USERINFO_ADDPAGE, wParam, (LPARAM) &odp); - - } - if (!lParam && proto->isOnline) { - CCSDATA ccs = {0}; - JabberGetInfo(ptr, 0, (LPARAM) &ccs); - } - return 0; -} - -typedef struct { - TlenProtocol *proto; - HANDLE hContact; -}TLENUSERINFODLGDATA; - - -static INT_PTR CALLBACK TlenUserInfoDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - TLENUSERINFODLGDATA *data = (TLENUSERINFODLGDATA *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - - data = (TLENUSERINFODLGDATA*)mir_alloc(sizeof(TLENUSERINFODLGDATA)); - data->hContact = (HANDLE) lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)data); - // lParam is hContact - TranslateDialogDefault(hwndDlg); - InitComboBox(GetDlgItem(hwndDlg, IDC_GENDER), tlenFieldGender); - InitComboBox(GetDlgItem(hwndDlg, IDC_OCCUPATION), tlenFieldOccupation); - InitComboBox(GetDlgItem(hwndDlg, IDC_LOOKFOR), tlenFieldLookfor); - - return TRUE; - case WM_TLEN_REFRESH: - { - DBVARIANT dbv; - char *jid; - int i; - JABBER_LIST_ITEM *item; - - SetDlgItemText(hwndDlg, IDC_INFO_JID, _T("")); - SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, _T("")); - SetFocus(GetDlgItem(hwndDlg, IDC_STATIC)); - - if (!DBGetContactSettingTString(data->hContact, data->proto->iface.m_szModuleName, "FirstName", &dbv)) { - SetDlgItemText(hwndDlg, IDC_FIRSTNAME, dbv.ptszVal); - DBFreeVariant(&dbv); - } else SetDlgItemText(hwndDlg, IDC_FIRSTNAME, _T("")); - if (!DBGetContactSettingTString(data->hContact, data->proto->iface.m_szModuleName, "LastName", &dbv)) { - SetDlgItemText(hwndDlg, IDC_LASTNAME, dbv.ptszVal); - DBFreeVariant(&dbv); - } else SetDlgItemText(hwndDlg, IDC_LASTNAME, _T("")); - if (!DBGetContactSettingTString(data->hContact, data->proto->iface.m_szModuleName, "Nick", &dbv)) { - SetDlgItemText(hwndDlg, IDC_NICKNAME, dbv.ptszVal); - DBFreeVariant(&dbv); - } else SetDlgItemText(hwndDlg, IDC_NICKNAME, _T("")); - if (!DBGetContactSettingTString(data->hContact, data->proto->iface.m_szModuleName, "e-mail", &dbv)) { - SetDlgItemText(hwndDlg, IDC_EMAIL, dbv.ptszVal); - DBFreeVariant(&dbv); - } else SetDlgItemText(hwndDlg, IDC_EMAIL, _T("")); - if (!DBGetContactSetting(data->hContact, data->proto->iface.m_szModuleName, "Age", &dbv)) { - SetDlgItemInt(hwndDlg, IDC_AGE, dbv.wVal, FALSE); - DBFreeVariant(&dbv); - } else SetDlgItemText(hwndDlg, IDC_AGE, _T("")); - if (!DBGetContactSettingTString(data->hContact, data->proto->iface.m_szModuleName, "City", &dbv)) { - SetDlgItemText(hwndDlg, IDC_CITY, dbv.ptszVal); - DBFreeVariant(&dbv); - } else SetDlgItemText(hwndDlg, IDC_CITY, _T("")); - if (!DBGetContactSettingTString(data->hContact, data->proto->iface.m_szModuleName, "School", &dbv)) { - SetDlgItemText(hwndDlg, IDC_SCHOOL, dbv.ptszVal); - DBFreeVariant(&dbv); - } else SetDlgItemText(hwndDlg, IDC_SCHOOL, _T("")); - switch (DBGetContactSettingByte(data->hContact, data->proto->iface.m_szModuleName, "Gender", '?')) { - case 'M': - SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 1, 0); - SetDlgItemText(hwndDlg, IDC_GENDER_TEXT, TranslateTS(tlenFieldGender[0].name)); - break; - case 'F': - SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 2, 0); - SetDlgItemText(hwndDlg, IDC_GENDER_TEXT, TranslateTS(tlenFieldGender[1].name)); - break; - default: - SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 0, 0); - SetDlgItemText(hwndDlg, IDC_GENDER_TEXT, _T("")); - break; - } - i = DBGetContactSettingWord(data->hContact, data->proto->iface.m_szModuleName, "Occupation", 0); - if (i>0 && i<13) { - SetDlgItemText(hwndDlg, IDC_OCCUPATION_TEXT, TranslateTS(tlenFieldOccupation[i-1].name)); - SendDlgItemMessage(hwndDlg, IDC_OCCUPATION, CB_SETCURSEL, i, 0); - } else { - SetDlgItemText(hwndDlg, IDC_OCCUPATION_TEXT, _T("")); - SendDlgItemMessage(hwndDlg, IDC_OCCUPATION, CB_SETCURSEL, 0, 0); - } - i = DBGetContactSettingWord(data->hContact, data->proto->iface.m_szModuleName, "LookingFor", 0); - if (i>0 && i<6) { - SetDlgItemText(hwndDlg, IDC_LOOKFOR_TEXT, TranslateTS(tlenFieldLookfor[i-1].name)); - SendDlgItemMessage(hwndDlg, IDC_LOOKFOR, CB_SETCURSEL, i, 0); - } else { - SetDlgItemText(hwndDlg, IDC_LOOKFOR_TEXT, _T("")); - SendDlgItemMessage(hwndDlg, IDC_LOOKFOR, CB_SETCURSEL, 0, 0); - } - i = DBGetContactSettingWord(data->hContact, data->proto->iface.m_szModuleName, "VoiceChat", 0); - CheckDlgButton(hwndDlg, IDC_VOICECONVERSATIONS, i); - i = DBGetContactSettingWord(data->hContact, data->proto->iface.m_szModuleName, "PublicStatus", 0); - CheckDlgButton(hwndDlg, IDC_PUBLICSTATUS, i); - if (!DBGetContactSetting(data->hContact, data->proto->iface.m_szModuleName, "jid", &dbv)) { - jid = JabberTextDecode(dbv.pszVal); - SetDlgItemTextA(hwndDlg, IDC_INFO_JID, jid); - mir_free(jid); - jid = dbv.pszVal; - if (data->proto->isOnline) { - if ((item=JabberListGetItemPtr(data->proto, LIST_ROSTER, jid)) != NULL) { - switch (item->subscription) { - case SUB_BOTH: - SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, TranslateT("both")); - break; - case SUB_TO: - SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, TranslateT("to")); - break; - case SUB_FROM: - SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, TranslateT("from")); - break; - default: - SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, TranslateT("none")); - break; - } - SetDlgItemTextA(hwndDlg, IDC_SOFTWARE, item->software); - SetDlgItemTextA(hwndDlg, IDC_VERSION, item->version); - SetDlgItemTextA(hwndDlg, IDC_SYSTEM, item->system); - } else { - SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, TranslateT("not on roster")); - } - } - DBFreeVariant(&dbv); - } - } - break; - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->idFrom) { - case 0: - switch (((LPNMHDR)lParam)->code) { - case PSN_INFOCHANGED: - { - HANDLE hContact = (HANDLE) ((LPPSHNOTIFY) lParam)->lParam; - SendMessage(hwndDlg, WM_TLEN_REFRESH, 0, (LPARAM) hContact); - } - break; - case PSN_PARAMCHANGED: - { - data->proto = ( TlenProtocol* )(( LPPSHNOTIFY )lParam )->lParam; - SendMessage(hwndDlg, WM_TLEN_REFRESH, 0, 0); - } - } - break; - } - break; - case WM_COMMAND: - if (LOWORD(wParam)==IDC_SAVE && HIWORD(wParam)==BN_CLICKED) { - char *str = NULL; - int strSize; - JabberStringAppend(&str, &strSize, "", JabberSerialNext(data->proto)); - FetchField(hwndDlg, IDC_FIRSTNAME, "first", &str, &strSize); - FetchField(hwndDlg, IDC_LASTNAME, "last", &str, &strSize); - FetchField(hwndDlg, IDC_NICKNAME, "nick", &str, &strSize); - FetchField(hwndDlg, IDC_EMAIL, "email", &str, &strSize); - FetchCombo(hwndDlg, IDC_GENDER, "s", &str, &strSize); - FetchField(hwndDlg, IDC_AGE, "b", &str, &strSize); - FetchField(hwndDlg, IDC_CITY, "c", &str, &strSize); - FetchCombo(hwndDlg, IDC_OCCUPATION, "j", &str, &strSize); - FetchField(hwndDlg, IDC_SCHOOL, "e", &str, &strSize); - FetchCombo(hwndDlg, IDC_LOOKFOR, "r", &str, &strSize); - JabberStringAppend(&str, &strSize, "%d", IsDlgButtonChecked(hwndDlg, IDC_VOICECONVERSATIONS) ? 1 : 0); - JabberStringAppend(&str, &strSize, "%d", IsDlgButtonChecked(hwndDlg, IDC_PUBLICSTATUS) ? 1 : 0); - JabberStringAppend(&str, &strSize, ""); - JabberSend(data->proto, "%s", str); - mir_free(str); - JabberGetInfo((PROTO_INTERFACE *)data->proto, NULL, 0); - } - break; - case WM_DESTROY: - mir_free(data); - break; - } - return FALSE; -} diff --git a/!NotAdopted/Tlen/tlen_voice.c b/!NotAdopted/Tlen/tlen_voice.c deleted file mode 100644 index 4c4868152c..0000000000 --- a/!NotAdopted/Tlen/tlen_voice.c +++ /dev/null @@ -1,1122 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "jabber.h" -#include -#include -#include -#include -#include -#include -//#include -#include "resource.h" -#include "jabber_list.h" -#include "tlen_voice.h" -#include "tlen_p2p_old.h" -#include "tlen_file.h" - -static int MODE_FREQUENCY[]= {0, 0, 8000, 11025, 22050, 44100}; -static int MODE_FRAME_SIZE[]= {0, 0, 5, 5, 10, 25}; -static int FRAMES_AVAILABLE_MAX_LIMIT = 2; -static int VU_METER_HEIGHT = 64; -static int VU_METER_WIDTH = 20; -static int VU_METER_LEVELS = 16; -static HBITMAP vuMeterBitmaps[100]; - -static void TlenVoiceReceiveParse(TLEN_FILE_TRANSFER *ft); -static void TlenVoiceSendParse(TLEN_FILE_TRANSFER *ft); -static void TlenVoiceReceivingConnection(HANDLE hNewConnection, DWORD dwRemoteIP, void * pExtra); - -static void CALLBACK TlenVoicePlaybackCallback(HWAVEOUT hwo, UINT uMsg, DWORD* dwInstance, DWORD dwParam1, DWORD dwParam2) -{ - if (uMsg == WOM_DONE) { - TLEN_VOICE_CONTROL *control = (TLEN_VOICE_CONTROL *) dwInstance; - waveOutUnprepareHeader(hwo, (WAVEHDR *) dwParam1, sizeof(WAVEHDR)); - if (control->proto->framesAvailableForPlayback > 0) { - control->proto->framesAvailableForPlayback--; - } -// playbackControl->waveHeaders[playbackControl->waveHeadersPos].dwFlags = WHDR_DONE; -// playbackControl->waveHeaders[playbackControl->waveHeadersPos].lpData = (char *) (playbackControl->waveData + playbackControl->waveHeadersPos * playbackControl->waveFrameSize); -// playbackControl->waveHeaders[playbackControl->waveHeadersPos].dwBufferLength = playbackControl->waveFrameSize * 2; -// waveOutPrepareHeader(playbackControl->hWaveOut, &playbackControl->waveHeaders[playbackControl->waveHeadersPos], sizeof(WAVEHDR)); -// waveOutWrite(playbackControl->hWaveOut, &playbackControl->waveHeaders[playbackControl->waveHeadersPos], sizeof(WAVEHDR)); - - } -} - -static DWORD WINAPI TlenVoiceRecordingThreadProc(TLEN_VOICE_CONTROL *control) -{ - MSG msg; - HWAVEIN hWaveIn; - WAVEHDR *hWaveHdr; - control->isRunning = 1; - control->stopThread = 0; - while (TRUE) { - GetMessage(&msg,NULL,0,0); - if (msg.message == MM_WIM_DATA) { -// JabberLog("recording thread running...%d", msg.message); - hWaveIn = (HWAVEIN) msg.wParam; - hWaveHdr = (WAVEHDR *) msg.lParam; - waveInUnprepareHeader(hWaveIn, hWaveHdr, sizeof(WAVEHDR)); - if (hWaveHdr->dwBytesRecorded>0 && !control->bDisable) { - control->recordingData = (short *)hWaveHdr->lpData; - TlenVoiceSendParse(control->ft); - } - if (!control->stopThread) { - waveInPrepareHeader(hWaveIn, &control->waveHeaders[control->waveHeadersPos], sizeof(WAVEHDR)); - waveInAddBuffer(hWaveIn, &control->waveHeaders[control->waveHeadersPos], sizeof(WAVEHDR)); - control->waveHeadersPos = (control->waveHeadersPos +1) % control->waveHeadersNum; - } - } - else if (msg.message == MM_WIM_CLOSE) { - break; - } - } - control->isRunning = 0; - JabberLog(control->proto, "recording thread ended..."); - return 0; -} - - -/*static void CALLBACK TlenVoiceRecordingCallback(HWAVEIN hwi, UINT uMsg, DWORD* dwInstance, DWORD dwParam1, DWORD dwParam2) -{ - if (uMsg == WIM_DATA) { - TLEN_VOICE_CONTROL *control = (TLEN_VOICE_CONTROL *) dwInstance; - if (control->waveHeaders[control->waveHeadersPos].dwBytesRecorded>0) { - control->recordingData = (short *)control->waveHeaders[control->waveHeadersPos].lpData; - TlenVoiceSendParse(control->ft); - } - waveInAddBuffer(control->hWaveIn, &control->waveHeaders[control->waveHeadersPos], sizeof(WAVEHDR)); - control->waveHeadersPos = (control->waveHeadersPos +1) % control->waveHeadersNum; - } -}*/ - -static int TlenVoicePlaybackStart(TLEN_VOICE_CONTROL *control) -{ - WAVEFORMATEX wfm; - MMRESULT mmres; - int i, j; - int iNumDevs, iSelDev; - WAVEOUTCAPS wic; - - memset(&wfm, 0, sizeof(wfm)); - wfm.cbSize = sizeof(WAVEFORMATEX); - wfm.nChannels = 1; - wfm.wBitsPerSample = 16; - wfm.nSamplesPerSec = MODE_FREQUENCY[control->codec]; - wfm.nAvgBytesPerSec = wfm.nSamplesPerSec * wfm.nChannels * wfm.wBitsPerSample/8; - wfm.nBlockAlign = 2 * wfm.nChannels; - wfm.wFormatTag = WAVE_FORMAT_PCM; - - control->waveMode = 0; - control->waveFrameSize = MODE_FRAME_SIZE[control->codec] * 160 * wfm.nChannels;// * wfm.wBitsPerSample / 8; - control->waveHeadersPos = 0; - control->waveHeadersNum = FRAMES_AVAILABLE_MAX_LIMIT + 2; - - j = DBGetContactSettingWord(NULL, control->proto->iface.m_szModuleName, "VoiceDeviceOut", 0); - iSelDev = WAVE_MAPPER; - if (j!=0) { - iNumDevs = waveOutGetNumDevs(); - for (i = 0; i < iNumDevs; i++) { - if (!waveOutGetDevCaps(i, &wic, sizeof(WAVEOUTCAPS))) { - if (wic.dwFormats != 0) { - j--; - if (j == 0) { - iSelDev = i; - break; - } - } - } - } - } - if (!waveOutGetDevCaps(iSelDev, &wic, sizeof(WAVEOUTCAPS))) { - JabberLog(control->proto, "Playback device ID #%u: %s\r\n", iSelDev, wic.szPname); - } - - mmres = waveOutOpen(&control->hWaveOut, iSelDev, &wfm, (DWORD) &TlenVoicePlaybackCallback, (DWORD) control, CALLBACK_FUNCTION); - if (mmres!=MMSYSERR_NOERROR) { - JabberLog(control->proto, "TlenVoiceStart FAILED!"); - return 1; - } - control->waveData = (short *)mir_alloc(control->waveHeadersNum * control->waveFrameSize * 2); - memset(control->waveData, 0, control->waveHeadersNum * control->waveFrameSize * 2); - control->waveHeaders = (WAVEHDR *)mir_alloc(control->waveHeadersNum * sizeof(WAVEHDR)); - JabberLog(control->proto, "TlenVoiceStart OK!"); - return 0; -} - - -static int TlenVoiceRecordingStart(TLEN_VOICE_CONTROL *control) -{ - WAVEFORMATEX wfm; - MMRESULT mmres; - int i, j; - int iNumDevs, iSelDev; - WAVEINCAPS wic; - - memset(&wfm, 0, sizeof(wfm)); - wfm.cbSize = sizeof(WAVEFORMATEX); - wfm.nChannels = 1; - wfm.wBitsPerSample = 16; - wfm.nSamplesPerSec = MODE_FREQUENCY[control->codec]; - wfm.nAvgBytesPerSec = wfm.nSamplesPerSec * wfm.nChannels * wfm.wBitsPerSample/8; - wfm.nBlockAlign = 2 * wfm.nChannels; - wfm.wFormatTag = WAVE_FORMAT_PCM; - - - control->waveMode = 0; -// control->isRunning = 1; - control->waveFrameSize = MODE_FRAME_SIZE[control->codec] * 160 * wfm.nChannels;// * wfm.wBitsPerSample / 8; - control->waveHeadersPos = 0; - control->waveHeadersNum = 2; - - control->hThread = CreateThread( NULL, - 0, - (LPTHREAD_START_ROUTINE)TlenVoiceRecordingThreadProc, - control, - 0, - (LPDWORD)&control->threadID); - - - SetThreadPriority(control->hThread, THREAD_PRIORITY_ABOVE_NORMAL); - - j = DBGetContactSettingWord(NULL, control->proto->iface.m_szModuleName, "VoiceDeviceIn", 0); - iSelDev = WAVE_MAPPER; - if (j!=0) { - iNumDevs = waveInGetNumDevs(); - for (i = 0; i < iNumDevs; i++) { - if (!waveInGetDevCaps(i, &wic, sizeof(WAVEINCAPS))) { - if (wic.dwFormats != 0) { - j--; - if (j == 0) { - iSelDev = i; - break; - } - } - } - } - } - if (!waveInGetDevCaps(iSelDev, &wic, sizeof(WAVEINCAPS))) { - JabberLog(control->proto, "Recording device ID #%u: %s\r\n", iSelDev, wic.szPname); - } - - mmres = waveInOpen(&control->hWaveIn, iSelDev, &wfm, (DWORD) control->threadID, 0, CALLBACK_THREAD); -// mmres = waveInOpen(&control->hWaveIn, 3, &wfm, (DWORD) &TlenVoiceRecordingCallback, (DWORD) control, CALLBACK_FUNCTION); - if (mmres!=MMSYSERR_NOERROR) { - PostThreadMessage(control->threadID, WIM_CLOSE, 0, 0); - JabberLog(control->proto, "TlenVoiceStart FAILED %d!", mmres); - return 1; - } - control->waveData = (short *)mir_alloc(control->waveHeadersNum * control->waveFrameSize * 2); - memset(control->waveData, 0, control->waveHeadersNum * control->waveFrameSize * 2); - control->waveHeaders = (WAVEHDR *)mir_alloc(control->waveHeadersNum * sizeof(WAVEHDR)); - for (i=0;iwaveHeadersNum;i++) { - control->waveHeaders[i].dwFlags = 0;//WHDR_DONE; - control->waveHeaders[i].lpData = (char *) (control->waveData + i * control->waveFrameSize); - control->waveHeaders[i].dwBufferLength = control->waveFrameSize *2; - mmres = waveInPrepareHeader(control->hWaveIn, &control->waveHeaders[i], sizeof(WAVEHDR)); - if (mmres!=MMSYSERR_NOERROR) { - waveInClose(control->hWaveIn); -// PostThreadMessage(control->threadID, WIM_CLOSE, 0, 0); - JabberLog(control->proto, "TlenVoiceStart FAILED #2!"); - return 1; - } - } - for (i=0;iwaveHeadersNum;i++) { - waveInAddBuffer(control->hWaveIn, &control->waveHeaders[i], sizeof(WAVEHDR)); - } - waveInStart(control->hWaveIn); - JabberLog(control->proto, "TlenVoiceRStart OK!"); - return 0; -} - - -static TLEN_VOICE_CONTROL *TlenVoiceCreateVC(TlenProtocol *proto, int codec) -{ - TLEN_VOICE_CONTROL *vc; - vc = (TLEN_VOICE_CONTROL *) mir_alloc(sizeof (TLEN_VOICE_CONTROL)); - memset(vc, 0, sizeof(TLEN_VOICE_CONTROL)); - vc->gsmstate = gsm_create(); - vc->codec = codec; - vc->proto = proto; - return vc; -} -static void TlenVoiceFreeVc(TLEN_VOICE_CONTROL *vc) -{ - int i; - JabberLog(vc->proto, "-> TlenVoiceFreeVc"); - vc->stopThread = 1; - PostThreadMessage(vc->threadID, MM_WIM_CLOSE, 0, 0); - while(vc->isRunning) { - Sleep(50); - } - if (vc->hThread!=NULL) CloseHandle(vc->hThread); - if (vc->hWaveIn) { - for (i=0;iwaveHeadersNum;i++) { - while(waveInUnprepareHeader(vc->hWaveIn, &vc->waveHeaders[i], sizeof(WAVEHDR)) == WAVERR_STILLPLAYING) { - Sleep(50); - } - } - while(waveInClose(vc->hWaveIn) == WAVERR_STILLPLAYING) { - Sleep(50); - } - } - if (vc->hWaveOut) { - for (i=0;iwaveHeadersNum;i++) { - while(waveOutUnprepareHeader(vc->hWaveOut, &vc->waveHeaders[i], sizeof(WAVEHDR)) == WAVERR_STILLPLAYING) { - Sleep(50); - } - } - while(waveOutClose(vc->hWaveOut) == WAVERR_STILLPLAYING) { - Sleep(50); - } - } - if (vc->waveData) mir_free(vc->waveData); - if (vc->waveHeaders) mir_free(vc->waveHeaders); - if (vc->gsmstate) gsm_release(vc->gsmstate); - JabberLog(vc->proto, "<- TlenVoiceFreeVc"); - mir_free(vc); -} - -static void TlenVoiceCrypt(char *buffer, int len) -{ - int i, j, k; - j = 0x71; - for (i=0;iproto, "Thread started: type=file_receive server='%s' port='%d'", ft->hostName, ft->wPort); - nloc.cbSize = NETLIBOPENCONNECTION_V1_SIZE;//sizeof(NETLIBOPENCONNECTION); - nloc.szHost = ft->hostName; - nloc.wPort = ft->wPort; - nloc.flags = 0; - SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Connecting...")); -// ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, ft, 0); - s = (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, (WPARAM) ft->proto->hNetlibUser, (LPARAM) &nloc); - if (s != NULL) { - ft->s = s; - JabberLog(ft->proto, "Entering file receive loop"); - TlenP2PEstablishOutgoingConnection(ft, FALSE); - if (ft->state!=FT_ERROR) { - ft->proto->playbackControl = NULL; - ft->proto->recordingControl = TlenVoiceCreateVC(ft->proto, 3); - ft->proto->recordingControl->ft = ft; - TlenVoiceRecordingStart(ft->proto->recordingControl); - while (ft->state!=FT_DONE && ft->state!=FT_ERROR) { - TlenVoiceReceiveParse(ft); - } - TlenVoiceFreeVc(ft->proto->recordingControl); - ft->proto->playbackControl = NULL; - ft->proto->recordingControl = NULL; - } - if (ft->s) { - Netlib_CloseHandle(s); - } - ft->s = NULL; - } else { - JabberLog(ft->proto, "Connection failed - receiving as server"); - ft->pfnNewConnectionV2 = TlenVoiceReceivingConnection; - s = TlenP2PListen(ft); - if (s != NULL) { - HANDLE hEvent; - char *nick; - SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Waiting for connection...")); - ft->s = s; - hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - ft->hFileEvent = hEvent; - ft->currentFile = 0; - ft->state = FT_CONNECTING; - nick = JabberNickFromJID(ft->jid); - JabberSend(ft->proto, "", nick, ft->iqId, ft->localName, ft->wLocalPort); - mir_free(nick); - JabberLog(ft->proto, "Waiting for the file to be received..."); - WaitForSingleObject(hEvent, INFINITE); - ft->hFileEvent = NULL; - CloseHandle(hEvent); - JabberLog(ft->proto, "Finish all files"); - Netlib_CloseHandle(s); - } else { - ft->state = FT_ERROR; - } - } - JabberListRemove(ft->proto, LIST_VOICE, ft->iqId); - if (ft->state==FT_DONE) { - SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Finished...")); - //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); - } else { - char *nick; - nick = JabberNickFromJID(ft->jid); - JabberSend(ft->proto, "", nick, ft->iqId); - mir_free(nick); - SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Error...")); - //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - } - JabberLog(ft->proto, "Thread ended: type=file_receive server='%s'", ft->hostName); - - TlenP2PFreeFileTransfer(ft); -} - -static void TlenVoiceReceivingConnection(JABBER_SOCKET hConnection, DWORD dwRemoteIP, void * pExtra) -{ - JABBER_SOCKET slisten; - TLEN_FILE_TRANSFER *ft; - TlenProtocol *proto = (TlenProtocol *)pExtra; - - ft = TlenP2PEstablishIncomingConnection(proto, hConnection, LIST_VOICE, FALSE); - if (ft != NULL) { - slisten = ft->s; - ft->s = hConnection; - JabberLog(ft->proto, "Set ft->s to %d (saving %d)", hConnection, slisten); - JabberLog(ft->proto, "Entering send loop for this file connection... (ft->s is hConnection)"); - proto->playbackControl = NULL; - proto->recordingControl = TlenVoiceCreateVC(proto, 3); - proto->recordingControl->ft = ft; - TlenVoiceRecordingStart(proto->recordingControl); - while (ft->state!=FT_DONE && ft->state!=FT_ERROR) { - TlenVoiceReceiveParse(ft); - } - TlenVoiceFreeVc(proto->recordingControl); - proto->playbackControl = NULL; - proto->recordingControl = NULL; - if (ft->state==FT_DONE) { - SetDlgItemText(proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Finished...")); -// ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); - } else { -// ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Error...")); - } - JabberLog(ft->proto, "Closing connection for this file transfer... (ft->s is now hBind)"); - ft->s = slisten; - JabberLog(ft->proto, "ft->s is restored to %d", ft->s); - } - Netlib_CloseHandle(hConnection); - if (ft!=NULL && ft->hFileEvent != NULL) - SetEvent(ft->hFileEvent); -} - -static void TlenVoiceReceiveParse(TLEN_FILE_TRANSFER *ft) -{ - char *statusTxt; - int i, j; - char *p; - float val; - TLEN_FILE_PACKET *packet; - packet = TlenP2PPacketReceive(ft->s); - if (packet != NULL) { - statusTxt = " Unknown packet "; - p = packet->packet; - if (packet->type == TLEN_VOICE_PACKET) { - short *out; - int codec, chunkNum; - statusTxt = " OK "; - TlenVoiceCrypt(packet->packet+4, packet->len-4); - codec = *((int *)packet->packet); - if (codec<2 || codec>5) { - statusTxt = " Unknown codec "; - } else { - if (ft->proto->playbackControl == NULL) { - ft->proto->playbackControl = TlenVoiceCreateVC(ft->proto, codec); - TlenVoicePlaybackStart(ft->proto->playbackControl); - ft->proto->framesAvailableForPlayback = 0; - ft->proto->availOverrunValue = 0; - } else if (ft->proto->playbackControl->codec != codec) { - TlenVoiceFreeVc(ft->proto->playbackControl); - ft->proto->playbackControl = TlenVoiceCreateVC(ft->proto, codec); - TlenVoicePlaybackStart(ft->proto->playbackControl); - ft->proto->framesAvailableForPlayback = 0; - ft->proto->availOverrunValue = 0; - } - if (!ft->proto->playbackControl->bDisable) { - ft->proto->playbackControl->waveHeaders[ft->proto->playbackControl->waveHeadersPos].dwFlags = WHDR_DONE; - ft->proto->playbackControl->waveHeaders[ft->proto->playbackControl->waveHeadersPos].lpData = (char *) (ft->proto->playbackControl->waveData + ft->proto->playbackControl->waveHeadersPos * ft->proto->playbackControl->waveFrameSize); - ft->proto->playbackControl->waveHeaders[ft->proto->playbackControl->waveHeadersPos].dwBufferLength = ft->proto->playbackControl->waveFrameSize * 2; - /* - if (availPlayback == 0) { - statusTxt = "!! Buffer is empty !!"; - availPlayback++; - waveOutPrepareHeader(playbackControl->hWaveOut, &playbackControl->waveHeaders[playbackControl->waveHeadersPos], sizeof(WAVEHDR)); - waveOutWrite(playbackControl->hWaveOut, &playbackControl->waveHeaders[playbackControl->waveHeadersPos], sizeof(WAVEHDR)); - playbackControl->waveHeadersPos = (playbackControl->waveHeadersPos +1) % playbackControl->waveHeadersNum; - playbackControl->waveHeaders[playbackControl->waveHeadersPos].dwFlags = WHDR_DONE; - playbackControl->waveHeaders[playbackControl->waveHeadersPos].lpData = (char *) (playbackControl->waveData + playbackControl->waveHeadersPos * playbackControl->waveFrameSize); - playbackControl->waveHeaders[playbackControl->waveHeadersPos].dwBufferLength = playbackControl->waveFrameSize * 2; - } - */ - chunkNum = min(MODE_FRAME_SIZE[codec], (int)(packet->len - 4) / 33); - out = (short *)ft->proto->playbackControl->waveHeaders[ft->proto->playbackControl->waveHeadersPos].lpData; - for (i=0; iproto->playbackControl->gsmstate->gsmFrame[j] = packet->packet[i*33 +j +4]; - } - gsm_decode(ft->proto->playbackControl->gsmstate, out); - out += 160; - } - out = (short *)ft->proto->playbackControl->waveHeaders[ft->proto->playbackControl->waveHeadersPos].lpData; - val = 0; - for (i=0; i VU_METER_LEVELS - 1 ) { - j = VU_METER_LEVELS - 1; - } else if (j<0) { - j = 0; - } - ft->proto->playbackControl->vuMeter = j; - ft->proto->playbackControl->bytesSum += 8 + packet->len; - /* Simple logic to avoid huge delays. If a delay is detected a frame is not played */ - j = ft->proto->availOverrunValue > 0 ? -1 : 0; - while (ft->proto->framesAvailableForPlayback > FRAMES_AVAILABLE_MAX_LIMIT) { - j = 1; - SleepEx(5, FALSE); - } - ft->proto->availOverrunValue += j; - /* 40 frames - 800ms/8kHz */ - if (ft->proto->availOverrunValue < 40) { - ft->proto->framesAvailableForPlayback++; - waveOutPrepareHeader(ft->proto->playbackControl->hWaveOut, &ft->proto->playbackControl->waveHeaders[ft->proto->playbackControl->waveHeadersPos], sizeof(WAVEHDR)); - waveOutWrite(ft->proto->playbackControl->hWaveOut, &ft->proto->playbackControl->waveHeaders[ft->proto->playbackControl->waveHeadersPos], sizeof(WAVEHDR)); - ft->proto->playbackControl->waveHeadersPos = (ft->proto->playbackControl->waveHeadersPos +1) % ft->proto->playbackControl->waveHeadersNum; - } else { - ft->proto->availOverrunValue -= 10; - statusTxt = "!! Skipping frame !!"; - } - } - } - } - { - char ttt[2048]; - sprintf(ttt, "%s %d %d ", statusTxt, ft->proto->framesAvailableForPlayback, ft->proto->availOverrunValue); - SetDlgItemTextA(ft->proto->voiceDlgHWND, IDC_STATUS, ttt); - } - TlenP2PPacketFree(packet); - } - else { - if (ft->proto->playbackControl!=NULL) { - TlenVoiceFreeVc(ft->proto->playbackControl); - ft->proto->playbackControl = NULL; - } - ft->state = FT_ERROR; - } -} - - -void __cdecl TlenVoiceSendingThread(TLEN_FILE_TRANSFER *ft) -{ - JABBER_SOCKET s = NULL; - HANDLE hEvent; - char *nick; - - JabberLog(ft->proto, "Thread started: type=voice_send"); - ft->pfnNewConnectionV2 = TlenVoiceReceivingConnection; - s = TlenP2PListen(ft); - if (s != NULL) { - SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Waiting for connection...")); - //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, ft, 0); - ft->s = s; - //JabberLog("ft->s = %d", s); - //JabberLog("fileCount = %d", ft->fileCount); - - hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - ft->hFileEvent = hEvent; - ft->currentFile = 0; - ft->state = FT_CONNECTING; - - nick = JabberNickFromJID(ft->jid); - JabberSend(ft->proto, "", nick, ft->iqId, ft->localName, ft->wLocalPort); - mir_free(nick); - JabberLog(ft->proto, "Waiting for the voice data to be sent..."); - WaitForSingleObject(hEvent, INFINITE); - ft->hFileEvent = NULL; - CloseHandle(hEvent); - JabberLog(ft->proto, "Finish voice"); - Netlib_CloseHandle(s); - ft->s = NULL; - JabberLog(ft->proto, "ft->s is NULL"); - - if (ft->state == FT_SWITCH) { - NETLIBOPENCONNECTION nloc; - JABBER_SOCKET s; - JabberLog(ft->proto, "Sending as client..."); - ft->state = FT_CONNECTING; - nloc.cbSize = NETLIBOPENCONNECTION_V1_SIZE;//sizeof(NETLIBOPENCONNECTION); - nloc.szHost = ft->hostName; - nloc.wPort = ft->wPort; - nloc.flags = 0; - s = (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, (WPARAM) ft->proto->hNetlibUser, (LPARAM) &nloc); - if (s != NULL) { - SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Connecting...")); - //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, ft, 0); - ft->s = s; - TlenP2PEstablishOutgoingConnection(ft, FALSE); - if (ft->state!=FT_ERROR) { - JabberLog(ft->proto, "Entering send loop for this file connection..."); - ft->proto->playbackControl = NULL; - ft->proto->recordingControl = TlenVoiceCreateVC(ft->proto, 3); - ft->proto->recordingControl->ft = ft; - TlenVoiceRecordingStart(ft->proto->recordingControl); - while (ft->state!=FT_DONE && ft->state!=FT_ERROR) { - TlenVoiceReceiveParse(ft); - } - } - JabberLog(ft->proto, "Closing connection for this file transfer... "); - Netlib_CloseHandle(s); - } else { - ft->state = FT_ERROR; - } - } - } else { - JabberLog(ft->proto, "Cannot allocate port to bind for file server thread, thread ended."); - ft->state = FT_ERROR; - } - JabberListRemove(ft->proto, LIST_VOICE, ft->iqId); - switch (ft->state) { - case FT_DONE: - JabberLog(ft->proto, "Finish successfully"); - SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Finished...")); - //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); - break; - case FT_DENIED: - SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Denied...")); - //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_DENIED, ft, 0); - break; - default: // FT_ERROR: - nick = JabberNickFromJID(ft->jid); - JabberSend(ft->proto, "", nick, ft->iqId); - mir_free(nick); - JabberLog(ft->proto, "Finish with errors"); - SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Error...")); - //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - break; - } - JabberLog(ft->proto, "Thread ended: type=voice_send"); - TlenP2PFreeFileTransfer(ft); -} - -static void TlenVoiceSendParse(TLEN_FILE_TRANSFER *ft) -{ - int codec, i; - TLEN_FILE_PACKET *packet; - - codec = ft->proto->recordingControl->codec; - if ((packet=TlenP2PPacketCreate(sizeof(DWORD)+MODE_FRAME_SIZE[codec]*33)) != NULL) { - short *in; - float val; - in = ft->proto->recordingControl->recordingData; - TlenP2PPacketSetType(packet, 0x96); - packet->packet[0] = codec; - TlenP2PPacketPackDword(packet, codec); - val = 0; - for (i=0; i VU_METER_LEVELS - 1 ) { - i = VU_METER_LEVELS - 1; - } else if (i<0) { - i = 0; - } - ft->proto->recordingControl->vuMeter = i; - for (i=0; iproto->recordingControl->gsmstate, in + i * 160); - TlenP2PPacketPackBuffer(packet, (char*)ft->proto->recordingControl->gsmstate->gsmFrame, 33); - } - TlenVoiceCrypt(packet->packet+4, packet->len-4); - if (!TlenP2PPacketSend(ft->s, packet)) { - ft->state = FT_ERROR; - } - ft->proto->recordingControl->bytesSum += 8 + packet->len; - TlenP2PPacketFree(packet); - } else { - ft->state = FT_ERROR; - } -} - -int TlenVoiceCancelAll(TlenProtocol *proto) -{ - JABBER_LIST_ITEM *item; - HANDLE hEvent; - int i = 0; - - while ((i=JabberListFindNext(proto, LIST_VOICE, 0)) >=0 ) { - if ((item=JabberListGetItemPtrFromIndex(proto, i)) != NULL) { - TLEN_FILE_TRANSFER *ft = item->ft; - JabberListRemoveByIndex(proto, i); - if (ft != NULL) { - if (ft->s) { - //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - JabberLog(proto, "Closing ft->s = %d", ft->s); - ft->state = FT_ERROR; - Netlib_CloseHandle(ft->s); - ft->s = NULL; - if (ft->hFileEvent != NULL) { - hEvent = ft->hFileEvent; - ft->hFileEvent = NULL; - SetEvent(hEvent); - } - } else { - JabberLog(proto, "freeing (V) ft struct"); - TlenP2PFreeFileTransfer(ft); - } - } - } - } - if (proto->voiceDlgHWND !=NULL) { - EndDialog(proto->voiceDlgHWND, 0); - } - return 0; -} - -INT_PTR TlenVoiceContactMenuHandleVoice(void *ptr, WPARAM wParam, LPARAM lParam) -{ - HANDLE hContact; - DBVARIANT dbv; - JABBER_LIST_ITEM *item; - TLEN_FILE_TRANSFER *ft; - TlenProtocol *proto =(TlenProtocol *)ptr; - if (!proto->isOnline) { - return 1; - } - if ((hContact=(HANDLE) wParam)!=NULL) { - if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { - char serialId[32]; - sprintf(serialId, "%d", JabberSerialNext(proto)); - if ((item = JabberListAdd(proto, LIST_VOICE, serialId)) != NULL) { - ft = TlenFileCreateFT(proto, dbv.pszVal); - ft->iqId = mir_strdup(serialId); - item->ft = ft; -// JabberSend(ft->proto, "", ft->jid); -// Sleep(5000); - TlenVoiceStart(ft, 2); - JabberSend(ft->proto, "", ft->jid, serialId); - } - DBFreeVariant(&dbv); - } - } - return 0; -} - -int TlenVoiceIsInUse(TlenProtocol *proto) { - if (JabberListFindNext(proto, LIST_VOICE, 0) >= 0 || proto->voiceDlgHWND!=NULL) { - JabberLog(proto, "voice in use ? %d", proto->voiceDlgHWND); - return 1; - } - return 0; -} - -static HBITMAP TlenVoiceMakeBitmap(int w, int h, int bpp, void *ptr) -{ - BITMAPINFO bmih; - HBITMAP hbm; - HDC hdc; - bmih.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmih.bmiHeader.biWidth = w&0xFFFFFFFC; - bmih.bmiHeader.biHeight = h;//&0xFFFFFFFC; - bmih.bmiHeader.biPlanes = 1; // musi byc 1 - bmih.bmiHeader.biBitCount = bpp; - bmih.bmiHeader.biCompression = BI_RGB; - bmih.bmiHeader.biSizeImage = 0; - bmih.bmiHeader.biXPelsPerMeter = 0; - bmih.bmiHeader.biYPelsPerMeter = 0; - bmih.bmiHeader.biClrUsed = 0; - bmih.bmiHeader.biClrImportant = 0; - hdc = CreateDC(_T("DISPLAY"), NULL, NULL, NULL); - hbm = CreateDIBitmap(hdc, (PBITMAPINFOHEADER) &bmih, CBM_INIT, ptr, &bmih, DIB_RGB_COLORS); - ReleaseDC(NULL,hdc); - return hbm; -} - -static void TlenVoiceInitVUMeters() -{ - int i, v, y, x, x0, col, col0; - unsigned char *pBits; - int ledWidth, ledHeight; - ledWidth = 9; - ledHeight = 6; - VU_METER_HEIGHT = ledHeight; - VU_METER_WIDTH = (VU_METER_LEVELS-1) * ledWidth; - VU_METER_WIDTH = (VU_METER_WIDTH + 3) & (~3); - pBits = (unsigned char *)mir_alloc(3*VU_METER_WIDTH*VU_METER_HEIGHT); - memset(pBits, 0x80, 3*VU_METER_WIDTH*VU_METER_HEIGHT); - for (i=0;i=i) { - if (v < 10) col0 = 0x104010; - else if (v<13) col0 = 0x404010; - else col0 = 0x401010; - } else { - if (v < 10) col0 = 0x00f000; - else if (v<13) col0 = 0xf0f000; - else col0 = 0xf00000; - } - x0 = v * ledWidth; - for (y=1;y>8) &0xFF; - pBits[3*(x+x0+y*VU_METER_WIDTH)+2] = (col>>16) &0xFF; - } - } - } - vuMeterBitmaps[i] = TlenVoiceMakeBitmap(VU_METER_WIDTH, VU_METER_HEIGHT, 24, pBits); - } - mir_free(pBits); -} - -static INT_PTR CALLBACK TlenVoiceDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - HDC hDC, hMemDC; - int v; - static int counter; - TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - case WM_INITDIALOG: - proto = (TlenProtocol *)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); - proto->voiceDlgHWND = hwndDlg; - TranslateDialogDefault(hwndDlg); - SendDlgItemMessage(hwndDlg, IDC_VCQUALITY, CB_ADDSTRING, 0, (LPARAM) TranslateT("8000 Hz / 13.8 kbps")); - SendDlgItemMessage(hwndDlg, IDC_VCQUALITY, CB_ADDSTRING, 0, (LPARAM) TranslateT("11025 Hz / 19.1 kbps")); - SendDlgItemMessage(hwndDlg, IDC_VCQUALITY, CB_ADDSTRING, 0, (LPARAM) TranslateT("22050 Hz / 36.8 kbps")); - SendDlgItemMessage(hwndDlg, IDC_VCQUALITY, CB_ADDSTRING, 0, (LPARAM) TranslateT("44100 Hz / 72 kbps")); - SendDlgItemMessage(hwndDlg, IDC_VCQUALITY, CB_SETCURSEL, 1, 0); - SendDlgItemMessage(hwndDlg, IDC_MICROPHONE, BUTTONSETASFLATBTN, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_SPEAKER, BUTTONSETASFLATBTN, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_MICROPHONE, BUTTONSETASPUSHBTN, 0, 0); - SendDlgItemMessage(hwndDlg, IDC_SPEAKER, BUTTONSETASPUSHBTN, 0, 0); - { - HICON hIcon = GetIcolibIcon(IDI_MICROPHONE); - SendDlgItemMessage(hwndDlg, IDC_MICROPHONE, BM_SETIMAGE, IMAGE_ICON, (LPARAM) hIcon); - ReleaseIcolibIcon(hIcon); - hIcon = GetIcolibIcon(IDI_SPEAKER); - SendDlgItemMessage(hwndDlg, IDC_SPEAKER, BM_SETIMAGE, IMAGE_ICON, (LPARAM) hIcon); - ReleaseIcolibIcon(hIcon); - } - CheckDlgButton(hwndDlg, IDC_MICROPHONE, TRUE); - CheckDlgButton(hwndDlg, IDC_SPEAKER, TRUE); - TlenVoiceInitVUMeters(); - SetDlgItemText(hwndDlg, IDC_STATUS, TranslateT("...???...")); - counter = 0; - SetTimer(hwndDlg, 1, 100, NULL); - return FALSE; - case WM_TIMER: - if (proto->recordingControl != NULL && !proto->recordingControl->bDisable) { - v = proto->recordingControl->vuMeter % VU_METER_LEVELS; - if (proto->recordingControl->vuMeter >0) { - proto->recordingControl->vuMeter--; - } - } else { - v = 0; - } - hDC = GetDC(GetDlgItem(hwndDlg, IDC_VUMETERIN)); - if (NULL != (hMemDC = CreateCompatibleDC( hDC ))) { - SelectObject( hMemDC, vuMeterBitmaps[v]) ; - BitBlt( hDC, 0, 0, VU_METER_WIDTH, VU_METER_HEIGHT, hMemDC, 0, 0, SRCCOPY ) ; - DeleteDC(hMemDC); - } - ReleaseDC(GetDlgItem(hwndDlg, IDC_PLAN), hDC); - if (proto->playbackControl != NULL && !proto->playbackControl->bDisable) { - v = proto->playbackControl->vuMeter % VU_METER_LEVELS; - if (proto->playbackControl->vuMeter >0) { - proto->playbackControl->vuMeter--; - } - } else { - v = 0; - } - hDC = GetDC(GetDlgItem(hwndDlg, IDC_VUMETEROUT)); - if (NULL != (hMemDC = CreateCompatibleDC( hDC ))) { - SelectObject( hMemDC, vuMeterBitmaps[v]) ; - BitBlt( hDC, 0, 0, VU_METER_WIDTH, VU_METER_HEIGHT, hMemDC, 0, 0, SRCCOPY ) ; - DeleteDC(hMemDC); - } - ReleaseDC(GetDlgItem(hwndDlg, IDC_PLAN), hDC); - counter ++; - if (counter %10 == 0) { - char str[50]; - float fv; - if (proto->recordingControl != NULL) { - fv = (float)proto->recordingControl->bytesSum; - proto->recordingControl->bytesSum = 0; - } else { - fv = 0; - } - sprintf(str, "%.1f kB/s", fv / 1024); - SetDlgItemTextA(hwndDlg, IDC_BYTESOUT, str); - if (proto->playbackControl != NULL) { - fv = (float)proto->playbackControl->bytesSum; - proto->playbackControl->bytesSum = 0; - } else { - fv = 0; - } - sprintf(str, "%.1f kB/s", fv / 1024); - SetDlgItemTextA(hwndDlg, IDC_BYTESIN, str); - } - break; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDCANCEL: - EndDialog(hwndDlg, 0); - return TRUE; - case IDC_VCQUALITY: - if (HIWORD(wParam)==CBN_SELCHANGE) { - if (proto->recordingControl!=NULL) { - int codec; - codec = SendDlgItemMessage(hwndDlg, IDC_VCQUALITY, CB_GETCURSEL, 0, 0) + 2; - if (codec!=proto->recordingControl->codec && codec>1 && codec<6) { - TLEN_FILE_TRANSFER *ft = proto->recordingControl->ft; - TlenVoiceFreeVc(proto->recordingControl); - proto->recordingControl = TlenVoiceCreateVC(ft->proto, codec); - proto->recordingControl->ft = ft; - TlenVoiceRecordingStart(proto->recordingControl); - } - } - } - case IDC_MICROPHONE: - if (proto->recordingControl!=NULL) { - proto->recordingControl->bDisable = !IsDlgButtonChecked(hwndDlg, IDC_MICROPHONE); - } - break; - case IDC_SPEAKER: - if (proto->playbackControl!=NULL) { - proto->playbackControl->bDisable = !IsDlgButtonChecked(hwndDlg, IDC_SPEAKER); - } - break; - } - break; - case WM_CLOSE: - EndDialog(hwndDlg, 0); - break; - case WM_DESTROY: - proto->voiceDlgHWND = NULL; - break; - - } - return FALSE; -} - -static void __cdecl TlenVoiceDlgThread(void *ptr) -{ - - TLEN_FILE_TRANSFER *ft = (TLEN_FILE_TRANSFER *)ptr; - TlenProtocol * proto = ft->proto; - DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_VOICE), NULL, TlenVoiceDlgProc, (LPARAM) proto); - TlenVoiceCancelAll(proto); -} - -int TlenVoiceStart(TLEN_FILE_TRANSFER *ft, int mode) -{ - - JabberLog(ft->proto, "starting voice %d", mode); - if (mode==0) { - JabberForkThread((void (__cdecl *)(void*))TlenVoiceReceiveThread, 0, ft); - } else if (mode==1) { - JabberForkThread((void (__cdecl *)(void*))TlenVoiceSendingThread, 0, ft); - } else { - JabberForkThread((void (__cdecl *)(void*))TlenVoiceDlgThread, 0, ft); - } - return 0; -} - -static char *getDisplayName(TlenProtocol *proto, const char *id) -{ - char jid[256]; - HANDLE hContact; - DBVARIANT dbv; - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { - _snprintf(jid, sizeof(jid), "%s@%s", id, dbv.pszVal); - DBFreeVariant(&dbv); - if ((hContact=JabberHContactFromJID(proto, jid)) != NULL) { - return mir_strdup((char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, 0)); - } - } - return mir_strdup(id); -} - -typedef struct { - TlenProtocol *proto; - JABBER_LIST_ITEM *item; -}ACCEPTDIALOGDATA; - -static INT_PTR CALLBACK TlenVoiceAcceptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - ACCEPTDIALOGDATA * data; - char *str; - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - data = (ACCEPTDIALOGDATA *) lParam; - str = getDisplayName(data->proto, data->item->nick); - SetDlgItemTextA(hwndDlg, IDC_FROM, str); - mir_free(str); - return FALSE; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_ACCEPT: - EndDialog(hwndDlg, 1); - return TRUE; - case IDCANCEL: - case IDCLOSE: - EndDialog(hwndDlg, 0); - return TRUE; - } - break; - case WM_CLOSE: - EndDialog(hwndDlg, 0); - break; - } - return FALSE; -} - -static void __cdecl TlenVoiceAcceptDlgThread(void *ptr) -{ - - ACCEPTDIALOGDATA *data = (ACCEPTDIALOGDATA *)ptr; - int result = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ACCEPT_VOICE), NULL, TlenVoiceAcceptDlgProc, (LPARAM) data); - if (result && data->proto->isOnline) { - data->item->ft = TlenFileCreateFT(data->proto, data->item->nick); - data->item->ft->iqId = mir_strdup(data->item->jid); - TlenVoiceStart(data->item->ft, 2); - JabberSend(data->proto, "", data->item->nick, data->item->jid); - } else { - if (data->proto->isOnline) { - JabberSend(data->proto, "", data->item->nick, data->item->jid); - } - JabberListRemove(data->proto, LIST_VOICE, data->item->jid); - } - mir_free(data); -} - -int TlenVoiceAccept(TlenProtocol *proto, const char *id, const char *from) -{ - JABBER_LIST_ITEM * item; - if (!TlenVoiceIsInUse(proto)) { - if ((item = JabberListAdd(proto, LIST_VOICE, id)) != NULL) { - int ask, ignore, voiceChatPolicy; - ask = TRUE; - ignore = FALSE; - voiceChatPolicy = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "VoiceChatPolicy", 0); - if (voiceChatPolicy == TLEN_MUC_ASK) { - ignore = FALSE; - ask = TRUE; - } else if (voiceChatPolicy == TLEN_MUC_IGNORE_ALL) { - ignore = TRUE; - } else if (voiceChatPolicy == TLEN_MUC_IGNORE_NIR) { - char jid[256]; - DBVARIANT dbv; - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { - _snprintf(jid, sizeof(jid), "%s@%s", from, dbv.pszVal); - DBFreeVariant(&dbv); - } else { - strcpy(jid, from); - } - ignore = !IsAuthorized(proto, jid); - ask = TRUE; - } else if (voiceChatPolicy == TLEN_MUC_ACCEPT_IR) { - char jid[256]; - JABBER_LIST_ITEM *item; - DBVARIANT dbv; - if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { - _snprintf(jid, sizeof(jid), "%s@%s", from, dbv.pszVal); - DBFreeVariant(&dbv); - } else { - strcpy(jid, from); - } - ask = !IsAuthorized(proto, jid); - ignore = FALSE; - } else if (voiceChatPolicy == TLEN_MUC_ACCEPT_ALL) { - ask = FALSE; - ignore = FALSE; - } - if (ignore) { - if (proto->isOnline) { - JabberSend(proto, "", from, id); - } - JabberListRemove(proto, LIST_VOICE, id); - } else { - item->nick = mir_strdup(from); - if (ask) { - ACCEPTDIALOGDATA *data = (ACCEPTDIALOGDATA *)mir_alloc(sizeof(ACCEPTDIALOGDATA)); - data->proto = proto; - data->item = item; - JabberForkThread((void (__cdecl *)(void*))TlenVoiceAcceptDlgThread, 0, data); - } else if (proto->isOnline) { - item->ft = TlenFileCreateFT(proto, from); - item->ft->iqId = mir_strdup(id); - TlenVoiceStart(item->ft, 2); - JabberSend(proto, "", item->nick, item->jid); - } - } - return 1; - } - } - return 0; -} - -int TlenVoiceBuildInDeviceList(TlenProtocol *proto, HWND hWnd) -{ int i, j, iNumDevs; - WAVEINCAPS wic; - iNumDevs = waveInGetNumDevs(); - SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)TranslateT("Default")); - for (i = j = 0; i < iNumDevs; i++) { - if (!waveInGetDevCaps(i, &wic, sizeof(WAVEINCAPS))) { - if (wic.dwFormats != 0) { - SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)wic.szPname); - j++; - } - } - } - i = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "VoiceDeviceIn", 0); - if (i>j) i = 0; - SendMessage(hWnd, CB_SETCURSEL, i, 0); - return 0; -} - -int TlenVoiceBuildOutDeviceList(TlenProtocol *proto, HWND hWnd) -{ int i, j, iNumDevs; - WAVEOUTCAPS woc; - iNumDevs = waveInGetNumDevs(); - SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)TranslateT("Default")); - for (i = j = 0; i < iNumDevs; i++) { - if (!waveOutGetDevCaps(i, &woc, sizeof(WAVEOUTCAPS))) { - if (woc.dwFormats != 0) { - SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)woc.szPname); - j++; - } - } - } - i = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "VoiceDeviceOut", 0); - if (i>j) i = 0; - SendMessage(hWnd, CB_SETCURSEL, i, 0); - return 0; -} diff --git a/!NotAdopted/Tlen/tlen_voice.h b/!NotAdopted/Tlen/tlen_voice.h deleted file mode 100644 index cd38a23c1c..0000000000 --- a/!NotAdopted/Tlen/tlen_voice.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - -Tlen Protocol Plugin for Miranda IM -Copyright (C) 2004-2007 Piotr Piastucki - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#ifndef _TLEN_VOICE_H_ -#define _TLEN_VOICE_H_ - -#include -#include - -#include "jabber.h" -#include "codec/gsm.h" - -typedef struct TLEN_VOICE_CONTROL_STRUCT { - int waveMode; - int codec; - int bDisable; - - short *recordingData; - short *waveData; - WAVEHDR *waveHeaders; - int waveFrameSize; - int waveHeadersPos; - int waveHeadersNum; - -// HANDLE hEvent; - HANDLE hThread; - DWORD threadID; - HWAVEOUT hWaveOut; - HWAVEIN hWaveIn; - int isRunning; - int stopThread; - gsm_state *gsmstate; - TLEN_FILE_TRANSFER *ft; - int vuMeter; - int bytesSum; - TlenProtocol *proto; -} TLEN_VOICE_CONTROL; - - -extern void __cdecl TlenVoiceSendingThread(TLEN_FILE_TRANSFER *ft); -extern void __cdecl TlenVoiceReceiveThread(TLEN_FILE_TRANSFER *ft); -extern int TlenVoiceIsInUse(TlenProtocol *proto); -extern INT_PTR TlenVoiceContactMenuHandleVoice(void *ptr, WPARAM wParam, LPARAM lParam); -extern int TlenVoiceCancelAll(TlenProtocol *proto); -extern int TlenVoiceStart(TLEN_FILE_TRANSFER *ft, int mode) ; -extern int TlenVoiceAccept(TlenProtocol *proto, const char *id, const char *from); -extern int TlenVoiceBuildInDeviceList(TlenProtocol *proto, HWND hWnd); -extern int TlenVoiceBuildOutDeviceList(TlenProtocol *proto, HWND hWnd); -#endif - diff --git a/!NotAdopted/XSoundNotify/DebugLogger.hpp b/!NotAdopted/XSoundNotify/DebugLogger.hpp deleted file mode 100644 index 3b2c5a5fc1..0000000000 --- a/!NotAdopted/XSoundNotify/DebugLogger.hpp +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef _GRS_DEBUG_LOGGER_H -#define _GRS_DEBUG_LOGGER_H - -#include -#include -#include -#include - -/** - * Простой логгер, который можно использовать в любом месте для вывода отладочной информации - * При выводе обычного сообщения надо использовать макрос GRS_DEBUG_LOG - * Для вывода сложного сообщения с использованием операторов ввода/вывода макрос GRS_DEBUG_FORMAT_LOG - * Лог сохраняется в рабочем каталоге под именем : grs_debug.log - */ - -namespace grs -{ - -class DebugLogger -{ -public: - class Except : public std::exception - { - public: - virtual const char * what() const throw() { return "pizda rulu"; } - }; - - DebugLogger() - { - try - { - _strm.open("D:\\grs_debug.log", std::ios::app); - } - catch (...) - { - throw Except(); - } - if (!_strm.is_open()) - throw Except(); - - log("Logger started"); - } - - void log(const std::string & str, const char * fileStr = 0, int line = 0) - { - if (!_strm.is_open()) - return ; - - time_t t(time(0)); - struct tm * timeinfo; - timeinfo = localtime (&t); - char timeStr[9]; - strftime (timeStr, 9, "%H:%M:%S", timeinfo); - _strm << "[" << timeStr << "] "; - if (fileStr) - _strm << fileStr << ":" << line<<" "; - _strm <<"# "<< str << std::endl; - } - - static DebugLogger * instance() - { - //static DebugLogger * logger = 0; - static std::auto_ptr loggerPtr; - if (loggerPtr.get() == 0) - loggerPtr.reset(new DebugLogger()); - return loggerPtr.get(); - } - -private: - std::ofstream _strm; -}; - -} - -#define GRS_DEBUG_FORMAT_LOG(data) {\ - grs::DebugLogger * l = grs::DebugLogger::instance();\ - if (l != 0) \ - {\ - std::stringstream strm;\ - strm << data;\ - l->log(strm.str(), __FILE__, __LINE__);\ - }\ - } - -#define GRS_DEBUG_LOG(data) {\ - grs::DebugLogger * l = grs::DebugLogger::instance();\ - if (l != 0)\ - l->log(data, __FILE__, __LINE__);\ - } - -#endif diff --git a/!NotAdopted/XSoundNotify/EventProcessor.cpp b/!NotAdopted/XSoundNotify/EventProcessor.cpp deleted file mode 100644 index 6a97b6b125..0000000000 --- a/!NotAdopted/XSoundNotify/EventProcessor.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include "EventProcessor.h" -#include -#include "m_protocols.h" -#include -#include "DebugLogger.hpp" - -// static area - -static std::unique_ptr XSN_EventProcessorPtr; - -void XSN_EventProcessor::make(PLUGINLINK * pl) -{ - XSN_EventProcessorPtr.reset(new XSN_EventProcessor(pl)); -} - -XSN_EventProcessor & XSN_EventProcessor::instance() -{ - return *XSN_EventProcessorPtr; -} - -// class methods - -XSN_EventProcessor::XSN_EventProcessor(PLUGINLINK * pl) : pluginLink(pl) -{ - -} - -void XSN_EventProcessor::process(WPARAM wParam, LPARAM lParam) -{ - if (!wParam || !lParam || !isReceiveMessage(lParam)) - return ; - try - { - MessageBox(0, "Receive message", "INFO", MB_OK); - /*GRS_DEBUG_LOG("Receive message"); - HANDLE contact = (HANDLE)wParam; - MessageBox(0, "Get protocol", "INFO", MB_OK); - GRS_DEBUG_LOG("Protocol : "); - xsn_string proto = getProtocol(wParam); - MessageBox(0, "Protocol is", proto.c_str(), MB_OK); - GRS_DEBUG_FORMAT_LOG(proto) - //xsn_string nick = getNick(wParam, proto.c_str()); - XSN_Variant sound; - DBGetContactSettingTString(contact, proto.c_str(), "XSNPlugin_sound", &sound); - if (!sound.empty()) - { - GRS_DEBUG_LOG("Sound for user exist"); - GRS_DEBUG_FORMAT_LOG("Playing sound : " << sound.ptszVal << ", for user : " << getNick(wParam, proto.c_str())); - PlaySound(sound.toString().c_str(), nullptr, SND_FILENAME | SND_ASYNC); - }*/ - } - catch (std::runtime_error &) - { - //MessageBoxA(0, e.what(), "Runtime error", MB_OK); - } - catch (...) - { - //MessageBoxA(0, "Unknown error occured", "Exception", MB_OK); - } -} - -bool XSN_EventProcessor::isReceiveMessage(LPARAM event) -{ - DBEVENTINFO info ={ sizeof(info) }; - CallService(MS_DB_EVENT_GET, event, (LPARAM)&info); - - // TODO : rec msg flag : 16, send msg flag : 18 - WTF? - // return (info.eventType == EVENTTYPE_MESSAGE) && (info.flags & DBEF_READ); - // It's condition work well - magic? - return !(((info.eventType != EVENTTYPE_MESSAGE) && !(info.flags & DBEF_READ)) || (info.flags & DBEF_SENT)); -} - -xsn_string XSN_EventProcessor::getProtocol(WPARAM contact) -{ - char *pszProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, contact, 0); - return xsn_string(pszProto); -} - -xsn_string XSN_EventProcessor::getNick(WPARAM contact, LPCTSTR protocol) -{ - XSN_Variant nick; - DBGetContactSettingTString((HANDLE)contact, protocol, "Nick", &nick); - return nick.toString(); -} diff --git a/!NotAdopted/XSoundNotify/EventProcessor.h b/!NotAdopted/XSoundNotify/EventProcessor.h deleted file mode 100644 index 6de14f8f98..0000000000 --- a/!NotAdopted/XSoundNotify/EventProcessor.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __XSN_EVENT_PROCESSOR -#define __XSN_EVENT_PROCESSOR - -#include -#include "xsn_types.h" -#include - - -class XSN_EventProcessor -{ -public: - static void make(PLUGINLINK * pl); - static XSN_EventProcessor & instance(); - - void process(WPARAM wParam, LPARAM lParam); - -protected: - XSN_EventProcessor(PLUGINLINK * pl); - - bool isReceiveMessage(LPARAM event); - xsn_string getProtocol(WPARAM contact); - xsn_string getNick(WPARAM contact, LPCTSTR protocol); - - PLUGINLINK * pluginLink; -}; - -#endif diff --git a/!NotAdopted/XSoundNotify/README b/!NotAdopted/XSoundNotify/README deleted file mode 100644 index d855b95460..0000000000 --- a/!NotAdopted/XSoundNotify/README +++ /dev/null @@ -1 +0,0 @@ -Choose release mode (debug mode not configured) and configure Visual Studio environment for boost and WTL libraries include/libs paths diff --git a/!NotAdopted/XSoundNotify/SettingsDialog.cpp b/!NotAdopted/XSoundNotify/SettingsDialog.cpp deleted file mode 100644 index 69b64d776f..0000000000 --- a/!NotAdopted/XSoundNotify/SettingsDialog.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include "SettingsDialog.h" -//#include "DebugLogger.hpp" - -template -T * GetComboBoxData(CComboBox & ctrl) -{ - return (T*)(ctrl.GetItemData(ctrl.GetCurSel())); -} - -SettingsDialog::SettingsDialog(SoundNotifyDataStorage & storage) : _dataStorage(storage) -{ - -} - -BOOL SettingsDialog::PreTranslateMessage(MSG* pMsg) -{ - return ::IsDialogMessage(m_hWnd, pMsg); -} - -LRESULT SettingsDialog::onInitDialog(UINT, WPARAM, LPARAM, BOOL&) -{ - _userCombo = GetDlgItem(IDC_COMBO_USERS); - _protoCombo = GetDlgItem(IDC_COMBO_PROTO); - _chooseButton = GetDlgItem(IDC_BUTTON_CHOOSE_SOUND); - _resetButton = GetDlgItem(IDC_BUTTON_RESET_SOUND); - _playButton = GetDlgItem(IDC_BUTTON_TEST_PLAY); - _soundLabel = GetDlgItem(IDC_LABEL_SOUND); - - auto & protocols = _dataStorage.getData(); - for (auto it = protocols.begin(), end = protocols.end(); it != end; ++it) - addProtocolItem(*it); - - _userCombo.EnableWindow(0); - GetDlgItem(IDC_BUTTON_CHOOSE_SOUND).EnableWindow(0); - GetDlgItem(IDC_BUTTON_RESET_SOUND).EnableWindow(0); - GetDlgItem(IDC_BUTTON_TEST_PLAY).EnableWindow(0); - return TRUE; -} - -LRESULT SettingsDialog::onOk(WORD, WORD wID, HWND, BOOL&) -{ - EndDialog(wID); - return 0; -} - -LRESULT SettingsDialog::onCancel(WORD, WORD wID, HWND, BOOL&) -{ - EndDialog(wID); - return 0; -} - -LRESULT SettingsDialog::onSelectProtocol(WORD, WORD, HWND, BOOL&) -{ - _userCombo.ResetContent(); - auto data = GetComboBoxData(_protoCombo); - for (auto it = data->second.begin(), end = data->second.end(); it != end; ++it) - { - int id = _userCombo.AddString(it->first.c_str()); - _userCombo.SetItemData(id, (DWORD_PTR)(&(*it))); - } - _userCombo.EnableWindow(TRUE); - _playButton.EnableWindow(FALSE); - _resetButton.EnableWindow(FALSE); - _chooseButton.EnableWindow(FALSE); - _soundLabel.SetWindowText(TEXT("")); - return 0; -} - -LRESULT SettingsDialog::onSelectUser(WORD, WORD, HWND, BOOL &) -{ - auto user = GetComboBoxData(_userCombo); - _chooseButton.EnableWindow(TRUE); - - BOOL soundSelected = !user->second->soundPath().empty(); - _resetButton.EnableWindow(soundSelected); - _playButton.EnableWindow(soundSelected); - setSoundLabelText(user->second->soundPath().c_str()); - - return 0; -} - -LRESULT SettingsDialog::onChooseSound(WORD, WORD, HWND , BOOL&) -{ - CFileDialog fileDlg(1, 0, 0, OFN_FILEMUSTEXIST, TEXT("WAV files\0*.wav\0\0")); - if (fileDlg.DoModal() != IDOK) - return 0; - - setSoundLabelText(fileDlg.m_szFileName); - auto user = GetComboBoxData(_userCombo); - user->second->setSound(xsn_string(fileDlg.m_szFileName)); - _resetButton.EnableWindow(TRUE); - _playButton.EnableWindow(TRUE); - return 0; -} - -LRESULT SettingsDialog::onResetSound(WORD, WORD wID, HWND , BOOL&) -{ - auto user = GetComboBoxData(_userCombo); - user->second->setSound(xsn_string()); - _resetButton.EnableWindow(FALSE); - _playButton.EnableWindow(FALSE); - _soundLabel.SetWindowText(TEXT("")); - return 0; -} - -LRESULT SettingsDialog::onTestPlay(WORD, WORD wID, HWND , BOOL&) -{ - auto user = GetComboBoxData(_userCombo); - PlaySound(user->second->soundPath().c_str(), nullptr, SND_FILENAME | SND_ASYNC); - return 0; -} - -void SettingsDialog::setSoundLabelText(LPCTSTR text) -{ - _soundLabel.SetWindowText(PathFindFileName(text)); -} - -void SettingsDialog::addProtocolItem(ProtocolTable::value_type & value) -{ - wchar_t protocol[30]; - mbstowcs(protocol, value.first.c_str(), 30); - int idx = _protoCombo.AddString(protocol); - _protoCombo.SetItemData(idx, (DWORD_PTR)(&value)); -} diff --git a/!NotAdopted/XSoundNotify/SettingsDialog.h b/!NotAdopted/XSoundNotify/SettingsDialog.h deleted file mode 100644 index c68503a6e8..0000000000 --- a/!NotAdopted/XSoundNotify/SettingsDialog.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef __XSN_SETTINGS_DIALOG_H -#define __XSN_SETTINGS_DIALOG_H - -#include -#include -#include -#include -#include -#include "resource.h" -#include "SoundNotifyDataStorage.h" - -class SettingsDialog : public CDialogImpl -{ -private: - CComboBox _userCombo; - CComboBox _protoCombo; - CButton _chooseButton; - CButton _resetButton; - CButton _playButton; - CStatic _soundLabel; - SoundNotifyDataStorage & _dataStorage; - -public: - SettingsDialog(SoundNotifyDataStorage & dataStorage); - virtual ~SettingsDialog() {} - static BOOL DlgProcCluiOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -public: - enum {IDD = IDD_DIALOG1}; - - BEGIN_MSG_MAP(SettingsDialog) - MESSAGE_HANDLER(WM_INITDIALOG, onInitDialog) - COMMAND_HANDLER(IDC_COMBO_PROTO, CBN_SELCHANGE, onSelectProtocol) - COMMAND_HANDLER(IDC_COMBO_USERS, CBN_SELCHANGE, onSelectUser) - COMMAND_ID_HANDLER(IDOK, onOk) - COMMAND_ID_HANDLER(IDCANCEL, onCancel) - COMMAND_ID_HANDLER(IDC_BUTTON_CHOOSE_SOUND, onChooseSound) - COMMAND_ID_HANDLER(IDC_BUTTON_RESET_SOUND, onResetSound) - COMMAND_ID_HANDLER(IDC_BUTTON_TEST_PLAY, onTestPlay) - END_MSG_MAP() - - virtual BOOL PreTranslateMessage(MSG* pMsg); - -protected: - LRESULT onInitDialog(UINT, WPARAM, LPARAM, BOOL&); - - LRESULT onOk(WORD, WORD, HWND, BOOL&); - LRESULT onCancel(WORD, WORD, HWND, BOOL &); - LRESULT onSelectProtocol(WORD, WORD, HWND, BOOL&); - LRESULT onSelectUser(WORD, WORD, HWND, BOOL &); - LRESULT onChooseSound(WORD, WORD, HWND , BOOL&); - LRESULT onResetSound(WORD, WORD, HWND , BOOL&); - LRESULT onTestPlay(WORD, WORD, HWND , BOOL&); - - void addProtocolItem(ProtocolTable::value_type & value); - - void setSoundLabelText(LPCTSTR text); -}; - -#endif diff --git a/!NotAdopted/XSoundNotify/SoundNotifyData.cpp b/!NotAdopted/XSoundNotify/SoundNotifyData.cpp deleted file mode 100644 index 1876db6ba0..0000000000 --- a/!NotAdopted/XSoundNotify/SoundNotifyData.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "SoundNotifyData.h" - -SoundNotifyData::SoundNotifyData() : _contact(0), _soundChanged(false) -{ - -} - -SoundNotifyData::SoundNotifyData(HANDLE contact, const ModuleString & module, const xsn_string & sound) : - _contact(contact), _soundPath(sound), _soundChanged(false) -{ -} - -void SoundNotifyData::setSound(const xsn_string & sound) -{ - _soundChanged = true; - _soundPath = sound; -} - -HANDLE SoundNotifyData::contact() const -{ - return _contact; -} - -const xsn_string & SoundNotifyData::soundPath() const -{ - return _soundPath; -} - -const ModuleString & SoundNotifyData::module() const -{ - return _module; -} - -bool SoundNotifyData::isSoundChanged() const -{ - return _soundChanged; -} diff --git a/!NotAdopted/XSoundNotify/SoundNotifyData.h b/!NotAdopted/XSoundNotify/SoundNotifyData.h deleted file mode 100644 index 18cb4844a4..0000000000 --- a/!NotAdopted/XSoundNotify/SoundNotifyData.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __XSN_DATA_H -#define __XSN_DATA_H - -#include -#include "xsn_types.h" -#include - -class SoundNotifyData -{ -public: - SoundNotifyData(); - SoundNotifyData(HANDLE contact, const ModuleString & module, const xsn_string & sound); - - void setSound(const xsn_string & sound); - - HANDLE contact() const; - const xsn_string & soundPath() const; - const ModuleString & module() const; - bool isSoundChanged() const; - -private: - HANDLE _contact; - ModuleString _module; - xsn_string _soundPath; - bool _soundChanged; -}; -typedef std::shared_ptr SoundNotifyDataPtr; - -typedef std::unordered_map UserDataTable; -typedef std::unordered_map ProtocolTable; -typedef std::unordered_map ModuleConvertTable; - -#endif diff --git a/!NotAdopted/XSoundNotify/SoundNotifyDataStorage.cpp b/!NotAdopted/XSoundNotify/SoundNotifyDataStorage.cpp deleted file mode 100644 index bd1b90df52..0000000000 --- a/!NotAdopted/XSoundNotify/SoundNotifyDataStorage.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "SoundNotifyDataStorage.h" -#include -#include -#include "xsn_utils.h" -//#include "DebugLogger.hpp" - -SoundNotifyDataStorage::SoundNotifyDataStorage(PLUGINLINK * pl) : pluginLink(pl) -{ - -} - -void SoundNotifyDataStorage::init() -{ - initModuleConvertTable(_moduleTable); - registerProtocols(); - - HANDLE contact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); - for(; contact; contact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)contact,0)) - { - try - { - addContact(contact); - } - catch (...) - { - // log - } - } -} - -void SoundNotifyDataStorage::commit() -{ - for (auto it = _protocolTable.begin(), end = _protocolTable.end(); it != end; ++it) - for (auto user = it->second.begin(), userEnd = it->second.end(); user != userEnd; ++user) - if (user->second->isSoundChanged()) - { - if (user->second->soundPath().empty()) - DBDeleteContactSetting(user->second->contact(), XSN_ModuleInfo::name(), XSN_ModuleInfo::soundSetting()); - else - DBWriteContactSettingTString(user->second->contact(), XSN_ModuleInfo::name(), XSN_ModuleInfo::soundSetting(), user->second->soundPath().c_str()); - } -} - -void SoundNotifyDataStorage::addContact(HANDLE contact) -{ - ModuleString module = getContactModule(contact); - ProtocolString proto = _moduleTable[module]; - xsn_string user = getContactId(contact, module, proto); - if (user.empty()) - return ; - - XSN_Variant sound; - DBGetContactSettingTString(contact, XSN_ModuleInfo::name(), XSN_ModuleInfo::soundSetting(), &sound); - _protocolTable[proto][user] = SoundNotifyDataPtr(new SoundNotifyData(contact, module, sound.toString())); -} - -xsn_string SoundNotifyDataStorage::getContactId(HANDLE contact, const ModuleString & module, const ProtocolString & proto) -{ - auto it = _registeredProtocols.find(proto); - if (it == _registeredProtocols.end()) - return xsn_string(); - return it->second(contact, module); -} - -ProtocolTable & SoundNotifyDataStorage::getData() -{ - return _protocolTable; -} - -void SoundNotifyDataStorage::registerProtocols() -{ - _registeredProtocols["ICQ"] = &getIcqContactId; - _registeredProtocols["JABBER"] = &getJabberContactId; -} diff --git a/!NotAdopted/XSoundNotify/SoundNotifyDataStorage.h b/!NotAdopted/XSoundNotify/SoundNotifyDataStorage.h deleted file mode 100644 index 7dbf03c494..0000000000 --- a/!NotAdopted/XSoundNotify/SoundNotifyDataStorage.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef _XSN_DATA_STORAGE -#define _XSN_DATA_STORAGE - -#include "SoundNotifyData.h" -#include -#include - -class SoundNotifyDataStorage -{ -public: - SoundNotifyDataStorage(PLUGINLINK * pl); - - void init(); - void commit(); - - ProtocolTable & getData(); - -protected: - void addContact(HANDLE contact); - xsn_string getContactId(HANDLE contact, const ModuleString & module, const ProtocolString & proto); - void registerProtocols(); - -private: - PLUGINLINK * pluginLink; - - ProtocolTable _protocolTable; - ModuleConvertTable _moduleTable; - - typedef boost::function getContactIdFunc; - typedef std::unordered_map RegisteredProtocols; - RegisteredProtocols _registeredProtocols; -}; - -#endif diff --git a/!NotAdopted/XSoundNotify/XSoundNotify.rc b/!NotAdopted/XSoundNotify/XSoundNotify.rc deleted file mode 100644 index ab42834a08..0000000000 Binary files a/!NotAdopted/XSoundNotify/XSoundNotify.rc and /dev/null differ diff --git a/!NotAdopted/XSoundNotify/resource.h b/!NotAdopted/XSoundNotify/resource.h deleted file mode 100644 index fcd39e7cf3..0000000000 Binary files a/!NotAdopted/XSoundNotify/resource.h and /dev/null differ diff --git a/!NotAdopted/XSoundNotify/testplug.vcxproj b/!NotAdopted/XSoundNotify/testplug.vcxproj deleted file mode 100644 index ebd0a0009f..0000000000 --- a/!NotAdopted/XSoundNotify/testplug.vcxproj +++ /dev/null @@ -1,167 +0,0 @@ -п»ї - - - - Debug - Win32 - - - Release - Win32 - - - - - - XSoundNotify - - - - DynamicLibrary - false - MultiByte - - - DynamicLibrary - false - Unicode - - - - - - - - - - - - - - - .\Release\ - .\Release\ - false - E:\Programming\libs\WTL\Include;$(IncludePath) - - - .\Debug\ - .\Debug\ - true - - - - MultiThreaded - OnlyExplicitInline - true - true - MaxSpeed - true - Level3 - e:\Programming\libs\boost_1_46_1\;../../include;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;TESTPLUG_EXPORTS;%(PreprocessorDefinitions) - .\Release\ - .\Release\testplug.pch - .\Release\ - .\Release\ - - - true - NDEBUG;%(PreprocessorDefinitions) - .\Release\testplug.tlb - true - Win32 - - - 0x0809 - NDEBUG;%(PreprocessorDefinitions) - - - true - .\Release\testplug.bsc - - - true - true - Console - release/xsoundnotify.dll - .\Release\testplug.lib - odbc32.lib;odbccp32.lib;winmm.lib;%(AdditionalDependencies) - e:\Programming\libs\wxWidgets-2.9.3\lib\vc_lib\;%(AdditionalLibraryDirectories) - - - - - MultiThreadedDebug - Default - false - Disabled - true - Level3 - true - EditAndContinue - e:\Programming\libs\wxWidgets-2.9.3\include\msvc\;e:\Programming\libs\wxWidgets-2.9.3\include\;../../include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;XSOUNDNOTIFY_EXPORTS;%(PreprocessorDefinitions) - .\Debug\ - .\Debug\testplug.pch - .\Debug\ - .\Debug\ - EnableFastChecks - - - true - _DEBUG;%(PreprocessorDefinitions) - .\Debug\testplug.tlb - true - Win32 - - - 0x0809 - _DEBUG;%(PreprocessorDefinitions) - - - true - .\Debug\testplug.bsc - - - true - true - true - Console - .\Debug\xsoundnotify.dll - .\Debug\xsoundnotify.lib - wxmsw29u_adv.lib;wxmsw29u_core.lib;wxbase29u.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;wxregexu.lib;wxexpat.lib;odbc32.lib;odbccp32.lib;winmm.lib;%(AdditionalDependencies) - - - e:\Programming\libs\wxWidgets-2.9.3\lib\vc_lib\;%(AdditionalLibraryDirectories) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/!NotAdopted/XSoundNotify/xsn_main.cpp b/!NotAdopted/XSoundNotify/xsn_main.cpp deleted file mode 100644 index ebcf029143..0000000000 --- a/!NotAdopted/XSoundNotify/xsn_main.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* -Miranda plugin template, originally by Richard Hughes -http://miranda-icq.sourceforge.net/ - -This file is placed in the public domain. Anybody is free to use or -modify it as they wish with no restriction. -There is no warranty. -*/ - -#include "SettingsDialog.h" - -#include -#include -#include -#include -#include -#include -#include -#include "xsn_utils.h" -//#include "DebugLogger.hpp" - -HINSTANCE hInst; -PLUGINLINK *pluginLink; -HANDLE AddEventHook; - -PLUGININFOEX pluginInfo = { - sizeof(PLUGININFOEX), // Размер стуктуры - "XSoundNotify", // Короткое имя плагинв - PLUGIN_MAKE_VERSION(1,0,0,0), // Версия плагина - "Provides extended options for sound notifications", // Описание плагина - "Roman Torsten", // Автор - "rs_torsten-public@yahoo.com", // Адресс автора - "© 2011 Copyright", // Копирайт - "https://plus.google.com/117081718640940130539", // Адресс сайта разработчика плагина - 0, - 0, - {0x8b86253, 0xec6e, 0x4d09, { 0xb7, 0xa9, 0x64, 0xac, 0xdf, 0x6, 0x27, 0xb8 }} //{08B86253-EC6E-4d09-B7A9-64ACDF0627B8} -}; - -extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) -{ - hInst = hinstDLL; - return TRUE; -} - -static int PluginMenuCommand(WPARAM wParam,LPARAM lParam) -{ - try - { - SoundNotifyDataStorage storage(pluginLink); - storage.init(); - SettingsDialog dlg(storage); - if (dlg.DoModal() == IDOK) - storage.commit(); - } - catch (...) - { - MessageBox(0, TEXT("Unknown error occured while configuring"), TEXT("XSoundNotify Error"), MB_OK | MB_ICONERROR); - } - - return 0; -} - -extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) -{ - return &pluginInfo; -} - -extern "C" __declspec(dllexport) const MUUID interfaces[] = {MIID_TESTPLUGIN, MIID_LAST}; -extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) -{ - return interfaces; -} - -INT processEvent(WPARAM wParam, LPARAM lParam) -{ - try - { - if (!isReceiveMessage(lParam)) - return 0; - - xsn_string sound = getContactSound((HANDLE)wParam); - if (!sound.empty()) - PlaySound(sound.c_str(), nullptr, SND_ASYNC | SND_FILENAME); - } - catch (std::exception & ) - { - // log - } - catch (...) - { - // log - } - - return 0; -} - -extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) -{ - CLISTMENUITEM mi; - - pluginLink=link; - CreateServiceFunction("XSoundNotify/MenuCommand", PluginMenuCommand); - ZeroMemory(&mi,sizeof(mi)); - mi.cbSize=sizeof(mi); - mi.position=-0x7FFFFFFF; - mi.flags=0; - mi.hIcon=LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); - mi.pszName=LPGEN("&XSoundNotify Plugin"); - mi.pszService="XSoundNotify/MenuCommand"; - CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi); - AddEventHook = HookEvent(ME_DB_EVENT_ADDED, processEvent); - - return 0; -} - -extern "C" int __declspec(dllexport) Unload(void) -{ - UnhookEvent(AddEventHook); - return 0; -} - diff --git a/!NotAdopted/XSoundNotify/xsn_types.cpp b/!NotAdopted/XSoundNotify/xsn_types.cpp deleted file mode 100644 index da0cc5b3f9..0000000000 --- a/!NotAdopted/XSoundNotify/xsn_types.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "xsn_types.h" - -XSN_Variant::XSN_Variant() -{ - ptszVal = nullptr; -} - -XSN_Variant::~XSN_Variant() -{ - if (ptszVal) - DBFreeVariant(this); -} - -xsn_string XSN_Variant::toString() const -{ - return ptszVal == nullptr ? xsn_string() : xsn_string(ptszVal); -} - -bool XSN_Variant::empty() const -{ - return ptszVal == nullptr; -} - -const char * XSN_ModuleInfo::name() -{ - return "XSoundNotify"; -} - -const char * XSN_ModuleInfo::soundSetting() -{ - return "XSNPlugin_sound"; -} diff --git a/!NotAdopted/XSoundNotify/xsn_types.h b/!NotAdopted/XSoundNotify/xsn_types.h deleted file mode 100644 index 43f4434fea..0000000000 --- a/!NotAdopted/XSoundNotify/xsn_types.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __XSN_TYPES -#define __XSN_TYPES - -#include -#include -#include -#include - -#ifndef UNICODE - typedef std::string xsn_string; -#else - typedef std::wstring xsn_string; -#endif - -typedef std::string ModuleString; -typedef std::string ProtocolString; - -struct XSN_Variant : DBVARIANT -{ - XSN_Variant(); - ~XSN_Variant(); - - xsn_string toString() const; - bool empty() const; -}; - -struct XSN_ModuleInfo -{ - static const char * name(); - static const char * soundSetting(); -}; - -#endif diff --git a/!NotAdopted/XSoundNotify/xsn_utils.cpp b/!NotAdopted/XSoundNotify/xsn_utils.cpp deleted file mode 100644 index d597776e8d..0000000000 --- a/!NotAdopted/XSoundNotify/xsn_utils.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "xsn_utils.h" -#include -#include - -void initModuleConvertTable(ModuleConvertTable & table) -{ - int number = 0; - // may be need to free PROTOACCOUNT, but did't found information about it - PROTOACCOUNT ** accounts; - ProtoEnumAccounts(&number, &accounts); - for (int i = 0; i < number; ++i) - table[ModuleString(accounts[i]->szModuleName)] = ProtocolString(accounts[i]->szProtoName); -} - -bool isReceiveMessage(LPARAM event) -{ - DBEVENTINFO info = { sizeof(info) }; - CallService(MS_DB_EVENT_GET, event, (LPARAM)&info); - // i don't understand why it works and how it works, but it works correctly - practice way (методом тыка) - // so, i think correct condition would be : eventType == EVENTTYPE_MESSAGE && info.flags & DBEF_READ, but it really isn't - return !(((info.eventType != EVENTTYPE_MESSAGE) && !(info.flags & DBEF_READ)) || (info.flags & DBEF_SENT)); -} - -xsn_string getContactSound(HANDLE contact) -{ - XSN_Variant sound; - DBGetContactSettingTString(contact, XSN_ModuleInfo::name(), XSN_ModuleInfo::soundSetting(), &sound); - return sound.toString(); -} - -ModuleString getContactModule(HANDLE contact) -{ - char * proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)contact, 0); - if (proto == nullptr) - throw std::runtime_error("MS_PROTO_GETCONTACTBASEPROTO failed"); - return ModuleString(proto); -} - -xsn_string getIcqContactId(HANDLE contact, const ModuleString & module) -{ - XSN_Variant nick; - DBGetContactSettingTString(contact, module.c_str(), "CustomNick", &nick); - if (nick.empty()) - DBGetContactSettingTString(contact, module.c_str(), "Nick", &nick); - DWORD uin = DBGetContactSettingDword(contact, module.c_str(), "UIN", 0); - xsn_string uinStr = boost::lexical_cast(uin); - if (nick.empty()) - return uinStr; - return nick.toString() + TEXT(" (") + uinStr + TEXT(")"); -} - -xsn_string getJabberContactId(HANDLE contact, const ModuleString & module) -{ - XSN_Variant jid, nick; - DBGetContactSettingTString(contact, module.c_str(), "jid", &jid); - DBGetContactSettingTString(contact, "CList", "MyHandle", &nick); - if (nick.empty()) - return jid.toString(); - return nick.toString() + TEXT(" (") + jid.toString() + TEXT(")"); -} diff --git a/!NotAdopted/XSoundNotify/xsn_utils.h b/!NotAdopted/XSoundNotify/xsn_utils.h deleted file mode 100644 index 66bdef2526..0000000000 --- a/!NotAdopted/XSoundNotify/xsn_utils.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _XSN_UTILS_H -#define _XSN_UTILS_H - -#include "xsn_types.h" -#include "SoundNotifyData.h" - -void initModuleConvertTable(ModuleConvertTable & table); - -bool isReceiveMessage(LPARAM event); - -xsn_string getContactSound(HANDLE contact); -ModuleString getContactModule(HANDLE contact); - -xsn_string getIcqContactId(HANDLE contact, const ModuleString & module); -xsn_string getJabberContactId(HANDLE contact, const ModuleString & module); - - -#endif diff --git a/plugins/!Deprecated/NewAwaySysMod/AggressiveOptimize.h b/plugins/!Deprecated/NewAwaySysMod/AggressiveOptimize.h new file mode 100644 index 0000000000..65cfa5b010 --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/AggressiveOptimize.h @@ -0,0 +1,169 @@ + +////////////////////////////// +// Version 1.40 +// October 22nd, 2002 - .NET (VC7, _MSC_VER=1300) support! +// Version 1.30 +// Nov 24th, 2000 +// Version 1.20 +// Jun 9th, 2000 +// Version 1.10 +// Jan 23rd, 2000 +// Version 1.00 +// May 20th, 1999 +// Todd C. Wilson, Fresh Ground Software +// (todd@nopcode.com) +// This header file will kick in settings for Visual C++ 5 and 6 that will (usually) +// result in smaller exe's. +// The "trick" is to tell the compiler to not pad out the function calls; this is done +// by not using the /O1 or /O2 option - if you do, you implicitly use /Gy, which pads +// out each and every function call. In one single 500k dll, I managed to cut out 120k +// by this alone! +// The other two "tricks" are telling the Linker to merge all data-type segments together +// in the exe file. The relocation, read-only (constants) data, and code section (.text) +// sections can almost always be merged. Each section merged can save 4k in exe space, +// since each section is padded out to 4k chunks. This is very noticeable with smaller +// exes, since you could have only 700 bytes of data, 300 bytes of code, 94 bytes of +// strings - padded out, this could be 12k of runtime, for 1094 bytes of stuff! For larger +// programs, this is less overall, but can save at least 4k. +// Note that if you're using MFC static or some other 3rd party libs, you may get poor +// results with merging the readonly (.rdata) section - the exe may grow larger. +// To use this feature, define _MERGE_DATA_ in your project or before this header is used. +// With Visual C++ 5, the program uses a file alignment of 512 bytes, which results +// in a small exe. Under VC6, the program instead uses 4k, which is the same as the +// section size. The reason (from what I understand) is that 4k is the chunk size of +// the virtual memory manager, and that WinAlign (an end-user tuning tool for Win98) +// will re-align the programs on this boundary. The problem with this is that all of +// Microsoft's system exes and dlls are *NOT* tuned like this, and using 4k causes serious +// exe bloat. This is very noticeable for smaller programs. +// The "trick" for this is to use the undocumented FILEALIGN linker parm to change the +// padding from 4k to 1/2k, which results in a much smaller exe - anywhere from 20%-75% +// depending on the size. Note that this is the same as using /OPT:NOWIN98, which *is* +// a previously documented switch, but was left out of the docs for some reason in VC6 and +// all of the current MSDN's - see KB:Q235956 for more information. +// Microsoft does say that using the 4k alignment will "speed up process loading", +// but I've been unable to notice a difference, even on my P180, with a very large (4meg) exe. +// Please note, however, that this will probably not change the size of the COMPRESSED +// file (either in a .zip file or in an install archive), since this 4k is all zeroes and +// gets compressed away. +// Also, the /ALIGN:4096 switch will "magically" do the same thing, even though this is the +// default setting for this switch. Apparently this sets the same values as the above two +// switches do. We do not use this in this header, since it smacks of a bug and not a feature. +// Thanks to Michael Geary for some additional tips! +// +// Notes about using this header in .NET +// First off, VC7 does not allow a lot of the linker command options in pragma's. There is no +// honest or good reason why Microsoft decided to make this change, it just doesn't. +// So that is why there are a lot of <1300 #if's in the header. +// If you want to take full advantage of the VC7 linker options, you will need to do it on a +// PER PROJECT BASIS; you can no longer use a global header file like this to make it better. +// Items I strongly suggest putting in all your VC7 project linker options command line settings: +// /ignore:4078 /RELEASE +// Compiler options: +// /GL (Whole Program Optimization) +// If you're making an .EXE and not a .DLL, consider adding in: +// /GA (Optimize for Windows Application) +// Some items to consider using in your VC7 projects (not VC6): +// Link-time Code Generation - whole code optimization. Put this in your exe/dll project link settings. +// /LTCG:NOSTATUS +// The classic no-padding and no-bloat compiler C/C++ switch: +// /opt:nowin98 +// +// (C++ command line options: /GL /opt:nowin98 and /GA for .exe files) +// (Link command line options: /ignore:4078 /RELEASE /LTCG:NOSTATUS) +// +// Now, notes on using these options in VC7 vs VC6. +// VC6 consistently, for me, produces smaller code from C++ the exact same sources, +// with or without this header. On average, VC6 produces 5% smaller binaries compared +// to VC7 compiling the exact same project, *without* this header. With this header, VC6 +// will make a 13k file, while VC7 will make a 64k one. VC7 is just bloaty, pure and +// simple - all that managed/unmanaged C++ runtimes, and the CLR stuff must be getting +// in the way of code generation. However, template support is better, so there. +// Both VC6 and VC7 show the same end kind of end result savings - larger binary output +// will shave about 2% off, where as smaller projects (support DLL's, cpl's, +// activex controls, ATL libs, etc) get the best result, since the padding is usually +// more than the actual usable code. But again, VC7 does not compile down as small as VC6. +// +// The argument can be made that doing this is a waste of time, since the "zero bytes" +// will be compressed out in a zip file or install archive. Not really - it doesn't matter +// if the data is a string of zeroes or ones or 85858585 - it will still take room (20 bytes +// in a zip file, 29 bytes if only *4* of them 4k bytes are not the same) and time to +// compress that data and decompress it. Also, 20k of zeros is NOT 20k on disk - it's the +// size of the cluster slop- for Fat32 systems, 20k can be 32k, NTFS could make it 24k if you're +// just 1 byte over (round up). Most end users do not have the dual P4 Xeon systems with +// two gigs of RDram and a Raid 0+1 of Western Digital 120meg Special Editions that all +// worthy developers have (all six of us), so they will need any space and LOADING TIME +// savings they will need; taking an extra 32k or more out of your end user's 64megs of +// ram on Windows 98 is Not a Good Thing. +// +// Now, as a ADDED BONUS at NO EXTRA COST TO YOU! Under VC6, using the /merge:.text=.data +// pragma will cause the output file to be un-disassembleable! (is that a word?) At least, +// with the normal tools - WinDisam, DumpBin, and the like will not work. Try it - use the +// header, compile release, and then use DUMPBIN /DISASM filename.exe - no code! +// Thanks to Gлzim Pani for discovering this gem - for a full writeup on +// this issue and the ramifactions of it, visit www.nopcode.com for the Aggressive Optimize +// article. + +#ifndef _AGGRESSIVEOPTIMIZE_H_ +#define _AGGRESSIVEOPTIMIZE_H_ + +#pragma warning(disable:4711) + +#ifdef NDEBUG +// /Og (global optimizations), /Os (favor small code), /Oy (no frame pointers) +#pragma optimize("gsy",on) + +#if (_MSC_VER<1300) + #pragma comment(linker,"/RELEASE") +#endif + +// Note that merging the .rdata section will result in LARGER exe's if you using +// MFC (esp. static link). If this is desirable, define _MERGE_RDATA_ in your project. +/* DEP prevents the plugin from running when section merging is used. Had to disable it. */ +/* +#ifdef _MERGE_RDATA_ +#pragma comment(linker,"/merge:.rdata=.data") +#endif // _MERGE_RDATA_ + +#pragma comment(linker,"/merge:.text=.data") +#if (_MSC_VER<1300) + // In VC7, this causes problems with the relocation and data tables, so best to not merge them + #pragma comment(linker,"/merge:.reloc=.data") +#endif +*/ + +// Merging sections with different attributes causes a linker warning, so +// turn off the warning. From Michael Geary. Undocumented, as usual! +#if (_MSC_VER<1300) + // In VC7, you will need to put this in your project settings + #pragma comment(linker,"/ignore:4078") +#endif + +// With Visual C++ 5, you already get the 512-byte alignment, so you will only need +// it for VC6, and maybe later. +#if _MSC_VER >= 1000 + +// Option #1: use /filealign +// Totally undocumented! And if you set it lower than 512 bytes, the program crashes. +// Either leave at 0x200 or 0x1000 +//#pragma comment(linker,"/FILEALIGN:0x200") + +// Option #2: use /opt:nowin98 +// See KB:Q235956 or the READMEVC.htm in your VC directory for info on this one. +// This is our currently preferred option, since it is fully documented and unlikely +// to break in service packs and updates. +#if (_MSC_VER<1300) + // In VC7, you will need to put this in your project settings + #pragma comment(linker,"/opt:nowin98") +#else + +// Option #3: use /align:4096 +// A side effect of using the default align value is that it turns on the above switch. +// Does nothing under Vc7 that /opt:nowin98 doesn't already give you +// #pragma comment(linker,"/ALIGN:512") +#endif + +#endif // _MSC_VER >= 1000 + +#endif // NDEBUG + +#endif // _AGGRESSIVEOPTIMIZE_H_ diff --git a/plugins/!Deprecated/NewAwaySysMod/AwayOpt.cpp b/plugins/!Deprecated/NewAwaySysMod/AwayOpt.cpp new file mode 100644 index 0000000000..d40fb85b18 --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/AwayOpt.cpp @@ -0,0 +1,1711 @@ +/* + New Away System - plugin for Miranda IM + Copyright (C) 2005-2007 Chervov Dmitry + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "Common.h" +#include "MsgTree.h" +#include "Properties.h" +#include "Path.h" +#include "m_button.h" +#include "m_clc.h" +#include "..\CommonLibs\Themes.h" +#include "..\CommonLibs\GroupCheckbox.h" +#include "..\CommonLibs\ThemedImageCheckbox.h" + +//NightFox +#include + +int g_Messages_RecentRootID, g_Messages_PredefinedRootID; +CIconList g_IconList; + + +void MySetPos(HWND hwndParent) +// Set window size and center its controls +{ + HWND hWndTab = FindWindowEx(GetParent(hwndParent), NULL, _T("SysTabControl32"), _T("")); + if (!hWndTab) + { + _ASSERT(0); + return; + } + RECT rcDlg; + GetClientRect(hWndTab, &rcDlg); + TabCtrl_AdjustRect(hWndTab, false, &rcDlg); + rcDlg.right -= rcDlg.left - 2; + rcDlg.bottom -= rcDlg.top; + rcDlg.top += 2; + if (hwndParent) + { + RECT OldSize; + GetClientRect(hwndParent, &OldSize); + MoveWindow(hwndParent, rcDlg.left, rcDlg.top, rcDlg.right, rcDlg.bottom, true); + int dx = (rcDlg.right - OldSize.right) >> 1; + int dy = (rcDlg.bottom - OldSize.bottom) >> 1; + HWND hCurWnd = GetWindow(hwndParent, GW_CHILD); + while (hCurWnd) + { + RECT CWOldPos; + GetWindowRect(hCurWnd, &CWOldPos); + POINT pt; + pt.x = CWOldPos.left; + pt.y = CWOldPos.top; + ScreenToClient(hwndParent, &pt); + SetWindowPos(hCurWnd, NULL, pt.x + dx, pt.y + dy, 0, 0, SWP_NOSIZE | SWP_NOZORDER); + hCurWnd = GetNextWindow(hCurWnd, GW_HWNDNEXT); + } + } +} + +// ================================================ Message options ================================================ + +COptPage g_MessagesOptPage(MOD_NAME, NULL); + +void EnableMessagesOptDlgControls(CMsgTree* MsgTree) +{ + int I; + int IsNotGroup = false; + int Selected = false; + CBaseTreeItem* TreeItem = MsgTree->GetSelection(); + if (TreeItem && !(TreeItem->Flags & TIF_ROOTITEM)) + { + IsNotGroup = !(TreeItem->Flags & TIF_GROUP); + Selected = true; + } + g_MessagesOptPage.Enable(IDC_MESSAGEDLG_DEL, Selected); + g_MessagesOptPage.Enable(IDC_MESSAGEDLG_MSGTITLE, Selected); + for (I = 0; I < g_MessagesOptPage.Items.GetSize(); I++) + { + if (g_MessagesOptPage.Items[I]->GetParam() == IDC_MESSAGEDLG_MSGTREE) + { + g_MessagesOptPage.Items[I]->Enable(IsNotGroup); + } + } + SendDlgItemMessage(g_MessagesOptPage.GetWnd(), IDC_MESSAGEDLG_MSGDATA, EM_SETREADONLY, !IsNotGroup, 0); + g_MessagesOptPage.MemToPage(true); +} + +static WNDPROC g_OrigDefStatusButtonMsgProc; + +static LRESULT CALLBACK DefStatusButtonSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + if (Msg == WM_LBUTTONUP && IsDlgButtonChecked(GetParent(hWnd), GetDlgCtrlID(hWnd))) + { + return 0; + } + return CallWindowProc(g_OrigDefStatusButtonMsgProc, hWnd, Msg, wParam, lParam); +} + + +INT_PTR CALLBACK MessagesOptDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static int ChangeLock = 0; + static CMsgTree* MsgTree = NULL; + static struct { + int DlgItem, Status, IconIndex; + } DefMsgDlgItems[] = { + IDC_MESSAGEDLG_DEF_ONL, ID_STATUS_ONLINE, ILI_PROTO_ONL, + IDC_MESSAGEDLG_DEF_AWAY, ID_STATUS_AWAY, ILI_PROTO_AWAY, + IDC_MESSAGEDLG_DEF_NA, ID_STATUS_NA, ILI_PROTO_NA, + IDC_MESSAGEDLG_DEF_OCC, ID_STATUS_OCCUPIED, ILI_PROTO_OCC, + IDC_MESSAGEDLG_DEF_DND, ID_STATUS_DND, ILI_PROTO_DND, + IDC_MESSAGEDLG_DEF_FFC, ID_STATUS_FREECHAT, ILI_PROTO_FFC, + IDC_MESSAGEDLG_DEF_INV, ID_STATUS_INVISIBLE, ILI_PROTO_INV, + IDC_MESSAGEDLG_DEF_OTP, ID_STATUS_ONTHEPHONE, ILI_PROTO_OTP, + IDC_MESSAGEDLG_DEF_OTL, ID_STATUS_OUTTOLUNCH, ILI_PROTO_OTL + }; + static struct { + int DlgItem, IconIndex; + TCHAR* Text; + } Buttons[] = { + IDC_MESSAGEDLG_NEWMSG, ILI_NEWMESSAGE, LPGENT("Create new message"), + IDC_MESSAGEDLG_NEWCAT, ILI_NEWCATEGORY, LPGENT("Create new category"), + IDC_MESSAGEDLG_DEL, ILI_DELETE, LPGENT("Delete"), + IDC_MESSAGEDLG_VARS, ILI_NOICON, LPGENT("Open Variables help dialog"), + }; + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + MySetPos(hwndDlg); + ChangeLock++; + g_MessagesOptPage.SetWnd(hwndDlg); + SendMessage(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTITLE), EM_LIMITTEXT, TREEITEMTITLE_MAXLEN, 0); + SendMessage(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGDATA), EM_LIMITTEXT, AWAY_MSGDATA_MAX, 0); + // init image buttons + int I; + for (I = 0; I < lengthof(Buttons); I++) + { + HWND hButton = GetDlgItem(hwndDlg, Buttons[I].DlgItem); + SendMessage(hButton, BUTTONADDTOOLTIP, (WPARAM)TranslateTS(Buttons[I].Text), BATF_TCHAR); + SendMessage(hButton, BUTTONSETASFLATBTN, TRUE, 0); + } + // now default status message buttons + for (I = 0; I < lengthof(DefMsgDlgItems); I++) + { + HWND hButton = GetDlgItem(hwndDlg, DefMsgDlgItems[I].DlgItem); + SendMessage(hButton, BUTTONADDTOOLTIP, CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, DefMsgDlgItems[I].Status, GSMDF_TCHAR), BATF_TCHAR); + SendMessage(hButton, BUTTONSETASPUSHBTN, 0, 0); + SendMessage(hButton, BUTTONSETASFLATBTN, TRUE, 0); + g_OrigDefStatusButtonMsgProc = (WNDPROC)SetWindowLongPtr(hButton, GWLP_WNDPROC, (LONG_PTR)DefStatusButtonSubclassProc); + } + SendMessage(hwndDlg, UM_ICONSCHANGED, 0, 0); + g_MessagesOptPage.DBToMemToPage(); + _ASSERT(!MsgTree); + MsgTree = new CMsgTree(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTREE)); + if (!MsgTree->SetSelection(MsgTree->GetDefMsg(ID_STATUS_AWAY), MTSS_BYID)) + { + MsgTree->SetSelection(g_Messages_PredefinedRootID, MTSS_BYID); + } + ChangeLock--; + return true; + } break; + case UM_ICONSCHANGED: + { + int I; + for (I = 0; I < lengthof(DefMsgDlgItems); I++) + { + SendDlgItemMessage(hwndDlg, DefMsgDlgItems[I].DlgItem, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[DefMsgDlgItems[I].IconIndex]); + } + for (I = 0; I < lengthof(Buttons); I++) + { + if (Buttons[I].IconIndex != ILI_NOICON) + { + SendDlgItemMessage(hwndDlg, Buttons[I].DlgItem, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[Buttons[I].IconIndex]); + } + } + my_variables_skin_helpbutton(hwndDlg, IDC_MESSAGEDLG_VARS); + } break; + case WM_NOTIFY: + { + switch (((NMHDR*)lParam)->code) + { + case PSN_APPLY: + { + HWND hTreeView = GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTREE); + HTREEITEM hSelectedItem = TreeView_GetSelection(hTreeView); + ChangeLock++; + TreeView_SelectItem(hTreeView, NULL); + TreeView_SelectItem(hTreeView, hSelectedItem); + ChangeLock--; + MsgTree->Save(); + return true; + } break; + } + if (((LPNMHDR)lParam)->idFrom == IDC_MESSAGEDLG_MSGTREE) + { + switch (((LPNMHDR)lParam)->code) + { + case MTN_SELCHANGED: + { + PNMMSGTREE pnm = (PNMMSGTREE)lParam; + int I; + if (pnm->ItemOld && !(pnm->ItemOld->Flags & (TIF_ROOTITEM | TIF_GROUP))) + { + TCString Msg; + GetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGDATA, Msg.GetBuffer(AWAY_MSGDATA_MAX), AWAY_MSGDATA_MAX); + Msg.ReleaseBuffer(); + if (((CTreeItem*)pnm->ItemOld)->User_Str1 != (const TCHAR*)Msg) + { + ((CTreeItem*)pnm->ItemOld)->User_Str1 = Msg; + MsgTree->SetModified(true); + } + } + if (pnm->ItemNew) + { + ChangeLock++; + if (!(pnm->ItemNew->Flags & TIF_ROOTITEM)) + { + SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGTITLE, pnm->ItemNew->Title); + SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGDATA, (pnm->ItemNew->Flags & TIF_GROUP) ? _T("") : ((CTreeItem*)pnm->ItemNew)->User_Str1); + } else + { + SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGTITLE, _T("")); + if (pnm->ItemNew->ID == g_Messages_RecentRootID) + { + SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGDATA, TranslateT("Your most recent status messages are placed in this category. It's not recommended to put your messages manually here, as they'll be replaced by your recent messages.")); + } else + { + _ASSERT(pnm->ItemNew->ID == g_Messages_PredefinedRootID); + SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGDATA, TranslateT("You can put your frequently used and favorite messages in this category.")); + } + } + for (I = 0; I < lengthof(DefMsgDlgItems); I++) + { + COptItem_Checkbox *Checkbox = (COptItem_Checkbox*)g_MessagesOptPage.Find(DefMsgDlgItems[I].DlgItem); + Checkbox->SetWndValue(g_MessagesOptPage.GetWnd(), MsgTree->GetDefMsg(DefMsgDlgItems[I].Status) == pnm->ItemNew->ID); + } + ChangeLock--; + } + EnableMessagesOptDlgControls(MsgTree); + return 0; + } break; + case MTN_DEFMSGCHANGED: + { + PNMMSGTREE pnm = (PNMMSGTREE)lParam; + if (!ChangeLock) + { + CBaseTreeItem* SelectedItem = MsgTree->GetSelection(); + _ASSERT(SelectedItem); + if ((pnm->ItemOld && pnm->ItemOld->ID == SelectedItem->ID) || (pnm->ItemNew && pnm->ItemNew->ID == SelectedItem->ID)) + { // SelectedItem contains the same info as one of ItemOld or ItemNew - so we'll just use SelectedItem and won't bother with identifying which of ItemOld or ItemNew is currently selected + int I; + for (I = 0; I < lengthof(DefMsgDlgItems); I++) + { + COptItem_Checkbox *Checkbox = (COptItem_Checkbox*)g_MessagesOptPage.Find(DefMsgDlgItems[I].DlgItem); + Checkbox->SetWndValue(g_MessagesOptPage.GetWnd(), MsgTree->GetDefMsg(DefMsgDlgItems[I].Status) == SelectedItem->ID); + } + } + } + if (!ChangeLock) + { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); + } + return 0; + } break; + case MTN_ITEMRENAMED: + { + PNMMSGTREE pnm = (PNMMSGTREE)lParam; + CBaseTreeItem* SelectedItem = MsgTree->GetSelection(); + _ASSERT(SelectedItem); + if (pnm->ItemNew->ID == SelectedItem->ID && !ChangeLock) + { + ChangeLock++; + SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGTITLE, pnm->ItemNew->Title); + ChangeLock--; + } + } // go through + case MTN_ENDDRAG: + case MTN_NEWCATEGORY: + case MTN_NEWMESSAGE: + case MTN_DELETEITEM: + case TVN_ITEMEXPANDED: + { + if (!ChangeLock) + { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); + } + return 0; + } break; + } + } + } break; + case WM_COMMAND: + { + switch (HIWORD(wParam)) + { + case BN_CLICKED: + { + switch (LOWORD(wParam)) + { + case IDC_MESSAGEDLG_DEF_ONL: + case IDC_MESSAGEDLG_DEF_AWAY: + case IDC_MESSAGEDLG_DEF_NA: + case IDC_MESSAGEDLG_DEF_OCC: + case IDC_MESSAGEDLG_DEF_DND: + case IDC_MESSAGEDLG_DEF_FFC: + case IDC_MESSAGEDLG_DEF_INV: + case IDC_MESSAGEDLG_DEF_OTP: + case IDC_MESSAGEDLG_DEF_OTL: + { + int I; + for (I = 0; I < lengthof(DefMsgDlgItems); I++) + { + if (LOWORD(wParam) == DefMsgDlgItems[I].DlgItem) + { + MsgTree->SetDefMsg(DefMsgDlgItems[I].Status, MsgTree->GetSelection()->ID); // PSM_CHANGED is sent here through MTN_DEFMSGCHANGED, so we don't need to send it once more + break; + } + } + } break; + case IDC_MESSAGEDLG_VARS: + { + my_variables_showhelp(hwndDlg, IDC_MESSAGEDLG_MSGDATA); + } break; + case IDC_MESSAGEDLG_DEL: + { + MsgTree->EnsureVisible(MsgTree->GetSelection()->hItem); + MsgTree->DeleteSelectedItem(); + } break; + case IDC_MESSAGEDLG_NEWCAT: + { + MsgTree->AddCategory(); + SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTITLE)); + } break; + case IDC_MESSAGEDLG_NEWMSG: + { + MsgTree->AddMessage(); + SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTITLE)); + } break; + } + } break; + case EN_CHANGE: + { + if (LOWORD(wParam) == IDC_MESSAGEDLG_MSGDATA || LOWORD(wParam) == IDC_MESSAGEDLG_MSGTITLE) + { + if (!ChangeLock) + { + if (LOWORD(wParam) == IDC_MESSAGEDLG_MSGTITLE) + { + CBaseTreeItem* TreeItem = MsgTree->GetSelection(); + if (TreeItem && !(TreeItem->Flags & TIF_ROOTITEM)) + { + GetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGTITLE, TreeItem->Title.GetBuffer(TREEITEMTITLE_MAXLEN), TREEITEMTITLE_MAXLEN); + TreeItem->Title.ReleaseBuffer(); + ChangeLock++; + MsgTree->UpdateItem(TreeItem->ID); + ChangeLock--; + } + } + MsgTree->SetModified(true); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); + } + } + } break; + } + } break; + case WM_DESTROY: + { + delete MsgTree; + MsgTree = NULL; + g_MessagesOptPage.SetWnd(NULL); + } break; + } + return 0; +} + +// ================================================ Main options ================================================ + + +COptPage g_MoreOptPage(MOD_NAME, NULL); + + +void EnableMoreOptDlgControls() +{ + g_MoreOptPage.Enable(IDC_MOREOPTDLG_PERSTATUSPERSONAL, g_MoreOptPage.GetWndValue(IDC_MOREOPTDLG_SAVEPERSONALMSGS)); + int Enabled = g_MoreOptPage.GetWndValue(IDC_MOREOPTDLG_RECENTMSGSCOUNT); + g_MoreOptPage.Enable(IDC_MOREOPTDLG_PERSTATUSMRM, Enabled); + g_MoreOptPage.Enable(IDC_MOREOPTDLG_USELASTMSG, Enabled); + g_MoreOptPage.Enable(IDC_MOREOPTDLG_USEDEFMSG, Enabled); + g_MoreOptPage.Enable(IDC_MOREOPTDLG_PERSTATUSPERSONAL, g_MoreOptPage.GetWndValue(IDC_MOREOPTDLG_SAVEPERSONALMSGS)); + g_MoreOptPage.Enable(IDC_MOREOPTDLG_UPDATEMSGSPERIOD, g_MoreOptPage.GetWndValue(IDC_MOREOPTDLG_UPDATEMSGS)); + InvalidateRect(GetDlgItem(g_MoreOptPage.GetWnd(), IDC_MOREOPTDLG_UPDATEMSGSPERIOD_SPIN), NULL, false); // update spin control + g_MoreOptPage.MemToPage(true); +} + + +INT_PTR CALLBACK MoreOptDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static int ChangeLock = 0; + static struct { + int DlgItem, Status, IconIndex; + } StatusButtons[] = { + IDC_MOREOPTDLG_DONTPOPDLG_ONL, ID_STATUS_ONLINE, ILI_PROTO_ONL, + IDC_MOREOPTDLG_DONTPOPDLG_AWAY, ID_STATUS_AWAY, ILI_PROTO_AWAY, + IDC_MOREOPTDLG_DONTPOPDLG_NA, ID_STATUS_NA, ILI_PROTO_NA, + IDC_MOREOPTDLG_DONTPOPDLG_OCC, ID_STATUS_OCCUPIED, ILI_PROTO_OCC, + IDC_MOREOPTDLG_DONTPOPDLG_DND, ID_STATUS_DND, ILI_PROTO_DND, + IDC_MOREOPTDLG_DONTPOPDLG_FFC, ID_STATUS_FREECHAT, ILI_PROTO_FFC, + IDC_MOREOPTDLG_DONTPOPDLG_INV, ID_STATUS_INVISIBLE, ILI_PROTO_INV, + IDC_MOREOPTDLG_DONTPOPDLG_OTP, ID_STATUS_ONTHEPHONE, ILI_PROTO_OTP, + IDC_MOREOPTDLG_DONTPOPDLG_OTL, ID_STATUS_OUTTOLUNCH, ILI_PROTO_OTL + }; + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + MySetPos(hwndDlg); + ChangeLock++; + g_MoreOptPage.SetWnd(hwndDlg); + SendDlgItemMessage(hwndDlg, IDC_MOREOPTDLG_WAITFORMSG, EM_LIMITTEXT, 4, 0); + SendDlgItemMessage(hwndDlg, IDC_MOREOPTDLG_RECENTMSGSCOUNT, EM_LIMITTEXT, 2, 0); + SendDlgItemMessage(hwndDlg, IDC_MOREOPTDLG_WAITFORMSG_SPIN, UDM_SETRANGE32, -1, 9999); + SendDlgItemMessage(hwndDlg, IDC_MOREOPTDLG_RECENTMSGSCOUNT_SPIN, UDM_SETRANGE32, 0, 99); + SendDlgItemMessage(hwndDlg, IDC_MOREOPTDLG_UPDATEMSGSPERIOD_SPIN, UDM_SETRANGE32, 30, 99999); + int I; + for (I = 0; I < lengthof(StatusButtons); I++) + { + HWND hButton = GetDlgItem(hwndDlg, StatusButtons[I].DlgItem); + SendMessage(hButton, BUTTONADDTOOLTIP, CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, StatusButtons[I].Status, GSMDF_TCHAR), BATF_TCHAR); + SendMessage(hButton, BUTTONSETASPUSHBTN, TRUE, 0); + SendMessage(hButton, BUTTONSETASFLATBTN, TRUE, 0); + } + SendMessage(hwndDlg, UM_ICONSCHANGED, 0, 0); + g_MoreOptPage.DBToMemToPage(); + EnableMoreOptDlgControls(); + ChangeLock--; + return true; + } break; + case UM_ICONSCHANGED: + { + int I; + for (I = 0; I < lengthof(StatusButtons); I++) + { + SendDlgItemMessage(hwndDlg, StatusButtons[I].DlgItem, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[StatusButtons[I].IconIndex]); + } + } break; + case WM_NOTIFY: + { + switch (((NMHDR*)lParam)->code) + { + case PSN_APPLY: + { + g_MoreOptPage.PageToMemToDB(); + InitUpdateMsgs(); + return true; + } break; + } + } break; + case WM_COMMAND: + { + switch (HIWORD(wParam)) + { + case BN_CLICKED: + { + switch (LOWORD(wParam)) + { + + case IDC_MOREOPTDLG_RESETPROTOMSGS: + case IDC_MOREOPTDLG_SAVEPERSONALMSGS: + case IDC_MOREOPTDLG_UPDATEMSGS: + { + EnableMoreOptDlgControls(); + } // go through + case IDC_MOREOPTDLG_PERSTATUSMRM: + case IDC_MOREOPTDLG_PERSTATUSPROTOMSGS: + case IDC_MOREOPTDLG_PERSTATUSPROTOSETTINGS: + case IDC_MOREOPTDLG_PERSTATUSPERSONAL: + case IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS: + case IDC_MOREOPTDLG_USEMENUITEM: + case IDC_MOREOPTDLG_MYNICKPERPROTO: + case IDC_MOREOPTDLG_USEDEFMSG: + case IDC_MOREOPTDLG_USELASTMSG: + case IDC_MOREOPTDLG_DONTPOPDLG_ONL: + case IDC_MOREOPTDLG_DONTPOPDLG_AWAY: + case IDC_MOREOPTDLG_DONTPOPDLG_NA: + case IDC_MOREOPTDLG_DONTPOPDLG_OCC: + case IDC_MOREOPTDLG_DONTPOPDLG_DND: + case IDC_MOREOPTDLG_DONTPOPDLG_FFC: + case IDC_MOREOPTDLG_DONTPOPDLG_INV: + case IDC_MOREOPTDLG_DONTPOPDLG_OTP: + case IDC_MOREOPTDLG_DONTPOPDLG_OTL: + { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); + return 0; + } break; + } + } break; + case EN_CHANGE: + { + if (!ChangeLock && g_MoreOptPage.GetWnd()) + { + if (LOWORD(wParam) == IDC_MOREOPTDLG_RECENTMSGSCOUNT) + { + EnableMoreOptDlgControls(); + } + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); + } + } break; + } + } break; + case WM_DESTROY: + { + g_MoreOptPage.SetWnd(NULL); + } break; + } + return 0; +} + + +// ================================================ Autoreply options ================================================ + + +COptPage g_AutoreplyOptPage(MOD_NAME, NULL); + + +void EnableAutoreplyOptDlgControls() +{ + int I; + g_AutoreplyOptPage.PageToMem(); + int Autoreply = g_AutoreplyOptPage.GetValue(IDC_REPLYDLG_ENABLEREPLY); + + for (I = 0; I < g_AutoreplyOptPage.Items.GetSize(); I++) + { + switch (g_AutoreplyOptPage.Items[I]->GetParam()) + { + case IDC_REPLYDLG_ENABLEREPLY: + { + g_AutoreplyOptPage.Items[I]->Enable(Autoreply); + } break; + case IDC_REPLYDLG_SENDCOUNT: + { + g_AutoreplyOptPage.Items[I]->Enable(Autoreply && g_AutoreplyOptPage.GetValue(IDC_REPLYDLG_SENDCOUNT) > 0); + } break; + } + } + g_AutoreplyOptPage.MemToPage(true); + InvalidateRect(GetDlgItem(g_AutoreplyOptPage.GetWnd(), IDC_REPLYDLG_SENDCOUNT_SPIN), NULL, 0); // update spin control +} + +INT_PTR CALLBACK AutoreplyOptDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static int ChangeLock = 0; + static HWND hWndTooltips; + static HFONT s_hDrawFont; + static struct { + int DlgItem, Status, IconIndex; + } StatusButtons[] = { + IDC_REPLYDLG_DISABLE_ONL, ID_STATUS_ONLINE, ILI_PROTO_ONL, + IDC_REPLYDLG_DISABLE_AWAY, ID_STATUS_AWAY, ILI_PROTO_AWAY, + IDC_REPLYDLG_DISABLE_NA, ID_STATUS_NA, ILI_PROTO_NA, + IDC_REPLYDLG_DISABLE_OCC, ID_STATUS_OCCUPIED, ILI_PROTO_OCC, + IDC_REPLYDLG_DISABLE_DND, ID_STATUS_DND, ILI_PROTO_DND, + IDC_REPLYDLG_DISABLE_FFC, ID_STATUS_FREECHAT, ILI_PROTO_FFC, + IDC_REPLYDLG_DISABLE_INV, ID_STATUS_INVISIBLE, ILI_PROTO_INV, + IDC_REPLYDLG_DISABLE_OTP, ID_STATUS_ONTHEPHONE, ILI_PROTO_OTP, + IDC_REPLYDLG_DISABLE_OTL, ID_STATUS_OUTTOLUNCH, ILI_PROTO_OTL + }; + switch (msg) + { + case WM_INITDIALOG: + { + ChangeLock++; + TranslateDialogDefault(hwndDlg); + MySetPos(hwndDlg); + g_AutoreplyOptPage.SetWnd(hwndDlg); + + LOGFONT logFont; + HFONT hFont = (HFONT)SendDlgItemMessage(hwndDlg, IDC_REPLYDLG_STATIC_DISABLEWHENSTATUS, WM_GETFONT, 0, 0); // try getting the font used by the control + if (!hFont) + { + hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); + } + GetObject(hFont, sizeof(logFont), &logFont); + logFont.lfWeight = FW_BOLD; + s_hDrawFont = CreateFontIndirect(&logFont); // recreate the font + SendDlgItemMessage(hwndDlg, IDC_REPLYDLG_STATIC_DISABLEWHENSTATUS, WM_SETFONT, (WPARAM)s_hDrawFont, true); + SendDlgItemMessage(hwndDlg, IDC_REPLYDLG_STATIC_FORMAT, WM_SETFONT, (WPARAM)s_hDrawFont, true); + + SendDlgItemMessage(hwndDlg, IDC_REPLYDLG_SENDCOUNT, EM_LIMITTEXT, 3, 0); + SendDlgItemMessage(hwndDlg, IDC_REPLYDLG_SENDCOUNT_SPIN, UDM_SETRANGE32, -1, 999); + + HWND hCombo = GetDlgItem(hwndDlg, IDC_REPLYDLG_ONLYIDLEREPLY_COMBO); + static struct { + TCHAR *Text; + int Meaning; + } IdleComboValues[] = { + LPGENT("Windows"), AUTOREPLY_IDLE_WINDOWS, + LPGENT("Miranda"), AUTOREPLY_IDLE_MIRANDA + }; + int I; + for (I = 0; I < lengthof(IdleComboValues); I++) + { + SendMessage(hCombo, CB_SETITEMDATA, SendMessage(hCombo, CB_ADDSTRING, 0, (LPARAM)TranslateTS(IdleComboValues[I].Text)), IdleComboValues[I].Meaning); + } + + for (I = 0; I < lengthof(StatusButtons); I++) + { + HWND hButton = GetDlgItem(hwndDlg, StatusButtons[I].DlgItem); + SendMessage(hButton, BUTTONADDTOOLTIP, CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, StatusButtons[I].Status, GSMDF_TCHAR), BATF_TCHAR); + SendMessage(hButton, BUTTONSETASPUSHBTN, TRUE, 0); + SendMessage(hButton, BUTTONSETASFLATBTN, TRUE, 0); + } + HWND hButton = GetDlgItem(hwndDlg, IDC_REPLYDLG_VARS); + SendMessage(hButton, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Open Variables help dialog"), BATF_TCHAR); + SendMessage(hButton, BUTTONSETASFLATBTN, TRUE, 0); + MakeThemedImageCheckbox(GetDlgItem(hwndDlg, IDC_MOREOPTDLG_EVNTMSG)); + MakeThemedImageCheckbox(GetDlgItem(hwndDlg, IDC_MOREOPTDLG_EVNTURL)); + MakeThemedImageCheckbox(GetDlgItem(hwndDlg, IDC_MOREOPTDLG_EVNTFILE)); + SendMessage(hwndDlg, UM_ICONSCHANGED, 0, 0); + + // init tooltips + struct { + int DlgItemID; + TCHAR* Text; + } Tooltips[] = { + IDC_REPLYDLG_RESETCOUNTERWHENSAMEICON, LPGENT("When this checkbox is ticked, NewAwaySys counts \"send times\" starting from the last status message change, even if status mode didn't change.\nWhen the checkbox isn't ticked, \"send times\" are counted from last status mode change (i.e. disabled state is more restrictive)."), + IDC_MOREOPTDLG_EVNTMSG, LPGENT("Message"), + IDC_MOREOPTDLG_EVNTURL, LPGENT("URL"), + IDC_MOREOPTDLG_EVNTFILE, LPGENT("File") + }; + TOOLINFO ti = {0}; + hWndTooltips = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, _T(""), WS_POPUP | TTS_NOPREFIX, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL); + ti.cbSize = sizeof(ti); + ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS; + ti.hwnd = hwndDlg; + for (I = 0; I < lengthof(Tooltips); I++) + { + ti.uId = (UINT)GetDlgItem(hwndDlg, Tooltips[I].DlgItemID); + ti.lpszText = TranslateTS(Tooltips[I].Text); + SendMessage(hWndTooltips, TTM_ADDTOOL, 0, (LPARAM)&ti); + } + SendMessage(hWndTooltips, TTM_SETMAXTIPWIDTH, 0, 500); + SendMessage(hWndTooltips, TTM_SETDELAYTIME, TTDT_AUTOPOP, 32767); // tooltip hide time; looks like 32 seconds is the maximum + + g_AutoreplyOptPage.DBToMemToPage(); + EnableAutoreplyOptDlgControls(); + ChangeLock--; + MakeGroupCheckbox(GetDlgItem(hwndDlg, IDC_REPLYDLG_ENABLEREPLY)); + return true; + } break; + case UM_ICONSCHANGED: + { + int I; + for (I = 0; I < lengthof(StatusButtons); I++) + { + SendDlgItemMessage(hwndDlg, StatusButtons[I].DlgItem, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[StatusButtons[I].IconIndex]); + } + my_variables_skin_helpbutton(hwndDlg, IDC_REPLYDLG_VARS); + SendDlgItemMessage(hwndDlg, IDC_MOREOPTDLG_EVNTMSG, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[ILI_EVENT_MESSAGE]); + SendDlgItemMessage(hwndDlg, IDC_MOREOPTDLG_EVNTURL, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[ILI_EVENT_URL]); + SendDlgItemMessage(hwndDlg, IDC_MOREOPTDLG_EVNTFILE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[ILI_EVENT_FILE]); + } break; + case WM_NOTIFY: + { + switch (((NMHDR*)lParam)->code) + { + case PSN_APPLY: + { + g_AutoreplyOptPage.PageToMemToDB(); + //UpdateSOEButtons(); + return true; + } break; + } + } break; + case WM_COMMAND: + { + switch (HIWORD(wParam)) + { + case BN_CLICKED: + { + switch (LOWORD(wParam)) + { + case IDC_REPLYDLG_ENABLEREPLY: + { + EnableAutoreplyOptDlgControls(); + } // go through + case IDC_REPLYDLG_DONTSENDTOICQ: + case IDC_REPLYDLG_DONTREPLYINVISIBLE: + case IDC_REPLYDLG_ONLYCLOSEDDLGREPLY: + case IDC_REPLYDLG_ONLYIDLEREPLY: + case IDC_REPLYDLG_RESETCOUNTERWHENSAMEICON: + case IDC_REPLYDLG_EVENTMSG: + case IDC_REPLYDLG_EVENTURL: + case IDC_REPLYDLG_EVENTFILE: + case IDC_REPLYDLG_LOGREPLY: + case IDC_REPLYDLG_DISABLE_ONL: + case IDC_REPLYDLG_DISABLE_AWAY: + case IDC_REPLYDLG_DISABLE_NA: + case IDC_REPLYDLG_DISABLE_OCC: + case IDC_REPLYDLG_DISABLE_DND: + case IDC_REPLYDLG_DISABLE_FFC: + case IDC_REPLYDLG_DISABLE_INV: + case IDC_REPLYDLG_DISABLE_OTP: + case IDC_REPLYDLG_DISABLE_OTL: + { + if (!ChangeLock) + { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); + } + } break; + case IDC_REPLYDLG_VARS: + { + my_variables_showhelp(hwndDlg, IDC_REPLYDLG_PREFIX); + } break; + } + } break; + case EN_CHANGE: + { + if ((LOWORD(wParam) == IDC_REPLYDLG_SENDCOUNT) || (LOWORD(wParam) == IDC_REPLYDLG_PREFIX)) + { + if (!ChangeLock && g_AutoreplyOptPage.GetWnd()) + { + if (LOWORD(wParam) == IDC_REPLYDLG_SENDCOUNT) + { + EnableAutoreplyOptDlgControls(); + } + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); + } + } + } break; + case CBN_SELCHANGE: + { + if (LOWORD(wParam) == IDC_REPLYDLG_ONLYIDLEREPLY_COMBO) + { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); + } + } break; + } + } break; + case WM_DESTROY: + { + g_AutoreplyOptPage.SetWnd(NULL); + if (s_hDrawFont) + { + DeleteObject(s_hDrawFont); + } + DestroyWindow(hWndTooltips); + } break; + } + return 0; +} +// ================================================ Modern options ============================================== + +INT_PTR CALLBACK MessagesModernOptDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static int ChangeLock = 0; + static CMsgTree* MsgTree = NULL; + static struct { + int DlgItem, Status, IconIndex; + } DefMsgDlgItems[] = { + IDC_MESSAGEDLG_DEF_ONL, ID_STATUS_ONLINE, ILI_PROTO_ONL, + IDC_MESSAGEDLG_DEF_AWAY, ID_STATUS_AWAY, ILI_PROTO_AWAY, + IDC_MESSAGEDLG_DEF_NA, ID_STATUS_NA, ILI_PROTO_NA, + IDC_MESSAGEDLG_DEF_OCC, ID_STATUS_OCCUPIED, ILI_PROTO_OCC, + IDC_MESSAGEDLG_DEF_DND, ID_STATUS_DND, ILI_PROTO_DND, + IDC_MESSAGEDLG_DEF_FFC, ID_STATUS_FREECHAT, ILI_PROTO_FFC, + IDC_MESSAGEDLG_DEF_INV, ID_STATUS_INVISIBLE, ILI_PROTO_INV, + IDC_MESSAGEDLG_DEF_OTP, ID_STATUS_ONTHEPHONE, ILI_PROTO_OTP, + IDC_MESSAGEDLG_DEF_OTL, ID_STATUS_OUTTOLUNCH, ILI_PROTO_OTL + }; + static struct { + int DlgItem, IconIndex; + TCHAR* Text; + } Buttons[] = { + IDC_MESSAGEDLG_NEWMSG, ILI_NEWMESSAGE, LPGENT("Create new message"), + IDC_MESSAGEDLG_NEWCAT, ILI_NEWCATEGORY, LPGENT("Create new category"), + IDC_MESSAGEDLG_DEL, ILI_DELETE, LPGENT("Delete"), + IDC_MESSAGEDLG_VARS, ILI_NOICON, LPGENT("Open Variables help dialog"), + }; + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + MySetPos(hwndDlg); + ChangeLock++; + g_MessagesOptPage.SetWnd(hwndDlg); + SendMessage(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTITLE), EM_LIMITTEXT, TREEITEMTITLE_MAXLEN, 0); + SendMessage(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGDATA), EM_LIMITTEXT, AWAY_MSGDATA_MAX, 0); + // init image buttons + int I; + for (I = 0; I < lengthof(Buttons); I++) + { + HWND hButton = GetDlgItem(hwndDlg, Buttons[I].DlgItem); + SendMessage(hButton, BUTTONADDTOOLTIP, (WPARAM)TranslateTS(Buttons[I].Text), BATF_TCHAR); + SendMessage(hButton, BUTTONSETASFLATBTN, TRUE, 0); + } + // now default status message buttons + for (I = 0; I < lengthof(DefMsgDlgItems); I++) + { + HWND hButton = GetDlgItem(hwndDlg, DefMsgDlgItems[I].DlgItem); + SendMessage(hButton, BUTTONADDTOOLTIP, CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, DefMsgDlgItems[I].Status, GSMDF_TCHAR), BATF_TCHAR); + SendMessage(hButton, BUTTONSETASPUSHBTN, TRUE, 0); + SendMessage(hButton, BUTTONSETASFLATBTN, TRUE, 0); + g_OrigDefStatusButtonMsgProc = (WNDPROC)SetWindowLongPtr(hButton, GWLP_WNDPROC, (LONG_PTR)DefStatusButtonSubclassProc); + } + SendMessage(hwndDlg, UM_ICONSCHANGED, 0, 0); + g_MessagesOptPage.DBToMemToPage(); + _ASSERT(!MsgTree); + MsgTree = new CMsgTree(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTREE)); + if (!MsgTree->SetSelection(MsgTree->GetDefMsg(ID_STATUS_AWAY), MTSS_BYID)) + { + MsgTree->SetSelection(g_Messages_PredefinedRootID, MTSS_BYID); + } + ChangeLock--; + //MakeGroupCheckbox(GetDlgItem(hwndDlg, IDC_REPLYDLG_ENABLEREPLY)); + return true; + } break; + case UM_ICONSCHANGED: + { + int I; + for (I = 0; I < lengthof(DefMsgDlgItems); I++) + { + SendDlgItemMessage(hwndDlg, DefMsgDlgItems[I].DlgItem, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[DefMsgDlgItems[I].IconIndex]); + } + for (I = 0; I < lengthof(Buttons); I++) + { + if (Buttons[I].IconIndex != ILI_NOICON) + { + SendDlgItemMessage(hwndDlg, Buttons[I].DlgItem, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[Buttons[I].IconIndex]); + } + } + my_variables_skin_helpbutton(hwndDlg, IDC_MESSAGEDLG_VARS); + } break; + case WM_NOTIFY: + { + switch (((NMHDR*)lParam)->code) + { + case PSN_APPLY: + { + HWND hTreeView = GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTREE); + HTREEITEM hSelectedItem = TreeView_GetSelection(hTreeView); + ChangeLock++; + TreeView_SelectItem(hTreeView, NULL); + TreeView_SelectItem(hTreeView, hSelectedItem); + ChangeLock--; + MsgTree->Save(); + return true; + } break; + } + if (((LPNMHDR)lParam)->idFrom == IDC_MESSAGEDLG_MSGTREE) + { + switch (((LPNMHDR)lParam)->code) + { + case MTN_SELCHANGED: + { + PNMMSGTREE pnm = (PNMMSGTREE)lParam; + int I; + if (pnm->ItemOld && !(pnm->ItemOld->Flags & (TIF_ROOTITEM | TIF_GROUP))) + { + TCString Msg; + GetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGDATA, Msg.GetBuffer(AWAY_MSGDATA_MAX), AWAY_MSGDATA_MAX); + Msg.ReleaseBuffer(); + if (((CTreeItem*)pnm->ItemOld)->User_Str1 != (const TCHAR*)Msg) + { + ((CTreeItem*)pnm->ItemOld)->User_Str1 = Msg; + MsgTree->SetModified(true); + } + } + if (pnm->ItemNew) + { + ChangeLock++; + if (!(pnm->ItemNew->Flags & TIF_ROOTITEM)) + { + SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGTITLE, pnm->ItemNew->Title); + SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGDATA, (pnm->ItemNew->Flags & TIF_GROUP) ? _T("") : ((CTreeItem*)pnm->ItemNew)->User_Str1); + } else + { + SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGTITLE, _T("")); + if (pnm->ItemNew->ID == g_Messages_RecentRootID) + { + SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGDATA, TranslateT("Your most recent status messages are placed in this category. It's not recommended to put your messages manually here, as they'll be replaced by your recent messages.")); + } else + { + _ASSERT(pnm->ItemNew->ID == g_Messages_PredefinedRootID); + SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGDATA, TranslateT("You can put your frequently used and favorite messages in this category.")); + } + } + for (I = 0; I < lengthof(DefMsgDlgItems); I++) + { + COptItem_Checkbox *Checkbox = (COptItem_Checkbox*)g_MessagesOptPage.Find(DefMsgDlgItems[I].DlgItem); + Checkbox->SetWndValue(g_MessagesOptPage.GetWnd(), MsgTree->GetDefMsg(DefMsgDlgItems[I].Status) == pnm->ItemNew->ID); + } + ChangeLock--; + } + EnableMessagesOptDlgControls(MsgTree); + return 0; + } break; + case MTN_DEFMSGCHANGED: + { + PNMMSGTREE pnm = (PNMMSGTREE)lParam; + if (!ChangeLock) + { + CBaseTreeItem* SelectedItem = MsgTree->GetSelection(); + _ASSERT(SelectedItem); + if ((pnm->ItemOld && pnm->ItemOld->ID == SelectedItem->ID) || (pnm->ItemNew && pnm->ItemNew->ID == SelectedItem->ID)) + { // SelectedItem contains the same info as one of ItemOld or ItemNew - so we'll just use SelectedItem and won't bother with identifying which of ItemOld or ItemNew is currently selected + int I; + for (I = 0; I < lengthof(DefMsgDlgItems); I++) + { + COptItem_Checkbox *Checkbox = (COptItem_Checkbox*)g_MessagesOptPage.Find(DefMsgDlgItems[I].DlgItem); + Checkbox->SetWndValue(g_MessagesOptPage.GetWnd(), MsgTree->GetDefMsg(DefMsgDlgItems[I].Status) == SelectedItem->ID); + } + } + } + if (!ChangeLock) + { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); + } + return 0; + } break; + case MTN_ITEMRENAMED: + { + PNMMSGTREE pnm = (PNMMSGTREE)lParam; + CBaseTreeItem* SelectedItem = MsgTree->GetSelection(); + _ASSERT(SelectedItem); + if (pnm->ItemNew->ID == SelectedItem->ID && !ChangeLock) + { + ChangeLock++; + SetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGTITLE, pnm->ItemNew->Title); + ChangeLock--; + } + } // go through + case MTN_ENDDRAG: + case MTN_NEWCATEGORY: + case MTN_NEWMESSAGE: + case MTN_DELETEITEM: + case TVN_ITEMEXPANDED: + { + if (!ChangeLock) + { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); + } + return 0; + } break; + } + } + } break; + case WM_COMMAND: + { + switch (HIWORD(wParam)) + { + case BN_CLICKED: + { + + + switch (LOWORD(wParam)) + { + + case IDC_MESSAGEDLG_DEF_ONL: + case IDC_MESSAGEDLG_DEF_AWAY: + case IDC_MESSAGEDLG_DEF_NA: + case IDC_MESSAGEDLG_DEF_OCC: + case IDC_MESSAGEDLG_DEF_DND: + case IDC_MESSAGEDLG_DEF_FFC: + case IDC_MESSAGEDLG_DEF_INV: + case IDC_MESSAGEDLG_DEF_OTP: + case IDC_MESSAGEDLG_DEF_OTL: + { + int I; + for (I = 0; I < lengthof(DefMsgDlgItems); I++) + { + if (LOWORD(wParam) == DefMsgDlgItems[I].DlgItem) + { + MsgTree->SetDefMsg(DefMsgDlgItems[I].Status, MsgTree->GetSelection()->ID); // PSM_CHANGED is sent here through MTN_DEFMSGCHANGED, so we don't need to send it once more + break; + } + } + } break; + case IDC_MESSAGEDLG_VARS: + { + my_variables_showhelp(hwndDlg, IDC_MESSAGEDLG_MSGDATA); + } break; + case IDC_MESSAGEDLG_DEL: + { + MsgTree->EnsureVisible(MsgTree->GetSelection()->hItem); + MsgTree->DeleteSelectedItem(); + } break; + case IDC_MESSAGEDLG_NEWCAT: + { + MsgTree->AddCategory(); + SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTITLE)); + } break; + case IDC_MESSAGEDLG_NEWMSG: + { + MsgTree->AddMessage(); + SetFocus(GetDlgItem(hwndDlg, IDC_MESSAGEDLG_MSGTITLE)); + } break; + + //NightFox: + case IDC_LNK_AUTOAWAY: + { + OPENOPTIONSDIALOG ood = {0}; + ood.cbSize = sizeof(ood); + ood.pszPage = "Status"; + ood.pszTab = "Autoreply"; + //CallService( MS_OPT_OPENOPTIONS, 0, (LPARAM)&ood ); + CallService( MS_OPT_OPENOPTIONSPAGE, 0, (LPARAM)&ood ); + break; + } + + } + + + } break; + case EN_CHANGE: + { + if (LOWORD(wParam) == IDC_MESSAGEDLG_MSGDATA || LOWORD(wParam) == IDC_MESSAGEDLG_MSGTITLE) + { + if (!ChangeLock) + { + if (LOWORD(wParam) == IDC_MESSAGEDLG_MSGTITLE) + { + CBaseTreeItem* TreeItem = MsgTree->GetSelection(); + if (TreeItem && !(TreeItem->Flags & TIF_ROOTITEM)) + { + GetDlgItemText(hwndDlg, IDC_MESSAGEDLG_MSGTITLE, TreeItem->Title.GetBuffer(TREEITEMTITLE_MAXLEN), TREEITEMTITLE_MAXLEN); + TreeItem->Title.ReleaseBuffer(); + ChangeLock++; + MsgTree->UpdateItem(TreeItem->ID); + ChangeLock--; + } + } + MsgTree->SetModified(true); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); + } + } + } break; + } + } break; + case WM_DESTROY: + { + delete MsgTree; + MsgTree = NULL; + g_MessagesOptPage.SetWnd(NULL); + } break; + } + return 0; +} + + + +// ================================================ Contact list ================================================ +// Based on the code from built-in Miranda ignore module + +#define UM_CONTACTSDLG_RESETLISTOPTIONS (WM_USER + 20) + +#define EXTRACOLUMNSCOUNT 3 +#define IGNORECOLUMN 2 +#define AUTOREPLYCOLUMN 1 +#define NOTIFYCOLUMN 0 + +#define EXTRAICON_DOT 0 +#define EXTRAICON_IGNORE 1 +#define EXTRAICON_AUTOREPLYON 2 +#define EXTRAICON_AUTOREPLYOFF 3 +//#define EXTRAICON_ENABLENOTIFY 4 +//#define EXTRAICON_DISABLENOTIFY 5 +//#define EXTRAICON_INDEFINITE 6 +#define EXTRAICON_INDEFINITE 4 + +#define VAL_INDEFINITE (-2) + +static WNDPROC g_OrigContactsProc; + +__inline int DBValueToIgnoreIcon(int Value) +{ + switch (Value) + { + case VAL_INDEFINITE: return EXTRAICON_INDEFINITE; + case 0: return EXTRAICON_DOT; + default: return EXTRAICON_IGNORE; + } +} + +__inline int IgnoreIconToDBValue(int Value) +{ + switch (Value) + { + case EXTRAICON_DOT: return 0; + case EXTRAICON_IGNORE: return 1; + default: return VAL_INDEFINITE; // EXTRAICON_INDEFINITE and 0xFF + } +} + +__inline int DBValueToOptReplyIcon(int Value) +{ + switch (Value) + { + case VAL_INDEFINITE: return EXTRAICON_INDEFINITE; + case VAL_USEDEFAULT: return EXTRAICON_DOT; + case 0: return EXTRAICON_AUTOREPLYOFF; + default: return EXTRAICON_AUTOREPLYON; + } +} + +__inline int ReplyIconToDBValue(int Value) +{ + switch (Value) + { + case EXTRAICON_DOT: return VAL_USEDEFAULT; + case EXTRAICON_AUTOREPLYOFF: return 0; + case EXTRAICON_AUTOREPLYON: return 1; + default: return VAL_INDEFINITE; // EXTRAICON_INDEFINITE and 0xFF + } +} +/* +__inline int DBValueToNotifyIcon(int Value) +{ + switch (Value) + { + case VAL_INDEFINITE: return EXTRAICON_INDEFINITE; + case VAL_USEDEFAULT: return EXTRAICON_DOT; + case 0: return EXTRAICON_DISABLENOTIFY; + default: return EXTRAICON_ENABLENOTIFY; + } +} + +__inline int NotifyIconToDBValue(int Value) +{ + switch (Value) + { + case EXTRAICON_DOT: return VAL_USEDEFAULT; + case EXTRAICON_DISABLENOTIFY: return 0; + case EXTRAICON_ENABLENOTIFY: return 1; + default: return VAL_INDEFINITE; // EXTRAICON_INDEFINITE and 0xFF + } +}*/ + +static void SetListGroupIcons(HWND hwndList, HANDLE hFirstItem, HANDLE hParentItem) +{ + int Icons[EXTRACOLUMNSCOUNT] = {0xFF, 0xFF, 0xFF}; + int I; + HANDLE hItem; + int FirstItemType = SendMessage(hwndList, CLM_GETITEMTYPE, (WPARAM)hFirstItem, 0); + hItem = (FirstItemType == CLCIT_GROUP) ? hFirstItem : (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hFirstItem); + while (hItem) + { + HANDLE hChildItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); + if (hChildItem) + { + SetListGroupIcons(hwndList, hChildItem, hItem); + } + for (I = 0; I < lengthof(Icons); I++) + { + int Icon = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(I, 0)); + if (Icons[I] == 0xFF) + { + Icons[I] = Icon; + } else if (Icon != 0xFF && Icons[I] != Icon) + { + Icons[I] = EXTRAICON_INDEFINITE; + } + } + hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hItem); + } + hItem = (FirstItemType == CLCIT_CONTACT) ? hFirstItem : (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hFirstItem); + while (hItem) + { + for (I = 0; I < lengthof(Icons); I++) + { + int Icon = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(I, 0)); + if (Icons[I] == 0xFF) + { + Icons[I] = Icon; + } else if (Icon != 0xFF && Icons[I] != Icon) + { + Icons[I] = EXTRAICON_INDEFINITE; + } + } + hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hItem); + } +// set icons + for (I = 0; I < lengthof(Icons); I++) + { + SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hParentItem, MAKELPARAM(I, Icons[I])); + } +} + +static void SetAllChildIcons(HWND hwndList, HANDLE hFirstItem, int iColumn, int iImage) +{ + int typeOfFirst, iOldIcon; + HANDLE hItem, hChildItem; + typeOfFirst = SendMessage(hwndList, CLM_GETITEMTYPE, (WPARAM)hFirstItem, 0); + //check groups + if (typeOfFirst == CLCIT_GROUP) + { + hItem = hFirstItem; + } else + { + hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hFirstItem); + } + while (hItem) + { + hChildItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); + if (hChildItem) + { + SetAllChildIcons(hwndList, hChildItem, iColumn, iImage); + } + hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hItem); + } + //check contacts + if (typeOfFirst == CLCIT_CONTACT) + { + hItem = hFirstItem; + } else + { + hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hFirstItem); + } + while (hItem) + { + iOldIcon = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, iColumn); + if (iOldIcon != 0xFF && iOldIcon != iImage) + { + SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(iColumn, iImage)); + } + hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hItem); + } +} + +static void SetIconsForColumn(HWND hwndList, HANDLE hItem, HANDLE hItemAll, int iColumn, int iImage) +{ + int itemType = SendMessage(hwndList, CLM_GETITEMTYPE, (WPARAM)hItem, 0); + switch (itemType) + { + case CLCIT_CONTACT: + { + int oldiImage = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, iColumn); + if (oldiImage != 0xFF && oldiImage != iImage) + { + SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(iColumn, iImage)); + } + } break; + case CLCIT_INFO: + { + if (hItem == hItemAll) + { + SetAllChildIcons(hwndList, hItem, iColumn, iImage); + } else + { +// _ASSERT(hItem == hItemUnknown); + SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(iColumn, iImage)); + } + } break; + case CLCIT_GROUP: + { + hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); + if (hItem) + { + SetAllChildIcons(hwndList, hItem, iColumn, iImage); + } + } break; + } +} + +static void SaveItemState(HWND hwndList, HANDLE hContact, HANDLE hItem) +{ // hContact == INVALID_HANDLE_VALUE means that hItem is hItemUnknown + int Ignore = IgnoreIconToDBValue(SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(IGNORECOLUMN, 0))); + int Reply = ReplyIconToDBValue(SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(AUTOREPLYCOLUMN, 0))); +// int Notify = NotifyIconToDBValue(SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(NOTIFYCOLUMN, 0))); + if (Ignore != VAL_INDEFINITE) + { + CContactSettings(ID_STATUS_ONLINE, hContact).Ignore = Ignore; + } + if (Reply != VAL_INDEFINITE) + { + CContactSettings(ID_STATUS_ONLINE, hContact).Autoreply = Reply; + } +/* if (Notify != VAL_INDEFINITE) + { + CContactSettings(ID_STATUS_ONLINE, hContact).PopupNotify = Notify; + }*/ + if (hContact != INVALID_HANDLE_VALUE && g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS)) + { + int iMode; + for (iMode = ID_STATUS_AWAY; iMode < ID_STATUS_OUTTOLUNCH; iMode++) + { + if (Ignore != VAL_INDEFINITE) + { + CContactSettings(iMode, hContact).Ignore = Ignore; + } + if (Reply != VAL_INDEFINITE) + { + CContactSettings(iMode, hContact).Autoreply = Reply; + } // Notify is not per-status, so we're not setting it here + } + } +} + +static void SetAllContactIcons(HWND hwndList, HANDLE hItemUnknown) +{ + HANDLE hContact, hItem; + char *szProto; +// set values for hItemUnknown first + SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItemUnknown, MAKELPARAM(IGNORECOLUMN, DBValueToIgnoreIcon(CContactSettings(ID_STATUS_ONLINE, INVALID_HANDLE_VALUE).Ignore))); + SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItemUnknown, MAKELPARAM(AUTOREPLYCOLUMN, DBValueToOptReplyIcon(CContactSettings(ID_STATUS_ONLINE, INVALID_HANDLE_VALUE).Autoreply))); +// SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItemUnknown, MAKELPARAM(NOTIFYCOLUMN, DBValueToNotifyIcon(CContactSettings(ID_STATUS_ONLINE, INVALID_HANDLE_VALUE).PopupNotify))); + + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + do + { + hItem = (HANDLE)SendMessage(hwndList, CLM_FINDCONTACT, (WPARAM)hContact, 0); + if (hItem)// && SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(IGNOREEVENT_MAX, 0)) == 0xFF) + { + szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + int Ignore = CContactSettings(ID_STATUS_ONLINE, hContact).Ignore; + int Reply = CContactSettings(ID_STATUS_ONLINE, hContact).Autoreply; +// int Notify = CContactSettings(ID_STATUS_ONLINE, hContact).PopupNotify; + if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS)) + { + int iMode; + for (iMode = ID_STATUS_AWAY; iMode < ID_STATUS_OUTTOLUNCH; iMode++) + { + if (CContactSettings(iMode, hContact).Ignore != Ignore) + { + Ignore = VAL_INDEFINITE; + } + if (CContactSettings(iMode, hContact).Autoreply != Reply) + { + Reply = VAL_INDEFINITE; + } // Notify is not per-status, so we're not checking it here + } + } + SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(IGNORECOLUMN, DBValueToIgnoreIcon(Ignore))); + SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(AUTOREPLYCOLUMN, DBValueToOptReplyIcon(Reply))); +// SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(NOTIFYCOLUMN, (szProto && IsAnICQProto(szProto)) ? DBValueToNotifyIcon(Notify) : 0xFF)); + } + } while (hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)); +} + +static LRESULT CALLBACK ContactsSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + switch (Msg) + { + case WM_LBUTTONDBLCLK: + { + DWORD hitFlags; + HANDLE hItem = (HANDLE)SendMessage(hWnd, CLM_HITTEST, (WPARAM)&hitFlags, lParam); + if (hItem && (hitFlags & CLCHT_ONITEMEXTRA)) + { + Msg = WM_LBUTTONDOWN; // may be considered as a hack, but it's needed to make clicking on extra icons more convenient + } + } break; + } + return CallWindowProc(g_OrigContactsProc, hWnd, Msg, wParam, lParam); +} + +INT_PTR CALLBACK ContactsOptDlg(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static HANDLE hItemAll, hItemUnknown; + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + MySetPos(hwndDlg); + HWND hwndList = GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST); + HIMAGELIST hIml; + hIml = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), (IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR8) | ILC_MASK, 5, 2); + ImageList_AddIcon(hIml, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_DOT))); + ImageList_AddIcon(hIml, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_IGNORE))); + ImageList_AddIcon(hIml, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SOE_ENABLED))); + ImageList_AddIcon(hIml, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SOE_DISABLED))); + //ImageList_AddIcon(hIml, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ENABLENOTIFY))); + //ImageList_AddIcon(hIml, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_DISABLENOTIFY))); + ImageList_AddIcon(hIml, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_INDEFINITE))); + SendMessage(hwndList, CLM_SETEXTRAIMAGELIST, 0, (LPARAM)hIml); + SendMessage(hwndDlg, UM_CONTACTSDLG_RESETLISTOPTIONS, 0, 0); + SendMessage(hwndList, CLM_SETEXTRACOLUMNS, EXTRACOLUMNSCOUNT, 0); + CLCINFOITEM cii={0}; + cii.cbSize = sizeof(cii); + cii.flags = CLCIIF_GROUPFONT; + cii.pszText = TranslateT("** All contacts **"); + hItemAll = (HANDLE)SendMessage(hwndList, CLM_ADDINFOITEM, 0, (LPARAM)&cii); + cii.pszText = TranslateT("** Not-on-list contacts **"); // == Unknown contacts + hItemUnknown = (HANDLE)SendMessage(hwndList, CLM_ADDINFOITEM, 0, (LPARAM)&cii); + HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + do + { + char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + if (szProto) + { + int Flag1 = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0); + if ((Flag1 & PF1_IM) != PF1_IM && !(Flag1 & PF1_INDIVMODEMSG)) + { // does contact's protocol supports message sending/receiving or individual status messages? + SendMessage(hwndList, CLM_DELETEITEM, SendMessage(hwndList, CLM_FINDCONTACT, (WPARAM)hContact, 0), 0); + } + } + } while (hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)); + SetAllContactIcons(hwndList, hItemUnknown); + SetListGroupIcons(hwndList, (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll); + g_OrigContactsProc = (WNDPROC)SetWindowLongPtr(hwndList, GWLP_WNDPROC, (LONG_PTR)ContactsSubclassProc); + } break; + case UM_CONTACTSDLG_RESETLISTOPTIONS: + { + HWND hwndList = GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST); + SendMessage(hwndList, CLM_SETBKBITMAP, 0, NULL); + SendMessage(hwndList, CLM_SETBKCOLOR, GetSysColor(COLOR_WINDOW), 0); + SendMessage(hwndList, CLM_SETGREYOUTFLAGS, 0, 0); + SendMessage(hwndList, CLM_SETLEFTMARGIN, 4, 0); + SendMessage(hwndList, CLM_SETINDENT, 10, 0); + SendMessage(hwndList, CLM_SETHIDEEMPTYGROUPS, 1, 0); + int I; + for (I = 0; I <= FONTID_MAX; I++) + { + SendMessage(hwndList, CLM_SETTEXTCOLOR, I, GetSysColor(COLOR_WINDOWTEXT)); + } + } break; + case WM_SETFOCUS: + { + SetFocus(GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST)); + } break; + case WM_NOTIFY: + { + switch (((LPNMHDR)lParam)->idFrom) + { + case IDC_CONTACTSDLG_LIST: + { + switch (((LPNMHDR)lParam)->code) + { + case CLN_NEWCONTACT: + case CLN_LISTREBUILT: + { + SetAllContactIcons(GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST), hItemUnknown); + } // fall through + case CLN_CONTACTMOVED: + { + SetListGroupIcons(GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST), (HANDLE)SendDlgItemMessage(hwndDlg, IDC_CONTACTSDLG_LIST, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll); + } break; + case CLN_OPTIONSCHANGED: + { + SendMessage(hwndDlg, UM_CONTACTSDLG_RESETLISTOPTIONS, 0, 0); + } break; + case NM_CLICK: + case NM_DBLCLK: + { + NMCLISTCONTROL *nm = (NMCLISTCONTROL*)lParam; + HWND hwndList = GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST); + HANDLE hItem; + DWORD hitFlags; + if (nm->iColumn == -1) + { + break; + } + hItem = (HANDLE)SendMessage(hwndList, CLM_HITTEST, (WPARAM)&hitFlags, MAKELPARAM(nm->pt.x, nm->pt.y)); + if (!hItem || !(hitFlags & CLCHT_ONITEMEXTRA)) + { + break; + } + int iImage = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(nm->iColumn, 0)); + switch (nm->iColumn) + { + case AUTOREPLYCOLUMN: + { + switch (iImage) + { + case EXTRAICON_DOT: iImage = EXTRAICON_AUTOREPLYOFF; break; + case EXTRAICON_AUTOREPLYOFF: iImage = EXTRAICON_AUTOREPLYON; break; + default: iImage = EXTRAICON_DOT; // EXTRAICON_AUTOREPLYON and EXTRAICON_INDEFINITE + } + } break; + case IGNORECOLUMN: + { + iImage = (iImage == EXTRAICON_DOT) ? EXTRAICON_IGNORE : EXTRAICON_DOT; + } break; + /*case NOTIFYCOLUMN: + { + switch (iImage) + { + case EXTRAICON_DOT: iImage = EXTRAICON_DISABLENOTIFY; break; + case EXTRAICON_DISABLENOTIFY: iImage = EXTRAICON_ENABLENOTIFY; break; + default: iImage = EXTRAICON_DOT; // EXTRAICON_ENABLENOTIFY and EXTRAICON_INDEFINITE + } + }*/ break; + } + SetIconsForColumn(hwndList, hItem, hItemAll, nm->iColumn, iImage); + SetListGroupIcons(hwndList, (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } break; + } + } break; + case 0: + { + switch (((LPNMHDR)lParam)->code) + { + case PSN_APPLY: + { + HANDLE hContact, hItem; + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + do + { + hItem = (HANDLE)SendDlgItemMessage(hwndDlg, IDC_CONTACTSDLG_LIST, CLM_FINDCONTACT, (WPARAM)hContact, 0); + if (hItem) + { + SaveItemState(GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST), hContact, hItem); + } + } while (hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)); +// SaveItemMask(GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST), NULL, hItemAll, "Default1"); // TODO: store All Contacts setting here too, - change global Notify and Autoreply settings? (& set the All Contacts icons to "?" initially if the global setting doesn't coincide with the setting calculated in the _current_ way); and also make sure that these settings will be refreshed in the other windows too + SaveItemState(GetDlgItem(hwndDlg, IDC_CONTACTSDLG_LIST), INVALID_HANDLE_VALUE, hItemUnknown); + return true; + } break; + } + } break; + } + } break; + case WM_DESTROY: + { + HIMAGELIST hIml = (HIMAGELIST)SendDlgItemMessage(hwndDlg, IDC_CONTACTSDLG_LIST, CLM_GETEXTRAIMAGELIST, 0, 0); + _ASSERT(hIml); + ImageList_Destroy(hIml); + } break; + } + return 0; +} + + +int OptsDlgInit(WPARAM wParam, LPARAM lParam) +{ + OPTIONSDIALOGPAGE optDi = {0}; + optDi.cbSize = sizeof(optDi); + optDi.position = 920000000; + optDi.hInstance = g_hInstance; + optDi.flags = ODPF_BOLDGROUPS; + + optDi.pszTitle = OPT_MAINGROUP; + optDi.pfnDlgProc = MessagesOptDlg; + optDi.pszTemplate = MAKEINTRESOURCEA(IDD_MESSAGES); + optDi.pszTab = LPGEN("Statuses messages"); + Options_AddPage(wParam, &optDi); + + optDi.pfnDlgProc = MoreOptDlg; + optDi.pszTemplate = MAKEINTRESOURCEA(IDD_MOREOPTDIALOG); + optDi.pszTab = LPGEN("Main options"); + Options_AddPage(wParam, &optDi); + + optDi.pfnDlgProc = AutoreplyOptDlg; + optDi.pszTemplate = MAKEINTRESOURCEA(IDD_AUTOREPLY); + optDi.pszTab = LPGEN("Autoreply"); + Options_AddPage(wParam, &optDi); + + optDi.pfnDlgProc = ContactsOptDlg; + optDi.pszTemplate = MAKEINTRESOURCEA(IDD_CONTACTSOPTDLG); + optDi.pszTab = LPGEN("Contacts"); + Options_AddPage(wParam, &optDi); + return 0; +} + + +COptPage g_SetAwayMsgPage(MOD_NAME, NULL); +COptPage g_MsgTreePage(MOD_NAME, NULL); + +void InitOptions() +{ + InitThemes(); + g_MessagesOptPage.Items.AddElem(new COptItem_Generic(IDC_MESSAGEDLG_VARS, IDC_MESSAGEDLG_MSGTREE)); + g_MessagesOptPage.Items.AddElem(new COptItem_Generic(IDC_MESSAGEDLG_DEL)); + g_MessagesOptPage.Items.AddElem(new COptItem_Generic(IDC_MESSAGEDLG_MSGTITLE)); + g_MessagesOptPage.Items.AddElem(new COptItem_Generic(IDC_MESSAGEDLG_MSGDATA)); + g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_ONL, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); + g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_AWAY, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); + g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_NA, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); + g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_OCC, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); + g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_DND, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); + g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_FFC, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); + g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_INV, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); + g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_OTP, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); + g_MessagesOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MESSAGEDLG_DEF_OTL, NULL, DBVT_BYTE, 0, 0, IDC_MESSAGEDLG_MSGTREE)); + TreeItemArray DefMsgTree; + int ParentID1; + int ID = 0; + TreeRootItemArray RootItems; + RootItems.AddElem(CTreeRootItem(TranslateT("Predefined messages"), g_Messages_PredefinedRootID = ID++, TIF_EXPANDED)); + RootItems.AddElem(CTreeRootItem(TranslateT("Recent messages"), g_Messages_RecentRootID = ID++, TIF_EXPANDED)); + DefMsgTree.AddElem(CTreeItem(TranslateT("Gone fragging"), g_Messages_PredefinedRootID, ID++, 0, TranslateTS(_T("Been fragging since %") _T(VAR_AWAYSINCE_TIME) _T("%, I'll msg you later when the adrenaline wears off.")))); + DefMsgTree.AddElem(CTreeItem(TranslateT("Creepy"), g_Messages_PredefinedRootID, ID++, 0, TranslateT("Your master, %nas_mynick%, has been %nas_statdesc% since the day that is only known as ?nas_awaysince_date(dddd)... When he gets back, I'll tell him you dropped by..."))); + DefMsgTree.AddElem(CTreeItem(TranslateT("Default messages"), g_Messages_PredefinedRootID, ParentID1 = ID++, TIF_GROUP | TIF_EXPANDED)); + g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_ONL, StatusToDBSetting(ID_STATUS_ONLINE, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); + DefMsgTree.AddElem(CTreeItem(TranslateT("Online"), ParentID1, ID++, 0, TranslateT("Yep, I'm here."))); + g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_AWAY, StatusToDBSetting(ID_STATUS_AWAY, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); + DefMsgTree.AddElem(CTreeItem(TranslateT("Away"), ParentID1, ID++, 0, TranslateT("Been gone since %nas_awaysince_time%, will be back later."))); + g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_NA, StatusToDBSetting(ID_STATUS_NA, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); + DefMsgTree.AddElem(CTreeItem(TranslateT("NA"), ParentID1, ID++, 0, TranslateT("Give it up, I'm not in!"))); + g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_OCC, StatusToDBSetting(ID_STATUS_OCCUPIED, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); + DefMsgTree.AddElem(CTreeItem(TranslateT("Occupied"), ParentID1, ID++, 0, TranslateT("Not right now."))); + g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_DND, StatusToDBSetting(ID_STATUS_DND, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); + DefMsgTree.AddElem(CTreeItem(TranslateT("DND"), ParentID1, ID++, 0, TranslateT("Give a guy some peace, would ya?"))); + g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_FFC, StatusToDBSetting(ID_STATUS_FREECHAT, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); + DefMsgTree.AddElem(CTreeItem(TranslateT("Free for chat"), ParentID1, ID++, 0, TranslateT("I'm a chatbot!"))); + g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_INV, StatusToDBSetting(ID_STATUS_INVISIBLE, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); + DefMsgTree.AddElem(CTreeItem(TranslateT("Invisible"), ParentID1, ID++, 0, TranslateT("I'm hiding from the mafia."))); + g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_OTP, StatusToDBSetting(ID_STATUS_ONTHEPHONE, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); + DefMsgTree.AddElem(CTreeItem(TranslateT("On the phone"), ParentID1, ID++, 0, TranslateT("I've been on the phone since %nas_awaysince_time%, give me a sec!"))); + g_MsgTreePage.Items.AddElem(new COptItem_IntDBSetting(IDS_MESSAGEDLG_DEF_OTL, StatusToDBSetting(ID_STATUS_OUTTOLUNCH, MESSAGES_DB_MSGTREEDEF), DBVT_WORD, false, ID)); + DefMsgTree.AddElem(CTreeItem(TranslateT("Out to lunch"), ParentID1, ID++, 0, TranslateT("Been having ?ifgreater(?ctime(H),2,?ifgreater(?ctime(H),10,?ifgreater(?ctime(H),16,supper,dinner),breakfast),supper) since %nas_awaysince_time%."))); + g_MsgTreePage.Items.AddElem(new COptItem_TreeCtrl(IDV_MSGTREE, "MsgTree", DefMsgTree, RootItems, 0, "Text")); + + g_SetAwayMsgPage.Items.AddElem(new COptItem_BitDBSetting(IDS_SAWAYMSG_SHOWMSGTREE, "SAMDlgFlags", DBVT_BYTE, DF_SAM_DEFDLGFLAGS, DF_SAM_SHOWMSGTREE)); + g_SetAwayMsgPage.Items.AddElem(new COptItem_BitDBSetting(IDS_SAWAYMSG_SHOWCONTACTTREE, "SAMDlgFlags", DBVT_BYTE, DF_SAM_DEFDLGFLAGS, DF_SAM_SHOWCONTACTTREE)); + g_SetAwayMsgPage.Items.AddElem(new COptItem_BitDBSetting(IDS_SAWAYMSG_AUTOSAVEDLGSETTINGS, "AutoSaveDlgSettings", DBVT_BYTE, 1)); + g_SetAwayMsgPage.Items.AddElem(new COptItem_BitDBSetting(IDS_SAWAYMSG_DISABLEVARIABLES, "DisableVariables", DBVT_BYTE, 0)); + + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_PERSTATUSMRM, "PerStatusMRM", DBVT_BYTE, 0)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_RESETPROTOMSGS, "ResetProtoMsgs", DBVT_BYTE, 1)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_PERSTATUSPROTOMSGS, "PerStatusProtoMsgs", DBVT_BYTE, 0)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_PERSTATUSPROTOSETTINGS, "PerStatusProtoSettings", DBVT_BYTE, 0)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_SAVEPERSONALMSGS, "SavePersonalMsgs", DBVT_BYTE, 1)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_PERSTATUSPERSONAL, "PerStatusPersonal", DBVT_BYTE, 0)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS, "PerStatusPersonalSettings", DBVT_BYTE, 0)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_USEMENUITEM, "UseMenuItem", DBVT_BYTE, 0)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_MYNICKPERPROTO, "MyNickPerProto", DBVT_BYTE, 1)); + g_MoreOptPage.Items.AddElem(new COptItem_IntEdit(IDC_MOREOPTDLG_WAITFORMSG, "WaitForMsg", DBVT_WORD, TRUE, 5)); + g_MoreOptPage.Items.AddElem(new COptItem_IntEdit(IDC_MOREOPTDLG_RECENTMSGSCOUNT, "MRMCount", DBVT_WORD, TRUE, 5)); + g_MoreOptPage.Items.AddElem(new COptItem_Radiobutton(IDC_MOREOPTDLG_USEDEFMSG, "UseByDefault", DBVT_BYTE, MOREOPTDLG_DEF_USEBYDEFAULT, 0)); + g_MoreOptPage.Items.AddElem(new COptItem_Radiobutton(IDC_MOREOPTDLG_USELASTMSG, "UseByDefault", DBVT_BYTE, MOREOPTDLG_DEF_USEBYDEFAULT, 1)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_UPDATEMSGS, "UpdateMsgs", DBVT_BYTE, 0)); + g_MoreOptPage.Items.AddElem(new COptItem_IntEdit(IDC_MOREOPTDLG_UPDATEMSGSPERIOD, "UpdateMsgsPeriod", DBVT_WORD, FALSE, 300)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_ONL, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_ONL)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_AWAY, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_AWAY)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_NA, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_NA)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_OCC, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_OCC)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_DND, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_DND)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_FFC, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_FFC)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_INV, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_INV)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_OTP, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_OTP)); + g_MoreOptPage.Items.AddElem(new COptItem_Checkbox(IDC_MOREOPTDLG_DONTPOPDLG_OTL, "DontPopDlg", DBVT_WORD, MOREOPTDLG_DEF_DONTPOPDLG, SF_OTL)); + + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_ENABLEREPLY, DB_ENABLEREPLY, DBVT_BYTE, AUTOREPLY_DEF_REPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Generic(IDC_REPLYDLG_STATIC_ONEVENT, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_EVENTMSG, "ReplyOnEvent", DBVT_BYTE, AUTOREPLY_DEF_REPLYONEVENT, EF_MSG, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_EVENTURL, "ReplyOnEvent", DBVT_BYTE, AUTOREPLY_DEF_REPLYONEVENT, EF_URL, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_EVENTFILE, "ReplyOnEvent", DBVT_BYTE, AUTOREPLY_DEF_REPLYONEVENT, EF_FILE, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DONTSENDTOICQ, "DontSendToICQ", DBVT_BYTE, 0, 0, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DONTREPLYINVISIBLE, "DontReplyInvisible", DBVT_BYTE, 1, 0, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_LOGREPLY, "LogReply", DBVT_BYTE, 1, 0, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_ONLYIDLEREPLY, "OnlyIdleReply", DBVT_BYTE, 0, 0, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_ONLYCLOSEDDLGREPLY, "OnlyClosedDlgReply", DBVT_BYTE, 1, 0, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Generic(IDC_REPLYDLG_STATIC_SEND, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_IntEdit(IDC_REPLYDLG_SENDCOUNT, "ReplyCount", DBVT_WORD, TRUE, -1, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Generic(IDC_REPLYDLG_STATIC_TIMES, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_RESETCOUNTERWHENSAMEICON, "ResetReplyCounterWhenSameIcon", DBVT_BYTE, 1, 0, IDC_REPLYDLG_SENDCOUNT)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Generic(IDC_REPLYDLG_STATIC_DISABLEWHENSTATUS, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_ONL, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_ONL, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_AWAY, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_AWAY, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_NA, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_NA, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_OCC, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_OCC, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_DND, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_DND, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_FFC, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_FFC, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_INV, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_INV, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_OTP, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_OTP, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Checkbox(IDC_REPLYDLG_DISABLE_OTL, "DisableReply", DBVT_WORD, AUTOREPLY_DEF_DISABLEREPLY, SF_OTL, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Generic(IDC_REPLYDLG_STATIC_FORMAT, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Edit(IDC_REPLYDLG_PREFIX, "ReplyPrefix", AWAY_MSGDATA_MAX, AUTOREPLY_DEF_PREFIX, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Generic(IDC_REPLYDLG_VARS, IDC_REPLYDLG_ENABLEREPLY)); + g_AutoreplyOptPage.Items.AddElem(new COptItem_Generic(IDC_REPLYDLG_STATIC_EXTRATEXT, IDC_REPLYDLG_ENABLEREPLY)); +} + +//NightFox +int ModernOptInitialise(WPARAM wParam, LPARAM lParam) +{ + static int iBoldControls[] = + { + IDC_TXT_TITLE1, + IDC_TXT_TITLE2, + IDC_TXT_TITLE3, + MODERNOPT_CTRL_LAST + }; + + MODERNOPTOBJECT obj = {0}; + + obj.cbSize = sizeof(obj); + obj.dwFlags = MODEROPT_FLG_TCHAR|MODEROPT_FLG_NORESIZE; + obj.hInstance = g_hInstance; + obj.iSection = MODERNOPT_PAGE_STATUS; + obj.iType = MODERNOPT_TYPE_SECTIONPAGE; + obj.iBoldControls = iBoldControls; +// obj.lpzClassicGroup = NULL; + obj.lpzClassicPage = "Status"; + obj.lpzClassicTab = "Main options"; +// obj.lpzHelpUrl = "http://wiki.miranda-im.org/"; + + obj.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_MESSAGES); + obj.pfnDlgProc = MessagesModernOptDlg; + CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); + return 0; +} \ No newline at end of file diff --git a/plugins/!Deprecated/NewAwaySysMod/AwaySys.cpp b/plugins/!Deprecated/NewAwaySysMod/AwaySys.cpp new file mode 100644 index 0000000000..d573009ede --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/AwaySys.cpp @@ -0,0 +1,1025 @@ +/* + New Away System - plugin for Miranda IM + Copyright (c) 2005-2007 Chervov Dmitry + Copyright (c) 2004-2005 Iksaif Entertainment + Copyright (c) 2002-2003 Goblineye Entertainment + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + Thanx to Faith Healer for icons and help, Unregistered for his plugins (variables, AAA :p), + mistag for GamerStatus, BigMuscle for his code to use AAA + Thanx to Tornado, orignal developer of AwaySys. + Please note that some code from the Miranda's original away module (SRAway) is used around + AwaySys. i tried to mention it wherever possible, but i might have forgotten a few. Kudos to Miranda's authors. + The Read-Away-Msg part was practically copied from Miranda, not proud of it, but since i really can't see how can i make it better, there + was no point in rewriting it all. +*/ + +#include "Common.h" +#include "m_genmenu.h" +#include "m_idle.h" +#include "m_statusplugins.h" +#include "m_NewAwaySys.h" +#include "m_ContactSettings.h" +#include "MsgTree.h" +#include "ContactList.h" +#include "Properties.h" +#include "Path.h" +#include "Services.h" +#include "VersionNo.h" + +//NightFox +#include +#include // needed for MSVC 7 msvcr7*.dll patch + +HINSTANCE g_hInstance; + +int hLangpack = 0; +LIST hHooks(5), hServices(5); +HANDLE g_hContactMenuItem = NULL, g_hReadStatMenuItem = NULL, /*g_hTopToolbarbutton = NULL, */g_hToggleSOEMenuItem = NULL, g_hToggleSOEContactMenuItem = NULL, g_hAutoreplyOnContactMenuItem = NULL, g_hAutoreplyOffContactMenuItem = NULL, g_hAutoreplyUseDefaultContactMenuItem = NULL; +bool g_fNoProcessing = false; // tells the status change proc not to do anything +int g_bIsIdle = false; +HANDLE hMainThread; +int g_CSProtoCount = 0; // CommonStatus - StartupStatus and AdvancedAutoAway +VAR_PARSE_DATA VarParseData; +INT_PTR (*g_OldCallService)(const char *, WPARAM, LPARAM) = NULL; + +static struct +{ + int Status, DisableReplyCtlID, DontShowDialogCtlID; +} StatusModeList[] = { + ID_STATUS_ONLINE, IDC_REPLYDLG_DISABLE_ONL, IDC_MOREOPTDLG_DONTPOPDLG_ONL, + ID_STATUS_AWAY, IDC_REPLYDLG_DISABLE_AWAY, IDC_MOREOPTDLG_DONTPOPDLG_AWAY, + ID_STATUS_NA, IDC_REPLYDLG_DISABLE_NA, IDC_MOREOPTDLG_DONTPOPDLG_NA, + ID_STATUS_OCCUPIED, IDC_REPLYDLG_DISABLE_OCC, IDC_MOREOPTDLG_DONTPOPDLG_OCC, + ID_STATUS_DND, IDC_REPLYDLG_DISABLE_DND, IDC_MOREOPTDLG_DONTPOPDLG_DND, + ID_STATUS_FREECHAT, IDC_REPLYDLG_DISABLE_FFC, IDC_MOREOPTDLG_DONTPOPDLG_FFC, + ID_STATUS_INVISIBLE, IDC_REPLYDLG_DISABLE_INV, IDC_MOREOPTDLG_DONTPOPDLG_INV, + ID_STATUS_ONTHEPHONE, IDC_REPLYDLG_DISABLE_OTP, IDC_MOREOPTDLG_DONTPOPDLG_OTP, + ID_STATUS_OUTTOLUNCH, IDC_REPLYDLG_DISABLE_OTL, IDC_MOREOPTDLG_DONTPOPDLG_OTL +}; + +// took this nice idea from MetaContacts plugin ;) +// my_make_version is required to break up #define PRODUCTVER from VersionNo.h +DWORD my_make_version(const int a, const int b, const int c, const int d) +{ + return PLUGIN_MAKE_VERSION(a, b, c, d); +} + +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), + "New Away System Mod", + my_make_version(PRODUCTVER), // see VersionNo.h + "New Away System Mod plugin for Miranda IM.", + "NightFox; Deathdemon; XF007; Goblineye Entertainment", + "NightFox@myied.org", + "© 2010 NightFox; © 2005-2007 Chervov Dmitry; © 2004-2005 Iksaif; © 2002-2003 Goblineye Entertainment", + "http://MyiEd.org/packs", + UNICODE_AWARE, + {0xb2dd9270, 0xce5e, 0x11df, {0xbd, 0x3d, 0x8, 0x0, 0x20, 0xc, 0x9a, 0x66}} +}; + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + g_hInstance = hinstDLL; + return TRUE; +} + +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_SRAWAY, MIID_LAST}; // TODO: add MIID_WHOISREADING here if there'll be any some time in future.. + +extern "C" __declspec(dllexport) PLUGININFOEX *MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +//NightFox +int ModernOptInitialise(WPARAM wParam,LPARAM lParam); + +TCString GetDynamicStatMsg(HANDLE hContact, char *szProto, DWORD UIN, int iStatus) +{ +// hContact is the contact that requests the status message + if (hContact != INVALID_HANDLE_VALUE) + { + VarParseData.Message = CContactSettings(iStatus, hContact).GetMsgFormat(GMF_ANYCURRENT, NULL, szProto); + } else + { // contact is unknown + VarParseData.Message = CProtoSettings(szProto, iStatus).GetMsgFormat(iStatus ? GMF_LASTORDEFAULT : GMF_ANYCURRENT); + } + TCString sTime; + VarParseData.szProto = szProto ? szProto : ((hContact && hContact != INVALID_HANDLE_VALUE) ? (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0) : NULL); + VarParseData.UIN = UIN; + VarParseData.Flags = 0; + if (ServiceExists(MS_VARS_FORMATSTRING) && !g_SetAwayMsgPage.GetDBValueCopy(IDS_SAWAYMSG_DISABLEVARIABLES)) + { + FORMATINFO fi = {0}; + fi.cbSize = sizeof(fi); + fi.tszFormat = VarParseData.Message; + fi.hContact = hContact; + fi.flags = FIF_TCHAR; + TCHAR *szResult = (TCHAR*)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0); + if (szResult) + { + VarParseData.Message = szResult; + CallService(MS_VARS_FREEMEMORY, (WPARAM)szResult, 0); + } + } + return VarParseData.Message = VarParseData.Message.Left(AWAY_MSGDATA_MAX); +} + + +int StatusMsgReq(WPARAM wParam, LPARAM lParam, CString &szProto) +{ + _ASSERT(szProto != NULL); + LogMessage("ME_ICQ_STATUSMSGREQ called. szProto=%s, Status=%d, UIN=%d", (char*)szProto, wParam, lParam); +// find the contact + char *szFoundProto; + HANDLE hFoundContact = NULL; // if we'll find the contact only on some other protocol, but not on szProto, then we'll use that hContact. + HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact) + { + char *szCurProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + if (DBGetContactSettingDword(hContact, szCurProto, "UIN", 0) == lParam) + { + szFoundProto = szCurProto; + hFoundContact = hContact; + if (!strcmp(szCurProto, szProto)) + { + break; + } + } + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + } + int iMode = ICQStatusToGeneralStatus(wParam); + if (!hFoundContact) + { + hFoundContact = INVALID_HANDLE_VALUE; + } else if (iMode >= ID_STATUS_ONLINE && iMode <= ID_STATUS_OUTTOLUNCH) + { // don't count xstatus requests + DBWriteContactSettingWord(hFoundContact, MOD_NAME, DB_REQUESTCOUNT, DBGetContactSettingWord(hFoundContact, MOD_NAME, DB_REQUESTCOUNT, 0) + 1); + } + HANDLE hContactForSettings = hFoundContact; // used to take into account not-on-list contacts when getting contact settings, but at the same time allows to get correct contact info for contacts that are in the DB + if (hContactForSettings != INVALID_HANDLE_VALUE && DBGetContactSettingByte(hContactForSettings, "CList", "NotOnList", 0)) + { + hContactForSettings = INVALID_HANDLE_VALUE; // INVALID_HANDLE_VALUE means the contact is not-on-list + } + if (g_SetAwayMsgPage.GetWnd()) + { + CallAllowedPS_SETAWAYMSG(szProto, iMode, NULL); // we can set status messages to NULL here, as they'll be changed again when the SAM dialog closes. + return 0; + } + if (CContactSettings(iMode, hContactForSettings).Ignore) + { + CallAllowedPS_SETAWAYMSG(szProto, iMode, ""); // currently NULL makes ICQ to ignore _any_ further status message requests until the next PS_SETAWAYMSG, so i can't use it here.. + return 0; // move along, sir + } + + if (iMode) + { // if it's not an xstatus message request + CallAllowedPS_SETAWAYMSG(szProto, iMode, (char*)TCHAR2ANSI(GetDynamicStatMsg(hFoundContact, szProto, lParam))); + } +// COptPage PopupNotifyData(g_PopupOptPage); +// PopupNotifyData.DBToMem(); + VarParseData.szProto = szProto; + VarParseData.UIN = lParam; + VarParseData.Flags = 0; + if (!iMode) + { + VarParseData.Flags |= VPF_XSTATUS; + } +/* + int ShowPopup = ((iMode == ID_STATUS_ONLINE && PopupNotifyData.GetValue(IDC_POPUPOPTDLG_ONLNOTIFY)) || + (iMode == ID_STATUS_AWAY && PopupNotifyData.GetValue(IDC_POPUPOPTDLG_AWAYNOTIFY)) || + (iMode == ID_STATUS_DND && PopupNotifyData.GetValue(IDC_POPUPOPTDLG_DNDNOTIFY)) || + (iMode == ID_STATUS_NA && PopupNotifyData.GetValue(IDC_POPUPOPTDLG_NANOTIFY)) || + (iMode == ID_STATUS_OCCUPIED && PopupNotifyData.GetValue(IDC_POPUPOPTDLG_OCCNOTIFY)) || + (iMode == ID_STATUS_FREECHAT && PopupNotifyData.GetValue(IDC_POPUPOPTDLG_FFCNOTIFY)) || + (!iMode && PopupNotifyData.GetValue(IDC_POPUPOPTDLG_OTHERNOTIFY))) && + CContactSettings(iMode, hContactForSettings).PopupNotify.IncludingParents(); + +// Show popup and play a sound + if (ShowPopup) + { + ShowPopup = ShowPopupNotification(PopupNotifyData, hFoundContact, iMode); // we need ShowPopup also to determine whether to log to file or not + } +*/ +// Log status message request to a file +// if (!PopupNotifyData.GetValue(IDC_POPUPOPTDLG_LOGONLYWITHPOPUP) || ShowPopup) +// { + TCString LogMsg; + if (!iMode) + { // if it's an xstatus message request + LogMsg = DBGetContactSettingString(NULL, szProto, "XStatusName", _T("")); + TCString XMsg(DBGetContactSettingString(NULL, szProto, "XStatusMsg", _T(""))); + if (XMsg.GetLen()) + { + if (LogMsg.GetLen()) + { + LogMsg += _T("\r\n"); + } + LogMsg += XMsg; + } + } else + { + LogMsg = VarParseData.Message; + } + if (ServiceExists(MS_VARS_FORMATSTRING)) + { + logservice_log(LOG_ID, hFoundContact, LogMsg); + } else + { + TCString szUIN; + _ultot(lParam, szUIN.GetBuffer(16), 10); + szUIN.ReleaseBuffer(); + TCHAR *szStatDesc = iMode ? (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iMode, 0) : STR_XSTATUSDESC; + if (!szStatDesc) + { + _ASSERT(0); + szStatDesc = _T(""); + } + logservice_log(LOG_ID, hFoundContact, TCString((TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hFoundContact, GCDNF_TCHAR)) + _T(" (") + szUIN + TranslateT(") read your ") + szStatDesc + TranslateT(" message:\r\n") + LogMsg); + } +// } + return 0; +} + +// Here is an ugly workaround to support multiple ICQ accounts +// hope 5 icq accounts will be sufficient for everyone ;) +#define MAXICQACCOUNTS 5 +CString ICQProtoList[MAXICQACCOUNTS]; +#define StatusMsgReqN(N) int StatusMsgReq##N(WPARAM wParam, LPARAM lParam) {return StatusMsgReq(wParam, lParam, ICQProtoList[N - 1]);} +StatusMsgReqN(1) StatusMsgReqN(2) StatusMsgReqN(3) StatusMsgReqN(4) StatusMsgReqN(5) +MIRANDAHOOK StatusMsgReqHooks[] = {StatusMsgReq1, StatusMsgReq2, StatusMsgReq3, StatusMsgReq4, StatusMsgReq5}; + +int IsAnICQProto(char *szProto) +{ + int i; + for (i = 0; i < MAXICQACCOUNTS; i++) + { + if (ICQProtoList[i] == (const char*)szProto) + { + return true; + } + } + return false; +} + + +int StatusChanged(WPARAM wParam, LPARAM lParam) +{ +// wParam = iMode +// lParam = (char*)szProto + LogMessage("MS_CLIST_SETSTATUSMODE called. szProto=%s, Status=%d", lParam ? (char*)lParam : "NULL", wParam); + g_ProtoStates[(char*)lParam].Status = wParam; +// let's check if we handle this thingy + if (g_fNoProcessing) // we're told not to do anything + { + g_fNoProcessing = false; // take it off + return 0; + } + DWORD Flag1 = 0; + DWORD Flag3 = 0; + if (lParam) + { + Flag1 = CallProtoService((char*)lParam, PS_GETCAPS, PFLAGNUM_1, 0); + Flag3 = CallProtoService((char*)lParam, PS_GETCAPS, PFLAGNUM_3, 0); + } else + { + PROTOCOLDESCRIPTOR **proto; + int iProtoCount = 0; + CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&iProtoCount, (LPARAM)&proto); + int i; + for (i = 0; i < iProtoCount; i++) + { + if (proto[i]->type == PROTOTYPE_PROTOCOL) + { + Flag1 |= CallProtoService(proto[i]->szName, PS_GETCAPS, PFLAGNUM_1, 0); + Flag3 |= CallProtoService(proto[i]->szName, PS_GETCAPS, PFLAGNUM_3, 0); + } + } + } + if (!(Flag1 & PF1_MODEMSGSEND || Flag3 & Proto_Status2Flag(wParam) || (Flag1 & PF1_IM) == PF1_IM)) + { + return 0; // there are no protocols with changed status that support autoreply or away messages for this status + } + if (g_SetAwayMsgPage.GetWnd()) + { + SetForegroundWindow(g_SetAwayMsgPage.GetWnd()); + return 0; + } + int i; + for (i = lengthof(StatusModeList) - 1; i >= 0; i--) + { + if (wParam == StatusModeList[i].Status) + { + break; + } + } + if (i < 0) + { + return 0; + } + BOOL bScreenSaverRunning; + SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &bScreenSaverRunning, 0); + if (bScreenSaverRunning || g_MoreOptPage.GetDBValueCopy(StatusModeList[i].DontShowDialogCtlID)) + { + CProtoSettings((char*)lParam).SetMsgFormat(SMF_PERSONAL, CProtoSettings((char*)lParam).GetMsgFormat(GMF_LASTORDEFAULT)); + ChangeProtoMessages((char*)lParam, wParam, TCString()); + } else + { + SetAwayMsgData *dat = new SetAwayMsgData; + ZeroMemory(dat, sizeof(SetAwayMsgData)); + dat->szProtocol = (char*)lParam; + dat->IsModeless = false; + DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_SETAWAYMSG), NULL, SetAwayMsgDlgProc, (LPARAM)dat); + } + return 0; +} + + +#define ID_STATUS_LAST 40081 // yes, 40081 means internal CommonStatus' ID_STATUS_LAST here, not ID_STATUS_IDLE :-S +#define ID_STATUS_CURRENT 40082 +#define ID_STATUS_DISABLED 41083 +int CSStatusChange(WPARAM wParam, LPARAM lParam) // CommonStatus plugins (StartupStatus and AdvancedAutoAway) +{ +// wParam = PROTOCOLSETTINGEX** protoSettings + PROTOCOLSETTINGEX** ps = *(PROTOCOLSETTINGEX***)wParam; + if (!ps) + { + return -1; + } + LogMessage("ME_CS_STATUSCHANGEEX event:"); + int i; + for (i = 0; i < g_CSProtoCount; i++) + { + LogMessage("%d: cbSize=%d, szProto=%s, status=%d, lastStatus=%d, szMsg:", i + 1, ps[i]->cbSize, ps[i]->szName ? (char*)ps[i]->szName : "NULL", ps[i]->status, ps[i]->lastStatus, ps[i]->szMsg ? ps[i]->szMsg : "NULL"); + if (ps[i]->status != ID_STATUS_DISABLED) + { + if (ps[i]->status != ID_STATUS_CURRENT) + { + g_ProtoStates[ps[i]->szName].Status = (ps[i]->status == ID_STATUS_LAST) ? ps[i]->lastStatus : ps[i]->status; + } + CProtoSettings(ps[i]->szName).SetMsgFormat(SMF_TEMPORARY, ps[i]->szMsg ? ANSI2TCHAR(ps[i]->szMsg) : CProtoSettings(ps[i]->szName).GetMsgFormat(GMF_LASTORDEFAULT)); + } + } + return 0; +} + + +static int IdleChangeEvent(WPARAM wParam, LPARAM lParam) +{ + LogMessage("ME_IDLE_CHANGED event. lParam=0x%x", lParam); // yes, we don't do anything with status message changes on idle.. there seems to be no any good solution for the wrong status message issue :( + g_bIsIdle = lParam & IDF_ISIDLE; + return 0; +} + + +int CSModuleLoaded(WPARAM wParam, LPARAM lParam) // StartupStatus and AdvancedAutoAway +{ +// wParam = ProtoCount + g_CSProtoCount = wParam; + return 0; +} + + +int PreBuildContactMenu(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE)wParam; + char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + CLISTMENUITEM miSetMsg = {0}; + miSetMsg.cbSize = sizeof(miSetMsg); + miSetMsg.flags = CMIM_FLAGS | CMIF_TCHAR | CMIF_HIDDEN; + CLISTMENUITEM miReadMsg = {0}; + miReadMsg.cbSize = sizeof(miReadMsg); + miReadMsg.flags = CMIM_FLAGS | CMIF_TCHAR | CMIF_HIDDEN; + int iMode = szProto ? CallProtoService(szProto, PS_GETSTATUS, 0, 0) : 0; + int Flag1 = szProto ? CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) : 0; + int iContactMode = DBGetContactSettingWord(hContact, szProto, "Status", ID_STATUS_OFFLINE); + TCHAR szSetStr[256], szReadStr[256]; + if (szProto) + { + int i; + for (i = lengthof(StatusModeList) - 1; i >= 0; i--) + { + if (iMode == StatusModeList[i].Status) + { + break; + } + } + if ((Flag1 & PF1_MODEMSGSEND && CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_3, 0) & Proto_Status2Flag(iMode)) || ((Flag1 & PF1_IM) == PF1_IM && (i < 0 || !g_AutoreplyOptPage.GetDBValueCopy(StatusModeList[i].DisableReplyCtlID)))) + { // the protocol supports status message sending for current status, or autoreplying + mir_sntprintf(szSetStr, SIZEOF(szSetStr), TranslateT("Set %s message for the contact"), CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iMode, GSMDF_TCHAR), CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR)); + miSetMsg.ptszName = szSetStr; + miSetMsg.flags = CMIM_FLAGS | CMIF_TCHAR | CMIM_NAME; + } + if (Flag1 & PF1_MODEMSGRECV && CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_3, 0) & Proto_Status2Flag(iContactMode)) + { // the protocol supports status message reading for contact's status + mir_sntprintf(szReadStr, SIZEOF(szReadStr), TranslateT("Re&ad %s Message"), CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iContactMode, GSMDF_TCHAR)); + miReadMsg.ptszName = szReadStr; + miReadMsg.flags = CMIM_FLAGS | CMIF_TCHAR | CMIM_NAME | CMIM_ICON; + miReadMsg.hIcon = LoadSkinnedProtoIcon(szProto, iContactMode); + } + } + if (g_hContactMenuItem) + { + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hContactMenuItem, (LPARAM)&miSetMsg); + + if ((Flag1 & PF1_IM) == PF1_IM) + { // if this contact supports sending/receiving messages + int iAutoreply = CContactSettings(g_ProtoStates[szProto].Status, hContact).Autoreply; + CLISTMENUITEM mi = {0}; + mi.cbSize = sizeof(mi); + mi.flags = CMIM_ICON | CMIM_FLAGS | CMIF_TCHAR; + switch (iAutoreply) + { + case VAL_USEDEFAULT: mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_DOT)); break; + case 0: mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SOE_DISABLED)); break; + default: iAutoreply = 1; mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SOE_ENABLED)); break; + } + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hToggleSOEContactMenuItem, (LPARAM)&mi); + mi.flags = CMIM_FLAGS | CMIF_TCHAR | (iAutoreply == 1 ? CMIF_CHECKED : 0); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hAutoreplyOnContactMenuItem, (LPARAM)&mi); + mi.flags = CMIM_FLAGS | CMIF_TCHAR | (iAutoreply == 0 ? CMIF_CHECKED : 0); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hAutoreplyOffContactMenuItem, (LPARAM)&mi); + mi.flags = CMIM_FLAGS | CMIF_TCHAR | (iAutoreply == VAL_USEDEFAULT ? CMIF_CHECKED : 0); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hAutoreplyUseDefaultContactMenuItem, (LPARAM)&mi); + } else + { // hide the Autoreply menu item + CLISTMENUITEM mi = {0}; + mi.cbSize = sizeof(mi); + mi.flags = CMIM_FLAGS | CMIF_TCHAR | CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hToggleSOEContactMenuItem, (LPARAM)&mi); + } + } + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hReadStatMenuItem, (LPARAM)&miReadMsg); + return 0; +} + + +static INT_PTR SetContactStatMsg(WPARAM wParam, LPARAM lParam) +{ + if (g_SetAwayMsgPage.GetWnd()) // already setting something + { + SetForegroundWindow(g_SetAwayMsgPage.GetWnd()); + return 0; + } + SetAwayMsgData *dat = new SetAwayMsgData; + ZeroMemory(dat, sizeof(SetAwayMsgData)); + dat->hInitContact = (HANDLE)wParam; + dat->szProtocol = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0); + dat->IsModeless = false; + DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_SETAWAYMSG), NULL, SetAwayMsgDlgProc, (LPARAM)dat); + return 0; +} + +/* //NightFox: deleted used-to-be support +void UpdateSOEButtons(HANDLE hContact) +{ + if (!hContact) + { + int SendOnEvent = CContactSettings(g_ProtoStates[(char*)NULL].Status).Autoreply; + CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)g_hTopToolbarbutton, SendOnEvent ? TTBST_PUSHED : TTBST_RELEASED); + CLISTMENUITEM mi = {0}; + mi.cbSize = sizeof(mi); + mi.position = 1000020000; + mi.flags = CMIF_TCHAR | CMIM_NAME | CMIM_ICON; // strange, but CMIF_TCHAR is still necessary even without CMIM_FLAGS + mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(SendOnEvent ? IDI_SOE_ENABLED : IDI_SOE_DISABLED)); + mi.ptszName = SendOnEvent ? DISABLE_SOE_COMMAND : ENABLE_SOE_COMMAND; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hToggleSOEMenuItem, (LPARAM)&mi); + } + if (g_SetAwayMsgPage.GetWnd()) + { + SendMessage(g_SetAwayMsgPage.GetWnd(), UM_SAM_REPLYSETTINGCHANGED, (WPARAM)hContact, 0); + } +} +*/ + +INT_PTR ToggleSendOnEvent(WPARAM wParam, LPARAM lParam) +{ // used only for the global setting + HANDLE hContact = (HANDLE)wParam; + CContactSettings(g_ProtoStates[hContact ? (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0) : (char*)NULL].Status, hContact).Autoreply.Toggle(); + //UpdateSOEButtons(); + return 0; +} + + +INT_PTR srvAutoreplyOn(WPARAM wParam, LPARAM lParam) +{ // wParam = hContact + HANDLE hContact = (HANDLE)wParam; + CContactSettings(g_ProtoStates[(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0)].Status, hContact).Autoreply = 1; + //UpdateSOEButtons(hContact); + return 0; +} + + +INT_PTR srvAutoreplyOff(WPARAM wParam, LPARAM lParam) +{ // wParam = hContact + HANDLE hContact = (HANDLE)wParam; + CContactSettings(g_ProtoStates[(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0)].Status, hContact).Autoreply = 0; + //UpdateSOEButtons(hContact); + return 0; +} + + +INT_PTR srvAutoreplyUseDefault(WPARAM wParam, LPARAM lParam) +{ // wParam = hContact + HANDLE hContact = (HANDLE)wParam; + CContactSettings(g_ProtoStates[(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0)].Status, hContact).Autoreply = VAL_USEDEFAULT; + //UpdateSOEButtons(hContact); + return 0; +} + +/* //NightFox: deleted used-to-be support +int Create_TopToolbar(WPARAM wParam, LPARAM lParam) +{ + int SendOnEvent = CContactSettings(g_ProtoStates[(char*)NULL].Status).Autoreply; + if (ServiceExists(MS_TTB_ADDBUTTON)) + { + TTBButton ttbb = {0}; + ttbb.cbSize = sizeof(ttbb); + ttbb.hbBitmapUp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_SOE_DISABLED)); + ttbb.hbBitmapDown = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_SOE_ENABLED)); + ttbb.pszServiceUp = MS_AWAYSYS_AUTOREPLY_TOGGLE; + ttbb.pszServiceDown = MS_AWAYSYS_AUTOREPLY_TOGGLE; + ttbb.dwFlags = TTBBF_VISIBLE | TTBBF_SHOWTOOLTIP; + ttbb.name = Translate("Toggle autoreply on/off"); + g_hTopToolbarbutton = (HANDLE)CallService(MS_TTB_ADDBUTTON, (WPARAM)&ttbb, 0); + CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)g_hTopToolbarbutton, SendOnEvent ? TTBST_PUSHED : TTBST_RELEASED); + } + return 0; +} +*/ + +static int IconsChanged(WPARAM wParam, LPARAM lParam) +{ + g_IconList.ReloadIcons(); + if (g_MessagesOptPage.GetWnd()) + { + SendMessage(g_MessagesOptPage.GetWnd(), UM_ICONSCHANGED, 0, 0); + } + if (g_MoreOptPage.GetWnd()) + { + SendMessage(g_MoreOptPage.GetWnd(), UM_ICONSCHANGED, 0, 0); + } + if (g_AutoreplyOptPage.GetWnd()) + { + SendMessage(g_AutoreplyOptPage.GetWnd(), UM_ICONSCHANGED, 0, 0); + } +/* if (g_PopupOptPage.GetWnd()) + { + SendMessage(g_PopupOptPage.GetWnd(), UM_ICONSCHANGED, 0, 0); + }*/ + return 0; +} + + +static int ContactSettingsInit(WPARAM wParam, LPARAM lParam) +{ + CONTACTSETTINGSINIT *csi = (CONTACTSETTINGSINIT*)wParam; + char *szProto = (csi->Type == CSIT_CONTACT) ? (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)csi->hContact, 0) : NULL; + if ((csi->Type == CSIT_GROUP) || szProto) + { + int Flag1 = (csi->Type == CSIT_CONTACT) ? CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) : PF1_IM; // we assume that there can be some contacts in the group with PF1_IM capability + if ((Flag1 & PF1_IM) == PF1_IM || Flag1 & PF1_INDIVMODEMSG) + { // does contact's protocol supports message sending/receiving or individual status messages? + CONTACTSETTINGSCONTROL csc = {0}; + csc.cbSize = sizeof(csc); + csc.cbStateSize = sizeof(CSCONTROLSTATE); + csc.Position = CSPOS_SORTBYALPHABET; + csc.ControlType = CSCT_CHECKBOX; + csc.szModule = MOD_NAME; + csc.StateNum = 3; + csc.DefState = 2; // these settings are used for all controls below + + /*if ((csi->Type == CSIT_GROUP) || IsAnICQProto(szProto)) + { + csc.Flags = CSCF_TCHAR; + csc.ptszTitle = LPGENT("New Away System: Status message request notifications"); + csc.ptszGroup = CSGROUP_NOTIFICATIONS; + csc.ptszTooltip = NULL; + csc.szSetting = DB_POPUPNOTIFY; + CallService(MS_CONTACTSETTINGS_ADDCONTROL, wParam, (LPARAM)&csc); + }*/ + int StatusMode = 0; + if (csi->Type == CSIT_CONTACT) + { + CContactSettings CSettings(0, csi->hContact); + StatusMode = CSettings.Status; + } else + { + _ASSERT(csi->Type == CSIT_GROUP); + StatusMode = g_ProtoStates[(char*)NULL].Status; + } + if (StatusMode == ID_STATUS_OFFLINE) + { + StatusMode = ID_STATUS_AWAY; + } + CString Setting; + TCHAR Title[128]; + csc.Flags = CSCF_TCHAR | CSCF_DONT_TRANSLATE_STRINGS; // these Flags and ptszGroup are used for both controls below + csc.ptszGroup = TranslateT("New Away System"); + + if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS)) + { + mir_sntprintf(Title, SIZEOF(Title), TranslateT("Enable autoreply when you are %s"), (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, StatusMode, GSMDF_TCHAR)); + csc.ptszTitle = Title; + csc.ptszTooltip = TranslateT("\"Store contact autoreply/ignore settings for each status separately\" is enabled, so this setting is per-contact AND per-status."); + } else + { + csc.ptszTitle = TranslateT("Enable autoreply"); + csc.ptszTooltip = NULL; + } + Setting = StatusToDBSetting(StatusMode, DB_ENABLEREPLY, IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS); + csc.szSetting = Setting; + CallService(MS_CONTACTSETTINGS_ADDCONTROL, wParam, (LPARAM)&csc); + + if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS)) + { + mir_sntprintf(Title, SIZEOF(Title), TranslateT("Don't send status message when you are %s"), (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, StatusMode, GSMDF_TCHAR)); + csc.ptszTitle = Title; + csc.ptszTooltip = TranslateT("Ignore status message requests from this contact and don't send an autoreply.\r\n\"Store contact autoreply/ignore settings for each status separately\" is enabled, so this setting is per-contact AND per-status."); + } else + { + csc.ptszTitle = TranslateT("Don't send status message"); + csc.ptszTooltip = TranslateT("Ignore status message requests from this contact and don't send an autoreply"); + } + Setting = StatusToDBSetting(StatusMode, DB_IGNOREREQUESTS, IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS); + csc.szSetting = Setting; + CallService(MS_CONTACTSETTINGS_ADDCONTROL, wParam, (LPARAM)&csc); + } + } + return 0; +} + + +INT_PTR srvVariablesHandler(WPARAM wParam, LPARAM lParam) +{ + ARGUMENTSINFO *ai = (ARGUMENTSINFO*)lParam; + ai->flags = AIF_DONTPARSE; + TCString Result; + if (!lstrcmp(ai->targv[0], _T(VAR_AWAYSINCE_TIME))) + { + GetTimeFormat(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), 0, g_ProtoStates[VarParseData.szProto].AwaySince, (ai->argc > 1 && *ai->targv[1]) ? ai->targv[1] : _T("H:mm"), Result.GetBuffer(256), 256); + Result.ReleaseBuffer(); + } else if (!lstrcmp(ai->targv[0], _T(VAR_AWAYSINCE_DATE))) + { + GetDateFormat(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), 0, g_ProtoStates[VarParseData.szProto].AwaySince, (ai->argc > 1 && *ai->targv[1]) ? ai->targv[1] : NULL, Result.GetBuffer(256), 256); + Result.ReleaseBuffer(); + } else if (!lstrcmp(ai->targv[0], _T(VAR_STATDESC))) + { + Result = (VarParseData.Flags & VPF_XSTATUS) ? STR_XSTATUSDESC : (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, g_ProtoStates[VarParseData.szProto].Status, GSMDF_TCHAR); + } else if (!lstrcmp(ai->targv[0], _T(VAR_MYNICK))) + { + if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_MYNICKPERPROTO) && VarParseData.szProto) + { + Result = DBGetContactSettingString(NULL, VarParseData.szProto, "Nick", (TCHAR*)NULL); + } + if (Result == NULL) + { + Result = (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, NULL, GCDNF_TCHAR); + } + if (Result == NULL) + { + Result = TranslateT("Stranger"); + } + } else if (!lstrcmp(ai->targv[0], _T(VAR_REQUESTCOUNT))) + { + mir_sntprintf(Result.GetBuffer(16), 16, _T("%d"), DBGetContactSettingWord(ai->fi->hContact, MOD_NAME, DB_REQUESTCOUNT, 0)); + Result.ReleaseBuffer(); + } else if (!lstrcmp(ai->targv[0], _T(VAR_MESSAGENUM))) + { + mir_sntprintf(Result.GetBuffer(16), 16, _T("%d"), DBGetContactSettingWord(ai->fi->hContact, MOD_NAME, DB_MESSAGECOUNT, 0)); + Result.ReleaseBuffer(); + } else if (!lstrcmp(ai->targv[0], _T(VAR_TIMEPASSED))) + { + ULARGE_INTEGER ul_AwaySince, ul_Now; + SYSTEMTIME st; + GetLocalTime(&st); + SystemTimeToFileTime(&st, (LPFILETIME)&ul_Now); + SystemTimeToFileTime(g_ProtoStates[VarParseData.szProto].AwaySince, (LPFILETIME)&ul_AwaySince); + ul_Now.QuadPart -= ul_AwaySince.QuadPart; + ul_Now.QuadPart /= 10000000; // now it's in seconds + Result.GetBuffer(256); + if (ul_Now.LowPart >= 7200) // more than 2 hours + { + mir_sntprintf(Result, 256, TranslateT("%d hours"), ul_Now.LowPart / 3600); + } else if (ul_Now.LowPart >= 120) // more than 2 minutes + { + mir_sntprintf(Result, 256, TranslateT("%d minutes"), ul_Now.LowPart / 60); + } else + { + mir_sntprintf(Result, 256, TranslateT("%d seconds"), ul_Now.LowPart); + } + Result.ReleaseBuffer(); + } else if (!lstrcmp(ai->targv[0], _T(VAR_PREDEFINEDMESSAGE))) + { + ai->flags = 0; // reset AIF_DONTPARSE flag + if (ai->argc != 2) + { + return NULL; + } + COptPage MsgTreeData(g_MsgTreePage); + COptItem_TreeCtrl *TreeCtrl = (COptItem_TreeCtrl*)MsgTreeData.Find(IDV_MSGTREE); + TreeCtrl->DBToMem(CString(MOD_NAME)); + int i; + for (i = 0; i < TreeCtrl->Value.GetSize(); i++) + { + if (!(TreeCtrl->Value[i].Flags & TIF_GROUP) && !_tcsicmp(TreeCtrl->Value[i].Title, ai->targv[1])) + { + Result = TreeCtrl->Value[i].User_Str1; + break; + } + } + if (Result == NULL) + { // if we didn't find a message with specified title + return NULL; // return it now, as later we change NULL to "" + } + } else if (!lstrcmp(ai->targv[0], _T(VAR_PROTOCOL))) + { + if (VarParseData.szProto) + { + CString AnsiResult; + CallProtoService(VarParseData.szProto, PS_GETNAME, 256, (LPARAM)AnsiResult.GetBuffer(256)); + AnsiResult.ReleaseBuffer(); + Result = ANSI2TCHAR(AnsiResult); + } + if (Result == NULL) + { // if we didn't find a message with specified title + return NULL; // return it now, as later we change NULL to "" + } + } + TCHAR *szResult; + if (!(szResult = (TCHAR*)malloc((Result.GetLen() + 1) * sizeof(TCHAR)))) + { + return NULL; + } + _tcscpy(szResult, (Result != NULL) ? Result : _T("")); + return (int)szResult; +} + + +INT_PTR srvFreeVarMem(WPARAM wParam, LPARAM lParam) +{ + if (!lParam) + { + return -1; + } + free((void*)lParam); + return 0; +} + + +static INT_PTR MyCallService(const char *name, WPARAM wParam, LPARAM lParam) +{ + if (name && wParam <= ID_STATUS_OUTTOLUNCH && wParam >= ID_STATUS_OFFLINE) // wParam conditions here are distinctive "features" of PS_SETSTATUS and PS_SETAWAYMSG services, so if wParam does not suit them, we'll pass the control to the old CallService function as soon as possible + { + const char *pProtoNameEnd = strrchr(name, '/'); + if (pProtoNameEnd) + { + if (!lstrcmpA(pProtoNameEnd, PS_SETSTATUS)) + { + // it's PS_SETSTATUS service; wParam = status; lParam = 0 + // returns 0 on success, nonzero on failure + CString Proto(""); + Proto.DiffCat(name, pProtoNameEnd); + if (wParam != g_ProtoStates[Proto].Status) + { + g_ProtoStates[Proto].Status = wParam; + TCString Msg(CProtoSettings(Proto).GetMsgFormat(GMF_LASTORDEFAULT)); + LogMessage("Detected a PS_SETSTATUS call with Status different from the one known to NAS. szProto=%s, NewStatus=%d, NewMsg:\n%s", (char*)Proto, wParam, (Msg != NULL) ? TCHAR2ANSI(Msg) : "NULL"); + CProtoSettings(Proto).SetMsgFormat(SMF_TEMPORARY, Msg); + } + } else if (!lstrcmpA(pProtoNameEnd, PS_SETAWAYMSG)) + { + // PS_SETAWAYMSG service; wParam = status; lParam = (const char*)szMessage + // returns 0 on success, nonzero on failure + CString Proto(""); + Proto.DiffCat(name, pProtoNameEnd); + LogMessage("Someone else than NAS called PS_SETAWAYMSG. szProto=%s, Status=%d, Msg:\n%s", (char*)Proto, wParam, lParam ? (char*)lParam : "NULL"); + CProtoSettings(Proto).SetMsgFormat(SMF_TEMPORARY, lParam ? ((ServiceExists(MS_VARS_FORMATSTRING) && !g_SetAwayMsgPage.GetDBValueCopy(IDS_SAWAYMSG_DISABLEVARIABLES)) ? VariablesEscape(ANSI2TCHAR((char*)lParam)) : ANSI2TCHAR((char*)lParam)) : TCString(_T(""))); + ChangeProtoMessages(Proto, wParam, TCString()); + return 0; + } + } + } + return g_OldCallService(name, wParam, lParam); +} + + +int MirandaLoaded(WPARAM wParam, LPARAM lParam) +{ + LoadMsgTreeModule(); + LoadCListModule(); + InitUpdateMsgs(); + g_IconList.ReloadIcons(); + + PROTOCOLDESCRIPTOR **proto; + DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hMainThread, THREAD_SET_CONTEXT, false, 0); + int iProtoCount = 0; + CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&iProtoCount, (LPARAM)&proto); + int i; + int CurProtoIndex; + for (i = 0, CurProtoIndex = 0; i < iProtoCount && CurProtoIndex < MAXICQACCOUNTS; i++) + { + if (proto[i]->type == PROTOTYPE_PROTOCOL) + { + HANDLE hHook = HookEvent(CString(proto[i]->szName) + ME_ICQ_STATUSMSGREQ, StatusMsgReqHooks[CurProtoIndex]); + if (hHook) + { + hHooks.insert(hHook); + ICQProtoList[CurProtoIndex] = proto[i]->szName; + CurProtoIndex++; + } + } + } + hServices.insert(CreateServiceFunction(MS_AWAYSYS_SETCONTACTSTATMSG, SetContactStatMsg)); + hServices.insert(CreateServiceFunction(MS_AWAYSYS_AUTOREPLY_TOGGLE, ToggleSendOnEvent)); + hServices.insert(CreateServiceFunction(MS_AWAYSYS_AUTOREPLY_ON, srvAutoreplyOn)); + hServices.insert(CreateServiceFunction(MS_AWAYSYS_AUTOREPLY_OFF, srvAutoreplyOff)); + hServices.insert(CreateServiceFunction(MS_AWAYSYS_AUTOREPLY_USEDEFAULT, srvAutoreplyUseDefault)); + hServices.insert(CreateServiceFunction(MS_NAS_GETSTATEA, GetStateA)); + hServices.insert(CreateServiceFunction(MS_NAS_SETSTATEA, SetStateA)); + hServices.insert(CreateServiceFunction(MS_NAS_GETSTATEW, GetStateW)); + hServices.insert(CreateServiceFunction(MS_NAS_SETSTATEW, SetStateW)); + hServices.insert(CreateServiceFunction(MS_NAS_INVOKESTATUSWINDOW, InvokeStatusWindow)); + hServices.insert(CreateServiceFunction(MS_AWAYMSG_GETSTATUSMSG, GetStatusMsg)); +// and old AwaySysMod service, for compatibility reasons + hServices.insert(CreateServiceFunction(MS_AWAYSYS_SETSTATUSMODE, SetStatusMode)); +//NightFox: none; +// hHooks.insert(HookEvent(ME_TTB_MODULELOADED, Create_TopToolbar)); + hHooks.insert(HookEvent(ME_OPT_INITIALISE, OptsDlgInit)); + hHooks.insert(HookEvent(ME_CLIST_STATUSMODECHANGE, StatusChanged)); + hHooks.insert(HookEvent(ME_CS_STATUSCHANGEEX, CSStatusChange)); // for compatibility with StartupStatus and AdvancedAutoAway + hHooks.insert(HookEvent(ME_DB_EVENT_FILTER_ADD, MsgEventAdded)); + hHooks.insert(HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PreBuildContactMenu)); + hHooks.insert(HookEvent(ME_SKIN_ICONSCHANGED, IconsChanged)); + hHooks.insert(HookEvent(ME_IDLE_CHANGED, IdleChangeEvent)); + hHooks.insert(HookEvent(ME_CONTACTSETTINGS_INITIALISE, ContactSettingsInit)); + g_hReadWndList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); + int SendOnEvent = CContactSettings(g_ProtoStates[(char*)NULL].Status).Autoreply; + + CLISTMENUITEM mi = {0}; + mi.cbSize = sizeof(mi); + mi.position = 1000020000; + mi.flags = CMIF_TCHAR | CMIF_NOTOFFLINE; + mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(SendOnEvent ? IDI_SOE_ENABLED : IDI_SOE_DISABLED)); + mi.ptszName = SendOnEvent ? DISABLE_SOE_COMMAND : ENABLE_SOE_COMMAND; + mi.pszService = MS_AWAYSYS_AUTOREPLY_TOGGLE; + g_hToggleSOEMenuItem = Menu_AddMainMenuItem(&mi); + + ZeroMemory(&mi, sizeof(mi)); + mi.cbSize = sizeof(mi); + mi.position = -2000005000; + mi.flags = CMIF_TCHAR | CMIF_NOTOFFLINE | CMIF_HIDDEN; + mi.ptszName = LPGENT("Read status message"); // never seen... + mi.pszService = MS_AWAYMSG_SHOWAWAYMSG; + g_hReadStatMenuItem = Menu_AddContactMenuItem(&mi); + if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_USEMENUITEM)) { + ZeroMemory(&mi, sizeof(mi)); + mi.cbSize = sizeof(mi); + mi.flags = CMIF_TCHAR | CMIF_HIDDEN; + mi.ptszName = LPGENT("Set status message"); // will never be shown + mi.position = 1000020000; + mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_MSGICON)); + mi.pszService = MS_AWAYSYS_SETCONTACTSTATMSG; + g_hContactMenuItem = Menu_AddContactMenuItem(&mi); + + ZeroMemory(&mi, sizeof(mi)); + mi.cbSize = sizeof(mi); + mi.flags = CMIF_TCHAR | CMIF_ROOTPOPUP; + mi.hIcon = NULL; + mi.pszPopupName = (char*)-1; + mi.position = 1000020000; + mi.ptszName = LPGENT("Autoreply"); + g_hToggleSOEContactMenuItem = Menu_AddContactMenuItem(&mi); + + mi.flags = CMIF_TCHAR | CMIF_CHILDPOPUP; + mi.pszPopupName = (char*)g_hToggleSOEContactMenuItem; + mi.popupPosition = 1000020000; + mi.position = 1000020000; + + mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SOE_ENABLED)); + mi.ptszName = LPGENT("On"); + mi.pszService = MS_AWAYSYS_AUTOREPLY_ON; + g_hAutoreplyOnContactMenuItem = Menu_AddContactMenuItem(&mi); + + mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SOE_DISABLED)); + mi.ptszName = LPGENT("Off"); + mi.pszService = MS_AWAYSYS_AUTOREPLY_OFF; + g_hAutoreplyOffContactMenuItem = Menu_AddContactMenuItem(&mi); + + mi.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_DOT)); + mi.ptszName = LPGENT("Use the default setting"); + mi.pszService = MS_AWAYSYS_AUTOREPLY_USEDEFAULT; + g_hAutoreplyUseDefaultContactMenuItem = Menu_AddContactMenuItem(&mi); + } + // add that funky thingy (just tweaked a bit, was spotted in Miranda's src code) + // we have to read the status message from contacts too... err + hServices.insert(CreateServiceFunction(MS_AWAYMSG_SHOWAWAYMSG, GetContactStatMsg)); + + SkinAddNewSoundEx(AWAYSYS_STATUSMSGREQUEST_SOUND, NULL, LPGEN("NewAwaySys: Incoming status message request")); + + if (ServiceExists(MS_VARS_REGISTERTOKEN)) { + struct + { + TCHAR *Name; + char *Descr; + int Flags; + } Variables[] = { + _T(VAR_AWAYSINCE_TIME), LPGEN("New Away System\t(x)\tAway since time in default format; ?nas_awaysince_time(x) in format x"), TRF_FIELD | TRF_FUNCTION, + _T(VAR_AWAYSINCE_DATE), LPGEN("New Away System\t(x)\tAway since date in default format; ?nas_awaysince_date(x) in format x"), TRF_FIELD | TRF_FUNCTION, + _T(VAR_STATDESC), LPGEN("New Away System\tStatus description"), TRF_FIELD | TRF_FUNCTION, + _T(VAR_MYNICK), LPGEN("New Away System\tYour nick for current protocol"), TRF_FIELD | TRF_FUNCTION, + _T(VAR_REQUESTCOUNT), LPGEN("New Away System\tNumber of status message requests from the contact"), TRF_FIELD | TRF_FUNCTION, + _T(VAR_MESSAGENUM), LPGEN("New Away System\tNumber of messages from the contact"), TRF_FIELD | TRF_FUNCTION, + _T(VAR_TIMEPASSED), LPGEN("New Away System\tTime passed until request"), TRF_FIELD | TRF_FUNCTION, + _T(VAR_PREDEFINEDMESSAGE), LPGEN("New Away System\t(x)\tReturns one of your predefined messages by its title: ?nas_predefinedmessage(creepy)"), TRF_FUNCTION, + _T(VAR_PROTOCOL), LPGEN("New Away System\tCurrent protocol name"), TRF_FIELD | TRF_FUNCTION + }; + hServices.insert(CreateServiceFunction(MS_AWAYSYS_FREEVARMEM, srvFreeVarMem)); + hServices.insert(CreateServiceFunction(MS_AWAYSYS_VARIABLESHANDLER, srvVariablesHandler)); + TOKENREGISTER tr = {0}; + tr.cbSize = sizeof(TOKENREGISTER); + tr.szService = MS_AWAYSYS_VARIABLESHANDLER; + tr.szCleanupService = MS_AWAYSYS_FREEVARMEM; + tr.memType = TR_MEM_OWNER; + int i; + for (i = 0; i < lengthof(Variables); i++) + { + tr.flags = Variables[i].Flags | TRF_CALLSVC | TRF_TCHAR; + tr.tszTokenString = Variables[i].Name; + tr.szHelpText = Variables[i].Descr; + CallService(MS_VARS_REGISTERTOKEN, 0, (LPARAM)&tr); + } + } + + //NightFox + HookEvent(ME_MODERNOPT_INITIALIZE, ModernOptInitialise); + + + return 0; +} + + +extern "C" int __declspec(dllexport) Load(void) +{ + + mir_getLP( &pluginInfo ); + + hHooks.insert(HookEvent(ME_SYSTEM_MODULESLOADED, MirandaLoaded)); + if (DBGetContactSettingString(NULL, "KnownModules", "New Away System", (char*)NULL) == NULL) + DBWriteContactSettingString(NULL, "KnownModules", "New Away System", MOD_NAME); + + InitCommonControls(); + InitOptions(); // must be called before we hook CallService + + logservice_register(LOG_ID, LPGENT("New Away System"), _T("NewAwaySys?puts(p,?dbsetting(%subject%,Protocol,p))?if2(_?dbsetting(,?get(p),?pinfo(?get(p),uidsetting)),).log"), TranslateTS(_T("`[`!cdate()-!ctime()`]` ?cinfo(%subject%,display) (?cinfo(%subject%,id)) read your %") _T(VAR_STATDESC) _T("% message:\r\n%extratext%\r\n\r\n"))); + + if (DBGetContactSettingByte(NULL, MOD_NAME, DB_SETTINGSVER, 0) < 1) + { // change all %nas_message% variables to %extratext% if it wasn't done before + TCString Str; + Str = DBGetContactSettingString(NULL, MOD_NAME, "PopupsFormat", _T("")); + if (Str.GetLen()) + { + DBWriteContactSettingTString(NULL, MOD_NAME, "PopupsFormat", Str.Replace(_T("nas_message"), _T("extratext"))); + } + Str = DBGetContactSettingString(NULL, MOD_NAME, "ReplyPrefix", _T("")); + if (Str.GetLen()) + { + DBWriteContactSettingTString(NULL, MOD_NAME, "ReplyPrefix", Str.Replace(_T("nas_message"), _T("extratext"))); + } + } + if (DBGetContactSettingByte(NULL, MOD_NAME, DB_SETTINGSVER, 0) < 2) + { // disable autoreply for not-on-list contacts, as such contact may be a spam bot + DBWriteContactSettingByte(NULL, MOD_NAME, ContactStatusToDBSetting(0, DB_ENABLEREPLY, 0, INVALID_HANDLE_VALUE), 0); + DBWriteContactSettingByte(NULL, MOD_NAME, DB_SETTINGSVER, 2); + } + return 0; +} + + +extern "C" int __declspec(dllexport) Unload() +{ + CloseHandle(hMainThread); + int i; + for (i = 0; i < hHooks.getCount(); i++) + UnhookEvent(hHooks[i]); + + for (i = 0; i < hServices.getCount(); i++) + DestroyServiceFunction(hServices[i]); + + return 0; +} diff --git a/plugins/!Deprecated/NewAwaySysMod/Client.cpp b/plugins/!Deprecated/NewAwaySysMod/Client.cpp new file mode 100644 index 0000000000..7767bdb285 --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/Client.cpp @@ -0,0 +1,232 @@ +/* + New Away System - plugin for Miranda IM + Copyright (c) 2005-2007 Chervov Dmitry + Copyright (c) 2004-2005 Iksaif Entertainment + Copyright (c) 2002-2003 Goblineye Entertainment + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "Common.h" +#include "MsgTree.h" +#include "Properties.h" + +#define PARSE_INTERVAL 10000 + +HANDLE g_hTerminateUpdateMsgsThread = NULL; +HANDLE g_hUpdateMsgsThread = NULL; + +void __cdecl UpdateMsgsThreadProc(void *) +{ + int ProtoCount; + PROTOCOLDESCRIPTOR **proto; + CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&ProtoCount, (LPARAM)&proto); + int I; + while (WaitForSingleObject(g_hTerminateUpdateMsgsThread, 0) == WAIT_TIMEOUT && !Miranda_Terminated()) + { + DWORD MinUpdateTimeDifference = g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_UPDATEMSGSPERIOD) * 1000; // in milliseconds + for (I = 0; I < ProtoCount; I++) + { + if (proto[I]->type == PROTOTYPE_PROTOCOL && CallProtoService(proto[I]->szName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND && !IsAnICQProto(proto[I]->szName)) + { + int Status = CallProtoService(proto[I]->szName, PS_GETSTATUS, 0, 0); + if (Status < ID_STATUS_OFFLINE || Status > ID_STATUS_OUTTOLUNCH) + { + Status = g_ProtoStates[proto[I]->szName].Status; + } + if (CallProtoService(proto[I]->szName, PS_GETCAPS, PFLAGNUM_3, 0) & Proto_Status2Flag(Status) && g_ProtoStates[proto[I]->szName].CurStatusMsg.GetUpdateTimeDifference() >= MinUpdateTimeDifference) + { + TCString CurMsg(GetDynamicStatMsg(INVALID_HANDLE_VALUE, proto[I]->szName)); + if ((TCString)g_ProtoStates[proto[I]->szName].CurStatusMsg != (const TCHAR*)CurMsg) // if the message has changed + { + g_ProtoStates[proto[I]->szName].CurStatusMsg = CurMsg; + CallAllowedPS_SETAWAYMSG(proto[I]->szName, Status, (char*)TCHAR2ANSI(CurMsg)); + } + } + } + } + SleepEx(PARSE_INTERVAL, true); + } +} + + +static void __stdcall DummyAPCFunc(ULONG_PTR) +{ + return; +} + + +void InitUpdateMsgs() +{ + int UpdateMsgs = g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_UPDATEMSGS); + if (g_hUpdateMsgsThread && !UpdateMsgs) + { + _ASSERT(WaitForSingleObject(g_hUpdateMsgsThread, 0) == WAIT_TIMEOUT); + SetEvent(g_hTerminateUpdateMsgsThread); + QueueUserAPC(DummyAPCFunc, g_hUpdateMsgsThread, 0); // wake up the thread, as it's most probably in SleepEx() now + WaitForSingleObject(g_hUpdateMsgsThread, INFINITE); + g_hUpdateMsgsThread = NULL; + CloseHandle(g_hTerminateUpdateMsgsThread); + } else if (!g_hUpdateMsgsThread && UpdateMsgs) + { + g_hTerminateUpdateMsgsThread = CreateEvent(NULL, TRUE, FALSE, NULL); + g_hUpdateMsgsThread = (HANDLE)mir_forkthread(UpdateMsgsThreadProc, NULL); + } +} + + +void ChangeProtoMessages(char* szProto, int iMode, TCString &Msg) +{ + TCString CurMsg(Msg); + if (szProto) + { + if (Msg == NULL) + { + CurMsg = GetDynamicStatMsg(INVALID_HANDLE_VALUE, szProto); + } + CallAllowedPS_SETAWAYMSG(szProto, iMode, (char*)TCHAR2ANSI(CurMsg)); + g_ProtoStates[szProto].CurStatusMsg = CurMsg; + } else // change message of all protocols + { + int ProtoCount; + PROTOCOLDESCRIPTOR **proto; + CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&ProtoCount, (LPARAM)&proto); + int I; + for (I = 0; I < ProtoCount; I++) + { + if (proto[I]->type == PROTOTYPE_PROTOCOL && !DBGetContactSettingByte(NULL, proto[I]->szName, "LockMainStatus", 0)) + { + if (Msg == NULL) + { + CurMsg = GetDynamicStatMsg(INVALID_HANDLE_VALUE, proto[I]->szName); + } + CallAllowedPS_SETAWAYMSG(proto[I]->szName, iMode, (char*)TCHAR2ANSI(CurMsg)); + g_ProtoStates[proto[I]->szName].CurStatusMsg = CurMsg; + } + } + } + static struct + { + int Status; + char *Setting; + } StatusSettings[] = { + ID_STATUS_OFFLINE, "Off", + ID_STATUS_ONLINE, "On", + ID_STATUS_AWAY, "Away", + ID_STATUS_NA, "Na", + ID_STATUS_DND, "Dnd", + ID_STATUS_OCCUPIED, "Occupied", + ID_STATUS_FREECHAT, "FreeChat", + ID_STATUS_INVISIBLE, "Inv", + ID_STATUS_ONTHEPHONE, "Otp", + ID_STATUS_OUTTOLUNCH, "Otl", + ID_STATUS_IDLE, "Idl" + }; + int I; + for (I = 0; I < lengthof(StatusSettings); I++) + { + if (iMode == StatusSettings[I].Status) + { + DBWriteContactSettingTString(NULL, "SRAway", CString(StatusSettings[I].Setting) + "Msg", CurMsg); + DBWriteContactSettingTString(NULL, "SRAway", CString(StatusSettings[I].Setting) + "Default", CurMsg); // TODO: make it more accurate, and change not only here, but when changing status messages through UpdateMsgsTimerFunc too; and when changing messages through AutoAway() ? + break; + } + } +// InitUpdateMsgs(); +} + + +int GetRecentGroupID(int iMode) +{ // returns an ID of a group where recent messages are stored, accordingly to current settings and status mode. + // -1 if the group is not found +// COptPage MoreOptData(g_MoreOptPage); + COptPage MsgTreeData(g_MsgTreePage); + COptItem_TreeCtrl *TreeCtrl = (COptItem_TreeCtrl*)MsgTreeData.Find(IDV_MSGTREE); + TreeCtrl->DBToMem(CString(MOD_NAME)); + int Order; + if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_PERSTATUSMRM)) + { + for (Order = 0; Order < TreeCtrl->Value.GetSize(); Order++) // find a group named accordingly to the current status + { + if (TreeCtrl->Value[Order].ParentID == g_Messages_RecentRootID && TreeCtrl->Value[Order].Flags & TIF_GROUP && !_tcsicmp(TreeCtrl->Value[Order].Title, iMode ? (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iMode, GSMDF_TCHAR) : MSGTREE_RECENT_OTHERGROUP)) + { + return TreeCtrl->Value[Order].ID; + } + } + } else // simply use Recent Messages category + { + return g_Messages_RecentRootID; + } + return -1; +} + + +int ICQStatusToGeneralStatus(int bICQStat) +{ + switch (bICQStat) + { + case MTYPE_AUTOONLINE: return ID_STATUS_ONLINE; + case MTYPE_AUTOAWAY: return ID_STATUS_AWAY; + case MTYPE_AUTONA: return ID_STATUS_NA; + case MTYPE_AUTODND: return ID_STATUS_DND; + case MTYPE_AUTOBUSY: return ID_STATUS_OCCUPIED; + case MTYPE_AUTOFFC: return ID_STATUS_FREECHAT; + default: return 0; + } +} + + +TCString VariablesEscape(TCString Str) +{ + if (!Str.GetLen()) + { + return _T(""); + } + enum eState + { + ST_TEXT, ST_QUOTE + }; + eState State = ST_QUOTE; + TCString Result(_T("`")); + const TCHAR *p = Str; + while (*p) + { + if (*p == '`') + { + if (State == ST_TEXT) + { + Result += _T("````"); + State = ST_QUOTE; + } else + { + Result += _T("``"); + } + } else + { + Result += *p; + State = ST_TEXT; + } + p++; + } + if (State == ST_QUOTE) + { + Result.GetBuffer()[Result.GetLen() - 1] = '\0'; + Result.ReleaseBuffer(); + } else + { + Result += '`'; + } + return Result; +} diff --git a/plugins/!Deprecated/NewAwaySysMod/Common.h b/plugins/!Deprecated/NewAwaySysMod/Common.h new file mode 100644 index 0000000000..7e261d875d --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/Common.h @@ -0,0 +1,411 @@ +/* + New Away System - plugin for Miranda IM + Copyright (c) 2005-2007 Chervov Dmitry + Copyright (c) 2004-2005 Iksaif Entertainment + Copyright (c) 2002-2003 Goblineye Entertainment + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#pragma once + +#define _CRT_SECURE_NO_WARNINGS +#define WIN32_LEAN_AND_MEAN +#define _WIN32_WINNT 0x0500 + +#define MIRANDA_VER 0x0600 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "newpluginapi.h" +#include "m_clist.h" +#include "m_system.h" +#include "m_database.h" +#include "m_clui.h" +#include "m_langpack.h" +#include "m_protosvc.h" +#include "m_options.h" +#include "..\..\protocols\IcqOscarJ\icq_constants.h" +#include "m_skin.h" +#include "m_awaymsg.h" +#include "m_utils.h" +#include "m_system_cpp.h" +#include "m_history.h" +#include "m_message.h" +#include "m_userinfo.h" +#include "m_icq.h" +#define THEMEAPI // we don't need no uxtheme defines :-/ they break everything when trying to include tmschema.h later +#include "win2k.h" +#undef THEMEAPI + +#include "resource.h" + +#include "m_variables.h" +//#include "m_toptoolbar.h" +#include "m_popup.h" +//#include "m_popupw.h" +#include "m_metacontacts.h" +#include "m_LogService.h" +#include "..\CommonLibs\CString.h" +#include "..\CommonLibs\Options.h" + + +#pragma comment(lib,"comctl32.lib") + +#define VAR_AWAYSINCE_TIME "nas_awaysince_time" +#define VAR_AWAYSINCE_DATE "nas_awaysince_date" +#define VAR_STATDESC "nas_statdesc" +#define VAR_MYNICK "nas_mynick" +#define VAR_REQUESTCOUNT "nas_requestcount" +#define VAR_MESSAGENUM "nas_messagecount" +#define VAR_TIMEPASSED "nas_timepassed" +#define VAR_PREDEFINEDMESSAGE "nas_predefinedmessage" +#define VAR_PROTOCOL "nas_protocol" + +#define SENDSMSG_EVENT_MSG 0x1 +#define SENDSMSG_EVENT_URL 0x2 +#define SENDSMSG_EVENT_FILE 0x4 + +#define AWAY_MSGDATA_MAX 8000 + +// Flags for status database settings +#define SF_OFF 0x1 +#define SF_ONL 0x2 +#define SF_AWAY 0x4 +#define SF_NA 0x8 +#define SF_OCC 0x10 +#define SF_DND 0x20 +#define SF_FFC 0x40 +#define SF_INV 0x80 +#define SF_OTP 0x100 +#define SF_OTL 0x200 +#define SF_OTHER 0x80000000 +/* +// Actions on popup click +#define PCA_OPENMESSAGEWND 0 // open message window +#define PCA_CLOSEPOPUP 1 // close popup +#define PCA_OPENDETAILS 2 // open contact details window +#define PCA_OPENMENU 3 // open contact menu +#define PCA_OPENHISTORY 4 // open contact history +#define PCA_OPENLOG 5 // open log file +#define PCA_DONOTHING 6 // do nothing + +// Notification options defaults +#define POPUP_DEF_POPUP_FORMAT TranslateT("?cinfo(%subject%,display) (?cinfo(%subject%,id)) is reading your %nas_statdesc% message:\r\n%extratext%") +#define POPUP_DEF_USEPOPUPS 0 +#define POPUP_DEF_LCLICKACTION PCA_OPENMESSAGEWND +#define POPUP_DEF_RCLICKACTION PCA_CLOSEPOPUP +#define POPUP_DEF_POPUP_BGCOLOUR 0xFFB5BC +#define POPUP_DEF_POPUP_TEXTCOLOUR 0 +#define POPUP_DEF_USEDEFBGCOLOUR 0 +#define POPUP_DEF_USEDEFTEXTCOLOUR 0 +#define POPUP_DEF_POPUPNOTIFYFLAGS (SF_ONL | SF_AWAY | SF_NA | SF_OCC | SF_DND | SF_FFC | SF_INV | SF_OTP | SF_OTL) +#define POPUP_DEF_POPUPDELAY 0 + +#define POPUP_MAXPOPUPDELAY 9999 +*/ +#define MOREOPTDLG_DEF_DONTPOPDLG (SF_ONL | SF_INV) +#define MOREOPTDLG_DEF_USEBYDEFAULT 0 + +// Event flags (used for "reply on event" options) +#define EF_MSG 1 +#define EF_URL 2 +#define EF_FILE 4 + +#define AUTOREPLY_DEF_REPLY 0 +#define AUTOREPLY_DEF_REPLYONEVENT (EF_MSG | EF_URL | EF_FILE) +#define AUTOREPLY_DEF_PREFIX TranslateT("Miranda IM autoreply >\r\n%extratext%") +#define AUTOREPLY_DEF_DISABLEREPLY (SF_ONL | SF_INV) + +#define AUTOREPLY_IDLE_WINDOWS 0 +#define AUTOREPLY_IDLE_MIRANDA 1 +#define AUTOREPLY_DEF_IDLEREPLYVALUE AUTOREPLY_IDLE_WINDOWS + +#define AUTOREPLY_MAXPREFIXLEN 8000 + +#define VAL_USEDEFAULT 2 // undefined value for ignore/autoreply/notification settings in the db; must be 2 for proper ContactSettings support + +// Set Away Message dialog flags +#define DF_SAM_SHOWMSGTREE 1 +#define DF_SAM_SHOWCONTACTTREE 2 +#define DF_SAM_DEFDLGFLAGS DF_SAM_SHOWMSGTREE + +// WriteAwayMsgInDB option flags: +#define WRITE_LMSG 1 +#define WRITE_RMSG 2 +#define WRITE_INTERPRET 4 +#define WRITE_CMSG 8 + +#define TOGGLE_SOE_COMMAND LPGENT("Toggle autoreply on/off") +#define DISABLE_SOE_COMMAND LPGENT("Toggle autoreply off") +#define ENABLE_SOE_COMMAND LPGENT("Toggle autoreply on") + +#define STR_XSTATUSDESC TranslateT("extended status") + +#define MOD_NAME "NewAwaySys" +#define LOG_ID MOD_NAME // LogService log ID +#define LOG_PREFIX MOD_NAME ": " // netlib.log prefix for all NAS' messages + +#define DB_SETTINGSVER "SettingsVer" + +#ifndef lengthof +#define lengthof(s) (sizeof(s) / sizeof(*s)) +#endif + +#define MS_NETLIB_LOG "Netlib/Log" + +#define UM_ICONSCHANGED (WM_USER + 121) + +// IDD_READAWAYMSG user-defined message constants +#define UM_RAM_AWAYMSGACK (WM_USER + 10) + +// IDD_SETAWAYMSG user-defined message constants +#define UM_SAM_SPLITTERMOVED (WM_USER + 1) +#define UM_SAM_SAVEDLGSETTINGS (WM_USER + 2) +#define UM_SAM_APPLYANDCLOSE (WM_USER + 3) +#define UM_SAM_KILLTIMER (WM_USER + 4) +#define UM_SAM_REPLYSETTINGCHANGED (WM_USER + 5) +#define UM_SAM_PROTOSTATUSCHANGED (WM_USER + 6) // wParam = (char*)szProto + +#define UM_CLICK (WM_USER + 100) + +#define SAM_DB_DLGPOSX "SAMDlgPosX" +#define SAM_DB_DLGPOSY "SAMDlgPosY" +#define SAM_DB_DLGSIZEX "SAMDlgSizeX" +#define SAM_DB_DLGSIZEY "SAMDlgSizeY" +#define SAM_DB_MSGSPLITTERPOS "SAMMsgSplitterPos" +#define SAM_DB_CONTACTSPLITTERPOS "SAMContactSplitterPos" + +#define DB_MESSAGECOUNT "MessageCount" +#define DB_REQUESTCOUNT "RequestCount" +#define DB_SENDCOUNT "SendCount" +#define MESSAGES_DB_MSGTREEDEF "MsgTreeDef" + +#define MSGTREE_RECENT_OTHERGROUP _T("Other") + +// GetMsgFormat flags +#define GMF_PERSONAL 1 // is also used to get global status message, when hContact = NULL (szProto = NULL) +#define GMF_PROTOORGLOBAL 2 +#define GMF_LASTORDEFAULT 4 // this flag doesn't require hContact or szProto +#define GMF_TEMPORARY 8 // doesn't require status +#define GMF_ANYCURRENT (GMF_TEMPORARY | GMF_PERSONAL | GMF_PROTOORGLOBAL) + +// SetMsgFormat flags +#define SMF_PERSONAL 1 // is also used to set global status message, when hContact = NULL (szProto = NULL) +#define SMF_LAST 2 +#define SMF_TEMPORARY 4 // doesn't require status + +// VAR_PARSE_DATA flags +#define VPF_XSTATUS 1 // use "extended status" instead of the usual status description in %nas_statdesc%, and XStatus message in %nas_message% + +// options dialog +#define OPT_TITLE LPGENT("Away System") +#define OPT_MAINGROUP LPGEN("Status") +#define OPT_POPUPGROUP LPGEN("PopUps") + +#define MRM_MAX_GENERATED_TITLE_LEN 35 // maximum length of automatically generated title for recent messages + +int ICQStatusToGeneralStatus(int bICQStat); // TODO: get rid of these protocol-specific functions, if possible + +#define MS_AWAYSYS_SETCONTACTSTATMSG "AwaySys/SetContactStatMsg" + +#define MS_AWAYSYS_AUTOREPLY_TOGGLE "AwaySys/AutoreplyToggle" +#define MS_AWAYSYS_AUTOREPLY_ON "AwaySys/AutoreplyOn" +#define MS_AWAYSYS_AUTOREPLY_OFF "AwaySys/AutoreplyOff" +#define MS_AWAYSYS_AUTOREPLY_USEDEFAULT "AwaySys/AutoreplyUseDefault" + +#define MS_AWAYSYS_VARIABLESHANDLER "AwaySys/VariablesHandler" +#define MS_AWAYSYS_FREEVARMEM "AwaySys/FreeVarMem" +// these are obsolete AwaySysMod services, though they're still here for compatibility with old plugins +#define MS_AWAYSYS_SETSTATUSMODE "AwaySys/SetStatusMode" // change the status mode. wParam is new mode, lParam is new status message (AwaySys will interpret variables out of it), may be NULL. +#define MS_AWAYSYS_IGNORENEXT "AwaySys/IgnoreNextStatusChange" //ignore nest status change + +typedef struct SetAwayMsgData_type +{ + CString szProtocol; + HANDLE hInitContact; // initial contact (filled by caller) + TCString Message; // initial message, NULL means default + bool IsModeless; // means the dialog was created with the CreateDialogParam function, not DialogBoxParam + int ISW_Flags; // InvokeStatusWindow service flags +} SetAwayMsgData; + +typedef struct READAWAYMSGDATA_TYPE +{ + HANDLE hContact; // contact + HANDLE hSeq; // sequence for stat msg request + HANDLE hAwayMsgEvent; // hooked +} READAWAYMSGDATA; + +typedef struct +{ + char *szProto; + TCString Message; + DWORD UIN; + int Flags; // a combination of VPF_ flags +} VAR_PARSE_DATA; + +typedef struct +{ + HANDLE hContact; + int iStatusMode; + TCString Proto; +} DYNAMIC_NOTIFY_DATA; + +typedef struct +{ + BYTE PopupLClickAction, PopupRClickAction; + HANDLE hContact; + HICON hStatusIcon; // needed here to destroy its handle on UM_FREEPLUGINDATA +} PLUGIN_DATA; + +typedef struct +{ + int cbSize; + char *szProto; + HANDLE hContact; + char *szMsg; + WORD status; +} NAS_ISWINFOv1; + +#define MTYPE_AUTOONLINE 0xE7 // required to support ICQ Plus online status messages +/* +// additional m_popup.h declarations + + typedef struct + { + HANDLE lchContact; + HICON lchIcon; + WCHAR lpzContactName[MAX_CONTACTNAME]; + WCHAR lpzText[MAX_SECONDLINE]; + COLORREF colorBack; + COLORREF colorText; + WNDPROC PluginWindowProc; + void * PluginData; + int iSeconds; + char cZero[16]; + } POPUPDATAT; + + #define MS_POPUP_ADDPOPUPT MS_POPUP_ADDPOPUPW + +*/ +// Beware of conflicts between two different windows trying to use the same page at a time! +// Other windows than the owner of the Page must copy the page to their own memory, +// or use GetDBValueCopy to retrieve values +extern COptPage g_MessagesOptPage; +extern COptPage g_AutoreplyOptPage; +//extern COptPage g_PopupOptPage; +extern COptPage g_MoreOptPage; +extern COptPage g_SetAwayMsgPage; + +extern HINSTANCE g_hInstance; +extern HANDLE hMainThread; +extern int g_Messages_RecentRootID, g_Messages_PredefinedRootID; +extern VAR_PARSE_DATA VarParseData; +extern bool g_fNoProcessing; +extern int g_bIsIdle; + +// AwaySys.cpp +TCString GetDynamicStatMsg(HANDLE hContact, char *szProto = NULL, DWORD UIN = 0, int iStatus = 0); +int IsAnICQProto(char *szProto); + +// Client.cpp +void InitUpdateMsgs(); +void ChangeProtoMessages(char* szProto, int iMode, TCString &Msg); +int GetRecentGroupID(int iMode); +TCString VariablesEscape(TCString Str); + +// SetAwayMsg.cpp +INT_PTR CALLBACK SetAwayMsgDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + +// ReadAwayMsg.cpp +extern HANDLE g_hReadWndList; +INT_PTR GetContactStatMsg(WPARAM wParam, LPARAM lParam); + +// AwayOpt.cpp +int OptsDlgInit(WPARAM wParam, LPARAM lParam); // called on opening of the options dialog +void InitOptions(); // called once when plugin is loaded + +//int ShowPopupNotification(COptPage &PopupNotifyData, HANDLE hContact, int iStatusMode); +void ShowLog(TCString &LogFilePath); +void ShowMsg(TCHAR *szFirstLine, TCHAR *szSecondLine = _T(""), bool IsErrorMsg = false, int Timeout = 0); + +#define AWAYSYS_STATUSMSGREQUEST_SOUND "AwaySysStatusMsgRequest" +#define ME_AWAYSYS_WORKAROUND "AwaySys/_CallService" +int _Workaround_CallService(const char *name, WPARAM wParam, LPARAM lParam); + +// MsgEventAdded.cpp +int MsgEventAdded(WPARAM wParam, LPARAM lParam); + +// buttons +//void UpdateSOEButtons(HANDLE hContact = NULL); +INT_PTR ToggleSendOnEvent(WPARAM wParam, LPARAM lParam); +//int Create_TopToolbar(WPARAM wParam, LPARAM lParam); + + +static __inline int LogMessage(const char *Format, ...) +{ + va_list va; + char szText[8096]; + strcpy(szText, LOG_PREFIX); + va_start(va, Format); + mir_vsnprintf(szText + (lengthof(LOG_PREFIX) - 1), sizeof(szText) - (lengthof(LOG_PREFIX) - 1), Format, va); + va_end(va); + return CallService(MS_NETLIB_LOG, NULL, (LPARAM)szText); +} + +__inline int CallAllowedPS_SETAWAYMSG(const char *szProto, int iMode, const char *szMsg) +{ // we must use this function everywhere we want to call PS_SETAWAYMSG, otherwise NAS won't allow to change the message! + LogMessage("PS_SETAWAYMSG called by NAS. szProto=%s, Status=%d, Msg:\n%s", szProto, iMode, szMsg ? szMsg : "NULL"); + char str[MAXMODULELABELLENGTH]; + strcpy(str, szProto); + strcat(str, PS_SETAWAYMSG); + return CallService(str, (WPARAM)iMode, (LPARAM)szMsg); +} + +static __inline void my_variables_skin_helpbutton(HWND hwndDlg, UINT uIDButton) +{ + HICON hIcon = ServiceExists(MS_VARS_GETSKINITEM) ? (HICON)CallService(MS_VARS_GETSKINITEM, 0, (LPARAM)VSI_HELPICON) : NULL; + if (hIcon) + { + SendDlgItemMessage(hwndDlg, uIDButton, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + } +} + +static __inline int my_variables_showhelp(HWND hwndDlg, UINT uIDEdit, int flags = 0, char *szSubjectDesc = NULL, char *szExtraDesc = NULL) +{ + if (ServiceExists(MS_VARS_SHOWHELPEX)) + { + VARHELPINFO vhi = {0}; + vhi.cbSize = sizeof(VARHELPINFO); + vhi.flags = flags ? flags : (VHF_FULLDLG | VHF_SETLASTSUBJECT); + vhi.hwndCtrl = GetDlgItem(hwndDlg, uIDEdit); + vhi.szSubjectDesc = szSubjectDesc; + vhi.szExtraTextDesc = szExtraDesc; + return CallService(MS_VARS_SHOWHELPEX, (WPARAM)hwndDlg, (LPARAM)&vhi); + } else + { + ShowMsg(TranslateT("New Away System"), TranslateT("Variables plugin is not installed"), true); + return -1; + } +} diff --git a/plugins/!Deprecated/NewAwaySysMod/ContactList.cpp b/plugins/!Deprecated/NewAwaySysMod/ContactList.cpp new file mode 100644 index 0000000000..70b26d1d57 --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/ContactList.cpp @@ -0,0 +1,905 @@ +/* + New Away System - plugin for Miranda IM + Copyright (c) 2005-2007 Chervov Dmitry + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "Common.h" +#include "ContactList.h" +#include "Properties.h" + +#define INTM_CONTACTDELETED (WM_USER + 1) +#define INTM_ICONCHANGED (WM_USER + 2) +#define INTM_INVALIDATE (WM_USER + 3) + +#define HCONTACT_ISGROUP 0x80000000 +#define HCONTACT_ISINFO 0xFFFF0000 +#define IsHContactInfo(h) (((unsigned)(h) & HCONTACT_ISINFO) == HCONTACT_ISINFO) +#define IsHContactGroup(h) (!IsHContactInfo(h) && ((unsigned)(h) & HCONTACT_ISGROUP)) +#define IsHContactContact(h) (((unsigned)(h) & HCONTACT_ISGROUP) == 0) + +#define EXTRAICON_XSTEP (GetSystemMetrics(SM_CXSMICON) + 1) + +static HANDLE hCLWindowList; + + +static int CLContactDeleted(WPARAM wParam, LPARAM lParam) +{ + WindowList_Broadcast(hCLWindowList, INTM_CONTACTDELETED, wParam, lParam); + return 0; +} + +static int CLContactIconChanged(WPARAM wParam, LPARAM lParam) +{ + WindowList_Broadcast(hCLWindowList, INTM_ICONCHANGED, wParam, lParam); + return 0; +} + +static int CLIconsChanged(WPARAM wParam, LPARAM lParam) +{ + WindowList_Broadcast(hCLWindowList, INTM_INVALIDATE, 0, 0); + return 0; +} + +void LoadCListModule() +{ + hCLWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); + HookEvent(ME_DB_CONTACT_DELETED, CLContactDeleted); + HookEvent(ME_CLIST_CONTACTICONCHANGED, CLContactIconChanged); + HookEvent(ME_SKIN_ICONSCHANGED, CLIconsChanged); +} + + +static LRESULT CALLBACK ParentSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + CCList *dat = CWndUserData(hWnd).GetCList(); + switch (Msg) + { + case WM_NOTIFY: + { + LPNMHDR pnmh = (LPNMHDR)lParam; + if (pnmh->hwndFrom == dat->hTreeView) + { + switch (pnmh->code) + { + case TVN_ITEMEXPANDED: // just set an appropriate group image + { + LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam; + TVITEM tvItem; + tvItem.hItem = pnmtv->itemNew.hItem; + tvItem.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; + tvItem.iImage = tvItem.iSelectedImage = (pnmtv->itemNew.state & TVIS_EXPANDED) ? IMAGE_GROUPOPEN : IMAGE_GROUPSHUT; + TreeView_SetItem(dat->hTreeView, &tvItem); + } break; + case TVN_SELCHANGED: + { + LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam; + TREEITEMARRAY OldSelection = dat->SelectedItems; + int I; + for (I = 0; I < dat->SelectedItems.GetSize(); I++) + { + if (dat->SelectedItems[I] != pnmtv->itemNew.hItem) + { + TreeView_SetItemState(dat->hTreeView, dat->SelectedItems[I], 0, TVIS_SELECTED); + } + } + dat->SelectedItems.RemoveAll(); + if (pnmtv->itemNew.hItem) + { + dat->SelectedItems.AddElem(pnmtv->itemNew.hItem); + dat->SelectGroups(pnmtv->itemNew.hItem, true); + } + NMCLIST nm; + nm.hdr.code = MCLN_SELCHANGED; + nm.hdr.hwndFrom = dat->hTreeView; + nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); + nm.OldSelection = &OldSelection; + nm.NewSelection = &dat->SelectedItems; + SendMessage(hWnd, WM_NOTIFY, 0, (LPARAM)&nm); + } break; + case TVN_DELETEITEM: + { + if (dat->Items.GetSize()) // if Items size = 0, then this TVN_DELETEITEM came after WM_DESTROY, so there is no need to do anything + { + LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam; + TREEITEMARRAY OldSelection = dat->SelectedItems; + int Index = dat->SelectedItems.Find(pnmtv->itemOld.hItem); + if (Index != -1) + { + dat->SelectedItems.RemoveElem(Index); + } + // find an item to pass to SelectGroups() + HTREEITEM hItem = TreeView_GetNextSibling(dat->hTreeView, pnmtv->itemOld.hItem); + if (!hItem) + { + hItem = TreeView_GetPrevSibling(dat->hTreeView, pnmtv->itemOld.hItem); + if (!hItem) + { + hItem = TreeView_GetParent(dat->hTreeView, pnmtv->itemOld.hItem); + } + } + if (hItem) // if it wasn't one of the root items + { + dat->SelectGroups(hItem, dat->SelectedItems.Find(hItem) != -1); + } + NMCLIST nm; + nm.hdr.code = MCLN_SELCHANGED; + nm.hdr.hwndFrom = dat->hTreeView; + nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); + nm.OldSelection = &OldSelection; + nm.NewSelection = &dat->SelectedItems; + SendMessage(hWnd, WM_NOTIFY, 0, (LPARAM)&nm); + dat->Items[pnmtv->itemOld.lParam].hContact = INVALID_HANDLE_VALUE; + } + } break; + case NM_CUSTOMDRAW: + { + LPNMTVCUSTOMDRAW lpNMCD = (LPNMTVCUSTOMDRAW)lParam; + switch (lpNMCD->nmcd.dwDrawStage) + { + case CDDS_PREPAINT: // the control is about to start painting + { + return CDRF_NOTIFYITEMDRAW; // instruct the control to return information when it draws items + } break; + case CDDS_ITEMPREPAINT: + { + return CDRF_NOTIFYPOSTPAINT; + } break; + case CDDS_ITEMPOSTPAINT: + { + RECT rc; + if (TreeView_GetItemRect(dat->hTreeView, (HTREEITEM)lpNMCD->nmcd.dwItemSpec, &rc, false)) + { + int I; + for (I = 0; I < MAXEXTRAICONS; I++) + { + BYTE nIndex = dat->Items[lpNMCD->nmcd.lItemlParam].ExtraIcons[I]; + if (nIndex != CLC_EXTRAICON_EMPTY) + { + ImageList_DrawEx(dat->ExtraImageList, nIndex, lpNMCD->nmcd.hdc, rc.right - EXTRAICON_XSTEP * (I + 1), rc.top, 0, 0, /*GetSysColor(COLOR_WINDOW)*/CLR_NONE, CLR_NONE, ILD_NORMAL); + } + } + } + } break; + } + } break; + } + } + } + } + return CallWindowProc(dat->OrigParentProc, hWnd, Msg, wParam, lParam); +} + + +static LRESULT CALLBACK ContactListSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + CCList *dat = CWndUserData(GetParent(hWnd)).GetCList(); + switch (Msg) + { + case INTM_CONTACTDELETED: // wParam = (HANDLE)hContact + { + HTREEITEM hItem = dat->FindContact((HANDLE)wParam); + if (hItem) + { + TreeView_DeleteItem(hWnd, hItem); + } + } break; + case INTM_ICONCHANGED: // wParam = (HANDLE)hContact, lParam = IconID + { + TVITEM tvi; + tvi.hItem = dat->FindContact((HANDLE)wParam); + if (tvi.hItem) + { + tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; + tvi.iImage = tvi.iSelectedImage = lParam; + TreeView_SetItem(hWnd, &tvi); + dat->SortContacts(); + InvalidateRect(hWnd, NULL, false); + } + } break; + case INTM_INVALIDATE: + { + InvalidateRect(hWnd, NULL, true); + } break; + case WM_RBUTTONDOWN: + { + SetFocus(hWnd); + TVHITTESTINFO hitTest; + hitTest.pt.x = (short)LOWORD(lParam); + hitTest.pt.y = (short)HIWORD(lParam); + TreeView_HitTest(hWnd, &hitTest); + if (hitTest.hItem && hitTest.flags & TVHT_ONITEM) + { + TreeView_SelectItem(hWnd, hitTest.hItem); + } + return DefWindowProc(hWnd, Msg, wParam, lParam); + } break; + case WM_LBUTTONDOWN: + { + POINT pt = {(short)LOWORD(lParam), (short)HIWORD(lParam)}; + DWORD hitFlags; + HTREEITEM hItem = dat->HitTest(&pt, &hitFlags); + if (!hItem) + { + break; + } + if (hitFlags & MCLCHT_ONITEMICON) + { + if (TreeView_GetChild(hWnd, hItem)) // if it's a group, then toggle its state + { + NMTREEVIEW nmtv; + nmtv.hdr.hwndFrom = hWnd; + nmtv.hdr.idFrom = GetDlgCtrlID(hWnd); + nmtv.hdr.code = TVN_ITEMEXPANDING; + nmtv.action = TVE_TOGGLE; + nmtv.itemNew.hItem = hItem; + nmtv.itemNew.mask = TVIF_HANDLE | TVIF_STATE | TVIF_PARAM; + TreeView_GetItem(hWnd, &nmtv.itemNew); + nmtv.ptDrag = pt; + if (SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nmtv)) + { + return 0; + } + HTREEITEM hOldSelItem = TreeView_GetSelection(hWnd); + TreeView_Expand(hWnd, hItem, TVE_TOGGLE); + HTREEITEM hNewSelItem = TreeView_GetSelection(hWnd); + if (hNewSelItem != hOldSelItem) + { + TreeView_SetItemState(hWnd, hOldSelItem, (dat->SelectedItems.Find(hOldSelItem) == -1) ? 0 : TVIS_SELECTED, TVIS_SELECTED); + TreeView_SetItemState(hWnd, hNewSelItem, (dat->SelectedItems.Find(hNewSelItem) == -1) ? 0 : TVIS_SELECTED, TVIS_SELECTED); + } + nmtv.hdr.code = TVN_ITEMEXPANDED; + TreeView_GetItem(hWnd, &nmtv.itemNew); + SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nmtv); + return 0; + } + } + if (hitFlags & MCLCHT_ONITEM) + { + if (wParam & MK_CONTROL) + { + SetFocus(hWnd); + TREEITEMARRAY OldSelection = dat->SelectedItems; + int nIndex = dat->SelectedItems.Find(hItem); + if (nIndex == -1) + { + TreeView_SetItemState(hWnd, hItem, TVIS_SELECTED, TVIS_SELECTED); + dat->SelectedItems.AddElem(hItem); + } else + { + TreeView_SetItemState(hWnd, hItem, 0, TVIS_SELECTED); + dat->SelectedItems.RemoveElem(nIndex); + } + dat->SelectGroups(hItem, nIndex == -1); + NMCLIST nm; + nm.hdr.code = MCLN_SELCHANGED; + nm.hdr.hwndFrom = hWnd; + nm.hdr.idFrom = GetDlgCtrlID(hWnd); + nm.OldSelection = &OldSelection; + nm.NewSelection = &dat->SelectedItems; + SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nm); + return 0; + } else + { + if (hItem == TreeView_GetSelection(hWnd) && (dat->SelectedItems.GetSize() != 1 || (dat->SelectedItems.GetSize() == 1 && dat->SelectedItems[0] != hItem))) // if it was a click on the selected item and there's need to do something in this case, then send SELCHANGED notification by ourselves, as the tree control doesn't do anything + { + TreeView_SetItemState(hWnd, hItem, TVIS_SELECTED, TVIS_SELECTED); + NMTREEVIEW nm = {0}; + nm.hdr.code = TVN_SELCHANGED; + nm.hdr.hwndFrom = hWnd; + nm.hdr.idFrom = GetDlgCtrlID(hWnd); + nm.itemOld.hItem = TreeView_GetSelection(hWnd); + nm.itemOld.mask = TVIF_HANDLE | TVIF_STATE | TVIF_PARAM; + TreeView_GetItem(hWnd, &nm.itemOld); + nm.itemNew = nm.itemOld; + SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nm); + } + } + } + } break; + case WM_SETFOCUS: + case WM_KILLFOCUS: + { + int I; + for (I = 0; I < dat->SelectedItems.GetSize(); I++) + { + RECT rc; + if (TreeView_GetItemRect(hWnd, dat->SelectedItems[I], &rc, false)) + { + InvalidateRect(hWnd, &rc, false); + } + } + } break; + case WM_SIZE: + case WM_HSCROLL: + { + InvalidateRect(hWnd, NULL, false); + } break; + case WM_MEASUREITEM: + { + if (!wParam) // if the message was sent by a menu + { + return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); + } + } break; + case WM_DRAWITEM: + { + if (!wParam) // if the message was sent by a menu + { + return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); + } + } break; + case WM_CONTEXTMENU: + { + POINT pt; + pt.x = (short)LOWORD(lParam); + pt.y = (short)HIWORD(lParam); + HTREEITEM hItem = NULL; + if (pt.x == -1 && pt.y == -1) + { + if (dat->SelectedItems.GetSize() == 1) + { + hItem = dat->SelectedItems[0]; + TreeView_EnsureVisible(hWnd, hItem); + RECT rc; + TreeView_GetItemRect(hWnd, hItem, &rc, true); + pt.x = rc.left; + pt.y = rc.bottom; + } + } else + { + DWORD hitFlags; + ScreenToClient(hWnd, &pt); + hItem = dat->HitTest(&pt, &hitFlags); + if (!(hitFlags & MCLCHT_ONITEM)) + { + hItem = NULL; + } + } + if (hItem) + { + HANDLE hContact = dat->GetItemData(hItem).hContact; + if (IsHContactContact(hContact)) + { + HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)hContact, 0); + if (hMenu) + { + ClientToScreen(hWnd, &pt); + CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, 0, hWnd, NULL), MPCF_CONTACTMENU), (LPARAM)hContact); + DestroyMenu(hMenu); + return 0; + } + } + } + } break; + case WM_DESTROY: + { + if (dat->ExtraImageList) + { + ImageList_Destroy(dat->ExtraImageList); + } + dat->SelectedItems.RemoveAll(); + dat->Items.RemoveAll(); + } break; + } + return CallWindowProc(dat->OrigTreeViewProc, hWnd, Msg, wParam, lParam); +} + + +CCList::CCList(HWND hTreeView): hTreeView(hTreeView), ExtraImageList(NULL) +{ + CWndUserData(GetParent(hTreeView)).SetCList(this); + OrigTreeViewProc = (WNDPROC)SetWindowLongPtr(hTreeView, GWLP_WNDPROC, (LONG_PTR)ContactListSubclassProc); + OrigParentProc = (WNDPROC)SetWindowLongPtr(GetParent(hTreeView), GWLP_WNDPROC, (LONG_PTR)ParentSubclassProc); + TreeView_SetImageList(hTreeView, CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0), TVSIL_NORMAL); + WindowList_Add(hCLWindowList, hTreeView, NULL); + TreeView_SetIndent(hTreeView, 5); // doesn't set it less than the initial value on my system, and I guess it's because of icons... but who knows - maybe it will work somewhere +} + + +CCList::~CCList() +{ + WindowList_Remove(hCLWindowList, hTreeView); + _ASSERT(GetWindowLongPtr(GetParent(hTreeView), GWLP_WNDPROC) == (LONG_PTR)ParentSubclassProc); // we won't allow anyone to change our WNDPROC. otherwise we're not sure that we're setting the right WNDPROC back + SetWindowLongPtr(hTreeView, GWLP_WNDPROC, (LONG_PTR)OrigTreeViewProc); + SetWindowLongPtr(GetParent(hTreeView), GWLP_WNDPROC, (LONG_PTR)OrigParentProc); + CWndUserData(GetParent(hTreeView)).SetCList(NULL); +} + + +HTREEITEM CCList::AddContact(HANDLE hContact) +// adds a new contact if it doesn't exist yet; returns its hItem +{ + _ASSERT(IsHContactContact(hContact)); + HTREEITEM hContactItem = FindContact(hContact); + if (hContactItem) + { + return hContactItem; + } + TVINSERTSTRUCT tvIns; + ZeroMemory(&tvIns, sizeof(tvIns)); + tvIns.hParent = AddGroup(DBGetContactSettingString(hContact, "CList", "Group", _T(""))); +/* if (!tvIns.hParent) + { + return NULL; + }*/ // <- place hidden contacts in the root anyway, as otherwise we won't see icq contacts that are hidden beneath metacontacts; TODO: show metacontacts as groups?? + tvIns.item.pszText = (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR); + tvIns.hInsertAfter = TVI_ROOT; + tvIns.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; + tvIns.item.iImage = tvIns.item.iSelectedImage = CallService(MS_CLIST_GETCONTACTICON, (WPARAM)hContact, 0); + tvIns.item.lParam = Items.AddElem(CCLItemData(hContact)); + return TreeView_InsertItem(hTreeView, &tvIns); +} + + +typedef struct +{ + HANDLE hGroup; + TCString GroupName; +} sGroupEnumData; + +int GroupEnum(const char *szSetting, LPARAM lParam) +{ + sGroupEnumData *GroupEnumData = (sGroupEnumData*)lParam; + TCString GroupName = DBGetContactSettingString(NULL, "CListGroups", szSetting, _T(" ")); + if (!lstrcmp(GroupEnumData->GroupName, &GroupName[1])) + { + GroupEnumData->hGroup = (HANDLE)(atol(szSetting) | HCONTACT_ISGROUP); + } + return 0; +} + +HTREEITEM CCList::AddGroup(TCString GroupName) +// adds a new group if it doesn't exist yet; returns its hItem +{ + if (GroupName == _T("")) + { + return TVI_ROOT; + } + sGroupEnumData GroupEnumData; + GroupEnumData.GroupName = GroupName; + GroupEnumData.hGroup = NULL; + DBCONTACTENUMSETTINGS dbEnum; + ZeroMemory(&dbEnum, sizeof(dbEnum)); + dbEnum.lParam = (LPARAM)&GroupEnumData; + dbEnum.pfnEnumProc = GroupEnum; + dbEnum.szModule = "CListGroups"; + CallService(MS_DB_CONTACT_ENUMSETTINGS, NULL, (LPARAM)&dbEnum); + if (!GroupEnumData.hGroup) // means there is no such group in the groups list + { + return NULL; + } + HTREEITEM hGroupItem = FindContact(GroupEnumData.hGroup); + if (hGroupItem) + { + return hGroupItem; // exists already, just return its handle + } + TVINSERTSTRUCT tvIns = {0}; + tvIns.hParent = TVI_ROOT; + tvIns.item.pszText = _tcsrchr(GroupName, '\\'); + if (tvIns.item.pszText) + { + TCString ParentGroupName(_T("")); + tvIns.hParent = AddGroup(ParentGroupName.DiffCat(GroupName, tvIns.item.pszText)); + tvIns.item.pszText++; + } else + { + tvIns.item.pszText = GroupName; + } + tvIns.hInsertAfter = TVI_ROOT; + tvIns.item.mask = TVIF_TEXT | TVIF_STATE | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; + tvIns.item.state = tvIns.item.stateMask = TVIS_BOLD | TVIS_EXPANDED; + tvIns.item.iImage = tvIns.item.iSelectedImage = IMAGE_GROUPOPEN; + tvIns.item.lParam = Items.AddElem(CCLItemData(GroupEnumData.hGroup)); + return TreeView_InsertItem(hTreeView, &tvIns); +} + + +HTREEITEM CCList::AddInfo(TCString Title, HTREEITEM hParent, HTREEITEM hInsertAfter, LPARAM lParam, HICON hIcon) +{ + TVINSERTSTRUCT tvi = {0}; + tvi.item.mask = TVIF_TEXT | TVIF_STATE | TVIF_PARAM; + tvi.item.pszText = Title; + tvi.hParent = hParent; + tvi.hInsertAfter = hInsertAfter; + tvi.item.lParam = Items.AddElem(CCLItemData()); + Items[tvi.item.lParam].lParam = lParam; + tvi.item.state = tvi.item.stateMask = TVIS_BOLD | TVIS_EXPANDED; + if (hIcon) + { + HIMAGELIST iml = TreeView_GetImageList(hTreeView, TVSIL_NORMAL); + tvi.item.mask |= TVIF_IMAGE | TVIF_SELECTEDIMAGE; + tvi.item.iImage = tvi.item.iSelectedImage = ImageList_AddIcon(iml, hIcon); // we don't check for duplicate icons, but I think that's ok, judging that the check will require some pretty significant amount of additional coding + TreeView_SetImageList(hTreeView, iml, TVSIL_NORMAL); + } + return TreeView_InsertItem(hTreeView, &tvi); +} + + +void CCList::SetInfoIcon(HTREEITEM hItem, HICON hIcon) +{ + _ASSERT(hItem && hIcon && GetItemType(hItem) == MCLCIT_INFO); + TVITEM tvi = {0}; + tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; + tvi.hItem = hItem; + HIMAGELIST iml = TreeView_GetImageList(hTreeView, TVSIL_NORMAL); + tvi.iImage = tvi.iSelectedImage = ImageList_AddIcon(iml, hIcon); // again, we don't check for duplicate icons + TreeView_SetImageList(hTreeView, iml, TVSIL_NORMAL); + TreeView_SetItem(hTreeView, &tvi); +} + + +static int CALLBACK CompareItemsCallback(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) +{ + CCList *dat = (CCList*)lParamSort; + if (IsHContactInfo(dat->Items[lParam1].hContact)) // Info items precede all other items + { + return (IsHContactInfo(dat->Items[lParam2].hContact)) ? 0 : -1; + } else if (IsHContactInfo(dat->Items[lParam2].hContact)) + { + return 1; + } + if (IsHContactGroup(dat->Items[lParam1].hContact)) // groups precede contacts + { + if (IsHContactGroup(dat->Items[lParam2].hContact)) + { + return (unsigned)dat->Items[lParam1].hContact - (unsigned)dat->Items[lParam2].hContact; + } else + { + return -1; + } + } else if (IsHContactGroup(dat->Items[lParam2].hContact)) + { + return 1; + } + return CallService(MS_CLIST_CONTACTSCOMPARE, (WPARAM)dat->Items[lParam1].hContact, (LPARAM)dat->Items[lParam2].hContact); +} + +void CCList::SortContacts() +{ + TVSORTCB tvSort; + ZeroMemory(&tvSort, sizeof(tvSort)); + tvSort.lpfnCompare = CompareItemsCallback; + tvSort.hParent = TVI_ROOT; + tvSort.lParam = (LPARAM)this; + while (tvSort.hParent) + { + TreeView_SortChildrenCB(hTreeView, &tvSort, 0); + tvSort.hParent = GetNextItem(MCLGN_NEXT | MCLGN_GROUP | MCLGN_MULTILEVEL, tvSort.hParent); + } +} + + +int CCList::GetExtraImage(HTREEITEM hItem, int iColumn) // returns iImage, or CLC_EXTRAICON_EMPTY +{ + _ASSERT(iColumn < MAXEXTRAICONS); + return GetItemData(hItem).ExtraIcons[iColumn]; +} + + +void CCList::SetExtraImage(HTREEITEM hItem, int iColumn, int iImage) // set iImage to CLC_EXTRAICON_EMPTY to reset image +{ + _ASSERT(iColumn < MAXEXTRAICONS); + GetItemData(hItem).ExtraIcons[iColumn] = iImage; + RECT rc; + if (TreeView_GetItemRect(hTreeView, hItem, &rc, false)) + { + InvalidateRect(hTreeView, &rc, true); + } +} + + +void CCList::SetExtraImageList(HIMAGELIST hImgList) +{ + ExtraImageList = hImgList; + InvalidateRect(hTreeView, NULL, false); +} + + +int CCList::GetItemType(HTREEITEM hItem) // returns a MCLCIT_ (see below) +{ + HANDLE hContact = GetItemData(hItem).hContact; + return (IsHContactInfo(hContact)) ? MCLCIT_INFO : ((IsHContactGroup(hContact)) ? MCLCIT_GROUP : MCLCIT_CONTACT); +} + + +DWORD CCList::GetItemTypeAsCLGNFlag(HTREEITEM hItem) +{ + HANDLE hContact = GetItemData(hItem).hContact; + return (IsHContactInfo(hContact)) ? MCLGN_INFO : ((IsHContactGroup(hContact)) ? MCLGN_GROUP : MCLGN_CONTACT); +} + + +HTREEITEM CCList::GetNextItem(DWORD Flags, HTREEITEM hItem) +{ + switch (Flags & ~(MCLGN_MULTILEVEL | MCLGN_NOTCHILD | MCLGN_ANY)) + { + case MCLGN_ROOT: + { + return TreeView_GetRoot(hTreeView); + } break; + case MCLGN_LAST: + { + HTREEITEM hNextItem = TVI_ROOT; + do + { + hItem = hNextItem; + hNextItem = TreeView_GetLastChild(hTreeView, hNextItem); + } while (hNextItem); + return (hItem == TVI_ROOT) ? NULL : hItem; + } break; + case MCLGN_CHILD: + { + return TreeView_GetChild(hTreeView, hItem); + } break; + case MCLGN_LASTCHILD: + { + return TreeView_GetLastChild(hTreeView, hItem); + } break; + case MCLGN_PARENT: + { + return TreeView_GetParent(hTreeView, hItem); + } break; + case MCLGN_NEXT: + { + do + { + if (Flags & MCLGN_MULTILEVEL) + { + HTREEITEM hNextItem = NULL; + if ((Flags & MCLGN_NOTCHILD) != MCLGN_NOTCHILD) + { + hNextItem = TreeView_GetChild(hTreeView, hItem); + } + if (!hNextItem) + { + hNextItem = TreeView_GetNextSibling(hTreeView, hItem); + while (!hNextItem) // move back until we find next sibling of the item or one of its parents + { + hItem = TreeView_GetParent(hTreeView, hItem); + if (!hItem) // means it was the root, there are no items left. + { + break; // returns NULL as the next item + } + hNextItem = TreeView_GetNextSibling(hTreeView, hItem); + } + } + hItem = hNextItem; + } else + { + hItem = TreeView_GetNextSibling(hTreeView, hItem); + } + Flags &= ~(MCLGN_NOTCHILD & ~MCLGN_MULTILEVEL); // clear MCLGN_NOTCHILD flag + } while (hItem && !(Flags & GetItemTypeAsCLGNFlag(hItem))); + return hItem; + } break; + case MCLGN_PREV: + { + do + { + if (Flags & MCLGN_MULTILEVEL) + { + HTREEITEM hNextItem = TreeView_GetPrevSibling(hTreeView, hItem); + if (hNextItem) + { + if ((Flags & MCLGN_NOTCHILD) != MCLGN_NOTCHILD) + { + while (hNextItem) + { + hItem = hNextItem; + hNextItem = TreeView_GetLastChild(hTreeView, hItem); + } + } else + { + hItem = hNextItem; + } + } else + { + hItem = TreeView_GetParent(hTreeView, hItem); + } + } else + { + hItem = TreeView_GetPrevSibling(hTreeView, hItem); + } + Flags &= ~(MCLGN_NOTCHILD & ~MCLGN_MULTILEVEL); // clear MCLGN_NOTCHILD flag + } while (hItem && !(Flags & GetItemTypeAsCLGNFlag(hItem))); + return hItem; + } break; + default: + { + _ASSERT(0); + } break; + } + return NULL; +} + + +HANDLE CCList::GethContact(HTREEITEM hItem) // returns hContact, hGroup or hInfo +{ + HANDLE hContact = GetItemData(hItem).hContact; + if (IsHContactContact(hContact)) + { + return hContact; + } else if (IsHContactGroup(hContact)) + { + return (HANDLE)((int)hContact & ~HCONTACT_ISGROUP); + } else + { + return (HANDLE)((int)hContact & ~HCONTACT_ISINFO); + } +} + + +HTREEITEM CCList::HitTest(LPPOINT pt, PDWORD hitFlags) // pt is relative to control; returns hItem or NULL +{ + TVHITTESTINFO hti; + hti.pt = *pt; + TreeView_HitTest(hTreeView, &hti); + *hitFlags = 0; + if (hti.flags & TVHT_ABOVE) + { + *hitFlags |= MCLCHT_ABOVE; + } + if (hti.flags & TVHT_BELOW) + { + *hitFlags |= MCLCHT_BELOW; + } + if (hti.flags & TVHT_TOLEFT) + { + *hitFlags |= MCLCHT_TOLEFT; + } + if (hti.flags & TVHT_TORIGHT) + { + *hitFlags |= MCLCHT_TORIGHT; + } + if (hti.flags & TVHT_NOWHERE) + { + *hitFlags |= MCLCHT_NOWHERE; + } + if (hti.flags & TVHT_ONITEMINDENT) + { + *hitFlags |= MCLCHT_ONITEMINDENT; + } + if (hti.flags & (TVHT_ONITEMICON | TVHT_ONITEMSTATEICON)) + { + *hitFlags |= MCLCHT_ONITEMICON; + } + if (hti.flags & TVHT_ONITEMLABEL) + { + *hitFlags |= MCLCHT_ONITEMLABEL; + } + if (hti.flags & TVHT_ONITEMRIGHT) + { + *hitFlags |= MCLCHT_ONITEMRIGHT; + } + if (hti.flags & (TVHT_ONITEMINDENT | TVHT_ONITEM | TVHT_ONITEMRIGHT)) + { + // extraicon tests + RECT rc; + if (TreeView_GetItemRect(hTreeView, hti.hItem, &rc, false)) + { + int nIndex = (rc.right - pt->x - 1) / EXTRAICON_XSTEP; + if (nIndex >= 0 && nIndex < MAXEXTRAICONS && GetItemData(hti.hItem).ExtraIcons[nIndex] != CLC_EXTRAICON_EMPTY) + { + *hitFlags |= MCLCHT_ONITEMEXTRA | (nIndex << 24); + } + } + } + return hti.hItem; +} + + +int CCList::Array_SetItemState(HTREEITEM hItem, bool bSelected) +{ + _ASSERT(hItem); + int nIndex = SelectedItems.Find(hItem); + if (nIndex == -1 && bSelected) + { + return SelectedItems.AddElem(hItem); + } else if (nIndex != -1 && !bSelected) + { + SelectedItems.RemoveElem(nIndex); + return -1; + } + return nIndex; +} + + +CCLItemData& CCList::GetItemData(HTREEITEM hItem) +{ + _ASSERT(hItem && hItem != INVALID_HANDLE_VALUE); + TVITEM tvi; + tvi.mask = TVIF_HANDLE | TVIF_PARAM; + tvi.hItem = hItem; + int Res = TreeView_GetItem(hTreeView, &tvi); + _ASSERT(Res); + return Items[tvi.lParam]; +} + + +HTREEITEM CCList::TreeView_GetLastChild(HWND hTreeView, HTREEITEM hItem) +{ + HTREEITEM hPrevItem = TreeView_GetChild(hTreeView, hItem); + hItem = hPrevItem; + while (hItem) // find last sibling + { + hPrevItem = hItem; + hItem = TreeView_GetNextSibling(hTreeView, hPrevItem); + } + return hPrevItem; +} + + +HTREEITEM CCList::FindContact(HANDLE hContact) +{ + TVITEM tvi; + tvi.mask = TVIF_HANDLE | TVIF_PARAM; + tvi.hItem = TreeView_GetRoot(hTreeView); + while (tvi.hItem) + { + TreeView_GetItem(hTreeView, &tvi); + if (Items[tvi.lParam].hContact == hContact) + { + return tvi.hItem; + } + tvi.hItem = GetNextItem(MCLGN_NEXT | MCLGN_ANY | MCLGN_MULTILEVEL, tvi.hItem); + } + return NULL; +} + + +void CCList::SelectGroups(HTREEITEM hCurItem, bool bSelected) +{ +// select/deselect all child items + HTREEITEM hItem = TreeView_GetChild(hTreeView, hCurItem); + HTREEITEM hLimitItem = GetNextItem(MCLGN_NEXT | MCLGN_ANY | MCLGN_NOTCHILD, hCurItem); + while (hItem && hItem != hLimitItem) + { + TreeView_SetItemState(hTreeView, hItem, bSelected ? TVIS_SELECTED : 0, TVIS_SELECTED); + Array_SetItemState(hItem, bSelected); + hItem = GetNextItem(MCLGN_NEXT | MCLGN_ANY | MCLGN_MULTILEVEL, hItem); + } +// select/deselect all parent groups + hCurItem = TreeView_GetParent(hTreeView, hCurItem); + if (bSelected) + { + while (hCurItem) // select until we'll find an unselected item or until we'll reach the root + { + hItem = TreeView_GetChild(hTreeView, hCurItem); + while (hItem) // walk through all siblings + { + if (!(TreeView_GetItemState(hTreeView, hItem, TVIS_SELECTED) & TVIS_SELECTED)) + { + break; + } + hItem = TreeView_GetNextSibling(hTreeView, hItem); + } + if (hItem) // means there was at least one unselected item + { + break; + } + TreeView_SetItemState(hTreeView, hCurItem, TVIS_SELECTED, TVIS_SELECTED); + Array_SetItemState(hCurItem, true); + hCurItem = TreeView_GetParent(hTreeView, hCurItem); + } + } + while (hCurItem) // and deselect all remaining parent groups + { + TreeView_SetItemState(hTreeView, hCurItem, 0, TVIS_SELECTED); + Array_SetItemState(hCurItem, false); + hCurItem = TreeView_GetParent(hTreeView, hCurItem); + } +} diff --git a/plugins/!Deprecated/NewAwaySysMod/ContactList.h b/plugins/!Deprecated/NewAwaySysMod/ContactList.h new file mode 100644 index 0000000000..1730887954 --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/ContactList.h @@ -0,0 +1,142 @@ +/* + New Away System - plugin for Miranda IM + Copyright (c) 2005-2007 Chervov Dmitry + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// Miranda's built-in CListControl is very slow and it has too limited functionality... 8( So I had to use my own control instead. + +#pragma once + +typedef TMyArray TREEITEMARRAY; +typedef TREEITEMARRAY* PTREEITEMARRAY; + + +#define CLC_EXTRAICON_EMPTY 0xFF +#define CLC_ROOT TVI_ROOT + +#define MAXEXTRAICONS 16 + +class CCLItemData // internal CCList's class +{ +public: + CCLItemData(HANDLE hContact = INVALID_HANDLE_VALUE): hContact(hContact) {FillMemory(ExtraIcons, sizeof(ExtraIcons), CLC_EXTRAICON_EMPTY);}; + + BYTE ExtraIcons[MAXEXTRAICONS]; + HANDLE hContact; + LPARAM lParam; +}; + +typedef TMyArray TREEITEMDATAARRAY; +typedef TREEITEMDATAARRAY* PTREEITEMDATAARRAY; + +class CCList +{ +public: + CCList(HWND hTreeView); + ~CCList(); + + HTREEITEM AddContact(HANDLE hContact); + HTREEITEM AddGroup(TCString GroupName); + HTREEITEM AddInfo(TCString Title, HTREEITEM hParent, HTREEITEM hInsertAfter, LPARAM lParam = NULL, HICON hIcon = NULL); + void SetInfoIcon(HTREEITEM hItem, HICON hIcon); + int GetExtraImage(HTREEITEM hItem, int iColumn); // returns iImage, or CLC_EXTRAICON_EMPTY + void SetExtraImage(HTREEITEM hItem, int iColumn, int iImage); // set iImage to CLC_EXTRAICON_EMPTY to reset image + void SetExtraImageList(HIMAGELIST hImgList); + int GetItemType(HTREEITEM hItem); // returns a MCLCIT_ (see below) + HTREEITEM GetNextItem(DWORD Flags, HTREEITEM hItem); + void SortContacts(); + HANDLE GethContact(HTREEITEM hItem); // returns hContact, hGroup or hInfo + HTREEITEM HitTest(LPPOINT pt, PDWORD hitFlags); // pt is relative to control; returns hItem or NULL + void EnsureVisible(HTREEITEM hItem) {TreeView_EnsureVisible(hTreeView, hItem); InvalidateRect(hTreeView, NULL, false);} // sometimes horizontal scrollbar position changes too, so we must redraw extra icons - that's why here is InvalidateRect. TODO: try to find a way to invalidate it on _every_ horizontal scrollbar position change, instead of just here - unfortunately the scrollbar doesn't notify the tree control of its position change through WM_HSCROLL in some cases + int SelectItem(HTREEITEM hItem) {return TreeView_SelectItem(hTreeView, hItem);} + void SetItemParam(HTREEITEM hItem, LPARAM lParam) {GetItemData(hItem).lParam = lParam;} + LPARAM GetItemParam(HTREEITEM hItem) {return GetItemData(hItem).lParam;} + PTREEITEMARRAY GetSelection() {return &SelectedItems;} + void SetRedraw(bool bRedraw) {SendMessage(hTreeView, WM_SETREDRAW, bRedraw, 0);} + + friend LRESULT CALLBACK ParentSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); + friend LRESULT CALLBACK ContactListSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); + friend int CALLBACK CompareItemsCallback(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); + +private: + int Array_SetItemState(HTREEITEM hItem, bool bSelected); + CCLItemData& GetItemData(HTREEITEM hItem); + HTREEITEM TreeView_GetLastChild(HWND hTreeView, HTREEITEM hItem); + HTREEITEM FindContact(HANDLE hContact); // returns NULL if not found + void SelectGroups(HTREEITEM hCurItem, bool bSelected); + DWORD GetItemTypeAsCLGNFlag(HTREEITEM hItem); // returns MCLGN_CONTACT, MCLGN_GROUP or MCLGN_INFO + + HWND hTreeView; + WNDPROC OrigTreeViewProc; + WNDPROC OrigParentProc; + TREEITEMDATAARRAY Items; // array that stores info for every tree item; array items are left even if corresponding tree item was deleted, so treeitem's lParam can be used as an index of an item in this array. + TREEITEMARRAY SelectedItems; // contains HTREEITEMs of all selected items + HIMAGELIST ExtraImageList; +}; + + +// HitTest constants +#define MCLCHT_ABOVE 0x0001 // above the client area +#define MCLCHT_BELOW 0x0002 // below the client area +#define MCLCHT_TOLEFT 0x0004 // to the left of the client area +#define MCLCHT_TORIGHT 0x0008 // to the right of the client area +#define MCLCHT_NOWHERE 0x0010 // in the client area, but below the last item +#define MCLCHT_ONITEMINDENT 0x0020 // to the left of an item icon +#define MCLCHT_ONITEMICON 0x0040 +#define MCLCHT_ONITEMLABEL 0x0080 +#define MCLCHT_ONITEMRIGHT 0x0100 // in the area to the right of an item +#define MCLCHT_ONITEMEXTRA 0x0200 // on an extra icon, HIBYTE(HIWORD(hitFlags)) says which +#define MCLCHT_ONITEM (MCLCHT_ONITEMICON | MCLCHT_ONITEMLABEL) + +// item types +#define MCLCIT_GROUP 0 +#define MCLCIT_CONTACT 1 +#define MCLCIT_INFO 3 + +// GetNextItem constants +#define MCLGN_ROOT 0 +#define MCLGN_LAST 1 +#define MCLGN_CHILD 2 +#define MCLGN_LASTCHILD 3 +#define MCLGN_PARENT 4 +#define MCLGN_NEXT 5 +#define MCLGN_PREV 6 +// flags for use with MCLGN_NEXT and MCLGN_PREV: +#define MCLGN_CONTACT 0x20 // you need to specify at least one of these three! otherwise GetNextItem will not find anything +#define MCLGN_GROUP 0x40 +#define MCLGN_INFO 0x80 +#define MCLGN_ANY (MCLGN_CONTACT | MCLGN_GROUP | MCLGN_INFO) +#define MCLGN_MULTILEVEL 0x100 // walk through items of different levels too (ex.: MCLGN_NEXT | MCLGN_MULTILEVEL) +#define MCLGN_NOTCHILD (0x200 | MCLGN_MULTILEVEL) // when this flag is set, child items of specified hItem are ignored. for example, MCLGN_NEXT | MCLGN_CONTACT | MCLGN_NOTCHILD retrieves next contact that is not a child of hItem. +// GetNextItem(MCLGN_PREV | MCLGN_ALL | MCLGN_NOTCHILD, CLM_GETNEXTITEM(MCLGN_NEXT | MCLGN_ALL | MCLGN_NOTCHILD, hItem) === hItem + + +// notifications + +typedef struct +{ + NMHDR hdr; + PTREEITEMARRAY OldSelection, NewSelection; +} NMCLIST; +typedef NMCLIST* PNMCLIST; + +#define MCLN_FIRST (0U - 100U) + +#define MCLN_SELCHANGED (MCLN_FIRST - 20) // lParam = &NMCLIST; OldSelection and NewSelection contain selection info + + +void LoadCListModule(); diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/Delete.ico b/plugins/!Deprecated/NewAwaySysMod/Images/Delete.ico new file mode 100644 index 0000000000..b44da83dbc Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/Delete.ico differ diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/DisableNotify.ico b/plugins/!Deprecated/NewAwaySysMod/Images/DisableNotify.ico new file mode 100644 index 0000000000..5df846b34e Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/DisableNotify.ico differ diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/Dot.ico b/plugins/!Deprecated/NewAwaySysMod/Images/Dot.ico new file mode 100644 index 0000000000..12ffcb1997 Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/Dot.ico differ diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/EnableNotify.ico b/plugins/!Deprecated/NewAwaySysMod/Images/EnableNotify.ico new file mode 100644 index 0000000000..da4e6af1c0 Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/EnableNotify.ico differ diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/Ignore.ico b/plugins/!Deprecated/NewAwaySysMod/Images/Ignore.ico new file mode 100644 index 0000000000..1ba34d7244 Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/Ignore.ico differ diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/Indefinite.ico b/plugins/!Deprecated/NewAwaySysMod/Images/Indefinite.ico new file mode 100644 index 0000000000..fb895622ff Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/Indefinite.ico differ diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/MsgIcon.ico b/plugins/!Deprecated/NewAwaySysMod/Images/MsgIcon.ico new file mode 100644 index 0000000000..7880f71a70 Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/MsgIcon.ico differ diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/NewCat.ico b/plugins/!Deprecated/NewAwaySysMod/Images/NewCat.ico new file mode 100644 index 0000000000..c6d213b289 Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/NewCat.ico differ diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/NewMessage.ico b/plugins/!Deprecated/NewAwaySysMod/Images/NewMessage.ico new file mode 100644 index 0000000000..1ba04c8d6a Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/NewMessage.ico differ diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/SaveAsNew.ico b/plugins/!Deprecated/NewAwaySysMod/Images/SaveAsNew.ico new file mode 100644 index 0000000000..6954faa978 Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/SaveAsNew.ico differ diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/SaveMsg.ico b/plugins/!Deprecated/NewAwaySysMod/Images/SaveMsg.ico new file mode 100644 index 0000000000..e972db2923 Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/SaveMsg.ico differ diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/Settings.ico b/plugins/!Deprecated/NewAwaySysMod/Images/Settings.ico new file mode 100644 index 0000000000..ddb72fb8ca Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/Settings.ico differ diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/Status_Other.ico b/plugins/!Deprecated/NewAwaySysMod/Images/Status_Other.ico new file mode 100644 index 0000000000..922d911bbb Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/Status_Other.ico differ diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/Variables.ico b/plugins/!Deprecated/NewAwaySysMod/Images/Variables.ico new file mode 100644 index 0000000000..7fd7196664 Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/Variables.ico differ diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/off.bmp b/plugins/!Deprecated/NewAwaySysMod/Images/off.bmp new file mode 100644 index 0000000000..fcc9507634 Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/off.bmp differ diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/off.ico b/plugins/!Deprecated/NewAwaySysMod/Images/off.ico new file mode 100644 index 0000000000..0facbfa29f Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/off.ico differ diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/on.bmp b/plugins/!Deprecated/NewAwaySysMod/Images/on.bmp new file mode 100644 index 0000000000..cf7343ef31 Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/on.bmp differ diff --git a/plugins/!Deprecated/NewAwaySysMod/Images/on.ico b/plugins/!Deprecated/NewAwaySysMod/Images/on.ico new file mode 100644 index 0000000000..f236715870 Binary files /dev/null and b/plugins/!Deprecated/NewAwaySysMod/Images/on.ico differ diff --git a/plugins/!Deprecated/NewAwaySysMod/MsgEventAdded.cpp b/plugins/!Deprecated/NewAwaySysMod/MsgEventAdded.cpp new file mode 100644 index 0000000000..a8219e7bd7 --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/MsgEventAdded.cpp @@ -0,0 +1,317 @@ +/* + New Away System - plugin for Miranda IM + Copyright (C) 2005-2007 Chervov Dmitry + Copyright (C) 2004-2005 Iksaif Entertainment + Copyright (C) 2002-2003 Goblineye Entertainment + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "Common.h" +#include "Properties.h" + +// stupid compiler.. kept returning me an "INTERNAL COMPILER ERROR" on almost every line of MsgEventAdded function with Release mode and unicode enabled >:( even disabling optimization through #pragma optimize didn't help.. The only acceptable solution I found is to move this function to a separate file and to disable optimization for the whole file in the project properties. + +static struct +{ + int Status, DisableReplyCtlID, DontShowDialogCtlID; +} StatusModeList[] = { + ID_STATUS_ONLINE, IDC_REPLYDLG_DISABLE_ONL, IDC_MOREOPTDLG_DONTPOPDLG_ONL, + ID_STATUS_AWAY, IDC_REPLYDLG_DISABLE_AWAY, IDC_MOREOPTDLG_DONTPOPDLG_AWAY, + ID_STATUS_NA, IDC_REPLYDLG_DISABLE_NA, IDC_MOREOPTDLG_DONTPOPDLG_NA, + ID_STATUS_OCCUPIED, IDC_REPLYDLG_DISABLE_OCC, IDC_MOREOPTDLG_DONTPOPDLG_OCC, + ID_STATUS_DND, IDC_REPLYDLG_DISABLE_DND, IDC_MOREOPTDLG_DONTPOPDLG_DND, + ID_STATUS_FREECHAT, IDC_REPLYDLG_DISABLE_FFC, IDC_MOREOPTDLG_DONTPOPDLG_FFC, + ID_STATUS_INVISIBLE, IDC_REPLYDLG_DISABLE_INV, IDC_MOREOPTDLG_DONTPOPDLG_INV, + ID_STATUS_ONTHEPHONE, IDC_REPLYDLG_DISABLE_OTP, IDC_MOREOPTDLG_DONTPOPDLG_OTP, + ID_STATUS_OUTTOLUNCH, IDC_REPLYDLG_DISABLE_OTL, IDC_MOREOPTDLG_DONTPOPDLG_OTL +}; + + +class CAutoreplyData +{ +public: + CAutoreplyData(HANDLE hContact, TCString Reply): hContact(hContact), Reply(Reply) {} + + HANDLE hContact; + TCString Reply; +}; + + +void __cdecl AutoreplyDelayThread(void *_ad) +{ // _ad must be allocated using "new CAutoreplyData()" + CAutoreplyData *ad = (CAutoreplyData*)_ad; + _ASSERT(ad && ad->hContact && ad->Reply.GetLen()); + char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ad->hContact, 0); + if (!szProto) + { + _ASSERT(0); + return; + } + + int ReplyLen = (ad->Reply.GetLen() + 1) * (sizeof(char) + sizeof(WCHAR)); + PBYTE pBuf = (PBYTE)malloc(ReplyLen); + memcpy(pBuf, TCHAR2ANSI(ad->Reply), ad->Reply.GetLen() + 1); + memcpy(pBuf + ad->Reply.GetLen() + 1, ad->Reply, (ad->Reply.GetLen() + 1) * sizeof(WCHAR)); + CallContactService(ad->hContact, ServiceExists(CString(szProto) + PSS_MESSAGE "W") ? (PSS_MESSAGE "W") : PSS_MESSAGE, PREF_UNICODE, (LPARAM)pBuf); + + if (g_AutoreplyOptPage.GetDBValueCopy(IDC_REPLYDLG_LOGREPLY)) + { // store in the history + DBEVENTINFO dbeo = {0}; + dbeo.cbSize = sizeof(dbeo); + dbeo.eventType = EVENTTYPE_MESSAGE; + dbeo.flags = DBEF_SENT; + dbeo.szModule = szProto; + dbeo.timestamp = time(NULL); + + dbeo.cbBlob = ReplyLen; + dbeo.pBlob = pBuf; + + SleepEx(1000, true); // delay before sending the reply, as we need it to be later than the message we're replying to (without this delay, srmm puts the messages in a wrong order) + CallService(MS_DB_EVENT_ADD, (WPARAM)ad->hContact, (LPARAM)&dbeo); + } + + free(pBuf); + +/* + char *utf8Reply = mir_utf8encodeT(ad->Reply); // todo: use this instead of the code above, when 0.7 will be released + if (g_AutoreplyOptPage.GetDBValueCopy(IDC_REPLYDLG_LOGREPLY)) + { // store in the history + DBEVENTINFO dbeo = {0}; + dbeo.cbSize = sizeof(dbeo); + dbeo.eventType = EVENTTYPE_MESSAGE; + dbeo.flags = DBEF_SENT | DBEF_UTF; + dbeo.szModule = szProto; + dbeo.timestamp = time(NULL); + dbeo.cbBlob = strlen(utf8Reply); + dbeo.pBlob = utf8Reply; + CallService(MS_DB_EVENT_ADD, (WPARAM)ad->hContact, (LPARAM)&dbeo); + } + CallContactService(ad->hContact, ServiceExists(CString(szProto) + PSS_MESSAGE "W") ? (PSS_MESSAGE "W") : PSS_MESSAGE, PREF_UTF, (LPARAM)utf8Reply); + mir_free(utf8Reply); +*/ + delete ad; +} + + +int IsSRMsgWindowOpen(HANDLE hContact, int DefaultRetVal) +{ + if (ServiceExists(MS_MSG_GETWINDOWDATA)) + { + MessageWindowData mwd = {0}; + mwd.cbSize = sizeof(mwd); + MessageWindowInputData mwid = {0}; + mwid.cbSize = sizeof(mwid); + mwid.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH; + mwid.hContact = hContact; + return !CallService(MS_MSG_GETWINDOWDATA, (WPARAM)&mwid, (LPARAM)&mwd) && mwd.hwndWindow; + } else + { + return DefaultRetVal; + } +} + + +#define MAX_REPLY_TIMEDIFF 5 // maximum "age" of an event to remain unfiltered; in seconds +#define MSGWNDOPEN_UNDEFINED (-1) + +class CMetacontactEvent +{ +public: + CMetacontactEvent(HANDLE hMetaContact, DWORD timestamp, int bMsgWindowIsOpen): hMetaContact(hMetaContact), timestamp(timestamp), bMsgWindowIsOpen(bMsgWindowIsOpen) {}; + + HANDLE hMetaContact; + DWORD timestamp; + int bMsgWindowIsOpen; +}; + +TMyArray MetacontactEvents; + + +int MsgEventAdded(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE)wParam; + DBEVENTINFO *dbei = (DBEVENTINFO*)lParam; + if (!hContact) + { + return 0; + } + if (dbei->flags & DBEF_SENT || (dbei->eventType != EVENTTYPE_MESSAGE && dbei->eventType != EVENTTYPE_URL && dbei->eventType != EVENTTYPE_FILE)) + { + return 0; + } + if (time(NULL) - dbei->timestamp > MAX_REPLY_TIMEDIFF) + { // don't reply to offline messages + return 0; + } + char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + if (!szProto) + { + return 0; + } + DWORD Flags1 = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0); + if (!(Flags1 & PF1_IMSEND)) + { // don't reply to protocols that don't support outgoing messages + return 0; + } + int bMsgWindowIsOpen = MSGWNDOPEN_UNDEFINED; + if (dbei->flags & DBEF_READ) + { + HANDLE hMetaContact; + if (ServiceExists(MS_MC_GETMETACONTACT) && (hMetaContact = (HANDLE)CallService(MS_MC_GETMETACONTACT, (WPARAM)hContact, 0))) // if it's a subcontact of a metacontact + { // ugly workaround for metacontacts, part II + // remove outdated events first + DWORD CurTime = time(NULL); + int I; + for (I = MetacontactEvents.GetSize() - 1; I >= 0; I--) + { + if (CurTime - MetacontactEvents[I].timestamp > MAX_REPLY_TIMEDIFF) + { + MetacontactEvents.RemoveElem(I); + } + } + // we compare only event timestamps, and do not look at the message itself. it's unlikely that there'll be two events from a contact at the same second, so it's a trade-off between speed and reliability + for (I = MetacontactEvents.GetSize() - 1; I >= 0; I--) + { + if (MetacontactEvents[I].timestamp == dbei->timestamp && MetacontactEvents[I].hMetaContact == hMetaContact) + { + bMsgWindowIsOpen = MetacontactEvents[I].bMsgWindowIsOpen; + break; + } + } + if (I < 0) + { + _ASSERT(0); + return 0; + } + } else + { + return 0; + } + } + if (ServiceExists(MS_MC_GETPROTOCOLNAME) && !lstrcmpA(szProto, (char*)CallService(MS_MC_GETPROTOCOLNAME, 0, 0))) + { // ugly workaround for metacontacts, part I; store all metacontacts' events to a temporary array, so we'll be able to get the 'source' protocol when subcontact event happens later. we need the protocol to get its status and per-status settings properly + // remove outdated events first + DWORD CurTime = time(NULL); + int I; + for (I = MetacontactEvents.GetSize() - 1; I >= 0; I--) + { + if (CurTime - MetacontactEvents[I].timestamp > MAX_REPLY_TIMEDIFF) + { + MetacontactEvents.RemoveElem(I); + } + } + // add the new event and wait for a subcontact's event + MetacontactEvents.AddElem(CMetacontactEvent(hContact, dbei->timestamp, IsSRMsgWindowOpen(hContact, false))); + return 0; + } + unsigned int iMode = CallProtoService(szProto, PS_GETSTATUS, 0, 0); + int I; + for (I = lengthof(StatusModeList) - 1; I >= 0; I--) + { + if (iMode == StatusModeList[I].Status) + { + break; + } + } + if (I < 0) + { + return 0; + } + COptPage AutoreplyOptData(g_AutoreplyOptPage); + AutoreplyOptData.DBToMem(); + if (dbei->eventType == EVENTTYPE_MESSAGE) + { + DBWriteContactSettingWord(hContact, MOD_NAME, DB_MESSAGECOUNT, DBGetContactSettingWord(hContact, MOD_NAME, DB_MESSAGECOUNT, 0) + 1); // increment message counter + } + if (AutoreplyOptData.GetValue(StatusModeList[I].DisableReplyCtlID)) + { + return 0; + } + HANDLE hContactForSettings = hContact; // used to take into account not-on-list contacts when getting contact settings, but at the same time allows to get correct contact info for contacts that are in the DB + if (hContactForSettings != INVALID_HANDLE_VALUE && DBGetContactSettingByte(hContactForSettings, "CList", "NotOnList", 0)) + { + hContactForSettings = INVALID_HANDLE_VALUE; // INVALID_HANDLE_VALUE means the contact is not-on-list + } + if (!CContactSettings(iMode, hContactForSettings).Autoreply.IncludingParents(szProto) || CContactSettings(iMode, hContactForSettings).Ignore) + { + return 0; + } + if (AutoreplyOptData.GetValue(IDC_REPLYDLG_DONTREPLYINVISIBLE)) + { + WORD ApparentMode = DBGetContactSettingWord(hContact, szProto, "ApparentMode", 0); + if ((iMode == ID_STATUS_INVISIBLE && (!(Flags1 & PF1_INVISLIST) || ApparentMode != ID_STATUS_ONLINE)) || + (Flags1 & PF1_VISLIST && ApparentMode == ID_STATUS_OFFLINE)) + { + return 0; + } + } + if (AutoreplyOptData.GetValue(IDC_REPLYDLG_ONLYCLOSEDDLGREPLY)) + { + if (bMsgWindowIsOpen && bMsgWindowIsOpen != MSGWNDOPEN_UNDEFINED) + { + return 0; + } + // we never get here for a metacontact; we did check for metacontact's window earlier, and here we need to check only for subcontact's window + if (IsSRMsgWindowOpen(hContact, false)) + { + return 0; + } + } + if (AutoreplyOptData.GetValue(IDC_REPLYDLG_ONLYIDLEREPLY) && !g_bIsIdle) + { + return 0; + } + int UIN = 0; + if (IsAnICQProto(szProto)) + { + UIN = DBGetContactSettingDword(hContact, szProto, "UIN", 0); + } + int SendCount = AutoreplyOptData.GetValue(IDC_REPLYDLG_SENDCOUNT); + if ((AutoreplyOptData.GetValue(IDC_REPLYDLG_DONTSENDTOICQ) && UIN) || // an icq contact + (SendCount != -1 && DBGetContactSettingByte(hContact, MOD_NAME, DB_SENDCOUNT, 0) >= SendCount)) + { + return 0; + } + if ((dbei->eventType == EVENTTYPE_MESSAGE && !AutoreplyOptData.GetValue(IDC_REPLYDLG_EVENTMSG)) || (dbei->eventType == EVENTTYPE_URL && !AutoreplyOptData.GetValue(IDC_REPLYDLG_EVENTURL)) || (dbei->eventType == EVENTTYPE_FILE && !AutoreplyOptData.GetValue(IDC_REPLYDLG_EVENTFILE))) + { + return 0; + } + DBWriteContactSettingByte(hContact, MOD_NAME, DB_SENDCOUNT, DBGetContactSettingByte(hContact, MOD_NAME, DB_SENDCOUNT, 0) + 1); + GetDynamicStatMsg(hContact); // it updates VarParseData.Message needed for %extratext% in the format + TCString Reply(*(TCString*)AutoreplyOptData.GetValue(IDC_REPLYDLG_PREFIX)); + if (Reply != NULL && ServiceExists(MS_VARS_FORMATSTRING) && !g_SetAwayMsgPage.GetDBValueCopy(IDS_SAWAYMSG_DISABLEVARIABLES)) + { + FORMATINFO fi = {0}; + fi.cbSize = sizeof(FORMATINFO); + fi.tszFormat = Reply; + fi.hContact = hContact; + fi.flags = FIF_TCHAR; + fi.tszExtraText = VarParseData.Message; + TCHAR *szResult = (TCHAR *)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0); + if (szResult != NULL) + { + Reply = szResult; + CallService(MS_VARS_FREEMEMORY, (WPARAM)szResult, 0); + } + } + if (Reply.GetLen()) + { + CAutoreplyData *ad = new CAutoreplyData(hContact, Reply); + mir_forkthread(AutoreplyDelayThread, ad); + } + return 0; +} + diff --git a/plugins/!Deprecated/NewAwaySysMod/MsgTree.cpp b/plugins/!Deprecated/NewAwaySysMod/MsgTree.cpp new file mode 100644 index 0000000000..c04665d33f --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/MsgTree.cpp @@ -0,0 +1,790 @@ +/* + New Away System - plugin for Miranda IM + Copyright (c) 2005-2007 Chervov Dmitry + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "Common.h" +#include "MsgTree.h" +#include "Properties.h" + +#define UM_MSGTREE_INIT (WM_USER + 0x2103) +#define UM_MSGTREE_UPDATE (WM_USER + 0x2104) + +#define MSGTREE_TIMER_ID 0x2103 +#define MSGTREE_DRAGANDDROP_GROUPEXPANDTIME 600 + +#define IMGLIST_NEWMESSAGE 0 +#define IMGLIST_NEWCATEGORY 1 +#define IMGLIST_DELETE 2 + +struct { + int DBSetting, Status, MenuItemID; +} StatusModeList[] = { + IDS_MESSAGEDLG_DEF_ONL, ID_STATUS_ONLINE, IDR_MSGTREEMENU_DEF_ONL, + IDS_MESSAGEDLG_DEF_AWAY, ID_STATUS_AWAY, IDR_MSGTREEMENU_DEF_AWAY, + IDS_MESSAGEDLG_DEF_NA, ID_STATUS_NA, IDR_MSGTREEMENU_DEF_NA, + IDS_MESSAGEDLG_DEF_OCC, ID_STATUS_OCCUPIED, IDR_MSGTREEMENU_DEF_OCC, + IDS_MESSAGEDLG_DEF_DND, ID_STATUS_DND, IDR_MSGTREEMENU_DEF_DND, + IDS_MESSAGEDLG_DEF_FFC, ID_STATUS_FREECHAT, IDR_MSGTREEMENU_DEF_FFC, + IDS_MESSAGEDLG_DEF_INV, ID_STATUS_INVISIBLE, IDR_MSGTREEMENU_DEF_INV, + IDS_MESSAGEDLG_DEF_OTP, ID_STATUS_ONTHEPHONE, IDR_MSGTREEMENU_DEF_OTP, + IDS_MESSAGEDLG_DEF_OTL, ID_STATUS_OUTTOLUNCH, IDR_MSGTREEMENU_DEF_OTL +}; + +static HANDLE hMTWindowList; +static WNDPROC g_OrigEditProc; + + +void LoadMsgTreeModule() +{ + hMTWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); +} + + +static LRESULT CALLBACK EditSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + switch (Msg) + { + case WM_GETDLGCODE: + { + return CallWindowProc(g_OrigEditProc, hWnd, Msg, wParam, lParam) | DLGC_WANTALLKEYS; + } break; + } + return CallWindowProc(g_OrigEditProc, hWnd, Msg, wParam, lParam); +} + +static LRESULT CALLBACK ParentSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + CMsgTree *dat = CWndUserData(hWnd).GetMsgTree(); + switch (Msg) + { + case WM_NOTIFY: + { + if (((LPNMHDR)lParam)->hwndFrom == dat->hTreeView) + { + switch (((LPNMHDR)lParam)->code) + { + case TVN_BEGINDRAGA: + case TVN_BEGINDRAGW: + { + LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam; + NMMSGTREE nm = {0}; + COptItem_TreeCtrl *TreeCtrl = dat->GetTreeCtrl(); + int Order = TreeCtrl->hItemToOrder(pnmtv->itemNew.hItem); + _ASSERT(Order != -1); + if (Order != -1) + { + nm.ItemOld = (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; + nm.hdr.code = MTN_BEGINDRAG; + nm.hdr.hwndFrom = dat->hTreeView; + nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); + if (!SendMessage(hWnd, WM_NOTIFY, 0, (LPARAM)&nm)) + { + SetCapture(hWnd); + dat->hPrevDropTarget = dat->hDragItem = pnmtv->itemNew.hItem; + SetFocus(dat->hTreeView); + TreeView_SelectItem(dat->hTreeView, dat->hDragItem); + } + } + } break; + case TVN_SELCHANGEDA: + case TVN_SELCHANGEDW: + { + if (dat->UpdateLock) + { + return 0; + } + LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam; + NMMSGTREE nm = {0}; + COptItem_TreeCtrl *TreeCtrl = dat->GetTreeCtrl(); + if (pnmtv->itemOld.hItem) + { + int Order = TreeCtrl->IDToOrder(pnmtv->itemOld.lParam); + if (Order != -1) + { + nm.ItemOld = (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; + } + } + if (pnmtv->itemNew.hItem) + { + int Order = TreeCtrl->IDToOrder(pnmtv->itemNew.lParam); + if (Order != -1) + { + nm.ItemNew = (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; + } + } + nm.hdr.code = MTN_SELCHANGED; + nm.hdr.hwndFrom = dat->hTreeView; + nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); + SendMessage(hWnd, WM_NOTIFY, 0, (LPARAM)&nm); + } break; + case TVN_BEGINLABELEDITA: + case TVN_BEGINLABELEDITW: + { + if (dat->GetTreeCtrl()->IDToOrder(((LPNMTVDISPINFO)lParam)->item.lParam) < 0) + { + return true; // cancel editing + } + g_OrigEditProc = (WNDPROC)SetWindowLongPtr(TreeView_GetEditControl(dat->hTreeView), GWLP_WNDPROC, (LONG_PTR)EditSubclassProc); + } break; +// case TVN_ENDLABELEDITA: // stupid miranda options.. how am I supposed to get ptvdi->item.pszText if it's in ANSI?? + case TVN_ENDLABELEDIT: + { + LPNMTVDISPINFO ptvdi = (LPNMTVDISPINFO)lParam; + if (ptvdi->item.pszText) + { + COptItem_TreeCtrl *TreeCtrl = dat->GetTreeCtrl(); + int Order = TreeCtrl->IDToOrder(ptvdi->item.lParam); + if (Order >= 0) + { + TreeCtrl->Value[Order].Title = ptvdi->item.pszText; + TreeCtrl->SetModified(true); + NMMSGTREE nm = {0}; + nm.ItemNew = &TreeCtrl->Value[Order]; + nm.hdr.code = MTN_ITEMRENAMED; + nm.hdr.hwndFrom = dat->hTreeView; + nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); + SendMessage(GetParent(dat->hTreeView), WM_NOTIFY, 0, (LPARAM)&nm); + return true; // commit new text + } + } + } break; + case NM_CLICK: + case NM_RCLICK: + { + TVHITTESTINFO hitTest; + hitTest.pt.x = (short)LOWORD(GetMessagePos()); + hitTest.pt.y = (short)HIWORD(GetMessagePos()); + ScreenToClient(dat->hTreeView, &hitTest.pt); + TreeView_HitTest(dat->hTreeView, &hitTest); + if (hitTest.hItem) + { + if (TreeView_GetSelection(dat->hTreeView) == hitTest.hItem) + { // make sure TVN_SELCHANGED notification is sent always, even if previous selected item was the same as new + TreeView_SelectItem(dat->hTreeView, NULL); + } + TreeView_SelectItem(dat->hTreeView, hitTest.hItem); + } + } break; + case NM_CUSTOMDRAW: + { + NMTVCUSTOMDRAW *lpNMCD = (NMTVCUSTOMDRAW*)lParam; + switch (lpNMCD->nmcd.dwDrawStage) + { + case CDDS_PREPAINT: // the control is about to start painting + { + return CDRF_NOTIFYITEMDRAW; // instruct the control to return information when it draws items + } break; + case CDDS_ITEMPREPAINT: + { + return CDRF_NOTIFYPOSTPAINT; + } break; + case CDDS_ITEMPOSTPAINT: + { + RECT rc; + TreeView_GetItemRect(lpNMCD->nmcd.hdr.hwndFrom, (HTREEITEM)lpNMCD->nmcd.dwItemSpec, &rc, true); + int iSize = GetSystemMetrics(SM_CXSMICON); + int I; + int x = rc.left - iSize - 5; + for (I = 0; I < lengthof(StatusModeList); I++) + { + if (lpNMCD->nmcd.lItemlParam == dat->MsgTreePage.GetValue(StatusModeList[I].DBSetting)) + { + DrawIconEx(lpNMCD->nmcd.hdc, x, rc.top, LoadSkinnedProtoIcon(NULL, StatusModeList[I].Status), iSize, iSize, 0, GetSysColorBrush(COLOR_WINDOW), DI_NORMAL); + x -= iSize + 1; + } +/* if (lpNMCD->nmcd.lItemlParam == GetRecentGroupID(StatusModeList[I].Status)) + { + DrawIconEx(lpNMCD->nmcd.hdc, 3, rc.top, LoadSkinnedProtoIcon(NULL, StatusModeList[I].Status), iSize, iSize, 0, GetSysColorBrush(COLOR_WINDOW), DI_NORMAL); + }*/ + } + } break; + } + } break; + } + } + } break; + case WM_MOUSEMOVE: + { + if (dat->hDragItem) + { + TVHITTESTINFO hti; + hti.pt.x = (short)LOWORD(lParam); + hti.pt.y = (short)HIWORD(lParam); + ClientToScreen(hWnd, &hti.pt); + ScreenToClient(dat->hTreeView, &hti.pt); + TreeView_HitTest(dat->hTreeView, &hti); + if (hti.hItem) + { + TreeView_SelectDropTarget(dat->hTreeView, hti.hItem); + SetTimer(hWnd, MSGTREE_TIMER_ID, MSGTREE_DRAGANDDROP_GROUPEXPANDTIME, NULL); + } else + { + if (hti.flags & TVHT_ABOVE) + { + SendMessage(dat->hTreeView, WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), 0); + } + if (hti.flags & TVHT_BELOW) + { + SendMessage(dat->hTreeView, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0); + } + TreeView_SelectDropTarget(dat->hTreeView, NULL); + KillTimer(hWnd, MSGTREE_TIMER_ID); + } + } + } break; + case WM_LBUTTONUP: + { + if (dat->hDragItem) + { + TreeView_SelectDropTarget(dat->hTreeView, NULL); + KillTimer(hWnd, MSGTREE_TIMER_ID); + ReleaseCapture(); + TVHITTESTINFO hti; + hti.pt.x = (short)LOWORD(lParam); + hti.pt.y = (short)HIWORD(lParam); + ClientToScreen(hWnd, &hti.pt); + ScreenToClient(dat->hTreeView, &hti.pt); + TreeView_HitTest(dat->hTreeView, &hti); + if (hti.hItem && dat->hDragItem != hti.hItem) + { + NMMSGTREE nm = {0}; + COptItem_TreeCtrl *TreeCtrl = dat->GetTreeCtrl(); + int OrderOld = TreeCtrl->hItemToOrder(dat->hDragItem); + int OrderNew = TreeCtrl->hItemToOrder(hti.hItem); + _ASSERT(OrderOld != -1 && OrderNew != -1); + nm.ItemOld = (OrderOld <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(OrderOld)] : (CBaseTreeItem*)&TreeCtrl->Value[OrderOld]; + nm.ItemNew = (OrderNew <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(OrderNew)] : (CBaseTreeItem*)&TreeCtrl->Value[OrderNew]; + nm.hdr.code = MTN_ENDDRAG; + nm.hdr.hwndFrom = dat->hTreeView; + nm.hdr.idFrom = GetDlgCtrlID(dat->hTreeView); + if (!SendMessage(hWnd, WM_NOTIFY, 0, (LPARAM)&nm)) + { + dat->UpdateLock++; + dat->GetTreeCtrl()->MoveItem(hWnd, dat->hDragItem, hti.hItem); + dat->UpdateLock--; + } + } + dat->hDragItem = NULL; + } + } break; + case WM_TIMER: + { + if (wParam == MSGTREE_TIMER_ID) + { + KillTimer(hWnd, MSGTREE_TIMER_ID); + TVHITTESTINFO hti; + hti.pt.x = (short)LOWORD(GetMessagePos()); + hti.pt.y = (short)HIWORD(GetMessagePos()); + ScreenToClient(dat->hTreeView, &hti.pt); + TreeView_HitTest(dat->hTreeView, &hti); + if (hti.hItem && dat->hDragItem != hti.hItem && TreeView_GetChild(dat->hTreeView, hti.hItem)) // target is a group and is not the same item that we're dragging + { + TreeView_Expand(dat->hTreeView, hti.hItem, TVE_EXPAND); + } + } + } break; + } + return CallWindowProc(dat->OrigParentProc, hWnd, Msg, wParam, lParam); +} + + +static LRESULT CALLBACK MsgTreeSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + CMsgTree *dat = CWndUserData(GetParent(hWnd)).GetMsgTree(); + switch (Msg) + { + case UM_MSGTREE_UPDATE: // returns TRUE if updated + { + bool Modified = dat->MsgTreePage.GetModified(); + TCString WndTitle; + if (Modified) + { + WndTitle.GetBuffer(256); + HWND hCurWnd = hWnd; + do + { + hCurWnd = GetParent(hCurWnd); + } while (hCurWnd && !GetWindowText(hCurWnd, WndTitle, 256)); + WndTitle.ReleaseBuffer(); + } + if (!Modified || MessageBox(GetParent(hWnd), TCString(TranslateT("You've made changes to multiple Message trees at a time.\r\nDo you want to leave changes in \"")) + WndTitle + TranslateT("\" dialog?\r\nPress Yes to leave changes in this dialog, or No to discard its changes and save changes of the other Message tree instead."), WndTitle + _T(" - ") + TranslateT("New Away System"), MB_ICONQUESTION | MB_YESNO) == IDNO) + { + COptItem_TreeCtrl *TreeCtrl = dat->GetTreeCtrl(); + TCString OldTitle, OldMsg, NewTitle, NewMsg; + int OldOrder = TreeCtrl->IDToOrder(TreeCtrl->GetSelectedItemID(GetParent(hWnd))); + if (OldOrder != -1) + { + CBaseTreeItem* ItemOld = (OldOrder <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(OldOrder)] : (CBaseTreeItem*)&TreeCtrl->Value[OldOrder]; + OldTitle = ItemOld->Title; + if (!(ItemOld->Flags & TIF_ROOTITEM)) + { + OldMsg = ((CTreeItem*)ItemOld)->User_Str1; + } + } + dat->UpdateLock++; + dat->MsgTreePage.DBToMemToPage(); + dat->UpdateLock--; + NMMSGTREE nm = {0}; + int Order = TreeCtrl->IDToOrder(TreeCtrl->GetSelectedItemID(GetParent(hWnd))); + if (Order != -1) + { + nm.ItemNew = (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; + NewTitle = nm.ItemNew->Title; + if (!(nm.ItemNew->Flags & TIF_ROOTITEM)) + { + NewMsg = ((CTreeItem*)nm.ItemNew)->User_Str1; + } + } + if (OldTitle.IsEmpty()) + { + OldTitle = _T(""); // to be sure that NULL will be equal to "" in the latter comparisons + } + if (OldMsg.IsEmpty()) + { + OldMsg = _T(""); + } + if (NewTitle.IsEmpty()) + { + NewTitle = _T(""); + } + if (NewMsg.IsEmpty()) + { + NewMsg = _T(""); + } + if (OldTitle != (const TCHAR*)NewTitle || OldMsg != (const TCHAR*)NewMsg) + { + // probably it's better to leave nm.ItemOld = NULL, to prevent accidental rewriting of it with old data from an edit control etc. + nm.hdr.code = MTN_SELCHANGED; + nm.hdr.hwndFrom = hWnd; + nm.hdr.idFrom = GetDlgCtrlID(hWnd); + SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nm); + } + return true; + } + return false; + } break; + case WM_KEYDOWN: + { + switch (wParam) + { + case VK_DELETE: + { + dat->DeleteSelectedItem(); + } break; + case VK_INSERT: + { + dat->AddMessage(); + } break; + } + } break; + case WM_RBUTTONDOWN: + { + SetFocus(hWnd); + TVHITTESTINFO hitTest; + hitTest.pt.x = (short)LOWORD(lParam); + hitTest.pt.y = (short)HIWORD(lParam); + TreeView_HitTest(hWnd, &hitTest); + if (hitTest.hItem && hitTest.flags & TVHT_ONITEM) + { + TreeView_SelectItem(hWnd, hitTest.hItem); + } + return DefWindowProc(hWnd, Msg, wParam, lParam); + } break; + case WM_CONTEXTMENU: + { + TVHITTESTINFO ht; + ht.pt.x = (short)LOWORD(lParam); + ht.pt.y = (short)HIWORD(lParam); + TVITEM tvi = {0}; + if (ht.pt.x == -1 && ht.pt.y == -1) // use selected item + { + if (tvi.hItem = TreeView_GetSelection(hWnd)) + { + TreeView_EnsureVisible(hWnd, tvi.hItem); + RECT rc; + TreeView_GetItemRect(hWnd, tvi.hItem, &rc, true); + ht.pt.x = rc.left; + ht.pt.y = rc.bottom; + } + } else + { + ScreenToClient(hWnd, &ht.pt); + TreeView_HitTest(hWnd, &ht); + if (ht.hItem && ht.flags & TVHT_ONITEM) + { + tvi.hItem = ht.hItem; + } + } + if (tvi.hItem) + { + COptItem_TreeCtrl *TreeCtrl = dat->GetTreeCtrl(); + tvi.mask = TVIF_HANDLE | TVIF_PARAM; + TreeView_GetItem(hWnd, &tvi); + int Order = TreeCtrl->IDToOrder(tvi.lParam); + if (Order >= 0) + { + HMENU hMenu; + if (TreeCtrl->Value[Order].Flags & TIF_GROUP) + { + hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_MSGTREE_CATEGORYMENU)); + } else + { + hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_MSGTREE_MESSAGEMENU)); + } + _ASSERT(hMenu); + HMENU hPopupMenu = GetSubMenu(hMenu, 0); + TranslateMenu(hPopupMenu); + ClientToScreen(hWnd, &ht.pt); + struct + { + int ItemID, IconID; + } MenuItems[] = { + IDM_MSGTREEMENU_NEWMESSAGE, IMGLIST_NEWMESSAGE, + IDM_MSGTREEMENU_NEWCATEGORY, IMGLIST_NEWCATEGORY, + IDM_MSGTREEMENU_DELETE, IMGLIST_DELETE + }; + MENUITEMINFO mii = {0}; + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_BITMAP | MIIM_DATA | MIIM_STATE | MIIM_CHECKMARKS; + mii.hbmpItem = HBMMENU_CALLBACK; + int I; + for (I = 0; I < lengthof(MenuItems); I++) // set icons + { + mii.dwItemData = MenuItems[I].IconID; + SetMenuItemInfo(hPopupMenu, MenuItems[I].ItemID, false, &mii); + } + mii.fMask = MIIM_STATE; + mii.fState = MFS_CHECKED; + for (I = 0; I < lengthof(StatusModeList); I++) // set checkmarks + { + if (TreeCtrl->Value[Order].ID == dat->MsgTreePage.GetValue(StatusModeList[I].DBSetting)) + { + SetMenuItemInfo(hPopupMenu, StatusModeList[I].MenuItemID, false, &mii); + } + } + int MenuResult = TrackPopupMenu(hPopupMenu, TPM_RIGHTBUTTON | TPM_RETURNCMD, ht.pt.x, ht.pt.y, 0, hWnd, NULL); + switch (MenuResult) + { + case IDM_MSGTREEMENU_NEWMESSAGE: + { + dat->AddMessage(); + } break; + case IDM_MSGTREEMENU_NEWCATEGORY: + { + dat->AddCategory(); + } break; + case IDM_MSGTREEMENU_RENAME: + { + TreeView_EditLabel(hWnd, tvi.hItem); + } break; + case IDM_MSGTREEMENU_DELETE: + { + dat->DeleteSelectedItem(); + } break; + case IDR_MSGTREEMENU_DEF_ONL: + case IDR_MSGTREEMENU_DEF_AWAY: + case IDR_MSGTREEMENU_DEF_NA: + case IDR_MSGTREEMENU_DEF_OCC: + case IDR_MSGTREEMENU_DEF_DND: + case IDR_MSGTREEMENU_DEF_FFC: + case IDR_MSGTREEMENU_DEF_INV: + case IDR_MSGTREEMENU_DEF_OTP: + case IDR_MSGTREEMENU_DEF_OTL: + { + int I; + for (I = 0; I < lengthof(StatusModeList); I++) + { + if (StatusModeList[I].MenuItemID == MenuResult) + { + dat->SetDefMsg(StatusModeList[I].Status, tvi.lParam); + break; + } + } + } break; + } + DestroyMenu(hMenu); + return 0; + } + } + } break; + case WM_MEASUREITEM: + { + LPMEASUREITEMSTRUCT lpmi = (LPMEASUREITEMSTRUCT)lParam; + if (lpmi->CtlType == ODT_MENU) + { + lpmi->itemWidth = max(0, GetSystemMetrics(SM_CXSMICON) - GetSystemMetrics(SM_CXMENUCHECK) + 4); + lpmi->itemHeight = GetSystemMetrics(SM_CYSMICON) + 2; + return true; + } + } break; + case WM_DRAWITEM: + { + LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lParam; + if (dis->CtlType == ODT_MENU) + { + ImageList_DrawEx(dat->hImageList, dis->itemData, dis->hDC, 2, (dis->rcItem.bottom + dis->rcItem.top - GetSystemMetrics(SM_CYSMICON)) / 2 + 1, 0, 0, GetSysColor(COLOR_WINDOW), CLR_NONE, ILD_NORMAL); + return true; + } + } break; + } + return CallWindowProc(dat->OrigTreeViewProc, hWnd, Msg, wParam, lParam); +} + + +CMsgTree::CMsgTree(HWND hTreeView): MsgTreePage(g_MsgTreePage), hTreeView(hTreeView), hDragItem(NULL), hPrevDropTarget(NULL), UpdateLock(0) +{ + CWndUserData(GetParent(hTreeView)).SetMsgTree(this); + OrigParentProc = (WNDPROC)SetWindowLongPtr(GetParent(hTreeView), GWLP_WNDPROC, (LONG_PTR)ParentSubclassProc); + OrigTreeViewProc = (WNDPROC)SetWindowLongPtr(hTreeView, GWLP_WNDPROC, (LONG_PTR)MsgTreeSubclassProc); + MsgTreePage.SetWnd(GetParent(hTreeView)); + COptItem_TreeCtrl* TreeCtrl = (COptItem_TreeCtrl*)MsgTreePage.Find(IDV_MSGTREE); + TreeCtrl->SetDlgItemID(GetDlgCtrlID(hTreeView)); + hImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), (IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR16) | ILC_MASK, 5, 2); + ImageList_AddIcon(hImageList, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_NEWMESSAGE))); + ImageList_AddIcon(hImageList, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_NEWCATEGORY))); + ImageList_AddIcon(hImageList, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_DELETE))); + MsgTreePage.DBToMemToPage(); + if (!g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_RECENTMSGSCOUNT)) + { // show "Recent messages" group only when RECENTMSGSCOUNT is not set to 0. + TreeView_DeleteItem(hTreeView, TreeCtrl->RootItems[g_Messages_RecentRootID].hItem); + } + WindowList_Add(hMTWindowList, hTreeView, NULL); +} + +CMsgTree::~CMsgTree() +{ + _ASSERT(GetWindowLongPtr(GetParent(hTreeView), GWLP_WNDPROC) == (LONG_PTR)ParentSubclassProc); // we won't allow anyone to change our WNDPROC. otherwise we're not sure that we're setting the right WNDPROC back + SetWindowLongPtr(hTreeView, GWLP_WNDPROC, (GetWindowLongPtr(GetParent(hTreeView), GWLP_WNDPROC) == (LONG_PTR)ParentSubclassProc) ? (LONG_PTR)OrigTreeViewProc : (LONG_PTR)DefDlgProc); // yeah, if that crazy Help plugin substituted MY WndProc again, he won't get his WndProc back.. he-he >:) + SetWindowLongPtr(GetParent(hTreeView), GWLP_WNDPROC, (LONG_PTR)OrigParentProc); + CWndUserData(GetParent(hTreeView)).SetMsgTree(NULL); + WindowList_Remove(hMTWindowList, hTreeView); + ImageList_Destroy(hImageList); +} + +CBaseTreeItem* CMsgTree::GetSelection() // returns NULL if there's nothing selected +{ + COptItem_TreeCtrl *TreeCtrl = GetTreeCtrl(); + int Order = TreeCtrl->IDToOrder(TreeCtrl->GetSelectedItemID(GetParent(hTreeView))); + if (Order != -1) + { + return (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; + } + return NULL; +} + +bool CMsgTree::SetSelection(int ID, int Flags) // set ID = -1 to unselect; returns TRUE on unselect and on successful select +{ + COptItem_TreeCtrl *TreeCtrl = GetTreeCtrl(); + int Order = (Flags & MTSS_BYORDER) ? ID : TreeCtrl->IDToOrder(ID); + if (Order == -1 && ID != -1) + { + return false; + } + TreeView_SelectItem(hTreeView, (Order == -1) ? NULL : ((Order <= TREECTRL_ROOTORDEROFFS) ? TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)].hItem : TreeCtrl->Value[Order].hItem)); + return true; +} + +int CMsgTree::GetDefMsg(int iMode) +{ + int I; + for (I = 0; I < lengthof(StatusModeList); I++) + { + if (StatusModeList[I].Status == iMode) + { + return MsgTreePage.GetValue(StatusModeList[I].DBSetting); + } + } + return 0; +} + +void CMsgTree::SetDefMsg(int iMode, int ID) +{ + int I; + for (I = 0; I < lengthof(StatusModeList); I++) + { + if (StatusModeList[I].Status == iMode) + { + if (MsgTreePage.GetValue(StatusModeList[I].DBSetting) != ID) + { + RECT rc; + COptItem_TreeCtrl *TreeCtrl = GetTreeCtrl(); + int OrderOld = TreeCtrl->IDToOrder(MsgTreePage.GetValue(StatusModeList[I].DBSetting)); + if (OrderOld >= 0 && TreeView_GetItemRect(hTreeView, TreeCtrl->Value[OrderOld].hItem, &rc, false)) + { + InvalidateRect(hTreeView, &rc, true); // refresh icons of previous default tree item + } + int OrderNew = TreeCtrl->IDToOrder(ID); + if (OrderNew >= 0 && TreeView_GetItemRect(hTreeView, TreeCtrl->Value[OrderNew].hItem, &rc, false)) + { + InvalidateRect(hTreeView, &rc, true); // refresh new default item icons + } + MsgTreePage.SetValue(StatusModeList[I].DBSetting, ID); + NMMSGTREE nm = {0}; + if (OrderOld >= 0) + { + nm.ItemOld = &TreeCtrl->Value[OrderOld]; + } + if (OrderNew >= 0) + { + nm.ItemNew = &TreeCtrl->Value[OrderNew]; + } + nm.hdr.code = MTN_DEFMSGCHANGED; + nm.hdr.hwndFrom = hTreeView; + nm.hdr.idFrom = GetDlgCtrlID(hTreeView); + SendMessage(GetParent(hTreeView), WM_NOTIFY, 0, (LPARAM)&nm); + } + break; + } + } +} + +void CMsgTree::Save() +{ + if (MsgTreePage.GetModified()) + { + MsgTreePage.PageToMemToDB(); + WindowList_BroadcastAsync(hMTWindowList, UM_MSGTREE_UPDATE, 0, 0); + } +} + +void CMsgTree::UpdateItem(int ID) // updates item title, and expanded/collapsed state for groups +{ + COptItem_TreeCtrl *TreeCtrl = GetTreeCtrl(); + int Order = TreeCtrl->IDToOrder(ID); + if (Order != -1) + { + CBaseTreeItem* TreeItem = (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; + TCString NewTitle; + TVITEM tvi; + tvi.mask = TVIF_HANDLE | TVIF_TEXT; + tvi.hItem = TreeItem->hItem; + tvi.pszText = NewTitle.GetBuffer(TREEITEMTITLE_MAXLEN); + tvi.cchTextMax = TREEITEMTITLE_MAXLEN; + TreeView_GetItem(hTreeView, &tvi); + if (TreeItem->Title != (const TCHAR*)tvi.pszText) + { + TreeCtrl->SetModified(true); + NMMSGTREE nm = {0}; + nm.ItemNew = TreeItem; + nm.hdr.code = MTN_ITEMRENAMED; + nm.hdr.hwndFrom = hTreeView; + nm.hdr.idFrom = GetDlgCtrlID(hTreeView); + SendMessage(GetParent(hTreeView), WM_NOTIFY, 0, (LPARAM)&nm); + } + tvi.mask = TVIF_HANDLE | TVIF_TEXT; + tvi.pszText = TreeItem->Title; + TreeView_SetItem(hTreeView, &tvi); + TreeView_Expand(hTreeView, tvi.hItem, (TreeItem->Flags & TIF_EXPANDED) ? TVE_EXPAND : TVE_COLLAPSE); + } +} + +bool CMsgTree::DeleteSelectedItem() // returns true if the item was deleted +{ + COptItem_TreeCtrl *TreeCtrl = GetTreeCtrl(); + int Order = TreeCtrl->IDToOrder(TreeCtrl->GetSelectedItemID(GetParent(hTreeView))); + _ASSERT(Order >= 0); + CTreeItem *SelectedItem = &TreeCtrl->Value[Order]; + //NightFox: fix for langpack and fix cut char space in text + //if (MessageBox(GetParent(hTreeView), TCString(TranslateT("Do you really want to delete this ")) + ((SelectedItem->Flags & TIF_GROUP) ? TranslateT("category with its messages?") : TranslateT("message?")), TranslateT("New Away System"), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2) == IDYES) + if (MessageBox(GetParent(hTreeView), + ((SelectedItem->Flags & TIF_GROUP) ? + TranslateT("Do you really want to delete this category with its messages?") + : + TranslateT("Do you really want to delete this message?")) + , + TranslateT("New Away System"), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2) == IDYES) + { + NMMSGTREE nm = {0}; + nm.ItemOld = SelectedItem; + nm.hdr.code = MTN_DELETEITEM; + nm.hdr.hwndFrom = hTreeView; + nm.hdr.idFrom = GetDlgCtrlID(hTreeView); + if (!SendMessage(GetParent(hTreeView), WM_NOTIFY, 0, (LPARAM)&nm)) + { + TreeCtrl->Delete(GetParent(hTreeView), TreeCtrl->GetSelectedItemID(GetParent(hTreeView))); + return true; + } + } + return false; +} + +CTreeItem* CMsgTree::AddCategory() +{ + COptItem_TreeCtrl *TreeCtrl = GetTreeCtrl(); + CTreeItem* TreeItem = TreeCtrl->InsertItem(GetParent(hTreeView), CTreeItem(_T(""), 0, 0, TIF_GROUP)); + TVITEM tvi; + tvi.mask = TVIF_HANDLE | TVIF_TEXT; + tvi.hItem = TreeItem->hItem; + TreeItem->Title = tvi.pszText = TranslateT("New category"); + TreeView_SetItem(hTreeView, &tvi); + TreeView_EditLabel(hTreeView, TreeItem->hItem); + NMMSGTREE nm = {0}; + nm.ItemNew = TreeItem; + nm.hdr.code = MTN_NEWCATEGORY; + nm.hdr.hwndFrom = hTreeView; + nm.hdr.idFrom = GetDlgCtrlID(hTreeView); + SendMessage(GetParent(hTreeView), WM_NOTIFY, 0, (LPARAM)&nm); + return TreeItem; +} + +CTreeItem* CMsgTree::AddMessage() +{ + COptItem_TreeCtrl *TreeCtrl = GetTreeCtrl(); + CTreeItem* TreeItem = TreeCtrl->InsertItem(GetParent(hTreeView), CTreeItem(_T(""), 0, 0)); + TVITEM tvi; + tvi.mask = TVIF_HANDLE | TVIF_TEXT; + tvi.hItem = TreeItem->hItem; + TreeItem->Title = tvi.pszText = TranslateT("New message"); + TreeView_SetItem(hTreeView, &tvi); + TreeView_EditLabel(hTreeView, TreeItem->hItem); + NMMSGTREE nm = {0}; + nm.ItemNew = TreeItem; + nm.hdr.code = MTN_NEWMESSAGE; + nm.hdr.hwndFrom = hTreeView; + nm.hdr.idFrom = GetDlgCtrlID(hTreeView); + SendMessage(GetParent(hTreeView), WM_NOTIFY, 0, (LPARAM)&nm); + return TreeItem; +} + +CBaseTreeItem* CMsgTree::GetNextItem(int Flags, CBaseTreeItem* Item) // Item is 'int ID' if MTGN_BYID flag is set; returns CBaseTreeItem* or NULL +{ + COptItem_TreeCtrl *TreeCtrl = GetTreeCtrl(); + CBaseTreeItem* TreeItem = Item; + if (Flags & MTGN_BYID) + { + int Order = TreeCtrl->IDToOrder((int)Item); + _ASSERT(Order != -1); + TreeItem = (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; + } + int TVFlag = 0; + switch (Flags & ~MTGN_BYID) + { + case MTGN_ROOT: TVFlag = TVGN_ROOT; break; + case MTGN_CHILD: TVFlag = TVGN_CHILD; break; + case MTGN_PARENT: TVFlag = TVGN_PARENT; break; + case MTGN_NEXT: TVFlag = TVGN_NEXT; break; + case MTGN_PREV: TVFlag = TVGN_PREVIOUS; break; + default: _ASSERT(0); + } + int Order = TreeCtrl->hItemToOrder(TreeView_GetNextItem(hTreeView, TreeItem ? TreeItem->hItem : NULL, TVFlag)); + if (Order != -1) + { + return (Order <= TREECTRL_ROOTORDEROFFS) ? (CBaseTreeItem*)&TreeCtrl->RootItems[ROOT_ORDER_TO_INDEX(Order)] : (CBaseTreeItem*)&TreeCtrl->Value[Order]; + } + return NULL; +} diff --git a/plugins/!Deprecated/NewAwaySysMod/MsgTree.h b/plugins/!Deprecated/NewAwaySysMod/MsgTree.h new file mode 100644 index 0000000000..98b2f9d6cc --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/MsgTree.h @@ -0,0 +1,95 @@ +/* + New Away System - plugin for Miranda IM + Copyright (c) 2005-2007 Chervov Dmitry + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#pragma once + +extern COptPage g_MsgTreePage; + +class CMsgTree +{ +public: + CMsgTree(HWND hTreeView); // warning: it changes GWLP_USERDATA of the parent window + ~CMsgTree(); + + CBaseTreeItem* GetSelection(); // returns NULL if there's nothing selected + bool SetSelection(int ID, int Flags); // set ID = -1 to unselect; ID specifies an order of an item if Flags = MTSS_BYORDER + int GetDefMsg(int iMode); + void SetDefMsg(int iMode, int ID); + void Save(); + void UpdateItem(int ID); // updates item title, and expanded/collapsed state for groups; set SetModified to TRUE to change Modified flag of the tree + bool DeleteSelectedItem(); // returns true if the item was deleted + CTreeItem* AddCategory(); + CTreeItem* AddMessage(); + CBaseTreeItem* GetNextItem(int Flags, CBaseTreeItem* Item); // Item is 'int ID' if MTGN_BYID flag is set; returns CBaseTreeItem* or NULL + void EnsureVisible(HTREEITEM hItem) {TreeView_EnsureVisible(hTreeView, hItem);} + bool GetModified() {return MsgTreePage.GetModified();} + void SetModified(bool Modified) {MsgTreePage.SetModified(Modified);} + + friend LRESULT CALLBACK ParentSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); + friend LRESULT CALLBACK MsgTreeSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); + +private: + COptItem_TreeCtrl* GetTreeCtrl() {return (COptItem_TreeCtrl*)MsgTreePage.Find(GetDlgCtrlID(hTreeView));} + + HWND hTreeView; + WNDPROC OrigTreeViewProc; + WNDPROC OrigParentProc; + COptPage MsgTreePage; + HTREEITEM hDragItem; + HTREEITEM hPrevDropTarget; + int UpdateLock; + HIMAGELIST hImageList; +}; + +// SetSelection constants +#define MTSS_BYID 0 +#define MTSS_BYORDER 1 + +// GetNextItem constants +#define MTGN_ROOT 0 +#define MTGN_CHILD 1 +#define MTGN_PARENT 2 +#define MTGN_NEXT 3 +#define MTGN_PREV 4 +#define MTGN_BYID 0x8000 // means that lParam is ID of an item, not a pointer to its data + + +// notifications + +typedef struct +{ + NMHDR hdr; + CBaseTreeItem* ItemOld; + CBaseTreeItem* ItemNew; +} NMMSGTREE; +typedef NMMSGTREE* PNMMSGTREE; + +#define MTN_FIRST (0U - 100U) + +#define MTN_SELCHANGED (MTN_FIRST - 0) // lParam = &NMMSGTREE; ItemOld and ItemNew contain old and new item info +#define MTN_BEGINDRAG (MTN_FIRST - 1) // lParam = &NMMSGTREE; ItemOld points to the item info; return TRUE to cancel dragging +#define MTN_ENDDRAG (MTN_FIRST - 2) // lParam = &NMMSGTREE; ItemOld points to the item info; ItemNew points to the item on which ItemOld was dropped; return TRUE to cancel moving +#define MTN_NEWCATEGORY (MTN_FIRST - 3) // lParam = &NMMSGTREE; ItemNew points to new category info +#define MTN_NEWMESSAGE (MTN_FIRST - 4) // lParam = &NMMSGTREE; ItemNew points to new message info +#define MTN_ITEMRENAMED (MTN_FIRST - 5) // lParam = &NMMSGTREE; ItemNew points to renamed item info +#define MTN_DELETEITEM (MTN_FIRST - 6) // lParam = &NMMSGTREE; ItemOld points to the item info; return TRUE to prevent item from being deleted +#define MTN_DEFMSGCHANGED (MTN_FIRST - 7) // lParam = &NMMSGTREE; ItemOld and ItemNew point to old and new default item info correspondingly + + +void LoadMsgTreeModule(); diff --git a/plugins/!Deprecated/NewAwaySysMod/NewAwaySys.rc b/plugins/!Deprecated/NewAwaySysMod/NewAwaySys.rc new file mode 100644 index 0000000000..7a0bfba8ee --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/NewAwaySys.rc @@ -0,0 +1,701 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Russian resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) +#ifdef _WIN32 +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +#pragma code_page(1251) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Russian resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE MOVEABLE PURE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE MOVEABLE PURE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_POPUPOPTDLG DIALOG DISCARDABLE 0, 0, 312, 237 +STYLE DS_SETFOREGROUND | DS_FIXEDSYS | DS_CONTROL | DS_CENTER | WS_CHILD +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX "",IDC_POPUPOPTDLG_GROUP_NOTIFICATION,6,6,300,208 + CONTROL "Popup notification",IDC_POPUPOPTDLG_USEPOPUPS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,12,5,108,10 + GROUPBOX "Popup text format",IDC_STATIC,12,18,288,76 + EDITTEXT IDC_POPUPOPTDLG_POPUPFORMAT,18,30,222,48,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | + WS_VSCROLL | WS_HSCROLL + PUSHBUTTON "Preview",IDC_POPUPOPTDLG_POPUPPREVIEW,246,30,48,14 + CONTROL "V",IDC_POPUPOPTDLG_VARS,"MButtonClass",WS_TABSTOP,246, + 50,16,14,0x18000000L + LTEXT "%extratext% is your status message", + IDC_POPUPOPTDLG_STATIC_EXTRATEXT,18,81,276,8 + GROUPBOX "Click action",IDC_STATIC,12,100,199,54 + RTEXT "On left click",IDC_POPUPOPTDLG_STATIC_LCLICK,17,115,55, + 8 + COMBOBOX IDC_POPUPOPTDLG_LCLICK_ACTION,78,112,125,86, + CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + RTEXT "On right click",IDC_POPUPOPTDLG_STATIC_RCLICK,17,133,55, + 8 + COMBOBOX IDC_POPUPOPTDLG_RCLICK_ACTION,78,130,125,86, + CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Delay",IDC_STATIC,217,100,83,54 + EDITTEXT IDC_POPUPOPTDLG_POPUPDELAY,240,112,32,12,ES_AUTOHSCROLL + CONTROL "",IDC_POPUPOPTDLG_POPUPDELAY_SPIN,"msctls_updown32", + UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | + UDS_ARROWKEYS | UDS_NOTHOUSANDS,260,112,12,12 + LTEXT "Sec",IDC_POPUPOPTDLG_STATIC_SEC,275,114,21,8 + CTEXT "0 = Default",IDC_POPUPOPTDLG_STATIC_DEFAULT,224,128,70, + 8 + CTEXT "-1 = Infinite",IDC_POPUPOPTDLG_STATIC_INFINITE,224,140, + 70,8 + GROUPBOX "Colours",IDC_STATIC,12,160,155,48 + CONTROL "",IDC_POPUPOPTDLG_BGCOLOUR,"ColourPicker",WS_TABSTOP,19, + 172,19,12 + LTEXT "Background",IDC_POPUPOPTDLG_STATIC_BGCOLOUR,43,175,39,8 + CONTROL "Use default",IDC_POPUPOPTDLG_DEFBGCOLOUR,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,90,175,73,10 + CONTROL "",IDC_POPUPOPTDLG_TEXTCOLOUR,"ColourPicker",WS_TABSTOP, + 19,190,19,12 + LTEXT "Text",IDC_POPUPOPTDLG_STATIC_TEXTCOLOUR,43,193,15,8 + CONTROL "Use default",IDC_POPUPOPTDLG_DEFTEXTCOLOUR,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,90,193,73,10 + GROUPBOX "Only notify when:",IDC_STATIC,174,160,125,32 + CONTROL "On&line",IDC_POPUPOPTDLG_ONLNOTIFY,"MButtonClass", + WS_TABSTOP,180,172,16,14,0x18000000L + CONTROL "&Away",IDC_POPUPOPTDLG_AWAYNOTIFY,"MButtonClass", + WS_TABSTOP,196,172,16,14,0x18000000L + CONTROL "&NA",IDC_POPUPOPTDLG_NANOTIFY,"MButtonClass",WS_TABSTOP, + 212,172,16,14,0x18000000L + CONTROL "Occ&upied",IDC_POPUPOPTDLG_OCCNOTIFY,"MButtonClass", + WS_TABSTOP,228,172,16,14,0x18000000L + CONTROL "&DND",IDC_POPUPOPTDLG_DNDNOTIFY,"MButtonClass", + WS_TABSTOP,244,172,16,14,0x18000000L + CONTROL "&Free for chat",IDC_POPUPOPTDLG_FFCNOTIFY,"MButtonClass", + WS_TABSTOP,260,172,16,14,0x18000000L + CONTROL "&Other",IDC_POPUPOPTDLG_OTHERNOTIFY,"MButtonClass", + WS_TABSTOP,276,172,16,14,0x18000000L + CONTROL "Log to a file only when popup notification for a contact is enabled", + IDC_POPUPOPTDLG_LOGONLYWITHPOPUP,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,6,219,300,10 +END + +IDD_AUTOREPLY DIALOG DISCARDABLE 0, 0, 312, 231 +STYLE DS_SETFOREGROUND | DS_FIXEDSYS | DS_CONTROL | DS_CENTER | WS_CHILD +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX "",IDC_MOREOPTDLG_PANEL,6,6,300,220 + CONTROL "Enable autoreply",IDC_REPLYDLG_ENABLEREPLY,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,12,5,139,10 + RTEXT "On event...",IDC_REPLYDLG_STATIC_ONEVENT,43,19,59,8 + CONTROL "",IDC_REPLYDLG_EVENTMSG,"Button",BS_AUTOCHECKBOX | + BS_ICON | WS_TABSTOP,110,17,29,12 + CONTROL "",IDC_REPLYDLG_EVENTURL,"Button",BS_AUTOCHECKBOX | + BS_ICON | WS_TABSTOP,145,17,29,12 + CONTROL "",IDC_REPLYDLG_EVENTFILE,"Button",BS_AUTOCHECKBOX | + BS_ICON | WS_TABSTOP,180,17,29,12 + CONTROL "Don't reply to ICQ contacts",IDC_REPLYDLG_DONTSENDTOICQ, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,119,275,10 + CONTROL "Don't reply when I'm invisible to the contact", + IDC_REPLYDLG_DONTREPLYINVISIBLE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,21,107,275,10 + CONTROL "Save autoreply to the history",IDC_REPLYDLG_LOGREPLY, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,34,275,10 + CONTROL "Reply only when Idle",IDC_REPLYDLG_ONLYIDLEREPLY,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,21,48,275,10 + CONTROL "Reply only when contact's message window is closed", + IDC_REPLYDLG_ONLYCLOSEDDLGREPLY,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,21,59,275,10 + LTEXT "Send maximum",IDC_REPLYDLG_STATIC_SEND,33,72,90,8 + EDITTEXT IDC_REPLYDLG_SENDCOUNT,127,70,40,12,ES_AUTOHSCROLL + CONTROL "",IDC_REPLYDLG_SENDCOUNT_SPIN,"msctls_updown32", + UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | + UDS_ARROWKEYS | UDS_NOTHOUSANDS,156,70,12,12 + LTEXT "times (-1=infinite)",IDC_REPLYDLG_STATIC_TIMES,172,72, + 124,8 + CONTROL "Reset this counter also when I just change my status text\n(when status icon remains the same)", + IDC_REPLYDLG_RESETCOUNTERWHENSAMEICON,"Button", + BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,34, + 84,262,18 + LTEXT "Disable autoreply when...", + IDC_REPLYDLG_STATIC_DISABLEWHENSTATUS,13,134,283,8 + CONTROL "On&line",IDC_REPLYDLG_DISABLE_ONL,"MButtonClass", + WS_TABSTOP,21,146,16,14,0x18000000L + CONTROL "&Away",IDC_REPLYDLG_DISABLE_AWAY,"MButtonClass", + WS_TABSTOP,37,146,16,14,0x18000000L + CONTROL "&NA",IDC_REPLYDLG_DISABLE_NA,"MButtonClass",WS_TABSTOP, + 53,146,16,14,0x18000000L + CONTROL "Occ&upied",IDC_REPLYDLG_DISABLE_OCC,"MButtonClass", + WS_TABSTOP,69,146,16,14,0x18000000L + CONTROL "&DND",IDC_REPLYDLG_DISABLE_DND,"MButtonClass", + WS_TABSTOP,85,146,16,14,0x18000000L + CONTROL "&Free for chat",IDC_REPLYDLG_DISABLE_FFC,"MButtonClass", + WS_TABSTOP,101,146,16,14,0x18000000L + CONTROL "&Invisible",IDC_REPLYDLG_DISABLE_INV,"MButtonClass", + WS_TABSTOP,117,146,16,14,0x18000000L + CONTROL "On the &Phone",IDC_REPLYDLG_DISABLE_OTP,"MButtonClass", + WS_TABSTOP,133,146,16,14,0x18000000L + CONTROL "Out to &Lunch",IDC_REPLYDLG_DISABLE_OTL,"MButtonClass", + WS_TABSTOP,149,146,16,14,0x18000000L + LTEXT "Autoreply format:",IDC_REPLYDLG_STATIC_FORMAT,13,168, + 283,8 + EDITTEXT IDC_REPLYDLG_PREFIX,21,180,209,30,ES_MULTILINE | + ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL + CONTROL "V",IDC_REPLYDLG_VARS,"MButtonClass",WS_TABSTOP,231,180, + 16,14,0x18000000L + LTEXT "%extratext% is your status message", + IDC_REPLYDLG_STATIC_EXTRATEXT,21,212,234,8 +END + +IDD_SETAWAYMSG DIALOGEX 0, 0, 398, 132 +STYLE DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | + WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + EDITTEXT IDC_SAWAYMSG_MSGDATA,116,1,170,114,ES_MULTILINE | + ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL + PUSHBUTTON "OK",IDC_OK,115,117,60,14 + CONTROL "&Variables",IDC_SAWAYMSG_VARS,"MButtonClass",WS_TABSTOP, + 255,117,16,14,0x18000000L + CONTROL "Se&ttings",IDC_SAWAYMSG_OPTIONS,"MButtonClass", + WS_TABSTOP,271,117,16,14,0x18000000L + ICON IDI_IGNORE,IDC_SAWAYMSG_STATIC_IGNOREICON,382,109,16,16, + SS_CENTERIMAGE | SS_REALSIZEIMAGE + ICON IDI_SOE_ENABLED,IDC_SAWAYMSG_STATIC_REPLYICON,382,118,16, + 16,SS_CENTERIMAGE | SS_REALSIZEIMAGE + CONTROL "",IDC_SAWAYMSG_CONTACTSTREE,"SysTreeView32", + TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | + TVS_TRACKSELECT | WS_BORDER | WS_TABSTOP,289,1,108,114 + CONTROL "Ignore requests",IDC_SAWAYMSG_IGNOREREQ,"Button", + BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,307,116,80,8, + WS_EX_RIGHT + CONTROL "Send an autoreply",IDC_SAWAYMSG_SENDMSG,"Button", + BS_AUTO3STATE | BS_LEFTTEXT | WS_TABSTOP,307,124,80,8, + WS_EX_RIGHT + CONTROL "",IDC_SAWAYMSG_TREE,"SysTreeView32",TVS_HASBUTTONS | + TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | + TVS_SHOWSELALWAYS | TVS_TRACKSELECT | WS_BORDER | + WS_TABSTOP,1,1,112,114 + CONTROL "&Delete",IDC_SAWAYMSG_DELETE,"MButtonClass",WS_TABSTOP, + 58,116,16,14,0x18000000L + CONTROL "New &Category",IDC_SAWAYMSG_NEWCATEGORY,"MButtonClass", + WS_TABSTOP,2,116,16,14,0x18000000L + CONTROL "Save As &New",IDC_SAWAYMSG_SAVEASNEW,"MButtonClass", + WS_TABSTOP,18,116,16,14,0x18000000L + CONTROL "&Save",IDC_SAWAYMSG_SAVEMSG,"MButtonClass",WS_TABSTOP, + 34,116,16,14,0x18000000L + CONTROL "",IDC_SAWAYMSG_MSGSPLITTER,"Static",SS_ENHMETAFILE | + SS_SUNKEN,114,0,1,115 + CONTROL "",IDC_SAWAYMSG_CONTACTSPLITTER,"Static",SS_ENHMETAFILE | + SS_SUNKEN,287,0,1,115 +END + +IDD_MESSAGES DIALOG DISCARDABLE 0, 0, 311, 221 +STYLE DS_SETFOREGROUND | DS_FIXEDSYS | DS_CONTROL | DS_CENTER | WS_CHILD +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "",IDC_MESSAGEDLG_MSGTREE,"SysTreeView32",TVS_HASBUTTONS | + TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | + TVS_SHOWSELALWAYS | TVS_TRACKSELECT | WS_BORDER | + WS_TABSTOP,6,6,126,210 + RTEXT "Title:",IDC_STATIC,136,8,51,8 + EDITTEXT IDC_MESSAGEDLG_MSGTITLE,189,6,115,12,ES_AUTOHSCROLL + EDITTEXT IDC_MESSAGEDLG_MSGDATA,138,24,166,138,ES_MULTILINE | + ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL + GROUPBOX "Use this message as default for",IDC_STATIC,138,186,166, + 30,BS_LEFT + CONTROL "On&line",IDC_MESSAGEDLG_DEF_ONL,"MButtonClass", + WS_TABSTOP,149,197,16,14,0x18000000L + CONTROL "&Away",IDC_MESSAGEDLG_DEF_AWAY,"MButtonClass", + WS_TABSTOP,165,197,16,14,0x18000000L + CONTROL "&NA",IDC_MESSAGEDLG_DEF_NA,"MButtonClass",WS_TABSTOP, + 181,197,16,14,0x18000000L + CONTROL "Occ&upied",IDC_MESSAGEDLG_DEF_OCC,"MButtonClass", + WS_TABSTOP,197,197,16,14,0x18000000L + CONTROL "&DND",IDC_MESSAGEDLG_DEF_DND,"MButtonClass",WS_TABSTOP, + 213,197,16,14,0x18000000L + CONTROL "&Free for chat",IDC_MESSAGEDLG_DEF_FFC,"MButtonClass", + WS_TABSTOP,229,197,16,14,0x18000000L + CONTROL "&Invisible",IDC_MESSAGEDLG_DEF_INV,"MButtonClass", + WS_TABSTOP,245,197,16,14,0x18000000L + CONTROL "On the &Phone",IDC_MESSAGEDLG_DEF_OTP,"MButtonClass", + WS_TABSTOP,261,197,16,14,0x18000000L + CONTROL "Out to &Lunch",IDC_MESSAGEDLG_DEF_OTL,"MButtonClass", + WS_TABSTOP,277,197,16,14,0x18000000L + CONTROL "New message",IDC_MESSAGEDLG_NEWMSG,"MButtonClass", + WS_TABSTOP,138,166,16,14,0x18000000L + CONTROL "New category",IDC_MESSAGEDLG_NEWCAT,"MButtonClass", + WS_TABSTOP,154,166,16,14,0x18000000L + CONTROL "Delete",IDC_MESSAGEDLG_DEL,"MButtonClass",WS_TABSTOP, + 170,166,16,14,0x18000000L + CONTROL "V",IDC_MESSAGEDLG_VARS,"MButtonClass",WS_TABSTOP,288, + 166,16,14,0x18000000L +END + +IDD_MODERNOPT_MESSAGES DIALOG DISCARDABLE 0, 0, 373, 154 +STYLE DS_SETFOREGROUND | DS_FIXEDSYS | DS_CONTROL | DS_CENTER | WS_CHILD +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "",IDC_MESSAGEDLG_MSGTREE,"SysTreeView32",TVS_HASBUTTONS | + TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | + TVS_SHOWSELALWAYS | TVS_TRACKSELECT | WS_BORDER | + WS_TABSTOP,6,13,126,128 + LTEXT "Title:",IDC_TXT_TITLE2,138,14,51,8 + EDITTEXT IDC_MESSAGEDLG_MSGTITLE,194,13,172,12,ES_AUTOHSCROLL + EDITTEXT IDC_MESSAGEDLG_MSGDATA,138,30,228,57,ES_MULTILINE | + ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL + GROUPBOX "Use this message as default for",IDC_TXT_TITLE3,138,111, + 228,30,BS_LEFT + CONTROL "On&line",IDC_MESSAGEDLG_DEF_ONL,"MButtonClass", + WS_TABSTOP,144,122,16,14,0x18000000L + CONTROL "&Away",IDC_MESSAGEDLG_DEF_AWAY,"MButtonClass", + WS_TABSTOP,160,122,16,14,0x18000000L + CONTROL "&NA",IDC_MESSAGEDLG_DEF_NA,"MButtonClass",WS_TABSTOP, + 176,122,16,14,0x18000000L + CONTROL "Occ&upied",IDC_MESSAGEDLG_DEF_OCC,"MButtonClass", + WS_TABSTOP,192,122,16,14,0x18000000L + CONTROL "&DND",IDC_MESSAGEDLG_DEF_DND,"MButtonClass",WS_TABSTOP, + 208,122,16,14,0x18000000L + CONTROL "&Free for chat",IDC_MESSAGEDLG_DEF_FFC,"MButtonClass", + WS_TABSTOP,224,122,16,14,0x18000000L + CONTROL "&Invisible",IDC_MESSAGEDLG_DEF_INV,"MButtonClass", + WS_TABSTOP,240,122,16,14,0x18000000L + CONTROL "On the &Phone",IDC_MESSAGEDLG_DEF_OTP,"MButtonClass", + WS_TABSTOP,256,122,16,14,0x18000000L + CONTROL "Out to &Lunch",IDC_MESSAGEDLG_DEF_OTL,"MButtonClass", + WS_TABSTOP,272,122,16,14,0x18000000L + CONTROL "New message",IDC_MESSAGEDLG_NEWMSG,"MButtonClass", + WS_TABSTOP,138,95,16,14,0x18000000L + CONTROL "New category",IDC_MESSAGEDLG_NEWCAT,"MButtonClass", + WS_TABSTOP,154,95,16,14,0x18000000L + CONTROL "Delete",IDC_MESSAGEDLG_DEL,"MButtonClass",WS_TABSTOP, + 170,95,16,14,0x18000000L + CONTROL "V",IDC_MESSAGEDLG_VARS,"MButtonClass",WS_TABSTOP,350,95, + 16,14,0x18000000L + LTEXT "Statuses messages:",IDC_TXT_TITLE1,0,2,99,9 + CONTROL "Configure autoaway",IDC_LNK_AUTOAWAY,"Hyperlink", + WS_TABSTOP,6,142,126,11 +END + +IDD_MOREOPTDIALOG DIALOG DISCARDABLE 0, 0, 311, 235 +STYLE DS_SETFOREGROUND | DS_FIXEDSYS | DS_CONTROL | DS_CENTER | WS_CHILD +FONT 8, "MS Shell Dlg" +BEGIN + RTEXT "Wait",IDC_STATIC_MOREOPTDLG_WAIT,2,10,36,8 + EDITTEXT IDC_MOREOPTDLG_WAITFORMSG,41,8,28,12,ES_AUTOHSCROLL + CONTROL "",IDC_MOREOPTDLG_WAITFORMSG_SPIN,"msctls_updown32", + UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | + UDS_ARROWKEYS | UDS_NOTHOUSANDS,57,8,12,12 + LTEXT "seconds before closing the status message dialog (-1=don't close)", + IDC_STATIC_MOREOPTDLG_SECONDSREMAIN,74,10,235,8 + RTEXT "Store",IDC_STATIC,2,28,36,8 + EDITTEXT IDC_MOREOPTDLG_RECENTMSGSCOUNT,41,26,28,12, + ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_MOREOPTDLG_RECENTMSGSCOUNT_SPIN,"msctls_updown32", + UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | + UDS_ARROWKEYS | UDS_NOTHOUSANDS,57,26,12,12 + LTEXT "most recent messages (0=disable)",IDC_STATIC,74,28,119, + 8 + CONTROL "Store for each status separately", + IDC_MOREOPTDLG_PERSTATUSMRM,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,41,42,267,10 + GROUPBOX "Use default...",IDC_STATIC,6,58,294,30 + CONTROL "Use the most recent message",IDC_MOREOPTDLG_USELASTMSG, + "Button",BS_AUTORADIOBUTTON | WS_TABSTOP,12,70,138,10 + CONTROL "Use the default message",IDC_MOREOPTDLG_USEDEFMSG, + "Button",BS_AUTORADIOBUTTON | WS_TABSTOP,156,70,138,10 + CONTROL "Reset per-protocol messages when changing global status", + IDC_MOREOPTDLG_RESETPROTOMSGS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,7,95,300,10 + CONTROL "Store protocol messages for each status separately", + IDC_MOREOPTDLG_PERSTATUSPROTOMSGS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,15,107,294,10 + CONTROL "Store protocol autoreply settings for each status separately", + IDC_MOREOPTDLG_PERSTATUSPROTOSETTINGS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,15,119,294,10 + CONTROL "Remember last message used for a contact...", + IDC_MOREOPTDLG_SAVEPERSONALMSGS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,6,133,297,10 + CONTROL "Store for each status separately", + IDC_MOREOPTDLG_PERSTATUSPERSONAL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,15,146,288,10 + CONTROL "Store contact autoreply/ignore settings for each status separately", + IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS,"Button", + BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,15, + 157,294,16 + CONTROL "Enable contact menu items",IDC_MOREOPTDLG_USEMENUITEM, + "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | + WS_TABSTOP,167,203,142,17 + CONTROL "Use protocol specific nick for %nas_mynick%", + IDC_MOREOPTDLG_MYNICKPERPROTO,"Button",BS_AUTOCHECKBOX | + BS_MULTILINE | WS_TABSTOP,6,175,294,8 + CONTROL "Update status messages for non-ICQ protocols every", + IDC_MOREOPTDLG_UPDATEMSGS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,6,187,199,10 + EDITTEXT IDC_MOREOPTDLG_UPDATEMSGSPERIOD,207,186,38,12, + ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_MOREOPTDLG_UPDATEMSGSPERIOD_SPIN,"msctls_updown32", + UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | + UDS_ARROWKEYS | UDS_NOTHOUSANDS,230,186,12,12 + LTEXT "seconds",IDC_STATIC,249,187,60,8 + GROUPBOX "Don't show the message dialog for",IDC_STATIC,6,200,156, + 31 + CONTROL "On&line",IDC_MOREOPTDLG_DONTPOPDLG_ONL,"MButtonClass", + WS_TABSTOP,12,212,16,14,0x18000000L + CONTROL "&Away",IDC_MOREOPTDLG_DONTPOPDLG_AWAY,"MButtonClass", + WS_TABSTOP,28,212,16,14,0x18000000L + CONTROL "&NA",IDC_MOREOPTDLG_DONTPOPDLG_NA,"MButtonClass", + WS_TABSTOP,44,212,16,14,0x18000000L + CONTROL "Occ&upied",IDC_MOREOPTDLG_DONTPOPDLG_OCC,"MButtonClass", + WS_TABSTOP,60,212,16,14,0x18000000L + CONTROL "&DND",IDC_MOREOPTDLG_DONTPOPDLG_DND,"MButtonClass", + WS_TABSTOP,76,212,16,14,0x18000000L + CONTROL "&Free for chat",IDC_MOREOPTDLG_DONTPOPDLG_FFC, + "MButtonClass",WS_TABSTOP,92,212,16,14,0x18000000L + CONTROL "&Invisible",IDC_MOREOPTDLG_DONTPOPDLG_INV,"MButtonClass", + WS_TABSTOP,108,212,16,14,0x18000000L + CONTROL "On the &Phone",IDC_MOREOPTDLG_DONTPOPDLG_OTP, + "MButtonClass",WS_TABSTOP,124,212,16,14,0x18000000L + CONTROL "Out to &Lunch",IDC_MOREOPTDLG_DONTPOPDLG_OTL, + "MButtonClass",WS_TABSTOP,140,212,16,14,0x18000000L +END + +IDD_READAWAYMSG DIALOGEX 0, 0, 186, 72 +STYLE DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "%s Message for %s" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + EDITTEXT IDC_READAWAYMSG_MSG,5,5,177,43,ES_MULTILINE | + ES_AUTOVSCROLL | ES_READONLY | NOT WS_VISIBLE | + WS_VSCROLL + CTEXT "Retrieving %s message...",IDC_READAWAYMSG_RETRIEVE,5,21, + 177,8,SS_NOPREFIX + DEFPUSHBUTTON "&Cancel",IDOK,69,53,50,14,BS_NOTIFY +END + +IDD_CONTACTSOPTDLG DIALOGEX 0, 0, 311, 221 +STYLE DS_FIXEDSYS | DS_CONTROL | DS_CENTER | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "",IDC_CONTACTSDLG_LIST,"CListControl",WS_TABSTOP | + 0x1f0,6,30,299,160,WS_EX_CLIENTEDGE + ICON 141,IDC_STATIC,197,0,20,20,SS_CENTERIMAGE | + SS_REALSIZEIMAGE | NOT WS_VISIBLE + LTEXT "Notify of requests",IDC_STATIC,217,5,87,8,SS_NOPREFIX | + SS_CENTERIMAGE | NOT WS_VISIBLE + ICON 140,IDC_STATIC,197,12,20,20,SS_CENTERIMAGE | + SS_REALSIZEIMAGE | NOT WS_VISIBLE + LTEXT "Don't notify of requests",IDC_STATIC,217,18,87,8, + SS_NOPREFIX | SS_CENTERIMAGE | NOT WS_VISIBLE + ICON IDI_SOE_ENABLED,IDC_STATIC,3,190,20,20,SS_CENTERIMAGE | + SS_REALSIZEIMAGE + LTEXT "Autoreply on",IDC_STATIC,24,196,106,8,SS_NOPREFIX | + SS_CENTERIMAGE + ICON IDI_SOE_DISABLED,IDC_STATIC,3,204,20,20,SS_CENTERIMAGE | + SS_REALSIZEIMAGE + LTEXT "Autoreply off",IDC_STATIC,24,210,107,8,SS_NOPREFIX | + SS_CENTERIMAGE + ICON IDI_IGNORE,IDC_STATIC,132,190,20,20,SS_CENTERIMAGE | + SS_REALSIZEIMAGE + LTEXT "Don't send status message",IDC_STATIC,151,196,153,8, + SS_NOPREFIX | SS_CENTERIMAGE + LTEXT "Note: these settings are applied to all status modes at once.", + IDC_STATIC,6,1,300,9 + ICON IDI_INDEFINITE,IDC_STATIC,6,13,16,16,SS_CENTERIMAGE | + SS_REALSIZEIMAGE + LTEXT "Means the setting is different for different status modes / contacts", + IDC_STATIC,22,17,281,8,SS_NOPREFIX | SS_CENTERIMAGE +END + +IDD_SETAWAYMSG_BAK DIALOGEX 0, 0, 398, 133 +STYLE DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | + WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + EDITTEXT IDC_SAWAYMSG_MSGDATA,115,1,172,114,ES_MULTILINE | + ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL + PUSHBUTTON "OK",IDC_OK,115,117,60,14 + CONTROL "&Variables",IDC_SAWAYMSG_VARS,"MButtonClass",WS_TABSTOP, + 255,117,16,14,0x18000000L + CONTROL "Se&ttings",IDC_SAWAYMSG_OPTIONS,"MButtonClass", + WS_TABSTOP,271,117,16,14,0x18000000L + ICON IDI_IGNORE,IDC_SAWAYMSG_STATIC_IGNOREICON,379,108,18,16, + SS_CENTERIMAGE | SS_REALSIZEIMAGE + ICON IDI_SOE_ENABLED,IDC_SAWAYMSG_STATIC_REPLYICON,379,116,18, + 16,SS_CENTERIMAGE | SS_REALSIZEIMAGE + CONTROL "",IDC_SAWAYMSG_CONTACTSTREE,"SysTreeView32", + TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | + TVS_TRACKSELECT | WS_BORDER | WS_TABSTOP,289,1,108,114 + CONTROL "Ignore requests",IDC_SAWAYMSG_IGNOREREQ,"Button", + BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,307,116,80,8, + WS_EX_RIGHT + CONTROL "Send an autoreply",IDC_SAWAYMSG_SENDMSG,"Button", + BS_AUTO3STATE | BS_LEFTTEXT | WS_TABSTOP,307,124,80,8, + WS_EX_RIGHT + CONTROL "",IDC_SAWAYMSG_TREE,"SysTreeView32",TVS_HASBUTTONS | + TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | + TVS_SHOWSELALWAYS | TVS_TRACKSELECT | WS_BORDER | + WS_TABSTOP,1,1,112,114 + CONTROL "&Delete",IDC_SAWAYMSG_DELETE,"MButtonClass",WS_TABSTOP, + 2,117,16,14,0x18000000L + CONTROL "New &Category",IDC_SAWAYMSG_NEWCATEGORY,"MButtonClass", + WS_TABSTOP,18,117,16,14,0x18000000L + CONTROL "Save As &New",IDC_SAWAYMSG_SAVEASNEW,"MButtonClass", + WS_TABSTOP,34,117,16,14,0x18000000L + CONTROL "&Save",IDC_SAWAYMSG_SAVEMSG,"MButtonClass",WS_TABSTOP, + 50,117,16,14,0x18000000L + CONTROL "",IDC_SAWAYMSG_MSGSPLITTER,"Static",SS_ENHMETAFILE,113, + 0,2,115,WS_EX_STATICEDGE + CONTROL "",IDC_SAWAYMSG_CONTACTSPLITTER,"Static",SS_ENHMETAFILE, + 287,0,2,115,WS_EX_STATICEDGE +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO MOVEABLE PURE +BEGIN + IDD_POPUPOPTDLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 305 + VERTGUIDE, 90 + VERTGUIDE, 163 + TOPMARGIN, 7 + BOTTOMMARGIN, 230 + END + + IDD_AUTOREPLY, DIALOG + BEGIN + RIGHTMARGIN, 297 + VERTGUIDE, 6 + VERTGUIDE, 21 + VERTGUIDE, 296 + VERTGUIDE, 306 + TOPMARGIN, 7 + BOTTOMMARGIN, 224 + END + + IDD_SETAWAYMSG, DIALOG + BEGIN + BOTTOMMARGIN, 124 + END + + IDD_MESSAGES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 304 + VERTGUIDE, 138 + TOPMARGIN, 7 + BOTTOMMARGIN, 164 + END + + IDD_MODERNOPT_MESSAGES, DIALOG + BEGIN + RIGHTMARGIN, 366 + VERTGUIDE, 138 + HORZGUIDE, 13 + END + + IDD_MOREOPTDIALOG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 309 + TOPMARGIN, 7 + BOTTOMMARGIN, 229 + END + + IDD_READAWAYMSG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 178 + TOPMARGIN, 7 + END + + IDD_CONTACTSOPTDLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 304 + TOPMARGIN, 7 + BOTTOMMARGIN, 214 + END + + IDD_SETAWAYMSG_BAK, DIALOG + BEGIN + VERTGUIDE, 98 + HORZGUIDE, 111 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_MSGICON ICON DISCARDABLE "Images\\MsgIcon.ico" +IDI_SOE_ENABLED ICON DISCARDABLE "Images\\on.ico" +IDI_SOE_DISABLED ICON DISCARDABLE "Images\\off.ico" +IDI_DOT ICON DISCARDABLE "Images\\Dot.ico" +IDI_IGNORE ICON DISCARDABLE "Images\\Ignore.ico" +IDI_SAVE ICON DISCARDABLE "Images\\SaveMsg.ico" +IDI_SAVEASNEW ICON DISCARDABLE "Images\\SaveAsNew.ico" +IDI_DELETE ICON DISCARDABLE "Images\\Delete.ico" +IDI_NEWCATEGORY ICON DISCARDABLE "Images\\NewCat.ico" +IDI_VARIABLES ICON DISCARDABLE "Images\\Variables.ico" +IDI_NEWMESSAGE ICON DISCARDABLE "Images\\NewMessage.ico" +IDI_SETTINGS ICON DISCARDABLE "Images\\Settings.ico" +IDI_STATUS_OTHER ICON DISCARDABLE "Images\\Status_Other.ico" +IDI_INDEFINITE ICON DISCARDABLE "Images\\Indefinite.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_SAM_OPTIONS MENU DISCARDABLE +BEGIN + POPUP "Set away message window options" + BEGIN + MENUITEM "Show predefined &messages", IDM_SAM_OPTIONS_SHOWMSGTREE + MENUITEM "Show &contacts", IDM_SAM_OPTIONS_SHOWCONTACTTREE + + MENUITEM SEPARATOR + MENUITEM "Save default window settings &automatically", + IDM_SAM_OPTIONS_AUTOSAVEDLGSETTINGS + + MENUITEM "&Save current window settings as default", + IDM_SAM_OPTIONS_SAVEDLGSETTINGSNOW + + MENUITEM SEPARATOR + MENUITEM "Disable parsing of status messages by Variables plugin", + IDM_SAM_OPTIONS_DISABLEVARIABLES + + END +END + +IDR_MSGTREE_CATEGORYMENU MENU DISCARDABLE +BEGIN + POPUP "Message tree menu" + BEGIN + MENUITEM "Create new &message", IDM_MSGTREEMENU_NEWMESSAGE + MENUITEM "Create new &category", IDM_MSGTREEMENU_NEWCATEGORY + MENUITEM "&Rename", IDM_MSGTREEMENU_RENAME + MENUITEM "&Delete", IDM_MSGTREEMENU_DELETE + END +END + +IDR_MSGTREE_MESSAGEMENU MENU DISCARDABLE +BEGIN + POPUP "Message tree category menu" + BEGIN + POPUP "Set as &default for" + BEGIN + MENUITEM "On&line", IDR_MSGTREEMENU_DEF_ONL + MENUITEM "&Away", IDR_MSGTREEMENU_DEF_AWAY + MENUITEM "&NA", IDR_MSGTREEMENU_DEF_NA + MENUITEM "Occ&upied", IDR_MSGTREEMENU_DEF_OCC + MENUITEM "&DND", IDR_MSGTREEMENU_DEF_DND + MENUITEM "&Free for chat", IDR_MSGTREEMENU_DEF_FFC + MENUITEM "&Invisible", IDR_MSGTREEMENU_DEF_INV + MENUITEM "On the &Phone", IDR_MSGTREEMENU_DEF_OTP + MENUITEM "Out to &Lunch", IDR_MSGTREEMENU_DEF_OTL + END + MENUITEM SEPARATOR + MENUITEM "Create new &message", 40022 + MENUITEM "Create new &category", 40024 + MENUITEM "&Rename", IDM_MSGTREEMENU_RENAME + MENUITEM "&Delete", 40026 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_SOE_ENABLED BITMAP MOVEABLE PURE "Images\\on.bmp" +IDB_SOE_DISABLED BITMAP MOVEABLE PURE "Images\\off.bmp" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/!Deprecated/NewAwaySysMod/NewAwaySys.vcxproj b/plugins/!Deprecated/NewAwaySysMod/NewAwaySys.vcxproj new file mode 100644 index 0000000000..b6693ffd31 --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/NewAwaySys.vcxproj @@ -0,0 +1,242 @@ +п»ї + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {6A516E27-AC50-5374-756B-A1558DB2EFA9} + + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + + + DynamicLibrary + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)64\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)64\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + true + + + + Disabled + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Use + Level3 + EditAndContinue + Common.h + + + true + $(IntDir)$(TargetName).lib + Windows + false + $(SolutionDir)\lib + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + + + Disabled + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN64;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Use + Level3 + Common.h + + + true + $(IntDir)$(TargetName).lib + Windows + false + $(SolutionDir)\lib + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + + + Full + OnlyExplicitInline + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Sync + false + false + Use + Level3 + Size + Common.h + + + true + $(IntDir)$(TargetName).lib + true + true + Windows + false + $(SolutionDir)\lib + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + + + Full + OnlyExplicitInline + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN64;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Sync + false + false + Use + Level3 + Size + Common.h + + + true + $(IntDir)$(TargetName).lib + true + true + Windows + false + $(SolutionDir)\lib + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + + + + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/!Deprecated/NewAwaySysMod/NewAwaySys.vcxproj.filters b/plugins/!Deprecated/NewAwaySysMod/NewAwaySys.vcxproj.filters new file mode 100644 index 0000000000..bb85b875dd --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/NewAwaySys.vcxproj.filters @@ -0,0 +1,187 @@ +п»ї + + + + {116110a1-b9f8-4995-aab2-1de50eab806f} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {7c639270-1dc0-403f-a6ba-7da092e1f885} + h;hpp;hxx;hm;inl + + + {bbdb7c3b-6f74-434a-b577-46de841df2af} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + {b1737ff9-4769-4f5b-b414-ee0f5256de7f} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Documentation + + + Documentation + + + Documentation + + + + + Resource Files + + + \ No newline at end of file diff --git a/plugins/!Deprecated/NewAwaySysMod/Notification.cpp b/plugins/!Deprecated/NewAwaySysMod/Notification.cpp new file mode 100644 index 0000000000..ca3f271f47 --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/Notification.cpp @@ -0,0 +1,289 @@ +/* + New Away System - plugin for Miranda IM + Copyright (C) 2005-2007 Chervov Dmitry + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "Common.h" +#include "Path.h" +#include "Properties.h" + + +void ShowMsg(TCHAR *FirstLine, TCHAR *SecondLine, bool IsErrorMsg, int Timeout) +{ + if (ServiceExists(MS_POPUP_ADDPOPUPEX)) + { + POPUPDATAT ppd = {0}; + ppd.lchIcon = LoadIcon(NULL, IsErrorMsg ? IDI_EXCLAMATION : IDI_INFORMATION); +// lstrcpy(ppd.lpzContactName, FirstLine); +// lstrcpy(ppd.lpzText, SecondLine); + lstrcpy(ppd.lptzContactName, FirstLine); + lstrcpy(ppd.lptzText, SecondLine); + ppd.colorBack = IsErrorMsg ? 0x0202E3 : 0xE8F1FD; + ppd.colorText = IsErrorMsg ? 0xE8F1FD : 0x000000; + ppd.iSeconds = Timeout; + CallService(MS_POPUP_ADDPOPUPT, (WPARAM)&ppd, 0); + } else + { + MessageBox(NULL, SecondLine, FirstLine, MB_OK | (IsErrorMsg ? MB_ICONEXCLAMATION : MB_ICONINFORMATION)); + } +} + + +static int CALLBACK MenuWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_MEASUREITEM: + { + return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); + } + case WM_DRAWITEM: + { + return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); + } + } + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + + +static VOID CALLBACK ShowContactMenu(DWORD wParam) +// wParam = hContact +{ + POINT pt; + HWND hMenuWnd = CreateWindowEx(WS_EX_TOOLWINDOW, _T("static"), _T(MOD_NAME)_T("_MenuWindow"), 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, g_hInstance, NULL); + SetWindowLongPtr(hMenuWnd, GWLP_WNDPROC, (LONG)(WNDPROC)MenuWndProc); + HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)wParam, 0); + GetCursorPos(&pt); + SetForegroundWindow(hMenuWnd); + CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, 0, hMenuWnd, NULL), MPCF_CONTACTMENU), (LPARAM)wParam); + PostMessage(hMenuWnd, WM_NULL, 0, 0); + DestroyMenu(hMenu); + DestroyWindow(hMenuWnd); +} + +/* +void Popup_DoAction(HWND hWnd, BYTE Action, PLUGIN_DATA *pdata) +{ + HANDLE hContact = (HANDLE)CallService(MS_POPUP_GETCONTACT, (WPARAM)hWnd, 0); + switch (Action) + { + case PCA_OPENMESSAGEWND: // open message window + { + if (hContact && hContact != INVALID_HANDLE_VALUE) + { + CallServiceSync(ServiceExists("SRMsg/LaunchMessageWindow") ? "SRMsg/LaunchMessageWindow" : MS_MSG_SENDMESSAGE, (WPARAM)hContact, 0); + } + } break; + case PCA_OPENMENU: // open contact menu + { + if (hContact && hContact != INVALID_HANDLE_VALUE) + { + QueueUserAPC(ShowContactMenu, hMainThread, (ULONG_PTR)hContact); + } + } break; + case PCA_OPENDETAILS: // open contact details window + { + if (hContact != INVALID_HANDLE_VALUE) + { + CallServiceSync(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0); + } + } break; + case PCA_OPENHISTORY: // open contact history + { + if (hContact != INVALID_HANDLE_VALUE) + { + CallServiceSync(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM)hContact, 0); + } + } break; + case PCA_OPENLOG: // open log file + { + TCString LogFilePath; + LS_LOGINFO li = {0}; + li.cbSize = sizeof(li); + li.szID = LOG_ID; + li.hContact = hContact; + li.Flags = LSLI_TCHAR; + li.tszLogPath = LogFilePath.GetBuffer(MAX_PATH); + if (!CallService(MS_LOGSERVICE_GETLOGINFO, (WPARAM)&li, 0)) + { + LogFilePath.ReleaseBuffer(); + ShowLog(LogFilePath); + } else + { + LogFilePath.ReleaseBuffer(); + } + } break; + case PCA_CLOSEPOPUP: // close popup + { + PUDeletePopUp(hWnd); + } break; + case PCA_DONOTHING: // do nothing + break; + } +} + + +static int CALLBACK ReqNotifyPopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + PLUGIN_DATA *pdata; + switch (message) + { + case WM_COMMAND: + { + if (HIWORD(wParam) == STN_CLICKED) // left mouse button + { + pdata = (PLUGIN_DATA*)CallService(MS_POPUP_GETPLUGINDATA, (WPARAM)hWnd, 0); + if (pdata) + { + Popup_DoAction(hWnd, pdata->PopupLClickAction, pdata); + } + return true; + } + } break; + case WM_CONTEXTMENU: // right mouse button + { + pdata = (PLUGIN_DATA*)CallService(MS_POPUP_GETPLUGINDATA, (WPARAM)hWnd, 0); + if (pdata) + { + Popup_DoAction(hWnd, pdata->PopupRClickAction, pdata); + } + return true; + } break; + case UM_FREEPLUGINDATA: + { + pdata = (PLUGIN_DATA*)CallService(MS_POPUP_GETPLUGINDATA, (WPARAM)hWnd, 0); + if (pdata) + { + if (pdata->hStatusIcon) + { + DestroyIcon(pdata->hStatusIcon); + } + free(pdata); + } + return true; + } break; + } + return DefWindowProc(hWnd, message, wParam, lParam); +} + + +int ShowPopupNotification(COptPage &PopupNotifyData, HANDLE hContact, int iStatusMode) +{ // returns TRUE if popup was shown +// we take szProto, UIN and Message from VarParseData + POPUPDATAT ppd = {0}; + ppd.lchContact = hContact; + TCString ExtraText; + if (!iStatusMode) + { // if it's an xstatus message request + ExtraText = DBGetContactSettingString(NULL, VarParseData.szProto, "XStatusName", _T("")); + TCString XMsg(DBGetContactSettingString(NULL, VarParseData.szProto, "XStatusMsg", _T(""))); + if (XMsg.GetLen()) + { + if (ExtraText.GetLen()) + { + ExtraText += _T("\r\n"); + } + ExtraText += XMsg; + } + } else + { + ExtraText = VarParseData.Message; + } + TCString PopupMsg(*(TCString*)PopupNotifyData.GetValue(IDC_POPUPOPTDLG_POPUPFORMAT)); + if (ServiceExists(MS_VARS_FORMATSTRING)) + { + FORMATINFO fi = {0}; + fi.cbSize = sizeof(fi); + fi.flags = FIF_TCHAR; + fi.tszFormat = PopupMsg; + fi.hContact = hContact; + fi.tszExtraText = ExtraText; + TCHAR *szResult = (TCHAR*)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0); + if (szResult) + { + PopupMsg = szResult; + CallService(MS_VARS_FREEMEMORY, (WPARAM)szResult, 0); + } + } else + { + TCString szUIN; + _ultot(VarParseData.UIN, szUIN.GetBuffer(16), 10); + szUIN.ReleaseBuffer(); + TCHAR *szStatDesc = iStatusMode ? (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iStatusMode, GSMDF_TCHAR) : STR_XSTATUSDESC; + _ASSERT(szStatDesc); + PopupMsg = TCString((TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR)) + _T(" (") + szUIN + TranslateT(") is reading your ") + szStatDesc + TranslateT(" message:\r\n") + ExtraText; + } + if (PopupMsg.GetLen()) + { + TCHAR *pLineBreak = _tcsstr(PopupMsg, _T("\n")); + if (pLineBreak) + { + PopupMsg.GetBuffer(); + TCHAR *pNextLine = pLineBreak + 1; + while ((*pNextLine == '\r' || *pNextLine == '\n') && *pNextLine) + { + *pNextLine++; + } + _tcsncpy(ppd.lpzText, pNextLine, 499); + while ((*pLineBreak == '\r' || *pLineBreak == '\n') && (pLineBreak >= PopupMsg)) + { + *pLineBreak-- = 0; + } + PopupMsg.ReleaseBuffer(); + } else + { + lstrcpy(ppd.lpzText, _T("")); + } + _tcsncpy(ppd.lpzContactName, PopupMsg, 499); + ppd.colorBack = (PopupNotifyData.GetValue(IDC_POPUPOPTDLG_DEFBGCOLOUR) ? 0 : PopupNotifyData.GetValue(IDC_POPUPOPTDLG_BGCOLOUR)); + ppd.colorText = (PopupNotifyData.GetValue(IDC_POPUPOPTDLG_DEFTEXTCOLOUR) ? 0 : PopupNotifyData.GetValue(IDC_POPUPOPTDLG_TEXTCOLOUR)); + ppd.PluginWindowProc = (WNDPROC)ReqNotifyPopupDlgProc; + PLUGIN_DATA *pdata = (PLUGIN_DATA*)calloc(1, sizeof(PLUGIN_DATA)); + if (!iStatusMode) + { // it's an xstatus message request + ppd.lchIcon = pdata->hStatusIcon = (HICON)CallProtoService(VarParseData.szProto, PS_ICQ_GETCUSTOMSTATUSICON, 0, 0); + } + if (!pdata->hStatusIcon || (DWORD)pdata->hStatusIcon == CALLSERVICE_NOTFOUND) + { + pdata->hStatusIcon = NULL; + ppd.lchIcon = LoadSkinnedProtoIcon(VarParseData.szProto, iStatusMode); + } + pdata->PopupLClickAction = PopupNotifyData.GetValue(IDC_POPUPOPTDLG_LCLICK_ACTION); + pdata->PopupRClickAction = PopupNotifyData.GetValue(IDC_POPUPOPTDLG_RCLICK_ACTION); + ppd.PluginData = pdata; + ppd.iSeconds = PopupNotifyData.GetValue(IDC_POPUPOPTDLG_POPUPDELAY); + CallService(MS_POPUP_ADDPOPUPT, (WPARAM)&ppd, 0); + if (hContact) + { + SkinPlaySound(AWAYSYS_STATUSMSGREQUEST_SOUND); + } + return true; + } + return false; +} +*/ + +void ShowLog(TCString &LogFilePath) +{ + int Result = (int)ShellExecute(NULL, _T("open"), LogFilePath, NULL, NULL, SW_SHOW); + if (Result <= 32) // Error + { + TCHAR szError[64]; + mir_sntprintf(szError, SIZEOF(szError), TranslateT("Error #%d"), Result); + ShowMsg(szError, TranslateT("Can't open log file ") + LogFilePath, true); + } +} diff --git a/plugins/!Deprecated/NewAwaySysMod/Path.h b/plugins/!Deprecated/NewAwaySysMod/Path.h new file mode 100644 index 0000000000..e64b7ceb3c --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/Path.h @@ -0,0 +1,43 @@ +/* + New Away System - plugin for Miranda IM + Copyright (c) 2005-2007 Chervov Dmitry + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#pragma once + +#include "m_utils.h" +#include "..\CommonLibs\CString.h" + + +__inline TCString Path_ToRelative(TCString &Path) +{ + CString Str; + Str.GetBuffer(MAX_PATH); + CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)(const char*)TCHAR2ANSI(Path), (LPARAM)(char*)Str); + Str.ReleaseBuffer(); + return ANSI2TCHAR(Str); +} + + +__inline TCString Path_ToAbsolute(TCString &Path) +{ + CString Str; + Str.GetBuffer(MAX_PATH); + CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)(const char*)TCHAR2ANSI(Path), (LPARAM)(char*)Str); + Str.ReleaseBuffer(); + return ANSI2TCHAR(Str); +} diff --git a/plugins/!Deprecated/NewAwaySysMod/Properties.cpp b/plugins/!Deprecated/NewAwaySysMod/Properties.cpp new file mode 100644 index 0000000000..c9dc3c1c9c --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/Properties.cpp @@ -0,0 +1,411 @@ +/* + New Away System - plugin for Miranda IM + Copyright (C) 2005-2007 Chervov Dmitry + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "Common.h" +#include "Properties.h" + +CProtoStates g_ProtoStates; + +void ResetContactSettingsOnStatusChange(HANDLE hContact) +{ + DBDeleteContactSetting(hContact, MOD_NAME, DB_REQUESTCOUNT); + DBDeleteContactSetting(hContact, MOD_NAME, DB_SENDCOUNT); + DBDeleteContactSetting(hContact, MOD_NAME, DB_MESSAGECOUNT); +} + + +void ResetSettingsOnStatusChange(const char *szProto = NULL, int bResetPersonalMsgs = false, int Status = 0) +{ + if (bResetPersonalMsgs) + { // bResetPersonalMsgs &&= g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_SAVEPERSONALMSGS); + bResetPersonalMsgs = !g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_SAVEPERSONALMSGS); + } + HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact) + { + const char *szCurProto; + if (!szProto || ((szCurProto = (const char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0)) && !lstrcmpA(szProto, szCurProto))) + { + ResetContactSettingsOnStatusChange(hContact); + if (bResetPersonalMsgs) + { + CContactSettings(Status, hContact).SetMsgFormat(SMF_PERSONAL, NULL); // TODO: delete only when SAM dialog opens? + } + } + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + } +} + + +CProtoState::CStatus& CProtoState::CStatus::operator = (int Status) +{ + _ASSERT(Status >= ID_STATUS_OFFLINE && Status <= ID_STATUS_OUTTOLUNCH); + if (Status < ID_STATUS_OFFLINE || Status > ID_STATUS_OUTTOLUNCH) + { + return *this; // ignore status change if the new status is unknown + } + bool bModified = false; + if (szProto) + { + if (this->Status != Status) + { + this->Status = Status; + (*GrandParent)[szProto].AwaySince.Reset(); + ResetSettingsOnStatusChange(szProto, true, Status); + bModified = true; + } + if ((*GrandParent)[szProto].TempMsg.IsSet()) + { + (*GrandParent)[szProto].TempMsg.Unset(); + bModified = true; + } + } else // global status change + { + int I; + int bStatusModified = false; + for (I = 0; I < GrandParent->GetSize(); I++) + { + CProtoState &State = (*GrandParent)[I]; + if (!DBGetContactSettingByte(NULL, State.GetProto(), "LockMainStatus", 0)) // if the protocol isn't locked + { + if (State.Status != Status) + { + State.Status.Status = Status; // "Status.Status" - changing Status directly to prevent recursive calls to the function + State.AwaySince.Reset(); + bModified = true; + bStatusModified = true; + } + if (State.TempMsg.IsSet()) + { + State.TempMsg.Unset(); + bModified = true; + } + if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_RESETPROTOMSGS)) + { + CProtoSettings(State.szProto, Status).SetMsgFormat(SMF_PERSONAL, NULL); + } + } + } + if (bStatusModified) + { + ResetSettingsOnStatusChange(NULL, true, Status); + } + } + if (bModified && g_SetAwayMsgPage.GetWnd()) + { + SendMessage(g_SetAwayMsgPage.GetWnd(), UM_SAM_PROTOSTATUSCHANGED, (WPARAM)(char*)szProto, 0); + } + return *this; +} + + +void CProtoState::CAwaySince::Reset() +{ + GetLocalTime(&AwaySince); + if (GrandParent && !szProto) + { + int I; + for (I = 0; I < GrandParent->GetSize(); I++) + { + GetLocalTime((*GrandParent)[I].AwaySince); + } + } +} + + +void CContactSettings::SetMsgFormat(int Flags, TCString Message) +{ + if (Flags & SMF_PERSONAL) + { // set a personal message for a contact. also it's used to set global status message (hContact = NULL). + // if Message == NULL, then the function deletes the message. + CString DBSetting(StatusToDBSetting(Status, DB_STATUSMSG, IDC_MOREOPTDLG_PERSTATUSPERSONAL)); + if (g_AutoreplyOptPage.GetDBValueCopy(IDC_REPLYDLG_RESETCOUNTERWHENSAMEICON) && GetMsgFormat(SMF_PERSONAL) != (const TCHAR*)Message) + { + ResetContactSettingsOnStatusChange(hContact); + } + if (Message != NULL) + { + DBWriteContactSettingTString(hContact, MOD_NAME, DBSetting, Message); + } else + { + DBDeleteContactSetting(hContact, MOD_NAME, DBSetting); + } + } + if (Flags & (SMF_LAST | SMF_TEMPORARY)) + { + _ASSERT(!hContact); + CProtoSettings().SetMsgFormat(Flags & (SMF_LAST | SMF_TEMPORARY), Message); + } +} + + +TCString CContactSettings::GetMsgFormat(int Flags, int *pOrder, char *szProtoOverride) +// returns the requested message; sets Order to the order of the message in the message tree, if available; or to -1 otherwise. +// szProtoOverride is needed only to get status message of the right protocol when the ICQ contact is on list, but not with the same protocol on which it requests the message - this way we can still get contact details. +{ + TCString Message = NULL; + if (pOrder) + { + *pOrder = -1; + } + if (Flags & GMF_PERSONAL) + { // try getting personal message (it overrides global) + Message = DBGetContactSettingString(hContact, MOD_NAME, StatusToDBSetting(Status, DB_STATUSMSG, IDC_MOREOPTDLG_PERSTATUSPERSONAL), (TCHAR*)NULL); + } + if (Flags & (GMF_LASTORDEFAULT | GMF_PROTOORGLOBAL | GMF_TEMPORARY) && Message.IsEmpty()) + { + char *szProto = szProtoOverride ? szProtoOverride : (hContact ? (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0) : NULL); + if (Flags & (GMF_LASTORDEFAULT | GMF_PROTOORGLOBAL)) + { // we mustn't pass here by GMF_TEMPORARY flag, as otherwise we'll handle GMF_TEMPORARY | GMF_PERSONAL combination incorrectly, which is supposed to get only per-contact messages, and at the same time also may be used with NULL contact to get the global status message + Message = CProtoSettings(szProto).GetMsgFormat(Flags, pOrder); + } else if (!hContact) + { // handle global temporary message too + if (g_ProtoStates[szProto].TempMsg.IsSet()) + { + Message = g_ProtoStates[szProto].TempMsg; + } + } + } + return Message; +} + + +void CProtoSettings::SetMsgFormat(int Flags, TCString Message) +{ + if (Flags & (SMF_TEMPORARY | SMF_PERSONAL) && g_AutoreplyOptPage.GetDBValueCopy(IDC_REPLYDLG_RESETCOUNTERWHENSAMEICON) && GetMsgFormat(Flags & (SMF_TEMPORARY | SMF_PERSONAL)) != (const TCHAR*)Message) + { + ResetSettingsOnStatusChange(szProto); + } + if (Flags & SMF_TEMPORARY) + { + _ASSERT(!Status || Status == g_ProtoStates[szProto].Status); + g_ProtoStates[szProto].TempMsg = (szProto || Message != NULL) ? Message : CProtoSettings(NULL, Status).GetMsgFormat(GMF_LASTORDEFAULT); + } + if (Flags & SMF_PERSONAL) + { // set a "personal" message for a protocol. also it's used to set global status message (hContact = NULL). + // if Message == NULL, then we'll use the "default" message - i.e. it's either the global message for szProto != NULL (we delete the per-proto DB setting), or it's just a default message for a given status for szProto == NULL. + g_ProtoStates[szProto].TempMsg.Unset(); + CString DBSetting(ProtoStatusToDBSetting(DB_STATUSMSG, IDC_MOREOPTDLG_PERSTATUSPROTOMSGS)); + if (Message != NULL) + { + DBWriteContactSettingTString(NULL, MOD_NAME, DBSetting, Message); + } else + { + if (!szProto) + { + DBWriteContactSettingTString(NULL, MOD_NAME, DBSetting, CProtoSettings(NULL, Status).GetMsgFormat(GMF_LASTORDEFAULT)); // global message can't be NULL; we can use an empty string instead if it's really necessary + } else + { + DBDeleteContactSetting(NULL, MOD_NAME, DBSetting); + } + } + } + if (Flags & SMF_LAST) + { + COptPage MsgTreeData(g_MsgTreePage); + COptItem_TreeCtrl *TreeCtrl = (COptItem_TreeCtrl*)MsgTreeData.Find(IDV_MSGTREE); + TreeCtrl->DBToMem(CString(MOD_NAME)); + int RecentGroupID = GetRecentGroupID(Status); + if (RecentGroupID == -1) + { // we didn't find the group, it also means that we're using per status messages; so we need to create it + TreeCtrl->Value.AddElem(CTreeItem(Status ? (const TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, Status, GSMDF_TCHAR) : MSGTREE_RECENT_OTHERGROUP, g_Messages_RecentRootID, RecentGroupID = TreeCtrl->GenerateID(), TIF_GROUP)); + TreeCtrl->SetModified(true); + } + int I; + TCString Title(_T("")); + for (I = 0; I < TreeCtrl->Value.GetSize(); I++) // try to find an identical message in the same group (to prevent saving multiple identical messages), or at least if we'll find an identical message somewhere else, then we'll use its title for our new message + { + if (!(TreeCtrl->Value[I].Flags & TIF_GROUP) && TreeCtrl->Value[I].User_Str1 == (const TCHAR*)Message) + { + if (TreeCtrl->Value[I].ParentID == RecentGroupID) + { // found it in the same group + int GroupOrder = TreeCtrl->IDToOrder(RecentGroupID); + TreeCtrl->Value.MoveElem(I, (GroupOrder >= 0) ? (GroupOrder + 1) : 0); // now move it to the top of recent messages list + TreeCtrl->SetModified(true); + break; // no reason to search for anything else + } else if (Title.IsEmpty()) + { // it's not in the same group, but at least we'll use its title + Title = TreeCtrl->Value[I].Title; + } + } + } + if (I == TreeCtrl->Value.GetSize()) + { // we didn't find an identical message in the same group, so we'll add our new message here + if (Title.IsEmpty()) + { // didn't find a title for our message either + if (Message.GetLen() > MRM_MAX_GENERATED_TITLE_LEN) + { + Title = Message.Left(MRM_MAX_GENERATED_TITLE_LEN - 3) + _T("..."); + } else + { + Title = Message; + } + TCHAR *p = Title.GetBuffer(); + while (*p) // remove "garbage" + { + if (!(p = _tcspbrk(p, _T("\r\n\t")))) + { + break; + } + *p++ = ' '; + } + Title.ReleaseBuffer(); + } + int GroupOrder = TreeCtrl->IDToOrder(RecentGroupID); + TreeCtrl->Value.InsertElem(CTreeItem(Title, RecentGroupID, TreeCtrl->GenerateID(), 0, Message), (GroupOrder >= 0) ? (GroupOrder + 1) : 0); + TreeCtrl->SetModified(true); + } + // now clean up here + int MRMNum = 0; + int MaxMRMNum = g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_RECENTMSGSCOUNT); + for (I = 0; I < TreeCtrl->Value.GetSize(); I++) + { + if (TreeCtrl->Value[I].ParentID == RecentGroupID) + { // found a child of our group + if (TreeCtrl->Value[I].Flags & TIF_GROUP || ++MRMNum > MaxMRMNum) // what groups are doing here?! :)) + { + TreeCtrl->Value.RemoveElem(I); + TreeCtrl->SetModified(true); + I--; + } + } + } + if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_PERSTATUSMRM)) + { // if we're saving recent messages per status, then remove any messages that were left at the recent messages' root + for (I = 0; I < TreeCtrl->Value.GetSize(); I++) + { + if (TreeCtrl->Value[I].ParentID == g_Messages_RecentRootID) + { + if (!(TreeCtrl->Value[I].Flags & TIF_GROUP)) + { + TreeCtrl->Value.RemoveElem(I); + TreeCtrl->SetModified(true); + I--; + } + } + } + } + TreeCtrl->MemToDB(CString(MOD_NAME)); + } +} + + +TCString CProtoSettings::GetMsgFormat(int Flags, int *pOrder) +// returns the requested message; sets Order to the order of the message in the message tree, if available; or to -1 otherwise. +{ + TCString Message = NULL; + if (pOrder) + { + *pOrder = -1; + } + if (Flags & GMF_TEMPORARY) + { + _ASSERT(!Status || Status == g_ProtoStates[szProto].Status); + if (g_ProtoStates[szProto].TempMsg.IsSet()) + { + Message = g_ProtoStates[szProto].TempMsg; + Flags &= ~GMF_PERSONAL; // don't allow personal message to overwrite our NULL temporary message + } + } + if (Flags & GMF_PERSONAL && Message == NULL) + { // try getting personal message (it overrides global) + Message = DBGetContactSettingString(NULL, MOD_NAME, ProtoStatusToDBSetting(DB_STATUSMSG, IDC_MOREOPTDLG_PERSTATUSPROTOMSGS), (TCHAR*)NULL); + } + if (Flags & GMF_PROTOORGLOBAL && Message == NULL) + { + Message = CProtoSettings().GetMsgFormat(GMF_PERSONAL | (Flags & GMF_TEMPORARY), pOrder); + return (Message == NULL) ? _T("") : Message; // global message can't be NULL + } + if (Flags & GMF_LASTORDEFAULT && Message == NULL) + { // try to get the last or default message, depending on current settings + COptPage MsgTreeData(g_MsgTreePage); + COptItem_TreeCtrl *TreeCtrl = (COptItem_TreeCtrl*)MsgTreeData.Find(IDV_MSGTREE); + TreeCtrl->DBToMem(CString(MOD_NAME)); + Message = NULL; + if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_USELASTMSG)) // if using last message by default... + { + Message = DBGetContactSettingString(NULL, MOD_NAME, ProtoStatusToDBSetting(DB_STATUSMSG, IDC_MOREOPTDLG_PERSTATUSPROTOMSGS), (TCHAR*)NULL); // try per-protocol message first + if (Message.IsEmpty()) + { + Message = NULL; // to be sure it's NULL, not "" - as we're checking 'Message == NULL' later + int RecentGroupID = GetRecentGroupID(Status); + if (RecentGroupID != -1) + { + int I; + for (I = 0; I < TreeCtrl->Value.GetSize(); I++) // find first message in the group + { + if (TreeCtrl->Value[I].ParentID == RecentGroupID && !(TreeCtrl->Value[I].Flags & TIF_GROUP)) + { + Message = TreeCtrl->Value[I].User_Str1; + if (pOrder) + { + *pOrder = I; + } + break; + } + } + } + } + } // else, if using default message by default... + if (Message == NULL) // ...or we didn't succeed retrieving the last message + { // get default message for this status + int DefMsgID = -1; + static struct { + int DBSetting, Status; + } DefMsgDlgItems[] = { + IDS_MESSAGEDLG_DEF_ONL, ID_STATUS_ONLINE, + IDS_MESSAGEDLG_DEF_AWAY, ID_STATUS_AWAY, + IDS_MESSAGEDLG_DEF_NA, ID_STATUS_NA, + IDS_MESSAGEDLG_DEF_OCC, ID_STATUS_OCCUPIED, + IDS_MESSAGEDLG_DEF_DND, ID_STATUS_DND, + IDS_MESSAGEDLG_DEF_FFC, ID_STATUS_FREECHAT, + IDS_MESSAGEDLG_DEF_INV, ID_STATUS_INVISIBLE, + IDS_MESSAGEDLG_DEF_OTP, ID_STATUS_ONTHEPHONE, + IDS_MESSAGEDLG_DEF_OTL, ID_STATUS_OUTTOLUNCH + }; + int I; + for (I = 0; I < lengthof(DefMsgDlgItems); I++) + { + if (DefMsgDlgItems[I].Status == Status) + { + DefMsgID = MsgTreeData.GetDBValue(DefMsgDlgItems[I].DBSetting); + break; + } + } + if (DefMsgID == -1) + { + DefMsgID = MsgTreeData.GetDBValue(IDS_MESSAGEDLG_DEF_AWAY); // use away message for unknown statuses + } + int Order = TreeCtrl->IDToOrder(DefMsgID); // this will return -1 in any case if something goes wrong + if (Order >= 0) + { + Message = TreeCtrl->Value[Order].User_Str1; + } + if (pOrder) + { + *pOrder = Order; + } + } + if (Message == NULL) + { + Message = _T(""); // last or default message can't be NULL.. otherwise ICQ won't reply to status message requests and won't notify us of status message requests at all + } + } + return Message; +} diff --git a/plugins/!Deprecated/NewAwaySysMod/Properties.h b/plugins/!Deprecated/NewAwaySysMod/Properties.h new file mode 100644 index 0000000000..6b981bd77e --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/Properties.h @@ -0,0 +1,605 @@ +/* + New Away System - plugin for Miranda IM + Copyright (c) 2005-2007 Chervov Dmitry + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#pragma once + +#include "Common.h" +#include "MsgTree.h" +#include "ContactList.h" +#include "statusmodes.h" + +#define DB_STATUSMSG "StatusMsg" +#define DB_ENABLEREPLY "EnableReply" +#define DB_IGNOREREQUESTS "IgnoreRequests" +//#define DB_POPUPNOTIFY "UsePopups" +#define DB_UNK_CONTACT_PREFIX "Unk" // DB_ENABLEREPLY, DB_IGNOREREQUESTS and DB_POPUPNOTIFY settings prefix for not-on-list contacts + +class _CWndUserData +{ +public: + _CWndUserData(): MsgTree(NULL), CList(NULL) {} + + CMsgTree *MsgTree; + CCList *CList; +}; + + +class CWndUserData +{ +public: + CWndUserData(HWND hWnd): hWnd(hWnd) + { + _ASSERT(hWnd); + dat = (_CWndUserData*)GetWindowLongPtr(hWnd, GWLP_USERDATA); + if (!dat) + { + dat = new _CWndUserData; + SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)dat); + } + } + + ~CWndUserData() + { + _ASSERT(dat == (_CWndUserData*)GetWindowLongPtr(hWnd, GWLP_USERDATA)); + if (!dat->MsgTree && !dat->CList) // TODO: Uninitialized Memory Read on closing the options dialog - fix it + { + SetWindowLongPtr(hWnd, GWLP_USERDATA, NULL); + delete dat; // TODO: memory leak - this is never executed - fix it + } + } + + CMsgTree *GetMsgTree() {return dat->MsgTree;} + void SetMsgTree(CMsgTree *MsgTree) {dat->MsgTree = MsgTree;} + CCList *GetCList() {return dat->CList;} + void SetCList(CCList *CList) {dat->CList = CList;} + +private: + HWND hWnd; + _CWndUserData *dat; +}; + +#define IL_SKINICON 0x80000000 +#define IL_PROTOICON 0x40000000 + +#define ILI_NOICON (-1) +#define ILI_EVENT_MESSAGE 0 +#define ILI_EVENT_URL 1 +#define ILI_EVENT_FILE 2 +#define ILI_PROTO_ONL 3 +#define ILI_PROTO_AWAY 4 +#define ILI_PROTO_NA 5 +#define ILI_PROTO_OCC 6 +#define ILI_PROTO_DND 7 +#define ILI_PROTO_FFC 8 +#define ILI_PROTO_INV 9 +#define ILI_PROTO_OTP 10 +#define ILI_PROTO_OTL 11 +#define ILI_DOT 12 +#define ILI_MSGICON 13 +#define ILI_IGNORE 14 +#define ILI_SOE_DISABLED 15 +#define ILI_SOE_ENABLED 16 +#define ILI_NEWMESSAGE 17 +#define ILI_NEWCATEGORY 18 +#define ILI_SAVE 19 +#define ILI_SAVEASNEW 20 +#define ILI_DELETE 21 +#define ILI_SETTINGS 22 +#define ILI_STATUS_OTHER 23 + +static int Icons[] = { + SKINICON_EVENT_MESSAGE | IL_SKINICON, SKINICON_EVENT_URL | IL_SKINICON, SKINICON_EVENT_FILE | IL_SKINICON, + ID_STATUS_ONLINE | IL_PROTOICON, ID_STATUS_AWAY | IL_PROTOICON, ID_STATUS_NA | IL_PROTOICON, ID_STATUS_OCCUPIED | IL_PROTOICON, ID_STATUS_DND | IL_PROTOICON, ID_STATUS_FREECHAT | IL_PROTOICON, ID_STATUS_INVISIBLE | IL_PROTOICON, ID_STATUS_ONTHEPHONE | IL_PROTOICON, ID_STATUS_OUTTOLUNCH | IL_PROTOICON, + IDI_DOT, IDI_MSGICON, IDI_IGNORE, IDI_SOE_ENABLED, IDI_SOE_DISABLED, IDI_NEWMESSAGE, IDI_NEWCATEGORY, IDI_SAVE, IDI_SAVEASNEW, IDI_DELETE, IDI_SETTINGS, IDI_STATUS_OTHER +}; + + +class CIconList +{ +public: + ~CIconList() + { + int I; + for (I = 0; I < IconList.GetSize(); I++) + { + if (IconList[I]) + { + DestroyIcon(IconList[I]); + } + } + } + + HICON& operator [] (int nIndex) {return IconList[nIndex];} + void ReloadIcons() + { + int cxIcon = GetSystemMetrics(SM_CXSMICON); + int cyIcon = GetSystemMetrics(SM_CYSMICON); + int I; + for (I = 0; I < lengthof(Icons); I++) + { + if (IconList.GetSize() > I && IconList[I]) + { + DestroyIcon(IconList[I]); + } + if (Icons[I] & IL_SKINICON) + { + IconList.SetAtGrow(I) = (HICON)CopyImage(LoadSkinnedIcon(Icons[I] & ~IL_SKINICON), IMAGE_ICON, cxIcon, cyIcon, LR_COPYFROMRESOURCE); + } else if (Icons[I] & IL_PROTOICON) + { + IconList.SetAtGrow(I) = (HICON)CopyImage(LoadSkinnedProtoIcon(NULL, Icons[I] & ~IL_PROTOICON), IMAGE_ICON, cxIcon, cyIcon, LR_COPYFROMRESOURCE); + } else + { + IconList.SetAtGrow(I) = (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(Icons[I]), IMAGE_ICON, cxIcon, cyIcon, 0); + } + } + } + +private: + TMyArray IconList; +}; + +extern CIconList g_IconList; + + +class CProtoStates; + +class CProtoState +{ +public: + CProtoState(const char* szProto, CProtoStates* Parent): szProto(szProto), Parent(Parent), Status(szProto, Parent), AwaySince(szProto, Parent) {} + + class CStatus + { + public: + CStatus(const char* szProto, CProtoStates* GrandParent): szProto(szProto), GrandParent(GrandParent), Status(ID_STATUS_OFFLINE) {} + CStatus& operator = (int Status); + operator int() {return Status;} + friend class CProtoState; + private: + int Status; + CString szProto; + CProtoStates* GrandParent; + } Status; + + class CAwaySince + { + public: + CAwaySince(const char* szProto, CProtoStates* GrandParent): szProto(szProto), GrandParent(GrandParent) {Reset();} + void Reset(); + operator LPSYSTEMTIME() {return &AwaySince;} + friend class CProtoState; + private: + SYSTEMTIME AwaySince; + CString szProto; + CProtoStates* GrandParent; + } AwaySince; + + class CCurStatusMsg + { + public: + CCurStatusMsg() {*this = NULL;} + CCurStatusMsg& operator = (TCString Msg) + { + CurStatusMsg = Msg; + SYSTEMTIME st; + GetLocalTime(&st); + SystemTimeToFileTime(&st, (LPFILETIME)&LastUpdateTime); // I'm too lazy to declare FILETIME structure and then copy its data to absolutely equivalent ULARGE_INTEGER structure, so we'll just pass a pointer to the ULARGE_INTEGER directly ;-P + return *this; + } + operator TCString() {return CurStatusMsg;} + DWORD GetUpdateTimeDifference() + { + ULARGE_INTEGER CurTime; + SYSTEMTIME st; + GetLocalTime(&st); + SystemTimeToFileTime(&st, (LPFILETIME)&CurTime); + return (DWORD)((CurTime.QuadPart - LastUpdateTime.QuadPart) / 10000); // in milliseconds + } + private: + TCString CurStatusMsg; + ULARGE_INTEGER LastUpdateTime; + } CurStatusMsg; + + class CTempMsg + { // we use temporary messages to keep user-defined per-protocol messages intact, when changing messages through MS_NAS_SETSTATE, or when autoaway becomes active etc.. temporary messages are automatically resetted when protocol status changes + public: + CTempMsg(): iIsSet(0) {} + CTempMsg& operator = (TCString Msg) {this->Msg = Msg; iIsSet = true; return *this;} + operator TCString() + { + _ASSERT(iIsSet); + return Msg; + } + void Unset() {iIsSet = false;} + int IsSet() {return iIsSet;} + + private: + int iIsSet; // as we need TempMsg to support every possible value, including NULL and "", we'll use this variable to specify whether TempMsg is set + TCString Msg; + } TempMsg; + + void SetParent(CProtoStates* Parent) + { + this->Parent = Parent; + Status.GrandParent = Parent; + AwaySince.GrandParent = Parent; + } + + CString &GetProto() {return szProto;} + +//NightFox: fix? +//private: +public: + CString szProto; + CProtoStates* Parent; +}; + + +class CProtoStates // this class stores all protocols' dynamic data +{ +public: + CProtoStates() {} + + CProtoStates(const CProtoStates &States) {*this = States;} + CProtoStates& operator = (const CProtoStates& States) + { + ProtoStates = States.ProtoStates; + int I; + for (I = 0; I < ProtoStates.GetSize(); I++) + { + ProtoStates[I].SetParent(this); + } + return *this; + } + + CProtoState& operator[](const char *szProto) + { + int I; + for (I = 0; I < ProtoStates.GetSize(); I++) + { + if (ProtoStates[I].GetProto() == szProto) + { + return ProtoStates[I]; + } + } + if (!szProto) // we need to be sure that we have _all_ protocols in the list, before dealing with global status, so we're adding them here. + { + int ProtoCount; + PROTOCOLDESCRIPTOR **proto; + CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&ProtoCount, (LPARAM)&proto); + int I; + for (I = 0; I < ProtoCount; I++) + { + if (proto[I]->type == PROTOTYPE_PROTOCOL) + { + (*this)[proto[I]->szName]; // add a protocol if it isn't in the list yet + } + } + } + return ProtoStates[ProtoStates.AddElem(CProtoState(szProto, this))]; + } + + friend class CProtoState; + friend class CProtoState::CStatus; + friend class CProtoState::CAwaySince; + +private: + CProtoState& operator[](int nIndex) {return ProtoStates[nIndex];} + int GetSize() {return ProtoStates.GetSize();} + + TMyArray ProtoStates; +}; + +extern CProtoStates g_ProtoStates; + + +static struct +{ + int Status; + char *Setting; +} StatusSettings[] = { + ID_STATUS_OFFLINE, "Off", + ID_STATUS_ONLINE, "Onl", + ID_STATUS_AWAY, "Away", + ID_STATUS_NA, "Na", + ID_STATUS_DND, "Dnd", + ID_STATUS_OCCUPIED, "Occ", + ID_STATUS_FREECHAT, "Ffc", + ID_STATUS_INVISIBLE, "Inv", + ID_STATUS_ONTHEPHONE, "Otp", + ID_STATUS_OUTTOLUNCH, "Otl", + ID_STATUS_IDLE, "Idle" +}; + + +class CProtoSettings +{ +public: + CProtoSettings(const char *szProto = NULL, int iStatus = 0): szProto(szProto), Status(iStatus, szProto) + { + Autoreply.Parent = this; + } + + CString ProtoStatusToDBSetting(const char *Prefix, int MoreOpt_PerStatusID = 0) + { + if (!MoreOpt_PerStatusID || g_MoreOptPage.GetDBValueCopy(MoreOpt_PerStatusID)) + { + int I; + for (I = 0; I < lengthof(StatusSettings); I++) + { + if (Status == StatusSettings[I].Status) + { + return szProto ? (CString(Prefix) + "_" + szProto + "_" + StatusSettings[I].Setting) : (CString(Prefix) + StatusSettings[I].Setting); + } + } + } + return szProto ? (CString(Prefix) + "_" + szProto) : CString(Prefix); + } + + class CAutoreply + { + public: + CAutoreply& operator = (const int Value) + { + CString Setting(Parent->szProto ? Parent->ProtoStatusToDBSetting(DB_ENABLEREPLY, IDC_MOREOPTDLG_PERSTATUSPROTOSETTINGS) : DB_ENABLEREPLY); + if (DBGetContactSettingByte(NULL, MOD_NAME, Setting, VAL_USEDEFAULT) == Value) + { + return *this; // prevent deadlocks when calling UpdateSOEButtons + } + if (Value != VAL_USEDEFAULT) + { + DBWriteContactSettingByte(NULL, MOD_NAME, Setting, Value != 0); + } else + { + DBDeleteContactSetting(NULL, MOD_NAME, Setting); + } + /*if (!Parent->szProto) + { + UpdateSOEButtons(); + }*/ + return *this; + } + operator int() {return DBGetContactSettingByte(NULL, MOD_NAME, Parent->szProto ? Parent->ProtoStatusToDBSetting(DB_ENABLEREPLY, IDC_MOREOPTDLG_PERSTATUSPROTOSETTINGS) : DB_ENABLEREPLY, Parent->szProto ? VAL_USEDEFAULT : AUTOREPLY_DEF_REPLY);} + int IncludingParents() // takes into account global data also, if per-protocol setting is not defined + { + _ASSERT(Parent->szProto); + int Value = *this; + return (Value == VAL_USEDEFAULT) ? CProtoSettings(NULL).Autoreply : Value; + } + friend class CProtoSettings; + private: + CProtoSettings *Parent; + } Autoreply; + + class CStatus + { + public: + CStatus(int iStatus = 0, const char *szProto = NULL): Status(iStatus), szProto(szProto) {} + CStatus& operator = (int Status) {this->Status = Status; return *this;} + operator int() + { + if (!Status) + { + Status = g_ProtoStates[szProto].Status; + } + return Status; + } + private: + int Status; + const char *szProto; + } Status; + + void SetMsgFormat(int Flags, TCString Message); + TCString GetMsgFormat(int Flags, int *pOrder = NULL); + +//NightFox: fix? +//private: +public: + const char *szProto; +}; + + +__inline CString StatusToDBSetting(int Status, const char *Prefix, int MoreOpt_PerStatusID = 0) +{ + if (!MoreOpt_PerStatusID || g_MoreOptPage.GetDBValueCopy(MoreOpt_PerStatusID)) + { + int I; + for (I = 0; I < lengthof(StatusSettings); I++) + { + if (Status == StatusSettings[I].Status) + { + return CString(Prefix) + StatusSettings[I].Setting; + } + } + } + return CString(Prefix); +} + + +__inline CString ContactStatusToDBSetting(int Status, const char *Prefix, int MoreOpt_PerStatusID, HANDLE hContact) +{ + if (hContact == INVALID_HANDLE_VALUE) + { // it's a not-on-list contact + return CString(DB_UNK_CONTACT_PREFIX) + Prefix; + } + if (hContact) + { + StatusToDBSetting(Status, Prefix, MoreOpt_PerStatusID); + } + return CString(Prefix); +} + + +class CContactSettings +{ +public: + CContactSettings(int iStatus = 0, HANDLE hContact = NULL): Status(iStatus, hContact), hContact(hContact) + { + Ignore.Parent = this; + Autoreply.Parent = this; +// PopupNotify.Parent = this; + } + + CString ContactStatusToDBSetting(const char *Prefix, int MoreOpt_PerStatusID = 0) + { + return ::ContactStatusToDBSetting((hContact != INVALID_HANDLE_VALUE) ? Status : NULL, Prefix, MoreOpt_PerStatusID, hContact); + } + + class CIgnore + { + public: + CIgnore& operator = (const int Value) + { + CString Setting(Parent->ContactStatusToDBSetting(DB_IGNOREREQUESTS, IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS)); + HANDLE hContact = (Parent->hContact != INVALID_HANDLE_VALUE) ? Parent->hContact : NULL; + if (Value) + { + DBWriteContactSettingByte(hContact, MOD_NAME, Setting, 1); + } else + { + DBDeleteContactSetting(hContact, MOD_NAME, Setting); + } + return *this; + } + operator int() {return DBGetContactSettingByte((Parent->hContact != INVALID_HANDLE_VALUE) ? Parent->hContact : NULL, MOD_NAME, Parent->ContactStatusToDBSetting(DB_IGNOREREQUESTS, IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS), 0);} + friend class CContactSettings; + private: + CContactSettings *Parent; + } Ignore; + + class CAutoreply + { + public: + CAutoreply& operator = (const int Value) + { + CString Setting(Parent->ContactStatusToDBSetting(DB_ENABLEREPLY, IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS)); + HANDLE hContact = (Parent->hContact != INVALID_HANDLE_VALUE) ? Parent->hContact : NULL; + if (DBGetContactSettingByte(hContact, MOD_NAME, Setting, VAL_USEDEFAULT) == Value) + { + return *this; // prevent deadlocks when calling UpdateSOEButtons + } + if (Value != VAL_USEDEFAULT) + { + DBWriteContactSettingByte(hContact, MOD_NAME, Setting, Value != 0); + } else + { + DBDeleteContactSetting(hContact, MOD_NAME, Setting); + } + /*if (Parent->hContact != INVALID_HANDLE_VALUE) + { + UpdateSOEButtons(Parent->hContact); + }*/ + return *this; + } + operator int() {return DBGetContactSettingByte((Parent->hContact != INVALID_HANDLE_VALUE) ? Parent->hContact : NULL, MOD_NAME, Parent->ContactStatusToDBSetting(DB_ENABLEREPLY, IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS), Parent->hContact ? VAL_USEDEFAULT : AUTOREPLY_DEF_REPLY);} + int IncludingParents(const char *szProtoOverride = NULL) // takes into account protocol and global data also, if per-contact setting is not defined + { + _ASSERT((Parent->hContact && Parent->hContact != INVALID_HANDLE_VALUE) || szProtoOverride); // we need either correct protocol or a correct hContact to determine its protocol + int Value = *this; + if (Value == VAL_USEDEFAULT) + { + const char *szProto = (Parent->hContact && Parent->hContact != INVALID_HANDLE_VALUE) ? (const char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)Parent->hContact, 0) : szProtoOverride; + return CProtoSettings(szProto).Autoreply.IncludingParents(); + } + return Value; + } + int GetNextToggleValue() + { + switch ((int)*this) + { + case VAL_USEDEFAULT: return 0; break; + case 0: return 1; break; + default: return Parent->hContact ? VAL_USEDEFAULT : AUTOREPLY_DEF_REPLY; break; + } + } + int Toggle() {return *this = GetNextToggleValue();} + friend class CContactSettings; + private: + CContactSettings *Parent; + } Autoreply; + +/* class CPopupNotify + { + public: + CPopupNotify& operator = (const int Value) + { + //CString Setting(Parent->ContactStatusToDBSetting(DB_POPUPNOTIFY, 0)); //IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS + HANDLE hContact = (Parent->hContact != INVALID_HANDLE_VALUE) ? Parent->hContact : NULL; + if (DBGetContactSettingByte(hContact, MOD_NAME, Setting, VAL_USEDEFAULT) == Value) + { + return *this; // prevent deadlocks when calling UpdateSOEButtons + } + if (Value != VAL_USEDEFAULT) + { + DBWriteContactSettingByte(hContact, MOD_NAME, Setting, Value != 0); + } else + { + DBDeleteContactSetting(hContact, MOD_NAME, Setting); + } + if (!Parent->hContact) + { + //UpdateSOEButtons(); + } + return *this; + } + operator int() {return DBGetContactSettingByte((Parent->hContact != INVALID_HANDLE_VALUE) ? Parent->hContact : NULL, MOD_NAME, Parent->ContactStatusToDBSetting(DB_POPUPNOTIFY, 0), Parent->hContact ? VAL_USEDEFAULT : POPUP_DEF_USEPOPUPS);} //IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS + int IncludingParents() // takes into account protocol and global data also, if per-contact setting is not defined + { + int Value = *this; + if (Value == VAL_USEDEFAULT) + { // PopupNotify setting is not per-status + return CContactSettings(ID_STATUS_ONLINE).PopupNotify; + } + return Value; + } + friend class CContactSettings; + private: + CContactSettings *Parent; + } PopupNotify; +*/ + class CStatus + { + public: + CStatus(int iStatus = 0, HANDLE hContact = NULL): Status(iStatus), hContact(hContact) {} + CStatus& operator = (int Status) {this->Status = Status; return *this;} + operator int() + { + if (!Status) + { + _ASSERT(hContact != INVALID_HANDLE_VALUE); + char *szProto = hContact ? (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0) : NULL; + Status = (szProto || !hContact) ? g_ProtoStates[szProto].Status : ID_STATUS_AWAY; + } + return Status; + } + friend class CPopupNotify; + friend class CAutoreply; + private: + int Status; + HANDLE hContact; + } Status; + + void SetMsgFormat(int Flags, TCString Message); + TCString GetMsgFormat(int Flags, int *pOrder = NULL, char *szProtoOverride = NULL); + +//NightFox: fix? +//private: +public: + HANDLE hContact; +}; diff --git a/plugins/!Deprecated/NewAwaySysMod/ReadAwayMsg.cpp b/plugins/!Deprecated/NewAwaySysMod/ReadAwayMsg.cpp new file mode 100644 index 0000000000..6d197b7614 --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/ReadAwayMsg.cpp @@ -0,0 +1,161 @@ +/* + New Away System - plugin for Miranda IM + Copyright (C) 2005-2007 Chervov Dmitry + Copyright (C) 2004-2005 Iksaif Entertainment + Copyright (C) 2002-2003 Goblineye Entertainment + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "Common.h" + +#define RAMDLGSIZESETTING "ReadAwayMsgDlg" + +HANDLE g_hReadWndList = NULL; + + +static int ReadAwayMsgDlgResize(HWND hwndDlg, LPARAM lParam, UTILRESIZECONTROL *urc) +{ + switch (urc->wId) + { + case IDC_READAWAYMSG_MSG: + { + return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; + } + case IDC_READAWAYMSG_RETRIEVE: + { + return RD_ANCHORX_CENTRE | RD_ANCHORY_CENTRE; + } + case IDOK: + { + return RD_ANCHORX_CENTRE | RD_ANCHORY_BOTTOM; + } + } + return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; +} + + +static INT_PTR CALLBACK ReadAwayMsgDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + HICON hTitleIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hTitleIcon); + SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hTitleIcon); + Utils_RestoreWindowPosition(hwndDlg, NULL, MOD_NAME, RAMDLGSIZESETTING); + READAWAYMSGDATA *awayData = new READAWAYMSGDATA; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)awayData); + awayData->hContact = (HANDLE)lParam; + awayData->hAwayMsgEvent = HookEventMessage(ME_PROTO_ACK, hwndDlg, UM_RAM_AWAYMSGACK); + awayData->hSeq = (HANDLE)CallContactService(awayData->hContact, PSS_GETAWAYMSG, 0, 0); + WindowList_Add(g_hReadWndList, hwndDlg, awayData->hContact); + + TCHAR str[256], format[128]; + TCHAR *status, *contactName; + contactName = (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)awayData->hContact, GCDNF_TCHAR); + char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)awayData->hContact, 0); + status = (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, DBGetContactSettingWord(awayData->hContact, szProto, "Status", ID_STATUS_OFFLINE), GSMDF_TCHAR); + GetWindowText(hwndDlg, format, lengthof(format)); + _sntprintf(str, lengthof(str), format, status, contactName); + SetWindowText(hwndDlg, str); + GetDlgItemText(hwndDlg, IDC_READAWAYMSG_RETRIEVE, format, sizeof(format)); + _sntprintf(str, lengthof(str), format, status); + SetDlgItemText(hwndDlg, IDC_READAWAYMSG_RETRIEVE, str); + return true; + } break; + case UM_RAM_AWAYMSGACK: // got away msg + { + ACKDATA *ack = (ACKDATA*)lParam; + READAWAYMSGDATA *awayData = (READAWAYMSGDATA*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + // make sure everything is ok, and this is our ack + if (ack->hContact != awayData->hContact || ack->type != ACKTYPE_AWAYMSG || ack->hProcess != awayData->hSeq || ack->result != ACKRESULT_SUCCESS) + { + break; + } + // done with the event + if (awayData->hAwayMsgEvent) + { + UnhookEvent(awayData->hAwayMsgEvent); + awayData->hAwayMsgEvent = NULL; + } + SetDlgItemText(hwndDlg, IDC_READAWAYMSG_MSG, (const TCHAR*)ack->lParam); + ShowWindow(GetDlgItem(hwndDlg, IDC_READAWAYMSG_RETRIEVE), SW_HIDE); + ShowWindow(GetDlgItem(hwndDlg, IDC_READAWAYMSG_MSG), SW_SHOW); + SetDlgItemText(hwndDlg, IDOK, TranslateT("&Close")); + DBWriteContactSettingString(awayData->hContact, "CList", "StatusMsg", (const char*)ack->lParam); + } break; + case WM_COMMAND: + { + switch (HIWORD(wParam)) + { + case BN_CLICKED: + { + switch(LOWORD(wParam)) + { + case IDCANCEL: + case IDOK: + { + DestroyWindow(hwndDlg); + } break; + } + } break; + } + } break; + case WM_SIZE: + { + UTILRESIZEDIALOG urd = {0}; + urd.cbSize = sizeof(urd); + urd.hInstance = g_hInstance; + urd.hwndDlg = hwndDlg; + urd.lpTemplate = MAKEINTRESOURCEA(IDD_READAWAYMSG); + urd.pfnResizer = ReadAwayMsgDlgResize; + CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); + break; + } + case WM_CLOSE: + { + DestroyWindow(hwndDlg); + } break; + case WM_DESTROY: + { + READAWAYMSGDATA *awayData = (READAWAYMSGDATA*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + if (awayData->hAwayMsgEvent) + { + UnhookEvent(awayData->hAwayMsgEvent); + awayData->hAwayMsgEvent = NULL; + } + delete awayData; + Utils_SaveWindowPosition(hwndDlg, NULL, MOD_NAME, RAMDLGSIZESETTING); + WindowList_Remove(g_hReadWndList, hwndDlg); + } break; + } + return false; +} + + +INT_PTR GetContactStatMsg(WPARAM wParam, LPARAM lParam) +{ + if (HWND hWnd = WindowList_Find(g_hReadWndList, (HANDLE)wParam)) // already have it + { + SetForegroundWindow(hWnd); + } else + { + CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_READAWAYMSG), NULL, ReadAwayMsgDlgProc, wParam); + } + return 0; +} diff --git a/plugins/!Deprecated/NewAwaySysMod/Services.cpp b/plugins/!Deprecated/NewAwaySysMod/Services.cpp new file mode 100644 index 0000000000..c8108eb1a9 --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/Services.cpp @@ -0,0 +1,231 @@ +/* + New Away System - plugin for Miranda IM + Copyright (c) 2005-2007 Chervov Dmitry + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "Common.h" +#include "Properties.h" +#include "m_NewAwaySys.h" + + +typedef struct { + int cbSize; + char *szProto; + union + { + char *szMsg; + WCHAR *wszMsg; + TCHAR *tszMsg; + }; + WORD status; +} NAS_PROTOINFOv1; + + +__inline void PSSetStatus(char *szProto, WORD Status, int bNoClistSetStatusMode = false) // just a helper function that sets the status and handles szProto==NULL correctly +{ + g_ProtoStates[szProto].Status = Status; + if (szProto) + { + CallProtoService(szProto, PS_SETSTATUS, Status, 0); + } else if (!bNoClistSetStatusMode) // global status + { +/* int ProtoCount; + PROTOCOLDESCRIPTOR **proto; + CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&ProtoCount, (LPARAM)&proto); + int i; + for (i = 0; i < ProtoCount; i++) + { + if (proto[i]->type == PROTOTYPE_PROTOCOL) + { + CallProtoService(proto[i]->szName, PS_SETSTATUS, Status, 0); + } + }*/ + g_fNoProcessing = true; + CallService(MS_CLIST_SETSTATUSMODE, Status, 0); + _ASSERT(!g_fNoProcessing && g_ProtoStates[(char*)NULL].Status == Status); + g_fNoProcessing = false; + } +} + + +INT_PTR GetStatusMsg(WPARAM wParam, LPARAM lParam) // called by GamerStatus and built-in miranda autoaway module +// wParam = (int)status, lParam = 0 +// MS_AWAYMSG_GETSTATUSMSG "SRAway/GetStatusMessage" +{ + LogMessage("MS_AWAYMSG_GETSTATUSMSG called. status=%d", wParam); + CString Msg(TCHAR2ANSI(GetDynamicStatMsg(INVALID_HANDLE_VALUE, NULL, 0, wParam))); + char *szMsg; + if (Msg == NULL) + { // it's ok to return NULL, so we'll do it + szMsg = NULL; + } else + { + szMsg = (char*)mir_alloc(Msg.GetLen() + 1); + lstrcpyA(szMsg, Msg); + } + LogMessage("returned szMsg:\n%s", szMsg ? szMsg : "NULL"); + return (int)szMsg; +} + + +INT_PTR SetStatusMode(WPARAM wParam, LPARAM lParam) // called by GamerStatus and StatCtrl +{ +// wParam = int iMode +// lParam = char* szMsg, may be null - then we need to use the default message +/* if (CallService(MS_CLIST_GETSTATUSMODE, 0, 0) != wParam) // not same status + {*/ // try this way; global status may be not the same as current status of some separate protocol + LogMessage("MS_AWAYSYS_SETSTATUSMODE called. status=%d, szMsg:\n%s", wParam, lParam ? (char*)lParam : "NULL"); + g_fNoProcessing = true; + CallService(MS_CLIST_SETSTATUSMODE, wParam, 0); +// } + _ASSERT(!g_fNoProcessing && g_ProtoStates[(char*)NULL].Status == wParam); + g_fNoProcessing = false; + CProtoSettings(NULL, wParam).SetMsgFormat(SMF_TEMPORARY, lParam ? ANSI2TCHAR((char*)lParam) : CProtoSettings(NULL, wParam).GetMsgFormat(GMF_LASTORDEFAULT)); + ChangeProtoMessages(NULL, wParam, TCString()); + return 0; +} + + +int GetState(WPARAM wParam, LPARAM lParam, int Widechar) +// wParam = (WPARAM)(NAS_PROTOINFO*)pi - pointer to an array of NAS_PROTOINFO items to be filled. +// lParam = (LPARAM)(int)protoCount - number of items in pi. +// returns 0 on success +{ + NAS_PROTOINFO *pi = (NAS_PROTOINFO*)wParam; + LogMessage("MS_NAS_GETSTATE called with %d items and Widechar=%d:", lParam, Widechar); + for (int i = 0; i < lParam; i++) + { + if (pi->cbSize < sizeof(NAS_PROTOINFO) && pi->cbSize != sizeof(NAS_PROTOINFOv1)) + return 1; + + int Flags = (pi->cbSize > sizeof(NAS_PROTOINFOv1)) ? pi->Flags : 0; + LogMessage("%d (received): cbSize=%d, status=%d, szProto=%s, Flags=0x%x", i + 1, pi->cbSize, pi->status, pi->szProto ? pi->szProto : "NULL", Flags); + if ((pi->status >= ID_STATUS_ONLINE && pi->status <= ID_STATUS_OUTTOLUNCH) || !pi->status) + { + TCString Msg(pi->status ? CProtoSettings(pi->szProto, pi->status).GetMsgFormat(GMF_LASTORDEFAULT) : CProtoSettings(pi->szProto).GetMsgFormat(((Flags & PIF_NOTTEMPORARY) ? 0 : GMF_TEMPORARY) | GMF_PERSONAL)); + if (Msg != NULL) + { + pi->szMsg = (char*)mir_alloc(Msg.GetLen() + 1); + _ASSERT(pi->szMsg); + if (Widechar) + lstrcpyW(pi->wszMsg, TCHAR2WCHAR(Msg)); + else + lstrcpyA(pi->szMsg, TCHAR2ANSI(Msg)); + } + else pi->szMsg = NULL; + + if (!pi->status) + pi->status = g_ProtoStates[pi->szProto].Status; + } + else pi->szMsg = NULL; + + LogMessage("%d (returned): status=%d, Flags=0x%x, szMsg:\n%s", i + 1, pi->status, (pi->cbSize > sizeof(NAS_PROTOINFOv1)) ? pi->Flags : 0, pi->szMsg ? (Widechar ? WCHAR2ANSI(pi->wszMsg) : pi->szMsg) : "NULL"); + *(char**)&pi += pi->cbSize; + } + return 0; +} + + +INT_PTR GetStateA(WPARAM wParam, LPARAM lParam) +{ + return GetState(wParam, lParam, false); +} + + +INT_PTR GetStateW(WPARAM wParam, LPARAM lParam) +{ + return GetState(wParam, lParam, true); +} + + +int SetState(WPARAM wParam, LPARAM lParam, int Widechar) +// wParam = (WPARAM)(NAS_PROTOINFO*)pi - pointer to an array of NAS_PROTOINFO items. +// lParam = (LPARAM)(int)protoCount - number of items in pi. +// returns 0 on success +{ + NAS_PROTOINFO *pi = (NAS_PROTOINFO*)wParam; + LogMessage("MS_NAS_SETSTATE called with %d items and Widechar=%d:", lParam, Widechar); + for (int i = 0; i < lParam; i++) + { + _ASSERT(pi->szMsg != (char*)(-1)); + if (pi->cbSize < sizeof(NAS_PROTOINFO) && pi->cbSize != sizeof(NAS_PROTOINFOv1)) + return 1; + + int Flags = (pi->cbSize > sizeof(NAS_PROTOINFOv1)) ? pi->Flags : 0; + LogMessage("%d: cbSize=%d, status=%d, szProto=%s, Flags=0x%x, szMsg:\n%s", i + 1, pi->cbSize, pi->status, pi->szProto ? pi->szProto : "NULL", Flags, pi->szMsg ? (Widechar ? WCHAR2ANSI(pi->wszMsg) : pi->szMsg) : "NULL"); + if (pi->status) + PSSetStatus(pi->szProto, pi->status, Flags & PIF_NO_CLIST_SETSTATUSMODE); + else + pi->status = g_ProtoStates[pi->szProto].Status; + + CProtoSettings(pi->szProto).SetMsgFormat((Flags & PIF_NOTTEMPORARY) ? SMF_PERSONAL : SMF_TEMPORARY, Widechar ? WCHAR2TCHAR(pi->wszMsg) : ANSI2TCHAR(pi->szMsg)); + if (pi->szMsg || !(Flags & PIF_NO_CLIST_SETSTATUSMODE)) + ChangeProtoMessages(pi->szProto, pi->status, TCString()); + + mir_free(pi->szMsg); + pi->szMsg = (char*)(-1); + *(char**)&pi += pi->cbSize; + } + return 0; +} + + +INT_PTR SetStateA(WPARAM wParam, LPARAM lParam) +{ + return SetState(wParam, lParam, false); +} + + +INT_PTR SetStateW(WPARAM wParam, LPARAM lParam) +{ + return SetState(wParam, lParam, true); +} + + +INT_PTR InvokeStatusWindow(WPARAM wParam, LPARAM lParam) +// wParam = (WPARAM)(NAS_ISWINFO*)iswi - pointer to a NAS_ISWINFO structure. +// lParam = 0 +// returns HWND of the window on success, or NULL on failure. +{ + NAS_ISWINFO *iswi = (NAS_ISWINFO*)wParam; + if (iswi->cbSize != sizeof(NAS_ISWINFOv1) && iswi->cbSize < sizeof(NAS_ISWINFO)) + { + return NULL; + } + LogMessage("MS_NAS_INVOKESTATUSWINDOW called. cbSize=%d, status=%d, szProto=%s, hContact=0x%08x, Flags=0x%x, szMsg:\n%s", iswi->cbSize, iswi->status, iswi->szProto ? iswi->szProto : "NULL", iswi->hContact, (iswi->cbSize < sizeof(NAS_ISWINFO)) ? 0 : iswi->Flags, iswi->szMsg ? ((iswi->Flags & ISWF_UNICODE) ? WCHAR2ANSI(iswi->wszMsg) : iswi->szMsg) : "NULL"); + if (iswi->status) + { + PSSetStatus(iswi->szProto, iswi->status); + } + if (g_SetAwayMsgPage.GetWnd()) // already setting something + { + SetForegroundWindow(g_SetAwayMsgPage.GetWnd()); + return (int)g_SetAwayMsgPage.GetWnd(); + } + SetAwayMsgData *dat = new SetAwayMsgData; + ZeroMemory(dat, sizeof(SetAwayMsgData)); + dat->hInitContact = iswi->hContact; + dat->szProtocol = iswi->szProto; + dat->Message = (iswi->Flags & ISWF_UNICODE) ? WCHAR2TCHAR(iswi->wszMsg) : ANSI2TCHAR(iswi->szMsg); + dat->IsModeless = true; + if (iswi->cbSize > sizeof(NAS_ISWINFOv1)) + { + dat->ISW_Flags = iswi->Flags; + } + return (int)CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_SETAWAYMSG), NULL, SetAwayMsgDlgProc, (LPARAM)dat); +} diff --git a/plugins/!Deprecated/NewAwaySysMod/Services.h b/plugins/!Deprecated/NewAwaySysMod/Services.h new file mode 100644 index 0000000000..903bbd3784 --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/Services.h @@ -0,0 +1,27 @@ +/* + New Away System - plugin for Miranda IM + Copyright (c) 2005-2007 Chervov Dmitry + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +INT_PTR GetStatusMsg(WPARAM wParam, LPARAM lParam); +INT_PTR SetStatusMode(WPARAM wParam, LPARAM lParam); +// int IgnoreNextStatusChange(WPARAM wParam, LPARAM lParam); +INT_PTR GetStateA(WPARAM wParam, LPARAM lParam); +INT_PTR SetStateA(WPARAM wParam, LPARAM lParam); +INT_PTR GetStateW(WPARAM wParam, LPARAM lParam); +INT_PTR SetStateW(WPARAM wParam, LPARAM lParam); +INT_PTR InvokeStatusWindow(WPARAM wParam, LPARAM lParam); diff --git a/plugins/!Deprecated/NewAwaySysMod/SetAwayMsg.cpp b/plugins/!Deprecated/NewAwaySysMod/SetAwayMsg.cpp new file mode 100644 index 0000000000..46748b991b --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/SetAwayMsg.cpp @@ -0,0 +1,1706 @@ +/* + New Away System plugin for Miranda IM + Copyright (c) 2005-2007 Chervov Dmitry + Copyright (c) 2004-2005 Iksaif Entertainment + Copyright (c) 2002-2003 Goblineye Entertainment + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "Common.h" +#include "m_button.h" +#include "m_icolib.h" +#include "ContactList.h" +#include "MsgTree.h" +#include "Properties.h" +#include "m_NewAwaySys.h" + +#define EXTRAIMGLIST_DOT 0 +#define EXTRAIMGLIST_IGNORE 1 +#define EXTRAIMGLIST_MSG 2 +#define EXTRAIMGLIST_AUTOREPLY_ON 3 +#define EXTRAIMGLIST_AUTOREPLY_OFF 4 + +#define EXTRACOLUMN_IGNORE 0 +#define EXTRACOLUMN_REPLY 1 + +#define MINSPLITTERPOS 176 +#define MINYDLGSIZE 100 + +#define SAM_TIMER_ID 1 + +#define UM_SAM_INITCLIST (WM_USER + 100) + +#define CLSEL_DAT_CONTACT ((PTREEITEMARRAY)(-1)) // these constants are used to specify selection when the contact list is not loaded +#define CLSEL_DAT_NOTHING ((PTREEITEMARRAY)(-2)) + +static WNDPROC g_OrigEditMsgProc; +static WNDPROC g_OrigSplitterProc; +static WNDPROC g_OrigCListProc; +static int g_VariablesButtonDX; +static int g_MsgSplitterX, g_ContactSplitterX; +static int MinMsgSplitterX, MinContactSplitterX; +static int MinMsgEditSize; // used to calculate minimal X size of the dialog + + + +static LRESULT CALLBACK MsgEditSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + switch (Msg) + { + case WM_CHAR: + { + if (GetKeyState(VK_CONTROL) & 0x8000) + { + if (wParam == '\n') + { // ctrl-enter + PostMessage(GetParent(hWnd), WM_COMMAND, IDC_OK, 0); + return 0; + } + if (wParam == 1) + { // ctrl-a + SendMessage(hWnd, EM_SETSEL, 0, -1); + return 0; + } + if (wParam == 23) + { // ctrl-w + SendMessage(GetParent(hWnd), WM_CLOSE, 0, 0); + return 0; + } + if (wParam == 127) + { // ctrl-backspace + DWORD start, end; + SendMessage(hWnd, EM_GETSEL, (WPARAM)&end, NULL); + SendMessage(hWnd, WM_KEYDOWN, VK_LEFT, 0); + SendMessage(hWnd, EM_GETSEL, (WPARAM)&start, NULL); + int nLen = GetWindowTextLength(hWnd); + TCHAR *text = (TCHAR*)malloc((nLen + 1) * sizeof(TCHAR)); + GetWindowText(hWnd, text, nLen + 1); + MoveMemory(text + start, text + end, sizeof(TCHAR) * (_tcslen(text) + 1 - end)); + SetWindowText(hWnd, text); + free(text); + SendMessage(hWnd, EM_SETSEL, start, start); + SendMessage(GetParent(hWnd), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hWnd), EN_CHANGE), (LPARAM)hWnd); + return 0; + } + } + } break; + case WM_KEYDOWN: + { + SendMessage(GetParent(hWnd), UM_SAM_KILLTIMER, 0, 0); + } break; + } + return CallWindowProc(g_OrigEditMsgProc, hWnd, Msg, wParam, lParam); +} + +// used splitter code from TabSRMM as a base +static LRESULT CALLBACK SplitterSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + switch (Msg) + { + case WM_NCHITTEST: + { + return HTCLIENT; + } + case WM_SETCURSOR: + { + SetCursor(LoadCursor(NULL, IDC_SIZEWE)); + return true; + } + case WM_LBUTTONDOWN: + { + SetCapture(hWnd); + return false; + } + case WM_MOUSEMOVE: + { + if (GetCapture() == hWnd) + { + RECT rc; + GetClientRect(hWnd, &rc); + SendMessage(GetParent(hWnd), UM_SAM_SPLITTERMOVED, (short)LOWORD(GetMessagePos()) + rc.right / 2, (LPARAM)GetDlgCtrlID(hWnd)); + } + return 0; + } + case WM_LBUTTONUP: + { + ReleaseCapture(); + return false; + } + } + return CallWindowProc(g_OrigSplitterProc, hWnd, Msg, wParam, lParam); +} + +static LRESULT CALLBACK CListSubclassProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + CCList *dat = CWndUserData(GetParent(hWnd)).GetCList(); + switch (Msg) + { + case WM_MOUSEMOVE: + { + DWORD hitFlags; + POINT pt = {(short)LOWORD(lParam), (short)HIWORD(lParam)}; + if (dat->HitTest(&pt, &hitFlags) && hitFlags & MCLCHT_ONITEMEXTRA) + { + lParam = 0; // reset mouse coordinates, so TreeView's wndproc will not draw any item in a hovered state + } + } break; + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + { + DWORD hitFlags; + POINT pt = {(short)LOWORD(lParam), (short)HIWORD(lParam)}; + if (dat->HitTest(&pt, &hitFlags) && hitFlags & MCLCHT_ONITEMEXTRA) + { + SetFocus(hWnd); + NMHDR nmhdr; + nmhdr.code = NM_CLICK; + nmhdr.hwndFrom = hWnd; + nmhdr.idFrom = GetDlgCtrlID(hWnd); + SendMessage(GetParent(hWnd), WM_NOTIFY, 0, (LPARAM)&nmhdr); + return DefWindowProc(hWnd, Msg, wParam, lParam); + } + } break; + } + return CallWindowProc(g_OrigCListProc, hWnd, Msg, wParam, lParam); +} + + +static int SetAwayMsgDlgResize(HWND hwndDlg, LPARAM lParam, UTILRESIZECONTROL *urc) +{ + COptPage *SetAwayMsgPage = (COptPage*)lParam; + int bShowMsgTree = SetAwayMsgPage->GetValue(IDS_SAWAYMSG_SHOWMSGTREE); + int bShowContactTree = SetAwayMsgPage->GetValue(IDS_SAWAYMSG_SHOWCONTACTTREE); + switch (urc->wId) + { + case IDC_SAWAYMSG_MSGDATA: + { + urc->rcItem.right = urc->dlgOriginalSize.cx - 2; + if (bShowContactTree) + { + urc->rcItem.right -= g_ContactSplitterX; + } + urc->rcItem.left = (bShowMsgTree) ? (g_MsgSplitterX + 2) : 2; + return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; + } + case IDC_SAWAYMSG_TREE: + { + urc->rcItem.right = g_MsgSplitterX - 2; + return RD_ANCHORX_LEFT | RD_ANCHORY_HEIGHT; + } + case IDC_SAWAYMSG_CONTACTSTREE: + { + urc->rcItem.left = urc->dlgOriginalSize.cx - g_ContactSplitterX + 2; + return RD_ANCHORX_RIGHT | RD_ANCHORY_HEIGHT; + } + case IDC_OK: + { + int X = bShowMsgTree ? min(max(g_MsgSplitterX, MinMsgSplitterX), urc->dlgNewSize.cx - ((bShowContactTree ? MinContactSplitterX : 0) + MinMsgEditSize)) : 0; + OffsetRect(&urc->rcItem, X + 2 - urc->rcItem.left, 0); + return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM; + } + case IDC_SAWAYMSG_EDITMSGS: + case IDC_SAWAYMSG_SAVEMSG: + case IDC_SAWAYMSG_SAVEASNEW: + case IDC_SAWAYMSG_NEWCATEGORY: + case IDC_SAWAYMSG_DELETE: + { + return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM; + } + case IDC_SAWAYMSG_VARS: + case IDC_SAWAYMSG_OPTIONS: + { + int X = bShowContactTree ? max(min(g_ContactSplitterX, urc->dlgNewSize.cx - (bShowMsgTree ? max(g_MsgSplitterX, MinMsgSplitterX) : 0) - MinMsgEditSize), MinContactSplitterX) : 0; + OffsetRect(&urc->rcItem, urc->dlgOriginalSize.cx - X - 2 - urc->rcItem.right - ((urc->wId == IDC_SAWAYMSG_VARS) ? g_VariablesButtonDX : 0), 0); + return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM; + } + case IDC_SAWAYMSG_STATIC_IGNOREICON: + case IDC_SAWAYMSG_STATIC_REPLYICON: + { + urc->rcItem.left = urc->rcItem.right - 16; + urc->rcItem.top = urc->rcItem.bottom - 16; + } // go through + case IDC_SAWAYMSG_IGNOREREQ: + case IDC_SAWAYMSG_SENDMSG: + { + return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM; + } + case IDC_SAWAYMSG_MSGSPLITTER: + { + OffsetRect(&urc->rcItem, g_MsgSplitterX - (urc->rcItem.left + ++urc->rcItem.right) / 2, 0); + return RD_ANCHORX_LEFT | RD_ANCHORY_HEIGHT; + } + case IDC_SAWAYMSG_CONTACTSPLITTER: + { + OffsetRect(&urc->rcItem, urc->dlgOriginalSize.cx - g_ContactSplitterX - (urc->rcItem.left + urc->rcItem.right) / 2, 0); + return RD_ANCHORX_RIGHT | RD_ANCHORY_HEIGHT; + } + } + + + return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM; +} + + +__inline int DBValueToReplyIcon(int Value) +{ + switch (Value) + { + case VAL_USEDEFAULT: return EXTRAIMGLIST_DOT; + case 0: return EXTRAIMGLIST_AUTOREPLY_OFF; + default: return EXTRAIMGLIST_AUTOREPLY_ON; + } +} + + +int GetRealReplyIcon(CCList *CList, HTREEITEM hItem) +{ + _ASSERT(CList); + HANDLE hContact = CList->GethContact(hItem); + int ItemType = CList->GetItemType(hItem); + char *szProto = (char*)CList->GetItemParam(hItem); + return (ItemType == MCLCIT_GROUP) ? CList->GetItemParam(hItem) : DBValueToReplyIcon((ItemType == MCLCIT_CONTACT) ? (int)CContactSettings(0, hContact).Autoreply : CProtoSettings(szProto).Autoreply); +} + + +void SetExtraIcon(CCList *CList, int nColumn, HTREEITEM hItem, int nIcon) +{ + _ASSERT(CList); + int ItemType = CList->GetItemType(hItem); + HANDLE hContact = CList->GethContact(hItem); + if (ItemType == MCLCIT_CONTACT) + { + if (nIcon == -1) // means we need to retrieve it from the db by ourselves + { + if (nColumn == EXTRACOLUMN_IGNORE) + { + nIcon = CContactSettings(0, hContact).Ignore ? EXTRAIMGLIST_IGNORE : EXTRAIMGLIST_DOT; + } else + { + _ASSERT(nColumn == EXTRACOLUMN_REPLY); + nIcon = DBValueToReplyIcon(CContactSettings(0, hContact).Autoreply); + } + } else // save it back to the db + { + if (nColumn == EXTRACOLUMN_IGNORE) + { + CContactSettings(0, hContact).Ignore = nIcon == EXTRAIMGLIST_IGNORE; + } else + { + _ASSERT(nColumn == EXTRACOLUMN_REPLY); + CContactSettings(0, hContact).Autoreply = (nIcon == EXTRAIMGLIST_DOT) ? VAL_USEDEFAULT : (nIcon == EXTRAIMGLIST_AUTOREPLY_ON); + } + } + if (nColumn == EXTRACOLUMN_IGNORE && nIcon != EXTRAIMGLIST_IGNORE) + { + nIcon = (CContactSettings(0, hContact).GetMsgFormat(GMF_PERSONAL) == NULL) ? EXTRAIMGLIST_DOT : EXTRAIMGLIST_MSG; + } + } else if (ItemType == MCLCIT_INFO) + { + char *szProto = (char*)CList->GetItemParam(hItem); + if (nColumn == EXTRACOLUMN_REPLY) + { + if (nIcon == -1) + { + nIcon = DBValueToReplyIcon(CProtoSettings(szProto).Autoreply); + } else + { + CProtoSettings(szProto).Autoreply = (nIcon == EXTRAIMGLIST_DOT) ? VAL_USEDEFAULT : (nIcon == EXTRAIMGLIST_AUTOREPLY_ON); + } + if (!szProto && nIcon == EXTRAIMGLIST_DOT) + { + nIcon = EXTRAIMGLIST_AUTOREPLY_OFF; + } + } else + { + nIcon = (CProtoSettings(szProto).GetMsgFormat(GMF_TEMPORARY | GMF_PERSONAL) == NULL) ? EXTRAIMGLIST_DOT : EXTRAIMGLIST_MSG; + } + } + int Ignore = (nColumn == EXTRACOLUMN_IGNORE) ? (nIcon == EXTRAIMGLIST_IGNORE) : ((ItemType == MCLCIT_CONTACT) ? CContactSettings(0, hContact).Ignore : ((ItemType == MCLCIT_GROUP) ? CList->GetExtraImage(hItem, EXTRACOLUMN_IGNORE) : false)); + if (Ignore) + { + if (nColumn == EXTRACOLUMN_IGNORE) + { + CList->SetExtraImage(hItem, EXTRACOLUMN_REPLY, CLC_EXTRAICON_EMPTY); + } else + { + nIcon = CLC_EXTRAICON_EMPTY; + } + } else + { + int nReplyIcon; + if (ItemType == MCLCIT_CONTACT) + { + nReplyIcon = DBValueToReplyIcon(CContactSettings(0, hContact).Autoreply); + } else if (ItemType == MCLCIT_GROUP) + { + nReplyIcon = GetRealReplyIcon(CList, hItem); + } else + { + _ASSERT(ItemType == MCLCIT_INFO); + char *szProto = (char*)CList->GetItemParam(hItem); + nReplyIcon = DBValueToReplyIcon(CProtoSettings(szProto).Autoreply); + } + if (nColumn == EXTRACOLUMN_IGNORE) + { + CList->SetExtraImage(hItem, EXTRACOLUMN_REPLY, nReplyIcon); + } else if (nIcon == CLC_EXTRAICON_EMPTY) + { + nIcon = nReplyIcon; + } + } + CList->SetExtraImage(hItem, nColumn, nIcon); +} + + +void SetCListGroupIcons(SetAwayMsgData *dat, CCList *CList) +{ + _ASSERT(CList); + HTREEITEM hItem = CList->GetNextItem(MCLGN_LAST, NULL); // start from last item, so every item is processed before its parents + if (!hItem) + { + return; + } + if (CList->GetItemType(hItem) != MCLCIT_GROUP) + { + hItem = CList->GetNextItem(MCLGN_PREV | MCLGN_GROUP | MCLGN_MULTILEVEL, hItem); + if (!hItem) + { + return; + } + } + do + { + HTREEITEM hCurItem = CList->GetNextItem(MCLGN_CHILD, hItem); + if (hCurItem) + { + int IgnoreIcon = CList->GetExtraImage(hCurItem, EXTRACOLUMN_IGNORE); + int AutoreplyIcon = GetRealReplyIcon(CList, hCurItem); + if (IgnoreIcon == EXTRAIMGLIST_MSG) + { + IgnoreIcon = EXTRAIMGLIST_DOT; + } + while ((hCurItem = CList->GetNextItem(MCLGN_NEXT | MCLGN_ANY, hCurItem)) && (IgnoreIcon != EXTRAIMGLIST_DOT || AutoreplyIcon != EXTRAIMGLIST_DOT)) + { + if (CList->GetExtraImage(hCurItem, EXTRACOLUMN_IGNORE) != EXTRAIMGLIST_IGNORE) + { + IgnoreIcon = EXTRAIMGLIST_DOT; + } + int CurReplyIcon = GetRealReplyIcon(CList, hCurItem); + if (CurReplyIcon != AutoreplyIcon) + { + AutoreplyIcon = EXTRAIMGLIST_DOT; + } + } + CList->SetItemParam(hItem, AutoreplyIcon); // store Reply icon in item's Param, so that we can always get real reply icon for groups later, even if CLC_EXTRAICON_EMPTY is set instead of it + SetExtraIcon(CList, EXTRACOLUMN_IGNORE, hItem, IgnoreIcon); + SetExtraIcon(CList, EXTRACOLUMN_REPLY, hItem, AutoreplyIcon); + } + } while (hItem = CList->GetNextItem(MCLGN_PREV | MCLGN_GROUP | MCLGN_MULTILEVEL, hItem)); +} + + +int GetSelContactsNum(CCList *CList, PTREEITEMARRAY Selection = NULL, bool *bOnlyInfo = NULL) // "SelContacts" mean not only contacts, but everything with "personal" status messages and settings - i.e. "All contacts" and protocol items are counted too. +{ + if (!CList) + { + return (Selection == CLSEL_DAT_NOTHING) ? 0 : 1; // Selection == NULL means we need to retrieve current selection by ourselves, and current selection is always CLSEL_DAT_CONTACT in this case + } + if (!Selection) + { + Selection = CList->GetSelection(); + } + int I; + int nContacts = 0; + if (bOnlyInfo) + { + *bOnlyInfo = true; + } + for (I = 0; I < Selection->GetSize(); I++) + { + int ItemType = CList->GetItemType((*Selection)[I]); + if (bOnlyInfo && ItemType != MCLCIT_INFO) + { + *bOnlyInfo = false; + } + nContacts += ItemType == MCLCIT_CONTACT || ItemType == MCLCIT_INFO; + } + return nContacts; +} + + +void ApplySelContactsMessage(SetAwayMsgData* dat, CCList *CList, PTREEITEMARRAY Selection = NULL) +{ + TCString Message; + HWND hwndDlg = g_SetAwayMsgPage.GetWnd(); + GetDlgItemText(hwndDlg, IDC_SAWAYMSG_MSGDATA, Message.GetBuffer(AWAY_MSGDATA_MAX), AWAY_MSGDATA_MAX); + Message.ReleaseBuffer(); + if (!lstrlen(Message)) + { + Message = NULL; // delete personal message if it's empty + } + if (CList) + { + if (!Selection) + { + Selection = CList->GetSelection(); + } + int I; + for (I = 0; I < Selection->GetSize(); I++) + { + HTREEITEM hItem = (*Selection)[I]; + int ItemType = CList->GetItemType(hItem); + if (ItemType == MCLCIT_CONTACT) + { + HANDLE hContact = CList->GethContact(hItem); + CContactSettings(0, hContact).SetMsgFormat(SMF_PERSONAL, Message); + } else if (ItemType == MCLCIT_INFO) + { + char *szProto = (char*)CList->GetItemParam(hItem); + CProtoSettings(szProto).SetMsgFormat(SMF_PERSONAL, (szProto || Message != NULL) ? Message : _T("")); // "szProto || Message != NULL..." means that we'll set an empty message instead of NULL for the global status, if the message is empty (NULL for the global status has a special meaning - SetMsgFormat will set the default message instead of NULL) + } else + { + continue; + } + SetExtraIcon(CList, EXTRACOLUMN_IGNORE, hItem, -1); // refresh contact's personal message icon (MSG or DOT) + } + } else if (Selection != CLSEL_DAT_NOTHING) + { + if (dat->hInitContact) + { + CContactSettings(0, dat->hInitContact).SetMsgFormat(SMF_PERSONAL, Message); + } else + { + CProtoSettings(dat->szProtocol).SetMsgFormat(SMF_PERSONAL, (dat->szProtocol || Message != NULL) ? Message : _T("")); + } + } + SendDlgItemMessage(hwndDlg, IDC_SAWAYMSG_MSGDATA, EM_SETMODIFY, false, 0); + SetDlgItemText(hwndDlg, IDC_OK, TranslateT("OK")); +} + + +void UpdateCheckboxesState(CCList *CList) +{ + _ASSERT(CList); + PTREEITEMARRAY Selection = CList->GetSelection(); + int I; + int ReplyIcon = -1; + int IgnoreIcon = -1; + for (I = 0; I < Selection->GetSize() && (IgnoreIcon != EXTRAIMGLIST_DOT || ReplyIcon != EXTRAIMGLIST_DOT); I++) + { + HTREEITEM hItem = (*Selection)[I]; + int ItemType = CList->GetItemType(hItem); + if (ItemType == MCLCIT_CONTACT || ItemType == MCLCIT_INFO) + { + int CurIgnoreIcon = CList->GetExtraImage(hItem, EXTRACOLUMN_IGNORE); + if (IgnoreIcon == -1) + { + IgnoreIcon = CurIgnoreIcon; + } else if (CurIgnoreIcon != EXTRAIMGLIST_IGNORE) + { + IgnoreIcon = EXTRAIMGLIST_DOT; + } + int CurReplyIcon = CList->GetExtraImage(hItem, EXTRACOLUMN_REPLY); + if (ReplyIcon == -1) + { + ReplyIcon = CurReplyIcon; + } else if (CurReplyIcon != ReplyIcon) + { + ReplyIcon = EXTRAIMGLIST_DOT; + } + } + } + HWND hwndDlg = g_SetAwayMsgPage.GetWnd(); + CheckDlgButton(hwndDlg, IDC_SAWAYMSG_IGNOREREQ, (IgnoreIcon == EXTRAIMGLIST_IGNORE) ? BST_CHECKED : BST_UNCHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_SENDMSG), IgnoreIcon != EXTRAIMGLIST_IGNORE); + CheckDlgButton(hwndDlg, IDC_SAWAYMSG_SENDMSG, (ReplyIcon == EXTRAIMGLIST_AUTOREPLY_ON) ? BST_CHECKED : ((ReplyIcon == EXTRAIMGLIST_AUTOREPLY_OFF) ? BST_UNCHECKED : BST_INDETERMINATE)); +} + +HICON g_LoadIconEx( const char* name, bool big ) +{ + char szSettingName[100]; + mir_snprintf( szSettingName, sizeof( szSettingName ), "%s_%s", "", name ); + return ( HICON )CallService( MS_SKIN2_GETICON, big, (LPARAM)szSettingName ); +} +INT_PTR CALLBACK SetAwayMsgDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + static int SetMsgSplitterX, SetContactSplitterX; + static SetAwayMsgData *dat; + static HWND hWndTooltips; + static int UpdateLock = 0; + static int Countdown; + static CMsgTree *MsgTree = NULL; + static CCList *CList = NULL; + static struct { + int DlgItem, IconIndex; + TCHAR* Text; + } Buttons[] = { + IDC_SAWAYMSG_SAVEMSG, ILI_SAVE, LPGENT("Save, replacing the selected message"), + IDC_SAWAYMSG_SAVEASNEW, ILI_SAVEASNEW, LPGENT("Save as a new message"), + IDC_SAWAYMSG_NEWCATEGORY, ILI_NEWCATEGORY, LPGENT("Create new category"), + IDC_SAWAYMSG_DELETE, ILI_DELETE, LPGENT("Delete"), + IDC_SAWAYMSG_VARS, ILI_NOICON, LPGENT("Open Variables help dialog"), + IDC_SAWAYMSG_OPTIONS, ILI_SETTINGS, LPGENT("Show settings menu") + }; + + + switch (uMsg) + { + case WM_INITDIALOG: + { + dat = (SetAwayMsgData*)lParam; + TranslateDialogDefault(hwndDlg); + g_SetAwayMsgPage.SetWnd(hwndDlg); + g_SetAwayMsgPage.DBToMemToPage(); +/* + HICON hTitleIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); + HICON hTitleIconBig = LoadSkinnedIconBig(SKINICON_OTHER_MIRANDA); + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hTitleIconBig); + SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hTitleIcon); +*/ + HICON hTitleIconBigElse = LoadSkinnedIconBig(SKINICON_OTHER_MIRANDA); + + char *szProto = dat->hInitContact ? (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)dat->hInitContact, 0) : dat->szProtocol; + int Status = 0; + Status = g_ProtoStates[dat->szProtocol].Status; + HICON hTitleIcon = LoadSkinnedProtoIcon(szProto, Status); + HICON hTitleIconBig = LoadSkinnedProtoIconBig(szProto, Status); + + + + + if(hTitleIconBig == NULL || (HICON)CALLSERVICE_NOTFOUND == hTitleIconBig) { + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hTitleIconBigElse); + } else { + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hTitleIconBig); + } + + SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hTitleIcon); + + + SendDlgItemMessage(hwndDlg, IDC_SAWAYMSG_MSGDATA, EM_LIMITTEXT, AWAY_MSGDATA_MAX, 0); + + + + + // init window size variables / resize the window + RECT rc; + POINT pt; + GetWindowRect(GetDlgItem(hwndDlg, IDC_SAWAYMSG_MSGSPLITTER), &rc); + pt.x = (rc.left + rc.right) / 2; + pt.y = 0; + ScreenToClient(hwndDlg, &pt); + g_MsgSplitterX = pt.x; + RECT rcContactSplitter; + GetWindowRect(GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSPLITTER), &rcContactSplitter); + RECT rcMsgDlg; + GetWindowRect(hwndDlg, &rcMsgDlg); + g_ContactSplitterX = rcMsgDlg.right - rcContactSplitter.left - (rcContactSplitter.right - rcContactSplitter.left) / 2; + RECT rcVars; + GetWindowRect(GetDlgItem(hwndDlg, IDC_SAWAYMSG_VARS), &rcVars); + g_VariablesButtonDX = rcContactSplitter.left - rcVars.right; +// GetWindowRect(GetDlgItem(hwndDlg, IDC_OK), &rc); + RECT rcOK; + GetWindowRect(GetDlgItem(hwndDlg, IDC_OK), &rcOK); + //MinMsgEditSize = rc.right - rc.left + rcContactSplitter.right - rcVars.left + 3; + MinMsgEditSize = rcOK.right - rc.left + rcContactSplitter.right - rcVars.left + 3; + rc.left = MINSPLITTERPOS; + + //NightFox: use MINSPLITTERPOS as min size ; +// GetWindowRect(GetDlgItem(hwndDlg, IDC_SAWAYMSG_SAVEMSG), &rc); +// GetWindowRect(GetDlgItem(hwndDlg, IDC_SAWAYMSG_DELETE), &rc); +// rc.left = MINSPLITTERPOS; + //GetWindowRect(GetDlgItem(hwndDlg, IDC_OK), &rc); + //GetWindowRect(GetDlgItem(hwndDlg, IDC_OK), &rc); + + pt.x = rc.right; + pt.y = 0; + ScreenToClient(hwndDlg, &pt); + MinMsgSplitterX = pt.x; + GetWindowRect(GetDlgItem(hwndDlg, IDC_SAWAYMSG_IGNOREREQ), &rc); + MinContactSplitterX = rcMsgDlg.right - rc.left + 1; + + /* + + //NightFox: add status bar + + PROTOACCOUNT * acc = ProtoGetAccount(szProto); + + //HWND hWndStatusBar = CreateStatusWindow(WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | SBARS_SIZEGRIP, NULL, hwndDlg, 999);//IDC_STATUSBAR); + SetWindowPos(hWndStatusBar, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); + + + SIZE sz; + + HDC hdc = GetDC(hWndStatusBar); + HFONT hFntSave = (HFONT)SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT)); + GetTextExtentPoint32(hdc, acc->tszAccountName, lstrlen(acc->tszAccountName), &sz); + sz.cx += GetSystemMetrics(SM_CXSMICON) * 3; + SelectObject(hdc, hFntSave); + ReleaseDC(hWndStatusBar, hdc); + + RECT rcStatus; GetWindowRect(hWndStatusBar, &rcStatus); + int parts[] = { rcStatus.right-rcStatus.left - sz.cx, -1 }; + SendMessage(hWndStatusBar, SB_SETPARTS, 2, (LPARAM)parts); + SendMessage(hWndStatusBar, SB_SETICON, 1, (LPARAM)LoadSkinnedProtoIcon(szProto, Status)); + SendMessage(hWndStatusBar, SB_SETTEXT, 1, (LPARAM)acc->tszAccountName); + */ + + + + + + + + + + + // [try] getting dialog position + int DlgPosX = DBGetContactSettingDword(NULL, MOD_NAME, SAM_DB_DLGPOSX, -1); + int DlgPosY = DBGetContactSettingDword(NULL, MOD_NAME, SAM_DB_DLGPOSY, -1); + int DlgSizeX = DBGetContactSettingDword(NULL, MOD_NAME, SAM_DB_DLGSIZEX, -1); + int DlgSizeY = DBGetContactSettingDword(NULL, MOD_NAME, SAM_DB_DLGSIZEY, -1); + int MsgSplitterX = DBGetContactSettingDword(NULL, MOD_NAME, SAM_DB_MSGSPLITTERPOS, -1); + int ContactSplitterX = DBGetContactSettingDword(NULL, MOD_NAME, SAM_DB_CONTACTSPLITTERPOS, -1); + if (DlgPosX >= 0 && DlgPosY >= 0 && DlgSizeX > 0 && DlgSizeY > 0 && MsgSplitterX > 0 && ContactSplitterX > 0) + { + RECT rcWorkArea, rcIntersect; + SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, 0); + RECT rcDlgPos = {DlgPosX, DlgPosY, DlgPosX + DlgSizeX, DlgPosY + DlgSizeY}; + if (!IntersectRect(&rcIntersect, &rcDlgPos, &rcWorkArea)) // make sure the window will be visible + { + DlgPosX = rcWorkArea.left; + DlgPosY = rcWorkArea.top; + } + SetWindowPos(hwndDlg, NULL, DlgPosX, DlgPosY, DlgSizeX, DlgSizeY, SWP_NOZORDER); + g_MsgSplitterX = MsgSplitterX; + g_ContactSplitterX = ContactSplitterX; + } + + SetMsgSplitterX = g_MsgSplitterX; + SetContactSplitterX = g_ContactSplitterX; + SendMessage(hwndDlg, WM_SIZE, 0, 0); // show/hide dialog controls accordingly to the settings + + MsgTree = new CMsgTree(GetDlgItem(hwndDlg, IDC_SAWAYMSG_TREE)); // Attention: it's important to call NEW and DELETE in a proper order, as CMsgTree and CCList are setting their own WNDPROCs for the parent window, so we must prevent WNDPROC conflicts. + CList = NULL; + if (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWCONTACTTREE)) + { + SendMessage(hwndDlg, UM_SAM_INITCLIST, 0, 0); + } else + { + NMCLIST nm; + nm.hdr.code = MCLN_SELCHANGED; + nm.hdr.hwndFrom = GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE); + nm.hdr.idFrom = IDC_SAWAYMSG_CONTACTSTREE; + nm.OldSelection = CLSEL_DAT_NOTHING; + nm.NewSelection = CLSEL_DAT_CONTACT; + SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&nm); + } + + // init message tree + if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_RECENTMSGSCOUNT) && g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_PERSTATUSMRM)) + { + char *szProto = dat->hInitContact ? (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)dat->hInitContact, 0) : dat->szProtocol; + int ID = GetRecentGroupID((szProto || !dat->hInitContact) ? g_ProtoStates[szProto].Status : ID_STATUS_AWAY); + CBaseTreeItem* pTreeItem = MsgTree->GetNextItem(MTGN_CHILD | MTGN_BYID, (CBaseTreeItem*)g_Messages_RecentRootID); + while (pTreeItem) + { + if (pTreeItem->Flags & TIF_GROUP) + { + if (pTreeItem->ID == ID) + { + pTreeItem->Flags |= TIF_EXPANDED; // leave expanded only one appropriate subgroup of Recent Messages group + } else + { + pTreeItem->Flags &= ~TIF_EXPANDED; + } + MsgTree->UpdateItem(pTreeItem->ID); + } + pTreeItem = MsgTree->GetNextItem(MTGN_NEXT, pTreeItem); + } +// InvalidateRect(GetDlgItem(hwndDlg, IDC_SAWAYMSG_TREE), NULL, true); + } + int Order; + CProtoSettings(dat->szProtocol).GetMsgFormat(GMF_LASTORDEFAULT, &Order); + if (Order >= 0) + { // so just select an appropriate message tree item; MSGDATA text is filled automatically through SELCHANGED notification + MsgTree->SetSelection(Order, MTSS_BYORDER); + } + + if (dat->Message != NULL) // this allows to override the default message + { + SetDlgItemText(hwndDlg, IDC_SAWAYMSG_MSGDATA, dat->Message); + SendDlgItemMessage(hwndDlg, IDC_SAWAYMSG_MSGDATA, EM_SETMODIFY, true, 0); + } + SendDlgItemMessage(hwndDlg, IDC_SAWAYMSG_MSGDATA, EM_SETSEL, 0, -1); // select all the text in the edit control + + // init timer + Countdown = (dat->ISW_Flags & ISWF_NOCOUNTDOWN) ? -1 : g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_WAITFORMSG); + if (Countdown == -1) // infinite + { + SetDlgItemText(hwndDlg, IDC_OK, TranslateT("OK")); + } else + { + SendMessage(hwndDlg, WM_TIMER, SAM_TIMER_ID, NULL); + SetTimer(hwndDlg, SAM_TIMER_ID, 1000, NULL); + } + + // init image buttons + int I; + for (I = 0; I < lengthof(Buttons); I++) + { + HWND hButton = GetDlgItem(hwndDlg, Buttons[I].DlgItem); + SendMessage(hButton, BUTTONADDTOOLTIP, (WPARAM)TranslateTS(Buttons[I].Text), BATF_TCHAR); + SendMessage(hButton, BUTTONSETASFLATBTN, TRUE, 0); + } + + // init tooltips + struct { + int DlgItemID; + TCHAR* Text; + } Tooltips[] = { + IDC_SAWAYMSG_IGNOREREQ, LPGENT("Don't send the status message to selected contact(s)"), + IDC_SAWAYMSG_SENDMSG, LPGENT("Send an autoreply to selected contact(s)"), + }; + TOOLINFO ti = {0}; + hWndTooltips = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, _T(""), WS_POPUP, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL); + ti.cbSize = sizeof(ti); + ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS; + for (I = 0; I < lengthof(Tooltips); I++) + { + ti.uId = (UINT)GetDlgItem(hwndDlg, Tooltips[I].DlgItemID); + ti.lpszText = TranslateTS(Tooltips[I].Text); + SendMessage(hWndTooltips, TTM_ADDTOOL, 0, (LPARAM)&ti); + } + SendMessage(hwndDlg, UM_ICONSCHANGED, 0, 0); + + g_OrigCListProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE), GWLP_WNDPROC, (LONG_PTR)CListSubclassProc); + g_OrigEditMsgProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_SAWAYMSG_MSGDATA), GWLP_WNDPROC, (LONG_PTR)MsgEditSubclassProc); + g_OrigSplitterProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_SAWAYMSG_MSGSPLITTER), GWLP_WNDPROC, (LONG_PTR)SplitterSubclassProc); + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSPLITTER), GWLP_WNDPROC, (LONG_PTR)SplitterSubclassProc); + return false; + } break; + case WM_NOTIFY: + { + switch (((NMHDR*)lParam)->idFrom) + { + case IDC_SAWAYMSG_CONTACTSTREE: + { + switch (((NMHDR*)lParam)->code) // check the notification code + { + case NM_CLICK: + { + _ASSERT(CList); + HWND hTreeView = GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE); + POINT pt = {(short)LOWORD(GetMessagePos()), (short)HIWORD(GetMessagePos())}; + ScreenToClient(hTreeView, &pt); + DWORD hitFlags; + HTREEITEM hItem = CList->HitTest(&pt, &hitFlags); + if (hitFlags & MCLCHT_ONITEMEXTRA) + { + int nColumn = HIBYTE(HIWORD(hitFlags)); + int CurIcon = CList->GetExtraImage(hItem, nColumn); + int ItemType = CList->GetItemType(hItem); + if (nColumn == EXTRACOLUMN_IGNORE) + { + CurIcon = (CurIcon == EXTRAIMGLIST_IGNORE) ? EXTRAIMGLIST_DOT : EXTRAIMGLIST_IGNORE; + } else + { + _ASSERT(nColumn == EXTRACOLUMN_REPLY); + switch (CurIcon) + { + case EXTRAIMGLIST_DOT: CurIcon = EXTRAIMGLIST_AUTOREPLY_OFF; break; + case EXTRAIMGLIST_AUTOREPLY_OFF: CurIcon = EXTRAIMGLIST_AUTOREPLY_ON; break; + case EXTRAIMGLIST_AUTOREPLY_ON: CurIcon = EXTRAIMGLIST_DOT; break; + } + } + SetExtraIcon(CList, nColumn, hItem, CurIcon); + if (ItemType == MCLCIT_GROUP) // set all child items + { + HTREEITEM hCurItem = CList->GetNextItem(MCLGN_CHILD, hItem); + HTREEITEM hLimitItem = CList->GetNextItem(MCLGN_NEXT | MCLGN_ANY | MCLGN_NOTCHILD, hItem); + while (hCurItem && hCurItem != hLimitItem) + { + SetExtraIcon(CList, nColumn, hCurItem, CurIcon); + hCurItem = CList->GetNextItem(MCLGN_NEXT | MCLGN_ANY | MCLGN_MULTILEVEL, hCurItem); + } + } + SetCListGroupIcons(dat, CList); + UpdateCheckboxesState(CList); + } + } break; + case MCLN_SELCHANGED: + { + PNMCLIST nm = (PNMCLIST)lParam; + TCString BtnTitle(TranslateT("OK")); + if (CList) + { + UpdateCheckboxesState(CList); + } + bool bOnlyInfo; + bool bLeaveOldMessage = nm->OldSelection == nm->NewSelection; // OldSelection == NewSelection when we send MCLN_SELCHANGED from UM_SAM_PROTOSTATUSCHANGED; seems that it's better to leave old message then + int nOldContacts = GetSelContactsNum(CList, nm->OldSelection); + int nNewContacts = GetSelContactsNum(CList, nm->NewSelection, &bOnlyInfo); + EnableWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_IGNOREREQ), !bOnlyInfo); + if (CList) + { + if (SendDlgItemMessage(hwndDlg, IDC_SAWAYMSG_MSGDATA, EM_GETMODIFY, 0, 0)) + { + int I, J; + for (I = nm->OldSelection->GetSize() - 1; I >= 0; I--) + { + for (J = nm->NewSelection->GetSize() - 1; J >= 0; J--) + { + if ((*nm->NewSelection)[J] == (*nm->OldSelection)[I]) + { + break; + } + } + if (J < 0) + { + break; + } + } + if (nNewContacts > 1) + { + BtnTitle = TranslateT("Apply"); + } + if (I >= 0 && nOldContacts) // there's at least one item in the old selection that is not present in the new one + { + if ((nOldContacts == 1) || MessageBox(hwndDlg, TranslateT("Do you want to apply the message?"), TranslateT("New Away System"), MB_ICONQUESTION | MB_YESNO) == IDYES) + { + ApplySelContactsMessage(dat, CList, nm->OldSelection); + } + } else if (nOldContacts) + { + bLeaveOldMessage = true; // don't change the edit control text yet - we're still writing... + } + } + } else + { + if (nOldContacts && !nNewContacts) + { + ApplySelContactsMessage(dat, CList, nm->OldSelection); + } + } + + // determine the right new message and window title for the edit control now + TCString Message; + int Status = 0; + if (CList) + { + bool MessageDetermined = false; + bool StatusDetermined = false; + int I; + for (I = 0; I < nm->NewSelection->GetSize(); I++) + { + HTREEITEM hItem = (*nm->NewSelection)[I]; + HANDLE hContact; + char *szProto; + int ItemType = CList->GetItemType(hItem); + if (ItemType == MCLCIT_CONTACT) + { + hContact = CList->GethContact(hItem); + _ASSERT(hContact); + szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + _ASSERT(szProto); + } else if (ItemType == MCLCIT_INFO) + { + szProto = (char*)CList->GetItemParam(hItem); + } + if (ItemType == MCLCIT_CONTACT || ItemType == MCLCIT_INFO) + { + int CurStatus = g_ProtoStates[szProto].Status; + if (!MessageDetermined) + { + TCString CurMessage((ItemType == MCLCIT_CONTACT) ? CContactSettings(0, hContact).GetMsgFormat(GMF_PERSONAL) : CProtoSettings(szProto).GetMsgFormat(GMF_TEMPORARY | GMF_PERSONAL)); + if (CurMessage == NULL) + { + CurMessage = _T(""); + } + if (Message == NULL) + { + Message = CurMessage; + } else if (CurMessage != (const TCHAR*)Message) + { + Message = _T(""); + BtnTitle = TranslateT("Apply"); + MessageDetermined = true; + } + } + if (!StatusDetermined) + { + if (!Status) + { + Status = CurStatus; + } else if (CurStatus != Status) + { + Status = 0; + StatusDetermined = true; + } + } + } + } + } else if (nNewContacts) // if (!CList) + { + Status = g_ProtoStates[dat->szProtocol].Status; + Message = dat->hInitContact ? CContactSettings(0, dat->hInitContact).GetMsgFormat(GMF_PERSONAL) : CProtoSettings(dat->szProtocol).GetMsgFormat(GMF_TEMPORARY | GMF_PERSONAL); + } + if (!bLeaveOldMessage) + { + SetDlgItemText(hwndDlg, IDC_SAWAYMSG_MSGDATA, (Message == NULL) ? _T("") : Message); + } + SetDlgItemText(hwndDlg, IDC_OK, BtnTitle); + //NightFox: fix titlebar + //TCString WindowTitle(TranslateT("Set ")); + TCString WindowTitle(TranslateT("Set message for")); + WindowTitle += _T(" \""); + WindowTitle += Status ? (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, Status, GSMDF_TCHAR) : TranslateT("Statuses"); + //WindowTitle += TranslateT(" message"); + if (nNewContacts == 1) + { + WindowTitle += TCString(TranslateT("\" (")); + HANDLE hContact = NULL; + char *szProto = NULL; + if (CList) + { + int I; + for (I = 0; I < nm->NewSelection->GetSize(); I++) + { + HTREEITEM hItem = (*nm->NewSelection)[I]; + int ItemType = CList->GetItemType(hItem); + if (ItemType == MCLCIT_CONTACT) + { + hContact = CList->GethContact((*nm->NewSelection)[I]); + break; + } else if (ItemType == MCLCIT_INFO) + { + szProto = (char*)CList->GetItemParam(hItem); + break; + } + } + } else + { + hContact = dat->hInitContact; + szProto = dat->szProtocol; + } + if (hContact) + { + + if (IsAnICQProto((char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0))) { + WindowTitle += TranslateT("message for"); + WindowTitle += _T(" "); + } else { + WindowTitle += TranslateT("for"); + WindowTitle += _T(" "); + } + + + WindowTitle += (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR); + if (!IsAnICQProto((char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0))) + { + //WindowTitle += TranslateT(" (autoreply only)"); + WindowTitle += _T(" "); + WindowTitle += TranslateT("available autoreply only"); + WindowTitle += _T(")"); + } else { + WindowTitle += _T(")"); + } + } else + { + if (!szProto) + { + //WindowTitle += TranslateT("all contacts"); + WindowTitle += TranslateT("all accounts"); + WindowTitle += _T(")"); + } else + { + //CString ProtoTitle; + + /*if (CallProtoService(szProto, PS_GETNAME, 256, (LPARAM)ProtoTitle.GetBuffer(256))) + { // on a failure, set ProtoTitle to an empty string + //ProtoTitle[0] = '\0'; + }*/ + //ProtoTitle.ReleaseBuffer(); + //WindowTitle += ANSI2TCHAR(ProtoTitle) + TranslateT(" protocol"); + + PROTOACCOUNT * acc = ProtoGetAccount(szProto); + + WindowTitle += acc->tszAccountName; + //WindowTitle += _T(" "); + //WindowTitle += TranslateT("account"); + WindowTitle += _T(")"); + } + } + } else { + WindowTitle += _T("\""); + } + SetWindowText(hwndDlg, WindowTitle); + } break; + } + } break; + case IDC_SAWAYMSG_TREE: + { + switch (((NMHDR*)lParam)->code) + { + case MTN_SELCHANGED: + { + if (!UpdateLock) + { + PNMMSGTREE pnm = (PNMMSGTREE)lParam; + if (pnm->ItemNew && !(pnm->ItemNew->Flags & (TIF_ROOTITEM | TIF_GROUP))) + { + SetDlgItemText(hwndDlg, IDC_SAWAYMSG_MSGDATA, ((CTreeItem*)pnm->ItemNew)->User_Str1); + SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_SAWAYMSG_MSGDATA, EN_CHANGE), (LPARAM)GetDlgItem(hwndDlg, IDC_SAWAYMSG_MSGDATA)); + SendDlgItemMessage(hwndDlg, IDC_SAWAYMSG_MSGDATA, EM_SETMODIFY, true, 0); + EnableWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_SAVEMSG), true); + } else + { + EnableWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_SAVEMSG), false); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_DELETE), pnm->ItemNew && !(pnm->ItemNew->Flags & TIF_ROOTITEM)); + } + } break; + } + } break; + } + return true; + } break; + case WM_TIMER: + { + if (wParam == SAM_TIMER_ID) + { + if (!Countdown) + { + SendMessage(hwndDlg, UM_SAM_APPLYANDCLOSE, 0, 0); + return true; + } + TCHAR BtnTitle[64]; + _sntprintf(BtnTitle, sizeof(BtnTitle), TranslateT("Closing in %d"), Countdown); + SetDlgItemText(hwndDlg, IDC_OK, BtnTitle); + Countdown--; + } + } break; + case UM_SAM_INITCLIST: + { + _ASSERT(!CList); + CList = new CCList(GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE)); + + // init contact tree + HIMAGELIST hil; + hil = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), (IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR16) | ILC_MASK, 5, 2); + ImageList_AddIcon(hil, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_DOT))); + ImageList_AddIcon(hil, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_IGNORE))); + ImageList_AddIcon(hil, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_MSGICON))); + ImageList_AddIcon(hil, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SOE_ENABLED))); + ImageList_AddIcon(hil, LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SOE_DISABLED))); + CList->SetExtraImageList(hil); + + HTREEITEM hSelItem; + HTREEITEM hItem = hSelItem = CList->AddInfo(TranslateT("** All contacts **"), CLC_ROOT, CLC_ROOT, NULL, LoadSkinnedProtoIcon(NULL, g_ProtoStates[(char*)NULL].Status)); + int ProtoCount; + PROTOCOLDESCRIPTOR **proto; + CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&ProtoCount, (LPARAM)&proto); + int I; + for (I = 0; I < ProtoCount; I++) + { + if (proto[I]->type == PROTOTYPE_PROTOCOL && CallProtoService(proto[I]->szName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND) // don't forget to change Recent Message Save loop in the UM_SAM_APPLYANDCLOSE if you're changing something here + { + //CString ProtoTitle; + //CallProtoService(proto[I]->szName, PS_GETNAME, 256, (LPARAM)ProtoTitle.GetBuffer(256)); + //ProtoTitle.ReleaseBuffer(); + + PROTOACCOUNT * acc = ProtoGetAccount(proto[I]->szName); + //NightFox: protocols -> accounts + //hItem = CList->AddInfo(TCString(_T("* ")) + ANSI2TCHAR(ProtoTitle) + TranslateT(" contacts *"), CLC_ROOT, hItem, (LPARAM)proto[I]->szName, LoadSkinnedProtoIcon(proto[I]->szName, g_ProtoStates[proto[I]->szName].Status)); + hItem = CList->AddInfo(TCString(_T("* ")) + acc->tszAccountName/* + TranslateT(" contacts *")*/ + _T(" *"), CLC_ROOT, hItem, (LPARAM)proto[I]->szName, LoadSkinnedProtoIcon(proto[I]->szName, g_ProtoStates[proto[I]->szName].Status)); + if (dat->szProtocol && !strcmp(proto[I]->szName, dat->szProtocol)) + { + hSelItem = hItem; + } + } + } + + HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + CList->SetRedraw(false); + do + { + char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + if (szProto) + { + int Flag1 = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0); + if ((Flag1 & PF1_IM) == PF1_IM || Flag1 & PF1_INDIVMODEMSG) + { // check if the protocol supports message sending/receiving or individual status messages before adding this contact + HTREEITEM hItem = CList->AddContact(hContact); + if (dat->hInitContact == hContact) + { + hSelItem = hItem; + } + } + } + } while (hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)); + CList->SortContacts(); + hItem = CLC_ROOT; + while (hItem = CList->GetNextItem(MCLGN_NEXT | MCLGN_CONTACT | MCLGN_INFO | MCLGN_MULTILEVEL, hItem)) + { + SetExtraIcon(CList, EXTRACOLUMN_IGNORE, hItem, -1); + SetExtraIcon(CList, EXTRACOLUMN_REPLY, hItem, -1); + } + SetCListGroupIcons(dat, CList); + CList->SetRedraw(true); // SetRedraw must be before SelectItem - otherwise SelectItem won't change scrollbar position to make the selected contact visible + CList->SelectItem(hSelItem); // must be selected after setting all extra icons, to set checkboxes properly + } break; + case UM_SAM_APPLYANDCLOSE: + { + KillTimer(hwndDlg, SAM_TIMER_ID); + if (CList) + { + CList->SelectItem(NULL); + } else + { + NMCLIST nm; + nm.hdr.code = MCLN_SELCHANGED; + nm.hdr.hwndFrom = GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE); + nm.hdr.idFrom = IDC_SAWAYMSG_CONTACTSTREE; + nm.OldSelection = CLSEL_DAT_CONTACT; + nm.NewSelection = CLSEL_DAT_NOTHING; + SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&nm); + } + MsgTree->Save(); + // save Recent Messages + int ProtoCount; + PROTOCOLDESCRIPTOR **proto; + CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&ProtoCount, (LPARAM)&proto); + int I; + for (I = 0; I < ProtoCount; I++) + { + if (proto[I]->type == PROTOTYPE_PROTOCOL && CallProtoService(proto[I]->szName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND) + { + TCString Message(CProtoSettings(proto[I]->szName).GetMsgFormat(GMF_PERSONAL)); // yes, we don't specify GMF_TEMPORARY here, because we don't need to save it + if (Message != NULL) + { + CProtoSettings(proto[I]->szName).SetMsgFormat(SMF_LAST, Message); // if the user set a message for this protocol, save it to the recent messages + } + ChangeProtoMessages(proto[I]->szName, g_ProtoStates[proto[I]->szName].Status, TCString(NULL)); // and actual setting of a status message for the protocol + } + } + TCString Message(CProtoSettings().GetMsgFormat(GMF_PERSONAL)); + if (Message != NULL) + { + CProtoSettings().SetMsgFormat(SMF_LAST, Message); // save the global message to the recent messages + } + if (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_AUTOSAVEDLGSETTINGS)) + { + SendMessage(hwndDlg, UM_SAM_SAVEDLGSETTINGS, 0, 0); + } + if (dat->IsModeless) + { + DestroyWindow(hwndDlg); + } else + { + EndDialog(hwndDlg, 2); + } + return true; + } break; + case UM_SAM_SAVEDLGSETTINGS: + { + RECT rcRect; + GetWindowRect(hwndDlg, &rcRect); + DBWriteContactSettingDword(NULL, MOD_NAME, SAM_DB_DLGPOSX, rcRect.left); + DBWriteContactSettingDword(NULL, MOD_NAME, SAM_DB_DLGPOSY, rcRect.top); + DBWriteContactSettingDword(NULL, MOD_NAME, SAM_DB_DLGSIZEX, rcRect.right - rcRect.left); + DBWriteContactSettingDword(NULL, MOD_NAME, SAM_DB_DLGSIZEY, rcRect.bottom - rcRect.top); + DBWriteContactSettingDword(NULL, MOD_NAME, SAM_DB_MSGSPLITTERPOS, g_MsgSplitterX); + DBWriteContactSettingDword(NULL, MOD_NAME, SAM_DB_CONTACTSPLITTERPOS, g_ContactSplitterX); + g_SetAwayMsgPage.PageToMemToDB(); + } break; + case UM_SAM_REPLYSETTINGCHANGED: + { // wParam = (HANDLE)hContact + if (CList) + { + HTREEITEM hItem = CLC_ROOT; + if (!wParam) + { // it's the global autoreply setting + while (hItem = CList->GetNextItem(MCLGN_NEXT | MCLGN_INFO | MCLGN_MULTILEVEL, hItem)) + { + if (!CList->GetItemParam(hItem)) + { // we found the item + SetExtraIcon(CList, EXTRACOLUMN_REPLY, hItem, -1); // update it + break; + } + } + } else + { // it's a contact's autoreply setting + while (hItem = CList->GetNextItem(MCLGN_NEXT | MCLGN_CONTACT | MCLGN_MULTILEVEL, hItem)) + { + HANDLE hContact = CList->GethContact(hItem); + if (CList->GethContact(hItem) == (HANDLE)wParam) + { // we found the item + SetExtraIcon(CList, EXTRACOLUMN_REPLY, hItem, -1); // update it + break; + } + } + } + UpdateCheckboxesState(CList); + } + } break; + case UM_SAM_PROTOSTATUSCHANGED: + { // wParam = (char*)szProto + if (CList) + { + HTREEITEM hItem = CLC_ROOT; + while (hItem = CList->GetNextItem(MCLGN_NEXT | MCLGN_CONTACT | MCLGN_INFO | MCLGN_MULTILEVEL, hItem)) + { + if (CList->GetItemType(hItem) == MCLCIT_INFO) + { + char *szProto = (char*)CList->GetItemParam(hItem); + if (!wParam || !lstrcmpA(szProto, (char*)wParam)) + { + CList->SetInfoIcon(hItem, LoadSkinnedProtoIcon(szProto, g_ProtoStates[szProto].Status)); + } + } + SetExtraIcon(CList, EXTRACOLUMN_IGNORE, hItem, -1); + SetExtraIcon(CList, EXTRACOLUMN_REPLY, hItem, -1); + } + SetCListGroupIcons(dat, CList); + } +/* dat->hInitContact = NULL; // TODO: test it + dat->szProtocol = (char*)wParam;*/ + NMCLIST nm; + nm.hdr.code = MCLN_SELCHANGED; + nm.hdr.hwndFrom = GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE); + nm.hdr.idFrom = IDC_SAWAYMSG_CONTACTSTREE; + nm.OldSelection = nm.NewSelection = CList ? CList->GetSelection() : CLSEL_DAT_CONTACT; + SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&nm); // everything else is in the MCLN_SELCHANGED handler, so we'll just call it from here. + } break; + case UM_ICONSCHANGED: + { + int I; + for (I = 0; I < lengthof(Buttons); I++) + { + if (Buttons[I].IconIndex != ILI_NOICON) + { + SendDlgItemMessage(hwndDlg, Buttons[I].DlgItem, BM_SETIMAGE, IMAGE_ICON, (LPARAM)g_IconList[Buttons[I].IconIndex]); + } + } + my_variables_skin_helpbutton(hwndDlg, IDC_SAWAYMSG_VARS); + } break; + case WM_COMMAND: + { + switch (HIWORD(wParam)) + { + case EN_CHANGE: + { + if (LOWORD(wParam) == IDC_SAWAYMSG_MSGDATA) + { + SetDlgItemText(hwndDlg, IDC_OK, TranslateTS((GetSelContactsNum(CList) > 1) ? LPGENT("Apply") : LPGENT("OK"))); + } + } break; + case EN_KILLFOCUS: + { + if (LOWORD(wParam) == IDC_SAWAYMSG_MSGDATA && GetForegroundWindow() == hwndDlg) + { + SendMessage(hwndDlg, UM_SAM_KILLTIMER, 0, 0); + } + } break; + case BN_CLICKED: + { + switch (LOWORD(wParam)) + { + case IDC_SAWAYMSG_IGNOREREQ: + { + _ASSERT(CList); + int Ignore = IsDlgButtonChecked(hwndDlg, IDC_SAWAYMSG_IGNOREREQ) == BST_CHECKED; + EnableWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_SENDMSG), !Ignore); + PTREEITEMARRAY Selection = CList->GetSelection(); + int I; + for (I = 0; I < Selection->GetSize(); I++) + { + if (CList->GetItemType((*Selection)[I]) == MCLCIT_CONTACT) + { + SetExtraIcon(CList, EXTRACOLUMN_IGNORE, (*Selection)[I], Ignore ? EXTRAIMGLIST_IGNORE : EXTRAIMGLIST_DOT); + } + } + if (Selection->GetSize() == 1) + { + CList->EnsureVisible((*Selection)[0]); + } + SetCListGroupIcons(dat, CList); + } break; + case IDC_SAWAYMSG_SENDMSG: + { + _ASSERT(CList); + int Reply = IsDlgButtonChecked(hwndDlg, IDC_SAWAYMSG_SENDMSG); + int ReplyIcon = (Reply == BST_CHECKED) ? EXTRAIMGLIST_AUTOREPLY_ON : ((Reply == BST_UNCHECKED) ? EXTRAIMGLIST_AUTOREPLY_OFF : EXTRAIMGLIST_DOT); + PTREEITEMARRAY Selection = CList->GetSelection(); + int I; + for (I = 0; I < Selection->GetSize(); I++) + { + SetExtraIcon(CList, EXTRACOLUMN_REPLY, (*Selection)[I], ReplyIcon); + } + if (Selection->GetSize() == 1) + { + CList->EnsureVisible((*Selection)[0]); + } + SetCListGroupIcons(dat, CList); + } break; + case IDC_SAWAYMSG_OPTIONS: + { + HMENU hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_SAM_OPTIONS)); + _ASSERT(hMenu); + HMENU hPopupMenu = GetSubMenu(hMenu, 0); + TranslateMenu(hPopupMenu); + CheckMenuItem(hPopupMenu, IDM_SAM_OPTIONS_SHOWMSGTREE, MF_BYCOMMAND | (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWMSGTREE) ? MF_CHECKED : MF_UNCHECKED)); + CheckMenuItem(hPopupMenu, IDM_SAM_OPTIONS_SHOWCONTACTTREE, MF_BYCOMMAND | (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWCONTACTTREE) ? MF_CHECKED : MF_UNCHECKED)); + CheckMenuItem(hPopupMenu, IDM_SAM_OPTIONS_AUTOSAVEDLGSETTINGS, MF_BYCOMMAND | (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_AUTOSAVEDLGSETTINGS) ? MF_CHECKED : MF_UNCHECKED)); + int VariablesInstalled = ServiceExists(MS_VARS_FORMATSTRING); + CheckMenuItem(hPopupMenu, IDM_SAM_OPTIONS_DISABLEVARIABLES, MF_BYCOMMAND | ((g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_DISABLEVARIABLES) || !VariablesInstalled) ? MF_CHECKED : MF_UNCHECKED)); + if (!VariablesInstalled) + { + EnableMenuItem(hPopupMenu, IDM_SAM_OPTIONS_DISABLEVARIABLES, MF_BYCOMMAND | MF_GRAYED); + } + switch (TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, (short)LOWORD(GetMessagePos()), (short)HIWORD(GetMessagePos()), 0, hwndDlg, NULL)) + { + case IDM_SAM_OPTIONS_SHOWMSGTREE: + { + int bShow = !g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWMSGTREE); + g_SetAwayMsgPage.SetValue(IDS_SAWAYMSG_SHOWMSGTREE, bShow); + RECT rcDlg; + GetWindowRect(hwndDlg, &rcDlg); + rcDlg.left -= bShow ? g_MsgSplitterX : -g_MsgSplitterX; + SendMessage(hwndDlg, WM_SIZING, WMSZ_LEFT, (LPARAM)&rcDlg); + SetWindowPos(hwndDlg, NULL, rcDlg.left, rcDlg.top, rcDlg.right - rcDlg.left, rcDlg.bottom - rcDlg.top, SWP_NOZORDER); + SendMessage(hwndDlg, WM_SIZE, 0, 0); // show/hide dialog controls accordingly + } break; + case IDM_SAM_OPTIONS_SHOWCONTACTTREE: + { + int bShow = !g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWCONTACTTREE); + if (bShow && !CList) + { + NMCLIST nm; + nm.hdr.code = MCLN_SELCHANGED; + nm.hdr.hwndFrom = GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE); + nm.hdr.idFrom = IDC_SAWAYMSG_CONTACTSTREE; + nm.OldSelection = CLSEL_DAT_CONTACT; + nm.NewSelection = CLSEL_DAT_NOTHING; + SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&nm); // save current message + SendMessage(hwndDlg, UM_SAM_INITCLIST, 0, 0); + } + g_SetAwayMsgPage.SetValue(IDS_SAWAYMSG_SHOWCONTACTTREE, bShow); + RECT rcDlg; + GetWindowRect(hwndDlg, &rcDlg); + rcDlg.right += bShow ? g_ContactSplitterX : -g_ContactSplitterX; + SendMessage(hwndDlg, WM_SIZING, WMSZ_RIGHT, (LPARAM)&rcDlg); + SetWindowPos(hwndDlg, NULL, 0, 0, rcDlg.right - rcDlg.left, rcDlg.bottom - rcDlg.top, SWP_NOZORDER | SWP_NOMOVE); + SendMessage(hwndDlg, WM_SIZE, 0, 0); // show/hide dialog controls accordingly + } break; + case IDM_SAM_OPTIONS_AUTOSAVEDLGSETTINGS: + { + g_SetAwayMsgPage.SetDBValue(IDS_SAWAYMSG_AUTOSAVEDLGSETTINGS, !g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_AUTOSAVEDLGSETTINGS)); + } break; + case IDM_SAM_OPTIONS_SAVEDLGSETTINGSNOW: + { + SendMessage(hwndDlg, UM_SAM_SAVEDLGSETTINGS, 0, 0); + } break; + case IDM_SAM_OPTIONS_DISABLEVARIABLES: + { + g_SetAwayMsgPage.SetDBValue(IDS_SAWAYMSG_DISABLEVARIABLES, !g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_DISABLEVARIABLES)); + } break; + } + DestroyMenu(hMenu); + } break; + case IDC_SAWAYMSG_SAVEMSG: + { + CBaseTreeItem* TreeItem = MsgTree->GetSelection(); + if (TreeItem && !(TreeItem->Flags & TIF_ROOTITEM)) + { + MsgTree->EnsureVisible(TreeItem->hItem); + TCString NewMsg; + GetDlgItemText(hwndDlg, IDC_SAWAYMSG_MSGDATA, NewMsg.GetBuffer(AWAY_MSGDATA_MAX), AWAY_MSGDATA_MAX); + NewMsg.ReleaseBuffer(); + if (((CTreeItem*)TreeItem)->User_Str1 != (const TCHAR*)NewMsg) + { + ((CTreeItem*)TreeItem)->User_Str1 = NewMsg; + MsgTree->SetModified(true); + } + } + } break; + case IDC_SAWAYMSG_SAVEASNEW: + { + TCString Text; + GetDlgItemText(hwndDlg, IDC_SAWAYMSG_MSGDATA, Text.GetBuffer(AWAY_MSGDATA_MAX), AWAY_MSGDATA_MAX); + Text.ReleaseBuffer(); + UpdateLock++; + CTreeItem* TreeItem = MsgTree->AddMessage(); + UpdateLock--; + TreeItem->User_Str1 = Text; + } break; + case IDC_SAWAYMSG_NEWCATEGORY: + { + MsgTree->AddCategory(); + } break; + case IDC_SAWAYMSG_DELETE: + { + MsgTree->EnsureVisible(MsgTree->GetSelection()->hItem); + MsgTree->DeleteSelectedItem(); + } break; + case IDC_SAWAYMSG_VARS: + { + my_variables_showhelp(hwndDlg, IDC_SAWAYMSG_MSGDATA); + } break; + case IDC_OK: + { + // save OK button title before resetting it in SetSelContactsMessage + TCString BtnTitle; + GetDlgItemText(hwndDlg, IDC_OK, BtnTitle.GetBuffer(64), 64); + BtnTitle.ReleaseBuffer(); + ApplySelContactsMessage(dat, CList); + if (BtnTitle != (const TCHAR*)TranslateT("Apply")) + { + SendMessage(hwndDlg, UM_SAM_APPLYANDCLOSE, 0, 0); + } + } break; + } + } break; + } + } break; + case UM_SAM_SPLITTERMOVED: + { + switch (lParam) + { + RECT rc; + POINT pt; + case IDC_SAWAYMSG_MSGSPLITTER: + { + GetClientRect(hwndDlg, &rc); + pt.x = wParam; + pt.y = 0; + ScreenToClient(hwndDlg, &pt); + g_MsgSplitterX = (pt.x < MINSPLITTERPOS) ? MINSPLITTERPOS : pt.x; + int MaxSetSplitterX = rc.right - MINSPLITTERPOS + 2; + int MaxSplitterX = MaxSetSplitterX; + if (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWCONTACTTREE)) + { + MaxSetSplitterX -= g_ContactSplitterX; + MaxSplitterX -= MINSPLITTERPOS; + } + if (g_MsgSplitterX > MaxSetSplitterX) + { + if (g_MsgSplitterX > MaxSplitterX) + { + g_ContactSplitterX = MINSPLITTERPOS; + g_MsgSplitterX = MaxSplitterX; + } else + { + g_ContactSplitterX = MINSPLITTERPOS + MaxSplitterX - g_MsgSplitterX; + } + } + } break; + case IDC_SAWAYMSG_CONTACTSPLITTER: + { + GetClientRect(hwndDlg, &rc); + pt.x = wParam; + pt.y = 0; + ScreenToClient(hwndDlg, &pt); + g_ContactSplitterX = (rc.right - pt.x < MINSPLITTERPOS) ? MINSPLITTERPOS : (rc.right - pt.x); + int MaxSetSplitterX = rc.right - MINSPLITTERPOS + 2; + int MaxSplitterX = MaxSetSplitterX; + if (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWMSGTREE)) + { + MaxSetSplitterX -= g_MsgSplitterX; + MaxSplitterX -= MINSPLITTERPOS; + } + if (g_ContactSplitterX > MaxSetSplitterX) + { + if (g_ContactSplitterX > MaxSplitterX) + { + g_MsgSplitterX = MINSPLITTERPOS; + g_ContactSplitterX = MaxSplitterX; + } else + { + g_MsgSplitterX = MINSPLITTERPOS + MaxSplitterX - g_ContactSplitterX; + } + } + } break; + } + SetMsgSplitterX = g_MsgSplitterX; + SetContactSplitterX = g_ContactSplitterX; + SendMessage(hwndDlg, WM_SIZE, 0, 0); + } break; + case WM_SIZING: + { + RECT *prcDlg = (RECT*)lParam; + int MinSetXSize = MINSPLITTERPOS + 7; + int MinXSize = MinMsgEditSize + 7; + if (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWMSGTREE)) + { + MinSetXSize += SetMsgSplitterX - 1; + MinXSize += MinMsgSplitterX - 1; + } + if (g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWCONTACTTREE)) + { + MinSetXSize += SetContactSplitterX - 1; + MinXSize += MinContactSplitterX - 1; + } + if (prcDlg->right - prcDlg->left < MinXSize) + { + if (wParam != WMSZ_LEFT && wParam != WMSZ_TOPLEFT && wParam != WMSZ_BOTTOMLEFT) + { + prcDlg->right = prcDlg->left + MinXSize; + } else + { + prcDlg->left = prcDlg->right - MinXSize; + } + } + if (prcDlg->right - prcDlg->left < MinSetXSize) + { + int Delta = MinSetXSize - (prcDlg->right - prcDlg->left); + if (SetMsgSplitterX > MinMsgSplitterX) + { + int D2 = min(Delta, SetMsgSplitterX - MinMsgSplitterX); + g_MsgSplitterX = SetMsgSplitterX - D2; + Delta -= D2; + } + g_ContactSplitterX = SetContactSplitterX - Delta; + } else + { + g_MsgSplitterX = SetMsgSplitterX; + g_ContactSplitterX = SetContactSplitterX; + } + if (prcDlg->bottom - prcDlg->top < MINYDLGSIZE) + { + if (wParam != WMSZ_TOP && wParam != WMSZ_TOPLEFT && wParam != WMSZ_TOPRIGHT) + { + prcDlg->bottom = prcDlg->top + MINYDLGSIZE; + } else + { + prcDlg->top = prcDlg->bottom - MINYDLGSIZE; + } + } + return true; + } break; + case WM_SIZE: + { + UTILRESIZEDIALOG urd = {0}; + urd.cbSize = sizeof(urd); + urd.hInstance = g_hInstance; + urd.hwndDlg = hwndDlg; + urd.lParam = (LPARAM)&g_SetAwayMsgPage; + urd.lpTemplate = MAKEINTRESOURCEA(IDD_SETAWAYMSG); + urd.pfnResizer = SetAwayMsgDlgResize; + CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd); + if (!wParam && !lParam) // means that we sent WM_SIZE message to apply new settings to the dialog; probably it's somewhat a misuse, but who cares ;-P + { + int bShow; + bShow = g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWMSGTREE) ? SW_SHOW : SW_HIDE; + ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_TREE), bShow); + ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_SAVEMSG), bShow); + ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_SAVEASNEW), bShow); + ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_NEWCATEGORY), bShow); + ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_DELETE), bShow); + ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_MSGSPLITTER), bShow); + bShow = g_SetAwayMsgPage.GetValue(IDS_SAWAYMSG_SHOWCONTACTTREE) ? SW_SHOW : SW_HIDE; + ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE), bShow); + ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_IGNOREREQ), bShow); + ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_SENDMSG), bShow); + ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSPLITTER), bShow); + ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_STATIC_IGNOREICON), bShow); + ShowWindow(GetDlgItem(hwndDlg, IDC_SAWAYMSG_STATIC_REPLYICON), bShow); + } + /*if (hWndStatusBar) + { + RECT rcStatus; GetWindowRect(hWndStatusBar, &rcStatus); + RECT rcClient; GetClientRect(hwndDlg, &rcClient); + SetWindowPos(hWndStatusBar, NULL, 0, rcClient.bottom-(rcStatus.bottom-rcStatus.top), rcClient.right, (rcStatus.bottom-rcStatus.top), SWP_NOZORDER); + }*/ + + + } // go through + case UM_SAM_KILLTIMER: + case WM_LBUTTONDOWN: + case WM_MOUSEACTIVATE: + case WM_MOVING: // stops counting + { + if (Countdown != -1) // still counting + { + KillTimer(hwndDlg, SAM_TIMER_ID); + SetDlgItemText(hwndDlg, IDC_OK, TranslateT("OK")); + Countdown = -1; + } + } break; + case WM_SETCURSOR: + { + HWND hTreeView = GetDlgItem(hwndDlg, IDC_SAWAYMSG_CONTACTSTREE); + if ((HWND)wParam == hTreeView && LOWORD(lParam) == HTCLIENT) + { + _ASSERT(CList); + DWORD hitFlags; + POINT pt; + pt.x = (short)LOWORD(GetMessagePos()); + pt.y = (short)HIWORD(GetMessagePos()); + ScreenToClient(hTreeView, &pt); + CList->HitTest(&pt, &hitFlags); + HCURSOR hCursor = NULL; + if (hitFlags & (MCLCHT_ONITEM | MCLCHT_ONITEMEXTRA)) + { + SetClassLong(hTreeView, GCLP_HCURSOR, NULL); + hCursor = LoadCursor(NULL, IDC_HAND); // set mouse cursor to a hand when hovering over items or their extra images + } else + { + SetClassLong(hTreeView, GCLP_HCURSOR, (LONG)LoadCursor(NULL, IDC_ARROW)); + } + if (!hCursor) + { + hCursor = LoadCursor(NULL, IDC_ARROW); + } + SetCursor(hCursor); + return true; + } else + { + SetClassLong(hTreeView, GCLP_HCURSOR, (LONG)LoadCursor(NULL, IDC_ARROW)); + } + } break; + case WM_CLOSE: + { + KillTimer(hwndDlg, SAM_TIMER_ID); + if (dat->IsModeless) + { + DestroyWindow(hwndDlg); + } else + { + EndDialog(hwndDlg, 2); + } + } break; + case WM_DESTROY: + { + if (dat) + { + delete dat; + } + if (CList) + { + delete CList; + CList = NULL; + } + delete MsgTree; + MsgTree = NULL; + g_SetAwayMsgPage.SetWnd(NULL); + DestroyWindow(hWndTooltips); + return false; + } break; + } + return false; +} diff --git a/plugins/!Deprecated/NewAwaySysMod/VersionNo.h b/plugins/!Deprecated/NewAwaySysMod/VersionNo.h new file mode 100644 index 0000000000..3634e99662 --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/VersionNo.h @@ -0,0 +1,5 @@ +#define STRSPECIALBUILD "2636" +#define FILEVER 0, 3, 8, 4 +#define STRFILEVER "0, 3, 8, 4" +#define PRODUCTVER FILEVER +#define STRPRODUCTVER STRFILEVER diff --git a/plugins/!Deprecated/NewAwaySysMod/copying.txt b/plugins/!Deprecated/NewAwaySysMod/copying.txt new file mode 100644 index 0000000000..45645b4b53 --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/copying.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/plugins/!Deprecated/NewAwaySysMod/nas_readme.txt b/plugins/!Deprecated/NewAwaySysMod/nas_readme.txt new file mode 100644 index 0000000000..83395abf60 --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/nas_readme.txt @@ -0,0 +1,281 @@ +New Away System plugin + by Chervov Dmitry aka Deathdemon + +You can always find the latest plugin version here: http://deathdemon.int.ru/projects.php +If you have some questions, you'll find answers on most of them on the Miranda forums: http://forums.miranda-im.org/showthread.php?t=2179 + +New Away System requires at least Miranda v0.6 to work properly. v0.7 or above is recommended. +If you use an older Miranda core, either update it or use New Away System v0.3.7.8, which is available here: +http://deathdemon.int.ru/projects/archive/NewAwaySysW_build2371.zip (Unicode; Windows XP/2000/NT) +http://deathdemon.int.ru/projects/archive/NewAwaySys_build2371.zip (ANSI; Windows 95/98/ME) + +Overview +======== + +New Away System is a successor to AwaySysMod plugin by XF007 and Tornado. +It allows to set your status messages using dynamic variables and do some interesting tricks, like different message each time someone requests it, or different status message depending on a time of the day, and much more... + +If you're confused by all these variables, it's not a problem :) NAS can also be used in a usual way, by entering usual text as a status message. the only thing you really need to remember is that if your message gets parsed incorrectly (and this happens in some rare cases, when you accidentally use some special characters in the message, like # character), try enclosing that part of your message in `quotes` (note, it's `, not ' !) + +Main features: +- categorized predefined status messages (a message tree is used to store them) +- autoreply +- per-protocol status messages, and (ICQ only) per-contact status messages +- optional notification through a popup that someone read your status message (works only for ICQ, as it's the only protocol that stores status messages on the client side) +- logging ICQ status message requests to a file (requires LogService plugin) +- optional updating of your status messages on non-ICQ protocols every X seconds +- multiple ICQ accounts support + +Known issues: +- currently there is no way to show UINs of contacts that are not on the contact list and requesting a status message - it requires some changes to Variables plugin +- there's still no proper unicode status message support in protocol plugins, so even with unicode NAS version much depends on protocol itself + +To use dynamic variables in NAS, you need to install Variables plugin by Unregistered: http://www.pboon.nl/projects.htm (highly recommended, as without Variables NAS will have a limited functionality). +To log ICQ status message requests to a file, you need LogService plugin: http://deathdemon.int.ru/projects.php + +some useful variables: +?cinfo(%subject%,display) - nick of the contact who is reading your status message +?cinfo(%subject%,first) - first name of the contact +?cinfo(%subject%,last) - last name of the contact +(for detailed description of other possible values, see the Variables help dialog and readme) + +A brief description of the plugin options, just to make things more clear: +Default messages are used by default for each status, unless you set "by default... use the message from last time" in the miranda options -> Status -> Away System -> Main options tab. +Each status can have one and only one default message. that's why it's not possible to 'uncheck' "use this message as default for.." buttons, once they were checked. - just select another message in the tree and set it as default. +You can set any predefined message to be default for certain statuses. +Also you can add/delete/modify/move your messages/categories in the "Predefined messages" category of the message tree. +Most recent status messages are placed in the "Recent messages" category; it's not recommended to put your messages manually there, as they'll be replaced by your recent messages. However this category is editable too, just like "predefined messages" is. + +FAQ +=== + +Q: when I click on the blue question mark button, nothing happens +A: make sure you have the latest build of Variables plugin installed + +Q: all variables remain unparsed and other contacts read my status message, for example, as "Gone since %nas_awaysince_time%" instead of "Gone since 11:45" +A: Either a) see the previous answer Or b) you checked the "Disable parsing of status messages by Variables plugin" checkbox in the settings menu (one of the buttons on the bottom of the status message change dialog) + +Q: NAS uses a wrong status message when miranda sets idle status automatically after several minutes of inactivity +A: it's a known incompatibility with the built-in autoaway module and it's impossible to solve it in a reasonable way without changes to the miranda core. you can use AdvancedAutoAway plugin if you really need a correct status message with autoaway + +Q: NAS uses a wrong status message even when I set it manually +A: You cannot ever trust contact list's status bar tooltips that show your own status message (though in many cases they still show it correctly). The only way to make sure that your status message is correct is to ask your friend to read it. + +Q: what about xstatus support? +A: it's planned + +Q: why does NAS show ?cinfo variables unparsed ("?cinfo(%subject%,display)", "?cinfo(%subject%,id)" etc.) when the contact is not on the contact list? +A: it requires changes to Variables plugin to allow NAS to override the default behavior of ?cinfo variable. currently there's no any solution of this issue + +Q: I can't read or set a status message in unicode +A: there's still no proper support of unicode status messages by protocol plugins. So, currently even the unicode build of NAS is unable to show unicode status messages of your contacts. I'll fix it as soon as protocol plugins allow me to do that. + +Q: I updated NAS and an autoreply doesn't contain my status message now. with an old version it appended the status message at the end. +A: check that %extratext% is present at the end of Autoreply format (options ->Status->Away System->Autoreply tab). If it's not there, just add it at the end. for example, the default format is: +Miranda IM autoreply > +%extratext% + + +Thanks to +========= + +- Faith Healer for icons and useful suggestions +- Nullbie for his ideas +- Bio for a nice idea of msvcr70->msvcrt patch +- UnregistereD for Variables plugin +- ...and to many other people who reported bugs and gave me ideas + + +Contact +======= +The preferable way for questions, bug reports or some suggestions is using Miranda forums: +http://forums.miranda-im.org/showthread.php?t=2179 +Otherwise, if you have something extremely important to say, you can contact me on ICQ or e-mail :) ICQ: 310927; e-mail: dchervov@yahoo.com + + +Changelog +========= + +v0.3.8.3 (build 26xx; xxx xx, 2007) +--------- + - fixed some GDI leaks + +v0.3.8.2 (build 2628; Oct 13, 2007) +--------- + - fixed a bug with default messages and per-contact notification settings, introduced in the previous build + +v0.3.8.1 (build 2626; Oct 13, 2007) +--------- + - added "Not-on-list contacts" setting to the NAS' contact list in the options + - added back an option to log to a file only when popup notification for a contact is enabled + - fix for %nas_timepassed% to return correct value + - minor interface improvements + - ContactSettings api change + - some minor fixes + +v0.3.8.0 (build 2601; Oct 4, 2007) +--------- + - added Miranda 0.8 support + - significantly improved autoreply, added more options and fixed bugs + - added support for ICQ Plus online status messages + - removed %nas_message% variable. use %extratext% instead + - fixed xstatus request notifications + - moved logging features to a separate plugin - LogService + - added support for ContactSettings plugin + - MS_VARS_GETICON service is used now to get an icon for Variables help buttons + - some more minor fixes and improvements + +v0.3.7.8 (build 2371; Jul 2, 2006) +--------- + - fixed a bug with disappeared notification icons under the Contacts tab + - other minor fixes + +v0.3.7.7 (build 2368; Jul 2, 2006) +--------- + - support for locked protocols + - implemented unicode logging correctly (thanks to Unregistered) + - fix for MS_AWAYMSG_GETSTATUSMSG to return parsed status message + - made xstatus notification popups show current xstatus icon + - added possibility to change per-contact autoreply setting from the contact menu + - fix for wrong extra icons in the contact list of the status message change window + - other minor fixes and improvements + +v0.3.7.6 (build 2348; May 12, 2006) +--------- + - changed NAS behavior so that it accepts status message changes through PS_SETAWAYMSG service now + - removed some obsolete implementations of NAS services (update your MyDetails/StartupStatus/AdvancedAutoAway plugins if they stopped working with this release of NAS) + - fixed a minor bug - empty status message after setting it through a service, in some specific cases + +v0.3.7.5 (build 2346; May 8, 2006) +--------- + - fixed crash on startup on some systems + +v0.3.7.4 (build 2344; May 5, 2006) +--------- + - fix due to database API change in nightly build #53 that made NAS reset its message tree to the defaults + +v0.3.7.3 (build 2341; May 4, 2006) +--------- + - fix for a wrong message in some cases, when using NAS' services + - some other minor fixes + +v0.3.7.2 (build 2338; April 30, 2006) +--------- + - various improvements and fixes to the NAS services (finally managed to get SS and NAS working together ok (hopefully); thanks to Unregistered) + - improved compatibility with plugins that don't support NAS (implemented a method to detect status changes by such plugins) + - disabled autoreply on protocols that don't support outgoing messages + - fixed a bug with usual status in popups on extended status message request when logging is disabled + - fixed some other bugs + +v0.3.7.1 (build 2311; April 22, 2006) +--------- + - fix for contact menu items in unicode build (only the first letter was displayed) + - some other minor changes + +v0.3.7.0 (build 2305; April 21, 2006) +--------- + - unicode support + - some fixes to the NAS services for compatibility with StartupStatus and AdvancedAutoAway plugins + - fixed an unnecessary 0x13 character at the end of the popup header + +v0.3.6.9 (build 2264; March 15, 2006) +-------- + - now it's possible to get default messages for any status mode using NAS services + +v0.3.6.8 (build 2262; March 13, 2006) +-------- + - %nas_requestcount% and %nas_messagecount% fix + - status message is automatically selected now when the status selection window opens + - now NAS doesn't add status message to an autoreply automatically. use %extratext% variable in the Autoreply format for that + +v0.3.6.7 (build 2257; February 12, 2006) +-------- + - some minor changes to improve MyDetails plugin support + +v0.3.6.6 (build 2256; November 2, 2005) +-------- + - status message change dialog didn't ever pop up for Online and Invisible modes, regardless of settings. fixed. + +v0.3.6.5 (build 2253; October 30, 2005) +-------- + - updated all the links (also for Updater plugin) to point to deathdemon.int.ru + +v0.3.6.4 (build 2250; October 16, 2005) +-------- + - now NAS shares contact status messages with other plugins when requesting them through contact's menu. + - improved accuracy of status message updates + - Read status message window is resizeable now + - Updater plugin support + - implemented MS_NAS_INVOKESTATUSWINDOW service + +v0.3.6.3 (build 2216; September 14, 2005) +-------- + - correct ICQ XStatus logging and popup notification. + - fixed a bug with status message refresh on startup when setting status through StartupStatus. + +v0.3.6.3 (build 2210; September 12, 2005) +-------- + - added a possibility to use %nas_message% variable in the autoreply format, to specify where exactly NAS should place usual status message. + - added "Log requests only if popup notification for a contact is enabled" checkbox in the Log tab + - some strings were untranslatable. fixed. + +v0.3.6.3 (build 2200; September 11, 2005) +-------- + - workaround for contact list's CLGN_NEXT bug. + +v0.3.6.3 (build 2193; September 10, 2005) +-------- + - now NAS will open the status message change window much faster when "Show contacts" is disabled + - optimized tabs in the options - now NAS' options will load faster + - previous NAS build didn't load on systems with an old msvcrt.dll version. fixed. (thanks to scHacklaban) + +v0.3.6.3 (build 2186; September 8, 2005) +-------- + - fixed a crash on status change when there are no groups in a contact list (thanks to Ladiko) + - added "Contacts" options tab - it allows to set per-contact settings, and also there is a new setting - per-contact popup notification + - added %nas_protocol% variable that returns current protocol name + - fixed a bug with message tree scrolling when per-status recent messages are enabled + - NAS stored per-protocol recent messages in wrong categories with per-status recent messages enabled + - some other minor bugfixes + +v0.3.6.2 (build 2136; August 28, 2005) +-------- + - fixed a bug with wrong status messages that was introduced in the previous build + - implemented services that will allow other plugins to get/set status messages in a way compatible with NAS + +v0.3.6.2 (build 2129; August 27, 2005) +-------- + - added support for StartupStatus and AdvancedAutoAway, and also hopefully for some other plugins that change status + - added nas_predefinedmessage variable + - some minor bugfixes + +v0.3.6.2 (build 2110; August 26, 2005) +-------- +bugfixes: + - hopefully fixed problems with autoreply + - previous builds set an empty message on statuses for which "don't show status message dialog.." was enabled + +v0.3.6.2 (build 2108; August 26, 2005) +-------- + - multiple ICQ accounts support + - optional updating of your status messages on non-ICQ protocols + - now NAS works pretty well even without Variables plugin + - some bugfixes + - added translation.txt + +v0.3.6.1 (build 2083; August 25, 2005) +-------- +Added a lot of new features: + - categorized predefined status messages + - separate default messages for different statuses + - (bugfix) NAS stores status messages separately for different protocols now. for example, if you'll change your MSN status message, your ICQ message won't be overwritten now. + - many improvements in user interface + - some bugfixes + +v0.3.6.0 (build 733; August 13, 2005) +-------- + - Just a quick fix of an old build to stop notification of custom status message requests (newer builds are still very unstable). + +v0.3.6.0 (build 732; May 16, 2005) +-------- + - First public release. \ No newline at end of file diff --git a/plugins/!Deprecated/NewAwaySysMod/nas_translation.txt b/plugins/!Deprecated/NewAwaySysMod/nas_translation.txt new file mode 100644 index 0000000000..9d7053a732 --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/nas_translation.txt @@ -0,0 +1,238 @@ +Miranda Language Pack Version 1 +Locale: 0809 +Authors: Deathdemon; XF007; Goblineye Entertainment +Author-email: dchervov@yahoo.com +Last-Modified-Using: Miranda IM 0.7svn +Plugins-included: NewAwaySys +; Generated by lpgen on Sat Oct 13 14:56:33 2007 +; Translations: 210 + +; Common strings that belong to many files +;[ message:\r\n] +;[** All contacts **] +;[Autoreply] +;[Create new category] +;[Delete] +;[Don't send status message] +;[Enable autoreply] +;[New Away System] +;[New category] +;[New message] +;[OK] +;[Open Variables help dialog] +;[PopUps] +;[Toggle autoreply on/off] + +; C:/VSProjects/Miranda/plugins/NewAwaySys/AwayOpt.cpp +;[** Not-on-list contacts **] +;[Away] +;[Been gone since %nas_awaysince_time%, will be back later.] +;[Been having ?ifgreater(?ctime(H),2,?ifgreater(?ctime(H),10,?ifgreater(?ctime(H),16,supper,dinner),breakfast),supper) since %nas_awaysince_time%.] +;[Close popup] +;[Contacts] +;[Create new message] +;[Creepy] +;[DND] +;[Default messages] +;[Do nothing] +;[Edit status messages] +;[File] +;[Free for chat] +;[Give a guy some peace, would ya?] +;[Give it up, I'm not in!] +;[Gone fragging] +;[I'm a chatbot!] +;[I'm hiding from the mafia.] +;[I've been on the phone since %nas_awaysince_time%, give me a sec!] +;[Invisible] +;[Main options] +;[Message] +;[Miranda] +;[NA] +;[Not right now.] +;[Occupied] +;[On the phone] +;[Online] +;[Open contact details window] +;[Open contact history] +;[Open contact menu] +;[Open log file] +;[Open message window] +;[Other (XStatus)] +;[Out to lunch] +;[Predefined messages] +;[Recent messages] +;[URL] +;[When this checkbox is ticked, NewAwaySys counts \"send times\" starting from the last status message change, even if status mode didn't change.\nWhen the checkbox isn't ticked, \"send times\" are counted from last status mode change (i.e. disabled state is more restrictive).] +;[Windows] +;[Yep, I'm here.] +;[You can put your frequently used and favorite messages in this category.] +;[Your master, %nas_mynick%, has been %nas_statdesc% since the day that is only known as ?nas_awaysince_date(dddd)... When he gets back, I'll tell him you dropped by...] +;[Your most recent status messages are placed in this category. It's not recommended to put your messages manually here, as they'll be replaced by your recent messages.] + +; C:/VSProjects/Miranda/plugins/NewAwaySys/AwaySys.cpp +;[%d hours] +;[%d minutes] +;[%d seconds] +;[) read your ] +;[Don't send status message when you are %s] +;[Enable autoreply when you are %s] +;[Ignore status message requests from this contact and don't send an autoreply] +;[Ignore status message requests from this contact and don't send an autoreply.\r\n\"Store contact autoreply/ignore settings for each status separately\" is enabled, so this setting is per-contact AND per-status.] +;[New Away System plugin requires Miranda version 0.6.0.0 or above.] +;[New Away System: Status message request notifications] +;[New Away System\t(x)\tAway since date in format x (x is optional)] +;[New Away System\t(x)\tAway since time in format x (x is optional)] +;[New Away System\t(x)\tReturns one of your predefined messages by its title: ?nas_predefinedmessage(creepy)] +;[New Away System\tCurrent protocol name] +;[New Away System\tNumber of messages from the contact] +;[New Away System\tNumber of status message requests from the contact] +;[New Away System\tStatus description] +;[New Away System\tTime passed until request] +;[New Away System\tYour nick for current protocol] +;[NewAwaySys: Incoming status message request] +;[Off] +;[On] +;[Re&ad %s Message] +;[Read status message] +;[Set %s message for the contact] +;[Set status message] +;[Stranger] +;[Use the default setting] +;[\"Store contact autoreply/ignore settings for each status separately\" is enabled, so this setting is per-contact AND per-status.] + +; C:/VSProjects/Miranda/plugins/NewAwaySys/Common.h +;[?cinfo(%subject%,display) (?cinfo(%subject%,id)) is reading your %nas_statdesc% message:\r\n%extratext%] +;[Away System] +;[Miranda IM autoreply >\r\n%extratext%] +;[Status] +;[Toggle autoreply off] +;[Toggle autoreply on] +;[Variables plugin is not installed] +;[extended status] + +; C:/VSProjects/Miranda/plugins/NewAwaySys/MsgTree.cpp +;[Do you really want to delete this ] +;[You've made changes to multiple Message trees at a time.\r\nDo you want to leave changes in \"] +;[\" dialog?\r\nPress Yes to leave changes in this dialog, or No to discard its changes and save changes of the other Message tree instead.] +;[category with its messages?] +;[message?] + +; C:/VSProjects/Miranda/plugins/NewAwaySys/Notification.cpp +;[) is reading your ] +;[Can't open log file ] +;[Error #%d] + +; C:/VSProjects/Miranda/plugins/NewAwaySys/ReadAwayMsg.cpp +;[&Close] + +; C:/VSProjects/Miranda/plugins/NewAwaySys/Resources.rc +;[%extratext% is your status message] +;[%s Message for %s] +;[&Away] +;[&Cancel] +;[&DND] +;[&Delete] +;[&Free for chat] +;[&Invisible] +;[&NA] +;[&Other] +;[&Rename] +;[&Save] +;[&Save current window settings as default] +;[&Variables] +;[-1 = Infinite] +;[...for each status separately] +;[0 = Default] +;[Autoreply format:] +;[Autoreply off] +;[Autoreply on] +;[Background] +;[By default...] +;[Click action] +;[Colours] +;[Create new &category] +;[Create new &message] +;[Delay] +;[Disable autoreply when...] +;[Disable parsing of status messages by Variables plugin] +;[Don't notify of requests] +;[Don't reply to ICQ contacts] +;[Don't reply when I'm invisible to the contact] +;[Don't show the message dialog for] +;[Enable contact menu items] +;[Ignore requests] +;[Log to a file only when popup notification for a contact is enabled] +;[Means the setting is different for different status modes / contacts] +;[Message tree category menu] +;[Message tree menu] +;[New &Category] +;[Note: these settings are applied to all status modes at once.] +;[Notify of requests] +;[Occ&upied] +;[On event...] +;[On left click] +;[On right click] +;[On the &Phone] +;[On&line] +;[Only notify when:] +;[Out to &Lunch] +;[Popup notification] +;[Popup text format] +;[Preview] +;[Remember last message used for a contact...] +;[Reply only when Idle] +;[Reply only when contact's message window is closed] +;[Reset per-protocol messages when changing global status] +;[Reset this counter also when I just change my status text\n(when status icon remains the same)] +;[Retrieving %s message...] +;[Save As &New] +;[Save autoreply to the history] +;[Save default window settings &automatically] +;[Se&ttings] +;[Sec] +;[Send an autoreply] +;[Send maximum] +;[Set as &default for] +;[Set away message window options] +;[Show &contacts] +;[Show predefined &messages] +;[Store] +;[Store contact autoreply/ignore settings for each status separately] +;[Store protocol autoreply settings for each status separately] +;[Store protocol messages for each status separately] +;[Text] +;[Title:] +;[Update status messages for non-ICQ protocols every] +;[Use default] +;[Use protocol specific nick for %nas_mynick%] +;[Use the default message] +;[Use the most recent message] +;[Use this message as default for] +;[V] +;[Wait] +;[most recent messages (0=disable)] +;[seconds] +;[seconds before closing the status message dialog (-1=don't close)] +;[times (-1=infinite)] + +; C:/VSProjects/Miranda/plugins/NewAwaySys/SetAwayMsg.cpp +;[ (autoreply only)] +;[ contacts *] +;[ for ] +;[ message] +;[ protocol] +;[Apply] +;[Closing in %d] +;[Do you want to apply the message?] +;[Don't send the status message to selected contact(s)] +;[Save as a new message] +;[Save, replacing the selected message] +;[Send an autoreply to selected contact(s)] +;[Set ] +;[Show settings menu] +;[all contacts] +;[status] + +; C:/VSProjects/Miranda/plugins/NewAwaySys/m_variables.h +;[Open String Formatting Help] diff --git a/plugins/!Deprecated/NewAwaySysMod/newawaysysmod-translation.txt b/plugins/!Deprecated/NewAwaySysMod/newawaysysmod-translation.txt new file mode 100644 index 0000000000..b89a9f4867 --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/newawaysysmod-translation.txt @@ -0,0 +1,226 @@ +; Common strings that belong to many files +;[ message:\r\n] +;[** All contacts **] +;[Autoreply] +;[Create new category] +;[Delete] +;[Don't send status message] +;[Enable autoreply] +;[New Away System] +;[New category] +;[New message] +;[OK] +;[Open Variables help dialog] +;[Toggle autoreply on/off] + +; ../../plugins/NewAwaySysMod/AwayOpt.cpp +;[** Not-on-list contacts **] +;[Away] +;[Been gone since %nas_awaysince_time%, will be back later.] +;[Been having ?ifgreater(?ctime(H),2,?ifgreater(?ctime(H),10,?ifgreater(?ctime(H),16,supper,dinner),breakfast),supper) since %nas_awaysince_time%.] +;[Contacts] +;[Create new message] +;[Creepy] +;[DND] +;[Default messages] +;[File] +;[Free for chat] +;[Give a guy some peace, would ya?] +;[Give it up, I'm not in!] +;[Gone fragging] +;[I'm a chatbot!] +;[I'm hiding from the mafia.] +;[I've been on the phone since %nas_awaysince_time%, give me a sec!] +;[Invisible] +;[Main options] +;[Message] +;[Miranda] +;[NA] +;[Not right now.] +;[Occupied] +;[On the phone] +;[Online] +;[Out to lunch] +;[Predefined messages] +;[Recent messages] +;[Statuses messages] +;[URL] +;[When this checkbox is ticked, NewAwaySys counts \"send times\" starting from the last status message change, even if status mode didn't change.\nWhen the checkbox isn't ticked, \"send times\" are counted from last status mode change (i.e. disabled state is more restrictive).] +;[Windows] +;[Yep, I'm here.] +;[You can put your frequently used and favorite messages in this category.] +;[Your master, %nas_mynick%, has been %nas_statdesc% since the day that is only known as ?nas_awaysince_date(dddd)... When he gets back, I'll tell him you dropped by...] +;[Your most recent status messages are placed in this category. It's not recommended to put your messages manually here, as they'll be replaced by your recent messages.] + +; ../../plugins/NewAwaySysMod/AwaySys.cpp +;[%d hours] +;[%d minutes] +;[%d seconds] +;[) read your ] +;[Don't send status message when you are %s] +;[Enable autoreply when you are %s] +;[Ignore status message requests from this contact and don't send an autoreply] +;[Ignore status message requests from this contact and don't send an autoreply.\r\n\"Store contact autoreply/ignore settings for each status separately\" is enabled, so this setting is per-contact AND per-status.] +;[New Away System: Status message request notifications] +;[New Away System\t(x)\tAway since date in default format; ?nas_awaysince_date(x) in format x] +;[New Away System\t(x)\tAway since time in default format; ?nas_awaysince_time(x) in format x] +;[New Away System\t(x)\tReturns one of your predefined messages by its title: ?nas_predefinedmessage(creepy)] +;[New Away System\tCurrent protocol name] +;[New Away System\tNumber of messages from the contact] +;[New Away System\tNumber of status message requests from the contact] +;[New Away System\tStatus description] +;[New Away System\tTime passed until request] +;[New Away System\tYour nick for current protocol] +;[NewAwaySys: Incoming status message request] +;[Off] +;[On] +;[Re&ad %s Message] +;[Read status message] +;[Set %s message for the contact] +;[Set status message] +;[Stranger] +;[Use the default setting] +;[\"Store contact autoreply/ignore settings for each status separately\" is enabled, so this setting is per-contact AND per-status.] + +; ../../plugins/NewAwaySysMod/Common.h +;[?cinfo(%subject%,display) (?cinfo(%subject%,id)) is reading your %nas_statdesc% message:\r\n%extratext%] +;[Away System] +;[Miranda IM autoreply >\r\n%extratext%] +;[PopUps] +;[Status] +;[Toggle autoreply off] +;[Toggle autoreply on] +;[Variables plugin is not installed] +;[extended status] + +; ../../plugins/NewAwaySysMod/MsgTree.cpp +;[Do you really want to delete this ] +;[Do you really want to delete this category with its messages?] +;[Do you really want to delete this message?] +;[You've made changes to multiple Message trees at a time.\r\nDo you want to leave changes in \"] +;[\" dialog?\r\nPress Yes to leave changes in this dialog, or No to discard its changes and save changes of the other Message tree instead.] +;[category with its messages?] +;[message?] + +; ../../plugins/NewAwaySysMod/NewAwaySys.rc +;[%extratext% is your status message] +;[%s Message for %s] +;[&Away] +;[&Cancel] +;[&DND] +;[&Delete] +;[&Free for chat] +;[&Invisible] +;[&NA] +;[&Other] +;[&Rename] +;[&Save] +;[&Save current window settings as default] +;[&Variables] +;[-1 = Infinite] +;[0 = Default] +;[Autoreply format:] +;[Autoreply off] +;[Autoreply on] +;[Background] +;[Click action] +;[Colours] +;[Configure autoaway] +;[Create new &category] +;[Create new &message] +;[Delay] +;[Disable autoreply when...] +;[Disable parsing of status messages by Variables plugin] +;[Don't notify of requests] +;[Don't reply to ICQ contacts] +;[Don't reply when I'm invisible to the contact] +;[Don't show the message dialog for] +;[Enable contact menu items] +;[Ignore requests] +;[Log to a file only when popup notification for a contact is enabled] +;[Means the setting is different for different status modes / contacts] +;[Message tree category menu] +;[Message tree menu] +;[New &Category] +;[Note: these settings are applied to all status modes at once.] +;[Notify of requests] +;[Occ&upied] +;[On event...] +;[On left click] +;[On right click] +;[On the &Phone] +;[On&line] +;[Only notify when:] +;[Out to &Lunch] +;[Popup notification] +;[Popup text format] +;[Preview] +;[Remember last message used for a contact...] +;[Reply only when Idle] +;[Reply only when contact's message window is closed] +;[Reset per-protocol messages when changing global status] +;[Reset this counter also when I just change my status text\n(when status icon remains the same)] +;[Retrieving %s message...] +;[Save As &New] +;[Save autoreply to the history] +;[Save default window settings &automatically] +;[Se&ttings] +;[Sec] +;[Send an autoreply] +;[Send maximum] +;[Set as &default for] +;[Set away message window options] +;[Show &contacts] +;[Show predefined &messages] +;[Statuses messages:] +;[Store] +;[Store contact autoreply/ignore settings for each status separately] +;[Store for each status separately] +;[Store protocol autoreply settings for each status separately] +;[Store protocol messages for each status separately] +;[Text] +;[Title:] +;[Update status messages for non-ICQ protocols every] +;[Use default] +;[Use default...] +;[Use protocol specific nick for %nas_mynick%] +;[Use the default message] +;[Use the most recent message] +;[Use this message as default for] +;[V] +;[Wait] +;[most recent messages (0=disable)] +;[seconds] +;[seconds before closing the status message dialog (-1=don't close)] +;[times (-1=infinite)] + +; ../../plugins/NewAwaySysMod/Notification.cpp +;[) is reading your ] +;[Can't open log file ] +;[Error #%d] + +; ../../plugins/NewAwaySysMod/ReadAwayMsg.cpp +;[&Close] + +; ../../plugins/NewAwaySysMod/SetAwayMsg.cpp +;[ (autoreply only)] +;[ contacts *] +;[ message] +;[ protocol] +;[Apply] +;[Closing in %d] +;[Do you want to apply the message?] +;[Don't send the status message to selected contact(s)] +;[Save as a new message] +;[Save, replacing the selected message] +;[Send an autoreply to selected contact(s)] +;[Set ] +;[Set message for] +;[Show settings menu] +;[Statuses] +;[account] +;[all accounts] +;[all contacts] +;[available autoreply only] +;[for] +;[message for] diff --git a/plugins/!Deprecated/NewAwaySysMod/resource.h b/plugins/!Deprecated/NewAwaySysMod/resource.h new file mode 100644 index 0000000000..1c6190554b --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/resource.h @@ -0,0 +1,261 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by NewAwaySys.rc +// +#define IDD_OPTDIALOGMAIN 101 +#define IDD_MESSAGES 101 +#define IDD_MODERNOPT_MESSAGES 102 +#define IDI_MSGICON 109 +#define IDI_SOE_ENABLED 110 +#define IDD_READAWAYMSG 111 +#define IDI_SOE_DISABLED 111 +#define IDB_SOE_ENABLED 112 +#define IDB_SOE_DISABLED 114 +#define IDD_NOTIFYOPTDLG 115 +#define IDD_NOTIFYVARSDLG 116 +#define IDD_AUTOREPLY 121 +#define IDR_SAM_OPTIONS 122 +#define IDI_DOT 123 +#define IDI_IGNORE 124 +#define IDI_SAVEMSG 127 +#define IDI_SAVE 127 +#define IDI_SAVEASNEW 128 +#define IDI_DELETE 130 +#define IDI_NEWCATEGORY 133 +#define IDR_MSGTREE_CATEGORYMENU 134 +#define IDR_MSGTREE_MESSAGEMENU 135 +#define IDI_NEWMESSAGE 136 +#define IDI_SETTINGS 137 +#define IDI_STATUS_OTHER 138 +#define IDD_CONTACTSOPTDLG 139 +#define IDI_DISABLENOTIFY 140 +#define IDI_ENABLENOTIFY 141 +#define IDI_INDEFINITE 142 +#define IDD_SETAWAYMSG_BAK 144 +#define IDD_SETAWAYMSG 216 +#define IDD_MOREOPTDIALOG 217 +#define IDD_POPUPOPTDLG 218 +#define IDC_STATUSBAR 999 +#define IDC_SAWAYMSG_MSGNAME 1001 +#define IDC_MESSAGEDLG_DEL 1002 +#define IDC_OPTDLG_MSGDATA 1003 +#define IDC_MESSAGEDLG_MSGDATA 1003 +#define IDC_OPTDLG_MSGNAME 1004 +#define IDC_OPTDLG_MAKEDEFAULT 1005 +#define IDC_OPTDLG_USELASTMSG 1007 +#define IDC_MOREOPTDLG_USELASTMSG 1007 +#define IDC_OPTDLG_USEDEFAULT 1008 +#define IDC_SAWAYMSG_MSGDATA 1008 +#define IDC_MOREOPTDLG_USEDEFMSG 1008 +#define IDC_OPTDLG_SAVE 1010 +#define IDC_LNK_AUTOAWAY 1010 +#define IDC_OPTDLG_RESET 1012 +#define IDC_OPTDLG_VARSLIST 1013 +#define IDC_MESSAGEDLG_VARS 1013 +#define IDC_SAWAYMSG_STATIC_CHARSTXT 1014 +#define IDC_STATIC_BYDEFAULT 1017 +#define IDC_STATIC_MSG 1021 +#define IDC_MOREOPTDLG_NEVERSTATDLG 1028 +#define IDC_MOREOPTDLG_WAITFORMSG 1029 +#define IDC_STATIC_MOREOPTDLG_WAIT 1030 +#define IDC_STATIC_MOREOPTDLG_SECONDSREMAIN 1031 +#define IDC_MOREOPTDLG_LMESTAT 1032 +#define IDC_MOREOPTDLG_PERSTATUSMRM 1032 +#define IDC_MOREOPTDLG_RMDLGPOS 1033 +#define IDC_MOREOPTDLG_SAVEDLGPOS 1033 +#define IDC_MOREOPTDLG_SETLASTCONTCAT 1034 +#define IDC_MOREOPTDLG_SAVECONTACTMSGS 1034 +#define IDC_MOREOPTDLG_SAVEPERSONALMSGS 1034 +#define IDC_MOREOPTDLG_USEMENUITEM 1035 +#define IDC_MOREOPTDLG_PERSTATUSPERSONAL 1036 +#define IDC_MOREOPTDLG_RESETPROTOMSGS 1037 +#define IDC_MOREOPTDLG_PERSTATUSPROTOMSGS 1038 +#define IDC_MOREOPTDLG_PERSTATUSPROTOSETTINGS 1039 +#define IDC_SAWAYMSG_CONTACTSTREE 1040 +#define IDC_MOREOPTDLG_PERSTATUSPERSONALSETTINGS 1040 +#define IDC_SAWAYMSG_STATIC_VARS 1041 +#define IDC_SAWAYMSG_SHOWCONTACTS 1042 +#define IDC_SAWAYMSG_STATIC_RESETCHNG 1043 +#define IDC_SAWAYMSG_OPTIONS 1043 +#define IDC_MOREOPTDLG_SENDNONICQ 1049 +#define IDC_REPLYDLG_DONTSENDTOICQ 1049 +#define IDC_MOREOPTDLG_EVNTMSG 1050 +#define IDC_REPLYDLG_EVENTMSG 1050 +#define IDC_MOREOPTDLG_EVNTURL 1051 +#define IDC_REPLYDLG_EVENTURL 1051 +#define IDC_MOREOPTDLG_EVNTFILE 1052 +#define IDC_REPLYDLG_EVENTFILE 1052 +#define IDC_MOREOPTDLG_SENDONCE 1053 +#define IDC_SAWAYMSG_SENDMSG 1054 +#define IDC_MOREOPTDLG_SENDALL 1054 +#define IDC_SAWAYMSG_IGNOREREQ 1055 +#define IDC_MOREOPTDLG_STATIC_SEND 1057 +#define IDC_REPLYDLG_STATIC_SEND 1057 +#define IDC_MOREOPTDLG_STATIC_ONEVENT 1058 +#define IDC_REPLYDLG_STATIC_ONEVENT 1058 +#define IDC_VARSLIST_STATIC_TIME 1061 +#define IDC_MOREOPTDLG_NOPOPLIST 1062 +#define IDC_MOREOPTDLG_NOPOP 1063 +#define IDC_MOREOPTDLG_NOSSMLIST 1064 +#define IDC_MOREOPTDLG_NOSSM 1065 +#define IDC_OPTDLG_PREFIX 1065 +#define IDC_REPLYDLG_PREFIX 1065 +#define IDC_MOREOPTDLG_LOGMSG 1066 +#define IDC_REPLYDLG_LOGREPLY 1066 +#define IDC_OPTDLG_USEDEFNICK 1068 +#define IDC_MOREOPTDLG_MYNICKPERPROTO 1068 +#define IDC_MOREOPTDLG_SHOWRMSG 1069 +#define IDC_MOREOPTDLG_SENDMSG 1070 +#define IDC_REPLYDLG_ENABLEREPLY 1070 +#define IDC_POPUPOPTDLG_POPUPFORMAT 1071 +#define IDC_POPUPOPTDLG_USEPOPUPS 1072 +#define IDC_POPUPOPTDLG_BGCOLOUR 1073 +#define IDC_POPUPOPTDLG_TEXTCOLOUR 1074 +#define IDC_POPUPOPTDLG_LCLICK_ACTION 1075 +#define IDC_POPUPOPTDLG_RCLICK_ACTION 1077 +#define IDC_POPUPOPTDLG_POPUPPREVIEW 1078 +#define IDC_POPUPOPTDLG_AWAYNOTIFY 1084 +#define IDC_POPUPOPTDLG_NANOTIFY 1085 +#define IDC_POPUPOPTDLG_OCCNOTIFY 1086 +#define IDC_POPUPOPTDLG_DNDNOTIFY 1087 +#define IDC_POPUPOPTDLG_FFCNOTIFY 1088 +#define IDC_POPUPOPTDLG_DEFBGCOLOUR 1089 +#define IDC_POPUPOPTDLG_DEFTEXTCOLOUR 1090 +#define IDC_NOTIFYVARS_STATIC_TIME 1091 +#define IDC_VARS_STATIC_TIME 1091 +#define IDC_POPUPOPTDLG_OTHERNOTIFY 1091 +#define IDC_POPUPOPTDLG_STATIC_LCLICK 1092 +#define IDC_POPUPOPTDLG_STATIC_RCLICK 1093 +#define IDC_POPUPOPTDLG_STATIC_BGCOLOUR 1094 +#define IDC_POPUPOPTDLG_STATIC_TEXTCOLOUR 1095 +#define IDC_POPUPOPTDLG_ONLNOTIFY 1096 +#define IDC_POPUPOPTDLG_POPUPDELAY 1099 +#define IDC_POPUPOPTDLG_STATIC_SEC 1100 +#define IDC_POPUPOPTDLG_STATIC_DEFAULT 1101 +#define IDC_POPUPOPTDLG_STATIC_INFINITE 1102 +#define IDC_MESSAGEDLG_DEF_AWAY 1109 +#define IDC_SAWAYMSG_SAVEMSG 1109 +#define IDC_REPLYDLG_ONLYIDLEREPLY 1109 +#define IDC_POPUPOPTDLG_VARS 1110 +#define IDC_REPLYDLG_DISABLE_AWAY 1110 +#define IDC_SAWAYMSG_SAVEASNEW 1110 +#define IDC_MOREOPTDLG_PANEL 1111 +#define IDC_SAWAYMSG_NEWCATEGORY 1111 +#define IDC_SAWAYMSG_DELETE 1112 +#define IDC_MESSAGEDLG_DEF_ONL 1113 +#define IDC_MESSAGEDLG_DEF_NA 1114 +#define IDC_MESSAGEDLG_DEF_OCC 1115 +#define IDC_MESSAGEDLG_DEF_DND 1116 +#define IDC_MESSAGEDLG_DEF_FFC 1117 +#define IDC_MESSAGEDLG_DEF_OTP 1118 +#define IDC_MESSAGEDLG_DEF_OTL 1119 +#define IDC_MESSAGEDLG_MSGTITLE 1120 +#define IDC_MOREOPTDLG_DONTPOPDLG_INV 1120 +#define IDC_MESSAGEDLG_MSGTREE 1121 +#define IDC_REPLYDLG_DISABLE_ONL 1121 +#define IDC_MESSAGEDLG_NEWCAT 1122 +#define IDC_REPLYDLG_DISABLE_NA 1122 +#define IDC_MESSAGEDLG_NEWMSG 1123 +#define IDC_REPLYDLG_DISABLE_OCC 1123 +#define IDC_REPLYDLG_DISABLE_DND 1124 +#define IDC_REPLYDLG_DISABLE_FFC 1125 +#define IDC_REPLYDLG_DISABLE_OTP 1126 +#define IDC_REPLYDLG_DISABLE_OTL 1127 +#define IDC_REPLYDLG_DISABLE_INV 1128 +#define IDC_MOREOPTDLG_RECENTMSGSCOUNT 1129 +#define IDC_MOREOPTDLG_UPDATEMSGSPERIOD 1130 +#define IDC_MESSAGEDLG_DEF_INV 1131 +#define IDC_REPLYDLG_SENDCOUNT 1132 +#define IDC_MOREOPTDLG_DONTPOPDLG_ONL 1133 +#define IDC_MOREOPTDLG_DONTPOPDLG_AWAY 1134 +#define IDC_MOREOPTDLG_DONTPOPDLG_NA 1135 +#define IDC_MOREOPTDLG_DONTPOPDLG_OCC 1136 +#define IDC_MOREOPTDLG_DONTPOPDLG_DND 1137 +#define IDC_MOREOPTDLG_DONTPOPDLG_FFC 1138 +#define IDC_MOREOPTDLG_DONTPOPDLG_OTP 1139 +#define IDC_MOREOPTDLG_DONTPOPDLG_OTL 1140 +#define IDC_REPLYDLG_STATIC_TIMES 1141 +#define IDC_MESSAGEDLG_TEST 1142 +#define IDC_MOREOPTDLG_EDITMESSAGES 1142 +#define IDC_SAWAYMSG_VARS 1142 +#define IDC_SAWAYMSG_TREE 1149 +#define IDC_SAWAYMSG_EDITMSGS 1150 +#define IDC_SAWAYMSG_RESET 1151 +#define IDC_OK 1152 +#define IDC_MSGSPLITTER 1154 +#define IDC_SAWAYMSG_MSGSPLITTER 1154 +#define IDC_CONTACTSPLITTER 1155 +#define IDC_SAWAYMSG_CONTACTSPLITTER 1155 +#define IDC_SAWAYMSG_STATIC_IGNOREICON 1157 +#define IDC_SAWAYMSG_STATIC_REPLYICON 1158 +#define IDC_MOREOPTDLG_WAITFORMSG_SPIN 1161 +#define IDC_MOREOPTDLG_RECENTMSGSCOUNT_SPIN 1162 +#define IDC_REPLYDLG_SENDCOUNT_SPIN 1163 +#define IDC_MOREOPTDLG_UPDATEMSGSPERIOD_SPIN 1163 +#define IDC_POPUPOPTDLG_POPUPDELAY_SPIN 1164 +#define IDC_REPLYDLG_VARS 1165 +#define IDC_MOREOPTDLG_UPDATEMSGS 1166 +#define IDC_CONTACTSDLG_LIST 1168 +#define IDC_REPLYDLG_DONTREPLYINVISIBLE 1169 +#define IDC_REPLYDLG_ONLYIDLEREPLY_COMBO 1170 +#define IDC_REPLYDLG_ONLYCLOSEDDLGREPLY 1171 +#define IDC_REPLYDLG_RESETCOUNTERWHENSAMEICON 1172 +#define IDC_REPLYDLG_STATIC_DISABLEWHENSTATUS 1174 +#define IDC_REPLYDLG_STATIC_FORMAT 1175 +#define IDC_POPUPOPTDLG_GROUP_NOTIFICATION 1176 +#define IDC_POPUPOPTDLG_LOGONLYWITHPOPUP 1177 +#define IDC_POPUPOPTDLG_STATIC_EXTRATEXT 1178 +#define IDC_REPLYDLG_STATIC_EXTRATEXT 1179 +#define IDC_TXT_TITLE1 1181 +#define IDC_TXT_TITLE2 1182 +#define IDC_TXT_TITLE3 1183 +#define IDC_SAWAYMSG_STATIC_COUNTER 1202 +#define IDC_READAWAYMSG_RETRIEVE 3453 +#define IDS_MESSAGEDLG_DEF_ONL 20000 +#define IDS_MESSAGEDLG_DEF_AWAY 20001 +#define IDS_MESSAGEDLG_DEF_NA 20002 +#define IDS_MESSAGEDLG_DEF_OCC 20003 +#define IDS_MESSAGEDLG_DEF_DND 20004 +#define IDS_MESSAGEDLG_DEF_FFC 20005 +#define IDS_MESSAGEDLG_DEF_INV 20006 +#define IDS_MESSAGEDLG_DEF_OTP 20007 +#define IDS_MESSAGEDLG_DEF_OTL 20008 +#define IDV_MSGTREE 20009 +#define IDS_SAWAYMSG_SHOWMSGTREE 20100 +#define IDS_SAWAYMSG_SHOWCONTACTTREE 20101 +#define IDS_SAWAYMSG_AUTOSAVEDLGSETTINGS 20102 +#define IDS_SAWAYMSG_DISABLEVARIABLES 20103 +#define IDM_SAM_OPTIONS_SHOWMSGTREE 40007 +#define IDM_SAM_OPTIONS_SHOWCONTACTTREE 40008 +#define IDM_SAM_OPTIONS_EDITMSGS 40009 +#define IDM_SAM_OPTIONS_AUTOSAVEDLGSETTINGS 40014 +#define IDM_SAM_OPTIONS_SAVEDLGSETTINGSNOW 40015 +#define IDM_MSGTREEMENU_RENAME 40017 +#define IDM_MSGTREEMENU_NEWMESSAGE 40022 +#define IDM_MSGTREEMENU_NEWCATEGORY 40024 +#define IDM_MSGTREEMENU_DELETE 40026 +#define ID_MESSAGETREECATEGORYMENU_SETASDEFAULTFOR 40027 +#define IDR_MSGTREEMENU_DEF_ONL 40037 +#define IDR_MSGTREEMENU_DEF_AWAY 40038 +#define IDR_MSGTREEMENU_DEF_NA 40039 +#define IDR_MSGTREEMENU_DEF_OCC 40040 +#define IDR_MSGTREEMENU_DEF_DND 40041 +#define IDR_MSGTREEMENU_DEF_FFC 40042 +#define IDR_MSGTREEMENU_DEF_INV 40043 +#define IDR_MSGTREEMENU_DEF_OTP 40044 +#define IDR_MSGTREEMENU_DEF_OTL 40045 +#define IDM_SAM_OPTIONS_DISABLEVARIABLES 40047 +#define IDC_READAWAYMSG_MSG 54765 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 145 +#define _APS_NEXT_COMMAND_VALUE 40048 +#define _APS_NEXT_CONTROL_VALUE 1185 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/!Deprecated/NewAwaySysMod/version.rc b/plugins/!Deprecated/NewAwaySysMod/version.rc new file mode 100644 index 0000000000..71fc8d12c6 --- /dev/null +++ b/plugins/!Deprecated/NewAwaySysMod/version.rc @@ -0,0 +1,58 @@ +// +// version.rc - resources Microsoft Visual C++ does not edit directly +// +#ifdef APSTUDIO_INVOKED +#error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// Add manually edited resources here... + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// +#include "VersionNo.h" +VS_VERSION_INFO VERSIONINFO + FILEVERSION FILEVER + PRODUCTVERSION PRODUCTVER + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x21L +#else + FILEFLAGS 0x20L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "NightFox; Deathdemon; XF007; Goblineye Entertainment" + VALUE "FileDescription", "New Away System plugin for Miranda IM" + VALUE "FileVersion", STRFILEVER + VALUE "LegalCopyright", "© 2010 NightFox; © 2005-2006 Chervov Dmitry; © 2004-2005 Iksaif Entertainment; © 2002-2003 Goblineye Entertainment" +#ifdef _UNICODE + VALUE "InternalName", "NewAwaySysW" + VALUE "OriginalFilename", "NewAwaySysW.dll" + VALUE "ProductName", "New Away System (Unicode)" +#else + VALUE "InternalName", "NewAwaySys" + VALUE "OriginalFilename", "NewAwaySys.dll" + VALUE "ProductName", "New Away System (ANSI)" +#endif + VALUE "ProductVersion", STRPRODUCTVER + VALUE "SpecialBuild", STRSPECIALBUILD + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +///////////////////////////////////////////////////////////////////////////// diff --git a/plugins/!NotAdopted/IMO2sProxy/Makefile b/plugins/!NotAdopted/IMO2sProxy/Makefile new file mode 100644 index 0000000000..e83db3ec76 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/Makefile @@ -0,0 +1,11 @@ +.PHONY: all imo2sproxy clean + +all : imo2sproxy + +imo2sproxy: + cd src/imo2skype && make imo2sproxy + cd ../.. + mv src/imo2skype/imo2sproxy bin/ + +clean : + rm imo2sproxy diff --git a/plugins/!NotAdopted/IMO2sProxy/README.txt b/plugins/!NotAdopted/IMO2sProxy/README.txt new file mode 100644 index 0000000000..0bd77dc7c2 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/README.txt @@ -0,0 +1,240 @@ +What is the SkypeProxy for imo.im +---------------------------------- +Back in 2005 when I developed the Skype plugin for Miranda IM, I also developed +a very simple protocol to tunnel the Skype API protocol via a socket. +The reason was, that some users wanted the possibility to run Skype on a +machine different to the machine they are using Miranda IM on. +So to tunnel the Skype API remotely over the network SkypeProxy was built and +was shipped with every Skype plugin build. + +The Skype API plugin for Miranda got more and more functions as the API evolved +and finally as I didn't have enough time to continue development, I handed over +development to user "tweety" who did the later versions. +The SkypeProxy-feature is still present in the current versions, as it is very +simple. It just wraps the communiction layer with the Skype API, therefore +this concept can also be adopted by other Skype-Plugins of other IMs. + +Ever since the first version of Skype plugin, people complained that they had to +install the Skype client on their machine in order to get it to work. +The Skype client was always bloated but it got even worse throughout the years. +I abandoned Skype some time ago, as this application is just consuming far too +many system ressources. However, there are some people that are only using Skype +and I need a way to communicate with them. I'm just interested in the chat +feature, so I only need to send and receive messages from other chat users. +So what can we do about it? + +There were some attempts to reverse-engineer the Skype protocol, but nobody +succeeded so far as the protocol relies heavily on cryptography, is proprietary +closed source and the Skype client itself is heaviely protected agains all +kinds of reverse-engineering (decrypts code on the fly, uses anti-debugging +tricks, etc.). + +However some users recently discovered, that there is a new Web 2.0 service that +makes it possible to do Instant messaging via the web browser using the Ajax +framework. The name of the service is imo.im +imo.im managed to provide basic connectivity to the Skype network via SkypeKit +and the nice thing about their service is, that you don't need to register, you +can just use it out of the box. +However most people are not so excited about IM in a web interface, there are +many features that an IM application provides and that are not so convenient in +a webinterface. But as their service is a webservice using jSON calls, +it is relatively easy to talk to their application server and so users of +Instant messengers that provide Skype protocol support can take advantage of +this for providing basic connectivity to the Skype network for instant messaging +without having to install the bloated Skype client application. +Only instant messaging is possible. In fact there is also alpha-Support for +Voicechat via the imo.im flash application, but this currently doesn't work +reliable due to some Macromedia Flash sandboxing issues. +But I think for most users like me that just want to stay in contact with +other Skype users via chat these functions will be enough. + +So as mentioned above the most generic approach to link imo.im services with an +Instant messanger would be to implement this as a wrapper between imo.im and +the Skype API. This way, we don't need to implement an extra plugin and it is +easily adaptable to Skype plugins of IMs, as you only need to use the +application in Skype API emulator mode. The Skype Plugin of the IM would need to do +proper error handling, but if the plugin is coded well (must be compatible with +Skype Protocol V3), this may even work out of the box. +The plugins mustn't assume that an API call always returns something useful on +every call. +The Skype API Emulation currently only works on Windows, other clients would +need to implement the very simple socket protocol for message exchange. +This application was originally developed to work with Miranda IM, so this IM +is officially supported. + +The application runs on Win32 as well as on Unix, so it's a cross-platform layer +that you can also install on your personal Server. By design, it would be even +able to manage multiple users at once, however this feature is currently not +implemented in the SkypeProxy protocol. Depeding on the user's needs, this +can be implemented, most of the code for this is already there. + +For usage with Miranda IM, a special plugin version was written, which +implementes the layer as a plugin so that it can be loaded into Miranda +and the user doesn't have to run the proxy application seperately. +The plugin version also has the advantage that it is able to communicate +with the Skype plugin directly. + +How does it work +---------------- + +Is described in the preamble, this is just a drop-in replacement for the +communication end point of the Skype API. +The classical communication model for Skype API is: + +[ Skype servers ] <--> [ Skype App ] <--> [ Plugin ] + +The SkypeProxy communication model is: + +[ Skype servers ] <--> [ Skype App ] <--> [ SkypeProxy ] <--> [ Plugin ] + +Now with this Drop-in replacement the communication model is: + +[ Skype servers ] <--> [ imo.im ] <--> [ SkypeProxy ] <--> [ Plugin ] + +The application communicates via a socket connection on Port 1402, like +SkypeProxy does. It uses the imo.im services to connect to the Skype network. + +You also have the possibility to emulate the Skype WIN32-API so that +any plugin can communicate with this application instead of Skype. + +As said, there are 3 connection points to communicate with the plugin: + - WIN32 Skype API via Windowmessages, emulates the real Skype API for + compatibility with any Skype plugin. (Windows) + - Socket communication layer via TCP/IP. (Windows/Unix) + - Internal plugin communcation layer used by the Miranda IM plugin to + communicate with Skype plugin versions starting with 0.0.0.46 + (Windows, Miranda IM plugin only) + +How to compile +-------------- +On Unix type systems, just extract this package and type "make". +After compiling, you will find imo2sproxy in the bin/ directory + +On Windows systems, you will find Visual C 6 project files in the +msvc/ subdirectory. +You have Makefiles available for the appropriate modules: +imoskype.mak - Compiles the imo2sproxy standalone executable +imoproxy.mak - Compiles the Miranda IM Plugin + +There are 4 available Targets: +Win32 Release - 32bit Windows Release version +Win64 Release - 64bit Windows Release version +Win32 Debug - 32bit Windows Debug version +Win64 Debug - 64bit Windows Debug version + +i.e.: +nmake -f imoskype.mak CFG="Win32 Release" + +Requirements +------------ +On Linux, libcurl Libraries and the pthread library for threading +are needed in order to get this to work. +You can download CURL on http://curl.haxx.se/download.html +To install, just use libtool as usual. + +On Windows, WININET is required which should be shipped with +Internet Explorer. So on an average Windows System, you shouldn't +need to install any additional libraries. +Please note, that libcurl IS NO LONGER NEEDED on Windows. + +How to use the commandline version +---------------------------------- +Find the precompiled binaries in the bin/ subdirectory. + +imo2sproxy [-d] [-v [-l ]] [-t] [-i] + [-m] [-h ] [-p ] + +-v - Verbose mode, log commands to console +-l - Set logfile to redirect verbose log to. +-d - Daemonize (detach from console) +-i - Use interactive mode (starts imo.im flash app upon call) +-t - Ignore server timestamp and use current time for messages +-h - Bind to a specific IP, not to all interfaces (default) +-p - Bind to another port (default: 1401) +-m - Specify connection mode to use: + s Socket mode (SkypeProxy protocol) [default] + a Skype API Emulation via Window messages (real Skype API) + +-ma is only available on Windows systems. + +As there is currently only a single-user implementation of this application, you + need to start imo2sproxy with your Skype username and password as parameters. + +Example for using the socket protocol: +imo2sproxy -d -h 127.0.0.1 myuser mypass + +As soon as the imo2sproxy is running, setup your Skype Plugin to use the +SkypeProxy at the machine you are running imo2sproxy on. +If you are running imo2sproxy locally, enter 127.0.0.1 as IP address. +After setting the SkypeProxy, you have to restart Miranda IM. + +If all works well, you should now be able to use Skype via imo.im. +If it doesn't work, you can use the -v parameter to see what's going on and +if the connection works. + +If it all works well, you can also install imo2sproxy on your machine +as a service using srvany. + +Example for using the Skype API Emulation (win32 only): +imo2sproxy.exe -d -ma myuser mypass + +As soon as the imo2sproxy is running, just try to use your Skype plugin and +see if it connects to the imo2sproxy locally. +Of course, if you have the Skype application installed, you mustn't run +it concurrently with the plugin with this configuration. + +How to use the Miranda plugin +----------------------------- +Copy the imoproxy.dll file to your Miranda Plugins-directory. +As the name starts with i and the the Skype plugin name starts with s, +the imoproxy.dll module is loaded prior to the Skype-Plugin DLL which +is important to work properly if you are using the socket method. + +For older versions of the Skype plugin (prior to 0.0.0.46, which is +currently still beta), you should use the socket communication method: +Configure the plugin DLL in the Options dialog Network/Skype Imoproxy. +Bind to address 127.0.0.1, Port 1401 +Make sure that the Skype Proxy settings in your Skype plugin are the +same. The Skypeproxy-Plugin tries to take care of that. +Enter your Username and Password, set the appropriate options and press +OK. The Skypeproxy-plugin restarts itself. Try to reconnect Skype plugin +and see if it works. +The plugin is still experimental and may contain some bugs or stability +problems, so use with care. It may be harder to hunt down bugs with this +Plugin as its running as Miranda plugin and the only logging facility is +a logfile. So if you want to hunt down bugs, you may be better off with +using the standalone version, however the plugin is a start to make the +use of imo2sproxy easier. Feel free to improve the plugin. + +For Skype plugin versions starting with 0.0.0.46, there is an internal +plugin link facility which makes it easier for the user to setup. +Bascially this should work out of the box, just enter your username and +password in the options dialog and ensute that the internal plugin +link service is active. +It will then automatically register to the Skype plugin. + +Module structure +---------------- + +For the structure of the code-modules, please refer to the +structure.txt document. + +SkypeProxy protocol +------------------- + +Plase download the sourcecode of skypeproxy.c of Miranda IM Skype plugin, it's +all well documented in the .c file. Basically the protocol just consists of: + +[UCHAR: number of bytes to send/receive][ Data] + +for every line sent or received. + +Contact +------- +Feel free to contact me regarding this project or if you wish to implement +SkypeProxy protocol in your own Skype-plugin implementation. + +leecher@dose.0wnz.at + + +Vienna, 10/07/2009 diff --git a/plugins/!NotAdopted/IMO2sProxy/bin/setupimo.bat b/plugins/!NotAdopted/IMO2sProxy/bin/setupimo.bat new file mode 100644 index 0000000000..9c765c6479 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/bin/setupimo.bat @@ -0,0 +1,24 @@ +@echo off +SET /P USER=Skype username: +IF "%USER%"=="" ( + echo Username is mandatory, aborting. + GOTO fini +) +SET /P PASS=Skype password: +IF "%PASS%"=="" ( + echo Password is mandatory, aborting. + GOTO fini +) +SET /P IP=Bind to IP [0.0.0.0]: +SET /P PORT=Bind to Port [1401]: +SET /P DAEM=Do you want to daemonize [N]: +IF /I "%DAEM%" NEQ "Y" SET /P VERB=Do you want verbose command output [N]: +IF /I "%DAEM%"=="Y" SET CMDLINE=%CMDLINE% -d +IF /I "%VERB%"=="Y" SET CMDLINE=%CMDLINE% -v +IF NOT "%IP%"=="" SET CMDLINE=%CMDLINE% -h %IP% +IF NOT "%PORT%"=="" SET CMDLINE=%CMDLINE% -p %PORT% +SET CMDLINE=%CMDLINE% %USER% %PASS% +echo imo2sproxy %CMDLINE% >startimo.bat +echo startimo.bat created. +:fini +pause diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsp b/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsp new file mode 100644 index 0000000000..d607233428 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsp @@ -0,0 +1,248 @@ +# Microsoft Developer Studio Project File - Name="imoproxy" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** NICHT BEARBEITEN ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=imoproxy - Win32 Debug +!MESSAGE Dies ist kein gьltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE +!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fьhren Sie den Befehl +!MESSAGE +!MESSAGE NMAKE /f "imoproxy.mak". +!MESSAGE +!MESSAGE Sie kцnnen beim Ausfьhren von NMAKE eine Konfiguration angeben +!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: +!MESSAGE +!MESSAGE NMAKE /f "imoproxy.mak" CFG="imoproxy - Win32 Debug" +!MESSAGE +!MESSAGE Fьr die Konfiguration stehen zur Auswahl: +!MESSAGE +!MESSAGE "imoproxy - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library") +!MESSAGE "imoproxy - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "imoproxy - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\src\common" /I "..\src\imolib" /I "..\src\imo2skype" /I "F:\miranda09_src\miranda" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /FR /YX /FD /c +# SUBTRACT CPP /X +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0xc07 /d "NDEBUG" +# ADD RSC /l 0xc07 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 + +!ELSEIF "$(CFG)" == "imoproxy - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\src\common" /I "..\src\imolib" /I "..\src\imo2skype" /I "F:\miranda09_src\miranda" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0xc07 /d "_DEBUG" +# ADD RSC /l 0xc07 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"F:\miranda09_src\miranda\bin\debug\Plugins\imoproxy.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "imoproxy - Win32 Release" +# Name "imoproxy - Win32 Debug" +# Begin Group "Quellcodedateien" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\src\imo2skype\avatarlist.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\buddylist.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\callqueue.c +# End Source File +# Begin Source File + +SOURCE=..\src\common\cJSON.c +# End Source File +# Begin Source File + +SOURCE=..\src\common\fifo.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\imo2skypeapi.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\imo2sproxy.c +# End Source File +# Begin Source File + +SOURCE=..\src\imolib\imo_request.c +# End Source File +# Begin Source File + +SOURCE=..\src\imolib\imo_skype.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\miranda\imoproxy.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\miranda\io_layer_netlib.c +# End Source File +# Begin Source File + +SOURCE=..\src\imolib\io_layer_win32.c +# End Source File +# Begin Source File + +SOURCE=..\src\common\memlist.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\msgqueue.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\queue.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\miranda\skypepluginlink.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\socksproxy.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\w32browser.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\w32skypeemu.c +# End Source File +# End Group +# Begin Group "Header-Dateien" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\src\imo2skype\buddylist.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\callqueue.h +# End Source File +# Begin Source File + +SOURCE=..\src\common\cJSON.h +# End Source File +# Begin Source File + +SOURCE=..\src\common\fifo.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\imo2skypeapi.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\imo2sproxy.h +# End Source File +# Begin Source File + +SOURCE=..\src\imolib\imo_request.h +# End Source File +# Begin Source File + +SOURCE=..\src\imolib\imo_skype.h +# End Source File +# Begin Source File + +SOURCE=..\src\imolib\io_layer.h +# End Source File +# Begin Source File + +SOURCE=..\src\common\memlist.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\msgqueue.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\queue.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\miranda\skypepluginlink.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\socksproxy.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\w32browser.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\w32skypeemu.h +# End Source File +# End Group +# Begin Group "Ressourcendateien" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=..\src\imo2skype\miranda\res.rc +# End Source File +# End Group +# End Target +# End Project diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsw b/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsw new file mode 100644 index 0000000000..2d4fb49ab6 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsw @@ -0,0 +1,41 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELЦSCHT WERDEN! + +############################################################################### + +Project: "imoproxy"=.\imoproxy.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "imoskype"=.\imoskype.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.mak b/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.mak new file mode 100644 index 0000000000..04b4371268 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.mak @@ -0,0 +1,221 @@ +!IF "$(CFG)" == "" +CFG=Win32 Debug +!MESSAGE Keine Konfiguration angegeben. Win32 Debug wird als Standard verwendet. +!ENDIF + +!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug" && "$(CFG)" != "Win64 Release" && "$(CFG)" != "Win64 Debug" +!MESSAGE Ungьltige Konfiguration "$(CFG)" angegeben. +!MESSAGE Sie kцnnen beim Ausfьhren von NMAKE eine Konfiguration angeben +!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: +!MESSAGE +!MESSAGE NMAKE /f "imoproxy.mak" CFG="Win32 Debug" +!MESSAGE +!MESSAGE Fьr die Konfiguration stehen zur Auswahl: +!MESSAGE +!MESSAGE "Win32 Release" +!MESSAGE "Win32 Debug" +!MESSAGE "Win64 Release" +!MESSAGE "Win64 Debug" +!MESSAGE +!ERROR Eine ungьltige Konfiguration wurde angegeben. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe +LINK32=link.exe + +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /pdb:"$(INTDIR)\imoproxy.pdb" /out:"$(OUTDIR)\imoproxy.dll" /implib:"$(INTDIR)\imoproxy.lib" +INCLUDES=/I "../src/common" /I "../src/imo2skype" /I "../src/imolib" /I "F:\miranda09_src\miranda" + +!IF "$(CFG)" == "Win64 Release" +OUTDIR=..\bin64 +INTDIR=.\Release64 +CPP_PROJ=/nologo /MT /W3 /O2 $(INCLUDES) /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /Fp"$(INTDIR)\imoproxy.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 +RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\res.res" /d "NDEBUG" +!ELSEIF "$(CFG)" == "Win32 Release" +OUTDIR=..\bin +INTDIR=.\Release +CPP_PROJ=/nologo /MT /W3 /O2 $(INCLUDES) /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /Fp"$(INTDIR)\imoproxy.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 +RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\res.res" /d "NDEBUG" +!ELSEIF "$(CFG)" == "Win64 Debug" +OUTDIR=.\Debug64 +INTDIR=$(OUTDIR) +CPP_PROJ=/nologo /MTd /W3 /Gm /ZI /Od $(INCLUDES) /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\imoproxy.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c +LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 +RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\res.res" /d "_DEBUG" +!ELSEIF "$(CFG)" == "Win32 Debug" +OUTDIR=.\Debug +INTDIR=$(OUTDIR) +CPP_PROJ=/nologo /MTd /W3 /Gm /ZI /Od $(INCLUDES) /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\imoproxy.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c +LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 +RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\res.res" /d "_DEBUG" +!ENDIF + +LINK32_OBJS= \ + "$(INTDIR)\avatarlist.obj" \ + "$(INTDIR)\buddylist.obj" \ + "$(INTDIR)\callqueue.obj" \ + "$(INTDIR)\cJSON.obj" \ + "$(INTDIR)\fifo.obj" \ + "$(INTDIR)\imo2skypeapi.obj" \ + "$(INTDIR)\imo2sproxy.obj" \ + "$(INTDIR)\imo_request.obj" \ + "$(INTDIR)\imo_skype.obj" \ + "$(INTDIR)\imoproxy.obj" \ + "$(INTDIR)\io_layer_win32.obj" \ + "$(INTDIR)\io_layer_netlib.obj" \ + "$(INTDIR)\memlist.obj" \ + "$(INTDIR)\msgqueue.obj" \ + "$(INTDIR)\queue.obj" \ + "$(INTDIR)\socksproxy.obj" \ + "$(INTDIR)\w32browser.obj" \ + "$(INTDIR)\w32skypeemu.obj" \ + "$(INTDIR)\res.res" \ + "$(INTDIR)\skypepluginlink.obj" + + +ALL : "$(OUTDIR)\imoproxy.dll" + + +CLEAN : + -@erase "$(INTDIR)\avatarlist.obj" + -@erase "$(INTDIR)\buddylist.obj" + -@erase "$(INTDIR)\callqueue.obj" + -@erase "$(INTDIR)\cJSON.obj" + -@erase "$(INTDIR)\fifo.obj" + -@erase "$(INTDIR)\imo2skypeapi.obj" + -@erase "$(INTDIR)\imo2sproxy.obj" + -@erase "$(INTDIR)\imo_request.obj" + -@erase "$(INTDIR)\imo_skype.obj" + -@erase "$(INTDIR)\imoproxy.obj" + -@erase "$(INTDIR)\io_layer_win32.obj" + -@erase "$(INTDIR)\io_layer_netlib.obj" + -@erase "$(INTDIR)\memlist.obj" + -@erase "$(INTDIR)\msgqueue.obj" + -@erase "$(INTDIR)\queue.obj" + -@erase "$(INTDIR)\res.res" + -@erase "$(INTDIR)\skypepluginlink.obj" + -@erase "$(INTDIR)\socksproxy.obj" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\w32browser.obj" + -@erase "$(INTDIR)\w32skypeemu.obj" + -@erase "$(OUTDIR)\imoproxy.dll" + -@erase "$(OUTDIR)\imoproxy.exp" + -@erase "$(OUTDIR)\imoproxy.lib" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(OUTDIR)\imoproxy.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +!IF "$(NO_EXTERNAL_DEPS)" != "1" +!IF EXISTS("imoproxy.dep") +!INCLUDE "imoproxy.dep" +!ELSE +!MESSAGE Warning: cannot find "imoproxy.dep" +!ENDIF +!ENDIF + + +SOURCE=..\src\imo2skype\avatarlist.c +"$(INTDIR)\avatarlist.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\buddylist.c +"$(INTDIR)\buddylist.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\callqueue.c +"$(INTDIR)\callqueue.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\common\cJSON.c +"$(INTDIR)\cJSON.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\common\fifo.c +"$(INTDIR)\fifo.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\imo2skypeapi.c +"$(INTDIR)\imo2skypeapi.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\imo2sproxy.c +"$(INTDIR)\imo2sproxy.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imolib\imo_request.c +"$(INTDIR)\imo_request.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imolib\imo_skype.c +"$(INTDIR)\imo_skype.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\miranda\imoproxy.c +"$(INTDIR)\imoproxy.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imolib\io_layer_win32.c +"$(INTDIR)\io_layer_win32.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\common\memlist.c +"$(INTDIR)\memlist.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\msgqueue.c +"$(INTDIR)\msgqueue.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\queue.c +"$(INTDIR)\queue.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\miranda\skypepluginlink.c +"$(INTDIR)\skypepluginlink.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\miranda\io_layer_netlib.c +"$(INTDIR)\io_layer_netlib.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\socksproxy.c +"$(INTDIR)\socksproxy.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\w32browser.c +"$(INTDIR)\w32browser.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\w32skypeemu.c +"$(INTDIR)\w32skypeemu.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=..\src\imo2skype\miranda\res.rc +"$(INTDIR)\res.res" : $(SOURCE) "$(INTDIR)" + $(RSC) /l 0xc07 /fo"$(INTDIR)\res.res" /i "..\src\imo2skype\miranda" /d "NDEBUG" $(SOURCE) + diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.dsp b/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.dsp new file mode 100644 index 0000000000..00d324b5b8 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.dsp @@ -0,0 +1,230 @@ +# Microsoft Developer Studio Project File - Name="imoskype" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** NICHT BEARBEITEN ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=imoskype - Win32 Debug +!MESSAGE Dies ist kein gьltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE +!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fьhren Sie den Befehl +!MESSAGE +!MESSAGE NMAKE /f "imoskype.mak". +!MESSAGE +!MESSAGE Sie kцnnen beim Ausfьhren von NMAKE eine Konfiguration angeben +!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: +!MESSAGE +!MESSAGE NMAKE /f "imoskype.mak" CFG="imoskype - Win32 Debug" +!MESSAGE +!MESSAGE Fьr die Konfiguration stehen zur Auswahl: +!MESSAGE +!MESSAGE "imoskype - Win32 Release" (basierend auf "Win32 (x86) Console Application") +!MESSAGE "imoskype - Win32 Debug" (basierend auf "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +RSC=rc.exe + +!IF "$(CFG)" == "imoskype - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../src/common" /I "../src/imo2skype" /I "../src/imolib" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c +# ADD BASE RSC /l 0xc07 /d "NDEBUG" +# ADD RSC /l 0xc07 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /out:"../bin/imo2sproxy.exe" + +!ELSEIF "$(CFG)" == "imoskype - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../src/common" /I "../src/imo2skype" /I "../src/imolib" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0xc07 /d "_DEBUG" +# ADD RSC /l 0xc07 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/imo2sproxy.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "imoskype - Win32 Release" +# Name "imoskype - Win32 Debug" +# Begin Group "Quellcodedateien" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=\temp\debug\imo.im\src\imo2skype\avatarlist.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\buddylist.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\callqueue.c +# End Source File +# Begin Source File + +SOURCE=..\src\common\cJSON.c +# End Source File +# Begin Source File + +SOURCE=..\src\common\fifo.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\imo2skypeapi.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\imo2sproxy.c +# End Source File +# Begin Source File + +SOURCE=..\src\imolib\imo_request.c +# End Source File +# Begin Source File + +SOURCE=..\src\imolib\imo_skype.c +# End Source File +# Begin Source File + +SOURCE=..\src\imolib\io_layer_win32.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\main.c +# End Source File +# Begin Source File + +SOURCE=..\src\common\memlist.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\msgqueue.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\queue.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\socksproxy.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\w32browser.c +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\w32skypeemu.c +# End Source File +# End Group +# Begin Group "Header-Dateien" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=\temp\debug\imo.im\src\imo2skype\avatarlist.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\buddylist.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\callqueue.h +# End Source File +# Begin Source File + +SOURCE=..\src\common\cJSON.h +# End Source File +# Begin Source File + +SOURCE=..\src\common\fifo.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\imo2skypeapi.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\imo2sproxy.h +# End Source File +# Begin Source File + +SOURCE=..\src\imolib\imo_request.h +# End Source File +# Begin Source File + +SOURCE=..\src\imolib\imo_skype.h +# End Source File +# Begin Source File + +SOURCE=..\src\imolib\io_layer.h +# End Source File +# Begin Source File + +SOURCE=..\src\common\memlist.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\msgqueue.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\queue.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\socksproxy.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\w32browser.h +# End Source File +# Begin Source File + +SOURCE=..\src\imo2skype\w32skypeemu.h +# End Source File +# End Group +# Begin Group "Ressourcendateien" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.dsw b/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.dsw new file mode 100644 index 0000000000..a4c512f5e0 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELЦSCHT WERDEN! + +############################################################################### + +Project: "imoskype"=.\imoskype.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.mak b/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.mak new file mode 100644 index 0000000000..be7b29f013 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.mak @@ -0,0 +1,193 @@ +!IF "$(CFG)" == "" +CFG=Win32 Debug +!MESSAGE Keine Konfiguration angegeben. Win32 Debug wird als Standard verwendet. +!ENDIF + +!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug" && "$(CFG)" != "Win64 Release" && "$(CFG)" != "Win64 Debug" +!MESSAGE UngЃltige Konfiguration "$(CFG)" angegeben. +!MESSAGE Sie k”nnen beim AusfЃhren von NMAKE eine Konfiguration angeben +!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: +!MESSAGE +!MESSAGE NMAKE /f "imoskype.mak" CFG="Win32 Debug" +!MESSAGE +!MESSAGE FЃr die Konfiguration stehen zur Auswahl: +!MESSAGE +!MESSAGE "Win32 Release" +!MESSAGE "Win32 Debug" +!MESSAGE "Win64 Release" +!MESSAGE "Win64 Debug" +!MESSAGE +!ERROR Eine ungЃltige Konfiguration wurde angegeben. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +CPP=cl.exe +RSC=rc.exe +LINK32=link.exe + +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ws2_32.lib /nologo /subsystem:console /pdb:"$(INTDIR)\imo2sproxy.pdb" /out:"$(OUTDIR)/imo2sproxy.exe" +INCLUDES=/I "../src/common" /I "../src/imo2skype" /I "../src/imolib" + +!IF "$(CFG)" == "Win64 Release" +OUTDIR=..\bin64 +INTDIR=.\Release64 +CPP_PROJ=/nologo /MT /W3 /O2 $(INCLUDES) /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\imoskype.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no +!ELSEIF "$(CFG)" == "Win32 Release" +OUTDIR=..\bin +INTDIR=.\Release +CPP_PROJ=/nologo /MT /W3 /O2 $(INCLUDES) /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\imoskype.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no +!ELSEIF "$(CFG)" == "Win64 Debug" +OUTDIR=.\Debug64 +INTDIR=$(OUTDIR) +CPP_PROJ=/nologo /MTd /W3 /Gm /ZI /Od $(INCLUDES) /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\imoskype.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c +LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept +!ELSEIF "$(CFG)" == "Win32 Debug" +OUTDIR=.\Debug +INTDIR=$(OUTDIR) +CPP_PROJ=/nologo /MTd /W3 /Gm /ZI /Od $(INCLUDES) /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\imoskype.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c +LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept +!ENDIF + +LINK32_OBJS= \ + "$(INTDIR)\avatarlist.obj" \ + "$(INTDIR)\buddylist.obj" \ + "$(INTDIR)\callqueue.obj" \ + "$(INTDIR)\cJSON.obj" \ + "$(INTDIR)\fifo.obj" \ + "$(INTDIR)\imo2skypeapi.obj" \ + "$(INTDIR)\imo2sproxy.obj" \ + "$(INTDIR)\imo_request.obj" \ + "$(INTDIR)\imo_skype.obj" \ + "$(INTDIR)\io_layer_win32.obj" \ + "$(INTDIR)\main.obj" \ + "$(INTDIR)\memlist.obj" \ + "$(INTDIR)\msgqueue.obj" \ + "$(INTDIR)\queue.obj" \ + "$(INTDIR)\socksproxy.obj" \ + "$(INTDIR)\w32browser.obj" \ + "$(INTDIR)\w32skypeemu.obj" + +ALL : "$(OUTDIR)\imo2sproxy.exe" + +CLEAN : + -@erase "$(INTDIR)\avatarlist.obj" + -@erase "$(INTDIR)\buddylist.obj" + -@erase "$(INTDIR)\callqueue.obj" + -@erase "$(INTDIR)\cJSON.obj" + -@erase "$(INTDIR)\fifo.obj" + -@erase "$(INTDIR)\imo2skypeapi.obj" + -@erase "$(INTDIR)\imo2sproxy.obj" + -@erase "$(INTDIR)\imo_request.obj" + -@erase "$(INTDIR)\imo_skype.obj" + -@erase "$(INTDIR)\io_layer_win32.obj" + -@erase "$(INTDIR)\main.obj" + -@erase "$(INTDIR)\memlist.obj" + -@erase "$(INTDIR)\msgqueue.obj" + -@erase "$(INTDIR)\queue.obj" + -@erase "$(INTDIR)\socksproxy.obj" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\w32browser.obj" + -@erase "$(INTDIR)\w32skypeemu.obj" + -@erase "$(INTDIR)\imo2sproxy.ilk" + -@erase "$(INTDIR)\imo2sproxy.pdb" + -@erase "$(OUTDIR)\imo2sproxy.exe" + + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(OUTDIR)\imo2sproxy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +!IF "$(NO_EXTERNAL_DEPS)" != "1" +!IF EXISTS("imoskype.dep") +!INCLUDE "imoskype.dep" +!ELSE +!MESSAGE Warning: cannot find "imoskype.dep" +!ENDIF +!ENDIF + + +SOURCE=..\src\imo2skype\avatarlist.c +"$(INTDIR)\avatarlist.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\buddylist.c +"$(INTDIR)\buddylist.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\callqueue.c +"$(INTDIR)\callqueue.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\common\cJSON.c +"$(INTDIR)\cJSON.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\common\fifo.c +"$(INTDIR)\fifo.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\imo2skypeapi.c +"$(INTDIR)\imo2skypeapi.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\imo2sproxy.c +"$(INTDIR)\imo2sproxy.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imolib\imo_request.c +"$(INTDIR)\imo_request.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imolib\imo_skype.c +"$(INTDIR)\imo_skype.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imolib\io_layer_win32.c +"$(INTDIR)\io_layer_win32.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\main.c +"$(INTDIR)\main.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\common\memlist.c +"$(INTDIR)\memlist.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\msgqueue.c +"$(INTDIR)\msgqueue.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\queue.c +"$(INTDIR)\queue.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\socksproxy.c +"$(INTDIR)\socksproxy.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\w32browser.c +"$(INTDIR)\w32browser.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=..\src\imo2skype\w32skypeemu.c +"$(INTDIR)\w32skypeemu.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/make.bat b/plugins/!NotAdopted/IMO2sProxy/msvc/make.bat new file mode 100644 index 0000000000..a974f238ab --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/make.bat @@ -0,0 +1,2 @@ +cmd /c make_w32 +cmd /c make_w64 diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/make_w32.bat b/plugins/!NotAdopted/IMO2sProxy/msvc/make_w32.bat new file mode 100644 index 0000000000..e5f7eafd2f --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/make_w32.bat @@ -0,0 +1,7 @@ +call "F:\Programme\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT" +nmake -f imoproxy.mak CFG="Win32 Release" clean +nmake -f imoskype.mak CFG="Win32 Release" clean +nmake -f imoproxy.mak CFG="Win32 Release" +nmake -f imoskype.mak CFG="Win32 Release" +nmake -f imoproxy.mak CFG="Win32 Debug" +nmake -f imoskype.mak CFG="Win32 Debug" diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/make_w64.bat b/plugins/!NotAdopted/IMO2sProxy/msvc/make_w64.bat new file mode 100644 index 0000000000..a97d4a2d7d --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/make_w64.bat @@ -0,0 +1,5 @@ +call f:\PlatformSDK\SetEnv /X64 /RETAIL +nmake -f imoproxy.mak CFG="Win64 Release" clean +nmake -f imoskype.mak CFG="Win64 Release" clean +nmake -f imoproxy.mak CFG="Win64 Release" +nmake -f imoskype.mak CFG="Win64 Release" diff --git a/plugins/!NotAdopted/IMO2sProxy/src/common/cJSON.c b/plugins/!NotAdopted/IMO2sProxy/src/common/cJSON.c new file mode 100644 index 0000000000..72f35f6117 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/common/cJSON.c @@ -0,0 +1,365 @@ +/* + Copyright (c) 2009 Dave Gamble + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +// cJSON +// JSON parser in C. + +#include +#include +#include +#include +#include +#include "cJSON.h" +#ifdef WIN32 +#define strcasecmp stricmp +#endif + +// Internal constructor. +static cJSON *cJSON_New_Item() { return (cJSON*)calloc(sizeof(cJSON),1); } + +// Delete a cJSON structure. +void cJSON_Delete(cJSON *c) +{ + cJSON *next; + while (c) + { + next=c->next; + if (c->child) cJSON_Delete(c->child); + if (c->valuestring) free(c->valuestring); + if (c->string) free(c->string); + free(c); + c=next; + } +} + +// Parse the input text to generate a number, and populate the result into item. +static const char *parse_number(cJSON *item,const char *num) +{ + double n=0,sign=1,scale=0;int subscale=0,signsubscale=1; + + // Could use sscanf for this? + if (*num=='-') sign=-1,num++; // Has sign? + if (*num=='0') num++; // is zero + if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); // Number? + if (*num=='.') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} // Fractional part? + if (*num=='e' || *num=='E') // Exponent? + { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; // With sign? + while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); // Number? + } + + n=sign*n*pow(10.0,(scale+subscale*signsubscale)); // number = +/- number.fraction * 10^+/- exponent + + item->valuedouble=n; + item->valueint=(int)n; + item->type=cJSON_Number; + return num; +} + +// Render the number nicely from the given item into a string. +static char *print_number(cJSON *item) +{ + char *str; + double d=item->valuedouble; + if (fabs(((double)item->valueint)-d)<=DBL_EPSILON) + { + str=malloc(21); // 2^64+1 can be represented in 21 chars. + sprintf(str,"%d",item->valueint); + } + else + { + str=malloc(64); // This is a nice tradeoff. + if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d); + else sprintf(str,"%f",d); + } + return str; +} + +// Parse the input text into an unescaped cstring, and populate item. +static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; +static const char *parse_string(cJSON *item,const char *str) +{ + const unsigned char *ptr=str+1; + unsigned char *ptr2; + char *out;int len=0;unsigned uc; + if (*str!='\"') return 0; // not a string! + + while (*ptr!='\"' && *ptr>31 && ++len) if (*ptr++ == '\\') ptr++; // Skip escaped quotes. + + out=(char*)malloc(len+1); // This is how long we need for the string, roughly. + + ptr=str+1;ptr2=out; + while (*ptr!='\"' && *ptr>31) + { + if (*ptr!='\\') *ptr2++=*ptr++; + else + { + ptr++; + switch (*ptr) + { + case 'b': *ptr2++='\b'; break; + case 'f': *ptr2++='\f'; break; + case 'n': *ptr2++='\n'; break; + case 'r': *ptr2++='\r'; break; + case 't': *ptr2++='\t'; break; + case 'u': // transcode utf16 to utf8. DOES NOT SUPPORT SURROGATE PAIRS CORRECTLY. + sscanf(ptr+1,"%4x",&uc); // get the unicode char. + len=3;if (uc<0x80) len=1;else if (uc<0x800) len=2;ptr2+=len; + + switch (len) { + case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; + case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; + case 1: *--ptr2 =(uc | firstByteMark[len]); + } + ptr2+=len;ptr+=4; + break; + default: *ptr2++=*ptr; break; + } + ptr++; + } + } + *ptr2=0; + if (*ptr=='\"') ptr++; + item->valuestring=out; + item->type=cJSON_String; + return ptr; +} + +// Render the cstring provided to an escaped version that can be printed. +static char *print_string_ptr(const char *str) +{ + const unsigned char *ptr; unsigned char *ptr2,*out;int len=0; + + ptr=str;while (*ptr && ++len) {if (*ptr<32 || *ptr=='\"' || *ptr=='\\') len++;ptr++;} + + out=(char*)malloc(len+3); + ptr2=out;ptr=str; + *ptr2++='\"'; + while (*ptr) + { + if (*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++; + else + { + *ptr2++='\\'; + switch (*ptr++) + { + case '\\': *ptr2++='\\'; break; + case '\"': *ptr2++='\"'; break; + case '\b': *ptr2++='b'; break; + case '\f': *ptr2++='f'; break; + case '\n': *ptr2++='n'; break; + case '\r': *ptr2++='r'; break; + case '\t': *ptr2++='t'; break; + default: ptr2--; break; // eviscerate with prejudice. + } + } + } + *ptr2++='\"';*ptr2++=0; + return out; +} +// Invote print_string_ptr (which is useful) on an item. +static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);} + +// Predeclare these prototypes. +static const char *parse_value(cJSON *item,const char *value); +static char *print_value(cJSON *item,int depth); +static const char *parse_array(cJSON *item,const char *value); +static char *print_array(cJSON *item,int depth); +static const char *parse_object(cJSON *item,const char *value); +static char *print_object(cJSON *item,int depth); + +// Parse an object - create a new root, and populate. +cJSON *cJSON_Parse(const char *value) {cJSON *c=cJSON_New_Item();parse_value(c,value);return c;} +// Render a cJSON item/entity/structure to text. +char *cJSON_Print(cJSON *item) {return print_value(item,0);} + +// Parser core - when encountering text, process appropriately. +static const char *parse_value(cJSON *item,const char *value) +{ + if (!value) return 0; // Fail on null. + if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; } + if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; } + if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; } + if (*value=='\"') { return parse_string(item,value); } + if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); } + if (*value=='[') { return parse_array(item,value); } + if (*value=='{') { return parse_object(item,value); } + + return 0; // failure. +} + +// Render a value to text. +static char *print_value(cJSON *item,int depth) +{ + char *out=0; + switch (item->type) + { + case cJSON_NULL: out=strdup("null"); break; + case cJSON_False: out=strdup("false");break; + case cJSON_True: out=strdup("true"); break; + case cJSON_Number: out=print_number(item);break; + case cJSON_String: out=print_string(item);break; + case cJSON_Array: out=print_array(item,depth);break; + case cJSON_Object: out=print_object(item,depth);break; + } + return out; +} + +// Utility to jump whitespace and cr/lf +static const char *skip(const char *in) {while (in && *in<=32) in++; return in;} + +// Build an array from input text. +static const char *parse_array(cJSON *item,const char *value) +{ + cJSON *child; + if (*value!='[') return 0; // not an array! + + item->type=cJSON_Array; + value=skip(value+1); + if (*value==']') return value+1; // empty array. + + item->child=child=cJSON_New_Item(); + value=skip(parse_value(child,skip(value))); // skip any spacing, get the value. + + while (*value==',') + { + cJSON *new_item; + if (!(new_item=cJSON_New_Item())) return 0; // memory fail + child->next=new_item;new_item->prev=child;child=new_item; + value=skip(parse_value(child,skip(value+1))); + } + + if (*value==']') return value+1; // end of array + return 0; // malformed. +} + +// Render an array to text +static char *print_array(cJSON *item,int depth) +{ + char *out,*ptr,*ret;int len=5; + cJSON *child=item->child; + + out=malloc(len);*out='['; + ptr=out+1;*ptr=0; + while (child) + { + ret=print_value(child,depth+1); + if (!ret) {free(out);return 0;} // Check for failure! + len+=strlen(ret)+3; + out=realloc(out,len); + ptr=out+strlen(out); + ptr+=sprintf(ptr,"%s",ret); + if (child->next) {*ptr++=',';*ptr++=' ';*ptr=0;} + child=child->next; + free(ret); + } + *ptr++=']';*ptr++=0; + return out; +} + +// Build an object from the text. +static const char *parse_object(cJSON *item,const char *value) +{ + cJSON *child; + if (*value!='{') return 0; // not an object! + + item->type=cJSON_Object; + value=skip(value+1); + if (*value=='}') return value+1; // empty array. + + item->child=child=cJSON_New_Item(); + value=skip(parse_string(child,skip(value))); + child->string=child->valuestring;child->valuestring=0; + if (*value!=':') return 0; // fail! + value=skip(parse_value(child,skip(value+1))); // skip any spacing, get the value. + + while (*value==',') + { + cJSON *new_item; + if (!(new_item=cJSON_New_Item())) return 0; // memory fail + child->next=new_item;new_item->prev=child;child=new_item; + value=skip(parse_string(child,skip(value+1))); + child->string=child->valuestring;child->valuestring=0; + if (*value!=':') return 0; // fail! + value=skip(parse_value(child,skip(value+1))); // skip any spacing, get the value. + } + + if (*value=='}') return value+1; // end of array + return 0; // malformed. +} + +// Render an object to text. +static char *print_object(cJSON *item,int depth) +{ + char *out,*ptr,*ret,*str;int len=7;//,i; + cJSON *child=item->child; + + depth++;out=malloc(len+depth);*out='{'; + ptr=out+1;*ptr++=' ';*ptr=0; + while (child) + { + str=print_string_ptr(child->string); + if (!str) {free(out);return 0;} + ret=print_value(child,depth); + if (!ret) {free(out);return 0;} // Check for failure! + len+=strlen(ret)+strlen(str)+4+depth; + out=realloc(out,len); + ptr=out+strlen(out); +// for (i=0;inext) *ptr++=','; + *ptr++=' ';*ptr=0; + child=child->next; + free(str);free(ret); + } +// for (i=0;ichild;int i=0;while(c)i++,c=c->next;return i;} +cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item) item--,c=c->next; return c;} +cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && strcasecmp(c->string,string)) c=c->next; return c;} + +// Utility for array list handling. +static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;} + +// Add item to array/object. +void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}} +void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (item->string) free(item->string);item->string=strdup(string);cJSON_AddItemToArray(object,item);} + +// Create basic types: +cJSON *cJSON_CreateNull() {cJSON *item=cJSON_New_Item();item->type=cJSON_NULL;return item;} +cJSON *cJSON_CreateTrue() {cJSON *item=cJSON_New_Item();item->type=cJSON_True;return item;} +cJSON *cJSON_CreateFalse() {cJSON *item=cJSON_New_Item();item->type=cJSON_False;return item;} +cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;return item;} +cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();item->type=cJSON_String;item->valuestring=strdup(string);return item;} +cJSON *cJSON_CreateArray() {cJSON *item=cJSON_New_Item();item->type=cJSON_Array;return item;} +cJSON *cJSON_CreateObject() {cJSON *item=cJSON_New_Item();item->type=cJSON_Object;return item;} + +// Create Arrays: +cJSON *cJSON_CreateIntArray(int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;ichild=n;else suffix_object(p,n);p=n;}return a;} +cJSON *cJSON_CreateFloatArray(float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;ichild=n;else suffix_object(p,n);p=n;}return a;} +cJSON *cJSON_CreateDoubleArray(double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;ichild=n;else suffix_object(p,n);p=n;}return a;} +cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;ichild=n;else suffix_object(p,n);p=n;}return a;} diff --git a/plugins/!NotAdopted/IMO2sProxy/src/common/cJSON.h b/plugins/!NotAdopted/IMO2sProxy/src/common/cJSON.h new file mode 100644 index 0000000000..debda45bc0 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/common/cJSON.h @@ -0,0 +1,97 @@ +/* + Copyright (c) 2009 Dave Gamble + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" +{ +#endif + +// cJSON Types: +#define cJSON_False 0 +#define cJSON_True 1 +#define cJSON_NULL 2 +#define cJSON_Number 3 +#define cJSON_String 4 +#define cJSON_Array 5 +#define cJSON_Object 6 + +// The cJSON structure: +typedef struct cJSON { + struct cJSON *next,*prev; // next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem + struct cJSON *child; // An array or object item will have a child pointer pointing to a chain of the items in the array/object. + + int type; // The type of the item, as above. + + char *valuestring; // The item's string, if type==cJSON_String + int valueint; // The item's number, if type==cJSON_Number + double valuedouble; // The item's number, if type==cJSON_Number + + char *string; // The item's name string, if this item is the child of, or is in the list of subitems of an object. +} cJSON; + +// Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. +extern cJSON *cJSON_Parse(const char *value); +// Render a cJSON entity to text for transfer/storage. Free the char* when finished. +extern char *cJSON_Print(cJSON *item); +// Delete a cJSON entity and all subentities. +extern void cJSON_Delete(cJSON *c); + +// Returns the number of items in an array (or object). +extern int cJSON_GetArraySize(cJSON *array); +// Retrieve item number "item" from array "array". Returns NULL if unsuccessful. +extern cJSON *cJSON_GetArrayItem(cJSON *array,int item); +// Get item "string" from object. Case insensitive. +extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string); + +// These calls create a cJSON item of the appropriate type. +extern cJSON *cJSON_CreateNull(); +extern cJSON *cJSON_CreateTrue(); +extern cJSON *cJSON_CreateFalse(); +extern cJSON *cJSON_CreateNumber(double num); +extern cJSON *cJSON_CreateString(const char *string); +extern cJSON *cJSON_CreateArray(); +extern cJSON *cJSON_CreateObject(); + +// These utilities create an Array of count items. +extern cJSON *cJSON_CreateIntArray(int *numbers,int count); +extern cJSON *cJSON_CreateFloatArray(float *numbers,int count); +extern cJSON *cJSON_CreateDoubleArray(double *numbers,int count); +extern cJSON *cJSON_CreateStringArray(const char **strings,int count); + +// Append item to the specified array/object. +extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); +extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item); + +#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) +#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) +#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) +#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) +#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/plugins/!NotAdopted/IMO2sProxy/src/common/fifo.c b/plugins/!NotAdopted/IMO2sProxy/src/common/fifo.c new file mode 100644 index 0000000000..d703ac33d4 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/common/fifo.c @@ -0,0 +1,144 @@ +#include +#include +#include "fifo.h" + +struct _tagFIFO +{ + unsigned int uiCount; + unsigned int uiCapacity; + unsigned int uiActInd; + char *acStorage; +}; + + +TYP_FIFO *Fifo_Init(unsigned int uiCapacity) +{ + TYP_FIFO *pstHandle; + + pstHandle = (TYP_FIFO *)malloc(sizeof(TYP_FIFO)); + if (!pstHandle) return NULL; + pstHandle->uiCount = pstHandle->uiActInd = 0; + pstHandle->uiCapacity = uiCapacity; + if (uiCapacity == 0) + pstHandle->acStorage = NULL; + else + { + pstHandle->acStorage = (char *)malloc(uiCapacity); + if (!pstHandle->acStorage) + { + free (pstHandle); + return NULL; + } + } + return pstHandle; +} + +void Fifo_Exit(TYP_FIFO *pstHandle) +{ + if (pstHandle->acStorage) + free (pstHandle->acStorage); + free (pstHandle); +} + +char *Fifo_AllocBuffer(TYP_FIFO *pstHandle, unsigned int uiPCount) +{ + unsigned int uiCount = pstHandle->uiCount; + + if (!Fifo_Add (pstHandle, NULL, uiPCount)) return NULL; + return &pstHandle->acStorage[pstHandle->uiActInd+uiCount]; + +} + +BOOL Fifo_Add(TYP_FIFO *pstHandle, char *acPBytes, unsigned int uiPCount) +{ + unsigned int uiFree; + + if (uiPCount == 0) return TRUE; + if (pstHandle->uiCapacity == 0) + { + if (!(pstHandle->acStorage = (char *)calloc(1, uiPCount))) + return FALSE; + if (acPBytes) + memcpy(pstHandle->acStorage, acPBytes, uiPCount); + else + memset(pstHandle->acStorage, 0, uiPCount); + pstHandle->uiCapacity = pstHandle->uiCount = uiPCount; + pstHandle->uiActInd = 0; + } + else + { + uiFree = pstHandle->uiCapacity-(pstHandle->uiActInd+pstHandle->uiCount); + if (uiFree < uiPCount) + { + if (pstHandle->uiActInd>=uiPCount && pstHandle->uiActInd*4>pstHandle->uiCount) + { + memmove(pstHandle->acStorage, pstHandle->acStorage+pstHandle->uiActInd, pstHandle->uiCount); + pstHandle->uiActInd = 0; + } + else + { + char *acBuf; + unsigned int uiNewLen; + + if (pstHandle->uiCapacity*2 < + pstHandle->uiCount+pstHandle->uiActInd+uiPCount) + uiNewLen = pstHandle->uiCount+pstHandle->uiActInd+uiPCount; + else + uiNewLen = pstHandle->uiCapacity*2; + acBuf = realloc(pstHandle->acStorage, uiNewLen); + if (acBuf == NULL) return FALSE; + pstHandle->acStorage = acBuf; + memset (acBuf+pstHandle->uiCapacity, 0, uiNewLen-pstHandle->uiCapacity); + pstHandle->uiCapacity = uiNewLen; + } + } + if (acPBytes) + memcpy (&pstHandle->acStorage[pstHandle->uiActInd+pstHandle->uiCount], acPBytes, uiPCount); + else + memset (&pstHandle->acStorage[pstHandle->uiActInd+pstHandle->uiCount], 0, uiPCount); + + pstHandle->uiCount += uiPCount; + } + + return TRUE; +} + +BOOL Fifo_AddString(TYP_FIFO *pstHandle, char *pszString) +{ + BOOL bRet; + + while (pstHandle->uiCount && pstHandle->acStorage[pstHandle->uiCount+pstHandle->uiActInd-1]==0) + pstHandle->uiCount--; + bRet = Fifo_Add (pstHandle, pszString, strlen(pszString)+1); + return bRet; +} + +char *Fifo_Get (TYP_FIFO *pstHandle, unsigned int *uiPCount) +{ + unsigned int uiCount; + char *pRet; + + if (!uiPCount) uiCount = pstHandle->uiCount; + else + { + if (pstHandle->uiCount < *uiPCount) + *uiPCount = pstHandle->uiCount; + uiCount = *uiPCount; + } + if (!uiCount) return NULL; + + pRet = &pstHandle->acStorage[pstHandle->uiActInd]; + pstHandle->uiActInd += uiCount; + pstHandle->uiCount -= uiCount; + return pRet; +} + +void Fifo_Reset (TYP_FIFO *pstHandle) +{ + pstHandle->uiCount = pstHandle->uiActInd = 0; +} + +unsigned int Fifo_Count (TYP_FIFO *pstHandle) +{ + return pstHandle->uiCount; +} diff --git a/plugins/!NotAdopted/IMO2sProxy/src/common/fifo.h b/plugins/!NotAdopted/IMO2sProxy/src/common/fifo.h new file mode 100644 index 0000000000..0ab9f4f469 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/common/fifo.h @@ -0,0 +1,26 @@ +#ifndef __FIFO_H__ +#define __FIFO_H__ + +struct _tagFIFO; +typedef struct _tagFIFO TYP_FIFO; + +#ifndef BOOL +#define BOOL int +#endif +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +TYP_FIFO *Fifo_Init(unsigned int uiCapacity); +void Fifo_Exit(TYP_FIFO *pstHandle); +char *Fifo_AllocBuffer(TYP_FIFO *pstHandle, unsigned int uiPCount); +BOOL Fifo_Add(TYP_FIFO *pstHandle, char *acPBytes, unsigned int uiPCount); +BOOL Fifo_AddString(TYP_FIFO *pstHandle, char *pszString); +char *Fifo_Get (TYP_FIFO *pstHandle, unsigned int *uiPCount); +unsigned int Fifo_Count (TYP_FIFO *pstHandle); +void Fifo_Reset (TYP_FIFO *hFifo); + +#endif diff --git a/plugins/!NotAdopted/IMO2sProxy/src/common/memlist.c b/plugins/!NotAdopted/IMO2sProxy/src/common/memlist.c new file mode 100644 index 0000000000..137a03eeac --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/common/memlist.c @@ -0,0 +1,158 @@ +#include "memlist.h" +#include +#include + +struct _tagLIST +{ + unsigned int uiCount; + unsigned int uiCapacity; + void **apStorage; +}; + +// ----------------------------------------------------------------------------- +// Interface +// ----------------------------------------------------------------------------- + +TYP_LIST *List_Init(unsigned int uiCapacity) +{ + TYP_LIST *pstHandle; + + pstHandle = (TYP_LIST *)malloc(sizeof(TYP_LIST)); + + if (!pstHandle) return NULL; + pstHandle->uiCount = 0; + pstHandle->uiCapacity = uiCapacity; + if (uiCapacity == 0) + pstHandle->apStorage = NULL; + else + { + pstHandle->apStorage = (void **)malloc(sizeof(void *)*uiCapacity); + if (!pstHandle->apStorage) + { + free(pstHandle); + return NULL; + } + } + return pstHandle; +} + +// ----------------------------------------------------------------------------- + +void List_Exit(TYP_LIST *pstHandle) +{ + if (pstHandle->apStorage) + free (pstHandle->apStorage); + free (pstHandle); +} + +// ----------------------------------------------------------------------------- + +BOOL List_Push(TYP_LIST *pstHandle, void *pItem) +{ + return List_InsertElementAt(pstHandle, pItem,pstHandle->uiCount); +} + +// ----------------------------------------------------------------------------- + +void *List_Pop (TYP_LIST *pstHandle) +{ + if (pstHandle->uiCount) + return List_RemoveElementAt(pstHandle ,pstHandle->uiCount-1); + else return NULL; +} + +// ----------------------------------------------------------------------------- + +BOOL List_ReplaceElementAt(TYP_LIST *pstHandle, void *pItem, unsigned int uiPos) +{ + if (uiPos >= pstHandle->uiCount) return NULL; + pstHandle->apStorage[uiPos]=pItem; + return TRUE; +} + +// ----------------------------------------------------------------------------- + +BOOL List_InsertElementAt(TYP_LIST *pstHandle, void *pItem, unsigned int uiPos) +{ + unsigned int uiStep; + void **apNewStorage; + + if (uiPos > pstHandle->uiCount) + uiPos = pstHandle->uiCount; + + if (pstHandle->uiCount >= pstHandle->uiCapacity) + { + uiStep = pstHandle->uiCount*2; + if (uiStep < 8) uiStep = 8; + + if (!pstHandle->apStorage) + apNewStorage = (void **)malloc(sizeof(void *)*uiStep); + else + apNewStorage = realloc (pstHandle->apStorage, sizeof(void *)*uiStep); + if (!apNewStorage) return FALSE; + pstHandle->apStorage = apNewStorage; + pstHandle->uiCapacity = uiStep; + } + + if (uiPosuiCount) + memmove(&pstHandle->apStorage[uiPos+1], &pstHandle->apStorage[uiPos], (pstHandle->uiCount-uiPos)*sizeof(void*)); + pstHandle->apStorage[uiPos] = pItem; + pstHandle->uiCount++; + return TRUE; +} + +// ----------------------------------------------------------------------------- + +void *List_RemoveElementAt(TYP_LIST *pstHandle, unsigned int uiPos) +{ + void *pRet; + + pRet = pstHandle->apStorage[uiPos]; + if (uiPosuiCount-1) + memmove (&pstHandle->apStorage[uiPos], &pstHandle->apStorage[uiPos+1], (pstHandle->uiCount-uiPos-1)*sizeof(void*)); + pstHandle->uiCount--; + return pRet; +} + +// ----------------------------------------------------------------------------- + +unsigned int List_Count(TYP_LIST *pstHandle) +{ + return pstHandle->uiCount; +} + +// ----------------------------------------------------------------------------- + +void *List_ElementAt(TYP_LIST *pstHandle,unsigned int uiPos) +{ + if (uiPos >= pstHandle->uiCount) return NULL; + return pstHandle->apStorage[uiPos]; +} + +// ----------------------------------------------------------------------------- + +void *List_Top(TYP_LIST *pstHandle) +{ + if (pstHandle->uiCount) + return List_ElementAt (pstHandle, pstHandle->uiCount-1); + else return NULL; +} + +// ----------------------------------------------------------------------------- + +void List_Sort(TYP_LIST *pstHandle, int (*pFunc)(const void*,const void*)) +{ + qsort(pstHandle->apStorage,pstHandle->uiCount,sizeof(void *),pFunc); +} + +// ----------------------------------------------------------------------------- + +void List_FreeElements(TYP_LIST *pstHandle) +{ + void *pEntry; + + while (pEntry = List_Pop(pstHandle)) + free (pEntry); +} + +// ----------------------------------------------------------------------------- diff --git a/plugins/!NotAdopted/IMO2sProxy/src/common/memlist.h b/plugins/!NotAdopted/IMO2sProxy/src/common/memlist.h new file mode 100644 index 0000000000..be37bbb723 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/common/memlist.h @@ -0,0 +1,30 @@ +#ifndef __LIST_H__ +#define __LIST_H__ + +#ifndef BOOL +#define BOOL int +#endif +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +struct _tagLIST; +typedef struct _tagLIST TYP_LIST; + +TYP_LIST *List_Init(unsigned int uiCapacity); +void List_Exit(TYP_LIST *pstHandle); +BOOL List_Push(TYP_LIST *pstHandle, void *pItem); +void *List_Pop (TYP_LIST *pstHandle); +BOOL List_ReplaceElementAt(TYP_LIST *pstHandle, void *pItem, unsigned int uiPos); +BOOL List_InsertElementAt(TYP_LIST *pstHandle, void *pItem, unsigned int uiPos); +void *List_RemoveElementAt(TYP_LIST *pstHandle, unsigned int uiPos); +unsigned int List_Count(TYP_LIST *pstHandle); +void *List_ElementAt(TYP_LIST *pstHandle,unsigned int uiPos); +void *List_Top(TYP_LIST *pstHandle); +void List_FreeElements(TYP_LIST *pstHandle); +void List_Sort(TYP_LIST *pstHandle, int (*pFunc)(const void*,const void*)); + +#endif diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/Makefile b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/Makefile new file mode 100644 index 0000000000..7e4420f87f --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/Makefile @@ -0,0 +1,19 @@ +CFLAGS = -O0 -g -I../common/ -I../imolib/ -lcurl -lpthread -lm +CC = gcc +COMMON = ../common/fifo.c ../common/cJSON.c ../common/memlist.c +IMOLIB = ../imolib/imo_request.c ../imolib/imo_skype.c ../imolib/io_layer.c +IMO2S = buddylist.c queue.c msgqueue.c imo2skypeapi.c callqueue.c socksproxy.c avatarlist.c +.PHONY: all imo2stest imo2sproxy clean + +all : imo2stest imo2sproxy + +imo2stest: $(COMMON) $(IMO2S) $(IMOLIB) imo2stest.c + $(CC) -o imo2stest $(COMMON) $(IMO2S) $(IMOLIB) imo2stest.c $(CFLAGS) + strip imo2stest + +imo2sproxy: $(COMMON) $(IMO2S) $(IMOLIB) imo2sproxy.c main.c + $(CC) -o imo2sproxy $(COMMON) $(IMO2S) $(IMOLIB) imo2sproxy.c main.c $(CFLAGS) +# strip imo2sproxy + +clean : + rm imo2stest imo2sproxy diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.c new file mode 100644 index 0000000000..f1c78f0567 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.c @@ -0,0 +1,110 @@ +/* Module: avatarlist.c + Purpose: Manages the avatars of your buddies + Author: leecher + Date: 18.08.2011 +*/ + +#include +#include +#include "memlist.h" +#include "avatarlist.h" + +static void SetEntry(AVATARENTRY *pEntry, cJSON *pNick); + +// ----------------------------------------------------------------------------- +// Interface +// ----------------------------------------------------------------------------- + +TYP_LIST *AvatarList_Init(void) +{ + TYP_LIST *hList = List_Init(16); + + return hList; +} + +// ----------------------------------------------------------------------------- + +void AvatarList_Exit(TYP_LIST *hList) +{ + AVATARENTRY *pEntry; + + while (pEntry=(AVATARENTRY*)List_Pop(hList)) + { + AvatarList_FreeEntry(pEntry); + free (pEntry); + } + List_Exit(hList); +} + +// ----------------------------------------------------------------------------- + +BOOL AvatarList_Insert(TYP_LIST *hList, cJSON *pIcon) +{ + AVATARENTRY *pEntry; + + if (pEntry=AvatarList_Find (hList, cJSON_GetObjectItem(pIcon, "buid")->valuestring)) + AvatarList_FreeEntry (pEntry); + else + { + if (!(pEntry = calloc (1, sizeof(AVATARENTRY)))) return FALSE; + if (!List_Push(hList, pEntry)) return FALSE; + } + SetEntry(pEntry, pIcon); + return TRUE; +} + +// ----------------------------------------------------------------------------- + +BOOL AvatarList_Remove(TYP_LIST *hList, AVATARENTRY *pEntry) +{ + AVATARENTRY *pListEntry; + int i, nCount; + + for (i=0, nCount=List_Count(hList); ipszUser, pszUser) == 0) + return pEntry; + } + return NULL; +} + +// ----------------------------------------------------------------------------- + +void AvatarList_FreeEntry(AVATARENTRY *pEntry) +{ + if (pEntry->pszUser) free (pEntry->pszUser); + if (pEntry->pszIcon) free (pEntry->pszIcon); +} + +// ----------------------------------------------------------------------------- +// Static +// ----------------------------------------------------------------------------- + +static void SetEntry(AVATARENTRY *pEntry, cJSON *pNick) +{ + pEntry->pszUser = strdup(cJSON_GetObjectItem(pNick, "buid")->valuestring); + pEntry->pszIcon = strdup(cJSON_GetObjectItem(pNick, "icon")->valuestring); +} diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.h new file mode 100644 index 0000000000..6a47ed2fa5 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.h @@ -0,0 +1,16 @@ +#include "cJSON.h" +#include "memlist.h" + +typedef struct +{ + char *pszUser; + char *pszIcon; +} AVATARENTRY; + +TYP_LIST *AvatarList_Init(void); +void AvatarList_Exit(TYP_LIST *hList); + +BOOL AvatarList_Insert(TYP_LIST *hList, cJSON *pIcon); +BOOL AvatarList_Remove(TYP_LIST *hList, AVATARENTRY *pEntry); +AVATARENTRY *AvatarList_Find(TYP_LIST *hList, char *pszUser); +void AvatarList_FreeEntry(AVATARENTRY *pEntry); diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.c new file mode 100644 index 0000000000..6d228ae4b9 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.c @@ -0,0 +1,204 @@ +/* Module: buddylist.c + Purpose: Manages your list of buddies in memory + Author: leecher + Date: 30.08.2009 +*/ + +#include +#include +#include +#include "memlist.h" +#include "buddylist.h" + +static void SetEntry(NICKENTRY *pEntry, cJSON *pNick); + +// ----------------------------------------------------------------------------- +// Interface +// ----------------------------------------------------------------------------- + +TYP_LIST *BuddyList_Init(void) +{ + TYP_LIST *hList = List_Init(16); + + return hList; +} + +// ----------------------------------------------------------------------------- + +void BuddyList_Exit(TYP_LIST *hList) +{ + NICKENTRY *pEntry; + + while (pEntry=(NICKENTRY*)List_Pop(hList)) + { + BuddyList_FreeEntry(pEntry, TRUE); + free (pEntry); + } + List_Exit(hList); +} + +// ----------------------------------------------------------------------------- + +BOOL BuddyList_Insert(TYP_LIST *hList, cJSON *pNick) +{ + NICKENTRY *pEntry; + cJSON *pElem; + + if (pEntry=BuddyList_Find (hList, cJSON_GetObjectItem(pNick, "buid")->valuestring)) + BuddyList_FreeEntry (pEntry, FALSE); + else + { + if (!(pEntry = calloc (1, sizeof(NICKENTRY)))) return FALSE; + if ((pElem=cJSON_GetObjectItem(pNick, "group")) && strcmp(pElem->valuestring, "Skype")) + { + char szBUID[256]; + NICKENTRY *pGroup; + + // Buddy Belongs to a chatgroup + sprintf (szBUID, "%s;", pElem->valuestring); + pGroup = BuddyList_Find (hList, szBUID); + + if (pGroup) // Group not yet created? Shouldn't be the case + { + if (!pGroup->hGCMembers) pGroup->hGCMembers=List_Init(1); + hList = pGroup->hGCMembers; + pEntry->pGroup = pGroup; + } + } + if (!List_Push(hList, pEntry)) return FALSE; + } + SetEntry(pEntry, pNick); + pEntry->iBuddyStatus = 3; + return TRUE; +} + +// ----------------------------------------------------------------------------- + +BOOL BuddyList_AddTemporaryUser(TYP_LIST *hList, char *pszUser) +{ + NICKENTRY *pEntry; + + if (BuddyList_Find (hList, pszUser)) return TRUE; + if (!(pEntry = calloc (1, sizeof(NICKENTRY)))) return FALSE; + pEntry->pszUser = strdup(pszUser); + pEntry->pszAlias = strdup(pszUser); + strcpy (pEntry->szStatus, "OFFLINE"); + pEntry->iBuddyStatus = 2; + return List_Push(hList, pEntry); +} + +// ----------------------------------------------------------------------------- + +BOOL BuddyList_Remove(TYP_LIST *hList, NICKENTRY *pEntry) +{ + NICKENTRY *pListEntry; + int i, nCount; + + if (pEntry->pGroup) hList=pEntry->pGroup->hGCMembers; + for (i=0, nCount=List_Count(hList); ipszUser, pszUser) == 0) + return pEntry; + else if (pEntry->hGCMembers) + { + if (pEntry = BuddyList_Find(pEntry->hGCMembers, pszUser)) + return pEntry; + } + } + return NULL; +} + +// ----------------------------------------------------------------------------- + +BOOL BuddyList_SetStatus(TYP_LIST *hList, cJSON *pNick) +{ + NICKENTRY *pEntry; + + if ((pEntry = BuddyList_Find(hList, cJSON_GetObjectItem(pNick, "buid")->valuestring))) + { + BuddyList_FreeEntry(pEntry, FALSE); + SetEntry(pEntry, pNick); + return TRUE; + } + return FALSE; +} + +// ----------------------------------------------------------------------------- + +void BuddyList_FreeEntry(NICKENTRY *pEntry, BOOL bFreeGC) +{ + if (pEntry->pszAlias) + { + free (pEntry->pszAlias); + pEntry->pszAlias = NULL; + } + if (pEntry->pszUser) + { + free (pEntry->pszUser); + pEntry->pszUser = NULL; + } + if (pEntry->pszStatusText) + { + free(pEntry->pszStatusText); + pEntry->pszStatusText = NULL; + } + if (pEntry->pszDisplay) + { + free(pEntry->pszDisplay); + pEntry->pszDisplay = NULL; + } + if (bFreeGC && pEntry->hGCMembers) + { + NICKENTRY *pNick; + + while (pNick=(NICKENTRY*)List_Pop(pEntry->hGCMembers)) + { + BuddyList_FreeEntry(pNick, bFreeGC); + free (pNick); + } + List_Exit (pEntry->hGCMembers); + pEntry->hGCMembers = NULL; + } +} + +// ----------------------------------------------------------------------------- +// Static +// ----------------------------------------------------------------------------- + +static void SetEntry(NICKENTRY *pEntry, cJSON *pNick) +{ + cJSON *obj; + + if ((obj=cJSON_GetObjectItem(pNick, "alias")) && obj->valuestring) + pEntry->pszAlias = strdup(obj->valuestring); + pEntry->pszUser = strdup(cJSON_GetObjectItem(pNick, "buid")->valuestring); + if ((obj=cJSON_GetObjectItem(pNick, "status")) && obj->valuestring) + pEntry->pszStatusText = strdup(obj->valuestring); + if ((obj=cJSON_GetObjectItem(pNick, "primitive")) && obj->valuestring) + strcpy (pEntry->szStatus, obj->valuestring); + if ((obj=cJSON_GetObjectItem(pNick, "display")) && obj->valuestring) + pEntry->pszDisplay = strdup(obj->valuestring); +} diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.h new file mode 100644 index 0000000000..3774ef3e5e --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.h @@ -0,0 +1,28 @@ +#include "cJSON.h" +#include "memlist.h" + +struct tag_nickentry; +typedef struct tag_nickentry NICKENTRY; + +struct tag_nickentry +{ + char *pszUser; + char *pszStatusText; + char szStatus[16]; + char *pszAlias; + char *pszDisplay; // Display name, on Groupchat it is topic + int iBuddyStatus; + TYP_LIST *hGCMembers; // List of groupchat members, if this is a groupchat + NICKENTRY *pGroup; // Uplink to Chatgroup, if Groupchat-Member +}; + +TYP_LIST *BuddyList_Init(void); +void BuddyList_Exit(TYP_LIST *hList); + +BOOL BuddyList_Insert(TYP_LIST *hList, cJSON *pNick); +BOOL BuddyList_AddTemporaryUser(TYP_LIST *hList, char *pszUser); +BOOL BuddyList_Remove(TYP_LIST *hList, NICKENTRY *pEntry); +NICKENTRY *BuddyList_Find(TYP_LIST *hList, char *pszUser); +BOOL BuddyList_SetStatus(TYP_LIST *hList, cJSON *pNick); +void BuddyList_FreeEntry(NICKENTRY *pEntry, BOOL bFreeGC); +#define BuddyList_IsGroupchat(pEntry) (pEntry->hGCMembers!=NULL) diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.c new file mode 100644 index 0000000000..f579eb184e --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.c @@ -0,0 +1,95 @@ +/* Module: callqueue.c + Purpose: Queue for incoming calls + Author: leecher + Date: 02.09.2009 + + Fixme: Sort on insert, do a binary search instead of iterating list. +*/ + +#include +#include +#include +#include "callqueue.h" + +static volatile unsigned int m_uMsgNr=0; +static void FreeEntry(void *pPEntry); + +// ----------------------------------------------------------------------------- +// Interface +// ----------------------------------------------------------------------------- + +TYP_LIST *CallQueue_Init(void) +{ + TYP_LIST *hList = List_Init(16); + + return hList; +} + +// ----------------------------------------------------------------------------- + +void CallQueue_Exit(TYP_LIST *hList) +{ + Queue_Exit (hList, FreeEntry); +} + +// ----------------------------------------------------------------------------- + +CALLENTRY *CallQueue_Insert(TYP_LIST *hList, cJSON *pNick, int iDirection) +{ + CALLENTRY *pEntry; + cJSON *pStream, *pVal, *pPipe; + + if (!(pEntry = Queue_InsertEntry(hList, sizeof(CALLENTRY), ++m_uMsgNr, + FreeEntry))) return NULL; + pEntry->pszUser = strdup(cJSON_GetObjectItem(pNick, "buid")->valuestring); + time (&pEntry->timestamp); + strcpy (pEntry->szStatus, "RINGING"); + + if (pStream = cJSON_GetObjectItem(pNick, "send_stream")) + { + strcpy (pEntry->szSendStream, pStream->valuestring); + if (pStream = cJSON_GetObjectItem(pNick, "recv_stream")) + strcpy (pEntry->szRecvStream, pStream->valuestring); + } + else + { + // Copy pipe to Call object + if (pPipe = cJSON_GetObjectItem(pNick, "pipe")) + { + if (pVal = cJSON_GetObjectItem(pPipe, "ip")) + strncpy (pEntry->szIP, pVal->valuestring, sizeof(pEntry->szIP)); + if (pVal = cJSON_GetObjectItem(pPipe, "conv")) + strncpy (pEntry->szConv, pVal->valuestring, sizeof(pEntry->szConv)); + if (pVal = cJSON_GetObjectItem(pPipe, "role")) + pEntry->iRole = pVal->valueint; + } + } + pEntry->iDirection = iDirection; + return pEntry; +} + +// ----------------------------------------------------------------------------- + +BOOL CallQueue_Remove(TYP_LIST *hList, unsigned int uMsgNr) +{ + return Queue_Remove (hList, uMsgNr, FreeEntry); +} + +// ----------------------------------------------------------------------------- + +CALLENTRY *CallQueue_Find(TYP_LIST *hList, unsigned int uMsgNr) +{ + return (CALLENTRY*)Queue_Find(hList, uMsgNr); +} + +// ----------------------------------------------------------------------------- +// Static +// ----------------------------------------------------------------------------- + +static void FreeEntry(void *pPEntry) +{ + CALLENTRY *pEntry = (CALLENTRY*)pPEntry; + + free (pEntry->pszUser); +} + diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.h new file mode 100644 index 0000000000..0c4fcfd2cf --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.h @@ -0,0 +1,32 @@ +#include "cJSON.h" +#include "queue.h" +#include + +#define CALL_INCOMING 0 +#define CALL_OUTGOING 1 + +typedef struct +{ + QUEUEHDR hdr; + char *pszUser; + char szStatus[16]; + + char szSendStream[18]; + char szRecvStream[18]; + + char szConv[18]; + char szIP[16]; + int iRole; + + char szCallFile[256]; + void *hCallWnd; + int iDirection; + time_t timestamp; +} CALLENTRY; + +TYP_LIST *CallQueue_Init(void); +void CallQueue_Exit(TYP_LIST *hList); + +CALLENTRY *CallQueue_Insert(TYP_LIST *hList, cJSON *pNick, int iDirection); +BOOL CallQueue_Remove(TYP_LIST *hList, unsigned int uCallNr); +CALLENTRY *CallQueue_Find(TYP_LIST *hList, unsigned int uCallNr); diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/crash.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/crash.c new file mode 100644 index 0000000000..91ad90032e --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/crash.c @@ -0,0 +1,295 @@ +#include +#include +#pragma comment (lib, "imagehlp.lib") + +#define MAXNAMELEN 1024 +#define HEXDUMP_BREAK 16 + +void HexDump(char *pszOutput, PBYTE pData, int cbLength, BOOL bShow) +{ + char *pszLastLine; + int i; + + *pszOutput=0; + pszLastLine = pszOutput; + for (i=0; i=HEXDUMP_BREAK) + { + int j; + + strcat (pszOutput, " "); + for (j=i-HEXDUMP_BREAK; j (DWORD)sysInfo.lpMaximumApplicationAddress) + return; + + if (ReadProcessMemory (GetCurrentProcess(), (PVOID)dwBase, mem, cbLength, &read)) + { + char *pszHexdump = (char *)alloca (((cbLength/HEXDUMP_BREAK)+1)*81); + + LOG (("Memory dump for %s:\n", pszName)); + HexDump (pszHexdump, mem, read, TRUE); + LOG (("\n")); + } +} + + +BOOL ShowThreadStack (HANDLE hThread, CONTEXT *c) +{ + STACKFRAME stFrame={0}; + DWORD dwSymOptions, dwFrameNum=0, dwMachine, dwOffsetFromSym=0; + IMAGEHLP_LINE Line={0}; + IMAGEHLP_MODULE Module={0}; + HANDLE hProcess = GetCurrentProcess(); + BYTE pbSym[sizeof(IMAGEHLP_SYMBOL) + MAXNAMELEN]; + IMAGEHLP_SYMBOL *pSym = (IMAGEHLP_SYMBOL *)&pbSym; + char szUndecName[MAXNAMELEN], szUndecFullName[MAXNAMELEN]; + + /* + if ( ! GetThreadContext( hThread, &c ) ) + { + SetError (NULL, NULL, 0); + LOG (("Cannot get thread context%d\n", GetLastError())); + return FALSE; + } + */ + LOG (("Please wait...\n")); + if (!SymInitialize (hProcess, NULL, TRUE)) + { + LOG (("Cannot initialize symbol engine (%08X)\n", GetLastError())); + return FALSE; + } + + dwSymOptions = SymGetOptions(); + dwSymOptions |= SYMOPT_LOAD_LINES; + dwSymOptions &= ~SYMOPT_UNDNAME; + SymSetOptions (dwSymOptions); + + stFrame.AddrPC.Mode = AddrModeFlat; + dwMachine = IMAGE_FILE_MACHINE_I386; + stFrame.AddrPC.Offset = c->Eip; + stFrame.AddrStack.Offset = c->Esp; + stFrame.AddrStack.Mode = AddrModeFlat; + stFrame.AddrFrame.Offset = c->Ebp; + stFrame.AddrFrame.Mode = AddrModeFlat; + + Module.SizeOfStruct = sizeof(Module); + Line.SizeOfStruct = sizeof(Module); + + LOG (("\n--# FV EIP----- RetAddr- FramePtr StackPtr Symbol\n")); + do + { + if (!StackWalk (dwMachine, hProcess, hThread, &stFrame, &c, NULL, &SymFunctionTableAccess, &SymGetModuleBase, NULL)) + break; + + LOG (( "\n%3d %c%c %08lx %08lx %08lx %08lx ", + dwFrameNum, stFrame.Far? 'F': '.', stFrame.Virtual? 'V': '.', + stFrame.AddrPC.Offset, stFrame.AddrReturn.Offset, + stFrame.AddrFrame.Offset, stFrame.AddrStack.Offset )); + + if (stFrame.AddrPC.Offset == 0) + { + LOG (( "(-nosymbols-)\n" )); + } + else + { // we seem to have a valid PC + if (!SymGetSymFromAddr (hProcess, stFrame.AddrPC.Offset, &dwOffsetFromSym, pSym)) + { + if (GetLastError() != 487) + { + LOG (("Unable to get symbol from addr (%08X)", GetLastError())); + } + } + else + { + UnDecorateSymbolName (pSym->Name, szUndecName, MAXNAMELEN, UNDNAME_NAME_ONLY ); + UnDecorateSymbolName (pSym->Name, szUndecFullName, MAXNAMELEN, UNDNAME_COMPLETE ); + LOG (("%s", szUndecName)); + if (dwOffsetFromSym) LOG ((" %+ld bytes", (long)dwOffsetFromSym)); + LOG (("\n Sig: %s\n Decl: %s\n", pSym->Name, szUndecFullName)); + } + + if (!SymGetLineFromAddr (hProcess, stFrame.AddrPC.Offset, &dwOffsetFromSym, &Line)) + { + if (GetLastError() != 487) + { + LOG (("Unable to get line from addr (%08X)", GetLastError())); + } + } + else + { + LOG ((" Line: %s(%lu) %+ld bytes\n", Line.FileName, Line.LineNumber, dwOffsetFromSym )); + } + + if (!SymGetModuleInfo (hProcess, stFrame.AddrPC.Offset, &Module)) + { + if (GetLastError() != 487) + { + LOG (("Unable to get module info (%08X)", GetLastError())); + } + } + else + { + char ty[80]; + + switch ( Module.SymType ) + { + case SymNone: + strcpy( ty, "-nosymbols-" ); + break; + case SymCoff: + strcpy( ty, "COFF" ); + break; + case SymCv: + strcpy( ty, "CV" ); + break; + case SymPdb: + strcpy( ty, "PDB" ); + break; + case SymExport: + strcpy( ty, "-exported-" ); + break; + case SymDeferred: + strcpy( ty, "-deferred-" ); + break; + case SymSym: + strcpy( ty, "SYM" ); + break; + default: + _snprintf( ty, sizeof ty, "symtype=%ld", (long) Module.SymType ); + break; + + } + LOG (( " Mod: %s[%s], base: %08lxh\n", Module.ModuleName, Module.ImageName, Module.BaseOfImage )); + LOG (( " Sym: type: %s, file: %s\n", ty, Module.LoadedImageName)); + } + } + dwFrameNum++; + } while (stFrame.AddrReturn.Offset); + SymCleanup (hProcess); + return TRUE; +} + + +LONG Win32FaultHandler(struct _EXCEPTION_POINTERS * ExInfo) +{ + char *FaultTx; + int wsFault = ExInfo->ExceptionRecord->ExceptionCode; + PVOID CodeAdress = ExInfo->ExceptionRecord->ExceptionAddress; +#ifndef USE_GUI + char choice[10]; +#endif + + if (//IsDebuggerPresent() || + ExInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) + return EXCEPTION_CONTINUE_SEARCH; + + switch(ExInfo->ExceptionRecord->ExceptionCode) + { + case EXCEPTION_ACCESS_VIOLATION : FaultTx = "ACCESS VIOLATION"; break; + case EXCEPTION_DATATYPE_MISALIGNMENT : FaultTx = "DATATYPE MISALIGNMENT"; break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO : FaultTx = "FLT DIVIDE BY ZERO"; break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED : FaultTx = "ARRAY BOUNDS EXCEEDED"; break; + case EXCEPTION_FLT_DENORMAL_OPERAND : FaultTx = "FLT DENORMAL OPERAND"; break; + case EXCEPTION_FLT_INEXACT_RESULT : FaultTx = "FLT INEXACT RESULT"; break; + case EXCEPTION_FLT_INVALID_OPERATION : FaultTx = "FLT INVALID OPERATION"; break; + case EXCEPTION_FLT_OVERFLOW : FaultTx = "FLT OVERFLOW"; break; + case EXCEPTION_FLT_STACK_CHECK : FaultTx = "FLT STACK CHECK"; break; + case EXCEPTION_FLT_UNDERFLOW : FaultTx = "FLT UNDERFLOW"; break; + case EXCEPTION_ILLEGAL_INSTRUCTION : FaultTx = "ILLEGAL INSTRUCTION"; break; + case EXCEPTION_IN_PAGE_ERROR : FaultTx = "IN PAGE ERROR"; break; + case EXCEPTION_INT_DIVIDE_BY_ZERO : FaultTx = "INT DEVIDE BY ZERO"; break; + case EXCEPTION_INT_OVERFLOW : FaultTx = "INT OVERFLOW"; break; + case EXCEPTION_INVALID_DISPOSITION : FaultTx = "INVALID DISPOSITION"; break; + case EXCEPTION_NONCONTINUABLE_EXCEPTION:FaultTx= "NONCONTINUABLE EXCEPTION"; break; + case EXCEPTION_PRIV_INSTRUCTION : FaultTx = "PRIVILEGED INSTRUCTION";break; + case EXCEPTION_SINGLE_STEP : FaultTx = "SINGLE STEP"; break; + case EXCEPTION_STACK_OVERFLOW : FaultTx = "STACK OVERFLOW"; break; + case DBG_CONTROL_C : return EXCEPTION_EXECUTE_HANDLER; + default : FaultTx = "(unknown)"; break; + } + + LOG (("****************************************************\n")); + LOG (("*** A Program Fault occurred: ***\n")); + LOG (("*** Error code %08X: %-24s***\n", wsFault, FaultTx)); + LOG (("****************************************************\n")); + LOG (("*** Address: %08X Flags: %08X ***\n", (int)CodeAdress, ExInfo->ExceptionRecord->ExceptionFlags)); + LOG (("*** EAX=%08X EBX=%08X ECX=%08X ***\n", ExInfo->ContextRecord->Eax, ExInfo->ContextRecord->Ebx, ExInfo->ContextRecord->Ecx)); + LOG (("*** EDX=%08X EBP=%08X ESI=%08X ***\n", ExInfo->ContextRecord->Edx, ExInfo->ContextRecord->Ebp, ExInfo->ContextRecord->Esi)); + LOG (("*** EDI=%08X ESP=%08X EIP=%08X ***\n", ExInfo->ContextRecord->Edi, ExInfo->ContextRecord->Esp, ExInfo->ContextRecord->Eip)); + LOG (("****************************************************\n")); + CrashDumpMem (ExInfo->ContextRecord->Eax, "EAX", 8); + CrashDumpMem (ExInfo->ContextRecord->Ebx, "EBX", 8); + CrashDumpMem (ExInfo->ContextRecord->Ecx, "ECX", 8); + CrashDumpMem (ExInfo->ContextRecord->Edx, "EDX", 8); + CrashDumpMem (ExInfo->ContextRecord->Esi, "ESI", 8); + CrashDumpMem (ExInfo->ContextRecord->Edi, "EDI", 8); + CrashDumpMem (ExInfo->ContextRecord->Esp, "ESP", 32); + CrashDumpMem (ExInfo->ContextRecord->Ebp, "EBP", 32); + { + OSVERSIONINFO ov={0}; + + ov.dwOSVersionInfoSize=sizeof(ov); + GetVersionEx (&ov); + LOG (("Target platform: Microsoft Windows NT %d.%d Build %d %s\n", ov.dwMajorVersion, ov.dwMinorVersion, + ov.dwBuildNumber, ov.szCSDVersion)); + } + + //LogStackFrames(CodeAddress, (char *)ExInfo->ContextRecord->Ebp); + ShowThreadStack (GetCurrentThread(), ExInfo->ContextRecord); + +#ifdef USE_GUI + if (MessageBox(NULL, "A Program Fault occurred. Do you want to continue execution (not recommended)?", "CRASH!", MB_ICONERROR | MB_YESNO) == IDYES) +#else + printf ("Do you want to continue program execution (not recommended) [y/N]? "); + fgets(choice, sizeof(choice) - 1, stdin); + + if (*choice=='y' || *choice=='Y') +#endif + { + ExInfo->ContextRecord->Eip++; + return EXCEPTION_CONTINUE_EXECUTION; + } + return EXCEPTION_EXECUTE_HANDLER; +} + +void Crash_Init(void) +{ +//#ifndef _DEBUG + SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER) Win32FaultHandler); +//#endif +} diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/crash.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/crash.h new file mode 100644 index 0000000000..7f2d790f6c --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/crash.h @@ -0,0 +1 @@ +void Crash_Init(void); diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.c new file mode 100644 index 0000000000..de0a9b4028 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.c @@ -0,0 +1,1959 @@ +/* Module: imo2skypeapi.c + Purpose: Simple wrapper for imo.im Webservice to SKYPE API to maintain compatibility with Skype-Plugins + Author: leecher + Date: 30.08.2009 +*/ + +#define VOICECALL_VERSION 1221873445 +#define IVC_VERSION "98a29c15e305a7af04634b03d5e1425d6c67806e" + +#include +#include +#include +#include +#include +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include "w32browser.h" +#define strcasecmp stricmp +#define strncasecmp strnicmp +#define thread_t HANDLE +#define vsnprintf _vsnprintf +#define GWL_PINST 0 +#define GWL_ORIGWPRC 1*sizeof(PVOID) +#else +#define thread_t pthread_t +#include +#include +#endif +#include "imo_skype.h" +#include "imo_request.h" +#include "fifo.h" +#include "memlist.h" +#include "buddylist.h" +#include "avatarlist.h" +#include "msgqueue.h" +#include "callqueue.h" +#include "imo2skypeapi.h" + +typedef struct +{ + char *pszImoStat; + char *pszSkypeStat; +} STATMAP; + +struct _tagIMOSAPI +{ + IMOSKYPE *hInst; + NICKENTRY myUser; + char *pszPass; + char *pszLogBuf; + char *pszClientName; + int cbBuf; + TYP_LIST *hBuddyList; + TYP_LIST *hAvatarList; + TYP_LIST *hMsgQueue; + TYP_LIST *hCallQueue; + int iProtocol; + int iLoginStat; + IMO2SCB Callback; + void *pUser; + FILE *fpLog; + thread_t hThread; + int bFriendsPending; + int iFlags; + int iShuttingDown; + volatile time_t tSetMoodText; + char *pszCmdID; + char *pszBuddiesToAdd; +}; + +static STATMAP m_stMap[] = +{ + {"available", "ONLINE"}, + {"available", "SKYPEME"}, + {"offline", "OFFLINE"}, + {"away", "AWAY"}, + {"busy", "DND"}, + {"busy", "NA"}, + {"invisible", "INVISIBLE"} +}; + +static int StartCallSWF (IMOSAPI *pInst, CALLENTRY *pCall); +static int StatusCallback (cJSON *pMsg, void *pUser); +static void DispatcherThread(void *pUser); +static int Dispatcher_Start(IMOSAPI *pInst); +static int Dispatcher_Stop(IMOSAPI *pInst); +static void Send(IMOSAPI *pInst, const char *pszMsg, ...); +static void HandleMessage(IMOSAPI *pInst, char *pszMsg); + + +// ----------------------------------------------------------------------------- +// Interface +// ----------------------------------------------------------------------------- + +IMOSAPI *Imo2S_Init(IMO2SCB Callback, void *pUser, int iFlags) +{ + IMOSAPI *pInst = calloc(1, sizeof(IMOSAPI)); + + if (!pInst) return NULL; + if (!(pInst->pszLogBuf = malloc(pInst->cbBuf=512)) || + !(pInst->hInst = ImoSkype_Init(StatusCallback, pInst)) || + !(pInst->hBuddyList = BuddyList_Init()) || + !(pInst->hAvatarList = AvatarList_Init()) || + !(pInst->hMsgQueue = MsgQueue_Init()) || +#ifdef WIN32 + ((iFlags & IMO2S_FLAG_ALLOWINTERACT) && W32Browser_Init(0)==-1) || +#endif + !(pInst->hCallQueue = CallQueue_Init())) + { + Imo2S_Exit(pInst); + return NULL; + } + pInst->Callback = Callback; + pInst->pUser = pUser; + pInst->iFlags = iFlags; + pInst->myUser.iBuddyStatus = 3; + strcpy (pInst->myUser.szStatus, "OFFLINE"); + pInst->iProtocol = 3; + return pInst; +} + +// ----------------------------------------------------------------------------- + +void Imo2S_SetLog (IMOSAPI *pInst, FILE *fpLog) +{ + pInst->fpLog = fpLog; +} + +// ----------------------------------------------------------------------------- + +void Imo2S_Exit (IMOSAPI *pInst) +{ + if (!pInst) return; + pInst->iShuttingDown = 1; + if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S_Exit()\n"); + if (pInst->iLoginStat == 1) Imo2S_Logout(pInst); + if (pInst->hInst) ImoSkype_Exit(pInst->hInst); + if (pInst->hBuddyList) BuddyList_Exit(pInst->hBuddyList); + if (pInst->hAvatarList) AvatarList_Exit(pInst->hAvatarList); + if (pInst->hMsgQueue) MsgQueue_Exit(pInst->hMsgQueue); + if (pInst->hCallQueue) CallQueue_Exit(pInst->hCallQueue); + if (pInst->pszPass) free (pInst->pszPass); + if (pInst->pszLogBuf) free(pInst->pszLogBuf); + if (pInst->pszClientName) free(pInst->pszClientName); +#ifdef WIN32 + if (pInst->iFlags & IMO2S_FLAG_ALLOWINTERACT) W32Browser_Exit(); +#endif + BuddyList_FreeEntry(&pInst->myUser, TRUE); + memset (pInst, 0, sizeof(IMOSAPI)); + free (pInst); +} + +// ----------------------------------------------------------------------------- + +int Imo2S_Login (IMOSAPI *pInst, char *pszUser, char *pszPass, char **ppszError) +{ + // In case this module is passing in the original values... + char *pszLocalUser, *pszLocalPass; + + if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S_Login(%s, ****)\n", pszUser); + if (pInst->iLoginStat == 1) return pInst->iLoginStat; + if (!pInst->hInst) pInst->hInst=ImoSkype_Init(StatusCallback, pInst); + pszLocalUser = strdup(pszUser); + if (pInst->myUser.pszUser) free (pInst->myUser.pszUser); + pInst->myUser.pszUser = pszLocalUser; + pszLocalPass = strdup(pszPass); + if (pInst->pszPass) free (pInst->pszPass); + pInst->pszPass = pszLocalPass; + Send(pInst, "CONNSTATUS CONNECTING"); + pInst->iLoginStat = ImoSkype_Login(pInst->hInst, pszLocalUser, pszLocalPass); + if (pInst->iLoginStat == 1) + { + ImoSkype_GetUnreadMsgs(pInst->hInst); + if (IMO_API_VERSION > 0) ImoSkype_GetAlpha(pInst->hInst); + Dispatcher_Start(pInst); + } + else + if (ppszError) *ppszError = ImoSkype_GetLastError(pInst->hInst); + return pInst->iLoginStat; +} + +// ----------------------------------------------------------------------------- + +void Imo2S_Logout(IMOSAPI *pInst) +{ + if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S_Logout()\n"); + Dispatcher_Stop(pInst); + if (ImoSkype_Logout(pInst->hInst) == 1) + { + pInst->iLoginStat = 0; + strcpy (pInst->myUser.szStatus, "OFFLINE"); + } + + + // If we relogin, user information won't be re-propagated if we + // reuse the same connection. Therefore also dispose the connection + // to imo.im service (wouldn't be necessary, but to ensure proper + // repropagation of contacts on login, we have to do it, sorry) + if (!pInst->iShuttingDown) + { + ImoSkype_Exit(pInst->hInst); + pInst->hInst = NULL; + } +} + +// ----------------------------------------------------------------------------- + +int Imo2S_Send (IMOSAPI *pInst, char *pszMsg) +{ + char *pszDup = strdup(pszMsg); + char *pszRealMsg = pszMsg; + + if (*pszRealMsg=='#') + { + char *p; + if (p = strchr (pszRealMsg, ' ')) pszRealMsg=p+1; + } + if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S_Send(%s)\n", pszMsg); + if (strlen(pszRealMsg)>15 && strncasecmp (pszRealMsg, "SET ", 4)== 0 && + (strncasecmp (pszRealMsg+4, "USERSTATUS", 10)==0 || + strncasecmp (pszRealMsg+4, "CONNSTATUS", 10)==0)) + { +// if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S_Send: iLoginStat = %d\n", +// pInst->iLoginStat); + if (pInst->iLoginStat == 0) + { + if (pInst->myUser.pszUser && pInst->pszPass && strncasecmp (pszRealMsg+15, "OFFLINE", 7)) + { + Imo2S_Login(pInst, pInst->myUser.pszUser, pInst->pszPass, NULL); + } + } + else + { + HandleMessage (pInst, pszDup); + if (strncasecmp (pszRealMsg+15, "OFFLINE", 7) == 0) + Imo2S_Logout(pInst); + free (pszDup); + return 0; + } + } + if (pInst->iLoginStat != 1) return -1; + HandleMessage(pInst, pszDup); + free (pszDup); + return 0; +} + +// ----------------------------------------------------------------------------- +// Static +// ----------------------------------------------------------------------------- + + +static int StatusCallback (cJSON *pMsg, void *pUser) +{ + char *pszName; + BOOL bAdded; + cJSON *pContent, *pProto; + IMOSAPI *pInst = (IMOSAPI*)pUser; + int m, iSize = cJSON_GetArraySize(pMsg); + + if (pInst->fpLog) + { + char *pszMsg = cJSON_Print(pMsg); + fprintf (pInst->fpLog, "Imo2S::StatusCallback():%s\n", pszMsg); + free(pszMsg); + } + + for (m=0; mvaluestring; + + if ((pProto = cJSON_GetObjectItem(pContent,"proto")) && strcasecmp (pProto->valuestring, "prpl-skype")) + continue; + + if (!strcmp(pszName, "recv_im")) + { + // I got a message! + cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"); + + if (pEdata) + { + MSGENTRY *pMsg; + + // imo.im sometimes seems to send information about messages you sent yourself. + // We have to ignore them. + if (strcmp(cJSON_GetObjectItem(pEdata, "buid")->valuestring, pInst->myUser.pszUser) && + (pMsg = MsgQueue_Insert(pInst->hMsgQueue, pEdata))) + { + if (pInst->iFlags & IMO2S_FLAG_CURRTIMESTAMP) time(&pMsg->timestamp); + Send(pInst, "%sMESSAGE %d STATUS %s", pInst->iProtocol>=3?"CHAT":"", + pMsg->hdr.uMsgNr, pMsg->szStatus); + } + } + } + else if (!strcmp(pszName, "signed_on")) + { + // I just signed on. + cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"); + char *pszAlias; + + Send(pInst, "CONNSTATUS ONLINE"); + if (strcmp(pInst->myUser.szStatus, "OFFLINE")==0) + strcpy (pInst->myUser.szStatus, "ONLINE"); + Send(pInst, "USERSTATUS %s", pInst->myUser.szStatus); + if (pEdata && (pszAlias = cJSON_GetObjectItem(pEdata, "alias")->valuestring)) + { + pInst->myUser.pszAlias = strdup(pszAlias); + } + Send(pInst, "CURRENTUSERHANDLE %s", cJSON_GetObjectItem(pContent, "uid")->valuestring); + } + else if (!strcmp(pszName, "buddy_icon")) + { + // Here are the Avatars for the buddies + //We have to track them in a seperate list as the buddies may get populated lateron + cJSON *pArray = cJSON_GetObjectItem(pContent,"edata"), *pItem; + int i, iCount; + + if (pArray) + { + for (i=0, iCount = cJSON_GetArraySize(pArray); ihAvatarList, pItem); + } + } + } + else if (!strcmp(pszName, "disconnect")) + { + // I got disconnected (wrong user/pass?) + cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"); + //char *pszMsg; + + Send(pInst, "CONNSTATUS OFFLINE"); + Send(pInst, "USERSTATUS OFFLINE"); + strcpy (pInst->myUser.szStatus, "OFFLINE"); + /* + if (pEdata && (pszMsg = cJSON_GetObjectItem(pEdata, "msg")->valuestring)) + { + if (strcmp(pszMsg, "uidpassword")==0) + { + fprintf (stderr, "Invalid username / password combination!\n"); + } + } + */ + } + else if ((bAdded = !strcmp(pszName, "buddy_added")) || !strcmp(pszName, "buddy_status")) + { + // Here comes the contact list + cJSON *pArray = cJSON_GetObjectItem(pContent,"edata"), *pItem; + char *pszLastBUID = NULL, *pszLastGroup = NULL; + int i, iCount; + + if (pArray) + { + TYP_LIST *hListMemToAdd = NULL; + + for (i=0, iCount = cJSON_GetArraySize(pArray); ivaluestring; + cJSON *pGroup = cJSON_GetObjectItem(pItem, "group"); + cJSON *pDisplay = cJSON_GetObjectItem(pItem, "display"); + + if (bAdded) + { + /* + if (BuddyList_Find (pInst->hBuddyList, cJSON_GetObjectItem(pItem, "buid")->valuestring)) + bAdded=FALSE; + else + */ + BuddyList_Insert(pInst->hBuddyList, pItem); + } + else BuddyList_SetStatus(pInst->hBuddyList, pItem); + + if ((!pGroup || strcmp(pGroup->valuestring, "Skype")==0 || + strcmp(pGroup->valuestring, "Offline")==0) && + !pDisplay) + { + // Normal user, not groupchat, so output this + sprintf (szQuery, "GET USER %s ONLINESTATUS", pszBUID); + HandleMessage (pInst, szQuery); + sprintf (szQuery, "GET USER %s MOOD_TEXT", pszBUID); + HandleMessage (pInst, szQuery); + } + else + { + // Groupchat created/added + MSGENTRY * pMsgEntry = NULL; + + if (bAdded && pInst->pszBuddiesToAdd) + { + // Process pending ADDs + char *pTok, szQuery[256]; + + for (pTok = strtok(pInst->pszBuddiesToAdd, ", "); pTok; pTok=strtok(NULL, ", ")) + ImoSkype_GroupInvite(pInst->hInst, pszBUID, pTok); + free (pInst->pszBuddiesToAdd); + pInst->pszBuddiesToAdd = NULL; + sprintf (szQuery, "GET CHAT %s STATUS", pszBUID); + HandleMessage (pInst, szQuery); + } + else + { + if (bAdded || !pDisplay) + { + char szQuery[256], szGroup[256]={0}; + NICKENTRY *pChat; + + if (pGroup) sprintf (szGroup, "%s;", pGroup->valuestring); + if (pGroup && (pChat=BuddyList_Find(pInst->hBuddyList, szGroup)) && + pChat->hGCMembers) + { + sprintf (szQuery, "GET CHAT %s MEMBERS", szGroup); + HandleMessage (pInst, szQuery); + } + else + { + if ((bAdded || !pChat) && (!pszLastBUID || strcmp(pszLastBUID, pszBUID)) && + (!pszLastGroup || (pGroup && strcmp(pszLastGroup, pGroup->valuestring)))) + { + if (!hListMemToAdd) hListMemToAdd=List_Init(0); + List_Push(hListMemToAdd, pItem); + pszLastBUID = pszBUID; + if (pGroup) pszLastGroup = pGroup->valuestring; + } + } + } + /* + else + { + pMsgEntry = MsgQueue_AddEvent (pInst->hMsgQueue, pszBUID, "SETTOPIC"); + if (pDisplay->valuestring) pMsgEntry->pszMessage = strdup(pDisplay->valuestring); + } + */ + if (pMsgEntry) + Send(pInst, "%sMESSAGE %d STATUS %s", pInst->iProtocol>=3?"CHAT":"", + pMsgEntry->hdr.uMsgNr, pMsgEntry->szStatus); + + } + } + } + } + if (hListMemToAdd) + { + int nCount; + + for (i=0, nCount=List_Count(hListMemToAdd); ihMsgQueue, cJSON_GetObjectItem(pItem, "buid")->valuestring, "ADDEDMEMBERS")) // MULTI_SUBSCRIBED + { + if (pInviter) pMsgEntry->pszAuthor = strdup(pInviter->valuestring); + Send(pInst, "%sMESSAGE %d STATUS %s", pInst->iProtocol>=3?"CHAT":"", + pMsgEntry->hdr.uMsgNr, pMsgEntry->szStatus); + } + } + + List_Exit(hListMemToAdd); + hListMemToAdd = NULL; + } + if (bAdded && pInst->bFriendsPending) + { + char szMsg[]="SEARCH FRIENDS"; + pInst->bFriendsPending = 0; + HandleMessage (pInst, szMsg); + } + } + } + else if (!strcmp(pszName, "buddy_removed")) + { + // Here comes the contact list + cJSON *pArray = cJSON_GetObjectItem(pContent,"edata"), *pItem; + int i, iCount; + + if (pArray) + { + for (i=0, iCount = cJSON_GetArraySize(pArray); ivaluestring)) + { + NICKENTRY *pNick = BuddyList_Find (pInst->hBuddyList, pszUser); + + if (pNick && pNick->pGroup) + { + MSGENTRY *pMsg = MsgQueue_AddEvent (pInst->hMsgQueue, pszUser, "KICKED"); + cJSON *pUid = cJSON_GetObjectItem(pContent,"uid"); + if (pUid) pMsg->pszAuthor = strdup(pUid->valuestring); + Send(pInst, "%sMESSAGE %d STATUS %s", pInst->iProtocol>=3?"CHAT":"", + pMsg->hdr.uMsgNr, pMsg->szStatus); + } + else + Send (pInst, "USER %s BUDDYSTATUS 1", pszUser); + if (pNick) + BuddyList_Remove (pInst->hBuddyList, pNick); + } + } + } + } + else + if (/*!strcmp(pszName, "recv") || */!strcmp(pszName, "streams_info")) + { + cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"), + *pType = cJSON_GetObjectItem(pContent,"type"), *pVal; + + if (pType && pEdata) + { + if (strcasecmp(pType->valuestring, "call")==0 || strcasecmp(pType->valuestring, "video")==0 || + strcasecmp(pType->valuestring, "av")==0) + { + // Rring, rrring... + int iDirection = ((pVal = cJSON_GetObjectItem(pEdata, "is_initiator")) && pVal->type == cJSON_True)?CALL_OUTGOING:CALL_INCOMING; + CALLENTRY *pCall = CallQueue_Insert (pInst->hCallQueue, pEdata, iDirection); + if (pCall) + { + Send (pInst, "CALL %d STATUS %s", pCall->hdr.uMsgNr, pCall->szStatus); + if ((pInst->iFlags & IMO2S_FLAG_ALLOWINTERACT) && iDirection == CALL_OUTGOING) + StartCallSWF (pInst, pCall); + } + } + } + } + else + if (!strcmp(pszName, "ended")) + { + cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"), + *pType = cJSON_GetObjectItem(pContent,"type"); + + if (pType && pEdata) + { + if (strcasecmp(pType->valuestring, "call")==0 || strcasecmp(pType->valuestring, "video")==0) + { + // No call ID, so just hangup all calls to this user + int i, nCount = List_Count(pInst->hCallQueue); + char *pszUser = cJSON_GetObjectItem(pEdata, "buid")->valuestring; + + for (i=0; ihCallQueue, i); + + if (!strcmp(pCall->pszUser, pszUser) && strcmp (pCall->szStatus, "FINISHED")) + { + char szQuery[256]; + + sprintf (szQuery, "SET CALL %d STATUS FINISHED", pCall->hdr.uMsgNr); + HandleMessage (pInst, szQuery); + } + } + } + } + } + else + if (!strcmp(pszName, "reflect")) // Status reflections. We may want to support more of them in the future + { + cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"), + *pType = cJSON_GetObjectItem(pContent,"type"), *pRname, *pValue; + + if (pEdata && pType && (pRname = cJSON_GetObjectItem(pEdata,"r_name"))) + { + if (strcasecmp(pType->valuestring, "account") == 0) + { + if (strcasecmp (pRname->valuestring, "set_status") == 0 && + (pValue = cJSON_GetObjectItem(pEdata,"primitive")) ) + { + unsigned int i; + + for (i=0; ivaluestring)) + { + strcpy (pInst->myUser.szStatus, m_stMap[i].pszSkypeStat); + Send (pInst, "USERSTATUS %s", pInst->myUser.szStatus); + break; + } + } + + // Just ensure that on autoaway we notify imo.im that we are still there + if (!strcmp (pValue->valuestring, "away")) + ImoSkype_KeepAlive(pInst->hInst); + + if (pValue = cJSON_GetObjectItem(pEdata,"status")) + { + if (pInst->myUser.pszStatusText) free (pInst->myUser.pszStatusText); + pInst->myUser.pszStatusText = NULL; + if (*pValue->valuestring) + pInst->myUser.pszStatusText = strdup(pValue->valuestring); + } + + } + } + else + if (strcasecmp(pType->valuestring, "conv") == 0) + { + if (strcasecmp (pRname->valuestring, "send_im") == 0) + { + MSGENTRY *pMsg; + + if (pMsg = MsgQueue_AddReflect(pInst->hMsgQueue, pEdata, pInst->hBuddyList)) + { + if (pInst->iFlags & IMO2S_FLAG_CURRTIMESTAMP) time(&pMsg->timestamp); + Send(pInst, "%sMESSAGE %d STATUS %s", pInst->iProtocol>=3?"CHAT":"", + pMsg->hdr.uMsgNr, pMsg->szStatus); + } + } + + } + } + } + else + if (!strcmp(pszName, "expired") && m>=iSize-1) + { + // Session expired, so we have to reconnect + Send(pInst, "CONNSTATUS OFFLINE"); + Send(pInst, "USERSTATUS OFFLINE"); + strcpy (pInst->myUser.szStatus, "OFFLINE"); + pInst->iLoginStat = 0; + Dispatcher_Stop(pInst); + if (pInst->myUser.pszUser && pInst->pszPass) + Imo2S_Login(pInst, pInst->myUser.pszUser, pInst->pszPass, NULL); + } + else + if (!strcmp(pszName, "ack")) + { + MSGENTRY *pMsg; + cJSON *pRqId = cJSON_GetObjectItem(pContent,"request_id"); + + if (pRqId && (pMsg = MsgQueue_FindByRqId(pInst->hMsgQueue, pRqId->valueint))) + { + cJSON *pResp, *pTS; + + strcpy (pMsg->szStatus, "SENT"); + if ((pResp = cJSON_GetObjectItem(pContent,"response")) && + (pTS = cJSON_GetObjectItem(pResp,"timestamp"))) + pMsg->timestamp = pTS->valueint; + Send (pInst, "MESSAGE %d STATUS %s", pMsg->hdr.uMsgNr, pMsg->szStatus); + } + } + else + { + char *pszMsg = cJSON_Print(pMsg); + fprintf (stderr, "%s\n\n", pszMsg); + free (pszMsg); + } + } + return 0; +} + +// ----------------------------------------------------------------------------- + +#ifdef WIN32 +// Set call status to finished when closing phone applet window just in case +// there is no callback by imo.im upon closure +static LRESULT CallWndFilter(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_DESTROY: + { + IMOSAPI *pInst = (IMOSAPI*)GetWindowLong (hWnd, GWL_PINST); + int i, nCount; + + if (!pInst) break; + for (i=0, nCount = List_Count(pInst->hCallQueue); ihCallQueue, i); + + if (pCall->hCallWnd == hWnd) + { + char szQuery[256]; + + sprintf (szQuery, "SET CALL %d STATUS FINISHED", pCall->hdr.uMsgNr); + HandleMessage (pInst, szQuery); + break; + } + } + break; + } + } + return CallWindowProc((WNDPROC)GetWindowLong (hWnd, GWL_ORIGWPRC), hWnd, message, wParam, lParam); +} +#endif + + +// ----------------------------------------------------------------------------- + +static int StartCallSWF (IMOSAPI *pInst, CALLENTRY *pCall) +{ + char szSWF[256], szFlashVars[1024], szID[18]; + char szHTML[2048]; + static unsigned int id=100; + + + /* The flash plugin basically opens rtmp://[host]/mchat in case of type=imo, otherwise rtmp://[host]/ivc + Maybe this can also be used with a SIP-phone or Asterisk? + */ +#ifndef WIN32 + FILE *fpTemp; + int iFound; + + sprintf (pCall->szCallFile, "xdg-open %s.html", tmpnam(NULL)); + if (!(fpTemp=fopen(pCall->szCallFile, "w"))) return -1; +#else + // Windows: + // Ensure that we are allowed to load the .swf from imo.im +#ifndef CSIDL_APPDATA +#define CSIDL_APPDATA 0x001a +#endif + static BOOL bInit = TRUE; + + if (bInit) + { + char szPath[MAX_PATH]={0}; + HMODULE hModule; + typedef HMODULE (__stdcall *SHGETFOLDERPATH)(HWND, int, HANDLE, DWORD, LPTSTR); + + if (hModule = LoadLibrary("SHFOLDER.DLL")) + { + SHGETFOLDERPATH fnShGetFolderPath = (SHGETFOLDERPATH)GetProcAddress(hModule, "SHGetFolderPathA"); + + if (fnShGetFolderPath && fnShGetFolderPath( NULL, CSIDL_APPDATA, NULL, 0, szPath)==S_OK) + { + strcat (szPath, "\\Macromedia\\Flash Player"); + if (GetFileAttributes (szPath) != 0xFFFFFFFF) + { + strcat (szPath, "\\#Security"); + _mkdir (szPath); + strcat (szPath, "\\FlashPlayerTrust"); + _mkdir (szPath); + strcat (szPath, "\\imo2sproxy.cfg"); + if (GetFileAttributes (szPath) == 0xFFFFFFFF) + { + FILE *fp = fopen (szPath, "w"); + + if (fp) + { + fputs ("https://imo.im/images/nchat.swf\nabout:blank\n", fp); + fclose (fp); + } + } + } + } + FreeLibrary(hModule); + } + bInit = FALSE; + } +#endif + sprintf (szSWF, "https://imo.im/images/nchat.swf?%s", IVC_VERSION); + ImoRq_CreateID (szID, 16); + //sprintf (szID, "imo%d", id++); + + if (*pCall->szSendStream) + sprintf (szFlashVars, + "type=skype&" + "send_stream=%s&" + "recv_stream=%s&" + "id=skype#%s&" + "host=video0.imo.im&" + "debug=conv net&" + "buddy_icon=https://imo.im/assets/main/icn_default.png&" + "setCookie=setCookie&" + "getCookie=getCookie&" + "removeCookie=removeCookie&" + "log=log&" + "init_callback=init_callback&" + "video_options_changed_cb=video_options_changed_cb&" + "options_changed_cb=options_changed_cb&" + "mic_changed_cb=mic_changed_cb&" + "cam_changed_cb=cam_changed_cb&" + "connection_status_cb=connection_status_cb", + pCall->szSendStream, pCall->szRecvStream, pCall->szSendStream); + else + return -1; + // sprintf (szFlashVars, "type=imo&conv=%s&role=%d&host=%s&id=%s", pCall->szConv, pCall->iRole, pCall->szIP, szID); + + strcat (szFlashVars, "&audio_only=true"); + // Currently not supported + sprintf (szHTML, "\n" + "" + "\n" + "\n" + "\n" + "\n" + "" + "\n" + "

\n" + "\n", + szSWF, szID, szSWF, szFlashVars); + +#ifdef WIN32 + //OutputDebugString (szHTML); + sprintf (szSWF, "Voicechat with %s", pCall->pszUser); + + /* + + { + FILE *fpOut = fopen("C:\\TEMP\\CALL.HTML", "w"); + + fputs (szHTML, fpOut); + fclose (fpOut); + system ("\"C:\\Programme\\Internet Explorer\\IEXPLORE.EXE\" C:\\TEMP\\CALL.HTML"); + } + */ + + if ((pCall->hCallWnd = W32Browser_ShowHTMLStr (szHTML,420, 280, szSWF))>0) + { + // Hook WndProc to handle WM_DESTROY so that we generate a CALL %d STATUS FINISHED on + // closing the chat window +#ifdef _WIN64 + SetWindowLongPtr ((HWND)pCall->hCallWnd, GWL_PINST, (LONG_PTR)pInst); + SetWindowLongPtr ((HWND)pCall->hCallWnd, GWL_ORIGWPRC, + GetWindowLongPtr ((HWND)pCall->hCallWnd, GWLP_WNDPROC)); + SetWindowLongPtr ((HWND)pCall->hCallWnd, GWLP_WNDPROC, (LONG_PTR)CallWndFilter); +#else + SetWindowLong ((HWND)pCall->hCallWnd, GWL_PINST, (LONG)pInst); + SetWindowLong ((HWND)pCall->hCallWnd, GWL_ORIGWPRC, GetWindowLong ((HWND)pCall->hCallWnd, GWL_WNDPROC)); + SetWindowLong((HWND)pCall->hCallWnd, GWL_WNDPROC, (LONG)CallWndFilter); +#endif + return 0; + } + return -1; +#else + fprintf (fpTemp, "%s", szHTML); + fclose (fpTemp); + iFound = system(pCall->szCallFile); + return (iFound == -1 || iFound == 127)?-1:0; +#endif +} + +// ----------------------------------------------------------------------------- + +static void DispatcherThread(void *pUser) +{ + IMOSAPI *pInst = (IMOSAPI*)pUser; + time_t t = 0, tcur; + + if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S::DispatcherThread() start\n"); + while (!pInst->iShuttingDown) + { +#if defined(WIN32) && defined(WIN32) + char szBuf[128]; + + sprintf (szBuf, "DispatcherThread %d loops.\n", GetCurrentThreadId()); + OutputDebugString (szBuf); +#endif + if (time(&tcur)>=t+300) + { + t=tcur; + //ImoSkype_Ping (pInst->hInst); + ImoSkype_KeepAlive(pInst->hInst); + } + + // Set status in case this is needed + if (pInst->tSetMoodText && tcur>=pInst->tSetMoodText) + { + int i; + + pInst->tSetMoodText = 0; + for (i=0; imyUser.szStatus)) + { + ImoSkype_SetStatus(pInst->hInst, m_stMap[i].pszImoStat, + pInst->myUser.pszStatusText?pInst->myUser.pszStatusText:""); + break; + } + } + } + ImoSkype_Poll(pInst->hInst); + } +} + +// ----------------------------------------------------------------------------- + +#ifdef WIN32 +static int Dispatcher_Start(IMOSAPI *pInst) +{ + DWORD ThreadID; + + if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S::Dispatcher_Start()\n"); + return (pInst->hThread=(thread_t)_beginthreadex(NULL, 0, + (unsigned(__stdcall *)(void*))DispatcherThread, pInst, 0, &ThreadID))!=0; + +} + +static int Dispatcher_Stop(IMOSAPI *pInst) +{ + int iRet, iOldShutdown; + + if (pInst->fpLog) + { + fprintf (pInst->fpLog, "Imo2S::Dispatcher_Stop()\n"); + fflush(pInst->fpLog); + } + + // Shutdown polling socket and wait some time if thread terminates + // gracefully, otherwise kill it + iOldShutdown = pInst->iShuttingDown; + pInst->iShuttingDown = 1; + ImoSkype_CancelPolling (pInst->hInst); + if (WaitForSingleObject (pInst->hThread, 2000) == WAIT_TIMEOUT) + iRet = TerminateThread (pInst->hThread, 0); + else iRet = 1; + pInst->iShuttingDown = iOldShutdown; + + if (iRet) + { + CloseHandle (pInst->hThread); + pInst->hThread = 0; + } + + if (pInst->fpLog) + { + fprintf (pInst->fpLog, "Imo2S::Dispatcher_Stop() done.\n"); + pInst->fpLog = NULL; + } + + return iRet; +} + +#else +static int Dispatcher_Start(IMOSAPI *pInst) +{ + if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S::Dispatcher_Start()\n"); + return pthread_create(&pInst->hThread, NULL, DispatcherThread, pInst)==0; +} + +static int Dispatcher_Stop(IMOSAPI *pInst) +{ + if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S::Dispatcher_Stop()\n"); + if (pthread_cancel(pInst->hThread)) + { + pInst->hThread=0; + return 1; + } + return 0; +} +#endif + +// ----------------------------------------------------------------------------- + +static void Send(IMOSAPI *pInst, const char *pszMsg, ...) +{ + va_list ap; + int iLen, iLenCmdID; + char *pszLogBuf = pInst->pszLogBuf; + int cbBuf = pInst->cbBuf; + + iLenCmdID = pInst->pszCmdID?strlen(pInst->pszCmdID)+1:0; + do + { + cbBuf = pInst->cbBuf - iLenCmdID; + pszLogBuf = pInst->pszLogBuf + iLenCmdID; + va_start(ap, pszMsg); + iLen = vsnprintf (pszLogBuf, cbBuf, pszMsg, ap); + va_end(ap); +#ifndef WIN32 + if (iLen>=cbBuf) iLen=-1; +#endif + if (iLen == -1) + { + char *pNewBuf; + + if (!(pNewBuf = realloc(pInst->pszLogBuf, pInst->cbBuf*2))) + { + break; + } + pInst->cbBuf*=2; + pInst->pszLogBuf = pNewBuf; + } + } while (iLen == -1); + if (pInst->pszCmdID && iLenCmdID>1) + { + memcpy (pInst->pszLogBuf, pInst->pszCmdID, iLenCmdID); + pInst->pszLogBuf[iLenCmdID-1]=' '; + } + +//printf ("%s\n", szBuf); + pInst->Callback(pInst->pszLogBuf, pInst->pUser); +} + +// ----------------------------------------------------------------------------- + +static void HandleMessage(IMOSAPI *pInst, char *pszMsg) +{ + char *pszCmd=strtok(pszMsg, " "); + + if (!pInst || !pszCmd || !pInst->hInst) return; + if (*pszCmd=='#') + { + // This is a PROTOCOL 4 feature, but we will support it just in case... + pInst->pszCmdID = pszCmd; + if (!(pszCmd=strtok(NULL, " "))) + { + pInst->pszCmdID = NULL; + return; + } + } + else pInst->pszCmdID = NULL; + + if (strcasecmp(pszCmd, "PROTOCOL") == 0) + { + if (pszCmd = strtok(NULL, " ")) + { + pInst->iProtocol = atoi(pszCmd); + if (pInst->iProtocol>3) pInst->iProtocol=3; + } + + Send (pInst, "PROTOCOL %d", pInst->iProtocol); + return; + } + else + if (strcasecmp(pszCmd, "PING") == 0) + { + Send (pInst, "PONG"); + return; + } + else + if (strcasecmp(pszCmd, "SEARCH") == 0) + { + TYP_FIFO *hFifo; + + if (!(pszCmd = strtok(NULL, " "))) + { + Send (pInst, "ERROR 2 Invalid command"); + return; + } + + if (strcasecmp(pszCmd, "FRIENDS") == 0) + { + unsigned int nCount =List_Count(pInst->hBuddyList); + + if (!nCount) + { + pInst->bFriendsPending = 1; + return; + } + if(hFifo=Fifo_Init(512)) + { + unsigned int i; + char *pszUsers; + + for (i=0; ihBuddyList, i); + if (!pEntry->pGroup && !pEntry->hGCMembers) + { + if (i>0) Fifo_AddString (hFifo, ", "); + Fifo_AddString (hFifo, pEntry->pszUser); + } + } + if (pszUsers = Fifo_Get(hFifo, NULL)) + Send (pInst, "USERS %s", pszUsers); + else + pInst->bFriendsPending = 1; + Fifo_Exit(hFifo); + } + } + else if (strcasecmp(pszCmd, "MISSEDMESSAGES") == 0) + { + unsigned int nCount=List_Count(pInst->hMsgQueue); + + if(nCount && (hFifo=Fifo_Init(512))) + { + unsigned int i, j=0; + + for (i=0; ihMsgQueue, i); + char szNr[32]; + + if (!strcmp(pEntry->szStatus, "RECEIVED")) + { + if (j>0) Fifo_AddString (hFifo, ", "); + sprintf (szNr, "%d", pEntry->hdr.uMsgNr); + Fifo_AddString (hFifo, szNr); + j++; + } + } + Send (pInst, "MESSAGES %s", Fifo_Get(hFifo, NULL)); + Fifo_Exit(hFifo); + } + } + else if (strcasecmp(pszCmd, "USERS") == 0) + { + // There is no possibility to search Skype users in imo.im + // therefore just return that the user exists even if it doesn't :( + Send (pInst, "USERS %s", pszCmd+6); + // We add the user as a temporary contact to our list so that the + // client can get the empty properties and set the buddystatus. + BuddyList_AddTemporaryUser (pInst->hBuddyList, pszCmd+6); + } + else if (strcasecmp(pszCmd, "USERSWAITINGMYAUTHORIZATION") == 0) + { + Send (pInst, "USERS"); + } + else if (strcasecmp(pszCmd, "ACTIVECALLS") == 0) + { + char szCalls[512]; + int i, nCount, iOffs=0; + + iOffs = sprintf (szCalls, "CALLS"); + for (i=0, nCount=List_Count(pInst->hCallQueue); ihCallQueue, i))->hdr.uMsgNr); + if (iOffs+6>=sizeof(szCalls)) break; + } + Send (pInst, szCalls); + } + else if (strcasecmp(pszCmd, "RECENTCHATS") == 0) + { + char szChats[2056]; + int i, nCount, iOffs=0, j=0; + + iOffs = sprintf (szChats, "CHATS "); + for (i=0, nCount=List_Count(pInst->hBuddyList); ihBuddyList, i); + + if (BuddyList_IsGroupchat(pChat)) + { + if (j) iOffs+=sprintf(&szChats[iOffs], ", "); + iOffs+=sprintf(&szChats[iOffs], "%s", pChat->pszUser); + if (iOffs+6>=sizeof(szChats)) break; + j++; + } + } + Send (pInst, szChats); + } + return; + } + else + if (strcasecmp(pszCmd, "GET") == 0) + { + if (!(pszCmd = strtok(NULL, " "))) + { + Send (pInst, "ERROR 7 Invalid property"); + return; + } + + if (strcasecmp(pszCmd, "USER") == 0) + { + NICKENTRY *pUser = NULL; + + if (pszCmd = strtok(NULL, " ")) + { + if (!strcasecmp (pszCmd, pInst->myUser.pszUser)) + pUser = &pInst->myUser; + else + pUser = BuddyList_Find(pInst->hBuddyList, pszCmd); + } + + if (!pUser) + { + Send (pInst, "ERROR 26 Invalid user handle"); + return; + } + if (!(pszCmd = strtok(NULL, " "))) + { + Send (pInst, "ERROR 10 Invalid property"); + return; + } + + if (!strcasecmp (pszCmd, "HANDLE")) + { + if (pUser->pszAlias) Send (pInst, "USER %s HANDLE %s", pUser->pszUser, pUser->pszAlias); + } + else if (!strcasecmp (pszCmd, "FULLNAME")) /* Workaround */ + Send (pInst, "USER %s FULLNAME %s", pUser->pszUser, pUser->pszAlias); + else if (!strcasecmp (pszCmd, "DISPLAYNAME")) + Send (pInst, "USER %s DISPLAYNAME %s", pUser->pszUser, pUser->pszAlias); + else if (!strcasecmp (pszCmd, "HASCALLEQUIPMENT")) + Send (pInst, "USER %s HASCALLEQUIPMENT TRUE", pUser->pszUser); + else if (!strcasecmp (pszCmd, "BUDDYSTATUS")) + Send (pInst, "USER %s BUDDYSTATUS %d", pUser->pszUser, pUser->iBuddyStatus); + else if (!strcasecmp (pszCmd, "ISAUTHORIZED")) + Send (pInst, "USER %s ISAUTHORIZED TRUE", pUser->pszUser); + else if (!strcasecmp (pszCmd, "MOOD_TEXT")) + Send (pInst, "USER %s MOOD_TEXT %s", pUser->pszUser, + pUser->pszStatusText?pUser->pszStatusText:""); + else if (!strcasecmp (pszCmd, "SEX")) + Send (pInst, "USER %s SEX UNKNOWN", pUser->pszUser); + else if (!strcasecmp (pszCmd, "BIRTHDAY")) + Send (pInst, "USER %s BIRTHDAY 0", pUser->pszUser); + else if (!strcasecmp (pszCmd, "ONLINESTATUS")) + { + unsigned int i; + + for (i=0; iszStatus)) + { + Send (pInst, "USER %s ONLINESTATUS %s", pUser->pszUser, m_stMap[i].pszSkypeStat); + break; + } + } + } + else if (!strcasecmp (pszCmd, "AVATAR")) + { + char *pszFile, *pAvatarBuf; + unsigned int dwLength; + AVATARENTRY *pAvatar; + FILE *fp; + + if (!(pszFile = strtok(NULL, " ")) || strcasecmp (pszFile, "1")) + { + Send (pInst, "ERROR 116 GET invalid ID"); + return; + } + if (!(pszFile = strtok(NULL, "\n"))) + { + Send (pInst, "ERROR 7 GET: invalid WHAT"); + return; + } + if (fp=fopen(pszFile, "r")) + { + fseek (fp, 0, SEEK_END); + if (ftell(fp)) + { + fclose(fp); + Send (pInst, "ERROR 124 GET Destination file is not empty"); + return; + } + fclose(fp); + } + if (!(pAvatar = AvatarList_Find(pInst->hAvatarList, pUser->pszUser)) || + !(pAvatarBuf = ImoSkype_GetAvatar (pInst->hInst, pAvatar->pszIcon, &dwLength))) + { + // FIXME: Normally we should return default avatar if pAvatar is NULL. + // Default avatar from imo.im is PNG, but JPEG is expected, so we + // return an error here + Send (pInst, "ERROR 122 GET Unable to load avatar"); + return; + } + if (!(fp=fopen(pszFile, +#ifdef WIN32 + "wb" +#else + "w" +#endif + ))) + { + Send (pInst, "ERROR 121 GET File path doesn't exist"); + return; + } + fwrite (pAvatarBuf, dwLength, 1, fp); + fclose (fp); + Send (pInst, "USER %s AVATAR 1 %s", pUser->pszUser, pszFile); + } + else + { + Send(pInst, "ERROR 10 Invalid propery"); + } + return; + } + else + if (strcasecmp(pszCmd, "CURRENTUSERHANDLE") == 0) + { + if (pInst->myUser.pszUser) + Send(pInst, "CURRENTUSERHANDLE %s", pInst->myUser.pszUser); + } + else + if (strcasecmp(pszCmd, "USERSTATUS") == 0) + { + Send(pInst, "USERSTATUS %s", pInst->myUser.szStatus); + } + else + if (strcasecmp(pszCmd, "MESSAGE") == 0 || strcasecmp(pszCmd, "CHATMESSAGE") == 0) + { + MSGENTRY *pEntry; + char *pszMessage = pszCmd; + + if (!(pszCmd = strtok(NULL, " ")) || !(pEntry = MsgQueue_Find(pInst->hMsgQueue, atol(pszCmd)))) + { + Send (pInst, "ERROR 14 Invalid message id"); + return; + } + if (!(pszCmd = strtok(NULL, " "))) + { + Send (pInst, "ERROR 10 Invalid property"); + return; + } + if (!strcasecmp (pszCmd, "TIMESTAMP")) + Send (pInst, "%s %d TIMESTAMP %ld", pszMessage, pEntry->hdr.uMsgNr, pEntry->timestamp); + else if (!strcasecmp (pszCmd, "PARTNER_HANDLE") || !strcasecmp (pszCmd, "FROM_HANDLE")) + { + char *pszUser = strdup(pEntry->pszAuthor?pEntry->pszAuthor:pEntry->pszUser), *p, *pszRealUser=pszUser; + + if (p=strtok(pszUser, ";")) + { + if (!(pszRealUser=strtok(NULL, ";"))) pszRealUser=p; + } + Send (pInst, "%s %d %s %s", pszMessage, pEntry->hdr.uMsgNr, pszCmd, pszRealUser); + free (pszUser); + } + else if (!strcasecmp (pszCmd, "PARTNER_DISPNAME")) + Send (pInst, "%s %d PARTNER_DISPNAME %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->pszAlias); + else if (!strcasecmp (pszCmd, "TYPE")) + Send (pInst, "%s %d TYPE %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->szType); + else if (!strcasecmp (pszCmd, "STATUS")) + Send (pInst, "%s %d STATUS %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->szStatus); + else if (!strcasecmp (pszCmd, "FAILUREREASON")) + Send (pInst, "%s %d FAILUREREASON %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->szFailure); + else if (!strcasecmp (pszCmd, "BODY")) + Send (pInst, "%s %d BODY %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->pszMessage); + else if (!strcasecmp (pszCmd, "CHATNAME")) + { + if (pEntry->pszAuthor || !pEntry->pszMessage || strchr(pEntry->pszUser, ';')) // Groupchat + { + char *pszUser = strdup(pEntry->pszUser), *p; + + if (p=strchr(pszUser, ';')) p[1]=0; + Send (pInst, "%s %d CHATNAME %s", pszMessage, pEntry->hdr.uMsgNr, pszUser); + free (pszUser); + } + else + Send (pInst, "%s %d CHATNAME #%s/$%s", pszMessage, pEntry->hdr.uMsgNr, pInst->myUser.pszUser, pEntry->pszUser); + } + else if (!strcasecmp (pszCmd, "USERS")) + { + // On KICK, this is the user who GOT kicked + char *pszUser = strchr(pEntry->pszUser, ';'); + if (pszUser) pszUser++; else pszUser=pEntry->pszUser; + Send (pInst, "%s %d USERS %s", pszMessage, pEntry->hdr.uMsgNr, pszUser); + } + else + Send (pInst, "ERROR 10 Invalid property / not implemented"); + return; + } + else + if (strcasecmp(pszCmd, "PRIVILEGE") == 0) + { + if (!(pszCmd = strtok(NULL, " ")) || + (strcasecmp (pszCmd, "SKYPEOUT") && + strcasecmp (pszCmd, "SKYPEIN") && + strcasecmp (pszCmd, "VOICEMAIL"))) + { + Send (pInst, "ERROR 40 Unknown Privilege"); + return; + } + Send (pInst, "PRIVILEGE %s FALSE", pszCmd); + return; + } + else + if (strcasecmp(pszCmd, "CHAT") == 0) + { + char *pszChat; + NICKENTRY *pChat=NULL; + + // A $ sign is in the name of a dialog, otherwise it's a groupchat ID + if (!(pszChat = strtok(NULL, " ")) || + (!strchr(pszChat, '$') && !(pChat=BuddyList_Find(pInst->hBuddyList, pszChat)))) + { + Send (pInst, "ERROR 14 Invalid message id"); + return; + } + + + if (!(pszCmd = strtok(NULL, " "))) + { + Send (pInst, "ERROR 10 Invalid property"); + return; + } + + if (strcasecmp(pszCmd, "NAME") == 0) + Send (pInst, "CHAT %s NAME %s", pszChat, pszChat); + else if (strcasecmp(pszCmd, "STATUS") == 0) + // A $ sign is in the name of a dialog, otherwise it's a groupchat ID + Send (pInst, "CHAT %s STATUS %s", pszChat, pChat?"MULTI_SUBSCRIBED":"LEGACY_DIALOG"); + else if (strcasecmp(pszCmd, "ADDER") == 0) + Send (pInst, "CHAT %s ADDER %s", pszChat, pInst->myUser.pszUser); + else if (strcasecmp(pszCmd, "TYPE") == 0) + Send (pInst, "CHAT %s TYPE %s", pszChat, pChat?"MULTICHAT":"DIALOG"); + else if (strcasecmp(pszCmd, "MYROLE") == 0) + Send (pInst, "CHAT %s MYROLE USER", pszChat); + else if (strcasecmp(pszCmd, "MYSTATUS") == 0) + Send (pInst, "CHAT %s MYSTATUS SUBSCRIBED", pszChat); + else if ((strcasecmp(pszCmd, "TOPIC") == 0 || strcasecmp(pszCmd, "FRIENDLYNAME") == 0) && pChat) + Send (pInst, "CHAT %s %s %s", pszChat, pszCmd, pChat->pszDisplay); + else if ((strcasecmp(pszCmd, "ACTIVEMEMBERS") == 0 || strcasecmp(pszCmd, "MEMBERS") == 0) && pChat) + { + char szMembers[1024]={0}; + int i, nCount, iOffs=0; + + iOffs = sprintf (szMembers, "CHAT %s %s ", pszChat, pszCmd); + for (i=0, nCount=List_Count(pChat->hGCMembers); ihGCMembers, i); + char szUser[512], *pTok; + + if (i) iOffs+=sprintf(&szMembers[iOffs], " "); + strcpy (szUser, pMemb->pszUser); + pTok=strtok(szUser, ";"); + pTok=strtok(NULL, ";"); + iOffs+=sprintf(&szMembers[iOffs], "%s", pTok); + if (iOffs+6>=sizeof(szMembers)) break; + } + Send (pInst, szMembers); + } + else + Send(pInst, "ERROR 7 Invalid property / not implemented"); + return; + } + else + if (strcasecmp(pszCmd, "CALL") == 0) + { + CALLENTRY *pEntry; + + if (!(pszCmd = strtok(NULL, " ")) || !(pEntry = CallQueue_Find(pInst->hCallQueue, atol(pszCmd)))) + { + Send (pInst, "ERROR 11 Invalid call id"); + return; + } + if (!(pszCmd = strtok(NULL, " "))) + { + Send (pInst, "ERROR 10 Invalid property"); + return; + } + if (!strcasecmp (pszCmd, "TIMESTAMP")) + Send (pInst, "CALL %d TIMESTAMP %ld", pEntry->hdr.uMsgNr, pEntry->timestamp); + else if (!strcasecmp (pszCmd, "PARTNER_HANDLE")) + Send (pInst, "CALL %d PARTNER_HANDLE %s", pEntry->hdr.uMsgNr, pEntry->pszUser); + else if (!strcasecmp (pszCmd, "PARTNER_DISPNAME")) + { + NICKENTRY *pNick = BuddyList_Find (pInst->hBuddyList, pEntry->pszUser); + + if (pNick) + Send (pInst, "CALL %d PARTNER_DISPNAME %s", pEntry->hdr.uMsgNr, pNick->pszAlias); + } + else if (!strcasecmp (pszCmd, "CONF_ID")) + Send (pInst, "CALL %d CONF_ID 0", pEntry->hdr.uMsgNr); + else if (!strcasecmp (pszCmd, "TYPE")) + Send (pInst, "CALL %d TYPE %s", pEntry->hdr.uMsgNr, pEntry->iDirection==CALL_INCOMING?"INCOMING_P2P":"OUTGOING_P2P"); + else if (!strcasecmp (pszCmd, "STATUS")) + Send (pInst, "CALL %d STATUS %s", pEntry->hdr.uMsgNr, pEntry->szStatus); + else if (!strcasecmp (pszCmd, "VIDEO_STATUS")) + Send (pInst, "CALL %d VIDEO_STATUS VIDEO_NONE", pEntry->hdr.uMsgNr); + else if (!strcasecmp (pszCmd, "VIDEO_SEND_STATUS") || !strcasecmp (pszCmd, "VIDEO_RECEIVE_STATUS")) + Send (pInst, "CALL %d %s NOT_AVAILABLE", pEntry->hdr.uMsgNr, pszCmd); + else if (!strcasecmp (pszCmd, "FAILUREREASON")) + Send (pInst, "CALL %d FAILUREREASON UNKNOWN", pEntry->hdr.uMsgNr); + else if (!strcasecmp (pszCmd, "DURATION")) + Send (pInst, "CALL %d DURATION 0", pEntry->hdr.uMsgNr); + else if (!strcasecmp (pszCmd, "CONF_PARTICIPANTS_COUNT")) + Send (pInst, "CALL %d CONF_PARTICIPANTS_COUNT 0", pEntry->hdr.uMsgNr); + else + Send (pInst, "ERROR 10 Invalid property / not implemented"); + return; + } + else + if (strcasecmp(pszCmd, "SKYPEVERSION") == 0) + { + Send (pInst, "SKYPEVERSION 3.8.0.188"); // Fake + } + else + { + Send(pInst, "ERROR 7 Invalid property / not implemented"); + } + return; + } + else + if (strcasecmp(pszCmd, "SET") == 0) + { + if (!(pszCmd = strtok(NULL, " "))) + { + Send (pInst, "ERROR 7 Invalid property"); + return; + } + + if (strcasecmp(pszCmd, "USER") == 0) + { + char *pszUser; + NICKENTRY *pUser = NULL; + + if (!(pszUser = strtok(NULL, " "))) + { + Send (pInst, "ERROR 26 Invalid user handle"); + return; + } + + if (!(pszCmd = strtok(NULL, " "))) + { + Send (pInst, "ERROR 7 Invalid property"); + return; + } + + pUser = BuddyList_Find(pInst->hBuddyList, pszUser); + + if (strcasecmp(pszCmd, "BUDDYSTATUS") == 0) + { + int iStatus = -1; + + if (pszCmd = strtok(NULL, " ")) + iStatus = atoi(pszCmd); + + if (!pUser && iStatus < 2) + { + Send (pInst, "ERROR 26 Invalid user handle"); + return; + } + if (iStatus == 2 || (iStatus > 2 && !pUser) || iStatus != pUser->iBuddyStatus) + { + switch (iStatus) + { + case 1: + if (ImoSkype_DelBuddy (pInst->hInst, pUser->pszUser, + strcmp(pUser->szStatus, "OFFLINE")?"Skype":"Offline") == 1) + pUser->iBuddyStatus = iStatus; + break; + case 2: + case 3: + ImoSkype_AddBuddy (pInst->hInst, pszUser); + return; + default: + Send (pInst, "ERROR 518 Invalid status given for BUDDYSTATUS"); + return; + } + } + Send (pInst, "USER %s BUDDYSTATUS %d", pUser->pszUser, pUser->iBuddyStatus); + return; + } + else if (!pUser) + { + Send (pInst, "ERROR 26 Invalid user handle"); + return; + } + else + { + // ISAUTHORIZED + Send (pInst, "ERROR 7 Not implemented"); + } + } + else + if (strcasecmp(pszCmd, "USERSTATUS") == 0) + { + unsigned int i; + + if (!(pszCmd = strtok(NULL, " "))) + { + Send (pInst, "ERROR 28 Unknown userstatus"); + return; + } + + if (strcasecmp(pInst->myUser.szStatus, pszCmd)) + { + for (i=0; itSetMoodText = 0; + if (ImoSkype_SetStatus(pInst->hInst, m_stMap[i].pszImoStat, + pInst->myUser.pszStatusText?pInst->myUser.pszStatusText:"")>0) + strcpy (pInst->myUser.szStatus, pszCmd); + Send (pInst, "USERSTATUS %s", pInst->myUser.szStatus); + break; + } + } + if (i==sizeof(m_stMap)/sizeof(m_stMap[0])) + Send (pInst, "ERROR 28 Unknown userstatus"); + } else Send (pInst, "USERSTATUS %s", pInst->myUser.szStatus); + return; + } + else + if (strcasecmp(pszCmd, "MESSAGE") == 0 || strcasecmp(pszCmd, "CHATMESSAGE") == 0) + { + MSGENTRY *pEntry; + char *pszMessage = pszCmd; + + if (!(pszCmd = strtok(NULL, " ")) || !(pEntry = MsgQueue_Find(pInst->hMsgQueue, atol(pszCmd)))) + { + Send (pInst, "ERROR 14 Invalid message id"); + return; + } + if (!(pszCmd = strtok(NULL, " "))) + { + Send (pInst, "ERROR 10 Invalid property"); + return; + } + if (!strcasecmp (pszCmd, "SEEN")) + { + strcpy (pEntry->szStatus, "READ"); + Send (pInst, "%s %d STATUS %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->szStatus); + } + else + Send (pInst, "ERROR 10 Invalid property / not implemented"); + return; + } + else + if (strcasecmp(pszCmd, "CALL") == 0) + { + CALLENTRY *pEntry; + + if (!(pszCmd = strtok(NULL, " ")) || !(pEntry = CallQueue_Find(pInst->hCallQueue, atol(pszCmd)))) + { + Send (pInst, "ERROR 11 Invalid call id"); + return; + } + if (!(pszCmd = strtok(NULL, " "))) + { + Send (pInst, "ERROR 10 Invalid property"); + return; + } + if (!strcasecmp (pszCmd, "STATUS")) + { + if (!(pszCmd = strtok(NULL, " "))) + { + Send (pInst, "ERROR 21 Unknown/disallowed call prop"); + return; + } + strcpy (pEntry->szStatus, pszCmd); + Send (pInst, "CALL %d STATUS %s", pEntry->hdr.uMsgNr, pEntry->szStatus); + + // {RINGING, INPROGRESS, ONHOLD, FINISHED} + if (pInst->iFlags & IMO2S_FLAG_ALLOWINTERACT) + { + if (strcasecmp (pEntry->szStatus, "INPROGRESS") == 0 && pEntry->iDirection == CALL_INCOMING) + { + StartCallSWF (pInst, pEntry); + } + else + if (strcasecmp (pEntry->szStatus, "FINISHED") == 0 && pEntry->hCallWnd) + { + if (*pEntry->szCallFile) + { + unlink(pEntry->szCallFile); + *pEntry->szCallFile=0; + } +#ifdef WIN32 + if (pEntry->hCallWnd) + { + W32Browser_CloseWindow (pEntry->hCallWnd); + pEntry->hCallWnd = NULL; + } +#endif + + // On incoming call, hang up + } + } + + // Currently we don't support calls, just hang up + /* FIXME: Hangup! */ + return; + } + return; + } + else + if (strcasecmp(pszCmd, "PROFILE") == 0) + { + if (!(pszCmd = strtok(NULL, " "))) + { + Send (pInst, "ERROR 10 Invalid property"); + return; + } + + if (!strcasecmp (pszCmd, "MOOD_TEXT")) + { + if (!pInst->myUser.pszStatusText || + strcasecmp(pInst->myUser.pszStatusText, pszCmd+10)) + { + time_t t; + // Delay setting of MOOD_TEXT, as next command in chain may change online status + // and we want to prevent double calls + // The polling-thread will take care of this event + pInst->tSetMoodText = time(&t)+15; + if (pInst->myUser.pszStatusText) free (pInst->myUser.pszStatusText); + pInst->myUser.pszStatusText = strdup (pszCmd+10); + } + } + else + { + Send (pInst, "ERROR 552 Invalid property"); + return; + } + } + else + { + Send (pInst, "ERROR 7 Invalid property"); + return; + } + } + else + if (strcasecmp(pszCmd, "MESSAGE") == 0 || strcasecmp(pszCmd, "CHATMESSAGE") == 0) + { + NICKENTRY *pUser; + unsigned int uMsgId; + MSGENTRY *pMsg; + + if (!(pszCmd = strtok(NULL, " ")) || !(pUser = BuddyList_Find(pInst->hBuddyList, pszCmd))) + { + Send (pInst, "ERROR 26 Invalid user handle"); + return; + } + pszCmd+=strlen(pszCmd)+1; + if (!*pszCmd) + { + Send (pInst, "ERROR 43 Cannot send empty message"); + return; + } + if (!(pMsg = MsgQueue_AddSent (pInst->hMsgQueue, pUser->pszUser, pUser->pszAlias, pszCmd, &uMsgId))) + { + Send (pInst, "ERROR 9901 Internal error"); + return; + } + if (IMO_API_VERSION == 0) Send (pInst, "MESSAGE %d STATUS SENDING", uMsgId); + if (ImoSkype_SendMessage(pInst->hInst, pUser->pszUser, pszCmd, &pMsg->uRqId)>0) + { + if (IMO_API_VERSION == 0) strcpy (pMsg->szStatus, "SENT"); + } + else + { + strcpy (pMsg->szStatus, "FAILED"); + strncpy (pMsg->szFailure, ImoSkype_GetLastError(pInst->hInst), sizeof(pMsg->szFailure)); + } + Send (pInst, "MESSAGE %d STATUS %s", uMsgId, pMsg->szStatus); + } + else + if (strcasecmp(pszCmd, "CHAT") == 0) + { + if (!(pszCmd = strtok(NULL, " "))) + { + Send (pInst, "ERROR 536 CREATE: no object or type given"); + return; + } + if (strcasecmp(pszCmd, "CREATE") == 0) + { + char szName[128]; // No name given here, so make up a name + time_t t; + + time(&t); + sprintf (szName, "%d", t); + if (ImoSkype_CreateSharedGroup(pInst->hInst, szName)<1) return; + + // Now buddy_added should be called which gives us the ID of the new groupchat + // where we can then add members to. However this is not known here yet, so feed + // list with users to add to instance and let it be processed by buddy_added handler + if (pszCmd = strtok(NULL, "\n")) + { + if (pInst->pszBuddiesToAdd) free(pInst->pszBuddiesToAdd); + pInst->pszBuddiesToAdd = strdup(pszCmd); + } + } + else + Send (pInst, "ERROR 503 CHAT: Invalid or unknown action"); + return; + } + else + if (strcasecmp(pszCmd, "CALL") == 0) + { + NICKENTRY *pUser; + + if (!(pszCmd = strtok(NULL, " ")) || !(pUser = BuddyList_Find(pInst->hBuddyList, pszCmd))) + { + Send (pInst, "ERROR 26 Invalid user handle"); + return; + } + + ImoSkype_StartVoiceCall (pInst->hInst, pUser->pszUser); + return; + } + else + if (strcasecmp(pszCmd, "OPEN") == 0) + { + return; + } + else + if (strcasecmp(pszCmd, "CREATE") == 0) + { + if (!(pszCmd = strtok(NULL, " "))) + { + Send (pInst, "ERROR 536 CREATE: no object or type given"); + return; + } + if (strcasecmp(pszCmd, "APPLICATION") == 0) + { + if (!(pszCmd = strtok(NULL, " ")) || strcasecmp(pszCmd, "libpurple_typing")) + Send (pInst, "ERROR 540 CREATE APPLICATION: Missing or invalid name"); + else + Send (pInst, "CREATE APPLICATION libpurple_typing"); + } + else + Send (pInst, "ERROR 537 CREATE: Unknown object type given"); + return; + } + else + if (strcasecmp(pszCmd, "DELETE") == 0) + { + if (!(pszCmd = strtok(NULL, " "))) + { + Send (pInst, "ERROR 538 DELETE: no object or type given"); + return; + } + if (strcasecmp(pszCmd, "APPLICATION") == 0) + { + if (!(pszCmd = strtok(NULL, " ")) || strcasecmp(pszCmd, "libpurple_typing")) + Send (pInst, "ERROR 542 DELETE APPLICATION: Missing or invalid application name"); + else + Send (pInst, "DELETE APPLICATION libpurple_typing"); + } + else + Send (pInst, "ERROR 539 DELETE: Unknown object type given"); + return; + } + else + if (strcasecmp(pszCmd, "ALTER") == 0) + { + if (!(pszCmd = strtok(NULL, " "))) + Send (pInst, "ERROR 526 ALTER: no object type given"); + else + { + if (strcasecmp(pszCmd, "APPLICATION") == 0) + { + if (!(pszCmd = strtok(NULL, " ")) || strcasecmp(pszCmd, "libpurple_typing") || + !(pszCmd = strtok(NULL, " "))) + Send (pInst, "ERROR 545 ALTER: missing or invalid action"); + else + { + NICKENTRY *pUser; + + if (strcasecmp (pszCmd, "CONNECT") == 0) + { + if (!(pszCmd = strtok(NULL, " ")) || !(pUser = BuddyList_Find(pInst->hBuddyList, pszCmd))) + Send (pInst, "ERROR 547 ALTER APPLICATION CONNECT: Invalid user handle"); + else + { + Send (pInst, "ALTER APPLICATION libpurple_typing CONNECT %s", pszCmd); + Send (pInst, "APPLICATION CONNECTING %s", pszCmd); + Send (pInst, "APPLICATION libpurple_typing STREAMS %s:1", pszCmd); + // FIXME: Shouldn't we enumerate all STREAMS here? dunno... + } + } else + if (strcasecmp (pszCmd, "DATAGRAM") == 0) + { + char *pSep; + + if (!(pszCmd = strtok(NULL, " ")) || !(pSep = strchr(pszCmd, ':'))) + Send (pInst, "ERROR 551 ALTER APPLICATION DATAGRAM: Missing or invalid stream identifier"); + else + { + *pSep=0; + if (!(pUser = BuddyList_Find(pInst->hBuddyList, pszCmd))) + Send (pInst, "ERROR 551 ALTER APPLICATION DATAGRAM: Missing or invalid stream identifier"); + else + { + *pSep=':'; + if (!(pszCmd = strtok(NULL, " "))) + Send (pInst, "ERROR 541 APPLICATION: Operation failed"); + else + { + if (!strcmp (pszCmd, "PURPLE_TYPING")) + ImoSkype_Typing (pInst->hInst, pUser->pszUser, "typing"); + else if (!strcmp (pszCmd, "PURPLE_TYPED")) + ImoSkype_Typing (pInst->hInst, pUser->pszUser, "typed"); + else if (!strcmp (pszCmd, "PURPLE_NOT_TYPING")) + ImoSkype_Typing (pInst->hInst, pUser->pszUser, "not_typing"); + } + } + } + } + } + + } + else + if (strcasecmp(pszCmd, "CHAT") == 0) + { + char *pszChat; + NICKENTRY *pChat; + + if (!(pszChat = strtok(NULL, " ")) || + !(pChat=BuddyList_Find(pInst->hBuddyList, pszChat))) + { + Send (pInst, "ERROR 14 Invalid message id"); + return; + } + + + if (!(pszCmd = strtok(NULL, " "))) + { + Send (pInst, "ERROR 503 CHAT: Invalid or unknown action"); + return; + } + + if (strcasecmp (pszCmd, "ADDMEMBERS") == 0) + { + while(pszCmd = strtok(NULL, ", ")) + { + ImoSkype_GroupInvite (pInst->hInst, pChat->pszUser, pszCmd); + } + } + else if (strcasecmp (pszCmd, "KICK") == 0) + { + while(pszCmd = strtok(NULL, ", ")) + { + ImoSkype_GroupKick (pInst->hInst, pChat->pszUser, pszCmd); + } + } + else if (strcasecmp (pszCmd, "SETTOPIC") == 0) + { + if(pszCmd = strtok(NULL, "")) + { + ImoSkype_GroupTopic (pInst->hInst, pChat->pszUser, pszCmd); + } + } + else if (strcasecmp (pszCmd, "LEAVE") == 0) + { + if(pszCmd = strtok(NULL, "")) + { + ImoSkype_GroupLeave (pInst->hInst, pChat->pszUser); + } + } + else Send (pInst, "ERROR 503 CHAT: Invalid or unknown action"); + } else + Send (pInst, "ERROR 527 ALTER: unknown object type given"); + } + return; + } + else + if (strcasecmp(pszCmd, "NAME") == 0) + { + if (pszCmd = strtok(NULL, " ")) + { + if (pInst->pszClientName) free(pInst->pszClientName); + pInst->pszClientName = strdup(pszCmd); + } + Send (pInst, "OK"); + return; + } + else + { + Send (pInst, "ERROR 2 Not Implemented"); + } +} + +// ----------------------------------------------------------------------------- + diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.h new file mode 100644 index 0000000000..fa68dd3899 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.h @@ -0,0 +1,13 @@ +typedef void(*IMO2SCB)(char *pszMsg, void *pUser); +struct _tagIMOSAPI; +typedef struct _tagIMOSAPI IMOSAPI; + +#define IMO2S_FLAG_CURRTIMESTAMP 1 // Use current timestamp on MSG receive +#define IMO2S_FLAG_ALLOWINTERACT 2 // Allow GUI interaction (CALL) + +IMOSAPI *Imo2S_Init(IMO2SCB Callback, void *pUser, int iFlags); +void Imo2S_Exit (IMOSAPI *pInst); +void Imo2S_SetLog (IMOSAPI *pInst, FILE *fpLog); +int Imo2S_Login (IMOSAPI *pInst, char *pszUser, char *pszPass, char **ppszError); +void Imo2S_Logout(IMOSAPI *pInst); +int Imo2S_Send (IMOSAPI *pInst, char *pszMsg); diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.c new file mode 100644 index 0000000000..1615d6ac46 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.c @@ -0,0 +1,78 @@ +/* Module: imo2skypeproxy.c + Purpose: Implementation of imo2skype API as Skype proxy (for Miranda Skype plugin) + Author: leecher + Date: 01.09.2009 + + Changelog: + 1.00 - 01.09.2009 - Initial release + 1.01 - 02.09.2009 - Little bugfix for Onlinestatus, introduced mutex for send thread. + 1.02 - 02.09.2009 - Added support for incoming call notifications and expired sessions. + 1.03 - 03.09.2009 - As WIN32-port of libcurl is a total mess, Win32-version now uses WinINET. + 1.04 - 04.09.2009 - Added support for searching, adding and removing buddies + 1.05 - 06.09.2009 - * Mapped "busy" to DND, not NA, as forum user AL|EN proposed. + * Mood text will now also be sent on status change of a contact + (doesn't really have an effect though) + * New Parameter -d (daemonize) to launch proxy in background + * Fixed a bug with a crash when encoding umlauts on Win32 + 1.06 - 25.09.2009 - Added parameter -t for local timestamps. + 1.07 - 07.10.2009 - Bugfix: Added parsing of multiple JSON messages + Added support for writing to logfile while in daemon mode (-l) + 1.08 - 18.10.2009 - Added support for voice calls via imo.im flash on WIN32 (-i) + - Limited memory queues to 50 entries to reduce memory usage. + 1.09 - 07.11.2009 - Split command line main module and proxy module to make proxy + accessible by different layers (i.e. new Miranda Plugin layer) + 1.10 - 14.12.2009 - Bug in the cJson library. The authors used the String as second + sprintf-Parameter which contains the format string instead of + ["%s", StringParam] causing problems sending Messages containt a % + - Added some space in the dialog for translations and added Translate() + function to some strings in the Wrapper-DLL + - More verbose output if you enable logging + - Fixes a Bug that caused the plugin to block after going offline + and reconnecting back online + - Hopefully fixed a severe threading problem: The Send-Mutex was not + covering a full transaction, but only 1 send causing the receiver + the receive garbled data causing "An existing connection was forcibly + closed by the remote host." error. + - Imo2S_Exit freed the temporary buffer too early resulting in a crash + on exit. + 1.12 - 19.04.2010 - POST interface changed from www.imo.im/amy to s.imo.im/amy + 1.13 - 19.12.2010 - imo.im modified their interface, so tried to adapt the communication + routines at low level to be compatible again. There still may be + many bugs. Don't forget to turn off history logging in the options + at https://imo.im + There also seems to be a nice new feature called "reflection" so that + you can login from multiple sessions and messages etc. entered there + will be reflected to the current session. This may be addressed in one + of the next builds... + 1.14 - 02.03.2011 - Added a Skype WIN32-API Emulation Layer for better compatibility with + other clients that don't want to implement the socks-protocol, so that + we are compatible out-of-the-box. + - Added a few features to be compatible with libpurple. i.e. we now support + message numbering, even tough this is only supported in PROTOCOL 4. + - Added Keepalive packet sending to circumvent imo.im AutoAway. + 1.15 - 18.07.2012 - Avatar support + - Support for new imo.im protocol, can now be compiled to use old or new + protocol, in case there are troubles. New protocol enables participation + in groupchats generated with native Skype client with at least 3 + participants (still a bit experimental) + - WININET HTTPS communication layer now uses async calls to try to prevent + lockups on connection loss. +*/ + +#include +#include "imo2sproxy.h" + +// ----------------------------------------------------------------------------- +// PUBLIC +// ----------------------------------------------------------------------------- + +void Imo2sproxy_Defaults (IMO2SPROXY_CFG *pCfg) +{ + memset (pCfg, 0, sizeof(IMO2SPROXY_CFG)); + pCfg->fpLog = stdout; + pCfg->logerror = fprintf; +} + +/* Real implementation is now in socksproxy.c for the socket communication method + and in w32skypeemu.c for the Window messages Skype emulation + */ diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.h new file mode 100644 index 0000000000..dbdbbf1cf7 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.h @@ -0,0 +1,28 @@ +#include +#include "imo2skypeapi.h" +#ifndef WIN32 +#define __cdecl +#endif + +typedef struct +{ + int bVerbose; + FILE *fpLog; + int iFlags; + int (__cdecl *logerror)( FILE *stream, const char *format, ...); +// FIXME: user+pass from cmdline, until there is a possibility for +// a client to authenticate + char *pszUser; + char *pszPass; +} IMO2SPROXY_CFG; + +typedef struct tag_imo2sproxy IMO2SPROXY; + +struct tag_imo2sproxy +{ + int (*Open)(IMO2SPROXY*); + void (*Loop)(IMO2SPROXY*); + void (*Exit)(IMO2SPROXY*); +}; + +void Imo2sproxy_Defaults (IMO2SPROXY_CFG *pCfg); diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2stest.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2stest.c new file mode 100644 index 0000000000..3007e3ce06 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2stest.c @@ -0,0 +1,60 @@ +/* Module: imo2stest.c + Purpose: Simple test application for imo2skypeapi + Author: leecher + Date: 31.08.2009 +*/ +#include +#include +#include +#include "imo2skypeapi.h" + +// ----------------------------------------------------------------------------- +// Static +// ----------------------------------------------------------------------------- +static void Recv(char *pszMsg, void *pUser) +{ + printf ("< %s\n", pszMsg); +} + +// ----------------------------------------------------------------------------- +// EIP +// ----------------------------------------------------------------------------- +int main(int argc, char **argv) +{ + int iRet = -1; + IMOSAPI *pInst; + char *pszError = NULL; + + if (argc<3) + { + printf ("Usage: %s [username] [password]\n", argv[0]); + return -1; + } + + if (!(pInst = Imo2S_Init(Recv, NULL,0))) + { + fprintf (stderr, "Failed initialization.\n"); + return -1; + } + + /* Logon */ + if (Imo2S_Login(pInst, argv[1], argv[2], &pszError) == 1) + { + /* Dispatch loop */ + char szLine[4096]={0}; + + while (gets(szLine)) + { + Imo2S_Send (pInst, szLine); + memset (szLine, 0, sizeof(szLine)); + } + } + else + { + fprintf (stderr, "Login failed: %s\n", pszError); + return -1; + } + + Imo2S_Exit (pInst); + return iRet; +} diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/main.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/main.c new file mode 100644 index 0000000000..872509616d --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/main.c @@ -0,0 +1,197 @@ +/* Module: main.c + Purpose: Main commandline dispatcher for imo.im Skypeproxy + Author: leecher + Date: 07.11.2009 +*/ +#include +#include +#include "imo2sproxy.h" +#include "socksproxy.h" +#ifdef WIN32 +#include "w32skypeemu.h" +#define WIN32_LEAN_AND_MEAN +#include +#include +#define Daemonize FreeConsole() +#ifdef _DEBUG +#define LOG(_args_) printf _args_ +#ifndef _WIN64 +#include "crash.c" +#endif +#endif +#else +#define Daemonize daemon(0, 0) +#endif + +// ----------------------------------------------------------------------------- +// EIP +// ----------------------------------------------------------------------------- +int main(int argc, char **argv) +{ + int i, j=0, bDaemon = 0; + char cMode='s'; + IMO2SPROXY_CFG stCfg; + SOCKSPROXY_CFG stSocksCfg; +#ifdef WIN32 + W32SKYPEEMU_CFG stSypeEmuCfg; +#endif + IMO2SPROXY *pProxy; + +#ifdef _DEBUG + Crash_Init(); +#endif + + Imo2sproxy_Defaults (&stCfg); + SocksProxy_Defaults (&stSocksCfg); +#ifdef WIN32 + W32SkypeEmu_Defaults(&stSypeEmuCfg); +#endif + if (argc<3) + { + printf ("imo.im Skypeproxy V1.15 - (c) by leecher 2009-2012\n\n" + "%s [-d] [-v [-l ]] [-t] [-i]\n" + "[-m] [-h ] [-p ] \n\n" + "-d\t- Daemonize (detach from console)\n" + "-v\t- Verbose mode, log commands to console\n" + "-l\t- Set logfile to redirect verbose log to.\n" + "-t\t- Ignore server timestamp and use current time for messages\n" + "-i\t- Use interactive mode (starts imo.im flash app upon call)\n" + "-m\t- Specify connection mode to use:\n" + "\t\ts\tSocket mode (SkypeProxy protocol) [default]\n" +#ifdef WIN32 + "\t\ta\tSkype API Emulation via Window messages (real Skype API)\n" +#endif + "\tParameters for socket mode:\n" + "-h\t- Bind to a specific IP, not to all interfaces (default)\n" + "-p\t- Bind to another port (default: 1401)\n" + "Default: Bind to any interface, Use Port %d\n", argv[0], stSocksCfg.sPort); + return EXIT_FAILURE; + } + + for (i=1; iOpen(pProxy) == 0) + pProxy->Loop(pProxy); + pProxy->Exit(pProxy); + + if (stCfg.fpLog && stCfg.fpLog != stdout && stCfg.fpLog != stderr) + { + fclose(stCfg.fpLog); + stCfg.fpLog = NULL; + } + + return EXIT_SUCCESS; +} + diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/imoproxy.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/imoproxy.c new file mode 100644 index 0000000000..195f479ea6 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/imoproxy.c @@ -0,0 +1,882 @@ +/* Module: imoproxy.c + Purpose: Proxy-DLL for Miranda IM to load imo2sproxy as plugin + Author: leecher + Date: 26.10.2009 +*/ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include +#include +#include +#pragma comment (lib, "Ws2_32.lib") +#include +#include "io_layer.h" +#include "imo2sproxy.h" +#include "imo_request.h" +#include "socksproxy.h" +#include "w32skypeemu.h" +#include "skypepluginlink.h" +#include "include/newpluginapi.h" +#include "include/m_langpack.h" +#include "include/m_options.h" +#include "include/m_database.h" +#include "include/m_system.h" +#include "sdk/m_updater.h" +#include "resource.h" + +// Crash dumper +#ifdef _DEBUG +void CrashLog (const char *pszFormat, ...) +{ + static FILE *fpLog = NULL; + char szLine[1024]; + va_list ap; + + if (!fpLog) fpLog=fopen("imoproxy.log", "a"); + va_start(ap, pszFormat); + _vsnprintf(szLine, sizeof(szLine), pszFormat, ap); + va_end(ap); + + if (fpLog) + { + fprintf (fpLog, "%s", szLine); + fflush (fpLog); + } +} +#define LOG(_args_) CrashLog _args_ +#ifndef _WIN64 +#include "crash.c" +#endif +#endif + + +PLUGINLINK *pluginLink; +HINSTANCE m_hInst; +static HANDLE m_hOptHook=NULL, m_hPreShutdownHook=NULL, m_hHookModulesLoaded=NULL; + +#define PROXY_SOCKS 0 +#define PROXY_W32SKYPEEMU 1 +#define PROXY_SKYPEPLUGIN 2 +#define PROXY_MAX 3 + +static IMO2SPROXY_CFG m_stCfg; +static SOCKSPROXY_CFG m_stSocksCfg; +static W32SKYPEEMU_CFG m_stSypeEmuCfg; +static SKYPEPLUGINLINK_CFG m_stSkypePluginCfg; + +static IMO2SPROXY *m_apProxy[PROXY_MAX] = {0}; +static HANDLE m_hThread[PROXY_MAX]={0}, m_hEvent = INVALID_HANDLE_VALUE; +static BOOL m_bConsole = FALSE; + +#define ANY_SIZE 1 + +typedef struct _MIB_IPADDRROW { + DWORD dwAddr; + DWORD dwIndex; + DWORD dwMask; + DWORD dwBCastAddr; + DWORD dwReasmSize; + unsigned short unused1; + unsigned short wType; +}MIB_IPADDRROW, *PMIB_IPADDRROW; + +typedef struct _MIB_IPADDRTABLE { + DWORD dwNumEntries; + MIB_IPADDRROW table[ANY_SIZE]; +}MIB_IPADDRTABLE, *PMIB_IPADDRTABLE; + + +// Plugin Info +#define PINFO \ + "imo2sproxy-Plugin", \ + PLUGIN_MAKE_VERSION(1,0,0,15), \ + "Tunnelling Skype traffic via imo.im Web service", \ + "leecher", \ + "leecher@dose.0wnz.at", \ + "© 2010-2012 leecher", \ + "http://dose.0wnz.at", \ + 0, \ + 0 //doesn't replace anything built-in + + +PLUGININFO pluginInfo = { + sizeof(PLUGININFO), + PINFO +}; + +// New plugininfo +PLUGININFOEX pluginInfoEx = { + sizeof (pluginInfoEx), + PINFO, + { 0x3005c2b1, 0x4278, 0x470c, { 0x94, 0x98, 0x5, 0x95, 0x3d, 0xfa, 0x4d, 0x88 } } // // {3005C2B1-4278-470c-9498-05953DFA4D88} +}; + +// Whatever this is... +// {95061E8D-B18C-4c1c-8E14-686DE967D851} +#define MIID_IMOPROXY { 0x95061e8d, 0xb18c, 0x4c1c, { 0x8e, 0x14, 0x68, 0x6d, 0xe9, 0x67, 0xd8, 0x51 } } +static const MUUID interfaces[] = { MIID_IMOPROXY, MIID_LAST }; + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- + +int ShowError( FILE *stream, const char *format, ...) +{ + char szBuf[1024]; + va_list ap; + int iRet; + + va_start(ap, format); + iRet = _vsnprintf (szBuf, sizeof(szBuf), format, ap); + va_end(ap); + + MessageBox (NULL, szBuf, Translate("IMOPROXY Error"), MB_ICONSTOP | MB_OK); + return iRet; +} + +// ----------------------------------------------------------------------------- + +static void LoadSettings(void) +{ + DBVARIANT dbv; + + // General config + if (!m_bConsole) + { + if (DBGetContactSetting(NULL, "IMOPROXY", "Logfile", &dbv)==0) + { + if ((m_stCfg.bVerbose = DBGetContactSettingByte(NULL, "IMOPROXY", "Verbose", 0)) && + *dbv.pszVal) + { + if (m_stCfg.fpLog) fclose (m_stCfg.fpLog); + if (!(m_stCfg.fpLog = fopen(dbv.pszVal, "a"))) + { + char szMsg[MAX_PATH+64]; + + sprintf (szMsg, Translate("Cannot open Logfile %s for writing."), dbv.pszVal); + MessageBox(NULL,szMsg,"IMOPROXY", MB_OK | MB_ICONWARNING); + m_stCfg.bVerbose = FALSE; + } + } + DBFreeVariant(&dbv); + } + } + m_stCfg.iFlags = DBGetContactSettingDword(NULL, "IMOPROXY", "Flags", 0); + if (DBGetContactSetting(NULL, "IMOPROXY", "User", &dbv)==0) + { + if (m_stCfg.pszUser) free(m_stCfg.pszUser); + m_stCfg.pszUser = strdup(dbv.pszVal); + DBFreeVariant(&dbv); + } + if (DBGetContactSetting(NULL, "IMOPROXY", "Password", &dbv)==0) + { + if (m_stCfg.pszPass) free(m_stCfg.pszPass); + m_stCfg.pszPass = strdup(dbv.pszVal); + DBFreeVariant(&dbv); + } + + // Socks Proxy config + m_stSocksCfg.sPort = DBGetContactSettingWord(NULL, "IMOPROXY", "Port", 1401); + if (DBGetContactSetting(NULL, "IMOPROXY", "Host", &dbv)==0) + { + m_stSocksCfg.lAddr = inet_addr(dbv.pszVal); + DBFreeVariant(&dbv); + } +} + +// ----------------------------------------------------------------------------- + +static BOOL CheckSettings(int iMask) +{ + DBVARIANT dbv; + + if (iMask & PROXY_SOCKS) + { + if (DBGetContactSetting(NULL, SKYPE_PROTONAME, "Host", &dbv)==0) + { + if (DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseSkype2Socket", 0) && + (lstrcmp (dbv.pszVal, "127.0.0.1")==0 || + lstrcmp (dbv.pszVal, "localhost")==0) && + DBGetContactSettingWord(NULL, SKYPE_PROTONAME, "Port", 0) == + DBGetContactSettingWord(NULL, "IMOPROXY", "Port", 1401)) + { + DBFreeVariant(&dbv); + return TRUE; + } + DBFreeVariant(&dbv); + } + } + if (DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "FirstRun", 9) == 9) + { + MessageBox (NULL, Translate("SKYPE plugin may not be installed, this plugin only works together with " + "the SKYPE-plugin. Please check if you installed and enabled it."), "IMOPROXY", + MB_OK | MB_ICONWARNING); + } + else + { + + if ((iMask & PROXY_SOCKS) && !ServiceExists(SKYPE_PROTONAME PSS_SKYPEAPIMSG) ) + { + if (MessageBox (NULL, Translate("Your Skype plugin currently doesn't seem to be setup to use imo2proxy, " + "do you want me to change its settings so that it uses this plugins?"), "IMOPROXY", + MB_YESNO | MB_ICONQUESTION) == IDYES) + { + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "UseSkype2Socket", 1); + DBWriteContactSettingWord (NULL, SKYPE_PROTONAME, "Port", m_stSocksCfg.sPort); + DBWriteContactSettingString (NULL, SKYPE_PROTONAME, "Host", "127.0.0.1"); + return TRUE; + } + } + } + return FALSE; +} + +// ----------------------------------------------------------------------------- + +static BOOL EnumNetInterfaces (HWND hwndControl) +{ + HINSTANCE hLib; + BOOL bRet = FALSE; + + if (hLib = LoadLibrary("Iphlpapi.dll")) + { + PMIB_IPADDRTABLE pTable; + ULONG uSize=1; + DWORD i; + FARPROC GetIpAddrTable; + + if (GetIpAddrTable = (FARPROC)GetProcAddress (hLib, "GetIpAddrTable")) + { + if ((GetIpAddrTable (&pTable, &uSize, TRUE) == ERROR_INSUFFICIENT_BUFFER) && + (pTable = HeapAlloc (GetProcessHeap(), 0, uSize))) + { + if (GetIpAddrTable (pTable, &uSize, TRUE) == NO_ERROR) + { + struct in_addr addr; + + for (i=0; idwNumEntries; i++) + { + addr.S_un.S_addr = pTable->table[i].dwAddr; + SendMessage (hwndControl, CB_ADDSTRING, 0, (LPARAM)inet_ntoa(addr)); + } + bRet = pTable->dwNumEntries > 0; + } + HeapFree (GetProcessHeap(), 0, pTable); + } + } + FreeLibrary (hLib); + } + return bRet; +} + +// ----------------------------------------------------------------------------- + +static DWORD WINAPI ProxyThread(IMO2SPROXY *pProxy) +{ + if (pProxy->Open(pProxy)<0) return -1; + SetEvent (m_hEvent); + pProxy->Loop(pProxy); + return 0; +} + +// ----------------------------------------------------------------------------- + +static BYTE GetProxies(void) +{ + return DBGetContactSettingByte(NULL, "IMOPROXY", "Proxies", + (ServiceExists(SKYPE_PROTONAME PSS_SKYPEAPIMSG)?(1<Open(m_apProxy[i])<0) + { + m_apProxy[i]->Exit(m_apProxy[i]); + return FALSE; + } + return TRUE; + default: + return FALSE; + } + if (!m_apProxy[i]) return FALSE; + + // As for example W32SKYPEEMU runs its own messagepump and the Window is + // Registered in the Open-Function (as it can fail), we have to start + // our Mainloop-Thread and wait for the Open() part to finish. + // If it worked ok, the loop will start to run, otherwise we return + // an error. So we need a Mutex for synchronisation. + m_hEvent = ahEvents[1] = CreateEvent (NULL, FALSE, FALSE, NULL); + + if (!(m_hThread[i] = ahEvents[0] = (HANDLE)_beginthreadex (NULL, 0, ProxyThread, m_apProxy[i], 0, &dwThreadId))) + { + MessageBox (NULL, Translate("IMOPROXY Cannot start dispatch thread"), "IMOPROXY", MB_OK | MB_ICONSTOP); + CloseHandle (m_hEvent); + m_apProxy[i]->Exit(m_apProxy[i]); + return FALSE; + } + + bRet = WaitForMultipleObjects (2, ahEvents, FALSE, INFINITE)==WAIT_OBJECT_0+1; + CloseHandle (m_hEvent); + return bRet; +} + +// ----------------------------------------------------------------------------- + +static void StopProxy (int i) +{ + if (m_apProxy[i]) + { + m_apProxy[i]->Exit(m_apProxy[i]); + m_apProxy[i] = NULL; + } + + if (m_hThread[i]) + { + if (WaitForSingleObject (m_hThread[i], 3000) != WAIT_OBJECT_0) + TerminateThread (m_hThread[i], -1); + m_hThread[i] = NULL; + } +} + +// ----------------------------------------------------------------------------- + +static BOOL StartProxies(int iMask) +{ + int i; + BOOL bRet=TRUE; + + for (i=0; i= 0x080000) + { + EnableWindow (GetDlgItem (hWnd, IDC_USENETLIB), TRUE); + if (DBGetContactSettingByte (NULL, "IMOPROXY", "UseNetlib", 0)) + CheckDlgButton (hWnd, IDC_USENETLIB, BST_CHECKED); + } + SetDlgItemText (hWnd, IDC_LOGFILE, szOldLog); + if (bOldVerbose = DBGetContactSettingByte(NULL, "IMOPROXY", "Verbose", 0)) + CheckDlgButton (hWnd, IDC_LOG, BST_CHECKED); + else + { + EnableWindow (GetDlgItem (hWnd, IDC_LOGFILE), FALSE); + EnableWindow (GetDlgItem (hWnd, IDC_OPEN), FALSE); + } + if (DBGetContactSetting(NULL, "IMOPROXY", "User", &dbv)==0) + { + lstrcpyn (szOldUser, dbv.pszVal, sizeof(szOldUser)); + DBFreeVariant(&dbv); + } + SetDlgItemText (hWnd, IDC_USERNAME, szOldUser); + if (DBGetContactSetting(NULL, "IMOPROXY", "Password", &dbv)==0) + { + lstrcpyn (szOldPass, dbv.pszVal, sizeof(szOldPass)); + DBFreeVariant(&dbv); + } + iOldProxies= GetProxies(); + CheckDlgButton (hWnd, IDC_USESOCKS, (iOldProxies&(1<code) + { + case PSN_APPLY: + case PSN_KILLACTIVE: + { + int iFlags=0, iProxies=0; + short sPort; + char szHost[64], szLog[MAX_PATH], szUser[64], szPass[64]; + BOOL bVerbose; + + GetDlgItemText (hWnd, IDC_BINDIP, szHost, sizeof(szHost)); + DBWriteContactSettingString (NULL, "IMOPROXY", "Host", szHost); + DBWriteContactSettingWord (NULL, "IMOPROXY", "Port", + (sPort = GetDlgItemInt (hWnd, IDC_BINDPORT, NULL, FALSE))); + if (IsDlgButtonChecked (hWnd, IDC_INTERACT)==BST_CHECKED) + iFlags|=IMO2S_FLAG_ALLOWINTERACT; + if (IsDlgButtonChecked (hWnd, IDC_CURRTIMESTAMP)==BST_CHECKED) + iFlags|=IMO2S_FLAG_CURRTIMESTAMP; + GetDlgItemText (hWnd, IDC_USERNAME, szUser, sizeof(szUser)); + DBWriteContactSettingString (NULL, "IMOPROXY", "User", szUser); + GetDlgItemText (hWnd, IDC_PASSWORD, szPass, sizeof(szPass)); + DBWriteContactSettingString (NULL, "IMOPROXY", "Password", szPass); + DBWriteContactSettingDword (NULL, "IMOPROXY", "Flags", iFlags); + DBWriteContactSettingByte(NULL, "IMOPROXY", "Verbose", + (char)(bVerbose = (IsDlgButtonChecked (hWnd, IDC_LOG)==BST_CHECKED))); + GetDlgItemText (hWnd, IDC_LOGFILE, szLog, sizeof(szLog)); + DBWriteContactSettingString (NULL, "IMOPROXY", "Logfile", szLog); + if (IsDlgButtonChecked (hWnd, IDC_USESOCKS)==BST_CHECKED) + iProxies|=(1<Skype to imo.im Gateway "; + update.szBetaUpdateURL = "http://dose.0wnz.at/miranda/Skype/imo2sproxy_w32_binonly.zip"; + update.szBetaVersionURL = "http://dose.0wnz.at/miranda/Skype/"; + update.pbBetaVersionPrefix = (BYTE *)"imo2sproxy version "; +#endif + + update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix); + update.cpbBetaVersionPrefix = strlen((char *)update.pbBetaVersionPrefix); + + CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update); + + } +} + +// ----------------------------------------------------------------------------- + +int PreShutdown(WPARAM wParam, LPARAM lParam) +{ + OutputDebugString ("IMOPROXY: PreShutdown"); + StopProxies (-1); + if (m_stCfg.fpLog && m_stCfg.fpLog != stdout && m_stCfg.fpLog != stderr) + { + fclose(m_stCfg.fpLog); + m_stCfg.fpLog = NULL; + } + if (m_stCfg.pszUser) + { + free(m_stCfg.pszUser); + m_stCfg.pszUser = NULL; + } + if (m_stCfg.pszPass) + { + free(m_stCfg.pszPass); + m_stCfg.pszPass = NULL; + } + + FreeConsole(); + return 0; +} + +// ----------------------------------------------------------------------------- + +int OnModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + BYTE CheckSkype = DBGetContactSettingByte (NULL, "IMOPROXY", "CheckSkype", 2); + if (CheckSkype) CheckSettings(-1); + if (CheckSkype == 2) DBWriteContactSettingByte (NULL, "IMOPROXY", "CheckSkype", 0); + RegisterToUpdate(); + + // On Miranda 0.0.0.8+ NETLIB suppotrs HTTPS, therefore we can use + // Netlib there + if (CallService (MS_SYSTEM_GETVERSION, 0, 0) >= 0x080000 && + DBGetContactSettingByte (NULL, "IMOPROXY", "UseNetlib", 0)) + ImoRq_SetIOLayer (IoLayerNETLIB_Init); + StartProxies(-1); + + return 0; +} + +// ----------------------------------------------------------------------------- + +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + m_hInst=hinstDLL; + return TRUE; +} + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- + +__declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +// ----------------------------------------------------------------------------- + +// New plugin API +__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfoEx; +} + +// ----------------------------------------------------------------------------- + +__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + +// ----------------------------------------------------------------------------- + +int __declspec(dllexport) Load(PLUGINLINK *link) +{ + +#ifdef _DEBUG + Crash_Init(); +#endif + pluginLink = link; + + // Init IMO2S config structures + Imo2sproxy_Defaults (&m_stCfg); + SocksProxy_Defaults (&m_stSocksCfg); + W32SkypeEmu_Defaults(&m_stSypeEmuCfg); + SkypePluginLink_Defaults(&m_stSkypePluginCfg); + m_stCfg.logerror = ShowError; + LoadSettings(); + + m_hOptHook = HookEvent(ME_OPT_INITIALISE, RegisterOptions); + m_hPreShutdownHook = HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown); + m_hHookModulesLoaded = HookEvent( ME_SYSTEM_MODULESLOADED, OnModulesLoaded); + + OutputDebugString ("IMOPROXY: Loaded"); + return 0; +} + +// ----------------------------------------------------------------------------- + +int __declspec(dllexport) Unload(void) +{ + OutputDebugString ("IMOPROXY: Unload"); + UnhookEvent(m_hOptHook); + UnhookEvent(m_hPreShutdownHook); + UnhookEvent(m_hHookModulesLoaded); + return 0; +} diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/io_layer_netlib.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/io_layer_netlib.c new file mode 100644 index 0000000000..378f72e65f --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/io_layer_netlib.c @@ -0,0 +1,340 @@ +/* Module: io_layer_netlib.c + Purpose: IO Layer for Internet communication using Miranda NETLIB + Author: leecher + Date: 20.04.2011 :=) +*/ +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include "include/newpluginapi.h" +#include "include/m_netlib.h" +#include "fifo.h" +#include "memlist.h" +#include "io_layer.h" + +#define USER_AGENT "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13" + +typedef struct +{ + IOLAYER vtbl; + int iRecursion; + NETLIBHTTPREQUEST *nlhrReply; + LPVOID lpErrorBuf; + HANDLE nlc; +} IOLAYER_INST; + +typedef struct +{ + HANDLE hNetlib; + TYP_LIST *hCookies; + TYP_FIFO *hCookieStr; + char *pszCookies; + LONG lRefCount; + CRITICAL_SECTION cs; +} IOLAYER_SINGLETON; + +static IOLAYER_SINGLETON *m_hNL = NULL; + +static void IoLayer_Exit (IOLAYER *hPIO); +static char *IoLayer_Post(IOLAYER *hPIO, char *pszURL, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength); +static char *IoLayer_Get(IOLAYER *hIO, char *pszURL, unsigned int *pdwLength); +static void IoLayer_Cancel(IOLAYER *hIO); +static char *IoLayer_GetLastError(IOLAYER *hIO); +static char *IoLayer_EscapeString(IOLAYER *hPIO, char *pszData); +static void IoLayer_FreeEscapeString(char *pszData); +static void FetchLastError (IOLAYER_INST *hIO); +static void add_cookies(char *pszCookies); +static void refresh_cookies(); +static HANDLE *OpenConnection(NETLIBHTTPREQUEST *nlhr); + +// ----------------------------------------------------------------------------- +// Interface +// ----------------------------------------------------------------------------- + +IOLAYER *IoLayerNETLIB_Init(void) +{ + IOLAYER_INST *hIO; + + if (CallService (MS_SYSTEM_GETVERSION, 0, 0) < 0x080000 || // Miranda HTTPS support starting with 0.8.0.0 + !(hIO = calloc(1, sizeof(IOLAYER_INST)))) + return NULL; + + // NETLIB only works as singleton + if (!m_hNL) + { + NETLIBUSER nlu={0}; + + if (!(m_hNL = calloc (1, sizeof(IOLAYER_SINGLETON)))) + { + free (hIO); + return NULL; + } + m_hNL->lRefCount++; + + // Init Netlib + nlu.cbSize = sizeof(nlu); + nlu.flags = NUF_OUTGOING; + nlu.szDescriptiveName = "imo2sproxy connection"; + nlu.szSettingsModule = "IMOPROXY"; + nlu.szHttpGatewayUserAgent = USER_AGENT; + if (!(m_hNL->hNetlib = (HANDLE)CallService (MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu)) || + !(m_hNL->hCookies = List_Init(0)) || + !(m_hNL->hCookieStr = Fifo_Init(0))) + { + IoLayer_Exit((IOLAYER*)hIO); + return NULL; + } + m_hNL->pszCookies = ""; + InitializeCriticalSection (&m_hNL->cs); + } else m_hNL->lRefCount++; + + // Init Vtbl + hIO->vtbl.Exit = IoLayer_Exit; + hIO->vtbl.Post = IoLayer_Post; + hIO->vtbl.Get = IoLayer_Get; + hIO->vtbl.Cancel = IoLayer_Cancel; + hIO->vtbl.GetLastError = IoLayer_GetLastError; + hIO->vtbl.EscapeString = IoLayer_EscapeString; + hIO->vtbl.FreeEscapeString = IoLayer_FreeEscapeString; + + return (IOLAYER*)hIO; +} +// ----------------------------------------------------------------------------- + +static void IoLayer_Exit (IOLAYER *hPIO) +{ + IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; + + if (hIO->nlhrReply) CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)hIO->nlhrReply); + if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf); + if (InterlockedDecrement(&m_hNL->lRefCount) <= 0) + { + if (m_hNL->hNetlib) Netlib_CloseHandle (m_hNL->hNetlib); + if (m_hNL->hCookies) { + List_FreeElements(m_hNL->hCookies); + List_Exit (m_hNL->hCookies); + } + if (m_hNL->hCookieStr) Fifo_Exit(m_hNL->hCookieStr); + DeleteCriticalSection (&m_hNL->cs); + free (m_hNL); + m_hNL = NULL; + } + free (hIO); +} + +// ----------------------------------------------------------------------------- + +static char *IoLayer_Post(IOLAYER *hPIO, char *pszURL, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength) +{ + IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; + NETLIBHTTPREQUEST nlhr={0}; + NETLIBHTTPHEADER headers[5]; + int i; + char *pszCookies = NULL; + + + /* + char szDbg[256]; + sprintf (szDbg, "Thread %d with hIO %08X requests %s\n", GetCurrentThreadId(), hIO, pszURL); + OutputDebugString(szDbg); + */ + + // Build basic request + nlhr.cbSize = sizeof(nlhr); + nlhr.flags = NLHRF_GENERATEHOST | NLHRF_SMARTREMOVEHOST | NLHRF_REDIRECT; + if (!pdwLength) nlhr.flags |= NLHRF_DUMPASTEXT; // pdwLength needed -> Binary data + nlhr.requestType = pszPostFields?REQUEST_POST:REQUEST_GET; + nlhr.szUrl = pszURL; + nlhr.pData = pszPostFields; + nlhr.dataLength = cbPostFields; + nlhr.headers = headers; + + // Add headers + EnterCriticalSection (&m_hNL->cs); + if (m_hNL->pszCookies && *m_hNL->pszCookies) + { + headers[nlhr.headersCount].szName = "Cookie"; + headers[nlhr.headersCount++].szValue = pszCookies = strdup(m_hNL->pszCookies); + } + headers[nlhr.headersCount].szName = "User-Agent"; + headers[nlhr.headersCount++].szValue = USER_AGENT; + headers[nlhr.headersCount].szName = "Accept-Encoding"; + headers[nlhr.headersCount++].szValue = "deflate, gzip"; + headers[nlhr.headersCount].szName = "Content-Type"; + headers[nlhr.headersCount++].szValue = "application/x-www-form-urlencoded; charset=UTF-8"; + headers[nlhr.headersCount].szName = "X-Requested-With"; + headers[nlhr.headersCount++].szValue = "XMLHttpRequest"; + LeaveCriticalSection (&m_hNL->cs); + + // Do the transaction + nlhr.nlc = hIO->nlc = OpenConnection (&nlhr); + if (hIO->nlhrReply) CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)hIO->nlhrReply); + hIO->nlhrReply = (NETLIBHTTPREQUEST*)CallService (MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNL->hNetlib, (LPARAM)&nlhr); + hIO->nlc = NULL; + + if (pszCookies) free (pszCookies); + if (!hIO->nlhrReply) + { + FetchLastError (hIO); + return NULL; + } + + if (!hIO->nlhrReply || !hIO->nlhrReply->dataLength || !hIO->nlhrReply->pData) + { + if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf); + if (hIO->lpErrorBuf = LocalAlloc (LPTR, 64)) + strcpy (hIO->lpErrorBuf, "Reply contained no data"); + return NULL; + } + + // Error handling + if (hIO->nlhrReply->resultCode < 200 || hIO->nlhrReply->resultCode >= 300) + { + if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf); + if (hIO->lpErrorBuf = LocalAlloc (LPTR, 64)) + sprintf (hIO->lpErrorBuf, "HTTP transaction returned status %d", hIO->nlhrReply->resultCode); + return NULL; + } + + // Process headers to collect cookies + EnterCriticalSection (&m_hNL->cs); + for (i=0; inlhrReply->headersCount; i++) + { + if (!strnicmp(hIO->nlhrReply->headers[i].szName, "Set-Cookie", 10)) + add_cookies(hIO->nlhrReply->headers[i].szValue); + } + LeaveCriticalSection (&m_hNL->cs); + + // Return reply + if (pdwLength) *pdwLength = hIO->nlhrReply->dataLength; + return hIO->nlhrReply->pData; +} + +// ----------------------------------------------------------------------------- + +static char *IoLayer_Get(IOLAYER *hIO, char *pszURL, unsigned int *pdwLength) +{ + return IoLayer_Post (hIO, pszURL, NULL, 0, pdwLength); +} + +// ----------------------------------------------------------------------------- + +static void IoLayer_Cancel(IOLAYER *hPIO) +{ + IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; + + if (hIO->nlc && Netlib_CloseHandle(hIO->nlc)) + hIO->nlc = NULL; +} + +// ----------------------------------------------------------------------------- + +static char *IoLayer_GetLastError(IOLAYER *hIO) +{ + return (char*)((IOLAYER_INST*)hIO)->lpErrorBuf; +} + +// ----------------------------------------------------------------------------- + +static char *IoLayer_EscapeString(IOLAYER *hPIO, char *pszData) +{ + return (char*)CallService (MS_NETLIB_URLENCODE, 0, (LPARAM)pszData); +} + +// ----------------------------------------------------------------------------- + +static void IoLayer_FreeEscapeString(char *pszData) +{ + HeapFree(GetProcessHeap(), 0, pszData); +} + +// ----------------------------------------------------------------------------- +// Static +// ----------------------------------------------------------------------------- + +static void FetchLastError (IOLAYER_INST *hIO) +{ + if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, + GetLastError(), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), + (LPTSTR)&hIO->lpErrorBuf, 0, NULL); +} + +// ----------------------------------------------------------------------------- + +static void add_cookies(char *pszCookies) +{ + int i, nCount, iLenCmp, iLenCookie; + char *p, *pszCookie = NULL; + + if (!(p = strchr(pszCookies, '='))) return; + iLenCmp=p-pszCookies+1; + if ((p=strchr (p, ';')) || (p=strchr (p, ';'))) iLenCookie = p-pszCookies; + else iLenCookie=strlen(pszCookies); + + for (i=0, nCount=List_Count(m_hNL->hCookies); ihCookies, i); + if (!strncmp(pszCookie, pszCookies, iLenCmp)) + break; + } + + if (i==nCount) pszCookie = NULL; + if (pszCookie = realloc (pszCookie, iLenCookie+1)) + { + strncpy (pszCookie, pszCookies, iLenCookie); + pszCookie[iLenCookie]=0; + if (ihCookies, pszCookie, i); + else + List_Push (m_hNL->hCookies, pszCookie); + } + refresh_cookies (); +} + +// ----------------------------------------------------------------------------- + +static void refresh_cookies() +{ + int i, nCount; + + Fifo_Reset (m_hNL->hCookieStr); + for (i=0, nCount=List_Count(m_hNL->hCookies); ihCookies, i); + Fifo_Add (m_hNL->hCookieStr, pszCookie, strlen(pszCookie)); + Fifo_Add (m_hNL->hCookieStr, "; ", 2); + } + Fifo_Add (m_hNL->hCookieStr, "", 1); + m_hNL->pszCookies = Fifo_Get (m_hNL->hCookieStr, NULL); +} + +// ----------------------------------------------------------------------------- + +static HANDLE *OpenConnection(NETLIBHTTPREQUEST *nlhr) +{ + NETLIBOPENCONNECTION nloc={0}; + BOOL secur = (nlhr->flags & NLHRF_SSL) || _strnicmp(nlhr->szUrl, "https", 5) == 0; + char* phost = strstr(nlhr->szUrl, "://"); + char *ppath, *pcolon; + + // Poor man's InternetCrackUrl + nloc.cbSize = sizeof(NETLIBOPENCONNECTION); + if (phost) phost+=3; else phost=nlhr->szUrl; + nloc.szHost = _alloca (strlen(phost)+1); + strcpy ((char*)nloc.szHost, phost); + if (ppath = strchr(nloc.szHost, '/')) *ppath = '\0'; + if (pcolon = strrchr(nloc.szHost, ':')) + { + *pcolon = '\0'; + nloc.wPort = (WORD)strtol(pcolon+1, NULL, 10); + } + else nloc.wPort = secur ? 443 : 80; + nloc.flags = (secur ? NLOCF_SSL : 0) | NLOCF_HTTP; + if (secur) nlhr->flags |= NLHRF_SSL; else nlhr->flags &= ~NLHRF_SSL; + + // Open connection + return (HANDLE)CallService (MS_NETLIB_OPENCONNECTION, (WPARAM)m_hNL->hNetlib, (LPARAM)&nloc); +} \ No newline at end of file diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.aps b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.aps new file mode 100644 index 0000000000..280086f42b Binary files /dev/null and b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.aps differ diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.rc b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.rc new file mode 100644 index 0000000000..487426fbfe --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.rc @@ -0,0 +1,145 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Deutsch (Цsterreich) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEA) +#ifdef _WIN32 +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN_AUSTRIAN +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPTIONS DIALOGEX 0, 0, 287, 224 +STYLE WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Sans Serif" +BEGIN + GROUPBOX "Account information",IDC_STATIC,7,7,273,31 + LTEXT "Username:",IDC_STATIC,17,20,53,9 + EDITTEXT IDC_USERNAME,74,18,56,12,ES_AUTOHSCROLL + LTEXT "Password:",IDC_STATIC,135,20,47,9 + EDITTEXT IDC_PASSWORD,185,18,56,12,ES_PASSWORD | ES_AUTOHSCROLL + CONTROL "Support for Voicecalls via imo.im Flash in Internet Explorer", + IDC_INTERACT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,42, + 273,9 + CONTROL "Ignore server timestamp and use current time for messages", + IDC_CURRTIMESTAMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 7,60,273,10 + CONTROL "Log traffic to file:",IDC_LOG,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,7,71,110,10 + EDITTEXT IDC_LOGFILE,119,71,128,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_OPEN,248,71,14,12 + LTEXT "Status:",IDC_STATIC,126,140,29,10 + LTEXT "Stopped",IDC_STATUSSOCKS,157,140,54,9,SS_SUNKEN + GROUPBOX "Socket Proxy",IDC_STATIC,7,129,273,45 + LTEXT "Bind to address:",IDC_STATIC,17,157,73,9 + COMBOBOX IDC_BINDIP,95,155,75,12,CBS_DROPDOWN | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + LTEXT "Port:",IDC_STATIC,179,157,31,9 + EDITTEXT IDC_BINDPORT,211,155,31,12,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "Use Socket Proxy",IDC_USESOCKS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,18,140,81,9 + PUSHBUTTON "Start",IDC_STARTSOCKS,216,137,30,12 + PUSHBUTTON "Stop",IDC_STOPSOCKS,246,137,30,12,WS_DISABLED + GROUPBOX "Skype compatible communication API",IDC_STATIC,7,177, + 273,40 + LTEXT "Caution: Don't use this if you have the Skype application running!", + IDC_STATIC,13,188,260,8 + LTEXT "Status:",IDC_STATIC,126,201,29,10 + LTEXT "Stopped",IDC_STATUSCOMM,158,201,54,9,SS_SUNKEN + CONTROL "Use compatible comm API",IDC_USECOMM,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,18,201,105,9 + PUSHBUTTON "Start",IDC_STARTCOMM,216,198,30,12 + PUSHBUTTON "Stop",IDC_STOPCOMM,246,198,30,12,WS_DISABLED + CONTROL "Console",IDC_CONSOLE,"Button",BS_AUTOCHECKBOX | + BS_PUSHLIKE | WS_TABSTOP,216,87,45,11 + GROUPBOX "Skype Plugin 0.0.0.46+ internal communication link", + IDC_STATIC,7,102,273,25 + LTEXT "Status:",IDC_STATIC,126,113,29,10 + LTEXT "Stopped",IDC_STATUSSKYPEPL,158,113,54,9,SS_SUNKEN + CONTROL "Use plugin link",IDC_USESKYPEPL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,18,113,105,9 + PUSHBUTTON "Start",IDC_STARTSKYPEPL,216,110,30,12 + PUSHBUTTON "Stop",IDC_STOPSKYPEPL,246,110,30,12,WS_DISABLED + CONTROL "Use Netlib instead of WinInet (Experimental)", + IDC_USENETLIB,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,7,51,273,9 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_OPTIONS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 280 + TOPMARGIN, 7 + BOTTOMMARGIN, 217 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Deutsch (Цsterreich) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/resource.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/resource.h new file mode 100644 index 0000000000..e0da6bef1d --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/resource.h @@ -0,0 +1,39 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by res.rc +// +#define IDD_OPTIONS 101 +#define IDC_BINDPORT 1001 +#define IDC_BINDIP 1002 +#define IDC_INTERACT 1003 +#define IDC_CURRTIMESTAMP 1004 +#define IDC_LOG 1005 +#define IDC_LOGFILE 1006 +#define IDC_OPEN 1007 +#define IDC_USERNAME 1008 +#define IDC_PASSWORD 1009 +#define IDC_STATUSSOCKS 1010 +#define IDC_STATUSCOMM 1011 +#define IDC_STATUSSKYPEPL 1012 +#define IDC_USESOCKS 1013 +#define IDC_STARTSOCKS 1014 +#define IDC_STOPSOCKS 1015 +#define IDC_USECOMM 1016 +#define IDC_STARTCOMM 1017 +#define IDC_STOPCOMM 1018 +#define IDC_CONSOLE 1019 +#define IDC_USESKYPEPL 1020 +#define IDC_STARTSKYPEPL 1021 +#define IDC_STOPSKYPEPL 1022 +#define IDC_USENETLIB 1023 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1020 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/sdk/m_updater.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/sdk/m_updater.h new file mode 100644 index 0000000000..371b7437a0 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/sdk/m_updater.h @@ -0,0 +1,146 @@ +#ifndef _M_UPDATER_H +#define _M_UPDATER_H + +// NOTES: +// - For langpack updates, include a string of the following format in the langpack text file: +// ";FLID: " +// version must be four numbers seperated by '.', in the range 0-255 inclusive +// - Updater will disable plugins that are downloaded but were not active prior to the update (this is so that, if an archive contains e.g. ansi and +// unicode versions, the correct plugin will be the only one active after the new version is installed)...so if you add a support plugin, you may need +// to install an ini file to make the plugin activate when miranda restarts after the update +// - Updater will replace all dlls that have the same internal shortName as a downloaded update dll (this is so that msn1.dll and msn2.dll, for example, +// will both be updated) - so if you have a unicode and a non-unicode version of a plugin in your archive, you should make the internal names different (which will break automatic +// updates from the file listing if there is only one file listing entry for both versions, unless you use the 'MS_UPDATE_REGISTER' service below) +// - Updater will install all files in the root of the archive into the plugins folder, except for langpack files that contain the FLID string which go into the root folder (same +// folder as miranda32.exe)...all folders in the archive will also be copied to miranda's root folder, and their contents transferred into the new folders. The only exception is a +// special folder called 'root_files' - if there is a folder by that name in the archive, it's contents will also be copied into miranda's root folder - this is intended to be used +// to install additional dlls etc that a plugin may require) + +// if you set Update.szUpdateURL to the following value when registering, as well as setting your beta site and version data, +// Updater will ignore szVersionURL and pbVersionPrefix, and attempt to find the file listing URL's from the backend XML data. +// for this to work, the plugin name in pluginInfo.shortName must match the file listing exactly (except for case) +#define UPDATER_AUTOREGISTER "UpdaterAUTOREGISTER" +// Updater will also use the backend xml data if you provide URL's that reference the miranda file listing for updates (so you can use that method +// if e.g. your plugin shortName does not match the file listing) - it will grab the file listing id from the end of these URLs + +typedef struct Update_tag { + int cbSize; + char *szComponentName; // component name as it will appear in the UI (will be translated before displaying) + + char *szVersionURL; // URL where the current version can be found (NULL to disable) + BYTE *pbVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data + // (note that this URL could point at a binary file - dunno why, but it could :) + int cpbVersionPrefix; // number of bytes pointed to by pbVersionPrefix + char *szUpdateURL; // URL where dll/zip is located + // set to UPDATER_AUTOREGISTER if you want Updater to find the file listing URLs (ensure plugin shortName matches file listing!) + + char *szBetaVersionURL; // URL where the beta version can be found (NULL to disable betas) + BYTE *pbBetaVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data + int cpbBetaVersionPrefix; // number of bytes pointed to by pbVersionPrefix + char *szBetaUpdateURL; // URL where dll/zip is located + + BYTE *pbVersion; // bytes of current version, used for comparison with those in VersionURL + int cpbVersion; // number of bytes pointed to by pbVersion + + char *szBetaChangelogURL; // url for displaying changelog for beta versions +} Update; + +// register a comonent with Updater +// +// wparam = 0 +// lparam = (LPARAM)&Update +#define MS_UPDATE_REGISTER "Update/Register" + +// utility functions to create a version string from a DWORD or from pluginInfo +// point buf at a buffer at least 16 chars wide - but note the version string returned may be shorter +// +__inline static char *CreateVersionString(DWORD version, char *buf) { + mir_snprintf(buf, 16, "%d.%d.%d.%d", (version >> 24) & 0xFF, (version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF); + return buf; +} + +__inline static char *CreateVersionStringPlugin(PLUGININFO *pluginInfo, char *buf) { + return CreateVersionString(pluginInfo->version, buf); +} + + +// register the 'easy' way - use this method if you have no beta URL and the plugin is on the miranda file listing +// NOTE: the plugin version string on the file listing must be the string version of the version in pluginInfo (i.e. 0.0.0.1, +// four numbers between 0 and 255 inclusivem, so no letters, brackets, etc.) +// +// wParam = (int)fileID - this is the file ID from the file listing (i.e. the number at the end of the download link) +// lParam = (PLUGININFO*)&pluginInfo +#define MS_UPDATE_REGISTERFL "Update/RegisterFL" + +// this function can be used to 'unregister' components - useful for plugins that register non-plugin/langpack components and +// may need to change those components on the fly +// lParam = (char *)szComponentName +#define MS_UPDATE_UNREGISTER "Update/Unregister" + +// this event is fired when the startup process is complete, but NOT if a restart is imminent +// it is designed for status managment plugins to use as a trigger for beggining their own startup process +// wParam = lParam = 0 (unused) +// (added in version 0.1.6.0) +#define ME_UPDATE_STARTUPDONE "Update/StartupDone" + +// this service can be used to enable/disable Updater's global status control +// it can be called from the StartupDone event handler +// wParam = (BOOL)enable +// lParam = 0 +// (added in version 0.1.6.0) +#define MS_UPDATE_ENABLESTATUSCONTROL "Update/EnableStatusControl" + +// An description of usage of the above service and event: +// Say you are a status control plugin that normally sets protocol or global statuses in your ModulesLoaded event handler. +// In order to make yourself 'Updater compatible', you would move the status control code from ModulesLoaded to another function, +// say DoStartup. Then, in ModulesLoaded you would check for the existence of the MS_UPDATE_ENABLESTATUSCONTROL service. +// If it does not exist, call DoStartup. If it does exist, hook the ME_UPDATE_STARTUPDONE event and call DoStartup from there. You may +// also wish to call MS_UPDATE_ENABLESTATUSCONTROL with wParam == FALSE at this time, to disable Updater's own status control feature. + +// this service can be used to determine whether updates are possible for a component with the given name +// wParam = 0 +// lParam = (char *)szComponentName +// returns TRUE if updates are supported, FALSE otherwise +#define MS_UPDATE_ISUPDATESUPPORTED "Update/IsUpdateSupported" + +#endif + + +/////////////// Usage Example /////////////// + +#ifdef EXAMPLE_CODE + +// you need to #include "m_updater.h" and HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded) in your Load function... + +int OnModulesLoaded(WPARAM wParam, LPARAM lParam) { + + Update update = {0}; // for c you'd use memset or ZeroMemory... + char szVersion[16]; + + update.cbSize = sizeof(Update); + + update.szComponentName = pluginInfo.shortName; + update.pbVersion = (BYTE *)CreateVersionString(&pluginInfo, szVersion); + update.cpbVersion = strlen((char *)update.pbVersion); + + // these are the three lines that matter - the archive, the page containing the version string, and the text (or data) + // before the version that we use to locate it on the page + // (note that if the update URL and the version URL point to standard file listing entries, the backend xml + // data will be used to check for updates rather than the actual web page - this is not true for beta urls) + update.szUpdateURL = "http://scottellis.com.au:81/test/updater.zip"; + update.szVersionURL = "http://scottellis.com.au:81/test/updater_test.html"; + update.pbVersionPrefix = (BYTE *)"Updater version "; + + update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix); + + // do the same for the beta versions of the above struct members if you wish to allow beta updates from another URL + + CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update); + + // Alternatively, to register a plugin with e.g. file ID 2254 on the file listing... + // CallService(MS_UPDATE_REGISTERFL, (WPARAM)2254, (LPARAM)&pluginInfo); + + return 0; +} + +#endif diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.c new file mode 100644 index 0000000000..0109bd6ede --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.c @@ -0,0 +1,233 @@ +#include "imo2sproxy.h" +#define WIN32_LEAN_AND_MEAN +#include +#include +#include "skypepluginlink.h" +#include "include/newpluginapi.h" +#include "include/m_system.h" + +#define LockMutex(x) EnterCriticalSection (&x) +#define UnlockMutex(x) LeaveCriticalSection(&x) +#define InitMutex(x) InitializeCriticalSection(&x) +#define ExitMutex(x) DeleteCriticalSection(&x) +#define mutex_t CRITICAL_SECTION + + +// ----------------------------------------------------------------------------- + +struct tag_proxyInst; +typedef struct tag_proxyInst IMO2SPROXY_INST; + +typedef struct +{ + IMOSAPI *hInst; + IMO2SPROXY_INST *hProxy; + mutex_t sendmutex; + mutex_t rcvmutex; + int iConnectionStat; +} CONNINST; + +struct tag_proxyInst +{ + IMO2SPROXY vtbl; // Must be first! + IMO2SPROXY_CFG *pCfg; + SKYPEPLUGINLINK_CFG *pMyCfg; + HANDLE hService; + CONNINST stClient; // Currently only 1 connection +}; + + +static CONNINST *m_pConn = NULL; + +// ----------------------------------------------------------------------------- + +static void EventHandler(char *pszMsg, void *pUser); +static int InitProxy(IMO2SPROXY_INST *hProxy); + +static int Imo2sproxy_Open(IMO2SPROXY *hInst); +static void Imo2sproxy_Loop(IMO2SPROXY *hInst); +static void Imo2sproxy_Exit(IMO2SPROXY *hInst); + +// ----------------------------------------------------------------------------- +static void EventHandler(char *pszMsg, void *pUser) +{ + CONNINST *pInst = (CONNINST*)pUser; + COPYDATASTRUCT cds; + DWORD dwRes = 0; + + //LockMutex (pInst->sendmutex); + if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) + { + fprintf (pInst->hProxy->pCfg->fpLog, "> %s\n", pszMsg); + fflush (pInst->hProxy->pCfg->fpLog); + } + cds.dwData = 0; + cds.cbData = strlen(pszMsg)+1; + cds.lpData = pszMsg; + CallService (SKYPE_PROTONAME PSS_SKYPEAPIMSG, 0, (LPARAM)&cds); + //UnlockMutex (pInst->sendmutex); +} + +// ----------------------------------------------------------------------------- + +INT_PTR CallIn(WPARAM wParam,LPARAM lParam) +{ + CONNINST *pInst = (CONNINST*)m_pConn; + PCOPYDATASTRUCT pCopyData = (PCOPYDATASTRUCT)lParam; + + if (!pInst) return -1; + + if (pInst->hProxy->pMyCfg->bDelayLogin && pInst->iConnectionStat < 1) + { + LockMutex (pInst->rcvmutex); + if (InitProxy(pInst->hProxy)<0) + { + UnlockMutex(pInst->rcvmutex); + return -1; + } + UnlockMutex(pInst->rcvmutex); + } + + if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) + { + fprintf (pInst->hProxy->pCfg->fpLog, "< [%s]\n", pCopyData->lpData); + fflush (pInst->hProxy->pCfg->fpLog); + } + Imo2S_Send (pInst->hInst, pCopyData->lpData); + return 0; +} + +// ----------------------------------------------------------------------------- + +static void FreeConnection (CONNINST *pInst) +{ + if (!pInst || !pInst->hProxy) return; + if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) + { + fprintf (pInst->hProxy->pCfg->fpLog, "SkypePluginLink: Closed connection\n"); + fflush (pInst->hProxy->pCfg->fpLog); + } + + if (pInst->hProxy->hService) + { + DestroyServiceFunction(pInst->hProxy->hService); + pInst->hProxy->hService = NULL; + CallService (SKYPE_PROTONAME SKYPE_REGPROXY, 0, 0); + } + ExitMutex(pInst->sendmutex); + ExitMutex(pInst->rcvmutex); + if (pInst->hInst) + { + IMOSAPI *hInst = pInst->hInst; + pInst->hInst = NULL; + Imo2S_Exit(hInst); + } +} + +// ----------------------------------------------------------------------------- + +static int InitProxy(IMO2SPROXY_INST *hProxy) +{ + char *pszError; + + if (!hProxy->stClient.hInst) + { + if (!(hProxy->stClient.hInst = Imo2S_Init(EventHandler, &hProxy->stClient, hProxy->pCfg->iFlags))) + { + hProxy->pCfg->logerror (stderr, "SkypePluginLink: Cannot start Imo2Skype instance.\n"); + return -1; + } + } + + // FIXME: We should enable logging dependent on a loglevel rather than just enabling it + Imo2S_SetLog (hProxy->stClient.hInst, hProxy->pCfg->fpLog); + + if (hProxy->stClient.iConnectionStat == 0 || + (hProxy->stClient.iConnectionStat = Imo2S_Login (hProxy->stClient.hInst, + hProxy->pCfg->pszUser, hProxy->pCfg->pszPass, &pszError)) != 1) + { + hProxy->pCfg->logerror (stderr, "SkypePluginLink: Cannot login with (%s/****): %s\n", + hProxy->pCfg->pszUser, pszError); + return -1; + } + return 0; +} + +// ----------------------------------------------------------------------------- +// PUBLIC +// ----------------------------------------------------------------------------- + +void SkypePluginLink_Defaults (SKYPEPLUGINLINK_CFG *pMyCfg) +{ + memset (pMyCfg, 0, sizeof(SKYPEPLUGINLINK_CFG)); + pMyCfg->bDelayLogin = TRUE; +} + +// ----------------------------------------------------------------------------- + +IMO2SPROXY *SkypePluginLink_Init (IMO2SPROXY_CFG *pCfg, SKYPEPLUGINLINK_CFG *pMyCfg) +{ + IMO2SPROXY_INST *pstInst = calloc(sizeof(IMO2SPROXY_INST), 1); + + pstInst->vtbl.Open = Imo2sproxy_Open; + pstInst->vtbl.Loop = Imo2sproxy_Loop; + pstInst->vtbl.Exit = Imo2sproxy_Exit; + pstInst->pCfg = pCfg; + pstInst->pMyCfg = pMyCfg; + return (IMO2SPROXY*)pstInst; +} + +// ----------------------------------------------------------------------------- +// IMPLEMENTATION +// ----------------------------------------------------------------------------- +static int Imo2sproxy_Open(IMO2SPROXY *hInst) +{ + IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst; + WNDCLASS WndClass ={0}; + + if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) + fprintf (hProxy->pCfg->fpLog, "SkypePluginLink:Open(Start)\n"); + + // Only 1 connection instance, so we can init it right here + InitMutex(hProxy->stClient.sendmutex); + InitMutex(hProxy->stClient.rcvmutex); + hProxy->stClient.hProxy = hProxy; + m_pConn = &hProxy->stClient; + + // Register with Skype Plugin + hProxy->hService = CreateServiceFunction("IMO2SPROXY" PSS_SKYPEAPIMSG, CallIn); + CallService (SKYPE_PROTONAME SKYPE_REGPROXY, 0, (LPARAM)"IMO2SPROXY" PSS_SKYPEAPIMSG); + hProxy->stClient.iConnectionStat = -1; + + if (!hProxy->pMyCfg->bDelayLogin) + { + if (InitProxy(hProxy)<0) + { + FreeConnection(&hProxy->stClient); + return -1; + } + } + return 0; +} + +// ----------------------------------------------------------------------------- + +static void Imo2sproxy_Loop(IMO2SPROXY *hInst) +{ + // No loop needed for call-in +} + + +// ----------------------------------------------------------------------------- + +static void Imo2sproxy_Exit(IMO2SPROXY *hInst) +{ + IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst; + + if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) + fprintf (hProxy->pCfg->fpLog, "SkypePluginLink:Exit()\n"); + + FreeConnection (&hProxy->stClient); + free (hProxy); +} + diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.h new file mode 100644 index 0000000000..ecc520ff1e --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.h @@ -0,0 +1,10 @@ +typedef struct { + int bDelayLogin; +} SKYPEPLUGINLINK_CFG; + +#define SKYPE_PROTONAME "SKYPE" +#define PSS_SKYPEAPIMSG "/SendSkypeAPIMsg" +#define SKYPE_REGPROXY "/RegisterProxySvc" + +void SkypePluginLink_Defaults (SKYPEPLUGINLINK_CFG *pMyCfg); +IMO2SPROXY *SkypePluginLink_Init (IMO2SPROXY_CFG *pCfg, SKYPEPLUGINLINK_CFG *pMyCfg); diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.c new file mode 100644 index 0000000000..7f1db504e9 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.c @@ -0,0 +1,158 @@ +/* Module: msgqueue.c + Purpose: Message queue for incoming messages + Author: leecher + Date: 30.08.2009 + + Fixme: Sort on insert, do a binary search instead of iterating list. +*/ + +#include +#include +#include +#include "msgqueue.h" +#include "buddylist.h" + +static volatile unsigned int m_uMsgNr=0; +static void FreeEntry(void *pEntry); + +// ----------------------------------------------------------------------------- +// Interface +// ----------------------------------------------------------------------------- + +TYP_LIST *MsgQueue_Init(void) +{ + TYP_LIST *hList = List_Init(16); + + return hList; +} + +// ----------------------------------------------------------------------------- + +void MsgQueue_Exit(TYP_LIST *hList) +{ + Queue_Exit(hList, FreeEntry); +} + +// ----------------------------------------------------------------------------- + +MSGENTRY *MsgQueue_Insert(TYP_LIST *hList, cJSON *pNick) +{ + MSGENTRY *pEntry; + cJSON *pVal; + + if (!(pEntry = Queue_InsertEntry(hList, sizeof(MSGENTRY), ++m_uMsgNr, + FreeEntry))) return NULL; + pEntry->pszUser = strdup(cJSON_GetObjectItem(pNick, "buid")->valuestring); + pEntry->pszAlias = strdup(cJSON_GetObjectItem(pNick, "alias")->valuestring); + pEntry->pszMessage = strdup(cJSON_GetObjectItem(pNick, "msg")->valuestring); + pEntry->timestamp = cJSON_GetObjectItem(pNick, "timestamp")->valueint; + if (pVal = cJSON_GetObjectItem(pNick, "author")) pEntry->pszAuthor=strdup(pVal->valuestring); + strcpy (pEntry->szStatus, "RECEIVED"); + strcpy (pEntry->szType, "TEXT"); + // imo.im somehow sets group topic via recv_im?? + if (strcmp(pEntry->pszAlias, pEntry->pszMessage) == 0) strcpy (pEntry->szType, "SETTOPIC"); + return pEntry; +} + +// ----------------------------------------------------------------------------- + +MSGENTRY *MsgQueue_AddReflect(TYP_LIST *hList, cJSON *pNick, TYP_LIST *hBuddyList) +{ + MSGENTRY *pEntry; + cJSON *pVal; + + if (!(pEntry = Queue_InsertEntry(hList, sizeof(MSGENTRY), ++m_uMsgNr, + FreeEntry))) return NULL; + pEntry->pszUser = strdup(cJSON_GetObjectItem(pNick, "buid")->valuestring); + + // Usually no alias in Reflection, so query buddy list, if available + if (pVal = cJSON_GetObjectItem(pNick, "alias")) + pEntry->pszAlias = strdup(pVal->valuestring); + else + { + NICKENTRY *pBuddy = hBuddyList?BuddyList_Find (hBuddyList, pEntry->pszUser):NULL; + pEntry->pszAlias = strdup (pBuddy?pBuddy->pszAlias:pEntry->pszUser); + } + + pEntry->pszMessage = strdup(cJSON_GetObjectItem(pNick, "msg")->valuestring); + pEntry->timestamp = cJSON_GetObjectItem(pNick, "timestamp")->valueint; + strcpy (pEntry->szStatus, "SENT"); + return pEntry; +} + +// ----------------------------------------------------------------------------- + +MSGENTRY *MsgQueue_AddSent(TYP_LIST *hList, char *pszUser, char *pszAlias, char *pszMessage, unsigned int *puMsgId) +{ + MSGENTRY *pEntry; + + if (!(pEntry = Queue_InsertEntry(hList, sizeof(MSGENTRY), ++m_uMsgNr, + FreeEntry))) return NULL; + pEntry->pszUser = strdup(pszUser); + pEntry->pszAlias = strdup(pszAlias); + pEntry->pszMessage = strdup(pszMessage); + time (&pEntry->timestamp); + strcpy (pEntry->szStatus, "SENDING"); + if (puMsgId) *puMsgId = pEntry->hdr.uMsgNr; + return pEntry; +} + +// ----------------------------------------------------------------------------- + +MSGENTRY *MsgQueue_AddEvent(TYP_LIST *hList, char *pszUser, char *pszType) +{ + MSGENTRY *pEntry; + + if (!(pEntry = Queue_InsertEntry(hList, sizeof(MSGENTRY), ++m_uMsgNr, + FreeEntry))) return NULL; + pEntry->pszUser = strdup(pszUser); + time (&pEntry->timestamp); + strcpy (pEntry->szStatus, "RECEIVED"); + strcpy (pEntry->szType, pszType); + return pEntry; +} + +// ----------------------------------------------------------------------------- + +BOOL MsgQueue_Remove(TYP_LIST *hList, unsigned int uMsgNr) +{ + return Queue_Remove(hList, uMsgNr, FreeEntry); +} + +// ----------------------------------------------------------------------------- + +MSGENTRY *MsgQueue_Find(TYP_LIST *hList, unsigned int uMsgNr) +{ + return (MSGENTRY*)Queue_Find(hList, uMsgNr); +} + +// ----------------------------------------------------------------------------- + +MSGENTRY *MsgQueue_FindByRqId(TYP_LIST *hList, unsigned int uRqId) +{ + unsigned int i; + MSGENTRY *pEntry; + + for (i=List_Count(hList)-1; (int)i!=-1; i--) + { + pEntry = (MSGENTRY*)List_ElementAt (hList, i); + if (pEntry->uRqId == uRqId) + return pEntry; + } + return NULL; +} + +// ----------------------------------------------------------------------------- +// Static +// ----------------------------------------------------------------------------- + +static void FreeEntry(void *pPEntry) +{ + MSGENTRY *pEntry = (MSGENTRY*)pPEntry; + + if (pEntry->pszAlias) free (pEntry->pszAlias); + free (pEntry->pszUser); + if (pEntry->pszMessage) free (pEntry->pszMessage); + if (pEntry->pszAuthor) free (pEntry->pszAuthor); +} + diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.h new file mode 100644 index 0000000000..ac8ce1cf8d --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.h @@ -0,0 +1,28 @@ +#include "cJSON.h" +#include "queue.h" +#include + +typedef struct +{ + QUEUEHDR hdr; + char *pszUser; + char *pszAuthor; // In case of groupchat, pszUser is the Groupchat ID and pszAuthor is the user sending it, if not a GC message, pszAuthor is NULL + char *pszAlias; + char *pszMessage; + time_t timestamp; + char szStatus[16]; + char szFailure[256]; + char szType[20]; // TEXT, SETTOPIC, ADDEDMEMBERS, CREATEDCHATWITH, LEFT, KICKED, ... + unsigned int uRqId; +} MSGENTRY; + +TYP_LIST *MsgQueue_Init(void); +void MsgQueue_Exit(TYP_LIST *hList); + +MSGENTRY *MsgQueue_Insert(TYP_LIST *hList, cJSON *pNick); +MSGENTRY *MsgQueue_AddReflect(TYP_LIST *hList, cJSON *pNick, TYP_LIST *hBuddyList); +MSGENTRY *MsgQueue_AddSent(TYP_LIST *hList, char *pszUser, char *pszAlias, char *pszMessage, unsigned int *puMsgId); +MSGENTRY *MsgQueue_AddEvent(TYP_LIST *hList, char *pszUser, char *pszType); +BOOL MsgQueue_Remove(TYP_LIST *hList, unsigned int uMsgNr); +MSGENTRY *MsgQueue_Find(TYP_LIST *hList, unsigned int uMsgNr); +MSGENTRY *MsgQueue_FindByRqId(TYP_LIST *hList, unsigned int uRqId); diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/queue.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/queue.c new file mode 100644 index 0000000000..a163314c8e --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/queue.c @@ -0,0 +1,94 @@ +/* Module: queue.c + Purpose: Queue management + Author: leecher + Date: 02.09.2009 +*/ + +#include +#include +#include +#include "memlist.h" +#include "queue.h" + +// Maximum threshold for queues (So that we don't leak memory) +#define THRESHOLD 50 + +// ----------------------------------------------------------------------------- +// Interface +// ----------------------------------------------------------------------------- + +void Queue_Exit(TYP_LIST *hList, void (*fpFree)(void *pEntry)) +{ + void *pEntry; + + while (pEntry=List_Pop(hList)) + { + if (fpFree) fpFree(pEntry); + free (pEntry); + } + List_Exit(hList); +} + +// ----------------------------------------------------------------------------- + +void* Queue_InsertEntry (TYP_LIST *hList, unsigned int cbSize, unsigned int uMsgNr, + void (*fpFree)(void *pEntry)) +{ + void *pEntry; + + if (!(pEntry = calloc (1, cbSize))) return NULL; + if (!List_Push(hList, pEntry)) + { + free (pEntry); + return NULL; + } else ((QUEUEHDR*)pEntry)->uMsgNr = uMsgNr; +#ifdef THRESHOLD + if (List_Count(hList)>THRESHOLD) + { + void *pEntry = List_RemoveElementAt(hList, 0); + + if (pEntry) fpFree (pEntry); + free (pEntry); + } +#endif + return pEntry; +} + +// ----------------------------------------------------------------------------- + +BOOL Queue_Remove(TYP_LIST *hList, unsigned int uMsgNr, void (*fpFree)(void *pEntry)) +{ + QUEUEHDR *pListEntry; + unsigned int i; + + for (i=List_Count(hList)-1; (int)i!=-1; i--) + { + pListEntry = List_ElementAt (hList, i); + if (pListEntry->uMsgNr == uMsgNr) + { + if (fpFree) fpFree (pListEntry); + List_RemoveElementAt(hList, i); + free (pListEntry); + return TRUE; + } + } + return FALSE; +} + +// ----------------------------------------------------------------------------- + +void *Queue_Find(TYP_LIST *hList, unsigned int uMsgNr) +{ + unsigned int i; + QUEUEHDR *pEntry; + + for (i=List_Count(hList)-1; (int)i!=-1; i--) + { + pEntry = (QUEUEHDR*)List_ElementAt (hList, i); + if (pEntry->uMsgNr == uMsgNr) + return pEntry; + } + return NULL; +} + +// ----------------------------------------------------------------------------- diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/queue.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/queue.h new file mode 100644 index 0000000000..4f42a3b42f --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/queue.h @@ -0,0 +1,17 @@ +#ifndef __QUEUE_H__ +#define __QUEUE_H__ + +#include "memlist.h" + +typedef struct +{ + unsigned int uMsgNr; +} QUEUEHDR; + +void Queue_Exit(TYP_LIST *hList, void (*fpFree)(void *pEntry)); +void* Queue_InsertEntry (TYP_LIST *hList, unsigned int cbSize, unsigned int uMsgNr, + void (*fpFree)(void *pEntry)); +BOOL Queue_Remove(TYP_LIST *hList, unsigned int uMsgNr, void (*fpFree)(void *pEntry)); +void *Queue_Find(TYP_LIST *hList, unsigned int uMsgNr); + +#endif diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c new file mode 100644 index 0000000000..20c56a7a66 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c @@ -0,0 +1,565 @@ +/* Module: imo2skypeproxy.c + Purpose: Implementation of imo2skype API as Skype proxy (for Miranda Skype plugin) + Author: leecher + Date: 01.09.2009 + + Changelog: + 1.00 - 01.09.2009 - Initial release + 1.01 - 02.09.2009 - Little bugfix for Onlinestatus, introduced mutex for send thread. + 1.02 - 02.09.2009 - Added support for incoming call notifications and expired sessions. + 1.03 - 03.09.2009 - As WIN32-port of libcurl is a total mess, Win32-version now uses WinINET. + 1.04 - 04.09.2009 - Added support for searching, adding and removing buddies + 1.05 - 06.09.2009 - * Mapped "busy" to DND, not NA, as forum user AL|EN proposed. + * Mood text will now also be sent on status change of a contact + (doesn't really have an effect though) + * New Parameter -d (daemonize) to launch proxy in background + * Fixed a bug with a crash when encoding umlauts on Win32 + 1.06 - 25.09.2009 - Added parameter -t for local timestamps. + 1.07 - 07.10.2009 - Bugfix: Added parsing of multiple JSON messages + Added support for writing to logfile while in daemon mode (-l) + 1.08 - 18.10.2009 - Added support for voice calls via imo.im flash on WIN32 (-i) + - Limited memory queues to 50 entries to reduce memory usage. + 1.09 - 07.11.2009 - Split command line main module and proxy module to make proxy + accessible by different layers (i.e. new Miranda Plugin layer) + 1.10 - 14.12.2009 - Bug in the cJson library. The authors used the String as second + sprintf-Parameter which contains the format string instead of + ["%s", StringParam] causing problems sending Messages containt a % + - Added some space in the dialog for translations and added Translate() + function to some strings in the Wrapper-DLL + - More verbose output if you enable logging + - Fixes a Bug that caused the plugin to block after going offline + and reconnecting back online + - Hopefully fixed a severe threading problem: The Send-Mutex was not + covering a full transaction, but only 1 send causing the receiver + the receive garbled data causing "An existing connection was forcibly + closed by the remote host." error. + - Imo2S_Exit freed the temporary buffer too early resulting in a crash + on exit. + 1.12 - 19.04.2010 - POST interface changed from www.imo.im/amy to s.imo.im/amy + 1.13 - 19.12.2010 - imo.im modified their interface, so tried to adapt the communication + routines at low level to be compatible again. There still may be + many bugs. Don't forget to turn off history logging in the options + at https://imo.im + There also seems to be a nice new feature called "reflection" so that + you can login from multiple sessions and messages etc. entered there + will be reflected to the current session. This may be addressed in one + of the next builds... +*/ + +#include +#include "imo2sproxy.h" +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#define thread_t HANDLE +#define LockMutex(x) EnterCriticalSection (&x) +#define UnlockMutex(x) LeaveCriticalSection(&x) +#define InitMutex(x) InitializeCriticalSection(&x) +#define ExitMutex(x) DeleteCriticalSection(&x) +#define strcasecmp stricmp +#define strncasecmp stricmpn +#define mutex_t CRITICAL_SECTION +#define SHUT_RD SD_RECEIVE +#define SHUT_WR SD_SEND +#define SHUT_RDWR SD_BOTH +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define SOCKET int +#define thread_t pthread_t +#define mutex_t pthread_mutex_t +#define INVALID_SOCKET -1 +#define SOCKET_ERROR INVALID_SOCKET +#define closesocket close +#define LockMutex(x) pthread_mutex_lock(&x) +#define UnlockMutex(x) pthread_mutex_unlock(&x) +#define InitMutex(x) pthread_mutex_init(&x, NULL); +#define ExitMutex(x) +#endif +#include +#include +#include +#include "memlist.h" +#include "socksproxy.h" + +// ----------------------------------------------------------------------------- + +#define AUTHENTICATE 0x01 +#define CAPABILITIES 0x02 +#define USE_AUTHENTICATION 0x01 + +typedef struct +{ + IMO2SPROXY vtbl; // Must be first! + IMO2SPROXY_CFG *pCfg; + SOCKSPROXY_CFG *pMyCfg; + + SOCKET listen_fd; + volatile int iRunning; + mutex_t loopmutex; +} IMO2SPROXY_INST; + +typedef struct +{ + SOCKET hSock; + thread_t hThread; + IMOSAPI *hInst; + int iConnectionStat; + mutex_t connected; + mutex_t sendmutex; + IMO2SPROXY_INST *hProxy; +} CONNINST; + + +// ----------------------------------------------------------------------------- + +static void EventHandler(char *pszMsg, void *pUser); +static void DispatcherThread(void *pUser); +static int Dispatcher_Start(CONNINST *pInst); +static int Dispatcher_Stop(CONNINST *pInst); +static char *GetError(void); +static int RcvPacket (CONNINST *pInst, void *buf, int len); +static int SendPacket (CONNINST *pInst, void *buf, int len); +static void FreeConnection (CONNINST *pInst); +static void CleanConnections (TYP_LIST *hList); +static SOCKET Init(unsigned long int lHost, short sPort, int iMaxConn); +static void Loop(SOCKET listen_fd); +static void Exit(SOCKET listen_fd); + +static int Imo2sproxy_Open(IMO2SPROXY *hInst); +static void Imo2sproxy_Loop(IMO2SPROXY *hInst); +static void Imo2sproxy_Exit(IMO2SPROXY *hInst); + +// ----------------------------------------------------------------------------- +static void EventHandler(char *pszMsg, void *pUser) +{ + CONNINST *pInst = (CONNINST*)pUser; + unsigned int uiLen = strlen (pszMsg); + static BOOL bFirstLogin = TRUE; + + if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) + { + fprintf (pInst->hProxy->pCfg->fpLog, "%03d> %s\n", pInst->hSock, pszMsg); + fflush (pInst->hProxy->pCfg->fpLog); + } + if (bFirstLogin && strncmp (pszMsg, "CONNSTATUS", 10) == 0 && + strcmp(pszMsg+11, "CONNECTING")) + { + pInst->iConnectionStat = (strcmp(pszMsg+11, "ONLINE")==0); + UnlockMutex (pInst->connected); + bFirstLogin = FALSE; + } + LockMutex(pInst->sendmutex); + if (!(SendPacket (pInst, &uiLen, sizeof(uiLen)) && SendPacket (pInst, pszMsg, uiLen))) + { + //Dispatcher_Stop(pInst); + //FreeConnection (pInst); + } + UnlockMutex(pInst->sendmutex); +} + +// ----------------------------------------------------------------------------- + +static void DispatcherThread(void *pUser) +{ + CONNINST *pInst = (CONNINST*)pUser; + char *pszUser, *pszPass, *pszError, *pszMsgBuf=NULL; + unsigned int uiLength, cbMsgBuf=0, bAuthenticated = 0, iConnected=0, iLogin=1; + char command=0, reply=0; + + if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) + fprintf (pInst->hProxy->pCfg->fpLog, "Imo2sproxy::DispatcherThread()\n"); + + if (!(pInst->hInst = Imo2S_Init(EventHandler, pInst, pInst->hProxy->pCfg->iFlags))) + { + pInst->hProxy->pCfg->logerror (stderr, "Connection %d: Cannot start Imo2Skype instance.\n", pInst->hSock); + FreeConnection (pInst); + return; + } + + // FIXME: Static user+pass from cmdline, until there is a possibility for + // a client to authenticate + pszUser = pInst->hProxy->pCfg->pszUser; + pszPass = pInst->hProxy->pCfg->pszPass; + + // FIXME: We should enable logging dependent on a loglevel rather than just enabling it + if (pInst->hProxy->pCfg->bVerbose) + Imo2S_SetLog (pInst->hInst, pInst->hProxy->pCfg->fpLog); + + + while (pInst->hProxy->iRunning) + { + if (RcvPacket(pInst, &uiLength, sizeof(uiLength))<=0) break; + LockMutex(pInst->sendmutex); + + if (uiLength == 0) + { + if (RcvPacket(pInst, &command, 1)<=0) + { + UnlockMutex(pInst->sendmutex); + break; + } + switch (command) + { + case AUTHENTICATE: + if (pInst->hProxy->pMyCfg->pszAuthPass) reply=1; + break; + case CAPABILITIES: + if (pInst->hProxy->pMyCfg->pszAuthPass) reply=USE_AUTHENTICATION; + break; + } + if (SendPacket (pInst, &reply, 1)<=0) + { + UnlockMutex(pInst->sendmutex); + break; + } + UnlockMutex(pInst->sendmutex); + continue; + } + + if (uiLength >= cbMsgBuf) + { + pszMsgBuf = realloc (pszMsgBuf, uiLength+1); + if (!pszMsgBuf) + { + UnlockMutex(pInst->sendmutex); + break; + } + cbMsgBuf=uiLength+1; + } + + if (RcvPacket(pInst, pszMsgBuf, uiLength)<=0) + { + UnlockMutex(pInst->sendmutex); + break; + } + + if (command) + { + if (command == AUTHENTICATE) + { + bAuthenticated = pInst->hProxy->pMyCfg->pszAuthPass && strcmp(pInst->hProxy->pMyCfg->pszAuthPass, pszMsgBuf) == 0; + if (SendPacket (pInst, &bAuthenticated, 1)<=0) + { + UnlockMutex(pInst->sendmutex); + break; + } + } + command = 0; + } + UnlockMutex(pInst->sendmutex); + + if (iLogin) + { + if (Imo2S_Login (pInst->hInst, pszUser, pszPass, &pszError) != 1) + { + pInst->hProxy->pCfg->logerror (stderr, "Connection %d: Cannot login with (%s/****): %s\n", + pInst->hSock, pszUser, pszError); + FreeConnection (pInst); + return; + } + iLogin = 0; + } + + if (pInst->hProxy->pMyCfg->pszAuthPass && !bAuthenticated)continue; + pszMsgBuf[uiLength]=0; + if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) + { + fprintf (pInst->hProxy->pCfg->fpLog, "%03d< [%s]\n", pInst->hSock, pszMsgBuf); + fflush (pInst->hProxy->pCfg->fpLog); + } + if (!iConnected) + { + LockMutex (pInst->connected); + iConnected = pInst->iConnectionStat; + if (!iConnected) + { + pInst->hProxy->pCfg->logerror(stderr, "Invalid username / password"); + } + } + Imo2S_Send (pInst->hInst, pszMsgBuf); + } + + FreeConnection (pInst); + if (pszMsgBuf) free (pszMsgBuf); + return; +} + +// ----------------------------------------------------------------------------- + +#ifdef WIN32 +static int Dispatcher_Start(CONNINST *pInst) +{ + DWORD ThreadID; + + return (pInst->hThread=(thread_t)_beginthreadex(NULL, 0, + (unsigned(__stdcall *)(void*))DispatcherThread, pInst, 0, &ThreadID))!=0; + +} + +static int Dispatcher_Stop(CONNINST *pInst) +{ + return pInst->hThread?TerminateThread (pInst->hThread, 0):1; +} + +static char *GetError(void) +{ + static char szMessage[1024]; + DWORD dwErr = WSAGetLastError(); + + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, 0, szMessage, sizeof(szMessage), NULL); + return szMessage; +} + +#else +static int Dispatcher_Start(CONNINST *pInst) +{ + return pthread_create(&pInst->hThread, NULL, DispatcherThread, pInst)==0; +} + +static int Dispatcher_Stop(CONNINST *pInst) +{ + if (!pInst->hThread || pthread_cancel(pInst->hThread)) + { + pInst->hThread=0; + return 1; + } + return 0; +} + +static char *GetError(void) +{ + return strerror (errno); +} + +#endif + +// ----------------------------------------------------------------------------- + +static int RcvPacket (CONNINST *pInst, void *buf, int len) +{ + int iReceived = recv (pInst->hSock, buf, len, 0); + if (iReceived <= 0) + pInst->hProxy->pCfg->logerror(stderr, "Connection %d (Receive): %s", pInst->hSock, GetError()); + return iReceived; +} + +// ----------------------------------------------------------------------------- + +static int SendPacket (CONNINST *pInst, void *buf, int len) +{ + int iSent; + + iSent = send (pInst->hSock, buf, len, 0); + if (iSent <= 0) + pInst->hProxy->pCfg->logerror (stderr, "Connection %d (Send): %s", pInst->hSock, GetError()); + return iSent; +} +// ----------------------------------------------------------------------------- + +static void FreeConnection (CONNINST *pInst) +{ + if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) + { + fprintf (pInst->hProxy->pCfg->fpLog, "Closed connection %d\n", pInst->hSock); + fflush (pInst->hProxy->pCfg->fpLog); + } + if (pInst->hSock != INVALID_SOCKET) + closesocket(pInst->hSock); + pInst->hSock = INVALID_SOCKET; + pInst->hThread = 0; + ExitMutex (pInst->connected); + ExitMutex (pInst->sendmutex); + if (pInst->hInst) + { + IMOSAPI *hInst = pInst->hInst; + pInst->hInst = NULL; + Imo2S_Exit(hInst); + } +} + +// ----------------------------------------------------------------------------- + +static void CleanConnections (TYP_LIST *hList) +{ + unsigned int i; + CONNINST *hInst; + + for (i=0; ihThread == 0) + { + free (List_RemoveElementAt(hList, i)); + i--; + } + } +} + +// ----------------------------------------------------------------------------- +// PUBLIC +// ----------------------------------------------------------------------------- + +void SocksProxy_Defaults (SOCKSPROXY_CFG *pMyCfg) +{ + memset (pMyCfg, 0, sizeof(SOCKSPROXY_CFG)); + pMyCfg->lAddr = htonl(INADDR_ANY); + pMyCfg->sPort = 1401; + pMyCfg->iMaxConn = SOMAXCONN; +} + +// ----------------------------------------------------------------------------- + +IMO2SPROXY *SocksProxy_Init (IMO2SPROXY_CFG *pCfg, SOCKSPROXY_CFG *pMyCfg) +{ + IMO2SPROXY_INST *pstInst = calloc(sizeof(IMO2SPROXY_INST), 1); + + pstInst->vtbl.Open = Imo2sproxy_Open; + pstInst->vtbl.Loop = Imo2sproxy_Loop; + pstInst->vtbl.Exit = Imo2sproxy_Exit; + pstInst->pCfg = pCfg; + pstInst->pMyCfg = pMyCfg; + InitMutex(pstInst->loopmutex); + return (IMO2SPROXY*)pstInst; +} + +// ----------------------------------------------------------------------------- +// IMPLEMENTATION +// ----------------------------------------------------------------------------- +static int Imo2sproxy_Open(IMO2SPROXY *hInst) +{ + struct sockaddr_in sock={0}; + int yes = 1; + IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst; + +#ifdef WIN32 + WSADATA wsaData; + + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) + { + hProxy->pCfg->logerror (stderr, "WSAStartup failed"); + return INVALID_SOCKET; + } +#endif + if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) + fprintf (hProxy->pCfg->fpLog, "Socksproxy:Loop(Start)\n"); + hProxy->listen_fd = socket(PF_INET, SOCK_STREAM, 0); + if(hProxy->listen_fd == INVALID_SOCKET) return -1; + if (setsockopt(hProxy->listen_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(int))<0) + { + hProxy->pCfg->logerror (stderr, "Cannot set socket options to SO_REUSEADDR"); + closesocket(hProxy->listen_fd); + return -1; + } + sock.sin_family = AF_INET; + sock.sin_addr.s_addr = hProxy->pMyCfg->lAddr; + sock.sin_port = htons(hProxy->pMyCfg->sPort); + + if (bind(hProxy->listen_fd, (struct sockaddr *) &sock, sizeof(sock)) != 0) + { + hProxy->pCfg->logerror (stderr, "Cannot bind socket"); + closesocket(hProxy->listen_fd); + return -1; + } + + if (listen(hProxy->listen_fd, hProxy->pMyCfg->iMaxConn) < 0) + { + hProxy->pCfg->logerror (stderr, "Cannot listen on socket"); + closesocket(hProxy->listen_fd); + return -1; + } + + return 0; +} + +// ----------------------------------------------------------------------------- + +static void Imo2sproxy_Loop(IMO2SPROXY *hInst) +{ + struct sockaddr_in sock; + int socklen; + SOCKET new_fd; + TYP_LIST *hConns = List_Init(32); + CONNINST *pInst; + IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst; + fd_set fdListen; + + if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) + fprintf (hProxy->pCfg->fpLog, "Socksproxy:Loop(Start)\n"); + hProxy->iRunning = 1; + LockMutex(hProxy->loopmutex); + while (hProxy->iRunning) + { + FD_ZERO(&fdListen); + FD_SET(hProxy->listen_fd, &fdListen); + socklen = sizeof(sock); + if (select (0, &fdListen, NULL, NULL, NULL) != SOCKET_ERROR && FD_ISSET(hProxy->listen_fd, &fdListen)) + { + new_fd = accept(hProxy->listen_fd, (struct sockaddr *) &sock, &socklen); + if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) + { + fprintf (hProxy->pCfg->fpLog, "Connection from %s:%d -> Connection: %d\n", inet_ntoa(sock.sin_addr), + ntohs(sock.sin_port), new_fd); + fflush (hProxy->pCfg->fpLog); + } + if (new_fd != INVALID_SOCKET && (pInst = calloc (1, sizeof(CONNINST)))) + { + CleanConnections (hConns); + List_Push(hConns, pInst); + pInst->hSock = new_fd; + pInst->hProxy = hProxy; + InitMutex(pInst->connected); + LockMutex(pInst->connected); + InitMutex(pInst->sendmutex); + Dispatcher_Start(pInst); + } + } + } + if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) + fprintf (hProxy->pCfg->fpLog, "Socksproxy:Loop(End)\n"); + + CleanConnections (hConns); + while (pInst=List_Pop(hConns)) + { + Dispatcher_Stop(pInst); + FreeConnection(pInst); + free (pInst); + } + List_Exit(hConns); + UnlockMutex(hProxy->loopmutex); +} + + +// ----------------------------------------------------------------------------- + +static void Imo2sproxy_Exit(IMO2SPROXY *hInst) +{ + IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst; + + if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) + fprintf (hProxy->pCfg->fpLog, "Socksproxy:Exit()\n"); + + hProxy->iRunning = 0; + shutdown (hProxy->listen_fd, SHUT_RDWR); + closesocket (hProxy->listen_fd); + LockMutex(hProxy->loopmutex); + +/* +#ifdef WIN32 + WSACleanup(); +#endif +*/ + UnlockMutex(hProxy->loopmutex); + ExitMutex(hProxy->loopmutex); + free (hProxy); +} + diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.h new file mode 100644 index 0000000000..6010e749f1 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.h @@ -0,0 +1,11 @@ +typedef struct +{ + char *pszAuthPass; + unsigned long int lAddr; + short sPort; + int iMaxConn; +} SOCKSPROXY_CFG; + + +void SocksProxy_Defaults (SOCKSPROXY_CFG *pMyCfg); +IMO2SPROXY *SocksProxy_Init (IMO2SPROXY_CFG *pCfg, SOCKSPROXY_CFG *pMyCfg); diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.c new file mode 100644 index 0000000000..8053a3c16d --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.c @@ -0,0 +1,1143 @@ +/* Module: win32_browsewnd.c + Purpose: Displays a window with an embedded browser in order to display the Voicechat + flash from imo.im + This example is bsaed on the work of Jeff Glatt (http://www.codeproject.com/KB/COM/cwebpage.aspx?msg=2852721) + Author: leecher, credits go to Jeff Glatt for his excellent work. + Date: 18.10.2009 +*/ + +#include +#include +#include +#include +#include +#include "memlist.h" +#include "w32browser.h" + +#ifndef _WIN64 +#if WINVER<0x0500 +#define SetWindowLongPtr SetWindowLong +#define GetWindowLongPtr GetWindowLong +#endif +#ifndef LONG_PTR +#define LONG_PTR LONG +#endif +#ifndef GWLP_USERDATA +#define GWLP_USERDATA GWL_USERDATA +#endif +#endif + +static const SAFEARRAYBOUND ArrayBound = {1, 0}; +static TYP_LIST *m_hWindows = NULL; +static DWORD m_dwThread = 0; +static HANDLE m_hThread = NULL, m_hEvent = NULL; + + +HRESULT STDMETHODCALLTYPE Frame_QueryInterface(IOleInPlaceFrame FAR* This, REFIID riid, LPVOID FAR* ppvObj); +HRESULT STDMETHODCALLTYPE Frame_AddRef(IOleInPlaceFrame FAR* This); +HRESULT STDMETHODCALLTYPE Frame_Release(IOleInPlaceFrame FAR* This); +HRESULT STDMETHODCALLTYPE Frame_GetWindow(IOleInPlaceFrame FAR* This, HWND FAR* lphwnd); +HRESULT STDMETHODCALLTYPE Frame_ContextSensitiveHelp(IOleInPlaceFrame FAR* This, BOOL fEnterMode); +HRESULT STDMETHODCALLTYPE Frame_GetBorder(IOleInPlaceFrame FAR* This, LPRECT lprectBorder); +HRESULT STDMETHODCALLTYPE Frame_RequestBorderSpace(IOleInPlaceFrame FAR* This, LPCBORDERWIDTHS pborderwidths); +HRESULT STDMETHODCALLTYPE Frame_SetBorderSpace(IOleInPlaceFrame FAR* This, LPCBORDERWIDTHS pborderwidths); +HRESULT STDMETHODCALLTYPE Frame_SetActiveObject(IOleInPlaceFrame FAR* This, IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName); +HRESULT STDMETHODCALLTYPE Frame_InsertMenus(IOleInPlaceFrame FAR* This, HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths); +HRESULT STDMETHODCALLTYPE Frame_SetMenu(IOleInPlaceFrame FAR* This, HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject); +HRESULT STDMETHODCALLTYPE Frame_RemoveMenus(IOleInPlaceFrame FAR* This, HMENU hmenuShared); +HRESULT STDMETHODCALLTYPE Frame_SetStatusText(IOleInPlaceFrame FAR* This, LPCOLESTR pszStatusText); +HRESULT STDMETHODCALLTYPE Frame_EnableModeless(IOleInPlaceFrame FAR* This, BOOL fEnable); +HRESULT STDMETHODCALLTYPE Frame_TranslateAccelerator(IOleInPlaceFrame FAR* This, LPMSG lpmsg, WORD wID); + +IOleInPlaceFrameVtbl MyIOleInPlaceFrameTable = {Frame_QueryInterface, +Frame_AddRef, +Frame_Release, +Frame_GetWindow, +Frame_ContextSensitiveHelp, +Frame_GetBorder, +Frame_RequestBorderSpace, +Frame_SetBorderSpace, +Frame_SetActiveObject, +Frame_InsertMenus, +Frame_SetMenu, +Frame_RemoveMenus, +Frame_SetStatusText, +Frame_EnableModeless, +Frame_TranslateAccelerator}; + +typedef struct { + IOleInPlaceFrame frame; + HWND window; +} _IOleInPlaceFrameEx; + +HRESULT STDMETHODCALLTYPE Site_QueryInterface(IOleClientSite FAR* This, REFIID riid, void ** ppvObject); +HRESULT STDMETHODCALLTYPE Site_AddRef(IOleClientSite FAR* This); +HRESULT STDMETHODCALLTYPE Site_Release(IOleClientSite FAR* This); +HRESULT STDMETHODCALLTYPE Site_SaveObject(IOleClientSite FAR* This); +HRESULT STDMETHODCALLTYPE Site_GetMoniker(IOleClientSite FAR* This, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk); +HRESULT STDMETHODCALLTYPE Site_GetContainer(IOleClientSite FAR* This, LPOLECONTAINER FAR* ppContainer); +HRESULT STDMETHODCALLTYPE Site_ShowObject(IOleClientSite FAR* This); +HRESULT STDMETHODCALLTYPE Site_OnShowWindow(IOleClientSite FAR* This, BOOL fShow); +HRESULT STDMETHODCALLTYPE Site_RequestNewObjectLayout(IOleClientSite FAR* This); + +IOleClientSiteVtbl MyIOleClientSiteTable = {Site_QueryInterface, +Site_AddRef, +Site_Release, +Site_SaveObject, +Site_GetMoniker, +Site_GetContainer, +Site_ShowObject, +Site_OnShowWindow, +Site_RequestNewObjectLayout}; + +HRESULT STDMETHODCALLTYPE UI_QueryInterface(IDocHostUIHandler FAR* This, REFIID riid, void ** ppvObject); +HRESULT STDMETHODCALLTYPE UI_AddRef(IDocHostUIHandler FAR* This); +HRESULT STDMETHODCALLTYPE UI_Release(IDocHostUIHandler FAR* This); +HRESULT STDMETHODCALLTYPE UI_ShowContextMenu(IDocHostUIHandler FAR* This, DWORD dwID, POINT __RPC_FAR *ppt, IUnknown __RPC_FAR *pcmdtReserved, IDispatch __RPC_FAR *pdispReserved); +HRESULT STDMETHODCALLTYPE UI_GetHostInfo(IDocHostUIHandler FAR* This, DOCHOSTUIINFO __RPC_FAR *pInfo); +HRESULT STDMETHODCALLTYPE UI_ShowUI(IDocHostUIHandler FAR* This, DWORD dwID, IOleInPlaceActiveObject __RPC_FAR *pActiveObject, IOleCommandTarget __RPC_FAR *pCommandTarget, IOleInPlaceFrame __RPC_FAR *pFrame, IOleInPlaceUIWindow __RPC_FAR *pDoc); +HRESULT STDMETHODCALLTYPE UI_HideUI(IDocHostUIHandler FAR* This); +HRESULT STDMETHODCALLTYPE UI_UpdateUI(IDocHostUIHandler FAR* This); +HRESULT STDMETHODCALLTYPE UI_EnableModeless(IDocHostUIHandler FAR* This, BOOL fEnable); +HRESULT STDMETHODCALLTYPE UI_OnDocWindowActivate(IDocHostUIHandler FAR* This, BOOL fActivate); +HRESULT STDMETHODCALLTYPE UI_OnFrameWindowActivate(IDocHostUIHandler FAR* This, BOOL fActivate); +HRESULT STDMETHODCALLTYPE UI_ResizeBorder(IDocHostUIHandler FAR* This, LPCRECT prcBorder, IOleInPlaceUIWindow __RPC_FAR *pUIWindow, BOOL fRameWindow); +HRESULT STDMETHODCALLTYPE UI_TranslateAccelerator(IDocHostUIHandler FAR* This, LPMSG lpMsg, const GUID __RPC_FAR *pguidCmdGroup, DWORD nCmdID); +HRESULT STDMETHODCALLTYPE UI_GetOptionKeyPath(IDocHostUIHandler FAR* This, LPOLESTR __RPC_FAR *pchKey, DWORD dw); +HRESULT STDMETHODCALLTYPE UI_GetDropTarget(IDocHostUIHandler FAR* This, IDropTarget __RPC_FAR *pDropTarget, IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget); +HRESULT STDMETHODCALLTYPE UI_GetExternal(IDocHostUIHandler FAR* This, IDispatch __RPC_FAR *__RPC_FAR *ppDispatch); +HRESULT STDMETHODCALLTYPE UI_TranslateUrl(IDocHostUIHandler FAR* This, DWORD dwTranslate, OLECHAR __RPC_FAR *pchURLIn, OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut); +HRESULT STDMETHODCALLTYPE UI_FilterDataObject(IDocHostUIHandler FAR* This, IDataObject __RPC_FAR *pDO, IDataObject __RPC_FAR *__RPC_FAR *ppDORet); + +IDocHostUIHandlerVtbl MyIDocHostUIHandlerTable = {UI_QueryInterface, +UI_AddRef, +UI_Release, +UI_ShowContextMenu, +UI_GetHostInfo, +UI_ShowUI, +UI_HideUI, +UI_UpdateUI, +UI_EnableModeless, +UI_OnDocWindowActivate, +UI_OnFrameWindowActivate, +UI_ResizeBorder, +UI_TranslateAccelerator, +UI_GetOptionKeyPath, +UI_GetDropTarget, +UI_GetExternal, +UI_TranslateUrl, +UI_FilterDataObject}; + +HRESULT STDMETHODCALLTYPE InPlace_QueryInterface(IOleInPlaceSite FAR* This, REFIID riid, void ** ppvObject); +HRESULT STDMETHODCALLTYPE InPlace_AddRef(IOleInPlaceSite FAR* This); +HRESULT STDMETHODCALLTYPE InPlace_Release(IOleInPlaceSite FAR* This); +HRESULT STDMETHODCALLTYPE InPlace_GetWindow(IOleInPlaceSite FAR* This, HWND FAR* lphwnd); +HRESULT STDMETHODCALLTYPE InPlace_ContextSensitiveHelp(IOleInPlaceSite FAR* This, BOOL fEnterMode); +HRESULT STDMETHODCALLTYPE InPlace_CanInPlaceActivate(IOleInPlaceSite FAR* This); +HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceActivate(IOleInPlaceSite FAR* This); +HRESULT STDMETHODCALLTYPE InPlace_OnUIActivate(IOleInPlaceSite FAR* This); +HRESULT STDMETHODCALLTYPE InPlace_GetWindowContext(IOleInPlaceSite FAR* This, LPOLEINPLACEFRAME FAR* lplpFrame,LPOLEINPLACEUIWINDOW FAR* lplpDoc,LPRECT lprcPosRect,LPRECT lprcClipRect,LPOLEINPLACEFRAMEINFO lpFrameInfo); +HRESULT STDMETHODCALLTYPE InPlace_Scroll(IOleInPlaceSite FAR* This, SIZE scrollExtent); +HRESULT STDMETHODCALLTYPE InPlace_OnUIDeactivate(IOleInPlaceSite FAR* This, BOOL fUndoable); +HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceDeactivate(IOleInPlaceSite FAR* This); +HRESULT STDMETHODCALLTYPE InPlace_DiscardUndoState(IOleInPlaceSite FAR* This); +HRESULT STDMETHODCALLTYPE InPlace_DeactivateAndUndo(IOleInPlaceSite FAR* This); +HRESULT STDMETHODCALLTYPE InPlace_OnPosRectChange(IOleInPlaceSite FAR* This, LPCRECT lprcPosRect); + +IOleInPlaceSiteVtbl MyIOleInPlaceSiteTable = {InPlace_QueryInterface, +InPlace_AddRef, +InPlace_Release, +InPlace_GetWindow, +InPlace_ContextSensitiveHelp, +InPlace_CanInPlaceActivate, +InPlace_OnInPlaceActivate, +InPlace_OnUIActivate, +InPlace_GetWindowContext, +InPlace_Scroll, +InPlace_OnUIDeactivate, +InPlace_OnInPlaceDeactivate, +InPlace_DiscardUndoState, +InPlace_DeactivateAndUndo, +InPlace_OnPosRectChange}; + +typedef struct { + IOleInPlaceSite inplace; + _IOleInPlaceFrameEx frame; +} _IOleInPlaceSiteEx; + +typedef struct { + IDocHostUIHandler ui; +} _IDocHostUIHandlerEx; + +typedef struct { + IOleClientSite client; + _IOleInPlaceSiteEx inplace; + _IDocHostUIHandlerEx ui; +} _IOleClientSiteEx; + +#define NOTIMPLEMENTED return(E_NOTIMPL) + +typedef struct +{ + char *pszHTML; + char *pszTitle; + int width; + int height; + HWND hWnd; // out +} ShowIEWndParam; + + +//////////////////////////////////// My IDocHostUIHandler functions ////////////////////////////////////// +// +HRESULT STDMETHODCALLTYPE UI_QueryInterface(IDocHostUIHandler FAR* This, REFIID riid, LPVOID FAR* ppvObj) +{ + return(Site_QueryInterface((IOleClientSite *)((char *)This - sizeof(IOleClientSite) - sizeof(_IOleInPlaceSiteEx)), riid, ppvObj)); +} + +HRESULT STDMETHODCALLTYPE UI_AddRef(IDocHostUIHandler FAR* This) +{ + return(1); +} + +HRESULT STDMETHODCALLTYPE UI_Release(IDocHostUIHandler FAR* This) +{ + return(1); +} + +HRESULT STDMETHODCALLTYPE UI_ShowContextMenu(IDocHostUIHandler FAR* This, DWORD dwID, POINT __RPC_FAR *ppt, IUnknown __RPC_FAR *pcmdtReserved, IDispatch __RPC_FAR *pdispReserved) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE UI_GetHostInfo(IDocHostUIHandler FAR* This, DOCHOSTUIINFO __RPC_FAR *pInfo) +{ + pInfo->cbSize = sizeof(DOCHOSTUIINFO); + pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER; + pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT; + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE UI_ShowUI(IDocHostUIHandler FAR* This, DWORD dwID, IOleInPlaceActiveObject __RPC_FAR *pActiveObject, IOleCommandTarget __RPC_FAR *pCommandTarget, IOleInPlaceFrame __RPC_FAR *pFrame, IOleInPlaceUIWindow __RPC_FAR *pDoc) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE UI_HideUI(IDocHostUIHandler FAR* This) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE UI_UpdateUI(IDocHostUIHandler FAR* This) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE UI_EnableModeless(IDocHostUIHandler FAR* This, BOOL fEnable) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE UI_OnDocWindowActivate(IDocHostUIHandler FAR* This, BOOL fActivate) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE UI_OnFrameWindowActivate(IDocHostUIHandler FAR* This, BOOL fActivate) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE UI_ResizeBorder(IDocHostUIHandler FAR* This, LPCRECT prcBorder, IOleInPlaceUIWindow __RPC_FAR *pUIWindow, BOOL fRameWindow) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE UI_TranslateAccelerator(IDocHostUIHandler FAR* This, LPMSG lpMsg, const GUID __RPC_FAR *pguidCmdGroup, DWORD nCmdID) +{ + return(S_FALSE); +} + +HRESULT STDMETHODCALLTYPE UI_GetOptionKeyPath(IDocHostUIHandler FAR* This, LPOLESTR __RPC_FAR *pchKey, DWORD dw) +{ + return(S_FALSE); +} + +HRESULT STDMETHODCALLTYPE UI_GetDropTarget(IDocHostUIHandler FAR* This, IDropTarget __RPC_FAR *pDropTarget, IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget) +{ + return(S_FALSE); +} + +HRESULT STDMETHODCALLTYPE UI_GetExternal(IDocHostUIHandler FAR* This, IDispatch __RPC_FAR *__RPC_FAR *ppDispatch) +{ + *ppDispatch = 0; + return(S_FALSE); +} + +HRESULT STDMETHODCALLTYPE UI_TranslateUrl(IDocHostUIHandler FAR* This, DWORD dwTranslate, OLECHAR __RPC_FAR *pchURLIn, OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut) +{ + *ppchURLOut = 0; + return(S_FALSE); +} + +HRESULT STDMETHODCALLTYPE UI_FilterDataObject(IDocHostUIHandler FAR* This, IDataObject __RPC_FAR *pDO, IDataObject __RPC_FAR *__RPC_FAR *ppDORet) +{ + *ppDORet = 0; + return(S_FALSE); +} + +////////////////////////////////////// My IOleClientSite functions ///////////////////////////////////// +// + +HRESULT STDMETHODCALLTYPE Site_QueryInterface(IOleClientSite FAR* This, REFIID riid, void ** ppvObject) +{ + if (!memcmp(riid, &IID_IUnknown, sizeof(GUID)) || !memcmp(riid, &IID_IOleClientSite, sizeof(GUID))) + *ppvObject = &((_IOleClientSiteEx *)This)->client; + else if (!memcmp(riid, &IID_IOleInPlaceSite, sizeof(GUID))) + *ppvObject = &((_IOleClientSiteEx *)This)->inplace; + else if (!memcmp(riid, &IID_IDocHostUIHandler, sizeof(GUID))) + *ppvObject = &((_IOleClientSiteEx *)This)->ui; + else + { + *ppvObject = 0; + return(E_NOINTERFACE); + } + + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE Site_AddRef(IOleClientSite FAR* This) +{ + return(1); +} + +HRESULT STDMETHODCALLTYPE Site_Release(IOleClientSite FAR* This) +{ + return(1); +} + +HRESULT STDMETHODCALLTYPE Site_SaveObject(IOleClientSite FAR* This) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Site_GetMoniker(IOleClientSite FAR* This, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Site_GetContainer(IOleClientSite FAR* This, LPOLECONTAINER FAR* ppContainer) +{ + *ppContainer = 0; + + return(E_NOINTERFACE); +} + +HRESULT STDMETHODCALLTYPE Site_ShowObject(IOleClientSite FAR* This) +{ + return(NOERROR); +} + +HRESULT STDMETHODCALLTYPE Site_OnShowWindow(IOleClientSite FAR* This, BOOL fShow) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Site_RequestNewObjectLayout(IOleClientSite FAR* This) +{ + NOTIMPLEMENTED; +} + + +////////////////////////////////////// My IOleInPlaceSite functions ///////////////////////////////////// +// +HRESULT STDMETHODCALLTYPE InPlace_QueryInterface(IOleInPlaceSite FAR* This, REFIID riid, LPVOID FAR* ppvObj) +{ + return(Site_QueryInterface((IOleClientSite *)((char *)This - sizeof(IOleClientSite)), riid, ppvObj)); +} + +HRESULT STDMETHODCALLTYPE InPlace_AddRef(IOleInPlaceSite FAR* This) +{ + return(1); +} + +HRESULT STDMETHODCALLTYPE InPlace_Release(IOleInPlaceSite FAR* This) +{ + return(1); +} + +HRESULT STDMETHODCALLTYPE InPlace_GetWindow(IOleInPlaceSite FAR* This, HWND FAR* lphwnd) +{ + *lphwnd = ((_IOleInPlaceSiteEx FAR*)This)->frame.window; + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE InPlace_ContextSensitiveHelp(IOleInPlaceSite FAR* This, BOOL fEnterMode) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE InPlace_CanInPlaceActivate(IOleInPlaceSite FAR* This) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceActivate(IOleInPlaceSite FAR* This) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE InPlace_OnUIActivate(IOleInPlaceSite FAR* This) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE InPlace_GetWindowContext(IOleInPlaceSite FAR* This, LPOLEINPLACEFRAME FAR* lplpFrame, LPOLEINPLACEUIWINDOW FAR* lplpDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo) +{ + *lplpFrame = (LPOLEINPLACEFRAME)&((_IOleInPlaceSiteEx *)This)->frame; + *lplpDoc = 0; + + lpFrameInfo->fMDIApp = FALSE; + lpFrameInfo->hwndFrame = ((_IOleInPlaceFrameEx *)*lplpFrame)->window; + lpFrameInfo->haccel = 0; + lpFrameInfo->cAccelEntries = 0; + + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE InPlace_Scroll(IOleInPlaceSite FAR* This, SIZE scrollExtent) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE InPlace_OnUIDeactivate(IOleInPlaceSite FAR* This, BOOL fUndoable) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceDeactivate(IOleInPlaceSite FAR* This) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE InPlace_DiscardUndoState(IOleInPlaceSite FAR* This) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE InPlace_DeactivateAndUndo(IOleInPlaceSite FAR* This) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE InPlace_OnPosRectChange(IOleInPlaceSite FAR* This, LPCRECT lprcPosRect) +{ + IOleObject *browserObject; + IOleInPlaceObject *inplace; + + browserObject = *((IOleObject **)((char *)This - sizeof(IOleObject *) - sizeof(IOleClientSite))); + if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IOleInPlaceObject, (void**)&inplace)) + { + inplace->lpVtbl->SetObjectRects(inplace, lprcPosRect, lprcPosRect); + inplace->lpVtbl->Release(inplace); + } + + return(S_OK); +} + + + +////////////////////////////////////// My IOleInPlaceFrame functions ///////////////////////////////////////// +// +HRESULT STDMETHODCALLTYPE Frame_QueryInterface(IOleInPlaceFrame FAR* This, REFIID riid, LPVOID FAR* ppvObj) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Frame_AddRef(IOleInPlaceFrame FAR* This) +{ + return(1); +} + +HRESULT STDMETHODCALLTYPE Frame_Release(IOleInPlaceFrame FAR* This) +{ + return(1); +} + +HRESULT STDMETHODCALLTYPE Frame_GetWindow(IOleInPlaceFrame FAR* This, HWND FAR* lphwnd) +{ + *lphwnd = ((_IOleInPlaceFrameEx *)This)->window; + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE Frame_ContextSensitiveHelp(IOleInPlaceFrame FAR* This, BOOL fEnterMode) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Frame_GetBorder(IOleInPlaceFrame FAR* This, LPRECT lprectBorder) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Frame_RequestBorderSpace(IOleInPlaceFrame FAR* This, LPCBORDERWIDTHS pborderwidths) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Frame_SetBorderSpace(IOleInPlaceFrame FAR* This, LPCBORDERWIDTHS pborderwidths) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Frame_SetActiveObject(IOleInPlaceFrame FAR* This, IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE Frame_InsertMenus(IOleInPlaceFrame FAR* This, HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Frame_SetMenu(IOleInPlaceFrame FAR* This, HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE Frame_RemoveMenus(IOleInPlaceFrame FAR* This, HMENU hmenuShared) +{ + NOTIMPLEMENTED; +} + +HRESULT STDMETHODCALLTYPE Frame_SetStatusText(IOleInPlaceFrame FAR* This, LPCOLESTR pszStatusText) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE Frame_EnableModeless(IOleInPlaceFrame FAR* This, BOOL fEnable) +{ + return(S_OK); +} + +HRESULT STDMETHODCALLTYPE Frame_TranslateAccelerator(IOleInPlaceFrame FAR* This, LPMSG lpmsg, WORD wID) +{ + NOTIMPLEMENTED; +} + + + + +/*************************** UnEmbedBrowserObject() ************************ + * Called to detach the browser object from our host window, and free its + * resources, right before we destroy our window. + * + * hwnd = Handle to the window hosting the browser object. + * + * NOTE: The pointer to the browser object must have been stored in the + * window's USERDATA field. In other words, don't call UnEmbedBrowserObject(). + * with a HWND that wasn't successfully passed to EmbedBrowserObject(). + */ + +void UnEmbedBrowserObject(HWND hwnd) +{ + IOleObject **browserHandle; + IOleObject *browserObject; + + // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when + // we initially attached the browser object to this window. + if ((browserHandle = (IOleObject **)GetWindowLongPtr(hwnd, GWLP_USERDATA))) + { + // Unembed the browser object, and release its resources. + browserObject = *browserHandle; + browserObject->lpVtbl->Close(browserObject, OLECLOSE_NOSAVE); + browserObject->lpVtbl->Release(browserObject); + + GlobalFree(browserHandle); + + return; + } +} + + +/******************************* DisplayHTMLStr() **************************** + * Takes a string containing some HTML BODY, and displays it in the specified + * window. For example, perhaps you want to display the HTML text of... + * + *

This is a picture.

+ * + * hwnd = Handle to the window hosting the browser object. + * string = Pointer to nul-terminated string containing the HTML BODY. + * (NOTE: No tags are required in the string). + * + * RETURNS: 0 if success, or non-zero if an error. + * + * NOTE: EmbedBrowserObject() must have been successfully called once with the + * specified window, prior to calling this function. You need call + * EmbedBrowserObject() once only, and then you can make multiple calls to + * this function to display numerous pages in the specified window. + */ + +long DisplayHTMLStr(HWND hwnd, LPCTSTR string) +{ + IWebBrowser2 *webBrowser2; + LPDISPATCH lpDispatch; + IHTMLDocument2 *htmlDoc2; + IOleObject *browserObject; + SAFEARRAY *sfArray; + VARIANT myURL; + VARIANT *pVar; + BSTR bstr; + + // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when + // we initially attached the browser object to this window. + browserObject = *((IOleObject **)GetWindowLongPtr(hwnd, GWLP_USERDATA)); + + // Assume an error. + bstr = 0; + + // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser + // object, so we can call some of the functions in the former's table. + if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2)) + { + // Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is + // webBrowser2->lpVtbl. + + // Before we can get_Document(), we actually need to have some HTML page loaded in the browser. So, + // let's load an empty HTML page. Then, once we have that empty page, we can get_Document() and + // write() to stuff our HTML string into it. + VariantInit(&myURL); + myURL.vt = VT_BSTR; + myURL.bstrVal = SysAllocString(L"about:blank"); + + // Call the Navigate2() function to actually display the page. + webBrowser2->lpVtbl->Navigate2(webBrowser2, &myURL, 0, 0, 0, 0); + + // Free any resources (including the BSTR). + VariantClear(&myURL); + + // Call the IWebBrowser2 object's get_Document so we can get its DISPATCH object. I don't know why you + // don't get the DISPATCH object via the browser object's QueryInterface(), but you don't. + if (!webBrowser2->lpVtbl->get_Document(webBrowser2, &lpDispatch)) + { + // We want to get a pointer to the IHTMLDocument2 object embedded within the DISPATCH + // object, so we can call some of the functions in the former's table. + if (!lpDispatch->lpVtbl->QueryInterface(lpDispatch, &IID_IHTMLDocument2, (void**)&htmlDoc2)) + { + // Ok, now the pointer to our IHTMLDocument2 object is in 'htmlDoc2', and so its VTable is + // htmlDoc2->lpVtbl. + + // Our HTML must be in the form of a BSTR. And it must be passed to write() in an + // array of "VARIENT" structs. So let's create all that. + if ((sfArray = SafeArrayCreate(VT_VARIANT, 1, (SAFEARRAYBOUND *)&ArrayBound))) + { + if (!SafeArrayAccessData(sfArray, (void**)&pVar)) + { + pVar->vt = VT_BSTR; +#ifndef UNICODE + { + wchar_t *buffer; + DWORD size; + + size = MultiByteToWideChar(CP_ACP, 0, string, -1, 0, 0); + if (!(buffer = (wchar_t *)GlobalAlloc(GMEM_FIXED, sizeof(wchar_t) * size))) goto bad; + MultiByteToWideChar(CP_ACP, 0, string, -1, buffer, size); + bstr = SysAllocString(buffer); + GlobalFree(buffer); + } +#else + bstr = SysAllocString(string); +#endif + // Store our BSTR pointer in the VARIENT. + if ((pVar->bstrVal = bstr)) + { + htmlDoc2->lpVtbl->clear(htmlDoc2); + // Pass the VARIENT with its BSTR to write() in order to shove our desired HTML string + // into the body of that empty page we created above. + htmlDoc2->lpVtbl->write(htmlDoc2, sfArray); + + // Close the document. If we don't do this, subsequent calls to DisplayHTMLStr + // would append to the current contents of the page + htmlDoc2->lpVtbl->close(htmlDoc2); + + // Normally, we'd need to free our BSTR, but SafeArrayDestroy() does it for us +// SysFreeString(bstr); + } + } + + // Free the array. This also frees the VARIENT that SafeArrayAccessData created for us, + // and even frees the BSTR we allocated with SysAllocString + SafeArrayDestroy(sfArray); + } + + // Release the IHTMLDocument2 object. +bad: htmlDoc2->lpVtbl->Release(htmlDoc2); + } + + // Release the DISPATCH object. + lpDispatch->lpVtbl->Release(lpDispatch); + } + + // Release the IWebBrowser2 object. + webBrowser2->lpVtbl->Release(webBrowser2); + } + + // No error? + if (bstr) return(0); + + // An error + return(-1); +} + + + +/******************************* ResizeBrowser() **************************** + * Resizes the browser object for the specified window to the specified + * width and height. + * + * hwnd = Handle to the window hosting the browser object. + * width = Width. + * height = Height. + * + * NOTE: EmbedBrowserObject() must have been successfully called once with the + * specified window, prior to calling this function. You need call + * EmbedBrowserObject() once only, and then you can make multiple calls to + * this function to resize the browser object. + */ + +void ResizeBrowser(HWND hwnd, DWORD width, DWORD height) +{ + IWebBrowser2 *webBrowser2; + IOleObject *browserObject; + + // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when + // we initially attached the browser object to this window. + browserObject = *((IOleObject **)GetWindowLongPtr(hwnd, GWLP_USERDATA)); + + // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser + // object, so we can call some of the functions in the former's table. + if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2)) + { + // Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is + // webBrowser2->lpVtbl. + + // Call are put_Width() and put_Height() to set the new width/height. + webBrowser2->lpVtbl->put_Width(webBrowser2, width); + webBrowser2->lpVtbl->put_Height(webBrowser2, height); + + // We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it, + // so we can release our hold on it). Note that we'll still maintain our hold on the browser + // object. + webBrowser2->lpVtbl->Release(webBrowser2); + } +} + + + + + +/***************************** EmbedBrowserObject() ************************** + * Puts the browser object inside our host window, and save a pointer to this + * window's browser object in the window's GWL_USERDATA field. + * + * hwnd = Handle of our window into which we embed the browser object. + * + * RETURNS: 0 if success, or non-zero if an error. + * + * NOTE: We tell the browser object to occupy the entire client area of the + * window. + * + * NOTE: No HTML page will be displayed here. We can do that with a subsequent + * call to either DisplayHTMLPage() or DisplayHTMLStr(). This is merely once-only + * initialization for using the browser object. In a nutshell, what we do + * here is get a pointer to the browser object in our window's GWL_USERDATA + * so we can access that object's functions whenever we want, and we also pass + * the browser a pointer to our IOleClientSite struct so that the browser can + * call our functions in our struct's VTable. + */ + +long EmbedBrowserObject(HWND hwnd) +{ + LPCLASSFACTORY pClassFactory; + IOleObject *browserObject; + IWebBrowser2 *webBrowser2; + RECT rect; + char *ptr; + _IOleClientSiteEx *_iOleClientSiteEx; + + // Our IOleClientSite, IOleInPlaceSite, and IOleInPlaceFrame functions need to get our window handle. We + // could store that in some global. But then, that would mean that our functions would work with only that + // one window. If we want to create multiple windows, each hosting its own browser object (to display its + // own web page), then we need to create unique IOleClientSite, IOleInPlaceSite, and IOleInPlaceFrame + // structs for each window. And we'll put an extra field at the end of those structs to store our extra + // data such as a window handle. So, our functions won't have to touch global data, and can therefore be + // re-entrant and work with multiple objects/windows. + // + // Remember that a pointer to our IOleClientSite we create here will be passed as the first arg to every + // one of our IOleClientSite functions. Ditto with the IOleInPlaceFrame object we create here, and the + // IOleInPlaceFrame functions. So, our functions are able to retrieve the window handle we'll store here, + // and then, they'll work with all such windows containing a browser control. + // + // Furthermore, since the browser will be calling our IOleClientSite's QueryInterface to get a pointer to + // our IOleInPlaceSite and IDocHostUIHandler objects, that means that our IOleClientSite QueryInterface + // must have an easy way to grab those pointers. Probably the easiest thing to do is just embed our + // IOleInPlaceSite and IDocHostUIHandler objects inside of an extended IOleClientSite which we'll call + // a _IOleClientSiteEx. As long as they come after the pointer to the IOleClientSite VTable, then we're + // ok. + // + // Of course, we need to GlobalAlloc the above structs now. We'll just get all 4 with a single call to + // GlobalAlloc, especially since 3 of them are all contained inside of our _IOleClientSiteEx anyway. + // + // So, we're not actually allocating separate IOleClientSite, IOleInPlaceSite, IOleInPlaceFrame and + // IDocHostUIHandler structs. + // + // One final thing. We're going to allocate extra room to store the pointer to the browser object. + if (!(ptr = (char *)GlobalAlloc(GMEM_FIXED, sizeof(_IOleClientSiteEx) + sizeof(IOleObject *)))) + return(-1); + + // Initialize our IOleClientSite object with a pointer to our IOleClientSite VTable. + _iOleClientSiteEx = (_IOleClientSiteEx *)(ptr + sizeof(IOleObject *)); + _iOleClientSiteEx->client.lpVtbl = &MyIOleClientSiteTable; + + // Initialize our IOleInPlaceSite object with a pointer to our IOleInPlaceSite VTable. + _iOleClientSiteEx->inplace.inplace.lpVtbl = &MyIOleInPlaceSiteTable; + + // Initialize our IOleInPlaceFrame object with a pointer to our IOleInPlaceFrame VTable. + _iOleClientSiteEx->inplace.frame.frame.lpVtbl = &MyIOleInPlaceFrameTable; + + // Save our HWND (in the IOleInPlaceFrame object) so our IOleInPlaceFrame functions can retrieve it. + _iOleClientSiteEx->inplace.frame.window = hwnd; + + // Initialize our IDocHostUIHandler object with a pointer to our IDocHostUIHandler VTable. + _iOleClientSiteEx->ui.ui.lpVtbl = &MyIDocHostUIHandlerTable; + + // Get a pointer to the browser object and lock it down (so it doesn't "disappear" while we're using + // it in this program). We do this by calling the OS function CoGetClassObject(). + // + // NOTE: We need this pointer to interact with and control the browser. With normal WIN32 controls such as a + // Static, Edit, Combobox, etc, you obtain an HWND and send messages to it with SendMessage(). Not so with + // the browser object. You need to get a pointer to its "base structure" (as returned by CoGetClassObject()). This + // structure contains an array of pointers to functions you can call within the browser object. Actually, the + // base structure contains a 'lpVtbl' field that is a pointer to that array. We'll call the array a 'VTable'. + // + // For example, the browser object happens to have a SetHostNames() function we want to call. So, after we + // retrieve the pointer to the browser object (in a local we'll name 'browserObject'), then we can call that + // function, and pass it args, as so: + // + // browserObject->lpVtbl->SetHostNames(browserObject, SomeString, SomeString); + // + // There's our pointer to the browser object in 'browserObject'. And there's the pointer to the browser object's + // VTable in 'browserObject->lpVtbl'. And the pointer to the SetHostNames function happens to be stored in an + // field named 'SetHostNames' within the VTable. So we are actually indirectly calling SetHostNames by using + // a pointer to it. That's how you use a VTable. + // + // NOTE: We pass our _IOleClientSiteEx struct and lie -- saying that it's a IOleClientSite. It's ok. A + // _IOleClientSiteEx struct starts with an embedded IOleClientSite. So the browser won't care, and we want + // this extended struct passed to our IOleClientSite functions. + + // Get a pointer to the browser object's IClassFactory object via CoGetClassObject() + pClassFactory = 0; + if (!CoGetClassObject(&CLSID_WebBrowser, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, NULL, &IID_IClassFactory, (void **)&pClassFactory) && pClassFactory) + { + // Call the IClassFactory's CreateInstance() to create a browser object + if (!pClassFactory->lpVtbl->CreateInstance(pClassFactory, 0, &IID_IOleObject, &browserObject)) + { + // Free the IClassFactory. We need it only to create a browser object instance + pClassFactory->lpVtbl->Release(pClassFactory); + + // Ok, we now have the pointer to the browser object in 'browserObject'. Let's save this in the + // memory block we allocated above, and then save the pointer to that whole thing in our window's + // USERDATA field. That way, if we need multiple windows each hosting its own browser object, we can + // call EmbedBrowserObject() for each one, and easily associate the appropriate browser object with + // its matching window and its own objects containing per-window data. + *((IOleObject **)ptr) = browserObject; + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)ptr); + + // Give the browser a pointer to my IOleClientSite object + if (!browserObject->lpVtbl->SetClientSite(browserObject, (IOleClientSite *)_iOleClientSiteEx)) + { + // We can now call the browser object's SetHostNames function. SetHostNames lets the browser object know our + // application's name and the name of the document in which we're embedding the browser. (Since we have no + // document name, we'll pass a 0 for the latter). When the browser object is opened for editing, it displays + // these names in its titlebar. + // + // We are passing 3 args to SetHostNames. You'll note that the first arg to SetHostNames is the base + // address of our browser control. This is something that you always have to remember when working in C + // (as opposed to C++). When calling a VTable function, the first arg to that function must always be the + // structure which contains the VTable. (In this case, that's the browser control itself). Why? That's + // because that function is always assumed to be written in C++. And the first argument to any C++ function + // must be its 'this' pointer (ie, the base address of its class, which in this case is our browser object + // pointer). In C++, you don't have to pass this first arg, because the C++ compiler is smart enough to + // produce an executable that always adds this first arg. In fact, the C++ compiler is smart enough to + // know to fetch the function pointer from the VTable, so you don't even need to reference that. In other + // words, the C++ equivalent code would be: + // + // browserObject->SetHostNames(L"My Host Name", 0); + // + // So, when you're trying to convert C++ code to C, always remember to add this first arg whenever you're + // dealing with a VTable (ie, the field is usually named 'lpVtbl') in the standard objects, and also add + // the reference to the VTable itself. + // + // Oh yeah, the L is because we need UNICODE strings. And BTW, the host and document names can be anything + // you want. + browserObject->lpVtbl->SetHostNames(browserObject, L"My Host Name", 0); + + GetClientRect(hwnd, &rect); + + // Let browser object know that it is embedded in an OLE container. + if (!OleSetContainedObject((struct IUnknown *)browserObject, TRUE) && + + // Set the display area of our browser control the same as our window's size + // and actually put the browser object into our window. + !browserObject->lpVtbl->DoVerb(browserObject, OLEIVERB_SHOW, NULL, (IOleClientSite *)_iOleClientSiteEx, -1, hwnd, &rect) && + + // Ok, now things may seem to get even trickier, One of those function pointers in the browser's VTable is + // to the QueryInterface() function. What does this function do? It lets us grab the base address of any + // other object that may be embedded within the browser object. And this other object has its own VTable + // containing pointers to more functions we can call for that object. + // + // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser + // object, so we can call some of the functions in the former's table. For example, one IWebBrowser2 function + // we intend to call below will be Navigate2(). So we call the browser object's QueryInterface to get our + // pointer to the IWebBrowser2 object. + !browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2)) + { + // Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is + // webBrowser2->lpVtbl. + + // Let's call several functions in the IWebBrowser2 object to position the browser display area + // in our window. The functions we call are put_Left(), put_Top(), put_Width(), and put_Height(). + // Note that we reference the IWebBrowser2 object's VTable to get pointers to those functions. And + // also note that the first arg we pass to each is the pointer to the IWebBrowser2 object. + webBrowser2->lpVtbl->put_Left(webBrowser2, 0); + webBrowser2->lpVtbl->put_Top(webBrowser2, 0); + webBrowser2->lpVtbl->put_Width(webBrowser2, rect.right); + webBrowser2->lpVtbl->put_Height(webBrowser2, rect.bottom); + + // We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it + // right now, so we can release our hold on it). Note that we'll still maintain our hold on the + // browser object until we're done with that object. + webBrowser2->lpVtbl->Release(webBrowser2); + + // Success + return(0); + } + } + + // Something went wrong setting up the browser! + UnEmbedBrowserObject(hwnd); + return(-4); + } + + pClassFactory->lpVtbl->Release(pClassFactory); + GlobalFree(ptr); + + // Can't create an instance of the browser! + return(-3); + } + + GlobalFree(ptr); + + // Can't get the web browser's IClassFactory! + return(-2); +} + + + + + +/****************************** WindowProc() *************************** + * Our message handler for our window to host the browser. + */ + +LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_SIZE: + { + // Resize the browser object to fit the window + ResizeBrowser(hwnd, LOWORD(lParam), HIWORD(lParam)); + return(0); + } + + case WM_CREATE: + { + // Embed the browser object into our host window. We need do this only + // once. Note that the browser object will start calling some of our + // IOleInPlaceFrame and IOleClientSite functions as soon as we start + // calling browser object functions in EmbedBrowserObject(). + if (EmbedBrowserObject(hwnd)) return(-1); + + // Success + return(0); + } + + case WM_DESTROY: + { + int i, nCount; + + // Detach the browser object from this window, and free resources. + UnEmbedBrowserObject(hwnd); + + // If all the windows are now closed, quit this app + if (m_hWindows) + { + for (i=0, nCount=List_Count(m_hWindows); ihWnd = CreateWindowEx(0, wc.lpszClassName, Param->pszTitle, WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, Param->width, Param->height, + HWND_DESKTOP, NULL, wc.hInstance, 0))) + { + List_Push (m_hWindows, Param->hWnd); + DisplayHTMLStr(Param->hWnd, Param->pszHTML); + ShowWindow(Param->hWnd, SW_SHOWNORMAL); + SetForegroundWindow (Param->hWnd); + UpdateWindow(Param->hWnd); + } + SetEvent (m_hEvent); + break; + } + case WM_USER+1: + { + DestroyWindow ((HWND)msg.lParam); + break; + } + } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + UnregisterClass (wc.lpszClassName, wc.hInstance); + CoUninitialize(); + if (m_hWindows) List_Exit (m_hWindows); + ExitThread (0); + return 0; +} + +// ----------------------------------------------------------------------------- +// Interface +// ----------------------------------------------------------------------------- + +// bInitBrowser - Tries to initialize a dummy window on start so that subsequent +// calls are faster as all libraries are already present in +// memory. Drawback: Higher memory consumption +int W32Browser_Init(BOOL bInitBrowser) +{ + if (m_hThread) W32Browser_Exit(); + m_hThread = (HANDLE)_beginthreadex(NULL, 0, ShowIEWndFunc, (LPVOID)bInitBrowser, 0, &m_dwThread); + if (!m_hThread) return -1; + if (!(m_hEvent = CreateEvent (NULL, FALSE, FALSE, NULL))) + { + TerminateThread (m_hThread, -1); + CloseHandle (m_hThread); + return -1; + } + return 0; +} + +// ----------------------------------------------------------------------------- + +void W32Browser_Exit(void) +{ + if (m_hWindows) + { + HWND hWnd; + + while (hWnd = List_Pop(m_hWindows)) + W32Browser_CloseWindow (hWnd); + m_hWindows = NULL; + } + if (m_hThread) + { + PostThreadMessage (m_dwThread, WM_QUIT, 0, 0); + if (WaitForSingleObject (m_hThread, 2000) == WAIT_TIMEOUT) + TerminateThread (m_hThread, -1); + CloseHandle (m_hThread); + m_hThread = NULL; + } + if (m_hEvent) + { + CloseHandle (m_hEvent); + m_hEvent = NULL; + } +} + +// ----------------------------------------------------------------------------- + +void *W32Browser_ShowHTMLStr(char *pszHTMLStr, int width, int height, char *pszTitle) +{ + // Window gets its own thread to not block the Mainthread + static ShowIEWndParam Param; + + Param.width = width; + Param.height = height; + Param.pszHTML = pszHTMLStr; + Param.pszTitle = pszTitle; + Param.hWnd = 0; + PostThreadMessage (m_dwThread, WM_USER, 0, (LPARAM)&Param); + WaitForSingleObject (m_hEvent, INFINITE); + return (void*)Param.hWnd; +} + +// ----------------------------------------------------------------------------- + +void W32Browser_CloseWindow (void *pWnd) +{ + PostThreadMessage (m_dwThread, WM_USER+1, 0, (LPARAM)pWnd); +} diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.h new file mode 100644 index 0000000000..effc86998d --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.h @@ -0,0 +1,5 @@ +int W32Browser_Init(int bInitBrowser); +void W32Browser_Exit(void); + +void *W32Browser_ShowHTMLStr(char *pszHTMLStr, int width, int height, char *pszTitle); +void W32Browser_CloseWindow (void *pWnd); diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.c new file mode 100644 index 0000000000..f9cc734cd1 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.c @@ -0,0 +1,387 @@ +#include +#include "imo2sproxy.h" +#define WIN32_LEAN_AND_MEAN +#include +#define LockMutex(x) EnterCriticalSection (&x) +#define UnlockMutex(x) LeaveCriticalSection(&x) +#define InitMutex(x) InitializeCriticalSection(&x) +#define ExitMutex(x) DeleteCriticalSection(&x) +#define strcasecmp stricmp +#define strncasecmp stricmpn +#define mutex_t CRITICAL_SECTION +#include +#include +#include +#include "memlist.h" +#include "w32skypeemu.h" + +#ifndef _WIN64 +#if WINVER<0x0500 +#define SetWindowLongPtr SetWindowLong +#define GetWindowLongPtr GetWindowLong +#endif +#ifndef LONG_PTR +#define LONG_PTR LONG +#endif +#ifndef GWLP_USERDATA +#define GWLP_USERDATA GWL_USERDATA +#endif +#endif + +// Skype API defines +#define SKYPECONTROLAPI_ATTACH_SUCCESS 0 +#define SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION 1 +#define SKYPECONTROLAPI_ATTACH_REFUSED 2 +#define SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE 3 +#define SKYPECONTROLAPI_ATTACH_API_AVAILABLE 0x8001 + +// ----------------------------------------------------------------------------- + +typedef struct +{ + IMO2SPROXY vtbl; // Must be first! + IMO2SPROXY_CFG *pCfg; + W32SKYPEEMU_CFG *pMyCfg; + HWND hWndDispatch; + TYP_LIST *hClients; + mutex_t loopmutex; + DWORD dwThreadID; +} IMO2SPROXY_INST; + +typedef struct +{ + HWND hWnd; + IMOSAPI *hInst; + IMO2SPROXY_INST *hProxy; + mutex_t sendmutex; + int iConnectionStat; +} CONNINST; + +static UINT m_ControlAPIAttach = 0; +static UINT m_ControlAPIDiscover = 0; + +// ----------------------------------------------------------------------------- + +static void EventHandler(char *pszMsg, void *pUser); +static CONNINST *FindClient(IMO2SPROXY_INST *hProxy, HWND hWnd); +static void CleanConnections (TYP_LIST *hList); +static void FreeConnection (CONNINST *pInst); +static LONG APIENTRY WndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam); + +static int Imo2sproxy_Open(IMO2SPROXY *hInst); +static void Imo2sproxy_Loop(IMO2SPROXY *hInst); +static void Imo2sproxy_Exit(IMO2SPROXY *hInst); + +// ----------------------------------------------------------------------------- +static void EventHandler(char *pszMsg, void *pUser) +{ + CONNINST *pInst = (CONNINST*)pUser; + COPYDATASTRUCT cds; + DWORD dwRes = 0; + + LockMutex(pInst->sendmutex); + if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) + { + fprintf (pInst->hProxy->pCfg->fpLog, "%08X> %s\n", pInst->hWnd, pszMsg); + fflush (pInst->hProxy->pCfg->fpLog); + } + cds.dwData = 0; + cds.cbData = strlen(pszMsg)+1; + cds.lpData = pszMsg; + SendMessageTimeout (pInst->hWnd, WM_COPYDATA, (WPARAM)pInst->hProxy->hWndDispatch, (LPARAM)&cds, SMTO_NORMAL, 1000, &dwRes); + UnlockMutex(pInst->sendmutex); +} + +// ----------------------------------------------------------------------------- + +static CONNINST *FindClient(IMO2SPROXY_INST *hProxy, HWND hWnd) +{ + int i, nCount; + CONNINST *pConn; + + for (i=0, nCount=List_Count(hProxy->hClients); ihClients, i))->hWnd == hWnd) + return pConn; + } + return NULL; +} + +// ----------------------------------------------------------------------------- + +static void CleanConnections (TYP_LIST *hList) +{ + unsigned int i; + CONNINST *pInst; + + for (i=0; ihWnd)) + { + if (pInst->hInst) FreeConnection(pInst); + free (List_RemoveElementAt(hList, i)); + i--; + } + } +} + +// ----------------------------------------------------------------------------- + +static void FreeConnection (CONNINST *pInst) +{ + if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) + { + fprintf (pInst->hProxy->pCfg->fpLog, "Closed connection %08X\n", pInst->hWnd); + fflush (pInst->hProxy->pCfg->fpLog); + } + ExitMutex (pInst->sendmutex); + if (pInst->hInst) + { + IMOSAPI *hInst = pInst->hInst; + pInst->hInst = NULL; + Imo2S_Exit(hInst); + } +} + +// ----------------------------------------------------------------------------- + +static LONG APIENTRY WndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam) +{ + switch (message) + { + case WM_CREATE: + { + LPCREATESTRUCT lpCr = (LPCREATESTRUCT)lParam; + + SetWindowLongPtr (hWnd, GWLP_USERDATA, (LONG_PTR)lpCr->lpCreateParams); + SetTimer (hWnd, 0, 60000, NULL); + break; + } + case WM_COPYDATA: + { + PCOPYDATASTRUCT pCopyData = (PCOPYDATASTRUCT)lParam; + CONNINST *pInst; + IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)GetWindowLongPtr(hWnd, GWLP_USERDATA); + + if (pInst = FindClient (hProxy, (HWND)wParam)) + { + if (pInst->hProxy->pMyCfg->bDelayLogin && pInst->iConnectionStat < 1) + { + char *pszError; + + if ((pInst->iConnectionStat = Imo2S_Login (pInst->hInst, hProxy->pCfg->pszUser, hProxy->pCfg->pszPass, &pszError)) != 1) + { + pInst->hProxy->pCfg->logerror (stderr, "Connection %08X: Cannot login with (%s/****): %s\n", + pInst->hWnd, hProxy->pCfg->pszUser, pszError); + FreeConnection(pInst); + free (List_Pop(hProxy->hClients)); + PostMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_REFUSED); + return 0; + } + } + LockMutex(pInst->sendmutex); + if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog) + { + fprintf (pInst->hProxy->pCfg->fpLog, "%08X< [%s]\n", pInst->hWnd, pCopyData->lpData); + fflush (pInst->hProxy->pCfg->fpLog); + } + Imo2S_Send (pInst->hInst, pCopyData->lpData); + UnlockMutex(pInst->sendmutex); + } + return 1; + } + case WM_TIMER: + // Housekeeping timer + CleanConnections (((IMO2SPROXY_INST*)GetWindowLongPtr(hWnd, GWLP_USERDATA))->hClients); + break; + case WM_DESTROY: + KillTimer (hWnd, 0); + break; + default: + if (message == m_ControlAPIDiscover) + { + CONNINST *pInst; + IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)GetWindowLongPtr(hWnd, GWLP_USERDATA); + char *pszError; + + if (!(pInst = FindClient (hProxy, (HWND)wParam))) + { + pInst = (CONNINST*)calloc (1, sizeof(CONNINST)); + if (!pInst) break; + List_Push(hProxy->hClients, pInst); + pInst->hProxy = hProxy; + pInst->hWnd = (HWND)wParam; + if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) + fprintf (hProxy->pCfg->fpLog, "Imo2sproxy::SkypeControlAPIDiscover\n"); + + if (!(pInst->hInst = Imo2S_Init(EventHandler, pInst, hProxy->pCfg->iFlags))) + { + hProxy->pCfg->logerror (stderr, "Connection %08X: Cannot start Imo2Skype instance.\n", pInst->hWnd); + free (List_Pop(hProxy->hClients)); + PostMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_REFUSED); + return 0; + } + + // FIXME: We should enable logging dependent on a loglevel rather than just enabling it + if (hProxy->pCfg->bVerbose) + Imo2S_SetLog (pInst->hInst, hProxy->pCfg->fpLog); + + InitMutex(pInst->sendmutex); + + if (!pInst->hProxy->pMyCfg->bDelayLogin) + { + PostMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE); + if ((pInst->iConnectionStat = Imo2S_Login (pInst->hInst, hProxy->pCfg->pszUser, hProxy->pCfg->pszPass, &pszError)) != 1) + { + pInst->hProxy->pCfg->logerror (stderr, "Connection %08X: Cannot login with (%s/****): %s\n", + pInst->hWnd, hProxy->pCfg->pszUser, pszError); + FreeConnection(pInst); + free (List_Pop(hProxy->hClients)); + PostMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_REFUSED); + return 0; + } + PostMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_API_AVAILABLE); + } + else + { + SendMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_SUCCESS); + } + return 0; + } + else + SendMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_SUCCESS); + return 0; + } + break; + } + return (DefWindowProc(hWnd, message, wParam, lParam)); +} + + + +// ----------------------------------------------------------------------------- +// PUBLIC +// ----------------------------------------------------------------------------- + +void W32SkypeEmu_Defaults (W32SKYPEEMU_CFG *pMyCfg) +{ + memset (pMyCfg, 0, sizeof(W32SKYPEEMU_CFG)); + // Login on first command from Client, immediately send SKYPECONTROLAPI_ATTACH_SUCCESS + // This is necessary for some broken plugins, i.e. current SVN build of Miranda + // Skype plugin, which doesn't correctly poll again if SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE + // is sent. + pMyCfg->bDelayLogin = TRUE; +} + +// ----------------------------------------------------------------------------- + +IMO2SPROXY *W32SkypeEmu_Init (IMO2SPROXY_CFG *pCfg, W32SKYPEEMU_CFG *pMyCfg) +{ + IMO2SPROXY_INST *pstInst = calloc(sizeof(IMO2SPROXY_INST), 1); + + pstInst->vtbl.Open = Imo2sproxy_Open; + pstInst->vtbl.Loop = Imo2sproxy_Loop; + pstInst->vtbl.Exit = Imo2sproxy_Exit; + pstInst->pCfg = pCfg; + pstInst->pMyCfg = pMyCfg; + InitMutex(pstInst->loopmutex); + return (IMO2SPROXY*)pstInst; +} + +// ----------------------------------------------------------------------------- +// IMPLEMENTATION +// ----------------------------------------------------------------------------- +static int Imo2sproxy_Open(IMO2SPROXY *hInst) +{ + IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst; + WNDCLASS WndClass ={0}; + + // Start Skype connection + if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) + fprintf (hProxy->pCfg->fpLog, "W32SkypeEmu:Open(Start)\n"); + if ((!m_ControlAPIAttach && !(m_ControlAPIAttach=RegisterWindowMessage("SkypeControlAPIAttach"))) || + (!m_ControlAPIDiscover && !(m_ControlAPIDiscover=RegisterWindowMessage("SkypeControlAPIDiscover")))) + { + hProxy->pCfg->logerror (stderr, "Cannot register Window messages!"); + return -1; + } + + // Create window class + WndClass.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS; + WndClass.lpfnWndProc = (WNDPROC)WndProc; + WndClass.hInstance = GetModuleHandle(NULL); + WndClass.lpszClassName = "Imo2SProxyDispatchWindow"; + RegisterClass(&WndClass); + + if (!(hProxy->hWndDispatch=CreateWindowEx( WS_EX_APPWINDOW|WS_EX_WINDOWEDGE, + WndClass.lpszClassName, "", WS_BORDER|WS_SYSMENU|WS_MINIMIZEBOX, + CW_USEDEFAULT, CW_USEDEFAULT, 128, 128, NULL, 0, (HINSTANCE)WndClass.hInstance, (LPVOID)hProxy))) + { + hProxy->pCfg->logerror (stderr, "Unable to create dispatch window!"); + UnregisterClass (WndClass.lpszClassName, WndClass.hInstance); + return -1; + } + + hProxy->hClients = List_Init(32); + return 0; +} + +// ----------------------------------------------------------------------------- + +static void Imo2sproxy_Loop(IMO2SPROXY *hInst) +{ + IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst; + MSG Message; + + if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) + fprintf (hProxy->pCfg->fpLog, "W32SkypeEmu:Loop(Start)\n"); + + // Pump da messages + hProxy->dwThreadID = GetCurrentThreadId(); + LockMutex(hProxy->loopmutex); + while (GetMessage(&Message, NULL, 0, 0)) + { + TranslateMessage(&Message); + DispatchMessage(&Message); + } + + if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) + fprintf (hProxy->pCfg->fpLog, "W32SkypeEmu:Loop(End)\n"); + UnlockMutex(hProxy->loopmutex); +} + + +// ----------------------------------------------------------------------------- + +static void Imo2sproxy_Exit(IMO2SPROXY *hInst) +{ + IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst; + CONNINST *pInst; + + if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog) + fprintf (hProxy->pCfg->fpLog, "W32SkypeEmu:Exit()\n"); + + if (hProxy->hWndDispatch) DestroyWindow (hProxy->hWndDispatch); + if (hProxy->dwThreadID) PostThreadMessage (hProxy->dwThreadID, WM_QUIT, 0, 0); + LockMutex(hProxy->loopmutex); + + // Kill 'em all! + if (hProxy->hClients) + { + while (pInst=List_Pop(hProxy->hClients)) + { + FreeConnection(pInst); + free (pInst); + } + List_Exit (hProxy->hClients); + } + + UnregisterClass ("Imo2SProxyDispatchWindow", GetModuleHandle(NULL)); + + UnlockMutex(hProxy->loopmutex); + ExitMutex(hProxy->loopmutex); + + free (hProxy); +} + diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.h new file mode 100644 index 0000000000..a8291f3357 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.h @@ -0,0 +1,6 @@ +typedef struct { + int bDelayLogin; +} W32SKYPEEMU_CFG; + +void W32SkypeEmu_Defaults (W32SKYPEEMU_CFG *pMyCfg); +IMO2SPROXY *W32SkypeEmu_Init (IMO2SPROXY_CFG *pCfg, W32SKYPEEMU_CFG *pMyCfg); diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/Makefile b/plugins/!NotAdopted/IMO2sProxy/src/imolib/Makefile new file mode 100644 index 0000000000..30775becec --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/Makefile @@ -0,0 +1,14 @@ +CFLAGS = -I../common/ -lcurl -lpthread -lm -O0 -g +CC = gcc +COMMON = ../common/fifo.c ../common/cJSON.c +OBJS = imo_request.c imo_skype.c skypetst.c io_layer.c + +.PHONY: all skypetst clean + +all : skypetst + +skypetst: $(COMMON) $(OBJS) + $(CC) -o skypetst $(COMMON) $(OBJS) $(CFLAGS) + +clean : + rm skypetst diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_request.c b/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_request.c new file mode 100644 index 0000000000..732a7e3e48 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_request.c @@ -0,0 +1,388 @@ +/* Module: imo_request.c + Purpose: Posts XMLHHTP-Requests to imo.im server + Author: leecher + Date: 30.08.2009 +*/ +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#define LockMutex(x) EnterCriticalSection (&x) +#define UnlockMutex(x) LeaveCriticalSection(&x) +#define InitMutex(x) InitializeCriticalSection(&x) +#define ExitMutex(x) DeleteCriticalSection(&x) +#define mutex_t CRITICAL_SECTION +#else +#include +#define LockMutex(x) pthread_mutex_lock(&x) +#define UnlockMutex(x) pthread_mutex_unlock(&x) +#define InitMutex(x) pthread_mutex_init(&x, NULL); +#define ExitMutex(x) +#define mutex_t pthread_mutex_t +#endif +#include +#include +#include +#include +#include "fifo.h" +#include "imo_request.h" +#include "io_layer.h" + +#define SSID_LENGTH 16 + +struct _tagIMORQ +{ + IOLAYER *hIO; + char szSessId[SSID_LENGTH+2]; + unsigned long send_ack; // Some Sending ACK number + unsigned long send_seq; // Within one ACK there seems to be a SEQ-Number? + unsigned long *psend_ack; // Pointer to send_ack to use + unsigned long *psend_seq; // Pointer to send_seq to use + mutex_t mutex; // Mutex for securing psend_ack and psend_seq read/write + BOOL bIsClone; // Indicates that the current handle is a clone + char *pszHost; // Login host + char szReqURL[32]; // Request-URL +}; + +static IOLAYER *(*IoLayer_Init)(void) = +#ifdef WIN32 +IoLayerW32_Init; +#else +IoLayerCURL_Init; +#endif + +// Forward declaration of private functions +static size_t add_data(char *data, size_t size, size_t nmemb, void *ctx); +static IMORQ *Init(void); + +// ----------------------------------------------------------------------------- +// Interface +// ----------------------------------------------------------------------------- + +void ImoRq_SetIOLayer(IOLAYER *(*fp_Init)(void)) +{ + IoLayer_Init = fp_Init; +} + +// ----------------------------------------------------------------------------- + +IMORQ *ImoRq_Init(void) +{ + + IMORQ *hRq; + + if (hRq = Init()) + { + /* Create session ID */ + ImoRq_CreateID (hRq->szSessId, SSID_LENGTH+1); + + hRq->psend_seq = &hRq->send_seq; + hRq->psend_ack = &hRq->send_ack; + InitMutex(hRq->mutex); + + /* Disptch version of imo.im protocol */ + switch (IMO_API_VERSION) + { + case 0: + hRq->pszHost = "https://o.imo.im/"; + break; + case 1: + hRq->pszHost = "https://imo.im/"; + break; + } + sprintf (hRq->szReqURL, "%simo", hRq->pszHost); + + /* Fetch start page to get cookies */ + if (hRq->hIO->Get (hRq->hIO, hRq->pszHost, NULL)) + + /* Get new session ID from system */ + { + char *pszRPC = ImoRq_ResetRPC (hRq), *pszRPCRes; + if (pszRPC) + { + if ((pszRPCRes = strstr(pszRPC, "ssid\":\"")) || (pszRPCRes = strstr(pszRPC, "ssid\": \""))) + strcpy (hRq->szSessId, strtok (pszRPCRes+7, "\"")); + } + } else { + ImoRq_Exit(hRq); + hRq = NULL; + } + } + + return hRq; +} + +// ----------------------------------------------------------------------------- + +IMORQ *ImoRq_Clone (IMORQ *hRq) +{ + IMORQ *hDup; + + if (!(hDup = Init())) return NULL; + strcpy (hDup->szSessId, hRq->szSessId); + hDup->psend_seq = hRq->psend_seq; + hDup->psend_ack = hRq->psend_ack; + hDup->mutex = hRq->mutex; + hDup->bIsClone = TRUE; + hDup->pszHost = hRq->pszHost; + strcpy (hDup->szReqURL, hRq->szReqURL); + return hDup; +} + +// ----------------------------------------------------------------------------- + +void ImoRq_Exit (IMORQ *hRq) +{ + if (hRq->hIO) hRq->hIO->Exit(hRq->hIO); + if (!hRq->bIsClone) ExitMutex (hRq->mutex); + free (hRq); +} +// ----------------------------------------------------------------------------- + +void ImoRq_Cancel (IMORQ *hRq) +{ + if (hRq->hIO) hRq->hIO->Cancel(hRq->hIO); +} + +// ----------------------------------------------------------------------------- + +char *ImoRq_PostImo(IMORQ *hRq, char *pszMethod, cJSON *data) +{ + TYP_FIFO *hPostString; + char *pszData, *pszEscData; + unsigned int uiCount = -1; + + if (!(pszData = cJSON_Print(data))) return NULL; +printf ("-> %s\n", pszData); +#ifdef _WIN32 +OutputDebugString (pszData); +OutputDebugString ("\n"); +#endif + pszEscData = hRq->hIO->EscapeString(hRq->hIO, pszData); + free (pszData); + if (!pszEscData || !(hPostString = Fifo_Init(strlen(pszEscData)+32))) + { + if (pszEscData) hRq->hIO->FreeEscapeString (pszEscData); + return NULL; + } + Fifo_AddString (hPostString, "method="); + Fifo_AddString (hPostString, pszMethod); + Fifo_AddString (hPostString, "&data="); + Fifo_AddString (hPostString, pszEscData); + hRq->hIO->FreeEscapeString (pszEscData); + pszEscData = Fifo_Get(hPostString, &uiCount); + pszData = hRq->hIO->Post (hRq->hIO, hRq->szReqURL, pszEscData, + uiCount-1, NULL); + Fifo_Exit(hPostString); +printf ("<- %s\n", pszData); + return pszData; +} + +// ----------------------------------------------------------------------------- + +char *ImoRq_PostSystem(IMORQ *hRq, char *pszMethod, char *pszSysTo, char *pszSysFrom, cJSON *data, int bFreeData) +{ + cJSON *root, *msgs, *msg, *to, *from; + char *pszRet; + + if (!(root=cJSON_CreateObject())) return NULL; + LockMutex (hRq->mutex); + cJSON_AddNumberToObject (root, "ack", *hRq->psend_ack); + if (*hRq->szSessId) cJSON_AddStringToObject (root, "ssid", hRq->szSessId); + else cJSON_AddNumberToObject (root, "ssid", 0); + cJSON_AddItemToObject (root, "messages", (msgs = cJSON_CreateArray())); + if (data) + { + msg=cJSON_CreateObject(); + cJSON_AddItemToObject(msg, "data", data); + to = cJSON_CreateObject(); + cJSON_AddStringToObject (to, "system", pszSysTo); + cJSON_AddItemToObject(msg, "to", to); + from = cJSON_CreateObject(); + cJSON_AddStringToObject (from, "system", pszSysFrom); + if (*hRq->szSessId) cJSON_AddStringToObject (from, "ssid", hRq->szSessId); + else cJSON_AddNumberToObject (from, "ssid", 0); + cJSON_AddItemToObject(msg, "from", from); + cJSON_AddNumberToObject (msg, "seq", (*hRq->psend_seq)++); + cJSON_AddItemToArray (msgs, msg); + } + UnlockMutex (hRq->mutex); + pszRet = ImoRq_PostImo (hRq, pszMethod, root); + if (data && !bFreeData) + { + msg->child = data->next; + data->next = NULL; + } + cJSON_Delete (root); + return pszRet; +} + +// ----------------------------------------------------------------------------- + +char *ImoRq_ResetRPC(IMORQ *hRq) +{ + cJSON *root, *ssid; + char *pszRet; + + if (!(root=cJSON_CreateObject())) return NULL; + cJSON_AddStringToObject (root, "method", (IMO_API_VERSION==0?"get_ssid":"get_cookie_and_ssid")); + ssid=cJSON_CreateObject(); + cJSON_AddStringToObject (ssid, "ssid", hRq->szSessId); + if (IMO_API_VERSION > 0) + { + cJSON_AddStringToObject (ssid, "kind", "reui"); + cJSON_AddStringToObject (ssid, "version", "1336611734.48"); + } + cJSON_AddItemToObject(root, "data", ssid); + if (IMO_API_VERSION == 0) *hRq->szSessId = 0; + pszRet = ImoRq_PostSystem (hRq, "rest_rpc", (IMO_API_VERSION==0?"ssid":"session"), "client", root, 1); + LockMutex (hRq->mutex); + *hRq->psend_seq=0; + UnlockMutex (hRq->mutex); + return pszRet; +} + +// ----------------------------------------------------------------------------- + +char *ImoRq_UserActivity(IMORQ *hRq) +{ + cJSON *ssid; + + ssid=cJSON_CreateObject(); + cJSON_AddStringToObject (ssid, "ssid", hRq->szSessId); + return ImoRq_PostToSys (hRq, "observed_user_activity", "session", ssid, 1, NULL); +} + +// ----------------------------------------------------------------------------- + +char *ImoRq_Echo(IMORQ *hRq) +{ + cJSON *data; + time_t t; + char szTime[16], *pszRet; + + if (!(data=cJSON_CreateObject())) return NULL; + sprintf (szTime, "%ld", time(&t)*1000); + cJSON_AddStringToObject (data, "t", szTime); + pszRet = ImoRq_PostImo (hRq, "echo", data); + cJSON_Delete (data); + return pszRet; +} + +// ----------------------------------------------------------------------------- + +char *ImoRq_Reui_Session(IMORQ *hRq) +{ + cJSON *ssid; + + ssid=cJSON_CreateObject(); + cJSON_AddStringToObject (ssid, "ssid", hRq->szSessId); + return ImoRq_PostToSys (hRq, "reui_session", "session", ssid, 1, NULL); +} + +// ----------------------------------------------------------------------------- + +char *ImoRq_PostToSys(IMORQ *hRq, char *pszMethod, char *pszSysTo, cJSON *data, int bFreeData, int *pireqid) +{ + cJSON *root; + char *pszRet; + + if (!(root=cJSON_CreateObject())) return NULL; + cJSON_AddStringToObject (root, "method", pszMethod); + if (pireqid) cJSON_AddNumberToObject(root, "request_id", *pireqid); + cJSON_AddItemToObject(root, "data", data); + pszRet = ImoRq_PostSystem (hRq, "forward_to_server", pszSysTo, "client", root, bFreeData); + if (!bFreeData) + { + data->prev->next = data->next; + if (data->next) data->next->prev = data->prev; + data->prev = data->next = NULL; + cJSON_Delete (root); + } + return pszRet; +} +// ----------------------------------------------------------------------------- + +char *ImoRq_PostAmy(IMORQ *hRq, char *pszMethod, cJSON *data) +{ + return ImoRq_PostToSys (hRq, pszMethod, "im", data, FALSE, NULL); +} + +// ----------------------------------------------------------------------------- + +char *ImoRq_SessId(IMORQ *hRq) +{ + return hRq->szSessId; +} + +// ----------------------------------------------------------------------------- + +char *ImoRq_GetLastError(IMORQ *hRq) +{ + return hRq->hIO->GetLastError (hRq->hIO); +} + +// ----------------------------------------------------------------------------- +char *ImoRq_GetHost(IMORQ *hRq) +{ + return hRq->pszHost; +} + +// ----------------------------------------------------------------------------- +void ImoRq_UpdateAck(IMORQ *hRq, unsigned long lAck) +{ + LockMutex (hRq->mutex); + *hRq->psend_ack = lAck; + UnlockMutex (hRq->mutex); +} +// ----------------------------------------------------------------------------- +unsigned long ImoRq_GetSeq(IMORQ *hRq) +{ + unsigned long lRet; + + LockMutex (hRq->mutex); + lRet = *hRq->psend_seq; + UnlockMutex (hRq->mutex); + return lRet; +} +// ----------------------------------------------------------------------------- + +void ImoRq_CreateID(char *pszID, int cbID) +{ + int i, r; + time_t curtime; + + srand(time(&curtime)); + for (i=0; ihIO->Get (hRq->hIO, pszURL, pdwLength); +} + +// ----------------------------------------------------------------------------- + +static IMORQ *Init(void) +{ + IMORQ *hRq = calloc(1, sizeof(IMORQ)); + + /* Setup CURL */ + if (!hRq) return NULL; + if (!(hRq->hIO = IoLayer_Init())) + { + ImoRq_Exit(hRq); + return NULL; + } + return hRq; +} + diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_request.h b/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_request.h new file mode 100644 index 0000000000..42da000bc2 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_request.h @@ -0,0 +1,36 @@ +#ifndef _IMO_REQUEST_H_ +#define _IMO_REQUEST_H_ + +#include "cJSON.h" + +// 1 - New imo.im api +// 0 - o.imo.im api +#define IMO_API_VERSION 1 + +struct _tagIMORQ; +typedef struct _tagIMORQ IMORQ; + +#ifdef _IOLAYER_H_ +void ImoRq_SetIOLayer(IOLAYER *(*fp_Init)(void)); +#endif + +IMORQ *ImoRq_Init(void); +IMORQ *ImoRq_Clone (IMORQ *hRq); +void ImoRq_Cancel (IMORQ *hRq); +void ImoRq_Exit (IMORQ *hRq); + +char *ImoRq_SessId(IMORQ *hRq); +char *ImoRq_GetLastError(IMORQ *hRq); +char *ImoRq_GetHost(IMORQ *hRq); +char *ImoRq_PostAmy(IMORQ *hRq, char *pszMethod, cJSON *data); +void ImoRq_CreateID(char *pszID, int cbID); +char *ImoRq_PostSystem(IMORQ *hRq, char *pszMethod, char *pszSysTo, char *pszSysFrom, cJSON *data, int bFreeData); +char *ImoRq_PostToSys(IMORQ *hRq, char *pszMethod, char *pszSysTo, cJSON *data, int bFreeData, int *pireqid); +void ImoRq_UpdateAck(IMORQ *hRq, unsigned long lAck); +unsigned long ImoRq_GetSeq(IMORQ *hRq); +char *ImoRq_UserActivity(IMORQ *hRq); +char *ImoRq_ResetRPC(IMORQ *hRq); +char *ImoRq_Reui_Session(IMORQ *hRq); +char *ImoRq_Echo(IMORQ *hRq); +char *ImoRq_HTTPGet(IMORQ *hRq, char *pszURL, unsigned int *pdwLength); +#endif diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.c b/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.c new file mode 100644 index 0000000000..f2bca4d7b8 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.c @@ -0,0 +1,707 @@ +/* Module: imo_skype.c + Purpose: Communication layer for imo.im Skype + Author: leecher + Date: 30.08.2009 +*/ +#include +#include +#include +#include "imo_request.h" +#include "imo_skype.h" + +#ifdef _WIN64 +#pragma comment (lib, "bufferoverflowU.lib") +#endif + +#define PROTO "prpl-skype" + +struct _tagIMOSKYPE +{ + IMORQ *hRq; + IMORQ *hPoll; + char *pszUser; + IMOSTATCB StatusCb; + char *pszLastRes; + void *pUser; + int request_id; +}; + +static int CheckReturn (IMOSKYPE *hSkype, char *pszMsg, char *pszExpected); +static int ManageBuddy(IMOSKYPE *hSkype, char *pszAction, char *pszBuddy, char *pszGroup); + +// ----------------------------------------------------------------------------- +// Interface +// ----------------------------------------------------------------------------- + +IMOSKYPE *ImoSkype_Init(IMOSTATCB StatusCb, void *pUser) +{ + IMOSKYPE *hSkype = calloc(1, sizeof(IMOSKYPE)); + + if (!hSkype) return NULL; + if (!(hSkype->hRq = ImoRq_Init()) || !(hSkype->hPoll = ImoRq_Clone(hSkype->hRq))) + { + ImoSkype_Exit(hSkype); + return NULL; + } + hSkype->StatusCb = StatusCb; + hSkype->pUser = pUser; + return hSkype; +} + +// ----------------------------------------------------------------------------- + +void ImoSkype_Exit(IMOSKYPE *hSkype) +{ + if (!hSkype) return; + if (hSkype->hRq) ImoRq_Exit(hSkype->hRq); + if (hSkype->hPoll) ImoRq_Exit(hSkype->hPoll); + if (hSkype->pszUser) free(hSkype->pszUser); + free (hSkype); +} + +// ----------------------------------------------------------------------------- + +void ImoSkype_CancelPolling(IMOSKYPE *hSkype) +{ + if (hSkype->hPoll) + ImoRq_Cancel(hSkype->hPoll); +} + +// ----------------------------------------------------------------------------- + +char *ImoSkype_GetLastError(IMOSKYPE *hSkype) +{ + char *pszRet = ImoRq_GetLastError(hSkype->hRq); + + if (!pszRet || !*pszRet) return hSkype->pszLastRes; + return pszRet; +} + +// ----------------------------------------------------------------------------- + +char *ImoSkype_GetUserHandle(IMOSKYPE *hSkype) +{ + return hSkype->pszUser; +} + +// ----------------------------------------------------------------------------- + +// -1 - Error +// 0 - Login failed +// 1 - Login successful +int ImoSkype_Login(IMOSKYPE *hSkype, char *pszUser, char *pszPass) +{ + cJSON *root; + char *pszRet; + int iRet = -1; + + if (!hSkype) return 0; + if (IMO_API_VERSION == 0) + { + if (!(root=cJSON_CreateObject())) return 0; + cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); + if (pszRet = ImoRq_PostToSys(hSkype->hRq, "cookie_login", "session", root, 1, NULL)) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + } + + if (!(root=cJSON_CreateObject())) return 0; + if (hSkype->pszUser) free (hSkype->pszUser); + cJSON_AddStringToObject(root, "uid", hSkype->pszUser = strdup(pszUser)); + cJSON_AddStringToObject(root, "proto", PROTO); + cJSON_AddStringToObject(root, "passwd", pszPass); + cJSON_AddNullToObject(root, "captcha"); // Uh-oh, thay may get annoying in the future! :( + cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); + if (pszRet = ImoRq_PostAmy(hSkype->hRq, "account_login", root)) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + cJSON_Delete(root); + + return iRet; +} + +// ----------------------------------------------------------------------------- + +// -1 - Error +// 0 - Logout failed +// 1 - Logout successful +int ImoSkype_Logout(IMOSKYPE *hSkype) +{ + cJSON *root; + char *pszRet; + int iRet = -1; + + if (!hSkype || !(root=cJSON_CreateObject())) return 0; + cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); + if (pszRet = ImoRq_PostToSys(hSkype->hRq, "signoff_all", "session", root, 1, NULL)) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + return iRet; +} + +// ----------------------------------------------------------------------------- + +// -1 - Error +// 0 - Received unknown answer +// 1 - Got back information, called notification callback +// 2 - Received PING [deprecated] +int ImoSkype_Poll(IMOSKYPE *hSkype) +{ + char *pszRet; + + if (!hSkype || !hSkype->hPoll) return 0; + pszRet = ImoRq_PostSystem(hSkype->hPoll, "forward_to_server", NULL, NULL, NULL, 1); + if (!pszRet) return -1; + return CheckReturn (hSkype, pszRet, "ping"); +} + +// ----------------------------------------------------------------------------- + +int ImoSkype_KeepAlive(IMOSKYPE *hSkype) +{ + char *pszRet; + + /* In case we want to receive Promo-Infos... + { + cJSON *edata = cJSON_CreateObject(), *root; + + root=cJSON_CreateObject(); + cJSON_AddStringToObject(edata, "kind", "web"); + cJSON_AddNumberToObject(edata, "quantity", 1); + cJSON_AddItemToObject(root, "edata", edata); + if (pszRet = ImoRq_PostToSys(hSkype->hRq, "get_promos", "promo", root, 1)) + CheckReturn(hSkype, pszRet, "ok"); + } + */ + + if (!hSkype) return 0; + pszRet = ImoRq_UserActivity(hSkype->hPoll); + if (!pszRet) return -1; + return CheckReturn (hSkype, pszRet, "ok"); +} + +// ----------------------------------------------------------------------------- + +// pszStatus: +// Valid states: +// typing +// typed +// not_typing +// +// -1 - Error +// 0 - Typing notification failed +// 1 - Typing notification successful +int ImoSkype_Typing(IMOSKYPE *hSkype, char *pszBuddy, char *pszStatus) +{ + cJSON *root; + char *pszRet; + int iRet = -1; + + if (!hSkype || !hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; + cJSON_AddStringToObject(root, "uid", hSkype->pszUser); + cJSON_AddStringToObject(root, "proto", PROTO); + cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); + cJSON_AddStringToObject(root, "buid", pszBuddy); + cJSON_AddStringToObject(root, "typing_state", pszStatus); + if (pszRet = ImoRq_PostAmy(hSkype->hRq, "im_typing", root)) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + cJSON_Delete(root); + return iRet; +} + +// ----------------------------------------------------------------------------- + +// -1 - Error +// 0 - Sending failed +// 1 - Send pending +int ImoSkype_SendMessage(IMOSKYPE *hSkype, char *pszBuddy, char *pszMessage, int *prequest_id) +{ + cJSON *root; + char *pszRet; + int iRet = -1; + + if (!hSkype || !hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; + cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); + cJSON_AddStringToObject(root, "uid", hSkype->pszUser); + cJSON_AddStringToObject(root, "proto", PROTO); + cJSON_AddStringToObject(root, "buid", pszBuddy); + cJSON_AddStringToObject(root, "msg", pszMessage); + if (pszRet = (IMO_API_VERSION==0?ImoRq_PostAmy(hSkype->hRq, "send_im", root):ImoRq_PostToSys (hSkype->hRq, "send_im", "im", root, 0, &hSkype->request_id))) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + if (prequest_id) *prequest_id = hSkype->request_id; + hSkype->request_id++; + cJSON_Delete(root); + return iRet; +} + +// ----------------------------------------------------------------------------- + +// pszStatus: +// Valid states: +// available +// away +// busy +// invisible +// +// -1 - Error +// 0 - Failed +// 1 - OK +int ImoSkype_SetStatus(IMOSKYPE *hSkype, char *pszStatus, char *pszStatusMsg) +{ + cJSON *root; + char *pszRet; + int iRet = -1; + + /* + if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; + cJSON_AddStringToObject(root, "uid", hSkype->pszUser); + cJSON_AddStringToObject(root, "proto", PROTO); + cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); + cJSON_AddStringToObject(root, "ad", ""); + cJSON_AddStringToObject(root, "primitive", pszStatus); + cJSON_AddStringToObject(root, "status", pszStatusMsg); + if (pszRet = ImoRq_PostAmy(hSkype->hRq, "set_status", root)) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + */ + + if (!hSkype || !hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; + cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); + cJSON_AddStringToObject(root, "ad", ""); + cJSON_AddStringToObject(root, "primitive", pszStatus); + cJSON_AddStringToObject(root, "status", pszStatusMsg); + cJSON_AddFalseToObject (root, "auto_away"); + if (pszRet = ImoRq_PostToSys(hSkype->hRq, "set_status", "session", root, 0, NULL)) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + + cJSON_Delete(root); + return iRet; +} + +// ----------------------------------------------------------------------------- + +// -1 - Error +// 0 - Failed +// 1 - OK +int ImoSkype_AddBuddy(IMOSKYPE *hSkype, char *pszBuddy) +{ + return ManageBuddy (hSkype, "add_buddy", pszBuddy, "Offline"); +} + +// ----------------------------------------------------------------------------- + +// pszGroup = "Offline" if the user if offline, otherwise "Skype" or "Buddies" +// -1 - Error +// 0 - Failed +// 1 - OK +int ImoSkype_DelBuddy(IMOSKYPE *hSkype, char *pszBuddy, char *pszGroup) +{ + int iRet = ManageBuddy (hSkype, "del_buddy", pszBuddy, pszGroup); + + if (iRet<1 && strcmp(pszGroup, "Skype")==0) + return ManageBuddy (hSkype, "del_buddy", pszBuddy, "Buddies"); + return iRet; +} +// ----------------------------------------------------------------------------- + +int ImoSkype_BlockBuddy(IMOSKYPE *hSkype, char *pszBuddy) +{ + return ManageBuddy (hSkype, "block_buddy", pszBuddy, NULL); +} + +// ----------------------------------------------------------------------------- + +int ImoSkype_UnblockBuddy(IMOSKYPE *hSkype, char *pszBuddy) +{ + return ManageBuddy (hSkype, "unblock_buddy", pszBuddy, NULL); +} + +// ----------------------------------------------------------------------------- + +int ImoSkype_ChangeAlias(IMOSKYPE *hSkype, char *pszBuddy, char *pszNewAlias) +{ + cJSON *root; + char *pszRet; + int iRet = -1; + + if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; + cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); + cJSON_AddStringToObject(root, "uid", hSkype->pszUser); + cJSON_AddStringToObject(root, "proto", PROTO); + cJSON_AddStringToObject(root, "buid", pszBuddy); + cJSON_AddStringToObject(root, "alias", pszNewAlias); + if (pszRet = ImoRq_PostAmy(hSkype->hRq, "change_buddy_alias", root)) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + cJSON_Delete(root); + return iRet; +} + +// ----------------------------------------------------------------------------- + +int ImoSkype_StartVoiceCall(IMOSKYPE *hSkype, char *pszBuddy) +{ + cJSON *root; + char *pszRet; + int iRet = -1; + + if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; + cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); + cJSON_AddStringToObject(root, "uid", hSkype->pszUser); + cJSON_AddStringToObject(root, "proto", PROTO); + cJSON_AddStringToObject(root, "buid", pszBuddy); + if (pszRet = ImoRq_PostToSys (hSkype->hRq, "start_audio_chat", "av", root, 1, NULL)) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + return iRet; +} + +// ----------------------------------------------------------------------------- + +int ImoSkype_Ping(IMOSKYPE *hSkype) +{ + char *pszRet; + int iRet = -1; + + if (pszRet = ImoRq_Echo(hSkype->hRq)) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + return iRet; +} + +// ----------------------------------------------------------------------------- + +char *ImoSkype_GetAvatar(IMOSKYPE *hSkype, char *pszID, unsigned int *pdwLength) +{ + char szURL[256]; + + sprintf (szURL, "%sb/%s", ImoRq_GetHost(hSkype->hRq), pszID); + return ImoRq_HTTPGet (hSkype->hRq, szURL, pdwLength); +} + +// ----------------------------------------------------------------------------- + +int ImoSkype_GetUnreadMsgs(IMOSKYPE *hSkype) +{ + cJSON *root; + char *pszRet; + int iRet = -1; + + if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; + cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); + cJSON_AddStringToObject(root, "uid", hSkype->pszUser); + cJSON_AddStringToObject(root, "proto", PROTO); + if (pszRet = ImoRq_PostAmy(hSkype->hRq, "get_unread_msgs", root)) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + cJSON_Delete(root); + return iRet; +} + +// ----------------------------------------------------------------------------- + +int ImoSkype_GetAlpha(IMOSKYPE *hSkype) +{ + cJSON *root; + char *pszRet; + int iRet = -1; + + if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; + cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); + cJSON_AddStringToObject(root, "uid", hSkype->pszUser); + cJSON_AddStringToObject(root, "proto", PROTO); + if (pszRet = ImoRq_PostToSys (hSkype->hRq, "get_alpha_for_user", "alpha", root, 1, NULL)) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + return iRet; +} + +// ----------------------------------------------------------------------------- + + +int ImoSkype_CreateSharedGroup(IMOSKYPE *hSkype, char *pszName) +{ + cJSON *root; + char *pszRet; + int iRet = -1; + + if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; + cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); + cJSON_AddStringToObject(root, "uid", hSkype->pszUser); + cJSON_AddStringToObject(root, "proto", PROTO); + cJSON_AddFalseToObject(root, "is_native"); // TRUE would be great, but not yet supported? + cJSON_AddStringToObject(root, "name", pszName); + if (pszRet = ImoRq_PostAmy(hSkype->hRq, "create_shared_group", root)) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + cJSON_Delete(root); + return iRet; +} + +// ----------------------------------------------------------------------------- + +int ImoSkype_GroupInvite(IMOSKYPE *hSkype, char *pszGroup, char *pszUser) +{ + cJSON *root; + char *pszRet, *p, *pszGroupDup = strdup(pszGroup); + int iRet = -1; + + if (p=strrchr(pszGroupDup, ';')) *p=0; + if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; + cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); + cJSON_AddStringToObject(root, "uid", hSkype->pszUser); + cJSON_AddStringToObject(root, "proto", PROTO); + cJSON_AddStringToObject(root, "gid", pszGroupDup); + cJSON_AddStringToObject(root, "iproto", PROTO); + cJSON_AddStringToObject(root, "iuid", hSkype->pszUser); + cJSON_AddStringToObject(root, "ibuid", pszUser); + if (pszRet = ImoRq_PostAmy(hSkype->hRq, "invite_to_group", root)) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + free (pszGroupDup); + cJSON_Delete(root); + return iRet; +} + +// ----------------------------------------------------------------------------- + +int ImoSkype_GroupKick(IMOSKYPE *hSkype, char *pszGroup, char *pszUser) +{ + cJSON *root; + char *pszRet, *p, *pszGroupDup = strdup(pszGroup), szBUID[256]; + int iRet = -1; + + if (p=strrchr(pszGroupDup, ';')) *p=0; + sprintf (szBUID, "%s;%s;"PROTO, pszGroupDup, pszUser); + if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; + cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); + cJSON_AddStringToObject(root, "uid", hSkype->pszUser); + cJSON_AddStringToObject(root, "proto", PROTO); + cJSON_AddStringToObject(root, "buid", szBUID); + if (pszRet = ImoRq_PostAmy(hSkype->hRq, "kick_member", root)) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + free (pszGroupDup); + cJSON_Delete(root); + return iRet; +} + +// ----------------------------------------------------------------------------- + +int ImoSkype_GroupTopic(IMOSKYPE *hSkype, char *pszGroup, char *pszTopic) +{ + cJSON *root; + char *pszRet, *p, *pszGroupDup = strdup(pszGroup); + int iRet = -1; + + if (p=strrchr(pszGroupDup, ';')) *p=0; + if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; + cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); + cJSON_AddStringToObject(root, "uid", hSkype->pszUser); + cJSON_AddStringToObject(root, "proto", PROTO); + cJSON_AddStringToObject(root, "gid", pszGroupDup); + cJSON_AddStringToObject(root, "topic", pszTopic); + if (pszRet = ImoRq_PostAmy(hSkype->hRq, "set_group_topic", root)) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + free (pszGroupDup); + cJSON_Delete(root); + return iRet; +} + +// ----------------------------------------------------------------------------- + +int ImoSkype_GroupLeave(IMOSKYPE *hSkype, char *pszGroup) +{ + cJSON *root; + char *pszRet, *p, *pszGroupDup = strdup(pszGroup); + int iRet = -1; + + if (p=strrchr(pszGroupDup, ';')) *p=0; + if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; + cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); + cJSON_AddStringToObject(root, "uid", hSkype->pszUser); + cJSON_AddStringToObject(root, "proto", PROTO); + cJSON_AddStringToObject(root, "gid", pszGroupDup); + if (pszRet = ImoRq_PostAmy(hSkype->hRq, "leave_group", root)) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + free (pszGroupDup); + cJSON_Delete(root); + return iRet; +} + +// ----------------------------------------------------------------------------- +// Static +// ----------------------------------------------------------------------------- +static void PostDisconnect(IMOSKYPE *hSkype) +{ + cJSON *arr, *root; + + if (arr = cJSON_CreateArray()) + { + if (!(root=cJSON_CreateObject())) return; + cJSON_AddStringToObject(root, "name", "disconnect"); + cJSON_AddItemToArray (arr, root); + hSkype->StatusCb(arr, hSkype->pUser); + cJSON_Delete(arr); + } +} + +// 0 - Unexpected answer +// 1 - Got back JSON data, notified callback +// 2 - Received expected message pszExpected [deprecated] +static int CheckReturn (IMOSKYPE *hSkype, char *pszMsg, char *pszExpected) +{ + cJSON *root, *data, *msgs, *msg, *sys, *arr, *prefs, *pref; + char *pszMethod, *pszSys; + + hSkype->pszLastRes = pszMsg; + if (root = cJSON_Parse(pszMsg)) + { + // Now let's see if this one is interesting for our system + if ((data = cJSON_GetObjectItem(root,"method")) && + (pszMethod = data->valuestring) && + strcmp(pszMethod, "forward_to_client") == 0 && + (data = cJSON_GetObjectItem(root,"data")) && + (msgs = cJSON_GetObjectItem(data,"messages"))) + { + int i, iCount = cJSON_GetArraySize(msgs); + + if (!iCount && pszExpected && strcmp(pszExpected, "ok") == 0) + { + if ((sys = cJSON_GetObjectItem(data,"ack")) && (unsigned long)sys->valueint >= ImoRq_GetSeq(hSkype->hRq)) + return 2; // imoim ACKnowledged this + else + { + if (sys && sys->valueint==0) + { + // ACK error, reset to 0, better reset the connection + PostDisconnect(hSkype); + } + return 0; // No ACK, sequence number not incremented :( + } + } + for (i=0; ivaluestring) && + strcmp (pszSys, "client") == 0) + { + if (sys = cJSON_GetObjectItem(msg,"seq")) + { + ImoRq_UpdateAck(hSkype->hRq, sys->valueint+1); + ImoRq_UpdateAck(hSkype->hPoll, sys->valueint+1); + } + + // Callback is only called for system IM + if ((sys = cJSON_GetObjectItem(msg,"from")) && + (pszSys = cJSON_GetObjectItem(sys, "system")->valuestring)) + { + if ((strcmp (pszSys, "im") == 0 || strcmp (pszSys, "av") == 0) && + (data = cJSON_GetObjectItem(msg,"data")) && + (arr = cJSON_CreateArray())) + { + // Pack data into array for Callback backwards + // compatibility + cJSON *next; + + next = data->next; + data->next = NULL; + cJSON_AddItemToArray (arr, data); + hSkype->StatusCb(arr, hSkype->pUser); + data->next = next; + free(arr); + } + else if (strcmp (pszSys, "internal") == 0 && + (data = cJSON_GetObjectItem(msg,"data")) && + (arr = cJSON_CreateArray())) + { + // Pack ACK msgs into a fake "ack" method so that callback + // function can dispatch them without interface change + cJSON *next; + + cJSON_AddStringToObject (data, "name", "ack"); + next = data->next; + data->next = NULL; + cJSON_AddItemToArray (arr, data); + hSkype->StatusCb(arr, hSkype->pUser); + data->next = next; + free(arr); + } + // Ensure to disable annoying autoaway + else if (strcmp (pszSys, "preference") == 0 && + (data = cJSON_GetObjectItem(msg,"data")) && + (prefs = cJSON_GetObjectItem(data, "preferences"))) + { + int j, nPrefs = cJSON_GetArraySize(prefs); + cJSON *kind, *thispref, *value, *prefdata; + + for (j=0; jvaluestring, "impref") == 0 && + (thispref = cJSON_GetObjectItem(pref, "pref")) && + strcmp (thispref->valuestring, "auto_away") == 0 && + (value = cJSON_GetObjectItem(pref, "value")) && + value->type == cJSON_True && hSkype->pszUser && + (prefdata = cJSON_CreateObject())) + { + cJSON *accs, *acc, *setprefs, *newpref; + + if (accs = cJSON_CreateArray()) + { + if (acc = cJSON_CreateObject()) + { + cJSON_AddStringToObject(acc, "uid", hSkype->pszUser); + cJSON_AddStringToObject(acc, "proto", PROTO); + cJSON_AddItemToArray (accs, acc); + } + cJSON_AddItemToObject(prefdata, "accounts", accs); + } + if (setprefs = cJSON_CreateArray()) + { + if (newpref = cJSON_CreateObject()) + { + cJSON_AddStringToObject(newpref, "kind", kind->valuestring); + cJSON_AddStringToObject(newpref, "pref", thispref->valuestring); + cJSON_AddFalseToObject (newpref, "value"); + cJSON_AddItemToArray (setprefs, newpref); + } + cJSON_AddItemToObject(prefdata, "preferences", setprefs); + } + ImoRq_PostToSys (hSkype->hRq, "set", "preference", prefdata, 1, NULL); + } + } + } + else if (strcmp (pszSys, "reset") == 0) + { + // System requested to reset connection + // Let's issue a "disconnect" to the callback to let it handle + // this situation + } + } + } + } + } + } + cJSON_Delete(root); + return 1; + } + else + { + if (pszExpected && strcmp(pszMsg, pszExpected)==0) + return 2; + } + return 0; +} + +// ----------------------------------------------------------------------------- + +static int ManageBuddy(IMOSKYPE *hSkype, char *pszAction, char *pszBuddy, char *pszGroup) +{ + cJSON *root; + char *pszRet; + int iRet = -1; + + if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0; + cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq)); + cJSON_AddStringToObject(root, "uid", hSkype->pszUser); + cJSON_AddStringToObject(root, "proto", PROTO); + cJSON_AddStringToObject(root, "buid", pszBuddy); + if (pszGroup) cJSON_AddStringToObject(root, "group", pszGroup); + if (pszRet = ImoRq_PostAmy(hSkype->hRq, pszAction, root)) + iRet = CheckReturn(hSkype, pszRet, "ok")>0; + cJSON_Delete(root); + return iRet; +} diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.h b/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.h new file mode 100644 index 0000000000..d9e1697ed6 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.h @@ -0,0 +1,37 @@ +#include "cJSON.h" + +struct _tagIMOSKYPE; +typedef struct _tagIMOSKYPE IMOSKYPE; +// 0 - Message received, you may delete the cJSON object now +// 1 - Don't delete cJSON object, callback will take care of freeing +typedef int(*IMOSTATCB)(cJSON *pMsg, void *pUser); + +IMOSKYPE *ImoSkype_Init(IMOSTATCB StatusCb, void *pUser); +void ImoSkype_Exit(IMOSKYPE *hSkype); +void ImoSkype_CancelPolling(IMOSKYPE *hSkype); +char *ImoSkype_GetLastError(IMOSKYPE *hSkype); +char *ImoSkype_GetUserHandle(IMOSKYPE *hSkype); + +int ImoSkype_Login(IMOSKYPE *hSkype, char *pszUser, char *pszPass); +int ImoSkype_Logout(IMOSKYPE *hSkype); +int ImoSkype_Poll(IMOSKYPE *hSkype); +int ImoSkype_Typing(IMOSKYPE *hSkype, char *pszBuddy, char *pszStatus); +int ImoSkype_SetStatus(IMOSKYPE *hSkype, char *pszStatus, char *pszStatusMsg); +int ImoSkype_SendMessage(IMOSKYPE *hSkype, char *pszBuddy, char *pszMessage, int *prequest_id); +int ImoSkype_AddBuddy(IMOSKYPE *hSkype, char *pszBuddy); +int ImoSkype_DelBuddy(IMOSKYPE *hSkype, char *pszBuddy, char *pszGroup); +int ImoSkype_BlockBuddy(IMOSKYPE *hSkype, char *pszBuddy); +int ImoSkype_UnblockBuddy(IMOSKYPE *hSkype, char *pszBuddy); +int ImoSkype_ChangeAlias(IMOSKYPE *hSkype, char *pszBuddy, char *pszNewAlias); +int ImoSkype_StartVoiceCall(IMOSKYPE *hSkype, char *pszBuddy); +int ImoSkype_KeepAlive(IMOSKYPE *hSkype); +int ImoSkype_Ping(IMOSKYPE *hSkype); +char *ImoSkype_GetAvatar(IMOSKYPE *hSkype, char *pszID, unsigned int *pdwLength); +int ImoSkype_GetUnreadMsgs(IMOSKYPE *hSkype); +int ImoSkype_GetAlpha(IMOSKYPE *hSkype); + +int ImoSkype_CreateSharedGroup(IMOSKYPE *hSkype, char *pszName); +int ImoSkype_GroupInvite(IMOSKYPE *hSkype, char *pszGroup, char *pszUser); +int ImoSkype_GroupKick(IMOSKYPE *hSkype, char *pszGroup, char *pszUser); +int ImoSkype_GroupTopic(IMOSKYPE *hSkype, char *pszGroup, char *pszTopic); +int ImoSkype_GroupLeave(IMOSKYPE *hSkype, char *pszGroup); diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer.c b/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer.c new file mode 100644 index 0000000000..1e18464682 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer.c @@ -0,0 +1,175 @@ +/* Module: io_layer.c + Purpose: IO Layer for Internet communication using libcurl + Author: leecher + Date: 30.08.2009 +*/ +#include +#include +#include +#include +#include "fifo.h" +#include "io_layer.h" + +typedef struct +{ + IOLAYER vtbl; + CURL *hCurl; + TYP_FIFO *hResult; + char szErrorBuf[CURL_ERROR_SIZE+1]; +} IOLAYER_INST; + +static void IoLayer_Exit (IOLAYER *hPIO); +static char *IoLayer_Post(IOLAYER *hPIO, char *pszUrl, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength); +static char *IoLayer_Get(IOLAYER *hPIO, char *pszUrl, unsigned int *pdwLength); +static void IoLayer_Cancel(IOLAYER *hIO); +static char *IoLayer_GetLastError(IOLAYER *hIO); +static char *IoLayer_EscapeString(IOLAYER *hIO, char *pszData); +static void IoLayer_FreeEscapeString(char *pszData); +static size_t add_data(char *data, size_t size, size_t nmemb, void *ctx); + +// ----------------------------------------------------------------------------- +// Interface +// ----------------------------------------------------------------------------- + +IOLAYER *IoLayerCURL_Init(void) +{ + IOLAYER_INST *hIO; + + if (!(hIO = calloc(1, sizeof(IOLAYER_INST)))) + return NULL; + + if (!(hIO->hCurl = curl_easy_init())) + { + free (hIO); + return NULL; + } + + if (!(hIO->hResult = Fifo_Init(1024))) + { + IoLayer_Exit((IOLAYER*)hIO); + return NULL; + } + + curl_easy_setopt(hIO->hCurl, CURLOPT_USERAGENT, "XMLHttpRequest/1.0"); + curl_easy_setopt(hIO->hCurl, CURLOPT_HEADER, 0); + curl_easy_setopt(hIO->hCurl, CURLOPT_AUTOREFERER, 1); +// curl_easy_setopt(hRq->hCurl, CURLOPT_RETURNTRANSFER, 1); + curl_easy_setopt(hIO->hCurl, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(hIO->hCurl, CURLOPT_SSL_VERIFYHOST, 0); + curl_easy_setopt(hIO->hCurl, CURLOPT_ERRORBUFFER, hIO->szErrorBuf); + curl_easy_setopt(hIO->hCurl, CURLOPT_COOKIEFILE, "cookies.txt"); + curl_easy_setopt(hIO->hCurl, CURLOPT_COOKIEJAR, "cookies.txt"); + curl_easy_setopt(hIO->hCurl, CURLOPT_WRITEFUNCTION, add_data); + curl_easy_setopt(hIO->hCurl, CURLOPT_FILE, hIO); + + // Init Vtbl + hIO->vtbl.Exit = IoLayer_Exit; + hIO->vtbl.Post = IoLayer_Post; + hIO->vtbl.Get = IoLayer_Get; + hIO->vtbl.Cancel = IoLayer_Cancel; + hIO->vtbl.GetLastError = IoLayer_GetLastError; + hIO->vtbl.EscapeString = IoLayer_EscapeString; + hIO->vtbl.FreeEscapeString = IoLayer_FreeEscapeString; + + return (IOLAYER*)hIO; +} + +// ----------------------------------------------------------------------------- + +static void IoLayer_Exit (IOLAYER *hPIO) +{ + IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; + + if (hIO->hCurl) curl_easy_cleanup(hIO->hCurl); + if (hIO->hResult) Fifo_Exit(hIO->hResult); + free (hIO); +} + +// ----------------------------------------------------------------------------- + +static char *IoLayer_Post(IOLAYER *hPIO, char *pszUrl, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength) +{ + IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; + + curl_easy_setopt(hIO->hCurl, CURLOPT_POST, 1); + curl_easy_setopt(hIO->hCurl, CURLOPT_URL, pszUrl); + curl_easy_setopt(hIO->hCurl, CURLOPT_POSTFIELDS, pszPostFields); + curl_easy_setopt(hIO->hCurl, CURLOPT_POSTFIELDSIZE, cbPostFields); + if (curl_easy_perform(hIO->hCurl)) return NULL; + if (!pdwLength) + { + // Get string + Fifo_Add (hIO->hResult, "", 1); + return Fifo_Get (hIO->hResult, NULL); + } + else + { + // Get binary, return size of buffer + *pdwLength = (unsigned int)-1; + return Fifo_Get (hIO->hResult, pdwLength); + } +} + +// ----------------------------------------------------------------------------- + +static char *IoLayer_Get(IOLAYER *hPIO, char *pszUrl, unsigned int *pdwLength) +{ + IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; + + curl_easy_setopt(hIO->hCurl, CURLOPT_POST, 0); + curl_easy_setopt(hIO->hCurl, CURLOPT_URL, pszUrl); + if (curl_easy_perform(hIO->hCurl)) return NULL; + if (!pdwLength) + { + // Get string + Fifo_Add (hIO->hResult, "", 1); + return Fifo_Get (hIO->hResult, NULL); + } + else + { + // Get binary, return size of buffer + *pdwLength = (unsigned int)-1; + return Fifo_Get (hIO->hResult, pdwLength); + } +} + +// ----------------------------------------------------------------------------- + +static void IoLayer_Cancel(IOLAYER *hIO) +{ + // FIXME: Currently not implemented +} + +// ----------------------------------------------------------------------------- + +static char *IoLayer_GetLastError(IOLAYER *hIO) +{ + return ((IOLAYER_INST*)hIO)->szErrorBuf; +} + +// ----------------------------------------------------------------------------- + +static char *IoLayer_EscapeString(IOLAYER *hIO, char *pszData) +{ + return curl_easy_escape(((IOLAYER_INST*)hIO)->hCurl, pszData, 0); +} + +// ----------------------------------------------------------------------------- + +static void IoLayer_FreeEscapeString(char *pszData) +{ + curl_free(pszData); +} + +// ----------------------------------------------------------------------------- +// Static +// ----------------------------------------------------------------------------- + +static size_t add_data(char *data, size_t size, size_t nmemb, void *ctx) +{ + IOLAYER_INST *hIO = (IOLAYER_INST*)ctx; + + if (Fifo_Add(hIO->hResult, data, size * nmemb)) return size * nmemb; + return 0; +} + diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer.h b/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer.h new file mode 100644 index 0000000000..13e10cf888 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer.h @@ -0,0 +1,25 @@ +#ifndef _IOLAYER_H_ +#define _IOLAYER_H_ + +struct _tagIOLAYER; +typedef struct _tagIOLAYER IOLAYER; + +struct _tagIOLAYER +{ + void (*Exit) (IOLAYER *hIO); + + char *(*Post) (IOLAYER *hIO, char *pszURL, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength); + char *(*Get) (IOLAYER *hIO, char *pszURL, unsigned int *pdwLength); + void (*Cancel) (IOLAYER *hIO); + char *(*GetLastError) (IOLAYER *hIO); + char *(*EscapeString) (IOLAYER *hIO, char *pszData); + void (*FreeEscapeString) (char *pszData); +}; + +#ifdef WIN32 +IOLAYER *IoLayerW32_Init(void); +IOLAYER *IoLayerNETLIB_Init(void); +#endif +IOLAYER *IoLayerCURL_Init(void); + +#endif diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer_win32.c b/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer_win32.c new file mode 100644 index 0000000000..1fd425ced7 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer_win32.c @@ -0,0 +1,440 @@ +/* Module: io_layer_win32.c + Purpose: IO Layer for Internet communication using WININET (Win32) + Author: leecher + Date: 30.08.2009 +*/ +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include "fifo.h" +#include "io_layer.h" + +#ifndef LongToPtr +#define DWORD_PTR DWORD +#endif + +/* Set this to use asynchronous I/O + This is needed as synchronous WININET functions tend to block forever on connection + loss or other occasions leading to a deadlock of the whole application + */ +#define ASYNC +#define ASYNC_CONN_TIMEOUT 5000 // Connection timeout in ms +#define ASYNC_REQ_TIMEOUT 40000 // HttpSendRequest timeout in ms in async mode (Should be at least 30 sec!) + +#pragma comment(lib,"wininet.lib") + +#define INET_FLAGS INTERNET_FLAG_IGNORE_CERT_CN_INVALID | INTERNET_FLAG_IGNORE_CERT_DATE_INVALID | \ + INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_UI | \ + INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_SECURE + +typedef struct +{ + IOLAYER vtbl; + HINTERNET hInet; + HINTERNET hRequest; +#ifdef ASYNC + INTERNET_ASYNC_RESULT stAsyncRes; + HANDLE hConnectedEvent; + HANDLE hRequestCompleteEvent; +#endif + TYP_FIFO *hResult; + LPVOID lpErrorBuf; +} IOLAYER_INST; + +static void IoLayer_Exit (IOLAYER *hPIO); +static char *IoLayer_Post(IOLAYER *hPIO, char *pszURL, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength); +static char *IoLayer_Get(IOLAYER *hIO, char *pszURL, unsigned int *pdwLength); +static void IoLayer_Cancel(IOLAYER *hIO); +static char *IoLayer_GetLastError(IOLAYER *hIO); +static char *IoLayer_EscapeString(IOLAYER *hPIO, char *pszData); +static void IoLayer_FreeEscapeString(char *pszData); +static void FetchLastError (IOLAYER_INST *hIO); +#ifdef ASYNC +static void __stdcall Callback(HINTERNET hInternet, DWORD dwContext, DWORD dwInternetStatus, + LPVOID lpStatusInfo, DWORD dwStatusInfoLen); +#endif + +// ----------------------------------------------------------------------------- +// Interface +// ----------------------------------------------------------------------------- + +IOLAYER *IoLayerW32_Init(void) +{ + IOLAYER_INST *hIO; + + if (!(hIO = calloc(1, sizeof(IOLAYER_INST)))) + return NULL; + + // Init Inet + if (!(hIO->hInet = InternetOpen ("Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13", + INTERNET_OPEN_TYPE_PRECONFIG, NULL, "", +#ifdef ASYNC + INTERNET_FLAG_ASYNC +#else + 0 +#endif + ))) + { + free (hIO); + return NULL; + } + + if (!(hIO->hResult = Fifo_Init(1024))) + { + IoLayer_Exit((IOLAYER*)hIO); + return NULL; + } + +#ifdef ASYNC + if (InternetSetStatusCallback(hIO->hInet, (INTERNET_STATUS_CALLBACK)&Callback) == INTERNET_INVALID_STATUS_CALLBACK) + { + IoLayer_Exit((IOLAYER*)hIO); + return NULL; + } + + hIO->hConnectedEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + hIO->hRequestCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL); +#endif + + //InternetSetCookie ("https://o.imo.im/", "proto", "prpl-skype"); + + // Init Vtbl + hIO->vtbl.Exit = IoLayer_Exit; + hIO->vtbl.Post = IoLayer_Post; + hIO->vtbl.Get = IoLayer_Get; + hIO->vtbl.Cancel = IoLayer_Cancel; + hIO->vtbl.GetLastError = IoLayer_GetLastError; + hIO->vtbl.EscapeString = IoLayer_EscapeString; + hIO->vtbl.FreeEscapeString = IoLayer_FreeEscapeString; + + return (IOLAYER*)hIO; +} +// ----------------------------------------------------------------------------- + +static void IoLayer_Exit (IOLAYER *hPIO) +{ + IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; + + if (hIO->hInet) InternetCloseHandle (hIO->hInet); + if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf); + if (hIO->hResult) Fifo_Exit(hIO->hResult); + +#ifdef ASYNC + if (hIO->hConnectedEvent) CloseHandle (hIO->hConnectedEvent); + if (hIO->hRequestCompleteEvent) CloseHandle (hIO->hRequestCompleteEvent); +#endif + free (hIO); +} + +// ----------------------------------------------------------------------------- + +static char *IoLayer_Post(IOLAYER *hPIO, char *pszURL, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength) +{ + IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; + URL_COMPONENTS urlInfo = {0}; + HINTERNET hUrl; + DWORD dwFlags = 0, cbFlags = sizeof(dwFlags), dwRemaining = 0; + char szHostName[INTERNET_MAX_HOST_NAME_LENGTH], + szURLPath[INTERNET_MAX_URL_LENGTH], *p; +#ifdef ASYNC + INTERNET_BUFFERS InetBuff={0}; + InetBuff.dwStructSize = sizeof(InetBuff); + + ResetEvent (hIO->hConnectedEvent); + ResetEvent (hIO->hRequestCompleteEvent); +#endif + +//OutputDebugString(pszPostFields); + urlInfo.dwStructSize = sizeof (URL_COMPONENTS); + urlInfo.lpszHostName = szHostName; + urlInfo.dwHostNameLength = sizeof(szHostName); + urlInfo.lpszUrlPath = szURLPath; + urlInfo.dwUrlPathLength = sizeof(szURLPath); + if (!InternetCrackUrl(pszURL, strlen(pszURL), 0, &urlInfo)) return NULL; + /* + if (!pszPostFields) + { + if (pszPostFields=strchr (pszURL, '?')) + cbPostFields = strlen(pszPostFields); + } + */ + if (!(hUrl = InternetConnect (hIO->hInet, szHostName, + INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)hIO))) + { +#ifdef ASYNC + if (GetLastError() == ERROR_IO_PENDING) + { + if (WaitForSingleObject(hIO->hConnectedEvent, ASYNC_CONN_TIMEOUT) == WAIT_OBJECT_0) + { + hUrl = (HINTERNET)hIO->stAsyncRes.dwResult; + hIO->stAsyncRes.dwResult = 0; + SetLastError(hIO->stAsyncRes.dwError); + } + } + if (!hUrl) +#endif + { + FetchLastError (hIO); + return NULL; + } + } + + hIO->hRequest = HttpOpenRequest (hUrl, pszPostFields?"POST":"GET", szURLPath, NULL, "https://imo.im/", NULL, + INET_FLAGS, (DWORD_PTR)hIO); + if (!hIO->hRequest) + { +#ifdef ASYNC + if (GetLastError() == ERROR_IO_PENDING) + { + if (WaitForSingleObject(hIO->hConnectedEvent, ASYNC_CONN_TIMEOUT) == WAIT_OBJECT_0) + { + hIO->hRequest = (HINTERNET)hIO->stAsyncRes.dwResult; + hIO->stAsyncRes.dwResult = 0; + SetLastError(hIO->stAsyncRes.dwError); + } + } + if (!hUrl) +#endif + { + FetchLastError (hIO); + InternetCloseHandle (hUrl); + return NULL; + } + } + + InternetQueryOption (hIO->hRequest, INTERNET_OPTION_SECURITY_FLAGS, (LPVOID)&dwFlags, &cbFlags); + dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA; + InternetSetOption (hIO->hRequest, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags)); + + /* + { + char szCookies[4096]; + DWORD cbCookies, dwIndex=0; + + OutputDebugString ("Sending headers:\n"); + do + { + cbCookies=sizeof(szCookies); + if (!HttpQueryInfo (hIO->hRequest, HTTP_QUERY_FLAG_REQUEST_HEADERS|HTTP_QUERY_RAW_HEADERS_CRLF, szCookies, &cbCookies, &dwIndex) || + GetLastError() != ERROR_SUCCESS) + break; + OutputDebugString (szCookies); + } while (1); + } + */ + +// ASYNC: This needs to block for at least 30 seconds on poll! + if (!(HttpSendRequest (hIO->hRequest, "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n" + "X-Requested-With: XMLHttpRequest", -1, + pszPostFields, cbPostFields))) + { +#ifdef ASYNC + BOOL bRes = FALSE; + + if (GetLastError() == ERROR_IO_PENDING) + { + if (WaitForSingleObject(hIO->hRequestCompleteEvent, ASYNC_REQ_TIMEOUT) == WAIT_OBJECT_0) + { + bRes = hIO->stAsyncRes.dwResult; + hIO->stAsyncRes.dwResult = 0; + SetLastError(hIO->stAsyncRes.dwError); + } + } + if (!bRes) +#endif + { + FetchLastError (hIO); + InternetCloseHandle (hIO->hRequest); + hIO->hRequest = NULL; + InternetCloseHandle (hUrl); + return NULL; + } + } +#ifdef ASYNC + else WaitForSingleObject(hIO->hRequestCompleteEvent, ASYNC_REQ_TIMEOUT); +#endif + + /* + { + char szCookies[4096]; + DWORD cbCookies, dwIndex=0; + + OutputDebugString ("Received headers:\n"); + do + { + cbCookies=sizeof(szCookies); + if (!HttpQueryInfo (hIO->hRequest, HTTP_QUERY_FLAG_REQUEST_HEADERS|HTTP_QUERY_RAW_HEADERS_CRLF, szCookies, &cbCookies, &dwIndex) || + GetLastError() != ERROR_SUCCESS) + break; + OutputDebugString (szCookies); + } while (1); + } + */ + +#ifdef ASYNC + do + { + if (!InternetQueryDataAvailable (hIO->hRequest, &InetBuff.dwBufferLength, 0, 0)) + { + BOOL bRes = FALSE; + + if (GetLastError() == ERROR_IO_PENDING) + { + if (WaitForSingleObject(hIO->hRequestCompleteEvent, ASYNC_REQ_TIMEOUT) == WAIT_OBJECT_0) + { + bRes = hIO->stAsyncRes.dwResult; + hIO->stAsyncRes.dwResult = 0; + SetLastError(hIO->stAsyncRes.dwError); + } + } + if (!bRes) break; + } + if (InetBuff.dwBufferLength == 0) break; + if (InetBuff.lpvBuffer = Fifo_AllocBuffer (hIO->hResult, InetBuff.dwBufferLength)) + { + if (!InternetReadFileEx (hIO->hRequest, &InetBuff, 0, (DWORD_PTR)hIO)) + { + BOOL bRes=FALSE; + + if (GetLastError() == ERROR_IO_PENDING) + { + if (WaitForSingleObject(hIO->hRequestCompleteEvent, ASYNC_REQ_TIMEOUT) == WAIT_OBJECT_0) + { + bRes = hIO->stAsyncRes.dwResult; + hIO->stAsyncRes.dwResult = 0; + SetLastError(hIO->stAsyncRes.dwError); + } + } + if (!bRes) break; + } + } + } + while(InetBuff.dwBufferLength); +#else + while (InternetQueryDataAvailable (hIO->hRequest, &dwRemaining, 0, 0) && dwRemaining > 0) + { + if (p = Fifo_AllocBuffer (hIO->hResult, dwRemaining)) + InternetReadFile (hIO->hRequest, p, dwRemaining, &dwRemaining); + } +#endif + + if (!pdwLength) + { + // Get string + Fifo_Add (hIO->hResult, "", 1); + p = Fifo_Get (hIO->hResult, NULL); + } + else + { + // Get binary, return size of buffer + *pdwLength = (unsigned int)-1; + p = Fifo_Get (hIO->hResult, pdwLength); + } + InternetCloseHandle (hIO->hRequest); + hIO->hRequest = NULL; + InternetCloseHandle (hUrl); +OutputDebugString(p); +OutputDebugString("\n"); + return p; +} + +// ----------------------------------------------------------------------------- + +static char *IoLayer_Get(IOLAYER *hIO, char *pszURL, unsigned int *pdwLength) +{ + return IoLayer_Post (hIO, pszURL, NULL, 0, pdwLength); +} + +// ----------------------------------------------------------------------------- + +static void IoLayer_Cancel(IOLAYER *hPIO) +{ + IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; + +#ifdef ASYNC + if (hIO->hRequest) + { + hIO->stAsyncRes.dwResult = 0; + hIO->stAsyncRes.dwError = ERROR_CANCELLED; + SetEvent(hIO->hRequestCompleteEvent); + } +#else + if (hIO->hRequest && InternetCloseHandle(hIO->hRequest)) + hIO->hRequest = NULL; +#endif +} + +// ----------------------------------------------------------------------------- + +static char *IoLayer_GetLastError(IOLAYER *hIO) +{ + return (char*)((IOLAYER_INST*)hIO)->lpErrorBuf; +} + +// ----------------------------------------------------------------------------- + +static char *IoLayer_EscapeString(IOLAYER *hPIO, char *pszData) +{ + IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO; + TYP_FIFO *hFifo; + char szBuf[8], *pszRet; + unsigned char *p; + + if (!(hFifo = Fifo_Init(strlen(pszData)))) return NULL; + for (p=pszData; *p; p++) + { + if (isalnum(*p)) Fifo_Add (hFifo, p, 1); + else { + wsprintf (szBuf, "%%%02X", *p); + Fifo_Add (hFifo, szBuf, 3); + } + } + Fifo_Add (hFifo, "", 1); + if (pszRet = Fifo_Get(hFifo, NULL)) + pszRet = strdup(pszRet); + Fifo_Exit(hFifo); + return pszRet; +} + +// ----------------------------------------------------------------------------- + +static void IoLayer_FreeEscapeString(char *pszData) +{ + free (pszData); +} + +// ----------------------------------------------------------------------------- +// Static +// ----------------------------------------------------------------------------- + +static void FetchLastError (IOLAYER_INST *hIO) +{ + if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, + GetLastError(), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), + (LPTSTR)&hIO->lpErrorBuf, 0, NULL); +} + +#ifdef ASYNC +static void __stdcall Callback(HINTERNET hInternet, DWORD dwContext, DWORD dwInternetStatus, + LPVOID lpStatusInfo, DWORD dwStatusInfoLen) +{ + IOLAYER_INST *hIO = (IOLAYER_INST*)dwContext; + + + switch(dwInternetStatus) + { + case INTERNET_STATUS_HANDLE_CREATED: + SetEvent (hIO->hConnectedEvent); + break; + case INTERNET_STATUS_REQUEST_COMPLETE: + hIO->stAsyncRes = *((INTERNET_ASYNC_RESULT *)lpStatusInfo); + SetEvent(hIO->hRequestCompleteEvent); + break; + } +} +#endif \ No newline at end of file diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/skypetst.c b/plugins/!NotAdopted/IMO2sProxy/src/imolib/skypetst.c new file mode 100644 index 0000000000..5c80533eaf --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/skypetst.c @@ -0,0 +1,211 @@ +/* Module: skypetst.c + Purpose: Very simple and straight forward testing application for Skype imo.im service + Author: leecher + Date: 30.08.2009 +*/ + +#include +#include +#include +#include +#include +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#else +#include +#include +#endif +#include "imo_skype.h" + +static IMOSKYPE *m_hInst = NULL; + +// ----------------------------------------------------------------------------- +// Static +// ----------------------------------------------------------------------------- +static int StatusCallback (cJSON *pMsg, void *pUser) +{ + char *pszName; + cJSON *pContent = cJSON_GetArrayItem(pMsg, 0); + + if (!pContent) return; + pszName = cJSON_GetObjectItem(pContent,"name")->valuestring; + + if (!strcmp(pszName, "recv_im")) + { + // I got a message! + cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"); + + if (pEdata) + { + time_t timestamp = (time_t)cJSON_GetObjectItem(pEdata, "timestamp")->valueint; + char szTimestamp[32]; + + strftime (szTimestamp, sizeof(szTimestamp), "%d.%m.%Y %H.%M.%S", localtime(×tamp)); + printf ("[%s] %s: %s\n", szTimestamp, + cJSON_GetObjectItem(pEdata, "alias")->valuestring, + cJSON_GetObjectItem(pEdata, "msg")->valuestring); + } + } + else if (!strcmp(pszName, "signed_on")) + { + // I just signed on. + cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"); + char *pszAlias; + + if (pEdata && (pszAlias = cJSON_GetObjectItem(pEdata, "alias")->valuestring)) + { + printf ("My alias is: %s\n", pszAlias); + } + } + else if (!strcmp(pszName, "buddy_added") || !strcmp(pszName, "buddy_status")) + { + // Here comes the contact list + cJSON *pArray = cJSON_GetObjectItem(pContent,"edata"), *pItem; + int i, iCount; + + if (pArray) + { + for (i=0, iCount = cJSON_GetArraySize(pArray); ivaluestring, + cJSON_GetObjectItem(pItem, "buid")->valuestring, + cJSON_GetObjectItem(pItem, "primitive")->valuestring); + } + } + } + } + else + { + char *pszMsg = cJSON_Print(pMsg); + fprintf (stderr, "%s\n\n", pszMsg); + free (pszMsg); + } + + return 0; +} + +// ----------------------------------------------------------------------------- + +static void DispatcherThread(void *pDummy) +{ + while (1) + ImoSkype_Poll(m_hInst); +} + +// ----------------------------------------------------------------------------- + +#ifdef WIN32 +static HANDLE m_hThread; + +static int Dispatcher_Start(void) +{ + DWORD ThreadID; + + return (m_hThread=CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE)DispatcherThread, NULL, 0, &ThreadID))!=0; + +} + +static int Dispatcher_Stop(void) +{ + return TerminateThread (m_hThread, 0); +} + +#else +static pthread_t m_hThread; + +static int Dispatcher_Start(void) +{ + return pthread_create(&m_hThread, NULL, DispatcherThread, NULL)==0; +} + +static int Dispatcher_Stop(void) +{ + if (pthread_cancel(m_hThread)) + { + m_hThread=0; + return 1; + } + return 0; +} +#endif + +// ----------------------------------------------------------------------------- +// EIP +// ----------------------------------------------------------------------------- + +int main(int argc, char **argv) +{ + int iRet = -1; + + if (argc<3) + { + printf ("Usage: %s [username] [password]\n", argv[0]); + return -1; + } + + /* Logon */ + if (!(m_hInst = ImoSkype_Init(StatusCallback, NULL))) + { + fprintf (stderr, "Initializing failed.\n"); + return -1; + } + if (ImoSkype_Login(m_hInst, argv[1], argv[2]) == 1) + { + /* Dispatch loop */ + char szLine[4096]={0}; + + Dispatcher_Start(); + printf ("> "); + fflush(stdout); + while (gets(szLine)) + { + if (strcmp(szLine, "exit") == 0) break; + if (strcmp(szLine, "help") == 0) + { + printf ("msg [buddy] [message]\nstatus [available|away|busy|invisible] \nexit\n"); + } else + if (strncmp(szLine, "msg ", 4) == 0) + { + char *pszBuddy; + + if (pszBuddy = strtok (szLine+4, " ")) + { + if (ImoSkype_SendMessage(m_hInst, pszBuddy, pszBuddy+strlen(pszBuddy)+1)) + printf ("Sent.\n"); + else + printf ("Sending failed: %s.\n", ImoSkype_GetLastError(m_hInst)); + } + } else + if (strncmp(szLine, "status ", 7) == 0) + { + char *pszStatus; + + if (pszStatus = strtok (szLine+7, " ")) + { + if (ImoSkype_SetStatus(m_hInst, pszStatus, pszStatus+strlen(pszStatus)+1)) + printf ("Status set.\n"); + else + printf ("Setting status failed: %s.\n", ImoSkype_GetLastError(m_hInst)); + } + } + memset (szLine, 0, sizeof(szLine)); + printf ("> "); + fflush(stdout); + } + Dispatcher_Stop(); + ImoSkype_Logout(m_hInst); + } + else + { + fprintf (stderr, "Login failed: %s\n", ImoSkype_GetLastError(m_hInst)); + return -1; + } + + ImoSkype_Exit(m_hInst); + return iRet; +} diff --git a/plugins/!NotAdopted/IMO2sProxy/structure.txt b/plugins/!NotAdopted/IMO2sProxy/structure.txt new file mode 100644 index 0000000000..37de021e3a --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/structure.txt @@ -0,0 +1,102 @@ +The communication module is divided into multiple layers that +are replacable or usable on their own. +First let's start with a list of files and a short description: + ++----------------+---+-------------------------------------------------------+ +| Module | T | Description | ++----------------+---+-------------------------------------------------------+ +| fifo.c | M | A simple fifo (First In, First Out) buffer | +| memlist.c | M | A simple memory list module | +| io_layer.c | M | Communication layer for HTTP requests | +| io_layer_win32.| M | Communication layer WIN32 | +| imo_request.c | M | Posts XMLHHTP-Requests to imo.im server | +| cJSON.c | M | JSON parser in C (by Dave Gamble, slightly modified | +| imo_skype.c | M | Communication layer for imo.im Skype | +| skypetst.c | X | Testing application for Skype imo.im service | +| queue.c | M | General Queue functions | +| msgqueue.c | M | Message queue for incoming messages | +| callqueue.c | M | Queue of incoming calls | +| buddylist.c | M | Manages your list of buddies in memory | +| imo2skypeapi.c | M | Wrapper for imo.im Webservice to SKYPE API | +| imo2stest.c | X | Simple test application for imo2skypeapi | +| imo2sproxy.c | M | Skypeproxy implementation to wrap imo2skypeapi | +| w32browser.c | M | C COM Interface to Internet Explorer for call supp. | +| main.c | X | Commandline interface for imo2sproxy module | +| imoproxy.c | X | Miranda plugin implementation for imo2sproxy | +| skypepluginlink| M | Communication layer with Miranda Skype Plugin 0.0.0.46| +| socksproxy.c | M | Communication layer with socket protocol. | +| w32skypeemu.c | M | Communication layer via Win32 Skype API emulation | ++----------------+---+-------------------------------------------------------+ + [T]ype is: M...Module, X...Executable (Application) + + +Now here is the module list with their dependencies divided into layers: + +==================================================================== + IMO.IM Communication layer +==================================================================== + ++------------------------------------------------------------------+ +| io_layer.c | ++------------------------------------------------------------------+ +| Communication layer for HTTP requests | +| Depends on: fifo.c, Win32:WinInet, linux:libCURL | ++------------------------------------------------------------------+ + || + || + \/ ++------------------------------------------------------------------+ +| imo_request.c | ++------------------------------------------------------------------+ +| Communication module with imo.im | +| Depends on: fifo.c, cJSON.c, io_layer.c | ++------------------------------------------------------------------+ + || + || + \/ ++------------------------------------------------------------------+ +| imo_skype.c | ++------------------------------------------------------------------+ +| Description: Skype protocol layer for imo.im | +| Depends on: imo_request.c, cJSON.c | +| Test application: skypetst.c | ++------------------------------------------------------------------+ + || +==================================================================== + imo.im <--> SkypeAPI wrapper +==================================================================== + || + \/ ++------------------------------------------------------------------+ +| imo2skypeapi.c | ++------------------------------------------------------------------+ +| Description: Mapper for imo.im to simple implementation of | +| SkypeAPI | +| Depends on: fifo.c, memlist.c, buddylist.c, msgqueue.c, | +| imo_skype.c, (w32browser.c),(libpthread) | +| Test application: imo2stest.c | ++------------------------------------------------------------------+ + || + || + \/ ++------------------------------------------------------------------+ +| imo2sproxy.c | ++------------------------------------------------------------------+ +| Description: Skypeproxy implementation to wrap imo2skypeapi| +| for Miranda Plugin and potentially others | +| Depends on: memlist.c, imo2skypeapi.c, (libpthread) | ++------------------------------------------------------------------+ + || || + || || + \/ \/ ++-----------------------------------------++-----------------------------------------+ +| main.c || imoproxy.c | ++-----------------------------------------++-----------------------------------------+ +| Description: Commandline dispatcher || Description: Miranda IM Plugin | +| Depends on: memlist.c, imo2skypeapi.c, || Depends on: memlist.c, imo2skypeapi.c, | +| imo2sproxy.c, (libpthread) || imo2sproxy.c, (libpthread) | ++-----------------------------------------++-----------------------------------------+ + | | | + +-------------------+ | + | | | +Communication layer: socksproxy.c w32skypeemu.c skypepluginlink.c diff --git a/plugins/!NotAdopted/NotesAndReminders/NotesReminders.vcxproj b/plugins/!NotAdopted/NotesAndReminders/NotesReminders.vcxproj new file mode 100644 index 0000000000..d77a0f481c --- /dev/null +++ b/plugins/!NotAdopted/NotesAndReminders/NotesReminders.vcxproj @@ -0,0 +1,121 @@ +п»ї + + + + Debug + Win32 + + + Release + Win32 + + + + {EEB57129-946C-4B98-8856-FDA501AE2A5E} + NotesReminders + + + + DynamicLibrary + MultiByte + true + + + DynamicLibrary + MultiByte + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + true + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + EditAndContinue + Use + globals.h + EnableFastChecks + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + comctl32.lib;Gdi32.lib;winmm.lib;wsock32.lib;%(AdditionalDependencies) + true + 0x14310000 + false + $(IntDir)$(TargetName).lib + Windows + $(SolutionDir)\lib + + + + + Full + OnlyExplicitInline + Size + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + true + Level3 + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + Use + global.h + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + Gdi32.lib;comctl32.lib;winmm.lib;wsock32.lib;%(AdditionalDependencies) + true + 0x14310000 + false + $(IntDir)$(TargetName).lib + true + Windows + $(SolutionDir)\lib + true + + + + + + Create + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/!NotAdopted/NotesAndReminders/NotesReminders.vcxproj.filters b/plugins/!NotAdopted/NotesAndReminders/NotesReminders.vcxproj.filters new file mode 100644 index 0000000000..5eccb5444e --- /dev/null +++ b/plugins/!NotAdopted/NotesAndReminders/NotesReminders.vcxproj.filters @@ -0,0 +1,53 @@ +п»ї + + + + {0542c19a-ad49-4dd8-8643-47204fa16e58} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {1e7a703d-e0f4-42ff-9e78-49de3375d4a5} + h;hpp;hxx;hm;inl + + + {38ee8469-7af5-4130-90a1-f4e8c620f475} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/plugins/!NotAdopted/NotesAndReminders/docs/N&R - langpack.txt b/plugins/!NotAdopted/NotesAndReminders/docs/N&R - langpack.txt new file mode 100644 index 0000000000..ebb446c99b --- /dev/null +++ b/plugins/!NotAdopted/NotesAndReminders/docs/N&R - langpack.txt @@ -0,0 +1,169 @@ +Miranda Language Pack Version 1 +Language: English (EN) +Locale: 0409 +Last-Modified-Using: Miranda 0.9.2 +Authors: d00mEr, Joe @ Whale, Georg Fischer +Author-email: d00mEr@dir.bg, jokusoftware@gmail.com +Plugins-included: Notes & Reminders 0.0.5.0 + +[&Close] + +;Name In Options Page +;-------------------- +[Notes & Reminders] +[Plugins] +[Alerts] +[Reminder Notify] + +;Menu Strings +;------------ +[Notes && Reminders] +[&New Note] +[&Show / Hide Notes] +[Vie&w Notes] +[Delete &All Notes] +[New &Reminder] +[&View Reminders] +[D&elete All Reminders] +[&Bring All to Front] + +;Hotkeys +;------- +[Bring All Notes to Front] +[Toggle Notes Visibility] + +;Sounds +;------ +[Reminder triggered] +[Reminder triggered (Alternative 1)] +[Reminder triggered (Alternative 2)] + +;Confirmation and Message Dialogs +--------------------------------- +[Are you sure you want to delete all notes?] +[Are you sure you want to delete this note?] +[Are you sure you want to delete all reminders?] +[Are you sure you want to delete this reminder?] +[The specified time is invalid.] +[The specified time offset is invalid.] +[The specified time is invalid due to begin of daylight saving (summer time).] +[Miranda could not load the Note & Reminders plugin, RICHED20.DLL is missing. If you are using Windows 95 or WINE please make sure you have riched20.dll installed. Press 'Yes' to continue loading Miranda.] + +;Note Window Popup Menu +;---------------------- +[&Delete Note] +[&Hide Note] +[&Always On Top] +[Appearance] +[Background Color] +[Text Color] +[Font] +[Custom...] +[Reset] +[Paste Title] +[Reset Title] +[Undo] +[&Copy] +[&Paste] +[C&ut] +[C&lear] + +;Note Window Popup Menu Color Presets +------------------------------------- +[Black] +[Maroon] +[Green] +[Olive] +[Navy] +[Purple] +[Teal] +[Gray] +[Silver] +[Red] +[Orange] +[Lime] +[Yellow] +[Blue] +[Fuchsia] +[Aqua] +[White] + +;Notes List Dialog and Popup Menu +;----------------------------------- +[Notes] +[Date/Title] +[Note text] +[V] +[T] +[Edi&t Note] +[&Visible] +[Always &On Top] + +;New Reminder Dialog +;------------------- +[&Add Reminder] +[&Update Reminder] +[Add Reminder] +[Trigger On Time && Date:] +[Date] +[Time] +[Reminder Note:] +[Reoccurence] +[None] +[Daily] +[Weekly] +[Monthly] +[Minutes] +[Hours] +[Every] +[Seconds] +[Default] +[Alternative 1] +[Alternative 2] +[Never] +[None] + +;Reminder List Dialog and Popup Menu +;----------------------------------- +[Reminders] +[Date of activation] +[Reminder text] +[Add New] +[Edi&t Reminder] +[&Delete Reminder] + +;Reminder Notify Dialog +;---------------------- +[&Dismiss] +[&Remind Again] +[Reminder] +[min.] +[After:] +[On Time && Date:] +[Hour] +[Day] +[Days] +[Week] + +;Options Dialog +;-------------- +[Note Transparency (Minimum Win 2k/XP)] +[Default Note Size] +[Width (Pixels)] +[Height (Pixels)] +[Startup options] +[Reset to defaults] +[Hide notes at startup] +[Add Contact list menu items] +[(Requires Miranda restart)] +[Send Reminders through E-mail / SMS :] +[Open links with this program instead:] +[Select Executable] +[Show Scrollbar] +[Show Buttons] +[Title Date] +[Title Time] +[Reminder Options] +[Add Reminder closes dialog] +[Use MCI to play alert sounds] +[(Using MCI allows different sounds to be played simultaneously, may not be needed or desired when a custom sound plugin is installed.)] diff --git a/plugins/!NotAdopted/NotesAndReminders/docs/N&R - readme.txt b/plugins/!NotAdopted/NotesAndReminders/docs/N&R - readme.txt new file mode 100644 index 0000000000..30ced4b8f1 --- /dev/null +++ b/plugins/!NotAdopted/NotesAndReminders/docs/N&R - readme.txt @@ -0,0 +1,315 @@ +About +----- +New "Notes & Reminders" Plugin + +Version 0.0.5.0 +Updated by Georg Fischer for Miranda IM 0.9.2+ (may work on earlier versions +possibly down to 0.7.0 but not tested) and VS2008, based on code: + +by Joe @ Whale (Joe Kucera) jokusoftware@gmail.com +Originally by d00mEr (Lubomir Ivanov) d00mEr@dir.bg +for Miranda ICQ 0.1.2.1+ written with Visual C++ 6.0 IMPORTANT: When upgrading to 0.0.5.0 (from 0.0.4.5-), it's recommended to make a backup of the Miranda DB file, because the format for notes and reminder DB data has changed. Allthough the new version should be able to read the old format, the old plugin version will not be able to read the new format, in case you need to downgrade plugin version again. +Description +----------- +This plugin allows user to create Sticky Notes, to +store some important data in a well visible place :) +New features allow to create reminders. This is a +note that will show up on specified date and time. +The notes are completely customizable. + +Features +-------- ++ Sticky Notes (each Note is limited to 16000 chars) ++ Reminders (each Reminder Text is limited to 16000 chars) ++ Reminder time input displays a preset list with times. For the current date (if date is not + changed) it displays presets for 5, 10, 15, 30 minutes and then every full and half hour. When + the time input is in current date mode, you can also enter a delta time by first entering a +. + For example +5 would specify in 5 minutes, +1:15 would specify in 1 hour and 15 minutes. ++ Allow change of fonts and colors ++ Allow setting default size for Notes ++ Notes always stay on top of all windows (unless option is disabled) ++ Show and Hide all notes ++ Show or Hide notes at startup. ++ Bring all notes to front (for notes that are not on top and are hidden behind other windows). ++ Hot Keys for New Note, New Reminder, Show/Hide notes and Bring All Notes to Front ++ Manage Reminder list. ++ Manage Notes list. ++ Quick delete all notes and/or reminders ++ Transparent Notes (on Windows 2000 or newer) ++ Language translations (see langpack_N&R.txt for details) ++ Select between 3 custom sounds to play On Reminder ++ Reminder alert sound can optionally play repeatedly at specified interval until user responds + to alert (makes it less likely to miss important reminders) ++ Font Colors ++ Reminder notification via E-mail or SMS. + +To Do: +------ +- Verify langpack for changes and new features introduced in 0.0.5.0 +- User configurable icons through the Miranda icon configuration functionality +- Icons for : Fix/Move the note +- Text formatting support for notes +- "best fit" feature - by pressing one button I would adjust the size of the note automatically +- double clicking a note's title-bar scrolls up the note (to be just the title bar). +- import/export of all notes/alarms +- Reminder (daily, weekly or monthly) without a specified time? i.e. when you start miranda... +- Trigger on event (remind me when is user online) +- Unicode support (Use Japanese texts was garbled) +- Easier way to delete notes (like Ctrl-D or ctrl-shift-d) + +Installation +------------ +Just copy the dll into Miranda's plugin subdirectory. + +Translation +----------- +see N&R-langpack.txt for details + +License +------- +Copyright (C) 2002 Lubomir Ivanov +Copyright (C) 2005 Joe Kucera + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +For more information, e-mail jokusoftware@gmail.com + d00mEr@dir.bg + +Changes +------- +0.0.5.1 +------- +! BugFix: Notes window init issue that could result in scrollbar being shown when it shouldn't. +! BugFix: Notes window init issue that could result in scrollbar position not being restored correctly + for notes that are suposed to be scrolled to top ++ Feature: Option to specify a custom program to use when opening links in notes. By default links + are opened using the system default web browser. ++ Feature: Set custom font on individual notes. + +------- +0.0.5.0 +------- +* (Temporary) Developer: Georg Fischer, I just updated it to work properly with the latest Miranda + version and added some features and polish. I don't know if I'll do much more work aside from immediate + bug fixes, at least on any regular basis. +! BugFix: Custom frame drawing for notes to look nicer but also avoid issues especially with Aero. +! BugFix: Changed window type/parent for notes so that they don't show up on Windows alt-tab list + and other issues. +! BugFix: Cleaned up custom window drawing for notes windows, to hopefully work more solidly. +! BugFix: Fixed pasting into notes window, so it doesn't paste text formatting (as formatting + is not currently supported and would be lost next time Miranda starts). +! BugFix: Removed reminder reoccurrence dialog options, it would just confuse the user because + there is no support for that functionality in the code. +! BugFix: Time handling reworked, which hopefully also fixes reported issue with reminders triggering at + wrong time (an hour early or later). Special handling for daylight saving (summer time) begin + and end was also added, which in some cases could lead to some issues on old Windows versions + which have outdated being and end dates/times. +! BugFix: Potential crash bug with reminder list window and empty reminder note. +! BugFix: Transparency slider (in options) now uses correct direction, previously 100% transparent was + actually 100% Opaque. Also clamped the internal max value to avoid 100% transparent windows. +! BugFix: Creating note from a reminder could result in a crash or corrupted data if note was deleted + before the reminder. +! BugFix: A few other unlisted bug/issue fixes. ++ Change: Changed DB format to be more flexible and easily allow adding features in the future without + breaking existing notes and reminders. ++ Change: Changed "Show notes at startup" to "Hide notes at startup" because that better matches + actual behavior. ++ Change: Changed the default menu item order to have New Note and New Reminder first as they're the + most commonly used commands. ++ Optimization: changed list iterations in various placed to directly iterate linked lists instead + of using index based for-loops. ++ Optimization: reminder list sorted by trigger time, which reduces update function to a single + check 99.99+% of the time. ++ Feature: Hotkeys, fonts and colors now configurable through the common config interface. ++ Feature: Notes save/restore their current scroll position. ++ Feature: Notes title bar is configurable to select prefered date and time formats or disable them. ++ Feature: Buttons in notes title bar can be disabled (all functions are also available in the context menu). ++ Feature: Bring All Notes to Front command, brings all visible notes in front of other windows + (without changing the on-top state). ++ Feature: Tweaked notes window context menu and added a couple of commands. ++ Feature: Option to make "Add Reminder" button in New Reminder dialog close the dialog (previously + it was required to click Close after Add Reminder to get rid of the dialog). ++ Feature: Reminder alerts now generate a Miranda system event, meaning it will blink the tray icon + which the user has to click in order to open the reminder dialog. Previously the reminder + dialog opened automatically which could interfere with the application currently being used. ++ Feature: Delete confirmation dialogs for all notes and reminder delete actions, to avoid accidental + deletion. ++ Feature: Reworked reminder date and time input controls. In particularily the time edit control works + more like it did in ICQ aswell as allowing user to enter custom values. ++ Feature: Per-reminder option to have alert sound repeat (until reminder event is acknowledged by + clicking the tray icon). Repeat interval can be selected between 5 and 60 seconds. ++ Feature: Set custom background and text color on individual notes. ++ Feature: Set custom title/caption on individual notes. (max 63 characters) ++ Feature: Select between 3 sound presets or disable sound completely for individual reminders. ++ Feature: Edit/Update reminders. ++ Feature: Update reminder message in reminder notify dialog, so that the text can be updated + before chosing to remind again. ++ Feature: Notes list dialog. ++ Feature: Notes/Reminders list dialogs resizable with persistent window and column sizes. + +------- +0.0.4.5 +------- +* New Developer: Joe @ Whale, jokusoftware@gmail.com, I took over the development + of this great plug-in, got sources of 0.0.4.0 from original author (newer were + lost), hopfully managed to add features of succeeding versions. +! BugFix: Hopefully fixed all crash issues & memory leaks +! BugFix: Fixed random reminder issue ++ Optimisation: minimised use of memory alloc/free (much faster loading) ++ Feature: reminder sound now configurable thru default Skin/Sounds module (EVents/Sounds) + +------- +0.0.4.2 +------- +! BugFix: Reminder -> SMS Notify now works. ++ Option: Show vertical scrollbar in Notes. ++ Feature: Create Note from content of Reminder Notify. ++ Feature: Icons for Delete Note, Hide Note + +------- +0.0.4.1 +------- +! BugFix: URL in Note problem fixed +! Bugfix: Closing Reminder dialog will now mean "Remind me again" + You must press "Dismiss" to remove reminder +! BugFix: Strange behaviour to add reminders + 1 hour.. (Now uses Localtime) +! BugFix: Missing Langpack strings + +------- +0.0.4.0 +------- ++ Totaly revriten everything!!! Moved to Microsoft (R) Visual C ++ 6.0 ++ Added TopToolbar buttons for "New Reminder" and "New Note" ++ Notify via SMS to E-mail gateway (Only for Reminders) + +------- +0.0.3.1 +------- ++ Sorry, i've forgot to remove debug :( That's why the plugin crashes + Now i've removed it :) Also i've relocated plugin to new base addres, so + there must not be a crash on start or exit (btw if you use any other + Delphi plugins, please contact autor to relocate them to a different + base addres than standart $4000000, or there will be a crash !! + +0.0.3.0 +------- ++ Reocurrence of Reminders (Daily, Weekly, Monthly) ++ Fixed bug with crash :( + +0.0.2.8 +------- ++ Changed DB structure again (fixed bug with Notes & Reminders size greater + than 4096 bytes). Now every Note & Reminder are stored into separate DB + setting, but every Note or Reminder is still limited to 4000 bytes :( sorry + for that. It is recomended you to clear all notes & Reminders to avoid errors :) ++ Implemented Purge function to free unused Notes & Reminders data from DB :) ++ Removed 'Empty' sign when a Note or Reminder have no text :) ++ Is the "Reminder On Top" bug still there? It works fine for me ?!? :) + (I've tested on Win ME, 2K Pro & XP) + +0.0.2.7 +------- ++ Fixed bug with Reminders not showing on top of all windows + +0.0.2.6 +------- ++ "Remind me again in:" now includes any date and(or) time in the future, + not just (5,10,15...etc min.). ++ Changed Name in Options dialog. + +0.0.2.5 +------- ++ Togle On-Top with the pin icon (Icon reflects status) ++ Change Font effects & colors (For Caption & Note body) ++ A "View Reminders" button in the "Add Reminder" box. ++ Rearanged TAB order :) + +0.0.2.4 +------- ++ Custom Sound to play On Reminder + +0.0.2.3 +------- +[Warning!!! New Format of DB data! Incompatible with old versions] +[It is recomended to delete all Notes and Reminders ] + ++ Fixed bug - not showing corectly "Remind Again In :" Combo Box ++ Fixed bug - Trying to delete from empty list of reminders causes + error message. ++ Fixed bug - Problem when using Unicode characters ++ Other minor bug (or not bug) fixes :) + +0.0.2.2 +------- ++ Switched to Delphi 6 (smaller code) ++ There where so many feature requests for language translations :) + So i decided to implement this feature :) ++ I think finally fixed the on-top bug ?!? + +0.0.2.1 +------- ++ Fixed bug on 9X platforms (Didn't draw notes correct) :) Sorry, i forgot + to initialize length of an structure :) ++ Changed Name :) ++ Added transparency of Notes (Win 2K & XP) + +0.0.2.0 +------- ++ Reminder function implemented :) ++ Changed version to 2.0 :) + +0.0.1.6 +------- ++ Fixed structure in DB to store new features (Visible,On Top). + (Now DB Settings of plugin are incompatible with old versions, + so if you update , you will loose all notes). ++ Added Popup menu items for new features (Visible, On Top). ++ Minor changes in code to improve preformance. Smaller code :) + +0.0.1.5 +------- ++ Replaced Hot Keys with global Hot Keys. ++ Added option to change these Hot Keys. ++ Added Popup menu to Notes (Cut,Copy,Paste). ++ Added option to set default size of notes on create new. ++ Basic Implementation of reminders. + +0.0.1.4 +------- ++ Now saving Notes data on every change to avoid loosing notes if crash. ++ Fixed some bugs with window placement. ++ Added options for staying Always On Top. ++ Added Hot Keys to menu. + +0.0.1.3 +------- ++ Fixed bug with notes that have no text. ++ Added functions to Show/Hide Notes. ++ Added some icons :) + +0.0.1.2 +------- ++ Added Options dialog, to alow change of color and fonts for notes. + +0.0.1.1 +------- ++ Changed to save Notes data into Miranda database insted + of Windows registry. + +0.0.1.0 +------- ++ First release of this plugin. \ No newline at end of file diff --git a/plugins/!NotAdopted/NotesAndReminders/res/addremin.ico b/plugins/!NotAdopted/NotesAndReminders/res/addremin.ico new file mode 100644 index 0000000000..0264fd1716 Binary files /dev/null and b/plugins/!NotAdopted/NotesAndReminders/res/addremin.ico differ diff --git a/plugins/!NotAdopted/NotesAndReminders/res/bringfront.ico b/plugins/!NotAdopted/NotesAndReminders/res/bringfront.ico new file mode 100644 index 0000000000..11984568a8 Binary files /dev/null and b/plugins/!NotAdopted/NotesAndReminders/res/bringfront.ico differ diff --git a/plugins/!NotAdopted/NotesAndReminders/res/captioni.ico b/plugins/!NotAdopted/NotesAndReminders/res/captioni.ico new file mode 100644 index 0000000000..c7543c075f Binary files /dev/null and b/plugins/!NotAdopted/NotesAndReminders/res/captioni.ico differ diff --git a/plugins/!NotAdopted/NotesAndReminders/res/captionn.ico b/plugins/!NotAdopted/NotesAndReminders/res/captionn.ico new file mode 100644 index 0000000000..fd925f0660 Binary files /dev/null and b/plugins/!NotAdopted/NotesAndReminders/res/captionn.ico differ diff --git a/plugins/!NotAdopted/NotesAndReminders/res/deleteic.ico b/plugins/!NotAdopted/NotesAndReminders/res/deleteic.ico new file mode 100644 index 0000000000..5aa90434c1 Binary files /dev/null and b/plugins/!NotAdopted/NotesAndReminders/res/deleteic.ico differ diff --git a/plugins/!NotAdopted/NotesAndReminders/res/deletere.ico b/plugins/!NotAdopted/NotesAndReminders/res/deletere.ico new file mode 100644 index 0000000000..8560fc8f5e Binary files /dev/null and b/plugins/!NotAdopted/NotesAndReminders/res/deletere.ico differ diff --git a/plugins/!NotAdopted/NotesAndReminders/res/hidenote.ico b/plugins/!NotAdopted/NotesAndReminders/res/hidenote.ico new file mode 100644 index 0000000000..bada524874 Binary files /dev/null and b/plugins/!NotAdopted/NotesAndReminders/res/hidenote.ico differ diff --git a/plugins/!NotAdopted/NotesAndReminders/res/noteicon.ico b/plugins/!NotAdopted/NotesAndReminders/res/noteicon.ico new file mode 100644 index 0000000000..5479ed29e7 Binary files /dev/null and b/plugins/!NotAdopted/NotesAndReminders/res/noteicon.ico differ diff --git a/plugins/!NotAdopted/NotesAndReminders/res/playsound.ico b/plugins/!NotAdopted/NotesAndReminders/res/playsound.ico new file mode 100644 index 0000000000..0e3711dbc5 Binary files /dev/null and b/plugins/!NotAdopted/NotesAndReminders/res/playsound.ico differ diff --git a/plugins/!NotAdopted/NotesAndReminders/res/reminder.ico b/plugins/!NotAdopted/NotesAndReminders/res/reminder.ico new file mode 100644 index 0000000000..d3bed91d4d Binary files /dev/null and b/plugins/!NotAdopted/NotesAndReminders/res/reminder.ico differ diff --git a/plugins/!NotAdopted/NotesAndReminders/res/removeno.ico b/plugins/!NotAdopted/NotesAndReminders/res/removeno.ico new file mode 100644 index 0000000000..d2aae887a6 Binary files /dev/null and b/plugins/!NotAdopted/NotesAndReminders/res/removeno.ico differ diff --git a/plugins/!NotAdopted/NotesAndReminders/res/resource.rc b/plugins/!NotAdopted/NotesAndReminders/res/resource.rc new file mode 100644 index 0000000000..064efb6453 --- /dev/null +++ b/plugins/!NotAdopted/NotesAndReminders/res/resource.rc @@ -0,0 +1,362 @@ +// Microsoft Visual C++ generated resource script. +// +#include "..\src\resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "..\\src\\resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,0,5,1 + PRODUCTVERSION 0,0,5,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "Comments", "New ""Notes And Reminders"" plugin for Miranda IM" + VALUE "CompanyName", "Jokusoftware, Digital Forcess" + VALUE "FileDescription", "New ""Notes And Reminders""" + VALUE "FileVersion", "0.0.5.1" + VALUE "InternalName", "NewNotesAndReminders" + VALUE "LegalCopyright", "(C) 2003,2005 by Joe Kucera, Lubomir Ivanov" + VALUE "LegalTrademarks", "Digital Forcess" + VALUE "OriginalFilename", "NewNR.dll" + VALUE "ProductName", "New ""Notes And Reminders""" + VALUE "ProductVersion", "0.0.5.1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_STNOTEOPTIONS DIALOGEX 47, 55, 301, 254 +STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE | WS_CAPTION +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Sticky Notes Options" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + GROUPBOX "Default Note Size",IDC_STATIC,5,6,159,51 + LTEXT "Width (Pixels)",IDC_STATIC,12,20,44,8 + EDITTEXT 1012,70,20,62,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "Height (Pixels)",IDC_STATIC,12,41,46,8 + EDITTEXT 1013,70,39,62,12,ES_AUTOHSCROLL | ES_NUMBER + GROUPBOX "Notes Appearance",IDC_STATIC,5,61,159,72 + CONTROL "Show Scrollbars",1018,"Button",BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,12,77,67,10 + CONTROL "Show Buttons",1019,"Button",BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,88,77,64,10 + LTEXT "Title Date",IDC_STATIC,12,96,32,8 + COMBOBOX IDC_COMBODATE,53,95,92,149,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Title Time",IDC_STATIC,12,115,32,8 + COMBOBOX IDC_COMBOTIME,53,114,92,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Startup options",IDC_STATIC,179,6,116,56 + CONTROL "Hide notes at startup",1010,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | BS_FLAT | WS_TABSTOP,185,17,82,16 + CONTROL "Add Contact list menu items",1011,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | BS_FLAT | WS_TABSTOP,185,35,103,10 + CTEXT "(Requires Miranda restart)",IDC_STATIC,196,50,84,10 + GROUPBOX "Reminder options",IDC_STATIC,179,66,116,90 + CONTROL "Add Reminder closes dialog",1020,"Button",BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,185,81,103,10 + CONTROL "Use MCI to play alert sounds",1023,"Button",BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,185,96,106,10 + GROUPBOX "Note Transparency (Minimum Win 2k/XP)",IDC_STATIC,6,161,290,35 + CONTROL "Slider1",1014,"msctls_trackbar32",TBS_ENABLESELRANGE | WS_TABSTOP,8,171,283,14 + LTEXT "0%",IDC_STATIC,12,185,9,8 + LTEXT "100%",IDC_STATIC,276,186,18,8 + LTEXT "Send Reminders through E-mail / SMS :",IDC_STATIC,6,207,130,10 + EDITTEXT 1017,137,204,158,14,ES_AUTOHSCROLL + LTEXT "Open links with this program instead:",IDC_STATIC,5,228,125,8 + EDITTEXT IDC_EDIT_ALTBROWSER,138,225,140,14,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_BTN_BROWSEBROWSER,280,225,15,15 + PUSHBUTTON "Reset to defaults",1007,32,140,94,14 + CTEXT "(Using MCI allows different sounds to be played simultaneously, may not be needed or desired when a custom sound plugin is installed.)",IDC_STATIC,181,111,111,42 +END + +IDD_ADDREMINDER DIALOGEX 0, 0, 238, 199 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Add Reminder" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + GROUPBOX "Trigger On Time && Date:",1005,4,2,146,52 + LTEXT "Date",IDC_STATIC,10,18,24,8 + CONTROL "DateTimePicker1",1000,"SysDateTimePick32",DTS_LONGDATEFORMAT | WS_TABSTOP,38,16,107,13 + LTEXT "Time",IDC_STATIC,10,37,25,8 + COMBOBOX IDC_COMBOREMINDERTIME,38,35,107,198,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Reminder Note:",1006,4,58,230,99 + EDITTEXT 1004,9,70,220,81,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL + GROUPBOX "",IDC_STATIC,4,157,228,22,NOT WS_VISIBLE + CONTROL "None",1008,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_TABSTOP,13,167,45,8 + CONTROL "Daily",1009,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_TABSTOP,68,167,45,8 + CONTROL "Weekly",1010,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_TABSTOP,124,167,45,8 + CONTROL "Monthly",1011,"Button",BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_TABSTOP,178,167,45,8 + LTEXT "Repeat Alert Sound",IDC_STATIC,31,166,90,8,0,WS_EX_RIGHT + COMBOBOX IDC_COMBO_REPEATSND,126,163,107,81,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Use Sound",IDC_STATIC,31,185,90,8,0,WS_EX_RIGHT + COMBOBOX IDC_COMBO_SOUND,126,182,90,81,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "",IDC_BTN_PLAYSOUND,220,183,13,12,BS_ICON + DEFPUSHBUTTON "&Add Reminder",1002,158,6,76,14 + PUSHBUTTON "&Close",1003,158,23,76,14 + PUSHBUTTON "&View Reminders",1007,158,40,76,14 + LTEXT "reftime",IDC_REFTIME,0,191,22,8,NOT WS_VISIBLE | NOT WS_GROUP +END + +IDD_NOTIFYREMINDER DIALOGEX 0, 0, 240, 146 +STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Reminder" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + EDITTEXT 1000,3,4,233,80,ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL + CONTROL "After:",1004,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,11,90,32,10,WS_EX_TRANSPARENT + CONTROL "On Time && Date:",1005,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,51,90,65,10,WS_EX_TRANSPARENT + GROUPBOX "",-1,4,90,148,52 + COMBOBOX 1003,24,113,107,104,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + LTEXT "Date",IDC_STATIC_DATE,10,106,23,8 + CONTROL "DateTimePicker1",1006,"SysDateTimePick32",DTS_LONGDATEFORMAT | WS_TABSTOP,39,104,107,13 + LTEXT "Time",IDC_STATIC_TIME,10,125,24,8 + COMBOBOX 1007,39,123,107,198,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "&Remind Again",1002,161,92,75,14 + PUSHBUTTON "&Create Note",1008,161,111,75,14 + PUSHBUTTON "&Dismiss",1001,161,129,75,14 + LTEXT "reftime",IDC_REFTIME,0,137,22,8,NOT WS_VISIBLE | NOT WS_GROUP +END + +IDD_LISTREMINDERS DIALOGEX 0, 0, 258, 244 +STYLE DS_SETFONT | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Reminders" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + CONTROL "List1",1000,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,3,4,251,146 + EDITTEXT 1001,3,153,251,69,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL + PUSHBUTTON "Add New",1002,151,227,50,14 + DEFPUSHBUTTON "&Close",1003,203,227,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ADDREMINDER ICON "addremin.ico" +IDI_DELETEICON ICON "deleteic.ico" +IDI_NOTEICON ICON "noteicon.ico" +IDI_SHOWHIDE ICON "showhide.ico" +IDI_CAPTIONICON ICON "captioni.ico" +IDI_DELETEREMINDER ICON "deletere.ico" +IDI_VIEWREMINDERS ICON "viewremi.ico" +IDI_CAPTIONICONNOTTOP ICON "captionn.ico" +IDI_HIDENOTE ICON "hidenote.ico" +IDI_REMOVENOTE ICON "removeno.ico" +IDI_REMINDER ICON "reminder.ico" +IDI_BRINGFRONT ICON "bringfront.ico" +IDI_PLAYSOUND ICON "playsound.ico" +IDI_VIEWNOTES ICON "viewnotes.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +MNU_REMINDERPOPUP MENU +BEGIN + POPUP "Context Menu Reminder ListView" + BEGIN + MENUITEM "Edi&t Reminder", ID_CONTEXTMENUREMINDERLISTVIEW_EDIT + MENUITEM SEPARATOR + MENUITEM "New &Reminder", 40001 + MENUITEM "&Delete Reminder", 40002 + MENUITEM SEPARATOR + MENUITEM "D&elete All Reminders", 40003 + END +END + +MNU_NOTEPOPUP MENU +BEGIN + POPUP "Context Menu Note Popup" + BEGIN + MENUITEM "&Hide Note", 40002 + MENUITEM "&Always On Top", 40003 + MENUITEM "&New Note", ID_CONTEXTMENUNOTEPOPUP_NEWNOTE + MENUITEM "&Delete Note", 40001 + MENUITEM SEPARATOR + POPUP "Appearance" + BEGIN + POPUP "Background Color" + BEGIN + MENUITEM "Custom...", ID_APPEARANCE_CUSTOMBG + MENUITEM SEPARATOR + MENUITEM "Reset", ID_BACKGROUNDCOLOR_RESET + END + POPUP "Text Color" + BEGIN + MENUITEM "Custom...", ID_APPEARANCE_CUSTOMTEXT + MENUITEM SEPARATOR + MENUITEM "Reset", ID_TEXTCOLOR_RESET + END + POPUP "Font" + BEGIN + MENUITEM "Custom...", ID_APPEARANCE_CUSTOMFONT + MENUITEM SEPARATOR + MENUITEM "Reset", ID_FONT_RESET + END + END + MENUITEM "Paste Title", ID_CONTEXTMENUNOTEPOPUP_PASTETITLE + MENUITEM "Reset Title", ID_CONTEXTMENUNOTEPOPUP_RESETTITLE + MENUITEM SEPARATOR + MENUITEM "Undo", 40004 + MENUITEM SEPARATOR + MENUITEM "&Copy", 40005 + MENUITEM "&Paste", 40006 + MENUITEM "C&ut", 40007 + MENUITEM "C&lear", 40008 + MENUITEM SEPARATOR + MENUITEM "&View Notes", ID_CONTEXTMENUNOTEPOPUP_VIEWNOTES + MENUITEM "&Bring All To Front", ID_CONTEXTMENUNOTEPOPUP_BRINGALLTOTOP + END +END + +MNU_NOTELISTPOPUP MENU +BEGIN + POPUP "Context Menu Note ListView" + BEGIN + MENUITEM "Edi&t Note", ID_CONTEXTMENUNOTELISTVIEW_EDITNOTE + MENUITEM SEPARATOR + MENUITEM "&Visible", ID_CONTEXTMENUNOTELISTVIEW_TOGGLEVISIBILITY + MENUITEM "Always &On Top", 40003 + MENUITEM "&New Note", ID_CONTEXTMENUNOTEPOPUP_NEWNOTE + MENUITEM "&Delete Note", 40001 + MENUITEM SEPARATOR + MENUITEM "Delete &All Notes", ID_CONTEXTMENUNOTELISTVIEW_DELETEALLNOTES + MENUITEM SEPARATOR + MENUITEM "&Show / Hide Notes", ID_CONTEXTMENUNOTELISTVIEW_SHOW + MENUITEM "&Bring All To Front", ID_CONTEXTMENUNOTEPOPUP_BRINGALLTOTOP + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + "IDD_STNOTEOPTIONS", DIALOG + BEGIN + VERTGUIDE, 5 + VERTGUIDE, 12 + VERTGUIDE, 70 + VERTGUIDE, 88 + VERTGUIDE, 179 + VERTGUIDE, 185 + VERTGUIDE, 295 + BOTTOMMARGIN, 249 + HORZGUIDE, 6 + HORZGUIDE, 20 + END + + "IDD_ADDREMINDER", DIALOG + BEGIN + VERTGUIDE, 4 + END + + "IDD_NOTIFYREMINDER", DIALOG + BEGIN + VERTGUIDE, 161 + VERTGUIDE, 236 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/!NotAdopted/NotesAndReminders/res/showhide.ico b/plugins/!NotAdopted/NotesAndReminders/res/showhide.ico new file mode 100644 index 0000000000..99b241d4fb Binary files /dev/null and b/plugins/!NotAdopted/NotesAndReminders/res/showhide.ico differ diff --git a/plugins/!NotAdopted/NotesAndReminders/res/viewnotes.ico b/plugins/!NotAdopted/NotesAndReminders/res/viewnotes.ico new file mode 100644 index 0000000000..18057a372a Binary files /dev/null and b/plugins/!NotAdopted/NotesAndReminders/res/viewnotes.ico differ diff --git a/plugins/!NotAdopted/NotesAndReminders/res/viewremi.ico b/plugins/!NotAdopted/NotesAndReminders/res/viewremi.ico new file mode 100644 index 0000000000..b9e8bce9d5 Binary files /dev/null and b/plugins/!NotAdopted/NotesAndReminders/res/viewremi.ico differ diff --git a/plugins/!NotAdopted/NotesAndReminders/src/globals.h b/plugins/!NotAdopted/NotesAndReminders/src/globals.h new file mode 100644 index 0000000000..f8cc794e4a --- /dev/null +++ b/plugins/!NotAdopted/NotesAndReminders/src/globals.h @@ -0,0 +1,147 @@ +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "win2k.h" +#include "newpluginapi.h" +#include "m_system.h" +#include "m_database.h" +#include "m_clist.h" +#include "m_langpack.h" +#include "m_options.h" +#include "m_skin.h" +#include "m_fontservice.h" +#include "m_hotkeys.h" +#include "m_icolib.h" + +#include "m_toptoolbar.h" + +#include "miscutils.h" +#include "resource.h" + +// {842A6668-F9DA-4968-BFD7-D2BD9DF848EE} +#define MIID_NNR {0x842a6668, 0xf9da, 0x4968, {0xbf, 0xd7, 0xd2, 0xbd, 0x9d, 0xf8, 0x48, 0xee}} + +#define MODULENAME "StickyNotes" +#define SECTIONNAME "Notes & Reminders" + +// normal timer interval for reminder update processing +#define REMINDER_UPDATE_INTERVAL 10000 +// short timer interval for reminder updates used as long as there are pending alarams in the event queue +#define REMINDER_UPDATE_INTERVAL_SHORT 5000 + + +// font IDs used with LoadNRFont +#define NR_FONTID_CAPTION 0 +#define NR_FONTID_BODY 1 +#define NR_FONTID_MAX NR_FONTID_BODY + + +typedef struct { + HFONT hFont; + char size; + BYTE style; // see the DBFONTF_* flags + BYTE charset; + char szFace[LF_FACESIZE]; +} STICKYNOTEFONT; + +typedef struct { + HWND SNHwnd,REHwnd; + BOOL Visible,OnTop; + char *data; + ULARGE_INTEGER ID; // FILETIME in UTC + char *title; + BOOL CustomTitle; + DWORD BgColor; // custom bg color override (only valid if non-zero) + DWORD FgColor; // custom fg/text color override (only valid if non-zero) + STICKYNOTEFONT *pCustomFont;// custom (body) font override (NULL if default font is used) +} STICKYNOTE; + +typedef struct { + HWND handle; + BOOL RemVisible; + DWORD uid; + char *Reminder; + ULARGE_INTEGER When; // FILETIME in UTC + UINT RepeatSound; + UINT RepeatSoundTTL; + int SoundSel; // -1 if sound disabled + BOOL SystemEventQueued; +} REMINDERDATA; + + +extern void CreateMsgWindow(void); +extern void DestroyMsgWindow(void); + +extern STICKYNOTE* NewNote(int Ax,int Ay,int Aw,int Ah,char *Data, + ULARGE_INTEGER *ID,BOOL Visible,BOOL OnTop,int scrollV); +extern void LoadNotes(BOOL bIsStartup); +extern void SaveNotes(void); +extern void DeleteNotes(void); +extern void ShowHideNotes(void); +extern void ListNotes(void); + +extern void NewReminder(void); +extern void LoadReminders(void); +extern void SaveReminders(void); +extern void DeleteReminders(void); +extern void ListReminders(void); +extern BOOL CheckRemindersAndStart(void); + +extern void InitSettings(void); +extern void TermSettings(void); +extern int CALLBACK DlgProcOptions(HWND hdlg,UINT message, + WPARAM wParam,LPARAM lParam); +extern void LoadNRFont(int i, LOGFONT *lf, COLORREF *colour); + +extern BOOL WS_Init(); +extern void WS_CleanUp(); + +extern LPCSTR GetDateFormatStr(); +extern LPCSTR GetTimeFormatStr(); + +extern HINSTANCE hinstance; +extern HINSTANCE hmiranda; +extern PLUGINLINK *pluginLink; + +extern BOOL g_CloseAfterAddReminder, g_UseDefaultPlaySound; +extern HICON g_hReminderIcon; + +extern LOGFONT lfBody,lfCaption; +extern HFONT hBodyFont,hCaptionFont; + +extern long BodyColor; +extern long CaptionFontColor,BodyFontColor; + +extern BOOL g_ShowNotesAtStart,g_ShowScrollbar,g_AddContListMI,g_ShowNoteButtons; +extern int g_NoteTitleDate, g_NoteTitleTime; + +extern int g_NoteWidth,g_NoteHeight; + +extern int g_Transparency; + +extern char *g_RemindSMS; + +extern BOOL g_isWin2kPlus; + +extern TCHAR *g_lpszAltBrowser; + +extern int g_reminderListGeom[4]; +extern int g_reminderListColGeom[2]; +extern int g_notesListGeom[4]; +extern int g_notesListColGeom[4]; + +extern HWND HKHwnd; +extern HANDLE hIconLibItem[]; + +// these defs are only used to emphasize that SYSTEMTIMEtoFILETIME/FILETIMEtoSYSTEMTIME only convert the data type, +// it does not apply any time conversion/correction like UTC to local etc. (if input is local, then output is local too) +#define SYSTEMTIMEtoFILETIME SystemTimeToFileTime +#define FILETIMEtoSYSTEMTIME FileTimeToSystemTime diff --git a/plugins/!NotAdopted/NotesAndReminders/src/hotkeys.cpp b/plugins/!NotAdopted/NotesAndReminders/src/hotkeys.cpp new file mode 100644 index 0000000000..a8bd8d3c53 --- /dev/null +++ b/plugins/!NotAdopted/NotesAndReminders/src/hotkeys.cpp @@ -0,0 +1,137 @@ +#include "globals.h" + +#define MSG_WND_CLASS "MIM_SNMsgWindow" + + +HWND HKHwnd; + + +enum KB_ACTIONS {KB_NEW_NOTE = 1, KB_TOGGLE_NOTES, KB_NEW_REMINDER}; + + +void RegisterKeyBindings() +{ + HOTKEYDESC desc; + + ZeroMemory(&desc, sizeof(desc)); + desc.cbSize = sizeof(desc); + desc.pszSection = SECTIONNAME; + + desc.pszName = MODULENAME"/NewNote"; + desc.pszDescription = "New Note"; + desc.lParam = KB_NEW_NOTE; + desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, VK_INSERT); + desc.pszService = MODULENAME"/MenuCommandAddNew"; + Hotkey_Register(&desc); + + desc.pszName = MODULENAME"/ToggleNotesVis"; + desc.pszDescription = "Toggle Notes Visibility"; + desc.lParam = KB_TOGGLE_NOTES; + desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, VK_ADD); + desc.pszService = MODULENAME"/MenuCommandShowHide"; + Hotkey_Register(&desc); + + desc.pszName = MODULENAME"/BringNotesFront"; + desc.pszDescription = "Bring All Notes to Front"; + desc.lParam = KB_TOGGLE_NOTES; + desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, VK_HOME); + desc.pszService = MODULENAME"/MenuCommandBringAllFront"; + Hotkey_Register(&desc); + + desc.pszName = MODULENAME"/NewReminder"; + desc.pszDescription = "New Reminder"; + desc.lParam = KB_NEW_REMINDER; + desc.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT, VK_SUBTRACT); + desc.pszService = MODULENAME"/MenuCommandNewReminder"; + Hotkey_Register(&desc); +} + + +/*int HandleNRShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + STICKYNOTE* PSN; + + BOOL isShift = GetKeyState(VK_SHIFT) & 0x8000; + BOOL isAlt = GetKeyState(VK_MENU) & 0x8000; + BOOL isCtrl = (GetKeyState(VK_CONTROL) & 0x8000) && !isAlt; + + int action; + MSG amsg; + amsg.hwnd = hwnd; + amsg.message = msg; + amsg.wParam = wParam; + amsg.lParam = lParam; + + switch ( (action = CallService(MS_HOTKEY_CHECK, (WPARAM)&amsg, (LPARAM)SECTIONNAME)) ) + { + case KB_NEW_NOTE: + PSN = NewNote(0,0,0,0,NULL,NULL,TRUE,TRUE,0); + SetFocus(PSN->REHwnd); + return FALSE; + case KB_TOGGLE_NOTES: + ShowHideNotes(); + return FALSE; + case KB_NEW_REMINDER: + NewReminder(); + return FALSE; + } + + return -1; +}*/ + + +int CALLBACK NotifyHotKeyWndProc(HWND AHwnd,UINT Message,WPARAM wParam,LPARAM lParam) +{ + BOOL b; + + switch (Message) + { + case WM_TIMER: + { + KillTimer(HKHwnd,1026); + b = CheckRemindersAndStart(); + SetTimer(HKHwnd,1026,b ? REMINDER_UPDATE_INTERVAL_SHORT : REMINDER_UPDATE_INTERVAL,0); + + return FALSE; + } + } + + return DefWindowProc(AHwnd,Message,wParam,lParam); +} + +void CreateMsgWindow(void) +{ + HWND hParent = NULL; + WNDCLASSEX TWC = {0}; + + if (!GetClassInfoEx(hmiranda,MSG_WND_CLASS,&TWC)) + { + TWC.style = 0; + TWC.cbClsExtra = 0; + TWC.cbWndExtra = 0; + TWC.hInstance = hmiranda; + TWC.hIcon = 0; + TWC.hCursor = 0; + TWC.hbrBackground = 0; + TWC.lpszMenuName = NULL; + TWC.lpszClassName = MSG_WND_CLASS; + TWC.cbSize = sizeof(TWC); + TWC.lpfnWndProc = (WNDPROC)NotifyHotKeyWndProc; + RegisterClassEx(&TWC); + } + + if ( IsWinVer2000Plus() ) + { + // win2k+ has special message-only windows support + hParent = HWND_MESSAGE; + } + + HKHwnd = CreateWindowEx(WS_EX_TOOLWINDOW,MSG_WND_CLASS,_T("StickyNotes"),0,0,0,0,0,hParent,NULL,hmiranda,NULL); + SetTimer(HKHwnd,1026,REMINDER_UPDATE_INTERVAL,0); +} + +void DestroyMsgWindow(void) +{ + KillTimer(HKHwnd,1026); + DestroyWindow(HKHwnd); +} diff --git a/plugins/!NotAdopted/NotesAndReminders/src/main.cpp b/plugins/!NotAdopted/NotesAndReminders/src/main.cpp new file mode 100644 index 0000000000..2165a8e49b --- /dev/null +++ b/plugins/!NotAdopted/NotesAndReminders/src/main.cpp @@ -0,0 +1,389 @@ +#include "globals.h" + +HINSTANCE hinstance = NULL; +HINSTANCE hmiranda = NULL; +int hLangpack; + +HANDLE hkOptInit = NULL; +HANDLE hkTopToolbarInit = NULL; +HANDLE hkModulesLoaded = NULL; +HANDLE hkFontChange = NULL; +HANDLE hkColorChange = NULL; +HMODULE hUserDll = NULL; +HMODULE hRichedDll = NULL; +HMODULE hKernelDll = NULL; + +extern TREEELEMENT *g_Stickies; +extern TREEELEMENT *RemindersList; + +static PLUGININFOEX pluginInfo = +{ + sizeof(PLUGININFOEX), + "Sticky Notes & Reminders", + PLUGIN_MAKE_VERSION(0,0,5,1), + "Sticky Notes & Reminders Implementation for Miranda IM.", + "Joe Kucera, Lubomir Kolev Ivanov, Georg Fischer", + "jokusoftware@users.sourceforge.net; d00mEr@dir.bg", + "(C) 2003,2005 Joe Kucera, Lubomir Ivanov", + "http://d00mer.freeshell.org/miranda/", + UNICODE_AWARE, + MIID_NNR +}; + + +void RegisterFontServiceFonts(); +void RegisterKeyBindings(); +int OpenTriggeredReminder(WPARAM w, LPARAM l); +void BringAllNotesToFront(STICKYNOTE *pActive); +void CloseNotesList(); +void CloseReminderList(); + +int PluginMenuCommandAddNew(WPARAM w,LPARAM l) +{ + STICKYNOTE* PSN; + PSN = NewNote(0,0,0,0,NULL,NULL,TRUE,TRUE,0); + SetFocus(PSN->REHwnd); + return 0; +} + +int PluginMenuCommandDeleteAll(WPARAM w,LPARAM l) +{ + if (g_Stickies && MessageBox(NULL, Translate("Are you sure you want to delete all notes?"), SECTIONNAME, MB_OKCANCEL) == IDOK) + DeleteNotes(); + return 0; +} + +int PluginMenuCommandShowHide(WPARAM w,LPARAM l) +{ + ShowHideNotes(); + return 0; +} + +int PluginMenuCommandViewNotes(WPARAM w,LPARAM l) +{ + ListNotes(); + return 0; +} + +int PluginMenuCommandAllBringFront(WPARAM w,LPARAM l) +{ + BringAllNotesToFront(NULL); + return 0; +} + +int PluginMenuCommandNewReminder(WPARAM w,LPARAM l) +{ + NewReminder(); + return 0; +} + +int PluginMenuCommandViewReminders(WPARAM w,LPARAM l) +{ + ListReminders(); + return 0; +} + +int PluginMenuCommandDeleteReminders(WPARAM w,LPARAM l) +{ + if (RemindersList && MessageBox(NULL, Translate("Are you sure you want to delete all reminders?"), SECTIONNAME, MB_OKCANCEL) == IDOK) + DeleteReminders(); + return 0; +} + +struct +{ + char* szDescr; + char* szName; + int defIconID; +} +static const iconList[] = +{ + {"New Reminder", "AddReminder", IDI_ADDREMINDER}, + {"Delete All Notes", "DeleteIcon", IDI_DELETEICON}, + {"New Note", "NoteIcon", IDI_NOTEICON}, + {"Show/Hide Notes", "ShowHide", IDI_SHOWHIDE}, + {"On Top Caption Icon", "CaptionIcon", IDI_CAPTIONICON}, + {"Delete All Reminders", "DeleteReminder", IDI_DELETEREMINDER}, + {"View Reminders", "ViewReminders", IDI_VIEWREMINDERS}, + {"Not on Top Caption Icon", "CaptionIconNotTop", IDI_CAPTIONICONNOTTOP}, + {"Hide Note Icon", "HideNote", IDI_HIDENOTE}, + {"Remove Note Icon", "RemoveNote", IDI_REMOVENOTE}, + {"Reminder Icon", "Reminder", IDI_REMINDER}, + {"Bring All to Front", "BringFront", IDI_BRINGFRONT}, + {"Play Sound Icon", "PlaySound", IDI_PLAYSOUND}, + {"View Notes", "ViewNotes", IDI_VIEWNOTES}, + {"New Note", "NewNote", IDI_NOTEICON}, + {"New Reminder", "NewReminder", IDI_ADDREMINDER} +}; + +HANDLE hIconLibItem[SIZEOF(iconList)]; + +void InitIcons(void) +{ + int i; + char szSettingName[100]; + SKINICONDESC sid = {0}; + TCHAR szFile[MAX_PATH]; + + GetModuleFileName(hinstance, szFile, SIZEOF(szFile)); + + sid.cbSize = sizeof(SKINICONDESC); + sid.ptszDefaultFile = szFile; + sid.pszName = szSettingName; + sid.pszSection = MODULENAME; + sid.flags = SIDF_PATH_TCHAR; + + for (i = 0; i < SIZEOF(iconList); i++) + { + mir_snprintf(szSettingName, SIZEOF(szSettingName), "%s_%s", MODULENAME, iconList[i].szName); + + sid.pszDescription = iconList[i].szDescr; + sid.iDefaultIndex = -iconList[i].defIconID; + hIconLibItem[i] = Skin_AddIcon(&sid); + } +} + +int OnOptInitialise(WPARAM w, LPARAM L) +{ + OPTIONSDIALOGPAGE odp = {0}; + odp.cbSize = sizeof(odp); + odp.position = 900002000; + odp.hInstance = hinstance; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_STNOTEOPTIONS); + odp.pszTitle = _T(SECTIONNAME); + odp.pszGroup = _T("Plugins"); + odp.pfnDlgProc = DlgProcOptions; + Options_AddPage(w, &odp); + return 0; +} + +int OnTopToolBarInit(WPARAM w,LPARAM L) +{ + TTBButton ttb = {0}; + ttb.cbSize = sizeof(TTBButton); + ttb.dwFlags = TTBBF_VISIBLE | TTBBF_SHOWTOOLTIP; + + ttb.hIconHandleUp = hIconLibItem[14]; + ttb.pszService = MODULENAME"/MenuCommandAddNew"; + ttb.name = ttb.pszTooltipUp = LPGEN("Add New Note"); + TopToolbar_AddButton(&ttb); + + ttb.hIconHandleUp = hIconLibItem[15]; + ttb.pszService = MODULENAME"/MenuCommandNewReminder"; + ttb.name = ttb.pszTooltipUp = LPGEN("Add New Reminder"); + TopToolbar_AddButton(&ttb); + + UnhookEvent(hkTopToolbarInit); + return 0; +} + +static void InitServices() +{ + // register sounds + + SkinAddNewSoundEx("AlertReminder", "Alerts", "Reminder triggered"); + SkinAddNewSoundEx("AlertReminder2", "Alerts", "Reminder triggered (Alternative 1)"); + SkinAddNewSoundEx("AlertReminder3", "Alerts", "Reminder triggered (Alternative 2)"); + + // register menu command services + + CreateServiceFunction(MODULENAME"/MenuCommandAddNew",PluginMenuCommandAddNew); + CreateServiceFunction(MODULENAME"/MenuCommandShowHide",PluginMenuCommandShowHide); + CreateServiceFunction(MODULENAME"/MenuCommandViewNotes",PluginMenuCommandViewNotes); + CreateServiceFunction(MODULENAME"/MenuCommandDeleteAll",PluginMenuCommandDeleteAll); + CreateServiceFunction(MODULENAME"/MenuCommandBringAllFront",PluginMenuCommandAllBringFront); + + // + + CreateServiceFunction(MODULENAME"/MenuCommandNewReminder",PluginMenuCommandNewReminder); + CreateServiceFunction(MODULENAME"/MenuCommandViewReminders",PluginMenuCommandViewReminders); + CreateServiceFunction(MODULENAME"/MenuCommandDeleteReminders",PluginMenuCommandDeleteReminders); + + // register misc + + CreateServiceFunction(MODULENAME"/OpenTriggeredReminder",OpenTriggeredReminder); +} + +int OnModulesLoaded(WPARAM wparam,LPARAM lparam) +{ + CLISTMENUITEM cmi = {0}; + + // register fonts and hotkeys + + RegisterFontServiceFonts(); + RegisterKeyBindings(); + + // register menus + + cmi.cbSize = sizeof(cmi); + cmi.pszContactOwner = NULL; + cmi.pszPopupName = "Notes && Reminders"; + cmi.flags = CMIM_ICON | CMIF_ICONFROMICOLIB; + + cmi.position = 1600000000; + cmi.icolibItem = hIconLibItem[2]; + cmi.pszName = "New &Note"; + cmi.pszService = MODULENAME"/MenuCommandAddNew"; + if (g_AddContListMI) Menu_AddContactMenuItem(&cmi); + Menu_AddMainMenuItem(&cmi); + + cmi.position = 1600000001; + cmi.icolibItem = hIconLibItem[0]; + cmi.pszName = "New &Reminder"; + cmi.pszService = MODULENAME"/MenuCommandNewReminder"; + if (g_AddContListMI) Menu_AddContactMenuItem(&cmi); + Menu_AddMainMenuItem(&cmi); + + // + + cmi.position = 1600100000; + cmi.icolibItem = hIconLibItem[3]; + cmi.pszName = "&Show / Hide Notes"; + cmi.pszService = MODULENAME"/MenuCommandShowHide"; + if (g_AddContListMI) Menu_AddContactMenuItem(&cmi); + Menu_AddMainMenuItem(&cmi); + + cmi.position = 1600100001; + cmi.icolibItem = hIconLibItem[13]; + cmi.pszName = "Vie&w Notes"; + cmi.pszService = MODULENAME"/MenuCommandViewNotes"; + if (g_AddContListMI) Menu_AddContactMenuItem(&cmi); + Menu_AddMainMenuItem(&cmi); + + cmi.position = 1600100002; + cmi.icolibItem = hIconLibItem[1]; + cmi.pszName = "&Delete All Notes"; + cmi.pszService = MODULENAME"/MenuCommandDeleteAll"; + if (g_AddContListMI) Menu_AddContactMenuItem(&cmi); + Menu_AddMainMenuItem(&cmi); + + cmi.position = 1600100003; + cmi.icolibItem = hIconLibItem[11]; + cmi.pszName = "&Bring All to Front"; + cmi.pszService = MODULENAME"/MenuCommandBringAllFront"; + if (g_AddContListMI) Menu_AddContactMenuItem(&cmi); + Menu_AddMainMenuItem(&cmi); + + // + + cmi.position = 1600200000; + cmi.icolibItem = hIconLibItem[6]; + cmi.pszName = "&View Reminders"; + cmi.pszService = MODULENAME"/MenuCommandViewReminders"; + if (g_AddContListMI) Menu_AddContactMenuItem(&cmi); + Menu_AddMainMenuItem(&cmi); + + cmi.position = 1600200001; + cmi.icolibItem = hIconLibItem[5]; + cmi.pszName = "D&elete All Reminders"; + cmi.pszService = MODULENAME"/MenuCommandDeleteReminders"; + if (g_AddContListMI) Menu_AddContactMenuItem(&cmi); + Menu_AddMainMenuItem(&cmi); + + // register misc + + hkOptInit = HookEvent(ME_OPT_INITIALISE, OnOptInitialise); + hkTopToolbarInit = HookEvent("TopToolBar/ModuleLoaded", OnTopToolBarInit); + UnhookEvent(hkModulesLoaded); + + // init vars and load all data + + InitSettings(); + CreateMsgWindow(); + LoadNotes(TRUE); + LoadReminders(); + + return 0; +} + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +extern "C" __declspec(dllexport) int Unload(void) +{ + CloseNotesList(); + CloseReminderList(); + SaveNotes(); + SaveReminders(); + DestroyMsgWindow(); + WS_CleanUp(); + TermSettings(); + + UnhookEvent(hkFontChange); + UnhookEvent(hkColorChange); + + UnhookEvent(hkOptInit); + + Skin_ReleaseIcon(g_hReminderIcon); + DeleteObject(hBodyFont); + DeleteObject(hCaptionFont); + + if (hRichedDll) + FreeLibrary(hRichedDll); + if (hUserDll) + FreeLibrary(hUserDll); + if (hKernelDll) + FreeLibrary(hKernelDll); + + return 0; +} + +BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID lpvReserved) +{ + hinstance = hinst; + return TRUE; +} + +extern "C" __declspec(dllexport) int Load(void) +{ + mir_getLP(&pluginInfo); + + INITCOMMONCONTROLSEX ctrls = {0}; + ctrls.dwSize = sizeof(INITCOMMONCONTROLSEX); + ctrls.dwICC = ICC_DATE_CLASSES; + InitCommonControlsEx(&ctrls); + + g_isWin2kPlus = IsWinVer2000Plus(); + + hRichedDll = LoadLibrary("RICHED20.DLL"); + if (!hRichedDll) + { + if (MessageBox(0, Translate("Miranda could not load the Note & Reminders plugin, RICHED20.DLL is missing. If you are using Windows 95 or WINE please make sure you have riched20.dll installed. Press 'Yes' to continue loading Miranda."), SECTIONNAME, MB_YESNO | MB_ICONINFORMATION) != IDYES) + return 1; + return 0; + } + + hUserDll = LoadLibrary("user32.dll"); + if (hUserDll) + { + MySetLayeredWindowAttributes = (BOOL (WINAPI *)(HWND,COLORREF,BYTE,DWORD))GetProcAddress(hUserDll,"SetLayeredWindowAttributes"); + MyMonitorFromWindow = (HANDLE (WINAPI*)(HWND,DWORD))GetProcAddress(hUserDll,"MonitorFromWindow"); + } + else + { + MySetLayeredWindowAttributes = NULL; + MyMonitorFromWindow = NULL; + } + + hKernelDll = LoadLibrary("kernel32.dll"); + if (hKernelDll) + { + MyTzSpecificLocalTimeToSystemTime = (BOOL (WINAPI*)(LPTIME_ZONE_INFORMATION,LPSYSTEMTIME,LPSYSTEMTIME))GetProcAddress(hKernelDll,"TzSpecificLocalTimeToSystemTime"); + MySystemTimeToTzSpecificLocalTime = (BOOL (WINAPI*)(LPTIME_ZONE_INFORMATION,LPSYSTEMTIME,LPSYSTEMTIME))GetProcAddress(hKernelDll,"SystemTimeToTzSpecificLocalTime"); + } + else + { + MyTzSpecificLocalTimeToSystemTime = NULL; + MySystemTimeToTzSpecificLocalTime = NULL; + } + + InitServices(); + WS_Init(); + + hkModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED,OnModulesLoaded); + InitIcons(); + + return 0; +} \ No newline at end of file diff --git a/plugins/!NotAdopted/NotesAndReminders/src/miscutils.cpp b/plugins/!NotAdopted/NotesAndReminders/src/miscutils.cpp new file mode 100644 index 0000000000..b4de98404c --- /dev/null +++ b/plugins/!NotAdopted/NotesAndReminders/src/miscutils.cpp @@ -0,0 +1,246 @@ +#include "globals.h" + +BOOL (WINAPI *MySetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD); +HANDLE (WINAPI *MyMonitorFromWindow)(HWND,DWORD); +BOOL (WINAPI *MyTzSpecificLocalTimeToSystemTime)(LPTIME_ZONE_INFORMATION,LPSYSTEMTIME,LPSYSTEMTIME); +BOOL (WINAPI *MySystemTimeToTzSpecificLocalTime)(LPTIME_ZONE_INFORMATION,LPSYSTEMTIME,LPSYSTEMTIME); + + +WORD ConvertHotKeyToControl(WORD HK) +{ + WORD R = 0; + if ((HK & MOD_CONTROL) == MOD_CONTROL) R = R | HOTKEYF_CONTROL; + if ((HK & MOD_ALT) == MOD_ALT) R = R | HOTKEYF_ALT; + if ((HK & MOD_SHIFT) == MOD_SHIFT) R = R | HOTKEYF_SHIFT; + return R; +} + +WORD ConvertControlToHotKey(WORD HK) +{ + WORD R = 0; + if ((HK & HOTKEYF_CONTROL) == HOTKEYF_CONTROL) R = R | MOD_CONTROL; + if ((HK & HOTKEYF_ALT) == HOTKEYF_ALT) R = R | MOD_ALT; + if ((HK & HOTKEYF_SHIFT) == HOTKEYF_SHIFT) R = R | MOD_SHIFT; + return R; +} + +void WriteSettingInt(HANDLE hContact,char *ModuleName,char *SettingName,int Value) +{ + DBCONTACTWRITESETTING cws = {0}; + DBVARIANT dbv = {0}; + dbv.type = DBVT_DWORD; + dbv.dVal = Value; + cws.szModule = ModuleName; + cws.szSetting = SettingName; + cws.value = dbv; + CallService(MS_DB_CONTACT_WRITESETTING,(DWORD)hContact,(DWORD)&cws); +} + +int ReadSettingInt(HANDLE hContact,char *ModuleName,char *SettingName,int Default) +{ + DBCONTACTGETSETTING cws = {0}; + DBVARIANT dbv = {0}; + dbv.type = DBVT_DWORD; + dbv.dVal = Default; + cws.szModule = ModuleName; + cws.szSetting = SettingName; + cws.pValue = &dbv; + if (CallService(MS_DB_CONTACT_GETSETTING,(DWORD)hContact,(DWORD)&cws)) + return Default; + else + return dbv.dVal; +} + +void DeleteSetting(HANDLE hContact,char *ModuleName,char *SettingName) +{ + DBCONTACTGETSETTING dbcgs = {0}; + dbcgs.szModule = ModuleName; + dbcgs.szSetting = SettingName; + dbcgs.pValue = NULL; + CallService(MS_DB_CONTACT_DELETESETTING,(DWORD)hContact,(DWORD)&dbcgs); +} + +void FreeSettingBlob(WORD pSize,void * pbBlob) +{ + DBVARIANT dbv = {0}; + dbv.type = DBVT_BLOB; + dbv.cpbVal = pSize; + dbv.pbVal = (BYTE*)pbBlob; + CallService(MS_DB_CONTACT_FREEVARIANT,0,(DWORD)&dbv); +} + +void WriteSettingBlob(HANDLE hContact,char *ModuleName,char *SettingName,WORD pSize,void *pbBlob) +{ + DBCONTACTWRITESETTING cgs = {0}; + DBVARIANT dbv = {0}; + dbv.type = DBVT_BLOB; + dbv.cpbVal = pSize; + dbv.pbVal = (BYTE*)pbBlob; + cgs.szModule = ModuleName; + cgs.szSetting = SettingName; + cgs.value = dbv; + CallService(MS_DB_CONTACT_WRITESETTING,(DWORD)hContact,(DWORD)&cgs); +} + +void ReadSettingBlob(HANDLE hContact, char *ModuleName, char *SettingName, WORD *pSize, void **pbBlob) +{ + DBCONTACTGETSETTING cgs = {0}; + DBVARIANT dbv = {0}; + dbv.type = DBVT_BLOB; +// dbv.cpbVal = (LOBYTE(pSize) | HIBYTE((BYTE)pbBlob)); // this is not used anyway + cgs.szModule = ModuleName; + cgs.szSetting = SettingName; + cgs.pValue = &dbv; + if (CallService(MS_DB_CONTACT_GETSETTING,(DWORD)hContact,(DWORD)&cgs)) + { + pSize = 0; // tohle asi ve 4.2 neni + pbBlob = NULL; + } + else + { + *pSize = LOWORD(dbv.cpbVal); + *pbBlob = (int*)dbv.pbVal; + } +} + +void WriteSettingIntArray(HANDLE hContact,char *ModuleName,char *SettingName,const int *Value, int Size) +{ + WriteSettingBlob(hContact,ModuleName,SettingName,sizeof(int)*Size,(void*)Value); +} + +BOOL ReadSettingIntArray(HANDLE hContact,char *ModuleName,char *SettingName,int *Value, int Size) +{ + WORD sz = 4096; + int *pData; + BOOL bResult; + + ReadSettingBlob(hContact, ModuleName, SettingName, &sz, (void**)&pData); + + if (!pData) + return FALSE; + + bResult = FALSE; + + if (sz == sizeof(int)*Size) + { + memcpy(Value, pData, sizeof(int)*Size); + bResult = TRUE; + } + + FreeSettingBlob(sz,pData); + + return bResult; +} + +void TreeAdd(TREEELEMENT **root, void *Data) +{ + TREEELEMENT *NTE; + NTE = (TREEELEMENT*)malloc(sizeof(TREEELEMENT)); + if (NTE) + { + NTE->ptrdata = Data; + NTE->next = *root; + *root = NTE; + } +} + +void TreeAddSorted(TREEELEMENT **root,void *Data,int (*CompareCb)(TREEELEMENT*,TREEELEMENT*)) +{ + TREEELEMENT *TTE,*Prev; + TREEELEMENT *NTE; + + if (!*root) + { + // list empty, just add normally + TreeAdd(root,Data); + return; + } + + NTE = (TREEELEMENT*)malloc(sizeof(TREEELEMENT)); + if (!NTE) + return; + + NTE->ptrdata = Data; + NTE->next = NULL; + + // insert sorted + + Prev = NULL; + TTE = *root; + + while (TTE) + { + if (CompareCb(NTE, TTE) < 0) + { + if (Prev) + { + Prev->next = NTE; + NTE->next = TTE; + } + else + { + // first in list + NTE->next = TTE; + *root = NTE; + } + return; + } + + Prev = TTE; + TTE = (TREEELEMENT*)TTE->next; + } + + // add last + Prev->next = NTE; +} + +void TreeDelete(TREEELEMENT **root,void *Item) +{ + TREEELEMENT *TTE,*Prev = NULL; + TTE = *root; + if (!TTE) return; + while ((TTE) && (TTE->ptrdata != Item)) + { + Prev = TTE; + TTE = (TREEELEMENT*)TTE->next; + } + if (TTE) + { + if (Prev) + Prev->next = TTE->next; + else + *root = (TREEELEMENT*)TTE->next; + SAFE_FREE((void**)&TTE); + } +} + +void *TreeGetAt(TREEELEMENT *root,int Item) +{ + TREEELEMENT *TTE; + int I = 0; + if (!root) return NULL; + TTE = root; + while ((TTE) && (I != Item)) + { + TTE = (TREEELEMENT*)TTE->next; + I++; + } + if (!TTE) + return NULL; + else + return TTE->ptrdata; +} + +int TreeGetCount(TREEELEMENT *root) +{ + int I = 0; + TREEELEMENT *TTE; + if (!root) return 0; + TTE = root; + while (TTE) + { + TTE = (TREEELEMENT*)TTE->next; + I++; + } + return I; +} diff --git a/plugins/!NotAdopted/NotesAndReminders/src/miscutils.h b/plugins/!NotAdopted/NotesAndReminders/src/miscutils.h new file mode 100644 index 0000000000..104de5313c --- /dev/null +++ b/plugins/!NotAdopted/NotesAndReminders/src/miscutils.h @@ -0,0 +1,47 @@ +void WriteSettingInt(HANDLE hContact,char *ModuleName, + char *SettingName,int Value); +int ReadSettingInt(HANDLE hContact,char *ModuleName, + char *SettingName,int Default); +void ReadSettingBlob(HANDLE hContact, char *ModuleName, + char *SettingName, WORD *pSize, void **pbBlob); +void WriteSettingBlob(HANDLE hContact,char *ModuleName, + char *SettingName,WORD pSize,void *pbBlob); +void FreeSettingBlob(WORD pSize,void * pbBlob); +BOOL ReadSettingBool(HANDLE hContact,char *ModuleName, + char *SettingName,BOOL Default); +void WriteSettingBool(HANDLE hContact,char *ModuleName, + char *SettingName,BOOL Value); +void DeleteSetting(HANDLE hContact,char *ModuleName, + char *SettingName); +void WriteSettingIntArray(HANDLE hContact,char *ModuleName, + char *SettingName,const int *Value, int Size); +BOOL ReadSettingIntArray(HANDLE hContact,char *ModuleName, + char *SettingName,int *Value, int Size); + +extern BOOL (WINAPI *MySetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD); +extern HANDLE (WINAPI *MyMonitorFromWindow)(HWND,DWORD); +extern BOOL (WINAPI *MyTzSpecificLocalTimeToSystemTime)(LPTIME_ZONE_INFORMATION,LPSYSTEMTIME,LPSYSTEMTIME); +extern BOOL (WINAPI *MySystemTimeToTzSpecificLocalTime)(LPTIME_ZONE_INFORMATION,LPSYSTEMTIME,LPSYSTEMTIME); + +WORD ConvertHotKeyToControl(WORD HK); +WORD ConvertControlToHotKey(WORD HK); + +typedef struct { + void *ptrdata; + void *next; +} TREEELEMENT; + +void TreeAdd(TREEELEMENT **root,void *Data); +void TreeAddSorted(TREEELEMENT **root,void *Data,int (*CompareCb)(TREEELEMENT*,TREEELEMENT*)); +void TreeDelete(TREEELEMENT **root,void *Item); +void *TreeGetAt(TREEELEMENT *root,int Item); +int TreeGetCount(TREEELEMENT *root); + +static void __inline SAFE_FREE(void** p) +{ + if (*p) + { + free(*p); + *p = NULL; + } +} diff --git a/plugins/!NotAdopted/NotesAndReminders/src/notes.cpp b/plugins/!NotAdopted/NotesAndReminders/src/notes.cpp new file mode 100644 index 0000000000..5f98768d8b --- /dev/null +++ b/plugins/!NotAdopted/NotesAndReminders/src/notes.cpp @@ -0,0 +1,2180 @@ +#include "globals.h" + +#ifndef MONITOR_DEFAULTTONULL +#define MONITOR_DEFAULTTONULL 0x00000000 +#endif + + +// NotesData DB data params +#define DATATAG_TEXT 1 // %s +#define DATATAG_SCROLLPOS 2 // %u (specifies rich edit controls scroll post as first visible line) +#define DATATAG_BGCOL 3 // %x (custom background color) +#define DATATAG_FGCOL 4 // %x (custom text/fg colors) +#define DATATAG_TITLE 5 // %s (custom note title) +#define DATATAG_FONT 6 // %d:%u:%u:%s (custom font) + + +#define MAX_TITLE_LEN 63 +#define MAX_NOTE_LEN 16384 + +// delay before saving note changes (ms) +#define NOTE_CHANGE_COMMIT_DELAY 1000 + + +#ifndef WS_EX_NOACTIVATE +#define WS_EX_NOACTIVATE 0x08000000 +#endif +#define IDM_REMOVENOTE 40001 +#define IDM_HIDENOTE 40002 +#define IDM_TOGGLEONTOP 40003 +#define IDM_UNDO 40004 +#define IDM_COPY 40005 +#define IDM_PASTE 40006 +#define IDM_CUT 40007 +#define IDM_CLEAR 40008 +#define WS_EX_LAYERED 0x00080000 +#define LWA_ALPHA 0x00000002 + +#define IDC_LISTREMINDERS 1000 +#define IDC_LISTREMINDERS_HEADER 2000 +#define IDC_REMINDERDATA 1001 +#define IDC_ADDNEWREMINDER 1002 +#define IDC_CLOSE 1003 +#define WM_RELOAD (WM_USER + 100) + +#define NOTIFY_LIST() if (ListNotesVisible) PostMessage(LV,WM_RELOAD,0,0) + +#define PENLINK ENLINK * + +#define NOTE_WND_CLASS "MIM_StickyNote" + + +#define IDM_COLORPRESET_BG 41000 +#define IDM_COLORPRESET_FG 41100 + + +static BOOL ListNotesVisible = FALSE; +static HWND LV; + + +struct ColorPreset +{ + TCHAR *szName; + COLORREF color; +}; + +static struct ColorPreset clrPresets[] = +{ + {"Black", RGB(0,0,0)}, + {"Maroon", RGB(128,0,0)}, + {"Green", RGB(0,128,0)}, + {"Olive", RGB(128,128,0)}, + {"Navy", RGB(0,0,128)}, + {"Purple", RGB(128,0,128)}, + {"Teal", RGB(0,128,128)}, + {"Gray", RGB(128,128,128)}, + {"Silver", RGB(192,192,192)}, + {"Red", RGB(255,0,0)}, + {"Orange", RGB(255,155,0)}, + {"Lime", RGB(0,255,0)}, + {"Yellow", RGB(255,255,0)}, + {"Blue", RGB(0,0,255)}, + {"Fuchsia", RGB(255,0,255)}, + {"Aqua", RGB(0,255,255)}, + {"White", RGB(255,255,255)} +}; + + +TREEELEMENT *g_Stickies = NULL; + + +int CALLBACK StickyNoteWndProc(HWND hdlg,UINT message, + WPARAM wParam,LPARAM lParam); +int CALLBACK DlgProcViewNotes(HWND Dialog,UINT Message,WPARAM wParam, + LPARAM lParam); +void JustSaveNotes(void); +int PluginMenuCommandAddNew(WPARAM w,LPARAM l); +int PluginMenuCommandDeleteAll(WPARAM w,LPARAM l); +void GetTriggerTimeString(const ULARGE_INTEGER *When, char *s, UINT strSize, BOOL bUtc); +void OnListResize(HWND Dialog); +void UpdateGeomFromWnd(HWND Dialog, int *geom, int *colgeom, int nCols); +void FileTimeToTzLocalST(const FILETIME *lpUtc, SYSTEMTIME *tmLocal); + + +COLORREF GetCaptionColor(COLORREF bodyClr) +{ + const DWORD r = ((bodyClr & 0xff) * 4) / 5; + const DWORD g = (((bodyClr & 0xff00) * 4) / 5) & 0xff00; + const DWORD b = (((bodyClr & 0xff0000) * 4) / 5) & 0xff0000; + + return (COLORREF)(r|g|b); +} + + +static void EnsureUniqueID(STICKYNOTE *TSN) +{ + TREEELEMENT *TTE; + + if (!g_Stickies) + return; + +try_next: + + // check existing notes if id is in use + TTE = g_Stickies; + while (TTE) + { + if (((STICKYNOTE*)TTE->ptrdata)->ID.QuadPart == TSN->ID.QuadPart) + { + // id in use, try new (increases the ID/time stamp by 100 nanosecond steps until an unused time is found, + // allthough it's very unlikely that there will be duplicated id's it's better to make 100% sure) + TSN->ID.QuadPart++; + goto try_next; + } + + TTE = (TREEELEMENT*)TTE->next; + } +} + + +static void InitNoteTitle(STICKYNOTE *TSN) +{ + if (g_NoteTitleDate) + { + char TempStr[MAX_PATH]; + SYSTEMTIME tm; + LCID lc = GetUserDefaultLCID(); + + TempStr[0] = 0; + + memset(&tm, 0, sizeof(tm)); + FileTimeToTzLocalST((FILETIME*)&TSN->ID, &tm); + + if ( GetDateFormat(lc, 0, &tm, GetDateFormatStr(), TempStr, MAX_PATH) ) + { + // append time if requested + if (g_NoteTitleTime) + { + int n = strlen(TempStr); + TempStr[n++] = ' '; + TempStr[n] = 0; + + GetTimeFormat(MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),0), 0, &tm, GetTimeFormatStr(), TempStr+n, MAX_PATH-n); + } + + TSN->title = _strdup(TempStr); + } + } + + TSN->CustomTitle = FALSE; +} + + +static void InitStickyNoteLogFont(STICKYNOTEFONT *pCustomFont, LOGFONT *lf) +{ + if (!pCustomFont->size) + { + HDC hdc; + + SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, FALSE); + lf->lfHeight = 10; + hdc = GetDC(0); + lf->lfHeight = -MulDiv(lf->lfHeight,GetDeviceCaps(hdc, LOGPIXELSY), 72); + ReleaseDC(0, hdc); + } + else + { + lf->lfHeight = pCustomFont->size; + } + + _tcscpy(lf->lfFaceName, pCustomFont->szFace); + + lf->lfWidth = lf->lfEscapement = lf->lfOrientation = 0; + lf->lfWeight = pCustomFont->style & DBFONTF_BOLD ? FW_BOLD : FW_NORMAL; + lf->lfItalic = (pCustomFont->style & DBFONTF_ITALIC) != 0; + lf->lfUnderline = (pCustomFont->style & DBFONTF_UNDERLINE) != 0; + lf->lfStrikeOut = (pCustomFont->style & DBFONTF_STRIKEOUT) != 0; + lf->lfCharSet = pCustomFont->charset; + lf->lfOutPrecision = OUT_DEFAULT_PRECIS; + lf->lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf->lfQuality = DEFAULT_QUALITY; + lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; +} + +static BOOL CreateStickyNoteFont(STICKYNOTEFONT *pCustomFont, LOGFONT *plf) +{ + LOGFONT lf = {0}; + + if (!plf) + { + InitStickyNoteLogFont(pCustomFont, &lf); + plf = &lf; + } + + if (pCustomFont->hFont) + DeleteObject(pCustomFont->hFont); + + pCustomFont->hFont = CreateFontIndirect(plf); + + return pCustomFont->hFont != NULL; +} + + +STICKYNOTE* NewNoteEx(int Ax,int Ay,int Aw,int Ah,char *Data,ULARGE_INTEGER *ID,BOOL Visible,BOOL OnTop,int scrollV,COLORREF bgClr,COLORREF fgClr,char *Title,STICKYNOTEFONT *pCustomFont,BOOL bLoading) +{ + STICKYNOTE* TSN; + WNDCLASSEX TWC = {0}; + WINDOWPLACEMENT TWP; + DWORD L1,L2; + SYSTEMTIME tm; + char TempStr[MAX_PATH] = {0}; + char *TData; + + const BOOL bIsStartup = Visible & 0x10000; + Visible &= ~0x10000; + + if (Data) TData = Data; else TData = NULL; + + if (!GetClassInfoEx(hmiranda, NOTE_WND_CLASS, &TWC)) + { + TWC.style = CS_HREDRAW | CS_VREDRAW | CS_NOCLOSE; + TWC.cbClsExtra = 0; + TWC.cbWndExtra = 0; + TWC.hInstance = hmiranda; + TWC.hIcon = LoadIcon(0,IDI_APPLICATION); + TWC.hCursor = LoadCursor(0,IDC_ARROW); + TWC.hbrBackground = 0; + TWC.lpszMenuName = 0; + TWC.lpszClassName = NOTE_WND_CLASS; + TWC.cbSize = sizeof(WNDCLASSEX); + TWC.lpfnWndProc = (WNDPROC)StickyNoteWndProc; + if (!RegisterClassEx(&TWC)) return NULL; + } + + if (!TData || Aw < 0 || Ah < 0) + { + TWP.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement(GetDesktopWindow(),&TWP); + Aw = g_NoteWidth; Ah = g_NoteHeight; + Ax = ((TWP.rcNormalPosition.right - TWP.rcNormalPosition.left) / 2) - (Aw / 2); + Ay = ((TWP.rcNormalPosition.bottom - TWP.rcNormalPosition.top) / 2) - (Ah / 2); + } + + TSN = (STICKYNOTE*)malloc(sizeof(STICKYNOTE)); + + if (ID) + { + TSN->ID = *ID; + } + else + { + GetSystemTime(&tm); + SYSTEMTIMEtoFILETIME(&tm, (FILETIME*)&TSN->ID); + } + + EnsureUniqueID(TSN); + + TreeAdd(&g_Stickies,TSN); + + if (!TData) + { + TData = _strdup(""); + TSN->data = TData; + } + else + TSN->data = TData; + + // init note title (time-stamp) + if (Title) + { + TSN->title = Title; + TSN->CustomTitle = TRUE; + } + else + { + TSN->title = NULL; + InitNoteTitle(TSN); + } + + TSN->Visible = Visible; + TSN->OnTop = OnTop; + + TSN->BgColor = bgClr; + TSN->FgColor = fgClr; + + TSN->pCustomFont = pCustomFont; + + L1 = WS_EX_TOOLWINDOW; + if (MySetLayeredWindowAttributes && g_Transparency < 255) L1 |= WS_EX_LAYERED; + if (OnTop) L1 |= WS_EX_TOPMOST; + + L2 = WS_POPUP | WS_THICKFRAME | WS_CAPTION; + + // NOTE: loaded note positions stem from GetWindowPlacement, which normally have a different coord space than + // CreateWindow/SetWindowPos, BUT since we now use WS_EX_TOOLWINDOW they use the same coord space so + // we don't have to worry about notes "drifting" between sessions + TSN->SNHwnd = CreateWindowEx(L1, NOTE_WND_CLASS, _T("StickyNote"), L2, Ax,Ay,Aw,Ah, NULL, 0, hmiranda, TSN); + + if (MySetLayeredWindowAttributes && g_Transparency < 255) + MySetLayeredWindowAttributes(TSN->SNHwnd,0,(BYTE)g_Transparency,LWA_ALPHA); + + // ensure that window is not placed off-screen (if previous session had different monitor count or resolution) + // NOTE: SetWindowPlacement should do this, but it's extremly flakey + if (Data) + { + if (MyMonitorFromWindow && !MyMonitorFromWindow(TSN->SNHwnd, MONITOR_DEFAULTTONULL) ) + { + TWP.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement(GetDesktopWindow(), &TWP); + + if (Aw > 500) Aw = 500; + if (Ay < TWP.rcNormalPosition.left+10 || Ax > TWP.rcNormalPosition.right-120) + Ax = ((TWP.rcNormalPosition.right - TWP.rcNormalPosition.left) / 2) - (Aw / 2) + (rand() & 0x3f); + if (Ay < TWP.rcNormalPosition.top+50 || Ay > TWP.rcNormalPosition.bottom-50) + Ay = ((TWP.rcNormalPosition.bottom - TWP.rcNormalPosition.top) / 4) + (rand() & 0x1f); + + SetWindowPos(TSN->SNHwnd, NULL, Ax, Ay, Aw, Ah, SWP_NOZORDER|SWP_NOACTIVATE); + } + } + + if (Visible) + { + ShowWindow(TSN->SNHwnd, SW_SHOWNA); + + // when loading notes (only at startup), place all non-top notes at the bottom so they don't cover other windows + if (Data && !OnTop && bIsStartup) + SetWindowPos(TSN->SNHwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_ASYNCWINDOWPOS); + } + + if (scrollV) + { + SendMessage(TSN->REHwnd, EM_LINESCROLL, 0, scrollV); + } + + // make sure that any event triggered by init doesn't cause a meaningless save + KillTimer(TSN->SNHwnd, 1025); + + if (!bLoading) + { + NOTIFY_LIST(); + } + + return TSN; +} + +STICKYNOTE* NewNote(int Ax,int Ay,int Aw,int Ah,char *Data,ULARGE_INTEGER *ID,BOOL Visible,BOOL OnTop,int scrollV) +{ + return NewNoteEx(Ax,Ay,Aw,Ah,Data,ID,Visible,OnTop,scrollV,0,0,NULL,NULL,FALSE); +} + +void LoadNotes(BOOL bIsStartup) +{ + int I; + int NotesCount; + WORD Size; + char *Value = NULL, *TVal = NULL; + char ValueName[32]; + + g_Stickies = NULL; + + NotesCount = ReadSettingInt(0,MODULENAME,"NotesData",0); + + for (I = 0; I < NotesCount; I++) + { + char *DelPos; + + sprintf(ValueName, "NotesData%d", I); + + if (Value) + { + FreeSettingBlob(Size, Value); + Value = NULL; + } + + Size = 65535; // does not get used + + ReadSettingBlob(0, MODULENAME, ValueName, &Size, (void**)&Value); + + if (!Size || !Value) + continue; // the setting could not be read from DB -> skip + + if (Value[0] == 'X') + { + // new eXtended/fleXible data format + + STICKYNOTE note = {0}; + int i, rect[4]; + int scrollV = 0; + STICKYNOTEFONT *pCustomFont = NULL; + DWORD flags; + + DelPos = strchr(Value+1,0x1B); + if (DelPos) + *DelPos = 0; + + // id:x:y:w:h:flags + + TVal = strchr(Value+1, ':'); + if (!TVal || (DelPos && TVal > DelPos)) + continue; + *TVal++ = 0; + + note.ID.QuadPart = _strtoui64(Value+1, NULL, 16); + + for (i=0; i<4; i++) + { + char *sep = strchr(TVal, ':'); + if (!sep || (DelPos && sep > DelPos)) + goto skip; + *sep++ = 0; + + rect[i] = strtol(TVal, NULL, 10); + + TVal = sep; + } + + flags = strtoul(TVal, NULL, 16); + + if (flags & 1) + note.Visible = TRUE; + if (flags & 2) + note.OnTop = TRUE; + + // optional \033 separated params + while (DelPos) + { + char *sep; + UINT tag; + + TVal = DelPos + 1; + // find param end and make sure it's null-terminated (if end of data then it's already null-terminated) + DelPos = strchr(TVal, 0x1B); + if (DelPos) + *DelPos = 0; + + // tag: + + sep = strchr(TVal, ':'); + if (!sep || (DelPos && sep > DelPos)) + goto skip; + + tag = strtoul(TVal, NULL, 10); + TVal = sep + 1; + + switch (tag) + { + case DATATAG_TEXT: + note.data = _strdup(TVal); + break; + + case DATATAG_SCROLLPOS: + scrollV = (int)strtoul(TVal, NULL, 10); + break; + + case DATATAG_BGCOL: + note.BgColor = strtoul(TVal, NULL, 16) | 0xff000000; + break; + + case DATATAG_FGCOL: + note.FgColor = strtoul(TVal, NULL, 16) | 0xff000000; + break; + + case DATATAG_TITLE: + if (strlen(TVal) > MAX_TITLE_LEN) + TVal[MAX_TITLE_LEN] = 0; + note.title = _strdup(TVal); + note.CustomTitle = TRUE; + break; + + case DATATAG_FONT: + { + int fsize; + UINT fstyle, fcharset; + + char *TVal2 = TVal; + sep = strchr(TVal2, ':'); + if (!sep || (DelPos && sep > DelPos)) + goto skip; + *sep++ = 0; + fsize = strtol(TVal2, NULL, 10); + TVal2 = sep; + + sep = strchr(TVal2, ':'); + if (!sep || (DelPos && sep > DelPos)) + goto skip; + *sep++ = 0; + fstyle = strtoul(TVal2, NULL, 10); + TVal2 = sep; + + sep = strchr(TVal2, ':'); + if (!sep || (DelPos && sep > DelPos)) + goto skip; + *sep++ = 0; + fcharset = strtoul(TVal2, NULL, 10); + TVal2 = sep; + + if (TVal2 >= DelPos) + goto skip; + + pCustomFont = (STICKYNOTEFONT*)malloc(sizeof(STICKYNOTEFONT)); + pCustomFont->size = (char)fsize; + pCustomFont->style = (BYTE)fstyle; + pCustomFont->charset = (BYTE)fcharset; + _tcscpy(pCustomFont->szFace, TVal2); + pCustomFont->hFont = NULL; + + if ( !CreateStickyNoteFont(pCustomFont, NULL) ) + { + free(pCustomFont); + pCustomFont = NULL; + } + } + break; + } + } + + if (!note.data) + note.data = _strdup(""); + + note.Visible = note.Visible && (!bIsStartup || g_ShowNotesAtStart); + if (bIsStartup) + note.Visible |= 0x10000; + + NewNoteEx(rect[0],rect[1],rect[2],rect[3],note.data,¬e.ID,note.Visible,note.OnTop,scrollV,note.BgColor,note.FgColor,note.title,pCustomFont,TRUE); + } + else + { + // old format (for DB backward compatibility) + + int Tx,Ty,Tw,Th,TV,OT; + BOOL V; + char *Data,*ID; + ULARGE_INTEGER newid; + + OT = 1; TV = 1; + Tx = 100; Ty = 100; + Tw = 179; Th = 35; + Data = NULL; ID = NULL; + + if (DelPos = strchr(Value,0x1B)) + { // get first delimiter + int PartLen = DelPos - TVal; + + Data = NULL; + ID = NULL; + TVal = Value; + DelPos[0] = 0x0; + Tx = strtol(TVal, NULL, 10); + + TVal = DelPos + 1; + DelPos = strchr(TVal, 0x1B); + if (!DelPos) continue; // setting is broken, do not crash + DelPos[0] = 0x0; + Ty = strtol(TVal, NULL, 10); + + TVal = DelPos + 1; + DelPos = strchr(TVal, 0x1B); + if (!DelPos) continue; // setting is broken, do not crash + DelPos[0] = 0x0; + Tw = strtol(TVal, NULL, 10); + + TVal = DelPos + 1; + DelPos = strchr(TVal, 0x1B); + if (!DelPos) continue; // setting is broken, do not crash + DelPos[0] = 0x0; + Th = strtol(TVal, NULL, 10); + + TVal = DelPos + 1; + DelPos = strchr(TVal, 0x1B); + if (!DelPos) continue; // setting is broken, do not crash + DelPos[0] = 0x0; + TV = strtol(TVal, NULL, 10); + + TVal = DelPos + 1; + DelPos = strchr(TVal, 0x1B); + if (!DelPos) continue; // setting is broken, do not crash + DelPos[0] = 0x0; + OT = strtol(TVal, NULL, 10); + + TVal = DelPos + 1; + DelPos = strchr(TVal, 0x1B); + if (!DelPos) continue; // setting is broken, do not crash + DelPos[0] = 0x0; + Data = _strdup(TVal); + + TVal = DelPos + 1; + ID = TVal; + + V = (BOOL)TV && (!bIsStartup || g_ShowNotesAtStart); + + if (bIsStartup) + V |= 0x10000; + + // convert old ID format to new + if ( strchr(ID, '-') ) + { + // validate format (otherwise create new) + if (strlen(ID) < 19 || ID[2] != '-' || ID[5] != '-' || ID[10] != ' ' || ID[13] != ':' || ID[16] != ':') + { + ID = NULL; + } + else + { + SYSTEMTIME tm; + + ID[2] = ID[5] = ID[10] = ID[13] = ID[16] = 0; + + memset(&tm, 0, sizeof(tm)); + tm.wDay = (WORD)strtoul(ID, NULL, 10); + tm.wMonth = (WORD)strtoul(ID+3, NULL, 10); + tm.wYear = (WORD)strtoul(ID+6, NULL, 10); + tm.wHour = (WORD)strtoul(ID+11, NULL, 10); + tm.wMinute = (WORD)strtoul(ID+14, NULL, 10); + tm.wSecond = (WORD)strtoul(ID+17, NULL, 10); + + SYSTEMTIMEtoFILETIME(&tm, (FILETIME*)&newid); + } + } + else + { + ID = NULL; + } + + NewNoteEx(Tx,Ty,Tw,Th,Data,ID?&newid:NULL,V,(BOOL)OT,0,0,0,NULL,NULL,TRUE); + } + } +skip:; + } + + if (Value) + FreeSettingBlob(Size, Value); // we do not leak on bad setting + + NOTIFY_LIST(); +} + +void CloseNotesList() +{ + if (ListNotesVisible) + { + DestroyWindow(LV); + ListNotesVisible = FALSE; + } +} + +static void PurgeNotesTree() +{ + STICKYNOTE *pt; + + while (g_Stickies) // empty whole tree + { + pt = (STICKYNOTE*)g_Stickies->ptrdata; + if (pt->SNHwnd) DestroyWindow(pt->SNHwnd); + SAFE_FREE((void**)&pt->title); + SAFE_FREE((void**)&pt->data); + if (pt->pCustomFont) + { + DeleteObject(pt->pCustomFont->hFont); + free(pt->pCustomFont); + } + TreeDelete(&g_Stickies,pt); + SAFE_FREE((void**)&pt); + } + g_Stickies = NULL; +} + +void SaveNotes(void) +{ + JustSaveNotes(); + PurgeNotesTree(); +} + +void PurgeNotes(void) +{ + int NotesCount, I; + char ValueName[16]; + + NotesCount = ReadSettingInt(0,MODULENAME,"NotesData",0); + for(I = 0; I < NotesCount; I++) + { + sprintf(ValueName, "NotesData%d", I); + DBDeleteContactSetting(0,MODULENAME,ValueName); + } +} + +void OnDeleteNote(HWND hdlg, STICKYNOTE *SN) +{ + if (MessageBox(hdlg, Translate("Are you sure you want to delete this note?"), SECTIONNAME, MB_OKCANCEL) == IDOK) + { + DestroyWindow(hdlg); + TreeDelete(&g_Stickies,SN); + SAFE_FREE((void**)&SN->data); + if (SN->pCustomFont) + { + DeleteObject(SN->pCustomFont->hFont); + free(SN->pCustomFont); + } + SAFE_FREE((void**)&SN); + JustSaveNotes(); + } +} + +void DeleteNotes(void) +{ + PurgeNotes(); + WriteSettingInt(0, MODULENAME, "NotesData", 0); + PurgeNotesTree(); +} + +void ShowHideNotes(void) +{ + TREEELEMENT *TTE; + int bShow; + UINT nHideCount, nVisCount; + BOOL Visible; + + if (!g_Stickies) + return; + + // if some notes are hidden but others visible then first make all visible + // only toggle vis state if all are hidden or all are visible + + nHideCount = nVisCount = 0; + TTE = g_Stickies; + while (TTE) + { + if (((STICKYNOTE*)TTE->ptrdata)->Visible) + nVisCount++; + else + nHideCount++; + + TTE = (TREEELEMENT*)TTE->next; + } + + if (!nVisCount) + Visible = TRUE; + else if (!nHideCount) + Visible = FALSE; + else + Visible = TRUE; + + bShow = Visible ? SW_SHOWNA : SW_HIDE; + + TTE = g_Stickies; + while (TTE) + { + STICKYNOTE *SN = (STICKYNOTE*)TTE->ptrdata; + + if ((!Visible) != (!SN->Visible)) + { + ShowWindow(SN->SNHwnd, bShow); + SN->Visible = Visible; + } + + TTE = (TREEELEMENT*)TTE->next; + } + + JustSaveNotes(); +} + +void BringAllNotesToFront(STICKYNOTE *pActive) +{ + TREEELEMENT *TTE; + + if (!g_Stickies) + return; + + // NOTE: for some reason there are issues when bringing to top through hotkey while another app (like Explorer) + // is active, it refuses to move notes to top like it should with HWND_TOP. as a workaround still doesn't + // work 100% of the time, but at least more often, we first move not to top-most then for non-always-on-top + // notes we demote them back as a non top-most window + + TTE = g_Stickies; + while (TTE) + { + STICKYNOTE *SN = (STICKYNOTE*)TTE->ptrdata; + + if (SN->Visible && pActive != SN) + { + SetWindowPos(SN->SNHwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); + if (!SN->OnTop) + SetWindowPos(SN->SNHwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); + } + + TTE = (TREEELEMENT*)TTE->next; + } + + if (pActive) + { + SetWindowPos(pActive->SNHwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); + if (!pActive->OnTop) + SetWindowPos(pActive->SNHwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); + } +} + +static void JustSaveNotesEx(STICKYNOTE *pModified) +{ + // pModified optionally points to the modified note that invoked the JustSaveNotesEx call + + TREEELEMENT *TTE; + int I, NotesCount = TreeGetCount(g_Stickies); + int n, l; + char ValueName[32]; + WINDOWPLACEMENT wp; + int TX,TY,TW,TH; + DWORD flags; + int SzT; + int scrollV; + char *tData, *Value; + + const int OldNotesCount = ReadSettingInt(0, MODULENAME, "NotesData", 0); + + WriteSettingInt(0, MODULENAME, "NotesData", NotesCount); + + for (TTE = g_Stickies, I = 0; TTE; TTE = (TREEELEMENT*)TTE->next, I++) + { + STICKYNOTE *pNote = (STICKYNOTE*)TTE->ptrdata; + BOOL bDeleteTData = TRUE; + scrollV = 0; + tData = NULL; + + // window pos and size + wp.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement(pNote->SNHwnd, &wp); + TX = wp.rcNormalPosition.left; + TY = wp.rcNormalPosition.top; + TW = wp.rcNormalPosition.right - wp.rcNormalPosition.left; + TH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; + + // set flags + flags = 0; + if (pNote->Visible) flags |= 1; + if (pNote->OnTop) flags |= 2; + + // get note text + SzT = SendMessage(pNote->REHwnd, WM_GETTEXTLENGTH, 0, 0); + if (SzT) // TODO: change to support unicode and rtf, use EM_STREAMOUT + { + if (SzT > MAX_NOTE_LEN) SzT = MAX_NOTE_LEN; // we want to be far below the 64k limit + tData = (char*)malloc(SzT+1); + if (tData) + SendMessage(pNote->REHwnd, WM_GETTEXT, SzT+1, (LPARAM)tData); + } + + if (pNote == pModified) + { + // update the data of the modified note + if (pNote->data) + free(pNote->data); + pNote->data = tData ? tData : _strdup(""); + bDeleteTData = FALSE; + } + + if (!tData) + // empty note + SzT = 0; + else + // get current scroll position + scrollV = SendMessage(pNote->REHwnd, EM_GETFIRSTVISIBLELINE, 0, 0); + + // + + Value = (char*)malloc(SzT + 512); + + if (!Value) + { + if (bDeleteTData) + SAFE_FREE((void**)&tData); + continue; + } + + n = 0; + + // data header + l = sprintf(Value, "X%I64x:%d:%d:%d:%d:%x", pNote->ID.QuadPart, TX, TY, TW, TH, flags); + if (l > 0) n += l; + + // scroll pos + if (scrollV > 0) + { + l = sprintf(Value+n, "\033""%u:%u", DATATAG_SCROLLPOS, (UINT)scrollV); + if (l > 0) n += l; + } + + // custom bg color + if (pNote->BgColor) + { + l = sprintf(Value+n, "\033""%u:%x", DATATAG_BGCOL, (UINT)(pNote->BgColor&0xffffff)); + if (l > 0) n += l; + } + + // custom fg color + if (pNote->FgColor) + { + l = sprintf(Value+n, "\033""%u:%x", DATATAG_FGCOL, (UINT)(pNote->FgColor&0xffffff)); + if (l > 0) n += l; + } + + if (pNote->pCustomFont) + { + l = sprintf(Value+n, "\033""%u:%d:%u:%u:%s", DATATAG_FONT, + (int)pNote->pCustomFont->size, (UINT)pNote->pCustomFont->style, (UINT)pNote->pCustomFont->charset, + pNote->pCustomFont->szFace); + if (l > 0) n += l; + } + + // custom title + if (pNote->CustomTitle && pNote->title) + { + l = sprintf(Value+n, "\033""%u:%s", DATATAG_TITLE, pNote->title); + if (l > 0) n += l; + } + + // note text (ALWAYS PUT THIS PARAM LAST) + if (tData) + { + l = sprintf(Value+n, "\033""%u:%s", DATATAG_TEXT, tData); + if (l > 0) n += l; + } + + // clamp data size to WORD (including null terminator) + if (n >= 0xffff) + { + // huston, we have a problem, strip some reminder text + n = 0xfffe; + ValueName[0xffff] = 0; + } + + sprintf(ValueName, "NotesData%d", NotesCount - I - 1); // we do not reverse notes in DB + + WriteSettingBlob(0, MODULENAME, ValueName, (WORD)(n+1), Value); + + SAFE_FREE((void**)&Value); + if (bDeleteTData) + SAFE_FREE((void**)&tData); + + // make no save is queued for the note + if (pNote->SNHwnd) + KillTimer(pNote->SNHwnd, 1025); + } + + // delete any left over DB note entries + for(; I < OldNotesCount; I++) + { + sprintf(ValueName, "NotesData%d", I); + DBDeleteContactSetting(0,MODULENAME,ValueName); + } + + NOTIFY_LIST(); +} + +__inline void JustSaveNotes(void) +{ + JustSaveNotesEx(NULL); +} + + +///////////////////////////////////////////////////////////////////// +// Note Window + +static int FindMenuItem(HMENU h, LPTSTR lpszName) +{ + int n; + UINT i; + TCHAR s[128]; + + n = GetMenuItemCount(h); + + if (n <= 0) + { + return -1; + } + + // searches for a menu item based on name (used to avoid hardcoding item indices for sub-menus) + for (i=0; i<(UINT)n; i++) + { + if ( GetMenuString(h, i, s, 128, MF_BYPOSITION) ) + { + if ( !_tcscmp(s, lpszName) ) + { + return (int)i; + } + } + } + + return -1; +} + +static BOOL DoContextMenu(HWND AhWnd,WPARAM wParam,LPARAM lParam) +{ + int n, i; + STICKYNOTE *SN = (STICKYNOTE*)GetProp(AhWnd,"ctrldata"); + + HMENU hMenuLoad, FhMenu, hSub; + hMenuLoad = LoadMenu(hinstance,"MNU_NOTEPOPUP"); + FhMenu = GetSubMenu(hMenuLoad,0); + + if (SN->OnTop) + CheckMenuItem(FhMenu, IDM_TOGGLEONTOP, MF_CHECKED|MF_BYCOMMAND); + + EnableMenuItem(FhMenu, ID_CONTEXTMENUNOTEPOPUP_PASTETITLE, MF_BYCOMMAND | (IsClipboardFormatAvailable(CF_TEXT) ? MF_ENABLED : MF_GRAYED)); + + if (!SN->CustomTitle) + EnableMenuItem(FhMenu, ID_CONTEXTMENUNOTEPOPUP_RESETTITLE, MF_BYCOMMAND | MF_GRAYED); + + // NOTE: names used for FindMenuItem would need to include & chars if such shortcuts are added to the menus + + // color preset menu items uses features that require win2k or later, I'm too lazy to make a fallback path + // for obsolete OS versions (win95/98/ME users can still use the "Custom" menu option) + if (g_isWin2kPlus) + { + n = FindMenuItem(FhMenu, _T("Appearance")); + if (n >= 0 && (hSub = GetSubMenu(FhMenu, n))) + { + HMENU hBg = GetSubMenu(hSub, FindMenuItem(hSub, _T("Background Color"))); + HMENU hFg = GetSubMenu(hSub, FindMenuItem(hSub, _T("Text Color"))); + + for (i=0; iszName); + SIZE sz; + GetTextExtentPoint32(hdc, lpsz, _tcslen(lpsz), &sz); + ReleaseDC(hdlg, hdc); + + lpMeasureItem->itemWidth = 50 + sz.cx; + lpMeasureItem->itemHeight = (sz.cy+2)>18 ? sz.cy+2 : 18; +} + +static void PaintColorPresetMenuItem(LPDRAWITEMSTRUCT lpDrawItem, struct ColorPreset *clrPresets) +{ + UINT n = lpDrawItem->itemID - IDM_COLORPRESET_BG; + RECT rect; + rect.left = lpDrawItem->rcItem.left + 50; + rect.top = lpDrawItem->rcItem.top; + rect.right = lpDrawItem->rcItem.right; + rect.bottom = lpDrawItem->rcItem.bottom; + + if (lpDrawItem->itemState & ODS_SELECTED) + { + SetDCBrushColor(lpDrawItem->hDC, GetSysColor(COLOR_MENUHILIGHT)); + FillRect(lpDrawItem->hDC, &lpDrawItem->rcItem, (HBRUSH)GetStockObject(DC_BRUSH)); + + SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); + } + else + { + SetDCBrushColor(lpDrawItem->hDC, GetSysColor(COLOR_MENU)); + FillRect(lpDrawItem->hDC, &lpDrawItem->rcItem, (HBRUSH)GetStockObject(DC_BRUSH)); + + SetTextColor(lpDrawItem->hDC, GetSysColor(COLOR_MENUTEXT)); + } + + SetBkMode(lpDrawItem->hDC, TRANSPARENT); + DrawText(lpDrawItem->hDC,clrPresets->szName,-1,&rect,DT_LEFT | DT_SINGLELINE | DT_END_ELLIPSIS | DT_VCENTER); + + { + int h = lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top; + rect.left = lpDrawItem->rcItem.left + 5; + rect.top = lpDrawItem->rcItem.top + ((h-14)>>1); + rect.right = rect.left + 40; + rect.bottom = rect.top + 14; + + FrameRect(lpDrawItem->hDC, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH)); + rect.left++; rect.top++; + rect.right--; rect.bottom--; + SetDCBrushColor(lpDrawItem->hDC, clrPresets->color); + FillRect(lpDrawItem->hDC, &rect, (HBRUSH)GetStockObject(DC_BRUSH)); + } +} + +static BOOL GetClipboardText_Title(char *pOut, int size) +{ + BOOL bResult = FALSE; + + if ( OpenClipboard(NULL) ) + { + HANDLE hData = GetClipboardData(CF_TEXT); + LPCSTR buffer; + + if (hData && (buffer = (LPCSTR)GlobalLock(hData))) + { + // trim initial white spaces + while (*buffer && isspace(*buffer)) + buffer++; + + if (buffer) + { + char *p; + + int n = (int)strlen(buffer); + if (n >= size) + n = size-1; + memcpy(pOut, buffer, n); + pOut[n] = 0; + + // end string on line break and convert tabs to spaces + p = pOut; + while (*p) + { + if (*p == '\r' || *p == '\n') + { + *p = 0; + n = strlen(pOut); + break; + } + else if (*p == '\t') + { + *p = ' '; + } + p++; + } + + // trim trailing white spaces + while (n && isspace(pOut[n-1])) + pOut[--n] = 0; + + if (n) + bResult = TRUE; + } + + GlobalUnlock(hData); + } + + CloseClipboard(); + } + + return bResult; +} + +static void SetNoteTextControl(STICKYNOTE *SN) +{ + CHARFORMAT CF = {0}; + CF.cbSize = sizeof(CHARFORMAT); + CF.dwMask = CFM_COLOR; + CF.crTextColor = SN->FgColor ? (SN->FgColor&0xffffff) : BodyFontColor; + SendMessage(SN->REHwnd, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&CF); + + if (SN->data) // TODO: use EM_STREAMIN + SendMessage(SN->REHwnd, WM_SETTEXT, 0, (LPARAM)(SN->data)); +} + + +static UINT_PTR CALLBACK CFHookProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg == WM_INITDIALOG) + { + // hide color selector + ShowWindow(GetDlgItem(hdlg,0x443), SW_HIDE); + ShowWindow(GetDlgItem(hdlg,0x473), SW_HIDE); + TranslateDialogDefault(hdlg); + } + + return 0; +} + + +int CALLBACK StickyNoteWndProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) +{ + switch (message) + { + case WM_CLOSE: + return TRUE; + + case WM_SIZE: + { + HWND H; + RECT SZ; + + GetClientRect(hdlg,&SZ); + H = GetDlgItem(hdlg,1); + MoveWindow(H, 0, 0, SZ.right,SZ.bottom, TRUE); + + KillTimer(hdlg, 1025); + SetTimer(hdlg, 1025, NOTE_CHANGE_COMMIT_DELAY, 0); + + return TRUE; + } + case WM_TIMER: + if (wParam == 1025) + { + STICKYNOTE *SN = (STICKYNOTE*)GetProp(hdlg,"ctrldata"); + + KillTimer(hdlg, 1025); + JustSaveNotesEx(SN); + } + break; + case WM_MOVE: + { + KillTimer(hdlg, 1025); + SetTimer(hdlg, 1025, NOTE_CHANGE_COMMIT_DELAY, 0); + return TRUE; + } + case WM_CREATE: + { + STICKYNOTE *SN = (STICKYNOTE*)GetProp(hdlg,"ctrldata"); + + CREATESTRUCT *CS = (CREATESTRUCT *)lParam; + HWND H; + DWORD mystyle; + + SN = (STICKYNOTE*)CS->lpCreateParams; + SetProp(hdlg,"ctrldata",(HANDLE)SN); + BringWindowToTop(hdlg); + mystyle = WS_CHILD | WS_VISIBLE | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN; + if (g_ShowScrollbar) mystyle |= WS_VSCROLL; + H = CreateWindow(RICHEDIT_CLASS, 0, mystyle, 0, 0, CS->cx-3-3, CS->cy-3-(3+14), hdlg, (HMENU)1, hmiranda, 0); + SN->REHwnd = H; + SendMessage(H, EM_SETTEXTMODE, TM_PLAINTEXT, 0); + SendMessage(H, EM_LIMITTEXT, MAX_NOTE_LEN, 0); + SendMessage(H, WM_SETFONT, (WPARAM)(SN->pCustomFont ? SN->pCustomFont->hFont : hBodyFont), 1); + SendMessage(H, EM_SETEVENTMASK, 0, ENM_CHANGE | ENM_LINK); + SendMessage(H, EM_SETBKGNDCOLOR, 0, SN->BgColor ? (SN->BgColor&0xffffff) : BodyColor); + SendMessage(H, EM_AUTOURLDETECT, 1, 0); + SetNoteTextControl(SN); + return TRUE; + } + case WM_GETMINMAXINFO: + { + MINMAXINFO *mm = (MINMAXINFO*)lParam; + // min width accomodates frame, buttons and some extra space for sanity + mm->ptMinTrackSize.x = 48+3+3+8 + 40; + // min height allows collapsing entire client area, only leaving frame and caption + mm->ptMinTrackSize.y = 3+3+14; + } + return 0; + case WM_ERASEBKGND: + // no BG needed as edit control takes up entire client area + return TRUE; + case WM_NCPAINT: + // make window borders have the same color as caption + { + STICKYNOTE *SN = (STICKYNOTE*)GetProp(hdlg,"ctrldata"); + + HBRUSH hBkBrush; + RECT rect, wr, r; + //HDC hdc = GetDCEx(hdlg, (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN); + HDC hdc = GetWindowDC(hdlg); + + GetWindowRect(hdlg, &wr); + if (wParam && wParam != 1) + { + SelectClipRgn(hdc, (HRGN)wParam); + OffsetClipRgn(hdc, -wr.left, -wr.top); + } + + rect = wr; + OffsetRect(&rect, -wr.left, -wr.top); + + if (g_isWin2kPlus) + { + hBkBrush = (HBRUSH)GetStockObject(DC_BRUSH); + SetDCBrushColor(hdc, GetCaptionColor((SN && SN->BgColor) ? SN->BgColor : BodyColor)); + } + else + { + hBkBrush = (HBRUSH)CreateSolidBrush( GetCaptionColor((SN && SN->BgColor) ? SN->BgColor : BodyColor) ); + } + + //FillRect(hdc, &rect, hBkBrush); + // draw all frame sides separately to avoid filling client area (which flickers) + { + // top + r.left = rect.left; r.right = rect.right; + r.top = rect.top; r.bottom = r.top + 3+14; + FillRect(hdc, &r, hBkBrush); + // bottom + r.top = rect.bottom - 3; r.bottom = rect.bottom; + FillRect(hdc, &r, hBkBrush); + // left + r.left = rect.left; r.right = r.left + 3; + r.top = rect.top + 3+14; r.bottom = rect.bottom - 3; + FillRect(hdc, &r, hBkBrush); + // right + r.left = rect.right - 3; r.right = rect.right; + FillRect(hdc, &r, hBkBrush); + } + if (hBkBrush && !g_isWin2kPlus) DeleteObject(hBkBrush); + + // paint title bar contents (time stamp and buttons) + + if (SN && SN->title) + { + RECT R; + SelectObject(hdc,hCaptionFont); + R.top = 3+1; R.bottom = 3+11; R.left = 3+2; R.right = rect.right-3-1; + if (g_ShowNoteButtons) + R.right -= 48; + + SetTextColor(hdc,SN->FgColor ? (SN->FgColor&0xffffff) : CaptionFontColor); + SetBkMode(hdc, TRANSPARENT); + DrawText(hdc,SN->title,-1,&R,DT_LEFT | DT_SINGLELINE | DT_END_ELLIPSIS | DT_VCENTER); + } + + if (g_ShowNoteButtons) + { + HICON hcIcon; + if (SN->OnTop) + hcIcon = Skin_GetIconByHandle(hIconLibItem[4]); + else + hcIcon = Skin_GetIconByHandle(hIconLibItem[7]); + DrawIcon(hdc, wr.right - wr.left - 16, 0 + 3, hcIcon); + Skin_ReleaseIcon(hcIcon); + + hcIcon = Skin_GetIconByHandle(hIconLibItem[9]); + DrawIcon(hdc, wr.right - wr.left - 32, 1 + 3, hcIcon); + Skin_ReleaseIcon(hcIcon); + + hcIcon = Skin_GetIconByHandle(hIconLibItem[8]); + DrawIcon(hdc, wr.right - wr.left - 48, 1 + 3, hcIcon); + Skin_ReleaseIcon(hcIcon); + } + + if (wParam && wParam != 1) + { + SelectClipRgn(hdc, NULL); + } + + ReleaseDC(hdlg, hdc); + return TRUE; + } + case WM_NCCALCSIZE: + { + RECT *pRect = wParam ? &((NCCALCSIZE_PARAMS*)lParam)->rgrc[0] : (RECT*)lParam; + pRect->bottom -= 3; + pRect->right -= 3; + pRect->left += 3; + pRect->top += 3+14; + return WVR_REDRAW; + } + case WM_NCACTIVATE: + // update window (so that parts that potentially became visible through activation get redrawn immediately) + RedrawWindow(hdlg, NULL, NULL, RDW_UPDATENOW); + return TRUE; + case WM_NOTIFY: + if (LOWORD(wParam) == 1) + { + char *Buff; + PENLINK PEnLnk = (PENLINK)lParam; + + if (PEnLnk->msg == WM_LBUTTONDOWN) + { + SendDlgItemMessage(hdlg,1,EM_EXSETSEL,0,(LPARAM)&(PEnLnk->chrg)); + Buff = (char*)malloc(PEnLnk->chrg.cpMax - PEnLnk->chrg.cpMin + 1); + SendDlgItemMessage(hdlg,1,EM_GETSELTEXT,0,(LPARAM)Buff); + if ((GetAsyncKeyState(VK_CONTROL) >> 15) != 0) + ShellExecute(hdlg,"open","iexplore",Buff,"",SW_SHOWNORMAL); + else if (g_lpszAltBrowser && *g_lpszAltBrowser) + ShellExecute(hdlg,"open",g_lpszAltBrowser,Buff,"",SW_SHOWNORMAL); + else + ShellExecute(hdlg,"open",Buff,"","",SW_SHOWNORMAL); + SAFE_FREE((void**)&Buff); + return TRUE; + } + return FALSE; + } + break; + case WM_NCHITTEST: + { + int r = DefWindowProc(hdlg,message,wParam,lParam); + // filter out potential hits on windows default title bar buttons + switch (r) + { + case HTSYSMENU: + case HTCLOSE: + case HTMINBUTTON: + case HTMAXBUTTON: + return HTCAPTION; + } + return r; + } + case WM_NCLBUTTONDOWN: + if (wParam == HTCAPTION && g_ShowNoteButtons) + { + long X,Y; + RECT rect; + int Tw; + + GetWindowRect(hdlg, &rect); + Tw = rect.right - rect.left; + + X = LOWORD(lParam) - rect.left; + Y = HIWORD(lParam) - rect.top; + + if (X > Tw - 16) + { + SendMessage(hdlg,WM_COMMAND,IDM_TOGGLEONTOP,0); + return TRUE; + } + else if (X > Tw - 31 && X < Tw - 16) + { + SendMessage(hdlg,WM_COMMAND,IDM_REMOVENOTE,0); + return TRUE; + } + else if (X > Tw - 48 && X < Tw - 32) + { + SendMessage(hdlg,WM_COMMAND,IDM_HIDENOTE,0); + return TRUE; + } + } + return DefWindowProc(hdlg,message,wParam,lParam); + case WM_MEASUREITEM: + { + LPMEASUREITEMSTRUCT lpMeasureItem = (LPMEASUREITEMSTRUCT)lParam; + + if (lpMeasureItem->CtlType != ODT_MENU) + break; + + if (lpMeasureItem->itemID >= IDM_COLORPRESET_BG && lpMeasureItem->itemID <= IDM_COLORPRESET_BG+SIZEOF(clrPresets)) + { + MeasureColorPresetMenuItem(hdlg, lpMeasureItem, clrPresets + (lpMeasureItem->itemID - IDM_COLORPRESET_BG)); + return TRUE; + } + else if (lpMeasureItem->itemID >= IDM_COLORPRESET_FG && lpMeasureItem->itemID <= IDM_COLORPRESET_FG+SIZEOF(clrPresets)) + { + MeasureColorPresetMenuItem(hdlg, lpMeasureItem, clrPresets + (lpMeasureItem->itemID - IDM_COLORPRESET_FG)); + return TRUE; + } + } + break; + case WM_DRAWITEM: + if (!wParam) + { + LPDRAWITEMSTRUCT lpDrawItem = (LPDRAWITEMSTRUCT)lParam; + + if (lpDrawItem->CtlType != ODT_MENU) + break; + + if (lpDrawItem->itemID >= IDM_COLORPRESET_BG && lpDrawItem->itemID <= IDM_COLORPRESET_BG+SIZEOF(clrPresets)) + { + PaintColorPresetMenuItem(lpDrawItem, clrPresets + (lpDrawItem->itemID - IDM_COLORPRESET_BG)); + return TRUE; + } + else if (lpDrawItem->itemID >= IDM_COLORPRESET_FG && lpDrawItem->itemID <= IDM_COLORPRESET_FG+SIZEOF(clrPresets)) + { + PaintColorPresetMenuItem(lpDrawItem, clrPresets + (lpDrawItem->itemID - IDM_COLORPRESET_FG)); + return TRUE; + } + } + break; + case WM_COMMAND: + { + STICKYNOTE *SN = (STICKYNOTE*)GetProp(hdlg,"ctrldata"); + + HWND H; + UINT id; + + switch ( HIWORD(wParam) ) + { + case EN_CHANGE: + case EN_VSCROLL: + case EN_HSCROLL: + { + KillTimer(hdlg,1025); + SetTimer(hdlg, 1025, NOTE_CHANGE_COMMIT_DELAY, 0); + } + break; + } + + id = (UINT) LOWORD(wParam); + + H = SN->REHwnd; + + if (id >= IDM_COLORPRESET_BG && id <= IDM_COLORPRESET_BG+SIZEOF(clrPresets)) + { + SN->BgColor = clrPresets[id-IDM_COLORPRESET_BG].color | 0xff000000; + SendMessage(H, EM_SETBKGNDCOLOR, 0, (LPARAM)(SN->BgColor&0xffffff)); + RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); + JustSaveNotes(); + return FALSE; + } + else if (id >= IDM_COLORPRESET_FG && id <= IDM_COLORPRESET_FG+SIZEOF(clrPresets)) + { + CHARFORMAT CF = {0}; + SN->FgColor = clrPresets[id-IDM_COLORPRESET_FG].color | 0xff000000; + CF.cbSize = sizeof(CHARFORMAT); + CF.dwMask = CFM_COLOR; + CF.crTextColor = SN->FgColor & 0xffffff; + SendMessage(H, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&CF); + RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); + JustSaveNotes(); + return FALSE; + } + + switch (id) + { + case ID_CONTEXTMENUNOTEPOPUP_NEWNOTE: + { + PluginMenuCommandAddNew(0,0); + } + break; + case ID_APPEARANCE_CUSTOMBG: + { + COLORREF custclr[16] = {0}; + CHOOSECOLOR cc = {0}; + COLORREF orgclr = SN->BgColor ? (COLORREF)(SN->BgColor&0xffffff) : (COLORREF)(BodyColor&0xffffff); + cc.lStructSize = sizeof(cc); + cc.hwndOwner = SN->SNHwnd; + cc.rgbResult = orgclr; + cc.Flags = CC_ANYCOLOR | CC_FULLOPEN | CC_RGBINIT | CC_SOLIDCOLOR; + cc.lpCustColors = custclr; + + if (ChooseColor(&cc) && cc.rgbResult != orgclr) + { + SN->BgColor = cc.rgbResult | 0xff000000; + SendMessage(H, EM_SETBKGNDCOLOR, 0, (LPARAM)(SN->BgColor&0xffffff)); + RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); + JustSaveNotes(); + } + } + break; + case ID_APPEARANCE_CUSTOMTEXT: + { + COLORREF custclr[16] = {0}; + CHOOSECOLOR cc = {0}; + COLORREF orgclr = SN->FgColor ? (COLORREF)(SN->FgColor&0xffffff) : (COLORREF)(BodyFontColor&0xffffff); + cc.lStructSize = sizeof(cc); + cc.hwndOwner = SN->SNHwnd; + cc.rgbResult = orgclr; + cc.Flags = CC_ANYCOLOR | CC_FULLOPEN | CC_RGBINIT | CC_SOLIDCOLOR; + cc.lpCustColors = custclr; + + if (ChooseColor(&cc) && cc.rgbResult != orgclr) + { + CHARFORMAT CF = {0}; + SN->FgColor = cc.rgbResult | 0xff000000; + CF.cbSize = sizeof(CHARFORMAT); + CF.dwMask = CFM_COLOR; + CF.crTextColor = SN->FgColor & 0xffffff; + SendMessage(H, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&CF); + RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); + JustSaveNotes(); + } + } + break; + case ID_APPEARANCE_CUSTOMFONT: + { + CHOOSEFONT cf = {0}; + LOGFONT lf = {0}; + + if (SN->pCustomFont) + InitStickyNoteLogFont(SN->pCustomFont, &lf); + else + LoadNRFont(NR_FONTID_BODY, &lf, NULL); + + cf.lStructSize = sizeof(cf); + cf.hwndOwner = SN->SNHwnd; + cf.lpLogFont = &lf; + cf.Flags = CF_EFFECTS | CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_ENABLEHOOK; + cf.lpfnHook = CFHookProc; + + if ( ChooseFont(&cf) ) + { + if (!SN->pCustomFont) + { + SN->pCustomFont = (STICKYNOTEFONT*)malloc(sizeof(STICKYNOTEFONT)); + SN->pCustomFont->hFont = NULL; + } + + SN->pCustomFont->size = (char)lf.lfHeight; + SN->pCustomFont->style = (lf.lfWeight >= FW_BOLD ? DBFONTF_BOLD : 0) | (lf.lfItalic ? DBFONTF_ITALIC : 0) | (lf.lfUnderline ? DBFONTF_UNDERLINE : 0) | (lf.lfStrikeOut ? DBFONTF_STRIKEOUT : 0); + SN->pCustomFont->charset = lf.lfCharSet; + _tcscpy(SN->pCustomFont->szFace, lf.lfFaceName); + + if ( !CreateStickyNoteFont(SN->pCustomFont, &lf) ) + { + // failed + free(SN->pCustomFont); + SN->pCustomFont = NULL; + } + + // clear text first to force a reformatting w.r.t scrollbar + SendMessage(H, WM_SETTEXT, 0, (LPARAM)""); + SendMessage(H, WM_SETFONT, (WPARAM)(SN->pCustomFont ? SN->pCustomFont->hFont : hBodyFont), FALSE); + SetNoteTextControl(SN); + RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); + JustSaveNotes(); + } + } + break; + case ID_BACKGROUNDCOLOR_RESET: + { + SN->BgColor = 0; + SendMessage(H, EM_SETBKGNDCOLOR, 0, (LPARAM)BodyColor); + RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); + JustSaveNotes(); + } + break; + case ID_TEXTCOLOR_RESET: + { + CHARFORMAT CF = {0}; + SN->FgColor = 0; + CF.cbSize = sizeof(CHARFORMAT); + CF.dwMask = CFM_COLOR; + CF.crTextColor = BodyFontColor; + SendMessage(H, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&CF); + RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); + JustSaveNotes(); + } + break; + case ID_FONT_RESET: + { + if (SN->pCustomFont) + { + DeleteObject(SN->pCustomFont->hFont); + free(SN->pCustomFont); + SN->pCustomFont = NULL; + + // clear text first to force a reformatting w.r.t scrollbar + SendMessage(H, WM_SETTEXT, 0, (LPARAM)""); + SendMessage(H, WM_SETFONT, (WPARAM)hBodyFont, FALSE); + SetNoteTextControl(SN); + RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); + JustSaveNotes(); + } + } + break; + case ID_CONTEXTMENUNOTEPOPUP_PASTETITLE: + { + char s[MAX_TITLE_LEN+1]; + if ( GetClipboardText_Title(s, sizeof(s)) ) + { + if (SN->title) + free(SN->title); + SN->title = _strdup(s); + SN->CustomTitle = TRUE; + RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); + JustSaveNotes(); + } + } + break; + case ID_CONTEXTMENUNOTEPOPUP_RESETTITLE: + if (SN->CustomTitle) + { + if (SN->title) + { + free(SN->title); + SN->title = NULL; + } + InitNoteTitle(SN); + RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_INVALIDATE|RDW_FRAME|RDW_UPDATENOW); + JustSaveNotes(); + } + break; + case IDM_REMOVENOTE: + OnDeleteNote(hdlg, SN); + break; + case IDM_HIDENOTE: + { + SN->Visible = FALSE; + ShowWindow(hdlg,SW_HIDE); + JustSaveNotes(); + } + break; + case IDM_COPY: SendMessage(H,WM_COPY,0,0); break; + case IDM_PASTE: SendMessage(H,WM_PASTE,0,0); break; + case IDM_CUT: SendMessage(H,WM_CUT,0,0); break; + case IDM_CLEAR: SendMessage(H,WM_CLEAR,0,0); break; + case IDM_UNDO: SendMessage(H,WM_UNDO,0,0); break; + case IDM_TOGGLEONTOP: + { + SN->OnTop = !SN->OnTop; + SetWindowPos(hdlg, SN->OnTop ? HWND_TOPMOST : HWND_NOTOPMOST, 0,0,0,0, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE); + RedrawWindow(hdlg, NULL, NULL, RDW_FRAME|RDW_INVALIDATE|RDW_UPDATENOW); + JustSaveNotes(); + } + break; + case ID_CONTEXTMENUNOTEPOPUP_VIEWNOTES: + ListNotes(); + break; + case ID_CONTEXTMENUNOTEPOPUP_BRINGALLTOTOP: + BringAllNotesToFront(SN); + break; + } + return TRUE; + } + case WM_NCDESTROY: + { + RemoveProp(hdlg, "ctrldata"); + } + break; + case WM_CONTEXTMENU: + if (DoContextMenu(hdlg,wParam,lParam)) return FALSE; + + default: + return DefWindowProc(hdlg,message,wParam,lParam); + } + return FALSE; +} + + +///////////////////////////////////////////////////////////////////// +// Notes List Dialog (uses same dialog template as reminder list) + +void ListNotes(void) +{ + if (!ListNotesVisible) + { + CreateDialog(hinstance, MAKEINTRESOURCE(IDD_LISTREMINDERS), 0, DlgProcViewNotes); + ListNotesVisible = TRUE; + } + else + { + BringWindowToTop(LV); + } +} + +static void EditNote(STICKYNOTE *SN) +{ + if (!SN) + return; + + if (!SN->Visible) + { + SN->Visible = TRUE; + JustSaveNotes(); + } + + SetWindowPos(SN->SNHwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); + if (!SN->OnTop) + SetWindowPos(SN->SNHwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); + + SetFocus(SN->REHwnd); +} + +char* GetPreviewString(const char *lpsz) +{ + int l; + char *p; + const int MaxLen = 80; + static char s[80+8]; + + if (!lpsz) + return ""; + + // trim leading spaces + while ( iswspace(*lpsz) ) + lpsz++; + + l = strlen(lpsz); + + if (!l) + return ""; + + if (l <= MaxLen) + { + strcpy(s, lpsz); + } + else + { + memcpy(s, lpsz, MaxLen); + s[MaxLen] = '.'; + s[MaxLen+1] = '.'; + s[MaxLen+2] = '.'; + s[MaxLen+3] = 0; + } + + if (!s) + return NULL; + + // convert line breaks and tabs to spaces + + p = s; + + while (*p) + { + if ( iswspace(*p) ) + *p = ' '; + p++; + } + + return s; +} + +static void InitListView(HWND AHLV) +{ + LV_ITEM lvTIt; + int I; + char *S; + char S1[128]; + STICKYNOTE *pNote; + TREEELEMENT *TTE; + + char *V = Translate("V"); + char *T = Translate("T"); + + ListView_SetHoverTime(AHLV,700); + ListView_SetExtendedListViewStyle(AHLV,LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_TRACKSELECT); + ListView_DeleteAllItems(AHLV); + + I = 0; + TTE = g_Stickies; + while (TTE) + { + pNote = (STICKYNOTE*)TTE->ptrdata; + + lvTIt.mask = LVIF_TEXT; + + if (!pNote->CustomTitle || !pNote->title) + GetTriggerTimeString(&pNote->ID, S1, sizeof(S1), TRUE); + + lvTIt.iItem = I; + lvTIt.iSubItem = 0; + lvTIt.pszText = (pNote->CustomTitle && pNote->title) ? pNote->title : S1; + lvTIt.cchTextMax = strlen(S1); + ListView_InsertItem(AHLV,&lvTIt); + + if (pNote->Visible) + { + lvTIt.iItem = I; + lvTIt.iSubItem = 1; + lvTIt.pszText = V; + lvTIt.cchTextMax = strlen(lvTIt.pszText); + ListView_SetItem(AHLV,&lvTIt); + } + + if (pNote->OnTop) + { + lvTIt.iItem = I; + lvTIt.iSubItem = 2; + lvTIt.pszText = T; + lvTIt.cchTextMax = strlen(lvTIt.pszText); + ListView_SetItem(AHLV,&lvTIt); + } + + S = GetPreviewString(pNote->data); + lvTIt.iItem = I; + lvTIt.iSubItem = 3; + lvTIt.pszText = S; + lvTIt.cchTextMax = strlen(S); + ListView_SetItem(AHLV,&lvTIt); + + I++; + TTE = (TREEELEMENT*)TTE->next; + } + + ListView_SetItemState(AHLV,0,LVIS_SELECTED,LVIS_SELECTED); +} + +static BOOL DoListContextMenu(HWND AhWnd,WPARAM wParam,LPARAM lParam,STICKYNOTE *pNote) +{ + HWND hwndListView; + HMENU hMenuLoad,FhMenu; + MENUITEMINFO mii; + + hwndListView = (HWND)wParam; + if (hwndListView != GetDlgItem(AhWnd,IDC_LISTREMINDERS)) return FALSE; + hMenuLoad = LoadMenu(hinstance,"MNU_NOTELISTPOPUP"); + FhMenu = GetSubMenu(hMenuLoad,0); + + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_STATE; + mii.fState = MFS_DEFAULT; + if (!pNote) + mii.fState |= MFS_GRAYED; + SetMenuItemInfo(FhMenu, ID_CONTEXTMENUNOTELISTVIEW_EDITNOTE, FALSE, &mii); + + if (!pNote) + { + EnableMenuItem(FhMenu, IDM_REMOVENOTE, MF_GRAYED|MF_BYCOMMAND); + EnableMenuItem(FhMenu, ID_CONTEXTMENUNOTELISTVIEW_TOGGLEVISIBILITY, MF_GRAYED|MF_BYCOMMAND); + EnableMenuItem(FhMenu, IDM_TOGGLEONTOP, MF_GRAYED|MF_BYCOMMAND); + } + else + { + if (pNote->Visible) + CheckMenuItem(FhMenu, ID_CONTEXTMENUNOTELISTVIEW_TOGGLEVISIBILITY, MF_CHECKED|MF_BYCOMMAND); + if (pNote->OnTop) + CheckMenuItem(FhMenu, IDM_TOGGLEONTOP, MF_CHECKED|MF_BYCOMMAND); + } + + CallService(MS_LANGPACK_TRANSLATEMENU,(DWORD)FhMenu,0); + TrackPopupMenu(FhMenu,TPM_LEFTALIGN | TPM_RIGHTBUTTON,LOWORD(lParam),HIWORD(lParam),0,AhWnd,0); + DestroyMenu(hMenuLoad); + + return TRUE; +} + + +int CALLBACK DlgProcViewNotes(HWND Dialog,UINT Message,WPARAM wParam,LPARAM lParam) +{ + LV_COLUMN lvCol; + NMLISTVIEW *NM; + char *S; + int I; + + switch (Message) + { + case WM_SIZE: + { + OnListResize(Dialog); + UpdateGeomFromWnd(Dialog, g_notesListGeom, NULL, 0); + break; + } + case WM_MOVE: + UpdateGeomFromWnd(Dialog, g_notesListGeom, NULL, 0); + break; + case WM_GETMINMAXINFO: + { + MINMAXINFO *mm = (MINMAXINFO*)lParam; + mm->ptMinTrackSize.x = 394; + mm->ptMinTrackSize.y = 300; + } + return 0; + case WM_RELOAD: + { + SetDlgItemText(Dialog,IDC_REMINDERDATA,""); + InitListView(GetDlgItem(Dialog,IDC_LISTREMINDERS)); + return TRUE; + } + case WM_CONTEXTMENU: + { + HWND H; + STICKYNOTE *pNote = NULL; + + H = GetDlgItem(Dialog,IDC_LISTREMINDERS); + if ( ListView_GetSelectedCount(H) ) + { + I = ListView_GetSelectionMark(H); + if (I != -1) + { + pNote = (STICKYNOTE*)TreeGetAt(g_Stickies, I); + } + } + + if (DoListContextMenu(Dialog, wParam, lParam, pNote)) + return TRUE; + } + break; + case WM_INITDIALOG: + { + HWND H; + + HICON hIcon = Skin_GetIconByHandle(hIconLibItem[13], ICON_SMALL); + SendMessage(Dialog, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIcon); + hIcon = Skin_GetIconByHandle(hIconLibItem[13], ICON_BIG); + SendMessage(Dialog, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hIcon); + + SetWindowText(Dialog, _T("Notes")); + + TranslateDialogDefault(Dialog); + + SetDlgItemText(Dialog,IDC_REMINDERDATA,""); + + H = GetDlgItem(Dialog,IDC_LISTREMINDERS); + lvCol.mask = LVCF_TEXT | LVCF_WIDTH; + + S = Translate("Note text"); + lvCol.pszText = S; + lvCol.cchTextMax = strlen(S); + lvCol.cx = g_notesListColGeom[3]; + ListView_InsertColumn(H,0,&lvCol); + lvCol.mask = LVCF_TEXT | LVCF_WIDTH; + + S = Translate("T"); + lvCol.pszText = S; + lvCol.cchTextMax = strlen(S); + lvCol.cx = g_notesListColGeom[2]; + ListView_InsertColumn(H,0,&lvCol); + lvCol.mask = LVCF_TEXT | LVCF_WIDTH; + + S = Translate("V"); + lvCol.pszText = S; + lvCol.cchTextMax = strlen(S); + lvCol.cx = g_notesListColGeom[1]; + ListView_InsertColumn(H,0,&lvCol); + lvCol.mask = LVCF_TEXT | LVCF_WIDTH; + + S = Translate("Date/Title"); + lvCol.pszText = S; + lvCol.cchTextMax = strlen(S); + lvCol.cx = g_notesListColGeom[0]; + ListView_InsertColumn(H,0,&lvCol); + + InitListView(H); + SetWindowLong(GetDlgItem(H, 0), GWL_ID, IDC_LISTREMINDERS_HEADER); + LV = Dialog; + + if (g_notesListGeom[1] && g_notesListGeom[2]) + { + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement(Dialog, &wp); + wp.rcNormalPosition.left = g_notesListGeom[0]; + wp.rcNormalPosition.top = g_notesListGeom[1]; + wp.rcNormalPosition.right = g_notesListGeom[2] + g_notesListGeom[0]; + wp.rcNormalPosition.bottom = g_notesListGeom[3] + g_notesListGeom[1]; + SetWindowPlacement(Dialog, &wp); + } + return TRUE; + } + case WM_CLOSE: + { + DestroyWindow(Dialog); + ListNotesVisible = FALSE; + return TRUE; + } + case WM_DESTROY: + ListNotesVisible = FALSE; + CallService(MS_SKIN2_RELEASEICONBIG, (WPARAM)SendMessage(Dialog, WM_SETICON, ICON_BIG, (LPARAM)NULL), 0); + CallService(MS_SKIN2_RELEASEICON, (WPARAM)SendMessage(Dialog, WM_SETICON, ICON_SMALL, (LPARAM)NULL), 0); + return TRUE; + case WM_NOTIFY: + { + if (wParam == IDC_LISTREMINDERS) + { + NM = (NMLISTVIEW *)lParam; + switch (NM->hdr.code) + { + case LVN_ITEMCHANGED: + { + S = ((STICKYNOTE*)TreeGetAt(g_Stickies,NM->iItem))->data; + SetDlgItemText(Dialog,IDC_REMINDERDATA,S); + } + break; + case NM_DBLCLK: + { + HWND H; + + H = GetDlgItem(Dialog,IDC_LISTREMINDERS); + if ( ListView_GetSelectedCount(H) ) + { + I = ListView_GetSelectionMark(H); + if (I != -1) + { + EditNote((STICKYNOTE *)TreeGetAt(g_Stickies, I)); + } + } + } + break; + } + } + else if (wParam == IDC_LISTREMINDERS_HEADER) + { + NMHEADER *NM = (NMHEADER*)lParam; + switch (NM->hdr.code) + { + case HDN_ENDTRACK: + UpdateGeomFromWnd(Dialog, NULL, g_notesListColGeom, SIZEOF(g_notesListColGeom)); + break; + } + } + } + break; + case WM_COMMAND: + { + switch(LOWORD(wParam)) + { + case ID_CONTEXTMENUNOTELISTVIEW_EDITNOTE: + { + HWND H; + + H = GetDlgItem(Dialog,IDC_LISTREMINDERS); + if ( ListView_GetSelectedCount(H) ) + { + I = ListView_GetSelectionMark(H); + if (I != -1) + { + EditNote((STICKYNOTE*)TreeGetAt(g_Stickies, I)); + } + } + } + return TRUE; + case ID_CONTEXTMENUNOTELISTVIEW_TOGGLEVISIBILITY: + { + HWND H; + + H = GetDlgItem(Dialog,IDC_LISTREMINDERS); + if ( ListView_GetSelectedCount(H) ) + { + I = ListView_GetSelectionMark(H); + if (I != -1) + { + STICKYNOTE *SN = (STICKYNOTE*)TreeGetAt(g_Stickies, I); + SN->Visible = !SN->Visible; + ShowWindow(SN->SNHwnd,SN->Visible?SW_SHOWNA:SW_HIDE); + JustSaveNotes(); + } + } + } + return TRUE; + case IDM_TOGGLEONTOP: + { + HWND H; + + H = GetDlgItem(Dialog,IDC_LISTREMINDERS); + if ( ListView_GetSelectedCount(H) ) + { + I = ListView_GetSelectionMark(H); + if (I != -1) + { + STICKYNOTE *SN = (STICKYNOTE*)TreeGetAt(g_Stickies,I); + SN->OnTop = !SN->OnTop; + SetWindowPos(SN->SNHwnd, SN->OnTop ? HWND_TOPMOST : HWND_NOTOPMOST, 0,0,0,0, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE); + RedrawWindow(SN->SNHwnd, NULL, NULL, RDW_FRAME|RDW_INVALIDATE|RDW_UPDATENOW); + JustSaveNotes(); + } + } + } + return TRUE; + case IDC_CLOSE: + { + DestroyWindow(Dialog); + ListNotesVisible = FALSE; + return TRUE; + } + case ID_CONTEXTMENUNOTEPOPUP_NEWNOTE: + case IDC_ADDNEWREMINDER: + { + PluginMenuCommandAddNew(0,0); + return TRUE; + } + case ID_CONTEXTMENUNOTELISTVIEW_DELETEALLNOTES: + { + PluginMenuCommandDeleteAll(0,0); + return TRUE; + } + case IDM_REMOVENOTE: + { + HWND H; + + H = GetDlgItem(Dialog,IDC_LISTREMINDERS); + if ( ListView_GetSelectedCount(H) ) + { + I = ListView_GetSelectionMark(H); + if (I != -1) + { + OnDeleteNote(Dialog, (STICKYNOTE*)TreeGetAt(g_Stickies, I)); + } + } + } + return TRUE; + case ID_CONTEXTMENUNOTELISTVIEW_SHOW: + { + ShowHideNotes(); + return TRUE; + } + case ID_CONTEXTMENUNOTEPOPUP_BRINGALLTOTOP: + { + BringAllNotesToFront(NULL); + return TRUE; + } + } + } + } + return FALSE; +} diff --git a/plugins/!NotAdopted/NotesAndReminders/src/options.cpp b/plugins/!NotAdopted/NotesAndReminders/src/options.cpp new file mode 100644 index 0000000000..8e15946db9 --- /dev/null +++ b/plugins/!NotAdopted/NotesAndReminders/src/options.cpp @@ -0,0 +1,637 @@ +#include "globals.h" + +#ifndef OFN_DONTADDTORECENT +#define OFN_DONTADDTORECENT 0x02000000 +#endif + + +// min allowed alpha (don't want 0 because it's a waste of resources as well as might confuse user) +#define MIN_ALPHA 30 + + +#define IDC_RESET 1007 +#define IDC_SHOWNOTES 1010 +#define IDC_ADDCONTACTMENU 1011 +#define IDC_NOTEWIDTH 1012 +#define IDC_NOTEHEIGHT 1013 +#define IDC_TRANSTRACK 1014 +#define IDC_REMINDEMAIL 1017 +#define IDC_SHOWSCROLLBAR 1018 +#define IDC_SHOWBUTTONS 1019 +#define IDC_ADDREMINDERCLOSES 1020 +#define IDC_USEMCI 1023 +#define PSM_CHANGED (WM_USER + 104) + + +extern HANDLE hkFontChange; +extern HANDLE hkColorChange; + +BOOL g_CloseAfterAddReminder, g_UseDefaultPlaySound; +HICON g_hReminderIcon = NULL; + +LOGFONT lfBody,lfCaption; +HFONT hBodyFont = NULL, hCaptionFont = NULL; +long BodyColor; +long CaptionFontColor,BodyFontColor; +BOOL g_ShowNotesAtStart,g_ShowScrollbar,g_AddContListMI,g_ShowNoteButtons; +int g_NoteTitleDate, g_NoteTitleTime; +int g_NoteWidth,g_NoteHeight; +int g_Transparency; +char *g_RemindSMS = NULL; +BOOL g_isWin2kPlus = TRUE; + +TCHAR *g_lpszAltBrowser = NULL; + +int g_reminderListGeom[4] = {0}; +int g_reminderListColGeom[2] = { 150, 205 }; +int g_notesListGeom[4] = {0}; +int g_notesListColGeom[4] = { 150, 20, 20, 165 }; + + +#define NRCDEFAULT_BODYCLR RGB(255,255,0) + + +struct DateFormat +{ + LPCSTR lpszUI; + LPCSTR lpszFmt; +} +static dateFormats[] = +{ + { "1981-12-31", "yyyy'-'MM'-'dd" }, + { "31-12-1981", "dd'-'MM'-'yyyy" }, + { "12-31-1981", "MM'-'dd'-'yyyy" }, + { "1981-dec-31", "yyyy'-'MMM'-'dd" }, + { "31-dec-1981", "dd'-'MMM'-'yyyy" }, + { "dec-31-1981", "MMM'-'dd'-'yyyy" }, + { "1981/12/31", "yyyy'/'MM'/'dd" }, + { "31/12/1981", "dd'/'MM'/'yyyy" }, + { "12/31/1981", "MM'/'dd'/'yyyy" }, + { "1981/dec/31", "yyyy'/'MMM'/'dd" }, + { "31/dec/1981", "dd'/'MMM'/'yyyy" }, + { "dec/31/1981", "MMM'/'dd'/'yyyy" }, + { "1981 dec 31", "yyyy MMM dd" }, + { "31 dec 1981", "dd MMM yyyy" }, + { "dec 31 1981", "MMM dd yyyy" } +}; + +struct TimeFormat +{ + LPCSTR lpszUI; + LPCSTR lpszFmt; +} +static timeFormats[] = +{ + { "19:30:00", "HH':'mm':'ss" }, + { "19:30", "HH':'mm'" }, + { "7:30:00 PM", "hh':'mm':'ss tt" }, + { "7:30 PM", "hh':'mm tt" }, + { "7:30:00P", "hh':'mm':'sst" }, + { "7:30P", "hh':'mmt" } +}; + + +struct FontOptionsList +{ + TCHAR *szDescr; + COLORREF defColour; + TCHAR *szDefFace; + BYTE defStyle; + char defSize; + TCHAR *szBkgName; +} +static fontOptionsList[] = +{ + {LPGENT("Sticky Note Caption"), RGB(0,0,0), _T("Small Fonts"), 0, 7, LPGENT("Sticky Note Background Color")}, + //{LPGENT("Sticky Note Caption"), RGB(0,0,0), _T("Terminal"), 0, 6, LPGENT("Sticky Note Background Color")}, + //{LPGENT("Sticky Note Caption"), RGB(0,0,0), _T("MS Serif"), 0, 7, LPGENT("Sticky Note Background Color")}, + //{LPGENT("Sticky Note Body"), RGB(0,0,0), _T("Tahoma"), 0, 8, LPGENT("Sticky Note Background Color")}, + {LPGENT("Sticky Note Body"), RGB(0,0,0), _T("System"), DBFONTF_BOLD, 10, LPGENT("Sticky Note Background Color")}, +}; + + +struct ColourOptionsList +{ + TCHAR *szName; + char *szSettingName; + COLORREF defColour; +} +static colourOptionsList[] = +{ + {LPGENT("Sticky Note Background Color"), "BodyColor", NRCDEFAULT_BODYCLR} +}; + + +LPCSTR GetDateFormatStr() +{ + return dateFormats[g_NoteTitleDate ? g_NoteTitleDate-1 : 0].lpszFmt; +} + +LPCSTR GetTimeFormatStr() +{ + return timeFormats[g_NoteTitleTime ? g_NoteTitleTime-1 : 0].lpszFmt; +} + +#if defined( _UNICODE ) +static BYTE MsgDlgGetFontDefaultCharset(const TCHAR* szFont) +{ + return DEFAULT_CHARSET; +} +#else +// get font charset according to current CP +static BYTE MsgDlgGetCPDefaultCharset() +{ + switch (GetACP()) { + case 1250: + return EASTEUROPE_CHARSET; + case 1251: + return RUSSIAN_CHARSET; + case 1252: + return ANSI_CHARSET; + case 1253: + return GREEK_CHARSET; + case 1254: + return TURKISH_CHARSET; + case 1255: + return HEBREW_CHARSET; + case 1256: + return ARABIC_CHARSET; + case 1257: + return BALTIC_CHARSET; + case 1361: + return JOHAB_CHARSET; + case 874: + return THAI_CHARSET; + case 932: + return SHIFTJIS_CHARSET; + case 936: + return GB2312_CHARSET; + case 949: + return HANGEUL_CHARSET; + case 950: + return CHINESEBIG5_CHARSET; + default: + return DEFAULT_CHARSET; + } +} + +static int CALLBACK EnumFontFamExProc(const LOGFONT *lpelfe, const TEXTMETRIC *lpntme, DWORD FontType, LPARAM lParam) +{ + *(int*)lParam = 1; + return 0; +} + +// get font charset according to current CP, if available for specified font +static BYTE MsgDlgGetFontDefaultCharset(const TCHAR* szFont) +{ + HDC hdc; + LOGFONT lf = {0}; + int found = 0; + + _tcscpy(lf.lfFaceName, szFont); + lf.lfCharSet = MsgDlgGetCPDefaultCharset(); + + // check if the font supports specified charset + hdc = GetDC(0); + EnumFontFamiliesEx(hdc, &lf, &EnumFontFamExProc, (LPARAM)&found, 0); + ReleaseDC(0, hdc); + + if (found) + return lf.lfCharSet; + else // no, give default + return DEFAULT_CHARSET; +} +#endif + + +static void InitFonts() +{ + ZeroMemory(&lfBody,sizeof(LOGFONT)); + ZeroMemory(&lfCaption,sizeof(LOGFONT)); + + LoadNRFont(NR_FONTID_CAPTION, &lfCaption, (COLORREF*)&CaptionFontColor); + LoadNRFont(NR_FONTID_BODY, &lfBody, (COLORREF*)&BodyFontColor); + + if (hBodyFont) + DeleteObject(hBodyFont); + if (hCaptionFont) + DeleteObject(hCaptionFont); + + hBodyFont = CreateFontIndirect(&lfBody); + hCaptionFont = CreateFontIndirect(&lfCaption); +} + + +static int FS_FontsChanged(WPARAM wParam, LPARAM lParam) +{ + InitFonts(); + + SaveNotes(); + LoadNotes(FALSE); + + return 0; +} + +static int FS_ColorChanged(WPARAM wParam, LPARAM lParam) +{ + LoadNRFont(NR_FONTID_CAPTION, &lfCaption, (COLORREF*)&CaptionFontColor); + LoadNRFont(NR_FONTID_BODY, &lfBody, (COLORREF*)&BodyFontColor); + + BodyColor = DBGetContactSettingDword(NULL, MODULENAME, colourOptionsList[0].szSettingName, colourOptionsList[0].defColour); + + SaveNotes(); + LoadNotes(FALSE); + + return 0; +} + +void RegisterFontServiceFonts() +{ + HDC hDC; + int nFontScale; + FontIDT fontid = {0}; + ColourIDT colorid = {0}; + char szTemp[100]; + int i; + + fontid.cbSize = sizeof(FontIDT); + + mir_sntprintf(fontid.group, SIZEOF(fontid.group), _T("%s"), LPGENT(SECTIONNAME)); + mir_sntprintf(fontid.backgroundGroup, SIZEOF(fontid.backgroundGroup), _T("%s"), LPGENT(SECTIONNAME)); + strncpy(fontid.dbSettingsGroup, MODULENAME, SIZEOF(fontid.dbSettingsGroup)); + fontid.flags = FIDF_ALLOWREREGISTER | FIDF_DEFAULTVALID | FIDF_SAVEPOINTSIZE; + + hDC = GetDC(NULL); + nFontScale = GetDeviceCaps(hDC, LOGPIXELSY); + ReleaseDC(NULL, hDC); + + for (i = 0; i < SIZEOF(fontOptionsList); i++) + { + fontid.order = i; + mir_snprintf(szTemp, SIZEOF(szTemp), "Font%d", i); + strncpy(fontid.prefix, szTemp, SIZEOF(fontid.prefix)); + _tcsncpy(fontid.name, fontOptionsList[i].szDescr, SIZEOF(fontid.name)); + fontid.deffontsettings.colour = fontOptionsList[i].defColour; + + fontid.deffontsettings.size = (char)-MulDiv(fontOptionsList[i].defSize, nFontScale, 72); + //fontid.deffontsettings.size = fontOptionsList[i].defSize; + + fontid.deffontsettings.style = fontOptionsList[i].defStyle; + fontid.deffontsettings.charset = MsgDlgGetFontDefaultCharset(fontOptionsList[i].szDefFace); + _tcsncpy(fontid.deffontsettings.szFace, fontOptionsList[i].szDefFace, SIZEOF(fontid.deffontsettings.szFace)); + _tcsncpy(fontid.backgroundName, fontOptionsList[i].szBkgName, SIZEOF(fontid.backgroundName)); + + FontRegister(&fontid); + } + + colorid.cbSize = sizeof(ColourIDT); + + mir_sntprintf(colorid.group, SIZEOF(colorid.group), _T("%s"), LPGENT(SECTIONNAME)); + strncpy(colorid.dbSettingsGroup, MODULENAME, SIZEOF(fontid.dbSettingsGroup)); + colorid.flags = 0; + + for (i = 0; i < SIZEOF(colourOptionsList); i++) + { + colorid.order = i; + _tcsncpy(colorid.name, colourOptionsList[i].szName, SIZEOF(colorid.name)); + colorid.defcolour = colourOptionsList[i].defColour; + strncpy(colorid.setting, colourOptionsList[i].szSettingName, SIZEOF(colorid.setting)); + + ColourRegister(&colorid); + } + + hkFontChange = HookEvent(ME_FONT_RELOAD, FS_FontsChanged); + hkColorChange = HookEvent(ME_COLOUR_RELOAD, FS_ColorChanged); +} + +void LoadNRFont(int i, LOGFONT *lf, COLORREF *colour) +{ + COLORREF col; + FontIDT fontid = {0}; + + fontid.cbSize = sizeof(fontid); + _tcsncpy(fontid.group, LPGENT(SECTIONNAME), SIZEOF(fontid.group)); + _tcsncpy(fontid.name, fontOptionsList[i].szDescr, SIZEOF(fontid.name)); + + col = CallService(MS_FONT_GETT, (WPARAM)&fontid, (LPARAM)lf); + + if (colour) + { + *colour = col; + } +} + + +static void TrimString(TCHAR *s) +{ + TCHAR *start; + TCHAR *end; + UINT n; + + if (!s || !*s) + { + return; + } + + start = s; + n = _tcslen(s) - 1; + + end = s + n; + + if (!_istspace(*start) && !_istspace(*end)) + { + // nothing to trim + return; + } + + // scan past leading spaces + while (*start && _istspace(*start)) start++; + + if (!*start) + { + // empty string + *s = 0; + return; + } + + // trim trailing spaces + while ( _istspace(*end) ) end--; + end[1] = 0; + + if (start > s) + { + // remove leading spaces + memmove(s, start, ((UINT)(end-start)+2)*sizeof(TCHAR)); + } +} + + +int CALLBACK DlgProcOptions(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) +{ + BOOL LB; + WORD SzT; + void *P; + int i; + + switch (message) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hdlg); + SendDlgItemMessage(hdlg,IDC_TRANSTRACK,TBM_SETRANGE,TRUE,MAKELONG(0,255-MIN_ALPHA)); + SendDlgItemMessage(hdlg,IDC_TRANSTRACK,TBM_SETPOS,TRUE,255-g_Transparency); + SendDlgItemMessage(hdlg,IDC_SHOWNOTES,BM_SETCHECK,(WPARAM)!g_ShowNotesAtStart,0); + SendDlgItemMessage(hdlg,IDC_SHOWBUTTONS,BM_SETCHECK,(WPARAM)g_ShowNoteButtons,0); + SendDlgItemMessage(hdlg,IDC_SHOWSCROLLBAR,BM_SETCHECK,(WPARAM)g_ShowScrollbar,0); // 4.2 + SendDlgItemMessage(hdlg,IDC_ADDCONTACTMENU,BM_SETCHECK,(WPARAM)g_AddContListMI,0); + SetDlgItemInt(hdlg,IDC_NOTEWIDTH,g_NoteWidth,FALSE); + SetDlgItemInt(hdlg,IDC_NOTEHEIGHT,g_NoteHeight,FALSE); + SendDlgItemMessage(hdlg,IDC_ADDREMINDERCLOSES,BM_SETCHECK,(WPARAM)g_CloseAfterAddReminder,0); + SendDlgItemMessage(hdlg,IDC_USEMCI,BM_SETCHECK,(WPARAM)!g_UseDefaultPlaySound,0); + + SendDlgItemMessage(hdlg,IDC_COMBODATE,CB_RESETCONTENT,0,0); + SendDlgItemMessage(hdlg,IDC_COMBOTIME,CB_RESETCONTENT,0,0); + for (i=0; icode == PSN_APPLY) + { + g_ShowNotesAtStart = !(BOOL)SendDlgItemMessage(hdlg,IDC_SHOWNOTES,BM_GETCHECK,0,0); + g_ShowNoteButtons = (BOOL)SendDlgItemMessage(hdlg,IDC_SHOWBUTTONS,BM_GETCHECK,0,0); + g_ShowScrollbar = (BOOL)SendDlgItemMessage(hdlg,IDC_SHOWSCROLLBAR,BM_GETCHECK,0,0); // 4.2 + g_AddContListMI = (BOOL)SendDlgItemMessage(hdlg,IDC_ADDCONTACTMENU,BM_GETCHECK,0,0); + g_NoteWidth = GetDlgItemInt(hdlg,IDC_NOTEWIDTH,&LB,FALSE); + g_NoteHeight = GetDlgItemInt(hdlg,IDC_NOTEHEIGHT,&LB,FALSE); + g_Transparency = 255-SendDlgItemMessage(hdlg,IDC_TRANSTRACK,TBM_GETPOS,0,0); + g_CloseAfterAddReminder = (BOOL)SendDlgItemMessage(hdlg,IDC_ADDREMINDERCLOSES,BM_GETCHECK,0,0); + g_UseDefaultPlaySound = !(BOOL)SendDlgItemMessage(hdlg,IDC_USEMCI,BM_GETCHECK,0,0); + g_NoteTitleDate = (SendDlgItemMessage(hdlg,IDC_COMBODATE,CB_GETCURSEL,0,0) + 1) % SendDlgItemMessage(hdlg,IDC_COMBODATE,CB_GETCOUNT,0,0); + g_NoteTitleTime = (SendDlgItemMessage(hdlg,IDC_COMBOTIME,CB_GETCURSEL,0,0) + 1) % SendDlgItemMessage(hdlg,IDC_COMBOTIME,CB_GETCOUNT,0,0); + if (g_NoteWidth < 179) + { + g_NoteWidth = 179; + SetDlgItemInt(hdlg,IDC_NOTEWIDTH,g_NoteWidth,FALSE); + } + if (g_NoteHeight < 35) + { + g_NoteHeight = 35; + SetDlgItemInt(hdlg,IDC_NOTEHEIGHT,g_NoteHeight,FALSE); + } + SzT = (WORD)SendDlgItemMessage(hdlg,IDC_REMINDEMAIL,WM_GETTEXTLENGTH,0,0); + if (SzT != 0) + { + g_RemindSMS = (char*)realloc(g_RemindSMS,SzT+1); + SendDlgItemMessage(hdlg,IDC_REMINDEMAIL,WM_GETTEXT,SzT+1,(LPARAM)g_RemindSMS); + } + P = g_RemindSMS; + WriteSettingBlob(0,MODULENAME,"RemindEmail",SzT,P); + + SzT = (WORD)SendDlgItemMessage(hdlg,IDC_EDIT_ALTBROWSER,WM_GETTEXTLENGTH,0,0); + if (SzT != 0) + { + g_lpszAltBrowser = (TCHAR*)mir_realloc(g_lpszAltBrowser,SzT+1); + SendDlgItemMessage(hdlg,IDC_EDIT_ALTBROWSER,WM_GETTEXT,SzT+1,(LPARAM)g_lpszAltBrowser); + TrimString(g_lpszAltBrowser); + if (!*g_lpszAltBrowser) + { + mir_free(g_lpszAltBrowser); + g_lpszAltBrowser = NULL; + } + } + else if (g_lpszAltBrowser) + { + mir_free(g_lpszAltBrowser); + g_lpszAltBrowser = NULL; + } + SetDlgItemText(hdlg,IDC_EDIT_ALTBROWSER,g_lpszAltBrowser ? g_lpszAltBrowser : _T("")); + if (g_lpszAltBrowser) + DBWriteContactSettingString(0,MODULENAME,"AltBrowser",g_lpszAltBrowser); + else + DBDeleteContactSetting(0,MODULENAME,"AltBrowser"); + + WriteSettingInt(0,MODULENAME,"ShowNotesAtStart",g_ShowNotesAtStart); + WriteSettingInt(0,MODULENAME,"ShowNoteButtons",g_ShowNoteButtons); + WriteSettingInt(0,MODULENAME,"ShowScrollbar",g_ShowScrollbar); // 4.2 + WriteSettingInt(0,MODULENAME,"AddContactMenuItems",g_AddContListMI); + WriteSettingInt(0,MODULENAME,"NoteWidth",g_NoteWidth); + WriteSettingInt(0,MODULENAME,"NoteHeight",g_NoteHeight); + WriteSettingInt(0,MODULENAME,"Transparency",g_Transparency); + WriteSettingInt(0,MODULENAME,"NoteTitleDate",g_NoteTitleDate); + WriteSettingInt(0,MODULENAME,"NoteTitleTime",g_NoteTitleTime); + WriteSettingInt(0,MODULENAME,"CloseAfterAddReminder",g_CloseAfterAddReminder); + WriteSettingInt(0,MODULENAME,"UseMCI",!g_UseDefaultPlaySound); + SaveNotes(); + LoadNotes(FALSE); + return TRUE; + } + break; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_BTN_BROWSEBROWSER: + { + TCHAR s[MAX_PATH]; + + OPENFILENAME ofn = {0}; +#if defined(WINVER) && _WIN32_WINNT >= 0x0500 + ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; +#else + ofn.lStructSize = sizeof(ofn); +#endif + ofn.hwndOwner = hdlg; + ofn.lpstrFilter = "Executable Files\0*.exe\0All Files\0*.*\0\0"; + ofn.lpstrFile = s; + ofn.nMaxFile = SIZEOF(s); + ofn.lpstrTitle = Translate("Select Executable"); + ofn.lpstrInitialDir = "."; + ofn.Flags = OFN_FILEMUSTEXIST|OFN_LONGNAMES; + if ( IsWinVer98Plus() ) + { + ofn.Flags |= OFN_ENABLESIZING; + if (g_isWin2kPlus) + ofn.Flags |= OFN_DONTADDTORECENT; + } + + SendDlgItemMessage(hdlg,IDC_EDIT_ALTBROWSER,WM_GETTEXT,(WPARAM)ofn.nMaxFile,(LPARAM)s); + + if ( GetOpenFileName(&ofn) ) + { + SetDlgItemText(hdlg,IDC_EDIT_ALTBROWSER,s); + } + } + break; + case IDC_RESET: + { + SAFE_FREE((void**)&g_RemindSMS); + SetDlgItemText(hdlg,IDC_REMINDEMAIL,""); + if (g_lpszAltBrowser) + { + mir_free(g_lpszAltBrowser); + g_lpszAltBrowser = NULL; + } + SetDlgItemText(hdlg,IDC_EDIT_ALTBROWSER,""); + g_ShowNotesAtStart = TRUE; + g_AddContListMI = TRUE; + g_ShowScrollbar = TRUE; // 4.2 + g_ShowNoteButtons = TRUE; + g_NoteTitleDate = 1; + g_NoteTitleTime = 1; + g_CloseAfterAddReminder = TRUE; + g_UseDefaultPlaySound = FALSE; + SendDlgItemMessage(hdlg,IDC_SHOWNOTES,BM_SETCHECK,!g_ShowNotesAtStart,0); + SendDlgItemMessage(hdlg,IDC_ADDCONTACTMENU,BM_SETCHECK,g_AddContListMI,0); + SendDlgItemMessage(hdlg,IDC_SHOWSCROLLBAR,BM_SETCHECK,g_ShowScrollbar,0); + SendDlgItemMessage(hdlg,IDC_SHOWBUTTONS,BM_SETCHECK,(WPARAM)g_ShowNoteButtons,0); + SendDlgItemMessage(hdlg,IDC_ADDREMINDERCLOSES,BM_SETCHECK,g_CloseAfterAddReminder,0); + SendDlgItemMessage(hdlg,IDC_USEMCI,BM_SETCHECK,!g_UseDefaultPlaySound,0); + SendDlgItemMessage(hdlg,IDC_COMBODATE,CB_SETCURSEL,(WPARAM)(g_NoteTitleDate-1),0); + SendDlgItemMessage(hdlg,IDC_COMBOTIME,CB_SETCURSEL,(WPARAM)(g_NoteTitleTime-1),0); + g_NoteWidth = 179; // 4.2 + g_NoteHeight = 35; + SetDlgItemInt(hdlg,IDC_NOTEWIDTH,g_NoteWidth,FALSE); + SetDlgItemInt(hdlg,IDC_NOTEHEIGHT,g_NoteHeight,FALSE); + g_Transparency = 255; + SendDlgItemMessage(hdlg,IDC_TRANSTRACK,TBM_SETPOS,TRUE,0); + SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0); // JK optim + return TRUE; + } + default: + SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0); + return TRUE; + } + } + return FALSE; +} + +void InitSettings(void) +{ + void *P = NULL; + short Sz1; + + Sz1 = MAX_PATH; P = NULL; + ReadSettingBlob(0, MODULENAME, "RemindEmail", (WORD*)&Sz1, &P); + if (!(Sz1 && P)) + g_RemindSMS = NULL; + else + { + g_RemindSMS = (char*)malloc(Sz1+1); + ZeroMemory(g_RemindSMS,Sz1+1); + memcpy(g_RemindSMS,P,Sz1); + FreeSettingBlob(Sz1,P); + } + + g_lpszAltBrowser = DBGetString(0,MODULENAME,"AltBrowser"); + + g_ShowNotesAtStart = (BOOL)ReadSettingInt(0,MODULENAME,"ShowNotesAtStart",1); + g_ShowNoteButtons = (BOOL)ReadSettingInt(0,MODULENAME,"ShowNoteButtons",1); + g_ShowScrollbar = (BOOL)ReadSettingInt(0,MODULENAME,"ShowScrollbar",1); + g_AddContListMI = (BOOL)ReadSettingInt(0,MODULENAME,"AddContactMenuItems",1); + g_NoteWidth = ReadSettingInt(0,MODULENAME,"NoteWidth",179); + g_NoteHeight = ReadSettingInt(0,MODULENAME,"NoteHeight",50); + g_Transparency = ReadSettingInt(0,MODULENAME,"Transparency",255); + g_NoteTitleDate = ReadSettingInt(0,MODULENAME,"NoteTitleDate",1); + g_NoteTitleTime = ReadSettingInt(0,MODULENAME,"NoteTitleTime",1); + g_CloseAfterAddReminder = (BOOL)ReadSettingInt(0,MODULENAME,"CloseAfterAddReminder",1); + g_UseDefaultPlaySound = !(BOOL)ReadSettingInt(0,MODULENAME,"UseMCI",1); + + ReadSettingIntArray(0,MODULENAME,"ReminderListGeom",g_reminderListGeom,SIZEOF(g_reminderListGeom)); + ReadSettingIntArray(0,MODULENAME,"ReminderListColGeom",g_reminderListColGeom,SIZEOF(g_reminderListColGeom)); + ReadSettingIntArray(0,MODULENAME,"NotesListGeom",g_notesListGeom,SIZEOF(g_notesListGeom)); + ReadSettingIntArray(0,MODULENAME,"NotesListColGeom",g_notesListColGeom,SIZEOF(g_notesListColGeom)); + + BodyColor = DBGetContactSettingDword(NULL, MODULENAME, colourOptionsList[0].szSettingName, colourOptionsList[0].defColour); + + InitFonts(); + + g_hReminderIcon = Skin_GetIconByHandle(hIconLibItem[10]); + + if (g_Transparency < MIN_ALPHA) + g_Transparency = MIN_ALPHA; + else if (g_Transparency > 255) + g_Transparency = 255; +} + +void TermSettings(void) +{ + if (g_reminderListGeom[2] > 0 && g_reminderListGeom[3] > 0) + { + WriteSettingIntArray(0,MODULENAME,"ReminderListGeom",g_reminderListGeom,SIZEOF(g_reminderListGeom)); + WriteSettingIntArray(0,MODULENAME,"ReminderListColGeom",g_reminderListColGeom,SIZEOF(g_reminderListColGeom)); + } + if (g_notesListGeom[2] > 0 && g_notesListGeom[3] > 0) + { + WriteSettingIntArray(0,MODULENAME,"NotesListGeom",g_notesListGeom,SIZEOF(g_notesListGeom)); + WriteSettingIntArray(0,MODULENAME,"NotesListColGeom",g_notesListColGeom,SIZEOF(g_notesListColGeom)); + } + + if (g_lpszAltBrowser) + { + mir_free(g_lpszAltBrowser); + g_lpszAltBrowser = NULL; + } +} diff --git a/plugins/!NotAdopted/NotesAndReminders/src/reminders.cpp b/plugins/!NotAdopted/NotesAndReminders/src/reminders.cpp new file mode 100644 index 0000000000..0d545056f9 --- /dev/null +++ b/plugins/!NotAdopted/NotesAndReminders/src/reminders.cpp @@ -0,0 +1,2890 @@ +#include "globals.h" + +#define FILETIME_TICKS_PER_SEC ((ULONGLONG)10000000) + +#define MAX_REMINDER_LEN 16384 + + +// RemindersData DB data params +#define DATATAG_TEXT 1 // %s +#define DATATAG_SNDREPEAT 2 // %u (specifies seconds to wait between sound repeats, 0 if repeat is disabled) +#define DATATAG_SNDSEL 3 // %d (which sound to use, default, alt1, alt2, -1 means no sound at all) + + +#define IDC_DATE 1000 +#define IDC_TIME IDC_COMBOREMINDERTIME +#define IDC_ADDREMINDER 1002 +#define IDC_CLOSE 1003 +#define IDC_REMINDER 1004 +#define IDC_LISTREMINDERS 1000 +#define IDC_LISTREMINDERS_HEADER 2000 +#define IDC_REMINDERDATA 1001 +#define IDC_ADDNEWREMINDER 1002 +#define IDC_REMDATA 1000 +#define IDC_DISMISS 1001 +#define IDC_REMINDAGAIN 1002 +#define IDC_REMINDAGAININ 1003 +#define IDC_AFTER 1004 +#define IDC_ONDATE 1005 +#define IDC_DATEAGAIN 1006 +#define IDC_TIMEAGAIN 1007 +#define IDC_VIEWREMINDERS 1007 +#define IDC_NONE 1008 +#define IDC_DAILY 1009 +#define IDC_WEEKLY 1010 +#define IDC_MONTHLY 1011 +#define IDM_NEWREMINDER 40001 +#define IDM_DELETEREMINDER 40002 +#define IDM_DELETEALLREMINDERS 40003 +#define WM_RELOAD (WM_USER + 100) + +#define NOTIFY_LIST() if (ListReminderVisible) PostMessage(LV,WM_RELOAD,0,0) + + +TREEELEMENT *RemindersList = NULL; +static UINT QueuedReminderCount = 0; +static BOOL ListReminderVisible = FALSE; +static BOOL NewReminderVisible = FALSE; +static REMINDERDATA *pEditReminder = NULL; +static HWND LV; +static SOCKET S; + +int WS_Send(SOCKET s,char *data,int datalen); +unsigned long WS_ResolveName(char *name,WORD *port,int defaultPort); + +int CALLBACK DlgProcNotifyReminder(HWND Dialog,UINT Message, + WPARAM wParam,LPARAM lParam); +int CALLBACK DlgProcNewReminder(HWND Dialog,UINT Message,WPARAM wParam, + LPARAM lParam); +int CALLBACK DlgProcViewReminders(HWND Dialog,UINT Message,WPARAM wParam, + LPARAM lParam); + +void Send(char *user, char *host, char *Msg, char* server); +char* GetPreviewString(const char *lpsz); + + +static int ReminderSortCb(TREEELEMENT *v1, TREEELEMENT *v2) +{ + return (((REMINDERDATA*)v1->ptrdata)->When.QuadPart < ((REMINDERDATA*)v2->ptrdata)->When.QuadPart) ? -1 : 1; +} + + +#ifndef WINXP_MINIMUM +// TzSpecificLocalTimeToSystemTime/SystemTimeToTzSpecificLocalTime (re-)implemented to work on win2k and older + +static const int DaysInMonth[2][12] = +{ + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, // normal year + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } // leap year +}; + +static __inline BOOL IsLeapYear(UINT Y) +{ + return !(Y & 3) && ((Y % 100) || !(Y % 400)); +} + +static int TZDateComp(const SYSTEMTIME *lpDate, const SYSTEMTIME *lpDateRef) +{ + int boundaryDay, day; + + if (lpDate->wMonth < lpDateRef->wMonth) + return -1; + if (lpDate->wMonth > lpDateRef->wMonth) + return 1; + + if (!lpDateRef->wYear) + { + const int week = (int)lpDateRef->wDay; + const WORD wFirst = (6 + lpDateRef->wDayOfWeek - lpDate->wDayOfWeek + lpDate->wDay) % 7 + 1; + boundaryDay = (int)wFirst + 7 * (week - 1); + if (boundaryDay > DaysInMonth[ IsLeapYear(lpDate->wYear) ][lpDate->wMonth-1]) + boundaryDay -= 7; + } + else + boundaryDay = (int)lpDateRef->wDay; + + boundaryDay = ((boundaryDay * 24 + (int)lpDateRef->wHour) * 60 + (int)lpDateRef->wMinute) * 60; + day = (((int)lpDate->wDay * 24 + (int)lpDate->wHour) * 60 + (int)lpDate->wMinute) * 60 + (int)lpDate->wSecond; + + return (day < boundaryDay) ? -1 : (day > boundaryDay); +} + +static UINT TZGetType(LPTIME_ZONE_INFORMATION lpTZI, ULARGE_INTEGER *lpFT, BOOL bLocal) +{ + if (lpTZI->DaylightDate.wMonth) + { + ULARGE_INTEGER ft = *lpFT; + SYSTEMTIME tm; + BOOL BeforeStandardDate, AfterDaylightDate; + UINT id; + + if (!lpTZI->StandardDate.wMonth || (!lpTZI->StandardDate.wYear + && (!lpTZI->StandardDate.wDay || lpTZI->StandardDate.wDay > 5 + || !lpTZI->DaylightDate.wDay || lpTZI->DaylightDate.wDay > 5))) + return TIME_ZONE_ID_INVALID; + + if (!bLocal) + ft.QuadPart -= (LONGLONG)(lpTZI->Bias + lpTZI->DaylightBias) * (LONGLONG)600000000; + + FileTimeToSystemTime((FILETIME*)&ft, &tm); + + BeforeStandardDate = (TZDateComp(&tm, &lpTZI->StandardDate) < 0); + + if (!bLocal) + { + ft.QuadPart -= (LONGLONG)(lpTZI->StandardBias - lpTZI->DaylightBias) * (LONGLONG)600000000; + FileTimeToSystemTime((FILETIME*)&ft, &tm); + } + + AfterDaylightDate = (TZDateComp(&tm, &lpTZI->DaylightDate) >= 0); + + id = TIME_ZONE_ID_STANDARD; + if (lpTZI->DaylightDate.wMonth < lpTZI->StandardDate.wMonth) + { + if (BeforeStandardDate && AfterDaylightDate) + id = TIME_ZONE_ID_DAYLIGHT; + } + else + { + if (BeforeStandardDate || AfterDaylightDate) + id = TIME_ZONE_ID_DAYLIGHT; + } + + return id; + } + + return TIME_ZONE_ID_UNKNOWN; +} + +static BOOL TZGetBias(LPTIME_ZONE_INFORMATION lpTZI, ULARGE_INTEGER *lpFT, BOOL bLocal, LONG *pBias) +{ + LONG Bias = lpTZI->Bias; + + switch ( TZGetType(lpTZI, lpFT, bLocal) ) + { + case TIME_ZONE_ID_INVALID: return FALSE; + case TIME_ZONE_ID_DAYLIGHT: Bias += lpTZI->DaylightBias; break; + case TIME_ZONE_ID_STANDARD: Bias += lpTZI->StandardBias; break; + } + + *pBias = Bias; + + return TRUE; +} + +#define TzSpecificLocalTimeToSystemTime _TzSpecificLocalTimeToSystemTime +static BOOL _TzSpecificLocalTimeToSystemTime(LPTIME_ZONE_INFORMATION lpTZI, LPSYSTEMTIME lpLocal, LPSYSTEMTIME lpUtc) +{ + TIME_ZONE_INFORMATION tzi; + ULARGE_INTEGER ft; + LONG Bias; + + // if possible use the real function (shouldn't be necessary, be feels more comfortable) + if (MyTzSpecificLocalTimeToSystemTime) + return MyTzSpecificLocalTimeToSystemTime(lpTZI, lpLocal, lpUtc); + + if (!lpTZI) + { + if (GetTimeZoneInformation(&tzi) == TIME_ZONE_ID_INVALID) + return FALSE; + lpTZI = &tzi; + } + + if (!SystemTimeToFileTime(lpLocal, (FILETIME*)&ft) + || !TZGetBias(lpTZI, &ft, TRUE, &Bias)) + return FALSE; + + ft.QuadPart += (LONGLONG)Bias * (LONGLONG)600000000; + + return FileTimeToSystemTime((FILETIME*)&ft, lpUtc); +} + +#define SystemTimeToTzSpecificLocalTime _SystemTimeToTzSpecificLocalTime +static BOOL _SystemTimeToTzSpecificLocalTime(LPTIME_ZONE_INFORMATION lpTZI, LPSYSTEMTIME lpUtc, LPSYSTEMTIME lpLocal) +{ + TIME_ZONE_INFORMATION tzi; + ULARGE_INTEGER ft; + LONG Bias; + + // if possible use the real function (shouldn't be necessary, be feels more comfortable) + if (MySystemTimeToTzSpecificLocalTime) + return MySystemTimeToTzSpecificLocalTime(lpTZI, lpUtc, lpLocal); + + if (!lpTZI) + { + if (GetTimeZoneInformation(&tzi) == TIME_ZONE_ID_INVALID) + return FALSE; + lpTZI = &tzi; + } + + if (!SystemTimeToFileTime(lpUtc, (FILETIME*)&ft) + || !TZGetBias(lpTZI, &ft, FALSE, &Bias)) + return FALSE; + + ft.QuadPart -= (LONGLONG)Bias * (LONGLONG)600000000; + + return FileTimeToSystemTime((FILETIME*)&ft, lpLocal); +} + +#endif + + +// time convertsion routines that take local time-zone specific daylight saving configuration into account +// (unlike the standard FileTimeToLocalFileTime functions) + +void UtcToTzLocalFT(const FILETIME *lpUtc, FILETIME *lpLocal) +{ + SYSTEMTIME tm, tmLocal; + FILETIMEtoSYSTEMTIME(lpUtc, &tm); + SystemTimeToTzSpecificLocalTime(NULL, &tm, &tmLocal); + SYSTEMTIMEtoFILETIME(&tmLocal, lpLocal); +} + +void TzLocalToUtcFT(const FILETIME *lpLocal, FILETIME *lpUtc) +{ + SYSTEMTIME tm, tmUtc; + FILETIMEtoSYSTEMTIME(lpLocal, &tm); + TzSpecificLocalTimeToSystemTime(NULL, &tm, &tmUtc); + SYSTEMTIMEtoFILETIME(&tmUtc, lpUtc); +} + +void FileTimeToTzLocalST(const FILETIME *lpUtc, SYSTEMTIME *tmLocal) +{ + SYSTEMTIME tm; + FILETIMEtoSYSTEMTIME(lpUtc, &tm); + SystemTimeToTzSpecificLocalTime(NULL, &tm, tmLocal); +} + +void TzLocalSTToFileTime(const SYSTEMTIME *tmLocal, FILETIME *lpUtc) +{ + SYSTEMTIME tm; + TzSpecificLocalTimeToSystemTime(NULL, (SYSTEMTIME*)tmLocal, &tm); + SYSTEMTIMEtoFILETIME(&tm, lpUtc); +} + +/*void AddToTzLocalFT(FILETIME *lpLocal, UINT nSeconds) +{ + ULARGE_INTEGER utc; + TzLocalToUtcFT(lpLocal, (FILETIME*)&utc); + utc.QuadPart += (ULONGLONG)nSeconds * FILETIME_TICKS_PER_SEC; + UtcToTzLocalFT((FILETIME*)&utc, lpLocal); +}*/ + +/*static void AddToSystemTime(SYSTEMTIME *tm, UINT nSeconds) +{ + ULARGE_INTEGER li; + FILETIME ft; + + SYSTEMTIMEtoFILETIME(tm, &ft); + + li.HighPart = ft.dwHighDateTime; + li.LowPart = ft.dwLowDateTime; + li.QuadPart += (ULONGLONG)nSeconds * FILETIME_TICKS_PER_SEC; + + FILETIMEtoSYSTEMTIME((FILETIME*)&li, tm); +}*/ + + +static DWORD CreateUid() +{ + DWORD uid; + TREEELEMENT *TTE; + + if (!RemindersList) + return 1; + + for (uid = 1; ; uid++) + { + // check existing reminders if uid is in use + TTE = RemindersList; + while (TTE) + { + if (((REMINDERDATA*)TTE->ptrdata)->uid == uid) + // uid in use + goto try_next; + + TTE = (TREEELEMENT*)TTE->next; + } + + return uid; + +try_next:; + } + + // should never get here (unless someone has 4294967295 reminders) + return 0; +} + +static REMINDERDATA* FindReminder(DWORD uid) +{ + TREEELEMENT *TTE; + + if (!RemindersList) + return NULL; + + TTE = RemindersList; + while (TTE) + { + REMINDERDATA *pReminder = (REMINDERDATA*)TTE->ptrdata; + + if (pReminder->uid == uid) + { + return pReminder; + } + + TTE = (TREEELEMENT*)TTE->next; + } + + return NULL; +} + + +static void RemoveReminderSystemEvent(REMINDERDATA *p) +{ + if (p->SystemEventQueued) + { + int i; + + for (i=0; ; i++) + { + CLISTEVENT *pev; + + pev = (CLISTEVENT*) CallService(MS_CLIST_GETEVENT,(WPARAM)INVALID_HANDLE_VALUE,i); + if (!pev) + break; + + if ((ULONG)pev->lParam == p->uid && !pev->hContact + && pev->pszService && !strcmp(pev->pszService, MODULENAME"/OpenTriggeredReminder")) + { + if ( !CallService(MS_CLIST_REMOVEEVENT,(WPARAM)pev->hContact,(LPARAM)pev->hDbEvent) ) + { + p->SystemEventQueued = FALSE; + if (QueuedReminderCount) + QueuedReminderCount--; + } + break; + } + } + } +} + +void PurgeReminders(void) +{ + int ReminderCount,I; + char ValueName[32]; + + ReminderCount = ReadSettingInt(0,MODULENAME,"RemindersData",0); + for(I = 0;I < ReminderCount;I++) + { + sprintf(ValueName, "RemindersData%d", I); + DeleteSetting(0,MODULENAME,ValueName); + } +} + +void JustSaveReminders(void) +{ + TREEELEMENT *TTE; + int I, n, l; + char *tmpReminder = NULL,*Value; + char ValueName[32]; + int ReminderCount; + REMINDERDATA *pReminder; + + const int OldReminderCount = ReadSettingInt(0, MODULENAME, "RemindersData", 0); + + ReminderCount = TreeGetCount(RemindersList); + + WriteSettingInt(0,MODULENAME, "RemindersData", ReminderCount); + + for (TTE = RemindersList, I = 0; TTE; TTE = (TREEELEMENT*)TTE->next, I++) + { + pReminder = (REMINDERDATA*)TTE->ptrdata; + if (pReminder->Reminder && strlen(pReminder->Reminder)) + tmpReminder = pReminder->Reminder; + else + tmpReminder = NULL; + + if (!tmpReminder) + tmpReminder = ""; + + Value = (char*)malloc(strlen(tmpReminder) + 512); + + if (!Value) + continue; + + n = 0; + + // data header (save 'When' with 1-second resolution, it's just a waste to have 100-nanosecond resolution + // which results in larger DB strings with no use) + l = sprintf(Value, "X%u:%I64x", pReminder->uid, pReminder->When.QuadPart/FILETIME_TICKS_PER_SEC); + if (l > 0) n += l; + + // sound repeat + if (pReminder->RepeatSound) + { + l = sprintf(Value+n, "\033""%u:%u", DATATAG_SNDREPEAT, pReminder->RepeatSound); + if (l > 0) n += l; + } + + // sound + if (pReminder->SoundSel) + { + l = sprintf(Value+n, "\033""%u:%d", DATATAG_SNDSEL, pReminder->SoundSel); + if (l > 0) n += l; + } + + // reminder text/note (ALWAYS PUT THIS PARAM LAST) + if (tmpReminder && *tmpReminder) + { + l = sprintf(Value+n, "\033""%u:%s", DATATAG_TEXT, tmpReminder); + if (l > 0) n += l; + } + + // clamp data size to WORD (including null terminator) + if (n >= 0xffff) + { + // huston, we have a problem, strip some reminder text + n = 0xfffe; + ValueName[0xffff] = 0; + } + + sprintf(ValueName, "RemindersData%d", ReminderCount - I - 1); // do not want to reverse in DB + + WriteSettingBlob(0, MODULENAME, ValueName, (WORD)(n+1), Value); + + SAFE_FREE((void**)&Value); + } + + // delete any left over DB reminder entries + for(; I < OldReminderCount; I++) + { + sprintf(ValueName, "RemindersData%d", I); + DBDeleteContactSetting(0,MODULENAME,ValueName); + } +} + +void LoadReminders(void) +{ + int I,RemindersCount; + char *Value; + WORD Size; + char ValueName[32]; + BOOL GenerateUids = FALSE; + + RemindersList = NULL; + RemindersCount = ReadSettingInt(0, MODULENAME, "RemindersData", 0); + + for (I = 0; I < RemindersCount; I++) + { + Size = 65535; + Value = NULL; + sprintf(ValueName, "RemindersData%d", I); + + ReadSettingBlob(0, MODULENAME, ValueName, &Size, (void**)&Value); + + if (Size && Value) // was the blob found + { + REMINDERDATA rem = {0}; + char *TVal; + REMINDERDATA *TempRem; + char *DelPos = strchr(Value, 0x1B); + + // ensure that read data is null-terminated + Value[(UINT)Size-1] = 0; + + if (Value[0] == 'X') + { + // new eXtended/fleXible data format + + if (DelPos) + *DelPos = 0; + + // uid:when + + TVal = strchr(Value+1, ':'); + if (!TVal || (DelPos && TVal > DelPos)) + continue; + *TVal++ = 0; + + rem.uid = strtoul(Value+1, NULL, 10); + rem.When.QuadPart = _strtoui64(TVal, NULL, 16) * FILETIME_TICKS_PER_SEC; + + // optional \033 separated params + while (DelPos) + { + char *sep; + UINT tag; + + TVal = DelPos + 1; + // find param end and make sure it's null-terminated (if end of data then it's already null-terminated) + DelPos = strchr(TVal, 0x1B); + if (DelPos) + *DelPos = 0; + + // tag: + + sep = strchr(TVal, ':'); + if (!sep || (DelPos && sep > DelPos)) + goto skip; + + tag = strtoul(TVal, NULL, 10); + TVal = sep + 1; + + switch (tag) + { + case DATATAG_TEXT: + rem.Reminder = _strdup(TVal); + break; + + case DATATAG_SNDREPEAT: + rem.RepeatSound = strtoul(TVal, NULL, 10); + break; + + case DATATAG_SNDSEL: + rem.SoundSel = strtol(TVal, NULL, 10); + if (rem.SoundSel > 2) rem.SoundSel = 2; + break; + } + } + + if (rem.SoundSel < 0) + rem.RepeatSound = 0; + if (!rem.Reminder) + rem.Reminder = _strdup(""); + } + else + { + // old format (for DB backward compatibility) + + if (!DelPos) + continue; + + DelPos[0] = 0; + // convert time_t to (local) FILETIME + { + SYSTEMTIME tm; + struct tm *stm; + time_t tt; + + tt = (time_t)strtoul(Value, NULL, 10); + stm = localtime(&tt); + tm.wDayOfWeek = 0; + tm.wSecond = 0; + tm.wMilliseconds = 0; + tm.wHour = stm->tm_hour; + tm.wMinute = stm->tm_min; + tm.wSecond = stm->tm_sec; + tm.wYear = stm->tm_year + 1900; + tm.wMonth = stm->tm_mon + 1; + tm.wDay = stm->tm_mday; + SYSTEMTIMEtoFILETIME(&tm, (FILETIME*)&rem.When); + } + TVal = DelPos + 1; + rem.Reminder = _strdup(TVal); + } + + // queue uid generation if invalid uid is present + if (!rem.uid) + GenerateUids = TRUE; + + TempRem = (REMINDERDATA*)malloc(sizeof(REMINDERDATA)); + if (TempRem) + { + *TempRem = rem; + TreeAddSorted(&RemindersList, TempRem, ReminderSortCb); + } + else if (rem.Reminder) + { + free(rem.Reminder); + } +skip:; + } + + FreeSettingBlob(Size, Value); + } + + // generate UIDs if there are any items with an invalid UID + if (GenerateUids && RemindersList) + { + TREEELEMENT *TTE; + + TTE = RemindersList; + while (TTE) + { + REMINDERDATA *pReminder = (REMINDERDATA*)TTE->ptrdata; + + if (!pReminder->uid) + pReminder->uid = CreateUid(); + + TTE = (TREEELEMENT*)TTE->next; + } + + JustSaveReminders(); + } +} + + +/*void EscapeString(LPCSTR lpszSrc, char *s, int maxLen) +{ + maxLen -= 3; + + *s++ = '"'; + + while (*lpszSrc && maxLen > 1) + { + switch (*lpszSrc) + { + case '\r': *s++ = '\\'; *s++ = 'r'; break; + case '\n': *s++ = '\\'; *s++ = 'n'; break; + case '"': *s++ = '\\'; *s++ = '"'; break; + case '\t': *s++ = '\\'; *s++ = 't'; break; + case '\\': *s++ = '\\'; *s++ = '\\'; break; + default: + *s++ = *lpszSrc; + } + + lpszSrc++; + maxLen--; + } + + *s++ = '"'; + *s = 0; +} + +void ExportReminders() +{ + LPCSTR lpsz; + TREEELEMENT *TTE; + char s[MAX_REMINDER_LEN+512]; + + if (!RemindersList) + return NULL; + + // CSV header + lpsz = "TimeUTC,SoundSel,SoundRepeat,Description"; + WriteFile(hFile, lpsz, strlen(lpsz), NULL, NULL); + + TTE = RemindersList; + while (TTE) + { + REMINDERDATA *pReminder = (REMINDERDATA*)TTE->ptrdata; + + sprintf(s, "%I64u,%d,%d,", (pReminder->When.QuadPart-(ULONGLONG)116444736000000000)/FILETIME_TICKS_PER_SEC, pReminder->SoundSel, pReminder->RepeatSound); + WriteFile(hFile, s, strlen(s), NULL, NULL); + + if (pReminder->Reminder) + { + EscapeString(pReminder->Reminder, s, sizeof(s)); + WriteFile(hFile, s, strlen(s), NULL, NULL); + } + + WriteFile(hFile, (LPCVOID)"\r\n", 2, NULL, NULL); + + TTE = TTE->next; + } + + return NULL; +}*/ + + +void NewReminder(void) +{ + if (!NewReminderVisible) + { + NewReminderVisible = TRUE; + CreateDialog(hinstance, MAKEINTRESOURCE(IDD_ADDREMINDER), 0, DlgProcNewReminder); + } +} + +void EditReminder(REMINDERDATA *p) +{ + if (!p) + return; + + if (!NewReminderVisible && !p->SystemEventQueued) + { + if (!p->RemVisible) + { + p->RemVisible = TRUE; + NewReminderVisible = 2; + pEditReminder = p; + CreateDialog(hinstance, MAKEINTRESOURCE(IDD_ADDREMINDER), 0, DlgProcNewReminder); + } + else + { + BringWindowToTop(p->handle); + } + } +} + +static void DeleteReminder(REMINDERDATA *p) +{ + if (!p) + return; + + if (p->SystemEventQueued) + { + // remove pending system event + RemoveReminderSystemEvent(p); + } + + TreeDelete(&RemindersList, p); + SAFE_FREE((void**)&p->Reminder); + SAFE_FREE((void**)&p); +} + +void CloseReminderList() +{ + if (ListReminderVisible) + { + DestroyWindow(LV); + ListReminderVisible = FALSE; + } +} + +static void PurgeReminderTree() +{ + REMINDERDATA *pt; + + while (RemindersList) // empty whole tree + { + pt = (REMINDERDATA*)RemindersList->ptrdata; + if (pt->handle) DestroyWindow(pt->handle); + DeleteReminder(pt); + } + RemindersList = NULL; +} + +void SaveReminders(void) +{ + JustSaveReminders(); + PurgeReminderTree(); +} + +void DeleteReminders(void) +{ + PurgeReminders(); + WriteSettingInt(0,MODULENAME,"RemindersData",0); + PurgeReminderTree(); +} + +void ListReminders(void) +{ + if (!ListReminderVisible) + { + CreateDialog(hinstance, MAKEINTRESOURCE(IDD_LISTREMINDERS), 0, DlgProcViewReminders); + ListReminderVisible = TRUE; + } + else + { + BringWindowToTop(LV); + } +} + + +void GetTriggerTimeString(const ULARGE_INTEGER *When, char *s, UINT strSize, BOOL bUtc) +{ + SYSTEMTIME tm; + LCID lc = GetUserDefaultLCID(); + + *s = 0; + + memset(&tm, 0, sizeof(tm)); + if (bUtc) + FileTimeToTzLocalST((const FILETIME*)When, &tm); + else + FILETIMEtoSYSTEMTIME((FILETIME*)When, &tm); + + if ( GetDateFormat(lc, DATE_LONGDATE, &tm, NULL, s, strSize) ) + { + // append time + { + int n = strlen(s); + s[n++] = ' '; + s[n] = 0; + + if ( !GetTimeFormat(lc, LOCALE_NOUSEROVERRIDE|TIME_NOSECONDS, &tm, NULL, s+n, strSize-n) ) + { + mir_snprintf(s+n, strSize-n, "%02d:%02d", tm.wHour, tm.wMinute); + } + } + } + else + { + mir_snprintf(s, strSize, "%d-%02d-%02d %02d:%02d", tm.wYear, tm.wMonth, tm.wDay, tm.wHour, tm.wMinute); + } +} + + +int OpenTriggeredReminder(WPARAM w, LPARAM l) +{ + REMINDERDATA *pReminder; + + if (!l) + return 0; + + l = ((CLISTEVENT*)l)->lParam; + + pReminder = (REMINDERDATA*)FindReminder((DWORD)l); + if (!pReminder || !pReminder->SystemEventQueued) + return 0; + + pReminder->SystemEventQueued = FALSE; + if (QueuedReminderCount) + QueuedReminderCount--; + + { + char S[MAX_PATH]; + char S1[128]; + HWND H; + GetTriggerTimeString(&pReminder->When, S1, sizeof(S1), TRUE); + + pReminder->RemVisible = TRUE; + + pReminder->handle = H = CreateDialog(hinstance, MAKEINTRESOURCE(IDD_NOTIFYREMINDER), 0, DlgProcNotifyReminder); + + sprintf(S, "%s! - %s", Translate("Reminder"), S1); + SetWindowText(H, S); + + if (pReminder->Reminder) + SetDlgItemText(H, IDC_REMDATA, pReminder->Reminder); + + BringWindowToTop(H); + } + + return 0; +} + +static void SkinPlaySoundPoly(LPCSTR pszSoundName) +{ + if (g_UseDefaultPlaySound) + { + SkinPlaySound(pszSoundName); + return; + } + + if (DBGetContactSettingByte(NULL, "SkinSoundsOff", pszSoundName, 0)==0) { + DBVARIANT dbv; + + if (DBGetContactSettingString(NULL, "SkinSounds", pszSoundName, &dbv)==0) { + char szFull[MAX_PATH]; + + CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)dbv.pszVal, (LPARAM)szFull); + + //NotifyEventHooks(hPlayEvent, 0, (LPARAM)szFull); + { + // use MCI device which allows multiple sounds playing at once + // NOTE: mciSendString does not like long paths names, must convert to short + char szShort[MAX_PATH]; + char s[512]; + GetShortPathNameA(szFull, szShort, sizeof(szShort)); + mir_snprintf(s, sizeof(s), "play \"%s\"", szShort); + mciSendStringA(s, NULL, 0, NULL); + } + + DBFreeVariant(&dbv); + } + } +} + +static void UpdateReminderEvent(REMINDERDATA *pReminder, UINT nElapsedSeconds, BOOL *pHasPlayedSound) +{ + DWORD dwSoundMask; + + if (pReminder->RepeatSound) + { + if (nElapsedSeconds >= pReminder->RepeatSoundTTL) + { + pReminder->RepeatSoundTTL = pReminder->RepeatSound; + + dwSoundMask = 1 << pReminder->SoundSel; + + if ( !(*pHasPlayedSound & dwSoundMask) ) + { + switch (pReminder->SoundSel) + { + case 1: SkinPlaySoundPoly("AlertReminder2"); break; + case 2: SkinPlaySoundPoly("AlertReminder3"); break; + default: + SkinPlaySoundPoly("AlertReminder"); + } + + *pHasPlayedSound |= dwSoundMask; + } + } + else + { + pReminder->RepeatSoundTTL -= nElapsedSeconds; + } + } +} + +static void FireReminder(REMINDERDATA *pReminder, BOOL *pHasPlayedSound) +{ + DWORD dwSoundMask; + + if (pReminder->SystemEventQueued) + return; + + // add a system event + { + CLISTEVENT ev = { 0 }; + + ev.cbSize = sizeof(ev); + ev.hIcon = g_hReminderIcon; + ev.flags = CLEF_URGENT; + ev.lParam = (LPARAM)pReminder->uid; + ev.pszService = MODULENAME"/OpenTriggeredReminder"; + ev.pszTooltip = Translate("Reminder"); + + CallService(MS_CLIST_ADDEVENT,0,(LPARAM)&ev); + } + + pReminder->SystemEventQueued = TRUE; + QueuedReminderCount++; + + if (pReminder->SoundSel < 0) + { + // sound disabled + return; + } + + dwSoundMask = 1 << pReminder->SoundSel; + + pReminder->RepeatSoundTTL = pReminder->RepeatSound; + + if ( !(*pHasPlayedSound & dwSoundMask) ) + { + switch (pReminder->SoundSel) + { + case 1: SkinPlaySoundPoly("AlertReminder2"); break; + case 2: SkinPlaySoundPoly("AlertReminder3"); break; + default: + SkinPlaySoundPoly("AlertReminder"); + } + + *pHasPlayedSound |= dwSoundMask; + } +} + + +BOOL CheckRemindersAndStart(void) +{ + // returns TRUE if there are any triggered reminder with SystemEventQueued, this will shorten the update interval + // allowing sound repeats with shorter intervals + + TREEELEMENT *TTE; + ULARGE_INTEGER curT; + BOOL bHasPlayedSound; + BOOL bResult; + BOOL bHasQueuedReminders; + + if (!RemindersList) + return FALSE; + + { + SYSTEMTIME tm; + GetSystemTime(&tm); + SYSTEMTIMEtoFILETIME(&tm, (FILETIME*)&curT); + } + + // NOTE: reminder list is sorted by trigger time, so we can early out on the first reminder > cur time + + // quick check for normal case with no reminder ready to be triggered and no queued triggered reminders + // (happens 99.99999999999% of the time) + if (curT.QuadPart < ((REMINDERDATA*)RemindersList->ptrdata)->When.QuadPart && !QueuedReminderCount) + { + return FALSE; + } + + bResult = FALSE; + + // var used to avoid playing multiple alarm sounds during a single update + bHasPlayedSound = FALSE; + + // if there are queued (triggered) reminders then iterate through entire list, becaue of WM_TIMECHANGE events + // and for example daylight saving changes it's possible for an already triggered event to end up with When>curT + bHasQueuedReminders = (QueuedReminderCount != 0); + + // allthough count should always be correct, it's fool proof to just count them again in the loop below + QueuedReminderCount = 0; + + TTE = RemindersList; + while (TTE && (bHasQueuedReminders || ((REMINDERDATA*)TTE->ptrdata)->When.QuadPart <= curT.QuadPart)) + { + REMINDERDATA *pReminder = (REMINDERDATA*)TTE->ptrdata; + + if (!pReminder->RemVisible) + { + if (pReminder->SystemEventQueued) + { + UpdateReminderEvent(pReminder, REMINDER_UPDATE_INTERVAL_SHORT/1000, &bHasPlayedSound); + + QueuedReminderCount++; + bResult = TRUE; + } + else if (((REMINDERDATA*)TTE->ptrdata)->When.QuadPart <= curT.QuadPart) + { + if (!g_RemindSMS) + { + FireReminder(pReminder, &bHasPlayedSound); + + if (pReminder->SystemEventQueued) + bResult = TRUE; + } + else + { + char* S2 = strchr(g_RemindSMS, '@'); + char* S1 = (char*)malloc(S2 - g_RemindSMS); + + strncpy(S1, g_RemindSMS, S2 - g_RemindSMS); + S1[S2 - g_RemindSMS]= 0x0; + S2++; + Send(S1, S2, pReminder->Reminder ? pReminder->Reminder : "", NULL); + SAFE_FREE((void**)&S1); + DeleteReminder(pReminder); + JustSaveReminders(); + NOTIFY_LIST(); + } + } + } + + TTE = (TREEELEMENT*)TTE->next; + } + + return bResult; +} + + +static LRESULT CALLBACK DatePickerWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_RBUTTONDBLCLK: + case WM_KEYDOWN: + case WM_KEYUP: + case WM_CHAR: + case WM_INITMENUPOPUP: + case WM_PASTE: + return TRUE; + case WM_SYSKEYUP: + case WM_SYSKEYDOWN: + case WM_SYSCHAR: + return FALSE; + } + + return CallWindowProc((WNDPROC)GetProp(hWnd, TEXT("OldWndProc")), hWnd, message, wParam, lParam); +} + +static void InitDatePicker(HWND Dialog, UINT nIDDate) +{ + // subclass date picker to prevent user editing (should only use the dropdown calender to ensure valid dates) + WNDPROC pOldWndProc; + HWND hCtrl = GetDlgItem(Dialog, nIDDate); + + // tweak style of picker + if ( IsWinVerVistaPlus() ) + { + DWORD dw = SendDlgItemMessage(Dialog,nIDDate,DTM_GETMCSTYLE,0,0); + dw |= MCS_WEEKNUMBERS | MCS_NOSELCHANGEONNAV; + SendDlgItemMessage(Dialog,nIDDate,DTM_SETMCSTYLE,0,dw); + } + +#ifdef _WIN64 + pOldWndProc = (WNDPROC)SetWindowLongPtr(hCtrl, GWLP_WNDPROC, (LONG_PTR)DatePickerWndProc); +#else + pOldWndProc = (WNDPROC)SetWindowLong(hCtrl, GWL_WNDPROC, (LONG)DatePickerWndProc); +#endif + + SetProp(hCtrl, TEXT("OldWndProc"), pOldWndProc); +} + +static BOOL ParseTime(LPCSTR s, int *hout, int *mout, BOOL bTimeOffset, BOOL bAllowOffsetOverride) +{ + // validate format: [][':'[]][p | P].* + + // if bTimeOffset is FALSE the user may still enter a time offset by using + as the first char, the + // delta time will be returned in minutes (even > 60) and hout will always be -1 + + // if bTimeOffset is TRUE time is always interpreted as an offset (ignores PM indicator and defaults to minutes) + + int h, m; + BOOL bOffset = bTimeOffset; + + // read hour + + while ( iswspace(*s) ) s++; + + if (*s == '+') + { + if (!bTimeOffset) + { + if (!bAllowOffsetOverride) + return FALSE; + + // treat value as an offset anyway + bOffset = TRUE; + } + + s++; + while ( iswspace(*s) ) s++; + } + + if ( !isdigit(*s) ) + return FALSE; + h = (int)(*s-'0'); + s++; + + if (!bOffset) + { + if ( isdigit(*s) ) + { + h = h * 10 + (int)(*s-'0'); + s++; + } + + if ( isdigit(*s) ) + return FALSE; + } + else + { + // allow more than 2-digit numbers for offset + while ( isdigit(*s) ) + { + h = h * 10 + (int)(*s-'0'); + s++; + } + } + + // find : separator + + while ( iswspace(*s) ) s++; + + if (*s == ':') + { + s++; + + // read minutes + + while ( iswspace(*s) ) s++; + + if ( !isdigit(*s) ) + return FALSE; + m = (int)(*s-'0'); + s++; + + if ( isdigit(*s) ) + { + m = m * 10 + (int)(*s-'0'); + s++; + } + } + else + { + if (bOffset) + { + // no : separator found, interpret the entered number as minutes and allow > 60 + + if (h < 0) + return FALSE; + + if (bTimeOffset) + { + *hout = h / 60; + *mout = h % 60; + } + else + { + *mout = h; + *hout = -1; + } + + return TRUE; + } + else + { + m = 0; + } + } + + // validate time + if (bOffset) + { + if (h < 0) + return FALSE; + if (m < 0 || m > 59) + return FALSE; + } + else + { + if (h == 24) + h = 0; + else if (h < 0 || h > 23) + return FALSE; + if (m < 0 || m > 59) + return FALSE; + } + + if (!bOffset) + { + // check for PM indicator (not strict, only checks for P char) + + while ( iswspace(*s) ) s++; + + if (*s == 'p' || *s == 'P') + { + if (h < 13) + h += 12; + else if (h == 12) + h = 0; + } + } + else if (!bTimeOffset) + { + // entered time is an offset + + *mout = h * 60 + m; + *hout = -1; + + return TRUE; + } + + *hout = h; + *mout = m; + + return TRUE; +} + +// returns TRUE if combo box list displays time offsets ("23:34 (5 Minutes)" etc.) +__inline static BOOL IsRelativeCombo(HWND Dialog, UINT nIDTime) +{ + return (int)SendDlgItemMessage(Dialog,nIDTime,CB_GETITEMDATA,0,0) >= 0; +} + +static void PopulateTimeCombo(HWND Dialog, UINT nIDTime, BOOL bRelative, const SYSTEMTIME *tmUtc) +{ + // NOTE: may seem like a bit excessive time converstion and handling, but this is done in order + // to gracefully handle crossing daylight saving boundaries + + SYSTEMTIME tm2; + ULARGE_INTEGER li; + ULONGLONG ref; + int i, n; + char s[64]; + const ULONGLONG MinutesToFileTime = (ULONGLONG)60 * FILETIME_TICKS_PER_SEC; + LPCSTR lpszMinutes; + LPCSTR lpszHours; + WORD wCurHour, wCurMinute; + + if (!bRelative) + { + SendDlgItemMessage(Dialog,nIDTime,CB_RESETCONTENT,0,0); + + // ensure that we start on midnight local time + SystemTimeToTzSpecificLocalTime(NULL, (SYSTEMTIME*)tmUtc, &tm2); + tm2.wHour = 0; + tm2.wMinute = 0; + tm2.wSecond = 0; + tm2.wMilliseconds = 0; + TzSpecificLocalTimeToSystemTime(NULL, &tm2, &tm2); + SYSTEMTIMEtoFILETIME(&tm2, (FILETIME*)&li); + + // from 00:00 to 23:30 in 30 minute steps + for (i=0; i<50; i++) + { + const int h = i>>1; + const int m = (i&1) ? 30 : 0; + + FileTimeToTzLocalST((FILETIME*)&li, &tm2); + sprintf(s, "%02d:%02d", (UINT)tm2.wHour, (UINT)tm2.wMinute); + n = SendDlgItemMessage(Dialog,nIDTime,CB_ADDSTRING,0,(LPARAM)s); + // item data contains time offset from midnight in seconds (bit 31 is set to flag that + // combo box items are absolute times and not relative times like below + SendDlgItemMessage(Dialog,nIDTime,CB_SETITEMDATA,(WPARAM)n,(LPARAM)((ULONG)((h*60+m)*60) | 0x80000000)); + + li.QuadPart += (ULONGLONG)30 * MinutesToFileTime; + + if (tm2.wHour == 23 && tm2.wMinute >= 30) + break; + } + + return; + } + + // + + SendDlgItemMessage(Dialog, nIDTime, CB_RESETCONTENT, 0, 0); + + lpszMinutes = Translate("Minutes"); + lpszHours = Translate("Hours"); + + SYSTEMTIMEtoFILETIME(tmUtc, (FILETIME*)&li); + ref = li.QuadPart; + + // NOTE: item data contains offset from reference time (tmUtc) in seconds + + // cur time + FileTimeToTzLocalST((FILETIME*)&li, &tm2); + wCurHour = tm2.wHour; + wCurMinute = tm2.wMinute; + mir_snprintf(s, sizeof(s), "%02d:%02d", (UINT)tm2.wHour, (UINT)tm2.wMinute); + n = SendDlgItemMessage(Dialog,nIDTime,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,nIDTime,CB_SETITEMDATA,(WPARAM)n,(LPARAM)((li.QuadPart-ref)/FILETIME_TICKS_PER_SEC)); + + // 5 minutes + li.QuadPart += (ULONGLONG)5 * MinutesToFileTime; + FileTimeToTzLocalST((FILETIME*)&li, &tm2); + mir_snprintf(s, sizeof(s), "%02d:%02d (5 %s)", (UINT)tm2.wHour, (UINT)tm2.wMinute, lpszMinutes); + n = SendDlgItemMessage(Dialog,nIDTime,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,nIDTime,CB_SETITEMDATA,(WPARAM)n,(LPARAM)((li.QuadPart-ref)/FILETIME_TICKS_PER_SEC)); + + // 10 minutes + li.QuadPart += (ULONGLONG)5 * MinutesToFileTime; + FileTimeToTzLocalST((FILETIME*)&li, &tm2); + mir_snprintf(s, sizeof(s), "%02d:%02d (10 %s)", (UINT)tm2.wHour, (UINT)tm2.wMinute, lpszMinutes); + n = SendDlgItemMessage(Dialog,nIDTime,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,nIDTime,CB_SETITEMDATA,(WPARAM)n,(LPARAM)((li.QuadPart-ref)/FILETIME_TICKS_PER_SEC)); + + // 15 minutes + li.QuadPart += (ULONGLONG)5 * MinutesToFileTime; + FileTimeToTzLocalST((FILETIME*)&li, &tm2); + mir_snprintf(s, sizeof(s), "%02d:%02d (15 %s)", (UINT)tm2.wHour, (UINT)tm2.wMinute, lpszMinutes); + n = SendDlgItemMessage(Dialog,nIDTime,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,nIDTime,CB_SETITEMDATA,(WPARAM)n,(LPARAM)((li.QuadPart-ref)/FILETIME_TICKS_PER_SEC)); + + // 30 minutes + li.QuadPart += (ULONGLONG)15 * MinutesToFileTime; + FileTimeToTzLocalST((FILETIME*)&li, &tm2); + mir_snprintf(s, sizeof(s), "%02d:%02d (30 %s)", (UINT)tm2.wHour, (UINT)tm2.wMinute, lpszMinutes); + n = SendDlgItemMessage(Dialog,nIDTime,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,nIDTime,CB_SETITEMDATA,(WPARAM)n,(LPARAM)((li.QuadPart-ref)/FILETIME_TICKS_PER_SEC)); + + // round +1h time to nearest even or half hour + li.QuadPart += (ULONGLONG)30 * MinutesToFileTime; + li.QuadPart = (li.QuadPart / (30 * MinutesToFileTime)) * (30 * MinutesToFileTime); + + // add from +1 to +23.5 (in half hour steps) if crossing daylight saving boundary it may be 22.5 or 24.5 hours + for (i=0; i<50; i++) + { + UINT dt; + + FileTimeToTzLocalST((FILETIME*)&li, &tm2); + + if (i > 40) + { + UINT nLastEntry = ((UINT)wCurHour * 60 + (UINT)wCurMinute) / 30; + if (nLastEntry) + nLastEntry *= 30; + else + nLastEntry = 23*60 + 30; + + if (((UINT)tm2.wHour * 60 + (UINT)tm2.wMinute) == nLastEntry) + break; + } + + // icq-style display 1.0, 1.5 etc. hours even though that isn't accurate due to rounding + //mir_snprintf(s, sizeof(s), "%02d:%02d (%d.%d %s)", (UINT)tm2.wHour, (UINT)tm2.wMinute, 1+(i>>1), (i&1) ? 5 : 0, lpszHours); + // display delta time more accurately to match reformatting (that icq doesn't do) + dt = (UINT)((li.QuadPart/MinutesToFileTime) - (ref/MinutesToFileTime)); + if (dt < 60) + mir_snprintf(s, sizeof(s), "%02d:%02d (%d %s)", (UINT)tm2.wHour, (UINT)tm2.wMinute, dt, lpszMinutes); + else + mir_snprintf(s, sizeof(s), "%02d:%02d (%d.%d %s)", (UINT)tm2.wHour, (UINT)tm2.wMinute, dt/60, ((dt%60)*10)/60, lpszHours); + n = SendDlgItemMessage(Dialog,nIDTime,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,nIDTime,CB_SETITEMDATA,(WPARAM)n,(LPARAM)(dt*60)); + + li.QuadPart += (ULONGLONG)30 * MinutesToFileTime; + } +} + +static void PopulateTimeOffsetCombo(HWND Dialog, UINT nIDCombo) +{ + int i, n; + LPCSTR lpszMinutes; + LPCSTR lpszHour; + LPCSTR lpszHours; + LPCSTR lpszDay; + LPCSTR lpszDays; + LPCSTR lpszWeek; + char s[MAX_PATH]; + + SendDlgItemMessage(Dialog,nIDCombo,CB_RESETCONTENT,0,0); + + lpszMinutes = Translate("Minutes"); + lpszHour = Translate("Hour"); + lpszHours = Translate("Hours"); + lpszDay = Translate("Day"); + lpszDays = Translate("Days"); + lpszWeek = Translate("Week"); + + // 5 - 55 minutes (in 5 minute steps) + for (i = 1; i < 12; i++) + { + mir_snprintf(s, sizeof(s), "%d %s", i*5, lpszMinutes); + n = SendDlgItemMessage(Dialog,nIDCombo,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,nIDCombo,CB_SETITEMDATA,(WPARAM)n,(LPARAM)(i*5)); + } + + // 1 hour + mir_snprintf(s, sizeof(s), "1 %s", lpszHour); + n = SendDlgItemMessage(Dialog,nIDCombo,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,nIDCombo,CB_SETITEMDATA,(WPARAM)n,(LPARAM)60); + + // 2, 4, 8 hours + for (i = 2; i <= 8; i+=2) + { + mir_snprintf(s, sizeof(s), "%d %s", i, lpszHours); + n = SendDlgItemMessage(Dialog,nIDCombo,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,nIDCombo,CB_SETITEMDATA,(WPARAM)n,(LPARAM)(i*60)); + } + + // 1 day + mir_snprintf(s, sizeof(s), "1 %s", lpszDay); + n = SendDlgItemMessage(Dialog,nIDCombo,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,nIDCombo,CB_SETITEMDATA,(WPARAM)n,(LPARAM)(24*60)); + + // 2-4 days + for (i = 2; i <= 4; i++) + { + mir_snprintf(s, sizeof(s), "%d %s", i, lpszDays); + n = SendDlgItemMessage(Dialog,nIDCombo,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,nIDCombo,CB_SETITEMDATA,(WPARAM)n,(LPARAM)(i*24*60)); + } + + // 1 week + mir_snprintf(s, sizeof(s), "1 %s", lpszWeek); + n = SendDlgItemMessage(Dialog,nIDCombo,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,nIDCombo,CB_SETITEMDATA,(WPARAM)n,(LPARAM)(7*24*60)); +} + +// returns non-zero if specified time was inside "missing" hour of daylight saving +// IMPORTANT: triggerRelUtcOut is only initialized if IsRelativeCombo() is TRUE and return value is 0 +static int ReformatTimeInputEx(HWND Dialog, UINT nIDTime, UINT nIDRefTime, int h, int m, const SYSTEMTIME *pDateLocal, ULARGE_INTEGER *triggerRelUtcOut) +{ + int n; + UINT dt; + char buf[64]; + const ULONGLONG MinutesToFileTime = (ULONGLONG)60 * FILETIME_TICKS_PER_SEC; + + if (h < 0) + { + // time value is an offset ('m' holds the offset in minutes) + + if ( IsRelativeCombo(Dialog, nIDTime) ) + { + ULONGLONG ref; + ULARGE_INTEGER li; + SYSTEMTIME tm; + + // get reference time (UTC) from hidden control + { + GetDlgItemText(Dialog, nIDRefTime, buf, 30); + li.QuadPart = ref = _strtoui64(buf, NULL, 16); + } + + // clamp delta time to 23.5 hours (coule be issues otherwise as relative combo only handles <24) + if (m > (23*60+30)) + m = 23*60+30; + + li.QuadPart += (ULONGLONG)(m * 60) * FILETIME_TICKS_PER_SEC; + + FileTimeToTzLocalST((FILETIME*)&li, &tm); + h = (int)tm.wHour; + m = (int)tm.wMinute; + + if (triggerRelUtcOut) + *triggerRelUtcOut = li; + + dt = (UINT)((li.QuadPart/MinutesToFileTime) - (ref/MinutesToFileTime)); + + if (dt < 60) + mir_snprintf(buf, sizeof(buf), "%02d:%02d (%d %s)", h, m, dt, Translate("Minutes")); + else + mir_snprintf(buf, sizeof(buf), "%02d:%02d (%d.%d %s)", h, m, dt/60, ((dt%60)*10)/60, Translate("Hours")); + + // search for preset + n = SendDlgItemMessage(Dialog, nIDTime, CB_FINDSTRING, (WPARAM)-1, (LPARAM)buf); + if (n != CB_ERR) + { + SendDlgItemMessage(Dialog, nIDTime, CB_SETCURSEL, (WPARAM)n, 0); + return 0; + } + + SetDlgItemText(Dialog, nIDTime, buf); + } + else + { + // should never happen + SendDlgItemMessage(Dialog, nIDTime, CB_SETCURSEL, 0, 0); + } + + return 0; + } + + // + + sprintf(buf, "%02d:%02d", h, m); + + // search for preset first + n = SendDlgItemMessage(Dialog, nIDTime, CB_FINDSTRING, (WPARAM)-1, (LPARAM)buf); + if (n != CB_ERR) + { + SendDlgItemMessage(Dialog, nIDTime, CB_SETCURSEL, (WPARAM)n, 0); + return 0; + } + + if ( IsRelativeCombo(Dialog, nIDTime) ) + { + // date format is a time offset ("24:43 (5 Minutes)" etc.) + + ULONGLONG ref; + SYSTEMTIME tmRefLocal; + SYSTEMTIME tmTriggerLocal, tmTriggerLocal2; + + // get reference time (UTC) from hidden control + { + GetDlgItemText(Dialog, nIDRefTime, buf, 30); + ref = _strtoui64(buf, NULL, 16); + } + + FileTimeToTzLocalST((FILETIME*)&ref, &tmRefLocal); + + { + ULARGE_INTEGER li; + const UINT nRefT = (UINT)tmRefLocal.wHour * 60 + (UINT)tmRefLocal.wMinute; + const UINT nT = h * 60 + m; + + tmTriggerLocal = tmRefLocal; + tmTriggerLocal.wHour = (WORD)h; + tmTriggerLocal.wMinute = (WORD)m; + tmTriggerLocal.wSecond = 0; + tmTriggerLocal.wMilliseconds = 0; + + if (nT < nRefT) + { + // (this special case only works correctly if time can be returned in triggerRelUtcOut) + if (tmRefLocal.wHour == tmTriggerLocal.wHour && triggerRelUtcOut) + { + // check for special case if daylight saving ends in this hour, then interpret as within the next hour + TzLocalSTToFileTime(&tmTriggerLocal, (FILETIME*)&li); + li.QuadPart += (ULONGLONG)3600*FILETIME_TICKS_PER_SEC; + FileTimeToTzLocalST((FILETIME*)&li, &tmTriggerLocal2); + if ((tmTriggerLocal2.wHour*60+tmTriggerLocal2.wMinute) == (tmTriggerLocal.wHour*60+tmTriggerLocal.wMinute)) + // special case detected + goto output_result; + } + + // tomorrow (add 24h to local time) + SYSTEMTIMEtoFILETIME(&tmTriggerLocal, (FILETIME*)&li); + li.QuadPart += (ULONGLONG)(24*3600)*FILETIME_TICKS_PER_SEC; + FILETIMEtoSYSTEMTIME((FILETIME*)&li, &tmTriggerLocal); + } + + // clean up value for potential daylight saving boundary + TzLocalSTToFileTime(&tmTriggerLocal, (FILETIME*)&li); + FileTimeToTzLocalST((FILETIME*)&li, &tmTriggerLocal2); + + // NOTE: win32 time functions will round hour downward if supplied hour does not exist due to daylight saving + // for example if supplied time is 02:30 on the night the clock is turned forward at 02:00 to 03:00, thus + // there never is a 02:30, the time functions will convert it to 01:30 (and not 03:30 as one might think) + // (02:00 would return 01:00) + + // check for special case when the current time and requested time is inside the "missing" hour + // standard->daylight switch, so that the cleaned up time ends up being earlier than the current + // time even though it originally wasn't (see note above) + if ((tmTriggerLocal2.wHour*60+tmTriggerLocal2.wMinute) < (tmTriggerLocal.wHour*60+tmTriggerLocal.wMinute)) + { + // special case detected, fall back to current time so at least the reminder won't be missed + // due to ending up at an undesired time (this way the user immediately notices something was wrong) + SendDlgItemMessage(Dialog, nIDTime, CB_SETCURSEL, 0, 0); +invalid_dst: + MessageBox(Dialog, Translate("The specified time is invalid due to begin of daylight saving (summer time)."), SECTIONNAME, MB_OK|MB_ICONWARNING); + return 1; + } + +output_result: + if (triggerRelUtcOut) + *triggerRelUtcOut = li; + + dt = (UINT)((li.QuadPart/MinutesToFileTime) - (ref/MinutesToFileTime)); + + if (dt < 60) + mir_snprintf(buf, sizeof(buf), "%02d:%02d (%d %s)", h, m, dt, Translate("Minutes")); + else + mir_snprintf(buf, sizeof(buf), "%02d:%02d (%d.%d %s)", h, m, dt/60, ((dt%60)*10)/60, Translate("Hours")); + } + } + else + { + // absolute time (00:00 to 23:59), clean up time to make sure it's not inside "missing" hour (will be rounded downard) + + FILETIME ft; + SYSTEMTIME Date = *pDateLocal; + Date.wHour = h; + Date.wMinute = m; + Date.wSecond = 0; + Date.wMilliseconds = 0; + + TzLocalSTToFileTime(&Date, &ft); + FileTimeToTzLocalST(&ft, &Date); + + if ((int)Date.wHour != h || (int)Date.wMinute != m) + { + sprintf(buf, "%02d:%02d", (UINT)Date.wHour, (UINT)Date.wMinute); + + // search for preset again + n = SendDlgItemMessage(Dialog, nIDTime, CB_FINDSTRING, (WPARAM)-1, (LPARAM)buf); + if (n != CB_ERR) + { + SendDlgItemMessage(Dialog, nIDTime, CB_SETCURSEL, (WPARAM)n, 0); + goto invalid_dst; + } + + SetDlgItemText(Dialog, nIDTime, buf); + + goto invalid_dst; + } + } + + SetDlgItemText(Dialog, nIDTime, buf); + + return 0; +} + +static __inline int ReformatTimeInput(HWND Dialog, UINT nIDTime, UINT nIDRefTime, int h, int m, const SYSTEMTIME *pDateLocal) +{ + return ReformatTimeInputEx(Dialog, nIDTime, nIDRefTime, h, m, pDateLocal, NULL); +} + +// in: pDate contains the desired trigger date in LOCAL time +// out: pDate contains the resulting trigger time and date in UTC +static BOOL GetTriggerTime(HWND Dialog, UINT nIDTime, UINT nIDRefTime, SYSTEMTIME *pDate) +{ + ULARGE_INTEGER li; + char buf[32]; + int n; + int h, m; + + // get reference (UTC) time from hidden control + { + GetDlgItemText(Dialog, nIDRefTime, buf, 30); + li.QuadPart = _strtoui64(buf, NULL, 16); + } + + if ((n = SendDlgItemMessage(Dialog, nIDTime, CB_GETCURSEL, 0, 0)) != CB_ERR) + { + // use preset value +preset_value:; + if ( IsRelativeCombo(Dialog, nIDTime) ) + { + // time offset from ref time ("24:43 (5 Minutes)" etc.) + + UINT nDeltaSeconds = (UINT)SendDlgItemMessage(Dialog, nIDTime, CB_GETITEMDATA, (WPARAM)n, 0); + li.QuadPart += (ULONGLONG)nDeltaSeconds * FILETIME_TICKS_PER_SEC; + + FILETIMEtoSYSTEMTIME((FILETIME*)&li, pDate); + + // if specified time is a small offset (< 10 Minutes) then retain current second count for better accuracy + // otherwise try to match specified time (which never contains seconds only even minutes) as close as possible + if (nDeltaSeconds >= 10*60) + { + pDate->wSecond = 0; + pDate->wMilliseconds = 0; + } + } + else + { + // absolute time (offset from midnight on pDate) + + UINT nDeltaSeconds = (UINT)((ULONG)SendDlgItemMessage(Dialog, nIDTime, CB_GETITEMDATA, (WPARAM)n, 0) & ~0x80000000); + pDate->wHour = 0; + pDate->wMinute = 0; + pDate->wSecond = 0; + pDate->wMilliseconds = 0; + TzLocalSTToFileTime(pDate, (FILETIME*)&li); + li.QuadPart += (ULONGLONG)nDeltaSeconds * FILETIME_TICKS_PER_SEC; + + FILETIMEtoSYSTEMTIME((FILETIME*)&li, pDate); + } + + return TRUE; + } + + // user entered a custom value + + GetDlgItemText(Dialog, nIDTime, buf, 30); + + if ( !ParseTime(buf, &h, &m, FALSE, IsRelativeCombo(Dialog, nIDTime)) ) + { + MessageBox(Dialog, Translate("The specified time is invalid."), SECTIONNAME, MB_OK|MB_ICONWARNING); + return FALSE; + } + + if ( IsRelativeCombo(Dialog, nIDTime) ) + { + // date has not been changed, the specified time is a time between reftime and reftime+24h + + ULARGE_INTEGER li2; + + if ( ReformatTimeInputEx(Dialog, nIDTime, nIDRefTime, h, m, pDate, &li2) ) + return FALSE; + + // check if reformatted value is a preset + if ((n = SendDlgItemMessage(Dialog, nIDTime, CB_GETCURSEL, 0, 0)) != CB_ERR) + goto preset_value; + + FILETIMEtoSYSTEMTIME((FILETIME*)&li2, pDate); + + return TRUE; + } + else + { + if ( ReformatTimeInputEx(Dialog, nIDTime, nIDRefTime, h, m, pDate, NULL) ) + return FALSE; + + // check if reformatted value is a preset + if ((n = SendDlgItemMessage(Dialog, nIDTime, CB_GETCURSEL, 0, 0)) != CB_ERR) + goto preset_value; + } + + // absolute time (on pDate) + + pDate->wHour = h; + pDate->wMinute = m; + pDate->wSecond = 0; + pDate->wMilliseconds = 0; + + TzLocalSTToFileTime(pDate, (FILETIME*)&li); + FILETIMEtoSYSTEMTIME((FILETIME*)&li, pDate); + + return TRUE; +} + +static void OnDateChanged(HWND Dialog, UINT nDateID, UINT nTimeID, UINT nRefTimeID) +{ + // repopulate time combo list with regular times (not offsets like "23:32 (5 minutes)" etc.) + + SYSTEMTIME Date, DateUtc; + int h = -1, m; + char s[32]; + + GetDlgItemText(Dialog, nTimeID, s, 30); + + ParseTime(s, &h, &m, FALSE, FALSE); + + SendDlgItemMessage(Dialog, nDateID, DTM_GETSYSTEMTIME, 0, (LPARAM)&Date); + + TzSpecificLocalTimeToSystemTime(NULL, &Date, &DateUtc); + PopulateTimeCombo(Dialog, nTimeID, FALSE, &DateUtc); + + if (h < 0) + { + // parsing failed, default to current time + SYSTEMTIME tm; + GetLocalTime(&tm); + h = (UINT)tm.wHour; + m = (UINT)tm.wMinute; + } + + ReformatTimeInput(Dialog, nTimeID, nRefTimeID, h, m, &Date); +} + + +int CALLBACK DlgProcNotifyReminder(HWND Dialog,UINT Message,WPARAM wParam,LPARAM lParam) +{ + int I; + + switch (Message) + { + case WM_INITDIALOG: + { + SYSTEMTIME tm; + ULARGE_INTEGER li; + + GetSystemTime(&tm); + SYSTEMTIMEtoFILETIME(&tm, (FILETIME*)&li); + + TranslateDialogDefault(Dialog); + + // save reference time in hidden control, is needed when adding reminder to properly detect if speicifed + // time wrapped around to tomorrow or not (dialog could in theory be open for a longer period of time + // which could potentially mess up things otherwise) + { + char s[32]; + sprintf(s, "%I64x", li.QuadPart); + SetDlgItemText(Dialog, IDC_REFTIME, s); + } + + BringWindowToTop(Dialog); + + PopulateTimeOffsetCombo(Dialog, IDC_REMINDAGAININ); + + ShowWindow(GetDlgItem(Dialog,IDC_REMINDAGAININ),SW_SHOW); + ShowWindow(GetDlgItem(Dialog,IDC_DATEAGAIN),SW_HIDE); + ShowWindow(GetDlgItem(Dialog,IDC_TIMEAGAIN),SW_HIDE); + ShowWindow(GetDlgItem(Dialog,IDC_STATIC_DATE),SW_HIDE); + ShowWindow(GetDlgItem(Dialog,IDC_STATIC_TIME),SW_HIDE); + SendDlgItemMessage(Dialog,IDC_AFTER,BM_SETCHECK,1,0); + SendDlgItemMessage(Dialog,IDC_ONDATE,BM_SETCHECK,0,0); + SendDlgItemMessage(Dialog,IDC_REMINDAGAININ,CB_SETCURSEL,0,0); + + SendDlgItemMessage(Dialog, IDC_REMDATA, EM_LIMITTEXT, MAX_REMINDER_LEN, 0); + + PopulateTimeCombo(Dialog, IDC_TIMEAGAIN, TRUE, &tm); + + FileTimeToTzLocalST((FILETIME*)&li, &tm); + + // make sure date picker uses reference time + SendDlgItemMessage(Dialog,IDC_DATEAGAIN,DTM_SETSYSTEMTIME,0,(LPARAM)&tm); + InitDatePicker(Dialog, IDC_DATEAGAIN); + + SendDlgItemMessage(Dialog,IDC_TIMEAGAIN,CB_SETCURSEL,0,0); + + return TRUE; + } + case WM_NCDESTROY: + RemoveProp(GetDlgItem(Dialog, IDC_DATEAGAIN), TEXT("OldWndProc")); + return TRUE; + case WM_NOTIFY: + { + if (wParam == IDC_DATEAGAIN) + { + NMLISTVIEW *NM = (NMLISTVIEW*)lParam; + + switch (NM->hdr.code) + { + case DTN_DATETIMECHANGE: + OnDateChanged(Dialog, IDC_DATEAGAIN, IDC_TIMEAGAIN, IDC_REFTIME); + break; + } + } + } + break; + case WM_CLOSE: + { + int ReminderCount = TreeGetCount(RemindersList); + for (I = 0; I < ReminderCount; I++) + { + REMINDERDATA *pReminder = (REMINDERDATA*)TreeGetAt(RemindersList, I); + + if (pReminder->handle == Dialog) + { + DeleteReminder(pReminder); + JustSaveReminders(); + break; + } + } + NOTIFY_LIST(); + } + DestroyWindow(Dialog); + return TRUE; + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDC_TIMEAGAIN: + switch (HIWORD(wParam)) + { + case CBN_KILLFOCUS: + // reformat displayed value + if (SendDlgItemMessage(Dialog, IDC_TIMEAGAIN, CB_GETCURSEL, 0, 0) == CB_ERR) + { + char buf[64]; + int h, m; + GetDlgItemText(Dialog, IDC_TIMEAGAIN, buf, 30); + + if ( ParseTime(buf, &h, &m, FALSE, IsRelativeCombo(Dialog, IDC_TIMEAGAIN)) ) + { + SYSTEMTIME Date; + SendDlgItemMessage(Dialog,IDC_DATEAGAIN,DTM_GETSYSTEMTIME,0,(LPARAM)&Date); + + ReformatTimeInput(Dialog, IDC_TIMEAGAIN, IDC_REFTIME, h, m, &Date); + } + else + { + SendDlgItemMessage(Dialog, IDC_TIMEAGAIN, CB_SETCURSEL, 0, 0); + } + } + break; + } + break; + + case IDC_REMINDAGAININ: + switch (HIWORD(wParam)) + { + case CBN_KILLFOCUS: + // reformat displayed value if it has been edited + if (SendDlgItemMessage(Dialog,IDC_REMINDAGAININ,CB_GETCURSEL,0,0) == CB_ERR) + { + char buf[64]; + int h, m; + GetDlgItemText(Dialog, IDC_REMINDAGAININ, buf, 30); + + if (ParseTime(buf, &h, &m, TRUE, TRUE) && h+m) + { + if (h) + { + LPCSTR lpszHours = Translate("Hours"); + sprintf(buf, "%d:%02d %s", h, m, lpszHours); + } + else + { + LPCSTR lpszMinutes = Translate("Minutes"); + sprintf(buf, "%d %s", m, lpszMinutes); + } + SetDlgItemText(Dialog, IDC_REMINDAGAININ, buf); + } + else + { + SendDlgItemMessage(Dialog,IDC_REMINDAGAININ,CB_SETCURSEL,0,0); + } + } + break; + } + break; + + case IDC_AFTER: + { + ShowWindow(GetDlgItem(Dialog,IDC_REMINDAGAININ),SW_SHOW); + ShowWindow(GetDlgItem(Dialog,IDC_DATEAGAIN),SW_HIDE); + ShowWindow(GetDlgItem(Dialog,IDC_TIMEAGAIN),SW_HIDE); + ShowWindow(GetDlgItem(Dialog,IDC_STATIC_DATE),SW_HIDE); + ShowWindow(GetDlgItem(Dialog,IDC_STATIC_TIME),SW_HIDE); + return TRUE; + } + case IDC_ONDATE: + { + ShowWindow(GetDlgItem(Dialog,IDC_DATEAGAIN),SW_SHOW); + ShowWindow(GetDlgItem(Dialog,IDC_TIMEAGAIN),SW_SHOW); + ShowWindow(GetDlgItem(Dialog,IDC_STATIC_DATE),SW_SHOW); + ShowWindow(GetDlgItem(Dialog,IDC_STATIC_TIME),SW_SHOW); + ShowWindow(GetDlgItem(Dialog,IDC_REMINDAGAININ),SW_HIDE); + return TRUE; + } + case IDC_DISMISS: + { + int ReminderCount = TreeGetCount(RemindersList); + for (I = 0; I < ReminderCount; I++) + { + REMINDERDATA *pReminder = (REMINDERDATA*)TreeGetAt(RemindersList, I); + + if (pReminder->handle == Dialog) + { + DeleteReminder(pReminder); + JustSaveReminders(); + break; + } + } + NOTIFY_LIST(); + DestroyWindow(Dialog); + return TRUE; + } + case IDC_REMINDAGAIN: + { + int ReminderCount = TreeGetCount(RemindersList); + for (I = 0; I < ReminderCount; I++) + { + REMINDERDATA *pReminder = (REMINDERDATA*)TreeGetAt(RemindersList, I); + + if (pReminder->handle == Dialog) + { + if (SendDlgItemMessage(Dialog,IDC_AFTER,BM_GETCHECK,0,0) == BST_CHECKED) + { + // delta time + + ULONGLONG TT; + SYSTEMTIME tm; + ULARGE_INTEGER li; + int n; + + GetSystemTime(&tm); + SYSTEMTIMEtoFILETIME(&tm, (FILETIME*)&li); + + n = SendDlgItemMessage(Dialog,IDC_REMINDAGAININ,CB_GETCURSEL,0,0); + if (n != CB_ERR) + { + TT = SendDlgItemMessage(Dialog,IDC_REMINDAGAININ,CB_GETITEMDATA,(WPARAM)n,0) * 60; + + if (TT >= 24*3600) + { + // selection is 1 day or more, take daylight saving boundaries into consideration + // (ie. 24 hour might actually be 23 or 25, in order for reminder to pop up at the + // same time tomorrow) + SYSTEMTIME tm2, tm3; + ULARGE_INTEGER li2 = li; + FileTimeToTzLocalST((FILETIME*)&li2, &tm2); + li2.QuadPart += (TT * FILETIME_TICKS_PER_SEC); + FileTimeToTzLocalST((FILETIME*)&li2, &tm3); + if (tm2.wHour != tm3.wHour || tm2.wMinute != tm3.wMinute) + { + // boundary crossed + + // do a quick and dirty sanity check that times not more than 2 hours apart + if (abs((int)(tm3.wHour*60+tm3.wMinute)-(int)(tm2.wHour*60+tm2.wMinute)) <= 120) + { + // adjust TT so that same HH:MM is set + tm3.wHour = tm2.wHour; + tm3.wMinute = tm2.wMinute; + TzLocalSTToFileTime(&tm3, (FILETIME*)&li2); + TT = (li2.QuadPart - li.QuadPart) / FILETIME_TICKS_PER_SEC; + } + } + } + } + else + { + // parse user input + char s[32]; + int h = 0, m = 0; + GetDlgItemText(Dialog, IDC_REMINDAGAININ, s, 30); + ParseTime(s, &h, &m, TRUE, TRUE); + m += h * 60; + if (!m) + { + MessageBox(Dialog, Translate("The specified time offset is invalid."), SECTIONNAME, MB_OK|MB_ICONWARNING); + return TRUE; + } + + TT = m * 60; + } + + pReminder->When = li; + pReminder->When.QuadPart += (TT * FILETIME_TICKS_PER_SEC); + } + else if (SendDlgItemMessage(Dialog,IDC_ONDATE,BM_GETCHECK,0,0) == BST_CHECKED) + { + SYSTEMTIME Date; + + SendDlgItemMessage(Dialog,IDC_DATEAGAIN,DTM_GETSYSTEMTIME,0,(LPARAM)&Date); + + if ( !GetTriggerTime(Dialog, IDC_TIMEAGAIN, IDC_REFTIME, &Date) ) + break; + + SYSTEMTIMEtoFILETIME(&Date, (FILETIME*)&pReminder->When); + } + + // update reminder text + { + char *ReminderText = NULL; + int SzT = SendDlgItemMessage(Dialog,IDC_REMDATA,WM_GETTEXTLENGTH,0,0); + if (SzT) + { + if (SzT > MAX_REMINDER_LEN) SzT = MAX_REMINDER_LEN; + ReminderText = (char*)malloc(SzT+1); + SendDlgItemMessage(Dialog,IDC_REMDATA,WM_GETTEXT,SzT+1,(LPARAM)ReminderText); + } + if (pReminder->Reminder) + free(pReminder->Reminder); + pReminder->Reminder = ReminderText; + } + + pReminder->RemVisible = FALSE; + pReminder->handle = NULL; + + // re-insert tree item sorted + TreeDelete(&RemindersList,pReminder); + TreeAddSorted(&RemindersList,pReminder,ReminderSortCb); + JustSaveReminders(); + break; + } + } + NOTIFY_LIST(); + DestroyWindow(Dialog); + return TRUE; + } + case IDC_NONE: + {// create note from remainder + int ReminderCount = TreeGetCount(RemindersList); + for (I = 0; I < ReminderCount; I++) + { + REMINDERDATA *pReminder = (REMINDERDATA*)TreeGetAt(RemindersList, I); + + if (pReminder->handle == Dialog) + { + // get up-to-date reminder text + char *ReminderText = NULL; + int SzT = SendDlgItemMessage(Dialog,IDC_REMDATA,WM_GETTEXTLENGTH,0,0); + if (SzT) + { + if (SzT > MAX_REMINDER_LEN) SzT = MAX_REMINDER_LEN; + ReminderText = (char*)malloc(SzT+1); + SendDlgItemMessage(Dialog,IDC_REMDATA,WM_GETTEXT,SzT+1,(LPARAM)ReminderText); + } + + SetFocus(NewNote(0, 0, -1, -1, ReminderText, 0, TRUE, TRUE, 0)->REHwnd); + break; + } + } + return TRUE; + } + } + } + } + return FALSE; +} + +int CALLBACK DlgProcNewReminder(HWND Dialog,UINT Message,WPARAM wParam,LPARAM lParam) +{ + HICON hIcon = NULL; + switch (Message) + { + case WM_INITDIALOG: + { + ULARGE_INTEGER li; + SYSTEMTIME tm; + + if (NewReminderVisible == 2) + { + // opening the edit reminder dialog (uses same dialog resource as add reminder) + SetWindowText(Dialog, _T("Reminder")); + SetDlgItemText(Dialog, IDC_ADDREMINDER, _T("&Update Reminder")); + ShowWindow(GetDlgItem(Dialog, IDC_VIEWREMINDERS), SW_HIDE); + + li = pEditReminder->When; + FILETIMEtoSYSTEMTIME((FILETIME*)&li, &tm); + } + else + { + GetSystemTime(&tm); + SYSTEMTIMEtoFILETIME(&tm, (FILETIME*)&li); + } + + TranslateDialogDefault(Dialog); + + // save reference time in hidden control, is needed when adding reminder to properly detect if speicifed + // time wrapped around to tomorrow or not (dialog could in theory be open for a longer period of time + // which could potentially mess up things otherwise) + { + char s[32]; + sprintf(s, "%I64x", li.QuadPart); + SetDlgItemText(Dialog, IDC_REFTIME, s); + } + + /*SendDlgItemMessage(Dialog,IDC_NONE,BM_SETCHECK,1,0); + SendDlgItemMessage(Dialog,IDC_DAILY,BM_SETCHECK,0,0); + SendDlgItemMessage(Dialog,IDC_WEEKLY,BM_SETCHECK,0,0); + SendDlgItemMessage(Dialog,IDC_MONTHLY,BM_SETCHECK,0,0);*/ + + PopulateTimeCombo(Dialog, IDC_TIME, NewReminderVisible != 2, &tm); + + FileTimeToTzLocalST((FILETIME*)&li, &tm); + + // make sure date picker uses reference time + SendDlgItemMessage(Dialog,IDC_DATE,DTM_SETSYSTEMTIME,0,(LPARAM)&tm); + InitDatePicker(Dialog, IDC_DATE); + + SendDlgItemMessage(Dialog, IDC_REMINDER, EM_LIMITTEXT, MAX_REMINDER_LEN, 0); + + if (NewReminderVisible == 2) + { + int n; + char s[32]; + mir_snprintf(s, sizeof(s), "%02d:%02d", (UINT)tm.wHour, (UINT)tm.wMinute); + + // search for preset first + n = SendDlgItemMessage(Dialog, IDC_TIME, CB_FINDSTRING, (WPARAM)-1, (LPARAM)s); + if (n != CB_ERR) + SendDlgItemMessage(Dialog, IDC_TIME, CB_SETCURSEL, (WPARAM)n, 0); + else + SetDlgItemText(Dialog, IDC_TIME, s); + + SetDlgItemText(Dialog, IDC_REMINDER, pEditReminder->Reminder); + } + else + { + SendDlgItemMessage(Dialog,IDC_TIME,CB_SETCURSEL,0,0); + } + + // populate sound repeat combo + { + char s[64]; + int n; + LPCSTR lpszEvery = Translate("Every"); + LPCSTR lpszSeconds = Translate("Seconds"); + + // NOTE: use multiples of REMINDER_UPDATE_INTERVAL_SHORT (currently 5 seconds) + + n = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_ADDSTRING,0,(LPARAM)Translate("Never")); + SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)0); + + mir_snprintf(s, sizeof(s), "%s 5 %s", lpszEvery, lpszSeconds); + n = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)5); + + mir_snprintf(s, sizeof(s), "%s 10 %s", lpszEvery, lpszSeconds); + n = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)10); + + mir_snprintf(s, sizeof(s), "%s 15 %s", lpszEvery, lpszSeconds); + n = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)15); + + mir_snprintf(s, sizeof(s), "%s 20 %s", lpszEvery, lpszSeconds); + n = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)20); + + mir_snprintf(s, sizeof(s), "%s 30 %s", lpszEvery, lpszSeconds); + n = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)30); + + mir_snprintf(s, sizeof(s), "%s 60 %s", lpszEvery, lpszSeconds); + n = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_ADDSTRING,0,(LPARAM)s); + SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)60); + + if (NewReminderVisible == 2 && pEditReminder->RepeatSound) + { + mir_snprintf(s, sizeof(s), "%s %d %s", lpszEvery, pEditReminder->RepeatSound, lpszSeconds); + SetDlgItemText(Dialog, IDC_COMBO_REPEATSND, s); + SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETCURSEL,SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_FINDSTRINGEXACT,(WPARAM)-1,(LPARAM)s),0); + } + else + { + SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_SETCURSEL,0,0); + } + } + + // populate sound selection combo + { + int n = SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_ADDSTRING,0,(LPARAM)Translate("Default")); + SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)0); + n = SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_ADDSTRING,0,(LPARAM)Translate("Alternative 1")); + SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)1); + n = SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_ADDSTRING,0,(LPARAM)Translate("Alternative 2")); + SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)2); + n = SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_ADDSTRING,0,(LPARAM)Translate("None")); + SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_SETITEMDATA,(WPARAM)n,(LPARAM)-1); + + if (NewReminderVisible == 2 && pEditReminder->SoundSel) + { + const UINT n = pEditReminder->SoundSel<0 ? 3 : pEditReminder->SoundSel; + SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_SETCURSEL,n,0); + } + else + { + SendDlgItemMessage(Dialog,IDC_COMBO_SOUND,CB_SETCURSEL,0,0); + } + } + + hIcon = Skin_GetIconByHandle(hIconLibItem[12]); + SendDlgItemMessage(Dialog,IDC_BTN_PLAYSOUND,BM_SETIMAGE,(WPARAM)IMAGE_ICON,(LPARAM)hIcon); + + if (NewReminderVisible == 2 && pEditReminder->SoundSel) + { + EnableWindow(GetDlgItem(Dialog, IDC_BTN_PLAYSOUND), pEditReminder->SoundSel>=0); + EnableWindow(GetDlgItem(Dialog, IDC_COMBO_REPEATSND), pEditReminder->SoundSel>=0); + } + + if (NewReminderVisible == 2) + SetFocus( GetDlgItem(Dialog, IDC_ADDREMINDER) ); + else + SetFocus( GetDlgItem(Dialog, IDC_REMINDER) ); + + return FALSE; + } + case WM_NCDESTROY: + RemoveProp(GetDlgItem(Dialog, IDC_DATE), TEXT("OldWndProc")); + return TRUE; + case WM_CLOSE: + { + if (NewReminderVisible == 2) + { + pEditReminder->RemVisible = FALSE; + } + DestroyWindow(Dialog); + NewReminderVisible = FALSE; + pEditReminder = NULL; + return TRUE; + } + case WM_NOTIFY: + { + if (wParam == IDC_DATE) + { + NMLISTVIEW *NM = (NMLISTVIEW*)lParam; + + switch (NM->hdr.code) + { + case DTN_DATETIMECHANGE: + OnDateChanged(Dialog, IDC_DATE, IDC_TIME, IDC_REFTIME); + break; + } + } + } + break; + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDC_TIME: + switch (HIWORD(wParam)) + { + case CBN_KILLFOCUS: + // reformat displayed value + if (SendDlgItemMessage(Dialog, IDC_TIME, CB_GETCURSEL, 0, 0) == CB_ERR) + { + char buf[64]; + int h, m; + GetDlgItemText(Dialog, IDC_TIME, buf, 30); + + if ( ParseTime(buf, &h, &m, FALSE, IsRelativeCombo(Dialog, IDC_TIME)) ) + { + SYSTEMTIME Date; + SendDlgItemMessage(Dialog,IDC_DATE,DTM_GETSYSTEMTIME,0,(LPARAM)&Date); + ReformatTimeInput(Dialog, IDC_TIME, IDC_REFTIME, h, m, &Date); + } + else + { + SendDlgItemMessage(Dialog, IDC_TIME, CB_SETCURSEL, 0, 0); + } + } + break; + } + break; + case IDC_COMBO_SOUND: + switch (HIWORD(wParam)) + { + case CBN_SELENDOK: + { + int n = SendDlgItemMessage(Dialog, IDC_COMBO_SOUND, CB_GETCURSEL, 0, 0); + n = (int)SendDlgItemMessage(Dialog, IDC_COMBO_SOUND, CB_GETITEMDATA, (WPARAM)n, 0); + + EnableWindow(GetDlgItem(Dialog, IDC_BTN_PLAYSOUND), n>=0); + EnableWindow(GetDlgItem(Dialog, IDC_COMBO_REPEATSND), n>=0); + } + break; + } + break; + + case IDC_BTN_PLAYSOUND: + { + int n = SendDlgItemMessage(Dialog, IDC_COMBO_SOUND, CB_GETCURSEL, 0, 0); + n = (int)SendDlgItemMessage(Dialog, IDC_COMBO_SOUND, CB_GETITEMDATA, (WPARAM)n, 0); + switch (n) + { + case 0: SkinPlaySound("AlertReminder"); break; + case 1: SkinPlaySound("AlertReminder2"); break; + case 2: SkinPlaySound("AlertReminder3"); break; + } + } + return TRUE; + case IDC_CLOSE: + { + if (NewReminderVisible == 2) + { + pEditReminder->RemVisible = FALSE; + } + DestroyWindow(Dialog); + NewReminderVisible = FALSE; + pEditReminder = NULL; + return TRUE; + } + case IDC_VIEWREMINDERS: + { + ListReminders(); + return TRUE; + } + case IDC_ADDREMINDER: + { + char *ReminderText = NULL; + int SzT; + SYSTEMTIME Date; + REMINDERDATA* TempRem; + int RepeatSound; + + SendDlgItemMessage(Dialog,IDC_DATE,DTM_GETSYSTEMTIME,0,(LPARAM)&Date); + + if ( !GetTriggerTime(Dialog, IDC_TIME, IDC_REFTIME, &Date) ) + break; + + RepeatSound = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_GETCURSEL,0,0); + if (RepeatSound != CB_ERR) + RepeatSound = SendDlgItemMessage(Dialog,IDC_COMBO_REPEATSND,CB_GETITEMDATA,(WPARAM)RepeatSound,0); + else + RepeatSound = 0; + + SzT = SendDlgItemMessage(Dialog,IDC_REMINDER,WM_GETTEXTLENGTH,0,0); + if (SzT) + { + if (SzT > MAX_REMINDER_LEN) SzT = MAX_REMINDER_LEN; + ReminderText = (char*)malloc(SzT+1); + SendDlgItemMessage(Dialog,IDC_REMINDER,WM_GETTEXT,SzT+1,(LPARAM)ReminderText); + } + + if (NewReminderVisible != 2) + { + // new reminder + TempRem = (REMINDERDATA*)malloc(sizeof(REMINDERDATA)); + TempRem->uid = CreateUid(); + SYSTEMTIMEtoFILETIME(&Date, (FILETIME*)&TempRem->When); + TempRem->Reminder = ReminderText; + TempRem->RemVisible = FALSE; + TempRem->SystemEventQueued = 0; + TempRem->RepeatSoundTTL = 0; + TempRem->SoundSel = (int)SendDlgItemMessage(Dialog, IDC_COMBO_SOUND, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(Dialog, IDC_COMBO_SOUND, CB_GETCURSEL, 0, 0), 0); + TempRem->RepeatSound = TempRem->SoundSel<0 ? 0 : (UINT)RepeatSound; + TreeAddSorted(&RemindersList,TempRem,ReminderSortCb); + } + else + { + // update existing reminder + + SYSTEMTIMEtoFILETIME(&Date, (FILETIME*)&pEditReminder->When); + if (pEditReminder->Reminder) + free(pEditReminder->Reminder); + pEditReminder->Reminder = ReminderText; + pEditReminder->SoundSel = (int)SendDlgItemMessage(Dialog, IDC_COMBO_SOUND, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(Dialog, IDC_COMBO_SOUND, CB_GETCURSEL, 0, 0), 0); + pEditReminder->RepeatSound = pEditReminder->SoundSel<0 ? 0 : (UINT)RepeatSound; + + // re-insert tree item sorted + TreeDelete(&RemindersList,pEditReminder); + TreeAddSorted(&RemindersList,pEditReminder,ReminderSortCb); + + pEditReminder->RemVisible = FALSE; + } + SetDlgItemText(Dialog,IDC_REMINDER,""); + JustSaveReminders(); + NOTIFY_LIST(); + + if (g_CloseAfterAddReminder || NewReminderVisible == 2) + { + DestroyWindow(Dialog); + NewReminderVisible = FALSE; + pEditReminder = NULL; + } + } + } + } + case WM_DESTROY: + { + Skin_ReleaseIcon(hIcon); + break; + } + } + return FALSE; +} + +static void InitListView(HWND AHLV) +{ + LV_ITEM lvTIt; + int I; + char *S; + char S1[128]; + REMINDERDATA *pReminder; + TREEELEMENT *TTE; + + ListView_SetHoverTime(AHLV,700); + ListView_SetExtendedListViewStyle(AHLV,LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_TRACKSELECT); + ListView_DeleteAllItems(AHLV); + + I = 0; + TTE = RemindersList; + while (TTE) + { + pReminder = (REMINDERDATA*)TTE->ptrdata; + + lvTIt.mask = LVIF_TEXT; + + GetTriggerTimeString(&pReminder->When, S1, sizeof(S1), TRUE); + + lvTIt.iItem = I; + lvTIt.iSubItem = 0; + lvTIt.pszText = S1; + lvTIt.cchTextMax = strlen(S1); + ListView_InsertItem(AHLV,&lvTIt); + lvTIt.mask = LVIF_TEXT; + S = GetPreviewString(pReminder->Reminder); + lvTIt.iItem = I; + lvTIt.iSubItem = 1; + lvTIt.pszText = S; + lvTIt.cchTextMax = strlen(S); + ListView_SetItem(AHLV,&lvTIt); + + I++; + TTE = (TREEELEMENT*)TTE->next; + } + + ListView_SetItemState(AHLV,0,LVIS_SELECTED,LVIS_SELECTED); +} + +void OnListResize(HWND Dialog) +{ + HWND hList, hText, hBtnNew, hBtnClose; + RECT lr, cr, tr, clsr; + int th, btnh, btnw, MARGIN; + POINT org = {0}; + + hList = GetDlgItem(Dialog, IDC_LISTREMINDERS); + hText = GetDlgItem(Dialog, IDC_REMINDERDATA); + hBtnNew = GetDlgItem(Dialog, IDC_ADDNEWREMINDER); + hBtnClose = GetDlgItem(Dialog, IDC_CLOSE); + + ClientToScreen(Dialog, &org); + GetClientRect(Dialog, &cr); + + GetWindowRect(hList, &lr); OffsetRect(&lr, -org.x, -org.y); + GetWindowRect(hText, &tr); OffsetRect(&tr, -org.x, -org.y); + GetWindowRect(hBtnClose, &clsr); OffsetRect(&clsr, -org.x, -org.y); + + MARGIN = lr.left; + + th = tr.bottom - tr.top; + btnh = clsr.bottom - clsr.top; + btnw = clsr.right - clsr.left; + + clsr.left = cr.right - MARGIN - btnw; + clsr.top = cr.bottom - MARGIN - btnh; + + tr.left = MARGIN; + tr.right = cr.right - MARGIN; + tr.bottom = clsr.top - MARGIN - 2; + tr.top = tr.bottom - th; + + lr.right = cr.right - MARGIN; + lr.bottom = tr.top - 5; + + MoveWindow(hList, lr.left, lr.top, lr.right-lr.left, lr.bottom-lr.top, FALSE); + MoveWindow(hText, tr.left, tr.top, tr.right-tr.left, tr.bottom-tr.top, FALSE); + + MoveWindow(hBtnClose, clsr.left, clsr.top, btnw, btnh, FALSE); + clsr.left -= btnw + 2; + MoveWindow(hBtnNew, clsr.left, clsr.top, btnw, btnh, FALSE); + + RedrawWindow(Dialog, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE); + //UpdateWindow(Dialog); +} + +void UpdateGeomFromWnd(HWND Dialog, int *geom, int *colgeom, int nCols) +{ + if (geom) + { + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + + GetWindowPlacement(Dialog, &wp); + + geom[0] = wp.rcNormalPosition.left; + geom[1] = wp.rcNormalPosition.top; + geom[2] = wp.rcNormalPosition.right - wp.rcNormalPosition.left; + geom[3] = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; + } + + if (colgeom) + { + int i; + HWND H = GetDlgItem(Dialog, IDC_LISTREMINDERS); + + for (i=0; iSystemEventQueued) + mii.fState |= MFS_GRAYED; + SetMenuItemInfo(FhMenu, ID_CONTEXTMENUREMINDERLISTVIEW_EDIT, FALSE, &mii); + + if (!pReminder) + EnableMenuItem(FhMenu, IDM_DELETEREMINDER, MF_GRAYED|MF_BYCOMMAND); + + CallService(MS_LANGPACK_TRANSLATEMENU,(DWORD)FhMenu,0); + TrackPopupMenu(FhMenu,TPM_LEFTALIGN | TPM_RIGHTBUTTON,LOWORD(lParam),HIWORD(lParam),0,AhWnd,0); + DestroyMenu(hMenuLoad); + return TRUE; +} + +int CALLBACK DlgProcViewReminders(HWND Dialog,UINT Message,WPARAM wParam,LPARAM lParam) +{ + LV_COLUMN lvCol; + NMLISTVIEW *NM; + char *S; + int I; + + switch (Message) + { + case WM_SIZE: + { + OnListResize(Dialog); + UpdateGeomFromWnd(Dialog, g_reminderListGeom, NULL, 0); + break; + } + case WM_MOVE: + UpdateGeomFromWnd(Dialog, g_reminderListGeom, NULL, 0); + break; + case WM_GETMINMAXINFO: + { + MINMAXINFO *mm = (MINMAXINFO*)lParam; + mm->ptMinTrackSize.x = 394; + mm->ptMinTrackSize.y = 300; + } + return 0; + case WM_RELOAD: + { + SetDlgItemText(Dialog,IDC_REMINDERDATA,""); + InitListView(GetDlgItem(Dialog,IDC_LISTREMINDERS)); + return TRUE; + } + case WM_CONTEXTMENU: + { + HWND H; + REMINDERDATA *pReminder = NULL; + + H = GetDlgItem(Dialog,IDC_LISTREMINDERS); + if ( ListView_GetSelectedCount(H) ) + { + I = ListView_GetSelectionMark(H); + if (I != -1) + { + pReminder = (REMINDERDATA*)TreeGetAt(RemindersList,I); + } + } + + if ( DoListContextMenu(Dialog, wParam, lParam, pReminder) ) + return TRUE; + } + break; + case WM_INITDIALOG: + { + HWND H; + + HICON hIcon = Skin_GetIconByHandle(hIconLibItem[6], ICON_SMALL); + SendMessage(Dialog, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIcon); + hIcon = Skin_GetIconByHandle(hIconLibItem[6], ICON_BIG); + SendMessage(Dialog, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hIcon); + + TranslateDialogDefault(Dialog); + SetDlgItemText(Dialog,IDC_REMINDERDATA,""); + H = GetDlgItem(Dialog,IDC_LISTREMINDERS); + lvCol.mask = LVCF_TEXT | LVCF_WIDTH; + S = Translate("Reminder text"); + lvCol.pszText = S; + lvCol.cchTextMax = strlen(S); + lvCol.cx = g_reminderListColGeom[1]; + ListView_InsertColumn(H,0,&lvCol); + lvCol.mask = LVCF_TEXT | LVCF_WIDTH; + S = Translate("Date of activation"); + lvCol.pszText = S; + lvCol.cchTextMax = strlen(S); + lvCol.cx = g_reminderListColGeom[0]; + ListView_InsertColumn(H,0,&lvCol); + InitListView(H); + SetWindowLong(GetDlgItem(H, 0), GWL_ID, IDC_LISTREMINDERS_HEADER); + LV = Dialog; + + if (g_reminderListGeom[1] && g_reminderListGeom[2]) + { + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement(Dialog, &wp); + wp.rcNormalPosition.left = g_reminderListGeom[0]; + wp.rcNormalPosition.top = g_reminderListGeom[1]; + wp.rcNormalPosition.right = g_reminderListGeom[2] + g_reminderListGeom[0]; + wp.rcNormalPosition.bottom = g_reminderListGeom[3] + g_reminderListGeom[1]; + SetWindowPlacement(Dialog, &wp); + } + return TRUE; + } + case WM_CLOSE: + { + DestroyWindow(Dialog); + ListReminderVisible = FALSE; + return TRUE; + } + case WM_NOTIFY: + { + if (wParam == IDC_LISTREMINDERS) + { + NM = (NMLISTVIEW *)lParam; + switch (NM->hdr.code) + { + case LVN_ITEMCHANGED: + { + S = ((REMINDERDATA*)TreeGetAt(RemindersList,NM->iItem))->Reminder; + SetDlgItemText(Dialog,IDC_REMINDERDATA,S); + } + break; + case NM_DBLCLK: + { + HWND H; + + H = GetDlgItem(Dialog,IDC_LISTREMINDERS); + if ( ListView_GetSelectedCount(H) ) + { + I = ListView_GetSelectionMark(H); + if (I != -1) + { + EditReminder((REMINDERDATA*)TreeGetAt(RemindersList, I)); + } + } + } + break; + } + } + else if (wParam == IDC_LISTREMINDERS_HEADER) + { + NMHEADER *NM = (NMHEADER*)lParam; + switch (NM->hdr.code) + { + case HDN_ENDTRACK: + UpdateGeomFromWnd(Dialog, NULL, g_reminderListColGeom, SIZEOF(g_reminderListColGeom)); + break; + } + } + } + break; + case WM_COMMAND: + { + switch(LOWORD(wParam)) + { + case ID_CONTEXTMENUREMINDERLISTVIEW_EDIT: + { + HWND H; + + H = GetDlgItem(Dialog,IDC_LISTREMINDERS); + if ( ListView_GetSelectedCount(H) ) + { + I = ListView_GetSelectionMark(H); + if (I != -1) + { + EditReminder((REMINDERDATA*)TreeGetAt(RemindersList, I)); + } + } + } + return TRUE; + case IDC_CLOSE: + { + DestroyWindow(Dialog); + ListReminderVisible = FALSE; + return TRUE; + } + case IDM_NEWREMINDER: + case IDC_ADDNEWREMINDER: + { + NewReminder(); + return TRUE; + } + case IDM_DELETEALLREMINDERS: + if (RemindersList && MessageBox(Dialog, Translate("Are you sure you want to delete all reminders?"), SECTIONNAME, MB_OKCANCEL) == IDOK) + { + SetDlgItemText(Dialog,IDC_REMINDERDATA,""); + DeleteReminders(); + InitListView(GetDlgItem(Dialog,IDC_LISTREMINDERS)); + } + return TRUE; + case IDM_DELETEREMINDER: + { + HWND H; + + H = GetDlgItem(Dialog,IDC_LISTREMINDERS); + if ( ListView_GetSelectedCount(H) ) + { + I = ListView_GetSelectionMark(H); + if (I != -1 + && MessageBox(Dialog, Translate("Are you sure you want to delete this reminder?"), SECTIONNAME, MB_OKCANCEL) == IDOK) + { + SetDlgItemText(Dialog,IDC_REMINDERDATA,""); + DeleteReminder((REMINDERDATA*)TreeGetAt(RemindersList, I)); + JustSaveReminders(); + InitListView(H); + } + } + return TRUE; + } + } + } + case WM_DESTROY: + { + CallService(MS_SKIN2_RELEASEICONBIG, (WPARAM)SendMessage(Dialog, WM_SETICON, ICON_BIG, (LPARAM)NULL), 0); + CallService(MS_SKIN2_RELEASEICON, (WPARAM)SendMessage(Dialog, WM_SETICON, ICON_SMALL, (LPARAM)NULL), 0); + break; + } + } + return FALSE; +} + + +///////////////////////////////////////////////////////////////////// +// Email/SMS and WinSock functions + +BOOL WS_Init() +{ + WSADATA wsd; + if (WSAStartup(MAKEWORD(2,2),&wsd)!=0) return FALSE; + return TRUE; +} + +void WS_CleanUp() +{ + WSACleanup(); +} + +int WS_Send(SOCKET s,char *data,int datalen) +{ + int rlen; + if ((rlen = send(s,data,datalen,0)) == SOCKET_ERROR) return FALSE; + return TRUE; +} + +unsigned long WS_ResolveName(char *name,WORD *port,int defaultPort) +{ + HOSTENT *lk; + char *pcolon,*nameCopy; + DWORD ret; + nameCopy=_strdup(name); + if(port != NULL) *port = defaultPort; + pcolon = strchr(nameCopy,':'); + if(pcolon != NULL) + { + if(port != NULL) *port = atoi(pcolon+1); + *pcolon = 0; + } + if (inet_addr(nameCopy) == INADDR_NONE) + { + lk = gethostbyname(nameCopy); + if(lk == 0) return SOCKET_ERROR; + else {free(nameCopy); return *(u_long*)lk->h_addr_list[0];} + } + ret=inet_addr(nameCopy); + free(nameCopy); + return ret; +} + +void Send(char *user, char *host, char *Msg, char *server) +{ + SOCKADDR_IN sockaddr; + WORD port; + char *ch = NULL; + S = socket(AF_INET,SOCK_STREAM,0); + if (!server) server = host; + if ((sockaddr.sin_addr.S_un.S_addr = WS_ResolveName(server, + &port,25))==SOCKET_ERROR) return; + sockaddr.sin_port = htons(port); + sockaddr.sin_family = AF_INET; + if(connect(S,(SOCKADDR*)&sockaddr,sizeof(sockaddr)) == SOCKET_ERROR) return; + ch = (char*)malloc(strlen(user) + strlen(host) + 16); + ch = (char*)realloc(ch,sprintf(ch,"rcpt to:%s@%s\r\n",user,host)); + WS_Send(S,"mail from: \r\n",13); + WS_Send(S,ch,strlen(ch)); + WS_Send(S,"data\r\n",6); + WS_Send(S,"From:\r\n\r\n",14); + WS_Send(S,Msg,strlen(Msg)); + WS_Send(S,"\r\n.\r\n",5); + WS_Send(S,"quit\r\n",6); + SAFE_FREE((void**)&ch); + closesocket(S); +} diff --git a/plugins/!NotAdopted/NotesAndReminders/src/resource.h b/plugins/!NotAdopted/NotesAndReminders/src/resource.h new file mode 100644 index 0000000000..0ddf8b4031 --- /dev/null +++ b/plugins/!NotAdopted/NotesAndReminders/src/resource.h @@ -0,0 +1,65 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.rc +// +#define IDD_STNOTEOPTIONS 101 +#define IDD_ADDREMINDER 102 +#define IDD_NOTIFYREMINDER 103 +#define IDD_LISTREMINDERS 104 +#define IDI_ADDREMINDER 110 +#define IDI_DELETEICON 111 +#define IDI_NOTEICON 112 +#define IDI_SHOWHIDE 113 +#define IDI_CAPTIONICON 114 +#define IDI_DELETEREMINDER 115 +#define IDI_VIEWREMINDERS 116 +#define IDI_CAPTIONICONNOTTOP 117 +#define IDI_HIDENOTE 118 +#define IDI_REMOVENOTE 119 +#define IDI_REMINDER 120 +#define IDI_BRINGFRONT 121 +#define IDI_PLAYSOUND 122 +#define IDI_VIEWNOTES 123 + +#define IDC_COMBODATE 1021 +#define IDC_COMBOTIME 1022 +#define IDC_COMBOREMINDERTIME 1023 +#define IDC_REFTIME 1024 +#define IDC_STATIC_DATE 1025 +#define IDC_STATIC_TIME 1026 +#define IDC_COMBO_REPEATSND 1028 +#define IDC_COMBO_SOUND 1029 +#define IDC_BTN_PLAYSOUND 1030 +#define IDC_EDIT_ALTBROWSER 1031 +#define IDC_BTN_BROWSEBROWSER 1032 +#define ID_CONTEXTMENUNOTEPOPUP_NEWNOTE 40009 +#define ID_CONTEXTMENUNOTEPOPUP_BRINGALLTOTOP 40010 +#define ID_CONTEXTMENUNOTEPOPUP_APPEARANCE 40011 +#define ID_APPEARANCE_BACKGROUNDCOLOR 40013 +#define ID_APPEARANCE_TEXTCOLOR 40014 +#define ID_APPEARANCE_CUSTOMTEXT 40015 +#define ID_APPEARANCE_CUSTOMBG 40016 +#define ID_BACKGROUNDCOLOR_RESET 40017 +#define ID_TEXTCOLOR_RESET 40018 +#define ID_CONTEXTMENUNOTEPOPUP_PASTETITLE 40019 +#define ID_CONTEXTMENUNOTEPOPUP_RESETTITLE 40020 +#define ID_CONTEXTMENUREMINDERLISTVIEW_EDIT 40021 +#define ID_CONTEXTMENUNOTELISTVIEW_EDITNOTE 40022 +#define ID_CONTEXTMENUNOTELISTVIEW_SHOW 40023 +#define ID_CONTEXTMENUNOTELISTVIEW_DELETEALLNOTES 40024 +#define ID_CONTEXTMENUNOTEPOPUP_VIEWNOTES 40025 +#define ID_CONTEXTMENUNOTELISTVIEW_TOGGLEVISIBILITY 40026 +#define ID_APPEARANCE_FONT 40027 +#define ID_APPEARANCE_CUSTOMFONT 40028 +#define ID_FONT_RESET 40029 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 106 +#define _APS_NEXT_COMMAND_VALUE 40030 +#define _APS_NEXT_CONTROL_VALUE 1033 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/!NotAdopted/SMS/!clear.bat b/plugins/!NotAdopted/SMS/!clear.bat new file mode 100644 index 0000000000..f35ebe94fd --- /dev/null +++ b/plugins/!NotAdopted/SMS/!clear.bat @@ -0,0 +1,36 @@ +@echo off + +del .\*.aps /q +del .\*.clw /q +del .\*.ncb /q +rem del .\*.opt /q +del .\*.plg /q + +del .\Release\*.obj /q +del .\Release\*.pch /q +del .\Release\*.pdb /q +del .\Release\*.idb /q +del .\Release\*.res /q +del .\Release\*.exp /q +del .\Release\*.sbr /q +del .\Release\*.map /q +del .\Release\*.cod /q + +del .\debug\*.obj /q +del .\debug\*.pch /q +del .\debug\*.pdb /q +del .\debug\*.idb /q +del .\debug\*.res /q +del .\debug\*.ilk /q +del .\debug\*.exp /q +del .\debug\*.sbr /q +del .\debug\*.asm /q +del .\debug\*.cod /q +del .\debug\*.map /q +del .\debug\*.opt /q +del .\debug\*._xe /q +del .\debug\*.pbi /q +del .\debug\*.pbo /q +del .\debug\*.pbt /q +del .\debug\*.map /q +del .\debug\*.cod /q diff --git a/plugins/!NotAdopted/SMS/AdditionalFunctions/BuffToLowerCase.h b/plugins/!NotAdopted/SMS/AdditionalFunctions/BuffToLowerCase.h new file mode 100644 index 0000000000..d2bb7a6671 --- /dev/null +++ b/plugins/!NotAdopted/SMS/AdditionalFunctions/BuffToLowerCase.h @@ -0,0 +1,56 @@ +#if !defined(AFX_BUFFTOLOWERCASE__H__INCLUDED_) +#define AFX_BUFFTOLOWERCASE__H__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + + +__inline DWORD BuffToLowerCase(LPCVOID lpcOutBuff,LPCVOID lpcBuff,SIZE_T dwLen) +{ + DWORD dwRetErrorCode=NO_ERROR; + + __asm + { + mov ecx,dwLen + test ecx,ecx + jz short end_func + + push ebx // сохраняем регистр + push edi // сохраняем регистр + push esi // сохраняем регистр + mov esi,lpcBuff + mov edi,lpcOutBuff + mov bl,'A' + mov bh,'Z' + mov ah,32 + cld + + lowcaseloop: + lodsb + cmp al,bl + jl short savebyte + cmp al,bh + jg short savebyte + or al,ah + + savebyte: + stosb + + dec ecx + jnz short lowcaseloop + + pop esi // восстанавливаем содержимое регистра + pop edi // восстанавливаем содержимое регистра + pop ebx // восстанавливаем содержимое регистра + end_func: + } + +return(dwRetErrorCode); +} + + + + +#endif // !defined(AFX_BUFFTOLOWERCASE__H__INCLUDED_) \ No newline at end of file diff --git a/plugins/!NotAdopted/SMS/AdditionalFunctions/DebugFunctions.h b/plugins/!NotAdopted/SMS/AdditionalFunctions/DebugFunctions.h new file mode 100644 index 0000000000..8b21d1bc5a --- /dev/null +++ b/plugins/!NotAdopted/SMS/AdditionalFunctions/DebugFunctions.h @@ -0,0 +1,101 @@ +#if !defined(AFX_DEBUG_FUNCTIONS__H__INCLUDED_) +#define AFX_DEBUG_FUNCTIONS__H__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#ifndef szCRLF +#define szCRLF TEXT("\r\n") +#endif +////////////////////////////////////////////////////////////////////////// +////////////////////////////DebugPrint//////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// DebugBuildPrint(Helo world); +// Отображение текста в Debug окне во время отладки +#ifdef _DEBUG + #define DebugPrintA(szText) OutputDebugStringA((szText)) + #define DebugPrintW(szText) OutputDebugStringW((szText)) + #define DebugPrintCRLFA(szText) OutputDebugStringA((szText));OutputDebugStringA("\r\n") + #define DebugPrintCRLFW(szText) OutputDebugStringW((szText));OutputDebugStringW(L"\r\n") +#else + #define DebugPrintA(szText) + #define DebugPrintW(szText) + #define DebugPrintCRLFA(szText) + #define DebugPrintCRLFW(szText) +#endif //_DEBUG + + +#ifdef UNICODE + #define DebugPrint DebugPrintW + #define DebugPrintCRLF DebugPrintCRLFW +#else + #define DebugPrint DebugPrintA + #define DebugPrintCRLF DebugPrintCRLFA +#endif +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + + + + +////////////////////////////////////////////////////////////////////////// +////////////////////////////DebugBuildPrint/////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// #pragma DebugBuildPrint(Helo world); +// Отображение сообщений в Build окне во время компиляции +#ifdef _DEBUG + #pragma warning(disable:4081) + #define chSTR2(x) #x + #define chSTR(x) chSTR2(x) + #define DebugBuildPrint(szText) message(__FILE__ "(" chSTR(__LINE__) "): " #szText) + #pragma warning(default:4081) +#else + #define DebugBuildPrint(szText) +#endif //_DEBUG +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + + + + +////////////////////////////////////////////////////////////////////////// +////////////////////////////DebugBufferFill/////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// DebugBufferFill(szString,sizeof(szString)); +// Полностью заполняет переданный буффер символом "A", применяется +// для выходного буффера на входе в функцию. +#ifdef _DEBUG + #define DebugBufferFill(lpBuffer,dwSize) memset(lpBuffer,'A',dwSize) +#else + #define DebugBufferFill(lpBuffer,dwSize) +#endif //_DEBUG +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + + + + +////////////////////////////////////////////////////////////////////////// +////////////////////////////DebugBreak//////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// DebugBreak(); +// Точка останова, более удобная альтернатива API +#if defined(_DEBUG) && defined(_X86_) + #define DebugBreak() _asm{int 3} +#else + #define DebugBreak() +#endif //_DEBUG +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + + + + + + +#endif // !defined(AFX_DEBUG_FUNCTIONS__H__INCLUDED_) diff --git a/plugins/!NotAdopted/SMS/AdditionalFunctions/InterlockedFunctions.h b/plugins/!NotAdopted/SMS/AdditionalFunctions/InterlockedFunctions.h new file mode 100644 index 0000000000..3fb008b216 --- /dev/null +++ b/plugins/!NotAdopted/SMS/AdditionalFunctions/InterlockedFunctions.h @@ -0,0 +1,127 @@ +#if !defined(AFX_INTERLOCKED_FUNCTIONS__H__INCLUDED_) +#define AFX_INTERLOCKED_FUNCTIONS__H__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + + + + +#ifdef InterlockedCompareExchange +#ifndef InterlockedAnd +LONG FORCEINLINE InterlockedAnd(LONG volatile *Destination,LONG Value) +{ + LONG Old; + + do + { + Old=*Destination; + }while(InterlockedCompareExchange(Destination,(Old&Value),Old)!=Old); +return(Old); +} +#endif //InterlockedAnd + + +#ifndef InterlockedOr +LONG FORCEINLINE InterlockedOr(LONG volatile *Destination,LONG Value) +{ + LONG Old; + + do + { + Old=*Destination; + }while(InterlockedCompareExchange(Destination,(Old|Value),Old)!=Old); +return(Old); +} +#endif //InterlockedOr + + +#ifndef InterlockedXor +LONG FORCEINLINE InterlockedXor(LONG volatile *Destination,LONG Value) +{ + LONG Old; + + do + { + Old=*Destination; + }while(InterlockedCompareExchange(Destination,(Old^Value),Old)!=Old); +return(Old); +} +#endif //InterlockedXor +#endif //InterlockedCompareExchange + + + + + +#ifdef InterlockedCompareExchange64 +#ifndef InterlockedAnd64 +LONGLONG FORCEINLINE InterlockedAnd64(LONGLONG volatile *Destination,LONGLONG Value) +{ + LONGLONG Old; + + do + { + Old=*Destination; + }while(InterlockedCompareExchange64(Destination,(Old&Value),Old)!=Old); +return(Old); +} +#endif //InterlockedAnd64 + + +#ifndef InterlockedOr64 +LONGLONG FORCEINLINE InterlockedOr64(LONGLONG volatile *Destination,LONGLONG Value) +{ + LONGLONG Old; + + do + { + Old=*Destination; + }while(InterlockedCompareExchange64(Destination,(Old|Value),Old)!=Old); +return(Old); +} +#endif //InterlockedOr64 + + +#ifndef InterlockedXor64 +LONGLONG FORCEINLINE InterlockedXor64(LONGLONG volatile *Destination,LONGLONG Value) +{ + LONGLONG Old; + + do + { + Old=*Destination; + }while(InterlockedCompareExchange64(Destination,(Old^Value),Old)!=Old); +return(Old); +} +#endif //InterlockedXor64 +#endif //InterlockedCompareExchange64 + + + + + +#ifndef InterlockedIncrementPointer +#if defined(_WIN64) +#define InterlockedIncrementPointer(lpAddend) (LPVOID)InterlockedIncrement64((LONGLONG volatile*)lpAddend) +#else +#define InterlockedIncrementPointer(lpAddend) (LPVOID)InterlockedIncrement((LONG volatile*)lpAddend) +#endif +#endif //InterlockedIncrementPointer + + +#ifndef InterlockedDecrementPointer +#if defined(_WIN64) +#define InterlockedDecrementPointer(lpAddend) (LPVOID)InterlockedDecrement64((LONGLONG volatile*)lpAddend) +#else +#define InterlockedDecrementPointer(lpAddend) (LPVOID)InterlockedDecrement((LONG volatile*)lpAddend) +#endif +#endif //InterlockedDecrementPointer + + + + + +#endif // !defined(AFX_INTERLOCKED_FUNCTIONS__H__INCLUDED_) diff --git a/plugins/!NotAdopted/SMS/AdditionalFunctions/ListMT.h b/plugins/!NotAdopted/SMS/AdditionalFunctions/ListMT.h new file mode 100644 index 0000000000..7cf1e81808 --- /dev/null +++ b/plugins/!NotAdopted/SMS/AdditionalFunctions/ListMT.h @@ -0,0 +1,328 @@ +#if !defined(AFX_LIST_MT__H__INCLUDED_) +#define AFX_LIST_MT__H__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + +#include + +#if defined(_MSC_VER) +#if _MSC_VER >= 800 +#if _MSC_VER >= 1200 +#pragma warning(push) +#endif +#pragma warning(disable:4312) // warning C4312: 'type cast' : conversion from 'LONG' to 'PVOID' of greater size +#endif +#endif + + +// структура для работы со списком, элемент списка +typedef struct _LIST_MT_ITEM +{ +#ifdef __cplusplus + _LIST_MT_ITEM *plmtiPrev; // *предыдущий элемент в списке + _LIST_MT_ITEM *plmtiNext; // *следующий элемент в списке +#else + LPVOID *plmtiPrev; // *предыдущий элемент в списке + LPVOID *plmtiNext; // *следующий элемент в списке +#endif + LPVOID lpData; // указатель на данные, связанные с элементом списка + LPVOID lpListMT; // указатель на заголовок списка, см структуру ниже +}LIST_MT_ITEM, *PLIST_MT_ITEM, *LPLIST_MT_ITEM; +typedef CONST PLIST_MT_ITEM PCLIST_MT_ITEM, LPCLIST_MT_ITEM; + + +// структура для работы со списком, заголовок списка +typedef struct _LIST_MT +{ + SIZE_T nCount; // *колличество элементов в списке + PLIST_MT_ITEM plmtiFirst; // *указывает на первый элемент в списке + PLIST_MT_ITEM plmtiLast; // *указывает на последний элемент в списке + CRITICAL_SECTION cs; // *section for exclysive access to List +}LIST_MT, *PLIST_MT, *LPLIST_MT; +typedef CONST PLIST_MT PCLIST_MT, LPCLIST_MT; + + +// структура для работы с итератором +typedef struct _LIST_MT_ITERATOR +{ + PLIST_MT_ITEM plmtListMTItem; +}LIST_MT_ITERATOR, *PLIST_MT_ITERATOR, *LPLIST_MT_ITERATOR; +//typedef LIST_MT_ITEM LIST_MT_ITERATOR, *PLIST_MT_ITERATOR, *LPLIST_MT_ITERATOR; +typedef CONST PLIST_MT_ITERATOR PCLIST_MT_ITERATOR, LPCLIST_MT_ITERATOR; + + + + +__inline DWORD ListMTInitialize(PCLIST_MT pclmtListMT,DWORD dwSpinCount) +{ + DWORD dwRetErrorCode; + +#if (_WIN32_WINNT >= 0x0403) + if (InitializeCriticalSectionAndSpinCount(&pclmtListMT->cs,((dwSpinCount)? (dwSpinCount | 0x80000000):0L))) +#else + InitializeCriticalSection(&pclmtListMT->cs); + if (TRUE) +#endif + { + InterlockedExchangePointer(&pclmtListMT->nCount,NULL); + pclmtListMT->plmtiFirst=NULL; + pclmtListMT->plmtiLast=NULL; + dwRetErrorCode=NO_ERROR; + }else{ + dwRetErrorCode=GetLastError(); + } +return(dwRetErrorCode); +} + + +__inline void ListMTDestroy(PCLIST_MT pclmtListMT) +{ + InterlockedExchangePointer(&pclmtListMT->nCount,NULL); + pclmtListMT->plmtiFirst=NULL; + pclmtListMT->plmtiLast=NULL; + DeleteCriticalSection(&pclmtListMT->cs); +} + + +__inline BOOL ListMTTryLock(PCLIST_MT pclmtListMT) +{ +#if (_WIN32_WINNT >= 0x0400) + return(TryEnterCriticalSection(&pclmtListMT->cs)); +#else + return(FALSE); +#endif +} + + +__inline void ListMTLock(PCLIST_MT pclmtListMT) +{ + EnterCriticalSection(&pclmtListMT->cs); +} + + +__inline void ListMTUnLock(PCLIST_MT pclmtListMT) +{ + LeaveCriticalSection(&pclmtListMT->cs); +} + + +__inline SIZE_T ListMTGetCount(PCLIST_MT pclmtListMT) +{ + return((SIZE_T)InterlockedCompareExchangePointer((LPVOID*)&pclmtListMT->nCount,NULL,NULL)); +} + + +__inline SIZE_T ListMTItemAdd(PCLIST_MT pclmtListMT,PCLIST_MT_ITEM pclmtListMTItem,LPVOID lpData) +{ + SIZE_T dwRet=(SIZE_T)InterlockedIncrementPointer(&pclmtListMT->nCount);//pclmtListMT->nCount++; + pclmtListMTItem->lpData=lpData; + pclmtListMTItem->lpListMT=pclmtListMT; + + if (pclmtListMT->plmtiLast) + {// add node to end of list + pclmtListMTItem->plmtiPrev=pclmtListMT->plmtiLast; + pclmtListMTItem->plmtiNext=NULL; + pclmtListMT->plmtiLast->plmtiNext=pclmtListMTItem; + pclmtListMT->plmtiLast=pclmtListMTItem; + }else{// add the first node to the linked list + pclmtListMTItem->plmtiPrev=NULL; + pclmtListMTItem->plmtiNext=NULL; + pclmtListMT->plmtiFirst=pclmtListMTItem; + pclmtListMT->plmtiLast=pclmtListMTItem; + } + +return(dwRet); +} + + +__inline DWORD ListMTItemDelete(PCLIST_MT pclmtListMT,PCLIST_MT_ITEM pclmtListMTItem) +{ + DWORD dwRetErrorCode; + + if (pclmtListMTItem->lpListMT==pclmtListMT && pclmtListMT) + {// Данный элемент принадлежит к этому списку, можно удалить. + PLIST_MT_ITEM plmtiPrevNode=pclmtListMTItem->plmtiPrev,plmtiNextNode=pclmtListMTItem->plmtiNext; + + if (plmtiPrevNode || plmtiNextNode) + { + if (plmtiPrevNode && plmtiNextNode==NULL) + {// This is the start node in the list to delete + // отключился последний подключившийся + plmtiPrevNode->plmtiNext=NULL; + pclmtListMT->plmtiLast=plmtiPrevNode; + }else{ + if (plmtiPrevNode==NULL && plmtiNextNode) + {// This is the end node in the list to delete + // отключился первый подключившийся + plmtiNextNode->plmtiPrev=NULL; + pclmtListMT->plmtiFirst=plmtiNextNode; + }else{// оключился клиент не первый и не последний + //if (plmtiPrev && plmtiNext) + {// Neither start node nor end node in the list + plmtiPrevNode->plmtiNext=plmtiNextNode; + plmtiNextNode->plmtiPrev=plmtiPrevNode; + } + } + } + }else{// This is the only node in the list to delete + pclmtListMT->plmtiFirst=NULL; + pclmtListMT->plmtiLast=NULL; + } + + pclmtListMTItem->lpListMT=NULL; + InterlockedDecrementPointer(&pclmtListMT->nCount);// pclmtListMT->nCount--; + dwRetErrorCode=NO_ERROR; + }else{// попытались удалить элемент не относящийся к данному списку + dwRetErrorCode=ERROR_INVALID_HANDLE; + } +return(dwRetErrorCode); +} + + +__inline LPVOID ListMTItemDataGet(PCLIST_MT_ITEM pclmtListMTItem) +{ + return(pclmtListMTItem->lpData); +} + + +__inline void ListMTItemDataSet(PCLIST_MT_ITEM pclmtListMTItem, LPVOID lpData) +{ + pclmtListMTItem->lpData=lpData; +} + + +__inline DWORD ListMTItemGetFirst(PCLIST_MT pclmtListMT,PLIST_MT_ITEM *pplmtListMTItem,LPVOID *plpData) +{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock + DWORD dwRetErrorCode; + + if (pclmtListMT->plmtiFirst) + { + if (pplmtListMTItem) (*pplmtListMTItem)=pclmtListMT->plmtiFirst; + if (plpData) (*plpData)=pclmtListMT->plmtiFirst->lpData; + dwRetErrorCode=NO_ERROR; + }else{ + dwRetErrorCode=ERROR_NO_MORE_ITEMS; + } +return(dwRetErrorCode); +} + + +__inline DWORD ListMTItemGetLast(PCLIST_MT pclmtListMT,PLIST_MT_ITEM *pplmtListMTItem,LPVOID *plpData) +{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock + DWORD dwRetErrorCode; + + if (pclmtListMT->plmtiLast) + { + if (pplmtListMTItem) (*pplmtListMTItem)=pclmtListMT->plmtiLast; + if (plpData) (*plpData)=pclmtListMT->plmtiLast->lpData; + dwRetErrorCode=NO_ERROR; + }else{ + dwRetErrorCode=ERROR_NO_MORE_ITEMS; + } +return(dwRetErrorCode); +} + + + +__inline void ListMTItemSwap(PCLIST_MT pclmtListMT,PCLIST_MT_ITEM pclmtListMTItem1,PCLIST_MT_ITEM pclmtListMTItem2) +{// поменять два элемента списка местами, даже если они из разных списков + + if (pclmtListMTItem1!=pclmtListMTItem2) + {// это разные элементы списка + PLIST_MT_ITEM lpTemp; + + lpTemp=pclmtListMTItem1->plmtiPrev; + if ((pclmtListMTItem1->plmtiPrev=pclmtListMTItem2->plmtiPrev)==NULL) + {// pclmtListMTItem2 был первым, обновляем заголвок листа, теперь первый pclmtListMTItem1 + pclmtListMT->plmtiFirst=pclmtListMTItem1; + } + + if ((pclmtListMTItem2->plmtiPrev=lpTemp)==NULL) + {// pclmtListMTItem1 был первым, обновляем заголвок листа, теперь первый pclmtListMTItem2 + pclmtListMT->plmtiFirst=pclmtListMTItem2; + } + + + lpTemp=pclmtListMTItem1->plmtiNext; + if ((pclmtListMTItem1->plmtiNext=pclmtListMTItem2->plmtiNext)==NULL) + {// pclmtListMTItem2 был последним, обновляем заголвок листа, теперь последний pclmtListMTItem1 + pclmtListMT->plmtiLast=pclmtListMTItem1; + } + + if ((pclmtListMTItem2->plmtiNext=lpTemp)==NULL) + {// pclmtListMTItem1 был последним, обновляем заголвок листа, теперь последний pclmtListMTItem2 + pclmtListMT->plmtiLast=pclmtListMTItem2; + } + } +} + + +__inline BOOL ListMTIteratorMoveFirst(PCLIST_MT pclmtListMT,PCLIST_MT_ITERATOR pclmtiIterator) +{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock + return((pclmtiIterator->plmtListMTItem=pclmtListMT->plmtiFirst)? TRUE:FALSE); +} + + +__inline BOOL ListMTIteratorMoveLast(PCLIST_MT pclmtListMT,PCLIST_MT_ITERATOR pclmtiIterator) +{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock + return((pclmtiIterator->plmtListMTItem=pclmtListMT->plmtiLast)? TRUE:FALSE); +} + + +__inline BOOL ListMTIteratorMovePrev(PCLIST_MT_ITERATOR pclmtiIterator) +{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock + BOOL bRet=FALSE; + + if (pclmtiIterator->plmtListMTItem) + { + if (pclmtiIterator->plmtListMTItem=pclmtiIterator->plmtListMTItem->plmtiPrev) bRet=TRUE; + } +return(bRet); +} + + +__inline BOOL ListMTIteratorMoveNext(PCLIST_MT_ITERATOR pclmtiIterator) +{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock + BOOL bRet=FALSE; + + if (pclmtiIterator->plmtListMTItem) + { + if (pclmtiIterator->plmtListMTItem=pclmtiIterator->plmtListMTItem->plmtiNext) bRet=TRUE; + } +return(bRet); +} + + +__inline DWORD ListMTIteratorGet(PCLIST_MT_ITERATOR pclmtiIterator,PLIST_MT_ITEM *pplmtListMTItem,LPVOID *plpData) +{// если нужно гарантировать эксклюзивный доступ, то есть ListMTLock и ListMTUnLock + DWORD dwRetErrorCode; + + if (pclmtiIterator->plmtListMTItem) + { + if (pplmtListMTItem) (*pplmtListMTItem)=pclmtiIterator->plmtListMTItem; + if (plpData) (*plpData)=pclmtiIterator->plmtListMTItem->lpData; + dwRetErrorCode=NO_ERROR; + }else{ + dwRetErrorCode=ERROR_NO_MORE_ITEMS; + } +return(dwRetErrorCode); +} + + + +#if defined(_MSC_VER) +#if _MSC_VER >= 800 +#if _MSC_VER >= 1200 +#pragma warning(pop) +#else +#pragma warning(default:4312) // warning C4312: 'type cast' : conversion from 'LONG' to 'PVOID' of greater size +#endif +#endif +#endif + + + +#endif // !defined(AFX_LIST_MT__H__INCLUDED_) diff --git a/plugins/!NotAdopted/SMS/AdditionalFunctions/MemoryCompare.h b/plugins/!NotAdopted/SMS/AdditionalFunctions/MemoryCompare.h new file mode 100644 index 0000000000..de663c6d8a --- /dev/null +++ b/plugins/!NotAdopted/SMS/AdditionalFunctions/MemoryCompare.h @@ -0,0 +1,177 @@ +#if !defined(AFX_MEMORYCOMPARE__H__INCLUDED_) +#define AFX_MEMORYCOMPARE__H__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + +// If the string pointed to by lpString1 is less than the string pointed +// to by lpString2, the return value is negative. +// If the string pointed to by lpString1 is greater than the string pointed +// to by lpString2, the return value is positive. +// If the strings are equal, the return value is zero. +// +// lpString1> ret=1=CSTR_LESS_THAN +// lpString1=lpString2 >> ret=2=CSTR_EQUAL +// lpString1>lpString2 >> ret=3=CSTR_GREATER_THAN + + +/*__inline DWORD MemoryCompare(LPCVOID lpcSource1,SIZE_T dwSource1Size,LPCVOID lpcSource2,SIZE_T dwSource2Size) +{ + DWORD dwRet; + + __asm + { + mov ecx,dwSource1Size //; ecx = Source string 1 Size + cmp ecx,dwSource2Size //; сверяем длинны участков памяти + jg short greater_than + jl short less_than + test ecx,ecx + jz short equal //; NULL=NULL + + mov esi,lpcSource1 //; edi = Source string 1 + mov edi,lpcSource2 //; esi = Source string 2 + cmp edi,esi //; сверяем указатели на участки памяти + je short equal //; это один и тотже участок, они естественно равны + + test esi,esi //; lpcSource1=NULL, lpcSource1lpcSource2 + jz short greater_than //; CSTR_GREATER_THAN + + //cld //; сканируя в прямом направлении + + repe cmpsb //; цикл сравнения. + cmp_loop: + //sub ecx,4 + //jz short equal + + //inc esi + //inc edi + //mov al,byte ptr [esi] + //cmpsd + //cmp al,byte ptr [edi] + //je short cmp_loop + jg short greater_than + jl short less_than + + equal: //; если мы попали сюда, значит, они + mov dwRet,CSTR_EQUAL //; совпадают (match) + jmp end_func + less_than: //; не совпадают + mov dwRet,CSTR_LESS_THAN + jmp end_func + greater_than: + mov dwRet,CSTR_GREATER_THAN + + end_func: + } +return(dwRet); +}//*/ + +__inline DWORD MemoryCompare(LPCVOID lpcSource1,SIZE_T dwSource1Size,LPCVOID lpcSource2,SIZE_T dwSource2Size) +{ + DWORD dwRet; + + if (dwSource1Size==dwSource2Size) + { + if (lpcSource1==lpcSource2) + { + dwRet=CSTR_EQUAL; + }else{ + if (lpcSource1 && lpcSource2) + { +#ifdef _INC_MEMORY + dwRet=(2+memcmp(lpcSource1,lpcSource2,dwSource1Size)); +#else + SIZE_T dwDiffPosition; + + //dwDiffPosition=RtlCompareMemory(lpcSource1,lpcSource2,dwSource1Size); + for(dwDiffPosition=0; (dwDiffPosition(*((BYTE*)(((SIZE_T)lpcSource2)+dwDiffPosition)))) + { + dwRet=CSTR_GREATER_THAN; + }else{ + dwRet=CSTR_LESS_THAN; + } + } +#endif + }else{ + if (lpcSource1) + {//lpcSource2==NULL + dwRet=CSTR_GREATER_THAN; + }else{//lpcSource1==NULL + dwRet=CSTR_LESS_THAN; + } + } + } + }else{ + if (dwSource1Size(*((BYTE*)(((SIZE_T)lpcSource2)+dwDiffPosition)))) + { + dwRet=CSTR_GREATER_THAN; + }else{ + dwRet=CSTR_LESS_THAN; + } + } + + if (pdwDiffPosition) (*pdwDiffPosition)=dwDiffPosition; + }else{ + if (lpcSource1) + {//lpcSource2==NULL + dwRet=CSTR_GREATER_THAN; + }else{//lpcSource1==NULL + dwRet=CSTR_LESS_THAN; + } + } + } + }else{ + if (dwSource1Size 1000 +#pragma once +#endif // _MSC_VER > 1000 + +__inline LPVOID MemoryFind(SIZE_T dwFrom,LPCVOID lpcSource,SIZE_T dwSourceSize,LPCVOID lpcWhatFind,SIZE_T dwWhatFindSize) +{ + LPVOID lpRet=NULL; + + __asm + { + push ebx // сохраняем регистр + push edi // сохраняем регистр + push esi // сохраняем регистр + + mov ecx,dwSourceSize //; ecx = Source string Size + test ecx,ecx // is size unknown? + jz short end_func + + mov edx,dwWhatFindSize //; edx = WhatFind string Size + test edx,edx // is size unknown? + jz short end_func + + mov ebx,dwFrom // ebx - start pos in Source string + mov edi,lpcSource //; edi = Source string + mov esi,lpcWhatFind //; esi = WhatFind string + + cmp ebx,ecx // проверка ecx(=len)=>ulFrom + jae short end_func + + add edi,ebx // сдвигаем начало на ulFrom(нач смещен) + sub ecx,ebx // уменьшаем длинну SourceSize на ulFrom(нач смещен) + + cmp ecx,edx // проверка NEWSourceSize ??? ulWhatFindSize + je short begin_memorycompare // NEWulSourceSize==ulWhatFindSize, Source ??? WhatFind + jl short end_func // NEWulSourceSize Source!=WhatFind + + sub ecx,edx // уменьшаем длинну SourceSize на ulWhatFindSize + inc ecx + + mov al,[esi] //; al=search byte + dec edi + cld //; сканируя в прямом направлении + + find_loop: + test ecx,ecx + jz short end_func + inc edi + repne scasb //; find that byte + dec edi //; di points to byte which stopped scan + + cmp [edi],al //; see if we have a hit + jne short end_func //; yes, point to byte + + begin_memorycompare: + push esi + push edi + push ecx + mov ecx,edx //; ulWhatFindSize байтов (CX используется в REPE), + repe cmpsb //; сравниваем их. + pop ecx + pop edi + pop esi + jne short find_loop //; признак ZF = 0, если сравниваемые + //; строки не совпадают (mismatch) match: + //; если мы попали сюда, значит, они + //; совпадают (match) + mov lpRet,edi //; ax=pointer to byte + end_func: + + pop esi // восстанавливаем содержимое регистра + pop edi // восстанавливаем содержимое регистра + pop ebx // восстанавливаем содержимое регистра + } +return(lpRet); +} + + +#endif // !defined(AFX_MEMORYFIND__H__INCLUDED_) diff --git a/plugins/!NotAdopted/SMS/AdditionalFunctions/MemoryFindByte.h b/plugins/!NotAdopted/SMS/AdditionalFunctions/MemoryFindByte.h new file mode 100644 index 0000000000..0dcc1f91a6 --- /dev/null +++ b/plugins/!NotAdopted/SMS/AdditionalFunctions/MemoryFindByte.h @@ -0,0 +1,71 @@ +#if !defined(AFX_MEMORYFINDBYTE__H__INCLUDED_) +#define AFX_MEMORYFINDBYTE__H__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + + +__inline LPVOID MemoryFindByte(SIZE_T dwFrom,LPCVOID lpcSource,SIZE_T dwSourceSize,unsigned char chWhatFind) +{ + LPVOID lpRet=NULL; + + if (lpcSource && dwSourceSize) + { + if (dwFromdwFrom + jae short end_func + + std //; count 'up' on string this time + sub ecx,eax //; уменьшаем длинну на dwFrom(нач смещен) + add edi,ecx //; сдвигаем начало на dwSourceSize(на конец) + mov al,chWhatFind //; al=search byte + repne scasb //; find that byte + inc edi //; di points to byte which stopped scan + cmp [edi],al //; see if we have a hit + jne short end_func //; yes, point to byte + mov lpRet,edi //; ax=pointer to byte + end_func: + + cld + pop esi // восстанавливаем содержимое регистра + pop edi // восстанавливаем содержимое регистра + pop ebx // восстанавливаем содержимое регистра + } +return(lpRet); +} + + + +#endif // !defined(AFX_MEMORYFINDBYTE__H__INCLUDED_) diff --git a/plugins/!NotAdopted/SMS/SMS.def b/plugins/!NotAdopted/SMS/SMS.def new file mode 100644 index 0000000000..3ec70ac7bb --- /dev/null +++ b/plugins/!NotAdopted/SMS/SMS.def @@ -0,0 +1,8 @@ +LIBRARY SMS + +EXPORTS + MirandaPluginInfo @1 + MirandaPluginInfoEx @2 + MirandaPluginInterfaces @3 + Load @4 + Unload @5 diff --git a/plugins/!NotAdopted/SMS/SMSConstans.h b/plugins/!NotAdopted/SMS/SMSConstans.h new file mode 100644 index 0000000000..ddaddc3df7 --- /dev/null +++ b/plugins/!NotAdopted/SMS/SMSConstans.h @@ -0,0 +1,108 @@ +#if !defined(AFX_SMS_CONSTANS_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_) +#define AFX_SMS_CONSTANS_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_ + + + + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + + +// {CF97FD5D-B911-47a8-AF03-D21968B5B894} +#define SMS_GUID { 0xcf97fd5d, 0xb911, 0x47a8, { 0xaf, 0x3, 0xd2, 0x19, 0x68, 0xb5, 0xb8, 0x94 } } + + +#define MIN_MIR_VER_VERSION_DWORD PLUGIN_MAKE_VERSION(0,8,0,0) + + +#define PLUGIN_VERSION_DWORD PLUGIN_MAKE_VERSION(0,2,5,3) +#define PROTOCOL_NAMEA "SMSPlugin" +#define PROTOCOL_NAMEW TEXT(PROTOCOL_NAMEA) +#define PROTOCOL_NAME_LEN (sizeof(PROTOCOL_NAMEA)-1) +#define PROTOCOL_NAME_SIZE sizeof(PROTOCOL_NAMEA) +#define PROTOCOL_DISPLAY_NAME_ORIG "SMS" +#define PROTOCOL_DISPLAY_NAME_ORIGW TEXT(PROTOCOL_DISPLAY_NAME_ORIG) + + + + +#define TIMEOUT_MSGSEND 60000 // send sms timeout +#define MIN_SMS_DBEVENT_LEN 4 // для фильтрации событий авторизации от джабер плагина +#define MAX_PHONE_LEN MAX_PATH +#define PHONES_MIN_COUNT 4 //internal // колличество элементов обязательно проверяемых при извлечении email адреса из инфы юзера +#define SMS_PLUGIN_UPDATER_ID 4187 //появляется после первого выкладывания на сайт + + + +#define SMS_DEFAULT_ +#define SMS_DEFAULT_SIGNATUREPOS FALSE +#define SMS_DEFAULT_SHOWACK TRUE +#define SMS_DEFAULT_USESIGNATURE TRUE +#define SMS_DEFAULT_AUTOPOP FALSE +#define SMS_DEFAULT_SAVEWINPOS FALSE + + + +// +#define ICQEVENTTYPE_SMSCONFIRMATION 3001 + + +//Fonts defenitions +//#define SRMMMOD "SRMM" +#define SRMMMOD "TabSRMM_Fonts" + +#define FONTF_BOLD 1 +#define FONTF_ITALIC 2 +struct FontOptionsList +{ + COLORREF defColour; + TCHAR* szDefFace; + BYTE defStyle; + char defSize; +} + +static fontOptionsList[] = { + { RGB(106, 106, 106), _T("Arial"), 0, -12}, +}; + + +#define MSGFONTID_MYMSG 0 +#define MSGFONTID_YOURMSG 2 +#define MSGFONTID_MESSAGEAREA 16 + + +#define SRMSGSET_BKGCOLOUR "BkgColour" +#define SRMSGSET_INPBKGCOLOUR "inputbg" +#define SRMSGDEFSET_BKGCOLOUR GetSysColor(COLOR_WINDOW) +#define FONTF_BOLD 1 +#define FONTF_ITALIC 2 + + + +//Decleration of functions that used when user hit miranda for new message/confirmation +int ReadAckSMS(WPARAM wParam,LPARAM lParam); +int ReadMsgSMS(WPARAM wParam,LPARAM lParam); +int SendSMSMenuCommand(WPARAM wParam,LPARAM lParam); + + + +#define SMS_READ "/ReadSms" +#define SMS_READ_ACK "/ReadSmsAck" +#define SMS_SEND "/SendSMS" +#define SMS_SEND_STR L"Send &SMS..." +#define SMS_SEND_CM_STR L"&SMS Message" + + +static const SERVICE_ITEM siPluginServices[] = +{ + { SMS_READ, ReadMsgSMS }, + { SMS_READ_ACK, ReadAckSMS }, + { SMS_SEND, SendSMSMenuCommand }, +}; + + + + +#endif // !defined(AFX_SMS_CONSTANS_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_) diff --git a/plugins/!NotAdopted/SMS/SMS_svc.cpp b/plugins/!NotAdopted/SMS/SMS_svc.cpp new file mode 100644 index 0000000000..24e6d1ad2f --- /dev/null +++ b/plugins/!NotAdopted/SMS/SMS_svc.cpp @@ -0,0 +1,243 @@ +#include "main.h" + + + +int LoadServices(void) +{ + CHAR szServiceFunction[MAX_PATH],*pszServiceFunctionName; + + CopyMemory(szServiceFunction,PROTOCOL_NAMEA,PROTOCOL_NAME_SIZE); + pszServiceFunctionName=szServiceFunction+PROTOCOL_NAME_LEN; + + // Service creation + for (SIZE_T i=0;ihDbEvent,0))!=-1) + { + dbei.pBlob=(PBYTE)MEMALLOC(dbei.cbBlob); + if (dbei.pBlob) + { + if (CallService(MS_DB_EVENT_GET,(WPARAM)((CLISTEVENT*)lParam)->hDbEvent,(LPARAM)&dbei)==0) + if (dbei.eventType==ICQEVENTTYPE_SMS || dbei.eventType==ICQEVENTTYPE_SMSCONFIRMATION) + if (dbei.cbBlob>MIN_SMS_DBEVENT_LEN) + { + if (RecvSMSWindowAdd(((CLISTEVENT*)lParam)->hContact,ICQEVENTTYPE_SMS,NULL,0,(LPSTR)dbei.pBlob,dbei.cbBlob)) + { + CallService(MS_DB_EVENT_MARKREAD,(WPARAM)((CLISTEVENT*)lParam)->hContact,(LPARAM)((CLISTEVENT*)lParam)->hDbEvent); + iRet=0; + } + } + MEMFREE(dbei.pBlob); + } + } +return(iRet); +} + +//This function used to popup a read SMS window after the user clicked on the received SMS confirmation. +int ReadAckSMS(WPARAM wParam,LPARAM lParam) +{ + int iRet=1; + DBEVENTINFO dbei={0}; + + dbei.cbSize=sizeof(dbei); + if ((dbei.cbBlob=CallService(MS_DB_EVENT_GETBLOBSIZE,(WPARAM)((CLISTEVENT*)lParam)->hDbEvent,0))!=-1) + { + dbei.pBlob=(PBYTE)MEMALLOC(dbei.cbBlob); + if (dbei.pBlob) + { + if (CallService(MS_DB_EVENT_GET,(WPARAM)((CLISTEVENT*)lParam)->hDbEvent,(LPARAM)&dbei)==0) + if (dbei.eventType==ICQEVENTTYPE_SMS || dbei.eventType==ICQEVENTTYPE_SMSCONFIRMATION) + if (dbei.cbBlob>MIN_SMS_DBEVENT_LEN) + { + if (RecvSMSWindowAdd(((CLISTEVENT*)lParam)->hContact,ICQEVENTTYPE_SMSCONFIRMATION,NULL,0,(LPSTR)dbei.pBlob,dbei.cbBlob)) + { + CallService(MS_DB_EVENT_DELETE,(WPARAM)((CLISTEVENT*)lParam)->hContact,(LPARAM)((CLISTEVENT*)lParam)->hDbEvent); + iRet=0; + } + } + MEMFREE(dbei.pBlob); + } + } +return(iRet); +} + +void RestoreUnreadMessageAlerts(void) +{ + DBEVENTINFO dbei={0}; + HANDLE hDbEvent,hContact; + + dbei.cbSize=sizeof(dbei); + for(hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);hContact!=NULL;hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)) + for(hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDFIRSTUNREAD,(WPARAM)hContact,0);hDbEvent!=NULL;hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hDbEvent,0)) + { + dbei.cbBlob=0; + if (CallService(MS_DB_EVENT_GET,(WPARAM)hDbEvent,(LPARAM)&dbei)==0) + if ((dbei.flags&(DBEF_SENT|DBEF_READ))==0 && ((dbei.eventType==ICQEVENTTYPE_SMS) || (dbei.eventType==ICQEVENTTYPE_SMSCONFIRMATION))) + if (dbei.cbBlob>MIN_SMS_DBEVENT_LEN) + { + handleNewMessage((WPARAM)hContact,(LPARAM)hDbEvent); + } + } + + hContact=NULL; + for(hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDFIRSTUNREAD,(WPARAM)hContact,0);hDbEvent!=NULL;hDbEvent=(HANDLE)CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hDbEvent,0)) + { + dbei.cbBlob=0; + if (CallService(MS_DB_EVENT_GET,(WPARAM)hDbEvent,(LPARAM)&dbei)==0) + if ((dbei.flags&(DBEF_SENT|DBEF_READ))==0 && ((dbei.eventType==ICQEVENTTYPE_SMS) || (dbei.eventType==ICQEVENTTYPE_SMSCONFIRMATION))) + if (dbei.cbBlob>MIN_SMS_DBEVENT_LEN) + { + handleNewMessage((WPARAM)hContact,(LPARAM)hDbEvent); + } + } +} + + + + + + + + + + + + + + + + diff --git a/plugins/!NotAdopted/SMS/functions.cpp b/plugins/!NotAdopted/SMS/functions.cpp new file mode 100644 index 0000000000..aebafa42d8 --- /dev/null +++ b/plugins/!NotAdopted/SMS/functions.cpp @@ -0,0 +1,761 @@ +#include "main.h" + + + + + +BOOL DB_GetStaticStringW(HANDLE hContact,LPSTR lpszModule,LPSTR lpszValueName,LPWSTR lpwszRetBuff,SIZE_T dwRetBuffSize,SIZE_T *pdwRetBuffSize) +{// sizes in wchars + BOOL bRet=FALSE; + SIZE_T dwReadedStringLen; + DBVARIANT dbv={0}; + DBCONTACTGETSETTING sVal={0}; + + dbv.type=DBVT_WCHAR; + sVal.pValue=&dbv; + sVal.szModule=lpszModule; + sVal.szSetting=lpszValueName; + if (CallService(MS_DB_CONTACT_GETSETTING_STR,(WPARAM)hContact,(LPARAM)&sVal)==0) + { + dwReadedStringLen=lstrlenW(dbv.pwszVal); + if (lpwszRetBuff && (dwRetBuffSize>dwReadedStringLen)) + { + CopyMemory(lpwszRetBuff,dbv.pszVal,(dwReadedStringLen*sizeof(WCHAR)));//include null terminated + (*((WCHAR*)(lpwszRetBuff+dwReadedStringLen)))=0; + bRet=TRUE; + }else{ + if (lpwszRetBuff && dwRetBuffSize>=sizeof(WCHAR)) (*((WCHAR*)lpwszRetBuff))=0; + } + if (pdwRetBuffSize) (*pdwRetBuffSize)=dwReadedStringLen; + + DBFreeVariant(&dbv); + }else{ + if (lpwszRetBuff && dwRetBuffSize>=sizeof(WCHAR)) (*((WCHAR*)lpwszRetBuff))=0; + if (pdwRetBuffSize) (*pdwRetBuffSize)=0; + } +return(bRet); +} + + +BOOL DB_SetStringExW(HANDLE hContact,LPSTR lpszModule,LPSTR lpszValueName,LPWSTR lpwszValue,SIZE_T dwValueSize) +{ + BOOL bRet=FALSE; + + if (lpwszValue && dwValueSize) + { + LPWSTR lpwszValueLocal=(LPWSTR)MEMALLOC(((dwValueSize+MAX_PATH)*sizeof(WCHAR))); + + if (lpwszValueLocal) + { + DBCONTACTWRITESETTING cws={0}; + + cws.szModule=lpszModule; + cws.szSetting=lpszValueName; + cws.value.type=DBVT_WCHAR; + cws.value.pwszVal=(WCHAR*)lpwszValueLocal; + CopyMemory(lpwszValueLocal,lpwszValue,(dwValueSize*sizeof(WCHAR))); + bRet=(CallService(MS_DB_CONTACT_WRITESETTING,(WPARAM)hContact,(LPARAM)&cws)==0); + + MEMFREE(lpwszValueLocal); + } + }else{ + bRet=TRUE; + DBDeleteContactSetting(hContact,lpszModule,lpszValueName); + } +return(bRet); +} + + +LPSTR GetModuleName(HANDLE hContact) +{ + LPSTR lpszRet; + + if (hContact) + { + lpszRet=(LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0); + if (lpszRet==NULL) lpszRet=PROTOCOL_NAMEA; + }else{ + lpszRet=PROTOCOL_NAMEA; + } +return(lpszRet); +} + + +void EnableControlsArray(HWND hWndDlg,WORD *pwControlsList,SIZE_T dwControlsListCount,BOOL bEnabled) +{ + for(SIZE_T i=0;i='0' && btChar<='9') (*lpbOutBuff++)=btChar; + } + (*lpbOutBuff)=0; + +return((lpbOutBuff-(LPBYTE)lpszOutBuff)); +} + +SIZE_T CopyNumberW(LPWSTR lpcOutBuff,LPWSTR lpcBuff,SIZE_T dwLen) +{ + WCHAR wChar; + LPWSTR lpwszOutBuff=lpcOutBuff,lpwszInBuff=lpcBuff; + + for(SIZE_T i=0;i='0' && wChar<='9') (*lpwszOutBuff++)=wChar; + } + (*lpwszOutBuff)=0; + +return((lpwszOutBuff-lpcOutBuff)); +} + + +BOOL IsPhoneW(LPWSTR lpwszString,SIZE_T dwStringLen) +{ + BOOL bRet; + + if (dwStringLen>1) + {// country code + WCHAR wChar; + + bRet=TRUE; + for(SIZE_T i=0;i'9') + if (wChar!='+' && wChar!='S' && wChar!='M' && wChar!=' ' && wChar!='(' && wChar!=')') + { + bRet=FALSE; + break; + } + } + }else{ + bRet=FALSE; + } +return(bRet); +} + + + +DWORD GetContactPhonesCountParam(HANDLE hContact,LPSTR lpszModule,LPSTR lpszValueName) +{ + DWORD dwRet=0; + char szBuff[MAX_PATH]; + WCHAR wszPhone[MAX_PHONE_LEN]; + SIZE_T i,dwPhoneSize; + + if (DB_GetStaticStringW(hContact,lpszModule,lpszValueName,wszPhone,SIZEOF(wszPhone),&dwPhoneSize)) + { + if (IsPhoneW(wszPhone,dwPhoneSize)) dwRet++; + } + + for (i=0;TRUE;i++) + { + mir_snprintf(szBuff,sizeof(szBuff),"%s%ld",lpszValueName,i); + if (DB_GetStaticStringW(hContact,lpszModule,szBuff,wszPhone,SIZEOF(wszPhone),&dwPhoneSize)) + { + if (IsPhoneW(wszPhone,dwPhoneSize)) dwRet++; + }else{ + if (i>PHONES_MIN_COUNT) break; + } + } +return(dwRet); +} + + +DWORD GetContactPhonesCount(HANDLE hContact) +{ + DWORD dwRet=0; + LPSTR lpszProto; + + lpszProto=(LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0); + if (lpszProto) + { + dwRet+=GetContactPhonesCountParam(hContact,lpszProto,"Phone"); + dwRet+=GetContactPhonesCountParam(hContact,lpszProto,"Cellular"); + dwRet+=GetContactPhonesCountParam(hContact,lpszProto,"Fax"); + } + dwRet+=GetContactPhonesCountParam(hContact,"UserInfo","MyPhone"); + dwRet+=GetContactPhonesCountParam(hContact,"UserInfo","Phone"); + dwRet+=GetContactPhonesCountParam(hContact,"UserInfo","Cellular"); + dwRet+=GetContactPhonesCountParam(hContact,"UserInfo","Fax"); + +return(dwRet); +} + + +BOOL IsContactPhoneParam(HANDLE hContact,LPSTR lpszModule,LPSTR lpszValueName,LPWSTR lpwszPhone,SIZE_T dwPhoneSize) +{ + BOOL bRet=FALSE; + char szBuff[MAX_PATH]; + WCHAR wszPhoneLocal[MAX_PHONE_LEN]; + SIZE_T i,dwPhoneSizeLocal; + + if (DB_GetStaticStringW(hContact,lpszModule,lpszValueName,wszPhoneLocal,SIZEOF(wszPhoneLocal),&dwPhoneSizeLocal)) + if (IsPhoneW(wszPhoneLocal,dwPhoneSizeLocal)) + { + dwPhoneSizeLocal=CopyNumberW(wszPhoneLocal,wszPhoneLocal,dwPhoneSizeLocal); + if (MemoryCompare(wszPhoneLocal,dwPhoneSizeLocal,lpwszPhone,dwPhoneSize)==CSTR_EQUAL) + { + bRet=TRUE; + } + } + + for (i=0;bRet==FALSE;i++) + { + mir_snprintf(szBuff,sizeof(szBuff),"%s%ld",lpszValueName,i); + if (DB_GetStaticStringW(hContact,lpszModule,szBuff,wszPhoneLocal,SIZEOF(wszPhoneLocal),&dwPhoneSizeLocal)) + { + if (IsPhoneW(wszPhoneLocal,dwPhoneSizeLocal)) + { + dwPhoneSizeLocal=CopyNumberW(wszPhoneLocal,wszPhoneLocal,dwPhoneSizeLocal); + if (MemoryCompare(wszPhoneLocal,dwPhoneSizeLocal,lpwszPhone,dwPhoneSize)==CSTR_EQUAL) + { + bRet=TRUE; + break; + } + } + }else{ + if (i>PHONES_MIN_COUNT) break; + } + } +return(bRet); +} + + +BOOL IsContactPhone(HANDLE hContact,LPWSTR lpwszPhone,SIZE_T dwPhoneSize) +{ + BOOL bRet=FALSE; + WCHAR wszPhoneLocal[MAX_PHONE_LEN]; + LPSTR lpszProto; + SIZE_T dwPhoneSizeLocal; + + dwPhoneSizeLocal=CopyNumberW(wszPhoneLocal,lpwszPhone,dwPhoneSize); + lpszProto=(LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0); + if (lpszProto) + { + if (bRet==FALSE) bRet=IsContactPhoneParam(hContact,lpszProto,"Phone",wszPhoneLocal,dwPhoneSizeLocal); + if (bRet==FALSE) bRet=IsContactPhoneParam(hContact,lpszProto,"Cellular",wszPhoneLocal,dwPhoneSizeLocal); + if (bRet==FALSE) bRet=IsContactPhoneParam(hContact,lpszProto,"Fax",wszPhoneLocal,dwPhoneSizeLocal); + } + if (bRet==FALSE) bRet=IsContactPhoneParam(hContact,"UserInfo","MyPhone",wszPhoneLocal,dwPhoneSizeLocal); + if (bRet==FALSE) bRet=IsContactPhoneParam(hContact,"UserInfo","Phone",wszPhoneLocal,dwPhoneSizeLocal); + if (bRet==FALSE) bRet=IsContactPhoneParam(hContact,"UserInfo","Cellular",wszPhoneLocal,dwPhoneSizeLocal); + if (bRet==FALSE) bRet=IsContactPhoneParam(hContact,"UserInfo","Fax",wszPhoneLocal,dwPhoneSizeLocal); + +return(bRet); +} + + +//This function get a string cellular number and return the HANDLE of the contact that has this +//number in the miranda phonebook (and marked as an SMS able) at the User Details. +//If no one has this number function returns NULL. +HANDLE HContactFromPhone(LPWSTR lpwszPhone,SIZE_T dwPhoneSize) +{ + HANDLE hContact=NULL; + + if (lpwszPhone && dwPhoneSize) + { + //check not already on list + for(hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);hContact!=NULL;hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)) + { + if (IsContactPhone(hContact,lpwszPhone,dwPhoneSize)) break; + } + } +return(hContact); +} + + +BOOL GetDataFromMessage(LPSTR lpszMessage,SIZE_T dwMessageSize,DWORD *pdwEventType,LPWSTR lpwszPhone,SIZE_T dwPhoneSize,SIZE_T *pdwPhoneSizeRet,UINT *piIcon) +{ + BOOL bRet=FALSE; + + DWORD dwEventTypeRet=0; + SIZE_T dwPhoneSizeRet=0; + UINT iIconRet=0; + + if (lpszMessage && dwMessageSize) + { + LPSTR lpsz; + + if (MemoryCompare(lpszMessage,10,"SMS From: ",10)==CSTR_EQUAL) + { + lpsz=(LPSTR)MemoryFind(10,lpszMessage,dwMessageSize,"\r\n",2); + if (lpsz) + { + if (lpwszPhone && dwPhoneSize) + { + dwPhoneSizeRet=MultiByteToWideChar(CP_UTF8,0,(lpszMessage+10),min((SIZE_T)(lpsz-(lpszMessage+10)),dwPhoneSize),lpwszPhone,dwPhoneSize); + dwPhoneSizeRet=CopyNumberW(lpwszPhone,lpwszPhone,dwPhoneSizeRet); + } + } + iIconRet=0; + dwEventTypeRet=ICQEVENTTYPE_SMS; + bRet=TRUE; + }else + if (MemoryCompare(lpszMessage,23,"SMS Confirmation From: ",23)==CSTR_EQUAL) + { + lpsz=(LPSTR)MemoryFind(23,lpszMessage,dwMessageSize,"\r\n",2); + if (lpsz) + { + if (lpwszPhone && dwPhoneSize) + { + dwPhoneSizeRet=MultiByteToWideChar(CP_UTF8,0,(lpszMessage+23),min((SIZE_T)(lpsz-(lpszMessage+23)),dwPhoneSize),lpwszPhone,dwPhoneSize); + dwPhoneSizeRet=CopyNumberW(lpwszPhone,lpwszPhone,dwPhoneSizeRet); + } + + lpsz+=2; + if (MemoryCompare(lpsz,24,"SMS was sent succesfully",24)==CSTR_EQUAL) + { + iIconRet=IDI_SMSSENT; + }else{ + iIconRet=IDI_SMSNOTSENT; + } + } + dwEventTypeRet=ICQEVENTTYPE_SMSCONFIRMATION; + bRet=TRUE; + } + } + + if (pdwPhoneSizeRet) (*pdwPhoneSizeRet)=dwPhoneSizeRet; + if (pdwEventType) (*pdwEventType)=dwEventTypeRet; + if (piIcon) (*piIcon)=iIconRet; + +return(bRet); +} + +BOOL GetXMLFieldEx(LPSTR lpszXML,SIZE_T dwXMLSize,LPSTR *plpszData,SIZE_T *pdwDataSize,const char *tag1,...) +{ + BOOL bRet=FALSE; + int thisLevel=0; + LPSTR lpszFindTag=(LPSTR)tag1,lpszTagStart,lpszTagEnd=lpszXML,lpszDataStart=NULL; + va_list va; + + va_start(va,tag1); + while(TRUE) + { + lpszTagStart=(LPSTR)MemoryFindByte((lpszTagEnd-lpszXML),lpszXML,dwXMLSize,'<'); + if (lpszTagStart) + { + lpszTagEnd=(LPSTR)MemoryFindByte((lpszTagStart-lpszXML),lpszXML,dwXMLSize,'>'); + if (lpszTagEnd) + { + lpszTagStart++; + lpszTagEnd--; + if ((*((BYTE*)lpszTagStart))=='/') + { + if (--thisLevel<0) + { + if (lpszDataStart) + { + if (plpszData) (*plpszData)=lpszDataStart; + if (pdwDataSize) (*pdwDataSize)=((lpszTagStart-1)-lpszDataStart); + bRet=TRUE; + } + break; + } + }else{ + if (++thisLevel==1) + if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszFindTag,-1,lpszTagStart,((lpszTagEnd+1)-lpszTagStart))==CSTR_EQUAL) + { + lpszFindTag=va_arg(va,LPSTR); + if (lpszFindTag==NULL) lpszDataStart=(lpszTagEnd+2); + thisLevel=0; + } + } + }else{ + break; + } + }else{ + break; + } + } + va_end(va); +return(bRet); +} + + +BOOL GetXMLFieldExBuff(LPSTR lpszXML,SIZE_T dwXMLSize,LPSTR lpszBuff,SIZE_T dwBuffSize,SIZE_T *pdwBuffSizeRet,const char *tag1,...) +{ + BOOL bRet=FALSE; + int thisLevel=0; + LPSTR lpszFindTag=(LPSTR)tag1,lpszTagStart,lpszTagEnd=lpszXML,lpszDataStart=NULL; + va_list va; + + + va_start(va,tag1); + while(TRUE) + { + lpszTagStart=(LPSTR)MemoryFindByte((lpszTagEnd-lpszXML),lpszXML,dwXMLSize,'<'); + if (lpszTagStart) + { + lpszTagEnd=(LPSTR)MemoryFindByte((lpszTagStart-lpszXML),lpszXML,dwXMLSize,'>'); + if (lpszTagEnd) + { + lpszTagStart++; + lpszTagEnd--; + if ((*((BYTE*)lpszTagStart))=='/') + { + if (--thisLevel<0) + { + if (lpszDataStart) + { + SIZE_T dwBuffSizeRet=min((dwBuffSize-2),(SIZE_T)((lpszTagStart-1)-lpszDataStart)); + if (lpszBuff && dwBuffSize) CopyMemory(lpszBuff,lpszDataStart,dwBuffSizeRet);(*((WORD*)(lpszBuff+dwBuffSizeRet)))=0; + if (pdwBuffSizeRet) (*pdwBuffSizeRet)=dwBuffSizeRet; + bRet=TRUE; + } + break; + } + }else{ + if (++thisLevel==1) + if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszFindTag,-1,lpszTagStart,((lpszTagEnd+1)-lpszTagStart))==CSTR_EQUAL) + { + lpszFindTag=va_arg(va,LPSTR); + if (lpszFindTag==NULL) lpszDataStart=(lpszTagEnd+2); + thisLevel=0; + } + } + }else{ + break; + } + }else{ + break; + } + } + va_end(va); + + + if (bRet==FALSE) + { + if (lpszBuff) (*((WORD*)lpszBuff))=0; + if (pdwBuffSizeRet) (*pdwBuffSizeRet)=0; + } + +return(bRet); +} + + +/*BOOL GetXMLFieldExW(LPWSTR lpwszXML,SIZE_T dwXMLSize,LPWSTR *plpwszData,SIZE_T *pdwDataSize,const WCHAR *tag1,...) +{ + BOOL bRet=FALSE; + int thisLevel=0; + LPWSTR lpwszFindTag=(LPWSTR)tag1,lpwszTagStart,lpwszTagEnd=lpwszXML,lpwszDataStart=NULL; + va_list va; + + va_start(va,tag1); + while(TRUE) + { + lpwszTagStart=(LPWSTR)MemoryFind((lpwszTagEnd-lpwszXML),lpwszXML,dwXMLSize,L"<",2); + if (lpwszTagStart) + { + lpwszTagEnd=(LPWSTR)MemoryFind((lpwszTagStart-lpwszXML),lpwszXML,dwXMLSize,L">",2); + if (lpwszTagEnd) + { + lpwszTagStart++; + lpwszTagEnd--; + if ((*((WORD*)lpwszTagStart))==(*((WORD*)"/"))) + { + if (--thisLevel<0) + { + if (lpwszDataStart) + { + if (plpwszData) (*plpwszData)=lpwszDataStart; + if (pdwDataSize) (*pdwDataSize)=((lpwszTagStart-1)-lpwszDataStart); + bRet=TRUE; + } + break; + } + }else{ + if (++thisLevel==1) + if (CompareStringW(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpwszFindTag,-1,lpwszTagStart,((lpwszTagEnd+1)-lpwszTagStart))==CSTR_EQUAL) + { + lpwszFindTag=va_arg(va,LPWSTR); + if (lpwszFindTag==NULL) lpwszDataStart=(lpwszTagEnd+2); + thisLevel=0; + } + } + }else{ + break; + } + }else{ + break; + } + } + va_end(va); +return(bRet); +} + + +BOOL GetXMLFieldExBuffW(LPWSTR lpwszXML,SIZE_T dwXMLSize,LPWSTR lpwszBuff,SIZE_T dwBuffSize,SIZE_T *pdwBuffSizeRet,const WCHAR *tag1,...) +{ + BOOL bRet; + LPWSTR lpwszData; + SIZE_T dwDataSize; + + if ((bRet=GetXMLFieldExW(lpwszXML,dwXMLSize,&lpwszData,&dwDataSize,tag1))) + { + SIZE_T dwBuffSizeRet=min((dwBuffSize-2),dwDataSize); + + if (lpwszBuff && dwBuffSize) CopyMemory(lpwszBuff,lpwszData,dwBuffSizeRet);(*((WORD*)(lpwszBuff+dwBuffSizeRet)))=0; + if (pdwBuffSizeRet) (*pdwBuffSizeRet)=dwBuffSizeRet; + }else{ + if (lpwszBuff) (*((WORD*)lpwszBuff))=0; + if (pdwBuffSizeRet) (*pdwBuffSizeRet)=0; + } + +return(bRet); +}//*/ + + +DWORD ReplaceInBuff(LPVOID lpInBuff,SIZE_T dwInBuffSize,SIZE_T dwReplaceItemsCount,LPVOID *plpInReplaceItems,SIZE_T *pdwInReplaceItemsCounts,LPVOID *plpOutReplaceItems,SIZE_T *pdwOutReplaceItemsCounts,LPVOID lpOutBuff,SIZE_T dwOutBuffSize,SIZE_T *pdwOutBuffSize) +{ + DWORD dwRetErrorCode=NO_ERROR; + LPBYTE *plpszFounded,lpszMessageConvertedCur,lpszMessageCur,lpszMessageCurPrev,lpszMessageConvertedMax; + SIZE_T i,dwFirstFoundedIndex=0,dwFoundedCount=0,dwMemPartToCopy; + +#ifdef _DEBUG //check tables + for(i=0;i(lpszMessageConvertedCur+(dwMemPartToCopy+pdwInReplaceItemsCounts[dwFirstFoundedIndex]))) + { + CopyMemory(lpszMessageConvertedCur,lpszMessageCurPrev,dwMemPartToCopy);lpszMessageConvertedCur+=dwMemPartToCopy; + CopyMemory(lpszMessageConvertedCur,plpOutReplaceItems[dwFirstFoundedIndex],pdwOutReplaceItemsCounts[dwFirstFoundedIndex]);lpszMessageConvertedCur+=pdwOutReplaceItemsCounts[dwFirstFoundedIndex]; + lpszMessageCurPrev=(plpszFounded[dwFirstFoundedIndex]+pdwInReplaceItemsCounts[dwFirstFoundedIndex]); + + for(i=0;i")}; +static const SIZE_T dwXMLSymbolsCount[] ={sizeof(TCHAR), sizeof(TCHAR), sizeof(TCHAR), sizeof(TCHAR), sizeof(TCHAR)}; + +//Decode XML coded string. The function translate special xml code into standard characters. +DWORD DecodeXML(LPTSTR lptszMessage,SIZE_T dwMessageSize,LPTSTR lptszMessageConverted,SIZE_T dwMessageConvertedBuffSize,SIZE_T *pdwMessageConvertedSize) +{ + DWORD dwRet=ReplaceInBuff(lptszMessage,(dwMessageSize*sizeof(TCHAR)),SIZEOF(lpszXMLTags),(LPVOID*)lpszXMLTags,(SIZE_T*)dwXMLTagsCount,(LPVOID*)lpszXMLSymbols,(SIZE_T*)dwXMLSymbolsCount,lptszMessageConverted,(dwMessageConvertedBuffSize*sizeof(TCHAR)),pdwMessageConvertedSize); + + if (pdwMessageConvertedSize) (*pdwMessageConvertedSize)/=sizeof(TCHAR); +return(dwRet); +} + +//Encode XML coded string. The function translate special saved xml characters into special characters. +DWORD EncodeXML(LPTSTR lptszMessage,SIZE_T dwMessageSize,LPTSTR lptszMessageConverted,SIZE_T dwMessageConvertedBuffSize,SIZE_T *pdwMessageConvertedSize) +{ + DWORD dwRet=ReplaceInBuff(lptszMessage,(dwMessageSize*sizeof(TCHAR)),SIZEOF(lpszXMLTags),(LPVOID*)lpszXMLSymbols,(SIZE_T*)dwXMLSymbolsCount,(LPVOID*)lpszXMLTags,(SIZE_T*)dwXMLTagsCount,lptszMessageConverted,(dwMessageConvertedBuffSize*sizeof(TCHAR)),pdwMessageConvertedSize); + + if (pdwMessageConvertedSize) (*pdwMessageConvertedSize)/=sizeof(TCHAR); +return(dwRet); +} + + +//(Taken from Miranda-IM source code:) +BYTE MsgDlgGetFontDefaultCharset(const TCHAR* szFont) +{ + return(DEFAULT_CHARSET); +} + + +void LoadMsgDlgFont(int i,LOGFONT *lf,COLORREF *colour) +{ + int style; + char str[MAX_PATH]; + DBVARIANT dbv; + + if (colour) + { + mir_snprintf(str,sizeof(str),"Font%dCol",i); + (*colour)=DBGetContactSettingDword(NULL,SRMMMOD,str,fontOptionsList[0].defColour); + } + + if (lf) + { + if (DBGetContactSetting(NULL,SRMMMOD,str,&dbv)) + { + lstrcpyn(lf->lfFaceName,fontOptionsList[0].szDefFace,SIZEOF(lf->lfFaceName)); + }else{ + lstrcpyn(lf->lfFaceName,dbv.ptszVal,SIZEOF(lf->lfFaceName)); + DBFreeVariant(&dbv); + } + + mir_snprintf(str,sizeof(str),"Font%dSize",i); + lf->lfHeight=(char)DBGetContactSettingByte(NULL,SRMMMOD,str,fontOptionsList[0].defSize); + lf->lfWidth=0; + lf->lfEscapement=0; + lf->lfOrientation=0; + mir_snprintf(str,sizeof(str),"Font%dSty",i); + style=DBGetContactSettingByte(NULL,SRMMMOD,str,fontOptionsList[0].defStyle); + lf->lfWeight=style&FONTF_BOLD?FW_BOLD:FW_NORMAL; + lf->lfItalic=style&FONTF_ITALIC?1:0; + lf->lfUnderline=0; + lf->lfStrikeOut=0; + mir_snprintf(str,sizeof(str),"Font%dSet",i); + lf->lfCharSet=DBGetContactSettingByte(NULL,SRMMMOD,str,MsgDlgGetFontDefaultCharset(lf->lfFaceName)); + lf->lfOutPrecision=OUT_DEFAULT_PRECIS; + lf->lfClipPrecision=CLIP_DEFAULT_PRECIS; + lf->lfQuality=DEFAULT_QUALITY; + lf->lfPitchAndFamily=DEFAULT_PITCH|FF_DONTCARE; + mir_snprintf(str,sizeof(str),"Font%d",i); + } +} + + +LRESULT CALLBACK MessageSubclassProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) +{ + LRESULT lrRet=0; + WNDPROC OldMessageEditProc=(WNDPROC)GetWindowLongPtr(hwnd,GWL_USERDATA); + + switch(message){ + case WM_CHAR: + if (wParam=='\n' && GetKeyState(VK_CONTROL)&0x8000) + { + PostMessage(GetParent(hwnd),WM_COMMAND,IDOK,0); + return(0); + } + break; + } + + if (OldMessageEditProc) lrRet=CallWindowProc(OldMessageEditProc,hwnd,message,wParam,lParam); + +return(lrRet); +} + + + + +//This function refresh account list. +//It called when SMS plugin loaded and upon change in the account list. +int RefreshAccountList(WPARAM eventCode,LPARAM lParam) +{ + SIZE_T dwAccCount=0,i,dwSMSAccountsCount=0; + PROTOACCOUNT **ppaAccounts; + + ProtoEnumAccounts((int*)&dwAccCount,&ppaAccounts); + + FreeAccountList(); + ssSMSSettings.ppaSMSAccounts=(PROTOACCOUNT**)MEMALLOC((dwAccCount*sizeof(LPVOID))); + if (ssSMSSettings.ppaSMSAccounts) + { + char szServiceName[MAX_PATH]; + + for (i=0;iszModuleName,MS_ICQ_SENDSMS); + if (ServiceExists(szServiceName)) + { + ssSMSSettings.ppaSMSAccounts[dwSMSAccountsCount++]=ppaAccounts[i]; + } + } + } + } + ssSMSSettings.dwSMSAccountsCount=dwSMSAccountsCount; + SendSMSWindowsUpdateAllAccountLists(); + +return(0); +} + +//This function free the global account list. +//This function should be called before list refresh or when SMS plugin unloaded. +void FreeAccountList() +{ + MEMFREE(ssSMSSettings.ppaSMSAccounts); + ssSMSSettings.dwSMSAccountsCount=0; +} + +//This function check if the module is in the account list that supports sms sending in miranda. +/*BOOL IsModuleInAccountList(LPSTR lpszModule) +{ + BOOL bRet=FALSE; + + if (ssSMSSettings.ppaSMSAccounts && ssSMSSettings.dwSMSAccountsCount) + { + for(SIZE_T i=0;iszModuleName,-1,lpszModule,-1)==CSTR_EQUAL) + { + bRet=TRUE; + break; + } + } + } +return(bRet); +}//*/ + diff --git a/plugins/!NotAdopted/SMS/langpack_sms.txt b/plugins/!NotAdopted/SMS/langpack_sms.txt new file mode 100644 index 0000000000..376dff2c65 --- /dev/null +++ b/plugins/!NotAdopted/SMS/langpack_sms.txt @@ -0,0 +1,119 @@ +Miranda Language Pack Version 1 +Language: English (UK) for Multi-Status Msgs +Locale: 0809 +Last-Modified-Using: Miranda 0.2.1.0 +Authors: bid, NuKe007 +Author-email: electrodudez@yahoo.com, nuke007@nuke007.tk +Plugins-included: SMS + + +; !!!SMS by Nuke007!!! +; The name of this file should be langpack_sms.txt and be in the miranda directory! +; Under all the [STRING] put your desired text to replace, and in all places that has %d, %s, /r, /n please keep them, because it could cause problem + +[Send &SMS...] + +[&SMS Message] + +[Can't load SMS Plugin, ICQ protocol must be loaded.] + +[SMS Plugin Error] + +[Unknown] + +; Don't forget the %d, and this could be in other langpack files. +[Custom %d] + +[Send SMS] + +[From %s on ICQ:\r\n\r\n] + +[Events] + +[SMS Plugin] + +[Multiple >>] + +[<< Single] + +[SMS message didn't send by ICQ to %s because:\r\n] + +[SMS Confirmation from %s] + +[SMS Message from %s] + +[Incoming SMS Message] + +[View User's History] + +[Add Number To The Multiple List] + +[Save Number To The User's Details Phonebook] + +[Show/Hide Multiple List] + +[Shows How Much Chars You've Typed] + +[The SMS message send to %s timed out.] + +[The phone number should start with a + and consist of numbers, spaces, brackets and hyphens only.] + +[Invalid Phone Number] + +[Error - Message too long] + +[Message is too long, press OK to continue.] + +[Valid phone numbers are of the form '+(country code)(phone number)'. The contents of the phone number portion is dependent on the national layout of phone numbers, but often omits the leading zero.] + +[No Numbers] + +[There must be numbers in the list first.] + +[Signature:] + +[Put signature at the:] + +[Begining] + +[End] + +[Show server notifications:] + +[Yes] + +[No] + +[To:] + +[Number:] + +[Enter message:] + +[&Send] + +[&Close] + +[Chars:] + +[Save number] + +[Add number to list] + +[From:] + +[Message received:] + +[&Reply] + +[Message ID:] + +[Network:] + +[Source:] + +[&Ok] + +[&Try again] + +[&Cancel] \ No newline at end of file diff --git a/plugins/!NotAdopted/SMS/main.cpp b/plugins/!NotAdopted/SMS/main.cpp new file mode 100644 index 0000000000..64ff1a92f1 --- /dev/null +++ b/plugins/!NotAdopted/SMS/main.cpp @@ -0,0 +1,298 @@ +/* +Miranda-IM SMS Plugin +Copyright (C) 2001-2 Richard Hughes +Copyright (C) 2007-8 Rozhuk Ivan + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +--------------------------------------------------------------------------- + +This was the original words. +This plugin was modified by Ariel Shulman (NuKe007). +For any comments, problems, etc. contact me at Miranda-IM forums or E-Mail or ICQ. +All the information needed you can find at www.nuke007.tk +Enjoy the code and use it smartly! +*/ + +#include "main.h" + + + + + +extern "C" __declspec(naked) void __cdecl _chkstk() +{ + #define _PAGESIZE_ 4096 + + __asm + { + push ecx + + ; Calculate new TOS. + + lea ecx, [esp] + 8 - 4 ; TOS before entering function + size for ret value + sub ecx, eax ; new TOS + + ; Handle allocation size that results in wraparound. + ; Wraparound will result in StackOverflow exception. + + sbb eax, eax ; 0 if CF==0, ~0 if CF==1 + not eax ; ~0 if TOS did not wrapped around, 0 otherwise + and ecx, eax ; set to 0 if wraparound + + mov eax, esp ; current TOS + and eax, not ( _PAGESIZE_ - 1) ; Round down to current page boundary + + cs10: + cmp ecx, eax ; Is new TOS + jb short cs20 ; in probed page? + mov eax, ecx ; yes. + pop ecx + xchg esp, eax ; update esp + mov eax, dword ptr [eax] ; get return address + mov dword ptr [esp], eax ; and put it at new TOS + ret + + ; Find next lower page and probe + cs20: + sub eax, _PAGESIZE_ ; decrease by PAGESIZE + test dword ptr [eax],eax ; probe page. + jmp short cs10 + + } +}// + + +extern "C" void __declspec(naked) __cdecl _aulldiv() +{// http://tamiaode.3322.org/svn/ntldr/trunk/source/ntldr/ia32/x86stub.cpp + __asm + { + push ebx + push esi + + mov eax,[esp + 24] + or eax,eax + jnz short L1 + + mov ecx,[esp + 20] + mov eax,[esp + 16] + xor edx,edx + div ecx + mov ebx,eax + mov eax,[esp + 12] + div ecx + mov edx,ebx + jmp short L2 + + L1: + mov ecx,eax + mov ebx,[esp + 20] + mov edx,[esp + 14] + mov eax,[esp + 12] + + L3: + shr ecx,1 + rcr ebx,1 + shr edx,1 + rcr eax,1 + or ecx,ecx + jnz short L3 + div ebx + mov esi,eax + + mul dword ptr [esp + 24] + mov ecx,eax + mov eax,[esp + 20] + mul esi + add edx,ecx + jc short L4 + + cmp edx,[esp + 16] + ja short L4 + jb short L5 + cmp eax,[esp + 12] + jbe short L5 + L4: + dec esi + L5: + xor edx,edx + mov eax,esi + + L2: + + pop esi + pop ebx + + ret 16 + } +}// + + + + + +MM_INTERFACE mmi; +PLUGINLINK *pluginLink; +SMS_SETTINGS ssSMSSettings; + + +PLUGININFOEX pluginInfoEx={ + sizeof(PLUGININFOEX), + PROTOCOL_DISPLAY_NAME_ORIG" (Unicode)", + PLUGIN_VERSION_DWORD, + "Send SMS text messages to mobile phones through the IM networks ("__DATE__" "__TIME__")", + "Richard Hughes, Improved by Ariel Shulman, rewritten by Rozhuk Ivan", + "Rozhuk_I@mail.ru", + "© 2001-2 Richard Hughes, 2003 Ariel Shulman, 2007-2009 Rozhuk Ivan (Rozhuk_I@mail.ru)", + "http://miranda-icq.sourceforge.net/", + UNICODE_AWARE, //not transient + 0, //doesn't replace anything built-in + // {70AC2AC9-85C6-4624-9B05-24733FEBB052} + SMS_GUID +}; + + +extern "C" __declspec(dllexport) const MUUID interfaces[]={SMS_GUID,MIID_LAST}; + + + +int OnModulesLoaded (WPARAM wParam,LPARAM lParam); +int OnPreShutdown (WPARAM wParam,LPARAM lParam); +void VersionConversions(); + + + +BOOL WINAPI DllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID lpvReserved) +{ + switch(dwReason){ + case DLL_PROCESS_ATTACH: + ZeroMemory(&ssSMSSettings,sizeof(ssSMSSettings)); + ssSMSSettings.hInstance=hInstance; + ssSMSSettings.hHeap=HeapCreate(0,0,0);//GetProcessHeap(); + DisableThreadLibraryCalls((HMODULE)hInstance); + break; + case DLL_PROCESS_DETACH: + HeapDestroy(ssSMSSettings.hHeap); + ssSMSSettings.hHeap=NULL; + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + break; + } +return(TRUE); +} + +__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + if (mirandaVersion +#include +#include +#include +#ifdef NDEBUG + #include <..\minicrt\minicrt.h> +#else + #include <..\minicrt\timefuncs.h> +#endif //_DEBUG*/ + +#include +#include +#include +#include +#include +#include +#include "newpluginapi.h" +#include "m_database.h" +#include "m_clist.h" +#include "m_langpack.h" +#include "m_history.h" +#include "m_protomod.h" +#include "m_autoreplacer.h" +#include "resource.h" +#include "m_skin.h" +#include "m_protosvc.h" +#include "m_icq.h" +#include "m_protosvc.h" +#include "m_system.h" +#include "m_utils.h" +#include "m_options.h" +#include "m_updater.h" +#include "win2k.h" + + +// структура содержащая информацию по построению меню или расширеных иконок +struct GUI_DISPLAY_ITEM +{ + LPSTR lpszName; // имя сервиса, оно же имя в иколибе + LPWSTR lpwszDescr; // текстовое описание отображаемое юзеру + LONG defIcon; // иконка из ресурсов + LPVOID lpFunc; // функция вызываемая меню +}; + + +// структура содержащая информацию о сервисах/функциях +struct SERVICE_ITEM +{ + LPSTR lpszName; // имя сервиса, оно же имя в иколибе + LPVOID lpFunc; // функция вызываемая +}; + + + + +#include "SMSConstans.h" +#include "senddlg.h" +#include "recvdlg.h" + + + +#define MAIN_MENU_ITEMS_COUNT 1 +#define CONTACT_MENU_ITEMS_COUNT 1 + + +typedef struct +{ + HANDLE hHeap; + HINSTANCE hInstance; + + //HANDLE hMainMenuIcons[MAIN_MENU_ITEMS_COUNT+1]; + HANDLE hMainMenuItems[MAIN_MENU_ITEMS_COUNT+1]; + + //HANDLE hContactMenuIcons[CONTACT_MENU_ITEMS_COUNT+1]; + HANDLE hContactMenuItems[CONTACT_MENU_ITEMS_COUNT+1]; + + HANDLE hHookModulesLoaded; + HANDLE hHookPreShutdown; + HANDLE hHookOptInitialize; + HANDLE hHookRebuildCMenu; + HANDLE hHookDbAdd; + HANDLE hHookProtoAck; + HANDLE hHookAccListChanged; + + LIST_MT lmtSendSMSWindowsListMT; + LIST_MT lmtRecvSMSWindowsListMT; + + PROTOACCOUNT **ppaSMSAccounts; + SIZE_T dwSMSAccountsCount; + +} SMS_SETTINGS; + + + +extern SMS_SETTINGS ssSMSSettings; + + + + +#define MEMALLOC(Size) HeapAlloc(ssSMSSettings.hHeap,HEAP_ZERO_MEMORY,(Size+sizeof(SIZE_T))) +#define MEMREALLOC(Mem,Size) HeapReAlloc(ssSMSSettings.hHeap,(HEAP_ZERO_MEMORY),(LPVOID)Mem,(Size+sizeof(SIZE_T))) +#define MEMFREE(Mem) if (Mem) {HeapFree(ssSMSSettings.hHeap,0,(LPVOID)Mem);Mem=NULL;} + +#define SEND_DLG_ITEM_MESSAGEW(hDlg,nIDDlgItem,Msg,wParam,lParam) SendMessageW(GetDlgItem(hDlg,nIDDlgItem),Msg,wParam,lParam) +#define SEND_DLG_ITEM_MESSAGEA(hDlg,nIDDlgItem,Msg,wParam,lParam) SendMessageA(GetDlgItem(hDlg,nIDDlgItem),Msg,wParam,lParam) +#define SEND_DLG_ITEM_MESSAGE(hDlg,nIDDlgItem,Msg,wParam,lParam) SendMessage(GetDlgItem(hDlg,nIDDlgItem),Msg,wParam,lParam) + +#define IS_DLG_BUTTON_CHECKED(hDlg,nIDDlgItem) SEND_DLG_ITEM_MESSAGE(hDlg,nIDDlgItem,BM_GETCHECK,NULL,NULL) +#define CHECK_DLG_BUTTON(hDlg,nIDDlgItem,uCheck) SEND_DLG_ITEM_MESSAGE(hDlg,nIDDlgItem,BM_SETCHECK,(WPARAM)uCheck,NULL) + +#define SET_DLG_ITEM_TEXTW(hDlg,nIDDlgItem,lpString) SEND_DLG_ITEM_MESSAGEW(hDlg,nIDDlgItem,WM_SETTEXT,0,(LPARAM)lpString) +#define SET_DLG_ITEM_TEXTA(hDlg,nIDDlgItem,lpString) SEND_DLG_ITEM_MESSAGEA(hDlg,nIDDlgItem,WM_SETTEXT,0,(LPARAM)lpString) +#define SET_DLG_ITEM_TEXT(hDlg,nIDDlgItem,lpString) SEND_DLG_ITEM_MESSAGE(hDlg,nIDDlgItem,WM_SETTEXT,0,(LPARAM)lpString) + +#define GET_DLG_ITEM_TEXTW(hDlg,nIDDlgItem,lpString,nMaxCount) SEND_DLG_ITEM_MESSAGEW(hDlg,nIDDlgItem,WM_GETTEXT,(WPARAM)nMaxCount,(LPARAM)lpString) +#define GET_DLG_ITEM_TEXTA(hDlg,nIDDlgItem,lpString,nMaxCount) SEND_DLG_ITEM_MESSAGEA(hDlg,nIDDlgItem,WM_GETTEXT,(WPARAM)nMaxCount,(LPARAM)lpString) +#define GET_DLG_ITEM_TEXT(hDlg,nIDDlgItem,lpString,nMaxCount) SEND_DLG_ITEM_MESSAGE(hDlg,nIDDlgItem,WM_GETTEXT,(WPARAM)nMaxCount,(LPARAM)lpString) + +#define GET_DLG_ITEM_TEXT_LENGTH(hDlg,nIDDlgItem) SEND_DLG_ITEM_MESSAGE(hDlg,nIDDlgItem,WM_GETTEXTLENGTH,NULL,NULL) +#define GET_WINDOW_TEXT_LENGTH(hDlg) SendMessage(hDlg,WM_GETTEXTLENGTH,NULL,NULL) + +#define GET_CURRENT_COMBO_DATA(hWndDlg,ControlID) SEND_DLG_ITEM_MESSAGE(hWndDlg,ControlID,CB_GETITEMDATA,SEND_DLG_ITEM_MESSAGE(hWndDlg,ControlID,CB_GETCURSEL,0,0),0) + + + + +#define GetContactNameA(Contact) (LPSTR)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)Contact,0) +#define GetContactNameW(Contact) (LPWSTR)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)Contact,GCDNF_UNICODE) + +#define DB_SMS_DeleteValue(Contact,valueName) DBDeleteContactSetting(Contact,PROTOCOL_NAMEA,valueName) +#define DB_SMS_GetDword(Contact,valueName,parDefltValue) DBGetContactSettingDword(Contact,PROTOCOL_NAMEA,valueName,parDefltValue) +#define DB_SMS_SetDword(Contact,valueName,parValue) DBWriteContactSettingDword(Contact,PROTOCOL_NAMEA,valueName,parValue) +#define DB_SMS_GetWord(Contact,valueName,parDefltValue) DBGetContactSettingWord(Contact,PROTOCOL_NAMEA,valueName,parDefltValue) +#define DB_SMS_SetWord(Contact,valueName,parValue) DBWriteContactSettingWord(Contact,PROTOCOL_NAMEA,valueName,parValue) +#define DB_SMS_GetByte(Contact,valueName,parDefltValue) DBGetContactSettingByte(Contact,PROTOCOL_NAMEA,valueName,parDefltValue) +#define DB_SMS_SetByte(Contact,valueName,parValue) DBWriteContactSettingByte(Contact,PROTOCOL_NAMEA,valueName,parValue) +BOOL DB_GetStaticStringW(HANDLE hContact,LPSTR lpszModule,LPSTR lpszValueName,LPWSTR lpszRetBuff,SIZE_T dwRetBuffSize,SIZE_T *pdwRetBuffSize); +#define DB_SMS_GetStaticStringW(Contact,ValueName,Ret,RetBuffSize,pRetBuffSize) DB_GetStaticStringW(Contact,PROTOCOL_NAMEA,ValueName,Ret,RetBuffSize,pRetBuffSize) +BOOL DB_SetStringExW(HANDLE hContact,LPSTR lpszModule,LPSTR lpszValueName,LPWSTR lpwszValue,SIZE_T dwValueSize); +#define DB_SetStringW(Contact,Module,valueName,parValue) DBWriteContactSettingWString(Contact,Module,valueName,parValue) +#define DB_SMS_SetStringW(Contact,valueName,parValue) DBWriteContactSettingWString(Contact,PROTOCOL_NAMEA,valueName,parValue) +#define DB_SMS_SetStringExW(Contact,valueName,parValue,parValueSize) DB_SetStringExW(Contact,PROTOCOL_NAMEA,valueName,parValue,parValueSize) + + +LPSTR GetModuleName (HANDLE hContact); +void EnableControlsArray (HWND hWndDlg,WORD *pwControlsList,SIZE_T dwControlsListCount,BOOL bEnabled); +void CListShowMenuItem (HANDLE hMenuItem,BOOL bShow); +//Decleration of function that returns received string with only numbers +SIZE_T CopyNumberA (LPSTR lpszOutBuff,LPSTR lpszBuff,SIZE_T dwLen); +SIZE_T CopyNumberW (LPWSTR lpcOutBuff,LPWSTR lpcBuff,SIZE_T dwLen); +BOOL IsPhoneW (LPWSTR lpwszString,SIZE_T dwStringLen); +DWORD GetContactPhonesCount (HANDLE hContact); +BOOL IsContactPhone (HANDLE hContact,LPWSTR lpwszPhone,SIZE_T dwPhoneSize); +//Decleration of function that returns HANDLE of contact by his cellular number +HANDLE HContactFromPhone (LPWSTR lpwszPhone,SIZE_T dwPhoneSize); +BOOL GetDataFromMessage (LPSTR lpszMessage,SIZE_T dwMessageSize,DWORD *pdwEventType,LPWSTR lpwszPhone,SIZE_T dwPhoneSize,SIZE_T *pdwPhoneSizeRet,UINT *piIcon); +//Decleration of function that gets a XML string and return the asked tag. +BOOL GetXMLFieldEx (LPSTR lpszXML,SIZE_T dwXMLSize,LPSTR *plpszData,SIZE_T *pdwDataSize,const char *tag1,...); +BOOL GetXMLFieldExBuff (LPSTR lpszXML,SIZE_T dwXMLSize,LPSTR lpszBuff,SIZE_T dwBuffSize,SIZE_T *pdwBuffSizeRet,const char *tag1,...); +//BOOL GetXMLFieldExW (LPWSTR lpwszXML,SIZE_T dwXMLSize,LPWSTR *plpwszData,SIZE_T *pdwDataSize,const WCHAR *tag1,...); +//BOOL GetXMLFieldExBuffW (LPWSTR lpwszXML,SIZE_T dwXMLSize,LPWSTR lpwszBuff,SIZE_T dwBuffSize,SIZE_T *pdwBuffSizeRet,const WCHAR *tag1,...); +DWORD DecodeXML (LPTSTR lptszMessage,SIZE_T dwMessageSize,LPTSTR lptszMessageConverted,SIZE_T dwMessageConvertedBuffSize,SIZE_T *pdwMessageConvertedSize); +DWORD EncodeXML (LPTSTR lptszMessage,SIZE_T dwMessageSize,LPTSTR lptszMessageConverted,SIZE_T dwMessageConvertedBuffSize,SIZE_T *pdwMessageConvertedSize); +void LoadMsgDlgFont (int i,LOGFONT *lf,COLORREF *colour); +LRESULT CALLBACK MessageSubclassProc (HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam); +int RefreshAccountList (WPARAM eventCode,LPARAM lParam); +void FreeAccountList (); +//BOOL IsModuleInAccountList (LPSTR lpszModule); + + + + +int OptInitialise (WPARAM wParam,LPARAM lParam); + +int LoadServices (); +int LoadModules (); +void UnloadModules (); +void UnloadServices (); + +int handleAckSMS(WPARAM wParam,LPARAM lParam); +int handleNewMessage(WPARAM wParam,LPARAM lParam); +void RestoreUnreadMessageAlerts(); + +//Decleration of Menu SMS send click function +int SmsRebuildContactMenu(WPARAM wParam,LPARAM lParam); + + +void StartSmsSend(HWND hWndDlg,SIZE_T dwModuleIndex,LPWSTR lpwszPhone,SIZE_T dwPhoneSize,LPWSTR lpwszMessage,SIZE_T dwMessageSize); + + + + + + + + + + + +#endif \ No newline at end of file diff --git a/plugins/!NotAdopted/SMS/options.cpp b/plugins/!NotAdopted/SMS/options.cpp new file mode 100644 index 0000000000..dd52602484 --- /dev/null +++ b/plugins/!NotAdopted/SMS/options.cpp @@ -0,0 +1,116 @@ +/* +Miranda-IM SMS Plugin +Copyright (C) 2001-2002 Richard Hughes +Copyright (C) 2007-2009 Rozhuk Ivan + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +--------------------------------------------------------------------------- + +This was the original words. +This plugin was modified by Ariel Shulman (NuKe007). +For any comments, problems, etc. contact me at Miranda-IM forums or E-Mail or ICQ. +All the information needed you can find at www.nuke007.tk +Enjoy the code and use it smartly! +*/ +#include "main.h" + + + +WORD wSMSSignControlsList[]={ + IDC_BEGIN, + IDC_END, + IDC_SIGNATURE, + IDC_SIGNGROUP +}; + + +BOOL CALLBACK DlgProcEditorOptions(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg){ + case WM_INITDIALOG: + TranslateDialogDefault(hWndDlg); + { + WCHAR wszSign[1024]; + BOOL bSignBebefore,bUseSign; + + if (DB_SMS_GetStaticStringW(NULL,"Signature",wszSign,SIZEOF(wszSign),NULL)==FALSE) + { + mir_sntprintf(wszSign,SIZEOF(wszSign),TranslateW(L"From %s:\r\n\r\n"),GetContactNameW(NULL)); + } + SET_DLG_ITEM_TEXTW(hWndDlg,IDC_SIGNATURE,wszSign); + + bUseSign=DB_SMS_GetByte(NULL,"UseSignature",SMS_DEFAULT_USESIGNATURE); + CHECK_DLG_BUTTON(hWndDlg,IDC_USESIGNATURE,bUseSign); + EnableControlsArray(hWndDlg,(WORD*)&wSMSSignControlsList,SIZEOF(wSMSSignControlsList),bUseSign); + + bSignBebefore=DB_SMS_GetByte(NULL,"SignaturePos",SMS_DEFAULT_SIGNATUREPOS); + CHECK_DLG_BUTTON(hWndDlg,IDC_BEGIN,bSignBebefore); + CHECK_DLG_BUTTON(hWndDlg,IDC_END,(!bSignBebefore)); + + CHECK_DLG_BUTTON(hWndDlg,IDC_SHOWACK,DB_SMS_GetByte(NULL,"ShowACK",SMS_DEFAULT_SHOWACK)); + CHECK_DLG_BUTTON(hWndDlg,IDC_AUTOPOP,DB_SMS_GetByte(NULL,"AutoPopup",SMS_DEFAULT_AUTOPOP)); + CHECK_DLG_BUTTON(hWndDlg,IDC_SAVEWINPOS,DB_SMS_GetByte(NULL,"SavePerContact",SMS_DEFAULT_SAVEWINPOS)); + } + return(TRUE); + case WM_COMMAND: + SendMessage(GetParent(hWndDlg),PSM_CHANGED,0,0); + switch(LOWORD(wParam)){ + case IDC_USESIGNATURE: + EnableControlsArray(hWndDlg,(WORD*)&wSMSSignControlsList,SIZEOF(wSMSSignControlsList),IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_USESIGNATURE)); + break; + } + break; + case WM_NOTIFY: + switch(((LPNMHDR)lParam)->idFrom){ + case 0: + switch (((LPNMHDR)lParam)->code){ + case PSN_APPLY: + { + WCHAR wszSign[1024]; + + GET_DLG_ITEM_TEXTW(hWndDlg,IDC_SIGNATURE,wszSign,SIZEOF(wszSign)); + DB_SMS_SetStringW(NULL,"Signature",wszSign); + + DB_SMS_SetByte(NULL,"UseSignature",IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_USESIGNATURE)); + DB_SMS_SetByte(NULL,"SignaturePos",IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_BEGIN)); + DB_SMS_SetByte(NULL,"ShowACK",IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_SHOWACK)); + DB_SMS_SetByte(NULL,"AutoPopup",IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_AUTOPOP)); + DB_SMS_SetByte(NULL,"SavePerContact",IS_DLG_BUTTON_CHECKED(hWndDlg,IDC_SAVEWINPOS)); + } + return(TRUE); + } + break; + } + break; + } +return(FALSE); +} + +int OptInitialise(WPARAM wParam,LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp={0}; + + odp.cbSize=sizeof(odp); + odp.position=910000000; + odp.hInstance=ssSMSSettings.hInstance; + odp.ptszGroup=TranslateW(L"Events"); + odp.flags=(ODPF_BOLDGROUPS|ODPF_UNICODE); + odp.pszTemplate=MAKEINTRESOURCEA(IDD_OPT_SMSPLUGIN); + odp.ptszTitle=PROTOCOL_DISPLAY_NAME_ORIGW; + odp.pfnDlgProc=DlgProcEditorOptions; + CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp); +return(0); +} + diff --git a/plugins/!NotAdopted/SMS/readme.txt b/plugins/!NotAdopted/SMS/readme.txt new file mode 100644 index 0000000000..3fe787fec8 --- /dev/null +++ b/plugins/!NotAdopted/SMS/readme.txt @@ -0,0 +1,49 @@ +SMS плагин для Miranda IM + + +2001-2002 Richard Hughes +2003 Ariel Shulman +2007-2009 Rozhuk Ivan (Ivan 83) + + + Плагин предназначен для отправки SMS сообщений через миранду +с использованием ICQ, MRA и других протоколов поддерживающих отправку SMS. + + Эта версия плагина была переписана почти полностью, сохранены без изменений +только диалоги и часть коментариев. + + +Home page: http://www.rozhuk.org.ru/forum/index.php?topic=3.0 + + + + +Change Log: + +Version 0.2.5.3 // 02.11.2009 + - Поддержка Updater плагина + +Version 0.2.5.2 // 01.11.2009 + - Unicode версия + - Поддержка мультиакаунтов + - Добавлены настройки + - Внутренние изменения + - Частично используются иконки из миранды (Main Icons) + - Исправлены недочёты при обработке XML + - Улучшен алгоритм подсчёта "оставшихся" символов + +Version 0.2.5.1 // 26.10.2009 + - В диалоге отправки автоматически выбирается первый номер телефона из списка + - Настройки шрифтов и цветов фона берутся от TabSRMM + - Уменьшен размер плагина + - Устранены утечки ресурсов + - Устранено появление ложных пустых сообщений от джабер протокола + +Version 0.2.5.0 // 17.03.2008 + - Добавлена совместимость с новым ядром (GUID идентификатор) + +Version 0.2.4.9 + - Полностью переписан код: оптимизирован, устранены утечки памяти + - Добавленна возможность выбора потокола для отправки сообщений + - Автоподстановка номера при ответе + - Мелкие исправлени \ No newline at end of file diff --git a/plugins/!NotAdopted/SMS/receive.cpp b/plugins/!NotAdopted/SMS/receive.cpp new file mode 100644 index 0000000000..24a1df5be5 --- /dev/null +++ b/plugins/!NotAdopted/SMS/receive.cpp @@ -0,0 +1,310 @@ +/* +Miranda-IM SMS Plugin +Copyright (C) 2001-2 Richard Hughes +Copyright (C) 2007-2009 Rozhuk Ivan + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +--------------------------------------------------------------------------- + +This was the original words. +This plugin was modified by Ariel Shulman (NuKe007). +For any comments, problems, etc. contact me at Miranda-IM forums or E-Mail or ICQ. +All the information needed you can find at www.nuke007.tk +Enjoy the code and use it smartly! +*/ + +#include "main.h" + + + +//This function handles the ACK received from that hooked. +int handleAckSMS(WPARAM wParam,LPARAM lParam) +{ + if (lParam) + if (((ACKDATA*)lParam)->type==ICQACKTYPE_SMS) + { + char szPhone[MAX_PHONE_LEN]={0}; + WCHAR wszPhone[MAX_PHONE_LEN]={0}; + LPSTR lpszXML=(LPSTR)((ACKDATA*)lParam)->lParam,lpszData,lpszPhone; + SIZE_T dwXMLSize=lstrlenA(lpszXML),dwDataSize,dwPhoneSize; + ACKDATA *ack=((ACKDATA*)lParam); + + if (GetXMLFieldEx(lpszXML,dwXMLSize,&lpszData,&dwDataSize,"sms_message","text",NULL)) + { + if (GetXMLFieldEx(lpszXML,dwXMLSize,&lpszPhone,&dwPhoneSize,"sms_message","sender",NULL)) + { + LPSTR lpszMessageUTF; + LPWSTR lpwszMessageXMLEncoded,lpwszMessageXMLDecoded; + SIZE_T dwBuffLen,dwMessageXMLEncodedSize,dwMessageXMLDecodedSize; + HANDLE hContact; + DBEVENTINFO dbei={0}; + + dwBuffLen=(dwDataSize+MAX_PATH); + dbei.pBlob=(LPBYTE)MEMALLOC((dwBuffLen+dwPhoneSize)); + lpwszMessageXMLEncoded=(LPWSTR)MEMALLOC((dwBuffLen*sizeof(WCHAR))); + lpwszMessageXMLDecoded=(LPWSTR)MEMALLOC((dwBuffLen*sizeof(WCHAR))); + if (dbei.pBlob && lpwszMessageXMLEncoded && lpwszMessageXMLDecoded) + { + dwMessageXMLEncodedSize=MultiByteToWideChar(CP_UTF8,0,lpszData,dwDataSize,lpwszMessageXMLEncoded,dwBuffLen); + DecodeXML(lpwszMessageXMLEncoded,dwMessageXMLEncodedSize,lpwszMessageXMLDecoded,dwBuffLen,&dwMessageXMLDecodedSize); + lpszMessageUTF=(LPSTR)lpwszMessageXMLEncoded; + WideCharToMultiByte(CP_UTF8,0,lpwszMessageXMLDecoded,dwMessageXMLDecodedSize,lpszMessageUTF,dwBuffLen,NULL,NULL); + + dwPhoneSize=CopyNumberA(szPhone,lpszPhone,dwPhoneSize); + dwPhoneSize=MultiByteToWideChar(CP_UTF8,0,szPhone,dwPhoneSize,wszPhone,MAX_PHONE_LEN); + hContact=HContactFromPhone(wszPhone,dwPhoneSize); + + dbei.cbSize=sizeof(dbei); + dbei.szModule=GetModuleName(hContact); + dbei.timestamp=time(NULL); + dbei.flags=(DBEF_UTF); + dbei.eventType=ICQEVENTTYPE_SMS; + dbei.cbBlob=(mir_snprintf((LPSTR)dbei.pBlob,((dwBuffLen+dwPhoneSize)),"SMS From: +%s\r\n%s",szPhone,lpszMessageUTF)+sizeof(DWORD)); + //dbei.pBlob=(LPBYTE)lpszBuff; + (*((DWORD*)(dbei.pBlob+(dbei.cbBlob-sizeof(DWORD)))))=0; + CallService(MS_DB_EVENT_ADD,(WPARAM)hContact,(LPARAM)&dbei); + if (hContact==NULL) + { + if (RecvSMSWindowAdd(NULL,ICQEVENTTYPE_SMS,wszPhone,dwPhoneSize,(LPSTR)dbei.pBlob,dbei.cbBlob)) + { + CallService(MS_DB_EVENT_MARKREAD,(WPARAM)hContact,(LPARAM)&dbei); + SkinPlaySound("RecvSMSMsg"); + } + } + } + MEMFREE(lpwszMessageXMLDecoded); + MEMFREE(lpwszMessageXMLEncoded); + MEMFREE(dbei.pBlob); + } + }else + if (GetXMLFieldEx(lpszXML,dwXMLSize,&lpszData,&dwDataSize,"sms_delivery_receipt","delivered",NULL)) + { + if (GetXMLFieldEx(lpszXML,dwXMLSize,&lpszPhone,&dwPhoneSize,"sms_delivery_receipt","destination",NULL)) + { + HANDLE hContact; + DBEVENTINFO dbei={0}; + + dwPhoneSize=CopyNumberA(szPhone,lpszPhone,dwPhoneSize); + dwPhoneSize=MultiByteToWideChar(CP_UTF8,0,szPhone,dwPhoneSize,wszPhone,MAX_PHONE_LEN); + hContact=HContactFromPhone(wszPhone,dwPhoneSize); + + dbei.cbSize=sizeof(dbei); + dbei.szModule=GetModuleName(hContact); + dbei.timestamp=time(NULL); + dbei.eventType=ICQEVENTTYPE_SMSCONFIRMATION; + if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszData,dwDataSize,"yes",3)==CSTR_EQUAL) + { + dbei.cbBlob=(MAX_PHONE_LEN+MAX_PATH); + dbei.pBlob=(PBYTE)MEMALLOC(dbei.cbBlob); + if (dbei.pBlob) dbei.cbBlob=(mir_snprintf((LPSTR)dbei.pBlob,dbei.cbBlob,"SMS Confirmation From: +%s\r\nSMS was sent succesfully",szPhone)+4); + }else{ + if (GetXMLFieldEx(lpszXML,dwXMLSize,&lpszData,&dwDataSize,"sms_delivery_receipt","error","params","param",NULL)==FALSE) + { + lpszData=""; + dwDataSize=0; + } + dbei.cbBlob=(MAX_PHONE_LEN+MAX_PATH+dwDataSize); + dbei.pBlob=(PBYTE)MEMALLOC(dbei.cbBlob); + if (dbei.pBlob) + { + dbei.cbBlob=mir_snprintf((LPSTR)dbei.pBlob,dbei.cbBlob,"SMS Confirmation From: +%s\r\nSMS was not sent succesfully: ",szPhone); + CopyMemory((dbei.pBlob+dbei.cbBlob),lpszData,dwDataSize); + dbei.cbBlob+=(dwDataSize+sizeof(DWORD)); + (*((DWORD*)(dbei.pBlob+(dbei.cbBlob-sizeof(DWORD)))))=0; + } + } + + if (dbei.pBlob) + { + if (hContact) + { + CallService(MS_DB_EVENT_ADD,(WPARAM)hContact,(LPARAM)&dbei); + }else{ + RecvSMSWindowAdd(NULL,ICQEVENTTYPE_SMSCONFIRMATION,wszPhone,dwPhoneSize,(LPSTR)dbei.pBlob,dbei.cbBlob); + } + MEMFREE(dbei.pBlob); + } + } + }else + if ((ack->result==ACKRESULT_FAILED) || GetXMLFieldEx(lpszXML,dwXMLSize,&lpszData,&dwDataSize,"sms_response","deliverable",NULL)) + { + HWND hWndDlg=SendSMSWindowHwndByHProcessGet(ack->hProcess); + if (hWndDlg) + { + char szNetwork[MAX_PATH]; + + KillTimer(hWndDlg,wParam); + GetXMLFieldExBuff(lpszXML,dwXMLSize,szNetwork,sizeof(szNetwork),NULL,"sms_response","network",NULL); + + if (ack->result==ACKRESULT_FAILED || CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszData,dwDataSize,"no",2)==CSTR_EQUAL) + { + HWND hwndTimeOut; + char szBuff[1024]; + WCHAR wszErrorMessage[1028]; + LPSTR lpszErrorDescription; + + if (SendSMSWindowMultipleGet(hWndDlg)) + { + TVITEM tvi; + tvi.mask=TVIF_TEXT; + tvi.hItem=SendSMSWindowHItemSendGet(hWndDlg); + tvi.pszText=wszPhone; + tvi.cchTextMax=SIZEOF(wszPhone); + TreeView_GetItem(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),&tvi); + }else{ + GET_DLG_ITEM_TEXTW(hWndDlg,IDC_ADDRESS,wszPhone,SIZEOF(szPhone)); + } + + if (ack->result==ACKRESULT_FAILED) + { + lpszErrorDescription=lpszXML; + }else{ + lpszErrorDescription=szBuff; + GetXMLFieldExBuff(lpszXML,dwXMLSize,szBuff,sizeof(szBuff),NULL,"sms_response","error","params","param",NULL); + } + + mir_sntprintf(wszErrorMessage,SIZEOF(wszErrorMessage),TranslateW(L"SMS message didn't send by %S to %s because: %S"),szNetwork,wszPhone,lpszErrorDescription); + ShowWindow(hWndDlg,SW_SHOWNORMAL); + EnableWindow(hWndDlg,FALSE); + hwndTimeOut=CreateDialog(ssSMSSettings.hInstance,MAKEINTRESOURCE(IDD_SENDSMSTIMEDOUT),hWndDlg,SMSTimedOutDlgProc); + SET_DLG_ITEM_TEXTW(hwndTimeOut,IDC_STATUS,wszErrorMessage); + }else{ + SendSMSWindowDBAdd(hWndDlg); + if (SendSMSWindowMultipleGet(hWndDlg)) + { + if (SendSMSWindowNextHItemGet(hWndDlg,SendSMSWindowHItemSendGet(hWndDlg))) + { + SendSMSWindowAsSentSet(hWndDlg); + SendSMSWindowHItemSendSet(hWndDlg,SendSMSWindowNextHItemGet(hWndDlg,SendSMSWindowHItemSendGet(hWndDlg))); + SendSMSWindowNext(hWndDlg); + }else{ + SendSMSWindowRemove(hWndDlg); + } + }else{ + if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszData,dwDataSize,"yes",3)==CSTR_EQUAL || CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszData,dwDataSize,"smtp",4)==CSTR_EQUAL) + { + char szSource[MAX_PATH],szMessageID[MAX_PATH]; + + if (DB_SMS_GetByte(NULL,"ShowACK",SMS_DEFAULT_SHOWACK)) + { + HWND hwndAccepted=CreateDialog(ssSMSSettings.hInstance,MAKEINTRESOURCE(IDD_SENDSMSACCEPT),hWndDlg,SMSAcceptedDlgProc); + if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpszData,dwDataSize,"yes",3)==CSTR_EQUAL) + { + GetXMLFieldExBuff(lpszXML,dwXMLSize,szSource,sizeof(szSource),NULL,"sms_response","source",NULL); + GetXMLFieldExBuff(lpszXML,dwXMLSize,szMessageID,sizeof(szMessageID),NULL,"sms_response","message_id",NULL); + }else{ + SET_DLG_ITEM_TEXTW(hwndAccepted,IDC_ST_SOURCE,TranslateW(L"From:")); + SET_DLG_ITEM_TEXTW(hwndAccepted,IDC_ST_MESSAGEID,TranslateW(L"To:")); + GetXMLFieldExBuff(lpszXML,dwXMLSize,szSource,sizeof(szSource),NULL,"sms_response","from",NULL); + GetXMLFieldExBuff(lpszXML,dwXMLSize,szMessageID,sizeof(szMessageID),NULL,"sms_response","to",NULL); + } + SET_DLG_ITEM_TEXTA(hwndAccepted,IDC_NETWORK,szNetwork); + SET_DLG_ITEM_TEXTA(hwndAccepted,IDC_SOURCE,szSource); + SET_DLG_ITEM_TEXTA(hwndAccepted,IDC_MESSAGEID,szMessageID); + }else{ + SendSMSWindowRemove(hWndDlg); + } + }else{ + SendSMSWindowRemove(hWndDlg); + } + } + } + } + } + } +return(0); +} + +//Handles new SMS messages added to the database +int handleNewMessage(WPARAM wParam,LPARAM lParam) +{ + CHAR szServiceFunction[MAX_PATH],*pszServiceFunctionName; + WCHAR szToolTip[MAX_PATH]; + HANDLE hContact=(HANDLE)wParam,hDbEvent=(HANDLE)lParam; + CLISTEVENT cle={0}; + DBEVENTINFO dbei={0}; + + dbei.cbSize=sizeof(dbei); + if ((dbei.cbBlob=CallService(MS_DB_EVENT_GETBLOBSIZE,lParam,0))!=-1) + { + dbei.pBlob=(PBYTE)MEMALLOC(dbei.cbBlob); + if (dbei.pBlob) + { + CopyMemory(szServiceFunction,PROTOCOL_NAMEA,PROTOCOL_NAME_SIZE); + pszServiceFunctionName=szServiceFunction+PROTOCOL_NAME_LEN; + + if (CallService(MS_DB_EVENT_GET,lParam,(LPARAM)&dbei)==0) + if ((dbei.flags&DBEF_SENT)==0) + if (dbei.eventType==ICQEVENTTYPE_SMS) + { + if (dbei.cbBlob>MIN_SMS_DBEVENT_LEN) + { + SkinPlaySound("RecvSMSMsg"); + if (DB_SMS_GetByte(NULL,"AutoPopup",0)) + { + if (RecvSMSWindowAdd(hContact,ICQEVENTTYPE_SMS,NULL,0,(LPSTR)dbei.pBlob,dbei.cbBlob)) + { + CallService(MS_DB_EVENT_MARKREAD,(WPARAM)hContact,(LPARAM)&dbei); + } + }else{ + CopyMemory(pszServiceFunctionName,SMS_READ,sizeof(SMS_READ)); + + cle.cbSize=sizeof(cle); + cle.flags=CLEF_UNICODE; + cle.hContact=hContact; + cle.hDbEvent=hDbEvent; + cle.hIcon=LoadSkinnedIcon(SKINICON_OTHER_SMS); + cle.pszService=szServiceFunction; + mir_sntprintf(szToolTip,SIZEOF(szToolTip),TranslateW(L"SMS Message from %s"),GetContactNameW(hContact)); + cle.ptszTooltip=szToolTip; + CallService(MS_CLIST_ADDEVENT,0,(LPARAM)&cle); + } + } + }else + if (dbei.eventType==ICQEVENTTYPE_SMSCONFIRMATION) + { + SkinPlaySound("RecvSMSConfirmation"); + if (DB_SMS_GetByte(NULL,"AutoPopup",0)) + { + if (RecvSMSWindowAdd(hContact,ICQEVENTTYPE_SMSCONFIRMATION,NULL,0,(LPSTR)dbei.pBlob,dbei.cbBlob)) + { + CallService(MS_DB_EVENT_DELETE,(WPARAM)hContact,(LPARAM)&dbei); + } + }else{ + UINT iIcon; + + if (GetDataFromMessage((LPSTR)dbei.pBlob,dbei.cbBlob,NULL,NULL,0,NULL,&iIcon)) + { + CopyMemory(pszServiceFunctionName,SMS_READ_ACK,sizeof(SMS_READ_ACK)); + + cle.cbSize=sizeof(cle); + cle.flags=(CLEF_UNICODE); + cle.hContact=hContact; + cle.hDbEvent=hDbEvent; + cle.hIcon=(HICON)LoadImage(ssSMSSettings.hInstance,MAKEINTRESOURCE(iIcon),IMAGE_ICON,0,0,LR_SHARED); + cle.pszService=szServiceFunction; + mir_sntprintf(szToolTip,SIZEOF(szToolTip),TranslateW(L"SMS Confirmation from %s"),GetContactNameW(hContact)); + cle.ptszTooltip=szToolTip; + CallService(MS_CLIST_ADDEVENT,0,(LPARAM)&cle); + } + } + } + MEMFREE(dbei.pBlob); + } + } +return(0); +} + + diff --git a/plugins/!NotAdopted/SMS/recvdlg.cpp b/plugins/!NotAdopted/SMS/recvdlg.cpp new file mode 100644 index 0000000000..ec3998edfc --- /dev/null +++ b/plugins/!NotAdopted/SMS/recvdlg.cpp @@ -0,0 +1,269 @@ +/* +Miranda-IM SMS Plugin +Copyright (C) 2001-2 Richard Hughes +Copyright (C) 2007-2009 Rozhuk Ivan + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +--------------------------------------------------------------------------- + +This was the original words. +This plugin was modified by Ariel Shulman (NuKe007). +For any comments, problems, etc. contact me at Miranda-IM forums or E-Mail or ICQ. +All the information needed you can find at www.nuke007.tk +Enjoy the code and use it smartly! +*/ + +#include "main.h" +#include "recvdlg.h" + +//Defnition needed to the SMS window list +typedef struct +{ + LIST_MT_ITEM lmtListMTItem; + HWND hWnd; + HBRUSH hBkgBrush; + HANDLE hContact; +} RECV_SMS_WINDOW_DATA; + + + +BOOL CALLBACK RecvSmsDlgProc (HWND hWndDlg,UINT message,WPARAM wParam,LPARAM lParam); +#define GET_WINDOW_DATA(hWndDlg) ((RECV_SMS_WINDOW_DATA*)GetWindowLongPtr(hWndDlg,GWL_USERDATA)) + + + + + +DWORD RecvSMSWindowInitialize() +{ + DWORD dwRetErrorCode; + + dwRetErrorCode=ListMTInitialize(&ssSMSSettings.lmtRecvSMSWindowsListMT,0); +return(dwRetErrorCode); +} + +//This function destroy all SMS receive windows +void RecvSMSWindowDestroy() +{ + RECV_SMS_WINDOW_DATA *prswdWindowData; + + ListMTLock(&ssSMSSettings.lmtRecvSMSWindowsListMT); + while(ListMTItemGetFirst(&ssSMSSettings.lmtRecvSMSWindowsListMT,NULL,(LPVOID*)&prswdWindowData)==NO_ERROR) + {// цикл + RecvSMSWindowRemove(prswdWindowData->hWnd); + } + ListMTUnLock(&ssSMSSettings.lmtRecvSMSWindowsListMT); + ListMTDestroy(&ssSMSSettings.lmtRecvSMSWindowsListMT); +} + + +BOOL CALLBACK RecvSmsDlgProc(HWND hWndDlg,UINT message,WPARAM wParam,LPARAM lParam) +{ + RECV_SMS_WINDOW_DATA *prswdWindowData=GET_WINDOW_DATA(hWndDlg); + + switch(message){ + case WM_INITDIALOG: + TranslateDialogDefault(hWndDlg); //Translate intially - bid + + prswdWindowData=(RECV_SMS_WINDOW_DATA*)lParam; + SetWindowLongPtr(hWndDlg,GWL_USERDATA,(LONG_PTR)lParam); + + { + WNDPROC OldEditWndProc; + + OldEditWndProc=(WNDPROC)SetWindowLongPtr(GetDlgItem(hWndDlg,IDC_MESSAGE),GWL_WNDPROC,(LONG_PTR)MessageSubclassProc); + SetWindowLongPtr(GetDlgItem(hWndDlg,IDC_MESSAGE),GWL_USERDATA,(LONG_PTR)OldEditWndProc); + } + + { + HFONT hFont; + LOGFONT lf; + hFont=(HFONT)SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,WM_GETFONT,0,0); + if (hFont && hFont!=(HFONT)SEND_DLG_ITEM_MESSAGE(hWndDlg,IDOK,WM_GETFONT,0,0)) DeleteObject(hFont); + LoadMsgDlgFont(MSGFONTID_YOURMSG,&lf,NULL); + hFont=CreateFontIndirect(&lf); + SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,WM_SETFONT,(WPARAM)hFont,MAKELPARAM(TRUE,0)); + + COLORREF colour=DBGetContactSettingDword(NULL,SRMMMOD,SRMSGSET_BKGCOLOUR,SRMSGDEFSET_BKGCOLOUR); + prswdWindowData->hBkgBrush=CreateSolidBrush(colour); + } + + if (Utils_RestoreWindowPosition(hWndDlg,(DB_SMS_GetByte(NULL,"SavePerContact",0)? prswdWindowData->hContact:NULL),PROTOCOL_NAMEA,"recv")) + {// def pos + SetWindowPos(hWndDlg,0,200,200,400,350,SWP_NOZORDER); + } + InvalidateRect(GetDlgItem(hWndDlg,IDC_MESSAGE),NULL,FALSE); + break; + case WM_CTLCOLORSTATIC: + if ((HWND)lParam==GetDlgItem(hWndDlg,IDC_MESSAGE)) + { + COLORREF colour; + + LoadMsgDlgFont(MSGFONTID_YOURMSG,NULL,&colour); + SetTextColor((HDC)wParam,colour); + SetBkColor((HDC)wParam,DBGetContactSettingDword(NULL,SRMMMOD,SRMSGSET_BKGCOLOUR,SRMSGDEFSET_BKGCOLOUR)); + return((BOOL)prswdWindowData->hBkgBrush); + } + break; + case WM_GETMINMAXINFO: + ((LPMINMAXINFO)lParam)->ptMinTrackSize.x=300; + ((LPMINMAXINFO)lParam)->ptMinTrackSize.y=230; + break; + case WM_SIZE: + { + int cx,cy; + RECT rcWin; + + GetWindowRect(hWndDlg,&rcWin); + cx = rcWin.right - rcWin.left; + cy = rcWin.bottom - rcWin.top; + SetWindowPos(GetDlgItem(hWndDlg,IDC_MESSAGE),0,0,0,cx - 14,cy - 112,SWP_NOZORDER|SWP_NOMOVE); + SetWindowPos(GetDlgItem(hWndDlg,IDC_NAME),0,0,0,(cx*35)/100,20,SWP_NOZORDER|SWP_NOMOVE); + SetWindowPos(GetDlgItem(hWndDlg,IDC_NUMBER),0,cx - (cx*35)/100 - 11,5,(cx*35)/100,20,SWP_NOZORDER); + SetWindowPos(GetDlgItem(hWndDlg,IDC_ST_NUMBER),0,cx - (cx*35)/100 - 58,5,40,20,SWP_NOZORDER); + SetWindowPos(GetDlgItem(hWndDlg,IDC_READNEXT),0,cx - 87, cy - 60,80,25,SWP_NOZORDER); + SetWindowPos(GetDlgItem(hWndDlg,IDOK),0,cx/2 - 87,cy - 60,80,25,SWP_NOZORDER); + SetWindowPos(GetDlgItem(hWndDlg,IDCANCEL),0,cx/2 + 7,cy - 60,80,25,SWP_NOZORDER); + + RedrawWindow(hWndDlg,NULL,NULL,RDW_FRAME|RDW_INVALIDATE); + } + break; + case WM_COMMAND: + switch(LOWORD(wParam)){ + case IDOK: + { + WCHAR wszPhone[MAX_PHONE_LEN]; + HWND hwndSendSms; + HANDLE hContact; + + hContact=HContactFromPhone(wszPhone,GET_DLG_ITEM_TEXTW(hWndDlg,IDC_NUMBER,wszPhone,SIZEOF(wszPhone))); + hwndSendSms=SendSMSWindowIsOtherInstanceHContact(hContact); + if (hwndSendSms) + { + SetFocus(hwndSendSms); + }else{ + hwndSendSms=SendSMSWindowAdd(prswdWindowData->hContact); + SET_DLG_ITEM_TEXTW(hwndSendSms,IDC_ADDRESS,wszPhone); + } + } + case IDCANCEL: + RecvSMSWindowRemove(hWndDlg); + break; + } + break; + case WM_CLOSE: + DeleteObject(prswdWindowData->hBkgBrush); + RecvSMSWindowRemove(hWndDlg); + break; + } +return(FALSE); +} + +//SMS Receive window list functions + +//This function create a new SMS receive window, and insert it to the list. +//The function gets void and return the window HWND +HWND RecvSMSWindowAdd(HANDLE hContact,DWORD dwEventType,LPWSTR lpwszPhone,SIZE_T dwPhoneSize,LPSTR lpszMessage,SIZE_T dwMessageSize) +{ + HWND hRet=NULL; + + if ((dwPhoneSize+dwMessageSize)>MIN_SMS_DBEVENT_LEN) + { + LPWSTR lpwszMessage; + + lpwszMessage=(LPWSTR)MEMALLOC(((dwMessageSize+MAX_PATH)*sizeof(WCHAR))); + if (lpwszMessage) + { + RECV_SMS_WINDOW_DATA *prswdWindowData; + + prswdWindowData=(RECV_SMS_WINDOW_DATA*)MEMALLOC(sizeof(RECV_SMS_WINDOW_DATA)); + if (prswdWindowData) + { + prswdWindowData->hContact=hContact; + prswdWindowData->hWnd=CreateDialogParam(ssSMSSettings.hInstance,MAKEINTRESOURCE(IDD_RECVSMS),NULL,RecvSmsDlgProc,(LPARAM)prswdWindowData); + if (prswdWindowData->hWnd) + { + HICON hIcon; + WCHAR wszTitle[MAX_PATH]={0},wszPhoneLocal[MAX_PHONE_LEN]={0}; + UINT iIcon; + LPWSTR lpwszContactDisplayName,lpwszTitlepart; + + ListMTLock(&ssSMSSettings.lmtRecvSMSWindowsListMT); + ListMTItemAdd(&ssSMSSettings.lmtRecvSMSWindowsListMT,&prswdWindowData->lmtListMTItem,prswdWindowData); + ListMTUnLock(&ssSMSSettings.lmtRecvSMSWindowsListMT); + + switch(dwEventType){ + case ICQEVENTTYPE_SMS: + lpwszTitlepart=TranslateW(L"Received SMS"); + hIcon=LoadSkinnedIcon(SKINICON_OTHER_SMS); + break; + case ICQEVENTTYPE_SMSCONFIRMATION: + lpwszTitlepart=TranslateW(L"Received SMS Confirmation"); + GetDataFromMessage(lpszMessage,dwMessageSize,NULL,NULL,0,NULL,&iIcon); + hIcon=(HICON)LoadImage(ssSMSSettings.hInstance,MAKEINTRESOURCE(iIcon),IMAGE_ICON,0,0,LR_SHARED); + break; + default: + lpwszTitlepart=L"Unknown event type"; + } + + wszPhoneLocal[0]='+'; + if (dwPhoneSize) + { + dwPhoneSize=CopyNumberW((wszPhoneLocal+1),lpwszPhone,dwPhoneSize); + }else{ + GetDataFromMessage(lpszMessage,dwMessageSize,NULL,(wszPhoneLocal+1),(SIZEOF(wszPhoneLocal)-1),&dwPhoneSize,NULL); + dwPhoneSize++; + } + + lpwszContactDisplayName=GetContactNameW(hContact); + mir_sntprintf(wszTitle,SIZEOF(wszTitle),L"%s - %s",lpwszContactDisplayName,lpwszTitlepart); + MultiByteToWideChar(CP_UTF8,0,lpszMessage,dwMessageSize,lpwszMessage,(dwMessageSize+MAX_PATH)); + + SendMessageW(prswdWindowData->hWnd,WM_SETTEXT,NULL,(LPARAM)wszTitle); + SET_DLG_ITEM_TEXTW(prswdWindowData->hWnd,IDC_NAME,lpwszContactDisplayName); + SET_DLG_ITEM_TEXTW(prswdWindowData->hWnd,IDC_NUMBER,wszPhoneLocal); + SET_DLG_ITEM_TEXTW(prswdWindowData->hWnd,IDC_MESSAGE,lpwszMessage); + SendMessage(prswdWindowData->hWnd,WM_SETICON,ICON_BIG,(LPARAM)hIcon); + + SetFocus(GetDlgItem(prswdWindowData->hWnd,IDC_MESSAGE)); + hRet=prswdWindowData->hWnd; + }else{ + MEMFREE(prswdWindowData); + } + } + MEMFREE(lpwszMessage); + } + } +return(hRet); +} + +//This function close the SMS receive window that given, and remove it from the list. +//The function gets the HWND of the window that should be removed and return void +void RecvSMSWindowRemove(HWND hWndDlg) +{ + RECV_SMS_WINDOW_DATA *prswdWindowData=GET_WINDOW_DATA(hWndDlg); + + if (prswdWindowData) + { + Utils_SaveWindowPosition(hWndDlg,(DB_SMS_GetByte(NULL,"SavePerContact",0)? prswdWindowData->hContact:NULL),PROTOCOL_NAMEA,"recv"); + + ListMTLock(&ssSMSSettings.lmtRecvSMSWindowsListMT); + ListMTItemDelete(&ssSMSSettings.lmtRecvSMSWindowsListMT,&prswdWindowData->lmtListMTItem); + ListMTUnLock(&ssSMSSettings.lmtRecvSMSWindowsListMT); + MEMFREE(prswdWindowData); + } + DestroyWindow(hWndDlg); +} + diff --git a/plugins/!NotAdopted/SMS/recvdlg.h b/plugins/!NotAdopted/SMS/recvdlg.h new file mode 100644 index 0000000000..a34231b255 --- /dev/null +++ b/plugins/!NotAdopted/SMS/recvdlg.h @@ -0,0 +1,18 @@ +#if !defined(AFX_SMS_RECVDLG_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_) +#define AFX_SMS_RECVDLG_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_ + + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + + +DWORD RecvSMSWindowInitialize (); +void RecvSMSWindowDestroy (); +HWND RecvSMSWindowAdd (HANDLE hContact,DWORD dwEventType,LPWSTR lpwszPhone,SIZE_T dwPhoneSize,LPSTR lpszMessage,SIZE_T dwMessageSize); +void RecvSMSWindowRemove (HWND hWndDlg); + + + +#endif // !defined(AFX_SMS_RECVDLG_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_) diff --git a/plugins/!NotAdopted/SMS/res/SMSNOTSENT.ico b/plugins/!NotAdopted/SMS/res/SMSNOTSENT.ico new file mode 100644 index 0000000000..edc59a9d00 Binary files /dev/null and b/plugins/!NotAdopted/SMS/res/SMSNOTSENT.ico differ diff --git a/plugins/!NotAdopted/SMS/res/SMSSENT.ico b/plugins/!NotAdopted/SMS/res/SMSSENT.ico new file mode 100644 index 0000000000..da61e1c52c Binary files /dev/null and b/plugins/!NotAdopted/SMS/res/SMSSENT.ico differ diff --git a/plugins/!NotAdopted/SMS/res/halftick.ico b/plugins/!NotAdopted/SMS/res/halftick.ico new file mode 100644 index 0000000000..a7fcd94b7a Binary files /dev/null and b/plugins/!NotAdopted/SMS/res/halftick.ico differ diff --git a/plugins/!NotAdopted/SMS/resource.h b/plugins/!NotAdopted/SMS/resource.h new file mode 100644 index 0000000000..3a7e98455d --- /dev/null +++ b/plugins/!NotAdopted/SMS/resource.h @@ -0,0 +1,70 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.rc +// +#define IDD_SENDSMS 102 +#define IDR_CONTEXT 104 +#define IDD_RECVSMS 109 +#define IDI_SMSNOTSENT 110 +#define IDI_SMSSENT 111 +#define IDD_SMSTIMEDOUT 112 +#define IDD_SENDSMSTIMEDOUT 113 +#define IDI_HALFTICK 119 +#define IDD_SENDSMSACCEPT 120 +#define IDD_OPT_SMSPLUGIN 234 +#define IDC_ADDRESS 1000 +#define IDC_EDIT 1001 +#define IDC_ADDRESS2 1001 +#define IDC_ACCOUNTS 1001 +#define IDC_MESSAGE 1002 +#define IDC_STATUS 1003 +#define IDC_NUMBER 1004 +#define IDC_NAME 1005 +#define IDC_ADD 1006 +#define IDC_DELETE 1008 +#define IDC_SIGNATURE 1008 +#define IDC_LIST 1009 +#define IDC_COUNT 1010 +#define IDC_TEXT 1011 +#define IDC_MSGTYPE 1012 +#define IDC_MSGTIME 1013 +#define IDC_BEGIN 1017 +#define IDC_END 1018 +#define IDC_SAVENUMBER 1020 +#define IDC_MULTIPLE 1025 +#define IDC_ADDNUMBER 1029 +#define IDC_ST_CHARS 1033 +#define IDC_ST_ENTERMESSAGE 1034 +#define IDC_ST_TO 1035 +#define IDC_ST_ADDRESS 1036 +#define IDC_ST_NUMBER 1037 +#define IDC_NUMBERSLIST 1038 +#define IDC_MESSAGEID 1039 +#define IDC_SOURCE 1040 +#define IDC_NETWORK 1041 +#define IDC_SHOWACK 1044 +#define IDC_NOSHOWACK 1045 +#define IDC_AUTOPOP 1045 +#define IDC_READNEXT 1046 +#define IDC_SAVEWINPOS 1046 +#define IDC_USESIGNATURE 1047 +#define IDC_SIGNGROUP 1048 +#define IDC_ST_MESSAGEID 1049 +#define IDC_ST_NETWORK 1050 +#define IDC_ST_SOURCE 1051 +#define IDC_HISTORY 1080 +#define IDM_VIEWMSG 40001 +#define IDM_VIEWACK 40002 +#define IDM_VIEWRCPT 40003 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 121 +#define _APS_NEXT_COMMAND_VALUE 40004 +#define _APS_NEXT_CONTROL_VALUE 1053 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/!NotAdopted/SMS/resource.rc b/plugins/!NotAdopted/SMS/resource.rc new file mode 100644 index 0000000000..50c92a2c70 --- /dev/null +++ b/plugins/!NotAdopted/SMS/resource.rc @@ -0,0 +1,291 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1251) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,2,5,3 + PRODUCTVERSION 0,2,5,3 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "Comments", "Send and receive SMS messages" + VALUE "CompanyName", " " + VALUE "FileDescription", "Miranda SMS plugin" + VALUE "FileVersion", "0.2.5.3" + VALUE "InternalName", "sms plugin" + VALUE "LegalCopyright", "Copyright © 2002-3 Ariel Shulman (Original by Richard Hughes), 2007-2009 Rozhuk Ivan (Ivan 83)" + VALUE "OriginalFilename", "sms.dll" + VALUE "ProductName", "Miranda IM" + VALUE "ProductVersion", "0.2.5.3" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_SMSNOTSENT ICON "res\\SMSNOTSENT.ico" +IDI_SMSSENT ICON "res\\SMSSENT.ico" +IDI_HALFTICK ICON "res\\halftick.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_RECVSMS DIALOGEX 0, 0, 278, 126 +STYLE DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "Received SMS" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + EDITTEXT IDC_MESSAGE,3,29,271,76,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | ES_WANTRETURN | WS_VSCROLL,WS_EX_CLIENTEDGE + DEFPUSHBUTTON "&Reply",IDOK,83,108,50,14 + PUSHBUTTON "&Close",IDCANCEL,143,108,50,14 + PUSHBUTTON "Read Next",IDC_READNEXT,217,105,57,17,NOT WS_VISIBLE + LTEXT "From:",IDC_STATIC,3,6,19,11 + LTEXT "Message received:",IDC_STATIC,3,20,108,8 + LTEXT "",IDC_NAME,24,5,105,11,SS_SUNKEN + LTEXT "Number:",IDC_ST_NUMBER,133,6,28,11 + LTEXT "",IDC_NUMBER,164,5,110,11,SS_SUNKEN +END + +IDD_SENDSMS DIALOGEX 0, 0, 394, 145 +STYLE DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "Send SMS" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "To:",IDC_ST_TO,2,5,18,8 + COMBOBOX IDC_NAME,20,3,111,12,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP + RTEXT "Number:",IDC_ST_ADDRESS,134,5,30,8 + COMBOBOX IDC_ADDRESS,164,3,113,62,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Add number to list",IDC_ADDNUMBER,284,3,108,14 + CONTROL "Tree1",IDC_NUMBERSLIST,"SysTreeView32",TVS_HASBUTTONS | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | TVS_NOTOOLTIPS | TVS_TRACKSELECT | TVS_FULLROWSELECT | WS_BORDER | WS_HSCROLL | WS_TABSTOP,284,17,108,109 + PUSHBUTTON "&H",IDC_HISTORY,2,17,15,11,BS_ICON + COMBOBOX IDC_ACCOUNTS,20,18,72,83,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Save number",IDC_SAVENUMBER,133,17,46,11 + PUSHBUTTON "Multiple >>",IDC_MULTIPLE,232,17,45,11 + LTEXT "Enter message:",IDC_ST_ENTERMESSAGE,2,32,76,9 + RTEXT "Chars:",IDC_ST_CHARS,207,32,34,8 + RTEXT "%d/160",IDC_COUNT,242,32,35,8,SS_NOPREFIX | SS_SUNKEN + EDITTEXT IDC_MESSAGE,2,42,275,84,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL,WS_EX_CLIENTEDGE + DEFPUSHBUTTON "&Send",IDOK,73,130,50,14 + PUSHBUTTON "&Close",IDCANCEL,143,130,50,14 +END + +IDD_SENDSMSTIMEDOUT DIALOG 0, 0, 211, 94 +STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "SMS Message Didn't Send" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "&Try again",IDOK,39,73,62,16 + PUSHBUTTON "&Cancel",IDCANCEL,106,73,62,16 + LTEXT "The SMS message send timed out",IDC_STATUS,5,6,201,61 +END + +IDD_OPT_SMSPLUGIN DIALOGEX 0, 0, 255, 161 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "SMS Plugin",IDC_STATIC,6,4,244,150 + GROUPBOX "",IDC_SIGNGROUP,12,28,231,74,WS_GROUP + EDITTEXT IDC_SIGNATURE,17,40,221,44,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + CONTROL "Begining",IDC_BEGIN,"Button",BS_AUTORADIOBUTTON | WS_GROUP,115,90,65,8 + CONTROL "End",IDC_END,"Button",BS_AUTORADIOBUTTON,180,90,58,8 + LTEXT "Put signature at the:",IDC_STATIC,18,90,89,10 + CONTROL "Use Signature",IDC_USESIGNATURE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,21,226,10 + CONTROL "Show server notifications",IDC_SHOWACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,108,226,10 + CONTROL "Auto popup on new message",IDC_AUTOPOP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,120,226,10 + CONTROL "Save window position per contact",IDC_SAVEWINPOS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,132,226,10 +END + +IDD_SENDSMSACCEPT DIALOG 0, 0, 256, 90 +STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "SMS Message Sent" +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "&OK",IDOK,91,69,62,16 + LTEXT "",IDC_MESSAGEID,57,6,194,9 + LTEXT "Message ID:",IDC_ST_MESSAGEID,5,6,52,8 + LTEXT "Source:",IDC_ST_SOURCE,5,27,52,8 + LTEXT "",IDC_SOURCE,57,27,194,39 + LTEXT "Network:",IDC_ST_NETWORK,5,17,52,8 + LTEXT "",IDC_NETWORK,57,17,194,10 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_RECVSMS, DIALOG + BEGIN + LEFTMARGIN, 3 + RIGHTMARGIN, 274 + TOPMARGIN, 5 + BOTTOMMARGIN, 122 + HORZGUIDE, 16 + HORZGUIDE, 29 + HORZGUIDE, 105 + END + + IDD_SENDSMS, DIALOG + BEGIN + LEFTMARGIN, 2 + RIGHTMARGIN, 392 + VERTGUIDE, 164 + VERTGUIDE, 277 + VERTGUIDE, 284 + TOPMARGIN, 3 + BOTTOMMARGIN, 144 + HORZGUIDE, 17 + HORZGUIDE, 28 + HORZGUIDE, 32 + HORZGUIDE, 51 + HORZGUIDE, 111 + HORZGUIDE, 126 + HORZGUIDE, 130 + END + + IDD_SENDSMSTIMEDOUT, DIALOG + BEGIN + LEFTMARGIN, 5 + RIGHTMARGIN, 206 + TOPMARGIN, 6 + BOTTOMMARGIN, 89 + END + + IDD_OPT_SMSPLUGIN, DIALOG + BEGIN + RIGHTMARGIN, 250 + VERTGUIDE, 6 + VERTGUIDE, 12 + VERTGUIDE, 18 + VERTGUIDE, 115 + VERTGUIDE, 180 + VERTGUIDE, 238 + VERTGUIDE, 243 + VERTGUIDE, 248 + BOTTOMMARGIN, 150 + HORZGUIDE, 84 + HORZGUIDE, 90 + HORZGUIDE, 95 + HORZGUIDE, 107 + HORZGUIDE, 116 + END + + IDD_SENDSMSACCEPT, DIALOG + BEGIN + LEFTMARGIN, 5 + RIGHTMARGIN, 251 + VERTGUIDE, 57 + TOPMARGIN, 6 + BOTTOMMARGIN, 85 + HORZGUIDE, 14 + HORZGUIDE, 17 + HORZGUIDE, 27 + END +END +#endif // APSTUDIO_INVOKED + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.K.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include \r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.K.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/!NotAdopted/SMS/send.cpp b/plugins/!NotAdopted/SMS/send.cpp new file mode 100644 index 0000000000..fdfc80ffd8 --- /dev/null +++ b/plugins/!NotAdopted/SMS/send.cpp @@ -0,0 +1,88 @@ +/* +Miranda-IM SMS Plugin +Copyright (C) 2001-2 Richard Hughes +Copyright (C) 2007-2009 Rozhuk Ivan + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +--------------------------------------------------------------------------- + +This was the original words. +This plugin was modified by Ariel Shulman (NuKe007). +For any comments, problems, etc. contact me at Miranda-IM forums or E-Mail or ICQ. +All the information needed you can find at www.nuke007.tk +Enjoy the code and use it smartly! +*/ + +#include "main.h" + + + +//This function gets HWND of the window, the number, and the message. +void StartSmsSend(HWND hWndDlg,SIZE_T dwModuleIndex,LPWSTR lpwszPhone,SIZE_T dwPhoneSize,LPWSTR lpwszMessage,SIZE_T dwMessageSize) +{ + if (ssSMSSettings.ppaSMSAccounts && dwModuleIndex!=-1 && dwModuleIndextimestamp=time(NULL); + pdbei->flags=(DBEF_SENT|DBEF_UTF); + pdbei->eventType=ICQEVENTTYPE_SMS; + pdbei->cbBlob=(mir_snprintf(lpszBuff,dwBuffSize,"SMS To: +%s\r\n%s",szPhone,lpszMessageUTF)+4); + pdbei->pBlob=(PBYTE)lpszBuff; + SendSMSWindowDbeiSet(hWndDlg,pdbei); + + mir_snprintf(szServiceName,sizeof(szServiceName),"%s%s",ssSMSSettings.ppaSMSAccounts[dwModuleIndex]->szModuleName,MS_ICQ_SENDSMS); + if (ServiceExists(szServiceName)) + { + WideCharToMultiByte(CP_UTF8,0,lpwszMessageXMLEncoded,dwMessageXMLEncodedSize,lpszMessageUTF,dwMessageUTFBuffSize,NULL,NULL); + hProcess=(HANDLE)CallService(szServiceName,(WPARAM)szPhone,(LPARAM)lpszMessageUTF); + SendSMSWindowHProcessSet(hWndDlg,hProcess); + }else{ + MEMFREE(pdbei); + } + } + MEMFREE(lpszMessageUTF); + } + MEMFREE(lpwszMessageXMLEncoded); + } + } +} + + + diff --git a/plugins/!NotAdopted/SMS/senddlg.cpp b/plugins/!NotAdopted/SMS/senddlg.cpp new file mode 100644 index 0000000000..dbecd20ec6 --- /dev/null +++ b/plugins/!NotAdopted/SMS/senddlg.cpp @@ -0,0 +1,1177 @@ +/* +Miranda-IM SMS Plugin +Copyright (C) 2001-2 Richard Hughes +Copyright (C) 2007-2009 Rozhuk Ivan + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +--------------------------------------------------------------------------- + +This was the original words. +This plugin was modified by Ariel Shulman (NuKe007). +For any comments, problems, etc. contact me at Miranda-IM forums or E-Mail or ICQ. +All the information needed you can find at www.nuke007.tk +Enjoy the code and use it smartly! +*/ + +#include "main.h" + + + +#define TIMERID_MSGSEND 0 +#define TIMEDOUT_CANCEL 0 +#define TIMEDOUT_RETRY 1 +#define DM_TIMEOUTDECIDED (WM_USER+18) + + +//Defnition needed to the SMS window list +typedef struct +{ + LIST_MT_ITEM lmtListMTItem; + HWND hWnd; + HBRUSH hBkgBrush; + HANDLE hProcess; + HANDLE hContact; + HANDLE hMyContact; + HTREEITEM hItemSend; + BOOL bMultiple; + SIZE_T dwContactsListCount; + HANDLE *phContactsList; + DBEVENTINFO *pdbei; +} SEND_SMS_WINDOW_DATA; + + + +void AddContactPhonesToCombo (HWND hWnd,HANDLE hContact); +void SendSMSWindowFillTreeView (HWND hWnd); +SIZE_T GetSMSMessageLenMax (HWND hWndDlg); + +#define GET_WINDOW_DATA(hWndDlg) ((SEND_SMS_WINDOW_DATA*)GetWindowLongPtr(hWndDlg,GWL_USERDATA)) + + + + + +DWORD SendSMSWindowInitialize() +{ + DWORD dwRetErrorCode; + + dwRetErrorCode=ListMTInitialize(&ssSMSSettings.lmtSendSMSWindowsListMT,0); +return(dwRetErrorCode); +} + +void SendSMSWindowDestroy() +{ + SEND_SMS_WINDOW_DATA *psswdWindowData; + + ListMTLock(&ssSMSSettings.lmtSendSMSWindowsListMT); + while(ListMTItemGetFirst(&ssSMSSettings.lmtSendSMSWindowsListMT,NULL,(LPVOID*)&psswdWindowData)==NO_ERROR) + {// цикл + SendSMSWindowRemove(psswdWindowData->hWnd); + } + ListMTUnLock(&ssSMSSettings.lmtSendSMSWindowsListMT); + ListMTDestroy(&ssSMSSettings.lmtSendSMSWindowsListMT); +} + + + +BOOL CALLBACK SendSmsDlgProc(HWND hWndDlg,UINT message,WPARAM wParam,LPARAM lParam) +{ + SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); + + switch(message){ + case WM_INITDIALOG: + TranslateDialogDefault(hWndDlg); //Translate intially - bid + AddWinHandle(GetDlgItem(hWndDlg,IDC_MESSAGE)); + + psswdWindowData=(SEND_SMS_WINDOW_DATA*)lParam; + SetWindowLongPtr(hWndDlg,GWL_USERDATA,(LONG_PTR)lParam); + + { + WNDPROC OldEditWndProc; + + OldEditWndProc=(WNDPROC)SetWindowLongPtr(GetDlgItem(hWndDlg,IDC_MESSAGE),GWL_WNDPROC,(LONG_PTR)MessageSubclassProc); + SetWindowLongPtr(GetDlgItem(hWndDlg,IDC_MESSAGE),GWL_USERDATA,(LONG_PTR)OldEditWndProc); + } + + SendMessage(hWndDlg,WM_SETICON,ICON_BIG,(LPARAM)LoadSkinnedIcon(SKINICON_OTHER_SMS)); + SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_HISTORY,BM_SETIMAGE,IMAGE_ICON,(LPARAM)LoadSkinnedIcon(SKINICON_OTHER_HISTORY)); + { + HICON hIcon; + HIMAGELIST hIml=ImageList_Create(16,16,ILC_COLOR32|ILC_MASK,0,30); + TreeView_SetImageList(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),hIml,TVSIL_NORMAL); + hIcon=LoadSkinnedIcon(SKINICON_OTHER_NOTICK); ImageList_AddIcon(hIml,hIcon); + hIcon=LoadSkinnedIcon(SKINICON_OTHER_TICK); ImageList_AddIcon(hIml,hIcon); + hIcon=(HICON)LoadImage(ssSMSSettings.hInstance,MAKEINTRESOURCE(IDI_HALFTICK),IMAGE_ICON,0,0,LR_SHARED); ImageList_AddIcon(hIml,hIcon); + } + { + HFONT hFont; + LOGFONT lf; + hFont=(HFONT)SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,WM_GETFONT,0,0); + if (hFont && hFont!=(HFONT)SEND_DLG_ITEM_MESSAGE(hWndDlg,IDOK,WM_GETFONT,0,0)) DeleteObject(hFont); + LoadMsgDlgFont(MSGFONTID_MESSAGEAREA,&lf,NULL); + hFont=CreateFontIndirect(&lf); + SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,WM_SETFONT,(WPARAM)hFont,MAKELPARAM(TRUE,0)); + + COLORREF colour=DBGetContactSettingDword(NULL,SRMMMOD,SRMSGSET_INPBKGCOLOUR,SRMSGDEFSET_BKGCOLOUR); + psswdWindowData->hBkgBrush=CreateSolidBrush(colour); + } + { + TOOLINFO ti; + HWND hwndToolTips; + hwndToolTips=CreateWindowEx(WS_EX_TOPMOST,TOOLTIPS_CLASS,TEXT(""),WS_POPUP,0,0,0,0,NULL,NULL,GetModuleHandle(NULL),NULL); + ZeroMemory(&ti,sizeof(ti)); + ti.cbSize=sizeof(ti); + ti.uFlags=TTF_IDISHWND|TTF_SUBCLASS; + ti.uId=(UINT)GetDlgItem(hWndDlg,IDC_HISTORY); + ti.lpszText=TranslateW(L"View User's History"); + SendMessage(hwndToolTips,TTM_ADDTOOL,0,(LPARAM)&ti); + ti.uId=(UINT)GetDlgItem(hWndDlg,IDC_ADDNUMBER); + ti.lpszText=TranslateW(L"Add Number To The Multiple List"); + SendMessage(hwndToolTips,TTM_ADDTOOL,0,(LPARAM)&ti); + ti.uId=(UINT)GetDlgItem(hWndDlg,IDC_SAVENUMBER); + ti.lpszText=TranslateW(L"Save Number To The User's Details Phonebook"); + SendMessage(hwndToolTips,TTM_ADDTOOL,0,(LPARAM)&ti); + ti.uId=(UINT)GetDlgItem(hWndDlg,IDC_MULTIPLE); + ti.lpszText=TranslateW(L"Show/Hide Multiple List"); + SendMessage(hwndToolTips,TTM_ADDTOOL,0,(LPARAM)&ti); + ti.uId=(UINT)GetDlgItem(hWndDlg,IDC_COUNT); + ti.lpszText=TranslateW(L"Shows How Much Chars You've Typed"); + SendMessage(hwndToolTips,TTM_ADDTOOL,0,(LPARAM)&ti); + } + { + RECT rcWin,rcList; + GetWindowRect(hWndDlg,&rcWin); + GetWindowRect(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),&rcList); + SetWindowPos(hWndDlg,0,rcWin.left,rcWin.top,rcWin.right-rcWin.left - (rcList.right-rcList.left) - 10,rcWin.bottom - rcWin.top,SWP_NOZORDER|SWP_NOMOVE); + } + + SendSMSWindowUpdateAccountList(hWndDlg); + + { + WCHAR wszSign[1024]; + SIZE_T dwSignLen; + + if (DB_SMS_GetByte(NULL,"UseSignature",SMS_DEFAULT_USESIGNATURE)) + if (DB_SMS_GetStaticStringW(NULL,"Signature",wszSign,SIZEOF(wszSign),&dwSignLen)) + { + SET_DLG_ITEM_TEXTW(hWndDlg,IDC_MESSAGE,wszSign); + + if (DB_SMS_GetByte(NULL,"SignaturePos",SMS_DEFAULT_SIGNATUREPOS)) SEND_DLG_ITEM_MESSAGEW(hWndDlg,IDC_MESSAGE,EM_SETSEL,dwSignLen,dwSignLen); + EnableWindow(GetDlgItem(hWndDlg,IDOK),dwSignLen); + } + + mir_sntprintf(wszSign,SIZEOF(wszSign),L"%d/%d",dwSignLen,GetSMSMessageLenMax(hWndDlg)); + SET_DLG_ITEM_TEXTW(hWndDlg,IDC_COUNT,wszSign); + } + + if (Utils_RestoreWindowPosition(hWndDlg,(DB_SMS_GetByte(NULL,"SavePerContact",0)? psswdWindowData->hMyContact:NULL),PROTOCOL_NAMEA,"send")) + {// def pos + SetWindowPos(hWndDlg,0,200,200,400,350,SWP_NOZORDER); + } + InvalidateRect(GetDlgItem(hWndDlg,IDC_MESSAGE),NULL,FALSE); + return(TRUE); + case WM_GETMINMAXINFO: + if (psswdWindowData->bMultiple) + { + ((LPMINMAXINFO)lParam)->ptMinTrackSize.x=461; + ((LPMINMAXINFO)lParam)->ptMinTrackSize.y=230; + }else{ + ((LPMINMAXINFO)lParam)->ptMinTrackSize.x=300; + ((LPMINMAXINFO)lParam)->ptMinTrackSize.y=230; + } + break; + case WM_SIZE: + { + int cx,cy; + RECT rcWin; + GetWindowRect(hWndDlg,&rcWin); + if (psswdWindowData->bMultiple) + { + cx=rcWin.right-rcWin.left-181; + cy=rcWin.bottom-rcWin.top; + }else{ + cx=rcWin.right-rcWin.left; + cy=rcWin.bottom-rcWin.top; + } + SetWindowPos(GetDlgItem(hWndDlg,IDC_MESSAGE),0,0,0,cx - 14,cy - 132,SWP_NOZORDER|SWP_NOMOVE); + SetWindowPos(GetDlgItem(hWndDlg,IDC_NAME),0,0,0,(cx*35)/100,20,SWP_NOZORDER|SWP_NOMOVE); + SetWindowPos(GetDlgItem(hWndDlg,IDC_ACCOUNTS),0,0,0,(cx*35)/100,20,SWP_NOZORDER|SWP_NOMOVE); + SetWindowPos(GetDlgItem(hWndDlg,IDC_ADDRESS),0,cx - (cx*35)/100 - 11,5,(cx*35)/100,20,SWP_NOZORDER); + SetWindowPos(GetDlgItem(hWndDlg,IDC_ST_ADDRESS),0,cx - (cx*35)/100 - 68,5,50,20,SWP_NOZORDER); + SetWindowPos(GetDlgItem(hWndDlg,IDC_MULTIPLE),0,cx - ((cx*35)/100 + 35)/2 - 11,30,((cx*35)/100 + 35)/2,20,SWP_NOZORDER); + SetWindowPos(GetDlgItem(hWndDlg,IDC_SAVENUMBER),0,cx - (cx*35)/100 - 58,30,((cx*35)/100 + 35)/2,20,SWP_NOZORDER); + SetWindowPos(GetDlgItem(hWndDlg,IDC_HISTORY),0,0,0,20,20,SWP_NOZORDER|SWP_NOMOVE); + SetWindowPos(GetDlgItem(hWndDlg,IDC_COUNT),0,cx - 61,52,50,15,SWP_NOZORDER); + SetWindowPos(GetDlgItem(hWndDlg,IDC_ST_CHARS),0,cx - 106,52,40,15,SWP_NOZORDER); + SetWindowPos(GetDlgItem(hWndDlg,IDC_ADDNUMBER),0,cx,5,170,20,SWP_NOZORDER); + SetWindowPos(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),0,cx,25,170,cy - 90,SWP_NOZORDER); + //SetWindowPos(GetDlgItem(hWndDlg,IDC_REMOVENUMBER),0,cx,cy - 110 + 25,170,20,SWP_NOZORDER); + SetWindowPos(GetDlgItem(hWndDlg,IDOK),0,cx/2 - 87,cy - 60,80,25,SWP_NOZORDER); + SetWindowPos(GetDlgItem(hWndDlg,IDCANCEL),0,cx/2 + 7,cy - 60,80,25,SWP_NOZORDER); + RedrawWindow(hWndDlg,NULL,NULL,RDW_FRAME|RDW_INVALIDATE); + } + break; + case WM_TIMER: + if (wParam==TIMERID_MSGSEND) + { + HWND hwndTimeOut; + WCHAR wszMessage[1028],wszPhone[MAX_PHONE_LEN]; + + if (psswdWindowData->bMultiple) + { + TVITEM tvi; + tvi.mask=TVIF_TEXT; + tvi.hItem=SendSMSWindowHItemSendGet(hWndDlg); + tvi.pszText=wszPhone; + tvi.cchTextMax=SIZEOF(wszPhone); + TreeView_GetItem(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),&tvi); + }else{ + GET_DLG_ITEM_TEXTW(hWndDlg,IDC_ADDRESS,wszPhone,SIZEOF(wszPhone)); + } + mir_sntprintf(wszMessage,SIZEOF(wszMessage),TranslateW(L"The SMS message send to %s timed out."),wszPhone); + KillTimer(hWndDlg,wParam); + ShowWindow(hWndDlg,SW_SHOWNORMAL); + EnableWindow(hWndDlg,FALSE); + hwndTimeOut=CreateDialog(ssSMSSettings.hInstance,MAKEINTRESOURCE(IDD_SENDSMSTIMEDOUT),hWndDlg,SMSTimedOutDlgProc); + SET_DLG_ITEM_TEXTW(hwndTimeOut,IDC_STATUS,wszMessage); + } + break; + case WM_CTLCOLOREDIT: + if ((HWND)lParam==GetDlgItem(hWndDlg,IDC_MESSAGE)) + { + COLORREF colour; + + LoadMsgDlgFont(MSGFONTID_MESSAGEAREA,NULL,&colour); + SetTextColor((HDC)wParam,colour); + SetBkColor((HDC)wParam,DBGetContactSettingDword(NULL,SRMMMOD,SRMSGSET_INPBKGCOLOUR,SRMSGDEFSET_BKGCOLOUR)); + return((BOOL)psswdWindowData->hBkgBrush); + } + break; + case DM_TIMEOUTDECIDED: + EnableWindow(hWndDlg,TRUE); + switch(wParam){ + case TIMEDOUT_CANCEL: + if (psswdWindowData->bMultiple) + { + if (SendSMSWindowNextHItemGet(hWndDlg,psswdWindowData->hItemSend)) + { + psswdWindowData->hItemSend=SendSMSWindowNextHItemGet(hWndDlg,psswdWindowData->hItemSend); + SendSMSWindowNext(hWndDlg); + }else{ + SendSMSWindowRemove(hWndDlg); + } + }else{ + EnableWindow(GetDlgItem(hWndDlg,IDOK),TRUE); + SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,EM_SETREADONLY,FALSE,0); + EnableWindow(GetDlgItem(hWndDlg,IDC_ACCOUNTS),TRUE); + EnableWindow(GetDlgItem(hWndDlg,IDC_ADDRESS),TRUE); + EnableWindow(GetDlgItem(hWndDlg,IDC_SAVENUMBER),TRUE); + EnableWindow(GetDlgItem(hWndDlg,IDC_MULTIPLE),TRUE); + EnableWindow(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),TRUE); + if (psswdWindowData->hMyContact==NULL) EnableWindow(GetDlgItem(hWndDlg,IDC_NAME),TRUE); + SetFocus(GetDlgItem(hWndDlg,IDC_MESSAGE)); + psswdWindowData->hItemSend=NULL; + } + break; + case TIMEDOUT_RETRY: + { + WCHAR wszPhone[MAX_PHONE_LEN]; + LPWSTR lpwszMessage; + SIZE_T dwPhoneSize,dwMessageSize; + + dwMessageSize=GET_DLG_ITEM_TEXT_LENGTH(hWndDlg,IDC_MESSAGE); + lpwszMessage=(LPWSTR)MEMALLOC(((dwMessageSize+4)*sizeof(WCHAR))); + if (lpwszMessage) + { + if (psswdWindowData->bMultiple) + { + TVITEM tvi; + tvi.mask=TVIF_TEXT; + tvi.hItem=psswdWindowData->hItemSend; + tvi.pszText=wszPhone; + tvi.cchTextMax=SIZEOF(wszPhone); + TreeView_GetItem(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),&tvi); + dwPhoneSize=lstrlenW(wszPhone); + }else{ + dwPhoneSize=GET_DLG_ITEM_TEXTW(hWndDlg,IDC_ADDRESS,wszPhone,SIZEOF(wszPhone)); + } + dwMessageSize=GET_DLG_ITEM_TEXTW(hWndDlg,IDC_MESSAGE,lpwszMessage,(dwMessageSize+2)); + SendSMSWindowNumberSet(hWndDlg,wszPhone,dwPhoneSize); + StartSmsSend(hWndDlg,SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ACCOUNTS,CB_GETCURSEL,0,0),wszPhone,dwPhoneSize,lpwszMessage,dwMessageSize); + MEMFREE(lpwszMessage); + } + } + SetTimer(hWndDlg,TIMERID_MSGSEND,TIMEOUT_MSGSEND,NULL); + break; + } + break; + case WM_COMMAND: + switch(LOWORD(wParam)){ + case IDC_MULTIPLE: + SendSMSWindowMultipleSet(hWndDlg,!psswdWindowData->bMultiple); + break; + case IDC_ADDNUMBER: + { + WCHAR wszPhone[MAX_PHONE_LEN]; + if (IsPhoneW(wszPhone,GET_DLG_ITEM_TEXTW(hWndDlg,IDC_ADDRESS,wszPhone,SIZEOF(wszPhone)))) + { + TVINSERTSTRUCT tvis={0}; + + tvis.item.mask=(TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE); + tvis.hInsertAfter=TVI_SORT; + tvis.item.pszText=wszPhone; + TreeView_InsertItem(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),&tvis); + }else{ + MessageBox(hWndDlg,TranslateW(L"The phone szPhone should start with a + and consist of numbers, spaces, brackets and hyphens only."),TranslateW(L"Invalid Phone Number"),MB_OK); + } + } + break; + case IDC_HISTORY: + CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)psswdWindowData->hMyContact,0); + break; + case IDOK: + if ((SIZE_T)GET_DLG_ITEM_TEXT_LENGTH(hWndDlg,IDC_MESSAGE) > GetSMSMessageLenMax(hWndDlg)) + { + MessageBox(hWndDlg,TranslateW(L"Message is too long, press OK to continue."),TranslateW(L"Error - Message too long"),MB_OK); + }else{ + if (psswdWindowData->bMultiple) + { + HTREEITEM hItem=SendSMSWindowNextHItemGet(hWndDlg,TreeView_GetRoot(GetDlgItem(hWndDlg,IDC_NUMBERSLIST))); + if (hItem) + { + psswdWindowData->hItemSend=hItem; + EnableWindow(GetDlgItem(hWndDlg,IDOK),FALSE); + EnableWindow(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),FALSE); + EnableWindow(GetDlgItem(hWndDlg,IDC_SAVENUMBER),FALSE); + EnableWindow(GetDlgItem(hWndDlg,IDC_NAME),FALSE); + EnableWindow(GetDlgItem(hWndDlg,IDC_MULTIPLE),FALSE); + EnableWindow(GetDlgItem(hWndDlg,IDC_ADDNUMBER),FALSE); + //EnableWindow(GetDlgItem(hWndDlg,IDC_REMOVENUMBER),FALSE); + SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,EM_SETREADONLY,TRUE,0); + EnableWindow(GetDlgItem(hWndDlg,IDC_ACCOUNTS),FALSE); + EnableWindow(GetDlgItem(hWndDlg,IDC_ADDRESS),FALSE); + SendSMSWindowNext(hWndDlg); + }else{ + MessageBox(hWndDlg,TranslateW(L"There must be numbers in the list first."),TranslateW(L"No Numbers"),MB_OK); + } + }else{ + WCHAR wszPhone[MAX_PHONE_LEN]; + SIZE_T dwPhoneSize; + + dwPhoneSize=GET_DLG_ITEM_TEXTW(hWndDlg,IDC_ADDRESS,wszPhone,SIZEOF(wszPhone)); + if (IsPhoneW(wszPhone,dwPhoneSize)) + { + LPWSTR lpwszMessage; + SIZE_T dwMessageSize; + + dwMessageSize=GET_DLG_ITEM_TEXT_LENGTH(hWndDlg,IDC_MESSAGE); + lpwszMessage=(LPWSTR)MEMALLOC((dwMessageSize+4)*sizeof(WCHAR)); + if (lpwszMessage) + { + dwMessageSize=GET_DLG_ITEM_TEXTW(hWndDlg,IDC_MESSAGE,lpwszMessage,(dwMessageSize+2)); + SendSMSWindowNumberSet(hWndDlg,wszPhone,dwPhoneSize); + EnableWindow(GetDlgItem(hWndDlg,IDOK),FALSE); + EnableWindow(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),FALSE); + EnableWindow(GetDlgItem(hWndDlg,IDC_SAVENUMBER),FALSE); + EnableWindow(GetDlgItem(hWndDlg,IDC_NAME),FALSE); + EnableWindow(GetDlgItem(hWndDlg,IDC_MULTIPLE),FALSE); + EnableWindow(GetDlgItem(hWndDlg,IDC_ACCOUNTS),FALSE); + EnableWindow(GetDlgItem(hWndDlg,IDC_ADDRESS),FALSE); + SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,EM_SETREADONLY,TRUE,0); + StartSmsSend(hWndDlg,SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ACCOUNTS,CB_GETCURSEL,0,0),wszPhone,dwPhoneSize,lpwszMessage,dwMessageSize); + SetTimer(hWndDlg,TIMERID_MSGSEND,TIMEOUT_MSGSEND,NULL); + + MEMFREE(lpwszMessage); + } + }else{ + MessageBox(hWndDlg,TranslateW(L"Valid phone numbers are of the form '+(country code)(phone szPhone)'. The contents of the phone szPhone portion is dependent on the national layout of phone numbers, but often omits the leading zero."),TranslateW(L"Invalid phone number"),MB_OK); + SetFocus(GetDlgItem(hWndDlg,IDC_ADDRESS)); + SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ADDRESS,CB_SETEDITSEL,0,MAKELPARAM(0,-1)); + } + } + } + break; + case IDCANCEL: + DeleteObject((HFONT)SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,WM_GETFONT,0,0)); + KillTimer(GetParent(hWndDlg),TIMERID_MSGSEND); + SendSMSWindowRemove(hWndDlg); + break; + case IDC_MESSAGE: + if (HIWORD(wParam)==EN_CHANGE) + { + WCHAR wszBuff[MAX_PATH]; + SIZE_T dwMessageSize=GET_DLG_ITEM_TEXT_LENGTH(hWndDlg,IDC_MESSAGE); + + EnableWindow(GetDlgItem(hWndDlg,IDOK),dwMessageSize); + mir_sntprintf(wszBuff,SIZEOF(wszBuff),L"%d/%d",dwMessageSize,GetSMSMessageLenMax(hWndDlg)); + SET_DLG_ITEM_TEXTW(hWndDlg,IDC_COUNT,wszBuff); + } + break; + case IDC_SAVENUMBER: + { + BOOL bCont=TRUE; + char szBuff[MAX_PATH]; + WCHAR wszPhone[MAX_PHONE_LEN]; + SIZE_T dwPhoneSize; + DBVARIANT dbv; + + dwPhoneSize=GET_DLG_ITEM_TEXTW(hWndDlg,IDC_ADDRESS,wszPhone,(SIZEOF(wszPhone)-4)); + if (IsPhoneW(wszPhone,dwPhoneSize)) + { + if (IsContactPhone(psswdWindowData->hMyContact,wszPhone,dwPhoneSize)==FALSE) + { + lstrcatW(wszPhone,L" SMS"); + for(DWORD i=0;bCont;i++) + { + mir_snprintf(szBuff,SIZEOF(szBuff),"MyPhone%d",i); + if (DBGetContactSetting(psswdWindowData->hMyContact,"UserInfo",szBuff,&dbv)) bCont=FALSE; + DBFreeVariant(&dbv); + } + DB_SetStringW(psswdWindowData->hMyContact,"UserInfo",szBuff,wszPhone); + } + }else{ + MessageBox(hWndDlg,TranslateW(L"The phone szPhone should start with a + and consist of numbers, spaces, brackets and hyphens only."),TranslateW(L"Invalid Phone Number"),MB_OK); + } + } + break; + case IDC_NAME: + if (HIWORD(wParam)==CBN_SELCHANGE) + { + SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ADDRESS,CB_RESETCONTENT,0,0); + if (SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_NAME,CB_GETCURSEL,0,0)) + { + HANDLE hContact=SendSMSWindowSMSContactGet(hWndDlg,(SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_NAME,CB_GETCURSEL,0,0)-1)); + if (hContact) AddContactPhonesToCombo(hWndDlg,hContact); + } + } + break; + } + break; + case WM_NOTIFY: + switch(((NMHDR*)lParam)->idFrom){ + case IDC_NUMBERSLIST: + switch(((NMHDR*)lParam)->code){ + case NM_CLICK: + { + int iImage,iSame=1; + HWND hWndTree=GetDlgItem(hWndDlg,IDC_NUMBERSLIST); + TVITEM tvi={0}; + HTREEITEM hParent; + TVHITTESTINFO hti={0}; + + hti.pt.x=(short)LOWORD(GetMessagePos()); + hti.pt.y=(short)HIWORD(GetMessagePos()); + ScreenToClient(((LPNMHDR)lParam)->hwndFrom,&hti.pt); + + if (TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom,&hti)) + if (hti.flags&TVHT_ONITEMICON) + { + tvi.mask=(TVIF_IMAGE|TVIF_SELECTEDIMAGE); + tvi.hItem=hti.hItem; + TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom,&tvi); + iImage=tvi.iImage=tvi.iSelectedImage=!tvi.iImage; + TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom,&tvi); + + if (TreeView_GetParent(hWndTree,hti.hItem)) + { + hParent=TreeView_GetParent(hWndTree,hti.hItem); + for(tvi.hItem=TreeView_GetChild(hWndTree,hParent);tvi.hItem;tvi.hItem=TreeView_GetNextSibling(hWndTree,tvi.hItem)) + { + TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom,&tvi); + if (tvi.iImage!=iImage) + { + iSame=0; + break; + } + } + tvi.hItem=hParent; + tvi.iImage=tvi.iSelectedImage=((iSame==1)? iImage:2); + TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom,&tvi); + }else{ + for(tvi.hItem=TreeView_GetChild(hWndTree,hti.hItem);tvi.hItem;tvi.hItem=TreeView_GetNextSibling(hWndTree,tvi.hItem)) + { + TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom,&tvi); + tvi.iImage=tvi.iSelectedImage=iImage; + TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom,&tvi); + } + } + } + } + break; + } + } + break; + case WM_CLOSE: + DeleteObject((HFONT)SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_MESSAGE,WM_GETFONT,0,0)); + DeleteObject(psswdWindowData->hBkgBrush); + RemWinHandle(GetDlgItem(hWndDlg,IDC_MESSAGE)); + KillTimer(GetParent(hWndDlg),TIMERID_MSGSEND); + SendSMSWindowRemove(hWndDlg); + break; + } +return(FALSE); +} + +BOOL CALLBACK SMSTimedOutDlgProc(HWND hWndDlg,UINT msg,WPARAM wParam,LPARAM lParam) +{ + switch(msg){ + case WM_INITDIALOG: + { + RECT rc,rcParent; + TranslateDialogDefault(hWndDlg); + GetWindowRect(hWndDlg,&rc); + GetWindowRect(GetParent(hWndDlg),&rcParent); + SetWindowPos(hWndDlg,0,(rcParent.left+rcParent.right-(rc.right-rc.left))/2,(rcParent.top+rcParent.bottom-(rc.bottom-rc.top))/2,0,0,SWP_NOZORDER|SWP_NOSIZE); + KillTimer(GetParent(hWndDlg),TIMERID_MSGSEND); + } + return(TRUE); + case WM_COMMAND: + switch(LOWORD(wParam)){ + case IDOK: + SendMessage(GetParent(hWndDlg),DM_TIMEOUTDECIDED,TIMEDOUT_RETRY,0); + DestroyWindow(hWndDlg); + break; + case IDCANCEL: + SendMessage(GetParent(hWndDlg),DM_TIMEOUTDECIDED,TIMEDOUT_CANCEL,0); + DestroyWindow(hWndDlg); + break; + } + break; + } +return(FALSE); +} + +BOOL CALLBACK SMSAcceptedDlgProc(HWND hWndDlg,UINT msg,WPARAM wParam,LPARAM lParam) +{ + switch(msg){ + case WM_INITDIALOG: + { + RECT rc,rcParent; + TranslateDialogDefault(hWndDlg); + GetWindowRect(hWndDlg,&rc); + GetWindowRect(GetParent(hWndDlg),&rcParent); + SetWindowPos(hWndDlg,0,(rcParent.left+rcParent.right-(rc.right-rc.left))/2,(rcParent.top+rcParent.bottom-(rc.bottom-rc.top))/2,0,0,SWP_NOZORDER|SWP_NOSIZE); + } + return(TRUE); + case WM_COMMAND: + switch(LOWORD(wParam)){ + case IDOK: + SendSMSWindowRemove(GetParent(hWndDlg)); + DestroyWindow(hWndDlg); + break; + } + break; + } +return(FALSE); +} + +//SMS Send window list functions + +//This function create a new SMS send window, and insert it to the list. +//The function gets void and return the window HWND +HWND SendSMSWindowAdd(HANDLE hContact) +{ + HWND hRet=NULL; + SEND_SMS_WINDOW_DATA *psswdWindowData; + + psswdWindowData=(SEND_SMS_WINDOW_DATA*)MEMALLOC(sizeof(SEND_SMS_WINDOW_DATA)); + if (psswdWindowData) + { + psswdWindowData->hMyContact=hContact; + psswdWindowData->hWnd=CreateDialogParam(ssSMSSettings.hInstance,MAKEINTRESOURCE(IDD_SENDSMS),NULL,SendSmsDlgProc,(LPARAM)psswdWindowData); + if (psswdWindowData->hWnd) + { + WCHAR wszTitle[MAX_PATH]; + LPWSTR lpwszContactDisplayName; + + ListMTLock(&ssSMSSettings.lmtSendSMSWindowsListMT); + ListMTItemAdd(&ssSMSSettings.lmtSendSMSWindowsListMT,&psswdWindowData->lmtListMTItem,psswdWindowData); + ListMTUnLock(&ssSMSSettings.lmtSendSMSWindowsListMT); + + lpwszContactDisplayName=GetContactNameW(hContact); + mir_sntprintf(wszTitle,SIZEOF(wszTitle),L"%s - %s",lpwszContactDisplayName,TranslateW(L"Send SMS")); + SendMessageW(psswdWindowData->hWnd,WM_SETTEXT,NULL,(LPARAM)wszTitle); + SEND_DLG_ITEM_MESSAGEW(psswdWindowData->hWnd,IDC_NAME,CB_ADDSTRING,0,(LPARAM)lpwszContactDisplayName); + SEND_DLG_ITEM_MESSAGE(psswdWindowData->hWnd,IDC_NAME,CB_SETCURSEL,0,0); + AddContactPhonesToCombo(psswdWindowData->hWnd,hContact); + SetFocus(GetDlgItem(psswdWindowData->hWnd,IDC_MESSAGE)); + hRet=psswdWindowData->hWnd; + }else{ + MEMFREE(psswdWindowData); + } + } +return(hRet); +} + +//This function close the SMS send window that given, and remove it from the list. +//The function gets the HWND of the window that should be removed and return void +void SendSMSWindowRemove(HWND hWndDlg) +{ + SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); + + if (psswdWindowData) + { + DB_SMS_SetDword(NULL,"LastProto",SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ACCOUNTS,CB_GETCURSEL,0,0)); + SendSMSWindowMultipleSet(hWndDlg,FALSE); + Utils_SaveWindowPosition(hWndDlg,(DB_SMS_GetByte(NULL,"SavePerContact",0)? psswdWindowData->hMyContact:NULL),PROTOCOL_NAMEA,"send"); + + ListMTLock(&ssSMSSettings.lmtSendSMSWindowsListMT); + ListMTItemDelete(&ssSMSSettings.lmtSendSMSWindowsListMT,&psswdWindowData->lmtListMTItem); + ListMTUnLock(&ssSMSSettings.lmtSendSMSWindowsListMT); + SendSMSWindowSMSContactsRemove(hWndDlg); + MEMFREE(psswdWindowData->pdbei); + MEMFREE(psswdWindowData); + } + DestroyWindow(hWndDlg); +} + +//This function return the contact HANDLE for the given to the SMS send window. +//The function gets the HWND of the window and return the HANDLE of the contact. +HANDLE SendSMSWindowHContactGet(HWND hWndDlg) +{ + HANDLE hRet=NULL; + SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); + + if (psswdWindowData) hRet=psswdWindowData->hMyContact; +return(hRet); +} + +//This function set the contact info of the person we send him the in the given to the SMS send window. +//The function gets the HWND of the window and the HANDLE of the contact and return void +void SendSMSWindowHContactSet(HWND hWndDlg,HANDLE hContact) +{ + SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); + if (psswdWindowData) psswdWindowData->hMyContact=hContact; +} + +//This function return the HWND of a SMS send window that have the same process as given. +//The function gets the HANDLE of a process and return the HWND of the SMS send window that has +//the same process +HWND SendSMSWindowHwndByHProcessGet(HANDLE hProcess) +{ + HWND hRet=NULL; + SEND_SMS_WINDOW_DATA *psswdWindowData; + LIST_MT_ITERATOR lmtiIterator; + + ListMTLock(&ssSMSSettings.lmtSendSMSWindowsListMT); + ListMTIteratorMoveFirst(&ssSMSSettings.lmtSendSMSWindowsListMT,&lmtiIterator); + do + {// цикл + if (ListMTIteratorGet(&lmtiIterator,NULL,(LPVOID*)&psswdWindowData)==NO_ERROR) + if (psswdWindowData->hProcess==hProcess) + { + hRet=psswdWindowData->hWnd; + break; + } + }while(ListMTIteratorMoveNext(&lmtiIterator)); + ListMTUnLock(&ssSMSSettings.lmtSendSMSWindowsListMT); +return(hRet); +} + +//This function set the process info of the send procedure we sent with the given SMS send window. +//The function gets the HWND of the window and the HANDLE of the process and return void +void SendSMSWindowHProcessSet(HWND hWndDlg,HANDLE hProcess) +{ + SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); + if (psswdWindowData) psswdWindowData->hProcess=hProcess; +} + +// +BOOL SendSMSWindowMultipleGet(HWND hWndDlg) +{ + BOOL bRet=FALSE; + SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); + + if (psswdWindowData) bRet=psswdWindowData->bMultiple; +return(bRet); +} + +// +void SendSMSWindowMultipleSet(HWND hWndDlg,BOOL bMultiple) +{ + SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); + + if (psswdWindowData) + if (psswdWindowData->bMultiple!=bMultiple) + { + RECT rcWin,rcList; + WINDOWPLACEMENT wp; + + psswdWindowData->bMultiple=bMultiple; + wp.length=sizeof(WINDOWPLACEMENT); + GetWindowRect(hWndDlg,&rcWin); + GetWindowRect(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),&rcList); + GetWindowPlacement(hWndDlg,&wp); + + if (bMultiple) + { + SendSMSWindowFillTreeView(hWndDlg); + + EnableWindow(GetDlgItem(hWndDlg,IDC_SAVENUMBER),FALSE); + SET_DLG_ITEM_TEXTW(hWndDlg,IDC_MULTIPLE,TranslateW(L"<< Single")); + if (wp.showCmd==SW_MAXIMIZE) SetWindowPos(hWndDlg,0,0,0,rcWin.right - rcWin.left - (rcList.right - rcList.left + 11) ,rcWin.bottom - rcWin.top,SWP_NOZORDER|SWP_NOMOVE); + SetWindowPos(hWndDlg,0,rcWin.left,rcWin.top,rcWin.right - rcWin.left + (rcList.right-rcList.left) + 11,rcWin.bottom - rcWin.top,SWP_NOZORDER|SWP_NOMOVE); + }else{ + if (psswdWindowData->hMyContact) AddContactPhonesToCombo(hWndDlg,psswdWindowData->hMyContact); + + EnableWindow(GetDlgItem(hWndDlg,IDC_SAVENUMBER),TRUE); + SET_DLG_ITEM_TEXTW(hWndDlg,IDC_MULTIPLE,TranslateW(L"Multiple >>")); + SetWindowPos(hWndDlg,0,rcWin.left,rcWin.top,rcWin.right-rcWin.left - (rcList.right-rcList.left) - 11,rcWin.bottom - rcWin.top,SWP_NOZORDER|SWP_NOMOVE); + if (wp.showCmd==SW_MAXIMIZE) SetWindowPos(hWndDlg,0,0,0,rcWin.right - rcWin.left + (rcList.right - rcList.left + 11) ,rcWin.bottom - rcWin.top,SWP_NOZORDER|SWP_NOMOVE); + } + } +} + +// +void SendSMSWindowNumberSet(HWND hWndDlg,LPWSTR lpwszPhone,SIZE_T dwPhoneSize) +{ + SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); + + if (psswdWindowData) + if (psswdWindowData->bMultiple) + { + psswdWindowData->hContact=psswdWindowData->hMyContact; + }else{ + psswdWindowData->hContact=HContactFromPhone(lpwszPhone,dwPhoneSize); + } +} + +// +void SendSMSWindowAsSentSet(HWND hWndDlg) +{ +// LVITEM lvi; +// char szPhone[MAX_PHONE_LEN]; +// lvi.mask=LVIF_TEXT|LVIF_IMAGE; +// lvi.iItem=GetSendSMSWindowSMSSend(hWndDlg) - 1; +// lvi.iSubItem=0; +// ListView_GetItemText(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),GetSendSMSWindowSMSSend(hWndDlg) - 1,0,szPhone,sizeof(szPhone)); +// lvi.pszText=szPhone; +// lvi.iImage=2; +// ListView_SetItem(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),&lvi); +// ListView_RedrawItems(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),0,ListView_GetItemCount(GetDlgItem(hWndDlg,IDC_NUMBERSLIST)) - 1); +} + +//This function set the databsae info of the sent message we sent with the SMS send window. +//The function gets the HWND of the window and the DBEI of the database information of the message +//and return void +void SendSMSWindowDbeiSet(HWND hWndDlg,DBEVENTINFO *pdbei) +{ + SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); + if (psswdWindowData) psswdWindowData->pdbei=pdbei; +} + +//This function get a HWND of SMS send window and add its database information into Miranda-IM database +//The function gets the HWND of the window and return void +//and return void +void SendSMSWindowDBAdd(HWND hWndDlg) +{ + SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); + + if (psswdWindowData) + { + psswdWindowData->pdbei->cbSize=sizeof(DBEVENTINFO); + psswdWindowData->pdbei->szModule=GetModuleName(psswdWindowData->hContact); + + CallService(MS_DB_EVENT_ADD,(WPARAM)psswdWindowData->hContact,(LPARAM)psswdWindowData->pdbei); + MEMFREE(psswdWindowData->pdbei); + } +} + +// +void SendSMSWindowHItemSendSet(HWND hWndDlg,HTREEITEM hItemSend) +{ + SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); + if (psswdWindowData) psswdWindowData->hItemSend=hItemSend; +} + +// +HTREEITEM SendSMSWindowHItemSendGet(HWND hWndDlg) +{ + HTREEITEM hRet=NULL; + SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); + + if (psswdWindowData) hRet=psswdWindowData->hItemSend; +return(hRet); +} + +// +HTREEITEM SendSMSWindowNextHItemGet(HWND hWndDlg,HTREEITEM hItem) +{ + int isFound=0; + HWND hWndTree=GetDlgItem(hWndDlg,IDC_NUMBERSLIST); + TVITEM tvi; + HTREEITEM hItemNext,hItemChild; + + if (hItem==TreeView_GetRoot(hWndTree)) isFound=1; + + for(hItemNext=TreeView_GetRoot(hWndTree);hItemNext;hItemNext=TreeView_GetNextSibling(hWndTree,hItemNext)) + { + if ((hItem==hItemNext) && (hItem!=TreeView_GetRoot(hWndTree))) + { + isFound=1; + continue; + } + + tvi.mask=(TVIF_IMAGE|TVIF_SELECTEDIMAGE); + tvi.hItem=hItemNext; + tvi.iImage=0; + tvi.iSelectedImage=0; + TreeView_GetItem(hWndTree,&tvi); + + if (tvi.iImage || tvi.iSelectedImage) + if (TreeView_GetChild(hWndTree,hItemNext)) + { + for (hItemChild=TreeView_GetChild(hWndTree,hItemNext);hItemChild;hItemChild=TreeView_GetNextSibling(hWndTree,hItemChild)) + { + if (hItem==hItemChild) + { + isFound=1; + continue; + } + + tvi.mask=(TVIF_IMAGE|TVIF_SELECTEDIMAGE); + tvi.hItem=hItemChild; + tvi.iImage=0; + tvi.iSelectedImage=0; + TreeView_GetItem(hWndTree,&tvi); + + if (tvi.iImage || tvi.iSelectedImage) + if (isFound) + { + return(hItemChild); + }else{ + continue; + } + } + }else{ + if (isFound) + { + return(hItemNext); + }else{ + continue; + } + } + } +return(NULL); +} + +//This function get the HANDLE of an user. if there is already a SMS send window for this contact +//it return its HWND else the function return NULL. +//The function gets the HANDLE of a contact and return HWND +HWND SendSMSWindowIsOtherInstanceHContact(HANDLE hContact) +{ + HWND hRet=NULL; + SEND_SMS_WINDOW_DATA *psswdWindowData; + LIST_MT_ITERATOR lmtiIterator; + + ListMTLock(&ssSMSSettings.lmtSendSMSWindowsListMT); + ListMTIteratorMoveFirst(&ssSMSSettings.lmtSendSMSWindowsListMT,&lmtiIterator); + do + {// цикл + if (ListMTIteratorGet(&lmtiIterator,NULL,(LPVOID*)&psswdWindowData)==NO_ERROR) + if (psswdWindowData->hMyContact==hContact) + { + hRet=psswdWindowData->hWnd; + break; + } + }while(ListMTIteratorMoveNext(&lmtiIterator)); + ListMTUnLock(&ssSMSSettings.lmtSendSMSWindowsListMT); +return(hRet); +} + + +// +void SendSMSWindowNext(HWND hWndDlg) +{ + WCHAR wszPhone[MAX_PHONE_LEN]; + LPWSTR lpwszMessage; + SIZE_T dwPhoneSize,dwMessageSize; + TVITEM tvi={0}; + + dwMessageSize=GET_DLG_ITEM_TEXT_LENGTH(hWndDlg,IDC_MESSAGE); + lpwszMessage=(LPWSTR)MEMALLOC(((dwMessageSize+4)*sizeof(WCHAR))); + if (lpwszMessage) + { + dwMessageSize=GET_DLG_ITEM_TEXTW(hWndDlg,IDC_MESSAGE,lpwszMessage,(dwMessageSize+2)); + + // if (SendSMSWindowNextHItemGet(hWndDlg,SendSMSWindowHItemSendGet(hWndDlg))==NULL) SendSMSWindowMultipleSet(hWndDlg,FALSE); + tvi.mask=TVIF_TEXT; + tvi.hItem=SendSMSWindowHItemSendGet(hWndDlg); + tvi.pszText=wszPhone; + tvi.cchTextMax=SIZEOF(wszPhone); + TreeView_GetItem(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),&tvi); + TreeView_SelectItem(GetDlgItem(hWndDlg,IDC_NUMBERSLIST),tvi.hItem); + dwPhoneSize=lstrlenW(wszPhone); + SendSMSWindowNumberSet(hWndDlg,wszPhone,dwPhoneSize); + StartSmsSend(hWndDlg,SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ACCOUNTS,CB_GETCURSEL,0,0),wszPhone,dwPhoneSize,lpwszMessage,dwMessageSize); + SetTimer(hWndDlg,TIMERID_MSGSEND,TIMEOUT_MSGSEND,NULL); + MEMFREE(lpwszMessage); + } +} + + +////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////// +//This function gets a HANDLE of a contact and add it to a list. +void SendSMSWindowSMSContactAdd(HWND hWndDlg,HANDLE hContact) +{ + SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); + + if (psswdWindowData) + { + psswdWindowData->dwContactsListCount++; + if (psswdWindowData->phContactsList) + { + psswdWindowData->phContactsList=(HANDLE*)MEMREALLOC(psswdWindowData->phContactsList,(sizeof(HANDLE)*psswdWindowData->dwContactsListCount)); + }else{ + psswdWindowData->phContactsList=(HANDLE*)MEMALLOC((sizeof(HANDLE)*psswdWindowData->dwContactsListCount)); + } + *(psswdWindowData->phContactsList+psswdWindowData->dwContactsListCount-1)=hContact; + } +} + +//This function gets the number of the given contact in the combo list and return its contact. +HANDLE SendSMSWindowSMSContactGet(HWND hWndDlg,SIZE_T iNum) +{ + SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); + + if (psswdWindowData) + { + return(*((psswdWindowData->phContactsList)+iNum)); + } +return(NULL); +} + +void SendSMSWindowSMSContactsRemove(HWND hWndDlg) +{ + SEND_SMS_WINDOW_DATA *psswdWindowData=GET_WINDOW_DATA(hWndDlg); + + if (psswdWindowData) + { + MEMFREE(psswdWindowData->phContactsList); + psswdWindowData->dwContactsListCount=0; + } +} + +void SendSMSWindowUpdateAccountList(HWND hWndDlg) +{ + if (ssSMSSettings.ppaSMSAccounts && ssSMSSettings.dwSMSAccountsCount) + { + SIZE_T i,dwCurSel; + + dwCurSel=SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ACCOUNTS,CB_GETCURSEL,0,0); + if (dwCurSel==-1) dwCurSel=DB_SMS_GetDword(NULL,"LastProto",0); + if (dwCurSel==-1) dwCurSel=0; + + SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ACCOUNTS,CB_RESETCONTENT,0,0); + for(i=0;iszModuleName); + } + SEND_DLG_ITEM_MESSAGE(hWndDlg,IDC_ACCOUNTS,CB_SETCURSEL,(WPARAM)dwCurSel,0); + } +} + + +void SendSMSWindowsUpdateAllAccountLists() +{ + SEND_SMS_WINDOW_DATA *psswdWindowData; + LIST_MT_ITERATOR lmtiIterator; + + ListMTLock(&ssSMSSettings.lmtSendSMSWindowsListMT); + ListMTIteratorMoveFirst(&ssSMSSettings.lmtSendSMSWindowsListMT,&lmtiIterator); + do + {// цикл + if (ListMTIteratorGet(&lmtiIterator,NULL,(LPVOID*)&psswdWindowData)==NO_ERROR) + { + SendSMSWindowUpdateAccountList(psswdWindowData->hWnd); + } + }while(ListMTIteratorMoveNext(&lmtiIterator)); + ListMTUnLock(&ssSMSSettings.lmtSendSMSWindowsListMT); +} +////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////// + + + + +void AddContactPhonesToComboToListParam(HANDLE hContact,LPSTR lpszModule,LPSTR lpszValueName,HWND hWndList) +{ + char szBuff[MAX_PATH]; + WCHAR wszPhone[MAX_PHONE_LEN],wszPhoneRaw[MAX_PHONE_LEN]; + SIZE_T i,dwPhoneSize; + + if (DB_GetStaticStringW(hContact,lpszModule,lpszValueName,wszPhoneRaw,SIZEOF(wszPhoneRaw),&dwPhoneSize)) + { + wszPhone[0]='+'; + dwPhoneSize=CopyNumberW((wszPhone+1),wszPhoneRaw,dwPhoneSize); + if (IsPhoneW(wszPhone,dwPhoneSize)) + { + if (SendMessage(hWndList,CB_FINDSTRING,-1,(LPARAM)wszPhone)==CB_ERR) SendMessage(hWndList,CB_ADDSTRING,0,(LPARAM)wszPhone); + } + } + + for (i=0;TRUE;i++) + { + mir_snprintf(szBuff,sizeof(szBuff),"%s%ld",lpszValueName,i); + if (DB_GetStaticStringW(hContact,lpszModule,szBuff,wszPhoneRaw,SIZEOF(wszPhoneRaw),&dwPhoneSize)) + { + wszPhone[0]='+'; + dwPhoneSize=CopyNumberW((wszPhone+1),wszPhoneRaw,dwPhoneSize); + if (IsPhoneW(wszPhone,dwPhoneSize)) + { + if (SendMessage(hWndList,CB_FINDSTRING,-1,(LPARAM)wszPhone)==CB_ERR) SendMessage(hWndList,CB_ADDSTRING,0,(LPARAM)wszPhone); + } + }else{ + if (i>PHONES_MIN_COUNT) break; + } + } +} + + +void AddContactPhonesToCombo(HWND hWnd,HANDLE hContact) +{ + HWND hWndList; + LPSTR lpszProto; + + hWndList=GetDlgItem(hWnd,IDC_ADDRESS); + SEND_DLG_ITEM_MESSAGE(hWnd,IDC_ADDRESS,CB_RESETCONTENT,0,0); + + lpszProto=(LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0); + if (lpszProto) + { + AddContactPhonesToComboToListParam(hContact,lpszProto,"Phone",hWndList); + AddContactPhonesToComboToListParam(hContact,lpszProto,"Cellular",hWndList); + AddContactPhonesToComboToListParam(hContact,lpszProto,"Fax",hWndList); + } + AddContactPhonesToComboToListParam(hContact,"UserInfo","MyPhone",hWndList); + AddContactPhonesToComboToListParam(hContact,"UserInfo","Phone",hWndList); + AddContactPhonesToComboToListParam(hContact,"UserInfo","Cellular",hWndList); + AddContactPhonesToComboToListParam(hContact,"UserInfo","Fax",hWndList); + + SEND_DLG_ITEM_MESSAGE(hWnd,IDC_ADDRESS,CB_SETCURSEL,0,0); +} + + + +void AddContactPhonesToTreeViewParam(HANDLE hContact,LPSTR lpszModule,LPSTR lpszValueName,HWND hWndList,HTREEITEM *phParent) +{ + char szBuff[MAX_PATH]; + WCHAR wszPhone[MAX_PHONE_LEN],wszPhoneRaw[MAX_PHONE_LEN]; + SIZE_T i,dwPhoneSize; + TVINSERTSTRUCT tvis={0}; + + if (phParent) tvis.hParent=(*phParent); + tvis.item.mask=(TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE); + tvis.hInsertAfter=TVI_SORT; + tvis.item.iImage=tvis.item.iSelectedImage=0; + + if (DB_GetStaticStringW(hContact,lpszModule,lpszValueName,wszPhoneRaw,SIZEOF(wszPhoneRaw),&dwPhoneSize)) + { + wszPhone[0]='+'; + dwPhoneSize=CopyNumberW((wszPhone+1),wszPhoneRaw,dwPhoneSize); + if (IsPhoneW(wszPhone,dwPhoneSize)) + { + if (tvis.hParent==NULL) + { + tvis.item.pszText=GetContactNameW(hContact); + tvis.hParent=TreeView_InsertItem(hWndList,&tvis); + } + tvis.item.pszText=wszPhone; + TreeView_InsertItem(hWndList,&tvis); + } + } + + for (i=0;TRUE;i++) + { + mir_snprintf(szBuff,sizeof(szBuff),"%s%ld",lpszValueName,i); + if (DB_GetStaticStringW(hContact,lpszModule,szBuff,wszPhoneRaw,SIZEOF(wszPhoneRaw),&dwPhoneSize)) + { + wszPhone[0]='+'; + dwPhoneSize=CopyNumberW((wszPhone+1),wszPhoneRaw,dwPhoneSize); + if (IsPhoneW(wszPhone,dwPhoneSize)) + { + if (tvis.hParent==NULL) + { + tvis.item.pszText=GetContactNameW(hContact); + tvis.hParent=TreeView_InsertItem(hWndList,&tvis); + } + tvis.item.pszText=wszPhone; + TreeView_InsertItem(hWndList,&tvis); + } + }else{ + if (i>PHONES_MIN_COUNT) break; + } + } + if (phParent) (*phParent)=tvis.hParent; +} + + +void SendSMSWindowFillTreeView(HWND hWnd) +{ + HWND hWndTreeView; + LPSTR lpszProto; + HTREEITEM hParent; + + hWndTreeView=GetDlgItem(hWnd,IDC_NUMBERSLIST); + TreeView_DeleteAllItems(hWndTreeView); + + for(HANDLE hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);hContact!=NULL;hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)) + { + hParent=NULL; + lpszProto=(LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0); + if (lpszProto) + { + AddContactPhonesToTreeViewParam(hContact,lpszProto,"Phone",hWndTreeView,&hParent); + AddContactPhonesToTreeViewParam(hContact,lpszProto,"Cellular",hWndTreeView,&hParent); + AddContactPhonesToTreeViewParam(hContact,lpszProto,"Fax",hWndTreeView,&hParent); + } + AddContactPhonesToTreeViewParam(hContact,"UserInfo","MyPhone",hWndTreeView,&hParent); + AddContactPhonesToTreeViewParam(hContact,"UserInfo","Phone",hWndTreeView,&hParent); + AddContactPhonesToTreeViewParam(hContact,"UserInfo","Cellular",hWndTreeView,&hParent); + AddContactPhonesToTreeViewParam(hContact,"UserInfo","Fax",hWndTreeView,&hParent); + } +} + + +SIZE_T GetSMSMessageLenMax(HWND hWndDlg) +{ + LPWSTR lpwszMessage; + SIZE_T dwMessageSize,dwLenght=160; + + dwMessageSize=GET_DLG_ITEM_TEXT_LENGTH(hWndDlg,IDC_MESSAGE); + lpwszMessage=(LPWSTR)MEMALLOC(((dwMessageSize+4)*sizeof(WCHAR))); + if (lpwszMessage) + { + dwMessageSize=GET_DLG_ITEM_TEXTW(hWndDlg,IDC_MESSAGE,lpwszMessage,(dwMessageSize+2)); + if (dwMessageSize!=WideCharToMultiByte(CP_UTF8,0,lpwszMessage,dwMessageSize,NULL,0,NULL,NULL)) dwLenght=70; + MEMFREE(lpwszMessage); + } +return(dwLenght); +} + + + + + + + + + + diff --git a/plugins/!NotAdopted/SMS/senddlg.h b/plugins/!NotAdopted/SMS/senddlg.h new file mode 100644 index 0000000000..225cf80f28 --- /dev/null +++ b/plugins/!NotAdopted/SMS/senddlg.h @@ -0,0 +1,40 @@ +#if !defined(AFX_SMS_SENDDLG_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_) +#define AFX_SMS_SENDDLG_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_ + + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + +DWORD SendSMSWindowInitialize (); +void SendSMSWindowDestroy (); + +//Decleration of SMS send window list +BOOL CALLBACK SMSAcceptedDlgProc (HWND hWndDlg,UINT msg,WPARAM wParam,LPARAM lParam); +BOOL CALLBACK SMSTimedOutDlgProc (HWND hWndDlg,UINT msg,WPARAM wParam,LPARAM lParam); +HWND SendSMSWindowAdd (HANDLE hContact); +void SendSMSWindowRemove (HWND hWndDlg); +HANDLE SendSMSWindowHContactGet (HWND hWndDlg); +void SendSMSWindowHContactSet (HWND hWndDlg,HANDLE hContact); +HWND SendSMSWindowHwndByHProcessGet (HANDLE hProcess); +void SendSMSWindowHProcessSet (HWND hWndDlg,HANDLE hProcess); +BOOL SendSMSWindowMultipleGet (HWND hWndDlg); +void SendSMSWindowMultipleSet (HWND hWndDlg,BOOL bMultiple); +void SendSMSWindowNumberSet (HWND hWndDlg,LPWSTR lpwszPhone,SIZE_T dwPhoneSize); +void SendSMSWindowAsSentSet (HWND hWndDlg); +void SendSMSWindowDbeiSet (HWND hWndDlg,DBEVENTINFO *pdbei); +void SendSMSWindowDBAdd (HWND hWndDlg); +void SendSMSWindowHItemSendSet (HWND hWndDlg,HTREEITEM hItemSend); +HTREEITEM SendSMSWindowHItemSendGet (HWND hWndDlg); +HTREEITEM SendSMSWindowNextHItemGet (HWND hWndDlg,HTREEITEM hItem); +HWND SendSMSWindowIsOtherInstanceHContact(HANDLE hContact); +void SendSMSWindowNext (HWND hWndDlg); + +void SendSMSWindowSMSContactAdd (HWND hWndDlg,HANDLE hContact); +HANDLE SendSMSWindowSMSContactGet (HWND hWndDlg,SIZE_T iNum); +void SendSMSWindowSMSContactsRemove (HWND hWndDlg); +void SendSMSWindowUpdateAccountList (HWND hWndDlg); +void SendSMSWindowsUpdateAllAccountLists (); + +#endif // !defined(AFX_SMS_SENDDLG_H__F58D13FF_F6F2_476C_B8F0_7B9E9357CF48__INCLUDED_) diff --git a/plugins/!NotAdopted/SMS/sms.dsp b/plugins/!NotAdopted/SMS/sms.dsp new file mode 100644 index 0000000000..75d75ee5d8 --- /dev/null +++ b/plugins/!NotAdopted/SMS/sms.dsp @@ -0,0 +1,231 @@ +# Microsoft Developer Studio Project File - Name="sms" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=sms - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "sms.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "sms.mak" CFG="sms - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "sms - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "sms - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "sms - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SMS_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SMS_EXPORTS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 LIBCTINY.LIB kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /base:"0x25000000" /dll /map /machine:I386 /nodefaultlib + +!ELSEIF "$(CFG)" == "sms - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SMS_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SMS_EXPORTS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 LIBCTINY.LIB kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /nodefaultlib /out:"../../Debug/plugins/sms.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "sms - Win32 Release" +# Name "sms - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Group "minicrt" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\mincrt\MEMSET.C +# End Source File +# Begin Source File + +SOURCE=.\mincrt\STRCHR.C +# End Source File +# Begin Source File + +SOURCE=.\mincrt\STRDUP.C +# End Source File +# Begin Source File + +SOURCE=.\mincrt\strncmp.c +# End Source File +# Begin Source File + +SOURCE=.\mincrt\STRSPN.C +# End Source File +# Begin Source File + +SOURCE=.\mincrt\time.c +# End Source File +# Begin Source File + +SOURCE=.\mincrt\wsnprintf.c +# End Source File +# End Group +# Begin Source File + +SOURCE=.\main.c +# End Source File +# Begin Source File + +SOURCE=.\options.c +# End Source File +# Begin Source File + +SOURCE=.\receive.c +# End Source File +# Begin Source File + +SOURCE=.\recvdlg.c +# End Source File +# Begin Source File + +SOURCE=.\send.c +# End Source File +# Begin Source File + +SOURCE=.\senddlg.c +# End Source File +# Begin Source File + +SOURCE=.\utf8.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\AggressiveOptimize.h +# End Source File +# Begin Source File + +SOURCE=.\m_autoreplacer.h +# End Source File +# Begin Source File + +SOURCE=.\main.h +# End Source File +# Begin Source File + +SOURCE=.\receive.h +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\send.h +# End Source File +# Begin Source File + +SOURCE=.\utf8.h +# End Source File +# Begin Source File + +SOURCE=.\mincrt\wsnprintf.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\halftick.ico +# End Source File +# Begin Source File + +SOURCE=.\history.ico +# End Source File +# Begin Source File + +SOURCE=.\res\history.ico +# End Source File +# Begin Source File + +SOURCE=.\notick.ico +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\SMSMSG.ico +# End Source File +# Begin Source File + +SOURCE=.\SMSNOTSENT.ico +# End Source File +# Begin Source File + +SOURCE=.\SMSSENT.ico +# End Source File +# Begin Source File + +SOURCE=.\tick.ico +# End Source File +# End Group +# End Target +# End Project diff --git a/plugins/!NotAdopted/SMS/sms.dsw b/plugins/!NotAdopted/SMS/sms.dsw new file mode 100644 index 0000000000..2bc1715ec7 --- /dev/null +++ b/plugins/!NotAdopted/SMS/sms.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "sms"=.\sms.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/plugins/!NotAdopted/SMS/sms.opt b/plugins/!NotAdopted/SMS/sms.opt new file mode 100644 index 0000000000..d32d04fb8b Binary files /dev/null and b/plugins/!NotAdopted/SMS/sms.opt differ diff --git a/plugins/!NotAdopted/SMS/sms.vcproj b/plugins/!NotAdopted/SMS/sms.vcproj new file mode 100644 index 0000000000..2b5e61d508 --- /dev/null +++ b/plugins/!NotAdopted/SMS/sms.vcproj @@ -0,0 +1,388 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/!NotAdopted/Skype/Skript1.aps b/plugins/!NotAdopted/Skype/Skript1.aps new file mode 100644 index 0000000000..d99f14a71e Binary files /dev/null and b/plugins/!NotAdopted/Skype/Skript1.aps differ diff --git a/plugins/!NotAdopted/Skype/Skript1.rc b/plugins/!NotAdopted/Skype/Skript1.rc new file mode 100644 index 0000000000..b2052187b7 --- /dev/null +++ b/plugins/!NotAdopted/Skype/Skript1.rc @@ -0,0 +1,484 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_SETAVATAR DIALOGEX 0, 0, 222, 131 +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + PUSHBUTTON "Set",IDC_SETAVATAR,10,108,45,13,WS_GROUP + PUSHBUTTON "Delete",IDC_DELETEAVATAR,57,108,45,13 + CONTROL "",IDC_AVATAR,"Static",SS_BITMAP | SS_CENTERIMAGE | + SS_SUNKEN | WS_GROUP,10,10,96,93 +END + +IDD_OPT_DEFAULT DIALOGEX 0, 0, 310, 223 +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "Start Skype with Miranda IM if not running using the following command line options:", + IDC_STARTSKYPE,"Button",BS_AUTOCHECKBOX | WS_GROUP | + WS_TABSTOP,10,4,290,10 + CONTROL "/NOSPLASH - Don't show splash screen on startup", + IDC_NOSPLASH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,17, + 264,12 + CONTROL "/MINIMIZED - Start Skype minimized",IDC_MINIMIZED, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,28,264,12 + CONTROL "/NOTRAY - Skype tray icon becomes grey and is therefore ""invisible""", + IDC_NOTRAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,40, + 264,12 + CONTROL "/REMOVEABLE - For running portable skype", + IDC_REMOVEABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,36, + 51,264,12 + CONTROL "/SECONDARY - This is the second instance",IDC_SECONDARY, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,62,264,12 + CONTROL "/DATAPATH - Specify Skype data folder*",IDC_DATAPATHO, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,36,74,264,12 + EDITTEXT IDC_DATAPATH,47,88,236,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_BROWSEDP,285,87,16,15 + CONTROL "Use custom Skype executable*",IDC_CUSTOMCOMMAND,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,36,103,264,10 + EDITTEXT IDC_COMMANDLINE,47,116,236,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_BROWSECMDL,285,115,16,15 + CTEXT "* Relative path root is Miranda IM folder", + IDC_STATIC_PATHINFO,10,136,290,8,NOT WS_GROUP + CONTROL "Shutdown Skype when you close Miranda IM",IDC_SHUTDOWN, + "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,151, + 290,10 + CONTROL "Unload Skype when you change to Offline status", + IDC_UNLOADOFFLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 10,164,290,11 + LTEXT "Try at least",IDC_STATIC,10,185,39,8 + EDITTEXT IDC_CONNATTEMPTS,52,183,21,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "times to connect to Skype API before giving up", + IDC_STATIC,78,185,224,8,NOT WS_GROUP + LTEXT "User name:",IDC_STATIC,10,206,38,8 + EDITTEXT IDC_USERNAME,52,204,79,12,ES_AUTOHSCROLL + LTEXT "Password:",IDC_STATIC,148,206,34,8 + EDITTEXT IDC_PASSWORD,186,204,79,12,ES_PASSWORD | ES_AUTOHSCROLL +END + +IDD_DIAL DIALOGEX 0, 0, 198, 46 +STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +CAPTION "Dial" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "Number:",IDC_STATIC,7,8,30,11 + COMBOBOX IDC_NUMBER,41,6,149,13,CBS_DROPDOWN | WS_VSCROLL | + WS_TABSTOP + DEFPUSHBUTTON "Dial",IDDIAL,88,25,50,14,WS_GROUP + PUSHBUTTON "Cancel",IDCANCEL,141,25,50,14 +END + +IDD_CALLSTAT DIALOGEX 0, 0, 220, 67 +STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "%s is calling" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "Join conference with %s",IDC_JOIN,"Button", + BS_AUTORADIOBUTTON | WS_GROUP,7,7,206,10 + CONTROL "Answer call; set call to %s on hold",IDC_HOLD,"Button", + BS_AUTORADIOBUTTON,7,19,206,10 + CONTROL "Hang up",IDC_HANGUP,"Button",BS_AUTORADIOBUTTON,7,31, + 206,10 + DEFPUSHBUTTON "OK",IDOK,163,46,50,14,WS_GROUP +END + +IDD_INPUTBOX DIALOGEX 0, 0, 221, 46 +STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + EDITTEXT IDC_TEXT,7,7,207,13,ES_AUTOHSCROLL | WS_GROUP + DEFPUSHBUTTON "OK",IDOK,112,25,50,14,WS_GROUP + PUSHBUTTON "Cancel",IDCANCEL,165,25,50,14 +END + +IDD_OPTIONS DIALOGEX 0, 0, 313, 249 +STYLE DS_FIXEDSYS | DS_CONTROL | DS_CENTER | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "Tab1",IDC_OPTIONSTAB,"SysTabControl32",0x0,0,-1,313,250 +END + +IDD_OPT_PROXY DIALOGEX 0, 0, 310, 223 +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "Use Skype proxy connection over network instead of local Skype API", + IDC_USES2S,"Button",BS_AUTOCHECKBOX | WS_GROUP | + WS_TABSTOP,10,4,290,9 + LTEXT "Host:",IDC_STATIC_HOST,20,21,18,10 + EDITTEXT IDC_HOST,41,19,133,12,ES_AUTOHSCROLL + LTEXT "Port:",IDC_STATIC_PORT,180,21,16,10,0,WS_EX_RIGHT + EDITTEXT IDC_PORT,200,19,29,12,ES_AUTOHSCROLL | ES_NUMBER + CTEXT "* You must restart Miranda IM in order to let the settings take effect", + IDC_STATIC_RESTART,10,54,290,8,NOT WS_GROUP + CONTROL "This Skype proxy requires password authentication:", + IDC_REQPASS,"Button",BS_AUTOCHECKBOX | WS_GROUP | + WS_TABSTOP,20,38,176,9 + EDITTEXT IDC_PASSWORD,200,36,82,12,ES_PASSWORD | ES_AUTOHSCROLL +END + +IDD_SETDETAILS DIALOGEX 0, 0, 216, 151 +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "Name:",IDC_STATIC,7,6,61,9 + EDITTEXT IDC_FULLNAME,73,4,141,12,ES_AUTOHSCROLL + LTEXT "Birthday:",IDC_STATIC,7,20,61,9 + CONTROL "DateTimePicker1",IDC_BIRTHDAY,"SysDateTimePick32", + DTS_RIGHTALIGN | DTS_APPCANPARSE | WS_TABSTOP,73,18,62, + 12 + LTEXT "Sex:",IDC_STATIC,7,34,61,9 + COMBOBOX IDC_SEX,73,32,141,12,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "City:",IDC_STATIC,7,48,61,9 + EDITTEXT IDC_CITY,73,46,141,12,ES_AUTOHSCROLL + LTEXT "Country:",IDC_STATIC,7,62,61,9 + EDITTEXT IDC_COUNTRY,73,60,141,12,ES_AUTOHSCROLL + LTEXT "Province:",IDC_STATIC,7,76,61,9 + EDITTEXT IDC_PROVINCE,73,74,141,12,ES_AUTOHSCROLL + LTEXT "Home phone:",IDC_STATIC,7,90,61,9 + EDITTEXT IDC_HOMEPHONE,73,88,141,12,ES_AUTOHSCROLL + LTEXT "Office phone:",IDC_STATIC,7,104,61,9 + EDITTEXT IDC_OFFICEPHONE,73,102,141,12,ES_AUTOHSCROLL + LTEXT "Homepage:",IDC_STATIC,7,118,61,9 + EDITTEXT IDC_HOMEPAGE,73,116,141,12,ES_AUTOHSCROLL + PUSHBUTTON "Save",IDC_SAVEDETAILS,170,134,45,14,WS_GROUP +END + +IDD_OPT_ADVANCED DIALOGEX 0, 0, 310, 223 +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "Enable Skype menu options (currently: Find/Add user)", + IDC_ENABLEMENU,"Button",BS_AUTOCHECKBOX | WS_GROUP | + WS_TABSTOP,10,4,290,9 + CONTROL "Use popup plugin for displaying messages ",IDC_USEPOPUP, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,19,290,9 + CONTROL "Suppress all error messages (not recommended, but if it annoys you... ;)", + IDC_NOERRORS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,34, + 290,9 + CONTROL "Use group chat interface for conversations (requires group chat module)", + IDC_GROUPCHAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10, + 49,290,9 + CONTROL "Mark group chat message as read to avoid notification", + IDC_GROUPCHATREAD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 10,64,290,9 + CONTROL "Keep requested online status on startup under every circumstance", + IDC_KEEPSTATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10, + 79,290,9 + CONTROL "Use time zone patch",IDC_TIMEZONE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,10,94,290,9 + CONTROL "Ignore time zones",IDC_IGNTZ,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,10,109,290,9 + CONTROL "Show default skype avatar for contacts", + IDC_SHOWDEFAULTAVATAR,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,10,124,290,9 + CONTROL "Suppress call summary chat message", + IDC_SUPPRESSCALLSUMMARYMESSAGE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,10,139,290,9 + CONTROL "Disable support for N/A and SkypeMe status (for Skype 4+)", + IDC_NOSKYPE3STATS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 10,154,290,9 + CONTROL "Show full name in contact list instead of nickname", + IDC_SHOWFULLNAME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 10,169,290,9 + LTEXT "SkypeOut contacts are in status:",IDC_STATIC,10,186,108, + 8 + COMBOBOX IDC_SKYPEOUTSTAT,120,184,79,54,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Cleanup Nicknames",IDC_CLEANUP,9,201,80,14,BS_MULTILINE | + WS_GROUP +END + +IDD_OPT_POPUP DIALOGEX 0, 0, 310, 228 +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Skype Popups",IDC_STATIC,0,1,309,227 + GROUPBOX "Incoming Calls",IDC_STATIC,6,16,297,62,WS_GROUP + CONTROL "Show incoming calls",IDC_POPUPINCOMING,"Button", + BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,28,278,8 + EDITTEXT IDC_POPUPTIME,16,41,20,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "seconds",IDC_STATIC,41,43,92,8,NOT WS_GROUP + CONTROL "",IDC_POPUPBACKCOLOR,"ColourPicker",WS_GROUP | + WS_TABSTOP,142,40,39,12 + LTEXT "Background",IDC_STATIC_POPUPBACKCOLOR,186,42,50,8, + SS_CENTERIMAGE | NOT WS_GROUP + CONTROL "Use Windows colors",IDC_USEWINCOLORS,"Button", + BS_AUTOCHECKBOX | BS_NOTIFY | BS_FLAT | WS_TABSTOP,16,58, + 121,8 + CONTROL "",IDC_POPUPTEXTCOLOR,"ColourPicker",WS_TABSTOP,142,55, + 39,12 + LTEXT "Text",IDC_STATIC_POPUPTEXTCOLOR,186,56,50,8, + SS_CENTERIMAGE | NOT WS_GROUP + PUSHBUTTON "Preview",IDC_PREVIEW,247,58,50,14,WS_GROUP + GROUPBOX "Error Messages",IDC_STATIC,6,81,297,62,WS_GROUP + CONTROL "Display error messages",IDC_POPUPERROR,"Button", + BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,94,278,8 + EDITTEXT IDC_POPUPTIMEERR,16,107,20,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "seconds",IDC_STATIC,41,109,92,8,NOT WS_GROUP + CONTROL "",IDC_POPUPBACKCOLORERR,"ColourPicker",WS_GROUP | + WS_TABSTOP,142,106,39,12 + LTEXT "Background",IDC_STATIC_POPUPBACKCOLORERR,186,108,50,8, + SS_CENTERIMAGE | NOT WS_GROUP + CONTROL "Use Windows colors",IDC_USEWINCOLORSERR,"Button", + BS_AUTOCHECKBOX | BS_NOTIFY | BS_FLAT | WS_TABSTOP,16, + 124,121,8 + CONTROL "",IDC_POPUPTEXTCOLORERR,"ColourPicker",WS_TABSTOP,142, + 121,39,12 + LTEXT "Text",IDC_STATIC_POPUPTEXTCOLORERR,186,123,50,8, + SS_CENTERIMAGE | NOT WS_GROUP + PUSHBUTTON "Preview",IDC_PREVIEWERR,247,124,50,14,WS_GROUP +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO MOVEABLE PURE +BEGIN + IDD_SETAVATAR, DIALOG + BEGIN + LEFTMARGIN, 10 + RIGHTMARGIN, 212 + TOPMARGIN, 10 + BOTTOMMARGIN, 121 + END + + IDD_OPT_DEFAULT, DIALOG + BEGIN + LEFTMARGIN, 1 + VERTGUIDE, 10 + VERTGUIDE, 300 + TOPMARGIN, 4 + END + + IDD_DIAL, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 190 + TOPMARGIN, 6 + BOTTOMMARGIN, 39 + END + + IDD_CALLSTAT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 213 + TOPMARGIN, 7 + BOTTOMMARGIN, 60 + END + + IDD_INPUTBOX, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 214 + TOPMARGIN, 7 + BOTTOMMARGIN, 39 + END + + IDD_OPTIONS, DIALOG + BEGIN + RIGHTMARGIN, 311 + BOTTOMMARGIN, 243 + END + + IDD_OPT_PROXY, DIALOG + BEGIN + LEFTMARGIN, 10 + RIGHTMARGIN, 300 + TOPMARGIN, 4 + BOTTOMMARGIN, 221 + END + + IDD_SETDETAILS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 214 + TOPMARGIN, 4 + BOTTOMMARGIN, 148 + END + + IDD_OPT_ADVANCED, DIALOG + BEGIN + LEFTMARGIN, 10 + RIGHTMARGIN, 300 + TOPMARGIN, 4 + BOTTOMMARGIN, 221 + HORZGUIDE, 4 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_SKYPE ICON DISCARDABLE "res\\skype.ico" +IDI_INVITE ICON DISCARDABLE "res\\Invite.ico" +IDI_ADD ICON DISCARDABLE "res\\add.ico" +IDI_IMPORT ICON DISCARDABLE "res\\import.ico" +IDI_ERRORS ICON DISCARDABLE "res\\error.ico" +IDI_MESSAGE ICON DISCARDABLE "res\\message.ico" +IDI_CALL ICON DISCARDABLE "res\\call.ico" +IDI_CALLSKYPEOUT ICON DISCARDABLE "res\\skypeout.ico" +IDI_HOLD ICON DISCARDABLE "res\\hold.ico" +IDI_RESUME ICON DISCARDABLE "res\\resume.ico" +IDI_HANGUP ICON DISCARDABLE "res\\hang_up.ico" +IDI_ONLINE ICON DISCARDABLE "res\\online.ico" +IDI_CHAT ICON DISCARDABLE "res\\chat.ico" +IDI_AWAY ICON DISCARDABLE "res\\away.ico" +IDI_NA ICON DISCARDABLE "res\\na.ico" +IDI_OCCUPIED ICON DISCARDABLE "res\\occupied.ico" +IDI_DND ICON DISCARDABLE "res\\dnd.ico" +IDI_INVISIBLE ICON DISCARDABLE "res\\invisible.ico" +IDI_OFFLINE ICON DISCARDABLE "res\\offline.ico" +IDI_PHONE ICON DISCARDABLE "res\\phone.ico" + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,0,0,53 + PRODUCTVERSION 0,0,0,53 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "Miranda IM community\0" + VALUE "FileDescription", "Skype\0" + VALUE "FileVersion", "0, 0, 0, 53\0" + VALUE "InternalName", "Skype\0" + VALUE "LegalCopyright", "Copyright © 2007-2011 leecher - tweety - jls17\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "Skype.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "Skype Protocol for Miranda IM\0" + VALUE "ProductVersion", "0, 0, 0, 53\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_CALL BITMAP MOVEABLE PURE "res\\call.bmp" +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// Deutsch (Цsterreich) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEA) +#ifdef _WIN32 +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN_AUSTRIAN +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE MOVEABLE PURE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE MOVEABLE PURE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE MOVEABLE PURE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Deutsch (Цsterreich) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/!NotAdopted/Skype/Skype_protocol.dsp b/plugins/!NotAdopted/Skype/Skype_protocol.dsp new file mode 100644 index 0000000000..3c9191838e --- /dev/null +++ b/plugins/!NotAdopted/Skype/Skype_protocol.dsp @@ -0,0 +1,394 @@ +# Microsoft Developer Studio Project File - Name="Skype_protocol" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** NICHT BEARBEITEN ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Skype_protocol - Win32 Debug UNICODE +!MESSAGE Dies ist kein gьltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE +!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fьhren Sie den Befehl +!MESSAGE +!MESSAGE NMAKE /f "Skype_protocol.mak". +!MESSAGE +!MESSAGE Sie kцnnen beim Ausfьhren von NMAKE eine Konfiguration angeben +!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: +!MESSAGE +!MESSAGE NMAKE /f "Skype_protocol.mak" CFG="Skype_protocol - Win32 Debug UNICODE" +!MESSAGE +!MESSAGE Fьr die Konfiguration stehen zur Auswahl: +!MESSAGE +!MESSAGE "Skype_protocol - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Skype_protocol - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Skype_protocol - Win32 Debug UNICODE" (basierend auf "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Skype_protocol - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /YX /FD /c +# SUBTRACT CPP /Fr +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0xc07 /d "NDEBUG" +# ADD RSC /l 0xc07 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib comctl32.lib Rpcrt4.lib /nologo /dll /machine:I386 /out:"../../bin/release/plugins/skype.dll" + +!ELSEIF "$(CFG)" == "Skype_protocol - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /YX /FD /GZ /c +# SUBTRACT CPP /Fr +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0xc07 /d "_DEBUG" +# ADD RSC /l 0xc07 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib comctl32.lib Rpcrt4.lib /nologo /dll /debug /machine:I386 /out:"../../../miranda-testaim/Miranda/plugins/Skype.dll" /pdbtype:sept +# SUBTRACT LINK32 /map + +!ELSEIF "$(CFG)" == "Skype_protocol - Win32 Debug UNICODE" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Skype_protocol___Win32_Debug_UNICODE" +# PROP BASE Intermediate_Dir "Skype_protocol___Win32_Debug_UNICODE" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Skype_protocol___Win32_Debug_UNICODE" +# PROP Intermediate_Dir "Skype_protocol___Win32_Debug_UNICODE" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /YX /FD /GZ /c +# SUBTRACT BASE CPP /Fr +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /D "UNICODE" /D "_UNICODE" /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0xc07 /d "_DEBUG" +# ADD RSC /l 0xc07 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib comctl32.lib Rpcrt4.lib /nologo /dll /debug /machine:I386 /out:"../../bin/debug/plugins/Skype.dll" /pdbtype:sept +# SUBTRACT BASE LINK32 /map +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib comctl32.lib Rpcrt4.lib /nologo /dll /debug /machine:I386 /out:"../../bin/debug Unicode/plugins/Skype.dll" /pdbtype:sept +# SUBTRACT LINK32 /map + +!ENDIF + +# Begin Target + +# Name "Skype_protocol - Win32 Release" +# Name "Skype_protocol - Win32 Debug" +# Name "Skype_protocol - Win32 Debug UNICODE" +# Begin Group "Quellcodedateien" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\alogon.c +# End Source File +# Begin Source File + +SOURCE=.\contacts.c +# End Source File +# Begin Source File + +SOURCE=.\debug.c +# End Source File +# Begin Source File + +SOURCE=.\gchat.c +# End Source File +# Begin Source File + +SOURCE=.\memlist.c +# End Source File +# Begin Source File + +SOURCE=.\msglist.c +# End Source File +# Begin Source File + +SOURCE=.\msgq.c +# End Source File +# Begin Source File + +SOURCE=.\pthread.c +# End Source File +# Begin Source File + +SOURCE=.\skype.c +# End Source File +# Begin Source File + +SOURCE=.\skypeapi.c +# End Source File +# Begin Source File + +SOURCE=.\skypeopt.c +# End Source File +# Begin Source File + +SOURCE=.\skypeprofile.c +# End Source File +# Begin Source File + +SOURCE=.\skypesvc.c +# End Source File +# Begin Source File + +SOURCE=.\utf8.c +# End Source File +# Begin Source File + +SOURCE=.\util.c +# End Source File +# Begin Source File + +SOURCE=.\voiceservice.c +# End Source File +# End Group +# Begin Group "Header-Dateien" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\alogon.h +# End Source File +# Begin Source File + +SOURCE=.\contacts.h +# End Source File +# Begin Source File + +SOURCE=.\debug.h +# End Source File +# Begin Source File + +SOURCE=.\gchat.h +# End Source File +# Begin Source File + +SOURCE=.\m_popup.h +# End Source File +# Begin Source File + +SOURCE=.\m_toptoolbar.h +# End Source File +# Begin Source File + +SOURCE=.\memlist.h +# End Source File +# Begin Source File + +SOURCE=.\msglist.h +# End Source File +# Begin Source File + +SOURCE=.\msgq.h +# End Source File +# Begin Source File + +SOURCE=.\pthread.h +# End Source File +# Begin Source File + +SOURCE=.\skype.h +# End Source File +# Begin Source File + +SOURCE=.\skypeapi.h +# End Source File +# Begin Source File + +SOURCE=.\skypeopt.h +# End Source File +# Begin Source File + +SOURCE=.\skypeprofile.h +# End Source File +# Begin Source File + +SOURCE=.\skypesvc.h +# End Source File +# Begin Source File + +SOURCE=.\utf8.h +# End Source File +# Begin Source File + +SOURCE=.\util.h +# End Source File +# Begin Source File + +SOURCE=.\voiceservice.h +# End Source File +# End Group +# Begin Group "Ressourcendateien" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\res\add.ico +# End Source File +# Begin Source File + +SOURCE=.\res\away.ico +# End Source File +# Begin Source File + +SOURCE=.\bitmap1.bmp +# End Source File +# Begin Source File + +SOURCE=.\res\call.bmp +# End Source File +# Begin Source File + +SOURCE=.\Call.ico +# End Source File +# Begin Source File + +SOURCE=.\res\call.ico +# End Source File +# Begin Source File + +SOURCE=.\res\chat.ico +# End Source File +# Begin Source File + +SOURCE=.\res\DND.ico +# End Source File +# Begin Source File + +SOURCE=.\res\error.ico +# End Source File +# Begin Source File + +SOURCE=.\res\hang_up.ico +# End Source File +# Begin Source File + +SOURCE=.\Hangup.ico +# End Source File +# Begin Source File + +SOURCE=.\res\hold.ico +# End Source File +# Begin Source File + +SOURCE=.\holdcall.ico +# End Source File +# Begin Source File + +SOURCE=.\icon1.ico +# End Source File +# Begin Source File + +SOURCE=.\icon2.ico +# End Source File +# Begin Source File + +SOURCE=.\res\import.ico +# End Source File +# Begin Source File + +SOURCE=.\res\invisible.ico +# End Source File +# Begin Source File + +SOURCE=.\res\Invite.ico +# End Source File +# Begin Source File + +SOURCE=.\res\message.ico +# End Source File +# Begin Source File + +SOURCE=.\res\NA.ico +# End Source File +# Begin Source File + +SOURCE=.\res\occupied.ico +# End Source File +# Begin Source File + +SOURCE=.\res\offline.ico +# End Source File +# Begin Source File + +SOURCE=.\res\online.ico +# End Source File +# Begin Source File + +SOURCE=.\res\phone.ico +# End Source File +# Begin Source File + +SOURCE=.\res\resume.ico +# End Source File +# Begin Source File + +SOURCE=.\resumecall.ico +# End Source File +# Begin Source File + +SOURCE=.\Skript1.rc +# End Source File +# Begin Source File + +SOURCE=.\res\skype.ico +# End Source File +# Begin Source File + +SOURCE=.\res\skypeout.ico +# End Source File +# End Group +# Begin Source File + +SOURCE=.\changelog.txt +# End Source File +# End Target +# End Project diff --git a/plugins/!NotAdopted/Skype/Skype_protocol.dsw b/plugins/!NotAdopted/Skype/Skype_protocol.dsw new file mode 100644 index 0000000000..3965e55d3e --- /dev/null +++ b/plugins/!NotAdopted/Skype/Skype_protocol.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELЦSCHT WERDEN! + +############################################################################### + +Project: "Skype_protocol"=.\Skype_protocol.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/plugins/!NotAdopted/Skype/Skype_protocol.mak b/plugins/!NotAdopted/Skype/Skype_protocol.mak new file mode 100644 index 0000000000..cf43334fb3 --- /dev/null +++ b/plugins/!NotAdopted/Skype/Skype_protocol.mak @@ -0,0 +1,238 @@ +!IF "$(CFG)" == "" +CFG=Win32 Debug +!MESSAGE Keine Konfiguration angegeben. Win32 Debug wird als Standard verwendet. +!ENDIF + +!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug" && "$(CFG)" != "Win64 Release" && "$(CFG)" != "Win64 Debug" && "$(CFG)" != "Win32 UNICODE Release" && "$(CFG)" != "Win32 UNICODE Debug" && "$(CFG)" != "Win64 UNICODE Release" && "$(CFG)" != "Win64 UNICODE Debug" +!MESSAGE Ungьltige Konfiguration "$(CFG)" angegeben. +!MESSAGE Sie kцnnen beim Ausfьhren von NMAKE eine Konfiguration angeben +!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: +!MESSAGE +!MESSAGE NMAKE /f "Skype_protocol.mak" CFG="Win32 Debug" +!MESSAGE +!MESSAGE Fьr die Konfiguration stehen zur Auswahl: +!MESSAGE +!MESSAGE "Win32 Release" +!MESSAGE "Win32 Debug" +!MESSAGE "Win64 Release" +!MESSAGE "Win64 Debug" +!MESSAGE "Win32 UNICODE Release" +!MESSAGE "Win32 UNICODE Debug" +!MESSAGE "Win64 UNICODE Release" +!MESSAGE "Win64 UNICODE Debug" + +!MESSAGE +!ERROR Eine ungьltige Konfiguration wurde angegeben. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe +LINK32=link.exe + +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib wsock32.lib comctl32.lib Rpcrt4.lib /nologo /dll /pdb:"$(INTDIR)\skype.pdb" /out:"$(OUTDIR)/skype.dll" /implib:"$(INTDIR)\skype.lib" + +!IF "$(CFG)" == "Win64 Release" +OUTDIR=.\Release64 +INTDIR=.\Release64 +CPP_PROJ=/nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /Fp"$(INTDIR)\Skype_protocol.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 +RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\Skript1.res" /d "NDEBUG" +!ELSEIF "$(CFG)" == "Win32 Release" +OUTDIR=.\Release +INTDIR=.\Release +CPP_PROJ=/nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /Fp"$(INTDIR)\Skype_protocol.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 +RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\Skript1.res" /d "NDEBUG" +!ELSEIF "$(CFG)" == "Win64 Debug" +OUTDIR=Debug64 +INTDIR=$(OUTDIR) +CPP_PROJ=/nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /Fp"$(INTDIR)\Skype_protocol.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c +LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 +RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\Skript1.res" /d "_DEBUG" +!ELSEIF "$(CFG)" == "Win32 Debug" +OUTDIR=.\Debug +INTDIR=$(OUTDIR) +CPP_PROJ=/nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /Fp"$(INTDIR)\Skype_protocol.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c +LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 +RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\Skript1.res" /d "_DEBUG" +!ELSEIF "$(CFG)" == "Win64 UNICODE Release" +OUTDIR=.\Release64-UNICODE +INTDIR=.\Release64-UNICODE +CPP_PROJ=/nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /D "UNICODE" /D "_UNICODE" /Fp"$(INTDIR)\Skype_protocol.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 +RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\Skript1.res" /d "NDEBUG" +!ELSEIF "$(CFG)" == "Win32 UNICODE Release" +OUTDIR=.\Release-UNICODE +INTDIR=.\Release-UNICODE +CPP_PROJ=/nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /D "UNICODE" /D "_UNICODE" /Fp"$(INTDIR)\Skype_protocol.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 +RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\Skript1.res" /d "NDEBUG" +!ELSEIF "$(CFG)" == "Win64 UNICODE Debug" +OUTDIR=Debug64-UNICODE +INTDIR=$(OUTDIR) +CPP_PROJ=/nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /D "UNICODE" /D "_UNICODE" /Fp"$(INTDIR)\Skype_protocol.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +LINK32_FLAGS= $(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 +RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\Skript1.res" /d "_DEBUG" +!ELSEIF "$(CFG)" == "Win32 UNICODE Debug" +OUTDIR=.\Debug-UNICODE +INTDIR=$(OUTDIR) +CPP_PROJ=/nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SKYPE_PROTOCOL_EXPORTS" /D "UNICODE" /D "_UNICODE" /Fp"$(INTDIR)\Skype_protocol.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c +LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 +RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\Skript1.res" /d "_DEBUG" +!ENDIF + +LINK32_OBJS= \ + "$(INTDIR)\contacts.obj" \ + "$(INTDIR)\debug.obj" \ + "$(INTDIR)\gchat.obj" \ + "$(INTDIR)\pthread.obj" \ + "$(INTDIR)\skype.obj" \ + "$(INTDIR)\skypeapi.obj" \ + "$(INTDIR)\skypeopt.obj" \ + "$(INTDIR)\skypeprofile.obj" \ + "$(INTDIR)\skypesvc.obj" \ + "$(INTDIR)\utf8.obj" \ + "$(INTDIR)\voiceservice.obj" \ + "$(INTDIR)\msglist.obj" \ + "$(INTDIR)\memlist.obj" \ + "$(INTDIR)\util.obj" \ + "$(INTDIR)\msgq.obj" \ + "$(INTDIR)\alogon.obj" \ + "$(INTDIR)\Skript1.res" + +ALL : "$(OUTDIR)\skype.dll" + + +CLEAN : + -@erase "$(INTDIR)\contacts.obj" + -@erase "$(INTDIR)\debug.obj" + -@erase "$(INTDIR)\gchat.obj" + -@erase "$(INTDIR)\pthread.obj" + -@erase "$(INTDIR)\Skript1.res" + -@erase "$(INTDIR)\skype.obj" + -@erase "$(INTDIR)\skypeapi.obj" + -@erase "$(INTDIR)\skypeopt.obj" + -@erase "$(INTDIR)\skypeprofile.obj" + -@erase "$(INTDIR)\skypesvc.obj" + -@erase "$(INTDIR)\msglist.obj" + -@erase "$(INTDIR)\memlist.obj" + -@erase "$(INTDIR)\util.obj" + -@erase "$(INTDIR)\msgq.obj" \ + -@erase "$(INTDIR)\alogon.obj" \ + -@erase "$(INTDIR)\utf8.obj" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\voiceservice.obj" + -@erase "$(INTDIR)\skype.exp" + -@erase "$(INTDIR)\skype.pdb" + -@erase "$(INTDIR)\skype.lib" + -@erase "$(OUTDIR)\skype.dll" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + + +"$(OUTDIR)\skype.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + + +!IF "$(NO_EXTERNAL_DEPS)" != "1" +!IF EXISTS("Skype_protocol.dep") +!INCLUDE "Skype_protocol.dep" +!ELSE +!MESSAGE Warning: cannot find "Skype_protocol.dep" +!ENDIF +!ENDIF + + +SOURCE=.\alogon.c + +"$(INTDIR)\alogon.obj" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\contacts.c + +"$(INTDIR)\contacts.obj" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\debug.c + +"$(INTDIR)\debug.obj" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\gchat.c + +"$(INTDIR)\gchat.obj" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\msgq.c + +"$(INTDIR)\msgq.obj" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\pthread.c + +"$(INTDIR)\pthread.obj" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\skype.c + +"$(INTDIR)\skype.obj" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\skypeapi.c + +"$(INTDIR)\skypeapi.obj" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\skypeopt.c + +"$(INTDIR)\skypeopt.obj" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\skypeprofile.c + +"$(INTDIR)\skypeprofile.obj" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\skypesvc.c + +"$(INTDIR)\skypesvc.obj" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\utf8.c + +"$(INTDIR)\utf8.obj" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\voiceservice.c + +"$(INTDIR)\voiceservice.obj" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\Skript1.rc + +"$(INTDIR)\Skript1.res" : $(SOURCE) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + diff --git a/plugins/!NotAdopted/Skype/Skype_protocol.sln b/plugins/!NotAdopted/Skype/Skype_protocol.sln new file mode 100644 index 0000000000..0ea2547268 --- /dev/null +++ b/plugins/!NotAdopted/Skype/Skype_protocol.sln @@ -0,0 +1,44 @@ +п»ї +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Skype_protocol", "Skype_protocol.vcproj", "{5F9243AE-C6C9-4F42-B670-67A97767A50B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + ANSI Debug|Win32 = ANSI Debug|Win32 + ANSI Debug|x64 = ANSI Debug|x64 + ANSI Release|Win32 = ANSI Release|Win32 + ANSI Release|x64 = ANSI Release|x64 + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + x64 Debug|Win32 = x64 Debug|Win32 + x64 Debug|x64 = x64 Debug|x64 + x64 Release|Win32 = x64 Release|Win32 + x64 Release|x64 = x64 Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.ANSI Debug|Win32.ActiveCfg = ANSI Debug|Win32 + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.ANSI Debug|Win32.Build.0 = ANSI Debug|Win32 + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.ANSI Debug|x64.ActiveCfg = ANSI Debug|x64 + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.ANSI Release|Win32.ActiveCfg = ANSI Release|Win32 + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.ANSI Release|Win32.Build.0 = ANSI Release|Win32 + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.ANSI Release|x64.ActiveCfg = ANSI Release|x64 + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.Debug|Win32.ActiveCfg = Debug|Win32 + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.Debug|Win32.Build.0 = Debug|Win32 + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.Debug|x64.ActiveCfg = Debug|x64 + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.Release|Win32.ActiveCfg = Release|Win32 + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.Release|Win32.Build.0 = Release|Win32 + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.Release|x64.ActiveCfg = Release|x64 + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.x64 Debug|Win32.ActiveCfg = x64 Debug|Win32 + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.x64 Debug|x64.ActiveCfg = x64 Debug|x64 + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.x64 Debug|x64.Build.0 = x64 Debug|x64 + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.x64 Release|Win32.ActiveCfg = x64 Release|Win32 + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.x64 Release|x64.ActiveCfg = x64 Release|x64 + {5F9243AE-C6C9-4F42-B670-67A97767A50B}.x64 Release|x64.Build.0 = x64 Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/plugins/!NotAdopted/Skype/Skype_protocol.vcproj b/plugins/!NotAdopted/Skype/Skype_protocol.vcproj new file mode 100644 index 0000000000..74e7e4bac0 --- /dev/null +++ b/plugins/!NotAdopted/Skype/Skype_protocol.vcproj @@ -0,0 +1,2843 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/!NotAdopted/Skype/alogon.c b/plugins/!NotAdopted/Skype/alogon.c new file mode 100644 index 0000000000..90c3510944 --- /dev/null +++ b/plugins/!NotAdopted/Skype/alogon.c @@ -0,0 +1,129 @@ +#include "skype.h" +#include "debug.h" + +extern char g_szProtoName[]; +extern HANDLE SkypeReady; + +/** + * Purpose: Retrieves class name from window + * + * Note: This is some sort of hack to return static local variable, + * but it works :) + */ +static const TCHAR* getClassName(HWND wnd) +{ + static TCHAR className[256]; + + *className=0; + GetClassName(wnd, &className[0], sizeof(className)/sizeof(className[0])); + return className; +} + +/** + * Purpose: Finds a window + * + * Note: This function relies on Skype window placement. + * It should work for Skype 3.x + */ +static HWND findWindow(HWND parent, const TCHAR* childClassName) +{ + // Get child window + // This window is not combo box or edit box + HWND wnd = GetWindow(parent, GW_CHILD); + while(wnd != NULL && _tcscmp(getClassName(wnd), childClassName) != 0) + wnd = GetWindow(wnd, GW_HWNDNEXT); + + return wnd; +} + +static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) +{ + DWORD dwPID; + const TCHAR *lpszClassName; + + + GetWindowThreadProcessId(hWnd,&dwPID); + if (lParam != 0 && dwPID != (DWORD)lParam) return TRUE; + lpszClassName = getClassName(hWnd); + if(_tcscmp(lpszClassName, _T("tSkMainForm.UnicodeClass")) == 0 || + _tcscmp(lpszClassName, _T("TLoginForm.UnicodeClass")) == 0) + { + HWND loginControl = GetWindow(hWnd, GW_CHILD); + + LOG(("setUserNamePasswordThread: Skype window found!")); + + // Sleep for some time, while Skype is loading + // It loads slowly :( + //Sleep(5000); + LOG (("TLoginControl = %S", getClassName(loginControl))); + + // Check for login control + if(_tcscmp(getClassName(loginControl), _T("TLoginControl")) == 0) + { + // Find user name window + HWND userName = findWindow(loginControl, _T("TNavigableTntComboBox.UnicodeClass")); + HWND password = findWindow(loginControl, _T("TNavigableTntEdit.UnicodeClass")); + + LOG (("userName=%08X; password=%08X", userName, password)); + if (userName && password) + { + // Set user name and password + DBVARIANT dbv; + + if(!DBGetContactSettingWString(NULL,SKYPE_PROTONAME,"LoginUserName",&dbv)) + { + SendMessageW(userName, WM_SETTEXT, 0, (LPARAM)dbv.pwszVal); + DBFreeVariant(&dbv); + } + + if(!DBGetContactSettingWString(NULL,SKYPE_PROTONAME,"LoginPassword",&dbv)) + { + SendMessageW(password, WM_SETTEXT, 0, (LPARAM)dbv.pwszVal); + DBFreeVariant(&dbv); + SendMessageW(password, WM_CHAR, 13, 0); + } + + + SendMessageW(hWnd, + WM_COMMAND, + 0x4a8, // sign-in button; WARNING: This ID can change during newer Skype versions + (LPARAM)findWindow(loginControl, _T("TTntButton.UnicodeClass"))); + } + return FALSE; + } + + } + return TRUE; +} + +DWORD WINAPI setUserNamePasswordThread(LPVOID lpDummy) +{ + DWORD dwPid = (DWORD)lpDummy; + HANDLE mutex = CreateMutex(NULL, TRUE, _T("setUserNamePasswordMutex")); + + // Check double entrance + if(GetLastError() == ERROR_ALREADY_EXISTS) + return 0; + + WaitForSingleObject(SkypeReady, 5000); + EnumWindows (EnumWindowsProc, dwPid); + + ReleaseMutex(mutex); + CloseHandle(mutex); + return 0; +} + +/** + * Purpose: Finds Skype window and sets user name and password. + * + * Note: This function relies on Skype window placement. + * It should work for Skype 3.x + */ +void setUserNamePassword(int dwPid) +{ + DWORD threadId; + CreateThread(NULL, 0, &setUserNamePasswordThread, (LPVOID)dwPid, 0, &threadId); + + // Give time to thread + Sleep(100); +} diff --git a/plugins/!NotAdopted/Skype/alogon.h b/plugins/!NotAdopted/Skype/alogon.h new file mode 100644 index 0000000000..00d2e7e703 --- /dev/null +++ b/plugins/!NotAdopted/Skype/alogon.h @@ -0,0 +1 @@ +void setUserNamePassword(int dwPid); diff --git a/plugins/!NotAdopted/Skype/changelog.txt b/plugins/!NotAdopted/Skype/changelog.txt new file mode 100644 index 0000000000..60526b1116 --- /dev/null +++ b/plugins/!NotAdopted/Skype/changelog.txt @@ -0,0 +1,330 @@ +NOTES +----- + + You have to manually disable popup of messages in SKYPE, as there is + currently no function in the API to do this + Got to File/Options/Instant messages and disable the checkboxes there + + +CODE +---- + Currently a real mess. At least I splitted it up a bit now. + But hey, it kinda works... ;) + +HISTORY +------- + +0.0.0.45 - ! "NA" and "Free for chat" status are available again; NA is supported by skype and Free for chat + uses skypes "Skype Me" status; better leave it that way + ! changes to the mood message of a contact were only visible after a status change + ! plugin was crashing when status changed to offline and a proxy is used + +0.0.0.44 - ! menu item "Hang up (Skype)" was show on none skype contacts + ! fixed serveral bugs in skype startup (including starting skype twice) + ! show connecting state correctly + ! hangup while ringing caused a state where contact isnt callable anymore + * removed "NA" and "Free for chat" status + +0.0.0.43 - + Added option to suppress summary chat message after call is finished (jls17) + ! Fix hangup causes a dial command if opponent hangs up a little bit earlier (jls17) + ! removed empty chat message on incoming call + ! empty mood message is send to skype correctly + + +0.0.0.42 - + Added a trick to identify skype 3 version (fingerprint) +0.0.0.41 - + Added option to enter user name and password. (Patch by NN) + +0.0.0.40 - + Support for new core service: get avatar caps + + Option to show/hide default avatar for contacts + + Hide Skype Avatar page in user details if >= #27 + +0.0.0.39 - + Voice service support in normall calls - no support for SkypeOut yet (pescuma) + ! Made options dialog a little bit smaller, removed frame and set bold frame for popups (pescuma) + + Add more status to manage for away message + +0.0.0.38 - ! Fix the load for pre 0.7.0 #17 build + * Patch by pescuma for avatar. + +0.0.0.37 - ! Avoid empty message from myself on first message received. + + Add the Get user avatar interface + * Change the get user info thread + * code cleanup + + Support for miranda 0.8 + ! Correct use of folder plugin (using "avatar cache folder"\SKYPE). + +0.0.0.36 - ! When settings skype offline, first set proto off then contacts. + * move the broadcast of status change out of if statement in status change. + * Set contacts ofline on plugin load (avoid skype contact to be online if starts skype is not checked) + ! Fix the use of datapath for portable skype + * Allow to choose no splash - no tray - minimized even if start skype with miranda is not checked. + ! Fix bug with timestamp in irc + +0.0.0.35 - * Use unicode nick, status message, city and country in skype profile. + ! Fix for sending status change when offline + * Do not send message to skype if not attached (avoid trying to connect to api at startup) + ! Fix crash on recieving message with groupchat checked. + +0.0.0.34 - + Try to identify if chat message comes from a group chat or not + + Add a option to flag group chat message as read if not using chat.dll for group chat. + ! Fix the check of message type (group chat or normal) + +0.0.0.33 - ! Fix for flags of event and metacontact (thanks SJE) + * Next step to custom popup support (in popup option page) + ! Fix infinite for error popup + +0.0.0.32 - ! Improvemnt of the Action message support. + ! Fix empty message on first chat with a contact. + +0.0.0.31 - + First step to Action Message support ( /me ) + + Updater support for File Listing. + + First step to a custom popup for call notification. + +0.0.0.30 - + Add an option to enable/disable the timezone patch + +0.0.0.29 - ! Try to fix the bug (set skype offline when closing miranda) + +0.0.0.28 - * Improved portable skype integration + +0.0.0.27 - * Try to fix the start using custom command line + + Close skype using custom command line too + +0.0.0.26 - + Add a way to use a custom command line to start skype. + +0.0.0.25 - ! patch from markcs about timezones. + ! shutdown patch by sje + +0.0.0.24 - * Change options dialog (use tabsrmm uxtheme) + +0.0.0.23 - ! Wrong db entry name for cellular (cellucar) + + Set mirver using is video capabale to identify skype 2.0 user + +0.0.0.22 - * Options page redesigned + * Work around to force refresh of avatar in MyDetail (w8 the avatar change service) + * Change Skype protocol to Skype in options->Network + * Free buffer in status message retrieve + * First step to a details info page. + +0.0.0.21 - * Some minor bugfixes + * Severe bugfix: Message sending routine worked incorrectly (no errors were shown + even if there were sending-errors) + * Removed PingPong - thread in favour of WM_TIMER + * Fixed critical section unlocking in skypeapi.c. In certain cases, critical sections + were not left correctly. + * Fixed a bug that caused Miranda to crash on exit with Newstatusnotify plugin + (thanks to TioDuke for reporting) + * Hopefully fixed the nasty bug that caused Miranda to lockup on exit. + +0.0.0.20 - * Split service and options in two new cpp file. + * Put the default attemps number to 10 + +0.0.0.19 - * Add avatar support for own user only (no api to ge contacts avatar) + * Add set status message. + * Add Get status message for contact where viewing contact details + * Change icons (thanks to Faith Healer) + * Updater support (BETA ONLY) + * DBeEditor known module support + * Mods to avoid warning in VC++ 8 + * Implement the MyDetail requested services + +0.0.0.18 - * HOTFIX - Double File-Transfer icon removed. Please note that you can't send files + via drag & drop, because of the nature of Skype API - Skype wants to open its own + "File/Open" dialog, so I cannot supply a path to the file to be sent, therefore I + had to add a seperate File-sending function rather than using Miranda's function. + +0.0.0.17 - * Startup of Skype in a seperate thread was not solved properly. Now it should really + start in background + * The hack for the statusmode-bug is optional in the settings and is turned off + per default. (Thx to Eddie Hung for reporting problems and help) + * Added an ugly hack for the Skype-API offline bug (grr.. ) + * Nickname is now set correctly. To cleanup the existing Nicks, please go to + the options page an push the "Cleanup Nicknames" button. + This will clean out entries where the Nick was set to the Skype handle + * Fixed a bug in the message sending routine that caused errors in communication + (missed messages in Skype that were not fetched..) + * Added "Hold call" feature while calling + * Added support for conference calls (if a second user is calling while you + are in a conversation, you can now choose whether to block the call or let + the user join you in a conference with the existing caller or to put the + other caller on hold) + * Fixed a bug in the code for adding users that were just searched via the + Skype search-window but never have been in contact list. + * Fixed some bugs (memleak, nick error, ..) in the Search-Routine for + Skype-contacts. (thx to Deadman for reporting) + * Fixed a bug with unknown SKYPE_IN contacts + * Added file-sending capability (requires new Skype-version) + * Did a litte code-cleanup + * Adding / Removing contacts can now be done via the Miranda standard-dialogs if + you use the newest Skype-Version + * With the new Skype-version you are able to handle Authorisation-Requests via Miranda + now. + +0.0.0.16 - * Fixed a severe memory-allocation bug in utf8-encoded messages that caused random + crashes (oops :-O) - Thanks to Ary Dvoretz for reporting. + * Bug in SkypeStatusMode-Bug fix from last release fixed (protocol stayed offline) + * Now onlinestatus for SkypeOut-Contacts is configurable + * Made Menu-Options translatable + * Added support for calling SkypeOut-Phonenumbers. You can now dial a PSTN-Number + by calling "Do a SkypeOut call" in the main menu (or top toolbar if the + toptoolbar plugin is installed) and entering a number or + by right-clicking on a non-Skype contact and selecting "Call using SkypeOut", + if there is a phone-Number entry in the User's-Details. + This, of course, is only working if you have SkypeOut privilege + +0.0.0.15 - * Fixed a crash on Miranda-exit when error occured on Skype-Protocol start + * Fixed Bug #0000006: Now user is asked if he wants to enable the Protocol + for the current profile, if he starts with a new profile. + * Fixed Bug #0000002: Now interfacing with Skype is really stopped on going + offline if the option is enabled. (PingPong-thread killed) + - This also applies on closing Skype + * Fixed a memory leak in MsgFetchThread that appeared in the last version because + of the groupchat-implementation (free() within wrong if clause, ooops ;) + * Fixed Bug #0000005: When there is a msg from a user that is not on Skype's contact + list, the user is now added PALF_TEMPORARY and disappears again on next Miranda-start + * Implemented a fix for Skype API's statusmode bug reported by Markus Mьtzel: + If you change the online status while Skype is still connecting, Skype changes to + the FIRST state that it was requested to change to, after going online, instead of + the LAST state. However the bug was not reproducable for me. + * Fixed broken popup-support (I hope) + * CHANGE of behaviour (inspired by Bug #0000007): + If you turn off "Start Skype with Miranda", the plugin wouldn't search for a + running Skype instance anymore. + * Now when going online and Skype is not launched, Skype will be launched via a + seperate thread (in background) so that Miranda isn't blocked while Skype is loading + * Options Dlg. should now be translateable too. + +0.0.0.14 - + * Miranda crash on exit if Skype was not found installed should be + fixed by now. + * Implemented compatibility layer for Skype API Protocol V3 and above. + * Removed some useless code introduced in 0.0.0.12 + * Added some fixes made by TioDuke (thank you!) + - Using your own Nick instead of your Skype-Handle in conversations + - LastName 3rd token & above are not ignored any more + - Status modes "On the phone" and "out to lunch" are mapped now + * Fixed a bug that caused "Skype API not available" messages under high load. + (thanks to Romeo28 for testing!) + * Fixed a bug that caused Message sending thread to wait forever if sending + a message times out (causing dead threads) + * Skype contact list should be synced now when Skype-Status changes. + (thx to Markus Mьtzel for Bugreport) + * Implemented a garbage collector that removes old messages from queue + in order to prevent possible memory exhaustion + * Added option to disable all modal Error-message dialog boxes (as people + keep telling me that they are annoyed by them) + * Added langpack support for error messages + * Added option to increase the time the protocol is waiting for Skype + * Added groupchat functions. WARNING: For testing purposes only! + Currently there is a memleak which I cannot find, but even worse, + Skype API doesn't seem to support sending to a groupchat, inviting etc. + So this is currently only experimental! When you send to a groupchat you + currently send single messages to every user seperately. Skype staff + didn't answer my question about sending to groupchats so far, so it + depends on them when this feature will be available for real use. + +0.0.0.13 - A few minor fixes: + * Logging off users shouldn't flood the StatusNotify-Plugin now. + * Popup-plugin can be enabled/disabled in the options dlg. + * Implemented support for SkypeOut contacts (they caused crashes) + * Now using Nick instead of Skype-Handle as Contact list name on + adding new users, if it is available. + +0.0.0.12 - Bugfixing because of strange Skype API behaviour: + * Adding of contacts that are just searched, but not added in Skype + should be prevented now. + * Version number correct again. + +0.0.0.11 - Only minor bugfixes: + * The gender in user-details is now saved correctly to the DB + (thanks to LeON for the hint!) + * The Apply-Button should now be disabled in the options DLG by default + (thanks to sje for the bug report) + * Contactlist should be reinitialized after a SYNC-Problem now. + * Bug with usernames that contain commas should be fixed + * Protocol messages are now shown as popups if Popup-plugin is installed + +0.0.0.10 - * Hopefully recovery after sync problem works a bit better now + (Sync-Problem Messages are no longer shown) + * Now you can hang up a call directly from a contact's context menu + * Now implemented support for using Skype over a network. You can use + the included skypeproxy service to in/output Skype API messages + on a socket and can connect to it with the plugin. + So you can, for example, launch the skypeproxy service on your + Windows-server (eeek! :P) and control Skype from your workstation + using Miranda. (requested feature by foosmate) + * Now you can accept incoming calls via Miranda (or hang them up) + * The status mode bug (clist status menu was not updated properly) + should be fixed by now. + * The logfile in the dbeug-build should now always be written to the + Miranda directory. + +0.0.0.9 - * Fixed bug with error when starting Skype with Miranda ("Wheee...") + * As Skype seems to use new, UNDOCUMENTED Message types (I think it's + a severe Skype-API bug) I adapted the plugin so that it works + with new API now. This fixes the problem of not being able to receive + messages in new Skype versions. + Skype now sends "MESSAGE TYPE SAID" instead of "MESSAGE TYPE TEXT", + the bug has been reported to Skype forum. + (http://forum.skype.com/viewtopic.php?t=15435) + * Fixed a memory leak in Message-receiving routine + * Added UTF8-support for Contact properties (does this fix something?) + * Fixed a memory leak in Startup-routine + * Finally renamed Plugin from SKYPE_PROTOCOL to SKYPE internally. + Hopefully it will upgrade your existing DB seamlessly. + * Now all threads should be sync with Miranda as I'm using the pthread- + functions "borrowed" from Yahoo protocol. + +0.0.0.8 - * Now there is support for the "Occupied" mode, which is mapped to DND + This is useful for users who do a global statusmodechange so that Skype + gets to "Occupied" state instead of staying online. + * Now the protocol doesn't disable itself when you chose to not start + Skype on startup, instead it stays offline and starts Skype when you + try to go online. + +0.0.0.7 - * Fixed a bug that caused a lockup on Plugin startup (when a Window was not + reacting to the HWND_BROADCAST) (thx to Cool Blue) + * Fixed a bug in the Startup-procedure.. + * Now Skype doesn't go offline when you close Miranda (thx to Egodust) + * Now it should really work unter WIN98 (thx to TioDuke for testing) + * Implemented feature for Shutting down Skype on going offline and + restarting Skype on changing to online mode again, as many people requested. + +0.0.0.6 - * Added feature requests from kreisquadratur: + * Option to disable Skype-Menuitems + * Fixed bug with Apply-Button + * Using a nicer Skype-Icon now + * Now using Skype-Timestamp for messages + * Implementing importing history from skype (see contextmenu of contact) + * Fixed bug with processing first message of MESSAGES - List + * Found out, that RegisterClass() doesn't work for UNICODE-Programs on + non-UNICODE win98, therefore return-value check for RegisterClass removed + * Fixed a bug that caused a "We got a Sync problem :(" + +0.0.0.5 - * Fixed a bug that caused the plugin to crash with bigger contact lists + (Skype API was flooded on startup) + +0.0.0.4 - * Missed messages are fetched now + * User details work now + * More verbose error msgs now (to help Win98 user debugging his problem) + * Added option for starting skype with miranda and shutting down + Skype when closing miranda. + * You can now chose the command line options to pass to Skype on startup + * Hopefully the bug with multiple Call - Entries per user is fixed now + * Protocol name is now "Skype", not "Skype_protocol" - Remember this + when updating, so DELETE skype_protocol.dll first!! + * Secured Message Queue with a Mutex + * Fixed a Message-receiving bug that could cause delays in message-processing + * Adding a Contact in Skype now also adds it to Miranda immediately + (Deleting should also work, but doesn't because of a Skype API bug) + * Added searching for contacts, but this feature seems to be quite useless, + as Skype API doesn't support adding contacts, so you still have to add + your contacts in the Skype program, sorry + In order to do this comfortably, I added a Miranda Menu-Item for adding + Skype-contacts. + +0.0.0.3 - * I hope it's thread-safe now + * Changing the Online-Status should work correctly now + * Fixed "We got a sync problem :(" bug - big thx to Azzie + * Now starts Skype more in the background as proposed by Kreisquadratur + * Implemented PING-PONG with Skype to detect if Connection to Skype API + was lost + * Launching of Skype by Miranda improved diff --git a/plugins/!NotAdopted/Skype/contacts.c b/plugins/!NotAdopted/Skype/contacts.c new file mode 100644 index 0000000000..c83d3294a1 --- /dev/null +++ b/plugins/!NotAdopted/Skype/contacts.c @@ -0,0 +1,417 @@ +/* + * Contactlist management functions + */ + +#include "skype.h" +#include "skypeapi.h" +#include "debug.h" +#include "pthread.h" +#include "gchat.h" +#include "voiceservice.h" + +#pragma warning (push) +#pragma warning (disable: 4100) // unreferenced formal parameter +#include "../../include/m_langpack.h" +#pragma warning (pop) + +#pragma warning (disable: 4706) // assignment within conditional expression + +// Imported Globals +extern HINSTANCE hInst; +extern BOOL bSkypeOut, bIsImoproxy; +extern char protocol, g_szProtoName[]; + +// Handles +static HANDLE hMenuCallItem, hMenuCallHangup, hMenuSkypeOutCallItem, hMenuHoldCallItem, hMenuFileTransferItem, hMenuChatInitItem; + +// Check if alpha blending icons are supported +// Seems to be not neccessary +/* +BOOL SupportAlphaIcons(void) { + HANDLE hMod; + DLLVERSIONINFO tDVI={0}; + BOOL retval=FALSE; + FARPROC pDllGetVersion; + + if (!(hMod=LoadLibrary("comctl32.dll"))) return FALSE; + if (pDllGetVersion=GetProcAddress(hMod, "DllGetVersion")) { + tDVI.cbSize=sizeof(tDVI); + if (!pDllGetVersion ((DLLVERSIONINFO *)&tDVI)) { + if (GetDeviceCaps(GetDC(NULL), BITSPIXEL)*GetDeviceCaps(GetDC(NULL), PLANES)>=32 && + tDVI.dwMajorVersion>=6) + retval=TRUE; + } + } + FreeLibrary(hMod); + return retval; +} +*/ + +CLISTMENUITEM CallItem(void) { + CLISTMENUITEM mi={0}; + + mi.cbSize=sizeof(mi); + mi.position=-2000005000; + mi.flags=CMIF_NOTOFFLINE|CMIF_TCHAR; + mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALL)); + mi.pszContactOwner=SKYPE_PROTONAME; + mi.ptszName=LPGENT("Call (Skype)"); + mi.pszService=SKYPE_CALL; + + return mi; +} + +CLISTMENUITEM SkypeOutCallItem(void) { + CLISTMENUITEM mi={0}; + + mi.cbSize=sizeof(mi); + mi.position=-2000005000; + mi.flags=CMIF_HIDDEN|CMIF_TCHAR; + mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALLSKYPEOUT)); + mi.ptszName=LPGENT("Call using SkypeOut"); + mi.pszService=SKYPEOUT_CALL; + + return mi; +} + +CLISTMENUITEM HupItem(void) { + CLISTMENUITEM mi={0}; + + mi.cbSize=sizeof(mi); + mi.position=-2000005000; + mi.flags=CMIF_NOTOFFLINE|CMIF_TCHAR; + mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_HANGUP)); + mi.pszContactOwner=SKYPE_PROTONAME; + mi.ptszName=LPGENT("Hang up call (Skype)"); + mi.pszService=SKYPE_CALLHANGUP; + + return mi; +} + +CLISTMENUITEM SkypeOutHupItem(void) { + CLISTMENUITEM mi={0}; + + mi.cbSize=sizeof(mi); + mi.position=-2000005000; + mi.flags=CMIF_TCHAR; + mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_HANGUP)); + mi.ptszName=LPGENT("Hang up SkypeOut call"); + mi.pszService=SKYPEOUT_CALL; + return mi; +} + +CLISTMENUITEM HoldCallItem(void) { + CLISTMENUITEM mi={0}; + + mi.cbSize=sizeof(mi); + mi.position=-2000005000; + mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; + mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_HOLD)); + mi.ptszName=LPGENT("Hold call"); + mi.pszService=SKYPE_HOLDCALL; + return mi; +} + +CLISTMENUITEM ResumeCallItem(void) { + CLISTMENUITEM mi={0}; + + mi.cbSize=sizeof(mi); + mi.position=-2000005000; + mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; + mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_RESUME)); + mi.ptszName=LPGENT("Resume call"); + mi.pszService=SKYPE_HOLDCALL; + return mi; +} + +CLISTMENUITEM FileTransferItem(void) { + CLISTMENUITEM mi={0}; + + // Stolen from file.c of Miranda core + mi.cbSize=sizeof(mi); + mi.position=-2000020000; + mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; + mi.hIcon=LoadSkinnedIcon(SKINICON_EVENT_FILE); + mi.ptszName=LPGENT("&File"); + mi.pszContactOwner=SKYPE_PROTONAME; + mi.pszService=SKYPE_SENDFILE; + return mi; +} + +CLISTMENUITEM ChatInitItem(void) { + CLISTMENUITEM mi={0}; + + mi.cbSize=sizeof(mi); + mi.position=-2000020000; + mi.flags=CMIF_HIDDEN|CMIF_NOTOFFLINE|CMIF_TCHAR; + mi.hIcon=LoadIcon( hInst, MAKEINTRESOURCE( IDI_INVITE )); + mi.ptszName=LPGENT("&Open groupchat"); + mi.pszContactOwner=SKYPE_PROTONAME; + mi.pszService=SKYPE_CHATNEW; + return mi; +} + +HANDLE add_contextmenu(HANDLE hContact) { + CLISTMENUITEM mi; + + UNREFERENCED_PARAMETER(hContact); + + if (!HasVoiceService()) { + mi=CallItem(); + hMenuCallItem=(HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0,(LPARAM)&mi); + mi=HupItem(); + hMenuCallHangup=(HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi); + } + + mi=SkypeOutCallItem(); + hMenuSkypeOutCallItem=(HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0,(LPARAM)&mi); + + if (!HasVoiceService()) { + mi=HoldCallItem(); + hMenuHoldCallItem=(HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0,(LPARAM)&mi); + } + + // We cannot use flag PF1_FILESEND for sending files, as Skype opens its own + // sendfile-Dialog. + mi=FileTransferItem(); + hMenuFileTransferItem=(HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0,(LPARAM)&mi); + + mi=ChatInitItem(); + hMenuChatInitItem=(HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0,(LPARAM)&mi); + + + ZeroMemory(&mi,sizeof(mi)); + mi.cbSize=sizeof(mi); + mi.position=-2000005000; + mi.flags=CMIF_TCHAR; + mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_IMPORT)); + mi.pszContactOwner=SKYPE_PROTONAME; + mi.ptszName=LPGENT("Import Skype history"); + mi.pszService=SKYPE_IMPORTHISTORY; + return (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0,(LPARAM)&mi); +} + +HANDLE add_mainmenu(void) { + CLISTMENUITEM mi={0}; + + mi.cbSize=sizeof(mi); + mi.position=-2000005000; + mi.flags=CMIF_TCHAR; + mi.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_ADD)); + mi.pszContactOwner=SKYPE_PROTONAME; + mi.ptszName=LPGENT("Add Skype contact"); + mi.pszService=SKYPE_ADDUSER; + return (HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM, (WPARAM)NULL,(LPARAM)&mi); + +} + +int __cdecl PrebuildContactMenu(WPARAM wParam, LPARAM lParam) { + DBVARIANT dbv; + CLISTMENUITEM mi; + char *szProto; + BOOL callAvailable = FALSE; + BOOL hangupAvailable = FALSE; + + UNREFERENCED_PARAMETER(lParam); + + if (!(szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0))) return 0; + + if (!HasVoiceService()) { + // Clear hold-Item in case it exists + mi=HoldCallItem(); + mi.flags|=CMIM_ALL; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuHoldCallItem,(LPARAM)&mi); + } + + if (!strcmp(szProto, SKYPE_PROTONAME)) { + if (!HasVoiceService()) { + if (!DBGetContactSetting((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { + if (DBGetContactSettingByte((HANDLE)wParam, SKYPE_PROTONAME, "OnHold", 0)) + mi=ResumeCallItem(); else mi=HoldCallItem(); + mi.flags=CMIM_ALL; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuHoldCallItem,(LPARAM)&mi); + + callAvailable = FALSE; + hangupAvailable = TRUE; + + DBFreeVariant(&dbv); + } else { callAvailable = TRUE; hangupAvailable = FALSE; } + + if (DBGetContactSettingByte((HANDLE)wParam, SKYPE_PROTONAME, "ChatRoom", 0)!=0) { + callAvailable = FALSE; + hangupAvailable = FALSE; + } + + mi = CallItem(); + mi.flags |= CMIM_ALL | (!callAvailable?CMIF_HIDDEN:0); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuCallItem,(LPARAM)&mi); + + mi = HupItem(); + mi.flags |= CMIM_ALL | (!hangupAvailable?CMIF_HIDDEN:0); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuCallHangup,(LPARAM)&mi); + } + + // Clear SkypeOut menu in case it exists + mi=SkypeOutCallItem(); + mi.flags|=CMIM_ALL; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuSkypeOutCallItem,(LPARAM)&mi); + + // File sending and groupchat-creation works starting with protocol version 5 + if (protocol>=5) { + mi=FileTransferItem(); + if (DBGetContactSettingByte((HANDLE)wParam, SKYPE_PROTONAME, "ChatRoom", 0)==0) + mi.flags ^= CMIF_HIDDEN; + mi.flags |= CMIM_FLAGS; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuFileTransferItem,(LPARAM)&mi); + + mi=ChatInitItem(); + if (DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseGroupchat", 0) && + DBGetContactSettingByte((HANDLE)wParam, SKYPE_PROTONAME, "ChatRoom", 0)==0) + mi.flags ^= CMIF_HIDDEN; + mi.flags |= CMIM_FLAGS; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuChatInitItem,(LPARAM)&mi); + } + + } else if (bSkypeOut) { + if (!DBGetContactSetting((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { + mi=SkypeOutHupItem(); + DBFreeVariant(&dbv); + } else { + mi=SkypeOutCallItem(); + if(!DBGetContactSetting((HANDLE)wParam,"UserInfo","MyPhone0",&dbv)) { + DBFreeVariant(&dbv); + mi.flags=0; + } + } + mi.flags|=CMIM_ALL; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)(HANDLE)hMenuSkypeOutCallItem,(LPARAM)&mi); + } + + return 0; +} + +/* +int ClistDblClick(WPARAM wParam, LPARAM lParam) { + char *szProto; + + szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, wParam, 0 ); + if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && + DBGetContactSettingWord((HANDLE)wParam, SKYPE_PROTONAME, "Status", ID_STATUS_OFFLINE)==ID_STATUS_ONTHEPHONE) { + SkypeCall(wParam, 0); + } + + return 0; +} +*/ + +HANDLE find_contact(char *name) { + char *szProto; + int tCompareResult; + HANDLE hContact; + DBVARIANT dbv; + + // already on list? + for (hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);hContact != NULL;hContact=(HANDLE)CallService( MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) + { + szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0 ); + if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && DBGetContactSettingByte(hContact, SKYPE_PROTONAME, "ChatRoom", 0)==0) + { + if (DBGetContactSettingString(hContact, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) continue; + tCompareResult = strcmp(dbv.pszVal, name); + DBFreeVariant(&dbv); + if (tCompareResult) continue; + return hContact; // already there, return handle + } + } + return NULL; +} +HANDLE find_contactT(TCHAR *name) { + char *szProto; + int tCompareResult; + HANDLE hContact; + DBVARIANT dbv; + + // already on list? + for (hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);hContact != NULL;hContact=(HANDLE)CallService( MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) + { + szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0 ); + if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && DBGetContactSettingByte(hContact, SKYPE_PROTONAME, "ChatRoom", 0)==0) + { + if (DBGetContactSettingTString(hContact, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) continue; + tCompareResult = _tcscmp(dbv.ptszVal, name); + DBFreeVariant(&dbv); + if (tCompareResult) continue; + return hContact; // already there, return handle + } + } + return NULL; +} + + +HANDLE add_contact(char *name, DWORD flags) { + HANDLE hContact; + + // already on list? + if (hContact=find_contact(name)) { + if (!(flags & PALF_TEMPORARY) && DBGetContactSettingByte(hContact, "CList", "NotOnList", 1)) { + DBDeleteContactSetting( hContact, "CList", "NotOnList" ); + DBDeleteContactSetting( hContact, "CList", "Hidden" ); + } + LOG(("add_contact: Found %s", name)); + return hContact; // already there, return handle + } + // no, so add + + LOG(("add_contact: Adding %s", name)); + hContact=(HANDLE)CallServiceSync(MS_DB_CONTACT_ADD, 0, 0); + if (hContact) { + if (CallServiceSync(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact,(LPARAM)SKYPE_PROTONAME)!=0) { + LOG(("add_contact: Ouch! MS_PROTO_ADDTOCONTACT failed for some reason")); + CallServiceSync(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0); + return NULL; + } + if (name[0]) DBWriteContactSettingString(hContact, SKYPE_PROTONAME, SKYPE_NAME, name); + + if (flags & PALF_TEMPORARY ) { + DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1); + DBWriteContactSettingByte(hContact, "CList", "Hidden", 1); + } + if (name[0]) { + SkypeSend("GET USER %s DISPLAYNAME", name); + } else {LOG(("add_contact: Info: The contact added has no name."));} + } else {LOG(("add_contact: Ouch! MS_DB_CONTACT_ADD failed for some reason"));} + LOG(("add_contact succeeded")); + return hContact; +} + +void logoff_contacts(BOOL bCleanup) { + HANDLE hContact; + char *szProto; + DBVARIANT dbv={0}; + + LOG(("logoff_contacts: Logging off contacts.")); + for (hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);hContact != NULL;hContact=(HANDLE)CallService( MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) { + szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0 ); + if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME)) + { + if (DBGetContactSettingWord(hContact, SKYPE_PROTONAME, "Status", ID_STATUS_OFFLINE)!=ID_STATUS_OFFLINE) + DBWriteContactSettingWord(hContact, SKYPE_PROTONAME, "Status", ID_STATUS_OFFLINE); + + DBDeleteContactSetting(hContact, SKYPE_PROTONAME, "CallId"); + if (DBGetContactSettingByte(hContact, SKYPE_PROTONAME, "ChatRoom", 0)==1) + { + if (DBGetContactSettingTString(hContact, SKYPE_PROTONAME, "ChatRoomID", &dbv)) continue; + RemChat (dbv.ptszVal); + DBFreeVariant(&dbv); + } + if (DBGetContactSettingString(hContact, SKYPE_PROTONAME, "Typing_Stream", &dbv) == 0) + { + if (bCleanup) SkypeSend ("ALTER APPLICATION libpurple_typing DISCONNECT %s", dbv.pszVal); + DBFreeVariant(&dbv); + DBDeleteContactSetting(hContact, SKYPE_PROTONAME, "Typing_Stream"); + } + + } + } + if (bCleanup && (protocol>=5 || bIsImoproxy)) SkypeSend ("DELETE APPLICATION libpurple_typing"); +} diff --git a/plugins/!NotAdopted/Skype/contacts.h b/plugins/!NotAdopted/Skype/contacts.h new file mode 100644 index 0000000000..35a400c3e9 --- /dev/null +++ b/plugins/!NotAdopted/Skype/contacts.h @@ -0,0 +1,11 @@ +// Prototypes +HANDLE add_contextmenu(HANDLE hContact); +HANDLE find_contact(char *name); +HANDLE find_contactT(TCHAR *name); +HANDLE add_contact(char *name, DWORD flags); +HANDLE add_mainmenu(void); +CLISTMENUITEM HupItem(void); +CLISTMENUITEM CallItem(void); +void logoff_contacts(BOOL bCleanup); +int PrebuildContactMenu(WPARAM, LPARAM); +//int ClistDblClick(WPARAM, LPARAM); \ No newline at end of file diff --git a/plugins/!NotAdopted/Skype/debug.c b/plugins/!NotAdopted/Skype/debug.c new file mode 100644 index 0000000000..a1267d8d8a --- /dev/null +++ b/plugins/!NotAdopted/Skype/debug.c @@ -0,0 +1,75 @@ +#ifndef _DEBUG +#pragma warning (disable: 4206) // nonstandard extension used : translation unit is empty +#else +#include "debug.h" + +#define WIN32_LEAN_AND_MEAN +//#include +#include +//#include +#include "skype.h" +#include +#include + +#define INITBUF 1024 /* Initial size of buffer */ + +#pragma warning (disable: 4706) // assignment within conditional expression + +extern char g_szProtoName[]; + +static CRITICAL_SECTION m_WriteFileMutex; +static FILE *m_fpLogFile = INVALID_HANDLE_VALUE; +static char *m_szLogBuf = NULL; +static DWORD m_iBufSize = 0; + +void init_debug(void) { + char *p; + char logfile[MAX_PATH]; + + ZeroMemory(logfile, sizeof(logfile)); + p=logfile+GetModuleFileNameA(NULL, logfile, sizeof(logfile)); + if (!(p=strrchr (logfile, '\\'))) p=logfile; else p++; + sprintf (p, "%s_log.txt", SKYPE_PROTONAME); + m_szLogBuf = calloc (1, (m_iBufSize = INITBUF)); + m_fpLogFile = fopen(logfile, "a"); + InitializeCriticalSection(&m_WriteFileMutex); +} + +void end_debug (void) { + if (m_szLogBuf) free (m_szLogBuf); + if (m_fpLogFile) fclose (m_fpLogFile); + DeleteCriticalSection(&m_WriteFileMutex); +} + +void do_log(const char *pszFormat, ...) { + char *ct, *pNewBuf; + va_list ap; + time_t lt; + int iLen; + + if (!m_szLogBuf || !m_fpLogFile) return; + EnterCriticalSection(&m_WriteFileMutex); + time(<); + ct=ctime(<); + ct[strlen(ct)-1]=0; + do + { + va_start(ap, pszFormat); + iLen = _vsnprintf(m_szLogBuf, m_iBufSize, pszFormat, ap); + va_end(ap); + if (iLen == -1) + { + if (!(pNewBuf = (char*)realloc (m_szLogBuf, m_iBufSize*2))) + { + iLen = strlen (m_szLogBuf); + break; + } + m_szLogBuf = pNewBuf; + m_iBufSize*=2; + } + } while (iLen == -1); + fprintf (m_fpLogFile, sizeof(time_t) == sizeof(int) ? "%s (%ld) [%08X] %s\n" : "%s (%lld) [%08X] %s\n", ct, lt, GetCurrentThreadId(), m_szLogBuf); + fflush (m_fpLogFile); + LeaveCriticalSection(&m_WriteFileMutex); +} +#endif \ No newline at end of file diff --git a/plugins/!NotAdopted/Skype/debug.h b/plugins/!NotAdopted/Skype/debug.h new file mode 100644 index 0000000000..9582246251 --- /dev/null +++ b/plugins/!NotAdopted/Skype/debug.h @@ -0,0 +1,23 @@ +//#define DEBUG_RELEASE 1 + +#ifdef DEBUG_RELEASE + #define _DEBUG 1 +#endif + +#ifdef _DEBUG + void init_debug(void); + void end_debug (void); + void do_log(const char *pszFormat, ...); + #define DEBUG_OUT(a) OUTPUT(a) + #define TRACE(a) OutputDebugString(a) + #define TRACEA(a) OutputDebugStringA(a) + #define TRACEW(a) OutputDebugStringW(a) + #define LOG(a) do_log a +#else + #define DEBUG_OUT(a) + #define LOG(a) + #define TRACE(a) + #define TRACEA(a) + #define TRACEW(a) +#endif + diff --git a/plugins/!NotAdopted/Skype/deploy.bat b/plugins/!NotAdopted/Skype/deploy.bat new file mode 100644 index 0000000000..eee9e164d1 --- /dev/null +++ b/plugins/!NotAdopted/Skype/deploy.bat @@ -0,0 +1,15 @@ +@echo off +set PATH=%PATH%;C:\Programme\WinRAR +echo Deploying.. +winrar a -apPlugins -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol.zip Release\skype.dll +rem There is no ANSI x64 Build +rem winrar a -apPlugins -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_x64.zip Release64\skype.dll +winrar a -apPlugins -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_unicode.zip Release-UNICODE\skype.dll +winrar a -apPlugins -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_unicode_x64.zip Release64-UNICODE\skype.dll + +winrar a -apDebug -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_debug.zip Debug\skype.pdb +winrar a -apDebug\Plugins -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_debug.zip Debug\skype.dll +winrar a -apDebug64-UNICODE -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_debug.zip Debug64-UNICODE\skype.pdb +winrar a -apDebug64-UNICODE\Plugins -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_debug.zip Debug64-UNICODE\skype.dll +winrar a -apDebug-UNICODE -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_debug.zip Debug-UNICODE\skype.pdb +winrar a -apDebug-UNICODE\Plugins -ep1 \\linux01\leecher\webserver\Skype\Skype_protocol_debug.zip Debug-UNICODE\skype.dll diff --git a/plugins/!NotAdopted/Skype/ezxml/ezxml.c b/plugins/!NotAdopted/Skype/ezxml/ezxml.c new file mode 100644 index 0000000000..24c02fbd70 --- /dev/null +++ b/plugins/!NotAdopted/Skype/ezxml/ezxml.c @@ -0,0 +1,1033 @@ +/* ezxml.c + * + * Copyright 2004-2006 Aaron Voisine + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#if defined(WIN32) || defined(_WIN32) +#include +#ifndef EZXML_NOMMAP +#define EZXML_NOMMAP +#endif +#endif + +#include +#include +#include +#include +#include +#if !defined(WIN32) && !defined(_WIN32) +#include +#endif +#include +#ifndef EZXML_NOMMAP +#include +#endif // EZXML_NOMMAP +#include +#include "ezxml.h" + +#if defined(WIN32) || defined(_WIN32) +#define vsnprintf _vsnprintf +#define snprintf _snprintf +#define open _open +#define read _read +#define write _write +#define close _close +#endif + +#define EZXML_WS "\t\r\n " // whitespace +#define EZXML_ERRL 128 // maximum error string length + +typedef struct ezxml_root *ezxml_root_t; +struct ezxml_root { // additional data for the root tag + struct ezxml xml; // is a super-struct built on top of ezxml struct + ezxml_t cur; // current xml tree insertion point + char *m; // original xml string + size_t len; // length of allocated memory for mmap, -1 for malloc + char *u; // UTF-8 conversion of string if original was UTF-16 + char *s; // start of work area + char *e; // end of work area + char **ent; // general entities (ampersand sequences) + char ***attr; // default attributes + char ***pi; // processing instructions + short standalone; // non-zero if + char err[EZXML_ERRL]; // error string +}; + +char *EZXML_NIL[] = { NULL }; // empty, null terminated array of strings + +// returns the first child tag with the given name or NULL if not found +ezxml_t ezxml_child(ezxml_t xml, const char *name) +{ + xml = (xml) ? xml->child : NULL; + while (xml && strcmp(name, xml->name)) xml = xml->sibling; + return xml; +} + +// returns the Nth tag with the same name in the same subsection or NULL if not +// found +ezxml_t ezxml_idx(ezxml_t xml, int idx) +{ + for (; xml && idx; idx--) xml = xml->next; + return xml; +} + +// returns the value of the requested tag attribute or NULL if not found +const char *ezxml_attr(ezxml_t xml, const char *attr) +{ + int i = 0, j = 1; + ezxml_root_t root = (ezxml_root_t)xml; + + if (! xml || ! xml->attr) return NULL; + while (xml->attr[i] && strcmp(attr, xml->attr[i])) i += 2; + if (xml->attr[i]) return xml->attr[i + 1]; // found attribute + + while (root->xml.parent) root = (ezxml_root_t)root->xml.parent; // root tag + for (i = 0; root->attr[i] && strcmp(xml->name, root->attr[i][0]); i++); + if (! root->attr[i]) return NULL; // no matching default attributes + while (root->attr[i][j] && strcmp(attr, root->attr[i][j])) j += 3; + return (root->attr[i][j]) ? root->attr[i][j + 1] : NULL; // found default +} + +// same as ezxml_get but takes an already initialized va_list +ezxml_t ezxml_vget(ezxml_t xml, va_list ap) +{ + char *name = va_arg(ap, char *); + int idx = -1; + + if (name && *name) { + idx = va_arg(ap, int); + xml = ezxml_child(xml, name); + } + return (idx < 0) ? xml : ezxml_vget(ezxml_idx(xml, idx), ap); +} + +// Traverses the xml tree to retrieve a specific subtag. Takes a variable +// length list of tag names and indexes. The argument list must be terminated +// by either an index of -1 or an empty string tag name. Example: +// title = ezxml_get(library, "shelf", 0, "book", 2, "title", -1); +// This retrieves the title of the 3rd book on the 1st shelf of library. +// Returns NULL if not found. +ezxml_t ezxml_get(ezxml_t xml, ...) +{ + va_list ap; + ezxml_t r; + + va_start(ap, xml); + r = ezxml_vget(xml, ap); + va_end(ap); + return r; +} + +// returns a null terminated array of processing instructions for the given +// target +const char **ezxml_pi(ezxml_t xml, const char *target) +{ + ezxml_root_t root = (ezxml_root_t)xml; + int i = 0; + + if (! root) return (const char **)EZXML_NIL; + while (root->xml.parent) root = (ezxml_root_t)root->xml.parent; // root tag + while (root->pi[i] && strcmp(target, root->pi[i][0])) i++; // find target + return (const char **)((root->pi[i]) ? root->pi[i] + 1 : EZXML_NIL); +} + +// set an error string and return root +ezxml_t ezxml_err(ezxml_root_t root, char *s, const char *err, ...) +{ + va_list ap; + int line = 1; + char *t, fmt[EZXML_ERRL]; + + for (t = root->s; t < s; t++) if (*t == '\n') line++; + snprintf(fmt, EZXML_ERRL, "[error near line %d]: %s", line, err); + + va_start(ap, err); + vsnprintf(root->err, EZXML_ERRL, fmt, ap); + va_end(ap); + + return &root->xml; +} + +// Recursively decodes entity and character references and normalizes new lines +// ent is a null terminated array of alternating entity names and values. set t +// to '&' for general entity decoding, '%' for parameter entity decoding, 'c' +// for cdata sections, ' ' for attribute normalization, or '*' for non-cdata +// attribute normalization. Returns s, or if the decoded string is longer than +// s, returns a malloced string that must be freed. +char *ezxml_decode(char *s, char **ent, char t) +{ + char *e, *r = s, *m = s; + long b, c, d, l; + + for (; *s; s++) { // normalize line endings + while (*s == '\r') { + *(s++) = '\n'; + if (*s == '\n') memmove(s, (s + 1), strlen(s)); + } + } + + for (s = r; ; ) { + while (*s && *s != '&' && (*s != '%' || t != '%') && !isspace(*s)) s++; + + if (! *s) break; + else if (t != 'c' && ! strncmp(s, "&#", 2)) { // character reference + if (s[2] == 'x') c = strtol(s + 3, &e, 16); // base 16 + else c = strtol(s + 2, &e, 10); // base 10 + if (! c || *e != ';') { s++; continue; } // not a character ref + + if (c < 0x80) *(s++) = c; // US-ASCII subset + else { // multi-byte UTF-8 sequence + for (b = 0, d = c; d; d /= 2) b++; // number of bits in c + b = (b - 2) / 5; // number of bytes in payload + *(s++) = (0xFF << (7 - b)) | (c >> (6 * b)); // head + while (b) *(s++) = 0x80 | ((c >> (6 * --b)) & 0x3F); // payload + } + + memmove(s, strchr(s, ';') + 1, strlen(strchr(s, ';'))); + } + else if ((*s == '&' && (t == '&' || t == ' ' || t == '*')) || + (*s == '%' && t == '%')) { // entity reference + for (b = 0; ent[b] && strncmp(s + 1, ent[b], strlen(ent[b])); + b += 2); // find entity in entity list + + if (ent[b++]) { // found a match + if ((c = strlen(ent[b])) - 1 > (e = strchr(s, ';')) - s) { + l = (d = (s - r)) + c + strlen(e); // new length + r = (r == m) ? strcpy(malloc(l), r) : realloc(r, l); + e = strchr((s = r + d), ';'); // fix up pointers + } + + memmove(s + c, e + 1, strlen(e)); // shift rest of string + strncpy(s, ent[b], c); // copy in replacement text + } + else s++; // not a known entity + } + else if ((t == ' ' || t == '*') && isspace(*s)) *(s++) = ' '; + else s++; // no decoding needed + } + + if (t == '*') { // normalize spaces for non-cdata attributes + for (s = r; *s; s++) { + if ((l = strspn(s, " "))) memmove(s, s + l, strlen(s + l) + 1); + while (*s && *s != ' ') s++; + } + if (--s >= r && *s == ' ') *s = '\0'; // trim any trailing space + } + return r; +} + +// called when parser finds start of new tag +void ezxml_open_tag(ezxml_root_t root, char *name, char **attr) +{ + ezxml_t xml = root->cur; + + if (xml->name) xml = ezxml_add_child(xml, name, strlen(xml->txt)); + else xml->name = name; // first open tag + + xml->attr = attr; + root->cur = xml; // update tag insertion point +} + +// called when parser finds character content between open and closing tag +void ezxml_char_content(ezxml_root_t root, char *s, size_t len, char t) +{ + ezxml_t xml = root->cur; + char *m = s; + size_t l; + + if (! xml || ! xml->name || ! len) return; // sanity check + + s[len] = '\0'; // null terminate text (calling functions anticipate this) + len = strlen(s = ezxml_decode(s, root->ent, t)) + 1; + + if (! *(xml->txt)) xml->txt = s; // initial character content + else { // allocate our own memory and make a copy + xml->txt = (xml->flags & EZXML_TXTM) // allocate some space + ? realloc(xml->txt, (l = strlen(xml->txt)) + len) + : strcpy(malloc((l = strlen(xml->txt)) + len), xml->txt); + strcpy(xml->txt + l, s); // add new char content + if (s != m) free(s); // free s if it was malloced by ezxml_decode() + } + + if (xml->txt != m) ezxml_set_flag(xml, EZXML_TXTM); +} + +// called when parser finds closing tag +ezxml_t ezxml_close_tag(ezxml_root_t root, char *name, char *s) +{ + if (! root->cur || ! root->cur->name || strcmp(name, root->cur->name)) + return ezxml_err(root, s, "unexpected closing tag ", name); + + root->cur = root->cur->parent; + return NULL; +} + +// checks for circular entity references, returns non-zero if no circular +// references are found, zero otherwise +int ezxml_ent_ok(char *name, char *s, char **ent) +{ + int i; + + for (; ; s++) { + while (*s && *s != '&') s++; // find next entity reference + if (! *s) return 1; + if (! strncmp(s + 1, name, strlen(name))) return 0; // circular ref. + for (i = 0; ent[i] && strncmp(ent[i], s + 1, strlen(ent[i])); i += 2); + if (ent[i] && ! ezxml_ent_ok(name, ent[i + 1], ent)) return 0; + } +} + +// called when the parser finds a processing instruction +void ezxml_proc_inst(ezxml_root_t root, char *s, size_t len) +{ + int i = 0, j = 1; + char *target = s; + + s[len] = '\0'; // null terminate instruction + if (*(s += strcspn(s, EZXML_WS))) { + *s = '\0'; // null terminate target + s += strspn(s + 1, EZXML_WS) + 1; // skip whitespace after target + } + + if (! strcmp(target, "xml")) { // + if ((s = strstr(s, "standalone")) && ! strncmp(s + strspn(s + 10, + EZXML_WS "='\"") + 10, "yes", 3)) root->standalone = 1; + return; + } + + if (! root->pi[0]) *(root->pi = malloc(sizeof(char **))) = NULL; //first pi + + while (root->pi[i] && strcmp(target, root->pi[i][0])) i++; // find target + if (! root->pi[i]) { // new target + root->pi = realloc(root->pi, sizeof(char **) * (i + 2)); + root->pi[i] = malloc(sizeof(char *) * 3); + root->pi[i][0] = target; + root->pi[i][1] = (char *)(root->pi[i + 1] = NULL); // terminate pi list + root->pi[i][2] = strdup(""); // empty document position list + } + + while (root->pi[i][j]) j++; // find end of instruction list for this target + root->pi[i] = realloc(root->pi[i], sizeof(char *) * (j + 3)); + root->pi[i][j + 2] = realloc(root->pi[i][j + 1], j + 1); + strcpy(root->pi[i][j + 2] + j - 1, (root->xml.name) ? ">" : "<"); + root->pi[i][j + 1] = NULL; // null terminate pi list for this target + root->pi[i][j] = s; // set instruction +} + +// called when the parser finds an internal doctype subset +short ezxml_internal_dtd(ezxml_root_t root, char *s, size_t len) +{ + char q, *c, *t, *n = NULL, *v, **ent, **pe; + int i, j; + + pe = memcpy(malloc(sizeof(EZXML_NIL)), EZXML_NIL, sizeof(EZXML_NIL)); + + for (s[len] = '\0'; s; ) { + while (*s && *s != '<' && *s != '%') s++; // find next declaration + + if (! *s) break; + else if (! strncmp(s, "'); + continue; + } + + for (i = 0, ent = (*c == '%') ? pe : root->ent; ent[i]; i++); + ent = realloc(ent, (i + 3) * sizeof(char *)); // space for next ent + if (*c == '%') pe = ent; + else root->ent = ent; + + *(++s) = '\0'; // null terminate name + if ((s = strchr(v, q))) *(s++) = '\0'; // null terminate value + ent[i + 1] = ezxml_decode(v, pe, '%'); // set value + ent[i + 2] = NULL; // null terminate entity list + if (! ezxml_ent_ok(n, ent[i + 1], ent)) { // circular reference + if (ent[i + 1] != v) free(ent[i + 1]); + ezxml_err(root, v, "circular entity declaration &%s", n); + break; + } + else ent[i] = n; // set entity name + } + else if (! strncmp(s, "")) == '>') continue; + else *s = '\0'; // null terminate tag name + for (i = 0; root->attr[i] && strcmp(n, root->attr[i][0]); i++); + + while (*(n = ++s + strspn(s, EZXML_WS)) && *n != '>') { + if (*(s = n + strcspn(n, EZXML_WS))) *s = '\0'; // attr name + else { ezxml_err(root, t, "malformed ") - 1; + if (*c == ' ') continue; // cdata is default, nothing to do + v = NULL; + } + else if ((*s == '"' || *s == '\'') && // default value + (s = strchr(v = s + 1, *s))) *s = '\0'; + else { ezxml_err(root, t, "malformed attr[i]) { // new tag name + root->attr = (! i) ? malloc(2 * sizeof(char **)) + : realloc(root->attr, + (i + 2) * sizeof(char **)); + root->attr[i] = malloc(2 * sizeof(char *)); + root->attr[i][0] = t; // set tag name + root->attr[i][1] = (char *)(root->attr[i + 1] = NULL); + } + + for (j = 1; root->attr[i][j]; j += 3); // find end of list + root->attr[i] = realloc(root->attr[i], + (j + 4) * sizeof(char *)); + + root->attr[i][j + 3] = NULL; // null terminate list + root->attr[i][j + 2] = c; // is it cdata? + root->attr[i][j + 1] = (v) ? ezxml_decode(v, root->ent, *c) + : NULL; + root->attr[i][j] = n; // attribute name + } + } + else if (! strncmp(s, ""); // comments + else if (! strncmp(s, ""))) + ezxml_proc_inst(root, c, s++ - c); + } + else if (*s == '<') s = strchr(s, '>'); // skip other declarations + else if (*(s++) == '%' && ! root->standalone) break; + } + + free(pe); + return ! *root->err; +} + +// Converts a UTF-16 string to UTF-8. Returns a new string that must be freed +// or NULL if no conversion was needed. +char *ezxml_str2utf8(char **s, size_t *len) +{ + char *u; + size_t l = 0, sl, max = *len; + long c, d; + int b, be = (**s == '\xFE') ? 1 : (**s == '\xFF') ? 0 : -1; + + if (be == -1) return NULL; // not UTF-16 + + u = malloc(max); + for (sl = 2; sl < *len - 1; sl += 2) { + c = (be) ? (((*s)[sl] & 0xFF) << 8) | ((*s)[sl + 1] & 0xFF) //UTF-16BE + : (((*s)[sl + 1] & 0xFF) << 8) | ((*s)[sl] & 0xFF); //UTF-16LE + if (c >= 0xD800 && c <= 0xDFFF && (sl += 2) < *len - 1) { // high-half + d = (be) ? (((*s)[sl] & 0xFF) << 8) | ((*s)[sl + 1] & 0xFF) + : (((*s)[sl + 1] & 0xFF) << 8) | ((*s)[sl] & 0xFF); + c = (((c & 0x3FF) << 10) | (d & 0x3FF)) + 0x10000; + } + + while (l + 6 > max) u = realloc(u, max += EZXML_BUFSIZE); + if (c < 0x80) u[l++] = c; // US-ASCII subset + else { // multi-byte UTF-8 sequence + for (b = 0, d = c; d; d /= 2) b++; // bits in c + b = (b - 2) / 5; // bytes in payload + u[l++] = (0xFF << (7 - b)) | (c >> (6 * b)); // head + while (b) u[l++] = 0x80 | ((c >> (6 * --b)) & 0x3F); // payload + } + } + return *s = realloc(u, *len = l); +} + +// frees a tag attribute list +void ezxml_free_attr(char **attr) { + int i = 0; + char *m; + + if (! attr || attr == EZXML_NIL) return; // nothing to free + while (attr[i]) i += 2; // find end of attribute list + m = attr[i + 1]; // list of which names and values are malloced + for (i = 0; m[i]; i++) { + if (m[i] & EZXML_NAMEM) free(attr[i * 2]); + if (m[i] & EZXML_TXTM) free(attr[(i * 2) + 1]); + } + free(m); + free(attr); +} + +// parse the given xml string and return an ezxml structure +ezxml_t ezxml_parse_str(char *s, size_t len) +{ + ezxml_root_t root = (ezxml_root_t)ezxml_new(NULL); + char q, e, *d, **attr, **a = NULL; // initialize a to avoid compile warning + int l, i, j; + + root->m = s; + if (! len) return ezxml_err(root, NULL, "root tag missing"); + root->u = ezxml_str2utf8(&s, &len); // convert utf-16 to utf-8 + root->e = (root->s = s) + len; // record start and end of work area + + e = s[len - 1]; // save end char + s[len - 1] = '\0'; // turn end char into null terminator + + while (*s && *s != '<') s++; // find first tag + if (! *s) return ezxml_err(root, s, "root tag missing"); + + for (; ; ) { + attr = (char **)EZXML_NIL; + d = ++s; + + if (isalpha(*s) || *s == '_' || *s == ':' || *s < '\0') { // new tag + if (! root->cur) + return ezxml_err(root, d, "markup outside of root element"); + + s += strcspn(s, EZXML_WS "/>"); + while (isspace(*s)) *(s++) = '\0'; // null terminate tag name + + if (*s && *s != '/' && *s != '>') // find tag in default attr list + for (i = 0; (a = root->attr[i]) && strcmp(a[0], d); i++); + + for (l = 0; *s && *s != '/' && *s != '>'; l += 2) { // new attrib + attr = (l) ? realloc(attr, (l + 4) * sizeof(char *)) + : malloc(4 * sizeof(char *)); // allocate space + attr[l + 3] = (l) ? realloc(attr[l + 1], (l / 2) + 2) + : malloc(2); // mem for list of maloced vals + strcpy(attr[l + 3] + (l / 2), " "); // value is not malloced + attr[l + 2] = NULL; // null terminate list + attr[l + 1] = ""; // temporary attribute value + attr[l] = s; // set attribute name + + s += strcspn(s, EZXML_WS "=/>"); + if (*s == '=' || isspace(*s)) { + *(s++) = '\0'; // null terminate tag attribute name + q = *(s += strspn(s, EZXML_WS "=")); + if (q == '"' || q == '\'') { // attribute value + attr[l + 1] = ++s; + while (*s && *s != q) s++; + if (*s) *(s++) = '\0'; // null terminate attribute val + else { + ezxml_free_attr(attr); + return ezxml_err(root, d, "missing %c", q); + } + + for (j = 1; a && a[j] && strcmp(a[j], attr[l]); j +=3); + attr[l + 1] = ezxml_decode(attr[l + 1], root->ent, (a + && a[j]) ? *a[j + 2] : ' '); + if (attr[l + 1] < d || attr[l + 1] > s) + attr[l + 3][l / 2] = EZXML_TXTM; // value malloced + } + } + while (isspace(*s)) s++; + } + + if (*s == '/') { // self closing tag + *(s++) = '\0'; + if ((*s && *s != '>') || (! *s && e != '>')) { + if (l) ezxml_free_attr(attr); + return ezxml_err(root, d, "missing >"); + } + ezxml_open_tag(root, d, attr); + ezxml_close_tag(root, d, s); + } + else if ((q = *s) == '>' || (! *s && e == '>')) { // open tag + *s = '\0'; // temporarily null terminate tag name + ezxml_open_tag(root, d, attr); + *s = q; + } + else { + if (l) ezxml_free_attr(attr); + return ezxml_err(root, d, "missing >"); + } + } + else if (*s == '/') { // close tag + s += strcspn(d = s + 1, EZXML_WS ">") + 1; + if (! (q = *s) && e != '>') return ezxml_err(root, d, "missing >"); + *s = '\0'; // temporarily null terminate tag name + if (ezxml_close_tag(root, d, s)) return &root->xml; + if (isspace(*s = q)) s += strspn(s, EZXML_WS); + } + else if (! strncmp(s, "!--", 3)) { // xml comment + if (! (s = strstr(s + 3, "--")) || (*(s += 2) != '>' && *s) || + (! *s && e != '>')) return ezxml_err(root, d, "unclosed Yes +// 0 --> No +int AnySkypeusers(void) +{ + HANDLE hContact; + DBVARIANT dbv; + int tCompareResult; + + // already on list? + for (hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + hContact != NULL; + hContact=(HANDLE)CallService( MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) + { + // GETCONTACTBASEPROTO doesn't work on not loaded protocol, therefore get + // protocol from DB + if (DBGetContactSettingString(hContact, "Protocol", "p", &dbv)) continue; + tCompareResult = !strcmp(dbv.pszVal, SKYPE_PROTONAME); + DBFreeVariant(&dbv); + if (tCompareResult) return 1; + } + return 0; +} + + +void UpgradeName(char *OldName) +{ + DBCONTACTENUMSETTINGS cns; + DBCONTACTWRITESETTING cws; + DBVARIANT dbv; + HANDLE hContact=NULL; + struct PLUGINDI pdi; + + LOG(("Updating old database settings if there are any...")); + cns.pfnEnumProc=EnumOldPluginName; + cns.lParam=(LPARAM)&pdi; + cns.szModule=OldName; + cns.ofsSettings=0; + + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + + for ( ;; ) { + memset(&pdi,0,sizeof(pdi)); + CallService(MS_DB_CONTACT_ENUMSETTINGS,(WPARAM)hContact,(LPARAM)&cns); + // Upgrade Protocol settings to new string + if (pdi.szSettings) { + int i; + + LOG(("We're currently upgrading...")); + for (i=0;i 0 && !Miranda_Terminated()) { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + UnregisterClass (WndClass.lpszClassName, hInst); + LOG (("Messagepump stopped.")); +} + +// DLL Stuff // + +__declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirVersion) +{ + mirandaVersion = mirVersion; + + pluginInfo.cbSize = sizeof(PLUGININFO); + return (PLUGININFO*) &pluginInfo; +} + +__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirVersion) +{ + mirandaVersion = mirVersion; + + return &pluginInfo; +} + +static const MUUID interfaces[] = {MUUID_SKYPE_CALL, MIID_LAST}; +__declspec(dllexport) const MUUID * MirandaPluginInterfaces(void) +{ + return interfaces; +} + + +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + UNREFERENCED_PARAMETER(fdwReason); + UNREFERENCED_PARAMETER(lpvReserved); + + hInst = hinstDLL; + return TRUE; +} + + +int PreShutdown(WPARAM wParam, LPARAM lParam) { + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + + PostThreadMessage(msgPumpThreadId, WM_QUIT, 0, 0); + return 0; +} + +int __declspec(dllexport) Load(PLUGINLINK *link) +{ + PROTOCOLDESCRIPTOR pd; + DWORD Buffsize; + HKEY MyKey; + BOOL SkypeInstalled; + BOOL UseCustomCommand; + WSADATA wsaData; + char path[MAX_PATH]; + + pluginLink = link; + mir_getMMI( &mmi ); + //mir_getLP(&pluginInfo); + + GetModuleFileNameA( hInst, path, sizeof( path )); + _splitpath (path, NULL, NULL, SKYPE_PROTONAME, NULL); + CharUpperA( SKYPE_PROTONAME ); + + InitializeCriticalSection(&RingAndEndcallMutex); + InitializeCriticalSection(&QueryThreadMutex); + InitializeCriticalSection(&TimeMutex); + + +#ifdef _DEBUG + init_debug(); +#endif + + LOG(("Load: Skype Plugin loading...")); + + // We need to upgrade SKYPE_PROTOCOL internal name to Skype if not already done + if (!DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UpgradeDone", 0)) + UpgradeName("SKYPE_PROTOCOL"); + + // Initialisation of Skype MsgQueue must be done because of Cleanup in end and + // Mutex is also initialized here. + LOG(("SkypeMsgInit initializing Skype MSG-queue")); + if (SkypeMsgInit()==-1) { + OUTPUT(_T("Memory allocation error on startup.")); + return 0; + } + + // On first run on new profile, ask user, if he wants to enable the plugin in + // this profile + // --> Fixing Issue #0000006 from bugtracker. + if (!DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "FirstRun", 0)) { + DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "FirstRun", 1); + if (AnySkypeusers()==0) // First run, it seems :) + if (MessageBox(NULL, TranslateT("This seems to be the first time that you're running the Skype protocol plugin. Do you want to enable the protocol for this Miranda-Profile? (If you chose NO, you can always enable it in the plugin options later."), _T("Welcome!"), MB_ICONQUESTION|MB_YESNO)==IDNO) { + char path[MAX_PATH], *filename; + GetModuleFileNameA(hInst, path, sizeof(path)); + if (filename = strrchr(path,'\\')+1) + DBWriteContactSettingByte(NULL,"PluginDisable",filename,1); + return 0; + } + } + + + // Check if Skype is installed + SkypeInstalled=TRUE; + UseCustomCommand = (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseCustomCommand", 0); + UseSockets = (BOOL)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseSkype2Socket", 0); + + if (!UseSockets && !UseCustomCommand) + { + if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Skype\\Phone"), 0, KEY_READ, &MyKey)!=ERROR_SUCCESS) + { + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Skype\\Phone"), 0, KEY_READ, &MyKey)!=ERROR_SUCCESS) + { + SkypeInstalled=FALSE; + } + } + + Buffsize=sizeof(skype_path); + + if (SkypeInstalled==FALSE || RegQueryValueExA(MyKey, "SkypePath", NULL, NULL, (unsigned char *)skype_path, &Buffsize)!=ERROR_SUCCESS) + { + //OUTPUT("Skype was not found installed :( \nMaybe you are using portable skype."); + RegCloseKey(MyKey); + skype_path[0]=0; + //return 0; + } + RegCloseKey(MyKey); + } + WSAStartup(MAKEWORD(2,2), &wsaData); + + // Start Skype connection + if (!(ControlAPIAttach=RegisterWindowMessage(_T("SkypeControlAPIAttach"))) || !(ControlAPIDiscover=RegisterWindowMessage(_T("SkypeControlAPIDiscover")))) + { + OUTPUT(_T("Cannot register Window message.")); + return 0; + } + + SkypeMsgReceived=CreateSemaphore(NULL, 0, MAX_MSGS, NULL); + if (!(SkypeReady=CreateEvent(NULL, TRUE, FALSE, NULL)) || + !(MessagePumpReady=CreateEvent(NULL, FALSE, FALSE, NULL)) || +#ifdef SKYPEBUG_OFFLN + !(GotUserstatus=CreateEvent(NULL, TRUE, FALSE, NULL)) || +#endif + !(hBuddyAdded=CreateEvent(NULL, FALSE, FALSE, NULL)) || + !(FetchMessageEvent=CreateEvent(NULL, FALSE, TRUE, NULL))) { + OUTPUT(_T("Unable to create Mutex!")); + return 0; + } + + /* Register the module */ + ZeroMemory(&pd, sizeof(pd)); + pd.cbSize = sizeof(pd); + pd.szName = SKYPE_PROTONAME; + pd.type = PROTOTYPE_PROTOCOL; + CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd); + + VoiceServiceInit(); + + CreateServices(); + HookEvents(); + InitVSApi(); + MsgList_Init(); + + HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown); + + // Startup Message-pump + pthread_create (( pThreadFunc )MsgPump, NULL); + WaitForSingleObject(MessagePumpReady, INFINITE); + return 0; +} + + + +int __declspec( dllexport ) Unload(void) +{ + BOOL UseCustomCommand = DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseCustomCommand", 0); + BOOL Shutdown = DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "Shutdown", 0); + + LOG (("Unload started")); + + if ( Shutdown && ((skype_path && skype_path[0]) ||UseCustomCommand) ) { + + if(UseCustomCommand) + { + DBVARIANT dbv; + if(!DBGetContactSettingString(NULL,SKYPE_PROTONAME,"CommandLine",&dbv)) + { + char szAbsolutePath[MAX_PATH]; + + TranslateMirandaRelativePathToAbsolute(dbv.pszVal, szAbsolutePath, FALSE); + _spawnl(_P_NOWAIT, szAbsolutePath, szAbsolutePath, "/SHUTDOWN", NULL); + LOG (("Unload Sent /shutdown to %s", szAbsolutePath)); + DBFreeVariant(&dbv); + } + } + else + { + _spawnl(_P_NOWAIT, skype_path, skype_path, "/SHUTDOWN", NULL); + LOG (("Unload Sent /shutdown to %s", skype_path)); + } + + } + SkypeMsgCleanup(); + WSACleanup(); + FreeVSApi(); + UnhookEvents(); + UnhookEvent(hChatEvent); + UnhookEvent (hChatMenu); + UnhookEvent (hEvInitChat); + DestroyHookableEvent(hInitChat); + VoiceServiceExit(); + GCExit(); + MsgList_Exit(); + + CloseHandle(SkypeReady); + CloseHandle(SkypeMsgReceived); +#ifdef SKYPEBUG_OFFLN + CloseHandle(GotUserstatus); +#endif + CloseHandle(MessagePumpReady); + CloseHandle(hBuddyAdded); + CloseHandle(FetchMessageEvent); + + DeleteCriticalSection(&RingAndEndcallMutex); + DeleteCriticalSection(&QueryThreadMutex); + + SkypeRegisterProxy (0, 0); + LOG (("Unload: Shutdown complete")); +#ifdef _DEBUG + end_debug(); +#endif + DeleteCriticalSection(&TimeMutex); + return 0; +} + diff --git a/plugins/!NotAdopted/Skype/skype.h b/plugins/!NotAdopted/Skype/skype.h new file mode 100644 index 0000000000..6439a24dc8 --- /dev/null +++ b/plugins/!NotAdopted/Skype/skype.h @@ -0,0 +1,188 @@ +#pragma once + +#define _CRT_SECURE_NO_DEPRECATE 1 +#define TEXT_LEN 1024 +#define CP_ACP 0 + +#define code_page CP_ACP; +#define MIRANDA_CUSTOM_LP + + +// System includes +#include +#include +#include +#include +#include +#include "resource.h" +#include +#include +#include +#include +#include "util.h" + +#pragma warning (push) +#pragma warning (disable: 4100) // unreferenced formal parameter + +// Miranda Includes +#include "../../include/newpluginapi.h" +#include "../../include/m_utils.h" +#include "../../include/m_protosvc.h" +#include "../../include/m_protomod.h" +#include "../../include/m_skin.h" +#include "../../include/m_message.h" +#include "../../include/m_database.h" +#include "../../include/m_clist.h" +#include "../../include/m_system.h" +#include "sdk/m_updater.h" +#include "sdk/m_folders.h" +#include "../../include/m_options.h" +#include "../../include/m_langpack.h" +#include "../../include/m_userinfo.h" +#include "../../include/m_avatars.h" +#include "../../include/m_contacts.h" +#include "../../include/m_popup.h" + +#pragma warning (pop) + +// MyDetails defines + +// wParam=NULL +// lParam=(char *) new nickname - do not free +// return=0 for sucess +#define PS_SETMYNICKNAME "/SetNickname" + +// Optional, default value is 1024 +// wParam=NULL +// lParam=NULL +// return= <=0 for error, >0 the max length of the nick +#define PS_GETMYNICKNAMEMAXLENGTH "/GetMyNicknameMaxLength" + +// wParam=(char *)Buffer to file name +// lParam=(int)Buffer size +// return=0 for sucess +#define PS_GETMYAVATAR "/GetMyAvatar" + +// wParam=0 +// lParam=(const char *)Avatar file name +// return=0 for sucess +#define PS_SETMYAVATAR "/SetMyAvatar" + + +// Program defines +#define SKYPE_NAME "Username" +#define SKYPE_PROTO "PROTOCOL 7" +#define SKYPE_PROTONAME g_szProtoName // Name of our protocol, taken from .DLL name +#define MAX_MSGS 128 // Maximum messages in queue +#define MAX_USERLEN 32 // Maximum length of a username in Skype +#define PING_INTERVAL 10000 // Ping every 10000 msec to see if Skype is still available +#define USEPOPUP 1 // Use the popup-plugin? +#define TIMEOUT_MSGSEND 9000 // Stolen from msgdialog.c +#define MAX_MSG_AGE 30 // Maximum age in seconds before a Message from queue gets trashed +#define SKYPEBUG_OFFLN 1 // Activate fix for the SkypeAPI Offline-Bug + +// Program hooks +typedef struct { + char ChatNew[MAXMODULELABELLENGTH]; + char SetAvatar[MAXMODULELABELLENGTH]; + char SendFile[MAXMODULELABELLENGTH]; + char HoldCall[MAXMODULELABELLENGTH]; + char AnswerCall[MAXMODULELABELLENGTH]; + char ImportHistory[MAXMODULELABELLENGTH]; + char AddUser[MAXMODULELABELLENGTH]; + char SkypeOutCallUser[MAXMODULELABELLENGTH]; + char CallHangupUser[MAXMODULELABELLENGTH]; + char CallUser[MAXMODULELABELLENGTH]; +} SKYPE_SVCNAMES; +#define SKYPE_CALL g_svcNames.CallUser +#define SKYPE_CALLHANGUP g_svcNames.CallHangupUser +#define SKYPEOUT_CALL g_svcNames.SkypeOutCallUser +#define SKYPE_ADDUSER g_svcNames.AddUser +#define SKYPE_IMPORTHISTORY g_svcNames.ImportHistory +#define SKYPE_ANSWERCALL g_svcNames.AnswerCall +#define SKYPE_HOLDCALL g_svcNames.HoldCall +#define SKYPE_SENDFILE g_svcNames.SendFile +#define SKYPE_SETAVATAR g_svcNames.SetAvatar +#define SKYPE_CHATNEW g_svcNames.ChatNew +#define EVENTTYPE_CALL 2000 + +#ifndef __SKYPESVC_C__ +extern SKYPE_SVCNAMES g_svcNames; +#endif + +// Skype API Communication services +#define PSS_SKYPEAPIMSG "/SendSkypeAPIMsg" +#define SKYPE_REGPROXY "/RegisterProxySvc" + +#define MUUID_SKYPE_CALL { 0x245241eb, 0x178c, 0x4b3f, { 0x91, 0xa, 0x4c, 0x4d, 0xf0, 0xa0, 0xc3, 0xb6 } } + + +// Common used code-pieces +#define OUTPUT(a) ShowMessage(IDI_ERRORS, a, 1); +#define OUTPUTA(a) ShowMessageA(IDI_ERRORS, a, 1); + +typedef void ( __cdecl* pThreadFunc )( void* ); + +// Prototypes + +void __cdecl SkypeSystemInit(char *); +void __cdecl MsgPump (char *dummy); +void PingPong(void); +void CheckIfApiIsResponding(char *); +void TellError(DWORD err); +int ShowMessage(int, TCHAR*, int); +#ifdef _UNICODE +int ShowMessageA(int iconID, char *lpzText, int mustShow); +#else +#define ShowMessageA ShowMessage +#endif +void EndCallThread(char *); +void GetInfoThread(HANDLE); +int OnDetailsInit( WPARAM, LPARAM ); +INT_PTR SkypeGetAvatarInfo(WPARAM wParam,LPARAM lParam); +INT_PTR SkypeGetAvatarCaps(WPARAM wParam,LPARAM lParam); +INT_PTR SkypeGetAwayMessage(WPARAM wParam,LPARAM lParam); +int HookContactAdded(WPARAM wParam, LPARAM lParam); +int HookContactDeleted(WPARAM wParam, LPARAM lParam); +INT_PTR ImportHistory(WPARAM wParam, LPARAM lParam); +int CreateTopToolbarButton(WPARAM wParam, LPARAM lParam); +int OnModulesLoaded(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeSetStatus(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeGetStatus(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeGetInfo(WPARAM wParam,LPARAM lParam); +INT_PTR SkypeAddToList(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeBasicSearch(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeSendMessage(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeRecvMessage(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeUserIsTyping(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeSendAuthRequest(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeRecvAuth(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeAuthAllow(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeAuthDeny(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeAddToListByEvent(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeRegisterProxy(WPARAM wParam, LPARAM lParam); +time_t SkypeTime(time_t *timer); +void MessageSendWatchThread(HANDLE hContact); +int OkToExit(WPARAM wParam, LPARAM lParam); +int MirandaExit(WPARAM wParam, LPARAM lParam); +int __stdcall EnterBitmapFileName( char* szDest ); +void CleanupNicknames(char *dummy); +int InitVSApi(); +int FreeVSApi(); +HANDLE GetMetaHandle(DWORD dwId); +void LaunchSkypeAndSetStatusThread(void *newStatus); + +// Write contact setting as UTF-8 for convenience, if possible. Older Miranda IM versions will store it as ANSI +INT_PTR SkypeDBWriteContactSettingUTF8String(HANDLE hContact,const char *szModule,const char *szSetting,const char *val); + +// Structs + +typedef struct { + char *SkypeSetting; + char *MirandaSetting; +} settings_map; + +// Optional includes +#ifdef USEPOPUP + #include "../../include/m_popup.h" +#endif diff --git a/plugins/!NotAdopted/Skype/skypeapi.c b/plugins/!NotAdopted/Skype/skypeapi.c new file mode 100644 index 0000000000..2a6eb1b76e --- /dev/null +++ b/plugins/!NotAdopted/Skype/skypeapi.c @@ -0,0 +1,1699 @@ +/* + * SkypeAPI - All more or less important functions that deal with Skype + */ + +#include "skype.h" +#include "skypeapi.h" +#include "utf8.h" +#include "debug.h" +#include "contacts.h" +#include "skypeproxy.h" +#include "pthread.h" +#include "gchat.h" +#include "alogon.h" +#include "msgq.h" +#pragma warning (push) +#pragma warning (disable: 4100) // unreferenced formal parameter +#include "../../include/m_utils.h" +#include "../../include/m_langpack.h" +#pragma warning (push) +#include "m_toptoolbar.h" + +#pragma warning (disable: 4706) // assignment within conditional expression + +// Imported Globals +extern HWND hSkypeWnd, g_hWnd; +extern BOOL SkypeInitialized, UseSockets, MirandaShuttingDown, bIsImoproxy; +extern int SkypeStatus, receivers; +extern HANDLE SkypeReady, SkypeMsgReceived, httbButton; +extern UINT ControlAPIAttach, ControlAPIDiscover; +extern LONG AttachStatus; +extern HINSTANCE hInst; +extern PLUGININFO pluginInfo; +extern HANDLE hProtocolAvatarsFolder, hHookSkypeApiRcv; +extern char DefaultAvatarsFolder[MAX_PATH+1], *pszProxyCallout, protocol, g_szProtoName[]; + +// -> Skype Message Queue functions // + +static TYP_MSGQ SkypeMsgs, SkypeSendQueue; + +status_map status_codes[] = { + {ID_STATUS_AWAY, "AWAY"}, + {ID_STATUS_NA, "NA"}, + {ID_STATUS_DND, "DND"}, + {ID_STATUS_ONLINE, "ONLINE"}, + {ID_STATUS_FREECHAT, "SKYPEME"}, // Unfortunately Skype API tells us userstatus ONLINE, if we are free for chat + {ID_STATUS_OFFLINE, "OFFLINE"}, + {ID_STATUS_INVISIBLE, "INVISIBLE"}, + {ID_STATUS_CONNECTING, "CONNECTING"}, + {0, NULL} +}; + +//status_map + + +static CRITICAL_SECTION ConnectMutex; +static BOOL rcvThreadRunning=FALSE, isConnecting = FALSE; +static SOCKET ClientSocket=INVALID_SOCKET; +static HANDLE SkypeMsgToSend=NULL; + +static char *m_szSendBuf = NULL; +static DWORD m_iBufSize = 0; + + +static int _ConnectToSkypeAPI(char *path, BOOL bStart); + + +/* SkypeReceivedMessage + * + * Purpose: Hook to be called when a message is received, if some caller is + * using our internal I/O services. + * Params : wParam - Not used + * lParam - COPYDATASTRUCT like in WM_COPYDATA + * Returns: Result from SendMessage + */ +INT_PTR SkypeReceivedAPIMessage(WPARAM wParam, LPARAM lParam) { + return SendMessage(g_hWnd, WM_COPYDATA, (WPARAM)hSkypeWnd, lParam); +} + +/* + * Skype via Socket --> Skype2Socket connection + */ + +void rcvThread(char *dummy) { + unsigned int length; + char *buf; + COPYDATASTRUCT CopyData; + int rcv; + + if (!UseSockets) return; + rcvThreadRunning=TRUE; + for ( ;; ) { + if (ClientSocket==INVALID_SOCKET) { + rcvThreadRunning=FALSE; + return; + } + LOG(("rcvThread Receiving from socket..")); + if ((rcv=recv(ClientSocket, (char *)&length, sizeof(length), 0))==SOCKET_ERROR || rcv==0) { + rcvThreadRunning=FALSE; + if (rcv==SOCKET_ERROR) {LOG(("rcvThread Socket error"));} + else {LOG(("rcvThread lost connection, graceful shutdown"));} + return; + } + LOG(("rcvThread Received length, recieving message..")); + buf=(char *)calloc(1, length+1); + if ((rcv = recv(ClientSocket, buf, length, 0))==SOCKET_ERROR || rcv==0) { + rcvThreadRunning=FALSE; + if (rcv==SOCKET_ERROR) {LOG(("rcvThread Socket error"));} + else {LOG(("rcvThread lost connection, graceful shutdown"));} + free(buf); + return; + } + LOG(("Received message: %s", buf)); + + CopyData.dwData=0; + CopyData.lpData=buf; + CopyData.cbData=(DWORD)strlen(buf)+1; + if (!SendMessage(g_hWnd, WM_COPYDATA, (WPARAM)hSkypeWnd, (LPARAM)&CopyData)) + { + LOG(("SendMessage failed: %08X", GetLastError())); + } + free(buf); + } +} + +void sendThread(char *dummy) { + COPYDATASTRUCT CopyData; + LRESULT SendResult; + int oldstatus; + unsigned int length; + char *szMsg; + + while (SkypeMsgToSend) { + if (WaitForSingleObject(SkypeMsgToSend, INFINITE) != WAIT_OBJECT_0) return; + if (!(szMsg = MsgQ_Get(&SkypeSendQueue))) continue; + length=(unsigned int)strlen(szMsg); + + if (UseSockets) { + if (send(ClientSocket, (char *)&length, sizeof(length), 0) != SOCKET_ERROR && + send(ClientSocket, szMsg, length, 0) != SOCKET_ERROR) { + free (szMsg); + continue; + } + SendResult = 0; + } else { + CopyData.dwData=0; + CopyData.lpData=szMsg; + CopyData.cbData=length+1; + + // Internal comm channel + if (pszProxyCallout) { + CallService (pszProxyCallout, 0, (LPARAM)&CopyData); + free(szMsg); + continue; + } + + // If this didn't work, proceed with normal Skype API + if (!hSkypeWnd) + { + LOG(("SkypeSend: DAMN! No Skype window handle! :(")); + } + SendResult=SendMessage(hSkypeWnd, WM_COPYDATA, (WPARAM)g_hWnd, (LPARAM)&CopyData); + LOG(("SkypeSend: SendMessage returned %d", SendResult)); + free(szMsg); + } + if (!SendResult) { + SkypeInitialized=FALSE; + AttachStatus=-1; + ResetEvent(SkypeReady); + if (g_hWnd) KillTimer (g_hWnd, 1); + if (SkypeStatus!=ID_STATUS_OFFLINE) { + // Go offline + logoff_contacts(FALSE); + oldstatus=SkypeStatus; + InterlockedExchange((long *)&SkypeStatus, (int)ID_STATUS_OFFLINE); + ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldstatus, SkypeStatus); + } + // Reconnect to Skype + ResetEvent(SkypeReady); + pthread_create(LaunchSkypeAndSetStatusThread, (void *)ID_STATUS_ONLINE); + WaitForSingleObject (SkypeReady, 10000); + // SendMessageTimeout(HWND_BROADCAST, ControlAPIDiscover, (WPARAM)g_hWnd, 0, SMTO_ABORTIFHUNG, 3000, NULL); + } + } +} + + +/* + * Skype Messagequeue - Implemented as a linked list + */ + +/* SkypeMsgInit + * + * Purpose: Initializes the Skype Message queue and API + * Returns: 0 - Success + * -1 - Memory allocation failure + */ +int SkypeMsgInit(void) { + + MsgQ_Init(&SkypeMsgs); + MsgQ_Init(&SkypeSendQueue); + InitializeCriticalSection(&ConnectMutex); + if (SkypeMsgToSend=CreateSemaphore(NULL, 0, MAX_MSGS, NULL)) { + if (m_szSendBuf = malloc(m_iBufSize=512)) { + if (_beginthread(( pThreadFunc )sendThread, 0, NULL)!=-1) + return 0; + free(m_szSendBuf); + } + CloseHandle (SkypeMsgToSend); + } + return -1; +} + +/* SkypeMsgAdd + * + * Purpose: Add Message to linked list + * Params : msg - Message to add to queue + * Returns: 0 - Success + * -1 - Memory allocation failure + */ +int SkypeMsgAdd(char *msg) { + return MsgQ_Add(&SkypeMsgs, msg)?0:-1; +} + +/* SkypeMsgCleanup + * + * Purpose: Clean up the whole MESSagequeue - free() all + */ +void SkypeMsgCleanup(void) { + int i; + + LOG(("SkypeMsgCleanup Cleaning up message queue..")); + if (receivers>1) + { + LOG (("SkypeMsgCleanup Releasing %d receivers", receivers)); + for (i=0;i %s", szMsg)); + + // Fake PING-PONG, as PING-PONG is not supported by Skype2Socket + if ((UseSockets || bIsImoproxy) && !strcmp(szMsg, "PING")) { + CopyData.dwData=0; + CopyData.lpData="PONG"; + CopyData.cbData=5; + SendMessage(g_hWnd, WM_COPYDATA, (WPARAM)hSkypeWnd, (LPARAM)&CopyData); + return 0; + } + + if (UseSockets && ClientSocket==INVALID_SOCKET) return -1; + if (!MsgQ_Add(&SkypeSendQueue, szMsg) || !ReleaseSemaphore(SkypeMsgToSend, 1, NULL)) + return -1; + return 0; +} + +/* SkypeSend + * + * Purpose: Sends the specified message to the Skype API. + * If it fails, try to reconnect zu the Skype API + * Params: use like sprintf without first param (dest. buffer) + * Returns: 0 - Success + * -1 - Failure + */ +int SkypeSend(char *szFmt, ...) { + char *pNewBuf; + va_list ap; + size_t iLen; + + // 0.0.0.17+ - Build message-String from supplied parameter list + // so the user doesn't have to care about memory allocation any more. + // 0.0.0.47+ - No more restrictions apply to the format string. + // The temporary buffer remains allocated during the session and gets + // dynamically expanded when needed. This makes sense, as this function + // is used very often and therefore it is faster to not allocate + // memory on every send. + if (!m_szSendBuf && !(m_szSendBuf=malloc(m_iBufSize=512))) return -1; + do + { + va_start(ap, szFmt); + iLen = _vsnprintf(m_szSendBuf, m_iBufSize, szFmt, ap); + va_end(ap); + if (iLen == -1) + { + if (!(pNewBuf = (char*)realloc (m_szSendBuf, m_iBufSize*2))) + { + iLen = strlen (m_szSendBuf); + break; + } + m_szSendBuf = pNewBuf; + m_iBufSize*=2; + } + } while (iLen == -1); + + return __sendMsg(m_szSendBuf); +} + +/* SkypeRcvTime + * + * Purpose: Wait, until either the message "what" is received or maxwait-Time has passed + * or there was an error and return it + * Params : what - Wait for this string-part at the beginning of a received string + * If the first character of the string is NULL, the rest after the NULL + * character will be searched in the entire received message-string. + * You can tokenize the string by using NULL characters. + * You HAVE TO end the string with a extra \0, otherwise the tokenizer + * will run amok in memory! + * st - The message timestamp must be newer or equal to st. + * Set to 0, if you do not need this and want the first message of this + * kind in the queue. + * maxwait - Wait this time before returning, if nothing was received, + * can be INFINITE + * Returns: The received message containing "what" or a ERROR-Message or NULL if + * time is up and nothing was received + * Warning: Don't forget to free() return value! + */ +char *SkypeRcvTime(char *what, time_t st, DWORD maxwait) { + char *msg, *token=NULL; + struct MsgQueue *ptr; + int j; + DWORD dwWaitStat; + BOOL bChatMsg = FALSE, bIsChatMsg = FALSE; + + LOG (("SkypeRcv - Requesting answer: %s", what)); + if (what) bChatMsg = strncmp(what, "CHATMESSAGE", 11)==0; + do { + EnterCriticalSection(&SkypeMsgs.cs); + // First, search for the requested message. On second run, also accept an ERROR + for (j=0; j<2; j++) + { + for (ptr=SkypeMsgs.l.tqh_first; ptr; ptr=ptr->l.tqe_next) { + if (what && what[0]==0) { + // Tokenizer syntax active + token=what+1; + while (*token) { + if (!strstr (ptr->message, token)) { + token=NULL; + break; + } + token+=strlen(token)+1; + } + } + + //if (j==1) {LOG(("SkypeRcv compare %s (%lu) -- %s (%lu)", ptr->message, ptr->tReceived, what, st));} + if ((st == 0 || ptr->tReceived >= st) && + (what==NULL || token || (what[0] && !strncmp(ptr->message, what, strlen(what))) || + (bIsChatMsg = (j==1 && bChatMsg && !strncmp(ptr->message, what+4, strlen(what+4)))) || + (j==1 && !strncmp(ptr->message, "ERROR", 5)))) + { + msg=MsgQ_RemoveMsg(&SkypeMsgs, ptr); + LOG(("1) InterlockedDecrement ((long *)&receivers); // receivers--; + if (receivers>1) {LOG (("SkypeRcv: %d receivers still waiting", receivers));} + + } while(dwWaitStat == WAIT_OBJECT_0 && !MirandaShuttingDown); + InterlockedDecrement ((long *)&receivers); + LOG(("message, what)); + pCurMsg = ptr->message; + bIsError = FALSE; + if (*what && !strncmp(pCurMsg, what, iLenWhat)) { + // Now we received a MESSAGE with an identifier. So this one is definitely for us + // However the status can be SENDING instead of SENT and next message with this number + // isn't using the ID anymore, so we have to save the ID as new identifier for message recognition + pCurMsg+=iLenWhat; + if ((pMsg = strchr (pCurMsg, ' ')) && (pMsg=strchr (pMsg+1, ' '))) + strncpy (msgid, pCurMsg, pMsg-pCurMsg); + else if (strncmp (pCurMsg, "ERROR", 5) == 0) bIsError = TRUE; + } + + if ((*msgid && strncmp (pCurMsg, msgid, strlen(msgid)) == 0) || + (!*what && ptr->tReceived >= st && + (strncmp(pCurMsg, "MESSAGE", 7) == 0 || strncmp(pCurMsg, "CHATMESSAGE", 11) == 0 ) + ) || bIsError || + (ptr->tReceived >= st && ptr->tReceived <=st+1 && + (bIsError=(strncmp(pCurMsg, "ERROR 26", 8)==0 || strncmp(pCurMsg, "ERROR 43", 8)==0)) + ) ) + { + bProcess = bIsError; + if (!bIsError) { + if ((pMsg = strchr (pCurMsg, ' ')) && (pMsg=strchr (pMsg+1, ' '))) { + pMsg++; + if (strncmp (pMsg, "STATUS ", 7) == 0) { + pMsg+=7; + if (strcmp (pMsg, "SENDING") == 0 && + DBGetContactSettingWord(hContact, SKYPE_PROTONAME, "Status", ID_STATUS_OFFLINE)!=ID_STATUS_OFFLINE) { + // Remove dat shit + struct MsgQueue *ptr_=ptr->l.tqe_next; + + free(MsgQ_RemoveMsg(&SkypeMsgs, ptr)); + ptr=ptr_; + continue; + } + bProcess = (strcmp (pMsg, "SENT") == 0 || strcmp (pMsg, "QUEUED") == 0 || + strcmp (pMsg, "FAILED") == 0 || strcmp (pMsg, "IGNORED") == 0 || + strcmp (pMsg, "SENDING") == 0); + } + } + } + if (bProcess) { + msg=MsgQ_RemoveMsg(&SkypeMsgs, ptr); + LOG(("l.tqe_next; + } + LeaveCriticalSection(&SkypeMsgs.cs); + InterlockedIncrement ((long *)&receivers); //receivers++; + dwWaitStat = WaitForSingleObject(SkypeMsgReceived, maxwait); + if (receivers>1) InterlockedDecrement ((long *)&receivers); // receivers--; + if (receivers>1) {LOG (("SkypeRcvMsg: %d receivers still waiting", receivers));} + + } while(dwWaitStat == WAIT_OBJECT_0 && !MirandaShuttingDown); + InterlockedDecrement ((long *)&receivers); + LOG((" Answer %s", str, ptr)); + return ptr; +} + +char *SkypeGetID(char *szWhat, char *szWho, char *szProperty) { + char szID[16]={0}; + static DWORD dwId = 0; + + if (protocol>=4 || bIsImoproxy) sprintf (szID, "#G%d ", dwId++); + return __SkypeGet (szID, szWhat, szWho, szProperty); +} + +char *SkypeGet(char *szWhat, char *szWho, char *szProperty) { + return __SkypeGet ("", szWhat, szWho, szProperty); +} + +#ifdef _UNICODE +WCHAR *SkypeGetW(char *szWhat, WCHAR *szWho, char *szProperty) { + char *ptszWho = (char*)make_utf8_string(szWho); + char *pRet = SkypeGet (szWhat, ptszWho, szProperty); + free (ptszWho); + if (pRet) { + WCHAR *ptr = make_unicode_string((const unsigned char*)pRet); + free (pRet); + return ptr; + } + return NULL; +} +#endif + +char *SkypeGetErr(char *szWhat, char *szWho, char *szProperty) { + char *ret = SkypeGet(szWhat, szWho, szProperty); + if (ret && !strncmp(ret, "ERROR", 5)) { + free (ret); + return NULL; + } + return ret; +} + +#ifdef _UNICODE +WCHAR *SkypeGetErrW(char *szWhat, TCHAR *szWho, char *szProperty) { + WCHAR *ret = SkypeGetW(szWhat, szWho, szProperty); + if (ret && !_tcsncmp(ret, _T("ERROR"), 5)) { + free (ret); + return NULL; + } + return ret; +} +#endif + + +/* SkypeGetProfile + * + * Issues a SET PROFILE szProperty szValue and waits until the answer is received + * Returns the answer or NULL on failure + * BEWARE: Don't forget to free() return value! + * + * For example: SkypeGetProfile("FULLNAME", "Tweety"); +*/ +char *SkypeGetProfile(char *szProperty) { + return SkypeGet ("PROFILE", "", szProperty); +} + +/* SkypeSetProfile + * + * +*/ +int SkypeSetProfile(char *szProperty, char *szValue) { + return SkypeSend("SET PROFILE %s %s", szProperty, szValue); +} + +/* SkypeMsgCollectGarbage + * + * Purpose: Runs the garbage collector on the Skype Message-Queue to throw out old + * messages which may unnecessarily eat up memory. + * Params : age - Time in seconds. Messages older than this value will be + * thrown out. + * Returns: 0 - No messages were thrown out + * >0 - n messages were thrown out + */ +int SkypeMsgCollectGarbage(time_t age) { + return MsgQ_CollectGarbage(&SkypeMsgs, age); +} + + +/* SkypeCall + * + * Purpose: Give a Skype call to the given User in wParam + * or hangs up existing call + * (hangUp is moved over to SkypeCallHangup) + * Params : wParam - Handle to the User to be called + * lParam - Can be NULL + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeCall(WPARAM wParam, LPARAM lParam) { + DBVARIANT dbv; + char *msg=0; + int res; + + if (!DBGetContactSettingString((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { + res = -1; // no direct return, because dbv needs to be freed + } else { + if (DBGetContactSettingString((HANDLE)wParam, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) return -1; + msg=(char *)malloc(strlen(dbv.pszVal)+6); + strcpy(msg, "CALL "); + strcat(msg, dbv.pszVal); + res=SkypeSend(msg); + } + DBFreeVariant(&dbv); + free(msg); + return res; +} + +/* SkypeCallHangup + * + * Prupose: Hangs up the existing call to the given User + * in wParam. + * + * Params : wParam - Handle to the User to be called + * lParam - Can be NULL + * + * Returns: 0 - Success + * -1 - Failure + * + */ +INT_PTR SkypeCallHangup(WPARAM wParam, LPARAM lParam) +{ + DBVARIANT dbv; + char *msg=0; + int res = -1; + + if (!DBGetContactSettingString((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { + msg=(char *)malloc(strlen(dbv.pszVal)+21); + sprintf(msg, "SET %s STATUS FINISHED", dbv.pszVal); + //sprintf(msg, "ALTER CALL %s HANGUP", dbv.pszVal); + res=SkypeSend(msg); +#if _DEBUG + DBDeleteContactSetting((HANDLE)wParam, SKYPE_PROTONAME, "CallId"); +#endif + //} else { + // if (DBGetContactSetting((HANDLE)wParam, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) return -1; + // msg=(char *)malloc(strlen(dbv.pszVal)+6); + // strcpy(msg, "CALL "); + // strcat(msg, dbv.pszVal); + // res=SkypeSend(msg); + } + DBFreeVariant(&dbv); + free(msg); + return res; +} + +/* FixNumber + * + * Purpose: Eliminates all non-numeric chars from the given phonenumber + * Params : p - Pointer to the buffer with the number + */ +static void FixNumber(char *p) { + unsigned int i; + + for (i=0;i<=strlen(p);i++) + if ((p[i]<'0' || p[i]>'9')) + if (p[i]) { + memmove(p+i, p+i+1, strlen(p+i)); + i--; + } else break; +} + + +/* DialDlgProc + * + * Purpose: Dialog procedure for the Dial-Dialog + */ +static BOOL CALLBACK DialDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { + static HANDLE hContact; + static unsigned int entries=0; + BOOL TempAdded=FALSE; + char number[64], *msg, *ptr=NULL; + + switch (uMsg){ + case WM_INITDIALOG: + hContact=(HANDLE)lParam; + Utils_RestoreWindowPosition(hwndDlg, NULL, SKYPE_PROTONAME, "DIALdlg"); + TranslateDialogDefault(hwndDlg); + + if (lParam) { + DBVARIANT dbv; + BOOL bDialNow=TRUE; + + if (!DBGetContactSetting(hContact,"UserInfo","MyPhone1",&dbv)) { + int j; + char idstr[16]; + + // Multiple phone numbers, select one + bDialNow=FALSE; + DBFreeVariant(&dbv); + for(j=0;;j++) { + sprintf(idstr,"MyPhone%d",j); + if(DBGetContactSettingString(hContact,"UserInfo",idstr,&dbv)) break; + FixNumber(dbv.pszVal+1); // Leave + alone + SendDlgItemMessage(hwndDlg,IDC_NUMBER,CB_ADDSTRING,0,(LPARAM)dbv.pszVal); + DBFreeVariant(&dbv); + } + } + if (DBGetContactSettingString(hContact,SKYPE_PROTONAME,"SkypeOutNr",&dbv)) { + DBGetContactSettingString(hContact,"UserInfo","MyPhone0",&dbv); + FixNumber(dbv.pszVal+1); + } + SetDlgItemTextA(hwndDlg, IDC_NUMBER, dbv.pszVal); + DBFreeVariant(&dbv); + if (bDialNow) PostMessage(hwndDlg, WM_COMMAND, IDDIAL, 0); + } else { + DBVARIANT dbv; + char number[64]; + + for (entries=0;entriesMAX_ENTRIES) entries=MAX_ENTRIES; + for (i=entries;i>0;i--) { + sprintf(buf, "LastNumber%d", i-1); + if (!DBGetContactSettingString(NULL, SKYPE_PROTONAME, buf, &dbv)) { + sprintf(buf, "LastNumber%d", i); + DBWriteContactSettingString(NULL, SKYPE_PROTONAME, buf, dbv.pszVal); + DBFreeVariant(&dbv); + } else break; + } + DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "LastNumber0", number); + } + TempAdded=TRUE; + } + if (!DBWriteContactSettingString(hContact, SKYPE_PROTONAME, "SkypeOutNr", number)) { + msg=(char *)malloc(strlen(number)+6); + strcpy(msg, "CALL "); + strcat(msg, number); + if (SkypeSend(msg) || (ptr=SkypeRcv("ERROR", 500))) { + DBDeleteContactSetting(hContact, SKYPE_PROTONAME, "SkypeOutNr"); + if (ptr) { + OUTPUTA(ptr); + free(ptr); + } + if (TempAdded) CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0); + } + free(msg); + } + case IDCANCEL: + DestroyWindow(hwndDlg); + break; + } + break; + case WM_DESTROY: + Utils_SaveWindowPosition(hwndDlg, NULL, SKYPE_PROTONAME, "DIALdlg"); + if (httbButton) CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)httbButton, TTBST_RELEASED); + break; + } + return FALSE; +} + +/* CallstatDlgProc + * + * Purpose: Dialog procedure for the CallStatus Dialog + */ +static BOOL CALLBACK CallstatDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { + static int selected; + static DBVARIANT dbv, dbv2={0}; + + switch (uMsg){ + case WM_INITDIALOG: + { + HANDLE hContact; + char *szProto; + + if (!DBGetContactSettingString((HANDLE)lParam, SKYPE_PROTONAME, "CallId", &dbv)) { + + // Check, if another call is in progress + for (hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);hContact != NULL;hContact=(HANDLE)CallService( MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) { + szProto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0 ); + if (szProto!=NULL && !strcmp(szProto, SKYPE_PROTONAME) && hContact!=(HANDLE)lParam && + DBGetContactSettingByte(hContact, SKYPE_PROTONAME, "ChatRoom", 0) == 0 && + !DBGetContactSettingString(hContact, SKYPE_PROTONAME, "CallId", &dbv2)) + { + if (DBGetContactSettingByte(hContact, SKYPE_PROTONAME, "OnHold", 0)) { + DBFreeVariant(&dbv2); + continue; + } else break; + } + } + + if (dbv2.pszVal) + { + char buf[256], buf2[256]; + char *szOtherCaller=(char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,0); + + Utils_RestoreWindowPosition(hwndDlg, NULL, SKYPE_PROTONAME, "CALLSTATdlg"); + TranslateDialogDefault(hwndDlg); + SendMessage(hwndDlg, WM_COMMAND, IDC_JOIN, 0); + + GetWindowTextA(hwndDlg, buf, sizeof(buf)); + _snprintf(buf2, sizeof(buf), buf, CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)lParam,0)); + SetWindowTextA(hwndDlg, buf2); + + GetDlgItemTextA(hwndDlg, IDC_JOIN, buf, sizeof(buf)); + _snprintf(buf2, sizeof(buf), buf, szOtherCaller); + SetDlgItemTextA(hwndDlg, IDC_JOIN, buf2); + + GetDlgItemTextA(hwndDlg, IDC_HOLD, buf, sizeof(buf)); + _snprintf(buf2, sizeof(buf), buf, szOtherCaller); + SetDlgItemTextA(hwndDlg, IDC_HOLD, buf2); + + return TRUE; + } + + // No other call in progress, no need for this Dlg., just answer the call + SkypeSend("SET %s STATUS INPROGRESS", dbv.pszVal); + testfor ("ERROR", 200); + DBFreeVariant(&dbv); + } + DestroyWindow(hwndDlg); + break; + } + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_JOIN: + case IDC_HOLD: + case IDC_HANGUP: + CheckRadioButton(hwndDlg, IDC_JOIN, IDC_HANGUP, (selected=LOWORD(wParam))); + break; + case IDOK: + { + char *szIdCall2; + + switch (selected) { + case IDC_JOIN: + if (szIdCall2=strchr(dbv2.pszVal, ' ')) + SkypeSend("SET %s JOIN_CONFERENCE%s", dbv.pszVal, szIdCall2); + break; + case IDC_HOLD: + SkypeSend("SET %s STATUS ONHOLD", dbv2.pszVal); + SkypeSend("SET %s STATUS INPROGRESS", dbv.pszVal); + break; + case IDC_HANGUP: + SkypeSend("SET %s STATUS FINISHED", dbv.pszVal); + break; + } + + DBFreeVariant(&dbv); + DBFreeVariant(&dbv2); + DestroyWindow(hwndDlg); + break; + } + } + break; + case WM_DESTROY: + Utils_SaveWindowPosition(hwndDlg, NULL, SKYPE_PROTONAME, "CALLSTATdlg"); + break; + } + return FALSE; +} + + +/* SkypeOutCallErrorCheck + * + * Purpose: Checks, if an error has occured after call and + * if so, hangs up the call + * This procedure is a seperate thread to not block the core + * while waiting for "ERROR" + * Params : szCallId - ID of the call + */ +void SkypeOutCallErrorCheck(char *szCallId) { + if (testfor("ERROR", 500)) EndCallThread(szCallId); +} + +/* SkypeOutCall + * + * Purpose: Give a SkypeOut call to the given User in wParam + * or hangs up existing call + * The user's record is searched for Phone-number entries. + * If there is more than 1 entry, the Dial-Dialog is shown + * Params : wParam - Handle to the User to be called + * If NULL, the dial-dialog is shown + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeOutCall(WPARAM wParam, LPARAM lParam) { + DBVARIANT dbv; + int res = -1; + + if (wParam && !DBGetContactSettingString((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) { + res=SkypeSend("SET %s STATUS FINISHED", dbv.pszVal); + pthread_create(( pThreadFunc )SkypeOutCallErrorCheck, _strdup(dbv.pszVal)); + DBFreeVariant(&dbv); + } else if (!CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_DIAL), NULL, DialDlgProc, (LPARAM)wParam)) return -1; + return res; +} + +/* SkypeHoldCall + * + * Purpose: Put the call to the User given in wParam on Hold or Resumes it + * Params : wParam - Handle to the User + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeHoldCall(WPARAM wParam, LPARAM lParam) { + DBVARIANT dbv; + int retval; + + LOG(("SkypeHoldCall started")); + if (!wParam || DBGetContactSettingString((HANDLE)wParam, SKYPE_PROTONAME, "CallId", &dbv)) + return -1; + retval = SkypeSend ("SET %s STATUS %s", dbv.pszVal, + DBGetContactSettingByte((HANDLE)wParam, SKYPE_PROTONAME, "OnHold", 0)?"INPROGRESS":"ONHOLD"); + DBFreeVariant(&dbv); + return retval; +} + +/* SkypeAnswerCall + * + * Purpose: Answer a Skype-call when a user double-clicks on + * The incoming-call-Symbol. Works for both, Skype and SkypeOut-calls + * Params : wParam - Not used + * lParam - CLISTEVENT* + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeAnswerCall(WPARAM wParam, LPARAM lParam) { + + LOG(("SkypeAnswerCall started")); + CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_CALLSTAT), NULL, CallstatDlgProc, (LPARAM)((CLISTEVENT*)lParam)->hContact); + return 0; +} +/* SkypeSetNick + * + * Purpose: Set Full Name in profile + * Params : wParam=0 + * lParam=(LPARAM)(const char*)Nick text + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeSetNick(WPARAM wParam, LPARAM lParam) { + int retval = -1; + char *Nick = NULL; + + if (wParam & SMNN_UNICODE) + { + DBWriteContactSettingWString(0, SKYPE_PROTONAME, "Nick", (WCHAR*)lParam); + if (AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS && + !(Nick = (char*)make_utf8_string((WCHAR*)lParam))) return -1; + } + else + { + DBWriteContactSettingString(0, SKYPE_PROTONAME, "Nick", (char*)lParam); + if(AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS && + utf8_encode((const char *)lParam, &Nick) == -1 ) return -1; + } + if(AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS) + retval = SkypeSend("SET PROFILE FULLNAME %s", Nick); + if (Nick) free (Nick); + + return retval; + +} +/* SkypeSetAwayMessage + * + * Purpose: Set Mood message in profile + * Params : wParam=status mode + * lParam=(LPARAM)(const char*)message text + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeSetAwayMessage(WPARAM wParam, LPARAM lParam) { + int retval = -1; + char *Mood = NULL; + + if (!lParam) lParam=(LPARAM)""; + if(utf8_encode((const char *)lParam, &Mood) == -1 ) return -1; + DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "MoodText", (const char *)lParam); + + if(AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS) + retval = SkypeSend("SET PROFILE MOOD_TEXT %s", Mood); + free (Mood); + + return retval; +} +INT_PTR SkypeSetAwayMessageW(WPARAM wParam, LPARAM lParam) { + int retval = -1; + char *Mood = NULL; + + if (!lParam) lParam=(LPARAM)""; + if (!(Mood = (char*)make_utf8_string((WCHAR*)lParam))) return -1; + DBWriteContactSettingWString(NULL, SKYPE_PROTONAME, "MoodText", (WCHAR*)lParam); + + if(AttachStatus == SKYPECONTROLAPI_ATTACH_SUCCESS) + retval = SkypeSend("SET PROFILE MOOD_TEXT %s", Mood); + free (Mood); + + return retval; +} + +/* SkypeSetAvatar + * + * Purpose: Set user avatar in profile + * Params : wParam=0 + * lParam=(LPARAM)(const char*)filename + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeSetAvatar(WPARAM wParam, LPARAM lParam) { + char *filename = (char *) lParam, *ext; + char AvatarFile[MAX_PATH+1], OldAvatarFile[1024]; + char *ptr = NULL; + int ret; + char command[500]; + DBVARIANT dbv = {0}; + BOOL hasOldAvatar = (DBGetContactSettingString(NULL, SKYPE_PROTONAME, "AvatarFile", &dbv) == 0 && dbv.type == DBVT_ASCIIZ); + size_t len; + + if (AttachStatus != SKYPECONTROLAPI_ATTACH_SUCCESS) + return -3; + + if (filename == NULL) + return -1; + len = strlen(filename); + if (len < 4) + return -1; + + ext = &filename[len-4]; + if (_stricmp(ext, ".jpg")==0 || _stricmp(ext-1, ".jpeg")==0) + ext = "jpg"; + else if (_stricmp(ext, ".png")==0) + ext = "png"; + else + return -2; + + FoldersGetCustomPath(hProtocolAvatarsFolder, AvatarFile, sizeof(AvatarFile), DefaultAvatarsFolder); + mir_snprintf(AvatarFile, sizeof(AvatarFile), "%s\\%s avatar.%s", AvatarFile, SKYPE_PROTONAME, ext); + + // Backup old file + if (hasOldAvatar) + { + strncpy(OldAvatarFile, dbv.pszVal, sizeof(OldAvatarFile)-4); + OldAvatarFile[sizeof(OldAvatarFile)-5] = '\0'; + strcat(OldAvatarFile, "_old"); + DeleteFileA(OldAvatarFile); + if (!MoveFileA(dbv.pszVal, OldAvatarFile)) + { + DBFreeVariant(&dbv); + return -3; + } + } + + // Copy new file + if (!CopyFileA(filename, AvatarFile, FALSE)) + { + if (hasOldAvatar) + { + MoveFileA(OldAvatarFile, dbv.pszVal); + DBFreeVariant(&dbv); + } + return -3; + } + + // Try to set with skype + mir_snprintf(command, sizeof(command), "SET AVATAR 1 %s", AvatarFile); + if (SkypeSend(command) || (ptr = SkypeRcv(command+4, INFINITE)) == NULL || !strncmp(ptr, "ERROR", 5)) + { + DeleteFileA(AvatarFile); + + if (hasOldAvatar) + MoveFileA(OldAvatarFile, dbv.pszVal); + + ret = -4; + } + else + { + if (hasOldAvatar) + DeleteFileA(OldAvatarFile); + + DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "AvatarFile", AvatarFile); + + ret = 0; + } + + if (ptr != NULL) + free(ptr); + + if (hasOldAvatar) + DBFreeVariant(&dbv); + + return ret; +} + + +/* SkypeSendFile + * + * Purpose: Opens the Skype-dialog to send a file + * Params : wParam - Handle to the User + * lParam - Not used + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeSendFile(WPARAM wParam, LPARAM lParam) { + DBVARIANT dbv; + int retval; + + if (!wParam || DBGetContactSettingString((HANDLE)wParam, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) + return -1; + retval=SkypeSend("OPEN FILETRANSFER %s", dbv.pszVal); + DBFreeVariant(&dbv); + return retval; +} + +/* SkypeChatCreate + * + * Purpose: Creates a groupchat with the user + * Params : wParam - Handle to the User + * lParam - Not used + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeChatCreate(WPARAM wParam, LPARAM lParam) { + DBVARIANT dbv; + HANDLE hContact=(HANDLE)wParam; + char *ptr, *ptr2; + + if (!hContact || DBGetContactSettingString(hContact, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) + return -1; + // Flush old messages + while (testfor("\0CHAT \0 STATUS \0", 0)); + if (SkypeSend("CHAT CREATE %s", dbv.pszVal) || !(ptr=SkypeRcv ("\0CHAT \0 STATUS \0", INFINITE))) + { + DBFreeVariant(&dbv); + return -1; + } + DBFreeVariant(&dbv); + if (ptr2=strstr (ptr, "STATUS")) { + *(ptr2-1)=0; + ChatStart (ptr+5, FALSE); + } + free(ptr); + return 0; +} + +/* SkypeAdduserDlg + * + * Purpose: Show Skype's Add user Dialog + */ +INT_PTR SkypeAdduserDlg(WPARAM wParam, LPARAM lParam) { + SkypeSend("OPEN ADDAFRIEND"); + return 0; +} + +/* SkypeFlush + * + * Purpose: Flush the Skype Message-List + */ +void SkypeFlush(void) { + char *ptr; + + while ((ptr=SkypeRcv(NULL, 0))!=NULL) free(ptr); +} + +/* SkypeStatusToMiranda + * + * Purpose: Converts the specified Skype-Status mode to the corresponding Miranda-Status mode + * Params : s - Skype Status + * Returns: The correct Status + * 0 - Nothing found + */ +int SkypeStatusToMiranda(char *s) { + int i; + if (!strcmp("SKYPEOUT", s)) return DBGetContactSettingDword(NULL, SKYPE_PROTONAME, "SkypeOutStatusMode", ID_STATUS_ONTHEPHONE); + for(i=0; status_codes[i].szStat; i++) + if (!strcmp(status_codes[i].szStat, s)) + return status_codes[i].id; + return 0; +} + +/* MirandaStatusToSkype + * + * Purpose: Converts the specified Miranda-Status mode to the corresponding Skype-Status mode + * Params : id - Miranda Status + * Returns: The correct Status + * NULL - Nothing found + */ +char *MirandaStatusToSkype(int id) { + int i; + if (DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "NoSkype3Stats", 0)) { + switch (id) + { + case ID_STATUS_NA: return "AWAY"; + case ID_STATUS_FREECHAT: return "ONLINE"; + } + } + for(i=0; status_codes[i].szStat; i++) + if (status_codes[i].id==id) + return status_codes[i].szStat; + return NULL; +} + +/* GetSkypeErrorMsg + * + * Purpose: Get a human-readable Error-Message for the supplied Skype Error-Message + * Params : str - Skype Error-Message string + * Returns: Human-readable Error Message or NULL, if nothing was found + * Warning: Don't forget to free() return value + */ +char *GetSkypeErrorMsg(char *str) { + char *pos, *reason, *msg; + + LOG (("GetSkypeErrorMsg received error: %s", str)); + if (!strncmp(str, "ERROR", 5)) { + reason=_strdup(str); + return reason; + } + if ((pos=strstr(str, "FAILURE")) ) { + switch(atoi(pos+14)) { + case MISC_ERROR: msg="Misc. Error"; break; + case USER_NOT_FOUND: msg="User does not exist, check username"; break; + case USER_NOT_ONLINE: msg="Trying to send IM to an user, who is not online"; break; + case USER_BLOCKED: msg="IM blocked by recipient"; break; + case TYPE_UNSUPPORTED: msg="Type unsupported"; break; + case SENDER_NOT_FRIEND: msg="Sending IM message to user, who has not added you to friendslist and has chosen 'only people in my friendslist can start IM'"; break; + case SENDER_NOT_AUTHORIZED: msg="Sending IM message to user, who has not authorized you and has chosen 'only people whom I have authorized can start IM'"; break; + default: msg="Unknown error"; + } + reason=(char *)malloc(strlen(pos)+strlen(msg)+3); + sprintf (reason, "%s: %s", pos, msg); + return reason; + } + return NULL; +} + +/* testfor + * + * Purpose: Wait, until the given Message-Fragment is received from Skype within + * the given amount of time + * Params : see SkypeRcv + * Returns: TRUE - Message was received within the given amount of time + * FALSE- nope, sorry + */ +BOOL testfor(char *what, DWORD maxwait) { + char *res; + + if ((res=SkypeRcv(what, maxwait))==NULL) return FALSE; + free(res); + return TRUE; +} + +char SendSkypeproxyCommand(char command) { + int length=0; + char reply=0; + BOOL res; + + res = send(ClientSocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR + || send(ClientSocket, (char *)&command, sizeof(command), 0)==SOCKET_ERROR + || recv(ClientSocket, (char *)&reply, sizeof(reply), 0)==SOCKET_ERROR; + if (res) + return -1; + else + return reply; +} + +/* ConnectToSkypeAPI + * + * Purpose: Establish a connection to the Skype API + * Params : path - Path to the Skype application + * iStart - Need to start skype for status change. + * 1 = Normal start if Skype not running + * 2 = Forced startp code execution no matter what + * Returns: 0 - Connecting succeeded + * -1 - Something went wrong + */ +int ConnectToSkypeAPI(char *path, int iStart) { + static int iRet = -1; // last request result + static volatile long newRequest = TRUE; + + InterlockedExchange(&newRequest, TRUE); // place new request + EnterCriticalSection(&ConnectMutex); // Prevent reentrance + if (iRet == -1 || newRequest) + { + iRet = _ConnectToSkypeAPI(path, iStart); + InterlockedExchange(&newRequest, FALSE); // every thread which is waiting for connect mutex will get our result as well.. but subsequent calls will set this value to true and call _Connect again + } + LeaveCriticalSection(&ConnectMutex); + return iRet; +} + +void TranslateMirandaRelativePathToAbsolute(LPCSTR cszPath, LPSTR szAbsolutePath, BOOL fQuoteSpaces) { + *szAbsolutePath = 0; + CallService (MS_UTILS_PATHTOABSOLUTE, (WPARAM)(*cszPath ? cszPath : ".\\"), (LPARAM)szAbsolutePath); + if(fQuoteSpaces && strchr((LPCSTR)szAbsolutePath, ' ')){ + memmove (szAbsolutePath+1, szAbsolutePath, strlen(szAbsolutePath)+1); + *szAbsolutePath='"'; + strcat (szAbsolutePath, "\""); + } + + TRACEA(szAbsolutePath); +} + +static int my_spawnv(const char *cmdname, const char *const *argv, PROCESS_INFORMATION *pi) +{ + int i, iLen=0; + char *CommandLine; + STARTUPINFOA si={0}; + BOOL bRet; + + memset (pi, 0, sizeof(PROCESS_INFORMATION)); + for (i=0; argv[i]; i++) iLen+=strlen(argv[i])+1; + if (!(CommandLine = calloc(1, iLen))) return -1; + for (i=0; argv[i]; i++) { + if (i) strcat (CommandLine, " "); + strcat (CommandLine, argv[i]); + } + si.cb = sizeof(si); + + bRet = CreateProcessA( cmdname,CommandLine,NULL,NULL,FALSE,0,NULL,NULL,&si,pi); + free(CommandLine); + if (!bRet) return -1; + return (DWORD)pi->hProcess; +} + +static int _ConnectToSkypeAPI(char *path, int iStart) { + BOOL SkypeLaunched=FALSE; + BOOL UseCustomCommand = DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseCustomCommand", 0); + int counter=0, i, j, maxattempts=DBGetContactSettingWord(NULL, SKYPE_PROTONAME, "ConnectionAttempts", 10); + char *args[7], *pFree = NULL; + char *SkypeOptions[]={"/notray", "/nosplash", "/minimized", "/removable", "/datapath:", "/secondary"}; + const int SkypeDefaults[]={0, 1, 1, 0, 0}; + + char szAbsolutePath[MAX_PATH]; + + LOG(("ConnectToSkypeAPI started.")); + if (UseSockets) + { + SOCKADDR_IN service; + DBVARIANT dbv; + long inet; + struct hostent *hp; + + LOG(("ConnectToSkypeAPI: Connecting to Skype2socket socket...")); + if ((ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET) return -1; + + if (!DBGetContactSettingString(NULL, SKYPE_PROTONAME, "Host", &dbv)) { + if ((inet=inet_addr(dbv.pszVal))==-1) { + if (hp=gethostbyname(dbv.pszVal)) + memcpy(&inet, hp->h_addr, sizeof(inet)); + else { + OUTPUT(_T("Cannot resolve host!")); + DBFreeVariant(&dbv); + return -1; + } + } + DBFreeVariant(&dbv); + } else { + OUTPUT(_T("Cannot find valid host to connect to.")); + return -1; + } + + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet; + service.sin_port = htons((unsigned short)DBGetContactSettingWord(NULL, SKYPE_PROTONAME, "Port", 1401)); + + if ( connect( ClientSocket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR) return -1; + + if (DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "RequiresPassword", 0) && !DBGetContactSettingString(NULL, SKYPE_PROTONAME, "Password", &dbv)) + { + char reply=0; + + CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM)dbv.pszVal); + if ((reply=SendSkypeproxyCommand(AUTHENTICATE))==-1) + { + DBFreeVariant(&dbv); + return -1; + } + if (!reply) { + OUTPUT(_T("Authentication is not supported/needed for this Skypeproxy server. It will be disabled.")); + DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "RequiresPassword", 0); + } else { + unsigned int length=(unsigned int)strlen(dbv.pszVal); + BOOL res; + res = send(ClientSocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR + || send(ClientSocket, dbv.pszVal, length, 0)==SOCKET_ERROR + || recv(ClientSocket, (char *)&reply, sizeof(reply), 0)==SOCKET_ERROR; + if (res) + { + DBFreeVariant(&dbv); + return -1; + } + if (!reply) + { + OUTPUT(_T("Authentication failed for this server, connection was not successful. Verify that your password is correct!")); + DBFreeVariant(&dbv); + return -1; + } + } + DBFreeVariant(&dbv); + } + else + { + char reply=0; + + if ((reply=SendSkypeproxyCommand(CAPABILITIES))==-1) return -1; + if (reply&USE_AUTHENTICATION) { + OUTPUT(_T("The server you specified requires authentication, but you have not supplied a password for it. Check the Skype plugin settings and try again.")); + return -1; + } + } + + + if (!rcvThreadRunning) + if(_beginthread(( pThreadFunc )rcvThread, 0, NULL)==-1) return -1; + + AttachStatus=SKYPECONTROLAPI_ATTACH_SUCCESS; + return 0; + } + + if (pszProxyCallout) + { + if (SkypeSend("SET USERSTATUS ONLINE")==-1) + { + AttachStatus=SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE; + return -1; + } + for ( ;; ) { + char *ptr = SkypeRcv ("CONNSTATUS", INFINITE); + if (strcmp (ptr+11, "CONNECTING")) + { + free (ptr); + break; + } + free (ptr); + } + + AttachStatus=SKYPECONTROLAPI_ATTACH_SUCCESS; + return 0; + } + + do + { + int retval; + /* To initiate communication, Client should broadcast windows message + ('SkypeControlAPIDiscover') to all windows in the system, specifying its own + window handle in wParam parameter. + */ + if (iStart != 2 || counter) + { + LOG(("ConnectToSkypeAPI sending discover message.. hWnd=%08X", (long)g_hWnd)); + retval=SendMessageTimeout(HWND_BROADCAST, ControlAPIDiscover, (WPARAM)g_hWnd, 0, SMTO_ABORTIFHUNG, 3000, NULL); + LOG(("ConnectToSkypeAPI sent discover message returning %d", retval)); + } + + /* In response, Skype responds with + message 'SkypeControlAPIAttach' to the handle specified, and indicates + connection status + SkypeReady is set if there is an answer by Skype other than API_AVAILABLE. + If there is no answer after 3 seconds, launch Skype as it's propably + not running. + */ + if (iStart == 2 || (WaitForSingleObject(SkypeReady, 3000)==WAIT_TIMEOUT && AttachStatus!=SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION)) + { + if (iStart != 2 && g_hWnd==NULL) + { + LOG(("ConnectToSkypeAPI: hWnd of SkypeDispatchWindow not yet set..")); + continue; + } + if ((iStart == 2 || !SkypeLaunched) && (path || UseCustomCommand)) + { + static PROCESS_INFORMATION pi={0}; + DWORD dwExitStatus = 0; + + if ((!pi.hProcess || !GetExitCodeProcess(pi.hProcess, &dwExitStatus) || dwExitStatus != STILL_ACTIVE) && + (DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "StartSkype", 1) || iStart)) + { + LOG(("ConnectToSkypeAPI Starting Skype, as it's not running")); + + j=1; + for (i=0; i=maxattempts && AttachStatus==-1) + { + int oldstatus=SkypeStatus; + InterlockedExchange((long *)&SkypeStatus, (int)ID_STATUS_OFFLINE); + ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldstatus, SkypeStatus); + OUTPUT(_T("ERROR: Skype not running / too old / working!")); + return -1; + } + } + } + LOG(("Attachstatus %d", AttachStatus)); + } while (AttachStatus==SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE || AttachStatus==SKYPECONTROLAPI_ATTACH_API_AVAILABLE || AttachStatus==-1); + + while (AttachStatus==SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION) Sleep(1000); + LOG(("Attachstatus %d", AttachStatus)); + if (AttachStatus!=SKYPECONTROLAPI_ATTACH_SUCCESS) { + int oldstatus; + + switch(AttachStatus) { + case SKYPECONTROLAPI_ATTACH_REFUSED: + OUTPUT(_T("Skype refused the connection :(")); + break; + case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE: + OUTPUT(_T("The Skype API is not available")); + break; + default: + LOG(("ERROR: AttachStatus: %d", AttachStatus)); + OUTPUT(_T("Wheee, Skype won't let me use the API. :(")); + } + oldstatus=SkypeStatus; + InterlockedExchange((long *)&SkypeStatus, (int)ID_STATUS_OFFLINE); + ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldstatus, SkypeStatus); + return -1; + } + + return 0; +} + +/* CloseSkypeAPI + * Purpose: Closes existing api connection + * Params: path - Path to the Skype application; could be NULL when using proxy + * Returns: always 0 + */ +int CloseSkypeAPI(char *skypePath) +{ + char szAbsolutePath[MAX_PATH]; + + logoff_contacts(TRUE); + if (UseSockets) + { + if (ClientSocket != INVALID_SOCKET) + { + closesocket(ClientSocket); + ClientSocket = INVALID_SOCKET; + } + } + else { + if (!pszProxyCallout) + { + if (AttachStatus!=-1) + { + // it was crashing when the skype-network-proxy is used (imo2sproxy for imo.im) and skype-path is empty + // now, with the "UseSockets" check and the skypePath[0] != 0 check its fixed + if (skypePath != NULL && skypePath[0] != 0) { + TranslateMirandaRelativePathToAbsolute(skypePath, szAbsolutePath, FALSE); + _spawnl(_P_NOWAIT, szAbsolutePath, szAbsolutePath, "/SHUTDOWN", NULL); + } + } + } + } + SkypeInitialized=FALSE; + ResetEvent(SkypeReady); + AttachStatus=-1; + if (g_hWnd) KillTimer (g_hWnd, 1); + return 0; +} +/* ConnectToSkypeAPI + * + * Purpose: Establish a connection to the Skype API + * Params : path - Path to the Skype application + * Returns: 0 - Connecting succeeded + * -1 - Something went wrong + */ +//int __connectAPI(char *path) { +// int retval; +// +// EnterCriticalSection(&ConnectMutex); +// if (AttachStatus!=-1) { +// LeaveCriticalSection(&ConnectMutex); +// return -1; +// } +// InterlockedExchange((long *)&SkypeStatus, ID_STATUS_CONNECTING); +// ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) ID_STATUS_OFFLINE, SkypeStatus); +// retval=__connectAPI(path); +// if (retval==-1) { +// logoff_contacts(); +// InterlockedExchange((long *)&SkypeStatus, ID_STATUS_OFFLINE); +// ProtoBroadcastAck(SKYPE_PROTONAME, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) ID_STATUS_CONNECTING, SkypeStatus); +// } +// LeaveCriticalSection(&ConnectMutex); +// return retval; +//} diff --git a/plugins/!NotAdopted/Skype/skypeapi.h b/plugins/!NotAdopted/Skype/skypeapi.h new file mode 100644 index 0000000000..fa4f5139a1 --- /dev/null +++ b/plugins/!NotAdopted/Skype/skypeapi.h @@ -0,0 +1,69 @@ +// Skype API defines +#define SKYPECONTROLAPI_ATTACH_SUCCESS 0 +#define SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION 1 +#define SKYPECONTROLAPI_ATTACH_REFUSED 2 +#define SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE 3 +#define SKYPECONTROLAPI_ATTACH_API_AVAILABLE 0x8001 + +#define MISC_ERROR 1 +#define USER_NOT_FOUND 2 +#define USER_NOT_ONLINE 3 +#define USER_BLOCKED 4 +#define TYPE_UNSUPPORTED 5 +#define SENDER_NOT_FRIEND 6 +#define SENDER_NOT_AUTHORIZED 7 + +#define MAX_ENTRIES 128 // Max. 128 number-Entries in Dial-dlg. + +typedef struct { + int id; + char *szStat; +} status_map; + +// Prototypes +int SkypeMsgInit(void); +int SkypeMsgAdd(char *msg); +void SkypeMsgCleanup(void); +char *SkypeMsgGet(void); +int SkypeSend(char*, ...); +char *SkypeRcv(char *what, DWORD maxwait); +char *SkypeRcvTime(char *what, time_t st, DWORD maxwait); +char *SkypeRcvMsg(char *what, time_t st, HANDLE hContact, DWORD maxwait); +INT_PTR SkypeCall(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeCallHangup(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeOutCall(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeHup(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeHoldCall(WPARAM wParam, LPARAM lParam); +void SkypeFlush(void); +int SkypeStatusToMiranda(char *s); +char *MirandaStatusToSkype(int id); +char *GetSkypeErrorMsg(char *str); +BOOL testfor(char *what, DWORD maxwait); +int ConnectToSkypeAPI(char *path, BOOL bStart); +int CloseSkypeAPI(char *skypePath); +INT_PTR SkypeAdduserDlg(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeAnswerCall(WPARAM wParam, LPARAM lParam); +int SkypeMsgCollectGarbage(time_t age); +INT_PTR SkypeSendFile(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeSetAvatar(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeSetAwayMessage(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeSetAwayMessageW(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeSetNick(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeChatCreate(WPARAM wParam, LPARAM lParam); +int SkypeSetProfile(char *szProperty, char *szValue); +char *SkypeGet(char *szWhat, char *szWho, char *szProperty); +char *SkypeGetID(char *szWhat, char *szWho, char *szProperty); +char *SkypeGetErr(char *szWhat, char *szWho, char *szProperty); +#ifdef _UNICODE +WCHAR *SkypeGetW(char *szWhat, WCHAR *szWho, char *szProperty); +WCHAR *SkypeGetErrW(char *szWhat, TCHAR *szWho, char *szProperty); +#define SkypeGetT SkypeGetW +#define SkypeGetErrT SkypeGetErrW +#else +#define SkypeGetT SkypeGet +#define SkypeGetErrT SkypeGetErr +#endif +char *SkypeGetProfile(char *szProperty); +void SetUserNamePassword(); +INT_PTR SkypeAdduserDlg(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeReceivedAPIMessage(WPARAM wParam, LPARAM lParam); diff --git a/plugins/!NotAdopted/Skype/skypeopt.c b/plugins/!NotAdopted/Skype/skypeopt.c new file mode 100644 index 0000000000..2dfc4faef5 --- /dev/null +++ b/plugins/!NotAdopted/Skype/skypeopt.c @@ -0,0 +1,969 @@ +#include "skype.h" +#include "skypeopt.h" +#include "pthread.h" +#include "gchat.h" +#include "skypeprofile.h" +#if(WINVER >= 0x0500) +#include "uxtheme.h" +#define HAVE_UXTHEMES +#endif + +#ifdef SKYPE_AUTO_DETECTION +#include "ezxml/ezxml.c" +#endif + +#ifdef UNICODE +#include "utf8.h" +#endif + +#pragma warning (disable: 4706) // assignment within conditional expression + +// VC6 SDK defines +#ifndef BIF_SHAREABLE +#define BIF_SHAREABLE 0x8000 // sharable resources displayed (remote shares, requires BIF_USENEWUI) +#endif +#ifndef BIF_NEWDIALOGSTYLE +#define BIF_NEWDIALOGSTYLE 0x0040 // Use the new dialog layout with the ability to resize +#endif // Caller needs to call OleInitialize() before using this API +#ifndef BIF_NONEWFOLDERBUTTON +#define BIF_NONEWFOLDERBUTTON 0x0200 // Do not add the "New Folder" button to the dialog. Only applicable with BIF_NEWDIALOGSTYLE. +#endif + + +extern HINSTANCE hInst; +extern PLUGININFO pluginInfo; +extern char protocol, g_szProtoName[]; +extern BOOL SkypeInitialized, bProtocolSet, bIsImoproxy; +extern DWORD mirandaVersion; + +BOOL showPopup, showPopupErr, popupWindowColor, popupWindowColorErr; +unsigned int popupBackColor, popupBackColorErr; +unsigned int popupTextColor, popupTextColorErr; +int popupTimeSec, popupTimeSecErr; +POPUPDATAT InCallPopup; +POPUPDATAT ErrorPopup; + +static SkypeProfile myProfile; +static HBITMAP hAvatar = NULL; + +extern BOOL PopupServiceExists; +extern BOOL (WINAPI *MyEnableThemeDialogTexture)(HANDLE, DWORD); + +int RegisterOptions(WPARAM wParam, LPARAM lParam) { + OPTIONSDIALOGPAGE odp; + + UNREFERENCED_PARAMETER(lParam); + + ZeroMemory(&odp, sizeof(odp)); + odp.cbSize = sizeof(odp); + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); + odp.pszGroup = "Network"; + odp.pszTitle = SKYPE_PROTONAME; + odp.pfnDlgProc = OptionsDlgProc; + odp.flags = ODPF_BOLDGROUPS; + CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp); + + if(PopupServiceExists) + { + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_POPUP); + odp.pszGroup = "Popups"; + odp.pfnDlgProc = OptPopupDlgProc; + CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp); + } + + return 0; +} + +INT_PTR CALLBACK OptPopupDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static RECT r; + + switch ( msg ) + { + case WM_INITDIALOG: + TranslateDialogDefault( hwnd ); + // Message Popup + popupTimeSec = DBGetContactSettingDword(NULL, SKYPE_PROTONAME, "popupTimeSec", 4); + popupTextColor = DBGetContactSettingDword(NULL, SKYPE_PROTONAME, "popupTextColor", GetSysColor(COLOR_WINDOWTEXT)); + popupBackColor = DBGetContactSettingDword(NULL, SKYPE_PROTONAME, "popupBackColor", GetSysColor(COLOR_BTNFACE)); + popupWindowColor = DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "popupWindowColor", FALSE); + showPopup = DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "showPopup", TRUE); + // ERROR Message Popup + popupTimeSecErr = DBGetContactSettingDword(NULL, SKYPE_PROTONAME, "popupTimeSecErr", 4); + popupTextColorErr = DBGetContactSettingDword(NULL, SKYPE_PROTONAME, "popupTextColorErr", GetSysColor(COLOR_WINDOWTEXT)); + popupBackColorErr = DBGetContactSettingDword(NULL, SKYPE_PROTONAME, "popupBackColorErr", GetSysColor(COLOR_BTNFACE)); + popupWindowColorErr = DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "popupWindowColorErr", FALSE); + showPopupErr = DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "showPopupErr", TRUE); + + EnableWindow(GetDlgItem(hwnd,IDC_USEWINCOLORS),showPopup); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLOR),showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLOR),showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLOR),showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLOR),showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTIME),showPopup); + EnableWindow(GetDlgItem(hwnd,IDC_PREVIEW),showPopup); + EnableWindow(GetDlgItem(hwnd,IDC_USEWINCOLORSERR),showPopupErr); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLORERR),showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLORERR),showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLORERR),showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLORERR),showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTIMEERR),showPopupErr); + EnableWindow(GetDlgItem(hwnd,IDC_PREVIEWERR),showPopupErr); + CheckDlgButton(hwnd, IDC_POPUPINCOMING, (WPARAM) showPopup); + CheckDlgButton(hwnd, IDC_USEWINCOLORS, (WPARAM) popupWindowColor); + CheckDlgButton(hwnd, IDC_POPUPERROR, (WPARAM) showPopupErr); + CheckDlgButton(hwnd, IDC_USEWINCOLORSERR, (WPARAM) popupWindowColorErr); + SendDlgItemMessage(hwnd, IDC_POPUPTIME, EM_SETLIMITTEXT, 3, 0L); + SetDlgItemInt(hwnd, IDC_POPUPTIME, popupTimeSec,FALSE); + SendDlgItemMessage(hwnd, IDC_POPUPTIMEERR, EM_SETLIMITTEXT, 3, 0L); + SetDlgItemInt(hwnd, IDC_POPUPTIMEERR, popupTimeSecErr,FALSE); + SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLOR, CPM_SETCOLOUR,0, popupBackColor); + SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLOR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_BTNFACE)); + SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLOR, CPM_SETCOLOUR,0, popupTextColor); + SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLOR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_WINDOWTEXT)); + SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLORERR, CPM_SETCOLOUR,0, popupBackColorErr); + SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLORERR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_BTNFACE)); + SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLORERR, CPM_SETCOLOUR,0, popupTextColorErr); + SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLORERR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_WINDOWTEXT)); + + + return TRUE; + break; + + case WM_NOTIFY: + switch(((LPNMHDR)lParam)->idFrom) + { + case 0: + switch (((LPNMHDR)lParam)->code) + { + case PSN_APPLY: + DBWriteContactSettingDword(NULL, SKYPE_PROTONAME, "popupBackColor", popupBackColor); + DBWriteContactSettingDword(NULL, SKYPE_PROTONAME, "popupTextColor", popupTextColor); + DBWriteContactSettingDword(NULL, SKYPE_PROTONAME, "popupTimeSec", popupTimeSec); + DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "popupWindowColor", (BYTE)popupWindowColor); + DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "showPopup", (BYTE)showPopup); + DBWriteContactSettingDword(NULL, SKYPE_PROTONAME, "popupBackColorErr", popupBackColorErr); + DBWriteContactSettingDword(NULL, SKYPE_PROTONAME, "popupTextColorErr", popupTextColorErr); + DBWriteContactSettingDword(NULL, SKYPE_PROTONAME, "popupTimeSecErr", popupTimeSecErr); + DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "popupWindowColorErr", (BYTE)popupWindowColorErr); + DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "showPopupErr", (BYTE)showPopupErr); + break; + } + } + break; + + + + case WM_COMMAND: + switch( LOWORD( wParam )) + { + case IDC_PREVIEW: + { + HANDLE hContact; + TCHAR * lpzContactName; + + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST,0,0); + lpzContactName = (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,GCDNF_TCHAR); + InCallPopup.lchContact = hContact; + InCallPopup.lchIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALL)); + InCallPopup.colorBack = ! popupWindowColor ? popupBackColor : GetSysColor(COLOR_BTNFACE); + InCallPopup.colorText = ! popupWindowColor ? popupTextColor : GetSysColor(COLOR_WINDOWTEXT); + InCallPopup.iSeconds = popupTimeSec; + InCallPopup.PluginData = (void *)1; + + lstrcpy(InCallPopup.lptzText, TranslateT("Incoming Skype Call")); + + lstrcpy(InCallPopup.lptzContactName, lpzContactName); + + CallService(MS_POPUP_ADDPOPUPT,(WPARAM)&InCallPopup,0); + + + break; + } + case IDC_PREVIEWERR: + ErrorPopup.lchContact = NULL; + ErrorPopup.lchIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_CALL)); + ErrorPopup.colorBack = ! popupWindowColorErr ? popupBackColorErr : GetSysColor(COLOR_BTNFACE); + ErrorPopup.colorText = ! popupWindowColorErr ? popupTextColorErr : GetSysColor(COLOR_WINDOWTEXT); + ErrorPopup.iSeconds = popupTimeSecErr; + ErrorPopup.PluginData = (void *)1; + + lstrcpy(ErrorPopup.lptzText, TranslateT("Preview Error Message")); + + lstrcpy(ErrorPopup.lptzContactName, _T("Error Message")); + + + CallService(MS_POPUP_ADDPOPUPT,(WPARAM)&ErrorPopup,0); + + break; + + case IDC_POPUPTIME: + case IDC_POPUPTIMEERR: + { + BOOL Translated; + popupTimeSec = GetDlgItemInt(hwnd,IDC_POPUPTIME,&Translated,FALSE); + popupTimeSecErr = GetDlgItemInt(hwnd,IDC_POPUPTIMEERR,&Translated,FALSE); + SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); + break; + } + case IDC_POPUPTEXTCOLOR: + case IDC_POPUPBACKCOLOR: + case IDC_POPUPTEXTCOLORERR: + case IDC_POPUPBACKCOLORERR: + popupBackColor = SendDlgItemMessage(hwnd,IDC_POPUPBACKCOLOR,CPM_GETCOLOUR,0,0); + popupTextColor = SendDlgItemMessage(hwnd,IDC_POPUPTEXTCOLOR,CPM_GETCOLOUR,0,0); + popupBackColorErr = SendDlgItemMessage(hwnd,IDC_POPUPBACKCOLORERR,CPM_GETCOLOUR,0,0); + popupTextColorErr = SendDlgItemMessage(hwnd,IDC_POPUPTEXTCOLORERR,CPM_GETCOLOUR,0,0); + SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); + break; + case IDC_USEWINCOLORS: + popupWindowColor = (IsDlgButtonChecked(hwnd,IDC_USEWINCOLORS)==BST_CHECKED); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLOR), showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLOR), showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLOR), showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLOR), showPopup && ! popupWindowColor); + SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); + break; + case IDC_POPUPINCOMING: + showPopup = (IsDlgButtonChecked(hwnd,IDC_POPUPINCOMING)==BST_CHECKED); + EnableWindow(GetDlgItem(hwnd,IDC_USEWINCOLORS),showPopup); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLOR),showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLOR),showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLOR),showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLOR),showPopup && ! popupWindowColor); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTIME),showPopup); + EnableWindow(GetDlgItem(hwnd,IDC_PREVIEW),showPopup); + SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); + break; + case IDC_USEWINCOLORSERR: + popupWindowColorErr = (IsDlgButtonChecked(hwnd,IDC_USEWINCOLORSERR)==BST_CHECKED); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLORERR), showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLORERR), showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLORERR), showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLORERR), showPopupErr && ! popupWindowColorErr); + SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); + break; + case IDC_POPUPERROR: + showPopupErr = (IsDlgButtonChecked(hwnd,IDC_POPUPERROR)==BST_CHECKED); + EnableWindow(GetDlgItem(hwnd,IDC_USEWINCOLORSERR),showPopupErr); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLORERR),showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPBACKCOLORERR),showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLORERR),showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_STATIC_POPUPTEXTCOLORERR),showPopupErr && ! popupWindowColorErr); + EnableWindow(GetDlgItem(hwnd,IDC_POPUPTIMEERR),showPopupErr); + EnableWindow(GetDlgItem(hwnd,IDC_PREVIEWERR),showPopupErr); + SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); + break; + } + + break; + + case WM_DESTROY: + break; + } + + return 0; +} + +INT_PTR CALLBACK OptionsDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static int iInit = TRUE; + + UNREFERENCED_PARAMETER(wParam); + + switch(msg) + { + case WM_INITDIALOG: + { + TCITEM tci; + RECT rcClient; + GetClientRect(hwnd, &rcClient); + + iInit = TRUE; + tci.mask = TCIF_PARAM|TCIF_TEXT; + tci.lParam = (LPARAM)CreateDialog(hInst,MAKEINTRESOURCE(IDD_OPT_DEFAULT), hwnd, OptionsDefaultDlgProc); + tci.pszText = TranslateT("Skype default"); + TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 0, &tci); + MoveWindow((HWND)tci.lParam,1,28,rcClient.right-5,rcClient.bottom-31,1); +#ifdef HAVE_UXTHEMES + if(MyEnableThemeDialogTexture) + MyEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB); +#endif + + tci.lParam = (LPARAM)CreateDialog(hInst,MAKEINTRESOURCE(IDD_OPT_ADVANCED),hwnd,OptionsAdvancedDlgProc); + tci.pszText = TranslateT("Skype advanced"); + TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 1, &tci); + MoveWindow((HWND)tci.lParam,1,28,rcClient.right-5,rcClient.bottom-31,1); + ShowWindow((HWND)tci.lParam, SW_HIDE); +#ifdef HAVE_UXTHEMES + if(MyEnableThemeDialogTexture) + MyEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB); +#endif + + tci.lParam = (LPARAM)CreateDialog(hInst,MAKEINTRESOURCE(IDD_OPT_PROXY),hwnd,OptionsProxyDlgProc); + tci.pszText = TranslateT("Skype proxy"); + TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 2, &tci); + MoveWindow((HWND)tci.lParam,1,28,rcClient.right-5,rcClient.bottom-31,1); + ShowWindow((HWND)tci.lParam, SW_HIDE); +#ifdef HAVE_UXTHEMES + if(MyEnableThemeDialogTexture) + MyEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB); +#endif + + iInit = FALSE; + return FALSE; + } + + case PSM_CHANGED: // used so tabs dont have to call SendMessage(GetParent(GetParent(hwnd)), PSM_CHANGED, 0, 0); + if(!iInit) + SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); + break; + case WM_NOTIFY: + switch(((LPNMHDR)lParam)->idFrom) { + case 0: + switch (((LPNMHDR)lParam)->code) + { + case PSN_APPLY: + { + TCITEM tci; + int i,count; + tci.mask = TCIF_PARAM; + count = TabCtrl_GetItemCount(GetDlgItem(hwnd,IDC_OPTIONSTAB)); + for (i=0;icode) + { + case TCN_SELCHANGING: + { + TCITEM tci; + tci.mask = TCIF_PARAM; + TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci); + ShowWindow((HWND)tci.lParam,SW_HIDE); + } + break; + case TCN_SELCHANGE: + { + TCITEM tci; + tci.mask = TCIF_PARAM; + TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci); + ShowWindow((HWND)tci.lParam,SW_SHOW); + } + break; + } + break; + + } + break; + } + return FALSE; +} + +INT_PTR CALLBACK OptionsProxyDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { + const int Skype2SocketControls[]={ IDC_STATIC_HOST, IDC_HOST, IDC_STATIC_PORT, IDC_PORT, IDC_REQPASS, IDC_PASSWORD, IDC_STATIC_RESTART }; + static BOOL initDlg=FALSE; + DBVARIANT dbv; + int i; + + switch (uMsg){ + case WM_INITDIALOG: + initDlg=TRUE; + TranslateDialogDefault(hwndDlg); + if (!DBGetContactSettingString(NULL, SKYPE_PROTONAME, "Host", &dbv)) { + SetDlgItemTextA(hwndDlg, IDC_HOST, dbv.pszVal); + DBFreeVariant(&dbv); + } else SetDlgItemText(hwndDlg, IDC_HOST, _T("localhost")); + SendDlgItemMessage(hwndDlg, IDC_PORT, EM_SETLIMITTEXT, 5, 0L); + SetDlgItemInt(hwndDlg, IDC_PORT, DBGetContactSettingWord(NULL, SKYPE_PROTONAME, "Port", 1401), FALSE); + CheckDlgButton(hwndDlg, IDC_REQPASS, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "RequiresPassword", 0)); + CheckDlgButton(hwndDlg, IDC_USES2S, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseSkype2Socket", 0)); + if (!DBGetContactSettingString(NULL, SKYPE_PROTONAME, "Password", &dbv)) { + CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM)dbv.pszVal); + SetDlgItemTextA(hwndDlg, IDC_PASSWORD, dbv.pszVal); + DBFreeVariant(&dbv); + } + SendMessage(hwndDlg, WM_COMMAND, IDC_USES2S, 0); + SendMessage(hwndDlg, WM_COMMAND, IDC_REQPASS, 0); + initDlg=FALSE; + return TRUE; + case WM_NOTIFY: { + NMHDR* nmhdr = (NMHDR*)lParam; + + switch (nmhdr->code){ + case PSN_APPLY: + case PSN_KILLACTIVE: + { + char buf[1024]; + GetDlgItemTextA(hwndDlg, IDC_HOST, buf, sizeof(buf)); + DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "Host", buf); + DBWriteContactSettingWord(NULL, SKYPE_PROTONAME, "Port", (unsigned short)GetDlgItemInt(hwndDlg, IDC_PORT, NULL, FALSE)); + DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "RequiresPassword", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_REQPASS), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "UseSkype2Socket", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_USES2S), BM_GETCHECK,0,0))); + ZeroMemory(buf, sizeof(buf)); + GetDlgItemTextA(hwndDlg, IDC_PASSWORD, buf, sizeof(buf)); + CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(buf), (LPARAM)buf); + DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "Password", buf); + return TRUE; + } + } + break; + } + case WM_COMMAND: { + switch (LOWORD(wParam)) { + case IDC_USES2S: + for (i=0; i=5)) { + CheckDlgButton(hwndDlg, IDC_GROUPCHAT, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseGroupchat", 0)); + CheckDlgButton(hwndDlg, IDC_GROUPCHATREAD, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "MarkGroupchatRead", 0)); + } else { + EnableWindow(GetDlgItem(hwndDlg, IDC_GROUPCHAT), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_GROUPCHATREAD), FALSE); + } + +#ifdef USEPOPUP + if (ServiceExists(MS_POPUP_ADDPOPUP)) + CheckDlgButton(hwndDlg, IDC_USEPOPUP, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UsePopup", 0)); + else +#endif + EnableWindow(GetDlgItem(hwndDlg, IDC_USEPOPUP), FALSE); + + j=DBGetContactSettingDword(NULL, SKYPE_PROTONAME, "SkypeOutStatusMode", ID_STATUS_ONTHEPHONE); + for(i=0;icode){ + case PSN_APPLY: + case PSN_KILLACTIVE: + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "EnableMenu", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_ENABLEMENU), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "UsePopup", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_USEPOPUP), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "UseGroupchat", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_GROUPCHAT), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "MarkGroupchatRead", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_GROUPCHATREAD), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "SuppressErrors", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_NOERRORS), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "KeepState", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_KEEPSTATE), BM_GETCHECK,0,0))); + DBWriteContactSettingDword(NULL, SKYPE_PROTONAME, "SkypeOutStatusMode", SendDlgItemMessage(hwndDlg,IDC_SKYPEOUTSTAT,CB_GETITEMDATA,SendDlgItemMessage(hwndDlg,IDC_SKYPEOUTSTAT,CB_GETCURSEL,0,0),0)); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "UseTimeZonePatch", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_TIMEZONE), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "IgnoreTimeZones", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_IGNTZ), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "ShowDefaultSkypeAvatar", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SHOWDEFAULTAVATAR), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "SuppressCallSummaryMessage", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SUPPRESSCALLSUMMARYMESSAGE), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "NoSkype3Stats", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_NOSKYPE3STATS), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "ShowFullname", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SHOWFULLNAME), BM_GETCHECK,0,0))); + return TRUE; + } + break; + } + case WM_COMMAND: { + switch (LOWORD(wParam)) { + case IDC_CLEANUP: + pthread_create(( pThreadFunc )CleanupNicknames, NULL); + break; + } + if (!initDlg) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + return 0; +} + +static int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData) +{ + UNREFERENCED_PARAMETER(lParam); + + switch (uMsg) + { + case BFFM_INITIALIZED: + { + // Set initial directory. +#ifdef UNICODE + wchar_t* wszInitFolder = make_unicode_string((const unsigned char*)lpData); + SendMessage(hWnd, BFFM_SETSELECTION, TRUE, (LPARAM)wszInitFolder); + free(wszInitFolder); +#else + SendMessage(hWnd, BFFM_SETSELECTION, TRUE, lpData); +#endif + break; + } + } + return 0; +} + +INT_PTR CALLBACK OptionsDefaultDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { + static BOOL initDlg=FALSE; + static int skypeLaunchControls[]={IDC_NOSPLASH,IDC_MINIMIZED,IDC_NOTRAY,IDC_REMOVEABLE,IDC_SECONDARY,IDC_DATAPATHO,IDC_CUSTOMCOMMAND,IDC_STATIC_PATHINFO}; + + switch (uMsg){ + case WM_INITDIALOG: + { + DBVARIANT dbv; + BOOL startSkype; + int i; + + initDlg=TRUE; + TranslateDialogDefault(hwndDlg); + + startSkype=DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "StartSkype", 1); + + CheckDlgButton(hwndDlg, IDC_STARTSKYPE, (BYTE)startSkype); + CheckDlgButton(hwndDlg, IDC_NOSPLASH, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "nosplash", 1)); + CheckDlgButton(hwndDlg, IDC_MINIMIZED, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "minimized", 1)); + CheckDlgButton(hwndDlg, IDC_NOTRAY, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "notray", 0)); + CheckDlgButton(hwndDlg, IDC_REMOVEABLE, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "removable", 0)); + CheckDlgButton(hwndDlg, IDC_SECONDARY, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "secondary", 0)); + CheckDlgButton(hwndDlg, IDC_DATAPATHO, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "datapath:", 0)); + CheckDlgButton(hwndDlg, IDC_SHUTDOWN, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "Shutdown", 0)); + CheckDlgButton(hwndDlg, IDC_UNLOADOFFLINE, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UnloadOnOffline", 0)); + + CheckDlgButton(hwndDlg, IDC_CUSTOMCOMMAND, (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseCustomCommand", 0)); + SendDlgItemMessage(hwndDlg, IDC_COMMANDLINE, EM_SETLIMITTEXT, MAX_PATH-1, 0L); + if(!DBGetContactSettingString(NULL,SKYPE_PROTONAME,"CommandLine",&dbv)) + { + SetWindowTextA(GetDlgItem(hwndDlg, IDC_COMMANDLINE), dbv.pszVal); + DBFreeVariant(&dbv); + } + + SendDlgItemMessage(hwndDlg, IDC_DATAPATH, EM_SETLIMITTEXT, MAX_PATH-1, 0L); + if(!DBGetContactSettingString(NULL,SKYPE_PROTONAME,"datapath",&dbv)) + { + SetWindowTextA(GetDlgItem(hwndDlg, IDC_DATAPATH), dbv.pszVal); + DBFreeVariant(&dbv); + } + + for(i=0; i < sizeof(skypeLaunchControls)/sizeof(skypeLaunchControls[0]); i++) + EnableWindow(GetDlgItem(hwndDlg, skypeLaunchControls[i]), startSkype); + + EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSECMDL), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); + EnableWindow(GetDlgItem(hwndDlg, IDC_COMMANDLINE), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); + + EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSEDP), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); + EnableWindow(GetDlgItem(hwndDlg, IDC_DATAPATH), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); + + // LoginUserName + if(!DBGetContactSettingWString(NULL,SKYPE_PROTONAME,"LoginUserName",&dbv)) + { + SetWindowTextW(GetDlgItem(hwndDlg, IDC_USERNAME), dbv.pwszVal); + DBFreeVariant(&dbv); + } + + // LoginPassword + if(!DBGetContactSettingWString(NULL,SKYPE_PROTONAME,"LoginPassword",&dbv)) + { + SetWindowTextW(GetDlgItem(hwndDlg, IDC_PASSWORD), dbv.pwszVal); + DBFreeVariant(&dbv); + } + + SendDlgItemMessage(hwndDlg, IDC_CONNATTEMPTS, EM_SETLIMITTEXT, 3, 0L); + SetDlgItemInt (hwndDlg, IDC_CONNATTEMPTS, DBGetContactSettingWord(NULL, SKYPE_PROTONAME, "ConnectionAttempts", 10), FALSE); + SendMessage(hwndDlg, WM_COMMAND, IDC_STARTSKYPE, 0); + initDlg=FALSE; + return TRUE; + } + case WM_NOTIFY: { + NMHDR* nmhdr = (NMHDR*)lParam; + + switch (nmhdr->code){ + case PSN_APPLY: + case PSN_KILLACTIVE: + { + char text[500]; + WCHAR wtext[500]; + char szRelativePath[MAX_PATH]; + + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "StartSkype", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_STARTSKYPE), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "nosplash", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_NOSPLASH), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "minimized", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_MINIMIZED), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "notray", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_NOTRAY), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "Shutdown", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SHUTDOWN), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "UnloadOnOffline", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_UNLOADOFFLINE), BM_GETCHECK,0,0))); + DBWriteContactSettingWord (NULL, SKYPE_PROTONAME, "ConnectionAttempts", (unsigned short)GetDlgItemInt(hwndDlg, IDC_CONNATTEMPTS, NULL, FALSE)); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "UseCustomCommand", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "datapath:", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "removable", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_REMOVEABLE), BM_GETCHECK,0,0))); + DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "secondary", (BYTE)(SendMessage(GetDlgItem(hwndDlg, IDC_SECONDARY), BM_GETCHECK,0,0))); + + GetDlgItemTextA(hwndDlg,IDC_COMMANDLINE,text,sizeof(text)); + strncpy(szRelativePath, text, sizeof(szRelativePath)-1); + CallService (MS_UTILS_PATHTORELATIVE, (WPARAM)text, (LPARAM)szRelativePath); + DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "CommandLine", szRelativePath); + + GetDlgItemTextA(hwndDlg,IDC_DATAPATH,text,sizeof(text)); + strncpy(szRelativePath, text, sizeof(szRelativePath)-1); + CallService (MS_UTILS_PATHTORELATIVE, (WPARAM)text, (LPARAM)szRelativePath); + DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "datapath", szRelativePath); + + // LoginUserName + GetDlgItemTextW(hwndDlg,IDC_USERNAME,wtext,sizeof(wtext)/sizeof(WCHAR)); + DBWriteContactSettingWString(NULL, SKYPE_PROTONAME, "LoginUserName", wtext); + + // LoginPassword + GetDlgItemTextW(hwndDlg,IDC_PASSWORD,wtext,sizeof(wtext)/sizeof(WCHAR)); + DBWriteContactSettingWString(NULL, SKYPE_PROTONAME, "LoginPassword", wtext); + + return TRUE; + } + } + break; + } + case WM_COMMAND: { + switch (LOWORD(wParam)) { + BOOL startSkype; + int i; + case IDC_STARTSKYPE: + startSkype=SendMessage(GetDlgItem(hwndDlg, IDC_STARTSKYPE), BM_GETCHECK,0,0); + + for(i=0; i < sizeof(skypeLaunchControls)/sizeof(skypeLaunchControls[0]); i++) + EnableWindow(GetDlgItem(hwndDlg, skypeLaunchControls[i]), startSkype); + + EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSECMDL), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); + EnableWindow(GetDlgItem(hwndDlg, IDC_COMMANDLINE), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); + + EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSEDP), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); + EnableWindow(GetDlgItem(hwndDlg, IDC_DATAPATH), startSkype && SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); + break; + case IDC_CLEANUP: + pthread_create(( pThreadFunc )CleanupNicknames, NULL); + break; + case IDC_DATAPATHO: + EnableWindow(GetDlgItem(hwndDlg, IDC_DATAPATH), SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); + EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSEDP), SendMessage(GetDlgItem(hwndDlg, IDC_DATAPATHO), BM_GETCHECK,0,0)); + break; + case IDC_CUSTOMCOMMAND: + EnableWindow(GetDlgItem(hwndDlg, IDC_COMMANDLINE), SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); + EnableWindow(GetDlgItem(hwndDlg, IDC_BROWSECMDL), SendMessage(GetDlgItem(hwndDlg, IDC_CUSTOMCOMMAND), BM_GETCHECK,0,0)); + break; + case IDC_BROWSECMDL: + { + OPENFILENAMEA ofn={0}; + BOOL gofnResult; + char szFileName[MAX_PATH]; + char szAbsolutePath[MAX_PATH]; + + ofn.lStructSize=sizeof(ofn); + ofn.hwndOwner=hwndDlg; + ofn.lpstrFilter="Executable files (*.exe)\0*.exe\0All files (*.*)\0*.*\0"; + ofn.nMaxFile=sizeof(szFileName); + ofn.lpstrDefExt="exe"; + ofn.lpstrFile=szFileName; + ofn.Flags=OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ENABLESIZING; + + GetDlgItemTextA(hwndDlg,IDC_COMMANDLINE,szFileName,sizeof(szFileName)); + TranslateMirandaRelativePathToAbsolute(szFileName, szAbsolutePath, FALSE); + strcpy (szFileName, szAbsolutePath); + + if (!(gofnResult = GetOpenFileNameA(&ofn)) && CommDlgExtendedError() == FNERR_INVALIDFILENAME){ + strcpy(szFileName, ".\\Skype.exe"); + TranslateMirandaRelativePathToAbsolute(szFileName, szAbsolutePath, FALSE); + strcpy (szFileName, szAbsolutePath); + gofnResult = GetOpenFileNameA(&ofn); + } + + if(gofnResult) + SetWindowTextA(GetDlgItem(hwndDlg, IDC_COMMANDLINE), szFileName); + + break; + } + case IDC_BROWSEDP: + { + BROWSEINFOA bi={0}; + LPITEMIDLIST pidl; + char szFileName[MAX_PATH]; + char szAbsolutePath[MAX_PATH]; + + GetDlgItemTextA (hwndDlg, IDC_DATAPATH, szFileName, MAX_PATH); + + TranslateMirandaRelativePathToAbsolute(szFileName, szAbsolutePath, FALSE); + bi.hwndOwner = hwndDlg; + bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_SHAREABLE | BIF_NEWDIALOGSTYLE | BIF_NONEWFOLDERBUTTON; + bi.lpfn = BrowseCallbackProc; + bi.lParam = (LPARAM)szAbsolutePath; + + if ( (pidl = SHBrowseForFolderA (&bi)) ) { + if (SHGetPathFromIDListA (pidl, szFileName)) + SetDlgItemTextA (hwndDlg, IDC_DATAPATH, szFileName); + CoTaskMemFree (pidl); + } + break; + } + +#ifdef SKYPE_AUTO_DETECTION + case IDC_AUTODETECTION: + DoAutoDetect(hwndDlg); + break; +#endif + } + if (!initDlg) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// OnDetailsInit - initializes user info dialog pages. + +int OnDetailsInit( WPARAM wParam, LPARAM lParam ) +{ + OPTIONSDIALOGPAGE odp = {0}; + HANDLE hContact = ( HANDLE )lParam; + + odp.cbSize = sizeof(odp); + odp.hIcon = NULL; + odp.hInstance = hInst; + + if ( hContact == NULL ) { + + char szTitle[256]; + + if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 7, 0, 27) && !bIsImoproxy) + { + mir_snprintf( szTitle, sizeof( szTitle ), "%s %s", SKYPE_PROTONAME, Translate( "Avatar" )); + + odp.pfnDlgProc = AvatarDlgProc; + odp.position = 1900000000; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_SETAVATAR); + odp.pszTitle = szTitle; + CallService(MS_USERINFO_ADDPAGE, wParam, (LPARAM)&odp); + } + + mir_snprintf( szTitle, sizeof( szTitle ), "%s %s", SKYPE_PROTONAME, Translate( "Details" )); + + odp.pfnDlgProc = DetailsDlgProc; + odp.position = 1900000000; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_SETDETAILS); + odp.pszTitle = szTitle; + CallService(MS_USERINFO_ADDPAGE, wParam, (LPARAM)&odp); + } + + return 0; +} + +/*AvatarDlgProc +* +* For setting the skype avatar +* +*/ +INT_PTR CALLBACK AvatarDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static RECT r; + + UNREFERENCED_PARAMETER(lParam); + + switch ( msg ) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + + hAvatar = NULL; + if(ServiceExists(MS_AV_GETMYAVATAR)){ + struct avatarCacheEntry *ace = (struct avatarCacheEntry *)CallService(MS_AV_GETMYAVATAR, 0,(LPARAM) SKYPE_PROTONAME); + if (ace!=NULL) { + hAvatar = ( HBITMAP )CallService( MS_UTILS_LOADBITMAP, 0, ( LPARAM )ace->szFilename); + if ( hAvatar != NULL ) + SendDlgItemMessage(hwndDlg, IDC_AVATAR, STM_SETIMAGE, IMAGE_BITMAP, (WPARAM)hAvatar ); + } + } + + + + return TRUE; + + case WM_COMMAND: + if ( HIWORD( wParam ) == BN_CLICKED ) { + switch( LOWORD( wParam )) { + case IDC_SETAVATAR: + { + char szFileName[ MAX_PATH ]; + if ( EnterBitmapFileName( szFileName ) != ERROR_SUCCESS ) + return FALSE; + + hAvatar = ( HBITMAP )CallService( MS_UTILS_LOADBITMAP, 0, ( LPARAM )szFileName); + if ( hAvatar != NULL ){ + SendDlgItemMessage(hwndDlg, IDC_AVATAR, STM_SETIMAGE, IMAGE_BITMAP, (WPARAM)hAvatar ); + CallService(SKYPE_SETAVATAR, 0, ( LPARAM )szFileName); + } + break; + } + case IDC_DELETEAVATAR: + if ( hAvatar != NULL ) { + DeleteObject( hAvatar ); + hAvatar = NULL; + CallService(SKYPE_SETAVATAR, 0, 0); + } + DBDeleteContactSetting( NULL, SKYPE_PROTONAME, "AvatarFile" ); + InvalidateRect( hwndDlg, NULL, TRUE ); + break; + } } + break; + + case WM_DESTROY: + if ( hAvatar != NULL ) + DeleteObject( hAvatar ); + break; + } + + return 0; +} + +/*DetailsDlgProc +* +* For setting the skype infos +* +*/ +INT_PTR CALLBACK DetailsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static int sexM = 0,sexF = 0, sex; + + UNREFERENCED_PARAMETER(lParam); + + switch ( msg ) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + + ZeroMemory (&myProfile, sizeof(myProfile)); + SkypeProfile_Load(&myProfile); + if(SkypeInitialized) + SkypeProfile_LoadFromSkype(&myProfile); + + SendDlgItemMessage(hwndDlg,IDC_SEX,CB_ADDSTRING,0,(LPARAM)_T("")); + sexM = SendDlgItemMessage(hwndDlg,IDC_SEX,CB_ADDSTRING,0,(LPARAM)TranslateT("MALE")); + sexF = SendDlgItemMessage(hwndDlg,IDC_SEX,CB_ADDSTRING,0,(LPARAM)TranslateT("FEMALE")); + + switch(myProfile.Sex) { + case 0x4D: SendDlgItemMessage(hwndDlg,IDC_SEX,CB_SETCURSEL, sexM, 0); break; + case 0x46: SendDlgItemMessage(hwndDlg,IDC_SEX,CB_SETCURSEL, sexF, 0); break; + } + + SetDlgItemText(hwndDlg, IDC_FULLNAME, myProfile.FullName); + SetDlgItemTextA(hwndDlg, IDC_HOMEPAGE, myProfile.HomePage); + SetDlgItemTextA(hwndDlg, IDC_HOMEPHONE, myProfile.HomePhone); + SetDlgItemTextA(hwndDlg, IDC_OFFICEPHONE, myProfile.OfficePhone); + SetDlgItemText(hwndDlg, IDC_CITY, myProfile.City); + SetDlgItemText(hwndDlg, IDC_PROVINCE, myProfile.Province); + DateTime_SetSystemtime (GetDlgItem (hwndDlg, IDC_BIRTHDAY), GDT_VALID, &myProfile.Birthday); + return TRUE; + + case WM_COMMAND: + if ( HIWORD( wParam ) == BN_CLICKED ) { + switch( LOWORD( wParam )) { + case IDC_SAVEDETAILS: + GetDlgItemText(hwndDlg,IDC_FULLNAME,myProfile.FullName,sizeof(myProfile.FullName)/sizeof(TCHAR)); + GetDlgItemTextA(hwndDlg,IDC_HOMEPAGE,myProfile.HomePage,sizeof(myProfile.HomePage)/sizeof(TCHAR)); + GetDlgItemTextA(hwndDlg,IDC_HOMEPHONE,myProfile.HomePhone,sizeof(myProfile.HomePhone)/sizeof(TCHAR)); + GetDlgItemTextA(hwndDlg,IDC_OFFICEPHONE,myProfile.OfficePhone,sizeof(myProfile.OfficePhone)/sizeof(TCHAR)); + GetDlgItemText(hwndDlg,IDC_CITY,myProfile.City,sizeof(myProfile.City)/sizeof(TCHAR)); + GetDlgItemText(hwndDlg,IDC_PROVINCE,myProfile.Province,sizeof(myProfile.Province)/sizeof(TCHAR)); + sex = SendMessage(GetDlgItem(hwndDlg,IDC_SEX),CB_GETCURSEL,0,0); + + myProfile.Sex = 0; + if(sex == sexF) myProfile.Sex = 0x46; else + if(sex == sexM) myProfile.Sex = 0x4D; + DateTime_GetSystemtime (GetDlgItem (hwndDlg, IDC_BIRTHDAY), &myProfile.Birthday); + + SkypeProfile_Save(&myProfile); + if(SkypeInitialized) + SkypeProfile_SaveToSkype(&myProfile); + break; + } + } + break; + + case WM_DESTROY: + if ( hAvatar != NULL ) + DeleteObject( hAvatar ); + break; + } + + return 0; +} + +#ifdef SKYPE_AUTO_DETECTION +/** + * DoAutoDetect + * @param dlg The default option dialog handle + */ +void DoAutoDetect(HWND dlg) +{ + char basePath[MAX_PATH]; + char fileName[MAX_PATH]; + char tmpUser[255]; + ezxml_t f1, acc; + + if (FAILED(SHGetFolderPath(dlg,CSIDL_APPDATA,NULL,0,basePath))) + { + OUTPUT("Error in retrieving appdata path!"); + return; + } + + strcat(basePath,"\\Skype\\"); + sprintf (fileName, "%s\\shared.xml", basePath); + + if (f1 = ezxml_parse_file(fileName)) + { + if (acc = ezxml_get(f1, "Lib", 0, "Account", 0, "Default", -1)) + { + if (GetWindowTextA(GetDlgItem(dlg,IDC_USERNAME),tmpUser,sizeof(tmpUser))) + SetWindowTextA(GetDlgItem(dlg,IDC_USERNAME),acc->txt); + /* Can't find this stuff in current Skype verions?? + sprintf (fileName, "%s\\%s\\config.xml", basePath, acc->txt); + if ((acc = ezxml_get(f1, "UI", 0, "Messages", 0, "OpenWindowInCompactMode", -1)) && *acc->txt!='0') + { + ezxml_set_txt (acc, "0"); + // ezXML doesn't supprot saving yet + } + */ + } + ezxml_free(f1); + } + else + { + OUTPUT("Failed to open skypes configuration files!"); + return; + } +} +#endif diff --git a/plugins/!NotAdopted/Skype/skypeopt.h b/plugins/!NotAdopted/Skype/skypeopt.h new file mode 100644 index 0000000000..23aa7a5212 --- /dev/null +++ b/plugins/!NotAdopted/Skype/skypeopt.h @@ -0,0 +1,49 @@ +/* + * RegisterOptions + * + * This function tells Miranda to add the configuration section of this plugin in + * the Options-dialog. + */ +int RegisterOptions(WPARAM wParam, LPARAM lParam); +/* + * OptionsDlgProc + * + * This callback function is called, when the options dialog in Miranda is shown + * The function contains all necessary stuff to process the options in the dialog + * and store them in the database, when changed, and fill out the settings-dialog + * correctly according to the current settings + */ +INT_PTR CALLBACK OptionsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + +INT_PTR CALLBACK OptionsDefaultDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK OptionsAdvancedDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK OptionsProxyDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK OptPopupDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + +/* +* Procedure to call when the option page is asked +* +*/ +int OnDetailsInit( WPARAM wParam, LPARAM lParam ); + +/* +* Dialog to change avatar in user details. +* +* +*/ +INT_PTR CALLBACK AvatarDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +/* +* Dialog to change infos in user details. +* +* +*/ +INT_PTR CALLBACK DetailsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +/* + * Helper functions + * + */ +void DoAutoDetect(HWND dlg); + +; \ No newline at end of file diff --git a/plugins/!NotAdopted/Skype/skypeprofile.c b/plugins/!NotAdopted/Skype/skypeprofile.c new file mode 100644 index 0000000000..3bf3c0b955 --- /dev/null +++ b/plugins/!NotAdopted/Skype/skypeprofile.c @@ -0,0 +1,145 @@ +#pragma warning (disable: 4706) // assignment within conditional expression + +#include "skypeprofile.h" +#include "skypeapi.h" +#include "utf8.h" + +extern char g_szProtoName[]; + +void SkypeProfile_Save(SkypeProfile *pstProf) +{ + DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "Gender", pstProf->Sex); + DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "HomePhone", pstProf->HomePhone); + DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "OfficePhone", pstProf->OfficePhone); + DBWriteContactSettingString(NULL, SKYPE_PROTONAME, "HomePage", pstProf->HomePage); + DBWriteContactSettingTString(NULL, SKYPE_PROTONAME, "Nick", pstProf->FullName); + DBWriteContactSettingTString(NULL, SKYPE_PROTONAME, "City", pstProf->City); + DBWriteContactSettingTString(NULL, SKYPE_PROTONAME, "Province", pstProf->Province); + DBWriteContactSettingWord(NULL, SKYPE_PROTONAME, "BirthYear", (WORD)pstProf->Birthday.wYear); + DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "BirthMonth", (BYTE)pstProf->Birthday.wMonth); + DBWriteContactSettingByte(NULL, SKYPE_PROTONAME, "BirthDay", (BYTE)pstProf->Birthday.wDay); +} + +void SkypeProfile_Load(SkypeProfile *pstProf) +{ + DBVARIANT dbv; + + pstProf->Sex = (BYTE)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "Gender", 0); + pstProf->Birthday.wYear = (WORD)DBGetContactSettingWord(NULL, SKYPE_PROTONAME, "BirthYear", 1900); + pstProf->Birthday.wMonth = (WORD)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "BirthMonth", 01); + pstProf->Birthday.wDay = (WORD)DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "BirthDay", 01); + if(!DBGetContactSettingTString(NULL,SKYPE_PROTONAME,"Nick",&dbv)) + { + _tcsncpy (pstProf->FullName, dbv.ptszVal, sizeof(pstProf->FullName)/sizeof(TCHAR)); + DBFreeVariant(&dbv); + } + if(!DBGetContactSettingString(NULL,SKYPE_PROTONAME,"HomePage",&dbv)) + { + strncpy (pstProf->HomePage, dbv.pszVal, sizeof(pstProf->HomePage)); + DBFreeVariant(&dbv); + } + if(!DBGetContactSettingTString(NULL,SKYPE_PROTONAME,"Province",&dbv)) + { + _tcsncpy (pstProf->Province, dbv.ptszVal, sizeof(pstProf->Province)/sizeof(TCHAR)); + DBFreeVariant(&dbv); + } + if(!DBGetContactSettingTString(NULL,SKYPE_PROTONAME,"City",&dbv)) + { + _tcsncpy (pstProf->City, dbv.ptszVal, sizeof(pstProf->City)/sizeof(TCHAR)); + DBFreeVariant(&dbv); + } + if(!DBGetContactSettingString(NULL,SKYPE_PROTONAME,"OfficePhone",&dbv)) + { + strncpy (pstProf->OfficePhone, dbv.pszVal, sizeof(pstProf->OfficePhone)); + DBFreeVariant(&dbv); + } + if(!DBGetContactSettingString(NULL,SKYPE_PROTONAME,"HomePhone",&dbv)) + { + strncpy (pstProf->HomePhone, dbv.pszVal, sizeof(pstProf->HomePhone)); + DBFreeVariant(&dbv); + } +} + +static void LoadSaveSkype(SkypeProfile *pstProf, BOOL bSet) +{ +#pragma warning (push) +#pragma warning (disable: 4204) // nonstandard extension used : non-constant aggregate initializer +#define ENTRY(x,y) {x, pstProf->y, sizeof(pstProf->y)/sizeof(pstProf->y[0]), sizeof(pstProf->y[0])} + const struct { + char *pszSetting; + LPVOID lpDest; + int iSize; + char cType; + } astSettings[] = { + ENTRY("FULLNAME", FullName), + ENTRY("PHONE_HOME", HomePhone), + ENTRY("PHONE_OFFICE", OfficePhone), + ENTRY("HOMEPAGE", HomePage), + ENTRY("CITY", City), + ENTRY("PROVINCE", Province) + }; +#pragma warning (pop) +#undef ENTRY + char *ptr; + int i; + + if (bSet) { + char *pBuf, szBirthday[16]; + for (i=0; iSex) + { + case 0x4D: SkypeSetProfile ("SEX", "MALE"); break; + case 0x46: SkypeSetProfile ("SEX", "FEMALE"); break; + } + sprintf (szBirthday, "%04d%02d%02d", pstProf->Birthday.wYear, pstProf->Birthday.wMonth, pstProf->Birthday.wDay); + SkypeSetProfile ("BIRTHDAY", szBirthday); + } else { + for (i=0; iSex=0x4D; else + if (!_stricmp(ptr, "FEMALE")) pstProf->Sex=0x46; + free (ptr); + } + if (ptr=SkypeGetProfile("BIRTHDAY")) + { + if (*ptr != '0') + sscanf(ptr, "%04hd%02hd%02hd", &pstProf->Birthday.wYear, &pstProf->Birthday.wMonth, + &pstProf->Birthday.wDay); + free(ptr); + } + } +} + +void SkypeProfile_LoadFromSkype(SkypeProfile *pstProf) +{ + LoadSaveSkype (pstProf, FALSE); +} + +void SkypeProfile_SaveToSkype(SkypeProfile *pstProf) +{ + LoadSaveSkype (pstProf, TRUE); +} \ No newline at end of file diff --git a/plugins/!NotAdopted/Skype/skypeprofile.h b/plugins/!NotAdopted/Skype/skypeprofile.h new file mode 100644 index 0000000000..60531128d1 --- /dev/null +++ b/plugins/!NotAdopted/Skype/skypeprofile.h @@ -0,0 +1,33 @@ +// System includes +#include +#include +#include +#include +#include +#include "resource.h" +#include "skype.h" + +#pragma warning (push) +#pragma warning (disable: 4100) // unreferenced formal parameter +// Miranda database access +#include "../../include/newpluginapi.h" +#include "../../include/m_database.h" +#pragma warning (pop) + +typedef struct +{ + TCHAR FullName[256]; + char HomePhone[256]; + char OfficePhone[256]; + char HomePage[256]; + TCHAR City[256]; + TCHAR Province[256]; + BYTE Sex; + SYSTEMTIME Birthday; +} SkypeProfile; + +void SkypeProfile_Load(SkypeProfile *pstProf); +void SkypeProfile_Save(SkypeProfile *pstProf); +void SkypeProfile_Free(SkypeProfile *pstProf); +void SkypeProfile_LoadFromSkype(SkypeProfile *pstProf); +void SkypeProfile_SaveToSkype(SkypeProfile *pstProf); diff --git a/plugins/!NotAdopted/Skype/skypeproxy.h b/plugins/!NotAdopted/Skype/skypeproxy.h new file mode 100644 index 0000000000..8e1490803e --- /dev/null +++ b/plugins/!NotAdopted/Skype/skypeproxy.h @@ -0,0 +1,7 @@ +/* Commands for command mode of Skype proxy */ + +#define AUTHENTICATE 0x01 +#define CAPABILITIES 0x02 + +/* Capabilities flags of Skypeproxy */ +#define USE_AUTHENTICATION 0x01 \ No newline at end of file diff --git a/plugins/!NotAdopted/Skype/skypeproxy/skypeproxy.c b/plugins/!NotAdopted/Skype/skypeproxy/skypeproxy.c new file mode 100644 index 0000000000..fff9c1b916 --- /dev/null +++ b/plugins/!NotAdopted/Skype/skypeproxy/skypeproxy.c @@ -0,0 +1,651 @@ +/* + +Purpose +======= +This program opens a connection on a local TCP/IP port and sends/ +receives Skype-API calls on it so that you can remote-control +Skype over a network. +Note, that there are currently NO SECURITY mechanisms, so don't +use this over an untrusted network! + +Author +====== +This program was written by leecher in 2005 (mailto:leecher@dose.0wnz.at) +Please give feedback at http://forum.skype.com/viewtopic.php?t=16187 + +Protocol +======== +Basic protocol structure +------------------------ +Sender and receiver have the same protocol: + + [(UINT)Length of message][(char[])Message] + +The Length is so that you can malloc() enough space for the data buffer +to receive the next message. + +A special case is, if the [Length of message] is 0. In this case the +client tells the server that he wants to switch to command mode. + +Command mode +------------ +The server expects + + [(char)Command] + +next. Currently the following commands are supported: + + CAPABILITIES - returns the Server's capabilities + AUTHENTICATE - Starts the authentification process + +CAPABILITIES +------------ +The server returns + + [(char)Capabilities] + +where this currently can be the following: + + USE_AUTHENTICATION - The server supports and requires authentication + +AUTHENTICATE +------------ +The server returns + + [(char)0x01] + +if authentication is supported AND needed (skypeproxy started with -k switch) or + + [(char)0x00] + +if this is not the case. +If 0x01 was returned the server next expects a normal message +(see "Basic protocol structure) containing the password. +If the authentication was successful, the server replies with + + [(char)0x01] + +otherwise with + + [(char)0x00] + +PLEASE NOTE THAT THE AUTHENTICATION CURRENTLY IS PLAIN TEXT. SO DON'T +USE THIS PROGRAM OVER AN UNTRUSTED NETWORK, OTHERWISE THERE MAY BE THE +POSSIBILITY THAT SOMEONE SNIFFS YOUR PASSWORD! + +Code example +------------ + +SOCKET MySocket; + +int SendPacket(char *szSkypeMessage) { + unsigned int length=strlen(szSkypeMsg); + + if (send(MySocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR || + send(MySocket, szSkypeMsg, length, 0)==SOCKET_ERROR) + return -1; + return 0; +} + +// don't forget to free() the return value on my Heap!! +char *ReceivePacket(void) { + unsigned int lenght, received; + char *buf; + + if ((received=recv(MySocket, (char *)&length, sizeof(length), 0))==SOCKET_ERROR || + received==0) + return NULL; + if (!(buf=calloc(1, length+1))) return NULL; + if (recv(MySocket, buf, length, 0)==SOCKET_ERROR) { + free(buf); + return NULL; + } + return buf; +} + + +License +======= +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +History +======== +V1.0alpha - First preview release +V1.0 - Implemented killing & restarting Skype process when it dies + - BUGFIX: SendMessage() is a blocking call, if Skype hangs our app hangs too -> Fixed + - Added command line parsing. + - Renamed from Skype2Socket to skypeproxy + - Added authentication feature. +*/ + +#include +#include +#include +#include +#include "skypeproxy.h" + +UINT ControlAPIAttach, ControlAPIDiscover; +HWND hSkypeWnd=NULL, hWnd; +HANDLE SkypeReady, ServerThreadBye; +LONG AttachStatus=-1; +int exitcode=EXIT_SUCCESS; +char skype_path[MAX_PATH], *password=NULL; +BYTE WatchDog=1; +BOOL WatchDogRunning=FALSE, Authenticated=FALSE; +SOCKET ListenSocket, AcceptSocket; + + +void bail_out(int i) { + OUTPUT("Got termination signal, bailing out."); + if (i==1) exitcode=EXIT_FAILURE; + PostMessage(hWnd, WM_QUIT, 0, 0); +} + +BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ) { + DWORD dwID ; + + GetWindowThreadProcessId(hwnd, &dwID) ; + if(dwID == (DWORD)lParam) + PostMessage(hwnd, WM_CLOSE, 0, 0) ; // May you be so kind to quit, please? + + return TRUE ; +} + +/* ConnectToSkypeAPI + * + * Purpose: Establish a connection to the Skype API + * Params : ForceRestart - Kill Skype if it's running before restarting + * Returns: 0 - Connecting succeeded + * -1 - Something went wrong + */ +void ConnectToSkypeAPI(void *ForceRestart) { + BOOL SkypeLaunched=FALSE; + int counter=0, i, j; + char *args[5]; + char *SkypeOptions[]={"/notray", "/nosplash", "/minimized"}; + char *szFuncName="ConnectToSkypeAPI"; + + ResetEvent(SkypeReady); + AttachStatus=-1; + if ((BOOL)ForceRestart) { + HANDLE hProc; + DWORD dwPID=0; + + if (!hSkypeWnd) { + OUTPUT("I can't kill Skype, as I don't even have its window handle!"); + return; + } + GetWindowThreadProcessId(hSkypeWnd, &dwPID); + LOG(("%s: Shutting down Skype as it was not behaving the way it should...", szFuncName)); + if (hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, dwPID)) { + + // Try to shutdown Skype the nice way by asking it to close + EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM) dwPID); + + if(WaitForSingleObject(hProc, 10000)!=WAIT_OBJECT_0) { + // Try it the hard way by killing it + LOG(("%s: I tried it the nice way, but you were not listening! Now DIIIIEEE!", szFuncName)); + if (!TerminateProcess(hProc,0)) { + OUTPUT("Argh, process refused to die, it's too mighty for me, I've given up"); + CloseHandle(hProc); + return; + } + LOG(("%s: Process killed! >:)", szFuncName)); + } + CloseHandle(hProc); + } + } + do { + /* To initiate communication, Client should broadcast windows message + ('SkypeControlAPIDiscover') to all windows in the system, specifying its own + window handle in wParam parameter. + */ + LOG(("%s: Sending discover message..", szFuncName)); + SendMessageTimeout(HWND_BROADCAST, ControlAPIDiscover, (WPARAM)hWnd, 0, SMTO_ABORTIFHUNG, 3000, NULL); + LOG(("%s: Discover message sent, waiting for Skype to become ready..", szFuncName)); + + /* In response, Skype responds with + message 'SkypeControlAPIAttach' to the handle specified, and indicates + connection status + SkypeReady is set if there is an answer by Skype other than API_AVAILABLE. + If there is no answer after 3 seconds, launch Skype as it's propably + not running. + */ + if (WaitForSingleObject(SkypeReady, 3000)==WAIT_TIMEOUT && + AttachStatus!=SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION) + { + if (hWnd==NULL) { + LOG(("%s: hWnd of SkypeDispatchWindow not yet set..", szFuncName)); + continue; + } + if (!SkypeLaunched && skype_path) { + LOG(("%s: Starting Skype, as it's not running", szFuncName)); + args[0]=skype_path; + j=1; + for (i=0; i<3; i++) { + args[j]=SkypeOptions[i]; + LOG(("%s: Using Skype parameter: ", szFuncName, args[j])); + j++; + } + args[j]=NULL; + _spawnv(_P_NOWAIT, skype_path, args); + ResetEvent(SkypeReady); + SkypeLaunched=TRUE; + LOG(("%s: Skype process started.", szFuncName)); + // Skype launching iniciated, keep sending Discover messages until it responds. + continue; + } else { + LOG(("%s: Check if Skype was launchable..", szFuncName)); + if (!skype_path) { + OUTPUT("There was no correct path for Skype application"); + bail_out(1); + return; + } + LOG("%s: Trying to attach: #%d", szFuncName, counter)); + counter++; + if (counter==5) { + OUTPUT("ERROR: Skype not running / too old / working!"); + bail_out(1); + return; + } + } + } + LOG(("%s: Attachstatus %d", szFuncName, AttachStatus)); + } while (AttachStatus==SKYPECONTROLAPI_ATTACH_API_AVAILABLE || AttachStatus==-1); + + while (AttachStatus==SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION) Sleep(1000); + LOG(("%s: Attachstatus %d", szFuncName, AttachStatus)); + if (AttachStatus!=SKYPECONTROLAPI_ATTACH_SUCCESS) { + switch(AttachStatus) { + case SKYPECONTROLAPI_ATTACH_REFUSED: + OUTPUT("Skype refused the connection :("); + break; + case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE: + OUTPUT("The Skype API is not available"); + break; + default: + LOG(("%s: ERROR: AttachStatus: %d", szFuncName, AttachStatus)); + OUTPUT("Wheee, Skype won't let me use the API. :("); + } + bail_out(1); + return; + } + OUTPUT("Attached to Skype successfully."); + if (!WatchDogRunning) + if (_beginthread(WatchDogTimer, 0, NULL)==-1) { + OUTPUT("Cannot start Watchdog."); + bail_out(1); + } + return; +} + +void SkypeSend(char *szMsg) { + COPYDATASTRUCT CopyData; + int count=0; + + if (!hSkypeWnd) { + LOG(("SkypeSend: DAMN! No Skype window handle! :(")); + return; + } + if (strcmp(szMsg, "PING")) {LOG(("> %s", szMsg));} + CopyData.dwData=0; + CopyData.lpData=szMsg; + CopyData.cbData=strlen(szMsg)+1; + while (!SendMessageTimeout(hSkypeWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&CopyData, SMTO_ABORTIFHUNG, 3000, NULL)) { + count++; + LOG(("SkypeSend: failed, try #%d", count)); + if (count==5) { + OUTPUT("Sending message to Skype failed too often."); + OUTPUT("Skype may have died unexpectedly, I will try to restart it."); + ConnectToSkypeAPI((void *)TRUE); + OUTPUT("Restart complete. Trying to deliver message one more time."); + if (!SendMessageTimeout(hSkypeWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&CopyData, SMTO_ABORTIFHUNG, 3000, NULL)) { + OUTPUT("It still failed. Skype seems to be completely f*cked up. I've given up. Bye.."); + bail_out(1); + break; + } else { + OUTPUT("Now it worked! :)"); + break; + } + } + Sleep(1000); + } +} + +void ServerThread(char *dummy) { + unsigned int length, received; + char *buf, command, reply; + + LOG(("ServerThread started")); + AcceptSocket=INVALID_SOCKET; + while( AcceptSocket == INVALID_SOCKET) { + if ((AcceptSocket = accept( ListenSocket, NULL, NULL ))==INVALID_SOCKET) { + LOG(("ServerThread: Byebye...")); + SetEvent(ServerThreadBye); + bail_out(1); + return; + } + OUTPUT("Connection by client"); + while(1) { + if ((received=recv(AcceptSocket, (char *)&length, sizeof(length), 0))==SOCKET_ERROR || + received==0) + { + OUTPUT("Connection was closed by client. See ya soon! :)"); + break; + } + // Command mode + if (length==0) { + reply=0; + if (recv(AcceptSocket, (char *)&command, 1, 0)==SOCKET_ERROR) { + OUTPUT("Connection to client was lost."); + break; + } +#ifdef USE_AUTHENTICATION + if (command==AUTHENTICATE) + if (password) reply=0x01; // Ok, go ahead + else command=0; +#endif + if (command==CAPABILITIES) + reply=password?USE_AUTHENTICATION:0; + + if (send(AcceptSocket, (char *)&reply, 1, 0)==SOCKET_ERROR) { + OUTPUT("Connection to client was lost."); + break; + } + continue; + } + // Normal Skype API-call + if (!(buf=calloc(1, length+1))) { + OUTPUT("Out of memory error while allocating buffer space."); + break; + } + if (recv(AcceptSocket, buf, length, 0)==SOCKET_ERROR) { + OUTPUT("Connection to client was lost."); + free(buf); + break; + } + switch (command) { +#ifdef USE_AUTHENTICATION + case 0x01: // Compare hash + if (password && !strcmp(password, buf)) Authenticated=TRUE; + else Authenticated=FALSE; + if (Authenticated) { + OUTPUT("User authenticated succesfully."); + reply=1; + } else { + OUTPUT("User authentication failed!! (Intruder?)"); + reply=0; + } + if (send(AcceptSocket, (char *)&reply, 1, 0)==SOCKET_ERROR) { + OUTPUT("Connection to client was lost."); + break; + } + command=0; + break; +#endif + default: +#ifdef USE_AUTHENTICATION + if (password && !Authenticated) break; +#endif + SkypeSend(buf); + } + command=0; + free(buf); + } + AcceptSocket=INVALID_SOCKET; +#ifdef USE_AUTHENTICATION + Authenticated=FALSE; +#endif + } +} + + +void WatchDogTimer(char *dummy) { + LOG(("WatchDogTimer started")); + WatchDogRunning=TRUE; + while (1) { + Sleep(PING_INTERVAL); + if (!WatchDog) { + OUTPUT("Ouch.. It seems that Skype has died unexpectedly. Trying to restart."); + ConnectToSkypeAPI((void *)TRUE); + } + WatchDog=0; + SkypeSend("PING"); + } +} + +LONG APIENTRY WndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam) +{ + PCOPYDATASTRUCT CopyData; + char *szSkypeMsg=NULL; + + switch (message) + { + case WM_COPYDATA: +// LOG("WM_COPYDATA", "start"); + if(hSkypeWnd==(HWND)wParam) { + CopyData=(PCOPYDATASTRUCT)lParam; + szSkypeMsg=strdup(CopyData->lpData); + ReplyMessage(1); + if (!strcmp(szSkypeMsg, "PONG")) { + WatchDog=1; + break; + } // Hide PING-PONG + LOG(("< %s", szSkypeMsg)); + if (!strcmp(szSkypeMsg, "USERSTATUS LOGGEDOUT")) { + OUTPUT("Skype shut down gracefully. I'll leave too, bye.. :)"); + bail_out(1); + } +#ifdef USE_AUTHENTICATION + if (password && !Authenticated) break; +#endif + if (AcceptSocket!=INVALID_SOCKET) { + unsigned int length=strlen(szSkypeMsg); + + if (send(AcceptSocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR || + send(AcceptSocket, szSkypeMsg, length, 0)==SOCKET_ERROR) + OUTPUT("Cannot send to client :("); + } + } + break; + + case WM_DESTROY: + PostQuitMessage(0); + break; + + default: + if(message==ControlAPIAttach) { + // Skype responds with Attach to the discover-message + AttachStatus=lParam; + if (AttachStatus==SKYPECONTROLAPI_ATTACH_SUCCESS) + hSkypeWnd=(HWND)wParam; // Skype gave us the communication window handle + if (AttachStatus!=SKYPECONTROLAPI_ATTACH_API_AVAILABLE) + SetEvent(SkypeReady); + break; + } + return (DefWindowProc(hWnd, message, wParam, lParam)); + } +// LOG("WM_COPYDATA", "exit"); + if (szSkypeMsg) free(szSkypeMsg); + return 1; +} + + +void TellError(DWORD err) { + LPVOID lpMsgBuf; + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); + MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION ); + LocalFree( lpMsgBuf ); + return; +} + +int main(int argc, char *argv[]) { + DWORD Buffsize; + HKEY MyKey; + BOOL SkypeInstalled=TRUE; + MSG Message; + WNDCLASS WndClass; + SOCKADDR_IN service; + WSADATA wsaData; + int ExitCode=STILL_ACTIVE; + unsigned short BindPort=1401; + char BindIP[16]="0.0.0.0"; + + printf("Skypeproxy V1.0, by leecher 2005 \n\n"); + + if (argc>1) { + int i; + + if (!stricmp(argv[1], "-h") || !stricmp(argv[1], "--help") || !stricmp(argv[1], "/?")) { + printf("Usage: %s [-i BindIP] [-p BindPort]", argv[0]); +#ifdef USE_AUTHENTICATION + printf(" [-k Password]"); +#endif + printf("\n\n"); + return EXIT_SUCCESS; + } + for (i=0;ii+1) + strncpy(BindIP, argv[i+1], sizeof(BindIP)); + if (!stricmp(argv[i], "-p") && argc>i+1) + if (!(BindPort=atoi(argv[i+1]))) { + OUTPUT("ERROR: Cannot convert port to int. bye.."); + return EXIT_FAILURE; + } +#ifdef USE_AUTHENTICATION + if (!stricmp(argv[i], "-k") && argc>i+1) + password=strdup(argv[i+1]); +#endif + } + } + + if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Skype\\Phone", 0, KEY_READ, &MyKey)!=ERROR_SUCCESS || + RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Skype\\Phone", 0, KEY_READ, &MyKey)!=ERROR_SUCCESS) + SkypeInstalled=FALSE; + Buffsize=sizeof(skype_path); + if (SkypeInstalled==FALSE || + RegQueryValueEx(MyKey, "SkypePath", NULL, NULL, skype_path, &Buffsize)!=ERROR_SUCCESS) { + OUTPUT("Skype was not found on this machine :("); + RegCloseKey(MyKey); + skype_path[0]=0; + return EXIT_FAILURE; + } + RegCloseKey(MyKey); + + if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { + OUTPUT("Error at loading windows sockets."); + return EXIT_FAILURE; + } + + if ((ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { + printf("* Error at creating socket(): Error %d", WSAGetLastError()); + return EXIT_FAILURE; + } + + service.sin_family = AF_INET; + service.sin_addr.s_addr = inet_addr(BindIP); + service.sin_port = htons(BindPort); + + printf("* Binding to interface %s, Port %d..", BindIP, BindPort); + if (bind( ListenSocket, (SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR || + listen( ListenSocket, 1 ) == SOCKET_ERROR) + { + OUTPUT("Failed."); + closesocket(ListenSocket); + return EXIT_FAILURE; + } + printf("OK\n"); + + + if (!(ControlAPIAttach=RegisterWindowMessage("SkypeControlAPIAttach")) || + !(ControlAPIDiscover=RegisterWindowMessage("SkypeControlAPIDiscover"))) { + OUTPUT("Cannot register Windows message."); + closesocket(ListenSocket); + return EXIT_FAILURE; + } + + // Create window class + hSkypeWnd=NULL; + WndClass.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS; + WndClass.lpfnWndProc = (WNDPROC)WndProc; + WndClass.cbClsExtra = 0; + WndClass.cbWndExtra = 0; + WndClass.hInstance = NULL; + WndClass.hIcon = NULL; + WndClass.hCursor = NULL; + WndClass.hbrBackground = NULL; + WndClass.lpszMenuName = NULL; + WndClass.lpszClassName = "SkypeApiDispatchWindow"; + RegisterClass(&WndClass); + // Do not check the retval of RegisterClass, because on non-unicode + // win98 it will fail, as it is a stub that returns false() there + + // Create main window + hWnd=CreateWindowEx( WS_EX_APPWINDOW|WS_EX_WINDOWEDGE, + "SkypeApiDispatchWindow", "", WS_BORDER|WS_SYSMENU|WS_MINIMIZEBOX, + CW_USEDEFAULT, CW_USEDEFAULT, 128, 128, NULL, 0, (HINSTANCE)WndClass.hInstance, 0); + + if (!hWnd) { + OUTPUT("Cannot create window."); + TellError(GetLastError()); + closesocket(ListenSocket); + CloseHandle(WndClass.hInstance); + return EXIT_FAILURE; + } + ShowWindow(hWnd, 0); + UpdateWindow(hWnd); + + if (!(SkypeReady=CreateEvent(NULL, TRUE, FALSE, NULL)) || + !(ServerThreadBye=CreateEvent(NULL, TRUE, FALSE, NULL))) { + OUTPUT("Unable to create Mutex!"); + closesocket(ListenSocket); + CloseHandle(WndClass.hInstance); + return EXIT_FAILURE; + } + + if (_beginthread(ConnectToSkypeAPI, 0, (void *)FALSE)==-1 || + _beginthread(ServerThread, 0, NULL)==-1) { + OUTPUT("Cannot create thread. Bye.."); + closesocket(ListenSocket); + CloseHandle(WndClass.hInstance); + CloseHandle(SkypeReady); + return EXIT_FAILURE; + } + + signal(SIGINT, &bail_out); + LOG(("Startup: Messagepump started.\nPress CTRL+C to terminate\n")); + + while (GetMessage(&Message, hWnd, 0, 0)) + { + TranslateMessage(&Message); + DispatchMessage(&Message); + } + + LOG(("Shutdown: Messagepump stopped")); + + if (password) free(password); + if (AcceptSocket != INVALID_SOCKET) closesocket(AcceptSocket); + closesocket(ListenSocket); + LOG(("Shutdown: Waiting for serverthread to quit...")); + if (WaitForSingleObject(ServerThreadBye, 3000)==WAIT_TIMEOUT) + {OUTPUT("Serverthread didn't terminate correctly, shutting down anyway...");} + else + {LOG(("ServerThread terminated"));} + CloseHandle(WndClass.hInstance); + CloseHandle(SkypeReady); + return exitcode; +} \ No newline at end of file diff --git a/plugins/!NotAdopted/Skype/skypeproxy/skypeproxy.h b/plugins/!NotAdopted/Skype/skypeproxy/skypeproxy.h new file mode 100644 index 0000000000..8ce122990b --- /dev/null +++ b/plugins/!NotAdopted/Skype/skypeproxy/skypeproxy.h @@ -0,0 +1,36 @@ +/*** Skype API ***/ +//Messages +#define SKYPECONTROLAPI_ATTACH_SUCCESS 0 +#define SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION 1 +#define SKYPECONTROLAPI_ATTACH_REFUSED 2 +#define SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE 3 +#define SKYPECONTROLAPI_ATTACH_API_AVAILABLE 0x8001 + +// Errors +#define MISC_ERROR 1 +#define USER_NOT_FOUND 2 +#define USER_NOT_ONLINE 3 +#define USER_BLOCKED 4 +#define TYPE_UNSUPPORTED 5 +#define SENDER_NOT_FRIEND 6 +#define SENDER_NOT_AUTHORIZED 7 + + +/*** Debugging macros ***/ +#define OUTPUT(a) printf("* %s\n", a); +#define LOG(a, b) printf("- %s: %s\n", a, b); +#define LOGL(a, b) printf("- %s: %d\n", a, b); + +/*** Program settings ***/ +#define PING_INTERVAL 10000 // Ping every 10000 msec to see if Skype is still available +#define USE_AUTHENTICATION 0x01 // Program supports authentication -> Comment to disable! + +/*** Commands ***/ +#define AUTHENTICATE 0x01 +#define CAPABILITIES 0x02 + +/*** Sockets ***/ +#pragma comment(lib, "ws2_32") + +/*** Prototypes ***/ +void WatchDogTimer(char *); \ No newline at end of file diff --git a/plugins/!NotAdopted/Skype/skypesvc.c b/plugins/!NotAdopted/Skype/skypesvc.c new file mode 100644 index 0000000000..c6d02e6d3a --- /dev/null +++ b/plugins/!NotAdopted/Skype/skypesvc.c @@ -0,0 +1,188 @@ +#define __SKYPESVC_C__ +#include "skype.h" +#include "skypesvc.h" +#include "skypeapi.h" +#include "skypeopt.h" +#include "contacts.h" +#include "m_toptoolbar.h" + +// Exports +SKYPE_SVCNAMES g_svcNames; + +//From skype.c +extern char protocol, g_szProtoName[]; +extern HINSTANCE hInst; +extern DWORD mirandaVersion; +static HANDLE m_hPrebuildCMenu=NULL, m_hStatusHookContact=NULL, m_hContactDeleted=NULL, + m_hHookModulesLoaded=NULL, m_hHookOkToExit=NULL, m_hOptHook=NULL, m_hHookMirandaExit=NULL, + m_hTTBModuleLoadedHook = NULL, m_hHookOnUserInfoInit = NULL; + +void CreateProtoService(const char* szService, MIRANDASERVICE svc) +{ + char str[MAXMODULELABELLENGTH]; + _snprintf(str, sizeof(str), "%s%s", SKYPE_PROTONAME, szService); + CreateServiceFunction(str, svc); +} + +#define CreateServiceName(srvce) _snprintf (g_svcNames.##srvce, sizeof(g_svcNames.##srvce), "%s/"#srvce, SKYPE_PROTONAME); + +void CreateServices(void) +{ + CreateServiceName(ChatNew); + CreateServiceName(SetAvatar); + CreateServiceName(SendFile); + CreateServiceName(HoldCall); + CreateServiceName(AnswerCall); + CreateServiceName(ImportHistory); + CreateServiceName(AddUser); + CreateServiceName(SkypeOutCallUser); + CreateServiceName(CallHangupUser); + CreateServiceName(CallUser); + + CreateServiceFunction(SKYPE_CALL, SkypeCall); + CreateServiceFunction(SKYPE_CALLHANGUP, SkypeCallHangup); + CreateServiceFunction(SKYPEOUT_CALL, SkypeOutCall); + CreateServiceFunction(SKYPE_HOLDCALL, SkypeHoldCall); + CreateServiceFunction(SKYPE_ADDUSER, SkypeAdduserDlg); + CreateServiceFunction(SKYPE_IMPORTHISTORY, ImportHistory); + CreateServiceFunction(SKYPE_ANSWERCALL, SkypeAnswerCall); + CreateServiceFunction(SKYPE_SENDFILE, SkypeSendFile); + CreateServiceFunction(SKYPE_SETAVATAR, SkypeSetAvatar); + + CreateProtoService(PS_GETCAPS, SkypeGetCaps); + CreateProtoService(PS_GETNAME, SkypeGetName); + CreateProtoService(PS_LOADICON, SkypeLoadIcon); + CreateProtoService(PS_SETSTATUS, SkypeSetStatus); + CreateProtoService(PS_GETSTATUS, SkypeGetStatus); + CreateProtoService(PS_ADDTOLIST, SkypeAddToList); + CreateProtoService(PS_ADDTOLISTBYEVENT, SkypeAddToListByEvent); + CreateProtoService(PS_BASICSEARCH, SkypeBasicSearch); + + CreateProtoService(PSS_GETINFO, SkypeGetInfo); + CreateProtoService(PSS_MESSAGE, SkypeSendMessage); + CreateProtoService(PSR_MESSAGE, SkypeRecvMessage); + CreateProtoService(PSS_USERISTYPING, SkypeUserIsTyping); + CreateProtoService(PSS_AUTHREQUEST, SkypeSendAuthRequest); + CreateProtoService(PSR_AUTH, SkypeRecvAuth); + CreateProtoService(PS_AUTHALLOW, SkypeAuthAllow); + CreateProtoService(PS_AUTHDENY, SkypeAuthDeny); + + CreateProtoService(PS_GETAVATARINFO, SkypeGetAvatarInfo); + CreateProtoService(PS_GETAVATARCAPS, SkypeGetAvatarCaps); + CreateProtoService(PS_GETMYAVATAR, SkypeGetAvatar); + CreateProtoService(PS_SETMYAVATAR, SkypeSetAvatar); + + CreateProtoService(PS_SETAWAYMSG, SkypeSetAwayMessage); + CreateProtoService(PS_SETAWAYMSGW, SkypeSetAwayMessageW); + CreateProtoService(PSS_GETAWAYMSG, SkypeGetAwayMessage); + CreateProtoService(PS_SETMYNICKNAME, SkypeSetNick); + + CreateProtoService(PSS_SKYPEAPIMSG, SkypeReceivedAPIMessage); + CreateProtoService(SKYPE_REGPROXY, SkypeRegisterProxy); +} + +void HookEvents(void) +{ + m_hPrebuildCMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PrebuildContactMenu); + + //HookEvent(ME_CLIST_DOUBLECLICKED, ClistDblClick); + m_hOptHook = HookEvent(ME_OPT_INITIALISE, RegisterOptions); + m_hStatusHookContact = HookEvent(ME_DB_CONTACT_ADDED,HookContactAdded); + m_hContactDeleted = HookEvent( ME_DB_CONTACT_DELETED, HookContactDeleted ); + m_hHookModulesLoaded = HookEvent( ME_SYSTEM_MODULESLOADED, OnModulesLoaded); + m_hHookMirandaExit = HookEvent(ME_SYSTEM_OKTOEXIT, MirandaExit); + m_hHookOkToExit = HookEvent(ME_SYSTEM_PRESHUTDOWN, OkToExit); +} + +void HookEventsLoaded(void) +{ + // We cannot check for the TTB-service before this event gets fired... :-/ + m_hTTBModuleLoadedHook = HookEvent(ME_TTB_MODULELOADED, CreateTopToolbarButton); + m_hHookOnUserInfoInit = HookEvent( ME_USERINFO_INITIALISE, OnDetailsInit ); +} + +void UnhookEvents(void) +{ + UnhookEvent(m_hOptHook); + UnhookEvent(m_hTTBModuleLoadedHook); + UnhookEvent(m_hHookOnUserInfoInit); + UnhookEvent(m_hStatusHookContact); + UnhookEvent(m_hContactDeleted); + UnhookEvent(m_hHookModulesLoaded); + UnhookEvent(m_hPrebuildCMenu); + UnhookEvent(m_hHookOkToExit); + UnhookEvent(m_hHookMirandaExit); + //UnhookEvent(ClistDblClick); +} + +INT_PTR SkypeGetCaps(WPARAM wParam, LPARAM lParam) { + int ret = 0; + + UNREFERENCED_PARAMETER(lParam); + + switch (wParam) { + case PFLAGNUM_1: + ret = PF1_BASICSEARCH | PF1_IM | PF1_MODEMSG; // | PF1_AUTHREQ; + if (protocol>=5) ret |= PF1_ADDSEARCHRES; + break; + + case PFLAGNUM_2: + ret = PF2_ONLINE | PF2_SHORTAWAY | PF2_INVISIBLE | PF2_HEAVYDND; +#ifdef MAPDND + ret |= PF2_LIGHTDND | PF2_HEAVYDND; +#endif + if (!DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "NoSkype3Stats", 0)) + ret |= PF2_LONGAWAY | PF2_FREECHAT; + break; + + case PFLAGNUM_3: + ret = PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE | PF2_IDLE; + break; + + case PFLAGNUM_4: + ret = PF4_FORCEAUTH | PF4_FORCEADDED | PF4_AVATARS | PF4_SUPPORTTYPING /* Not really, but libgaim compat. */; + if (mirandaVersion >= 0x070000) ret |= PF4_IMSENDUTF; + break; + case PFLAG_UNIQUEIDTEXT: + ret = (INT_PTR) "NAME"; + break; + case PFLAG_UNIQUEIDSETTING: + ret = (INT_PTR) SKYPE_NAME; + break; + } + return ret; + +} + +INT_PTR SkypeGetName(WPARAM wParam, LPARAM lParam) +{ + if (lParam) + { + strncpy((char *)lParam, SKYPE_PROTONAME, wParam); + return 0; // Success + } + return 1; // Failure +} + + +INT_PTR SkypeLoadIcon(WPARAM wParam,LPARAM lParam) +{ + UINT id; + + UNREFERENCED_PARAMETER(lParam); + + switch(wParam&0xFFFF) { + case PLI_PROTOCOL: id=IDI_SKYPE; break; // IDI_MAIN is the main icon for the protocol + default: return (int)(HICON)NULL; + } + return (int)LoadImage(hInst,MAKEINTRESOURCE(id),IMAGE_ICON,GetSystemMetrics(wParam&PLIF_SMALL?SM_CXSMICON:SM_CXICON),GetSystemMetrics(wParam&PLIF_SMALL?SM_CYSMICON:SM_CYICON),0); +} + +INT_PTR SkypeGetAvatar(WPARAM wParam,LPARAM lParam) +{ DBVARIANT dbv; + if (!DBGetContactSettingString(NULL,SKYPE_PROTONAME, "AvatarFile", &dbv)){ + lstrcpynA((char*)wParam, dbv.pszVal, (int)lParam); + DBFreeVariant(&dbv); + } + return 0; +} diff --git a/plugins/!NotAdopted/Skype/skypesvc.h b/plugins/!NotAdopted/Skype/skypesvc.h new file mode 100644 index 0000000000..74c8cd37bf --- /dev/null +++ b/plugins/!NotAdopted/Skype/skypesvc.h @@ -0,0 +1,24 @@ +#include +#include +#include +#include +#include +#include "resource.h" + +void CreateProtoService(const char* szService, MIRANDASERVICE svc); +void HookEvents(void); +void HookEventsLoaded(void); +void UnhookEvents(void); +void CreateServices(void); +INT_PTR SkypeLoadIcon(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeGetName(WPARAM wParam, LPARAM lParam); +INT_PTR SkypeGetCaps(WPARAM wParam, LPARAM lParam); +/* SkypeGetAvatar + * + * Purpose: Return the avatar file name + * Params : wParam=0 + * lParam=0 + * Returns: 0 - Success + * -1 - Failure + */ +INT_PTR SkypeGetAvatar(WPARAM wParam,LPARAM lParam); \ No newline at end of file diff --git a/plugins/!NotAdopted/Skype/utf8.c b/plugins/!NotAdopted/Skype/utf8.c new file mode 100644 index 0000000000..8ae746e871 --- /dev/null +++ b/plugins/!NotAdopted/Skype/utf8.c @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2001 Peter Harris + * Copyright (C) 2001 Edmund Grimley Evans + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Convert a string between UTF-8 and the locale's charset. + */ + +#include +#include + +#include "utf8.h" + +#ifdef _WIN32 + + /* Thanks to Peter Harris for this win32 + * code. + */ + +#include +#include + +unsigned char *make_utf8_string(const wchar_t *unicode) +{ + int size = 0, index = 0, out_index = 0; + unsigned char *out; + unsigned short c; + + /* first calculate the size of the target string */ + c = unicode[index++]; + while(c) { + if(c < 0x0080) { + size += 1; + } else if(c < 0x0800) { + size += 2; + } else { + size += 3; + } + c = unicode[index++]; + } + + out = (unsigned char *) malloc(size + 1); + if (out == NULL) + return NULL; + index = 0; + + c = unicode[index++]; + while(c) + { + if(c < 0x080) { + out[out_index++] = (unsigned char)c; + } else if(c < 0x800) { + #pragma warning (suppress: 4244) // conversion from 'int' to 'unsigned char', possible loss of data + out[out_index++] = 0xc0 | (c >> 6); + out[out_index++] = 0x80 | (c & 0x3f); + } else { + out[out_index++] = 0xe0 | (c >> 12); + out[out_index++] = 0x80 | ((c >> 6) & 0x3f); + out[out_index++] = 0x80 | (c & 0x3f); + } + c = unicode[index++]; + } + out[out_index] = 0x00; + + return out; +} + +wchar_t *make_unicode_string(const unsigned char *utf8) +{ + int size = 0, index = 0, out_index = 0; + wchar_t *out; + unsigned char c; + + /* first calculate the size of the target string */ + c = utf8[index++]; + while(c) { + if((c & 0x80) == 0) { + index += 0; + } else if((c & 0xe0) == 0xe0) { + index += 2; + } else { + index += 1; + } + size += 1; + c = utf8[index++]; + } + + out = (wchar_t *) malloc((size + 1) * sizeof(wchar_t)); + if (out == NULL) + return NULL; + index = 0; + + c = utf8[index++]; + while(c) + { + if((c & 0x80) == 0) { + out[out_index++] = c; + } else if((c & 0xe0) == 0xe0) { + out[out_index] = (c & 0x1F) << 12; + c = utf8[index++]; + out[out_index] |= (c & 0x3F) << 6; + c = utf8[index++]; + out[out_index++] |= (c & 0x3F); + } else { + out[out_index] = (c & 0x3F) << 6; + c = utf8[index++]; + out[out_index++] |= (c & 0x3F); + } + c = utf8[index++]; + } + out[out_index] = 0; + + return out; +} + +int utf8_encode(const char *from, char **to) +{ + wchar_t *unicode; + int wchars, err; + + wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, strlen(from), NULL, 0); + + if(wchars == 0) + { +// fprintf(stderr, "Unicode translation error %d\n"), GetLastError(); + return -1; + } + + unicode = (wchar_t *) calloc(wchars + 1, sizeof(unsigned short)); + if(unicode == NULL) + { +// fprintf(stderr, "Out of memory processing string to UTF8\n"); + return -1; + } + + err = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, strlen(from), unicode, wchars); + if(err != wchars) + { + free(unicode); +// fprintf(stderr, "Unicode translation error %d\n"), GetLastError(); + return -1; + } + + /* On NT-based windows systems, we could use WideCharToMultiByte(), but + * MS doesn't actually have a consistent API across win32. + */ + *to = (char *) make_utf8_string(unicode); + + free(unicode); + return 0; +} + +int utf8_decode(const char *from, char **to) +{ + wchar_t *unicode; + int chars, err; +// LPCPINFO lpCPInfo; + + /* On NT-based windows systems, we could use MultiByteToWideChar(CP_UTF8), but + * MS doesn't actually have a consistent API across win32. + */ + unicode = make_unicode_string( (const unsigned char *)from); + if(unicode == NULL) + { + fprintf(stderr, "Out of memory processing string from UTF8 to UNICODE16\n"); + return -1; + } + + //if(GetCPInfo(CP_ACP,lpCPInfo)) + { + + chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, NULL, 0, NULL, NULL); + } + /*else + { + chars = WideCharToMultiByte(GetConsoleCP(), WC_COMPOSITECHECK, unicode, -1, NULL, 0, NULL, NULL); + }*/ + + if(chars == 0) + { + fprintf(stderr, "Unicode translation error %ld\n", GetLastError()); + free(unicode); + return -1; + } + + *to = (char *) calloc(chars + 1, sizeof(unsigned char)); + if(*to == NULL) + { + fprintf(stderr, "Out of memory processing string to local charset\n"); + free(unicode); + return -1; + } + + //err = WideCharToMultiByte(GetConsoleCP(), WC_COMPOSITECHECK, unicode, -1, *to, chars, NULL, NULL); + err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, *to, chars, NULL, NULL); + if(err != chars) + { + fprintf(stderr, "Unicode translation error %ld\n", GetLastError()); + free(unicode); + free(*to); + *to = NULL; + return -1; + } + + free(unicode); + return 0; +} + +#ifndef _UNICODE +char *make_tchar_string(const unsigned char *utf8) { + char *ret; + if (utf8_decode((const char*)utf8, &ret)==-1) return NULL; + return ret; +} +#endif + +#else /* End win32. Rest is for real operating systems */ + + +#ifdef HAVE_LANGINFO_CODESET +#include +#endif + +int iconvert(const char *fromcode, const char *tocode, + const char *from, size_t fromlen, + char **to, size_t *tolen); + +static char *current_charset = "BIG-5"; /* means "US-ASCII" */ + +void convert_set_charset(const char *charset) +{ + + if (!charset) + charset = getenv("CHARSET"); + +#ifdef HAVE_LANGINFO_CODESET + if (!charset) + charset = nl_langinfo(CODESET); +#endif + + free(current_charset); + current_charset = 0; + if (charset && *charset) + current_charset = _strdup(charset); +} + +static int convert_buffer(const char *fromcode, const char *tocode, + const char *from, size_t fromlen, + char **to, size_t *tolen) +{ + int ret = -1; + +#ifdef HAVE_ICONV + ret = iconvert(fromcode, tocode, from, fromlen, to, tolen); + if (ret != -1) + return ret; +#endif + +#ifndef HAVE_ICONV /* should be ifdef USE_CHARSET_CONVERT */ + ret = charset_convert(fromcode, tocode, from, fromlen, to, tolen); + if (ret != -1) + return ret; +#endif + + return ret; +} + +static int convert_string(const char *fromcode, const char *tocode, + const char *from, char **to, char replace) +{ + int ret; + size_t fromlen; + char *s; + + fromlen = lstrlen(from); + ret = convert_buffer(fromcode, tocode, from, fromlen, to, 0); + if (ret == -2) + return -1; + if (ret != -1) + return ret; + + s = malloc(fromlen + 1); + if (!s) + return -1; + lstrcpy(s, from); + *to = s; + for (; *s; s++) + if (*s & ~0x7f) + *s = replace; + return 3; +} + +int utf8_encode(const char *from, char **to) +{ + char *charset; + + if (!current_charset) + convert_set_charset(0); + charset = current_charset ? current_charset : "US-ASCII"; + return convert_string(charset, "UTF-8", from, to, '#'); +} + +int utf8_decode(const char *from, char **to) +{ + char *charset; + + if(*from == 0) { + *to = malloc(1); + **to = 0; + return 1; + } + + if (!current_charset) + convert_set_charset(0); + charset = current_charset ? current_charset : "US-ASCII"; + return convert_string("UTF-8", charset, from, to, '?'); +} + +#endif diff --git a/plugins/!NotAdopted/Skype/utf8.h b/plugins/!NotAdopted/Skype/utf8.h new file mode 100644 index 0000000000..70c533deca --- /dev/null +++ b/plugins/!NotAdopted/Skype/utf8.h @@ -0,0 +1,47 @@ +/* + * Convert a string between UTF-8 and the locale's charset. + * Invalid bytes are replaced by '#', and characters that are + * not available in the target encoding are replaced by '?'. + * + * If the locale's charset is not set explicitly then it is + * obtained using nl_langinfo(CODESET), where available, the + * environment variable CHARSET, or assumed to be US-ASCII. + * + * Return value of conversion functions: + * + * -1 : memory allocation failed + * 0 : data was converted exactly + * 1 : valid data was converted approximately (using '?') + * 2 : input was invalid (but still converted, using '#') + * 3 : unknown encoding (but still converted, using '?') + */ + +#ifndef __UTF8_H +#define __UTF8_H + +#ifdef __cplusplus +extern "C" { +#endif + +void convert_set_charset(const char *charset); + +int utf8_encode(const char *from, char **to); +int utf8_decode(const char *from, char **to); +wchar_t *make_unicode_string(const unsigned char *utf8); +unsigned char *make_utf8_string(const wchar_t *unicode); +#ifdef _UNICODE +#define make_tchar_string make_unicode_string +// Helpers for strings that only can contain 7bit chars to not make unneccessary memory allocation +#define make_nonutf_tchar_string(x) make_tchar_string(x) +#define free_nonutf_tchar_string(x) if(x) free(x); +#else +char *make_tchar_string(const unsigned char *utf8); +#define make_nonutf_tchar_string(x) (char*)x +#define free_nonutf_tchar_string(x) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __UTF8_H */ diff --git a/plugins/!NotAdopted/Skype/util.c b/plugins/!NotAdopted/Skype/util.c new file mode 100644 index 0000000000..ce5ad9c756 --- /dev/null +++ b/plugins/!NotAdopted/Skype/util.c @@ -0,0 +1,57 @@ +#include + +char * __cdecl strtok_r ( + char * string, + const char * control, + char **nextoken + ) +{ + unsigned char *str; + const unsigned char *ctrl = (const unsigned char*)control; + + unsigned char map[32]; + int count; + + /* Clear control map */ + for (count = 0; count < 32; count++) + map[count] = 0; + + /* Set bits in delimiter table */ + do { + map[*ctrl >> 3] |= (1 << (*ctrl & 7)); + } while (*ctrl++); + + /* Initialize str. If string is NULL, set str to the saved + * pointer (i.e., continue breaking tokens out of the string + * from the last strtok call) */ + if (string) + str = (unsigned char*)string; + else + str = (unsigned char*)(*nextoken); + + /* Find beginning of token (skip over leading delimiters). Note that + * there is no token iff this loop sets str to point to the terminal + * null (*str == '\0') */ + while ( (map[*str >> 3] & (1 << (*str & 7))) && *str ) + str++; + + string = (char*)str; + + /* Find the end of the token. If it is not the end of the string, + * put a null there. */ + for ( ; *str ; str++ ) + if ( map[*str >> 3] & (1 << (*str & 7)) ) { + *str++ = '\0'; + break; + } + + /* Update nextoken (or the corresponding field in the per-thread data + * structure */ + *nextoken = (char*)str; + + /* Determine if a token has been found. */ + if ( string == (char*)str ) + return NULL; + else + return string; +} diff --git a/plugins/!NotAdopted/Skype/util.h b/plugins/!NotAdopted/Skype/util.h new file mode 100644 index 0000000000..181f5d1878 --- /dev/null +++ b/plugins/!NotAdopted/Skype/util.h @@ -0,0 +1,7 @@ +char * __cdecl strtok_r ( + char * string, + const char * control, + char **nextoken + ); + +void TranslateMirandaRelativePathToAbsolute(LPCSTR cszPath, LPSTR szAbsolutePath, BOOL fQuoteSpaces); diff --git a/plugins/!NotAdopted/Skype/voiceservice.c b/plugins/!NotAdopted/Skype/voiceservice.c new file mode 100644 index 0000000000..b13ac097c1 --- /dev/null +++ b/plugins/!NotAdopted/Skype/voiceservice.c @@ -0,0 +1,156 @@ +#include "skype.h" +#include "skypeapi.h" +#include "skypesvc.h" +#include "voiceservice.h" +#include "sdk/m_voiceservice.h" + +#pragma warning (push) +#pragma warning (disable: 4100) // unreferenced formal parameter +#include "../../include/m_utils.h" +#pragma warning (pop) + +HANDLE hVoiceNotify = NULL; +BOOL has_voice_service = FALSE; + +extern char g_szProtoName[]; + + +BOOL HasVoiceService() +{ + return has_voice_service; +} + +void NofifyVoiceService(HANDLE hContact, char *callId, int state) +{ + VOICE_CALL vc = {0}; + vc.cbSize = sizeof(vc); + vc.szModule = SKYPE_PROTONAME; + vc.id = callId; + vc.flags = VOICE_CALL_CONTACT; + vc.state = state; + vc.hContact = hContact; + NotifyEventHooks(hVoiceNotify, (WPARAM) &vc, 0); +} + +static INT_PTR VoiceGetInfo(WPARAM wParam, LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + + return VOICE_SUPPORTED | VOICE_CALL_CONTACT | VOICE_CAN_HOLD; +} + +static HANDLE FindContactByCallId(char *callId) +{ + HANDLE hContact; + int iCmpRes; + for (hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + hContact != NULL; + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) + { + char *szProto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + + DBVARIANT dbv; + if (szProto != NULL + && !strcmp(szProto, SKYPE_PROTONAME) + && DBGetContactSettingByte(hContact, SKYPE_PROTONAME, "ChatRoom", 0) == 0 + && !DBGetContactSettingString(hContact, SKYPE_PROTONAME, "CallId", &dbv)) + { + iCmpRes = strcmp(callId, dbv.pszVal); + DBFreeVariant(&dbv); + if (iCmpRes == 0) return hContact; + } + } + + return NULL; +} + +static INT_PTR VoiceCall(WPARAM wParam, LPARAM lParam) +{ + DBVARIANT dbv; + + UNREFERENCED_PARAMETER(lParam); + + if (!wParam) return -1; + + if (DBGetContactSettingString((HANDLE)wParam, SKYPE_PROTONAME, SKYPE_NAME, &dbv)) + return -1; + + SkypeSend("CALL %s", dbv.pszVal); + DBFreeVariant (&dbv); + + return 0; +} + +static INT_PTR VoiceAnswer(WPARAM wParam, LPARAM lParam) +{ + char *callId = (char *) wParam; + + UNREFERENCED_PARAMETER(lParam); + + if (!wParam) return -1; + + if (FindContactByCallId(callId) == NULL) + return -1; + + SkypeSend("SET %s STATUS INPROGRESS", callId); + testfor("ERROR", 200); + + return 0; +} + +static INT_PTR VoiceDrop(WPARAM wParam, LPARAM lParam) +{ + char *callId = (char *) wParam; + + UNREFERENCED_PARAMETER(lParam); + + if (!wParam) return -1; + + if (FindContactByCallId(callId) == NULL) + return -1; + + SkypeSend("SET %s STATUS FINISHED", callId); + + return 0; +} + +static INT_PTR VoiceHold(WPARAM wParam, LPARAM lParam) +{ + char *callId = (char *) wParam; + + UNREFERENCED_PARAMETER(lParam); + + if (!wParam) return -1; + + if (FindContactByCallId(callId) == NULL) + return -1; + + SkypeSend("SET %s STATUS ONHOLD", callId); + + return 0; +} + +void VoiceServiceInit() +{ + // leecher, 26.03.2011: Did this ever work in the old versions?? + char szEvent[MAXMODULELABELLENGTH]; + + _snprintf (szEvent, sizeof(szEvent), "%s%s", SKYPE_PROTONAME, PE_VOICE_CALL_STATE); + hVoiceNotify = CreateHookableEvent( szEvent ); + CreateProtoService( PS_VOICE_GETINFO, VoiceGetInfo ); + CreateProtoService( PS_VOICE_CALL, VoiceCall ); + CreateProtoService( PS_VOICE_ANSWERCALL, VoiceAnswer ); + CreateProtoService( PS_VOICE_DROPCALL, VoiceDrop ); + CreateProtoService( PS_VOICE_HOLDCALL, VoiceHold ); +} + +void VoiceServiceExit() +{ + DestroyHookableEvent(hVoiceNotify); +} + +void VoiceServiceModulesLoaded() +{ + has_voice_service = ServiceExists(MS_VOICESERVICE_REGISTER); +} \ No newline at end of file diff --git a/plugins/!NotAdopted/Skype/voiceservice.h b/plugins/!NotAdopted/Skype/voiceservice.h new file mode 100644 index 0000000000..bbb333ec4b --- /dev/null +++ b/plugins/!NotAdopted/Skype/voiceservice.h @@ -0,0 +1,18 @@ +#ifndef _VOICESERVICE_H_ +#define _VOICESERVICE_H_ + +#pragma warning (push) +#pragma warning (disable: 4201) // nonstandard extension used : nameless struct/union +#include "sdk/m_voice.h" +#pragma warning (pop) + +BOOL HasVoiceService(); +void VoiceServiceInit(); +void VoiceServiceExit(); +void VoiceServiceModulesLoaded(); +void NofifyVoiceService(HANDLE hContact, char *callId, int state) ; + + + +#endif // _VOICESERVICE_H_ + diff --git a/plugins/!NotAdopted/SmartAutoAway/AggressiveOptimize.h b/plugins/!NotAdopted/SmartAutoAway/AggressiveOptimize.h new file mode 100644 index 0000000000..51e5f5de04 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/AggressiveOptimize.h @@ -0,0 +1,166 @@ + +////////////////////////////// +// Version 1.40 +// October 22nd, 2002 - .NET (VC7, _MSC_VER=1300) support! +// Version 1.30 +// Nov 24th, 2000 +// Version 1.20 +// Jun 9th, 2000 +// Version 1.10 +// Jan 23rd, 2000 +// Version 1.00 +// May 20th, 1999 +// Todd C. Wilson, Fresh Ground Software +// (todd@nopcode.com) +// This header file will kick in settings for Visual C++ 5 and 6 that will (usually) +// result in smaller exe's. +// The "trick" is to tell the compiler to not pad out the function calls; this is done +// by not using the /O1 or /O2 option - if you do, you implicitly use /Gy, which pads +// out each and every function call. In one single 500k dll, I managed to cut out 120k +// by this alone! +// The other two "tricks" are telling the Linker to merge all data-type segments together +// in the exe file. The relocation, read-only (constants) data, and code section (.text) +// sections can almost always be merged. Each section merged can save 4k in exe space, +// since each section is padded out to 4k chunks. This is very noticeable with smaller +// exes, since you could have only 700 bytes of data, 300 bytes of code, 94 bytes of +// strings - padded out, this could be 12k of runtime, for 1094 bytes of stuff! For larger +// programs, this is less overall, but can save at least 4k. +// Note that if you're using MFC static or some other 3rd party libs, you may get poor +// results with merging the readonly (.rdata) section - the exe may grow larger. +// To use this feature, define _MERGE_DATA_ in your project or before this header is used. +// With Visual C++ 5, the program uses a file alignment of 512 bytes, which results +// in a small exe. Under VC6, the program instead uses 4k, which is the same as the +// section size. The reason (from what I understand) is that 4k is the chunk size of +// the virtual memory manager, and that WinAlign (an end-user tuning tool for Win98) +// will re-align the programs on this boundary. The problem with this is that all of +// Microsoft's system exes and dlls are *NOT* tuned like this, and using 4k causes serious +// exe bloat. This is very noticeable for smaller programs. +// The "trick" for this is to use the undocumented FILEALIGN linker parm to change the +// padding from 4k to 1/2k, which results in a much smaller exe - anywhere from 20%-75% +// depending on the size. Note that this is the same as using /OPT:NOWIN98, which *is* +// a previously documented switch, but was left out of the docs for some reason in VC6 and +// all of the current MSDN's - see KB:Q235956 for more information. +// Microsoft does say that using the 4k alignment will "speed up process loading", +// but I've been unable to notice a difference, even on my P180, with a very large (4meg) exe. +// Please note, however, that this will probably not change the size of the COMPRESSED +// file (either in a .zip file or in an install archive), since this 4k is all zeroes and +// gets compressed away. +// Also, the /ALIGN:4096 switch will "magically" do the same thing, even though this is the +// default setting for this switch. Apparently this sets the same values as the above two +// switches do. We do not use this in this header, since it smacks of a bug and not a feature. +// Thanks to Michael Geary for some additional tips! +// +// Notes about using this header in .NET +// First off, VC7 does not allow a lot of the linker command options in pragma's. There is no +// honest or good reason why Microsoft decided to make this change, it just doesn't. +// So that is why there are a lot of <1300 #if's in the header. +// If you want to take full advantage of the VC7 linker options, you will need to do it on a +// PER PROJECT BASIS; you can no longer use a global header file like this to make it better. +// Items I strongly suggest putting in all your VC7 project linker options command line settings: +// /ignore:4078 /RELEASE +// Compiler options: +// /GL (Whole Program Optimization) +// If you're making an .EXE and not a .DLL, consider adding in: +// /GA (Optimize for Windows Application) +// Some items to consider using in your VC7 projects (not VC6): +// Link-time Code Generation - whole code optimization. Put this in your exe/dll project link settings. +// /LTCG:NOSTATUS +// The classic no-padding and no-bloat compiler C/C++ switch: +// /opt:nowin98 +// +// (C++ command line options: /GL /opt:nowin98 and /GA for .exe files) +// (Link command line options: /ignore:4078 /RELEASE /LTCG:NOSTATUS) +// +// Now, notes on using these options in VC7 vs VC6. +// VC6 consistently, for me, produces smaller code from C++ the exact same sources, +// with or without this header. On average, VC6 produces 5% smaller binaries compared +// to VC7 compiling the exact same project, *without* this header. With this header, VC6 +// will make a 13k file, while VC7 will make a 64k one. VC7 is just bloaty, pure and +// simple - all that managed/unmanaged C++ runtimes, and the CLR stuff must be getting +// in the way of code generation. However, template support is better, so there. +// Both VC6 and VC7 show the same end kind of end result savings - larger binary output +// will shave about 2% off, where as smaller projects (support DLL's, cpl's, +// activex controls, ATL libs, etc) get the best result, since the padding is usually +// more than the actual usable code. But again, VC7 does not compile down as small as VC6. +// +// The argument can be made that doing this is a waste of time, since the "zero bytes" +// will be compressed out in a zip file or install archive. Not really - it doesn't matter +// if the data is a string of zeroes or ones or 85858585 - it will still take room (20 bytes +// in a zip file, 29 bytes if only *4* of them 4k bytes are not the same) and time to +// compress that data and decompress it. Also, 20k of zeros is NOT 20k on disk - it's the +// size of the cluster slop- for Fat32 systems, 20k can be 32k, NTFS could make it 24k if you're +// just 1 byte over (round up). Most end users do not have the dual P4 Xeon systems with +// two gigs of RDram and a Raid 0+1 of Western Digital 120meg Special Editions that all +// worthy developers have (all six of us), so they will need any space and LOADING TIME +// savings they will need; taking an extra 32k or more out of your end user's 64megs of +// ram on Windows 98 is Not a Good Thing. +// +// Now, as a ADDED BONUS at NO EXTRA COST TO YOU! Under VC6, using the /merge:.text=.data +// pragma will cause the output file to be un-disassembleable! (is that a word?) At least, +// with the normal tools - WinDisam, DumpBin, and the like will not work. Try it - use the +// header, compile release, and then use DUMPBIN /DISASM filename.exe - no code! +// Thanks to Gлzim Pani for discovering this gem - for a full writeup on +// this issue and the ramifactions of it, visit www.nopcode.com for the Aggressive Optimize +// article. + +#ifndef _AGGRESSIVEOPTIMIZE_H_ +#define _AGGRESSIVEOPTIMIZE_H_ + +#pragma warning(disable:4711) + +#ifdef NDEBUG +// /Og (global optimizations), /Os (favor small code), /Oy (no frame pointers) +#pragma optimize("gsy",on) + +#if (_MSC_VER<1300) + #pragma comment(linker,"/RELEASE") +#endif + +// Note that merging the .rdata section will result in LARGER exe's if you using +// MFC (esp. static link). If this is desirable, define _MERGE_RDATA_ in your project. +#ifdef _MERGE_RDATA_ +#pragma comment(linker,"/merge:.rdata=.data") +#endif // _MERGE_RDATA_ + +#pragma comment(linker,"/merge:.text=.data") +#if (_MSC_VER<1300) + // In VC7, this causes problems with the relocation and data tables, so best to not merge them + #pragma comment(linker,"/merge:.reloc=.data") +#endif + +// Merging sections with different attributes causes a linker warning, so +// turn off the warning. From Michael Geary. Undocumented, as usual! +#if (_MSC_VER<1300) + // In VC7, you will need to put this in your project settings + #pragma comment(linker,"/ignore:4078") +#endif + +// With Visual C++ 5, you already get the 512-byte alignment, so you will only need +// it for VC6, and maybe later. +#if _MSC_VER >= 1000 + +// Option #1: use /filealign +// Totally undocumented! And if you set it lower than 512 bytes, the program crashes. +// Either leave at 0x200 or 0x1000 +//#pragma comment(linker,"/FILEALIGN:0x200") + +// Option #2: use /opt:nowin98 +// See KB:Q235956 or the READMEVC.htm in your VC directory for info on this one. +// This is our currently preferred option, since it is fully documented and unlikely +// to break in service packs and updates. +#if (_MSC_VER<1300) + // In VC7, you will need to put this in your project settings + #pragma comment(linker,"/opt:nowin98") +#else + +// Option #3: use /align:4096 +// A side effect of using the default align value is that it turns on the above switch. +// Does nothing under Vc7 that /opt:nowin98 doesn't already give you +// #pragma comment(linker,"/ALIGN:512") +#endif + +#endif // _MSC_VER >= 1000 + +#endif // NDEBUG + +#endif // _AGGRESSIVEOPTIMIZE_H_ diff --git a/plugins/!NotAdopted/SmartAutoAway/aa_utils.cpp b/plugins/!NotAdopted/SmartAutoAway/aa_utils.cpp new file mode 100644 index 0000000000..c759cff91c --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/aa_utils.cpp @@ -0,0 +1,396 @@ +#include "globals.h" + + +//Proto_Status2Flag + + int OldIndexToStatus(int oldIndex){ + switch (oldIndex){ + case 0 : return ID_STATUS_AWAY; + case 1 : return ID_STATUS_DND; + case 2 : return ID_STATUS_NA; + case 3 : return ID_STATUS_OCCUPIED; + case 4 : return ID_STATUS_INVISIBLE; + case 5 : return ID_STATUS_ONTHEPHONE; + case 6 : return ID_STATUS_OUTTOLUNCH; + case 7 : return ID_STATUS_ONLINE; + case 8 : return ID_STATUS_FREECHAT; + case 9 : return ID_STATUS_OFFLINE; + } + return 0; +} + int StatusToOldIndex(int status){ + switch (status){ + case ID_STATUS_AWAY : return 0; + case ID_STATUS_DND : return 1; + case ID_STATUS_NA : return 2; + case ID_STATUS_OCCUPIED : return 3; + case ID_STATUS_INVISIBLE : return 4; + case ID_STATUS_ONTHEPHONE : return 5; + case ID_STATUS_OUTTOLUNCH : return 6; + case ID_STATUS_ONLINE : return 7; + case ID_STATUS_FREECHAT : return 8; + case ID_STATUS_OFFLINE : return 9; + } + return 0; +} + + unsigned long SetBits (unsigned long target,unsigned long mask,unsigned long value) +{ + int shift = 0; + unsigned long t; + while (!((mask>>shift)&1)) { + shift++; + } + t = mask ^ 0xFFFFFFFF; + target = target & t; + value = value<>shift)&1)) { + shift++; + } + t = source & mask; + return t >> shift; +} + +BOOL isInterestingProto(int j){ + if ( proto[j]->type != PROTOTYPE_PROTOCOL ) return 0; + if (protoModes[j] > 1) return 1; + else return 0; + } + + BOOL IsStatusBitSet(int status, int bits){ + int i=0; + int mask=1; + for (i = numStatuses-1; i>=0; i--){ + if (aa_Status[i]==status) return (mask & bits); + mask <<= 1; + } + return 0; +} + + int StatusByProtoIndex(int modes, int index){ + int i=0; + int indexcount=0; + int mask = (1<<(numStatuses-1)); + for (i = 0; i < numStatuses ; i++){ + BOOL isset = (modes & mask); + if (isset) { + indexcount++; + if (indexcount==index) return aa_Status[i]; + } + mask >>= 1; + } + return 0; +} + + int StatusToProtoIndex(int status, int modes){ + int i=0; + int indexcount=0; + int mask = (1<<(numStatuses-1)); + for (i = 0; i < numStatuses ; i++){ + BOOL isset = (modes & mask); + if (isset) { + indexcount++; + if (status==aa_Status[i]) return indexcount; + } + mask >>= 1; + } + return 0; + +} + BOOL StrikeOut(HWND hWnd, int item, BOOL striked) +{ + LOGFONT lf; + HFONT hFont; + BOOL previous; + + hFont = (HFONT)SendDlgItemMessage(hWnd, item, WM_GETFONT, 0, 0); + GetObject(hFont, sizeof(lf), &lf); + previous = lf.lfItalic; + lf.lfItalic = striked; + SendDlgItemMessage(hWnd, item, WM_SETFONT, (WPARAM)CreateFontIndirect(&lf), TRUE); + return previous; +} + + int GetCourSelProtocol(int sel){ + int j; + int protoindex=0; + int selectedProto = 0; + for (j = 0 ; j < protoCount ; j++) { + if ( !isInterestingProto(j) ) continue; + { + if (protoindex==(sel)){ + return j; + } + } + protoindex++; + } + return -1; +} + +LRESULT SetDlgItems(HWND hwndDlg, int coursel) +{ + SendDlgItemMessage(hwndDlg, IDC_REQSTATUSLABEL, WM_SETTEXT, 0,(LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)reqStatus[coursel], GCMDF_TCHAR)); + SendDlgItemMessage(hwndDlg, IDC_COURSTATUSLABEL, WM_SETTEXT, 0,(LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courStatus[coursel], GCMDF_TCHAR)); + return TRUE; +} + +int GetReconnectDelayFromSlider(int slide) +{ + if (slide < 4) return 6+slide; + else if (slide < 29) return 2+slide* 2; + else if (slide < 53) return -85+slide* 5; + else if (slide < 65) return -350+slide*10; + else if (slide < 85) return-1650+slide*30; + else return -4200+slide*60; +} + +int GetSliderFromReconnectDelay(int delay) +{ + if (delay< 6) return 0; + else if (delay< 10) return -6+delay; + else if (delay< 60) return -1+delay/ 2; + else if (delay< 180) return 17+delay/ 5; + else if (delay< 300) return 35+delay/10; + else if (delay< 900) return 55+delay/30; + else if (delay<1800) return 70+delay/60; + else return 100; +} +BOOL GetStringFromDelay(TCHAR * str, int delay) +{ + int min,sec; + min = (int)delay/60; + sec = delay-min*60; + int pos = _stprintf(str,_T("%s "), TranslateT("Reconnect after")); + if (min) pos += _stprintf(&str[pos],_T("%d %s "),min,TranslateT("min")); + if (sec) pos += _stprintf(&str[pos],_T("%d %s"),sec,TranslateT("sec")); +// if (!min) sprintf(str,"%s (Too fast!)",str); + return (delay<60); +} + + +void GetLastActiveLocalTime(SYSTEMTIME * at, unsigned long Seconds){ + FILETIME ft; + ULARGE_INTEGER t; + + GetSystemTimeAsFileTime(&ft); + t.u.LowPart = ft.dwLowDateTime; + t.u.HighPart = ft.dwHighDateTime; + t.QuadPart -= (__int64)Seconds*10000000; + ft.dwLowDateTime = t.u.LowPart; + ft.dwHighDateTime = t.u.HighPart; + FileTimeToSystemTime(&ft,at); + SystemTimeToTzSpecificLocalTime(NULL,at,at); +} + +int GetTimeZone(TCHAR * name){ + TIME_ZONE_INFORMATION tzi={0}; + DWORD dwSta; + + dwSta= GetTimeZoneInformation( &tzi ); + switch (dwSta) { + case 0: + case TIME_ZONE_ID_STANDARD: +#ifdef UNICODE + wcscpy(name,tzi.StandardName); +#else + _stprintf(name,_T("%S"),tzi.StandardName); +#endif + return -(tzi.Bias+tzi.StandardBias); + break; + case TIME_ZONE_ID_DAYLIGHT: +#ifdef UNICODE + wcscpy(name,tzi.DaylightName); +#else + _stprintf(name,_T("%S"),tzi.DaylightName); +#endif + return -(tzi.Bias+tzi.DaylightBias); + break; + case TIME_ZONE_ID_INVALID: + default: + name[0] = 0; + return 0; + break; + } +} +void my_u2a(const TCHAR* src, char * target, unsigned int max){ +#ifdef UNICODE + int r = WideCharToMultiByte(codePage, 0, src, -1, target, max, NULL, NULL ); + /*if (!r){ + int err=GetLastError(); + WCHAR errBuf[1024]; + int p = wsprintf(errBuf,L"Error %u: \n",err); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + err, + 0, + &errBuf[p], + 1024-p-1, + NULL); + MessageBoxW(NULL, errBuf, L"Error u2a", MB_OK); + }*/ +#else + strncpy(target,src,max); +#endif + target[ max ] = 0; +} + +void my_a2u(const char* src, TCHAR * target, unsigned int max){ +#ifdef UNICODE + int r = MultiByteToWideChar(codePage, 0, src, -1, target, max); +#else + strncpy(target,src,max); +#endif + target[ max ] = 0; +} + +UINT ParseString(TCHAR *szstring,TCHAR *sztemp, unsigned int MaxOutLen) +{ + UINT loop=0; + TCHAR *weekdays[]={LPGENT("Sunday"),LPGENT("Monday"),LPGENT("Tuesday"),LPGENT("Wednesday"),LPGENT("Thursday"),LPGENT("Friday"),LPGENT("Saturday")}; + TCHAR *wdays_short[]={LPGENT("Sun"),LPGENT("Mon"),LPGENT("Tue"),LPGENT("Wed"),LPGENT("Thu"),LPGENT("Fri"),LPGENT("Sat")}; + TCHAR *monthnames[]={LPGENT("January"),LPGENT("February"),LPGENT("March"),LPGENT("April"),LPGENT("May"),LPGENT("June"),LPGENT("July"),LPGENT("August"),LPGENT("September"),LPGENT("October"),LPGENT("November"),LPGENT("December")}; + TCHAR *mnames_short[]={LPGENT("Jan"),LPGENT("Feb"),LPGENT("Mar"),LPGENT("Apr"),LPGENT("May"),LPGENT("Jun"),LPGENT("Jul"),LPGENT("Aug"),LPGENT("Sep"),LPGENT("Oct"),LPGENT("Nov"),LPGENT("Dec")}; + SYSTEMTIME st = {0}; + BOOL stFilled = FALSE; + BOOL tzFilled = FALSE; + TCHAR tzName[128]; + int tzDrift; + *sztemp = '\0'; + UINT inpLen=_tcsclen(szstring); + UINT pos=0; + for(loop=0;loop12)?12:0)):12); + break; + + case 'p': + res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%s"),TranslateTS((st.wHour>12)?_T("PM"):_T("AM"))); + break; + + case 'M': + res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%02i"),st.wMinute); + break; + + case 'S': + res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%02i"),st.wSecond); + break; + + case 'L': + case 'l': + case 'K': + case 'k': + { + switch (szstring[loop]){ + case 'L': + case 'l': + res = GetDateFormat(localeID, szstring[loop]=='L'?DATE_LONGDATE:DATE_SHORTDATE, &st, NULL, &sztemp[pos], MaxOutLen-pos); + break; + case 'K': + case 'k': + res = GetTimeFormat(localeID, szstring[loop]=='K'?0:TIME_NOSECONDS, &st, NULL, &sztemp[pos], MaxOutLen-pos); + default: + break; + } + if (res>0) res--; + else res=0; + } break; + default: + break; + } + break; + case 'z': case 'Z': + if (!tzFilled) { + tzDrift = GetTimeZone(tzName); + tzFilled = TRUE; + } + if (szstring[loop]=='Z') res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%s"),tzName); + else { + res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%02d:%02d"),div(tzDrift,60).quot,tzDrift<0?-div(tzDrift,60).rem:div(tzDrift,60).rem); + } + break; + case 'b': + res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("\x0D\x0A")); + break; + case 't': + res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%c"),_T('\t')); + break; + default: + res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%%%c"),szstring[loop]); + break; + } + } + if (res<0) break; + else pos += res; + } + //sztemp[MaxOutLen]=sztemp[pos]=0; // Just in case + return pos; +} + + + diff --git a/plugins/!NotAdopted/SmartAutoAway/autoaway.cpp b/plugins/!NotAdopted/SmartAutoAway/autoaway.cpp new file mode 100644 index 0000000000..18754df9d2 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/autoaway.cpp @@ -0,0 +1,662 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2006 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "globals.h" + + +// globals +//static HANDLE AutoAwayEventHandle = NULL; +//static HANDLE StatusModeChangeEventHandle = NULL; +//static HANDLE ProtoAckEventHandle = NULL; +//static HANDLE AutoAwayShutdownHandle = NULL; +//static HANDLE AutoAwayOptInitialiseHandle = NULL; + + +//#define AA_LASTSTATUS "LastStatus_" +//#define AA_ONLYIF "OnlyIf" +//#define AA_ONLYIF2 "OnlyIf2" + +//#define ME_IDLE_CHANGED "Miranda/SmartIdle/Changed" +//static HANDLE hIdleEvent = NULL; + + +#define allprotomodes 0x03FF //0000 0011 1111 1111; +#define aa_OnlyIfBitsDefault 0x01BB01B8 //2 x 0000 0001 1011 1011; + //1111 0000 0000 0000; +//#define known 0x8000 //1000 0000 0000 0000; + + + + +//static int aa_OnlyIfDefaults[] = {2,2,2,2,1,2,2,2,2,1}; + +extern unsigned long lastIdleEventTime; + + +int AutoAwayOptInitialise(WPARAM wParam,LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp; + + ZeroMemory(&odp,sizeof(odp)); + odp.cbSize=sizeof(odp); + odp.position=1000000000; +#ifdef SAA_PLUGIN + odp.hInstance=g_hInst; +#else + odp.hInstance=GetModuleHandle(NULL); +#endif + odp.pszTemplate=MAKEINTRESOURCEA(IDD_OPT_SMARTAUTOAWAY); + odp.pszTitle=SECTIONNAME; + odp.pszGroup="Status"; + odp.pfnDlgProc=DlgProcAutoAwayOpts; + odp.flags=ODPF_BOLDGROUPS; + CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp); + return 0; +} + +static short int curIdleStatus = -1; //0: NotIdle, 1: Short Idle, 2: Long Idle, -1 Not init yet: Will be inited on AutoAwayEvent; +int AutoAwayEvent(WPARAM wParam, LPARAM lParam) +{ +// char str[MAXMODULELABELLENGTH]; +//#define IDF_ISIDLE 0x1 // idle has become active (if not set, inactive) +//#define IDF_SHORT 0x2 // short idle mode +//#define IDF_LONG 0x4 // long idle mode +//#define IDF_PRIVACY 0x8 // if set, the information provided shouldn't be given to third parties. +//#define IDF_ONFORCE 0x10 // screensaver/onstationlocked,etc cause instant idle + + int j; + +#ifdef AALOG + { + char log[1024]=""; + sprintf(log,"IdleEvent came: %sdle;%s%s%s%sorced.", + lParam & IDF_ISIDLE?"I":"Not i", + lParam & IDF_SHORT?" Short;":"", + lParam & IDF_LONG?" Long;":"", + lParam & IDF_PRIVACY?" Private;":"", + lParam & IDF_ONFORCE?" F":"Not f"); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); + { + MIRANDA_IDLE_INFO mii; + ZeroMemory(&mii, sizeof(mii)); + mii.cbSize = sizeof(mii); + if (CallService(MS_IDLE_GETIDLEINFO, 0, (LPARAM)&mii)==0){ + sprintf(log,"IdleInfo valid: IdleTime:%d; %srivate; Status: %s(%d); aaLock: %s.", + mii.idleTime, + mii.privacy?"P":"Not p", + CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)mii.aaStatus, 0), + mii.aaStatus, + mii.aaLock?"Yes":"No"); + } else { + sprintf(log,"IdleInfo Failed: Size: %d; IdleTime: %d.",mii.cbSize,mii.idleTime); + } + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); + } + } +#endif + if ( lParam & IDF_ISIDLE ) { //going to sleep... + if ( lParam & IDF_LONG ) { //... deeply + if (curIdleStatus > 1) return 0; // we are already deeply sleeping... + curIdleStatus = 2; + } else { //... lite if IDF_LONG is not set + if (curIdleStatus > 0) return 0; // we are already sleeping... + curIdleStatus = 1; + } + } else { // we are going to awake + if (curIdleStatus == 0) return 0; // we are already awake... + curIdleStatus = 0; + } + if (!starting){ + lastIdleEventTime = time(NULL)-secondsAfterLastActivity; + if ((idleOptsPerm&IdleSuppressAutoHere)!=0) { + DBWriteContactSettingByte(NULL,AA_MODULE,AA_LASTIDLESTATUS,(BYTE)curIdleStatus); + DBWriteContactSettingDword(NULL,AA_MODULE,AA_LASTIDLETIME,(DWORD)lastIdleEventTime); + } } + switch (curIdleStatus) { + case 0: + xModifyMenu(0,CMIF_CHECKED); + xModifyMenu(1,0); + xModifyMenu(2,0); + break; + case 1: + xModifyMenu(0,0); + xModifyMenu(1,CMIF_CHECKED); + xModifyMenu(2,0); + break; + case 2: + xModifyMenu(0,0); + xModifyMenu(1,CMIF_GRAYED); + xModifyMenu(2,CMIF_CHECKED); + break; + } + + for (j = 0 ; j < protoCount ; j++) { + if ( proto[j]->type != PROTOTYPE_PROTOCOL ) continue; + { //status mode change + int newStatus = 0; + int reqStatusInd = numStatuses-StatusToProtoIndex(reqStatus[j],allprotomodes); + bool isStatusLocked = DBGetContactSettingByte( NULL, proto[j]->szName, , "LockMainStatus", 0 ) != 0; + if (isStatusLocked) newStatus = reqStatus[j]; + else switch (curIdleStatus) { + case 1 : { //sleeping lite + if ( GetBits(awayStatusesPerm[j],maskIsShortAwayEnabled)){ + int bits = 1<<(reqStatusInd); + BOOL permit = GetBits(onlyIfBitsPerm[j], bits); + if ( permit ) { + // get the index of the status we should use + newStatus = aa_Status[GetBits(awayStatusesPerm[j],maskShortAwayStatus)-1]; + } else { +#ifdef AALOG + { + char log[1024] ; + sprintf(log,"%s: Status Change to short idle was not permitted",proto[j]->szName,0); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); + } +#endif + continue; + } + + } else continue; + break; + } + case 2 : { //sleeping deeply + if ( GetBits(awayStatusesPerm[j],maskIsLongAwayEnabled) ) { + int bits = 1<<(reqStatusInd+16); + BOOL permit = GetBits(onlyIfBitsPerm[j], bits); + if ( permit ) { + // get the index of the status we should use + newStatus = aa_Status[GetBits(awayStatusesPerm[j],maskLongAwayStatus)-1]; + } else { +#ifdef AALOG + { + char log[1024] ; + sprintf(log,"%s: Status Change to long idle was not permitted",proto[j]->szName,0); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); + } +#endif + continue; + } + } else continue; + break; + } + case 0: { //wakening up + newStatus = reqStatus[j]; +#ifdef AALOG + { + char str[256]; + sprintf(str,"%s WakeningUp: %s",proto[j]->szName,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0)); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); + } +#endif + break; + } + } // switch + if (newStatus){ + courAwayStatus[j] = newStatus; + //FatalError? and "dontReconnectOnFatalError"? and we are not just awaken +#ifdef AALOG + { + char str[1000]; + sprintf(str,"%s: Reconnect conditions before change status to %s(%d) are: FatalError did%s happen; DontReconnectOnFatalError is %sabled and we are going to %s.", + proto[j]->szName, + CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0),newStatus, + (protoStatus[j]&2)?"":"n't", + (reconnectOptsPerm[j]&aa_ReconnectNotFatalError)?"En":"Dis", + (curIdleStatus==1)?"take a short nap":((curIdleStatus==2)?"sleep":"awake")); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); + } +#endif + if ((protoStatus[j]&2)&& + (reconnectOptsPerm[j]&aa_ReconnectNotFatalError)&& + (curIdleStatus>0)) { + // do nothing :) but only the log, eventualy +#ifdef AALOG + char str[1000]; + sprintf(str,"%s: we will not change the status to %s(%d).", + proto[j]->szName, + CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0),newStatus); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + } else { +#ifdef AALOG + char str[1000]; + sprintf(str,"%s: we will change the status to %s(%d).", + proto[j]->szName, + CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0),newStatus); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + if ( CallProtoService(proto[j]->szName, PS_GETSTATUS, 0, 0) != newStatus ) { + //if (DBGetContactSettingByte( NULL, proto[j]->szName, , "LockMainStatus", 0 )) + // continue; //szName + + CallProtoService(proto[j]->szName, PS_SETSTATUS, newStatus, 0); +#ifdef AALOG + } else { + char str[256]; + sprintf(str,"%s: %s already set",proto[j]->szName,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0)); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + } + } + if (isStatusLocked) { + // do nothing - log only +#ifdef AALOG + char str[1000]; + sprintf(str,"%s: Protocol Locked to %s(%d). Not touching StatusMessage", + proto[j]->szName, + CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0),newStatus); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + } else if (messCaps[j] && !(lParam&IDF_PRIVACY)){//setting the statusMessage if protocol supports AND privacy is disabled + TCHAR * awayMsg=0; + int specificMsg = messCaps[j] & Proto_Status2Flag(newStatus); + + switch (curIdleStatus) { + case 0 : specificMsg = (specificMsg > 0) && (GetBits(idleMessOpts[j],IdleMessOptsMaskUseHere)>0); break; + case 1 : specificMsg = (specificMsg > 0) && (GetBits(idleMessOpts[j],IdleMessOptsMaskUseShort)>0); break; + case 2 : specificMsg = (specificMsg > 0) && (GetBits(idleMessOpts[j],IdleMessOptsMaskUseLong)>0); break; + } + if (/*!starting &&*/ specificMsg){ + awayMsg = (TCHAR *)mir_alloc((maxMessageLength+1)*sizeof(TCHAR)); + //TCHAR temp[maxMessageLength+1]; + switch (curIdleStatus) { + case 0 : ParseString(mesgHerePerm[j],awayMsg,maxMessageLength); break; + case 1 : ParseString(mesgShortPerm[j],awayMsg,maxMessageLength); break; + case 2 : ParseString(mesgLongPerm[j],awayMsg,maxMessageLength); break; + default: awayMsg[0]=0; + } + //my_u2a(temp, awayMsg, maxMessageLength); + } else { +#ifdef UNICODE + if (HasAwayMessageW){ + awayMsg = (TCHAR *) CallService(MS_AWAYMSG_GETSTATUSMSGW, (WPARAM) newStatus, 0); + } else { + char *temp=(char *)CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) newStatus, 0); + if ((int)temp == CALLSERVICE_NOTFOUND) awayMsg = 0; + else{ + awayMsg = (TCHAR *)mir_alloc((maxMessageLength+1)*sizeof(TCHAR)); + my_a2u(temp,awayMsg,maxMessageLength); + mir_free(temp); + } + } +#else + char *temp=(char *)CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) newStatus, 0); + awayMsg=(char *)CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) newStatus, 0); + if ((int)temp == CALLSERVICE_NOTFOUND) awayMsg = 0; +#endif + } +#ifdef AALOG + { + char str[1000]; + sprintf(str,"%s: Specific Status Message is %s",proto[j]->szName, + specificMsg?"Enabled":"Disabled"); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); + sprintf(str,"%s: Going to %s (%d); StatusMessage is: %s", proto[j]->szName,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0),newStatus, + awayMsg ? awayMsg : "none or private"); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); + } +#endif +#ifdef UNICODE + if (protoHasAwayMessageW[j]) CallProtoService(proto[j]->szName, PS_SETAWAYMSGW, newStatus, (LPARAM) awayMsg); + else { + char temp[maxMessageLength+1]; + my_u2a(awayMsg,temp,maxMessageLength); + CallProtoService(proto[j]->szName, PS_SETAWAYMSG, newStatus, (LPARAM) temp); + } +#else + CallProtoService(proto[j]->szName, PS_SETAWAYMSG, newStatus, (LPARAM) awayMsg); +#endif + if (awayMsg) { +#ifdef AALOG + {char str[1000]; + sprintf(str,"%s: Cleaning after MS_AWAYMSG_GETSTATUSMSG: %s",proto[j]->szName,awayMsg); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);} +#endif + mir_free(awayMsg); + } + if ((curIdleStatus==0) && (GetBits(idleMessOpts[j],IdleMessOptsMaskRstHere)>0) && /*!starting &&*/ specificMsg){ +#ifdef AALOG + char str[1000]; + sprintf(str,"%s: Scheduling \"ResetDefaultStatusMessage\" after %d seconds",proto[j]->szName,GetBits(idleMessOpts[j],IdleMessOptsMaskRstHereDelay)); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + isWaitingForRestoreStatusMessage[j] = GetBits(idleMessOpts[j],IdleMessOptsMaskRstHereDelay)/2+1; + } + } + }//if + } //StatusChange Was done + } //for + if (starting) { +#ifdef AALOG + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"Clearing the \"starting\" flag..."); +#endif + starting = 0; + } + return 0; +} + + + +extern int StatusModeChangeEvent(WPARAM wParam,LPARAM lParam) +{ + int j=0; + char str[256]; + +#ifdef AALOG + { + char log[1024]; + sprintf(log,"Status Mode change event: %s: %s\n\n",lParam,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, wParam, 0)); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); + } +#endif + if (lParam){ + for (j = 0 ; j < protoCount ; j++) { + if ( proto[j]->type != PROTOTYPE_PROTOCOL ) continue; + if (strcmp((char *)lParam,proto[j]->szName)==0) { + sprintf(str,AA_LASTREQUESTEDSTATUS,proto[j]->szName); + reqStatus[j] = wParam; + DBWriteContactSettingWord(NULL,AA_MODULE,str,(WORD)reqStatus[j]); + } + } + } else { + if (idleOptsPerm&KeepMainStatusOffline) { +#ifdef AALOG + { + char log[1024]; + sprintf(log,"Global Status Mode change event: %s. Keep it offline!",CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, wParam, 0)); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); + } +#endif + DBWriteContactSettingWord(NULL,"CList","Status",(WORD)ID_STATUS_OFFLINE); + } + if (starting && (wParam == ID_STATUS_OFFLINE)){ +#ifdef AALOG + { + char log[1024]; + sprintf(log,"Do not set last request status to %s. We are still starting.",CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, wParam, 0)); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); + } +#endif + } else for (j = 0 ; j < protoCount ; j++) { + if ( proto[j]->type != PROTOTYPE_PROTOCOL ) continue; + sprintf(str,AA_LASTREQUESTEDSTATUS,proto[j]->szName); + reqStatus[j] = wParam; + DBWriteContactSettingWord(NULL,AA_MODULE,str,(WORD)reqStatus[j]); + } + } +#ifdef AALOG + { + char log[1024] = {0}; + for (j = 0 ; j < protoCount ; j++) { + sprintf(log,"%s%d:%s: %s\n",log,j,proto[j]->szName,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, reqStatus[j], 0)); + } + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"Status Mode change event: done"); + } +#endif + if (idleOptsPerm&IdleHereOnStatusChange){ + if (curIdleStatus){ + if (wParam!=ID_STATUS_OFFLINE){ +#ifdef AALOG + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"New requested status. Forcing ""Not Idle""."); +#endif + SimulateIdle(0); + } + } + } + +// CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"Keeping Last Requested statuses"); + if (theDialog) SetDlgItems(theDialog, courProtocolSelection); + if (theDialogIdleMessages) SetDlgItemsIdleMessages(theDialogIdleMessages, courProtocolSelection); + return 0; +} + + + +int ProtoAckEvent(WPARAM wParam,LPARAM lParam) +{ +#ifdef AALOG + char log[2048]; +#endif + char str[1024]; + int j = 0; + ACKDATA * ack = (ACKDATA*) lParam; + for (j = 0 ; j < protoCount ; j++) if (proto[j]->type==PROTOTYPE_PROTOCOL) if (strcmp(ack->szModule,proto[j]->szName)==0){ + if (ack->type==ACKTYPE_STATUS) { +// MessageBox( 0,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->lParam, 0),proto[j]->szName,0); + if (!(ack->hContact)) ProtocolsProc(j,ack); + if (ack->result==ACKRESULT_SUCCESS){ + courStatus[j] = ack->lParam; + if (theDialog){ + int coursel = SendDlgItemMessage(theDialog, IDC_AAPROTOCOL, CB_GETCURSEL, 0, 0); + SendDlgItemMessageA(theDialog,IDC_AAPROTOCOL,CB_GETLBTEXT,coursel,(LPARAM)str); + if (strcmp(ack->szModule,str)==0){ + SetDlgItems(theDialog,GetCourSelProtocol(coursel)); +// SendDlgItemMessage(theDialog, IDC_COURSTATUSLABEL, WM_SETTEXT, 0, +// (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courStatus[j], 0)); + } + } + } + } else if (ack->type==ACKTYPE_LOGIN) { + if (!ack->hContact) LoginAck(j,ack); + } + } + +#ifdef AALOG +// if (theDialog) SendDlgItemMessage(theDialog, 40201, WM_SETTEXT, 0,(LPARAM)ack->szModule); + sprintf(log,"ProtoAck: szModule: %s;",ack->szModule); + sprintf(str,"%s",ack->hContact?(char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)ack->hContact,0):"null"); + sprintf(log,"%s hContact: %s;",log,str); +// if (theDialog) SendDlgItemMessage(theDialog, 40202, WM_SETTEXT, 0,(LPARAM)str); + sprintf(str,"%d",ack->type); + sprintf(log,"%stype: %s;",log,str); +// if (theDialog) SendDlgItemMessage(theDialog, 40203, WM_SETTEXT, 0,str); + sprintf(str,"%d",ack->result); + sprintf(log,"%s result: %s;",log,str); +// if (theDialog) SendDlgItemMessage(theDialog, 40204, WM_SETTEXT, 0,str); + sprintf(str,"%d(%s)",ack->hProcess, + CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->hProcess, 0)); + sprintf(log,"%s hProcess: %s;",log,str); +// if (theDialog) SendDlgItemMessage(theDialog, 40205, WM_SETTEXT, 0,str); + sprintf(str,"%d(%s)",ack->lParam, + CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->lParam, 0)); + sprintf(log,"%s lParam: %s;",log,str); +// if (theDialog) SendDlgItemMessage(theDialog, 40206, WM_SETTEXT, 0,str); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); +#endif + return 0; +} + + +int SimulateIdle(int idlstatus) +{ +// MessageBox(theDialog,"ButtonPressed","Button",0); + int flags = IDF_ISIDLE; + switch (idlstatus) + { + case 0: {flags = 0;/*MessageBox(theDialog,"BeHere","Button Pressed",0);*/ break;} + case 1: {flags |= IDF_SHORT; /*MessageBox(theDialog,"BeAway","Button Pressed",0);*/ break;} + case 2: {flags |= IDF_LONG; /*MessageBox(theDialog,"BeNA","Button Pressed",0);*/ break;} + } + if (idleOptsPerm&IdleBitsPrivate) flags |= IDF_PRIVACY; + isCurrentlyIdle = idlstatus; + NotifyEventHooks( hIdleEvent, 0, flags ); + return 0; +} + +LRESULT SetDlgItemsAA(HWND hwndDlg, int coursel){ + int status = awayStatuses[coursel]; + long onlyif = onlyIfBits[coursel]; + BOOL enabledShort = (status & maskIsShortAwayEnabled)>0; + BOOL enabledLong = (status & maskIsLongAwayEnabled)>0; + int i =0; + EnableWindow(GetDlgItem(hwndDlg, IDC_AASTATUS), enabledShort); + EnableWindow(GetDlgItem(hwndDlg, IDC_AALONGSTATUS), enabledLong); + CheckDlgButton(hwndDlg, IDC_AASHORTIDLE, enabledShort?BST_CHECKED:BST_UNCHECKED ); + CheckDlgButton(hwndDlg, IDC_AALONGIDLE, enabledLong?BST_CHECKED:BST_UNCHECKED ); + + SendDlgItemMessage(hwndDlg, IDC_AASTATUS, CB_RESETCONTENT, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_AALONGSTATUS, CB_RESETCONTENT, 0, 0); + for (i=0;i0; + BOOL bitl = IsStatusBitSet(aa_Status[i],onlyif>>16)>0; + BOOL bita = IsStatusBitSet(aa_Status[i],protoModes[coursel])==0; + EnableWindow(GetDlgItem(hwndDlg, aa_Status[i]), enabledShort); + StrikeOut(hwndDlg,aa_Status[i],bita); + CheckDlgButton(hwndDlg, aa_Status[i], bits?BST_CHECKED:BST_UNCHECKED ); + EnableWindow(GetDlgItem(hwndDlg, aa_Status[i]+0x10), enabledLong); + StrikeOut(hwndDlg,aa_Status[i]+0x10,bita); + CheckDlgButton(hwndDlg, aa_Status[i]+0x10, bitl?BST_CHECKED:BST_UNCHECKED ); +// ShowWindow(GetDlgItem(hwndDlg, aa_Status[i]), bita); +// ShowWindow(GetDlgItem(hwndDlg, aa_Status[i]+0x10), bita); + } + } + { + int s = status & 0x000F; + int l = status & 0x00F0; + l = l>>4; + s = StatusToProtoIndex(aa_Status[s-1],protoModes[coursel]); + l = StatusToProtoIndex(aa_Status[l-1],protoModes[coursel]); + SendDlgItemMessage(hwndDlg, IDC_AASTATUS, CB_SETCURSEL, s-1, 0); + SendDlgItemMessage(hwndDlg, IDC_AALONGSTATUS, CB_SETCURSEL, l-1, 0); + } + return TRUE; +} + +BOOL CALLBACK DlgProcOptsAA(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + SetDlgItemsAA(hwndDlg, courProtocolSelection); + return TRUE; + case WM_USER+1: + { + awayStatuses[courProtocolSelection] = (short)SetBits(awayStatuses[courProtocolSelection],maskIsShortAwayEnabled,IsDlgButtonChecked(hwndDlg, IDC_AASHORTIDLE)==BST_CHECKED); + awayStatuses[courProtocolSelection] = (short)SetBits(awayStatuses[courProtocolSelection],maskIsLongAwayEnabled,IsDlgButtonChecked(hwndDlg, IDC_AALONGIDLE)==BST_CHECKED); + SetDlgItemsAA(hwndDlg, courProtocolSelection); + break; + } + case WM_USER+2: + { + int t = HIWORD(lParam)?16:0; + int thebit = numStatuses-StatusToProtoIndex(LOWORD(lParam),allprotomodes); + int value = IsDlgButtonChecked(hwndDlg, LOWORD(lParam)+t)==BST_CHECKED; + thebit = 1<<(thebit+t); + onlyIfBits[courProtocolSelection] = + SetBits(onlyIfBits[courProtocolSelection], + thebit, + value); + break; + } + case WM_USER+3: + { + int awStInd = SendDlgItemMessage(hwndDlg, lParam, CB_GETCURSEL, 0, 0); + awStInd = StatusByProtoIndex(protoModes[courProtocolSelection],awStInd+1); + awStInd = StatusToProtoIndex(awStInd,allprotomodes); + if (lParam == IDC_AASTATUS) { + awayStatuses[courProtocolSelection] = (short)SetBits(awayStatuses[courProtocolSelection],maskShortAwayStatus,awStInd); + } else if (lParam == IDC_AALONGSTATUS) { + awayStatuses[courProtocolSelection] = (short)SetBits(awayStatuses[courProtocolSelection],maskLongAwayStatus,awStInd); + } +#ifdef _DEBUG + else MessageBoxA(hwndDlg,"Came From Long Place","WM_USER+3",0) +#endif //_DEBUG + ; + SetDlgItemsIdleMessages(theDialogIdleMessages, courProtocolSelection); + break; + } + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_AASHORTIDLE: + case IDC_AALONGIDLE: + { + SendMessage(hwndDlg, WM_USER+1,0,0); + break; + } + case ID_STATUS_AWAY: + case ID_STATUS_DND: + case ID_STATUS_NA: + case ID_STATUS_OCCUPIED: + case ID_STATUS_INVISIBLE: + case ID_STATUS_ONTHEPHONE: + case ID_STATUS_OUTTOLUNCH: + case ID_STATUS_ONLINE: + case ID_STATUS_FREECHAT: + case ID_STATUS_OFFLINE: + { + SendMessage(hwndDlg, WM_USER+2,0,wParam); + break; + } + case ID_STATUS_AWAY+16: + case ID_STATUS_DND+16: + case ID_STATUS_NA+16: + case ID_STATUS_OCCUPIED+16: + case ID_STATUS_INVISIBLE+16: + case ID_STATUS_ONTHEPHONE+16: + case ID_STATUS_OUTTOLUNCH+16: + case ID_STATUS_ONLINE+16: + case ID_STATUS_FREECHAT+16: + case ID_STATUS_OFFLINE+16: + { + SendMessage(hwndDlg, WM_USER+2,0,(wParam-16)|0x00010000); + break; + } + case IDC_AASTATUS: + case IDC_AALONGSTATUS: + { + if ( HIWORD(wParam) != CBN_SELCHANGE ) return TRUE; + SendMessage(hwndDlg, WM_USER+3,0,LOWORD(wParam)); + break; + } //case + } + if ((HIWORD(wParam)==BN_CLICKED)||(HIWORD(wParam)==CBN_SELCHANGE)) + { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + break; + case WM_NOTIFY: + switch (((LPNMHDR) lParam)->idFrom) { + case 0: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: { + return TRUE; + } + } + break; + } + break; + case WM_DESTROY: + break; + } + return FALSE; +} + + + diff --git a/plugins/!NotAdopted/SmartAutoAway/dlgproc.cpp b/plugins/!NotAdopted/SmartAutoAway/dlgproc.cpp new file mode 100644 index 0000000000..e37ce72ce9 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/dlgproc.cpp @@ -0,0 +1,281 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2006 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "globals.h" + +BOOL CALLBACK DlgProcAutoAwayOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ +// char str[MAXMODULELABELLENGTH]; + static short int tabprotosel; + switch (msg) + { + case WM_INITDIALOG: + { + short int t,p,protoListed; + TCITEM tci; + RECT theTabSpace; + RECT rcClient; + { + RECT rcTab, rcDlg; + TabCtrl_GetItemRect(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB),0,&rcTab); + theTabSpace.top = rcTab.bottom; // the size of the tab + GetWindowRect(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB), &rcTab); + GetWindowRect(hwndDlg, &rcDlg); + theTabSpace.bottom = rcTab.bottom -rcTab.top -theTabSpace.top; + theTabSpace.top = rcTab.top -rcDlg.top +theTabSpace.top; + theTabSpace.left = rcTab.left - rcDlg.left; + theTabSpace.right = rcTab.right-rcTab.left; + } + theDialog = hwndDlg; + TranslateDialogDefault(hwndDlg); + protoListed = 0; + for (p = 0 ; p < protoCount ;p++) { + int caps=0; + if ( !isInterestingProto(p) ) continue; + caps = CallProtoService(proto[p]->szName, PS_GETCAPS, PFLAGNUM_2, 0); + PROTOACCOUNT* protoAccount=ProtoGetAccount(proto[p]->szName); + if ((int)protoAccount!=CALLSERVICE_NOTFOUND){ + SendDlgItemMessage(hwndDlg, IDC_AAPROTOCOL, CB_ADDSTRING, 0, (LPARAM)protoAccount->tszAccountName ); + } else SendDlgItemMessageA(hwndDlg, IDC_AAPROTOCOL, CB_ADDSTRING, 0, (LPARAM)proto[p]->szName ); + protoListed++; + } + tabprotosel = DBGetContactSettingWord(NULL, AA_MODULE, AA_PROTOSELECTION, 0); + t = (tabprotosel&0x0F00) >> 8; if (t>3) t=3; + p = (tabprotosel&0x00FF); + if ((p>=protoListed)) p= protoListed-1; + SendDlgItemMessage(hwndDlg, IDC_AAPROTOCOL, CB_SETCURSEL, p, 0); + SetDlgItems(hwndDlg, courProtocolSelection = GetCourSelProtocol(p)); + + tci.mask = TCIF_PARAM|TCIF_TEXT; + +#ifdef SAA_PLUGIN + theDialogAA = CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_SAA_AA), hwndDlg, DlgProcOptsAA); +#else + theDialogAA = CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_OPT_SAA_AA), hwndDlg, DlgProcOptsAA); +#endif + tci.lParam = (LPARAM)theDialogAA; + tci.pszText = TranslateT("Statuses"); + GetClientRect(theDialogAA,&rcClient); + SendMessage(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB), TCM_INSERTITEM, (WPARAM)0, (LPARAM)&tci); + MoveWindow((HWND)theDialogAA,theTabSpace.left+(theTabSpace.right-rcClient.right)/2, + theTabSpace.top+(theTabSpace.bottom-rcClient.bottom)/2, + rcClient.right,rcClient.bottom,1); + ShowWindow((HWND)tci.lParam, (t==0)?SW_SHOW:SW_HIDE); + + +#ifdef SAA_PLUGIN + theDialogIdle = CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_SAA_IDLE), hwndDlg, DlgProcOptsIdle); +#else + theDialogIdle = CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_OPT_SAA_IDLE), hwndDlg, DlgProcOptsIdle); +#endif + tci.lParam = (LPARAM)theDialogIdle; + tci.pszText = TranslateT("Idle"); + GetClientRect(theDialogIdle,&rcClient); + SendMessage(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB), TCM_INSERTITEM, (WPARAM)1, (LPARAM)&tci); + MoveWindow((HWND)theDialogIdle,theTabSpace.left+(theTabSpace.right-rcClient.right)/2, + theTabSpace.top+(theTabSpace.bottom-rcClient.bottom)/2, + rcClient.right,rcClient.bottom,1); + ShowWindow((HWND)tci.lParam, (t==1)?SW_SHOW:SW_HIDE); + +#ifdef SAA_PLUGIN + theDialogIdleMessages = CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_SAA_IDLEMESSAGES), hwndDlg, DlgProcOptsIdleMessages); +#else + theDialogIdleMessages = CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_OPT_SAA_IDLEMESSAGES), hwndDlg, DlgProcOptsIdleMessages); +#endif + tci.lParam = (LPARAM)theDialogIdleMessages; + tci.pszText = TranslateT("Status Messages"); + GetClientRect(theDialogIdleMessages,&rcClient); + SendMessage(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB), TCM_INSERTITEM, (WPARAM)2, (LPARAM)&tci); + MoveWindow((HWND)theDialogIdleMessages,theTabSpace.left+(theTabSpace.right-rcClient.right)/2, + theTabSpace.top+(theTabSpace.bottom-rcClient.bottom)/2, + rcClient.right,rcClient.bottom,1); + ShowWindow((HWND)tci.lParam, (t==2)?SW_SHOW:SW_HIDE); + +#ifdef SAA_PLUGIN + theDialogReconnect = CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_SAA_RECONNECT), hwndDlg, DlgProcOptsReconnect); +#else + theDialogReconnect = CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_OPT_SAA_RECONNECT), hwndDlg, DlgProcOptsReconnect); +#endif + tci.lParam = (LPARAM)theDialogReconnect; + tci.pszText = TranslateT("Reconnect"); + GetClientRect(theDialogReconnect,&rcClient); + SendMessage(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB), TCM_INSERTITEM, (WPARAM)3, (LPARAM)&tci); + MoveWindow((HWND)theDialogReconnect,theTabSpace.left+(theTabSpace.right-rcClient.right)/2, + theTabSpace.top+(theTabSpace.bottom-rcClient.bottom)/2, + rcClient.right,rcClient.bottom,1); + ShowWindow((HWND)tci.lParam, (t==3)?SW_SHOW:SW_HIDE); + TabCtrl_SetCurSel(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB),t); + + if(enableThemeDialogTexture) { + enableThemeDialogTexture(theDialogAA, ETDT_ENABLETAB); + enableThemeDialogTexture(theDialogIdle, ETDT_ENABLETAB); + enableThemeDialogTexture(theDialogIdleMessages, ETDT_ENABLETAB); + enableThemeDialogTexture(theDialogReconnect, ETDT_ENABLETAB); + } + return TRUE; + } + + case WM_COMMAND: + { + switch (LOWORD(wParam)) { + case IDC_AAPROTOCOL: + { + int cour = SendDlgItemMessage(hwndDlg, IDC_AAPROTOCOL, CB_GETCURSEL, 0, 0); + courProtocolSelection = GetCourSelProtocol(cour); + if ( HIWORD(wParam) != CBN_SELCHANGE ) return TRUE; + DBWriteContactSettingWord(NULL, AA_MODULE, AA_PROTOSELECTION, + (unsigned short)(tabprotosel=courProtocolSelection|(tabprotosel&0xFF00))); + SetDlgItems(hwndDlg, courProtocolSelection); + SetDlgItemsReconnect(theDialogReconnect,courProtocolSelection); + SetDlgItemsAA(theDialogAA,courProtocolSelection); + SetDlgItemsIdleMessages(theDialogIdleMessages,courProtocolSelection); + break; + } + case IDC_APPLYTOALL: + { + int i; + for (i=0;iidFrom) { + case 0: { + BOOL CommandApply; + if ( (CommandApply = lParam && ((LPNMHDR)lParam)->code == PSN_APPLY) || (lParam && ((LPNMHDR)lParam)->code == PSN_RESET) ) { + int j=0; +#ifdef _DEBUG + //MessageBox(hwndDlg,CommandApply?"Apply":"Cancel","EventHapened",0); +#endif + for (j = 0 ; j < protoCount ; j++) { + if ( isInterestingProto(j) ) { + char str[256]; + if (CommandApply) { + onlyIfBitsPerm[j] = onlyIfBits[j]; + awayStatusesPerm[j] = awayStatuses[j]; + reconnectOptsPerm[j] = reconnectOpts[j]; + sprintf(str,AA_BITSONLYIF,proto[j]->szName); + DBWriteContactSettingDword(NULL,AA_MODULE,str,onlyIfBitsPerm[j]); + sprintf(str,AA_AWAYSTATUSES,proto[j]->szName); + DBWriteContactSettingWord(NULL,AA_MODULE,str,awayStatusesPerm[j]); + sprintf(str,AA_RECONNECTOPTS,proto[j]->szName); + DBWriteContactSettingDword(NULL,AA_MODULE,str,reconnectOptsPerm[j]); + if (messCaps[j]) { + idleMessOptsPerm[j] = idleMessOpts[j]; + sprintf(str,idleMsgOptionsName,proto[j]->szName); + DBWriteContactSettingDword(NULL,AA_MODULE,str,idleMessOptsPerm[j]); + + sprintf(str,idleMsgOptionsTextHere,proto[j]->szName); + _tcscpy(mesgHerePerm[j],mesgHere[j]); + DBWriteContactSettingTString(NULL,AA_MODULE,str,mesgHerePerm[j]); + + sprintf(str,idleMsgOptionsTextShort,proto[j]->szName); + _tcscpy(mesgShortPerm[j],mesgShort[j]); + DBWriteContactSettingTString(NULL,AA_MODULE,str,mesgShortPerm[j]); + + sprintf(str,idleMsgOptionsTextLong,proto[j]->szName); + _tcscpy(mesgLongPerm[j],mesgLong[j]); + DBWriteContactSettingTString(NULL,AA_MODULE,str,mesgLongPerm[j]); + } + } else { + onlyIfBits[j] = onlyIfBitsPerm[j]; + awayStatuses[j] = awayStatusesPerm[j]; + reconnectOpts[j] = reconnectOptsPerm[j]; + idleMessOpts[j] = idleMessOptsPerm[j]; + if (messCaps[j]) { + _tcscpy(mesgHere[j],mesgHerePerm[j]); + _tcscpy(mesgShort[j],mesgShortPerm[j]); + _tcscpy(mesgLong[j],mesgLongPerm[j]); + } + } + } + } + if (CommandApply) { + idleOptsPerm = idleOpts; + DBWriteContactSettingDword(NULL,AA_MODULE,AA_IDLEOPTIONS,idleOptsPerm); + } else { + idleOpts = idleOptsPerm; + } + } //if PSN_APPLY + break; + case IDC_OPT_SAA_TAB: + switch (((LPNMHDR)lParam)->code) + { + case TCN_SELCHANGING: + { + TCITEM tci; + tci.mask = TCIF_PARAM; + TabCtrl_GetItem(GetDlgItem(hwndDlg,IDC_OPT_SAA_TAB),TabCtrl_GetCurSel(GetDlgItem(hwndDlg,IDC_OPT_SAA_TAB)),&tci); + ShowWindow((HWND)tci.lParam,SW_HIDE); + } + break; + case TCN_SELCHANGE: + { + TCITEM tci; + short int t; + tci.mask = TCIF_PARAM; + t = TabCtrl_GetCurSel(GetDlgItem(hwndDlg,IDC_OPT_SAA_TAB)); + TabCtrl_GetItem(GetDlgItem(hwndDlg,IDC_OPT_SAA_TAB),t,&tci); + DBWriteContactSettingWord(NULL, AA_MODULE, AA_PROTOSELECTION, + (unsigned short)(tabprotosel=(t<<8)|(tabprotosel&0xF0FF))); + ShowWindow((HWND)tci.lParam,SW_SHOW); + { BOOL enableW = (tci.lParam!=(long)theDialogIdle); + EnableWindow(GetDlgItem(hwndDlg,IDC_AAPROTOCOL),enableW); + EnableWindow(GetDlgItem(hwndDlg,IDC_APPLYTOALL),enableW); + } + } + break; + } + break; + } + }//end case(LPNMHDR)lParam)->idFrom + + } +//WTF??? if(wParam!=0x12345678) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + return FALSE; +} + + + diff --git a/plugins/!NotAdopted/SmartAutoAway/globals.cpp b/plugins/!NotAdopted/SmartAutoAway/globals.cpp new file mode 100644 index 0000000000..82f2087b3d --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/globals.cpp @@ -0,0 +1,113 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2006 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "globals.h" + +HANDLE hIdleEvent = NULL; +HANDLE hNetlib; +UINT hIdleTimer = 0; + +BOOL starting=1; // this flag will be cleared later + +#ifdef UNICODE +bool *protoHasAwayMessageW=0; +bool HasAwayMessageW=0; +#endif + +int *isWaitingForRestoreStatusMessage=0; + + int *reqStatus=0; + int *courStatus=0; + int *courAwayStatus=0; + + int *protoModes=0; + + short int *awayStatusesPerm=0; + long *onlyIfBitsPerm=0; + short int *awayStatuses=0; + long *onlyIfBits=0; + + int aa_Status[] = { + ID_STATUS_OFFLINE, + ID_STATUS_ONLINE, + ID_STATUS_AWAY, + ID_STATUS_NA, + ID_STATUS_OCCUPIED, + ID_STATUS_DND, + ID_STATUS_FREECHAT, + ID_STATUS_INVISIBLE, + ID_STATUS_ONTHEPHONE, + ID_STATUS_OUTTOLUNCH +}; + + int numStatuses = sizeof(aa_Status)/sizeof(aa_Status[0]); + +HWND theDialog = 0; +HWND theDialogReconnect=0; +HWND theDialogIdle=0; +HWND theDialogIdleMessages=0; +HWND theDialogAA=0; + + +PROTOCOLDESCRIPTOR **proto=0; +int protoCount=0; +int courProtocolSelection = 0; + +int localeID=0; +int codePage=0; + + +TCHAR *VariableList[][2]={ + {NULL,LPGENT("Date")}, + {_T("Y"),LPGENT("year (4 digits)")}, + {_T("y"),LPGENT("year (2 digits)")}, + {_T("m"),LPGENT("month")}, + {_T("E"),LPGENT("name of month")}, + {_T("e"),LPGENT("short name of month")}, + {_T("d"),LPGENT("day")}, + {_T("W"),LPGENT("weekday (full)")}, + {_T("w"),LPGENT("weekday (abbreviated)")}, + {_T("L"),LPGENT("Localized Date (Long)")}, + {_T("l"),LPGENT("Localized Date (Short)")}, + {NULL,LPGENT("Time")}, + {_T("H"),LPGENT("hours (24)")}, + {_T("h"),LPGENT("hours (12)")}, + {_T("p"),LPGENT("AM/PM")}, + {_T("M"),LPGENT("minutes")}, + {_T("S"),LPGENT("seconds")}, + {_T("K"),LPGENT("Localized Time (Long)")}, + {_T("k"),LPGENT("Localized Time (no Seconds)")}, + {NULL,LPGENT("Time Zone")}, + {_T("z"),LPGENT("total bias")}, + {_T("Z"),LPGENT("time zone name")}, + {NULL,LPGENT("Format")}, + {_T("t"),LPGENT("tabulator")}, + {_T("b"),LPGENT("line break")}, +}; + +HOTKEYDESC hotkeydescs[] = { + {sizeof(HOTKEYDESC), "saa_benotidle", "Not Idle", SECTIONNAME, AA_IDLE_BENOTIDLESERVICE, 0, 0}, + {sizeof(HOTKEYDESC), "saa_beshortidle", "Short Idle", SECTIONNAME, AA_IDLE_BESHORTIDLESERVICE, 0, 0}, + {sizeof(HOTKEYDESC), "saa_belongidle", "Long Idle", SECTIONNAME, AA_IDLE_BELONGIDLESERVICE, 0, 0}, + {sizeof(HOTKEYDESC), "saa_reconnect", "Reconnect", SECTIONNAME, AA_IDLE_RECONNECTSERVICE, 0, 0}, + }; + diff --git a/plugins/!NotAdopted/SmartAutoAway/globals.h b/plugins/!NotAdopted/SmartAutoAway/globals.h new file mode 100644 index 0000000000..788076a0c2 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/globals.h @@ -0,0 +1,349 @@ +#ifdef UNICODE + #ifndef _UNICODE + #define _UNICODE + #endif +#endif + +//#ifdef VCL_VC60 +#include "AggressiveOptimize.h" +//#endif + +//#include + +#ifdef _DEBUG +#ifndef UNICODE + #define AALOG + #define AALOG1 +#endif +#endif + +#define _WIN32_WINNT 0x0700 +#ifndef SAA_PLUGIN + #include "../../src/core/commonheaders.h" +#else + #include + #include + #include + #include + #include + #include "newpluginapi.h" + #include + #include + #include + #include + #include + #include + #include + #include "m_idle.h" + #ifndef time + #include + #endif + #define offsetof(s,m) (size_t)&(((s *)0)->m) + extern BOOL (WINAPI *enableThemeDialogTexture)(HANDLE, DWORD); +#ifdef AALOG + #include +#endif +#endif +#include + + +//#ifdef SAA_PLUGIN +// extern struct MM_INTERFACE memoryManagerInterface; +// #define mir_alloc(n) memoryManagerInterface.mmi_malloc(n) +// #define mir_free(ptr) memoryManagerInterface.mmi_free(ptr) +// #define mir_realloc(ptr,size) memoryManagerInterface.mmi_realloc(ptr,size) +//#endif + +#define SECTIONNAME "Smart Auto Away" + + #include "resource.h" +//#define IDF_ISIDLE 0x1 // idle has become active (if not set, inactive) +#define IDF_SHORT 0x2 // short idle mode +#define IDF_LONG 0x4 // long idle mode +//#define IDF_PRIVACY 0x8 // if set, the information provided shouldn't be given to third parties. +#define IDF_ONFORCE 0x10 // screensaver/onstationlocked,etc cause instant idle + +extern int FirstTick; + +#ifdef UNICODE +extern bool *protoHasAwayMessageW; +extern bool HasAwayMessageW; +#endif + +extern HOTKEYDESC hotkeydescs[]; + +//typedef struct { +// int cbSize; // sizeof() +// unsigned int idleTime; // idle in mins, if zero then disabled +// int privacy; // user doesnt want other people seeing anything more than they are idle +// int aaStatus; // status to go to when user is auto away +//} MIRANDA_IDLE_INFO; +//typedef struct { +// int cbSize; // sizeof() +// int enabled; // monitoring is going on +// int idleShortTime; // short idle in mins, if zero then disabled +// int idleLongTime; // long idle in mins, if zero then disabled +// int privacy; // user doesnt want other people seeing anything more than they are idle +//} MIRANDA_IDLE_INFO; + +//typedef struct{ +// int cbSize; //sizeof //5*sizeof(int) or 4*sizeof(int) +// unsigned int fieldTime; //enabled or idleTime in minutes +// int field1; //idleShortTime or privacy +// int field2; //idleLongTime or aaStatus +// // the "new structure ends here" +// int field3; //privacy or none +//} MYIDLEINFO; +//#define MS_IDLE_GETIDLEINFO "Miranda/Idle/GetInfo" +//#define ME_IDLE_CHANGED "Miranda/Idle/Changed" +extern int isCurrentlyIdle; + +extern unsigned long idleOptsPerm; // CMHG SL S SM P L S --LONG-- --SHORT- +extern unsigned long idleOpts; // C G L S tM P L S --LONG-- --SHORT- +#define idleOptsDefault 0x95851E0A // 1001 0101 1000 0101 00011110 00001010 +#define IdleBitsTimeFirst 0x000000FF // ---- ---- ---- ---- -------- 11111111 +#define IdleBitsTimeSecond 0x0000FF00 // ---- ---- ---- ---- 11111111 -------- +#define IdleBitsCheck 0x80000000 // 1000 0000 0000 0000 00000000 00000000 +#define IdleBitsMethod 0x00400000 // 0000 0000 0100 0000 00000000 00000000 +#define IdleBitsFirstOn 0x00010000 // 0000 0000 0000 0001 00000000 00000000 +#define IdleBitsSecondOn 0x00040000 // 0000 0000 0000 0100 00000000 00000000 +#define IdleBitsOnSaver 0x01000000 // 0000 0001 0000 0000 00000000 00000000 +#define IdleBitsOnLock 0x04000000 // 0000 0100 0000 0000 00000000 00000000 +#define IdleBitsGLI 0x10000000 // 0001 0000 0000 0000 00000000 00000000 +#define IdleBitsPrivate 0x00100000 // 0000 0000 0001 0000 00000000 00000000 +#define IdleSuppressIdleMenu 0x40000000 // 0100 0000 0000 0000 00000000 00000000 +#define IdleSuppressAutoHere 0x20000000 // 0010 0000 0000 0000 00000000 00000000 +#define KeepMainStatusOffline 0x08000000 // 0000 1000 0000 0000 00000000 00000000 +#define IdleHereOnStatusChange 0x00800000// 0000 0000 1000 0000 00000000 00000000 + + + + +#ifdef SAA_PLUGIN + int __cdecl LoadAutoAwayModule(void); + extern HINSTANCE g_hInst; +#endif + + +#define MS_SYSTEM_GETIDLE "Miranda/GetIdle" +#ifdef AALOG + extern HANDLE hNetlib; +#endif +static int InitVariables( WPARAM wParam, LPARAM lParam ); + +extern HANDLE hIdleEvent; +extern UINT hIdleTimer; + +extern BOOL CALLBACK DlgProcAutoAwayOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +extern BOOL CALLBACK DlgProcOptsIdle(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + + +int AutoAwayOptInitialise(WPARAM wParam,LPARAM lParam); +//extern int AutoAwayShutdown(WPARAM wParam,LPARAM lParam); + +#define IDLEMODULE "Idle" +// live settings +//extern int idleCheckPerm; +//extern int idleMethodPerm; +//extern int idleTimeFirstPerm; // this is in mins +//extern int idleTimeSecondPerm; // +//extern int idleTimeFirstOnPerm; +//extern int idleTimeSecondOnPerm; +//extern int idleOnSaverPerm; +//extern int idleOnLockPerm; +//extern int idleGLIPerm; +//extern int idlePrivatePerm; + +//We will not try to import previous Idle settings anymore +// db settings keys +//#define IDL_IDLECHECK "IdleCheck" +//#define IDL_IDLEMETHOD "IdleMethod" +//#define IDL_IDLEGLI "IdleGLI" +//#define IDL_IDLETIME1ST "IdleTime1st" +//#define IDL_IDLETIME2ND "IdleTime2nd" +//#define IDL_IDLEONSAVER "IdleOnSaver" +//#define IDL_IDLEONLOCK "IdleOnLock" +//#define IDL_IDLETIME1STON "IdleTime1stOn" +//#define IDL_IDLETIME2NDON "IdleTime2ndOn" +//#define IDL_IDLEPRIVATE "IdlePrivate" + +extern BOOL (WINAPI * MyGetLastInputInfo)(PLASTINPUTINFO); +extern int IdleGetInfo(WPARAM wParam, LPARAM lParam); + +VOID CALLBACK IdleTimer(HWND hwnd, UINT message, UINT idEvent, DWORD dwTime); +BOOL InitDialogIdlePart(HWND hwndDlg); + + +//AutoAway Module +#define AA_IDLEOPTIONS "IdleOptions" +#define AA_LASTIDLESTATUS "IdleLastStatus" +#define AA_LASTIDLETIME "IdleLastTime" +#define AA_OLDMODULE "AutoAway" +#define AA_USESHORT "IsShortEnabled" +#define AA_USELONG "IsLongEnabled" +#define AA_SHORTSTATUS "ShortStatus" +#define AA_LONGSTATUS "LongStatus" + +#define AA_MODULE "SmartAutoAway" + +#define AA_PROTOSELECTION "ProtoSelection" + +#define AA_AWAYSTATUSES "AwayStatuses_%s" +#define AA_BITSONLYIF "BitsOnlyIf_%s" +#define AA_LASTREQUESTEDSTATUS "LastRequestedStatus_%s" + +//#define AA_SIMULATEIDLESERVICE "SAA/SimulateIdle" +#define AA_IDLE_BENOTIDLESERVICE "SAA/IdleBeNotIdle" +MIRANDASERVICE idleServiceNotIdle(WPARAM w, LPARAM l); +#define AA_IDLE_BESHORTIDLESERVICE "SAA/IdleBeShortIdle" +MIRANDASERVICE idleServiceShortIdle(WPARAM w, LPARAM l); +#define AA_IDLE_BELONGIDLESERVICE "SAA/IdleBeLongIdle" +MIRANDASERVICE idleServiceLongIdle(WPARAM w, LPARAM l); +#define AA_IDLE_RECONNECTSERVICE "SAA/ForceReconnect" +MIRANDASERVICE reconnectService(WPARAM w, LPARAM l); + +//#define aa_AwayStatusesDefault ((StatusToProtoIndex(ID_STATUS_AWAY,allprotomodes)<<8)|StatusToProtoIndex(ID_STATUS_NA,allprotomodes)) | 0x8000 + //K--- --21 LLLL SSSS +#define maskIsShortAwayEnabled 0x0100 +#define maskIsLongAwayEnabled 0x0200 +#define maskShortAwayStatus 0x000F +#define maskLongAwayStatus 0x00F0 + +#define allprotomodes 0x03FF // 0000 0011 1111 1111; +#define aa_OnlyIfBitsDefault 0x01BB01B8 //Short 0001 1011 1000; + //Long 0001 1011 1011 + + +extern HANDLE hStatusModeChangeEvent; + +extern int aa_Status[]; +extern int numStatuses; + +extern int *reqStatus; +extern int *courStatus; +extern int *courAwayStatus; //to be used in reconnect part + +extern int *protoModes; + +extern short int *awayStatusesPerm; +extern long *onlyIfBitsPerm; +extern short int *awayStatuses; +extern long *onlyIfBits; + + +extern HWND theDialog; +extern HWND theDialogReconnect; +extern HWND theDialogIdle; +extern HWND theDialogAA; +extern HWND theDialogIdleMessages; + + +extern PROTOCOLDESCRIPTOR **proto; +extern int protoCount; +extern int courProtocolSelection; + +unsigned long GetBits (unsigned long source,unsigned long mask); +unsigned long SetBits (unsigned long target,unsigned long mask,unsigned long value); +BOOL IsStatusBitSet(int status, int bits); +int StatusByProtoIndex(int modes, int index); +int StatusToProtoIndex(int status, int modes); + +int OldIndexToStatus(int oldIndex); +int StatusToOldIndex(int status); + +LRESULT SetDlgItems(HWND hwndDlg, int coursel); +LRESULT SetDlgItemsReconnect(HWND hwndDlg, int coursel); +LRESULT SetDlgItemsAA(HWND hwndDlg, int coursel); +LRESULT SetDlgItemsIdleMessages(HWND hwndDlg, int coursel); + +int StatusToProtoIndex(int status, int modes); +int GetCourSelProtocol(int sel); +BOOL StrikeOut(HWND hWnd, int item, BOOL striked); + +int AutoAwayShutdown(WPARAM wParam,LPARAM lParam); +int AutoAwayEvent(WPARAM wParam, LPARAM lParam); +//extern int SimulateIdle(HWND theDialog, int button); +int StatusModeChangeEvent(WPARAM wParam,LPARAM lParam); +int ProtoAckEvent(WPARAM wParam,LPARAM lParam); +int SimulateIdle(int idlstatus); + + +//Reconnect Part +int GetReconnectDelayFromSlider(int slide); +BOOL GetStringFromDelay(TCHAR * str, int delay); +int GetSliderFromReconnectDelay(int delay); +void ProtocolsProc(int protoIndex, ACKDATA * ack); +void LoginAck(int protoIndex, ACKDATA * ack); +void TimerProc(); +extern BOOL CALLBACK DlgProcOptsReconnect(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +#define AA_RECONNECTOPTS "ReconnectOptions_%s" +#define aa_ReconnectOptsDefault 0x003CC1AE +//-----60 sec-------- 1100 0001 1010 1110 +//DDDD DDDD DDDD DDDD Rfxx xxFN ANOD FIPL +#define aa_ReconnectBitsDelay 0xFFFF0000 +#define aa_ReconnectBitsEnabled 0x00008000 +#define aa_ReconnectNotFatalError 0x00004000 + +extern BOOL CALLBACK DlgProcOptsAA(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +extern long *reconnectOpts; +extern long *reconnectOptsPerm; +extern unsigned int *protoOfflineTimes; +extern int *protoStatus; //0:OK; :1:couning; 2:fatalError; + +//IdleMessage part +extern BOOL starting; +extern int *isWaitingForRestoreStatusMessage; +extern unsigned long secondsAfterLastActivity; + + +#define idleMsgOptionsTextHere "IdleMsgTextHere_%s" +#define idleMsgOptionsTextShort "IdleMsgTextShort_%s" +#define idleMsgOptionsTextLong "IdleMsgTextLong_%s" +#define messHereDefaultOld _T("I am back") +#define messShortDefaultOld _T("I am distracted") +#define messLongDefaultOld _T("I am sleeping") +#define messHereDefault _T("I came back on %H:%M:%S%b%Z (%z)") +#define messShortDefault _T("I am distracted since %H:%M:%S%b%Z (%z)") +#define messLongDefault _T("I fell asleep on %H:%M:%S %d %E %Y (%W)%b%Z (%z)") +#define maxMessageLength 2047 +extern TCHAR **mesgHere; +extern TCHAR **mesgShort; +extern TCHAR **mesgLong; +extern TCHAR **mesgHerePerm; +extern TCHAR **mesgShortPerm; +extern TCHAR **mesgLongPerm; + +#define idleMsgOptionsName "IdleMsgOpts_%s" +#define idleMsgOptionsDefault 0x0111103C +extern int *messCaps; + +extern BOOL CALLBACK DlgProcOptsIdleMessages(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +extern long *idleMessOptsPerm; +extern long *idleMessOpts; + // xxxx xxxL xxxS xxxH xxxE xxx- RSTHERE- +#define IdleMessOptsMaskRstHereDelay 0x000001FF // 0000 0000 0000 0000 0000 0001 11111111 +#define IdleMessOptsMaskRstHere 0x00001000 // 0000 0000 0000 0000 0001 0000 00000000 +#define IdleMessOptsMaskUseHere 0x00010000 // 0000 0000 0000 0001 0000 0000 00000000 +#define IdleMessOptsMaskUseShort 0x00100000 // 0000 0000 0001 0000 0000 0000 00000000 +#define IdleMessOptsMaskUseLong 0x01000000 // 0000 0001 0000 0000 0000 0000 00000000 + +extern int localeID; +extern int codePage; +void my_u2a(const TCHAR* src, char * target, unsigned int max); +void my_a2u(const char* src, TCHAR * target, unsigned int max); +void GetLastActiveLocalTime(SYSTEMTIME * at, unsigned long miliSeconds); +int GetTimeZone(TCHAR * name); +UINT ParseString(TCHAR *szstring,TCHAR *sztemp, unsigned int MaxOutLen); + +//borrowed from "Last Seen Plugin" +//#define VARIABLE_LIST "%s\n%%Y: \t %s\n%%y: \t %s\n%%m: \t %s\n%%E: \t %s\n%%e: \t %s\n%%d: \t %s\n%%W: \t %s\n%%w: \t %s\n\n%s\n%%H: \t %s\n%%h: \t %s\n%%p: \t %s\n%%M: \t %s\n%%S: \t %s\n\n%s\n%%z: \t %s\n%%Z: \t %s\n\n%s\n%%t: \t %s\n%%b: \t %s",Translate("-- Date --"),Translate("year (4 digits)"),Translate("year (2 digits)"),Translate("month"),Translate("name of month"),Translate("short name of month"),Translate("day"),Translate("weekday (full)"),Translate("weekday (abbreviated)"),Translate("-- Time --"),Translate("hours (24)"),Translate("hours (12)"),Translate("AM/PM"),Translate("minutes"),Translate("seconds"),Translate("-- Time Zone --"),Translate("total bias"),Translate("time zone name"),Translate("-- Format --"),Translate("tabulator"),Translate("line break") +extern TCHAR *VariableList[][2]; + +void AddIdleMenu(); +extern HANDLE hHookIconsChanged; +void xModifyMenu(int menuInd,long flags); +BOOL isInterestingProto(int j); diff --git a/plugins/!NotAdopted/SmartAutoAway/here.ico b/plugins/!NotAdopted/SmartAutoAway/here.ico new file mode 100644 index 0000000000..ab282fba52 Binary files /dev/null and b/plugins/!NotAdopted/SmartAutoAway/here.ico differ diff --git a/plugins/!NotAdopted/SmartAutoAway/idle.cpp b/plugins/!NotAdopted/SmartAutoAway/idle.cpp new file mode 100644 index 0000000000..9751bcf0e6 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/idle.cpp @@ -0,0 +1,374 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2006 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "globals.h" +//#include "../../miranda-IM/core/commonheaders.h" + + +//int idleCheckPerm = 0; +//int idleMethodPerm = 0; +//int idleTimeFirstPerm = 5; // this is in mins +//int idleTimeSecondPerm = 10; // +//int idleTimeFirstOnPerm = 0; +//int idleTimeSecondOnPerm = 0; +//int idleOnSaverPerm = 0; +//int idleOnLockPerm = 0; +//int idleGLIPerm = 1; +//int idlePrivatePerm = 0; +BOOL (WINAPI * MyGetLastInputInfo)(PLASTINPUTINFO); +unsigned long idleOptsPerm; // C G L S M P L S --LONG-- --SHORT- +unsigned long idleOpts; // C G L S M P L S --LONG-- --SHORT- +static BOOL idleDialogInInit = FALSE; + BOOL InitDialogIdlePart(HWND hwndDlg) +{ +// TranslateDialogDefault(hwndDlg); + CheckDlgButton(hwndDlg, IDC_IDLECHECK, (idleOpts&IdleBitsCheck) ? BST_CHECKED : BST_UNCHECKED); + // check/uncheck options + CheckDlgButton(hwndDlg, IDC_IDLEONWINDOWS, (idleOpts&IdleBitsMethod) ? BST_UNCHECKED : BST_CHECKED); + CheckDlgButton(hwndDlg, IDC_IDLEONMIRANDA, (idleOpts&IdleBitsMethod) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_IDLEUSEGLI, (idleOpts&IdleBitsGLI) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SCREENSAVER, (idleOpts&IdleBitsOnSaver) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_LOCKED, (idleOpts&IdleBitsOnLock) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_IDLESHORT, (idleOpts&IdleBitsFirstOn) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_IDLELONG, (idleOpts&IdleBitsSecondOn) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_IDLEPRIVATE, (idleOpts&IdleBitsPrivate) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_DISBABLEAUTOHERE, (idleOpts&IdleSuppressAutoHere) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_DISABLEIDLEMENU, (idleOpts&IdleSuppressIdleMenu) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_HEREONSTATUSCHANGE, (idleOpts&IdleHereOnStatusChange)? BST_CHECKED : BST_UNCHECKED); + // set times + idleDialogInInit = TRUE; + SetDlgItemInt(hwndDlg, IDC_IDLE1STTIME, GetBits(idleOpts,IdleBitsTimeFirst), FALSE); + SetDlgItemInt(hwndDlg, IDC_IDLE2NDTIME, GetBits(idleOpts,IdleBitsTimeSecond), FALSE); + idleDialogInInit = FALSE; + // enable options + SendMessage(hwndDlg, WM_USER+4, (WPARAM)((idleOpts&IdleBitsCheck)!=0), 0); + return TRUE; +} + +// delphi code here http://www.swissdelphicenter.ch/torry/printcode.php?id=2048 + BOOL IsWorkstationLocked(void) +{ + BOOL rc=0; + HDESK hDesk = OpenDesktopA("default", 0, FALSE, DESKTOP_SWITCHDESKTOP); + if ( hDesk != 0 ) { + rc = SwitchDesktop(hDesk) == FALSE; + CloseDesktop(hDesk); + } + return rc; +} + +// ticks every 2 seconds + int FirstTick; + unsigned long secondsAfterLastActivity; + unsigned long lastIdleEventTime = 0; + int isCurrentlyIdle=0; //0 notidle //1 short //2long + VOID CALLBACK IdleTimer(HWND hwnd, UINT message, UINT idEvent, DWORD dwTime) +{ + DWORD dwTick = GetTickCount(); + int isIdle[3] = {0}; + static int isEventFired[3] = {0}; + int j; + + if (FirstTick) { + FirstTick--; + if (FirstTick==0){ + int flags = 0; + starting = 1; + switch (isCurrentlyIdle) + { + default : {flags = 0;/*MessageBox(theDialog,"BeHere","Button Pressed",0);*/ break;} + case 1: {flags = IDF_SHORT|IDF_ISIDLE; /*MessageBox(theDialog,"BeAway","Button Pressed",0);*/ break;} + case 2: {flags = IDF_LONG|IDF_ISIDLE; /*MessageBox(theDialog,"BeNA","Button Pressed",0);*/ break;} + } + if (isCurrentlyIdle) { + lastIdleEventTime = DBGetContactSettingDword(NULL,AA_MODULE,AA_LASTIDLETIME,(DWORD)time(NULL)); + secondsAfterLastActivity = time(NULL) - lastIdleEventTime; + + } else secondsAfterLastActivity = 0; + flags |= idleOpts&IdleBitsPrivate?IDF_PRIVACY:0; + NotifyEventHooks( hIdleEvent, 0, flags ); //Tell everyone we are here + return; + } + } + + for (j = 0 ; j < protoCount ; j++) { + if ( !isInterestingProto(j) ) continue; + if (isWaitingForRestoreStatusMessage[j]) { + isWaitingForRestoreStatusMessage[j]--; + if (!(isWaitingForRestoreStatusMessage[j])) { +#ifdef UNICODE + TCHAR *awayMsg=0; + if (HasAwayMessageW){ + awayMsg = (TCHAR *) CallService(MS_AWAYMSG_GETSTATUSMSGW, (WPARAM) courAwayStatus[j], 0); + } else { + char *temp=(char *)CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) courAwayStatus[j], 0); + if ((int)temp == CALLSERVICE_NOTFOUND) awayMsg = 0; + else{ + awayMsg = (TCHAR *)mir_alloc((maxMessageLength+1)*sizeof(TCHAR)); + my_a2u(temp,awayMsg,maxMessageLength); + mir_free(temp); + } + } +#else + char * awayMsg = (char *) CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) courAwayStatus[j], 0); + if ((int)awayMsg==CALLSERVICE_NOTFOUND) awayMsg = NULL; +#endif + +#ifdef AALOG + { + char str[1000]; + sprintf(str,"%s: Restoring the default \"StatusMessage\": %s",proto[j]->szName,awayMsg ? awayMsg : "none"); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); + } +#endif +#ifdef UNICODE + if (protoHasAwayMessageW[j]) CallProtoService(proto[j]->szName, PS_SETAWAYMSGW, courAwayStatus[j], (LPARAM) awayMsg); + else { + char temp[maxMessageLength+1]; + my_u2a(awayMsg,temp,maxMessageLength); + CallProtoService(proto[j]->szName, PS_SETAWAYMSG, courAwayStatus[j], (LPARAM) temp); + } +#else + CallProtoService(proto[j]->szName, PS_SETAWAYMSG, courAwayStatus[j], (LPARAM) awayMsg); +#endif + if (awayMsg) { +#ifdef AALOG + char str[1000]; + sprintf(str,"%s: Cleaning after MS_AWAYMSG_GETSTATUSMSG: %s",proto[j]->szName,awayMsg); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + mir_free(awayMsg); + } + + } + } + } + + TimerProc(); //for the reconnect + secondsAfterLastActivity = 0; + isCurrentlyIdle = 0; + if ( (idleOptsPerm&IdleBitsCheck) == 0 ) return; + + if ( (idleOptsPerm&IdleBitsMethod) == 0 ) { + // use windows idle time + if ( GetBits(idleOptsPerm,IdleBitsGLI) && (MyGetLastInputInfo != 0) ) { + LASTINPUTINFO ii; + memset(&ii,0,sizeof(ii)); + ii.cbSize=sizeof(ii); + if ( MyGetLastInputInfo(&ii) ) dwTick = ii.dwTime; + } else { + // mouse check + static int mouseIdle = 0; + static POINT lastMousePos = {0}; + POINT pt; + GetCursorPos(&pt); + if ( pt.x != lastMousePos.x || pt.y != lastMousePos.y ) + { + mouseIdle=0; + lastMousePos=pt; + } + else mouseIdle += 2; // interval of timer + if ( mouseIdle ) dwTick = GetTickCount() - (mouseIdle * 1000); + } + } else { + // use miranda idle time + CallService(MS_SYSTEM_GETIDLE, 0, (LPARAM)&dwTick); + } + secondsAfterLastActivity = (GetTickCount() - dwTick)/1000; +#ifdef AALOG + { char log[1024]; + sprintf(log,"%d seconds after last activity",secondsAfterLastActivity); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);} +#endif + // has the first idle elapsed? If not permited FirstIdle time:ignore + isIdle[0] = (idleOptsPerm&IdleBitsFirstOn)? (secondsAfterLastActivity >= (DWORD)( GetBits(idleOptsPerm,IdleBitsTimeFirst) * 60 )):0; + // and the second? if not permited the SecondIdleTime: idnore + isIdle[1] = (idleOptsPerm&IdleBitsSecondOn)?(secondsAfterLastActivity >= (DWORD)( GetBits(idleOptsPerm,IdleBitsTimeSecond) * 60 )):0; + + isIdle[2] = FALSE; + if ( idleOptsPerm&IdleBitsOnSaver ) { // check saver + BOOL isScreenSaverRunning = FALSE; + SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &isScreenSaverRunning, FALSE); + isIdle[2] |= isScreenSaverRunning; + } + + // check workstation? + if ( idleOptsPerm&IdleBitsOnLock ) { // check station locked? + isIdle[2] |= IsWorkstationLocked(); + } + { //check if the new idle is more idle than the previous idle is idle ;) + int temp = isIdle[1]?2:((isIdle[0] || isIdle[2])?1:0); + if (temp>=isCurrentlyIdle) isCurrentlyIdle = temp; + else return; //if we are alredy idle then exit + } + for ( j = 0; j<3; j++ ) + { + int flags = ( idleOptsPerm&IdleBitsPrivate ? IDF_PRIVACY:0 ); + switch (j) { + case 0: flags |= IDF_SHORT; break; + case 1: flags |= IDF_LONG; break; + case 2: flags |= IDF_ONFORCE; break; + } + if ( isIdle[j]==1 && isEventFired[j] == 0 ) { // idle and no one knows + isEventFired[j]=1; + NotifyEventHooks( hIdleEvent, 0, IDF_ISIDLE | flags ); + } + if ( isIdle[j]==0 && isEventFired[j] == 1 ) { // not idle, no one knows + isEventFired[j]=0; + if ( !(idleOptsPerm&IdleSuppressAutoHere) ) NotifyEventHooks( hIdleEvent, 0, flags ); + } + }//for +// { +// int flags = ( idleOptsPerm&IdleBitsPrivate ? IDF_PRIVACY:0 ); +// if (isIdle[0]||isIdle[1]||isIdle[2]) flags |= IDF_ISIDLE; +// if (isIdle[0]) flags |= IDF_SHORT; +// if (isIdle[1]) flags |= IDF_LONG; +// if (isIdle[2]) flags |= IDF_ONFORCE; +// NotifyEventHooks( hIdleEvent, 0, flags ); +// } +} + + int IdleGetInfo(WPARAM wParam, LPARAM lParam) +{ + MIRANDA_IDLE_INFO * mii = (MIRANDA_IDLE_INFO *) lParam; + if (mii) { + int minutesAfterLastActivity = (time(NULL)-lastIdleEventTime)/60; +#ifdef AALOG + char log[1024]; + sprintf(log,"\"%s\": %d came.", + MS_IDLE_GETIDLEINFO, + mii->cbSize/sizeof(mii->cbSize)); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); +#endif + if (minutesAfterLastActivity<=0) minutesAfterLastActivity = 1; + //this is the only field with similar meaning in "old" and "new miranda"; + if (mii->cbSize/sizeof(mii->cbSize)>=2) mii->idleTime = isCurrentlyIdle?minutesAfterLastActivity:0; + if (mii->cbSize/sizeof(mii->cbSize)>=3) mii->privacy = (idleOptsPerm&IdleBitsPrivate) !=0; + if (mii->cbSize/sizeof(mii->cbSize)>=4) mii->aaStatus = isCurrentlyIdle==1?ID_STATUS_AWAY:(isCurrentlyIdle>1?ID_STATUS_NA:ID_STATUS_ONLINE); //dont know what to with that + if (mii->cbSize/sizeof(mii->cbSize)>=5) mii->aaLock = (idleOptsPerm&IdleSuppressAutoHere) !=0; + if (mii->cbSize/sizeof(mii->cbSize)>=6) mii->idleType = isCurrentlyIdle?1:0; + return 0; + } else return 1; +} + +BOOL CALLBACK DlgProcOptsIdle(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + InitDialogIdlePart(hwndDlg); + return TRUE; + case WM_USER+4: + { + DWORD nID[] = { IDC_IDLEONWINDOWS, + IDC_IDLEUSEGLI, + IDC_IDLEONMIRANDA, + IDC_SCREENSAVER, + IDC_LOCKED, + IDC_IDLESHORT, + IDC_IDLE1STTIME, + IDC_IDLELONG, + IDC_IDLE2NDTIME//,IDC_IDLEPRIVATE + }; + int j; + // enable/disable all sub controls, + for (j = 0; j < sizeof(nID) / sizeof(nID[0]); j++) { + int nEnable = wParam; + switch ( nID[j] ) { + case IDC_IDLEUSEGLI: nEnable &= IsDlgButtonChecked(hwndDlg, IDC_IDLEONWINDOWS) == BST_CHECKED ? 1 : 0; break; + case IDC_IDLE1STTIME: nEnable &= IsDlgButtonChecked(hwndDlg, IDC_IDLESHORT) == BST_CHECKED ? 1 : 0; break; + case IDC_IDLE2NDTIME: nEnable &= IsDlgButtonChecked(hwndDlg, IDC_IDLELONG) == BST_CHECKED ? 1 : 0; break; + } + EnableWindow(GetDlgItem(hwndDlg, nID[j]), nEnable); + } + + idleOpts=SetBits(idleOpts,IdleBitsCheck, IsDlgButtonChecked(hwndDlg, IDC_IDLECHECK) == BST_CHECKED); + idleOpts=SetBits(idleOpts,IdleBitsMethod, IsDlgButtonChecked(hwndDlg, IDC_IDLEONMIRANDA) == BST_CHECKED); + idleOpts=SetBits(idleOpts,IdleBitsFirstOn, IsDlgButtonChecked(hwndDlg, IDC_IDLESHORT) == BST_CHECKED); + idleOpts=SetBits(idleOpts,IdleBitsSecondOn, IsDlgButtonChecked(hwndDlg, IDC_IDLELONG) == BST_CHECKED); + idleOpts=SetBits(idleOpts,IdleBitsGLI, IsDlgButtonChecked(hwndDlg, IDC_IDLEUSEGLI) == BST_CHECKED); + idleOpts=SetBits(idleOpts,IdleBitsOnSaver, IsDlgButtonChecked(hwndDlg, IDC_SCREENSAVER) == BST_CHECKED); + idleOpts=SetBits(idleOpts,IdleBitsOnLock, IsDlgButtonChecked(hwndDlg, IDC_LOCKED) == BST_CHECKED); + idleOpts=SetBits(idleOpts,IdleBitsPrivate, IsDlgButtonChecked(hwndDlg, IDC_IDLEPRIVATE) == BST_CHECKED); + idleOpts=SetBits(idleOpts,IdleSuppressAutoHere, IsDlgButtonChecked(hwndDlg, IDC_DISBABLEAUTOHERE) == BST_CHECKED); + idleOpts=SetBits(idleOpts,IdleSuppressIdleMenu, IsDlgButtonChecked(hwndDlg, IDC_DISABLEIDLEMENU) == BST_CHECKED); + idleOpts=SetBits(idleOpts,IdleHereOnStatusChange, IsDlgButtonChecked(hwndDlg, IDC_HEREONSTATUSCHANGE) == BST_CHECKED); + break; + } + case WM_USER+8: + { + if (wParam == IDC_IDLE1STTIME) idleOpts = SetBits(idleOpts,IdleBitsTimeFirst,GetDlgItemInt(hwndDlg, wParam, NULL, FALSE)); + if (wParam == IDC_IDLE2NDTIME) idleOpts = SetBits(idleOpts,IdleBitsTimeSecond,GetDlgItemInt(hwndDlg, wParam, NULL, FALSE)); + break; + } + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_IDLEBUTTON: + case IDC_IDLEBUTTON+1: + case IDC_IDLEBUTTON+2:SimulateIdle(LOWORD(wParam)-IDC_IDLEBUTTON); break; + case IDC_IDLECHECK: + case IDC_IDLEONWINDOWS: + case IDC_IDLEONMIRANDA: + case IDC_IDLESHORT: + case IDC_IDLELONG: + case IDC_IDLEUSEGLI: + case IDC_SCREENSAVER: + case IDC_LOCKED: + case IDC_IDLEPRIVATE: + case IDC_DISBABLEAUTOHERE: + case IDC_HEREONSTATUSCHANGE: + case IDC_DISABLEIDLEMENU: + { + SendMessage(hwndDlg, WM_USER+4, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_IDLECHECK) == BST_CHECKED, 0); + break; + } + case IDC_IDLE1STTIME: + case IDC_IDLE2NDTIME: + { + if ( HIWORD(wParam) != EN_CHANGE ) return TRUE; + SendMessage(hwndDlg, WM_USER+8, LOWORD(wParam), 0); + break; + } + } + if (!idleDialogInInit) if ((HIWORD(wParam)==BN_CLICKED)||(HIWORD(wParam)==EN_CHANGE)) + { + if ((LOWORD(wParam)!=IDC_IDLEBUTTON)&&(LOWORD(wParam)!=IDC_IDLEBUTTON+1)&&(LOWORD(wParam)!=IDC_IDLEBUTTON+2)) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + break; + case WM_NOTIFY: + switch (((LPNMHDR) lParam)->idFrom) { + case 0: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: { + return TRUE; + } + } + break; + } + break; + case WM_DESTROY: + break; + } + return FALSE; +} + diff --git a/plugins/!NotAdopted/SmartAutoAway/idleMenu.cpp b/plugins/!NotAdopted/SmartAutoAway/idleMenu.cpp new file mode 100644 index 0000000000..bc5ad2a255 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/idleMenu.cpp @@ -0,0 +1,147 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2006 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "globals.h" +#ifdef SAA_PLUGIN +# include "m_icolib.h" +#endif + +HANDLE hIdleMenu[4] = {NULL,NULL,NULL,NULL}; +HANDLE hHookIconsChanged = NULL; +static char *iconDescs[4]={"Not Idle","Short Idle","Long Idle","Reconnect"}; +static int iconInd[4]={IDI_IDLE_HERE,IDI_IDLE_SHORT,IDI_IDLE_LONG,IDI_RECONNECT}; +static char *IdleServices[4]={AA_IDLE_BENOTIDLESERVICE,AA_IDLE_BESHORTIDLESERVICE,AA_IDLE_BELONGIDLESERVICE,AA_IDLE_RECONNECTSERVICE}; + +void xModifyMenu(int menuInd,long flags) +{ if (hIdleMenu[menuInd]){ + CLISTMENUITEM mi = {0}; + + mi.cbSize = sizeof(mi); + mi.flags = CMIM_FLAGS; + mi.flags |= flags; + CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hIdleMenu[menuInd],(LPARAM)&mi); +} } + +static int hasIcoLib = 0; + +static void CListSetMenuItemIcon(HANDLE hMenuItem, HICON hIcon) +{ + CLISTMENUITEM mi = {0}; + + mi.cbSize = sizeof(mi); + mi.flags = CMIM_FLAGS | CMIM_ICON; + + mi.hIcon = hIcon; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuItem, (LPARAM)&mi); +} + +static int IconLibIconsChanged(WPARAM wParam, LPARAM lParam) +{ + int i; + for (i=0;i<4;i++) + { + HICON hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)IdleServices[i]); + CListSetMenuItemIcon(hIdleMenu[i], hIcon); + CallService(MS_SKIN2_RELEASEICON, 0, (LPARAM)IdleServices[i]); + } + return 0; +} + +void AddIdleMenu(){ + CLISTMENUITEM mi; + int i; + if (ServiceExists(MS_SKIN2_GETICON)){ + SKINICONDESC sid = {0}; + hHookIconsChanged = HookEvent(ME_SKIN2_ICONSCHANGED, IconLibIconsChanged); + hasIcoLib = 1; + sid.cbSize = SKINICONDESC_SIZE_V2; + sid.pszSection = SECTIONNAME; + sid.pszDefaultFile = NULL; + sid.iDefaultIndex = 0; + for (i=0;i<4;i++){ + sid.pszDescription = iconDescs[i]; + sid.pszName = IdleServices[i]; + sid.iDefaultIndex = iconInd[i]; + sid.hDefaultIcon = (HICON)LoadImage( + #ifdef SAA_PLUGIN + g_hInst, + #else + GetModuleHandle(NULL), + #endif + MAKEINTRESOURCE( iconInd[i] ), IMAGE_ICON, 0, 0, 0); + CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid); + DestroyIcon(sid.hDefaultIcon); + } + } + + ZeroMemory(&mi,sizeof(mi)); + mi.cbSize=sizeof(mi); + mi.pszPopupName="&Idle"; + mi.popupPosition=1000090000; + for (i=0;i<4;i++) + { + if (hasIcoLib) + mi.hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)IdleServices[i]); + else + mi.hIcon = (HICON)LoadImage( + #ifdef SAA_PLUGIN + g_hInst, + #else + GetModuleHandle(NULL), + #endif + MAKEINTRESOURCE(iconInd[i]), IMAGE_ICON, 0, 0, 0); + + mi.position=i+1; + mi.pszName=iconDescs[i]; + mi.pszService=IdleServices[i]; + if (i==3) mi.position=1000000; + hIdleMenu[i]=(HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi); + + if (hasIcoLib) + CallService(MS_SKIN2_RELEASEICON, 0, (LPARAM)IdleServices[i]); + else + DestroyIcon(mi.hIcon); + } +// return 0; +} + +MIRANDASERVICE idleServiceNotIdle(WPARAM w, LPARAM l){ + SimulateIdle(0); + return 0; +}; +MIRANDASERVICE idleServiceShortIdle(WPARAM w, LPARAM l){ + SimulateIdle(1); + return 0; +}; +MIRANDASERVICE idleServiceLongIdle(WPARAM w, LPARAM l){ + SimulateIdle(2); + return 0; +}; +MIRANDASERVICE reconnectService(WPARAM w, LPARAM l){ + int i; + for (i=0;iszName); + SetDlgItemText(hwndDlg,IDC_PROTODONOTSUPPORT,str); + } + idleDialogInInit = FALSE; + EnableWindow(GetDlgItem(hwndDlg, IDC_VARIABLES), (messCaps[coursel])); +// CheckDlgButton(hwndDlg, IDC_ENABLERECONNECT, enabledReconnect?BST_CHECKED:BST_UNCHECKED ); +// CheckDlgButton(hwndDlg, IDC_NOTFATALERROR, dontReconnectOnFatalError?BST_CHECKED:BST_UNCHECKED ); +// EnableWindow(GetDlgItem(hwndDlg, IDC_RECONNECTSLIDER), enabledReconnect); +// EnableWindow(GetDlgItem(hwndDlg, IDC_NOTFATALERROR), enabledReconnect); + return TRUE; +} + + + +BOOL CALLBACK DlgProcOptsIdleMessages(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + SetDlgItemsIdleMessages(hwndDlg, courProtocolSelection); + return TRUE; + case WM_USER+1: + { + EnableWindow(GetDlgItem(hwndDlg, IDC_RESTOREMSGSLIDER), wParam); + idleMessOpts[courProtocolSelection] = SetBits(idleMessOpts[courProtocolSelection],IdleMessOptsMaskRstHere,wParam); + break; + } + case WM_USER+2: + { + EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEMSGHERE), wParam); + EnableWindow(GetDlgItem(hwndDlg, IDC_RESTOREMSGSLIDER), wParam); + EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLERESTOREMSG), wParam); + idleMessOpts[courProtocolSelection] = SetBits(idleMessOpts[courProtocolSelection],IdleMessOptsMaskUseHere,wParam); + break; + } + case WM_USER+3: + { + EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEMSGSHORT), wParam); + idleMessOpts[courProtocolSelection] = SetBits(idleMessOpts[courProtocolSelection],IdleMessOptsMaskUseShort,wParam); + break; + } + case WM_USER+4: + { + EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEMSGLONG), wParam); + idleMessOpts[courProtocolSelection] = SetBits(idleMessOpts[courProtocolSelection],IdleMessOptsMaskUseLong,wParam); + break; + } + case WM_USER+8: + { + TCHAR temp[maxMessageLength+1]; + ParseString((TCHAR *)lParam,temp,maxMessageLength); +#ifdef UNICODE + if(!protoHasAwayMessageW[courProtocolSelection]) { + char tempa[maxMessageLength+1]; + my_u2a(temp, tempa, maxMessageLength); + my_a2u(tempa,temp,maxMessageLength); + } +#endif + SetDlgItemText(hwndDlg,IDC_PROTODONOTSUPPORT,temp); + break; + } + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_ENABLERESTOREMSG: + { + SendMessage(hwndDlg, WM_USER+1, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_ENABLERESTOREMSG) == BST_CHECKED, 0); + break; + } + case IDC_IDLEMSGHERE_THIS: + { + SendMessage(hwndDlg,WM_USER+2, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_IDLEMSGHERE_THIS) == BST_CHECKED, 0); + break; + } + case IDC_IDLEMSGSHORT_THIS: + { + SendMessage(hwndDlg,WM_USER+3, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_IDLEMSGSHORT_THIS) == BST_CHECKED, 0); + break; + } + case IDC_IDLEMSGLONG_THIS: + { + SendMessage(hwndDlg,WM_USER+4, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_IDLEMSGLONG_THIS) == BST_CHECKED, 0); + break; + } + case IDC_IDLEMSGHERE: + { + if (HIWORD(wParam)==EN_CHANGE || HIWORD(wParam)==EN_SETFOCUS){ + TCHAR str[maxMessageLength+1]; + GetDlgItemText(hwndDlg,IDC_IDLEMSGHERE,str,maxMessageLength+1); + SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)str); + } else if (HIWORD(wParam)==EN_KILLFOCUS) { + GetDlgItemText(hwndDlg,IDC_IDLEMSGHERE,mesgHere[courProtocolSelection],maxMessageLength+1); + SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)""); + } + break; + } + case IDC_IDLEMSGSHORT: + { + if (HIWORD(wParam)==EN_CHANGE || HIWORD(wParam)==EN_SETFOCUS){ + TCHAR str[maxMessageLength+1]; + GetDlgItemText(hwndDlg,IDC_IDLEMSGSHORT,str,maxMessageLength+1); + SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)str); + } else if (HIWORD(wParam)==EN_KILLFOCUS) { + GetDlgItemText(hwndDlg,IDC_IDLEMSGSHORT,mesgShort[courProtocolSelection],maxMessageLength+1); + SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)""); + } + break; + } + case IDC_IDLEMSGLONG: + { + if (HIWORD(wParam)==EN_CHANGE || HIWORD(wParam)==EN_SETFOCUS){ + TCHAR str[maxMessageLength+1]; + GetDlgItemText(hwndDlg,IDC_IDLEMSGLONG,str,maxMessageLength+1); + SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)str); + } else if (HIWORD(wParam)==EN_KILLFOCUS) { + GetDlgItemText(hwndDlg,IDC_IDLEMSGLONG,mesgLong[courProtocolSelection],maxMessageLength+1); + SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)""); + } + break; + } + case IDC_VARIABLES: + { + TCHAR szout[2048]=_T(""); + UINT pos=0; + for (int i=0;i<25;i++){ + if (VariableList[i][0]){ + pos+=_sntprintf(&szout[pos],2048-pos,_T("%%%s \t %s\n"),VariableList[i][0],TranslateTS(VariableList[i][1])); + } else { + pos+=_sntprintf(&szout[pos],2048-pos,_T("-- %s --\n"),TranslateTS(VariableList[i][1])); + } + } + //sprintf(szout,VARIABLE_LIST); + MessageBox(NULL,szout,TranslateT("Variables to use"),MB_OK|MB_TOPMOST); + break; + } + + break; //case WM_COMMAND + } + if (!idleDialogInInit) if ((HIWORD(wParam)==BN_CLICKED)||(HIWORD(wParam)==EN_CHANGE)) + { + if (LOWORD(wParam)!=IDC_VARIABLES) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + break; + case WM_NOTIFY: + switch (((LPNMHDR) lParam)->idFrom) { + case 0: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: { + return TRUE; + } + } + break; + } + break; + case WM_HSCROLL: + if((HWND)lParam == GetDlgItem(hwndDlg, IDC_RESTOREMSGSLIDER)) { + moveScrollBarRestoreMsgEvent(hwndDlg); + if (LOWORD(wParam) == SB_ENDSCROLL) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + break; + case WM_DESTROY: + break; + } + return FALSE; +} diff --git a/plugins/!NotAdopted/SmartAutoAway/long.ico b/plugins/!NotAdopted/SmartAutoAway/long.ico new file mode 100644 index 0000000000..37845ebbb0 Binary files /dev/null and b/plugins/!NotAdopted/SmartAutoAway/long.ico differ diff --git a/plugins/!NotAdopted/SmartAutoAway/reconnect.cpp b/plugins/!NotAdopted/SmartAutoAway/reconnect.cpp new file mode 100644 index 0000000000..aad175c2f8 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/reconnect.cpp @@ -0,0 +1,328 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2006 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "globals.h" + +long *reconnectOptsPerm=0; +long *reconnectOpts=0; + +unsigned int *protoOfflineTimes=0; +int *protoStatus=0; //0:OK; :1:couning; 2:fatalError; 4:reconnectForced + + +void LoginAck(int protoIndex, ACKDATA * ack) +{ +#ifdef AALOG + char log[1024]; + sprintf(log,"LoginAck: %s: result: %d; hProcess: %d; lParam: %d;" , + proto[protoIndex]->szName, + ack->result,ack->hProcess,ack->lParam +// CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->hProcess, 0), +// CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->lParam, 0) + ); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); +#endif + if (ack->result == ACKRESULT_FAILED) switch (ack->lParam){ + case LOGINERR_WRONGPASSWORD: + case LOGINERR_BADUSERID: + case LOGINERR_WRONGPROTOCOL: + case LOGINERR_OTHERLOCATION: + { +#ifdef AALOG + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"LoginAck: FatalError occured"); +#endif + protoStatus[protoIndex]|=2; + protoOfflineTimes[protoIndex]=0; + return; + break; + } + } +} + + +void ProtocolsProc(int protoIndex, ACKDATA * ack) +//ProtoProc: ICQ-AUX: result: 0; hProcess: Online; lParam: Offline; +{ +#ifdef AALOG + char log[1024]; + sprintf(log,"ProtoProc: %s: result: %d; hProcess: %s; lParam: %s; RequestedStatus: %s; AutoAwayStatus: %s" , + proto[protoIndex]->szName, + ack->result, + CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->hProcess, 0), + CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->lParam, 0), + CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)reqStatus[protoIndex], 0), + CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courAwayStatus[protoIndex], 0) + ); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); +#endif + protoOfflineTimes[protoIndex]=0; + if (ack->lParam==ID_STATUS_OFFLINE) protoStatus[protoIndex]|=1; //will be counting, keeping eventual "FatalError" Flag + else protoStatus[protoIndex] = 0; //We are not offline or are connecting -> clear counting and "FatalError" +#ifdef AALOG + sprintf(log,"ProtoProc: %s: Result: ProtoStatus: %d", + proto[protoIndex]->szName,protoStatus[protoIndex]); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); +#endif + +} + +#ifdef AALOG +#define AALOG2 +#endif +int IsReconnectForbidden(int protoIndex){ //0 if it permitted +#ifdef AALOG2 + char str[256]; +#endif + if (!(protoStatus[protoIndex]&1)) return 1; //Proto is not counting or is not offline + protoOfflineTimes[protoIndex] += 2; //the timer ticks every 2 seconds + if (protoStatus[protoIndex]&4) { // Reconnect is forced +#ifdef AALOG2 + sprintf(str,"ReconnForbiddden: %s reconnection is forced.",proto[protoIndex]->szName); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + return 0; + } +#ifdef AALOG2 + sprintf(str,"ReconnForbiddden: %s is Offline and counting: %d to %d",proto[protoIndex]->szName,protoOfflineTimes[protoIndex],HIWORD(reconnectOptsPerm[protoIndex])); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + if (protoOfflineTimes[protoIndex] <= HIWORD(reconnectOptsPerm[protoIndex])) return 2; // not yet + if (!(reconnectOptsPerm[protoIndex]&aa_ReconnectBitsEnabled)) return 3; //reconnect is disabled +#ifdef AALOG2 + sprintf(str,"ReconnForbiddden: %s has ReconnectEnabled",proto[protoIndex]->szName); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + if (protoStatus[protoIndex]&2) { //FatalError? +#ifdef AALOG2 + sprintf(str,"ReconnForbiddden: %s has FatalError; ProtoStatus: %d",proto[protoIndex]->szName,protoStatus[protoIndex]); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + if (reconnectOptsPerm[protoIndex]&aa_ReconnectNotFatalError) { +#ifdef AALOG2 + sprintf(str,"ReconnForbiddden: %s has DontReconnectOnFatalError",proto[protoIndex]->szName); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + return 4; //exit if "dontReconnectOnFatalError" enabled +#ifdef AALOG2 + } else { + sprintf(str,"ReconnForbiddden: %s has FatalError but DontReconnectOnFatalError disabled",proto[protoIndex]->szName); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + } + } //if FatalError + if (IsStatusBitSet(courAwayStatus[protoIndex],LOWORD(reconnectOptsPerm[protoIndex]))){ //is reconnect permited on this lastonline status? + //reconnecting... +#ifdef AALOG2 + sprintf(str,"ReconnForbiddden: %s Reconnect permitted",proto[protoIndex]->szName); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + return 0; // reconnect is permitted +#ifdef AALOG2 + } else { + sprintf(str,"ReconnForbiddden: %s Reconnecting to %s(%d) was not permited by %d", + proto[protoIndex]->szName, + CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courAwayStatus[protoIndex], 0), + courAwayStatus[protoIndex], + reconnectOptsPerm[protoIndex]); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + } + return 5; // forbidden because current status is disabled +} +#undef AALOG2 +void TimerProc() +{ +#ifdef AALOG + char str[256]; +#endif + int i; + for (i=0;iszName); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + if (protoStatus[i]&1) { +#ifdef AALOG1 + sprintf(str,"TimerProc: %s is Counting: AwayStatus: %s; reqStatus: %s;", + proto[i]->szName, + CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courAwayStatus[i], 0), + CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)reqStatus[i], 0) + ); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + if ((courAwayStatus[i]==ID_STATUS_OFFLINE)||(reqStatus[i]==ID_STATUS_OFFLINE)){ + protoStatus[i]&=2; //keeping fatalerror if any +#ifdef AALOG + sprintf(str,"TimerProc: %s Counting Cancelled: AwayStatus: %s; reqStatus: %s;", + proto[i]->szName, + CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courAwayStatus[i], 0), + CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)reqStatus[i], 0) + ); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + } + } + switch (IsReconnectForbidden(i)) { +#ifdef AALOG1 + case 1 : sprintf(str,"IsReconnectForbidden: %s is not counting or is not offline",proto[i]->szName); break; + case 2 : sprintf(str,"IsReconnectForbidden: %s it is too early to reconnect",proto[i]->szName); break; + case 3 : sprintf(str,"IsReconnectForbidden: %s has reconnect disabled",proto[i]->szName); break; + case 4 : sprintf(str,"IsReconnectForbidden: %s fatal error and DontReconnect enabled",proto[i]->szName); break; + case 5 : sprintf(str,"IsReconnectForbidden: %s current AAStatus should not be reconnected",proto[i]->szName); break; +#endif + case 0 : +#ifdef AALOG + sprintf(str,"IsReconnectForbidden: %s is permited to reconnect",proto[i]->szName); +#endif + CallProtoService(proto[i]->szName, PS_SETSTATUS, courAwayStatus[i], 0); + break; + default : +#ifdef AALOG + sprintf(str,"IsReconnectForbidden: %s Surprising answer",proto[i]->szName); +#endif + break; + } +#ifdef AALOG1 + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +#endif + }//protoType protocol + }//for +} +void moveScrollBarEvent(HWND hwndDlg){ + TCHAR str[256]; + int slide = SendDlgItemMessage(hwndDlg,IDC_RECONNECTSLIDER,TBM_GETPOS,0,0); + int delay = GetReconnectDelayFromSlider(slide); + ShowWindow(GetDlgItem(hwndDlg, IDC_RECONNECTWARNING),GetStringFromDelay(str, delay)?SW_SHOW:SW_HIDE); + SetDlgItemText(hwndDlg,IDC_ENABLERECONNECT,str); + reconnectOpts[courProtocolSelection] = SetBits(reconnectOpts[courProtocolSelection],aa_ReconnectBitsDelay,delay); +} + +LRESULT SetDlgItemsReconnect(HWND hwndDlg, int coursel){ + BOOL enabledReconnect = GetBits(reconnectOpts[coursel],aa_ReconnectBitsEnabled); + BOOL dontReconnectOnFatalError = GetBits(reconnectOpts[coursel],aa_ReconnectNotFatalError); + int i =0; + + for (i=0;i0; + EnableWindow(GetDlgItem(hwndDlg, aa_Status[i]+0x20), enabledReconnect); + StrikeOut(hwndDlg,aa_Status[i]+0x20,bita); + CheckDlgButton(hwndDlg, aa_Status[i]+0x20, bitr?BST_CHECKED:BST_UNCHECKED ); + } + SendDlgItemMessage(hwndDlg,IDC_RECONNECTSLIDER,TBM_SETPOS,TRUE,GetSliderFromReconnectDelay(GetBits(reconnectOpts[coursel],aa_ReconnectBitsDelay))); + moveScrollBarEvent(hwndDlg); + CheckDlgButton(hwndDlg, IDC_ENABLERECONNECT, enabledReconnect?BST_CHECKED:BST_UNCHECKED ); + CheckDlgButton(hwndDlg, IDC_NOTFATALERROR, dontReconnectOnFatalError?BST_CHECKED:BST_UNCHECKED ); + EnableWindow(GetDlgItem(hwndDlg, IDC_RECONNECTSLIDER), enabledReconnect); + EnableWindow(GetDlgItem(hwndDlg, IDC_NOTFATALERROR), enabledReconnect); + CheckDlgButton(hwndDlg, IDC_KEEPMAINSTATUSOFFLINE, (idleOpts&KeepMainStatusOffline)? BST_CHECKED : BST_UNCHECKED); + return TRUE; +} + + +BOOL CALLBACK DlgProcOptsReconnect(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + SetDlgItemsReconnect(hwndDlg, courProtocolSelection); + return TRUE; + case WM_USER+5: + { + int thebit = numStatuses-StatusToProtoIndex(LOWORD(lParam),allprotomodes); + int value = IsDlgButtonChecked(hwndDlg, LOWORD(lParam)+32)==BST_CHECKED; + thebit = 1<idFrom) { + case 0: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: { + return TRUE; + } + } + break; + } + break; + case WM_HSCROLL: + if((HWND)lParam == GetDlgItem(hwndDlg, IDC_RECONNECTSLIDER)) { + moveScrollBarEvent(hwndDlg); + if (LOWORD(wParam) == SB_ENDSCROLL) SendMessage(GetParent(hwndDlg), PSM_CHANGED, (unsigned int)hwndDlg, 0); + } + break; + case WM_DESTROY: + break; + } + return FALSE; +} diff --git a/plugins/!NotAdopted/SmartAutoAway/reconnect.ico b/plugins/!NotAdopted/SmartAutoAway/reconnect.ico new file mode 100644 index 0000000000..ee4092e593 Binary files /dev/null and b/plugins/!NotAdopted/SmartAutoAway/reconnect.ico differ diff --git a/plugins/!NotAdopted/SmartAutoAway/resource.h b/plugins/!NotAdopted/SmartAutoAway/resource.h new file mode 100644 index 0000000000..5473b9529e --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/resource.h @@ -0,0 +1,77 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by saa-res.rc +// +#define IDR_MENUIDLE 101 +#define IDD_OPT_SAA_AA 301 +#define IDD_OPT_SAA_RECONNECT 302 +#define IDD_OPT_SAA_IDLE 303 +#define IDD_OPT_SAA_IDLEMESSAGES 304 +#define IDD_OPT_SMARTAUTOAWAY 202 +#define IDC_OPT_SAA_TAB 1000 +#define IDC_IDLEGROUP_HERE 1001 +#define IDC_IDLEGROUP_SHORT 1002 +#define IDC_IDLEGROUP_LONG 1003 +#define IDC_IDLEMSGHERE_THIS 1004 +#define IDC_IDLEMSGSHORT_THIS 1006 +#define IDC_IDLEMSGHERE 1007 +#define IDC_IDLEMSGSHORT 1008 +#define IDC_IDLEMSGLONG 1009 +#define IDC_IDLEMSGLONG_THIS 1011 +#define IDC_ENABLERESTOREMSG 1012 +#define IDC_RESTOREMSGSLIDER 1013 +#define IDC_PROTODONOTSUPPORT 1014 +#define IDC_VARIABLES 1015 +#define IDC_IDLEBUTTON 1500 +#define IDC_IDLECHECK 1636 +#define IDC_IDLEONWINDOWS 1637 +#define IDC_IDLEONMIRANDA 1638 +#define IDC_IDLEUSEGLI 1639 +#define IDC_DISBABLEAUTOHERE 1640 +#define IDC_SCREENSAVER 1642 +#define IDC_LOCKED 1643 +#define IDC_IDLESHORT 1644 +#define IDC_IDLELONG 1645 +#define IDC_IDLE1STTIME 1646 +#define IDC_IDLE2NDTIME 1647 +#define IDC_IDLEPRIVATE 1649 +#define IDC_AASTATUS 1650 +#define IDC_AASHORTIDLE 1651 +#define IDC_AALONGSTATUS 1652 +#define IDC_AAPROTOCOL 1653 +#define IDC_AALONGIDLE 1656 +#define IDC_COURSTATUSLABEL 1657 +#define IDC_REQSTATUSLABEL 1658 +#define IDC_ENABLERECONNECT 1660 +#define IDC_RECONNECTSLIDER 1663 +#define IDC_NOTFATALERROR 1664 +#define IDC_RECONNECTWARNING 1665 +#define IDC_APPLYTOALL 1667 +#define IDC_KEEPMAINSTATUSOFFLINE 1671 +#define IDC_DISABLEIDLEMENU 1672 +#define IDC_HEREONSTATUSCHANGE 1673 +#define IDI_IDLE_HERE 10101 +#define IDI_IDLE_SHORT 10102 +#define IDI_IDLE_LONG 10103 +#define IDI_RECONNECT 10104 +#define ID_STATUS_OFFLINE 40071 +#define ID_STATUS_ONLINE 40072 +#define ID_STATUS_AWAY 40073 +#define ID_STATUS_DND 40074 +#define ID_STATUS_NA 40075 +#define ID_STATUS_OCCUPIED 40076 +#define ID_STATUS_FREECHAT 40077 +#define ID_STATUS_INVISIBLE 40078 +#define ID_STATUS_ONTHEPHONE 40079 +#define ID_STATUS_OUTTOLUNCH 40080 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 10104 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1016 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/!NotAdopted/SmartAutoAway/saa-res.rc b/plugins/!NotAdopted/SmartAutoAway/saa-res.rc new file mode 100644 index 0000000000..98549fa59b --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/saa-res.rc @@ -0,0 +1,238 @@ +//Microsoft Developer Studio generated resource script. +// + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "resource.h" +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1251) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPT_SMARTAUTOAWAY DIALOGEX 0, 0, 313, 247 +STYLE DS_FIXEDSYS | DS_CENTER | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CTEXT "Static",IDC_REQSTATUSLABEL,246,1,66,9,0,WS_EX_STATICEDGE + RTEXT "Requested Status:",IDC_STATIC,164,1,80,8 + CTEXT "Static",IDC_COURSTATUSLABEL,246,11,66,9,0,WS_EX_STATICEDGE + RTEXT "Current Status:",IDC_STATIC,181,12,63,8 + COMBOBOX IDC_AAPROTOCOL,8,1,65,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "",IDC_OPT_SAA_TAB,"SysTabControl32",0x0,20,23,273,216,0//WS_EX_ACCEPTFILES + PUSHBUTTON "Apply to all protocols",IDC_APPLYTOALL,76,1,81,12 +END + +IDD_OPT_SAA_AA DIALOGEX 0, 0, 256, 191 +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Short Idle",IDC_STATIC,0,0,256,93,BS_CENTER + CONTROL "Change my status mode to:",IDC_AASHORTIDLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,14,116,11 + COMBOBOX IDC_AASTATUS,132,13,75,12,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Only if my requested status is:",IDC_STATIC,0,32,256,61 + CONTROL "Online",ID_STATUS_ONLINE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,47,65,10 + CONTROL "Away",ID_STATUS_AWAY,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,60,65,10 + CONTROL "N/A",ID_STATUS_NA,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,72,65,10 + CONTROL "Invisible",ID_STATUS_INVISIBLE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,47,65,10 + CONTROL "Occupied",ID_STATUS_OCCUPIED,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,60,65,10 + CONTROL "DND",ID_STATUS_DND,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,72,65,13 + CONTROL "On the phone",ID_STATUS_ONTHEPHONE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,39,65,10 + CONTROL "Out to lunch",ID_STATUS_OUTTOLUNCH,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,52,65,10 + CONTROL "Free for chat",ID_STATUS_FREECHAT,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,66,65,10 + CONTROL "Offline",ID_STATUS_OFFLINE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,78,65,10 + GROUPBOX "Long Idle",IDC_STATIC,0,98,256,93,BS_CENTER + CONTROL "Change my status mode to:",IDC_AALONGIDLE,"Button",BS_AUTOCHECKBOX | BS_RIGHT | WS_TABSTOP,9,110,101,11 + COMBOBOX IDC_AALONGSTATUS,132,109,75,16,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Only if my requested status is:",IDC_STATIC,0,130,256,61 + CONTROL "Online",40088,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,145,65,10 + CONTROL "Away",40089,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,158,65,10 + CONTROL "N/A",40091,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,171,65,10 + CONTROL "Invisible",40094,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,145,65,10 + CONTROL "Occupied",40092,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,158,65,10 + CONTROL "DND",40090,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,172,65,10 + CONTROL "On the phone",40095,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,137,65,10 + CONTROL "Out to lunch",40096,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,150,65,10 + CONTROL "Free for chat",40093,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,163,65,10 + CONTROL "Offline",40087,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,176,65,10 +END + +IDD_OPT_SAA_RECONNECT DIALOGEX 0, 0, 256, 164 +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "",IDC_STATIC,0,0,256,114,BS_CENTER + CONTROL "reconnect after",IDC_ENABLERECONNECT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,9,150,10 + CONTROL "Slider2",IDC_RECONNECTSLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,1,22,253,10 + GROUPBOX "If my current status is:",IDC_STATIC,0,37,256,52,BS_CENTER + RTEXT "Too Fast!",IDC_RECONNECTWARNING,160,10,91,8,NOT WS_VISIBLE + CONTROL "Online",40104,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,47,65,10 + CONTROL "Away",40105,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,60,65,10 + CONTROL "N/A",40107,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,74,65,10 + CONTROL "Invisible",40110,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,47,65,10 + CONTROL "Occupied",40108,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,60,65,10 + CONTROL "DND",40106,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,74,65,10 + CONTROL "On the phone",40111,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,47,65,10 + CONTROL "Out to lunch",40112,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,60,65,10 + CONTROL "Free for chat",40109,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,74,65,10 + CONTROL "Do not reconnect after fatal error",IDC_NOTFATALERROR,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,96,133,10 + GROUPBOX "",IDC_STATIC,0,126,254,38 + CONTROL "Keep main status offline*",IDC_KEEPMAINSTATUSOFFLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,138,133,10 + LTEXT "* Setting this option may confuse other plugins",IDC_STATIC,9,150,200,8 +END + +IDD_OPT_SAA_IDLE DIALOGEX 0, 0, 256, 196 +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Idle",IDC_STATIC,0,0,255,142,BS_CENTER + CONTROL "Enable",IDC_IDLECHECK,"Button",BS_AUTOCHECKBOX |WS_TABSTOP,8,12,43,11 + CONTROL "If Windows is inactive",IDC_IDLEONWINDOWS,"Button",BS_AUTORADIOBUTTON,62,13,110,9 + CONTROL "If Miranda is inactive",IDC_IDLEONMIRANDA,"Button",BS_AUTORADIOBUTTON,62,37,104,9 + CONTROL "Use GetLastInputInfo()",IDC_IDLEUSEGLI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,75,24,87,9 + GROUPBOX "Force short idle if:",IDC_STATIC,0,54,129,38 + CONTROL "Screen Saver is running",IDC_SCREENSAVER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,65,111,9 + CONTROL "Workstation is Locked (2K/XP)",IDC_LOCKED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,78,113,9 + GROUPBOX "Inactivity times:",IDC_STATIC,128,54,127,38 + CONTROL "Short idle after",IDC_IDLESHORT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,137,65,59,9 + EDITTEXT IDC_IDLE1STTIME,206,63,16,12,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "Long idle after",IDC_IDLELONG,"Button",BS_AUTOCHECKBOX |WS_TABSTOP,137,78,59,9 + EDITTEXT IDC_IDLE2NDTIME,206,76,16,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "min.",IDC_STATIC,223,65,24,9 + LTEXT "min.",IDC_STATIC,223,78,23,9 + CONTROL "Do not share my idle info.",IDC_IDLEPRIVATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,63,97,151,10 + CONTROL "Do not set ""Not Idle"" automaticaly",IDC_DISBABLEAUTOHERE,"Button",BS_AUTOCHECKBOX |WS_TABSTOP,63,111,158,10 + CONTROL "Set ""Not Idle"" on manual status change",IDC_HEREONSTATUSCHANGE,"Button",BS_AUTOCHECKBOX |WS_TABSTOP,63,125,158,10 + GROUPBOX "Simulate Idle",IDC_STATIC,0,146,255,50 + PUSHBUTTON "Be Not Idle",IDC_IDLEBUTTON,29,162,55,12 + PUSHBUTTON "Be Short Idle",IDC_IDLEBUTTON+1,95,162,55,12 + PUSHBUTTON "Be Long Idle",IDC_IDLEBUTTON+2,161,162,55,12 + CONTROL "Disable Idle menu. (restart is required)",IDC_DISABLEIDLEMENU,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,63,179,158,10 +END + +IDD_OPT_SAA_IDLEMESSAGES DIALOGEX 0, 0, 251, 166 +STYLE DS_FIXEDSYS | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "",IDC_IDLEGROUP_HERE,6,3,239,63 + CONTROL "Use:",IDC_IDLEMSGHERE_THIS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,14,31,10 + EDITTEXT IDC_IDLEMSGHERE,70,14,169,21,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL + CONTROL "",IDC_ENABLERESTOREMSG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,39,230,10 + CONTROL "Slider2",IDC_RESTOREMSGSLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,8,51,236,10 + GROUPBOX "",IDC_IDLEGROUP_SHORT,6,68,239,36 + CONTROL "Use:",IDC_IDLEMSGSHORT_THIS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,80,31,10 + EDITTEXT IDC_IDLEMSGSHORT,70,79,169,21,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL + GROUPBOX "",IDC_IDLEGROUP_LONG,6,108,239,36 + CONTROL "Use:",IDC_IDLEMSGLONG_THIS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,119,31,10 + EDITTEXT IDC_IDLEMSGLONG,70,119,169,21,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL + LTEXT "",IDC_PROTODONOTSUPPORT,12,148,204,18 + PUSHBUTTON "?",IDC_VARIABLES,223,149,22,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO MOVEABLE PURE +BEGIN + IDD_OPT_SMARTAUTOAWAY, DIALOG + BEGIN + BOTTOMMARGIN, 246 + END + + IDD_OPT_SAA_AA, DIALOG + BEGIN + VERTGUIDE, 9 + VERTGUIDE, 84 + VERTGUIDE, 169 + HORZGUIDE, 19 + HORZGUIDE, 32 + HORZGUIDE, 39 + HORZGUIDE, 52 + HORZGUIDE, 65 + HORZGUIDE, 78 + HORZGUIDE, 93 + HORZGUIDE, 98 + HORZGUIDE, 115 + HORZGUIDE, 130 + HORZGUIDE, 137 + HORZGUIDE, 150 + HORZGUIDE, 163 + HORZGUIDE, 176 + END + + IDD_OPT_SAA_RECONNECT, DIALOG + BEGIN + VERTGUIDE, 9 + VERTGUIDE, 84 + VERTGUIDE, 169 + HORZGUIDE, 14 + HORZGUIDE, 37 + HORZGUIDE, 52 + HORZGUIDE, 65 + HORZGUIDE, 79 + END + + IDD_OPT_SAA_IDLE, DIALOG + BEGIN + VERTGUIDE, 8 + HORZGUIDE, 17 + HORZGUIDE, 54 + HORZGUIDE, 67 + END + + IDD_OPT_SAA_IDLEMESSAGES, DIALOG + BEGIN + VERTGUIDE, 6 + VERTGUIDE, 12 + VERTGUIDE, 70 + VERTGUIDE, 245 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_IDLE_HERE ICON DISCARDABLE "here.ico" +IDI_IDLE_SHORT ICON DISCARDABLE "short.ico" +IDI_IDLE_LONG ICON DISCARDABLE "long.ico" +IDI_RECONNECT ICON DISCARDABLE "reconnect.ico" +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/!NotAdopted/SmartAutoAway/saa.cpp b/plugins/!NotAdopted/SmartAutoAway/saa.cpp new file mode 100644 index 0000000000..a36e5b5981 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/saa.cpp @@ -0,0 +1,130 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2006 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "saa.h" + +int InitVariables( WPARAM wParam, LPARAM lParam ); + + +PLUGINLINK *pluginLink; +HINSTANCE g_hInst; + +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), +#ifdef AALOG + SECTIONNAME " - Debug", +#else + SECTIONNAME, +#endif +#include "version.txt" + UNICODE_AWARE, + DEFMOD_RNDAUTOAWAY, // replace internal version (if any) +#if defined( _UNICODE ) + {0xec29e895,0x9f97,0x4cb1,{0xac, 0x9b, 0xb1, 0xae, 0x88, 0x25, 0x8b, 0x4a} /* EC29E895-9F97-4cb1-AC9B-B1AE88258B4A */} +#else + {0x19c5be89,0xf7e3,0x4632,{0xa1, 0x25, 0x15, 0xf3, 0x84, 0xcd, 0x0c, 0xd3} /* 19c5be89-f7e3-4632-a125-15f384cd0cd3 */} +#endif +}; + +static HMODULE hUxTheme = 0; +BOOL (WINAPI *enableThemeDialogTexture)(HANDLE, DWORD) = 0; + + +extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + g_hInst = hinstDLL; + return TRUE; +} +static char description[1023]; + +#ifdef AALOG + static BOOL warningShown = 0; +#endif +static bool isNewMiranda = false; +extern "C" __declspec(dllexport) PLUGININFOEX *MirandaPluginInfo(DWORD mirandaVersion) +{ + + sprintf(description,"Highly configurable AutoAway/Idle/Reconnect system"); +#ifdef AALOG + sprintf(description,"%s\r\nThis is the debug version. It will make a lot of noise through Netlib log",description); + if (!warningShown) { + MessageBoxA(0,description,pluginInfo.shortName,MB_ICONINFORMATION); + warningShown = 1; + } +#endif + if ((mirandaVersion>=0x00030400) && (!isNewMiranda)) { + sprintf(description,"%s\r\n%s",description,"Miranda %d.%d.%d.%d has build-in \"Idle\" support and it is highly advisable to suppress it by putting SAANI.dll in plugins directory."); + sprintf(description,description, // Yes, I realize this is strange approach... + mirandaVersion>>24&0xFF, + mirandaVersion>>16&0xFF, + mirandaVersion>>8&0xFF, + mirandaVersion&0xFF + ); + }; + sprintf(description,"%s\r\n[Build %s %s]",description, __DATE__,__TIME__); + pluginInfo.description = description; + if ( mirandaVersion < PLUGIN_MAKE_VERSION( 0,7,0,17 )) pluginInfo.cbSize = sizeof( PLUGININFO ); + return &pluginInfo; +} + +extern "C" __declspec(dllexport) PLUGININFOEX * MirandaPluginInfoEx(DWORD mirandaVersion) +{ + isNewMiranda=true; + return MirandaPluginInfo(mirandaVersion); +} + +extern "C" __declspec(dllexport) const MUUID interfaces[] = {MIID_AUTOAWAY, MIID_IDLE, MIID_LAST}; +extern "C" __declspec(dllexport) const MUUID * MirandaPluginInterfaces(void) +{ + return interfaces; +} + +extern "C" int __declspec(dllexport) Load(PLUGINLINK * link) +{ + pluginLink = link; + LoadAutoAwayModule(); + hUxTheme = GetModuleHandle(_T("uxtheme.dll")); + if(hUxTheme) + enableThemeDialogTexture = (BOOL (WINAPI *)(HANDLE, DWORD))GetProcAddress(hUxTheme, "EnableThemeDialogTexture"); + return 0; +} + +extern "C" int __declspec(dllexport) Unload(void) +{ +// AutoAwayShutdown(0,0); +//#ifdef AALOG +// CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"Killing Timer"); +//#endif +// KillTimer(NULL, hIdleTimer); +//#ifdef AALOG +// CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"DestroyHookableEvent(hIdleEvent)"); +//#endif +// DestroyHookableEvent(hIdleEvent); + + if(hUxTheme != 0) + FreeLibrary(hUxTheme); + + return 1; //if 1 we dont want to shutdown because we have hooked ME_SYSTEM_SHUTDOWN +} + + diff --git a/plugins/!NotAdopted/SmartAutoAway/saa.dsp b/plugins/!NotAdopted/SmartAutoAway/saa.dsp new file mode 100644 index 0000000000..949d67f78f --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/saa.dsp @@ -0,0 +1,291 @@ +# Microsoft Developer Studio Project File - Name="saa" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=saa - Win32 Debug Unicode +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "saa.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "saa.mak" CFG="saa - Win32 Debug Unicode" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "saa - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "saa - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "saa - Win32 Logging" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "saa - Win32 Debug Unicode" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "saa - Win32 Release Unicode" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "saa - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleasePlugin" +# PROP Intermediate_Dir "ReleasePlugin" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SAA_EXPORTS" /YX /FD /c +# ADD CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x402 /d "NDEBUG" +# ADD RSC /l 0x417 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /machine:I386 /out:"../../bin/release/plugins/saa.dll" /FILEALIGN:0x200 +# SUBTRACT LINK32 /pdb:none +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Cmds=upx --best --lzma --force ../../bin/release/plugins/saa.dll +# End Special Build Tool + +!ELSEIF "$(CFG)" == "saa - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "saa___Win32_Debug" +# PROP BASE Intermediate_Dir "saa___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugPlugin" +# PROP Intermediate_Dir "DebugPlugin" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SAA_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x402 /d "_DEBUG" +# ADD RSC /l 0x417 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /debug /machine:I386 /out:"../../Bin/debug/Plugins/saa.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "saa - Win32 Logging" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "saa___Win32_Logging" +# PROP BASE Intermediate_Dir "saa___Win32_Logging" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Logging" +# PROP Intermediate_Dir "Logging" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O1 /D "SAA_PLUGIN" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O1 /I "../../include" /D "SAA_PLUGIN" /D "AALOG" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x402 /d "NDEBUG" +# ADD RSC /l 0x417 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /machine:I386 /out:"../../bin/release/plugins/saa.dll" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /machine:I386 /out:"../../bin/logging/plugins/saa.dll" +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Cmds=upx --best --lzma --force ../../bin/logging/plugins/saa.dll +# End Special Build Tool + +!ELSEIF "$(CFG)" == "saa - Win32 Debug Unicode" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "saa___Win32_Debug_Unicode" +# PROP BASE Intermediate_Dir "saa___Win32_Debug_Unicode" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_Unicode" +# PROP Intermediate_Dir "Debug_Unicode" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "UNICODE" /D "_USRDLL" /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x417 /d "_DEBUG" +# ADD RSC /l 0x417 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /debug /machine:I386 /out:"../../Bin/debug/Plugins/saa.dll" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /debug /machine:I386 /out:"../../Bin/debug Unicode/Plugins/saa.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "saa - Win32 Release Unicode" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "saa___Win32_Release_Unicode" +# PROP BASE Intermediate_Dir "saa___Win32_Release_Unicode" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_Unicode" +# PROP Intermediate_Dir "Release_Unicode" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /c +# ADD CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "UNICODE" /D "_USRDLL" /FR /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x417 /d "NDEBUG" +# ADD RSC /l 0x417 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /machine:I386 /out:"../../bin/release/plugins/saa.dll" /FILEALIGN:0x200 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /machine:I386 /out:"../../bin/Release Unicode/plugins/saa.dll" /FILEALIGN:0x200 +# SUBTRACT LINK32 /pdb:none +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Cmds=upx --best --force ../../bin/"Release Unicode"/plugins/saa.dll +# End Special Build Tool + +!ENDIF + +# Begin Target + +# Name "saa - Win32 Release" +# Name "saa - Win32 Debug" +# Name "saa - Win32 Logging" +# Name "saa - Win32 Debug Unicode" +# Name "saa - Win32 Release Unicode" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\aa_utils.cpp +# End Source File +# Begin Source File + +SOURCE=.\autoaway.cpp +# End Source File +# Begin Source File + +SOURCE=.\dlgproc.cpp +# End Source File +# Begin Source File + +SOURCE=.\globals.cpp +# End Source File +# Begin Source File + +SOURCE=.\idle.cpp + +!IF "$(CFG)" == "saa - Win32 Release" + +!ELSEIF "$(CFG)" == "saa - Win32 Debug" + +# SUBTRACT CPP /YX + +!ELSEIF "$(CFG)" == "saa - Win32 Logging" + +!ELSEIF "$(CFG)" == "saa - Win32 Debug Unicode" + +# SUBTRACT BASE CPP /YX +# SUBTRACT CPP /YX + +!ELSEIF "$(CFG)" == "saa - Win32 Release Unicode" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\idleMenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\idleMessages.cpp +# End Source File +# Begin Source File + +SOURCE=.\reconnect.cpp +# End Source File +# Begin Source File + +SOURCE=.\saa.cpp +# End Source File +# Begin Source File + +SOURCE=.\saamain.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\globals.h +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\here.ico +# End Source File +# Begin Source File + +SOURCE=.\long.ico +# End Source File +# Begin Source File + +SOURCE=.\reconnect.ico +# End Source File +# Begin Source File + +SOURCE=".\saa-res.rc" +# End Source File +# Begin Source File + +SOURCE=.\short.ico +# End Source File +# End Group +# End Target +# End Project diff --git a/plugins/!NotAdopted/SmartAutoAway/saa.dsw b/plugins/!NotAdopted/SmartAutoAway/saa.dsw new file mode 100644 index 0000000000..d39bc38701 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/saa.dsw @@ -0,0 +1,41 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "saa"=".\saa.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "saani"=".\saani.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/plugins/!NotAdopted/SmartAutoAway/saa.h b/plugins/!NotAdopted/SmartAutoAway/saa.h new file mode 100644 index 0000000000..b59f155202 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/saa.h @@ -0,0 +1 @@ +#include "globals.h" diff --git a/plugins/!NotAdopted/SmartAutoAway/saamain.cpp b/plugins/!NotAdopted/SmartAutoAway/saamain.cpp new file mode 100644 index 0000000000..0dee323c28 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/saamain.cpp @@ -0,0 +1,415 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2006 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "globals.h" + +#ifdef SAA_PLUGIN + struct MM_INTERFACE memoryManagerInterface; +#endif + +HANDLE hService[5]; +HANDLE hHooks[6]; + +#ifndef SAA_PLUGIN + int LoadIdleModule(void){return 0;} + int UnloadIdleModule(void){return 0;} +#endif + +int LoadAutoAwayModule(void) +{ + +#ifdef SAA_PLUGIN + memset(&memoryManagerInterface, 0, sizeof(memoryManagerInterface)); + memoryManagerInterface.cbSize = sizeof(memoryManagerInterface); + CallService(MS_SYSTEM_GET_MMI, 0, (LPARAM) &memoryManagerInterface); +#endif + + hHooks[0] = HookEvent(ME_SYSTEM_MODULESLOADED,InitVariables); + hIdleEvent = CreateHookableEvent(ME_IDLE_CHANGED); + hHooks[1] = HookEvent(ME_OPT_INITIALISE,AutoAwayOptInitialise); + MyGetLastInputInfo=(BOOL (WINAPI *)(PLASTINPUTINFO)) GetProcAddress( GetModuleHandleA("user32"),"GetLastInputInfo" ); + // load settings into live ones + idleOpts = idleOptsPerm=DBGetContactSettingDword(NULL, AA_MODULE,AA_IDLEOPTIONS,idleOptsDefault); +// if ((idleOptsPerm&IdleSuppressIdleMenu)==0) AddIdleMenu(); +// idleCheckPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLECHECK, 0); +// idleMethodPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLEMETHOD, 0); +// idleGLIPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLEGLI, 1); +// idleTimeFirstPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLETIME1ST, 10); +// idleTimeSecondPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLETIME2ND, 30); +// idleTimeFirstOnPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLETIME1STON, 0); +// idleTimeSecondOnPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLETIME2NDON, 0); +// idleOnSaverPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLEONSAVER, 0); +// idleOnLockPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLEONLOCK, 0); +// idlePrivatePerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLEPRIVATE, 0); + hService[0] = CreateServiceFunction(MS_IDLE_GETIDLEINFO, IdleGetInfo); + + hHooks[2] = HookEvent(ME_SYSTEM_SHUTDOWN,AutoAwayShutdown); + hHooks[3] = HookEvent(ME_IDLE_CHANGED, AutoAwayEvent); + hHooks[4] = HookEvent(ME_CLIST_STATUSMODECHANGE,StatusModeChangeEvent); + hHooks[5] = HookEvent(ME_PROTO_ACK, ProtoAckEvent); + + hService[1] = CreateServiceFunction(AA_IDLE_BENOTIDLESERVICE,(MIRANDASERVICE)idleServiceNotIdle); + hService[2] = CreateServiceFunction(AA_IDLE_BESHORTIDLESERVICE,(MIRANDASERVICE)idleServiceShortIdle); + hService[3] = CreateServiceFunction(AA_IDLE_BELONGIDLESERVICE,(MIRANDASERVICE)idleServiceLongIdle); + hService[4] = CreateServiceFunction(AA_IDLE_RECONNECTSERVICE,(MIRANDASERVICE)reconnectService); + return 0; +} + +int InitVariables( WPARAM wParam, LPARAM lParam ) +{ + int j=0; + int i=0; + localeID = CallService(MS_LANGPACK_GETLOCALE,0,0); + if (localeID==CALLSERVICE_NOTFOUND) localeID=LOCALE_USER_DEFAULT; + codePage = CallService(MS_LANGPACK_GETCODEPAGE,0,0); + if (codePage==CALLSERVICE_NOTFOUND) codePage=CP_ACP; +#ifdef UNICODE + HasAwayMessageW = (ServiceExists(MS_AWAYMSG_GETSTATUSMSGW)!=0); +#endif + if (ServiceExists(MS_HOTKEY_REGISTER)){ + for (i=0;i<4;i++) { + CallService(MS_HOTKEY_REGISTER, 0, (LPARAM) &hotkeydescs[i]); + } + } + + +#ifdef AALOG + { + NETLIBUSER nlu = { 0 }; + nlu.cbSize = sizeof(nlu); + nlu.szSettingsModule = "SAA"; + nlu.flags=NUF_NOOPTIONS | NUF_NOHTTPSOPTION; + nlu.szDescriptiveName = Translate(SECTIONNAME " Module"); + hNetlib = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) & nlu); + } + { + SYSTEMTIME st={0}; + int drift; + char str[32]; + char log[1024]; + char target[1024]; + drift = GetTimeZone(str); + GetLastActiveLocalTime(&st,0); + sprintf(log,"Now is %02d/%02d/%02d %02d:%02d:%02d %s (%02d:%02d)", + st.wYear, st.wMonth, st.wDay, + st.wHour, st.wMinute, st.wSecond,str, + div(drift,60).quot,drift<0?-div(drift,60).rem:div(drift,60).rem); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); + GetLastActiveLocalTime(&st,24*60*60*1000); + sprintf(log,"1 day ago was %02d/%02d/%02d %02d:%02d:%02d %s (%02d:%02d)", + st.wYear, st.wMonth, st.wDay, + st.wHour, st.wMinute, st.wSecond,str, + div(drift,60).quot,drift<0?-div(drift,60).rem:div(drift,60).rem); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); + ParseString("%Y-%m-%d %H:%M:%S",target,1023); + sprintf(log,"Testing ParseString: %s",target); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); + ParseString("%E/%d/%y %W %h:%M:%S %p",target,1023); + sprintf(log,"Testing ParseString: %s",target); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); + ParseString("%w %% %Z (%z)%n%L%b%l%b%K%b%k",target,1023); + sprintf(log,"Testing ParseString: %s",target); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); + } +#endif + + CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM)&protoCount,(LPARAM)&proto); + reqStatus = (int *)mir_alloc((protoCount)*sizeof(reqStatus[0])); + courStatus = (int *)mir_alloc((protoCount)*sizeof(courStatus[0])); + courAwayStatus = (int *)mir_alloc((protoCount)*sizeof(courStatus[0])); + protoModes = (int *)mir_alloc((protoCount)*sizeof(protoModes[0])); + messCaps = (int *)mir_alloc((protoCount)*sizeof(messCaps[0])); + + awayStatuses=(short int *)mir_alloc((protoCount)*sizeof(awayStatuses[0])); + onlyIfBits=(long int *)mir_alloc((protoCount)*sizeof(onlyIfBits[0])); + awayStatusesPerm=(short int *)mir_alloc((protoCount)*sizeof(awayStatuses[0])); + onlyIfBitsPerm=(long int *)mir_alloc((protoCount)*sizeof(onlyIfBits[0])); + + reconnectOpts=(long int *)mir_alloc((protoCount)*sizeof(reconnectOpts[0])); + reconnectOptsPerm=(long int *)mir_alloc((protoCount)*sizeof(reconnectOptsPerm[0])); + protoOfflineTimes=(unsigned int *)mir_alloc((protoCount)*sizeof(protoOfflineTimes[0])); + protoStatus=(int *)mir_alloc((protoCount)*sizeof(protoStatus[0])); + + idleMessOpts=(long int *)mir_alloc((protoCount)*sizeof(idleMessOpts[0])); + idleMessOptsPerm=(long int *)mir_alloc((protoCount)*sizeof(idleMessOptsPerm[0])); + + mesgHere = (TCHAR**)mir_alloc(protoCount * sizeof(mesgHere[0])); + mesgHerePerm = (TCHAR**)mir_alloc(protoCount * sizeof(mesgHerePerm[0])); + mesgShort = (TCHAR**)mir_alloc(protoCount * sizeof(mesgShort[0])); + mesgShortPerm = (TCHAR**)mir_alloc(protoCount * sizeof(mesgShortPerm[0])); + mesgLong = (TCHAR**)mir_alloc(protoCount * sizeof(mesgLong[0])); + mesgLongPerm = (TCHAR**)mir_alloc(protoCount * sizeof(mesgLongPerm[0])); + + #ifdef UNICODE + protoHasAwayMessageW=(bool *)mir_alloc(protoCount * sizeof(protoHasAwayMessageW[0])); + #endif + + isWaitingForRestoreStatusMessage = (int *)mir_alloc((protoCount)*sizeof(isWaitingForRestoreStatusMessage[0])); + + for (j = 0 ; j < protoCount ; j++) { + int caps=0; +#ifdef AALOG + { + char log[1024]; + sprintf(log,"Checking protocol index %d out of %d...",j+1,protoCount); + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); + } +#endif + reqStatus[j] = 0; + courStatus[j] = ID_STATUS_OFFLINE; + protoModes[j] =0; + isWaitingForRestoreStatusMessage[j] = 0; + caps = CallProtoService(proto[j]->szName, PS_GETCAPS, PFLAGNUM_2, 0); + messCaps[j] = (CallProtoService(proto[j]->szName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)? + CallProtoService(proto[j]->szName, PS_GETCAPS, PFLAGNUM_3, 0):0; +#ifdef AALOG + { + char log[1024]; + if (messCaps[j]){ + int i; + sprintf(log,"StatusMessages Caps for %s:", + proto[j]->szName + ); + for (i=0;i<10;i++){ + int statusFlag = Proto_Status2Flag(aa_Status[i]); + if (statusFlag & messCaps[j]){ + sprintf(log,"%s %s",log,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, aa_Status[i], 0)); + } + } + } else { + sprintf(log,"%s cannot set StatusMessage", + proto[j]->szName); + } + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log); + } +#endif + for (i = 0; iszName); +// MessageBox( 0,str,proto[j]->szName,0); + onlyIfBits[j]= DBGetContactSettingDword(NULL,AA_MODULE,str,-1); + if (onlyIfBits[j]==-1){ +// onlyIfBits[j] = (((protoModes[j]<<16)|(protoModes[j])) & aa_OnlyIfBitsDefault); + onlyIfBits[j] = aa_OnlyIfBitsDefault; + DBWriteContactSettingDword(NULL,AA_MODULE,str,onlyIfBits[j]); + } + onlyIfBitsPerm[j]=onlyIfBits[j]; +#ifdef UNICODE + sprintf(str,"%s%s",proto[j]->szName,PS_SETAWAYMSGW); + protoHasAwayMessageW[j]=(ServiceExists(str)!=0); +#endif +// sprintf(str,AA_BITSLONGONLYIF,proto[j]->szName); +//// MessageBox( 0,str,proto[j]->szName,0); +// if (!DBGetContactSettingWord(NULL,AA_MODULE,str,0)) +// DBWriteContactSettingWord(NULL,AA_MODULE,str,(protoModes[j] & aa_OnlyIfBitsDefault)|known); + sprintf(str,AA_AWAYSTATUSES,proto[j]->szName); +// MessageBox( 0,str,proto[j]->szName,0); + awayStatuses[j] = DBGetContactSettingWord(NULL,AA_MODULE,str,-1); + if (awayStatuses[j] ==-1){ + int old = DBGetContactSettingWord(NULL,AA_OLDMODULE,AA_SHORTSTATUS,-1); + int s = StatusToProtoIndex(((old==-1)?ID_STATUS_AWAY:OldIndexToStatus(old)),protoModes[j]); + int l = 0; + int comb = 0; + old = DBGetContactSettingWord(NULL,AA_OLDMODULE,AA_LONGSTATUS,-1); + l = StatusToProtoIndex(((old==-1)?ID_STATUS_NA:OldIndexToStatus(old)),protoModes[j]); + comb = (l<<4)|s; + old = DBGetContactSettingByte(NULL,AA_OLDMODULE,AA_USESHORT,-1); + if (s) comb |= ((old==-1)?1<<8:(old==1)<<8); + old = DBGetContactSettingByte(NULL,AA_OLDMODULE,AA_USELONG,-1); + if (l) comb |= ((old==-1)?1<<9:(old==1)<<9); +// comb |= (1<<15); + awayStatuses[j]=comb; + DBWriteContactSettingWord(NULL,AA_MODULE,str,(WORD)awayStatuses[j]); + } + awayStatusesPerm[j] = awayStatuses[j]; + + sprintf(str,AA_LASTREQUESTEDSTATUS,proto[j]->szName); //get last requested status + reqStatus[j] = DBGetContactSettingWord(NULL,AA_MODULE,str,ID_STATUS_ONLINE); //default: online + + sprintf(str,AA_RECONNECTOPTS,proto[j]->szName); //get reconnect options status + reconnectOpts[j] = DBGetContactSettingDword(NULL,AA_MODULE,str,aa_ReconnectOptsDefault); + reconnectOptsPerm[j] = reconnectOpts[j]; + protoStatus[j] = 0; + protoOfflineTimes[j] = 0; + mesgHere[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1)); + mesgHerePerm[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1)); + mesgShort[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1)); + mesgShortPerm[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1)); + mesgLong[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1)); + mesgLongPerm[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1)); + + if (messCaps[j]){ + DBVARIANT dbv; + sprintf(str,idleMsgOptionsName,proto[j]->szName); + idleMessOptsPerm[j] = idleMessOpts[j] = DBGetContactSettingDword(NULL,AA_MODULE,str,idleMsgOptionsDefault); + + sprintf(str,idleMsgOptionsTextHere,proto[j]->szName); + if(DBGetContactSettingTString(NULL,AA_MODULE,str,&dbv)==0) { + _tcsncpy(mesgHere[j],dbv.ptszVal,maxMessageLength); + mesgHere[j][maxMessageLength]=0; + DBFreeVariant(&dbv); + } else _tcscpy(mesgHere[j],messHereDefault); + if(!_tcscmp(mesgHere[j],messHereDefaultOld)) _tcscpy(mesgHere[j],messHereDefault); + _tcscpy(mesgHerePerm[j],mesgHere[j]); + + sprintf(str,idleMsgOptionsTextShort,proto[j]->szName); + if(DBGetContactSettingTString(NULL,AA_MODULE,str,&dbv)==0) { + _tcsncpy(mesgShort[j],dbv.ptszVal,maxMessageLength); + mesgShort[j][maxMessageLength]=0; + DBFreeVariant(&dbv); + } else _tcscpy(mesgShort[j],messShortDefault); + if(!_tcscmp(mesgShort[j],messShortDefaultOld)) _tcscpy(mesgShort[j],messShortDefault); + _tcscpy(mesgShortPerm[j],mesgShort[j]); + + sprintf(str,idleMsgOptionsTextLong,proto[j]->szName); + if(DBGetContactSettingTString(NULL,AA_MODULE,str,&dbv)==0) { + _tcsncpy(mesgLong[j],dbv.ptszVal,maxMessageLength); + mesgLong[j][maxMessageLength]=0; + DBFreeVariant(&dbv); + } else _tcscpy(mesgLong[j],messLongDefault); + if(!_tcscmp(mesgLong[j],messLongDefaultOld)) _tcsncpy(mesgLong[j],messLongDefault,maxMessageLength); + _tcsncpy(mesgLongPerm[j],mesgLong[j],maxMessageLength); +// sprintf(mesgHere[j],"%d: %s: %s",j,proto[j]->szName,"Test text"); + } else { + idleMessOptsPerm[j] = idleMessOpts[j] = 0; + mesgHerePerm[j] = mesgHere[j] = mesgShortPerm[j] = mesgShort[j] = mesgLongPerm[j] = mesgLong[j] = NULL; + } + } + } +#ifdef AALOG + { + char str[1024]=""; + for (j = 0 ; j < protoCount ; j++) { + int status; + sprintf(str,"%s\n%s Type:%d\nLastReqStatus: %s\n",str,proto[j]->szName,proto[j]->type,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)reqStatus[j], 0)); + i=1; + while(status=StatusByProtoIndex(protoModes[j],i)){ + sprintf(str,"%s %d. %s\n",str,i,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)status, 0)); + i++; + } +// IsStatusBitSet(aa_Status[i],protoModes[j])?"":"not", +// CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)aa_Status[i], 0), +// IsStatusBitSet(aa_Status[i],aa_OnlyIfBitsDefault)?"n":"ff" +// ); + + } + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); + } +#endif +//something is hapaning here on startup, if main status is not offline +//will move Notify hIdleEvent for later in the IdleTimer +// NotifyEventHooks( hIdleEvent, 0, idleOpts&IdleBitsPrivate?IDF_PRIVACY:0 ); //Tell everyone we are here + FirstTick = 1; //we will wait 1 ticks of the timer before Forcing Awake +// FirstTick = 10; //we will wait 20 seconds before Forcing Awake + hIdleTimer=SetTimer(NULL, 0, 2000, IdleTimer); +// { +// char str[20000]=""; +// for (i=0;i<=101;i++){ +// char str1[128]; +// GetStringFromDelay(str1,GetReconnectDelayFromSlider(i)); +// sprintf(str,"%d\t%d\t%s",GetReconnectDelayFromSlider(i),i,str1); +// CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str); +// } +// } + if ((idleOptsPerm&IdleSuppressIdleMenu)==0) AddIdleMenu(); + if ((idleOptsPerm&IdleSuppressAutoHere)!=0) isCurrentlyIdle=DBGetContactSettingByte(NULL,AA_MODULE,AA_LASTIDLESTATUS,0);; + return 0; +} + +//#ifndef SAA_PLUGIN +int AutoAwayShutdown(WPARAM wParam,LPARAM lParam) +{ + int i; + +#ifdef AALOG + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"Killing Timer"); +#endif + KillTimer(NULL, hIdleTimer); + if (hHookIconsChanged){ + #ifdef AALOG + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"UnHooking hHookIconsChanged"); + #endif + UnhookEvent(hHookIconsChanged); + } +#ifdef AALOG + CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"DestroyHookableEvent(hIdleEvent)"); +#endif + for (i=0; i +#include + +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFO), + "Smart Auto Away NI", +#include "version.txt" + 0, + DEFMOD_RNDIDLE, // replace internal version (if any) + { 0x91bb7ad7,0x7ed8,0x40b9,{0xb1, 0x50, 0x3f, 0x37, 0x6b, 0x6b, 0x67, 0xfe}/* 91bb7ad7-7ed8-40b9-b150-3f376b6b67fe */} +}; + + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + return TRUE; +} +static char description[1023]; +sprintf(char *, const char *, ...); +__declspec(dllexport) PLUGININFOEX *MirandaPluginInfo(DWORD mirandaVersion) +{ + sprintf(description,"%s","Just to suppress the build-in \"Idle\" module"); + if (mirandaVersion<0x00030400) { + sprintf(description,"%s\r\n%s",description,"Miranda %d.%d.%d.%d has no build-in \"Idle\" support and this plugin is useless"); + sprintf(description,description, // Yes, I realize this is strange approach... + mirandaVersion>>24&0xFF, + mirandaVersion>>16&0xFF, + mirandaVersion>>8&0xFF, + mirandaVersion&0xFF + ); + } + sprintf(description,"%s\r\n[Build %s %s]",description, __DATE__,__TIME__); + pluginInfo.description = description; + return &pluginInfo; +} +__declspec(dllexport) PLUGININFOEX * MirandaPluginInfoEx(DWORD mirandaVersion) +{ + //return 0; + pluginInfo.cbSize = sizeof( PLUGININFOEX ); + return MirandaPluginInfo(mirandaVersion); +} + +extern "C" __declspec(dllexport) const MUUID interfaces[] = {MIID_IDLE, MIID_LAST}; +__declspec(dllexport) const MUUID * MirandaPluginInterfaces(void) +{ + return interfaces; +} + +int __declspec(dllexport) Load(PLUGINLINK * link) +{ + return 0; +} + +int __declspec(dllexport) Unload(void) +{ +// AutoAwayShutdown(0,0); + return 0; //if 1 we dont want to shutdown because we have hooked ME_SYSTEM_SHUTDOWN +} + diff --git a/plugins/!NotAdopted/SmartAutoAway/saani.dsp b/plugins/!NotAdopted/SmartAutoAway/saani.dsp new file mode 100644 index 0000000000..f36ee7738f --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/saani.dsp @@ -0,0 +1,107 @@ +# Microsoft Developer Studio Project File - Name="saani" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=saani - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "saani.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "saani.mak" CFG="saani - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "saani - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "saani - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "saani - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleasePlugin" +# PROP BASE Intermediate_Dir "ReleasePlugin" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleasePlugin" +# PROP Intermediate_Dir "ReleasePlugin" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SAANI_EXPORTS" /YX /FD /c +# ADD CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AALOG" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x402 /d "NDEBUG" +# ADD RSC /l 0x402 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"../../bin/release/plugins/saani.dll" + +!ELSEIF "$(CFG)" == "saani - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugPlugin" +# PROP BASE Intermediate_Dir "DebugPlugin" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugPlugin" +# PROP Intermediate_Dir "DebugPlugin" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SAANI_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "SAANI_EXPORTS" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x402 /d "_DEBUG" +# ADD RSC /l 0x402 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"../../Bin/debug/Plugins/saani.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "saani - Win32 Release" +# Name "saani - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\saani.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/plugins/!NotAdopted/SmartAutoAway/short.ico b/plugins/!NotAdopted/SmartAutoAway/short.ico new file mode 100644 index 0000000000..32817713fa Binary files /dev/null and b/plugins/!NotAdopted/SmartAutoAway/short.ico differ diff --git a/plugins/!NotAdopted/SmartAutoAway/version.txt b/plugins/!NotAdopted/SmartAutoAway/version.txt new file mode 100644 index 0000000000..ddbd1c8713 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoAway/version.txt @@ -0,0 +1,7 @@ + PLUGIN_MAKE_VERSION(0, 0, 3, 3), + "", + "YB", + "y_b" /* these */ "@" /* fucking spammers */ "saaplugin.no-ip.info" /* gather everything */, + "© 2005-2009 YB; 2000-2006 Miranda-IM", + "http://saaplugin.no-ip.info/", + diff --git a/plugins/!NotAdopted/SmartAutoReplier/ActionsHandler.cpp b/plugins/!NotAdopted/SmartAutoReplier/ActionsHandler.cpp new file mode 100644 index 0000000000..53bf7d2aea --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/ActionsHandler.cpp @@ -0,0 +1,31 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" +#include "actionshandler.h" + +CActionsHandler::CActionsHandler(void) +{ +} + +CActionsHandler::~CActionsHandler(void) +{ +} diff --git a/plugins/!NotAdopted/SmartAutoReplier/ActionsHandler.h b/plugins/!NotAdopted/SmartAutoReplier/ActionsHandler.h new file mode 100644 index 0000000000..cb2e996111 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/ActionsHandler.h @@ -0,0 +1,30 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +/// manager that executes actions... +class CActionsHandler +{ +public: + CActionsHandler(void); + ~CActionsHandler(void); +}; diff --git a/plugins/!NotAdopted/SmartAutoReplier/AggressiveOptimize.h b/plugins/!NotAdopted/SmartAutoReplier/AggressiveOptimize.h new file mode 100644 index 0000000000..076d96d920 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/AggressiveOptimize.h @@ -0,0 +1,59 @@ + +////////////////////////////// +// Version 1.10 +// Jan 23rd, 2000 +// Version 1.00 +// May 20th, 1999 +// Todd C. Wilson, Fresh Ground Software +// (todd@nopcode.com) +// This header file will kick in settings for Visual C++ 5 and 6 that will (usually) +// result in smaller exe's. +// The "trick" is to tell the compiler to not pad out the function calls; this is done +// by not using the /O1 or /O2 option - if you do, you implicitly use /Gy, which pads +// out each and every function call. In one single 500k dll, I managed to cut out 120k +// by this alone! +// The other two "tricks" are telling the Linker to merge all data-type segments together +// in the exe file. The relocation, read-only (constants) data, and code section (.text) +// sections can almost always be merged. Each section merged can save 4k in exe space, +// since each section is padded out to 4k chunks. This is very noticable with smaller +// exes, since you could have only 700 bytes of data, 300 bytes of code, 94 bytes of +// strings - padded out, this could be 12k of runtime, for 1094 bytes of stuff! +// Note that if you're using MFC static or some other 3rd party libs, you may get poor +// results with merging the readonly (.rdata) section - the exe may grow larger. +// To use this feature, define _MERGE_DATA_ in your project or before this header is used. +// With Visual C++ 5, the program uses a file alignement of 512 bytes, which results +// in a small exe. Under VC6, the program instead uses 4k, which is the same as the +// section size. The reason (from what I understand) is that 4k is the chunk size of +// the virtual memory manager, and that WinAlign (an end-user tuning tool for Win98) +// will re-align the programs on this boundary. The problem with this is that all of +// Microsoft's system exes and dlls are not tuned like this, and using 4k causes serious +// exe bloat. Very noticable for smaller programs. +// The "trick" for this is to use the undocumented FILEALIGN linker parm to change the +// padding from 4k to 1/2k, which results in a much smaller exe - anywhere from 20%-75% +// depending on the size. + + +#ifdef NDEBUG +#pragma message( "Using AggressiveOptimise" ) +// /Og (global optimizations), /Os (favor small code), /Oy (no frame pointers) +#pragma optimize("gsy",on) + +#pragma comment(linker,"/RELEASE") + +// Note that merging the .rdata section will result in LARGER exe's if you using +// MFC (esp. static link). If this is desirable, define _MERGE_RDATA_ in your project. +#ifdef _MERGE_RDATA_ +#pragma comment(linker,"/merge:.rdata=.data") +#endif // _MERGE_RDATA_ + +#pragma comment(linker,"/merge:.text=.data") +//#pragma comment(linker,"/merge:.reloc=.data") + +#if _MSC_VER >= 1000 +// Only supported/needed with VC6; VC5 already does 0x200 for release builds. +// Totally undocumented! And if you set it lower than 512 bytes, the program crashes. +// Either leave at 0x200 or 0x1000 +#pragma comment(linker,"/FILEALIGN:0x200") +#endif // _MSC_VER >= 1000 + +#endif // NDEBUG diff --git a/plugins/!NotAdopted/SmartAutoReplier/Crc32Static.cpp b/plugins/!NotAdopted/SmartAutoReplier/Crc32Static.cpp new file mode 100644 index 0000000000..89646ec0bb --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/Crc32Static.cpp @@ -0,0 +1,139 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" +#include "Crc32Static.h" + +// Static CRC table +DWORD CCrc32Static::s_arrdwCrc32Table[256] = +{ + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, +}; + +/// ctor +CCrc32Static::CCrc32Static() +{ +} + +/// dtor +CCrc32Static::~CCrc32Static() +{ +} + +/// calculating crc32 +inline void CCrc32Static::CalcCrc32(const BYTE byte, DWORD &dwCrc32) +{ + dwCrc32 = ((dwCrc32) >> 8) ^ s_arrdwCrc32Table[(byte) ^ ((dwCrc32) & 0x000000FF)]; +} + +/// getting crc32 for a string +DWORD CCrc32Static::StringCrc32(LPCTSTR szString, DWORD &dwCrc32) +{ + _ASSERTE(szString); + + DWORD dwErrorCode = NO_ERROR; + + dwCrc32 = 0xFFFFFFFF; + + try + { + while(*szString != _T('\0')) + { + CalcCrc32((BYTE)*szString, dwCrc32); + szString++; + } + } + catch(...) + { + // An unknown exception happened + dwErrorCode = ERROR_CRC; + } + + dwCrc32 = ~dwCrc32; + + return dwErrorCode; +} diff --git a/plugins/!NotAdopted/SmartAutoReplier/Crc32Static.h b/plugins/!NotAdopted/SmartAutoReplier/Crc32Static.h new file mode 100644 index 0000000000..4039822cae --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/Crc32Static.h @@ -0,0 +1,33 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +class CCrc32Static +{ +public: + CCrc32Static(); + virtual ~CCrc32Static(); + static DWORD StringCrc32(LPCTSTR szString, DWORD &dwCrc32); +protected: + static inline void CalcCrc32(const BYTE byte, DWORD &dwCrc32); + static DWORD s_arrdwCrc32Table[256]; +}; diff --git a/plugins/!NotAdopted/SmartAutoReplier/CrushLog.cpp b/plugins/!NotAdopted/SmartAutoReplier/CrushLog.cpp new file mode 100644 index 0000000000..639e4965ff --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/CrushLog.cpp @@ -0,0 +1,165 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" +#include "crushlog.h" +#include "shlobj.h" + +extern HINSTANCE hInst; +extern CCrushLog CRUSHLOGOBJ; + +/// init static members +TCHAR CCrushLog::m_szLogPath[MAX_PATH] = {0}; +CRITICAL_SECTION CCrushLog::m_critSect; + +/// ctor +CCrushLog::CCrushLog(void) +{/// nothing for now +BEGIN_PROTECT_AND_LOG_CODE +END_PROTECT_AND_LOG_CODE +} + +/// d'ctor +CCrushLog::~CCrushLog(void) +{ +BEGIN_PROTECT_AND_LOG_CODE +END_PROTECT_AND_LOG_CODE +} + +/// deinit internal data... +void CCrushLog::DeInit(void) +{ + DeleteCriticalSection(&m_critSect); +} + +/// init internal data... +void CCrushLog::Init(void) +{ + HRESULT hr = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, m_szLogPath); + size_t nLen = _tcslen(m_szLogPath); + + if (m_szLogPath[nLen - 1] != TEXT('\\')) + { + _tcscat(m_szLogPath, TEXT("\\Sar\\")); + } + else + { + _tcscat(m_szLogPath, TEXT("Sar\\")); + } + + CreateDirectory(m_szLogPath, NULL); + + _tcscat(m_szLogPath, LOG_FILENAME); + + /*if (_tcslen(m_szLogPath) == 0) /// let's get path to log file + { + GetModuleFileName(hInst, m_szLogPath, sizeof(m_szLogPath) * sizeof(TCHAR)); + + TCHAR *ptrPos = _tcsrchr(m_szLogPath, '\\'); + if (ptrPos) + { + ptrPos++; + _tcscpy(ptrPos, LOG_FILENAME); + } + else + { + _RPT0(_CRT_WARN, "CCrushLog::CCrushLog - unable to form path"); + } + }*/ + + InitializeCriticalSection(&m_critSect); +} + +/// provides forming data struct and saving it to log +void CCrushLog::InternalProtect(CHAR* FunctionName, CHAR* FileName, + CHAR* CompilationDate, INT LineNumber, + INT LastError) +{ + CRUSHLOG_ITEM item = {0}; + + item.CompilationDate = CompilationDate; + item.FileName = FileName; + item.FunctionName = FunctionName; + item.LineNumber = LineNumber; + item.LastError = LastError; + g_crushLog.SaveToLog(item); + + TCHAR tch[MAX_PATH * 3] = {0}; + _tcscpy(tch, TranslateTS(TEXT("Exception has occured please, analize or just send log file\n\r "))); + _tcscat(tch, CCrushLog::m_szLogPath); + _tcscat(tch, TranslateTS(TEXT("\r\n to developer."))); + + ::MessageBox (NULL, tch, TranslateTS(TEXT("Smart Auto Replier crash. Send the log file to http://shcherbyna.com/forum/viewforum.php?f=8")), MB_OK); +} + +/// saving log information +void CCrushLog::SaveToLog(CRUSHLOG_ITEM & item) +{ + EnterCriticalSection(&m_critSect); + + HANDLE hFile = NULL; + hFile = CreateFile (m_szLogPath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + + if (hFile == INVALID_HANDLE_VALUE) + { + LeaveCriticalSection(&m_critSect); + + return; + } + + { + DWORD dwRetVal = 0; + DWORD dw = GetFileSize(hFile, &dwRetVal); + SetFilePointer(hFile, dw, NULL, FILE_BEGIN); + } + + int nSize = strlen(item.CompilationDate); + nSize += strlen(item.FileName); + nSize += strlen(item.FunctionName); + nSize *= 2; + + CHAR *tsz = new CHAR[nSize]; + + if (tsz) + { + strcpy(tsz, ("******\n")); + strcat(tsz, item.CompilationDate); + strcat(tsz, ("\n")); + strcat(tsz, item.FileName); + strcat(tsz, ("\n")); + strcat(tsz, item.FunctionName); + strcat(tsz, ("\n")); + CHAR tchtemp[MAX_PATH] = {0}; + itoa(item.LineNumber, tchtemp, 10); + strcat(tsz, tchtemp); + strcat(tsz, ("\n")); + itoa(item.LastError, tchtemp, 10); + strcat(tsz, tchtemp); + strcat(tsz, ("\n")); + DWORD dw = 0; + WriteFile (hFile, tsz, strlen(tsz), &dw, NULL); + + delete tsz; + } + + CloseHandle (hFile); + LeaveCriticalSection(&m_critSect); +} diff --git a/plugins/!NotAdopted/SmartAutoReplier/CrushLog.h b/plugins/!NotAdopted/SmartAutoReplier/CrushLog.h new file mode 100644 index 0000000000..1a595d055b --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/CrushLog.h @@ -0,0 +1,54 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +/// crash item that is written in file... +typedef struct _CRUSHLOG_ITEM +{ + CHAR* CompilationDate; /// compilation date of the source file + CHAR* FileName; /// file name where exception has occured + CHAR* FunctionName; /// function name where exception has occured + INT LineNumber; /// line number + INT LastError; /// last error +}CRUSHLOG_ITEM, *PCRUSHLOG_ITEM; + +#define LOG_FILENAME TEXT("sarcrushes.log") + +/// class that handles all crushes +/// occured between BEGIN_LOG_AND_PRO.. and END_LOG.. +class CCrushLog +{ +public: /// ctors, dtors section... + CCrushLog(void); + ~CCrushLog(void); +public: + static void Init(void); /// inits internal data.. + static void DeInit(void); /// deinits internal data.. + static void SaveToLog(CRUSHLOG_ITEM & item); /// saves data to log file + static void InternalProtect(CHAR* FunctionName, CHAR* FileName, + CHAR* CompilationDate, INT LineNumber, + INT LastError); +public: + static TCHAR m_szLogPath[MAX_PATH]; /// path to log file +private: + static CRITICAL_SECTION m_critSect; /// sync object... +}; diff --git a/plugins/!NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.cpp b/plugins/!NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.cpp new file mode 100644 index 0000000000..0d76db3210 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.cpp @@ -0,0 +1,219 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" +#include "../resource.h" +#include "addruledlg.h" +#include "addruledlg.h" +#include "selectuserdlg.h" + +extern LPTSTR g_strPluginName; +extern CMessagesHandler *g_pMessHandler; +extern CCrushLog CRUSHLOGOBJ; + +CAddRuleDlg::CAddRuleDlg(void) : m_dwCRC32(NULL), m_baur2thisMode(false), m_bEditing(false) +{ +BEGIN_PROTECT_AND_LOG_CODE + ZeroMemory(&m_item, sizeof(m_item)); +END_PROTECT_AND_LOG_CODE +} + +CAddRuleDlg::~CAddRuleDlg(void) +{ +BEGIN_PROTECT_AND_LOG_CODE +END_PROTECT_AND_LOG_CODE +} + +LRESULT CAddRuleDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + TranslateDialogDefault(m_hWnd); + m_editRuleName = GetDlgItem(IDC_ED_RULENAME); + m_editContactName = GetDlgItem(IDC_ED_RULECNAME); + m_editReplyText = GetDlgItem(IDC_ED_RULEREPLY); + //m_editReplyAction = GetDlgItem(IDC_ED_RULEACTION); + m_btnSelUser = GetDlgItem(IDC_BTN_SELUSER); + + CenterWindow(); + + if (m_dwCRC32) + { + SetWindowText(TranslateTS(TEXT("Edit rule"))); + m_editRuleName.SetWindowText(m_item.RuleName); + m_editContactName.SetWindowText(m_item.ContactName); + m_editReplyText.SetWindowText(m_item.ReplyText); + //m_editReplyAction.SetWindowText(m_item.ReplyAction); + m_bEditing = true; + } + else if (m_baur2thisMode) + { + m_editRuleName.SetWindowText(m_item.RuleName); + m_editContactName.SetWindowText(m_item.ContactName); + m_editReplyText.SetWindowText(m_item.ReplyText); + //m_editReplyAction.SetWindowText(m_item.ReplyAction); + + m_btnSelUser.EnableWindow(FALSE); + m_editContactName.EnableWindow(FALSE); + m_editReplyText.SetSel(0, _tcslen(m_item.ReplyText), FALSE); + m_editReplyText.SetFocus(); + } + else + { + m_editRuleName.SetWindowText(SETTINGS_DEF_RULE_NAME); + m_editReplyText.SetWindowText(SETTINGS_DEF_MESSAGE_RULE); + } + +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT CAddRuleDlg::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + return FALSE; +END_PROTECT_AND_LOG_CODE +} + +BOOL CAddRuleDlg::PreTranslateMessage(MSG* pMsg) +{ +BEGIN_PROTECT_AND_LOG_CODE + return FALSE; +END_PROTECT_AND_LOG_CODE +} + +LRESULT CAddRuleDlg::OnBtnOKClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE +#define ON_ERROR_1BYTE(x) if (x == 1) { \ + MessageBox(TranslateTS(TEXT("Please, specify longer contact name")), g_strPluginName, MB_OK); \ + return FALSE; } + +#define ON_ERROR(x) MessageBox(TranslateTS(x), g_strPluginName, MB_OK); \ + return FALSE; + + int nLength = m_editRuleName.GetWindowTextLength(); + if (nLength) + { + nLength++; + m_item.RuleName = new TCHAR[nLength]; + + if (m_item.RuleName != NULL) + { + memset(m_item.RuleName, 0, nLength * sizeof(TCHAR)); + m_editRuleName.GetWindowText(m_item.RuleName, nLength); + } + } + else + { + ON_ERROR(TEXT("Please, specify Rule Name")) + } + + nLength = m_editContactName.GetWindowTextLength(); + if (nLength) + { + ON_ERROR_1BYTE(nLength) + nLength++; + m_item.ContactName = new TCHAR[nLength]; + + if (m_item.ContactName != NULL) + { + memset(m_item.ContactName, 0, nLength * sizeof(TCHAR)); + m_editContactName.GetWindowText(m_item.ContactName, nLength); + } + } + else + { + ON_ERROR(TEXT("Please, specify Contact Name")) + } + + nLength = m_editReplyText.GetWindowTextLength(); + if (nLength) + { + if (nLength > SETTINGS_MESSAGE_MAXVALENGTH) + { + MessageBox(TranslateTS(TEXT("header is too big")), g_strPluginName, MB_OK); + return FALSE; + } + + nLength++; + m_item.ReplyText = new TCHAR[nLength]; + + if (m_item.ContactName != NULL) + { + memset(m_item.ReplyText, 0, nLength * sizeof(TCHAR)); + m_editReplyText.GetWindowText(m_item.ReplyText, nLength); + } + } + else + { + ON_ERROR(TEXT("Please, specify Reply Text")) + } + + { + if (m_bEditing) + {/// delete prev item from storage... + g_pMessHandler->getSettings().getStorage().RemReplyAction(m_dwCRC32); + } + + bool b; + DWORD dwCrc = g_pMessHandler->getSettings().AddReplyAction(m_item, b); + if (b) + { + MessageBox(TranslateTS(TEXT("Rule with the same contact name already exists")), g_strPluginName, MB_OK); + return FALSE; + } + + m_bAddedOk = ((b == false) && dwCrc); + m_dwCRC32 = dwCrc; + } + + EndDialog(0); +#undef ON_ERROR +#undef ON_ERROR_1BYTE +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT CAddRuleDlg::OnBtnCancelClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + m_bAddedOk = false; + EndDialog(0); +END_PROTECT_AND_LOG_CODE + return FALSE; +} +LRESULT CAddRuleDlg::OnBnClickedBtnSeluser(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + CSelectUserDlg dlg; + dlg.DoModal(m_hWnd); + if (dlg.m_bAllOk == true) + { + m_editContactName.SetWindowText(dlg.m_szRetVal); + m_editReplyText.SetFocus(); + } + else + { + m_editContactName.SetFocus(); + } +END_PROTECT_AND_LOG_CODE + return 0; +} diff --git a/plugins/!NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.h b/plugins/!NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.h new file mode 100644 index 0000000000..d02fde733c --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/GUI/AddRuleDlg.h @@ -0,0 +1,67 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include + +#include "../RuleItem.h" + +class CAddRuleDlg : public CDialogImpl, public CMessageFilter +{ +public: + CAddRuleDlg(void); + virtual ~CAddRuleDlg(void); +public: + enum {IDD = IDD_ADDRULE_DLG}; + BEGIN_MSG_MAP(COptionsDlg) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + + COMMAND_ID_HANDLER(IDOK, OnBtnOKClicked) + COMMAND_ID_HANDLER(IDCANCEL, OnBtnCancelClicked) + COMMAND_HANDLER(IDC_BTN_SELUSER, BN_CLICKED, OnBnClickedBtnSeluser) + END_MSG_MAP() +protected: + virtual BOOL PreTranslateMessage(MSG* pMsg); + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT OnBtnOKClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnBtnCancelClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnBnClickedBtnSeluser(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); +protected: + CEdit m_editRuleName; + CEdit m_editContactName; + CEdit m_editReplyText; + //CEdit m_editReplyAction; + CButton m_btnSelUser; +public: + RULE_ITEM m_item; + bool m_bAddedOk; + DWORD m_dwCRC32; +private: + bool m_bEditing; +public: + bool m_baur2thisMode; +}; diff --git a/plugins/!NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.cpp b/plugins/!NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.cpp new file mode 100644 index 0000000000..5dbc6989bc --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.cpp @@ -0,0 +1,88 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" +#include "editreplydlg.h" + +extern LPTSTR g_strPluginName; + +CEditReplyDlg::CEditReplyDlg(void) +{ +} + +CEditReplyDlg::~CEditReplyDlg(void) +{ +} + +BOOL CEditReplyDlg::PreTranslateMessage(MSG* pMsg) +{ + return IsDialogMessage(pMsg); +} + +LRESULT CEditReplyDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +{ + TranslateDialogDefault(m_hWnd); + m_editReplyText = GetDlgItem(IDC_ED_TEXT); + + if (m_commRule.Message) + { + m_editReplyText.SetWindowText(m_commRule.Message); + } + + CenterWindow(GetDesktopWindow()); + + return FALSE; +} + +LRESULT CEditReplyDlg::OnBtnOKClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ + int nLength = 0; + + delete m_commRule.Message; + + nLength = m_editReplyText.GetWindowTextLength(); + + if (nLength > SETTINGS_MESSAGE_MAXVALENGTH) + { + MessageBox(TranslateTS(TEXT("message is too big")), g_strPluginName, MB_OK); + + return FALSE; + } + nLength++; + m_commRule.Message = new TCHAR[nLength]; + + if (!m_commRule.Message) + return FALSE; + + memset(m_commRule.Message, 0, nLength * sizeof(TCHAR)); + m_editReplyText.GetWindowText((LPTSTR)m_commRule.Message, nLength); + + m_bAllOk = true; + EndDialog(1); + return FALSE; +} + +LRESULT CEditReplyDlg::OnBtnCancelClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ + m_bAllOk = false; + EndDialog(0); + return FALSE; +} \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.h b/plugins/!NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.h new file mode 100644 index 0000000000..0b4a5fb94a --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/GUI/EditReplyDlg.h @@ -0,0 +1,55 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +#include "..\resource.h" + +#include +#include +#include +#include + +class CEditReplyDlg : public CDialogImpl, public CMessageFilter +{ +public: + CEditReplyDlg(void); + ~CEditReplyDlg(void); +public: + enum {IDD = IDD_SET_AURMESSAGEDLG}; + BEGIN_MSG_MAP(CEditReplyDlg) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_ID_HANDLER(IDOK, OnBtnOKClicked) + COMMAND_ID_HANDLER(IDCANCEL, OnBtnCancelClicked) + END_MSG_MAP() +protected: + virtual BOOL PreTranslateMessage(MSG* pMsg); + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT OnBtnOKClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnBtnCancelClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); +public: + REPLYER_SETTINGS m_settings; + COMMON_RULE_ITEM m_commRule; + bool m_bAllOk; +protected: + CEdit m_editReplyText; + CEdit m_editReplyHeader; +}; diff --git a/plugins/!NotAdopted/SmartAutoReplier/GUI/OptionsDlg.cpp b/plugins/!NotAdopted/SmartAutoReplier/GUI/OptionsDlg.cpp new file mode 100644 index 0000000000..1f25812101 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/GUI/OptionsDlg.cpp @@ -0,0 +1,528 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" +#include "optionsdlg.h" +#include "addruledlg.h" + +/// need ptr to get/set info +extern CMessagesHandler *g_pMessHandler; +extern CCrushLog CRUSHLOGOBJ; +extern LPTSTR g_strPluginName; + +//COptionsDlg g_optionsDlg; + +BOOL CALLBACK COptionsDlg::DlgProcCluiOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ +BEGIN_PROTECT_AND_LOG_CODE + + /*if (g_optionsDlg.m_bDestroying) + return FALSE; + + if (g_optionsDlg.m_hWnd == NULL) + g_optionsDlg.Attach(hwndDlg); + + LRESULT lre = {0}; + DWORD dwId = {0}; + return g_optionsDlg.ProcessWindowMessage(hwndDlg, msg, wParam, lParam, lre, dwId);*/ + +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +COptionsDlg::COptionsDlg(void) : m_bShown(false), m_szMessage(NULL) +{ +BEGIN_PROTECT_AND_LOG_CODE +///g_optionsDlg.m_bDestroying = false; +m_bDestroying = false; +END_PROTECT_AND_LOG_CODE +} + +COptionsDlg::~COptionsDlg(void) +{ +BEGIN_PROTECT_AND_LOG_CODE +END_PROTECT_AND_LOG_CODE +} + +BOOL COptionsDlg::PreTranslateMessage(MSG* pMsg) +{ +BEGIN_PROTECT_AND_LOG_CODE + return ::IsDialogMessage(m_hWnd, pMsg); +END_PROTECT_AND_LOG_CODE +} + +/// process OnInitDialog +LRESULT COptionsDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + TranslateDialogDefault(m_hWnd); + + if (!g_pMessHandler) + return FALSE; + + m_listRules = GetDlgItem(IDC_LIST_RULES); + m_editReplayDelay = GetDlgItem(IDC_EDIT_REPLAYDELAY); +// m_editHeaderMessage = GetDlgItem(IDC_EDIT_HEADER); + m_editMessageText = GetDlgItem(IDC_EDIT_MESSAGE); + m_btnAdd = GetDlgItem(IDC_BTN_ADDRULE); + m_btnDel = GetDlgItem(IDC_BTN_DELRULE); + m_btnChange = GetDlgItem(IDC_BTN_EDITRULE); + m_wndCheckDOnSOn = GetDlgItem(IDC_CHECK_DISABLEWMON); + m_wndCheckModeTypes = GetDlgItem(IDC_CH_ENABLE_WSCH); + m_cbModeTypes = GetDlgItem(IDC_CB_ENWSC); + m_chbShowAurWhmc = GetDlgItem(IDC_CH_SHOWCG); + m_cbDisWMBTypes = GetDlgItem(IDC_CB_DWSB); + m_chDisWMB = GetDlgItem(IDC_CH_DISWHSB); + m_chSaveAURSToHist = GetDlgItem(IDC_CH_SAVE_AURS); + + m_cbModeTypes.AddString(TranslateTS(TEXT("DND/NA/Away/Occupied modes"))); + m_cbModeTypes.AddString(TranslateTS(TEXT("DND mode"))); + m_cbModeTypes.AddString(TranslateTS(TEXT("NA mode"))); + m_cbModeTypes.AddString(TranslateTS(TEXT("Away mode"))); + m_cbModeTypes.AddString(TranslateTS(TEXT("Occupied mode"))); + + m_cbDisWMBTypes.AddString(TranslateTS(TEXT("Online/Free for chat modes"))); + m_cbDisWMBTypes.AddString(TranslateTS(TEXT("Online mode"))); + m_cbDisWMBTypes.AddString(TranslateTS(TEXT("Free for chat mode"))); + + COMMON_RULE_ITEM & commRules = g_pMessHandler->getSettings().getStorage().getCommonRule(); + REPLYER_SETTINGS & settings = g_pMessHandler->getSettings().getSettings(); + + if (settings.ModeValue > m_cbModeTypes.GetCount()) + m_cbModeTypes.SetCurSel(0); + else + m_cbModeTypes.SetCurSel(settings.ModeValue); + if (settings.ModeDisValue > m_cbDisWMBTypes.GetCount()) + m_cbDisWMBTypes.SetCurSel(0); + else + m_cbDisWMBTypes.SetCurSel(settings.ModeDisValue); + + m_cbDisWMBTypes.EnableWindow(settings.bDisableWhenModeIsSet); + + if (settings.bDisableWhenModeIsSet) + { + m_chDisWMB.SendMessage(BM_SETCHECK, BST_CHECKED, 0); + } + else + { + m_chDisWMB.SendMessage(BM_SETCHECK, BST_UNCHECKED, 0); + } + + if (settings.bShowAURDlgWhenModeChanges) + { + m_chbShowAurWhmc.SendMessage(BM_SETCHECK, BST_CHECKED, 0); + } + else + { + m_chbShowAurWhmc.SendMessage(BST_UNCHECKED, BST_CHECKED, 0); + } + + if (settings.bEnableWhenModeIsSet) + { + m_wndCheckModeTypes.SendMessage(BM_SETCHECK, BST_CHECKED, 0); + } + else + { + m_wndCheckModeTypes.SendMessage(BST_UNCHECKED, BST_CHECKED, 0); + } + + if (settings.bSaveToHistory) + { + m_chSaveAURSToHist.SendMessage(BM_SETCHECK, BST_CHECKED, 0); + } + else + { + m_chSaveAURSToHist.SendMessage(BST_UNCHECKED, BST_CHECKED, 0); + } + + m_cbModeTypes.EnableWindow(settings.bEnableWhenModeIsSet); + + int nLength = settings.ReplayDelay; + if (nLength == 0) + nLength = SETTINGS_DEF_COMMON_VALREPDELAY; + + if (settings.bDisableWhenMirandaIsOn) + m_wndCheckDOnSOn.SendMessage(BM_SETCHECK, BST_CHECKED, 0); + else + m_wndCheckDOnSOn.SendMessage(BM_SETCHECK, BST_UNCHECKED, 0); + + TCHAR strNumber[MAX_PATH] = {0}; + m_editReplayDelay.SetWindowText(_itot(nLength, strNumber, 10)); + m_nReplayDelay = nLength; + + TCHAR* str = commRules.Message; + m_editMessageText.SetWindowText(str); + + if (m_szMessage) + { + delete m_szMessage; + m_szMessage = NULL; + } + + m_szMessage = new TCHAR[SETTINGS_MESSAGE_MAXVALENGTH]; + + if (!m_szMessage) + return FALSE; + + memset(m_szMessage, 0, SETTINGS_MESSAGE_MAXVALENGTH * sizeof(TCHAR)); + + m_editMessageText.GetWindowText(m_szMessage, SETTINGS_MESSAGE_MAXVALENGTH); + + { /// filling listbox with rule names... + RulesHash::iterator it; + RulesHash & hash = g_pMessHandler->getSettings().getStorage().getHashTable(); + int nPos = 0; + + bool bAdded = false; + for (it = hash.begin(); it != hash.end(); it++) + { + nPos = m_listRules.AddString(it->second.RuleName); + if (nPos != -1) + { + m_listRules.SetItemData(nPos, it->first); + if (!bAdded) + bAdded = true; + } + } + if (bAdded) + { + OnSetSelInRulesList(0); + } + } +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +/// process WM_DESTROY +LRESULT COptionsDlg::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + m_bDestroying = true; + ///g_optionsDlg.m_bDestroying = true; + ///::DestroyWindow(m_hWnd); + ///g_optionsDlg.m_hWnd = NULL; + //m_hWnd = NULL; + m_szMessage = NULL; + // m_bDestroying = false; + ///g_optionsDlg.m_bDestroying = false; + return FALSE; +END_PROTECT_AND_LOG_CODE +} + +void COptionsDlg::OnNotifyAboutChanges(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + SendMessage(m_hwndHolder, PSM_CHANGED, 0, 0); +END_PROTECT_AND_LOG_CODE +} + +/// handler of typing in replay delay edit box +LRESULT COptionsDlg::OnEditReply(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + if (m_bShown) + { + m_bShown = false; + return FALSE; + } + TCHAR tch[MAX_PATH] = {0}; + GetDlgItemText (IDC_EDIT_REPLAYDELAY, tch, sizeof(tch)); + int nValue = _tstoi(tch); + + if (nValue != m_nReplayDelay) + { + m_nReplayDelay = nValue; + OnNotifyAboutChanges(); + } + +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT COptionsDlg::OnNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + switch (((LPNMHDR)lParam)->code) + { + case PSN_APPLY: + { /// apply our changes... + REPLYER_SETTINGS sett; + COMMON_RULE_ITEM commrule; + + commrule.Message = m_szMessage; + + sett.bEnabled = g_pMessHandler->getSettings().getSettings().bEnabled; + sett.ReplayDelay = m_nReplayDelay; + + LRESULT lres = m_wndCheckDOnSOn.SendMessage(BM_GETCHECK, 0, 0); + sett.bDisableWhenMirandaIsOn = (lres == BST_CHECKED); + lres = m_wndCheckModeTypes.SendMessage(BM_GETCHECK, 0, 0); + sett.bEnableWhenModeIsSet = (lres == BST_CHECKED); + lres = m_chbShowAurWhmc.SendMessage(BM_GETCHECK, 0, 0); + sett.bShowAURDlgWhenModeChanges = (lres == BST_CHECKED); + lres = m_chSaveAURSToHist.SendMessage(BM_GETCHECK, 0, 0); + sett.bSaveToHistory = (lres == BST_CHECKED); + sett.ModeValue = m_cbModeTypes.GetCurSel(); + lres = m_chDisWMB.SendMessage(BM_GETCHECK, 0, 0); + sett.bDisableWhenModeIsSet = (lres == BST_CHECKED); + sett.ModeDisValue = m_cbDisWMBTypes.GetCurSel(); + + CSettingsHandler & handler = g_pMessHandler->getSettings(); + handler.setSettings(sett, &commrule); + //handler.getStorage().Flush(); /// flush all unflushed rules into hdd + } + } + +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT COptionsDlg::OnEditHeader(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT COptionsDlg::OnEditMessage(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + if (!m_szMessage) + return FALSE; + + int nLength = m_editMessageText.GetWindowTextLength(); + + if (nLength > SETTINGS_MESSAGE_MAXVALENGTH) + { + MessageBox(TranslateTS(TEXT("too big size")), g_strPluginName, MB_OK); + m_editMessageText.SetWindowText(m_szMessage); + + return FALSE; + } + nLength++; + LPTSTR str2 = new TCHAR[nLength]; + + if (!str2) + return FALSE; + + memset(str2, 0, nLength * sizeof(TCHAR)); + m_editMessageText.GetWindowText(str2, nLength); + + if (_tcscmp(m_szMessage, str2) != 0) + { + _tcscpy(m_szMessage, str2); + OnNotifyAboutChanges(); + } + + delete str2; +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +void COptionsDlg::OnSetSelInRulesList(int nIndex) +{ +BEGIN_PROTECT_AND_LOG_CODE + m_listRules.SetCurSel(nIndex); + BOOL b; + OnListBoxSelChanged(0, 0, 0, b); +END_PROTECT_AND_LOG_CODE +} + +LRESULT COptionsDlg::OnBtnAddRuleClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + CAddRuleDlg dlg; + dlg.DoModal(m_hWnd, 0); + if (dlg.m_bAddedOk) + { + int npos = m_listRules.AddString(dlg.m_item.RuleName); + if (npos != -1) + { + m_listRules.SetItemData(npos, dlg.m_dwCRC32); + OnSetSelInRulesList(npos); + OnNotifyAboutChanges(); + } + } +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT COptionsDlg::OnBtnEditRuleClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + int nIndex = m_listRules.GetCurSel(); + if (nIndex >= 0) + { + DWORD dwCrc32 = static_cast(m_listRules.GetItemData(nIndex)); + if (dwCrc32) + { + CAddRuleDlg dlgEdit; + RulesHash::iterator it; + RulesHash & hash = g_pMessHandler->getSettings().getStorage().getHashTable(); + it = hash.find(dwCrc32); + if (it != hash.end()) + { + dlgEdit.m_item = it->second; + dlgEdit.m_dwCRC32 = dwCrc32; + dlgEdit.DoModal(); + if (dlgEdit.m_bAddedOk) + {/// the rule is edited... + m_listRules.DeleteString(nIndex); + nIndex = m_listRules.AddString(dlgEdit.m_item.RuleName); + m_listRules.SetItemData(nIndex, dlgEdit.m_dwCRC32); + OnSetSelInRulesList(nIndex); + OnNotifyAboutChanges(); + } + } + } + } +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT COptionsDlg::OnBtnDeleteRuleClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + int nIndex = m_listRules.GetCurSel(); + if (nIndex >= 0) + { + DWORD dwptr = static_cast(m_listRules.GetItemData(nIndex)); + if (dwptr)/// we have ptr + { + if (MessageBox(TranslateTS(TEXT("Do you really want delete selected rule ?")), g_strPluginName, MB_YESNO) == IDNO) + return FALSE; + + CRulesStorage & hash = g_pMessHandler->getSettings().getStorage(); + + if (hash.RemReplyAction(dwptr)) + {/// we found item in storage list... + int nCount = m_listRules.DeleteString(nIndex); + if (nCount != LB_ERR) + { /// set sel to prev one + if (nIndex == 0 && nCount) + OnSetSelInRulesList(0); + else + if ( (nIndex - 1) <= nCount) + { + OnSetSelInRulesList(nIndex - 1); + } + } + + OnNotifyAboutChanges(); + } + } + } + + BOOL b; + OnListBoxSelChanged(0, 0, 0, b); + +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT COptionsDlg::OnListBoxSelChanged(WORD wParam, WORD w2Param, HWND hwnd, BOOL & bHandled) +{ +BEGIN_PROTECT_AND_LOG_CODE + int nCount = m_listRules.GetCurSel(); + //m_btnChange.EnableWindow((nCount >= 0)); + BOOL bEnable = (nCount >= 0); + m_btnDel.EnableWindow(bEnable); + m_btnChange.EnableWindow(bEnable); + +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT COptionsDlg::OnBnClickedCheck(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + OnNotifyAboutChanges(); + + return FALSE; +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT COptionsDlg::OnBnCheckEnableWhenModeIsOn(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + LRESULT lres = m_wndCheckModeTypes.SendMessage(BM_GETCHECK, 0, 0); + m_cbModeTypes.EnableWindow(lres == BST_CHECKED); + OnNotifyAboutChanges(); +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT COptionsDlg::OnCbnSelchangeCbEnwsc(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + OnNotifyAboutChanges(); + +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT COptionsDlg::OnCheckSaveToHistory(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + OnNotifyAboutChanges(); +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT COptionsDlg::OnBnCheckDisableWhenModeIsOn(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + LRESULT lres = m_chDisWMB.SendMessage(BM_GETCHECK, 0, 0); + m_cbDisWMBTypes.EnableWindow(lres == BST_CHECKED); + OnNotifyAboutChanges(); + +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT COptionsDlg::OnCbnSelchangeCbDisnwsc(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + OnNotifyAboutChanges(); + +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +/// options are changed in another place... +/// so just update them all... +LRESULT COptionsDlg::OnRefreshOptions(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + MessageBox (TranslateTS(TEXT("Options are changed in another dialog")), g_strPluginName, MB_OK); + ///OnNotifyAboutChanges(); +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT COptionsDlg::OnLbnDblclkListRules(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) +{ +BEGIN_PROTECT_AND_LOG_CODE + return OnBtnEditRuleClick(wNotifyCode, wID, hWndCtl, bHandled); +END_PROTECT_AND_LOG_CODE +} \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/GUI/OptionsDlg.h b/plugins/!NotAdopted/SmartAutoReplier/GUI/OptionsDlg.h new file mode 100644 index 0000000000..0e2e91f191 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/GUI/OptionsDlg.h @@ -0,0 +1,119 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +/// #warning: redeclaring....quick programming ;) +/// look at stdafx.h +#ifndef REFRESH_OPTS_MSG + #define REFRESH_OPTS_MSG WM_USER + 666 +#endif + +#include +#include +#include +#include +#include + +/// here is a wrapper on options dlg +class COptionsDlg : public CDialogImpl, public CMessageFilter +{ +public: + COptionsDlg(void); + virtual ~COptionsDlg(void); +public: + enum {IDD = IDD_OPTIONS}; + BEGIN_MSG_MAP(COptionsDlg) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_HANDLER(WM_NOTIFY, OnNotify) + MESSAGE_HANDLER(REFRESH_OPTS_MSG, OnRefreshOptions) + COMMAND_ID_HANDLER(IDC_BTN_ADDRULE, OnBtnAddRuleClick) + COMMAND_ID_HANDLER(IDC_BTN_DELRULE, OnBtnDeleteRuleClick) + COMMAND_ID_HANDLER(IDC_BTN_EDITRULE, OnBtnEditRuleClick) + COMMAND_ID_HANDLER(IDC_EDIT_REPLAYDELAY, OnEditReply) + COMMAND_ID_HANDLER(IDC_EDIT_HEADER, OnEditHeader) + COMMAND_ID_HANDLER(IDC_EDIT_MESSAGE, OnEditMessage) + COMMAND_CODE_HANDLER(LBN_SELCHANGE, OnListBoxSelChanged) + COMMAND_HANDLER(IDC_LIST_RULES, LBN_DBLCLK, OnLbnDblclkListRules) + COMMAND_HANDLER(IDC_CHECK_DISABLEWMON, BN_CLICKED, OnBnClickedCheck) + COMMAND_HANDLER(IDC_CH_ENABLE_WSCH, BN_CLICKED, OnBnCheckEnableWhenModeIsOn) + COMMAND_HANDLER(IDC_CH_SHOWCG, BN_CLICKED, OnBnCheckEnableWhenModeIsOn) + COMMAND_HANDLER(IDC_CH_SAVE_AURS, BN_CLICKED, OnCheckSaveToHistory) + COMMAND_HANDLER(IDC_CB_ENWSC, CBN_SELENDOK, OnCbnSelchangeCbEnwsc) + COMMAND_HANDLER(IDC_CH_DISWHSB, BN_CLICKED, OnBnCheckDisableWhenModeIsOn) + COMMAND_HANDLER(IDC_CB_DWSB, CBN_SELENDOK, OnCbnSelchangeCbDisnwsc) + END_MSG_MAP() + virtual BOOL PreTranslateMessage(MSG* pMsg); +protected: + /// messages handlers prototypes + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT OnNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT OnRefreshOptions(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + + /// commands handlers prototypes + LRESULT OnBtnAddRuleClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnBtnDeleteRuleClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnBtnEditRuleClick(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnEditReply(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnEditHeader(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnEditMessage(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnListBoxSelChanged(WORD wParam, WORD wParam2, HWND hwnd, BOOL & bHandled); + LRESULT OnBnClickedCheck(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnBnCheckEnableWhenModeIsOn(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnCbnSelchangeCbEnwsc(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnBnCheckDisableWhenModeIsOn(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnCheckSaveToHistory(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnCbnSelchangeCbDisnwsc(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnLbnDblclkListRules(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); +public: + static BOOL CALLBACK DlgProcCluiOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +private: + void OnNotifyAboutChanges(void); + void OnSetSelInRulesList(int nIndex); +protected: + CEdit m_editReplayDelay; /// edit box where reply delay is specifyed + CEdit m_editMessageText; /// edit box where message text is specifyed + CListBox m_listRules; /// list box where all rules are specifyed + CButton m_btnAdd; /// button add rule + CButton m_btnDel; /// button delete rule + CButton m_btnChange; /// button change rule + CWindow m_wndCheckDOnSOn; /// checkbox that specifyes dis of plug. when mir is on + CComboBox m_cbModeTypes; /// cb mode types + CWindow m_wndCheckModeTypes; /// ch mode types + CWindow m_chbShowAurWhmc; /// ch show edit reply message + CWindow m_chDisWMB; /// ch disable when mode becomes... + CWindow m_chSaveAURSToHist; /// save aurs to history + CComboBox m_cbDisWMBTypes; /// cb disable when mode becomes... +private: + LPTSTR m_szMessage; + int m_nReplayDelay; + bool m_bDestroying; +protected: + bool m_bShown; +public: + HWND m_hwndHolder; +}; + +/// here is static dlg proc for options dialog.. +/// very bad but mirand can accept only this function +BOOL CALLBACK DlgProcCluiOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.cpp b/plugins/!NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.cpp new file mode 100644 index 0000000000..6a51ccae19 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.cpp @@ -0,0 +1,109 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" +#include "selectuserdlg.h" +#include "selectuserdlg.h" + +extern LPTSTR g_strPluginName; +extern CMessagesHandler * g_pMessHandler; + + +CSelectUserDlg::CSelectUserDlg(void) : m_bAllOk(false) +{ +} + +CSelectUserDlg::~CSelectUserDlg(void) +{ +} + +BOOL CSelectUserDlg::PreTranslateMessage(MSG* pMsg) +{ + return IsDialogMessage(pMsg); +} + +LRESULT CSelectUserDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + TranslateDialogDefault(m_hWnd); + m_listUsers = GetDlgItem(IDC_LIST_USERS); + RebuildCL(); +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +void CSelectUserDlg::RebuildCL() +{ +BEGIN_PROTECT_AND_LOG_CODE + HANDLE hContact= reinterpret_cast (CallService(MS_DB_CONTACT_FINDFIRST, 0, 0)); + TCHAR* szContactName = NULL; + TCHAR* szProto = NULL; + DWORD wId = 0; + while (hContact != NULL) + { + szContactName = g_pMessHandler->GetContactName(hContact); + szProto = (TCHAR*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + if (szProto) + { + size_t nPos = -1; + if (szContactName) + { + nPos = m_listUsers.AddString(szContactName); + } + + /*DBVARIANT db = {0}; + DBGetContactSetting(hContact, szProto, "uin", &db); + DBGetContactSetting(hContact, szProto, "UIN", &db);*/ + //m_listUsers.SetItemData(nPos, ) + } + + hContact = reinterpret_cast (CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM) hContact, 0)); + } +END_PROTECT_AND_LOG_CODE +} + +LRESULT CSelectUserDlg::OnBtnOKClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + INT nsel = m_listUsers.GetCurSel(); + m_bAllOk = (nsel != -1); + if (m_bAllOk == true) + { + m_listUsers.GetText(nsel, m_szRetVal); + EndDialog(0); + } +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT CSelectUserDlg::OnBtnCancelClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + m_bAllOk = false; + EndDialog(0); +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT CSelectUserDlg::OnLbnDblclkListUsers(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) +{ + return OnBtnOKClicked(wNotifyCode, wID, hWndCtl, bHandled); +} diff --git a/plugins/!NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.h b/plugins/!NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.h new file mode 100644 index 0000000000..1756e7a4b8 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/GUI/SelectUserDlg.h @@ -0,0 +1,58 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +#include "..\resource.h" + +#include +#include +#include +#include + +class CSelectUserDlg : public CDialogImpl, public CMessageFilter +{ +public: + CSelectUserDlg(void); + ~CSelectUserDlg(void); +public: + enum {IDD = IDD_SEL_USER}; + BEGIN_MSG_MAP(CSelectUserDlg) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_ID_HANDLER(IDOK, OnBtnOKClicked) + COMMAND_ID_HANDLER(IDCANCEL, OnBtnCancelClicked) + COMMAND_HANDLER(IDC_LIST_USERS, LBN_DBLCLK, OnLbnDblclkListUsers) + END_MSG_MAP() +protected: + virtual BOOL PreTranslateMessage(MSG* pMsg); + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT OnBtnOKClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnBtnCancelClicked(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); +private: + void RebuildCL(); +public: + bool m_bAllOk; + TCHAR m_szRetVal[MAX_PATH]; +protected: + CListBox m_listUsers; +public: + LRESULT OnLbnDblclkListUsers(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); +}; diff --git a/plugins/!NotAdopted/SmartAutoReplier/GUI/SettingsDlgHolder.cpp b/plugins/!NotAdopted/SmartAutoReplier/GUI/SettingsDlgHolder.cpp new file mode 100644 index 0000000000..4a9eae542a --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/GUI/SettingsDlgHolder.cpp @@ -0,0 +1,207 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" +#include "settingsdlgholder.h" + +/// #warning +/// dont make Translate each time +/// instead once fill list of translated strings +/// and use them + +extern LPTSTR g_strPluginName; +extern CMessagesHandler * g_pMessHandler; +CSettingsDlgHolder * CSettingsDlgHolder::m_pThis = NULL; + +CSettingsDlgHolder::CSettingsDlgHolder(void) : +IMSingeltone(this), +m_bTabSelected(false), +m_bDestroying(false) +{ +} + +CSettingsDlgHolder::~CSettingsDlgHolder(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + BOOL b; + OnDestroy(NULL, NULL, NULL, b); +END_PROTECT_AND_LOG_CODE +} + +BOOL CSettingsDlgHolder::PreTranslateMessage(MSG* pMsg) +{ + return IsDialogMessage(pMsg); +} + +LRESULT CSettingsDlgHolder::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + TranslateDialogDefault(m_hWnd); + + m_tabCtrl = GetDlgItem(IDC_TABSHOLDER); + m_statusMsg = GetDlgItem(IDC_STATUSMSG); + + TCITEM ti = {0}; + ti.mask = TCIF_TEXT; + ti.pszText = TranslateTS(TEXT("General")); + ti.cchTextMax = _tcslen(ti.pszText); + m_tabCtrl.InsertItem(0, &ti); + /*ti.pszText = Translate("About"); + ti.cchTextMax = _tcslen(ti.pszText); + m_tabCtrl.InsertItem(1, &ti);*/ + + m_generalOpt.Create(m_tabCtrl, NULL); + m_generalOpt.m_hwndHolder = this->m_hWnd; + m_tabCtrl.SetCurSel(0); + + /// #warning + /// copy paste from OnNotify(), fix later + /*m_statusMsg.SetWindowText(Translate("General options, provides basic functionality."));*/ + m_statusMsg.SetWindowText(TranslateTS(TEXT(""))); + m_generalOpt.SetWindowPos(NULL, 7, 23, NULL, NULL, SWP_NOSIZE); + m_generalOpt.ShowWindow(SW_SHOW); + +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +void CSettingsDlgHolder::OnNotifyParents(LPNMHDR lpnmhdr, int nCode) +{ +BEGIN_PROTECT_AND_LOG_CODE + lpnmhdr->code = nCode; + m_generalOpt.SendMessage(WM_NOTIFY, 0, reinterpret_cast(lpnmhdr)); +END_PROTECT_AND_LOG_CODE +} + +LRESULT CSettingsDlgHolder::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + LPNMHDR lpnmhdr = NULL; + lpnmhdr = (LPNMHDR)lParam; + if (lpnmhdr == NULL) + { + return FALSE; + } + + if (m_bTabSelected == false) + { + m_bTabSelected = true; + return FALSE; + } + + switch (lpnmhdr->code) + { + case PSN_APPLY: + OnNotifyParents(lpnmhdr, PSN_APPLY); + break; + } + + int nSel = -1; + if (lpnmhdr->hwndFrom == m_tabCtrl) + { + nSel = m_tabCtrl.GetCurSel(); + /// let's make a switch by dialogs... + if (nSel == 0) + { + m_statusMsg.SetWindowText(TranslateTS(TEXT("General options, provides basic functionality."))); + m_generalOpt.ShowWindow(SW_SHOW); + m_generalOpt.SetWindowPos(NULL, 7, 23, NULL, NULL, SWP_NOSIZE); + } + else + m_generalOpt.ShowWindow(SW_HIDE); + } + + m_bTabSelected = false; + +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +BOOL CALLBACK CSettingsDlgHolder::FakeDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ +BEGIN_PROTECT_AND_LOG_CODE + CSettingsDlgHolder *pHandler = CSettingsDlgHolder::GetObject(); + + if (pHandler == NULL) + return FALSE; + + if (pHandler->m_bDestroying == true) + return FALSE; + + if (pHandler->m_hWnd == NULL) + pHandler->Attach(hwndDlg); + + LRESULT lr = 0; + DWORD dwid = 0; + BOOL bRetVal = pHandler->ProcessWindowMessage(hwndDlg, msg, wParam, lParam, lr, dwid); + return bRetVal; + END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT CSettingsDlgHolder::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + m_bDestroying = true; + + if (m_tabCtrl.IsWindow()) + { + m_tabCtrl.DeleteAllItems(); + m_tabCtrl.DestroyWindow(); + } + if (m_statusMsg.IsWindow()) + m_statusMsg.DestroyWindow(); + + if (m_generalOpt.IsWindow()) + { + /*try + {*/ + //OSVERSIONINFO ver = {0}; + //ver.dwOSVersionInfoSize = sizeof(ver); + + //if (GetVersionEx(&ver) == TRUE) + //{ + // if (ver.dwMajorVersion > 4) + // { + NMHDR h = {0}; + h.code = PSN_APPLY; + OnNotifyParents(&h, PSN_APPLY); + // } + //} + m_generalOpt.DestroyWindow(); + //} + //catch (...) + //{/// win9x will die here + //} + } + m_hWnd = NULL; + +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +LRESULT CSettingsDlgHolder::OnSettingsChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) +{ +BEGIN_PROTECT_AND_LOG_CODE + return SendMessage(GetParent(), PSM_CHANGED, 0, 0); +END_PROTECT_AND_LOG_CODE + return FALSE; +} \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/GUI/SettingsDlgHolder.h b/plugins/!NotAdopted/SmartAutoReplier/GUI/SettingsDlgHolder.h new file mode 100644 index 0000000000..61fb460e5b --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/GUI/SettingsDlgHolder.h @@ -0,0 +1,69 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +#include "..\resource.h" + +#include +#include +#include +#include + +#include "optionsdlg.h" + +/// dialog that holds all +/// gui dialogs.. +class CSettingsDlgHolder : public CDialogImpl, + public CMessageFilter, + public IMSingeltone +{ +public: /// ctors + CSettingsDlgHolder(void); + /// dctors + ~CSettingsDlgHolder(void); +public: + enum {IDD = IDD_SDLGHOLDER}; + BEGIN_MSG_MAP(CSettingsDlgHolder) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + MESSAGE_HANDLER(WM_NOTIFY, OnNotify) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_HANDLER(PSM_CHANGED, OnSettingsChanged) + END_MSG_MAP() +protected: + virtual BOOL PreTranslateMessage(MSG* pMsg); + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT OnNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT OnSettingsChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); +private: + void OnNotifyParents(LPNMHDR lpnmhdr, int nCode); +private: + bool m_bTabSelected; +public: + static BOOL CALLBACK FakeDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +protected: + CTabCtrl m_tabCtrl; /// holder of all settings dlg + CStatic m_statusMsg; + COptionsDlg m_generalOpt; /// general options dlg +public: + bool m_bDestroying; +}; diff --git a/plugins/!NotAdopted/SmartAutoReplier/Interfaces/ISettings.h b/plugins/!NotAdopted/SmartAutoReplier/Interfaces/ISettings.h new file mode 100644 index 0000000000..4a789be694 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/Interfaces/ISettings.h @@ -0,0 +1,34 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +/// base for settings data... +interface ISettingsStream +{ +}; + +/// base interface for settings managers... +interface ISettings +{ + virtual bool Serialize(ISettingsStream *pStream, DWORD & ObjectSize) = NULL; + virtual bool Deserialize(DWORD & ObjectSize) = NULL; +}; \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/Interfaces/ISingletone.h b/plugins/!NotAdopted/SmartAutoReplier/Interfaces/ISingletone.h new file mode 100644 index 0000000000..7474127e89 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/Interfaces/ISingletone.h @@ -0,0 +1,35 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +/// base class for singletones in plugin +template +class IMSingeltone +{ +public: + IMSingeltone(){}; + IMSingeltone(T * ptclass) {m_pThis = ptclass;} + static void SetObject(T* pObj) {m_pThis = pObj;}; + static T* GetObject(){return m_pThis;}; +protected: + static T* m_pThis; +}; \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/LuaBridge.cpp b/plugins/!NotAdopted/SmartAutoReplier/LuaBridge.cpp new file mode 100644 index 0000000000..764dec3381 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/LuaBridge.cpp @@ -0,0 +1,127 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This code is inspired by article of RichardS at http://www.codeproject.com/Articles/11508/Integrating-Lua-into-C + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" +#include "LuaBridge.h" + +CLuaBridge::CLuaBridge(void) : m_pLuaContext(NULL) +{ + m_pLuaContext = lua_open(); + + if (m_pLuaContext != NULL) + { + lua_pushcclosure(m_pLuaContext, LuaDebugMessage, 0); + lua_setglobal(m_pLuaContext, "trace"); + + lua_atpanic(m_pLuaContext, (lua_CFunction)HandleLuaAsssert); + + luaopen_io(m_pLuaContext); + luaopen_math(m_pLuaContext); + luaopen_base(m_pLuaContext); + luaopen_loadlib(m_pLuaContext); + luaopen_table(m_pLuaContext); + luaopen_string(m_pLuaContext); + luaopen_debug(m_pLuaContext); + } +} + +CLuaBridge::~CLuaBridge(void) +{ + if (m_pLuaContext != NULL) + { + lua_close(m_pLuaContext); + } +} + +int CLuaBridge::LuaDebugMessage(lua_State *pContext) +{ + const char *szFunction = NULL; + const char *szMessage = NULL; + lua_Debug LuaDebug = {0}; + + int n = lua_tonumber(pContext, 1); + szMessage = lua_tostring(pContext, 1); + + if (szMessage == NULL) + { + return FALSE; + } + + lua_getstack(pContext, 1, &LuaDebug); + lua_getinfo (pContext, "Snl", &LuaDebug); + + szFunction = LuaDebug.source; + + if (szFunction == NULL) + { + return FALSE; + } + + OutputDebugStringA("Smart Auto Replier : "); + OutputDebugStringA("("); + OutputDebugStringA(szFunction); + OutputDebugStringA("): "); + OutputDebugStringA(szMessage); + OutputDebugStringA("\r\n"); + + return TRUE; +} + +void CLuaBridge::HandleLuaAsssert(lua_State * pContext) +{ + DebugBreak(); +} + +bool CLuaBridge::RunScript(const char *szScript, size_t nLength, const char *szFuncName) +{ + bool bRetVal = false; + + if (szFuncName == NULL) + { + szFuncName = "SarFakeProcedure"; + } + + if (luaL_loadbuffer(m_pLuaContext, szScript, nLength, szFuncName) == 0) + { + bRetVal = (lua_pcall(m_pLuaContext, 0, LUA_MULTRET, 0) == 0); + } + + return bRetVal; +} + +bool CLuaBridge::ExecuteFunction(int nArgs, int nReturns) +{ + bool bRetVal = false; + + if (lua_isfunction(m_pLuaContext, -nArgs - 1)) + { + bRetVal = (lua_pcall(m_pLuaContext, nArgs, nReturns, 0) == FALSE); + } + + return bRetVal; +} + +CLuaBridge::operator lua_State *() +{ + return m_pLuaContext; +} \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/LuaBridge.h b/plugins/!NotAdopted/SmartAutoReplier/LuaBridge.h new file mode 100644 index 0000000000..f012a55db4 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/LuaBridge.h @@ -0,0 +1,96 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This code is inspired by article of RichardS at http://www.codeproject.com/Articles/11508/Integrating-Lua-into-C + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +#include "luainc.h" + +class CLuaBridge +{ +public: + CLuaBridge(void); + ~CLuaBridge(void); + +public: + static int LuaDebugMessage(lua_State * pContext); + static void HandleLuaAsssert(lua_State * pContext); + + bool RunScript(const char *szScript, size_t nLength, const char *szFuncName = NULL); + bool ExecuteFunction(int nArgs, int nReturns = 0); + operator lua_State *(); + +protected: + lua_State *m_pLuaContext; +}; + +class CLuaStack +{ +public: + CLuaStack(CLuaBridge & luaBridge) : m_pState(NULL), m_nTopIndex(0) + { + m_pState = (lua_State*)luaBridge; + m_nTopIndex = lua_gettop(m_pState); + } + + virtual ~CLuaStack() + { + lua_settop(m_pState, m_nTopIndex); + } + +protected: + + lua_State *m_pState; + int m_nTopIndex; +}; + +class CLuaTableThis +{ +public: + CLuaTableThis(CLuaBridge & luaBridge, int nRef) : m_nOldRef(0), m_luaBridge(luaBridge) + { + lua_State *state = (lua_State*)m_luaBridge; + + lua_getglobal(state, "this"); + m_nOldRef = luaL_ref(state, LUA_REGISTRYINDEX); + + lua_rawgeti(state, LUA_REGISTRYINDEX, nRef); + lua_setglobal(state, "this"); + } + + virtual ~CLuaTableThis() + { + lua_State *state = (lua_State*)m_luaBridge; + + if (m_nOldRef > 0) + { + lua_rawgeti(state, LUA_REGISTRYINDEX, m_nOldRef); + lua_setglobal (state, "this"); + luaL_unref(state, LUA_REGISTRYINDEX, m_nOldRef); + } + } + +protected: + int m_nOldRef; + CLuaBridge & m_luaBridge; +}; + diff --git a/plugins/!NotAdopted/SmartAutoReplier/LuaScript.cpp b/plugins/!NotAdopted/SmartAutoReplier/LuaScript.cpp new file mode 100644 index 0000000000..5ad1508d99 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/LuaScript.cpp @@ -0,0 +1,215 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This code is inspired by article of RichardS at http://www.codeproject.com/Articles/11508/Integrating-Lua-into-C + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" + +#include +#include "luainc.h" +#include "luascript.h" + +#define LUA_CODE_CHUNK_ENTER(luaBridge) lua_State *state = (lua_State*)luaBridge; + +#define LUA_CODE_CHUNK_LEAVE + +CLuaScript::CLuaScript(CLuaBridge & luaBridge) : m_luaBridge(luaBridge), m_nMethods(DEFAULT_INDEX_INITIALIZER), m_nThisRef(DEFAULT_INDEX_INITIALIZER), m_nArgs(DEFAULT_INDEX_INITIALIZER) +{ +LUA_CODE_CHUNK_ENTER(luaBridge) + + lua_newtable(state); + m_nThisRef = luaL_ref(state, LUA_REGISTRYINDEX); + + CLuaStack luaStack(luaBridge); + lua_rawgeti(state, LUA_REGISTRYINDEX, m_nThisRef); + lua_pushlightuserdata(state, reinterpret_cast(this)); + lua_rawseti(state, -2, 0); + +LUA_CODE_CHUNK_LEAVE +} + +CLuaScript::~CLuaScript(void) +{ + CLuaStack luaStack(m_luaBridge); + +LUA_CODE_CHUNK_ENTER(m_luaBridge) + + lua_rawgeti(state, LUA_REGISTRYINDEX, m_nThisRef); + lua_pushnil(state); + lua_rawseti(state, -2, 0); + +LUA_CODE_CHUNK_LEAVE +} + +int CLuaScript::LuaCallback(lua_State *lua) +{ + int iNumberIdx = lua_upvalueindex(1); + int nRetsOnStack = 0; + + bool bRetVal = false; + + if (lua_istable(lua, 1)) + { + lua_rawgeti(lua, 1, 0); + + if (lua_islightuserdata(lua, -1)) + { + CLuaScript *pThis = reinterpret_cast(lua_touserdata(lua, -1)); + int nMethod = static_cast(lua_tonumber(lua, iNumberIdx)); + + assert(!(nMethod > pThis->MethodsCount())); + + lua_remove(lua, 1); lua_remove(lua, -1); + + nRetsOnStack = pThis->ScriptCalling(pThis->Bridge(), nMethod); + + bRetVal = true; + } + } + + if (bRetVal == false) + { + lua_error(lua); + } + + return nRetsOnStack; +} + +bool CLuaScript::CompileScript(const char *szScript, size_t nLength) +{ + CLuaTableThis luaThisTable(m_luaBridge, m_nThisRef); + + return m_luaBridge.RunScript(szScript, nLength); +} + +int CLuaScript::RegisterFunction(const char *szFuncName) +{ + int nMethod = -1; + + CLuaStack luaStack(m_luaBridge); + +LUA_CODE_CHUNK_ENTER(m_luaBridge) + + nMethod = ++m_nMethods; + + lua_rawgeti(state, LUA_REGISTRYINDEX, m_nThisRef); + lua_pushstring(state, szFuncName); + lua_pushnumber(state, (lua_Number)nMethod); + lua_pushcclosure(state, CLuaScript::LuaCallback, 1); + lua_settable(state, -3); + +LUA_CODE_CHUNK_LEAVE + + return nMethod; +} + +bool CLuaScript::SelectScriptFunction(const char *szFunction) +{ + bool bRetVal = true; + +LUA_CODE_CHUNK_ENTER(m_luaBridge) + + lua_rawgeti(state, LUA_REGISTRYINDEX, m_nThisRef); + lua_pushstring(state, szFunction); + lua_rawget(state, -2); + lua_remove(state, -2); + + lua_rawgeti(state, LUA_REGISTRYINDEX, m_nThisRef); + + if (!lua_isfunction(state, -2)) + { + bRetVal = false; + lua_pop(state, 2); + } + else + { + m_nArgs = 0; + m_szFunction = szFunction; + } + +LUA_CODE_CHUNK_LEAVE + + return bRetVal; +} + +bool CLuaScript::ScriptHasFunction(const char * szFunction) +{ + CLuaStack luaStack(m_luaBridge); + + bool bRetVal = false; + +LUA_CODE_CHUNK_ENTER(m_luaBridge) + + lua_rawgeti(state, LUA_REGISTRYINDEX, m_nThisRef); + lua_pushstring(state, szFunction); + lua_rawget(state, -2); + lua_remove(state, -2); + + bRetVal = (lua_isfunction(state, -1) != FALSE); + +LUA_CODE_CHUNK_LEAVE + + return bRetVal; +} + +void CLuaScript::AddParam(char * szValue) +{ +LUA_CODE_CHUNK_ENTER(m_luaBridge) + lua_pushstring(state, szValue); ++m_nArgs; +LUA_CODE_CHUNK_LEAVE +} + +void CLuaScript::AddParam(int nValue) +{ +LUA_CODE_CHUNK_ENTER(m_luaBridge) + lua_pushnumber(state, (lua_Number)nValue); ++m_nArgs; +LUA_CODE_CHUNK_LEAVE +} + +void CLuaScript::AddParam(float fValue) +{ +LUA_CODE_CHUNK_ENTER(m_luaBridge) + lua_pushnumber(state, (lua_Number)fValue); ++m_nArgs; +LUA_CODE_CHUNK_LEAVE +} + +bool CLuaScript::Run(int nRetValues) +{ + bool bRetVal = m_luaBridge.ExecuteFunction((m_nArgs + 1), nRetValues); + + if (bRetVal == true && nRetValues > 0) + { + HandleReturns(m_luaBridge, m_szFunction); + lua_pop(static_cast(m_luaBridge), nRetValues); + } + + return bRetVal; +} + +CLuaBridge & CLuaScript::Bridge() +{ + return m_luaBridge; +} + +int CLuaScript::MethodsCount() +{ + return m_nMethods; +} \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/LuaScript.h b/plugins/!NotAdopted/SmartAutoReplier/LuaScript.h new file mode 100644 index 0000000000..73c29c0a3f --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/LuaScript.h @@ -0,0 +1,68 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This code is inspired by article of RichardS at http://www.codeproject.com/Articles/11508/Integrating-Lua-into-C + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +#include "luainc.h" +#include "LuaBridge.h" + +/// +#define DEFAULT_INDEX_INITIALIZER 0 + +class CLuaScript +{ +public: + CLuaScript(CLuaBridge & luaBridge); + virtual ~CLuaScript(); + +public: + + static int LuaCallback (lua_State *lua); + bool CompileScript(const char *szScript, size_t nLength); + int RegisterFunction(const char *szFuncName); + bool SelectScriptFunction(const char *szFunction); + bool ScriptHasFunction(const char *szFunction); + bool Run(int nRetValues = 0); + +public: + void AddParam(int nValue); + void AddParam(float fValue); + void AddParam(char *szValue); + CLuaBridge & Bridge(); + + int MethodsCount(); + +public: + virtual int ScriptCalling(CLuaBridge & luaBridge, int nFunction) = 0; + virtual void HandleReturns(CLuaBridge & luaBridge, const char * szFunction) = 0; + +protected: + + CLuaBridge & m_luaBridge; + + const char * m_szFunction; + + int m_nMethods, + m_nThisRef, + m_nArgs; +}; \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/MessagesHandler.cpp b/plugins/!NotAdopted/SmartAutoReplier/MessagesHandler.cpp new file mode 100644 index 0000000000..3f3e8e5ad5 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/MessagesHandler.cpp @@ -0,0 +1,469 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" +#include "messageshandler.h" +#include "SarLuaScript.h" +#include + +extern CCrushLog CRUSHLOGOBJ; + +/// init static members... +CMessagesHandler * CMessagesHandler::m_pThis = NULL; + +/// thread that is checking +/// users that sent messages, +/// analize sent time and if +/// reply delay is greater then +/// difference between current time and +/// sent time thread deletes item. +INT WINAPI ContactsFetcherThread(LPVOID lp) +{ +BEGIN_PROTECT_AND_LOG_CODE +#define SLEEP_TIME 50 + CMessagesHandler *pHolder = CMessagesHandler::GetObject(); + if (pHolder) + { + while (pHolder->m_bShouldWork) + { + WaitForSingleObject(pHolder->m_hEnableEvent, INFINITE); + if (!pHolder->m_bShouldWork) + break; + + EnterCriticalSection(&pHolder->m_critSect); + + if (pHolder->m_contacts.size() == 0) + { + LeaveCriticalSection(&pHolder->m_critSect); + Sleep (SLEEP_TIME); + continue; + } + + SYSTEMTIME sysTime = {0}; + FILETIME ft = {0}; + LARGE_INTEGER liNow = {0}; + + GetLocalTime (&sysTime); + SystemTimeToFileTime(&sysTime, &ft); + memcpy(&liNow, &ft, sizeof(liNow)); + + ContactsMap::iterator it; + + CONTACT_METAINFO rawm = {0}; + LARGE_INTEGER liDiff = {0}; + + for (it = pHolder->m_contacts.begin(); it != pHolder->m_contacts.end(); it++) + { + if (pHolder->m_contacts.size() == 0) + { + break; + } + rawm = it->second; + liDiff.QuadPart = liNow.QuadPart - rawm.StartTime.QuadPart; + if (liDiff.QuadPart >= rawm.DiffTime.QuadPart) + { + if (pHolder->m_contacts.size() == 1) + { + pHolder->m_contacts.clear(); + break; + } + else + pHolder->m_contacts.erase(it); + } + } + + LeaveCriticalSection(&pHolder->m_critSect); + + Sleep (SLEEP_TIME); + } + } +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +/// ctor of main plugin manager +CMessagesHandler::CMessagesHandler(void) : IMSingeltone(this), +m_hFetcherThread(NULL), +m_hEnableEvent(NULL), +m_bShouldWork(true), +m_bInited(false) +{ +BEGIN_PROTECT_AND_LOG_CODE + m_settings.Init(); +END_PROTECT_AND_LOG_CODE +} + +/// dtor of main plugin manager +CMessagesHandler::~CMessagesHandler(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + m_settings.DeInit(); + m_bShouldWork = false; + CMessagesHandler::m_pThis = NULL; +END_PROTECT_AND_LOG_CODE +} + +/// enables or disables feature +void CMessagesHandler::MakeAction(bool bEnable) +{ +BEGIN_PROTECT_AND_LOG_CODE + REPLYER_SETTINGS & s = m_settings.getSettings(); + s.bEnabled = bEnable; + m_settings.setSettings(s); + + if (bEnable) + { + HookEvents(); + SetEvent (m_hEnableEvent); + } + else + UnHookEvents(); +END_PROTECT_AND_LOG_CODE +} + +bool CMessagesHandler::AllowReply(HANDLE hContact) +{ +BEGIN_PROTECT_AND_LOG_CODE + if (!m_settings.getSettings().bEnabled) + return FALSE; + ContactsMap::iterator it; + bool bRetVal = false; + + EnterCriticalSection(&m_critSect); + + it = m_contacts.find(hContact); + + SYSTEMTIME sysTime = {0}; + FILETIME ft = {0}; + GetLocalTime (&sysTime); + SystemTimeToFileTime(&sysTime, &ft); + + if (it == m_contacts.end()) + { /// no such contact... + CONTACT_METAINFO cm = {0}; + + memcpy(&cm.StartTime, &ft, sizeof(cm.StartTime)); + cm.DiffTime.QuadPart = m_settings.getSettings().ReplayDelay * nano100SecInSec; + ContactsPair p(hContact, cm); + + m_contacts.insert(p); + bRetVal = true; + } + else + { /// there is one... + memcpy(&it->second.StartTime, &ft, sizeof(it->second.StartTime)); + } + + LeaveCriticalSection(&m_critSect); + + return bRetVal; +END_PROTECT_AND_LOG_CODE + return false; +} + +void CMessagesHandler::HookEvents(void) +{ +BEGIN_PROTECT_AND_LOG_CODE +#ifdef _DEBUG +#endif + + InitializeCriticalSection(&m_critSect); + m_settings.Init(); +#ifdef _DEBUG + bool bEnabled = m_settings.getSettings().bEnabled; +#endif + m_hEnableEvent = CreateEvent(NULL, TRUE, m_settings.getSettings().bEnabled, NULL); + + DWORD dw = 0; + m_bShouldWork = true; + m_hFetcherThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ContactsFetcherThread, NULL, NULL, &dw); + m_hEvents[0] = HookEvent(ME_DB_EVENT_ADDED, CMessagesHandler::EventAddHook); + m_bInited = true; +END_PROTECT_AND_LOG_CODE +} + +void CMessagesHandler::UnHookEvents(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + m_bShouldWork = false; + if (!m_bInited) + return; + SetEvent(m_hEnableEvent); + + for (size_t i = 0; i < HOOKS_NUM; i++) + UnhookEvent(m_hEvents[i]); + + WaitForSingleObject(m_hFetcherThread, INFINITE); + DeleteCriticalSection(&m_critSect); + CloseHandle(m_hEnableEvent); + //m_settings.DeInit(); + + m_hEnableEvent = NULL; + m_hFetcherThread = NULL; + +END_PROTECT_AND_LOG_CODE +} + +LPTSTR CMessagesHandler::GetContactName(HANDLE hContact) +{ + LPARAM lFlags = GCDNF_NOMYHANDLE; + +#ifdef _UNICODE + lFlags |= GCDNF_UNICODE; +#endif +BEGIN_PROTECT_AND_LOG_CODE + return reinterpret_cast(CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, lFlags)); +END_PROTECT_AND_LOG_CODE + return NULL; +} + +int CMessagesHandler::SendProtoMess(HANDLE hContact, LPCSTR szMess) +{ +BEGIN_PROTECT_AND_LOG_CODE + return CallContactService(hContact, PSS_MESSAGE, 0, reinterpret_cast(szMess)); +END_PROTECT_AND_LOG_CODE + return 0; +} + +/** Convert unicode to ansi (utf16 to utf8) + + * @return ansi string or null +*/ +char* Utf16toUtf8(LPCWSTR lpwszStrIn, UINT & nSize) +{ + LPSTR pszOut = NULL; + + if (lpwszStrIn != NULL) + { + +#define SAFE_DELTA 2 + + int nInputStrLen = (int)wcslen(lpwszStrIn); + int nOutputStrLen = WideCharToMultiByte(CP_UTF8, 0, lpwszStrIn, nInputStrLen, NULL, 0, 0, 0); + + if (nOutputStrLen == 0) + { + return NULL; + } + + nOutputStrLen += SAFE_DELTA; + + pszOut = (LPSTR)malloc(nOutputStrLen); + + if (pszOut) + { + nSize = nOutputStrLen - SAFE_DELTA; + memset(pszOut, 0x00, nOutputStrLen); + + WideCharToMultiByte(CP_UTF8, 0, lpwszStrIn, nInputStrLen, pszOut, nOutputStrLen, 0, 0); + } + } + + return pszOut; +} + +/** Convert unicode to ansi (utf16 to utf8) + + * @return ansi string or null +*/ +wchar_t* Utf8toUtf16(CHAR * szStrIn, UINT & nSize) +{ + wchar_t * pszOut = NULL; + + if (szStrIn != NULL) + { + +#define SAFE_DELTA 2 + + int nInputStrLen = (int)nSize; + int nOutputStrLen = MultiByteToWideChar(CP_UTF8, 0, szStrIn, nInputStrLen, NULL, 0); + + if (nOutputStrLen == 0) + { + return NULL; + } + + nOutputStrLen += SAFE_DELTA; + + pszOut = (wchar_t*)malloc(nOutputStrLen * sizeof(wchar_t)); + + if (pszOut) + { + nSize = nOutputStrLen - SAFE_DELTA; + memset(pszOut, 0x00, nOutputStrLen * sizeof(wchar_t)); + + MultiByteToWideChar(CP_UTF8, 0, szStrIn, nInputStrLen, pszOut, nOutputStrLen); + } + } + + return pszOut; +} + +/// this handle is invoked wnen +/// event is added to db +int CMessagesHandler::EventAddHook(WPARAM wp, LPARAM lp) +{ +BEGIN_PROTECT_AND_LOG_CODE + DWORD dwOffset = static_cast (lp); + HANDLE hContact = reinterpret_cast(wp); + DBEVENTINFO dbei; + + if (!hContact || !dwOffset) + { + return FALSE; /// unspecifyed error + } + + ZeroMemory(&dbei, sizeof(dbei)); + dbei.cbSize = sizeof(dbei); + dbei.cbBlob = 0; + + CallService(MS_DB_EVENT_GET, lp, (LPARAM)&dbei); /// detect size of msg + + if ((dbei.eventType != EVENTTYPE_MESSAGE) || (dbei.flags == DBEF_READ) || (dbei.flags == DBEF_SENT) ) + { + return FALSE; /// we need EVENTTYPE_MESSAGE event.. + } + else + { /// needed event has occured.. + if (!dbei.cbBlob) /// invalid size + { + return FALSE; + } + + dbei.pBlob = new BYTE[dbei.cbBlob]; + + if (dbei.pBlob) + { + LPARAM lParam = GCDNF_NOMYHANDLE; + +#ifdef _UNICODE + lParam |= GCDNF_UNICODE; +#endif + CallService(MS_DB_EVENT_GET, lp, reinterpret_cast(&dbei)); + + TCHAR * szMessage = DbGetEventTextT(&dbei, 0); + + TCHAR * szContactName = reinterpret_cast(CallService(MS_CLIST_GETCONTACTDISPLAYNAME, wp, lParam)); + + CMessagesHandler *ptrHolder = NULL; + ptrHolder = CMessagesHandler::GetObject(); + + if (!szContactName || !ptrHolder) + { + return FALSE; + } + + if (!ptrHolder->AllowReply(hContact)) + { + return FALSE; + } + + TCHAR * lpMessage = NULL; + + { + RULE_METAINFO inf = {0}; + inf.ContactName = szContactName; + + /// analizes all rules and formes autoreply + /// message - it's stored in lpMessage + /// then - just sent it to user + CSettingsHandler & settingsManager = ptrHolder->getSettings(); + settingsManager.getStorage().IsRuleMatch(inf, lpMessage, szMessage); + + { + /// do the lua trick + CLuaBridge luaBridge; + CSarLuaScript script(luaBridge); + + UINT nReplyScriptLength = 0; + CHAR * szReplyScript = NULL; + + szReplyScript = Utf16toUtf8(lpMessage, nReplyScriptLength); + + if (szReplyScript != NULL) + { + UINT nUserMessage = 0; + CHAR * szUserMessage = Utf16toUtf8(szMessage, nUserMessage); + + UINT nUserName = 0; + CHAR * szUserName = Utf16toUtf8(szContactName, nUserName); + + script.CompileScript(szReplyScript, nReplyScriptLength); + + script.SelectScriptFunction("SAR"); + script.AddParam((int)hContact); + script.AddParam(szUserMessage); + script.AddParam(szUserName); + script.AddParam((char*)dbei.szModule); + script.Run(); + + free(szReplyScript); + free(szUserMessage); + free(szUserName); + } + } + + mir_free(szMessage); + + delete lpMessage; + delete dbei.pBlob; + + return FALSE; + } + } + } + +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +void CMessagesHandler::WriteToHistory(LPTSTR lpMsg, HANDLE hContact) +{ + LPTSTR lp1 = TranslateTS(TEXT("Generated autoreply:\r\n")); + + LPTSTR lpszMess = new TCHAR[_tcslen(lpMsg) + _tcslen(lp1)]; + if (lpszMess == NULL) + return; + + memset(lpszMess, 0, (_tcslen(lpMsg) + _tcslen(lp1)) * sizeof(TCHAR)); + _tcscpy(lpszMess, lp1); + _tcscat(lpszMess, lpMsg); + + DBEVENTINFO dbei = {0}; + dbei.cbSize = sizeof(dbei); + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.flags = DBEF_READ; + dbei.szModule = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact, 0); + dbei.timestamp = time(NULL); + dbei.cbBlob = _tcslen(lpszMess) + 1; + dbei.pBlob = (PBYTE)lpszMess; + CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei); + + delete lpszMess; +} + +/// getting settings.. +CSettingsHandler & CMessagesHandler::getSettings(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + return m_settings; +END_PROTECT_AND_LOG_CODE +} \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/MessagesHandler.h b/plugins/!NotAdopted/SmartAutoReplier/MessagesHandler.h new file mode 100644 index 0000000000..2d9240f0d5 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/MessagesHandler.h @@ -0,0 +1,72 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +#include "settingshandler.h" +#include "interfaces\ISingletone.h" + +#include +using namespace std; + +typedef struct _CONTACT_METAINFO +{ + LARGE_INTEGER StartTime; + LARGE_INTEGER DiffTime; +}CONTACT_METAINFO,*PCONTACT_METAINFO; + +typedef std::map ContactsMap; +typedef std::pair ContactsPair; +const __int64 nano100SecInSec = (__int64)10000000; + +/// hooks def... +#define HOOKS_NUM 1 + +INT WINAPI ContactsFetcherThread(LPVOID lp); + +class CMessagesHandler : public IMSingeltone +{ + friend INT WINAPI ContactsFetcherThread(LPVOID lp); +public: + CMessagesHandler(void); + ~CMessagesHandler(void); +public: + void HookEvents(void); + void UnHookEvents(void); + void WriteToHistory(LPTSTR lpMsg, HANDLE hContact); + CSettingsHandler & getSettings(void); + bool AllowReply(HANDLE hContact); + void MakeAction(bool bEnable); + static LPTSTR GetContactName(HANDLE hContact); + static int SendProtoMess(HANDLE hContact, LPCSTR szMess); +protected: // hooks procs + static int EventAddHook(WPARAM wp, LPARAM lp); +private: + bool m_bInited; +private: + HANDLE m_hEvents[HOOKS_NUM]; + CSettingsHandler m_settings; + ContactsMap m_contacts; + CRITICAL_SECTION m_critSect; + HANDLE m_hFetcherThread; + HANDLE m_hEnableEvent; + bool m_bShouldWork; +}; \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/ModeMessHandler.cpp b/plugins/!NotAdopted/SmartAutoReplier/ModeMessHandler.cpp new file mode 100644 index 0000000000..5509bea091 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/ModeMessHandler.cpp @@ -0,0 +1,119 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" +#include "modemesshandler.h" + +/// TODO: add comments and change char* to TCHAR* !!! + +/// ctor +CModeMessHandler::CModeMessHandler(void) +{ +} + +/// dtor +CModeMessHandler::~CModeMessHandler(void) +{ +} + +TCHAR * CModeMessHandler::StatusModeToDbSetting(int status, TCHAR *suffix) +{ + LPTSTR prefix; + static TCHAR str[64] = {0}; + + switch(status) { + case ID_STATUS_AWAY: prefix = TEXT("Away"); break; + case ID_STATUS_NA: prefix = TEXT("Na"); break; + case ID_STATUS_DND: prefix = TEXT("Dnd"); break; + case ID_STATUS_OCCUPIED: prefix = TEXT("Occupied"); break; + case ID_STATUS_FREECHAT: prefix = TEXT("FreeChat"); break; + case ID_STATUS_ONLINE: prefix = TEXT("On"); break; + case ID_STATUS_OFFLINE: prefix = TEXT("Off"); break; + case ID_STATUS_INVISIBLE: prefix = TEXT("Inv"); break; + case ID_STATUS_ONTHEPHONE: prefix = TEXT("Otp"); break; + case ID_STATUS_OUTTOLUNCH: prefix = TEXT("Otl"); break; + default: + return NULL; + } + lstrcpy(str, prefix); + _tcscat(str, suffix); + + return str; +} + +LPTSTR CModeMessHandler::GetDefaultMessage(INT status) +{ + switch (status) + { + case ID_STATUS_AWAY: return TranslateTS(TEXT("I've been away since %time%.")); + case ID_STATUS_NA: return TranslateTS(TEXT("Give it up, I'm not in!")); + case ID_STATUS_OCCUPIED: return TranslateTS(TEXT("Not right now.")); + case ID_STATUS_DND: return TranslateTS(TEXT("Give a guy some peace, would ya?")); + case ID_STATUS_FREECHAT: return TranslateTS(TEXT("Well, I would talk to you if Miranda IM supported chat")); + case ID_STATUS_ONLINE: return TranslateTS(TEXT("Yep, I'm here.")); + case ID_STATUS_OFFLINE: return TranslateTS(TEXT("Nope, not here.")); + case ID_STATUS_INVISIBLE: return TranslateTS(TEXT("I'm hiding from the mafia.")); + case ID_STATUS_ONTHEPHONE: return TranslateTS(TEXT("That'll be the phone.")); + case ID_STATUS_OUTTOLUNCH: return TranslateTS(TEXT("Mmm...food.")); + } + return NULL; +} + +/// returnes mode message +/// looks like ret. val should be free(), but +/// read notes in the place where this func is used +LPTSTR CModeMessHandler::GetModeMessage(INT statusMode) +{ + /*DBVARIANT dbv = {0}; + INT nretVal = {0}; /// suppose failure.. + + nretVal = DBGetContactSetting(NULL, TCHAR("SRAway"), StatusModeToDbSetting(statusMode, TCHAR("Msg")), &dbv); + if (nretVal) /// unable to get away msg... + { + dbv.pszVal = _tcsdup(GetDefaultMessage(statusMode)); + if (dbv.pszVal == NULL) /// maybe will occure ;) + { + DBGetContactSetting(NULL, TCHAR("SRAway"), StatusModeToDbSetting(statusMode, TCHAR("Default")), &dbv); + } + } + + int i; + TCHAR substituteStr[128] = {0}; + for(i = 0; dbv.pszVal[i]; i++) + { + if (dbv.pszVal[i] != '%') + continue; + if (!_tcsncicmp((TCHAR*)dbv.pszVal+i, TEXT("%time%"), 6)) + GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, NULL, NULL, substituteStr, sizeof(substituteStr) / sizeof (TCHAR)); + else if (!_tcsncicmp((TCHAR*)dbv.pszVal+i, TEXT("%date%"), 6)) + GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, substituteStr, sizeof(substituteStr) / sizeof(TCHAR)); + else + continue; + if (_tcslen(substituteStr) > 6) + dbv.pszVal = ((TCHAR*))realloc((TCHAR*)dbv.pszVal, _tcslen((TCHAR*)dbv.pszVal) + 1 + _tcslen(substituteStr) - 6); + MoveMemory(dbv.pszVal + i + _tcslen(substituteStr), dbv.pszVal + i + 6, _tcslen(dbv.pszVal) - i - 5); + CopyMemory(dbv.pszVal + i, substituteStr, _tcslen(substituteStr)); + }*/ + + //return dbv.pszVal; + + return NULL; +} \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/ModeMessHandler.h b/plugins/!NotAdopted/SmartAutoReplier/ModeMessHandler.h new file mode 100644 index 0000000000..87931ba487 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/ModeMessHandler.h @@ -0,0 +1,34 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +class CModeMessHandler +{ +public: + CModeMessHandler(void); + ~CModeMessHandler(void); +public: + static LPTSTR GetModeMessage(INT nMode); +private: + static LPTSTR GetDefaultMessage(INT status); + static TCHAR *StatusModeToDbSetting(int status, TCHAR *suffix); +}; diff --git a/plugins/!NotAdopted/SmartAutoReplier/RuleItem.h b/plugins/!NotAdopted/SmartAutoReplier/RuleItem.h new file mode 100644 index 0000000000..dd7bfa7549 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/RuleItem.h @@ -0,0 +1,47 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +#include "interfaces\isettings.h" + +/// a typical rule item +/// contains info to reply to specific user +typedef struct _RULE_ITEM : ISettingsStream +{ + LPTSTR RuleName, /// item name + ContactName, /// contact name + ReplyText; /// reply text + /*ReplyAction; /// reply action*/ +}RULE_ITEM, *PRULE_ITEM; + +/// common item... - a rule that is +/// applied to all users. +typedef struct _COMMON_RULE_ITEM : ISettingsStream +{ + //LPTSTR Header; + LPTSTR Message; +}COMMON_RULE_ITEM, *P_COMMON_RULE_ITEM; + +typedef struct _RULE_METAINFO +{ + LPTSTR ContactName; +}RULE_METAINFO, *PRULE_METAINFO; diff --git a/plugins/!NotAdopted/SmartAutoReplier/RulesStorage.cpp b/plugins/!NotAdopted/SmartAutoReplier/RulesStorage.cpp new file mode 100644 index 0000000000..6b4f6a2ab0 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/RulesStorage.cpp @@ -0,0 +1,536 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" +#include "rulesstorage.h" +#include "crc32static.h" + +extern HINSTANCE hInst; +extern CCrushLog CRUSHLOGOBJ; +extern CMessagesHandler * g_pMessHandler; + +/// ctor... +CRulesStorage::CRulesStorage(void) : m_hFile(NULL) +{ + m_comItem.Message = NULL; +BEGIN_PROTECT_AND_LOG_CODE + MakeFullPath(m_szSettFileName, sizeof(m_szSettFileName), STORAGE_NAME); + InitializeCriticalSection(&m_critSect); +END_PROTECT_AND_LOG_CODE +} + +/// dtor... +CRulesStorage::~CRulesStorage(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + DeleteCriticalSection(&m_critSect); + DeInit(); +END_PROTECT_AND_LOG_CODE +} + +bool CRulesStorage::Serialize(ISettingsStream *pSettings, DWORD & ObjectSize) +{ +BEGIN_PROTECT_AND_LOG_CODE + Flush(); +END_PROTECT_AND_LOG_CODE + return true; +} + +bool CRulesStorage::Deserialize(DWORD & ObjectSize) +{ +BEGIN_PROTECT_AND_LOG_CODE + Init(); +END_PROTECT_AND_LOG_CODE + return false; +} + +/// deiniting... +void CRulesStorage::DeInit(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + if (m_hFile && m_hFile != INVALID_HANDLE_VALUE) + CloseHandle(m_hFile); + + m_hFile = NULL; + + /// now release memory... + for (RulesHash::iterator it = m_hashTable.begin(); it != m_hashTable.end(); it++) + { + RULE_ITEM & i = it->second; + + delete i.ContactName; + delete i.ReplyText; + delete i.RuleName; + } + + m_hashTable.clear(); + + if (m_comItem.Message != NULL) + { + delete m_comItem.Message; + m_comItem.Message = NULL; + } + +END_PROTECT_AND_LOG_CODE +} + +/// writing a string into a file.. +void CRulesStorage::RawWriteDataBufByChunk(LPTSTR str) +{ +BEGIN_PROTECT_AND_LOG_CODE + int nLength = _tcslen(str) * sizeof(TCHAR); + DWORD dwWritten = 0; + BOOL bVal = FALSE; + + bVal = WriteFile(m_hFile, &nLength, sizeof(nLength), &dwWritten, NULL); + + if (!bVal || dwWritten != sizeof(nLength)) + throw bVal; + + bVal = WriteFile(m_hFile, str, nLength, &dwWritten, NULL); + if (!bVal || nLength != dwWritten) + { + throw bVal; + } +END_PROTECT_AND_LOG_CODE +} + +/// flushing all data from memory into a file... +void CRulesStorage::Flush(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + RulesHash::iterator it; + + SetFilePointer(m_hFile, NULL, NULL, FILE_BEGIN); + SetEndOfFile(m_hFile); /// clear old data + + SetCommonMessages(); + + for (it = m_hashTable.begin(); it != m_hashTable.end(); it++) + { + FlushItem(it->second); + } + +END_PROTECT_AND_LOG_CODE +} + +/// n.c. +bool CRulesStorage::IsRuleMatch(RULE_METAINFO & info, LPTSTR & strMess, LPTSTR & lpIncomingMsg) +{ +BEGIN_PROTECT_AND_LOG_CODE + EnterCriticalSection(&m_critSect); + + RulesHash::iterator iter; + bool bExists = false; + DWORD dwCRC32 = 0; + CCrc32Static::StringCrc32(info.ContactName, dwCRC32); + iter = m_hashTable.find(dwCRC32); + + CScriptsReader & screader = g_pMessHandler->getSettings().getScriptsReader(); + + if (iter != m_hashTable.end()) + { + /// I have to make copy of ReplyText, + /// cause GetReturnedMessage will release ptr + /// that is stored rule + /// found this bug after 20 min. of debugging ;( + strMess = new TCHAR[_tcslen(iter->second.ReplyText) + (1 * sizeof(TCHAR))]; + + if (strMess == NULL) /// ooops... + { + //screader.GetReturnMessage(info.ContactName, strMess, lpIncomingMsg); + LeaveCriticalSection(&m_critSect); + + return false; + } + + memset(strMess, 0, _tcslen(iter->second.ReplyText) * sizeof(TCHAR) + (1 * sizeof(TCHAR))); + _tcscpy(strMess, iter->second.ReplyText); + bExists = true; + //screader.GetReturnMessage(iter->second.ContactName, strMess, lpIncomingMsg); + } + else + screader.GetReturnMessage(info.ContactName, strMess, lpIncomingMsg); + + LeaveCriticalSection(&m_critSect); + return bExists; +END_PROTECT_AND_LOG_CODE + return false; +} + +/// adding rule into memory... +DWORD CRulesStorage::AddRuleItem(RULE_ITEM item, bool & bExists) +{ +BEGIN_PROTECT_AND_LOG_CODE + DWORD dwCRC32 = NULL; + CCrc32Static::StringCrc32(item.ContactName, dwCRC32); + RulesHash::iterator iter; + iter = m_hashTable.find(dwCRC32); + + if (iter != m_hashTable.end()) + { + bExists = true; + return 0; + } + + bExists = false; + + m_hashTable.insert(RulesHash::value_type(dwCRC32, item)); + return dwCRC32; +END_PROTECT_AND_LOG_CODE + return 0; +} + +/// flushing item... +void CRulesStorage::FlushItem(RULE_ITEM & item) +{ +BEGIN_PROTECT_AND_LOG_CODE + RawWriteDataBufByChunk(item.RuleName); + RawWriteDataBufByChunk(item.ContactName); + RawWriteDataBufByChunk(item.ReplyText); + //RawWriteDataBufByChunk(item.ReplyAction); +END_PROTECT_AND_LOG_CODE +} + +/// initing rules manager... +void CRulesStorage::Init(void) +{ +#ifdef _DEBUG + //MessageBox (NULL, __FUNCTION__, __FILE__, MB_OK); +#endif +BEGIN_PROTECT_AND_LOG_CODE + if (m_hFile) + CloseHandle (m_hFile); + + bool bFileExists = true; + if (!PathFileExists(m_szSettFileName)) + {/// file does not exists... + /// need to fill it with common rules... + bFileExists = false; + } + + m_hFile = CreateFile (m_szSettFileName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, (bFileExists ? OPEN_ALWAYS : CREATE_ALWAYS), FILE_ATTRIBUTE_NORMAL, NULL); + + if (m_hFile == INVALID_HANDLE_VALUE) + {/// show notification msg to user.. + throw INVALID_HANDLE_VALUE; + } + + if (bFileExists == false) + { + ClearCommonMessages(); + m_comItem.Message = new TCHAR[sizeof(SETTINGS_DEF_MESSAGE) / sizeof(TCHAR) + sizeof(TCHAR)]; + + if (m_comItem.Message != NULL) + { + memset(m_comItem.Message, 0, sizeof(SETTINGS_DEF_MESSAGE) / sizeof(TCHAR) + sizeof(TCHAR)); + _tcscpy(m_comItem.Message, SETTINGS_DEF_MESSAGE); + SetCommonMessages(); + } + } + + DWORD dwSize = 0; + dwSize = GetFileSize(m_hFile, &dwSize); + + DWORD dwReaded = 0, + dwCrc32 = 0; + + int nLength = 0; + + /// suppose that func is failed + BOOL bReaded = FALSE; + bool bFailed = false; + + if (bFileExists) + { + dwSize -= GetCommonMessages(); + } + else + { + dwSize -= _tcslen(SETTINGS_DEF_MESSAGE) * sizeof(TCHAR); + dwSize -= 1 * sizeof(int); + } + + while (dwSize) + { + RULE_ITEM it; + + bReaded = ReadFile(m_hFile, &nLength, sizeof(nLength), &dwReaded, NULL); + + if (bReaded == FALSE || dwReaded != sizeof(nLength)) + { + bFailed = true; + break; + } + + dwSize -= sizeof(nLength); + it.RuleName = new TCHAR[nLength / sizeof(TCHAR) + (1 * sizeof(TCHAR))]; + + if (it.RuleName == NULL) + { + bFailed = true; + break; + } + + memset(it.RuleName, 0, (nLength + (1 * sizeof(TCHAR)))); + + bReaded = ReadFile(m_hFile, it.RuleName, nLength, &dwReaded, NULL); + if (bReaded == FALSE || dwReaded != (nLength)) + { + delete it.RuleName; + bFailed = true; + break; + } + + dwSize -= dwReaded; + bReaded = ReadFile(m_hFile, &nLength, sizeof(nLength), &dwReaded, NULL); + + if (bReaded == FALSE || dwReaded != sizeof(nLength)) + { + delete it.RuleName; + bFailed = true; + break; + } + + dwSize -= sizeof(nLength); + it.ContactName = new TCHAR[nLength / sizeof(TCHAR) + (1 * sizeof(TCHAR))]; + + if (it.ContactName == NULL) + { + delete it.RuleName; + bFailed = true; + break; + } + + memset(it.ContactName, 0, (nLength + (1 * sizeof(TCHAR)))); + bReaded = ReadFile(m_hFile, it.ContactName, nLength, &dwReaded, NULL); + + if (bReaded == FALSE || dwReaded != (nLength)) + { + delete it.RuleName; + delete it.ContactName; + bFailed = true; + break; + } + + dwSize -= dwReaded; + bReaded = ReadFile (m_hFile, &nLength, sizeof(nLength), &dwReaded, NULL); + + if (bReaded == FALSE || dwReaded != sizeof(nLength)) + { + delete it.RuleName; + delete it.ContactName; + bFailed = true; + break; + } + + dwSize -= sizeof(nLength); + it.ReplyText = new TCHAR[nLength / sizeof(TCHAR) + (1 * sizeof(TCHAR))]; + + if (it.ReplyText == NULL) + { + delete it.RuleName; + delete it.ContactName; + bFailed = true; + break; + } + + memset(it.ReplyText, 0, (nLength + (1 * sizeof(TCHAR)))); + bReaded = ReadFile (m_hFile, it.ReplyText, nLength, &dwReaded, NULL); + + if (bReaded == FALSE || dwReaded != (nLength)) + { + delete it.RuleName; + delete it.ContactName; + delete it.ReplyText; + + bFailed = true; + break; + } + + dwSize -= dwReaded; + + dwCrc32 = NULL; + CCrc32Static::StringCrc32(it.ContactName, dwCrc32); + m_hashTable.insert(RulesHash::value_type(dwCrc32, it) ); /// filling list + } + + if (bFailed) + { /// upps... + bool bdelete = NotifyAboutWrongSettings(m_szSettFileName); + + if (bdelete) + { + CloseHandle (m_hFile); + m_hFile = NULL; + DeleteFile (m_szSettFileName); + DeInit(); + Init(); + } + } + +END_PROTECT_AND_LOG_CODE +} + +/// reading an data from file storage... +UINT CRulesStorage::RawReadDataBufByChunk(LPTSTR & szData) +{ +BEGIN_PROTECT_AND_LOG_CODE + UINT nRetVal = 0; + + if (m_hFile == NULL || m_hFile == INVALID_HANDLE_VALUE) + { + return nRetVal; + } + + int nSizeOf = 0; + DWORD dwReaded = 0; + const int nsizeof = sizeof(nSizeOf); + BOOL bReaded = ReadFile(m_hFile, &nSizeOf, nsizeof, &dwReaded, NULL); + nRetVal += dwReaded; + + if (bReaded == FALSE || dwReaded != nsizeof) + { + return nRetVal; + } + + szData = new TCHAR[(nSizeOf / sizeof(TCHAR)) + (1 * sizeof(TCHAR))]; + + if (szData == NULL) + { + return nRetVal + dwReaded; + } + + memset(szData, 0, nSizeOf + (1 * sizeof(TCHAR))); + bReaded = ReadFile(m_hFile, szData, nSizeOf, &dwReaded, NULL); + nRetVal += dwReaded; + + if (bReaded == FALSE || dwReaded != nSizeOf) + { + delete szData; + szData = NULL; + return nRetVal; + } + + return nRetVal; +END_PROTECT_AND_LOG_CODE +} + +/// +void CRulesStorage::SetCommonMessages(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + RawWriteDataBufByChunk(m_comItem.Message); +END_PROTECT_AND_LOG_CODE +} + +void CRulesStorage::ClearCommonMessages(void) +{ + if (m_comItem.Message) + { + delete m_comItem.Message; + m_comItem.Message = NULL; + } +} + +/// reads from storage common rules - header and +/// message that is replyed to all users... +UINT CRulesStorage::GetCommonMessages(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + ClearCommonMessages(); + UINT nRetVal = 0; + + nRetVal += RawReadDataBufByChunk(m_comItem.Message); + + return nRetVal; +END_PROTECT_AND_LOG_CODE +#undef RAW_DATACLEAR + return 0; +} + +void CRulesStorage::setCommonRule(COMMON_RULE_ITEM r) /// n.c. +{ +BEGIN_PROTECT_AND_LOG_CODE + memcpy (&m_comItem, &r, sizeof(COMMON_RULE_ITEM)); +END_PROTECT_AND_LOG_CODE +} + +COMMON_RULE_ITEM & CRulesStorage::getCommonRule(void) /// n.c. +{ +BEGIN_PROTECT_AND_LOG_CODE + return m_comItem; +END_PROTECT_AND_LOG_CODE +} + +/// getting hash table +RulesHash & CRulesStorage::getHashTable(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + return m_hashTable; +END_PROTECT_AND_LOG_CODE +} + +/// remove rule by its id +bool CRulesStorage::RemReplyAction(DWORD dwCrc32) +{ + bool bRetVal = false; +BEGIN_PROTECT_AND_LOG_CODE + EnterCriticalSection(&m_critSect); + RulesHash::iterator it; + it = m_hashTable.find(dwCrc32); + if (it != m_hashTable.end()) + { + delete it->second.ContactName; + delete it->second.ReplyText; + delete it->second.RuleName; + + m_hashTable.erase(it); + bRetVal = true; + } + LeaveCriticalSection(&m_critSect); +END_PROTECT_AND_LOG_CODE + return bRetVal; +} + +bool CRulesStorage::RuleIsRegistered(LPTSTR lpContactName) +{ +BEGIN_PROTECT_AND_LOG_CODE + bool bRetVal = false; + if (lpContactName == NULL) + return bRetVal; + DWORD dwCRC32 = NULL; + CCrc32Static::StringCrc32(lpContactName, dwCRC32); + RulesHash::iterator iter; + + EnterCriticalSection(&m_critSect); + iter = m_hashTable.find(dwCRC32); + + if (iter != m_hashTable.end()) + { + bRetVal = true; + } + LeaveCriticalSection(&m_critSect); + + return bRetVal; +END_PROTECT_AND_LOG_CODE + return false; +} \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/RulesStorage.h b/plugins/!NotAdopted/SmartAutoReplier/RulesStorage.h new file mode 100644 index 0000000000..25cbec2942 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/RulesStorage.h @@ -0,0 +1,63 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +#include "RuleItem.h" +#include + +#define STORAGE_NAME TEXT("sar.rsu") /// a def. name of a file that is storing settings +typedef std::map RulesHash; /// storage representation in memory + +/// storage manager.. +class CRulesStorage : ISettings +{ +public: /// ctor'rs, dtors.. + CRulesStorage(void); + ~CRulesStorage(void); +public: /// ISettings interface... + bool Serialize(ISettingsStream *pSettings, DWORD & ObjectSize); + bool Deserialize(DWORD & ObjectSize); +public: + void Init(void); /// initing state of an object + void DeInit(void); /// deiniting state of an object + DWORD AddRuleItem(RULE_ITEM item, bool & bExists); /// n.c. + bool RemReplyAction(DWORD dwCrc32); /// n.c. + RulesHash & getHashTable(void); /// n.c. + COMMON_RULE_ITEM & getCommonRule(void); /// n.c. + void setCommonRule(COMMON_RULE_ITEM r); /// n.c. + void Flush(void); /// flushes all from memory to a file + void FlushItem(RULE_ITEM & item); /// flushes an item into file from memory + bool IsRuleMatch(RULE_METAINFO & info, LPTSTR & strMess, LPTSTR & lpIncomingMsg); /// n.c. + void ClearCommonMessages(void); /// releases memory that is commited for comm. rule + bool RuleIsRegistered(LPTSTR lpContactName); +private: + void RawWriteDataBufByChunk(LPTSTR); /// writes string to a file + UINT RawReadDataBufByChunk(LPTSTR & szData); /// reads string from file + UINT GetCommonMessages(void); /// gets common rules from file to memory + void SetCommonMessages(void); /// sets common rules from memory to file +private: + COMMON_RULE_ITEM m_comItem; /// common rule item.. + RulesHash m_hashTable; /// main storage... + HANDLE m_hFile; /// handle to file that is storing data + TCHAR m_szSettFileName[MAX_PATH]; /// path to a file... + CRITICAL_SECTION m_critSect; /// needed for sync +}; \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/SAR.cpp b/plugins/!NotAdopted/SmartAutoReplier/SAR.cpp new file mode 100644 index 0000000000..a2617b496b --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/SAR.cpp @@ -0,0 +1,462 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" +#include "resource.h" + +/// these dlg are necessary here.. +#include "gui\settingsdlgholder.h" +#include "gui\EditReplyDlg.h" +#include "gui\addruledlg.h" + +#include "../updater/m_updater.h" + +/// let's advertise myselft and this plugin ;) +#define ICQPROTONAME "SAR" +#if defined( _UNICODE ) +#define ICQPROTODECRSHORT "Smart Auto Replier" +#else +#define ICQPROTODECRSHORT "Smart Auto Replier" +#endif +#define ICQPROTODECR "Plugin is able to reply on all incoming messages, making possible use of rules that are applied to specific contacts. Plugin allows to use Lua scripts as a rules, thus allowing user to make virtually any type of customizations." +#define DEVNAME "Volodymyr M. Shcherbyna" +#define DEVMAIL "volodymyr@shcherbyna.com" +#define DEVCOPYRIGHT "© 2004-2012 Volodymyr M. Shcherbyna, www.shcherbyna.com" +#define DEVWWW "http://www.shcherbyna.com/forum/viewforum.php?f=8" +#define GLOB_HOOKS 3 + +/// global menu items strings... +#define MENU_ITEM_DISABLE_CAPTION TranslateTS(TEXT("Disable Smart Auto Replier")) +#define MENU_ITEM_ENABLE_CAPTION TranslateTS(TEXT("Enable Smart Auto Replier")) + +//#define +/// global data... +HINSTANCE hInst = NULL; /// hinstance +PLUGINLINK *pluginLink = NULL; /// ptr to plugin object +CMessagesHandler *g_pMessHandler = NULL; /// ptr to "main" global manager object +CSettingsDlgHolder *g_pSettingsDlg = NULL; +static HANDLE g_hHook[GLOB_HOOKS] = {NULL}; /// global hooks +CLISTMENUITEM g_mi = {NULL}; /// handle to menu item that is used to switch on/off plugin +CLISTMENUITEM g_miAUR2This = {NULL}; /// handle to menu item that is used to add user to aur +bool g_bEnableMItem = true; /// flag for menu item.. +HANDLE g_hMenuItem; /// global handle to menu service +CCrushLog CRUSHLOGOBJ; /// global object that handles all crushes +LPTSTR g_strPluginName = TEXT(ICQPROTONAME); /// global string that represents plugin name... +INT g_nCurrentMode = 0; /// current mode of a protocol == i duno which exactly protocol... +HANDLE g_hAUR2User = NULL; /// handle to proto service of "autoreply to this user" + +struct MM_INTERFACE mmi; + +/// forming an info structure +PLUGININFOEX pluginInfo = +{ + sizeof(PLUGININFOEX), + ICQPROTODECRSHORT, + PLUGIN_MAKE_VERSION(2, 0, 0, 3), + ICQPROTODECR, + DEVNAME, + DEVMAIL, + DEVCOPYRIGHT, + DEVWWW, + UNICODE_AWARE, + 0, +//#if defined( _UNICODE ) +// // {B9C9AC38-9D81-45D3-A9D7-67A7D8EA9D29} +// { 0xb9c9ac38, 0x9d81, 0x45d3, { 0xa9, 0xd7, 0x67, 0xa7, 0xd8, 0xea, 0x9d, 0x29 } } +//#else + // {9E536082-017E-423B-BF4F-DEDFEB9B3B60} + { 0x9e536082, 0x17e, 0x423b, { 0xbf, 0x4f, 0xde, 0xdf, 0xeb, 0x9b, 0x3b, 0x60 } } +//#endif +}; + +/// mapping into mirandaim.exe +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ +BEGIN_PROTECT_AND_LOG_CODE + hInst = hinstDLL; + DisableThreadLibraryCalls(hinstDLL); + return TRUE; +END_PROTECT_AND_LOG_CODE +} + +__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +extern "C" __declspec(dllexport) const MUUID interfaces[] = {MIID_CHAT, MIID_SRMM, MIID_LAST}; + +__declspec(dllexport) const MUUID * MirandaPluginInterfaces(void) +{ + return interfaces; +} + +/// handler of event when the options are choosed +static int OptionsInitialized(WPARAM wp, LPARAM lp) +{ +BEGIN_PROTECT_AND_LOG_CODE + LPTSTR lpszGroup = TranslateTS(TEXT("Plugins")); + OPTIONSDIALOGPAGE optsDialog = {0}; + optsDialog.cbSize = sizeof(OPTIONSDIALOGPAGE); + optsDialog.hInstance = hInst; + optsDialog.position = 910000000; + optsDialog.pszTemplate = (char*)MAKEINTRESOURCE(IDD_SDLGHOLDER); + TCHAR szMax[MAX_PATH] = {0}; + _tcscpy(szMax, TranslateTS(TEXT(ICQPROTODECRSHORT))); + +#ifdef _UNICODE + optsDialog.ptszGroup = lpszGroup; + optsDialog.ptszTitle = szMax; +#else + optsDialog.pszTitle = (char*)szMax; + optsDialog.pszGroup = lpszGroup; +#endif + optsDialog.pfnDlgProc = (DLGPROC)&CSettingsDlgHolder::FakeDlgProc; + optsDialog.flags = ODPF_BOLDGROUPS/*|ODPF_EXPERTONLY*/; /// some lames are scaring that option... +#ifdef _UNICODE + optsDialog.flags |= ODPF_UNICODE; +#endif + + g_pSettingsDlg->m_bDestroying = false; + CallService(MS_OPT_ADDPAGE, wp, reinterpret_cast(&optsDialog)); +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +/// pre building menu item for a contact.. +static int AURContactPreBuildMenu(WPARAM wParam, LPARAM lParam) +{ + LPTSTR lpContactName = g_pMessHandler->GetContactName(reinterpret_cast(wParam)); + CRulesStorage & storage = g_pMessHandler->getSettings().getStorage(); + bool bval = storage.RuleIsRegistered(lpContactName); + + if (bval) + { + g_miAUR2This.flags = CMIM_FLAGS | CMIF_GRAYED; + } + else + { + g_miAUR2This.flags = CMIM_FLAGS; + } + + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hAUR2User, (LPARAM)&g_miAUR2This); + + return 0; +} + +/// handler of clicking on menu item +/// aur to this user... +static int AUR2User(WPARAM wParam, LPARAM lParam) +{ + CAddRuleDlg dlg; + RULE_ITEM item; + item.ContactName = g_pMessHandler->GetContactName(reinterpret_cast(wParam)); + //item.ReplyAction = " "; + item.ReplyText = SETTINGS_DEF_MESSAGE_RULE; + TCHAR rulename[MAX_PATH * 5] = {0}; + _tcscat(rulename, TEXT("reply to ")); + _tcscat(rulename, item.ContactName); + item.RuleName = rulename; + + dlg.m_baur2thisMode = true; + dlg.m_item = item; + dlg.DoModal(); + if (dlg.m_bAddedOk) + { /// already added... + OnRefreshSettings(); + } + + return 0; +} + +/// handler of clicking on menu item enablr/disable plugin... +static int PluginMenuCommand(WPARAM wParam, LPARAM lParam) +{ +BEGIN_PROTECT_AND_LOG_CODE + if (!g_pMessHandler) + return 0; + + if (g_bEnableMItem) + {/// lets handle enabling of AUR feature + g_pMessHandler->MakeAction(true); /// this will enable plugin + } + else + {/// lets handle disabling of AUR feature + g_pMessHandler->MakeAction(false); /// this will disable plugin + } + + /// put here stuff to do + TCHAR sz[MAX_PATH] = {0}; + _tcscpy(sz, (g_bEnableMItem == true ? MENU_ITEM_DISABLE_CAPTION : MENU_ITEM_ENABLE_CAPTION)); + g_mi.pszName = (char*)TranslateTS(sz); + g_mi.flags = CMIM_NAME; + +#ifdef _UNICODE + g_mi.flags |= CMIF_UNICODE; +#endif + +#ifdef _DEBUG + int nretval = +#endif + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hMenuItem, (LPARAM)&g_mi); + + g_bEnableMItem = !g_bEnableMItem; +END_PROTECT_AND_LOG_CODE + return 0; +} + +/// handler that is invoked when mode is changed +static int OnStatusModeChanged(WPARAM wp, LPARAM lp) +{ +BEGIN_PROTECT_AND_LOG_CODE + g_nCurrentMode = static_cast(wp); + if (!g_pMessHandler) + return FALSE; + + bool bNonOnOffLine = (wp != ID_STATUS_ONLINE && + wp != ID_STATUS_OFFLINE && + wp != ID_STATUS_FREECHAT); + + REPLYER_SETTINGS & s = g_pMessHandler->getSettings().getSettings(); + COMMON_RULE_ITEM & r = g_pMessHandler->getSettings().getStorage().getCommonRule(); + + if (!bNonOnOffLine && s.bDisableWhenModeIsSet) + { + if (s.bEnabled) /// plugin is enabled... we have a chance to disable it + { + bool bDisableIt = false; + + if (s.ModeDisValue == 0) + bDisableIt = true; + else if (s.ModeDisValue == 1 && wp == ID_STATUS_ONLINE) + bDisableIt = true; + else if (s.ModeDisValue == 2 && wp == ID_STATUS_FREECHAT) + bDisableIt = true; + + if (bDisableIt) + { /// disable plugin... + PluginMenuCommand(0, 0); + } + } + return FALSE; + } + + if (s.bShowAURDlgWhenModeChanges) + { + CEditReplyDlg dlg; + dlg.m_commRule = r; + + dlg.DoModal(); + if (dlg.m_bAllOk) + { + r = dlg.m_commRule; + } + } + if (s.bEnableWhenModeIsSet) + { + if (!s.bEnabled) + { + bool bEnable = false; + if (s.ModeValue == 0 && bNonOnOffLine) + bEnable = true; + else if (s.ModeValue == 1 && wp == ID_STATUS_DND) + bEnable = true; + else if (s.ModeValue == 2 && wp == ID_STATUS_NA) + bEnable = true; + else if (s.ModeValue == 3 && wp == ID_STATUS_AWAY) + bEnable = true; + else if (s.ModeValue == 4 && wp == ID_STATUS_OCCUPIED) + bEnable = true; + + if (bEnable) /// enabling plugin... (I realize that enabling and disabling is made via ass but i am lazy today) + PluginMenuCommand(0, 0); + } + } + + return FALSE; +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +#ifndef _DEBUG +LPTOP_LEVEL_EXCEPTION_FILTER UnhandledExceptionFilter( + LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter +) +{ + LPTOP_LEVEL_EXCEPTION_FILTER f = {0}; +BEGIN_PROTECT_AND_LOG_CODE + throw f; /// show msgbox to user and store inf to file +END_PROTECT_AND_LOG_CODE + return f; /// let compiler shut ups... +} +#endif + +int OnModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + Update update = {0}; // for c you'd use memset or ZeroMemory... + char szVersion[16]; + + update.cbSize = sizeof(Update); + + update.szComponentName = pluginInfo.shortName; + update.pbVersion = (BYTE*)CreateVersionStringPluginEx(&pluginInfo, szVersion); + update.cpbVersion = strlen((char*)update.pbVersion); + + // these are the three lines that matter - the archive, the page containing the version string, and the text (or data) + // before the version that we use to locate it on the page + // (note that if the update URL and the version URL point to standard file listing entries, the backend xml + // data will be used to check for updates rather than the actual web page - this is not true for beta urls) + //update.szUpdateURL = "http://www.shcherbyna.com/files/sar/SAR.zip"; + //update.szVersionURL = "http://www.shcherbyna.com/files/sar/SAR.html"; + + update.szUpdateURL = "http://addons.miranda-im.org/details.php?action=viewfile&id=1609"; + + //update.pbVersionPrefix = (BYTE *)"SAR version "; + + //update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix); + + // do the same for the beta versions of the above struct members if you wish to allow beta updates from another URL + + CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update); + + // Alternatively, to register a plugin with e.g. file ID 2254 on the file listing... + // CallService(MS_UPDATE_REGISTERFL, (WPARAM)2254, (LPARAM)&pluginInfo); + + return 0; +} + +/// loading plugin +extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) +{ +#ifndef _DEBUG + SetUnhandledExceptionFilter(UnhandledExceptionFilter); +#endif +#ifdef _DEBUG + //MessageBox (NULL, __FUNCTION__, __FILE__, MB_OK); +#endif + + CCrushLog::Init(); /// crushes manager should be inited first + int nRetVal = 0; +BEGIN_PROTECT_AND_LOG_CODE + pluginLink = link; + +#ifndef _DEBUG + /// creates help file near plugin + /// if it is absent... + /// note: originally help is in recources of plugin + //CheckForHelpFile(); +#endif + /// main manager... + g_pMessHandler = new CMessagesHandler(); + g_pSettingsDlg = new CSettingsDlgHolder(); + + if (g_pMessHandler) + { /// is inited + REPLYER_SETTINGS & s = g_pMessHandler->getSettings().getSettings(); + if (s.bDisableWhenMirandaIsOn) + { + s.bEnabled = false; + } + else + { + if (s.bEnabled) + g_pMessHandler->HookEvents(); + } + + /// hook main events + //HookEvent(MS_AWAYMSG_SHOWAWAYMSG, OnShow + g_hHook[0] = HookEvent(ME_OPT_INITIALISE, OptionsInitialized); + g_hHook[1] = HookEvent(ME_CLIST_STATUSMODECHANGE, OnStatusModeChanged); + g_hHook[2] = HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded); + + /// Yushenko Tak, Yanukovich - Mudak. (Orange revolution) + /// this was written in 2004-2005 in Kiev :) + + /// create menu item for disabling / enabling plugin + CreateServiceFunction("AUR/MenuCommand", PluginMenuCommand); + ZeroMemory(&g_mi, sizeof(g_mi)); + g_mi.cbSize = sizeof(g_mi); + g_mi.position = -0x7FFFFFFF; + g_mi.flags = 0; + g_mi.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_SAR_ICON)); //LoadSkinnedIcon(IDI_AUR_ICON/*SKINICON_OTHER_MIRANDA*/); + bool bVal = g_pMessHandler->getSettings().getSettings().bEnabled; + TCHAR sz[MAX_PATH] = {0}; + _tcscpy(sz, bVal ? MENU_ITEM_DISABLE_CAPTION : MENU_ITEM_ENABLE_CAPTION); +#ifdef _UNICODE + g_mi.ptszName = TranslateTS(sz); + g_mi.flags = CMIF_UNICODE; +#else + g_mi.pszName = (char*)TranslateTS(sz); +#endif + g_mi.pszService = "AUR/MenuCommand"; + + g_hMenuItem = (HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&g_mi); + g_bEnableMItem = !bVal; + + /// creating menu item for a contact + ZeroMemory(&g_miAUR2This, sizeof(g_miAUR2This)); + g_miAUR2This.cbSize = sizeof(g_miAUR2This); + g_miAUR2This.position = -2000010000; + g_miAUR2This.flags = 0; + g_miAUR2This.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_SAR_ICON)); + g_miAUR2This.pszContactOwner = NULL; +#ifdef _UNICODE + g_miAUR2This.ptszName = TranslateTS(TEXT("&Smart Auto Reply to this user ...")); + g_miAUR2This.flags = CMIF_UNICODE; +#else + g_miAUR2This.pszName = TranslateTS(TEXT("&Smart Auto Reply to this user ...")); +#endif + CreateServiceFunction("AUR/AURToThis", AUR2User); + g_miAUR2This.pszService = "AUR/AURToThis"; + g_hAUR2User = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&g_miAUR2This); + HookEvent(ME_CLIST_PREBUILDCONTACTMENU, AURContactPreBuildMenu); + } + + CallService(MS_SYSTEM_GET_MMI, 0, (LPARAM)&mmi); + +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +/// unloading plugin +extern "C" int __declspec(dllexport) Unload(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + for (size_t i = 0; i < GLOB_HOOKS; i++) + UnhookEvent(g_hHook[i]); + + if (g_pSettingsDlg) + { + if (g_pSettingsDlg->IsWindow()) + g_pSettingsDlg->DestroyWindow(); + delete g_pSettingsDlg; + } + if (g_pMessHandler) + { /// unhook manager's events... + g_pMessHandler->UnHookEvents(); + delete g_pMessHandler; /// call dtor + g_pMessHandler = NULL; + } +END_PROTECT_AND_LOG_CODE + + CCrushLog::DeInit(); /// destroy crushes manager obj + return FALSE; +} diff --git a/plugins/!NotAdopted/SmartAutoReplier/SAR.rc b/plugins/!NotAdopted/SmartAutoReplier/SAR.rc new file mode 100644 index 0000000000..5ae222d012 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/SAR.rc @@ -0,0 +1,274 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Ukrainian (Ukraine) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_UKR) +LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT +#pragma code_page(1251) + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPTIONS DIALOGEX 0, 0, 308, 208 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IDC_EDIT_REPLAYDELAY,68,10,29,13,ES_MULTILINE | ES_AUTOHSCROLL | ES_WANTRETURN | ES_NUMBER + EDITTEXT IDC_EDIT_MESSAGE,68,24,232,53,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL + LISTBOX IDC_LIST_RULES,60,84,236,61,LBS_SORT | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Add rule",IDC_BTN_ADDRULE,8,85,50,14 + PUSHBUTTON "Delete rule",IDC_BTN_DELRULE,8,101,50,14,WS_DISABLED + PUSHBUTTON "Edit rule",IDC_BTN_EDITRULE,8,117,50,14,WS_DISABLED + LTEXT "Action script:",IDC_STATIC_MESSAGE_TEXT,8,42,51,10 + GROUPBOX "Auto replier settings",IDC_STATIC,0,0,306,204 + LTEXT "Reply delay:",IDC_STATIC,9,12,41,8 + LTEXT "second(s)",IDC_STATIC,106,13,32,8 + GROUPBOX "Custom rules",IDC_STATIC,5,75,294,73 + CONTROL "Disable when Miranda is switched on",IDC_CHECK_DISABLEWMON, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,149,12,151,11 + CONTROL "Enable when status becomes",IDC_CH_ENABLE_WSCH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,152,125,10 + COMBOBOX IDC_CB_ENWSC,144,151,156,36,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Ask to set autoreply message when mode changes",IDC_CH_SHOWCG, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,180,266,10 + CONTROL "Disable when status becomes",IDC_CH_DISWHSB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,167,129,10 + COMBOBOX IDC_CB_DWSB,143,165,156,40,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Save autoreplies to history",IDC_CH_SAVE_AURS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,193,266,10 +END + +IDD_ADDRULE_DLG DIALOGEX 0, 0, 384, 250 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Add contact specific Smart Auto Replier action script" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IDC_ED_RULENAME,68,14,184,12,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL + EDITTEXT IDC_ED_RULECNAME,68,29,168,13,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL + EDITTEXT IDC_ED_RULEREPLY,21,54,342,166,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL + DEFPUSHBUTTON "OK",IDOK,325,231,50,14 + PUSHBUTTON "Cancel",IDCANCEL,273,231,50,14 + PUSHBUTTON "...",IDC_BTN_SELUSER,238,28,13,14 + GROUPBOX "Rule settings",IDC_STATIC,7,3,368,225 + LTEXT "Rule name:",IDC_STATIC,15,16,41,10 + LTEXT "Contact name",IDC_STATIC,15,31,46,10 + GROUPBOX "Action script",IDC_STATIC,14,42,355,182 +END + +IDD_SET_AURMESSAGEDLG DIALOGEX 0, 0, 291, 157 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Set Smart Auto Replier action script" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IDC_ED_TEXT,6,10,278,123,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL + DEFPUSHBUTTON "OK",IDOK,239,139,50,14 + PUSHBUTTON "Cancel",IDCANCEL,186,139,50,14 + GROUPBOX "Smart Auto Replier action script",IDC_STATIC,2,0,287,137 +END + +IDD_SEL_USER DIALOGEX 0, 0, 92, 194 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Select user from a list" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "Select",IDOK,51,178,40,14 + PUSHBUTTON "Exit",IDCANCEL,1,178,38,14 + LISTBOX IDC_LIST_USERS,1,2,89,174,LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP +END + +IDD_HISTORYLOGS DIALOGEX 0, 0, 186, 95 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 +END + +IDD_SDLGHOLDER DIALOGEX 0, 0, 326, 253 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_TABSHOLDER,"SysTabControl32",0x0,4,13,316,224 + LTEXT "Static",IDC_STATUSMSG,7,3,300,8 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_OPTIONS, DIALOG + BEGIN + LEFTMARGIN, 7 + TOPMARGIN, 3 + BOTTOMMARGIN, 195 + END + + IDD_ADDRULE_DLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 377 + TOPMARGIN, 7 + BOTTOMMARGIN, 247 + END + + IDD_SET_AURMESSAGEDLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 284 + TOPMARGIN, 7 + BOTTOMMARGIN, 150 + END + + IDD_SEL_USER, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 85 + TOPMARGIN, 7 + BOTTOMMARGIN, 187 + END + + IDD_HISTORYLOGS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END + + IDD_SDLGHOLDER, DIALOG + BEGIN + LEFTMARGIN, 2 + RIGHTMARGIN, 302 + TOPMARGIN, 3 + BOTTOMMARGIN, 237 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_SAR_ICON ICON "sar.ico" +#endif // Ukrainian (Ukraine) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// French (Switzerland) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRS) +LANGUAGE LANG_FRENCH, SUBLANG_FRENCH_SWISS +#pragma code_page(1252) + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 2,0,0,3 + PRODUCTVERSION 2,0,0,3 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "042204b0" + BEGIN + VALUE "CompanyName", "Volodymyr Shcherbyna, www.shcherbyna.com" + VALUE "FileDescription", "Smart Auto Replier plugin for Miranda IM, http://shcherbyna.com/forum/viewforum.php?f=8" + VALUE "FileVersion", "2.0.0.3" + VALUE "InternalName", "sar.dll" + VALUE "LegalCopyright", "Copyright (C) 2004 - 2012 by Volodymyr Shcherbyna" + VALUE "OriginalFilename", "sar.dll" + VALUE "ProductName", "sar.dll" + VALUE "ProductVersion", "2.0.0.3" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x422, 1200 + END +END + +#endif // French (Switzerland) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/!NotAdopted/SmartAutoReplier/SAR.vcxproj b/plugins/!NotAdopted/SmartAutoReplier/SAR.vcxproj new file mode 100644 index 0000000000..3091d45ae8 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/SAR.vcxproj @@ -0,0 +1,189 @@ +п»ї + + + + Debug + Win32 + + + Release + Win32 + + + Template + Win32 + + + + {C71749EF-EBA8-4317-9F9E-327E1A7366EC} + Win32Proj + SAR + + + + DynamicLibrary + MultiByte + true + + + DynamicLibrary + Static + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + Debug\ + Debug\ + true + Release\ + Release\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + ..\lualib;..\wtl\Include;$(IncludePath) + ..\wtl\Include;$(IncludePath) + + + + Disabled + C:\Users\vshcherbyna\Downloads\aur\wtl\Include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;SAR_EXPORTS;UNICODE;_UNICODE + true + EnableFastChecks + MultiThreadedDebug + Use + Level3 + EditAndContinue + + + D:\Projects\smart-auto-replier\sar\Debug\lualib.lib;shell32.lib;comctl32.lib;%(AdditionalDependencies) + C:\Program Files (x86)\Miranda IM\Plugins\Sar.dll + true + $(OutDir)SAR.pdb + Windows + 0x40000000 + false + + + $(OutDir)SAR.lib + MachineX86 + sar.def + + + + + MinSpace + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;SAR_EXPORTS;UNICODE;_UNICODE;%(PreprocessorDefinitions) + MultiThreaded + Use + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + true + Windows + true + true + 0x40000000 + false + + + $(OutDir)SAR.lib + MachineX86 + D:\Projects\smart-auto-replier\sar\Release\lualib.lib;%(AdditionalDependencies) + sar.def + + + + + sar.def + + + + + + + + + + + + + + + + + + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/SAR.vcxproj.filters b/plugins/!NotAdopted/SmartAutoReplier/SAR.vcxproj.filters new file mode 100644 index 0000000000..8c8e9d59f4 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/SAR.vcxproj.filters @@ -0,0 +1,77 @@ +п»ї + + + + + + + + + + + + + + + + + + + + Lua + + + Lua + + + Lua + + + + + + + + + + + + + + + + + + + + + + + + + + Lua + + + Lua + + + Lua + + + Lua + + + + + + + + {f3d54a11-21ba-4f12-b8c0-8576228a1625} + + + + + + + \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/SarLuaScript.cpp b/plugins/!NotAdopted/SmartAutoReplier/SarLuaScript.cpp new file mode 100644 index 0000000000..d83f82c51d --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/SarLuaScript.cpp @@ -0,0 +1,358 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This code is inspired by article of RichardS at http://www.codeproject.com/Articles/11508/Integrating-Lua-into-C + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" +#include "SarLuaScript.h" + +#include "../miranda32/m_protomod.h" +#include "../miranda32/m_protosvc.h" + +extern INT g_nCurrentMode; +extern CMessagesHandler *g_pMessHandler; + +wchar_t* Utf8toUtf16(CHAR * szStrIn, UINT & nSize); +char* Utf16toUtf8(LPCWSTR lpwszStrIn, UINT & nSize); + +CSarLuaScript::CSarLuaScript(CLuaBridge & luaBridge) : CLuaScript(luaBridge) +{ + m_nFuncBaseIndex = RegisterFunction("SendMessage"); + + RegisterFunction("GetMyStatus"); + RegisterFunction("SetMyStatus"); + RegisterFunction("Wait"); + RegisterFunction("FindUser"); + RegisterFunction("SetVariable"); + RegisterFunction("GetVariable"); +} + +CSarLuaScript::~CSarLuaScript(void) +{ +} + +int CSarLuaScript::ScriptCalling(CLuaBridge & luaBridge, int nFncNumber) +{ + switch (nFncNumber - m_nFuncBaseIndex) + { + case 0: + return SendMessage(luaBridge); + + case 1: + return GetMyStatus(luaBridge); + + case 2: + return SetMyStatus(luaBridge); + + case 3: + return Wait(luaBridge); + + case 4: + return FindUser(luaBridge); + + case 5: + return SetVariable(luaBridge); + + case 6: + return GetVariable(luaBridge); + } + + return FALSE; +} + +int CSarLuaScript::SendMessage(CLuaBridge & luaBridge) +{ + lua_State *pFunctionContext = (lua_State*)luaBridge; + + UINT nMessageLen = lua_strlen(pFunctionContext, -1); + const char * szMessage = lua_tostring(pFunctionContext, -1); + int hUserToken = (int)lua_tonumber(pFunctionContext, -2); + + if (szMessage == NULL) + { + return FALSE; + } + + int nRetVal = 0; + +#ifdef _UNICODE + /*/// as I am in unicode, I have to convert all strings from utf8 to utf16 :) + wchar_t * szwMessage = Utf8toUtf16((char*)szMessage, nMessageLen);*/ + + nRetVal = CallContactService((HANDLE)hUserToken, PSS_MESSAGE, PREF_UTF, reinterpret_cast(szMessage)); + + /*free(szwMessage);*/ +#else + nRetVal = CallContactService((HANDLE)hUserToken, PSS_MESSAGE, 0, reinterpret_cast(szMessage)); +#endif + + return FALSE; +} + +int CSarLuaScript::GetMyStatus(CLuaBridge & luaBridge) +{ + lua_State *pFunctionContext = (lua_State*)luaBridge; + int nStatusMode = CallService(MS_CLIST_GETSTATUSMODE, (WPARAM)0, (LPARAM)0); + + nStatusMode = g_nCurrentMode; + + switch (nStatusMode) + { + case ID_STATUS_ONLINE: + AddParam("Online"); + break; + + case ID_STATUS_OFFLINE: + AddParam("Offline"); + break; + + case ID_STATUS_AWAY: + AddParam("Away"); + break; + + case ID_STATUS_DND: + AddParam("DND"); + break; + + case ID_STATUS_NA: + AddParam("NA"); + break; + + case ID_STATUS_OCCUPIED: + AddParam("Occupied"); + break; + + case ID_STATUS_FREECHAT: + AddParam("FreeChat"); + break; + + case ID_STATUS_INVISIBLE: + AddParam("Invisible"); + break; + + case ID_STATUS_ONTHEPHONE: + AddParam("OnThePhone"); + break; + + case ID_STATUS_OUTTOLUNCH: + AddParam("OutToLunch"); + break; + + default: + AddParam("Unknown"); + break; + } + + return TRUE; +} + +int CSarLuaScript::SetMyStatus(CLuaBridge & luaBridge) +{ + int nNewStatus = 0; + lua_State *pFunctionContext = (lua_State*)luaBridge; + + const char * szStatus = lua_tostring(pFunctionContext, -1); + + if (szStatus == NULL) + { + return FALSE; + } + + if (strcmp(szStatus, "Online") == 0) + { + nNewStatus = ID_STATUS_ONLINE; + } + else if (strcmp(szStatus, "Offline") == 0) + { + nNewStatus = ID_STATUS_OFFLINE; + } + else if (strcmp(szStatus, "Away") == 0) + { + nNewStatus = ID_STATUS_AWAY; + } + else if (strcmp(szStatus, "DND") == 0) + { + nNewStatus = ID_STATUS_DND; + } + else if (strcmp(szStatus, "NA") == 0) + { + nNewStatus = ID_STATUS_NA; + } + else if (strcmp(szStatus, "Occupied") == 0) + { + nNewStatus = ID_STATUS_OCCUPIED; + } + else if (strcmp(szStatus, "FreeChat") == 0) + { + nNewStatus = ID_STATUS_FREECHAT; + } + else if (strcmp(szStatus, "Invisible") == 0) + { + nNewStatus = ID_STATUS_INVISIBLE; + } + else if (strcmp(szStatus, "OnThePhone") == 0) + { + nNewStatus = ID_STATUS_ONTHEPHONE; + } + else if (strcmp(szStatus, "OutToLunch") == 0) + { + nNewStatus = ID_STATUS_OUTTOLUNCH; + } + + CallService(MS_CLIST_SETSTATUSMODE, (WPARAM)nNewStatus, (LPARAM)0); + + return FALSE; +} + +typedef map MapOfStrings; + +MapOfStrings g_MapOfVariables; + +int CSarLuaScript::SetVariable(CLuaBridge & luaBridge) +{ + lua_State *pFunctionContext = (lua_State*)luaBridge; + + UINT nNameLength = lua_strlen(pFunctionContext, -2); + const char * szName = lua_tostring(pFunctionContext, -2); + + UINT nVariableLength = lua_strlen(pFunctionContext, -1); + const char * szVariable = lua_tostring(pFunctionContext, -1); + + if (szName == NULL || szVariable == NULL) + { + return FALSE; + } + + wchar_t * szwName = Utf8toUtf16((char*)szName, nNameLength); + wchar_t * szwVariable = Utf8toUtf16((char*)szVariable, nVariableLength); + + if (szwName && szwVariable) + { + g_MapOfVariables[szwName] = szwVariable; + } + + if (szwName) + { + free(szwName); + } + + if (szwVariable) + { + free(szwVariable); + } + + return FALSE; +} + +int CSarLuaScript::GetVariable(CLuaBridge & luaBridge) +{ + lua_State *pFunctionContext = (lua_State*)luaBridge; + + UINT nNameLength = lua_strlen(pFunctionContext, -1); + const char * szName = lua_tostring(pFunctionContext, -1); + + if (szName == NULL) + { + return FALSE; + } + + wchar_t * szwName = Utf8toUtf16((char*)szName, nNameLength); + + if (szwName) + { + MapOfStrings::iterator it = g_MapOfVariables.find(szwName); + + if (it != g_MapOfVariables.end()) + { + UINT nSize = 0; + char * szUtf = Utf16toUtf8(it->second.c_str(), nSize); + + if (szUtf != NULL) + { + AddParam(szUtf); + free(szUtf); + free(szwName); + + return TRUE; + } + } + } + + if (szwName) + { + free(szwName); + } + + return FALSE; +} + +int CSarLuaScript::Wait(CLuaBridge & luaBridge) +{ + lua_State *pFunctionContext = (lua_State*)luaBridge; + + int nSleepInterval = (int)lua_tonumber(pFunctionContext, -1); + + Sleep(1000 * nSleepInterval); + + return FALSE; +} + +int CSarLuaScript::FindUser(CLuaBridge & luaBridge) +{ + lua_State *pFunctionContext = (lua_State*)luaBridge; + + const CHAR * szUser = (CHAR*)lua_tostring(pFunctionContext, -2); + const CHAR * szProtocol = (CHAR*)lua_tostring(pFunctionContext, -1); + + if (szProtocol == NULL || szUser == NULL) + { + return FALSE; + } + + HANDLE hContact = reinterpret_cast(CallService(MS_DB_CONTACT_FINDFIRST, 0, 0)); + CHAR* szContactName = NULL; + CHAR* szProto = NULL; + DWORD wId = 0; + + while (hContact != NULL) + { + szContactName = reinterpret_cast(CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_NOMYHANDLE)); + szProto = (CHAR*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + + if (szProto && szContactName) + { + if ( (strcmp(szUser, szContactName)) == 0 && (strcmp(szProto, szProtocol) == 0)) + { + AddParam((int)hContact); + return TRUE; + } + } + + hContact = reinterpret_cast (CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM) hContact, 0)); + } + + return FALSE; +} + +void CSarLuaScript::HandleReturns(CLuaBridge & luaBridge, const char *szFunc) +{ + +} \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/SarLuaScript.h b/plugins/!NotAdopted/SmartAutoReplier/SarLuaScript.h new file mode 100644 index 0000000000..26b9ba1a61 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/SarLuaScript.h @@ -0,0 +1,57 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This code is inspired by article of RichardS at http://www.codeproject.com/Articles/11508/Integrating-Lua-into-C + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +#include "LuaBridge.h" +#include "LuaScript.h" + +#include +#include + +using namespace std; + +class CSarLuaScript : public CLuaScript +{ +public: + CSarLuaScript(CLuaBridge & luaBridge); + ~CSarLuaScript(void); + +private: + int SendMessage(CLuaBridge & luaBridge); + int GetMyStatus(CLuaBridge & luaBridge); + int SetMyStatus(CLuaBridge & luaBridge); + int Wait(CLuaBridge & luaBridge); + int FindUser(CLuaBridge & luaBridge); + int SetVariable(CLuaBridge & luaBridge); + int GetVariable(CLuaBridge & luaBridge); + +protected: + int ScriptCalling(CLuaBridge & luaBridge, int nFncNumber); + + void HandleReturns(CLuaBridge & luaBridge, const char *szFunc); + +protected: + int m_nFuncBaseIndex; +}; + diff --git a/plugins/!NotAdopted/SmartAutoReplier/ScriptsReader.cpp b/plugins/!NotAdopted/SmartAutoReplier/ScriptsReader.cpp new file mode 100644 index 0000000000..4bd45d22e6 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/ScriptsReader.cpp @@ -0,0 +1,175 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" +#include "scriptsreader.h" +#include "messageshandler.h" +#include "modemesshandler.h" + +extern INT g_nCurrentMode; +extern CMessagesHandler * g_pMessHandler; + +/// ctor +CScriptsReader::CScriptsReader(void) +{ +} + +/// dtor +CScriptsReader::~CScriptsReader(void) +{ +} + +/// dtor +void CScriptsReader::InternalInit(void) +{ +} + +ACTIONS CScriptsReader::ParceString(LPTSTR & strMessage) +{ + ACTIONS act; + return act; +} + +bool CScriptsReader::Replace(LPSTR & lpString, LPSTR strReplWhat, LPSTR & strReplWith) +{ +BEGIN_PROTECT_AND_LOG_CODE + if (strcmp(lpString, strReplWhat) == 0) + { + strcpy(lpString, strReplWith); + return true; + } + char * ptr = strstr(lpString, strReplWhat); + if (ptr) + { + int nPos = static_cast(ptr - lpString + 1); + if (!nPos) + return false; + char *szPrev = new char[nPos]; + + if (!szPrev) + return false; + strncpy(szPrev, lpString, nPos - 1); + int nPos2 = static_cast(nPos + strlen(strReplWhat)); + int nLength = static_cast(strlen(lpString)); + int nSize2 = nLength - nPos2 + 1; + if (nSize2 == 0) + nSize2++; + char *szPost = new char[nSize2]; + if (!szPost) + { + delete szPrev; + return false; + } + ptr += strlen(strReplWhat); + if (nPos == 1) + { + ptr++; + } + strncpy(szPost, ptr, nSize2); + strcpy(lpString, szPrev); + strcat(lpString, strReplWith); + if (nPos == 1) + strcat(lpString, " "); + strcat(lpString, szPost); + delete szPrev; + delete szPost; + + return Replace(lpString, strReplWhat, strReplWith); + } + else + return false; +END_PROTECT_AND_LOG_CODE + return false; +} + +/// returnes message that is replied to contact. +/// the core of a plugin ;) (a joke..) +bool CScriptsReader::GetReturnMessage(LPTSTR lpContactName, LPTSTR & lpMsg, LPTSTR & lpIncomingMsg) +{ +BEGIN_PROTECT_AND_LOG_CODE + DWORD dwSizeOfMess = SETTINGS_MESSAGE_MAXVALENGTH + SETTINGS_HEADER_MAXVALENGTH; + dwSizeOfMess += _tcslen(lpIncomingMsg); + LPTSTR szOwnNick = g_pMessHandler->GetContactName(NULL); + if (szOwnNick) + dwSizeOfMess += _tcslen(szOwnNick); + + bool bspecific = (lpMsg != NULL); + dwSizeOfMess = dwSizeOfMess * 3; /// Any replacing can cause increasing size of data + LPTSTR lpPrev = NULL; + if (bspecific) + { + dwSizeOfMess += _tcslen(lpMsg); + lpPrev = lpMsg; + } + + lpMsg = new TCHAR[dwSizeOfMess]; + + memset(lpMsg, 0, dwSizeOfMess * sizeof(TCHAR)); + + COMMON_RULE_ITEM & commRule = g_pMessHandler->getSettings().getStorage().getCommonRule(); + + if (!bspecific) + { + _tcscpy(lpMsg, commRule.Message); + } + else + { + _tcscpy(lpMsg, lpPrev); + VirtualFree (lpPrev, NULL, MEM_RELEASE); + } + + /*TCHAR strDate[0x100] = {0}; + SYSTEMTIME t = {0}; + GetLocalTime(&t); + sprintf(strDate, "[%d-%d-%d %d-%d-%d]", t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond); + LPSTR lp = strDate; + if (!bspecific) + { + _tcscat(lpMsg, "\r\n"); + _tcscat(lpMsg, commRule.Message); + } + + Replace(lpMsg, SETTINGS_SCRIPT_CURRDATA, lp); + Replace(lpMsg, SETTINGS_SCRIPT_USERNAME, lpContactName); + Replace(lpMsg, SETTINGS_SCRIPT_OWNNICKNAME, szOwnNick); + + LPTSTR lptMMess = CModeMessHandler::GetModeMessage(g_nCurrentMode); + + if (lptMMess) + { + Replace(lpMsg, SETTINGS_SCRIPT_MODEMESSAGE, lptMMess); + /// seems like i should free this ptr + /// but when this is done heap is corrupted + /// so better we have a leak of small amount + /// of memory then corrupted heap. (imho).Sad + /// free (lptMMess); + } + + Replace(lpMsg, SETTINGS_SCRIPT_INCOMMINGMESSAGE, lpIncomingMsg);*/ + + if (lpMsg) + return true; + else + return false; + +END_PROTECT_AND_LOG_CODE + return false; +} \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/ScriptsReader.h b/plugins/!NotAdopted/SmartAutoReplier/ScriptsReader.h new file mode 100644 index 0000000000..c2b89c3d0f --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/ScriptsReader.h @@ -0,0 +1,57 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +#include + +/// class that converts all scripts +/// into an actions or raw text + +/// replacing commands +#define SETTINGS_SCRIPT_USERNAME "%username%" +#define SETTINGS_SCRIPT_CURRDATA "%currdate%" +#define SETTINGS_SCRIPT_MODEMESSAGE "%modemessage%" +#define SETTINGS_SCRIPT_INCOMMINGMESSAGE "%incomingmessage%" +#define SETTINGS_SCRIPT_OWNNICKNAME "%ownnickname%" + +/// actios commands + +typedef struct _ACTION +{ + LPTSTR ActionCode; +}ACTION, *PACTION; + +typedef std::list ACTIONS; + +class CScriptsReader +{ +public: + CScriptsReader(void); + ~CScriptsReader(void); +public: + ACTIONS ParceString(LPTSTR & strMessage); + bool GetReturnMessage(LPTSTR lpContactName, LPTSTR & lpMsg, LPTSTR & lpIncomingMsg); + static bool Replace(LPSTR & lpString, LPSTR strReplWhat, LPSTR & strReplWith); +private: + void InternalInit(void); +private: +}; \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/SettingsHandler.cpp b/plugins/!NotAdopted/SmartAutoReplier/SettingsHandler.cpp new file mode 100644 index 0000000000..c95ea0c539 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/SettingsHandler.cpp @@ -0,0 +1,204 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" +#include "settingshandler.h" +#include "modemesshandler.h" + +/// we need hinst +extern HINSTANCE hInst; +extern CCrushLog CRUSHLOGOBJ; +extern INT g_nCurrentMode; + +/// ctor +CSettingsHandler::CSettingsHandler(void) : m_bResettings(false), +m_replSize(sizeof(REPLYER_SETTINGS)) +{ +BEGIN_PROTECT_AND_LOG_CODE + MakeFullPath(m_szSettFileName, sizeof(m_szSettFileName), SETTINGS_DB); + m_rulesStorage.Init(); +END_PROTECT_AND_LOG_CODE +} + +/// d'ctor +CSettingsHandler::~CSettingsHandler(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + DeInit(); + m_rulesStorage.Flush(); +END_PROTECT_AND_LOG_CODE +} + +/// changing settings... +void CSettingsHandler::setSettings(REPLYER_SETTINGS & settings, COMMON_RULE_ITEM * pcommrule) +{ +BEGIN_PROTECT_AND_LOG_CODE + m_Settings = settings; +#ifdef _DEBUG + bool bflushed = +#endif + Serialize(&m_Settings, m_replSize); + if (pcommrule) + { + m_rulesStorage.setCommonRule(*pcommrule); + DWORD dw = NULL; + m_rulesStorage.Serialize(NULL, dw); + } +END_PROTECT_AND_LOG_CODE +} + +bool CSettingsHandler::Serialize(ISettingsStream *pSettings, DWORD & ObjectSize) +{ +BEGIN_PROTECT_AND_LOG_CODE + bool bRetVal = false; + HANDLE hFile = CreateFile (m_szSettFileName, GENERIC_WRITE, + FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == NULL || hFile == INVALID_HANDLE_VALUE) + return bRetVal; /// + else + { /// check ptr for null + bool bValid = (pSettings != NULL); + if (bValid) /// for readibility.. + bValid = (IsBadReadPtr(pSettings, sizeof(pSettings)) == TRUE ? false : true); + + DWORD dwWritten = NULL; + bRetVal = (WriteFile (hFile, (bValid ? pSettings : &m_Settings), sizeof(REPLYER_SETTINGS), &dwWritten, NULL) == TRUE ? true : false); + CloseHandle (hFile); + return bRetVal; + } +END_PROTECT_AND_LOG_CODE + return false; +} + +bool CSettingsHandler::Deserialize(DWORD & ObjectSize) +{ +BEGIN_PROTECT_AND_LOG_CODE + bool bRetVal = false; + HANDLE hFile = CreateFile (m_szSettFileName, GENERIC_READ, + FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == NULL || hFile == INVALID_HANDLE_VALUE) + return bRetVal; /// + else + { + DWORD dwSizeHigh = 0; + DWORD dwSize = GetFileSize(hFile, &dwSizeHigh); + + if (dwSize != ObjectSize) + { + bool bDel = NotifyAboutWrongSettings(m_szSettFileName); + if (bDel) + { + CloseHandle (hFile); + DeleteFile (m_szSettFileName); + m_bResettings = true; + Init(); + m_bResettings = false; + return true; + } + } + DWORD dwReaded = NULL; + bRetVal = (ReadFile (hFile, &m_Settings, ObjectSize, &dwReaded, NULL) == TRUE ? true : false); + CloseHandle (hFile); + + return bRetVal; + } +END_PROTECT_AND_LOG_CODE + return false; +} + +void CSettingsHandler::Init(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + + if (!PathFileExists(m_szSettFileName)) + { /// create file with def settings... + /// create def. configuration and store it to file... + m_Settings.bDisableWhenModeIsSet = SETTINGS_DEF_COMMON_EN_DISONMODEON; + m_Settings.ModeDisValue = SETTINGS_DEF_COMMON_EN_ONMODEDISVAL; + m_Settings.bShowAURDlgWhenModeChanges = false; + m_Settings.bEnableWhenModeIsSet = SETTINGS_DEF_COMMON_EN_ONMODEON; + m_Settings.ModeValue = SETTINGS_DEF_COMMON_EN_ONMODEONVAL; + + m_Settings.bDisableWhenMirandaIsOn = SETTINGS_DEF_COMMON_DWMION; + m_Settings.ReplayDelay = SETTINGS_DEF_COMMON_VALREPDELAY; + m_Settings.bEnabled = true; + m_Settings.bFirstRun = !m_bResettings; + m_Settings.bSaveToHistory = false; + + Serialize(&m_Settings, m_replSize); + + if (m_Settings.bFirstRun) + { /// show only once to user readme file... + m_Settings.bFirstRun = false; + TCHAR * szreadme = NULL; + szreadme = new TCHAR[MAX_PATH + 1]; + if (szreadme) + { + //MakeFullPath(szreadme, MAX_PATH, READMEFILE); + ::ShellExecute(NULL, TEXT("open"), TEXT("http://www.shcherbyna.com/?page_id=1747"), NULL, NULL, SW_SHOW); + //::ShellExecute(NULL, "open", TEXT("http://shcherbyna.com/forum/viewforum.php?f=8"), NULL, NULL, SW_SHOW); + + delete szreadme; + } + } + } + else + { + Deserialize(m_replSize); + } +END_PROTECT_AND_LOG_CODE +} + +void CSettingsHandler::DeInit(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + Serialize(&m_Settings, m_replSize); +END_PROTECT_AND_LOG_CODE +} + +CScriptsReader & CSettingsHandler::getScriptsReader(void) +{ + return m_scriptsReader; +} + +REPLYER_SETTINGS & CSettingsHandler::getSettings(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + return m_Settings; +END_PROTECT_AND_LOG_CODE +} + +DWORD CSettingsHandler::AddReplyAction(RULE_ITEM item, bool & bExists) +{ +BEGIN_PROTECT_AND_LOG_CODE + return m_rulesStorage.AddRuleItem(item, bExists); +END_PROTECT_AND_LOG_CODE + return 0; +} + +CRulesStorage & CSettingsHandler::getStorage(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + return m_rulesStorage; +END_PROTECT_AND_LOG_CODE +} \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/SettingsHandler.h b/plugins/!NotAdopted/SmartAutoReplier/SettingsHandler.h new file mode 100644 index 0000000000..9e0a859796 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/SettingsHandler.h @@ -0,0 +1,96 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +#include "RuleItem.h" +#include "RulesStorage.h" +#include "interfaces\ISettings.h" +#include "comfunc.h" +#include "scriptsreader.h" + +/// settings defs... +#define SETTINGS_DB TEXT("sar.csu") +#define READMEFILE TEXT("sar.html") + +#define SETTINGS_HEADER_MAXVALENGTH 1024 * 1 /// 1 kb by def +#define SETTINGS_MESSAGE_MAXVALENGTH 1024 * 3 /// 3 kb by def + +#define SETTINGS_DEF_COMMON_DWMION 1 +#define SETTINGS_DEF_COMMVALUE 0 + +#define SETTINGS_DEF_MESSAGE TEXT("function this.SAR(this, hUser, szMessage, szUser, szProtocol)\r\n this:SendMessage(hUser, \"Here is my autoreply!\")\r\nend") +#define SETTINGS_DEF_MESSAGE_RULE TEXT("-- Main handler function written in Lua:\r\n\r\nfunction this.SAR(this, hUser, szMessage, szUser, szProtocol)\r\n this:SendMessage(hUser, \"Here is my specific to user autoreply!\")\r\nend") +#define SETTINGS_DEF_RULE_NAME TEXT("Some generic rule name") + +#define SETTINGS_DEF_COMMON_VALREPDELAY 2 +#define SETTINGS_DEF_COMMON_EN_ONMODEON 0 +#define SETTINGS_DEF_COMMON_EN_DISONMODEON 0 + +#define SETTINGS_DEF_COMMON_EN_ONMODEDISVAL 0 +#define SETTINGS_DEF_COMMON_EN_ONMODEONVAL 0 +#define SETTINGS_DEF_COMMON_SHOWAURDLGWMC 0 + +/// settings that are stored in file... +/// serialized +typedef struct _REPLYER_SETTINGS : ISettingsStream +{ + bool bEnabled; + bool bDisableWhenMirandaIsOn; + int ReplayDelay; + bool bEnableWhenModeIsSet; + bool bDisableWhenModeIsSet; + int ModeValue; + int ModeDisValue; + bool bShowAURDlgWhenModeChanges; + bool bFirstRun; + bool bSaveToHistory; +}REPLYER_SETTINGS, *PREPLYER_SETTINGS; + +#ifndef MAX_PATH + #define MAX_PATH 260 +#endif + +/// manager that handles settings of a plugin... +class CSettingsHandler : ISettings +{ +public: + CSettingsHandler(void); + ~CSettingsHandler(void); +public: /// ISettings interface... + bool Serialize(ISettingsStream *pSettings, DWORD & ObjectSize); + bool Deserialize(DWORD & ObjectSize); +public: + void Init(void); /// deserialize... + void DeInit(void); /// serialize... + REPLYER_SETTINGS & getSettings(void); + CScriptsReader & getScriptsReader(void); + CRulesStorage & getStorage(void); + void setSettings(REPLYER_SETTINGS & settings, COMMON_RULE_ITEM * pcommrule = NULL); + DWORD AddReplyAction(RULE_ITEM item, bool & bExists); +private: + REPLYER_SETTINGS m_Settings; + TCHAR m_szSettFileName[MAX_PATH]; + bool m_bResettings; + CRulesStorage m_rulesStorage; + CScriptsReader m_scriptsReader; + DWORD m_replSize; +}; \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/comfunc.cpp b/plugins/!NotAdopted/SmartAutoReplier/comfunc.cpp new file mode 100644 index 0000000000..0f79871fbb --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/comfunc.cpp @@ -0,0 +1,74 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" +#include "comfunc.h" +#include "shlobj.h" + +extern LPTSTR g_strPluginName; +extern HINSTANCE hInst; + +/// show to user msgbox that settings +/// file is corrupted... +bool NotifyAboutWrongSettings(LPTSTR szFile) +{ + TCHAR szTxt[MAX_PATH * 2] = {0}; + _tcscpy(szTxt, TEXT("Settings file: ")); + _tcscat(szTxt, szFile); + _tcscat(szTxt, TEXT(" is corrupted !\n")); + _tcscat(szTxt, TEXT("As a result plugin can crush.\n")); + _tcscat(szTxt, TEXT("Reset settings to default ?")); + + DWORD dw = MessageBox(NULL, TranslateTS(szTxt), g_strPluginName, MB_YESNO); + return (dw == IDYES); +} + +/// forming path +bool MakeFullPath(LPTSTR lpRetval, DWORD dwSize, LPTSTR lpFile) +{ + HRESULT hr = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, lpRetval); + size_t nLen = _tcslen(lpRetval); + + if (lpRetval[nLen - 1] != TEXT('\\')) + { + _tcscat(lpRetval, TEXT("\\Sar\\")); + } + else + { + _tcscat(lpRetval, TEXT("Sar\\")); + } + + _tcscat(lpRetval, lpFile); + + /*GetModuleFileName(hInst, lpRetval, dwSize); + TCHAR *ptrPos = _tcsrchr(lpRetval, '\\'); + if (ptrPos) + { + ptrPos++; + _tcscpy (ptrPos, lpFile); + } + else + { + _RPT0(_CRT_WARN, "MakeFullPath - unable to form path"); + return false; + }*/ + return true; +} \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/comfunc.h b/plugins/!NotAdopted/SmartAutoReplier/comfunc.h new file mode 100644 index 0000000000..ab74a7e8ca --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/comfunc.h @@ -0,0 +1,26 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +bool NotifyAboutWrongSettings(LPTSTR szFile); +bool MakeFullPath(LPTSTR lpRetval, DWORD dwSize, LPTSTR lpFile); +bool CheckForHelpFile(); \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/comlogging.h b/plugins/!NotAdopted/SmartAutoReplier/comlogging.h new file mode 100644 index 0000000000..ea8482a198 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/comlogging.h @@ -0,0 +1,42 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +/// define hlobal object.. +#ifndef CRUSHLOGOBJ + #define CRUSHLOGOBJ g_crushLog +#endif + +/// this macro should be placed at the begining of any func of plugin.. +#ifndef BEGIN_PROTECT_AND_LOG_CODE + #define BEGIN_PROTECT_AND_LOG_CODE try { \ + SetLastError(0); +#endif + +/// this macro should be placed at the end of any func of plugin.. +#ifndef END_PROTECT_AND_LOG_CODE + #define END_PROTECT_AND_LOG_CODE } \ + catch (...) \ + { \ + CCrushLog::InternalProtect(__FUNCTION__, __FILE__, __DATE__, __LINE__, GetLastError());\ + } +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/luainc.h b/plugins/!NotAdopted/SmartAutoReplier/luainc.h new file mode 100644 index 0000000000..276c25bae5 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/luainc.h @@ -0,0 +1,31 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This code is inspired by article of RichardS at http://www.codeproject.com/Articles/11508/Integrating-Lua-into-C + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +extern "C" +{ + #include "../lualib/lua.h" + #include "../lualib/lauxlib.h" + #include "../lualib/lualib.h" +} \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/ReadMe.txt b/plugins/!NotAdopted/SmartAutoReplier/lualib/ReadMe.txt new file mode 100644 index 0000000000..457efed27e --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/ReadMe.txt @@ -0,0 +1,37 @@ +======================================================================== + STATIC LIBRARY : lualib Project Overview +======================================================================== + +AppWizard has created this lualib library project for you. + +This file contains a summary of what you will find in each of the files that +make up your lualib application. + + +lualib.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +lualib.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + + +///////////////////////////////////////////////////////////////////////////// + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named lualib.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lapi.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/lapi.c new file mode 100644 index 0000000000..d5dd9ca465 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lapi.c @@ -0,0 +1,922 @@ +/* +** $Id: lapi.c,v 1.235 2003/04/07 14:36:08 roberto Exp $ +** Lua API +** See Copyright Notice in lua.h +*/ + + +#include +#include + +#define lapi_c + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" + + +const char lua_ident[] = + "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n" + "$Authors: " LUA_AUTHORS " $\n" + "$URL: www.lua.org $\n"; + + + +#ifndef api_check +#define api_check(L, o) /*{ assert(o); }*/ +#endif + +#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) + +#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;} + + + + +static TObject *negindex (lua_State *L, int idx) { + if (idx > LUA_REGISTRYINDEX) { + api_check(L, idx != 0 && -idx <= L->top - L->base); + return L->top+idx; + } + else switch (idx) { /* pseudo-indices */ + case LUA_REGISTRYINDEX: return registry(L); + case LUA_GLOBALSINDEX: return gt(L); + default: { + TObject *func = (L->base - 1); + idx = LUA_GLOBALSINDEX - idx; + lua_assert(iscfunction(func)); + return (idx <= clvalue(func)->c.nupvalues) + ? &clvalue(func)->c.upvalue[idx-1] + : NULL; + } + } +} + + +static TObject *luaA_index (lua_State *L, int idx) { + if (idx > 0) { + api_check(L, idx <= L->top - L->base); + return L->base + idx - 1; + } + else { + TObject *o = negindex(L, idx); + api_check(L, o != NULL); + return o; + } +} + + +static TObject *luaA_indexAcceptable (lua_State *L, int idx) { + if (idx > 0) { + TObject *o = L->base+(idx-1); + api_check(L, idx <= L->stack_last - L->base); + if (o >= L->top) return NULL; + else return o; + } + else + return negindex(L, idx); +} + + +void luaA_pushobject (lua_State *L, const TObject *o) { + setobj2s(L->top, o); + incr_top(L); +} + + +LUA_API int lua_checkstack (lua_State *L, int size) { + int res; + lua_lock(L); + if ((L->top - L->base + size) > LUA_MAXCSTACK) + res = 0; /* stack overflow */ + else { + luaD_checkstack(L, size); + if (L->ci->top < L->top + size) + L->ci->top = L->top + size; + res = 1; + } + lua_unlock(L); + return res; +} + + +LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { + int i; + lua_lock(to); + api_checknelems(from, n); + from->top -= n; + for (i = 0; i < n; i++) { + setobj2s(to->top, from->top + i); + api_incr_top(to); + } + lua_unlock(to); +} + + +LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { + lua_CFunction old; + lua_lock(L); + old = G(L)->panic; + G(L)->panic = panicf; + lua_unlock(L); + return old; +} + + +LUA_API lua_State *lua_newthread (lua_State *L) { + lua_State *L1; + lua_lock(L); + luaC_checkGC(L); + L1 = luaE_newthread(L); + setthvalue(L->top, L1); + api_incr_top(L); + lua_unlock(L); + lua_userstateopen(L1); + return L1; +} + + + +/* +** basic stack manipulation +*/ + + +LUA_API int lua_gettop (lua_State *L) { + return (L->top - L->base); +} + + +LUA_API void lua_settop (lua_State *L, int idx) { + lua_lock(L); + if (idx >= 0) { + api_check(L, idx <= L->stack_last - L->base); + while (L->top < L->base + idx) + setnilvalue(L->top++); + L->top = L->base + idx; + } + else { + api_check(L, -(idx+1) <= (L->top - L->base)); + L->top += idx+1; /* `subtract' index (index is negative) */ + } + lua_unlock(L); +} + + +LUA_API void lua_remove (lua_State *L, int idx) { + StkId p; + lua_lock(L); + p = luaA_index(L, idx); + while (++p < L->top) setobjs2s(p-1, p); + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_insert (lua_State *L, int idx) { + StkId p; + StkId q; + lua_lock(L); + p = luaA_index(L, idx); + for (q = L->top; q>p; q--) setobjs2s(q, q-1); + setobjs2s(p, L->top); + lua_unlock(L); +} + + +LUA_API void lua_replace (lua_State *L, int idx) { + lua_lock(L); + api_checknelems(L, 1); + setobj(luaA_index(L, idx), L->top - 1); /* write barrier */ + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_pushvalue (lua_State *L, int idx) { + lua_lock(L); + setobj2s(L->top, luaA_index(L, idx)); + api_incr_top(L); + lua_unlock(L); +} + + + +/* +** access functions (stack -> C) +*/ + + +LUA_API int lua_type (lua_State *L, int idx) { + StkId o = luaA_indexAcceptable(L, idx); + return (o == NULL) ? LUA_TNONE : ttype(o); +} + + +LUA_API const char *lua_typename (lua_State *L, int t) { + UNUSED(L); + return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; +} + + +LUA_API int lua_iscfunction (lua_State *L, int idx) { + StkId o = luaA_indexAcceptable(L, idx); + return (o == NULL) ? 0 : iscfunction(o); +} + + +LUA_API int lua_isnumber (lua_State *L, int idx) { + TObject n; + const TObject *o = luaA_indexAcceptable(L, idx); + return (o != NULL && tonumber(o, &n)); +} + + +LUA_API int lua_isstring (lua_State *L, int idx) { + int t = lua_type(L, idx); + return (t == LUA_TSTRING || t == LUA_TNUMBER); +} + + +LUA_API int lua_isuserdata (lua_State *L, int idx) { + const TObject *o = luaA_indexAcceptable(L, idx); + return (o != NULL && (ttisuserdata(o) || ttislightuserdata(o))); +} + + +LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { + StkId o1 = luaA_indexAcceptable(L, index1); + StkId o2 = luaA_indexAcceptable(L, index2); + return (o1 == NULL || o2 == NULL) ? 0 /* index out of range */ + : luaO_rawequalObj(o1, o2); +} + + +LUA_API int lua_equal (lua_State *L, int index1, int index2) { + StkId o1, o2; + int i; + lua_lock(L); /* may call tag method */ + o1 = luaA_indexAcceptable(L, index1); + o2 = luaA_indexAcceptable(L, index2); + i = (o1 == NULL || o2 == NULL) ? 0 /* index out of range */ + : equalobj(L, o1, o2); + lua_unlock(L); + return i; +} + + +LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { + StkId o1, o2; + int i; + lua_lock(L); /* may call tag method */ + o1 = luaA_indexAcceptable(L, index1); + o2 = luaA_indexAcceptable(L, index2); + i = (o1 == NULL || o2 == NULL) ? 0 /* index out-of-range */ + : luaV_lessthan(L, o1, o2); + lua_unlock(L); + return i; +} + + + +LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { + TObject n; + const TObject *o = luaA_indexAcceptable(L, idx); + if (o != NULL && tonumber(o, &n)) + return nvalue(o); + else + return 0; +} + + +LUA_API int lua_toboolean (lua_State *L, int idx) { + const TObject *o = luaA_indexAcceptable(L, idx); + return (o != NULL) && !l_isfalse(o); +} + + +LUA_API const char *lua_tostring (lua_State *L, int idx) { + StkId o = luaA_indexAcceptable(L, idx); + if (o == NULL) + return NULL; + else if (ttisstring(o)) + return svalue(o); + else { + const char *s; + lua_lock(L); /* `luaV_tostring' may create a new string */ + s = (luaV_tostring(L, o) ? svalue(o) : NULL); + luaC_checkGC(L); + lua_unlock(L); + return s; + } +} + + +LUA_API size_t lua_strlen (lua_State *L, int idx) { + StkId o = luaA_indexAcceptable(L, idx); + if (o == NULL) + return 0; + else if (ttisstring(o)) + return tsvalue(o)->tsv.len; + else { + size_t l; + lua_lock(L); /* `luaV_tostring' may create a new string */ + l = (luaV_tostring(L, o) ? tsvalue(o)->tsv.len : 0); + lua_unlock(L); + return l; + } +} + + +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { + StkId o = luaA_indexAcceptable(L, idx); + return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->c.f; +} + + +LUA_API void *lua_touserdata (lua_State *L, int idx) { + StkId o = luaA_indexAcceptable(L, idx); + if (o == NULL) return NULL; + switch (ttype(o)) { + case LUA_TUSERDATA: return (uvalue(o) + 1); + case LUA_TLIGHTUSERDATA: return pvalue(o); + default: return NULL; + } +} + + +LUA_API lua_State *lua_tothread (lua_State *L, int idx) { + StkId o = luaA_indexAcceptable(L, idx); + return (o == NULL || !ttisthread(o)) ? NULL : thvalue(o); +} + + +LUA_API const void *lua_topointer (lua_State *L, int idx) { + StkId o = luaA_indexAcceptable(L, idx); + if (o == NULL) return NULL; + else { + switch (ttype(o)) { + case LUA_TTABLE: return hvalue(o); + case LUA_TFUNCTION: return clvalue(o); + case LUA_TTHREAD: return thvalue(o); + case LUA_TUSERDATA: + case LUA_TLIGHTUSERDATA: + return lua_touserdata(L, idx); + default: return NULL; + } + } +} + + + +/* +** push functions (C -> stack) +*/ + + +LUA_API void lua_pushnil (lua_State *L) { + lua_lock(L); + setnilvalue(L->top); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { + lua_lock(L); + setnvalue(L->top, n); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { + lua_lock(L); + luaC_checkGC(L); + setsvalue2s(L->top, luaS_newlstr(L, s, len)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushstring (lua_State *L, const char *s) { + if (s == NULL) + lua_pushnil(L); + else + lua_pushlstring(L, s, strlen(s)); +} + + +LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, + va_list argp) { + const char *ret; + lua_lock(L); + luaC_checkGC(L); + ret = luaO_pushvfstring(L, fmt, argp); + lua_unlock(L); + return ret; +} + + +LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { + const char *ret; + va_list argp; + lua_lock(L); + luaC_checkGC(L); + va_start(argp, fmt); + ret = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + lua_unlock(L); + return ret; +} + + +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { + Closure *cl; + lua_lock(L); + luaC_checkGC(L); + api_checknelems(L, n); + cl = luaF_newCclosure(L, n); + cl->c.f = fn; + L->top -= n; + while (n--) + setobj2n(&cl->c.upvalue[n], L->top+n); + setclvalue(L->top, cl); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushboolean (lua_State *L, int b) { + lua_lock(L); + setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { + lua_lock(L); + setpvalue(L->top, p); + api_incr_top(L); + lua_unlock(L); +} + + + +/* +** get functions (Lua -> stack) +*/ + + +LUA_API void lua_gettable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = luaA_index(L, idx); + setobj2s(L->top - 1, luaV_gettable(L, t, L->top - 1, 0)); + lua_unlock(L); +} + + +LUA_API void lua_rawget (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = luaA_index(L, idx); + api_check(L, ttistable(t)); + setobj2s(L->top - 1, luaH_get(hvalue(t), L->top - 1)); + lua_unlock(L); +} + + +LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { + StkId o; + lua_lock(L); + o = luaA_index(L, idx); + api_check(L, ttistable(o)); + setobj2s(L->top, luaH_getnum(hvalue(o), n)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_newtable (lua_State *L) { + lua_lock(L); + luaC_checkGC(L); + sethvalue(L->top, luaH_new(L, 0, 0)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API int lua_getmetatable (lua_State *L, int objindex) { + const TObject *obj; + Table *mt = NULL; + int res; + lua_lock(L); + obj = luaA_indexAcceptable(L, objindex); + if (obj != NULL) { + switch (ttype(obj)) { + case LUA_TTABLE: + mt = hvalue(obj)->metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(obj)->uv.metatable; + break; + } + } + if (mt == NULL || mt == hvalue(defaultmeta(L))) + res = 0; + else { + sethvalue(L->top, mt); + api_incr_top(L); + res = 1; + } + lua_unlock(L); + return res; +} + + +LUA_API void lua_getfenv (lua_State *L, int idx) { + StkId o; + lua_lock(L); + o = luaA_index(L, idx); + setobj2s(L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L)); + api_incr_top(L); + lua_unlock(L); +} + + +/* +** set functions (stack -> Lua) +*/ + + +LUA_API void lua_settable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = luaA_index(L, idx); + luaV_settable(L, t, L->top - 2, L->top - 1); + L->top -= 2; /* pop index and value */ + lua_unlock(L); +} + + +LUA_API void lua_rawset (lua_State *L, int idx) { + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = luaA_index(L, idx); + api_check(L, ttistable(t)); + setobj2t(luaH_set(L, hvalue(t), L->top-2), L->top-1); /* write barrier */ + L->top -= 2; + lua_unlock(L); +} + + +LUA_API void lua_rawseti (lua_State *L, int idx, int n) { + StkId o; + lua_lock(L); + api_checknelems(L, 1); + o = luaA_index(L, idx); + api_check(L, ttistable(o)); + setobj2t(luaH_setnum(L, hvalue(o), n), L->top-1); /* write barrier */ + L->top--; + lua_unlock(L); +} + + +LUA_API int lua_setmetatable (lua_State *L, int objindex) { + TObject *obj, *mt; + int res = 1; + lua_lock(L); + api_checknelems(L, 1); + obj = luaA_index(L, objindex); + mt = (!ttisnil(L->top - 1)) ? L->top - 1 : defaultmeta(L); + api_check(L, ttistable(mt)); + switch (ttype(obj)) { + case LUA_TTABLE: { + hvalue(obj)->metatable = hvalue(mt); /* write barrier */ + break; + } + case LUA_TUSERDATA: { + uvalue(obj)->uv.metatable = hvalue(mt); /* write barrier */ + break; + } + default: { + res = 0; /* cannot set */ + break; + } + } + L->top--; + lua_unlock(L); + return res; +} + + +LUA_API int lua_setfenv (lua_State *L, int idx) { + StkId o; + int res = 0; + lua_lock(L); + api_checknelems(L, 1); + o = luaA_index(L, idx); + L->top--; + api_check(L, ttistable(L->top)); + if (isLfunction(o)) { + res = 1; + clvalue(o)->l.g = *(L->top); + } + lua_unlock(L); + return res; +} + + +/* +** `load' and `call' functions (run Lua code) +*/ + +LUA_API void lua_call (lua_State *L, int nargs, int nresults) { + StkId func; + lua_lock(L); + api_checknelems(L, nargs+1); + func = L->top - (nargs+1); + luaD_call(L, func, nresults); + lua_unlock(L); +} + + + +/* +** Execute a protected call. +*/ +struct CallS { /* data to `f_call' */ + StkId func; + int nresults; +}; + + +static void f_call (lua_State *L, void *ud) { + struct CallS *c = cast(struct CallS *, ud); + luaD_call(L, c->func, c->nresults); +} + + + +LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { + struct CallS c; + int status; + ptrdiff_t func; + lua_lock(L); + func = (errfunc == 0) ? 0 : savestack(L, luaA_index(L, errfunc)); + c.func = L->top - (nargs+1); /* function to be called */ + c.nresults = nresults; + status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); + lua_unlock(L); + return status; +} + + +/* +** Execute a protected C call. +*/ +struct CCallS { /* data to `f_Ccall' */ + lua_CFunction func; + void *ud; +}; + + +static void f_Ccall (lua_State *L, void *ud) { + struct CCallS *c = cast(struct CCallS *, ud); + Closure *cl; + cl = luaF_newCclosure(L, 0); + cl->c.f = c->func; + setclvalue(L->top, cl); /* push function */ + incr_top(L); + setpvalue(L->top, c->ud); /* push only argument */ + incr_top(L); + luaD_call(L, L->top - 2, 0); +} + + +LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { + struct CCallS c; + int status; + lua_lock(L); + c.func = func; + c.ud = ud; + status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0); + lua_unlock(L); + return status; +} + + +LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data, + const char *chunkname) { + ZIO z; + int status; + int c; + lua_lock(L); + if (!chunkname) chunkname = "?"; + luaZ_init(&z, reader, data, chunkname); + c = luaZ_lookahead(&z); + status = luaD_protectedparser(L, &z, (c == LUA_SIGNATURE[0])); + lua_unlock(L); + return status; +} + + +LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data) { + int status; + TObject *o; + lua_lock(L); + api_checknelems(L, 1); + o = L->top - 1; + if (isLfunction(o) && clvalue(o)->l.nupvalues == 0) { + luaU_dump(L, clvalue(o)->l.p, writer, data); + status = 1; + } + else + status = 0; + lua_unlock(L); + return status; +} + + +/* +** Garbage-collection functions +*/ + +/* GC values are expressed in Kbytes: #bytes/2^10 */ +#define GCscalel(x) ((x)>>10) +#define GCscale(x) (cast(int, GCscalel(x))) +#define GCunscale(x) (cast(lu_mem, x)<<10) + +LUA_API int lua_getgcthreshold (lua_State *L) { + int threshold; + lua_lock(L); + threshold = GCscale(G(L)->GCthreshold); + lua_unlock(L); + return threshold; +} + +LUA_API int lua_getgccount (lua_State *L) { + int count; + lua_lock(L); + count = GCscale(G(L)->nblocks); + lua_unlock(L); + return count; +} + +LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) { + lua_lock(L); + if (cast(lu_mem, newthreshold) > GCscalel(MAX_LUMEM)) + G(L)->GCthreshold = MAX_LUMEM; + else + G(L)->GCthreshold = GCunscale(newthreshold); + luaC_checkGC(L); + lua_unlock(L); +} + + +/* +** miscellaneous functions +*/ + + +LUA_API const char *lua_version (void) { + return LUA_VERSION; +} + + +LUA_API int lua_error (lua_State *L) { + lua_lock(L); + api_checknelems(L, 1); + luaG_errormsg(L); + lua_unlock(L); + return 0; /* to avoid warnings */ +} + + +LUA_API int lua_next (lua_State *L, int idx) { + StkId t; + int more; + lua_lock(L); + t = luaA_index(L, idx); + api_check(L, ttistable(t)); + more = luaH_next(L, hvalue(t), L->top - 1); + if (more) { + api_incr_top(L); + } + else /* no more elements */ + L->top -= 1; /* remove key */ + lua_unlock(L); + return more; +} + + +LUA_API void lua_concat (lua_State *L, int n) { + lua_lock(L); + luaC_checkGC(L); + api_checknelems(L, n); + if (n >= 2) { + luaV_concat(L, n, L->top - L->base - 1); + L->top -= (n-1); + } + else if (n == 0) { /* push empty string */ + setsvalue2s(L->top, luaS_newlstr(L, NULL, 0)); + api_incr_top(L); + } + /* else n == 1; nothing to do */ + lua_unlock(L); +} + + +LUA_API void *lua_newuserdata (lua_State *L, size_t size) { + Udata *u; + lua_lock(L); + luaC_checkGC(L); + u = luaS_newudata(L, size); + setuvalue(L->top, u); + api_incr_top(L); + lua_unlock(L); + return u + 1; +} + + +LUA_API int lua_pushupvalues (lua_State *L) { + Closure *func; + int n, i; + lua_lock(L); + api_check(L, iscfunction(L->base - 1)); + func = clvalue(L->base - 1); + n = func->c.nupvalues; + luaD_checkstack(L, n + LUA_MINSTACK); + for (i=0; itop, &func->c.upvalue[i]); + L->top++; + } + lua_unlock(L); + return n; +} + + +static const char *aux_upvalue (lua_State *L, int funcindex, int n, + TObject **val) { + Closure *f; + StkId fi = luaA_index(L, funcindex); + if (!ttisfunction(fi)) return NULL; + f = clvalue(fi); + if (f->c.isC) { + if (n > f->c.nupvalues) return NULL; + *val = &f->c.upvalue[n-1]; + return ""; + } + else { + Proto *p = f->l.p; + if (n > p->sizeupvalues) return NULL; + *val = f->l.upvals[n-1]->v; + return getstr(p->upvalues[n-1]); + } +} + + +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TObject *val; + lua_lock(L); + name = aux_upvalue(L, funcindex, n, &val); + if (name) { + setobj2s(L->top, val); + api_incr_top(L); + } + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TObject *val; + lua_lock(L); + api_checknelems(L, 1); + name = aux_upvalue(L, funcindex, n, &val); + if (name) { + L->top--; + setobj(val, L->top); /* write barrier */ + } + lua_unlock(L); + return name; +} + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lapi.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/lapi.h new file mode 100644 index 0000000000..d12612f304 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lapi.h @@ -0,0 +1,16 @@ +/* +** $Id: lapi.h,v 1.21 2002/03/04 21:29:41 roberto Exp $ +** Auxiliary functions from Lua API +** See Copyright Notice in lua.h +*/ + +#ifndef lapi_h +#define lapi_h + + +#include "lobject.h" + + +void luaA_pushobject (lua_State *L, const TObject *o); + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lauxlib.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/lauxlib.c new file mode 100644 index 0000000000..ee2d1339b0 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lauxlib.c @@ -0,0 +1,591 @@ +/* +** $Id: lauxlib.c,v 1.100 2003/04/07 14:35:00 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include + + +/* This file uses only the official API of Lua. +** Any function declared here could be written as an application function. +*/ + +#define lauxlib_c + +#include "lua.h" + +#include "lauxlib.h" + + +/* number of prereserved references (for internal use) */ +#define RESERVED_REFS 2 + +/* reserved references */ +#define FREELIST_REF 1 /* free list of references */ +#define ARRAYSIZE_REF 2 /* array sizes */ + + +/* convert a stack index to positive */ +#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ + lua_gettop(L) + (i) + 1) + + +/* +** {====================================================== +** Error-report functions +** ======================================================= +*/ + + +LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { + lua_Debug ar; + lua_getstack(L, 0, &ar); + lua_getinfo(L, "n", &ar); + if (strcmp(ar.namewhat, "method") == 0) { + narg--; /* do not count `self' */ + if (narg == 0) /* error is in the self argument itself? */ + return luaL_error(L, "calling `%s' on bad self (%s)", ar.name, extramsg); + } + if (ar.name == NULL) + ar.name = "?"; + return luaL_error(L, "bad argument #%d to `%s' (%s)", + narg, ar.name, extramsg); +} + + +LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { + const char *msg = lua_pushfstring(L, "%s expected, got %s", + tname, lua_typename(L, lua_type(L,narg))); + return luaL_argerror(L, narg, msg); +} + + +static void tag_error (lua_State *L, int narg, int tag) { + luaL_typerror(L, narg, lua_typename(L, tag)); +} + + +LUALIB_API void luaL_where (lua_State *L, int level) { + lua_Debug ar; + if (lua_getstack(L, level, &ar)) { /* check function at level */ + lua_getinfo(L, "Snl", &ar); /* get info about it */ + if (ar.currentline > 0) { /* is there info? */ + lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); + return; + } + } + lua_pushliteral(L, ""); /* else, no information available... */ +} + + +LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); + return lua_error(L); +} + +/* }====================================================== */ + + +LUALIB_API int luaL_findstring (const char *name, const char *const list[]) { + int i; + for (i=0; list[i]; i++) + if (strcmp(list[i], name) == 0) + return i; + return -1; /* name not found */ +} + + +LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { + lua_pushstring(L, tname); + lua_rawget(L, LUA_REGISTRYINDEX); /* get registry.name */ + if (!lua_isnil(L, -1)) /* name already in use? */ + return 0; /* leave previous value on top, but return 0 */ + lua_pop(L, 1); + lua_newtable(L); /* create metatable */ + lua_pushstring(L, tname); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); /* registry.name = metatable */ + lua_pushvalue(L, -1); + lua_pushstring(L, tname); + lua_rawset(L, LUA_REGISTRYINDEX); /* registry[metatable] = name */ + return 1; +} + + +LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname) { + lua_pushstring(L, tname); + lua_rawget(L, LUA_REGISTRYINDEX); +} + + +LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { + const char *tn; + if (!lua_getmetatable(L, ud)) return NULL; /* no metatable? */ + lua_rawget(L, LUA_REGISTRYINDEX); /* get registry[metatable] */ + tn = lua_tostring(L, -1); + if (tn && (strcmp(tn, tname) == 0)) { + lua_pop(L, 1); + return lua_touserdata(L, ud); + } + else { + lua_pop(L, 1); + return NULL; + } +} + + +LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) { + if (!lua_checkstack(L, space)) + luaL_error(L, "stack overflow (%s)", mes); +} + + +LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { + if (lua_type(L, narg) != t) + tag_error(L, narg, t); +} + + +LUALIB_API void luaL_checkany (lua_State *L, int narg) { + if (lua_type(L, narg) == LUA_TNONE) + luaL_argerror(L, narg, "value expected"); +} + + +LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { + const char *s = lua_tostring(L, narg); + if (!s) tag_error(L, narg, LUA_TSTRING); + if (len) *len = lua_strlen(L, narg); + return s; +} + + +LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, + const char *def, size_t *len) { + if (lua_isnoneornil(L, narg)) { + if (len) + *len = (def ? strlen(def) : 0); + return def; + } + else return luaL_checklstring(L, narg, len); +} + + +LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { + lua_Number d = lua_tonumber(L, narg); + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { + if (lua_isnoneornil(L, narg)) return def; + else return luaL_checknumber(L, narg); +} + + +LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { + if (!lua_getmetatable(L, obj)) /* no metatable? */ + return 0; + lua_pushstring(L, event); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { + lua_pop(L, 2); /* remove metatable and metafield */ + return 0; + } + else { + lua_remove(L, -2); /* remove only metatable */ + return 1; + } +} + + +LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { + obj = abs_index(L, obj); + if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ + return 0; + lua_pushvalue(L, obj); + lua_call(L, 1, 1); + return 1; +} + + +LUALIB_API void luaL_openlib (lua_State *L, const char *libname, + const luaL_reg *l, int nup) { + if (libname) { + lua_pushstring(L, libname); + lua_gettable(L, LUA_GLOBALSINDEX); /* check whether lib already exists */ + if (lua_isnil(L, -1)) { /* no? */ + lua_pop(L, 1); + lua_newtable(L); /* create it */ + lua_pushstring(L, libname); + lua_pushvalue(L, -2); + lua_settable(L, LUA_GLOBALSINDEX); /* register it with given name */ + } + lua_insert(L, -(nup+1)); /* move library table to below upvalues */ + } + for (; l->name; l++) { + int i; + lua_pushstring(L, l->name); + for (i=0; ifunc, nup); + lua_settable(L, -(nup+3)); + } + lua_pop(L, nup); /* remove upvalues */ +} + + + +/* +** {====================================================== +** getn-setn: size for arrays +** ======================================================= +*/ + +static int checkint (lua_State *L, int topop) { + int n = (int)lua_tonumber(L, -1); + if (n == 0 && !lua_isnumber(L, -1)) n = -1; + lua_pop(L, topop); + return n; +} + + +static void getsizes (lua_State *L) { + lua_rawgeti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); + if (lua_isnil(L, -1)) { /* no `size' table? */ + lua_pop(L, 1); /* remove nil */ + lua_newtable(L); /* create it */ + lua_pushvalue(L, -1); /* `size' will be its own metatable */ + lua_setmetatable(L, -2); + lua_pushliteral(L, "__mode"); + lua_pushliteral(L, "k"); + lua_rawset(L, -3); /* metatable(N).__mode = "k" */ + lua_pushvalue(L, -1); + lua_rawseti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); /* store in register */ + } +} + + +void luaL_setn (lua_State *L, int t, int n) { + t = abs_index(L, t); + lua_pushliteral(L, "n"); + lua_rawget(L, t); + if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */ + lua_pushliteral(L, "n"); /* use it */ + lua_pushnumber(L, (lua_Number)n); + lua_rawset(L, t); + } + else { /* use `sizes' */ + getsizes(L); + lua_pushvalue(L, t); + lua_pushnumber(L, (lua_Number)n); + lua_rawset(L, -3); /* sizes[t] = n */ + lua_pop(L, 1); /* remove `sizes' */ + } +} + + +int luaL_getn (lua_State *L, int t) { + int n; + t = abs_index(L, t); + lua_pushliteral(L, "n"); /* try t.n */ + lua_rawget(L, t); + if ((n = checkint(L, 1)) >= 0) return n; + getsizes(L); /* else try sizes[t] */ + lua_pushvalue(L, t); + lua_rawget(L, -2); + if ((n = checkint(L, 2)) >= 0) return n; + for (n = 1; ; n++) { /* else must count elements */ + lua_rawgeti(L, t, n); + if (lua_isnil(L, -1)) break; + lua_pop(L, 1); + } + lua_pop(L, 1); + return n - 1; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + + +#define bufflen(B) ((B)->p - (B)->buffer) +#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) + +#define LIMIT (LUA_MINSTACK/2) + + +static int emptybuffer (luaL_Buffer *B) { + size_t l = bufflen(B); + if (l == 0) return 0; /* put nothing on stack */ + else { + lua_pushlstring(B->L, B->buffer, l); + B->p = B->buffer; + B->lvl++; + return 1; + } +} + + +static void adjuststack (luaL_Buffer *B) { + if (B->lvl > 1) { + lua_State *L = B->L; + int toget = 1; /* number of levels to concat */ + size_t toplen = lua_strlen(L, -1); + do { + size_t l = lua_strlen(L, -(toget+1)); + if (B->lvl - toget + 1 >= LIMIT || toplen > l) { + toplen += l; + toget++; + } + else break; + } while (toget < B->lvl); + lua_concat(L, toget); + B->lvl = B->lvl - toget + 1; + } +} + + +LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) { + if (emptybuffer(B)) + adjuststack(B); + return B->buffer; +} + + +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { + while (l--) + luaL_putchar(B, *s++); +} + + +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { + luaL_addlstring(B, s, strlen(s)); +} + + +LUALIB_API void luaL_pushresult (luaL_Buffer *B) { + emptybuffer(B); + lua_concat(B->L, B->lvl); + B->lvl = 1; +} + + +LUALIB_API void luaL_addvalue (luaL_Buffer *B) { + lua_State *L = B->L; + size_t vl = lua_strlen(L, -1); + if (vl <= bufffree(B)) { /* fit into buffer? */ + memcpy(B->p, lua_tostring(L, -1), vl); /* put it there */ + B->p += vl; + lua_pop(L, 1); /* remove from stack */ + } + else { + if (emptybuffer(B)) + lua_insert(L, -2); /* put buffer before new value */ + B->lvl++; /* add new value into B stack */ + adjuststack(B); + } +} + + +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { + B->L = L; + B->p = B->buffer; + B->lvl = 0; +} + +/* }====================================================== */ + + +LUALIB_API int luaL_ref (lua_State *L, int t) { + int ref; + t = abs_index(L, t); + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* remove from stack */ + return LUA_REFNIL; /* `nil' has a unique fixed reference */ + } + lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ + ref = (int)lua_tonumber(L, -1); /* ref = t[FREELIST_REF] */ + lua_pop(L, 1); /* remove it from stack */ + if (ref != 0) { /* any free element? */ + lua_rawgeti(L, t, ref); /* remove it from list */ + lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ + } + else { /* no free elements */ + ref = luaL_getn(L, t); + if (ref < RESERVED_REFS) + ref = RESERVED_REFS; /* skip reserved references */ + ref++; /* create new reference */ + luaL_setn(L, t, ref); + } + lua_rawseti(L, t, ref); + return ref; +} + + +LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { + if (ref >= 0) { + t = abs_index(L, t); + lua_rawgeti(L, t, FREELIST_REF); + lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ + lua_pushnumber(L, (lua_Number)ref); + lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ + } +} + + + +/* +** {====================================================== +** Load functions +** ======================================================= +*/ + +typedef struct LoadF { + FILE *f; + char buff[LUAL_BUFFERSIZE]; +} LoadF; + + +static const char *getF (lua_State *L, void *ud, size_t *size) { + LoadF *lf = (LoadF *)ud; + (void)L; + if (feof(lf->f)) return NULL; + *size = fread(lf->buff, 1, LUAL_BUFFERSIZE, lf->f); + return (*size > 0) ? lf->buff : NULL; +} + + +static int errfile (lua_State *L, int fnameindex) { + const char *filename = lua_tostring(L, fnameindex) + 1; + lua_pushfstring(L, "cannot read %s: %s", filename, strerror(errno)); + lua_remove(L, fnameindex); + return LUA_ERRFILE; +} + + +LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { + LoadF lf; + int status, readstatus; + int c; + int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ + if (filename == NULL) { + lua_pushliteral(L, "=stdin"); + lf.f = stdin; + } + else { + lua_pushfstring(L, "@%s", filename); + lf.f = fopen(filename, "r"); + } + if (lf.f == NULL) return errfile(L, fnameindex); /* unable to open file */ + c = ungetc(getc(lf.f), lf.f); + if (!(isspace(c) || isprint(c)) && lf.f != stdin) { /* binary file? */ + fclose(lf.f); + lf.f = fopen(filename, "rb"); /* reopen in binary mode */ + if (lf.f == NULL) return errfile(L, fnameindex); /* unable to reopen file */ + } + status = lua_load(L, getF, &lf, lua_tostring(L, -1)); + readstatus = ferror(lf.f); + if (lf.f != stdin) fclose(lf.f); /* close file (even in case of errors) */ + if (readstatus) { + lua_settop(L, fnameindex); /* ignore results from `lua_load' */ + return errfile(L, fnameindex); + } + lua_remove(L, fnameindex); + return status; +} + + +typedef struct LoadS { + const char *s; + size_t size; +} LoadS; + + +static const char *getS (lua_State *L, void *ud, size_t *size) { + LoadS *ls = (LoadS *)ud; + (void)L; + if (ls->size == 0) return NULL; + *size = ls->size; + ls->size = 0; + return ls->s; +} + + +LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size, + const char *name) { + LoadS ls; + ls.s = buff; + ls.size = size; + return lua_load(L, getS, &ls, name); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** compatibility code +** ======================================================= +*/ + + +static void callalert (lua_State *L, int status) { + if (status != 0) { + lua_getglobal(L, "_ALERT"); + if (lua_isfunction(L, -1)) { + lua_insert(L, -2); + lua_call(L, 1, 0); + } + else { /* no _ALERT function; print it on stderr */ + fprintf(stderr, "%s\n", lua_tostring(L, -2)); + lua_pop(L, 2); /* remove error message and _ALERT */ + } + } +} + + +static int aux_do (lua_State *L, int status) { + if (status == 0) { /* parse OK? */ + status = lua_pcall(L, 0, LUA_MULTRET, 0); /* call main */ + } + callalert(L, status); + return status; +} + + +LUALIB_API int lua_dofile (lua_State *L, const char *filename) { + return aux_do(L, luaL_loadfile(L, filename)); +} + + +LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, + const char *name) { + return aux_do(L, luaL_loadbuffer(L, buff, size, name)); +} + + +LUALIB_API int lua_dostring (lua_State *L, const char *str) { + return lua_dobuffer(L, str, strlen(str), str); +} + +/* }====================================================== */ diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lauxlib.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/lauxlib.h new file mode 100644 index 0000000000..450e16c720 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lauxlib.h @@ -0,0 +1,145 @@ +/* +** $Id: lauxlib.h,v 1.60 2003/04/03 13:35:34 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + + +#include +#include + +#include "lua.h" + + +#ifndef LUALIB_API +#define LUALIB_API LUA_API +#endif + + + +typedef struct luaL_reg { + const char *name; + lua_CFunction func; +} luaL_reg; + + +LUALIB_API void luaL_openlib (lua_State *L, const char *libname, + const luaL_reg *l, int nup); +LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *e); +LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *e); +LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname); +LUALIB_API int luaL_argerror (lua_State *L, int numarg, const char *extramsg); +LUALIB_API const char *luaL_checklstring (lua_State *L, int numArg, size_t *l); +LUALIB_API const char *luaL_optlstring (lua_State *L, int numArg, + const char *def, size_t *l); +LUALIB_API lua_Number luaL_checknumber (lua_State *L, int numArg); +LUALIB_API lua_Number luaL_optnumber (lua_State *L, int nArg, lua_Number def); + +LUALIB_API void luaL_checkstack (lua_State *L, int sz, const char *msg); +LUALIB_API void luaL_checktype (lua_State *L, int narg, int t); +LUALIB_API void luaL_checkany (lua_State *L, int narg); + +LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname); +LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname); +LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname); + +LUALIB_API void luaL_where (lua_State *L, int lvl); +LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...); + +LUALIB_API int luaL_findstring (const char *st, const char *const lst[]); + +LUALIB_API int luaL_ref (lua_State *L, int t); +LUALIB_API void luaL_unref (lua_State *L, int t, int ref); + +LUALIB_API int luaL_getn (lua_State *L, int t); +LUALIB_API void luaL_setn (lua_State *L, int t, int n); + +LUALIB_API int luaL_loadfile (lua_State *L, const char *filename); +LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz, + const char *name); + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define luaL_argcheck(L, cond,numarg,extramsg) if (!(cond)) \ + luaL_argerror(L, numarg,extramsg) +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) +#define luaL_checkint(L,n) ((int)luaL_checknumber(L, n)) +#define luaL_checklong(L,n) ((long)luaL_checknumber(L, n)) +#define luaL_optint(L,n,d) ((int)luaL_optnumber(L, n,(lua_Number)(d))) +#define luaL_optlong(L,n,d) ((long)luaL_optnumber(L, n,(lua_Number)(d))) + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + + +#ifndef LUAL_BUFFERSIZE +#define LUAL_BUFFERSIZE BUFSIZ +#endif + + +typedef struct luaL_Buffer { + char *p; /* current position in buffer */ + int lvl; /* number of strings in the stack (level) */ + lua_State *L; + char buffer[LUAL_BUFFERSIZE]; +} luaL_Buffer; + +#define luaL_putchar(B,c) \ + ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ + (*(B)->p++ = (char)(c))) + +#define luaL_addsize(B,n) ((B)->p += (n)) + +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B); +LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B); +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s); +LUALIB_API void luaL_addvalue (luaL_Buffer *B); +LUALIB_API void luaL_pushresult (luaL_Buffer *B); + + +/* }====================================================== */ + + + +/* +** Compatibility macros and functions +*/ + +LUALIB_API int lua_dofile (lua_State *L, const char *filename); +LUALIB_API int lua_dostring (lua_State *L, const char *str); +LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t sz, + const char *n); + + +#define luaL_check_lstr luaL_checklstring +#define luaL_opt_lstr luaL_optlstring +#define luaL_check_number luaL_checknumber +#define luaL_opt_number luaL_optnumber +#define luaL_arg_check luaL_argcheck +#define luaL_check_string luaL_checkstring +#define luaL_opt_string luaL_optstring +#define luaL_check_int luaL_checkint +#define luaL_check_long luaL_checklong +#define luaL_opt_int luaL_optint +#define luaL_opt_long luaL_optlong + + +#endif + + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lbaselib.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/lbaselib.c new file mode 100644 index 0000000000..7381cf3357 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lbaselib.c @@ -0,0 +1,674 @@ +/* +** $Id: lbaselib.c,v 1.130 2003/04/03 13:35:34 roberto Exp $ +** Basic library +** See Copyright Notice in lua.h +*/ + + + +#include +#include +#include +#include + +#define lbaselib_c + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + + +/* +** If your system does not support `stdout', you can just remove this function. +** If you need, you can define your own `print' function, following this +** model but changing `fputs' to put the strings at a proper place +** (a console window or a log file, for instance). +*/ +static int luaB_print (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int i; + lua_getglobal(L, "tostring"); + for (i=1; i<=n; i++) { + const char *s; + lua_pushvalue(L, -1); /* function to be called */ + lua_pushvalue(L, i); /* value to print */ + lua_call(L, 1, 1); + s = lua_tostring(L, -1); /* get result */ + if (s == NULL) + return luaL_error(L, "`tostring' must return a string to `print'"); + if (i>1) fputs("\t", stdout); + fputs(s, stdout); + lua_pop(L, 1); /* pop result */ + } + fputs("\n", stdout); + return 0; +} + + +static int luaB_tonumber (lua_State *L) { + int base = luaL_optint(L, 2, 10); + if (base == 10) { /* standard conversion */ + luaL_checkany(L, 1); + if (lua_isnumber(L, 1)) { + lua_pushnumber(L, lua_tonumber(L, 1)); + return 1; + } + } + else { + const char *s1 = luaL_checkstring(L, 1); + char *s2; + unsigned long n; + luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); + n = strtoul(s1, &s2, base); + if (s1 != s2) { /* at least one valid digit? */ + while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ + if (*s2 == '\0') { /* no invalid trailing characters? */ + lua_pushnumber(L, (lua_Number)n); + return 1; + } + } + } + lua_pushnil(L); /* else not a number */ + return 1; +} + + +static int luaB_error (lua_State *L) { + int level = luaL_optint(L, 2, 1); + luaL_checkany(L, 1); + if (!lua_isstring(L, 1) || level == 0) + lua_pushvalue(L, 1); /* propagate error message without changes */ + else { /* add extra information */ + luaL_where(L, level); + lua_pushvalue(L, 1); + lua_concat(L, 2); + } + return lua_error(L); +} + + +static int luaB_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); + return 1; /* no metatable */ + } + luaL_getmetafield(L, 1, "__metatable"); + return 1; /* returns either __metatable field (if present) or metatable */ +} + + +static int luaB_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + if (luaL_getmetafield(L, 1, "__metatable")) + luaL_error(L, "cannot change a protected metatable"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; +} + + +static void getfunc (lua_State *L) { + if (lua_isfunction(L, 1)) lua_pushvalue(L, 1); + else { + lua_Debug ar; + int level = luaL_optint(L, 1, 1); + luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); + if (lua_getstack(L, level, &ar) == 0) + luaL_argerror(L, 1, "invalid level"); + lua_getinfo(L, "f", &ar); + if (lua_isnil(L, -1)) + luaL_error(L, "no function environment for tail call at level %d", + level); + } +} + + +static int aux_getfenv (lua_State *L) { + lua_getfenv(L, -1); + lua_pushliteral(L, "__fenv"); + lua_rawget(L, -2); + return !lua_isnil(L, -1); +} + + +static int luaB_getfenv (lua_State *L) { + getfunc(L); + if (!aux_getfenv(L)) /* __fenv not defined? */ + lua_pop(L, 1); /* remove it, to return real environment */ + return 1; +} + + +static int luaB_setfenv (lua_State *L) { + luaL_checktype(L, 2, LUA_TTABLE); + getfunc(L); + if (aux_getfenv(L)) /* __fenv defined? */ + luaL_error(L, "`setfenv' cannot change a protected environment"); + else + lua_pop(L, 2); /* remove __fenv and real environment table */ + lua_pushvalue(L, 2); + if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) + lua_replace(L, LUA_GLOBALSINDEX); + else if (lua_setfenv(L, -2) == 0) + luaL_error(L, "`setfenv' cannot change environment of given function"); + return 0; +} + + +static int luaB_rawequal (lua_State *L) { + luaL_checkany(L, 1); + luaL_checkany(L, 2); + lua_pushboolean(L, lua_rawequal(L, 1, 2)); + return 1; +} + + +static int luaB_rawget (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + lua_rawget(L, 1); + return 1; +} + +static int luaB_rawset (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + luaL_checkany(L, 3); + lua_rawset(L, 1); + return 1; +} + + +static int luaB_gcinfo (lua_State *L) { + lua_pushnumber(L, (lua_Number)lua_getgccount(L)); + lua_pushnumber(L, (lua_Number)lua_getgcthreshold(L)); + return 2; +} + + +static int luaB_collectgarbage (lua_State *L) { + lua_setgcthreshold(L, luaL_optint(L, 1, 0)); + return 0; +} + + +static int luaB_type (lua_State *L) { + luaL_checkany(L, 1); + lua_pushstring(L, lua_typename(L, lua_type(L, 1))); + return 1; +} + + +static int luaB_next (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 2); /* create a 2nd argument if there isn't one */ + if (lua_next(L, 1)) + return 2; + else { + lua_pushnil(L); + return 1; + } +} + + +static int luaB_pairs (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushliteral(L, "next"); + lua_rawget(L, LUA_GLOBALSINDEX); /* return generator, */ + lua_pushvalue(L, 1); /* state, */ + lua_pushnil(L); /* and initial value */ + return 3; +} + + +static int luaB_ipairs (lua_State *L) { + lua_Number i = lua_tonumber(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + if (i == 0 && lua_isnone(L, 2)) { /* `for' start? */ + lua_pushliteral(L, "ipairs"); + lua_rawget(L, LUA_GLOBALSINDEX); /* return generator, */ + lua_pushvalue(L, 1); /* state, */ + lua_pushnumber(L, 0); /* and initial value */ + return 3; + } + else { /* `for' step */ + i++; /* next value */ + lua_pushnumber(L, i); + lua_rawgeti(L, 1, (int)i); + return (lua_isnil(L, -1)) ? 0 : 2; + } +} + + +static int load_aux (lua_State *L, int status) { + if (status == 0) /* OK? */ + return 1; + else { + lua_pushnil(L); + lua_insert(L, -2); /* put before error message */ + return 2; /* return nil plus error message */ + } +} + + +static int luaB_loadstring (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + const char *chunkname = luaL_optstring(L, 2, s); + return load_aux(L, luaL_loadbuffer(L, s, l, chunkname)); +} + + +static int luaB_loadfile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + return load_aux(L, luaL_loadfile(L, fname)); +} + + +static int luaB_dofile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + int status = luaL_loadfile(L, fname); + if (status != 0) lua_error(L); + lua_call(L, 0, LUA_MULTRET); + return lua_gettop(L) - 1; +} + + +static int luaB_assert (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_toboolean(L, 1)) + return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); + lua_settop(L, 1); + return 1; +} + + +static int luaB_unpack (lua_State *L) { + int n, i; + luaL_checktype(L, 1, LUA_TTABLE); + n = luaL_getn(L, 1); + luaL_checkstack(L, n, "table too big to unpack"); + for (i=1; i<=n; i++) /* push arg[1...n] */ + lua_rawgeti(L, 1, i); + return n; +} + + +static int luaB_pcall (lua_State *L) { + int status; + luaL_checkany(L, 1); + status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); + lua_pushboolean(L, (status == 0)); + lua_insert(L, 1); + return lua_gettop(L); /* return status + all results */ +} + + +static int luaB_xpcall (lua_State *L) { + int status; + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_insert(L, 1); /* put error function under function to be called */ + status = lua_pcall(L, 0, LUA_MULTRET, 1); + lua_pushboolean(L, (status == 0)); + lua_replace(L, 1); + return lua_gettop(L); /* return status + all results */ +} + + +static int luaB_tostring (lua_State *L) { + char buff[64]; + luaL_checkany(L, 1); + if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ + return 1; /* use its value */ + switch (lua_type(L, 1)) { + case LUA_TNUMBER: + lua_pushstring(L, lua_tostring(L, 1)); + return 1; + case LUA_TSTRING: + lua_pushvalue(L, 1); + return 1; + case LUA_TBOOLEAN: + lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false")); + return 1; + case LUA_TTABLE: + sprintf(buff, "table: %p", lua_topointer(L, 1)); + break; + case LUA_TFUNCTION: + sprintf(buff, "function: %p", lua_topointer(L, 1)); + break; + case LUA_TUSERDATA: + case LUA_TLIGHTUSERDATA: + sprintf(buff, "userdata: %p", lua_touserdata(L, 1)); + break; + case LUA_TTHREAD: + sprintf(buff, "thread: %p", (void *)lua_tothread(L, 1)); + break; + case LUA_TNIL: + lua_pushliteral(L, "nil"); + return 1; + } + lua_pushstring(L, buff); + return 1; +} + + +static int luaB_newproxy (lua_State *L) { + lua_settop(L, 1); + lua_newuserdata(L, 0); /* create proxy */ + if (lua_toboolean(L, 1) == 0) + return 1; /* no metatable */ + else if (lua_isboolean(L, 1)) { + lua_newtable(L); /* create a new metatable `m' ... */ + lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ + lua_pushboolean(L, 1); + lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */ + } + else { + int validproxy = 0; /* to check if weaktable[metatable(u)] == true */ + if (lua_getmetatable(L, 1)) { + lua_rawget(L, lua_upvalueindex(1)); + validproxy = lua_toboolean(L, -1); + lua_pop(L, 1); /* remove value */ + } + luaL_argcheck(L, validproxy, 1, "boolean or proxy expected"); + lua_getmetatable(L, 1); /* metatable is valid; get it */ + } + lua_setmetatable(L, 2); + return 1; +} + + +/* +** {====================================================== +** `require' function +** ======================================================= +*/ + + +/* name of global that holds table with loaded packages */ +#define REQTAB "_LOADED" + +/* name of global that holds the search path for packages */ +#define LUA_PATH "LUA_PATH" + +#ifndef LUA_PATH_SEP +#define LUA_PATH_SEP ';' +#endif + +#ifndef LUA_PATH_MARK +#define LUA_PATH_MARK '?' +#endif + +#ifndef LUA_PATH_DEFAULT +#define LUA_PATH_DEFAULT "?;?.lua" +#endif + + +static const char *getpath (lua_State *L) { + const char *path; + lua_getglobal(L, LUA_PATH); /* try global variable */ + path = lua_tostring(L, -1); + lua_pop(L, 1); + if (path) return path; + path = getenv(LUA_PATH); /* else try environment variable */ + if (path) return path; + return LUA_PATH_DEFAULT; /* else use default */ +} + + +static const char *pushnextpath (lua_State *L, const char *path) { + const char *l; + if (*path == '\0') return NULL; /* no more paths */ + if (*path == LUA_PATH_SEP) path++; /* skip separator */ + l = strchr(path, LUA_PATH_SEP); /* find next separator */ + if (l == NULL) l = path+strlen(path); + lua_pushlstring(L, path, l - path); /* directory name */ + return l; +} + + +static void pushcomposename (lua_State *L) { + const char *path = lua_tostring(L, -1); + const char *wild; + int n = 1; + while ((wild = strchr(path, LUA_PATH_MARK)) != NULL) { + /* is there stack space for prefix, name, and eventual last sufix? */ + luaL_checkstack(L, 3, "too many marks in a path component"); + lua_pushlstring(L, path, wild - path); /* push prefix */ + lua_pushvalue(L, 1); /* push package name (in place of MARK) */ + path = wild + 1; /* continue after MARK */ + n += 2; + } + lua_pushstring(L, path); /* push last sufix (`n' already includes this) */ + lua_concat(L, n); +} + + +static int luaB_require (lua_State *L) { + const char *path; + int status = LUA_ERRFILE; /* not found (yet) */ + luaL_checkstring(L, 1); + lua_settop(L, 1); + lua_getglobal(L, REQTAB); + if (!lua_istable(L, 2)) return luaL_error(L, "`" REQTAB "' is not a table"); + path = getpath(L); + lua_pushvalue(L, 1); /* check package's name in book-keeping table */ + lua_rawget(L, 2); + if (lua_toboolean(L, -1)) /* is it there? */ + return 1; /* package is already loaded; return its result */ + else { /* must load it */ + while (status == LUA_ERRFILE) { + lua_settop(L, 3); /* reset stack position */ + if ((path = pushnextpath(L, path)) == NULL) break; + pushcomposename(L); + status = luaL_loadfile(L, lua_tostring(L, -1)); /* try to load it */ + } + } + switch (status) { + case 0: { + lua_getglobal(L, "_REQUIREDNAME"); /* save previous name */ + lua_insert(L, -2); /* put it below function */ + lua_pushvalue(L, 1); + lua_setglobal(L, "_REQUIREDNAME"); /* set new name */ + lua_call(L, 0, 1); /* run loaded module */ + lua_insert(L, -2); /* put result below previous name */ + lua_setglobal(L, "_REQUIREDNAME"); /* reset to previous name */ + if (lua_isnil(L, -1)) { /* no/nil return? */ + lua_pushboolean(L, 1); + lua_replace(L, -2); /* replace to true */ + } + lua_pushvalue(L, 1); + lua_pushvalue(L, -2); + lua_rawset(L, 2); /* mark it as loaded */ + return 1; /* return value */ + } + case LUA_ERRFILE: { /* file not found */ + return luaL_error(L, "could not load package `%s' from path `%s'", + lua_tostring(L, 1), getpath(L)); + } + default: { + return luaL_error(L, "error loading package `%s' (%s)", + lua_tostring(L, 1), lua_tostring(L, -1)); + } + } +} + +/* }====================================================== */ + + +static const luaL_reg base_funcs[] = { + {"error", luaB_error}, + {"getmetatable", luaB_getmetatable}, + {"setmetatable", luaB_setmetatable}, + {"getfenv", luaB_getfenv}, + {"setfenv", luaB_setfenv}, + {"next", luaB_next}, + {"ipairs", luaB_ipairs}, + {"pairs", luaB_pairs}, + {"print", luaB_print}, + {"tonumber", luaB_tonumber}, + {"tostring", luaB_tostring}, + {"type", luaB_type}, + {"assert", luaB_assert}, + {"unpack", luaB_unpack}, + {"rawequal", luaB_rawequal}, + {"rawget", luaB_rawget}, + {"rawset", luaB_rawset}, + {"pcall", luaB_pcall}, + {"xpcall", luaB_xpcall}, + {"collectgarbage", luaB_collectgarbage}, + {"gcinfo", luaB_gcinfo}, + {"loadfile", luaB_loadfile}, + {"dofile", luaB_dofile}, + {"loadstring", luaB_loadstring}, + {"require", luaB_require}, + {NULL, NULL} +}; + + +/* +** {====================================================== +** Coroutine library +** ======================================================= +*/ + +static int auxresume (lua_State *L, lua_State *co, int narg) { + int status; + if (!lua_checkstack(co, narg)) + luaL_error(L, "too many arguments to resume"); + lua_xmove(L, co, narg); + status = lua_resume(co, narg); + if (status == 0) { + int nres = lua_gettop(co); + if (!lua_checkstack(L, nres)) + luaL_error(L, "too many results to resume"); + lua_xmove(co, L, nres); /* move yielded values */ + return nres; + } + else { + lua_xmove(co, L, 1); /* move error message */ + return -1; /* error flag */ + } +} + + +static int luaB_coresume (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + int r; + luaL_argcheck(L, co, 1, "coroutine expected"); + r = auxresume(L, co, lua_gettop(L) - 1); + if (r < 0) { + lua_pushboolean(L, 0); + lua_insert(L, -2); + return 2; /* return false + error message */ + } + else { + lua_pushboolean(L, 1); + lua_insert(L, -(r + 1)); + return r + 1; /* return true + `resume' returns */ + } +} + + +static int luaB_auxwrap (lua_State *L) { + lua_State *co = lua_tothread(L, lua_upvalueindex(1)); + int r = auxresume(L, co, lua_gettop(L)); + if (r < 0) { + if (lua_isstring(L, -1)) { /* error object is a string? */ + luaL_where(L, 1); /* add extra info */ + lua_insert(L, -2); + lua_concat(L, 2); + } + lua_error(L); /* propagate error */ + } + return r; +} + + +static int luaB_cocreate (lua_State *L) { + lua_State *NL = lua_newthread(L); + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, + "Lua function expected"); + lua_pushvalue(L, 1); /* move function to top */ + lua_xmove(L, NL, 1); /* move function from L to NL */ + return 1; +} + + +static int luaB_cowrap (lua_State *L) { + luaB_cocreate(L); + lua_pushcclosure(L, luaB_auxwrap, 1); + return 1; +} + + +static int luaB_yield (lua_State *L) { + return lua_yield(L, lua_gettop(L)); +} + + +static int luaB_costatus (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + luaL_argcheck(L, co, 1, "coroutine expected"); + if (L == co) lua_pushliteral(L, "running"); + else { + lua_Debug ar; + if (lua_getstack(co, 0, &ar) == 0 && lua_gettop(co) == 0) + lua_pushliteral(L, "dead"); + else + lua_pushliteral(L, "suspended"); + } + return 1; +} + + +static const luaL_reg co_funcs[] = { + {"create", luaB_cocreate}, + {"wrap", luaB_cowrap}, + {"resume", luaB_coresume}, + {"yield", luaB_yield}, + {"status", luaB_costatus}, + {NULL, NULL} +}; + +/* }====================================================== */ + + + +static void base_open (lua_State *L) { + lua_pushliteral(L, "_G"); + lua_pushvalue(L, LUA_GLOBALSINDEX); + luaL_openlib(L, NULL, base_funcs, 0); /* open lib into global table */ + lua_pushliteral(L, "_VERSION"); + lua_pushliteral(L, LUA_VERSION); + lua_rawset(L, -3); /* set global _VERSION */ + /* `newproxy' needs a weaktable as upvalue */ + lua_pushliteral(L, "newproxy"); + lua_newtable(L); /* new table `w' */ + lua_pushvalue(L, -1); /* `w' will be its own metatable */ + lua_setmetatable(L, -2); + lua_pushliteral(L, "__mode"); + lua_pushliteral(L, "k"); + lua_rawset(L, -3); /* metatable(w).__mode = "k" */ + lua_pushcclosure(L, luaB_newproxy, 1); + lua_rawset(L, -3); /* set global `newproxy' */ + lua_rawset(L, -1); /* set global _G */ +} + + +LUALIB_API int luaopen_base (lua_State *L) { + base_open(L); + luaL_openlib(L, LUA_COLIBNAME, co_funcs, 0); + lua_newtable(L); + lua_setglobal(L, REQTAB); + return 0; +} + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lcode.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/lcode.c new file mode 100644 index 0000000000..d626ecd60e --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lcode.c @@ -0,0 +1,714 @@ +/* +** $Id: lcode.c,v 1.117 2003/04/03 13:35:34 roberto Exp $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + + +#include + +#define lcode_c + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "ltable.h" + + +#define hasjumps(e) ((e)->t != (e)->f) + + +void luaK_nil (FuncState *fs, int from, int n) { + Instruction *previous; + if (fs->pc > fs->lasttarget && /* no jumps to current position? */ + GET_OPCODE(*(previous = &fs->f->code[fs->pc-1])) == OP_LOADNIL) { + int pfrom = GETARG_A(*previous); + int pto = GETARG_B(*previous); + if (pfrom <= from && from <= pto+1) { /* can connect both? */ + if (from+n-1 > pto) + SETARG_B(*previous, from+n-1); + return; + } + } + luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */ +} + + +int luaK_jump (FuncState *fs) { + int jpc = fs->jpc; /* save list of jumps to here */ + int j; + fs->jpc = NO_JUMP; + j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); + luaK_concat(fs, &j, jpc); /* keep them on hold */ + return j; +} + + +static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) { + luaK_codeABC(fs, op, A, B, C); + return luaK_jump(fs); +} + + +static void luaK_fixjump (FuncState *fs, int pc, int dest) { + Instruction *jmp = &fs->f->code[pc]; + int offset = dest-(pc+1); + lua_assert(dest != NO_JUMP); + if (abs(offset) > MAXARG_sBx) + luaX_syntaxerror(fs->ls, "control structure too long"); + SETARG_sBx(*jmp, offset); +} + + +/* +** returns current `pc' and marks it as a jump target (to avoid wrong +** optimizations with consecutive instructions not in the same basic block). +*/ +int luaK_getlabel (FuncState *fs) { + fs->lasttarget = fs->pc; + return fs->pc; +} + + +static int luaK_getjump (FuncState *fs, int pc) { + int offset = GETARG_sBx(fs->f->code[pc]); + if (offset == NO_JUMP) /* point to itself represents end of list */ + return NO_JUMP; /* end of list */ + else + return (pc+1)+offset; /* turn offset into absolute position */ +} + + +static Instruction *getjumpcontrol (FuncState *fs, int pc) { + Instruction *pi = &fs->f->code[pc]; + if (pc >= 1 && testOpMode(GET_OPCODE(*(pi-1)), OpModeT)) + return pi-1; + else + return pi; +} + + +/* +** check whether list has any jump that do not produce a value +** (or produce an inverted value) +*/ +static int need_value (FuncState *fs, int list, int cond) { + for (; list != NO_JUMP; list = luaK_getjump(fs, list)) { + Instruction i = *getjumpcontrol(fs, list); + if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1; + } + return 0; /* not found */ +} + + +static void patchtestreg (Instruction *i, int reg) { + if (reg == NO_REG) reg = GETARG_B(*i); + SETARG_A(*i, reg); +} + + +static void luaK_patchlistaux (FuncState *fs, int list, + int ttarget, int treg, int ftarget, int freg, int dtarget) { + while (list != NO_JUMP) { + int next = luaK_getjump(fs, list); + Instruction *i = getjumpcontrol(fs, list); + if (GET_OPCODE(*i) != OP_TEST) { + lua_assert(dtarget != NO_JUMP); + luaK_fixjump(fs, list, dtarget); /* jump to default target */ + } + else { + if (GETARG_C(*i)) { + lua_assert(ttarget != NO_JUMP); + patchtestreg(i, treg); + luaK_fixjump(fs, list, ttarget); + } + else { + lua_assert(ftarget != NO_JUMP); + patchtestreg(i, freg); + luaK_fixjump(fs, list, ftarget); + } + } + list = next; + } +} + + +static void luaK_dischargejpc (FuncState *fs) { + luaK_patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc, NO_REG, fs->pc); + fs->jpc = NO_JUMP; +} + + +void luaK_patchlist (FuncState *fs, int list, int target) { + if (target == fs->pc) + luaK_patchtohere(fs, list); + else { + lua_assert(target < fs->pc); + luaK_patchlistaux(fs, list, target, NO_REG, target, NO_REG, target); + } +} + + +void luaK_patchtohere (FuncState *fs, int list) { + luaK_getlabel(fs); + luaK_concat(fs, &fs->jpc, list); +} + + +void luaK_concat (FuncState *fs, int *l1, int l2) { + if (l2 == NO_JUMP) return; + else if (*l1 == NO_JUMP) + *l1 = l2; + else { + int list = *l1; + int next; + while ((next = luaK_getjump(fs, list)) != NO_JUMP) /* find last element */ + list = next; + luaK_fixjump(fs, list, l2); + } +} + + +void luaK_checkstack (FuncState *fs, int n) { + int newstack = fs->freereg + n; + if (newstack > fs->f->maxstacksize) { + if (newstack >= MAXSTACK) + luaX_syntaxerror(fs->ls, "function or expression too complex"); + fs->f->maxstacksize = cast(lu_byte, newstack); + } +} + + +void luaK_reserveregs (FuncState *fs, int n) { + luaK_checkstack(fs, n); + fs->freereg += n; +} + + +static void freereg (FuncState *fs, int reg) { + if (reg >= fs->nactvar && reg < MAXSTACK) { + fs->freereg--; + lua_assert(reg == fs->freereg); + } +} + + +static void freeexp (FuncState *fs, expdesc *e) { + if (e->k == VNONRELOC) + freereg(fs, e->info); +} + + +static int addk (FuncState *fs, TObject *k, TObject *v) { + const TObject *idx = luaH_get(fs->h, k); + if (ttisnumber(idx)) { + lua_assert(luaO_rawequalObj(&fs->f->k[cast(int, nvalue(idx))], v)); + return cast(int, nvalue(idx)); + } + else { /* constant not found; create a new entry */ + Proto *f = fs->f; + luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject, + MAXARG_Bx, "constant table overflow"); + setobj2n(&f->k[fs->nk], v); + setnvalue(luaH_set(fs->L, fs->h, k), cast(lua_Number, fs->nk)); + return fs->nk++; + } +} + + +int luaK_stringK (FuncState *fs, TString *s) { + TObject o; + setsvalue(&o, s); + return addk(fs, &o, &o); +} + + +int luaK_numberK (FuncState *fs, lua_Number r) { + TObject o; + setnvalue(&o, r); + return addk(fs, &o, &o); +} + + +static int nil_constant (FuncState *fs) { + TObject k, v; + setnilvalue(&v); + sethvalue(&k, fs->h); /* cannot use nil as key; instead use table itself */ + return addk(fs, &k, &v); +} + + +void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) { + if (e->k == VCALL) { /* expression is an open function call? */ + SETARG_C(getcode(fs, e), nresults+1); + if (nresults == 1) { /* `regular' expression? */ + e->k = VNONRELOC; + e->info = GETARG_A(getcode(fs, e)); + } + } +} + + +void luaK_dischargevars (FuncState *fs, expdesc *e) { + switch (e->k) { + case VLOCAL: { + e->k = VNONRELOC; + break; + } + case VUPVAL: { + e->info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->info, 0); + e->k = VRELOCABLE; + break; + } + case VGLOBAL: { + e->info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->info); + e->k = VRELOCABLE; + break; + } + case VINDEXED: { + freereg(fs, e->aux); + freereg(fs, e->info); + e->info = luaK_codeABC(fs, OP_GETTABLE, 0, e->info, e->aux); + e->k = VRELOCABLE; + break; + } + case VCALL: { + luaK_setcallreturns(fs, e, 1); + break; + } + default: break; /* there is one value available (somewhere) */ + } +} + + +static int code_label (FuncState *fs, int A, int b, int jump) { + luaK_getlabel(fs); /* those instructions may be jump targets */ + return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); +} + + +static void discharge2reg (FuncState *fs, expdesc *e, int reg) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: { + luaK_nil(fs, reg, 1); + break; + } + case VFALSE: case VTRUE: { + luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); + break; + } + case VK: { + luaK_codeABx(fs, OP_LOADK, reg, e->info); + break; + } + case VRELOCABLE: { + Instruction *pc = &getcode(fs, e); + SETARG_A(*pc, reg); + break; + } + case VNONRELOC: { + if (reg != e->info) + luaK_codeABC(fs, OP_MOVE, reg, e->info, 0); + break; + } + default: { + lua_assert(e->k == VVOID || e->k == VJMP); + return; /* nothing to do... */ + } + } + e->info = reg; + e->k = VNONRELOC; +} + + +static void discharge2anyreg (FuncState *fs, expdesc *e) { + if (e->k != VNONRELOC) { + luaK_reserveregs(fs, 1); + discharge2reg(fs, e, fs->freereg-1); + } +} + + +static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) { + discharge2reg(fs, e, reg); + if (e->k == VJMP) + luaK_concat(fs, &e->t, e->info); /* put this jump in `t' list */ + if (hasjumps(e)) { + int final; /* position after whole expression */ + int p_f = NO_JUMP; /* position of an eventual LOAD false */ + int p_t = NO_JUMP; /* position of an eventual LOAD true */ + if (need_value(fs, e->t, 1) || need_value(fs, e->f, 0)) { + int fj = NO_JUMP; /* first jump (over LOAD ops.) */ + if (e->k != VJMP) + fj = luaK_jump(fs); + p_f = code_label(fs, reg, 0, 1); + p_t = code_label(fs, reg, 1, 0); + luaK_patchtohere(fs, fj); + } + final = luaK_getlabel(fs); + luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f); + luaK_patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t); + } + e->f = e->t = NO_JUMP; + e->info = reg; + e->k = VNONRELOC; +} + + +void luaK_exp2nextreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + freeexp(fs, e); + luaK_reserveregs(fs, 1); + luaK_exp2reg(fs, e, fs->freereg - 1); +} + + +int luaK_exp2anyreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + if (e->k == VNONRELOC) { + if (!hasjumps(e)) return e->info; /* exp is already in a register */ + if (e->info >= fs->nactvar) { /* reg. is not a local? */ + luaK_exp2reg(fs, e, e->info); /* put value on it */ + return e->info; + } + } + luaK_exp2nextreg(fs, e); /* default */ + return e->info; +} + + +void luaK_exp2val (FuncState *fs, expdesc *e) { + if (hasjumps(e)) + luaK_exp2anyreg(fs, e); + else + luaK_dischargevars(fs, e); +} + + +int luaK_exp2RK (FuncState *fs, expdesc *e) { + luaK_exp2val(fs, e); + switch (e->k) { + case VNIL: { + if (fs->nk + MAXSTACK <= MAXARG_C) { /* constant fit in argC? */ + e->info = nil_constant(fs); + e->k = VK; + return e->info + MAXSTACK; + } + else break; + } + case VK: { + if (e->info + MAXSTACK <= MAXARG_C) /* constant fit in argC? */ + return e->info + MAXSTACK; + else break; + } + default: break; + } + /* not a constant in the right range: put it in a register */ + return luaK_exp2anyreg(fs, e); +} + + +void luaK_storevar (FuncState *fs, expdesc *var, expdesc *exp) { + switch (var->k) { + case VLOCAL: { + freeexp(fs, exp); + luaK_exp2reg(fs, exp, var->info); + return; + } + case VUPVAL: { + int e = luaK_exp2anyreg(fs, exp); + luaK_codeABC(fs, OP_SETUPVAL, e, var->info, 0); + break; + } + case VGLOBAL: { + int e = luaK_exp2anyreg(fs, exp); + luaK_codeABx(fs, OP_SETGLOBAL, e, var->info); + break; + } + case VINDEXED: { + int e = luaK_exp2RK(fs, exp); + luaK_codeABC(fs, OP_SETTABLE, var->info, var->aux, e); + break; + } + default: { + lua_assert(0); /* invalid var kind to store */ + break; + } + } + freeexp(fs, exp); +} + + +void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { + int func; + luaK_exp2anyreg(fs, e); + freeexp(fs, e); + func = fs->freereg; + luaK_reserveregs(fs, 2); + luaK_codeABC(fs, OP_SELF, func, e->info, luaK_exp2RK(fs, key)); + freeexp(fs, key); + e->info = func; + e->k = VNONRELOC; +} + + +static void invertjump (FuncState *fs, expdesc *e) { + Instruction *pc = getjumpcontrol(fs, e->info); + lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT) && + GET_OPCODE(*pc) != OP_TEST); + SETARG_A(*pc, !(GETARG_A(*pc))); +} + + +static int jumponcond (FuncState *fs, expdesc *e, int cond) { + if (e->k == VRELOCABLE) { + Instruction ie = getcode(fs, e); + if (GET_OPCODE(ie) == OP_NOT) { + fs->pc--; /* remove previous OP_NOT */ + return luaK_condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond); + } + /* else go through */ + } + discharge2anyreg(fs, e); + freeexp(fs, e); + return luaK_condjump(fs, OP_TEST, NO_REG, e->info, cond); +} + + +void luaK_goiftrue (FuncState *fs, expdesc *e) { + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VK: case VTRUE: { + pc = NO_JUMP; /* always true; do nothing */ + break; + } + case VFALSE: { + pc = luaK_jump(fs); /* always jump */ + break; + } + case VJMP: { + invertjump(fs, e); + pc = e->info; + break; + } + default: { + pc = jumponcond(fs, e, 0); + break; + } + } + luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ +} + + +void luaK_goiffalse (FuncState *fs, expdesc *e) { + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: case VFALSE: { + pc = NO_JUMP; /* always false; do nothing */ + break; + } + case VTRUE: { + pc = luaK_jump(fs); /* always jump */ + break; + } + case VJMP: { + pc = e->info; + break; + } + default: { + pc = jumponcond(fs, e, 1); + break; + } + } + luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ +} + + +static void codenot (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: case VFALSE: { + e->k = VTRUE; + break; + } + case VK: case VTRUE: { + e->k = VFALSE; + break; + } + case VJMP: { + invertjump(fs, e); + break; + } + case VRELOCABLE: + case VNONRELOC: { + discharge2anyreg(fs, e); + freeexp(fs, e); + e->info = luaK_codeABC(fs, OP_NOT, 0, e->info, 0); + e->k = VRELOCABLE; + break; + } + default: { + lua_assert(0); /* cannot happen */ + break; + } + } + /* interchange true and false lists */ + { int temp = e->f; e->f = e->t; e->t = temp; } +} + + +void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { + t->aux = luaK_exp2RK(fs, k); + t->k = VINDEXED; +} + + +void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { + if (op == OPR_MINUS) { + luaK_exp2val(fs, e); + if (e->k == VK && ttisnumber(&fs->f->k[e->info])) + e->info = luaK_numberK(fs, -nvalue(&fs->f->k[e->info])); + else { + luaK_exp2anyreg(fs, e); + freeexp(fs, e); + e->info = luaK_codeABC(fs, OP_UNM, 0, e->info, 0); + e->k = VRELOCABLE; + } + } + else /* op == NOT */ + codenot(fs, e); +} + + +void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { + switch (op) { + case OPR_AND: { + luaK_goiftrue(fs, v); + luaK_patchtohere(fs, v->t); + v->t = NO_JUMP; + break; + } + case OPR_OR: { + luaK_goiffalse(fs, v); + luaK_patchtohere(fs, v->f); + v->f = NO_JUMP; + break; + } + case OPR_CONCAT: { + luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ + break; + } + default: { + luaK_exp2RK(fs, v); + break; + } + } +} + + +static void codebinop (FuncState *fs, expdesc *res, BinOpr op, + int o1, int o2) { + if (op <= OPR_POW) { /* arithmetic operator? */ + OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD); /* ORDER OP */ + res->info = luaK_codeABC(fs, opc, 0, o1, o2); + res->k = VRELOCABLE; + } + else { /* test operator */ + static const OpCode ops[] = {OP_EQ, OP_EQ, OP_LT, OP_LE, OP_LT, OP_LE}; + int cond = 1; + if (op >= OPR_GT) { /* `>' or `>='? */ + int temp; /* exchange args and replace by `<' or `<=' */ + temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ + } + else if (op == OPR_NE) cond = 0; + res->info = luaK_condjump(fs, ops[op - OPR_NE], cond, o1, o2); + res->k = VJMP; + } +} + + +void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { + switch (op) { + case OPR_AND: { + lua_assert(e1->t == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e1->f, e2->f); + e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->t = e2->t; + break; + } + case OPR_OR: { + lua_assert(e1->f == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e1->t, e2->t); + e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->f = e2->f; + break; + } + case OPR_CONCAT: { + luaK_exp2val(fs, e2); + if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { + lua_assert(e1->info == GETARG_B(getcode(fs, e2))-1); + freeexp(fs, e1); + SETARG_B(getcode(fs, e2), e1->info); + e1->k = e2->k; e1->info = e2->info; + } + else { + luaK_exp2nextreg(fs, e2); + freeexp(fs, e2); + freeexp(fs, e1); + e1->info = luaK_codeABC(fs, OP_CONCAT, 0, e1->info, e2->info); + e1->k = VRELOCABLE; + } + break; + } + default: { + int o1 = luaK_exp2RK(fs, e1); + int o2 = luaK_exp2RK(fs, e2); + freeexp(fs, e2); + freeexp(fs, e1); + codebinop(fs, e1, op, o1, o2); + } + } +} + + +void luaK_fixline (FuncState *fs, int line) { + fs->f->lineinfo[fs->pc - 1] = line; +} + + +int luaK_code (FuncState *fs, Instruction i, int line) { + Proto *f = fs->f; + luaK_dischargejpc(fs); /* `pc' will change */ + /* put new instruction in code array */ + luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, + MAX_INT, "code size overflow"); + f->code[fs->pc] = i; + /* save corresponding line information */ + luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, + MAX_INT, "code size overflow"); + f->lineinfo[fs->pc] = line; + return fs->pc++; +} + + +int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { + lua_assert(getOpMode(o) == iABC); + return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline); +} + + +int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { + lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); + return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); +} + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lcode.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/lcode.h new file mode 100644 index 0000000000..74908c6580 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lcode.h @@ -0,0 +1,74 @@ +/* +** $Id: lcode.h,v 1.38 2002/12/11 12:34:22 roberto Exp $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lcode_h +#define lcode_h + +#include "llex.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" + + +/* +** Marks the end of a patch list. It is an invalid value both as an absolute +** address, and as a list link (would link an element to itself). +*/ +#define NO_JUMP (-1) + + +/* +** grep "ORDER OPR" if you change these enums +*/ +typedef enum BinOpr { + OPR_ADD, OPR_SUB, OPR_MULT, OPR_DIV, OPR_POW, + OPR_CONCAT, + OPR_NE, OPR_EQ, + OPR_LT, OPR_LE, OPR_GT, OPR_GE, + OPR_AND, OPR_OR, + OPR_NOBINOPR +} BinOpr; + +#define binopistest(op) ((op) >= OPR_NE) + +typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr; + + +#define getcode(fs,e) ((fs)->f->code[(e)->info]) + +#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) + +int luaK_code (FuncState *fs, Instruction i, int line); +int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); +int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); +void luaK_fixline (FuncState *fs, int line); +void luaK_nil (FuncState *fs, int from, int n); +void luaK_reserveregs (FuncState *fs, int n); +void luaK_checkstack (FuncState *fs, int n); +int luaK_stringK (FuncState *fs, TString *s); +int luaK_numberK (FuncState *fs, lua_Number r); +void luaK_dischargevars (FuncState *fs, expdesc *e); +int luaK_exp2anyreg (FuncState *fs, expdesc *e); +void luaK_exp2nextreg (FuncState *fs, expdesc *e); +void luaK_exp2val (FuncState *fs, expdesc *e); +int luaK_exp2RK (FuncState *fs, expdesc *e); +void luaK_self (FuncState *fs, expdesc *e, expdesc *key); +void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); +void luaK_goiftrue (FuncState *fs, expdesc *e); +void luaK_goiffalse (FuncState *fs, expdesc *e); +void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); +void luaK_setcallreturns (FuncState *fs, expdesc *var, int nresults); +int luaK_jump (FuncState *fs); +void luaK_patchlist (FuncState *fs, int list, int target); +void luaK_patchtohere (FuncState *fs, int list); +void luaK_concat (FuncState *fs, int *l1, int l2); +int luaK_getlabel (FuncState *fs); +void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); +void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); +void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); + + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/ldblib.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/ldblib.c new file mode 100644 index 0000000000..6dc9b64cfc --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/ldblib.c @@ -0,0 +1,299 @@ +/* +** $Id: ldblib.c,v 1.80 2003/04/03 13:35:34 roberto Exp $ +** Interface from Lua to its debug API +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define ldblib_c + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +static void settabss (lua_State *L, const char *i, const char *v) { + lua_pushstring(L, i); + lua_pushstring(L, v); + lua_rawset(L, -3); +} + + +static void settabsi (lua_State *L, const char *i, int v) { + lua_pushstring(L, i); + lua_pushnumber(L, (lua_Number)v); + lua_rawset(L, -3); +} + + +static int getinfo (lua_State *L) { + lua_Debug ar; + const char *options = luaL_optstring(L, 2, "flnSu"); + if (lua_isnumber(L, 1)) { + if (!lua_getstack(L, (int)(lua_tonumber(L, 1)), &ar)) { + lua_pushnil(L); /* level out of range */ + return 1; + } + } + else if (lua_isfunction(L, 1)) { + lua_pushfstring(L, ">%s", options); + options = lua_tostring(L, -1); + lua_pushvalue(L, 1); + } + else + return luaL_argerror(L, 1, "function or level expected"); + if (!lua_getinfo(L, options, &ar)) + return luaL_argerror(L, 2, "invalid option"); + lua_newtable(L); + for (; *options; options++) { + switch (*options) { + case 'S': + settabss(L, "source", ar.source); + settabss(L, "short_src", ar.short_src); + settabsi(L, "linedefined", ar.linedefined); + settabss(L, "what", ar.what); + break; + case 'l': + settabsi(L, "currentline", ar.currentline); + break; + case 'u': + settabsi(L, "nups", ar.nups); + break; + case 'n': + settabss(L, "name", ar.name); + settabss(L, "namewhat", ar.namewhat); + break; + case 'f': + lua_pushliteral(L, "func"); + lua_pushvalue(L, -3); + lua_rawset(L, -3); + break; + } + } + return 1; /* return table */ +} + + +static int getlocal (lua_State *L) { + lua_Debug ar; + const char *name; + if (!lua_getstack(L, luaL_checkint(L, 1), &ar)) /* level out of range? */ + return luaL_argerror(L, 1, "level out of range"); + name = lua_getlocal(L, &ar, luaL_checkint(L, 2)); + if (name) { + lua_pushstring(L, name); + lua_pushvalue(L, -2); + return 2; + } + else { + lua_pushnil(L); + return 1; + } +} + + +static int setlocal (lua_State *L) { + lua_Debug ar; + if (!lua_getstack(L, luaL_checkint(L, 1), &ar)) /* level out of range? */ + return luaL_argerror(L, 1, "level out of range"); + luaL_checkany(L, 3); + lua_pushstring(L, lua_setlocal(L, &ar, luaL_checkint(L, 2))); + return 1; +} + + +static int auxupvalue (lua_State *L, int get) { + const char *name; + int n = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TFUNCTION); + if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */ + name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); + if (name == NULL) return 0; + lua_pushstring(L, name); + lua_insert(L, -(get+1)); + return get + 1; +} + + +static int getupvalue (lua_State *L) { + return auxupvalue(L, 1); +} + + +static int setupvalue (lua_State *L) { + luaL_checkany(L, 3); + return auxupvalue(L, 0); +} + + + +static const char KEY_HOOK = 'h'; + + +static void hookf (lua_State *L, lua_Debug *ar) { + static const char *const hooknames[] = + {"call", "return", "line", "count", "tail return"}; + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_rawget(L, LUA_REGISTRYINDEX); + if (lua_isfunction(L, -1)) { + lua_pushstring(L, hooknames[(int)ar->event]); + if (ar->currentline >= 0) + lua_pushnumber(L, (lua_Number)ar->currentline); + else lua_pushnil(L); + lua_assert(lua_getinfo(L, "lS", ar)); + lua_call(L, 2, 0); + } + else + lua_pop(L, 1); /* pop result from gettable */ +} + + +static int makemask (const char *smask, int count) { + int mask = 0; + if (strchr(smask, 'c')) mask |= LUA_MASKCALL; + if (strchr(smask, 'r')) mask |= LUA_MASKRET; + if (strchr(smask, 'l')) mask |= LUA_MASKLINE; + if (count > 0) mask |= LUA_MASKCOUNT; + return mask; +} + + +static char *unmakemask (int mask, char *smask) { + int i = 0; + if (mask & LUA_MASKCALL) smask[i++] = 'c'; + if (mask & LUA_MASKRET) smask[i++] = 'r'; + if (mask & LUA_MASKLINE) smask[i++] = 'l'; + smask[i] = '\0'; + return smask; +} + + +static int sethook (lua_State *L) { + if (lua_isnoneornil(L, 1)) { + lua_settop(L, 1); + lua_sethook(L, NULL, 0, 0); /* turn off hooks */ + } + else { + const char *smask = luaL_checkstring(L, 2); + int count = luaL_optint(L, 3, 0); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_sethook(L, hookf, makemask(smask, count), count); + } + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_pushvalue(L, 1); + lua_rawset(L, LUA_REGISTRYINDEX); /* set new hook */ + return 0; +} + + +static int gethook (lua_State *L) { + char buff[5]; + int mask = lua_gethookmask(L); + lua_Hook hook = lua_gethook(L); + if (hook != NULL && hook != hookf) /* external hook? */ + lua_pushliteral(L, "external hook"); + else { + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */ + } + lua_pushstring(L, unmakemask(mask, buff)); + lua_pushnumber(L, (lua_Number)lua_gethookcount(L)); + return 3; +} + + +static int debug (lua_State *L) { + for (;;) { + char buffer[250]; + fputs("lua_debug> ", stderr); + if (fgets(buffer, sizeof(buffer), stdin) == 0 || + strcmp(buffer, "cont\n") == 0) + return 0; + lua_dostring(L, buffer); + lua_settop(L, 0); /* remove eventual returns */ + } +} + + +#define LEVELS1 12 /* size of the first part of the stack */ +#define LEVELS2 10 /* size of the second part of the stack */ + +static int errorfb (lua_State *L) { + int level = 1; /* skip level 0 (it's this function) */ + int firstpart = 1; /* still before eventual `...' */ + lua_Debug ar; + if (lua_gettop(L) == 0) + lua_pushliteral(L, ""); + else if (!lua_isstring(L, 1)) return 1; /* no string message */ + else lua_pushliteral(L, "\n"); + lua_pushliteral(L, "stack traceback:"); + while (lua_getstack(L, level++, &ar)) { + if (level > LEVELS1 && firstpart) { + /* no more than `LEVELS2' more levels? */ + if (!lua_getstack(L, level+LEVELS2, &ar)) + level--; /* keep going */ + else { + lua_pushliteral(L, "\n\t..."); /* too many levels */ + while (lua_getstack(L, level+LEVELS2, &ar)) /* find last levels */ + level++; + } + firstpart = 0; + continue; + } + lua_pushliteral(L, "\n\t"); + lua_getinfo(L, "Snl", &ar); + lua_pushfstring(L, "%s:", ar.short_src); + if (ar.currentline > 0) + lua_pushfstring(L, "%d:", ar.currentline); + switch (*ar.namewhat) { + case 'g': /* global */ + case 'l': /* local */ + case 'f': /* field */ + case 'm': /* method */ + lua_pushfstring(L, " in function `%s'", ar.name); + break; + default: { + if (*ar.what == 'm') /* main? */ + lua_pushfstring(L, " in main chunk"); + else if (*ar.what == 'C' || *ar.what == 't') + lua_pushliteral(L, " ?"); /* C function or tail call */ + else + lua_pushfstring(L, " in function <%s:%d>", + ar.short_src, ar.linedefined); + } + } + lua_concat(L, lua_gettop(L)); + } + lua_concat(L, lua_gettop(L)); + return 1; +} + + +static const luaL_reg dblib[] = { + {"getlocal", getlocal}, + {"getinfo", getinfo}, + {"gethook", gethook}, + {"getupvalue", getupvalue}, + {"sethook", sethook}, + {"setlocal", setlocal}, + {"setupvalue", setupvalue}, + {"debug", debug}, + {"traceback", errorfb}, + {NULL, NULL} +}; + + +LUALIB_API int luaopen_debug (lua_State *L) { + luaL_openlib(L, LUA_DBLIBNAME, dblib, 0); + lua_pushliteral(L, "_TRACEBACK"); + lua_pushcfunction(L, errorfb); + lua_settable(L, LUA_GLOBALSINDEX); + return 1; +} + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/ldebug.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/ldebug.c new file mode 100644 index 0000000000..8e511e3bd9 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/ldebug.c @@ -0,0 +1,585 @@ +/* +** $Id: ldebug.c,v 1.150 2003/03/19 21:24:04 roberto Exp $ +** Debug Interface +** See Copyright Notice in lua.h +*/ + + +#include +#include + +#define ldebug_c + +#include "lua.h" + +#include "lapi.h" +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +static const char *getfuncname (CallInfo *ci, const char **name); + + +#define isLua(ci) (!((ci)->state & CI_C)) + + +static int currentpc (CallInfo *ci) { + if (!isLua(ci)) return -1; /* function is not a Lua function? */ + if (ci->state & CI_HASFRAME) /* function has a frame? */ + ci->u.l.savedpc = *ci->u.l.pc; /* use `pc' from there */ + /* function's pc is saved */ + return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p); +} + + +static int currentline (CallInfo *ci) { + int pc = currentpc(ci); + if (pc < 0) + return -1; /* only active lua functions have current-line information */ + else + return getline(ci_func(ci)->l.p, pc); +} + + +void luaG_inithooks (lua_State *L) { + CallInfo *ci; + for (ci = L->ci; ci != L->base_ci; ci--) /* update all `savedpc's */ + currentpc(ci); + L->hookinit = 1; +} + + +/* +** this function can be called asynchronous (e.g. during a signal) +*/ +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { + if (func == NULL || mask == 0) { /* turn off hooks? */ + mask = 0; + func = NULL; + } + L->hook = func; + L->basehookcount = count; + resethookcount(L); + L->hookmask = cast(lu_byte, mask); + L->hookinit = 0; + return 1; +} + + +LUA_API lua_Hook lua_gethook (lua_State *L) { + return L->hook; +} + + +LUA_API int lua_gethookmask (lua_State *L) { + return L->hookmask; +} + + +LUA_API int lua_gethookcount (lua_State *L) { + return L->basehookcount; +} + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { + int status; + CallInfo *ci; + lua_lock(L); + for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { + level--; + if (!(ci->state & CI_C)) /* Lua function? */ + level -= ci->u.l.tailcalls; /* skip lost tail calls */ + } + if (level > 0 || ci == L->base_ci) status = 0; /* there is no such level */ + else if (level < 0) { /* level is of a lost tail call */ + status = 1; + ar->i_ci = 0; + } + else { + status = 1; + ar->i_ci = ci - L->base_ci; + } + lua_unlock(L); + return status; +} + + +static Proto *getluaproto (CallInfo *ci) { + return (isLua(ci) ? ci_func(ci)->l.p : NULL); +} + + +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { + const char *name; + CallInfo *ci; + Proto *fp; + lua_lock(L); + name = NULL; + ci = L->base_ci + ar->i_ci; + fp = getluaproto(ci); + if (fp) { /* is a Lua function? */ + name = luaF_getlocalname(fp, n, currentpc(ci)); + if (name) + luaA_pushobject(L, ci->base+(n-1)); /* push value */ + } + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { + const char *name; + CallInfo *ci; + Proto *fp; + lua_lock(L); + name = NULL; + ci = L->base_ci + ar->i_ci; + fp = getluaproto(ci); + L->top--; /* pop new value */ + if (fp) { /* is a Lua function? */ + name = luaF_getlocalname(fp, n, currentpc(ci)); + if (!name || name[0] == '(') /* `(' starts private locals */ + name = NULL; + else + setobjs2s(ci->base+(n-1), L->top); + } + lua_unlock(L); + return name; +} + + +static void funcinfo (lua_Debug *ar, StkId func) { + Closure *cl = clvalue(func); + if (cl->c.isC) { + ar->source = "=[C]"; + ar->linedefined = -1; + ar->what = "C"; + } + else { + ar->source = getstr(cl->l.p->source); + ar->linedefined = cl->l.p->lineDefined; + ar->what = (ar->linedefined == 0) ? "main" : "Lua"; + } + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); +} + + +static const char *travglobals (lua_State *L, const TObject *o) { + Table *g = hvalue(gt(L)); + int i = sizenode(g); + while (i--) { + Node *n = gnode(g, i); + if (luaO_rawequalObj(o, gval(n)) && ttisstring(gkey(n))) + return getstr(tsvalue(gkey(n))); + } + return NULL; +} + + +static void info_tailcall (lua_State *L, lua_Debug *ar) { + ar->name = ar->namewhat = ""; + ar->what = "tail"; + ar->linedefined = ar->currentline = -1; + ar->source = "=(tail call)"; + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); + ar->nups = 0; + setnilvalue(L->top); +} + + +static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, + StkId f, CallInfo *ci) { + int status = 1; + for (; *what; what++) { + switch (*what) { + case 'S': { + funcinfo(ar, f); + break; + } + case 'l': { + ar->currentline = (ci) ? currentline(ci) : -1; + break; + } + case 'u': { + ar->nups = clvalue(f)->c.nupvalues; + break; + } + case 'n': { + ar->namewhat = (ci) ? getfuncname(ci, &ar->name) : NULL; + if (ar->namewhat == NULL) { + /* try to find a global name */ + if ((ar->name = travglobals(L, f)) != NULL) + ar->namewhat = "global"; + else ar->namewhat = ""; /* not found */ + } + break; + } + case 'f': { + setobj2s(L->top, f); + break; + } + default: status = 0; /* invalid option */ + } + } + return status; +} + + +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { + int status = 1; + lua_lock(L); + if (*what == '>') { + StkId f = L->top - 1; + if (!ttisfunction(f)) + luaG_runerror(L, "value for `lua_getinfo' is not a function"); + status = auxgetinfo(L, what + 1, ar, f, NULL); + L->top--; /* pop function */ + } + else if (ar->i_ci != 0) { /* no tail call? */ + CallInfo *ci = L->base_ci + ar->i_ci; + lua_assert(ttisfunction(ci->base - 1)); + status = auxgetinfo(L, what, ar, ci->base - 1, ci); + } + else + info_tailcall(L, ar); + if (strchr(what, 'f')) incr_top(L); + lua_unlock(L); + return status; +} + + +/* +** {====================================================== +** Symbolic Execution and code checker +** ======================================================= +*/ + +#define check(x) if (!(x)) return 0; + +#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode) + +#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) + + + +static int precheck (const Proto *pt) { + check(pt->maxstacksize <= MAXSTACK); + check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); + lua_assert(pt->numparams+pt->is_vararg <= pt->maxstacksize); + check(GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); + return 1; +} + + +static int checkopenop (const Proto *pt, int pc) { + Instruction i = pt->code[pc+1]; + switch (GET_OPCODE(i)) { + case OP_CALL: + case OP_TAILCALL: + case OP_RETURN: { + check(GETARG_B(i) == 0); + return 1; + } + case OP_SETLISTO: return 1; + default: return 0; /* invalid instruction after an open call */ + } +} + + +static int checkRK (const Proto *pt, int r) { + return (r < pt->maxstacksize || (r >= MAXSTACK && r-MAXSTACK < pt->sizek)); +} + + +static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { + int pc; + int last; /* stores position of last instruction that changed `reg' */ + last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ + check(precheck(pt)); + for (pc = 0; pc < lastpc; pc++) { + const Instruction i = pt->code[pc]; + OpCode op = GET_OPCODE(i); + int a = GETARG_A(i); + int b = 0; + int c = 0; + checkreg(pt, a); + switch (getOpMode(op)) { + case iABC: { + b = GETARG_B(i); + c = GETARG_C(i); + if (testOpMode(op, OpModeBreg)) { + checkreg(pt, b); + } + else if (testOpMode(op, OpModeBrk)) + check(checkRK(pt, b)); + if (testOpMode(op, OpModeCrk)) + check(checkRK(pt, c)); + break; + } + case iABx: { + b = GETARG_Bx(i); + if (testOpMode(op, OpModeK)) check(b < pt->sizek); + break; + } + case iAsBx: { + b = GETARG_sBx(i); + break; + } + } + if (testOpMode(op, OpModesetA)) { + if (a == reg) last = pc; /* change register `a' */ + } + if (testOpMode(op, OpModeT)) { + check(pc+2 < pt->sizecode); /* check skip */ + check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); + } + switch (op) { + case OP_LOADBOOL: { + check(c == 0 || pc+2 < pt->sizecode); /* check its jump */ + break; + } + case OP_LOADNIL: { + if (a <= reg && reg <= b) + last = pc; /* set registers from `a' to `b' */ + break; + } + case OP_GETUPVAL: + case OP_SETUPVAL: { + check(b < pt->nups); + break; + } + case OP_GETGLOBAL: + case OP_SETGLOBAL: { + check(ttisstring(&pt->k[b])); + break; + } + case OP_SELF: { + checkreg(pt, a+1); + if (reg == a+1) last = pc; + break; + } + case OP_CONCAT: { + /* `c' is a register, and at least two operands */ + check(c < MAXSTACK && b < c); + break; + } + case OP_TFORLOOP: + checkreg(pt, a+c+5); + if (reg >= a) last = pc; /* affect all registers above base */ + /* go through */ + case OP_FORLOOP: + checkreg(pt, a+2); + /* go through */ + case OP_JMP: { + int dest = pc+1+b; + check(0 <= dest && dest < pt->sizecode); + /* not full check and jump is forward and do not skip `lastpc'? */ + if (reg != NO_REG && pc < dest && dest <= lastpc) + pc += b; /* do the jump */ + break; + } + case OP_CALL: + case OP_TAILCALL: { + if (b != 0) { + checkreg(pt, a+b-1); + } + c--; /* c = num. returns */ + if (c == LUA_MULTRET) { + check(checkopenop(pt, pc)); + } + else if (c != 0) + checkreg(pt, a+c-1); + if (reg >= a) last = pc; /* affect all registers above base */ + break; + } + case OP_RETURN: { + b--; /* b = num. returns */ + if (b > 0) checkreg(pt, a+b-1); + break; + } + case OP_SETLIST: { + checkreg(pt, a + (b&(LFIELDS_PER_FLUSH-1)) + 1); + break; + } + case OP_CLOSURE: { + int nup; + check(b < pt->sizep); + nup = pt->p[b]->nups; + check(pc + nup < pt->sizecode); + for (; nup>0; nup--) { + OpCode op1 = GET_OPCODE(pt->code[pc+nup]); + check(op1 == OP_GETUPVAL || op1 == OP_MOVE); + } + break; + } + default: break; + } + } + return pt->code[last]; +} + +#undef check +#undef checkjump +#undef checkreg + +/* }====================================================== */ + + +int luaG_checkcode (const Proto *pt) { + return luaG_symbexec(pt, pt->sizecode, NO_REG); +} + + +static const char *kname (Proto *p, int c) { + c = c - MAXSTACK; + if (c >= 0 && ttisstring(&p->k[c])) + return svalue(&p->k[c]); + else + return "?"; +} + + +static const char *getobjname (CallInfo *ci, int stackpos, const char **name) { + if (isLua(ci)) { /* a Lua function? */ + Proto *p = ci_func(ci)->l.p; + int pc = currentpc(ci); + Instruction i; + *name = luaF_getlocalname(p, stackpos+1, pc); + if (*name) /* is a local? */ + return "local"; + i = luaG_symbexec(p, pc, stackpos); /* try symbolic execution */ + lua_assert(pc != -1); + switch (GET_OPCODE(i)) { + case OP_GETGLOBAL: { + int g = GETARG_Bx(i); /* global index */ + lua_assert(ttisstring(&p->k[g])); + *name = svalue(&p->k[g]); + return "global"; + } + case OP_MOVE: { + int a = GETARG_A(i); + int b = GETARG_B(i); /* move from `b' to `a' */ + if (b < a) + return getobjname(ci, b, name); /* get name for `b' */ + break; + } + case OP_GETTABLE: { + int k = GETARG_C(i); /* key index */ + *name = kname(p, k); + return "field"; + } + case OP_SELF: { + int k = GETARG_C(i); /* key index */ + *name = kname(p, k); + return "method"; + } + default: break; + } + } + return NULL; /* no useful name found */ +} + + +static const char *getfuncname (CallInfo *ci, const char **name) { + Instruction i; + if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci - 1)) + return NULL; /* calling function is not Lua (or is unknown) */ + ci--; /* calling function */ + i = ci_func(ci)->l.p->code[currentpc(ci)]; + if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL) + return getobjname(ci, GETARG_A(i), name); + else + return NULL; /* no useful name can be found */ +} + + +/* only ANSI way to check whether a pointer points to an array */ +static int isinstack (CallInfo *ci, const TObject *o) { + StkId p; + for (p = ci->base; p < ci->top; p++) + if (o == p) return 1; + return 0; +} + + +void luaG_typeerror (lua_State *L, const TObject *o, const char *op) { + const char *name = NULL; + const char *t = luaT_typenames[ttype(o)]; + const char *kind = (isinstack(L->ci, o)) ? + getobjname(L->ci, o - L->base, &name) : NULL; + if (kind) + luaG_runerror(L, "attempt to %s %s `%s' (a %s value)", + op, kind, name, t); + else + luaG_runerror(L, "attempt to %s a %s value", op, t); +} + + +void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { + if (ttisstring(p1)) p1 = p2; + lua_assert(!ttisstring(p1)); + luaG_typeerror(L, p1, "concatenate"); +} + + +void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2) { + TObject temp; + if (luaV_tonumber(p1, &temp) == NULL) + p2 = p1; /* first operand is wrong */ + luaG_typeerror(L, p2, "perform arithmetic on"); +} + + +int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) { + const char *t1 = luaT_typenames[ttype(p1)]; + const char *t2 = luaT_typenames[ttype(p2)]; + if (t1[2] == t2[2]) + luaG_runerror(L, "attempt to compare two %s values", t1); + else + luaG_runerror(L, "attempt to compare %s with %s", t1, t2); + return 0; +} + + +static void addinfo (lua_State *L, const char *msg) { + CallInfo *ci = L->ci; + if (isLua(ci)) { /* is Lua code? */ + char buff[LUA_IDSIZE]; /* add file:line information */ + int line = currentline(ci); + luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); + luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); + } +} + + +void luaG_errormsg (lua_State *L) { + if (L->errfunc != 0) { /* is there an error handling function? */ + StkId errfunc = restorestack(L, L->errfunc); + if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); + setobjs2s(L->top, L->top - 1); /* move argument */ + setobjs2s(L->top - 1, errfunc); /* push function */ + incr_top(L); + luaD_call(L, L->top - 2, 1); /* call it */ + } + luaD_throw(L, LUA_ERRRUN); +} + + +void luaG_runerror (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + addinfo(L, luaO_pushvfstring(L, fmt, argp)); + va_end(argp); + luaG_errormsg(L); +} + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/ldebug.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/ldebug.h new file mode 100644 index 0000000000..7ff395839c --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/ldebug.h @@ -0,0 +1,31 @@ +/* +** $Id: ldebug.h,v 1.32 2002/11/18 11:01:55 roberto Exp $ +** Auxiliary functions from Debug Interface module +** See Copyright Notice in lua.h +*/ + +#ifndef ldebug_h +#define ldebug_h + + +#include "lstate.h" + + +#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) + +#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) + +#define resethookcount(L) (L->hookcount = L->basehookcount) + + +void luaG_inithooks (lua_State *L); +void luaG_typeerror (lua_State *L, const TObject *o, const char *opname); +void luaG_concaterror (lua_State *L, StkId p1, StkId p2); +void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2); +int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2); +void luaG_runerror (lua_State *L, const char *fmt, ...); +void luaG_errormsg (lua_State *L); +int luaG_checkcode (const Proto *pt); + + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/ldo.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/ldo.c new file mode 100644 index 0000000000..ae4f22fd44 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/ldo.c @@ -0,0 +1,458 @@ +/* +** $Id: ldo.c,v 1.217 2003/04/03 13:35:34 roberto Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define ldo_c + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" +#include "lzio.h" + + + + +/* +** {====================================================== +** Error-recovery functions (based on long jumps) +** ======================================================= +*/ + + +/* chain list of long jump buffers */ +struct lua_longjmp { + struct lua_longjmp *previous; + jmp_buf b; + volatile int status; /* error code */ +}; + + +static void seterrorobj (lua_State *L, int errcode, StkId oldtop) { + switch (errcode) { + case LUA_ERRMEM: { + setsvalue2s(oldtop, luaS_new(L, MEMERRMSG)); + break; + } + case LUA_ERRERR: { + setsvalue2s(oldtop, luaS_new(L, "error in error handling")); + break; + } + case LUA_ERRSYNTAX: + case LUA_ERRRUN: { + setobjs2s(oldtop, L->top - 1); /* error message on current top */ + break; + } + } + L->top = oldtop + 1; +} + + +void luaD_throw (lua_State *L, int errcode) { + if (L->errorJmp) { + L->errorJmp->status = errcode; + longjmp(L->errorJmp->b, 1); + } + else { + G(L)->panic(L); + exit(EXIT_FAILURE); + } +} + + +int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { + struct lua_longjmp lj; + lj.status = 0; + lj.previous = L->errorJmp; /* chain new error handler */ + L->errorJmp = &lj; + if (setjmp(lj.b) == 0) + (*f)(L, ud); + L->errorJmp = lj.previous; /* restore old error handler */ + return lj.status; +} + + +static void restore_stack_limit (lua_State *L) { + L->stack_last = L->stack+L->stacksize-1; + if (L->size_ci > LUA_MAXCALLS) { /* there was an overflow? */ + int inuse = (L->ci - L->base_ci); + if (inuse + 1 < LUA_MAXCALLS) /* can `undo' overflow? */ + luaD_reallocCI(L, LUA_MAXCALLS); + } +} + +/* }====================================================== */ + + +static void correctstack (lua_State *L, TObject *oldstack) { + CallInfo *ci; + GCObject *up; + L->top = (L->top - oldstack) + L->stack; + for (up = L->openupval; up != NULL; up = up->gch.next) + gcotouv(up)->v = (gcotouv(up)->v - oldstack) + L->stack; + for (ci = L->base_ci; ci <= L->ci; ci++) { + ci->top = (ci->top - oldstack) + L->stack; + ci->base = (ci->base - oldstack) + L->stack; + } + L->base = L->ci->base; +} + + +void luaD_reallocstack (lua_State *L, int newsize) { + TObject *oldstack = L->stack; + luaM_reallocvector(L, L->stack, L->stacksize, newsize, TObject); + L->stacksize = newsize; + L->stack_last = L->stack+newsize-1-EXTRA_STACK; + correctstack(L, oldstack); +} + + +void luaD_reallocCI (lua_State *L, int newsize) { + CallInfo *oldci = L->base_ci; + luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); + L->size_ci = cast(unsigned short, newsize); + L->ci = (L->ci - oldci) + L->base_ci; + L->end_ci = L->base_ci + L->size_ci; +} + + +void luaD_growstack (lua_State *L, int n) { + if (n <= L->stacksize) /* double size is enough? */ + luaD_reallocstack(L, 2*L->stacksize); + else + luaD_reallocstack(L, L->stacksize + n + EXTRA_STACK); +} + + +static void luaD_growCI (lua_State *L) { + if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */ + luaD_throw(L, LUA_ERRERR); + else { + luaD_reallocCI(L, 2*L->size_ci); + if (L->size_ci > LUA_MAXCALLS) + luaG_runerror(L, "stack overflow"); + } +} + + +void luaD_callhook (lua_State *L, int event, int line) { + lua_Hook hook = L->hook; + if (hook && L->allowhook) { + ptrdiff_t top = savestack(L, L->top); + ptrdiff_t ci_top = savestack(L, L->ci->top); + lua_Debug ar; + ar.event = event; + ar.currentline = line; + if (event == LUA_HOOKTAILRET) + ar.i_ci = 0; /* tail call; no debug information about it */ + else + ar.i_ci = L->ci - L->base_ci; + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + L->ci->top = L->top + LUA_MINSTACK; + L->allowhook = 0; /* cannot call hooks inside a hook */ + lua_unlock(L); + (*hook)(L, &ar); + lua_lock(L); + lua_assert(!L->allowhook); + L->allowhook = 1; + L->ci->top = restorestack(L, ci_top); + L->top = restorestack(L, top); + } +} + + +static void adjust_varargs (lua_State *L, int nfixargs, StkId base) { + int i; + Table *htab; + TObject nname; + int actual = L->top - base; /* actual number of arguments */ + if (actual < nfixargs) { + luaD_checkstack(L, nfixargs - actual); + for (; actual < nfixargs; ++actual) + setnilvalue(L->top++); + } + actual -= nfixargs; /* number of extra arguments */ + htab = luaH_new(L, actual, 1); /* create `arg' table */ + for (i=0; itop - actual + i); + /* store counter in field `n' */ + setsvalue(&nname, luaS_newliteral(L, "n")); + setnvalue(luaH_set(L, htab, &nname), cast(lua_Number, actual)); + L->top -= actual; /* remove extra elements from the stack */ + sethvalue(L->top, htab); + incr_top(L); +} + + +static StkId tryfuncTM (lua_State *L, StkId func) { + const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); + StkId p; + ptrdiff_t funcr = savestack(L, func); + if (!ttisfunction(tm)) + luaG_typeerror(L, func, "call"); + /* Open a hole inside the stack at `func' */ + for (p = L->top; p > func; p--) setobjs2s(p, p-1); + incr_top(L); + func = restorestack(L, funcr); /* previous call may change stack */ + setobj2s(func, tm); /* tag method is the new function to be called */ + return func; +} + + +StkId luaD_precall (lua_State *L, StkId func) { + LClosure *cl; + ptrdiff_t funcr = savestack(L, func); + if (!ttisfunction(func)) /* `func' is not a function? */ + func = tryfuncTM(L, func); /* check the `function' tag method */ + if (L->ci + 1 == L->end_ci) luaD_growCI(L); + else condhardstacktests(luaD_reallocCI(L, L->size_ci)); + cl = &clvalue(func)->l; + if (!cl->isC) { /* Lua function? prepare its call */ + CallInfo *ci; + Proto *p = cl->p; + if (p->is_vararg) /* varargs? */ + adjust_varargs(L, p->numparams, func+1); + luaD_checkstack(L, p->maxstacksize); + ci = ++L->ci; /* now `enter' new function */ + L->base = L->ci->base = restorestack(L, funcr) + 1; + ci->top = L->base + p->maxstacksize; + ci->u.l.savedpc = p->code; /* starting point */ + ci->u.l.tailcalls = 0; + ci->state = CI_SAVEDPC; + while (L->top < ci->top) + setnilvalue(L->top++); + L->top = ci->top; + return NULL; + } + else { /* if is a C function, call it */ + CallInfo *ci; + int n; + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci = ++L->ci; /* now `enter' new function */ + L->base = L->ci->base = restorestack(L, funcr) + 1; + ci->top = L->top + LUA_MINSTACK; + ci->state = CI_C; /* a C function */ + if (L->hookmask & LUA_MASKCALL) + luaD_callhook(L, LUA_HOOKCALL, -1); + lua_unlock(L); +#ifdef LUA_COMPATUPVALUES + lua_pushupvalues(L); +#endif + n = (*clvalue(L->base - 1)->c.f)(L); /* do the actual call */ + lua_lock(L); + return L->top - n; + } +} + + +static StkId callrethooks (lua_State *L, StkId firstResult) { + ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ + luaD_callhook(L, LUA_HOOKRET, -1); + if (!(L->ci->state & CI_C)) { /* Lua function? */ + while (L->ci->u.l.tailcalls--) /* call hook for eventual tail calls */ + luaD_callhook(L, LUA_HOOKTAILRET, -1); + } + return restorestack(L, fr); +} + + +void luaD_poscall (lua_State *L, int wanted, StkId firstResult) { + StkId res; + if (L->hookmask & LUA_MASKRET) + firstResult = callrethooks(L, firstResult); + res = L->base - 1; /* res == final position of 1st result */ + L->ci--; + L->base = L->ci->base; /* restore base */ + /* move results to correct place */ + while (wanted != 0 && firstResult < L->top) { + setobjs2s(res++, firstResult++); + wanted--; + } + while (wanted-- > 0) + setnilvalue(res++); + L->top = res; +} + + +/* +** Call a function (C or Lua). The function to be called is at *func. +** The arguments are on the stack, right after the function. +** When returns, all the results are on the stack, starting at the original +** function position. +*/ +void luaD_call (lua_State *L, StkId func, int nResults) { + StkId firstResult; + lua_assert(!(L->ci->state & CI_CALLING)); + if (++L->nCcalls >= LUA_MAXCCALLS) { + if (L->nCcalls == LUA_MAXCCALLS) + luaG_runerror(L, "C stack overflow"); + else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3))) + luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ + } + firstResult = luaD_precall(L, func); + if (firstResult == NULL) /* is a Lua function? */ + firstResult = luaV_execute(L); /* call it */ + luaD_poscall(L, nResults, firstResult); + L->nCcalls--; + luaC_checkGC(L); +} + + +static void resume (lua_State *L, void *ud) { + StkId firstResult; + int nargs = *cast(int *, ud); + CallInfo *ci = L->ci; + if (ci == L->base_ci) { /* no activation record? */ + if (nargs >= L->top - L->base) + luaG_runerror(L, "cannot resume dead coroutine"); + luaD_precall(L, L->top - (nargs + 1)); /* start coroutine */ + } + else if (ci->state & CI_YIELD) { /* inside a yield? */ + if (ci->state & CI_C) { /* `common' yield? */ + /* finish interrupted execution of `OP_CALL' */ + int nresults; + lua_assert((ci-1)->state & CI_SAVEDPC); + lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL || + GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL); + nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1; + luaD_poscall(L, nresults, L->top - nargs); /* complete it */ + if (nresults >= 0) L->top = L->ci->top; + } + else { /* yielded inside a hook: just continue its execution */ + ci->state &= ~CI_YIELD; + } + } + else + luaG_runerror(L, "cannot resume non-suspended coroutine"); + firstResult = luaV_execute(L); + if (firstResult != NULL) /* return? */ + luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */ +} + + +LUA_API int lua_resume (lua_State *L, int nargs) { + int status; + lu_byte old_allowhooks; + lua_lock(L); + old_allowhooks = L->allowhook; + lua_assert(L->errfunc == 0 && L->nCcalls == 0); + status = luaD_rawrunprotected(L, resume, &nargs); + if (status != 0) { /* error? */ + L->ci = L->base_ci; /* go back to initial level */ + L->base = L->ci->base; + L->nCcalls = 0; + luaF_close(L, L->base); /* close eventual pending closures */ + seterrorobj(L, status, L->base); + L->allowhook = old_allowhooks; + restore_stack_limit(L); + } + lua_unlock(L); + return status; +} + + +LUA_API int lua_yield (lua_State *L, int nresults) { + CallInfo *ci; + lua_lock(L); + ci = L->ci; + if (L->nCcalls > 0) + luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); + if (ci->state & CI_C) { /* usual yield */ + if ((ci-1)->state & CI_C) + luaG_runerror(L, "cannot yield a C function"); + if (L->top - nresults > L->base) { /* is there garbage in the stack? */ + int i; + for (i=0; ibase + i, L->top - nresults + i); + L->top = L->base + nresults; + } + } /* else it's an yield inside a hook: nothing to do */ + ci->state |= CI_YIELD; + lua_unlock(L); + return -1; +} + + +int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t old_top, ptrdiff_t ef) { + int status; + unsigned short oldnCcalls = L->nCcalls; + ptrdiff_t old_ci = saveci(L, L->ci); + lu_byte old_allowhooks = L->allowhook; + ptrdiff_t old_errfunc = L->errfunc; + L->errfunc = ef; + status = luaD_rawrunprotected(L, func, u); + if (status != 0) { /* an error occurred? */ + StkId oldtop = restorestack(L, old_top); + luaF_close(L, oldtop); /* close eventual pending closures */ + seterrorobj(L, status, oldtop); + L->nCcalls = oldnCcalls; + L->ci = restoreci(L, old_ci); + L->base = L->ci->base; + L->allowhook = old_allowhooks; + restore_stack_limit(L); + } + L->errfunc = old_errfunc; + return status; +} + + + +/* +** Execute a protected parser. +*/ +struct SParser { /* data to `f_parser' */ + ZIO *z; + Mbuffer buff; /* buffer to be used by the scanner */ + int bin; +}; + +static void f_parser (lua_State *L, void *ud) { + struct SParser *p; + Proto *tf; + Closure *cl; + luaC_checkGC(L); + p = cast(struct SParser *, ud); + tf = p->bin ? luaU_undump(L, p->z, &p->buff) : luaY_parser(L, p->z, &p->buff); + cl = luaF_newLclosure(L, 0, gt(L)); + cl->l.p = tf; + setclvalue(L->top, cl); + incr_top(L); +} + + +int luaD_protectedparser (lua_State *L, ZIO *z, int bin) { + struct SParser p; + int status; + ptrdiff_t oldtopr = savestack(L, L->top); /* save current top */ + p.z = z; p.bin = bin; + luaZ_initbuffer(L, &p.buff); + status = luaD_rawrunprotected(L, f_parser, &p); + luaZ_freebuffer(L, &p.buff); + if (status != 0) { /* error? */ + StkId oldtop = restorestack(L, oldtopr); + seterrorobj(L, status, oldtop); + } + return status; +} + + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/ldo.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/ldo.h new file mode 100644 index 0000000000..2a61bf5bb2 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/ldo.h @@ -0,0 +1,60 @@ +/* +** $Id: ldo.h,v 1.56 2002/12/04 17:29:32 roberto Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + +#ifndef ldo_h +#define ldo_h + + +#include "lobject.h" +#include "lstate.h" +#include "lzio.h" + + +/* +** macro to control inclusion of some hard tests on stack reallocation +*/ +#ifndef HARDSTACKTESTS +#define condhardstacktests(x) { /* empty */ } +#else +#define condhardstacktests(x) x +#endif + + +#define luaD_checkstack(L,n) \ + if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TObject)) \ + luaD_growstack(L, n); \ + else condhardstacktests(luaD_reallocstack(L, L->stacksize)); + + +#define incr_top(L) {luaD_checkstack(L,1); L->top++;} + +#define savestack(L,p) ((char *)(p) - (char *)L->stack) +#define restorestack(L,n) ((TObject *)((char *)L->stack + (n))) + +#define saveci(L,p) ((char *)(p) - (char *)L->base_ci) +#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n))) + + +/* type of protected functions, to be ran by `runprotected' */ +typedef void (*Pfunc) (lua_State *L, void *ud); + +void luaD_resetprotection (lua_State *L); +int luaD_protectedparser (lua_State *L, ZIO *z, int bin); +void luaD_callhook (lua_State *L, int event, int line); +StkId luaD_precall (lua_State *L, StkId func); +void luaD_call (lua_State *L, StkId func, int nResults); +int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t oldtop, ptrdiff_t ef); +void luaD_poscall (lua_State *L, int wanted, StkId firstResult); +void luaD_reallocCI (lua_State *L, int newsize); +void luaD_reallocstack (lua_State *L, int newsize); +void luaD_growstack (lua_State *L, int n); + +void luaD_throw (lua_State *L, int errcode); +int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); + + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/ldump.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/ldump.c new file mode 100644 index 0000000000..234b011f5f --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/ldump.c @@ -0,0 +1,170 @@ +/* +** $Id: ldump.c,v 1.4 2003/02/11 23:52:12 lhf Exp $ +** save bytecodes +** See Copyright Notice in lua.h +*/ + +#include + +#define ldump_c + +#include "lua.h" + +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lundump.h" + +#define DumpVector(b,n,size,D) DumpBlock(b,(n)*(size),D) +#define DumpLiteral(s,D) DumpBlock("" s,(sizeof(s))-1,D) + +typedef struct { + lua_State* L; + lua_Chunkwriter write; + void* data; +} DumpState; + +static void DumpBlock(const void* b, size_t size, DumpState* D) +{ + lua_unlock(D->L); + (*D->write)(D->L,b,size,D->data); + lua_lock(D->L); +} + +static void DumpByte(int y, DumpState* D) +{ + char x=(char)y; + DumpBlock(&x,sizeof(x),D); +} + +static void DumpInt(int x, DumpState* D) +{ + DumpBlock(&x,sizeof(x),D); +} + +static void DumpSize(size_t x, DumpState* D) +{ + DumpBlock(&x,sizeof(x),D); +} + +static void DumpNumber(lua_Number x, DumpState* D) +{ + DumpBlock(&x,sizeof(x),D); +} + +static void DumpString(TString* s, DumpState* D) +{ + if (s==NULL || getstr(s)==NULL) + DumpSize(0,D); + else + { + size_t size=s->tsv.len+1; /* include trailing '\0' */ + DumpSize(size,D); + DumpBlock(getstr(s),size,D); + } +} + +static void DumpCode(const Proto* f, DumpState* D) +{ + DumpInt(f->sizecode,D); + DumpVector(f->code,f->sizecode,sizeof(*f->code),D); +} + +static void DumpLocals(const Proto* f, DumpState* D) +{ + int i,n=f->sizelocvars; + DumpInt(n,D); + for (i=0; ilocvars[i].varname,D); + DumpInt(f->locvars[i].startpc,D); + DumpInt(f->locvars[i].endpc,D); + } +} + +static void DumpLines(const Proto* f, DumpState* D) +{ + DumpInt(f->sizelineinfo,D); + DumpVector(f->lineinfo,f->sizelineinfo,sizeof(*f->lineinfo),D); +} + +static void DumpUpvalues(const Proto* f, DumpState* D) +{ + int i,n=f->sizeupvalues; + DumpInt(n,D); + for (i=0; iupvalues[i],D); +} + +static void DumpFunction(const Proto* f, const TString* p, DumpState* D); + +static void DumpConstants(const Proto* f, DumpState* D) +{ + int i,n; + DumpInt(n=f->sizek,D); + for (i=0; ik[i]; + DumpByte(ttype(o),D); + switch (ttype(o)) + { + case LUA_TNUMBER: + DumpNumber(nvalue(o),D); + break; + case LUA_TSTRING: + DumpString(tsvalue(o),D); + break; + case LUA_TNIL: + break; + default: + lua_assert(0); /* cannot happen */ + break; + } + } + DumpInt(n=f->sizep,D); + for (i=0; ip[i],f->source,D); +} + +static void DumpFunction(const Proto* f, const TString* p, DumpState* D) +{ + DumpString((f->source==p) ? NULL : f->source,D); + DumpInt(f->lineDefined,D); + DumpByte(f->nups,D); + DumpByte(f->numparams,D); + DumpByte(f->is_vararg,D); + DumpByte(f->maxstacksize,D); + DumpLines(f,D); + DumpLocals(f,D); + DumpUpvalues(f,D); + DumpConstants(f,D); + DumpCode(f,D); +} + +static void DumpHeader(DumpState* D) +{ + DumpLiteral(LUA_SIGNATURE,D); + DumpByte(VERSION,D); + DumpByte(luaU_endianness(),D); + DumpByte(sizeof(int),D); + DumpByte(sizeof(size_t),D); + DumpByte(sizeof(Instruction),D); + DumpByte(SIZE_OP,D); + DumpByte(SIZE_A,D); + DumpByte(SIZE_B,D); + DumpByte(SIZE_C,D); + DumpByte(sizeof(lua_Number),D); + DumpNumber(TEST_NUMBER,D); +} + +/* +** dump function as precompiled chunk +*/ +void luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data) +{ + DumpState D; + D.L=L; + D.write=w; + D.data=data; + DumpHeader(&D); + DumpFunction(Main,NULL,&D); +} + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lfunc.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/lfunc.c new file mode 100644 index 0000000000..31044fa56b --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lfunc.c @@ -0,0 +1,135 @@ +/* +** $Id: lfunc.c,v 1.67 2003/03/18 12:50:04 roberto Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + + +#include + +#define lfunc_c + +#include "lua.h" + +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + +#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ + cast(int, sizeof(TObject)*((n)-1))) + +#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ + cast(int, sizeof(TObject *)*((n)-1))) + + + +Closure *luaF_newCclosure (lua_State *L, int nelems) { + Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); + luaC_link(L, valtogco(c), LUA_TFUNCTION); + c->c.isC = 1; + c->c.nupvalues = cast(lu_byte, nelems); + return c; +} + + +Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *e) { + Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); + luaC_link(L, valtogco(c), LUA_TFUNCTION); + c->l.isC = 0; + c->l.g = *e; + c->l.nupvalues = cast(lu_byte, nelems); + return c; +} + + +UpVal *luaF_findupval (lua_State *L, StkId level) { + GCObject **pp = &L->openupval; + UpVal *p; + UpVal *v; + while ((p = ngcotouv(*pp)) != NULL && p->v >= level) { + if (p->v == level) return p; + pp = &p->next; + } + v = luaM_new(L, UpVal); /* not found: create a new one */ + v->tt = LUA_TUPVAL; + v->marked = 1; /* open upvalues should not be collected */ + v->v = level; /* current value lives in the stack */ + v->next = *pp; /* chain it in the proper position */ + *pp = valtogco(v); + return v; +} + + +void luaF_close (lua_State *L, StkId level) { + UpVal *p; + while ((p = ngcotouv(L->openupval)) != NULL && p->v >= level) { + setobj(&p->value, p->v); /* save current value (write barrier) */ + p->v = &p->value; /* now current value lives here */ + L->openupval = p->next; /* remove from `open' list */ + luaC_link(L, valtogco(p), LUA_TUPVAL); + } +} + + +Proto *luaF_newproto (lua_State *L) { + Proto *f = luaM_new(L, Proto); + luaC_link(L, valtogco(f), LUA_TPROTO); + f->k = NULL; + f->sizek = 0; + f->p = NULL; + f->sizep = 0; + f->code = NULL; + f->sizecode = 0; + f->sizelineinfo = 0; + f->sizeupvalues = 0; + f->nups = 0; + f->upvalues = NULL; + f->numparams = 0; + f->is_vararg = 0; + f->maxstacksize = 0; + f->lineinfo = NULL; + f->sizelocvars = 0; + f->locvars = NULL; + f->lineDefined = 0; + f->source = NULL; + return f; +} + + +void luaF_freeproto (lua_State *L, Proto *f) { + luaM_freearray(L, f->code, f->sizecode, Instruction); + luaM_freearray(L, f->p, f->sizep, Proto *); + luaM_freearray(L, f->k, f->sizek, TObject); + luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); + luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); + luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); + luaM_freelem(L, f); +} + + +void luaF_freeclosure (lua_State *L, Closure *c) { + int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : + sizeLclosure(c->l.nupvalues); + luaM_free(L, c, size); +} + + +/* +** Look for n-th local variable at line `line' in function `func'. +** Returns NULL if not found. +*/ +const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { + int i; + for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { + if (pc < f->locvars[i].endpc) { /* is variable active? */ + local_number--; + if (local_number == 0) + return getstr(f->locvars[i].varname); + } + } + return NULL; /* not found */ +} + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lfunc.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/lfunc.h new file mode 100644 index 0000000000..5d5325076b --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lfunc.h @@ -0,0 +1,25 @@ +/* +** $Id: lfunc.h,v 1.21 2003/03/18 12:50:04 roberto Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + +#ifndef lfunc_h +#define lfunc_h + + +#include "lobject.h" + + +Proto *luaF_newproto (lua_State *L); +Closure *luaF_newCclosure (lua_State *L, int nelems); +Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *e); +UpVal *luaF_findupval (lua_State *L, StkId level); +void luaF_close (lua_State *L, StkId level); +void luaF_freeproto (lua_State *L, Proto *f); +void luaF_freeclosure (lua_State *L, Closure *c); + +const char *luaF_getlocalname (const Proto *func, int local_number, int pc); + + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lgc.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/lgc.c new file mode 100644 index 0000000000..4cc45e39d0 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lgc.c @@ -0,0 +1,493 @@ +/* +** $Id: lgc.c,v 1.171 2003/04/03 13:35:34 roberto Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#include + +#define lgc_c + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +typedef struct GCState { + GCObject *tmark; /* list of marked objects to be traversed */ + GCObject *wk; /* list of traversed key-weak tables (to be cleared) */ + GCObject *wv; /* list of traversed value-weak tables */ + GCObject *wkv; /* list of traversed key-value weak tables */ + global_State *g; +} GCState; + + +/* +** some userful bit tricks +*/ +#define setbit(x,b) ((x) |= (1<<(b))) +#define resetbit(x,b) ((x) &= cast(lu_byte, ~(1<<(b)))) +#define testbit(x,b) ((x) & (1<<(b))) + +#define unmark(x) resetbit((x)->gch.marked, 0) +#define ismarked(x) ((x)->gch.marked & ((1<<4)|1)) + +#define stringmark(s) setbit((s)->tsv.marked, 0) + + +#define isfinalized(u) (!testbit((u)->uv.marked, 1)) +#define markfinalized(u) resetbit((u)->uv.marked, 1) + + +#define KEYWEAKBIT 1 +#define VALUEWEAKBIT 2 +#define KEYWEAK (1<gch.marked, 0); /* mark object */ + switch (o->gch.tt) { + case LUA_TUSERDATA: { + markvalue(st, gcotou(o)->uv.metatable); + break; + } + case LUA_TFUNCTION: { + gcotocl(o)->c.gclist = st->tmark; + st->tmark = o; + break; + } + case LUA_TTABLE: { + gcotoh(o)->gclist = st->tmark; + st->tmark = o; + break; + } + case LUA_TTHREAD: { + gcototh(o)->gclist = st->tmark; + st->tmark = o; + break; + } + case LUA_TPROTO: { + gcotop(o)->gclist = st->tmark; + st->tmark = o; + break; + } + default: lua_assert(o->gch.tt == LUA_TSTRING); + } +} + + +static void marktmu (GCState *st) { + GCObject *u; + for (u = st->g->tmudata; u; u = u->gch.next) { + unmark(u); /* may be marked, if left from previous GC */ + reallymarkobject(st, u); + } +} + + +/* move `dead' udata that need finalization to list `tmudata' */ +void luaC_separateudata (lua_State *L) { + GCObject **p = &G(L)->rootudata; + GCObject *curr; + GCObject *collected = NULL; /* to collect udata with gc event */ + GCObject **lastcollected = &collected; + while ((curr = *p) != NULL) { + lua_assert(curr->gch.tt == LUA_TUSERDATA); + if (ismarked(curr) || isfinalized(gcotou(curr))) + p = &curr->gch.next; /* don't bother with them */ + + else if (fasttm(L, gcotou(curr)->uv.metatable, TM_GC) == NULL) { + markfinalized(gcotou(curr)); /* don't need finalization */ + p = &curr->gch.next; + } + else { /* must call its gc method */ + *p = curr->gch.next; + curr->gch.next = NULL; /* link `curr' at the end of `collected' list */ + *lastcollected = curr; + lastcollected = &curr->gch.next; + } + } + /* insert collected udata with gc event into `tmudata' list */ + *lastcollected = G(L)->tmudata; + G(L)->tmudata = collected; +} + + +static void removekey (Node *n) { + setnilvalue(gval(n)); /* remove corresponding value ... */ + if (iscollectable(gkey(n))) + setttype(gkey(n), LUA_TNONE); /* dead key; remove it */ +} + + +static void traversetable (GCState *st, Table *h) { + int i; + int weakkey = 0; + int weakvalue = 0; + const TObject *mode; + markvalue(st, h->metatable); + lua_assert(h->lsizenode || h->node == st->g->dummynode); + mode = gfasttm(st->g, h->metatable, TM_MODE); + if (mode && ttisstring(mode)) { /* is there a weak mode? */ + weakkey = (strchr(svalue(mode), 'k') != NULL); + weakvalue = (strchr(svalue(mode), 'v') != NULL); + if (weakkey || weakvalue) { /* is really weak? */ + GCObject **weaklist; + h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */ + h->marked |= cast(lu_byte, (weakkey << KEYWEAKBIT) | + (weakvalue << VALUEWEAKBIT)); + weaklist = (weakkey && weakvalue) ? &st->wkv : + (weakkey) ? &st->wk : + &st->wv; + h->gclist = *weaklist; /* must be cleared after GC, ... */ + *weaklist = valtogco(h); /* ... so put in the appropriate list */ + } + } + if (!weakvalue) { + i = h->sizearray; + while (i--) + markobject(st, &h->array[i]); + } + i = sizenode(h); + while (i--) { + Node *n = gnode(h, i); + if (!ttisnil(gval(n))) { + lua_assert(!ttisnil(gkey(n))); + condmarkobject(st, gkey(n), !weakkey); + condmarkobject(st, gval(n), !weakvalue); + } + } +} + + +static void traverseproto (GCState *st, Proto *f) { + int i; + stringmark(f->source); + for (i=0; isizek; i++) { /* mark literal strings */ + if (ttisstring(f->k+i)) + stringmark(tsvalue(f->k+i)); + } + for (i=0; isizeupvalues; i++) /* mark upvalue names */ + stringmark(f->upvalues[i]); + for (i=0; isizep; i++) /* mark nested protos */ + markvalue(st, f->p[i]); + for (i=0; isizelocvars; i++) /* mark local-variable names */ + stringmark(f->locvars[i].varname); + lua_assert(luaG_checkcode(f)); +} + + + +static void traverseclosure (GCState *st, Closure *cl) { + if (cl->c.isC) { + int i; + for (i=0; ic.nupvalues; i++) /* mark its upvalues */ + markobject(st, &cl->c.upvalue[i]); + } + else { + int i; + lua_assert(cl->l.nupvalues == cl->l.p->nups); + markvalue(st, hvalue(&cl->l.g)); + markvalue(st, cl->l.p); + for (i=0; il.nupvalues; i++) { /* mark its upvalues */ + UpVal *u = cl->l.upvals[i]; + if (!u->marked) { + markobject(st, &u->value); + u->marked = 1; + } + } + } +} + + +static void checkstacksizes (lua_State *L, StkId max) { + int used = L->ci - L->base_ci; /* number of `ci' in use */ + if (4*used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci) + luaD_reallocCI(L, L->size_ci/2); /* still big enough... */ + else condhardstacktests(luaD_reallocCI(L, L->size_ci)); + used = max - L->stack; /* part of stack in use */ + if (4*used < L->stacksize && 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize) + luaD_reallocstack(L, L->stacksize/2); /* still big enough... */ + else condhardstacktests(luaD_reallocstack(L, L->stacksize)); +} + + +static void traversestack (GCState *st, lua_State *L1) { + StkId o, lim; + CallInfo *ci; + markobject(st, gt(L1)); + lim = L1->top; + for (ci = L1->base_ci; ci <= L1->ci; ci++) { + lua_assert(ci->top <= L1->stack_last); + lua_assert(ci->state & (CI_C | CI_HASFRAME | CI_SAVEDPC)); + if (!(ci->state & CI_C) && lim < ci->top) + lim = ci->top; + } + for (o = L1->stack; o < L1->top; o++) + markobject(st, o); + for (; o <= lim; o++) + setnilvalue(o); + checkstacksizes(L1, lim); +} + + +static void propagatemarks (GCState *st) { + while (st->tmark) { /* traverse marked objects */ + switch (st->tmark->gch.tt) { + case LUA_TTABLE: { + Table *h = gcotoh(st->tmark); + st->tmark = h->gclist; + traversetable(st, h); + break; + } + case LUA_TFUNCTION: { + Closure *cl = gcotocl(st->tmark); + st->tmark = cl->c.gclist; + traverseclosure(st, cl); + break; + } + case LUA_TTHREAD: { + lua_State *th = gcototh(st->tmark); + st->tmark = th->gclist; + traversestack(st, th); + break; + } + case LUA_TPROTO: { + Proto *p = gcotop(st->tmark); + st->tmark = p->gclist; + traverseproto(st, p); + break; + } + default: lua_assert(0); + } + } +} + + +static int valismarked (const TObject *o) { + if (ttisstring(o)) + stringmark(tsvalue(o)); /* strings are `values', so are never weak */ + return !iscollectable(o) || testbit(o->value.gc->gch.marked, 0); +} + + +/* +** clear collected keys from weaktables +*/ +static void cleartablekeys (GCObject *l) { + while (l) { + Table *h = gcotoh(l); + int i = sizenode(h); + lua_assert(h->marked & KEYWEAK); + while (i--) { + Node *n = gnode(h, i); + if (!valismarked(gkey(n))) /* key was collected? */ + removekey(n); /* remove entry from table */ + } + l = h->gclist; + } +} + + +/* +** clear collected values from weaktables +*/ +static void cleartablevalues (GCObject *l) { + while (l) { + Table *h = gcotoh(l); + int i = h->sizearray; + lua_assert(h->marked & VALUEWEAK); + while (i--) { + TObject *o = &h->array[i]; + if (!valismarked(o)) /* value was collected? */ + setnilvalue(o); /* remove value */ + } + i = sizenode(h); + while (i--) { + Node *n = gnode(h, i); + if (!valismarked(gval(n))) /* value was collected? */ + removekey(n); /* remove entry from table */ + } + l = h->gclist; + } +} + + +static void freeobj (lua_State *L, GCObject *o) { + switch (o->gch.tt) { + case LUA_TPROTO: luaF_freeproto(L, gcotop(o)); break; + case LUA_TFUNCTION: luaF_freeclosure(L, gcotocl(o)); break; + case LUA_TUPVAL: luaM_freelem(L, gcotouv(o)); break; + case LUA_TTABLE: luaH_free(L, gcotoh(o)); break; + case LUA_TTHREAD: { + lua_assert(gcototh(o) != L && gcototh(o) != G(L)->mainthread); + luaE_freethread(L, gcototh(o)); + break; + } + case LUA_TSTRING: { + luaM_free(L, o, sizestring(gcotots(o)->tsv.len)); + break; + } + case LUA_TUSERDATA: { + luaM_free(L, o, sizeudata(gcotou(o)->uv.len)); + break; + } + default: lua_assert(0); + } +} + + +static int sweeplist (lua_State *L, GCObject **p, int limit) { + GCObject *curr; + int count = 0; /* number of collected items */ + while ((curr = *p) != NULL) { + if (curr->gch.marked > limit) { + unmark(curr); + p = &curr->gch.next; + } + else { + count++; + *p = curr->gch.next; + freeobj(L, curr); + } + } + return count; +} + + +static void sweepstrings (lua_State *L, int all) { + int i; + for (i=0; istrt.size; i++) { /* for each list */ + G(L)->strt.nuse -= sweeplist(L, &G(L)->strt.hash[i], all); + } +} + + +static void checkSizes (lua_State *L) { + /* check size of string hash */ + if (G(L)->strt.nuse < cast(ls_nstr, G(L)->strt.size/4) && + G(L)->strt.size > MINSTRTABSIZE*2) + luaS_resize(L, G(L)->strt.size/2); /* table is too big */ + /* check size of buffer */ + if (luaZ_sizebuffer(&G(L)->buff) > LUA_MINBUFFER*2) { /* buffer too big? */ + size_t newsize = luaZ_sizebuffer(&G(L)->buff) / 2; + luaZ_resizebuffer(L, &G(L)->buff, newsize); + } + G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */ +} + + +static void do1gcTM (lua_State *L, Udata *udata) { + const TObject *tm = fasttm(L, udata->uv.metatable, TM_GC); + if (tm != NULL) { + setobj2s(L->top, tm); + setuvalue(L->top+1, udata); + L->top += 2; + luaD_call(L, L->top - 2, 0); + } +} + + +void luaC_callGCTM (lua_State *L) { + lu_byte oldah = L->allowhook; + L->allowhook = 0; /* stop debug hooks during GC tag methods */ + L->top++; /* reserve space to keep udata while runs its gc method */ + while (G(L)->tmudata != NULL) { + GCObject *o = G(L)->tmudata; + Udata *udata = gcotou(o); + G(L)->tmudata = udata->uv.next; /* remove udata from `tmudata' */ + udata->uv.next = G(L)->rootudata; /* return it to `root' list */ + G(L)->rootudata = o; + setuvalue(L->top - 1, udata); /* keep a reference to it */ + unmark(o); + markfinalized(udata); + do1gcTM(L, udata); + } + L->top--; + L->allowhook = oldah; /* restore hooks */ +} + + +void luaC_sweep (lua_State *L, int all) { + if (all) all = 256; /* larger than any mark */ + sweeplist(L, &G(L)->rootudata, all); + sweepstrings(L, all); + sweeplist(L, &G(L)->rootgc, all); +} + + +/* mark root set */ +static void markroot (GCState *st, lua_State *L) { + global_State *g = st->g; + markobject(st, defaultmeta(L)); + markobject(st, registry(L)); + traversestack(st, g->mainthread); + if (L != g->mainthread) /* another thread is running? */ + markvalue(st, L); /* cannot collect it */ +} + + +static void mark (lua_State *L) { + GCState st; + GCObject *wkv; + st.g = G(L); + st.tmark = NULL; + st.wkv = st.wk = st.wv = NULL; + markroot(&st, L); + propagatemarks(&st); /* mark all reachable objects */ + cleartablevalues(st.wkv); + cleartablevalues(st.wv); + wkv = st.wkv; /* keys must be cleared after preserving udata */ + st.wkv = NULL; + st.wv = NULL; + luaC_separateudata(L); /* separate userdata to be preserved */ + marktmu(&st); /* mark `preserved' userdata */ + propagatemarks(&st); /* remark, to propagate `preserveness' */ + cleartablekeys(wkv); + /* `propagatemarks' may resuscitate some weak tables; clear them too */ + cleartablekeys(st.wk); + cleartablevalues(st.wv); + cleartablekeys(st.wkv); + cleartablevalues(st.wkv); +} + + +void luaC_collectgarbage (lua_State *L) { + mark(L); + luaC_sweep(L, 0); + checkSizes(L); + luaC_callGCTM(L); +} + + +void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { + o->gch.next = G(L)->rootgc; + G(L)->rootgc = o; + o->gch.marked = 0; + o->gch.tt = tt; +} + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lgc.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/lgc.h new file mode 100644 index 0000000000..6ab6c91749 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lgc.h @@ -0,0 +1,25 @@ +/* +** $Id: lgc.h,v 1.19 2003/02/28 19:45:15 roberto Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#ifndef lgc_h +#define lgc_h + + +#include "lobject.h" + + +#define luaC_checkGC(L) { lua_assert(!(L->ci->state & CI_CALLING)); \ + if (G(L)->nblocks >= G(L)->GCthreshold) luaC_collectgarbage(L); } + + +void luaC_separateudata (lua_State *L); +void luaC_callGCTM (lua_State *L); +void luaC_sweep (lua_State *L, int all); +void luaC_collectgarbage (lua_State *L); +void luaC_link (lua_State *L, GCObject *o, lu_byte tt); + + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/liolib.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/liolib.c new file mode 100644 index 0000000000..14bd7d9909 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/liolib.c @@ -0,0 +1,750 @@ +/* +** $Id: liolib.c,v 2.39 2003/03/19 21:16:12 roberto Exp $ +** Standard I/O (and system) library +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include +#include + +#define liolib_c + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +/* +** by default, gcc does not get `tmpname' +*/ +#ifndef USE_TMPNAME +#ifdef __GNUC__ +#define USE_TMPNAME 0 +#else +#define USE_TMPNAME 1 +#endif +#endif + + +/* +** by default, posix systems get `popen' +*/ +#ifndef USE_POPEN +#ifdef _POSIX_C_SOURCE +#if _POSIX_C_SOURCE >= 2 +#define USE_POPEN 1 +#endif +#endif +#endif + +#ifndef USE_POPEN +#define USE_POPEN 0 +#endif + + + + +/* +** {====================================================== +** FILE Operations +** ======================================================= +*/ + + +#if !USE_POPEN +#define pclose(f) (-1) +#endif + + +#define FILEHANDLE "FILE*" + +#define IO_INPUT "_input" +#define IO_OUTPUT "_output" + + +static int pushresult (lua_State *L, int i, const char *filename) { + if (i) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushnil(L); + if (filename) + lua_pushfstring(L, "%s: %s", filename, strerror(errno)); + else + lua_pushfstring(L, "%s", strerror(errno)); + lua_pushnumber(L, errno); + return 3; + } +} + + +static FILE **topfile (lua_State *L, int findex) { + FILE **f = (FILE **)luaL_checkudata(L, findex, FILEHANDLE); + if (f == NULL) luaL_argerror(L, findex, "bad file"); + return f; +} + + +static int io_type (lua_State *L) { + FILE **f = (FILE **)luaL_checkudata(L, 1, FILEHANDLE); + if (f == NULL) lua_pushnil(L); + else if (*f == NULL) + lua_pushliteral(L, "closed file"); + else + lua_pushliteral(L, "file"); + return 1; +} + + +static FILE *tofile (lua_State *L, int findex) { + FILE **f = topfile(L, findex); + if (*f == NULL) + luaL_error(L, "attempt to use a closed file"); + return *f; +} + + + +/* +** When creating file handles, always creates a `closed' file handle +** before opening the actual file; so, if there is a memory error, the +** file is not left opened. +*/ +static FILE **newfile (lua_State *L) { + FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); + *pf = NULL; /* file handle is currently `closed' */ + luaL_getmetatable(L, FILEHANDLE); + lua_setmetatable(L, -2); + return pf; +} + + +/* +** assumes that top of the stack is the `io' library, and next is +** the `io' metatable +*/ +static void registerfile (lua_State *L, FILE *f, const char *name, + const char *impname) { + lua_pushstring(L, name); + *newfile(L) = f; + if (impname) { + lua_pushstring(L, impname); + lua_pushvalue(L, -2); + lua_settable(L, -6); /* metatable[impname] = file */ + } + lua_settable(L, -3); /* io[name] = file */ +} + + +static int aux_close (lua_State *L) { + FILE *f = tofile(L, 1); + if (f == stdin || f == stdout || f == stderr) + return 0; /* file cannot be closed */ + else { + int ok = (pclose(f) != -1) || (fclose(f) == 0); + if (ok) + *(FILE **)lua_touserdata(L, 1) = NULL; /* mark file as closed */ + return ok; + } +} + + +static int io_close (lua_State *L) { + if (lua_isnone(L, 1)) { + lua_pushstring(L, IO_OUTPUT); + lua_rawget(L, lua_upvalueindex(1)); + } + return pushresult(L, aux_close(L), NULL); +} + + +static int io_gc (lua_State *L) { + FILE **f = topfile(L, 1); + if (*f != NULL) /* ignore closed files */ + aux_close(L); + return 0; +} + + +static int io_tostring (lua_State *L) { + char buff[32]; + FILE **f = topfile(L, 1); + if (*f == NULL) + strcpy(buff, "closed"); + else + sprintf(buff, "%p", lua_touserdata(L, 1)); + lua_pushfstring(L, "file (%s)", buff); + return 1; +} + + +static int io_open (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + FILE **pf = newfile(L); + *pf = fopen(filename, mode); + return (*pf == NULL) ? pushresult(L, 0, filename) : 1; +} + + +static int io_popen (lua_State *L) { +#if !USE_POPEN + luaL_error(L, "`popen' not supported"); + return 0; +#else + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + FILE **pf = newfile(L); + *pf = popen(filename, mode); + return (*pf == NULL) ? pushresult(L, 0, filename) : 1; +#endif +} + + +static int io_tmpfile (lua_State *L) { + FILE **pf = newfile(L); + *pf = tmpfile(); + return (*pf == NULL) ? pushresult(L, 0, NULL) : 1; +} + + +static FILE *getiofile (lua_State *L, const char *name) { + lua_pushstring(L, name); + lua_rawget(L, lua_upvalueindex(1)); + return tofile(L, -1); +} + + +static int g_iofile (lua_State *L, const char *name, const char *mode) { + if (!lua_isnoneornil(L, 1)) { + const char *filename = lua_tostring(L, 1); + lua_pushstring(L, name); + if (filename) { + FILE **pf = newfile(L); + *pf = fopen(filename, mode); + if (*pf == NULL) { + lua_pushfstring(L, "%s: %s", filename, strerror(errno)); + luaL_argerror(L, 1, lua_tostring(L, -1)); + } + } + else { + tofile(L, 1); /* check that it's a valid file handle */ + lua_pushvalue(L, 1); + } + lua_rawset(L, lua_upvalueindex(1)); + } + /* return current value */ + lua_pushstring(L, name); + lua_rawget(L, lua_upvalueindex(1)); + return 1; +} + + +static int io_input (lua_State *L) { + return g_iofile(L, IO_INPUT, "r"); +} + + +static int io_output (lua_State *L) { + return g_iofile(L, IO_OUTPUT, "w"); +} + + +static int io_readline (lua_State *L); + + +static void aux_lines (lua_State *L, int idx, int close) { + lua_pushliteral(L, FILEHANDLE); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_pushvalue(L, idx); + lua_pushboolean(L, close); /* close/not close file when finished */ + lua_pushcclosure(L, io_readline, 3); +} + + +static int f_lines (lua_State *L) { + tofile(L, 1); /* check that it's a valid file handle */ + aux_lines(L, 1, 0); + return 1; +} + + +static int io_lines (lua_State *L) { + if (lua_isnoneornil(L, 1)) { /* no arguments? */ + lua_pushstring(L, IO_INPUT); + lua_rawget(L, lua_upvalueindex(1)); /* will iterate over default input */ + return f_lines(L); + } + else { + const char *filename = luaL_checkstring(L, 1); + FILE **pf = newfile(L); + *pf = fopen(filename, "r"); + luaL_argcheck(L, *pf, 1, strerror(errno)); + aux_lines(L, lua_gettop(L), 1); + return 1; + } +} + + +/* +** {====================================================== +** READ +** ======================================================= +*/ + + +static int read_number (lua_State *L, FILE *f) { + lua_Number d; + if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { + lua_pushnumber(L, d); + return 1; + } + else return 0; /* read fails */ +} + + +static int test_eof (lua_State *L, FILE *f) { + int c = getc(f); + ungetc(c, f); + lua_pushlstring(L, NULL, 0); + return (c != EOF); +} + + +static int read_line (lua_State *L, FILE *f) { + luaL_Buffer b; + luaL_buffinit(L, &b); + for (;;) { + size_t l; + char *p = luaL_prepbuffer(&b); + if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ + luaL_pushresult(&b); /* close buffer */ + return (lua_strlen(L, -1) > 0); /* check whether read something */ + } + l = strlen(p); + if (p[l-1] != '\n') + luaL_addsize(&b, l); + else { + luaL_addsize(&b, l - 1); /* do not include `eol' */ + luaL_pushresult(&b); /* close buffer */ + return 1; /* read at least an `eol' */ + } + } +} + + +static int read_chars (lua_State *L, FILE *f, size_t n) { + size_t rlen; /* how much to read */ + size_t nr; /* number of chars actually read */ + luaL_Buffer b; + luaL_buffinit(L, &b); + rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ + do { + char *p = luaL_prepbuffer(&b); + if (rlen > n) rlen = n; /* cannot read more than asked */ + nr = fread(p, sizeof(char), rlen, f); + luaL_addsize(&b, nr); + n -= nr; /* still have to read `n' chars */ + } while (n > 0 && nr == rlen); /* until end of count or eof */ + luaL_pushresult(&b); /* close buffer */ + return (n == 0 || lua_strlen(L, -1) > 0); +} + + +static int g_read (lua_State *L, FILE *f, int first) { + int nargs = lua_gettop(L) - 1; + int success; + int n; + if (nargs == 0) { /* no arguments? */ + success = read_line(L, f); + n = first+1; /* to return 1 result */ + } + else { /* ensure stack space for all results and for auxlib's buffer */ + luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); + success = 1; + for (n = first; nargs-- && success; n++) { + if (lua_type(L, n) == LUA_TNUMBER) { + size_t l = (size_t)lua_tonumber(L, n); + success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); + } + else { + const char *p = lua_tostring(L, n); + luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); + switch (p[1]) { + case 'n': /* number */ + success = read_number(L, f); + break; + case 'l': /* line */ + success = read_line(L, f); + break; + case 'a': /* file */ + read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ + success = 1; /* always success */ + break; + case 'w': /* word */ + return luaL_error(L, "obsolete option `*w' to `read'"); + default: + return luaL_argerror(L, n, "invalid format"); + } + } + } + } + if (!success) { + lua_pop(L, 1); /* remove last result */ + lua_pushnil(L); /* push nil instead */ + } + return n - first; +} + + +static int io_read (lua_State *L) { + return g_read(L, getiofile(L, IO_INPUT), 1); +} + + +static int f_read (lua_State *L) { + return g_read(L, tofile(L, 1), 2); +} + + +static int io_readline (lua_State *L) { + FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(2)); + if (f == NULL) /* file is already closed? */ + luaL_error(L, "file is already closed"); + if (read_line(L, f)) return 1; + else { /* EOF */ + if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ + lua_settop(L, 0); + lua_pushvalue(L, lua_upvalueindex(2)); + aux_close(L); /* close it */ + } + return 0; + } +} + +/* }====================================================== */ + + +static int g_write (lua_State *L, FILE *f, int arg) { + int nargs = lua_gettop(L) - 1; + int status = 1; + for (; nargs--; arg++) { + if (lua_type(L, arg) == LUA_TNUMBER) { + /* optimization: could be done exactly as for strings */ + status = status && + fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; + } + else { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + status = status && (fwrite(s, sizeof(char), l, f) == l); + } + } + return pushresult(L, status, NULL); +} + + +static int io_write (lua_State *L) { + return g_write(L, getiofile(L, IO_OUTPUT), 1); +} + + +static int f_write (lua_State *L) { + return g_write(L, tofile(L, 1), 2); +} + + +static int f_seek (lua_State *L) { + static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; + static const char *const modenames[] = {"set", "cur", "end", NULL}; + FILE *f = tofile(L, 1); + int op = luaL_findstring(luaL_optstring(L, 2, "cur"), modenames); + long offset = luaL_optlong(L, 3, 0); + luaL_argcheck(L, op != -1, 2, "invalid mode"); + op = fseek(f, offset, mode[op]); + if (op) + return pushresult(L, 0, NULL); /* error */ + else { + lua_pushnumber(L, ftell(f)); + return 1; + } +} + + +static int io_flush (lua_State *L) { + return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); +} + + +static int f_flush (lua_State *L) { + return pushresult(L, fflush(tofile(L, 1)) == 0, NULL); +} + + +static const luaL_reg iolib[] = { + {"input", io_input}, + {"output", io_output}, + {"lines", io_lines}, + {"close", io_close}, + {"flush", io_flush}, + {"open", io_open}, + {"popen", io_popen}, + {"read", io_read}, + {"tmpfile", io_tmpfile}, + {"type", io_type}, + {"write", io_write}, + {NULL, NULL} +}; + + +static const luaL_reg flib[] = { + {"flush", f_flush}, + {"read", f_read}, + {"lines", f_lines}, + {"seek", f_seek}, + {"write", f_write}, + {"close", io_close}, + {"__gc", io_gc}, + {"__tostring", io_tostring}, + {NULL, NULL} +}; + + +static void createmeta (lua_State *L) { + luaL_newmetatable(L, FILEHANDLE); /* create new metatable for file handles */ + /* file methods */ + lua_pushliteral(L, "__index"); + lua_pushvalue(L, -2); /* push metatable */ + lua_rawset(L, -3); /* metatable.__index = metatable */ + luaL_openlib(L, NULL, flib, 0); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Other O.S. Operations +** ======================================================= +*/ + +static int io_execute (lua_State *L) { + lua_pushnumber(L, system(luaL_checkstring(L, 1))); + return 1; +} + + +static int io_remove (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + return pushresult(L, remove(filename) == 0, filename); +} + + +static int io_rename (lua_State *L) { + const char *fromname = luaL_checkstring(L, 1); + const char *toname = luaL_checkstring(L, 2); + return pushresult(L, rename(fromname, toname) == 0, fromname); +} + + +static int io_tmpname (lua_State *L) { +#if !USE_TMPNAME + luaL_error(L, "`tmpname' not supported"); + return 0; +#else + char buff[L_tmpnam]; + if (tmpnam(buff) != buff) + return luaL_error(L, "unable to generate a unique filename in `tmpname'"); + lua_pushstring(L, buff); + return 1; +#endif +} + + +static int io_getenv (lua_State *L) { + lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ + return 1; +} + + +static int io_clock (lua_State *L) { + lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); + return 1; +} + + +/* +** {====================================================== +** Time/Date operations +** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, +** wday=%w+1, yday=%j, isdst=? } +** ======================================================= +*/ + +static void setfield (lua_State *L, const char *key, int value) { + lua_pushstring(L, key); + lua_pushnumber(L, value); + lua_rawset(L, -3); +} + +static void setboolfield (lua_State *L, const char *key, int value) { + lua_pushstring(L, key); + lua_pushboolean(L, value); + lua_rawset(L, -3); +} + +static int getboolfield (lua_State *L, const char *key) { + int res; + lua_pushstring(L, key); + lua_gettable(L, -2); + res = lua_toboolean(L, -1); + lua_pop(L, 1); + return res; +} + + +static int getfield (lua_State *L, const char *key, int d) { + int res; + lua_pushstring(L, key); + lua_gettable(L, -2); + if (lua_isnumber(L, -1)) + res = (int)(lua_tonumber(L, -1)); + else { + if (d == -2) + return luaL_error(L, "field `%s' missing in date table", key); + res = d; + } + lua_pop(L, 1); + return res; +} + + +static int io_date (lua_State *L) { + const char *s = luaL_optstring(L, 1, "%c"); + time_t t = (time_t)(luaL_optnumber(L, 2, -1)); + struct tm *stm; + if (t == (time_t)(-1)) /* no time given? */ + t = time(NULL); /* use current time */ + if (*s == '!') { /* UTC? */ + stm = gmtime(&t); + s++; /* skip `!' */ + } + else + stm = localtime(&t); + if (stm == NULL) /* invalid date? */ + lua_pushnil(L); + else if (strcmp(s, "*t") == 0) { + lua_newtable(L); + setfield(L, "sec", stm->tm_sec); + setfield(L, "min", stm->tm_min); + setfield(L, "hour", stm->tm_hour); + setfield(L, "day", stm->tm_mday); + setfield(L, "month", stm->tm_mon+1); + setfield(L, "year", stm->tm_year+1900); + setfield(L, "wday", stm->tm_wday+1); + setfield(L, "yday", stm->tm_yday+1); + setboolfield(L, "isdst", stm->tm_isdst); + } + else { + char b[256]; + if (strftime(b, sizeof(b), s, stm)) + lua_pushstring(L, b); + else + return luaL_error(L, "`date' format too long"); + } + return 1; +} + + +static int io_time (lua_State *L) { + if (lua_isnoneornil(L, 1)) /* called without args? */ + lua_pushnumber(L, time(NULL)); /* return current time */ + else { + time_t t; + struct tm ts; + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 1); /* make sure table is at the top */ + ts.tm_sec = getfield(L, "sec", 0); + ts.tm_min = getfield(L, "min", 0); + ts.tm_hour = getfield(L, "hour", 12); + ts.tm_mday = getfield(L, "day", -2); + ts.tm_mon = getfield(L, "month", -2) - 1; + ts.tm_year = getfield(L, "year", -2) - 1900; + ts.tm_isdst = getboolfield(L, "isdst"); + t = mktime(&ts); + if (t == (time_t)(-1)) + lua_pushnil(L); + else + lua_pushnumber(L, t); + } + return 1; +} + + +static int io_difftime (lua_State *L) { + lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), + (time_t)(luaL_optnumber(L, 2, 0)))); + return 1; +} + +/* }====================================================== */ + + +static int io_setloc (lua_State *L) { + static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, + LC_NUMERIC, LC_TIME}; + static const char *const catnames[] = {"all", "collate", "ctype", "monetary", + "numeric", "time", NULL}; + const char *l = lua_tostring(L, 1); + int op = luaL_findstring(luaL_optstring(L, 2, "all"), catnames); + luaL_argcheck(L, l || lua_isnoneornil(L, 1), 1, "string expected"); + luaL_argcheck(L, op != -1, 2, "invalid option"); + lua_pushstring(L, setlocale(cat[op], l)); + return 1; +} + + +static int io_exit (lua_State *L) { + exit(luaL_optint(L, 1, EXIT_SUCCESS)); + return 0; /* to avoid warnings */ +} + +static const luaL_reg syslib[] = { + {"clock", io_clock}, + {"date", io_date}, + {"difftime", io_difftime}, + {"execute", io_execute}, + {"exit", io_exit}, + {"getenv", io_getenv}, + {"remove", io_remove}, + {"rename", io_rename}, + {"setlocale", io_setloc}, + {"time", io_time}, + {"tmpname", io_tmpname}, + {NULL, NULL} +}; + +/* }====================================================== */ + + + +LUALIB_API int luaopen_io (lua_State *L) { + luaL_openlib(L, LUA_OSLIBNAME, syslib, 0); + createmeta(L); + lua_pushvalue(L, -1); + luaL_openlib(L, LUA_IOLIBNAME, iolib, 1); + /* put predefined file handles into `io' table */ + registerfile(L, stdin, "stdin", IO_INPUT); + registerfile(L, stdout, "stdout", IO_OUTPUT); + registerfile(L, stderr, "stderr", NULL); + return 1; +} + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/llex.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/llex.c new file mode 100644 index 0000000000..045e999443 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/llex.c @@ -0,0 +1,417 @@ +/* +** $Id: llex.c,v 1.119 2003/03/24 12:39:34 roberto Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + + +#include +#include + +#define llex_c + +#include "lua.h" + +#include "ldo.h" +#include "llex.h" +#include "lobject.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "lzio.h" + + + +#define next(LS) (LS->current = zgetc(LS->z)) + + + +/* ORDER RESERVED */ +static const char *const token2string [] = { + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "if", + "in", "local", "nil", "not", "or", "repeat", + "return", "then", "true", "until", "while", "*name", + "..", "...", "==", ">=", "<=", "~=", + "*number", "*string", "" +}; + + +void luaX_init (lua_State *L) { + int i; + for (i=0; itsv.reserved = cast(lu_byte, i+1); /* reserved word */ + } +} + + +#define MAXSRC 80 + + +void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) { + if (val > limit) { + msg = luaO_pushfstring(ls->L, "too many %s (limit=%d)", msg, limit); + luaX_syntaxerror(ls, msg); + } +} + + +void luaX_errorline (LexState *ls, const char *s, const char *token, int line) { + lua_State *L = ls->L; + char buff[MAXSRC]; + luaO_chunkid(buff, getstr(ls->source), MAXSRC); + luaO_pushfstring(L, "%s:%d: %s near `%s'", buff, line, s, token); + luaD_throw(L, LUA_ERRSYNTAX); +} + + +static void luaX_error (LexState *ls, const char *s, const char *token) { + luaX_errorline(ls, s, token, ls->linenumber); +} + + +void luaX_syntaxerror (LexState *ls, const char *msg) { + const char *lasttoken; + switch (ls->t.token) { + case TK_NAME: + lasttoken = getstr(ls->t.seminfo.ts); + break; + case TK_STRING: + case TK_NUMBER: + lasttoken = luaZ_buffer(ls->buff); + break; + default: + lasttoken = luaX_token2str(ls, ls->t.token); + break; + } + luaX_error(ls, msg, lasttoken); +} + + +const char *luaX_token2str (LexState *ls, int token) { + if (token < FIRST_RESERVED) { + lua_assert(token == (unsigned char)token); + return luaO_pushfstring(ls->L, "%c", token); + } + else + return token2string[token-FIRST_RESERVED]; +} + + +static void luaX_lexerror (LexState *ls, const char *s, int token) { + if (token == TK_EOS) + luaX_error(ls, s, luaX_token2str(ls, token)); + else + luaX_error(ls, s, luaZ_buffer(ls->buff)); +} + + +static void inclinenumber (LexState *LS) { + next(LS); /* skip `\n' */ + ++LS->linenumber; + luaX_checklimit(LS, LS->linenumber, MAX_INT, "lines in a chunk"); +} + + +void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) { + LS->L = L; + LS->lookahead.token = TK_EOS; /* no look-ahead token */ + LS->z = z; + LS->fs = NULL; + LS->linenumber = 1; + LS->lastline = 1; + LS->source = source; + next(LS); /* read first char */ + if (LS->current == '#') { + do { /* skip first line */ + next(LS); + } while (LS->current != '\n' && LS->current != EOZ); + } +} + + + +/* +** ======================================================= +** LEXICAL ANALYZER +** ======================================================= +*/ + + +/* use buffer to store names, literal strings and numbers */ + +/* extra space to allocate when growing buffer */ +#define EXTRABUFF 32 + +/* maximum number of chars that can be read without checking buffer size */ +#define MAXNOCHECK 5 + +#define checkbuffer(LS, len) \ + if (((len)+MAXNOCHECK)*sizeof(char) > luaZ_sizebuffer((LS)->buff)) \ + luaZ_openspace((LS)->L, (LS)->buff, (len)+EXTRABUFF) + +#define save(LS, c, l) \ + (luaZ_buffer((LS)->buff)[l++] = cast(char, c)) +#define save_and_next(LS, l) (save(LS, LS->current, l), next(LS)) + + +static size_t readname (LexState *LS) { + size_t l = 0; + checkbuffer(LS, l); + do { + checkbuffer(LS, l); + save_and_next(LS, l); + } while (isalnum(LS->current) || LS->current == '_'); + save(LS, '\0', l); + return l-1; +} + + +/* LUA_NUMBER */ +static void read_numeral (LexState *LS, int comma, SemInfo *seminfo) { + size_t l = 0; + checkbuffer(LS, l); + if (comma) save(LS, '.', l); + while (isdigit(LS->current)) { + checkbuffer(LS, l); + save_and_next(LS, l); + } + if (LS->current == '.') { + save_and_next(LS, l); + if (LS->current == '.') { + save_and_next(LS, l); + save(LS, '\0', l); + luaX_lexerror(LS, + "ambiguous syntax (decimal point x string concatenation)", + TK_NUMBER); + } + } + while (isdigit(LS->current)) { + checkbuffer(LS, l); + save_and_next(LS, l); + } + if (LS->current == 'e' || LS->current == 'E') { + save_and_next(LS, l); /* read `E' */ + if (LS->current == '+' || LS->current == '-') + save_and_next(LS, l); /* optional exponent sign */ + while (isdigit(LS->current)) { + checkbuffer(LS, l); + save_and_next(LS, l); + } + } + save(LS, '\0', l); + if (!luaO_str2d(luaZ_buffer(LS->buff), &seminfo->r)) + luaX_lexerror(LS, "malformed number", TK_NUMBER); +} + + +static void read_long_string (LexState *LS, SemInfo *seminfo) { + int cont = 0; + size_t l = 0; + checkbuffer(LS, l); + save(LS, '[', l); /* save first `[' */ + save_and_next(LS, l); /* pass the second `[' */ + if (LS->current == '\n') /* string starts with a newline? */ + inclinenumber(LS); /* skip it */ + for (;;) { + checkbuffer(LS, l); + switch (LS->current) { + case EOZ: + save(LS, '\0', l); + luaX_lexerror(LS, (seminfo) ? "unfinished long string" : + "unfinished long comment", TK_EOS); + break; /* to avoid warnings */ + case '[': + save_and_next(LS, l); + if (LS->current == '[') { + cont++; + save_and_next(LS, l); + } + continue; + case ']': + save_and_next(LS, l); + if (LS->current == ']') { + if (cont == 0) goto endloop; + cont--; + save_and_next(LS, l); + } + continue; + case '\n': + save(LS, '\n', l); + inclinenumber(LS); + if (!seminfo) l = 0; /* reset buffer to avoid wasting space */ + continue; + default: + save_and_next(LS, l); + } + } endloop: + save_and_next(LS, l); /* skip the second `]' */ + save(LS, '\0', l); + if (seminfo) + seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 2, l - 5); +} + + +static void read_string (LexState *LS, int del, SemInfo *seminfo) { + size_t l = 0; + checkbuffer(LS, l); + save_and_next(LS, l); + while (LS->current != del) { + checkbuffer(LS, l); + switch (LS->current) { + case EOZ: + save(LS, '\0', l); + luaX_lexerror(LS, "unfinished string", TK_EOS); + break; /* to avoid warnings */ + case '\n': + save(LS, '\0', l); + luaX_lexerror(LS, "unfinished string", TK_STRING); + break; /* to avoid warnings */ + case '\\': + next(LS); /* do not save the `\' */ + switch (LS->current) { + case 'a': save(LS, '\a', l); next(LS); break; + case 'b': save(LS, '\b', l); next(LS); break; + case 'f': save(LS, '\f', l); next(LS); break; + case 'n': save(LS, '\n', l); next(LS); break; + case 'r': save(LS, '\r', l); next(LS); break; + case 't': save(LS, '\t', l); next(LS); break; + case 'v': save(LS, '\v', l); next(LS); break; + case '\n': save(LS, '\n', l); inclinenumber(LS); break; + case EOZ: break; /* will raise an error next loop */ + default: { + if (!isdigit(LS->current)) + save_and_next(LS, l); /* handles \\, \", \', and \? */ + else { /* \xxx */ + int c = 0; + int i = 0; + do { + c = 10*c + (LS->current-'0'); + next(LS); + } while (++i<3 && isdigit(LS->current)); + if (c > UCHAR_MAX) { + save(LS, '\0', l); + luaX_lexerror(LS, "escape sequence too large", TK_STRING); + } + save(LS, c, l); + } + } + } + break; + default: + save_and_next(LS, l); + } + } + save_and_next(LS, l); /* skip delimiter */ + save(LS, '\0', l); + seminfo->ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff) + 1, l - 3); +} + + +int luaX_lex (LexState *LS, SemInfo *seminfo) { + for (;;) { + switch (LS->current) { + + case '\n': { + inclinenumber(LS); + continue; + } + case '-': { + next(LS); + if (LS->current != '-') return '-'; + /* else is a comment */ + next(LS); + if (LS->current == '[' && (next(LS), LS->current == '[')) + read_long_string(LS, NULL); /* long comment */ + else /* short comment */ + while (LS->current != '\n' && LS->current != EOZ) + next(LS); + continue; + } + case '[': { + next(LS); + if (LS->current != '[') return '['; + else { + read_long_string(LS, seminfo); + return TK_STRING; + } + } + case '=': { + next(LS); + if (LS->current != '=') return '='; + else { next(LS); return TK_EQ; } + } + case '<': { + next(LS); + if (LS->current != '=') return '<'; + else { next(LS); return TK_LE; } + } + case '>': { + next(LS); + if (LS->current != '=') return '>'; + else { next(LS); return TK_GE; } + } + case '~': { + next(LS); + if (LS->current != '=') return '~'; + else { next(LS); return TK_NE; } + } + case '"': + case '\'': { + read_string(LS, LS->current, seminfo); + return TK_STRING; + } + case '.': { + next(LS); + if (LS->current == '.') { + next(LS); + if (LS->current == '.') { + next(LS); + return TK_DOTS; /* ... */ + } + else return TK_CONCAT; /* .. */ + } + else if (!isdigit(LS->current)) return '.'; + else { + read_numeral(LS, 1, seminfo); + return TK_NUMBER; + } + } + case EOZ: { + return TK_EOS; + } + default: { + if (isspace(LS->current)) { + next(LS); + continue; + } + else if (isdigit(LS->current)) { + read_numeral(LS, 0, seminfo); + return TK_NUMBER; + } + else if (isalpha(LS->current) || LS->current == '_') { + /* identifier or reserved word */ + size_t l = readname(LS); + TString *ts = luaS_newlstr(LS->L, luaZ_buffer(LS->buff), l); + if (ts->tsv.reserved > 0) /* reserved word? */ + return ts->tsv.reserved - 1 + FIRST_RESERVED; + seminfo->ts = ts; + return TK_NAME; + } + else { + int c = LS->current; + if (iscntrl(c)) + luaX_error(LS, "invalid control char", + luaO_pushfstring(LS->L, "char(%d)", c)); + next(LS); + return c; /* single-char tokens (+ - / ...) */ + } + } + } + } +} + +#undef next diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/llex.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/llex.h new file mode 100644 index 0000000000..740e3f6b31 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/llex.h @@ -0,0 +1,75 @@ +/* +** $Id: llex.h,v 1.47 2003/02/28 17:19:47 roberto Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + +#ifndef llex_h +#define llex_h + +#include "lobject.h" +#include "lzio.h" + + +#define FIRST_RESERVED 257 + +/* maximum length of a reserved word */ +#define TOKEN_LEN (sizeof("function")/sizeof(char)) + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER RESERVED" +*/ +enum RESERVED { + /* terminal symbols denoted by reserved words */ + TK_AND = FIRST_RESERVED, TK_BREAK, + TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, + TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, + TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, + /* other terminal symbols */ + TK_NAME, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, + TK_STRING, TK_EOS +}; + +/* number of reserved words */ +#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) + + +typedef union { + lua_Number r; + TString *ts; +} SemInfo; /* semantics information */ + + +typedef struct Token { + int token; + SemInfo seminfo; +} Token; + + +typedef struct LexState { + int current; /* current character (charint) */ + int linenumber; /* input line counter */ + int lastline; /* line of last token `consumed' */ + Token t; /* current token */ + Token lookahead; /* look ahead token */ + struct FuncState *fs; /* `FuncState' is private to the parser */ + struct lua_State *L; + ZIO *z; /* input stream */ + Mbuffer *buff; /* buffer for tokens */ + TString *source; /* current source name */ + int nestlevel; /* level of nested non-terminals */ +} LexState; + + +void luaX_init (lua_State *L); +void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source); +int luaX_lex (LexState *LS, SemInfo *seminfo); +void luaX_checklimit (LexState *ls, int val, int limit, const char *msg); +void luaX_syntaxerror (LexState *ls, const char *s); +void luaX_errorline (LexState *ls, const char *s, const char *token, int line); +const char *luaX_token2str (LexState *ls, int token); + + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/llimits.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/llimits.h new file mode 100644 index 0000000000..343c922612 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/llimits.h @@ -0,0 +1,185 @@ +/* +** $Id: llimits.h,v 1.52 2003/02/20 19:33:23 roberto Exp $ +** Limits, basic types, and some other `installation-dependent' definitions +** See Copyright Notice in lua.h +*/ + +#ifndef llimits_h +#define llimits_h + + +#include +#include + + +#include "lua.h" + + +/* +** try to find number of bits in an integer +*/ +#ifndef BITS_INT +/* avoid overflows in comparison */ +#if INT_MAX-20 < 32760 +#define BITS_INT 16 +#else +#if INT_MAX > 2147483640L +/* machine has at least 32 bits */ +#define BITS_INT 32 +#else +#error "you must define BITS_INT with number of bits in an integer" +#endif +#endif +#endif + + +/* +** the following types define integer types for values that may not +** fit in a `small int' (16 bits), but may waste space in a +** `large long' (64 bits). The current definitions should work in +** any machine, but may not be optimal. +*/ + +/* an unsigned integer to hold hash values */ +typedef unsigned int lu_hash; +/* its signed equivalent */ +typedef int ls_hash; + +/* an unsigned integer big enough to count the total memory used by Lua; */ +/* it should be at least as large as size_t */ +typedef unsigned long lu_mem; + +#define MAX_LUMEM ULONG_MAX + + +/* an integer big enough to count the number of strings in use */ +typedef long ls_nstr; + +/* chars used as small naturals (so that `char' is reserved for characters) */ +typedef unsigned char lu_byte; + + +#define MAX_SIZET ((size_t)(~(size_t)0)-2) + + +#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ + +/* +** conversion of pointer to integer +** this is for hashing only; there is no problem if the integer +** cannot hold the whole pointer value +*/ +#define IntPoint(p) ((lu_hash)(p)) + + + +/* type to ensure maximum alignment */ +#ifndef LUSER_ALIGNMENT_T +typedef union { double u; void *s; long l; } L_Umaxalign; +#else +typedef LUSER_ALIGNMENT_T L_Umaxalign; +#endif + + +/* result of `usual argument conversion' over lua_Number */ +#ifndef LUA_UACNUMBER +typedef double l_uacNumber; +#else +typedef LUA_UACNUMBER l_uacNumber; +#endif + + +#ifndef lua_assert +#define lua_assert(c) /* empty */ +#endif + + +#ifndef check_exp +#define check_exp(c,e) (e) +#endif + + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) /* to avoid warnings */ +#endif + + +#ifndef cast +#define cast(t, exp) ((t)(exp)) +#endif + + + +/* +** type for virtual-machine instructions +** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) +*/ +typedef unsigned long Instruction; + + +/* maximum depth for calls (unsigned short) */ +#ifndef LUA_MAXCALLS +#define LUA_MAXCALLS 4096 +#endif + + +/* +** maximum depth for C calls (unsigned short): Not too big, or may +** overflow the C stack... +*/ + +#ifndef LUA_MAXCCALLS +#define LUA_MAXCCALLS 200 +#endif + + +/* maximum size for the C stack */ +#ifndef LUA_MAXCSTACK +#define LUA_MAXCSTACK 2048 +#endif + + +/* maximum stack for a Lua function */ +#define MAXSTACK 250 + + +/* maximum number of variables declared in a function */ +#ifndef MAXVARS +#define MAXVARS 200 /* arbitrary limit ( +#include + +#define lmathlib_c + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#undef PI +#define PI (3.14159265358979323846) +#define RADIANS_PER_DEGREE (PI/180.0) + + + +/* +** If you want Lua to operate in degrees (instead of radians), +** define USE_DEGREES +*/ +#ifdef USE_DEGREES +#define FROMRAD(a) ((a)/RADIANS_PER_DEGREE) +#define TORAD(a) ((a)*RADIANS_PER_DEGREE) +#else +#define FROMRAD(a) (a) +#define TORAD(a) (a) +#endif + + +static int math_abs (lua_State *L) { + lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sin (lua_State *L) { + lua_pushnumber(L, sin(TORAD(luaL_checknumber(L, 1)))); + return 1; +} + +static int math_cos (lua_State *L) { + lua_pushnumber(L, cos(TORAD(luaL_checknumber(L, 1)))); + return 1; +} + +static int math_tan (lua_State *L) { + lua_pushnumber(L, tan(TORAD(luaL_checknumber(L, 1)))); + return 1; +} + +static int math_asin (lua_State *L) { + lua_pushnumber(L, FROMRAD(asin(luaL_checknumber(L, 1)))); + return 1; +} + +static int math_acos (lua_State *L) { + lua_pushnumber(L, FROMRAD(acos(luaL_checknumber(L, 1)))); + return 1; +} + +static int math_atan (lua_State *L) { + lua_pushnumber(L, FROMRAD(atan(luaL_checknumber(L, 1)))); + return 1; +} + +static int math_atan2 (lua_State *L) { + lua_pushnumber(L, FROMRAD(atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2)))); + return 1; +} + +static int math_ceil (lua_State *L) { + lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); + return 1; +} + +static int math_floor (lua_State *L) { + lua_pushnumber(L, floor(luaL_checknumber(L, 1))); + return 1; +} + +static int math_mod (lua_State *L) { + lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_sqrt (lua_State *L) { + lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); + return 1; +} + +static int math_pow (lua_State *L) { + lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_log (lua_State *L) { + lua_pushnumber(L, log(luaL_checknumber(L, 1))); + return 1; +} + +static int math_log10 (lua_State *L) { + lua_pushnumber(L, log10(luaL_checknumber(L, 1))); + return 1; +} + +static int math_exp (lua_State *L) { + lua_pushnumber(L, exp(luaL_checknumber(L, 1))); + return 1; +} + +static int math_deg (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); + return 1; +} + +static int math_rad (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); + return 1; +} + +static int math_frexp (lua_State *L) { + int e; + lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); + lua_pushnumber(L, e); + return 2; +} + +static int math_ldexp (lua_State *L) { + lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2))); + return 1; +} + + + +static int math_min (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmin = luaL_checknumber(L, 1); + int i; + for (i=2; i<=n; i++) { + lua_Number d = luaL_checknumber(L, i); + if (d < dmin) + dmin = d; + } + lua_pushnumber(L, dmin); + return 1; +} + + +static int math_max (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmax = luaL_checknumber(L, 1); + int i; + for (i=2; i<=n; i++) { + lua_Number d = luaL_checknumber(L, i); + if (d > dmax) + dmax = d; + } + lua_pushnumber(L, dmax); + return 1; +} + + +static int math_random (lua_State *L) { + /* the `%' avoids the (rare) case of r==1, and is needed also because on + some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ + lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; + switch (lua_gettop(L)) { /* check number of arguments */ + case 0: { /* no arguments */ + lua_pushnumber(L, r); /* Number between 0 and 1 */ + break; + } + case 1: { /* only upper limit */ + int u = luaL_checkint(L, 1); + luaL_argcheck(L, 1<=u, 1, "interval is empty"); + lua_pushnumber(L, (int)floor(r*u)+1); /* int between 1 and `u' */ + break; + } + case 2: { /* lower and upper limits */ + int l = luaL_checkint(L, 1); + int u = luaL_checkint(L, 2); + luaL_argcheck(L, l<=u, 2, "interval is empty"); + lua_pushnumber(L, (int)floor(r*(u-l+1))+l); /* int between `l' and `u' */ + break; + } + default: return luaL_error(L, "wrong number of arguments"); + } + return 1; +} + + +static int math_randomseed (lua_State *L) { + srand(luaL_checkint(L, 1)); + return 0; +} + + +static const luaL_reg mathlib[] = { + {"abs", math_abs}, + {"sin", math_sin}, + {"cos", math_cos}, + {"tan", math_tan}, + {"asin", math_asin}, + {"acos", math_acos}, + {"atan", math_atan}, + {"atan2", math_atan2}, + {"ceil", math_ceil}, + {"floor", math_floor}, + {"mod", math_mod}, + {"frexp", math_frexp}, + {"ldexp", math_ldexp}, + {"sqrt", math_sqrt}, + {"min", math_min}, + {"max", math_max}, + {"log", math_log}, + {"log10", math_log10}, + {"exp", math_exp}, + {"deg", math_deg}, + {"pow", math_pow}, + {"rad", math_rad}, + {"random", math_random}, + {"randomseed", math_randomseed}, + {NULL, NULL} +}; + + +/* +** Open math library +*/ +LUALIB_API int luaopen_math (lua_State *L) { + luaL_openlib(L, LUA_MATHLIBNAME, mathlib, 0); + lua_pushliteral(L, "pi"); + lua_pushnumber(L, PI); + lua_settable(L, -3); + lua_pushliteral(L, "__pow"); + lua_pushcfunction(L, math_pow); + lua_settable(L, LUA_GLOBALSINDEX); + return 1; +} + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lmem.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/lmem.c new file mode 100644 index 0000000000..f977770af0 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lmem.c @@ -0,0 +1,91 @@ +/* +** $Id: lmem.c,v 1.61 2002/12/04 17:38:31 roberto Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + + +#include + +#define lmem_c + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +/* +** definition for realloc function. It must assure that l_realloc(NULL, +** 0, x) allocates a new block (ANSI C assures that). (`os' is the old +** block size; some allocators may use that.) +*/ +#ifndef l_realloc +#define l_realloc(b,os,s) realloc(b,s) +#endif + +/* +** definition for free function. (`os' is the old block size; some +** allocators may use that.) +*/ +#ifndef l_free +#define l_free(b,os) free(b) +#endif + + +#define MINSIZEARRAY 4 + + +void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems, + int limit, const char *errormsg) { + void *newblock; + int newsize = (*size)*2; + if (newsize < MINSIZEARRAY) + newsize = MINSIZEARRAY; /* minimum size */ + else if (*size >= limit/2) { /* cannot double it? */ + if (*size < limit - MINSIZEARRAY) /* try something smaller... */ + newsize = limit; /* still have at least MINSIZEARRAY free places */ + else luaG_runerror(L, errormsg); + } + newblock = luaM_realloc(L, block, + cast(lu_mem, *size)*cast(lu_mem, size_elems), + cast(lu_mem, newsize)*cast(lu_mem, size_elems)); + *size = newsize; /* update only when everything else is OK */ + return newblock; +} + + +/* +** generic allocation routine. +*/ +void *luaM_realloc (lua_State *L, void *block, lu_mem oldsize, lu_mem size) { + lua_assert((oldsize == 0) == (block == NULL)); + if (size == 0) { + if (block != NULL) { + l_free(block, oldsize); + block = NULL; + } + else return NULL; /* avoid `nblocks' computations when oldsize==size==0 */ + } + else if (size >= MAX_SIZET) + luaG_runerror(L, "memory allocation error: block too big"); + else { + block = l_realloc(block, oldsize, size); + if (block == NULL) { + if (L) + luaD_throw(L, LUA_ERRMEM); + else return NULL; /* error before creating state! */ + } + } + if (L) { + lua_assert(G(L) != NULL && G(L)->nblocks > 0); + G(L)->nblocks -= oldsize; + G(L)->nblocks += size; + } + return block; +} + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lmem.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/lmem.h new file mode 100644 index 0000000000..1bb4fde0b2 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lmem.h @@ -0,0 +1,44 @@ +/* +** $Id: lmem.h,v 1.26 2002/05/01 20:40:42 roberto Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + +#ifndef lmem_h +#define lmem_h + + +#include + +#include "llimits.h" +#include "lua.h" + +#define MEMERRMSG "not enough memory" + + +void *luaM_realloc (lua_State *L, void *oldblock, lu_mem oldsize, lu_mem size); + +void *luaM_growaux (lua_State *L, void *block, int *size, int size_elem, + int limit, const char *errormsg); + +#define luaM_free(L, b, s) luaM_realloc(L, (b), (s), 0) +#define luaM_freelem(L, b) luaM_realloc(L, (b), sizeof(*(b)), 0) +#define luaM_freearray(L, b, n, t) luaM_realloc(L, (b), \ + cast(lu_mem, n)*cast(lu_mem, sizeof(t)), 0) + +#define luaM_malloc(L, t) luaM_realloc(L, NULL, 0, (t)) +#define luaM_new(L, t) cast(t *, luaM_malloc(L, sizeof(t))) +#define luaM_newvector(L, n,t) cast(t *, luaM_malloc(L, \ + cast(lu_mem, n)*cast(lu_mem, sizeof(t)))) + +#define luaM_growvector(L,v,nelems,size,t,limit,e) \ + if (((nelems)+1) > (size)) \ + ((v)=cast(t *, luaM_growaux(L,v,&(size),sizeof(t),limit,e))) + +#define luaM_reallocvector(L, v,oldn,n,t) \ + ((v)=cast(t *, luaM_realloc(L, v,cast(lu_mem, oldn)*cast(lu_mem, sizeof(t)), \ + cast(lu_mem, n)*cast(lu_mem, sizeof(t))))) + + +#endif + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/loadlib.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/loadlib.c new file mode 100644 index 0000000000..ac4d697a68 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/loadlib.c @@ -0,0 +1,205 @@ +/* +** $Id: loadlib.c,v 1.4 2003/04/07 20:11:53 roberto Exp $ +** Dynamic library loader for Lua +** See Copyright Notice in lua.h +* +* This Lua library exports a single function, called loadlib, which is +* called from Lua as loadlib(lib,init), where lib is the full name of the +* library to be loaded (including the complete path) and init is the name +* of a function to be called after the library is loaded. Typically, this +* function will register other functions, thus making the complete library +* available to Lua. The init function is *not* automatically called by +* loadlib. Instead, loadlib returns the init function as a Lua function +* that the client can call when it thinks is appropriate. In the case of +* errors, loadlib returns nil and two strings describing the error. +* The first string is supplied by the operating system; it should be +* informative and useful for error messages. The second string is "open", +* "init", or "absent" to identify the error and is meant to be used for +* making decisions without having to look into the first string (whose +* format is system-dependent). +* +* This module contains an implementation of loadlib for Unix systems that +* have dlfcn, an implementation for Windows, and a stub for other systems. +* See the list at the end of this file for some links to available +* implementations of dlfcn and interfaces to other native dynamic loaders +* on top of which loadlib could be implemented. +* +*/ + +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" + + +#undef LOADLIB + + +#ifdef USE_DLOPEN +#define LOADLIB +/* +* This is an implementation of loadlib based on the dlfcn interface. +* The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, +* NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least +* as an emulation layer on top of native functions. +*/ + +#include + +static int loadlib(lua_State *L) +{ + const char *path=luaL_checkstring(L,1); + const char *init=luaL_checkstring(L,2); + void *lib=dlopen(path,RTLD_NOW); + if (lib!=NULL) + { + lua_CFunction f=(lua_CFunction) dlsym(lib,init); + if (f!=NULL) + { + lua_pushlightuserdata(L,lib); + lua_pushcclosure(L,f,1); + return 1; + } + } + /* else return appropriate error messages */ + lua_pushnil(L); + lua_pushstring(L,dlerror()); + lua_pushstring(L,(lib!=NULL) ? "init" : "open"); + if (lib!=NULL) dlclose(lib); + return 3; +} + +#endif + + + +/* +** In Windows, default is to use dll; otherwise, default is not to use dll +*/ +#ifndef USE_DLL +#ifdef _WIN32 +#define USE_DLL 1 +#else +#define USE_DLL 0 +#endif +#endif + + +#if USE_DLL +#define LOADLIB +/* +* This is an implementation of loadlib for Windows using native functions. +*/ + +#include + +static void pusherror(lua_State *L) +{ + int error=GetLastError(); + char buffer[128]; + if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, + 0, error, 0, buffer, sizeof(buffer), 0)) + lua_pushstring(L,buffer); + else + lua_pushfstring(L,"system error %d\n",error); +} + +static int loadlib(lua_State *L) +{ + const char *path=luaL_checkstring(L,1); + const char *init=luaL_checkstring(L,2); + HINSTANCE lib=LoadLibrary(path); + if (lib!=NULL) + { + lua_CFunction f=(lua_CFunction) GetProcAddress(lib,init); + if (f!=NULL) + { + lua_pushlightuserdata(L,lib); + lua_pushcclosure(L,f,1); + return 1; + } + } + lua_pushnil(L); + pusherror(L); + lua_pushstring(L,(lib!=NULL) ? "init" : "open"); + if (lib!=NULL) FreeLibrary(lib); + return 3; +} + +#endif + + + +#ifndef LOADLIB +/* Fallback for other systems */ + +/* +** Those systems support dlopen, so they should have defined USE_DLOPEN. +** The default (no)implementation gives them a special error message. +*/ +#ifdef linux +#define LOADLIB +#endif + +#ifdef sun +#define LOADLIB +#endif + +#ifdef sgi +#define LOADLIB +#endif + +#ifdef BSD +#define LOADLIB +#endif + +#ifdef _WIN32 +#define LOADLIB +#endif + +#ifdef LOADLIB +#undef LOADLIB +#define LOADLIB "`loadlib' not installed (check your Lua configuration)" +#else +#define LOADLIB "`loadlib' not supported" +#endif + +static int loadlib(lua_State *L) +{ + lua_pushnil(L); + lua_pushliteral(L,LOADLIB); + lua_pushliteral(L,"absent"); + return 3; +} +#endif + +LUALIB_API int luaopen_loadlib (lua_State *L) +{ + lua_register(L,"loadlib",loadlib); + return 0; +} + +/* +* Here are some links to available implementations of dlfcn and +* interfaces to other native dynamic loaders on top of which loadlib +* could be implemented. Please send contributions and corrections to us. +* +* AIX +* Starting with AIX 4.2, dlfcn is included in the base OS. +* There is also an emulation package available. +* http://www.faqs.org/faqs/aix-faq/part4/section-21.html +* +* HPUX +* HPUX 11 has dlfcn. For HPUX 10 use shl_*. +* http://www.geda.seul.org/mailinglist/geda-dev37/msg00094.html +* http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html +* +* Macintosh, Windows +* http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html +* +* Mac OS X/Darwin +* http://www.opendarwin.org/projects/dlcompat/ +* +* GLIB has wrapper code for BeOS, OS2, Unix and Windows +* http://cvs.gnome.org/lxr/source/glib/gmodule/ +* +*/ diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lobject.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/lobject.c new file mode 100644 index 0000000000..9522b6e812 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lobject.c @@ -0,0 +1,195 @@ +/* +** $Id: lobject.c,v 1.97 2003/04/03 13:35:34 roberto Exp $ +** Some generic functions over Lua objects +** See Copyright Notice in lua.h +*/ + +#include +#include +#include +#include + +#define lobject_c + +#include "lua.h" + +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "lvm.h" + + +/* function to convert a string to a lua_Number */ +#ifndef lua_str2number +#define lua_str2number(s,p) strtod((s), (p)) +#endif + + +const TObject luaO_nilobject = {LUA_TNIL, {NULL}}; + + +/* +** converts an integer to a "floating point byte", represented as +** (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm) +*/ +int luaO_int2fb (unsigned int x) { + int m = 0; /* mantissa */ + while (x >= (1<<3)) { + x = (x+1) >> 1; + m++; + } + return (m << 3) | cast(int, x); +} + + +int luaO_log2 (unsigned int x) { + static const lu_byte log_8[255] = { + 0, + 1,1, + 2,2,2,2, + 3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 + }; + if (x >= 0x00010000) { + if (x >= 0x01000000) return log_8[((x>>24) & 0xff) - 1]+24; + else return log_8[((x>>16) & 0xff) - 1]+16; + } + else { + if (x >= 0x00000100) return log_8[((x>>8) & 0xff) - 1]+8; + else if (x) return log_8[(x & 0xff) - 1]; + return -1; /* special `log' for 0 */ + } +} + + +int luaO_rawequalObj (const TObject *t1, const TObject *t2) { + if (ttype(t1) != ttype(t2)) return 0; + else switch (ttype(t1)) { + case LUA_TNIL: + return 1; + case LUA_TNUMBER: + return nvalue(t1) == nvalue(t2); + case LUA_TBOOLEAN: + return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ + case LUA_TLIGHTUSERDATA: + return pvalue(t1) == pvalue(t2); + default: + lua_assert(iscollectable(t1)); + return gcvalue(t1) == gcvalue(t2); + } +} + + +int luaO_str2d (const char *s, lua_Number *result) { + char *endptr; + lua_Number res = lua_str2number(s, &endptr); + if (endptr == s) return 0; /* no conversion */ + while (isspace((unsigned char)(*endptr))) endptr++; + if (*endptr != '\0') return 0; /* invalid trailing characters? */ + *result = res; + return 1; +} + + + +static void pushstr (lua_State *L, const char *str) { + setsvalue2s(L->top, luaS_new(L, str)); + incr_top(L); +} + + +/* this function handles only `%d', `%c', %f, and `%s' formats */ +const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { + int n = 1; + pushstr(L, ""); + for (;;) { + const char *e = strchr(fmt, '%'); + if (e == NULL) break; + setsvalue2s(L->top, luaS_newlstr(L, fmt, e-fmt)); + incr_top(L); + switch (*(e+1)) { + case 's': + pushstr(L, va_arg(argp, char *)); + break; + case 'c': { + char buff[2]; + buff[0] = cast(char, va_arg(argp, int)); + buff[1] = '\0'; + pushstr(L, buff); + break; + } + case 'd': + setnvalue(L->top, cast(lua_Number, va_arg(argp, int))); + incr_top(L); + break; + case 'f': + setnvalue(L->top, cast(lua_Number, va_arg(argp, l_uacNumber))); + incr_top(L); + break; + case '%': + pushstr(L, "%"); + break; + default: lua_assert(0); + } + n += 2; + fmt = e+2; + } + pushstr(L, fmt); + luaV_concat(L, n+1, L->top - L->base - 1); + L->top -= n; + return svalue(L->top - 1); +} + + +const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { + const char *msg; + va_list argp; + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + return msg; +} + + +void luaO_chunkid (char *out, const char *source, int bufflen) { + if (*source == '=') { + strncpy(out, source+1, bufflen); /* remove first char */ + out[bufflen-1] = '\0'; /* ensures null termination */ + } + else { /* out = "source", or "...source" */ + if (*source == '@') { + int l; + source++; /* skip the `@' */ + bufflen -= sizeof(" `...' "); + l = strlen(source); + strcpy(out, ""); + if (l>bufflen) { + source += (l-bufflen); /* get last part of file name */ + strcat(out, "..."); + } + strcat(out, source); + } + else { /* out = [string "string"] */ + int len = strcspn(source, "\n"); /* stop at first newline */ + bufflen -= sizeof(" [string \"...\"] "); + if (len > bufflen) len = bufflen; + strcpy(out, "[string \""); + if (source[len] != '\0') { /* must truncate? */ + strncat(out, source, len); + strcat(out, "..."); + } + else + strcat(out, source); + strcat(out, "\"]"); + } + } +} diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lobject.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/lobject.h new file mode 100644 index 0000000000..321a7e06c1 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lobject.h @@ -0,0 +1,336 @@ +/* +** $Id: lobject.h,v 1.159 2003/03/18 12:50:04 roberto Exp $ +** Type definitions for Lua objects +** See Copyright Notice in lua.h +*/ + +#ifndef lobject_h +#define lobject_h + + +#include "llimits.h" +#include "lua.h" + + +/* tags for values visible from Lua */ +#define NUM_TAGS LUA_TTHREAD + + +/* +** Extra tags for non-values +*/ +#define LUA_TPROTO (NUM_TAGS+1) +#define LUA_TUPVAL (NUM_TAGS+2) + + +/* +** Union of all collectable objects +*/ +typedef union GCObject GCObject; + + +/* +** Common Header for all collectable objects (in macro form, to be +** included in other objects) +*/ +#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked + + +/* +** Common header in struct form +*/ +typedef struct GCheader { + CommonHeader; +} GCheader; + + + + +/* +** Union of all Lua values +*/ +typedef union { + GCObject *gc; + void *p; + lua_Number n; + int b; +} Value; + + +/* +** Lua values (or `tagged objects') +*/ +typedef struct lua_TObject { + int tt; + Value value; +} TObject; + + +/* Macros to test type */ +#define ttisnil(o) (ttype(o) == LUA_TNIL) +#define ttisnumber(o) (ttype(o) == LUA_TNUMBER) +#define ttisstring(o) (ttype(o) == LUA_TSTRING) +#define ttistable(o) (ttype(o) == LUA_TTABLE) +#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) +#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) +#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) +#define ttisthread(o) (ttype(o) == LUA_TTHREAD) +#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) + +/* Macros to access values */ +#define ttype(o) ((o)->tt) +#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc) +#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) +#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n) +#define tsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts) +#define uvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u) +#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl) +#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h) +#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b) +#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th) + +#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) + +/* Macros to set values */ +#define setnvalue(obj,x) \ + { TObject *i_o=(obj); i_o->tt=LUA_TNUMBER; i_o->value.n=(x); } + +#define chgnvalue(obj,x) \ + check_exp(ttype(obj)==LUA_TNUMBER, (obj)->value.n=(x)) + +#define setpvalue(obj,x) \ + { TObject *i_o=(obj); i_o->tt=LUA_TLIGHTUSERDATA; i_o->value.p=(x); } + +#define setbvalue(obj,x) \ + { TObject *i_o=(obj); i_o->tt=LUA_TBOOLEAN; i_o->value.b=(x); } + +#define setsvalue(obj,x) \ + { TObject *i_o=(obj); i_o->tt=LUA_TSTRING; \ + i_o->value.gc=cast(GCObject *, (x)); \ + lua_assert(i_o->value.gc->gch.tt == LUA_TSTRING); } + +#define setuvalue(obj,x) \ + { TObject *i_o=(obj); i_o->tt=LUA_TUSERDATA; \ + i_o->value.gc=cast(GCObject *, (x)); \ + lua_assert(i_o->value.gc->gch.tt == LUA_TUSERDATA); } + +#define setthvalue(obj,x) \ + { TObject *i_o=(obj); i_o->tt=LUA_TTHREAD; \ + i_o->value.gc=cast(GCObject *, (x)); \ + lua_assert(i_o->value.gc->gch.tt == LUA_TTHREAD); } + +#define setclvalue(obj,x) \ + { TObject *i_o=(obj); i_o->tt=LUA_TFUNCTION; \ + i_o->value.gc=cast(GCObject *, (x)); \ + lua_assert(i_o->value.gc->gch.tt == LUA_TFUNCTION); } + +#define sethvalue(obj,x) \ + { TObject *i_o=(obj); i_o->tt=LUA_TTABLE; \ + i_o->value.gc=cast(GCObject *, (x)); \ + lua_assert(i_o->value.gc->gch.tt == LUA_TTABLE); } + +#define setnilvalue(obj) ((obj)->tt=LUA_TNIL) + + + +/* +** for internal debug only +*/ +#define checkconsistency(obj) \ + lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt)) + + +#define setobj(obj1,obj2) \ + { const TObject *o2=(obj2); TObject *o1=(obj1); \ + checkconsistency(o2); \ + o1->tt=o2->tt; o1->value = o2->value; } + + +/* +** different types of sets, according to destination +*/ + +/* from stack to (same) stack */ +#define setobjs2s setobj +/* to stack (not from same stack) */ +#define setobj2s setobj +#define setsvalue2s setsvalue +/* from table to same table */ +#define setobjt2t setobj +/* to table */ +#define setobj2t setobj +/* to new object */ +#define setobj2n setobj +#define setsvalue2n setsvalue + +#define setttype(obj, tt) (ttype(obj) = (tt)) + + +#define iscollectable(o) (ttype(o) >= LUA_TSTRING) + + + +typedef TObject *StkId; /* index to stack elements */ + + +/* +** String headers for string table +*/ +typedef union TString { + L_Umaxalign dummy; /* ensures maximum alignment for strings */ + struct { + CommonHeader; + lu_byte reserved; + lu_hash hash; + size_t len; + } tsv; +} TString; + + +#define getstr(ts) cast(const char *, (ts) + 1) +#define svalue(o) getstr(tsvalue(o)) + + + +typedef union Udata { + L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ + struct { + CommonHeader; + struct Table *metatable; + size_t len; + } uv; +} Udata; + + + + +/* +** Function Prototypes +*/ +typedef struct Proto { + CommonHeader; + TObject *k; /* constants used by the function */ + Instruction *code; + struct Proto **p; /* functions defined inside the function */ + int *lineinfo; /* map from opcodes to source lines */ + struct LocVar *locvars; /* information about local variables */ + TString **upvalues; /* upvalue names */ + TString *source; + int sizeupvalues; + int sizek; /* size of `k' */ + int sizecode; + int sizelineinfo; + int sizep; /* size of `p' */ + int sizelocvars; + int lineDefined; + GCObject *gclist; + lu_byte nups; /* number of upvalues */ + lu_byte numparams; + lu_byte is_vararg; + lu_byte maxstacksize; +} Proto; + + +typedef struct LocVar { + TString *varname; + int startpc; /* first point where variable is active */ + int endpc; /* first point where variable is dead */ +} LocVar; + + + +/* +** Upvalues +*/ + +typedef struct UpVal { + CommonHeader; + TObject *v; /* points to stack or to its own value */ + TObject value; /* the value (when closed) */ +} UpVal; + + +/* +** Closures +*/ + +#define ClosureHeader \ + CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist + +typedef struct CClosure { + ClosureHeader; + lua_CFunction f; + TObject upvalue[1]; +} CClosure; + + +typedef struct LClosure { + ClosureHeader; + struct Proto *p; + TObject g; /* global table for this closure */ + UpVal *upvals[1]; +} LClosure; + + +typedef union Closure { + CClosure c; + LClosure l; +} Closure; + + +#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC) +#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC) + + +/* +** Tables +*/ + +typedef struct Node { + TObject i_key; + TObject i_val; + struct Node *next; /* for chaining */ +} Node; + + +typedef struct Table { + CommonHeader; + lu_byte flags; /* 1<

lsizenode)) + + + +extern const TObject luaO_nilobject; + +int luaO_log2 (unsigned int x); +int luaO_int2fb (unsigned int x); +#define fb2int(x) (((x) & 7) << ((x) >> 3)) + +int luaO_rawequalObj (const TObject *t1, const TObject *t2); +int luaO_str2d (const char *s, lua_Number *result); + +const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp); +const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); +void luaO_chunkid (char *out, const char *source, int len); + + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lopcodes.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/lopcodes.c new file mode 100644 index 0000000000..993e426d35 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lopcodes.c @@ -0,0 +1,102 @@ +/* +** $Id: lopcodes.c,v 1.22 2002/12/04 17:38:31 roberto Exp $ +** extracted automatically from lopcodes.h by mkprint.lua +** DO NOT EDIT +** See Copyright Notice in lua.h +*/ + + +#define lopcodes_c + +#include "lua.h" + +#include "lobject.h" +#include "lopcodes.h" + + +#ifdef LUA_OPNAMES + +const char *const luaP_opnames[] = { + "MOVE", + "LOADK", + "LOADBOOL", + "LOADNIL", + "GETUPVAL", + "GETGLOBAL", + "GETTABLE", + "SETGLOBAL", + "SETUPVAL", + "SETTABLE", + "NEWTABLE", + "SELF", + "ADD", + "SUB", + "MUL", + "DIV", + "POW", + "UNM", + "NOT", + "CONCAT", + "JMP", + "EQ", + "LT", + "LE", + "TEST", + "CALL", + "TAILCALL", + "RETURN", + "FORLOOP", + "TFORLOOP", + "TFORPREP", + "SETLIST", + "SETLISTO", + "CLOSE", + "CLOSURE" +}; + +#endif + +#define opmode(t,b,bk,ck,sa,k,m) (((t)<>1) /* `sBx' is signed */ +#else +#define MAXARG_Bx MAX_INT +#define MAXARG_sBx MAX_INT +#endif + + +#define MAXARG_A ((1<>POS_A)) +#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ + ((cast(Instruction, u)<>POS_B) & MASK1(SIZE_B,0))) +#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ + ((cast(Instruction, b)<>POS_C) & MASK1(SIZE_C,0))) +#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \ + ((cast(Instruction, b)<>POS_Bx) & MASK1(SIZE_Bx,0))) +#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \ + ((cast(Instruction, b)< C) then R(A) := R(B) else pc++ */ + +OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ + +OP_FORLOOP,/* A sBx R(A)+=R(A+2); if R(A) =) R(A)*/ +OP_CLOSURE/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ +} OpCode; + + +#define NUM_OPCODES (cast(int, OP_CLOSURE+1)) + + + +/*=========================================================================== + Notes: + (1) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, + and can be 0: OP_CALL then sets `top' to last_result+1, so + next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. + + (2) In OP_RETURN, if (B == 0) then return up to `top' + + (3) For comparisons, B specifies what conditions the test should accept. + + (4) All `skips' (pc++) assume that next instruction is a jump +===========================================================================*/ + + +/* +** masks for instruction properties +*/ +enum OpModeMask { + OpModeBreg = 2, /* B is a register */ + OpModeBrk, /* B is a register/constant */ + OpModeCrk, /* C is a register/constant */ + OpModesetA, /* instruction set register A */ + OpModeK, /* Bx is a constant */ + OpModeT /* operator is a test */ + +}; + + +extern const lu_byte luaP_opmodes[NUM_OPCODES]; + +#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) +#define testOpMode(m, b) (luaP_opmodes[m] & (1 << (b))) + + +#ifdef LUA_OPNAMES +extern const char *const luaP_opnames[]; /* opcode names */ +#endif + + + +/* number of list items to accumulate before a SETLIST instruction */ +/* (must be a power of 2) */ +#define LFIELDS_PER_FLUSH 32 + + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lparser.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/lparser.c new file mode 100644 index 0000000000..c1323ecd2a --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lparser.c @@ -0,0 +1,1329 @@ +/* +** $Id: lparser.c,v 1.208 2003/04/03 13:35:34 roberto Exp $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + + +#include + +#define lparser_c + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "lfunc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" + + + + +#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) + + +#define enterlevel(ls) if (++(ls)->nestlevel > LUA_MAXPARSERLEVEL) \ + luaX_syntaxerror(ls, "too many syntax levels"); +#define leavelevel(ls) ((ls)->nestlevel--) + + +/* +** nodes for block list (list of active blocks) +*/ +typedef struct BlockCnt { + struct BlockCnt *previous; /* chain */ + int breaklist; /* list of jumps out of this loop */ + int nactvar; /* # active local variables outside the breakable structure */ + int upval; /* true if some variable in the block is an upvalue */ + int isbreakable; /* true if `block' is a loop */ +} BlockCnt; + + + +/* +** prototypes for recursive non-terminal functions +*/ +static void chunk (LexState *ls); +static void expr (LexState *ls, expdesc *v); + + + +static void next (LexState *ls) { + ls->lastline = ls->linenumber; + if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ + ls->t = ls->lookahead; /* use this one */ + ls->lookahead.token = TK_EOS; /* and discharge it */ + } + else + ls->t.token = luaX_lex(ls, &ls->t.seminfo); /* read next token */ +} + + +static void lookahead (LexState *ls) { + lua_assert(ls->lookahead.token == TK_EOS); + ls->lookahead.token = luaX_lex(ls, &ls->lookahead.seminfo); +} + + +static void error_expected (LexState *ls, int token) { + luaX_syntaxerror(ls, + luaO_pushfstring(ls->L, "`%s' expected", luaX_token2str(ls, token))); +} + + +static int testnext (LexState *ls, int c) { + if (ls->t.token == c) { + next(ls); + return 1; + } + else return 0; +} + + +static void check (LexState *ls, int c) { + if (!testnext(ls, c)) + error_expected(ls, c); +} + + +#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } + + + +static void check_match (LexState *ls, int what, int who, int where) { + if (!testnext(ls, what)) { + if (where == ls->linenumber) + error_expected(ls, what); + else { + luaX_syntaxerror(ls, luaO_pushfstring(ls->L, + "`%s' expected (to close `%s' at line %d)", + luaX_token2str(ls, what), luaX_token2str(ls, who), where)); + } + } +} + + +static TString *str_checkname (LexState *ls) { + TString *ts; + check_condition(ls, (ls->t.token == TK_NAME), " expected"); + ts = ls->t.seminfo.ts; + next(ls); + return ts; +} + + +static void init_exp (expdesc *e, expkind k, int i) { + e->f = e->t = NO_JUMP; + e->k = k; + e->info = i; +} + + +static void codestring (LexState *ls, expdesc *e, TString *s) { + init_exp(e, VK, luaK_stringK(ls->fs, s)); +} + + +static void checkname(LexState *ls, expdesc *e) { + codestring(ls, e, str_checkname(ls)); +} + + +static int luaI_registerlocalvar (LexState *ls, TString *varname) { + FuncState *fs = ls->fs; + Proto *f = fs->f; + luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, + LocVar, MAX_INT, ""); + f->locvars[fs->nlocvars].varname = varname; + return fs->nlocvars++; +} + + +static void new_localvar (LexState *ls, TString *name, int n) { + FuncState *fs = ls->fs; + luaX_checklimit(ls, fs->nactvar+n+1, MAXVARS, "local variables"); + fs->actvar[fs->nactvar+n] = luaI_registerlocalvar(ls, name); +} + + +static void adjustlocalvars (LexState *ls, int nvars) { + FuncState *fs = ls->fs; + fs->nactvar += nvars; + for (; nvars; nvars--) { + getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; + } +} + + +static void removevars (LexState *ls, int tolevel) { + FuncState *fs = ls->fs; + while (fs->nactvar > tolevel) + getlocvar(fs, --fs->nactvar).endpc = fs->pc; +} + + +static void new_localvarstr (LexState *ls, const char *name, int n) { + new_localvar(ls, luaS_new(ls->L, name), n); +} + + +static void create_local (LexState *ls, const char *name) { + new_localvarstr(ls, name, 0); + adjustlocalvars(ls, 1); +} + + +static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { + int i; + Proto *f = fs->f; + for (i=0; inups; i++) { + if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) { + lua_assert(fs->f->upvalues[i] == name); + return i; + } + } + /* new one */ + luaX_checklimit(fs->ls, f->nups + 1, MAXUPVALUES, "upvalues"); + luaM_growvector(fs->L, fs->f->upvalues, f->nups, fs->f->sizeupvalues, + TString *, MAX_INT, ""); + fs->f->upvalues[f->nups] = name; + fs->upvalues[f->nups] = *v; + return f->nups++; +} + + +static int searchvar (FuncState *fs, TString *n) { + int i; + for (i=fs->nactvar-1; i >= 0; i--) { + if (n == getlocvar(fs, i).varname) + return i; + } + return -1; /* not found */ +} + + +static void markupval (FuncState *fs, int level) { + BlockCnt *bl = fs->bl; + while (bl && bl->nactvar > level) bl = bl->previous; + if (bl) bl->upval = 1; +} + + +static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { + if (fs == NULL) /* no more levels? */ + init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ + else { + int v = searchvar(fs, n); /* look up at current level */ + if (v >= 0) { + init_exp(var, VLOCAL, v); + if (!base) + markupval(fs, v); /* local will be used as an upval */ + } + else { /* not found at current level; try upper one */ + singlevaraux(fs->prev, n, var, 0); + if (var->k == VGLOBAL) { + if (base) + var->info = luaK_stringK(fs, n); /* info points to global name */ + } + else { /* LOCAL or UPVAL */ + var->info = indexupvalue(fs, n, var); + var->k = VUPVAL; /* upvalue in this level */ + } + } + } +} + + +static TString *singlevar (LexState *ls, expdesc *var, int base) { + TString *varname = str_checkname(ls); + singlevaraux(ls->fs, varname, var, base); + return varname; +} + + +static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { + FuncState *fs = ls->fs; + int extra = nvars - nexps; + if (e->k == VCALL) { + extra++; /* includes call itself */ + if (extra <= 0) extra = 0; + else luaK_reserveregs(fs, extra-1); + luaK_setcallreturns(fs, e, extra); /* call provides the difference */ + } + else { + if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ + if (extra > 0) { + int reg = fs->freereg; + luaK_reserveregs(fs, extra); + luaK_nil(fs, reg, extra); + } + } +} + + +static void code_params (LexState *ls, int nparams, int dots) { + FuncState *fs = ls->fs; + adjustlocalvars(ls, nparams); + luaX_checklimit(ls, fs->nactvar, MAXPARAMS, "parameters"); + fs->f->numparams = cast(lu_byte, fs->nactvar); + fs->f->is_vararg = cast(lu_byte, dots); + if (dots) + create_local(ls, "arg"); + luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ +} + + +static void enterblock (FuncState *fs, BlockCnt *bl, int isbreakable) { + bl->breaklist = NO_JUMP; + bl->isbreakable = isbreakable; + bl->nactvar = fs->nactvar; + bl->upval = 0; + bl->previous = fs->bl; + fs->bl = bl; + lua_assert(fs->freereg == fs->nactvar); +} + + +static void leaveblock (FuncState *fs) { + BlockCnt *bl = fs->bl; + fs->bl = bl->previous; + removevars(fs->ls, bl->nactvar); + if (bl->upval) + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); + lua_assert(bl->nactvar == fs->nactvar); + fs->freereg = fs->nactvar; /* free registers */ + luaK_patchtohere(fs, bl->breaklist); +} + + +static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { + FuncState *fs = ls->fs; + Proto *f = fs->f; + int i; + luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, + MAXARG_Bx, "constant table overflow"); + f->p[fs->np++] = func->f; + init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); + for (i=0; if->nups; i++) { + OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; + luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); + } +} + + +static void open_func (LexState *ls, FuncState *fs) { + Proto *f = luaF_newproto(ls->L); + fs->f = f; + fs->prev = ls->fs; /* linked list of funcstates */ + fs->ls = ls; + fs->L = ls->L; + ls->fs = fs; + fs->pc = 0; + fs->lasttarget = 0; + fs->jpc = NO_JUMP; + fs->freereg = 0; + fs->nk = 0; + fs->h = luaH_new(ls->L, 0, 0); + fs->np = 0; + fs->nlocvars = 0; + fs->nactvar = 0; + fs->bl = NULL; + f->source = ls->source; + f->maxstacksize = 2; /* registers 0/1 are always valid */ +} + + +static void close_func (LexState *ls) { + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; + removevars(ls, 0); + luaK_codeABC(fs, OP_RETURN, 0, 1, 0); /* final return */ + luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); + f->sizecode = fs->pc; + luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); + f->sizelineinfo = fs->pc; + luaM_reallocvector(L, f->k, f->sizek, fs->nk, TObject); + f->sizek = fs->nk; + luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); + f->sizep = fs->np; + luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); + f->sizelocvars = fs->nlocvars; + luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *); + f->sizeupvalues = f->nups; + lua_assert(luaG_checkcode(f)); + lua_assert(fs->bl == NULL); + ls->fs = fs->prev; +} + + +Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff) { + struct LexState lexstate; + struct FuncState funcstate; + lexstate.buff = buff; + lexstate.nestlevel = 0; + luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z))); + open_func(&lexstate, &funcstate); + next(&lexstate); /* read first token */ + chunk(&lexstate); + check_condition(&lexstate, (lexstate.t.token == TK_EOS), " expected"); + close_func(&lexstate); + lua_assert(funcstate.prev == NULL); + lua_assert(funcstate.f->nups == 0); + lua_assert(lexstate.nestlevel == 0); + return funcstate.f; +} + + + +/*============================================================*/ +/* GRAMMAR RULES */ +/*============================================================*/ + + +static void luaY_field (LexState *ls, expdesc *v) { + /* field -> ['.' | ':'] NAME */ + FuncState *fs = ls->fs; + expdesc key; + luaK_exp2anyreg(fs, v); + next(ls); /* skip the dot or colon */ + checkname(ls, &key); + luaK_indexed(fs, v, &key); +} + + +static void luaY_index (LexState *ls, expdesc *v) { + /* index -> '[' expr ']' */ + next(ls); /* skip the '[' */ + expr(ls, v); + luaK_exp2val(ls->fs, v); + check(ls, ']'); +} + + +/* +** {====================================================================== +** Rules for Constructors +** ======================================================================= +*/ + + +struct ConsControl { + expdesc v; /* last list item read */ + expdesc *t; /* table descriptor */ + int nh; /* total number of `record' elements */ + int na; /* total number of array elements */ + int tostore; /* number of array elements pending to be stored */ +}; + + +static void recfield (LexState *ls, struct ConsControl *cc) { + /* recfield -> (NAME | `['exp1`]') = exp1 */ + FuncState *fs = ls->fs; + int reg = ls->fs->freereg; + expdesc key, val; + if (ls->t.token == TK_NAME) { + luaX_checklimit(ls, cc->nh, MAX_INT, "items in a constructor"); + cc->nh++; + checkname(ls, &key); + } + else /* ls->t.token == '[' */ + luaY_index(ls, &key); + check(ls, '='); + luaK_exp2RK(fs, &key); + expr(ls, &val); + luaK_codeABC(fs, OP_SETTABLE, cc->t->info, luaK_exp2RK(fs, &key), + luaK_exp2RK(fs, &val)); + fs->freereg = reg; /* free registers */ +} + + +static void closelistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->v.k == VVOID) return; /* there is no list item */ + luaK_exp2nextreg(fs, &cc->v); + cc->v.k = VVOID; + if (cc->tostore == LFIELDS_PER_FLUSH) { + luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1); /* flush */ + cc->tostore = 0; /* no more items pending */ + fs->freereg = cc->t->info + 1; /* free registers */ + } +} + + +static void lastlistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->tostore == 0) return; + if (cc->v.k == VCALL) { + luaK_setcallreturns(fs, &cc->v, LUA_MULTRET); + luaK_codeABx(fs, OP_SETLISTO, cc->t->info, cc->na-1); + } + else { + if (cc->v.k != VVOID) + luaK_exp2nextreg(fs, &cc->v); + luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1); + } + fs->freereg = cc->t->info + 1; /* free registers */ +} + + +static void listfield (LexState *ls, struct ConsControl *cc) { + expr(ls, &cc->v); + luaX_checklimit(ls, cc->na, MAXARG_Bx, "items in a constructor"); + cc->na++; + cc->tostore++; +} + + +static void constructor (LexState *ls, expdesc *t) { + /* constructor -> ?? */ + FuncState *fs = ls->fs; + int line = ls->linenumber; + int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); + struct ConsControl cc; + cc.na = cc.nh = cc.tostore = 0; + cc.t = t; + init_exp(t, VRELOCABLE, pc); + init_exp(&cc.v, VVOID, 0); /* no value (yet) */ + luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ + check(ls, '{'); + do { + lua_assert(cc.v.k == VVOID || cc.tostore > 0); + testnext(ls, ';'); /* compatibility only */ + if (ls->t.token == '}') break; + closelistfield(fs, &cc); + switch(ls->t.token) { + case TK_NAME: { /* may be listfields or recfields */ + lookahead(ls); + if (ls->lookahead.token != '=') /* expression? */ + listfield(ls, &cc); + else + recfield(ls, &cc); + break; + } + case '[': { /* constructor_item -> recfield */ + recfield(ls, &cc); + break; + } + default: { /* constructor_part -> listfield */ + listfield(ls, &cc); + break; + } + } + } while (testnext(ls, ',') || testnext(ls, ';')); + check_match(ls, '}', '{', line); + lastlistfield(fs, &cc); + SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ + SETARG_C(fs->f->code[pc], luaO_log2(cc.nh)+1); /* set initial table size */ +} + +/* }====================================================================== */ + + + +static void parlist (LexState *ls) { + /* parlist -> [ param { `,' param } ] */ + int nparams = 0; + int dots = 0; + if (ls->t.token != ')') { /* is `parlist' not empty? */ + do { + switch (ls->t.token) { + case TK_DOTS: dots = 1; next(ls); break; + case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break; + default: luaX_syntaxerror(ls, " or `...' expected"); + } + } while (!dots && testnext(ls, ',')); + } + code_params(ls, nparams, dots); +} + + +static void body (LexState *ls, expdesc *e, int needself, int line) { + /* body -> `(' parlist `)' chunk END */ + FuncState new_fs; + open_func(ls, &new_fs); + new_fs.f->lineDefined = line; + check(ls, '('); + if (needself) + create_local(ls, "self"); + parlist(ls); + check(ls, ')'); + chunk(ls); + check_match(ls, TK_END, TK_FUNCTION, line); + close_func(ls); + pushclosure(ls, &new_fs, e); +} + + +static int explist1 (LexState *ls, expdesc *v) { + /* explist1 -> expr { `,' expr } */ + int n = 1; /* at least one expression */ + expr(ls, v); + while (testnext(ls, ',')) { + luaK_exp2nextreg(ls->fs, v); + expr(ls, v); + n++; + } + return n; +} + + +static void funcargs (LexState *ls, expdesc *f) { + FuncState *fs = ls->fs; + expdesc args; + int base, nparams; + int line = ls->linenumber; + switch (ls->t.token) { + case '(': { /* funcargs -> `(' [ explist1 ] `)' */ + if (line != ls->lastline) + luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)"); + next(ls); + if (ls->t.token == ')') /* arg list is empty? */ + args.k = VVOID; + else { + explist1(ls, &args); + luaK_setcallreturns(fs, &args, LUA_MULTRET); + } + check_match(ls, ')', '(', line); + break; + } + case '{': { /* funcargs -> constructor */ + constructor(ls, &args); + break; + } + case TK_STRING: { /* funcargs -> STRING */ + codestring(ls, &args, ls->t.seminfo.ts); + next(ls); /* must use `seminfo' before `next' */ + break; + } + default: { + luaX_syntaxerror(ls, "function arguments expected"); + return; + } + } + lua_assert(f->k == VNONRELOC); + base = f->info; /* base register for call */ + if (args.k == VCALL) + nparams = LUA_MULTRET; /* open call */ + else { + if (args.k != VVOID) + luaK_exp2nextreg(fs, &args); /* close last argument */ + nparams = fs->freereg - (base+1); + } + init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); + luaK_fixline(fs, line); + fs->freereg = base+1; /* call remove function and arguments and leaves + (unless changed) one result */ +} + + + + +/* +** {====================================================================== +** Expression parsing +** ======================================================================= +*/ + + +static void prefixexp (LexState *ls, expdesc *v) { + /* prefixexp -> NAME | '(' expr ')' */ + switch (ls->t.token) { + case '(': { + int line = ls->linenumber; + next(ls); + expr(ls, v); + check_match(ls, ')', '(', line); + luaK_dischargevars(ls->fs, v); + return; + } + case TK_NAME: { + singlevar(ls, v, 1); + return; + } +#ifdef LUA_COMPATUPSYNTAX + case '%': { /* for compatibility only */ + TString *varname; + int line = ls->linenumber; + next(ls); /* skip `%' */ + varname = singlevar(ls, v, 1); + if (v->k != VUPVAL) + luaX_errorline(ls, "global upvalues are obsolete", + getstr(varname), line); + return; + } +#endif + default: { + luaX_syntaxerror(ls, "unexpected symbol"); + return; + } + } +} + + +static void primaryexp (LexState *ls, expdesc *v) { + /* primaryexp -> + prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ + FuncState *fs = ls->fs; + prefixexp(ls, v); + for (;;) { + switch (ls->t.token) { + case '.': { /* field */ + luaY_field(ls, v); + break; + } + case '[': { /* `[' exp1 `]' */ + expdesc key; + luaK_exp2anyreg(fs, v); + luaY_index(ls, &key); + luaK_indexed(fs, v, &key); + break; + } + case ':': { /* `:' NAME funcargs */ + expdesc key; + next(ls); + checkname(ls, &key); + luaK_self(fs, v, &key); + funcargs(ls, v); + break; + } + case '(': case TK_STRING: case '{': { /* funcargs */ + luaK_exp2nextreg(fs, v); + funcargs(ls, v); + break; + } + default: return; + } + } +} + + +static void simpleexp (LexState *ls, expdesc *v) { + /* simpleexp -> NUMBER | STRING | NIL | constructor | FUNCTION body + | primaryexp */ + switch (ls->t.token) { + case TK_NUMBER: { + init_exp(v, VK, luaK_numberK(ls->fs, ls->t.seminfo.r)); + next(ls); /* must use `seminfo' before `next' */ + break; + } + case TK_STRING: { + codestring(ls, v, ls->t.seminfo.ts); + next(ls); /* must use `seminfo' before `next' */ + break; + } + case TK_NIL: { + init_exp(v, VNIL, 0); + next(ls); + break; + } + case TK_TRUE: { + init_exp(v, VTRUE, 0); + next(ls); + break; + } + case TK_FALSE: { + init_exp(v, VFALSE, 0); + next(ls); + break; + } + case '{': { /* constructor */ + constructor(ls, v); + break; + } + case TK_FUNCTION: { + next(ls); + body(ls, v, 0, ls->linenumber); + break; + } + default: { + primaryexp(ls, v); + break; + } + } +} + + +static UnOpr getunopr (int op) { + switch (op) { + case TK_NOT: return OPR_NOT; + case '-': return OPR_MINUS; + default: return OPR_NOUNOPR; + } +} + + +static BinOpr getbinopr (int op) { + switch (op) { + case '+': return OPR_ADD; + case '-': return OPR_SUB; + case '*': return OPR_MULT; + case '/': return OPR_DIV; + case '^': return OPR_POW; + case TK_CONCAT: return OPR_CONCAT; + case TK_NE: return OPR_NE; + case TK_EQ: return OPR_EQ; + case '<': return OPR_LT; + case TK_LE: return OPR_LE; + case '>': return OPR_GT; + case TK_GE: return OPR_GE; + case TK_AND: return OPR_AND; + case TK_OR: return OPR_OR; + default: return OPR_NOBINOPR; + } +} + + +static const struct { + lu_byte left; /* left priority for each binary operator */ + lu_byte right; /* right priority */ +} priority[] = { /* ORDER OPR */ + {6, 6}, {6, 6}, {7, 7}, {7, 7}, /* arithmetic */ + {10, 9}, {5, 4}, /* power and concat (right associative) */ + {3, 3}, {3, 3}, /* equality */ + {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ + {2, 2}, {1, 1} /* logical (and/or) */ +}; + +#define UNARY_PRIORITY 8 /* priority for unary operators */ + + +/* +** subexpr -> (simplexep | unop subexpr) { binop subexpr } +** where `binop' is any binary operator with a priority higher than `limit' +*/ +static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { + BinOpr op; + UnOpr uop; + enterlevel(ls); + uop = getunopr(ls->t.token); + if (uop != OPR_NOUNOPR) { + next(ls); + subexpr(ls, v, UNARY_PRIORITY); + luaK_prefix(ls->fs, uop, v); + } + else simpleexp(ls, v); + /* expand while operators have priorities higher than `limit' */ + op = getbinopr(ls->t.token); + while (op != OPR_NOBINOPR && cast(int, priority[op].left) > limit) { + expdesc v2; + BinOpr nextop; + next(ls); + luaK_infix(ls->fs, op, v); + /* read sub-expression with higher priority */ + nextop = subexpr(ls, &v2, cast(int, priority[op].right)); + luaK_posfix(ls->fs, op, v, &v2); + op = nextop; + } + leavelevel(ls); + return op; /* return first untreated operator */ +} + + +static void expr (LexState *ls, expdesc *v) { + subexpr(ls, v, -1); +} + +/* }==================================================================== */ + + + +/* +** {====================================================================== +** Rules for Statements +** ======================================================================= +*/ + + +static int block_follow (int token) { + switch (token) { + case TK_ELSE: case TK_ELSEIF: case TK_END: + case TK_UNTIL: case TK_EOS: + return 1; + default: return 0; + } +} + + +static void block (LexState *ls) { + /* block -> chunk */ + FuncState *fs = ls->fs; + BlockCnt bl; + enterblock(fs, &bl, 0); + chunk(ls); + lua_assert(bl.breaklist == NO_JUMP); + leaveblock(fs); +} + + +/* +** structure to chain all variables in the left-hand side of an +** assignment +*/ +struct LHS_assign { + struct LHS_assign *prev; + expdesc v; /* variable (global, local, upvalue, or indexed) */ +}; + + +/* +** check whether, in an assignment to a local variable, the local variable +** is needed in a previous assignment (to a table). If so, save original +** local value in a safe place and use this safe copy in the previous +** assignment. +*/ +static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { + FuncState *fs = ls->fs; + int extra = fs->freereg; /* eventual position to save local variable */ + int conflict = 0; + for (; lh; lh = lh->prev) { + if (lh->v.k == VINDEXED) { + if (lh->v.info == v->info) { /* conflict? */ + conflict = 1; + lh->v.info = extra; /* previous assignment will use safe copy */ + } + if (lh->v.aux == v->info) { /* conflict? */ + conflict = 1; + lh->v.aux = extra; /* previous assignment will use safe copy */ + } + } + } + if (conflict) { + luaK_codeABC(fs, OP_MOVE, fs->freereg, v->info, 0); /* make copy */ + luaK_reserveregs(fs, 1); + } +} + + +static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { + expdesc e; + check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, + "syntax error"); + if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ + struct LHS_assign nv; + nv.prev = lh; + primaryexp(ls, &nv.v); + if (nv.v.k == VLOCAL) + check_conflict(ls, lh, &nv.v); + assignment(ls, &nv, nvars+1); + } + else { /* assignment -> `=' explist1 */ + int nexps; + check(ls, '='); + nexps = explist1(ls, &e); + if (nexps != nvars) { + adjust_assign(ls, nvars, nexps, &e); + if (nexps > nvars) + ls->fs->freereg -= nexps - nvars; /* remove extra values */ + } + else { + luaK_setcallreturns(ls->fs, &e, 1); /* close last expression */ + luaK_storevar(ls->fs, &lh->v, &e); + return; /* avoid default */ + } + } + init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ + luaK_storevar(ls->fs, &lh->v, &e); +} + + +static void cond (LexState *ls, expdesc *v) { + /* cond -> exp */ + expr(ls, v); /* read condition */ + if (v->k == VNIL) v->k = VFALSE; /* `falses' are all equal here */ + luaK_goiftrue(ls->fs, v); + luaK_patchtohere(ls->fs, v->t); +} + + +/* +** The while statement optimizes its code by coding the condition +** after its body (and thus avoiding one jump in the loop). +*/ + +/* +** maximum size of expressions for optimizing `while' code +*/ +#ifndef MAXEXPWHILE +#define MAXEXPWHILE 100 +#endif + +/* +** the call `luaK_goiffalse' may grow the size of an expression by +** at most this: +*/ +#define EXTRAEXP 5 + +static void whilestat (LexState *ls, int line) { + /* whilestat -> WHILE cond DO block END */ + Instruction codeexp[MAXEXPWHILE + EXTRAEXP]; + int lineexp; + int i; + int sizeexp; + FuncState *fs = ls->fs; + int whileinit, blockinit, expinit; + expdesc v; + BlockCnt bl; + next(ls); /* skip WHILE */ + whileinit = luaK_jump(fs); /* jump to condition (which will be moved) */ + expinit = luaK_getlabel(fs); + expr(ls, &v); /* parse condition */ + if (v.k == VK) v.k = VTRUE; /* `trues' are all equal here */ + lineexp = ls->linenumber; + luaK_goiffalse(fs, &v); + luaK_concat(fs, &v.f, fs->jpc); + fs->jpc = NO_JUMP; + sizeexp = fs->pc - expinit; /* size of expression code */ + if (sizeexp > MAXEXPWHILE) + luaX_syntaxerror(ls, "`while' condition too complex"); + for (i = 0; i < sizeexp; i++) /* save `exp' code */ + codeexp[i] = fs->f->code[expinit + i]; + fs->pc = expinit; /* remove `exp' code */ + enterblock(fs, &bl, 1); + check(ls, TK_DO); + blockinit = luaK_getlabel(fs); + block(ls); + luaK_patchtohere(fs, whileinit); /* initial jump jumps to here */ + /* move `exp' back to code */ + if (v.t != NO_JUMP) v.t += fs->pc - expinit; + if (v.f != NO_JUMP) v.f += fs->pc - expinit; + for (i=0; i REPEAT block UNTIL cond */ + FuncState *fs = ls->fs; + int repeat_init = luaK_getlabel(fs); + expdesc v; + BlockCnt bl; + enterblock(fs, &bl, 1); + next(ls); + block(ls); + check_match(ls, TK_UNTIL, TK_REPEAT, line); + cond(ls, &v); + luaK_patchlist(fs, v.f, repeat_init); + leaveblock(fs); +} + + +static int exp1 (LexState *ls) { + expdesc e; + int k; + expr(ls, &e); + k = e.k; + luaK_exp2nextreg(ls->fs, &e); + return k; +} + + +static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { + BlockCnt bl; + FuncState *fs = ls->fs; + int prep, endfor; + adjustlocalvars(ls, nvars); /* scope for all variables */ + check(ls, TK_DO); + enterblock(fs, &bl, 1); /* loop block */ + prep = luaK_getlabel(fs); + block(ls); + luaK_patchtohere(fs, prep-1); + endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : + luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3); + luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ + luaK_patchlist(fs, (isnum) ? endfor : luaK_jump(fs), prep); + leaveblock(fs); +} + + +static void fornum (LexState *ls, TString *varname, int line) { + /* fornum -> NAME = exp1,exp1[,exp1] DO body */ + FuncState *fs = ls->fs; + int base = fs->freereg; + new_localvar(ls, varname, 0); + new_localvarstr(ls, "(for limit)", 1); + new_localvarstr(ls, "(for step)", 2); + check(ls, '='); + exp1(ls); /* initial value */ + check(ls, ','); + exp1(ls); /* limit */ + if (testnext(ls, ',')) + exp1(ls); /* optional step */ + else { /* default step = 1 */ + luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); + luaK_reserveregs(fs, 1); + } + luaK_codeABC(fs, OP_SUB, fs->freereg - 3, fs->freereg - 3, fs->freereg - 1); + luaK_jump(fs); + forbody(ls, base, line, 3, 1); +} + + +static void forlist (LexState *ls, TString *indexname) { + /* forlist -> NAME {,NAME} IN explist1 DO body */ + FuncState *fs = ls->fs; + expdesc e; + int nvars = 0; + int line; + int base = fs->freereg; + new_localvarstr(ls, "(for generator)", nvars++); + new_localvarstr(ls, "(for state)", nvars++); + new_localvar(ls, indexname, nvars++); + while (testnext(ls, ',')) + new_localvar(ls, str_checkname(ls), nvars++); + check(ls, TK_IN); + line = ls->linenumber; + adjust_assign(ls, nvars, explist1(ls, &e), &e); + luaK_checkstack(fs, 3); /* extra space to call generator */ + luaK_codeAsBx(fs, OP_TFORPREP, base, NO_JUMP); + forbody(ls, base, line, nvars, 0); +} + + +static void forstat (LexState *ls, int line) { + /* forstat -> fornum | forlist */ + FuncState *fs = ls->fs; + TString *varname; + BlockCnt bl; + enterblock(fs, &bl, 0); /* block to control variable scope */ + next(ls); /* skip `for' */ + varname = str_checkname(ls); /* first variable name */ + switch (ls->t.token) { + case '=': fornum(ls, varname, line); break; + case ',': case TK_IN: forlist(ls, varname); break; + default: luaX_syntaxerror(ls, "`=' or `in' expected"); + } + check_match(ls, TK_END, TK_FOR, line); + leaveblock(fs); +} + + +static void test_then_block (LexState *ls, expdesc *v) { + /* test_then_block -> [IF | ELSEIF] cond THEN block */ + next(ls); /* skip IF or ELSEIF */ + cond(ls, v); + check(ls, TK_THEN); + block(ls); /* `then' part */ +} + + +static void ifstat (LexState *ls, int line) { + /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ + FuncState *fs = ls->fs; + expdesc v; + int escapelist = NO_JUMP; + test_then_block(ls, &v); /* IF cond THEN block */ + while (ls->t.token == TK_ELSEIF) { + luaK_concat(fs, &escapelist, luaK_jump(fs)); + luaK_patchtohere(fs, v.f); + test_then_block(ls, &v); /* ELSEIF cond THEN block */ + } + if (ls->t.token == TK_ELSE) { + luaK_concat(fs, &escapelist, luaK_jump(fs)); + luaK_patchtohere(fs, v.f); + next(ls); /* skip ELSE (after patch, for correct line info) */ + block(ls); /* `else' part */ + } + else + luaK_concat(fs, &escapelist, v.f); + luaK_patchtohere(fs, escapelist); + check_match(ls, TK_END, TK_IF, line); +} + + +static void localfunc (LexState *ls) { + expdesc v, b; + new_localvar(ls, str_checkname(ls), 0); + init_exp(&v, VLOCAL, ls->fs->freereg++); + adjustlocalvars(ls, 1); + body(ls, &b, 0, ls->linenumber); + luaK_storevar(ls->fs, &v, &b); +} + + +static void localstat (LexState *ls) { + /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ + int nvars = 0; + int nexps; + expdesc e; + do { + new_localvar(ls, str_checkname(ls), nvars++); + } while (testnext(ls, ',')); + if (testnext(ls, '=')) + nexps = explist1(ls, &e); + else { + e.k = VVOID; + nexps = 0; + } + adjust_assign(ls, nvars, nexps, &e); + adjustlocalvars(ls, nvars); +} + + +static int funcname (LexState *ls, expdesc *v) { + /* funcname -> NAME {field} [`:' NAME] */ + int needself = 0; + singlevar(ls, v, 1); + while (ls->t.token == '.') + luaY_field(ls, v); + if (ls->t.token == ':') { + needself = 1; + luaY_field(ls, v); + } + return needself; +} + + +static void funcstat (LexState *ls, int line) { + /* funcstat -> FUNCTION funcname body */ + int needself; + expdesc v, b; + next(ls); /* skip FUNCTION */ + needself = funcname(ls, &v); + body(ls, &b, needself, line); + luaK_storevar(ls->fs, &v, &b); + luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ +} + + +static void exprstat (LexState *ls) { + /* stat -> func | assignment */ + FuncState *fs = ls->fs; + struct LHS_assign v; + primaryexp(ls, &v.v); + if (v.v.k == VCALL) { /* stat -> func */ + luaK_setcallreturns(fs, &v.v, 0); /* call statement uses no results */ + } + else { /* stat -> assignment */ + v.prev = NULL; + assignment(ls, &v, 1); + } +} + + +static void retstat (LexState *ls) { + /* stat -> RETURN explist */ + FuncState *fs = ls->fs; + expdesc e; + int first, nret; /* registers with returned values */ + next(ls); /* skip RETURN */ + if (block_follow(ls->t.token) || ls->t.token == ';') + first = nret = 0; /* return no values */ + else { + nret = explist1(ls, &e); /* optional return values */ + if (e.k == VCALL) { + luaK_setcallreturns(fs, &e, LUA_MULTRET); + if (nret == 1) { /* tail call? */ + SET_OPCODE(getcode(fs,&e), OP_TAILCALL); + lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); + } + first = fs->nactvar; + nret = LUA_MULTRET; /* return all values */ + } + else { + if (nret == 1) /* only one single value? */ + first = luaK_exp2anyreg(fs, &e); + else { + luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ + first = fs->nactvar; /* return all `active' values */ + lua_assert(nret == fs->freereg - first); + } + } + } + luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); +} + + +static void breakstat (LexState *ls) { + /* stat -> BREAK [NAME] */ + FuncState *fs = ls->fs; + BlockCnt *bl = fs->bl; + int upval = 0; + next(ls); /* skip BREAK */ + while (bl && !bl->isbreakable) { + upval |= bl->upval; + bl = bl->previous; + } + if (!bl) + luaX_syntaxerror(ls, "no loop to break"); + if (upval) + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); + luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); +} + + +static int statement (LexState *ls) { + int line = ls->linenumber; /* may be needed for error messages */ + switch (ls->t.token) { + case TK_IF: { /* stat -> ifstat */ + ifstat(ls, line); + return 0; + } + case TK_WHILE: { /* stat -> whilestat */ + whilestat(ls, line); + return 0; + } + case TK_DO: { /* stat -> DO block END */ + next(ls); /* skip DO */ + block(ls); + check_match(ls, TK_END, TK_DO, line); + return 0; + } + case TK_FOR: { /* stat -> forstat */ + forstat(ls, line); + return 0; + } + case TK_REPEAT: { /* stat -> repeatstat */ + repeatstat(ls, line); + return 0; + } + case TK_FUNCTION: { + funcstat(ls, line); /* stat -> funcstat */ + return 0; + } + case TK_LOCAL: { /* stat -> localstat */ + next(ls); /* skip LOCAL */ + if (testnext(ls, TK_FUNCTION)) /* local function? */ + localfunc(ls); + else + localstat(ls); + return 0; + } + case TK_RETURN: { /* stat -> retstat */ + retstat(ls); + return 1; /* must be last statement */ + } + case TK_BREAK: { /* stat -> breakstat */ + breakstat(ls); + return 1; /* must be last statement */ + } + default: { + exprstat(ls); + return 0; /* to avoid warnings */ + } + } +} + + +static void chunk (LexState *ls) { + /* chunk -> { stat [`;'] } */ + int islast = 0; + enterlevel(ls); + while (!islast && !block_follow(ls->t.token)) { + islast = statement(ls); + testnext(ls, ';'); + lua_assert(ls->fs->freereg >= ls->fs->nactvar); + ls->fs->freereg = ls->fs->nactvar; /* free registers */ + } + leavelevel(ls); +} + +/* }====================================================================== */ diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lparser.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/lparser.h new file mode 100644 index 0000000000..d6aaaf0e7d --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lparser.h @@ -0,0 +1,71 @@ +/* +** $Id: lparser.h,v 1.47 2003/02/11 10:46:24 roberto Exp $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + +#ifndef lparser_h +#define lparser_h + +#include "llimits.h" +#include "lobject.h" +#include "ltable.h" +#include "lzio.h" + + +/* +** Expression descriptor +*/ + +typedef enum { + VVOID, /* no value */ + VNIL, + VTRUE, + VFALSE, + VK, /* info = index of constant in `k' */ + VLOCAL, /* info = local register */ + VUPVAL, /* info = index of upvalue in `upvalues' */ + VGLOBAL, /* info = index of table; aux = index of global name in `k' */ + VINDEXED, /* info = table register; aux = index register (or `k') */ + VJMP, /* info = instruction pc */ + VRELOCABLE, /* info = instruction pc */ + VNONRELOC, /* info = result register */ + VCALL /* info = result register */ +} expkind; + +typedef struct expdesc { + expkind k; + int info, aux; + int t; /* patch list of `exit when true' */ + int f; /* patch list of `exit when false' */ +} expdesc; + + +struct BlockCnt; /* defined in lparser.c */ + + +/* state needed to generate code for a given function */ +typedef struct FuncState { + Proto *f; /* current function header */ + Table *h; /* table to find (and reuse) elements in `k' */ + struct FuncState *prev; /* enclosing function */ + struct LexState *ls; /* lexical state */ + struct lua_State *L; /* copy of the Lua state */ + struct BlockCnt *bl; /* chain of current blocks */ + int pc; /* next position to code (equivalent to `ncode') */ + int lasttarget; /* `pc' of last `jump target' */ + int jpc; /* list of pending jumps to `pc' */ + int freereg; /* first free register */ + int nk; /* number of elements in `k' */ + int np; /* number of elements in `p' */ + int nlocvars; /* number of elements in `locvars' */ + int nactvar; /* number of active local variables */ + expdesc upvalues[MAXUPVALUES]; /* upvalues */ + int actvar[MAXVARS]; /* declared-variable stack */ +} FuncState; + + +Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff); + + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lstate.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/lstate.c new file mode 100644 index 0000000000..b593658def --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lstate.c @@ -0,0 +1,220 @@ +/* +** $Id: lstate.c,v 1.123 2003/04/03 13:35:34 roberto Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + + +#include + +#define lstate_c + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +/* +** macro to allow the inclusion of user information in Lua state +*/ +#ifndef LUA_USERSTATE +#define EXTRASPACE 0 +#else +union UEXTRASPACE {L_Umaxalign a; LUA_USERSTATE b;}; +#define EXTRASPACE (sizeof(union UEXTRASPACE)) +#endif + + + +/* +** you can change this function through the official API: +** call `lua_setpanicf' +*/ +static int default_panic (lua_State *L) { + UNUSED(L); + return 0; +} + + +static lua_State *mallocstate (lua_State *L) { + lu_byte *block = (lu_byte *)luaM_malloc(L, sizeof(lua_State) + EXTRASPACE); + if (block == NULL) return NULL; + else { + block += EXTRASPACE; + return cast(lua_State *, block); + } +} + + +static void freestate (lua_State *L, lua_State *L1) { + luaM_free(L, cast(lu_byte *, L1) - EXTRASPACE, + sizeof(lua_State) + EXTRASPACE); +} + + +static void stack_init (lua_State *L1, lua_State *L) { + L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TObject); + L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; + L1->top = L1->stack; + L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; + L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); + L1->ci = L1->base_ci; + L1->ci->state = CI_C; /* not a Lua function */ + setnilvalue(L1->top++); /* `function' entry for this `ci' */ + L1->base = L1->ci->base = L1->top; + L1->ci->top = L1->top + LUA_MINSTACK; + L1->size_ci = BASIC_CI_SIZE; + L1->end_ci = L1->base_ci + L1->size_ci; +} + + +static void freestack (lua_State *L, lua_State *L1) { + luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); + luaM_freearray(L, L1->stack, L1->stacksize, TObject); +} + + +/* +** open parts that may cause memory-allocation errors +*/ +static void f_luaopen (lua_State *L, void *ud) { + /* create a new global state */ + global_State *g = luaM_new(NULL, global_State); + UNUSED(ud); + if (g == NULL) luaD_throw(L, LUA_ERRMEM); + L->l_G = g; + g->mainthread = L; + g->GCthreshold = 0; /* mark it as unfinished state */ + g->strt.size = 0; + g->strt.nuse = 0; + g->strt.hash = NULL; + setnilvalue(defaultmeta(L)); + setnilvalue(registry(L)); + luaZ_initbuffer(L, &g->buff); + g->panic = default_panic; + g->rootgc = NULL; + g->rootudata = NULL; + g->tmudata = NULL; + setnilvalue(gkey(g->dummynode)); + setnilvalue(gval(g->dummynode)); + g->dummynode->next = NULL; + g->nblocks = sizeof(lua_State) + sizeof(global_State); + stack_init(L, L); /* init stack */ + /* create default meta table with a dummy table, and then close the loop */ + defaultmeta(L)->tt = LUA_TTABLE; + sethvalue(defaultmeta(L), luaH_new(L, 0, 0)); + hvalue(defaultmeta(L))->metatable = hvalue(defaultmeta(L)); + sethvalue(gt(L), luaH_new(L, 0, 4)); /* table of globals */ + sethvalue(registry(L), luaH_new(L, 4, 4)); /* registry */ + luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ + luaT_init(L); + luaX_init(L); + luaS_fix(luaS_newliteral(L, MEMERRMSG)); + g->GCthreshold = 4*G(L)->nblocks; +} + + +static void preinit_state (lua_State *L) { + L->stack = NULL; + L->stacksize = 0; + L->errorJmp = NULL; + L->hook = NULL; + L->hookmask = L->hookinit = 0; + L->basehookcount = 0; + L->allowhook = 1; + resethookcount(L); + L->openupval = NULL; + L->size_ci = 0; + L->nCcalls = 0; + L->base_ci = L->ci = NULL; + L->errfunc = 0; + setnilvalue(gt(L)); +} + + +static void close_state (lua_State *L) { + luaF_close(L, L->stack); /* close all upvalues for this thread */ + if (G(L)) { /* close global state */ + luaC_sweep(L, 1); /* collect all elements */ + lua_assert(G(L)->rootgc == NULL); + lua_assert(G(L)->rootudata == NULL); + luaS_freeall(L); + luaZ_freebuffer(L, &G(L)->buff); + } + freestack(L, L); + if (G(L)) { + lua_assert(G(L)->nblocks == sizeof(lua_State) + sizeof(global_State)); + luaM_freelem(NULL, G(L)); + } + freestate(NULL, L); +} + + +lua_State *luaE_newthread (lua_State *L) { + lua_State *L1 = mallocstate(L); + luaC_link(L, valtogco(L1), LUA_TTHREAD); + preinit_state(L1); + L1->l_G = L->l_G; + stack_init(L1, L); /* init stack */ + setobj2n(gt(L1), gt(L)); /* share table of globals */ + return L1; +} + + +void luaE_freethread (lua_State *L, lua_State *L1) { + luaF_close(L1, L1->stack); /* close all upvalues for this thread */ + lua_assert(L1->openupval == NULL); + freestack(L, L1); + freestate(L, L1); +} + + +LUA_API lua_State *lua_open (void) { + lua_State *L = mallocstate(NULL); + if (L) { /* allocation OK? */ + L->tt = LUA_TTHREAD; + L->marked = 0; + L->next = L->gclist = NULL; + preinit_state(L); + L->l_G = NULL; + if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { + /* memory allocation error: free partial state */ + close_state(L); + L = NULL; + } + } + lua_userstateopen(L); + return L; +} + + +static void callallgcTM (lua_State *L, void *ud) { + UNUSED(ud); + luaC_callGCTM(L); /* call GC metamethods for all udata */ +} + + +LUA_API void lua_close (lua_State *L) { + lua_lock(L); + L = G(L)->mainthread; /* only the main thread can be closed */ + luaF_close(L, L->stack); /* close all upvalues for this thread */ + luaC_separateudata(L); /* separate udata that have GC metamethods */ + L->errfunc = 0; /* no error function during GC metamethods */ + do { /* repeat until no more errors */ + L->ci = L->base_ci; + L->base = L->top = L->ci->base; + L->nCcalls = 0; + } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); + lua_assert(G(L)->tmudata == NULL); + close_state(L); +} + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lstate.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/lstate.h new file mode 100644 index 0000000000..5422f1b196 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lstate.h @@ -0,0 +1,195 @@ +/* +** $Id: lstate.h,v 1.109 2003/02/27 11:52:30 roberto Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + +#ifndef lstate_h +#define lstate_h + +#include "lua.h" + +#include "lobject.h" +#include "ltm.h" +#include "lzio.h" + + +/* +** macros for thread synchronization inside Lua core machine: +** all accesses to the global state and to global objects are synchronized. +** Because threads can read the stack of other threads +** (when running garbage collection), +** a thread must also synchronize any write-access to its own stack. +** Unsynchronized accesses are allowed only when reading its own stack, +** or when reading immutable fields from global objects +** (such as string values and udata values). +*/ +#ifndef lua_lock +#define lua_lock(L) ((void) 0) +#endif + +#ifndef lua_unlock +#define lua_unlock(L) ((void) 0) +#endif + + +#ifndef lua_userstateopen +#define lua_userstateopen(l) +#endif + + + +struct lua_longjmp; /* defined in ldo.c */ + + +/* default meta table (both for tables and udata) */ +#define defaultmeta(L) (&G(L)->_defaultmeta) + +/* table of globals */ +#define gt(L) (&L->_gt) + +/* registry */ +#define registry(L) (&G(L)->_registry) + + +/* extra stack space to handle TM calls and some other extras */ +#define EXTRA_STACK 5 + + +#define BASIC_CI_SIZE 8 + +#define BASIC_STACK_SIZE (2*LUA_MINSTACK) + + + +typedef struct stringtable { + GCObject **hash; + ls_nstr nuse; /* number of elements */ + int size; +} stringtable; + + +/* +** informations about a call +*/ +typedef struct CallInfo { + StkId base; /* base for called function */ + StkId top; /* top for this function */ + int state; /* bit fields; see below */ + union { + struct { /* for Lua functions */ + const Instruction *savedpc; + const Instruction **pc; /* points to `pc' variable in `luaV_execute' */ + int tailcalls; /* number of tail calls lost under this entry */ + } l; + struct { /* for C functions */ + int dummy; /* just to avoid an empty struct */ + } c; + } u; +} CallInfo; + + +/* +** bit fields for `CallInfo.state' +*/ +#define CI_C (1<<0) /* 1 if function is a C function */ +/* 1 if (Lua) function has an active `luaV_execute' running it */ +#define CI_HASFRAME (1<<1) +/* 1 if Lua function is calling another Lua function (and therefore its + `pc' is being used by the other, and therefore CI_SAVEDPC is 1 too) */ +#define CI_CALLING (1<<2) +#define CI_SAVEDPC (1<<3) /* 1 if `savedpc' is updated */ +#define CI_YIELD (1<<4) /* 1 if thread is suspended */ + + +#define ci_func(ci) (clvalue((ci)->base - 1)) + + +/* +** `global state', shared by all threads of this state +*/ +typedef struct global_State { + stringtable strt; /* hash table for strings */ + GCObject *rootgc; /* list of (almost) all collectable objects */ + GCObject *rootudata; /* (separated) list of all userdata */ + GCObject *tmudata; /* list of userdata to be GC */ + Mbuffer buff; /* temporary buffer for string concatentation */ + lu_mem GCthreshold; + lu_mem nblocks; /* number of `bytes' currently allocated */ + lua_CFunction panic; /* to be called in unprotected errors */ + TObject _registry; + TObject _defaultmeta; + struct lua_State *mainthread; + Node dummynode[1]; /* common node array for all empty tables */ + TString *tmname[TM_N]; /* array with tag-method names */ +} global_State; + + +/* +** `per thread' state +*/ +struct lua_State { + CommonHeader; + StkId top; /* first free slot in the stack */ + StkId base; /* base of current function */ + global_State *l_G; + CallInfo *ci; /* call info for current function */ + StkId stack_last; /* last free slot in the stack */ + StkId stack; /* stack base */ + int stacksize; + CallInfo *end_ci; /* points after end of ci array*/ + CallInfo *base_ci; /* array of CallInfo's */ + unsigned short size_ci; /* size of array `base_ci' */ + unsigned short nCcalls; /* number of nested C calls */ + lu_byte hookmask; + lu_byte allowhook; + lu_byte hookinit; + int basehookcount; + int hookcount; + lua_Hook hook; + TObject _gt; /* table of globals */ + GCObject *openupval; /* list of open upvalues in this stack */ + GCObject *gclist; + struct lua_longjmp *errorJmp; /* current error recover point */ + ptrdiff_t errfunc; /* current error handling function (stack index) */ +}; + + +#define G(L) (L->l_G) + + +/* +** Union of all collectable objects +*/ +union GCObject { + GCheader gch; + union TString ts; + union Udata u; + union Closure cl; + struct Table h; + struct Proto p; + struct UpVal uv; + struct lua_State th; /* thread */ +}; + + +/* macros to convert a GCObject into a specific value */ +#define gcotots(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) +#define gcotou(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) +#define gcotocl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) +#define gcotoh(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) +#define gcotop(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) +#define gcotouv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define ngcotouv(o) \ + check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define gcototh(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) + +/* macro to convert any value into a GCObject */ +#define valtogco(v) (cast(GCObject *, (v))) + + +lua_State *luaE_newthread (lua_State *L); +void luaE_freethread (lua_State *L, lua_State *L1); + +#endif + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lstring.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/lstring.c new file mode 100644 index 0000000000..8cbddbd218 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lstring.c @@ -0,0 +1,102 @@ +/* +** $Id: lstring.c,v 1.78 2002/12/04 17:38:31 roberto Exp $ +** String table (keeps all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + + +#include + +#define lstring_c + +#include "lua.h" + +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" + + + +void luaS_freeall (lua_State *L) { + lua_assert(G(L)->strt.nuse==0); + luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); +} + + +void luaS_resize (lua_State *L, int newsize) { + GCObject **newhash = luaM_newvector(L, newsize, GCObject *); + stringtable *tb = &G(L)->strt; + int i; + for (i=0; isize; i++) { + GCObject *p = tb->hash[i]; + while (p) { /* for each node in the list */ + GCObject *next = p->gch.next; /* save next */ + lu_hash h = gcotots(p)->tsv.hash; + int h1 = lmod(h, newsize); /* new position */ + lua_assert(cast(int, h%newsize) == lmod(h, newsize)); + p->gch.next = newhash[h1]; /* chain it */ + newhash[h1] = p; + p = next; + } + } + luaM_freearray(L, tb->hash, tb->size, TString *); + tb->size = newsize; + tb->hash = newhash; +} + + +static TString *newlstr (lua_State *L, const char *str, size_t l, lu_hash h) { + TString *ts = cast(TString *, luaM_malloc(L, sizestring(l))); + stringtable *tb; + ts->tsv.len = l; + ts->tsv.hash = h; + ts->tsv.marked = 0; + ts->tsv.tt = LUA_TSTRING; + ts->tsv.reserved = 0; + memcpy(ts+1, str, l*sizeof(char)); + ((char *)(ts+1))[l] = '\0'; /* ending 0 */ + tb = &G(L)->strt; + h = lmod(h, tb->size); + ts->tsv.next = tb->hash[h]; /* chain new entry */ + tb->hash[h] = valtogco(ts); + tb->nuse++; + if (tb->nuse > cast(ls_nstr, tb->size) && tb->size <= MAX_INT/2) + luaS_resize(L, tb->size*2); /* too crowded */ + return ts; +} + + +TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { + GCObject *o; + lu_hash h = (lu_hash)l; /* seed */ + size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ + size_t l1; + for (l1=l; l1>=step; l1-=step) /* compute hash */ + h = h ^ ((h<<5)+(h>>2)+(unsigned char)(str[l1-1])); + for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; + o != NULL; + o = o->gch.next) { + TString *ts = gcotots(o); + if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) + return ts; + } + return newlstr(L, str, l, h); /* not found */ +} + + +Udata *luaS_newudata (lua_State *L, size_t s) { + Udata *u; + u = cast(Udata *, luaM_malloc(L, sizeudata(s))); + u->uv.marked = (1<<1); /* is not finalized */ + u->uv.tt = LUA_TUSERDATA; + u->uv.len = s; + u->uv.metatable = hvalue(defaultmeta(L)); + /* chain it on udata list */ + u->uv.next = G(L)->rootudata; + G(L)->rootudata = valtogco(u); + return u; +} + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lstring.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/lstring.h new file mode 100644 index 0000000000..be5a1e3767 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lstring.h @@ -0,0 +1,33 @@ +/* +** $Id: lstring.h,v 1.37 2002/08/16 14:45:55 roberto Exp $ +** String table (keep all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + +#ifndef lstring_h +#define lstring_h + + +#include "lobject.h" +#include "lstate.h" + + + +#define sizestring(l) (cast(lu_mem, sizeof(union TString))+ \ + (cast(lu_mem, l)+1)*sizeof(char)) + +#define sizeudata(l) (cast(lu_mem, sizeof(union Udata))+(l)) + +#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) +#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ + (sizeof(s)/sizeof(char))-1)) + +#define luaS_fix(s) ((s)->tsv.marked |= (1<<4)) + +void luaS_resize (lua_State *L, int newsize); +Udata *luaS_newudata (lua_State *L, size_t s); +void luaS_freeall (lua_State *L); +TString *luaS_newlstr (lua_State *L, const char *str, size_t l); + + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lstrlib.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/lstrlib.c new file mode 100644 index 0000000000..8752e3aba3 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lstrlib.c @@ -0,0 +1,770 @@ +/* +** $Id: lstrlib.c,v 1.98 2003/04/03 13:35:34 roberto Exp $ +** Standard library for string operations and pattern-matching +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include + +#define lstrlib_c + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* macro to `unsign' a character */ +#ifndef uchar +#define uchar(c) ((unsigned char)(c)) +#endif + + +typedef long sint32; /* a signed version for size_t */ + + +static int str_len (lua_State *L) { + size_t l; + luaL_checklstring(L, 1, &l); + lua_pushnumber(L, (lua_Number)l); + return 1; +} + + +static sint32 posrelat (sint32 pos, size_t len) { + /* relative string position: negative means back from end */ + return (pos>=0) ? pos : (sint32)len+pos+1; +} + + +static int str_sub (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + sint32 start = posrelat(luaL_checklong(L, 2), l); + sint32 end = posrelat(luaL_optlong(L, 3, -1), l); + if (start < 1) start = 1; + if (end > (sint32)l) end = (sint32)l; + if (start <= end) + lua_pushlstring(L, s+start-1, end-start+1); + else lua_pushliteral(L, ""); + return 1; +} + + +static int str_lower (lua_State *L) { + size_t l; + size_t i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + luaL_buffinit(L, &b); + for (i=0; i 0) + luaL_addlstring(&b, s, l); + luaL_pushresult(&b); + return 1; +} + + +static int str_byte (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + sint32 pos = posrelat(luaL_optlong(L, 2, 1), l); + if (pos <= 0 || (size_t)(pos) > l) /* index out of range? */ + return 0; /* no answer */ + lua_pushnumber(L, uchar(s[pos-1])); + return 1; +} + + +static int str_char (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int i; + luaL_Buffer b; + luaL_buffinit(L, &b); + for (i=1; i<=n; i++) { + int c = luaL_checkint(L, i); + luaL_argcheck(L, uchar(c) == c, i, "invalid value"); + luaL_putchar(&b, uchar(c)); + } + luaL_pushresult(&b); + return 1; +} + + +static int writer (lua_State *L, const void* b, size_t size, void* B) { + (void)L; + luaL_addlstring((luaL_Buffer*) B, (const char *)b, size); + return 1; +} + + +static int str_dump (lua_State *L) { + luaL_Buffer b; + luaL_checktype(L, 1, LUA_TFUNCTION); + luaL_buffinit(L,&b); + if (!lua_dump(L, writer, &b)) + luaL_error(L, "unable to dump given function"); + luaL_pushresult(&b); + return 1; +} + + + +/* +** {====================================================== +** PATTERN MATCHING +** ======================================================= +*/ + +#ifndef MAX_CAPTURES +#define MAX_CAPTURES 32 /* arbitrary limit */ +#endif + + +#define CAP_UNFINISHED (-1) +#define CAP_POSITION (-2) + +typedef struct MatchState { + const char *src_init; /* init of source string */ + const char *src_end; /* end (`\0') of source string */ + lua_State *L; + int level; /* total number of captures (finished or unfinished) */ + struct { + const char *init; + sint32 len; + } capture[MAX_CAPTURES]; +} MatchState; + + +#define ESC '%' +#define SPECIALS "^$*+?.([%-" + + +static int check_capture (MatchState *ms, int l) { + l -= '1'; + if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) + return luaL_error(ms->L, "invalid capture index"); + return l; +} + + +static int capture_to_close (MatchState *ms) { + int level = ms->level; + for (level--; level>=0; level--) + if (ms->capture[level].len == CAP_UNFINISHED) return level; + return luaL_error(ms->L, "invalid pattern capture"); +} + + +static const char *luaI_classend (MatchState *ms, const char *p) { + switch (*p++) { + case ESC: { + if (*p == '\0') + luaL_error(ms->L, "malformed pattern (ends with `%')"); + return p+1; + } + case '[': { + if (*p == '^') p++; + do { /* look for a `]' */ + if (*p == '\0') + luaL_error(ms->L, "malformed pattern (missing `]')"); + if (*(p++) == ESC && *p != '\0') + p++; /* skip escapes (e.g. `%]') */ + } while (*p != ']'); + return p+1; + } + default: { + return p; + } + } +} + + +static int match_class (int c, int cl) { + int res; + switch (tolower(cl)) { + case 'a' : res = isalpha(c); break; + case 'c' : res = iscntrl(c); break; + case 'd' : res = isdigit(c); break; + case 'l' : res = islower(c); break; + case 'p' : res = ispunct(c); break; + case 's' : res = isspace(c); break; + case 'u' : res = isupper(c); break; + case 'w' : res = isalnum(c); break; + case 'x' : res = isxdigit(c); break; + case 'z' : res = (c == 0); break; + default: return (cl == c); + } + return (islower(cl) ? res : !res); +} + + +static int matchbracketclass (int c, const char *p, const char *ec) { + int sig = 1; + if (*(p+1) == '^') { + sig = 0; + p++; /* skip the `^' */ + } + while (++p < ec) { + if (*p == ESC) { + p++; + if (match_class(c, *p)) + return sig; + } + else if ((*(p+1) == '-') && (p+2 < ec)) { + p+=2; + if (uchar(*(p-2)) <= c && c <= uchar(*p)) + return sig; + } + else if (uchar(*p) == c) return sig; + } + return !sig; +} + + +static int luaI_singlematch (int c, const char *p, const char *ep) { + switch (*p) { + case '.': return 1; /* matches any char */ + case ESC: return match_class(c, *(p+1)); + case '[': return matchbracketclass(c, p, ep-1); + default: return (uchar(*p) == c); + } +} + + +static const char *match (MatchState *ms, const char *s, const char *p); + + +static const char *matchbalance (MatchState *ms, const char *s, + const char *p) { + if (*p == 0 || *(p+1) == 0) + luaL_error(ms->L, "unbalanced pattern"); + if (*s != *p) return NULL; + else { + int b = *p; + int e = *(p+1); + int cont = 1; + while (++s < ms->src_end) { + if (*s == e) { + if (--cont == 0) return s+1; + } + else if (*s == b) cont++; + } + } + return NULL; /* string ends out of balance */ +} + + +static const char *max_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + sint32 i = 0; /* counts maximum expand for item */ + while ((s+i)src_end && luaI_singlematch(uchar(*(s+i)), p, ep)) + i++; + /* keeps trying to match with the maximum repetitions */ + while (i>=0) { + const char *res = match(ms, (s+i), ep+1); + if (res) return res; + i--; /* else didn't match; reduce 1 repetition to try again */ + } + return NULL; +} + + +static const char *min_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + for (;;) { + const char *res = match(ms, s, ep+1); + if (res != NULL) + return res; + else if (ssrc_end && luaI_singlematch(uchar(*s), p, ep)) + s++; /* try with one more repetition */ + else return NULL; + } +} + + +static const char *start_capture (MatchState *ms, const char *s, + const char *p, int what) { + const char *res; + int level = ms->level; + if (level >= MAX_CAPTURES) luaL_error(ms->L, "too many captures"); + ms->capture[level].init = s; + ms->capture[level].len = what; + ms->level = level+1; + if ((res=match(ms, s, p)) == NULL) /* match failed? */ + ms->level--; /* undo capture */ + return res; +} + + +static const char *end_capture (MatchState *ms, const char *s, + const char *p) { + int l = capture_to_close(ms); + const char *res; + ms->capture[l].len = s - ms->capture[l].init; /* close capture */ + if ((res = match(ms, s, p)) == NULL) /* match failed? */ + ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ + return res; +} + + +static const char *match_capture (MatchState *ms, const char *s, int l) { + size_t len; + l = check_capture(ms, l); + len = ms->capture[l].len; + if ((size_t)(ms->src_end-s) >= len && + memcmp(ms->capture[l].init, s, len) == 0) + return s+len; + else return NULL; +} + + +static const char *match (MatchState *ms, const char *s, const char *p) { + init: /* using goto's to optimize tail recursion */ + switch (*p) { + case '(': { /* start capture */ + if (*(p+1) == ')') /* position capture? */ + return start_capture(ms, s, p+2, CAP_POSITION); + else + return start_capture(ms, s, p+1, CAP_UNFINISHED); + } + case ')': { /* end capture */ + return end_capture(ms, s, p+1); + } + case ESC: { + switch (*(p+1)) { + case 'b': { /* balanced string? */ + s = matchbalance(ms, s, p+2); + if (s == NULL) return NULL; + p+=4; goto init; /* else return match(ms, s, p+4); */ + } + case 'f': { /* frontier? */ + const char *ep; char previous; + p += 2; + if (*p != '[') + luaL_error(ms->L, "missing `[' after `%%f' in pattern"); + ep = luaI_classend(ms, p); /* points to what is next */ + previous = (s == ms->src_init) ? '\0' : *(s-1); + if (matchbracketclass(uchar(previous), p, ep-1) || + !matchbracketclass(uchar(*s), p, ep-1)) return NULL; + p=ep; goto init; /* else return match(ms, s, ep); */ + } + default: { + if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */ + s = match_capture(ms, s, *(p+1)); + if (s == NULL) return NULL; + p+=2; goto init; /* else return match(ms, s, p+2) */ + } + goto dflt; /* case default */ + } + } + } + case '\0': { /* end of pattern */ + return s; /* match succeeded */ + } + case '$': { + if (*(p+1) == '\0') /* is the `$' the last char in pattern? */ + return (s == ms->src_end) ? s : NULL; /* check end of string */ + else goto dflt; + } + default: dflt: { /* it is a pattern item */ + const char *ep = luaI_classend(ms, p); /* points to what is next */ + int m = ssrc_end && luaI_singlematch(uchar(*s), p, ep); + switch (*ep) { + case '?': { /* optional */ + const char *res; + if (m && ((res=match(ms, s+1, ep+1)) != NULL)) + return res; + p=ep+1; goto init; /* else return match(ms, s, ep+1); */ + } + case '*': { /* 0 or more repetitions */ + return max_expand(ms, s, p, ep); + } + case '+': { /* 1 or more repetitions */ + return (m ? max_expand(ms, s+1, p, ep) : NULL); + } + case '-': { /* 0 or more repetitions (minimum) */ + return min_expand(ms, s, p, ep); + } + default: { + if (!m) return NULL; + s++; p=ep; goto init; /* else return match(ms, s+1, ep); */ + } + } + } + } +} + + + +static const char *lmemfind (const char *s1, size_t l1, + const char *s2, size_t l2) { + if (l2 == 0) return s1; /* empty strings are everywhere */ + else if (l2 > l1) return NULL; /* avoids a negative `l1' */ + else { + const char *init; /* to search for a `*s2' inside `s1' */ + l2--; /* 1st char will be checked by `memchr' */ + l1 = l1-l2; /* `s2' cannot be found after that */ + while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { + init++; /* 1st char is already checked */ + if (memcmp(init, s2+1, l2) == 0) + return init-1; + else { /* correct `l1' and `s1' to try again */ + l1 -= init-s1; + s1 = init; + } + } + return NULL; /* not found */ + } +} + + +static void push_onecapture (MatchState *ms, int i) { + int l = ms->capture[i].len; + if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); + if (l == CAP_POSITION) + lua_pushnumber(ms->L, (lua_Number)(ms->capture[i].init - ms->src_init + 1)); + else + lua_pushlstring(ms->L, ms->capture[i].init, l); +} + + +static int push_captures (MatchState *ms, const char *s, const char *e) { + int i; + luaL_checkstack(ms->L, ms->level, "too many captures"); + if (ms->level == 0 && s) { /* no explicit captures? */ + lua_pushlstring(ms->L, s, e-s); /* return whole match */ + return 1; + } + else { /* return all captures */ + for (i=0; ilevel; i++) + push_onecapture(ms, i); + return ms->level; /* number of strings pushed */ + } +} + + +static int str_find (lua_State *L) { + size_t l1, l2; + const char *s = luaL_checklstring(L, 1, &l1); + const char *p = luaL_checklstring(L, 2, &l2); + sint32 init = posrelat(luaL_optlong(L, 3, 1), l1) - 1; + if (init < 0) init = 0; + else if ((size_t)(init) > l1) init = (sint32)l1; + if (lua_toboolean(L, 4) || /* explicit request? */ + strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */ + /* do a plain search */ + const char *s2 = lmemfind(s+init, l1-init, p, l2); + if (s2) { + lua_pushnumber(L, (lua_Number)(s2-s+1)); + lua_pushnumber(L, (lua_Number)(s2-s+l2)); + return 2; + } + } + else { + MatchState ms; + int anchor = (*p == '^') ? (p++, 1) : 0; + const char *s1=s+init; + ms.L = L; + ms.src_init = s; + ms.src_end = s+l1; + do { + const char *res; + ms.level = 0; + if ((res=match(&ms, s1, p)) != NULL) { + lua_pushnumber(L, (lua_Number)(s1-s+1)); /* start */ + lua_pushnumber(L, (lua_Number)(res-s)); /* end */ + return push_captures(&ms, NULL, 0) + 2; + } + } while (s1++L; + if (lua_isstring(L, 3)) { + const char *news = lua_tostring(L, 3); + size_t l = lua_strlen(L, 3); + size_t i; + for (i=0; i= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)), + 3, "string or function expected"); + luaL_buffinit(L, &b); + ms.L = L; + ms.src_init = src; + ms.src_end = src+srcl; + while (n < max_s) { + const char *e; + ms.level = 0; + e = match(&ms, src, p); + if (e) { + n++; + add_s(&ms, &b, src, e); + } + if (e && e>src) /* non empty match? */ + src = e; /* skip it */ + else if (src < ms.src_end) + luaL_putchar(&b, *src++); + else break; + if (anchor) break; + } + luaL_addlstring(&b, src, ms.src_end-src); + luaL_pushresult(&b); + lua_pushnumber(L, (lua_Number)n); /* number of substitutions */ + return 2; +} + +/* }====================================================== */ + + +/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ +#define MAX_ITEM 512 +/* maximum size of each format specification (such as '%-099.99d') */ +#define MAX_FORMAT 20 + + +static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + luaL_putchar(b, '"'); + while (l--) { + switch (*s) { + case '"': case '\\': case '\n': { + luaL_putchar(b, '\\'); + luaL_putchar(b, *s); + break; + } + case '\0': { + luaL_addlstring(b, "\\000", 4); + break; + } + default: { + luaL_putchar(b, *s); + break; + } + } + s++; + } + luaL_putchar(b, '"'); +} + + +static const char *scanformat (lua_State *L, const char *strfrmt, + char *form, int *hasprecision) { + const char *p = strfrmt; + while (strchr("-+ #0", *p)) p++; /* skip flags */ + if (isdigit(uchar(*p))) p++; /* skip width */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + if (*p == '.') { + p++; + *hasprecision = 1; + if (isdigit(uchar(*p))) p++; /* skip precision */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + } + if (isdigit(uchar(*p))) + luaL_error(L, "invalid format (width or precision too long)"); + if (p-strfrmt+2 > MAX_FORMAT) /* +2 to include `%' and the specifier */ + luaL_error(L, "invalid format (too long)"); + form[0] = '%'; + strncpy(form+1, strfrmt, p-strfrmt+1); + form[p-strfrmt+2] = 0; + return p; +} + + +static int str_format (lua_State *L) { + int arg = 1; + size_t sfl; + const char *strfrmt = luaL_checklstring(L, arg, &sfl); + const char *strfrmt_end = strfrmt+sfl; + luaL_Buffer b; + luaL_buffinit(L, &b); + while (strfrmt < strfrmt_end) { + if (*strfrmt != '%') + luaL_putchar(&b, *strfrmt++); + else if (*++strfrmt == '%') + luaL_putchar(&b, *strfrmt++); /* %% */ + else { /* format item */ + char form[MAX_FORMAT]; /* to store the format (`%...') */ + char buff[MAX_ITEM]; /* to store the formatted item */ + int hasprecision = 0; + if (isdigit(uchar(*strfrmt)) && *(strfrmt+1) == '$') + return luaL_error(L, "obsolete option (d$) to `format'"); + arg++; + strfrmt = scanformat(L, strfrmt, form, &hasprecision); + switch (*strfrmt++) { + case 'c': case 'd': case 'i': { + sprintf(buff, form, luaL_checkint(L, arg)); + break; + } + case 'o': case 'u': case 'x': case 'X': { + sprintf(buff, form, (unsigned int)(luaL_checknumber(L, arg))); + break; + } + case 'e': case 'E': case 'f': + case 'g': case 'G': { + sprintf(buff, form, luaL_checknumber(L, arg)); + break; + } + case 'q': { + luaI_addquoted(L, &b, arg); + continue; /* skip the `addsize' at the end */ + } + case 's': { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + if (!hasprecision && l >= 100) { + /* no precision and string is too long to be formatted; + keep original string */ + lua_pushvalue(L, arg); + luaL_addvalue(&b); + continue; /* skip the `addsize' at the end */ + } + else { + sprintf(buff, form, s); + break; + } + } + default: { /* also treat cases `pnLlh' */ + return luaL_error(L, "invalid option to `format'"); + } + } + luaL_addlstring(&b, buff, strlen(buff)); + } + } + luaL_pushresult(&b); + return 1; +} + + +static const luaL_reg strlib[] = { + {"len", str_len}, + {"sub", str_sub}, + {"lower", str_lower}, + {"upper", str_upper}, + {"char", str_char}, + {"rep", str_rep}, + {"byte", str_byte}, + {"format", str_format}, + {"dump", str_dump}, + {"find", str_find}, + {"gfind", gfind}, + {"gsub", str_gsub}, + {NULL, NULL} +}; + + +/* +** Open string library +*/ +LUALIB_API int luaopen_string (lua_State *L) { + luaL_openlib(L, LUA_STRLIBNAME, strlib, 0); + return 1; +} + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/ltable.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/ltable.c new file mode 100644 index 0000000000..0c64adb10a --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/ltable.c @@ -0,0 +1,509 @@ +/* +** $Id: ltable.c,v 1.132 2003/04/03 13:35:34 roberto Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + + +/* +** Implementation of tables (aka arrays, objects, or hash tables). +** Tables keep its elements in two parts: an array part and a hash part. +** Non-negative integer keys are all candidates to be kept in the array +** part. The actual size of the array is the largest `n' such that at +** least half the slots between 0 and n are in use. +** Hash uses a mix of chained scatter table with Brent's variation. +** A main invariant of these tables is that, if an element is not +** in its main position (i.e. the `original' position that its hash gives +** to it), then the colliding element is in its own main position. +** In other words, there are collisions only when two elements have the +** same main position (i.e. the same hash values for that table size). +** Because of that, the load factor of these tables can be 100% without +** performance penalties. +*/ + +#include + +#define ltable_c + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "ltable.h" + + +/* +** max size of array part is 2^MAXBITS +*/ +#if BITS_INT > 26 +#define MAXBITS 24 +#else +#define MAXBITS (BITS_INT-2) +#endif + +/* check whether `x' < 2^MAXBITS */ +#define toobig(x) ((((x)-1) >> MAXBITS) != 0) + + +/* function to convert a lua_Number to int (with any rounding method) */ +#ifndef lua_number2int +#define lua_number2int(i,n) ((i)=(int)(n)) +#endif + + +#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) + +#define hashstr(t,str) hashpow2(t, (str)->tsv.hash) +#define hashboolean(t,p) hashpow2(t, p) + + +/* +** for some types, it is better to avoid modulus by power of 2, as +** they tend to have many 2 factors. +*/ +#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) + + +#define hashpointer(t,p) hashmod(t, IntPoint(p)) + + +/* +** number of ints inside a lua_Number +*/ +#define numints cast(int, sizeof(lua_Number)/sizeof(int)) + + +/* +** hash for lua_Numbers +*/ +static Node *hashnum (const Table *t, lua_Number n) { + unsigned int a[numints]; + int i; + n += 1; /* normalize number (avoid -0) */ + lua_assert(sizeof(a) <= sizeof(n)); + memcpy(a, &n, sizeof(a)); + for (i = 1; i < numints; i++) a[0] += a[i]; + return hashmod(t, cast(lu_hash, a[0])); +} + + + +/* +** returns the `main' position of an element in a table (that is, the index +** of its hash value) +*/ +Node *luaH_mainposition (const Table *t, const TObject *key) { + switch (ttype(key)) { + case LUA_TNUMBER: + return hashnum(t, nvalue(key)); + case LUA_TSTRING: + return hashstr(t, tsvalue(key)); + case LUA_TBOOLEAN: + return hashboolean(t, bvalue(key)); + case LUA_TLIGHTUSERDATA: + return hashpointer(t, pvalue(key)); + default: + return hashpointer(t, gcvalue(key)); + } +} + + +/* +** returns the index for `key' if `key' is an appropriate key to live in +** the array part of the table, -1 otherwise. +*/ +static int arrayindex (const TObject *key) { + if (ttisnumber(key)) { + int k; + lua_number2int(k, (nvalue(key))); + if (cast(lua_Number, k) == nvalue(key) && k >= 1 && !toobig(k)) + return k; + } + return -1; /* `key' did not match some condition */ +} + + +/* +** returns the index of a `key' for table traversals. First goes all +** elements in the array part, then elements in the hash part. The +** beginning and end of a traversal are signalled by -1. +*/ +static int luaH_index (lua_State *L, Table *t, StkId key) { + int i; + if (ttisnil(key)) return -1; /* first iteration */ + i = arrayindex(key); + if (0 <= i && i <= t->sizearray) { /* is `key' inside array part? */ + return i-1; /* yes; that's the index (corrected to C) */ + } + else { + const TObject *v = luaH_get(t, key); + if (v == &luaO_nilobject) + luaG_runerror(L, "invalid key for `next'"); + i = cast(int, (cast(const lu_byte *, v) - + cast(const lu_byte *, gval(gnode(t, 0)))) / sizeof(Node)); + return i + t->sizearray; /* hash elements are numbered after array ones */ + } +} + + +int luaH_next (lua_State *L, Table *t, StkId key) { + int i = luaH_index(L, t, key); /* find original element */ + for (i++; i < t->sizearray; i++) { /* try first array part */ + if (!ttisnil(&t->array[i])) { /* a non-nil value? */ + setnvalue(key, cast(lua_Number, i+1)); + setobj2s(key+1, &t->array[i]); + return 1; + } + } + for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ + if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ + setobj2s(key, gkey(gnode(t, i))); + setobj2s(key+1, gval(gnode(t, i))); + return 1; + } + } + return 0; /* no more elements */ +} + + +/* +** {============================================================= +** Rehash +** ============================================================== +*/ + + +static void computesizes (int nums[], int ntotal, int *narray, int *nhash) { + int i; + int a = nums[0]; /* number of elements smaller than 2^i */ + int na = a; /* number of elements to go to array part */ + int n = (na == 0) ? -1 : 0; /* (log of) optimal size for array part */ + for (i = 1; a < *narray && *narray >= twoto(i-1); i++) { + if (nums[i] > 0) { + a += nums[i]; + if (a >= twoto(i-1)) { /* more than half elements in use? */ + n = i; + na = a; + } + } + } + lua_assert(na <= *narray && *narray <= ntotal); + *nhash = ntotal - na; + *narray = (n == -1) ? 0 : twoto(n); + lua_assert(na <= *narray && na >= *narray/2); +} + + +static void numuse (const Table *t, int *narray, int *nhash) { + int nums[MAXBITS+1]; + int i, lg; + int totaluse = 0; + /* count elements in array part */ + for (i=0, lg=0; lg<=MAXBITS; lg++) { /* for each slice [2^(lg-1) to 2^lg) */ + int ttlg = twoto(lg); /* 2^lg */ + if (ttlg > t->sizearray) { + ttlg = t->sizearray; + if (i >= ttlg) break; + } + nums[lg] = 0; + for (; iarray[i])) { + nums[lg]++; + totaluse++; + } + } + } + for (; lg<=MAXBITS; lg++) nums[lg] = 0; /* reset other counts */ + *narray = totaluse; /* all previous uses were in array part */ + /* count elements in hash part */ + i = sizenode(t); + while (i--) { + Node *n = &t->node[i]; + if (!ttisnil(gval(n))) { + int k = arrayindex(gkey(n)); + if (k >= 0) { /* is `key' an appropriate array index? */ + nums[luaO_log2(k-1)+1]++; /* count as such */ + (*narray)++; + } + totaluse++; + } + } + computesizes(nums, totaluse, narray, nhash); +} + + +static void setarrayvector (lua_State *L, Table *t, int size) { + int i; + luaM_reallocvector(L, t->array, t->sizearray, size, TObject); + for (i=t->sizearray; iarray[i]); + t->sizearray = size; +} + + +static void setnodevector (lua_State *L, Table *t, int lsize) { + int i; + int size = twoto(lsize); + if (lsize > MAXBITS) + luaG_runerror(L, "table overflow"); + if (lsize == 0) { /* no elements to hash part? */ + t->node = G(L)->dummynode; /* use common `dummynode' */ + lua_assert(ttisnil(gkey(t->node))); /* assert invariants: */ + lua_assert(ttisnil(gval(t->node))); + lua_assert(t->node->next == NULL); /* (`dummynode' must be empty) */ + } + else { + t->node = luaM_newvector(L, size, Node); + for (i=0; inode[i].next = NULL; + setnilvalue(gkey(gnode(t, i))); + setnilvalue(gval(gnode(t, i))); + } + } + t->lsizenode = cast(lu_byte, lsize); + t->firstfree = gnode(t, size-1); /* first free position to be used */ +} + + +static void resize (lua_State *L, Table *t, int nasize, int nhsize) { + int i; + int oldasize = t->sizearray; + int oldhsize = t->lsizenode; + Node *nold; + Node temp[1]; + if (oldhsize) + nold = t->node; /* save old hash ... */ + else { /* old hash is `dummynode' */ + lua_assert(t->node == G(L)->dummynode); + temp[0] = t->node[0]; /* copy it to `temp' */ + nold = temp; + setnilvalue(gkey(G(L)->dummynode)); /* restate invariant */ + setnilvalue(gval(G(L)->dummynode)); + lua_assert(G(L)->dummynode->next == NULL); + } + if (nasize > oldasize) /* array part must grow? */ + setarrayvector(L, t, nasize); + /* create new hash part with appropriate size */ + setnodevector(L, t, nhsize); + /* re-insert elements */ + if (nasize < oldasize) { /* array part must shrink? */ + t->sizearray = nasize; + /* re-insert elements from vanishing slice */ + for (i=nasize; iarray[i])) + setobjt2t(luaH_setnum(L, t, i+1), &t->array[i]); + } + /* shrink array */ + luaM_reallocvector(L, t->array, oldasize, nasize, TObject); + } + /* re-insert elements in hash part */ + for (i = twoto(oldhsize) - 1; i >= 0; i--) { + Node *old = nold+i; + if (!ttisnil(gval(old))) + setobjt2t(luaH_set(L, t, gkey(old)), gval(old)); + } + if (oldhsize) + luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */ +} + + +static void rehash (lua_State *L, Table *t) { + int nasize, nhsize; + numuse(t, &nasize, &nhsize); /* compute new sizes for array and hash parts */ + resize(L, t, nasize, luaO_log2(nhsize)+1); +} + + + +/* +** }============================================================= +*/ + + +Table *luaH_new (lua_State *L, int narray, int lnhash) { + Table *t = luaM_new(L, Table); + luaC_link(L, valtogco(t), LUA_TTABLE); + t->metatable = hvalue(defaultmeta(L)); + t->flags = cast(lu_byte, ~0); + /* temporary values (kept only if some malloc fails) */ + t->array = NULL; + t->sizearray = 0; + t->lsizenode = 0; + t->node = NULL; + setarrayvector(L, t, narray); + setnodevector(L, t, lnhash); + return t; +} + + +void luaH_free (lua_State *L, Table *t) { + if (t->lsizenode) + luaM_freearray(L, t->node, sizenode(t), Node); + luaM_freearray(L, t->array, t->sizearray, TObject); + luaM_freelem(L, t); +} + + +#if 0 +/* +** try to remove an element from a hash table; cannot move any element +** (because gc can call `remove' during a table traversal) +*/ +void luaH_remove (Table *t, Node *e) { + Node *mp = luaH_mainposition(t, gkey(e)); + if (e != mp) { /* element not in its main position? */ + while (mp->next != e) mp = mp->next; /* find previous */ + mp->next = e->next; /* remove `e' from its list */ + } + else { + if (e->next != NULL) ?? + } + lua_assert(ttisnil(gval(node))); + setnilvalue(gkey(e)); /* clear node `e' */ + e->next = NULL; +} +#endif + + +/* +** inserts a new key into a hash table; first, check whether key's main +** position is free. If not, check whether colliding node is in its main +** position or not: if it is not, move colliding node to an empty place and +** put new key in its main position; otherwise (colliding node is in its main +** position), new key goes to an empty position. +*/ +static TObject *newkey (lua_State *L, Table *t, const TObject *key) { + TObject *val; + Node *mp = luaH_mainposition(t, key); + if (!ttisnil(gval(mp))) { /* main position is not free? */ + Node *othern = luaH_mainposition(t, gkey(mp)); /* `mp' of colliding node */ + Node *n = t->firstfree; /* get a free place */ + if (othern != mp) { /* is colliding node out of its main position? */ + /* yes; move colliding node into free position */ + while (othern->next != mp) othern = othern->next; /* find previous */ + othern->next = n; /* redo the chain with `n' in place of `mp' */ + *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ + mp->next = NULL; /* now `mp' is free */ + setnilvalue(gval(mp)); + } + else { /* colliding node is in its own main position */ + /* new node will go into free position */ + n->next = mp->next; /* chain new position */ + mp->next = n; + mp = n; + } + } + setobj2t(gkey(mp), key); /* write barrier */ + lua_assert(ttisnil(gval(mp))); + for (;;) { /* correct `firstfree' */ + if (ttisnil(gkey(t->firstfree))) + return gval(mp); /* OK; table still has a free place */ + else if (t->firstfree == t->node) break; /* cannot decrement from here */ + else (t->firstfree)--; + } + /* no more free places; must create one */ + setbvalue(gval(mp), 0); /* avoid new key being removed */ + rehash(L, t); /* grow table */ + val = cast(TObject *, luaH_get(t, key)); /* get new position */ + lua_assert(ttisboolean(val)); + setnilvalue(val); + return val; +} + + +/* +** generic search function +*/ +static const TObject *luaH_getany (Table *t, const TObject *key) { + if (ttisnil(key)) return &luaO_nilobject; + else { + Node *n = luaH_mainposition(t, key); + do { /* check whether `key' is somewhere in the chain */ + if (luaO_rawequalObj(gkey(n), key)) return gval(n); /* that's it */ + else n = n->next; + } while (n); + return &luaO_nilobject; + } +} + + +/* +** search function for integers +*/ +const TObject *luaH_getnum (Table *t, int key) { + if (1 <= key && key <= t->sizearray) + return &t->array[key-1]; + else { + lua_Number nk = cast(lua_Number, key); + Node *n = hashnum(t, nk); + do { /* check whether `key' is somewhere in the chain */ + if (ttisnumber(gkey(n)) && nvalue(gkey(n)) == nk) + return gval(n); /* that's it */ + else n = n->next; + } while (n); + return &luaO_nilobject; + } +} + + +/* +** search function for strings +*/ +const TObject *luaH_getstr (Table *t, TString *key) { + Node *n = hashstr(t, key); + do { /* check whether `key' is somewhere in the chain */ + if (ttisstring(gkey(n)) && tsvalue(gkey(n)) == key) + return gval(n); /* that's it */ + else n = n->next; + } while (n); + return &luaO_nilobject; +} + + +/* +** main search function +*/ +const TObject *luaH_get (Table *t, const TObject *key) { + switch (ttype(key)) { + case LUA_TSTRING: return luaH_getstr(t, tsvalue(key)); + case LUA_TNUMBER: { + int k; + lua_number2int(k, (nvalue(key))); + if (cast(lua_Number, k) == nvalue(key)) /* is an integer index? */ + return luaH_getnum(t, k); /* use specialized version */ + /* else go through */ + } + default: return luaH_getany(t, key); + } +} + + +TObject *luaH_set (lua_State *L, Table *t, const TObject *key) { + const TObject *p = luaH_get(t, key); + t->flags = 0; + if (p != &luaO_nilobject) + return cast(TObject *, p); + else { + if (ttisnil(key)) luaG_runerror(L, "table index is nil"); + else if (ttisnumber(key) && nvalue(key) != nvalue(key)) + luaG_runerror(L, "table index is NaN"); + return newkey(L, t, key); + } +} + + +TObject *luaH_setnum (lua_State *L, Table *t, int key) { + const TObject *p = luaH_getnum(t, key); + if (p != &luaO_nilobject) + return cast(TObject *, p); + else { + TObject k; + setnvalue(&k, cast(lua_Number, key)); + return newkey(L, t, &k); + } +} + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/ltable.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/ltable.h new file mode 100644 index 0000000000..3d4d753c3c --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/ltable.h @@ -0,0 +1,31 @@ +/* +** $Id: ltable.h,v 1.44 2003/03/18 12:50:04 roberto Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + +#ifndef ltable_h +#define ltable_h + +#include "lobject.h" + + +#define gnode(t,i) (&(t)->node[i]) +#define gkey(n) (&(n)->i_key) +#define gval(n) (&(n)->i_val) + + +const TObject *luaH_getnum (Table *t, int key); +TObject *luaH_setnum (lua_State *L, Table *t, int key); +const TObject *luaH_getstr (Table *t, TString *key); +const TObject *luaH_get (Table *t, const TObject *key); +TObject *luaH_set (lua_State *L, Table *t, const TObject *key); +Table *luaH_new (lua_State *L, int narray, int lnhash); +void luaH_free (lua_State *L, Table *t); +int luaH_next (lua_State *L, Table *t, StkId key); + +/* exported only for debugging */ +Node *luaH_mainposition (const Table *t, const TObject *key); + + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/ltablib.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/ltablib.c new file mode 100644 index 0000000000..c9bb2d1b7e --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/ltablib.c @@ -0,0 +1,250 @@ +/* +** $Id: ltablib.c,v 1.21 2003/04/03 13:35:34 roberto Exp $ +** Library for Table Manipulation +** See Copyright Notice in lua.h +*/ + + +#include + +#define ltablib_c + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) + + +static int luaB_foreachi (lua_State *L) { + int i; + int n = aux_getn(L, 1); + luaL_checktype(L, 2, LUA_TFUNCTION); + for (i=1; i<=n; i++) { + lua_pushvalue(L, 2); /* function */ + lua_pushnumber(L, (lua_Number)i); /* 1st argument */ + lua_rawgeti(L, 1, i); /* 2nd argument */ + lua_call(L, 2, 1); + if (!lua_isnil(L, -1)) + return 1; + lua_pop(L, 1); /* remove nil result */ + } + return 0; +} + + +static int luaB_foreach (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checktype(L, 2, LUA_TFUNCTION); + lua_pushnil(L); /* first key */ + for (;;) { + if (lua_next(L, 1) == 0) + return 0; + lua_pushvalue(L, 2); /* function */ + lua_pushvalue(L, -3); /* key */ + lua_pushvalue(L, -3); /* value */ + lua_call(L, 2, 1); + if (!lua_isnil(L, -1)) + return 1; + lua_pop(L, 2); /* remove value and result */ + } +} + + +static int luaB_getn (lua_State *L) { + lua_pushnumber(L, (lua_Number)aux_getn(L, 1)); + return 1; +} + + +static int luaB_setn (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_setn(L, 1, luaL_checkint(L, 2)); + return 0; +} + + +static int luaB_tinsert (lua_State *L) { + int v = lua_gettop(L); /* number of arguments */ + int n = aux_getn(L, 1) + 1; + int pos; /* where to insert new element */ + if (v == 2) /* called with only 2 arguments */ + pos = n; /* insert new element at the end */ + else { + pos = luaL_checkint(L, 2); /* 2nd argument is the position */ + if (pos > n) n = pos; /* `grow' array if necessary */ + v = 3; /* function may be called with more than 3 args */ + } + luaL_setn(L, 1, n); /* new size */ + while (--n >= pos) { /* move up elements */ + lua_rawgeti(L, 1, n); + lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */ + } + lua_pushvalue(L, v); + lua_rawseti(L, 1, pos); /* t[pos] = v */ + return 0; +} + + +static int luaB_tremove (lua_State *L) { + int n = aux_getn(L, 1); + int pos = luaL_optint(L, 2, n); + if (n <= 0) return 0; /* table is `empty' */ + luaL_setn(L, 1, n-1); /* t.n = n-1 */ + lua_rawgeti(L, 1, pos); /* result = t[pos] */ + for ( ;pos= P */ + while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { + if (i>u) luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[i] */ + } + /* repeat --j until a[j] <= P */ + while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { + if (j +#include +#include +#include +#include + +#define ltests_c + +#include "lua.h" + +#include "lapi.h" +#include "lauxlib.h" +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lualib.h" + + + +/* +** The whole module only makes sense with LUA_DEBUG on +*/ +#ifdef LUA_DEBUG + + +#define lua_pushintegral(L,i) lua_pushnumber(L, cast(lua_Number, (i))) + + +static lua_State *lua_state = NULL; + +int islocked = 0; + + +#define func_at(L,k) (L->ci->base+(k) - 1) + + +static void setnameval (lua_State *L, const char *name, int val) { + lua_pushstring(L, name); + lua_pushintegral(L, val); + lua_settable(L, -3); +} + + +/* +** {====================================================================== +** Controlled version for realloc. +** ======================================================================= +*/ + +#define MARK 0x55 /* 01010101 (a nice pattern) */ + +#ifndef EXTERNMEMCHECK +/* full memory check */ +#define HEADER (sizeof(L_Umaxalign)) /* ensures maximum alignment for HEADER */ +#define MARKSIZE 16 /* size of marks after each block */ +#define blockhead(b) (cast(char *, b) - HEADER) +#define setsize(newblock, size) (*cast(size_t *, newblock) = size) +#define checkblocksize(b, size) (size == (*cast(size_t *, blockhead(b)))) +#define fillmem(mem,size) memset(mem, -MARK, size) +#else +/* external memory check: don't do it twice */ +#define HEADER 0 +#define MARKSIZE 0 +#define blockhead(b) (b) +#define setsize(newblock, size) /* empty */ +#define checkblocksize(b,size) (1) +#define fillmem(mem,size) /* empty */ +#endif + +unsigned long memdebug_numblocks = 0; +unsigned long memdebug_total = 0; +unsigned long memdebug_maxmem = 0; +unsigned long memdebug_memlimit = ULONG_MAX; + + +static void *checkblock (void *block, size_t size) { + void *b = blockhead(block); + int i; + for (i=0;i 0); + if (size == 0) { + freeblock(block, oldsize); + return NULL; + } + else if (size > oldsize && memdebug_total+size-oldsize > memdebug_memlimit) + return NULL; /* to test memory allocation errors */ + else { + void *newblock; + int i; + size_t realsize = HEADER+size+MARKSIZE; + size_t commonsize = (oldsize < size) ? oldsize : size; + if (realsize < size) return NULL; /* overflow! */ + newblock = malloc(realsize); /* alloc a new block */ + if (newblock == NULL) return NULL; + if (block) { + memcpy(cast(char *, newblock)+HEADER, block, commonsize); + freeblock(block, oldsize); /* erase (and check) old copy */ + } + /* initialize new part of the block with something `weird' */ + fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize); + memdebug_total += size; + if (memdebug_total > memdebug_maxmem) + memdebug_maxmem = memdebug_total; + memdebug_numblocks++; + setsize(newblock, size); + for (i=0;icode[pc]; + OpCode o = GET_OPCODE(i); + const char *name = luaP_opnames[o]; + int line = getline(p, pc); + sprintf(buff, "(%4d) %4d - ", line, pc); + switch (getOpMode(o)) { + case iABC: + sprintf(buff+strlen(buff), "%-12s%4d %4d %4d", name, + GETARG_A(i), GETARG_B(i), GETARG_C(i)); + break; + case iABx: + sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i)); + break; + case iAsBx: + sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_sBx(i)); + break; + } + return buff; +} + + +#if 0 +void luaI_printcode (Proto *pt, int size) { + int pc; + for (pc=0; pcl.p; + lua_newtable(L); + setnameval(L, "maxstack", p->maxstacksize); + setnameval(L, "numparams", p->numparams); + for (pc=0; pcsizecode; pc++) { + char buff[100]; + lua_pushintegral(L, pc+1); + lua_pushstring(L, buildop(p, pc, buff)); + lua_settable(L, -3); + } + return 1; +} + + +static int listk (lua_State *L) { + Proto *p; + int i; + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), + 1, "Lua function expected"); + p = clvalue(func_at(L, 1))->l.p; + lua_newtable(L); + for (i=0; isizek; i++) { + lua_pushintegral(L, i+1); + luaA_pushobject(L, p->k+i); + lua_settable(L, -3); + } + return 1; +} + + +static int listlocals (lua_State *L) { + Proto *p; + int pc = luaL_checkint(L, 2) - 1; + int i = 0; + const char *name; + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), + 1, "Lua function expected"); + p = clvalue(func_at(L, 1))->l.p; + while ((name = luaF_getlocalname(p, ++i, pc)) != NULL) + lua_pushstring(L, name); + return i-1; +} + +/* }====================================================== */ + + + + +static int get_limits (lua_State *L) { + lua_newtable(L); + setnameval(L, "BITS_INT", BITS_INT); + setnameval(L, "LFPF", LFIELDS_PER_FLUSH); + setnameval(L, "MAXVARS", MAXVARS); + setnameval(L, "MAXPARAMS", MAXPARAMS); + setnameval(L, "MAXSTACK", MAXSTACK); + setnameval(L, "MAXUPVALUES", MAXUPVALUES); + return 1; +} + + +static int mem_query (lua_State *L) { + if (lua_isnone(L, 1)) { + lua_pushintegral(L, memdebug_total); + lua_pushintegral(L, memdebug_numblocks); + lua_pushintegral(L, memdebug_maxmem); + return 3; + } + else { + memdebug_memlimit = luaL_checkint(L, 1); + return 0; + } +} + + +static int hash_query (lua_State *L) { + if (lua_isnone(L, 2)) { + luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected"); + lua_pushintegral(L, tsvalue(func_at(L, 1))->tsv.hash); + } + else { + TObject *o = func_at(L, 1); + Table *t; + luaL_checktype(L, 2, LUA_TTABLE); + t = hvalue(func_at(L, 2)); + lua_pushintegral(L, luaH_mainposition(t, o) - t->node); + } + return 1; +} + + +static int stacklevel (lua_State *L) { + unsigned long a = 0; + lua_pushintegral(L, (int)(L->top - L->stack)); + lua_pushintegral(L, (int)(L->stack_last - L->stack)); + lua_pushintegral(L, (int)(L->ci - L->base_ci)); + lua_pushintegral(L, (int)(L->end_ci - L->base_ci)); + lua_pushintegral(L, (unsigned long)&a); + return 5; +} + + +static int table_query (lua_State *L) { + const Table *t; + int i = luaL_optint(L, 2, -1); + luaL_checktype(L, 1, LUA_TTABLE); + t = hvalue(func_at(L, 1)); + if (i == -1) { + lua_pushintegral(L, t->sizearray); + lua_pushintegral(L, sizenode(t)); + lua_pushintegral(L, t->firstfree - t->node); + } + else if (i < t->sizearray) { + lua_pushintegral(L, i); + luaA_pushobject(L, &t->array[i]); + lua_pushnil(L); + } + else if ((i -= t->sizearray) < sizenode(t)) { + if (!ttisnil(gval(gnode(t, i))) || + ttisnil(gkey(gnode(t, i))) || + ttisnumber(gkey(gnode(t, i)))) { + luaA_pushobject(L, gkey(gnode(t, i))); + } + else + lua_pushstring(L, ""); + luaA_pushobject(L, gval(gnode(t, i))); + if (t->node[i].next) + lua_pushintegral(L, t->node[i].next - t->node); + else + lua_pushnil(L); + } + return 3; +} + + +static int string_query (lua_State *L) { + stringtable *tb = &G(L)->strt; + int s = luaL_optint(L, 2, 0) - 1; + if (s==-1) { + lua_pushintegral(L ,tb->nuse); + lua_pushintegral(L ,tb->size); + return 2; + } + else if (s < tb->size) { + GCObject *ts; + int n = 0; + for (ts = tb->hash[s]; ts; ts = ts->gch.next) { + setsvalue2s(L->top, gcotots(ts)); + incr_top(L); + n++; + } + return n; + } + return 0; +} + + +static int tref (lua_State *L) { + int level = lua_gettop(L); + int lock = luaL_optint(L, 2, 1); + luaL_checkany(L, 1); + lua_pushvalue(L, 1); + lua_pushintegral(L, lua_ref(L, lock)); + assert(lua_gettop(L) == level+1); /* +1 for result */ + return 1; +} + +static int getref (lua_State *L) { + int level = lua_gettop(L); + lua_getref(L, luaL_checkint(L, 1)); + assert(lua_gettop(L) == level+1); + return 1; +} + +static int unref (lua_State *L) { + int level = lua_gettop(L); + lua_unref(L, luaL_checkint(L, 1)); + assert(lua_gettop(L) == level); + return 0; +} + +static int metatable (lua_State *L) { + luaL_checkany(L, 1); + if (lua_isnone(L, 2)) { + if (lua_getmetatable(L, 1) == 0) + lua_pushnil(L); + } + else { + lua_settop(L, 2); + luaL_checktype(L, 2, LUA_TTABLE); + lua_setmetatable(L, 1); + } + return 1; +} + + +static int upvalue (lua_State *L) { + int n = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TFUNCTION); + if (lua_isnone(L, 3)) { + const char *name = lua_getupvalue(L, 1, n); + if (name == NULL) return 0; + lua_pushstring(L, name); + return 2; + } + else { + const char *name = lua_setupvalue(L, 1, n); + lua_pushstring(L, name); + return 1; + } +} + + +static int newuserdata (lua_State *L) { + size_t size = luaL_checkint(L, 1); + char *p = cast(char *, lua_newuserdata(L, size)); + while (size--) *p++ = '\0'; + return 1; +} + + +static int pushuserdata (lua_State *L) { + lua_pushlightuserdata(L, cast(void *, luaL_checkint(L, 1))); + return 1; +} + + +static int udataval (lua_State *L) { + lua_pushintegral(L, cast(int, lua_touserdata(L, 1))); + return 1; +} + + +static int doonnewstack (lua_State *L) { + lua_State *L1 = lua_newthread(L); + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + int status = luaL_loadbuffer(L1, s, l, s); + if (status == 0) + status = lua_pcall(L1, 0, 0, 0); + lua_pushintegral(L, status); + return 1; +} + + +static int s2d (lua_State *L) { + lua_pushnumber(L, *cast(const double *, luaL_checkstring(L, 1))); + return 1; +} + +static int d2s (lua_State *L) { + double d = luaL_checknumber(L, 1); + lua_pushlstring(L, cast(char *, &d), sizeof(d)); + return 1; +} + + +static int newstate (lua_State *L) { + lua_State *L1 = lua_open(); + if (L1) { + lua_userstateopen(L1); /* init lock */ + lua_pushintegral(L, (unsigned long)L1); + } + else + lua_pushnil(L); + return 1; +} + + +static int loadlib (lua_State *L) { + static const luaL_reg libs[] = { + {"mathlibopen", luaopen_math}, + {"strlibopen", luaopen_string}, + {"iolibopen", luaopen_io}, + {"tablibopen", luaopen_table}, + {"dblibopen", luaopen_debug}, + {"baselibopen", luaopen_base}, + {NULL, NULL} + }; + lua_State *L1 = cast(lua_State *, + cast(unsigned long, luaL_checknumber(L, 1))); + lua_pushvalue(L1, LUA_GLOBALSINDEX); + luaL_openlib(L1, NULL, libs, 0); + return 0; +} + +static int closestate (lua_State *L) { + lua_State *L1 = cast(lua_State *, cast(unsigned long, luaL_checknumber(L, 1))); + lua_close(L1); + lua_unlock(L); /* close cannot unlock that */ + return 0; +} + +static int doremote (lua_State *L) { + lua_State *L1 = cast(lua_State *,cast(unsigned long,luaL_checknumber(L, 1))); + size_t lcode; + const char *code = luaL_checklstring(L, 2, &lcode); + int status; + lua_settop(L1, 0); + status = luaL_loadbuffer(L1, code, lcode, code); + if (status == 0) + status = lua_pcall(L1, 0, LUA_MULTRET, 0); + if (status != 0) { + lua_pushnil(L); + lua_pushintegral(L, status); + lua_pushstring(L, lua_tostring(L1, -1)); + return 3; + } + else { + int i = 0; + while (!lua_isnone(L1, ++i)) + lua_pushstring(L, lua_tostring(L1, i)); + lua_pop(L1, i-1); + return i-1; + } +} + + +static int log2_aux (lua_State *L) { + lua_pushintegral(L, luaO_log2(luaL_checkint(L, 1))); + return 1; +} + +static int int2fb_aux (lua_State *L) { + int b = luaO_int2fb(luaL_checkint(L, 1)); + lua_pushintegral(L, b); + lua_pushintegral(L, fb2int(b)); + return 2; +} + + +static int test_do (lua_State *L) { + const char *p = luaL_checkstring(L, 1); + if (*p == '@') + lua_dofile(L, p+1); + else + lua_dostring(L, p); + return lua_gettop(L); +} + + + +/* +** {====================================================== +** function to test the API with C. It interprets a kind of assembler +** language with calls to the API, so the test can be driven by Lua code +** ======================================================= +*/ + +static const char *const delimits = " \t\n,;"; + +static void skip (const char **pc) { + while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++; +} + +static int getnum_aux (lua_State *L, const char **pc) { + int res = 0; + int sig = 1; + skip(pc); + if (**pc == '.') { + res = cast(int, lua_tonumber(L, -1)); + lua_pop(L, 1); + (*pc)++; + return res; + } + else if (**pc == '-') { + sig = -1; + (*pc)++; + } + while (isdigit(cast(int, **pc))) res = res*10 + (*(*pc)++) - '0'; + return sig*res; +} + +static const char *getname_aux (char *buff, const char **pc) { + int i = 0; + skip(pc); + while (**pc != '\0' && !strchr(delimits, **pc)) + buff[i++] = *(*pc)++; + buff[i] = '\0'; + return buff; +} + + +#define EQ(s1) (strcmp(s1, inst) == 0) + +#define getnum (getnum_aux(L, &pc)) +#define getname (getname_aux(buff, &pc)) + + +static int testC (lua_State *L) { + char buff[30]; + const char *pc = luaL_checkstring(L, 1); + for (;;) { + const char *inst = getname; + if EQ("") return 0; + else if EQ("isnumber") { + lua_pushintegral(L, lua_isnumber(L, getnum)); + } + else if EQ("isstring") { + lua_pushintegral(L, lua_isstring(L, getnum)); + } + else if EQ("istable") { + lua_pushintegral(L, lua_istable(L, getnum)); + } + else if EQ("iscfunction") { + lua_pushintegral(L, lua_iscfunction(L, getnum)); + } + else if EQ("isfunction") { + lua_pushintegral(L, lua_isfunction(L, getnum)); + } + else if EQ("isuserdata") { + lua_pushintegral(L, lua_isuserdata(L, getnum)); + } + else if EQ("isudataval") { + lua_pushintegral(L, lua_islightuserdata(L, getnum)); + } + else if EQ("isnil") { + lua_pushintegral(L, lua_isnil(L, getnum)); + } + else if EQ("isnull") { + lua_pushintegral(L, lua_isnone(L, getnum)); + } + else if EQ("tonumber") { + lua_pushnumber(L, lua_tonumber(L, getnum)); + } + else if EQ("tostring") { + const char *s = lua_tostring(L, getnum); + lua_pushstring(L, s); + } + else if EQ("strlen") { + lua_pushintegral(L, lua_strlen(L, getnum)); + } + else if EQ("tocfunction") { + lua_pushcfunction(L, lua_tocfunction(L, getnum)); + } + else if EQ("return") { + return getnum; + } + else if EQ("gettop") { + lua_pushintegral(L, lua_gettop(L)); + } + else if EQ("settop") { + lua_settop(L, getnum); + } + else if EQ("pop") { + lua_pop(L, getnum); + } + else if EQ("pushnum") { + lua_pushintegral(L, getnum); + } + else if EQ("pushnil") { + lua_pushnil(L); + } + else if EQ("pushbool") { + lua_pushboolean(L, getnum); + } + else if EQ("tobool") { + lua_pushintegral(L, lua_toboolean(L, getnum)); + } + else if EQ("pushvalue") { + lua_pushvalue(L, getnum); + } + else if EQ("pushcclosure") { + lua_pushcclosure(L, testC, getnum); + } + else if EQ("pushupvalues") { + lua_pushupvalues(L); + } + else if EQ("remove") { + lua_remove(L, getnum); + } + else if EQ("insert") { + lua_insert(L, getnum); + } + else if EQ("replace") { + lua_replace(L, getnum); + } + else if EQ("gettable") { + lua_gettable(L, getnum); + } + else if EQ("settable") { + lua_settable(L, getnum); + } + else if EQ("next") { + lua_next(L, -2); + } + else if EQ("concat") { + lua_concat(L, getnum); + } + else if EQ("lessthan") { + int a = getnum; + lua_pushboolean(L, lua_lessthan(L, a, getnum)); + } + else if EQ("equal") { + int a = getnum; + lua_pushboolean(L, lua_equal(L, a, getnum)); + } + else if EQ("rawcall") { + int narg = getnum; + int nres = getnum; + lua_call(L, narg, nres); + } + else if EQ("call") { + int narg = getnum; + int nres = getnum; + lua_pcall(L, narg, nres, 0); + } + else if EQ("loadstring") { + size_t sl; + const char *s = luaL_checklstring(L, getnum, &sl); + luaL_loadbuffer(L, s, sl, s); + } + else if EQ("loadfile") { + luaL_loadfile(L, luaL_checkstring(L, getnum)); + } + else if EQ("setmetatable") { + lua_setmetatable(L, getnum); + } + else if EQ("getmetatable") { + if (lua_getmetatable(L, getnum) == 0) + lua_pushnil(L); + } + else if EQ("type") { + lua_pushstring(L, lua_typename(L, lua_type(L, getnum))); + } + else if EQ("getn") { + int i = getnum; + lua_pushintegral(L, luaL_getn(L, i)); + } + else if EQ("setn") { + int i = getnum; + int n = cast(int, lua_tonumber(L, -1)); + luaL_setn(L, i, n); + lua_pop(L, 1); + } + else luaL_error(L, "unknown instruction %s", buff); + } + return 0; +} + +/* }====================================================== */ + + +/* +** {====================================================== +** tests for yield inside hooks +** ======================================================= +*/ + +static void yieldf (lua_State *L, lua_Debug *ar) { + lua_yield(L, 0); +} + +static int setyhook (lua_State *L) { + if (lua_isnoneornil(L, 1)) + lua_sethook(L, NULL, 0, 0); /* turn off hooks */ + else { + const char *smask = luaL_checkstring(L, 1); + int count = luaL_optint(L, 2, 0); + int mask = 0; + if (strchr(smask, 'l')) mask |= LUA_MASKLINE; + if (count > 0) mask |= LUA_MASKCOUNT; + lua_sethook(L, yieldf, mask, count); + } + return 0; +} + + +static int coresume (lua_State *L) { + int status; + lua_State *co = lua_tothread(L, 1); + luaL_argcheck(L, co, 1, "coroutine expected"); + status = lua_resume(co, 0); + if (status != 0) { + lua_pushboolean(L, 0); + lua_insert(L, -2); + return 2; /* return false + error message */ + } + else { + lua_pushboolean(L, 1); + return 1; + } +} + +/* }====================================================== */ + + + +static const struct luaL_reg tests_funcs[] = { + {"hash", hash_query}, + {"limits", get_limits}, + {"listcode", listcode}, + {"listk", listk}, + {"listlocals", listlocals}, + {"loadlib", loadlib}, + {"stacklevel", stacklevel}, + {"querystr", string_query}, + {"querytab", table_query}, + {"doit", test_do}, + {"testC", testC}, + {"ref", tref}, + {"getref", getref}, + {"unref", unref}, + {"d2s", d2s}, + {"s2d", s2d}, + {"metatable", metatable}, + {"upvalue", upvalue}, + {"newuserdata", newuserdata}, + {"pushuserdata", pushuserdata}, + {"udataval", udataval}, + {"doonnewstack", doonnewstack}, + {"newstate", newstate}, + {"closestate", closestate}, + {"doremote", doremote}, + {"log2", log2_aux}, + {"int2fb", int2fb_aux}, + {"totalmem", mem_query}, + {"resume", coresume}, + {"setyhook", setyhook}, + {NULL, NULL} +}; + + +static void fim (void) { + if (!islocked) + lua_close(lua_state); + lua_assert(memdebug_numblocks == 0); + lua_assert(memdebug_total == 0); +} + + +static int l_panic (lua_State *L) { + UNUSED(L); + fprintf(stderr, "unable to recover; exiting\n"); + return 0; +} + + +int luaB_opentests (lua_State *L) { + lua_atpanic(L, l_panic); + lua_userstateopen(L); /* init lock */ + lua_state = L; /* keep first state to be opened */ + luaL_openlib(L, "T", tests_funcs, 0); + atexit(fim); + return 0; +} + + +#undef main +int main (int argc, char *argv[]) { + char *limit = getenv("MEMLIMIT"); + if (limit) + memdebug_memlimit = strtoul(limit, NULL, 10); + l_main(argc, argv); + return 0; +} + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/ltm.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/ltm.c new file mode 100644 index 0000000000..1b3e515e57 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/ltm.c @@ -0,0 +1,70 @@ +/* +** $Id: ltm.c,v 1.106 2003/04/03 13:35:34 roberto Exp $ +** Tag methods +** See Copyright Notice in lua.h +*/ + + +#include + +#define ltm_c + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + + +const char *const luaT_typenames[] = { + "nil", "boolean", "userdata", "number", + "string", "table", "function", "userdata", "thread" +}; + + +void luaT_init (lua_State *L) { + static const char *const luaT_eventname[] = { /* ORDER TM */ + "__index", "__newindex", + "__gc", "__mode", "__eq", + "__add", "__sub", "__mul", "__div", + "__pow", "__unm", "__lt", "__le", + "__concat", "__call" + }; + int i; + for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); + luaS_fix(G(L)->tmname[i]); /* never collect these names */ + } +} + + +/* +** function to be used with macro "fasttm": optimized for absence of +** tag methods +*/ +const TObject *luaT_gettm (Table *events, TMS event, TString *ename) { + const TObject *tm = luaH_getstr(events, ename); + lua_assert(event <= TM_EQ); + if (ttisnil(tm)) { /* no tag method? */ + events->flags |= cast(lu_byte, 1u<tmname[event]; + switch (ttype(o)) { + case LUA_TTABLE: + return luaH_getstr(hvalue(o)->metatable, ename); + case LUA_TUSERDATA: + return luaH_getstr(uvalue(o)->uv.metatable, ename); + default: + return &luaO_nilobject; + } +} + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/ltm.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/ltm.h new file mode 100644 index 0000000000..8eebfd3dc3 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/ltm.h @@ -0,0 +1,51 @@ +/* +** $Id: ltm.h,v 1.41 2002/11/14 11:51:50 roberto Exp $ +** Tag methods +** See Copyright Notice in lua.h +*/ + +#ifndef ltm_h +#define ltm_h + + +#include "lobject.h" + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER TM" +*/ +typedef enum { + TM_INDEX, + TM_NEWINDEX, + TM_GC, + TM_MODE, + TM_EQ, /* last tag method with `fast' access */ + TM_ADD, + TM_SUB, + TM_MUL, + TM_DIV, + TM_POW, + TM_UNM, + TM_LT, + TM_LE, + TM_CONCAT, + TM_CALL, + TM_N /* number of elements in the enum */ +} TMS; + + + +#define gfasttm(g,et,e) \ + (((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) + +#define fasttm(l,et,e) gfasttm(G(l), et, e) + + +const TObject *luaT_gettm (Table *events, TMS event, TString *ename); +const TObject *luaT_gettmbyobj (lua_State *L, const TObject *o, TMS event); +void luaT_init (lua_State *L); + +extern const char *const luaT_typenames[]; + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lua.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/lua.h new file mode 100644 index 0000000000..0d827b10c7 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lua.h @@ -0,0 +1,391 @@ +/* +** $Id: lua.h,v 1.175 2003/03/18 12:31:39 roberto Exp $ +** Lua - An Extensible Extension Language +** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil +** http://www.lua.org mailto:info@lua.org +** See Copyright Notice at the end of this file +*/ + + +#ifndef lua_h +#define lua_h + +#include +#include + + +#define LUA_VERSION "Lua 5.0" +#define LUA_COPYRIGHT "Copyright (C) 1994-2003 Tecgraf, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" + + + +/* option for multiple returns in `lua_pcall' and `lua_call' */ +#define LUA_MULTRET (-1) + + +/* +** pseudo-indices +*/ +#define LUA_REGISTRYINDEX (-10000) +#define LUA_GLOBALSINDEX (-10001) +#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) + + +/* error codes for `lua_load' and `lua_pcall' */ +#define LUA_ERRRUN 1 +#define LUA_ERRFILE 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRERR 5 + + +typedef struct lua_State lua_State; + +typedef int (*lua_CFunction) (lua_State *L); + + +/* +** functions that read/write blocks when loading/dumping Lua chunks +*/ +typedef const char * (*lua_Chunkreader) (lua_State *L, void *ud, size_t *sz); + +typedef int (*lua_Chunkwriter) (lua_State *L, const void* p, + size_t sz, void* ud); + + +/* +** basic types +*/ +#define LUA_TNONE (-1) + +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 + + +/* minimum Lua stack available to a C function */ +#define LUA_MINSTACK 20 + + +/* +** generic extra include file +*/ +#ifdef LUA_USER_H +#include LUA_USER_H +#endif + + +/* type of numbers in Lua */ +#ifndef LUA_NUMBER +typedef double lua_Number; +#else +typedef LUA_NUMBER lua_Number; +#endif + + +/* mark for all API functions */ +#ifndef LUA_API +#define LUA_API extern +#endif + + +/* +** state manipulation +*/ +LUA_API lua_State *lua_open (void); +LUA_API void lua_close (lua_State *L); +LUA_API lua_State *lua_newthread (lua_State *L); + +LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf); + + +/* +** basic stack manipulation +*/ +LUA_API int lua_gettop (lua_State *L); +LUA_API void lua_settop (lua_State *L, int idx); +LUA_API void lua_pushvalue (lua_State *L, int idx); +LUA_API void lua_remove (lua_State *L, int idx); +LUA_API void lua_insert (lua_State *L, int idx); +LUA_API void lua_replace (lua_State *L, int idx); +LUA_API int lua_checkstack (lua_State *L, int sz); + +LUA_API void lua_xmove (lua_State *from, lua_State *to, int n); + + +/* +** access functions (stack -> C) +*/ + +LUA_API int lua_isnumber (lua_State *L, int idx); +LUA_API int lua_isstring (lua_State *L, int idx); +LUA_API int lua_iscfunction (lua_State *L, int idx); +LUA_API int lua_isuserdata (lua_State *L, int idx); +LUA_API int lua_type (lua_State *L, int idx); +LUA_API const char *lua_typename (lua_State *L, int tp); + +LUA_API int lua_equal (lua_State *L, int idx1, int idx2); +LUA_API int lua_rawequal (lua_State *L, int idx1, int idx2); +LUA_API int lua_lessthan (lua_State *L, int idx1, int idx2); + +LUA_API lua_Number lua_tonumber (lua_State *L, int idx); +LUA_API int lua_toboolean (lua_State *L, int idx); +LUA_API const char *lua_tostring (lua_State *L, int idx); +LUA_API size_t lua_strlen (lua_State *L, int idx); +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx); +LUA_API void *lua_touserdata (lua_State *L, int idx); +LUA_API lua_State *lua_tothread (lua_State *L, int idx); +LUA_API const void *lua_topointer (lua_State *L, int idx); + + +/* +** push functions (C -> stack) +*/ +LUA_API void lua_pushnil (lua_State *L); +LUA_API void lua_pushnumber (lua_State *L, lua_Number n); +LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t l); +LUA_API void lua_pushstring (lua_State *L, const char *s); +LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, + va_list argp); +LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...); +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); +LUA_API void lua_pushboolean (lua_State *L, int b); +LUA_API void lua_pushlightuserdata (lua_State *L, void *p); + + +/* +** get functions (Lua -> stack) +*/ +LUA_API void lua_gettable (lua_State *L, int idx); +LUA_API void lua_rawget (lua_State *L, int idx); +LUA_API void lua_rawgeti (lua_State *L, int idx, int n); +LUA_API void lua_newtable (lua_State *L); +LUA_API void *lua_newuserdata (lua_State *L, size_t sz); +LUA_API int lua_getmetatable (lua_State *L, int objindex); +LUA_API void lua_getfenv (lua_State *L, int idx); + + +/* +** set functions (stack -> Lua) +*/ +LUA_API void lua_settable (lua_State *L, int idx); +LUA_API void lua_rawset (lua_State *L, int idx); +LUA_API void lua_rawseti (lua_State *L, int idx, int n); +LUA_API int lua_setmetatable (lua_State *L, int objindex); +LUA_API int lua_setfenv (lua_State *L, int idx); + + +/* +** `load' and `call' functions (load and run Lua code) +*/ +LUA_API void lua_call (lua_State *L, int nargs, int nresults); +LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc); +LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud); +LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *dt, + const char *chunkname); + +LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data); + + +/* +** coroutine functions +*/ +LUA_API int lua_yield (lua_State *L, int nresults); +LUA_API int lua_resume (lua_State *L, int narg); + +/* +** garbage-collection functions +*/ +LUA_API int lua_getgcthreshold (lua_State *L); +LUA_API int lua_getgccount (lua_State *L); +LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold); + +/* +** miscellaneous functions +*/ + +LUA_API const char *lua_version (void); + +LUA_API int lua_error (lua_State *L); + +LUA_API int lua_next (lua_State *L, int idx); + +LUA_API void lua_concat (lua_State *L, int n); + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define lua_boxpointer(L,u) \ + (*(void **)(lua_newuserdata(L, sizeof(void *))) = (u)) + +#define lua_unboxpointer(L,i) (*(void **)(lua_touserdata(L, i))) + +#define lua_pop(L,n) lua_settop(L, -(n)-1) + +#define lua_register(L,n,f) \ + (lua_pushstring(L, n), \ + lua_pushcfunction(L, f), \ + lua_settable(L, LUA_GLOBALSINDEX)) + +#define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0) + +#define lua_isfunction(L,n) (lua_type(L,n) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L,n) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L,n) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L,n) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L,n) == LUA_TBOOLEAN) +#define lua_isnone(L,n) (lua_type(L,n) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L,n) <= 0) + +#define lua_pushliteral(L, s) \ + lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) + + + +/* +** compatibility macros and functions +*/ + + +LUA_API int lua_pushupvalues (lua_State *L); + +#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) +#define lua_setglobal(L,s) \ + (lua_pushstring(L, s), lua_insert(L, -2), lua_settable(L, LUA_GLOBALSINDEX)) + +#define lua_getglobal(L,s) \ + (lua_pushstring(L, s), lua_gettable(L, LUA_GLOBALSINDEX)) + + +/* compatibility with ref system */ + +/* pre-defined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + +#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ + (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) + +#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) + +#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, ref) + + + +/* +** {====================================================================== +** useful definitions for Lua kernel and libraries +** ======================================================================= +*/ + +/* formats for Lua numbers */ +#ifndef LUA_NUMBER_SCAN +#define LUA_NUMBER_SCAN "%lf" +#endif + +#ifndef LUA_NUMBER_FMT +#define LUA_NUMBER_FMT "%.14g" +#endif + +/* }====================================================================== */ + + +/* +** {====================================================================== +** Debug API +** ======================================================================= +*/ + + +/* +** Event codes +*/ +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 +#define LUA_HOOKTAILRET 4 + + +/* +** Event masks +*/ +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) + +typedef struct lua_Debug lua_Debug; /* activation record */ + +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); + +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); +LUA_API lua_Hook lua_gethook (lua_State *L); +LUA_API int lua_gethookmask (lua_State *L); +LUA_API int lua_gethookcount (lua_State *L); + + +#define LUA_IDSIZE 60 + +struct lua_Debug { + int event; + const char *name; /* (n) */ + const char *namewhat; /* (n) `global', `local', `field', `method' */ + const char *what; /* (S) `Lua', `C', `main', `tail' */ + const char *source; /* (S) */ + int currentline; /* (l) */ + int nups; /* (u) number of upvalues */ + int linedefined; /* (S) */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + int i_ci; /* active function */ +}; + +/* }====================================================================== */ + + +/****************************************************************************** +* Copyright (C) 1994-2003 Tecgraf, PUC-Rio. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +******************************************************************************/ + + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/luainc.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/luainc.h new file mode 100644 index 0000000000..1306197b64 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/luainc.h @@ -0,0 +1,12 @@ + +#ifndef __LUA_INC_H__ +#define __LUA_INC_H__ + +extern "C" +{ + #include "lualib/lua.h" + #include "lualib/lauxlib.h" + #include "lualib/lualib.h" +} + +#endif // __LUA_INC_H__ \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lualib.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/lualib.h new file mode 100644 index 0000000000..e22c4c3063 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lualib.h @@ -0,0 +1,56 @@ +/* +** $Id: lualib.h,v 1.28 2003/03/18 12:24:26 roberto Exp $ +** Lua standard libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lualib_h +#define lualib_h + +#include "lua.h" + + +#ifndef LUALIB_API +#define LUALIB_API LUA_API +#endif + + +#define LUA_COLIBNAME "coroutine" +LUALIB_API int luaopen_base (lua_State *L); + +#define LUA_TABLIBNAME "table" +LUALIB_API int luaopen_table (lua_State *L); + +#define LUA_IOLIBNAME "io" +#define LUA_OSLIBNAME "os" +LUALIB_API int luaopen_io (lua_State *L); + +#define LUA_STRLIBNAME "string" +LUALIB_API int luaopen_string (lua_State *L); + +#define LUA_MATHLIBNAME "math" +LUALIB_API int luaopen_math (lua_State *L); + +#define LUA_DBLIBNAME "debug" +LUALIB_API int luaopen_debug (lua_State *L); + + +LUALIB_API int luaopen_loadlib (lua_State *L); + + +/* to help testing the libraries */ +#ifndef lua_assert +#define lua_assert(c) /* empty */ +#endif + + +/* compatibility code */ +#define lua_baselibopen luaopen_base +#define lua_tablibopen luaopen_table +#define lua_iolibopen luaopen_io +#define lua_strlibopen luaopen_string +#define lua_mathlibopen luaopen_math +#define lua_dblibopen luaopen_debug + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lualib.vcxproj b/plugins/!NotAdopted/SmartAutoReplier/lualib/lualib.vcxproj new file mode 100644 index 0000000000..b7618412cf --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lualib.vcxproj @@ -0,0 +1,138 @@ +п»ї + + + + Debug + Win32 + + + Release + Win32 + + + + {6DB53D29-2EA9-407B-84F3-06E8031F3314} + Win32Proj + lualib + + + + StaticLibrary + true + Unicode + + + StaticLibrary + false + true + Unicode + + + + + + + + + + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB + MultiThreadedDebug + + + Windows + true + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + MultiThreaded + + + Windows + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + + + + + + \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lualib.vcxproj.filters b/plugins/!NotAdopted/SmartAutoReplier/lualib/lualib.vcxproj.filters new file mode 100644 index 0000000000..a224003846 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lualib.vcxproj.filters @@ -0,0 +1,186 @@ +п»ї + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lundump.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/lundump.c new file mode 100644 index 0000000000..151a8507cc --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lundump.c @@ -0,0 +1,286 @@ +/* +** $Id: lundump.c,v 1.49 2003/04/07 20:34:20 lhf Exp $ +** load pre-compiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#define lundump_c + +#include "lua.h" + +#include "ldebug.h" +#include "lfunc.h" +#include "lmem.h" +#include "lopcodes.h" +#include "lstring.h" +#include "lundump.h" +#include "lzio.h" + +#define LoadByte (lu_byte) ezgetc + +typedef struct { + lua_State* L; + ZIO* Z; + Mbuffer* b; + int swap; + const char* name; +} LoadState; + +static void unexpectedEOZ (LoadState* S) +{ + luaG_runerror(S->L,"unexpected end of file in %s",S->name); +} + +static int ezgetc (LoadState* S) +{ + int c=zgetc(S->Z); + if (c==EOZ) unexpectedEOZ(S); + return c; +} + +static void ezread (LoadState* S, void* b, int n) +{ + int r=luaZ_read(S->Z,b,n); + if (r!=0) unexpectedEOZ(S); +} + +static void LoadBlock (LoadState* S, void* b, size_t size) +{ + if (S->swap) + { + char* p=(char*) b+size-1; + int n=size; + while (n--) *p--=(char)ezgetc(S); + } + else + ezread(S,b,size); +} + +static void LoadVector (LoadState* S, void* b, int m, size_t size) +{ + if (S->swap) + { + char* q=(char*) b; + while (m--) + { + char* p=q+size-1; + int n=size; + while (n--) *p--=(char)ezgetc(S); + q+=size; + } + } + else + ezread(S,b,m*size); +} + +static int LoadInt (LoadState* S) +{ + int x; + LoadBlock(S,&x,sizeof(x)); + if (x<0) luaG_runerror(S->L,"bad integer in %s",S->name); + return x; +} + +static size_t LoadSize (LoadState* S) +{ + size_t x; + LoadBlock(S,&x,sizeof(x)); + return x; +} + +static lua_Number LoadNumber (LoadState* S) +{ + lua_Number x; + LoadBlock(S,&x,sizeof(x)); + return x; +} + +static TString* LoadString (LoadState* S) +{ + size_t size=LoadSize(S); + if (size==0) + return NULL; + else + { + char* s=luaZ_openspace(S->L,S->b,size); + ezread(S,s,size); + return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ + } +} + +static void LoadCode (LoadState* S, Proto* f) +{ + int size=LoadInt(S); + f->code=luaM_newvector(S->L,size,Instruction); + f->sizecode=size; + LoadVector(S,f->code,size,sizeof(*f->code)); +} + +static void LoadLocals (LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->locvars=luaM_newvector(S->L,n,LocVar); + f->sizelocvars=n; + for (i=0; ilocvars[i].varname=LoadString(S); + f->locvars[i].startpc=LoadInt(S); + f->locvars[i].endpc=LoadInt(S); + } +} + +static void LoadLines (LoadState* S, Proto* f) +{ + int size=LoadInt(S); + f->lineinfo=luaM_newvector(S->L,size,int); + f->sizelineinfo=size; + LoadVector(S,f->lineinfo,size,sizeof(*f->lineinfo)); +} + +static void LoadUpvalues (LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + if (n!=0 && n!=f->nups) + luaG_runerror(S->L,"bad nupvalues in %s: read %d; expected %d", + S->name,n,f->nups); + f->upvalues=luaM_newvector(S->L,n,TString*); + f->sizeupvalues=n; + for (i=0; iupvalues[i]=LoadString(S); +} + +static Proto* LoadFunction (LoadState* S, TString* p); + +static void LoadConstants (LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->k=luaM_newvector(S->L,n,TObject); + f->sizek=n; + for (i=0; ik[i]; + int t=LoadByte(S); + switch (t) + { + case LUA_TNUMBER: + setnvalue(o,LoadNumber(S)); + break; + case LUA_TSTRING: + setsvalue2n(o,LoadString(S)); + break; + case LUA_TNIL: + setnilvalue(o); + break; + default: + luaG_runerror(S->L,"bad constant type (%d) in %s",t,S->name); + break; + } + } + n=LoadInt(S); + f->p=luaM_newvector(S->L,n,Proto*); + f->sizep=n; + for (i=0; ip[i]=LoadFunction(S,f->source); +} + +static Proto* LoadFunction (LoadState* S, TString* p) +{ + Proto* f=luaF_newproto(S->L); + f->source=LoadString(S); if (f->source==NULL) f->source=p; + f->lineDefined=LoadInt(S); + f->nups=LoadByte(S); + f->numparams=LoadByte(S); + f->is_vararg=LoadByte(S); + f->maxstacksize=LoadByte(S); + LoadLines(S,f); + LoadLocals(S,f); + LoadUpvalues(S,f); + LoadConstants(S,f); + LoadCode(S,f); +#ifndef TRUST_BINARIES + if (!luaG_checkcode(f)) luaG_runerror(S->L,"bad code in %s",S->name); +#endif + return f; +} + +static void LoadSignature (LoadState* S) +{ + const char* s=LUA_SIGNATURE; + while (*s!=0 && ezgetc(S)==*s) + ++s; + if (*s!=0) luaG_runerror(S->L,"bad signature in %s",S->name); +} + +static void TestSize (LoadState* S, int s, const char* what) +{ + int r=LoadByte(S); + if (r!=s) + luaG_runerror(S->L,"virtual machine mismatch in %s: " + "size of %s is %d but read %d",S->name,what,s,r); +} + +#define TESTSIZE(s,w) TestSize(S,s,w) +#define V(v) v/16,v%16 + +static void LoadHeader (LoadState* S) +{ + int version; + lua_Number x,tx=TEST_NUMBER; + LoadSignature(S); + version=LoadByte(S); + if (version>VERSION) + luaG_runerror(S->L,"%s too new: " + "read version %d.%d; expected at most %d.%d", + S->name,V(version),V(VERSION)); + if (versionL,"%s too old: " + "read version %d.%d; expected at least %d.%d", + S->name,V(version),V(VERSION0)); + S->swap=(luaU_endianness()!=LoadByte(S)); /* need to swap bytes? */ + TESTSIZE(sizeof(int),"int"); + TESTSIZE(sizeof(size_t), "size_t"); + TESTSIZE(sizeof(Instruction), "Instruction"); + TESTSIZE(SIZE_OP, "OP"); + TESTSIZE(SIZE_A, "A"); + TESTSIZE(SIZE_B, "B"); + TESTSIZE(SIZE_C, "C"); + TESTSIZE(sizeof(lua_Number), "number"); + x=LoadNumber(S); + if ((long)x!=(long)tx) /* disregard errors in last bits of fraction */ + luaG_runerror(S->L,"unknown number format in %s",S->name); +} + +static Proto* LoadChunk (LoadState* S) +{ + LoadHeader(S); + return LoadFunction(S,NULL); +} + +/* +** load precompiled chunk +*/ +Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff) +{ + LoadState S; + const char* s=zname(Z); + if (*s=='@' || *s=='=') + S.name=s+1; + else if (*s==LUA_SIGNATURE[0]) + S.name="binary string"; + else + S.name=s; + S.L=L; + S.Z=Z; + S.b=buff; + return LoadChunk(&S); +} + +/* +** find byte order +*/ +int luaU_endianness (void) +{ + int x=1; + return *(char*)&x; +} diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lundump.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/lundump.h new file mode 100644 index 0000000000..c7e6959b30 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lundump.h @@ -0,0 +1,34 @@ +/* +** $Id: lundump.h,v 1.30 2003/04/07 20:34:20 lhf Exp $ +** load pre-compiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#ifndef lundump_h +#define lundump_h + +#include "lobject.h" +#include "lzio.h" + +/* load one chunk; from lundump.c */ +Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff); + +/* find byte order; from lundump.c */ +int luaU_endianness (void); + +/* dump one chunk; from ldump.c */ +void luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data); + +/* print one chunk; from print.c */ +void luaU_print (const Proto* Main); + +/* definitions for headers of binary files */ +#define LUA_SIGNATURE "\033Lua" /* binary files start with "Lua" */ +#define VERSION 0x50 /* last format change was in 5.0 */ +#define VERSION0 0x50 /* last major change was in 5.0 */ + +/* a multiple of PI for testing native format */ +/* multiplying by 1E7 gives non-trivial integer values */ +#define TEST_NUMBER ((lua_Number)3.14159265358979323846E7) + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lvm.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/lvm.c new file mode 100644 index 0000000000..eaa5c700b0 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lvm.c @@ -0,0 +1,780 @@ +/* +** $Id: lvm.c,v 1.284 2003/04/03 13:35:34 roberto Exp $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +/* needed only when `lua_number2str' uses `sprintf' */ +#include + +#define lvm_c + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +/* function to convert a lua_Number to a string */ +#ifndef lua_number2str +#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) +#endif + + +/* limit for table tag-method chains (to avoid loops) */ +#define MAXTAGLOOP 100 + + +const TObject *luaV_tonumber (const TObject *obj, TObject *n) { + lua_Number num; + if (ttisnumber(obj)) return obj; + if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { + setnvalue(n, num); + return n; + } + else + return NULL; +} + + +int luaV_tostring (lua_State *L, StkId obj) { + if (!ttisnumber(obj)) + return 0; + else { + char s[32]; /* 16 digits, sign, point and \0 (+ some extra...) */ + lua_number2str(s, nvalue(obj)); + setsvalue2s(obj, luaS_new(L, s)); + return 1; + } +} + + +static void traceexec (lua_State *L) { + lu_byte mask = L->hookmask; + if (mask > LUA_MASKLINE) { /* instruction-hook set? */ + if (L->hookcount == 0) { + resethookcount(L); + luaD_callhook(L, LUA_HOOKCOUNT, -1); + return; + } + } + if (mask & LUA_MASKLINE) { + CallInfo *ci = L->ci; + Proto *p = ci_func(ci)->l.p; + int newline = getline(p, pcRel(*ci->u.l.pc, p)); + if (!L->hookinit) { + luaG_inithooks(L); + return; + } + lua_assert(ci->state & CI_HASFRAME); + if (pcRel(*ci->u.l.pc, p) == 0) /* tracing may be starting now? */ + ci->u.l.savedpc = *ci->u.l.pc; /* initialize `savedpc' */ + /* calls linehook when enters a new line or jumps back (loop) */ + if (*ci->u.l.pc <= ci->u.l.savedpc || + newline != getline(p, pcRel(ci->u.l.savedpc, p))) { + luaD_callhook(L, LUA_HOOKLINE, newline); + ci = L->ci; /* previous call may reallocate `ci' */ + } + ci->u.l.savedpc = *ci->u.l.pc; + } +} + + +static void callTMres (lua_State *L, const TObject *f, + const TObject *p1, const TObject *p2) { + setobj2s(L->top, f); /* push function */ + setobj2s(L->top+1, p1); /* 1st argument */ + setobj2s(L->top+2, p2); /* 2nd argument */ + luaD_checkstack(L, 3); /* cannot check before (could invalidate p1, p2) */ + L->top += 3; + luaD_call(L, L->top - 3, 1); + L->top--; /* result will be in L->top */ +} + + + +static void callTM (lua_State *L, const TObject *f, + const TObject *p1, const TObject *p2, const TObject *p3) { + setobj2s(L->top, f); /* push function */ + setobj2s(L->top+1, p1); /* 1st argument */ + setobj2s(L->top+2, p2); /* 2nd argument */ + setobj2s(L->top+3, p3); /* 3th argument */ + luaD_checkstack(L, 4); /* cannot check before (could invalidate p1...p3) */ + L->top += 4; + luaD_call(L, L->top - 4, 0); +} + + +static const TObject *luaV_index (lua_State *L, const TObject *t, + TObject *key, int loop) { + const TObject *tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); + if (tm == NULL) return &luaO_nilobject; /* no TM */ + if (ttisfunction(tm)) { + callTMres(L, tm, t, key); + return L->top; + } + else return luaV_gettable(L, tm, key, loop); +} + +static const TObject *luaV_getnotable (lua_State *L, const TObject *t, + TObject *key, int loop) { + const TObject *tm = luaT_gettmbyobj(L, t, TM_INDEX); + if (ttisnil(tm)) + luaG_typeerror(L, t, "index"); + if (ttisfunction(tm)) { + callTMres(L, tm, t, key); + return L->top; + } + else return luaV_gettable(L, tm, key, loop); +} + + +/* +** Function to index a table. +** Receives the table at `t' and the key at `key'. +** leaves the result at `res'. +*/ +const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key, + int loop) { + if (loop > MAXTAGLOOP) + luaG_runerror(L, "loop in gettable"); + if (ttistable(t)) { /* `t' is a table? */ + Table *h = hvalue(t); + const TObject *v = luaH_get(h, key); /* do a primitive get */ + if (!ttisnil(v)) return v; + else return luaV_index(L, t, key, loop+1); + } + else return luaV_getnotable(L, t, key, loop+1); +} + + +/* +** Receives table at `t', key at `key' and value at `val'. +*/ +void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val) { + const TObject *tm; + int loop = 0; + do { + if (ttistable(t)) { /* `t' is a table? */ + Table *h = hvalue(t); + TObject *oldval = luaH_set(L, h, key); /* do a primitive set */ + if (!ttisnil(oldval) || /* result is no nil? */ + (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ + setobj2t(oldval, val); /* write barrier */ + return; + } + /* else will try the tag method */ + } + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) + luaG_typeerror(L, t, "index"); + if (ttisfunction(tm)) { + callTM(L, tm, t, key, val); + return; + } + t = tm; /* else repeat with `tm' */ + } while (++loop <= MAXTAGLOOP); + luaG_runerror(L, "loop in settable"); +} + + +static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2, + StkId res, TMS event) { + ptrdiff_t result = savestack(L, res); + const TObject *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ + if (ttisnil(tm)) + tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ + if (!ttisfunction(tm)) return 0; + callTMres(L, tm, p1, p2); + res = restorestack(L, result); /* previous call may change stack */ + setobjs2s(res, L->top); + return 1; +} + + +static const TObject *get_compTM (lua_State *L, Table *mt1, Table *mt2, + TMS event) { + const TObject *tm1 = fasttm(L, mt1, event); + const TObject *tm2; + if (tm1 == NULL) return NULL; /* no metamethod */ + if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ + tm2 = fasttm(L, mt2, event); + if (tm2 == NULL) return NULL; /* no metamethod */ + if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */ + return tm1; + return NULL; +} + + +static int call_orderTM (lua_State *L, const TObject *p1, const TObject *p2, + TMS event) { + const TObject *tm1 = luaT_gettmbyobj(L, p1, event); + const TObject *tm2; + if (ttisnil(tm1)) return -1; /* no metamethod? */ + tm2 = luaT_gettmbyobj(L, p2, event); + if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ + return -1; + callTMres(L, tm1, p1, p2); + return !l_isfalse(L->top); +} + + +static int luaV_strcmp (const TString *ls, const TString *rs) { + const char *l = getstr(ls); + size_t ll = ls->tsv.len; + const char *r = getstr(rs); + size_t lr = rs->tsv.len; + for (;;) { + int temp = strcoll(l, r); + if (temp != 0) return temp; + else { /* strings are equal up to a `\0' */ + size_t len = strlen(l); /* index of first `\0' in both strings */ + if (len == lr) /* r is finished? */ + return (len == ll) ? 0 : 1; + else if (len == ll) /* l is finished? */ + return -1; /* l is smaller than r (because r is not finished) */ + /* both strings longer than `len'; go on comparing (after the `\0') */ + len++; + l += len; ll -= len; r += len; lr -= len; + } + } +} + + +int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) { + int res; + if (ttype(l) != ttype(r)) + return luaG_ordererror(L, l, r); + else if (ttisnumber(l)) + return nvalue(l) < nvalue(r); + else if (ttisstring(l)) + return luaV_strcmp(tsvalue(l), tsvalue(r)) < 0; + else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) + return res; + return luaG_ordererror(L, l, r); +} + + +static int luaV_lessequal (lua_State *L, const TObject *l, const TObject *r) { + int res; + if (ttype(l) != ttype(r)) + return luaG_ordererror(L, l, r); + else if (ttisnumber(l)) + return nvalue(l) <= nvalue(r); + else if (ttisstring(l)) + return luaV_strcmp(tsvalue(l), tsvalue(r)) <= 0; + else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ + return res; + else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ + return !res; + return luaG_ordererror(L, l, r); +} + + +int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2) { + const TObject *tm; + lua_assert(ttype(t1) == ttype(t2)); + switch (ttype(t1)) { + case LUA_TNIL: return 1; + case LUA_TNUMBER: return nvalue(t1) == nvalue(t2); + case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ + case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); + case LUA_TUSERDATA: { + if (uvalue(t1) == uvalue(t2)) return 1; + tm = get_compTM(L, uvalue(t1)->uv.metatable, uvalue(t2)->uv.metatable, + TM_EQ); + break; /* will try TM */ + } + case LUA_TTABLE: { + if (hvalue(t1) == hvalue(t2)) return 1; + tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + default: return gcvalue(t1) == gcvalue(t2); + } + if (tm == NULL) return 0; /* no TM? */ + callTMres(L, tm, t1, t2); /* call TM */ + return !l_isfalse(L->top); +} + + +void luaV_concat (lua_State *L, int total, int last) { + do { + StkId top = L->base + last + 1; + int n = 2; /* number of elements handled in this pass (at least 2) */ + if (!tostring(L, top-2) || !tostring(L, top-1)) { + if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) + luaG_concaterror(L, top-2, top-1); + } else if (tsvalue(top-1)->tsv.len > 0) { /* if len=0, do nothing */ + /* at least two string values; get as many as possible */ + lu_mem tl = cast(lu_mem, tsvalue(top-1)->tsv.len) + + cast(lu_mem, tsvalue(top-2)->tsv.len); + char *buffer; + int i; + while (n < total && tostring(L, top-n-1)) { /* collect total length */ + tl += tsvalue(top-n-1)->tsv.len; + n++; + } + if (tl > MAX_SIZET) luaG_runerror(L, "string size overflow"); + buffer = luaZ_openspace(L, &G(L)->buff, tl); + tl = 0; + for (i=n; i>0; i--) { /* concat all strings */ + size_t l = tsvalue(top-i)->tsv.len; + memcpy(buffer+tl, svalue(top-i), l); + tl += l; + } + setsvalue2s(top-n, luaS_newlstr(L, buffer, tl)); + } + total -= n-1; /* got `n' strings to create 1 new */ + last -= n-1; + } while (total > 1); /* repeat until only 1 result left */ +} + + +static void Arith (lua_State *L, StkId ra, + const TObject *rb, const TObject *rc, TMS op) { + TObject tempb, tempc; + const TObject *b, *c; + if ((b = luaV_tonumber(rb, &tempb)) != NULL && + (c = luaV_tonumber(rc, &tempc)) != NULL) { + switch (op) { + case TM_ADD: setnvalue(ra, nvalue(b) + nvalue(c)); break; + case TM_SUB: setnvalue(ra, nvalue(b) - nvalue(c)); break; + case TM_MUL: setnvalue(ra, nvalue(b) * nvalue(c)); break; + case TM_DIV: setnvalue(ra, nvalue(b) / nvalue(c)); break; + case TM_POW: { + const TObject *f = luaH_getstr(hvalue(gt(L)), G(L)->tmname[TM_POW]); + ptrdiff_t res = savestack(L, ra); + if (!ttisfunction(f)) + luaG_runerror(L, "`__pow' (`^' operator) is not a function"); + callTMres(L, f, b, c); + ra = restorestack(L, res); /* previous call may change stack */ + setobjs2s(ra, L->top); + break; + } + default: lua_assert(0); break; + } + } + else if (!call_binTM(L, rb, rc, ra, op)) + luaG_aritherror(L, rb, rc); +} + + + +/* +** some macros for common tasks in `luaV_execute' +*/ + +#define runtime_check(L, c) { if (!(c)) return 0; } + +#define RA(i) (base+GETARG_A(i)) +/* to be used after possible stack reallocation */ +#define XRA(i) (L->base+GETARG_A(i)) +#define RB(i) (base+GETARG_B(i)) +#define RKB(i) ((GETARG_B(i) < MAXSTACK) ? RB(i) : k+GETARG_B(i)-MAXSTACK) +#define RC(i) (base+GETARG_C(i)) +#define RKC(i) ((GETARG_C(i) < MAXSTACK) ? RC(i) : k+GETARG_C(i)-MAXSTACK) +#define KBx(i) (k+GETARG_Bx(i)) + + +#define dojump(pc, i) ((pc) += (i)) + + +StkId luaV_execute (lua_State *L) { + LClosure *cl; + TObject *k; + const Instruction *pc; + callentry: /* entry point when calling new functions */ + L->ci->u.l.pc = &pc; + if (L->hookmask & LUA_MASKCALL) + luaD_callhook(L, LUA_HOOKCALL, -1); + retentry: /* entry point when returning to old functions */ + lua_assert(L->ci->state == CI_SAVEDPC || + L->ci->state == (CI_SAVEDPC | CI_CALLING)); + L->ci->state = CI_HASFRAME; /* activate frame */ + pc = L->ci->u.l.savedpc; + cl = &clvalue(L->base - 1)->l; + k = cl->p->k; + /* main loop of interpreter */ + for (;;) { + const Instruction i = *pc++; + StkId base, ra; + if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && + (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { + traceexec(L); + if (L->ci->state & CI_YIELD) { /* did hook yield? */ + L->ci->u.l.savedpc = pc - 1; + L->ci->state = CI_YIELD | CI_SAVEDPC; + return NULL; + } + } + /* warning!! several calls may realloc the stack and invalidate `ra' */ + base = L->base; + ra = RA(i); + lua_assert(L->ci->state & CI_HASFRAME); + lua_assert(base == L->ci->base); + lua_assert(L->top <= L->stack + L->stacksize && L->top >= base); + lua_assert(L->top == L->ci->top || + GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || + GET_OPCODE(i) == OP_RETURN || GET_OPCODE(i) == OP_SETLISTO); + switch (GET_OPCODE(i)) { + case OP_MOVE: { + setobjs2s(ra, RB(i)); + break; + } + case OP_LOADK: { + setobj2s(ra, KBx(i)); + break; + } + case OP_LOADBOOL: { + setbvalue(ra, GETARG_B(i)); + if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ + break; + } + case OP_LOADNIL: { + TObject *rb = RB(i); + do { + setnilvalue(rb--); + } while (rb >= ra); + break; + } + case OP_GETUPVAL: { + int b = GETARG_B(i); + setobj2s(ra, cl->upvals[b]->v); + break; + } + case OP_GETGLOBAL: { + TObject *rb = KBx(i); + const TObject *v; + lua_assert(ttisstring(rb) && ttistable(&cl->g)); + v = luaH_getstr(hvalue(&cl->g), tsvalue(rb)); + if (!ttisnil(v)) { setobj2s(ra, v); } + else + setobj2s(XRA(i), luaV_index(L, &cl->g, rb, 0)); + break; + } + case OP_GETTABLE: { + StkId rb = RB(i); + TObject *rc = RKC(i); + if (ttistable(rb)) { + const TObject *v = luaH_get(hvalue(rb), rc); + if (!ttisnil(v)) { setobj2s(ra, v); } + else + setobj2s(XRA(i), luaV_index(L, rb, rc, 0)); + } + else + setobj2s(XRA(i), luaV_getnotable(L, rb, rc, 0)); + break; + } + case OP_SETGLOBAL: { + lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g)); + luaV_settable(L, &cl->g, KBx(i), ra); + break; + } + case OP_SETUPVAL: { + int b = GETARG_B(i); + setobj(cl->upvals[b]->v, ra); /* write barrier */ + break; + } + case OP_SETTABLE: { + luaV_settable(L, ra, RKB(i), RKC(i)); + break; + } + case OP_NEWTABLE: { + int b = GETARG_B(i); + b = fb2int(b); + sethvalue(ra, luaH_new(L, b, GETARG_C(i))); + luaC_checkGC(L); + break; + } + case OP_SELF: { + StkId rb = RB(i); + TObject *rc = RKC(i); + runtime_check(L, ttisstring(rc)); + setobjs2s(ra+1, rb); + if (ttistable(rb)) { + const TObject *v = luaH_getstr(hvalue(rb), tsvalue(rc)); + if (!ttisnil(v)) { setobj2s(ra, v); } + else + setobj2s(XRA(i), luaV_index(L, rb, rc, 0)); + } + else + setobj2s(XRA(i), luaV_getnotable(L, rb, rc, 0)); + break; + } + case OP_ADD: { + TObject *rb = RKB(i); + TObject *rc = RKC(i); + if (ttisnumber(rb) && ttisnumber(rc)) { + setnvalue(ra, nvalue(rb) + nvalue(rc)); + } + else + Arith(L, ra, rb, rc, TM_ADD); + break; + } + case OP_SUB: { + TObject *rb = RKB(i); + TObject *rc = RKC(i); + if (ttisnumber(rb) && ttisnumber(rc)) { + setnvalue(ra, nvalue(rb) - nvalue(rc)); + } + else + Arith(L, ra, rb, rc, TM_SUB); + break; + } + case OP_MUL: { + TObject *rb = RKB(i); + TObject *rc = RKC(i); + if (ttisnumber(rb) && ttisnumber(rc)) { + setnvalue(ra, nvalue(rb) * nvalue(rc)); + } + else + Arith(L, ra, rb, rc, TM_MUL); + break; + } + case OP_DIV: { + TObject *rb = RKB(i); + TObject *rc = RKC(i); + if (ttisnumber(rb) && ttisnumber(rc)) { + setnvalue(ra, nvalue(rb) / nvalue(rc)); + } + else + Arith(L, ra, rb, rc, TM_DIV); + break; + } + case OP_POW: { + Arith(L, ra, RKB(i), RKC(i), TM_POW); + break; + } + case OP_UNM: { + const TObject *rb = RB(i); + TObject temp; + if (tonumber(rb, &temp)) { + setnvalue(ra, -nvalue(rb)); + } + else { + setnilvalue(&temp); + if (!call_binTM(L, RB(i), &temp, ra, TM_UNM)) + luaG_aritherror(L, RB(i), &temp); + } + break; + } + case OP_NOT: { + int res = l_isfalse(RB(i)); /* next assignment may change this value */ + setbvalue(ra, res); + break; + } + case OP_CONCAT: { + int b = GETARG_B(i); + int c = GETARG_C(i); + luaV_concat(L, c-b+1, c); /* may change `base' (and `ra') */ + base = L->base; + setobjs2s(RA(i), base+b); + luaC_checkGC(L); + break; + } + case OP_JMP: { + dojump(pc, GETARG_sBx(i)); + break; + } + case OP_EQ: { + if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; + else dojump(pc, GETARG_sBx(*pc) + 1); + break; + } + case OP_LT: { + if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; + else dojump(pc, GETARG_sBx(*pc) + 1); + break; + } + case OP_LE: { + if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++; + else dojump(pc, GETARG_sBx(*pc) + 1); + break; + } + case OP_TEST: { + TObject *rb = RB(i); + if (l_isfalse(rb) == GETARG_C(i)) pc++; + else { + setobjs2s(ra, rb); + dojump(pc, GETARG_sBx(*pc) + 1); + } + break; + } + case OP_CALL: + case OP_TAILCALL: { + StkId firstResult; + int b = GETARG_B(i); + int nresults; + if (b != 0) L->top = ra+b; /* else previous instruction set top */ + nresults = GETARG_C(i) - 1; + firstResult = luaD_precall(L, ra); + if (firstResult) { + if (firstResult > L->top) { /* yield? */ + lua_assert(L->ci->state == (CI_C | CI_YIELD)); + (L->ci - 1)->u.l.savedpc = pc; + (L->ci - 1)->state = CI_SAVEDPC; + return NULL; + } + /* it was a C function (`precall' called it); adjust results */ + luaD_poscall(L, nresults, firstResult); + if (nresults >= 0) L->top = L->ci->top; + } + else { /* it is a Lua function */ + if (GET_OPCODE(i) == OP_CALL) { /* regular call? */ + (L->ci-1)->u.l.savedpc = pc; /* save `pc' to return later */ + (L->ci-1)->state = (CI_SAVEDPC | CI_CALLING); + } + else { /* tail call: put new frame in place of previous one */ + int aux; + base = (L->ci - 1)->base; /* `luaD_precall' may change the stack */ + ra = RA(i); + if (L->openupval) luaF_close(L, base); + for (aux = 0; ra+aux < L->top; aux++) /* move frame down */ + setobjs2s(base+aux-1, ra+aux); + (L->ci - 1)->top = L->top = base+aux; /* correct top */ + lua_assert(L->ci->state & CI_SAVEDPC); + (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc; + (L->ci - 1)->u.l.tailcalls++; /* one more call lost */ + (L->ci - 1)->state = CI_SAVEDPC; + L->ci--; /* remove new frame */ + L->base = L->ci->base; + } + goto callentry; + } + break; + } + case OP_RETURN: { + CallInfo *ci = L->ci - 1; /* previous function frame */ + int b = GETARG_B(i); + if (b != 0) L->top = ra+b-1; + lua_assert(L->ci->state & CI_HASFRAME); + if (L->openupval) luaF_close(L, base); + L->ci->state = CI_SAVEDPC; /* deactivate current function */ + L->ci->u.l.savedpc = pc; + /* previous function was running `here'? */ + if (!(ci->state & CI_CALLING)) { + lua_assert((ci->state & CI_C) || ci->u.l.pc != &pc); + return ra; /* no: return */ + } + else { /* yes: continue its execution */ + int nresults; + lua_assert(ci->u.l.pc == &pc && + ttisfunction(ci->base - 1) && + (ci->state & CI_SAVEDPC)); + lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL); + nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1; + luaD_poscall(L, nresults, ra); + if (nresults >= 0) L->top = L->ci->top; + goto retentry; + } + } + case OP_FORLOOP: { + lua_Number step, idx, limit; + const TObject *plimit = ra+1; + const TObject *pstep = ra+2; + if (!ttisnumber(ra)) + luaG_runerror(L, "`for' initial value must be a number"); + if (!tonumber(plimit, ra+1)) + luaG_runerror(L, "`for' limit must be a number"); + if (!tonumber(pstep, ra+2)) + luaG_runerror(L, "`for' step must be a number"); + step = nvalue(pstep); + idx = nvalue(ra) + step; /* increment index */ + limit = nvalue(plimit); + if (step > 0 ? idx <= limit : idx >= limit) { + dojump(pc, GETARG_sBx(i)); /* jump back */ + chgnvalue(ra, idx); /* update index */ + } + break; + } + case OP_TFORLOOP: { + int nvar = GETARG_C(i) + 1; + StkId cb = ra + nvar + 2; /* call base */ + setobjs2s(cb, ra); + setobjs2s(cb+1, ra+1); + setobjs2s(cb+2, ra+2); + L->top = cb+3; /* func. + 2 args (state and index) */ + luaD_call(L, cb, nvar); + L->top = L->ci->top; + ra = XRA(i) + 2; /* final position of first result */ + cb = ra + nvar; + do { /* move results to proper positions */ + nvar--; + setobjs2s(ra+nvar, cb+nvar); + } while (nvar > 0); + if (ttisnil(ra)) /* break loop? */ + pc++; /* skip jump (break loop) */ + else + dojump(pc, GETARG_sBx(*pc) + 1); /* jump back */ + break; + } + case OP_TFORPREP: { /* for compatibility only */ + if (ttistable(ra)) { + setobjs2s(ra+1, ra); + setobj2s(ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next"))); + } + dojump(pc, GETARG_sBx(i)); + break; + } + case OP_SETLIST: + case OP_SETLISTO: { + int bc; + int n; + Table *h; + runtime_check(L, ttistable(ra)); + h = hvalue(ra); + bc = GETARG_Bx(i); + if (GET_OPCODE(i) == OP_SETLIST) + n = (bc&(LFIELDS_PER_FLUSH-1)) + 1; + else { + n = L->top - ra - 1; + L->top = L->ci->top; + } + bc &= ~(LFIELDS_PER_FLUSH-1); /* bc = bc - bc%FPF */ + for (; n > 0; n--) + setobj2t(luaH_setnum(L, h, bc+n), ra+n); /* write barrier */ + break; + } + case OP_CLOSE: { + luaF_close(L, ra); + break; + } + case OP_CLOSURE: { + Proto *p; + Closure *ncl; + int nup, j; + p = cl->p->p[GETARG_Bx(i)]; + nup = p->nups; + ncl = luaF_newLclosure(L, nup, &cl->g); + ncl->l.p = p; + for (j=0; jl.upvals[j] = cl->upvals[GETARG_B(*pc)]; + else { + lua_assert(GET_OPCODE(*pc) == OP_MOVE); + ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc)); + } + } + setclvalue(ra, ncl); + luaC_checkGC(L); + break; + } + } + } +} + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lvm.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/lvm.h new file mode 100644 index 0000000000..19cce200b6 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lvm.h @@ -0,0 +1,35 @@ +/* +** $Id: lvm.h,v 1.47 2002/11/14 16:16:21 roberto Exp $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lvm_h +#define lvm_h + + +#include "ldo.h" +#include "lobject.h" +#include "ltm.h" + + +#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) + +#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \ + (((o) = luaV_tonumber(o,n)) != NULL)) + +#define equalobj(L,o1,o2) \ + (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) + + +int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r); +int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2); +const TObject *luaV_tonumber (const TObject *obj, TObject *n); +int luaV_tostring (lua_State *L, StkId obj); +const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key, + int loop); +void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val); +StkId luaV_execute (lua_State *L); +void luaV_concat (lua_State *L, int total, int last); + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lzio.c b/plugins/!NotAdopted/SmartAutoReplier/lualib/lzio.c new file mode 100644 index 0000000000..3aeca1c588 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lzio.c @@ -0,0 +1,81 @@ +/* +** $Id: lzio.c,v 1.24 2003/03/20 16:00:56 roberto Exp $ +** a generic input stream interface +** See Copyright Notice in lua.h +*/ + + +#include + +#define lzio_c + +#include "lua.h" + +#include "llimits.h" +#include "lmem.h" +#include "lzio.h" + + +int luaZ_fill (ZIO *z) { + size_t size; + const char *buff = z->reader(NULL, z->data, &size); + if (buff == NULL || size == 0) return EOZ; + z->n = size - 1; + z->p = buff; + return char2int(*(z->p++)); +} + + +int luaZ_lookahead (ZIO *z) { + if (z->n == 0) { + int c = luaZ_fill(z); + if (c == EOZ) return c; + z->n++; + z->p--; + } + return char2int(*z->p); +} + + +void luaZ_init (ZIO *z, lua_Chunkreader reader, void *data, const char *name) { + z->reader = reader; + z->data = data; + z->name = name; + z->n = 0; + z->p = NULL; +} + + +/* --------------------------------------------------------------- read --- */ +size_t luaZ_read (ZIO *z, void *b, size_t n) { + while (n) { + size_t m; + if (z->n == 0) { + if (luaZ_fill(z) == EOZ) + return n; /* return number of missing bytes */ + else { + ++z->n; /* filbuf removed first byte; put back it */ + --z->p; + } + } + m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ + memcpy(b, z->p, m); + z->n -= m; + z->p += m; + b = (char *)b + m; + n -= m; + } + return 0; +} + +/* ------------------------------------------------------------------------ */ +char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { + if (n > buff->buffsize) { + if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; + luaM_reallocvector(L, buff->buffer, buff->buffsize, n, char); + buff->buffsize = n; + } + return buff->buffer; +} + + diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/lzio.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/lzio.h new file mode 100644 index 0000000000..5e73615cc0 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/lzio.h @@ -0,0 +1,64 @@ +/* +** $Id: lzio.h,v 1.15 2003/03/20 16:00:56 roberto Exp $ +** Buffered streams +** See Copyright Notice in lua.h +*/ + + +#ifndef lzio_h +#define lzio_h + +#include "lua.h" + + +#define EOZ (-1) /* end of stream */ + +typedef struct Zio ZIO; + + +#define char2int(c) cast(int, cast(unsigned char, (c))) + +#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z)) + +#define zname(z) ((z)->name) + +void luaZ_init (ZIO *z, lua_Chunkreader reader, void *data, const char *name); +size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ +int luaZ_lookahead (ZIO *z); + + + +typedef struct Mbuffer { + char *buffer; + size_t buffsize; +} Mbuffer; + + +char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); + +#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) + +#define luaZ_sizebuffer(buff) ((buff)->buffsize) +#define luaZ_buffer(buff) ((buff)->buffer) + +#define luaZ_resizebuffer(L, buff, size) \ + (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ + (buff)->buffsize = size) + +#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) + + +/* --------- Private Part ------------------ */ + +struct Zio { + size_t n; /* bytes still unread */ + const char *p; /* current position in buffer */ + lua_Chunkreader reader; + void* data; /* additional data */ + const char *name; +}; + + +int luaZ_fill (ZIO *z); + +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/lualib/targetver.h b/plugins/!NotAdopted/SmartAutoReplier/lualib/targetver.h new file mode 100644 index 0000000000..90e767bfce --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/lualib/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/plugins/!NotAdopted/SmartAutoReplier/resource.h b/plugins/!NotAdopted/SmartAutoReplier/resource.h new file mode 100644 index 0000000000..38765d95fc --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/resource.h @@ -0,0 +1,52 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by SAR.rc +// +#define IDD_OPTIONS 101 +#define IDD_ADDRULE_DLG 102 +#define IDI_SAR_ICON 103 +#define IDD_SET_AURMESSAGEDLG 104 +#define IDD_SEL_USER 110 +#define IDD_HISTORYLOGS 111 +#define IDD_SDLGHOLDER 113 +#define IDC_STATIC_HEADER_TEXT 1001 +#define IDC_EDIT_HEADER 1002 +#define IDC_STATIC_MESSAGE_TEXT 1003 +#define IDC_EDIT_MESSAGE 1004 +#define IDC_EDIT_REPLAYDELAY 1006 +#define IDC_LIST_RULES 1007 +#define IDC_BTN_ADDRULE 1008 +#define IDC_BTN_DELRULE 1009 +#define IDC_ED_RULENAME 1009 +#define IDC_BTN_EDITRULE 1010 +#define IDC_ED_RULECNAME 1010 +#define IDC_ED_RULEREPLY 1011 +#define IDC_ED_RULEACTION 1012 +#define IDC_BUTTON1 1013 +#define IDC_BTN_SELUSER 1013 +#define IDC_CHECK_DISABLEWMON 1014 +#define IDC_CHECK1 1017 +#define IDC_CH_SHOW_AURDLG_WHMC 1017 +#define IDC_CH_DISWHSB 1017 +#define IDC_ED_TEXT 1019 +#define IDC_CB_DWSB 1020 +#define IDC_LIST_USERS 1021 +#define IDC_TABS 1022 +#define IDC_TABSHOLDER 1022 +#define IDC_STATUSMSG 1023 +#define IDC_CH_ENABLE_WSCH 1115 +#define IDC_CB_ENWSC 1116 +#define IDC_CH_SHOWCG 1117 +#define IDC_CH_SHOWCG2 1118 +#define IDC_CH_SAVE_AURS 1118 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 113 +#define _APS_NEXT_COMMAND_VALUE 40002 +#define _APS_NEXT_CONTROL_VALUE 1024 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/!NotAdopted/SmartAutoReplier/sar.ico b/plugins/!NotAdopted/SmartAutoReplier/sar.ico new file mode 100644 index 0000000000..27a5d17bbb Binary files /dev/null and b/plugins/!NotAdopted/SmartAutoReplier/sar.ico differ diff --git a/plugins/!NotAdopted/SmartAutoReplier/stdafx.cpp b/plugins/!NotAdopted/SmartAutoReplier/stdafx.cpp new file mode 100644 index 0000000000..39aa93ac1d --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/stdafx.cpp @@ -0,0 +1,27 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#include "stdafx.h" + +void OnRefreshSettings(void) +{ + SendMessage(HWND_BROADCAST, REFRESH_OPTS_MSG, 0, 0); +} \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/stdafx.h b/plugins/!NotAdopted/SmartAutoReplier/stdafx.h new file mode 100644 index 0000000000..76f6c5128c --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/stdafx.h @@ -0,0 +1,74 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * This file is part of SAR. + * + * SAR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SAR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SAR. If not, see . +*/ + +#pragma once + +#include "AggressiveOptimize.h" + +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0500 + +#define WIN32_LEAN_AND_MEAN +#define _MERGE_RDATA_ + +/// windows and crt headers (win32 api) +#include +#include +#include +#include +#include "resource.h" +#include +#include + +#include + +/// shell's headers... (windows shell) +#include +#include + +#pragma comment(lib, "shlwapi.lib") +#pragma comment(lib, "shell32.lib") + +#pragma warning(disable:4312) +#pragma warning(disable:4267) +#pragma warning(disable:4356) + +/// miranda's headers... +#include "../miranda32/newpluginapi.h" +#include "../miranda32/m_system.h" +#include "../miranda32/m_protomod.h" +#include "../miranda32/m_protosvc.h" +#include "../miranda32/m_clist.h" +#include "../miranda32/m_skin.h" +#include "../miranda32/m_database.h" +#include "../miranda32/m_options.h" +#include "../miranda32/m_langpack.h" + +/// plugin's specific headers... +#include "messageshandler.h" /// messages handler +#include "settingshandler.h" /// settings handler +#include "GUI/optionsDlg.h" /// options handler +#include "comlogging.h" /// common loggin helper macroses +#include "crushlog.h" /// crush log handler + +#define REFRESH_OPTS_MSG WM_USER + 666 + +void OnRefreshSettings(void); \ No newline at end of file diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlapp.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlapp.h new file mode 100644 index 0000000000..e47bcd633b --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlapp.h @@ -0,0 +1,2035 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLAPP_H__ +#define __ATLAPP_H__ + +#pragma once + +#ifndef __cplusplus + #error WTL requires C++ compilation (use a .cpp suffix) +#endif + +#ifndef __ATLBASE_H__ + #error atlapp.h requires atlbase.h to be included first +#endif + +#ifndef _WIN32_WCE + #if (WINVER < 0x0400) + #error WTL requires Windows version 4.0 or higher + #endif + + #if (_WIN32_IE < 0x0300) + #error WTL requires IE version 3.0 or higher + #endif +#endif + +#ifdef _ATL_NO_COMMODULE + #error WTL requires that _ATL_NO_COMMODULE is not defined +#endif + +#if (_ATL_VER >= 0x0900) && defined(_ATL_MIN_CRT) + #error _ATL_MIN_CRT is not supported with ATL 9.0 and higher +#endif + +#if defined(_WIN32_WCE) && defined(_ATL_MIN_CRT) + #pragma message("Warning: WTL for Windows CE doesn't use _ATL_MIN_CRT") +#endif + +#include +#if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE) + #include // for _beginthreadex +#endif + +#if (_ATL_VER < 0x0800) && !defined(_DEBUG) + #include +#endif + +#include +#ifndef _WIN32_WCE + #pragma comment(lib, "comctl32.lib") +#endif + +#ifndef _WIN32_WCE + #include "atlres.h" +#else // CE specific + #include "atlresce.h" +#endif // _WIN32_WCE + +// We need to disable this warning because of template class arguments +#pragma warning(disable: 4127) + +#if (_ATL_VER >= 0x0900) && !defined(_SECURE_ATL) + #define _SECURE_ATL 1 +#endif + + +/////////////////////////////////////////////////////////////////////////////// +// WTL version number + +#define _WTL_VER 0x0810 + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CMessageFilter +// CIdleHandler +// CMessageLoop +// +// CAppModule +// CServerAppModule +// +// CRegKeyEx +// +// Global functions: +// AtlGetDefaultGuiFont() +// AtlCreateControlFont() +// AtlCreateBoldFont() +// AtlInitCommonControls() + + +/////////////////////////////////////////////////////////////////////////////// +// Global support for Windows CE + +#ifdef _WIN32_WCE + +#ifndef SW_SHOWDEFAULT + #define SW_SHOWDEFAULT SW_SHOWNORMAL +#endif // !SW_SHOWDEFAULT + +// These get's OR-ed in a constant and will have no effect. +// Defining them reduces the number of #ifdefs required for CE. +#define LR_DEFAULTSIZE 0 +#define LR_LOADFROMFILE 0 + +#ifndef SM_CXCURSOR + #define SM_CXCURSOR 13 +#endif +#ifndef SM_CYCURSOR + #define SM_CYCURSOR 14 +#endif + +inline BOOL IsMenu(HMENU hMenu) +{ + MENUITEMINFO mii = { sizeof(MENUITEMINFO) }; + ::SetLastError(0); + BOOL bRet = ::GetMenuItemInfo(hMenu, 0, TRUE, &mii); + if(!bRet) + bRet = (::GetLastError() != ERROR_INVALID_MENU_HANDLE) ? TRUE : FALSE; + return bRet; +} + +#if (_WIN32_WCE >= 410) +extern "C" void WINAPI ListView_SetItemSpacing(HWND hwndLV, int iHeight); +#endif // (_WIN32_WCE >= 410) + +inline int MulDiv(IN int nNumber, IN int nNumerator, IN int nDenominator) +{ + __int64 multiple = nNumber * nNumerator; + return static_cast(multiple / nDenominator); +} + +#if (_ATL_VER >= 0x0800) + +#ifndef _WTL_KEEP_WS_OVERLAPPEDWINDOW + #ifdef WS_OVERLAPPEDWINDOW + #undef WS_OVERLAPPEDWINDOW + #define WS_OVERLAPPEDWINDOW 0 + #endif // WS_OVERLAPPEDWINDOW +#endif // !_WTL_KEEP_WS_OVERLAPPEDWINDOW + +#ifndef RDW_FRAME + #define RDW_FRAME 0 +#endif // !RDW_FRAME + +#ifndef WM_WINDOWPOSCHANGING + #define WM_WINDOWPOSCHANGING 0 +#endif // !WM_WINDOWPOSCHANGING + +#define FreeResource(x) +#define UnlockResource(x) + +namespace ATL +{ + inline HRESULT CComModule::RegisterClassObjects(DWORD /*dwClsContext*/, DWORD /*dwFlags*/) throw() + { return E_NOTIMPL; } + inline HRESULT CComModule::RevokeClassObjects() throw() + { return E_NOTIMPL; } +}; // namespace ATL + +#ifndef lstrlenW + #define lstrlenW (int)ATL::lstrlenW +#endif // lstrlenW + +inline int WINAPI lstrlenA(LPCSTR lpszString) +{ return ATL::lstrlenA(lpszString); } + +#ifdef lstrcpyn + #undef lstrcpyn + #define lstrcpyn ATL::lstrcpynW +#endif // lstrcpyn + +#ifndef SetWindowLongPtrW + inline LONG_PTR tmp_SetWindowLongPtrW( HWND hWnd, int nIndex, LONG_PTR dwNewLong ) + { + return( ::SetWindowLongW( hWnd, nIndex, LONG( dwNewLong ) ) ); + } + #define SetWindowLongPtrW tmp_SetWindowLongPtrW +#endif + +#ifndef GetWindowLongPtrW + inline LONG_PTR tmp_GetWindowLongPtrW( HWND hWnd, int nIndex ) + { + return( ::GetWindowLongW( hWnd, nIndex ) ); + } + #define GetWindowLongPtrW tmp_GetWindowLongPtrW +#endif + +#ifndef LongToPtr + #define LongToPtr(x) ((void*)x) +#endif + +#ifndef PtrToInt + #define PtrToInt( p ) ((INT)(INT_PTR) (p) ) +#endif + +#else // !(_ATL_VER >= 0x0800) + +#ifdef lstrlenW + #undef lstrlenW + #define lstrlenW (int)::wcslen +#endif // lstrlenW + +#define lstrlenA (int)strlen + +#ifndef lstrcpyn + inline LPTSTR lstrcpyn(LPTSTR lpstrDest, LPCTSTR lpstrSrc, int nLength) + { + if(lpstrDest == NULL || lpstrSrc == NULL || nLength <= 0) + return NULL; + int nLen = min(lstrlen(lpstrSrc), nLength - 1); + LPTSTR lpstrRet = (LPTSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(TCHAR)); + lpstrDest[nLen] = 0; + return lpstrRet; + } +#endif // !lstrcpyn + +#ifndef lstrcpynW + inline LPWSTR lstrcpynW(LPWSTR lpstrDest, LPCWSTR lpstrSrc, int nLength) + { + return lstrcpyn(lpstrDest, lpstrSrc, nLength); // WinCE is Unicode only + } +#endif // !lstrcpynW + +#ifndef lstrcpynA + inline LPSTR lstrcpynA(LPSTR lpstrDest, LPCSTR lpstrSrc, int nLength) + { + if(lpstrDest == NULL || lpstrSrc == NULL || nLength <= 0) + return NULL; + int nLen = min(lstrlenA(lpstrSrc), nLength - 1); + LPSTR lpstrRet = (LPSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(char)); + lpstrDest[nLen] = 0; + return lpstrRet; + } +#endif // !lstrcpyn + +#ifdef TrackPopupMenu + #undef TrackPopupMenu +#endif // TrackPopupMenu + +#define DECLARE_WND_CLASS_EX(WndClassName, style, bkgnd) \ +static CWndClassInfo& GetWndClassInfo() \ +{ \ + static CWndClassInfo wc = \ + { \ + { style, StartWindowProc, \ + 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName }, \ + NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \ + }; \ + return wc; \ +} + +#ifndef _MAX_FNAME + #define _MAX_FNAME _MAX_PATH +#endif // _MAX_FNAME + +#if (_WIN32_WCE < 400) + #define MAKEINTATOM(i) (LPTSTR)((ULONG_PTR)((WORD)(i))) +#endif // (_WIN32_WCE < 400) + +#if (_WIN32_WCE < 410) + #define WHEEL_PAGESCROLL (UINT_MAX) + #define WHEEL_DELTA 120 +#endif // (_WIN32_WCE < 410) + +#ifdef DrawIcon + #undef DrawIcon +#endif + +#ifndef VARCMP_LT + #define VARCMP_LT 0 +#endif +#ifndef VARCMP_EQ + #define VARCMP_EQ 1 +#endif +#ifndef VARCMP_GT + #define VARCMP_GT 2 +#endif +#ifndef VARCMP_NULL + #define VARCMP_NULL 3 +#endif + +#ifndef RDW_ALLCHILDREN + #define RDW_ALLCHILDREN 0 +#endif + +#endif // !(_ATL_VER >= 0x0800) + +#endif // _WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// Global support for using original VC++ 6.0 headers with WTL + +#ifndef _ATL_NO_OLD_HEADERS_WIN64 +#if !defined(_WIN64) && (_ATL_VER < 0x0700) + + #ifndef PSM_INSERTPAGE + #define PSM_INSERTPAGE (WM_USER + 119) + #endif // !PSM_INSERTPAGE + + #ifndef GetClassLongPtr + #define GetClassLongPtrA GetClassLongA + #define GetClassLongPtrW GetClassLongW + #ifdef UNICODE + #define GetClassLongPtr GetClassLongPtrW + #else + #define GetClassLongPtr GetClassLongPtrA + #endif // !UNICODE + #endif // !GetClassLongPtr + + #ifndef GCLP_HICONSM + #define GCLP_HICONSM (-34) + #endif // !GCLP_HICONSM + + #ifndef GetWindowLongPtr + #define GetWindowLongPtrA GetWindowLongA + #define GetWindowLongPtrW GetWindowLongW + #ifdef UNICODE + #define GetWindowLongPtr GetWindowLongPtrW + #else + #define GetWindowLongPtr GetWindowLongPtrA + #endif // !UNICODE + #endif // !GetWindowLongPtr + + #ifndef SetWindowLongPtr + #define SetWindowLongPtrA SetWindowLongA + #define SetWindowLongPtrW SetWindowLongW + #ifdef UNICODE + #define SetWindowLongPtr SetWindowLongPtrW + #else + #define SetWindowLongPtr SetWindowLongPtrA + #endif // !UNICODE + #endif // !SetWindowLongPtr + + #ifndef GWLP_WNDPROC + #define GWLP_WNDPROC (-4) + #endif + #ifndef GWLP_HINSTANCE + #define GWLP_HINSTANCE (-6) + #endif + #ifndef GWLP_HWNDPARENT + #define GWLP_HWNDPARENT (-8) + #endif + #ifndef GWLP_USERDATA + #define GWLP_USERDATA (-21) + #endif + #ifndef GWLP_ID + #define GWLP_ID (-12) + #endif + + #ifndef DWLP_MSGRESULT + #define DWLP_MSGRESULT 0 + #endif + + typedef long LONG_PTR; + typedef unsigned long ULONG_PTR; + typedef ULONG_PTR DWORD_PTR; + + #ifndef HandleToUlong + #define HandleToUlong( h ) ((ULONG)(ULONG_PTR)(h) ) + #endif + #ifndef HandleToLong + #define HandleToLong( h ) ((LONG)(LONG_PTR) (h) ) + #endif + #ifndef LongToHandle + #define LongToHandle( h) ((HANDLE)(LONG_PTR) (h)) + #endif + #ifndef PtrToUlong + #define PtrToUlong( p ) ((ULONG)(ULONG_PTR) (p) ) + #endif + #ifndef PtrToLong + #define PtrToLong( p ) ((LONG)(LONG_PTR) (p) ) + #endif + #ifndef PtrToUint + #define PtrToUint( p ) ((UINT)(UINT_PTR) (p) ) + #endif + #ifndef PtrToInt + #define PtrToInt( p ) ((INT)(INT_PTR) (p) ) + #endif + #ifndef PtrToUshort + #define PtrToUshort( p ) ((unsigned short)(ULONG_PTR)(p) ) + #endif + #ifndef PtrToShort + #define PtrToShort( p ) ((short)(LONG_PTR)(p) ) + #endif + #ifndef IntToPtr + #define IntToPtr( i ) ((VOID *)(INT_PTR)((int)i)) + #endif + #ifndef UIntToPtr + #define UIntToPtr( ui ) ((VOID *)(UINT_PTR)((unsigned int)ui)) + #endif + #ifndef LongToPtr + #define LongToPtr( l ) ((VOID *)(LONG_PTR)((long)l)) + #endif + #ifndef ULongToPtr + #define ULongToPtr( ul ) ((VOID *)(ULONG_PTR)((unsigned long)ul)) + #endif + +#endif // !defined(_WIN64) && (_ATL_VER < 0x0700) +#endif // !_ATL_NO_OLD_HEADERS_WIN64 + + +/////////////////////////////////////////////////////////////////////////////// +// Global support for SecureHelper functions + +#ifndef _TRUNCATE + #define _TRUNCATE ((size_t)-1) +#endif + +#ifndef _ERRCODE_DEFINED + #define _ERRCODE_DEFINED + typedef int errno_t; +#endif + +#ifndef _SECURECRT_ERRCODE_VALUES_DEFINED + #define _SECURECRT_ERRCODE_VALUES_DEFINED + #define EINVAL 22 + #define STRUNCATE 80 +#endif + +#ifndef _countof + #define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0])) +#endif + + +/////////////////////////////////////////////////////////////////////////////// +// Miscellaneous global support + +// define useful macros from winuser.h +#ifndef IS_INTRESOURCE + #define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0) +#endif // IS_INTRESOURCE + +// protect template members from windowsx.h macros +#ifdef _INC_WINDOWSX + #undef SubclassWindow +#endif // _INC_WINDOWSX + +// define useful macros from windowsx.h +#ifndef GET_X_LPARAM + #define GET_X_LPARAM(lParam) ((int)(short)LOWORD(lParam)) +#endif +#ifndef GET_Y_LPARAM + #define GET_Y_LPARAM(lParam) ((int)(short)HIWORD(lParam)) +#endif + +// Dummy structs for compiling with /CLR +#if (_MSC_VER >= 1300) && defined(_MANAGED) + __if_not_exists(_IMAGELIST::_IMAGELIST) { struct _IMAGELIST { }; } + __if_not_exists(_TREEITEM::_TREEITEM) { struct _TREEITEM { }; } + __if_not_exists(_PSP::_PSP) { struct _PSP { }; } +#endif + +// Define ATLVERIFY macro for ATL3 +#if (_ATL_VER < 0x0700) + #ifndef ATLVERIFY + #ifdef _DEBUG + #define ATLVERIFY(expr) ATLASSERT(expr) + #else + #define ATLVERIFY(expr) (expr) + #endif // DEBUG + #endif // ATLVERIFY +#endif // (_ATL_VER < 0x0700) + +// Forward declaration for ATL3 fix +#if (_ATL_VER < 0x0700) && defined(_ATL_DLL) && !defined(_WIN32_WCE) + namespace ATL { HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor); }; +#endif + + +namespace WTL +{ + +#if (_ATL_VER >= 0x0700) + DECLARE_TRACE_CATEGORY(atlTraceUI); + #ifdef _DEBUG + __declspec(selectany) ATL::CTraceCategory atlTraceUI(_T("atlTraceUI")); + #endif // _DEBUG +#else // !(_ATL_VER >= 0x0700) + enum wtlTraceFlags + { + atlTraceUI = 0x10000000 + }; +#endif // !(_ATL_VER >= 0x0700) + +// Windows version helper +inline bool AtlIsOldWindows() +{ + OSVERSIONINFO ovi = { 0 }; + ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + BOOL bRet = ::GetVersionEx(&ovi); + return (!bRet || !((ovi.dwMajorVersion >= 5) || (ovi.dwMajorVersion == 4 && ovi.dwMinorVersion >= 90))); +} + +// Default GUI font helper - "MS Shell Dlg" stock font +inline HFONT AtlGetDefaultGuiFont() +{ +#ifndef _WIN32_WCE + return (HFONT)::GetStockObject(DEFAULT_GUI_FONT); +#else // CE specific + return (HFONT)::GetStockObject(SYSTEM_FONT); +#endif // _WIN32_WCE +} + +// Control font helper - default font for controls not in a dialog +// (NOTE: Caller owns the font, and should destroy it when it's no longer needed) +inline HFONT AtlCreateControlFont() +{ +#ifndef _WIN32_WCE + LOGFONT lf = { 0 }; + ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE); + HFONT hFont = ::CreateFontIndirect(&lf); + ATLASSERT(hFont != NULL); + return hFont; +#else // CE specific + return (HFONT)::GetStockObject(SYSTEM_FONT); +#endif // _WIN32_WCE +} + +// Bold font helper +// (NOTE: Caller owns the font, and should destroy it when it's no longer needed) +inline HFONT AtlCreateBoldFont(HFONT hFont = NULL) +{ + LOGFONT lf = { 0 }; +#ifndef _WIN32_WCE + if(hFont == NULL) + ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE); + else + ATLVERIFY(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT)); +#else // CE specific + if(hFont == NULL) + hFont = (HFONT)::GetStockObject(SYSTEM_FONT); + ATLVERIFY(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT)); +#endif // _WIN32_WCE + lf.lfWeight = FW_BOLD; + HFONT hFontBold = ::CreateFontIndirect(&lf); + ATLASSERT(hFontBold != NULL); + return hFontBold; +} + +// Common Controls initialization helper +inline BOOL AtlInitCommonControls(DWORD dwFlags) +{ + INITCOMMONCONTROLSEX iccx = { sizeof(INITCOMMONCONTROLSEX), dwFlags }; + BOOL bRet = ::InitCommonControlsEx(&iccx); + ATLASSERT(bRet); + return bRet; +} + + +/////////////////////////////////////////////////////////////////////////////// +// RunTimeHelper - helper functions for Windows version and structure sizes + +// Not for Windows CE +#if defined(_WIN32_WCE) && !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) + #define _WTL_NO_RUNTIME_STRUCT_SIZE +#endif + +#ifndef _WTL_NO_RUNTIME_STRUCT_SIZE + +#ifndef _SIZEOF_STRUCT + #define _SIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member)) +#endif + +#if (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE) + #define REBARBANDINFO_V6_SIZE _SIZEOF_STRUCT(REBARBANDINFO, cxHeader) +#endif // (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE) + +#if (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE) + #define LVGROUP_V5_SIZE _SIZEOF_STRUCT(LVGROUP, uAlign) +#endif // (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE) + +#if (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE) + #define LVTILEINFO_V5_SIZE _SIZEOF_STRUCT(LVTILEINFO, puColumns) +#endif // (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE) + +#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE) + #define MCHITTESTINFO_V1_SIZE _SIZEOF_STRUCT(MCHITTESTINFO, st) +#endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE) + +#if !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE) + #define NONCLIENTMETRICS_V1_SIZE _SIZEOF_STRUCT(NONCLIENTMETRICS, lfMessageFont) +#endif // !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE) + +#endif // !_WTL_NO_RUNTIME_STRUCT_SIZE + +namespace RunTimeHelper +{ +#ifndef _WIN32_WCE + inline bool IsCommCtrl6() + { + DWORD dwMajor = 0, dwMinor = 0; + HRESULT hRet = ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor); + return (SUCCEEDED(hRet) && (dwMajor >= 6)); + } + + inline bool IsVista() + { + OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) }; + BOOL bRet = ::GetVersionEx(&ovi); + return ((bRet != FALSE) && (ovi.dwMajorVersion >= 6)); + } + + inline bool IsThemeAvailable() + { + bool bRet = false; + + if(IsCommCtrl6()) + { + HMODULE hThemeDLL = ::LoadLibrary(_T("uxtheme.dll")); + if(hThemeDLL != NULL) + { + typedef BOOL (STDAPICALLTYPE *PFN_IsThemeActive)(); + PFN_IsThemeActive pfnIsThemeActive = (PFN_IsThemeActive)::GetProcAddress(hThemeDLL, "IsThemeActive"); + ATLASSERT(pfnIsThemeActive != NULL); + bRet = (pfnIsThemeActive != NULL) && (pfnIsThemeActive() != FALSE); + if(bRet) + { + typedef BOOL (STDAPICALLTYPE *PFN_IsAppThemed)(); + PFN_IsAppThemed pfnIsAppThemed = (PFN_IsAppThemed)::GetProcAddress(hThemeDLL, "IsAppThemed"); + ATLASSERT(pfnIsAppThemed != NULL); + bRet = (pfnIsAppThemed != NULL) && (pfnIsAppThemed() != FALSE); + } + + ::FreeLibrary(hThemeDLL); + } + } + + return bRet; + } + + inline bool IsWin7() + { + OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) }; + BOOL bRet = ::GetVersionEx(&ovi); + return ((bRet != FALSE) && (ovi.dwMajorVersion == 6) && (ovi.dwMinorVersion >= 1)); + } + + inline bool IsRibbonUIAvailable() + { + static INT iRibbonUI = -1; + +#if defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7) + if (iRibbonUI == -1) + { + HMODULE hRibbonDLL = ::LoadLibrary(_T("propsys.dll")); + if (hRibbonDLL != NULL) + { + const GUID CLSID_UIRibbonFramework = { 0x926749fa, 0x2615, 0x4987, { 0x88, 0x45, 0xc3, 0x3e, 0x65, 0xf2, 0xb9, 0x57 } }; + // block - create instance + { + ATL::CComPtr pIUIFramework; + iRibbonUI = SUCCEEDED(pIUIFramework.CoCreateInstance(CLSID_UIRibbonFramework)) ? 1 : 0; + } + ::FreeLibrary(hRibbonDLL); + } + else + { + iRibbonUI = 0; + } + } +#endif // defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7) + + return (iRibbonUI == 1); + } + +#endif // !_WIN32_WCE + + inline int SizeOf_REBARBANDINFO() + { + int nSize = sizeof(REBARBANDINFO); +#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) + if(!(IsVista() && IsCommCtrl6())) + nSize = REBARBANDINFO_V6_SIZE; +#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) + return nSize; + } + +#if (_WIN32_WINNT >= 0x501) + inline int SizeOf_LVGROUP() + { + int nSize = sizeof(LVGROUP); +#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) + if(!IsVista()) + nSize = LVGROUP_V5_SIZE; +#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) + return nSize; + } + + inline int SizeOf_LVTILEINFO() + { + int nSize = sizeof(LVTILEINFO); +#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) + if(!IsVista()) + nSize = LVTILEINFO_V5_SIZE; +#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) + return nSize; + } +#endif // (_WIN32_WINNT >= 0x501) + + inline int SizeOf_MCHITTESTINFO() + { + int nSize = sizeof(MCHITTESTINFO); +#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) + if(!(IsVista() && IsCommCtrl6())) + nSize = MCHITTESTINFO_V1_SIZE; +#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) + return nSize; + } + +#ifndef _WIN32_WCE + inline int SizeOf_NONCLIENTMETRICS() + { + int nSize = sizeof(NONCLIENTMETRICS); +#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600) + if(!IsVista()) + nSize = NONCLIENTMETRICS_V1_SIZE; +#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600) + return nSize; + } +#endif // !_WIN32_WCE +}; + + +/////////////////////////////////////////////////////////////////////////////// +// ModuleHelper - helper functions for ATL3 and ATL7 module classes + +namespace ModuleHelper +{ + inline HINSTANCE GetModuleInstance() + { +#if (_ATL_VER >= 0x0700) + return ATL::_AtlBaseModule.GetModuleInstance(); +#else // !(_ATL_VER >= 0x0700) + return ATL::_pModule->GetModuleInstance(); +#endif // !(_ATL_VER >= 0x0700) + } + + inline HINSTANCE GetResourceInstance() + { +#if (_ATL_VER >= 0x0700) + return ATL::_AtlBaseModule.GetResourceInstance(); +#else // !(_ATL_VER >= 0x0700) + return ATL::_pModule->GetResourceInstance(); +#endif // !(_ATL_VER >= 0x0700) + } + + inline void AddCreateWndData(ATL::_AtlCreateWndData* pData, void* pObject) + { +#if (_ATL_VER >= 0x0700) + ATL::_AtlWinModule.AddCreateWndData(pData, pObject); +#else // !(_ATL_VER >= 0x0700) + ATL::_pModule->AddCreateWndData(pData, pObject); +#endif // !(_ATL_VER >= 0x0700) + } + + inline void* ExtractCreateWndData() + { +#if (_ATL_VER >= 0x0700) + return ATL::_AtlWinModule.ExtractCreateWndData(); +#else // !(_ATL_VER >= 0x0700) + return ATL::_pModule->ExtractCreateWndData(); +#endif // !(_ATL_VER >= 0x0700) + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// SecureHelper - helper functions for VS2005 secure CRT + +namespace SecureHelper +{ + inline void strcpyA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc) + { +#if _SECURE_ATL + ATL::Checked::strcpy_s(lpstrDest, cchDest, lpstrSrc); +#else + if(cchDest > (size_t)lstrlenA(lpstrSrc)) + ATLVERIFY(lstrcpyA(lpstrDest, lpstrSrc) != NULL); + else + ATLASSERT(FALSE); +#endif + } + + inline void strcpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc) + { +#if _SECURE_ATL + ATL::Checked::wcscpy_s(lpstrDest, cchDest, lpstrSrc); +#else + if(cchDest > (size_t)lstrlenW(lpstrSrc)) + ATLVERIFY(lstrcpyW(lpstrDest, lpstrSrc) != NULL); + else + ATLASSERT(FALSE); +#endif + } + + inline void strcpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc) + { +#ifdef _UNICODE + strcpyW_x(lpstrDest, cchDest, lpstrSrc); +#else + strcpyA_x(lpstrDest, cchDest, lpstrSrc); +#endif + } + + inline errno_t strncpyA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc, size_t cchCount) + { +#if _SECURE_ATL + return ATL::Checked::strncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount); +#else + errno_t nRet = 0; + if(lpstrDest == NULL || cchDest == 0 || lpstrSrc == NULL) + { + nRet = EINVAL; + } + else if(cchCount == _TRUNCATE) + { + cchCount = min(cchDest - 1, size_t(lstrlenA(lpstrSrc))); + nRet = STRUNCATE; + } + else if(cchDest <= cchCount) + { + lpstrDest[0] = 0; + nRet = EINVAL; + } + if(nRet == 0 || nRet == STRUNCATE) + nRet = (lstrcpynA(lpstrDest, lpstrSrc, (int)cchCount + 1) != NULL) ? nRet : EINVAL; + ATLASSERT(nRet == 0 || nRet == STRUNCATE); + return nRet; +#endif + } + + inline errno_t strncpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc, size_t cchCount) + { +#if _SECURE_ATL + return ATL::Checked::wcsncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount); +#else + errno_t nRet = 0; + if(lpstrDest == NULL || cchDest == 0 || lpstrSrc == NULL) + { + nRet = EINVAL; + } + else if(cchCount == _TRUNCATE) + { + cchCount = min(cchDest - 1, size_t(lstrlenW(lpstrSrc))); + nRet = STRUNCATE; + } + else if(cchDest <= cchCount) + { + lpstrDest[0] = 0; + nRet = EINVAL; + } + if(nRet == 0 || nRet == STRUNCATE) + nRet = (lstrcpynW(lpstrDest, lpstrSrc, (int)cchCount + 1) != NULL) ? nRet : EINVAL; + ATLASSERT(nRet == 0 || nRet == STRUNCATE); + return nRet; +#endif + } + + inline errno_t strncpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc, size_t cchCount) + { +#ifdef _UNICODE + return strncpyW_x(lpstrDest, cchDest, lpstrSrc, cchCount); +#else + return strncpyA_x(lpstrDest, cchDest, lpstrSrc, cchCount); +#endif + } + + inline void strcatA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc) + { +#if _SECURE_ATL + ATL::Checked::strcat_s(lpstrDest, cchDest, lpstrSrc); +#else + if(cchDest > (size_t)lstrlenA(lpstrSrc)) + ATLVERIFY(lstrcatA(lpstrDest, lpstrSrc) != NULL); + else + ATLASSERT(FALSE); +#endif + } + + inline void strcatW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc) + { +#if _SECURE_ATL + ATL::Checked::wcscat_s(lpstrDest, cchDest, lpstrSrc); +#else + if(cchDest > (size_t)lstrlenW(lpstrSrc)) + ATLVERIFY(lstrcatW(lpstrDest, lpstrSrc) != NULL); + else + ATLASSERT(FALSE); +#endif + } + + inline void strcat_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc) + { +#ifdef _UNICODE + strcatW_x(lpstrDest, cchDest, lpstrSrc); +#else + strcatA_x(lpstrDest, cchDest, lpstrSrc); +#endif + } + + inline void memcpy_x(void* pDest, size_t cbDest, const void* pSrc, size_t cbSrc) + { +#if _SECURE_ATL + ATL::Checked::memcpy_s(pDest, cbDest, pSrc, cbSrc); +#else + if(cbDest >= cbSrc) + memcpy(pDest, pSrc, cbSrc); + else + ATLASSERT(FALSE); +#endif + } + + inline void memmove_x(void* pDest, size_t cbDest, const void* pSrc, size_t cbSrc) + { +#if _SECURE_ATL + ATL::Checked::memmove_s(pDest, cbDest, pSrc, cbSrc); +#else + if(cbDest >= cbSrc) + memmove(pDest, pSrc, cbSrc); + else + ATLASSERT(FALSE); +#endif + } + + inline int vsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args) + { +#if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE) + return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args); +#else + cchBuff; // Avoid unused argument warning +#pragma warning(disable: 4996) + return _vstprintf(lpstrBuff, lpstrFormat, args); +#pragma warning(default: 4996) +#endif + } + + inline int wvsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args) + { +#if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE) + return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args); +#else + cchBuff; // Avoid unused argument warning + return ::wvsprintf(lpstrBuff, lpstrFormat, args); +#endif + } + + inline int sprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, ...) + { + va_list args; + va_start(args, lpstrFormat); + int nRes = vsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args); + va_end(args); + return nRes; + } + + inline int wsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, ...) + { + va_list args; + va_start(args, lpstrFormat); + int nRes = wvsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args); + va_end(args); + return nRes; + } +}; // namespace SecureHelper + + +/////////////////////////////////////////////////////////////////////////////// +// CMessageFilter - Interface for message filter support + +class CMessageFilter +{ +public: + virtual BOOL PreTranslateMessage(MSG* pMsg) = 0; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CIdleHandler - Interface for idle processing + +class CIdleHandler +{ +public: + virtual BOOL OnIdle() = 0; +}; + +#ifndef _ATL_NO_OLD_NAMES + // for compatilibility with old names only + typedef CIdleHandler CUpdateUIObject; + #define DoUpdate OnIdle +#endif // !_ATL_NO_OLD_NAMES + + +/////////////////////////////////////////////////////////////////////////////// +// CMessageLoop - message loop implementation + +class CMessageLoop +{ +public: + ATL::CSimpleArray m_aMsgFilter; + ATL::CSimpleArray m_aIdleHandler; + MSG m_msg; + +// Message filter operations + BOOL AddMessageFilter(CMessageFilter* pMessageFilter) + { + return m_aMsgFilter.Add(pMessageFilter); + } + + BOOL RemoveMessageFilter(CMessageFilter* pMessageFilter) + { + return m_aMsgFilter.Remove(pMessageFilter); + } + +// Idle handler operations + BOOL AddIdleHandler(CIdleHandler* pIdleHandler) + { + return m_aIdleHandler.Add(pIdleHandler); + } + + BOOL RemoveIdleHandler(CIdleHandler* pIdleHandler) + { + return m_aIdleHandler.Remove(pIdleHandler); + } + +#ifndef _ATL_NO_OLD_NAMES + // for compatilibility with old names only + BOOL AddUpdateUI(CIdleHandler* pIdleHandler) + { + ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIObject and AddUpdateUI are deprecated. Please change your code to use CIdleHandler and OnIdle\n")); + return AddIdleHandler(pIdleHandler); + } + + BOOL RemoveUpdateUI(CIdleHandler* pIdleHandler) + { + ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIObject and RemoveUpdateUI are deprecated. Please change your code to use CIdleHandler and OnIdle\n")); + return RemoveIdleHandler(pIdleHandler); + } +#endif // !_ATL_NO_OLD_NAMES + +// message loop + int Run() + { + BOOL bDoIdle = TRUE; + int nIdleCount = 0; + BOOL bRet; + + for(;;) + { + while(bDoIdle && !::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE)) + { + if(!OnIdle(nIdleCount++)) + bDoIdle = FALSE; + } + + bRet = ::GetMessage(&m_msg, NULL, 0, 0); + + if(bRet == -1) + { + ATLTRACE2(atlTraceUI, 0, _T("::GetMessage returned -1 (error)\n")); + continue; // error, don't process + } + else if(!bRet) + { + ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run - exiting\n")); + break; // WM_QUIT, exit message loop + } + + if(!PreTranslateMessage(&m_msg)) + { + ::TranslateMessage(&m_msg); + ::DispatchMessage(&m_msg); + } + + if(IsIdleMessage(&m_msg)) + { + bDoIdle = TRUE; + nIdleCount = 0; + } + } + + return (int)m_msg.wParam; + } + + static BOOL IsIdleMessage(MSG* pMsg) + { + // These messages should NOT cause idle processing + switch(pMsg->message) + { + case WM_MOUSEMOVE: +#ifndef _WIN32_WCE + case WM_NCMOUSEMOVE: +#endif // !_WIN32_WCE + case WM_PAINT: + case 0x0118: // WM_SYSTIMER (caret blink) + return FALSE; + } + + return TRUE; + } + +// Overrideables + // Override to change message filtering + virtual BOOL PreTranslateMessage(MSG* pMsg) + { + // loop backwards + for(int i = m_aMsgFilter.GetSize() - 1; i >= 0; i--) + { + CMessageFilter* pMessageFilter = m_aMsgFilter[i]; + if(pMessageFilter != NULL && pMessageFilter->PreTranslateMessage(pMsg)) + return TRUE; + } + return FALSE; // not translated + } + + // override to change idle processing + virtual BOOL OnIdle(int /*nIdleCount*/) + { + for(int i = 0; i < m_aIdleHandler.GetSize(); i++) + { + CIdleHandler* pIdleHandler = m_aIdleHandler[i]; + if(pIdleHandler != NULL) + pIdleHandler->OnIdle(); + } + return FALSE; // don't continue + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CStaticDataInitCriticalSectionLock and CWindowCreateCriticalSectionLock +// internal classes to manage critical sections for both ATL3 and ATL7 + +class CStaticDataInitCriticalSectionLock +{ +public: +#if (_ATL_VER >= 0x0700) + ATL::CComCritSecLock m_cslock; + + CStaticDataInitCriticalSectionLock() : m_cslock(ATL::_pAtlModule->m_csStaticDataInitAndTypeInfo, false) + { } +#endif // (_ATL_VER >= 0x0700) + + HRESULT Lock() + { +#if (_ATL_VER >= 0x0700) + return m_cslock.Lock(); +#else // !(_ATL_VER >= 0x0700) + ::EnterCriticalSection(&ATL::_pModule->m_csStaticDataInit); + return S_OK; +#endif // !(_ATL_VER >= 0x0700) + } + + void Unlock() + { +#if (_ATL_VER >= 0x0700) + m_cslock.Unlock(); +#else // !(_ATL_VER >= 0x0700) + ::LeaveCriticalSection(&ATL::_pModule->m_csStaticDataInit); +#endif // !(_ATL_VER >= 0x0700) + } +}; + + +class CWindowCreateCriticalSectionLock +{ +public: +#if (_ATL_VER >= 0x0700) + ATL::CComCritSecLock m_cslock; + + CWindowCreateCriticalSectionLock() : m_cslock(ATL::_AtlWinModule.m_csWindowCreate, false) + { } +#endif // (_ATL_VER >= 0x0700) + + HRESULT Lock() + { +#if (_ATL_VER >= 0x0700) + return m_cslock.Lock(); +#else // !(_ATL_VER >= 0x0700) + ::EnterCriticalSection(&ATL::_pModule->m_csWindowCreate); + return S_OK; +#endif // !(_ATL_VER >= 0x0700) + } + + void Unlock() + { +#if (_ATL_VER >= 0x0700) + m_cslock.Unlock(); +#else // !(_ATL_VER >= 0x0700) + ::LeaveCriticalSection(&ATL::_pModule->m_csWindowCreate); +#endif // !(_ATL_VER >= 0x0700) + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CTempBuffer - helper class for stack allocations for ATL3 + +#ifndef _WTL_STACK_ALLOC_THRESHOLD + #define _WTL_STACK_ALLOC_THRESHOLD 512 +#endif + +#if (_ATL_VER >= 0x0700) + +using ATL::CTempBuffer; + +#else // !(_ATL_VER >= 0x0700) + +#ifndef SIZE_MAX + #ifdef _WIN64 + #define SIZE_MAX _UI64_MAX + #else + #define SIZE_MAX UINT_MAX + #endif +#endif + +#pragma warning(disable: 4284) // warning for operator -> + +template +class CTempBuffer +{ +public: + CTempBuffer() : m_p(NULL) + { + } + + CTempBuffer(size_t nElements) : m_p(NULL) + { + Allocate(nElements); + } + + ~CTempBuffer() + { + if(m_p != reinterpret_cast(m_abFixedBuffer)) + free(m_p); + } + + operator T*() const + { + return m_p; + } + + T* operator ->() const + { + ATLASSERT(m_p != NULL); + return m_p; + } + + T* Allocate(size_t nElements) + { + ATLASSERT(nElements <= (SIZE_MAX / sizeof(T))); + return AllocateBytes(nElements * sizeof(T)); + } + + T* AllocateBytes(size_t nBytes) + { + ATLASSERT(m_p == NULL); + if(nBytes > t_nFixedBytes) + m_p = static_cast(malloc(nBytes)); + else + m_p = reinterpret_cast(m_abFixedBuffer); + + return m_p; + } + +private: + T* m_p; + BYTE m_abFixedBuffer[t_nFixedBytes]; +}; + +#pragma warning(default: 4284) + +#endif // !(_ATL_VER >= 0x0700) + + +/////////////////////////////////////////////////////////////////////////////// +// CAppModule - module class for an application + +class CAppModule : public ATL::CComModule +{ +public: + DWORD m_dwMainThreadID; + ATL::CSimpleMap* m_pMsgLoopMap; + ATL::CSimpleArray* m_pSettingChangeNotify; + +// Overrides of CComModule::Init and Term + HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL) + { + HRESULT hRet = CComModule::Init(pObjMap, hInstance, pLibID); + if(FAILED(hRet)) + return hRet; + + m_dwMainThreadID = ::GetCurrentThreadId(); + typedef ATL::CSimpleMap _mapClass; + m_pMsgLoopMap = NULL; + ATLTRY(m_pMsgLoopMap = new _mapClass); + if(m_pMsgLoopMap == NULL) + return E_OUTOFMEMORY; + m_pSettingChangeNotify = NULL; + + return hRet; + } + + void Term() + { + TermSettingChangeNotify(); + delete m_pMsgLoopMap; + CComModule::Term(); + } + +// Message loop map methods + BOOL AddMessageLoop(CMessageLoop* pMsgLoop) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddMessageLoop.\n")); + ATLASSERT(FALSE); + return FALSE; + } + + ATLASSERT(pMsgLoop != NULL); + ATLASSERT(m_pMsgLoopMap->Lookup(::GetCurrentThreadId()) == NULL); // not in map yet + + BOOL bRet = m_pMsgLoopMap->Add(::GetCurrentThreadId(), pMsgLoop); + + lock.Unlock(); + + return bRet; + } + + BOOL RemoveMessageLoop() + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveMessageLoop.\n")); + ATLASSERT(FALSE); + return FALSE; + } + + BOOL bRet = m_pMsgLoopMap->Remove(::GetCurrentThreadId()); + + lock.Unlock(); + + return bRet; + } + + CMessageLoop* GetMessageLoop(DWORD dwThreadID = ::GetCurrentThreadId()) const + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::GetMessageLoop.\n")); + ATLASSERT(FALSE); + return NULL; + } + + CMessageLoop* pLoop = m_pMsgLoopMap->Lookup(dwThreadID); + + lock.Unlock(); + + return pLoop; + } + +// Setting change notify methods + // Note: Call this from the main thread for MSDI apps + BOOL InitSettingChangeNotify(DLGPROC pfnDlgProc = _SettingChangeDlgProc) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::InitSettingChangeNotify.\n")); + ATLASSERT(FALSE); + return FALSE; + } + + if(m_pSettingChangeNotify == NULL) + { + typedef ATL::CSimpleArray _notifyClass; + ATLTRY(m_pSettingChangeNotify = new _notifyClass); + ATLASSERT(m_pSettingChangeNotify != NULL); + } + + BOOL bRet = (m_pSettingChangeNotify != NULL); + if(bRet && m_pSettingChangeNotify->GetSize() == 0) + { + // init everything + _ATL_EMPTY_DLGTEMPLATE templ; + HWND hNtfWnd = ::CreateDialogIndirect(GetModuleInstance(), &templ, NULL, pfnDlgProc); + ATLASSERT(::IsWindow(hNtfWnd)); + if(::IsWindow(hNtfWnd)) + { +// need conditional code because types don't match in winuser.h +#ifdef _WIN64 + ::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, (LONG_PTR)this); +#else + ::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, PtrToLong(this)); +#endif + bRet = m_pSettingChangeNotify->Add(hNtfWnd); + } + else + { + bRet = FALSE; + } + } + + lock.Unlock(); + + return bRet; + } + + void TermSettingChangeNotify() + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::TermSettingChangeNotify.\n")); + ATLASSERT(FALSE); + return; + } + + if(m_pSettingChangeNotify != NULL && m_pSettingChangeNotify->GetSize() > 0) + ::DestroyWindow((*m_pSettingChangeNotify)[0]); + delete m_pSettingChangeNotify; + m_pSettingChangeNotify = NULL; + + lock.Unlock(); + } + + BOOL AddSettingChangeNotify(HWND hWnd) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddSettingChangeNotify.\n")); + ATLASSERT(FALSE); + return FALSE; + } + + ATLASSERT(::IsWindow(hWnd)); + BOOL bRet = FALSE; + if(InitSettingChangeNotify() != FALSE) + bRet = m_pSettingChangeNotify->Add(hWnd); + + lock.Unlock(); + + return bRet; + } + + BOOL RemoveSettingChangeNotify(HWND hWnd) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveSettingChangeNotify.\n")); + ATLASSERT(FALSE); + return FALSE; + } + + BOOL bRet = FALSE; + if(m_pSettingChangeNotify != NULL) + bRet = m_pSettingChangeNotify->Remove(hWnd); + + lock.Unlock(); + + return bRet; + } + +// Implementation - setting change notify dialog template and dialog procedure + struct _ATL_EMPTY_DLGTEMPLATE : DLGTEMPLATE + { + _ATL_EMPTY_DLGTEMPLATE() + { + memset(this, 0, sizeof(_ATL_EMPTY_DLGTEMPLATE)); + style = WS_POPUP; + } + WORD wMenu, wClass, wTitle; + }; + +#ifdef _WIN64 + static INT_PTR CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +#else + static BOOL CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +#endif + { + if(uMsg == WM_SETTINGCHANGE) + { +// need conditional code because types don't match in winuser.h +#ifdef _WIN64 + CAppModule* pModule = (CAppModule*)::GetWindowLongPtr(hWnd, GWLP_USERDATA); +#else + CAppModule* pModule = (CAppModule*)LongToPtr(::GetWindowLongPtr(hWnd, GWLP_USERDATA)); +#endif + ATLASSERT(pModule != NULL); + ATLASSERT(pModule->m_pSettingChangeNotify != NULL); + const UINT uTimeout = 1500; // ms + for(int i = 1; i < pModule->m_pSettingChangeNotify->GetSize(); i++) + { +#if !defined(_WIN32_WCE) + ::SendMessageTimeout((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam, SMTO_ABORTIFHUNG, uTimeout, NULL); +#elif(_WIN32_WCE >= 400) // CE specific + ::SendMessageTimeout((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam, SMTO_NORMAL, uTimeout, NULL); +#else // _WIN32_WCE < 400 specific + uTimeout; + ::SendMessage((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam); +#endif + } + return TRUE; + } + return FALSE; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CServerAppModule - module class for a COM server application + +class CServerAppModule : public CAppModule +{ +public: + HANDLE m_hEventShutdown; + bool m_bActivity; + DWORD m_dwTimeOut; + DWORD m_dwPause; + +// Override of CAppModule::Init + HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL) + { + m_dwTimeOut = 5000; + m_dwPause = 1000; + return CAppModule::Init(pObjMap, hInstance, pLibID); + } + + void Term() + { + if(m_hEventShutdown != NULL && ::CloseHandle(m_hEventShutdown)) + m_hEventShutdown = NULL; + CAppModule::Term(); + } + +// COM Server methods + LONG Unlock() + { + LONG lRet = CComModule::Unlock(); + if(lRet == 0) + { + m_bActivity = true; + ::SetEvent(m_hEventShutdown); // tell monitor that we transitioned to zero + } + return lRet; + } + + void MonitorShutdown() + { + for(;;) + { + ::WaitForSingleObject(m_hEventShutdown, INFINITE); + DWORD dwWait = 0; + do + { + m_bActivity = false; + dwWait = ::WaitForSingleObject(m_hEventShutdown, m_dwTimeOut); + } + while(dwWait == WAIT_OBJECT_0); + // timed out + if(!m_bActivity && m_nLockCnt == 0) // if no activity let's really bail + { +#if ((_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM)) && defined(_ATL_FREE_THREADED) && !defined(_WIN32_WCE) + ::CoSuspendClassObjects(); + if(!m_bActivity && m_nLockCnt == 0) +#endif + break; + } + } + // This handle should be valid now. If it isn't, + // check if _Module.Term was called first (it shouldn't) + if(::CloseHandle(m_hEventShutdown)) + m_hEventShutdown = NULL; + ::PostThreadMessage(m_dwMainThreadID, WM_QUIT, 0, 0); + } + + bool StartMonitor() + { + m_hEventShutdown = ::CreateEvent(NULL, false, false, NULL); + if(m_hEventShutdown == NULL) + return false; + DWORD dwThreadID = 0; +#if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE) + HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, (UINT (WINAPI*)(void*))MonitorProc, this, 0, (UINT*)&dwThreadID); +#else + HANDLE hThread = ::CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID); +#endif + bool bRet = (hThread != NULL); + if(bRet) + ::CloseHandle(hThread); + return bRet; + } + + static DWORD WINAPI MonitorProc(void* pv) + { + CServerAppModule* p = (CServerAppModule*)pv; + p->MonitorShutdown(); + return 0; + } + +#if (_ATL_VER < 0x0700) + // search for an occurence of string p2 in string p1 + static LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2) + { + while(p1 != NULL && *p1 != NULL) + { + LPCTSTR p = p2; + while(p != NULL && *p != NULL) + { + if(*p1 == *p) + return ::CharNext(p1); + p = ::CharNext(p); + } + p1 = ::CharNext(p1); + } + return NULL; + } +#endif // (_ATL_VER < 0x0700) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CRegKeyEx - adds type-specific methods to ATL3 CRegKey + +#if (_ATL_VER < 0x0700) + +class CRegKeyEx : public ATL::CRegKey +{ +public: +// Constructors and operators + CRegKeyEx(HKEY hKey = NULL) + { + m_hKey = hKey; + } + + CRegKeyEx(CRegKeyEx& key) + { + Attach(key.Detach()); + } + + CRegKeyEx& operator =(CRegKeyEx& key) + { + Close(); + Attach(key.Detach()); + return *this; + } + +// Methods + LONG SetValue(LPCTSTR pszValueName, DWORD dwType, const void* pValue, ULONG nBytes) + { + ATLASSERT(m_hKey != NULL); + return ::RegSetValueEx(m_hKey, pszValueName, NULL, dwType, static_cast(pValue), nBytes); + } + + LONG SetGUIDValue(LPCTSTR pszValueName, REFGUID guidValue) + { + ATLASSERT(m_hKey != NULL); + + OLECHAR szGUID[64] = { 0 }; + ::StringFromGUID2(guidValue, szGUID, 64); + + USES_CONVERSION; + LPCTSTR lpstr = OLE2CT(szGUID); +#ifndef _UNICODE + if(lpstr == NULL) + return E_OUTOFMEMORY; +#endif + return SetStringValue(pszValueName, lpstr); + } + + LONG SetBinaryValue(LPCTSTR pszValueName, const void* pValue, ULONG nBytes) + { + ATLASSERT(m_hKey != NULL); + return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_BINARY, reinterpret_cast(pValue), nBytes); + } + + LONG SetDWORDValue(LPCTSTR pszValueName, DWORD dwValue) + { + ATLASSERT(m_hKey != NULL); + return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_DWORD, reinterpret_cast(&dwValue), sizeof(DWORD)); + } + +#ifndef _WIN32_WCE + LONG SetQWORDValue(LPCTSTR pszValueName, ULONGLONG qwValue) + { + ATLASSERT(m_hKey != NULL); + return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_QWORD, reinterpret_cast(&qwValue), sizeof(ULONGLONG)); + } +#endif + + LONG SetStringValue(LPCTSTR pszValueName, LPCTSTR pszValue, DWORD dwType = REG_SZ) + { + ATLASSERT(m_hKey != NULL); + if(pszValue == NULL) + { + ATLASSERT(FALSE); + return ERROR_INVALID_DATA; + } + ATLASSERT((dwType == REG_SZ) || (dwType == REG_EXPAND_SZ)); + + return ::RegSetValueEx(m_hKey, pszValueName, NULL, dwType, reinterpret_cast(pszValue), (lstrlen(pszValue) + 1) * sizeof(TCHAR)); + } + + LONG SetMultiStringValue(LPCTSTR pszValueName, LPCTSTR pszValue) + { + ATLASSERT(m_hKey != NULL); + if(pszValue == NULL) + { + ATLASSERT(FALSE); + return ERROR_INVALID_DATA; + } + + ULONG nBytes = 0; + ULONG nLength = 0; + LPCTSTR pszTemp = pszValue; + do + { + nLength = lstrlen(pszTemp) + 1; + pszTemp += nLength; + nBytes += nLength * sizeof(TCHAR); + } while (nLength != 1); + + return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_MULTI_SZ, reinterpret_cast(pszValue), nBytes); + } + + LONG QueryValue(LPCTSTR pszValueName, DWORD* pdwType, void* pData, ULONG* pnBytes) + { + ATLASSERT(m_hKey != NULL); + return ::RegQueryValueEx(m_hKey, pszValueName, NULL, pdwType, static_cast(pData), pnBytes); + } + + LONG QueryGUIDValue(LPCTSTR pszValueName, GUID& guidValue) + { + ATLASSERT(m_hKey != NULL); + + guidValue = GUID_NULL; + + TCHAR szGUID[64] = { 0 }; + ULONG nCount = 64; + LONG lRes = QueryStringValue(pszValueName, szGUID, &nCount); + + if (lRes != ERROR_SUCCESS) + return lRes; + + if(szGUID[0] != _T('{')) + return ERROR_INVALID_DATA; + + USES_CONVERSION; + LPOLESTR lpstr = T2OLE(szGUID); +#ifndef _UNICODE + if(lpstr == NULL) + return E_OUTOFMEMORY; +#endif + + HRESULT hr = ::CLSIDFromString(lpstr, &guidValue); + if (FAILED(hr)) + return ERROR_INVALID_DATA; + + return ERROR_SUCCESS; + } + + LONG QueryBinaryValue(LPCTSTR pszValueName, void* pValue, ULONG* pnBytes) + { + ATLASSERT(pnBytes != NULL); + ATLASSERT(m_hKey != NULL); + + DWORD dwType = 0; + LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast(pValue), pnBytes); + if (lRes != ERROR_SUCCESS) + return lRes; + if (dwType != REG_BINARY) + return ERROR_INVALID_DATA; + + return ERROR_SUCCESS; + } + + LONG QueryDWORDValue(LPCTSTR pszValueName, DWORD& dwValue) + { + ATLASSERT(m_hKey != NULL); + + ULONG nBytes = sizeof(DWORD); + DWORD dwType = 0; + LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast(&dwValue), &nBytes); + if (lRes != ERROR_SUCCESS) + return lRes; + if (dwType != REG_DWORD) + return ERROR_INVALID_DATA; + + return ERROR_SUCCESS; + } + + LONG QueryQWORDValue(LPCTSTR pszValueName, ULONGLONG& qwValue) + { + ATLASSERT(m_hKey != NULL); + + ULONG nBytes = sizeof(ULONGLONG); + DWORD dwType = 0; + LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast(&qwValue), &nBytes); + if (lRes != ERROR_SUCCESS) + return lRes; + if (dwType != REG_QWORD) + return ERROR_INVALID_DATA; + + return ERROR_SUCCESS; + } + + LONG QueryStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG* pnChars) + { + ATLASSERT(m_hKey != NULL); + ATLASSERT(pnChars != NULL); + + ULONG nBytes = (*pnChars) * sizeof(TCHAR); + DWORD dwType = 0; + *pnChars = 0; + LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast(pszValue), &nBytes); + + if (lRes != ERROR_SUCCESS) + { + return lRes; + } + + if(dwType != REG_SZ && dwType != REG_EXPAND_SZ) + { + return ERROR_INVALID_DATA; + } + + if (pszValue != NULL) + { + if(nBytes != 0) + { + if ((nBytes % sizeof(TCHAR) != 0) || (pszValue[nBytes / sizeof(TCHAR) -1] != 0)) + return ERROR_INVALID_DATA; + } + else + { + pszValue[0] = _T('\0'); + } + } + + *pnChars = nBytes / sizeof(TCHAR); + + return ERROR_SUCCESS; + } + + LONG QueryMultiStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG* pnChars) + { + ATLASSERT(m_hKey != NULL); + ATLASSERT(pnChars != NULL); + + if (pszValue != NULL && *pnChars < 2) + return ERROR_INSUFFICIENT_BUFFER; + + ULONG nBytes = (*pnChars) * sizeof(TCHAR); + DWORD dwType = 0; + *pnChars = 0; + LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast(pszValue), &nBytes); + if (lRes != ERROR_SUCCESS) + return lRes; + if (dwType != REG_MULTI_SZ) + return ERROR_INVALID_DATA; + if (pszValue != NULL && (nBytes % sizeof(TCHAR) != 0 || nBytes / sizeof(TCHAR) < 1 || pszValue[nBytes / sizeof(TCHAR) - 1] != 0 || ((nBytes / sizeof(TCHAR)) > 1 && pszValue[nBytes / sizeof(TCHAR) - 2] != 0))) + return ERROR_INVALID_DATA; + + *pnChars = nBytes / sizeof(TCHAR); + + return ERROR_SUCCESS; + } +}; + +#else // !(_ATL_VER < 0x0700) + +typedef ATL::CRegKey CRegKeyEx; + +#endif // !(_ATL_VER < 0x0700) + + +/////////////////////////////////////////////////////////////////////////////// +// CString forward reference (enables CString use in atluser.h and atlgdi.h) + +#if defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING) + #define _WTL_USE_CSTRING +#endif // defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING) + +#ifdef _WTL_USE_CSTRING + class CString; // forward declaration (include atlmisc.h for the whole class) +#endif // _WTL_USE_CSTRING + +// CString namespace +#ifndef _CSTRING_NS + #ifdef __ATLSTR_H__ + #define _CSTRING_NS ATL + #else + #define _CSTRING_NS WTL + #endif +#endif // _CSTRING_NS + +// Type classes namespace +#ifndef _WTYPES_NS + #ifdef __ATLTYPES_H__ + #define _WTYPES_NS + #else + #define _WTYPES_NS WTL + #endif +#endif // _WTYPES_NS + +}; // namespace WTL + + +/////////////////////////////////////////////////////////////////////////////// +// General DLL version helpers (excluded from atlbase.h if _ATL_DLL is defined) + +#if (_ATL_VER < 0x0700) && defined(_ATL_DLL) && !defined(_WIN32_WCE) + +namespace ATL +{ + +inline HRESULT AtlGetDllVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionInfo) +{ + ATLASSERT(pDllVersionInfo != NULL); + if(pDllVersionInfo == NULL) + return E_INVALIDARG; + + // We must get this function explicitly because some DLLs don't implement it. + DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress(hInstDLL, "DllGetVersion"); + if(pfnDllGetVersion == NULL) + return E_NOTIMPL; + + return (*pfnDllGetVersion)(pDllVersionInfo); +} + +inline HRESULT AtlGetDllVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersionInfo) +{ + HINSTANCE hInstDLL = ::LoadLibrary(lpstrDllName); + if(hInstDLL == NULL) + return E_FAIL; + HRESULT hRet = AtlGetDllVersion(hInstDLL, pDllVersionInfo); + ::FreeLibrary(hInstDLL); + return hRet; +} + +// Common Control Versions: +// Win95/WinNT 4.0 maj=4 min=00 +// IE 3.x maj=4 min=70 +// IE 4.0 maj=4 min=71 +inline HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor) +{ + ATLASSERT(pdwMajor != NULL && pdwMinor != NULL); + if(pdwMajor == NULL || pdwMinor == NULL) + return E_INVALIDARG; + + DLLVERSIONINFO dvi; + ::ZeroMemory(&dvi, sizeof(dvi)); + dvi.cbSize = sizeof(dvi); + HRESULT hRet = AtlGetDllVersion(_T("comctl32.dll"), &dvi); + + if(SUCCEEDED(hRet)) + { + *pdwMajor = dvi.dwMajorVersion; + *pdwMinor = dvi.dwMinorVersion; + } + else if(hRet == E_NOTIMPL) + { + // If DllGetVersion is not there, then the DLL is a version + // previous to the one shipped with IE 3.x + *pdwMajor = 4; + *pdwMinor = 0; + hRet = S_OK; + } + + return hRet; +} + +// Shell Versions: +// Win95/WinNT 4.0 maj=4 min=00 +// IE 3.x, IE 4.0 without Web Integrated Desktop maj=4 min=00 +// IE 4.0 with Web Integrated Desktop maj=4 min=71 +// IE 4.01 with Web Integrated Desktop maj=4 min=72 +inline HRESULT AtlGetShellVersion(LPDWORD pdwMajor, LPDWORD pdwMinor) +{ + ATLASSERT(pdwMajor != NULL && pdwMinor != NULL); + if(pdwMajor == NULL || pdwMinor == NULL) + return E_INVALIDARG; + + DLLVERSIONINFO dvi; + ::ZeroMemory(&dvi, sizeof(dvi)); + dvi.cbSize = sizeof(dvi); + HRESULT hRet = AtlGetDllVersion(_T("shell32.dll"), &dvi); + + if(SUCCEEDED(hRet)) + { + *pdwMajor = dvi.dwMajorVersion; + *pdwMinor = dvi.dwMinorVersion; + } + else if(hRet == E_NOTIMPL) + { + // If DllGetVersion is not there, then the DLL is a version + // previous to the one shipped with IE 4.x + *pdwMajor = 4; + *pdwMinor = 0; + hRet = S_OK; + } + + return hRet; +} + +}; // namespace ATL + +#endif // (_ATL_VER < 0x0700) && defined(_ATL_DLL) && !defined(_WIN32_WCE) + + +// These are always included +#include "atlwinx.h" +#include "atluser.h" +#include "atlgdi.h" + +#ifndef _WTL_NO_AUTOMATIC_NAMESPACE +using namespace WTL; +#endif // !_WTL_NO_AUTOMATIC_NAMESPACE + +#endif // __ATLAPP_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlcrack.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlcrack.h new file mode 100644 index 0000000000..b9971b5510 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlcrack.h @@ -0,0 +1,2384 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLCRACK_H__ +#define __ATLCRACK_H__ + +#pragma once + +#ifndef __ATLAPP_H__ + #error atlcrack.h requires atlapp.h to be included first +#endif + + +/////////////////////////////////////////////////////////////////////////////// +// Message map macro for cracked handlers + +// Note about message maps with cracked handlers: +// For ATL 3.0, a message map using cracked handlers MUST use BEGIN_MSG_MAP_EX. +// For ATL 7.0 or higher, you can use BEGIN_MSG_MAP for CWindowImpl/CDialogImpl derived classes, +// but must use BEGIN_MSG_MAP_EX for classes that don't derive from CWindowImpl/CDialogImpl. + +#define BEGIN_MSG_MAP_EX(theClass) \ +public: \ + BOOL m_bMsgHandled; \ + /* "handled" management for cracked handlers */ \ + BOOL IsMsgHandled() const \ + { \ + return m_bMsgHandled; \ + } \ + void SetMsgHandled(BOOL bHandled) \ + { \ + m_bMsgHandled = bHandled; \ + } \ + BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0) \ + { \ + BOOL bOldMsgHandled = m_bMsgHandled; \ + BOOL bRet = _ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, dwMsgMapID); \ + m_bMsgHandled = bOldMsgHandled; \ + return bRet; \ + } \ + BOOL _ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID) \ + { \ + BOOL bHandled = TRUE; \ + hWnd; \ + uMsg; \ + wParam; \ + lParam; \ + lResult; \ + bHandled; \ + switch(dwMsgMapID) \ + { \ + case 0: + + +/////////////////////////////////////////////////////////////////////////////// +// Standard Windows message macros + +// int OnCreate(LPCREATESTRUCT lpCreateStruct) +#define MSG_WM_CREATE(func) \ + if (uMsg == WM_CREATE) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((LPCREATESTRUCT)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam) +#define MSG_WM_INITDIALOG(func) \ + if (uMsg == WM_INITDIALOG) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HWND)wParam, lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// BOOL OnCopyData(CWindow wnd, PCOPYDATASTRUCT pCopyDataStruct) +#define MSG_WM_COPYDATA(func) \ + if (uMsg == WM_COPYDATA) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HWND)wParam, (PCOPYDATASTRUCT)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnDestroy() +#define MSG_WM_DESTROY(func) \ + if (uMsg == WM_DESTROY) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnMove(CPoint ptPos) +#define MSG_WM_MOVE(func) \ + if (uMsg == WM_MOVE) \ + { \ + SetMsgHandled(TRUE); \ + func(_WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnSize(UINT nType, CSize size) +#define MSG_WM_SIZE(func) \ + if (uMsg == WM_SIZE) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnActivate(UINT nState, BOOL bMinimized, CWindow wndOther) +#define MSG_WM_ACTIVATE(func) \ + if (uMsg == WM_ACTIVATE) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)LOWORD(wParam), (BOOL)HIWORD(wParam), (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnSetFocus(CWindow wndOld) +#define MSG_WM_SETFOCUS(func) \ + if (uMsg == WM_SETFOCUS) \ + { \ + SetMsgHandled(TRUE); \ + func((HWND)wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnKillFocus(CWindow wndFocus) +#define MSG_WM_KILLFOCUS(func) \ + if (uMsg == WM_KILLFOCUS) \ + { \ + SetMsgHandled(TRUE); \ + func((HWND)wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnEnable(BOOL bEnable) +#define MSG_WM_ENABLE(func) \ + if (uMsg == WM_ENABLE) \ + { \ + SetMsgHandled(TRUE); \ + func((BOOL)wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnPaint(CDCHandle dc) +#define MSG_WM_PAINT(func) \ + if (uMsg == WM_PAINT) \ + { \ + SetMsgHandled(TRUE); \ + func((HDC)wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnClose() +#define MSG_WM_CLOSE(func) \ + if (uMsg == WM_CLOSE) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// BOOL OnQueryEndSession(UINT nSource, UINT uLogOff) +#define MSG_WM_QUERYENDSESSION(func) \ + if (uMsg == WM_QUERYENDSESSION) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((UINT)wParam, (UINT)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// BOOL OnQueryOpen() +#define MSG_WM_QUERYOPEN(func) \ + if (uMsg == WM_QUERYOPEN) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func(); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// BOOL OnEraseBkgnd(CDCHandle dc) +#define MSG_WM_ERASEBKGND(func) \ + if (uMsg == WM_ERASEBKGND) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HDC)wParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnSysColorChange() +#define MSG_WM_SYSCOLORCHANGE(func) \ + if (uMsg == WM_SYSCOLORCHANGE) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnEndSession(BOOL bEnding, UINT uLogOff) +#define MSG_WM_ENDSESSION(func) \ + if (uMsg == WM_ENDSESSION) \ + { \ + SetMsgHandled(TRUE); \ + func((BOOL)wParam, (UINT)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnShowWindow(BOOL bShow, UINT nStatus) +#define MSG_WM_SHOWWINDOW(func) \ + if (uMsg == WM_SHOWWINDOW) \ + { \ + SetMsgHandled(TRUE); \ + func((BOOL)wParam, (int)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// HBRUSH OnCtlColorEdit(CDCHandle dc, CEdit edit) +#define MSG_WM_CTLCOLOREDIT(func) \ + if (uMsg == WM_CTLCOLOREDIT) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// HBRUSH OnCtlColorListBox(CDCHandle dc, CListBox listBox) +#define MSG_WM_CTLCOLORLISTBOX(func) \ + if (uMsg == WM_CTLCOLORLISTBOX) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// HBRUSH OnCtlColorBtn(CDCHandle dc, CButton button) +#define MSG_WM_CTLCOLORBTN(func) \ + if (uMsg == WM_CTLCOLORBTN) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// HBRUSH OnCtlColorDlg(CDCHandle dc, CWindow wnd) +#define MSG_WM_CTLCOLORDLG(func) \ + if (uMsg == WM_CTLCOLORDLG) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// HBRUSH OnCtlColorScrollBar(CDCHandle dc, CScrollBar scrollBar) +#define MSG_WM_CTLCOLORSCROLLBAR(func) \ + if (uMsg == WM_CTLCOLORSCROLLBAR) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// HBRUSH OnCtlColorStatic(CDCHandle dc, CStatic wndStatic) +#define MSG_WM_CTLCOLORSTATIC(func) \ + if (uMsg == WM_CTLCOLORSTATIC) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnSettingChange(UINT uFlags, LPCTSTR lpszSection) +#define MSG_WM_SETTINGCHANGE(func) \ + if (uMsg == WM_SETTINGCHANGE) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, (LPCTSTR)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnDevModeChange(LPCTSTR lpDeviceName) +#define MSG_WM_DEVMODECHANGE(func) \ + if (uMsg == WM_DEVMODECHANGE) \ + { \ + SetMsgHandled(TRUE); \ + func((LPCTSTR)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnActivateApp(BOOL bActive, DWORD dwThreadID) +#define MSG_WM_ACTIVATEAPP(func) \ + if (uMsg == WM_ACTIVATEAPP) \ + { \ + SetMsgHandled(TRUE); \ + func((BOOL)wParam, (DWORD)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnFontChange() +#define MSG_WM_FONTCHANGE(func) \ + if (uMsg == WM_FONTCHANGE) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnTimeChange() +#define MSG_WM_TIMECHANGE(func) \ + if (uMsg == WM_TIMECHANGE) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnCancelMode() +#define MSG_WM_CANCELMODE(func) \ + if (uMsg == WM_CANCELMODE) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// BOOL OnSetCursor(CWindow wnd, UINT nHitTest, UINT message) +#define MSG_WM_SETCURSOR(func) \ + if (uMsg == WM_SETCURSOR) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HWND)wParam, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// int OnMouseActivate(CWindow wndTopLevel, UINT nHitTest, UINT message) +#define MSG_WM_MOUSEACTIVATE(func) \ + if (uMsg == WM_MOUSEACTIVATE) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HWND)wParam, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnChildActivate() +#define MSG_WM_CHILDACTIVATE(func) \ + if (uMsg == WM_CHILDACTIVATE) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnGetMinMaxInfo(LPMINMAXINFO lpMMI) +#define MSG_WM_GETMINMAXINFO(func) \ + if (uMsg == WM_GETMINMAXINFO) \ + { \ + SetMsgHandled(TRUE); \ + func((LPMINMAXINFO)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnIconEraseBkgnd(CDCHandle dc) +#define MSG_WM_ICONERASEBKGND(func) \ + if (uMsg == WM_ICONERASEBKGND) \ + { \ + SetMsgHandled(TRUE); \ + func((HDC)wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnSpoolerStatus(UINT nStatus, UINT nJobs) +#define MSG_WM_SPOOLERSTATUS(func) \ + if (uMsg == WM_SPOOLERSTATUS) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, (UINT)LOWORD(lParam)); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) +#define MSG_WM_DRAWITEM(func) \ + if (uMsg == WM_DRAWITEM) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, (LPDRAWITEMSTRUCT)lParam); \ + lResult = TRUE; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct) +#define MSG_WM_MEASUREITEM(func) \ + if (uMsg == WM_MEASUREITEM) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, (LPMEASUREITEMSTRUCT)lParam); \ + lResult = TRUE; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnDeleteItem(int nIDCtl, LPDELETEITEMSTRUCT lpDeleteItemStruct) +#define MSG_WM_DELETEITEM(func) \ + if (uMsg == WM_DELETEITEM) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, (LPDELETEITEMSTRUCT)lParam); \ + lResult = TRUE; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +//int OnCharToItem(UINT nChar, UINT nIndex, CListBox listBox) +#define MSG_WM_CHARTOITEM(func) \ + if (uMsg == WM_CHARTOITEM) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), (HWND)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// int OnVKeyToItem(UINT nKey, UINT nIndex, CListBox listBox) +#define MSG_WM_VKEYTOITEM(func) \ + if (uMsg == WM_VKEYTOITEM) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), (HWND)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// HCURSOR OnQueryDragIcon() +#define MSG_WM_QUERYDRAGICON(func) \ + if (uMsg == WM_QUERYDRAGICON) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func(); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// int OnCompareItem(int nIDCtl, LPCOMPAREITEMSTRUCT lpCompareItemStruct) +#define MSG_WM_COMPAREITEM(func) \ + if (uMsg == WM_COMPAREITEM) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((UINT)wParam, (LPCOMPAREITEMSTRUCT)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnCompacting(UINT nCpuTime) +#define MSG_WM_COMPACTING(func) \ + if (uMsg == WM_COMPACTING) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// BOOL OnNcCreate(LPCREATESTRUCT lpCreateStruct) +#define MSG_WM_NCCREATE(func) \ + if (uMsg == WM_NCCREATE) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((LPCREATESTRUCT)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnNcDestroy() +#define MSG_WM_NCDESTROY(func) \ + if (uMsg == WM_NCDESTROY) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnNcCalcSize(BOOL bCalcValidRects, LPARAM lParam) +#define MSG_WM_NCCALCSIZE(func) \ + if (uMsg == WM_NCCALCSIZE) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func((BOOL)wParam, lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// UINT OnNcHitTest(CPoint point) +#define MSG_WM_NCHITTEST(func) \ + if (uMsg == WM_NCHITTEST) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func(_WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnNcPaint(CRgnHandle rgn) +#define MSG_WM_NCPAINT(func) \ + if (uMsg == WM_NCPAINT) \ + { \ + SetMsgHandled(TRUE); \ + func((HRGN)wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// BOOL OnNcActivate(BOOL bActive) +#define MSG_WM_NCACTIVATE(func) \ + if (uMsg == WM_NCACTIVATE) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((BOOL)wParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// UINT OnGetDlgCode(LPMSG lpMsg) +#define MSG_WM_GETDLGCODE(func) \ + if (uMsg == WM_GETDLGCODE) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((LPMSG)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnNcMouseMove(UINT nHitTest, CPoint point) +#define MSG_WM_NCMOUSEMOVE(func) \ + if (uMsg == WM_NCMOUSEMOVE) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnNcLButtonDown(UINT nHitTest, CPoint point) +#define MSG_WM_NCLBUTTONDOWN(func) \ + if (uMsg == WM_NCLBUTTONDOWN) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnNcLButtonUp(UINT nHitTest, CPoint point) +#define MSG_WM_NCLBUTTONUP(func) \ + if (uMsg == WM_NCLBUTTONUP) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnNcLButtonDblClk(UINT nHitTest, CPoint point) +#define MSG_WM_NCLBUTTONDBLCLK(func) \ + if (uMsg == WM_NCLBUTTONDBLCLK) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnNcRButtonDown(UINT nHitTest, CPoint point) +#define MSG_WM_NCRBUTTONDOWN(func) \ + if (uMsg == WM_NCRBUTTONDOWN) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnNcRButtonUp(UINT nHitTest, CPoint point) +#define MSG_WM_NCRBUTTONUP(func) \ + if (uMsg == WM_NCRBUTTONUP) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnNcRButtonDblClk(UINT nHitTest, CPoint point) +#define MSG_WM_NCRBUTTONDBLCLK(func) \ + if (uMsg == WM_NCRBUTTONDBLCLK) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnNcMButtonDown(UINT nHitTest, CPoint point) +#define MSG_WM_NCMBUTTONDOWN(func) \ + if (uMsg == WM_NCMBUTTONDOWN) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnNcMButtonUp(UINT nHitTest, CPoint point) +#define MSG_WM_NCMBUTTONUP(func) \ + if (uMsg == WM_NCMBUTTONUP) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnNcMButtonDblClk(UINT nHitTest, CPoint point) +#define MSG_WM_NCMBUTTONDBLCLK(func) \ + if (uMsg == WM_NCMBUTTONDBLCLK) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +#define MSG_WM_KEYDOWN(func) \ + if (uMsg == WM_KEYDOWN) \ + { \ + SetMsgHandled(TRUE); \ + func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +#define MSG_WM_KEYUP(func) \ + if (uMsg == WM_KEYUP) \ + { \ + SetMsgHandled(TRUE); \ + func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) +#define MSG_WM_CHAR(func) \ + if (uMsg == WM_CHAR) \ + { \ + SetMsgHandled(TRUE); \ + func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnDeadChar(UINT nChar, UINT nRepCnt, UINT nFlags) +#define MSG_WM_DEADCHAR(func) \ + if (uMsg == WM_DEADCHAR) \ + { \ + SetMsgHandled(TRUE); \ + func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +#define MSG_WM_SYSKEYDOWN(func) \ + if (uMsg == WM_SYSKEYDOWN) \ + { \ + SetMsgHandled(TRUE); \ + func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnSysKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +#define MSG_WM_SYSKEYUP(func) \ + if (uMsg == WM_SYSKEYUP) \ + { \ + SetMsgHandled(TRUE); \ + func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnSysChar(UINT nChar, UINT nRepCnt, UINT nFlags) +#define MSG_WM_SYSCHAR(func) \ + if (uMsg == WM_SYSCHAR) \ + { \ + SetMsgHandled(TRUE); \ + func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnSysDeadChar(UINT nChar, UINT nRepCnt, UINT nFlags) +#define MSG_WM_SYSDEADCHAR(func) \ + if (uMsg == WM_SYSDEADCHAR) \ + { \ + SetMsgHandled(TRUE); \ + func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnSysCommand(UINT nID, LPARAM lParam) +#define MSG_WM_SYSCOMMAND(func) \ + if (uMsg == WM_SYSCOMMAND) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnTCard(UINT idAction, DWORD dwActionData) +#define MSG_WM_TCARD(func) \ + if (uMsg == WM_TCARD) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, (DWORD)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnTimer(UINT_PTR nIDEvent) +#define MSG_WM_TIMER(func) \ + if (uMsg == WM_TIMER) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT_PTR)wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar) +#define MSG_WM_HSCROLL(func) \ + if (uMsg == WM_HSCROLL) \ + { \ + SetMsgHandled(TRUE); \ + func((int)LOWORD(wParam), (short)HIWORD(wParam), (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar) +#define MSG_WM_VSCROLL(func) \ + if (uMsg == WM_VSCROLL) \ + { \ + SetMsgHandled(TRUE); \ + func((int)LOWORD(wParam), (short)HIWORD(wParam), (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnInitMenu(CMenuHandle menu) +#define MSG_WM_INITMENU(func) \ + if (uMsg == WM_INITMENU) \ + { \ + SetMsgHandled(TRUE); \ + func((HMENU)wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnInitMenuPopup(CMenuHandle menuPopup, UINT nIndex, BOOL bSysMenu) +#define MSG_WM_INITMENUPOPUP(func) \ + if (uMsg == WM_INITMENUPOPUP) \ + { \ + SetMsgHandled(TRUE); \ + func((HMENU)wParam, (UINT)LOWORD(lParam), (BOOL)HIWORD(lParam)); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnMenuSelect(UINT nItemID, UINT nFlags, CMenuHandle menu) +#define MSG_WM_MENUSELECT(func) \ + if (uMsg == WM_MENUSELECT) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), (HMENU)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnMenuChar(UINT nChar, UINT nFlags, CMenuHandle menu) +#define MSG_WM_MENUCHAR(func) \ + if (uMsg == WM_MENUCHAR) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func((TCHAR)LOWORD(wParam), (UINT)HIWORD(wParam), (HMENU)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnNotify(int idCtrl, LPNMHDR pnmh) +#define MSG_WM_NOTIFY(func) \ + if (uMsg == WM_NOTIFY) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func((int)wParam, (LPNMHDR)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnEnterIdle(UINT nWhy, CWindow wndWho) +#define MSG_WM_ENTERIDLE(func) \ + if (uMsg == WM_ENTERIDLE) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnMouseMove(UINT nFlags, CPoint point) +#define MSG_WM_MOUSEMOVE(func) \ + if (uMsg == WM_MOUSEMOVE) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) +#define MSG_WM_MOUSEWHEEL(func) \ + if (uMsg == WM_MOUSEWHEEL) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((UINT)LOWORD(wParam), (short)HIWORD(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnLButtonDown(UINT nFlags, CPoint point) +#define MSG_WM_LBUTTONDOWN(func) \ + if (uMsg == WM_LBUTTONDOWN) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnLButtonUp(UINT nFlags, CPoint point) +#define MSG_WM_LBUTTONUP(func) \ + if (uMsg == WM_LBUTTONUP) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnLButtonDblClk(UINT nFlags, CPoint point) +#define MSG_WM_LBUTTONDBLCLK(func) \ + if (uMsg == WM_LBUTTONDBLCLK) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnRButtonDown(UINT nFlags, CPoint point) +#define MSG_WM_RBUTTONDOWN(func) \ + if (uMsg == WM_RBUTTONDOWN) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnRButtonUp(UINT nFlags, CPoint point) +#define MSG_WM_RBUTTONUP(func) \ + if (uMsg == WM_RBUTTONUP) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnRButtonDblClk(UINT nFlags, CPoint point) +#define MSG_WM_RBUTTONDBLCLK(func) \ + if (uMsg == WM_RBUTTONDBLCLK) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnMButtonDown(UINT nFlags, CPoint point) +#define MSG_WM_MBUTTONDOWN(func) \ + if (uMsg == WM_MBUTTONDOWN) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnMButtonUp(UINT nFlags, CPoint point) +#define MSG_WM_MBUTTONUP(func) \ + if (uMsg == WM_MBUTTONUP) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnMButtonDblClk(UINT nFlags, CPoint point) +#define MSG_WM_MBUTTONDBLCLK(func) \ + if (uMsg == WM_MBUTTONDBLCLK) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnParentNotify(UINT message, UINT nChildID, LPARAM lParam) +#define MSG_WM_PARENTNOTIFY(func) \ + if (uMsg == WM_PARENTNOTIFY) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnMDIActivate(CWindow wndActivate, CWindow wndDeactivate) +#define MSG_WM_MDIACTIVATE(func) \ + if (uMsg == WM_MDIACTIVATE) \ + { \ + SetMsgHandled(TRUE); \ + func((HWND)wParam, (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnRenderFormat(UINT nFormat) +#define MSG_WM_RENDERFORMAT(func) \ + if (uMsg == WM_RENDERFORMAT) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnRenderAllFormats() +#define MSG_WM_RENDERALLFORMATS(func) \ + if (uMsg == WM_RENDERALLFORMATS) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnDestroyClipboard() +#define MSG_WM_DESTROYCLIPBOARD(func) \ + if (uMsg == WM_DESTROYCLIPBOARD) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnDrawClipboard() +#define MSG_WM_DRAWCLIPBOARD(func) \ + if (uMsg == WM_DRAWCLIPBOARD) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnPaintClipboard(CWindow wndViewer, const LPPAINTSTRUCT lpPaintStruct) +#define MSG_WM_PAINTCLIPBOARD(func) \ + if (uMsg == WM_PAINTCLIPBOARD) \ + { \ + SetMsgHandled(TRUE); \ + func((HWND)wParam, (const LPPAINTSTRUCT)::GlobalLock((HGLOBAL)lParam)); \ + ::GlobalUnlock((HGLOBAL)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnVScrollClipboard(CWindow wndViewer, UINT nSBCode, UINT nPos) +#define MSG_WM_VSCROLLCLIPBOARD(func) \ + if (uMsg == WM_VSCROLLCLIPBOARD) \ + { \ + SetMsgHandled(TRUE); \ + func((HWND)wParam, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnContextMenu(CWindow wnd, CPoint point) +#define MSG_WM_CONTEXTMENU(func) \ + if (uMsg == WM_CONTEXTMENU) \ + { \ + SetMsgHandled(TRUE); \ + func((HWND)wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnSizeClipboard(CWindow wndViewer, const LPRECT lpRect) +#define MSG_WM_SIZECLIPBOARD(func) \ + if (uMsg == WM_SIZECLIPBOARD) \ + { \ + SetMsgHandled(TRUE); \ + func((HWND)wParam, (const LPRECT)::GlobalLock((HGLOBAL)lParam)); \ + ::GlobalUnlock((HGLOBAL)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnAskCbFormatName(UINT nMaxCount, LPTSTR lpszString) +#define MSG_WM_ASKCBFORMATNAME(func) \ + if (uMsg == WM_ASKCBFORMATNAME) \ + { \ + SetMsgHandled(TRUE); \ + func((DWORD)wParam, (LPTSTR)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnChangeCbChain(CWindow wndRemove, CWindow wndAfter) +#define MSG_WM_CHANGECBCHAIN(func) \ + if (uMsg == WM_CHANGECBCHAIN) \ + { \ + SetMsgHandled(TRUE); \ + func((HWND)wParam, (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnHScrollClipboard(CWindow wndViewer, UINT nSBCode, UINT nPos) +#define MSG_WM_HSCROLLCLIPBOARD(func) \ + if (uMsg == WM_HSCROLLCLIPBOARD) \ + { \ + SetMsgHandled(TRUE); \ + func((HWND)wParam, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// BOOL OnQueryNewPalette() +#define MSG_WM_QUERYNEWPALETTE(func) \ + if (uMsg == WM_QUERYNEWPALETTE) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func(); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnPaletteChanged(CWindow wndFocus) +#define MSG_WM_PALETTECHANGED(func) \ + if (uMsg == WM_PALETTECHANGED) \ + { \ + SetMsgHandled(TRUE); \ + func((HWND)wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnPaletteIsChanging(CWindow wndPalChg) +#define MSG_WM_PALETTEISCHANGING(func) \ + if (uMsg == WM_PALETTEISCHANGING) \ + { \ + SetMsgHandled(TRUE); \ + func((HWND)wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnDropFiles(HDROP hDropInfo) +#define MSG_WM_DROPFILES(func) \ + if (uMsg == WM_DROPFILES) \ + { \ + SetMsgHandled(TRUE); \ + func((HDROP)wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnWindowPosChanging(LPWINDOWPOS lpWndPos) +#define MSG_WM_WINDOWPOSCHANGING(func) \ + if (uMsg == WM_WINDOWPOSCHANGING) \ + { \ + SetMsgHandled(TRUE); \ + func((LPWINDOWPOS)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnWindowPosChanged(LPWINDOWPOS lpWndPos) +#define MSG_WM_WINDOWPOSCHANGED(func) \ + if (uMsg == WM_WINDOWPOSCHANGED) \ + { \ + SetMsgHandled(TRUE); \ + func((LPWINDOWPOS)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnExitMenuLoop(BOOL fIsTrackPopupMenu) +#define MSG_WM_EXITMENULOOP(func) \ + if (uMsg == WM_EXITMENULOOP) \ + { \ + SetMsgHandled(TRUE); \ + func((BOOL)wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnEnterMenuLoop(BOOL fIsTrackPopupMenu) +#define MSG_WM_ENTERMENULOOP(func) \ + if (uMsg == WM_ENTERMENULOOP) \ + { \ + SetMsgHandled(TRUE); \ + func((BOOL)wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnStyleChanged(int nStyleType, LPSTYLESTRUCT lpStyleStruct) +#define MSG_WM_STYLECHANGED(func) \ + if (uMsg == WM_STYLECHANGED) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, (LPSTYLESTRUCT)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnStyleChanging(int nStyleType, LPSTYLESTRUCT lpStyleStruct) +#define MSG_WM_STYLECHANGING(func) \ + if (uMsg == WM_STYLECHANGING) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, (LPSTYLESTRUCT)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnSizing(UINT fwSide, LPRECT pRect) +#define MSG_WM_SIZING(func) \ + if (uMsg == WM_SIZING) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, (LPRECT)lParam); \ + lResult = TRUE; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnMoving(UINT fwSide, LPRECT pRect) +#define MSG_WM_MOVING(func) \ + if (uMsg == WM_MOVING) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, (LPRECT)lParam); \ + lResult = TRUE; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnCaptureChanged(CWindow wnd) +#define MSG_WM_CAPTURECHANGED(func) \ + if (uMsg == WM_CAPTURECHANGED) \ + { \ + SetMsgHandled(TRUE); \ + func((HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// BOOL OnDeviceChange(UINT nEventType, DWORD dwData) +#define MSG_WM_DEVICECHANGE(func) \ + if (uMsg == WM_DEVICECHANGE) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((UINT)wParam, (DWORD)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnCommand(UINT uNotifyCode, int nID, CWindow wndCtl) +#define MSG_WM_COMMAND(func) \ + if (uMsg == WM_COMMAND) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnDisplayChange(UINT uBitsPerPixel, CSize sizeScreen) +#define MSG_WM_DISPLAYCHANGE(func) \ + if (uMsg == WM_DISPLAYCHANGE) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, _WTYPES_NS::CSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnEnterSizeMove() +#define MSG_WM_ENTERSIZEMOVE(func) \ + if (uMsg == WM_ENTERSIZEMOVE) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnExitSizeMove() +#define MSG_WM_EXITSIZEMOVE(func) \ + if (uMsg == WM_EXITSIZEMOVE) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// HFONT OnGetFont() +#define MSG_WM_GETFONT(func) \ + if (uMsg == WM_GETFONT) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func(); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnGetHotKey() +#define MSG_WM_GETHOTKEY(func) \ + if (uMsg == WM_GETHOTKEY) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func(); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// HICON OnGetIcon() +#define MSG_WM_GETICON(func) \ + if (uMsg == WM_GETICON) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((UINT)wParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// int OnGetText(int cchTextMax, LPTSTR lpszText) +#define MSG_WM_GETTEXT(func) \ + if (uMsg == WM_GETTEXT) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((int)wParam, (LPTSTR)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// int OnGetTextLength() +#define MSG_WM_GETTEXTLENGTH(func) \ + if (uMsg == WM_GETTEXTLENGTH) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func(); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnHelp(LPHELPINFO lpHelpInfo) +#define MSG_WM_HELP(func) \ + if (uMsg == WM_HELP) \ + { \ + SetMsgHandled(TRUE); \ + func((LPHELPINFO)lParam); \ + lResult = TRUE; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnHotKey(int nHotKeyID, UINT uModifiers, UINT uVirtKey) +#define MSG_WM_HOTKEY(func) \ + if (uMsg == WM_HOTKEY) \ + { \ + SetMsgHandled(TRUE); \ + func((int)wParam, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnInputLangChange(DWORD dwCharSet, HKL hKbdLayout) +#define MSG_WM_INPUTLANGCHANGE(func) \ + if (uMsg == WM_INPUTLANGCHANGE) \ + { \ + SetMsgHandled(TRUE); \ + func((DWORD)wParam, (HKL)lParam); \ + lResult = TRUE; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnInputLangChangeRequest(BOOL bSysCharSet, HKL hKbdLayout) +#define MSG_WM_INPUTLANGCHANGEREQUEST(func) \ + if (uMsg == WM_INPUTLANGCHANGEREQUEST) \ + { \ + SetMsgHandled(TRUE); \ + func((BOOL)wParam, (HKL)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnNextDlgCtl(BOOL bHandle, WPARAM wCtlFocus) +#define MSG_WM_NEXTDLGCTL(func) \ + if (uMsg == WM_NEXTDLGCTL) \ + { \ + SetMsgHandled(TRUE); \ + func((BOOL)LOWORD(lParam), wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnNextMenu(int nVirtKey, LPMDINEXTMENU lpMdiNextMenu) +#define MSG_WM_NEXTMENU(func) \ + if (uMsg == WM_NEXTMENU) \ + { \ + SetMsgHandled(TRUE); \ + func((int)wParam, (LPMDINEXTMENU)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// int OnNotifyFormat(CWindow wndFrom, int nCommand) +#define MSG_WM_NOTIFYFORMAT(func) \ + if (uMsg == WM_NOTIFYFORMAT) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HWND)wParam, (int)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// BOOL OnPowerBroadcast(DWORD dwPowerEvent, DWORD dwData) +#define MSG_WM_POWERBROADCAST(func) \ + if (uMsg == WM_POWERBROADCAST) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((DWORD)wParam, (DWORD)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnPrint(CDCHandle dc, UINT uFlags) +#define MSG_WM_PRINT(func) \ + if (uMsg == WM_PRINT) \ + { \ + SetMsgHandled(TRUE); \ + func((HDC)wParam, (UINT)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnPrintClient(CDCHandle dc, UINT uFlags) +#define MSG_WM_PRINTCLIENT(func) \ + if (uMsg == WM_PRINTCLIENT) \ + { \ + SetMsgHandled(TRUE); \ + func((HDC)wParam, (UINT)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnRasDialEvent(RASCONNSTATE rasconnstate, DWORD dwError) +#define MSG_WM_RASDIALEVENT(func) \ + if (uMsg == WM_RASDIALEVENT) \ + { \ + SetMsgHandled(TRUE); \ + func((RASCONNSTATE)wParam, (DWORD)lParam); \ + lResult = TRUE; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnSetFont(CFontHandle font, BOOL bRedraw) +#define MSG_WM_SETFONT(func) \ + if (uMsg == WM_SETFONT) \ + { \ + SetMsgHandled(TRUE); \ + func((HFONT)wParam, (BOOL)LOWORD(lParam)); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// int OnSetHotKey(int nVirtKey, UINT uFlags) +#define MSG_WM_SETHOTKEY(func) \ + if (uMsg == WM_SETHOTKEY) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((int)LOBYTE(LOWORD(wParam)), (UINT)HIBYTE(LOWORD(wParam))); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// HICON OnSetIcon(UINT uType, HICON hIcon) +#define MSG_WM_SETICON(func) \ + if (uMsg == WM_SETICON) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((UINT)wParam, (HICON)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnSetRedraw(BOOL bRedraw) +#define MSG_WM_SETREDRAW(func) \ + if (uMsg == WM_SETREDRAW) \ + { \ + SetMsgHandled(TRUE); \ + func((BOOL)wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// int OnSetText(LPCTSTR lpstrText) +#define MSG_WM_SETTEXT(func) \ + if (uMsg == WM_SETTEXT) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((LPCTSTR)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnUserChanged() +#define MSG_WM_USERCHANGED(func) \ + if (uMsg == WM_USERCHANGED) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +/////////////////////////////////////////////////////////////////////////////// +// New NT4 & NT5 messages + +#if(_WIN32_WINNT >= 0x0400) + +// void OnMouseHover(WPARAM wParam, CPoint ptPos) +#define MSG_WM_MOUSEHOVER(func) \ + if (uMsg == WM_MOUSEHOVER) \ + { \ + SetMsgHandled(TRUE); \ + func(wParam, _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnMouseLeave() +#define MSG_WM_MOUSELEAVE(func) \ + if (uMsg == WM_MOUSELEAVE) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +#endif /* _WIN32_WINNT >= 0x0400 */ + +#if(WINVER >= 0x0500) + +// void OnMenuRButtonUp(WPARAM wParam, CMenuHandle menu) +#define MSG_WM_MENURBUTTONUP(func) \ + if (uMsg == WM_MENURBUTTONUP) \ + { \ + SetMsgHandled(TRUE); \ + func(wParam, (HMENU)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnMenuDrag(WPARAM wParam, CMenuHandle menu) +#define MSG_WM_MENUDRAG(func) \ + if (uMsg == WM_MENUDRAG) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func(wParam, (HMENU)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnMenuGetObject(PMENUGETOBJECTINFO info) +#define MSG_WM_MENUGETOBJECT(func) \ + if (uMsg == WM_MENUGETOBJECT) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func((PMENUGETOBJECTINFO)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnUnInitMenuPopup(UINT nID, CMenuHandle menu) +#define MSG_WM_UNINITMENUPOPUP(func) \ + if (uMsg == WM_UNINITMENUPOPUP) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)HIWORD(lParam), (HMENU)wParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnMenuCommand(WPARAM nIndex, CMenuHandle menu) +#define MSG_WM_MENUCOMMAND(func) \ + if (uMsg == WM_MENUCOMMAND) \ + { \ + SetMsgHandled(TRUE); \ + func(wParam, (HMENU)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +#endif /* WINVER >= 0x0500 */ + +#if(_WIN32_WINNT >= 0x0500) + +// BOOL OnAppCommand(CWindow wndFocus, short cmd, WORD uDevice, int dwKeys) +#define MSG_WM_APPCOMMAND(func) \ + if (uMsg == WM_APPCOMMAND) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HWND)wParam, GET_APPCOMMAND_LPARAM(lParam), GET_DEVICE_LPARAM(lParam), GET_KEYSTATE_LPARAM(lParam)); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnNCXButtonDown(int fwButton, short nHittest, CPoint ptPos) +#define MSG_WM_NCXBUTTONDOWN(func) \ + if (uMsg == WM_NCXBUTTONDOWN) \ + { \ + SetMsgHandled(TRUE); \ + func(GET_XBUTTON_WPARAM(wParam), GET_NCHITTEST_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnNCXButtonUp(int fwButton, short nHittest, CPoint ptPos) +#define MSG_WM_NCXBUTTONUP(func) \ + if (uMsg == WM_NCXBUTTONUP) \ + { \ + SetMsgHandled(TRUE); \ + func(GET_XBUTTON_WPARAM(wParam), GET_NCHITTEST_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnNCXButtonDblClk(int fwButton, short nHittest, CPoint ptPos) +#define MSG_WM_NCXBUTTONDBLCLK(func) \ + if (uMsg == WM_NCXBUTTONDBLCLK) \ + { \ + SetMsgHandled(TRUE); \ + func(GET_XBUTTON_WPARAM(wParam), GET_NCHITTEST_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnXButtonDown(int fwButton, int dwKeys, CPoint ptPos) +#define MSG_WM_XBUTTONDOWN(func) \ + if (uMsg == WM_XBUTTONDOWN) \ + { \ + SetMsgHandled(TRUE); \ + func(GET_XBUTTON_WPARAM(wParam), GET_KEYSTATE_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnXButtonUp(int fwButton, int dwKeys, CPoint ptPos) +#define MSG_WM_XBUTTONUP(func) \ + if (uMsg == WM_XBUTTONUP) \ + { \ + SetMsgHandled(TRUE); \ + func(GET_XBUTTON_WPARAM(wParam), GET_KEYSTATE_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnXButtonDblClk(int fwButton, int dwKeys, CPoint ptPos) +#define MSG_WM_XBUTTONDBLCLK(func) \ + if (uMsg == WM_XBUTTONDBLCLK) \ + { \ + SetMsgHandled(TRUE); \ + func(GET_XBUTTON_WPARAM(wParam), GET_KEYSTATE_WPARAM(wParam), _WTYPES_NS::CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnChangeUIState(WORD nAction, WORD nState) +#define MSG_WM_CHANGEUISTATE(func) \ + if (uMsg == WM_CHANGEUISTATE) \ + { \ + SetMsgHandled(TRUE); \ + func(LOWORD(wParam), HIWORD(wParam)); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnUpdateUIState(WORD nAction, WORD nState) +#define MSG_WM_UPDATEUISTATE(func) \ + if (uMsg == WM_UPDATEUISTATE) \ + { \ + SetMsgHandled(TRUE); \ + func(LOWORD(wParam), HIWORD(wParam)); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnQueryUIState() +#define MSG_WM_QUERYUISTATE(func) \ + if (uMsg == WM_QUERYUISTATE) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func(); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +#endif // (_WIN32_WINNT >= 0x0500) + +#if(_WIN32_WINNT >= 0x0501) + +// void OnInput(WPARAM RawInputCode, HRAWINPUT hRawInput) +#define MSG_WM_INPUT(func) \ + if (uMsg == WM_INPUT) \ + { \ + SetMsgHandled(TRUE); \ + func(GET_RAWINPUT_CODE_WPARAM(wParam), (HRAWINPUT)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnUniChar(TCHAR nChar, UINT nRepCnt, UINT nFlags) +#define MSG_WM_UNICHAR(func) \ + if (uMsg == WM_UNICHAR) \ + { \ + SetMsgHandled(TRUE); \ + func((TCHAR)wParam, (UINT)lParam & 0xFFFF, (UINT)((lParam & 0xFFFF0000) >> 16)); \ + if(IsMsgHandled()) \ + { \ + lResult = (wParam == UNICODE_NOCHAR) ? TRUE : FALSE; \ + return TRUE; \ + } \ + } + +// void OnWTSSessionChange(WPARAM nStatusCode, PWTSSESSION_NOTIFICATION nSessionID) +#define MSG_WM_WTSSESSION_CHANGE(func) \ + if (uMsg == WM_WTSSESSION_CHANGE) \ + { \ + SetMsgHandled(TRUE); \ + func(wParam, (PWTSSESSION_NOTIFICATION)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// OnThemeChanged() +#define MSG_WM_THEMECHANGED(func) \ + if (uMsg == WM_THEMECHANGED) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +#endif /* _WIN32_WINNT >= 0x0501 */ + +/////////////////////////////////////////////////////////////////////////////// +// ATL defined messages + +// BOOL OnForwardMsg(LPMSG Msg, DWORD nUserData) +#define MSG_WM_FORWARDMSG(func) \ + if (uMsg == WM_FORWARDMSG) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((LPMSG)lParam, (DWORD)wParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +/////////////////////////////////////////////////////////////////////////////// +// Dialog specific messages + +// LRESULT OnDMGetDefID() +#define MSG_DM_GETDEFID(func) \ + if (uMsg == DM_GETDEFID) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func(); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnDMSetDefID(UINT DefID) +#define MSG_DM_SETDEFID(func) \ + if (uMsg == DM_SETDEFID) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam); \ + lResult = TRUE; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnDMReposition() +#define MSG_DM_REPOSITION(func) \ + if (uMsg == DM_REPOSITION) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +/////////////////////////////////////////////////////////////////////////////// +// Reflected messages + +// void OnReflectedCommand(UINT uNotifyCode, int nID, CWindow wndCtl) +#define MSG_OCM_COMMAND(func) \ + if (uMsg == OCM_COMMAND) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnReflectedNotify(int idCtrl, LPNMHDR pnmh) +#define MSG_OCM_NOTIFY(func) \ + if (uMsg == OCM_NOTIFY) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func((int)wParam, (LPNMHDR)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnReflectedParentNotify(UINT message, UINT nChildID, LPARAM lParam) +#define MSG_OCM_PARENTNOTIFY(func) \ + if (uMsg == OCM_PARENTNOTIFY) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnReflectedDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) +#define MSG_OCM_DRAWITEM(func) \ + if (uMsg == OCM_DRAWITEM) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, (LPDRAWITEMSTRUCT)lParam); \ + lResult = TRUE; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnReflectedMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct) +#define MSG_OCM_MEASUREITEM(func) \ + if (uMsg == OCM_MEASUREITEM) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, (LPMEASUREITEMSTRUCT)lParam); \ + lResult = TRUE; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// int OnReflectedCompareItem(int nIDCtl, LPCOMPAREITEMSTRUCT lpCompareItemStruct) +#define MSG_OCM_COMPAREITEM(func) \ + if (uMsg == OCM_COMPAREITEM) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((UINT)wParam, (LPCOMPAREITEMSTRUCT)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnReflectedDeleteItem(int nIDCtl, LPDELETEITEMSTRUCT lpDeleteItemStruct) +#define MSG_OCM_DELETEITEM(func) \ + if (uMsg == OCM_DELETEITEM) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)wParam, (LPDELETEITEMSTRUCT)lParam); \ + lResult = TRUE; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// int OnReflectedVKeyToItem(UINT nKey, UINT nIndex, CListBox listBox) +#define MSG_OCM_VKEYTOITEM(func) \ + if (uMsg == OCM_VKEYTOITEM) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), (HWND)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +//int OnReflectedCharToItem(UINT nChar, UINT nIndex, CListBox listBox) +#define MSG_OCM_CHARTOITEM(func) \ + if (uMsg == OCM_CHARTOITEM) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((UINT)LOWORD(wParam), (UINT)HIWORD(wParam), (HWND)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnReflectedHScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar) +#define MSG_OCM_HSCROLL(func) \ + if (uMsg == OCM_HSCROLL) \ + { \ + SetMsgHandled(TRUE); \ + func((int)LOWORD(wParam), (short)HIWORD(wParam), (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnReflectedVScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar) +#define MSG_OCM_VSCROLL(func) \ + if (uMsg == OCM_VSCROLL) \ + { \ + SetMsgHandled(TRUE); \ + func((int)LOWORD(wParam), (short)HIWORD(wParam), (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// HBRUSH OnReflectedCtlColorEdit(CDCHandle dc, CEdit edit) +#define MSG_OCM_CTLCOLOREDIT(func) \ + if (uMsg == OCM_CTLCOLOREDIT) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// HBRUSH OnReflectedCtlColorListBox(CDCHandle dc, CListBox listBox) +#define MSG_OCM_CTLCOLORLISTBOX(func) \ + if (uMsg == OCM_CTLCOLORLISTBOX) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// HBRUSH OnReflectedCtlColorBtn(CDCHandle dc, CButton button) +#define MSG_OCM_CTLCOLORBTN(func) \ + if (uMsg == OCM_CTLCOLORBTN) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// HBRUSH OnReflectedCtlColorDlg(CDCHandle dc, CWindow wnd) +#define MSG_OCM_CTLCOLORDLG(func) \ + if (uMsg == OCM_CTLCOLORDLG) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// HBRUSH OnReflectedCtlColorScrollBar(CDCHandle dc, CScrollBar scrollBar) +#define MSG_OCM_CTLCOLORSCROLLBAR(func) \ + if (uMsg == OCM_CTLCOLORSCROLLBAR) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// HBRUSH OnReflectedCtlColorStatic(CDCHandle dc, CStatic wndStatic) +#define MSG_OCM_CTLCOLORSTATIC(func) \ + if (uMsg == OCM_CTLCOLORSTATIC) \ + { \ + SetMsgHandled(TRUE); \ + lResult = (LRESULT)func((HDC)wParam, (HWND)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +/////////////////////////////////////////////////////////////////////////////// +// Edit specific messages + +// void OnClear() +#define MSG_WM_CLEAR(func) \ + if (uMsg == WM_CLEAR) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnCopy() +#define MSG_WM_COPY(func) \ + if (uMsg == WM_COPY) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnCut() +#define MSG_WM_CUT(func) \ + if (uMsg == WM_CUT) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnPaste() +#define MSG_WM_PASTE(func) \ + if (uMsg == WM_PASTE) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnUndo() +#define MSG_WM_UNDO(func) \ + if (uMsg == WM_UNDO) \ + { \ + SetMsgHandled(TRUE); \ + func(); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +/////////////////////////////////////////////////////////////////////////////// +// Generic message handlers + +// LRESULT OnMessageHandlerEX(UINT uMsg, WPARAM wParam, LPARAM lParam) +#define MESSAGE_HANDLER_EX(msg, func) \ + if(uMsg == msg) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func(uMsg, wParam, lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnMessageRangeHandlerEX(UINT uMsg, WPARAM wParam, LPARAM lParam) +#define MESSAGE_RANGE_HANDLER_EX(msgFirst, msgLast, func) \ + if(uMsg >= msgFirst && uMsg <= msgLast) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func(uMsg, wParam, lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +/////////////////////////////////////////////////////////////////////////////// +// Commands and notifications + +// void OnCommandHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) +#define COMMAND_HANDLER_EX(id, code, func) \ + if (uMsg == WM_COMMAND && code == HIWORD(wParam) && id == LOWORD(wParam)) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnCommandIDHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) +#define COMMAND_ID_HANDLER_EX(id, func) \ + if (uMsg == WM_COMMAND && id == LOWORD(wParam)) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnCommandCodeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) +#define COMMAND_CODE_HANDLER_EX(code, func) \ + if (uMsg == WM_COMMAND && code == HIWORD(wParam)) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnNotifyHandlerEX(LPNMHDR pnmh) +#define NOTIFY_HANDLER_EX(id, cd, func) \ + if (uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code && id == ((LPNMHDR)lParam)->idFrom) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func((LPNMHDR)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnNotifyIDHandlerEX(LPNMHDR pnmh) +#define NOTIFY_ID_HANDLER_EX(id, func) \ + if (uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func((LPNMHDR)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnNotifyCodeHandlerEX(LPNMHDR pnmh) +#define NOTIFY_CODE_HANDLER_EX(cd, func) \ + if (uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func((LPNMHDR)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnCommandRangeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) +#define COMMAND_RANGE_HANDLER_EX(idFirst, idLast, func) \ + if(uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnCommandRangeCodeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) +#define COMMAND_RANGE_CODE_HANDLER_EX(idFirst, idLast, code, func) \ + if(uMsg == WM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnNotifyRangeHandlerEX(LPNMHDR pnmh) +#define NOTIFY_RANGE_HANDLER_EX(idFirst, idLast, func) \ + if(uMsg == WM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func((LPNMHDR)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnNotifyRangeCodeHandlerEX(LPNMHDR pnmh) +#define NOTIFY_RANGE_CODE_HANDLER_EX(idFirst, idLast, cd, func) \ + if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func((LPNMHDR)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnReflectedCommandHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) +#define REFLECTED_COMMAND_HANDLER_EX(id, code, func) \ + if (uMsg == OCM_COMMAND && code == HIWORD(wParam) && id == LOWORD(wParam)) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnReflectedCommandIDHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) +#define REFLECTED_COMMAND_ID_HANDLER_EX(id, func) \ + if (uMsg == OCM_COMMAND && id == LOWORD(wParam)) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnReflectedCommandCodeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) +#define REFLECTED_COMMAND_CODE_HANDLER_EX(code, func) \ + if (uMsg == OCM_COMMAND && code == HIWORD(wParam)) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnReflectedNotifyHandlerEX(LPNMHDR pnmh) +#define REFLECTED_NOTIFY_HANDLER_EX(id, cd, func) \ + if (uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code && id == ((LPNMHDR)lParam)->idFrom) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func((LPNMHDR)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnReflectedNotifyIDHandlerEX(LPNMHDR pnmh) +#define REFLECTED_NOTIFY_ID_HANDLER_EX(id, func) \ + if (uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func((LPNMHDR)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnReflectedNotifyCodeHandlerEX(LPNMHDR pnmh) +#define REFLECTED_NOTIFY_CODE_HANDLER_EX(cd, func) \ + if (uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func((LPNMHDR)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnReflectedCommandRangeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) +#define REFLECTED_COMMAND_RANGE_HANDLER_EX(idFirst, idLast, func) \ + if(uMsg == OCM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// void OnReflectedCommandRangeCodeHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl) +#define REFLECTED_COMMAND_RANGE_CODE_HANDLER_EX(idFirst, idLast, code, func) \ + if(uMsg == OCM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ + { \ + SetMsgHandled(TRUE); \ + func((UINT)HIWORD(wParam), (int)LOWORD(wParam), (HWND)lParam); \ + lResult = 0; \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnReflectedNotifyRangeHandlerEX(LPNMHDR pnmh) +#define REFLECTED_NOTIFY_RANGE_HANDLER_EX(idFirst, idLast, func) \ + if(uMsg == OCM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func((LPNMHDR)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +// LRESULT OnReflectedNotifyRangeCodeHandlerEX(LPNMHDR pnmh) +#define REFLECTED_NOTIFY_RANGE_CODE_HANDLER_EX(idFirst, idLast, cd, func) \ + if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ + { \ + SetMsgHandled(TRUE); \ + lResult = func((LPNMHDR)lParam); \ + if(IsMsgHandled()) \ + return TRUE; \ + } + +#endif // __ATLCRACK_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlctrls.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlctrls.h new file mode 100644 index 0000000000..00df403181 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlctrls.h @@ -0,0 +1,10041 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLCTRLS_H__ +#define __ATLCTRLS_H__ + +#pragma once + +#include + +#ifndef __ATLAPP_H__ + #error atlctrls.h requires atlapp.h to be included first +#endif + +#ifndef __ATLWIN_H__ + #error atlctrls.h requires atlwin.h to be included first +#endif + +#ifndef _WIN32_WCE + #include + #include +#elif defined(WIN32_PLATFORM_WFSP) && !defined(_WINUSERM_H_) + #include +#endif // !_WIN32_WCE + +// protect template members from windowsx.h macros +#ifdef _INC_WINDOWSX + #undef GetNextSibling + #undef GetPrevSibling +#endif // _INC_WINDOWSX + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CStaticT - CStatic +// CButtonT - CButton +// CListBoxT - CListBox +// CComboBoxT - CComboBox +// CEditT - CEdit +// CEditCommands +// CScrollBarT - CScrollBar +// +// CImageList +// CListViewCtrlT - CListViewCtrl +// CTreeViewCtrlT - CTreeViewCtrl +// CTreeItemT - CTreeItem +// CTreeViewCtrlExT - CTreeViewCtrlEx +// CHeaderCtrlT - CHeaderCtrl +// CToolBarCtrlT - CToolBarCtrl +// CStatusBarCtrlT - CStatusBarCtrl +// CTabCtrlT - CTabCtrl +// CToolInfo +// CToolTipCtrlT - CToolTipCtrl +// CTrackBarCtrlT - CTrackBarCtrl +// CUpDownCtrlT - CUpDownCtrl +// CProgressBarCtrlT - CProgressBarCtrl +// CHotKeyCtrlT - CHotKeyCtrl +// CAnimateCtrlT - CAnimateCtrl +// CRichEditCtrlT - CRichEditCtrl +// CRichEditCommands +// CDragListBoxT - CDragListBox +// CDragListNotifyImpl +// CReBarCtrlT - CReBarCtrl +// CComboBoxExT - CComboBoxEx +// CDateTimePickerCtrlT - CDateTimePickerCtrl +// CMonthCalendarCtrlT - CMonthCalendarCtrl +// CFlatScrollBarImpl +// CFlatScrollBarT - CFlatScrollBar +// CIPAddressCtrlT - CIPAddressCtrl +// CPagerCtrlT - CPagerCtrl +// CLinkCtrlT - CLinkCtrl +// +// CCustomDraw +// +// CCECommandBarCtrlT - CCECommandBarCtrl +// CCECommandBandsCtrlT - CCECommandBandsCtrl + + +namespace WTL +{ + +// These are wrapper classes for Windows standard and common controls. +// To implement a window based on a control, use following: +// Example: Implementing a window based on a list box +// +// class CMyListBox : CWindowImpl +// { +// public: +// BEGIN_MSG_MAP(CMyListBox) +// // put your message handler entries here +// END_MSG_MAP() +// }; + + + +// --- Standard Windows controls --- + +/////////////////////////////////////////////////////////////////////////////// +// CStatic - client side for a Windows STATIC control + +template +class CStaticT : public TBase +{ +public: +// Constructors + CStaticT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CStaticT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return _T("STATIC"); + } + +#ifndef _WIN32_WCE + HICON GetIcon() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HICON)::SendMessage(m_hWnd, STM_GETICON, 0, 0L); + } + + HICON SetIcon(HICON hIcon) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HICON)::SendMessage(m_hWnd, STM_SETICON, (WPARAM)hIcon, 0L); + } + + HENHMETAFILE GetEnhMetaFile() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HENHMETAFILE)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_ENHMETAFILE, 0L); + } + + HENHMETAFILE SetEnhMetaFile(HENHMETAFILE hMetaFile) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HENHMETAFILE)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_ENHMETAFILE, (LPARAM)hMetaFile); + } +#else // CE specific + HICON GetIcon() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HICON)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_ICON, 0L); + } + + HICON SetIcon(HICON hIcon) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HICON)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + } +#endif // _WIN32_WCE + + CBitmapHandle GetBitmap() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_BITMAP, 0L)); + } + + CBitmapHandle SetBitmap(HBITMAP hBitmap) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap)); + } + + HCURSOR GetCursor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HCURSOR)::SendMessage(m_hWnd, STM_GETIMAGE, IMAGE_CURSOR, 0L); + } + + HCURSOR SetCursor(HCURSOR hCursor) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HCURSOR)::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_CURSOR, (LPARAM)hCursor); + } +}; + +typedef CStaticT CStatic; + + +/////////////////////////////////////////////////////////////////////////////// +// CButton - client side for a Windows BUTTON control + +template +class CButtonT : public TBase +{ +public: +// Constructors + CButtonT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CButtonT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return _T("BUTTON"); + } + + UINT GetState() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, BM_GETSTATE, 0, 0L); + } + + void SetState(BOOL bHighlight) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, BM_SETSTATE, bHighlight, 0L); + } + + int GetCheck() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, BM_GETCHECK, 0, 0L); + } + + void SetCheck(int nCheck) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, BM_SETCHECK, nCheck, 0L); + } + + UINT GetButtonStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::GetWindowLong(m_hWnd, GWL_STYLE) & 0xFFFF; + } + + void SetButtonStyle(UINT nStyle, BOOL bRedraw = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, BM_SETSTYLE, nStyle, (LPARAM)bRedraw); + } + +#ifndef _WIN32_WCE + HICON GetIcon() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HICON)::SendMessage(m_hWnd, BM_GETIMAGE, IMAGE_ICON, 0L); + } + + HICON SetIcon(HICON hIcon) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HICON)::SendMessage(m_hWnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + } + + CBitmapHandle GetBitmap() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, BM_GETIMAGE, IMAGE_BITMAP, 0L)); + } + + CBitmapHandle SetBitmap(HBITMAP hBitmap) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CBitmapHandle((HBITMAP)::SendMessage(m_hWnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap)); + } +#endif // !_WIN32_WCE + +#if (_WIN32_WINNT >= 0x0501) + BOOL GetIdealSize(LPSIZE lpSize) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, BCM_GETIDEALSIZE, 0, (LPARAM)lpSize); + } + + BOOL GetImageList(PBUTTON_IMAGELIST pButtonImagelist) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, BCM_GETIMAGELIST, 0, (LPARAM)pButtonImagelist); + } + + BOOL SetImageList(PBUTTON_IMAGELIST pButtonImagelist) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, BCM_SETIMAGELIST, 0, (LPARAM)pButtonImagelist); + } + + BOOL GetTextMargin(LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, BCM_GETTEXTMARGIN, 0, (LPARAM)lpRect); + } + + BOOL SetTextMargin(LPRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, BCM_SETTEXTMARGIN, 0, (LPARAM)lpRect); + } +#endif // (_WIN32_WINNT >= 0x0501) + +#if (WINVER >= 0x0600) + void SetDontClick(BOOL bDontClick) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, BM_SETDONTCLICK, (WPARAM)bDontClick, 0L); + } +#endif // (WINVER >= 0x0600) + +#if (_WIN32_WINNT >= 0x0600) + BOOL SetDropDownState(BOOL bDropDown) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (BS_SPLITBUTTON | BS_DEFSPLITBUTTON)) != 0); + return (BOOL)::SendMessage(m_hWnd, BCM_SETDROPDOWNSTATE, (WPARAM)bDropDown, 0L); + } + + BOOL GetSplitInfo(PBUTTON_SPLITINFO pSplitInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (BS_SPLITBUTTON | BS_DEFSPLITBUTTON)) != 0); + return (BOOL)::SendMessage(m_hWnd, BCM_GETSPLITINFO, 0, (LPARAM)pSplitInfo); + } + + BOOL SetSplitInfo(PBUTTON_SPLITINFO pSplitInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (BS_SPLITBUTTON | BS_DEFSPLITBUTTON)) != 0); + return (BOOL)::SendMessage(m_hWnd, BCM_SETSPLITINFO, 0, (LPARAM)pSplitInfo); + } + + int GetNoteLength() const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (BS_COMMANDLINK | BS_DEFCOMMANDLINK)) != 0); + return (int)::SendMessage(m_hWnd, BCM_GETNOTELENGTH, 0, 0L); + } + + BOOL GetNote(LPWSTR lpstrNoteText, int cchNoteText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (BS_COMMANDLINK | BS_DEFCOMMANDLINK)) != 0); + return (BOOL)::SendMessage(m_hWnd, BCM_GETNOTE, cchNoteText, (LPARAM)lpstrNoteText); + } + + BOOL SetNote(LPCWSTR lpstrNoteText) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (BS_COMMANDLINK | BS_DEFCOMMANDLINK)) != 0); + return (BOOL)::SendMessage(m_hWnd, BCM_SETNOTE, 0, (LPARAM)lpstrNoteText); + } + + LRESULT SetElevationRequiredState(BOOL bSet) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::SendMessage(m_hWnd, BCM_SETSHIELD, 0, (LPARAM)bSet); + } +#endif // (_WIN32_WINNT >= 0x0600) + +// Operations + void Click() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, BM_CLICK, 0, 0L); + } +}; + +typedef CButtonT CButton; + + +/////////////////////////////////////////////////////////////////////////////// +// CListBox - client side for a Windows LISTBOX control + +template +class CListBoxT : public TBase +{ +public: +// Constructors + CListBoxT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CListBoxT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return _T("LISTBOX"); + } + + // for entire listbox + int GetCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETCOUNT, 0, 0L); + } + +#ifndef _WIN32_WCE + int SetCount(int cItems) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(((GetStyle() & LBS_NODATA) != 0) && ((GetStyle() & LBS_HASSTRINGS) == 0)); + return (int)::SendMessage(m_hWnd, LB_SETCOUNT, cItems, 0L); + } +#endif // !_WIN32_WCE + + int GetHorizontalExtent() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETHORIZONTALEXTENT, 0, 0L); + } + + void SetHorizontalExtent(int cxExtent) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LB_SETHORIZONTALEXTENT, cxExtent, 0L); + } + + int GetTopIndex() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETTOPINDEX, 0, 0L); + } + + int SetTopIndex(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_SETTOPINDEX, nIndex, 0L); + } + + LCID GetLocale() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LCID)::SendMessage(m_hWnd, LB_GETLOCALE, 0, 0L); + } + + LCID SetLocale(LCID nNewLocale) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LCID)::SendMessage(m_hWnd, LB_SETLOCALE, (WPARAM)nNewLocale, 0L); + } + +#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) + DWORD GetListBoxInfo() const + { + ATLASSERT(::IsWindow(m_hWnd)); +#if (_WIN32_WINNT >= 0x0501) + return (DWORD)::SendMessage(m_hWnd, LB_GETLISTBOXINFO, 0, 0L); +#else // !(_WIN32_WINNT >= 0x0501) + return ::GetListBoxInfo(m_hWnd); +#endif // !(_WIN32_WINNT >= 0x0501) + } +#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) + + // for single-selection listboxes + int GetCurSel() const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) == 0); + return (int)::SendMessage(m_hWnd, LB_GETCURSEL, 0, 0L); + } + + int SetCurSel(int nSelect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) == 0); + return (int)::SendMessage(m_hWnd, LB_SETCURSEL, nSelect, 0L); + } + + // for multiple-selection listboxes + int GetSel(int nIndex) const // also works for single-selection + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETSEL, nIndex, 0L); + } + + int SetSel(int nIndex, BOOL bSelect = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); + return (int)::SendMessage(m_hWnd, LB_SETSEL, bSelect, nIndex); + } + + int GetSelCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); + return (int)::SendMessage(m_hWnd, LB_GETSELCOUNT, 0, 0L); + } + + int GetSelItems(int nMaxItems, LPINT rgIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); + return (int)::SendMessage(m_hWnd, LB_GETSELITEMS, nMaxItems, (LPARAM)rgIndex); + } + + int GetAnchorIndex() const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); + return (int)::SendMessage(m_hWnd, LB_GETANCHORINDEX, 0, 0L); + } + + void SetAnchorIndex(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); + ::SendMessage(m_hWnd, LB_SETANCHORINDEX, nIndex, 0L); + } + + int GetCaretIndex() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETCARETINDEX, 0, 0); + } + + int SetCaretIndex(int nIndex, BOOL bScroll = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_SETCARETINDEX, nIndex, MAKELONG(bScroll, 0)); + } + + // for listbox items + DWORD_PTR GetItemData(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD_PTR)::SendMessage(m_hWnd, LB_GETITEMDATA, nIndex, 0L); + } + + int SetItemData(int nIndex, DWORD_PTR dwItemData) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_SETITEMDATA, nIndex, (LPARAM)dwItemData); + } + + void* GetItemDataPtr(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (void*)::SendMessage(m_hWnd, LB_GETITEMDATA, nIndex, 0L); + } + + int SetItemDataPtr(int nIndex, void* pData) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItemData(nIndex, (DWORD_PTR)pData); + } + + int GetItemRect(int nIndex, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETITEMRECT, nIndex, (LPARAM)lpRect); + } + + int GetText(int nIndex, LPTSTR lpszBuffer) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETTEXT, nIndex, (LPARAM)lpszBuffer); + } + +#ifndef _ATL_NO_COM +#ifdef _OLEAUTO_H_ + BOOL GetTextBSTR(int nIndex, BSTR& bstrText) const + { + USES_CONVERSION; + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(bstrText == NULL); + + int nLen = GetTextLen(nIndex); + if(nLen == LB_ERR) + return FALSE; + + CTempBuffer buff; + LPTSTR lpstrText = buff.Allocate(nLen + 1); + if(lpstrText == NULL) + return FALSE; + + if(GetText(nIndex, lpstrText) == LB_ERR) + return FALSE; + + bstrText = ::SysAllocString(T2OLE(lpstrText)); + return (bstrText != NULL) ? TRUE : FALSE; + } +#endif // _OLEAUTO_H_ +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + int GetText(int nIndex, _CSTRING_NS::CString& strText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int cchLen = GetTextLen(nIndex); + if(cchLen == LB_ERR) + return LB_ERR; + int nRet = LB_ERR; + LPTSTR lpstr = strText.GetBufferSetLength(cchLen); + if(lpstr != NULL) + { + nRet = GetText(nIndex, lpstr); + strText.ReleaseBuffer(); + } + return nRet; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + int GetTextLen(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETTEXTLEN, nIndex, 0L); + } + + int GetItemHeight(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_GETITEMHEIGHT, nIndex, 0L); + } + + int SetItemHeight(int nIndex, UINT cyItemHeight) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_SETITEMHEIGHT, nIndex, MAKELONG(cyItemHeight, 0)); + } + + // Settable only attributes + void SetColumnWidth(int cxWidth) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LB_SETCOLUMNWIDTH, cxWidth, 0L); + } + + BOOL SetTabStops(int nTabStops, LPINT rgTabStops) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & LBS_USETABSTOPS) != 0); + return (BOOL)::SendMessage(m_hWnd, LB_SETTABSTOPS, nTabStops, (LPARAM)rgTabStops); + } + + BOOL SetTabStops() + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & LBS_USETABSTOPS) != 0); + return (BOOL)::SendMessage(m_hWnd, LB_SETTABSTOPS, 0, 0L); + } + + BOOL SetTabStops(const int& cxEachStop) // takes an 'int' + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & LBS_USETABSTOPS) != 0); + return (BOOL)::SendMessage(m_hWnd, LB_SETTABSTOPS, 1, (LPARAM)(LPINT)&cxEachStop); + } + +// Operations + int InitStorage(int nItems, UINT nBytes) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_INITSTORAGE, (WPARAM)nItems, nBytes); + } + + void ResetContent() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LB_RESETCONTENT, 0, 0L); + } + + UINT ItemFromPoint(POINT pt, BOOL& bOutside) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dw = (DWORD)::SendMessage(m_hWnd, LB_ITEMFROMPOINT, 0, MAKELPARAM(pt.x, pt.y)); + bOutside = (BOOL)HIWORD(dw); + return (UINT)LOWORD(dw); + } + + // manipulating listbox items + int AddString(LPCTSTR lpszItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_ADDSTRING, 0, (LPARAM)lpszItem); + } + + int DeleteString(UINT nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_DELETESTRING, nIndex, 0L); + } + + int InsertString(int nIndex, LPCTSTR lpszItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_INSERTSTRING, nIndex, (LPARAM)lpszItem); + } + +#ifndef _WIN32_WCE + int Dir(UINT attr, LPCTSTR lpszWildCard) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_DIR, attr, (LPARAM)lpszWildCard); + } + + int AddFile(LPCTSTR lpstrFileName) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_ADDFILE, 0, (LPARAM)lpstrFileName); + } +#endif // !_WIN32_WCE + + // selection helpers + int FindString(int nStartAfter, LPCTSTR lpszItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_FINDSTRING, nStartAfter, (LPARAM)lpszItem); + } + + int FindStringExact(int nIndexStart, LPCTSTR lpszFind) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_FINDSTRINGEXACT, nIndexStart, (LPARAM)lpszFind); + } + + int SelectString(int nStartAfter, LPCTSTR lpszItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LB_SELECTSTRING, nStartAfter, (LPARAM)lpszItem); + } + + int SelItemRange(BOOL bSelect, int nFirstItem, int nLastItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) != 0); + ATLASSERT(nFirstItem <= nLastItem); + return bSelect ? (int)::SendMessage(m_hWnd, LB_SELITEMRANGEEX, nFirstItem, nLastItem) : (int)::SendMessage(m_hWnd, LB_SELITEMRANGEEX, nLastItem, nFirstItem); + } + +#ifdef WIN32_PLATFORM_WFSP // SmartPhone only messages + DWORD GetInputMode(BOOL bCurrentMode = TRUE) + { + return SendMessage(LB_GETINPUTMODE, 0, (LPARAM)bCurrentMode); + } + + BOOL SetInputMode(DWORD dwMode) + { + return SendMessage(LB_SETINPUTMODE, 0, (LPARAM)dwMode); + } +#endif // WIN32_PLATFORM_WFSP +}; + +typedef CListBoxT CListBox; + + +/////////////////////////////////////////////////////////////////////////////// +// CComboBox - client side for a Windows COMBOBOX control + +#ifndef WIN32_PLATFORM_WFSP // No COMBOBOX on SmartPhones + +template +class CComboBoxT : public TBase +{ +public: +// Constructors + CComboBoxT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CComboBoxT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return _T("COMBOBOX"); + } + + // for entire combo box + int GetCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_GETCOUNT, 0, 0L); + } + + int GetCurSel() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_GETCURSEL, 0, 0L); + } + + int SetCurSel(int nSelect) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_SETCURSEL, nSelect, 0L); + } + + LCID GetLocale() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LCID)::SendMessage(m_hWnd, CB_GETLOCALE, 0, 0L); + } + + LCID SetLocale(LCID nNewLocale) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LCID)::SendMessage(m_hWnd, CB_SETLOCALE, (WPARAM)nNewLocale, 0L); + } + + int GetTopIndex() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_GETTOPINDEX, 0, 0L); + } + + int SetTopIndex(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_SETTOPINDEX, nIndex, 0L); + } + + UINT GetHorizontalExtent() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, CB_GETHORIZONTALEXTENT, 0, 0L); + } + + void SetHorizontalExtent(UINT nExtent) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, CB_SETHORIZONTALEXTENT, nExtent, 0L); + } + + int GetDroppedWidth() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_GETDROPPEDWIDTH, 0, 0L); + } + + int SetDroppedWidth(UINT nWidth) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_SETDROPPEDWIDTH, nWidth, 0L); + } + +#if ((WINVER >= 0x0500) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420)) + BOOL GetComboBoxInfo(PCOMBOBOXINFO pComboBoxInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); +#if ((_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420)) + return (BOOL)::SendMessage(m_hWnd, CB_GETCOMBOBOXINFO, 0, (LPARAM)pComboBoxInfo); +#else // !((_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420)) + return ::GetComboBoxInfo(m_hWnd, pComboBoxInfo); +#endif // !((_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420)) + } +#endif // ((WINVER >= 0x0500) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 420)) + + // for edit control + DWORD GetEditSel() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, CB_GETEDITSEL, 0, 0L); + } + + BOOL SetEditSel(int nStartChar, int nEndChar) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CB_SETEDITSEL, 0, MAKELONG(nStartChar, nEndChar)); + } + + // for combobox item + DWORD_PTR GetItemData(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD_PTR)::SendMessage(m_hWnd, CB_GETITEMDATA, nIndex, 0L); + } + + int SetItemData(int nIndex, DWORD_PTR dwItemData) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_SETITEMDATA, nIndex, (LPARAM)dwItemData); + } + + void* GetItemDataPtr(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (void*)GetItemData(nIndex); + } + + int SetItemDataPtr(int nIndex, void* pData) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItemData(nIndex, (DWORD_PTR)pData); + } + + int GetLBText(int nIndex, LPTSTR lpszText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_GETLBTEXT, nIndex, (LPARAM)lpszText); + } + +#ifndef _ATL_NO_COM + BOOL GetLBTextBSTR(int nIndex, BSTR& bstrText) const + { + USES_CONVERSION; + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(bstrText == NULL); + + int nLen = GetLBTextLen(nIndex); + if(nLen == CB_ERR) + return FALSE; + + CTempBuffer buff; + LPTSTR lpstrText = buff.Allocate(nLen + 1); + if(lpstrText == NULL) + return FALSE; + + if(GetLBText(nIndex, lpstrText) == CB_ERR) + return FALSE; + + bstrText = ::SysAllocString(T2OLE(lpstrText)); + return (bstrText != NULL) ? TRUE : FALSE; + } +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + int GetLBText(int nIndex, _CSTRING_NS::CString& strText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int cchLen = GetLBTextLen(nIndex); + if(cchLen == CB_ERR) + return CB_ERR; + int nRet = CB_ERR; + LPTSTR lpstr = strText.GetBufferSetLength(cchLen); + if(lpstr != NULL) + { + nRet = GetLBText(nIndex, lpstr); + strText.ReleaseBuffer(); + } + return nRet; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + int GetLBTextLen(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_GETLBTEXTLEN, nIndex, 0L); + } + + int GetItemHeight(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_GETITEMHEIGHT, nIndex, 0L); + } + + int SetItemHeight(int nIndex, UINT cyItemHeight) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_SETITEMHEIGHT, nIndex, MAKELONG(cyItemHeight, 0)); + } + + BOOL GetExtendedUI() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CB_GETEXTENDEDUI, 0, 0L); + } + + int SetExtendedUI(BOOL bExtended = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_SETEXTENDEDUI, bExtended, 0L); + } + + void GetDroppedControlRect(LPRECT lprect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)lprect); + } + + BOOL GetDroppedState() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CB_GETDROPPEDSTATE, 0, 0L); + } + +#if (_WIN32_WINNT >= 0x0501) + int GetMinVisible() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_GETMINVISIBLE, 0, 0L); + } + + BOOL SetMinVisible(int nMinVisible) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CB_SETMINVISIBLE, nMinVisible, 0L); + } + + // Vista only + BOOL GetCueBannerText(LPWSTR lpwText, int cchText) const + { +#ifndef CB_GETCUEBANNER + const UINT CB_GETCUEBANNER = (CBM_FIRST + 4); +#endif + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CB_GETCUEBANNER, (WPARAM)lpwText, cchText); + } + + // Vista only + BOOL SetCueBannerText(LPCWSTR lpcwText) + { +#ifndef CB_SETCUEBANNER + const UINT CB_SETCUEBANNER = (CBM_FIRST + 3); +#endif + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CB_SETCUEBANNER, 0, (LPARAM)lpcwText); + } +#endif // (_WIN32_WINNT >= 0x0501) + +// Operations + int InitStorage(int nItems, UINT nBytes) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_INITSTORAGE, (WPARAM)nItems, nBytes); + } + + void ResetContent() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, CB_RESETCONTENT, 0, 0L); + } + + // for edit control + BOOL LimitText(int nMaxChars) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CB_LIMITTEXT, nMaxChars, 0L); + } + + // for drop-down combo boxes + void ShowDropDown(BOOL bShowIt = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, CB_SHOWDROPDOWN, bShowIt, 0L); + } + + // manipulating listbox items + int AddString(LPCTSTR lpszString) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_ADDSTRING, 0, (LPARAM)lpszString); + } + + int DeleteString(UINT nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_DELETESTRING, nIndex, 0L); + } + + int InsertString(int nIndex, LPCTSTR lpszString) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_INSERTSTRING, nIndex, (LPARAM)lpszString); + } + +#ifndef _WIN32_WCE + int Dir(UINT attr, LPCTSTR lpszWildCard) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_DIR, attr, (LPARAM)lpszWildCard); + } +#endif // !_WIN32_WCE + + // selection helpers + int FindString(int nStartAfter, LPCTSTR lpszString) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_FINDSTRING, nStartAfter, (LPARAM)lpszString); + } + + int FindStringExact(int nIndexStart, LPCTSTR lpszFind) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_FINDSTRINGEXACT, nIndexStart, (LPARAM)lpszFind); + } + + int SelectString(int nStartAfter, LPCTSTR lpszString) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CB_SELECTSTRING, nStartAfter, (LPARAM)lpszString); + } + + // Clipboard operations + void Clear() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_CLEAR, 0, 0L); + } + + void Copy() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_COPY, 0, 0L); + } + + void Cut() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_CUT, 0, 0L); + } + + void Paste() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_PASTE, 0, 0L); + } +}; + +typedef CComboBoxT CComboBox; + +#endif // !WIN32_PLATFORM_WFSP + +/////////////////////////////////////////////////////////////////////////////// +// CEdit - client side for a Windows EDIT control + +template +class CEditT : public TBase +{ +public: +// Constructors + CEditT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CEditT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return _T("EDIT"); + } + + BOOL CanUndo() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_CANUNDO, 0, 0L); + } + + int GetLineCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETLINECOUNT, 0, 0L); + } + + BOOL GetModify() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_GETMODIFY, 0, 0L); + } + + void SetModify(BOOL bModified = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETMODIFY, bModified, 0L); + } + + void GetRect(LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_GETRECT, 0, (LPARAM)lpRect); + } + + DWORD GetSel() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, EM_GETSEL, 0, 0L); + } + + void GetSel(int& nStartChar, int& nEndChar) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar); + } + +#ifndef _WIN32_WCE + HLOCAL GetHandle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HLOCAL)::SendMessage(m_hWnd, EM_GETHANDLE, 0, 0L); + } + + void SetHandle(HLOCAL hBuffer) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETHANDLE, (WPARAM)hBuffer, 0L); + } +#endif // !_WIN32_WCE + + DWORD GetMargins() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, EM_GETMARGINS, 0, 0L); + } + + void SetMargins(UINT nLeft, UINT nRight) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, MAKELONG(nLeft, nRight)); + } + + UINT GetLimitText() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, EM_GETLIMITTEXT, 0, 0L); + } + + void SetLimitText(UINT nMax) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETLIMITTEXT, nMax, 0L); + } + + POINT PosFromChar(UINT nChar) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, EM_POSFROMCHAR, nChar, 0); + POINT point = { GET_X_LPARAM(dwRet), GET_Y_LPARAM(dwRet) }; + return point; + } + + int CharFromPos(POINT pt, int* pLine = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, EM_CHARFROMPOS, 0, MAKELPARAM(pt.x, pt.y)); + if(pLine != NULL) + *pLine = (int)(short)HIWORD(dwRet); + return (int)(short)LOWORD(dwRet); + } + + // NOTE: first word in lpszBuffer must contain the size of the buffer! + int GetLine(int nIndex, LPTSTR lpszBuffer) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer); + } + + int GetLine(int nIndex, LPTSTR lpszBuffer, int nMaxLength) const + { + ATLASSERT(::IsWindow(m_hWnd)); + *(LPWORD)lpszBuffer = (WORD)nMaxLength; + return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer); + } + + TCHAR GetPasswordChar() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (TCHAR)::SendMessage(m_hWnd, EM_GETPASSWORDCHAR, 0, 0L); + } + + void SetPasswordChar(TCHAR ch) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETPASSWORDCHAR, ch, 0L); + } + +#ifndef _WIN32_WCE + EDITWORDBREAKPROC GetWordBreakProc() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (EDITWORDBREAKPROC)::SendMessage(m_hWnd, EM_GETWORDBREAKPROC, 0, 0L); + } + + void SetWordBreakProc(EDITWORDBREAKPROC ewbprc) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETWORDBREAKPROC, 0, (LPARAM)ewbprc); + } +#endif // !_WIN32_WCE + + int GetFirstVisibleLine() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETFIRSTVISIBLELINE, 0, 0L); + } + +#ifndef _WIN32_WCE + int GetThumb() const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & ES_MULTILINE) != 0); + return (int)::SendMessage(m_hWnd, EM_GETTHUMB, 0, 0L); + } +#endif // !_WIN32_WCE + + BOOL SetReadOnly(BOOL bReadOnly = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETREADONLY, bReadOnly, 0L); + } + +#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) + UINT GetImeStatus(UINT uStatus) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, EM_GETIMESTATUS, uStatus, 0L); + } + + UINT SetImeStatus(UINT uStatus, UINT uData) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, EM_SETIMESTATUS, uStatus, uData); + } +#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) + +#if (_WIN32_WINNT >= 0x0501) + BOOL GetCueBannerText(LPCWSTR lpstrText, int cchText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_GETCUEBANNER, (WPARAM)lpstrText, cchText); + } + + // bKeepWithFocus - Vista only + BOOL SetCueBannerText(LPCWSTR lpstrText, BOOL bKeepWithFocus = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETCUEBANNER, (WPARAM)bKeepWithFocus, (LPARAM)(lpstrText)); + } +#endif // (_WIN32_WINNT >= 0x0501) + +// Operations + void EmptyUndoBuffer() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_EMPTYUNDOBUFFER, 0, 0L); + } + + BOOL FmtLines(BOOL bAddEOL) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_FMTLINES, bAddEOL, 0L); + } + + void LimitText(int nChars = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_LIMITTEXT, nChars, 0L); + } + + int LineFromChar(int nIndex = -1) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_LINEFROMCHAR, nIndex, 0L); + } + + int LineIndex(int nLine = -1) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_LINEINDEX, nLine, 0L); + } + + int LineLength(int nLine = -1) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_LINELENGTH, nLine, 0L); + } + + void LineScroll(int nLines, int nChars = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_LINESCROLL, nChars, nLines); + } + + void ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_REPLACESEL, (WPARAM) bCanUndo, (LPARAM)lpszNewText); + } + + void SetRect(LPCRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETRECT, 0, (LPARAM)lpRect); + } + + void SetRectNP(LPCRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETRECTNP, 0, (LPARAM)lpRect); + } + + void SetSel(DWORD dwSelection, BOOL bNoScroll = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETSEL, LOWORD(dwSelection), HIWORD(dwSelection)); + if(!bNoScroll) + ::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L); + } + + void SetSel(int nStartChar, int nEndChar, BOOL bNoScroll = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETSEL, nStartChar, nEndChar); + if(!bNoScroll) + ::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L); + } + + void SetSelAll(BOOL bNoScroll = FALSE) + { + SetSel(0, -1, bNoScroll); + } + + void SetSelNone(BOOL bNoScroll = FALSE) + { + SetSel(-1, 0, bNoScroll); + } + + BOOL SetTabStops(int nTabStops, LPINT rgTabStops) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, nTabStops, (LPARAM)rgTabStops); + } + + BOOL SetTabStops() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 0, 0L); + } + + BOOL SetTabStops(const int& cxEachStop) // takes an 'int' + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 1, (LPARAM)(LPINT)&cxEachStop); + } + + void ScrollCaret() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L); + } + + int Scroll(int nScrollAction) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & ES_MULTILINE) != 0); + LRESULT lRet = ::SendMessage(m_hWnd, EM_SCROLL, nScrollAction, 0L); + if(!(BOOL)HIWORD(lRet)) + return -1; // failed + return (int)(short)LOWORD(lRet); + + } + + void InsertText(int nInsertAfterChar, LPCTSTR lpstrText, BOOL bNoScroll = FALSE, BOOL bCanUndo = FALSE) + { + SetSel(nInsertAfterChar, nInsertAfterChar, bNoScroll); + ReplaceSel(lpstrText, bCanUndo); + } + + void AppendText(LPCTSTR lpstrText, BOOL bNoScroll = FALSE, BOOL bCanUndo = FALSE) + { + InsertText(GetWindowTextLength(), lpstrText, bNoScroll, bCanUndo); + } + +#if (_WIN32_WINNT >= 0x0501) + BOOL ShowBalloonTip(PEDITBALLOONTIP pEditBaloonTip) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SHOWBALLOONTIP, 0, (LPARAM)pEditBaloonTip); + } + + BOOL HideBalloonTip() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_HIDEBALLOONTIP, 0, 0L); + } +#endif // (_WIN32_WINNT >= 0x0501) + +#if (_WIN32_WINNT >= 0x0600) + DWORD GetHilite() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, EM_GETHILITE, 0, 0L); + } + + void GetHilite(int& nStartChar, int& nEndChar) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, EM_GETHILITE, 0, 0L); + nStartChar = (int)(short)LOWORD(dwRet); + nEndChar = (int)(short)HIWORD(dwRet); + } + + void SetHilite(int nStartChar, int nEndChar) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETHILITE, nStartChar, nEndChar); + } +#endif // (_WIN32_WINNT >= 0x0600) + + // Clipboard operations + BOOL Undo() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_UNDO, 0, 0L); + } + + void Clear() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_CLEAR, 0, 0L); + } + + void Copy() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_COPY, 0, 0L); + } + + void Cut() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_CUT, 0, 0L); + } + + void Paste() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_PASTE, 0, 0L); + } + +#ifdef WIN32_PLATFORM_WFSP // SmartPhone only messages + DWORD GetExtendedStyle() + { + return SendMessage(EM_GETEXTENDEDSTYLE); + } + + DWORD SetExtendedStyle(DWORD dwMask, DWORD dwExStyle) + { + return SendMessage(EM_SETEXTENDEDSTYLE, (WPARAM)dwMask, (LPARAM)dwExStyle); + } + + DWORD GetInputMode(BOOL bCurrentMode = TRUE) + { + return SendMessage(EM_GETINPUTMODE, 0, (LPARAM)bCurrentMode); + } + + BOOL SetInputMode(DWORD dwMode) + { + return SendMessage(EM_SETINPUTMODE, 0, (LPARAM)dwMode); + } + + BOOL SetSymbols(LPCTSTR szSymbols) + { + return SendMessage(EM_SETSYMBOLS, 0, (LPARAM)szSymbols); + } + + BOOL ResetSymbols() + { + return SendMessage(EM_SETSYMBOLS); + } +#endif // WIN32_PLATFORM_WFSP +}; + +typedef CEditT CEdit; + + +/////////////////////////////////////////////////////////////////////////////// +// CEditCommands - message handlers for standard EDIT commands + +// Chain to CEditCommands message map. Your class must also derive from CEdit. +// Example: +// class CMyEdit : public CWindowImpl, +// public CEditCommands +// { +// public: +// BEGIN_MSG_MAP(CMyEdit) +// // your handlers... +// CHAIN_MSG_MAP_ALT(CEditCommands, 1) +// END_MSG_MAP() +// // other stuff... +// }; + +template +class CEditCommands +{ +public: + BEGIN_MSG_MAP(CEditCommands< T >) + ALT_MSG_MAP(1) + COMMAND_ID_HANDLER(ID_EDIT_CLEAR, OnEditClear) + COMMAND_ID_HANDLER(ID_EDIT_CLEAR_ALL, OnEditClearAll) + COMMAND_ID_HANDLER(ID_EDIT_COPY, OnEditCopy) + COMMAND_ID_HANDLER(ID_EDIT_CUT, OnEditCut) + COMMAND_ID_HANDLER(ID_EDIT_PASTE, OnEditPaste) + COMMAND_ID_HANDLER(ID_EDIT_SELECT_ALL, OnEditSelectAll) + COMMAND_ID_HANDLER(ID_EDIT_UNDO, OnEditUndo) + END_MSG_MAP() + + LRESULT OnEditClear(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->Clear(); + return 0; + } + + LRESULT OnEditClearAll(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->SetSel(0, -1); + pT->Clear(); + return 0; + } + + LRESULT OnEditCopy(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->Copy(); + return 0; + } + + LRESULT OnEditCut(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->Cut(); + return 0; + } + + LRESULT OnEditPaste(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->Paste(); + return 0; + } + + LRESULT OnEditSelectAll(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->SetSel(0, -1); + return 0; + } + + LRESULT OnEditUndo(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->Undo(); + return 0; + } + +// State (update UI) helpers + BOOL CanCut() const + { return HasSelection(); } + + BOOL CanCopy() const + { return HasSelection(); } + + BOOL CanClear() const + { return HasSelection(); } + + BOOL CanSelectAll() const + { return HasText(); } + + BOOL CanFind() const + { return HasText(); } + + BOOL CanRepeat() const + { return HasText(); } + + BOOL CanReplace() const + { return HasText(); } + + BOOL CanClearAll() const + { return HasText(); } + +// Implementation + BOOL HasSelection() const + { + const T* pT = static_cast(this); + int nMin, nMax; + ::SendMessage(pT->m_hWnd, EM_GETSEL, (WPARAM)&nMin, (LPARAM)&nMax); + return (nMin != nMax); + } + + BOOL HasText() const + { + const T* pT = static_cast(this); + return (pT->GetWindowTextLength() > 0); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CScrollBar - client side for a Windows SCROLLBAR control + +template +class CScrollBarT : public TBase +{ +public: +// Constructors + CScrollBarT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CScrollBarT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return _T("SCROLLBAR"); + } + +#ifndef _WIN32_WCE + int GetScrollPos() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::GetScrollPos(m_hWnd, SB_CTL); + } +#endif // !_WIN32_WCE + + int SetScrollPos(int nPos, BOOL bRedraw = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::SetScrollPos(m_hWnd, SB_CTL, nPos, bRedraw); + } + +#ifndef _WIN32_WCE + void GetScrollRange(LPINT lpMinPos, LPINT lpMaxPos) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::GetScrollRange(m_hWnd, SB_CTL, lpMinPos, lpMaxPos); + } +#endif // !_WIN32_WCE + + void SetScrollRange(int nMinPos, int nMaxPos, BOOL bRedraw = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SetScrollRange(m_hWnd, SB_CTL, nMinPos, nMaxPos, bRedraw); + } + + BOOL GetScrollInfo(LPSCROLLINFO lpScrollInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::GetScrollInfo(m_hWnd, SB_CTL, lpScrollInfo); + } + + int SetScrollInfo(LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::SetScrollInfo(m_hWnd, SB_CTL, lpScrollInfo, bRedraw); + } + +#ifndef _WIN32_WCE + int GetScrollLimit() const + { + int nMin = 0, nMax = 0; + ::GetScrollRange(m_hWnd, SB_CTL, &nMin, &nMax); + SCROLLINFO info = { 0 }; + info.cbSize = sizeof(SCROLLINFO); + info.fMask = SIF_PAGE; + if(::GetScrollInfo(m_hWnd, SB_CTL, &info)) + nMax -= ((info.nPage - 1) > 0) ? (info.nPage - 1) : 0; + + return nMax; + } + +#if (WINVER >= 0x0500) + BOOL GetScrollBarInfo(PSCROLLBARINFO pScrollBarInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); +#if (_WIN32_WINNT >= 0x0501) + return (BOOL)::SendMessage(m_hWnd, SBM_GETSCROLLBARINFO, 0, (LPARAM)pScrollBarInfo); +#else // !(_WIN32_WINNT >= 0x0501) + return ::GetScrollBarInfo(m_hWnd, OBJID_CLIENT, pScrollBarInfo); +#endif // !(_WIN32_WINNT >= 0x0501) + } +#endif // (WINVER >= 0x0500) + +// Operations + void ShowScrollBar(BOOL bShow = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::ShowScrollBar(m_hWnd, SB_CTL, bShow); + } + + BOOL EnableScrollBar(UINT nArrowFlags = ESB_ENABLE_BOTH) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::EnableScrollBar(m_hWnd, SB_CTL, nArrowFlags); + } +#endif // !_WIN32_WCE +}; + +typedef CScrollBarT CScrollBar; + + +// --- Windows Common Controls --- + +/////////////////////////////////////////////////////////////////////////////// +// CImageList + +class CImageList +{ +public: + HIMAGELIST m_hImageList; + +// Constructor + CImageList(HIMAGELIST hImageList = NULL) : m_hImageList(hImageList) + { } + +// Operators, etc. + CImageList& operator =(HIMAGELIST hImageList) + { + m_hImageList = hImageList; + return *this; + } + + operator HIMAGELIST() const { return m_hImageList; } + + void Attach(HIMAGELIST hImageList) + { + ATLASSERT(m_hImageList == NULL); + ATLASSERT(hImageList != NULL); + m_hImageList = hImageList; + } + + HIMAGELIST Detach() + { + HIMAGELIST hImageList = m_hImageList; + m_hImageList = NULL; + return hImageList; + } + + bool IsNull() const { return (m_hImageList == NULL); } + +// Attributes + int GetImageCount() const + { + ATLASSERT(m_hImageList != NULL); + return ImageList_GetImageCount(m_hImageList); + } + + COLORREF GetBkColor() const + { + ATLASSERT(m_hImageList != NULL); + return ImageList_GetBkColor(m_hImageList); + } + + COLORREF SetBkColor(COLORREF cr) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_SetBkColor(m_hImageList, cr); + } + + BOOL GetImageInfo(int nImage, IMAGEINFO* pImageInfo) const + { + ATLASSERT(m_hImageList != NULL); + return ImageList_GetImageInfo(m_hImageList, nImage, pImageInfo); + } + + HICON GetIcon(int nIndex, UINT uFlags = ILD_NORMAL) const + { + ATLASSERT(m_hImageList != NULL); + return ImageList_GetIcon(m_hImageList, nIndex, uFlags); + } + + BOOL GetIconSize(int& cx, int& cy) const + { + ATLASSERT(m_hImageList != NULL); + return ImageList_GetIconSize(m_hImageList, &cx, &cy); + } + + BOOL GetIconSize(SIZE& size) const + { + ATLASSERT(m_hImageList != NULL); + return ImageList_GetIconSize(m_hImageList, (int*)&size.cx, (int*)&size.cy); + } + + BOOL SetIconSize(int cx, int cy) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_SetIconSize(m_hImageList, cx, cy); + } + + BOOL SetIconSize(SIZE size) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_SetIconSize(m_hImageList, size.cx, size.cy); + } + + BOOL SetImageCount(UINT uNewCount) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_SetImageCount(m_hImageList, uNewCount); + } + + BOOL SetOverlayImage(int nImage, int nOverlay) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_SetOverlayImage(m_hImageList, nImage, nOverlay); + } + +// Operations + BOOL Create(int cx, int cy, UINT nFlags, int nInitial, int nGrow) + { + ATLASSERT(m_hImageList == NULL); + m_hImageList = ImageList_Create(cx, cy, nFlags, nInitial, nGrow); + return (m_hImageList != NULL) ? TRUE : FALSE; + } + + BOOL Create(ATL::_U_STRINGorID bitmap, int cx, int nGrow, COLORREF crMask) + { + ATLASSERT(m_hImageList == NULL); + m_hImageList = ImageList_LoadBitmap(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr, cx, nGrow, crMask); + return (m_hImageList != NULL) ? TRUE : FALSE; + } + + BOOL CreateFromImage(ATL::_U_STRINGorID image, int cx, int nGrow, COLORREF crMask, UINT uType, UINT uFlags = LR_DEFAULTCOLOR | LR_DEFAULTSIZE) + { + ATLASSERT(m_hImageList == NULL); + m_hImageList = ImageList_LoadImage(ModuleHelper::GetResourceInstance(), image.m_lpstr, cx, nGrow, crMask, uType, uFlags); + return (m_hImageList != NULL) ? TRUE : FALSE; + } + + BOOL Merge(HIMAGELIST hImageList1, int nImage1, HIMAGELIST hImageList2, int nImage2, int dx, int dy) + { + ATLASSERT(m_hImageList == NULL); + m_hImageList = ImageList_Merge(hImageList1, nImage1, hImageList2, nImage2, dx, dy); + return (m_hImageList != NULL) ? TRUE : FALSE; + } + +#ifndef _WIN32_WCE +#ifdef __IStream_INTERFACE_DEFINED__ + BOOL CreateFromStream(LPSTREAM lpStream) + { + ATLASSERT(m_hImageList == NULL); + m_hImageList = ImageList_Read(lpStream); + return (m_hImageList != NULL) ? TRUE : FALSE; + } +#endif // __IStream_INTERFACE_DEFINED__ +#endif // !_WIN32_WCE + + BOOL Destroy() + { + if (m_hImageList == NULL) + return FALSE; + BOOL bRet = ImageList_Destroy(m_hImageList); + if(bRet) + m_hImageList = NULL; + return bRet; + } + + int Add(HBITMAP hBitmap, HBITMAP hBitmapMask = NULL) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_Add(m_hImageList, hBitmap, hBitmapMask); + } + + int Add(HBITMAP hBitmap, COLORREF crMask) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_AddMasked(m_hImageList, hBitmap, crMask); + } + + BOOL Remove(int nImage) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_Remove(m_hImageList, nImage); + } + + BOOL RemoveAll() + { + ATLASSERT(m_hImageList != NULL); + return ImageList_RemoveAll(m_hImageList); + } + + BOOL Replace(int nImage, HBITMAP hBitmap, HBITMAP hBitmapMask) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_Replace(m_hImageList, nImage, hBitmap, hBitmapMask); + } + + int AddIcon(HICON hIcon) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_AddIcon(m_hImageList, hIcon); + } + + int ReplaceIcon(int nImage, HICON hIcon) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_ReplaceIcon(m_hImageList, nImage, hIcon); + } + + HICON ExtractIcon(int nImage) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_ExtractIcon(NULL, m_hImageList, nImage); + } + + BOOL Draw(HDC hDC, int nImage, int x, int y, UINT nStyle) + { + ATLASSERT(m_hImageList != NULL); + ATLASSERT(hDC != NULL); + return ImageList_Draw(m_hImageList, nImage, hDC, x, y, nStyle); + } + + BOOL Draw(HDC hDC, int nImage, POINT pt, UINT nStyle) + { + ATLASSERT(m_hImageList != NULL); + ATLASSERT(hDC != NULL); + return ImageList_Draw(m_hImageList, nImage, hDC, pt.x, pt.y, nStyle); + } + + BOOL DrawEx(int nImage, HDC hDC, int x, int y, int dx, int dy, COLORREF rgbBk, COLORREF rgbFg, UINT fStyle) + { + ATLASSERT(m_hImageList != NULL); + ATLASSERT(hDC != NULL); + return ImageList_DrawEx(m_hImageList, nImage, hDC, x, y, dx, dy, rgbBk, rgbFg, fStyle); + } + + BOOL DrawEx(int nImage, HDC hDC, RECT& rect, COLORREF rgbBk, COLORREF rgbFg, UINT fStyle) + { + ATLASSERT(m_hImageList != NULL); + ATLASSERT(hDC != NULL); + return ImageList_DrawEx(m_hImageList, nImage, hDC, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, rgbBk, rgbFg, fStyle); + } + + static BOOL DrawIndirect(IMAGELISTDRAWPARAMS* pimldp) + { + return ImageList_DrawIndirect(pimldp); + } + + BOOL Copy(int nSrc, int nDst, UINT uFlags = ILCF_MOVE) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_Copy(m_hImageList, nDst, m_hImageList, nSrc, uFlags); + } + +#ifdef __IStream_INTERFACE_DEFINED__ +#ifndef _WIN32_WCE + static HIMAGELIST Read(LPSTREAM lpStream) + { + return ImageList_Read(lpStream); + } + + BOOL Write(LPSTREAM lpStream) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_Write(m_hImageList, lpStream); + } +#endif // !_WIN32_WCE + +#if (_WIN32_WINNT >= 0x0501) + static HRESULT ReadEx(DWORD dwFlags, LPSTREAM lpStream, REFIID riid, PVOID* ppv) + { + DebugBreak(); + return NULL; + //return ImageList_ReadEx(dwFlags, lpStream, riid, ppv); + } + + HRESULT WriteEx(DWORD dwFlags, LPSTREAM lpStream) + { + ATLASSERT(m_hImageList != NULL); + DebugBreak(); + return NULL; + //return ImageList_WriteEx(m_hImageList, dwFlags, lpStream); + } +#endif // (_WIN32_WINNT >= 0x0501) +#endif // __IStream_INTERFACE_DEFINED__ + + // Drag operations + BOOL BeginDrag(int nImage, POINT ptHotSpot) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_BeginDrag(m_hImageList, nImage, ptHotSpot.x, ptHotSpot.y); + } + + BOOL BeginDrag(int nImage, int xHotSpot, int yHotSpot) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_BeginDrag(m_hImageList, nImage, xHotSpot, yHotSpot); + } + + static void EndDrag() + { + ImageList_EndDrag(); + } + + static BOOL DragMove(POINT pt) + { + return ImageList_DragMove(pt.x, pt.y); + } + + static BOOL DragMove(int x, int y) + { + return ImageList_DragMove(x, y); + } + + BOOL SetDragCursorImage(int nDrag, POINT ptHotSpot) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_SetDragCursorImage(m_hImageList, nDrag, ptHotSpot.x, ptHotSpot.y); + } + + BOOL SetDragCursorImage(int nDrag, int xHotSpot, int yHotSpot) + { + ATLASSERT(m_hImageList != NULL); + return ImageList_SetDragCursorImage(m_hImageList, nDrag, xHotSpot, yHotSpot); + } + + static BOOL DragShowNolock(BOOL bShow = TRUE) + { + return ImageList_DragShowNolock(bShow); + } + + static CImageList GetDragImage(LPPOINT lpPoint, LPPOINT lpPointHotSpot) + { + return CImageList(ImageList_GetDragImage(lpPoint, lpPointHotSpot)); + } + + static BOOL DragEnter(HWND hWnd, POINT point) + { + return ImageList_DragEnter(hWnd, point.x, point.y); + } + + static BOOL DragEnter(HWND hWnd, int x, int y) + { + return ImageList_DragEnter(hWnd, x, y); + } + + static BOOL DragLeave(HWND hWnd) + { + return ImageList_DragLeave(hWnd); + } + +#if (_WIN32_IE >= 0x0400) + CImageList Duplicate() const + { + ATLASSERT(m_hImageList != NULL); + return CImageList(ImageList_Duplicate(m_hImageList)); + } + + static CImageList Duplicate(HIMAGELIST hImageList) + { + ATLASSERT(hImageList != NULL); + return CImageList(ImageList_Duplicate(hImageList)); + } +#endif // (_WIN32_IE >= 0x0400) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CToolTipCtrl + +#ifndef _WIN32_WCE + +class CToolInfo : public TOOLINFO +{ +public: + CToolInfo(UINT nFlags, HWND hWnd, UINT nIDTool = 0, LPRECT lpRect = NULL, LPTSTR lpstrText = LPSTR_TEXTCALLBACK, LPARAM lUserParam = NULL) + { + Init(nFlags, hWnd, nIDTool, lpRect, lpstrText, lUserParam); + } + + operator LPTOOLINFO() { return this; } + + operator LPARAM() { return (LPARAM)this; } + + void Init(UINT nFlags, HWND hWnd, UINT nIDTool = 0, LPRECT lpRect = NULL, LPTSTR lpstrText = LPSTR_TEXTCALLBACK, LPARAM lUserParam = NULL) + { + ATLASSERT(::IsWindow(hWnd)); + memset(this, 0, sizeof(TOOLINFO)); + cbSize = sizeof(TOOLINFO); + uFlags = nFlags; + if(nIDTool == 0) + { + hwnd = ::GetParent(hWnd); + uFlags |= TTF_IDISHWND; + uId = (UINT_PTR)hWnd; + } + else + { + hwnd = hWnd; + uId = nIDTool; + } + if(lpRect != NULL) + rect = *lpRect; + hinst = ModuleHelper::GetResourceInstance(); + lpszText = lpstrText; + lParam = lUserParam; + } +}; + +template +class CToolTipCtrlT : public TBase +{ +public: +// Constructors + CToolTipCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CToolTipCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return TOOLTIPS_CLASS; + } + + void GetText(LPTOOLINFO lpToolInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_GETTEXT, 0, (LPARAM)&lpToolInfo); + } + + void GetText(LPTSTR lpstrText, HWND hWnd, UINT nIDTool = 0) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hWnd != NULL); + CToolInfo ti(0, hWnd, nIDTool, NULL, lpstrText); + ::SendMessage(m_hWnd, TTM_GETTEXT, 0, ti); + } + + BOOL GetToolInfo(LPTOOLINFO lpToolInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TTM_GETTOOLINFO, 0, (LPARAM)lpToolInfo); + } + + BOOL GetToolInfo(HWND hWnd, UINT nIDTool, UINT* puFlags, LPRECT lpRect, LPTSTR lpstrText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hWnd != NULL); + ATLASSERT(puFlags != NULL); + ATLASSERT(lpRect != NULL); + CToolInfo ti(0, hWnd, nIDTool, NULL, lpstrText); + BOOL bRet = (BOOL)::SendMessage(m_hWnd, TTM_GETTOOLINFO, 0, ti); + if(bRet != FALSE) + { + *puFlags = ti.uFlags; + *lpRect = ti.rect; + } + return bRet; + } + + void SetToolInfo(LPTOOLINFO lpToolInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_SETTOOLINFO, 0, (LPARAM)lpToolInfo); + } + + void SetToolRect(LPTOOLINFO lpToolInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_NEWTOOLRECT, 0, (LPARAM)lpToolInfo); + } + + void SetToolRect(HWND hWnd, UINT nIDTool, LPCRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hWnd != NULL); + ATLASSERT(nIDTool != 0); + + CToolInfo ti(0, hWnd, nIDTool, (LPRECT)lpRect, NULL); + ::SendMessage(m_hWnd, TTM_NEWTOOLRECT, 0, ti); + } + + int GetToolCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TTM_GETTOOLCOUNT, 0, 0L); + } + + int GetDelayTime(DWORD dwType) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TTM_GETDELAYTIME, dwType, 0L); + } + + void SetDelayTime(DWORD dwType, int nTime) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_SETDELAYTIME, dwType, MAKELPARAM(nTime, 0)); + } + + void GetMargin(LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_GETMARGIN, 0, (LPARAM)lpRect); + } + + void SetMargin(LPRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_SETMARGIN, 0, (LPARAM)lpRect); + } + + int GetMaxTipWidth() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TTM_GETMAXTIPWIDTH, 0, 0L); + } + + int SetMaxTipWidth(int nWidth) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TTM_SETMAXTIPWIDTH, 0, nWidth); + } + + COLORREF GetTipBkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TTM_GETTIPBKCOLOR, 0, 0L); + } + + void SetTipBkColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_SETTIPBKCOLOR, (WPARAM)clr, 0L); + } + + COLORREF GetTipTextColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TTM_GETTIPTEXTCOLOR, 0, 0L); + } + + void SetTipTextColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_SETTIPTEXTCOLOR, (WPARAM)clr, 0L); + } + + BOOL GetCurrentTool(LPTOOLINFO lpToolInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TTM_GETCURRENTTOOL, 0, (LPARAM)lpToolInfo); + } + +#if (_WIN32_IE >= 0x0500) + SIZE GetBubbleSize(LPTOOLINFO lpToolInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, TTM_GETBUBBLESIZE, 0, (LPARAM)lpToolInfo); + SIZE size = { GET_X_LPARAM(dwRet), GET_Y_LPARAM(dwRet) }; + return size; + } + + BOOL SetTitle(UINT uIcon, LPCTSTR lpstrTitle) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TTM_SETTITLE, uIcon, (LPARAM)lpstrTitle); + } +#endif // (_WIN32_IE >= 0x0500) + +#if (_WIN32_WINNT >= 0x0501) + void GetTitle(PTTGETTITLE pTTGetTitle) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_GETTITLE, 0, (LPARAM)pTTGetTitle); + } + + void SetWindowTheme(LPCWSTR lpstrTheme) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_SETWINDOWTHEME, 0, (LPARAM)lpstrTheme); + } +#endif // (_WIN32_WINNT >= 0x0501) + +// Operations + void Activate(BOOL bActivate) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_ACTIVATE, bActivate, 0L); + } + + BOOL AddTool(LPTOOLINFO lpToolInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TTM_ADDTOOL, 0, (LPARAM)lpToolInfo); + } + + BOOL AddTool(HWND hWnd, ATL::_U_STRINGorID text = LPSTR_TEXTCALLBACK, LPCRECT lpRectTool = NULL, UINT nIDTool = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hWnd != NULL); + // the toolrect and toolid must both be zero or both valid + ATLASSERT((lpRectTool != NULL && nIDTool != 0) || (lpRectTool == NULL && nIDTool == 0)); + + CToolInfo ti(0, hWnd, nIDTool, (LPRECT)lpRectTool, (LPTSTR)text.m_lpstr); + return (BOOL)::SendMessage(m_hWnd, TTM_ADDTOOL, 0, ti); + } + + void DelTool(LPTOOLINFO lpToolInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_DELTOOL, 0, (LPARAM)lpToolInfo); + } + + void DelTool(HWND hWnd, UINT nIDTool = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hWnd != NULL); + + CToolInfo ti(0, hWnd, nIDTool, NULL, NULL); + ::SendMessage(m_hWnd, TTM_DELTOOL, 0, ti); + } + + BOOL HitTest(LPTTHITTESTINFO lpHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TTM_HITTEST, 0, (LPARAM)lpHitTestInfo); + } + + BOOL HitTest(HWND hWnd, POINT pt, LPTOOLINFO lpToolInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hWnd != NULL); + ATLASSERT(lpToolInfo != NULL); + + TTHITTESTINFO hti = { 0 }; + hti.ti.cbSize = sizeof(TOOLINFO); + hti.hwnd = hWnd; + hti.pt.x = pt.x; + hti.pt.y = pt.y; + if((BOOL)::SendMessage(m_hWnd, TTM_HITTEST, 0, (LPARAM)&hti) != FALSE) + { + *lpToolInfo = hti.ti; + return TRUE; + } + return FALSE; + } + + void RelayEvent(LPMSG lpMsg) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_RELAYEVENT, 0, (LPARAM)lpMsg); + } + + void UpdateTipText(LPTOOLINFO lpToolInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_UPDATETIPTEXT, 0, (LPARAM)lpToolInfo); + } + + void UpdateTipText(ATL::_U_STRINGorID text, HWND hWnd, UINT nIDTool = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hWnd != NULL); + + CToolInfo ti(0, hWnd, nIDTool, NULL, (LPTSTR)text.m_lpstr); + ::SendMessage(m_hWnd, TTM_UPDATETIPTEXT, 0, ti); + } + + BOOL EnumTools(UINT nTool, LPTOOLINFO lpToolInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TTM_ENUMTOOLS, nTool, (LPARAM)lpToolInfo); + } + + void Pop() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_POP, 0, 0L); + } + + void TrackActivate(LPTOOLINFO lpToolInfo, BOOL bActivate) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_TRACKACTIVATE, bActivate, (LPARAM)lpToolInfo); + } + + void TrackPosition(int xPos, int yPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_TRACKPOSITION, 0, MAKELPARAM(xPos, yPos)); + } + +#if (_WIN32_IE >= 0x0400) + void Update() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_UPDATE, 0, 0L); + } +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0500) + BOOL AdjustRect(LPRECT lpRect, BOOL bLarger /*= TRUE*/) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TTM_ADJUSTRECT, bLarger, (LPARAM)lpRect); + } +#endif // (_WIN32_IE >= 0x0500) + +#if (_WIN32_WINNT >= 0x0501) + void Popup() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TTM_POPUP, 0, 0L); + } +#endif // (_WIN32_WINNT >= 0x0501) +}; + +typedef CToolTipCtrlT CToolTipCtrl; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CHeaderCtrl + +template +class CHeaderCtrlT : public TBase +{ +public: +// Constructors + CHeaderCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CHeaderCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_HEADER; + } + + int GetItemCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_GETITEMCOUNT, 0, 0L); + } + + BOOL GetItem(int nIndex, LPHDITEM pHeaderItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_GETITEM, nIndex, (LPARAM)pHeaderItem); + } + + BOOL SetItem(int nIndex, LPHDITEM pHeaderItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_SETITEM, nIndex, (LPARAM)pHeaderItem); + } + + CImageList GetImageList() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, HDM_GETIMAGELIST, 0, 0L)); + } + + CImageList SetImageList(HIMAGELIST hImageList) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, HDM_SETIMAGELIST, 0, (LPARAM)hImageList)); + } + + BOOL GetOrderArray(int nSize, int* lpnArray) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_GETORDERARRAY, nSize, (LPARAM)lpnArray); + } + + BOOL SetOrderArray(int nSize, int* lpnArray) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_SETORDERARRAY, nSize, (LPARAM)lpnArray); + } + + BOOL GetItemRect(int nIndex, LPRECT lpItemRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_GETITEMRECT, nIndex, (LPARAM)lpItemRect); + } + + int SetHotDivider(BOOL bPos, DWORD dwInputValue) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_SETHOTDIVIDER, bPos, dwInputValue); + } + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + int GetBitmapMargin() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_GETBITMAPMARGIN, 0, 0L); + } + + int SetBitmapMargin(int nWidth) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_SETBITMAPMARGIN, nWidth, 0L); + } + + int SetFilterChangeTimeout(DWORD dwTimeOut) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_SETFILTERCHANGETIMEOUT, 0, dwTimeOut); + } +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + +#if (_WIN32_WINNT >= 0x0600) + BOOL GetItemDropDownRect(int nIndex, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_GETITEMDROPDOWNRECT, nIndex, (LPARAM)lpRect); + } + + BOOL GetOverflowRect(LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_GETOVERFLOWRECT, 0, (LPARAM)lpRect); + } + + int GetFocusedItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_GETFOCUSEDITEM, 0, 0L); + } + + BOOL SetFocusedItem(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_SETFOCUSEDITEM, 0, nIndex); + } +#endif // (_WIN32_WINNT >= 0x0600) + +// Operations + int InsertItem(int nIndex, LPHDITEM phdi) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_INSERTITEM, nIndex, (LPARAM)phdi); + } + + int AddItem(LPHDITEM phdi) + { + return InsertItem(GetItemCount(), phdi); + } + + BOOL DeleteItem(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_DELETEITEM, nIndex, 0L); + } + + BOOL Layout(HD_LAYOUT* pHeaderLayout) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, HDM_LAYOUT, 0, (LPARAM)pHeaderLayout); + } + + int HitTest(LPHDHITTESTINFO lpHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_HITTEST, 0, (LPARAM)lpHitTestInfo); + } + + int OrderToIndex(int nOrder) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_ORDERTOINDEX, nOrder, 0L); + } + + CImageList CreateDragImage(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, HDM_CREATEDRAGIMAGE, nIndex, 0L)); + } + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + int EditFilter(int nColumn, BOOL bDiscardChanges) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_EDITFILTER, nColumn, MAKELPARAM(bDiscardChanges, 0)); + } + + int ClearFilter(int nColumn) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_CLEARFILTER, nColumn, 0L); + } + + int ClearAllFilters() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, HDM_CLEARFILTER, (WPARAM)-1, 0L); + } +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) +}; + +typedef CHeaderCtrlT CHeaderCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CListViewCtrl + +template +class CListViewCtrlT : public TBase +{ +public: +// Constructors + CListViewCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CListViewCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_LISTVIEW; + } + + COLORREF GetBkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, LVM_GETBKCOLOR, 0, 0L); + } + + BOOL SetBkColor(COLORREF cr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETBKCOLOR, 0, cr); + } + + CImageList GetImageList(int nImageListType) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, LVM_GETIMAGELIST, nImageListType, 0L)); + } + + CImageList SetImageList(HIMAGELIST hImageList, int nImageList) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, LVM_SETIMAGELIST, nImageList, (LPARAM)hImageList)); + } + + int GetItemCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETITEMCOUNT, 0, 0L); + } + + BOOL SetItemCount(int nItems) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMCOUNT, nItems, 0L); + } + + BOOL GetItem(LPLVITEM pItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETITEM, 0, (LPARAM)pItem); + } + + BOOL SetItem(const LVITEM* pItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEM, 0, (LPARAM)pItem); + } + + BOOL SetItem(int nItem, int nSubItem, UINT nMask, LPCTSTR lpszItem, + int nImage, UINT nState, UINT nStateMask, LPARAM lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + LVITEM lvi = { 0 }; + lvi.mask = nMask; + lvi.iItem = nItem; + lvi.iSubItem = nSubItem; + lvi.stateMask = nStateMask; + lvi.state = nState; + lvi.pszText = (LPTSTR) lpszItem; + lvi.iImage = nImage; + lvi.lParam = lParam; + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEM, 0, (LPARAM)&lvi); + } + + UINT GetItemState(int nItem, UINT nMask) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, LVM_GETITEMSTATE, nItem, nMask); + } + + BOOL SetItemState(int nItem, UINT nState, UINT nStateMask) + { + ATLASSERT(::IsWindow(m_hWnd)); + LVITEM lvi = { 0 }; + lvi.state = nState; + lvi.stateMask = nStateMask; + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMSTATE, nItem, (LPARAM)&lvi); + } + + BOOL SetItemState(int nItem, LPLVITEM pItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMSTATE, nItem, (LPARAM)pItem); + } + +#ifndef _ATL_NO_COM + BOOL GetItemText(int nItem, int nSubItem, BSTR& bstrText) const + { + USES_CONVERSION; + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(bstrText == NULL); + LVITEM lvi = { 0 }; + lvi.iSubItem = nSubItem; + + LPTSTR lpstrText = NULL; + int nRes = 0; + for(int nLen = 256; ; nLen *= 2) + { + ATLTRY(lpstrText = new TCHAR[nLen]); + if(lpstrText == NULL) + break; + lpstrText[0] = NULL; + lvi.cchTextMax = nLen; + lvi.pszText = lpstrText; + nRes = (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem, (LPARAM)&lvi); + if(nRes < nLen - 1) + break; + delete [] lpstrText; + lpstrText = NULL; + } + + if(lpstrText != NULL) + { + if(nRes != 0) + bstrText = ::SysAllocString(T2OLE(lpstrText)); + delete [] lpstrText; + } + + return (bstrText != NULL) ? TRUE : FALSE; + } +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + int GetItemText(int nItem, int nSubItem, _CSTRING_NS::CString& strText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + LVITEM lvi = { 0 }; + lvi.iSubItem = nSubItem; + + strText.Empty(); + int nRes = 0; + for(int nLen = 256; ; nLen *= 2) + { + lvi.cchTextMax = nLen; + lvi.pszText = strText.GetBufferSetLength(nLen); + if(lvi.pszText == NULL) + { + nRes = 0; + break; + } + nRes = (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem, (LPARAM)&lvi); + if(nRes < nLen - 1) + break; + } + strText.ReleaseBuffer(); + return nRes; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + int GetItemText(int nItem, int nSubItem, LPTSTR lpszText, int nLen) const + { + ATLASSERT(::IsWindow(m_hWnd)); + LVITEM lvi = { 0 }; + lvi.iSubItem = nSubItem; + lvi.cchTextMax = nLen; + lvi.pszText = lpszText; + return (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem, (LPARAM)&lvi); + } + + BOOL SetItemText(int nItem, int nSubItem, LPCTSTR lpszText) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItem(nItem, nSubItem, LVIF_TEXT, lpszText, 0, 0, 0, 0); + } + + DWORD_PTR GetItemData(int nItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + LVITEM lvi = { 0 }; + lvi.iItem = nItem; + lvi.mask = LVIF_PARAM; + BOOL bRet = (BOOL)::SendMessage(m_hWnd, LVM_GETITEM, 0, (LPARAM)&lvi); + return (DWORD_PTR)(bRet ? lvi.lParam : NULL); + } + + BOOL SetItemData(int nItem, DWORD_PTR dwData) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItem(nItem, 0, LVIF_PARAM, NULL, 0, 0, 0, (LPARAM)dwData); + } + + UINT GetCallbackMask() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, LVM_GETCALLBACKMASK, 0, 0L); + } + + BOOL SetCallbackMask(UINT nMask) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETCALLBACKMASK, nMask, 0L); + } + + BOOL GetItemPosition(int nItem, LPPOINT lpPoint) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETITEMPOSITION, nItem, (LPARAM)lpPoint); + } + + BOOL SetItemPosition(int nItem, POINT pt) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(((GetStyle() & LVS_TYPEMASK) == LVS_ICON) || ((GetStyle() & LVS_TYPEMASK) == LVS_SMALLICON)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMPOSITION32, nItem, (LPARAM)&pt); + } + + BOOL SetItemPosition(int nItem, int x, int y) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(((GetStyle() & LVS_TYPEMASK) == LVS_ICON) || ((GetStyle() & LVS_TYPEMASK) == LVS_SMALLICON)); + POINT pt = { x, y }; + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMPOSITION32, nItem, (LPARAM)&pt); + } + + int GetStringWidth(LPCTSTR lpsz) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETSTRINGWIDTH, 0, (LPARAM)lpsz); + } + + CEdit GetEditControl() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CEdit((HWND)::SendMessage(m_hWnd, LVM_GETEDITCONTROL, 0, 0L)); + } + + BOOL GetColumn(int nCol, LVCOLUMN* pColumn) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETCOLUMN, nCol, (LPARAM)pColumn); + } + + BOOL SetColumn(int nCol, const LVCOLUMN* pColumn) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETCOLUMN, nCol, (LPARAM)pColumn); + } + + int GetColumnWidth(int nCol) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETCOLUMNWIDTH, nCol, 0L); + } + + BOOL SetColumnWidth(int nCol, int cx) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETCOLUMNWIDTH, nCol, MAKELPARAM(cx, 0)); + } + + BOOL GetViewRect(LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETVIEWRECT, 0, (LPARAM)lpRect); + } + + COLORREF GetTextColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, LVM_GETTEXTCOLOR, 0, 0L); + } + + BOOL SetTextColor(COLORREF cr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETTEXTCOLOR, 0, cr); + } + + COLORREF GetTextBkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, LVM_GETTEXTBKCOLOR, 0, 0L); + } + + BOOL SetTextBkColor(COLORREF cr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETTEXTBKCOLOR, 0, cr); + } + + int GetTopIndex() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETTOPINDEX, 0, 0L); + } + + int GetCountPerPage() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETCOUNTPERPAGE, 0, 0L); + } + + BOOL GetOrigin(LPPOINT lpPoint) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETORIGIN, 0, (LPARAM)lpPoint); + } + + UINT GetSelectedCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, LVM_GETSELECTEDCOUNT, 0, 0L); + } + + BOOL GetItemRect(int nItem, LPRECT lpRect, UINT nCode) const + { + ATLASSERT(::IsWindow(m_hWnd)); + lpRect->left = nCode; + return (BOOL)::SendMessage(m_hWnd, LVM_GETITEMRECT, (WPARAM)nItem, (LPARAM)lpRect); + } + +#ifndef _WIN32_WCE + HCURSOR GetHotCursor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HCURSOR)::SendMessage(m_hWnd, LVM_GETHOTCURSOR, 0, 0L); + } + + HCURSOR SetHotCursor(HCURSOR hHotCursor) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HCURSOR)::SendMessage(m_hWnd, LVM_SETHOTCURSOR, 0, (LPARAM)hHotCursor); + } + + int GetHotItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETHOTITEM, 0, 0L); + } + + int SetHotItem(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_SETHOTITEM, nIndex, 0L); + } +#endif // !_WIN32_WCE + + BOOL GetColumnOrderArray(int nCount, int* lpnArray) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETCOLUMNORDERARRAY, nCount, (LPARAM)lpnArray); + } + + BOOL SetColumnOrderArray(int nCount, int* lpnArray) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETCOLUMNORDERARRAY, nCount, (LPARAM)lpnArray); + } + + CHeaderCtrl GetHeader() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CHeaderCtrl((HWND)::SendMessage(m_hWnd, LVM_GETHEADER, 0, 0L)); + } + + BOOL GetSubItemRect(int nItem, int nSubItem, int nFlag, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & LVS_TYPEMASK) == LVS_REPORT); + ATLASSERT(lpRect != NULL); + lpRect->top = nSubItem; + lpRect->left = nFlag; + return (BOOL)::SendMessage(m_hWnd, LVM_GETSUBITEMRECT, nItem, (LPARAM)lpRect); + } + + DWORD SetIconSpacing(int cx, int cy) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & LVS_TYPEMASK) == LVS_ICON); + return (DWORD)::SendMessage(m_hWnd, LVM_SETICONSPACING, 0, MAKELPARAM(cx, cy)); + } + + int GetISearchString(LPTSTR lpstr) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETISEARCHSTRING, 0, (LPARAM)lpstr); + } + + void GetItemSpacing(SIZE& sizeSpacing, BOOL bSmallIconView = FALSE) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, LVM_GETITEMSPACING, bSmallIconView, 0L); + sizeSpacing.cx = GET_X_LPARAM(dwRet); + sizeSpacing.cy = GET_Y_LPARAM(dwRet); + } + +#if (_WIN32_WCE >= 410) + void SetItemSpacing(INT cySpacing) + { + ATLASSERT(::IsWindow(m_hWnd)); + ListView_SetItemSpacing(m_hWnd, cySpacing); + } +#endif // (_WIN32_WCE >= 410) + + // single-selection only + int GetSelectedIndex() const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & LVS_SINGLESEL) != 0); + return (int)::SendMessage(m_hWnd, LVM_GETNEXTITEM, (WPARAM)-1, MAKELPARAM(LVNI_ALL | LVNI_SELECTED, 0)); + } + + BOOL GetSelectedItem(LPLVITEM pItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & LVS_SINGLESEL) != 0); + ATLASSERT(pItem != NULL); + pItem->iItem = (int)::SendMessage(m_hWnd, LVM_GETNEXTITEM, (WPARAM)-1, MAKELPARAM(LVNI_ALL | LVNI_SELECTED, 0)); + if(pItem->iItem == -1) + return FALSE; + return (BOOL)::SendMessage(m_hWnd, LVM_GETITEM, 0, (LPARAM)pItem); + } + + // extended list view styles + DWORD GetExtendedListViewStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0L); + } + + // dwExMask = 0 means all styles + DWORD SetExtendedListViewStyle(DWORD dwExStyle, DWORD dwExMask = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE, dwExMask, dwExStyle); + } + + // checkboxes only + BOOL GetCheckState(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetExtendedListViewStyle() & LVS_EX_CHECKBOXES) != 0); + UINT uRet = GetItemState(nIndex, LVIS_STATEIMAGEMASK); + return (uRet >> 12) - 1; + } + + BOOL SetCheckState(int nItem, BOOL bCheck) + { + int nCheck = bCheck ? 2 : 1; // one based index + return SetItemState(nItem, INDEXTOSTATEIMAGEMASK(nCheck), LVIS_STATEIMAGEMASK); + } + + // view type + DWORD GetViewType() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (GetStyle() & LVS_TYPEMASK); + } + + DWORD SetViewType(DWORD dwType) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(dwType == LVS_ICON || dwType == LVS_SMALLICON || dwType == LVS_LIST || dwType == LVS_REPORT); + DWORD dwOldType = GetViewType(); + if(dwType != dwOldType) + ModifyStyle(LVS_TYPEMASK, (dwType & LVS_TYPEMASK)); + return dwOldType; + } + +#if (_WIN32_IE >= 0x0400) +#ifndef _WIN32_WCE + BOOL GetBkImage(LPLVBKIMAGE plvbki) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETBKIMAGE, 0, (LPARAM)plvbki); + } + + BOOL SetBkImage(LPLVBKIMAGE plvbki) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETBKIMAGE, 0, (LPARAM)plvbki); + } +#endif // !_WIN32_WCE + + int GetSelectionMark() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETSELECTIONMARK, 0, 0L); + } + + int SetSelectionMark(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_SETSELECTIONMARK, 0, nIndex); + } + +#ifndef _WIN32_WCE + BOOL GetWorkAreas(int nWorkAreas, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETWORKAREAS, nWorkAreas, (LPARAM)lpRect); + } + + BOOL SetWorkAreas(int nWorkAreas, LPRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETWORKAREAS, nWorkAreas, (LPARAM)lpRect); + } + + DWORD GetHoverTime() const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetExtendedListViewStyle() & (LVS_EX_TRACKSELECT | LVS_EX_ONECLICKACTIVATE | LVS_EX_TWOCLICKACTIVATE)) != 0); + return (DWORD)::SendMessage(m_hWnd, LVM_GETHOVERTIME, 0, 0L); + } + + DWORD SetHoverTime(DWORD dwHoverTime) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetExtendedListViewStyle() & (LVS_EX_TRACKSELECT | LVS_EX_ONECLICKACTIVATE | LVS_EX_TWOCLICKACTIVATE)) != 0); + return (DWORD)::SendMessage(m_hWnd, LVM_SETHOVERTIME, 0, dwHoverTime); + } + + BOOL GetNumberOfWorkAreas(int* pnWorkAreas) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETNUMBEROFWORKAREAS, 0, (LPARAM)pnWorkAreas); + } +#endif // !_WIN32_WCE + + BOOL SetItemCountEx(int nItems, DWORD dwFlags) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(((GetStyle() & LVS_OWNERDATA) != 0) && (((GetStyle() & LVS_TYPEMASK) == LVS_REPORT) || ((GetStyle() & LVS_TYPEMASK) == LVS_LIST))); + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMCOUNT, nItems, dwFlags); + } + +#ifndef _WIN32_WCE + CToolTipCtrl GetToolTips() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CToolTipCtrl((HWND)::SendMessage(m_hWnd, LVM_GETTOOLTIPS, 0, 0L)); + } + + CToolTipCtrl SetToolTips(HWND hWndTT) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CToolTipCtrl((HWND)::SendMessage(m_hWnd, LVM_SETTOOLTIPS, (WPARAM)hWndTT, 0L)); + } + + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // !_WIN32_WCE +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_WINNT >= 0x0501) + int GetSelectedColumn() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETSELECTEDCOLUMN, 0, 0L); + } + + void SetSelectedColumn(int nColumn) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_SETSELECTEDCOLUMN, nColumn, 0L); + } + + DWORD GetView() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, LVM_GETVIEW, 0, 0L); + } + + int SetView(DWORD dwView) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_SETVIEW, dwView, 0L); + } + + BOOL IsGroupViewEnabled() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_ISGROUPVIEWENABLED, 0, 0L); + } + + int GetGroupInfo(int nGroupID, PLVGROUP pGroup) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETGROUPINFO, nGroupID, (LPARAM)pGroup); + } + + int SetGroupInfo(int nGroupID, PLVGROUP pGroup) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_SETGROUPINFO, nGroupID, (LPARAM)pGroup); + } + + void GetGroupMetrics(PLVGROUPMETRICS pGroupMetrics) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_GETGROUPMETRICS, 0, (LPARAM)pGroupMetrics); + } + + void SetGroupMetrics(PLVGROUPMETRICS pGroupMetrics) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_SETGROUPMETRICS, 0, (LPARAM)pGroupMetrics); + } + + void GetTileViewInfo(PLVTILEVIEWINFO pTileViewInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_GETTILEVIEWINFO, 0, (LPARAM)pTileViewInfo); + } + + BOOL SetTileViewInfo(PLVTILEVIEWINFO pTileViewInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETTILEVIEWINFO, 0, (LPARAM)pTileViewInfo); + } + + void GetTileInfo(PLVTILEINFO pTileInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_GETTILEINFO, 0, (LPARAM)pTileInfo); + } + + BOOL SetTileInfo(PLVTILEINFO pTileInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETTILEINFO, 0, (LPARAM)pTileInfo); + } + + BOOL GetInsertMark(LPLVINSERTMARK pInsertMark) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETINSERTMARK, 0, (LPARAM)pInsertMark); + } + + BOOL SetInsertMark(LPLVINSERTMARK pInsertMark) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETINSERTMARK, 0, (LPARAM)pInsertMark); + } + + int GetInsertMarkRect(LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETINSERTMARKRECT, 0, (LPARAM)lpRect); + } + + COLORREF GetInsertMarkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, LVM_GETINSERTMARKCOLOR, 0, 0L); + } + + COLORREF SetInsertMarkColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, LVM_SETINSERTMARKCOLOR, 0, clr); + } + + COLORREF GetOutlineColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, LVM_GETOUTLINECOLOR, 0, 0L); + } + + COLORREF SetOutlineColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, LVM_SETOUTLINECOLOR, 0, clr); + } +#endif // (_WIN32_WINNT >= 0x0501) + +#if (_WIN32_WINNT >= 0x0600) + int GetGroupCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETGROUPCOUNT, 0, 0L); + } + + BOOL GetGroupInfoByIndex(int nIndex, PLVGROUP pGroup) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETGROUPINFOBYINDEX, nIndex, (LPARAM)pGroup); + } + + BOOL GetGroupRect(int nGroupID, int nType, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpRect != NULL); + if(lpRect != NULL) + lpRect->top = nType; + return (BOOL)::SendMessage(m_hWnd, LVM_GETGROUPRECT, nGroupID, (LPARAM)lpRect); + } + + UINT GetGroupState(int nGroupID, UINT uMask) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, LVM_GETGROUPSTATE, nGroupID, (LPARAM)uMask); + } + + int GetFocusedGroup() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETFOCUSEDGROUP, 0, 0L); + } + + BOOL GetEmptyText(LPWSTR lpstrText, int cchText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETEMPTYTEXT, cchText, (LPARAM)lpstrText); + } + + BOOL GetFooterRect(LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETFOOTERRECT, 0, (LPARAM)lpRect); + } + + BOOL GetFooterInfo(LPLVFOOTERINFO lpFooterInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETFOOTERINFO, 0, (LPARAM)lpFooterInfo); + } + + BOOL GetFooterItemRect(int nItem, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETFOOTERITEMRECT, nItem, (LPARAM)lpRect); + } + + BOOL GetFooterItem(int nItem, LPLVFOOTERITEM lpFooterItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETFOOTERITEM, nItem, (LPARAM)lpFooterItem); + } + + BOOL GetItemIndexRect(PLVITEMINDEX pItemIndex, int nSubItem, int nType, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pItemIndex != NULL); + ATLASSERT(lpRect != NULL); + if(lpRect != NULL) + { + lpRect->top = nSubItem; + lpRect->left = nType; + } + return (BOOL)::SendMessage(m_hWnd, LVM_GETITEMINDEXRECT, (WPARAM)pItemIndex, (LPARAM)lpRect); + } + + BOOL SetItemIndexState(PLVITEMINDEX pItemIndex, UINT uState, UINT dwMask) + { + ATLASSERT(::IsWindow(m_hWnd)); + LVITEM lvi = { 0 }; + lvi.state = uState; + lvi.stateMask = dwMask; + return (BOOL)::SendMessage(m_hWnd, LVM_SETITEMINDEXSTATE, (WPARAM)pItemIndex, (LPARAM)&lvi); + } + + BOOL GetNextItemIndex(PLVITEMINDEX pItemIndex, WORD wFlags) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_GETNEXTITEMINDEX, (WPARAM)pItemIndex, MAKELPARAM(wFlags, 0)); + } +#endif // (_WIN32_WINNT >= 0x0600) + +// Operations + int InsertColumn(int nCol, const LVCOLUMN* pColumn) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_INSERTCOLUMN, nCol, (LPARAM)pColumn); + } + + int InsertColumn(int nCol, LPCTSTR lpszColumnHeading, int nFormat = LVCFMT_LEFT, + int nWidth = -1, int nSubItem = -1, int iImage = -1, int iOrder = -1) + { + LVCOLUMN column = { 0 }; + column.mask = LVCF_TEXT|LVCF_FMT; + column.pszText = (LPTSTR)lpszColumnHeading; + column.fmt = nFormat; + if (nWidth != -1) + { + column.mask |= LVCF_WIDTH; + column.cx = nWidth; + } + if (nSubItem != -1) + { + column.mask |= LVCF_SUBITEM; + column.iSubItem = nSubItem; + } + if (iImage != -1) + { + column.mask |= LVCF_IMAGE; + column.iImage = iImage; + } + if (iOrder != -1) + { + column.mask |= LVCF_ORDER; + column.iOrder = iOrder; + } + return InsertColumn(nCol, &column); + } + + BOOL DeleteColumn(int nCol) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_DELETECOLUMN, nCol, 0L); + } + + int InsertItem(UINT nMask, int nItem, LPCTSTR lpszItem, UINT nState, UINT nStateMask, int nImage, LPARAM lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + LVITEM item = { 0 }; + item.mask = nMask; + item.iItem = nItem; + item.iSubItem = 0; + item.pszText = (LPTSTR)lpszItem; + item.state = nState; + item.stateMask = nStateMask; + item.iImage = nImage; + item.lParam = lParam; + return InsertItem(&item); + } + + int InsertItem(const LVITEM* pItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_INSERTITEM, 0, (LPARAM)pItem); + } + + int InsertItem(int nItem, LPCTSTR lpszItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return InsertItem(LVIF_TEXT, nItem, lpszItem, 0, 0, 0, 0); + } + + int InsertItem(int nItem, LPCTSTR lpszItem, int nImage) + { + ATLASSERT(::IsWindow(m_hWnd)); + return InsertItem(LVIF_TEXT|LVIF_IMAGE, nItem, lpszItem, 0, 0, nImage, 0); + } + + int GetNextItem(int nItem, int nFlags) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_GETNEXTITEM, nItem, MAKELPARAM(nFlags, 0)); + } + + BOOL DeleteItem(int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_DELETEITEM, nItem, 0L); + } + + BOOL DeleteAllItems() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_DELETEALLITEMS, 0, 0L); + } + + int FindItem(LVFINDINFO* pFindInfo, int nStart) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_FINDITEM, nStart, (LPARAM)pFindInfo); + } + + int HitTest(LVHITTESTINFO* pHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_HITTEST, 0, (LPARAM)pHitTestInfo); + } + + int HitTest(POINT pt, UINT* pFlags) const + { + ATLASSERT(::IsWindow(m_hWnd)); + LVHITTESTINFO hti = { 0 }; + hti.pt = pt; + int nRes = (int)::SendMessage(m_hWnd, LVM_HITTEST, 0, (LPARAM)&hti); + if (pFlags != NULL) + *pFlags = hti.flags; + return nRes; + } + + BOOL EnsureVisible(int nItem, BOOL bPartialOK) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_ENSUREVISIBLE, nItem, MAKELPARAM(bPartialOK, 0)); + } + + BOOL Scroll(SIZE size) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SCROLL, size.cx, size.cy); + } + + BOOL RedrawItems(int nFirst, int nLast) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_REDRAWITEMS, nFirst, nLast); + } + + BOOL Arrange(UINT nCode) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_ARRANGE, nCode, 0L); + } + + CEdit EditLabel(int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CEdit((HWND)::SendMessage(m_hWnd, LVM_EDITLABEL, nItem, 0L)); + } + + BOOL Update(int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_UPDATE, nItem, 0L); + } + + BOOL SortItems(PFNLVCOMPARE pfnCompare, LPARAM lParamSort) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SORTITEMS, (WPARAM)lParamSort, (LPARAM)pfnCompare); + } + + CImageList RemoveImageList(int nImageList) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, LVM_SETIMAGELIST, (WPARAM)nImageList, NULL)); + } + + CImageList CreateDragImage(int nItem, LPPOINT lpPoint) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, LVM_CREATEDRAGIMAGE, nItem, (LPARAM)lpPoint)); + } + + DWORD ApproximateViewRect(int cx = -1, int cy = -1, int nCount = -1) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, LVM_APPROXIMATEVIEWRECT, nCount, MAKELPARAM(cx, cy)); + } + + int SubItemHitTest(LPLVHITTESTINFO lpInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_SUBITEMHITTEST, 0, (LPARAM)lpInfo); + } + + int AddColumn(LPCTSTR strItem, int nItem, int nSubItem = -1, + int nMask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM, + int nFmt = LVCFMT_LEFT) + { + const int cxOffset = 15; + ATLASSERT(::IsWindow(m_hWnd)); + LVCOLUMN lvc = { 0 }; + lvc.mask = nMask; + lvc.fmt = nFmt; + lvc.pszText = (LPTSTR)strItem; + lvc.cx = GetStringWidth(lvc.pszText) + cxOffset; + if(nMask & LVCF_SUBITEM) + lvc.iSubItem = (nSubItem != -1) ? nSubItem : nItem; + return InsertColumn(nItem, &lvc); + } + + int AddItem(int nItem, int nSubItem, LPCTSTR strItem, int nImageIndex = -1) + { + ATLASSERT(::IsWindow(m_hWnd)); + LVITEM lvItem = { 0 }; + lvItem.mask = LVIF_TEXT; + lvItem.iItem = nItem; + lvItem.iSubItem = nSubItem; + lvItem.pszText = (LPTSTR)strItem; + if(nImageIndex != -1) + { + lvItem.mask |= LVIF_IMAGE; + lvItem.iImage = nImageIndex; + } + if(nSubItem == 0) + return InsertItem(&lvItem); + return SetItem(&lvItem) ? nItem : -1; + } + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + BOOL SortItemsEx(PFNLVCOMPARE pfnCompare, LPARAM lParamSort) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SORTITEMSEX, (WPARAM)lParamSort, (LPARAM)pfnCompare); + } +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + +#if (_WIN32_WINNT >= 0x0501) + int InsertGroup(int nItem, PLVGROUP pGroup) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_INSERTGROUP, nItem, (LPARAM)pGroup); + } + + int AddGroup(PLVGROUP pGroup) + { + return InsertGroup(-1, pGroup); + } + + int RemoveGroup(int nGroupID) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_REMOVEGROUP, nGroupID, 0L); + } + + void MoveGroup(int nGroupID, int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_MOVEGROUP, nGroupID, nItem); + } + + void MoveItemToGroup(int nItem, int nGroupID) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_MOVEITEMTOGROUP, nItem, nGroupID); + } + + int EnableGroupView(BOOL bEnable) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_ENABLEGROUPVIEW, bEnable, 0L); + } + + int SortGroups(PFNLVGROUPCOMPARE pCompareFunc, LPVOID lpVoid = NULL) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_SORTGROUPS, (WPARAM)pCompareFunc, (LPARAM)lpVoid); + } + + void InsertGroupSorted(PLVINSERTGROUPSORTED pInsertGroupSorted) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_INSERTGROUPSORTED, (WPARAM)pInsertGroupSorted, 0L); + } + + void RemoveAllGroups() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_REMOVEALLGROUPS, 0, 0L); + } + + BOOL HasGroup(int nGroupID) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_HASGROUP, nGroupID, 0L); + } + + BOOL InsertMarkHitTest(LPPOINT lpPoint, LPLVINSERTMARK pInsertMark) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_INSERTMARKHITTEST, (WPARAM)lpPoint, (LPARAM)pInsertMark); + } + + BOOL SetInfoTip(PLVSETINFOTIP pSetInfoTip) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LVM_SETINFOTIP, 0, (LPARAM)pSetInfoTip); + } + + void CancelEditLabel() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, LVM_CANCELEDITLABEL, 0, 0L); + } + + UINT MapIndexToID(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, LVM_MAPINDEXTOID, nIndex, 0L); + } + + int MapIDToIndex(UINT uID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_MAPIDTOINDEX, uID, 0L); + } +#endif // (_WIN32_WINNT >= 0x0501) + +#if (_WIN32_WINNT >= 0x0600) + int HitTestEx(LPLVHITTESTINFO lpHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_HITTEST, (WPARAM)-1, (LPARAM)lpHitTestInfo); + } + + int HitTestEx(POINT pt, UINT* pFlags) const + { + ATLASSERT(::IsWindow(m_hWnd)); + LVHITTESTINFO hti = { 0 }; + hti.pt = pt; + int nRes = (int)::SendMessage(m_hWnd, LVM_HITTEST, (WPARAM)-1, (LPARAM)&hti); + if (pFlags != NULL) + *pFlags = hti.flags; + return nRes; + } + + int SubItemHitTestEx(LPLVHITTESTINFO lpHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LVM_SUBITEMHITTEST, (WPARAM)-1, (LPARAM)lpHitTestInfo); + } +#endif // (_WIN32_WINNT >= 0x0600) + + // Note: selects only one item + BOOL SelectItem(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + + // multi-selection only: de-select all items + if((GetStyle() & LVS_SINGLESEL) == 0) + SetItemState(-1, 0, LVIS_SELECTED); + + BOOL bRet = SetItemState(nIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + if(bRet) + bRet = EnsureVisible(nIndex, FALSE); + + return bRet; + } +}; + +typedef CListViewCtrlT CListViewCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CTreeViewCtrl + +template +class CTreeViewCtrlT : public TBase +{ +public: +// Constructors + CTreeViewCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CTreeViewCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_TREEVIEW; + } + + UINT GetCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, TVM_GETCOUNT, 0, 0L); + } + + UINT GetIndent() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, TVM_GETINDENT, 0, 0L); + } + + void SetIndent(UINT nIndent) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TVM_SETINDENT, nIndent, 0L); + } + + CImageList GetImageList(int nImageListType = TVSIL_NORMAL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TVM_GETIMAGELIST, (WPARAM)nImageListType, 0L)); + } + + CImageList SetImageList(HIMAGELIST hImageList, int nImageListType = TVSIL_NORMAL) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TVM_SETIMAGELIST, (WPARAM)nImageListType, (LPARAM)hImageList)); + } + + BOOL GetItem(LPTVITEM pItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)pItem); + } + + BOOL SetItem(LPTVITEM pItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)pItem); + } + + BOOL SetItem(HTREEITEM hItem, UINT nMask, LPCTSTR lpszItem, int nImage, + int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + TVITEM item = { 0 }; + item.hItem = hItem; + item.mask = nMask; + item.pszText = (LPTSTR) lpszItem; + item.iImage = nImage; + item.iSelectedImage = nSelectedImage; + item.state = nState; + item.stateMask = nStateMask; + item.lParam = lParam; + return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)&item); + } + + BOOL GetItemText(HTREEITEM hItem, LPTSTR lpstrText, int nLen) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpstrText != NULL); + + TVITEM item = { 0 }; + item.hItem = hItem; + item.mask = TVIF_TEXT; + item.pszText = lpstrText; + item.cchTextMax = nLen; + + return (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); + } + +#ifndef _ATL_NO_COM + BOOL GetItemText(HTREEITEM hItem, BSTR& bstrText) const + { + USES_CONVERSION; + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(bstrText == NULL); + TVITEM item = { 0 }; + item.hItem = hItem; + item.mask = TVIF_TEXT; + + LPTSTR lpstrText = NULL; + BOOL bRet = FALSE; + for(int nLen = 256; ; nLen *= 2) + { + ATLTRY(lpstrText = new TCHAR[nLen]); + if(lpstrText == NULL) + break; + lpstrText[0] = NULL; + item.pszText = lpstrText; + item.cchTextMax = nLen; + bRet = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); + if(!bRet || (lstrlen(item.pszText) < nLen - 1)) + break; + delete [] lpstrText; + lpstrText = NULL; + } + + if(lpstrText != NULL) + { + if(bRet) + bstrText = ::SysAllocString(T2OLE(lpstrText)); + delete [] lpstrText; + } + + return (bstrText != NULL) ? TRUE : FALSE; + } +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + BOOL GetItemText(HTREEITEM hItem, _CSTRING_NS::CString& strText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TVITEM item = { 0 }; + item.hItem = hItem; + item.mask = TVIF_TEXT; + + strText.Empty(); + BOOL bRet = FALSE; + for(int nLen = 256; ; nLen *= 2) + { + item.pszText = strText.GetBufferSetLength(nLen); + if(item.pszText == NULL) + { + bRet = FALSE; + break; + } + item.cchTextMax = nLen; + bRet = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); + if(!bRet || (lstrlen(item.pszText) < nLen - 1)) + break; + } + strText.ReleaseBuffer(); + return bRet; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + BOOL SetItemText(HTREEITEM hItem, LPCTSTR lpszItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItem(hItem, TVIF_TEXT, lpszItem, 0, 0, 0, 0, NULL); + } + + BOOL GetItemImage(HTREEITEM hItem, int& nImage, int& nSelectedImage) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TVITEM item = { 0 }; + item.hItem = hItem; + item.mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE; + BOOL bRes = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); + if (bRes) + { + nImage = item.iImage; + nSelectedImage = item.iSelectedImage; + } + return bRes; + } + + BOOL SetItemImage(HTREEITEM hItem, int nImage, int nSelectedImage) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItem(hItem, TVIF_IMAGE|TVIF_SELECTEDIMAGE, NULL, nImage, nSelectedImage, 0, 0, NULL); + } + + UINT GetItemState(HTREEITEM hItem, UINT nStateMask) const + { + ATLASSERT(::IsWindow(m_hWnd)); +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + return (((UINT)::SendMessage(m_hWnd, TVM_GETITEMSTATE, (WPARAM)hItem, (LPARAM)nStateMask)) & nStateMask); +#else // !((_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)) + TVITEM item = { 0 }; + item.hItem = hItem; + item.mask = TVIF_STATE; + item.state = 0; + item.stateMask = nStateMask; + ::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); + return (item.state & nStateMask); +#endif // !((_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)) + } + + BOOL SetItemState(HTREEITEM hItem, UINT nState, UINT nStateMask) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItem(hItem, TVIF_STATE, NULL, 0, 0, nState, nStateMask, NULL); + } + + DWORD_PTR GetItemData(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TVITEM item = { 0 }; + item.hItem = hItem; + item.mask = TVIF_PARAM; + BOOL bRet = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); + return (DWORD_PTR)(bRet ? item.lParam : NULL); + } + + BOOL SetItemData(HTREEITEM hItem, DWORD_PTR dwData) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItem(hItem, TVIF_PARAM, NULL, 0, 0, 0, 0, (LPARAM)dwData); + } + + CEdit GetEditControl() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CEdit((HWND)::SendMessage(m_hWnd, TVM_GETEDITCONTROL, 0, 0L)); + } + + UINT GetVisibleCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, TVM_GETVISIBLECOUNT, 0, 0L); + } + + BOOL GetItemRect(HTREEITEM hItem, LPRECT lpRect, BOOL bTextOnly) const + { + ATLASSERT(::IsWindow(m_hWnd)); + *(HTREEITEM*)lpRect = hItem; + return (BOOL)::SendMessage(m_hWnd, TVM_GETITEMRECT, (WPARAM)bTextOnly, (LPARAM)lpRect); + } + + BOOL ItemHasChildren(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TVITEM item = { 0 }; + item.hItem = hItem; + item.mask = TVIF_CHILDREN; + ::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); + return item.cChildren; + } + +#ifndef _WIN32_WCE + CToolTipCtrl GetToolTips() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TVM_GETTOOLTIPS, 0, 0L)); + } + + CToolTipCtrl SetToolTips(HWND hWndTT) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TVM_SETTOOLTIPS, (WPARAM)hWndTT, 0L)); + } +#endif // !_WIN32_WCE + + int GetISearchString(LPTSTR lpstr) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TVM_GETISEARCHSTRING, 0, (LPARAM)lpstr); + } + + // checkboxes only + BOOL GetCheckState(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & TVS_CHECKBOXES) != 0); + UINT uRet = GetItemState(hItem, TVIS_STATEIMAGEMASK); + return (uRet >> 12) - 1; + } + + BOOL SetCheckState(HTREEITEM hItem, BOOL bCheck) + { + int nCheck = bCheck ? 2 : 1; // one based index + return SetItemState(hItem, INDEXTOSTATEIMAGEMASK(nCheck), TVIS_STATEIMAGEMASK); + } + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + COLORREF GetBkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TVM_GETBKCOLOR, 0, 0L); + } + + COLORREF SetBkColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TVM_SETBKCOLOR, 0, (LPARAM)clr); + } + + COLORREF GetInsertMarkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TVM_GETINSERTMARKCOLOR, 0, 0L); + } + + COLORREF SetInsertMarkColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TVM_SETINSERTMARKCOLOR, 0, (LPARAM)clr); + } + + int GetItemHeight() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TVM_GETITEMHEIGHT, 0, 0L); + } + + int SetItemHeight(int cyHeight) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TVM_SETITEMHEIGHT, cyHeight, 0L); + } + + int GetScrollTime() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TVM_GETSCROLLTIME, 0, 0L); + } + + int SetScrollTime(int nScrollTime) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TVM_SETSCROLLTIME, nScrollTime, 0L); + } + + COLORREF GetTextColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TVM_GETTEXTCOLOR, 0, 0L); + } + + COLORREF SetTextColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TVM_SETTEXTCOLOR, 0, (LPARAM)clr); + } + + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + COLORREF GetLineColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TVM_GETLINECOLOR, 0, 0L); + } + + COLORREF SetLineColor(COLORREF clrNew /*= CLR_DEFAULT*/) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TVM_SETLINECOLOR, 0, (LPARAM)clrNew); + } +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + BOOL GetItem(LPTVITEMEX pItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)pItem); + } + + BOOL SetItem(LPTVITEMEX pItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)pItem); + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + + DWORD GetExtendedStyle() const + { +#ifndef TVM_GETEXTENDEDSTYLE + const UINT TVM_GETEXTENDEDSTYLE = (TV_FIRST + 45); +#endif + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TVM_GETEXTENDEDSTYLE, 0, 0L); + } + + DWORD SetExtendedStyle(DWORD dwStyle, DWORD dwMask) + { +#ifndef TVM_SETEXTENDEDSTYLE + const UINT TVM_SETEXTENDEDSTYLE = (TV_FIRST + 44); +#endif + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TVM_SETEXTENDEDSTYLE, dwMask, dwStyle); + } + +#if (_WIN32_WINNT >= 0x0600) + BOOL SetAutoScrollInfo(UINT uPixPerSec, UINT uUpdateTime) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SETAUTOSCROLLINFO, (WPARAM)uPixPerSec, (LPARAM)uUpdateTime); + } + + DWORD GetSelectedCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TVM_GETSELECTEDCOUNT, 0, 0L); + } + + BOOL GetItemPartRect(HTREEITEM hItem, TVITEMPART partID, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TVGETITEMPARTRECTINFO gipri = { hItem, lpRect, partID }; + return (BOOL)::SendMessage(m_hWnd, TVM_GETITEMPARTRECT, 0, (LPARAM)&gipri); + } +#endif // (_WIN32_WINNT >= 0x0600) + +// Operations + HTREEITEM InsertItem(LPTVINSERTSTRUCT lpInsertStruct) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)lpInsertStruct); + } + + HTREEITEM InsertItem(LPCTSTR lpszItem, int nImage, + int nSelectedImage, HTREEITEM hParent, HTREEITEM hInsertAfter) + { + ATLASSERT(::IsWindow(m_hWnd)); + return InsertItem(TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE, lpszItem, nImage, nSelectedImage, 0, 0, 0, hParent, hInsertAfter); + } + + HTREEITEM InsertItem(LPCTSTR lpszItem, HTREEITEM hParent, HTREEITEM hInsertAfter) + { + ATLASSERT(::IsWindow(m_hWnd)); + return InsertItem(TVIF_TEXT, lpszItem, 0, 0, 0, 0, 0, hParent, hInsertAfter); + } + + HTREEITEM InsertItem(UINT nMask, LPCTSTR lpszItem, int nImage, + int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam, + HTREEITEM hParent, HTREEITEM hInsertAfter) + { + ATLASSERT(::IsWindow(m_hWnd)); + TVINSERTSTRUCT tvis = { 0 }; + tvis.hParent = hParent; + tvis.hInsertAfter = hInsertAfter; + tvis.item.mask = nMask; + tvis.item.pszText = (LPTSTR) lpszItem; + tvis.item.iImage = nImage; + tvis.item.iSelectedImage = nSelectedImage; + tvis.item.state = nState; + tvis.item.stateMask = nStateMask; + tvis.item.lParam = lParam; + return (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)&tvis); + } + + BOOL DeleteItem(HTREEITEM hItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_DELETEITEM, 0, (LPARAM)hItem); + } + + BOOL DeleteAllItems() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT); + } + + BOOL Expand(HTREEITEM hItem, UINT nCode = TVE_EXPAND) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_EXPAND, nCode, (LPARAM)hItem); + } + + HTREEITEM GetNextItem(HTREEITEM hItem, UINT nCode) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, nCode, (LPARAM)hItem); + } + + HTREEITEM GetChildItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem); + } + + HTREEITEM GetNextSiblingItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem); + } + + HTREEITEM GetPrevSiblingItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PREVIOUS, (LPARAM)hItem); + } + + HTREEITEM GetParentItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItem); + } + + HTREEITEM GetFirstVisibleItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_FIRSTVISIBLE, 0L); + } + + HTREEITEM GetNextVisibleItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, (LPARAM)hItem); + } + + HTREEITEM GetPrevVisibleItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PREVIOUSVISIBLE, (LPARAM)hItem); + } + + HTREEITEM GetSelectedItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CARET, 0L); + } + + HTREEITEM GetDropHilightItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_DROPHILITE, 0L); + } + + HTREEITEM GetRootItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_ROOT, 0L); + } + +#if !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) + HTREEITEM GetLastVisibleItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_LASTVISIBLE, 0L); + } +#endif // !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0600) + HTREEITEM GetNextSelectedItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXTSELECTED, 0L); + } +#endif // (_WIN32_IE >= 0x0600) + + BOOL Select(HTREEITEM hItem, UINT nCode) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SELECTITEM, nCode, (LPARAM)hItem); + } + + BOOL SelectItem(HTREEITEM hItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hItem); + } + + BOOL SelectDropTarget(HTREEITEM hItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SELECTITEM, TVGN_DROPHILITE, (LPARAM)hItem); + } + + BOOL SelectSetFirstVisible(HTREEITEM hItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SELECTITEM, TVGN_FIRSTVISIBLE, (LPARAM)hItem); + } + + CEdit EditLabel(HTREEITEM hItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CEdit((HWND)::SendMessage(m_hWnd, TVM_EDITLABEL, 0, (LPARAM)hItem)); + } + + BOOL EndEditLabelNow(BOOL bCancel) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_ENDEDITLABELNOW, bCancel, 0L); + } + + HTREEITEM HitTest(TVHITTESTINFO* pHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0, (LPARAM)pHitTestInfo); + } + + HTREEITEM HitTest(POINT pt, UINT* pFlags) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TVHITTESTINFO hti = { 0 }; + hti.pt = pt; + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0, (LPARAM)&hti); + if (pFlags != NULL) + *pFlags = hti.flags; + return hTreeItem; + } + + BOOL SortChildren(HTREEITEM hItem, BOOL bRecurse = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SORTCHILDREN, (WPARAM)bRecurse, (LPARAM)hItem); + } + + BOOL EnsureVisible(HTREEITEM hItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_ENSUREVISIBLE, 0, (LPARAM)hItem); + } + + BOOL SortChildrenCB(LPTVSORTCB pSort, BOOL bRecurse = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SORTCHILDRENCB, (WPARAM)bRecurse, (LPARAM)pSort); + } + + CImageList RemoveImageList(int nImageList) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TVM_SETIMAGELIST, (WPARAM)nImageList, NULL)); + } + + CImageList CreateDragImage(HTREEITEM hItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TVM_CREATEDRAGIMAGE, 0, (LPARAM)hItem)); + } + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + BOOL SetInsertMark(HTREEITEM hTreeItem, BOOL bAfter) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SETINSERTMARK, bAfter, (LPARAM)hTreeItem); + } + + BOOL RemoveInsertMark() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TVM_SETINSERTMARK, 0, 0L); + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +#if (_WIN32_WINNT >= 0x0501) + HTREEITEM MapAccIDToHTREEITEM(UINT uID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HTREEITEM)::SendMessage(m_hWnd, TVM_MAPACCIDTOHTREEITEM, uID, 0L); + } + + UINT MapHTREEITEMToAccID(HTREEITEM hTreeItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, TVM_MAPHTREEITEMTOACCID, (WPARAM)hTreeItem, 0L); + } +#endif // (_WIN32_WINNT >= 0x0501) + +#if (_WIN32_WINNT >= 0x0600) + void ShowInfoTip(HTREEITEM hItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TVM_SHOWINFOTIP, 0, (LPARAM)hItem); + } +#endif // (_WIN32_WINNT >= 0x0600) +}; + +typedef CTreeViewCtrlT CTreeViewCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CTreeViewCtrlEx + +// forward declaration +template class CTreeViewCtrlExT; + +// Note: TBase here is for CTreeViewCtrlExT, and not for CTreeItemT itself +template +class CTreeItemT +{ +public: + HTREEITEM m_hTreeItem; + CTreeViewCtrlExT* m_pTreeView; + +// Construction + CTreeItemT(HTREEITEM hTreeItem = NULL, CTreeViewCtrlExT* pTreeView = NULL) : m_hTreeItem(hTreeItem), m_pTreeView(pTreeView) + { } + + CTreeItemT(const CTreeItemT& posSrc) + { + *this = posSrc; + } + + operator HTREEITEM() { return m_hTreeItem; } + + CTreeItemT& operator =(const CTreeItemT& itemSrc) + { + m_hTreeItem = itemSrc.m_hTreeItem; + m_pTreeView = itemSrc.m_pTreeView; + return *this; + } + +// Attributes + CTreeViewCtrlExT* GetTreeView() const { return m_pTreeView; } + + BOOL operator !() const { return m_hTreeItem == NULL; } + + BOOL IsNull() const { return m_hTreeItem == NULL; } + + BOOL GetRect(LPRECT lpRect, BOOL bTextOnly) const; + BOOL GetText(LPTSTR lpstrText, int nLen) const; +#ifndef _ATL_NO_COM + BOOL GetText(BSTR& bstrText) const; +#endif // !_ATL_NO_COM +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + BOOL GetText(_CSTRING_NS::CString& strText) const; +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + BOOL SetText(LPCTSTR lpszItem); + BOOL GetImage(int& nImage, int& nSelectedImage) const; + BOOL SetImage(int nImage, int nSelectedImage); + UINT GetState(UINT nStateMask) const; + BOOL SetState(UINT nState, UINT nStateMask); + DWORD_PTR GetData() const; + BOOL SetData(DWORD_PTR dwData); + BOOL SetItem(UINT nMask, LPCTSTR lpszItem, int nImage, int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam); + +// Operations + CTreeItemT InsertAfter(LPCTSTR lpstrItem, HTREEITEM hItemAfter, int nImageIndex) + { + return _Insert(lpstrItem, nImageIndex, hItemAfter); + } + + CTreeItemT AddHead(LPCTSTR lpstrItem, int nImageIndex) + { + return _Insert(lpstrItem, nImageIndex, TVI_FIRST); + } + + CTreeItemT AddTail(LPCTSTR lpstrItem, int nImageIndex) + { + return _Insert(lpstrItem, nImageIndex, TVI_LAST); + } + + CTreeItemT GetChild() const; + CTreeItemT GetNext(UINT nCode) const; + CTreeItemT GetNextSibling() const; + CTreeItemT GetPrevSibling() const; + CTreeItemT GetParent() const; + CTreeItemT GetFirstVisible() const; + CTreeItemT GetNextVisible() const; + CTreeItemT GetPrevVisible() const; + CTreeItemT GetSelected() const; + CTreeItemT GetDropHilight() const; + CTreeItemT GetRoot() const; +#if !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) + CTreeItemT GetLastVisible() const; +#endif // !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) +#if (_WIN32_IE >= 0x0600) + CTreeItemT GetNextSelected() const; +#endif // (_WIN32_IE >= 0x0600) + BOOL HasChildren() const; + BOOL Delete(); + BOOL Expand(UINT nCode = TVE_EXPAND); + BOOL Select(UINT nCode); + BOOL Select(); + BOOL SelectDropTarget(); + BOOL SelectSetFirstVisible(); + HWND EditLabel(); + HIMAGELIST CreateDragImage(); + BOOL SortChildren(BOOL bRecurse = FALSE); + BOOL EnsureVisible(); + CTreeItemT _Insert(LPCTSTR lpstrItem, int nImageIndex, HTREEITEM hItemAfter); + int GetImageIndex() const; +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + BOOL SetInsertMark(BOOL bAfter); +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) +#if (_WIN32_WINNT >= 0x0501) + UINT MapHTREEITEMToAccID() const; +#endif // (_WIN32_WINNT >= 0x0501) +#if (_WIN32_WINNT >= 0x0600) + void ShowInfoTip(); + BOOL GetPartRect(TVITEMPART partID, LPRECT lpRect) const; +#endif // (_WIN32_WINNT >= 0x0600) +}; + +typedef CTreeItemT CTreeItem; + + +template +class CTreeViewCtrlExT : public CTreeViewCtrlT< TBase > +{ +public: +// Constructors + CTreeViewCtrlExT(HWND hWnd = NULL) : CTreeViewCtrlT< TBase >(hWnd) + { } + + CTreeViewCtrlExT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + +// Operations (overides that return CTreeItem) + CTreeItemT InsertItem(LPTVINSERTSTRUCT lpInsertStruct) + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)lpInsertStruct); + return CTreeItemT(hTreeItem, this); + } + + CTreeItemT InsertItem(LPCTSTR lpszItem, int nImage, + int nSelectedImage, HTREEITEM hParent, HTREEITEM hInsertAfter) + { + ATLASSERT(::IsWindow(m_hWnd)); + return InsertItem(TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE, lpszItem, nImage, nSelectedImage, 0, 0, 0, hParent, hInsertAfter); + } + + CTreeItemT InsertItem(LPCTSTR lpszItem, HTREEITEM hParent, HTREEITEM hInsertAfter) + { + ATLASSERT(::IsWindow(m_hWnd)); + return InsertItem(TVIF_TEXT, lpszItem, 0, 0, 0, 0, 0, hParent, hInsertAfter); + } + + CTreeItemT GetNextItem(HTREEITEM hItem, UINT nCode) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, nCode, (LPARAM)hItem); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetChildItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetNextSiblingItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetPrevSiblingItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PREVIOUS, (LPARAM)hItem); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetParentItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItem); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetFirstVisibleItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_FIRSTVISIBLE, 0L); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetNextVisibleItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, (LPARAM)hItem); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetPrevVisibleItem(HTREEITEM hItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_PREVIOUSVISIBLE, (LPARAM)hItem); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetSelectedItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CARET, 0L); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetDropHilightItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_DROPHILITE, 0L); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT GetRootItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_ROOT, 0L); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + +#if !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) + CTreeItemT GetLastVisibleItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_LASTVISIBLE, 0L); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } +#endif // !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0600) + CTreeItemT GetNextSelectedItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_NEXTSELECTED, 0L); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } +#endif // (_WIN32_IE >= 0x0600) + + CTreeItemT HitTest(TVHITTESTINFO* pHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0, (LPARAM)pHitTestInfo); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + + CTreeItemT InsertItem(UINT nMask, LPCTSTR lpszItem, int nImage, + int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam, + HTREEITEM hParent, HTREEITEM hInsertAfter) + { + ATLASSERT(::IsWindow(m_hWnd)); + TVINSERTSTRUCT tvis = { 0 }; + tvis.hParent = hParent; + tvis.hInsertAfter = hInsertAfter; + tvis.item.mask = nMask; + tvis.item.pszText = (LPTSTR) lpszItem; + tvis.item.iImage = nImage; + tvis.item.iSelectedImage = nSelectedImage; + tvis.item.state = nState; + tvis.item.stateMask = nStateMask; + tvis.item.lParam = lParam; + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)&tvis); + return CTreeItemT(hTreeItem, this); + } + + CTreeItemT HitTest(POINT pt, UINT* pFlags) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TVHITTESTINFO hti = { 0 }; + hti.pt = pt; + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0, (LPARAM)&hti); + if (pFlags != NULL) + *pFlags = hti.flags; + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } + +#if (_WIN32_WINNT >= 0x0501) + CTreeItemT MapAccIDToHTREEITEM(UINT uID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + HTREEITEM hTreeItem = (HTREEITEM)::SendMessage(m_hWnd, TVM_MAPACCIDTOHTREEITEM, uID, 0L); + return CTreeItemT(hTreeItem, (CTreeViewCtrlExT*)this); + } +#endif // (_WIN32_WINNT >= 0x0501) +}; + +typedef CTreeViewCtrlExT CTreeViewCtrlEx; + + +// CTreeItem inline methods +template +inline BOOL CTreeItemT::GetRect(LPRECT lpRect, BOOL bTextOnly) const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetItemRect(m_hTreeItem,lpRect,bTextOnly); +} + +template +inline CTreeItemT CTreeItemT::GetNext(UINT nCode) const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetNextItem(m_hTreeItem,nCode); +} + +template +inline CTreeItemT CTreeItemT::GetChild() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetChildItem(m_hTreeItem); +} + +template +inline CTreeItemT CTreeItemT::GetNextSibling() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetNextSiblingItem(m_hTreeItem); +} + +template +inline CTreeItemT CTreeItemT::GetPrevSibling() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetPrevSiblingItem(m_hTreeItem); +} + +template +inline CTreeItemT CTreeItemT::GetParent() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetParentItem(m_hTreeItem); +} + +template +inline CTreeItemT CTreeItemT::GetFirstVisible() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetFirstVisibleItem(); +} + +template +inline CTreeItemT CTreeItemT::GetNextVisible() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetNextVisibleItem(m_hTreeItem); +} + +template +inline CTreeItemT CTreeItemT::GetPrevVisible() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetPrevVisibleItem(m_hTreeItem); +} + +template +inline CTreeItemT CTreeItemT::GetSelected() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetSelectedItem(); +} + +template +inline CTreeItemT CTreeItemT::GetDropHilight() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetDropHilightItem(); +} + +template +inline CTreeItemT CTreeItemT::GetRoot() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetRootItem(); +} + +#if !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) +template +inline CTreeItemT CTreeItemT::GetLastVisible() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetLastVisibleItem(); +} +#endif // !defined(_WIN32_WCE) && (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0600) +template +inline CTreeItemT CTreeItemT::GetNextSelected() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetNextSelectedItem(); +} +#endif // (_WIN32_IE >= 0x0600) + +template +inline BOOL CTreeItemT::GetText(LPTSTR lpstrText, int nLen) const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetItemText(m_hTreeItem, lpstrText, nLen); +} + +#ifndef _ATL_NO_COM +#ifdef _OLEAUTO_H_ +template +inline BOOL CTreeItemT::GetText(BSTR& bstrText) const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetItemText(m_hTreeItem, bstrText); +} +#endif // _OLEAUTO_H_ +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) +template +inline BOOL CTreeItemT::GetText(_CSTRING_NS::CString& strText) const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetItemText(m_hTreeItem, strText); +} +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + +template +inline BOOL CTreeItemT::GetImage(int& nImage, int& nSelectedImage) const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetItemImage(m_hTreeItem,nImage,nSelectedImage); +} + +template +inline UINT CTreeItemT::GetState(UINT nStateMask) const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetItemState(m_hTreeItem,nStateMask); +} + +template +inline DWORD_PTR CTreeItemT::GetData() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetItemData(m_hTreeItem); +} + +template +inline BOOL CTreeItemT::SetItem(UINT nMask, LPCTSTR lpszItem, int nImage, + int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SetItem(m_hTreeItem, nMask, lpszItem, nImage, nSelectedImage, nState, nStateMask, lParam); +} + +template +inline BOOL CTreeItemT::SetText(LPCTSTR lpszItem) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SetItemText(m_hTreeItem,lpszItem); +} + +template +inline BOOL CTreeItemT::SetImage(int nImage, int nSelectedImage) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SetItemImage(m_hTreeItem,nImage,nSelectedImage); +} + +template +inline BOOL CTreeItemT::SetState(UINT nState, UINT nStateMask) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SetItemState(m_hTreeItem,nState,nStateMask); +} + +template +inline BOOL CTreeItemT::SetData(DWORD_PTR dwData) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SetItemData(m_hTreeItem,dwData); +} + +template +inline BOOL CTreeItemT::HasChildren() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->ItemHasChildren(m_hTreeItem); +} + +template +inline BOOL CTreeItemT::Delete() +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->DeleteItem(m_hTreeItem); +} + +template +inline BOOL CTreeItemT::Expand(UINT nCode /*= TVE_EXPAND*/) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->Expand(m_hTreeItem,nCode); +} + +template +inline BOOL CTreeItemT::Select(UINT nCode) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->Select(m_hTreeItem,nCode); +} + +template +inline BOOL CTreeItemT::Select() +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SelectItem(m_hTreeItem); +} + +template +inline BOOL CTreeItemT::SelectDropTarget() +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SelectDropTarget(m_hTreeItem); +} + +template +inline BOOL CTreeItemT::SelectSetFirstVisible() +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SelectSetFirstVisible(m_hTreeItem); +} + +template +inline HWND CTreeItemT::EditLabel() +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->EditLabel(m_hTreeItem); +} + +template +inline HIMAGELIST CTreeItemT::CreateDragImage() +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->CreateDragImage(m_hTreeItem); +} + +template +inline BOOL CTreeItemT::SortChildren(BOOL bRecurse /*= FALSE*/) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SortChildren(m_hTreeItem, bRecurse); +} + +template +inline BOOL CTreeItemT::EnsureVisible() +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->EnsureVisible(m_hTreeItem); +} + +template +inline CTreeItemT CTreeItemT::_Insert(LPCTSTR lpstrItem, int nImageIndex, HTREEITEM hItemAfter) +{ + ATLASSERT(m_pTreeView != NULL); + TVINSERTSTRUCT ins = { 0 }; + ins.hParent = m_hTreeItem; + ins.hInsertAfter = hItemAfter; + ins.item.mask = TVIF_TEXT; + ins.item.pszText = (LPTSTR)lpstrItem; + if(nImageIndex != -1) + { + ins.item.mask |= TVIF_IMAGE | TVIF_SELECTEDIMAGE; + ins.item.iImage = nImageIndex; + ins.item.iSelectedImage = nImageIndex; + } + return CTreeItemT(m_pTreeView->InsertItem(&ins), m_pTreeView); +} + +template +inline int CTreeItemT::GetImageIndex() const +{ + ATLASSERT(m_pTreeView != NULL); + TVITEM item = { 0 }; + item.mask = TVIF_HANDLE | TVIF_IMAGE; + item.hItem = m_hTreeItem; + m_pTreeView->GetItem(&item); + return item.iImage; +} + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) +template +inline BOOL CTreeItemT::SetInsertMark(BOOL bAfter) +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->SetInsertMark(m_hTreeItem, bAfter); +} +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +#if (_WIN32_WINNT >= 0x0501) +template +inline UINT CTreeItemT::MapHTREEITEMToAccID() const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->MapHTREEITEMToAccID(m_hTreeItem); +} +#endif // (_WIN32_WINNT >= 0x0501) + +#if (_WIN32_WINNT >= 0x0600) +template +inline void CTreeItemT::ShowInfoTip() +{ + ATLASSERT(m_pTreeView != NULL); + m_pTreeView->ShowInfoTip(m_hTreeItem); +} + +template +inline BOOL CTreeItemT::GetPartRect(TVITEMPART partID, LPRECT lpRect) const +{ + ATLASSERT(m_pTreeView != NULL); + return m_pTreeView->GetItemPartRect(m_hTreeItem, partID, lpRect); +} +#endif // (_WIN32_WINNT >= 0x0600) + + +/////////////////////////////////////////////////////////////////////////////// +// CToolBarCtrl + +template +class CToolBarCtrlT : public TBase +{ +public: +// Construction + CToolBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CToolBarCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return TOOLBARCLASSNAME; + } + + BOOL IsButtonEnabled(int nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONENABLED, nID, 0L); + } + + BOOL IsButtonChecked(int nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONCHECKED, nID, 0L); + } + + BOOL IsButtonPressed(int nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONPRESSED, nID, 0L); + } + + BOOL IsButtonHidden(int nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return(BOOL) ::SendMessage(m_hWnd, TB_ISBUTTONHIDDEN, nID, 0L); + } + + BOOL IsButtonIndeterminate(int nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONINDETERMINATE, nID, 0L); + } + + int GetState(int nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_GETSTATE, nID, 0L); + } + + BOOL SetState(int nID, UINT nState) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETSTATE, nID, MAKELPARAM(nState, 0)); + } + + BOOL GetButton(int nIndex, LPTBBUTTON lpButton) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_GETBUTTON, nIndex, (LPARAM)lpButton); + } + + int GetButtonCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_BUTTONCOUNT, 0, 0L); + } + + BOOL GetItemRect(int nIndex, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_GETITEMRECT, nIndex, (LPARAM)lpRect); + } + + void SetButtonStructSize(int nSize = sizeof(TBBUTTON)) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_BUTTONSTRUCTSIZE, nSize, 0L); + } + + BOOL SetButtonSize(SIZE size) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONSIZE, 0, MAKELPARAM(size.cx, size.cy)); + } + + BOOL SetButtonSize(int cx, int cy) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONSIZE, 0, MAKELPARAM(cx, cy)); + } + + BOOL SetBitmapSize(SIZE size) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETBITMAPSIZE, 0, MAKELPARAM(size.cx, size.cy)); + } + + BOOL SetBitmapSize(int cx, int cy) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETBITMAPSIZE, 0, MAKELPARAM(cx, cy)); + } + +#ifndef _WIN32_WCE + CToolTipCtrl GetToolTips() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TB_GETTOOLTIPS, 0, 0L)); + } + + void SetToolTips(HWND hWndToolTip) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_SETTOOLTIPS, (WPARAM)hWndToolTip, 0L); + } +#endif // !_WIN32_WCE + + void SetNotifyWnd(HWND hWnd) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_SETPARENT, (WPARAM)hWnd, 0L); + } + + int GetRows() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_GETROWS, 0, 0L); + } + + void SetRows(int nRows, BOOL bLarger, LPRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_SETROWS, MAKELPARAM(nRows, bLarger), (LPARAM)lpRect); + } + + BOOL SetCmdID(int nIndex, UINT nID) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETCMDID, nIndex, nID); + } + + DWORD GetBitmapFlags() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TB_GETBITMAPFLAGS, 0, 0L); + } + + int GetBitmap(int nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_GETBITMAP, nID, 0L); + } + + int GetButtonText(int nID, LPTSTR lpstrText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_GETBUTTONTEXT, nID, (LPARAM)lpstrText); + } + + // nIndex - IE5 or higher only + CImageList GetImageList(int nIndex = 0) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_GETIMAGELIST, nIndex, 0L)); + } + + // nIndex - IE5 or higher only + CImageList SetImageList(HIMAGELIST hImageList, int nIndex = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_SETIMAGELIST, nIndex, (LPARAM)hImageList)); + } + + // nIndex - IE5 or higher only + CImageList GetDisabledImageList(int nIndex = 0) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_GETDISABLEDIMAGELIST, nIndex, 0L)); + } + + // nIndex - IE5 or higher only + CImageList SetDisabledImageList(HIMAGELIST hImageList, int nIndex = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_SETDISABLEDIMAGELIST, nIndex, (LPARAM)hImageList)); + } + +#ifndef _WIN32_WCE + // nIndex - IE5 or higher only + CImageList GetHotImageList(int nIndex = 0) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_GETHOTIMAGELIST, nIndex, 0L)); + } + + // nIndex - IE5 or higher only + CImageList SetHotImageList(HIMAGELIST hImageList, int nIndex = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_SETHOTIMAGELIST, nIndex, (LPARAM)hImageList)); + } +#endif // !_WIN32_WCE + + DWORD GetStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TB_GETSTYLE, 0, 0L); + } + + void SetStyle(DWORD dwStyle) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_SETSTYLE, 0, dwStyle); + } + + DWORD GetButtonSize() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TB_GETBUTTONSIZE, 0, 0L); + } + + void GetButtonSize(SIZE& size) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, TB_GETBUTTONSIZE, 0, 0L); + size.cx = LOWORD(dwRet); + size.cy = HIWORD(dwRet); + } + + BOOL GetRect(int nID, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_GETRECT, nID, (LPARAM)lpRect); + } + + int GetTextRows() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_GETTEXTROWS, 0, 0L); + } + + BOOL SetButtonWidth(int cxMin, int cxMax) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONWIDTH, 0, MAKELPARAM(cxMin, cxMax)); + } + + BOOL SetIndent(int nIndent) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETINDENT, nIndent, 0L); + } + + BOOL SetMaxTextRows(int nMaxTextRows) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETMAXTEXTROWS, nMaxTextRows, 0L); + } + +#if (_WIN32_IE >= 0x0400) +#ifndef _WIN32_WCE + BOOL GetAnchorHighlight() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_GETANCHORHIGHLIGHT, 0, 0L); + } + + BOOL SetAnchorHighlight(BOOL bEnable = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETANCHORHIGHLIGHT, bEnable, 0L); + } +#endif // !_WIN32_WCE + + int GetButtonInfo(int nID, LPTBBUTTONINFO lptbbi) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_GETBUTTONINFO, nID, (LPARAM)lptbbi); + } + + BOOL SetButtonInfo(int nID, LPTBBUTTONINFO lptbbi) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONINFO, nID, (LPARAM)lptbbi); + } + + BOOL SetButtonInfo(int nID, DWORD dwMask, BYTE Style, BYTE State, LPCTSTR lpszItem, + int iImage, WORD cx, int iCommand, DWORD_PTR lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + TBBUTTONINFO tbbi = { 0 }; + tbbi.cbSize = sizeof(TBBUTTONINFO); + tbbi.dwMask = dwMask; + tbbi.idCommand = iCommand; + tbbi.iImage = iImage; + tbbi.fsState = State; + tbbi.fsStyle = Style; + tbbi.cx = cx; + tbbi.pszText = (LPTSTR) lpszItem; + tbbi.lParam = lParam; + return (BOOL)::SendMessage(m_hWnd, TB_SETBUTTONINFO, nID, (LPARAM)&tbbi); + } + +#ifndef _WIN32_WCE + int GetHotItem() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_GETHOTITEM, 0, 0L); + } + + int SetHotItem(int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_SETHOTITEM, nItem, 0L); + } +#endif // !_WIN32_WCE + + BOOL IsButtonHighlighted(int nButtonID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_ISBUTTONHIGHLIGHTED, nButtonID, 0L); + } + + DWORD SetDrawTextFlags(DWORD dwMask, DWORD dwFlags) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TB_SETDRAWTEXTFLAGS, dwMask, dwFlags); + } + +#ifndef _WIN32_WCE + BOOL GetColorScheme(LPCOLORSCHEME lpcs) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_GETCOLORSCHEME, 0, (LPARAM)lpcs); + } + + void SetColorScheme(LPCOLORSCHEME lpcs) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_SETCOLORSCHEME, 0, (LPARAM)lpcs); + } + + DWORD GetExtendedStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TB_GETEXTENDEDSTYLE, 0, 0L); + } + + DWORD SetExtendedStyle(DWORD dwStyle) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TB_SETEXTENDEDSTYLE, 0, dwStyle); + } + + void GetInsertMark(LPTBINSERTMARK lptbim) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_GETINSERTMARK, 0, (LPARAM)lptbim); + } + + void SetInsertMark(LPTBINSERTMARK lptbim) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_SETINSERTMARK, 0, (LPARAM)lptbim); + } + + COLORREF GetInsertMarkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TB_GETINSERTMARKCOLOR, 0, 0L); + } + + COLORREF SetInsertMarkColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, TB_SETINSERTMARKCOLOR, 0, (LPARAM)clr); + } + + BOOL GetMaxSize(LPSIZE lpSize) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_GETMAXSIZE, 0, (LPARAM)lpSize); + } + + void GetPadding(LPSIZE lpSizePadding) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpSizePadding != NULL); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, TB_GETPADDING, 0, 0L); + lpSizePadding->cx = GET_X_LPARAM(dwRet); + lpSizePadding->cy = GET_Y_LPARAM(dwRet); + } + + void SetPadding(int cx, int cy, LPSIZE lpSizePadding = NULL) + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, TB_SETPADDING, 0, MAKELPARAM(cx, cy)); + if(lpSizePadding != NULL) + { + lpSizePadding->cx = GET_X_LPARAM(dwRet); + lpSizePadding->cy = GET_Y_LPARAM(dwRet); + } + } + + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // !_WIN32_WCE +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + int GetString(int nString, LPTSTR lpstrString, int cchMaxLen) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(cchMaxLen, nString), (LPARAM)lpstrString); + } + + int GetStringBSTR(int nString, BSTR& bstrString) const + { + USES_CONVERSION; + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(bstrString == NULL); + int nLength = (int)(short)LOWORD(::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(0, nString), NULL)); + if(nLength != -1) + { + CTempBuffer buff; + LPTSTR lpstrText = buff.Allocate(nLength + 1); + if(lpstrText != NULL) + { + nLength = (int)::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(nLength + 1, nString), (LPARAM)lpstrText); + if(nLength != -1) + bstrString = ::SysAllocString(T2OLE(lpstrText)); + } + else + { + nLength = -1; + } + } + + return nLength; + } + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + int GetString(int nString, _CSTRING_NS::CString& str) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int nLength = (int)(short)LOWORD(::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(0, nString), NULL)); + if(nLength != -1) + { + LPTSTR lpstr = str.GetBufferSetLength(nLength + 1); + if(lpstr != NULL) + nLength = (int)::SendMessage(m_hWnd, TB_GETSTRING, MAKEWPARAM(nLength + 1, nString), (LPARAM)lpstr); + else + nLength = -1; + str.ReleaseBuffer(); + } + return nLength; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + +#if (_WIN32_WINNT >= 0x0501) + void GetMetrics(LPTBMETRICS lptbm) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_GETMETRICS, 0, (LPARAM)lptbm); + } + + void SetMetrics(LPTBMETRICS lptbm) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_SETMETRICS, 0, (LPARAM)lptbm); + } + + void SetWindowTheme(LPCWSTR lpstrTheme) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_SETWINDOWTHEME, 0, (LPARAM)lpstrTheme); + } +#endif // (_WIN32_WINNT >= 0x0501) + +#if (_WIN32_WINNT >= 0x0600) + CImageList GetPressedImageList(int nIndex = 0) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_GETPRESSEDIMAGELIST, nIndex, 0L)); + } + + CImageList SetPressedImageList(HIMAGELIST hImageList, int nIndex = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TB_SETPRESSEDIMAGELIST, nIndex, (LPARAM)hImageList)); + } +#endif // (_WIN32_WINNT >= 0x0600) + +// Operations + BOOL EnableButton(int nID, BOOL bEnable = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_ENABLEBUTTON, nID, MAKELPARAM(bEnable, 0)); + } + + BOOL CheckButton(int nID, BOOL bCheck = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_CHECKBUTTON, nID, MAKELPARAM(bCheck, 0)); + } + + BOOL PressButton(int nID, BOOL bPress = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_PRESSBUTTON, nID, MAKELPARAM(bPress, 0)); + } + + BOOL HideButton(int nID, BOOL bHide = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_HIDEBUTTON, nID, MAKELPARAM(bHide, 0)); + } + + BOOL Indeterminate(int nID, BOOL bIndeterminate = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_INDETERMINATE, nID, MAKELPARAM(bIndeterminate, 0)); + } + + int AddBitmap(int nNumButtons, UINT nBitmapID) + { + ATLASSERT(::IsWindow(m_hWnd)); + TBADDBITMAP tbab = { 0 }; + tbab.hInst = ModuleHelper::GetResourceInstance(); + ATLASSERT(tbab.hInst != NULL); + tbab.nID = nBitmapID; + return (int)::SendMessage(m_hWnd, TB_ADDBITMAP, (WPARAM)nNumButtons, (LPARAM)&tbab); + } + + int AddBitmap(int nNumButtons, HBITMAP hBitmap) + { + ATLASSERT(::IsWindow(m_hWnd)); + TBADDBITMAP tbab = { 0 }; + tbab.hInst = NULL; + tbab.nID = (UINT_PTR)hBitmap; + return (int)::SendMessage(m_hWnd, TB_ADDBITMAP, (WPARAM)nNumButtons, (LPARAM)&tbab); + } + + BOOL AddButtons(int nNumButtons, LPTBBUTTON lpButtons) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_ADDBUTTONS, nNumButtons, (LPARAM)lpButtons); + } + + BOOL InsertButton(int nIndex, LPTBBUTTON lpButton) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_INSERTBUTTON, nIndex, (LPARAM)lpButton); + } + + BOOL InsertButton(int nIndex, int iCommand, BYTE Style, BYTE State, int iBitmap, + INT_PTR iString, DWORD_PTR lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + TBBUTTON tbb = { 0 }; + tbb.fsStyle = Style; + tbb.fsState = State; + tbb.idCommand = iCommand; + tbb.iBitmap = iBitmap; + tbb.iString = iString; + tbb.dwData = lParam; + return (BOOL)::SendMessage(m_hWnd, TB_INSERTBUTTON, nIndex, (LPARAM)&tbb); + } + + BOOL InsertButton(int nIndex, int iCommand, BYTE Style, BYTE State, int iBitmap, + LPCTSTR lpszItem, DWORD_PTR lParam) + { + return InsertButton(nIndex, iCommand, Style, State, iBitmap, (INT_PTR)lpszItem, lParam); + } + + BOOL AddButton(LPTBBUTTON lpButton) + { + return InsertButton(-1, lpButton); + } + + BOOL AddButton(int iCommand, BYTE Style, BYTE State, int iBitmap, INT_PTR iString, DWORD_PTR lParam) + { + return InsertButton(-1, iCommand, Style, State, iBitmap, iString, lParam); + } + + BOOL AddButton(int iCommand, BYTE Style, BYTE State, int iBitmap, LPCTSTR lpszItem, DWORD_PTR lParam) + { + return InsertButton(-1, iCommand, Style, State, iBitmap, lpszItem, lParam); + } + + BOOL DeleteButton(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_DELETEBUTTON, nIndex, 0L); + } + + UINT CommandToIndex(UINT nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, TB_COMMANDTOINDEX, nID, 0L); + } + +#ifndef _WIN32_WCE + void SaveState(HKEY hKeyRoot, LPCTSTR lpszSubKey, LPCTSTR lpszValueName) + { + ATLASSERT(::IsWindow(m_hWnd)); + TBSAVEPARAMS tbs = { 0 }; + tbs.hkr = hKeyRoot; + tbs.pszSubKey = lpszSubKey; + tbs.pszValueName = lpszValueName; + ::SendMessage(m_hWnd, TB_SAVERESTORE, (WPARAM)TRUE, (LPARAM)&tbs); + } + + void RestoreState(HKEY hKeyRoot, LPCTSTR lpszSubKey, LPCTSTR lpszValueName) + { + ATLASSERT(::IsWindow(m_hWnd)); + TBSAVEPARAMS tbs = { 0 }; + tbs.hkr = hKeyRoot; + tbs.pszSubKey = lpszSubKey; + tbs.pszValueName = lpszValueName; + ::SendMessage(m_hWnd, TB_SAVERESTORE, (WPARAM)FALSE, (LPARAM)&tbs); + } + + void Customize() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_CUSTOMIZE, 0, 0L); + } +#endif // !_WIN32_WCE + + int AddString(UINT nStringID) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_ADDSTRING, (WPARAM)ModuleHelper::GetResourceInstance(), (LPARAM)nStringID); + } + + int AddStrings(LPCTSTR lpszStrings) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_ADDSTRING, 0, (LPARAM)lpszStrings); + } + + void AutoSize() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TB_AUTOSIZE, 0, 0L); + } + + BOOL ChangeBitmap(int nID, int nBitmap) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_CHANGEBITMAP, nID, MAKELPARAM(nBitmap, 0)); + } + + int LoadImages(int nBitmapID) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_LOADIMAGES, nBitmapID, (LPARAM)ModuleHelper::GetResourceInstance()); + } + + int LoadStdImages(int nBitmapID) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_LOADIMAGES, nBitmapID, (LPARAM)HINST_COMMCTRL); + } + + BOOL ReplaceBitmap(LPTBREPLACEBITMAP ptbrb) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_REPLACEBITMAP, 0, (LPARAM)ptbrb); + } + +#if (_WIN32_IE >= 0x0400) + int HitTest(LPPOINT lpPoint) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TB_HITTEST, 0, (LPARAM)lpPoint); + } + +#ifndef _WIN32_WCE + BOOL InsertMarkHitTest(LPPOINT lpPoint, LPTBINSERTMARK lptbim) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_INSERTMARKHITTEST, (WPARAM)lpPoint, (LPARAM)lptbim); + } + + BOOL InsertMarkHitTest(int x, int y, LPTBINSERTMARK lptbim) const + { + ATLASSERT(::IsWindow(m_hWnd)); + POINT pt = { x, y }; + return (BOOL)::SendMessage(m_hWnd, TB_INSERTMARKHITTEST, (WPARAM)&pt, (LPARAM)lptbim); + } + + BOOL MapAccelerator(TCHAR chAccel, int& nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_MAPACCELERATOR, (WPARAM)chAccel, (LPARAM)&nID); + } + + BOOL MarkButton(int nID, BOOL bHighlight = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_MARKBUTTON, nID, MAKELPARAM(bHighlight, 0)); + } + + BOOL MoveButton(int nOldPos, int nNewPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TB_MOVEBUTTON, nOldPos, nNewPos); + } + + HRESULT GetObject(REFIID iid, LPVOID* ppvObject) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HRESULT)::SendMessage(m_hWnd, TB_GETOBJECT, (WPARAM)&iid, (LPARAM)ppvObject); + } +#endif // !_WIN32_WCE +#endif // (_WIN32_IE >= 0x0400) +}; + +typedef CToolBarCtrlT CToolBarCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CStatusBarCtrl + +template +class CStatusBarCtrlT : public TBase +{ +public: +// Constructors + CStatusBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CStatusBarCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Methods + static LPCTSTR GetWndClassName() + { + return STATUSCLASSNAME; + } + + int GetParts(int nParts, int* pParts) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, SB_GETPARTS, nParts, (LPARAM)pParts); + } + + BOOL SetParts(int nParts, int* pWidths) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, SB_SETPARTS, nParts, (LPARAM)pWidths); + } + + int GetTextLength(int nPane, int* pType = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, SB_GETTEXTLENGTH, (WPARAM)nPane, 0L); + if (pType != NULL) + *pType = (int)(short)HIWORD(dwRet); + return (int)(short)LOWORD(dwRet); + } + + int GetText(int nPane, LPTSTR lpszText, int* pType = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, SB_GETTEXT, (WPARAM)nPane, (LPARAM)lpszText); + if(pType != NULL) + *pType = (int)(short)HIWORD(dwRet); + return (int)(short)LOWORD(dwRet); + } + +#ifndef _ATL_NO_COM + BOOL GetTextBSTR(int nPane, BSTR& bstrText, int* pType = NULL) const + { + USES_CONVERSION; + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + ATLASSERT(bstrText == NULL); + int nLength = (int)(short)LOWORD(::SendMessage(m_hWnd, SB_GETTEXTLENGTH, (WPARAM)nPane, 0L)); + if(nLength == 0) + return FALSE; + + CTempBuffer buff; + LPTSTR lpstrText = buff.Allocate(nLength + 1); + if(lpstrText == NULL) + return FALSE; + + if(!GetText(nPane, lpstrText, pType)) + return FALSE; + + bstrText = ::SysAllocString(T2OLE(lpstrText)); + return (bstrText != NULL) ? TRUE : FALSE; + } +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + int GetText(int nPane, _CSTRING_NS::CString& strText, int* pType = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + int nLength = (int)(short)LOWORD(::SendMessage(m_hWnd, SB_GETTEXTLENGTH, (WPARAM)nPane, 0L)); + if(nLength == 0) + return 0; + + LPTSTR lpstr = strText.GetBufferSetLength(nLength); + if(lpstr == NULL) + return 0; + return GetText(nPane, lpstr, pType); + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + BOOL SetText(int nPane, LPCTSTR lpszText, int nType = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + return (BOOL)::SendMessage(m_hWnd, SB_SETTEXT, (nPane | nType), (LPARAM)lpszText); + } + + BOOL GetRect(int nPane, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + return (BOOL)::SendMessage(m_hWnd, SB_GETRECT, nPane, (LPARAM)lpRect); + } + + BOOL GetBorders(int* pBorders) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, SB_GETBORDERS, 0, (LPARAM)pBorders); + } + + BOOL GetBorders(int& nHorz, int& nVert, int& nSpacing) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int borders[3] = { 0, 0, 0 }; + BOOL bResult = (BOOL)::SendMessage(m_hWnd, SB_GETBORDERS, 0, (LPARAM)&borders); + if(bResult) + { + nHorz = borders[0]; + nVert = borders[1]; + nSpacing = borders[2]; + } + return bResult; + } + + void SetMinHeight(int nMin) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, SB_SETMINHEIGHT, nMin, 0L); + } + + BOOL SetSimple(BOOL bSimple = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, SB_SIMPLE, bSimple, 0L); + } + + BOOL IsSimple() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, SB_ISSIMPLE, 0, 0L); + } + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, SB_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, SB_SETUNICODEFORMAT, bUnicode, 0L); + } + + void GetTipText(int nPane, LPTSTR lpstrText, int nSize) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + ::SendMessage(m_hWnd, SB_GETTIPTEXT, MAKEWPARAM(nPane, nSize), (LPARAM)lpstrText); + } + + void SetTipText(int nPane, LPCTSTR lpstrText) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + ::SendMessage(m_hWnd, SB_SETTIPTEXT, nPane, (LPARAM)lpstrText); + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +#if ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500)) + COLORREF SetBkColor(COLORREF clrBk) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, SB_SETBKCOLOR, 0, (LPARAM)clrBk); + } + + HICON GetIcon(int nPane) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + return (HICON)::SendMessage(m_hWnd, SB_GETICON, nPane, 0L); + } + + BOOL SetIcon(int nPane, HICON hIcon) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPane < 256); + return (BOOL)::SendMessage(m_hWnd, SB_SETICON, nPane, (LPARAM)hIcon); + } +#endif // ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500)) +}; + +typedef CStatusBarCtrlT CStatusBarCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CTabCtrl + +template +class CTabCtrlT : public TBase +{ +public: +// Constructors + CTabCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CTabCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_TABCONTROL; + } + + CImageList GetImageList() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TCM_GETIMAGELIST, 0, 0L)); + } + + CImageList SetImageList(HIMAGELIST hImageList) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, TCM_SETIMAGELIST, 0, (LPARAM)hImageList)); + } + + int GetItemCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TCM_GETITEMCOUNT, 0, 0L); + } + + BOOL GetItem(int nItem, LPTCITEM pTabCtrlItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TCM_GETITEM, nItem, (LPARAM)pTabCtrlItem); + } + + BOOL SetItem(int nItem, LPTCITEM pTabCtrlItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TCM_SETITEM, nItem, (LPARAM)pTabCtrlItem); + } + + int SetItem(int nItem, UINT mask, LPCTSTR lpszItem, DWORD dwState, DWORD dwStateMask, int iImage, LPARAM lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + TCITEM tci = { 0 }; + tci.mask = mask; + tci.pszText = (LPTSTR) lpszItem; + tci.dwState = dwState; + tci.dwStateMask = dwStateMask; + tci.iImage = iImage; + tci.lParam = lParam; + return (int)::SendMessage(m_hWnd, TCM_SETITEM, nItem, (LPARAM)&tci); + } + + BOOL GetItemRect(int nItem, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TCM_GETITEMRECT, nItem, (LPARAM)lpRect); + } + + int GetCurSel() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TCM_GETCURSEL, 0, 0L); + } + + int SetCurSel(int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TCM_SETCURSEL, nItem, 0L); + } + + SIZE SetItemSize(SIZE size) + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwSize = (DWORD)::SendMessage(m_hWnd, TCM_SETITEMSIZE, 0, MAKELPARAM(size.cx, size.cy)); + SIZE sizeRet = { GET_X_LPARAM(dwSize), GET_Y_LPARAM(dwSize) }; + return sizeRet; + } + + void SetItemSize(int cx, int cy) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TCM_SETITEMSIZE, 0, MAKELPARAM(cx, cy)); + } + + void SetPadding(SIZE size) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TCM_SETPADDING, 0, MAKELPARAM(size.cx, size.cy)); + } + + int GetRowCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TCM_GETROWCOUNT, 0, 0L); + } + +#ifndef _WIN32_WCE + CToolTipCtrl GetTooltips() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TCM_GETTOOLTIPS, 0, 0L)); + } + + void SetTooltips(HWND hWndToolTip) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TCM_SETTOOLTIPS, (WPARAM)hWndToolTip, 0L); + } +#endif // !_WIN32_WCE + + int GetCurFocus() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TCM_GETCURFOCUS, 0, 0L); + } + + void SetCurFocus(int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TCM_SETCURFOCUS, nItem, 0L); + } + + BOOL SetItemExtra(int cbExtra) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetItemCount() == 0); // must be empty + return (BOOL)::SendMessage(m_hWnd, TCM_SETITEMEXTRA, cbExtra, 0L); + } + + int SetMinTabWidth(int nWidth = -1) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TCM_SETMINTABWIDTH, 0, nWidth); + } + +#if (_WIN32_IE >= 0x0400) + DWORD GetExtendedStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TCM_GETEXTENDEDSTYLE, 0, 0L); + } + + DWORD SetExtendedStyle(DWORD dwExMask, DWORD dwExStyle) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, TCM_SETEXTENDEDSTYLE, dwExMask, dwExStyle); + } + +#ifndef _WIN32_WCE + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TCM_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TCM_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // !_WIN32_WCE +#endif // (_WIN32_IE >= 0x0400) + +// Operations + int InsertItem(int nItem, LPTCITEM pTabCtrlItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TCM_INSERTITEM, nItem, (LPARAM)pTabCtrlItem); + } + + int InsertItem(int nItem, UINT mask, LPCTSTR lpszItem, int iImage, LPARAM lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + TCITEM tci = { 0 }; + tci.mask = mask; + tci.pszText = (LPTSTR) lpszItem; + tci.iImage = iImage; + tci.lParam = lParam; + return (int)::SendMessage(m_hWnd, TCM_INSERTITEM, nItem, (LPARAM)&tci); + } + + int InsertItem(int nItem, LPCTSTR lpszItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + TCITEM tci = { 0 }; + tci.mask = TCIF_TEXT; + tci.pszText = (LPTSTR) lpszItem; + return (int)::SendMessage(m_hWnd, TCM_INSERTITEM, nItem, (LPARAM)&tci); + } + + int AddItem(LPTCITEM pTabCtrlItem) + { + return InsertItem(GetItemCount(), pTabCtrlItem); + } + + int AddItem(UINT mask, LPCTSTR lpszItem, int iImage, LPARAM lParam) + { + return InsertItem(GetItemCount(), mask, lpszItem, iImage, lParam); + } + + int AddItem(LPCTSTR lpszItem) + { + return InsertItem(GetItemCount(), lpszItem); + } + + BOOL DeleteItem(int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TCM_DELETEITEM, nItem, 0L); + } + + BOOL DeleteAllItems() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TCM_DELETEALLITEMS, 0, 0L); + } + + void AdjustRect(BOOL bLarger, LPRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TCM_ADJUSTRECT, bLarger, (LPARAM)lpRect); + } + + void RemoveImage(int nImage) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TCM_REMOVEIMAGE, nImage, 0L); + } + + int HitTest(TC_HITTESTINFO* pHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TCM_HITTEST, 0, (LPARAM)pHitTestInfo); + } + + void DeselectAll(BOOL bExcludeFocus = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TCM_DESELECTALL, bExcludeFocus, 0L); + } + +#if (_WIN32_IE >= 0x0400) + BOOL HighlightItem(int nIndex, BOOL bHighlight = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TCM_HIGHLIGHTITEM, nIndex, MAKELPARAM(bHighlight, 0)); + } +#endif // (_WIN32_IE >= 0x0400) +}; + +typedef CTabCtrlT CTabCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CTrackBarCtrl + +template +class CTrackBarCtrlT : public TBase +{ +public: +// Constructors + CTrackBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CTrackBarCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return TRACKBAR_CLASS; + } + + int GetLineSize() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETLINESIZE, 0, 0L); + } + + int SetLineSize(int nSize) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_SETLINESIZE, 0, nSize); + } + + int GetPageSize() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETPAGESIZE, 0, 0L); + } + + int SetPageSize(int nSize) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_SETPAGESIZE, 0, nSize); + } + + int GetRangeMin() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETRANGEMIN, 0, 0L); + } + + void SetRangeMin(int nMin, BOOL bRedraw = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETRANGEMIN, bRedraw, nMin); + } + + int GetRangeMax() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETRANGEMAX, 0, 0L); + } + + void SetRangeMax(int nMax, BOOL bRedraw = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETRANGEMAX, bRedraw, nMax); + } + + void GetRange(int& nMin, int& nMax) const + { + nMin = GetRangeMin(); + nMax = GetRangeMax(); + } + + void SetRange(int nMin, int nMax, BOOL bRedraw = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETRANGE, bRedraw, MAKELPARAM(nMin, nMax)); + } + + int GetSelStart() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETSELSTART, 0, 0L); + } + + void SetSelStart(int nMin) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETSELSTART, 0, (LPARAM)nMin); + } + + int GetSelEnd() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETSELEND, 0, 0L); + } + + void SetSelEnd(int nMax) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETSELEND, 0, (LPARAM)nMax); + } + + void GetSelection(int& nMin, int& nMax) const + { + nMin = GetSelStart(); + nMax = GetSelEnd(); + } + + void SetSelection(int nMin, int nMax) + { + SetSelStart(nMin); + SetSelEnd(nMax); + } + + void GetChannelRect(LPRECT lprc) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_GETCHANNELRECT, 0, (LPARAM)lprc); + } + + void GetThumbRect(LPRECT lprc) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_GETTHUMBRECT, 0, (LPARAM)lprc); + } + + int GetPos() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETPOS, 0, 0L); + } + + void SetPos(int nPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETPOS, TRUE, nPos); + } + + UINT GetNumTics() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, TBM_GETNUMTICS, 0, 0L); + } + + DWORD* GetTicArray() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD*)::SendMessage(m_hWnd, TBM_GETPTICS, 0, 0L); + } + + int GetTic(int nTic) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETTIC, nTic, 0L); + } + + BOOL SetTic(int nTic) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TBM_SETTIC, 0, nTic); + } + + int GetTicPos(int nTic) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETTICPOS, nTic, 0L); + } + + void SetTicFreq(int nFreq) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETTICFREQ, nFreq, 0L); + } + + int GetThumbLength() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_GETTHUMBLENGTH, 0, 0L); + } + + void SetThumbLength(int nLength) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETTHUMBLENGTH, nLength, 0L); + } + + void SetSel(int nStart, int nEnd, BOOL bRedraw = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & TBS_ENABLESELRANGE) != 0); + ::SendMessage(m_hWnd, TBM_SETSEL, bRedraw, MAKELPARAM(nStart, nEnd)); + } + + ATL::CWindow GetBuddy(BOOL bLeft = TRUE) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ATL::CWindow((HWND)::SendMessage(m_hWnd, TBM_GETBUDDY, bLeft, 0L)); + } + + ATL::CWindow SetBuddy(HWND hWndBuddy, BOOL bLeft = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ATL::CWindow((HWND)::SendMessage(m_hWnd, TBM_SETBUDDY, bLeft, (LPARAM)hWndBuddy)); + } + +#ifndef _WIN32_WCE + CToolTipCtrl GetToolTips() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CToolTipCtrl((HWND)::SendMessage(m_hWnd, TBM_GETTOOLTIPS, 0, 0L)); + } + + void SetToolTips(HWND hWndTT) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETTOOLTIPS, (WPARAM)hWndTT, 0L); + } + + int SetTipSide(int nSide) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, TBM_SETTIPSIDE, nSide, 0L); + } +#endif // !_WIN32_WCE + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TBM_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, TBM_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +// Operations + void ClearSel(BOOL bRedraw = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_CLEARSEL, bRedraw, 0L); + } + + void VerifyPos() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_SETPOS, FALSE, 0L); + } + + void ClearTics(BOOL bRedraw = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, TBM_CLEARTICS, bRedraw, 0L); + } +}; + +typedef CTrackBarCtrlT CTrackBarCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CUpDownCtrl + +template +class CUpDownCtrlT : public TBase +{ +public: +// Constructors + CUpDownCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CUpDownCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return UPDOWN_CLASS; + } + + UINT GetAccel(int nAccel, UDACCEL* pAccel) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)LOWORD(::SendMessage(m_hWnd, UDM_GETACCEL, nAccel, (LPARAM)pAccel)); + } + + BOOL SetAccel(int nAccel, UDACCEL* pAccel) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)LOWORD(::SendMessage(m_hWnd, UDM_SETACCEL, nAccel, (LPARAM)pAccel)); + } + + UINT GetBase() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)LOWORD(::SendMessage(m_hWnd, UDM_GETBASE, 0, 0L)); + } + + int SetBase(int nBase) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, UDM_SETBASE, nBase, 0L); + } + + ATL::CWindow GetBuddy() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ATL::CWindow((HWND)::SendMessage(m_hWnd, UDM_GETBUDDY, 0, 0L)); + } + + ATL::CWindow SetBuddy(HWND hWndBuddy) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ATL::CWindow((HWND)::SendMessage(m_hWnd, UDM_SETBUDDY, (WPARAM)hWndBuddy, 0L)); + } + + int GetPos(LPBOOL lpbError = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, UDM_GETPOS, 0, 0L); + // Note: Seems that Windows always sets error to TRUE if + // UDS_SETBUDDYINT style is not used + if(lpbError != NULL) + *lpbError = (HIWORD(dwRet) != 0) ? TRUE : FALSE; + return (int)(short)LOWORD(dwRet); + } + + int SetPos(int nPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)(short)LOWORD(::SendMessage(m_hWnd, UDM_SETPOS, 0, MAKELPARAM(nPos, 0))); + } + + DWORD GetRange() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, UDM_GETRANGE, 0, 0L); + } + + void GetRange(int& nLower, int& nUpper) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, UDM_GETRANGE, 0, 0L); + nLower = (int)(short)HIWORD(dwRet); + nUpper = (int)(short)LOWORD(dwRet); + } + + void SetRange(int nLower, int nUpper) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, UDM_SETRANGE, 0, MAKELPARAM(nUpper, nLower)); + } + +#if (_WIN32_IE >= 0x0400) + void SetRange32(int nLower, int nUpper) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, UDM_SETRANGE32, nLower, nUpper); + } + + void GetRange32(int& nLower, int& nUpper) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, UDM_GETRANGE32, (WPARAM)&nLower, (LPARAM)&nUpper); + } + +#ifndef _WIN32_WCE + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, UDM_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, UDM_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // !_WIN32_WCE +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + int GetPos32(LPBOOL lpbError = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + // Note: Seems that Windows always sets error to TRUE if + // UDS_SETBUDDYINT style is not used + return (int)::SendMessage(m_hWnd, UDM_GETPOS32, 0, (LPARAM)lpbError); + } + + int SetPos32(int nPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, UDM_SETPOS32, 0, (LPARAM)nPos); + } +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) +}; + +typedef CUpDownCtrlT CUpDownCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CProgressBarCtrl + +template +class CProgressBarCtrlT : public TBase +{ +public: +// Constructors + CProgressBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CProgressBarCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return PROGRESS_CLASS; + } + + DWORD SetRange(int nLower, int nUpper) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, PBM_SETRANGE, 0, MAKELPARAM(nLower, nUpper)); + } + + int SetPos(int nPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)(short)LOWORD(::SendMessage(m_hWnd, PBM_SETPOS, nPos, 0L)); + } + + int OffsetPos(int nPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)(short)LOWORD(::SendMessage(m_hWnd, PBM_DELTAPOS, nPos, 0L)); + } + + int SetStep(int nStep) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)(short)LOWORD(::SendMessage(m_hWnd, PBM_SETSTEP, nStep, 0L)); + } + + UINT GetPos() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, PBM_GETPOS, 0, 0L); + } + + void GetRange(PPBRANGE pPBRange) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pPBRange != NULL); + ::SendMessage(m_hWnd, PBM_GETRANGE, TRUE, (LPARAM)pPBRange); + } + + void GetRange(int& nLower, int& nUpper) const + { + ATLASSERT(::IsWindow(m_hWnd)); + PBRANGE range = { 0 }; + ::SendMessage(m_hWnd, PBM_GETRANGE, TRUE, (LPARAM)&range); + nLower = range.iLow; + nUpper = range.iHigh; + } + + int GetRangeLimit(BOOL bLowLimit) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PBM_GETRANGE, bLowLimit, (LPARAM)NULL); + } + + DWORD SetRange32(int nMin, int nMax) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, PBM_SETRANGE32, nMin, nMax); + } + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + COLORREF SetBarColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, PBM_SETBARCOLOR, 0, (LPARAM)clr); + } + + COLORREF SetBkColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, PBM_SETBKCOLOR, 0, (LPARAM)clr); + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +#if (_WIN32_WINNT >= 0x0501) && defined(PBM_SETMARQUEE) + BOOL SetMarquee(BOOL bMarquee, UINT uUpdateTime = 0U) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, PBM_SETMARQUEE, (WPARAM)bMarquee, (LPARAM)uUpdateTime); + } +#endif // (_WIN32_WINNT >= 0x0501) && defined(PBM_SETMARQUEE) + +#if (_WIN32_WINNT >= 0x0600) + int GetStep() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PBM_GETSTEP, 0, 0L); + } + + COLORREF GetBkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, PBM_GETBKCOLOR, 0, 0L); + } + + COLORREF GetBarColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, PBM_GETBARCOLOR, 0, 0L); + } + + int GetState() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PBM_GETSTATE, 0, 0L); + } + + int SetState(int nState) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PBM_SETSTATE, nState, 0L); + } +#endif // (_WIN32_WINNT >= 0x0600) + +// Operations + int StepIt() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)(short)LOWORD(::SendMessage(m_hWnd, PBM_STEPIT, 0, 0L)); + } +}; + +typedef CProgressBarCtrlT CProgressBarCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CHotKeyCtrl + +#ifndef _WIN32_WCE + +template +class CHotKeyCtrlT : public TBase +{ +public: +// Constructors + CHotKeyCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CHotKeyCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return HOTKEY_CLASS; + } + + DWORD GetHotKey() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, HKM_GETHOTKEY, 0, 0L); + } + + void GetHotKey(WORD &wVirtualKeyCode, WORD &wModifiers) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dw = (DWORD)::SendMessage(m_hWnd, HKM_GETHOTKEY, 0, 0L); + wVirtualKeyCode = LOBYTE(LOWORD(dw)); + wModifiers = HIBYTE(LOWORD(dw)); + } + + void SetHotKey(WORD wVirtualKeyCode, WORD wModifiers) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, HKM_SETHOTKEY, MAKEWORD(wVirtualKeyCode, wModifiers), 0L); + } + + void SetRules(WORD wInvalidComb, WORD wModifiers) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, HKM_SETRULES, wInvalidComb, MAKELPARAM(wModifiers, 0)); + } +}; + +typedef CHotKeyCtrlT CHotKeyCtrl; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CAnimateCtrl + +#ifndef _WIN32_WCE + +template +class CAnimateCtrlT : public TBase +{ +public: +// Constructors + CAnimateCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CAnimateCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return ANIMATE_CLASS; + } + +// Operations + BOOL Open(ATL::_U_STRINGorID FileName) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, ACM_OPEN, 0, (LPARAM)FileName.m_lpstr); + } + + BOOL Play(UINT nFrom, UINT nTo, UINT nRep) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, ACM_PLAY, nRep, MAKELPARAM(nFrom, nTo)); + } + + BOOL Stop() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, ACM_STOP, 0, 0L); + } + + BOOL Close() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, ACM_OPEN, 0, 0L); + } + + BOOL Seek(UINT nTo) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, ACM_PLAY, 0, MAKELPARAM(nTo, nTo)); + } + + // Vista only + BOOL IsPlaying() const + { +#ifndef ACM_ISPLAYING + const UINT ACM_ISPLAYING = (WM_USER+104); +#endif + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, ACM_ISPLAYING, 0, 0L); + } +}; + +typedef CAnimateCtrlT CAnimateCtrl; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CRichEditCtrl + +#ifndef _WIN32_WCE + +#ifdef _UNICODE +#if (_RICHEDIT_VER == 0x0100) +#undef RICHEDIT_CLASS +#define RICHEDIT_CLASS L"RICHEDIT" +#endif // (_RICHEDIT_VER == 0x0100) +#endif // _UNICODE + +template +class CRichEditCtrlT : public TBase +{ +public: +// Constructors + CRichEditCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CRichEditCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return RICHEDIT_CLASS; + } + + static LPCTSTR GetLibraryName() + { +#if (_RICHEDIT_VER >= 0x0200) + return _T("RICHED20.DLL"); +#else + return _T("RICHED32.DLL"); +#endif + } + + int GetLineCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETLINECOUNT, 0, 0L); + } + + BOOL GetModify() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_GETMODIFY, 0, 0L); + } + + void SetModify(BOOL bModified = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETMODIFY, bModified, 0L); + } + + void GetRect(LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_GETRECT, 0, (LPARAM)lpRect); + } + + DWORD GetOptions() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, EM_GETOPTIONS, 0, 0L); + } + + DWORD SetOptions(WORD wOperation, DWORD dwOptions) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, EM_SETOPTIONS, wOperation, dwOptions); + } + + // NOTE: first word in lpszBuffer must contain the size of the buffer! + int GetLine(int nIndex, LPTSTR lpszBuffer) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer); + } + + int GetLine(int nIndex, LPTSTR lpszBuffer, int nMaxLength) const + { + ATLASSERT(::IsWindow(m_hWnd)); + *(LPWORD)lpszBuffer = (WORD)nMaxLength; + return (int)::SendMessage(m_hWnd, EM_GETLINE, nIndex, (LPARAM)lpszBuffer); + } + + BOOL CanUndo() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_CANUNDO, 0, 0L); + } + + BOOL CanPaste(UINT nFormat = 0) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_CANPASTE, nFormat, 0L); + } + + void GetSel(LONG& nStartChar, LONG& nEndChar) const + { + ATLASSERT(::IsWindow(m_hWnd)); + CHARRANGE cr = { 0, 0 }; + ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr); + nStartChar = cr.cpMin; + nEndChar = cr.cpMax; + } + + void GetSel(CHARRANGE &cr) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr); + } + + int SetSel(LONG nStartChar, LONG nEndChar) + { + ATLASSERT(::IsWindow(m_hWnd)); + CHARRANGE cr = { nStartChar, nEndChar }; + return (int)::SendMessage(m_hWnd, EM_EXSETSEL, 0, (LPARAM)&cr); + } + + int SetSel(CHARRANGE &cr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_EXSETSEL, 0, (LPARAM)&cr); + } + + int SetSelAll() + { + return SetSel(0, -1); + } + + int SetSelNone() + { + return SetSel(-1, 0); + } + + DWORD GetDefaultCharFormat(CHARFORMAT& cf) const + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT); + return (DWORD)::SendMessage(m_hWnd, EM_GETCHARFORMAT, 0, (LPARAM)&cf); + } + + DWORD GetSelectionCharFormat(CHARFORMAT& cf) const + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT); + return (DWORD)::SendMessage(m_hWnd, EM_GETCHARFORMAT, 1, (LPARAM)&cf); + } + + DWORD GetEventMask() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, EM_GETEVENTMASK, 0, 0L); + } + + LONG GetLimitText() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LONG)::SendMessage(m_hWnd, EM_GETLIMITTEXT, 0, 0L); + } + + DWORD GetParaFormat(PARAFORMAT& pf) const + { + ATLASSERT(::IsWindow(m_hWnd)); + pf.cbSize = sizeof(PARAFORMAT); + return (DWORD)::SendMessage(m_hWnd, EM_GETPARAFORMAT, 0, (LPARAM)&pf); + } + +#if (_RICHEDIT_VER >= 0x0200) + LONG GetSelText(LPTSTR lpstrBuff) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LONG)::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrBuff); + } +#else // !(_RICHEDIT_VER >= 0x0200) + // RichEdit 1.0 EM_GETSELTEXT is ANSI only + LONG GetSelText(LPSTR lpstrBuff) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LONG)::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrBuff); + } +#endif // !(_RICHEDIT_VER >= 0x0200) + +#ifndef _ATL_NO_COM + BOOL GetSelTextBSTR(BSTR& bstrText) const + { + USES_CONVERSION; + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(bstrText == NULL); + + CHARRANGE cr = { 0, 0 }; + ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr); + +#if (_RICHEDIT_VER >= 0x0200) + CTempBuffer buff; + LPTSTR lpstrText = buff.Allocate(cr.cpMax - cr.cpMin + 1); + if(lpstrText == NULL) + return FALSE; + if(::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrText) == 0) + return FALSE; + + bstrText = ::SysAllocString(T2W(lpstrText)); +#else // !(_RICHEDIT_VER >= 0x0200) + CTempBuffer buff; + LPSTR lpstrText = buff.Allocate(cr.cpMax - cr.cpMin + 1); + if(lpstrText == NULL) + return FALSE; + if(::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrText) == 0) + return FALSE; + + bstrText = ::SysAllocString(A2W(lpstrText)); +#endif // !(_RICHEDIT_VER >= 0x0200) + + return (bstrText != NULL) ? TRUE : FALSE; + } +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + LONG GetSelText(_CSTRING_NS::CString& strText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + + CHARRANGE cr = { 0, 0 }; + ::SendMessage(m_hWnd, EM_EXGETSEL, 0, (LPARAM)&cr); + +#if (_RICHEDIT_VER >= 0x0200) + LONG lLen = 0; + LPTSTR lpstrText = strText.GetBufferSetLength(cr.cpMax - cr.cpMin); + if(lpstrText != NULL) + { + lLen = (LONG)::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrText); + strText.ReleaseBuffer(); + } +#else // !(_RICHEDIT_VER >= 0x0200) + CTempBuffer buff; + LPSTR lpstrText = buff.Allocate(cr.cpMax - cr.cpMin + 1); + if(lpstrText == NULL) + return 0; + LONG lLen = (LONG)::SendMessage(m_hWnd, EM_GETSELTEXT, 0, (LPARAM)lpstrText); + if(lLen == 0) + return 0; + + USES_CONVERSION; + strText = A2T(lpstrText); +#endif // !(_RICHEDIT_VER >= 0x0200) + + return lLen; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + WORD GetSelectionType() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (WORD)::SendMessage(m_hWnd, EM_SELECTIONTYPE, 0, 0L); + } + + COLORREF SetBackgroundColor(COLORREF cr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, EM_SETBKGNDCOLOR, 0, cr); + } + + COLORREF SetBackgroundColor() // sets to system background + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, EM_SETBKGNDCOLOR, 1, 0); + } + + BOOL SetCharFormat(CHARFORMAT& cf, WORD wFlags) + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT); + return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, (WPARAM)wFlags, (LPARAM)&cf); + } + + BOOL SetDefaultCharFormat(CHARFORMAT& cf) + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT); + return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, 0, (LPARAM)&cf); + } + + BOOL SetSelectionCharFormat(CHARFORMAT& cf) + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT); + return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + } + + BOOL SetWordCharFormat(CHARFORMAT& cf) + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT); + return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_SELECTION | SCF_WORD, (LPARAM)&cf); + } + + DWORD SetEventMask(DWORD dwEventMask) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, EM_SETEVENTMASK, 0, dwEventMask); + } + + BOOL SetParaFormat(PARAFORMAT& pf) + { + ATLASSERT(::IsWindow(m_hWnd)); + pf.cbSize = sizeof(PARAFORMAT); + return (BOOL)::SendMessage(m_hWnd, EM_SETPARAFORMAT, 0, (LPARAM)&pf); + } + + BOOL SetTargetDevice(HDC hDC, int cxLineWidth) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETTARGETDEVICE, (WPARAM)hDC, cxLineWidth); + } + + int GetTextLength() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, WM_GETTEXTLENGTH, 0, 0L); + } + + BOOL SetReadOnly(BOOL bReadOnly = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETREADONLY, bReadOnly, 0L); + } + + int GetFirstVisibleLine() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETFIRSTVISIBLELINE, 0, 0L); + } + + EDITWORDBREAKPROCEX GetWordBreakProcEx() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (EDITWORDBREAKPROCEX)::SendMessage(m_hWnd, EM_GETWORDBREAKPROCEX, 0, 0L); + } + + EDITWORDBREAKPROCEX SetWordBreakProcEx(EDITWORDBREAKPROCEX pfnEditWordBreakProcEx) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (EDITWORDBREAKPROCEX)::SendMessage(m_hWnd, EM_SETWORDBREAKPROCEX, 0, (LPARAM)pfnEditWordBreakProcEx); + } + + int GetTextRange(TEXTRANGE* pTextRange) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETTEXTRANGE, 0, (LPARAM)pTextRange); + } + +#if (_RICHEDIT_VER >= 0x0200) + int GetTextRange(LONG nStartChar, LONG nEndChar, LPTSTR lpstrText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TEXTRANGE tr = { 0 }; + tr.chrg.cpMin = nStartChar; + tr.chrg.cpMax = nEndChar; + tr.lpstrText = lpstrText; + return (int)::SendMessage(m_hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr); + } +#else // !(_RICHEDIT_VER >= 0x0200) + + int GetTextRange(LONG nStartChar, LONG nEndChar, LPSTR lpstrText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + TEXTRANGE tr = { 0 }; + tr.chrg.cpMin = nStartChar; + tr.chrg.cpMax = nEndChar; + tr.lpstrText = lpstrText; + return (int)::SendMessage(m_hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr); + } +#endif // !(_RICHEDIT_VER >= 0x0200) + +#if (_RICHEDIT_VER >= 0x0200) + DWORD GetDefaultCharFormat(CHARFORMAT2& cf) const + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT2); + return (DWORD)::SendMessage(m_hWnd, EM_GETCHARFORMAT, 0, (LPARAM)&cf); + } + + BOOL SetCharFormat(CHARFORMAT2& cf, WORD wFlags) + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT2); + return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, (WPARAM)wFlags, (LPARAM)&cf); + } + + BOOL SetDefaultCharFormat(CHARFORMAT2& cf) + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT2); + return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, 0, (LPARAM)&cf); + } + + DWORD GetSelectionCharFormat(CHARFORMAT2& cf) const + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT2); + return (DWORD)::SendMessage(m_hWnd, EM_GETCHARFORMAT, 1, (LPARAM)&cf); + } + + BOOL SetSelectionCharFormat(CHARFORMAT2& cf) + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT2); + return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + } + + BOOL SetWordCharFormat(CHARFORMAT2& cf) + { + ATLASSERT(::IsWindow(m_hWnd)); + cf.cbSize = sizeof(CHARFORMAT2); + return (BOOL)::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_SELECTION | SCF_WORD, (LPARAM)&cf); + } + + DWORD GetParaFormat(PARAFORMAT2& pf) const + { + ATLASSERT(::IsWindow(m_hWnd)); + pf.cbSize = sizeof(PARAFORMAT2); + return (DWORD)::SendMessage(m_hWnd, EM_GETPARAFORMAT, 0, (LPARAM)&pf); + } + + BOOL SetParaFormat(PARAFORMAT2& pf) + { + ATLASSERT(::IsWindow(m_hWnd)); + pf.cbSize = sizeof(PARAFORMAT2); + return (BOOL)::SendMessage(m_hWnd, EM_SETPARAFORMAT, 0, (LPARAM)&pf); + } + + TEXTMODE GetTextMode() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (TEXTMODE)::SendMessage(m_hWnd, EM_GETTEXTMODE, 0, 0L); + } + + BOOL SetTextMode(TEXTMODE enumTextMode) + { + ATLASSERT(::IsWindow(m_hWnd)); + return !(BOOL)::SendMessage(m_hWnd, EM_SETTEXTMODE, enumTextMode, 0L); + } + + UNDONAMEID GetUndoName() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UNDONAMEID)::SendMessage(m_hWnd, EM_GETUNDONAME, 0, 0L); + } + + UNDONAMEID GetRedoName() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UNDONAMEID)::SendMessage(m_hWnd, EM_GETREDONAME, 0, 0L); + } + + BOOL CanRedo() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_CANREDO, 0, 0L); + } + + BOOL GetAutoURLDetect() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_GETAUTOURLDETECT, 0, 0L); + } + + BOOL SetAutoURLDetect(BOOL bAutoDetect = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return !(BOOL)::SendMessage(m_hWnd, EM_AUTOURLDETECT, bAutoDetect, 0L); + } + + // this method is deprecated, please use SetAutoURLDetect + BOOL EnableAutoURLDetect(BOOL bEnable = TRUE) { return SetAutoURLDetect(bEnable); } + + UINT SetUndoLimit(UINT uUndoLimit) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, EM_SETUNDOLIMIT, uUndoLimit, 0L); + } + + void SetPalette(HPALETTE hPalette) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETPALETTE, (WPARAM)hPalette, 0L); + } + + int GetTextEx(GETTEXTEX* pGetTextEx, LPTSTR lpstrText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETTEXTEX, (WPARAM)pGetTextEx, (LPARAM)lpstrText); + } + + int GetTextEx(LPTSTR lpstrText, int nTextLen, DWORD dwFlags = GT_DEFAULT, UINT uCodePage = CP_ACP, LPCSTR lpDefaultChar = NULL, LPBOOL lpUsedDefChar = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + GETTEXTEX gte = { 0 }; + gte.cb = nTextLen * sizeof(TCHAR); + gte.codepage = uCodePage; + gte.flags = dwFlags; + gte.lpDefaultChar = lpDefaultChar; + gte.lpUsedDefChar = lpUsedDefChar; + return (int)::SendMessage(m_hWnd, EM_GETTEXTEX, (WPARAM)>e, (LPARAM)lpstrText); + } + + int GetTextLengthEx(GETTEXTLENGTHEX* pGetTextLengthEx) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETTEXTLENGTHEX, (WPARAM)pGetTextLengthEx, 0L); + } + + int GetTextLengthEx(DWORD dwFlags = GTL_DEFAULT, UINT uCodePage = CP_ACP) const + { + ATLASSERT(::IsWindow(m_hWnd)); + GETTEXTLENGTHEX gtle = { 0 }; + gtle.codepage = uCodePage; + gtle.flags = dwFlags; + return (int)::SendMessage(m_hWnd, EM_GETTEXTLENGTHEX, (WPARAM)>le, 0L); + } +#endif // (_RICHEDIT_VER >= 0x0200) + +#if (_RICHEDIT_VER >= 0x0300) + int SetTextEx(SETTEXTEX* pSetTextEx, LPCTSTR lpstrText) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_SETTEXTEX, (WPARAM)pSetTextEx, (LPARAM)lpstrText); + } + + int SetTextEx(LPCTSTR lpstrText, DWORD dwFlags = ST_DEFAULT, UINT uCodePage = CP_ACP) + { + ATLASSERT(::IsWindow(m_hWnd)); + SETTEXTEX ste = { 0 }; + ste.flags = dwFlags; + ste.codepage = uCodePage; + return (int)::SendMessage(m_hWnd, EM_SETTEXTEX, (WPARAM)&ste, (LPARAM)lpstrText); + } + + int GetEditStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_GETEDITSTYLE, 0, 0L); + } + + int SetEditStyle(int nStyle, int nMask = -1) + { + ATLASSERT(::IsWindow(m_hWnd)); + if(nMask == -1) + nMask = nStyle; // set everything specified + return (int)::SendMessage(m_hWnd, EM_SETEDITSTYLE, nStyle, nMask); + } + + BOOL SetFontSize(int nFontSizeDelta) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nFontSizeDelta >= -1637 && nFontSizeDelta <= 1638); + return (BOOL)::SendMessage(m_hWnd, EM_SETFONTSIZE, nFontSizeDelta, 0L); + } + + void GetScrollPos(LPPOINT lpPoint) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpPoint != NULL); + ::SendMessage(m_hWnd, EM_GETSCROLLPOS, 0, (LPARAM)lpPoint); + } + + void SetScrollPos(LPPOINT lpPoint) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpPoint != NULL); + ::SendMessage(m_hWnd, EM_SETSCROLLPOS, 0, (LPARAM)lpPoint); + } + + BOOL GetZoom(int& nNum, int& nDen) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_GETZOOM, (WPARAM)&nNum, (LPARAM)&nDen); + } + + BOOL SetZoom(int nNum, int nDen) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nNum >= 0 && nNum <= 64); + ATLASSERT(nDen >= 0 && nDen <= 64); + return (BOOL)::SendMessage(m_hWnd, EM_SETZOOM, nNum, nDen); + } + + BOOL SetZoomOff() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETZOOM, 0, 0L); + } +#endif // (_RICHEDIT_VER >= 0x0300) + +// Operations + void LimitText(LONG nChars = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_EXLIMITTEXT, 0, nChars); + } + + int LineFromChar(LONG nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_EXLINEFROMCHAR, 0, nIndex); + } + + POINT PosFromChar(LONG nChar) const + { + ATLASSERT(::IsWindow(m_hWnd)); + POINT point = { 0, 0 }; + ::SendMessage(m_hWnd, EM_POSFROMCHAR, (WPARAM)&point, nChar); + return point; + } + + int CharFromPos(POINT pt) const + { + ATLASSERT(::IsWindow(m_hWnd)); + POINTL ptl = { pt.x, pt.y }; + return (int)::SendMessage(m_hWnd, EM_CHARFROMPOS, 0, (LPARAM)&ptl); + } + + void EmptyUndoBuffer() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_EMPTYUNDOBUFFER, 0, 0L); + } + + int LineIndex(int nLine = -1) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_LINEINDEX, nLine, 0L); + } + + int LineLength(int nLine = -1) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, EM_LINELENGTH, nLine, 0L); + } + + BOOL LineScroll(int nLines, int nChars = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_LINESCROLL, nChars, nLines); + } + + void ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_REPLACESEL, (WPARAM) bCanUndo, (LPARAM)lpszNewText); + } + + void SetRect(LPCRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETRECT, 0, (LPARAM)lpRect); + } + + BOOL DisplayBand(LPRECT pDisplayRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_DISPLAYBAND, 0, (LPARAM)pDisplayRect); + } + + LONG FindText(DWORD dwFlags, FINDTEXT& ft) const + { + ATLASSERT(::IsWindow(m_hWnd)); +#if (_RICHEDIT_VER >= 0x0200) && defined(_UNICODE) + return (LONG)::SendMessage(m_hWnd, EM_FINDTEXTW, dwFlags, (LPARAM)&ft); +#else + return (LONG)::SendMessage(m_hWnd, EM_FINDTEXT, dwFlags, (LPARAM)&ft); +#endif + } + + LONG FindText(DWORD dwFlags, FINDTEXTEX& ft) const + { + ATLASSERT(::IsWindow(m_hWnd)); +#if (_RICHEDIT_VER >= 0x0200) && defined(_UNICODE) + return (LONG)::SendMessage(m_hWnd, EM_FINDTEXTEXW, dwFlags, (LPARAM)&ft); +#else + return (LONG)::SendMessage(m_hWnd, EM_FINDTEXTEX, dwFlags, (LPARAM)&ft); +#endif + } + + LONG FormatRange(FORMATRANGE& fr, BOOL bDisplay = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LONG)::SendMessage(m_hWnd, EM_FORMATRANGE, bDisplay, (LPARAM)&fr); + } + + LONG FormatRange(FORMATRANGE* pFormatRange, BOOL bDisplay = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LONG)::SendMessage(m_hWnd, EM_FORMATRANGE, bDisplay, (LPARAM)pFormatRange); + } + + void HideSelection(BOOL bHide = TRUE, BOOL bChangeStyle = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_HIDESELECTION, bHide, bChangeStyle); + } + + void PasteSpecial(UINT uClipFormat, DWORD dwAspect = 0, HMETAFILE hMF = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + REPASTESPECIAL reps = { dwAspect, (DWORD_PTR)hMF }; + ::SendMessage(m_hWnd, EM_PASTESPECIAL, uClipFormat, (LPARAM)&reps); + } + + void RequestResize() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_REQUESTRESIZE, 0, 0L); + } + + LONG StreamIn(UINT uFormat, EDITSTREAM& es) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LONG)::SendMessage(m_hWnd, EM_STREAMIN, uFormat, (LPARAM)&es); + } + + LONG StreamOut(UINT uFormat, EDITSTREAM& es) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LONG)::SendMessage(m_hWnd, EM_STREAMOUT, uFormat, (LPARAM)&es); + } + + DWORD FindWordBreak(int nCode, LONG nStartChar) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, EM_FINDWORDBREAK, nCode, nStartChar); + } + + // Additional operations + void ScrollCaret() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SCROLLCARET, 0, 0L); + } + + int InsertText(long nInsertAfterChar, LPCTSTR lpstrText, BOOL bCanUndo = FALSE) + { + int nRet = SetSel(nInsertAfterChar, nInsertAfterChar); + ReplaceSel(lpstrText, bCanUndo); + return nRet; + } + + int AppendText(LPCTSTR lpstrText, BOOL bCanUndo = FALSE) + { + return InsertText(GetWindowTextLength(), lpstrText, bCanUndo); + } + + // Clipboard operations + BOOL Undo() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_UNDO, 0, 0L); + } + + void Clear() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_CLEAR, 0, 0L); + } + + void Copy() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_COPY, 0, 0L); + } + + void Cut() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_CUT, 0, 0L); + } + + void Paste() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_PASTE, 0, 0L); + } + + // OLE support + IRichEditOle* GetOleInterface() const + { + ATLASSERT(::IsWindow(m_hWnd)); + IRichEditOle *pRichEditOle = NULL; + ::SendMessage(m_hWnd, EM_GETOLEINTERFACE, 0, (LPARAM)&pRichEditOle); + return pRichEditOle; + } + + BOOL SetOleCallback(IRichEditOleCallback* pCallback) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETOLECALLBACK, 0, (LPARAM)pCallback); + } + +#if (_RICHEDIT_VER >= 0x0200) + BOOL Redo() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_REDO, 0, 0L); + } + + void StopGroupTyping() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_STOPGROUPTYPING, 0, 0L); + } + + void ShowScrollBar(int nBarType, BOOL bVisible = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SHOWSCROLLBAR, nBarType, bVisible); + } +#endif // (_RICHEDIT_VER >= 0x0200) + +#if (_RICHEDIT_VER >= 0x0300) + BOOL SetTabStops(int nTabStops, LPINT rgTabStops) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, nTabStops, (LPARAM)rgTabStops); + } + + BOOL SetTabStops() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 0, 0L); + } + + BOOL SetTabStops(const int& cxEachStop) // takes an 'int' + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_SETTABSTOPS, 1, (LPARAM)(LPINT)&cxEachStop); + } +#endif // (_RICHEDIT_VER >= 0x0300) +}; + +typedef CRichEditCtrlT CRichEditCtrl; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CRichEditCommands - message handlers for standard EDIT commands + +#ifndef _WIN32_WCE + +// Chain to CRichEditCommands message map. Your class must also derive from CRichEditCtrl. +// Example: +// class CMyRichEdit : public CWindowImpl, +// public CRichEditCommands +// { +// public: +// BEGIN_MSG_MAP(CMyRichEdit) +// // your handlers... +// CHAIN_MSG_MAP_ALT(CRichEditCommands, 1) +// END_MSG_MAP() +// // other stuff... +// }; + +template +class CRichEditCommands : public CEditCommands< T > +{ +public: + BEGIN_MSG_MAP(CRichEditCommands< T >) + ALT_MSG_MAP(1) + COMMAND_ID_HANDLER(ID_EDIT_CLEAR, CEditCommands< T >::OnEditClear) + COMMAND_ID_HANDLER(ID_EDIT_CLEAR_ALL, CEditCommands< T >::OnEditClearAll) + COMMAND_ID_HANDLER(ID_EDIT_COPY, CEditCommands< T >::OnEditCopy) + COMMAND_ID_HANDLER(ID_EDIT_CUT, CEditCommands< T >::OnEditCut) + COMMAND_ID_HANDLER(ID_EDIT_PASTE, CEditCommands< T >::OnEditPaste) + COMMAND_ID_HANDLER(ID_EDIT_SELECT_ALL, CEditCommands< T >::OnEditSelectAll) + COMMAND_ID_HANDLER(ID_EDIT_UNDO, CEditCommands< T >::OnEditUndo) +#if (_RICHEDIT_VER >= 0x0200) + COMMAND_ID_HANDLER(ID_EDIT_REDO, OnEditRedo) +#endif // (_RICHEDIT_VER >= 0x0200) + END_MSG_MAP() + +#if (_RICHEDIT_VER >= 0x0200) + LRESULT OnEditRedo(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->Redo(); + return 0; + } +#endif // (_RICHEDIT_VER >= 0x0200) + +// State (update UI) helpers + BOOL CanCut() const + { return HasSelection(); } + + BOOL CanCopy() const + { return HasSelection(); } + + BOOL CanClear() const + { return HasSelection(); } + +// Implementation + BOOL HasSelection() const + { + const T* pT = static_cast(this); + return (pT->GetSelectionType() != SEL_EMPTY); + } +}; + +#endif // _WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CDragListBox + +#ifndef _WIN32_WCE + +template +class CDragListBoxT : public CListBoxT< TBase > +{ +public: +// Constructors + CDragListBoxT(HWND hWnd = NULL) : CListBoxT< TBase >(hWnd) + { } + + CDragListBoxT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + HWND hWnd = TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + if(hWnd != NULL) + MakeDragList(); + return hWnd; + } + +// Operations + BOOL MakeDragList() + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) == 0); + return ::MakeDragList(m_hWnd); + } + + int LBItemFromPt(POINT pt, BOOL bAutoScroll = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::LBItemFromPt(m_hWnd, pt, bAutoScroll); + } + + void DrawInsert(int nItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::DrawInsert(GetParent(), m_hWnd, nItem); + } + + static UINT GetDragListMessage() + { + static UINT uDragListMessage = 0; + if(uDragListMessage == 0) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CDragListBox::GetDragListMessage.\n")); + ATLASSERT(FALSE); + return 0; + } + + if(uDragListMessage == 0) + uDragListMessage = ::RegisterWindowMessage(DRAGLISTMSGSTRING); + + lock.Unlock(); + } + ATLASSERT(uDragListMessage != 0); + return uDragListMessage; + } +}; + +typedef CDragListBoxT CDragListBox; + +template +class CDragListNotifyImpl +{ +public: + BEGIN_MSG_MAP(CDragListNotifyImpl< T >) + MESSAGE_HANDLER(CDragListBox::GetDragListMessage(), OnDragListNotify) + END_MSG_MAP() + + LRESULT OnDragListNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + uMsg; // avoid level 4 warning + ATLASSERT(uMsg == CDragListBox::GetDragListMessage()); + T* pT = static_cast(this); + LPDRAGLISTINFO lpDragListInfo = (LPDRAGLISTINFO)lParam; + LRESULT lRet = 0; + switch(lpDragListInfo->uNotification) + { + case DL_BEGINDRAG: + lRet = (LPARAM)pT->OnBeginDrag((int)wParam, lpDragListInfo->hWnd, lpDragListInfo->ptCursor); + break; + case DL_CANCELDRAG: + pT->OnCancelDrag((int)wParam, lpDragListInfo->hWnd, lpDragListInfo->ptCursor); + break; + case DL_DRAGGING: + lRet = (LPARAM)pT->OnDragging((int)wParam, lpDragListInfo->hWnd, lpDragListInfo->ptCursor); + break; + case DL_DROPPED: + pT->OnDropped((int)wParam, lpDragListInfo->hWnd, lpDragListInfo->ptCursor); + break; + default: + ATLTRACE2(atlTraceUI, 0, _T("Unknown DragListBox notification\n")); + bHandled = FALSE; // don't handle it + break; + } + return lRet; + } + +// Overrideables + BOOL OnBeginDrag(int /*nCtlID*/, HWND /*hWndDragList*/, POINT /*ptCursor*/) + { + return TRUE; // allow dragging + } + + void OnCancelDrag(int /*nCtlID*/, HWND /*hWndDragList*/, POINT /*ptCursor*/) + { + // nothing to do + } + + int OnDragging(int /*nCtlID*/, HWND /*hWndDragList*/, POINT /*ptCursor*/) + { + return 0; // don't change cursor + } + + void OnDropped(int /*nCtlID*/, HWND /*hWndDragList*/, POINT /*ptCursor*/) + { + // nothing to do + } +}; + +#endif // _WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CReBarCtrl + +template +class CReBarCtrlT : public TBase +{ +public: +// Constructors + CReBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CReBarCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return REBARCLASSNAME; + } + + UINT GetBandCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, RB_GETBANDCOUNT, 0, 0L); + } + + BOOL GetBandInfo(int nBand, LPREBARBANDINFO lprbbi) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_GETBANDINFO, nBand, (LPARAM)lprbbi); + } + + BOOL SetBandInfo(int nBand, LPREBARBANDINFO lprbbi) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_SETBANDINFO, nBand, (LPARAM)lprbbi); + } + + BOOL GetBarInfo(LPREBARINFO lprbi) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_GETBARINFO, 0, (LPARAM)lprbi); + } + + BOOL SetBarInfo(LPREBARINFO lprbi) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_SETBARINFO, 0, (LPARAM)lprbi); + } + + CImageList GetImageList() const + { + ATLASSERT(::IsWindow(m_hWnd)); + REBARINFO rbi = { 0 }; + rbi.cbSize = sizeof(REBARINFO); + rbi.fMask = RBIM_IMAGELIST; + if( (BOOL)::SendMessage(m_hWnd, RB_GETBARINFO, 0, (LPARAM)&rbi) == FALSE ) return CImageList(); + return CImageList(rbi.himl); + } + + BOOL SetImageList(HIMAGELIST hImageList) + { + ATLASSERT(::IsWindow(m_hWnd)); + REBARINFO rbi = { 0 }; + rbi.cbSize = sizeof(REBARINFO); + rbi.fMask = RBIM_IMAGELIST; + rbi.himl = hImageList; + return (BOOL)::SendMessage(m_hWnd, RB_SETBARINFO, 0, (LPARAM)&rbi); + } + + UINT GetRowCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, RB_GETROWCOUNT, 0, 0L); + } + + UINT GetRowHeight(int nBand) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, RB_GETROWHEIGHT, nBand, 0L); + } + +#if (_WIN32_IE >= 0x0400) + COLORREF GetTextColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, RB_GETTEXTCOLOR, 0, 0L); + } + + COLORREF SetTextColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, RB_SETTEXTCOLOR, 0, (LPARAM)clr); + } + + COLORREF GetBkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, RB_GETBKCOLOR, 0, 0L); + } + + COLORREF SetBkColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, RB_SETBKCOLOR, 0, (LPARAM)clr); + } + + UINT GetBarHeight() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, RB_GETBARHEIGHT, 0, 0L); + } + + BOOL GetRect(int nBand, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_GETRECT, nBand, (LPARAM)lpRect); + } + +#ifndef _WIN32_WCE + CToolTipCtrl GetToolTips() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CToolTipCtrl((HWND)::SendMessage(m_hWnd, RB_GETTOOLTIPS, 0, 0L)); + } + + void SetToolTips(HWND hwndToolTip) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_SETTOOLTIPS, (WPARAM)hwndToolTip, 0L); + } +#endif // !_WIN32_WCE + + void GetBandBorders(int nBand, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpRect != NULL); + ::SendMessage(m_hWnd, RB_GETBANDBORDERS, nBand, (LPARAM)lpRect); + } + +#ifndef _WIN32_WCE + BOOL GetColorScheme(LPCOLORSCHEME lpColorScheme) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpColorScheme != NULL); + return (BOOL)::SendMessage(m_hWnd, RB_GETCOLORSCHEME, 0, (LPARAM)lpColorScheme); + } + + void SetColorScheme(LPCOLORSCHEME lpColorScheme) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpColorScheme != NULL); + ::SendMessage(m_hWnd, RB_SETCOLORSCHEME, 0, (LPARAM)lpColorScheme); + } + + HPALETTE GetPalette() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HPALETTE)::SendMessage(m_hWnd, RB_GETPALETTE, 0, 0L); + } + + HPALETTE SetPalette(HPALETTE hPalette) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HPALETTE)::SendMessage(m_hWnd, RB_SETPALETTE, 0, (LPARAM)hPalette); + } + + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // !_WIN32_WCE +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_WINNT >= 0x0501) + // requires uxtheme.h to be included to use MARGINS struct +#ifndef _UXTHEME_H_ + typedef struct _MARGINS* PMARGINS; +#endif // !_UXTHEME_H_ + void GetBandMargins(PMARGINS pMargins) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_GETBANDMARGINS, 0, (LPARAM)pMargins); + } + + void SetWindowTheme(LPCWSTR lpstrTheme) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_SETWINDOWTHEME, 0, (LPARAM)lpstrTheme); + } +#endif // (_WIN32_WINNT >= 0x0501) + +#if (_WIN32_IE >= 0x0600) + DWORD GetExtendedStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, RB_GETEXTENDEDSTYLE, 0, 0L); + } + + DWORD SetExtendedStyle(DWORD dwStyle, DWORD dwMask) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, RB_SETEXTENDEDSTYLE, dwMask, dwStyle); + } +#endif // (_WIN32_IE >= 0x0600) + +// Operations + BOOL InsertBand(int nBand, LPREBARBANDINFO lprbbi) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_INSERTBAND, nBand, (LPARAM)lprbbi); + } + + BOOL AddBand(LPREBARBANDINFO lprbbi) + { + return InsertBand(-1, lprbbi); + } + + BOOL DeleteBand(int nBand) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_DELETEBAND, nBand, 0L); + } + + ATL::CWindow SetNotifyWnd(HWND hWnd) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ATL::CWindow((HWND)::SendMessage(m_hWnd, RB_SETPARENT, (WPARAM)hWnd, 0L)); + } + +#if (_WIN32_IE >= 0x0400) + void BeginDrag(int nBand, DWORD dwPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_BEGINDRAG, nBand, dwPos); + } + + void BeginDrag(int nBand, int xPos, int yPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_BEGINDRAG, nBand, MAKELPARAM(xPos, yPos)); + } + + void EndDrag() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_ENDDRAG, 0, 0L); + } + + void DragMove(DWORD dwPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_DRAGMOVE, 0, dwPos); + } + + void DragMove(int xPos, int yPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_DRAGMOVE, 0, MAKELPARAM(xPos, yPos)); + } + +#ifndef _WIN32_WCE + void GetDropTarget(IDropTarget** ppDropTarget) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_GETDROPTARGET, 0, (LPARAM)ppDropTarget); + } +#endif // !_WIN32_WCE + + void MaximizeBand(int nBand, BOOL bIdeal = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_MAXIMIZEBAND, nBand, bIdeal); + } + + void MinimizeBand(int nBand) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_MINIMIZEBAND, nBand, 0L); + } + + BOOL SizeToRect(LPRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_SIZETORECT, 0, (LPARAM)lpRect); + } + + int IdToIndex(UINT uBandID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, RB_IDTOINDEX, uBandID, 0L); + } + + int HitTest(LPRBHITTESTINFO lprbht) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, RB_HITTEST, 0, (LPARAM)lprbht); + } + + BOOL ShowBand(int nBand, BOOL bShow) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_SHOWBAND, nBand, bShow); + } + +#ifndef _WIN32_WCE + BOOL MoveBand(int nBand, int nNewPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nNewPos >= 0 && nNewPos <= ((int)GetBandCount() - 1)); + return (BOOL)::SendMessage(m_hWnd, RB_MOVEBAND, nBand, nNewPos); + } +#endif // !_WIN32_WCE +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + void PushChevron(int nBand, LPARAM lAppValue) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, RB_PUSHCHEVRON, nBand, lAppValue); + } +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + +// Extra operations +#if (_WIN32_IE >= 0x0400) + void LockBands(bool bLock) + { + int nBandCount = GetBandCount(); + for(int i =0; i < nBandCount; i++) + { + REBARBANDINFO rbbi = { RunTimeHelper::SizeOf_REBARBANDINFO() }; + rbbi.fMask = RBBIM_STYLE; + BOOL bRet = GetBandInfo(i, &rbbi); + ATLASSERT(bRet); + + if((rbbi.fStyle & RBBS_GRIPPERALWAYS) == 0) + { + rbbi.fStyle |= RBBS_GRIPPERALWAYS; + bRet = SetBandInfo(i, &rbbi); + ATLASSERT(bRet); + rbbi.fStyle &= ~RBBS_GRIPPERALWAYS; + } + + if(bLock) + rbbi.fStyle |= RBBS_NOGRIPPER; + else + rbbi.fStyle &= ~RBBS_NOGRIPPER; + + bRet = SetBandInfo(i, &rbbi); + ATLASSERT(bRet); + } + } +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_WINNT >= 0x0600) + BOOL SetBandWidth(int nBand, int cxWidth) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, RB_SETBANDWIDTH, nBand, cxWidth); + } +#endif // (_WIN32_WINNT >= 0x0600) +}; + +typedef CReBarCtrlT CReBarCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CComboBoxEx + +#ifndef _WIN32_WCE + +template +class CComboBoxExT : public CComboBoxT< TBase > +{ +public: +// Constructors + CComboBoxExT(HWND hWnd = NULL) : CComboBoxT< TBase >(hWnd) + { } + + CComboBoxExT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_COMBOBOXEX; + } + + CImageList GetImageList() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, CBEM_GETIMAGELIST, 0, 0L)); + } + + CImageList SetImageList(HIMAGELIST hImageList) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CImageList((HIMAGELIST)::SendMessage(m_hWnd, CBEM_SETIMAGELIST, 0, (LPARAM)hImageList)); + } + +#if (_WIN32_IE >= 0x0400) + DWORD GetExtendedStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, CBEM_GETEXTENDEDSTYLE, 0, 0L); + } + + DWORD SetExtendedStyle(DWORD dwExMask, DWORD dwExStyle) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, CBEM_SETEXTENDEDSTYLE, dwExMask, dwExStyle); + } + + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CBEM_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CBEM_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_WINNT >= 0x0501) + void SetWindowTheme(LPCWSTR lpstrTheme) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, CBEM_SETWINDOWTHEME, 0, (LPARAM)lpstrTheme); + } +#endif // (_WIN32_WINNT >= 0x0501) + +// Operations + int InsertItem(const COMBOBOXEXITEM* lpcCBItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CBEM_INSERTITEM, 0, (LPARAM)lpcCBItem); + } + + int InsertItem(UINT nMask, int nIndex, LPCTSTR lpszItem, int nImage, int nSelImage, + int iIndent, int iOverlay, LPARAM lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + COMBOBOXEXITEM cbex = { 0 }; + cbex.mask = nMask; + cbex.iItem = nIndex; + cbex.pszText = (LPTSTR) lpszItem; + cbex.iImage = nImage; + cbex.iSelectedImage = nSelImage; + cbex.iIndent = iIndent; + cbex.iOverlay = iOverlay; + cbex.lParam = lParam; + return (int)::SendMessage(m_hWnd, CBEM_INSERTITEM, 0, (LPARAM)&cbex); + } + + int InsertItem(int nIndex, LPCTSTR lpszItem, int nImage, int nSelImage, int iIndent, LPARAM lParam = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + COMBOBOXEXITEM cbex = { 0 }; + cbex.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_INDENT | CBEIF_LPARAM; + cbex.iItem = nIndex; + cbex.pszText = (LPTSTR) lpszItem; + cbex.iImage = nImage; + cbex.iSelectedImage = nSelImage; + cbex.iIndent = iIndent; + cbex.lParam = lParam; + return (int)::SendMessage(m_hWnd, CBEM_INSERTITEM, 0, (LPARAM)&cbex); + } + + int AddItem(UINT nMask, LPCTSTR lpszItem, int nImage, int nSelImage, int iIndent, int iOverlay, LPARAM lParam) + { + return InsertItem(nMask, -1, lpszItem, nImage, nSelImage, iIndent, iOverlay, lParam); + } + + int AddItem(LPCTSTR lpszItem, int nImage, int nSelImage, int iIndent, LPARAM lParam = 0) + { + return InsertItem(-1, lpszItem, nImage, nSelImage, iIndent, lParam); + } + + int DeleteItem(int nIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, CBEM_DELETEITEM, nIndex, 0L); + } + + BOOL GetItem(PCOMBOBOXEXITEM pCBItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CBEM_GETITEM, 0, (LPARAM)pCBItem); + } + + BOOL SetItem(const COMBOBOXEXITEM* lpcCBItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CBEM_SETITEM, 0, (LPARAM)lpcCBItem); + } + + int SetItem(int nIndex, UINT nMask, LPCTSTR lpszItem, int nImage, int nSelImage, + int iIndent, int iOverlay, LPARAM lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + COMBOBOXEXITEM cbex = { 0 }; + cbex.mask = nMask; + cbex.iItem = nIndex; + cbex.pszText = (LPTSTR) lpszItem; + cbex.iImage = nImage; + cbex.iSelectedImage = nSelImage; + cbex.iIndent = iIndent; + cbex.iOverlay = iOverlay; + cbex.lParam = lParam; + return (int)::SendMessage(m_hWnd, CBEM_SETITEM, 0, (LPARAM)&cbex); + } + + BOOL GetItemText(int nIndex, LPTSTR lpszItem, int nLen) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpszItem != NULL); + + COMBOBOXEXITEM cbex = { 0 }; + cbex.mask = CBEIF_TEXT; + cbex.iItem = nIndex; + cbex.pszText = lpszItem; + cbex.cchTextMax = nLen; + + return (BOOL)::SendMessage(m_hWnd, CBEM_GETITEM, 0, (LPARAM)&cbex); + } + +#ifndef _ATL_NO_COM + BOOL GetItemText(int nIndex, BSTR& bstrText) const + { + USES_CONVERSION; + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(bstrText == NULL); + + COMBOBOXEXITEM cbex = { 0 }; + cbex.mask = CBEIF_TEXT; + cbex.iItem = nIndex; + + LPTSTR lpstrText = NULL; + BOOL bRet = FALSE; + for(int nLen = 256; ; nLen *= 2) + { + ATLTRY(lpstrText = new TCHAR[nLen]); + if(lpstrText == NULL) + break; + lpstrText[0] = NULL; + cbex.pszText = lpstrText; + cbex.cchTextMax = nLen; + bRet = (BOOL)::SendMessage(m_hWnd, CBEM_GETITEM, 0, (LPARAM)&cbex); + if(!bRet || (lstrlen(cbex.pszText) < nLen - 1)) + break; + delete [] lpstrText; + lpstrText = NULL; + } + + if(lpstrText != NULL) + { + if(bRet) + bstrText = ::SysAllocString(T2OLE(lpstrText)); + delete [] lpstrText; + } + + return (bstrText != NULL) ? TRUE : FALSE; + } +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + BOOL GetItemText(int nIndex, _CSTRING_NS::CString& strText) const + { + ATLASSERT(::IsWindow(m_hWnd)); + + COMBOBOXEXITEM cbex = { 0 }; + cbex.mask = CBEIF_TEXT; + cbex.iItem = nIndex; + + strText.Empty(); + BOOL bRet = FALSE; + for(int nLen = 256; ; nLen *= 2) + { + cbex.pszText = strText.GetBufferSetLength(nLen); + if(cbex.pszText == NULL) + { + bRet = FALSE; + break; + } + cbex.cchTextMax = nLen; + bRet = (BOOL)::SendMessage(m_hWnd, CBEM_GETITEM, 0, (LPARAM)&cbex); + if(!bRet || (lstrlen(cbex.pszText) < nLen - 1)) + break; + } + strText.ReleaseBuffer(); + return bRet; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + BOOL SetItemText(int nIndex, LPCTSTR lpszItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return SetItem(nIndex, CBEIF_TEXT, lpszItem, 0, 0, 0, 0, 0); + } + + CComboBox GetComboCtrl() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CComboBox((HWND)::SendMessage(m_hWnd, CBEM_GETCOMBOCONTROL, 0, 0L)); + } + + CEdit GetEditCtrl() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CEdit((HWND)::SendMessage(m_hWnd, CBEM_GETEDITCONTROL, 0, 0L)); + } + + BOOL HasEditChanged() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, CBEM_HASEDITCHANGED, 0, 0L); + } + +// Non-functional + int AddString(LPCTSTR /*lpszItem*/) + { + ATLASSERT(FALSE); // Not available in CComboBoxEx; use InsertItem + return 0; + } + + int InsertString(int /*nIndex*/, LPCTSTR /*lpszString*/) + { + ATLASSERT(FALSE); // Not available in CComboBoxEx; use InsertItem + return 0; + } + + int Dir(UINT /*attr*/, LPCTSTR /*lpszWildCard*/) + { + ATLASSERT(FALSE); // Not available in CComboBoxEx + return 0; + } + + int FindString(int /*nStartAfter*/, LPCTSTR /*lpszString*/) const + { + ATLASSERT(FALSE); // Not available in CComboBoxEx; try FindStringExact + return 0; + } +}; + +typedef CComboBoxExT CComboBoxEx; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CMonthCalendarCtrl + +template +class CMonthCalendarCtrlT : public TBase +{ +public: +// Constructors + CMonthCalendarCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CMonthCalendarCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return MONTHCAL_CLASS; + } + + COLORREF GetColor(int nColorType) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, MCM_GETCOLOR, nColorType, 0L); + } + + COLORREF SetColor(int nColorType, COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, MCM_SETCOLOR, nColorType, clr); + } + + BOOL GetCurSel(LPSYSTEMTIME lpSysTime) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_GETCURSEL, 0, (LPARAM)lpSysTime); + } + + BOOL SetCurSel(LPSYSTEMTIME lpSysTime) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_SETCURSEL, 0, (LPARAM)lpSysTime); + } + + int GetFirstDayOfWeek(BOOL* pbLocaleVal = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, MCM_GETFIRSTDAYOFWEEK, 0, 0L); + if(pbLocaleVal != NULL) + *pbLocaleVal = (BOOL)HIWORD(dwRet); + return (int)(short)LOWORD(dwRet); + } + + int SetFirstDayOfWeek(int nDay, BOOL* pbLocaleVal = NULL) + { + ATLASSERT(::IsWindow(m_hWnd)); + DWORD dwRet = (DWORD)::SendMessage(m_hWnd, MCM_SETFIRSTDAYOFWEEK, 0, nDay); + if(pbLocaleVal != NULL) + *pbLocaleVal = (BOOL)HIWORD(dwRet); + return (int)(short)LOWORD(dwRet); + } + + int GetMaxSelCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, MCM_GETMAXSELCOUNT, 0, 0L); + } + + BOOL SetMaxSelCount(int nMax) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_SETMAXSELCOUNT, nMax, 0L); + } + + int GetMonthDelta() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, MCM_GETMONTHDELTA, 0, 0L); + } + + int SetMonthDelta(int nDelta) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, MCM_SETMONTHDELTA, nDelta, 0L); + } + + DWORD GetRange(LPSYSTEMTIME lprgSysTimeArray) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, MCM_GETRANGE, 0, (LPARAM)lprgSysTimeArray); + } + + BOOL SetRange(DWORD dwFlags, LPSYSTEMTIME lprgSysTimeArray) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_SETRANGE, dwFlags, (LPARAM)lprgSysTimeArray); + } + + BOOL GetSelRange(LPSYSTEMTIME lprgSysTimeArray) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_GETSELRANGE, 0, (LPARAM)lprgSysTimeArray); + } + + BOOL SetSelRange(LPSYSTEMTIME lprgSysTimeArray) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_SETSELRANGE, 0, (LPARAM)lprgSysTimeArray); + } + + BOOL GetToday(LPSYSTEMTIME lpSysTime) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_GETTODAY, 0, (LPARAM)lpSysTime); + } + + void SetToday(LPSYSTEMTIME lpSysTime) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, MCM_SETTODAY, 0, (LPARAM)lpSysTime); + } + + BOOL GetMinReqRect(LPRECT lpRectInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_GETMINREQRECT, 0, (LPARAM)lpRectInfo); + } + + int GetMaxTodayWidth() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, MCM_GETMAXTODAYWIDTH, 0, 0L); + } + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + BOOL GetUnicodeFormat() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_GETUNICODEFORMAT, 0, 0L); + } + + BOOL SetUnicodeFormat(BOOL bUnicode = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_SETUNICODEFORMAT, bUnicode, 0L); + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) + DWORD GetCurrentView() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, MCM_GETCURRENTVIEW, 0, 0L); + } + + BOOL SetCurrentView(DWORD dwView) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_SETCURRENTVIEW, 0, dwView); + } + + DWORD GetCalendarCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, MCM_GETCALENDARCOUNT, 0, 0L); + } + + BOOL GetCalendarGridInfo(PMCGRIDINFO pGridInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_GETCALENDARGRIDINFO, 0, (LPARAM)pGridInfo); + } + + CALID GetCALID() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (CALID)::SendMessage(m_hWnd, MCM_GETCALID, 0, 0L); + } + + void SetCALID(CALID calid) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, MCM_SETCALID, (LPARAM)calid, 0L); + } + + int GetCalendarBorder() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, MCM_GETCALENDARBORDER, 0, 0L); + } + + void SetCalendarBorder(int cxyBorder, BOOL bSet = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, MCM_SETCALENDARBORDER, (WPARAM)bSet, (LPARAM)cxyBorder); + } +#endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) + +// Operations + int GetMonthRange(DWORD dwFlags, LPSYSTEMTIME lprgSysTimeArray) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, MCM_GETMONTHRANGE, dwFlags, (LPARAM)lprgSysTimeArray); + } + + BOOL SetDayState(int nMonths, LPMONTHDAYSTATE lpDayStateArray) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, MCM_SETDAYSTATE, nMonths, (LPARAM)lpDayStateArray); + } + + DWORD HitTest(PMCHITTESTINFO pMCHitTest) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, MCM_HITTEST, 0, (LPARAM)pMCHitTest); + } + +#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) + void SizeRectToMin(LPRECT lpRect) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, MCM_SIZERECTTOMIN, 0, (LPARAM)lpRect); + } +#endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) +}; + +typedef CMonthCalendarCtrlT CMonthCalendarCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CDateTimePickerCtrl + +template +class CDateTimePickerCtrlT : public TBase +{ +public: +// Constructors + CDateTimePickerCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CDateTimePickerCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Operations + static LPCTSTR GetWndClassName() + { + return DATETIMEPICK_CLASS; + } + + BOOL SetFormat(LPCTSTR lpszFormat) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, DTM_SETFORMAT, 0, (LPARAM)lpszFormat); + } + + COLORREF GetMonthCalColor(int nColorType) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, DTM_GETMCCOLOR, nColorType, 0L); + } + + COLORREF SetMonthCalColor(int nColorType, COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, DTM_SETMCCOLOR, nColorType, clr); + } + + DWORD GetRange(LPSYSTEMTIME lpSysTimeArray) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, DTM_GETRANGE, 0, (LPARAM)lpSysTimeArray); + } + + BOOL SetRange(DWORD dwFlags, LPSYSTEMTIME lpSysTimeArray) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, DTM_SETRANGE, dwFlags, (LPARAM)lpSysTimeArray); + } + + DWORD GetSystemTime(LPSYSTEMTIME lpSysTime) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)lpSysTime); + } + + BOOL SetSystemTime(DWORD dwFlags, LPSYSTEMTIME lpSysTime) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, DTM_SETSYSTEMTIME, dwFlags, (LPARAM)lpSysTime); + } + + CMonthCalendarCtrl GetMonthCal() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CMonthCalendarCtrl((HWND)::SendMessage(m_hWnd, DTM_GETMONTHCAL, 0, 0L)); + } + +#if (_WIN32_IE >= 0x0400) + CFontHandle GetMonthCalFont() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CFontHandle((HFONT)::SendMessage(m_hWnd, DTM_GETMCFONT, 0, 0L)); + } + + void SetMonthCalFont(HFONT hFont, BOOL bRedraw = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_SETMCFONT, (WPARAM)hFont, MAKELPARAM(bRedraw, 0)); + } +#endif // (_WIN32_IE >= 0x0400) + +#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) + DWORD GetMonthCalStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, DTM_GETMCSTYLE, 0, 0L); + } + + DWORD SetMonthCalStyle(DWORD dwStyle) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (DWORD)::SendMessage(m_hWnd, DTM_SETMCSTYLE, 0, (LPARAM)dwStyle); + } + + void GetDateTimePickerInfo(LPDATETIMEPICKERINFO lpPickerInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_GETDATETIMEPICKERINFO, 0, (LPARAM)lpPickerInfo); + } + + BOOL GetIdealSize(LPSIZE lpSize) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, DTM_GETIDEALSIZE, 0, (LPARAM)lpSize); + } + + void CloseMonthCal() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_CLOSEMONTHCAL, 0, 0L); + } +#endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) +}; + +typedef CDateTimePickerCtrlT CDateTimePickerCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CFlatScrollBarImpl - support for flat scroll bars + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +template +class CFlatScrollBarImpl +{ +public: +// Initialization + BOOL FlatSB_Initialize() + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::InitializeFlatSB(pT->m_hWnd); + } + + HRESULT FlatSB_Uninitialize() + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::UninitializeFlatSB(pT->m_hWnd); + } + +// Flat scroll bar properties + BOOL FlatSB_GetScrollProp(UINT uIndex, LPINT lpnValue) const + { + const T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_GetScrollProp(pT->m_hWnd, uIndex, lpnValue); + } + + BOOL FlatSB_SetScrollProp(UINT uIndex, int nValue, BOOL bRedraw = TRUE) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_SetScrollProp(pT->m_hWnd, uIndex, nValue, bRedraw); + } + +// Attributes + int FlatSB_GetScrollPos(int nBar) const + { + const T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_GetScrollPos(pT->m_hWnd, nBar); + } + + int FlatSB_SetScrollPos(int nBar, int nPos, BOOL bRedraw = TRUE) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_SetScrollPos(pT->m_hWnd, nBar, nPos, bRedraw); + } + + BOOL FlatSB_GetScrollRange(int nBar, LPINT lpMinPos, LPINT lpMaxPos) const + { + const T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_GetScrollRange(pT->m_hWnd, nBar, lpMinPos, lpMaxPos); + } + + BOOL FlatSB_SetScrollRange(int nBar, int nMinPos, int nMaxPos, BOOL bRedraw = TRUE) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_SetScrollRange(pT->m_hWnd, nBar, nMinPos, nMaxPos, bRedraw); + } + + BOOL FlatSB_GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo) const + { + const T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_GetScrollInfo(pT->m_hWnd, nBar, lpScrollInfo); + } + + int FlatSB_SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_SetScrollInfo(pT->m_hWnd, nBar, lpScrollInfo, bRedraw); + } + +// Operations + BOOL FlatSB_ShowScrollBar(UINT nBar, BOOL bShow = TRUE) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_ShowScrollBar(pT->m_hWnd, nBar, bShow); + } + + BOOL FlatSB_EnableScrollBar(UINT uSBFlags, UINT uArrowFlags = ESB_ENABLE_BOTH) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::FlatSB_EnableScrollBar(pT->m_hWnd, uSBFlags, uArrowFlags); + } +}; + +template +class CFlatScrollBarT : public TBase, public CFlatScrollBarImpl > +{ +public: + CFlatScrollBarT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CFlatScrollBarT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } +}; + +typedef CFlatScrollBarT CFlatScrollBar; + +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + + +/////////////////////////////////////////////////////////////////////////////// +// CIPAddressCtrl + +#if (_WIN32_IE >= 0x0400) + +template +class CIPAddressCtrlT : public TBase +{ +public: +// Constructors + CIPAddressCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CIPAddressCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Atteributes + static LPCTSTR GetWndClassName() + { + return WC_IPADDRESS; + } + + BOOL IsBlank() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, IPM_ISBLANK, 0, 0L); + } + + int GetAddress(LPDWORD lpdwAddress) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, IPM_GETADDRESS, 0, (LPARAM)lpdwAddress); + } + + void SetAddress(DWORD dwAddress) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, IPM_SETADDRESS, 0, dwAddress); + } + + void ClearAddress() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, IPM_CLEARADDRESS, 0, 0L); + } + + void SetRange(int nField, WORD wRange) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, IPM_SETRANGE, nField, wRange); + } + + void SetRange(int nField, BYTE nMin, BYTE nMax) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, IPM_SETRANGE, nField, MAKEIPRANGE(nMin, nMax)); + } + + void SetFocus(int nField) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, IPM_SETFOCUS, nField, 0L); + } +}; + +typedef CIPAddressCtrlT CIPAddressCtrl; + +#endif // (_WIN32_IE >= 0x0400) + + +/////////////////////////////////////////////////////////////////////////////// +// CPagerCtrl + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +template +class CPagerCtrlT : public TBase +{ +public: +// Constructors + CPagerCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CPagerCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_PAGESCROLLER; + } + + int GetButtonSize() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PGM_GETBUTTONSIZE, 0, 0L); + } + + int SetButtonSize(int nButtonSize) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PGM_SETBUTTONSIZE, 0, nButtonSize); + } + + DWORD GetButtonState(int nButton) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nButton == PGB_TOPORLEFT || nButton == PGB_BOTTOMORRIGHT); + return (DWORD)::SendMessage(m_hWnd, PGM_GETBUTTONSTATE, 0, nButton); + } + + COLORREF GetBkColor() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, PGM_GETBKCOLOR, 0, 0L); + } + + COLORREF SetBkColor(COLORREF clrBk) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (COLORREF)::SendMessage(m_hWnd, PGM_SETBKCOLOR, 0, (LPARAM)clrBk); + } + + int GetBorder() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PGM_GETBORDER, 0, 0L); + } + + int SetBorder(int nBorderSize) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PGM_SETBORDER, 0, nBorderSize); + } + + int GetPos() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PGM_GETPOS, 0, 0L); + } + + int SetPos(int nPos) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PGM_SETPOS, 0, nPos); + } + +// Operations + void SetChild(HWND hWndChild) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, PGM_SETCHILD, 0, (LPARAM)hWndChild); + } + + void ForwardMouse(BOOL bForward = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, PGM_FORWARDMOUSE, bForward, 0L); + } + + void RecalcSize() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, PGM_RECALCSIZE, 0, 0L); + } + + void GetDropTarget(IDropTarget** ppDropTarget) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(ppDropTarget != NULL); + ::SendMessage(m_hWnd, PGM_GETDROPTARGET, 0, (LPARAM)ppDropTarget); + } +}; + +typedef CPagerCtrlT CPagerCtrl; + +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + + +/////////////////////////////////////////////////////////////////////////////// +// CLinkCtrl - Windows SYSLINK control + +#if (_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE) + +template +class CLinkCtrlT : public TBase +{ +public: +// Constructors + CLinkCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CLinkCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + return TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + } + +// Attributes + static LPCTSTR GetWndClassName() + { +#ifdef _UNICODE + return WC_LINK; +#else // !_UNICODE + return "SysLink"; +#endif // !_UNICODE + } + + int GetIdealHeight(int cxMaxWidth = 0) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LM_GETIDEALHEIGHT, cxMaxWidth, 0L); + } + + BOOL GetItem(PLITEM pLItem) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LM_GETITEM, 0, (LPARAM)pLItem); + } + + BOOL SetItem(PLITEM pLItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LM_SETITEM, 0, (LPARAM)pLItem); + } + + // Vista only + int GetIdealSize(SIZE& size, int cxMaxWidth = 0) const + { +#ifndef LM_GETIDEALSIZE + const UINT LM_GETIDEALSIZE = LM_GETIDEALHEIGHT; +#endif + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, LM_GETIDEALSIZE, cxMaxWidth, (LPARAM)&size); + } + +// Operations + BOOL HitTest(PLHITTESTINFO pLHitTestInfo) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, LM_HITTEST, 0, (LPARAM)pLHitTestInfo); + } +}; + +typedef CLinkCtrlT CLinkCtrl; + +#endif // (_WIN32_WINNT >= 0x0501) && !defined(_WIN32_WCE) + + +/////////////////////////////////////////////////////////////////////////////// +// CCustomDraw - MI class for custom-draw support + +template +class CCustomDraw +{ +public: +#if (_ATL_VER < 0x0700) + BOOL m_bHandledCD; + + BOOL IsMsgHandled() const + { + return m_bHandledCD; + } + + void SetMsgHandled(BOOL bHandled) + { + m_bHandledCD = bHandled; + } +#endif // !(_ATL_VER < 0x0700) + +// Message map and handlers + BEGIN_MSG_MAP(CCustomDraw< T >) + NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw) + ALT_MSG_MAP(1) + REFLECTED_NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw) + END_MSG_MAP() + +// message handler + LRESULT OnCustomDraw(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) + { + T* pT = static_cast(this); + pT->SetMsgHandled(TRUE); + LPNMCUSTOMDRAW lpNMCustomDraw = (LPNMCUSTOMDRAW)pnmh; + DWORD dwRet = 0; + switch(lpNMCustomDraw->dwDrawStage) + { + case CDDS_PREPAINT: + dwRet = pT->OnPrePaint(idCtrl, lpNMCustomDraw); + break; + case CDDS_POSTPAINT: + dwRet = pT->OnPostPaint(idCtrl, lpNMCustomDraw); + break; + case CDDS_PREERASE: + dwRet = pT->OnPreErase(idCtrl, lpNMCustomDraw); + break; + case CDDS_POSTERASE: + dwRet = pT->OnPostErase(idCtrl, lpNMCustomDraw); + break; + case CDDS_ITEMPREPAINT: + dwRet = pT->OnItemPrePaint(idCtrl, lpNMCustomDraw); + break; + case CDDS_ITEMPOSTPAINT: + dwRet = pT->OnItemPostPaint(idCtrl, lpNMCustomDraw); + break; + case CDDS_ITEMPREERASE: + dwRet = pT->OnItemPreErase(idCtrl, lpNMCustomDraw); + break; + case CDDS_ITEMPOSTERASE: + dwRet = pT->OnItemPostErase(idCtrl, lpNMCustomDraw); + break; +#if (_WIN32_IE >= 0x0400) + case (CDDS_ITEMPREPAINT | CDDS_SUBITEM): + dwRet = pT->OnSubItemPrePaint(idCtrl, lpNMCustomDraw); + break; +#endif // (_WIN32_IE >= 0x0400) + default: + pT->SetMsgHandled(FALSE); + break; + } + bHandled = pT->IsMsgHandled(); + return dwRet; + } + +// Overrideables + DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } + + DWORD OnPostPaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } + + DWORD OnPreErase(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } + + DWORD OnPostErase(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } + + DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } + + DWORD OnItemPostPaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } + + DWORD OnItemPreErase(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } + + DWORD OnItemPostErase(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } + +#if (_WIN32_IE >= 0x0400) + DWORD OnSubItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_DODEFAULT; + } +#endif // (_WIN32_IE >= 0x0400) +}; + + +// --- Windows CE common controls --- + +#ifdef _WIN32_WCE + +/////////////////////////////////////////////////////////////////////////////// +// CCECommandBarCtrl + +template +class CCECommandBarCtrlT : public TBase +{ +public: +// Constructors + CCECommandBarCtrlT(HWND hWnd = NULL) : TBase(hWnd) { } + + CCECommandBarCtrlT< TBase >& operator=(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + +// Attributes + BOOL IsVisible() const + { + return IsWindowVisible(); + } + + int GetHeight() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_Height(m_hWnd); + } + + HMENU GetMenu(WORD wButton) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_GetMenu(m_hWnd, wButton); + } + +// Operations + HWND Create(HWND hWndParent, int nCmdBarID) + { + m_hWnd = ::CommandBar_Create(ModuleHelper::GetModuleInstance(), hWndParent, nCmdBarID); + ATLASSERT(::IsWindow(m_hWnd)); + return m_hWnd; + } + + void Destroy() + { + DestroyWindow(); + } + + BOOL Show(BOOL bShow = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_Show(m_hWnd, bShow); + } + + BOOL DrawMenuBar(WORD wButton) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_DrawMenuBar(m_hWnd, wButton); + } + + BOOL AddAdornments(DWORD dwFlags = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_AddAdornments(m_hWnd, dwFlags, 0); + } + + int AddBitmap(int nBitmapID, int nNumImages) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_AddBitmap(m_hWnd, ModuleHelper::GetResourceInstance(), nBitmapID, nNumImages, 16, 16); + } + + BOOL AddButtons(UINT uNumButtons, LPTBBUTTON lpButtons) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CommandBar_AddButtons(m_hWnd, uNumButtons, lpButtons); + } + + BOOL AddToolTips(UINT uNumToolTips, LPTSTR lpToolTips) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CommandBar_AddToolTips(m_hWnd, uNumToolTips, lpToolTips); + } + + BOOL InsertButton(int nButton, LPTBBUTTON lpButton) + { + ATLASSERT(::IsWindow(m_hWnd)); + return CommandBar_InsertButton(m_hWnd, nButton, lpButton); + } + + HWND InsertComboBox(int nWidth, UINT dwStyle, WORD wComboBoxID, WORD wButton) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_InsertComboBox(m_hWnd, ModuleHelper::GetModuleInstance(), nWidth, dwStyle, wComboBoxID, wButton); + } + + BOOL InsertMenubar(WORD wMenuID, WORD wButton) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_InsertMenubar(m_hWnd, ModuleHelper::GetResourceInstance(), wMenuID, wButton); + } + + BOOL InsertMenubarEx(ATL::_U_STRINGorID menu, WORD wButton) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBar_InsertMenubarEx(m_hWnd, ModuleHelper::GetResourceInstance(), (LPTSTR)menu.m_lpstr, wButton); + } + + BOOL IsCommandBarMessage(LPMSG lpMsg) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::IsCommandBarMessage(m_hWnd, lpMsg); + } +}; + +#if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC MenuBar + typedef CCECommandBarCtrlT CMenuBarCtrl; +#else + typedef CCECommandBarCtrlT CCECommandBarCtrl; +#endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) + +/////////////////////////////////////////////////////////////////////////////// +// CCECommandBandsCtrl + +template +class CCECommandBandsCtrlT : public TBase +{ +public: +// Constructors + CCECommandBandsCtrlT(HWND hWnd = NULL) : TBase(hWnd) { } + + CCECommandBandsCtrlT< TBase >& operator=(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + +// Attributes + BOOL IsVisible() const + { + return IsWindowVisible(); + } + +#if (_WIN32_IE >= 0x0400) + UINT GetHeight() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CommandBands_Height(m_hWnd); + } +#endif // (_WIN32_IE >= 0x0400) + + HWND GetCommandBar(UINT uBand) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBands_GetCommandBar(m_hWnd, uBand); + } + + BOOL GetRestoreInformation(UINT uBand, LPCOMMANDBANDSRESTOREINFO pcbr) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBands_GetRestoreInformation(m_hWnd, uBand, pcbr); + } + +// Operations + HWND Create(HWND hWndParent, UINT wID, DWORD dwStyles, HIMAGELIST hImageList = NULL) + { + m_hWnd = ::CommandBands_Create(ModuleHelper::GetModuleInstance(), hWndParent, wID, dwStyles, hImageList); + ATLASSERT(::IsWindow(m_hWnd)); + return m_hWnd; + } + + BOOL AddAdornments(DWORD dwFlags = 0, LPREBARBANDINFO prbbi = NULL) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBands_AddAdornments(m_hWnd, ModuleHelper::GetModuleInstance(), dwFlags, prbbi); + } + + BOOL AddBands(UINT uBandCount, LPREBARBANDINFO prbbi) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBands_AddBands(m_hWnd, ModuleHelper::GetModuleInstance(), uBandCount, prbbi); + } + + BOOL Show(BOOL bShow = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::CommandBands_Show(m_hWnd, bShow); + } +}; + +typedef CCECommandBandsCtrlT CCECommandBandsCtrl; + +#endif // _WIN32_WCE + +}; // namespace WTL + +#endif // __ATLCTRLS_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlctrlw.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlctrlw.h new file mode 100644 index 0000000000..7f95bdfda1 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlctrlw.h @@ -0,0 +1,4157 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLCTRLW_H__ +#define __ATLCTRLW_H__ + +#pragma once + +#ifdef _WIN32_WCE + #error atlctrlw.h is not supported on Windows CE +#endif + +#ifndef __ATLAPP_H__ + #error atlctrlw.h requires atlapp.h to be included first +#endif + +#ifndef __ATLCTRLS_H__ + #error atlctrlw.h requires atlctrls.h to be included first +#endif + +#if (_WIN32_IE < 0x0400) + #error atlctrlw.h requires _WIN32_IE >= 0x0400 +#endif + +// Define _WTL_CMDBAR_VISTA_MENUS as 0 to exclude Vista menus support +#if !defined(_WTL_CMDBAR_VISTA_MENUS) && (WINVER >= 0x0500) && (_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501) + #define _WTL_CMDBAR_VISTA_MENUS 1 +#endif + +#if _WTL_CMDBAR_VISTA_MENUS + #if !((_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501)) + #error _WTL_CMDBAR_VISTA_MENUS requires (_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501) + #endif +#endif + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CCommandBarCtrlImpl +// CCommandBarCtrl +// CMDICommandBarCtrlImpl +// CMDICommandBarCtrl + + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// Command Bars + +// Window Styles: +#define CBRWS_TOP CCS_TOP +#define CBRWS_BOTTOM CCS_BOTTOM +#define CBRWS_NORESIZE CCS_NORESIZE +#define CBRWS_NOPARENTALIGN CCS_NOPARENTALIGN +#define CBRWS_NODIVIDER CCS_NODIVIDER + +// Extended styles +#define CBR_EX_TRANSPARENT 0x00000001L +#define CBR_EX_SHAREMENU 0x00000002L +#define CBR_EX_ALTFOCUSMODE 0x00000004L +#define CBR_EX_TRACKALWAYS 0x00000008L +#define CBR_EX_NOVISTAMENUS 0x00000010L + +// standard command bar styles +#define ATL_SIMPLE_CMDBAR_PANE_STYLE \ + (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CBRWS_NODIVIDER | CBRWS_NORESIZE | CBRWS_NOPARENTALIGN) + +// Messages - support chevrons for frame windows +#define CBRM_GETCMDBAR (WM_USER + 301) // returns command bar HWND +#define CBRM_GETMENU (WM_USER + 302) // returns loaded or attached menu +#define CBRM_TRACKPOPUPMENU (WM_USER + 303) // displays a popup menu + +typedef struct tagCBRPOPUPMENU +{ + int cbSize; + HMENU hMenu; // popup menu do display + UINT uFlags; // TPM_* flags for ::TrackPopupMenuEx + int x; + int y; + LPTPMPARAMS lptpm; // ptr to TPMPARAMS for ::TrackPopupMenuEx +} CBRPOPUPMENU, *LPCBRPOPUPMENU; + +// helper class +template +class CSimpleStack : public ATL::CSimpleArray< T > +{ +public: + BOOL Push(T t) + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - STACK-PUSH (%8.8X) size = %i\n"), t, GetSize()); +#endif + return Add(t); + } + + T Pop() + { + int nLast = GetSize() - 1; + if(nLast < 0) + return NULL; // must be able to convert to NULL + T t = m_aT[nLast]; +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - STACK-POP (%8.8X) size = %i\n"), t, GetSize()); +#endif + if(!RemoveAt(nLast)) + return NULL; + return t; + } + + T GetCurrent() + { + int nLast = GetSize() - 1; + if(nLast < 0) + return NULL; // must be able to convert to NULL + return m_aT[nLast]; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CCommandBarCtrlBase - base class for the Command Bar implementation + +class CCommandBarCtrlBase : public CToolBarCtrl +{ +public: + struct _MsgHookData + { + HHOOK hMsgHook; + DWORD dwUsage; + + _MsgHookData() : hMsgHook(NULL), dwUsage(0) + { } + }; + + typedef ATL::CSimpleMap CMsgHookMap; + static CMsgHookMap* s_pmapMsgHook; + + static HHOOK s_hCreateHook; + static bool s_bW2K; // For animation flag + static CCommandBarCtrlBase* s_pCurrentBar; + static bool s_bStaticInit; + + CSimpleStack m_stackMenuWnd; + CSimpleStack m_stackMenuHandle; + + HWND m_hWndHook; + DWORD m_dwMagic; + + + CCommandBarCtrlBase() : m_hWndHook(NULL), m_dwMagic(1314) + { + // init static variables + if(!s_bStaticInit) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlBase::CCommandBarCtrlBase.\n")); + ATLASSERT(FALSE); + return; + } + + if(!s_bStaticInit) + { + // Just in case... + AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES); + // Animation on Win2000 only + s_bW2K = !AtlIsOldWindows(); + // done + s_bStaticInit = true; + } + + lock.Unlock(); + } + } + + bool IsCommandBarBase() const { return m_dwMagic == 1314; } +}; + +__declspec(selectany) CCommandBarCtrlBase::CMsgHookMap* CCommandBarCtrlBase::s_pmapMsgHook = NULL; +__declspec(selectany) HHOOK CCommandBarCtrlBase::s_hCreateHook = NULL; +__declspec(selectany) CCommandBarCtrlBase* CCommandBarCtrlBase::s_pCurrentBar = NULL; +__declspec(selectany) bool CCommandBarCtrlBase::s_bW2K = false; +__declspec(selectany) bool CCommandBarCtrlBase::s_bStaticInit = false; + + +/////////////////////////////////////////////////////////////////////////////// +// CCommandBarCtrl - ATL implementation of Command Bars + +template +class ATL_NO_VTABLE CCommandBarCtrlImpl : public ATL::CWindowImpl< T, TBase, TWinTraits > +{ +public: + DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName()) + +// Declarations + struct _MenuItemData // menu item data + { + DWORD dwMagic; + LPTSTR lpstrText; + UINT fType; + UINT fState; + int iButton; + + _MenuItemData() { dwMagic = 0x1313; } + bool IsCmdBarMenuItem() { return (dwMagic == 0x1313); } + }; + + struct _ToolBarData // toolbar resource data + { + WORD wVersion; + WORD wWidth; + WORD wHeight; + WORD wItemCount; + //WORD aItems[wItemCount] + + WORD* items() + { return (WORD*)(this+1); } + }; + +// Constants + enum _CmdBarDrawConstants + { + s_kcxGap = 1, + s_kcxTextMargin = 2, + s_kcxButtonMargin = 3, + s_kcyButtonMargin = 3 + }; + + enum + { + _nMaxMenuItemTextLength = 100, + _chChevronShortcut = _T('/') + }; + +#ifndef DT_HIDEPREFIX + enum { DT_HIDEPREFIX = 0x00100000 }; +#endif // !DT_HIDEPREFIX + +// Data members + HMENU m_hMenu; + HIMAGELIST m_hImageList; + ATL::CSimpleValArray m_arrCommand; + + DWORD m_dwExtendedStyle; // Command Bar specific extended styles + + ATL::CContainedWindow m_wndParent; + + bool m_bMenuActive:1; + bool m_bAttachedMenu:1; + bool m_bImagesVisible:1; + bool m_bPopupItem:1; + bool m_bContextMenu:1; + bool m_bEscapePressed:1; + bool m_bSkipMsg:1; + bool m_bParentActive:1; + bool m_bFlatMenus:1; + bool m_bUseKeyboardCues:1; + bool m_bShowKeyboardCues:1; + bool m_bAllowKeyboardCues:1; + bool m_bKeyboardInput:1; + bool m_bAlphaImages:1; + bool m_bLayoutRTL:1; + bool m_bSkipPostDown:1; + bool m_bVistaMenus:1; + + int m_nPopBtn; + int m_nNextPopBtn; + + SIZE m_szBitmap; + SIZE m_szButton; + + COLORREF m_clrMask; + CFont m_fontMenu; // used internally, only to measure text + + UINT m_uSysKey; + + HWND m_hWndFocus; // Alternate focus mode + + int m_cxExtraSpacing; + +#if _WTL_CMDBAR_VISTA_MENUS + ATL::CSimpleValArray m_arrVistaBitmap; // Bitmaps for Vista menus +#endif // _WTL_CMDBAR_VISTA_MENUS + +// Constructor/destructor + CCommandBarCtrlImpl() : + m_hMenu(NULL), + m_hImageList(NULL), + m_wndParent(this, 1), + m_bMenuActive(false), + m_bAttachedMenu(false), + m_nPopBtn(-1), + m_nNextPopBtn(-1), + m_bPopupItem(false), + m_bImagesVisible(true), + m_bSkipMsg(false), + m_uSysKey(0), + m_hWndFocus(NULL), + m_bContextMenu(false), + m_bEscapePressed(false), + m_clrMask(RGB(192, 192, 192)), + m_dwExtendedStyle(CBR_EX_TRANSPARENT | CBR_EX_SHAREMENU | CBR_EX_TRACKALWAYS), + m_bParentActive(true), + m_bFlatMenus(false), + m_bUseKeyboardCues(false), + m_bShowKeyboardCues(false), + m_bAllowKeyboardCues(true), + m_bKeyboardInput(false), + m_cxExtraSpacing(0), + m_bAlphaImages(false), + m_bLayoutRTL(false), + m_bSkipPostDown(false), + m_bVistaMenus(false) + { + SetImageSize(16, 15); // default + } + + ~CCommandBarCtrlImpl() + { + if(m_wndParent.IsWindow()) +/*scary!*/ m_wndParent.UnsubclassWindow(); + + if(m_hMenu != NULL && (m_dwExtendedStyle & CBR_EX_SHAREMENU) == 0) + ::DestroyMenu(m_hMenu); + + if(m_hImageList != NULL) + ::ImageList_Destroy(m_hImageList); + } + +// Attributes + DWORD GetCommandBarExtendedStyle() const + { + return m_dwExtendedStyle; + } + + DWORD SetCommandBarExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) + { + DWORD dwPrevStyle = m_dwExtendedStyle; + if(dwMask == 0) + m_dwExtendedStyle = dwExtendedStyle; + else + m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); + return dwPrevStyle; + } + + CMenuHandle GetMenu() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return m_hMenu; + } + + COLORREF GetImageMaskColor() const + { + return m_clrMask; + } + + COLORREF SetImageMaskColor(COLORREF clrMask) + { + COLORREF clrOld = m_clrMask; + m_clrMask = clrMask; + return clrOld; + } + + bool GetImagesVisible() const + { + return m_bImagesVisible; + } + + bool SetImagesVisible(bool bVisible) + { + bool bOld = m_bImagesVisible; + m_bImagesVisible = bVisible; + return bOld; + } + + void GetImageSize(SIZE& size) const + { + size = m_szBitmap; + } + + bool SetImageSize(SIZE& size) + { + return SetImageSize(size.cx, size.cy); + } + + bool SetImageSize(int cx, int cy) + { + if(m_hImageList != NULL) + { + if(::ImageList_GetImageCount(m_hImageList) == 0) // empty + { + ::ImageList_Destroy(m_hImageList); + m_hImageList = NULL; + } + else + { + return false; // can't set, image list exists + } + } + + if(cx == 0 || cy == 0) + return false; + + m_szBitmap.cx = cx; + m_szBitmap.cy = cy; + m_szButton.cx = m_szBitmap.cx + 2 * s_kcxButtonMargin; + m_szButton.cy = m_szBitmap.cy + 2 * s_kcyButtonMargin; + + return true; + } + + bool GetAlphaImages() const + { + return m_bAlphaImages; + } + + bool SetAlphaImages(bool bAlphaImages) + { + if(m_hImageList != NULL) + { + if(::ImageList_GetImageCount(m_hImageList) == 0) // empty + { + ::ImageList_Destroy(m_hImageList); + m_hImageList = NULL; + } + else + { + return false; // can't set, image list exists + } + } + + m_bAlphaImages = bAlphaImages; + return true; + } + + HWND GetCmdBar() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HWND)::SendMessage(m_hWnd, CBRM_GETCMDBAR, 0, 0L); + } + +// Methods + HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + UINT nID = 0, LPVOID lpCreateParam = NULL) + { + // These styles are required for command bars + dwStyle |= TBSTYLE_LIST | TBSTYLE_FLAT; +#if (_MSC_VER >= 1300) + return ATL::CWindowImpl< T, TBase, TWinTraits >::Create(hWndParent, rcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam); +#else // !(_MSC_VER >= 1300) + typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass; + return _baseClass::Create(hWndParent, rcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam); +#endif // !(_MSC_VER >= 1300) + } + + BOOL AttachToWindow(HWND hWnd) + { + ATLASSERT(m_hWnd == NULL); + ATLASSERT(::IsWindow(hWnd)); + BOOL bRet = SubclassWindow(hWnd); + if(bRet) + { + m_bAttachedMenu = true; + T* pT = static_cast(this); + pT->GetSystemSettings(); + } + return bRet; + } + + BOOL LoadMenu(ATL::_U_STRINGorID menu) + { + ATLASSERT(::IsWindow(m_hWnd)); + + if(m_bAttachedMenu) // doesn't work in this mode + return FALSE; + if(menu.m_lpstr == NULL) + return FALSE; + + HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), menu.m_lpstr); + if(hMenu == NULL) + return FALSE; + + return AttachMenu(hMenu); + } + + BOOL AttachMenu(HMENU hMenu) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hMenu == NULL || ::IsMenu(hMenu)); + if(hMenu != NULL && !::IsMenu(hMenu)) + return FALSE; + +#if _WTL_CMDBAR_VISTA_MENUS + // remove Vista bitmaps if used + if(m_bVistaMenus && (m_hMenu != NULL)) + { + T* pT = static_cast(this); + pT->_RemoveVistaBitmapsFromMenu(); + } +#endif // _WTL_CMDBAR_VISTA_MENUS + + // destroy old menu, if needed, and set new one + if(m_hMenu != NULL && (m_dwExtendedStyle & CBR_EX_SHAREMENU) == 0) + ::DestroyMenu(m_hMenu); + + m_hMenu = hMenu; + + if(m_bAttachedMenu) // Nothing else in this mode + return TRUE; + + // Build buttons according to menu + SetRedraw(FALSE); + + // Clear all buttons + int nCount = GetButtonCount(); + for(int i = 0; i < nCount; i++) + ATLVERIFY(DeleteButton(0) != FALSE); + + // Add buttons for each menu item + if(m_hMenu != NULL) + { + int nItems = ::GetMenuItemCount(m_hMenu); + + T* pT = static_cast(this); + pT; // avoid level 4 warning + TCHAR szString[pT->_nMaxMenuItemTextLength]; + for(int i = 0; i < nItems; i++) + { + CMenuItemInfo mii; + mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU; + mii.fType = MFT_STRING; + mii.dwTypeData = szString; + mii.cch = pT->_nMaxMenuItemTextLength; + BOOL bRet = ::GetMenuItemInfo(m_hMenu, i, TRUE, &mii); + ATLASSERT(bRet); + // If we have more than the buffer, we assume we have bitmaps bits + if(lstrlen(szString) > pT->_nMaxMenuItemTextLength - 1) + { + mii.fType = MFT_BITMAP; + ::SetMenuItemInfo(m_hMenu, i, TRUE, &mii); + szString[0] = 0; + } + + // NOTE: Command Bar currently supports only drop-down menu items + ATLASSERT(mii.hSubMenu != NULL); + + TBBUTTON btn = { 0 }; + btn.iBitmap = 0; + btn.idCommand = i; + btn.fsState = (BYTE)(((mii.fState & MFS_DISABLED) == 0) ? TBSTATE_ENABLED : 0); + btn.fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE | TBSTYLE_DROPDOWN; + btn.dwData = 0; + btn.iString = 0; + + bRet = InsertButton(-1, &btn); + ATLASSERT(bRet); + + TBBUTTONINFO bi = { 0 }; + bi.cbSize = sizeof(TBBUTTONINFO); + bi.dwMask = TBIF_TEXT; + bi.pszText = szString; + + bRet = SetButtonInfo(i, &bi); + ATLASSERT(bRet); + } + } + + SetRedraw(TRUE); + Invalidate(); + UpdateWindow(); + + return TRUE; + } + + BOOL LoadImages(ATL::_U_STRINGorID image) + { + return _LoadImagesHelper(image, false); + } + + BOOL LoadMappedImages(UINT nIDImage, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0) + { + return _LoadImagesHelper(nIDImage, true, nFlags , lpColorMap, nMapSize); + } + + BOOL _LoadImagesHelper(ATL::_U_STRINGorID image, bool bMapped, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + HINSTANCE hInstance = ModuleHelper::GetResourceInstance(); + + HRSRC hRsrc = ::FindResource(hInstance, image.m_lpstr, (LPTSTR)RT_TOOLBAR); + if(hRsrc == NULL) + return FALSE; + + HGLOBAL hGlobal = ::LoadResource(hInstance, hRsrc); + if(hGlobal == NULL) + return FALSE; + + _ToolBarData* pData = (_ToolBarData*)::LockResource(hGlobal); + if(pData == NULL) + return FALSE; + ATLASSERT(pData->wVersion == 1); + + WORD* pItems = pData->items(); + int nItems = pData->wItemCount; + + // Set internal data + SetImageSize(pData->wWidth, pData->wHeight); + + // Create image list if needed + if(m_hImageList == NULL) + { + // Check if the bitmap is 32-bit (alpha channel) bitmap (valid for Windows XP only) + T* pT = static_cast(this); + m_bAlphaImages = AtlIsAlphaBitmapResource(image); + + if(!pT->CreateInternalImageList(pData->wItemCount)) + return FALSE; + } + +#if _WTL_CMDBAR_VISTA_MENUS + int nOldImageCount = ::ImageList_GetImageCount(m_hImageList); +#endif // _WTL_CMDBAR_VISTA_MENUS + + // Add bitmap to our image list + CBitmap bmp; + if(bMapped) + { + ATLASSERT(HIWORD(PtrToUlong(image.m_lpstr)) == 0); // if mapped, must be a numeric ID + int nIDImage = (int)(short)LOWORD(PtrToUlong(image.m_lpstr)); + bmp.LoadMappedBitmap(nIDImage, (WORD)nFlags, lpColorMap, nMapSize); + } + else + { + if(m_bAlphaImages) + bmp = (HBITMAP)::LoadImage(ModuleHelper::GetResourceInstance(), image.m_lpstr, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE); + else + bmp.LoadBitmap(image.m_lpstr); + } + ATLASSERT(bmp.m_hBitmap != NULL); + if(bmp.m_hBitmap == NULL) + return FALSE; + if(::ImageList_AddMasked(m_hImageList, bmp, m_clrMask) == -1) + return FALSE; + + // Fill the array with command IDs + for(int i = 0; i < nItems; i++) + { + if(pItems[i] != 0) + m_arrCommand.Add(pItems[i]); + } + + int nImageCount = ::ImageList_GetImageCount(m_hImageList); + ATLASSERT(nImageCount == m_arrCommand.GetSize()); + if(nImageCount != m_arrCommand.GetSize()) + return FALSE; + +#if _WTL_CMDBAR_VISTA_MENUS + if(RunTimeHelper::IsVista()) + { + T* pT = static_cast(this); + pT->_AddVistaBitmapsFromImageList(nOldImageCount, nImageCount - nOldImageCount); + ATLASSERT(nImageCount == m_arrVistaBitmap.GetSize()); + } +#endif // _WTL_CMDBAR_VISTA_MENUS + + return TRUE; + } + + BOOL AddBitmap(ATL::_U_STRINGorID bitmap, int nCommandID) + { + ATLASSERT(::IsWindow(m_hWnd)); + CBitmap bmp; + bmp.LoadBitmap(bitmap.m_lpstr); + if(bmp.m_hBitmap == NULL) + return FALSE; + return AddBitmap(bmp, nCommandID); + } + + BOOL AddBitmap(HBITMAP hBitmap, UINT nCommandID) + { + ATLASSERT(::IsWindow(m_hWnd)); + T* pT = static_cast(this); + // Create image list if it doesn't exist + if(m_hImageList == NULL) + { + if(!pT->CreateInternalImageList(1)) + return FALSE; + } + // check bitmap size + CBitmapHandle bmp = hBitmap; + SIZE size = { 0, 0 }; + bmp.GetSize(size); + if(size.cx != m_szBitmap.cx || size.cy != m_szBitmap.cy) + { + ATLASSERT(FALSE); // must match size! + return FALSE; + } + // add bitmap + int nRet = ::ImageList_AddMasked(m_hImageList, hBitmap, m_clrMask); + if(nRet == -1) + return FALSE; + BOOL bRet = m_arrCommand.Add((WORD)nCommandID); + ATLASSERT(::ImageList_GetImageCount(m_hImageList) == m_arrCommand.GetSize()); +#if _WTL_CMDBAR_VISTA_MENUS + if(RunTimeHelper::IsVista()) + { + pT->_AddVistaBitmapFromImageList(m_arrCommand.GetSize() - 1); + ATLASSERT(m_arrVistaBitmap.GetSize() == m_arrCommand.GetSize()); + } +#endif // _WTL_CMDBAR_VISTA_MENUS + return bRet; + } + + BOOL AddIcon(ATL::_U_STRINGorID icon, UINT nCommandID) + { + ATLASSERT(::IsWindow(m_hWnd)); + HICON hIcon = ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr); + if(hIcon == NULL) + return FALSE; + return AddIcon(hIcon, nCommandID); + } + + BOOL AddIcon(HICON hIcon, UINT nCommandID) + { + ATLASSERT(::IsWindow(m_hWnd)); + T* pT = static_cast(this); + // create image list if it doesn't exist + if(m_hImageList == NULL) + { + if(!pT->CreateInternalImageList(1)) + return FALSE; + } + + int nRet = ::ImageList_AddIcon(m_hImageList, hIcon); + if(nRet == -1) + return FALSE; + BOOL bRet = m_arrCommand.Add((WORD)nCommandID); + ATLASSERT(::ImageList_GetImageCount(m_hImageList) == m_arrCommand.GetSize()); +#if _WTL_CMDBAR_VISTA_MENUS + if(RunTimeHelper::IsVista()) + { + pT->_AddVistaBitmapFromImageList(m_arrCommand.GetSize() - 1); + ATLASSERT(m_arrVistaBitmap.GetSize() == m_arrCommand.GetSize()); + } +#endif // _WTL_CMDBAR_VISTA_MENUS + return bRet; + } + + BOOL ReplaceBitmap(ATL::_U_STRINGorID bitmap, int nCommandID) + { + ATLASSERT(::IsWindow(m_hWnd)); + CBitmap bmp; + bmp.LoadBitmap(bitmap.m_lpstr); + if(bmp.m_hBitmap == NULL) + return FALSE; + return ReplaceBitmap(bmp, nCommandID); + } + + BOOL ReplaceBitmap(HBITMAP hBitmap, UINT nCommandID) + { + ATLASSERT(::IsWindow(m_hWnd)); + BOOL bRet = FALSE; + for(int i = 0; i < m_arrCommand.GetSize(); i++) + { + if(m_arrCommand[i] == nCommandID) + { + bRet = ::ImageList_Remove(m_hImageList, i); + if(bRet) + { + m_arrCommand.RemoveAt(i); +#if _WTL_CMDBAR_VISTA_MENUS + if(RunTimeHelper::IsVista()) + { + if(m_arrVistaBitmap[i] != NULL) + ::DeleteObject(m_arrVistaBitmap[i]); + m_arrVistaBitmap.RemoveAt(i); + } +#endif // _WTL_CMDBAR_VISTA_MENUS + } + break; + } + } + if(bRet) + bRet = AddBitmap(hBitmap, nCommandID); + return bRet; + } + + BOOL ReplaceIcon(ATL::_U_STRINGorID icon, UINT nCommandID) + { + ATLASSERT(::IsWindow(m_hWnd)); + HICON hIcon = ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr); + if(hIcon == NULL) + return FALSE; + return ReplaceIcon(hIcon, nCommandID); + } + + BOOL ReplaceIcon(HICON hIcon, UINT nCommandID) + { + ATLASSERT(::IsWindow(m_hWnd)); + BOOL bRet = FALSE; + for(int i = 0; i < m_arrCommand.GetSize(); i++) + { + if(m_arrCommand[i] == nCommandID) + { + bRet = (::ImageList_ReplaceIcon(m_hImageList, i, hIcon) != -1); +#if _WTL_CMDBAR_VISTA_MENUS + if(RunTimeHelper::IsVista() && bRet != FALSE) + { + T* pT = static_cast(this); + pT->_ReplaceVistaBitmapFromImageList(i); + } +#endif // _WTL_CMDBAR_VISTA_MENUS + break; + } + } + return bRet; + } + + BOOL RemoveImage(int nCommandID) + { + ATLASSERT(::IsWindow(m_hWnd)); + + BOOL bRet = FALSE; + for(int i = 0; i < m_arrCommand.GetSize(); i++) + { + if(m_arrCommand[i] == nCommandID) + { + bRet = ::ImageList_Remove(m_hImageList, i); + if(bRet) + { + m_arrCommand.RemoveAt(i); +#if _WTL_CMDBAR_VISTA_MENUS + if(RunTimeHelper::IsVista()) + { + if(m_arrVistaBitmap[i] != NULL) + ::DeleteObject(m_arrVistaBitmap[i]); + m_arrVistaBitmap.RemoveAt(i); + } +#endif // _WTL_CMDBAR_VISTA_MENUS + } + break; + } + } + return bRet; + } + + BOOL RemoveAllImages() + { + ATLASSERT(::IsWindow(m_hWnd)); + + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Removing all images\n")); + BOOL bRet = ::ImageList_RemoveAll(m_hImageList); + if(bRet) + { + m_arrCommand.RemoveAll(); +#if _WTL_CMDBAR_VISTA_MENUS + for(int i = 0; i < m_arrVistaBitmap.GetSize(); i++) + { + if(m_arrVistaBitmap[i] != NULL) + ::DeleteObject(m_arrVistaBitmap[i]); + } + m_arrVistaBitmap.RemoveAll(); +#endif // _WTL_CMDBAR_VISTA_MENUS + } + return bRet; + } + + BOOL TrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y, LPTPMPARAMS lpParams = NULL) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(::IsMenu(hMenu)); + if(!::IsMenu(hMenu)) + return FALSE; + m_bContextMenu = true; + if(m_bUseKeyboardCues) + m_bShowKeyboardCues = m_bKeyboardInput; + T* pT = static_cast(this); + return pT->DoTrackPopupMenu(hMenu, uFlags, x, y, lpParams); + } + + BOOL SetMDIClient(HWND /*hWndMDIClient*/) + { + // Use CMDICommandBarCtrl for MDI support + ATLASSERT(FALSE); + return FALSE; + } + +// Message map and handlers + BEGIN_MSG_MAP(CCommandBarCtrlImpl) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) + MESSAGE_HANDLER(WM_INITMENU, OnInitMenu) + MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup) + MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect) + MESSAGE_HANDLER(GetAutoPopupMessage(), OnInternalAutoPopup) + MESSAGE_HANDLER(GetGetBarMessage(), OnInternalGetBar) + MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) + MESSAGE_HANDLER(WM_MENUCHAR, OnMenuChar) + + MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown) + MESSAGE_HANDLER(WM_KEYUP, OnKeyUp) + MESSAGE_HANDLER(WM_CHAR, OnChar) + MESSAGE_HANDLER(WM_SYSKEYDOWN, OnSysKeyDown) + MESSAGE_HANDLER(WM_SYSKEYUP, OnSysKeyUp) + MESSAGE_HANDLER(WM_SYSCHAR, OnSysChar) +// public API handlers - these stay to support chevrons in atlframe.h + MESSAGE_HANDLER(CBRM_GETMENU, OnAPIGetMenu) + MESSAGE_HANDLER(CBRM_TRACKPOPUPMENU, OnAPITrackPopupMenu) + MESSAGE_HANDLER(CBRM_GETCMDBAR, OnAPIGetCmdBar) + + MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem) + MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem) + + MESSAGE_HANDLER(WM_FORWARDMSG, OnForwardMsg) + ALT_MSG_MAP(1) // Parent window messages + NOTIFY_CODE_HANDLER(TBN_HOTITEMCHANGE, OnParentHotItemChange) + NOTIFY_CODE_HANDLER(TBN_DROPDOWN, OnParentDropDown) + MESSAGE_HANDLER(WM_INITMENUPOPUP, OnParentInitMenuPopup) + MESSAGE_HANDLER(GetGetBarMessage(), OnParentInternalGetBar) + MESSAGE_HANDLER(WM_SYSCOMMAND, OnParentSysCommand) + MESSAGE_HANDLER(CBRM_GETMENU, OnParentAPIGetMenu) + MESSAGE_HANDLER(WM_MENUCHAR, OnParentMenuChar) + MESSAGE_HANDLER(CBRM_TRACKPOPUPMENU, OnParentAPITrackPopupMenu) + MESSAGE_HANDLER(CBRM_GETCMDBAR, OnParentAPIGetCmdBar) + MESSAGE_HANDLER(WM_SETTINGCHANGE, OnParentSettingChange) + + MESSAGE_HANDLER(WM_DRAWITEM, OnParentDrawItem) + MESSAGE_HANDLER(WM_MEASUREITEM, OnParentMeasureItem) + + MESSAGE_HANDLER(WM_ACTIVATE, OnParentActivate) + NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnParentCustomDraw) + ALT_MSG_MAP(2) // MDI client window messages + // Use CMDICommandBarCtrl for MDI support + ALT_MSG_MAP(3) // Message hook messages + MESSAGE_HANDLER(WM_MOUSEMOVE, OnHookMouseMove) + MESSAGE_HANDLER(WM_SYSKEYDOWN, OnHookSysKeyDown) + MESSAGE_HANDLER(WM_SYSKEYUP, OnHookSysKeyUp) + MESSAGE_HANDLER(WM_SYSCHAR, OnHookSysChar) + MESSAGE_HANDLER(WM_KEYDOWN, OnHookKeyDown) + MESSAGE_HANDLER(WM_NEXTMENU, OnHookNextMenu) + MESSAGE_HANDLER(WM_CHAR, OnHookChar) + END_MSG_MAP() + + LRESULT OnForwardMsg(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) + { + LPMSG pMsg = (LPMSG)lParam; + if(pMsg->message >= WM_MOUSEFIRST && pMsg->message <= WM_MOUSELAST) + m_bKeyboardInput = false; + else if(pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST) + m_bKeyboardInput = true; + LRESULT lRet = 0; + ProcessWindowMessage(pMsg->hwnd, pMsg->message, pMsg->wParam, pMsg->lParam, lRet, 3); + return lRet; + } + + LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + // Let the toolbar initialize itself + LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); + // get and use system settings + T* pT = static_cast(this); + pT->GetSystemSettings(); + // Parent init + ATL::CWindow wndParent = GetParent(); + ATL::CWindow wndTopLevelParent = wndParent.GetTopLevelParent(); + m_wndParent.SubclassWindow(wndTopLevelParent); + // Toolbar Init + SetButtonStructSize(); + SetImageList(NULL); + + // Create message hook if needed + CWindowCreateCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::OnCreate.\n")); + ATLASSERT(FALSE); + return -1; + } + + if(s_pmapMsgHook == NULL) + { + ATLTRY(s_pmapMsgHook = new CMsgHookMap); + ATLASSERT(s_pmapMsgHook != NULL); + } + + if(s_pmapMsgHook != NULL) + { + DWORD dwThreadID = ::GetCurrentThreadId(); + _MsgHookData* pData = s_pmapMsgHook->Lookup(dwThreadID); + if(pData == NULL) + { + ATLTRY(pData = new _MsgHookData); + ATLASSERT(pData != NULL); + HHOOK hMsgHook = ::SetWindowsHookEx(WH_GETMESSAGE, MessageHookProc, ModuleHelper::GetModuleInstance(), dwThreadID); + ATLASSERT(hMsgHook != NULL); + if(pData != NULL && hMsgHook != NULL) + { + pData->hMsgHook = hMsgHook; + pData->dwUsage = 1; + BOOL bRet = s_pmapMsgHook->Add(dwThreadID, pData); + bRet; + ATLASSERT(bRet); + } + } + else + { + (pData->dwUsage)++; + } + } + lock.Unlock(); + + // Get layout +#if (WINVER >= 0x0500) + m_bLayoutRTL = ((GetExStyle() & WS_EX_LAYOUTRTL) != 0); +#endif // (WINVER >= 0x0500) + + return lRet; + } + + LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); + +#if _WTL_CMDBAR_VISTA_MENUS + if(m_bVistaMenus && (m_hMenu != NULL)) + { + T* pT = static_cast(this); + pT->_RemoveVistaBitmapsFromMenu(); + } + + for(int i = 0; i < m_arrVistaBitmap.GetSize(); i++) + { + if(m_arrVistaBitmap[i] != NULL) + ::DeleteObject(m_arrVistaBitmap[i]); + } +#endif // _WTL_CMDBAR_VISTA_MENUS + + if(m_bAttachedMenu) // nothing to do in this mode + return lRet; + + CWindowCreateCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::OnDestroy.\n")); + ATLASSERT(FALSE); + return lRet; + } + + if(s_pmapMsgHook != NULL) + { + DWORD dwThreadID = ::GetCurrentThreadId(); + _MsgHookData* pData = s_pmapMsgHook->Lookup(dwThreadID); + if(pData != NULL) + { + (pData->dwUsage)--; + if(pData->dwUsage == 0) + { + BOOL bRet = ::UnhookWindowsHookEx(pData->hMsgHook); + ATLASSERT(bRet); + bRet = s_pmapMsgHook->Remove(dwThreadID); + ATLASSERT(bRet); + if(bRet) + delete pData; + } + + if(s_pmapMsgHook->GetSize() == 0) + { + delete s_pmapMsgHook; + s_pmapMsgHook = NULL; + } + } + } + + lock.Unlock(); + + return lRet; + } + + LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnKeyDown\n")); +#endif + bHandled = FALSE; + // Simulate Alt+Space for the parent + if(wParam == VK_SPACE) + { + m_wndParent.PostMessage(WM_SYSKEYDOWN, wParam, lParam | (1 << 29)); + bHandled = TRUE; + } +#if (_WIN32_IE >= 0x0500) + else if(wParam == VK_LEFT || wParam == VK_RIGHT) + { + WPARAM wpNext = m_bLayoutRTL ? VK_LEFT : VK_RIGHT; + + if(!m_bMenuActive) + { + T* pT = static_cast(this); + int nBtn = GetHotItem(); + int nNextBtn = (wParam == wpNext) ? pT->GetNextMenuItem(nBtn) : pT->GetPreviousMenuItem(nBtn); + if(nNextBtn == -2) + { + SetHotItem(-1); + if(pT->DisplayChevronMenu()) + bHandled = TRUE; + } + } + } +#endif // (_WIN32_IE >= 0x0500) + return 0; + } + + LRESULT OnKeyUp(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnKeyUp\n")); +#endif + if(wParam != VK_SPACE) + bHandled = FALSE; + return 0; + } + + LRESULT OnChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnChar\n")); +#endif + if(wParam != VK_SPACE) + bHandled = FALSE; + else + return 0; + // Security + if(!m_wndParent.IsWindowEnabled() || ::GetFocus() != m_hWnd) + return 0; + + // Handle mnemonic press when we have focus + int nBtn = 0; + if(wParam != VK_RETURN && !MapAccelerator((TCHAR)LOWORD(wParam), nBtn)) + { +#if (_WIN32_IE >= 0x0500) + if((TCHAR)LOWORD(wParam) != _chChevronShortcut) +#endif // (_WIN32_IE >= 0x0500) + ::MessageBeep(0); + } + else + { +#if (_WIN32_IE >= 0x0500) + RECT rcClient = { 0 }; + GetClientRect(&rcClient); + RECT rcBtn = { 0 }; + GetItemRect(nBtn, &rcBtn); + TBBUTTON tbb = { 0 }; + GetButton(nBtn, &tbb); + if((tbb.fsState & TBSTATE_ENABLED) != 0 && (tbb.fsState & TBSTATE_HIDDEN) == 0 && rcBtn.right <= rcClient.right) + { +#endif // (_WIN32_IE >= 0x0500) + PostMessage(WM_KEYDOWN, VK_DOWN, 0L); + if(wParam != VK_RETURN) + SetHotItem(nBtn); +#if (_WIN32_IE >= 0x0500) + } + else + { + ::MessageBeep(0); + bHandled = TRUE; + } +#endif // (_WIN32_IE >= 0x0500) + } + return 0; + } + + LRESULT OnSysKeyDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnSysKeyDown\n")); +#endif + bHandled = FALSE; + return 0; + } + + LRESULT OnSysKeyUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnSysKeyUp\n")); +#endif + bHandled = FALSE; + return 0; + } + + LRESULT OnSysChar(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnSysChar\n")); +#endif + bHandled = FALSE; + return 0; + } + + LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_bAttachedMenu || (m_dwExtendedStyle & CBR_EX_TRANSPARENT)) + { + bHandled = FALSE; + return 0; + } + + CDCHandle dc = (HDC)wParam; + RECT rect = { 0 }; + GetClientRect(&rect); + dc.FillRect(&rect, COLOR_MENU); + + return 1; // don't do the default erase + } + + LRESULT OnInitMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + int nIndex = GetHotItem(); + SendMessage(WM_MENUSELECT, MAKEWPARAM(nIndex, MF_POPUP|MF_HILITE), (LPARAM)m_hMenu); + bHandled = FALSE; + return 1; + } + + LRESULT OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + if((BOOL)HIWORD(lParam)) // System menu, do nothing + { + bHandled = FALSE; + return 1; + } + + if(!(m_bAttachedMenu || m_bMenuActive)) // Not attached or ours, do nothing + { + bHandled = FALSE; + return 1; + } + +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnInitMenuPopup\n")); +#endif + // forward to the parent or subclassed window, so it can handle update UI + LRESULT lRet = 0; + if(m_bAttachedMenu) + lRet = DefWindowProc(uMsg, wParam, (lParam || m_bContextMenu) ? lParam : GetHotItem()); + else + lRet = m_wndParent.DefWindowProc(uMsg, wParam, (lParam || m_bContextMenu) ? lParam : GetHotItem()); + +#if _WTL_CMDBAR_VISTA_MENUS + // If Vista menus are active, just set bitmaps and return + if(m_bVistaMenus) + { + CMenuHandle menu = (HMENU)wParam; + ATLASSERT(menu.m_hMenu != NULL); + + for(int i = 0; i < menu.GetMenuItemCount(); i++) + { + WORD nID = (WORD)menu.GetMenuItemID(i); + int nIndex = m_arrCommand.Find(nID); + + CMenuItemInfo mii; + mii.fMask = MIIM_BITMAP; + mii.hbmpItem = (m_bImagesVisible && (nIndex != -1)) ? m_arrVistaBitmap[nIndex] : NULL; + menu.SetMenuItemInfo(i, TRUE, &mii); + } + + return lRet; + } +#endif // _WTL_CMDBAR_VISTA_MENUS + + // Convert menu items to ownerdraw, add our data + if(m_bImagesVisible) + { + CMenuHandle menuPopup = (HMENU)wParam; + ATLASSERT(menuPopup.m_hMenu != NULL); + + T* pT = static_cast(this); + pT; // avoid level 4 warning + TCHAR szString[pT->_nMaxMenuItemTextLength]; + BOOL bRet = FALSE; + for(int i = 0; i < menuPopup.GetMenuItemCount(); i++) + { + CMenuItemInfo mii; + mii.cch = pT->_nMaxMenuItemTextLength; + mii.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE; + mii.dwTypeData = szString; + bRet = menuPopup.GetMenuItemInfo(i, TRUE, &mii); + ATLASSERT(bRet); + + if(!(mii.fType & MFT_OWNERDRAW)) // Not already an ownerdraw item + { + mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_STATE; + _MenuItemData* pMI = NULL; + ATLTRY(pMI = new _MenuItemData); + ATLASSERT(pMI != NULL); + if(pMI != NULL) + { + pMI->fType = mii.fType; + pMI->fState = mii.fState; + mii.fType |= MFT_OWNERDRAW; + pMI->iButton = -1; + for(int j = 0; j < m_arrCommand.GetSize(); j++) + { + if(m_arrCommand[j] == mii.wID) + { + pMI->iButton = j; + break; + } + } + int cchLen = lstrlen(szString) + 1; + pMI->lpstrText = NULL; + ATLTRY(pMI->lpstrText = new TCHAR[cchLen]); + ATLASSERT(pMI->lpstrText != NULL); + if(pMI->lpstrText != NULL) + SecureHelper::strcpy_x(pMI->lpstrText, cchLen, szString); + mii.dwItemData = (ULONG_PTR)pMI; + bRet = menuPopup.SetMenuItemInfo(i, TRUE, &mii); + ATLASSERT(bRet); + } + } + } + + // Add it to the list + m_stackMenuHandle.Push(menuPopup.m_hMenu); + } + + return lRet; + } + + LRESULT OnMenuSelect(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + if(!m_bAttachedMenu) // Not attached, do nothing, forward to parent + { + m_bPopupItem = (lParam != NULL) && ((HMENU)lParam != m_hMenu) && (HIWORD(wParam) & MF_POPUP); + if(m_wndParent.IsWindow()) + m_wndParent.SendMessage(uMsg, wParam, lParam); + bHandled = FALSE; + return 1; + } + + // Check if a menu is closing, do a cleanup + if(HIWORD(wParam) == 0xFFFF && lParam == NULL) // Menu closing + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnMenuSelect - CLOSING!!!!\n")); +#endif + ATLASSERT(m_stackMenuWnd.GetSize() == 0); + // Restore the menu items to the previous state for all menus that were converted + if(m_bImagesVisible) + { + HMENU hMenu = NULL; + while((hMenu = m_stackMenuHandle.Pop()) != NULL) + { + CMenuHandle menuPopup = hMenu; + ATLASSERT(menuPopup.m_hMenu != NULL); + // Restore state and delete menu item data + BOOL bRet = FALSE; + for(int i = 0; i < menuPopup.GetMenuItemCount(); i++) + { + CMenuItemInfo mii; + mii.fMask = MIIM_DATA | MIIM_TYPE; + bRet = menuPopup.GetMenuItemInfo(i, TRUE, &mii); + ATLASSERT(bRet); + + _MenuItemData* pMI = (_MenuItemData*)mii.dwItemData; + if(pMI != NULL && pMI->IsCmdBarMenuItem()) + { + mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_STATE; + mii.fType = pMI->fType; + mii.dwTypeData = pMI->lpstrText; + mii.cch = lstrlen(pMI->lpstrText); + mii.dwItemData = NULL; + + bRet = menuPopup.SetMenuItemInfo(i, TRUE, &mii); + ATLASSERT(bRet); + + delete [] pMI->lpstrText; + pMI->dwMagic = 0x6666; + delete pMI; + } + } + } + } + } + + bHandled = FALSE; + return 1; + } + + LRESULT OnInternalAutoPopup(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + int nIndex = (int)wParam; + T* pT = static_cast(this); + pT->DoPopupMenu(nIndex, false); + return 0; + } + + LRESULT OnInternalGetBar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + // Let's make sure we're not embedded in another process + if((LPVOID)wParam != NULL) + *((DWORD*)wParam) = GetCurrentProcessId(); + if(IsWindowVisible()) + return (LRESULT)static_cast(this); + else + return NULL; + } + + LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { +#ifndef SPI_GETKEYBOARDCUES + const UINT SPI_SETKEYBOARDCUES = 0x100B; +#endif // !SPI_GETKEYBOARDCUES +#ifndef SPI_GETFLATMENU + const UINT SPI_SETFLATMENU = 0x1023; +#endif // !SPI_GETFLATMENU + + if(wParam == SPI_SETNONCLIENTMETRICS || wParam == SPI_SETKEYBOARDCUES || wParam == SPI_SETFLATMENU) + { + T* pT = static_cast(this); + pT->GetSystemSettings(); + } + + return 0; + } + + LRESULT OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); + + LPWINDOWPOS lpWP = (LPWINDOWPOS)lParam; + int cyMin = ::GetSystemMetrics(SM_CYMENU); + if(lpWP->cy < cyMin) + lpWP->cy = cyMin; + + return lRet; + } + + LRESULT OnMenuChar(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - OnMenuChar\n")); +#endif + bHandled = TRUE; + T* pT = static_cast(this); + + LRESULT lRet; + if(m_bMenuActive && LOWORD(wParam) != 0x0D) + lRet = 0; + else + lRet = MAKELRESULT(1, 1); + + if(m_bMenuActive && HIWORD(wParam) == MF_POPUP) + { + // Convert character to lower/uppercase and possibly Unicode, using current keyboard layout + TCHAR ch = (TCHAR)LOWORD(wParam); + CMenuHandle menu = (HMENU)lParam; + int nCount = ::GetMenuItemCount(menu); + int nRetCode = MNC_EXECUTE; + BOOL bRet = FALSE; + TCHAR szString[pT->_nMaxMenuItemTextLength]; + WORD wMnem = 0; + bool bFound = false; + for(int i = 0; i < nCount; i++) + { + CMenuItemInfo mii; + mii.cch = pT->_nMaxMenuItemTextLength; + mii.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE; + mii.dwTypeData = szString; + bRet = menu.GetMenuItemInfo(i, TRUE, &mii); + if(!bRet || (mii.fType & MFT_SEPARATOR)) + continue; + _MenuItemData* pmd = (_MenuItemData*)mii.dwItemData; + if(pmd != NULL && pmd->IsCmdBarMenuItem()) + { + LPTSTR p = pmd->lpstrText; + + if(p != NULL) + { + while(*p && *p != _T('&')) + p = ::CharNext(p); + if(p != NULL && *p) + { + DWORD dwP = MAKELONG(*(++p), 0); + DWORD dwC = MAKELONG(ch, 0); + if(::CharLower((LPTSTR)ULongToPtr(dwP)) == ::CharLower((LPTSTR)ULongToPtr(dwC))) + { + if(!bFound) + { + wMnem = (WORD)i; + bFound = true; + } + else + { + nRetCode = MNC_SELECT; + break; + } + } + } + } + } + } + if(bFound) + { + if(nRetCode == MNC_EXECUTE) + { + PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L); + pT->GiveFocusBack(); + } + bHandled = TRUE; + lRet = MAKELRESULT(wMnem, nRetCode); + } + } + else if(!m_bMenuActive) + { + int nBtn = 0; + if(!MapAccelerator((TCHAR)LOWORD(wParam), nBtn)) + { + bHandled = FALSE; + PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L); + pT->GiveFocusBack(); + +#if (_WIN32_IE >= 0x0500) + // check if we should display chevron menu + if((TCHAR)LOWORD(wParam) == pT->_chChevronShortcut) + { + if(pT->DisplayChevronMenu()) + bHandled = TRUE; + } +#endif // (_WIN32_IE >= 0x0500) + } + else if(m_wndParent.IsWindowEnabled()) + { +#if (_WIN32_IE >= 0x0500) + RECT rcClient = { 0 }; + GetClientRect(&rcClient); + RECT rcBtn = { 0 }; + GetItemRect(nBtn, &rcBtn); + TBBUTTON tbb = { 0 }; + GetButton(nBtn, &tbb); + if((tbb.fsState & TBSTATE_ENABLED) != 0 && (tbb.fsState & TBSTATE_HIDDEN) == 0 && rcBtn.right <= rcClient.right) + { +#endif // (_WIN32_IE >= 0x0500) + if(m_bUseKeyboardCues && !m_bShowKeyboardCues) + { + m_bAllowKeyboardCues = true; + ShowKeyboardCues(true); + } + pT->TakeFocus(); + PostMessage(WM_KEYDOWN, VK_DOWN, 0L); + SetHotItem(nBtn); +#if (_WIN32_IE >= 0x0500) + } + else + { + ::MessageBeep(0); + } +#endif // (_WIN32_IE >= 0x0500) + } + } + + return lRet; + } + + LRESULT OnDrawItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + LPDRAWITEMSTRUCT lpDrawItemStruct = (LPDRAWITEMSTRUCT)lParam; + _MenuItemData* pmd = (_MenuItemData*)lpDrawItemStruct->itemData; + if(lpDrawItemStruct->CtlType == ODT_MENU && pmd != NULL && pmd->IsCmdBarMenuItem()) + { + T* pT = static_cast(this); + pT->DrawItem(lpDrawItemStruct); + } + else + { + bHandled = FALSE; + } + return (LRESULT)TRUE; + } + + LRESULT OnMeasureItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + LPMEASUREITEMSTRUCT lpMeasureItemStruct = (LPMEASUREITEMSTRUCT)lParam; + _MenuItemData* pmd = (_MenuItemData*)lpMeasureItemStruct->itemData; + if(lpMeasureItemStruct->CtlType == ODT_MENU && pmd != NULL && pmd->IsCmdBarMenuItem()) + { + T* pT = static_cast(this); + pT->MeasureItem(lpMeasureItemStruct); + } + else + { + bHandled = FALSE; + } + return (LRESULT)TRUE; + } + +// API message handlers + LRESULT OnAPIGetMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return (LRESULT)m_hMenu; + } + + LRESULT OnAPITrackPopupMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) + { + if(lParam == NULL) + return FALSE; + LPCBRPOPUPMENU lpCBRPopupMenu = (LPCBRPOPUPMENU)lParam; + if(lpCBRPopupMenu->cbSize != sizeof(CBRPOPUPMENU)) + return FALSE; + + T* pT = static_cast(this); + return pT->TrackPopupMenu(lpCBRPopupMenu->hMenu, lpCBRPopupMenu->uFlags, lpCBRPopupMenu->x, lpCBRPopupMenu->y, lpCBRPopupMenu->lptpm); + } + + LRESULT OnAPIGetCmdBar(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return (LRESULT)m_hWnd; + } + +// Parent window message handlers + LRESULT OnParentHotItemChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) + { + LPNMTBHOTITEM lpNMHT = (LPNMTBHOTITEM)pnmh; + + // Check if this comes from us + if(pnmh->hwndFrom != m_hWnd) + { + bHandled = FALSE; + return 0; + } + + bool bBlockTracking = false; + if((m_dwExtendedStyle & CBR_EX_TRACKALWAYS) == 0) + { + DWORD dwProcessID; + ::GetWindowThreadProcessId(::GetActiveWindow(), &dwProcessID); + bBlockTracking = (::GetCurrentProcessId() != dwProcessID); + } + + if((!m_wndParent.IsWindowEnabled() || bBlockTracking) && (lpNMHT->dwFlags & HICF_MOUSE)) + { + return 1; + } + else + { +#ifndef HICF_LMOUSE + const DWORD HICF_LMOUSE = 0x00000080; // left mouse button selected +#endif + bHandled = FALSE; + + // Send WM_MENUSELECT to the app if it needs to display a status text + if(!(lpNMHT->dwFlags & HICF_MOUSE) + && !(lpNMHT->dwFlags & HICF_ACCELERATOR) + && !(lpNMHT->dwFlags & HICF_LMOUSE)) + { + if(lpNMHT->dwFlags & HICF_ENTERING) + m_wndParent.SendMessage(WM_MENUSELECT, 0, (LPARAM)m_hMenu); + if(lpNMHT->dwFlags & HICF_LEAVING) + m_wndParent.SendMessage(WM_MENUSELECT, MAKEWPARAM(0, 0xFFFF), NULL); + } + + return 0; + } + } + + LRESULT OnParentDropDown(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) + { + // Check if this comes from us + if(pnmh->hwndFrom != m_hWnd) + { + bHandled = FALSE; + return 1; + } + + T* pT = static_cast(this); + if(::GetFocus() != m_hWnd) + pT->TakeFocus(); + LPNMTOOLBAR pNMToolBar = (LPNMTOOLBAR)pnmh; + int nIndex = CommandToIndex(pNMToolBar->iItem); + m_bContextMenu = false; + m_bEscapePressed = false; + pT->DoPopupMenu(nIndex, true); + + return TBDDRET_DEFAULT; + } + + LRESULT OnParentInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + return OnInitMenuPopup(uMsg, wParam, lParam, bHandled); + } + + LRESULT OnParentInternalGetBar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + return OnInternalGetBar(uMsg, wParam, lParam, bHandled); + } + + LRESULT OnParentSysCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + bHandled = FALSE; + if((m_uSysKey == VK_MENU + || (m_uSysKey == VK_F10 && !(::GetKeyState(VK_SHIFT) & 0x80)) + || m_uSysKey == VK_SPACE) + && wParam == SC_KEYMENU) + { + T* pT = static_cast(this); + if(::GetFocus() == m_hWnd) + { + pT->GiveFocusBack(); // exit menu "loop" + PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L); + } + else if(m_uSysKey != VK_SPACE && !m_bSkipMsg) + { + if(m_bUseKeyboardCues && !m_bShowKeyboardCues && m_bAllowKeyboardCues) + ShowKeyboardCues(true); + + pT->TakeFocus(); // enter menu "loop" + bHandled = TRUE; + } + else if(m_uSysKey != VK_SPACE) + { + bHandled = TRUE; + } + } + m_bSkipMsg = false; + return 0; + } + + LRESULT OnParentAPIGetMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + return OnAPIGetMenu(uMsg, wParam, lParam, bHandled); + } + + LRESULT OnParentMenuChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + return OnMenuChar(uMsg, wParam, lParam, bHandled); + } + + LRESULT OnParentAPITrackPopupMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + return OnAPITrackPopupMenu(uMsg, wParam, lParam, bHandled); + } + + LRESULT OnParentAPIGetCmdBar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + return OnAPIGetCmdBar(uMsg, wParam, lParam, bHandled); + } + + LRESULT OnParentSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + OnSettingChange(uMsg, wParam, lParam, bHandled); + bHandled = FALSE; + return 1; + } + + LRESULT OnParentDrawItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + return OnDrawItem(uMsg, wParam, lParam, bHandled); + } + + LRESULT OnParentMeasureItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + return OnMeasureItem(uMsg, wParam, lParam, bHandled); + } + + LRESULT OnParentActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + m_bParentActive = (LOWORD(wParam) != WA_INACTIVE); + if(!m_bParentActive && m_bUseKeyboardCues && m_bShowKeyboardCues) + { + ShowKeyboardCues(false); // this will repaint our window + } + else + { + Invalidate(); + UpdateWindow(); + } + bHandled = FALSE; + return 1; + } + + LRESULT OnParentCustomDraw(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) + { + LRESULT lRet = CDRF_DODEFAULT; + bHandled = FALSE; + if(pnmh->hwndFrom == m_hWnd) + { + LPNMTBCUSTOMDRAW lpTBCustomDraw = (LPNMTBCUSTOMDRAW)pnmh; + if(lpTBCustomDraw->nmcd.dwDrawStage == CDDS_PREPAINT) + { + lRet = CDRF_NOTIFYITEMDRAW; + bHandled = TRUE; + } + else if(lpTBCustomDraw->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) + { + if(m_bFlatMenus) + { +#ifndef COLOR_MENUHILIGHT + const int COLOR_MENUHILIGHT = 29; +#endif // !COLOR_MENUHILIGHT + bool bDisabled = ((lpTBCustomDraw->nmcd.uItemState & CDIS_DISABLED) == CDIS_DISABLED); + if(!bDisabled && ((lpTBCustomDraw->nmcd.uItemState & CDIS_HOT) == CDIS_HOT || + (lpTBCustomDraw->nmcd.uItemState & CDIS_SELECTED) == CDIS_SELECTED)) + { + ::FillRect(lpTBCustomDraw->nmcd.hdc, &lpTBCustomDraw->nmcd.rc, ::GetSysColorBrush(COLOR_MENUHILIGHT)); + ::FrameRect(lpTBCustomDraw->nmcd.hdc, &lpTBCustomDraw->nmcd.rc, ::GetSysColorBrush(COLOR_HIGHLIGHT)); + lpTBCustomDraw->clrText = ::GetSysColor(m_bParentActive ? COLOR_HIGHLIGHTTEXT : COLOR_GRAYTEXT); + } + else if(bDisabled || !m_bParentActive) + { + lpTBCustomDraw->clrText = ::GetSysColor(COLOR_GRAYTEXT); + } + CDCHandle dc = lpTBCustomDraw->nmcd.hdc; + dc.SetTextColor(lpTBCustomDraw->clrText); + dc.SetBkMode(lpTBCustomDraw->nStringBkMode); + HFONT hFont = GetFont(); + HFONT hFontOld = NULL; + if(hFont != NULL) + hFontOld = dc.SelectFont(hFont); + const int cchText = 200; + TCHAR szText[cchText] = { 0 }; + TBBUTTONINFO tbbi = { 0 }; + tbbi.cbSize = sizeof(TBBUTTONINFO); + tbbi.dwMask = TBIF_TEXT; + tbbi.pszText = szText; + tbbi.cchText = cchText; + GetButtonInfo((int)lpTBCustomDraw->nmcd.dwItemSpec, &tbbi); + dc.DrawText(szText, -1, &lpTBCustomDraw->nmcd.rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER | (m_bShowKeyboardCues ? 0 : DT_HIDEPREFIX)); + if(hFont != NULL) + dc.SelectFont(hFontOld); + lRet = CDRF_SKIPDEFAULT; + bHandled = TRUE; + } + else if(!m_bParentActive) + { + lpTBCustomDraw->clrText = ::GetSysColor(COLOR_GRAYTEXT); + bHandled = TRUE; + } + } + } + return lRet; + } + +// Message hook handlers + LRESULT OnHookMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + static POINT s_point = { -1, -1 }; + DWORD dwPoint = ::GetMessagePos(); + POINT point = { GET_X_LPARAM(dwPoint), GET_Y_LPARAM(dwPoint) }; + + bHandled = FALSE; + if(m_bMenuActive) + { + if(::WindowFromPoint(point) == m_hWnd) + { + ScreenToClient(&point); + int nHit = HitTest(&point); + + if((point.x != s_point.x || point.y != s_point.y) && nHit >= 0 && nHit < ::GetMenuItemCount(m_hMenu) && nHit != m_nPopBtn && m_nPopBtn != -1) + { + TBBUTTON tbb = { 0 }; + GetButton(nHit, &tbb); + if((tbb.fsState & TBSTATE_ENABLED) != 0) + { + m_nNextPopBtn = nHit | 0xFFFF0000; + HWND hWndMenu = m_stackMenuWnd.GetCurrent(); + ATLASSERT(hWndMenu != NULL); + + // this one is needed to close a menu if mouse button was down + ::PostMessage(hWndMenu, WM_LBUTTONUP, 0, MAKELPARAM(point.x, point.y)); + // this one closes a popup menu + ::PostMessage(hWndMenu, WM_KEYDOWN, VK_ESCAPE, 0L); + + bHandled = TRUE; + } + } + } + } + else + { + ScreenToClient(&point); + } + + s_point = point; + return 0; + } + + LRESULT OnHookSysKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + bHandled = FALSE; +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_SYSKEYDOWN (0x%2.2X)\n"), wParam); +#endif + + if(wParam == VK_MENU && m_bParentActive && m_bUseKeyboardCues && !m_bShowKeyboardCues && m_bAllowKeyboardCues) + ShowKeyboardCues(true); + + if(wParam != VK_SPACE && !m_bMenuActive && ::GetFocus() == m_hWnd) + { + m_bAllowKeyboardCues = false; + PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L); + T* pT = static_cast(this); + pT->GiveFocusBack(); + m_bSkipMsg = true; + } + else + { + if(wParam == VK_SPACE && m_bUseKeyboardCues && m_bShowKeyboardCues) + { + m_bAllowKeyboardCues = true; + ShowKeyboardCues(false); + } + m_uSysKey = (UINT)wParam; + } + return 0; + } + + LRESULT OnHookSysKeyUp(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if(!m_bAllowKeyboardCues) + m_bAllowKeyboardCues = true; + bHandled = FALSE; + wParam; +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_SYSKEYUP (0x%2.2X)\n"), wParam); +#endif + return 0; + } + + LRESULT OnHookSysChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + bHandled = FALSE; +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_SYSCHAR (0x%2.2X)\n"), wParam); +#endif + + if(!m_bMenuActive && m_hWndHook != m_hWnd && wParam != VK_SPACE) + bHandled = TRUE; + return 0; + } + + LRESULT OnHookKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_KEYDOWN (0x%2.2X)\n"), wParam); +#endif + bHandled = FALSE; + T* pT = static_cast(this); + + if(wParam == VK_ESCAPE && m_stackMenuWnd.GetSize() <= 1) + { + if(m_bMenuActive && !m_bContextMenu) + { + int nHot = GetHotItem(); + if(nHot == -1) + nHot = m_nPopBtn; + if(nHot == -1) + nHot = 0; + SetHotItem(nHot); + bHandled = TRUE; + pT->TakeFocus(); + m_bEscapePressed = true; // To keep focus + m_bSkipPostDown = false; + } + else if(::GetFocus() == m_hWnd && m_wndParent.IsWindow()) + { + SetHotItem(-1); + pT->GiveFocusBack(); + bHandled = TRUE; + } + } + else if(wParam == VK_RETURN || wParam == VK_UP || wParam == VK_DOWN) + { + if(!m_bMenuActive && ::GetFocus() == m_hWnd && m_wndParent.IsWindow()) + { + int nHot = GetHotItem(); + if(nHot != -1) + { + if(wParam != VK_RETURN) + { + if(!m_bSkipPostDown) + { +// IE4 only: WM_KEYDOWN doesn't generate TBN_DROPDOWN, we need to simulate a mouse click +#if (_WIN32_IE < 0x0500) + DWORD dwMajor = 0, dwMinor = 0; + ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor); + if(dwMajor <= 4 || (dwMajor == 5 && dwMinor < 80)) + { + RECT rect; + GetItemRect(nHot, &rect); + PostMessage(WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(rect.left, rect.top)); + } +#endif // (_WIN32_IE < 0x0500) + PostMessage(WM_KEYDOWN, VK_DOWN, 0L); + m_bSkipPostDown = true; + } + else + { + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - skipping posting another VK_DOWN\n")); + m_bSkipPostDown = false; + } + } + } + else + { + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Can't find hot button\n")); + } + } + if(wParam == VK_RETURN && m_bMenuActive) + { + PostMessage(TB_SETHOTITEM, (WPARAM)-1, 0L); + m_nNextPopBtn = -1; + pT->GiveFocusBack(); + } + } + else if(wParam == VK_LEFT || wParam == VK_RIGHT) + { + WPARAM wpNext = m_bLayoutRTL ? VK_LEFT : VK_RIGHT; + WPARAM wpPrev = m_bLayoutRTL ? VK_RIGHT : VK_LEFT; + + if(m_bMenuActive && !m_bContextMenu && !(wParam == wpNext && m_bPopupItem)) + { + bool bAction = false; + if(wParam == wpPrev && s_pCurrentBar->m_stackMenuWnd.GetSize() == 1) + { + m_nNextPopBtn = pT->GetPreviousMenuItem(m_nPopBtn); + if(m_nNextPopBtn != -1) + bAction = true; + } + else if(wParam == wpNext) + { + m_nNextPopBtn = pT->GetNextMenuItem(m_nPopBtn); + if(m_nNextPopBtn != -1) + bAction = true; + } + HWND hWndMenu = m_stackMenuWnd.GetCurrent(); + ATLASSERT(hWndMenu != NULL); + + // Close the popup menu + if(bAction) + { + ::PostMessage(hWndMenu, WM_KEYDOWN, VK_ESCAPE, 0L); + if(wParam == wpNext) + { + int cItem = m_stackMenuWnd.GetSize() - 1; + while(cItem >= 0) + { + hWndMenu = m_stackMenuWnd[cItem]; + if(hWndMenu != NULL) + ::PostMessage(hWndMenu, WM_KEYDOWN, VK_ESCAPE, 0L); + cItem--; + } + } +#if (_WIN32_IE >= 0x0500) + if(m_nNextPopBtn == -2) + { + m_nNextPopBtn = -1; + pT->DisplayChevronMenu(); + } +#endif // (_WIN32_IE >= 0x0500) + bHandled = TRUE; + } + } + } + return 0; + } + + LRESULT OnHookNextMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_NEXTMENU\n")); +#endif + bHandled = FALSE; + return 1; + } + + LRESULT OnHookChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook WM_CHAR (0x%2.2X)\n"), wParam); +#endif + bHandled = (wParam == VK_ESCAPE); + return 0; + } + +// Implementation - ownerdraw overrideables and helpers + void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) + { + T* pT = static_cast(this); + if(m_bFlatMenus) + pT->DrawItemFlat(lpDrawItemStruct); + else + pT->DrawItem3D(lpDrawItemStruct); + + } + + void DrawItem3D(LPDRAWITEMSTRUCT lpDrawItemStruct) + { + _MenuItemData* pmd = (_MenuItemData*)lpDrawItemStruct->itemData; + CDCHandle dc = lpDrawItemStruct->hDC; + const RECT& rcItem = lpDrawItemStruct->rcItem; + T* pT = static_cast(this); + + if(pmd->fType & MFT_SEPARATOR) + { + // draw separator + RECT rc = rcItem; + rc.top += (rc.bottom - rc.top) / 2; // vertical center + dc.DrawEdge(&rc, EDGE_ETCHED, BF_TOP); // draw separator line + } + else // not a separator + { + BOOL bDisabled = lpDrawItemStruct->itemState & ODS_GRAYED; + BOOL bSelected = lpDrawItemStruct->itemState & ODS_SELECTED; + BOOL bChecked = lpDrawItemStruct->itemState & ODS_CHECKED; + BOOL bHasImage = FALSE; + + if(LOWORD(lpDrawItemStruct->itemID) == (WORD)-1) + bSelected = FALSE; + RECT rcButn = { rcItem.left, rcItem.top, rcItem.left + m_szButton.cx, rcItem.top + m_szButton.cy }; // button rect + ::OffsetRect(&rcButn, 0, ((rcItem.bottom - rcItem.top) - (rcButn.bottom - rcButn.top)) / 2); // center vertically + + int iButton = pmd->iButton; + if(iButton >= 0) + { + bHasImage = TRUE; + + // calc drawing point + SIZE sz = { rcButn.right - rcButn.left - m_szBitmap.cx, rcButn.bottom - rcButn.top - m_szBitmap.cy }; + sz.cx /= 2; + sz.cy /= 2; + POINT point = { rcButn.left + sz.cx, rcButn.top + sz.cy }; + + // fill background depending on state + if(!bChecked || (bSelected && !bDisabled)) + { + if(!bDisabled) + dc.FillRect(&rcButn, (bChecked && !bSelected) ? COLOR_3DLIGHT : COLOR_MENU); + else + dc.FillRect(&rcButn, COLOR_MENU); + } + else + { + COLORREF crTxt = dc.SetTextColor(::GetSysColor(COLOR_BTNFACE)); + COLORREF crBk = dc.SetBkColor(::GetSysColor(COLOR_BTNHILIGHT)); + CBrush hbr(CDCHandle::GetHalftoneBrush()); + dc.SetBrushOrg(rcButn.left, rcButn.top); + dc.FillRect(&rcButn, hbr); + dc.SetTextColor(crTxt); + dc.SetBkColor(crBk); + } + + // draw disabled or normal + if(!bDisabled) + { + // draw pushed-in or popped-out edge + if(bSelected || bChecked) + { + RECT rc2 = rcButn; + dc.DrawEdge(&rc2, bChecked ? BDR_SUNKENOUTER : BDR_RAISEDINNER, BF_RECT); + } + // draw the image + ::ImageList_Draw(m_hImageList, iButton, dc, point.x, point.y, ILD_TRANSPARENT); + } + else + { + HBRUSH hBrushBackground = bChecked ? NULL : ::GetSysColorBrush(COLOR_MENU); + pT->DrawBitmapDisabled(dc, iButton, point, hBrushBackground); + } + } + else + { + // no image - look for custom checked/unchecked bitmaps + CMenuItemInfo info; + info.fMask = MIIM_CHECKMARKS | MIIM_TYPE; + ::GetMenuItemInfo((HMENU)lpDrawItemStruct->hwndItem, lpDrawItemStruct->itemID, MF_BYCOMMAND, &info); + if(bChecked || info.hbmpUnchecked != NULL) + { + BOOL bRadio = ((info.fType & MFT_RADIOCHECK) != 0); + bHasImage = pT->DrawCheckmark(dc, rcButn, bSelected, bDisabled, bRadio, bChecked ? info.hbmpChecked : info.hbmpUnchecked); + } + } + + // draw item text + int cxButn = m_szButton.cx; + COLORREF colorBG = ::GetSysColor(bSelected ? COLOR_HIGHLIGHT : COLOR_MENU); + if(bSelected || lpDrawItemStruct->itemAction == ODA_SELECT) + { + RECT rcBG = rcItem; + if(bHasImage) + rcBG.left += cxButn + s_kcxGap; + dc.FillRect(&rcBG, bSelected ? COLOR_HIGHLIGHT : COLOR_MENU); + } + + // calc text rectangle and colors + RECT rcText = rcItem; + rcText.left += cxButn + s_kcxGap + s_kcxTextMargin; + rcText.right -= cxButn; + dc.SetBkMode(TRANSPARENT); + COLORREF colorText = ::GetSysColor(bDisabled ? (bSelected ? COLOR_GRAYTEXT : COLOR_3DSHADOW) : (bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT)); + + // font already selected by Windows + if(bDisabled && (!bSelected || colorText == colorBG)) + { + // disabled - draw shadow text shifted down and right 1 pixel (unles selected) + RECT rcDisabled = rcText; + ::OffsetRect(&rcDisabled, 1, 1); + pT->DrawMenuText(dc, rcDisabled, pmd->lpstrText, ::GetSysColor(COLOR_3DHILIGHT)); + } + pT->DrawMenuText(dc, rcText, pmd->lpstrText, colorText); // finally! + } + } + + void DrawItemFlat(LPDRAWITEMSTRUCT lpDrawItemStruct) + { + _MenuItemData* pmd = (_MenuItemData*)lpDrawItemStruct->itemData; + CDCHandle dc = lpDrawItemStruct->hDC; + const RECT& rcItem = lpDrawItemStruct->rcItem; + T* pT = static_cast(this); + +#ifndef COLOR_MENUHILIGHT + const int COLOR_MENUHILIGHT = 29; +#endif // !COLOR_MENUHILIGHT + + BOOL bDisabled = lpDrawItemStruct->itemState & ODS_GRAYED; + BOOL bSelected = lpDrawItemStruct->itemState & ODS_SELECTED; + BOOL bChecked = lpDrawItemStruct->itemState & ODS_CHECKED; + + // paint background + if(bSelected || lpDrawItemStruct->itemAction == ODA_SELECT) + { + if(bSelected) + { + dc.FillRect(&rcItem, ::GetSysColorBrush(COLOR_MENUHILIGHT)); + dc.FrameRect(&rcItem, ::GetSysColorBrush(COLOR_HIGHLIGHT)); + } + else + { + dc.FillRect(&rcItem, ::GetSysColorBrush(COLOR_MENU)); + } + } + + if(pmd->fType & MFT_SEPARATOR) + { + // draw separator + RECT rc = rcItem; + rc.top += (rc.bottom - rc.top) / 2; // vertical center + dc.DrawEdge(&rc, EDGE_ETCHED, BF_TOP); // draw separator line + } + else // not a separator + { + if(LOWORD(lpDrawItemStruct->itemID) == (WORD)-1) + bSelected = FALSE; + RECT rcButn = { rcItem.left, rcItem.top, rcItem.left + m_szButton.cx, rcItem.top + m_szButton.cy }; // button rect + ::OffsetRect(&rcButn, 0, ((rcItem.bottom - rcItem.top) - (rcButn.bottom - rcButn.top)) / 2); // center vertically + + // draw background and border for checked items + if(bChecked) + { + RECT rcCheck = rcButn; + ::InflateRect(&rcCheck, -1, -1); + if(bSelected) + dc.FillRect(&rcCheck, ::GetSysColorBrush(COLOR_MENU)); + dc.FrameRect(&rcCheck, ::GetSysColorBrush(COLOR_HIGHLIGHT)); + } + + int iButton = pmd->iButton; + if(iButton >= 0) + { + // calc drawing point + SIZE sz = { rcButn.right - rcButn.left - m_szBitmap.cx, rcButn.bottom - rcButn.top - m_szBitmap.cy }; + sz.cx /= 2; + sz.cy /= 2; + POINT point = { rcButn.left + sz.cx, rcButn.top + sz.cy }; + + // draw disabled or normal + if(!bDisabled) + { + ::ImageList_Draw(m_hImageList, iButton, dc, point.x, point.y, ILD_TRANSPARENT); + } + else + { + HBRUSH hBrushBackground = ::GetSysColorBrush((bSelected && !(bDisabled && bChecked)) ? COLOR_MENUHILIGHT : COLOR_MENU); + HBRUSH hBrushDisabledImage = ::GetSysColorBrush(COLOR_3DSHADOW); + pT->DrawBitmapDisabled(dc, iButton, point, hBrushBackground, hBrushBackground, hBrushDisabledImage); + } + } + else + { + // no image - look for custom checked/unchecked bitmaps + CMenuItemInfo info; + info.fMask = MIIM_CHECKMARKS | MIIM_TYPE; + ::GetMenuItemInfo((HMENU)lpDrawItemStruct->hwndItem, lpDrawItemStruct->itemID, MF_BYCOMMAND, &info); + if(bChecked || info.hbmpUnchecked != NULL) + { + BOOL bRadio = ((info.fType & MFT_RADIOCHECK) != 0); + pT->DrawCheckmark(dc, rcButn, bSelected, bDisabled, bRadio, bChecked ? info.hbmpChecked : info.hbmpUnchecked); + } + } + + // draw item text + int cxButn = m_szButton.cx; + // calc text rectangle and colors + RECT rcText = rcItem; + rcText.left += cxButn + s_kcxGap + s_kcxTextMargin; + rcText.right -= cxButn; + dc.SetBkMode(TRANSPARENT); + COLORREF colorText = ::GetSysColor(bDisabled ? (bSelected ? COLOR_GRAYTEXT : COLOR_3DSHADOW) : (bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT)); + + pT->DrawMenuText(dc, rcText, pmd->lpstrText, colorText); // finally! + } + } + + void DrawMenuText(CDCHandle& dc, RECT& rc, LPCTSTR lpstrText, COLORREF color) + { + int nTab = -1; + for(int i = 0; i < lstrlen(lpstrText); i++) + { + if(lpstrText[i] == _T('\t')) + { + nTab = i; + break; + } + } + dc.SetTextColor(color); + dc.DrawText(lpstrText, nTab, &rc, DT_SINGLELINE | DT_LEFT | DT_VCENTER | (m_bShowKeyboardCues ? 0 : DT_HIDEPREFIX)); + if(nTab != -1) + dc.DrawText(&lpstrText[nTab + 1], -1, &rc, DT_SINGLELINE | DT_RIGHT | DT_VCENTER | (m_bShowKeyboardCues ? 0 : DT_HIDEPREFIX)); + } + + void DrawBitmapDisabled(CDCHandle& dc, int nImage, POINT point, + HBRUSH hBrushBackground = ::GetSysColorBrush(COLOR_3DFACE), + HBRUSH hBrush3DEffect = ::GetSysColorBrush(COLOR_3DHILIGHT), + HBRUSH hBrushDisabledImage = ::GetSysColorBrush(COLOR_3DSHADOW)) + { +#if (_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501) + if(m_bAlphaImages) + { + IMAGELISTDRAWPARAMS ildp = { 0 }; + ildp.cbSize = sizeof(IMAGELISTDRAWPARAMS); + ildp.himl = m_hImageList; + ildp.i = nImage; + ildp.hdcDst = dc; + ildp.x = point.x; + ildp.y = point.y; + ildp.cx = 0; + ildp.cy = 0; + ildp.xBitmap = 0; + ildp.yBitmap = 0; + ildp.fStyle = ILD_TRANSPARENT; + ildp.fState = ILS_SATURATE; + ildp.Frame = 0; + ::ImageList_DrawIndirect(&ildp); + } + else +#endif // (_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501) + { + // create memory DC + CDC dcMem; + dcMem.CreateCompatibleDC(dc); + // create mono or color bitmap + CBitmap bmp; + bmp.CreateCompatibleBitmap(dc, m_szBitmap.cx, m_szBitmap.cy); + ATLASSERT(bmp.m_hBitmap != NULL); + // draw image into memory DC--fill BG white first + HBITMAP hBmpOld = dcMem.SelectBitmap(bmp); + dcMem.PatBlt(0, 0, m_szBitmap.cx, m_szBitmap.cy, WHITENESS); + // If white is the text color, we can't use the normal painting since + // it would blend with the WHITENESS, but the mask is OK + UINT uDrawStyle = (::GetSysColor(COLOR_BTNTEXT) == RGB(255, 255, 255)) ? ILD_MASK : ILD_NORMAL; + ::ImageList_Draw(m_hImageList, nImage, dcMem, 0, 0, uDrawStyle); + dc.DitherBlt(point.x, point.y, m_szBitmap.cx, m_szBitmap.cy, dcMem, NULL, 0, 0, hBrushBackground, hBrush3DEffect, hBrushDisabledImage); + dcMem.SelectBitmap(hBmpOld); // restore + } + } + + // old name + BOOL Draw3DCheckmark(CDCHandle& dc, const RECT& rc, BOOL bSelected, BOOL bDisabled, BOOL bRadio, HBITMAP hBmpCheck) + { + return DrawCheckmark(dc, rc, bSelected, bDisabled, bRadio, hBmpCheck); + } + + BOOL DrawCheckmark(CDCHandle& dc, const RECT& rc, BOOL bSelected, BOOL bDisabled, BOOL bRadio, HBITMAP hBmpCheck) + { + // get checkmark bitmap, if none, use Windows standard + SIZE size = { 0, 0 }; + CBitmapHandle bmp = hBmpCheck; + if(hBmpCheck != NULL) + { + bmp.GetSize(size); + } + else + { + size.cx = ::GetSystemMetrics(SM_CXMENUCHECK); + size.cy = ::GetSystemMetrics(SM_CYMENUCHECK); + bmp.CreateCompatibleBitmap(dc, size.cx, size.cy); + ATLASSERT(bmp.m_hBitmap != NULL); + } + // center bitmap in caller's rectangle + RECT rcDest = rc; + if((rc.right - rc.left) > size.cx) + { + rcDest.left = rc.left + (rc.right - rc.left - size.cx) / 2; + rcDest.right = rcDest.left + size.cx; + } + if((rc.bottom - rc.top) > size.cy) + { + rcDest.top = rc.top + (rc.bottom - rc.top - size.cy) / 2; + rcDest.bottom = rcDest.top + size.cy; + } + // paint background + if(!m_bFlatMenus) + { + if(bSelected && !bDisabled) + { + dc.FillRect(&rcDest, COLOR_MENU); + } + else + { + COLORREF clrTextOld = dc.SetTextColor(::GetSysColor(COLOR_BTNFACE)); + COLORREF clrBkOld = dc.SetBkColor(::GetSysColor(COLOR_BTNHILIGHT)); + CBrush hbr(CDCHandle::GetHalftoneBrush()); + dc.SetBrushOrg(rcDest.left, rcDest.top); + dc.FillRect(&rcDest, hbr); + dc.SetTextColor(clrTextOld); + dc.SetBkColor(clrBkOld); + } + } + + // create source image + CDC dcSource; + dcSource.CreateCompatibleDC(dc); + HBITMAP hBmpOld = dcSource.SelectBitmap(bmp); + // set colors + const COLORREF clrBlack = RGB(0, 0, 0); + const COLORREF clrWhite = RGB(255, 255, 255); + COLORREF clrTextOld = dc.SetTextColor(clrBlack); + COLORREF clrBkOld = dc.SetBkColor(clrWhite); + // create mask + CDC dcMask; + dcMask.CreateCompatibleDC(dc); + CBitmap bmpMask; + bmpMask.CreateBitmap(size.cx, size.cy, 1, 1, NULL); + HBITMAP hBmpOld1 = dcMask.SelectBitmap(bmpMask); + + // draw the checkmark transparently + int cx = rcDest.right - rcDest.left; + int cy = rcDest.bottom - rcDest.top; + if(hBmpCheck != NULL) + { + // build mask based on transparent color + dcSource.SetBkColor(m_clrMask); + dcMask.SetBkColor(clrBlack); + dcMask.SetTextColor(clrWhite); + dcMask.BitBlt(0, 0, size.cx, size.cy, dcSource, 0, 0, SRCCOPY); + // draw bitmap using the mask + dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcSource, 0, 0, SRCINVERT); + dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcMask, 0, 0, SRCAND); + dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcSource, 0, 0, SRCINVERT); + } + else + { + const DWORD ROP_DSno = 0x00BB0226L; + const DWORD ROP_DSa = 0x008800C6L; + const DWORD ROP_DSo = 0x00EE0086L; + const DWORD ROP_DSna = 0x00220326L; + + // draw mask + RECT rcSource = { 0, 0, min(size.cx, rc.right - rc.left), min(size.cy, rc.bottom - rc.top) }; + dcMask.DrawFrameControl(&rcSource, DFC_MENU, bRadio ? DFCS_MENUBULLET : DFCS_MENUCHECK); + + // draw shadow if disabled + if(!m_bFlatMenus && bDisabled) + { + // offset by one pixel + int x = rcDest.left + 1; + int y = rcDest.top + 1; + // paint source bitmap + const int nColor = COLOR_3DHILIGHT; + dcSource.FillRect(&rcSource, nColor); + // draw checkmark - special case black and white colors + COLORREF clrCheck = ::GetSysColor(nColor); + if(clrCheck == clrWhite) + { + dc.BitBlt(x, y, cx, cy, dcMask, 0, 0, ROP_DSno); + dc.BitBlt(x, y, cx, cy, dcSource, 0, 0, ROP_DSa); + } + else + { + if(clrCheck != clrBlack) + { + ATLASSERT(dcSource.GetTextColor() == clrBlack); + ATLASSERT(dcSource.GetBkColor() == clrWhite); + dcSource.BitBlt(0, 0, size.cx, size.cy, dcMask, 0, 0, ROP_DSna); + } + dc.BitBlt(x, y, cx, cy, dcMask, 0, 0, ROP_DSa); + dc.BitBlt(x, y, cx, cy, dcSource, 0, 0, ROP_DSo); + } + } + + // paint source bitmap + const int nColor = bDisabled ? COLOR_BTNSHADOW : COLOR_MENUTEXT; + dcSource.FillRect(&rcSource, nColor); + // draw checkmark - special case black and white colors + COLORREF clrCheck = ::GetSysColor(nColor); + if(clrCheck == clrWhite) + { + dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcMask, 0, 0, ROP_DSno); + dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcSource, 0, 0, ROP_DSa); + } + else + { + if(clrCheck != clrBlack) + { + ATLASSERT(dcSource.GetTextColor() == clrBlack); + ATLASSERT(dcSource.GetBkColor() == clrWhite); + dcSource.BitBlt(0, 0, size.cx, size.cy, dcMask, 0, 0, ROP_DSna); + } + dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcMask, 0, 0, ROP_DSa); + dc.BitBlt(rcDest.left, rcDest.top, cx, cy, dcSource, 0, 0, ROP_DSo); + } + } + // restore all + dc.SetTextColor(clrTextOld); + dc.SetBkColor(clrBkOld); + dcSource.SelectBitmap(hBmpOld); + dcMask.SelectBitmap(hBmpOld1); + if(hBmpCheck == NULL) + bmp.DeleteObject(); + // draw pushed-in hilight + if(!m_bFlatMenus && !bDisabled) + { + if(rc.right - rc.left > size.cx) + ::InflateRect(&rcDest, 1,1); // inflate checkmark by one pixel all around + dc.DrawEdge(&rcDest, BDR_SUNKENOUTER, BF_RECT); + } + + return TRUE; + } + + void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) + { + _MenuItemData* pmd = (_MenuItemData*)lpMeasureItemStruct->itemData; + + if(pmd->fType & MFT_SEPARATOR) // separator - use half system height and zero width + { + lpMeasureItemStruct->itemHeight = ::GetSystemMetrics(SM_CYMENU) / 2; + lpMeasureItemStruct->itemWidth = 0; + } + else + { + // compute size of text - use DrawText with DT_CALCRECT + CWindowDC dc(NULL); + CFont fontBold; + HFONT hOldFont = NULL; + if(pmd->fState & MFS_DEFAULT) + { + // need bold version of font + LOGFONT lf = { 0 }; + m_fontMenu.GetLogFont(lf); + lf.lfWeight += 200; + fontBold.CreateFontIndirect(&lf); + ATLASSERT(fontBold.m_hFont != NULL); + hOldFont = dc.SelectFont(fontBold); + } + else + { + hOldFont = dc.SelectFont(m_fontMenu); + } + + RECT rcText = { 0, 0, 0, 0 }; + dc.DrawText(pmd->lpstrText, -1, &rcText, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT); + int cx = rcText.right - rcText.left; + dc.SelectFont(hOldFont); + + LOGFONT lf = { 0 }; + m_fontMenu.GetLogFont(lf); + int cy = lf.lfHeight; + if(cy < 0) + cy = -cy; + const int cyMargin = 8; + cy += cyMargin; + + // height of item is the bigger of these two + lpMeasureItemStruct->itemHeight = max(cy, (int)m_szButton.cy); + + // width is width of text plus a bunch of stuff + cx += 2 * s_kcxTextMargin; // L/R margin for readability + cx += s_kcxGap; // space between button and menu text + cx += 2 * m_szButton.cx; // button width (L=button; R=empty margin) + cx += m_cxExtraSpacing; // extra between item text and accelerator keys + + // Windows adds 1 to returned value + cx -= ::GetSystemMetrics(SM_CXMENUCHECK) - 1; + lpMeasureItemStruct->itemWidth = cx; // done deal + } + } + +// Implementation - Hook procs + static LRESULT CALLBACK CreateHookProc(int nCode, WPARAM wParam, LPARAM lParam) + { + const int cchClassName = 7; + TCHAR szClassName[cchClassName] = { 0 }; + + if(nCode == HCBT_CREATEWND) + { + HWND hWndMenu = (HWND)wParam; +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - HCBT_CREATEWND (HWND = %8.8X)\n"), hWndMenu); +#endif + + ::GetClassName(hWndMenu, szClassName, cchClassName); + if(!lstrcmp(_T("#32768"), szClassName)) + s_pCurrentBar->m_stackMenuWnd.Push(hWndMenu); + } + else if(nCode == HCBT_DESTROYWND) + { + HWND hWndMenu = (HWND)wParam; +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - HCBT_DESTROYWND (HWND = %8.8X)\n"), hWndMenu); +#endif + + ::GetClassName(hWndMenu, szClassName, cchClassName); + if(!lstrcmp(_T("#32768"), szClassName)) + { + ATLASSERT(hWndMenu == s_pCurrentBar->m_stackMenuWnd.GetCurrent()); + s_pCurrentBar->m_stackMenuWnd.Pop(); + } + } + + return ::CallNextHookEx(s_hCreateHook, nCode, wParam, lParam); + } + + static LRESULT CALLBACK MessageHookProc(int nCode, WPARAM wParam, LPARAM lParam) + { + LPMSG pMsg = (LPMSG)lParam; + + if(nCode == HC_ACTION && wParam == PM_REMOVE && pMsg->message != GetGetBarMessage() && pMsg->message != WM_FORWARDMSG) + { + CCommandBarCtrlBase* pCmdBar = NULL; + HWND hWnd = pMsg->hwnd; + DWORD dwPID = 0; + while(pCmdBar == NULL && hWnd != NULL) + { + pCmdBar = (CCommandBarCtrlBase*)::SendMessage(hWnd, GetGetBarMessage(), (WPARAM)&dwPID, 0L); + hWnd = ::GetParent(hWnd); + } + + if(pCmdBar != NULL && dwPID == GetCurrentProcessId()) + { + pCmdBar->m_hWndHook = pMsg->hwnd; + ATLASSERT(pCmdBar->IsCommandBarBase()); + + if(::IsWindow(pCmdBar->m_hWnd)) + pCmdBar->SendMessage(WM_FORWARDMSG, 0, (LPARAM)pMsg); + else + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - Hook skipping message, can't find command bar!\n")); + } + } + + LRESULT lRet = 0; + ATLASSERT(s_pmapMsgHook != NULL); + if(s_pmapMsgHook != NULL) + { + DWORD dwThreadID = ::GetCurrentThreadId(); + _MsgHookData* pData = s_pmapMsgHook->Lookup(dwThreadID); + if(pData != NULL) + { + lRet = ::CallNextHookEx(pData->hMsgHook, nCode, wParam, lParam); + } + } + return lRet; + } + +// Implementation + void DoPopupMenu(int nIndex, bool bAnimate) + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - DoPopupMenu, bAnimate = %s\n"), bAnimate ? "true" : "false"); +#endif + + // Menu animation flags +#ifndef TPM_VERPOSANIMATION + const UINT TPM_VERPOSANIMATION = 0x1000L; +#endif +#ifndef TPM_NOANIMATION + const UINT TPM_NOANIMATION = 0x4000L; +#endif + T* pT = static_cast(this); + + // get popup menu and it's position + RECT rect = { 0 }; + GetItemRect(nIndex, &rect); + POINT pt = { rect.left, rect.bottom }; + MapWindowPoints(NULL, &pt, 1); + MapWindowPoints(NULL, &rect); + TPMPARAMS TPMParams = { 0 }; + TPMParams.cbSize = sizeof(TPMPARAMS); + TPMParams.rcExclude = rect; + HMENU hMenuPopup = ::GetSubMenu(m_hMenu, nIndex); + ATLASSERT(hMenuPopup != NULL); + + // get button ID + TBBUTTON tbb = { 0 }; + GetButton(nIndex, &tbb); + int nCmdID = tbb.idCommand; + + m_nPopBtn = nIndex; // remember current button's index + + // press button and display popup menu + PressButton(nCmdID, TRUE); + SetHotItem(nCmdID); + pT->DoTrackPopupMenu(hMenuPopup, TPM_LEFTBUTTON | TPM_VERTICAL | TPM_LEFTALIGN | TPM_TOPALIGN | + (s_bW2K ? (bAnimate ? TPM_VERPOSANIMATION : TPM_NOANIMATION) : 0), pt.x, pt.y, &TPMParams); + PressButton(nCmdID, FALSE); + if(::GetFocus() != m_hWnd) + SetHotItem(-1); + + m_nPopBtn = -1; // restore + + // eat next message if click is on the same button + MSG msg = { 0 }; + if(::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE) && ::PtInRect(&rect, msg.pt)) + ::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_REMOVE); + + // check if another popup menu should be displayed + if(m_nNextPopBtn != -1) + { + PostMessage(GetAutoPopupMessage(), m_nNextPopBtn & 0xFFFF); + if(!(m_nNextPopBtn & 0xFFFF0000) && !m_bPopupItem) + PostMessage(WM_KEYDOWN, VK_DOWN, 0); + m_nNextPopBtn = -1; + } + else + { + m_bContextMenu = false; + // If user didn't hit escape, give focus back + if(!m_bEscapePressed) + { + if(m_bUseKeyboardCues && m_bShowKeyboardCues) + m_bAllowKeyboardCues = false; + pT->GiveFocusBack(); + } + else + { + SetHotItem(nCmdID); + SetAnchorHighlight(TRUE); + } + } + } + + BOOL DoTrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y, LPTPMPARAMS lpParams = NULL) + { + CMenuHandle menuPopup = hMenu; + + CWindowCreateCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::DoTrackPopupMenu.\n")); + ATLASSERT(FALSE); + return FALSE; + } + + ATLASSERT(s_hCreateHook == NULL); + + s_pCurrentBar = static_cast(this); + + s_hCreateHook = ::SetWindowsHookEx(WH_CBT, CreateHookProc, ModuleHelper::GetModuleInstance(), GetCurrentThreadId()); + ATLASSERT(s_hCreateHook != NULL); + + m_bPopupItem = false; + m_bMenuActive = true; + + BOOL bTrackRet = menuPopup.TrackPopupMenuEx(uFlags, x, y, m_hWnd, lpParams); + m_bMenuActive = false; + + ::UnhookWindowsHookEx(s_hCreateHook); + + s_hCreateHook = NULL; + s_pCurrentBar = NULL; + + lock.Unlock(); + + // cleanup - convert menus back to original state +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - TrackPopupMenu - cleanup\n")); +#endif + + ATLASSERT(m_stackMenuWnd.GetSize() == 0); + + UpdateWindow(); + ATL::CWindow wndTL = GetTopLevelParent(); + wndTL.UpdateWindow(); + + // restore the menu items to the previous state for all menus that were converted + if(m_bImagesVisible) + { + HMENU hMenuSav = NULL; + while((hMenuSav = m_stackMenuHandle.Pop()) != NULL) + { + menuPopup = hMenuSav; + BOOL bRet = FALSE; + // restore state and delete menu item data + for(int i = 0; i < menuPopup.GetMenuItemCount(); i++) + { + CMenuItemInfo mii; + mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_ID; + bRet = menuPopup.GetMenuItemInfo(i, TRUE, &mii); + ATLASSERT(bRet); + + _MenuItemData* pMI = (_MenuItemData*)mii.dwItemData; + if(pMI != NULL && pMI->IsCmdBarMenuItem()) + { + mii.fMask = MIIM_DATA | MIIM_TYPE | MIIM_STATE; + mii.fType = pMI->fType; + mii.fState = pMI->fState; + mii.dwTypeData = pMI->lpstrText; + mii.cch = lstrlen(pMI->lpstrText); + mii.dwItemData = NULL; + + bRet = menuPopup.SetMenuItemInfo(i, TRUE, &mii); + // this one triggers WM_MEASUREITEM + menuPopup.ModifyMenu(i, MF_BYPOSITION | mii.fType | mii.fState, mii.wID, pMI->lpstrText); + ATLASSERT(bRet); + + delete [] pMI->lpstrText; + delete pMI; + } + } + } + } + return bTrackRet; + } + + int GetPreviousMenuItem(int nBtn) const + { + if(nBtn == -1) + return -1; +#if (_WIN32_IE >= 0x0500) + RECT rcClient; + GetClientRect(&rcClient); +#endif // (_WIN32_IE >= 0x0500) + int nNextBtn; + for(nNextBtn = nBtn - 1; nNextBtn != nBtn; nNextBtn--) + { + if(nNextBtn < 0) + nNextBtn = ::GetMenuItemCount(m_hMenu) - 1; + TBBUTTON tbb = { 0 }; + GetButton(nNextBtn, &tbb); +#if (_WIN32_IE >= 0x0500) + RECT rcBtn; + GetItemRect(nNextBtn, &rcBtn); + if(rcBtn.right > rcClient.right) + { + nNextBtn = -2; // chevron + break; + } +#endif // (_WIN32_IE >= 0x0500) + if((tbb.fsState & TBSTATE_ENABLED) != 0 && (tbb.fsState & TBSTATE_HIDDEN) == 0) + break; + } + return (nNextBtn != nBtn) ? nNextBtn : -1; + } + + int GetNextMenuItem(int nBtn) const + { + if(nBtn == -1) + return -1; +#if (_WIN32_IE >= 0x0500) + RECT rcClient = { 0 }; + GetClientRect(&rcClient); +#endif // (_WIN32_IE >= 0x0500) + int nNextBtn = 0; + int nCount = ::GetMenuItemCount(m_hMenu); + for(nNextBtn = nBtn + 1; nNextBtn != nBtn; nNextBtn++) + { + if(nNextBtn >= nCount) + nNextBtn = 0; + TBBUTTON tbb = { 0 }; + GetButton(nNextBtn, &tbb); +#if (_WIN32_IE >= 0x0500) + RECT rcBtn = { 0 }; + GetItemRect(nNextBtn, &rcBtn); + if(rcBtn.right > rcClient.right) + { + nNextBtn = -2; // chevron + break; + } +#endif // (_WIN32_IE >= 0x0500) + if((tbb.fsState & TBSTATE_ENABLED) != 0 && (tbb.fsState & TBSTATE_HIDDEN) == 0) + break; + } + return (nNextBtn != nBtn) ? nNextBtn : -1; + } + +#if (_WIN32_IE >= 0x0500) + bool DisplayChevronMenu() + { + // assume we are in a rebar + HWND hWndReBar = GetParent(); + int nCount = (int)::SendMessage(hWndReBar, RB_GETBANDCOUNT, 0, 0L); + bool bRet = false; + for(int i = 0; i < nCount; i++) + { + REBARBANDINFO rbbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_STYLE }; + BOOL bRetBandInfo = (BOOL)::SendMessage(hWndReBar, RB_GETBANDINFO, i, (LPARAM)&rbbi); + if(bRetBandInfo && rbbi.hwndChild == m_hWnd) + { + if((rbbi.fStyle & RBBS_USECHEVRON) != 0) + { + ::PostMessage(hWndReBar, RB_PUSHCHEVRON, i, 0L); + PostMessage(WM_KEYDOWN, VK_DOWN, 0L); + bRet = true; + } + break; + } + } + return bRet; + } +#endif // (_WIN32_IE >= 0x0500) + + void GetSystemSettings() + { + // refresh our font + NONCLIENTMETRICS info = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() }; + BOOL bRet = ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0); + ATLASSERT(bRet); + if(bRet) + { + LOGFONT logfont = { 0 }; + if(m_fontMenu.m_hFont != NULL) + m_fontMenu.GetLogFont(logfont); + if(logfont.lfHeight != info.lfMenuFont.lfHeight || + logfont.lfWidth != info.lfMenuFont.lfWidth || + logfont.lfEscapement != info.lfMenuFont.lfEscapement || + logfont.lfOrientation != info.lfMenuFont.lfOrientation || + logfont.lfWeight != info.lfMenuFont.lfWeight || + logfont.lfItalic != info.lfMenuFont.lfItalic || + logfont.lfUnderline != info.lfMenuFont.lfUnderline || + logfont.lfStrikeOut != info.lfMenuFont.lfStrikeOut || + logfont.lfCharSet != info.lfMenuFont.lfCharSet || + logfont.lfOutPrecision != info.lfMenuFont.lfOutPrecision || + logfont.lfClipPrecision != info.lfMenuFont.lfClipPrecision || + logfont.lfQuality != info.lfMenuFont.lfQuality || + logfont.lfPitchAndFamily != info.lfMenuFont.lfPitchAndFamily || + lstrcmp(logfont.lfFaceName, info.lfMenuFont.lfFaceName) != 0) + { + HFONT hFontMenu = ::CreateFontIndirect(&info.lfMenuFont); + ATLASSERT(hFontMenu != NULL); + if(hFontMenu != NULL) + { + if(m_fontMenu.m_hFont != NULL) + m_fontMenu.DeleteObject(); + m_fontMenu.Attach(hFontMenu); + SetFont(m_fontMenu); + AddStrings(_T("NS\0")); // for proper item height + AutoSize(); + } + } + } + + // check if we need extra spacing for menu item text + CWindowDC dc(m_hWnd); + HFONT hFontOld = dc.SelectFont(m_fontMenu); + RECT rcText = { 0, 0, 0, 0 }; + dc.DrawText(_T("\t"), -1, &rcText, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT); + if((rcText.right - rcText.left) < 4) + { + ::SetRectEmpty(&rcText); + dc.DrawText(_T("x"), -1, &rcText, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT); + m_cxExtraSpacing = rcText.right - rcText.left; + } + else + { + m_cxExtraSpacing = 0; + } + dc.SelectFont(hFontOld); + + // get Windows version + OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) }; + ::GetVersionEx(&ovi); + + // query keyboard cues mode (Windows 2000 or later) + if(ovi.dwMajorVersion >= 5) + { +#ifndef SPI_GETKEYBOARDCUES + const UINT SPI_GETKEYBOARDCUES = 0x100A; +#endif // !SPI_GETKEYBOARDCUES + BOOL bRetVal = TRUE; + bRet = ::SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &bRetVal, 0); + m_bUseKeyboardCues = (bRet && !bRetVal); + m_bAllowKeyboardCues = true; + ShowKeyboardCues(!m_bUseKeyboardCues); + } + + // query flat menu mode (Windows XP or later) + if((ovi.dwMajorVersion == 5 && ovi.dwMinorVersion >= 1) || (ovi.dwMajorVersion > 5)) + { +#ifndef SPI_GETFLATMENU + const UINT SPI_GETFLATMENU = 0x1022; +#endif // !SPI_GETFLATMENU + BOOL bRetVal = FALSE; + bRet = ::SystemParametersInfo(SPI_GETFLATMENU, 0, &bRetVal, 0); + m_bFlatMenus = (bRet && bRetVal); + } + +#if _WTL_CMDBAR_VISTA_MENUS + // check if we should use Vista menus + bool bVistaMenus = (RunTimeHelper::IsVista() && RunTimeHelper::IsCommCtrl6() && ((m_dwExtendedStyle & CBR_EX_NOVISTAMENUS) == 0)); + + if(bVistaMenus) + { + HMODULE hThemeDLL = ::LoadLibrary(_T("uxtheme.dll")); + if(hThemeDLL != NULL) + { + typedef BOOL (STDAPICALLTYPE *PFN_IsThemeActive)(); + PFN_IsThemeActive pfnIsThemeActive = (PFN_IsThemeActive)::GetProcAddress(hThemeDLL, "IsThemeActive"); + ATLASSERT(pfnIsThemeActive != NULL); + bVistaMenus = bVistaMenus && (pfnIsThemeActive != NULL) && (pfnIsThemeActive() != FALSE); + + typedef BOOL (STDAPICALLTYPE *PFN_IsAppThemed)(); + PFN_IsAppThemed pfnIsAppThemed = (PFN_IsAppThemed)::GetProcAddress(hThemeDLL, "IsAppThemed"); + ATLASSERT(pfnIsAppThemed != NULL); + bVistaMenus = bVistaMenus && (pfnIsAppThemed != NULL) && (pfnIsAppThemed() != FALSE); + + ::FreeLibrary(hThemeDLL); + } + } + + if(!bVistaMenus && m_bVistaMenus && (m_hMenu != NULL) && (m_arrCommand.GetSize() > 0)) + { + T* pT = static_cast(this); + pT->_RemoveVistaBitmapsFromMenu(); + } + + m_bVistaMenus = bVistaMenus; +#endif // _WTL_CMDBAR_VISTA_MENUS + +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("CmdBar - GetSystemSettings:\n m_bFlatMenus = %s\n m_bUseKeyboardCues = %s m_bVistaMenus = %s\n"), + m_bFlatMenus ? "true" : "false", m_bUseKeyboardCues ? "true" : "false", m_bVistaMenus ? "true" : "false"); +#endif + } + +// Implementation - alternate focus mode support + void TakeFocus() + { + if((m_dwExtendedStyle & CBR_EX_ALTFOCUSMODE) && m_hWndFocus == NULL) + m_hWndFocus = ::GetFocus(); + SetFocus(); + } + + void GiveFocusBack() + { + if(m_bParentActive) + { + if((m_dwExtendedStyle & CBR_EX_ALTFOCUSMODE) && ::IsWindow(m_hWndFocus)) + ::SetFocus(m_hWndFocus); + else if(!(m_dwExtendedStyle & CBR_EX_ALTFOCUSMODE) && m_wndParent.IsWindow()) + m_wndParent.SetFocus(); + } + m_hWndFocus = NULL; + SetAnchorHighlight(FALSE); + if(m_bUseKeyboardCues && m_bShowKeyboardCues) + ShowKeyboardCues(false); + m_bSkipPostDown = false; + } + + void ShowKeyboardCues(bool bShow) + { + m_bShowKeyboardCues = bShow; + SetDrawTextFlags(DT_HIDEPREFIX, m_bShowKeyboardCues ? 0 : DT_HIDEPREFIX); + Invalidate(); + UpdateWindow(); + } + +// Implementation - internal message helpers + static UINT GetAutoPopupMessage() + { + static UINT uAutoPopupMessage = 0; + if(uAutoPopupMessage == 0) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::GetAutoPopupMessage.\n")); + ATLASSERT(FALSE); + return 0; + } + + if(uAutoPopupMessage == 0) + uAutoPopupMessage = ::RegisterWindowMessage(_T("WTL_CmdBar_InternalAutoPopupMsg")); + + lock.Unlock(); + } + ATLASSERT(uAutoPopupMessage != 0); + return uAutoPopupMessage; + } + + static UINT GetGetBarMessage() + { + static UINT uGetBarMessage = 0; + if(uGetBarMessage == 0) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CCommandBarCtrlImpl::GetGetBarMessage.\n")); + ATLASSERT(FALSE); + return 0; + } + + if(uGetBarMessage == 0) + uGetBarMessage = ::RegisterWindowMessage(_T("WTL_CmdBar_InternalGetBarMsg")); + + lock.Unlock(); + } + ATLASSERT(uGetBarMessage != 0); + return uGetBarMessage; + } + +// Implementation + bool CreateInternalImageList(int cImages) + { + UINT uFlags = (m_bAlphaImages ? ILC_COLOR32 : ILC_COLOR24) | ILC_MASK; + m_hImageList = ::ImageList_Create(m_szBitmap.cx, m_szBitmap.cy, uFlags, cImages, 1); + ATLASSERT(m_hImageList != NULL); + return (m_hImageList != NULL); + } + +// Implementation - support for Vista menus +#if _WTL_CMDBAR_VISTA_MENUS + void _AddVistaBitmapsFromImageList(int nStartIndex, int nCount) + { + // Create display compatible memory DC + CClientDC dc(NULL); + CDC dcMem; + dcMem.CreateCompatibleDC(dc); + HBITMAP hBitmapSave = dcMem.GetCurrentBitmap(); + + T* pT = static_cast(this); + // Create bitmaps for all menu items + for(int i = 0; i < nCount; i++) + { + HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nStartIndex + i, dc, dcMem); + dcMem.SelectBitmap(hBitmapSave); + m_arrVistaBitmap.Add(hBitmap); + } + } + + void _AddVistaBitmapFromImageList(int nIndex) + { + // Create display compatible memory DC + CClientDC dc(NULL); + CDC dcMem; + dcMem.CreateCompatibleDC(dc); + HBITMAP hBitmapSave = dcMem.GetCurrentBitmap(); + + // Create bitmap for menu item + T* pT = static_cast(this); + HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nIndex, dc, dcMem); + + // Select saved bitmap back and add bitmap to the array + dcMem.SelectBitmap(hBitmapSave); + m_arrVistaBitmap.Add(hBitmap); + } + + void _ReplaceVistaBitmapFromImageList(int nIndex) + { + // Delete existing bitmap + if(m_arrVistaBitmap[nIndex] != NULL) + ::DeleteObject(m_arrVistaBitmap[nIndex]); + + // Create display compatible memory DC + CClientDC dc(NULL); + CDC dcMem; + dcMem.CreateCompatibleDC(dc); + HBITMAP hBitmapSave = dcMem.GetCurrentBitmap(); + + // Create bitmap for menu item + T* pT = static_cast(this); + HBITMAP hBitmap = pT->_CreateVistaBitmapHelper(nIndex, dc, dcMem); + + // Select saved bitmap back and replace bitmap in the array + dcMem.SelectBitmap(hBitmapSave); + m_arrVistaBitmap.SetAtIndex(nIndex, hBitmap); + } + + HBITMAP _CreateVistaBitmapHelper(int nIndex, HDC hDCSource, HDC hDCTarget) + { + // Create 32-bit bitmap + BITMAPINFO bi = { 0 }; + bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bi.bmiHeader.biWidth = m_szBitmap.cx; + bi.bmiHeader.biHeight = m_szBitmap.cy; + bi.bmiHeader.biPlanes = 1; + bi.bmiHeader.biBitCount = 32; + bi.bmiHeader.biCompression = BI_RGB; + bi.bmiHeader.biSizeImage = 0; + bi.bmiHeader.biXPelsPerMeter = 0; + bi.bmiHeader.biYPelsPerMeter = 0; + bi.bmiHeader.biClrUsed = 0; + bi.bmiHeader.biClrImportant = 0; + HBITMAP hBitmap = ::CreateDIBSection(hDCSource, &bi, DIB_RGB_COLORS, NULL, NULL, 0); + ATLASSERT(hBitmap != NULL); + + // Select bitmap into target DC and draw from image list to it + if(hBitmap != NULL) + { + ::SelectObject(hDCTarget, hBitmap); + + IMAGELISTDRAWPARAMS ildp = { 0 }; + ildp.cbSize = sizeof(IMAGELISTDRAWPARAMS); + ildp.himl = m_hImageList; + ildp.i = nIndex; + ildp.hdcDst = hDCTarget; + ildp.x = 0; + ildp.y = 0; + ildp.cx = 0; + ildp.cy = 0; + ildp.xBitmap = 0; + ildp.yBitmap = 0; + ildp.fStyle = ILD_TRANSPARENT; + ildp.fState = ILS_ALPHA; + ildp.Frame = 255; + ::ImageList_DrawIndirect(&ildp); + } + + return hBitmap; + } + + void _RemoveVistaBitmapsFromMenu() + { + CMenuHandle menu = m_hMenu; + for(int i = 0; i < m_arrCommand.GetSize(); i++) + { + CMenuItemInfo mii; + mii.fMask = MIIM_BITMAP; + mii.hbmpItem = NULL; + menu.SetMenuItemInfo(m_arrCommand[i], FALSE, &mii); + } + } +#endif // _WTL_CMDBAR_VISTA_MENUS +}; + + +class CCommandBarCtrl : public CCommandBarCtrlImpl +{ +public: + DECLARE_WND_SUPERCLASS(_T("WTL_CommandBar"), GetWndClassName()) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CMDICommandBarCtrl - ATL implementation of Command Bars for MDI apps + +template +class ATL_NO_VTABLE CMDICommandBarCtrlImpl : public CCommandBarCtrlImpl< T, TBase, TWinTraits> +{ +public: +// Data members + ATL::CContainedWindow m_wndMDIClient; + bool m_bChildMaximized; + HWND m_hWndChildMaximized; + HICON m_hIconChildMaximized; + int m_nBtnPressed; + int m_nBtnWasPressed; + + int m_cxyOffset; // offset between nonclient elements + int m_cxIconWidth; // small icon width + int m_cyIconHeight; // small icon height + int m_cxBtnWidth; // nonclient button width + int m_cyBtnHeight; // nonclient button height + int m_cxLeft; // left nonclient area width + int m_cxRight; // right nonclient area width + +// Theme declarations and data members +#ifndef _WTL_NO_AUTO_THEME +#ifndef _UXTHEME_H_ + typedef HANDLE HTHEME; +#endif // !_UXTHEME_H_ + typedef HTHEME (STDAPICALLTYPE *PFN_OpenThemeData)(HWND hwnd, LPCWSTR pszClassList); + typedef HRESULT (STDAPICALLTYPE *PFN_CloseThemeData)(HTHEME hTheme); + typedef HRESULT (STDAPICALLTYPE *PFN_DrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect); + typedef HRESULT (STDAPICALLTYPE *PFN_DrawThemeParentBackground)(HWND hwnd, HDC hdc, OPTIONAL RECT* prc); + + HMODULE m_hThemeDLL; + HTHEME m_hTheme; + PFN_DrawThemeBackground m_pfnDrawThemeBackground; + PFN_DrawThemeParentBackground m_pfnDrawThemeParentBackground; +#endif // !_WTL_NO_AUTO_THEME + +// Constructor/destructor + CMDICommandBarCtrlImpl() : + m_wndMDIClient(this, 2), m_bChildMaximized(false), + m_hWndChildMaximized(NULL), m_hIconChildMaximized(NULL), + m_nBtnPressed(-1), m_nBtnWasPressed(-1), +#ifndef _WTL_NO_AUTO_THEME + m_hThemeDLL(NULL), m_hTheme(NULL), m_pfnDrawThemeBackground(NULL), m_pfnDrawThemeParentBackground(NULL), +#endif // !_WTL_NO_AUTO_THEME + m_cxyOffset(2), + m_cxIconWidth(16), m_cyIconHeight(16), + m_cxBtnWidth(16), m_cyBtnHeight(14), + m_cxLeft(20), m_cxRight(55) + { } + + ~CMDICommandBarCtrlImpl() + { + if(m_wndMDIClient.IsWindow()) +/*scary!*/ m_wndMDIClient.UnsubclassWindow(); + } + +// Operations + BOOL SetMDIClient(HWND hWndMDIClient) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(::IsWindow(hWndMDIClient)); + if(!::IsWindow(hWndMDIClient)) + return FALSE; + +#ifdef _DEBUG + // BLOCK: Test if the passed window is MDICLIENT + { + LPCTSTR lpszMDIClientClass = _T("MDICLIENT"); + const int nNameLen = 9 + 1; // "MDICLIENT" + NULL + TCHAR szClassName[nNameLen] = { 0 }; + ::GetClassName(hWndMDIClient, szClassName, nNameLen); + ATLASSERT(lstrcmpi(szClassName, lpszMDIClientClass) == 0); + } +#endif // _DEBUG + + if(m_wndMDIClient.IsWindow()) +/*scary!*/ m_wndMDIClient.UnsubclassWindow(); + + return m_wndMDIClient.SubclassWindow(hWndMDIClient); + } + +// Message maps + typedef CCommandBarCtrlImpl< T, TBase, TWinTraits > _baseClass; + BEGIN_MSG_MAP(CMDICommandBarCtrlImpl) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) +#ifndef _WTL_NO_AUTO_THEME + MESSAGE_HANDLER(_GetThemeChangedMsg(), OnThemeChanged) +#endif // !_WTL_NO_AUTO_THEME + MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_NCCALCSIZE, OnNcCalcSize) + MESSAGE_HANDLER(WM_NCPAINT, OnNcPaint) + MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest) + MESSAGE_HANDLER(WM_NCLBUTTONDOWN, OnNcLButtonDown) + MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) + MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) + MESSAGE_HANDLER(WM_NCLBUTTONDBLCLK, OnNcLButtonDblClk) + MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged) + CHAIN_MSG_MAP(_baseClass) + ALT_MSG_MAP(1) // Parent window messages + MESSAGE_HANDLER(WM_ACTIVATE, OnParentActivate) + CHAIN_MSG_MAP_ALT(_baseClass, 1) + ALT_MSG_MAP(2) // MDI client window messages + MESSAGE_HANDLER(WM_MDISETMENU, OnMDISetMenu) + // no chaining needed since this was moved from the base class here + ALT_MSG_MAP(3) // Message hook messages + MESSAGE_RANGE_HANDLER(0, 0xFFFF, OnAllHookMessages) + CHAIN_MSG_MAP_ALT(_baseClass, 3) + END_MSG_MAP() + +// Additional MDI message handlers + LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + LRESULT lRet = _baseClass::OnCreate(uMsg, wParam, lParam, bHandled); + if(lRet == (LRESULT)-1) + return lRet; + +#ifndef _WTL_NO_AUTO_THEME + // this will fail if theming is not supported + m_hThemeDLL = ::LoadLibrary(_T("uxtheme.dll")); + if(m_hThemeDLL != NULL) + { + m_pfnDrawThemeBackground = (PFN_DrawThemeBackground)::GetProcAddress(m_hThemeDLL, "DrawThemeBackground"); + ATLASSERT(m_pfnDrawThemeBackground != NULL); + if(m_pfnDrawThemeBackground != NULL) + { + T* pT = static_cast(this); + pT->_OpenThemeData(); + } + else + { + ::FreeLibrary(m_hThemeDLL); + m_hThemeDLL = NULL; + } + m_pfnDrawThemeParentBackground = (PFN_DrawThemeParentBackground)::GetProcAddress(m_hThemeDLL, "DrawThemeParentBackground"); + ATLASSERT(m_pfnDrawThemeParentBackground != NULL); + } +#endif // !_WTL_NO_AUTO_THEME + + return lRet; + } + + LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + LRESULT lRet = _baseClass::OnDestroy(uMsg, wParam, lParam, bHandled); + +#ifndef _WTL_NO_AUTO_THEME + if(m_hThemeDLL != NULL) + { + T* pT = static_cast(this); + pT->_CloseThemeData(); + ::FreeLibrary(m_hThemeDLL); + m_hThemeDLL = NULL; + } +#endif // !_WTL_NO_AUTO_THEME + + return lRet; + } + +#ifndef _WTL_NO_AUTO_THEME + LRESULT OnThemeChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + if(m_hThemeDLL != NULL) + { + T* pT = static_cast(this); + pT->_CloseThemeData(); + pT->_OpenThemeData(); + } + return 0; + } +#endif // !_WTL_NO_AUTO_THEME + + LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); + T* pT = static_cast(this); + pT->_AdjustBtnSize(GET_Y_LPARAM(lParam)); + return lRet; + } + + LRESULT OnNcCalcSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); + + if(m_bChildMaximized && (BOOL)wParam) + { + LPNCCALCSIZE_PARAMS lpParams = (LPNCCALCSIZE_PARAMS)lParam; + if(m_bLayoutRTL) + { + lpParams->rgrc[0].left += m_cxRight; + lpParams->rgrc[0].right -= m_cxLeft; + } + else + { + lpParams->rgrc[0].left += m_cxLeft; + lpParams->rgrc[0].right -= m_cxRight; + } + } + + return lRet; + } + + LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); + + if(!m_bChildMaximized) + return lRet; + + ATLASSERT(m_hWndChildMaximized != NULL && m_hIconChildMaximized != NULL); + + // get DC and window rectangle + CWindowDC dc(m_hWnd); + RECT rect; + GetWindowRect(&rect); + int cxWidth = rect.right - rect.left; + int cyHeight = rect.bottom - rect.top; + + // paint left side nonclient background and draw icon + ::SetRect(&rect, 0, 0, m_cxLeft, cyHeight); +#ifndef _WTL_NO_AUTO_THEME + if(m_hTheme != NULL) + { + if(m_pfnDrawThemeParentBackground != NULL) + m_pfnDrawThemeParentBackground(m_hWnd, dc, &rect); + else + dc.FillRect(&rect, COLOR_WINDOW); + } + else +#endif // !_WTL_NO_AUTO_THEME + { + if((m_dwExtendedStyle & CBR_EX_TRANSPARENT) != 0) + dc.FillRect(&rect, COLOR_3DFACE); + else + dc.FillRect(&rect, COLOR_MENU); + } + + RECT rcIcon = { 0 }; + T* pT = static_cast(this); + pT->_CalcIconRect(cxWidth, cyHeight, rcIcon); + dc.DrawIconEx(rcIcon.left, rcIcon.top, m_hIconChildMaximized, m_cxIconWidth, m_cyIconHeight); + + // paint right side nonclient background + ::SetRect(&rect, cxWidth - m_cxRight, 0, cxWidth, cyHeight); +#ifndef _WTL_NO_AUTO_THEME + if(m_hTheme != NULL) + { + if(m_pfnDrawThemeParentBackground != NULL) + { + // this is to account for the left non-client area + POINT ptOrg = { 0, 0 }; + dc.GetViewportOrg(&ptOrg); + dc.SetViewportOrg(ptOrg.x + m_cxLeft, ptOrg.y); + ::OffsetRect(&rect, -m_cxLeft, 0); + + m_pfnDrawThemeParentBackground(m_hWnd, dc, &rect); + + // restore + dc.SetViewportOrg(ptOrg); + ::OffsetRect(&rect, m_cxLeft, 0); + } + else + { + dc.FillRect(&rect, COLOR_3DFACE); + } + } + else +#endif // !_WTL_NO_AUTO_THEME + { + if((m_dwExtendedStyle & CBR_EX_TRANSPARENT) != 0) + dc.FillRect(&rect, COLOR_3DFACE); + else + dc.FillRect(&rect, COLOR_MENU); + } + + // draw buttons + RECT arrRect[3] = { 0 }; + pT->_CalcBtnRects(cxWidth, cyHeight, arrRect); + pT->_DrawMDIButton(dc, arrRect, -1); // draw all buttons + + return lRet; + } + + LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); + if(m_bChildMaximized) + { + RECT rect = { 0 }; + GetWindowRect(&rect); + POINT pt = { GET_X_LPARAM(lParam) - rect.left, GET_Y_LPARAM(lParam) - rect.top }; + if(m_bLayoutRTL) + { + if((pt.x < m_cxRight) || (pt.x > ((rect.right - rect.left) - m_cxLeft))) + lRet = HTBORDER; + } + else + { + if((pt.x < m_cxLeft) || (pt.x > ((rect.right - rect.left) - m_cxRight))) + lRet = HTBORDER; + } + } + return lRet; + } + + LRESULT OnNcLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + if(!m_bChildMaximized) + { + bHandled = FALSE; + return 1; + } + + ATLASSERT(_DebugCheckChild()); + + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + RECT rect = { 0 }; + GetWindowRect(&rect); + pt.x -= rect.left; + pt.y -= rect.top; + + RECT rcIcon = { 0 }; + T* pT = static_cast(this); + pT->_CalcIconRect(rect.right - rect.left, rect.bottom - rect.top, rcIcon, m_bLayoutRTL); + RECT arrRect[3] = { 0 }; + pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect, m_bLayoutRTL); + + if(::PtInRect(&rcIcon, pt)) + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonDown: icon\n")); +#endif +#ifndef TPM_VERPOSANIMATION + const UINT TPM_VERPOSANIMATION = 0x1000L; // Menu animation flag +#endif + CMenuHandle menu = ::GetSystemMenu(m_hWndChildMaximized, FALSE); + UINT uRet = (UINT)menu.TrackPopupMenu(TPM_LEFTBUTTON | TPM_VERTICAL | TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | + (s_bW2K ? TPM_VERPOSANIMATION : 0), m_bLayoutRTL ? rect.right : rect.left, rect.bottom, m_hWndChildMaximized); + + // eat next message if click is on the same button + ::OffsetRect(&rcIcon, rect.left, rect.top); + MSG msg = { 0 }; + if(::PeekMessage(&msg, m_hWnd, WM_NCLBUTTONDOWN, WM_NCLBUTTONDOWN, PM_NOREMOVE) && ::PtInRect(&rcIcon, msg.pt)) + ::PeekMessage(&msg, m_hWnd, WM_NCLBUTTONDOWN, WM_NCLBUTTONDOWN, PM_REMOVE); + + if(uRet != 0) + ::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, uRet, 0L); + } + else if(::PtInRect(&arrRect[0], pt)) + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonDown: close button\n")); +#endif + m_nBtnWasPressed = m_nBtnPressed = 0; + } + else if(::PtInRect(&arrRect[1], pt)) + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonDown: restore button\n")); +#endif + m_nBtnWasPressed = m_nBtnPressed = 1; + } + else if(::PtInRect(&arrRect[2], pt)) + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonDown: minimize button\n")); +#endif + m_nBtnWasPressed = m_nBtnPressed = 2; + } + else + { + bHandled = FALSE; + } + + // draw the button state if it was pressed + if(m_nBtnPressed != -1) + { + SetCapture(); + CWindowDC dc(m_hWnd); + pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect); + pT->_DrawMDIButton(dc, arrRect, m_nBtnPressed); + } + + return 0; + } + + LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + if(!m_bChildMaximized || ::GetCapture() != m_hWnd || m_nBtnWasPressed == -1) + { + bHandled = FALSE; + return 1; + } + + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + ClientToScreen(&pt); + RECT rect = { 0 }; + GetWindowRect(&rect); + pt.x -= rect.left; + pt.y -= rect.top; + RECT arrRect[3] = { 0 }; + T* pT = static_cast(this); + pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect, m_bLayoutRTL); + int nOldBtnPressed = m_nBtnPressed; + m_nBtnPressed = ::PtInRect(&arrRect[m_nBtnWasPressed], pt) ? m_nBtnWasPressed : -1; + if(nOldBtnPressed != m_nBtnPressed) + { + CWindowDC dc(m_hWnd); + pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect); + pT->_DrawMDIButton(dc, arrRect, (m_nBtnPressed != -1) ? m_nBtnPressed : nOldBtnPressed); + } + + return 0; + } + + LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + if(!m_bChildMaximized || ::GetCapture() != m_hWnd || m_nBtnWasPressed == -1) + { + bHandled = FALSE; + return 1; + } + + ATLASSERT(_DebugCheckChild()); + + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + ClientToScreen(&pt); + RECT rect = { 0 }; + GetWindowRect(&rect); + pt.x -= rect.left; + pt.y -= rect.top; + + int nBtn = m_nBtnWasPressed; + ReleaseCapture(); + + RECT arrRect[3] = { 0 }; + T* pT = static_cast(this); + pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect, m_bLayoutRTL); + if(::PtInRect(&arrRect[nBtn], pt)) + { + switch(nBtn) + { + case 0: // close +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonUp: close button\n")); +#endif + ::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, SC_CLOSE, 0L); + break; + case 1: // restore +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonUp: restore button\n")); +#endif + ::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, SC_RESTORE, 0L); + break; + case 2: // minimize +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - LButtonUp: minimize button\n")); +#endif + ::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, SC_MINIMIZE, 0L); + break; + default: + break; + } + } + + return 0; + } + + LRESULT OnNcLButtonDblClk(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + if(!m_bChildMaximized || m_nBtnWasPressed != -1) + { + bHandled = FALSE; + return 1; + } + + ATLASSERT(_DebugCheckChild()); + + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + RECT rect = { 0 }; + GetWindowRect(&rect); + pt.x -= rect.left; + pt.y -= rect.top; + + RECT rcIcon = { 0 }; + T* pT = static_cast(this); + pT->_CalcIconRect(rect.right - rect.left, rect.bottom - rect.top, rcIcon, m_bLayoutRTL); + RECT arrRect[3] = { 0 }; + pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect, m_bLayoutRTL); + + if(::PtInRect(&rcIcon, pt)) + { + CMenuHandle menu = ::GetSystemMenu(m_hWndChildMaximized, FALSE); + UINT uDefID = menu.GetMenuDefaultItem(); + if(uDefID == (UINT)-1) + uDefID = SC_CLOSE; + ::SendMessage(m_hWndChildMaximized, WM_SYSCOMMAND, uDefID, 0L); + } + + return 0; + } + + LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_bChildMaximized) + { + if(m_nBtnPressed != -1) + { + ATLASSERT(m_nBtnPressed == m_nBtnWasPressed); // must be + m_nBtnPressed = -1; + RECT rect = { 0 }; + GetWindowRect(&rect); + RECT arrRect[3] = { 0 }; + T* pT = static_cast(this); + pT->_CalcBtnRects(rect.right - rect.left, rect.bottom - rect.top, arrRect); + CWindowDC dc(m_hWnd); + pT->_DrawMDIButton(dc, arrRect, m_nBtnWasPressed); + } + m_nBtnWasPressed = -1; + } + else + { + bHandled = FALSE; + } + return 0; + } + +// Parent window message handlers + LRESULT OnParentActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + m_bParentActive = (LOWORD(wParam) != WA_INACTIVE); + RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW); + bHandled = FALSE; + return 1; + } + +// MDI client window message handlers + LRESULT OnMDISetMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + m_wndMDIClient.DefWindowProc(uMsg, NULL, lParam); + HMENU hOldMenu = GetMenu(); + BOOL bRet = AttachMenu((HMENU)wParam); + bRet; // avoid level 4 warning + ATLASSERT(bRet); + +#if (_WIN32_IE >= 0x0400) + T* pT = static_cast(this); + pT->UpdateRebarBandIdealSize(); +#endif // (_WIN32_IE >= 0x0400) + + return (LRESULT)hOldMenu; + } + +// All messages from the message hook + LRESULT OnAllHookMessages(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + T* pT = static_cast(this); + pT->_ProcessAllHookMessages(uMsg, wParam, lParam); + + bHandled = FALSE; + return 1; + } + +// Overrideables + // override this to provide different ideal size + void UpdateRebarBandIdealSize() + { + // assuming we are in a rebar, change ideal size to our size + // we hope that if we are not in a rebar, nCount will be 0 + int nCount = (int)::SendMessage(GetParent(), RB_GETBANDCOUNT, 0, 0L); + for(int i = 0; i < nCount; i++) + { + REBARBANDINFO rbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE }; + ::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi); + if(rbi.hwndChild == m_hWnd) + { + rbi.fMask = RBBIM_IDEALSIZE; + rbi.cxIdeal = m_bChildMaximized ? m_cxLeft + m_cxRight : 0; + int nBtnCount = GetButtonCount(); + if(nBtnCount > 0) + { + RECT rect = { 0 }; + GetItemRect(nBtnCount - 1, &rect); + rbi.cxIdeal += rect.right; + } + ::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi); + break; + } + } + } + + // all hook messages - check for the maximized MDI child window change + void _ProcessAllHookMessages(UINT uMsg, WPARAM /*wParam*/, LPARAM /*lParam*/) + { + if(uMsg == WM_MDIGETACTIVE || uMsg == WM_MDISETMENU) + return; + + BOOL bMaximized = FALSE; + HWND hWndChild = (HWND)::SendMessage(m_wndMDIClient, WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized); + bool bMaxOld = m_bChildMaximized; + m_bChildMaximized = (hWndChild != NULL && bMaximized); + HICON hIconOld = m_hIconChildMaximized; + + if(m_bChildMaximized) + { + if(m_hWndChildMaximized != hWndChild) + { + ATL::CWindow wnd = m_hWndChildMaximized = hWndChild; + m_hIconChildMaximized = wnd.GetIcon(FALSE); + if(m_hIconChildMaximized == NULL) + { + m_hIconChildMaximized = wnd.GetIcon(TRUE); + if(m_hIconChildMaximized == NULL) + { + // no icon set with WM_SETICON, get the class one +// need conditional code because types don't match in winuser.h +#ifdef _WIN64 + m_hIconChildMaximized = (HICON)::GetClassLongPtr(wnd, GCLP_HICONSM); +#else + m_hIconChildMaximized = (HICON)LongToHandle(::GetClassLongPtr(wnd, GCLP_HICONSM)); +#endif + } + } + } + } + else + { + m_hWndChildMaximized = NULL; + m_hIconChildMaximized = NULL; + } + + if(bMaxOld != m_bChildMaximized) + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - All messages hook change: m_bChildMaximized = %s\n"), m_bChildMaximized ? "true" : "false"); +#endif + // assuming we are in a rebar, change our size to accomodate new state + // we hope that if we are not in a rebar, nCount will be 0 + int nCount = (int)::SendMessage(GetParent(), RB_GETBANDCOUNT, 0, 0L); + int cxDiff = (m_bChildMaximized ? 1 : -1) * (m_cxLeft + m_cxRight); + for(int i = 0; i < nCount; i++) + { +#if (_WIN32_IE >= 0x0500) + REBARBANDINFO rbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_STYLE }; + ::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi); + if(rbi.hwndChild == m_hWnd) + { + if((rbi.fStyle & RBBS_USECHEVRON) != 0) + { + rbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE; + rbi.cxMinChild += cxDiff; + rbi.cxIdeal += cxDiff; + ::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi); + } + break; + } +#elif (_WIN32_IE >= 0x0400) + REBARBANDINFO rbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE }; + ::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi); + if(rbi.hwndChild == m_hWnd) + { + rbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE; + rbi.cxMinChild += cxDiff; + rbi.cxIdeal += cxDiff; + ::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi); + break; + } +#else // (_WIN32_IE < 0x0400) + REBARBANDINFO rbi = { RunTimeHelper::SizeOf_REBARBANDINFO(), RBBIM_CHILD | RBBIM_CHILDSIZE }; + ::SendMessage(GetParent(), RB_GETBANDINFO, i, (LPARAM)&rbi); + if(rbi.hwndChild == m_hWnd) + { + rbi.fMask = RBBIM_CHILDSIZE; + rbi.cxMinChild += cxDiff; + ::SendMessage(GetParent(), RB_SETBANDINFO, i, (LPARAM)&rbi); + break; + } +#endif // (_WIN32_IE < 0x0400) + } + } + + if(bMaxOld != m_bChildMaximized || hIconOld != m_hIconChildMaximized) + { + // force size change and redraw everything + RECT rect = { 0 }; + GetWindowRect(&rect); + ::MapWindowPoints(NULL, GetParent(), (LPPOINT)&rect, 2); + SetRedraw(FALSE); + SetWindowPos(NULL, 0, 0, 1, 1, SWP_NOZORDER | SWP_NOMOVE); + SetWindowPos(NULL, &rect, SWP_NOZORDER | SWP_NOMOVE); + SetRedraw(TRUE); + RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW); + } + } + +// Implementation + void GetSystemSettings() + { +#ifdef _CMDBAR_EXTRA_TRACE + ATLTRACE2(atlTraceUI, 0, _T("MDI CmdBar - GetSystemSettings\n")); +#endif + _baseClass::GetSystemSettings(); + + NONCLIENTMETRICS info = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() }; + BOOL bRet = ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0); + ATLASSERT(bRet); + if(bRet) + { + m_cxIconWidth = ::GetSystemMetrics(SM_CXSMICON); + m_cyIconHeight = ::GetSystemMetrics(SM_CYSMICON); + m_cxLeft = m_cxIconWidth; + +#ifndef _WTL_NO_AUTO_THEME + if(m_hTheme != NULL) + { + m_cxBtnWidth = info.iCaptionWidth - 2 * m_cxyOffset; + m_cyBtnHeight = info.iCaptionHeight - 2 * m_cxyOffset; + m_cxRight = 3 * m_cxBtnWidth; + } + else +#endif // !_WTL_NO_AUTO_THEME + { + m_cxBtnWidth = info.iCaptionWidth - m_cxyOffset; + m_cyBtnHeight = info.iCaptionHeight - 2 * m_cxyOffset; + m_cxRight = 3 * m_cxBtnWidth + m_cxyOffset; + } + } + + RECT rect = { 0 }; + GetClientRect(&rect); + T* pT = static_cast(this); + pT->_AdjustBtnSize(rect.bottom); + } + + void _AdjustBtnSize(int cyHeight) + { + if(cyHeight > 1 && m_cyBtnHeight > cyHeight) + { +#ifndef _WTL_NO_AUTO_THEME + if(m_hTheme != NULL) + { + m_cyBtnHeight = cyHeight; + m_cxBtnWidth = cyHeight; + m_cxRight = 3 * m_cxBtnWidth; + } + else +#endif // !_WTL_NO_AUTO_THEME + { + m_cyBtnHeight = cyHeight; + m_cxBtnWidth = cyHeight + m_cxyOffset; + m_cxRight = 3 * m_cxBtnWidth + m_cxyOffset; + } + } + } + + void _CalcIconRect(int cxWidth, int cyHeight, RECT& rect, bool bInvertX = false) const + { + int xStart = (m_cxLeft - m_cxIconWidth) / 2; + if(xStart < 0) + xStart = 0; + int yStart = (cyHeight - m_cyIconHeight) / 2; + if(yStart < 0) + yStart = 0; + + if(bInvertX) + ::SetRect(&rect, cxWidth - (xStart + m_cxBtnWidth), yStart, cxWidth - xStart, yStart + m_cyBtnHeight); + else + ::SetRect(&rect, xStart, yStart, xStart + m_cxBtnWidth, yStart + m_cyBtnHeight); + } + + void _CalcBtnRects(int cxWidth, int cyHeight, RECT arrRect[3], bool bInvertX = false) const + { + int yStart = (cyHeight - m_cyBtnHeight) / 2; + if(yStart < 0) + yStart = 0; + + RECT rcBtn = { cxWidth - m_cxBtnWidth, yStart, cxWidth, yStart + m_cyBtnHeight }; + int nDirection = -1; + if(bInvertX) + { + ::SetRect(&rcBtn, 0, yStart, m_cxBtnWidth, yStart + m_cyBtnHeight); + nDirection = 1; + } + + arrRect[0] = rcBtn; +#ifndef _WTL_NO_AUTO_THEME + if(m_hTheme != NULL) + ::OffsetRect(&rcBtn, nDirection * m_cxBtnWidth, 0); + else +#endif // !_WTL_NO_AUTO_THEME + ::OffsetRect(&rcBtn, nDirection * (m_cxBtnWidth + m_cxyOffset), 0); + arrRect[1] = rcBtn; + ::OffsetRect(&rcBtn, nDirection * m_cxBtnWidth, 0); + arrRect[2] = rcBtn; + } + + void _DrawMDIButton(CWindowDC& dc, LPRECT pRects, int nBtn) + { +#ifndef _WTL_NO_AUTO_THEME + if(m_hTheme != NULL) + { +#ifndef TMSCHEMA_H + const int WP_MDICLOSEBUTTON = 20; + const int CBS_NORMAL = 1; + const int CBS_PUSHED = 3; + const int CBS_DISABLED = 4; + const int WP_MDIRESTOREBUTTON = 22; + const int RBS_NORMAL = 1; + const int RBS_PUSHED = 3; + const int RBS_DISABLED = 4; + const int WP_MDIMINBUTTON = 16; + const int MINBS_NORMAL = 1; + const int MINBS_PUSHED = 3; + const int MINBS_DISABLED = 4; +#endif // TMSCHEMA_H + if(nBtn == -1 || nBtn == 0) + m_pfnDrawThemeBackground(m_hTheme, dc, WP_MDICLOSEBUTTON, m_bParentActive ? ((m_nBtnPressed == 0) ? CBS_PUSHED : CBS_NORMAL) : CBS_DISABLED, &pRects[0], NULL); + if(nBtn == -1 || nBtn == 1) + m_pfnDrawThemeBackground(m_hTheme, dc, WP_MDIRESTOREBUTTON, m_bParentActive ? ((m_nBtnPressed == 1) ? RBS_PUSHED : RBS_NORMAL) : RBS_DISABLED, &pRects[1], NULL); + if(nBtn == -1 || nBtn == 2) + m_pfnDrawThemeBackground(m_hTheme, dc, WP_MDIMINBUTTON, m_bParentActive ? ((m_nBtnPressed == 2) ? MINBS_PUSHED : MINBS_NORMAL) : MINBS_DISABLED, &pRects[2], NULL); + } + else +#endif // !_WTL_NO_AUTO_THEME + { + if(nBtn == -1 || nBtn == 0) + dc.DrawFrameControl(&pRects[0], DFC_CAPTION, DFCS_CAPTIONCLOSE | ((m_nBtnPressed == 0) ? DFCS_PUSHED : 0)); + if(nBtn == -1 || nBtn == 1) + dc.DrawFrameControl(&pRects[1], DFC_CAPTION, DFCS_CAPTIONRESTORE | ((m_nBtnPressed == 1) ? DFCS_PUSHED : 0)); + if(nBtn == -1 || nBtn == 2) + dc.DrawFrameControl(&pRects[2], DFC_CAPTION, DFCS_CAPTIONMIN | ((m_nBtnPressed == 2) ? DFCS_PUSHED : 0)); + } + } + +#ifndef _WTL_NO_AUTO_THEME + static UINT _GetThemeChangedMsg() + { +#ifndef WM_THEMECHANGED + static const UINT WM_THEMECHANGED = 0x031A; +#endif // !WM_THEMECHANGED + return WM_THEMECHANGED; + } + + void _OpenThemeData() + { + ATLASSERT(m_hThemeDLL != NULL); + + PFN_OpenThemeData pfnOpenThemeData = (PFN_OpenThemeData)::GetProcAddress(m_hThemeDLL, "OpenThemeData"); + ATLASSERT(pfnOpenThemeData != NULL); + if(pfnOpenThemeData != NULL) + m_hTheme = pfnOpenThemeData(m_hWnd, L"Window"); + } + + void _CloseThemeData() + { + ATLASSERT(m_hThemeDLL != NULL); + + if(m_hTheme == NULL) + return; // nothing to do + + PFN_CloseThemeData pfnCloseThemeData = (PFN_CloseThemeData)::GetProcAddress(m_hThemeDLL, "CloseThemeData"); + ATLASSERT(pfnCloseThemeData != NULL); + if(pfnCloseThemeData != NULL) + { + pfnCloseThemeData(m_hTheme); + m_hTheme = NULL; + } + } +#endif // !_WTL_NO_AUTO_THEME + + bool _DebugCheckChild() + { +#ifdef _DEBUG + BOOL bMaximized = FALSE; + HWND hWndChild = (HWND)::SendMessage(m_wndMDIClient, WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized); + return (bMaximized && hWndChild == m_hWndChildMaximized); +#else // !_DEBUG + return true; +#endif // !_DEBUG + } +}; + +class CMDICommandBarCtrl : public CMDICommandBarCtrlImpl +{ +public: + DECLARE_WND_SUPERCLASS(_T("WTL_MDICommandBar"), GetWndClassName()) +}; + +}; // namespace WTL + +#endif // __ATLCTRLW_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlctrlx.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlctrlx.h new file mode 100644 index 0000000000..65d8f934a5 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlctrlx.h @@ -0,0 +1,5004 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLCTRLX_H__ +#define __ATLCTRLX_H__ + +#pragma once + +#ifndef __ATLAPP_H__ + #error atlctrlx.h requires atlapp.h to be included first +#endif + +#ifndef __ATLCTRLS_H__ + #error atlctrlx.h requires atlctrls.h to be included first +#endif + +#ifndef WM_UPDATEUISTATE + #define WM_UPDATEUISTATE 0x0128 +#endif // !WM_UPDATEUISTATE + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CBitmapButtonImpl +// CBitmapButton +// CCheckListViewCtrlImpl +// CCheckListViewCtrl +// CHyperLinkImpl +// CHyperLink +// CWaitCursor +// CCustomWaitCursor +// CMultiPaneStatusBarCtrlImpl +// CMultiPaneStatusBarCtrl +// CPaneContainerImpl +// CPaneContainer +// CSortListViewImpl +// CSortListViewCtrlImpl +// CSortListViewCtrl +// CTabViewImpl +// CTabView + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// CBitmapButton - bitmap button implementation + +#ifndef _WIN32_WCE + +// bitmap button extended styles +#define BMPBTN_HOVER 0x00000001 +#define BMPBTN_AUTO3D_SINGLE 0x00000002 +#define BMPBTN_AUTO3D_DOUBLE 0x00000004 +#define BMPBTN_AUTOSIZE 0x00000008 +#define BMPBTN_SHAREIMAGELISTS 0x00000010 +#define BMPBTN_AUTOFIRE 0x00000020 + +template +class ATL_NO_VTABLE CBitmapButtonImpl : public ATL::CWindowImpl< T, TBase, TWinTraits> +{ +public: + DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName()) + + enum + { + _nImageNormal = 0, + _nImagePushed, + _nImageFocusOrHover, + _nImageDisabled, + + _nImageCount = 4, + }; + + enum + { + ID_TIMER_FIRST = 1000, + ID_TIMER_REPEAT = 1001 + }; + + // Bitmap button specific extended styles + DWORD m_dwExtendedStyle; + + CImageList m_ImageList; + int m_nImage[_nImageCount]; + + CToolTipCtrl m_tip; + LPTSTR m_lpstrToolTipText; + + // Internal states + unsigned m_fMouseOver:1; + unsigned m_fFocus:1; + unsigned m_fPressed:1; + + +// Constructor/Destructor + CBitmapButtonImpl(DWORD dwExtendedStyle = BMPBTN_AUTOSIZE, HIMAGELIST hImageList = NULL) : + m_ImageList(hImageList), m_dwExtendedStyle(dwExtendedStyle), + m_lpstrToolTipText(NULL), + m_fMouseOver(0), m_fFocus(0), m_fPressed(0) + { + m_nImage[_nImageNormal] = -1; + m_nImage[_nImagePushed] = -1; + m_nImage[_nImageFocusOrHover] = -1; + m_nImage[_nImageDisabled] = -1; + } + + ~CBitmapButtonImpl() + { + if((m_dwExtendedStyle & BMPBTN_SHAREIMAGELISTS) == 0) + m_ImageList.Destroy(); + delete [] m_lpstrToolTipText; + } + + // overridden to provide proper initialization + BOOL SubclassWindow(HWND hWnd) + { +#if (_MSC_VER >= 1300) + BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits>::SubclassWindow(hWnd); +#else // !(_MSC_VER >= 1300) + typedef ATL::CWindowImpl< T, TBase, TWinTraits> _baseClass; + BOOL bRet = _baseClass::SubclassWindow(hWnd); +#endif // !(_MSC_VER >= 1300) + if(bRet) + Init(); + return bRet; + } + +// Attributes + DWORD GetBitmapButtonExtendedStyle() const + { + return m_dwExtendedStyle; + } + + DWORD SetBitmapButtonExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) + { + DWORD dwPrevStyle = m_dwExtendedStyle; + if(dwMask == 0) + m_dwExtendedStyle = dwExtendedStyle; + else + m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); + return dwPrevStyle; + } + + HIMAGELIST GetImageList() const + { + return m_ImageList; + } + + HIMAGELIST SetImageList(HIMAGELIST hImageList) + { + HIMAGELIST hImageListPrev = m_ImageList; + m_ImageList = hImageList; + if((m_dwExtendedStyle & BMPBTN_AUTOSIZE) != 0 && ::IsWindow(m_hWnd)) + SizeToImage(); + return hImageListPrev; + } + + int GetToolTipTextLength() const + { + return (m_lpstrToolTipText == NULL) ? -1 : lstrlen(m_lpstrToolTipText); + } + + bool GetToolTipText(LPTSTR lpstrText, int nLength) const + { + ATLASSERT(lpstrText != NULL); + if(m_lpstrToolTipText == NULL) + return false; + + errno_t nRet = SecureHelper::strncpy_x(lpstrText, nLength, m_lpstrToolTipText, _TRUNCATE); + + return (nRet == 0 || nRet == STRUNCATE); + } + + bool SetToolTipText(LPCTSTR lpstrText) + { + if(m_lpstrToolTipText != NULL) + { + delete [] m_lpstrToolTipText; + m_lpstrToolTipText = NULL; + } + + if(lpstrText == NULL) + { + if(m_tip.IsWindow()) + m_tip.Activate(FALSE); + return true; + } + + int cchLen = lstrlen(lpstrText) + 1; + ATLTRY(m_lpstrToolTipText = new TCHAR[cchLen]); + if(m_lpstrToolTipText == NULL) + return false; + + SecureHelper::strcpy_x(m_lpstrToolTipText, cchLen, lpstrText); + if(m_tip.IsWindow()) + { + m_tip.Activate(TRUE); + m_tip.AddTool(m_hWnd, m_lpstrToolTipText); + } + + return true; + } + +// Operations + void SetImages(int nNormal, int nPushed = -1, int nFocusOrHover = -1, int nDisabled = -1) + { + if(nNormal != -1) + m_nImage[_nImageNormal] = nNormal; + if(nPushed != -1) + m_nImage[_nImagePushed] = nPushed; + if(nFocusOrHover != -1) + m_nImage[_nImageFocusOrHover] = nFocusOrHover; + if(nDisabled != -1) + m_nImage[_nImageDisabled] = nDisabled; + } + + BOOL SizeToImage() + { + ATLASSERT(::IsWindow(m_hWnd) && m_ImageList.m_hImageList != NULL); + int cx = 0; + int cy = 0; + if(!m_ImageList.GetIconSize(cx, cy)) + return FALSE; + return ResizeClient(cx, cy); + } + +// Overrideables + void DoPaint(CDCHandle dc) + { + ATLASSERT(m_ImageList.m_hImageList != NULL); // image list must be set + ATLASSERT(m_nImage[0] != -1); // main bitmap must be set + + // set bitmap according to the current button state + int nImage = -1; + bool bHover = IsHoverMode(); + if(!IsWindowEnabled()) + nImage = m_nImage[_nImageDisabled]; + else if(m_fPressed == 1) + nImage = m_nImage[_nImagePushed]; + else if((!bHover && m_fFocus == 1) || (bHover && m_fMouseOver == 1)) + nImage = m_nImage[_nImageFocusOrHover]; + if(nImage == -1) // not there, use default one + nImage = m_nImage[_nImageNormal]; + + // draw the button image + int xyPos = 0; + if((m_fPressed == 1) && ((m_dwExtendedStyle & (BMPBTN_AUTO3D_SINGLE | BMPBTN_AUTO3D_DOUBLE)) != 0) && (m_nImage[_nImagePushed] == -1)) + xyPos = 1; + m_ImageList.Draw(dc, nImage, xyPos, xyPos, ILD_NORMAL); + + // draw 3D border if required + if((m_dwExtendedStyle & (BMPBTN_AUTO3D_SINGLE | BMPBTN_AUTO3D_DOUBLE)) != 0) + { + RECT rect; + GetClientRect(&rect); + + if(m_fPressed == 1) + dc.DrawEdge(&rect, ((m_dwExtendedStyle & BMPBTN_AUTO3D_SINGLE) != 0) ? BDR_SUNKENOUTER : EDGE_SUNKEN, BF_RECT); + else if(!bHover || m_fMouseOver == 1) + dc.DrawEdge(&rect, ((m_dwExtendedStyle & BMPBTN_AUTO3D_SINGLE) != 0) ? BDR_RAISEDINNER : EDGE_RAISED, BF_RECT); + + if(!bHover && m_fFocus == 1) + { + ::InflateRect(&rect, -2 * ::GetSystemMetrics(SM_CXEDGE), -2 * ::GetSystemMetrics(SM_CYEDGE)); + dc.DrawFocusRect(&rect); + } + } + } + +// Message map and handlers + BEGIN_MSG_MAP(CBitmapButtonImpl) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) + MESSAGE_HANDLER(WM_PAINT, OnPaint) + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) + MESSAGE_HANDLER(WM_SETFOCUS, OnFocus) + MESSAGE_HANDLER(WM_KILLFOCUS, OnFocus) + MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) + MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDblClk) + MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) + MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged) + MESSAGE_HANDLER(WM_ENABLE, OnEnable) + MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) + MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave) + MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown) + MESSAGE_HANDLER(WM_KEYUP, OnKeyUp) + MESSAGE_HANDLER(WM_TIMER, OnTimer) + MESSAGE_HANDLER(WM_UPDATEUISTATE, OnUpdateUiState) + END_MSG_MAP() + + LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + Init(); + bHandled = FALSE; + return 1; + } + + LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_tip.IsWindow()) + { + m_tip.DestroyWindow(); + m_tip.m_hWnd = NULL; + } + bHandled = FALSE; + return 1; + } + + LRESULT OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + MSG msg = { m_hWnd, uMsg, wParam, lParam }; + if(m_tip.IsWindow()) + m_tip.RelayEvent(&msg); + bHandled = FALSE; + return 1; + } + + LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return 1; // no background needed + } + + LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + if(wParam != NULL) + { + pT->DoPaint((HDC)wParam); + } + else + { + CPaintDC dc(m_hWnd); + pT->DoPaint(dc.m_hDC); + } + return 0; + } + + LRESULT OnFocus(UINT uMsg, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + m_fFocus = (uMsg == WM_SETFOCUS) ? 1 : 0; + Invalidate(); + UpdateWindow(); + bHandled = FALSE; + return 1; + } + + LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + LRESULT lRet = 0; + if(IsHoverMode()) + SetCapture(); + else + lRet = DefWindowProc(uMsg, wParam, lParam); + if(::GetCapture() == m_hWnd) + { + m_fPressed = 1; + Invalidate(); + UpdateWindow(); + } + if((m_dwExtendedStyle & BMPBTN_AUTOFIRE) != 0) + { + int nElapse = 250; + int nDelay = 0; + if(::SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &nDelay, 0)) + nElapse += nDelay * 250; // all milli-seconds + SetTimer(ID_TIMER_FIRST, nElapse); + } + return lRet; + } + + LRESULT OnLButtonDblClk(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + LRESULT lRet = 0; + if(!IsHoverMode()) + lRet = DefWindowProc(uMsg, wParam, lParam); + if(::GetCapture() != m_hWnd) + SetCapture(); + if(m_fPressed == 0) + { + m_fPressed = 1; + Invalidate(); + UpdateWindow(); + } + return lRet; + } + + LRESULT OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + LRESULT lRet = 0; + bool bHover = IsHoverMode(); + if(!bHover) + lRet = DefWindowProc(uMsg, wParam, lParam); + if(::GetCapture() == m_hWnd) + { + if(bHover && m_fPressed == 1) + ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd); + ::ReleaseCapture(); + } + return lRet; + } + + LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_fPressed == 1) + { + m_fPressed = 0; + Invalidate(); + UpdateWindow(); + } + bHandled = FALSE; + return 1; + } + + LRESULT OnEnable(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + Invalidate(); + UpdateWindow(); + bHandled = FALSE; + return 1; + } + + LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + if(::GetCapture() == m_hWnd) + { + POINT ptCursor = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + ClientToScreen(&ptCursor); + RECT rect = { 0 }; + GetWindowRect(&rect); + unsigned int uPressed = ::PtInRect(&rect, ptCursor) ? 1 : 0; + if(m_fPressed != uPressed) + { + m_fPressed = uPressed; + Invalidate(); + UpdateWindow(); + } + } + else if(IsHoverMode() && m_fMouseOver == 0) + { + m_fMouseOver = 1; + Invalidate(); + UpdateWindow(); + StartTrackMouseLeave(); + } + bHandled = FALSE; + return 1; + } + + LRESULT OnMouseLeave(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + if(m_fMouseOver == 1) + { + m_fMouseOver = 0; + Invalidate(); + UpdateWindow(); + } + return 0; + } + + LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if(wParam == VK_SPACE && IsHoverMode()) + return 0; // ignore if in hover mode + if(wParam == VK_SPACE && m_fPressed == 0) + { + m_fPressed = 1; + Invalidate(); + UpdateWindow(); + } + bHandled = FALSE; + return 1; + } + + LRESULT OnKeyUp(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if(wParam == VK_SPACE && IsHoverMode()) + return 0; // ignore if in hover mode + if(wParam == VK_SPACE && m_fPressed == 1) + { + m_fPressed = 0; + Invalidate(); + UpdateWindow(); + } + bHandled = FALSE; + return 1; + } + + LRESULT OnTimer(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + ATLASSERT((m_dwExtendedStyle & BMPBTN_AUTOFIRE) != 0); + switch(wParam) // timer ID + { + case ID_TIMER_FIRST: + KillTimer(ID_TIMER_FIRST); + if(m_fPressed == 1) + { + ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd); + int nElapse = 250; + int nRepeat = 40; + if(::SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &nRepeat, 0)) + nElapse = 10000 / (10 * nRepeat + 25); // milli-seconds, approximated + SetTimer(ID_TIMER_REPEAT, nElapse); + } + break; + case ID_TIMER_REPEAT: + if(m_fPressed == 1) + ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd); + else if(::GetCapture() != m_hWnd) + KillTimer(ID_TIMER_REPEAT); + break; + default: // not our timer + break; + } + return 0; + } + + LRESULT OnUpdateUiState(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + // If the control is subclassed or superclassed, this message can cause + // repainting without WM_PAINT. We don't use this state, so just do nothing. + return 0; + } + +// Implementation + void Init() + { + // We need this style to prevent Windows from painting the button + ModifyStyle(0, BS_OWNERDRAW); + + // create a tool tip + m_tip.Create(m_hWnd); + ATLASSERT(m_tip.IsWindow()); + if(m_tip.IsWindow() && m_lpstrToolTipText != NULL) + { + m_tip.Activate(TRUE); + m_tip.AddTool(m_hWnd, m_lpstrToolTipText); + } + + if(m_ImageList.m_hImageList != NULL && (m_dwExtendedStyle & BMPBTN_AUTOSIZE) != 0) + SizeToImage(); + } + + BOOL StartTrackMouseLeave() + { + TRACKMOUSEEVENT tme = { 0 }; + tme.cbSize = sizeof(tme); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = m_hWnd; + return _TrackMouseEvent(&tme); + } + + bool IsHoverMode() const + { + return ((m_dwExtendedStyle & BMPBTN_HOVER) != 0); + } +}; + +class CBitmapButton : public CBitmapButtonImpl +{ +public: + DECLARE_WND_SUPERCLASS(_T("WTL_BitmapButton"), GetWndClassName()) + + CBitmapButton(DWORD dwExtendedStyle = BMPBTN_AUTOSIZE, HIMAGELIST hImageList = NULL) : + CBitmapButtonImpl(dwExtendedStyle, hImageList) + { } +}; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CCheckListCtrlView - list view control with check boxes + +template +class CCheckListViewCtrlImplTraits +{ +public: + static DWORD GetWndStyle(DWORD dwStyle) + { + return (dwStyle == 0) ? t_dwStyle : dwStyle; + } + + static DWORD GetWndExStyle(DWORD dwExStyle) + { + return (dwExStyle == 0) ? t_dwExStyle : dwExStyle; + } + + static DWORD GetExtendedLVStyle() + { + return t_dwExListViewStyle; + } +}; + +typedef CCheckListViewCtrlImplTraits CCheckListViewCtrlTraits; + +template +class ATL_NO_VTABLE CCheckListViewCtrlImpl : public ATL::CWindowImpl +{ +public: + DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName()) + +// Attributes + static DWORD GetExtendedLVStyle() + { + return TWinTraits::GetExtendedLVStyle(); + } + +// Operations + BOOL SubclassWindow(HWND hWnd) + { +#if (_MSC_VER >= 1300) + BOOL bRet = ATL::CWindowImplBaseT< TBase, TWinTraits>::SubclassWindow(hWnd); +#else // !(_MSC_VER >= 1300) + typedef ATL::CWindowImplBaseT< TBase, TWinTraits> _baseClass; + BOOL bRet = _baseClass::SubclassWindow(hWnd); +#endif // !(_MSC_VER >= 1300) + if(bRet) + { + T* pT = static_cast(this); + pT; + ATLASSERT((pT->GetExtendedLVStyle() & LVS_EX_CHECKBOXES) != 0); + SetExtendedListViewStyle(pT->GetExtendedLVStyle()); + } + return bRet; + } + + void CheckSelectedItems(int nCurrItem) + { + // first check if this item is selected + LVITEM lvi = { 0 }; + lvi.iItem = nCurrItem; + lvi.iSubItem = 0; + lvi.mask = LVIF_STATE; + lvi.stateMask = LVIS_SELECTED; + GetItem(&lvi); + // if item is not selected, don't do anything + if(!(lvi.state & LVIS_SELECTED)) + return; + // new check state will be reverse of the current state, + BOOL bCheck = !GetCheckState(nCurrItem); + int nItem = -1; + int nOldItem = -1; + while((nItem = GetNextItem(nOldItem, LVNI_SELECTED)) != -1) + { + if(nItem != nCurrItem) + SetCheckState(nItem, bCheck); + nOldItem = nItem; + } + } + +// Implementation + BEGIN_MSG_MAP(CCheckListViewCtrlImpl) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) + MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDown) + MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown) + END_MSG_MAP() + + LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + // first let list view control initialize everything + LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); + T* pT = static_cast(this); + pT; + ATLASSERT((pT->GetExtendedLVStyle() & LVS_EX_CHECKBOXES) != 0); + SetExtendedListViewStyle(pT->GetExtendedLVStyle()); + return lRet; + } + + LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + POINT ptMsg = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + LVHITTESTINFO lvh = { 0 }; + lvh.pt = ptMsg; + if(HitTest(&lvh) != -1 && lvh.flags == LVHT_ONITEMSTATEICON && ::GetKeyState(VK_CONTROL) >= 0) + { + T* pT = static_cast(this); + pT->CheckSelectedItems(lvh.iItem); + } + bHandled = FALSE; + return 1; + } + + LRESULT OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if(wParam == VK_SPACE) + { + int nCurrItem = GetNextItem(-1, LVNI_FOCUSED); + if(nCurrItem != -1 && ::GetKeyState(VK_CONTROL) >= 0) + { + T* pT = static_cast(this); + pT->CheckSelectedItems(nCurrItem); + } + } + bHandled = FALSE; + return 1; + } +}; + +class CCheckListViewCtrl : public CCheckListViewCtrlImpl +{ +public: + DECLARE_WND_SUPERCLASS(_T("WTL_CheckListView"), GetWndClassName()) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CHyperLink - hyper link control implementation + +#if (WINVER < 0x0500) && !defined(_WIN32_WCE) +__declspec(selectany) struct +{ + enum { cxWidth = 32, cyHeight = 32 }; + int xHotSpot; + int yHotSpot; + unsigned char arrANDPlane[cxWidth * cyHeight / 8]; + unsigned char arrXORPlane[cxWidth * cyHeight / 8]; +} _AtlHyperLink_CursorData = +{ + 5, 0, + { + 0xF9, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, + 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0xF0, 0x01, 0xFF, 0xFF, + 0xF0, 0x00, 0xFF, 0xFF, 0x10, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, + 0x80, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, + 0xE0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0xF8, 0x01, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }, + { + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0xC0, 0x00, 0x00, 0x06, 0xD8, 0x00, 0x00, + 0x06, 0xDA, 0x00, 0x00, 0x06, 0xDB, 0x00, 0x00, 0x67, 0xFB, 0x00, 0x00, 0x77, 0xFF, 0x00, 0x00, + 0x37, 0xFF, 0x00, 0x00, 0x17, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0x00, 0x00, + 0x0F, 0xFE, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, + 0x03, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + } +}; +#endif // (WINVER < 0x0500) && !defined(_WIN32_WCE) + +#define HLINK_UNDERLINED 0x00000000 +#define HLINK_NOTUNDERLINED 0x00000001 +#define HLINK_UNDERLINEHOVER 0x00000002 +#define HLINK_COMMANDBUTTON 0x00000004 +#define HLINK_NOTIFYBUTTON 0x0000000C +#define HLINK_USETAGS 0x00000010 +#define HLINK_USETAGSBOLD 0x00000030 +#define HLINK_NOTOOLTIP 0x00000040 +#define HLINK_AUTOCREATELINKFONT 0x00000080 +#define HLINK_SINGLELINE 0x00000100 + +// Notes: +// - HLINK_USETAGS and HLINK_USETAGSBOLD are always left-aligned +// - When HLINK_USETAGSBOLD is used, the underlined styles will be ignored + +template +class ATL_NO_VTABLE CHyperLinkImpl : public ATL::CWindowImpl< T, TBase, TWinTraits > +{ +public: + LPTSTR m_lpstrLabel; + LPTSTR m_lpstrHyperLink; + + HCURSOR m_hCursor; + HFONT m_hFontLink; + HFONT m_hFontNormal; + + RECT m_rcLink; +#ifndef _WIN32_WCE + CToolTipCtrl m_tip; +#endif // !_WIN32_WCE + + COLORREF m_clrLink; + COLORREF m_clrVisited; + + DWORD m_dwExtendedStyle; // Hyper Link specific extended styles + + bool m_bPaintLabel:1; + bool m_bVisited:1; + bool m_bHover:1; + bool m_bInternalLinkFont:1; + bool m_bInternalNormalFont:1; + + +// Constructor/Destructor + CHyperLinkImpl(DWORD dwExtendedStyle = HLINK_UNDERLINED) : + m_lpstrLabel(NULL), m_lpstrHyperLink(NULL), + m_hCursor(NULL), m_hFontLink(NULL), m_hFontNormal(NULL), + m_clrLink(RGB(0, 0, 255)), m_clrVisited(RGB(128, 0, 128)), + m_dwExtendedStyle(dwExtendedStyle), + m_bPaintLabel(true), m_bVisited(false), + m_bHover(false), m_bInternalLinkFont(false), m_bInternalNormalFont(false) + { + ::SetRectEmpty(&m_rcLink); + } + + ~CHyperLinkImpl() + { + delete [] m_lpstrLabel; + delete [] m_lpstrHyperLink; +#if (WINVER < 0x0500) && !defined(_WIN32_WCE) + // It was created, not loaded, so we have to destroy it + if(m_hCursor != NULL) + ::DestroyCursor(m_hCursor); +#endif // (WINVER < 0x0500) && !defined(_WIN32_WCE) + } + +// Attributes + DWORD GetHyperLinkExtendedStyle() const + { + return m_dwExtendedStyle; + } + + DWORD SetHyperLinkExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) + { + DWORD dwPrevStyle = m_dwExtendedStyle; + if(dwMask == 0) + m_dwExtendedStyle = dwExtendedStyle; + else + m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); + return dwPrevStyle; + } + + bool GetLabel(LPTSTR lpstrBuffer, int nLength) const + { + if(m_lpstrLabel == NULL) + return false; + ATLASSERT(lpstrBuffer != NULL); + if(nLength <= lstrlen(m_lpstrLabel)) + return false; + + SecureHelper::strcpy_x(lpstrBuffer, nLength, m_lpstrLabel); + + return true; + } + + bool SetLabel(LPCTSTR lpstrLabel) + { + delete [] m_lpstrLabel; + m_lpstrLabel = NULL; + int cchLen = lstrlen(lpstrLabel) + 1; + ATLTRY(m_lpstrLabel = new TCHAR[cchLen]); + if(m_lpstrLabel == NULL) + return false; + + SecureHelper::strcpy_x(m_lpstrLabel, cchLen, lpstrLabel); + T* pT = static_cast(this); + pT->CalcLabelRect(); + + if(m_hWnd != NULL) + SetWindowText(lpstrLabel); // Set this for accessibility + + return true; + } + + bool GetHyperLink(LPTSTR lpstrBuffer, int nLength) const + { + if(m_lpstrHyperLink == NULL) + return false; + ATLASSERT(lpstrBuffer != NULL); + if(nLength <= lstrlen(m_lpstrHyperLink)) + return false; + + SecureHelper::strcpy_x(lpstrBuffer, nLength, m_lpstrHyperLink); + + return true; + } + + bool SetHyperLink(LPCTSTR lpstrLink) + { + delete [] m_lpstrHyperLink; + m_lpstrHyperLink = NULL; + int cchLen = lstrlen(lpstrLink) + 1; + ATLTRY(m_lpstrHyperLink = new TCHAR[cchLen]); + if(m_lpstrHyperLink == NULL) + return false; + + SecureHelper::strcpy_x(m_lpstrHyperLink, cchLen, lpstrLink); + if(m_lpstrLabel == NULL) + { + T* pT = static_cast(this); + pT->CalcLabelRect(); + } +#ifndef _WIN32_WCE + if(m_tip.IsWindow()) + { + m_tip.Activate(TRUE); + m_tip.AddTool(m_hWnd, m_lpstrHyperLink, &m_rcLink, 1); + } +#endif // !_WIN32_WCE + return true; + } + + HFONT GetLinkFont() const + { + return m_hFontLink; + } + + void SetLinkFont(HFONT hFont) + { + if(m_bInternalLinkFont) + { + ::DeleteObject(m_hFontLink); + m_bInternalLinkFont = false; + } + + m_hFontLink = hFont; + + T* pT = static_cast(this); + pT->CalcLabelRect(); + } + + int GetIdealHeight() const + { + ATLASSERT(::IsWindow(m_hWnd)); + if(m_lpstrLabel == NULL && m_lpstrHyperLink == NULL) + return -1; + if(!m_bPaintLabel) + return -1; + + UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK; + + CClientDC dc(m_hWnd); + RECT rect = { 0 }; + GetClientRect(&rect); + HFONT hFontOld = dc.SelectFont(m_hFontNormal); + RECT rcText = rect; + dc.DrawText(_T("NS"), -1, &rcText, DT_LEFT | uFormat | DT_CALCRECT); + dc.SelectFont(m_hFontLink); + RECT rcLink = rect; + dc.DrawText(_T("NS"), -1, &rcLink, DT_LEFT | uFormat | DT_CALCRECT); + dc.SelectFont(hFontOld); + return max(rcText.bottom - rcText.top, rcLink.bottom - rcLink.top); + } + + bool GetIdealSize(SIZE& size) const + { + int cx = 0, cy = 0; + bool bRet = GetIdealSize(cx, cy); + if(bRet) + { + size.cx = cx; + size.cy = cy; + } + return bRet; + } + + bool GetIdealSize(int& cx, int& cy) const + { + ATLASSERT(::IsWindow(m_hWnd)); + if(m_lpstrLabel == NULL && m_lpstrHyperLink == NULL) + return false; + if(!m_bPaintLabel) + return false; + + CClientDC dc(m_hWnd); + RECT rcClient = { 0 }; + GetClientRect(&rcClient); + RECT rcAll = rcClient; + + if(IsUsingTags()) + { + // find tags and label parts + LPTSTR lpstrLeft = NULL; + int cchLeft = 0; + LPTSTR lpstrLink = NULL; + int cchLink = 0; + LPTSTR lpstrRight = NULL; + int cchRight = 0; + + const T* pT = static_cast(this); + pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight); + + // get label part rects + UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK; + + HFONT hFontOld = dc.SelectFont(m_hFontNormal); + RECT rcLeft = rcClient; + dc.DrawText(lpstrLeft, cchLeft, &rcLeft, DT_LEFT | uFormat | DT_CALCRECT); + + dc.SelectFont(m_hFontLink); + RECT rcLink = { rcLeft.right, rcLeft.top, rcClient.right, rcClient.bottom }; + dc.DrawText(lpstrLink, cchLink, &rcLink, DT_LEFT | uFormat | DT_CALCRECT); + + dc.SelectFont(m_hFontNormal); + RECT rcRight = { rcLink.right, rcLink.top, rcClient.right, rcClient.bottom }; + dc.DrawText(lpstrRight, cchRight, &rcRight, DT_LEFT | uFormat | DT_CALCRECT); + + dc.SelectFont(hFontOld); + + int cyMax = max(rcLeft.bottom, max(rcLink.bottom, rcRight.bottom)); + ::SetRect(&rcAll, rcLeft.left, rcLeft.top, rcRight.right, cyMax); + } + else + { + HFONT hOldFont = NULL; + if(m_hFontLink != NULL) + hOldFont = dc.SelectFont(m_hFontLink); + LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink; + DWORD dwStyle = GetStyle(); + UINT uFormat = DT_LEFT; + if (dwStyle & SS_CENTER) + uFormat = DT_CENTER; + else if (dwStyle & SS_RIGHT) + uFormat = DT_RIGHT; + uFormat |= IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK; + dc.DrawText(lpstrText, -1, &rcAll, uFormat | DT_CALCRECT); + if(m_hFontLink != NULL) + dc.SelectFont(hOldFont); + if (dwStyle & SS_CENTER) + { + int dx = (rcClient.right - rcAll.right) / 2; + ::OffsetRect(&rcAll, dx, 0); + } + else if (dwStyle & SS_RIGHT) + { + int dx = rcClient.right - rcAll.right; + ::OffsetRect(&rcAll, dx, 0); + } + } + + cx = rcAll.right - rcAll.left; + cy = rcAll.bottom - rcAll.top; + + return true; + } + + // for command buttons only + bool GetToolTipText(LPTSTR lpstrBuffer, int nLength) const + { + ATLASSERT(IsCommandButton()); + return GetHyperLink(lpstrBuffer, nLength); + } + + bool SetToolTipText(LPCTSTR lpstrToolTipText) + { + ATLASSERT(IsCommandButton()); + return SetHyperLink(lpstrToolTipText); + } + +// Operations + BOOL SubclassWindow(HWND hWnd) + { + ATLASSERT(m_hWnd == NULL); + ATLASSERT(::IsWindow(hWnd)); + if(m_hFontNormal == NULL) + m_hFontNormal = (HFONT)::SendMessage(hWnd, WM_GETFONT, 0, 0L); +#if (_MSC_VER >= 1300) + BOOL bRet = ATL::CWindowImpl< T, TBase, TWinTraits>::SubclassWindow(hWnd); +#else // !(_MSC_VER >= 1300) + typedef ATL::CWindowImpl< T, TBase, TWinTraits> _baseClass; + BOOL bRet = _baseClass::SubclassWindow(hWnd); +#endif // !(_MSC_VER >= 1300) + if(bRet) + { + T* pT = static_cast(this); + pT->Init(); + } + return bRet; + } + + bool Navigate() + { + ATLASSERT(::IsWindow(m_hWnd)); + bool bRet = true; + if(IsNotifyButton()) + { + NMHDR nmhdr = { m_hWnd, GetDlgCtrlID(), NM_CLICK }; + ::SendMessage(GetParent(), WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&nmhdr); + } + else if(IsCommandButton()) + { + ::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd); + } + else + { + ATLASSERT(m_lpstrHyperLink != NULL); +#ifndef _WIN32_WCE + DWORD_PTR dwRet = (DWORD_PTR)::ShellExecute(0, _T("open"), m_lpstrHyperLink, 0, 0, SW_SHOWNORMAL); + bRet = (dwRet > 32); +#else // CE specific + SHELLEXECUTEINFO shExeInfo = { sizeof(SHELLEXECUTEINFO), 0, 0, L"open", m_lpstrHyperLink, 0, 0, SW_SHOWNORMAL, 0, 0, 0, 0, 0, 0, 0 }; + ::ShellExecuteEx(&shExeInfo); + DWORD_PTR dwRet = (DWORD_PTR)shExeInfo.hInstApp; + bRet = (dwRet == 0) || (dwRet > 32); +#endif // _WIN32_WCE + ATLASSERT(bRet); + if(bRet) + { + m_bVisited = true; + Invalidate(); + } + } + return bRet; + } + + void CreateLinkFontFromNormal() + { + if(m_bInternalLinkFont) + { + ::DeleteObject(m_hFontLink); + m_bInternalLinkFont = false; + } + + CFontHandle font = (m_hFontNormal != NULL) ? m_hFontNormal : (HFONT)::GetStockObject(SYSTEM_FONT); + LOGFONT lf = { 0 }; + font.GetLogFont(&lf); + + if(IsUsingTagsBold()) + lf.lfWeight = FW_BOLD; + else if(!IsNotUnderlined()) + lf.lfUnderline = TRUE; + + m_hFontLink = ::CreateFontIndirect(&lf); + m_bInternalLinkFont = true; + ATLASSERT(m_hFontLink != NULL); + } + +// Message map and handlers + BEGIN_MSG_MAP(CHyperLinkImpl) + MESSAGE_HANDLER(WM_CREATE, OnCreate) +#ifndef _WIN32_WCE + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage) +#endif // !_WIN32_WCE + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) + MESSAGE_HANDLER(WM_PAINT, OnPaint) +#ifndef _WIN32_WCE + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) +#endif // !_WIN32_WCE + MESSAGE_HANDLER(WM_SETFOCUS, OnFocus) + MESSAGE_HANDLER(WM_KILLFOCUS, OnFocus) + MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) +#ifndef _WIN32_WCE + MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave) +#endif // !_WIN32_WCE + MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) + MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) + MESSAGE_HANDLER(WM_CHAR, OnChar) + MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode) + MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor) + MESSAGE_HANDLER(WM_ENABLE, OnEnable) + MESSAGE_HANDLER(WM_GETFONT, OnGetFont) + MESSAGE_HANDLER(WM_SETFONT, OnSetFont) + MESSAGE_HANDLER(WM_UPDATEUISTATE, OnUpdateUiState) + MESSAGE_HANDLER(WM_SIZE, OnSize) + END_MSG_MAP() + + LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->Init(); + return 0; + } + +#ifndef _WIN32_WCE + LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_tip.IsWindow()) + { + m_tip.DestroyWindow(); + m_tip.m_hWnd = NULL; + } + + if(m_bInternalLinkFont) + { + ::DeleteObject(m_hFontLink); + m_hFontLink = NULL; + m_bInternalLinkFont = false; + } + + if(m_bInternalNormalFont) + { + ::DeleteObject(m_hFontNormal); + m_hFontNormal = NULL; + m_bInternalNormalFont = false; + } + + bHandled = FALSE; + return 1; + } + + LRESULT OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + MSG msg = { m_hWnd, uMsg, wParam, lParam }; + if(m_tip.IsWindow() && IsUsingToolTip()) + m_tip.RelayEvent(&msg); + bHandled = FALSE; + return 1; + } +#endif // !_WIN32_WCE + + LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return 1; // no background painting needed (we do it all during WM_PAINT) + } + + LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if(!m_bPaintLabel) + { + bHandled = FALSE; + return 1; + } + + T* pT = static_cast(this); + if(wParam != NULL) + { + pT->DoEraseBackground((HDC)wParam); + pT->DoPaint((HDC)wParam); + } + else + { + CPaintDC dc(m_hWnd); + pT->DoEraseBackground(dc.m_hDC); + pT->DoPaint(dc.m_hDC); + } + + return 0; + } + + LRESULT OnFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_bPaintLabel) + Invalidate(); + else + bHandled = FALSE; + return 0; + } + + LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + if((m_lpstrHyperLink != NULL || IsCommandButton()) && ::PtInRect(&m_rcLink, pt)) + { + ::SetCursor(m_hCursor); + if(IsUnderlineHover()) + { + if(!m_bHover) + { + m_bHover = true; + InvalidateRect(&m_rcLink); + UpdateWindow(); +#ifndef _WIN32_WCE + StartTrackMouseLeave(); +#endif // !_WIN32_WCE + } + } + } + else + { + if(IsUnderlineHover()) + { + if(m_bHover) + { + m_bHover = false; + InvalidateRect(&m_rcLink); + UpdateWindow(); + } + } + bHandled = FALSE; + } + return 0; + } + +#ifndef _WIN32_WCE + LRESULT OnMouseLeave(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + if(IsUnderlineHover() && m_bHover) + { + m_bHover = false; + InvalidateRect(&m_rcLink); + UpdateWindow(); + } + return 0; + } +#endif // !_WIN32_WCE + + LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) + { + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + if(::PtInRect(&m_rcLink, pt)) + { + SetFocus(); + SetCapture(); + } + return 0; + } + + LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) + { + if(GetCapture() == m_hWnd) + { + ReleaseCapture(); + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + if(::PtInRect(&m_rcLink, pt)) + { + T* pT = static_cast(this); + pT->Navigate(); + } + } + return 0; + } + + LRESULT OnChar(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + if(wParam == VK_RETURN || wParam == VK_SPACE) + { + T* pT = static_cast(this); + pT->Navigate(); + } + return 0; + } + + LRESULT OnGetDlgCode(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return DLGC_WANTCHARS; + } + + LRESULT OnSetCursor(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + POINT pt = { 0, 0 }; + GetCursorPos(&pt); + ScreenToClient(&pt); + if((m_lpstrHyperLink != NULL || IsCommandButton()) && ::PtInRect(&m_rcLink, pt)) + { + return TRUE; + } + bHandled = FALSE; + return FALSE; + } + + LRESULT OnEnable(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + Invalidate(); + UpdateWindow(); + return 0; + } + + LRESULT OnGetFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return (LRESULT)m_hFontNormal; + } + + LRESULT OnSetFont(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + if(m_bInternalNormalFont) + { + ::DeleteObject(m_hFontNormal); + m_bInternalNormalFont = false; + } + + bool bCreateLinkFont = m_bInternalLinkFont; + + m_hFontNormal = (HFONT)wParam; + + if(bCreateLinkFont || IsAutoCreateLinkFont()) + CreateLinkFontFromNormal(); + + T* pT = static_cast(this); + pT->CalcLabelRect(); + + if((BOOL)lParam) + { + Invalidate(); + UpdateWindow(); + } + + return 0; + } + + LRESULT OnUpdateUiState(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + // If the control is subclassed or superclassed, this message can cause + // repainting without WM_PAINT. We don't use this state, so just do nothing. + return 0; + } + + LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->CalcLabelRect(); + pT->Invalidate(); + return 0; + } + +// Implementation + void Init() + { + ATLASSERT(::IsWindow(m_hWnd)); + + // Check if we should paint a label + const int cchBuff = 8; + TCHAR szBuffer[cchBuff] = { 0 }; + if(::GetClassName(m_hWnd, szBuffer, cchBuff)) + { + if(lstrcmpi(szBuffer, _T("static")) == 0) + { + ModifyStyle(0, SS_NOTIFY); // we need this + DWORD dwStyle = GetStyle() & 0x000000FF; +#ifndef _WIN32_WCE + if(dwStyle == SS_ICON || dwStyle == SS_BLACKRECT || dwStyle == SS_GRAYRECT || + dwStyle == SS_WHITERECT || dwStyle == SS_BLACKFRAME || dwStyle == SS_GRAYFRAME || + dwStyle == SS_WHITEFRAME || dwStyle == SS_OWNERDRAW || + dwStyle == SS_BITMAP || dwStyle == SS_ENHMETAFILE) +#else // CE specific + if(dwStyle == SS_ICON || dwStyle == SS_BITMAP) +#endif // _WIN32_WCE + m_bPaintLabel = false; + } + } + + // create or load a cursor +#if (WINVER >= 0x0500) || defined(_WIN32_WCE) + m_hCursor = ::LoadCursor(NULL, IDC_HAND); +#else + m_hCursor = ::CreateCursor(ModuleHelper::GetModuleInstance(), _AtlHyperLink_CursorData.xHotSpot, _AtlHyperLink_CursorData.yHotSpot, _AtlHyperLink_CursorData.cxWidth, _AtlHyperLink_CursorData.cyHeight, _AtlHyperLink_CursorData.arrANDPlane, _AtlHyperLink_CursorData.arrXORPlane); +#endif + ATLASSERT(m_hCursor != NULL); + + // set fonts + if(m_bPaintLabel) + { + if(m_hFontNormal == NULL) + { + m_hFontNormal = AtlCreateControlFont(); + m_bInternalNormalFont = true; + } + + if(m_hFontLink == NULL) + CreateLinkFontFromNormal(); + } + +#ifndef _WIN32_WCE + // create a tool tip + m_tip.Create(m_hWnd); + ATLASSERT(m_tip.IsWindow()); +#endif // !_WIN32_WCE + + // set label (defaults to window text) + if(m_lpstrLabel == NULL) + { + int nLen = GetWindowTextLength(); + if(nLen > 0) + { + ATLTRY(m_lpstrLabel = new TCHAR[nLen + 1]); + if(m_lpstrLabel != NULL) + ATLVERIFY(GetWindowText(m_lpstrLabel, nLen + 1) > 0); + } + } + + T* pT = static_cast(this); + pT->CalcLabelRect(); + + // set hyperlink (defaults to label), or just activate tool tip if already set + if(m_lpstrHyperLink == NULL && !IsCommandButton()) + { + if(m_lpstrLabel != NULL) + SetHyperLink(m_lpstrLabel); + } +#ifndef _WIN32_WCE + else + { + m_tip.Activate(TRUE); + m_tip.AddTool(m_hWnd, m_lpstrHyperLink, &m_rcLink, 1); + } +#endif // !_WIN32_WCE + + // set link colors + if(m_bPaintLabel) + { + CRegKeyEx rk; + LONG lRet = rk.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Internet Explorer\\Settings")); + if(lRet == ERROR_SUCCESS) + { + const int cchValue = 12; + TCHAR szValue[cchValue] = { 0 }; + ULONG ulCount = cchValue; + lRet = rk.QueryStringValue(_T("Anchor Color"), szValue, &ulCount); + if(lRet == ERROR_SUCCESS) + { + COLORREF clr = pT->_ParseColorString(szValue); + ATLASSERT(clr != CLR_INVALID); + if(clr != CLR_INVALID) + m_clrLink = clr; + } + + ulCount = cchValue; + lRet = rk.QueryStringValue(_T("Anchor Color Visited"), szValue, &ulCount); + if(lRet == ERROR_SUCCESS) + { + COLORREF clr = pT->_ParseColorString(szValue); + ATLASSERT(clr != CLR_INVALID); + if(clr != CLR_INVALID) + m_clrVisited = clr; + } + } + } + } + + static COLORREF _ParseColorString(LPTSTR lpstr) + { + int c[3] = { -1, -1, -1 }; + LPTSTR p = NULL; + for(int i = 0; i < 2; i++) + { + for(p = lpstr; *p != _T('\0'); p = ::CharNext(p)) + { + if(*p == _T(',')) + { + *p = _T('\0'); + c[i] = T::_xttoi(lpstr); + lpstr = &p[1]; + break; + } + } + if(c[i] == -1) + return CLR_INVALID; + } + if(*lpstr == _T('\0')) + return CLR_INVALID; + c[2] = T::_xttoi(lpstr); + + return RGB(c[0], c[1], c[2]); + } + + bool CalcLabelRect() + { + if(!::IsWindow(m_hWnd)) + return false; + if(m_lpstrLabel == NULL && m_lpstrHyperLink == NULL) + return false; + + CClientDC dc(m_hWnd); + RECT rcClient = { 0 }; + GetClientRect(&rcClient); + m_rcLink = rcClient; + if(!m_bPaintLabel) + return true; + + if(IsUsingTags()) + { + // find tags and label parts + LPTSTR lpstrLeft = NULL; + int cchLeft = 0; + LPTSTR lpstrLink = NULL; + int cchLink = 0; + LPTSTR lpstrRight = NULL; + int cchRight = 0; + + T* pT = static_cast(this); + pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight); + ATLASSERT(lpstrLink != NULL); + ATLASSERT(cchLink > 0); + + // get label part rects + HFONT hFontOld = dc.SelectFont(m_hFontNormal); + + UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK; + + RECT rcLeft = rcClient; + if(lpstrLeft != NULL) + dc.DrawText(lpstrLeft, cchLeft, &rcLeft, DT_LEFT | uFormat | DT_CALCRECT); + + dc.SelectFont(m_hFontLink); + RECT rcLink = rcClient; + if(lpstrLeft != NULL) + rcLink.left = rcLeft.right; + dc.DrawText(lpstrLink, cchLink, &rcLink, DT_LEFT | uFormat | DT_CALCRECT); + + dc.SelectFont(hFontOld); + + m_rcLink = rcLink; + } + else + { + HFONT hOldFont = NULL; + if(m_hFontLink != NULL) + hOldFont = dc.SelectFont(m_hFontLink); + LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink; + DWORD dwStyle = GetStyle(); + UINT uFormat = DT_LEFT; + if (dwStyle & SS_CENTER) + uFormat = DT_CENTER; + else if (dwStyle & SS_RIGHT) + uFormat = DT_RIGHT; + uFormat |= IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK; + dc.DrawText(lpstrText, -1, &m_rcLink, uFormat | DT_CALCRECT); + if(m_hFontLink != NULL) + dc.SelectFont(hOldFont); + if (dwStyle & SS_CENTER) + { + int dx = (rcClient.right - m_rcLink.right) / 2; + ::OffsetRect(&m_rcLink, dx, 0); + } + else if (dwStyle & SS_RIGHT) + { + int dx = rcClient.right - m_rcLink.right; + ::OffsetRect(&m_rcLink, dx, 0); + } + } + + return true; + } + + void CalcLabelParts(LPTSTR& lpstrLeft, int& cchLeft, LPTSTR& lpstrLink, int& cchLink, LPTSTR& lpstrRight, int& cchRight) const + { + lpstrLeft = NULL; + cchLeft = 0; + lpstrLink = NULL; + cchLink = 0; + lpstrRight = NULL; + cchRight = 0; + + LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink; + int cchText = lstrlen(lpstrText); + bool bOutsideLink = true; + for(int i = 0; i < cchText; i++) + { + if(lpstrText[i] != _T('<')) + continue; + + if(bOutsideLink) + { + if(::CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, &lpstrText[i], 3, _T(""), 3) == CSTR_EQUAL) + { + if(i > 0) + { + lpstrLeft = lpstrText; + cchLeft = i; + } + lpstrLink = &lpstrText[i + 3]; + bOutsideLink = false; + } + } + else + { + if(::CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, &lpstrText[i], 4, _T(""), 4) == CSTR_EQUAL) + { + cchLink = i - 3 - cchLeft; + if(lpstrText[i + 4] != 0) + { + lpstrRight = &lpstrText[i + 4]; + cchRight = cchText - (i + 4); + break; + } + } + } + } + + } + + void DoEraseBackground(CDCHandle dc) + { + HBRUSH hBrush = (HBRUSH)::SendMessage(GetParent(), WM_CTLCOLORSTATIC, (WPARAM)dc.m_hDC, (LPARAM)m_hWnd); + if(hBrush != NULL) + { + RECT rect = { 0 }; + GetClientRect(&rect); + dc.FillRect(&rect, hBrush); + } + } + + void DoPaint(CDCHandle dc) + { + if(IsUsingTags()) + { + // find tags and label parts + LPTSTR lpstrLeft = NULL; + int cchLeft = 0; + LPTSTR lpstrLink = NULL; + int cchLink = 0; + LPTSTR lpstrRight = NULL; + int cchRight = 0; + + T* pT = static_cast(this); + pT->CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight); + + // get label part rects + RECT rcClient = { 0 }; + GetClientRect(&rcClient); + + dc.SetBkMode(TRANSPARENT); + HFONT hFontOld = dc.SelectFont(m_hFontNormal); + + UINT uFormat = IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK; + + if(lpstrLeft != NULL) + dc.DrawText(lpstrLeft, cchLeft, &rcClient, DT_LEFT | uFormat); + + COLORREF clrOld = dc.SetTextColor(IsWindowEnabled() ? (m_bVisited ? m_clrVisited : m_clrLink) : (::GetSysColor(COLOR_GRAYTEXT))); + if(m_hFontLink != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover))) + dc.SelectFont(m_hFontLink); + else + dc.SelectFont(m_hFontNormal); + + dc.DrawText(lpstrLink, cchLink, &m_rcLink, DT_LEFT | uFormat); + + dc.SetTextColor(clrOld); + dc.SelectFont(m_hFontNormal); + if(lpstrRight != NULL) + { + RECT rcRight = { m_rcLink.right, m_rcLink.top, rcClient.right, rcClient.bottom }; + dc.DrawText(lpstrRight, cchRight, &rcRight, DT_LEFT | uFormat); + } + + if(GetFocus() == m_hWnd) + dc.DrawFocusRect(&m_rcLink); + + dc.SelectFont(hFontOld); + } + else + { + dc.SetBkMode(TRANSPARENT); + COLORREF clrOld = dc.SetTextColor(IsWindowEnabled() ? (m_bVisited ? m_clrVisited : m_clrLink) : (::GetSysColor(COLOR_GRAYTEXT))); + + HFONT hFontOld = NULL; + if(m_hFontLink != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover))) + hFontOld = dc.SelectFont(m_hFontLink); + else + hFontOld = dc.SelectFont(m_hFontNormal); + + LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink; + + DWORD dwStyle = GetStyle(); + UINT uFormat = DT_LEFT; + if (dwStyle & SS_CENTER) + uFormat = DT_CENTER; + else if (dwStyle & SS_RIGHT) + uFormat = DT_RIGHT; + uFormat |= IsSingleLine() ? DT_SINGLELINE : DT_WORDBREAK; + + dc.DrawText(lpstrText, -1, &m_rcLink, uFormat); + + if(GetFocus() == m_hWnd) + dc.DrawFocusRect(&m_rcLink); + + dc.SetTextColor(clrOld); + dc.SelectFont(hFontOld); + } + } + +#ifndef _WIN32_WCE + BOOL StartTrackMouseLeave() + { + TRACKMOUSEEVENT tme = { 0 }; + tme.cbSize = sizeof(tme); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = m_hWnd; + return _TrackMouseEvent(&tme); + } +#endif // !_WIN32_WCE + +// Implementation helpers + bool IsUnderlined() const + { + return ((m_dwExtendedStyle & (HLINK_NOTUNDERLINED | HLINK_UNDERLINEHOVER)) == 0); + } + + bool IsNotUnderlined() const + { + return ((m_dwExtendedStyle & HLINK_NOTUNDERLINED) != 0); + } + + bool IsUnderlineHover() const + { + return ((m_dwExtendedStyle & HLINK_UNDERLINEHOVER) != 0); + } + + bool IsCommandButton() const + { + return ((m_dwExtendedStyle & HLINK_COMMANDBUTTON) != 0); + } + + bool IsNotifyButton() const + { + return ((m_dwExtendedStyle & HLINK_NOTIFYBUTTON) == HLINK_NOTIFYBUTTON); + } + + bool IsUsingTags() const + { + return ((m_dwExtendedStyle & HLINK_USETAGS) != 0); + } + + bool IsUsingTagsBold() const + { + return ((m_dwExtendedStyle & HLINK_USETAGSBOLD) == HLINK_USETAGSBOLD); + } + + bool IsUsingToolTip() const + { + return ((m_dwExtendedStyle & HLINK_NOTOOLTIP) == 0); + } + + bool IsAutoCreateLinkFont() const + { + return ((m_dwExtendedStyle & HLINK_AUTOCREATELINKFONT) == HLINK_AUTOCREATELINKFONT); + } + + bool IsSingleLine() const + { + return ((m_dwExtendedStyle & HLINK_SINGLELINE) == HLINK_SINGLELINE); + } + + static int _xttoi(const TCHAR* nptr) + { +#ifndef _ATL_MIN_CRT + return _ttoi(nptr); +#else // _ATL_MIN_CRT + while(*nptr == _T(' ')) // skip spaces + ++nptr; + + int c = (int)(_TUCHAR)*nptr++; + int sign = c; // save sign indication + if (c == _T('-') || c == _T('+')) + c = (int)(_TUCHAR)*nptr++; // skip sign + + int total = 0; + while((TCHAR)c >= _T('0') && (TCHAR)c <= _T('9')) + { + total = 10 * total + ((TCHAR)c - _T('0')); // accumulate digit + c = (int)(_TUCHAR)*nptr++; // get next char + } + + // return result, negated if necessary + return ((TCHAR)sign != _T('-')) ? total : -total; +#endif // _ATL_MIN_CRT + } +}; + +class CHyperLink : public CHyperLinkImpl +{ +public: + DECLARE_WND_CLASS(_T("WTL_HyperLink")) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CWaitCursor - displays a wait cursor + +class CWaitCursor +{ +public: +// Data + HCURSOR m_hWaitCursor; + HCURSOR m_hOldCursor; + bool m_bInUse; + +// Constructor/destructor + CWaitCursor(bool bSet = true, LPCTSTR lpstrCursor = IDC_WAIT, bool bSys = true) : m_hOldCursor(NULL), m_bInUse(false) + { + HINSTANCE hInstance = bSys ? NULL : ModuleHelper::GetResourceInstance(); + m_hWaitCursor = ::LoadCursor(hInstance, lpstrCursor); + ATLASSERT(m_hWaitCursor != NULL); + + if(bSet) + Set(); + } + + ~CWaitCursor() + { + Restore(); + } + +// Methods + bool Set() + { + if(m_bInUse) + return false; + m_hOldCursor = ::SetCursor(m_hWaitCursor); + m_bInUse = true; + return true; + } + + bool Restore() + { + if(!m_bInUse) + return false; + ::SetCursor(m_hOldCursor); + m_bInUse = false; + return true; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CCustomWaitCursor - for custom and animated cursors + +class CCustomWaitCursor : public CWaitCursor +{ +public: +// Constructor/destructor + CCustomWaitCursor(ATL::_U_STRINGorID cursor, bool bSet = true, HINSTANCE hInstance = NULL) : + CWaitCursor(false, IDC_WAIT, true) + { + if(hInstance == NULL) + hInstance = ModuleHelper::GetResourceInstance(); + m_hWaitCursor = (HCURSOR)::LoadImage(hInstance, cursor.m_lpstr, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE); + + if(bSet) + Set(); + } + + ~CCustomWaitCursor() + { + Restore(); +#if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))) + ::DestroyCursor(m_hWaitCursor); +#endif // !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))) + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CMultiPaneStatusBarCtrl - Status Bar with multiple panes + +template +class ATL_NO_VTABLE CMultiPaneStatusBarCtrlImpl : public ATL::CWindowImpl< T, TBase > +{ +public: + DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName()) + +// Data + enum { m_cxPaneMargin = 3 }; + + int m_nPanes; + int* m_pPane; + +// Constructor/destructor + CMultiPaneStatusBarCtrlImpl() : m_nPanes(0), m_pPane(NULL) + { } + + ~CMultiPaneStatusBarCtrlImpl() + { + delete [] m_pPane; + } + +// Methods + HWND Create(HWND hWndParent, LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR) + { +#if (_MSC_VER >= 1300) + return ATL::CWindowImpl< T, TBase >::Create(hWndParent, rcDefault, lpstrText, dwStyle, 0, nID); +#else // !(_MSC_VER >= 1300) + typedef ATL::CWindowImpl< T, TBase > _baseClass; + return _baseClass::Create(hWndParent, rcDefault, lpstrText, dwStyle, 0, nID); +#endif // !(_MSC_VER >= 1300) + } + + HWND Create(HWND hWndParent, UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR) + { + const int cchMax = 128; // max text length is 127 for status bars (+1 for null) + TCHAR szText[cchMax]; + szText[0] = 0; + ::LoadString(ModuleHelper::GetResourceInstance(), nTextID, szText, cchMax); + return Create(hWndParent, szText, dwStyle, nID); + } + + BOOL SetPanes(int* pPanes, int nPanes, bool bSetText = true) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPanes > 0); + + m_nPanes = nPanes; + delete [] m_pPane; + m_pPane = NULL; + + ATLTRY(m_pPane = new int[nPanes]); + ATLASSERT(m_pPane != NULL); + if(m_pPane == NULL) + return FALSE; + + CTempBuffer buff; + int* pPanesPos = buff.Allocate(nPanes); + ATLASSERT(pPanesPos != NULL); + if(pPanesPos == NULL) + return FALSE; + + SecureHelper::memcpy_x(m_pPane, nPanes * sizeof(int), pPanes, nPanes * sizeof(int)); + + // get status bar DC and set font + CClientDC dc(m_hWnd); + HFONT hOldFont = dc.SelectFont(GetFont()); + + // get status bar borders + int arrBorders[3] = { 0 }; + GetBorders(arrBorders); + + const int cchBuff = 128; + TCHAR szBuff[cchBuff] = { 0 }; + SIZE size = { 0, 0 }; + int cxLeft = arrBorders[0]; + + // calculate right edge of each part + for(int i = 0; i < nPanes; i++) + { + if(pPanes[i] == ID_DEFAULT_PANE) + { + // make very large, will be resized later + pPanesPos[i] = INT_MAX / 2; + } + else + { + ::LoadString(ModuleHelper::GetResourceInstance(), pPanes[i], szBuff, cchBuff); + dc.GetTextExtent(szBuff, lstrlen(szBuff), &size); + T* pT = static_cast(this); + pT; + pPanesPos[i] = cxLeft + size.cx + arrBorders[2] + 2 * pT->m_cxPaneMargin; + } + cxLeft = pPanesPos[i]; + } + + BOOL bRet = SetParts(nPanes, pPanesPos); + + if(bRet && bSetText) + { + for(int i = 0; i < nPanes; i++) + { + if(pPanes[i] != ID_DEFAULT_PANE) + { + ::LoadString(ModuleHelper::GetResourceInstance(), pPanes[i], szBuff, cchBuff); + SetPaneText(m_pPane[i], szBuff); + } + } + } + + dc.SelectFont(hOldFont); + return bRet; + } + + bool GetPaneTextLength(int nPaneID, int* pcchLength = NULL, int* pnType = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return false; + + int nLength = GetTextLength(nIndex, pnType); + if(pcchLength != NULL) + *pcchLength = nLength; + + return true; + } + + BOOL GetPaneText(int nPaneID, LPTSTR lpstrText, int* pcchLength = NULL, int* pnType = NULL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return FALSE; + + int nLength = GetText(nIndex, lpstrText, pnType); + if(pcchLength != NULL) + *pcchLength = nLength; + + return TRUE; + } + + BOOL SetPaneText(int nPaneID, LPCTSTR lpstrText, int nType = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return FALSE; + + return SetText(nIndex, lpstrText, nType); + } + + BOOL GetPaneRect(int nPaneID, LPRECT lpRect) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return FALSE; + + return GetRect(nIndex, lpRect); + } + + BOOL SetPaneWidth(int nPaneID, int cxWidth) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPaneID != ID_DEFAULT_PANE); // Can't resize this one + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return FALSE; + + // get pane positions + CTempBuffer buff; + int* pPanesPos = buff.Allocate(m_nPanes); + if(pPanesPos == NULL) + return FALSE; + GetParts(m_nPanes, pPanesPos); + // calculate offset + int cxPaneWidth = pPanesPos[nIndex] - ((nIndex == 0) ? 0 : pPanesPos[nIndex - 1]); + int cxOff = cxWidth - cxPaneWidth; + // find variable width pane + int nDef = m_nPanes; + for(int i = 0; i < m_nPanes; i++) + { + if(m_pPane[i] == ID_DEFAULT_PANE) + { + nDef = i; + break; + } + } + // resize + if(nIndex < nDef) // before default pane + { + for(int i = nIndex; i < nDef; i++) + pPanesPos[i] += cxOff; + + } + else // after default one + { + for(int i = nDef; i < nIndex; i++) + pPanesPos[i] -= cxOff; + } + // set pane postions + return SetParts(m_nPanes, pPanesPos); + } + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + BOOL GetPaneTipText(int nPaneID, LPTSTR lpstrText, int nSize) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return FALSE; + + GetTipText(nIndex, lpstrText, nSize); + return TRUE; + } + + BOOL SetPaneTipText(int nPaneID, LPCTSTR lpstrText) + { + ATLASSERT(::IsWindow(m_hWnd)); + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return FALSE; + + SetTipText(nIndex, lpstrText); + return TRUE; + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +#if ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500)) + BOOL GetPaneIcon(int nPaneID, HICON& hIcon) const + { + ATLASSERT(::IsWindow(m_hWnd)); + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return FALSE; + + hIcon = GetIcon(nIndex); + return TRUE; + } + + BOOL SetPaneIcon(int nPaneID, HICON hIcon) + { + ATLASSERT(::IsWindow(m_hWnd)); + int nIndex = GetPaneIndexFromID(nPaneID); + if(nIndex == -1) + return FALSE; + + return SetIcon(nIndex, hIcon); + } +#endif // ((_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)) || (defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500)) + +// Message map and handlers + BEGIN_MSG_MAP(CMultiPaneStatusBarCtrlImpl< T >) + MESSAGE_HANDLER(WM_SIZE, OnSize) + END_MSG_MAP() + + LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); + if(wParam != SIZE_MINIMIZED && m_nPanes > 0) + { + T* pT = static_cast(this); + pT->UpdatePanesLayout(); + } + return lRet; + } + +// Implementation + BOOL UpdatePanesLayout() + { + // get pane positions + CTempBuffer buff; + int* pPanesPos = buff.Allocate(m_nPanes); + ATLASSERT(pPanesPos != NULL); + if(pPanesPos == NULL) + return FALSE; + int nRet = GetParts(m_nPanes, pPanesPos); + ATLASSERT(nRet == m_nPanes); + if(nRet != m_nPanes) + return FALSE; + // calculate offset + RECT rcClient = { 0 }; + GetClientRect(&rcClient); + int cxOff = rcClient.right - pPanesPos[m_nPanes - 1]; +#ifndef _WIN32_WCE + // Move panes left if size grip box is present + if((GetStyle() & SBARS_SIZEGRIP) != 0) + cxOff -= ::GetSystemMetrics(SM_CXVSCROLL) + ::GetSystemMetrics(SM_CXEDGE); +#endif // !_WIN32_WCE + // find variable width pane + int i; + for(i = 0; i < m_nPanes; i++) + { + if(m_pPane[i] == ID_DEFAULT_PANE) + break; + } + // resize all panes from the variable one to the right + if((i < m_nPanes) && (pPanesPos[i] + cxOff) > ((i == 0) ? 0 : pPanesPos[i - 1])) + { + for(; i < m_nPanes; i++) + pPanesPos[i] += cxOff; + } + // set pane postions + return SetParts(m_nPanes, pPanesPos); + } + + int GetPaneIndexFromID(int nPaneID) const + { + for(int i = 0; i < m_nPanes; i++) + { + if(m_pPane[i] == nPaneID) + return i; + } + + return -1; // not found + } +}; + +class CMultiPaneStatusBarCtrl : public CMultiPaneStatusBarCtrlImpl +{ +public: + DECLARE_WND_SUPERCLASS(_T("WTL_MultiPaneStatusBar"), GetWndClassName()) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CPaneContainer - provides header with title and close button for panes + +// pane container extended styles +#define PANECNT_NOCLOSEBUTTON 0x00000001 +#define PANECNT_VERTICAL 0x00000002 +#define PANECNT_FLATBORDER 0x00000004 +#define PANECNT_NOBORDER 0x00000008 + +template +class ATL_NO_VTABLE CPaneContainerImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CCustomDraw< T > +{ +public: + DECLARE_WND_CLASS_EX(NULL, 0, -1) + +// Constants + enum + { + m_cxyBorder = 2, + m_cxyTextOffset = 4, + m_cxyBtnOffset = 1, + + m_cchTitle = 80, + + m_cxImageTB = 13, + m_cyImageTB = 11, + m_cxyBtnAddTB = 7, + + m_cxToolBar = m_cxImageTB + m_cxyBtnAddTB + m_cxyBorder + m_cxyBtnOffset, + + m_xBtnImageLeft = 6, + m_yBtnImageTop = 5, + m_xBtnImageRight = 12, + m_yBtnImageBottom = 11, + + m_nCloseBtnID = ID_PANE_CLOSE + }; + +// Data members + CToolBarCtrl m_tb; + ATL::CWindow m_wndClient; + int m_cxyHeader; + TCHAR m_szTitle[m_cchTitle]; + DWORD m_dwExtendedStyle; // Pane container specific extended styles + HFONT m_hFont; + bool m_bInternalFont; + + +// Constructor + CPaneContainerImpl() : m_cxyHeader(0), m_dwExtendedStyle(0), m_hFont(NULL), m_bInternalFont(false) + { + m_szTitle[0] = 0; + } + +// Attributes + DWORD GetPaneContainerExtendedStyle() const + { + return m_dwExtendedStyle; + } + + DWORD SetPaneContainerExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) + { + DWORD dwPrevStyle = m_dwExtendedStyle; + if(dwMask == 0) + m_dwExtendedStyle = dwExtendedStyle; + else + m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); + if(m_hWnd != NULL) + { + T* pT = static_cast(this); + bool bUpdate = false; + + if(((dwPrevStyle & PANECNT_NOCLOSEBUTTON) != 0) && ((m_dwExtendedStyle & PANECNT_NOCLOSEBUTTON) == 0)) // add close button + { + pT->CreateCloseButton(); + bUpdate = true; + } + else if(((dwPrevStyle & PANECNT_NOCLOSEBUTTON) == 0) && ((m_dwExtendedStyle & PANECNT_NOCLOSEBUTTON) != 0)) // remove close button + { + pT->DestroyCloseButton(); + bUpdate = true; + } + + if((dwPrevStyle & PANECNT_VERTICAL) != (m_dwExtendedStyle & PANECNT_VERTICAL)) // change orientation + { + pT->CalcSize(); + bUpdate = true; + } + + if((dwPrevStyle & (PANECNT_FLATBORDER | PANECNT_NOBORDER)) != + (m_dwExtendedStyle & (PANECNT_FLATBORDER | PANECNT_NOBORDER))) // change border + { + bUpdate = true; + } + + if(bUpdate) + pT->UpdateLayout(); + } + return dwPrevStyle; + } + + HWND GetClient() const + { + return m_wndClient; + } + + HWND SetClient(HWND hWndClient) + { + HWND hWndOldClient = m_wndClient; + m_wndClient = hWndClient; + if(m_hWnd != NULL) + { + T* pT = static_cast(this); + pT->UpdateLayout(); + } + return hWndOldClient; + } + + BOOL GetTitle(LPTSTR lpstrTitle, int cchLength) const + { + ATLASSERT(lpstrTitle != NULL); + + errno_t nRet = SecureHelper::strncpy_x(lpstrTitle, cchLength, m_szTitle, _TRUNCATE); + + return (nRet == 0 || nRet == STRUNCATE); + } + + BOOL SetTitle(LPCTSTR lpstrTitle) + { + ATLASSERT(lpstrTitle != NULL); + + errno_t nRet = SecureHelper::strncpy_x(m_szTitle, m_cchTitle, lpstrTitle, _TRUNCATE); + bool bRet = (nRet == 0 || nRet == STRUNCATE); + if(bRet && m_hWnd != NULL) + { + T* pT = static_cast(this); + pT->UpdateLayout(); + } + + return bRet; + } + + int GetTitleLength() const + { + return lstrlen(m_szTitle); + } + +// Methods + HWND Create(HWND hWndParent, LPCTSTR lpstrTitle = NULL, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + DWORD dwExStyle = 0, UINT nID = 0, LPVOID lpCreateParam = NULL) + { + if(lpstrTitle != NULL) + SecureHelper::strncpy_x(m_szTitle, m_cchTitle, lpstrTitle, _TRUNCATE); +#if (_MSC_VER >= 1300) + return ATL::CWindowImpl< T, TBase, TWinTraits >::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam); +#else // !(_MSC_VER >= 1300) + typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass; + return _baseClass::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam); +#endif // !(_MSC_VER >= 1300) + } + + HWND Create(HWND hWndParent, UINT uTitleID, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + DWORD dwExStyle = 0, UINT nID = 0, LPVOID lpCreateParam = NULL) + { + if(uTitleID != 0U) + ::LoadString(ModuleHelper::GetResourceInstance(), uTitleID, m_szTitle, m_cchTitle); +#if (_MSC_VER >= 1300) + return ATL::CWindowImpl< T, TBase, TWinTraits >::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam); +#else // !(_MSC_VER >= 1300) + typedef ATL::CWindowImpl< T, TBase, TWinTraits > _baseClass; + return _baseClass::Create(hWndParent, rcDefault, NULL, dwStyle, dwExStyle, nID, lpCreateParam); +#endif // !(_MSC_VER >= 1300) + } + + BOOL EnableCloseButton(BOOL bEnable) + { + ATLASSERT(::IsWindow(m_hWnd)); + T* pT = static_cast(this); + pT; // avoid level 4 warning + return (m_tb.m_hWnd != NULL) ? m_tb.EnableButton(pT->m_nCloseBtnID, bEnable) : FALSE; + } + + void UpdateLayout() + { + RECT rcClient = { 0 }; + GetClientRect(&rcClient); + T* pT = static_cast(this); + pT->UpdateLayout(rcClient.right, rcClient.bottom); + } + +// Message map and handlers + BEGIN_MSG_MAP(CPaneContainerImpl) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) + MESSAGE_HANDLER(WM_GETFONT, OnGetFont) + MESSAGE_HANDLER(WM_SETFONT, OnSetFont) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) + MESSAGE_HANDLER(WM_PAINT, OnPaint) +#ifndef _WIN32_WCE + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) +#endif // !_WIN32_WCE + MESSAGE_HANDLER(WM_NOTIFY, OnNotify) + MESSAGE_HANDLER(WM_COMMAND, OnCommand) + FORWARD_NOTIFICATIONS() + END_MSG_MAP() + + LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + if(m_hFont == NULL) + { + // The same as AtlCreateControlFont() for horizontal pane +#ifndef _WIN32_WCE + LOGFONT lf = { 0 }; + ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE); + if(IsVertical()) + lf.lfEscapement = 900; // 90 degrees + m_hFont = ::CreateFontIndirect(&lf); +#else // CE specific + m_hFont = (HFONT)::GetStockObject(SYSTEM_FONT); + if(IsVertical()) + { + CLogFont lf(m_hFont); + lf.lfEscapement = 900; // 90 degrees + m_hFont = ::CreateFontIndirect(&lf); + } +#endif // _WIN32_WCE + m_bInternalFont = true; + } + + T* pT = static_cast(this); + pT->CalcSize(); + + if((m_dwExtendedStyle & PANECNT_NOCLOSEBUTTON) == 0) + pT->CreateCloseButton(); + + return 0; + } + + LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + if(m_bInternalFont) + { + ::DeleteObject(m_hFont); + m_hFont = NULL; + m_bInternalFont = false; + } + + return 0; + } + + LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->UpdateLayout(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + return 0; + } + + LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + if(m_wndClient.m_hWnd != NULL) + m_wndClient.SetFocus(); + return 0; + } + + LRESULT OnGetFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return (LRESULT)m_hFont; + } + + LRESULT OnSetFont(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + if(m_bInternalFont) + { + ::DeleteObject(m_hFont); + m_bInternalFont = false; + } + + m_hFont = (HFONT)wParam; + + T* pT = static_cast(this); + pT->CalcSize(); + + if((BOOL)lParam != FALSE) + pT->UpdateLayout(); + + return 0; + } + + LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return 1; // no background needed + } + + LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + if(wParam != NULL) + { + pT->DrawPaneTitle((HDC)wParam); + + if(m_wndClient.m_hWnd == NULL) // no client window + pT->DrawPane((HDC)wParam); + } + else + { + CPaintDC dc(m_hWnd); + pT->DrawPaneTitle(dc.m_hDC); + + if(m_wndClient.m_hWnd == NULL) // no client window + pT->DrawPane(dc.m_hDC); + } + + return 0; + } + + LRESULT OnNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + if(m_tb.m_hWnd == NULL) + { + bHandled = FALSE; + return 1; + } + + T* pT = static_cast(this); + pT; + LPNMHDR lpnmh = (LPNMHDR)lParam; + LRESULT lRet = 0; + + // pass toolbar custom draw notifications to the base class + if(lpnmh->code == NM_CUSTOMDRAW && lpnmh->hwndFrom == m_tb.m_hWnd) + lRet = CCustomDraw< T >::OnCustomDraw(0, lpnmh, bHandled); +#ifndef _WIN32_WCE + // tooltip notifications come with the tooltip window handle and button ID, + // pass them to the parent if we don't handle them + else if(lpnmh->code == TTN_GETDISPINFO && lpnmh->idFrom == pT->m_nCloseBtnID) + bHandled = pT->GetToolTipText(lpnmh); +#endif // !_WIN32_WCE + // only let notifications not from the toolbar go to the parent + else if(lpnmh->hwndFrom != m_tb.m_hWnd && lpnmh->idFrom != pT->m_nCloseBtnID) + bHandled = FALSE; + + return lRet; + } + + LRESULT OnCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + // if command comes from the close button, substitute HWND of the pane container instead + if(m_tb.m_hWnd != NULL && (HWND)lParam == m_tb.m_hWnd) + return ::SendMessage(GetParent(), WM_COMMAND, wParam, (LPARAM)m_hWnd); + + bHandled = FALSE; + return 1; + } + +// Custom draw overrides + DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/) + { + return CDRF_NOTIFYITEMDRAW; // we need per-item notifications + } + + DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw) + { + CDCHandle dc = lpNMCustomDraw->hdc; +#if (_WIN32_IE >= 0x0400) + RECT& rc = lpNMCustomDraw->rc; +#else // !(_WIN32_IE >= 0x0400) + RECT rc; + m_tb.GetItemRect(0, &rc); +#endif // !(_WIN32_IE >= 0x0400) + + dc.FillRect(&rc, COLOR_3DFACE); + + return CDRF_NOTIFYPOSTPAINT; + } + + DWORD OnItemPostPaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw) + { + CDCHandle dc = lpNMCustomDraw->hdc; +#if (_WIN32_IE >= 0x0400) + RECT& rc = lpNMCustomDraw->rc; +#else // !(_WIN32_IE >= 0x0400) + RECT rc = { 0 }; + m_tb.GetItemRect(0, &rc); +#endif // !(_WIN32_IE >= 0x0400) + + RECT rcImage = { m_xBtnImageLeft, m_yBtnImageTop, m_xBtnImageRight + 1, m_yBtnImageBottom + 1 }; + ::OffsetRect(&rcImage, rc.left, rc.top); + T* pT = static_cast(this); + + if((lpNMCustomDraw->uItemState & CDIS_DISABLED) != 0) + { + RECT rcShadow = rcImage; + ::OffsetRect(&rcShadow, 1, 1); + CPen pen1; + pen1.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DHILIGHT)); + pT->DrawButtonImage(dc, rcShadow, pen1); + CPen pen2; + pen2.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DSHADOW)); + pT->DrawButtonImage(dc, rcImage, pen2); + } + else + { + if((lpNMCustomDraw->uItemState & CDIS_SELECTED) != 0) + ::OffsetRect(&rcImage, 1, 1); + CPen pen; + pen.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNTEXT)); + pT->DrawButtonImage(dc, rcImage, pen); + } + + return CDRF_DODEFAULT; // continue with the default item painting + } + +// Implementation - overrideable methods + void UpdateLayout(int cxWidth, int cyHeight) + { + ATLASSERT(::IsWindow(m_hWnd)); + RECT rect = { 0 }; + + if(IsVertical()) + { + ::SetRect(&rect, 0, 0, m_cxyHeader, cyHeight); + if(m_tb.m_hWnd != NULL) + m_tb.SetWindowPos(NULL, m_cxyBorder, m_cxyBorder + m_cxyBtnOffset, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); + + if(m_wndClient.m_hWnd != NULL) + m_wndClient.SetWindowPos(NULL, m_cxyHeader, 0, cxWidth - m_cxyHeader, cyHeight, SWP_NOZORDER); + else + rect.right = cxWidth; + } + else + { + ::SetRect(&rect, 0, 0, cxWidth, m_cxyHeader); + if(m_tb.m_hWnd != NULL) + m_tb.SetWindowPos(NULL, rect.right - m_cxToolBar, m_cxyBorder + m_cxyBtnOffset, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); + + if(m_wndClient.m_hWnd != NULL) + m_wndClient.SetWindowPos(NULL, 0, m_cxyHeader, cxWidth, cyHeight - m_cxyHeader, SWP_NOZORDER); + else + rect.bottom = cyHeight; + } + + InvalidateRect(&rect); + } + + void CreateCloseButton() + { + ATLASSERT(m_tb.m_hWnd == NULL); + // create toolbar for the "x" button + m_tb.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NORESIZE | CCS_NOPARENTALIGN | CCS_NOMOVEY | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT, 0); + ATLASSERT(m_tb.IsWindow()); + + if(m_tb.m_hWnd != NULL) + { + T* pT = static_cast(this); + pT; // avoid level 4 warning + + m_tb.SetButtonStructSize(); + + TBBUTTON tbbtn = { 0 }; + tbbtn.idCommand = pT->m_nCloseBtnID; + tbbtn.fsState = TBSTATE_ENABLED; + tbbtn.fsStyle = TBSTYLE_BUTTON; + m_tb.AddButtons(1, &tbbtn); + + m_tb.SetBitmapSize(m_cxImageTB, m_cyImageTB); + m_tb.SetButtonSize(m_cxImageTB + m_cxyBtnAddTB, m_cyImageTB + m_cxyBtnAddTB); + + if(IsVertical()) + m_tb.SetWindowPos(NULL, m_cxyBorder + m_cxyBtnOffset, m_cxyBorder + m_cxyBtnOffset, m_cxImageTB + m_cxyBtnAddTB, m_cyImageTB + m_cxyBtnAddTB, SWP_NOZORDER | SWP_NOACTIVATE); + else + m_tb.SetWindowPos(NULL, 0, 0, m_cxImageTB + m_cxyBtnAddTB, m_cyImageTB + m_cxyBtnAddTB, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); + } + } + + void DestroyCloseButton() + { + if(m_tb.m_hWnd != NULL) + m_tb.DestroyWindow(); + } + + void CalcSize() + { + T* pT = static_cast(this); + CFontHandle font = pT->GetTitleFont(); + if(font.IsNull()) + font = (HFONT)::GetStockObject(SYSTEM_FONT); + LOGFONT lf = { 0 }; + font.GetLogFont(lf); + if(IsVertical()) + { + m_cxyHeader = m_cxImageTB + m_cxyBtnAddTB + m_cxyBorder; + } + else + { + int cyFont = abs(lf.lfHeight) + m_cxyBorder + 2 * m_cxyTextOffset; + int cyBtn = m_cyImageTB + m_cxyBtnAddTB + m_cxyBorder + 2 * m_cxyBtnOffset; + m_cxyHeader = max(cyFont, cyBtn); + } + } + + HFONT GetTitleFont() const + { + return m_hFont; + } + +#ifndef _WIN32_WCE + BOOL GetToolTipText(LPNMHDR /*lpnmh*/) + { + return FALSE; + } +#endif // !_WIN32_WCE + + void DrawPaneTitle(CDCHandle dc) + { + RECT rect = { 0 }; + GetClientRect(&rect); + + UINT uBorder = BF_LEFT | BF_TOP | BF_ADJUST; + if(IsVertical()) + { + rect.right = rect.left + m_cxyHeader; + uBorder |= BF_BOTTOM; + } + else + { + rect.bottom = rect.top + m_cxyHeader; + uBorder |= BF_RIGHT; + } + + if((m_dwExtendedStyle & PANECNT_NOBORDER) == 0) + { + if((m_dwExtendedStyle & PANECNT_FLATBORDER) != 0) + uBorder |= BF_FLAT; + dc.DrawEdge(&rect, EDGE_ETCHED, uBorder); + } + dc.FillRect(&rect, COLOR_3DFACE); + + // draw title text + dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT)); + dc.SetBkMode(TRANSPARENT); + T* pT = static_cast(this); + HFONT hFontOld = dc.SelectFont(pT->GetTitleFont()); +#ifdef _WIN32_WCE + const UINT DT_END_ELLIPSIS = 0; +#endif // _WIN32_WCE + + if(IsVertical()) + { + rect.top += m_cxyTextOffset; + rect.bottom -= m_cxyTextOffset; + if(m_tb.m_hWnd != NULL) + rect.top += m_cxToolBar;; + + RECT rcCalc = { rect.left, rect.bottom, rect.right, rect.top }; + int cxFont = dc.DrawText(m_szTitle, -1, &rcCalc, DT_TOP | DT_SINGLELINE | DT_END_ELLIPSIS | DT_CALCRECT); + RECT rcText = { 0 }; + rcText.left = (rect.right - rect.left - cxFont) / 2; + rcText.right = rcText.left + (rect.bottom - rect.top); + rcText.top = rect.bottom; + rcText.bottom = rect.top; + dc.DrawText(m_szTitle, -1, &rcText, DT_TOP | DT_SINGLELINE | DT_END_ELLIPSIS); + } + else + { + rect.left += m_cxyTextOffset; + rect.right -= m_cxyTextOffset; + if(m_tb.m_hWnd != NULL) + rect.right -= m_cxToolBar;; + + dc.DrawText(m_szTitle, -1, &rect, DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS); + } + + dc.SelectFont(hFontOld); + } + + // called only if pane is empty + void DrawPane(CDCHandle dc) + { + RECT rect = { 0 }; + GetClientRect(&rect); + if(IsVertical()) + rect.left += m_cxyHeader; + else + rect.top += m_cxyHeader; + if((GetExStyle() & WS_EX_CLIENTEDGE) == 0) + dc.DrawEdge(&rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); + dc.FillRect(&rect, COLOR_APPWORKSPACE); + } + + // drawing helper - draws "x" button image + void DrawButtonImage(CDCHandle dc, RECT& rcImage, HPEN hPen) + { +#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) + HPEN hPenOld = dc.SelectPen(hPen); + + dc.MoveTo(rcImage.left, rcImage.top); + dc.LineTo(rcImage.right, rcImage.bottom); + dc.MoveTo(rcImage.left + 1, rcImage.top); + dc.LineTo(rcImage.right + 1, rcImage.bottom); + + dc.MoveTo(rcImage.left, rcImage.bottom - 1); + dc.LineTo(rcImage.right, rcImage.top - 1); + dc.MoveTo(rcImage.left + 1, rcImage.bottom - 1); + dc.LineTo(rcImage.right + 1, rcImage.top - 1); + + dc.SelectPen(hPenOld); +#else // (_WIN32_WCE < 400) + rcImage; + hPen; + // no support for the "x" button image +#endif // (_WIN32_WCE < 400) + } + + bool IsVertical() const + { + return ((m_dwExtendedStyle & PANECNT_VERTICAL) != 0); + } +}; + +class CPaneContainer : public CPaneContainerImpl +{ +public: + DECLARE_WND_CLASS_EX(_T("WTL_PaneContainer"), 0, -1) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CSortListViewCtrl - implements sorting for a listview control + +// sort listview extended styles +#define SORTLV_USESHELLBITMAPS 0x00000001 + +// Notification sent to parent when sort column is changed by user clicking header. +#define SLVN_SORTCHANGED LVN_LAST + +// A LPNMSORTLISTVIEW is sent with the SLVN_SORTCHANGED notification +typedef struct tagNMSORTLISTVIEW +{ + NMHDR hdr; + int iNewSortColumn; + int iOldSortColumn; +} NMSORTLISTVIEW, *LPNMSORTLISTVIEW; + +// Column sort types. Can be set on a per-column basis with the SetColumnSortType method. +enum +{ + LVCOLSORT_NONE, + LVCOLSORT_TEXT, // default + LVCOLSORT_TEXTNOCASE, + LVCOLSORT_LONG, + LVCOLSORT_DOUBLE, + LVCOLSORT_DECIMAL, + LVCOLSORT_DATETIME, + LVCOLSORT_DATE, + LVCOLSORT_TIME, + LVCOLSORT_CUSTOM, + LVCOLSORT_LAST = LVCOLSORT_CUSTOM +}; + + +template +class CSortListViewImpl +{ +public: + enum + { + m_cchCmpTextMax = 32, // overrideable + m_cxSortImage = 16, + m_cySortImage = 15, + m_cxSortArrow = 11, + m_cySortArrow = 6, + m_iSortUp = 0, // index of sort bitmaps + m_iSortDown = 1, + m_nShellSortUpID = 133 + }; + + // passed to LVCompare functions as lParam1 and lParam2 + struct LVCompareParam + { + int iItem; + DWORD_PTR dwItemData; + union + { + long lValue; + double dblValue; + DECIMAL decValue; + LPCTSTR pszValue; + }; + }; + + // passed to LVCompare functions as the lParamSort parameter + struct LVSortInfo + { + T* pT; + int iSortCol; + bool bDescending; + }; + + bool m_bSortDescending; + bool m_bCommCtrl6; + int m_iSortColumn; + CBitmap m_bmSort[2]; + int m_fmtOldSortCol; + HBITMAP m_hbmOldSortCol; + DWORD m_dwSortLVExtendedStyle; + ATL::CSimpleArray m_arrColSortType; + bool m_bUseWaitCursor; + + CSortListViewImpl() : + m_bSortDescending(false), + m_bCommCtrl6(false), + m_iSortColumn(-1), + m_fmtOldSortCol(0), + m_hbmOldSortCol(NULL), + m_dwSortLVExtendedStyle(SORTLV_USESHELLBITMAPS), + m_bUseWaitCursor(true) + { +#ifndef _WIN32_WCE + DWORD dwMajor = 0; + DWORD dwMinor = 0; + HRESULT hRet = ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor); + m_bCommCtrl6 = SUCCEEDED(hRet) && dwMajor >= 6; +#endif // !_WIN32_WCE + } + +// Attributes + void SetSortColumn(int iCol) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + CHeaderCtrl header = pT->GetHeader(); + ATLASSERT(header.m_hWnd != NULL); + ATLASSERT(iCol >= -1 && iCol < m_arrColSortType.GetSize()); + + int iOldSortCol = m_iSortColumn; + m_iSortColumn = iCol; + if(m_bCommCtrl6) + { +#ifndef HDF_SORTUP + const int HDF_SORTUP = 0x0400; +#endif // HDF_SORTUP +#ifndef HDF_SORTDOWN + const int HDF_SORTDOWN = 0x0200; +#endif // HDF_SORTDOWN + const int nMask = HDF_SORTUP | HDF_SORTDOWN; + HDITEM hditem = { HDI_FORMAT }; + if(iOldSortCol != iCol && iOldSortCol >= 0 && header.GetItem(iOldSortCol, &hditem)) + { + hditem.fmt &= ~nMask; + header.SetItem(iOldSortCol, &hditem); + } + if(iCol >= 0 && header.GetItem(iCol, &hditem)) + { + hditem.fmt &= ~nMask; + hditem.fmt |= m_bSortDescending ? HDF_SORTDOWN : HDF_SORTUP; + header.SetItem(iCol, &hditem); + } + return; + } + + if(m_bmSort[m_iSortUp].IsNull()) + pT->CreateSortBitmaps(); + + // restore previous sort column's bitmap, if any, and format + HDITEM hditem = { HDI_BITMAP | HDI_FORMAT }; + if(iOldSortCol != iCol && iOldSortCol >= 0) + { + hditem.hbm = m_hbmOldSortCol; + hditem.fmt = m_fmtOldSortCol; + header.SetItem(iOldSortCol, &hditem); + } + + // save new sort column's bitmap and format, and add our sort bitmap + if(iCol >= 0 && header.GetItem(iCol, &hditem)) + { + if(iOldSortCol != iCol) + { + m_fmtOldSortCol = hditem.fmt; + m_hbmOldSortCol = hditem.hbm; + } + hditem.fmt &= ~HDF_IMAGE; + hditem.fmt |= HDF_BITMAP | HDF_BITMAP_ON_RIGHT; + int i = m_bSortDescending ? m_iSortDown : m_iSortUp; + hditem.hbm = m_bmSort[i]; + header.SetItem(iCol, &hditem); + } + } + + int GetSortColumn() const + { + return m_iSortColumn; + } + + void SetColumnSortType(int iCol, WORD wType) + { + ATLASSERT(iCol >= 0 && iCol < m_arrColSortType.GetSize()); + ATLASSERT(wType >= LVCOLSORT_NONE && wType <= LVCOLSORT_LAST); + m_arrColSortType[iCol] = wType; + } + + WORD GetColumnSortType(int iCol) const + { + ATLASSERT((iCol >= 0) && iCol < m_arrColSortType.GetSize()); + return m_arrColSortType[iCol]; + } + + int GetColumnCount() const + { + const T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + CHeaderCtrl header = pT->GetHeader(); + return header.m_hWnd != NULL ? header.GetItemCount() : 0; + } + + bool IsSortDescending() const + { + return m_bSortDescending; + } + + DWORD GetSortListViewExtendedStyle() const + { + return m_dwSortLVExtendedStyle; + } + + DWORD SetSortListViewExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) + { + DWORD dwPrevStyle = m_dwSortLVExtendedStyle; + if(dwMask == 0) + m_dwSortLVExtendedStyle = dwExtendedStyle; + else + m_dwSortLVExtendedStyle = (m_dwSortLVExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); + return dwPrevStyle; + } + +// Operations + bool DoSortItems(int iCol, bool bDescending = false) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + ATLASSERT(iCol >= 0 && iCol < m_arrColSortType.GetSize()); + + WORD wType = m_arrColSortType[iCol]; + if(wType == LVCOLSORT_NONE) + return false; + + int nCount = pT->GetItemCount(); + if(nCount < 2) + { + m_bSortDescending = bDescending; + SetSortColumn(iCol); + return true; + } + + CWaitCursor waitCursor(false); + if(m_bUseWaitCursor) + waitCursor.Set(); + + LVCompareParam* pParam = NULL; + ATLTRY(pParam = new LVCompareParam[nCount]); + PFNLVCOMPARE pFunc = NULL; + TCHAR pszTemp[pT->m_cchCmpTextMax]; + bool bStrValue = false; + + switch(wType) + { + case LVCOLSORT_TEXT: + pFunc = (PFNLVCOMPARE)pT->LVCompareText; + case LVCOLSORT_TEXTNOCASE: + if(pFunc == NULL) + pFunc = (PFNLVCOMPARE)pT->LVCompareTextNoCase; + case LVCOLSORT_CUSTOM: + { + if(pFunc == NULL) + pFunc = (PFNLVCOMPARE)pT->LVCompareCustom; + + for(int i = 0; i < nCount; i++) + { + pParam[i].iItem = i; + pParam[i].dwItemData = pT->GetItemData(i); + pParam[i].pszValue = new TCHAR[pT->m_cchCmpTextMax]; + pT->GetItemText(i, iCol, (LPTSTR)pParam[i].pszValue, pT->m_cchCmpTextMax); + pT->SetItemData(i, (DWORD_PTR)&pParam[i]); + } + bStrValue = true; + } + break; + case LVCOLSORT_LONG: + { + pFunc = (PFNLVCOMPARE)pT->LVCompareLong; + for(int i = 0; i < nCount; i++) + { + pParam[i].iItem = i; + pParam[i].dwItemData = pT->GetItemData(i); + pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax); + pParam[i].lValue = pT->StrToLong(pszTemp); + pT->SetItemData(i, (DWORD_PTR)&pParam[i]); + } + } + break; + case LVCOLSORT_DOUBLE: + { + pFunc = (PFNLVCOMPARE)pT->LVCompareDouble; + for(int i = 0; i < nCount; i++) + { + pParam[i].iItem = i; + pParam[i].dwItemData = pT->GetItemData(i); + pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax); + pParam[i].dblValue = pT->StrToDouble(pszTemp); + pT->SetItemData(i, (DWORD_PTR)&pParam[i]); + } + } + break; + case LVCOLSORT_DECIMAL: + { + pFunc = (PFNLVCOMPARE)pT->LVCompareDecimal; + for(int i = 0; i < nCount; i++) + { + pParam[i].iItem = i; + pParam[i].dwItemData = pT->GetItemData(i); + pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax); + pT->StrToDecimal(pszTemp, &pParam[i].decValue); + pT->SetItemData(i, (DWORD_PTR)&pParam[i]); + } + } + break; + case LVCOLSORT_DATETIME: + case LVCOLSORT_DATE: + case LVCOLSORT_TIME: + { + pFunc = (PFNLVCOMPARE)pT->LVCompareDouble; + DWORD dwFlags = LOCALE_NOUSEROVERRIDE; + if(wType == LVCOLSORT_DATE) + dwFlags |= VAR_DATEVALUEONLY; + else if(wType == LVCOLSORT_TIME) + dwFlags |= VAR_TIMEVALUEONLY; + for(int i = 0; i < nCount; i++) + { + pParam[i].iItem = i; + pParam[i].dwItemData = pT->GetItemData(i); + pT->GetItemText(i, iCol, pszTemp, pT->m_cchCmpTextMax); + pParam[i].dblValue = pT->DateStrToDouble(pszTemp, dwFlags); + pT->SetItemData(i, (DWORD_PTR)&pParam[i]); + } + } + break; + default: + ATLTRACE2(atlTraceUI, 0, _T("Unknown value for sort type in CSortListViewImpl::DoSortItems()\n")); + break; + } // switch(wType) + + ATLASSERT(pFunc != NULL); + LVSortInfo lvsi = { pT, iCol, bDescending }; + bool bRet = ((BOOL)pT->DefWindowProc(LVM_SORTITEMS, (WPARAM)&lvsi, (LPARAM)pFunc) != FALSE); + for(int i = 0; i < nCount; i++) + { + DWORD_PTR dwItemData = pT->GetItemData(i); + LVCompareParam* p = (LVCompareParam*)dwItemData; + ATLASSERT(p != NULL); + if(bStrValue) + delete [] (TCHAR*)p->pszValue; + pT->SetItemData(i, p->dwItemData); + } + delete [] pParam; + + if(bRet) + { + m_bSortDescending = bDescending; + SetSortColumn(iCol); + } + + if(m_bUseWaitCursor) + waitCursor.Restore(); + + return bRet; + } + + void CreateSortBitmaps() + { + if((m_dwSortLVExtendedStyle & SORTLV_USESHELLBITMAPS) != 0) + { + bool bFree = false; + LPCTSTR pszModule = _T("shell32.dll"); + HINSTANCE hShell = ::GetModuleHandle(pszModule); + + if (hShell == NULL) + { + hShell = ::LoadLibrary(pszModule); + bFree = true; + } + + if (hShell != NULL) + { + bool bSuccess = true; + for(int i = m_iSortUp; i <= m_iSortDown; i++) + { + if(!m_bmSort[i].IsNull()) + m_bmSort[i].DeleteObject(); + m_bmSort[i] = (HBITMAP)::LoadImage(hShell, MAKEINTRESOURCE(m_nShellSortUpID + i), +#ifndef _WIN32_WCE + IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS); +#else // CE specific + IMAGE_BITMAP, 0, 0, 0); +#endif // _WIN32_WCE + if(m_bmSort[i].IsNull()) + { + bSuccess = false; + break; + } + } + if(bFree) + ::FreeLibrary(hShell); + if(bSuccess) + return; + } + } + + T* pT = static_cast(this); + for(int i = m_iSortUp; i <= m_iSortDown; i++) + { + if(!m_bmSort[i].IsNull()) + m_bmSort[i].DeleteObject(); + + CDC dcMem; + CClientDC dc(::GetDesktopWindow()); + dcMem.CreateCompatibleDC(dc.m_hDC); + m_bmSort[i].CreateCompatibleBitmap(dc.m_hDC, m_cxSortImage, m_cySortImage); + HBITMAP hbmOld = dcMem.SelectBitmap(m_bmSort[i]); + RECT rc = {0,0,m_cxSortImage, m_cySortImage}; + pT->DrawSortBitmap(dcMem.m_hDC, i, &rc); + dcMem.SelectBitmap(hbmOld); + dcMem.DeleteDC(); + } + } + + void NotifyParentSortChanged(int iNewSortCol, int iOldSortCol) + { + T* pT = static_cast(this); + int nID = pT->GetDlgCtrlID(); + NMSORTLISTVIEW nm = { { pT->m_hWnd, nID, SLVN_SORTCHANGED }, iNewSortCol, iOldSortCol }; + ::SendMessage(pT->GetParent(), WM_NOTIFY, (WPARAM)nID, (LPARAM)&nm); + } + +// Overrideables + int CompareItemsCustom(LVCompareParam* /*pItem1*/, LVCompareParam* /*pItem2*/, int /*iSortCol*/) + { + // pItem1 and pItem2 contain valid iItem, dwItemData, and pszValue members. + // If item1 > item2 return 1, if item1 < item2 return -1, else return 0. + return 0; + } + + void DrawSortBitmap(CDCHandle dc, int iBitmap, LPRECT prc) + { + dc.FillRect(prc, ::GetSysColorBrush(COLOR_BTNFACE)); + HBRUSH hbrOld = dc.SelectBrush(::GetSysColorBrush(COLOR_BTNSHADOW)); + CPen pen; + pen.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNSHADOW)); + HPEN hpenOld = dc.SelectPen(pen); + POINT ptOrg = { (m_cxSortImage - m_cxSortArrow) / 2, (m_cySortImage - m_cySortArrow) / 2 }; + if(iBitmap == m_iSortUp) + { + POINT pts[3] = + { + { ptOrg.x + m_cxSortArrow / 2, ptOrg.y }, + { ptOrg.x, ptOrg.y + m_cySortArrow - 1 }, + { ptOrg.x + m_cxSortArrow - 1, ptOrg.y + m_cySortArrow - 1 } + }; + dc.Polygon(pts, 3); + } + else + { + POINT pts[3] = + { + { ptOrg.x, ptOrg.y }, + { ptOrg.x + m_cxSortArrow / 2, ptOrg.y + m_cySortArrow - 1 }, + { ptOrg.x + m_cxSortArrow - 1, ptOrg.y } + }; + dc.Polygon(pts, 3); + } + dc.SelectBrush(hbrOld); + dc.SelectPen(hpenOld); + } + + double DateStrToDouble(LPCTSTR lpstr, DWORD dwFlags) + { + ATLASSERT(lpstr != NULL); + if(lpstr == NULL || lpstr[0] == _T('\0')) + return 0; + + USES_CONVERSION; + HRESULT hRet = E_FAIL; + DATE dRet = 0; + if (FAILED(hRet = ::VarDateFromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, dwFlags, &dRet))) + { + ATLTRACE2(atlTraceUI, 0, _T("VarDateFromStr failed with result of 0x%8.8X\n"), hRet); + dRet = 0; + } + return dRet; + } + + long StrToLong(LPCTSTR lpstr) + { + ATLASSERT(lpstr != NULL); + if(lpstr == NULL || lpstr[0] == _T('\0')) + return 0; + + USES_CONVERSION; + HRESULT hRet = E_FAIL; + long lRet = 0; + if (FAILED(hRet = ::VarI4FromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, &lRet))) + { + ATLTRACE2(atlTraceUI, 0, _T("VarI4FromStr failed with result of 0x%8.8X\n"), hRet); + lRet = 0; + } + return lRet; + } + + double StrToDouble(LPCTSTR lpstr) + { + ATLASSERT(lpstr != NULL); + if(lpstr == NULL || lpstr[0] == _T('\0')) + return 0; + + USES_CONVERSION; + HRESULT hRet = E_FAIL; + double dblRet = 0; + if (FAILED(hRet = ::VarR8FromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, &dblRet))) + { + ATLTRACE2(atlTraceUI, 0, _T("VarR8FromStr failed with result of 0x%8.8X\n"), hRet); + dblRet = 0; + } + return dblRet; + } + + bool StrToDecimal(LPCTSTR lpstr, DECIMAL* pDecimal) + { + ATLASSERT(lpstr != NULL); + ATLASSERT(pDecimal != NULL); + if(lpstr == NULL || pDecimal == NULL) + return false; + + USES_CONVERSION; + HRESULT hRet = E_FAIL; + if (FAILED(hRet = ::VarDecFromStr((LPOLESTR)T2COLE(lpstr), LANG_USER_DEFAULT, LOCALE_NOUSEROVERRIDE, pDecimal))) + { + ATLTRACE2(atlTraceUI, 0, _T("VarDecFromStr failed with result of 0x%8.8X\n"), hRet); + pDecimal->Lo64 = 0; + pDecimal->Hi32 = 0; + pDecimal->signscale = 0; + return false; + } + return true; + } + +// Overrideable PFNLVCOMPARE functions + static int CALLBACK LVCompareText(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) + { + ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); + + LVCompareParam* pParam1 = (LVCompareParam*)lParam1; + LVCompareParam* pParam2 = (LVCompareParam*)lParam2; + LVSortInfo* pInfo = (LVSortInfo*)lParamSort; + + int nRet = lstrcmp(pParam1->pszValue, pParam2->pszValue); + return pInfo->bDescending ? -nRet : nRet; + } + + static int CALLBACK LVCompareTextNoCase(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) + { + ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); + + LVCompareParam* pParam1 = (LVCompareParam*)lParam1; + LVCompareParam* pParam2 = (LVCompareParam*)lParam2; + LVSortInfo* pInfo = (LVSortInfo*)lParamSort; + + int nRet = lstrcmpi(pParam1->pszValue, pParam2->pszValue); + return pInfo->bDescending ? -nRet : nRet; + } + + static int CALLBACK LVCompareLong(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) + { + ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); + + LVCompareParam* pParam1 = (LVCompareParam*)lParam1; + LVCompareParam* pParam2 = (LVCompareParam*)lParam2; + LVSortInfo* pInfo = (LVSortInfo*)lParamSort; + + int nRet = 0; + if(pParam1->lValue > pParam2->lValue) + nRet = 1; + else if(pParam1->lValue < pParam2->lValue) + nRet = -1; + return pInfo->bDescending ? -nRet : nRet; + } + + static int CALLBACK LVCompareDouble(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) + { + ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); + + LVCompareParam* pParam1 = (LVCompareParam*)lParam1; + LVCompareParam* pParam2 = (LVCompareParam*)lParam2; + LVSortInfo* pInfo = (LVSortInfo*)lParamSort; + + int nRet = 0; + if(pParam1->dblValue > pParam2->dblValue) + nRet = 1; + else if(pParam1->dblValue < pParam2->dblValue) + nRet = -1; + return pInfo->bDescending ? -nRet : nRet; + } + + static int CALLBACK LVCompareCustom(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) + { + ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); + + LVCompareParam* pParam1 = (LVCompareParam*)lParam1; + LVCompareParam* pParam2 = (LVCompareParam*)lParam2; + LVSortInfo* pInfo = (LVSortInfo*)lParamSort; + + int nRet = pInfo->pT->CompareItemsCustom(pParam1, pParam2, pInfo->iSortCol); + return pInfo->bDescending ? -nRet : nRet; + } + +#ifndef _WIN32_WCE + static int CALLBACK LVCompareDecimal(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) + { + ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); + + LVCompareParam* pParam1 = (LVCompareParam*)lParam1; + LVCompareParam* pParam2 = (LVCompareParam*)lParam2; + LVSortInfo* pInfo = (LVSortInfo*)lParamSort; + + int nRet = (int)::VarDecCmp(&pParam1->decValue, &pParam2->decValue); + nRet--; + return pInfo->bDescending ? -nRet : nRet; + } +#else + // Compare mantissas, ignore sign and scale + static int CompareMantissas(const DECIMAL& decLeft, const DECIMAL& decRight) + { + if (decLeft.Hi32 < decRight.Hi32) + { + return -1; + } + if (decLeft.Hi32 > decRight.Hi32) + { + return 1; + } + // Here, decLeft.Hi32 == decRight.Hi32 + if (decLeft.Lo64 < decRight.Lo64) + { + return -1; + } + if (decLeft.Lo64 > decRight.Lo64) + { + return 1; + } + return 0; + } + + // return values: VARCMP_LT, VARCMP_EQ, VARCMP_GT, VARCMP_NULL + static HRESULT VarDecCmp(const DECIMAL* pdecLeft, const DECIMAL* pdecRight) + { + static const ULONG powersOfTen[] = + { + 10ul, + 100ul, + 1000ul, + 10000ul, + 100000ul, + 1000000ul, + 10000000ul, + 100000000ul, + 1000000000ul + }; + static const int largestPower = sizeof(powersOfTen) / sizeof(powersOfTen[0]); + if (!pdecLeft || !pdecRight) + { + return VARCMP_NULL; + } + + // Degenerate case - at least one comparand is of the form + // [+-]0*10^N (denormalized zero) + bool bLeftZero = (!pdecLeft->Lo64 && !pdecLeft->Hi32); + bool bRightZero = (!pdecRight->Lo64 && !pdecRight->Hi32); + if (bLeftZero && bRightZero) + { + return VARCMP_EQ; + } + bool bLeftNeg = ((pdecLeft->sign & DECIMAL_NEG) != 0); + bool bRightNeg = ((pdecRight->sign & DECIMAL_NEG) != 0); + if (bLeftZero) + { + return (bRightNeg ? VARCMP_GT : VARCMP_LT); + } + // This also covers the case where the comparands have different signs + if (bRightZero || bLeftNeg != bRightNeg) + { + return (bLeftNeg ? VARCMP_LT : VARCMP_GT); + } + + // Here both comparands have the same sign and need to be compared + // on mantissa and scale. The result is obvious when + // 1. Scales are equal (then compare mantissas) + // 2. A number with smaller scale is also the one with larger mantissa + // (then this number is obviously larger) + // In the remaining case, we would multiply the number with smaller + // scale by 10 and simultaneously increment its scale (which amounts to + // adding trailing zeros after decimal point), until the numbers fall under + // one of the two cases above + DECIMAL temp; + bool bInvert = bLeftNeg; // the final result needs to be inverted + if (pdecLeft->scale < pdecRight->scale) + { + temp = *pdecLeft; + } + else + { + temp = *pdecRight; + pdecRight = pdecLeft; + bInvert = !bInvert; + } + + // Now temp is the number with smaller (or equal) scale, and + // we can modify it freely without touching original parameters + int comp; + while ((comp = CompareMantissas(temp, *pdecRight)) < 0 && + temp.scale < pdecRight->scale) + { + // Multiply by an appropriate power of 10 + int scaleDiff = pdecRight->scale - temp.scale; + if (scaleDiff > largestPower) + { + // Keep the multiplier representable in 32bit + scaleDiff = largestPower; + } + DWORDLONG power = powersOfTen[scaleDiff - 1]; + // Multiply temp's mantissa by power + DWORDLONG product = temp.Lo32 * power; + ULONG carry = static_cast(product >> 32); + temp.Lo32 = static_cast(product); + product = temp.Mid32 * power + carry; + carry = static_cast(product >> 32); + temp.Mid32 = static_cast(product); + product = temp.Hi32 * power + carry; + if (static_cast(product >> 32)) + { + // Multiplication overflowed - pdecLeft is clearly larger + break; + } + temp.Hi32 = static_cast(product); + temp.scale = (BYTE)(temp.scale + scaleDiff); + } + if (temp.scale < pdecRight->scale) + { + comp = 1; + } + if (bInvert) + { + comp = -comp; + } + return (comp > 0 ? VARCMP_GT : comp < 0 ? VARCMP_LT : VARCMP_EQ); + } + + static int CALLBACK LVCompareDecimal(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) + { + ATLASSERT(lParam1 != NULL && lParam2 != NULL && lParamSort != NULL); + + LVCompareParam* pParam1 = (LVCompareParam*)lParam1; + LVCompareParam* pParam2 = (LVCompareParam*)lParam2; + LVSortInfo* pInfo = (LVSortInfo*)lParamSort; + + int nRet = (int)VarDecCmp(&pParam1->decValue, &pParam2->decValue); + nRet--; + return pInfo->bDescending ? -nRet : nRet; + } +#endif // !_WIN32_WCE + + BEGIN_MSG_MAP(CSortListViewImpl) + MESSAGE_HANDLER(LVM_INSERTCOLUMN, OnInsertColumn) + MESSAGE_HANDLER(LVM_DELETECOLUMN, OnDeleteColumn) + NOTIFY_CODE_HANDLER(HDN_ITEMCLICKA, OnHeaderItemClick) + NOTIFY_CODE_HANDLER(HDN_ITEMCLICKW, OnHeaderItemClick) + MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) + END_MSG_MAP() + + LRESULT OnInsertColumn(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + LRESULT lRet = pT->DefWindowProc(uMsg, wParam, lParam); + if(lRet == -1) + return -1; + + WORD wType = 0; + m_arrColSortType.Add(wType); + int nCount = m_arrColSortType.GetSize(); + ATLASSERT(nCount == GetColumnCount()); + + for(int i = nCount - 1; i > lRet; i--) + m_arrColSortType[i] = m_arrColSortType[i - 1]; + m_arrColSortType[(int)lRet] = LVCOLSORT_TEXT; + + if(lRet <= m_iSortColumn) + m_iSortColumn++; + + return lRet; + } + + LRESULT OnDeleteColumn(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + LRESULT lRet = pT->DefWindowProc(uMsg, wParam, lParam); + if(lRet == 0) + return 0; + + int iCol = (int)wParam; + if(m_iSortColumn == iCol) + m_iSortColumn = -1; + else if(m_iSortColumn > iCol) + m_iSortColumn--; + m_arrColSortType.RemoveAt(iCol); + + return lRet; + } + + LRESULT OnHeaderItemClick(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) + { + LPNMHEADER p = (LPNMHEADER)pnmh; + if(p->iButton == 0) + { + int iOld = m_iSortColumn; + bool bDescending = (m_iSortColumn == p->iItem) ? !m_bSortDescending : false; + if(DoSortItems(p->iItem, bDescending)) + NotifyParentSortChanged(p->iItem, iOld); + } + bHandled = FALSE; + return 0; + } + + LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { +#ifndef _WIN32_WCE + if(wParam == SPI_SETNONCLIENTMETRICS) + GetSystemSettings(); +#else // CE specific + wParam; // avoid level 4 warning + GetSystemSettings(); +#endif // _WIN32_WCE + bHandled = FALSE; + return 0; + } + + void GetSystemSettings() + { + if(!m_bCommCtrl6 && !m_bmSort[m_iSortUp].IsNull()) + { + T* pT = static_cast(this); + pT->CreateSortBitmaps(); + if(m_iSortColumn != -1) + SetSortColumn(m_iSortColumn); + } + } + +}; + + +typedef ATL::CWinTraits CSortListViewCtrlTraits; + +template +class ATL_NO_VTABLE CSortListViewCtrlImpl: public ATL::CWindowImpl, public CSortListViewImpl +{ +public: + DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName()) + + bool SortItems(int iCol, bool bDescending = false) + { + return DoSortItems(iCol, bDescending); + } + + BEGIN_MSG_MAP(CSortListViewCtrlImpl) + MESSAGE_HANDLER(LVM_INSERTCOLUMN, CSortListViewImpl::OnInsertColumn) + MESSAGE_HANDLER(LVM_DELETECOLUMN, CSortListViewImpl::OnDeleteColumn) + NOTIFY_CODE_HANDLER(HDN_ITEMCLICKA, CSortListViewImpl::OnHeaderItemClick) + NOTIFY_CODE_HANDLER(HDN_ITEMCLICKW, CSortListViewImpl::OnHeaderItemClick) + MESSAGE_HANDLER(WM_SETTINGCHANGE, CSortListViewImpl::OnSettingChange) + END_MSG_MAP() +}; + +class CSortListViewCtrl : public CSortListViewCtrlImpl +{ +public: + DECLARE_WND_SUPERCLASS(_T("WTL_SortListViewCtrl"), GetWndClassName()) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CTabView - implements tab view window + +// TabView Notifications +#define TBVN_PAGEACTIVATED (0U-741) +#define TBVN_CONTEXTMENU (0U-742) + +// Notification data for TBVN_CONTEXTMENU +struct TBVCONTEXTMENUINFO +{ + NMHDR hdr; + POINT pt; +}; + +typedef TBVCONTEXTMENUINFO* LPTBVCONTEXTMENUINFO; + + +template +class ATL_NO_VTABLE CTabViewImpl : public ATL::CWindowImpl +{ +public: + DECLARE_WND_CLASS_EX(NULL, 0, COLOR_APPWORKSPACE) + +// Declarations and enums + struct TABVIEWPAGE + { + HWND hWnd; + LPTSTR lpstrTitle; + LPVOID pData; + }; + + struct TCITEMEXTRA + { + TCITEMHEADER tciheader; + TABVIEWPAGE tvpage; + + operator LPTCITEM() { return (LPTCITEM)this; } + }; + + enum + { + m_nTabID = 1313, + m_cxMoveMark = 6, + m_cyMoveMark = 3, + m_nMenuItemsMax = (ID_WINDOW_TABLAST - ID_WINDOW_TABFIRST + 1) + }; + +// Data members + ATL::CContainedWindowT m_tab; + int m_cyTabHeight; + + int m_nActivePage; + + int m_nInsertItem; + POINT m_ptStartDrag; + + CMenuHandle m_menu; + + int m_cchTabTextLength; + + int m_nMenuItemsCount; + + ATL::CWindow m_wndTitleBar; + LPTSTR m_lpstrTitleBarBase; + int m_cchTitleBarLength; + + CImageList m_ilDrag; + + bool m_bDestroyPageOnRemove:1; + bool m_bDestroyImageList:1; + bool m_bActivePageMenuItem:1; + bool m_bActiveAsDefaultMenuItem:1; + bool m_bEmptyMenuItem:1; + bool m_bWindowsMenuItem:1; + bool m_bNoTabDrag:1; + // internal + bool m_bTabCapture:1; + bool m_bTabDrag:1; + bool m_bInternalFont:1; + +// Constructor/destructor + CTabViewImpl() : + m_nActivePage(-1), + m_cyTabHeight(0), + m_tab(this, 1), + m_nInsertItem(-1), + m_cchTabTextLength(30), + m_nMenuItemsCount(10), + m_lpstrTitleBarBase(NULL), + m_cchTitleBarLength(100), + m_bDestroyPageOnRemove(true), + m_bDestroyImageList(true), + m_bActivePageMenuItem(true), + m_bActiveAsDefaultMenuItem(false), + m_bEmptyMenuItem(false), + m_bWindowsMenuItem(false), + m_bNoTabDrag(false), + m_bTabCapture(false), + m_bTabDrag(false), + m_bInternalFont(false) + { + m_ptStartDrag.x = 0; + m_ptStartDrag.y = 0; + } + + ~CTabViewImpl() + { + delete [] m_lpstrTitleBarBase; + } + +// Message filter function - to be called from PreTranslateMessage of the main window + BOOL PreTranslateMessage(MSG* pMsg) + { + if(IsWindow() == FALSE) + return FALSE; + + BOOL bRet = FALSE; + + // Check for TabView built-in accelerators (Ctrl+Tab/Ctrl+Shift+Tab - next/previous page) + int nCount = GetPageCount(); + if(nCount > 0) + { + bool bControl = (::GetKeyState(VK_CONTROL) < 0); + if((pMsg->message == WM_KEYDOWN) && (pMsg->wParam == VK_TAB) && bControl) + { + if(nCount > 1) + { + int nPage = m_nActivePage; + bool bShift = (::GetKeyState(VK_SHIFT) < 0); + if(bShift) + nPage = (nPage > 0) ? (nPage - 1) : (nCount - 1); + else + nPage = ((nPage >= 0) && (nPage < (nCount - 1))) ? (nPage + 1) : 0; + + SetActivePage(nPage); + T* pT = static_cast(this); + pT->OnPageActivated(m_nActivePage); + } + + bRet = TRUE; + } + } + + // If we are doing drag-drop, check for Escape key that cancels it + if(bRet == FALSE) + { + if(m_bTabCapture && pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) + { + ::ReleaseCapture(); + bRet = TRUE; + } + } + + // Pass the message to the active page + if(bRet == FALSE) + { + if(m_nActivePage != -1) + bRet = (BOOL)::SendMessage(GetPageHWND(m_nActivePage), WM_FORWARDMSG, 0, (LPARAM)pMsg); + } + + return bRet; + } + +// Attributes + int GetPageCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return m_tab.GetItemCount(); + } + + int GetActivePage() const + { + return m_nActivePage; + } + + void SetActivePage(int nPage) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + T* pT = static_cast(this); + + SetRedraw(FALSE); + + if(m_nActivePage != -1) + ::ShowWindow(GetPageHWND(m_nActivePage), FALSE); + m_nActivePage = nPage; + m_tab.SetCurSel(m_nActivePage); + ::ShowWindow(GetPageHWND(m_nActivePage), TRUE); + + pT->UpdateLayout(); + + SetRedraw(TRUE); + RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); + + if(::GetFocus() != m_tab.m_hWnd) + ::SetFocus(GetPageHWND(m_nActivePage)); + + pT->UpdateTitleBar(); + pT->UpdateMenu(); + } + + HIMAGELIST GetImageList() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return m_tab.GetImageList(); + } + + HIMAGELIST SetImageList(HIMAGELIST hImageList) + { + ATLASSERT(::IsWindow(m_hWnd)); + return m_tab.SetImageList(hImageList); + } + + void SetWindowMenu(HMENU hMenu) + { + ATLASSERT(::IsWindow(m_hWnd)); + + m_menu = hMenu; + + T* pT = static_cast(this); + pT->UpdateMenu(); + } + + void SetTitleBarWindow(HWND hWnd) + { + ATLASSERT(::IsWindow(m_hWnd)); + + delete [] m_lpstrTitleBarBase; + m_lpstrTitleBarBase = NULL; + + m_wndTitleBar = hWnd; + if(hWnd == NULL) + return; + + int cchLen = m_wndTitleBar.GetWindowTextLength() + 1; + ATLTRY(m_lpstrTitleBarBase = new TCHAR[cchLen]); + if(m_lpstrTitleBarBase != NULL) + { + m_wndTitleBar.GetWindowText(m_lpstrTitleBarBase, cchLen); + T* pT = static_cast(this); + pT->UpdateTitleBar(); + } + } + +// Page attributes + HWND GetPageHWND(int nPage) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_PARAM; + m_tab.GetItem(nPage, tcix); + + return tcix.tvpage.hWnd; + } + + LPCTSTR GetPageTitle(int nPage) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_PARAM; + if(m_tab.GetItem(nPage, tcix) == FALSE) + return NULL; + + return tcix.tvpage.lpstrTitle; + } + + bool SetPageTitle(int nPage, LPCTSTR lpstrTitle) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + T* pT = static_cast(this); + + int cchBuff = lstrlen(lpstrTitle) + 1; + LPTSTR lpstrBuff = NULL; + ATLTRY(lpstrBuff = new TCHAR[cchBuff]); + if(lpstrBuff == NULL) + return false; + + SecureHelper::strcpy_x(lpstrBuff, cchBuff, lpstrTitle); + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_PARAM; + if(m_tab.GetItem(nPage, tcix) == FALSE) + return false; + + CTempBuffer buff; + LPTSTR lpstrTabText = buff.Allocate(m_cchTabTextLength + 1); + if(lpstrTabText == NULL) + return false; + + delete [] tcix.tvpage.lpstrTitle; + + pT->ShortenTitle(lpstrTitle, lpstrTabText, m_cchTabTextLength + 1); + + tcix.tciheader.mask = TCIF_TEXT | TCIF_PARAM; + tcix.tciheader.pszText = lpstrTabText; + tcix.tvpage.lpstrTitle = lpstrBuff; + if(m_tab.SetItem(nPage, tcix) == FALSE) + return false; + + pT->UpdateTitleBar(); + pT->UpdateMenu(); + + return true; + } + + LPVOID GetPageData(int nPage) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_PARAM; + m_tab.GetItem(nPage, tcix); + + return tcix.tvpage.pData; + } + + LPVOID SetPageData(int nPage, LPVOID pData) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_PARAM; + m_tab.GetItem(nPage, tcix); + LPVOID pDataOld = tcix.tvpage.pData; + + tcix.tvpage.pData = pData; + m_tab.SetItem(nPage, tcix); + + return pDataOld; + } + + int GetPageImage(int nPage) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_IMAGE; + m_tab.GetItem(nPage, tcix); + + return tcix.tciheader.iImage; + } + + int SetPageImage(int nPage, int nImage) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_IMAGE; + m_tab.GetItem(nPage, tcix); + int nImageOld = tcix.tciheader.iImage; + + tcix.tciheader.iImage = nImage; + m_tab.SetItem(nPage, tcix); + + return nImageOld; + } + +// Operations + bool AddPage(HWND hWndView, LPCTSTR lpstrTitle, int nImage = -1, LPVOID pData = NULL) + { + return InsertPage(GetPageCount(), hWndView, lpstrTitle, nImage, pData); + } + + bool InsertPage(int nPage, HWND hWndView, LPCTSTR lpstrTitle, int nImage = -1, LPVOID pData = NULL) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(nPage == GetPageCount() || IsValidPageIndex(nPage)); + + T* pT = static_cast(this); + + int cchBuff = lstrlen(lpstrTitle) + 1; + LPTSTR lpstrBuff = NULL; + ATLTRY(lpstrBuff = new TCHAR[cchBuff]); + if(lpstrBuff == NULL) + return false; + + SecureHelper::strcpy_x(lpstrBuff, cchBuff, lpstrTitle); + + CTempBuffer buff; + LPTSTR lpstrTabText = buff.Allocate(m_cchTabTextLength + 1); + if(lpstrTabText == NULL) + return false; + + pT->ShortenTitle(lpstrTitle, lpstrTabText, m_cchTabTextLength + 1); + + SetRedraw(FALSE); + + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM; + tcix.tciheader.pszText = lpstrTabText; + tcix.tciheader.iImage = nImage; + tcix.tvpage.hWnd = hWndView; + tcix.tvpage.lpstrTitle = lpstrBuff; + tcix.tvpage.pData = pData; + int nItem = m_tab.InsertItem(nPage, tcix); + if(nItem == -1) + { + delete [] lpstrBuff; + SetRedraw(TRUE); + return false; + } + + SetActivePage(nItem); + pT->OnPageActivated(m_nActivePage); + + if(GetPageCount() == 1) + pT->ShowTabControl(true); + + pT->UpdateLayout(); + + SetRedraw(TRUE); + RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); + + return true; + } + + void RemovePage(int nPage) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(IsValidPageIndex(nPage)); + + T* pT = static_cast(this); + + SetRedraw(FALSE); + + if(GetPageCount() == 1) + pT->ShowTabControl(false); + + if(m_bDestroyPageOnRemove) + ::DestroyWindow(GetPageHWND(nPage)); + else + ::ShowWindow(GetPageHWND(nPage), FALSE); + LPTSTR lpstrTitle = (LPTSTR)GetPageTitle(nPage); + delete [] lpstrTitle; + + ATLVERIFY(m_tab.DeleteItem(nPage) != FALSE); + + if(m_nActivePage == nPage) + { + m_nActivePage = -1; + + if(nPage > 0) + { + SetActivePage(nPage - 1); + } + else if(GetPageCount() > 0) + { + SetActivePage(nPage); + } + else + { + SetRedraw(TRUE); + Invalidate(); + UpdateWindow(); + pT->UpdateTitleBar(); + pT->UpdateMenu(); + } + } + else + { + nPage = (nPage < m_nActivePage) ? (m_nActivePage - 1) : m_nActivePage; + m_nActivePage = -1; + SetActivePage(nPage); + } + + pT->OnPageActivated(m_nActivePage); + } + + void RemoveAllPages() + { + ATLASSERT(::IsWindow(m_hWnd)); + + if(GetPageCount() == 0) + return; + + T* pT = static_cast(this); + + SetRedraw(FALSE); + + pT->ShowTabControl(false); + + for(int i = 0; i < GetPageCount(); i++) + { + if(m_bDestroyPageOnRemove) + ::DestroyWindow(GetPageHWND(i)); + else + ::ShowWindow(GetPageHWND(i), FALSE); + LPTSTR lpstrTitle = (LPTSTR)GetPageTitle(i); + delete [] lpstrTitle; + } + m_tab.DeleteAllItems(); + + m_nActivePage = -1; + pT->OnPageActivated(m_nActivePage); + + SetRedraw(TRUE); + Invalidate(); + UpdateWindow(); + + pT->UpdateTitleBar(); + pT->UpdateMenu(); + } + + int PageIndexFromHwnd(HWND hWnd) const + { + int nIndex = -1; + + for(int i = 0; i < GetPageCount(); i++) + { + if(GetPageHWND(i) == hWnd) + { + nIndex = i; + break; + } + } + + return nIndex; + } + + void BuildWindowMenu(HMENU hMenu, int nMenuItemsCount = 10, bool bEmptyMenuItem = true, bool bWindowsMenuItem = true, bool bActivePageMenuItem = true, bool bActiveAsDefaultMenuItem = false) + { + ATLASSERT(::IsWindow(m_hWnd)); + + CMenuHandle menu = hMenu; + T* pT = static_cast(this); + pT; // avoid level 4 warning + int nFirstPos = 0; + + // Find first menu item in our range +#ifndef _WIN32_WCE + for(nFirstPos = 0; nFirstPos < menu.GetMenuItemCount(); nFirstPos++) + { + UINT nID = menu.GetMenuItemID(nFirstPos); + if((nID >= ID_WINDOW_TABFIRST && nID <= ID_WINDOW_TABLAST) || nID == ID_WINDOW_SHOWTABLIST) + break; + } +#else // CE specific + for(nFirstPos = 0; ; nFirstPos++) + { + CMenuItemInfo mii; + mii.fMask = MIIM_ID; + BOOL bRet = menu.GetMenuItemInfo(nFirstPos, TRUE, &mii); + if(bRet == FALSE) + break; + if((mii.wID >= ID_WINDOW_TABFIRST && mii.wID <= ID_WINDOW_TABLAST) || mii.wID == ID_WINDOW_SHOWTABLIST) + break; + } +#endif // _WIN32_WCE + + // Remove all menu items for tab pages + BOOL bRet = TRUE; + while(bRet != FALSE) + bRet = menu.DeleteMenu(nFirstPos, MF_BYPOSITION); + + // Add separator if it's not already there + int nPageCount = GetPageCount(); + if((bWindowsMenuItem || (nPageCount > 0)) && (nFirstPos > 0)) + { + CMenuItemInfo mii; + mii.fMask = MIIM_TYPE; + menu.GetMenuItemInfo(nFirstPos - 1, TRUE, &mii); + if((nFirstPos <= 0) || ((mii.fType & MFT_SEPARATOR) == 0)) + { + menu.AppendMenu(MF_SEPARATOR); + nFirstPos++; + } + } + + // Add menu items for all pages + if(nPageCount > 0) + { + // Append menu items for all pages + const int cchPrefix = 3; // 2 digits + space + nMenuItemsCount = min(min(nPageCount, nMenuItemsCount), (int)m_nMenuItemsMax); + ATLASSERT(nMenuItemsCount < 100); // 2 digits only + if(nMenuItemsCount >= 100) + nMenuItemsCount = 99; + + for(int i = 0; i < nMenuItemsCount; i++) + { + LPCTSTR lpstrTitle = GetPageTitle(i); + int nLen = lstrlen(lpstrTitle); + CTempBuffer buff; + LPTSTR lpstrText = buff.Allocate(cchPrefix + nLen + 1); + ATLASSERT(lpstrText != NULL); + if(lpstrText != NULL) + { + LPCTSTR lpstrFormat = (i < 9) ? _T("&%i %s") : _T("%i %s"); + SecureHelper::wsprintf_x(lpstrText, cchPrefix + nLen + 1, lpstrFormat, i + 1, lpstrTitle); + menu.AppendMenu(MF_STRING, ID_WINDOW_TABFIRST + i, lpstrText); + } + } + + // Mark active page + if(bActivePageMenuItem && (m_nActivePage != -1)) + { +#ifndef _WIN32_WCE + if(bActiveAsDefaultMenuItem) + { + menu.SetMenuDefaultItem((UINT)-1, TRUE); + menu.SetMenuDefaultItem(nFirstPos + m_nActivePage, TRUE); + } + else +#else // CE specific + bActiveAsDefaultMenuItem; // avoid level 4 warning +#endif // _WIN32_WCE + { + menu.CheckMenuRadioItem(nFirstPos, nFirstPos + nMenuItemsCount, nFirstPos + m_nActivePage, MF_BYPOSITION); + } + } + } + else + { + if(bEmptyMenuItem) + { + menu.AppendMenu(MF_BYPOSITION | MF_STRING, ID_WINDOW_TABFIRST, pT->GetEmptyListText()); + menu.EnableMenuItem(ID_WINDOW_TABFIRST, MF_GRAYED); + } + + // Remove separator if nothing else is there + if(!bEmptyMenuItem && !bWindowsMenuItem && (nFirstPos > 0)) + { + CMenuItemInfo mii; + mii.fMask = MIIM_TYPE; + menu.GetMenuItemInfo(nFirstPos - 1, TRUE, &mii); + if((mii.fType & MFT_SEPARATOR) != 0) + menu.DeleteMenu(nFirstPos - 1, MF_BYPOSITION); + } + } + + // Add "Windows..." menu item + if(bWindowsMenuItem) + menu.AppendMenu(MF_BYPOSITION | MF_STRING, ID_WINDOW_SHOWTABLIST, pT->GetWindowsMenuItemText()); + } + +// Message map and handlers + BEGIN_MSG_MAP(CTabViewImpl) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) + MESSAGE_HANDLER(WM_GETFONT, OnGetFont) + MESSAGE_HANDLER(WM_SETFONT, OnSetFont) + NOTIFY_HANDLER(m_nTabID, TCN_SELCHANGE, OnTabChanged) + NOTIFY_ID_HANDLER(m_nTabID, OnTabNotification) +#ifndef _WIN32_WCE + NOTIFY_CODE_HANDLER(TTN_GETDISPINFO, OnTabGetDispInfo) +#endif // !_WIN32_WCE + FORWARD_NOTIFICATIONS() + ALT_MSG_MAP(1) // tab control + MESSAGE_HANDLER(WM_LBUTTONDOWN, OnTabLButtonDown) + MESSAGE_HANDLER(WM_LBUTTONUP, OnTabLButtonUp) + MESSAGE_HANDLER(WM_CAPTURECHANGED, OnTabCaptureChanged) + MESSAGE_HANDLER(WM_MOUSEMOVE, OnTabMouseMove) + MESSAGE_HANDLER(WM_RBUTTONUP, OnTabRButtonUp) + MESSAGE_HANDLER(WM_SYSKEYDOWN, OnTabSysKeyDown) + END_MSG_MAP() + + LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->CreateTabControl(); + + return 0; + } + + LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + RemoveAllPages(); + + if(m_bDestroyImageList) + { + CImageList il = m_tab.SetImageList(NULL); + if(il.m_hImageList != NULL) + il.Destroy(); + } + + if(m_bInternalFont) + { + HFONT hFont = m_tab.GetFont(); + m_tab.SetFont(NULL, FALSE); + ::DeleteObject(hFont); + m_bInternalFont = false; + } + + return 0; + } + + LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->UpdateLayout(); + return 0; + } + + LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + if(m_nActivePage != -1) + ::SetFocus(GetPageHWND(m_nActivePage)); + return 0; + } + + LRESULT OnGetFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return m_tab.SendMessage(WM_GETFONT); + } + + LRESULT OnSetFont(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + if(m_bInternalFont) + { + HFONT hFont = m_tab.GetFont(); + m_tab.SetFont(NULL, FALSE); + ::DeleteObject(hFont); + m_bInternalFont = false; + } + + m_tab.SendMessage(WM_SETFONT, wParam, lParam); + + T* pT = static_cast(this); + m_cyTabHeight = pT->CalcTabHeight(); + + if((BOOL)lParam != FALSE) + pT->UpdateLayout(); + + return 0; + } + + LRESULT OnTabChanged(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) + { + SetActivePage(m_tab.GetCurSel()); + T* pT = static_cast(this); + pT->OnPageActivated(m_nActivePage); + + return 0; + } + + LRESULT OnTabNotification(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) + { + // nothing to do - this just blocks all tab control + // notifications from being propagated further + return 0; + } + +#ifndef _WIN32_WCE + LRESULT OnTabGetDispInfo(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) + { + LPNMTTDISPINFO pTTDI = (LPNMTTDISPINFO)pnmh; + if(pTTDI->hdr.hwndFrom == m_tab.GetTooltips()) + { + T* pT = static_cast(this); + pT->UpdateTooltipText(pTTDI); + } + else + { + bHandled = FALSE; + } + + return 0; + } +#endif // !_WIN32_WCE + +// Tab control message handlers + LRESULT OnTabLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + if(!m_bNoTabDrag && (m_tab.GetItemCount() > 1)) + { + m_bTabCapture = true; + m_tab.SetCapture(); + + m_ptStartDrag.x = GET_X_LPARAM(lParam); + m_ptStartDrag.y = GET_Y_LPARAM(lParam); + } + + bHandled = FALSE; + return 0; + } + + LRESULT OnTabLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + if(m_bTabCapture) + { + if(m_bTabDrag) + { + TCHITTESTINFO hti = { 0 }; + hti.pt.x = GET_X_LPARAM(lParam); + hti.pt.y = GET_Y_LPARAM(lParam); + int nItem = m_tab.HitTest(&hti); + if(nItem != -1) + MovePage(m_nActivePage, nItem); + } + + ::ReleaseCapture(); + } + + bHandled = FALSE; + return 0; + } + + LRESULT OnTabCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_bTabCapture) + { + m_bTabCapture = false; + + if(m_bTabDrag) + { + m_bTabDrag = false; + T* pT = static_cast(this); + pT->DrawMoveMark(-1); + +#ifndef _WIN32_WCE + m_ilDrag.DragLeave(GetDesktopWindow()); +#endif // !_WIN32_WCE + m_ilDrag.EndDrag(); + + m_ilDrag.Destroy(); + m_ilDrag.m_hImageList = NULL; + } + } + + bHandled = FALSE; + return 0; + } + + LRESULT OnTabMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + bHandled = FALSE; + + if(m_bTabCapture) + { + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + + if(!m_bTabDrag) + { +#ifndef _WIN32_WCE + if(abs(m_ptStartDrag.x - GET_X_LPARAM(lParam)) >= ::GetSystemMetrics(SM_CXDRAG) || + abs(m_ptStartDrag.y - GET_Y_LPARAM(lParam)) >= ::GetSystemMetrics(SM_CYDRAG)) +#else // CE specific + if(abs(m_ptStartDrag.x - GET_X_LPARAM(lParam)) >= 4 || + abs(m_ptStartDrag.y - GET_Y_LPARAM(lParam)) >= 4) +#endif // _WIN32_WCE + { + T* pT = static_cast(this); + pT->GenerateDragImage(m_nActivePage); + + int cxCursor = ::GetSystemMetrics(SM_CXCURSOR); + int cyCursor = ::GetSystemMetrics(SM_CYCURSOR); + m_ilDrag.BeginDrag(0, -(cxCursor / 2), -(cyCursor / 2)); +#ifndef _WIN32_WCE + POINT ptEnter = m_ptStartDrag; + m_tab.ClientToScreen(&ptEnter); + m_ilDrag.DragEnter(GetDesktopWindow(), ptEnter); +#endif // !_WIN32_WCE + + m_bTabDrag = true; + } + } + + if(m_bTabDrag) + { + TCHITTESTINFO hti = { 0 }; + hti.pt = pt; + int nItem = m_tab.HitTest(&hti); + + T* pT = static_cast(this); + pT->SetMoveCursor(nItem != -1); + + if(m_nInsertItem != nItem) + pT->DrawMoveMark(nItem); + + m_ilDrag.DragShowNolock((nItem != -1) ? TRUE : FALSE); + m_tab.ClientToScreen(&pt); + m_ilDrag.DragMove(pt); + + bHandled = TRUE; + } + } + + return 0; + } + + LRESULT OnTabRButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) + { + TCHITTESTINFO hti = { 0 }; + hti.pt.x = GET_X_LPARAM(lParam); + hti.pt.y = GET_Y_LPARAM(lParam); + int nItem = m_tab.HitTest(&hti); + if(nItem != -1) + { + T* pT = static_cast(this); + pT->OnContextMenu(nItem, hti.pt); + } + + return 0; + } + + LRESULT OnTabSysKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + bool bShift = (::GetKeyState(VK_SHIFT) < 0); + if(wParam == VK_F10 && bShift) + { + if(m_nActivePage != -1) + { + RECT rect = { 0 }; + m_tab.GetItemRect(m_nActivePage, &rect); + POINT pt = { rect.left, rect.bottom }; + T* pT = static_cast(this); + pT->OnContextMenu(m_nActivePage, pt); + } + } + else + { + bHandled = FALSE; + } + + return 0; + } + +// Implementation helpers + bool IsValidPageIndex(int nPage) const + { + return (nPage >= 0 && nPage < GetPageCount()); + } + + bool MovePage(int nMovePage, int nInsertBeforePage) + { + ATLASSERT(IsValidPageIndex(nMovePage)); + ATLASSERT(IsValidPageIndex(nInsertBeforePage)); + + if(!IsValidPageIndex(nMovePage) || !IsValidPageIndex(nInsertBeforePage)) + return false; + + if(nMovePage == nInsertBeforePage) + return true; // nothing to do + + CTempBuffer buff; + LPTSTR lpstrTabText = buff.Allocate(m_cchTabTextLength + 1); + if(lpstrTabText == NULL) + return false; + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM; + tcix.tciheader.pszText = lpstrTabText; + tcix.tciheader.cchTextMax = m_cchTabTextLength + 1; + BOOL bRet = m_tab.GetItem(nMovePage, tcix); + ATLASSERT(bRet != FALSE); + if(bRet == FALSE) + return false; + + int nInsertItem = (nInsertBeforePage > nMovePage) ? nInsertBeforePage + 1 : nInsertBeforePage; + int nNewItem = m_tab.InsertItem(nInsertItem, tcix); + ATLASSERT(nNewItem == nInsertItem); + if(nNewItem != nInsertItem) + { + ATLVERIFY(m_tab.DeleteItem(nNewItem)); + return false; + } + + if(nMovePage > nInsertBeforePage) + ATLVERIFY(m_tab.DeleteItem(nMovePage + 1) != FALSE); + else if(nMovePage < nInsertBeforePage) + ATLVERIFY(m_tab.DeleteItem(nMovePage) != FALSE); + + SetActivePage(nInsertBeforePage); + T* pT = static_cast(this); + pT->OnPageActivated(m_nActivePage); + + return true; + } + +// Implementation overrideables + bool CreateTabControl() + { +#ifndef _WIN32_WCE + m_tab.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_TOOLTIPS, 0, m_nTabID); +#else // CE specific + m_tab.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, m_nTabID); +#endif // _WIN32_WCE + ATLASSERT(m_tab.m_hWnd != NULL); + if(m_tab.m_hWnd == NULL) + return false; + + m_tab.SetFont(AtlCreateControlFont()); + m_bInternalFont = true; + + m_tab.SetItemExtra(sizeof(TABVIEWPAGE)); + + T* pT = static_cast(this); + m_cyTabHeight = pT->CalcTabHeight(); + + return true; + } + + int CalcTabHeight() + { + int nCount = m_tab.GetItemCount(); + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_TEXT; + tcix.tciheader.pszText = _T("NS"); + int nIndex = m_tab.InsertItem(nCount, tcix); + + RECT rect = { 0, 0, 1000, 1000 }; + m_tab.AdjustRect(FALSE, &rect); + + RECT rcWnd = { 0, 0, 1000, rect.top }; + ::AdjustWindowRectEx(&rcWnd, m_tab.GetStyle(), FALSE, m_tab.GetExStyle()); + + int nHeight = rcWnd.bottom - rcWnd.top; + + m_tab.DeleteItem(nIndex); + + return nHeight; + } + + void ShowTabControl(bool bShow) + { + m_tab.ShowWindow(bShow ? SW_SHOWNOACTIVATE : SW_HIDE); + } + + void UpdateLayout() + { + RECT rect; + GetClientRect(&rect); + + if(m_tab.IsWindow() && ((m_tab.GetStyle() & WS_VISIBLE) != 0)) + m_tab.SetWindowPos(NULL, 0, 0, rect.right - rect.left, m_cyTabHeight, SWP_NOZORDER); + + if(m_nActivePage != -1) + ::SetWindowPos(GetPageHWND(m_nActivePage), NULL, 0, m_cyTabHeight, rect.right - rect.left, rect.bottom - rect.top - m_cyTabHeight, SWP_NOZORDER); + } + + void UpdateMenu() + { + if(m_menu.m_hMenu != NULL) + BuildWindowMenu(m_menu, m_nMenuItemsCount, m_bEmptyMenuItem, m_bWindowsMenuItem, m_bActivePageMenuItem, m_bActiveAsDefaultMenuItem); + } + + void UpdateTitleBar() + { + if(!m_wndTitleBar.IsWindow() || m_lpstrTitleBarBase == NULL) + return; // nothing to do + + if(m_nActivePage != -1) + { + T* pT = static_cast(this); + LPCTSTR lpstrTitle = pT->GetPageTitle(m_nActivePage); + LPCTSTR lpstrDivider = pT->GetTitleDividerText(); + int cchBuffer = m_cchTitleBarLength + lstrlen(lpstrDivider) + lstrlen(m_lpstrTitleBarBase) + 1; + CTempBuffer buff; + LPTSTR lpstrPageTitle = buff.Allocate(cchBuffer); + ATLASSERT(lpstrPageTitle != NULL); + if(lpstrPageTitle != NULL) + { + pT->ShortenTitle(lpstrTitle, lpstrPageTitle, m_cchTitleBarLength + 1); + SecureHelper::strcat_x(lpstrPageTitle, cchBuffer, lpstrDivider); + SecureHelper::strcat_x(lpstrPageTitle, cchBuffer, m_lpstrTitleBarBase); + } + else + { + lpstrPageTitle = m_lpstrTitleBarBase; + } + + m_wndTitleBar.SetWindowText(lpstrPageTitle); + } + else + { + m_wndTitleBar.SetWindowText(m_lpstrTitleBarBase); + } + } + + void DrawMoveMark(int nItem) + { + T* pT = static_cast(this); + + if(m_nInsertItem != -1) + { + RECT rect = { 0 }; + pT->GetMoveMarkRect(rect); + m_tab.InvalidateRect(&rect); + } + + m_nInsertItem = nItem; + + if(m_nInsertItem != -1) + { + CClientDC dc(m_tab.m_hWnd); + + RECT rect = { 0 }; + pT->GetMoveMarkRect(rect); + + CPen pen; + pen.CreatePen(PS_SOLID, 1, ::GetSysColor(COLOR_WINDOWTEXT)); + CBrush brush; + brush.CreateSolidBrush(::GetSysColor(COLOR_WINDOWTEXT)); + + HPEN hPenOld = dc.SelectPen(pen); + HBRUSH hBrushOld = dc.SelectBrush(brush); + + int x = rect.left; + int y = rect.top; + POINT ptsTop[3] = { { x, y }, { x + m_cxMoveMark, y }, { x + (m_cxMoveMark / 2), y + m_cyMoveMark } }; + dc.Polygon(ptsTop, 3); + + y = rect.bottom - 1; + POINT ptsBottom[3] = { { x, y }, { x + m_cxMoveMark, y }, { x + (m_cxMoveMark / 2), y - m_cyMoveMark } }; + dc.Polygon(ptsBottom, 3); + + dc.SelectPen(hPenOld); + dc.SelectBrush(hBrushOld); + } + } + + void GetMoveMarkRect(RECT& rect) const + { + m_tab.GetClientRect(&rect); + + RECT rcItem = { 0 }; + m_tab.GetItemRect(m_nInsertItem, &rcItem); + + if(m_nInsertItem <= m_nActivePage) + { + rect.left = rcItem.left - m_cxMoveMark / 2 - 1; + rect.right = rcItem.left + m_cxMoveMark / 2; + } + else + { + rect.left = rcItem.right - m_cxMoveMark / 2 - 1; + rect.right = rcItem.right + m_cxMoveMark / 2; + } + } + + void SetMoveCursor(bool bCanMove) + { + ::SetCursor(::LoadCursor(NULL, bCanMove ? IDC_ARROW : IDC_NO)); + } + + void GenerateDragImage(int nItem) + { + ATLASSERT(IsValidPageIndex(nItem)); + +#ifndef _WIN32_WCE + RECT rcItem = { 0 }; + m_tab.GetItemRect(nItem, &rcItem); + ::InflateRect(&rcItem, 2, 2); // make bigger to cover selected item +#else // CE specific + nItem; // avoid level 4 warning + RECT rcItem = { 0, 0, 40, 20 }; +#endif // _WIN32_WCE + + ATLASSERT(m_ilDrag.m_hImageList == NULL); + m_ilDrag.Create(rcItem.right - rcItem.left, rcItem.bottom - rcItem.top, ILC_COLORDDB | ILC_MASK, 1, 1); + + CClientDC dc(m_hWnd); + CDC dcMem; + dcMem.CreateCompatibleDC(dc); + ATLASSERT(dcMem.m_hDC != NULL); + dcMem.SetViewportOrg(-rcItem.left, -rcItem.top); + + CBitmap bmp; + bmp.CreateCompatibleBitmap(dc, rcItem.right - rcItem.left, rcItem.bottom - rcItem.top); + ATLASSERT(bmp.m_hBitmap != NULL); + + HBITMAP hBmpOld = dcMem.SelectBitmap(bmp); +#ifndef _WIN32_WCE + m_tab.SendMessage(WM_PRINTCLIENT, (WPARAM)dcMem.m_hDC); +#else // CE specific + dcMem.Rectangle(&rcItem); +#endif // _WIN32_WCE + dcMem.SelectBitmap(hBmpOld); + + ATLVERIFY(m_ilDrag.Add(bmp.m_hBitmap, RGB(255, 0, 255)) != -1); + } + + void ShortenTitle(LPCTSTR lpstrTitle, LPTSTR lpstrShortTitle, int cchShortTitle) + { + if(lstrlen(lpstrTitle) >= cchShortTitle) + { + LPCTSTR lpstrEllipsis = _T("..."); + int cchEllipsis = lstrlen(lpstrEllipsis); + SecureHelper::strncpy_x(lpstrShortTitle, cchShortTitle, lpstrTitle, cchShortTitle - cchEllipsis - 1); + SecureHelper::strcat_x(lpstrShortTitle, cchShortTitle, lpstrEllipsis); + } + else + { + SecureHelper::strcpy_x(lpstrShortTitle, cchShortTitle, lpstrTitle); + } + } + +#ifndef _WIN32_WCE + void UpdateTooltipText(LPNMTTDISPINFO pTTDI) + { + ATLASSERT(pTTDI != NULL); + pTTDI->lpszText = (LPTSTR)GetPageTitle((int)pTTDI->hdr.idFrom); + } +#endif // !_WIN32_WCE + +// Text for menu items and title bar - override to provide different strings + static LPCTSTR GetEmptyListText() + { + return _T("(Empty)"); + } + + static LPCTSTR GetWindowsMenuItemText() + { + return _T("&Windows..."); + } + + static LPCTSTR GetTitleDividerText() + { + return _T(" - "); + } + +// Notifications - override to provide different behavior + void OnPageActivated(int nPage) + { + NMHDR nmhdr = { 0 }; + nmhdr.hwndFrom = m_hWnd; + nmhdr.idFrom = nPage; + nmhdr.code = TBVN_PAGEACTIVATED; + ::SendMessage(GetParent(), WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&nmhdr); + } + + void OnContextMenu(int nPage, POINT pt) + { + m_tab.ClientToScreen(&pt); + + TBVCONTEXTMENUINFO cmi = { 0 }; + cmi.hdr.hwndFrom = m_hWnd; + cmi.hdr.idFrom = nPage; + cmi.hdr.code = TBVN_CONTEXTMENU; + cmi.pt = pt; + ::SendMessage(GetParent(), WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&cmi); + } +}; + +class CTabView : public CTabViewImpl +{ +public: + DECLARE_WND_CLASS_EX(_T("WTL_TabView"), 0, COLOR_APPWORKSPACE) +}; + +}; // namespace WTL + +#endif // __ATLCTRLX_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlddx.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlddx.h new file mode 100644 index 0000000000..ecaf0adb01 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlddx.h @@ -0,0 +1,679 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLDDX_H__ +#define __ATLDDX_H__ + +#pragma once + +#ifndef __ATLAPP_H__ + #error atlddx.h requires atlapp.h to be included first +#endif + +#if defined(_ATL_USE_DDX_FLOAT) && defined(_ATL_MIN_CRT) + #error Cannot use floating point DDX with _ATL_MIN_CRT defined +#endif // defined(_ATL_USE_DDX_FLOAT) && defined(_ATL_MIN_CRT) + +#ifdef _ATL_USE_DDX_FLOAT + #include +#endif // _ATL_USE_DDX_FLOAT + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CWinDataExchange + + +namespace WTL +{ + +// Constants +#define DDX_LOAD FALSE +#define DDX_SAVE TRUE + +// DDX map macros +#define BEGIN_DDX_MAP(thisClass) \ + BOOL DoDataExchange(BOOL bSaveAndValidate = FALSE, UINT nCtlID = (UINT)-1) \ + { \ + bSaveAndValidate; \ + nCtlID; + +#define DDX_TEXT(nID, var) \ + if(nCtlID == (UINT)-1 || nCtlID == nID) \ + { \ + if(!DDX_Text(nID, var, sizeof(var), bSaveAndValidate)) \ + return FALSE; \ + } + +#define DDX_TEXT_LEN(nID, var, len) \ + if(nCtlID == (UINT)-1 || nCtlID == nID) \ + { \ + if(!DDX_Text(nID, var, sizeof(var), bSaveAndValidate, TRUE, len)) \ + return FALSE; \ + } + +#define DDX_INT(nID, var) \ + if(nCtlID == (UINT)-1 || nCtlID == nID) \ + { \ + if(!DDX_Int(nID, var, TRUE, bSaveAndValidate)) \ + return FALSE; \ + } + +#define DDX_INT_RANGE(nID, var, min, max) \ + if(nCtlID == (UINT)-1 || nCtlID == nID) \ + { \ + if(!DDX_Int(nID, var, TRUE, bSaveAndValidate, TRUE, min, max)) \ + return FALSE; \ + } + +#define DDX_UINT(nID, var) \ + if(nCtlID == (UINT)-1 || nCtlID == nID) \ + { \ + if(!DDX_Int(nID, var, FALSE, bSaveAndValidate)) \ + return FALSE; \ + } + +#define DDX_UINT_RANGE(nID, var, min, max) \ + if(nCtlID == (UINT)-1 || nCtlID == nID) \ + { \ + if(!DDX_Int(nID, var, FALSE, bSaveAndValidate, TRUE, min, max)) \ + return FALSE; \ + } + +#ifdef _ATL_USE_DDX_FLOAT +#define DDX_FLOAT(nID, var) \ + if(nCtlID == (UINT)-1 || nCtlID == nID) \ + { \ + if(!DDX_Float(nID, var, bSaveAndValidate)) \ + return FALSE; \ + } + +#define DDX_FLOAT_RANGE(nID, var, min, max) \ + if(nCtlID == (UINT)-1 || nCtlID == nID) \ + { \ + if(!DDX_Float(nID, var, bSaveAndValidate, TRUE, min, max)) \ + return FALSE; \ + } +#define DDX_FLOAT_P(nID, var, precision) \ + if(nCtlID == (UINT)-1 || nCtlID == nID) \ + { \ + if(!DDX_Float(nID, var, bSaveAndValidate, FALSE, 0, 0, precision)) \ + return FALSE; \ + } + +#define DDX_FLOAT_P_RANGE(nID, var, min, max, precision) \ + if(nCtlID == (UINT)-1 || nCtlID == nID) \ + { \ + if(!DDX_Float(nID, var, bSaveAndValidate, TRUE, min, max, precision)) \ + return FALSE; \ + } +#endif // _ATL_USE_DDX_FLOAT + +#define DDX_CONTROL(nID, obj) \ + if(nCtlID == (UINT)-1 || nCtlID == nID) \ + DDX_Control(nID, obj, bSaveAndValidate); + +#define DDX_CONTROL_HANDLE(nID, obj) \ + if(nCtlID == (UINT)-1 || nCtlID == nID) \ + DDX_Control_Handle(nID, obj, bSaveAndValidate); + +#define DDX_CHECK(nID, var) \ + if(nCtlID == (UINT)-1 || nCtlID == nID) \ + DDX_Check(nID, var, bSaveAndValidate); + +#define DDX_RADIO(nID, var) \ + if(nCtlID == (UINT)-1 || nCtlID == nID) \ + DDX_Radio(nID, var, bSaveAndValidate); + +#define END_DDX_MAP() \ + return TRUE; \ + } + +// DDX support for Tab, Combo, ListBox and ListView selection index +// Note: Specialized versions require atlctrls.h to be included first +#define DDX_INDEX(CtrlClass, nID, var) \ + if(nCtlID == (UINT)-1 || nCtlID == nID) \ + DDX_Index(nID, var, bSaveAndValidate); + +#ifdef __ATLCTRLS_H__ + #define DDX_TAB_INDEX(nID, var) DDX_INDEX(WTL::CTabCtrl, nID, var) + #define DDX_COMBO_INDEX(nID, var) DDX_INDEX(WTL::CComboBox, nID, var) + #define DDX_LISTBOX_INDEX(nID, var) DDX_INDEX(WTL::CListBox, nID, var) + #define DDX_LISTVIEW_INDEX(nID, var) DDX_INDEX(WTL::CListViewCtrl, nID, var) +#endif // __ATLCTRLS_H__ + + +/////////////////////////////////////////////////////////////////////////////// +// CWinDataExchange - provides support for DDX + +template +class CWinDataExchange +{ +public: +// Data exchange method - override in your derived class + BOOL DoDataExchange(BOOL /*bSaveAndValidate*/ = FALSE, UINT /*nCtlID*/ = (UINT)-1) + { + // this one should never be called, override it in + // your derived class by implementing DDX map + ATLASSERT(FALSE); + return FALSE; + } + +// Helpers for validation error reporting + enum _XDataType + { + ddxDataNull = 0, + ddxDataText = 1, + ddxDataInt = 2, + ddxDataFloat = 3, + ddxDataDouble = 4 + }; + + struct _XTextData + { + int nLength; + int nMaxLength; + }; + + struct _XIntData + { + long nVal; + long nMin; + long nMax; + }; + + struct _XFloatData + { + double nVal; + double nMin; + double nMax; + }; + + struct _XData + { + _XDataType nDataType; + union + { + _XTextData textData; + _XIntData intData; + _XFloatData floatData; + }; + }; + +// Text exchange + BOOL DDX_Text(UINT nID, LPTSTR lpstrText, int cbSize, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0) + { + T* pT = static_cast(this); + BOOL bSuccess = TRUE; + + if(bSave) + { + HWND hWndCtrl = pT->GetDlgItem(nID); + int nRetLen = ::GetWindowText(hWndCtrl, lpstrText, cbSize / sizeof(TCHAR)); + if(nRetLen < ::GetWindowTextLength(hWndCtrl)) + bSuccess = FALSE; + } + else + { + ATLASSERT(!bValidate || lstrlen(lpstrText) <= nLength); + bSuccess = pT->SetDlgItemText(nID, lpstrText); + } + + if(!bSuccess) + { + pT->OnDataExchangeError(nID, bSave); + } + else if(bSave && bValidate) // validation + { + ATLASSERT(nLength > 0); + if(lstrlen(lpstrText) > nLength) + { + _XData data = { ddxDataText }; + data.textData.nLength = lstrlen(lpstrText); + data.textData.nMaxLength = nLength; + pT->OnDataValidateError(nID, bSave, data); + bSuccess = FALSE; + } + } + return bSuccess; + } + + BOOL DDX_Text(UINT nID, BSTR& bstrText, int /*cbSize*/, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0) + { + T* pT = static_cast(this); + BOOL bSuccess = TRUE; + + if(bSave) + { + bSuccess = pT->GetDlgItemText(nID, bstrText); + } + else + { + USES_CONVERSION; + LPTSTR lpstrText = OLE2T(bstrText); + ATLASSERT(!bValidate || lstrlen(lpstrText) <= nLength); + bSuccess = pT->SetDlgItemText(nID, lpstrText); + } + + if(!bSuccess) + { + pT->OnDataExchangeError(nID, bSave); + } + else if(bSave && bValidate) // validation + { + ATLASSERT(nLength > 0); + if((int)::SysStringLen(bstrText) > nLength) + { + _XData data = { ddxDataText }; + data.textData.nLength = (int)::SysStringLen(bstrText); + data.textData.nMaxLength = nLength; + pT->OnDataValidateError(nID, bSave, data); + bSuccess = FALSE; + } + } + return bSuccess; + } + + BOOL DDX_Text(UINT nID, ATL::CComBSTR& bstrText, int /*cbSize*/, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0) + { + T* pT = static_cast(this); + BOOL bSuccess = TRUE; + + if(bSave) + { + bSuccess = pT->GetDlgItemText(nID, (BSTR&)bstrText); + } + else + { + USES_CONVERSION; + LPTSTR lpstrText = OLE2T(bstrText); + ATLASSERT(!bValidate || lstrlen(lpstrText) <= nLength); + bSuccess = pT->SetDlgItemText(nID, lpstrText); + } + + if(!bSuccess) + { + pT->OnDataExchangeError(nID, bSave); + } + else if(bSave && bValidate) // validation + { + ATLASSERT(nLength > 0); + if((int)bstrText.Length() > nLength) + { + _XData data = { ddxDataText }; + data.textData.nLength = (int)bstrText.Length(); + data.textData.nMaxLength = nLength; + pT->OnDataValidateError(nID, bSave, data); + bSuccess = FALSE; + } + } + return bSuccess; + } + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + BOOL DDX_Text(UINT nID, _CSTRING_NS::CString& strText, int /*cbSize*/, BOOL bSave, BOOL bValidate = FALSE, int nLength = 0) + { + T* pT = static_cast(this); + BOOL bSuccess = TRUE; + + if(bSave) + { + HWND hWndCtrl = pT->GetDlgItem(nID); + int nLen = ::GetWindowTextLength(hWndCtrl); + int nRetLen = -1; + LPTSTR lpstr = strText.GetBufferSetLength(nLen); + if(lpstr != NULL) + { + nRetLen = ::GetWindowText(hWndCtrl, lpstr, nLen + 1); + strText.ReleaseBuffer(); + } + if(nRetLen < nLen) + bSuccess = FALSE; + } + else + { + bSuccess = pT->SetDlgItemText(nID, strText); + } + + if(!bSuccess) + { + pT->OnDataExchangeError(nID, bSave); + } + else if(bSave && bValidate) // validation + { + ATLASSERT(nLength > 0); + if(strText.GetLength() > nLength) + { + _XData data = { ddxDataText }; + data.textData.nLength = strText.GetLength(); + data.textData.nMaxLength = nLength; + pT->OnDataValidateError(nID, bSave, data); + bSuccess = FALSE; + } + } + return bSuccess; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + +// Numeric exchange + template + BOOL DDX_Int(UINT nID, Type& nVal, BOOL bSigned, BOOL bSave, BOOL bValidate = FALSE, Type nMin = 0, Type nMax = 0) + { + T* pT = static_cast(this); + BOOL bSuccess = TRUE; + + if(bSave) + { + nVal = (Type)pT->GetDlgItemInt(nID, &bSuccess, bSigned); + } + else + { + ATLASSERT(!bValidate || nVal >= nMin && nVal <= nMax); + bSuccess = pT->SetDlgItemInt(nID, nVal, bSigned); + } + + if(!bSuccess) + { + pT->OnDataExchangeError(nID, bSave); + } + else if(bSave && bValidate) // validation + { + ATLASSERT(nMin != nMax); + if(nVal < nMin || nVal > nMax) + { + _XData data = { ddxDataInt }; + data.intData.nVal = (long)nVal; + data.intData.nMin = (long)nMin; + data.intData.nMax = (long)nMax; + pT->OnDataValidateError(nID, bSave, data); + bSuccess = FALSE; + } + } + return bSuccess; + } + +// Float exchange +#ifdef _ATL_USE_DDX_FLOAT + static BOOL _AtlSimpleFloatParse(LPCTSTR lpszText, double& d) + { + ATLASSERT(lpszText != NULL); + while (*lpszText == _T(' ') || *lpszText == _T('\t')) + lpszText++; + + TCHAR chFirst = lpszText[0]; + d = _tcstod(lpszText, (LPTSTR*)&lpszText); + if (d == 0.0 && chFirst != _T('0')) + return FALSE; // could not convert + while (*lpszText == _T(' ') || *lpszText == _T('\t')) + lpszText++; + + if (*lpszText != _T('\0')) + return FALSE; // not terminated properly + + return TRUE; + } + + BOOL DDX_Float(UINT nID, float& nVal, BOOL bSave, BOOL bValidate = FALSE, float nMin = 0.F, float nMax = 0.F, int nPrecision = FLT_DIG) + { + T* pT = static_cast(this); + BOOL bSuccess = TRUE; + const int cchBuff = 32; + TCHAR szBuff[cchBuff] = { 0 }; + + if(bSave) + { + pT->GetDlgItemText(nID, szBuff, cchBuff); + double d = 0; + if(_AtlSimpleFloatParse(szBuff, d)) + nVal = (float)d; + else + bSuccess = FALSE; + } + else + { + ATLASSERT(!bValidate || nVal >= nMin && nVal <= nMax); + SecureHelper::sprintf_x(szBuff, cchBuff, _T("%.*g"), nPrecision, nVal); + bSuccess = pT->SetDlgItemText(nID, szBuff); + } + + if(!bSuccess) + { + pT->OnDataExchangeError(nID, bSave); + } + else if(bSave && bValidate) // validation + { + ATLASSERT(nMin != nMax); + if(nVal < nMin || nVal > nMax) + { + _XData data = { ddxDataFloat }; + data.floatData.nVal = (double)nVal; + data.floatData.nMin = (double)nMin; + data.floatData.nMax = (double)nMax; + pT->OnDataValidateError(nID, bSave, data); + bSuccess = FALSE; + } + } + return bSuccess; + } + + BOOL DDX_Float(UINT nID, double& nVal, BOOL bSave, BOOL bValidate = FALSE, double nMin = 0., double nMax = 0., int nPrecision = DBL_DIG) + { + T* pT = static_cast(this); + BOOL bSuccess = TRUE; + const int cchBuff = 32; + TCHAR szBuff[cchBuff] = { 0 }; + + if(bSave) + { + pT->GetDlgItemText(nID, szBuff, cchBuff); + double d = 0; + if(_AtlSimpleFloatParse(szBuff, d)) + nVal = d; + else + bSuccess = FALSE; + } + else + { + ATLASSERT(!bValidate || nVal >= nMin && nVal <= nMax); + SecureHelper::sprintf_x(szBuff, cchBuff, _T("%.*g"), nPrecision, nVal); + bSuccess = pT->SetDlgItemText(nID, szBuff); + } + + if(!bSuccess) + { + pT->OnDataExchangeError(nID, bSave); + } + else if(bSave && bValidate) // validation + { + ATLASSERT(nMin != nMax); + if(nVal < nMin || nVal > nMax) + { + _XData data = { ddxDataFloat }; + data.floatData.nVal = nVal; + data.floatData.nMin = nMin; + data.floatData.nMax = nMax; + pT->OnDataValidateError(nID, bSave, data); + bSuccess = FALSE; + } + } + return bSuccess; + } +#endif // _ATL_USE_DDX_FLOAT + +// Full control subclassing (for CWindowImpl derived controls) + template + void DDX_Control(UINT nID, TControl& ctrl, BOOL bSave) + { + if(!bSave && ctrl.m_hWnd == NULL) + { + T* pT = static_cast(this); + ctrl.SubclassWindow(pT->GetDlgItem(nID)); + } + } + +// Simple control attaching (for HWND wrapper controls) + template + void DDX_Control_Handle(UINT nID, TControl& ctrl, BOOL bSave) + { + if(!bSave && ctrl.m_hWnd == NULL) + { + T* pT = static_cast(this); + ctrl = pT->GetDlgItem(nID); + } + } + +// Control state + void DDX_Check(UINT nID, int& nValue, BOOL bSave) + { + T* pT = static_cast(this); + HWND hWndCtrl = pT->GetDlgItem(nID); + if(bSave) + { + nValue = (int)::SendMessage(hWndCtrl, BM_GETCHECK, 0, 0L); + ATLASSERT(nValue >= 0 && nValue <= 2); + } + else + { + if(nValue < 0 || nValue > 2) + { + ATLTRACE2(atlTraceUI, 0, _T("ATL: Warning - dialog data checkbox value (%d) out of range.\n"), nValue); + nValue = 0; // default to off + } + ::SendMessage(hWndCtrl, BM_SETCHECK, nValue, 0L); + } + } + + // variant that supports bool (checked/not-checked, no intermediate state) + void DDX_Check(UINT nID, bool& bCheck, BOOL bSave) + { + int nValue = bCheck ? 1 : 0; + DDX_Check(nID, nValue, bSave); + + if(bSave) + { + if(nValue == 2) + ATLTRACE2(atlTraceUI, 0, _T("ATL: Warning - checkbox state (%d) out of supported range.\n"), nValue); + bCheck = (nValue == 1); + } + } + + void DDX_Radio(UINT nID, int& nValue, BOOL bSave) + { + T* pT = static_cast(this); + HWND hWndCtrl = pT->GetDlgItem(nID); + ATLASSERT(hWndCtrl != NULL); + + // must be first in a group of auto radio buttons + ATLASSERT(::GetWindowLong(hWndCtrl, GWL_STYLE) & WS_GROUP); + ATLASSERT(::SendMessage(hWndCtrl, WM_GETDLGCODE, 0, 0L) & DLGC_RADIOBUTTON); + + if(bSave) + nValue = -1; // value if none found + + // walk all children in group + int nButton = 0; + do + { + if(::SendMessage(hWndCtrl, WM_GETDLGCODE, 0, 0L) & DLGC_RADIOBUTTON) + { + // control in group is a radio button + if(bSave) + { + if(::SendMessage(hWndCtrl, BM_GETCHECK, 0, 0L) != 0) + { + ATLASSERT(nValue == -1); // only set once + nValue = nButton; + } + } + else + { + // select button + ::SendMessage(hWndCtrl, BM_SETCHECK, (nButton == nValue), 0L); + } + nButton++; + } + else + { + ATLTRACE2(atlTraceUI, 0, _T("ATL: Warning - skipping non-radio button in group.\n")); + } + hWndCtrl = ::GetWindow(hWndCtrl, GW_HWNDNEXT); + } + while (hWndCtrl != NULL && !(GetWindowLong(hWndCtrl, GWL_STYLE) & WS_GROUP)); + } + +// DDX support for Tab, Combo, ListBox and ListView selection index + template + INT _getSel(TCtrl& tCtrl) + { + return tCtrl.GetCurSel(); + } + + template + void _setSel(TCtrl& tCtrl, INT iSel) + { + if(iSel < 0) + tCtrl.SetCurSel(-1); + else + tCtrl.SetCurSel(iSel); + } + +#ifdef __ATLCTRLS_H__ + // ListViewCtrl specialization + template <> + INT _getSel(WTL::CListViewCtrl& tCtrl) + { + return tCtrl.GetSelectedIndex(); + } + + template <> + void _setSel(WTL::CListViewCtrl& tCtrl, INT iSel) + { + if(iSel < 0) + tCtrl.SelectItem(-1); + else + tCtrl.SelectItem(iSel); + } +#endif // __ATLCTRLS_H__ + + template + void DDX_Index(UINT nID, INT& nVal, BOOL bSave) + { + T* pT = static_cast(this); + TCtrl ctrl(pT->GetDlgItem(nID)); + + if(bSave) + nVal = _getSel(ctrl); + else + _setSel(ctrl, nVal); + } + +// Overrideables + void OnDataExchangeError(UINT nCtrlID, BOOL /*bSave*/) + { + // Override to display an error message + ::MessageBeep((UINT)-1); + T* pT = static_cast(this); + ::SetFocus(pT->GetDlgItem(nCtrlID)); + } + + void OnDataValidateError(UINT nCtrlID, BOOL /*bSave*/, _XData& /*data*/) + { + // Override to display an error message + ::MessageBeep((UINT)-1); + T* pT = static_cast(this); + ::SetFocus(pT->GetDlgItem(nCtrlID)); + } +}; + +}; // namespace WTL + +#endif // __ATLDDX_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atldlgs.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atldlgs.h new file mode 100644 index 0000000000..a55fed4cb5 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atldlgs.h @@ -0,0 +1,6403 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLDLGS_H__ +#define __ATLDLGS_H__ + +#pragma once + +#ifndef __ATLAPP_H__ + #error atldlgs.h requires atlapp.h to be included first +#endif + +#ifndef __ATLWIN_H__ + #error atldlgs.h requires atlwin.h to be included first +#endif + +#include +#include + +#if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) + #include +#endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CFileDialogImpl +// CFileDialog +// CFileDialogEx +// CMultiFileDialogImpl +// CMultiFileDialog +// CShellFileDialogImpl +// CShellFileOpenDialogImpl +// CShellFileOpenDialog +// CShellFileSaveDialogImpl +// CShellFileSaveDialog +// CFolderDialogImpl +// CFolderDialog +// CFontDialogImpl +// CFontDialog +// CRichEditFontDialogImpl +// CRichEditFontDialog +// CColorDialogImpl +// CColorDialog +// CPrintDialogImpl +// CPrintDialog +// CPrintDialogExImpl +// CPrintDialogEx +// CPageSetupDialogImpl +// CPageSetupDialog +// CFindReplaceDialogImpl +// CFindReplaceDialog +// +// CDialogBaseUnits +// CMemDlgTemplate +// CIndirectDialogImpl +// +// CPropertySheetWindow +// CPropertySheetImpl +// CPropertySheet +// CPropertyPageWindow +// CPropertyPageImpl +// CPropertyPage +// CAxPropertyPageImpl +// CAxPropertyPage +// +// CWizard97SheetWindow +// CWizard97SheetImpl +// CWizard97Sheet +// CWizard97PageWindow +// CWizard97PageImpl +// CWizard97ExteriorPageImpl +// CWizard97InteriorPageImpl +// +// CAeroWizardFrameWindow +// CAeroWizardFrameImpl +// CAeroWizardFrame +// CAeroWizardPageWindow +// CAeroWizardPageImpl +// CAeroWizardPage +// CAeroWizardAxPageImpl +// CAeroWizardAxPage +// +// CTaskDialogConfig +// CTaskDialogImpl +// CTaskDialog +// +// Global functions: +// AtlTaskDialog() + + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// CFileDialogImpl - used for File Open or File Save As + +// compatibility with the old (vc6.0) headers +#if (_WIN32_WINNT >= 0x0500) && !defined(OPENFILENAME_SIZE_VERSION_400) + #ifndef CDSIZEOF_STRUCT + #define CDSIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member)) + #endif + #define OPENFILENAME_SIZE_VERSION_400A CDSIZEOF_STRUCT(OPENFILENAMEA,lpTemplateName) + #define OPENFILENAME_SIZE_VERSION_400W CDSIZEOF_STRUCT(OPENFILENAMEW,lpTemplateName) + #ifdef UNICODE + #define OPENFILENAME_SIZE_VERSION_400 OPENFILENAME_SIZE_VERSION_400W + #else + #define OPENFILENAME_SIZE_VERSION_400 OPENFILENAME_SIZE_VERSION_400A + #endif // !UNICODE +#endif // (_WIN32_WINNT >= 0x0500) && !defined(OPENFILENAME_SIZE_VERSION_400) + +#if !defined(_WIN32_WCE) && !defined(CDN_INCLUDEITEM) + #define CDN_INCLUDEITEM (CDN_FIRST - 0x0007) +#endif + +template +class ATL_NO_VTABLE CFileDialogImpl : public ATL::CDialogImplBase +{ +public: +#if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501) + OPENFILENAMEEX m_ofn; +#else + OPENFILENAME m_ofn; +#endif + BOOL m_bOpenFileDialog; // TRUE for file open, FALSE for file save + TCHAR m_szFileTitle[_MAX_FNAME]; // contains file title after return + TCHAR m_szFileName[_MAX_PATH]; // contains full path name after return + + CFileDialogImpl(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs + LPCTSTR lpszDefExt = NULL, + LPCTSTR lpszFileName = NULL, + DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, + LPCTSTR lpszFilter = NULL, + HWND hWndParent = NULL) + { + memset(&m_ofn, 0, sizeof(m_ofn)); // initialize structure to 0/NULL + m_szFileName[0] = _T('\0'); + m_szFileTitle[0] = _T('\0'); + + m_bOpenFileDialog = bOpenFileDialog; + +#if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501) + m_ofn.lStructSize = bOpenFileDialog ? sizeof(m_ofn) : sizeof(OPENFILENAME); +#else + m_ofn.lStructSize = sizeof(m_ofn); +#endif + +#if (_WIN32_WINNT >= 0x0500) + // adjust struct size if running on older version of Windows + if(AtlIsOldWindows()) + { + ATLASSERT(sizeof(m_ofn) > OPENFILENAME_SIZE_VERSION_400); // must be + m_ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; + } +#endif // (_WIN32_WINNT >= 0x0500) + m_ofn.lpstrFile = m_szFileName; + m_ofn.nMaxFile = _MAX_PATH; + m_ofn.lpstrDefExt = lpszDefExt; + m_ofn.lpstrFileTitle = (LPTSTR)m_szFileTitle; + m_ofn.nMaxFileTitle = _MAX_FNAME; +#ifndef _WIN32_WCE + m_ofn.Flags = dwFlags | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLESIZING; +#else // CE specific + m_ofn.Flags = dwFlags | OFN_EXPLORER | OFN_ENABLEHOOK; +#endif // !_WIN32_WCE + m_ofn.lpstrFilter = lpszFilter; + m_ofn.hInstance = ModuleHelper::GetResourceInstance(); + m_ofn.lpfnHook = (LPOFNHOOKPROC)T::StartDialogProc; + m_ofn.hwndOwner = hWndParent; + + // setup initial file name + if(lpszFileName != NULL) + SecureHelper::strncpy_x(m_szFileName, _countof(m_szFileName), lpszFileName, _TRUNCATE); + } + + INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) + { + ATLASSERT((m_ofn.Flags & OFN_ENABLEHOOK) != 0); + ATLASSERT(m_ofn.lpfnHook != NULL); // can still be a user hook + + ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); + + if(m_ofn.hwndOwner == NULL) // set only if not specified before + m_ofn.hwndOwner = hWndParent; + + ATLASSERT(m_hWnd == NULL); + ModuleHelper::AddCreateWndData(&m_thunk.cd, (ATL::CDialogImplBase*)this); + + BOOL bRet; + if(m_bOpenFileDialog) +#if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501) + bRet = ::GetOpenFileNameEx(&m_ofn); + else + bRet = ::GetSaveFileName((LPOPENFILENAME)&m_ofn); +#else + bRet = ::GetOpenFileName(&m_ofn); + else + bRet = ::GetSaveFileName(&m_ofn); +#endif + + m_hWnd = NULL; + + return bRet ? IDOK : IDCANCEL; + } + +// Attributes + ATL::CWindow GetFileDialogWindow() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return ATL::CWindow(GetParent()); + } + + int GetFilePath(LPTSTR lpstrFilePath, int nLength) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); + + return (int)GetFileDialogWindow().SendMessage(CDM_GETFILEPATH, nLength, (LPARAM)lpstrFilePath); + } + + int GetFolderIDList(LPVOID lpBuff, int nLength) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); + + return (int)GetFileDialogWindow().SendMessage(CDM_GETFOLDERIDLIST, nLength, (LPARAM)lpBuff); + } + + int GetFolderPath(LPTSTR lpstrFolderPath, int nLength) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); + + return (int)GetFileDialogWindow().SendMessage(CDM_GETFOLDERPATH, nLength, (LPARAM)lpstrFolderPath); + } + + int GetSpec(LPTSTR lpstrSpec, int nLength) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); + + return (int)GetFileDialogWindow().SendMessage(CDM_GETSPEC, nLength, (LPARAM)lpstrSpec); + } + + void SetControlText(int nCtrlID, LPCTSTR lpstrText) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); + + GetFileDialogWindow().SendMessage(CDM_SETCONTROLTEXT, nCtrlID, (LPARAM)lpstrText); + } + + void SetDefExt(LPCTSTR lpstrExt) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); + + GetFileDialogWindow().SendMessage(CDM_SETDEFEXT, 0, (LPARAM)lpstrExt); + } + + BOOL GetReadOnlyPref() const // return TRUE if readonly checked + { + return ((m_ofn.Flags & OFN_READONLY) != 0) ? TRUE : FALSE; + } + +// Operations + void HideControl(int nCtrlID) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); + + GetFileDialogWindow().SendMessage(CDM_HIDECONTROL, nCtrlID); + } + +// Special override for common dialogs + BOOL EndDialog(INT_PTR /*nRetCode*/ = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + GetFileDialogWindow().SendMessage(WM_COMMAND, MAKEWPARAM(IDCANCEL, 0)); + return TRUE; + } + +// Message map and handlers + BEGIN_MSG_MAP(CFileDialogImpl) + NOTIFY_CODE_HANDLER(CDN_FILEOK, _OnFileOK) + NOTIFY_CODE_HANDLER(CDN_FOLDERCHANGE, _OnFolderChange) + NOTIFY_CODE_HANDLER(CDN_HELP, _OnHelp) + NOTIFY_CODE_HANDLER(CDN_INITDONE, _OnInitDone) + NOTIFY_CODE_HANDLER(CDN_SELCHANGE, _OnSelChange) + NOTIFY_CODE_HANDLER(CDN_SHAREVIOLATION, _OnShareViolation) + NOTIFY_CODE_HANDLER(CDN_TYPECHANGE, _OnTypeChange) +#ifndef _WIN32_WCE + NOTIFY_CODE_HANDLER(CDN_INCLUDEITEM, _OnIncludeItem) +#endif // !_WIN32_WCE + END_MSG_MAP() + + LRESULT _OnFileOK(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) + { + ATLASSERT(::IsWindow(m_hWnd)); + T* pT = static_cast(this); + return !pT->OnFileOK((LPOFNOTIFY)pnmh); + } + + LRESULT _OnFolderChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) + { + ATLASSERT(::IsWindow(m_hWnd)); + T* pT = static_cast(this); + pT->OnFolderChange((LPOFNOTIFY)pnmh); + return 0; + } + + LRESULT _OnHelp(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) + { + ATLASSERT(::IsWindow(m_hWnd)); + T* pT = static_cast(this); + pT->OnHelp((LPOFNOTIFY)pnmh); + return 0; + } + + LRESULT _OnInitDone(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) + { + ATLASSERT(::IsWindow(m_hWnd)); + T* pT = static_cast(this); + pT->OnInitDone((LPOFNOTIFY)pnmh); + return 0; + } + + LRESULT _OnSelChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) + { + ATLASSERT(::IsWindow(m_hWnd)); + T* pT = static_cast(this); + pT->OnSelChange((LPOFNOTIFY)pnmh); + return 0; + } + + LRESULT _OnShareViolation(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) + { + ATLASSERT(::IsWindow(m_hWnd)); + T* pT = static_cast(this); + return pT->OnShareViolation((LPOFNOTIFY)pnmh); + } + + LRESULT _OnTypeChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) + { + ATLASSERT(::IsWindow(m_hWnd)); + T* pT = static_cast(this); + pT->OnTypeChange((LPOFNOTIFY)pnmh); + return 0; + } + +#ifndef _WIN32_WCE + LRESULT _OnIncludeItem(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) + { + ATLASSERT(::IsWindow(m_hWnd)); + T* pT = static_cast(this); + return pT->OnIncludeItem((LPOFNOTIFYEX)pnmh); + } +#endif // !_WIN32_WCE + +// Overrideables + BOOL OnFileOK(LPOFNOTIFY /*lpon*/) + { + return TRUE; + } + + void OnFolderChange(LPOFNOTIFY /*lpon*/) + { + } + + void OnHelp(LPOFNOTIFY /*lpon*/) + { + } + + void OnInitDone(LPOFNOTIFY /*lpon*/) + { + } + + void OnSelChange(LPOFNOTIFY /*lpon*/) + { + } + + int OnShareViolation(LPOFNOTIFY /*lpon*/) + { + return 0; + } + + void OnTypeChange(LPOFNOTIFY /*lpon*/) + { + } + +#ifndef _WIN32_WCE + BOOL OnIncludeItem(LPOFNOTIFYEX /*lponex*/) + { + return TRUE; // include item + } +#endif // !_WIN32_WCE +}; + +class CFileDialog : public CFileDialogImpl +{ +public: + CFileDialog(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs + LPCTSTR lpszDefExt = NULL, + LPCTSTR lpszFileName = NULL, + DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, + LPCTSTR lpszFilter = NULL, + HWND hWndParent = NULL) + : CFileDialogImpl(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, hWndParent) + { } + + // override base class map and references to handlers + DECLARE_EMPTY_MSG_MAP() +}; + +#if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501) +class CFileDialogEx : public CFileDialogImpl +{ +public: + CFileDialogEx( // Supports only FileOpen + LPCTSTR lpszDefExt = NULL, + LPCTSTR lpszFileName = NULL, + DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, + OFN_EXFLAG ExFlags = OFN_EXFLAG_THUMBNAILVIEW, + OFN_SORTORDER dwSortOrder = OFN_SORTORDER_AUTO, + LPCTSTR lpszFilter = NULL, + HWND hWndParent = NULL) + : CFileDialogImpl(TRUE, lpszDefExt, lpszFileName, dwFlags, lpszFilter, hWndParent) + { + m_ofn.ExFlags = ExFlags; + m_ofn.dwSortOrder = dwSortOrder; + } + + // override base class map and references to handlers + DECLARE_EMPTY_MSG_MAP() +}; +#endif // defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501) + + +/////////////////////////////////////////////////////////////////////////////// +// Multi File Dialog - Multi-select File Open dialog + +#ifndef _WIN32_WCE + +// The class dynamically resizes the buffer as the file selection changes +// (as described in Knowledge Base article 131462). It also expands selected +// shortcut files to take into account the full path of the target file. +// Note that this doesn't work on Win9x for the old style dialogs, as well as +// on NT for non-Unicode builds. + +#ifndef _WTL_FIXED_OFN_BUFFER_LENGTH + #define _WTL_FIXED_OFN_BUFFER_LENGTH 0x10000 +#endif + +template +class ATL_NO_VTABLE CMultiFileDialogImpl : public CFileDialogImpl< T > +{ +public: + mutable LPCTSTR m_pNextFile; +#ifndef _UNICODE + bool m_bIsNT; +#endif + + CMultiFileDialogImpl( + LPCTSTR lpszDefExt = NULL, + LPCTSTR lpszFileName = NULL, + DWORD dwFlags = OFN_HIDEREADONLY, + LPCTSTR lpszFilter = NULL, + HWND hWndParent = NULL) + : CFileDialogImpl(TRUE, lpszDefExt, lpszFileName, dwFlags, lpszFilter, hWndParent), + m_pNextFile(NULL) + { + m_ofn.Flags |= OFN_ALLOWMULTISELECT; // Force multiple selection mode + +#ifndef _UNICODE + OSVERSIONINFO ovi = { sizeof(ovi) }; + ::GetVersionEx(&ovi); + m_bIsNT = (ovi.dwPlatformId == VER_PLATFORM_WIN32_NT); + if (m_bIsNT) + { + // On NT platforms, GetOpenFileNameA thunks to GetOpenFileNameW and there + // is absolutely nothing we can do except to start off with a large buffer. + ATLVERIFY(ResizeFilenameBuffer(_WTL_FIXED_OFN_BUFFER_LENGTH)); + } +#endif + } + + ~CMultiFileDialogImpl() + { + if (m_ofn.lpstrFile != m_szFileName) // Free the buffer if we allocated it + delete[] m_ofn.lpstrFile; + } + +// Operations + // Get the directory that the files were chosen from. + // The function returns the number of characters copied, not including the terminating zero. + // If the buffer is NULL, the function returns the required size, in characters, including the terminating zero. + // If the function fails, the return value is zero. + int GetDirectory(LPTSTR pBuffer, int nBufLen) const + { + if (m_ofn.lpstrFile == NULL) + return 0; + + LPCTSTR pStr = m_ofn.lpstrFile; + int nLength = lstrlen(pStr); + if (pStr[nLength + 1] == 0) + { + // The OFN buffer contains a single item so extract its path. + LPCTSTR pSep = _strrchr(pStr, _T('\\')); + if (pSep != NULL) + nLength = (int)(DWORD_PTR)(pSep - pStr); + } + + int nRet = 0; + if (pBuffer == NULL) // If the buffer is NULL, return the required length + { + nRet = nLength + 1; + } + else if (nBufLen > nLength) + { + SecureHelper::strncpy_x(pBuffer, nBufLen, pStr, nLength); + nRet = nLength; + } + + return nRet; + } + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + bool GetDirectory(_CSTRING_NS::CString& strDir) const + { + bool bRet = false; + + int nLength = GetDirectory(NULL, 0); + if (nLength > 0) + { + bRet = (GetDirectory(strDir.GetBuffer(nLength), nLength) > 0); + strDir.ReleaseBuffer(nLength - 1); + } + + return bRet; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + // Get the first filename as a pointer into the buffer. + LPCTSTR GetFirstFileName() const + { + if (m_ofn.lpstrFile == NULL) + return NULL; + + m_pNextFile = NULL; // Reset internal buffer pointer + + LPCTSTR pStr = m_ofn.lpstrFile; + int nLength = lstrlen(pStr); + if (pStr[nLength + 1] != 0) + { + // Multiple items were selected. The first string is the directory, + // so skip forwards to the second string. + pStr += nLength + 1; + + // Set up m_pNext so it points to the second item (or null). + m_pNextFile = pStr; + GetNextFileName(); + } + else + { + // A single item was selected. Skip forward past the path. + LPCTSTR pSep = _strrchr(pStr, _T('\\')); + if (pSep != NULL) + pStr = pSep + 1; + } + + return pStr; + } + + // Get the next filename as a pointer into the buffer. + LPCTSTR GetNextFileName() const + { + if (m_pNextFile == NULL) + return NULL; + + LPCTSTR pStr = m_pNextFile; + // Set "m_pNextFile" to point to the next file name, or null if we + // have reached the last file in the list. + int nLength = lstrlen(pStr); + m_pNextFile = (pStr[nLength + 1] != 0) ? &pStr[nLength + 1] : NULL; + + return pStr; + } + + // Get the first filename as a full path. + // The function returns the number of characters copied, not including the terminating zero. + // If the buffer is NULL, the function returns the required size, in characters, including the terminating zero. + // If the function fails, the return value is zero. + int GetFirstPathName(LPTSTR pBuffer, int nBufLen) const + { + LPCTSTR pStr = GetFirstFileName(); + int nLengthDir = GetDirectory(NULL, 0); + if((pStr == NULL) || (nLengthDir == 0)) + return 0; + + // Figure out the required length. + int nLengthTotal = nLengthDir + lstrlen(pStr); + + int nRet = 0; + if(pBuffer == NULL) // If the buffer is NULL, return the required length + { + nRet = nLengthTotal + 1; + } + else if (nBufLen > nLengthTotal) // If the buffer is big enough, go ahead and construct the path + { + GetDirectory(pBuffer, nBufLen); + SecureHelper::strcat_x(pBuffer, nBufLen, _T("\\")); + SecureHelper::strcat_x(pBuffer, nBufLen, pStr); + nRet = nLengthTotal; + } + + return nRet; + } + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + bool GetFirstPathName(_CSTRING_NS::CString& strPath) const + { + bool bRet = false; + + int nLength = GetFirstPathName(NULL, 0); + if (nLength > 0) + { + bRet = (GetFirstPathName(strPath.GetBuffer(nLength), nLength) > 0); + strPath.ReleaseBuffer(nLength - 1); + } + + return bRet; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + // Get the next filename as a full path. + // The function returns the number of characters copied, not including the terminating zero. + // If the buffer is NULL, the function returns the required size, in characters, including the terminating zero. + // If the function fails, the return value is zero. + // The internal position marker is moved forward only if the function succeeds and the buffer was large enough. + int GetNextPathName(LPTSTR pBuffer, int nBufLen) const + { + if (m_pNextFile == NULL) + return 0; + + int nRet = 0; + LPCTSTR pStr = m_pNextFile; + // Does the filename contain a backslash? + if (_strrchr(pStr, _T('\\')) != NULL) + { + // Yes, so we'll assume it's a full path. + int nLength = lstrlen(pStr); + + if (pBuffer == NULL) // If the buffer is NULL, return the required length + { + nRet = nLength + 1; + } + else if (nBufLen > nLength) // The buffer is big enough, so go ahead and copy the filename + { + SecureHelper::strcpy_x(pBuffer, nBufLen, GetNextFileName()); + nRet = nBufLen; + } + } + else + { + // The filename is relative, so construct the full path. + int nLengthDir = GetDirectory(NULL, 0); + if (nLengthDir > 0) + { + // Calculate the required space. + int nLengthTotal = nLengthDir + lstrlen(pStr); + + if(pBuffer == NULL) // If the buffer is NULL, return the required length + { + nRet = nLengthTotal + 1; + } + else if (nBufLen > nLengthTotal) // If the buffer is big enough, go ahead and construct the path + { + GetDirectory(pBuffer, nBufLen); + SecureHelper::strcat_x(pBuffer, nBufLen, _T("\\")); + SecureHelper::strcat_x(pBuffer, nBufLen, GetNextFileName()); + nRet = nLengthTotal; + } + } + } + + return nRet; + } + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + bool GetNextPathName(_CSTRING_NS::CString& strPath) const + { + bool bRet = false; + + int nLength = GetNextPathName(NULL, 0); + if (nLength > 0) + { + bRet = (GetNextPathName(strPath.GetBuffer(nLength), nLength) > 0); + strPath.ReleaseBuffer(nLength - 1); + } + + return bRet; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + +// Implementation + bool ResizeFilenameBuffer(DWORD dwLength) + { + if (dwLength > m_ofn.nMaxFile) + { + // Free the old buffer. + if (m_ofn.lpstrFile != m_szFileName) + { + delete[] m_ofn.lpstrFile; + m_ofn.lpstrFile = NULL; + m_ofn.nMaxFile = 0; + } + + // Allocate the new buffer. + LPTSTR lpstrBuff = NULL; + ATLTRY(lpstrBuff = new TCHAR[dwLength]); + if (lpstrBuff != NULL) + { + m_ofn.lpstrFile = lpstrBuff; + m_ofn.lpstrFile[0] = 0; + m_ofn.nMaxFile = dwLength; + } + } + + return (m_ofn.lpstrFile != NULL); + } + + void OnSelChange(LPOFNOTIFY /*lpon*/) + { +#ifndef _UNICODE + // There is no point resizing the buffer in ANSI builds running on NT. + if (m_bIsNT) + return; +#endif + + // Get the buffer length required to hold the spec. + int nLength = GetSpec(NULL, 0); + if (nLength <= 1) + return; // no files are selected, presumably + + // Add room for the directory, and an extra terminating zero. + nLength += GetFolderPath(NULL, 0) + 1; + + if (!ResizeFilenameBuffer(nLength)) + { + ATLASSERT(FALSE); + return; + } + + // If we are not following links then our work is done. + if ((m_ofn.Flags & OFN_NODEREFERENCELINKS) != 0) + return; + + // Get the file spec, which is the text in the edit control. + if (GetSpec(m_ofn.lpstrFile, m_ofn.nMaxFile) <= 0) + return; + + // Get the ID-list of the current folder. + int nBytes = GetFolderIDList(NULL, 0); + CTempBuffer idlist; + idlist.AllocateBytes(nBytes); + if ((nBytes <= 0) || (GetFolderIDList(idlist, nBytes) <= 0)) + return; + + // First bind to the desktop folder, then to the current folder. + ATL::CComPtr pDesktop, pFolder; + if (FAILED(::SHGetDesktopFolder(&pDesktop))) + return; + if (FAILED(pDesktop->BindToObject(idlist, NULL, IID_IShellFolder, (void**)&pFolder))) + return; + + // Work through the file spec, looking for quoted filenames. If we find a shortcut file, then + // we need to add enough extra buffer space to hold its target path. + DWORD nExtraChars = 0; + bool bInsideQuotes = false; + LPCTSTR pAnchor = m_ofn.lpstrFile; + LPCTSTR pChar = m_ofn.lpstrFile; + for ( ; *pChar; ++pChar) + { + // Look for quotation marks. + if (*pChar == _T('\"')) + { + // We are either entering or leaving a passage of quoted text. + bInsideQuotes = !bInsideQuotes; + + // Is it an opening or closing quote? + if (bInsideQuotes) + { + // We found an opening quote, so set "pAnchor" to the following character. + pAnchor = pChar + 1; + } + else // closing quote + { + // Each quoted entity should be shorter than MAX_PATH. + if (pChar - pAnchor >= MAX_PATH) + return; + + // Get the ID-list and attributes of the file. + USES_CONVERSION; + int nFileNameLength = (int)(DWORD_PTR)(pChar - pAnchor); + TCHAR szFileName[MAX_PATH]; + SecureHelper::strncpy_x(szFileName, MAX_PATH, pAnchor, nFileNameLength); + LPITEMIDLIST pidl = NULL; + DWORD dwAttrib = SFGAO_LINK; + if (SUCCEEDED(pFolder->ParseDisplayName(NULL, NULL, T2W(szFileName), NULL, &pidl, &dwAttrib))) + { + // Is it a shortcut file? + if (dwAttrib & SFGAO_LINK) + { + // Bind to its IShellLink interface. + ATL::CComPtr pLink; + if (SUCCEEDED(pFolder->BindToObject(pidl, NULL, IID_IShellLink, (void**)&pLink))) + { + // Get the shortcut's target path. + TCHAR szPath[MAX_PATH]; + if (SUCCEEDED(pLink->GetPath(szPath, MAX_PATH, NULL, 0))) + { + // If the target path is longer than the shortcut name, then add on the number + // of extra characters that are required. + int nNewLength = lstrlen(szPath); + if (nNewLength > nFileNameLength) + nExtraChars += nNewLength - nFileNameLength; + } + } + } + + // Free the ID-list returned by ParseDisplayName. + ::CoTaskMemFree(pidl); + } + } + } + } + + // If we need more space for shortcut targets, then reallocate. + if (nExtraChars > 0) + ATLVERIFY(ResizeFilenameBuffer(m_ofn.nMaxFile + nExtraChars)); + } + + // Helper for _ATL_MIN_CRT + static const TCHAR* _strrchr(const TCHAR* p, TCHAR ch) + { +#ifndef _ATL_MIN_CRT + return _tcsrchr(p, ch); +#else // _ATL_MIN_CRT + const TCHAR* lpsz = NULL; + while (*p != 0) + { + if (*p == ch) + lpsz = p; + p = ::CharNext(p); + } + return lpsz; +#endif // _ATL_MIN_CRT + } +}; + +class CMultiFileDialog : public CMultiFileDialogImpl +{ +public: + CMultiFileDialog( + LPCTSTR lpszDefExt = NULL, + LPCTSTR lpszFileName = NULL, + DWORD dwFlags = OFN_HIDEREADONLY, + LPCTSTR lpszFilter = NULL, + HWND hWndParent = NULL) + : CMultiFileDialogImpl(lpszDefExt, lpszFileName, dwFlags, lpszFilter, hWndParent) + { } + + BEGIN_MSG_MAP(CMultiFileDialog) + CHAIN_MSG_MAP(CMultiFileDialogImpl) + END_MSG_MAP() +}; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// Shell File Dialog - new Shell File Open and Save dialogs in Vista + +// Note: Use GetPtr() to access dialog interface methods. +// Example: +// CShellFileOpenDialog dlg; +// dlg.GetPtr()->SetTitle(L"MyFileOpenDialog"); + +#if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) + +/////////////////////////////////////////////////////////////////////////////// +// CShellFileDialogImpl - base class for CShellFileOpenDialogImpl and CShellFileSaveDialogImpl + +template +class ATL_NO_VTABLE CShellFileDialogImpl : public IFileDialogEvents +{ +public: +// Operations + INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) + { + INT_PTR nRet = -1; + + T* pT = static_cast(this); + if(pT->m_spFileDlg == NULL) + { + ATLASSERT(FALSE); + return nRet; + } + + DWORD dwCookie = 0; + pT->_Advise(dwCookie); + + HRESULT hRet = pT->m_spFileDlg->Show(hWndParent); + if(SUCCEEDED(hRet)) + nRet = IDOK; + else if(hRet == HRESULT_FROM_WIN32(ERROR_CANCELLED)) + nRet = IDCANCEL; + else + ATLASSERT(FALSE); // error + + pT->_Unadvise(dwCookie); + + return nRet; + } + + bool IsNull() const + { + const T* pT = static_cast(this); + return (pT->m_spFileDlg == NULL); + } + +// Operations - get file path after dialog returns + HRESULT GetFilePath(LPWSTR lpstrFilePath, int cchLength) + { + T* pT = static_cast(this); + ATLASSERT(pT->m_spFileDlg != NULL); + + ATL::CComPtr spItem; + HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem); + + if(SUCCEEDED(hRet)) + hRet = GetFileNameFromShellItem(spItem, SIGDN_FILESYSPATH, lpstrFilePath, cchLength); + + return hRet; + } + + HRESULT GetFileTitle(LPWSTR lpstrFileTitle, int cchLength) + { + T* pT = static_cast(this); + ATLASSERT(pT->m_spFileDlg != NULL); + + ATL::CComPtr spItem; + HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem); + + if(SUCCEEDED(hRet)) + hRet = GetFileNameFromShellItem(spItem, SIGDN_NORMALDISPLAY, lpstrFileTitle, cchLength); + + return hRet; + } + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + HRESULT GetFilePath(_CSTRING_NS::CString& strFilePath) + { + T* pT = static_cast(this); + ATLASSERT(pT->m_spFileDlg != NULL); + + ATL::CComPtr spItem; + HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem); + + if(SUCCEEDED(hRet)) + hRet = GetFileNameFromShellItem(spItem, SIGDN_FILESYSPATH, strFilePath); + + return hRet; + } + + HRESULT GetFileTitle(_CSTRING_NS::CString& strFileTitle) + { + T* pT = static_cast(this); + ATLASSERT(pT->m_spFileDlg != NULL); + + ATL::CComPtr spItem; + HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem); + + if(SUCCEEDED(hRet)) + hRet = GetFileNameFromShellItem(spItem, SIGDN_NORMALDISPLAY, strFileTitle); + + return hRet; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + +// Helpers for IShellItem + static HRESULT GetFileNameFromShellItem(IShellItem* pShellItem, SIGDN type, LPWSTR lpstr, int cchLength) + { + ATLASSERT(pShellItem != NULL); + + LPWSTR lpstrName = NULL; + HRESULT hRet = pShellItem->GetDisplayName(type, &lpstrName); + + if(SUCCEEDED(hRet)) + { + if(lstrlenW(lpstrName) < cchLength) + { + SecureHelper::strcpyW_x(lpstr, cchLength, lpstrName); + } + else + { + ATLASSERT(FALSE); + hRet = DISP_E_BUFFERTOOSMALL; + } + + ::CoTaskMemFree(lpstrName); + } + + return hRet; + } + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + static HRESULT GetFileNameFromShellItem(IShellItem* pShellItem, SIGDN type, _CSTRING_NS::CString& str) + { + ATLASSERT(pShellItem != NULL); + + LPWSTR lpstrName = NULL; + HRESULT hRet = pShellItem->GetDisplayName(type, &lpstrName); + + if(SUCCEEDED(hRet)) + { + str = lpstrName; + ::CoTaskMemFree(lpstrName); + } + + return hRet; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + +// Implementation + void _Advise(DWORD& dwCookie) + { + T* pT = static_cast(this); + ATLASSERT(pT->m_spFileDlg != NULL); + HRESULT hRet = pT->m_spFileDlg->Advise((IFileDialogEvents*)this, &dwCookie); + ATLVERIFY(SUCCEEDED(hRet)); + } + + void _Unadvise(DWORD dwCookie) + { + T* pT = static_cast(this); + ATLASSERT(pT->m_spFileDlg != NULL); + HRESULT hRet = pT->m_spFileDlg->Unadvise(dwCookie); + ATLVERIFY(SUCCEEDED(hRet)); + } + + void _Init(LPCWSTR lpszFileName, DWORD dwOptions, LPCWSTR lpszDefExt, const COMDLG_FILTERSPEC* arrFilterSpec, UINT uFilterSpecCount) + { + T* pT = static_cast(this); + ATLASSERT(pT->m_spFileDlg != NULL); + + HRESULT hRet = E_FAIL; + + if(lpszFileName != NULL) + { + hRet = pT->m_spFileDlg->SetFileName(lpszFileName); + ATLASSERT(SUCCEEDED(hRet)); + } + + hRet = pT->m_spFileDlg->SetOptions(dwOptions); + ATLASSERT(SUCCEEDED(hRet)); + + if(lpszDefExt != NULL) + { + hRet = pT->m_spFileDlg->SetDefaultExtension(lpszDefExt); + ATLASSERT(SUCCEEDED(hRet)); + } + + if(arrFilterSpec != NULL && uFilterSpecCount != 0U) + { + hRet = pT->m_spFileDlg->SetFileTypes(uFilterSpecCount, arrFilterSpec); + ATLASSERT(SUCCEEDED(hRet)); + } + } + +// Implementation - IUnknown interface + STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject) + { + if(ppvObject == NULL) + return E_POINTER; + + T* pT = static_cast(this); + if(IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IFileDialogEvents)) + { + *ppvObject = (IFileDialogEvents*)pT; + // AddRef() not needed + return S_OK; + } + + return E_NOINTERFACE; + } + + virtual ULONG STDMETHODCALLTYPE AddRef() + { + return 1; + } + + virtual ULONG STDMETHODCALLTYPE Release() + { + return 1; + } + +// Implementation - IFileDialogEvents interface + virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFileOk(IFileDialog* pfd) + { + T* pT = static_cast(this); + ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); + pfd; // avoid level 4 warning + return pT->OnFileOk(); + } + + virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFolderChanging(IFileDialog* pfd, IShellItem* psiFolder) + { + T* pT = static_cast(this); + ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); + pfd; // avoid level 4 warning + return pT->OnFolderChanging(psiFolder); + } + + virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFolderChange(IFileDialog* pfd) + { + T* pT = static_cast(this); + ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); + pfd; // avoid level 4 warning + return pT->OnFolderChange(); + } + + virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnSelectionChange(IFileDialog* pfd) + { + T* pT = static_cast(this); + ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); + pfd; // avoid level 4 warning + return pT->OnSelectionChange(); + } + + virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnShareViolation(IFileDialog* pfd, IShellItem* psi, FDE_SHAREVIOLATION_RESPONSE* pResponse) + { + T* pT = static_cast(this); + ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); + pfd; // avoid level 4 warning + return pT->OnShareViolation(psi, pResponse); + } + + virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnTypeChange(IFileDialog* pfd) + { + T* pT = static_cast(this); + ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); + pfd; // avoid level 4 warning + return pT->OnTypeChange(); + } + + virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnOverwrite(IFileDialog* pfd, IShellItem* psi, FDE_OVERWRITE_RESPONSE* pResponse) + { + T* pT = static_cast(this); + ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); + pfd; // avoid level 4 warning + return pT->OnOverwrite(psi, pResponse); + } + +// Overrideables - Event handlers + HRESULT OnFileOk() + { + return E_NOTIMPL; + } + + HRESULT OnFolderChanging(IShellItem* /*psiFolder*/) + { + return E_NOTIMPL; + } + + HRESULT OnFolderChange() + { + return E_NOTIMPL; + } + + HRESULT OnSelectionChange() + { + return E_NOTIMPL; + } + + HRESULT OnShareViolation(IShellItem* /*psi*/, FDE_SHAREVIOLATION_RESPONSE* /*pResponse*/) + { + return E_NOTIMPL; + } + + HRESULT OnTypeChange() + { + return E_NOTIMPL; + } + + HRESULT OnOverwrite(IShellItem* /*psi*/, FDE_OVERWRITE_RESPONSE* /*pResponse*/) + { + return E_NOTIMPL; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CShellFileOpenDialogImpl - implements new Shell File Open dialog + +template +class ATL_NO_VTABLE CShellFileOpenDialogImpl : public CShellFileDialogImpl< T > +{ +public: + ATL::CComPtr m_spFileDlg; + + CShellFileOpenDialogImpl(LPCWSTR lpszFileName = NULL, + DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST, + LPCWSTR lpszDefExt = NULL, + const COMDLG_FILTERSPEC* arrFilterSpec = NULL, + UINT uFilterSpecCount = 0U) + { + HRESULT hRet = m_spFileDlg.CoCreateInstance(CLSID_FileOpenDialog); + + if(SUCCEEDED(hRet)) + _Init(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount); + } + + IFileOpenDialog* GetPtr() + { + return m_spFileDlg; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CShellFileOpenDialog - new Shell File Open dialog without events + +class CShellFileOpenDialog : public CShellFileOpenDialogImpl +{ +public: + CShellFileOpenDialog(LPCWSTR lpszFileName = NULL, + DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST, + LPCWSTR lpszDefExt = NULL, + const COMDLG_FILTERSPEC* arrFilterSpec = NULL, + UINT uFilterSpecCount = 0U) : CShellFileOpenDialogImpl(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount) + { } + +// Implementation (remove _Advise/_Unadvise code using template magic) + void _Advise(DWORD& /*dwCookie*/) + { } + + void _Unadvise(DWORD /*dwCookie*/) + { } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CShellFileSaveDialogImpl - implements new Shell File Save dialog + +template +class ATL_NO_VTABLE CShellFileSaveDialogImpl : public CShellFileDialogImpl< T > +{ +public: + ATL::CComPtr m_spFileDlg; + + CShellFileSaveDialogImpl(LPCWSTR lpszFileName = NULL, + DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT, + LPCWSTR lpszDefExt = NULL, + const COMDLG_FILTERSPEC* arrFilterSpec = NULL, + UINT uFilterSpecCount = 0U) + { + HRESULT hRet = m_spFileDlg.CoCreateInstance(CLSID_FileSaveDialog); + + if(SUCCEEDED(hRet)) + _Init(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount); + } + + IFileSaveDialog* GetPtr() + { + return m_spFileDlg; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CShellFileSaveDialog - new Shell File Save dialog without events + +class CShellFileSaveDialog : public CShellFileSaveDialogImpl +{ +public: + CShellFileSaveDialog(LPCWSTR lpszFileName = NULL, + DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT, + LPCWSTR lpszDefExt = NULL, + const COMDLG_FILTERSPEC* arrFilterSpec = NULL, + UINT uFilterSpecCount = 0U) : CShellFileSaveDialogImpl(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount) + { } + +// Implementation (remove _Advise/_Unadvise code using template magic) + void _Advise(DWORD& /*dwCookie*/) + { } + + void _Unadvise(DWORD /*dwCookie*/) + { } +}; + +#endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) + + +/////////////////////////////////////////////////////////////////////////////// +// CFolderDialogImpl - used for browsing for a folder + +#ifndef _WIN32_WCE + +template +class ATL_NO_VTABLE CFolderDialogImpl +{ +public: + BROWSEINFO m_bi; + LPCTSTR m_lpstrInitialFolder; + LPCITEMIDLIST m_pidlInitialSelection; + bool m_bExpandInitialSelection; + TCHAR m_szFolderDisplayName[MAX_PATH]; + TCHAR m_szFolderPath[MAX_PATH]; + LPITEMIDLIST m_pidlSelected; + HWND m_hWnd; // used only in the callback function + +// Constructor + CFolderDialogImpl(HWND hWndParent = NULL, LPCTSTR lpstrTitle = NULL, UINT uFlags = BIF_RETURNONLYFSDIRS) : + m_lpstrInitialFolder(NULL), m_pidlInitialSelection(NULL), m_bExpandInitialSelection(false), m_pidlSelected(NULL), m_hWnd(NULL) + { + memset(&m_bi, 0, sizeof(m_bi)); // initialize structure to 0/NULL + + m_bi.hwndOwner = hWndParent; + m_bi.pidlRoot = NULL; + m_bi.pszDisplayName = m_szFolderDisplayName; + m_bi.lpszTitle = lpstrTitle; + m_bi.ulFlags = uFlags; + m_bi.lpfn = BrowseCallbackProc; + m_bi.lParam = (LPARAM)static_cast(this); + + m_szFolderPath[0] = 0; + m_szFolderDisplayName[0] = 0; + } + + ~CFolderDialogImpl() + { + ::CoTaskMemFree(m_pidlSelected); + } + +// Operations + INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) + { + if(m_bi.hwndOwner == NULL) // set only if not specified before + m_bi.hwndOwner = hWndParent; + + // Clear out any previous results + m_szFolderPath[0] = 0; + m_szFolderDisplayName[0] = 0; + ::CoTaskMemFree(m_pidlSelected); + + INT_PTR nRet = IDCANCEL; + m_pidlSelected = ::SHBrowseForFolder(&m_bi); + + if(m_pidlSelected != NULL) + { + nRet = IDOK; + + // If BIF_RETURNONLYFSDIRS is set, we try to get the filesystem path. + // Otherwise, the caller must handle the ID-list directly. + if((m_bi.ulFlags & BIF_RETURNONLYFSDIRS) != 0) + { + if(::SHGetPathFromIDList(m_pidlSelected, m_szFolderPath) == FALSE) + nRet = IDCANCEL; + } + } + + return nRet; + } + + // Methods to call before DoModal + void SetInitialFolder(LPCTSTR lpstrInitialFolder, bool bExpand = true) + { + // lpstrInitialFolder may be a file if BIF_BROWSEINCLUDEFILES is specified + m_lpstrInitialFolder = lpstrInitialFolder; + m_bExpandInitialSelection = bExpand; + } + + void SetInitialSelection(LPCITEMIDLIST pidl, bool bExpand = true) + { + m_pidlInitialSelection = pidl; + m_bExpandInitialSelection = bExpand; + } + + // Methods to call after DoModal + LPITEMIDLIST GetSelectedItem(bool bDetach = false) + { + LPITEMIDLIST pidl = m_pidlSelected; + if(bDetach) + m_pidlSelected = NULL; + + return pidl; + } + + LPCTSTR GetFolderPath() const + { + return m_szFolderPath; + } + + LPCTSTR GetFolderDisplayName() const + { + return m_szFolderDisplayName; + } + + int GetFolderImageIndex() const + { + return m_bi.iImage; + } + +// Callback function and overrideables + static int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData) + { +#ifndef BFFM_VALIDATEFAILED + #ifdef UNICODE + const int BFFM_VALIDATEFAILED = 4; + #else + const int BFFM_VALIDATEFAILED = 3; + #endif +#endif // !BFFM_VALIDATEFAILED +#ifndef BFFM_IUNKNOWN + const int BFFM_IUNKNOWN = 5; +#endif // !BFFM_IUNKNOWN +#ifndef BIF_NEWDIALOGSTYLE + const UINT BIF_NEWDIALOGSTYLE = 0x0040; +#endif // !BIF_NEWDIALOGSTYLE + + int nRet = 0; + T* pT = (T*)lpData; + bool bClear = false; + if(pT->m_hWnd == NULL) + { + pT->m_hWnd = hWnd; + bClear = true; + } + else + { + ATLASSERT(pT->m_hWnd == hWnd); + } + + switch(uMsg) + { + case BFFM_INITIALIZED: + // Set initial selection + // Note that m_pidlInitialSelection, if set, takes precedence over m_lpstrInitialFolder + if(pT->m_pidlInitialSelection != NULL) + pT->SetSelection(pT->m_pidlInitialSelection); + else if(pT->m_lpstrInitialFolder != NULL) + pT->SetSelection(pT->m_lpstrInitialFolder); + + // Expand initial selection if appropriate + if(pT->m_bExpandInitialSelection && ((pT->m_bi.ulFlags & BIF_NEWDIALOGSTYLE) != 0)) + { + if(pT->m_pidlInitialSelection != NULL) + pT->SetExpanded(pT->m_pidlInitialSelection); + else if(pT->m_lpstrInitialFolder != NULL) + pT->SetExpanded(pT->m_lpstrInitialFolder); + } + pT->OnInitialized(); + break; + case BFFM_SELCHANGED: + pT->OnSelChanged((LPITEMIDLIST)lParam); + break; + case BFFM_VALIDATEFAILED: + nRet = pT->OnValidateFailed((LPCTSTR)lParam); + break; + case BFFM_IUNKNOWN: + pT->OnIUnknown((IUnknown*)lParam); + break; + default: + ATLTRACE2(atlTraceUI, 0, _T("Unknown message received in CFolderDialogImpl::BrowseCallbackProc\n")); + break; + } + + if(bClear) + pT->m_hWnd = NULL; + return nRet; + } + + void OnInitialized() + { + } + + void OnSelChanged(LPITEMIDLIST /*pItemIDList*/) + { + } + + int OnValidateFailed(LPCTSTR /*lpstrFolderPath*/) + { + return 1; // 1=continue, 0=EndDialog + } + + void OnIUnknown(IUnknown* /*pUnknown*/) + { + } + + // Commands - valid to call only from handlers + void EnableOK(BOOL bEnable) + { + ATLASSERT(m_hWnd != NULL); + ::SendMessage(m_hWnd, BFFM_ENABLEOK, 0, bEnable); + } + + void SetSelection(LPCITEMIDLIST pItemIDList) + { + ATLASSERT(m_hWnd != NULL); + ::SendMessage(m_hWnd, BFFM_SETSELECTION, FALSE, (LPARAM)pItemIDList); + } + + void SetSelection(LPCTSTR lpstrFolderPath) + { + ATLASSERT(m_hWnd != NULL); + ::SendMessage(m_hWnd, BFFM_SETSELECTION, TRUE, (LPARAM)lpstrFolderPath); + } + + void SetStatusText(LPCTSTR lpstrText) + { + ATLASSERT(m_hWnd != NULL); + ::SendMessage(m_hWnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)lpstrText); + } + + void SetOKText(LPCTSTR lpstrOKText) + { +#ifndef BFFM_SETOKTEXT + const UINT BFFM_SETOKTEXT = WM_USER + 105; +#endif + ATLASSERT(m_hWnd != NULL); + USES_CONVERSION; + LPCWSTR lpstr = T2CW(lpstrOKText); + ::SendMessage(m_hWnd, BFFM_SETOKTEXT, 0, (LPARAM)lpstr); + } + + void SetExpanded(LPCITEMIDLIST pItemIDList) + { +#ifndef BFFM_SETEXPANDED + const UINT BFFM_SETEXPANDED = WM_USER + 106; +#endif + ATLASSERT(m_hWnd != NULL); + ::SendMessage(m_hWnd, BFFM_SETEXPANDED, FALSE, (LPARAM)pItemIDList); + } + + void SetExpanded(LPCTSTR lpstrFolderPath) + { +#ifndef BFFM_SETEXPANDED + const UINT BFFM_SETEXPANDED = WM_USER + 106; +#endif + ATLASSERT(m_hWnd != NULL); + USES_CONVERSION; + LPCWSTR lpstr = T2CW(lpstrFolderPath); + ::SendMessage(m_hWnd, BFFM_SETEXPANDED, TRUE, (LPARAM)lpstr); + } +}; + +class CFolderDialog : public CFolderDialogImpl +{ +public: + CFolderDialog(HWND hWndParent = NULL, LPCTSTR lpstrTitle = NULL, UINT uFlags = BIF_RETURNONLYFSDIRS) + : CFolderDialogImpl(hWndParent, lpstrTitle, uFlags) + { } +}; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CCommonDialogImplBase - base class for common dialog classes + +class ATL_NO_VTABLE CCommonDialogImplBase : public ATL::CWindowImplBase +{ +public: + static UINT_PTR APIENTRY HookProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + if(uMsg != WM_INITDIALOG) + return 0; + CCommonDialogImplBase* pT = (CCommonDialogImplBase*)ModuleHelper::ExtractCreateWndData(); + ATLASSERT(pT != NULL); + ATLASSERT(pT->m_hWnd == NULL); + ATLASSERT(::IsWindow(hWnd)); + // subclass dialog's window + if(!pT->SubclassWindow(hWnd)) + { + ATLTRACE2(atlTraceUI, 0, _T("Subclassing a common dialog failed\n")); + return 0; + } + // check message map for WM_INITDIALOG handler + LRESULT lRes = 0; + if(pT->ProcessWindowMessage(pT->m_hWnd, uMsg, wParam, lParam, lRes, 0) == FALSE) + return 0; + return lRes; + } + +// Special override for common dialogs + BOOL EndDialog(INT_PTR /*nRetCode*/ = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + SendMessage(WM_COMMAND, MAKEWPARAM(IDABORT, 0)); + return TRUE; + } + +// Implementation - try to override these, to prevent errors + HWND Create(HWND, ATL::_U_RECT, LPCTSTR, DWORD, DWORD, ATL::_U_MENUorID, ATOM, LPVOID) + { + ATLASSERT(FALSE); // should not be called + return NULL; + } + + static LRESULT CALLBACK StartWindowProc(HWND /*hWnd*/, UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/) + { + ATLASSERT(FALSE); // should not be called + return 0; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CFontDialogImpl - font selection dialog + +#ifndef _WIN32_WCE + +template +class ATL_NO_VTABLE CFontDialogImpl : public CCommonDialogImplBase +{ +public: + enum { _cchStyleName = 64 }; + + CHOOSEFONT m_cf; + TCHAR m_szStyleName[_cchStyleName]; // contains style name after return + LOGFONT m_lf; // default LOGFONT to store the info + +// Constructors + CFontDialogImpl(LPLOGFONT lplfInitial = NULL, + DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS, + HDC hDCPrinter = NULL, + HWND hWndParent = NULL) + { + memset(&m_cf, 0, sizeof(m_cf)); + memset(&m_lf, 0, sizeof(m_lf)); + memset(&m_szStyleName, 0, sizeof(m_szStyleName)); + + m_cf.lStructSize = sizeof(m_cf); + m_cf.hwndOwner = hWndParent; + m_cf.rgbColors = RGB(0, 0, 0); + m_cf.lpszStyle = (LPTSTR)&m_szStyleName; + m_cf.Flags = dwFlags | CF_ENABLEHOOK; + m_cf.lpfnHook = (LPCFHOOKPROC)T::HookProc; + + if(lplfInitial != NULL) + { + m_cf.lpLogFont = lplfInitial; + m_cf.Flags |= CF_INITTOLOGFONTSTRUCT; + m_lf = *lplfInitial; + } + else + { + m_cf.lpLogFont = &m_lf; + } + + if(hDCPrinter != NULL) + { + m_cf.hDC = hDCPrinter; + m_cf.Flags |= CF_PRINTERFONTS; + } + } + +// Operations + INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) + { + ATLASSERT((m_cf.Flags & CF_ENABLEHOOK) != 0); + ATLASSERT(m_cf.lpfnHook != NULL); // can still be a user hook + + if(m_cf.hwndOwner == NULL) // set only if not specified before + m_cf.hwndOwner = hWndParent; + + ATLASSERT(m_hWnd == NULL); + ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this); + + BOOL bRet = ::ChooseFont(&m_cf); + + m_hWnd = NULL; + + if(bRet) // copy logical font from user's initialization buffer (if needed) + SecureHelper::memcpy_x(&m_lf, sizeof(m_lf), m_cf.lpLogFont, sizeof(m_lf)); + + return bRet ? IDOK : IDCANCEL; + } + + // works only when the dialog is dislayed or after + void GetCurrentFont(LPLOGFONT lplf) const + { + ATLASSERT(lplf != NULL); + + if(m_hWnd != NULL) + ::SendMessage(m_hWnd, WM_CHOOSEFONT_GETLOGFONT, 0, (LPARAM)lplf); + else + *lplf = m_lf; + } + + // works only when the dialog is dislayed or before +#ifndef _WIN32_WCE + void SetLogFont(LPLOGFONT lplf) + { + ATLASSERT(lplf != NULL); +#ifndef WM_CHOOSEFONT_SETLOGFONT + const UINT WM_CHOOSEFONT_SETLOGFONT = (WM_USER + 101); +#endif + if(m_hWnd != NULL) + { + ::SendMessage(m_hWnd, WM_CHOOSEFONT_SETLOGFONT, 0, (LPARAM)lplf); + } + else + { + m_lf = *lplf; + m_cf.Flags |= CF_INITTOLOGFONTSTRUCT; + } + } + + void SetFlags(DWORD dwFlags) + { +#ifndef WM_CHOOSEFONT_SETFLAGS + const UINT WM_CHOOSEFONT_SETFLAGS = (WM_USER + 102); +#endif + if(m_hWnd != NULL) + { + CHOOSEFONT cf = { sizeof(CHOOSEFONT) }; + cf.Flags = dwFlags; + ::SendMessage(m_hWnd, WM_CHOOSEFONT_SETFLAGS, 0, (LPARAM)&cf); + } + else + { + m_cf.Flags = dwFlags; + } + } +#endif // !_WIN32_WCE + + // Helpers for parsing information after successful return + LPCTSTR GetFaceName() const // return the face name of the font + { + return (LPCTSTR)m_cf.lpLogFont->lfFaceName; + } + + LPCTSTR GetStyleName() const // return the style name of the font + { + return m_cf.lpszStyle; + } + + int GetSize() const // return the pt size of the font + { + return m_cf.iPointSize; + } + + COLORREF GetColor() const // return the color of the font + { + return m_cf.rgbColors; + } + + int GetWeight() const // return the chosen font weight + { + return (int)m_cf.lpLogFont->lfWeight; + } + + BOOL IsStrikeOut() const // return TRUE if strikeout + { + return (m_cf.lpLogFont->lfStrikeOut) ? TRUE : FALSE; + } + + BOOL IsUnderline() const // return TRUE if underline + { + return (m_cf.lpLogFont->lfUnderline) ? TRUE : FALSE; + } + + BOOL IsBold() const // return TRUE if bold font + { + return (m_cf.lpLogFont->lfWeight == FW_BOLD) ? TRUE : FALSE; + } + + BOOL IsItalic() const // return TRUE if italic font + { + return m_cf.lpLogFont->lfItalic ? TRUE : FALSE; + } +}; + +class CFontDialog : public CFontDialogImpl +{ +public: + CFontDialog(LPLOGFONT lplfInitial = NULL, + DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS, + HDC hDCPrinter = NULL, + HWND hWndParent = NULL) + : CFontDialogImpl(lplfInitial, dwFlags, hDCPrinter, hWndParent) + { } + + DECLARE_EMPTY_MSG_MAP() +}; + +#endif // _WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CRichEditFontDialogImpl - font selection for the Rich Edit ctrl + +#if defined(_RICHEDIT_) && !defined(_WIN32_WCE) + +template +class ATL_NO_VTABLE CRichEditFontDialogImpl : public CFontDialogImpl< T > +{ +public: + CRichEditFontDialogImpl(const CHARFORMAT& charformat, + DWORD dwFlags = CF_SCREENFONTS, + HDC hDCPrinter = NULL, + HWND hWndParent = NULL) + : CFontDialogImpl< T >(NULL, dwFlags, hDCPrinter, hWndParent) + { + m_cf.Flags |= CF_INITTOLOGFONTSTRUCT; + m_cf.Flags |= FillInLogFont(charformat); + m_cf.lpLogFont = &m_lf; + + if((charformat.dwMask & CFM_COLOR) != 0) + m_cf.rgbColors = charformat.crTextColor; + } + + void GetCharFormat(CHARFORMAT& cf) const + { + USES_CONVERSION; + cf.dwEffects = 0; + cf.dwMask = 0; + if((m_cf.Flags & CF_NOSTYLESEL) == 0) + { + cf.dwMask |= CFM_BOLD | CFM_ITALIC; + cf.dwEffects |= IsBold() ? CFE_BOLD : 0; + cf.dwEffects |= IsItalic() ? CFE_ITALIC : 0; + } + if((m_cf.Flags & CF_NOSIZESEL) == 0) + { + cf.dwMask |= CFM_SIZE; + // GetSize() returns in tenths of points so mulitply by 2 to get twips + cf.yHeight = GetSize() * 2; + } + + if((m_cf.Flags & CF_NOFACESEL) == 0) + { + cf.dwMask |= CFM_FACE; + cf.bPitchAndFamily = m_cf.lpLogFont->lfPitchAndFamily; +#if (_RICHEDIT_VER >= 0x0200) + SecureHelper::strcpy_x(cf.szFaceName, _countof(cf.szFaceName), GetFaceName()); +#else // !(_RICHEDIT_VER >= 0x0200) + SecureHelper::strcpyA_x(cf.szFaceName, _countof(cf.szFaceName), T2A((LPTSTR)(LPCTSTR)GetFaceName())); +#endif // !(_RICHEDIT_VER >= 0x0200) + } + + if((m_cf.Flags & CF_EFFECTS) != 0) + { + cf.dwMask |= CFM_UNDERLINE | CFM_STRIKEOUT | CFM_COLOR; + cf.dwEffects |= IsUnderline() ? CFE_UNDERLINE : 0; + cf.dwEffects |= IsStrikeOut() ? CFE_STRIKEOUT : 0; + cf.crTextColor = GetColor(); + } + if((m_cf.Flags & CF_NOSCRIPTSEL) == 0) + { + cf.bCharSet = m_cf.lpLogFont->lfCharSet; + cf.dwMask |= CFM_CHARSET; + } + cf.yOffset = 0; + } + + DWORD FillInLogFont(const CHARFORMAT& cf) + { + USES_CONVERSION; + DWORD dwFlags = 0; + if((cf.dwMask & CFM_SIZE) != 0) + { + HDC hDC = ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL); + LONG yPerInch = ::GetDeviceCaps(hDC, LOGPIXELSY); + m_lf.lfHeight = -(int)((cf.yHeight * yPerInch) / 1440); + } + else + m_lf.lfHeight = 0; + + m_lf.lfWidth = 0; + m_lf.lfEscapement = 0; + m_lf.lfOrientation = 0; + + if((cf.dwMask & (CFM_ITALIC | CFM_BOLD)) == (CFM_ITALIC | CFM_BOLD)) + { + m_lf.lfWeight = ((cf.dwEffects & CFE_BOLD) != 0) ? FW_BOLD : FW_NORMAL; + m_lf.lfItalic = (BYTE)(((cf.dwEffects & CFE_ITALIC) != 0) ? TRUE : FALSE); + } + else + { + dwFlags |= CF_NOSTYLESEL; + m_lf.lfWeight = FW_DONTCARE; + m_lf.lfItalic = FALSE; + } + + if((cf.dwMask & (CFM_UNDERLINE | CFM_STRIKEOUT | CFM_COLOR)) == (CFM_UNDERLINE|CFM_STRIKEOUT|CFM_COLOR)) + { + dwFlags |= CF_EFFECTS; + m_lf.lfUnderline = (BYTE)(((cf.dwEffects & CFE_UNDERLINE) != 0) ? TRUE : FALSE); + m_lf.lfStrikeOut = (BYTE)(((cf.dwEffects & CFE_STRIKEOUT) != 0) ? TRUE : FALSE); + } + else + { + m_lf.lfUnderline = (BYTE)FALSE; + m_lf.lfStrikeOut = (BYTE)FALSE; + } + + if((cf.dwMask & CFM_CHARSET) != 0) + m_lf.lfCharSet = cf.bCharSet; + else + dwFlags |= CF_NOSCRIPTSEL; + m_lf.lfOutPrecision = OUT_DEFAULT_PRECIS; + m_lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + m_lf.lfQuality = DEFAULT_QUALITY; + if((cf.dwMask & CFM_FACE) != 0) + { + m_lf.lfPitchAndFamily = cf.bPitchAndFamily; +#if (_RICHEDIT_VER >= 0x0200) + SecureHelper::strcpy_x(m_lf.lfFaceName, _countof(m_lf.lfFaceName), cf.szFaceName); +#else // !(_RICHEDIT_VER >= 0x0200) + SecureHelper::strcpy_x(m_lf.lfFaceName, _countof(m_lf.lfFaceName), A2T((LPSTR)cf.szFaceName)); +#endif // !(_RICHEDIT_VER >= 0x0200) + } + else + { + m_lf.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE; + m_lf.lfFaceName[0] = (TCHAR)0; + } + return dwFlags; + } +}; + +class CRichEditFontDialog : public CRichEditFontDialogImpl +{ +public: + CRichEditFontDialog(const CHARFORMAT& charformat, + DWORD dwFlags = CF_SCREENFONTS, + HDC hDCPrinter = NULL, + HWND hWndParent = NULL) + : CRichEditFontDialogImpl(charformat, dwFlags, hDCPrinter, hWndParent) + { } + + DECLARE_EMPTY_MSG_MAP() +}; + +#endif // defined(_RICHEDIT_) && !defined(_WIN32_WCE) + + +/////////////////////////////////////////////////////////////////////////////// +// CColorDialogImpl - color selection + +#if !defined(_WIN32_WCE) || ((_WIN32_WCE > 420) && !(defined(WIN32_PLATFORM_WFSP) && (_WIN32_WCE > 0x0500))) + +#ifdef _WIN32_WCE + #pragma comment(lib, "commdlg.lib") + + #ifndef SETRGBSTRING + #define SETRGBSTRING _T("commdlg_SetRGBColor") + #endif + + #ifndef COLOROKSTRING + #define COLOROKSTRING _T("commdlg_ColorOK") + #endif +#endif + +template +class ATL_NO_VTABLE CColorDialogImpl : public CCommonDialogImplBase +{ +public: + CHOOSECOLOR m_cc; + +// Constructor + CColorDialogImpl(COLORREF clrInit = 0, DWORD dwFlags = 0, HWND hWndParent = NULL) + { + memset(&m_cc, 0, sizeof(m_cc)); + + m_cc.lStructSize = sizeof(m_cc); + m_cc.lpCustColors = GetCustomColors(); + m_cc.hwndOwner = hWndParent; + m_cc.Flags = dwFlags | CC_ENABLEHOOK; + m_cc.lpfnHook = (LPCCHOOKPROC)T::HookProc; + + if(clrInit != 0) + { + m_cc.rgbResult = clrInit; + m_cc.Flags |= CC_RGBINIT; + } + } + +// Operations + INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) + { + ATLASSERT((m_cc.Flags & CC_ENABLEHOOK) != 0); + ATLASSERT(m_cc.lpfnHook != NULL); // can still be a user hook + + if(m_cc.hwndOwner == NULL) // set only if not specified before + m_cc.hwndOwner = hWndParent; + + ATLASSERT(m_hWnd == NULL); + ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this); + + BOOL bRet = ::ChooseColor(&m_cc); + + m_hWnd = NULL; + + return bRet ? IDOK : IDCANCEL; + } + + // Set the current color while dialog is displayed + void SetCurrentColor(COLORREF clr) + { + ATLASSERT(::IsWindow(m_hWnd)); + SendMessage(_GetSetRGBMessage(), 0, (LPARAM)clr); + } + + // Get the selected color after DoModal returns, or in OnColorOK + COLORREF GetColor() const + { + return m_cc.rgbResult; + } + +// Special override for the color dialog + static UINT_PTR APIENTRY HookProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + if(uMsg != WM_INITDIALOG && uMsg != _GetColorOKMessage()) + return 0; + + LPCHOOSECOLOR lpCC = (LPCHOOSECOLOR)lParam; + CCommonDialogImplBase* pT = NULL; + + if(uMsg == WM_INITDIALOG) + { + pT = (CCommonDialogImplBase*)ModuleHelper::ExtractCreateWndData(); + lpCC->lCustData = (LPARAM)pT; + ATLASSERT(pT != NULL); + ATLASSERT(pT->m_hWnd == NULL); + ATLASSERT(::IsWindow(hWnd)); + // subclass dialog's window + if(!pT->SubclassWindow(hWnd)) + { + ATLTRACE2(atlTraceUI, 0, _T("Subclassing a Color common dialog failed\n")); + return 0; + } + } + else if(uMsg == _GetColorOKMessage()) + { + pT = (CCommonDialogImplBase*)lpCC->lCustData; + ATLASSERT(pT != NULL); + ATLASSERT(::IsWindow(pT->m_hWnd)); + } + + // pass to the message map + LRESULT lRes; + if(pT->ProcessWindowMessage(pT->m_hWnd, uMsg, wParam, lParam, lRes, 0) == FALSE) + return 0; + return lRes; + } + +// Helpers + static COLORREF* GetCustomColors() + { + static COLORREF rgbCustomColors[16] = + { + RGB(255, 255, 255), RGB(255, 255, 255), + RGB(255, 255, 255), RGB(255, 255, 255), + RGB(255, 255, 255), RGB(255, 255, 255), + RGB(255, 255, 255), RGB(255, 255, 255), + RGB(255, 255, 255), RGB(255, 255, 255), + RGB(255, 255, 255), RGB(255, 255, 255), + RGB(255, 255, 255), RGB(255, 255, 255), + RGB(255, 255, 255), RGB(255, 255, 255), + }; + + return rgbCustomColors; + } + + static UINT _GetSetRGBMessage() + { + static UINT uSetRGBMessage = 0; + if(uSetRGBMessage == 0) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CColorDialogImpl::_GetSetRGBMessage.\n")); + ATLASSERT(FALSE); + return 0; + } + + if(uSetRGBMessage == 0) + uSetRGBMessage = ::RegisterWindowMessage(SETRGBSTRING); + + lock.Unlock(); + } + ATLASSERT(uSetRGBMessage != 0); + return uSetRGBMessage; + } + + static UINT _GetColorOKMessage() + { + static UINT uColorOKMessage = 0; + if(uColorOKMessage == 0) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CColorDialogImpl::_GetColorOKMessage.\n")); + ATLASSERT(FALSE); + return 0; + } + + if(uColorOKMessage == 0) + uColorOKMessage = ::RegisterWindowMessage(COLOROKSTRING); + + lock.Unlock(); + } + ATLASSERT(uColorOKMessage != 0); + return uColorOKMessage; + } + +// Message map and handlers + BEGIN_MSG_MAP(CColorDialogImpl) + MESSAGE_HANDLER(_GetColorOKMessage(), _OnColorOK) + END_MSG_MAP() + + LRESULT _OnColorOK(UINT, WPARAM, LPARAM, BOOL&) + { + T* pT = static_cast(this); + return pT->OnColorOK(); + } + +// Overrideable + BOOL OnColorOK() // validate color + { + return FALSE; + } +}; + +class CColorDialog : public CColorDialogImpl +{ +public: + CColorDialog(COLORREF clrInit = 0, DWORD dwFlags = 0, HWND hWndParent = NULL) + : CColorDialogImpl(clrInit, dwFlags, hWndParent) + { } + + // override base class map and references to handlers + DECLARE_EMPTY_MSG_MAP() +}; + +#endif // !defined(_WIN32_WCE) || ((_WIN32_WCE > 420) && !(defined(WIN32_PLATFORM_WFSP) && (_WIN32_WCE > 0x0500))) + + +/////////////////////////////////////////////////////////////////////////////// +// CPrintDialogImpl - used for Print... and PrintSetup... + +#ifndef _WIN32_WCE + +// global helper +static HDC _AtlCreateDC(HGLOBAL hDevNames, HGLOBAL hDevMode) +{ + if(hDevNames == NULL) + return NULL; + + LPDEVNAMES lpDevNames = (LPDEVNAMES)::GlobalLock(hDevNames); + LPDEVMODE lpDevMode = (hDevMode != NULL) ? (LPDEVMODE)::GlobalLock(hDevMode) : NULL; + + if(lpDevNames == NULL) + return NULL; + + HDC hDC = ::CreateDC((LPCTSTR)lpDevNames + lpDevNames->wDriverOffset, + (LPCTSTR)lpDevNames + lpDevNames->wDeviceOffset, + (LPCTSTR)lpDevNames + lpDevNames->wOutputOffset, + lpDevMode); + + ::GlobalUnlock(hDevNames); + if(hDevMode != NULL) + ::GlobalUnlock(hDevMode); + return hDC; +} + +template +class ATL_NO_VTABLE CPrintDialogImpl : public CCommonDialogImplBase +{ +public: + // print dialog parameter block (note this is a reference) + PRINTDLG& m_pd; + +// Constructors + CPrintDialogImpl(BOOL bPrintSetupOnly = FALSE, // TRUE for Print Setup, FALSE for Print Dialog + DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_NOSELECTION, + HWND hWndParent = NULL) + : m_pd(m_pdActual) + { + memset(&m_pdActual, 0, sizeof(m_pdActual)); + + m_pd.lStructSize = sizeof(m_pdActual); + m_pd.hwndOwner = hWndParent; + m_pd.Flags = (dwFlags | PD_ENABLEPRINTHOOK | PD_ENABLESETUPHOOK); + m_pd.lpfnPrintHook = (LPPRINTHOOKPROC)T::HookProc; + m_pd.lpfnSetupHook = (LPSETUPHOOKPROC)T::HookProc; + + if(bPrintSetupOnly) + m_pd.Flags |= PD_PRINTSETUP; + else + m_pd.Flags |= PD_RETURNDC; + + m_pd.Flags &= ~PD_RETURNIC; // do not support information context + } + +// Operations + INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) + { + ATLASSERT((m_pd.Flags & PD_ENABLEPRINTHOOK) != 0); + ATLASSERT((m_pd.Flags & PD_ENABLESETUPHOOK) != 0); + ATLASSERT(m_pd.lpfnPrintHook != NULL); // can still be a user hook + ATLASSERT(m_pd.lpfnSetupHook != NULL); // can still be a user hook + ATLASSERT((m_pd.Flags & PD_RETURNDEFAULT) == 0); // use GetDefaults for this + + if(m_pd.hwndOwner == NULL) // set only if not specified before + m_pd.hwndOwner = hWndParent; + + ATLASSERT(m_hWnd == NULL); + ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this); + + BOOL bRet = ::PrintDlg(&m_pd); + + m_hWnd = NULL; + + return bRet ? IDOK : IDCANCEL; + } + + // GetDefaults will not display a dialog but will get device defaults + BOOL GetDefaults() + { + m_pd.Flags |= PD_RETURNDEFAULT; + ATLASSERT(m_pd.hDevMode == NULL); // must be NULL + ATLASSERT(m_pd.hDevNames == NULL); // must be NULL + + return ::PrintDlg(&m_pd); + } + + // Helpers for parsing information after successful return num. copies requested + int GetCopies() const + { + if((m_pd.Flags & PD_USEDEVMODECOPIES) != 0) + { + LPDEVMODE lpDevMode = GetDevMode(); + return (lpDevMode != NULL) ? lpDevMode->dmCopies : -1; + } + + return m_pd.nCopies; + } + + BOOL PrintCollate() const // TRUE if collate checked + { + return ((m_pd.Flags & PD_COLLATE) != 0) ? TRUE : FALSE; + } + + BOOL PrintSelection() const // TRUE if printing selection + { + return ((m_pd.Flags & PD_SELECTION) != 0) ? TRUE : FALSE; + } + + BOOL PrintAll() const // TRUE if printing all pages + { + return (!PrintRange() && !PrintSelection()) ? TRUE : FALSE; + } + + BOOL PrintRange() const // TRUE if printing page range + { + return ((m_pd.Flags & PD_PAGENUMS) != 0) ? TRUE : FALSE; + } + + BOOL PrintToFile() const // TRUE if printing to a file + { + return ((m_pd.Flags & PD_PRINTTOFILE) != 0) ? TRUE : FALSE; + } + + int GetFromPage() const // starting page if valid + { + return PrintRange() ? m_pd.nFromPage : -1; + } + + int GetToPage() const // ending page if valid + { + return PrintRange() ? m_pd.nToPage : -1; + } + + LPDEVMODE GetDevMode() const // return DEVMODE + { + if(m_pd.hDevMode == NULL) + return NULL; + + return (LPDEVMODE)::GlobalLock(m_pd.hDevMode); + } + + LPCTSTR GetDriverName() const // return driver name + { + if(m_pd.hDevNames == NULL) + return NULL; + + LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pd.hDevNames); + if(lpDev == NULL) + return NULL; + + return (LPCTSTR)lpDev + lpDev->wDriverOffset; + } + + LPCTSTR GetDeviceName() const // return device name + { + if(m_pd.hDevNames == NULL) + return NULL; + + LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pd.hDevNames); + if(lpDev == NULL) + return NULL; + + return (LPCTSTR)lpDev + lpDev->wDeviceOffset; + } + + LPCTSTR GetPortName() const // return output port name + { + if(m_pd.hDevNames == NULL) + return NULL; + + LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pd.hDevNames); + if(lpDev == NULL) + return NULL; + + return (LPCTSTR)lpDev + lpDev->wOutputOffset; + } + + HDC GetPrinterDC() const // return HDC (caller must delete) + { + ATLASSERT((m_pd.Flags & PD_RETURNDC) != 0); + return m_pd.hDC; + } + + // This helper creates a DC based on the DEVNAMES and DEVMODE structures. + // This DC is returned, but also stored in m_pd.hDC as though it had been + // returned by CommDlg. It is assumed that any previously obtained DC + // has been/will be deleted by the user. This may be + // used without ever invoking the print/print setup dialogs. + HDC CreatePrinterDC() + { + m_pd.hDC = _AtlCreateDC(m_pd.hDevNames, m_pd.hDevMode); + return m_pd.hDC; + } + +// Implementation + PRINTDLG m_pdActual; // the Print/Print Setup need to share this + + // The following handle the case of print setup... from the print dialog + CPrintDialogImpl(PRINTDLG& pdInit) : m_pd(pdInit) + { } + + BEGIN_MSG_MAP(CPrintDialogImpl) +#ifdef psh1 + COMMAND_ID_HANDLER(psh1, OnPrintSetup) // print setup button when print is displayed +#else // !psh1 + COMMAND_ID_HANDLER(0x0400, OnPrintSetup) // value from dlgs.h +#endif // !psh1 + END_MSG_MAP() + + LRESULT OnPrintSetup(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& /*bHandled*/) + { + T dlgSetup(m_pd); + ModuleHelper::AddCreateWndData(&dlgSetup.m_thunk.cd, (CCommonDialogImplBase*)&dlgSetup); + return DefWindowProc(WM_COMMAND, MAKEWPARAM(wID, wNotifyCode), (LPARAM)hWndCtl); + } +}; + +class CPrintDialog : public CPrintDialogImpl +{ +public: + CPrintDialog(BOOL bPrintSetupOnly = FALSE, + DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_NOSELECTION, + HWND hWndParent = NULL) + : CPrintDialogImpl(bPrintSetupOnly, dwFlags, hWndParent) + { } + + CPrintDialog(PRINTDLG& pdInit) : CPrintDialogImpl(pdInit) + { } +}; + +#endif // _WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CPrintDialogExImpl - new print dialog for Windows 2000 + +#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) + +}; // namespace WTL + +#include + +extern "C" const __declspec(selectany) IID IID_IPrintDialogCallback = {0x5852a2c3, 0x6530, 0x11d1, {0xb6, 0xa3, 0x0, 0x0, 0xf8, 0x75, 0x7b, 0xf9}}; +extern "C" const __declspec(selectany) IID IID_IPrintDialogServices = {0x509aaeda, 0x5639, 0x11d1, {0xb6, 0xa1, 0x0, 0x0, 0xf8, 0x75, 0x7b, 0xf9}}; + +namespace WTL +{ + +template +class ATL_NO_VTABLE CPrintDialogExImpl : + public ATL::CWindow, + public ATL::CMessageMap, + public IPrintDialogCallback, + public ATL::IObjectWithSiteImpl< T > +{ +public: + PRINTDLGEX m_pdex; + +// Constructor + CPrintDialogExImpl(DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_NOSELECTION | PD_NOCURRENTPAGE, + HWND hWndParent = NULL) + { + memset(&m_pdex, 0, sizeof(m_pdex)); + + m_pdex.lStructSize = sizeof(PRINTDLGEX); + m_pdex.hwndOwner = hWndParent; + m_pdex.Flags = dwFlags; + m_pdex.nStartPage = START_PAGE_GENERAL; + // callback object will be set in DoModal + + m_pdex.Flags &= ~PD_RETURNIC; // do not support information context + } + +// Operations + HRESULT DoModal(HWND hWndParent = ::GetActiveWindow()) + { + ATLASSERT(m_hWnd == NULL); + ATLASSERT((m_pdex.Flags & PD_RETURNDEFAULT) == 0); // use GetDefaults for this + + if(m_pdex.hwndOwner == NULL) // set only if not specified before + m_pdex.hwndOwner = hWndParent; + + T* pT = static_cast(this); + m_pdex.lpCallback = (IUnknown*)(IPrintDialogCallback*)pT; + + HRESULT hResult = ::PrintDlgEx(&m_pdex); + + m_hWnd = NULL; + + return hResult; + } + + BOOL EndDialog(INT_PTR /*nRetCode*/ = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + SendMessage(WM_COMMAND, MAKEWPARAM(IDABORT, 0)); + return TRUE; + } + + // GetDefaults will not display a dialog but will get device defaults + HRESULT GetDefaults() + { + m_pdex.Flags |= PD_RETURNDEFAULT; + ATLASSERT(m_pdex.hDevMode == NULL); // must be NULL + ATLASSERT(m_pdex.hDevNames == NULL); // must be NULL + + return ::PrintDlgEx(&m_pdex); + } + + // Helpers for parsing information after successful return num. copies requested + int GetCopies() const + { + if((m_pdex.Flags & PD_USEDEVMODECOPIES) != 0) + { + LPDEVMODE lpDevMode = GetDevMode(); + return (lpDevMode != NULL) ? lpDevMode->dmCopies : -1; + } + + return m_pdex.nCopies; + } + + BOOL PrintCollate() const // TRUE if collate checked + { + return ((m_pdex.Flags & PD_COLLATE) != 0) ? TRUE : FALSE; + } + + BOOL PrintSelection() const // TRUE if printing selection + { + return ((m_pdex.Flags & PD_SELECTION) != 0) ? TRUE : FALSE; + } + + BOOL PrintAll() const // TRUE if printing all pages + { + return (!PrintRange() && !PrintSelection()) ? TRUE : FALSE; + } + + BOOL PrintRange() const // TRUE if printing page range + { + return ((m_pdex.Flags & PD_PAGENUMS) != 0) ? TRUE : FALSE; + } + + BOOL PrintToFile() const // TRUE if printing to a file + { + return ((m_pdex.Flags & PD_PRINTTOFILE) != 0) ? TRUE : FALSE; + } + + LPDEVMODE GetDevMode() const // return DEVMODE + { + if(m_pdex.hDevMode == NULL) + return NULL; + + return (LPDEVMODE)::GlobalLock(m_pdex.hDevMode); + } + + LPCTSTR GetDriverName() const // return driver name + { + if(m_pdex.hDevNames == NULL) + return NULL; + + LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pdex.hDevNames); + if(lpDev == NULL) + return NULL; + + return (LPCTSTR)lpDev + lpDev->wDriverOffset; + } + + LPCTSTR GetDeviceName() const // return device name + { + if(m_pdex.hDevNames == NULL) + return NULL; + + LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pdex.hDevNames); + if(lpDev == NULL) + return NULL; + + return (LPCTSTR)lpDev + lpDev->wDeviceOffset; + } + + LPCTSTR GetPortName() const // return output port name + { + if(m_pdex.hDevNames == NULL) + return NULL; + + LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pdex.hDevNames); + if(lpDev == NULL) + return NULL; + + return (LPCTSTR)lpDev + lpDev->wOutputOffset; + } + + HDC GetPrinterDC() const // return HDC (caller must delete) + { + ATLASSERT((m_pdex.Flags & PD_RETURNDC) != 0); + return m_pdex.hDC; + } + + // This helper creates a DC based on the DEVNAMES and DEVMODE structures. + // This DC is returned, but also stored in m_pdex.hDC as though it had been + // returned by CommDlg. It is assumed that any previously obtained DC + // has been/will be deleted by the user. This may be + // used without ever invoking the print/print setup dialogs. + HDC CreatePrinterDC() + { + m_pdex.hDC = _AtlCreateDC(m_pdex.hDevNames, m_pdex.hDevMode); + return m_pdex.hDC; + } + +// Implementation - interfaces + +// IUnknown + STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject) + { + if(ppvObject == NULL) + return E_POINTER; + + T* pT = static_cast(this); + if(IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IPrintDialogCallback)) + { + *ppvObject = (IPrintDialogCallback*)pT; + // AddRef() not needed + return S_OK; + } + else if(IsEqualGUID(riid, IID_IObjectWithSite)) + { + *ppvObject = (IObjectWithSite*)pT; + // AddRef() not needed + return S_OK; + } + + return E_NOINTERFACE; + } + + virtual ULONG STDMETHODCALLTYPE AddRef() + { + return 1; + } + + virtual ULONG STDMETHODCALLTYPE Release() + { + return 1; + } + +// IPrintDialogCallback + STDMETHOD(InitDone)() + { + return S_FALSE; + } + + STDMETHOD(SelectionChange)() + { + return S_FALSE; + } + + STDMETHOD(HandleMessage)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* plResult) + { + // set up m_hWnd the first time + if(m_hWnd == NULL) + Attach(hWnd); + + // call message map + HRESULT hRet = ProcessWindowMessage(hWnd, uMsg, wParam, lParam, *plResult, 0) ? S_OK : S_FALSE; + if(hRet == S_OK && uMsg == WM_NOTIFY) // return in DWLP_MSGRESULT + ::SetWindowLongPtr(GetParent(), DWLP_MSGRESULT, (LONG_PTR)*plResult); + + if(uMsg == WM_INITDIALOG && hRet == S_OK && (BOOL)*plResult != FALSE) + hRet = S_FALSE; + + return hRet; + } +}; + +class CPrintDialogEx : public CPrintDialogExImpl +{ +public: + CPrintDialogEx( + DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_NOSELECTION | PD_NOCURRENTPAGE, + HWND hWndParent = NULL) + : CPrintDialogExImpl(dwFlags, hWndParent) + { } + + DECLARE_EMPTY_MSG_MAP() +}; + +#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) + + +/////////////////////////////////////////////////////////////////////////////// +// CPageSetupDialogImpl - Page Setup dialog + +#ifndef _WIN32_WCE + +template +class ATL_NO_VTABLE CPageSetupDialogImpl : public CCommonDialogImplBase +{ +public: + PAGESETUPDLG m_psd; + ATL::CWndProcThunk m_thunkPaint; + +// Constructors + CPageSetupDialogImpl(DWORD dwFlags = PSD_MARGINS | PSD_INWININIINTLMEASURE, HWND hWndParent = NULL) + { + memset(&m_psd, 0, sizeof(m_psd)); + + m_psd.lStructSize = sizeof(m_psd); + m_psd.hwndOwner = hWndParent; + m_psd.Flags = (dwFlags | PSD_ENABLEPAGESETUPHOOK | PSD_ENABLEPAGEPAINTHOOK); + m_psd.lpfnPageSetupHook = (LPPAGESETUPHOOK)T::HookProc; + m_thunkPaint.Init((WNDPROC)T::PaintHookProc, this); +#if (_ATL_VER >= 0x0700) + m_psd.lpfnPagePaintHook = (LPPAGEPAINTHOOK)m_thunkPaint.GetWNDPROC(); +#else + m_psd.lpfnPagePaintHook = (LPPAGEPAINTHOOK)&(m_thunkPaint.thunk); +#endif + } + + DECLARE_EMPTY_MSG_MAP() + +// Attributes + LPDEVMODE GetDevMode() const // return DEVMODE + { + if(m_psd.hDevMode == NULL) + return NULL; + + return (LPDEVMODE)::GlobalLock(m_psd.hDevMode); + } + + LPCTSTR GetDriverName() const // return driver name + { + if(m_psd.hDevNames == NULL) + return NULL; + + LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_psd.hDevNames); + return (LPCTSTR)lpDev + lpDev->wDriverOffset; + } + + LPCTSTR GetDeviceName() const // return device name + { + if(m_psd.hDevNames == NULL) + return NULL; + + LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_psd.hDevNames); + return (LPCTSTR)lpDev + lpDev->wDeviceOffset; + } + + LPCTSTR GetPortName() const // return output port name + { + if(m_psd.hDevNames == NULL) + return NULL; + + LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_psd.hDevNames); + return (LPCTSTR)lpDev + lpDev->wOutputOffset; + } + + HDC CreatePrinterDC() + { + return _AtlCreateDC(m_psd.hDevNames, m_psd.hDevMode); + } + + SIZE GetPaperSize() const + { + SIZE size; + size.cx = m_psd.ptPaperSize.x; + size.cy = m_psd.ptPaperSize.y; + return size; + } + + void GetMargins(LPRECT lpRectMargins, LPRECT lpRectMinMargins) const + { + if(lpRectMargins != NULL) + *lpRectMargins = m_psd.rtMargin; + if(lpRectMinMargins != NULL) + *lpRectMinMargins = m_psd.rtMinMargin; + } + +// Operations + INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) + { + ATLASSERT((m_psd.Flags & PSD_ENABLEPAGESETUPHOOK) != 0); + ATLASSERT((m_psd.Flags & PSD_ENABLEPAGEPAINTHOOK) != 0); + ATLASSERT(m_psd.lpfnPageSetupHook != NULL); // can still be a user hook + ATLASSERT(m_psd.lpfnPagePaintHook != NULL); // can still be a user hook + + if(m_psd.hwndOwner == NULL) // set only if not specified before + m_psd.hwndOwner = hWndParent; + + ATLASSERT(m_hWnd == NULL); + ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this); + + BOOL bRet = ::PageSetupDlg(&m_psd); + + m_hWnd = NULL; + + return bRet ? IDOK : IDCANCEL; + } + +// Implementation + static UINT_PTR CALLBACK PaintHookProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + T* pT = (T*)hWnd; + UINT_PTR uRet = 0; + switch(uMsg) + { + case WM_PSD_PAGESETUPDLG: + uRet = pT->PreDrawPage(LOWORD(wParam), HIWORD(wParam), (LPPAGESETUPDLG)lParam); + break; + case WM_PSD_FULLPAGERECT: + case WM_PSD_MINMARGINRECT: + case WM_PSD_MARGINRECT: + case WM_PSD_GREEKTEXTRECT: + case WM_PSD_ENVSTAMPRECT: + case WM_PSD_YAFULLPAGERECT: + uRet = pT->OnDrawPage(uMsg, (HDC)wParam, (LPRECT)lParam); + break; + default: + ATLTRACE2(atlTraceUI, 0, _T("CPageSetupDialogImpl::PaintHookProc - unknown message received\n")); + break; + } + return uRet; + } + +// Overridables + UINT_PTR PreDrawPage(WORD /*wPaper*/, WORD /*wFlags*/, LPPAGESETUPDLG /*pPSD*/) + { + // return 1 to prevent any more drawing + return 0; + } + + UINT_PTR OnDrawPage(UINT /*uMsg*/, HDC /*hDC*/, LPRECT /*lpRect*/) + { + return 0; // do the default + } +}; + +class CPageSetupDialog : public CPageSetupDialogImpl +{ +public: + CPageSetupDialog(DWORD dwFlags = PSD_MARGINS | PSD_INWININIINTLMEASURE, HWND hWndParent = NULL) + : CPageSetupDialogImpl(dwFlags, hWndParent) + { } + + // override PaintHookProc and references to handlers + static UINT_PTR CALLBACK PaintHookProc(HWND, UINT, WPARAM, LPARAM) + { + return 0; + } +}; + +#endif // _WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CFindReplaceDialogImpl - Find/FindReplace modeless dialogs + +#ifndef _WIN32_WCE + +template +class ATL_NO_VTABLE CFindReplaceDialogImpl : public CCommonDialogImplBase +{ +public: + enum { _cchFindReplaceBuffer = 128 }; + + FINDREPLACE m_fr; + TCHAR m_szFindWhat[_cchFindReplaceBuffer]; + TCHAR m_szReplaceWith[_cchFindReplaceBuffer]; + +// Constructors + CFindReplaceDialogImpl() + { + memset(&m_fr, 0, sizeof(m_fr)); + m_szFindWhat[0] = _T('\0'); + m_szReplaceWith[0] = _T('\0'); + + m_fr.lStructSize = sizeof(m_fr); + m_fr.Flags = FR_ENABLEHOOK; + m_fr.lpfnHook = (LPFRHOOKPROC)T::HookProc; + m_fr.lpstrFindWhat = (LPTSTR)m_szFindWhat; + m_fr.wFindWhatLen = _cchFindReplaceBuffer; + m_fr.lpstrReplaceWith = (LPTSTR)m_szReplaceWith; + m_fr.wReplaceWithLen = _cchFindReplaceBuffer; + } + + // Note: You must allocate the object on the heap. + // If you do not, you must override OnFinalMessage() + virtual void OnFinalMessage(HWND /*hWnd*/) + { + delete this; + } + + HWND Create(BOOL bFindDialogOnly, // TRUE for Find, FALSE for FindReplace + LPCTSTR lpszFindWhat, + LPCTSTR lpszReplaceWith = NULL, + DWORD dwFlags = FR_DOWN, + HWND hWndParent = NULL) + { + ATLASSERT((m_fr.Flags & FR_ENABLEHOOK) != 0); + ATLASSERT(m_fr.lpfnHook != NULL); + + m_fr.Flags |= dwFlags; + + if(hWndParent == NULL) + m_fr.hwndOwner = ::GetActiveWindow(); + else + m_fr.hwndOwner = hWndParent; + ATLASSERT(m_fr.hwndOwner != NULL); // must have an owner for modeless dialog + + if(lpszFindWhat != NULL) + SecureHelper::strncpy_x(m_szFindWhat, _countof(m_szFindWhat), lpszFindWhat, _TRUNCATE); + + if(lpszReplaceWith != NULL) + SecureHelper::strncpy_x(m_szReplaceWith, _countof(m_szReplaceWith), lpszReplaceWith, _TRUNCATE); + + ATLASSERT(m_hWnd == NULL); + ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this); + + HWND hWnd = NULL; + if(bFindDialogOnly) + hWnd = ::FindText(&m_fr); + else + hWnd = ::ReplaceText(&m_fr); + + ATLASSERT(m_hWnd == hWnd); + return hWnd; + } + + static const UINT GetFindReplaceMsg() + { + static const UINT nMsgFindReplace = ::RegisterWindowMessage(FINDMSGSTRING); + return nMsgFindReplace; + } + // call while handling FINDMSGSTRING registered message + // to retreive the object + static T* PASCAL GetNotifier(LPARAM lParam) + { + ATLASSERT(lParam != NULL); + T* pDlg = (T*)(lParam - offsetof(T, m_fr)); + return pDlg; + } + +// Operations + // Helpers for parsing information after successful return + LPCTSTR GetFindString() const // get find string + { + return (LPCTSTR)m_fr.lpstrFindWhat; + } + + LPCTSTR GetReplaceString() const // get replacement string + { + return (LPCTSTR)m_fr.lpstrReplaceWith; + } + + BOOL SearchDown() const // TRUE if search down, FALSE is up + { + return ((m_fr.Flags & FR_DOWN) != 0) ? TRUE : FALSE; + } + + BOOL FindNext() const // TRUE if command is find next + { + return ((m_fr.Flags & FR_FINDNEXT) != 0) ? TRUE : FALSE; + } + + BOOL MatchCase() const // TRUE if matching case + { + return ((m_fr.Flags & FR_MATCHCASE) != 0) ? TRUE : FALSE; + } + + BOOL MatchWholeWord() const // TRUE if matching whole words only + { + return ((m_fr.Flags & FR_WHOLEWORD) != 0) ? TRUE : FALSE; + } + + BOOL ReplaceCurrent() const // TRUE if replacing current string + { + return ((m_fr. Flags & FR_REPLACE) != 0) ? TRUE : FALSE; + } + + BOOL ReplaceAll() const // TRUE if replacing all occurrences + { + return ((m_fr.Flags & FR_REPLACEALL) != 0) ? TRUE : FALSE; + } + + BOOL IsTerminating() const // TRUE if terminating dialog + { + return ((m_fr.Flags & FR_DIALOGTERM) != 0) ? TRUE : FALSE ; + } +}; + +class CFindReplaceDialog : public CFindReplaceDialogImpl +{ +public: + DECLARE_EMPTY_MSG_MAP() +}; + +#endif // !_WIN32_WCE + + +///////////////////////////////////////////////////////////////////////// +// CDialogBaseUnits - Dialog Units helper +// + +class CDialogBaseUnits +{ +public: + SIZE m_sizeUnits; + +// Constructors + CDialogBaseUnits() + { + // The base units of the out-dated System Font + LONG nDlgBaseUnits = ::GetDialogBaseUnits(); + m_sizeUnits.cx = LOWORD(nDlgBaseUnits); + m_sizeUnits.cy = HIWORD(nDlgBaseUnits); + } + + CDialogBaseUnits(HWND hWnd) + { + if(!InitDialogBaseUnits(hWnd)) { + LONG nDlgBaseUnits = ::GetDialogBaseUnits(); + m_sizeUnits.cx = LOWORD(nDlgBaseUnits); + m_sizeUnits.cy = HIWORD(nDlgBaseUnits); + } + } + + CDialogBaseUnits(HFONT hFont, HWND hWnd = NULL) + { + if(!InitDialogBaseUnits(hFont, hWnd)) { + LONG nDlgBaseUnits = ::GetDialogBaseUnits(); + m_sizeUnits.cx = LOWORD(nDlgBaseUnits); + m_sizeUnits.cy = HIWORD(nDlgBaseUnits); + } + } + + CDialogBaseUnits(LOGFONT lf, HWND hWnd = NULL) + { + if(!InitDialogBaseUnits(lf, hWnd)) { + LONG nDlgBaseUnits = ::GetDialogBaseUnits(); + m_sizeUnits.cx = LOWORD(nDlgBaseUnits); + m_sizeUnits.cy = HIWORD(nDlgBaseUnits); + } + } + +// Operations + BOOL InitDialogBaseUnits(HWND hWnd) + { + ATLASSERT(::IsWindow(hWnd)); + RECT rc = { 0, 0, 4, 8 }; + if(!::MapDialogRect(hWnd, &rc)) return FALSE; + m_sizeUnits.cx = rc.right; + m_sizeUnits.cy = rc.bottom; + return TRUE; + } + + BOOL InitDialogBaseUnits(LOGFONT lf, HWND hWnd = NULL) + { + CFont font; + font.CreateFontIndirect(&lf); + if(font.IsNull()) return FALSE; + return InitDialogBaseUnits(font, hWnd); + } + + BOOL InitDialogBaseUnits(HFONT hFont, HWND hWnd = NULL) + { + ATLASSERT(hFont != NULL); + CWindowDC dc = hWnd; + TEXTMETRIC tmText = { 0 }; + SIZE sizeText = { 0 }; + HFONT hFontOld = dc.SelectFont(hFont); + dc.GetTextMetrics(&tmText); + m_sizeUnits.cy = tmText.tmHeight + tmText.tmExternalLeading; + dc.GetTextExtent(_T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), 52, &sizeText); + m_sizeUnits.cx = (sizeText.cx + 26) / 52; + dc.SelectFont(hFontOld); + return TRUE; + } + + SIZE GetDialogBaseUnits() const + { + return m_sizeUnits; + } + + INT MapDialogPixelsX(INT x) const + { + return ::MulDiv(x, 4, m_sizeUnits.cx); // Pixels X to DLU + } + + INT MapDialogPixelsY(INT y) const + { + return ::MulDiv(y, 8, m_sizeUnits.cy); // Pixels Y to DLU + } + + POINT MapDialogPixels(POINT pt) const + { + POINT out = { MapDialogPixelsX(pt.x), MapDialogPixelsY(pt.y) }; + return out; + } + + SIZE MapDialogPixels(SIZE input) const + { + SIZE out = { MapDialogPixelsX(input.cx), MapDialogPixelsY(input.cy) }; + return out; + } + + RECT MapDialogPixels(RECT input) const + { + RECT out = { MapDialogPixelsX(input.left), MapDialogPixelsY(input.top), MapDialogPixelsX(input.right), MapDialogPixelsY(input.bottom) }; + return out; + } + + INT MapDialogUnitsX(INT x) const + { + return ::MulDiv(x, m_sizeUnits.cx, 4); // DLU to Pixels X + } + + INT MapDialogUnitsY(INT y) const + { + return ::MulDiv(y, m_sizeUnits.cx, 8); // DLU to Pixels Y + } + + POINT MapDialogUnits(POINT pt) const + { + POINT out = { MapDialogUnitsX(pt.x), MapDialogUnitsY(pt.y) }; + return out; + } + + SIZE MapDialogUnits(SIZE input) const + { + SIZE out = { MapDialogUnitsX(input.cx), MapDialogUnitsY(input.cy) }; + return out; + } + + RECT MapDialogUnits(RECT input) const + { + RECT out = { MapDialogUnitsX(input.left), MapDialogUnitsY(input.top), MapDialogUnitsX(input.right), MapDialogUnitsY(input.bottom) }; + return out; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CMemDlgTemplate - in-memory dialog template - DLGTEMPLATE or DLGTEMPLATEEX + +#if (_ATL_VER >= 0x800) + typedef ATL::_DialogSplitHelper::DLGTEMPLATEEX DLGTEMPLATEEX; + typedef ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX DLGITEMTEMPLATEEX; +#else // (_ATL_VER >= 0x800) + typedef ATL::_DialogSizeHelper::_ATL_DLGTEMPLATEEX DLGTEMPLATEEX; + #pragma pack(push, 4) + struct DLGITEMTEMPLATEEX + { + DWORD helpID; + DWORD exStyle; + DWORD style; + short x; + short y; + short cx; + short cy; + DWORD id; + }; + #pragma pack(pop) +#endif // (_ATL_VER >= 0x800) + + +class CMemDlgTemplate +{ +public: + enum StdCtrlType + { + CTRL_BUTTON = 0x0080, + CTRL_EDIT = 0x0081, + CTRL_STATIC = 0x0082, + CTRL_LISTBOX = 0x0083, + CTRL_SCROLLBAR = 0x0084, + CTRL_COMBOBOX = 0x0085 + }; + + CMemDlgTemplate() : m_hData(NULL), m_pData(NULL), m_pPtr(NULL), m_cAllocated(0) + { } + + ~CMemDlgTemplate() + { + Reset(); + } + + bool IsValid() const + { + return (m_pData != NULL); + } + + bool IsTemplateEx() const + { + return (IsValid() && ((DLGTEMPLATEEX*)m_pData)->signature == 0xFFFF); + } + + LPDLGTEMPLATE GetTemplatePtr() + { + return reinterpret_cast(m_pData); + } + + DLGTEMPLATEEX* GetTemplateExPtr() + { + return reinterpret_cast(m_pData); + } + + void Reset() + { + if (IsValid()) { +#ifndef UNDER_CE + ::GlobalUnlock(m_pData); +#endif + ATLVERIFY(::GlobalFree(m_hData) == NULL); + } + + m_hData = NULL; + m_pData = NULL; + m_pPtr = NULL; + m_cAllocated = 0; + } + + void Create(bool bDlgEx, LPCTSTR lpszCaption, RECT rc, DWORD dwStyle = 0, DWORD dwExStyle = 0, + LPCTSTR lpstrFontName = NULL, WORD wFontSize = 0, WORD wWeight = 0, BYTE bItalic = 0, BYTE bCharset = 0, DWORD dwHelpID = 0, + ATL::_U_STRINGorID ClassName = 0U, ATL::_U_STRINGorID Menu = 0U) + { + Create(bDlgEx, lpszCaption, (short) rc.left, (short) rc.top, (short) (rc.right - rc.left), (short) (rc.bottom - rc.top), dwStyle, dwExStyle, + lpstrFontName, wFontSize, wWeight, bItalic, bCharset, dwHelpID, ClassName.m_lpstr, Menu.m_lpstr); + } + + void Create(bool bDlgEx, LPCTSTR lpszCaption, short nX, short nY, short nWidth, short nHeight, DWORD dwStyle = 0, DWORD dwExStyle = 0, + LPCTSTR lpstrFontName = NULL, WORD wFontSize = 0, WORD wWeight = 0, BYTE bItalic = 0, BYTE bCharset = 0, DWORD dwHelpID = 0, + ATL::_U_STRINGorID ClassName = 0U, ATL::_U_STRINGorID Menu = 0U) + { + // Should have DS_SETFONT style to set the dialog font name and size + if (lpstrFontName != NULL) + { + dwStyle |= DS_SETFONT; + } + else + { + dwStyle &= ~DS_SETFONT; + } + + if (bDlgEx) + { + DLGTEMPLATEEX dlg = {1, 0xFFFF, dwHelpID, dwExStyle, dwStyle, 0, nX, nY, nWidth, nHeight}; + AddData(&dlg, sizeof(dlg)); + } + else + { + DLGTEMPLATE dlg = {dwStyle, dwExStyle, 0, nX, nY, nWidth, nHeight}; + AddData(&dlg, sizeof(dlg)); + } + +#ifndef _WIN32_WCE + if (Menu.m_lpstr == NULL) + { + WORD menuData = 0; + AddData(&menuData, sizeof(WORD)); + } + else if (IS_INTRESOURCE(Menu.m_lpstr)) + { + WORD menuData[] = {0xFFFF, (WORD)Menu.m_lpstr}; + AddData(menuData, sizeof(menuData)); + } + else + { + AddString(Menu.m_lpstr); + } +#else // _WIN32_WCE + // Windows CE doesn't support the addition of menus to a dialog box + ATLASSERT(Menu.m_lpstr == NULL); + Menu.m_lpstr; // avoid level 4 warning + WORD menuData = 0; + AddData(&menuData, sizeof(WORD)); +#endif // _WIN32_WCE + + if (ClassName.m_lpstr == NULL) + { + WORD classData = 0; + AddData(&classData, sizeof(WORD)); + } + else if (IS_INTRESOURCE(ClassName.m_lpstr)) + { + WORD classData[] = {0xFFFF, (WORD)ClassName.m_lpstr}; + AddData(classData, sizeof(classData)); + } + else + { + AddString(ClassName.m_lpstr); + } + + // Set dialog caption + AddString(lpszCaption); + + if (lpstrFontName != NULL) + { + AddData(&wFontSize, sizeof(wFontSize)); + + if (bDlgEx) + { + AddData(&wWeight, sizeof(wWeight)); + AddData(&bItalic, sizeof(bItalic)); + AddData(&bCharset, sizeof(bCharset)); + } + + AddString(lpstrFontName); + } + } + + void AddControl(ATL::_U_STRINGorID ClassName, WORD wId, RECT rc, DWORD dwStyle, DWORD dwExStyle, + ATL::_U_STRINGorID Text, const WORD* pCreationData = NULL, WORD nCreationData = 0, DWORD dwHelpID = 0) + { + AddControl(ClassName.m_lpstr, wId, (short) rc.left, (short) rc.top, (short) (rc.right - rc.left), (short) (rc.bottom - rc.top), dwStyle, dwExStyle, + Text.m_lpstr, pCreationData, nCreationData, dwHelpID); + } + + void AddControl(ATL::_U_STRINGorID ClassName, WORD wId, short nX, short nY, short nWidth, short nHeight, DWORD dwStyle, DWORD dwExStyle, + ATL::_U_STRINGorID Text, const WORD* pCreationData = NULL, WORD nCreationData = 0, DWORD dwHelpID = 0) + { + ATLASSERT(IsValid()); + + // DWORD align data + m_pPtr = (LPBYTE)(DWORD_PTR)((DWORD)(DWORD_PTR)(m_pPtr + 3) & (~3)); + + if (IsTemplateEx()) + { + DLGTEMPLATEEX* dlg = (DLGTEMPLATEEX*)m_pData; + dlg->cDlgItems++; + + DLGITEMTEMPLATEEX item = {dwHelpID, ATL::CControlWinTraits::GetWndExStyle(0) | dwExStyle, ATL::CControlWinTraits::GetWndStyle(0) | dwStyle, nX, nY, nWidth, nHeight, wId}; + AddData(&item, sizeof(item)); + } + else + { + LPDLGTEMPLATE dlg = (LPDLGTEMPLATE)m_pData; + dlg->cdit++; + + DLGITEMTEMPLATE item = {ATL::CControlWinTraits::GetWndStyle(0) | dwStyle, ATL::CControlWinTraits::GetWndExStyle(0) | dwExStyle, nX, nY, nWidth, nHeight, wId}; + AddData(&item, sizeof(item)); + } + + ATLASSERT(ClassName.m_lpstr != NULL); + if (IS_INTRESOURCE(ClassName.m_lpstr)) + { + WORD wData[] = {0xFFFF, (WORD)ClassName.m_lpstr}; + AddData(wData, sizeof(wData)); + } + else + { + AddString(ClassName.m_lpstr); + } + + if (Text.m_lpstr == NULL) + { + WORD classData = 0; + AddData(&classData, sizeof(WORD)); + } + else if (IS_INTRESOURCE(Text.m_lpstr)) + { + WORD wData[] = {0xFFFF, (WORD)Text.m_lpstr}; + AddData(wData, sizeof(wData)); + } + else + { + AddString(Text.m_lpstr); + } + + AddData(&nCreationData, sizeof(nCreationData)); + + if ((nCreationData != 0)) + { + ATLASSERT(pCreationData != NULL); + AddData(pCreationData, nCreationData * sizeof(WORD)); + } + } + + void AddStdControl(StdCtrlType CtrlType, WORD wId, short nX, short nY, short nWidth, short nHeight, + DWORD dwStyle, DWORD dwExStyle, ATL::_U_STRINGorID Text, const WORD* pCreationData = NULL, WORD nCreationData = 0, DWORD dwHelpID = 0) + { + AddControl(CtrlType, wId, nX, nY, nWidth, nHeight, dwStyle, dwExStyle, Text, pCreationData, nCreationData, dwHelpID); + } + + void AddData(LPCVOID pData, size_t nData) + { + ATLASSERT(pData != NULL); + + const SIZE_T ALLOCATION_INCREMENT = 1024; + + if (m_pData == NULL) + { + m_cAllocated = ((nData / ALLOCATION_INCREMENT) + 1) * ALLOCATION_INCREMENT; + m_hData = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, m_cAllocated); + ATLASSERT(m_hData != NULL); +#ifndef UNDER_CE + m_pPtr = m_pData = static_cast(::GlobalLock(m_hData)); +#else + m_pPtr = m_pData = static_cast(m_hData); +#endif + ATLASSERT(m_pData != NULL); + } + else if (((m_pPtr - m_pData) + nData) > m_cAllocated) + { + SIZE_T ptrPos = (m_pPtr - m_pData); + m_cAllocated += ((nData / ALLOCATION_INCREMENT) + 1) * ALLOCATION_INCREMENT; +#ifndef UNDER_CE + ::GlobalUnlock(m_pData); +#endif + m_hData = ::GlobalReAlloc(m_hData, m_cAllocated, GMEM_MOVEABLE | GMEM_ZEROINIT); + ATLASSERT(m_hData != NULL); +#ifndef UNDER_CE + m_pData = static_cast(::GlobalLock(m_hData)); +#else + m_pData = static_cast(m_hData); +#endif + ATLASSERT(m_pData != NULL); + m_pPtr = m_pData + ptrPos; + } + + SecureHelper::memcpy_x(m_pPtr, m_cAllocated - (m_pPtr - m_pData), pData, nData); + + m_pPtr += nData; + } + + void AddString(LPCTSTR lpszStr) + { + if (lpszStr == NULL) + { + WCHAR szEmpty = 0; + AddData(&szEmpty, sizeof(szEmpty)); + } + else + { + USES_CONVERSION; + LPCWSTR lpstr = T2CW(lpszStr); + int nSize = lstrlenW(lpstr) + 1; + AddData(lpstr, nSize * sizeof(WCHAR)); + } + } + + HANDLE m_hData; + LPBYTE m_pData; + LPBYTE m_pPtr; + SIZE_T m_cAllocated; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// Dialog and control macros for indirect dialogs + +// for DLGTEMPLATE +#define BEGIN_DIALOG(x, y, width, height) \ + void DoInitTemplate() \ + { \ + bool bExTemplate = false; \ + short nX = x, nY = y, nWidth = width, nHeight = height; \ + LPCTSTR szCaption = NULL; \ + DWORD dwStyle = WS_POPUP | WS_BORDER | WS_SYSMENU; \ + DWORD dwExStyle = 0; \ + LPCTSTR szFontName = NULL; \ + WORD wFontSize = 0; \ + WORD wWeight = 0; \ + BYTE bItalic = 0; \ + BYTE bCharset = 0; \ + DWORD dwHelpID = 0; \ + ATL::_U_STRINGorID Menu = 0U; \ + ATL::_U_STRINGorID ClassName = 0U; + +// for DLGTEMPLATEEX +#define BEGIN_DIALOG_EX(x, y, width, height, helpID) \ + void DoInitTemplate() \ + { \ + bool bExTemplate = true; \ + short nX = x, nY = y, nWidth = width, nHeight = height; \ + LPCTSTR szCaption = NULL; \ + DWORD dwStyle = WS_POPUP | WS_BORDER | WS_SYSMENU; \ + DWORD dwExStyle = 0; \ + LPCTSTR szFontName = NULL; \ + WORD wFontSize = 0; \ + WORD wWeight = 0; \ + BYTE bItalic = 0; \ + BYTE bCharset = 0; \ + DWORD dwHelpID = helpID; \ + ATL::_U_STRINGorID Menu = 0U; \ + ATL::_U_STRINGorID ClassName = 0U; + +#define END_DIALOG() \ + m_Template.Create(bExTemplate, szCaption, nX, nY, nWidth, nHeight, dwStyle, dwExStyle, szFontName, wFontSize, wWeight, bItalic, bCharset, dwHelpID, ClassName, Menu); \ + }; + +#define DIALOG_CAPTION(caption) \ + szCaption = caption; +#define DIALOG_STYLE(style) \ + dwStyle = style; +#define DIALOG_EXSTYLE(exStyle) \ + dwExStyle = exStyle; +#define DIALOG_FONT(pointSize, typeFace) \ + wFontSize = pointSize; \ + szFontName = typeFace; +#define DIALOG_FONT_EX(pointsize, typeface, weight, italic, charset) \ + ATLASSERT(bExTemplate); \ + wFontSize = pointsize; \ + szFontName = typeface; \ + wWeight = weight; \ + bItalic = italic; \ + bCharset = charset; +#define DIALOG_MENU(menuName) \ + Menu = menuName; +#define DIALOG_CLASS(className) \ + ClassName = className; + +#define BEGIN_CONTROLS_MAP() \ + void DoInitControls() \ + { + +#define END_CONTROLS_MAP() \ + }; + + +#define CONTROL_LTEXT(text, id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_LEFT | WS_GROUP, exStyle, text, NULL, 0); +#define CONTROL_CTEXT(text, id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_CENTER | WS_GROUP, exStyle, text, NULL, 0); +#define CONTROL_RTEXT(text, id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_RIGHT | WS_GROUP, exStyle, text, NULL, 0); +#define CONTROL_PUSHBUTTON(text, id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_PUSHBUTTON | WS_TABSTOP, exStyle, text, NULL, 0); +#define CONTROL_DEFPUSHBUTTON(text, id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_DEFPUSHBUTTON | WS_TABSTOP, exStyle, text, NULL, 0); +#ifndef _WIN32_WCE +#define CONTROL_PUSHBOX(text, id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_PUSHBOX | WS_TABSTOP, exStyle, text, NULL, 0); +#endif // !_WIN32_WCE +#define CONTROL_STATE3(text, id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_3STATE | WS_TABSTOP, exStyle, text, NULL, 0); +#define CONTROL_AUTO3STATE(text, id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_AUTO3STATE | WS_TABSTOP, exStyle, text, NULL, 0); +#define CONTROL_CHECKBOX(text, id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_CHECKBOX | WS_TABSTOP, exStyle, text, NULL, 0); +#define CONTROL_AUTOCHECKBOX(text, id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_AUTOCHECKBOX | WS_TABSTOP, exStyle, text, NULL, 0); +#define CONTROL_RADIOBUTTON(text, id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_RADIOBUTTON | WS_TABSTOP, exStyle, text, NULL, 0); +#define CONTROL_AUTORADIOBUTTON(text, id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_AUTORADIOBUTTON | WS_TABSTOP, exStyle, text, NULL, 0); +#define CONTROL_COMBOBOX(id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_COMBOBOX, (WORD)id, x, y, width, height, style | CBS_DROPDOWN | WS_TABSTOP, exStyle, (LPCTSTR)NULL, NULL, 0); +#define CONTROL_EDITTEXT(id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_EDIT, (WORD)id, x, y, width, height, style | ES_LEFT | WS_BORDER | WS_TABSTOP, exStyle, (LPCTSTR)NULL, NULL, 0); +#define CONTROL_GROUPBOX(text, id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_GROUPBOX, exStyle, text, NULL, 0); +#define CONTROL_LISTBOX(id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_LISTBOX, (WORD)id, x, y, width, height, style | LBS_NOTIFY | WS_BORDER, exStyle, (LPCTSTR)NULL, NULL, 0); +#define CONTROL_SCROLLBAR(id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_SCROLLBAR, (WORD)id, x, y, width, height, style | SBS_HORZ, exStyle, (LPCTSTR)NULL, NULL, 0); +#define CONTROL_ICON(text, id, x, y, width, height, style, exStyle) \ + m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_ICON, exStyle, text, NULL, 0); +#define CONTROL_CONTROL(text, id, className, style, x, y, width, height, exStyle) \ + m_Template.AddControl(className, (WORD)id, x, y, width, height, style, exStyle, text, NULL, 0); + + +/////////////////////////////////////////////////////////////////////////////// +// CIndirectDialogImpl - dialogs with template in memory + +template > +class ATL_NO_VTABLE CIndirectDialogImpl : public TBase +{ +public: + enum { IDD = 0 }; // no dialog template resource + + TDlgTemplate m_Template; + + void CreateTemplate() + { + T* pT = static_cast(this); + pT->DoInitTemplate(); + pT->DoInitControls(); + } + + INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow(), LPARAM dwInitParam = NULL) + { + T* pT = static_cast(this); + ATLASSERT(pT->m_hWnd == NULL); + + if (!m_Template.IsValid()) + CreateTemplate(); + +#if (_ATL_VER >= 0x0800) + // Allocate the thunk structure here, where we can fail gracefully. + BOOL result = m_thunk.Init(NULL, NULL); + if (result == FALSE) + { + SetLastError(ERROR_OUTOFMEMORY); + return -1; + } +#endif // (_ATL_VER >= 0x0800) + + ModuleHelper::AddCreateWndData(&m_thunk.cd, pT); + +#ifdef _DEBUG + m_bModal = true; +#endif // _DEBUG + + return ::DialogBoxIndirectParam(ModuleHelper::GetResourceInstance(), m_Template.GetTemplatePtr(), hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam); + } + + HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL) + { + T* pT = static_cast(this); + ATLASSERT(pT->m_hWnd == NULL); + + if (!m_Template.IsValid()) + CreateTemplate(); + +#if (_ATL_VER >= 0x0800) + // Allocate the thunk structure here, where we can fail gracefully. + BOOL result = m_thunk.Init(NULL, NULL); + if (result == FALSE) + { + SetLastError(ERROR_OUTOFMEMORY); + return NULL; + } +#endif // (_ATL_VER >= 0x0800) + + ModuleHelper::AddCreateWndData(&m_thunk.cd, pT); + +#ifdef _DEBUG + m_bModal = false; +#endif // _DEBUG + + HWND hWnd = ::CreateDialogIndirectParam(ModuleHelper::GetResourceInstance(), (LPCDLGTEMPLATE)m_Template.GetTemplatePtr(), hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam); + ATLASSERT(m_hWnd == hWnd); + + return hWnd; + } + + // for CComControl + HWND Create(HWND hWndParent, RECT&, LPARAM dwInitParam = NULL) + { + return Create(hWndParent, dwInitParam); + } + + void DoInitTemplate() + { + ATLASSERT(FALSE); // MUST be defined in derived class + } + + void DoInitControls() + { + ATLASSERT(FALSE); // MUST be defined in derived class + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// CPropertySheetWindow - client side for a property sheet + +class CPropertySheetWindow : public ATL::CWindow +{ +public: +// Constructors + CPropertySheetWindow(HWND hWnd = NULL) : ATL::CWindow(hWnd) + { } + + CPropertySheetWindow& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + +// Attributes + int GetPageCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + HWND hWndTabCtrl = GetTabControl(); + ATLASSERT(hWndTabCtrl != NULL); + return (int)::SendMessage(hWndTabCtrl, TCM_GETITEMCOUNT, 0, 0L); + } + + HWND GetActivePage() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HWND)::SendMessage(m_hWnd, PSM_GETCURRENTPAGEHWND, 0, 0L); + } + + int GetActiveIndex() const + { + ATLASSERT(::IsWindow(m_hWnd)); + HWND hWndTabCtrl = GetTabControl(); + ATLASSERT(hWndTabCtrl != NULL); + return (int)::SendMessage(hWndTabCtrl, TCM_GETCURSEL, 0, 0L); + } + + BOOL SetActivePage(int nPageIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, PSM_SETCURSEL, nPageIndex, 0L); + } + + BOOL SetActivePage(HPROPSHEETPAGE hPage) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hPage != NULL); + return (BOOL)::SendMessage(m_hWnd, PSM_SETCURSEL, 0, (LPARAM)hPage); + } + + BOOL SetActivePageByID(int nPageID) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, PSM_SETCURSELID, 0, nPageID); + } + + void SetTitle(LPCTSTR lpszText, UINT nStyle = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT((nStyle & ~PSH_PROPTITLE) == 0); // only PSH_PROPTITLE is valid + ATLASSERT(lpszText != NULL); + ::SendMessage(m_hWnd, PSM_SETTITLE, nStyle, (LPARAM)lpszText); + } + + HWND GetTabControl() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HWND)::SendMessage(m_hWnd, PSM_GETTABCONTROL, 0, 0L); + } + + void SetFinishText(LPCTSTR lpszText) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, PSM_SETFINISHTEXT, 0, (LPARAM)lpszText); + } + + void SetWizardButtons(DWORD dwFlags) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::PostMessage(m_hWnd, PSM_SETWIZBUTTONS, 0, dwFlags); + } + +// Operations + BOOL AddPage(HPROPSHEETPAGE hPage) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hPage != NULL); + return (BOOL)::SendMessage(m_hWnd, PSM_ADDPAGE, 0, (LPARAM)hPage); + } + + BOOL AddPage(LPCPROPSHEETPAGE pPage) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pPage != NULL); + HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage); + if(hPage == NULL) + return FALSE; + return (BOOL)::SendMessage(m_hWnd, PSM_ADDPAGE, 0, (LPARAM)hPage); + } + +#ifndef _WIN32_WCE + BOOL InsertPage(int nNewPageIndex, HPROPSHEETPAGE hPage) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hPage != NULL); + return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, nNewPageIndex, (LPARAM)hPage); + } + + BOOL InsertPage(int nNewPageIndex, LPCPROPSHEETPAGE pPage) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pPage != NULL); + HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage); + if(hPage == NULL) + return FALSE; + return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, nNewPageIndex, (LPARAM)hPage); + } + + BOOL InsertPage(HPROPSHEETPAGE hPageInsertAfter, HPROPSHEETPAGE hPage) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hPage != NULL); + return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, (WPARAM)hPageInsertAfter, (LPARAM)hPage); + } + + BOOL InsertPage(HPROPSHEETPAGE hPageInsertAfter, LPCPROPSHEETPAGE pPage) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pPage != NULL); + HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage); + if(hPage == NULL) + return FALSE; + return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, (WPARAM)hPageInsertAfter, (LPARAM)hPage); + } +#endif // !_WIN32_WCE + + void RemovePage(int nPageIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, PSM_REMOVEPAGE, nPageIndex, 0L); + } + + void RemovePage(HPROPSHEETPAGE hPage) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(hPage != NULL); + ::SendMessage(m_hWnd, PSM_REMOVEPAGE, 0, (LPARAM)hPage); + } + + BOOL PressButton(int nButton) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, PSM_PRESSBUTTON, nButton, 0L); + } + + BOOL Apply() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, PSM_APPLY, 0, 0L); + } + + void CancelToClose() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, PSM_CANCELTOCLOSE, 0, 0L); + } + + void SetModified(HWND hWndPage, BOOL bChanged = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(::IsWindow(hWndPage)); + UINT uMsg = bChanged ? PSM_CHANGED : PSM_UNCHANGED; + ::SendMessage(m_hWnd, uMsg, (WPARAM)hWndPage, 0L); + } + + LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + return ::SendMessage(m_hWnd, PSM_QUERYSIBLINGS, wParam, lParam); + } + + void RebootSystem() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, PSM_REBOOTSYSTEM, 0, 0L); + } + + void RestartWindows() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, PSM_RESTARTWINDOWS, 0, 0L); + } + + BOOL IsDialogMessage(LPMSG lpMsg) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, PSM_ISDIALOGMESSAGE, 0, (LPARAM)lpMsg); + } + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + int HwndToIndex(HWND hWnd) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PSM_HWNDTOINDEX, (WPARAM)hWnd, 0L); + } + + HWND IndexToHwnd(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HWND)::SendMessage(m_hWnd, PSM_INDEXTOHWND, nIndex, 0L); + } + + int PageToIndex(HPROPSHEETPAGE hPage) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PSM_PAGETOINDEX, 0, (LPARAM)hPage); + } + + HPROPSHEETPAGE IndexToPage(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HPROPSHEETPAGE)::SendMessage(m_hWnd, PSM_INDEXTOPAGE, nIndex, 0L); + } + + int IdToIndex(int nID) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PSM_IDTOINDEX, 0, nID); + } + + int IndexToId(int nIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PSM_INDEXTOID, nIndex, 0L); + } + + int GetResult() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, PSM_GETRESULT, 0, 0L); + } + + BOOL RecalcPageSizes() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, PSM_RECALCPAGESIZES, 0, 0L); + } + + void SetHeaderTitle(int nIndex, LPCTSTR lpstrHeaderTitle) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, PSM_SETHEADERTITLE, nIndex, (LPARAM)lpstrHeaderTitle); + } + + void SetHeaderSubTitle(int nIndex, LPCTSTR lpstrHeaderSubTitle) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, PSM_SETHEADERSUBTITLE, nIndex, (LPARAM)lpstrHeaderSubTitle); + } +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + +// Implementation - override to prevent usage + HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL) + { + ATLASSERT(FALSE); + return NULL; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// CPropertySheetImpl - implements a property sheet + +template +class ATL_NO_VTABLE CPropertySheetImpl : public ATL::CWindowImplBaseT< TBase > +{ +public: + PROPSHEETHEADER m_psh; + ATL::CSimpleArray m_arrPages; + +#if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific + #ifndef PROPSHEET_LINK_SIZE + #define PROPSHEET_LINK_SIZE 128 + #endif // PROPSHEET_LINK_SIZE + TCHAR m_szLink[PROPSHEET_LINK_SIZE]; + static LPCTSTR m_pszTitle; + static LPCTSTR m_pszLink; +#endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) + +// Construction/Destruction + CPropertySheetImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL) + { + memset(&m_psh, 0, sizeof(PROPSHEETHEADER)); + m_psh.dwSize = sizeof(PROPSHEETHEADER); + m_psh.dwFlags = PSH_USECALLBACK; + m_psh.hInstance = ModuleHelper::GetResourceInstance(); + m_psh.phpage = NULL; // will be set later + m_psh.nPages = 0; // will be set later + m_psh.pszCaption = title.m_lpstr; + m_psh.nStartPage = uStartPage; + m_psh.hwndParent = hWndParent; // if NULL, will be set in DoModal/Create + m_psh.pfnCallback = T::PropSheetCallback; + +#if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific + m_psh.dwFlags |= PSH_MAXIMIZE; + m_szLink[0] = 0; +#endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) + } + + ~CPropertySheetImpl() + { + if(m_arrPages.GetSize() > 0) // sheet never created, destroy all pages + { + for(int i = 0; i < m_arrPages.GetSize(); i++) + ::DestroyPropertySheetPage((HPROPSHEETPAGE)m_arrPages[i]); + } + } + +// Callback function and overrideables + static int CALLBACK PropSheetCallback(HWND hWnd, UINT uMsg, LPARAM lParam) + { + lParam; // avoid level 4 warning + int nRet = 0; + + if(uMsg == PSCB_INITIALIZED) + { + ATLASSERT(hWnd != NULL); + T* pT = (T*)ModuleHelper::ExtractCreateWndData(); + // subclass the sheet window + pT->SubclassWindow(hWnd); + // remove page handles array + pT->_CleanUpPages(); + +#if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific + m_pszTitle = pT->m_psh.pszCaption; + if(*pT->m_szLink != 0) + m_pszLink = pT->m_szLink; +#endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific + + pT->OnSheetInitialized(); + } +#if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific uMsg + else + { + switch(uMsg) + { + case PSCB_GETVERSION : + nRet = COMCTL32_VERSION; + break; + case PSCB_GETTITLE : + if(m_pszTitle != NULL) + { + lstrcpy((LPTSTR)lParam, m_pszTitle); + m_pszTitle = NULL; + } + break; + case PSCB_GETLINKTEXT: + if(m_pszLink != NULL) + { + lstrcpy((LPTSTR)lParam, m_pszLink); + m_pszLink = NULL; + } + break; + default: + break; + } + } +#endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) + + return nRet; + } + + void OnSheetInitialized() + { + } + +// Create method + HWND Create(HWND hWndParent = NULL) + { + ATLASSERT(m_hWnd == NULL); + + m_psh.dwFlags |= PSH_MODELESS; + if(m_psh.hwndParent == NULL) + m_psh.hwndParent = hWndParent; + m_psh.phpage = (HPROPSHEETPAGE*)m_arrPages.GetData(); + m_psh.nPages = m_arrPages.GetSize(); + + T* pT = static_cast(this); + ModuleHelper::AddCreateWndData(&pT->m_thunk.cd, pT); + + HWND hWnd = (HWND)::PropertySheet(&m_psh); + _CleanUpPages(); // ensure clean-up, required if call failed + + ATLASSERT(m_hWnd == hWnd); + + return hWnd; + } + + INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) + { + ATLASSERT(m_hWnd == NULL); + + m_psh.dwFlags &= ~PSH_MODELESS; + if(m_psh.hwndParent == NULL) + m_psh.hwndParent = hWndParent; + m_psh.phpage = (HPROPSHEETPAGE*)m_arrPages.GetData(); + m_psh.nPages = m_arrPages.GetSize(); + + T* pT = static_cast(this); + ModuleHelper::AddCreateWndData(&pT->m_thunk.cd, pT); + + INT_PTR nRet = ::PropertySheet(&m_psh); + _CleanUpPages(); // ensure clean-up, required if call failed + + return nRet; + } + + // implementation helper - clean up pages array + void _CleanUpPages() + { + m_psh.nPages = 0; + m_psh.phpage = NULL; + m_arrPages.RemoveAll(); + } + +// Attributes (extended overrides of client class methods) +// These now can be called before the sheet is created +// Note: Calling these after the sheet is created gives unpredictable results + int GetPageCount() const + { + if(m_hWnd == NULL) // not created yet + return m_arrPages.GetSize(); + return TBase::GetPageCount(); + } + + int GetActiveIndex() const + { + if(m_hWnd == NULL) // not created yet + return m_psh.nStartPage; + return TBase::GetActiveIndex(); + } + + HPROPSHEETPAGE GetPage(int nPageIndex) const + { + ATLASSERT(m_hWnd == NULL); // can't do this after it's created + return (HPROPSHEETPAGE)m_arrPages[nPageIndex]; + } + + int GetPageIndex(HPROPSHEETPAGE hPage) const + { + ATLASSERT(m_hWnd == NULL); // can't do this after it's created + return m_arrPages.Find((HPROPSHEETPAGE&)hPage); + } + + BOOL SetActivePage(int nPageIndex) + { + if(m_hWnd == NULL) // not created yet + { + ATLASSERT(nPageIndex >= 0 && nPageIndex < m_arrPages.GetSize()); + m_psh.nStartPage = nPageIndex; + return TRUE; + } + return TBase::SetActivePage(nPageIndex); + } + + BOOL SetActivePage(HPROPSHEETPAGE hPage) + { + ATLASSERT(hPage != NULL); + if (m_hWnd == NULL) // not created yet + { + int nPageIndex = GetPageIndex(hPage); + if(nPageIndex == -1) + return FALSE; + + return SetActivePage(nPageIndex); + } + return TBase::SetActivePage(hPage); + + } + + void SetTitle(LPCTSTR lpszText, UINT nStyle = 0) + { + ATLASSERT((nStyle & ~PSH_PROPTITLE) == 0); // only PSH_PROPTITLE is valid + ATLASSERT(lpszText != NULL); + + if(m_hWnd == NULL) + { + // set internal state + m_psh.pszCaption = lpszText; // must exist until sheet is created + m_psh.dwFlags &= ~PSH_PROPTITLE; + m_psh.dwFlags |= nStyle; + } + else + { + // set external state + TBase::SetTitle(lpszText, nStyle); + } + } + +#if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific Link field + void SetLinkText(LPCTSTR lpszText) + { + ATLASSERT(lpszText != NULL); + ATLASSERT(lstrlen(lpszText) < PROPSHEET_LINK_SIZE); + lstrcpy(m_szLink, lpszText); + } +#endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) + + void SetWizardMode() + { + m_psh.dwFlags |= PSH_WIZARD; + } + + void EnableHelp() + { + m_psh.dwFlags |= PSH_HASHELP; + } + +// Operations + BOOL AddPage(HPROPSHEETPAGE hPage) + { + ATLASSERT(hPage != NULL); + BOOL bRet = FALSE; + if(m_hWnd != NULL) + bRet = TBase::AddPage(hPage); + else // sheet not created yet, use internal data + bRet = m_arrPages.Add((HPROPSHEETPAGE&)hPage); + return bRet; + } + + BOOL AddPage(LPCPROPSHEETPAGE pPage) + { + ATLASSERT(pPage != NULL); + HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage); + if(hPage == NULL) + return FALSE; + BOOL bRet = AddPage(hPage); + if(!bRet) + ::DestroyPropertySheetPage(hPage); + return bRet; + } + + BOOL RemovePage(HPROPSHEETPAGE hPage) + { + ATLASSERT(hPage != NULL); + if (m_hWnd == NULL) // not created yet + { + int nPage = GetPageIndex(hPage); + if(nPage == -1) + return FALSE; + return RemovePage(nPage); + } + TBase::RemovePage(hPage); + return TRUE; + + } + + BOOL RemovePage(int nPageIndex) + { + BOOL bRet = TRUE; + if(m_hWnd != NULL) + TBase::RemovePage(nPageIndex); + else // sheet not created yet, use internal data + bRet = m_arrPages.RemoveAt(nPageIndex); + return bRet; + } + +#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + void SetHeader(LPCTSTR szbmHeader) + { + ATLASSERT(m_hWnd == NULL); // can't do this after it's created + + m_psh.dwFlags &= ~PSH_WIZARD; + m_psh.dwFlags |= (PSH_HEADER | PSH_WIZARD97); + m_psh.pszbmHeader = szbmHeader; + } + + void SetHeader(HBITMAP hbmHeader) + { + ATLASSERT(m_hWnd == NULL); // can't do this after it's created + + m_psh.dwFlags &= ~PSH_WIZARD; + m_psh.dwFlags |= (PSH_HEADER | PSH_USEHBMHEADER | PSH_WIZARD97); + m_psh.hbmHeader = hbmHeader; + } + + void SetWatermark(LPCTSTR szbmWatermark, HPALETTE hplWatermark = NULL) + { + ATLASSERT(m_hWnd == NULL); // can't do this after it's created + + m_psh.dwFlags &= ~PSH_WIZARD; + m_psh.dwFlags |= PSH_WATERMARK | PSH_WIZARD97; + m_psh.pszbmWatermark = szbmWatermark; + + if (hplWatermark != NULL) + { + m_psh.dwFlags |= PSH_USEHPLWATERMARK; + m_psh.hplWatermark = hplWatermark; + } + } + + void SetWatermark(HBITMAP hbmWatermark, HPALETTE hplWatermark = NULL) + { + ATLASSERT(m_hWnd == NULL); // can't do this after it's created + + m_psh.dwFlags &= ~PSH_WIZARD; + m_psh.dwFlags |= (PSH_WATERMARK | PSH_USEHBMWATERMARK | PSH_WIZARD97); + m_psh.hbmWatermark = hbmWatermark; + + if (hplWatermark != NULL) + { + m_psh.dwFlags |= PSH_USEHPLWATERMARK; + m_psh.hplWatermark = hplWatermark; + } + } + + void StretchWatermark(bool bStretchWatermark) + { + ATLASSERT(m_hWnd == NULL); // can't do this after it's created + if (bStretchWatermark) + m_psh.dwFlags |= PSH_STRETCHWATERMARK; + else + m_psh.dwFlags &= ~PSH_STRETCHWATERMARK; + } +#endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +// Message map and handlers + BEGIN_MSG_MAP(CPropertySheetImpl) + MESSAGE_HANDLER(WM_COMMAND, OnCommand) + MESSAGE_HANDLER(WM_SYSCOMMAND, OnSysCommand) + END_MSG_MAP() + + LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); + if(HIWORD(wParam) == BN_CLICKED && (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) && + ((m_psh.dwFlags & PSH_MODELESS) != 0) && (GetActivePage() == NULL)) + DestroyWindow(); + return lRet; + } + + LRESULT OnSysCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if(((m_psh.dwFlags & PSH_MODELESS) == PSH_MODELESS) && ((wParam & 0xFFF0) == SC_CLOSE)) + SendMessage(WM_CLOSE); + else + bHandled = FALSE; + return 0; + } +}; + +#if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC static pointers +template < class T, class TBase > +LPCWSTR CPropertySheetImpl::m_pszTitle = NULL; +template < class T, class TBase> +LPCWSTR CPropertySheetImpl::m_pszLink = NULL; +#endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) + +// for non-customized sheets +class CPropertySheet : public CPropertySheetImpl +{ +public: + CPropertySheet(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL) + : CPropertySheetImpl(title, uStartPage, hWndParent) + { } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CPropertyPageWindow - client side for a property page + +class CPropertyPageWindow : public ATL::CWindow +{ +public: +// Constructors + CPropertyPageWindow(HWND hWnd = NULL) : ATL::CWindow(hWnd) + { } + + CPropertyPageWindow& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + +// Attributes + CPropertySheetWindow GetPropertySheet() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CPropertySheetWindow(GetParent()); + } + +// Operations + BOOL Apply() + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetParent() != NULL); + return GetPropertySheet().Apply(); + } + + void CancelToClose() + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetParent() != NULL); + GetPropertySheet().CancelToClose(); + } + + void SetModified(BOOL bChanged = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetParent() != NULL); + GetPropertySheet().SetModified(m_hWnd, bChanged); + } + + LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetParent() != NULL); + return GetPropertySheet().QuerySiblings(wParam, lParam); + } + + void RebootSystem() + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetParent() != NULL); + GetPropertySheet().RebootSystem(); + } + + void RestartWindows() + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetParent() != NULL); + GetPropertySheet().RestartWindows(); + } + + void SetWizardButtons(DWORD dwFlags) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetParent() != NULL); + GetPropertySheet().SetWizardButtons(dwFlags); + } + +// Implementation - overrides to prevent usage + HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL) + { + ATLASSERT(FALSE); + return NULL; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// CPropertyPageImpl - implements a property page + +template +class ATL_NO_VTABLE CPropertyPageImpl : public ATL::CDialogImplBaseT< TBase > +{ +public: + PROPSHEETPAGE m_psp; + + operator PROPSHEETPAGE*() { return &m_psp; } + +// Construction + CPropertyPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) + { + // initialize PROPSHEETPAGE struct + memset(&m_psp, 0, sizeof(PROPSHEETPAGE)); + m_psp.dwSize = sizeof(PROPSHEETPAGE); + m_psp.dwFlags = PSP_USECALLBACK; + m_psp.hInstance = ModuleHelper::GetResourceInstance(); + T* pT = static_cast(this); + m_psp.pszTemplate = MAKEINTRESOURCE(pT->IDD); + m_psp.pfnDlgProc = (DLGPROC)T::StartDialogProc; + m_psp.pfnCallback = T::PropPageCallback; + m_psp.lParam = (LPARAM)pT; + + if(title.m_lpstr != NULL) + SetTitle(title); + } + +// Callback function and overrideables + static UINT CALLBACK PropPageCallback(HWND hWnd, UINT uMsg, LPPROPSHEETPAGE ppsp) + { + hWnd; // avoid level 4 warning + ATLASSERT(hWnd == NULL); + T* pT = (T*)ppsp->lParam; + UINT uRet = 0; + + switch(uMsg) + { + case PSPCB_CREATE: + { + ATL::CDialogImplBaseT< TBase >* pPage = (ATL::CDialogImplBaseT< TBase >*)pT; + ModuleHelper::AddCreateWndData(&pPage->m_thunk.cd, pPage); + uRet = pT->OnPageCreate() ? 1 : 0; + } + break; +#if (_WIN32_IE >= 0x0500) + case PSPCB_ADDREF: + pT->OnPageAddRef(); + break; +#endif // (_WIN32_IE >= 0x0500) + case PSPCB_RELEASE: + pT->OnPageRelease(); + break; + default: + break; + } + + return uRet; + } + + bool OnPageCreate() + { + return true; // true - allow page to be created, false - prevent creation + } + +#if (_WIN32_IE >= 0x0500) + void OnPageAddRef() + { + } +#endif // (_WIN32_IE >= 0x0500) + + void OnPageRelease() + { + } + +// Create method + HPROPSHEETPAGE Create() + { + return ::CreatePropertySheetPage(&m_psp); + } + +// Attributes + void SetTitle(ATL::_U_STRINGorID title) + { + m_psp.pszTitle = title.m_lpstr; + m_psp.dwFlags |= PSP_USETITLE; + } + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + void SetHeaderTitle(LPCTSTR lpstrHeaderTitle) + { + ATLASSERT(m_hWnd == NULL); // can't do this after it's created + m_psp.dwFlags |= PSP_USEHEADERTITLE; + m_psp.pszHeaderTitle = lpstrHeaderTitle; + } + + void SetHeaderSubTitle(LPCTSTR lpstrHeaderSubTitle) + { + ATLASSERT(m_hWnd == NULL); // can't do this after it's created + m_psp.dwFlags |= PSP_USEHEADERSUBTITLE; + m_psp.pszHeaderSubTitle = lpstrHeaderSubTitle; + } +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + +// Operations + void EnableHelp() + { + m_psp.dwFlags |= PSP_HASHELP; + } + +// Message map and handlers + BEGIN_MSG_MAP(CPropertyPageImpl) + MESSAGE_HANDLER(WM_NOTIFY, OnNotify) + END_MSG_MAP() + + // NOTE: Define _WTL_NEW_PAGE_NOTIFY_HANDLERS to use new notification + // handlers that return direct values without any restrictions + LRESULT OnNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { +#ifndef _WIN32_WCE + // This notification is sometimes received on Windows CE after the window is already destroyed + ATLASSERT(::IsWindow(m_hWnd)); +#endif + NMHDR* pNMHDR = (NMHDR*)lParam; + + // don't handle messages not from the page/sheet itself + if(pNMHDR->hwndFrom != m_hWnd && pNMHDR->hwndFrom != ::GetParent(m_hWnd)) + { + bHandled = FALSE; + return 1; + } +#ifdef _WIN32_WCE + ATLASSERT(::IsWindow(m_hWnd)); +#endif + + T* pT = static_cast(this); + LRESULT lResult = 0; + switch(pNMHDR->code) + { +#ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS + case PSN_SETACTIVE: + lResult = pT->OnSetActive(); + break; + case PSN_KILLACTIVE: + lResult = pT->OnKillActive(); + break; + case PSN_APPLY: + lResult = pT->OnApply(); + break; + case PSN_RESET: + pT->OnReset(); + break; + case PSN_QUERYCANCEL: + lResult = pT->OnQueryCancel(); + break; + case PSN_WIZNEXT: + lResult = pT->OnWizardNext(); + break; + case PSN_WIZBACK: + lResult = pT->OnWizardBack(); + break; + case PSN_WIZFINISH: + lResult = pT->OnWizardFinish(); + break; + case PSN_HELP: + pT->OnHelp(); + break; +#ifndef _WIN32_WCE +#if (_WIN32_IE >= 0x0400) + case PSN_GETOBJECT: + if(!pT->OnGetObject((LPNMOBJECTNOTIFY)lParam)) + bHandled = FALSE; + break; +#endif // (_WIN32_IE >= 0x0400) +#if (_WIN32_IE >= 0x0500) + case PSN_TRANSLATEACCELERATOR: + { + LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam; + lResult = pT->OnTranslateAccelerator((LPMSG)lpPSHNotify->lParam); + } + break; + case PSN_QUERYINITIALFOCUS: + { + LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam; + lResult = (LRESULT)pT->OnQueryInitialFocus((HWND)lpPSHNotify->lParam); + } + break; +#endif // (_WIN32_IE >= 0x0500) +#endif // !_WIN32_WCE + +#else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS + case PSN_SETACTIVE: + lResult = pT->OnSetActive() ? 0 : -1; + break; + case PSN_KILLACTIVE: + lResult = !pT->OnKillActive(); + break; + case PSN_APPLY: + lResult = pT->OnApply() ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE; + break; + case PSN_RESET: + pT->OnReset(); + break; + case PSN_QUERYCANCEL: + lResult = !pT->OnQueryCancel(); + break; + case PSN_WIZNEXT: + lResult = pT->OnWizardNext(); + break; + case PSN_WIZBACK: + lResult = pT->OnWizardBack(); + break; + case PSN_WIZFINISH: + lResult = !pT->OnWizardFinish(); + break; + case PSN_HELP: + pT->OnHelp(); + break; +#ifndef _WIN32_WCE +#if (_WIN32_IE >= 0x0400) + case PSN_GETOBJECT: + if(!pT->OnGetObject((LPNMOBJECTNOTIFY)lParam)) + bHandled = FALSE; + break; +#endif // (_WIN32_IE >= 0x0400) +#if (_WIN32_IE >= 0x0500) + case PSN_TRANSLATEACCELERATOR: + { + LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam; + lResult = pT->OnTranslateAccelerator((LPMSG)lpPSHNotify->lParam) ? PSNRET_MESSAGEHANDLED : PSNRET_NOERROR; + } + break; + case PSN_QUERYINITIALFOCUS: + { + LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam; + lResult = (LRESULT)pT->OnQueryInitialFocus((HWND)lpPSHNotify->lParam); + } + break; +#endif // (_WIN32_IE >= 0x0500) +#endif // !_WIN32_WCE + +#endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS + default: + bHandled = FALSE; // not handled + } + + return lResult; + } + +// Overridables + // NOTE: Define _WTL_NEW_PAGE_NOTIFY_HANDLERS to use new notification + // handlers that return direct values without any restrictions +#ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS + int OnSetActive() + { + // 0 = allow activate + // -1 = go back that was active + // page ID = jump to page + return 0; + } + + BOOL OnKillActive() + { + // FALSE = allow deactivate + // TRUE = prevent deactivation + return FALSE; + } + + int OnApply() + { + // PSNRET_NOERROR = apply OK + // PSNRET_INVALID = apply not OK, return to this page + // PSNRET_INVALID_NOCHANGEPAGE = apply not OK, don't change focus + return PSNRET_NOERROR; + } + + void OnReset() + { + } + + BOOL OnQueryCancel() + { + // FALSE = allow cancel + // TRUE = prevent cancel + return FALSE; + } + + int OnWizardBack() + { + // 0 = goto previous page + // -1 = prevent page change + // >0 = jump to page by dlg ID + return 0; + } + + int OnWizardNext() + { + // 0 = goto next page + // -1 = prevent page change + // >0 = jump to page by dlg ID + return 0; + } + + INT_PTR OnWizardFinish() + { + // FALSE = allow finish + // TRUE = prevent finish + // HWND = prevent finish and set focus to HWND (CommCtrl 5.80 only) + return FALSE; + } + + void OnHelp() + { + } + +#ifndef _WIN32_WCE +#if (_WIN32_IE >= 0x0400) + BOOL OnGetObject(LPNMOBJECTNOTIFY /*lpObjectNotify*/) + { + return FALSE; // not processed + } +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0500) + int OnTranslateAccelerator(LPMSG /*lpMsg*/) + { + // PSNRET_NOERROR - message not handled + // PSNRET_MESSAGEHANDLED - message handled + return PSNRET_NOERROR; + } + + HWND OnQueryInitialFocus(HWND /*hWndFocus*/) + { + // NULL = set focus to default control + // HWND = set focus to HWND + return NULL; + } +#endif // (_WIN32_IE >= 0x0500) +#endif // !_WIN32_WCE + +#else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS + BOOL OnSetActive() + { + return TRUE; + } + + BOOL OnKillActive() + { + return TRUE; + } + + BOOL OnApply() + { + return TRUE; + } + + void OnReset() + { + } + + BOOL OnQueryCancel() + { + return TRUE; // ok to cancel + } + + int OnWizardBack() + { + // 0 = goto previous page + // -1 = prevent page change + // >0 = jump to page by dlg ID + return 0; + } + + int OnWizardNext() + { + // 0 = goto next page + // -1 = prevent page change + // >0 = jump to page by dlg ID + return 0; + } + + BOOL OnWizardFinish() + { + return TRUE; + } + + void OnHelp() + { + } + +#ifndef _WIN32_WCE +#if (_WIN32_IE >= 0x0400) + BOOL OnGetObject(LPNMOBJECTNOTIFY /*lpObjectNotify*/) + { + return FALSE; // not processed + } +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0500) + BOOL OnTranslateAccelerator(LPMSG /*lpMsg*/) + { + return FALSE; // not translated + } + + HWND OnQueryInitialFocus(HWND /*hWndFocus*/) + { + return NULL; // default + } +#endif // (_WIN32_IE >= 0x0500) +#endif // !_WIN32_WCE + +#endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS +}; + +// for non-customized pages +template +class CPropertyPage : public CPropertyPageImpl > +{ +public: + enum { IDD = t_wDlgTemplateID }; + + CPropertyPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CPropertyPageImpl(title) + { } + + DECLARE_EMPTY_MSG_MAP() +}; + +/////////////////////////////////////////////////////////////////////////////// +// CAxPropertyPageImpl - property page that hosts ActiveX controls + +#ifndef _ATL_NO_HOSTING + +// Note: You must #include to use these classes + +template +class ATL_NO_VTABLE CAxPropertyPageImpl : public CPropertyPageImpl< T, TBase > +{ +public: +// Data members + HGLOBAL m_hInitData; + HGLOBAL m_hDlgRes; + HGLOBAL m_hDlgResSplit; + +// Constructor/destructor + CAxPropertyPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : + CPropertyPageImpl< T, TBase >(title), + m_hInitData(NULL), m_hDlgRes(NULL), m_hDlgResSplit(NULL) + { + T* pT = static_cast(this); + pT; // avoid level 4 warning + + // initialize ActiveX hosting and modify dialog template + ATL::AtlAxWinInit(); + + HINSTANCE hInstance = ModuleHelper::GetResourceInstance(); + LPCTSTR lpTemplateName = MAKEINTRESOURCE(pT->IDD); + HRSRC hDlg = ::FindResource(hInstance, lpTemplateName, (LPTSTR)RT_DIALOG); + if(hDlg != NULL) + { + HRSRC hDlgInit = ::FindResource(hInstance, lpTemplateName, (LPTSTR)_ATL_RT_DLGINIT); + + BYTE* pInitData = NULL; + if(hDlgInit != NULL) + { + m_hInitData = ::LoadResource(hInstance, hDlgInit); + pInitData = (BYTE*)::LockResource(m_hInitData); + } + + m_hDlgRes = ::LoadResource(hInstance, hDlg); + DLGTEMPLATE* pDlg = (DLGTEMPLATE*)::LockResource(m_hDlgRes); + LPCDLGTEMPLATE lpDialogTemplate = ATL::_DialogSplitHelper::SplitDialogTemplate(pDlg, pInitData); + if(lpDialogTemplate != pDlg) + m_hDlgResSplit = GlobalHandle(lpDialogTemplate); + + // set up property page to use in-memory dialog template + if(lpDialogTemplate != NULL) + { + m_psp.dwFlags |= PSP_DLGINDIRECT; + m_psp.pResource = lpDialogTemplate; + } + else + { + ATLASSERT(FALSE && _T("CAxPropertyPageImpl - ActiveX initializtion failed!")); + } + } + else + { + ATLASSERT(FALSE && _T("CAxPropertyPageImpl - Cannot find dialog template!")); + } + } + + ~CAxPropertyPageImpl() + { + if(m_hInitData != NULL) + { + UnlockResource(m_hInitData); + FreeResource(m_hInitData); + } + if(m_hDlgRes != NULL) + { + UnlockResource(m_hDlgRes); + FreeResource(m_hDlgRes); + } + if(m_hDlgResSplit != NULL) + { + ::GlobalFree(m_hDlgResSplit); + } + } + +// Methods + // call this one to handle keyboard message for ActiveX controls + BOOL PreTranslateMessage(LPMSG pMsg) + { + if ((pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST) && + (pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAST)) + return FALSE; + // find a direct child of the dialog from the window that has focus + HWND hWndCtl = ::GetFocus(); + if (IsChild(hWndCtl) && ::GetParent(hWndCtl) != m_hWnd) + { + do + { + hWndCtl = ::GetParent(hWndCtl); + } + while (::GetParent(hWndCtl) != m_hWnd); + } + // give controls a chance to translate this message + return (BOOL)::SendMessage(hWndCtl, WM_FORWARDMSG, 0, (LPARAM)pMsg); + } + +// Overridables +#if (_WIN32_IE >= 0x0500) + // new default implementation for ActiveX hosting pages +#ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS + int OnTranslateAccelerator(LPMSG lpMsg) + { + T* pT = static_cast(this); + return (pT->PreTranslateMessage(lpMsg) != FALSE) ? PSNRET_MESSAGEHANDLED : PSNRET_NOERROR; + } +#else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS + BOOL OnTranslateAccelerator(LPMSG lpMsg) + { + T* pT = static_cast(this); + return pT->PreTranslateMessage(lpMsg); + } +#endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS +#endif // (_WIN32_IE >= 0x0500) + +// Support for new stuff in ATL7 +#if (_ATL_VER >= 0x0700) + int GetIDD() + { + return( static_cast(this)->IDD ); + } + + virtual DLGPROC GetDialogProc() + { + return DialogProc; + } + + static INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + CAxPropertyPageImpl< T, TBase >* pThis = (CAxPropertyPageImpl< T, TBase >*)hWnd; + if (uMsg == WM_INITDIALOG) + { + HRESULT hr; + if (FAILED(hr = pThis->CreateActiveXControls(pThis->GetIDD()))) + { + ATLASSERT(FALSE); + return FALSE; + } + } + return CPropertyPageImpl< T, TBase >::DialogProc(hWnd, uMsg, wParam, lParam); + } + +// ActiveX controls creation + virtual HRESULT CreateActiveXControls(UINT nID) + { + // Load dialog template and InitData + HRSRC hDlgInit = ::FindResource(ATL::_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(nID), (LPTSTR)_ATL_RT_DLGINIT); + BYTE* pInitData = NULL; + HGLOBAL hData = NULL; + HRESULT hr = S_OK; + if (hDlgInit != NULL) + { + hData = ::LoadResource(ATL::_AtlBaseModule.GetResourceInstance(), hDlgInit); + if (hData != NULL) + pInitData = (BYTE*) ::LockResource(hData); + } + + HRSRC hDlg = ::FindResource(ATL::_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(nID), (LPTSTR)RT_DIALOG); + if (hDlg != NULL) + { + HGLOBAL hResource = ::LoadResource(ATL::_AtlBaseModule.GetResourceInstance(), hDlg); + DLGTEMPLATE* pDlg = NULL; + if (hResource != NULL) + { + pDlg = (DLGTEMPLATE*) ::LockResource(hResource); + if (pDlg != NULL) + { + // Get first control on the template + BOOL bDialogEx = ATL::_DialogSplitHelper::IsDialogEx(pDlg); + WORD nItems = ATL::_DialogSplitHelper::DlgTemplateItemCount(pDlg); + + // Get first control on the dialog + DLGITEMTEMPLATE* pItem = ATL::_DialogSplitHelper::FindFirstDlgItem(pDlg); + HWND hWndPrev = GetWindow(GW_CHILD); + + // Create all ActiveX cotnrols in the dialog template and place them in the correct tab order (z-order) + for (WORD nItem = 0; nItem < nItems; nItem++) + { + DWORD wID = bDialogEx ? ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->id : pItem->id; + if (ATL::_DialogSplitHelper::IsActiveXControl(pItem, bDialogEx)) + { + BYTE* pData = NULL; + DWORD dwLen = ATL::_DialogSplitHelper::FindCreateData(wID, pInitData, &pData); + ATL::CComPtr spStream; + if (dwLen != 0) + { + HGLOBAL h = GlobalAlloc(GHND, dwLen); + if (h != NULL) + { + BYTE* pBytes = (BYTE*) GlobalLock(h); + BYTE* pSource = pData; + SecureHelper::memcpy_x(pBytes, dwLen, pSource, dwLen); + GlobalUnlock(h); + CreateStreamOnHGlobal(h, TRUE, &spStream); + } + else + { + hr = E_OUTOFMEMORY; + break; + } + } + + ATL::CComBSTR bstrLicKey; + hr = ATL::_DialogSplitHelper::ParseInitData(spStream, &bstrLicKey.m_str); + if (SUCCEEDED(hr)) + { + ATL::CAxWindow2 wnd; + // Get control caption. + LPWSTR pszClassName = + bDialogEx ? + (LPWSTR)(((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem) + 1) : + (LPWSTR)(pItem + 1); + // Get control rect. + RECT rect; + rect.left = + bDialogEx ? + ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->x : + pItem->x; + rect.top = + bDialogEx ? + ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->y : + pItem->y; + rect.right = rect.left + + (bDialogEx ? + ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->cx : + pItem->cx); + rect.bottom = rect.top + + (bDialogEx ? + ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->cy : + pItem->cy); + + // Convert from dialog units to screen units + MapDialogRect(&rect); + + // Create AxWindow with a NULL caption. + wnd.Create(m_hWnd, + &rect, + NULL, + (bDialogEx ? + ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->style : + pItem->style) | WS_TABSTOP, + bDialogEx ? + ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->exStyle : + 0, + bDialogEx ? + ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->id : + pItem->id, + NULL); + + if (wnd != NULL) + { +#ifndef _WIN32_WCE + // Set the Help ID + if (bDialogEx && ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->helpID != 0) + wnd.SetWindowContextHelpId(((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->helpID); +#endif // !_WIN32_WCE + // Try to create the ActiveX control. + hr = wnd.CreateControlLic(pszClassName, spStream, NULL, bstrLicKey); + if (FAILED(hr)) + break; + // Set the correct tab position. + if (nItem == 0) + hWndPrev = HWND_TOP; + wnd.SetWindowPos(hWndPrev, 0,0,0,0,SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); + hWndPrev = wnd; + } + else + { + hr = ATL::AtlHresultFromLastError(); + } + } + } + else + { + if (nItem != 0) + hWndPrev = ::GetWindow(hWndPrev, GW_HWNDNEXT); + } + pItem = ATL::_DialogSplitHelper::FindNextDlgItem(pItem, bDialogEx); + } + } + else + hr = ATL::AtlHresultFromLastError(); + } + else + hr = ATL::AtlHresultFromLastError(); + } + return hr; + } + +// Event handling support + HRESULT AdviseSinkMap(bool bAdvise) + { + if(!bAdvise && m_hWnd == NULL) + { + // window is gone, controls are already unadvised + ATLTRACE2(atlTraceUI, 0, _T("CAxPropertyPageImpl::AdviseSinkMap called after the window was destroyed\n")); + return S_OK; + } + HRESULT hRet = E_NOTIMPL; + __if_exists(T::_GetSinkMapFinder) + { + T* pT = static_cast(this); + hRet = AtlAdviseSinkMap(pT, bAdvise); + } + return hRet; + } + +// Message map and handlers + typedef CPropertyPageImpl< T, TBase> _baseClass; + BEGIN_MSG_MAP(CAxPropertyPageImpl) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + CHAIN_MSG_MAP(_baseClass) + END_MSG_MAP() + + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + // initialize controls in dialog with DLGINIT resource section + ExecuteDlgInit(static_cast(this)->IDD); + AdviseSinkMap(true); + bHandled = FALSE; + return 1; + } + + LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + AdviseSinkMap(false); + bHandled = FALSE; + return 1; + } +#endif // (_ATL_VER >= 0x0700) +}; + +// for non-customized pages +template +class CAxPropertyPage : public CAxPropertyPageImpl > +{ +public: + enum { IDD = t_wDlgTemplateID }; + + CAxPropertyPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAxPropertyPageImpl(title) + { } + +#if (_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700) + // not empty so we handle accelerators/create controls + BEGIN_MSG_MAP(CAxPropertyPage) + CHAIN_MSG_MAP(CAxPropertyPageImpl >) + END_MSG_MAP() +#else // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)) + DECLARE_EMPTY_MSG_MAP() +#endif // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)) +}; + +#endif // _ATL_NO_HOSTING + + +/////////////////////////////////////////////////////////////////////////////// +// Wizard97 Support + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + +// Sample wizard dialog resources: +// +// IDD_WIZ97_INTERIOR_BLANK DIALOG 0, 0, 317, 143 +// STYLE DS_SETFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +// CAPTION "Wizard97 Property Page - Interior" +// FONT 8, "MS Shell Dlg" +// BEGIN +// END +// +// IDD_WIZ97_EXTERIOR_BLANK DIALOGEX 0, 0, 317, 193 +// STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION +// CAPTION "Wizard97 Property Page - Welcome/Complete" +// FONT 8, "MS Shell Dlg", 0, 0, 0x0 +// BEGIN +// LTEXT "Welcome to the X Wizard",IDC_WIZ97_EXTERIOR_TITLE,115,8, +// 195,24 +// LTEXT "Wizard Explanation\r\n(The height of the static text should be in multiples of 8 dlus)", +// IDC_STATIC,115,40,195,16 +// LTEXT "h",IDC_WIZ97_BULLET1,118,64,8,8 +// LTEXT "List Item 1 (the h is turned into a bullet)",IDC_STATIC, +// 127,63,122,8 +// LTEXT "h",IDC_WIZ97_BULLET2,118,79,8,8 +// LTEXT "List Item 2. Keep 7 dlus between paragraphs",IDC_STATIC, +// 127,78,33,8 +// CONTROL "&Do not show this Welcome page again", +// IDC_WIZ97_WELCOME_NOTAGAIN,"Button",BS_AUTOCHECKBOX | +// WS_TABSTOP,115,169,138,10 +// END +// +// GUIDELINES DESIGNINFO +// BEGIN +// IDD_WIZ97_INTERIOR_BLANK, DIALOG +// BEGIN +// LEFTMARGIN, 7 +// RIGHTMARGIN, 310 +// VERTGUIDE, 21 +// VERTGUIDE, 31 +// VERTGUIDE, 286 +// VERTGUIDE, 296 +// TOPMARGIN, 7 +// BOTTOMMARGIN, 136 +// HORZGUIDE, 8 +// END +// +// IDD_WIZ97_EXTERIOR_BLANK, DIALOG +// BEGIN +// RIGHTMARGIN, 310 +// VERTGUIDE, 115 +// VERTGUIDE, 118 +// VERTGUIDE, 127 +// TOPMARGIN, 7 +// BOTTOMMARGIN, 186 +// HORZGUIDE, 8 +// HORZGUIDE, 32 +// HORZGUIDE, 40 +// HORZGUIDE, 169 +// END +// END + +/////////////////////////////////////////////////////////////////////////////// +// CWizard97SheetWindow - client side for a Wizard 97 style wizard sheet + +class CWizard97SheetWindow : public CPropertySheetWindow +{ +public: +// Constructors + CWizard97SheetWindow(HWND hWnd = NULL) : CPropertySheetWindow(hWnd) + { } + + CWizard97SheetWindow& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + +// Operations + HFONT GetExteriorPageTitleFont(void) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HFONT)::SendMessage(m_hWnd, GetMessage_GetExteriorPageTitleFont(), 0, 0L); + } + + HFONT GetBulletFont(void) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HFONT)::SendMessage(m_hWnd, GetMessage_GetBulletFont(), 0, 0L); + } + +// Helpers + static UINT GetMessage_GetExteriorPageTitleFont() + { + static UINT uGetExteriorPageTitleFont = 0; + if(uGetExteriorPageTitleFont == 0) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CWizard97SheetWindow::GetMessage_GetExteriorPageTitleFont().\n")); + ATLASSERT(FALSE); + return 0; + } + + if(uGetExteriorPageTitleFont == 0) + uGetExteriorPageTitleFont = ::RegisterWindowMessage(_T("GetExteriorPageTitleFont_531AF056-B8BE-4c4c-B786-AC608DF0DF12")); + + lock.Unlock(); + } + ATLASSERT(uGetExteriorPageTitleFont != 0); + return uGetExteriorPageTitleFont; + } + + static UINT GetMessage_GetBulletFont() + { + static UINT uGetBulletFont = 0; + if(uGetBulletFont == 0) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CWizard97SheetWindow::GetMessage_GetBulletFont().\n")); + ATLASSERT(FALSE); + return 0; + } + + if(uGetBulletFont == 0) + uGetBulletFont = ::RegisterWindowMessage(_T("GetBulletFont_AD347D08-8F65-45ef-982E-6352E8218AD5")); + + lock.Unlock(); + } + ATLASSERT(uGetBulletFont != 0); + return uGetBulletFont; + } + +// Implementation - override to prevent usage + HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL) + { + ATLASSERT(FALSE); + return NULL; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CWizard97SheetImpl - implements a Wizard 97 style wizard sheet + +template +class ATL_NO_VTABLE CWizard97SheetImpl : public CPropertySheetImpl< T, TBase > +{ +protected: +// Typedefs + typedef CWizard97SheetImpl< T, TBase > thisClass; + typedef CPropertySheetImpl< T, TBase > baseClass; + +// Member variables + CFont m_fontExteriorPageTitle; // Welcome and Completion page title font + CFont m_fontBullet; // Bullet font (used on static text 'h' to produce a small bullet) + bool m_bReceivedFirstSizeMessage; + +public: + CWizard97SheetImpl(ATL::_U_STRINGorID title, ATL::_U_STRINGorID headerBitmap, ATL::_U_STRINGorID watermarkBitmap, UINT uStartPage = 0, HWND hWndParent = NULL) : + baseClass(title, uStartPage, hWndParent), + m_bReceivedFirstSizeMessage(false) + { + m_psh.dwFlags &= ~(PSH_NOCONTEXTHELP); + m_psh.dwFlags &= ~(PSH_WIZARD | PSH_WIZARD_LITE); + + m_psh.dwFlags |= (PSH_HASHELP | PSH_WIZARDCONTEXTHELP); + m_psh.dwFlags |= PSH_WIZARD97; + + baseClass::SetHeader(headerBitmap.m_lpstr); + baseClass::SetWatermark(watermarkBitmap.m_lpstr); + } + +// Overrides from base class + void OnSheetInitialized() + { + T* pT = static_cast(this); + pT->_InitializeFonts(); + + // We'd like to center the wizard here, but its too early. + // Instead, we'll do CenterWindow upon our first WM_SIZE message + } + +// Initialization + void _InitializeFonts() + { + // Setup the Title and Bullet Font + // (Property pages can send the "get external page title font" and "get bullet font" messages) + // The derived class needs to do the actual SetFont for the dialog items) + + CFontHandle fontThisDialog = this->GetFont(); + CClientDC dcScreen(NULL); + + LOGFONT titleLogFont = {0}; + LOGFONT bulletLogFont = {0}; + fontThisDialog.GetLogFont(&titleLogFont); + fontThisDialog.GetLogFont(&bulletLogFont); + + // The Wizard 97 Spec recommends to do the Title Font + // as Verdana Bold, 12pt. + titleLogFont.lfCharSet = DEFAULT_CHARSET; + titleLogFont.lfWeight = FW_BOLD; + SecureHelper::strcpy_x(titleLogFont.lfFaceName, _countof(titleLogFont.lfFaceName), _T("Verdana Bold")); + INT titleFontPointSize = 12; + titleLogFont.lfHeight = -::MulDiv(titleFontPointSize, dcScreen.GetDeviceCaps(LOGPIXELSY), 72); + m_fontExteriorPageTitle.CreateFontIndirect(&titleLogFont); + + // The Wizard 97 Spec recommends to do Bullets by having + // static text of "h" in the Marlett font. + bulletLogFont.lfCharSet = DEFAULT_CHARSET; + bulletLogFont.lfWeight = FW_NORMAL; + SecureHelper::strcpy_x(bulletLogFont.lfFaceName, _countof(bulletLogFont.lfFaceName), _T("Marlett")); + INT bulletFontSize = 8; + bulletLogFont.lfHeight = -::MulDiv(bulletFontSize, dcScreen.GetDeviceCaps(LOGPIXELSY), 72); + m_fontBullet.CreateFontIndirect(&bulletLogFont); + } + +// Message Handling + BEGIN_MSG_MAP(thisClass) + MESSAGE_HANDLER(CWizard97SheetWindow::GetMessage_GetExteriorPageTitleFont(), OnGetExteriorPageTitleFont) + MESSAGE_HANDLER(CWizard97SheetWindow::GetMessage_GetBulletFont(), OnGetBulletFont) + MESSAGE_HANDLER(WM_SIZE, OnSize) + CHAIN_MSG_MAP(baseClass) + END_MSG_MAP() + + LRESULT OnGetExteriorPageTitleFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return (LRESULT)(HFONT)m_fontExteriorPageTitle; + } + + LRESULT OnGetBulletFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return (LRESULT)(HFONT)m_fontBullet; + } + + LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(!m_bReceivedFirstSizeMessage) + { + m_bReceivedFirstSizeMessage = true; + this->CenterWindow(); + } + + bHandled = FALSE; + return 0; + } +}; + +// for non-customized sheets +class CWizard97Sheet : public CWizard97SheetImpl +{ +protected: +// Typedefs + typedef CWizard97Sheet thisClass; + typedef CWizard97SheetImpl baseClass; + +public: + CWizard97Sheet(ATL::_U_STRINGorID title, ATL::_U_STRINGorID headerBitmap, ATL::_U_STRINGorID watermarkBitmap, UINT uStartPage = 0, HWND hWndParent = NULL) : + baseClass(title, headerBitmap, watermarkBitmap, uStartPage, hWndParent) + { } + + BEGIN_MSG_MAP(thisClass) + CHAIN_MSG_MAP(baseClass) + END_MSG_MAP() +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CWizard97PageWindow - client side for a Wizard 97 style wizard page + +#define WIZARD97_EXTERIOR_CXDLG 317 +#define WIZARD97_EXTERIOR_CYDLG 193 + +#define WIZARD97_INTERIOR_CXDLG 317 +#define WIZARD97_INTERIOR_CYDLG 143 + +class CWizard97PageWindow : public CPropertyPageWindow +{ +public: +// Constructors + CWizard97PageWindow(HWND hWnd = NULL) : CPropertyPageWindow(hWnd) + { } + + CWizard97PageWindow& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + +// Attributes + CWizard97SheetWindow GetPropertySheet() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return CWizard97SheetWindow(GetParent()); + } + +// Operations + HFONT GetExteriorPageTitleFont(void) + { + ATLASSERT(::IsWindow(m_hWnd)); + return GetPropertySheet().GetExteriorPageTitleFont(); + } + + HFONT GetBulletFont(void) + { + ATLASSERT(::IsWindow(m_hWnd)); + return GetPropertySheet().GetBulletFont(); + } + +// Implementation - overrides to prevent usage + HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL) + { + ATLASSERT(FALSE); + return NULL; + } + +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CWizard97PageImpl - implements a Wizard 97 style wizard page + +template +class ATL_NO_VTABLE CWizard97PageImpl : public CPropertyPageImpl< T, TBase > +{ +protected: +// Typedefs + typedef CWizard97PageImpl< T, TBase > thisClass; + typedef CPropertyPageImpl< T, TBase > baseClass; + +public: + CWizard97PageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : baseClass(title) + { } + +// Message Handling + BEGIN_MSG_MAP(thisClass) + CHAIN_MSG_MAP(baseClass) + END_MSG_MAP() +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CWizard97ExteriorPageImpl - implements a Wizard 97 style exterior wizard page + +template +class ATL_NO_VTABLE CWizard97ExteriorPageImpl : public CPropertyPageImpl< T, TBase > +{ +protected: +// Typedefs + typedef CWizard97ExteriorPageImpl< T, TBase > thisClass; + typedef CPropertyPageImpl< T, TBase > baseClass; + +public: +// Constructors + CWizard97ExteriorPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : baseClass(title) + { + m_psp.dwFlags |= PSP_HASHELP; + m_psp.dwFlags |= PSP_HIDEHEADER; + } + +// Message Handling + BEGIN_MSG_MAP(thisClass) + CHAIN_MSG_MAP(baseClass) + END_MSG_MAP() +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CWizard97InteriorPageImpl - implements a Wizard 97 style interior wizard page + +template +class ATL_NO_VTABLE CWizard97InteriorPageImpl : public CPropertyPageImpl< T, TBase > +{ +protected: +// Typedefs + typedef CWizard97InteriorPageImpl< T, TBase > thisClass; + typedef CPropertyPageImpl< T, TBase > baseClass; + +public: +// Constructors + CWizard97InteriorPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : baseClass(title) + { + m_psp.dwFlags |= PSP_HASHELP; + m_psp.dwFlags &= ~PSP_HIDEHEADER; + m_psp.dwFlags |= PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; + + // Be sure to have the derived class define this in the constructor. + // We'll default it to something obvious in case its forgotten. + baseClass::SetHeaderTitle(_T("Call SetHeaderTitle in Derived Class")); + baseClass::SetHeaderSubTitle(_T("Call SetHeaderSubTitle in the constructor of the Derived Class.")); + } + +// Message Handling + BEGIN_MSG_MAP(thisClass) + CHAIN_MSG_MAP(baseClass) + END_MSG_MAP() +}; + +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + + +/////////////////////////////////////////////////////////////////////////////// +// Aero Wizard support + +#if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) + +/////////////////////////////////////////////////////////////////////////////// +// CAeroWizardFrameWindow - client side for an Aero Wizard frame window + +class CAeroWizardFrameWindow : public CPropertySheetWindow +{ +public: +// Constructors + CAeroWizardFrameWindow(HWND hWnd = NULL) : CPropertySheetWindow(hWnd) + { } + + CAeroWizardFrameWindow& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + +// Operations - new, Aero Wizard only + void SetNextText(LPCWSTR lpszText) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, PSM_SETNEXTTEXT, 0, (LPARAM)lpszText); + } + + void ShowWizardButtons(DWORD dwButtons, DWORD dwStates) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::PostMessage(m_hWnd, PSM_SHOWWIZBUTTONS, (WPARAM)dwStates, (LPARAM)dwButtons); + } + + void EnableWizardButtons(DWORD dwButtons, DWORD dwStates) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::PostMessage(m_hWnd, PSM_ENABLEWIZBUTTONS, (WPARAM)dwStates, (LPARAM)dwButtons); + } + + void SetButtonText(DWORD dwButton, LPCWSTR lpszText) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, PSM_SETBUTTONTEXT, (WPARAM)dwButton, (LPARAM)lpszText); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CAeroWizardFrameImpl - implements an Aero Wizard frame + +template +class ATL_NO_VTABLE CAeroWizardFrameImpl : public CPropertySheetImpl +{ +public: +// Constructor + CAeroWizardFrameImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL) : + CPropertySheetImpl(title, uStartPage, hWndParent) + { + m_psh.dwFlags |= PSH_WIZARD | PSH_AEROWIZARD; + } + +// Operations + void EnableResizing() + { + ATLASSERT(m_hWnd == NULL); // can't do this after it's created + m_psh.dwFlags |= PSH_RESIZABLE; + } + + void UseHeaderBitmap() + { + ATLASSERT(m_hWnd == NULL); // can't do this after it's created + m_psh.dwFlags |= PSH_HEADERBITMAP; + } + + void SetNoMargin() + { + ATLASSERT(m_hWnd == NULL); // can't do this after it's created + m_psh.dwFlags |= PSH_NOMARGIN; + } + +// Override to prevent use + HWND Create(HWND /*hWndParent*/ = NULL) + { + ATLASSERT(FALSE); // not supported for Aero Wizard + return NULL; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CAeroWizardFrame - for non-customized frames + +class CAeroWizardFrame : public CAeroWizardFrameImpl +{ +public: + CAeroWizardFrame(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL) + : CAeroWizardFrameImpl(title, uStartPage, hWndParent) + { } + + BEGIN_MSG_MAP(CAeroWizardFrame) + MESSAGE_HANDLER(WM_COMMAND, CAeroWizardFrameImpl::OnCommand) + END_MSG_MAP() +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CAeroWizardPageWindow - client side for an Aero Wizard page + +class CAeroWizardPageWindow : public CPropertyPageWindow +{ +public: +// Constructors + CAeroWizardPageWindow(HWND hWnd = NULL) : CPropertyPageWindow(hWnd) + { } + + CAeroWizardPageWindow& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + +// Attributes + CAeroWizardFrameWindow GetAeroWizardFrame() const + { + ATLASSERT(::IsWindow(m_hWnd)); + // This is not really top-level frame window, but it processes all frame messages + return CAeroWizardFrameWindow(GetParent()); + } + +// Operations - new, Aero Wizard only + void SetNextText(LPCWSTR lpszText) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetParent() != NULL); + GetAeroWizardFrame().SetNextText(lpszText); + } + + void ShowWizardButtons(DWORD dwButtons, DWORD dwStates) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetParent() != NULL); + GetAeroWizardFrame().ShowWizardButtons(dwButtons, dwStates); + } + + void EnableWizardButtons(DWORD dwButtons, DWORD dwStates) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetParent() != NULL); + GetAeroWizardFrame().EnableWizardButtons(dwButtons, dwStates); + } + + void SetButtonText(DWORD dwButton, LPCWSTR lpszText) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetParent() != NULL); + GetAeroWizardFrame().SetButtonText(dwButton, lpszText); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CAeroWizardPageImpl - implements an Aero Wizard page + +template +class ATL_NO_VTABLE CAeroWizardPageImpl : public CPropertyPageImpl +{ +public: + CAeroWizardPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CPropertyPageImpl(title) + { } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CAeroWizardPage - for non-customized pages + +template +class CAeroWizardPage : public CAeroWizardPageImpl > +{ +public: + enum { IDD = t_wDlgTemplateID }; + + CAeroWizardPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAeroWizardPageImpl(title) + { } + + DECLARE_EMPTY_MSG_MAP() +}; + + +#ifndef _ATL_NO_HOSTING + +// Note: You must #include to use these classes + +/////////////////////////////////////////////////////////////////////////////// +// CAeroWizardAxPageImpl - Aero Wizard page that hosts ActiveX controls + +template +class ATL_NO_VTABLE CAeroWizardAxPageImpl : public CAxPropertyPageImpl< T, TBase > +{ +public: + CAeroWizardAxPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAxPropertyPageImpl< T, TBase >(title) + { } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CAeroWizardAxPage - for non-customized pages + +template +class CAeroWizardAxPage : public CAeroWizardAxPageImpl > +{ +public: + enum { IDD = t_wDlgTemplateID }; + + CAeroWizardAxPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAeroWizardAxPageImpl(title) + { } + +#if (_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700) + // not empty so we handle accelerators/create controls + BEGIN_MSG_MAP(CAeroWizardAxPage) + CHAIN_MSG_MAP(CAeroWizardAxPageImpl >) + END_MSG_MAP() +#else // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)) + DECLARE_EMPTY_MSG_MAP() +#endif // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)) +}; + +#endif // _ATL_NO_HOSTING + +#endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) + + +/////////////////////////////////////////////////////////////////////////////// +// TaskDialog support + +#if ((_WIN32_WINNT >= 0x0600) || defined(_WTL_TASKDIALOG)) && !defined(_WIN32_WCE) + +/////////////////////////////////////////////////////////////////////////////// +// AtlTaskDialog - support for TaskDialog() function + +inline int AtlTaskDialog(HWND hWndParent, + ATL::_U_STRINGorID WindowTitle, ATL::_U_STRINGorID MainInstructionText, ATL::_U_STRINGorID ContentText, + TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons = 0U, ATL::_U_STRINGorID Icon = (LPCTSTR)NULL) +{ + int nRet = -1; + +#ifdef _WTL_TASKDIALOG_DIRECT + USES_CONVERSION; + HRESULT hRet = ::TaskDialog(hWndParent, ModuleHelper::GetResourceInstance(), + IS_INTRESOURCE(WindowTitle.m_lpstr) ? (LPCWSTR) WindowTitle.m_lpstr : T2CW(WindowTitle.m_lpstr), + IS_INTRESOURCE(MainInstructionText.m_lpstr) ? (LPCWSTR) MainInstructionText.m_lpstr : T2CW(MainInstructionText.m_lpstr), + IS_INTRESOURCE(ContentText.m_lpstr) ? (LPCWSTR) ContentText.m_lpstr : T2CW(ContentText.m_lpstr), + dwCommonButtons, + IS_INTRESOURCE(Icon.m_lpstr) ? (LPCWSTR) Icon.m_lpstr : T2CW(Icon.m_lpstr), + &nRet); + ATLVERIFY(SUCCEEDED(hRet)); +#else + // This allows apps to run on older versions of Windows + typedef HRESULT (STDAPICALLTYPE *PFN_TaskDialog)(HWND hwndParent, HINSTANCE hInstance, PCWSTR pszWindowTitle, PCWSTR pszMainInstruction, PCWSTR pszContent, TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons, PCWSTR pszIcon, int* pnButton); + + HMODULE m_hCommCtrlDLL = ::LoadLibrary(_T("comctl32.dll")); + if(m_hCommCtrlDLL != NULL) + { + PFN_TaskDialog pfnTaskDialog = (PFN_TaskDialog)::GetProcAddress(m_hCommCtrlDLL, "TaskDialog"); + if(pfnTaskDialog != NULL) + { + USES_CONVERSION; + HRESULT hRet = pfnTaskDialog(hWndParent, ModuleHelper::GetResourceInstance(), + IS_INTRESOURCE(WindowTitle.m_lpstr) ? (LPCWSTR) WindowTitle.m_lpstr : T2CW(WindowTitle.m_lpstr), + IS_INTRESOURCE(MainInstructionText.m_lpstr) ? (LPCWSTR) MainInstructionText.m_lpstr : T2CW(MainInstructionText.m_lpstr), + IS_INTRESOURCE(ContentText.m_lpstr) ? (LPCWSTR) ContentText.m_lpstr : T2CW(ContentText.m_lpstr), + dwCommonButtons, + IS_INTRESOURCE(Icon.m_lpstr) ? (LPCWSTR) Icon.m_lpstr : T2CW(Icon.m_lpstr), + &nRet); + ATLVERIFY(SUCCEEDED(hRet)); + } + + ::FreeLibrary(m_hCommCtrlDLL); + } +#endif + + return nRet; +} + + +/////////////////////////////////////////////////////////////////////////////// +// CTaskDialogConfig - TASKDIALOGCONFIG wrapper + +class CTaskDialogConfig : public TASKDIALOGCONFIG +{ +public: +// Constructor + CTaskDialogConfig() + { + Init(); + } + + void Init() + { + memset(this, 0, sizeof(TASKDIALOGCONFIG)); // initialize structure to 0/NULL + this->cbSize = sizeof(TASKDIALOGCONFIG); + this->hInstance = ModuleHelper::GetResourceInstance(); + } + +// Operations - setting values + // common buttons + void SetCommonButtons(TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons) + { + this->dwCommonButtons = dwCommonButtons; + } + + // window title text + void SetWindowTitle(UINT nID) + { + this->pszWindowTitle = MAKEINTRESOURCEW(nID); + } + + void SetWindowTitle(LPCWSTR lpstrWindowTitle) + { + this->pszWindowTitle = lpstrWindowTitle; + } + + // main icon + void SetMainIcon(HICON hIcon) + { + this->dwFlags |= TDF_USE_HICON_MAIN; + this->hMainIcon = hIcon; + } + + void SetMainIcon(UINT nID) + { + this->dwFlags &= ~TDF_USE_HICON_MAIN; + this->pszMainIcon = MAKEINTRESOURCEW(nID); + } + + void SetMainIcon(LPCWSTR lpstrMainIcon) + { + this->dwFlags &= ~TDF_USE_HICON_MAIN; + this->pszMainIcon = lpstrMainIcon; + } + + // main instruction text + void SetMainInstructionText(UINT nID) + { + this->pszMainInstruction = MAKEINTRESOURCEW(nID); + } + + void SetMainInstructionText(LPCWSTR lpstrMainInstruction) + { + this->pszMainInstruction = lpstrMainInstruction; + } + + // content text + void SetContentText(UINT nID) + { + this->pszContent = MAKEINTRESOURCEW(nID); + } + + void SetContentText(LPCWSTR lpstrContent) + { + this->pszContent = lpstrContent; + } + + // buttons + void SetButtons(const TASKDIALOG_BUTTON* pButtons, UINT cButtons, int nDefaultButton = 0) + { + this->pButtons = pButtons; + this->cButtons = cButtons; + if(nDefaultButton != 0) + this->nDefaultButton = nDefaultButton; + } + + void SetDefaultButton(int nDefaultButton) + { + this->nDefaultButton = nDefaultButton; + } + + // radio buttons + void SetRadioButtons(const TASKDIALOG_BUTTON* pRadioButtons, UINT cRadioButtons, int nDefaultRadioButton = 0) + { + this->pRadioButtons = pRadioButtons; + this->cRadioButtons = cRadioButtons; + if(nDefaultRadioButton != 0) + this->nDefaultRadioButton = nDefaultRadioButton; + } + + void SetDefaultRadioButton(int nDefaultRadioButton) + { + this->nDefaultRadioButton = nDefaultRadioButton; + } + + // verification text + void SetVerificationText(UINT nID) + { + this->pszVerificationText = MAKEINTRESOURCEW(nID); + } + + void SetVerificationText(LPCWSTR lpstrVerificationText) + { + this->pszVerificationText = lpstrVerificationText; + } + + // expanded information text + void SetExpandedInformationText(UINT nID) + { + this->pszExpandedInformation = MAKEINTRESOURCEW(nID); + } + + void SetExpandedInformationText(LPCWSTR lpstrExpandedInformation) + { + this->pszExpandedInformation = lpstrExpandedInformation; + } + + // expanded control text + void SetExpandedControlText(UINT nID) + { + this->pszExpandedControlText = MAKEINTRESOURCEW(nID); + } + + void SetExpandedControlText(LPCWSTR lpstrExpandedControlText) + { + this->pszExpandedControlText = lpstrExpandedControlText; + } + + // collapsed control text + void SetCollapsedControlText(UINT nID) + { + this->pszCollapsedControlText = MAKEINTRESOURCEW(nID); + } + + void SetCollapsedControlText(LPCWSTR lpstrCollapsedControlText) + { + this->pszCollapsedControlText = lpstrCollapsedControlText; + } + + // footer icon + void SetFooterIcon(HICON hIcon) + { + this->dwFlags |= TDF_USE_HICON_FOOTER; + this->hFooterIcon = hIcon; + } + + void SetFooterIcon(UINT nID) + { + this->dwFlags &= ~TDF_USE_HICON_FOOTER; + this->pszFooterIcon = MAKEINTRESOURCEW(nID); + } + + void SetFooterIcon(LPCWSTR lpstrFooterIcon) + { + this->dwFlags &= ~TDF_USE_HICON_FOOTER; + this->pszFooterIcon = lpstrFooterIcon; + } + + // footer text + void SetFooterText(UINT nID) + { + this->pszFooter = MAKEINTRESOURCEW(nID); + } + + void SetFooterText(LPCWSTR lpstrFooterText) + { + this->pszFooter = lpstrFooterText; + } + + // width (in DLUs) + void SetWidth(UINT cxWidth) + { + this->cxWidth = cxWidth; + } + + // modify flags + void ModifyFlags(DWORD dwRemove, DWORD dwAdd) + { + this->dwFlags = (this->dwFlags & ~dwRemove) | dwAdd; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CTaskDialogImpl - implements a Task Dialog + +template +class ATL_NO_VTABLE CTaskDialogImpl +{ +public: + CTaskDialogConfig m_tdc; + HWND m_hWnd; // used only in callback functions + +// Constructor + CTaskDialogImpl(HWND hWndParent = NULL) : m_hWnd(NULL) + { + m_tdc.hwndParent = hWndParent; + m_tdc.pfCallback = T::TaskDialogCallback; + m_tdc.lpCallbackData = (LONG_PTR)static_cast(this); + } + +// Operations + HRESULT DoModal(HWND hWndParent = ::GetActiveWindow(), int* pnButton = NULL, int* pnRadioButton = NULL, BOOL* pfVerificationFlagChecked = NULL) + { + if(m_tdc.hwndParent == NULL) + m_tdc.hwndParent = hWndParent; + +#ifdef _WTL_TASKDIALOG_DIRECT + return ::TaskDialogIndirect(&m_tdc, pnButton, pnRadioButton, pfVerificationFlagChecked); +#else + + // This allows apps to run on older versions of Windows + typedef HRESULT (STDAPICALLTYPE *PFN_TaskDialogIndirect)(const TASKDIALOGCONFIG* pTaskConfig, int* pnButton, int* pnRadioButton, BOOL* pfVerificationFlagChecked); + + HRESULT hRet = E_UNEXPECTED; + HMODULE m_hCommCtrlDLL = ::LoadLibrary(_T("comctl32.dll")); + if(m_hCommCtrlDLL != NULL) + { + PFN_TaskDialogIndirect pfnTaskDialogIndirect = (PFN_TaskDialogIndirect)::GetProcAddress(m_hCommCtrlDLL, "TaskDialogIndirect"); + if(pfnTaskDialogIndirect != NULL) + hRet = pfnTaskDialogIndirect(&m_tdc, pnButton, pnRadioButton, pfVerificationFlagChecked); + + ::FreeLibrary(m_hCommCtrlDLL); + } + + return hRet; +#endif + } + +// Operations - setting values of TASKDIALOGCONFIG + // common buttons + void SetCommonButtons(TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons) + { m_tdc.SetCommonButtons(dwCommonButtons); } + // window title text + void SetWindowTitle(UINT nID) + { m_tdc.SetWindowTitle(nID); } + void SetWindowTitle(LPCWSTR lpstrWindowTitle) + { m_tdc.SetWindowTitle(lpstrWindowTitle); } + // main icon + void SetMainIcon(HICON hIcon) + { m_tdc.SetMainIcon(hIcon); } + void SetMainIcon(UINT nID) + { m_tdc.SetMainIcon(nID); } + void SetMainIcon(LPCWSTR lpstrMainIcon) + { m_tdc.SetMainIcon(lpstrMainIcon); } + // main instruction text + void SetMainInstructionText(UINT nID) + { m_tdc.SetMainInstructionText(nID); } + void SetMainInstructionText(LPCWSTR lpstrMainInstruction) + { m_tdc.SetMainInstructionText(lpstrMainInstruction); } + // content text + void SetContentText(UINT nID) + { m_tdc.SetContentText(nID); } + void SetContentText(LPCWSTR lpstrContent) + { m_tdc.SetContentText(lpstrContent); } + // buttons + void SetButtons(const TASKDIALOG_BUTTON* pButtons, UINT cButtons, int nDefaultButton = 0) + { m_tdc.SetButtons(pButtons, cButtons, nDefaultButton); } + void SetDefaultButton(int nDefaultButton) + { m_tdc.SetDefaultButton(nDefaultButton); } + // radio buttons + void SetRadioButtons(const TASKDIALOG_BUTTON* pRadioButtons, UINT cRadioButtons, int nDefaultRadioButton = 0) + { m_tdc.SetRadioButtons(pRadioButtons, cRadioButtons, nDefaultRadioButton); } + void SetDefaultRadioButton(int nDefaultRadioButton) + { m_tdc.SetDefaultRadioButton(nDefaultRadioButton); } + // verification text + void SetVerificationText(UINT nID) + { m_tdc.SetVerificationText(nID); } + void SetVerificationText(LPCWSTR lpstrVerificationText) + { m_tdc.SetVerificationText(lpstrVerificationText); } + // expanded information text + void SetExpandedInformationText(UINT nID) + { m_tdc.SetExpandedInformationText(nID); } + void SetExpandedInformationText(LPCWSTR lpstrExpandedInformation) + { m_tdc.SetExpandedInformationText(lpstrExpandedInformation); } + // expanded control text + void SetExpandedControlText(UINT nID) + { m_tdc.SetExpandedControlText(nID); } + void SetExpandedControlText(LPCWSTR lpstrExpandedControlText) + { m_tdc.SetExpandedControlText(lpstrExpandedControlText); } + // collapsed control text + void SetCollapsedControlText(UINT nID) + { m_tdc.SetCollapsedControlText(nID); } + void SetCollapsedControlText(LPCWSTR lpstrCollapsedControlText) + { m_tdc.SetCollapsedControlText(lpstrCollapsedControlText); } + // footer icon + void SetFooterIcon(HICON hIcon) + { m_tdc.SetFooterIcon(hIcon); } + void SetFooterIcon(UINT nID) + { m_tdc.SetFooterIcon(nID); } + void SetFooterIcon(LPCWSTR lpstrFooterIcon) + { m_tdc.SetFooterIcon(lpstrFooterIcon); } + // footer text + void SetFooterText(UINT nID) + { m_tdc.SetFooterText(nID); } + void SetFooterText(LPCWSTR lpstrFooterText) + { m_tdc.SetFooterText(lpstrFooterText); } + // width (in DLUs) + void SetWidth(UINT cxWidth) + { m_tdc.SetWidth(cxWidth); } + // modify flags + void ModifyFlags(DWORD dwRemove, DWORD dwAdd) + { m_tdc.ModifyFlags(dwRemove, dwAdd); } + +// Implementation + static HRESULT CALLBACK TaskDialogCallback(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData) + { + T* pT = (T*)lpRefData; + ATLASSERT(pT->m_hWnd == NULL || pT->m_hWnd == hWnd); + + BOOL bRet = FALSE; + switch(uMsg) + { + case TDN_DIALOG_CONSTRUCTED: + pT->m_hWnd = hWnd; + pT->OnDialogConstructed(); + break; + case TDN_CREATED: + pT->OnCreated(); + break; + case TDN_BUTTON_CLICKED: + bRet = pT->OnButtonClicked((int)wParam); + break; + case TDN_RADIO_BUTTON_CLICKED: + pT->OnRadioButtonClicked((int)wParam); + break; + case TDN_HYPERLINK_CLICKED: + pT->OnHyperlinkClicked((LPCWSTR)lParam); + break; + case TDN_EXPANDO_BUTTON_CLICKED: + pT->OnExpandoButtonClicked((wParam != 0)); + break; + case TDN_VERIFICATION_CLICKED: + pT->OnVerificationClicked((wParam != 0)); + break; + case TDN_HELP: + pT->OnHelp(); + break; + case TDN_TIMER: + bRet = pT->OnTimer((DWORD)wParam); + break; + case TDN_NAVIGATED: + pT->OnNavigated(); + break; + case TDN_DESTROYED: + pT->OnDestroyed(); + pT->m_hWnd = NULL; + break; + default: + ATLTRACE2(atlTraceUI, 0, _T("Unknown notification received in CTaskDialogImpl::TaskDialogCallback\n")); + break; + } + + return (HRESULT)bRet; + } + +// Overrideables - notification handlers + void OnDialogConstructed() + { + } + + void OnCreated() + { + } + + BOOL OnButtonClicked(int /*nButton*/) + { + return FALSE; // don't prevent dialog to close + } + + void OnRadioButtonClicked(int /*nRadioButton*/) + { + } + + void OnHyperlinkClicked(LPCWSTR /*pszHREF*/) + { + } + + void OnExpandoButtonClicked(bool /*bExpanded*/) + { + } + + void OnVerificationClicked(bool /*bChecked*/) + { + } + + void OnHelp() + { + } + + BOOL OnTimer(DWORD /*dwTickCount*/) + { + return FALSE; // don't reset counter + } + + void OnNavigated() + { + } + + void OnDestroyed() + { + } + +// Commands - valid to call only from handlers + void NavigatePage(TASKDIALOGCONFIG& tdc) + { + ATLASSERT(m_hWnd != NULL); + + tdc.cbSize = sizeof(TASKDIALOGCONFIG); + if(tdc.hwndParent == NULL) + tdc.hwndParent = m_tdc.hwndParent; + tdc.pfCallback = m_tdc.pfCallback; + tdc.lpCallbackData = m_tdc.lpCallbackData; + (TASKDIALOGCONFIG)m_tdc = tdc; + + ::SendMessage(m_hWnd, TDM_NAVIGATE_PAGE, 0, (LPARAM)&tdc); + } + + // modify TASKDIALOGCONFIG values, then call this to update task dialog + void NavigatePage() + { + ATLASSERT(m_hWnd != NULL); + ::SendMessage(m_hWnd, TDM_NAVIGATE_PAGE, 0, (LPARAM)&m_tdc); + } + + void ClickButton(int nButton) + { + ATLASSERT(m_hWnd != NULL); + ::SendMessage(m_hWnd, TDM_CLICK_BUTTON, nButton, 0L); + } + + void SetMarqueeProgressBar(BOOL bMarquee) + { + ATLASSERT(m_hWnd != NULL); + ::SendMessage(m_hWnd, TDM_SET_MARQUEE_PROGRESS_BAR, bMarquee, 0L); + } + + BOOL SetProgressBarState(int nNewState) + { + ATLASSERT(m_hWnd != NULL); + return (BOOL)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_STATE, nNewState, 0L); + } + + DWORD SetProgressBarRange(int nMinRange, int nMaxRange) + { + ATLASSERT(m_hWnd != NULL); + return (DWORD)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_RANGE, 0, MAKELPARAM(nMinRange, nMaxRange)); + } + + int SetProgressBarPos(int nNewPos) + { + ATLASSERT(m_hWnd != NULL); + return (int)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_POS, nNewPos, 0L); + } + + BOOL SetProgressBarMarquee(BOOL bMarquee, UINT uSpeed) + { + ATLASSERT(m_hWnd != NULL); + return (BOOL)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_MARQUEE, bMarquee, uSpeed); + } + + void SetElementText(TASKDIALOG_ELEMENTS element, LPCWSTR lpstrText) + { + ATLASSERT(m_hWnd != NULL); + ::SendMessage(m_hWnd, TDM_SET_ELEMENT_TEXT, element, (LPARAM)lpstrText); + } + + void ClickRadioButton(int nRadioButton) + { + ATLASSERT(m_hWnd != NULL); + ::SendMessage(m_hWnd, TDM_CLICK_RADIO_BUTTON, nRadioButton, 0L); + } + + void EnableButton(int nButton, BOOL bEnable) + { + ATLASSERT(m_hWnd != NULL); + ::SendMessage(m_hWnd, TDM_ENABLE_BUTTON, nButton, bEnable); + } + + void EnableRadioButton(int nButton, BOOL bEnable) + { + ATLASSERT(m_hWnd != NULL); + ::SendMessage(m_hWnd, TDM_ENABLE_RADIO_BUTTON, nButton, bEnable); + } + + void ClickVerification(BOOL bCheck, BOOL bFocus) + { + ATLASSERT(m_hWnd != NULL); + ::SendMessage(m_hWnd, TDM_CLICK_VERIFICATION, bCheck, bFocus); + } + + void UpdateElementText(TASKDIALOG_ELEMENTS element, LPCWSTR lpstrText) + { + ATLASSERT(m_hWnd != NULL); + ::SendMessage(m_hWnd, TDM_UPDATE_ELEMENT_TEXT, element, (LPARAM)lpstrText); + } + + void SetButtonElevationRequiredState(int nButton, BOOL bElevation) + { + ATLASSERT(m_hWnd != NULL); + ::SendMessage(m_hWnd, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, nButton, bElevation); + } + + void UpdateIcon(TASKDIALOG_ICON_ELEMENTS element, HICON hIcon) + { + ATLASSERT(m_hWnd != NULL); +#ifdef _DEBUG + if(element == TDIE_ICON_MAIN) + ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_MAIN) != 0); + else if(element == TDIE_ICON_FOOTER) + ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_FOOTER) != 0); +#endif // _DEBUG + ::SendMessage(m_hWnd, TDM_UPDATE_ICON, element, (LPARAM)hIcon); + } + + void UpdateIcon(TASKDIALOG_ICON_ELEMENTS element, LPCWSTR lpstrIcon) + { + ATLASSERT(m_hWnd != NULL); +#ifdef _DEBUG + if(element == TDIE_ICON_MAIN) + ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_MAIN) == 0); + else if(element == TDIE_ICON_FOOTER) + ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_FOOTER) == 0); +#endif // _DEBUG + ::SendMessage(m_hWnd, TDM_UPDATE_ICON, element, (LPARAM)lpstrIcon); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CTaskDialog - for non-customized task dialogs + +class CTaskDialog : public CTaskDialogImpl +{ +public: + CTaskDialog(HWND hWndParent = NULL) : CTaskDialogImpl(hWndParent) + { + m_tdc.pfCallback = NULL; + } +}; + +#endif // ((_WIN32_WINNT >= 0x0600) || defined(_WTL_TASKDIALOG)) && !defined(_WIN32_WCE) + +}; // namespace WTL + +#endif // __ATLDLGS_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atldwm.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atldwm.h new file mode 100644 index 0000000000..fea8254827 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atldwm.h @@ -0,0 +1,461 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLDWM_H__ +#define __ATLDWM_H__ + +#pragma once + +#ifdef _WIN32_WCE + #error atldwm.h is not supported on Windows CE +#endif + +#ifndef __ATLAPP_H__ + #error atldwm.h requires atlapp.h to be included first +#endif + +#ifndef __ATLWIN_H__ + #error atldwm.h requires atlwin.h to be included first +#endif + +#if (_WIN32_WINNT < 0x0600) + #error atldwm.h requires _WIN32_WINNT >= 0x0600 +#endif // (_WIN32_WINNT < 0x0600) + +#ifndef _DWMAPI_H_ +#include +#endif // _DWMAPI_H_ +#pragma comment(lib, "dwmapi.lib") + +// Note: To create an application that also runs on older versions of Windows, +// use delay load of dwmapi.dll and ensure that no calls to the DWM API are +// Delay load is NOT AUTOMATIC for VC++ 7, you have to link to delayimp.lib, +// and add dwmapi.dll in the Linker.Input.Delay Loaded DLLs section of the +// project properties. +#if (_MSC_VER < 1300) && !defined(_WTL_NO_DWMAPI_DELAYLOAD) + #pragma comment(lib, "delayimp.lib") + #pragma comment(linker, "/delayload:dwmapi.dll") +#endif // (_MSC_VER < 1300) && !defined(_WTL_NO_DWMAPI_DELAYLOAD) + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CDwm +// CDwmImpl +// CDwmWindowT - CDwmWindow +// CDwmThumbnailT +// CDwmThumbnail +// CDwmThumbnailHandle +// CAeroControlImpl + + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// CDwm - wrapper for DWM handle + +class CDwm +{ +public: +// Data members + static int m_nIsDwmSupported; + +// Constructor + CDwm() + { + IsDwmSupported(); + } + +// Dwm support helper + static bool IsDwmSupported() + { + if(m_nIsDwmSupported == -1) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CDwm::IsDwmSupported.\n")); + ATLASSERT(FALSE); + return false; + } + + if(m_nIsDwmSupported == -1) + { + HMODULE hDwmDLL = ::LoadLibrary(_T("dwmapi.dll")); + m_nIsDwmSupported = (hDwmDLL != NULL) ? 1 : 0; + if(hDwmDLL != NULL) + ::FreeLibrary(hDwmDLL); + } + + lock.Unlock(); + } + + ATLASSERT(m_nIsDwmSupported != -1); + return (m_nIsDwmSupported == 1); + } + +// Operations + BOOL DwmIsCompositionEnabled() const + { + if(!IsDwmSupported()) return FALSE; + BOOL bRes = FALSE; + return SUCCEEDED(::DwmIsCompositionEnabled(&bRes)) && bRes; + } + + BOOL DwmEnableComposition(UINT fEnable) + { + if(!IsDwmSupported()) return FALSE; + return SUCCEEDED(::DwmEnableComposition(fEnable)); + } + + BOOL DwmEnableMMCSS(BOOL fEnableMMCSS) + { + if(!IsDwmSupported()) return FALSE; + return SUCCEEDED(::DwmEnableMMCSS(fEnableMMCSS)); + } + + HRESULT DwmGetColorizationColor(DWORD* pcrColorization, BOOL* pfOpaqueBlend) + { + if(!IsDwmSupported()) return E_NOTIMPL; + return ::DwmGetColorizationColor(pcrColorization, pfOpaqueBlend); + } + + HRESULT DwmFlush() + { + if(!IsDwmSupported()) return E_NOTIMPL; + return ::DwmFlush(); + } +}; + +__declspec(selectany) int CDwm::m_nIsDwmSupported = -1; + + +/////////////////////////////////////////////////////////////////////////////// +// CDwmImpl - DWM window support + +template +class CDwmImpl : public TBase +{ +public: + HRESULT DwmEnableBlurBehindWindow(const DWM_BLURBEHIND* pBB) + { + if(!IsDwmSupported()) return E_NOTIMPL; + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::DwmEnableBlurBehindWindow(pT->m_hWnd, pBB); + } + + HRESULT DwmExtendFrameIntoClientArea(const MARGINS* pMargins) + { + if(!IsDwmSupported()) return E_NOTIMPL; + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::DwmExtendFrameIntoClientArea(pT->m_hWnd, pMargins); + } + + HRESULT DwmExtendFrameIntoEntireClientArea() + { + MARGINS margins = { -1 }; + return DwmExtendFrameIntoClientArea(&margins); + } + + HRESULT DwmGetCompositionTimingInfo(DWM_TIMING_INFO* pTimingInfo) + { + if(!IsDwmSupported()) return E_NOTIMPL; + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::DwmGetCompositionTimingInfo(pT->m_hWnd, pTimingInfo); + } + + HRESULT DwmGetWindowAttribute(DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute) + { + if(!IsDwmSupported()) return E_NOTIMPL; + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::DwmGetWindowAttribute(pT->m_hWnd, dwAttribute, pvAttribute, cbAttribute); + } + + HRESULT DwmModifyPreviousDxFrameDuration(INT cRefreshes, BOOL fRelative) + { + if(!IsDwmSupported()) return E_NOTIMPL; + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::DwmModifyPreviousDxFrameDuration(pT->m_hWnd, cRefreshes, fRelative); + } + + HRESULT DwmSetDxFrameDuration(INT cRefreshes) + { + if(!IsDwmSupported()) return E_NOTIMPL; + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::DwmSetDxFrameDuration(pT->m_hWnd, cRefreshes); + } + + HRESULT DwmSetPresentParameters(DWM_PRESENT_PARAMETERS* pPresentParams) + { + if(!IsDwmSupported()) return E_NOTIMPL; + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::DwmSetPresentParameters(pT->m_hWnd, pPresentParams); + } + + HRESULT DwmSetWindowAttribute(DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute) + { + if(!IsDwmSupported()) return E_NOTIMPL; + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::DwmSetWindowAttribute(pT->m_hWnd, dwAttribute, pvAttribute, cbAttribute); + } + + HRESULT DwmAttachMilContent() + { + if(!IsDwmSupported()) return E_NOTIMPL; + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::DwmAttachMilContent(pT->m_hWnd); + } + + HRESULT DwmDetachMilContent() + { + if(!IsDwmSupported()) return E_NOTIMPL; + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::DwmDetachMilContent(pT->m_hWnd); + } +}; + +template +class CDwmWindowT : public TBase, public CDwmImpl > +{ +public: + CDwmWindowT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CDwmWindowT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } +}; + +typedef CDwmWindowT CDwmWindow; + + +/////////////////////////////////////////////////////////////////////////////// +// CDwmThumbnail - provides DWM thumbnail support + +template +class CDwmThumbnailT : public TBase +{ +public: +// Data members + HTHUMBNAIL m_hThumbnail; + +// Constructor + CDwmThumbnailT(HTHUMBNAIL hThumbnail = NULL) : m_hThumbnail(hThumbnail) + { + } + + ~CDwmThumbnailT() + { + if(t_bManaged && m_hThumbnail != NULL) + Unregister(); + } + +// Operations + CDwmThumbnailT& operator =(HTHUMBNAIL hThumbnail) + { + Attach(hThumbnail); + return *this; + } + + void Attach(HTHUMBNAIL hThumbnailNew) + { + if(t_bManaged && m_hThumbnail != NULL && m_hThumbnail != hThumbnailNew) + Unregister(); + m_hThumbnail = hThumbnailNew; + } + + HTHUMBNAIL Detach() + { + HTHUMBNAIL hThumbnail = m_hThumbnail; + m_hThumbnail = NULL; + return hThumbnail; + } + + HRESULT Register(HWND hwndDestination, HWND hwndSource) + { + ATLASSERT(::IsWindow(hwndDestination)); + ATLASSERT(::IsWindow(hwndSource)); + ATLASSERT(m_hThumbnail==NULL); + if(!IsDwmSupported()) return E_NOTIMPL; + return ::DwmRegisterThumbnail(hwndDestination, hwndSource, &m_hThumbnail); + } + + HRESULT Unregister() + { + if(!IsDwmSupported()) return E_NOTIMPL; + if(m_hThumbnail == NULL) return S_FALSE; + HRESULT Hr = ::DwmUnregisterThumbnail(m_hThumbnail); + if(SUCCEEDED(Hr)) m_hThumbnail = NULL; + return Hr; + } + + operator HTHUMBNAIL() const { return m_hThumbnail; } + + bool IsNull() const { return (m_hThumbnail == NULL); } + + HRESULT UpdateProperties(const DWM_THUMBNAIL_PROPERTIES* ptnProperties) + { + if(!IsDwmSupported()) return E_NOTIMPL; + ATLASSERT(m_hThumbnail != NULL); + return ::DwmUpdateThumbnailProperties(m_hThumbnail, ptnProperties); + } + +// Attributes + HRESULT QuerySourceSize(PSIZE pSize) + { + if(!IsDwmSupported()) return E_NOTIMPL; + ATLASSERT(m_hThumbnail != NULL); + return ::DwmQueryThumbnailSourceSize(m_hThumbnail, pSize); + } +}; + +typedef CDwmThumbnailT CDwmThumbnail; +typedef CDwmThumbnailT CDwmThumbnailHandle; + + +#ifdef __ATLTHEME_H__ + +/////////////////////////////////////////////////////////////////////////////// +// CAeroControlImpl - Base class for controls on Glass + +template +class CAeroControlImpl : + public CThemeImpl, + public CBufferedPaintImpl, + public ATL::CWindowImpl +{ +public: + typedef CThemeImpl _themeClass; + typedef CBufferedPaintImpl _baseClass; + typedef ATL::CWindowImpl _windowClass; + + CAeroControlImpl() + { + m_PaintParams.dwFlags = BPPF_ERASE; + } + + static LPCWSTR GetThemeName() + { +#ifdef _UNICODE + return TBase::GetWndClassName(); +#else + ATLASSERT(!_T("Return UNICODE string of window classname / theme class")); + return NULL; +#endif // _UNICODE + } + +// Message map and handlers + BEGIN_MSG_MAP(CAeroControlImpl) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_ACTIVATE, OnActivate) + CHAIN_MSG_MAP(_themeClass) + CHAIN_MSG_MAP(_baseClass) + END_MSG_MAP() + + LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + T* pT = static_cast(this); + pT->Init(); + bHandled = FALSE; + return 0; + } + + LRESULT OnActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(IsThemingSupported()) Invalidate(FALSE); + bHandled = FALSE; + return 0; + } + +// Operations + BOOL SubclassWindow(HWND hWnd) + { + ATLASSERT(m_hWnd == NULL); + ATLASSERT(::IsWindow(hWnd)); + BOOL bRet = _windowClass::SubclassWindow(hWnd); + if(bRet) { + T* pT = static_cast(this); + pT->Init(); + } + return bRet; + } + +// Implementation + LRESULT DefWindowProc() + { + const _ATL_MSG* pMsg = m_pCurrentMsg; + LRESULT lRes = 0; + if(pMsg != NULL) + lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg->lParam); + return lRes; + } + + LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) + { + T* pT = static_cast(this); + LRESULT lRes = 0; + if( ::DwmDefWindowProc(pT->m_hWnd, uMsg, wParam, lParam, &lRes) ) return lRes; + return _windowClass::DefWindowProc(uMsg, wParam, lParam); + } + + void DoBufferedPaint(HDC hDC, RECT& rcPaint) + { + T* pT = static_cast(this); + HDC hDCPaint = NULL; + RECT rcClient = { 0 }; + GetClientRect(&rcClient); + m_BufferedPaint.Begin(hDC, &rcClient, m_dwFormat, &m_PaintParams, &hDCPaint); + ATLASSERT(hDCPaint != NULL); + pT->DoAeroPaint(hDCPaint, rcClient, rcPaint); + m_BufferedPaint.End(); + } + + void DoPaint(HDC /*hdc*/, RECT& /*rcClient*/) + { + DefWindowProc(); + } + +// Overridables + void Init() + { + T* pT = static_cast(this); + SetThemeClassList(pT->GetThemeName()); + if(m_lpstrThemeClassList != NULL) + OpenThemeData(); + } + + void DoAeroPaint(HDC hDC, RECT& /*rcClient*/, RECT& rcPaint) + { + DefWindowProc(WM_PAINT, (WPARAM) hDC, 0L); + m_BufferedPaint.MakeOpaque(&rcPaint); + } +}; + +#endif // __ATLTHEME_H__ + + +}; // namespace WTL + + +#endif // __ATLDWM_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlfind.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlfind.h new file mode 100644 index 0000000000..832aba204e --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlfind.h @@ -0,0 +1,1032 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLFIND_H__ +#define __ATLFIND_H__ + +#pragma once + +#ifdef _WIN32_WCE + #error atlfind.h is not supported on Windows CE +#endif + +#ifndef __ATLCTRLS_H__ + #error atlfind.h requires atlctrls.h to be included first +#endif + +#ifndef __ATLDLGS_H__ + #error atlfind.h requires atldlgs.h to be included first +#endif + +#if !((defined(__ATLMISC_H__) && defined(_WTL_USE_CSTRING)) || defined(__ATLSTR_H__)) + #error atlfind.h requires CString (either from ATL's atlstr.h or WTL's atlmisc.h with _WTL_USE_CSTRING) +#endif + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CEditFindReplaceImplBase +// CEditFindReplaceImpl +// CRichEditFindReplaceImpl + + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// CEditFindReplaceImplBase - Base class for mixin classes that +// help implement Find/Replace for CEdit or CRichEditCtrl based window classes. + +template +class CEditFindReplaceImplBase +{ +protected: +// Typedefs + typedef CEditFindReplaceImplBase thisClass; + +// Data members + TFindReplaceDialog* m_pFindReplaceDialog; + _CSTRING_NS::CString m_sFindNext, m_sReplaceWith; + BOOL m_bFindOnly, m_bFirstSearch, m_bMatchCase, m_bWholeWord, m_bFindDown; + LONG m_nInitialSearchPos; + HCURSOR m_hOldCursor; + +// Enumerations + enum TranslationTextItem + { + eText_OnReplaceAllMessage = 0, + eText_OnReplaceAllTitle = 1, + eText_OnTextNotFoundMessage = 2, + eText_OnTextNotFoundTitle = 3 + }; + +public: +// Constructors + CEditFindReplaceImplBase() : + m_pFindReplaceDialog(NULL), + m_bFindOnly(TRUE), + m_bFirstSearch(TRUE), + m_bMatchCase(FALSE), + m_bWholeWord(FALSE), + m_bFindDown(TRUE), + m_nInitialSearchPos(0), + m_hOldCursor(NULL) + { + } + +// Message Handlers + BEGIN_MSG_MAP(thisClass) + ALT_MSG_MAP(1) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_HANDLER(TFindReplaceDialog::GetFindReplaceMsg(), OnFindReplaceCmd) + COMMAND_ID_HANDLER(ID_EDIT_FIND, OnEditFind) + COMMAND_ID_HANDLER(ID_EDIT_REPEAT, OnEditRepeat) + COMMAND_ID_HANDLER(ID_EDIT_REPLACE, OnEditReplace) + END_MSG_MAP() + + LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_pFindReplaceDialog != NULL) + { + m_pFindReplaceDialog->SendMessage(WM_CLOSE); + ATLASSERT(m_pFindReplaceDialog == NULL); + } + + bHandled = FALSE; + return 0; + } + + LRESULT OnFindReplaceCmd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + + TFindReplaceDialog* pDialog = TFindReplaceDialog::GetNotifier(lParam); + if(pDialog == NULL) + { + ATLASSERT(FALSE); + ::MessageBeep(MB_ICONERROR); + return 1; + } + ATLASSERT(pDialog == m_pFindReplaceDialog); + + LPFINDREPLACE findReplace = (LPFINDREPLACE)lParam; + if((m_pFindReplaceDialog != NULL) && (findReplace != NULL)) + { + if(pDialog->FindNext()) + { + pT->OnFindNext(pDialog->GetFindString(), pDialog->SearchDown(), + pDialog->MatchCase(), pDialog->MatchWholeWord()); + } + else if(pDialog->ReplaceCurrent()) + { + pT->OnReplaceSel(pDialog->GetFindString(), + pDialog->SearchDown(), pDialog->MatchCase(), pDialog->MatchWholeWord(), + pDialog->GetReplaceString()); + } + else if(pDialog->ReplaceAll()) + { + pT->OnReplaceAll(pDialog->GetFindString(), pDialog->GetReplaceString(), + pDialog->MatchCase(), pDialog->MatchWholeWord()); + } + else if(pDialog->IsTerminating()) + { + // Dialog is going away (but hasn't gone away yet) + // OnFinalMessage will "delete this" + pT->OnTerminatingFindReplaceDialog(m_pFindReplaceDialog); + m_pFindReplaceDialog = NULL; + } + } + + return 0; + } + + LRESULT OnEditFind(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->FindReplace(TRUE); + + return 0; + } + + LRESULT OnEditRepeat(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + + // If the user is holding down SHIFT when hitting F3, we'll + // search in reverse. Otherwise, we'll search forward. + // (be sure to have an accelerator mapped to ID_EDIT_REPEAT + // for both F3 and Shift+F3) + m_bFindDown = !((::GetKeyState(VK_SHIFT) & 0x8000) == 0x8000); + + if(m_sFindNext.IsEmpty()) + { + pT->FindReplace(TRUE); + } + else + { + if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown)) + pT->TextNotFound(m_sFindNext); + } + + return 0; + } + + LRESULT OnEditReplace(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& bHandled) + { + T* pT = static_cast(this); + + DWORD style = pT->GetStyle(); + if((style & ES_READONLY) != ES_READONLY) + { + pT->FindReplace(FALSE); + } + else + { + // Don't allow replace when the edit control is read only + bHandled = FALSE; + } + + return 0; + } + +// Operations (overrideable) + TFindReplaceDialog* CreateFindReplaceDialog(BOOL bFindOnly, // TRUE for Find, FALSE for FindReplace + LPCTSTR lpszFindWhat, + LPCTSTR lpszReplaceWith = NULL, + DWORD dwFlags = FR_DOWN, + HWND hWndParent = NULL) + { + // You can override all of this in a derived class + + TFindReplaceDialog* findReplaceDialog = new TFindReplaceDialog(); + if(findReplaceDialog == NULL) + { + ::MessageBeep(MB_ICONHAND); + } + else + { + HWND hWndFindReplace = findReplaceDialog->Create(bFindOnly, + lpszFindWhat, lpszReplaceWith, dwFlags, hWndParent); + if(hWndFindReplace == NULL) + { + delete findReplaceDialog; + findReplaceDialog = NULL; + } + else + { + findReplaceDialog->SetActiveWindow(); + findReplaceDialog->ShowWindow(SW_SHOW); + } + } + + return findReplaceDialog; + } + + void AdjustDialogPosition(HWND hWndDialog) + { + ATLASSERT((hWndDialog != NULL) && ::IsWindow(hWndDialog)); + + T* pT = static_cast(this); + LONG nStartChar = 0, nEndChar = 0; + // Send EM_GETSEL so we can use both Edit and RichEdit + // (CEdit::GetSel uses int&, and CRichEditCtrlT::GetSel uses LONG&) + ::SendMessage(pT->m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar); + POINT point = pT->PosFromChar(nStartChar); + ::ClientToScreen(pT->GetParent(), &point); + CRect rect; + ::GetWindowRect(hWndDialog, &rect); + if(rect.PtInRect(point)) + { + if(point.y > rect.Height()) + { + rect.OffsetRect(0, point.y - rect.bottom - 20); + } + else + { + int nVertExt = GetSystemMetrics(SM_CYSCREEN); + if(point.y + rect.Height() < nVertExt) + rect.OffsetRect(0, 40 + point.y - rect.top); + } + + ::MoveWindow(hWndDialog, rect.left, rect.top, rect.Width(), rect.Height(), TRUE); + } + } + + DWORD GetFindReplaceDialogFlags(void) const + { + DWORD dwFlags = 0; + + if(m_bFindDown) + dwFlags |= FR_DOWN; + if(m_bMatchCase) + dwFlags |= FR_MATCHCASE; + if(m_bWholeWord) + dwFlags |= FR_WHOLEWORD; + + return dwFlags; + } + + void FindReplace(BOOL bFindOnly) + { + T* pT = static_cast(this); + m_bFirstSearch = TRUE; + if(m_pFindReplaceDialog != NULL) + { + if(m_bFindOnly == bFindOnly) + { + m_pFindReplaceDialog->SetActiveWindow(); + m_pFindReplaceDialog->ShowWindow(SW_SHOW); + return; + } + else + { + m_pFindReplaceDialog->SendMessage(WM_CLOSE); + ATLASSERT(m_pFindReplaceDialog == NULL); + } + } + + ATLASSERT(m_pFindReplaceDialog == NULL); + + _CSTRING_NS::CString findNext; + pT->GetSelText(findNext); + // if selection is empty or spans multiple lines use old find text + if(findNext.IsEmpty() || (findNext.FindOneOf(_T("\n\r")) != -1)) + findNext = m_sFindNext; + _CSTRING_NS::CString replaceWith = m_sReplaceWith; + DWORD dwFlags = pT->GetFindReplaceDialogFlags(); + + m_pFindReplaceDialog = pT->CreateFindReplaceDialog(bFindOnly, + findNext, replaceWith, dwFlags, pT->operator HWND()); + ATLASSERT(m_pFindReplaceDialog != NULL); + if(m_pFindReplaceDialog != NULL) + m_bFindOnly = bFindOnly; + } + + BOOL SameAsSelected(LPCTSTR lpszCompare, BOOL bMatchCase, BOOL /*bWholeWord*/) + { + T* pT = static_cast(this); + + // check length first + size_t nLen = lstrlen(lpszCompare); + LONG nStartChar = 0, nEndChar = 0; + // Send EM_GETSEL so we can use both Edit and RichEdit + // (CEdit::GetSel uses int&, and CRichEditCtrlT::GetSel uses LONG&) + ::SendMessage(pT->m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar); + if(nLen != (size_t)(nEndChar - nStartChar)) + return FALSE; + + // length is the same, check contents + _CSTRING_NS::CString selectedText; + pT->GetSelText(selectedText); + + return (bMatchCase && selectedText.Compare(lpszCompare) == 0) || + (!bMatchCase && selectedText.CompareNoCase(lpszCompare) == 0); + } + + void TextNotFound(LPCTSTR lpszFind) + { + T* pT = static_cast(this); + m_bFirstSearch = TRUE; + pT->OnTextNotFound(lpszFind); + } + + _CSTRING_NS::CString GetTranslationText(enum TranslationTextItem eItem) const + { + _CSTRING_NS::CString text; + switch(eItem) + { + case eText_OnReplaceAllMessage: + text = _T("Replaced %d occurances of \"%s\" with \"%s\""); + break; + case eText_OnReplaceAllTitle: + text = _T("Replace All"); + break; + case eText_OnTextNotFoundMessage: + text = _T("Unable to find the text \"%s\""); + break; + case eText_OnTextNotFoundTitle: + text = _T("Text not found"); + break; + } + + return text; + } + +// Overrideable Handlers + void OnFindNext(LPCTSTR lpszFind, BOOL bFindDown, BOOL bMatchCase, BOOL bWholeWord) + { + T* pT = static_cast(this); + + m_sFindNext = lpszFind; + m_bMatchCase = bMatchCase; + m_bWholeWord = bWholeWord; + m_bFindDown = bFindDown; + + if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown)) + pT->TextNotFound(m_sFindNext); + else + pT->AdjustDialogPosition(m_pFindReplaceDialog->operator HWND()); + } + + void OnReplaceSel(LPCTSTR lpszFind, BOOL bFindDown, BOOL bMatchCase, BOOL bWholeWord, LPCTSTR lpszReplace) + { + T* pT = static_cast(this); + + m_sFindNext = lpszFind; + m_sReplaceWith = lpszReplace; + m_bMatchCase = bMatchCase; + m_bWholeWord = bWholeWord; + m_bFindDown = bFindDown; + + if(pT->SameAsSelected(m_sFindNext, m_bMatchCase, m_bWholeWord)) + pT->ReplaceSel(m_sReplaceWith); + + if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown)) + pT->TextNotFound(m_sFindNext); + else + pT->AdjustDialogPosition(m_pFindReplaceDialog->operator HWND()); + } + + void OnReplaceAll(LPCTSTR lpszFind, LPCTSTR lpszReplace, BOOL bMatchCase, BOOL bWholeWord) + { + T* pT = static_cast(this); + + m_sFindNext = lpszFind; + m_sReplaceWith = lpszReplace; + m_bMatchCase = bMatchCase; + m_bWholeWord = bWholeWord; + m_bFindDown = TRUE; + + // no selection or different than what looking for + if(!pT->SameAsSelected(m_sFindNext, m_bMatchCase, m_bWholeWord)) + { + if(!pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown)) + { + pT->TextNotFound(m_sFindNext); + return; + } + } + + pT->OnReplaceAllCoreBegin(); + + int replaceCount=0; + do + { + ++replaceCount; + pT->ReplaceSel(m_sReplaceWith); + } while(pT->FindTextSimple(m_sFindNext, m_bMatchCase, m_bWholeWord, m_bFindDown)); + + pT->OnReplaceAllCoreEnd(replaceCount); + } + + void OnReplaceAllCoreBegin() + { + T* pT = static_cast(this); + + m_hOldCursor = ::SetCursor(::LoadCursor(NULL, IDC_WAIT)); + + pT->HideSelection(TRUE, FALSE); + + } + + void OnReplaceAllCoreEnd(int replaceCount) + { + T* pT = static_cast(this); + pT->HideSelection(FALSE, FALSE); + + ::SetCursor(m_hOldCursor); + + _CSTRING_NS::CString message = pT->GetTranslationText(eText_OnReplaceAllMessage); + if(message.GetLength() > 0) + { + _CSTRING_NS::CString formattedMessage; + formattedMessage.Format(message, + replaceCount, m_sFindNext, m_sReplaceWith); + if(m_pFindReplaceDialog != NULL) + { + m_pFindReplaceDialog->MessageBox(formattedMessage, + pT->GetTranslationText(eText_OnReplaceAllTitle), + MB_OK | MB_ICONINFORMATION | MB_APPLMODAL); + } + else + { + pT->MessageBox(formattedMessage, + pT->GetTranslationText(eText_OnReplaceAllTitle), + MB_OK | MB_ICONINFORMATION | MB_APPLMODAL); + } + } + } + + void OnTextNotFound(LPCTSTR lpszFind) + { + T* pT = static_cast(this); + _CSTRING_NS::CString message = pT->GetTranslationText(eText_OnTextNotFoundMessage); + if(message.GetLength() > 0) + { + _CSTRING_NS::CString formattedMessage; + formattedMessage.Format(message, lpszFind); + if(m_pFindReplaceDialog != NULL) + { + m_pFindReplaceDialog->MessageBox(formattedMessage, + pT->GetTranslationText(eText_OnTextNotFoundTitle), + MB_OK | MB_ICONINFORMATION | MB_APPLMODAL); + } + else + { + pT->MessageBox(formattedMessage, + pT->GetTranslationText(eText_OnTextNotFoundTitle), + MB_OK | MB_ICONINFORMATION | MB_APPLMODAL); + } + } + else + { + ::MessageBeep(MB_ICONHAND); + } + } + + void OnTerminatingFindReplaceDialog(TFindReplaceDialog*& /*findReplaceDialog*/) + { + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CEditFindReplaceImpl - Mixin class for implementing Find/Replace for CEdit +// based window classes. + +// Chain to CEditFindReplaceImpl message map. Your class must also derive from CEdit. +// Example: +// class CMyEdit : public CWindowImpl, +// public CEditFindReplaceImpl +// { +// public: +// BEGIN_MSG_MAP(CMyEdit) +// // your handlers... +// CHAIN_MSG_MAP_ALT(CEditFindReplaceImpl, 1) +// END_MSG_MAP() +// // other stuff... +// }; + +template +class CEditFindReplaceImpl : public CEditFindReplaceImplBase +{ +protected: + typedef CEditFindReplaceImpl thisClass; + typedef CEditFindReplaceImplBase baseClass; + +// Data members + LPTSTR m_pShadowBuffer; // Special shadow buffer only used in some cases. + UINT m_nShadowSize; + int m_bShadowBufferNeeded; // TRUE, FALSE, < 0 => Need to check + +public: +// Constructors + CEditFindReplaceImpl() : + m_pShadowBuffer(NULL), + m_nShadowSize(0), + m_bShadowBufferNeeded(-1) + { + } + + virtual ~CEditFindReplaceImpl() + { + if(m_pShadowBuffer != NULL) + { + delete [] m_pShadowBuffer; + m_pShadowBuffer = NULL; + } + } + +// Message Handlers + BEGIN_MSG_MAP(thisClass) + ALT_MSG_MAP(1) + CHAIN_MSG_MAP_ALT(baseClass, 1) + END_MSG_MAP() + +// Operations + // Supported only for RichEdit, so this does nothing for Edit + void HideSelection(BOOL /*bHide*/ = TRUE, BOOL /*bChangeStyle*/ = FALSE) + { + } + +// Operations (overrideable) + BOOL FindTextSimple(LPCTSTR lpszFind, BOOL bMatchCase, BOOL bWholeWord, BOOL bFindDown = TRUE) + { + T* pT = static_cast(this); + + ATLASSERT(lpszFind != NULL); + ATLASSERT(*lpszFind != _T('\0')); + + UINT nLen = pT->GetBufferLength(); + int nStartChar = 0, nEndChar = 0; + pT->GetSel(nStartChar, nEndChar); + UINT nStart = nStartChar; + int iDir = bFindDown ? +1 : -1; + + // can't find a match before the first character + if(nStart == 0 && iDir < 0) + return FALSE; + + LPCTSTR lpszText = pT->LockBuffer(); + + bool isDBCS = false; +#ifdef _MBCS + CPINFO info = { 0 }; + ::GetCPInfo(::GetOEMCP(), &info); + isDBCS = (info.MaxCharSize > 1); +#endif + + if(iDir < 0) + { + // always go back one for search backwards + nStart -= int((lpszText + nStart) - ::CharPrev(lpszText, lpszText + nStart)); + } + else if(nStartChar != nEndChar && pT->SameAsSelected(lpszFind, bMatchCase, bWholeWord)) + { + // easy to go backward/forward with SBCS +#ifndef _UNICODE + if(::IsDBCSLeadByte(lpszText[nStart])) + nStart++; +#endif + nStart += iDir; + } + + // handle search with nStart past end of buffer + UINT nLenFind = ::lstrlen(lpszFind); + if(nStart + nLenFind - 1 >= nLen) + { + if(iDir < 0 && nLen >= nLenFind) + { + if(isDBCS) + { + // walk back to previous character n times + nStart = nLen; + int n = nLenFind; + while(n--) + { + nStart -= int((lpszText + nStart) - ::CharPrev(lpszText, lpszText + nStart)); + } + } + else + { + // single-byte character set is easy and fast + nStart = nLen - nLenFind; + } + ATLASSERT(nStart + nLenFind - 1 <= nLen); + } + else + { + pT->UnlockBuffer(); + return FALSE; + } + } + + // start the search at nStart + LPCTSTR lpsz = lpszText + nStart; + typedef int (WINAPI* CompareProc)(LPCTSTR str1, LPCTSTR str2); + CompareProc pfnCompare = bMatchCase ? lstrcmp : lstrcmpi; + + if(isDBCS) + { + // double-byte string search + LPCTSTR lpszStop = NULL; + if(iDir > 0) + { + // start at current and find _first_ occurrance + lpszStop = lpszText + nLen - nLenFind + 1; + } + else + { + // start at top and find _last_ occurrance + lpszStop = lpsz; + lpsz = lpszText; + } + + LPCTSTR lpszFound = NULL; + while(lpsz <= lpszStop) + { +#ifndef _UNICODE + if(!bMatchCase || (*lpsz == *lpszFind && (!::IsDBCSLeadByte(*lpsz) || lpsz[1] == lpszFind[1]))) +#else + if(!bMatchCase || (*lpsz == *lpszFind && lpsz[1] == lpszFind[1])) +#endif + { + LPTSTR lpch = (LPTSTR)(lpsz + nLenFind); + TCHAR chSave = *lpch; + *lpch = _T('\0'); + int nResult = (*pfnCompare)(lpsz, lpszFind); + *lpch = chSave; + if(nResult == 0) + { + lpszFound = lpsz; + if(iDir > 0) + break; + } + } + lpsz = ::CharNext(lpsz); + } + pT->UnlockBuffer(); + + if(lpszFound != NULL) + { + int n = (int)(lpszFound - lpszText); + pT->SetSel(n, n + nLenFind); + return TRUE; + } + } + else + { + // single-byte string search + UINT nCompare; + if(iDir < 0) + nCompare = (UINT)(lpsz - lpszText) + 1; + else + nCompare = nLen - (UINT)(lpsz - lpszText) - nLenFind + 1; + + while(nCompare > 0) + { + ATLASSERT(lpsz >= lpszText); + ATLASSERT(lpsz + nLenFind - 1 <= lpszText + nLen - 1); + + LPSTR lpch = (LPSTR)(lpsz + nLenFind); + char chSave = *lpch; + *lpch = '\0'; + int nResult = (*pfnCompare)(lpsz, lpszFind); + *lpch = chSave; + if(nResult == 0) + { + pT->UnlockBuffer(); + int n = (int)(lpsz - lpszText); + pT->SetSel(n, n + nLenFind); + return TRUE; + } + + // restore character at end of search + *lpch = chSave; + + // move on to next substring + nCompare--; + lpsz += iDir; + } + pT->UnlockBuffer(); + } + + return FALSE; + } + + LPCTSTR LockBuffer() const + { + const T* pT = static_cast(this); + + ATLASSERT(pT->m_hWnd != NULL); + + BOOL useShadowBuffer = pT->UseShadowBuffer(); + if(useShadowBuffer) + { + if(m_pShadowBuffer == NULL || pT->GetModify()) + { + ATLASSERT(m_pShadowBuffer != NULL || m_nShadowSize == 0); + UINT nSize = pT->GetWindowTextLength() + 1; + if(nSize > m_nShadowSize) + { + // need more room for shadow buffer + T* pThisNoConst = const_cast(pT); + delete[] m_pShadowBuffer; + pThisNoConst->m_pShadowBuffer = NULL; + pThisNoConst->m_nShadowSize = 0; + pThisNoConst->m_pShadowBuffer = new TCHAR[nSize]; + pThisNoConst->m_nShadowSize = nSize; + } + + // update the shadow buffer with GetWindowText + ATLASSERT(m_nShadowSize >= nSize); + ATLASSERT(m_pShadowBuffer != NULL); + pT->GetWindowText(m_pShadowBuffer, nSize); + } + + return m_pShadowBuffer; + } + + HLOCAL hLocal = pT->GetHandle(); + ATLASSERT(hLocal != NULL); + LPCTSTR lpszText = (LPCTSTR)::LocalLock(hLocal); + ATLASSERT(lpszText != NULL); + + return lpszText; + } + + void UnlockBuffer() const + { + const T* pT = static_cast(this); + + ATLASSERT(pT->m_hWnd != NULL); + + BOOL useShadowBuffer = pT->UseShadowBuffer(); + if(!useShadowBuffer) + { + HLOCAL hLocal = pT->GetHandle(); + ATLASSERT(hLocal != NULL); + ::LocalUnlock(hLocal); + } + } + + UINT GetBufferLength() const + { + const T* pT = static_cast(this); + + ATLASSERT(pT->m_hWnd != NULL); + UINT nLen = 0; + LPCTSTR lpszText = pT->LockBuffer(); + if(lpszText != NULL) + nLen = ::lstrlen(lpszText); + pT->UnlockBuffer(); + + return nLen; + } + + LONG EndOfLine(LPCTSTR lpszText, UINT nLen, UINT nIndex) const + { + LPCTSTR lpsz = lpszText + nIndex; + LPCTSTR lpszStop = lpszText + nLen; + while(lpsz < lpszStop && *lpsz != _T('\r')) + ++lpsz; + return LONG(lpsz - lpszText); + } + + LONG GetSelText(_CSTRING_NS::CString& strText) const + { + const T* pT = static_cast(this); + + int nStartChar = 0, nEndChar = 0; + pT->GetSel(nStartChar, nEndChar); + ATLASSERT((UINT)nEndChar <= pT->GetBufferLength()); + LPCTSTR lpszText = pT->LockBuffer(); + LONG nLen = pT->EndOfLine(lpszText, nEndChar, nStartChar) - nStartChar; + SecureHelper::memcpy_x(strText.GetBuffer(nLen), nLen * sizeof(TCHAR), lpszText + nStartChar, nLen * sizeof(TCHAR)); + strText.ReleaseBuffer(nLen); + pT->UnlockBuffer(); + + return nLen; + } + + BOOL UseShadowBuffer(void) const + { + const T* pT = static_cast(this); + + if(pT->m_bShadowBufferNeeded < 0) + { + T* pThisNoConst = const_cast(pT); + + OSVERSIONINFO ovi = { 0 }; + ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + ::GetVersionEx(&ovi); + + bool bWin9x = (ovi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); + if(bWin9x) + { + // Windows 95, 98, ME + // Under Win9x, it is necessary to maintain a shadow buffer. + // It is only updated when the control contents have been changed. + pThisNoConst->m_bShadowBufferNeeded = TRUE; + } + else + { + // Windows NT, 2000, XP, etc. + pThisNoConst->m_bShadowBufferNeeded = FALSE; + +#ifndef _UNICODE + // On Windows XP (or later), if common controls version 6 is in use + // (such as via theming), then EM_GETHANDLE will always return a UNICODE string. + // If theming is enabled and Common Controls version 6 is in use, + // you're really not suppose to superclass or subclass common controls + // with an ANSI windows procedure (so its best to only theme if you use UNICODE). + // Using a shadow buffer uses GetWindowText instead, so it solves + // this problem for us (although it makes it a little less efficient). + + if((ovi.dwMajorVersion == 5 && ovi.dwMinorVersion >= 1) || (ovi.dwMajorVersion > 5)) + { + // We use DLLVERSIONINFO_private so we don't have to depend on shlwapi.h + typedef struct _DLLVERSIONINFO_private + { + DWORD cbSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + DWORD dwPlatformID; + } DLLVERSIONINFO_private; + + HMODULE hModule = ::LoadLibrary("comctl32.dll"); + if(hModule != NULL) + { + typedef HRESULT (CALLBACK *LPFN_DllGetVersion)(DLLVERSIONINFO_private *); + LPFN_DllGetVersion fnDllGetVersion = (LPFN_DllGetVersion)::GetProcAddress(hModule, "DllGetVersion"); + if(fnDllGetVersion != NULL) + { + DLLVERSIONINFO_private version = { 0 }; + version.cbSize = sizeof(DLLVERSIONINFO_private); + if(SUCCEEDED(fnDllGetVersion(&version))) + { + if(version.dwMajorVersion >= 6) + { + pThisNoConst->m_bShadowBufferNeeded = TRUE; + + ATLTRACE2(atlTraceUI, 0, _T("Warning: You have compiled for MBCS/ANSI but are using common controls version 6 or later (likely through a manifest file).\r\n")); + ATLTRACE2(atlTraceUI, 0, _T("If you use common controls version 6 or later, you should only do so for UNICODE builds.\r\n")); + } + } + } + + ::FreeLibrary(hModule); + hModule = NULL; + } + } +#endif // !_UNICODE + } + } + + return (pT->m_bShadowBufferNeeded != FALSE); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CRichEditFindReplaceImpl - Mixin class for implementing Find/Replace for CRichEditCtrl +// based window classes. + +// Chain to CRichEditFindReplaceImpl message map. Your class must also derive from CRichEditCtrl. +// Example: +// class CMyRichEdit : public CWindowImpl, +// public CRichEditFindReplaceImpl +// { +// public: +// BEGIN_MSG_MAP(CMyRichEdit) +// // your handlers... +// CHAIN_MSG_MAP_ALT(CRichEditFindReplaceImpl, 1) +// END_MSG_MAP() +// // other stuff... +// }; + +template +class CRichEditFindReplaceImpl : public CEditFindReplaceImplBase +{ +protected: + typedef CRichEditFindReplaceImpl thisClass; + typedef CEditFindReplaceImplBase baseClass; + +public: + BEGIN_MSG_MAP(thisClass) + ALT_MSG_MAP(1) + CHAIN_MSG_MAP_ALT(baseClass, 1) + END_MSG_MAP() + +// Operations (overrideable) + BOOL FindTextSimple(LPCTSTR lpszFind, BOOL bMatchCase, BOOL bWholeWord, BOOL bFindDown = TRUE) + { + T* pT = static_cast(this); + + ATLASSERT(lpszFind != NULL); + FINDTEXTEX ft = { 0 }; + + pT->GetSel(ft.chrg); + if(m_bFirstSearch) + { + if(bFindDown) + m_nInitialSearchPos = ft.chrg.cpMin; + else + m_nInitialSearchPos = ft.chrg.cpMax; + m_bFirstSearch = FALSE; + } + +#if (_RICHEDIT_VER >= 0x0200) + ft.lpstrText = (LPTSTR)lpszFind; +#else // !(_RICHEDIT_VER >= 0x0200) + USES_CONVERSION; + ft.lpstrText = T2A((LPTSTR)lpszFind); +#endif // !(_RICHEDIT_VER >= 0x0200) + + if(ft.chrg.cpMin != ft.chrg.cpMax) // i.e. there is a selection + { + if(bFindDown) + { + ft.chrg.cpMin++; + } + else + { + // won't wraparound backwards + ft.chrg.cpMin = max(ft.chrg.cpMin, 0); + } + } + + DWORD dwFlags = bMatchCase ? FR_MATCHCASE : 0; + dwFlags |= bWholeWord ? FR_WHOLEWORD : 0; + + ft.chrg.cpMax = pT->GetTextLength() + m_nInitialSearchPos; + + if(bFindDown) + { + if(m_nInitialSearchPos >= 0) + ft.chrg.cpMax = pT->GetTextLength(); + + dwFlags |= FR_DOWN; + ATLASSERT(ft.chrg.cpMax >= ft.chrg.cpMin); + } + else + { + if(m_nInitialSearchPos >= 0) + ft.chrg.cpMax = 0; + + dwFlags &= ~FR_DOWN; + ATLASSERT(ft.chrg.cpMax <= ft.chrg.cpMin); + } + + BOOL bRet = FALSE; + + if(pT->FindAndSelect(dwFlags, ft) != -1) + { + bRet = TRUE; // we found the text + } + else if(m_nInitialSearchPos > 0) + { + // if the original starting point was not the beginning + // of the buffer and we haven't already been here + if(bFindDown) + { + ft.chrg.cpMin = 0; + ft.chrg.cpMax = m_nInitialSearchPos; + } + else + { + ft.chrg.cpMin = pT->GetTextLength(); + ft.chrg.cpMax = m_nInitialSearchPos; + } + m_nInitialSearchPos = m_nInitialSearchPos - pT->GetTextLength(); + + bRet = (pT->FindAndSelect(dwFlags, ft) != -1) ? TRUE : FALSE; + } + + return bRet; + } + + long FindAndSelect(DWORD dwFlags, FINDTEXTEX& ft) + { + T* pT = static_cast(this); + LONG index = pT->FindText(dwFlags, ft); + if(index != -1) // i.e. we found something + pT->SetSel(ft.chrgText); + + return index; + } +}; + +}; // namespace WTL + +#endif // __ATLFIND_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlframe.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlframe.h new file mode 100644 index 0000000000..252e50e902 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlframe.h @@ -0,0 +1,3688 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLFRAME_H__ +#define __ATLFRAME_H__ + +#pragma once + +#ifndef __ATLAPP_H__ + #error atlframe.h requires atlapp.h to be included first +#endif + +#ifndef __ATLWIN_H__ + #error atlframe.h requires atlwin.h to be included first +#endif + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CFrameWindowImpl +// CMDIWindow +// CMDIFrameWindowImpl +// CMDIChildWindowImpl +// COwnerDraw +// CUpdateUIBase +// CUpdateUI +// CDynamicUpdateUI +// CAutoUpdateUI +// CDialogResize +// CDoubleBufferImpl +// CDoubleBufferWindowImpl +// +// Global functions: +// AtlCreateSimpleToolBar() + + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// CFrameWndClassInfo - Manages frame window Windows class information + +class CFrameWndClassInfo +{ +public: +#ifndef _WIN32_WCE + enum { cchAutoName = 5 + sizeof(void*) * 2 }; // sizeof(void*) * 2 is the number of digits %p outputs + WNDCLASSEX m_wc; +#else // CE specific + enum { cchAutoName = MAX_PATH }; // MAX_PATH because this can be set in the wizard generated CMainFrame::ActivatePreviousInstance to a user defined string. + WNDCLASS m_wc; +#endif // !_WIN32_WCE + LPCTSTR m_lpszOrigName; + WNDPROC pWndProc; + LPCTSTR m_lpszCursorID; + BOOL m_bSystemCursor; + ATOM m_atom; + TCHAR m_szAutoName[cchAutoName]; + UINT m_uCommonResourceID; + +#ifndef _WIN32_WCE + ATOM Register(WNDPROC* pProc) + { + if (m_atom == 0) + { + CWindowCreateCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CFrameWndClassInfo::Register.\n")); + ATLASSERT(FALSE); + return 0; + } + + if(m_atom == 0) + { + HINSTANCE hInst = ModuleHelper::GetModuleInstance(); + + if (m_lpszOrigName != NULL) + { + ATLASSERT(pProc != NULL); + LPCTSTR lpsz = m_wc.lpszClassName; + WNDPROC proc = m_wc.lpfnWndProc; + + WNDCLASSEX wc = { 0 }; + wc.cbSize = sizeof(WNDCLASSEX); + // try process local class first + if(!::GetClassInfoEx(ModuleHelper::GetModuleInstance(), m_lpszOrigName, &wc)) + { + // try global class + if(!::GetClassInfoEx(NULL, m_lpszOrigName, &wc)) + { + lock.Unlock(); + return 0; + } + } + m_wc = wc; + pWndProc = m_wc.lpfnWndProc; + m_wc.lpszClassName = lpsz; + m_wc.lpfnWndProc = proc; + } + else + { + m_wc.hCursor = ::LoadCursor(m_bSystemCursor ? NULL : hInst, m_lpszCursorID); + } + + m_wc.hInstance = hInst; + m_wc.style &= ~CS_GLOBALCLASS; // we don't register global classes + if (m_wc.lpszClassName == NULL) + { +#if (_WIN32_WINNT >= 0x0500) || defined(_WIN64) + SecureHelper::wsprintf_x(m_szAutoName, cchAutoName, _T("ATL:%p"), &m_wc); +#else // !((_WIN32_WINNT >= 0x0500) || defined(_WIN64)) + SecureHelper::wsprintf_x(m_szAutoName, cchAutoName, _T("ATL:%8.8X"), (DWORD_PTR)&m_wc); +#endif // !((_WIN32_WINNT >= 0x0500) || defined(_WIN64)) + m_wc.lpszClassName = m_szAutoName; + } + + WNDCLASSEX wcTemp = m_wc; + m_atom = (ATOM)::GetClassInfoEx(m_wc.hInstance, m_wc.lpszClassName, &wcTemp); + if (m_atom == 0) + { + if(m_uCommonResourceID != 0) // use it if not zero + { + m_wc.hIcon = (HICON)::LoadImage(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(m_uCommonResourceID), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR); + m_wc.hIconSm = (HICON)::LoadImage(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(m_uCommonResourceID), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + } + m_atom = ::RegisterClassEx(&m_wc); + } + } + + lock.Unlock(); + } + + if (m_lpszOrigName != NULL) + { + ATLASSERT(pProc != NULL); + ATLASSERT(pWndProc != NULL); + *pProc = pWndProc; + } + + return m_atom; + } +#else // CE specific + ATOM Register(WNDPROC* pProc) + { + if (m_atom == 0) + { + CWindowCreateCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CFrameWndClassInfo::Register.\n")); + ATLASSERT(FALSE); + return 0; + } + + if(m_atom == 0) + { + HINSTANCE hInst = ModuleHelper::GetModuleInstance(); + + if (m_lpszOrigName != NULL) + { + ATLASSERT(pProc != NULL); + LPCTSTR lpsz = m_wc.lpszClassName; + WNDPROC proc = m_wc.lpfnWndProc; + + WNDCLASS wc = { 0 }; + // try process local class first + if(!::GetClassInfo(ModuleHelper::GetModuleInstance(), m_lpszOrigName, &wc)) + { + // try global class + if(!::GetClassInfo(NULL, m_lpszOrigName, &wc)) + { + lock.Unlock(); + return 0; + } + } + m_wc = wc; + pWndProc = m_wc.lpfnWndProc; + m_wc.lpszClassName = lpsz; + m_wc.lpfnWndProc = proc; + } + else + { +#if defined(GWES_CURSOR) || defined(GWES_MCURSOR) + m_wc.hCursor = ::LoadCursor(m_bSystemCursor ? NULL : hInst, m_lpszCursorID); +#else // !(defined(GWES_CURSOR) || defined(GWES_MCURSOR)) + m_wc.hCursor = NULL; +#endif // !(defined(GWES_CURSOR) || defined(GWES_MCURSOR)) + } + + m_wc.hInstance = hInst; + m_wc.style &= ~CS_GLOBALCLASS; // we don't register global classes + if (m_wc.lpszClassName == NULL) + { + wsprintf(m_szAutoName, _T("ATL:%8.8X"), (DWORD_PTR)&m_wc); + m_wc.lpszClassName = m_szAutoName; + } + + WNDCLASS wcTemp = m_wc; + m_atom = (ATOM)::GetClassInfo(m_wc.hInstance, m_wc.lpszClassName, &wcTemp); + if (m_atom == 0) + { + if(m_uCommonResourceID != 0) // use it if not zero + m_wc.hIcon = (HICON)::LoadImage(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(m_uCommonResourceID), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR); + m_atom = ::RegisterClass(&m_wc); + } + } + + lock.Unlock(); + } + + if (m_lpszOrigName != NULL) + { + ATLASSERT(pProc != NULL); + ATLASSERT(pWndProc != NULL); + *pProc = pWndProc; + } + + return m_atom; + } +#endif // _WIN32_WCE +}; + + +/////////////////////////////////////////////////////////////////////////////// +// Macros for declaring frame window WNDCLASS + +#ifndef _WIN32_WCE + +#define DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) \ +static WTL::CFrameWndClassInfo& GetWndClassInfo() \ +{ \ + static WTL::CFrameWndClassInfo wc = \ + { \ + { sizeof(WNDCLASSEX), 0, StartWindowProc, \ + 0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndClassName, NULL }, \ + NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \ + }; \ + return wc; \ +} + +#define DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd) \ +static WTL::CFrameWndClassInfo& GetWndClassInfo() \ +{ \ + static WTL::CFrameWndClassInfo wc = \ + { \ + { sizeof(WNDCLASSEX), style, StartWindowProc, \ + 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName, NULL }, \ + NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \ + }; \ + return wc; \ +} + +#define DECLARE_FRAME_WND_SUPERCLASS(WndClassName, OrigWndClassName, uCommonResourceID) \ +static WTL::CFrameWndClassInfo& GetWndClassInfo() \ +{ \ + static WTL::CFrameWndClassInfo wc = \ + { \ + { sizeof(WNDCLASSEX), 0, StartWindowProc, \ + 0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName, NULL }, \ + OrigWndClassName, NULL, NULL, TRUE, 0, _T(""), uCommonResourceID \ + }; \ + return wc; \ +} + +#else // CE specific + +#define DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) \ +static WTL::CFrameWndClassInfo& GetWndClassInfo() \ +{ \ + static WTL::CFrameWndClassInfo wc = \ + { \ + { 0, StartWindowProc, \ + 0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndClassName }, \ + NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \ + }; \ + return wc; \ +} + +#define DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd) \ +static WTL::CFrameWndClassInfo& GetWndClassInfo() \ +{ \ + static WTL::CFrameWndClassInfo wc = \ + { \ + { style, StartWindowProc, \ + 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName }, \ + NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \ + }; \ + return wc; \ +} + +#define DECLARE_FRAME_WND_SUPERCLASS(WndClassName, OrigWndClassName, uCommonResourceID) \ +static WTL::CFrameWndClassInfo& GetWndClassInfo() \ +{ \ + static WTL::CFrameWndClassInfo wc = \ + { \ + { NULL, StartWindowProc, \ + 0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName }, \ + OrigWndClassName, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \ + }; \ + return wc; \ +} + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CFrameWindowImpl + +// Client window command chaining macro (only for frame windows) +#define CHAIN_CLIENT_COMMANDS() \ + if(uMsg == WM_COMMAND && m_hWndClient != NULL) \ + ::SendMessage(m_hWndClient, uMsg, wParam, lParam); + +// standard toolbar styles +#define ATL_SIMPLE_TOOLBAR_STYLE \ + (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS) +// toolbar in a rebar pane +#define ATL_SIMPLE_TOOLBAR_PANE_STYLE \ + (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NORESIZE | CCS_NOPARENTALIGN | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT) +// standard rebar styles +#if (_WIN32_IE >= 0x0400) + #define ATL_SIMPLE_REBAR_STYLE \ + (WS_CHILD | WS_VISIBLE | WS_BORDER | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_AUTOSIZE) +#else + #define ATL_SIMPLE_REBAR_STYLE \ + (WS_CHILD | WS_VISIBLE | WS_BORDER | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS) +#endif // !(_WIN32_IE >= 0x0400) +// rebar without borders +#if (_WIN32_IE >= 0x0400) + #define ATL_SIMPLE_REBAR_NOBORDER_STYLE \ + (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_AUTOSIZE | CCS_NODIVIDER) +#else + #define ATL_SIMPLE_REBAR_NOBORDER_STYLE \ + (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS | CCS_NODIVIDER) +#endif // !(_WIN32_IE >= 0x0400) + +// command bar support +#if !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE) + +#define CBRM_GETCMDBAR (WM_USER + 301) // returns command bar HWND +#define CBRM_GETMENU (WM_USER + 302) // returns loaded or attached menu +#define CBRM_TRACKPOPUPMENU (WM_USER + 303) // displays a popup menu + +struct _AtlFrameWnd_CmdBarPopupMenu +{ + int cbSize; + HMENU hMenu; + UINT uFlags; + int x; + int y; + LPTPMPARAMS lptpm; +}; + +#define CBRPOPUPMENU _AtlFrameWnd_CmdBarPopupMenu + +#endif // !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE) + + +template +class ATL_NO_VTABLE CFrameWindowImplBase : public ATL::CWindowImplBaseT< TBase, TWinTraits > +{ +public: + DECLARE_FRAME_WND_CLASS(NULL, 0) + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + struct _ChevronMenuInfo + { + HMENU hMenu; + LPNMREBARCHEVRON lpnm; + bool bCmdBar; + }; +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + +// Data members + HWND m_hWndToolBar; + HWND m_hWndStatusBar; + HWND m_hWndClient; + +#ifdef _WIN32_WCE + HWND m_hWndCECommandBar; +#endif // _WIN32_WCE + + HACCEL m_hAccel; + +// Constructor + CFrameWindowImplBase() : + m_hWndToolBar(NULL), + m_hWndStatusBar(NULL), + m_hWndClient(NULL), +#ifdef _WIN32_WCE + m_hWndCECommandBar(NULL), +#endif // _WIN32_WCE + m_hAccel(NULL) + { } + +// Methods + HWND Create(HWND hWndParent, ATL::_U_RECT rect, LPCTSTR szWindowName, DWORD dwStyle, DWORD dwExStyle, ATL::_U_MENUorID MenuOrID, ATOM atom, LPVOID lpCreateParam) + { + ATLASSERT(m_hWnd == NULL); + + if(atom == 0) + return NULL; + + ModuleHelper::AddCreateWndData(&m_thunk.cd, this); + + if(MenuOrID.m_hMenu == NULL && (dwStyle & WS_CHILD)) + MenuOrID.m_hMenu = (HMENU)(UINT_PTR)this; + if(rect.m_lpRect == NULL) + rect.m_lpRect = &TBase::rcDefault; + + HWND hWnd = ::CreateWindowEx(dwExStyle, MAKEINTATOM(atom), szWindowName, + dwStyle, rect.m_lpRect->left, rect.m_lpRect->top, rect.m_lpRect->right - rect.m_lpRect->left, + rect.m_lpRect->bottom - rect.m_lpRect->top, hWndParent, MenuOrID.m_hMenu, + ModuleHelper::GetModuleInstance(), lpCreateParam); + + ATLASSERT(hWnd == NULL || m_hWnd == hWnd); + + return hWnd; + } + + static HWND CreateSimpleToolBarCtrl(HWND hWndParent, UINT nResourceID, BOOL bInitialSeparator = FALSE, + DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) + { + HINSTANCE hInst = ModuleHelper::GetResourceInstance(); + HRSRC hRsrc = ::FindResource(hInst, MAKEINTRESOURCE(nResourceID), RT_TOOLBAR); + if (hRsrc == NULL) + return NULL; + + HGLOBAL hGlobal = ::LoadResource(hInst, hRsrc); + if (hGlobal == NULL) + return NULL; + + _AtlToolBarData* pData = (_AtlToolBarData*)::LockResource(hGlobal); + if (pData == NULL) + return NULL; + ATLASSERT(pData->wVersion == 1); + + WORD* pItems = pData->items(); + int nItems = pData->wItemCount + (bInitialSeparator ? 1 : 0); + CTempBuffer buff; + TBBUTTON* pTBBtn = buff.Allocate(nItems); + ATLASSERT(pTBBtn != NULL); + if(pTBBtn == NULL) + return NULL; + + const int cxSeparator = 8; + + // set initial separator (half width) + if(bInitialSeparator) + { + pTBBtn[0].iBitmap = cxSeparator / 2; + pTBBtn[0].idCommand = 0; + pTBBtn[0].fsState = 0; + pTBBtn[0].fsStyle = TBSTYLE_SEP; + pTBBtn[0].dwData = 0; + pTBBtn[0].iString = 0; + } + + int nBmp = 0; + for(int i = 0, j = bInitialSeparator ? 1 : 0; i < pData->wItemCount; i++, j++) + { + if(pItems[i] != 0) + { + pTBBtn[j].iBitmap = nBmp++; + pTBBtn[j].idCommand = pItems[i]; + pTBBtn[j].fsState = TBSTATE_ENABLED; + pTBBtn[j].fsStyle = TBSTYLE_BUTTON; + pTBBtn[j].dwData = 0; + pTBBtn[j].iString = 0; + } + else + { + pTBBtn[j].iBitmap = cxSeparator; + pTBBtn[j].idCommand = 0; + pTBBtn[j].fsState = 0; + pTBBtn[j].fsStyle = TBSTYLE_SEP; + pTBBtn[j].dwData = 0; + pTBBtn[j].iString = 0; + } + } + +#ifndef _WIN32_WCE + HWND hWnd = ::CreateWindowEx(0, TOOLBARCLASSNAME, NULL, dwStyle, 0, 0, 100, 100, hWndParent, (HMENU)LongToHandle(nID), ModuleHelper::GetModuleInstance(), NULL); + if(hWnd == NULL) + { + ATLASSERT(FALSE); + return NULL; + } +#else // CE specific + dwStyle; + nID; + // The toolbar must go onto the existing CommandBar or MenuBar + HWND hWnd = hWndParent; +#endif // _WIN32_WCE + + ::SendMessage(hWnd, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0L); + + // check if font is taller than our bitmaps + CFontHandle font = (HFONT)::SendMessage(hWnd, WM_GETFONT, 0, 0L); + if(font.IsNull()) + font = (HFONT)::GetStockObject(SYSTEM_FONT); + LOGFONT lf = { 0 }; + font.GetLogFont(lf); + WORD cyFontHeight = (WORD)abs(lf.lfHeight); + +#ifndef _WIN32_WCE + WORD bitsPerPixel = AtlGetBitmapResourceBitsPerPixel(nResourceID); + if(bitsPerPixel > 4) + { + COLORREF crMask = CLR_DEFAULT; + if(bitsPerPixel == 32) + { + // 32-bit color bitmap with alpha channel (valid for Windows XP and later) + crMask = CLR_NONE; + } + HIMAGELIST hImageList = ImageList_LoadImage(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(nResourceID), pData->wWidth, 1, crMask, IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_DEFAULTSIZE); + ATLASSERT(hImageList != NULL); + ::SendMessage(hWnd, TB_SETIMAGELIST, 0, (LPARAM)hImageList); + } + else +#endif // !_WIN32_WCE + { + TBADDBITMAP tbab = { 0 }; + tbab.hInst = hInst; + tbab.nID = nResourceID; + ::SendMessage(hWnd, TB_ADDBITMAP, nBmp, (LPARAM)&tbab); + } + + ::SendMessage(hWnd, TB_ADDBUTTONS, nItems, (LPARAM)pTBBtn); + ::SendMessage(hWnd, TB_SETBITMAPSIZE, 0, MAKELONG(pData->wWidth, max(pData->wHeight, cyFontHeight))); + const int cxyButtonMargin = 7; + ::SendMessage(hWnd, TB_SETBUTTONSIZE, 0, MAKELONG(pData->wWidth + cxyButtonMargin, max(pData->wHeight, cyFontHeight) + cxyButtonMargin)); + + return hWnd; + } + +#ifndef _WIN32_WCE + static HWND CreateSimpleReBarCtrl(HWND hWndParent, DWORD dwStyle = ATL_SIMPLE_REBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) + { + // Ensure style combinations for proper rebar painting + if(dwStyle & CCS_NODIVIDER && dwStyle & WS_BORDER) + dwStyle &= ~WS_BORDER; + else if(!(dwStyle & WS_BORDER) && !(dwStyle & CCS_NODIVIDER)) + dwStyle |= CCS_NODIVIDER; + + // Create rebar window + HWND hWndReBar = ::CreateWindowEx(0, REBARCLASSNAME, NULL, dwStyle, 0, 0, 100, 100, hWndParent, (HMENU)LongToHandle(nID), ModuleHelper::GetModuleInstance(), NULL); + if(hWndReBar == NULL) + { + ATLTRACE2(atlTraceUI, 0, _T("Failed to create rebar.\n")); + return NULL; + } + + // Initialize and send the REBARINFO structure + REBARINFO rbi = { 0 }; + rbi.cbSize = sizeof(REBARINFO); + rbi.fMask = 0; + if(!::SendMessage(hWndReBar, RB_SETBARINFO, 0, (LPARAM)&rbi)) + { + ATLTRACE2(atlTraceUI, 0, _T("Failed to initialize rebar.\n")); + ::DestroyWindow(hWndReBar); + return NULL; + } + + return hWndReBar; + } + + BOOL CreateSimpleReBar(DWORD dwStyle = ATL_SIMPLE_REBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) + { + ATLASSERT(!::IsWindow(m_hWndToolBar)); + m_hWndToolBar = CreateSimpleReBarCtrl(m_hWnd, dwStyle, nID); + return (m_hWndToolBar != NULL); + } + + static BOOL AddSimpleReBarBandCtrl(HWND hWndReBar, HWND hWndBand, int nID = 0, LPCTSTR lpstrTitle = NULL, BOOL bNewRow = FALSE, int cxWidth = 0, BOOL bFullWidthAlways = FALSE) + { + ATLASSERT(::IsWindow(hWndReBar)); // must be already created +#ifdef _DEBUG + // block - check if this is really a rebar + { + TCHAR lpszClassName[sizeof(REBARCLASSNAME)] = { 0 }; + ::GetClassName(hWndReBar, lpszClassName, sizeof(REBARCLASSNAME)); + ATLASSERT(lstrcmp(lpszClassName, REBARCLASSNAME) == 0); + } +#endif // _DEBUG + ATLASSERT(::IsWindow(hWndBand)); // must be already created + + // Get number of buttons on the toolbar + int nBtnCount = (int)::SendMessage(hWndBand, TB_BUTTONCOUNT, 0, 0L); + + // Set band info structure + REBARBANDINFO rbBand = { RunTimeHelper::SizeOf_REBARBANDINFO() }; +#if (_WIN32_IE >= 0x0400) + rbBand.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_ID | RBBIM_SIZE | RBBIM_IDEALSIZE; +#else + rbBand.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_ID | RBBIM_SIZE; +#endif // !(_WIN32_IE >= 0x0400) + if(lpstrTitle != NULL) + rbBand.fMask |= RBBIM_TEXT; + rbBand.fStyle = RBBS_CHILDEDGE; +#if (_WIN32_IE >= 0x0500) + if(nBtnCount > 0) // add chevron style for toolbar with buttons + rbBand.fStyle |= RBBS_USECHEVRON; +#endif // (_WIN32_IE >= 0x0500) + if(bNewRow) + rbBand.fStyle |= RBBS_BREAK; + + rbBand.lpText = (LPTSTR)lpstrTitle; + rbBand.hwndChild = hWndBand; + if(nID == 0) // calc band ID + nID = ATL_IDW_BAND_FIRST + (int)::SendMessage(hWndReBar, RB_GETBANDCOUNT, 0, 0L); + rbBand.wID = nID; + + // Calculate the size of the band + BOOL bRet = FALSE; + RECT rcTmp = { 0 }; + if(nBtnCount > 0) + { + bRet = (BOOL)::SendMessage(hWndBand, TB_GETITEMRECT, nBtnCount - 1, (LPARAM)&rcTmp); + ATLASSERT(bRet); + rbBand.cx = (cxWidth != 0) ? cxWidth : rcTmp.right; + rbBand.cyMinChild = rcTmp.bottom - rcTmp.top; + if(bFullWidthAlways) + { + rbBand.cxMinChild = rbBand.cx; + } + else if(lpstrTitle == NULL) + { + bRet = (BOOL)::SendMessage(hWndBand, TB_GETITEMRECT, 0, (LPARAM)&rcTmp); + ATLASSERT(bRet); + rbBand.cxMinChild = rcTmp.right; + } + else + { + rbBand.cxMinChild = 0; + } + } + else // no buttons, either not a toolbar or really has no buttons + { + bRet = ::GetWindowRect(hWndBand, &rcTmp); + ATLASSERT(bRet); + rbBand.cx = (cxWidth != 0) ? cxWidth : (rcTmp.right - rcTmp.left); + rbBand.cxMinChild = bFullWidthAlways ? rbBand.cx : 0; + rbBand.cyMinChild = rcTmp.bottom - rcTmp.top; + } + +#if (_WIN32_IE >= 0x0400) + rbBand.cxIdeal = rbBand.cx; +#endif // (_WIN32_IE >= 0x0400) + + // Add the band + LRESULT lRes = ::SendMessage(hWndReBar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand); + if(lRes == 0) + { + ATLTRACE2(atlTraceUI, 0, _T("Failed to add a band to the rebar.\n")); + return FALSE; + } + +#if (_WIN32_IE >= 0x0501) + DWORD dwExStyle = (DWORD)::SendMessage(hWndBand, TB_GETEXTENDEDSTYLE, 0, 0L); + ::SendMessage(hWndBand, TB_SETEXTENDEDSTYLE, 0, dwExStyle | TBSTYLE_EX_HIDECLIPPEDBUTTONS); +#endif // (_WIN32_IE >= 0x0501) + + return TRUE; + } + + BOOL AddSimpleReBarBand(HWND hWndBand, LPCTSTR lpstrTitle = NULL, BOOL bNewRow = FALSE, int cxWidth = 0, BOOL bFullWidthAlways = FALSE) + { + ATLASSERT(::IsWindow(m_hWndToolBar)); // must be an existing rebar + ATLASSERT(::IsWindow(hWndBand)); // must be created + return AddSimpleReBarBandCtrl(m_hWndToolBar, hWndBand, 0, lpstrTitle, bNewRow, cxWidth, bFullWidthAlways); + } + +#if (_WIN32_IE >= 0x0400) + void SizeSimpleReBarBands() + { + ATLASSERT(::IsWindow(m_hWndToolBar)); // must be an existing rebar + + int nCount = (int)::SendMessage(m_hWndToolBar, RB_GETBANDCOUNT, 0, 0L); + + for(int i = 0; i < nCount; i++) + { + REBARBANDINFO rbBand = { RunTimeHelper::SizeOf_REBARBANDINFO() }; + rbBand.fMask = RBBIM_SIZE; + BOOL bRet = (BOOL)::SendMessage(m_hWndToolBar, RB_GETBANDINFO, i, (LPARAM)&rbBand); + ATLASSERT(bRet); + RECT rect = { 0, 0, 0, 0 }; + ::SendMessage(m_hWndToolBar, RB_GETBANDBORDERS, i, (LPARAM)&rect); + rbBand.cx += rect.left + rect.right; + bRet = (BOOL)::SendMessage(m_hWndToolBar, RB_SETBANDINFO, i, (LPARAM)&rbBand); + ATLASSERT(bRet); + } + } +#endif // (_WIN32_IE >= 0x0400) +#endif // _WIN32_WCE + +#ifndef _WIN32_WCE + BOOL CreateSimpleStatusBar(LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR) +#else // CE specific + BOOL CreateSimpleStatusBar(LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, UINT nID = ATL_IDW_STATUS_BAR) +#endif // _WIN32_WCE + { + ATLASSERT(!::IsWindow(m_hWndStatusBar)); + m_hWndStatusBar = ::CreateStatusWindow(dwStyle, lpstrText, m_hWnd, nID); + return (m_hWndStatusBar != NULL); + } + +#ifndef _WIN32_WCE + BOOL CreateSimpleStatusBar(UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL_IDW_STATUS_BAR) +#else // CE specific + BOOL CreateSimpleStatusBar(UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, UINT nID = ATL_IDW_STATUS_BAR) +#endif // _WIN32_WCE + { + const int cchMax = 128; // max text length is 127 for status bars (+1 for null) + TCHAR szText[cchMax]; + szText[0] = 0; + ::LoadString(ModuleHelper::GetResourceInstance(), nTextID, szText, cchMax); + return CreateSimpleStatusBar(szText, dwStyle, nID); + } + +#ifdef _WIN32_WCE + BOOL CreateSimpleCECommandBar(LPTSTR pszMenu = NULL, WORD iButton = 0, DWORD dwFlags = 0, int nCmdBarID = 1) + { + ATLASSERT(m_hWndCECommandBar == NULL); + ATLASSERT(m_hWndToolBar == NULL); + + m_hWndCECommandBar = ::CommandBar_Create(ModuleHelper::GetModuleInstance(), m_hWnd, nCmdBarID); + if(m_hWndCECommandBar == NULL) + return FALSE; + + m_hWndToolBar = m_hWndCECommandBar; + + BOOL bRet = TRUE; + + if(pszMenu != NULL) + bRet &= ::CommandBar_InsertMenubarEx(m_hWndCECommandBar, IS_INTRESOURCE(pszMenu) ? ModuleHelper::GetResourceInstance() : NULL, pszMenu, iButton); + + bRet &= ::CommandBar_AddAdornments(m_hWndCECommandBar, dwFlags, 0); + + return bRet; + } + +#if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) + BOOL CreateSimpleCEMenuBar(UINT nToolBarId = ATL_IDW_MENU_BAR, DWORD dwFlags = 0, int nBmpId = 0, int cBmpImages = 0) + { + ATLASSERT(m_hWndCECommandBar == NULL); + + SHMENUBARINFO mbi = { 0 }; + mbi.cbSize = sizeof(mbi); + mbi.hwndParent = m_hWnd; + mbi.dwFlags = dwFlags; + mbi.nToolBarId = nToolBarId; + mbi.hInstRes = ModuleHelper::GetResourceInstance(); + mbi.nBmpId = nBmpId; + mbi.cBmpImages = cBmpImages; + mbi.hwndMB = NULL; // This gets set by SHCreateMenuBar + + BOOL bRet = ::SHCreateMenuBar(&mbi); + if(bRet != FALSE) + { + m_hWndCECommandBar = mbi.hwndMB; + SizeToMenuBar(); + } + + return bRet; + } + + void SizeToMenuBar() // for menu bar only + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(::IsWindow(m_hWndCECommandBar)); + + RECT rect = { 0 }; + GetWindowRect(&rect); + RECT rectMB = { 0 }; + ::GetWindowRect(m_hWndCECommandBar, &rectMB); + int cy = ::IsWindowVisible(m_hWndCECommandBar) ? rectMB.top - rect.top : rectMB.bottom - rect.top; + SetWindowPos(NULL, 0, 0, rect.right - rect.left, cy, SWP_NOZORDER | SWP_NOMOVE); + } +#endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) +#endif // _WIN32_WCE + + void UpdateLayout(BOOL bResizeBars = TRUE) + { + RECT rect = { 0 }; + GetClientRect(&rect); + + // position bars and offset their dimensions + UpdateBarsPosition(rect, bResizeBars); + + // resize client window + if(m_hWndClient != NULL) + ::SetWindowPos(m_hWndClient, NULL, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, + SWP_NOZORDER | SWP_NOACTIVATE); + } + + void UpdateBarsPosition(RECT& rect, BOOL bResizeBars = TRUE) + { + // resize toolbar + if(m_hWndToolBar != NULL && ((DWORD)::GetWindowLong(m_hWndToolBar, GWL_STYLE) & WS_VISIBLE)) + { + if(bResizeBars != FALSE) + { + ::SendMessage(m_hWndToolBar, WM_SIZE, 0, 0); + ::InvalidateRect(m_hWndToolBar, NULL, TRUE); + } + RECT rectTB = { 0 }; + ::GetWindowRect(m_hWndToolBar, &rectTB); + rect.top += rectTB.bottom - rectTB.top; + } + + // resize status bar + if(m_hWndStatusBar != NULL && ((DWORD)::GetWindowLong(m_hWndStatusBar, GWL_STYLE) & WS_VISIBLE)) + { + if(bResizeBars != FALSE) + ::SendMessage(m_hWndStatusBar, WM_SIZE, 0, 0); + RECT rectSB = { 0 }; + ::GetWindowRect(m_hWndStatusBar, &rectSB); + rect.bottom -= rectSB.bottom - rectSB.top; + } + } + + BOOL PreTranslateMessage(MSG* pMsg) + { + if(m_hAccel != NULL && ::TranslateAccelerator(m_hWnd, m_hAccel, pMsg)) + return TRUE; + return FALSE; + } + + BEGIN_MSG_MAP(CFrameWindowImplBase) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) +#ifndef _WIN32_WCE + MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect) +#endif // !_WIN32_WCE + MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) +#ifndef _WIN32_WCE + NOTIFY_CODE_HANDLER(TTN_GETDISPINFOA, OnToolTipTextA) + NOTIFY_CODE_HANDLER(TTN_GETDISPINFOW, OnToolTipTextW) +#endif // !_WIN32_WCE + END_MSG_MAP() + + LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_hWndClient != NULL) // view will paint itself instead + return 1; + + bHandled = FALSE; + return 0; + } + +#ifndef _WIN32_WCE + LRESULT OnMenuSelect(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + bHandled = FALSE; + + if(m_hWndStatusBar == NULL) + return 1; + + WORD wFlags = HIWORD(wParam); + if(wFlags == 0xFFFF && lParam == NULL) // menu closing + { + ::SendMessage(m_hWndStatusBar, SB_SIMPLE, FALSE, 0L); + } + else + { + const int cchBuff = 256; + TCHAR szBuff[cchBuff]; + szBuff[0] = 0; + if(!(wFlags & MF_POPUP)) + { + WORD wID = LOWORD(wParam); + // check for special cases + if(wID >= 0xF000 && wID < 0xF1F0) // system menu IDs + wID = (WORD)(((wID - 0xF000) >> 4) + ATL_IDS_SCFIRST); + else if(wID >= ID_FILE_MRU_FIRST && wID <= ID_FILE_MRU_LAST) // MRU items + wID = ATL_IDS_MRU_FILE; + else if(wID >= ATL_IDM_FIRST_MDICHILD && wID <= ATL_IDM_LAST_MDICHILD) // MDI child windows + wID = ATL_IDS_MDICHILD; + + int nRet = ::LoadString(ModuleHelper::GetResourceInstance(), wID, szBuff, cchBuff); + for(int i = 0; i < nRet; i++) + { + if(szBuff[i] == _T('\n')) + { + szBuff[i] = 0; + break; + } + } + } + ::SendMessage(m_hWndStatusBar, SB_SIMPLE, TRUE, 0L); + ::SendMessage(m_hWndStatusBar, SB_SETTEXT, (255 | SBT_NOBORDERS), (LPARAM)szBuff); + } + + return 1; + } +#endif // !_WIN32_WCE + + LRESULT OnSetFocus(UINT, WPARAM, LPARAM, BOOL& bHandled) + { + if(m_hWndClient != NULL) + ::SetFocus(m_hWndClient); + + bHandled = FALSE; + return 1; + } + + LRESULT OnDestroy(UINT, WPARAM, LPARAM, BOOL& bHandled) + { + if((GetStyle() & (WS_CHILD | WS_POPUP)) == 0) + ::PostQuitMessage(1); + + bHandled = FALSE; + return 1; + } + +#ifndef _WIN32_WCE + LRESULT OnToolTipTextA(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/) + { + LPNMTTDISPINFOA pDispInfo = (LPNMTTDISPINFOA)pnmh; + pDispInfo->szText[0] = 0; + + if((idCtrl != 0) && !(pDispInfo->uFlags & TTF_IDISHWND)) + { + const int cchBuff = 256; + char szBuff[cchBuff]; + szBuff[0] = 0; + int nRet = ::LoadStringA(ModuleHelper::GetResourceInstance(), idCtrl, szBuff, cchBuff); + for(int i = 0; i < nRet; i++) + { + if(szBuff[i] == '\n') + { + SecureHelper::strncpyA_x(pDispInfo->szText, _countof(pDispInfo->szText), &szBuff[i + 1], _TRUNCATE); + break; + } + } +#if (_WIN32_IE >= 0x0300) + if(nRet > 0) // string was loaded, save it + pDispInfo->uFlags |= TTF_DI_SETITEM; +#endif // (_WIN32_IE >= 0x0300) + } + + return 0; + } + + LRESULT OnToolTipTextW(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/) + { + LPNMTTDISPINFOW pDispInfo = (LPNMTTDISPINFOW)pnmh; + pDispInfo->szText[0] = 0; + + if((idCtrl != 0) && !(pDispInfo->uFlags & TTF_IDISHWND)) + { + const int cchBuff = 256; + wchar_t szBuff[cchBuff]; + szBuff[0] = 0; + int nRet = ::LoadStringW(ModuleHelper::GetResourceInstance(), idCtrl, szBuff, cchBuff); + for(int i = 0; i < nRet; i++) + { + if(szBuff[i] == L'\n') + { + SecureHelper::strncpyW_x(pDispInfo->szText, _countof(pDispInfo->szText), &szBuff[i + 1], _TRUNCATE); + break; + } + } +#if (_WIN32_IE >= 0x0300) + if(nRet > 0) // string was loaded, save it + pDispInfo->uFlags |= TTF_DI_SETITEM; +#endif // (_WIN32_IE >= 0x0300) + } + + return 0; + } +#endif // !_WIN32_WCE + +// Implementation - chevron menu support +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + bool PrepareChevronMenu(_ChevronMenuInfo& cmi) + { + // get rebar and toolbar + REBARBANDINFO rbbi = { RunTimeHelper::SizeOf_REBARBANDINFO() }; + rbbi.fMask = RBBIM_CHILD; + BOOL bRet = (BOOL)::SendMessage(cmi.lpnm->hdr.hwndFrom, RB_GETBANDINFO, cmi.lpnm->uBand, (LPARAM)&rbbi); + ATLASSERT(bRet); + + // assume the band is a toolbar + ATL::CWindow wnd = rbbi.hwndChild; + int nCount = (int)wnd.SendMessage(TB_BUTTONCOUNT); + if(nCount <= 0) // probably not a toolbar + return false; + + // check if it's a command bar + CMenuHandle menuCmdBar = (HMENU)wnd.SendMessage(CBRM_GETMENU); + cmi.bCmdBar = (menuCmdBar.m_hMenu != NULL); + + // build a menu from hidden items + CMenuHandle menu; + bRet = menu.CreatePopupMenu(); + ATLASSERT(bRet); + RECT rcClient = { 0 }; + bRet = wnd.GetClientRect(&rcClient); + ATLASSERT(bRet); + for(int i = 0; i < nCount; i++) + { + TBBUTTON tbb = { 0 }; + bRet = (BOOL)wnd.SendMessage(TB_GETBUTTON, i, (LPARAM)&tbb); + ATLASSERT(bRet); + // skip hidden buttons + if((tbb.fsState & TBSTATE_HIDDEN) != 0) + continue; + RECT rcButton = { 0 }; + bRet = (BOOL)wnd.SendMessage(TB_GETITEMRECT, i, (LPARAM)&rcButton); + ATLASSERT(bRet); + bool bEnabled = ((tbb.fsState & TBSTATE_ENABLED) != 0); + if(rcButton.right > rcClient.right) + { + if(tbb.fsStyle & BTNS_SEP) + { + if(menu.GetMenuItemCount() > 0) + menu.AppendMenu(MF_SEPARATOR); + } + else if(cmi.bCmdBar) + { + const int cchBuff = 200; + TCHAR szBuff[cchBuff] = { 0 }; + CMenuItemInfo mii; + mii.fMask = MIIM_TYPE | MIIM_SUBMENU; + mii.dwTypeData = szBuff; + mii.cch = cchBuff; + bRet = menuCmdBar.GetMenuItemInfo(i, TRUE, &mii); + ATLASSERT(bRet); + // Note: CmdBar currently supports only drop-down items + ATLASSERT(::IsMenu(mii.hSubMenu)); + bRet = menu.AppendMenu(MF_STRING | MF_POPUP | (bEnabled ? MF_ENABLED : MF_GRAYED), (UINT_PTR)mii.hSubMenu, mii.dwTypeData); + ATLASSERT(bRet); + } + else + { + // get button's text + const int cchBuff = 200; + TCHAR szBuff[cchBuff] = { 0 }; + LPTSTR lpstrText = szBuff; + TBBUTTONINFO tbbi = { 0 }; + tbbi.cbSize = sizeof(TBBUTTONINFO); + tbbi.dwMask = TBIF_TEXT; + tbbi.pszText = szBuff; + tbbi.cchText = cchBuff; + if(wnd.SendMessage(TB_GETBUTTONINFO, tbb.idCommand, (LPARAM)&tbbi) == -1 || lstrlen(szBuff) == 0) + { + // no text for this button, try a resource string + lpstrText = _T(""); + int nRet = ::LoadString(ModuleHelper::GetResourceInstance(), tbb.idCommand, szBuff, cchBuff); + for(int n = 0; n < nRet; n++) + { + if(szBuff[n] == _T('\n')) + { + lpstrText = &szBuff[n + 1]; + break; + } + } + } + bRet = menu.AppendMenu(MF_STRING | (bEnabled ? MF_ENABLED : MF_GRAYED), tbb.idCommand, lpstrText); + ATLASSERT(bRet); + } + } + } + + if(menu.GetMenuItemCount() == 0) // no hidden buttons after all + { + menu.DestroyMenu(); + ::MessageBeep((UINT)-1); + return false; + } + + cmi.hMenu = menu; + return true; + } + + void DisplayChevronMenu(_ChevronMenuInfo& cmi) + { +#ifndef TPM_VERPOSANIMATION + const UINT TPM_VERPOSANIMATION = 0x1000L; // Menu animation flag +#endif + // convert chevron rect to screen coordinates + ATL::CWindow wndFrom = cmi.lpnm->hdr.hwndFrom; + POINT pt = { cmi.lpnm->rc.left, cmi.lpnm->rc.bottom }; + wndFrom.MapWindowPoints(NULL, &pt, 1); + RECT rc = cmi.lpnm->rc; + wndFrom.MapWindowPoints(NULL, &rc); + // set up flags and rect + UINT uMenuFlags = TPM_LEFTBUTTON | TPM_VERTICAL | TPM_LEFTALIGN | TPM_TOPALIGN | (!AtlIsOldWindows() ? TPM_VERPOSANIMATION : 0); + TPMPARAMS TPMParams = { 0 }; + TPMParams.cbSize = sizeof(TPMPARAMS); + TPMParams.rcExclude = rc; + // check if this window has a command bar + HWND hWndCmdBar = (HWND)::SendMessage(m_hWnd, CBRM_GETCMDBAR, 0, 0L); + if(::IsWindow(hWndCmdBar)) + { + CBRPOPUPMENU CBRPopupMenu = { sizeof(CBRPOPUPMENU), cmi.hMenu, uMenuFlags, pt.x, pt.y, &TPMParams }; + ::SendMessage(hWndCmdBar, CBRM_TRACKPOPUPMENU, 0, (LPARAM)&CBRPopupMenu); + } + else + { + CMenuHandle menu = cmi.hMenu; + menu.TrackPopupMenuEx(uMenuFlags, pt.x, pt.y, m_hWnd, &TPMParams); + } + } + + void CleanupChevronMenu(_ChevronMenuInfo& cmi) + { + CMenuHandle menu = cmi.hMenu; + // if menu is from a command bar, detach submenus so they are not destroyed + if(cmi.bCmdBar) + { + for(int i = menu.GetMenuItemCount() - 1; i >=0; i--) + menu.RemoveMenu(i, MF_BYPOSITION); + } + // destroy menu + menu.DestroyMenu(); + // convert chevron rect to screen coordinates + ATL::CWindow wndFrom = cmi.lpnm->hdr.hwndFrom; + RECT rc = cmi.lpnm->rc; + wndFrom.MapWindowPoints(NULL, &rc); + // eat next message if click is on the same button + MSG msg = { 0 }; + if(::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE) && ::PtInRect(&rc, msg.pt)) + ::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_REMOVE); + } +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) +}; + + +template +class ATL_NO_VTABLE CFrameWindowImpl : public CFrameWindowImplBase< TBase, TWinTraits > +{ +public: + HWND Create(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + HMENU hMenu = NULL, LPVOID lpCreateParam = NULL) + { + ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc); + + dwStyle = T::GetWndStyle(dwStyle); + dwExStyle = T::GetWndExStyle(dwExStyle); + + if(rect.m_lpRect == NULL) + rect.m_lpRect = &TBase::rcDefault; + + return CFrameWindowImplBase< TBase, TWinTraits >::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, hMenu, atom, lpCreateParam); + } + + HWND CreateEx(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL) + { + const int cchName = 256; + TCHAR szWindowName[cchName]; + szWindowName[0] = 0; +#ifndef _WIN32_WCE + ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName); + HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID)); +#else // CE specific + ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName); + + // This always needs to be NULL for Windows CE. + // Frame Window menus have to go onto the CommandBar. + // Use CreateSimpleCECommandBar + HMENU hMenu = NULL; +#endif // _WIN32_WCE + + T* pT = static_cast(this); + HWND hWnd = pT->Create(hWndParent, rect, szWindowName, dwStyle, dwExStyle, hMenu, lpCreateParam); + + if(hWnd != NULL) + m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID)); + + return hWnd; + } + + BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) + { + if(nResourceID == 0) + nResourceID = T::GetWndClassInfo().m_uCommonResourceID; +#ifndef _WIN32_WCE + ATLASSERT(!::IsWindow(m_hWndToolBar)); + m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE, dwStyle, nID); + return (m_hWndToolBar != NULL); +#else // CE specific + HWND hWnd= T::CreateSimpleToolBarCtrl(m_hWndCECommandBar, nResourceID, TRUE, dwStyle, nID); + return (hWnd != NULL); +#endif // _WIN32_WCE + } + +#ifdef _WIN32_WCE + // CE specific variant that returns the handle of the toolbar + HWND CreateSimpleCEToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) + { + if(nResourceID == 0) + nResourceID = T::GetWndClassInfo().m_uCommonResourceID; + + return T::CreateSimpleToolBarCtrl(m_hWndCECommandBar, nResourceID, TRUE, dwStyle, nID); + } +#endif // _WIN32_WCE + +// message map and handlers + typedef CFrameWindowImplBase< TBase, TWinTraits > _baseClass; + + BEGIN_MSG_MAP(CFrameWindowImpl) + MESSAGE_HANDLER(WM_SIZE, OnSize) +#ifndef _ATL_NO_REBAR_SUPPORT +#if (_WIN32_IE >= 0x0400) + NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize) +#endif // (_WIN32_IE >= 0x0400) +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed) +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) +#endif // !_ATL_NO_REBAR_SUPPORT + CHAIN_MSG_MAP(_baseClass) + END_MSG_MAP() + + LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if(wParam != SIZE_MINIMIZED) + { + T* pT = static_cast(this); + pT->UpdateLayout(); + } + bHandled = FALSE; + return 1; + } + +#ifndef _ATL_NO_REBAR_SUPPORT +#if (_WIN32_IE >= 0x0400) + LRESULT OnReBarAutoSize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->UpdateLayout(FALSE); + return 0; + } +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) + LRESULT OnChevronPushed(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) + { + T* pT = static_cast(this); + _ChevronMenuInfo cmi = { NULL, (LPNMREBARCHEVRON)pnmh, false }; + if(!pT->PrepareChevronMenu(cmi)) + { + bHandled = FALSE; + return 1; + } + // display a popup menu with hidden items + pT->DisplayChevronMenu(cmi); + // cleanup + pT->CleanupChevronMenu(cmi); + return 0; + } +#endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) +#endif // !_ATL_NO_REBAR_SUPPORT +}; + + +/////////////////////////////////////////////////////////////////////////////// +// AtlCreateSimpleToolBar - helper for creating simple toolbars + +#ifndef _WIN32_WCE + +inline HWND AtlCreateSimpleToolBar(HWND hWndParent, UINT nResourceID, BOOL bInitialSeparator = FALSE, + DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) +{ + return CFrameWindowImplBase<>::CreateSimpleToolBarCtrl(hWndParent, nResourceID, bInitialSeparator, dwStyle, nID); +} + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CMDIWindow + +#ifndef _WIN32_WCE + +#ifndef _WTL_MDIWINDOWMENU_TEXT +#define _WTL_MDIWINDOWMENU_TEXT _T("&Window") +#endif + +class CMDIWindow : public ATL::CWindow +{ +public: +// Data members + HWND m_hWndMDIClient; + HMENU m_hMenu; + +// Constructors + CMDIWindow(HWND hWnd = NULL) : ATL::CWindow(hWnd), m_hWndMDIClient(NULL), m_hMenu(NULL) + { } + + CMDIWindow& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + +// Operations + HWND MDIGetActive(BOOL* lpbMaximized = NULL) + { + ATLASSERT(::IsWindow(m_hWndMDIClient)); + return (HWND)::SendMessage(m_hWndMDIClient, WM_MDIGETACTIVE, 0, (LPARAM)lpbMaximized); + } + + void MDIActivate(HWND hWndChildToActivate) + { + ATLASSERT(::IsWindow(m_hWndMDIClient)); + ATLASSERT(::IsWindow(hWndChildToActivate)); + ::SendMessage(m_hWndMDIClient, WM_MDIACTIVATE, (WPARAM)hWndChildToActivate, 0); + } + + void MDINext(HWND hWndChild, BOOL bPrevious = FALSE) + { + ATLASSERT(::IsWindow(m_hWndMDIClient)); + ATLASSERT(hWndChild == NULL || ::IsWindow(hWndChild)); + ::SendMessage(m_hWndMDIClient, WM_MDINEXT, (WPARAM)hWndChild, (LPARAM)bPrevious); + } + + void MDIMaximize(HWND hWndChildToMaximize) + { + ATLASSERT(::IsWindow(m_hWndMDIClient)); + ATLASSERT(::IsWindow(hWndChildToMaximize)); + ::SendMessage(m_hWndMDIClient, WM_MDIMAXIMIZE, (WPARAM)hWndChildToMaximize, 0); + } + + void MDIRestore(HWND hWndChildToRestore) + { + ATLASSERT(::IsWindow(m_hWndMDIClient)); + ATLASSERT(::IsWindow(hWndChildToRestore)); + ::SendMessage(m_hWndMDIClient, WM_MDIRESTORE, (WPARAM)hWndChildToRestore, 0); + } + + void MDIDestroy(HWND hWndChildToDestroy) + { + ATLASSERT(::IsWindow(m_hWndMDIClient)); + ATLASSERT(::IsWindow(hWndChildToDestroy)); + ::SendMessage(m_hWndMDIClient, WM_MDIDESTROY, (WPARAM)hWndChildToDestroy, 0); + } + + BOOL MDICascade(UINT uFlags = 0) + { + ATLASSERT(::IsWindow(m_hWndMDIClient)); + return (BOOL)::SendMessage(m_hWndMDIClient, WM_MDICASCADE, (WPARAM)uFlags, 0); + } + + BOOL MDITile(UINT uFlags = MDITILE_HORIZONTAL) + { + ATLASSERT(::IsWindow(m_hWndMDIClient)); + return (BOOL)::SendMessage(m_hWndMDIClient, WM_MDITILE, (WPARAM)uFlags, 0); + } + + void MDIIconArrange() + { + ATLASSERT(::IsWindow(m_hWndMDIClient)); + ::SendMessage(m_hWndMDIClient, WM_MDIICONARRANGE, 0, 0); + } + + HMENU MDISetMenu(HMENU hMenuFrame, HMENU hMenuWindow) + { + ATLASSERT(::IsWindow(m_hWndMDIClient)); + return (HMENU)::SendMessage(m_hWndMDIClient, WM_MDISETMENU, (WPARAM)hMenuFrame, (LPARAM)hMenuWindow); + } + + HMENU MDIRefreshMenu() + { + ATLASSERT(::IsWindow(m_hWndMDIClient)); + return (HMENU)::SendMessage(m_hWndMDIClient, WM_MDIREFRESHMENU, 0, 0); + } + +// Additional operations + static HMENU GetStandardWindowMenu(HMENU hMenu) + { + int nCount = ::GetMenuItemCount(hMenu); + if(nCount == -1) + return NULL; + int nLen = ::GetMenuString(hMenu, nCount - 2, NULL, 0, MF_BYPOSITION); + if(nLen == 0) + return NULL; + CTempBuffer buff; + LPTSTR lpszText = buff.Allocate(nLen + 1); + if(lpszText == NULL) + return NULL; + if(::GetMenuString(hMenu, nCount - 2, lpszText, nLen + 1, MF_BYPOSITION) != nLen) + return NULL; + if(lstrcmp(lpszText, _WTL_MDIWINDOWMENU_TEXT) != 0) + return NULL; + return ::GetSubMenu(hMenu, nCount - 2); + } + + void SetMDIFrameMenu() + { + HMENU hWindowMenu = GetStandardWindowMenu(m_hMenu); + MDISetMenu(m_hMenu, hWindowMenu); + MDIRefreshMenu(); + ::DrawMenuBar(GetMDIFrame()); + } + + HWND GetMDIFrame() const + { + return ::GetParent(m_hWndMDIClient); + } +}; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CMDIFrameWindowImpl + +#ifndef _WIN32_WCE + +// MDI child command chaining macro (only for MDI frame windows) +#define CHAIN_MDI_CHILD_COMMANDS() \ + if(uMsg == WM_COMMAND) \ + { \ + HWND hWndChild = MDIGetActive(); \ + if(hWndChild != NULL) \ + ::SendMessage(hWndChild, uMsg, wParam, lParam); \ + } + +template +class ATL_NO_VTABLE CMDIFrameWindowImpl : public CFrameWindowImplBase +{ +public: + HWND Create(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + HMENU hMenu = NULL, LPVOID lpCreateParam = NULL) + { + m_hMenu = hMenu; + ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc); + + dwStyle = T::GetWndStyle(dwStyle); + dwExStyle = T::GetWndExStyle(dwExStyle); + + if(rect.m_lpRect == NULL) + rect.m_lpRect = &TBase::rcDefault; + + return CFrameWindowImplBase::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, hMenu, atom, lpCreateParam); + } + + HWND CreateEx(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL) + { + const int cchName = 256; + TCHAR szWindowName[cchName]; + szWindowName[0] = 0; + ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName); + HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID)); + + T* pT = static_cast(this); + HWND hWnd = pT->Create(hWndParent, rect, szWindowName, dwStyle, dwExStyle, hMenu, lpCreateParam); + + if(hWnd != NULL) + m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID)); + + return hWnd; + } + + BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) + { + ATLASSERT(!::IsWindow(m_hWndToolBar)); + if(nResourceID == 0) + nResourceID = T::GetWndClassInfo().m_uCommonResourceID; + m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE, dwStyle, nID); + return (m_hWndToolBar != NULL); + } + + virtual WNDPROC GetWindowProc() + { + return MDIFrameWindowProc; + } + + static LRESULT CALLBACK MDIFrameWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + CMDIFrameWindowImpl< T, TBase, TWinTraits >* pThis = (CMDIFrameWindowImpl< T, TBase, TWinTraits >*)hWnd; + // set a ptr to this message and save the old value +#if (_ATL_VER >= 0x0700) + ATL::_ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam); + const ATL::_ATL_MSG* pOldMsg = pThis->m_pCurrentMsg; +#else // !(_ATL_VER >= 0x0700) + MSG msg = { pThis->m_hWnd, uMsg, wParam, lParam, 0, { 0, 0 } }; + const MSG* pOldMsg = pThis->m_pCurrentMsg; +#endif // !(_ATL_VER >= 0x0700) + pThis->m_pCurrentMsg = &msg; + // pass to the message map to process + LRESULT lRes = 0; + BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0); + // restore saved value for the current message + ATLASSERT(pThis->m_pCurrentMsg == &msg); + pThis->m_pCurrentMsg = pOldMsg; + // do the default processing if message was not handled + if(!bRet) + { + if(uMsg != WM_NCDESTROY) + lRes = pThis->DefWindowProc(uMsg, wParam, lParam); + else + { + // unsubclass, if needed + LONG_PTR pfnWndProc = ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC); + lRes = pThis->DefWindowProc(uMsg, wParam, lParam); + if(pThis->m_pfnSuperWindowProc != ::DefWindowProc && ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC) == pfnWndProc) + ::SetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC, (LONG_PTR)pThis->m_pfnSuperWindowProc); +#if (_ATL_VER >= 0x0700) + // mark window as destryed + pThis->m_dwState |= WINSTATE_DESTROYED; +#else // !(_ATL_VER >= 0x0700) + // clear out window handle + HWND hWnd = pThis->m_hWnd; + pThis->m_hWnd = NULL; + // clean up after window is destroyed + pThis->OnFinalMessage(hWnd); +#endif // !(_ATL_VER >= 0x0700) + } + } +#if (_ATL_VER >= 0x0700) + if(pThis->m_dwState & WINSTATE_DESTROYED && pThis->m_pCurrentMsg == NULL) + { + // clear out window handle + HWND hWnd = pThis->m_hWnd; + pThis->m_hWnd = NULL; + pThis->m_dwState &= ~WINSTATE_DESTROYED; + // clean up after window is destroyed + pThis->OnFinalMessage(hWnd); + } +#endif // (_ATL_VER >= 0x0700) + return lRes; + } + + // Overriden to call DefWindowProc which uses DefFrameProc + LRESULT DefWindowProc() + { + const MSG* pMsg = m_pCurrentMsg; + LRESULT lRes = 0; + if (pMsg != NULL) + lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg->lParam); + return lRes; + } + + LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) + { + return ::DefFrameProc(m_hWnd, m_hWndMDIClient, uMsg, wParam, lParam); + } + + BOOL PreTranslateMessage(MSG* pMsg) + { + if(CFrameWindowImplBase::PreTranslateMessage(pMsg)) + return TRUE; + return ::TranslateMDISysAccel(m_hWndMDIClient, pMsg); + } + + HWND CreateMDIClient(HMENU hWindowMenu = NULL, UINT nID = ATL_IDW_CLIENT, UINT nFirstChildID = ATL_IDM_FIRST_MDICHILD) + { + DWORD dwStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | MDIS_ALLCHILDSTYLES; + DWORD dwExStyle = WS_EX_CLIENTEDGE; + + CLIENTCREATESTRUCT ccs = { 0 }; + ccs.hWindowMenu = hWindowMenu; + ccs.idFirstChild = nFirstChildID; + + if((GetStyle() & (WS_HSCROLL | WS_VSCROLL)) != 0) + { + // parent MDI frame's scroll styles move to the MDICLIENT + dwStyle |= (GetStyle() & (WS_HSCROLL | WS_VSCROLL)); + + // fast way to turn off the scrollbar bits (without a resize) + ModifyStyle(WS_HSCROLL | WS_VSCROLL, 0, SWP_NOREDRAW | SWP_FRAMECHANGED); + } + + // Create MDICLIENT window + m_hWndClient = ::CreateWindowEx(dwExStyle, _T("MDIClient"), NULL, + dwStyle, 0, 0, 1, 1, m_hWnd, (HMENU)LongToHandle(nID), + ModuleHelper::GetModuleInstance(), (LPVOID)&ccs); + if (m_hWndClient == NULL) + { + ATLTRACE2(atlTraceUI, 0, _T("MDI Frame failed to create MDICLIENT.\n")); + return NULL; + } + + // Move it to the top of z-order + ::BringWindowToTop(m_hWndClient); + + // set as MDI client window + m_hWndMDIClient = m_hWndClient; + + // update to proper size + T* pT = static_cast(this); + pT->UpdateLayout(); + + return m_hWndClient; + } + + typedef CFrameWindowImplBase _baseClass; + + BEGIN_MSG_MAP(CMDIFrameWindowImpl) + MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) + MESSAGE_HANDLER(WM_MDISETMENU, OnMDISetMenu) +#ifndef _ATL_NO_REBAR_SUPPORT +#if (_WIN32_IE >= 0x0400) + NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize) +#endif // (_WIN32_IE >= 0x0400) +#if (_WIN32_IE >= 0x0500) + NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed) +#endif // (_WIN32_IE >= 0x0500) +#endif // !_ATL_NO_REBAR_SUPPORT + CHAIN_MSG_MAP(_baseClass) + END_MSG_MAP() + + LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + if(wParam != SIZE_MINIMIZED) + { + T* pT = static_cast(this); + pT->UpdateLayout(); + } + // message must be handled, otherwise DefFrameProc would resize the client again + return 0; + } + + LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + // don't allow CFrameWindowImplBase to handle this one + return DefWindowProc(uMsg, wParam, lParam); + } + + LRESULT OnMDISetMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + SetMDIFrameMenu(); + return 0; + } + +#ifndef _ATL_NO_REBAR_SUPPORT +#if (_WIN32_IE >= 0x0400) + LRESULT OnReBarAutoSize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->UpdateLayout(FALSE); + return 0; + } +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0500) + LRESULT OnChevronPushed(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) + { + T* pT = static_cast(this); + _ChevronMenuInfo cmi = { NULL, (LPNMREBARCHEVRON)pnmh, false }; + if(!pT->PrepareChevronMenu(cmi)) + { + bHandled = FALSE; + return 1; + } + // display a popup menu with hidden items + pT->DisplayChevronMenu(cmi); + // cleanup + pT->CleanupChevronMenu(cmi); + return 0; + } +#endif // (_WIN32_IE >= 0x0500) +#endif // !_ATL_NO_REBAR_SUPPORT +}; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CMDIChildWindowImpl + +#ifndef _WIN32_WCE + +template +class ATL_NO_VTABLE CMDIChildWindowImpl : public CFrameWindowImplBase +{ +public: + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + UINT nMenuID = 0, LPVOID lpCreateParam = NULL) + { + ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc); + + if(nMenuID != 0) + m_hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(nMenuID)); + + dwStyle = T::GetWndStyle(dwStyle); + dwExStyle = T::GetWndExStyle(dwExStyle); + + dwExStyle |= WS_EX_MDICHILD; // force this one + m_pfnSuperWindowProc = ::DefMDIChildProc; + m_hWndMDIClient = hWndParent; + ATLASSERT(::IsWindow(m_hWndMDIClient)); + + if(rect.m_lpRect == NULL) + rect.m_lpRect = &TBase::rcDefault; + + // If the currently active MDI child is maximized, we want to create this one maximized too + ATL::CWindow wndParent = hWndParent; + BOOL bMaximized = FALSE; + wndParent.SendMessage(WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized); + if(bMaximized) + wndParent.SetRedraw(FALSE); + + HWND hWnd = CFrameWindowImplBase::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, (UINT)0U, atom, lpCreateParam); + + if(bMaximized) + { + // Maximize and redraw everything + if(hWnd != NULL) + MDIMaximize(hWnd); + wndParent.SetRedraw(TRUE); + wndParent.RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); + ::SetFocus(GetMDIFrame()); // focus will be set back to this window + } + else if(hWnd != NULL && ::IsWindowVisible(m_hWnd) && !::IsChild(hWnd, ::GetFocus())) + { + ::SetFocus(hWnd); + } + + return hWnd; + } + + HWND CreateEx(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR lpcstrWindowName = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL) + { + const int cchName = 256; + TCHAR szWindowName[cchName]; + szWindowName[0] = 0; + if(lpcstrWindowName == NULL) + { + ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName); + lpcstrWindowName = szWindowName; + } + + T* pT = static_cast(this); + HWND hWnd = pT->Create(hWndParent, rect, lpcstrWindowName, dwStyle, dwExStyle, T::GetWndClassInfo().m_uCommonResourceID, lpCreateParam); + + if(hWnd != NULL) + m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID)); + + return hWnd; + } + + BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) + { + ATLASSERT(!::IsWindow(m_hWndToolBar)); + if(nResourceID == 0) + nResourceID = T::GetWndClassInfo().m_uCommonResourceID; + m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE, dwStyle, nID); + return (m_hWndToolBar != NULL); + } + + BOOL UpdateClientEdge(LPRECT lpRect = NULL) + { + // only adjust for active MDI child window + HWND hWndChild = MDIGetActive(); + if(hWndChild != NULL && hWndChild != m_hWnd) + return FALSE; + + // need to adjust the client edge style as max/restore happens + DWORD dwStyle = ::GetWindowLong(m_hWndMDIClient, GWL_EXSTYLE); + DWORD dwNewStyle = dwStyle; + if(hWndChild != NULL && ((GetExStyle() & WS_EX_CLIENTEDGE) == 0) && ((GetStyle() & WS_MAXIMIZE) != 0)) + dwNewStyle &= ~(WS_EX_CLIENTEDGE); + else + dwNewStyle |= WS_EX_CLIENTEDGE; + + if(dwStyle != dwNewStyle) + { + // SetWindowPos will not move invalid bits + ::RedrawWindow(m_hWndMDIClient, NULL, NULL, + RDW_INVALIDATE | RDW_ALLCHILDREN); + // remove/add WS_EX_CLIENTEDGE to MDI client area + ::SetWindowLong(m_hWndMDIClient, GWL_EXSTYLE, dwNewStyle); + ::SetWindowPos(m_hWndMDIClient, NULL, 0, 0, 0, 0, + SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | + SWP_NOZORDER | SWP_NOCOPYBITS); + + // return new client area + if (lpRect != NULL) + ::GetClientRect(m_hWndMDIClient, lpRect); + + return TRUE; + } + + return FALSE; + } + + typedef CFrameWindowImplBase _baseClass; + BEGIN_MSG_MAP(CMDIChildWindowImpl) + MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_WINDOWPOSCHANGED, OnWindowPosChanged) + MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate) + MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect) + MESSAGE_HANDLER(WM_MDIACTIVATE, OnMDIActivate) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) +#ifndef _ATL_NO_REBAR_SUPPORT +#if (_WIN32_IE >= 0x0400) + NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize) +#endif // (_WIN32_IE >= 0x0400) +#if (_WIN32_IE >= 0x0500) + NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed) +#endif // (_WIN32_IE >= 0x0500) +#endif // !_ATL_NO_REBAR_SUPPORT + CHAIN_MSG_MAP(_baseClass) + END_MSG_MAP() + + LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + DefWindowProc(uMsg, wParam, lParam); // needed for MDI children + if(wParam != SIZE_MINIMIZED) + { + T* pT = static_cast(this); + pT->UpdateLayout(); + } + return 0; + } + + LRESULT OnWindowPosChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + // update MDI client edge and adjust MDI child rect + LPWINDOWPOS lpWndPos = (LPWINDOWPOS)lParam; + + if(!(lpWndPos->flags & SWP_NOSIZE)) + { + RECT rectClient; + if(UpdateClientEdge(&rectClient) && ((GetStyle() & WS_MAXIMIZE) != 0)) + { + ::AdjustWindowRectEx(&rectClient, GetStyle(), FALSE, GetExStyle()); + lpWndPos->x = rectClient.left; + lpWndPos->y = rectClient.top; + lpWndPos->cx = rectClient.right - rectClient.left; + lpWndPos->cy = rectClient.bottom - rectClient.top; + } + } + + bHandled = FALSE; + return 1; + } + + LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + LRESULT lRes = DefWindowProc(uMsg, wParam, lParam); + + // Activate this MDI window if needed + if(lRes == MA_ACTIVATE || lRes == MA_ACTIVATEANDEAT) + { + if(MDIGetActive() != m_hWnd) + MDIActivate(m_hWnd); + } + + return lRes; + } + + LRESULT OnMenuSelect(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + return ::SendMessage(GetMDIFrame(), uMsg, wParam, lParam); + } + + LRESULT OnMDIActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + if((HWND)lParam == m_hWnd && m_hMenu != NULL) + SetMDIFrameMenu(); + else if((HWND)lParam == NULL) + ::SendMessage(GetMDIFrame(), WM_MDISETMENU, 0, 0); + + bHandled = FALSE; + return 1; + } + + LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_hMenu != NULL) + { + ::DestroyMenu(m_hMenu); + m_hMenu = NULL; + } + UpdateClientEdge(); + bHandled = FALSE; + return 1; + } + +#ifndef _ATL_NO_REBAR_SUPPORT +#if (_WIN32_IE >= 0x0400) + LRESULT OnReBarAutoSize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->UpdateLayout(FALSE); + return 0; + } +#endif // (_WIN32_IE >= 0x0400) + +#if (_WIN32_IE >= 0x0500) + LRESULT OnChevronPushed(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) + { + T* pT = static_cast(this); + _ChevronMenuInfo cmi = { NULL, (LPNMREBARCHEVRON)pnmh, false }; + if(!pT->PrepareChevronMenu(cmi)) + { + bHandled = FALSE; + return 1; + } + // display a popup menu with hidden items + pT->DisplayChevronMenu(cmi); + // cleanup + pT->CleanupChevronMenu(cmi); + return 0; + } +#endif // (_WIN32_IE >= 0x0500) +#endif // !_ATL_NO_REBAR_SUPPORT +}; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// COwnerDraw - MI class for owner-draw support + +template +class COwnerDraw +{ +public: +#if (_ATL_VER < 0x0700) + BOOL m_bHandledOD; + + BOOL IsMsgHandled() const + { + return m_bHandledOD; + } + void SetMsgHandled(BOOL bHandled) + { + m_bHandledOD = bHandled; + } +#endif // (_ATL_VER < 0x0700) + +// Message map and handlers + BEGIN_MSG_MAP(COwnerDraw< T >) + MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem) + MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem) + MESSAGE_HANDLER(WM_COMPAREITEM, OnCompareItem) + MESSAGE_HANDLER(WM_DELETEITEM, OnDeleteItem) + ALT_MSG_MAP(1) + MESSAGE_HANDLER(OCM_DRAWITEM, OnDrawItem) + MESSAGE_HANDLER(OCM_MEASUREITEM, OnMeasureItem) + MESSAGE_HANDLER(OCM_COMPAREITEM, OnCompareItem) + MESSAGE_HANDLER(OCM_DELETEITEM, OnDeleteItem) + END_MSG_MAP() + + LRESULT OnDrawItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + T* pT = static_cast(this); + pT->SetMsgHandled(TRUE); + pT->DrawItem((LPDRAWITEMSTRUCT)lParam); + bHandled = pT->IsMsgHandled(); + return (LRESULT)TRUE; + } + + LRESULT OnMeasureItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + T* pT = static_cast(this); + pT->SetMsgHandled(TRUE); + pT->MeasureItem((LPMEASUREITEMSTRUCT)lParam); + bHandled = pT->IsMsgHandled(); + return (LRESULT)TRUE; + } + + LRESULT OnCompareItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + T* pT = static_cast(this); + pT->SetMsgHandled(TRUE); + bHandled = pT->IsMsgHandled(); + return (LRESULT)pT->CompareItem((LPCOMPAREITEMSTRUCT)lParam); + } + + LRESULT OnDeleteItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + T* pT = static_cast(this); + pT->SetMsgHandled(TRUE); + pT->DeleteItem((LPDELETEITEMSTRUCT)lParam); + bHandled = pT->IsMsgHandled(); + return (LRESULT)TRUE; + } + +// Overrideables + void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/) + { + // must be implemented + ATLASSERT(FALSE); + } + + void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) + { + if(lpMeasureItemStruct->CtlType != ODT_MENU) + { + // return default height for a system font + T* pT = static_cast(this); + HWND hWnd = pT->GetDlgItem(lpMeasureItemStruct->CtlID); + CClientDC dc(hWnd); + TEXTMETRIC tm = { 0 }; + dc.GetTextMetrics(&tm); + + lpMeasureItemStruct->itemHeight = tm.tmHeight; + } + else + lpMeasureItemStruct->itemHeight = ::GetSystemMetrics(SM_CYMENU); + } + + int CompareItem(LPCOMPAREITEMSTRUCT /*lpCompareItemStruct*/) + { + // all items are equal + return 0; + } + + void DeleteItem(LPDELETEITEMSTRUCT /*lpDeleteItemStruct*/) + { + // default - nothing + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// Update UI macros + +// these build the Update UI map inside a class definition +#define BEGIN_UPDATE_UI_MAP(thisClass) \ + static const CUpdateUIBase::_AtlUpdateUIMap* GetUpdateUIMap() \ + { \ + static const _AtlUpdateUIMap theMap[] = \ + { + +#define UPDATE_ELEMENT(nID, wType) \ + { nID, wType }, + +#define END_UPDATE_UI_MAP() \ + { (WORD)-1, 0 } \ + }; \ + return theMap; \ + } + +/////////////////////////////////////////////////////////////////////////////// +// CUpdateUI - manages UI elements updating + +class CUpdateUIBase +{ +public: + // constants + enum + { + // UI element type + UPDUI_MENUPOPUP = 0x0001, + UPDUI_MENUBAR = 0x0002, + UPDUI_CHILDWINDOW = 0x0004, + UPDUI_TOOLBAR = 0x0008, + UPDUI_STATUSBAR = 0x0010, + // state + UPDUI_ENABLED = 0x0000, + UPDUI_DISABLED = 0x0100, + UPDUI_CHECKED = 0x0200, + UPDUI_CHECKED2 = 0x0400, + UPDUI_RADIO = 0x0800, + UPDUI_DEFAULT = 0x1000, + UPDUI_TEXT = 0x2000, + // internal state + UPDUI_CLEARDEFAULT = 0x4000, + }; + + // element data + struct _AtlUpdateUIElement + { + HWND m_hWnd; + WORD m_wType; + + bool operator ==(const _AtlUpdateUIElement& e) const + { return (m_hWnd == e.m_hWnd && m_wType == e.m_wType); } + }; + + // map data + struct _AtlUpdateUIMap + { + WORD m_nID; + WORD m_wType; + + bool operator ==(const _AtlUpdateUIMap& e) const + { return (m_nID == e.m_nID && m_wType == e.m_wType); } + }; + + // instance data + struct _AtlUpdateUIData + { + WORD m_wState; + union + { + void* m_lpData; + LPTSTR m_lpstrText; + struct + { + WORD m_nIDFirst; + WORD m_nIDLast; + }; + }; + + bool operator ==(const _AtlUpdateUIData& e) const + { return (m_wState == e.m_wState && m_lpData == e.m_lpData); } + }; + + ATL::CSimpleArray<_AtlUpdateUIElement> m_UIElements; // elements data + const _AtlUpdateUIMap* m_pUIMap; // static UI data + _AtlUpdateUIData* m_pUIData; // instance UI data + WORD m_wDirtyType; // global dirty flag + + bool m_bBlockAccelerators; + + +// Constructor, destructor + CUpdateUIBase() : m_pUIMap(NULL), m_pUIData(NULL), m_wDirtyType(0), m_bBlockAccelerators(false) + { } + + ~CUpdateUIBase() + { + if(m_pUIMap != NULL && m_pUIData != NULL) + { + const _AtlUpdateUIMap* pUIMap = m_pUIMap; + _AtlUpdateUIData* pUIData = m_pUIData; + while(pUIMap->m_nID != (WORD)-1) + { + if(pUIData->m_wState & UPDUI_TEXT) + delete [] pUIData->m_lpstrText; + pUIMap++; + pUIData++; + } + delete [] m_pUIData; + } + } + +// Check for disabled commands + bool UIGetBlockAccelerators() const + { + return m_bBlockAccelerators; + } + + bool UISetBlockAccelerators(bool bBlock) + { + bool bOld = m_bBlockAccelerators; + m_bBlockAccelerators = bBlock; + return bOld; + } + +// Add elements + BOOL UIAddMenuBar(HWND hWnd) // menu bar (main menu) + { + if(hWnd == NULL) + return FALSE; + _AtlUpdateUIElement e; + e.m_hWnd = hWnd; + e.m_wType = UPDUI_MENUBAR; + return m_UIElements.Add(e); + } + + BOOL UIAddToolBar(HWND hWnd) // toolbar + { + if(hWnd == NULL) + return FALSE; + _AtlUpdateUIElement e; + e.m_hWnd = hWnd; + e.m_wType = UPDUI_TOOLBAR; + return m_UIElements.Add(e); + } + + BOOL UIAddStatusBar(HWND hWnd) // status bar + { + if(hWnd == NULL) + return FALSE; + _AtlUpdateUIElement e; + e.m_hWnd = hWnd; + e.m_wType = UPDUI_STATUSBAR; + return m_UIElements.Add(e); + } + + BOOL UIAddChildWindowContainer(HWND hWnd) // child window + { + if(hWnd == NULL) + return FALSE; + _AtlUpdateUIElement e; + e.m_hWnd = hWnd; + e.m_wType = UPDUI_CHILDWINDOW; + return m_UIElements.Add(e); + } + +// Message map for popup menu updates and accelerator blocking + BEGIN_MSG_MAP(CUpdateUIBase) + MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup) + MESSAGE_HANDLER(WM_COMMAND, OnCommand) + END_MSG_MAP() + + LRESULT OnInitMenuPopup(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + bHandled = FALSE; + HMENU hMenu = (HMENU)wParam; + if(hMenu == NULL) + return 1; + _AtlUpdateUIData* pUIData = m_pUIData; + if(pUIData == NULL) + return 1; + const _AtlUpdateUIMap* pMap = m_pUIMap; + while(pMap->m_nID != (WORD)-1) + { + if(pMap->m_wType & UPDUI_MENUPOPUP) + { + UIUpdateMenuBarElement(pMap->m_nID, pUIData, hMenu); + + if((pUIData->m_wState & UPDUI_RADIO) != 0) + ::CheckMenuRadioItem(hMenu, pUIData->m_nIDFirst, pUIData->m_nIDLast, pMap->m_nID, MF_BYCOMMAND); + } + pMap++; + pUIData++; + } + return 0; + } + + LRESULT OnCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + bHandled = FALSE; + if(m_bBlockAccelerators && HIWORD(wParam) == 1) // accelerators only + { + int nID = LOWORD(wParam); + if((UIGetState(nID) & UPDUI_DISABLED) == UPDUI_DISABLED) + { + ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIBase::OnCommand - blocked disabled command 0x%4.4X\n"), nID); + bHandled = TRUE; // eat the command, UI item is disabled + } + } + return 0; + } + +// methods for setting UI element state + BOOL UIEnable(int nID, BOOL bEnable, BOOL bForceUpdate = FALSE) + { + const _AtlUpdateUIMap* pMap = m_pUIMap; + _AtlUpdateUIData* pUIData = m_pUIData; + if(pUIData == NULL) + return FALSE; + + for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) + { + if(nID == (int)pMap->m_nID) + { + if(bEnable) + { + if(pUIData->m_wState & UPDUI_DISABLED) + { + pUIData->m_wState |= pMap->m_wType; + pUIData->m_wState &= ~UPDUI_DISABLED; + } + } + else + { + if(!(pUIData->m_wState & UPDUI_DISABLED)) + { + pUIData->m_wState |= pMap->m_wType; + pUIData->m_wState |= UPDUI_DISABLED; + } + } + + if(bForceUpdate) + pUIData->m_wState |= pMap->m_wType; + if(pUIData->m_wState & pMap->m_wType) + m_wDirtyType |= pMap->m_wType; + + break; // found + } + } + + return TRUE; + } + + BOOL UISetCheck(int nID, int nCheck, BOOL bForceUpdate = FALSE) + { + const _AtlUpdateUIMap* pMap = m_pUIMap; + _AtlUpdateUIData* pUIData = m_pUIData; + if(pUIData == NULL) + return FALSE; + + for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) + { + if(nID == (int)pMap->m_nID) + { + switch(nCheck) + { + case 0: + if((pUIData->m_wState & UPDUI_CHECKED) || (pUIData->m_wState & UPDUI_CHECKED2)) + { + pUIData->m_wState |= pMap->m_wType; + pUIData->m_wState &= ~(UPDUI_CHECKED | UPDUI_CHECKED2); + } + break; + case 1: + if(!(pUIData->m_wState & UPDUI_CHECKED)) + { + pUIData->m_wState |= pMap->m_wType; + pUIData->m_wState &= ~UPDUI_CHECKED2; + pUIData->m_wState |= UPDUI_CHECKED; + } + break; + case 2: + if(!(pUIData->m_wState & UPDUI_CHECKED2)) + { + pUIData->m_wState |= pMap->m_wType; + pUIData->m_wState &= ~UPDUI_CHECKED; + pUIData->m_wState |= UPDUI_CHECKED2; + } + break; + } + + if(bForceUpdate) + pUIData->m_wState |= pMap->m_wType; + if(pUIData->m_wState & pMap->m_wType) + m_wDirtyType |= pMap->m_wType; + + break; // found + } + } + + return TRUE; + } + + // variant that supports bool (checked/not-checked, no intermediate state) + BOOL UISetCheck(int nID, bool bCheck, BOOL bForceUpdate = FALSE) + { + return UISetCheck(nID, bCheck ? 1 : 0, bForceUpdate); + } + + BOOL UISetRadio(int nID, BOOL bRadio, BOOL bForceUpdate = FALSE) + { + const _AtlUpdateUIMap* pMap = m_pUIMap; + _AtlUpdateUIData* pUIData = m_pUIData; + if(pUIData == NULL) + return FALSE; + + for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) + { + if(nID == (int)pMap->m_nID) + { + if(bRadio) + { + if(!(pUIData->m_wState & UPDUI_RADIO)) + { + pUIData->m_wState |= pMap->m_wType; + pUIData->m_wState |= UPDUI_RADIO; + } + } + else + { + if(pUIData->m_wState & UPDUI_RADIO) + { + pUIData->m_wState |= pMap->m_wType; + pUIData->m_wState &= ~UPDUI_RADIO; + } + } + + if(bForceUpdate) + pUIData->m_wState |= pMap->m_wType; + if(pUIData->m_wState & pMap->m_wType) + m_wDirtyType |= pMap->m_wType; + + break; // found + } + } + + return TRUE; + } + + // for menu items + BOOL UISetRadioMenuItem(int nID, int nIDFirst, int nIDLast, BOOL bForceUpdate = FALSE) + { + const _AtlUpdateUIMap* pMap = m_pUIMap; + _AtlUpdateUIData* pUIData = m_pUIData; + if(pUIData == NULL) + return FALSE; + + for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) + { + if(nID == (int)pMap->m_nID) + { + pUIData->m_wState |= pMap->m_wType; + pUIData->m_wState |= UPDUI_RADIO; + pUIData->m_nIDFirst = (WORD)nIDFirst; + pUIData->m_nIDLast = (WORD)nIDLast; + + if(bForceUpdate) + pUIData->m_wState |= pMap->m_wType; + if(pUIData->m_wState & pMap->m_wType) + m_wDirtyType |= pMap->m_wType; + } + else if(pMap->m_nID >= nIDFirst && pMap->m_nID <= nIDLast) + { + if(pUIData->m_wState & UPDUI_RADIO) + { + pUIData->m_wState &= ~pMap->m_wType; + pUIData->m_wState &= ~UPDUI_RADIO; + pUIData->m_nIDFirst = 0; + pUIData->m_nIDLast = 0; + } + } + + if(pMap->m_nID == nIDLast) + break; + } + + return TRUE; + } + + BOOL UISetText(int nID, LPCTSTR lpstrText, BOOL bForceUpdate = FALSE) + { + const _AtlUpdateUIMap* pMap = m_pUIMap; + _AtlUpdateUIData* pUIData = m_pUIData; + if(pUIData == NULL) + return FALSE; + if(lpstrText == NULL) + lpstrText = _T(""); + + for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) + { + if(nID == (int)pMap->m_nID) + { + if(pUIData->m_lpstrText == NULL || lstrcmp(pUIData->m_lpstrText, lpstrText)) + { + delete [] pUIData->m_lpstrText; + pUIData->m_lpstrText = NULL; + int nStrLen = lstrlen(lpstrText); + ATLTRY(pUIData->m_lpstrText = new TCHAR[nStrLen + 1]); + if(pUIData->m_lpstrText == NULL) + { + ATLTRACE2(atlTraceUI, 0, _T("UISetText - memory allocation failed\n")); + break; + } + SecureHelper::strcpy_x(pUIData->m_lpstrText, nStrLen + 1, lpstrText); + pUIData->m_wState |= (UPDUI_TEXT | pMap->m_wType); + } + + if(bForceUpdate) + pUIData->m_wState |= (UPDUI_TEXT | pMap->m_wType); + if(pUIData->m_wState & pMap->m_wType) + m_wDirtyType |= pMap->m_wType; + + break; // found + } + } + + return TRUE; + } + + BOOL UISetDefault(int nID, BOOL bDefault, BOOL bForceUpdate = FALSE) + { + const _AtlUpdateUIMap* pMap = m_pUIMap; + _AtlUpdateUIData* pUIData = m_pUIData; + if(pUIData == NULL) + return FALSE; + + for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) + { + if(nID == (int)pMap->m_nID) + { + if(bDefault) + { + if((pUIData->m_wState & UPDUI_DEFAULT) == 0) + { + pUIData->m_wState |= pMap->m_wType; + pUIData->m_wState |= UPDUI_DEFAULT; + } + } + else + { + if((pUIData->m_wState & UPDUI_DEFAULT) != 0) + { + pUIData->m_wState |= pMap->m_wType; + pUIData->m_wState &= ~UPDUI_DEFAULT; + pUIData->m_wState |= UPDUI_CLEARDEFAULT; + } + } + + if(bForceUpdate) + pUIData->m_wState |= pMap->m_wType; + if(pUIData->m_wState & pMap->m_wType) + m_wDirtyType |= pMap->m_wType; + + break; // found + } + } + + return TRUE; + } + +// methods for complete state set/get + BOOL UISetState(int nID, DWORD dwState) + { + const _AtlUpdateUIMap* pMap = m_pUIMap; + _AtlUpdateUIData* pUIData = m_pUIData; + if(pUIData == NULL) + return FALSE; + for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) + { + if(nID == (int)pMap->m_nID) + { + pUIData->m_wState = (WORD)(dwState | pMap->m_wType); + m_wDirtyType |= pMap->m_wType; + break; // found + } + } + return TRUE; + } + + DWORD UIGetState(int nID) + { + const _AtlUpdateUIMap* pMap = m_pUIMap; + _AtlUpdateUIData* pUIData = m_pUIData; + if(pUIData == NULL) + return 0; + for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) + { + if(nID == (int)pMap->m_nID) + return pUIData->m_wState; + } + return 0; + } + +// methods for updating UI +#ifndef _WIN32_WCE + BOOL UIUpdateMenuBar(BOOL bForceUpdate = FALSE, BOOL bMainMenu = FALSE) + { + if(!(m_wDirtyType & UPDUI_MENUBAR) && !bForceUpdate) + return TRUE; + + const _AtlUpdateUIMap* pMap = m_pUIMap; + _AtlUpdateUIData* pUIData = m_pUIData; + if(pUIData == NULL) + return FALSE; + + while(pMap->m_nID != (WORD)-1) + { + for(int i = 0; i < m_UIElements.GetSize(); i++) + { + if(m_UIElements[i].m_wType == UPDUI_MENUBAR) + { + HMENU hMenu = ::GetMenu(m_UIElements[i].m_hWnd); + if(hMenu != NULL && (pUIData->m_wState & UPDUI_MENUBAR) && (pMap->m_wType & UPDUI_MENUBAR)) + UIUpdateMenuBarElement(pMap->m_nID, pUIData, hMenu); + } + if(bMainMenu) + ::DrawMenuBar(m_UIElements[i].m_hWnd); + } + pMap++; + pUIData->m_wState &= ~UPDUI_MENUBAR; + if(pUIData->m_wState & UPDUI_TEXT) + { + delete [] pUIData->m_lpstrText; + pUIData->m_lpstrText = NULL; + pUIData->m_wState &= ~UPDUI_TEXT; + } + pUIData++; + } + + m_wDirtyType &= ~UPDUI_MENUBAR; + return TRUE; + } +#endif // !_WIN32_WCE + + BOOL UIUpdateToolBar(BOOL bForceUpdate = FALSE) + { + if(!(m_wDirtyType & UPDUI_TOOLBAR) && !bForceUpdate) + return TRUE; + + const _AtlUpdateUIMap* pMap = m_pUIMap; + _AtlUpdateUIData* pUIData = m_pUIData; + if(pUIData == NULL) + return FALSE; + + while(pMap->m_nID != (WORD)-1) + { + for(int i = 0; i < m_UIElements.GetSize(); i++) + { + if(m_UIElements[i].m_wType == UPDUI_TOOLBAR) + { + if((pUIData->m_wState & UPDUI_TOOLBAR) && (pMap->m_wType & UPDUI_TOOLBAR)) + UIUpdateToolBarElement(pMap->m_nID, pUIData, m_UIElements[i].m_hWnd); + } + } + pMap++; + pUIData->m_wState &= ~UPDUI_TOOLBAR; + pUIData++; + } + + m_wDirtyType &= ~UPDUI_TOOLBAR; + return TRUE; + } + + BOOL UIUpdateStatusBar(BOOL bForceUpdate = FALSE) + { + if(!(m_wDirtyType & UPDUI_STATUSBAR) && !bForceUpdate) + return TRUE; + + const _AtlUpdateUIMap* pMap = m_pUIMap; + _AtlUpdateUIData* pUIData = m_pUIData; + if(pUIData == NULL) + return FALSE; + + while(pMap->m_nID != (WORD)-1) + { + for(int i = 0; i < m_UIElements.GetSize(); i++) + { + if(m_UIElements[i].m_wType == UPDUI_STATUSBAR) + { + if((pUIData->m_wState & UPDUI_STATUSBAR) && (pMap->m_wType & UPDUI_STATUSBAR)) + UIUpdateStatusBarElement(pMap->m_nID, pUIData, m_UIElements[i].m_hWnd); + } + } + pMap++; + pUIData->m_wState &= ~UPDUI_STATUSBAR; + if(pUIData->m_wState & UPDUI_TEXT) + { + delete [] pUIData->m_lpstrText; + pUIData->m_lpstrText = NULL; + pUIData->m_wState &= ~UPDUI_TEXT; + } + pUIData++; + } + + m_wDirtyType &= ~UPDUI_STATUSBAR; + return TRUE; + } + + BOOL UIUpdateChildWindows(BOOL bForceUpdate = FALSE) + { + if(!(m_wDirtyType & UPDUI_CHILDWINDOW) && !bForceUpdate) + return TRUE; + + const _AtlUpdateUIMap* pMap = m_pUIMap; + _AtlUpdateUIData* pUIData = m_pUIData; + if(pUIData == NULL) + return FALSE; + + while(pMap->m_nID != (WORD)-1) + { + for(int i = 0; i < m_UIElements.GetSize(); i++) + { + if(m_UIElements[i].m_wType == UPDUI_CHILDWINDOW) + { + if((pUIData->m_wState & UPDUI_CHILDWINDOW) && (pMap->m_wType & UPDUI_CHILDWINDOW)) + UIUpdateChildWindow(pMap->m_nID, pUIData, m_UIElements[i].m_hWnd); + } + } + pMap++; + pUIData->m_wState &= ~UPDUI_CHILDWINDOW; + if(pUIData->m_wState & UPDUI_TEXT) + { + delete [] pUIData->m_lpstrText; + pUIData->m_lpstrText = NULL; + pUIData->m_wState &= ~UPDUI_TEXT; + } + pUIData++; + } + + m_wDirtyType &= ~UPDUI_CHILDWINDOW; + return TRUE; + } + +// internal element specific methods + static void UIUpdateMenuBarElement(int nID, _AtlUpdateUIData* pUIData, HMENU hMenu) + { +#ifndef _WIN32_WCE + if((pUIData->m_wState & UPDUI_CLEARDEFAULT) != 0) + { + ::SetMenuDefaultItem(hMenu, (UINT)-1, 0); + pUIData->m_wState &= ~UPDUI_CLEARDEFAULT; + } +#endif // !_WIN32_WCE + + CMenuItemInfo mii; + mii.fMask = MIIM_STATE; + mii.wID = nID; + +#ifndef _WIN32_WCE + if((pUIData->m_wState & UPDUI_DISABLED) != 0) + mii.fState |= MFS_DISABLED | MFS_GRAYED; + else + mii.fState |= MFS_ENABLED; + + if((pUIData->m_wState & UPDUI_CHECKED) != 0) + mii.fState |= MFS_CHECKED; + else + mii.fState |= MFS_UNCHECKED; + + if((pUIData->m_wState & UPDUI_DEFAULT) != 0) + mii.fState |= MFS_DEFAULT; +#else // CE specific + // ::SetMenuItemInfo() can't disable or check menu items + // on Windows CE, so we have to do that directly + UINT uEnable = MF_BYCOMMAND; + if((pUIData->m_wState & UPDUI_DISABLED) != 0) + uEnable |= MF_GRAYED; + else + uEnable |= MF_ENABLED; + ::EnableMenuItem(hMenu, nID, uEnable); + + UINT uCheck = MF_BYCOMMAND; + if((pUIData->m_wState & UPDUI_CHECKED) != 0) + uCheck |= MF_CHECKED; + else + uCheck |= MF_UNCHECKED; + ::CheckMenuItem(hMenu, nID, uCheck); +#endif // _WIN32_WCE + + if((pUIData->m_wState & UPDUI_TEXT) != 0) + { + CMenuItemInfo miiNow; + miiNow.fMask = MIIM_TYPE; + miiNow.wID = nID; + if(::GetMenuItemInfo(hMenu, nID, FALSE, &miiNow)) + { + mii.fMask |= MIIM_TYPE; + // MFT_BITMAP and MFT_SEPARATOR don't go together with MFT_STRING +#ifndef _WIN32_WCE + mii.fType |= (miiNow.fType & ~(MFT_BITMAP | MFT_SEPARATOR)) | MFT_STRING; +#else // CE specific + mii.fType |= (miiNow.fType & ~(MFT_SEPARATOR)) | MFT_STRING; +#endif // _WIN32_WCE + mii.dwTypeData = pUIData->m_lpstrText; + } + } + + ::SetMenuItemInfo(hMenu, nID, FALSE, &mii); + } + + static void UIUpdateToolBarElement(int nID, _AtlUpdateUIData* pUIData, HWND hWndToolBar) + { + // Note: only handles enabled/disabled, checked state, and radio (press) + ::SendMessage(hWndToolBar, TB_ENABLEBUTTON, nID, (LPARAM)(pUIData->m_wState & UPDUI_DISABLED) ? FALSE : TRUE); + ::SendMessage(hWndToolBar, TB_CHECKBUTTON, nID, (LPARAM)(pUIData->m_wState & UPDUI_CHECKED) ? TRUE : FALSE); + ::SendMessage(hWndToolBar, TB_INDETERMINATE, nID, (LPARAM)(pUIData->m_wState & UPDUI_CHECKED2) ? TRUE : FALSE); + ::SendMessage(hWndToolBar, TB_PRESSBUTTON, nID, (LPARAM)(pUIData->m_wState & UPDUI_RADIO) ? TRUE : FALSE); + } + + static void UIUpdateStatusBarElement(int nID, _AtlUpdateUIData* pUIData, HWND hWndStatusBar) + { + // Note: only handles text + if(pUIData->m_wState & UPDUI_TEXT) + ::SendMessage(hWndStatusBar, SB_SETTEXT, nID, (LPARAM)pUIData->m_lpstrText); + } + + static void UIUpdateChildWindow(int nID, _AtlUpdateUIData* pUIData, HWND hWnd) + { + HWND hChild = ::GetDlgItem(hWnd, nID); + + ::EnableWindow(hChild, (pUIData->m_wState & UPDUI_DISABLED) ? FALSE : TRUE); + // for check and radio, assume that window is a button + int nCheck = BST_UNCHECKED; + if(pUIData->m_wState & UPDUI_CHECKED || pUIData->m_wState & UPDUI_RADIO) + nCheck = BST_CHECKED; + else if(pUIData->m_wState & UPDUI_CHECKED2) + nCheck = BST_INDETERMINATE; + ::SendMessage(hChild, BM_SETCHECK, nCheck, 0L); + if(pUIData->m_wState & UPDUI_DEFAULT) + { + DWORD dwRet = (DWORD)::SendMessage(hWnd, DM_GETDEFID, 0, 0L); + if(HIWORD(dwRet) == DC_HASDEFID) + { + HWND hOldDef = ::GetDlgItem(hWnd, (int)(short)LOWORD(dwRet)); + // remove BS_DEFPUSHBUTTON + ::SendMessage(hOldDef, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0)); + } + ::SendMessage(hWnd, DM_SETDEFID, nID, 0L); + } + if(pUIData->m_wState & UPDUI_TEXT) + ::SetWindowText(hChild, pUIData->m_lpstrText); + } +}; + +template +class CUpdateUI : public CUpdateUIBase +{ +public: + CUpdateUI() + { + T* pT = static_cast(this); + pT; + const _AtlUpdateUIMap* pMap = pT->GetUpdateUIMap(); + m_pUIMap = pMap; + ATLASSERT(m_pUIMap != NULL); + int nCount; + for(nCount = 1; pMap->m_nID != (WORD)-1; nCount++) + pMap++; + + // check for duplicates (debug only) +#ifdef _DEBUG + for(int i = 0; i < nCount; i++) + { + for(int j = 0; j < nCount; j++) + { + // shouldn't have duplicates in the update UI map + if(i != j) + ATLASSERT(m_pUIMap[j].m_nID != m_pUIMap[i].m_nID); + } + } +#endif // _DEBUG + + ATLTRY(m_pUIData = new _AtlUpdateUIData[nCount]); + ATLASSERT(m_pUIData != NULL); + + if(m_pUIData != NULL) + memset(m_pUIData, 0, sizeof(_AtlUpdateUIData) * nCount); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CDynamicUpdateUI - allows update elements to dynamically added and removed +// in addition to a static update UI map + +template +class CDynamicUpdateUI : public CUpdateUIBase +{ +public: +// Data members + ATL::CSimpleArray<_AtlUpdateUIMap> m_arrUIMap; // copy of the static UI data + ATL::CSimpleArray<_AtlUpdateUIData> m_arrUIData; // instance UI data + +// Constructor/destructor + CDynamicUpdateUI() + { + T* pT = static_cast(this); + pT; + const _AtlUpdateUIMap* pMap = pT->GetUpdateUIMap(); + ATLASSERT(pMap != NULL); + + for(;;) + { + BOOL bRet = m_arrUIMap.Add(*(_AtlUpdateUIMap*)pMap); + ATLASSERT(bRet); + + if(bRet != FALSE) + { + _AtlUpdateUIData data = { 0, NULL }; + bRet = m_arrUIData.Add(data); + ATLASSERT(bRet); + } + + if(pMap->m_nID == (WORD)-1) + break; + + pMap++; + } + + ATLASSERT(m_arrUIMap.GetSize() == m_arrUIData.GetSize()); + +#ifdef _DEBUG + // check for duplicates (debug only) + for(int i = 0; i < m_arrUIMap.GetSize(); i++) + { + for(int j = 0; j < m_arrUIMap.GetSize(); j++) + { + // shouldn't have duplicates in the update UI map + if(i != j) + ATLASSERT(m_arrUIMap[j].m_nID != m_arrUIMap[i].m_nID); + } + } +#endif // _DEBUG + + // Set internal data pointers to point to the new data arrays + m_pUIMap = m_arrUIMap.m_aT; + m_pUIData = m_arrUIData.m_aT; + } + + ~CDynamicUpdateUI() + { + for(int i = 0; i < m_arrUIData.GetSize(); i++) + { + if((m_arrUIData[i].m_wState & UPDUI_TEXT) != 0) + delete [] m_arrUIData[i].m_lpstrText; + } + + // Reset internal data pointers (memory will be released by CSimpleArray d-tor) + m_pUIMap = NULL; + m_pUIData = NULL; + } + +// Methods for dynamically adding and removing update elements + bool UIAddUpdateElement(WORD nID, WORD wType) + { + // check for duplicates + for(int i = 0; i < m_arrUIMap.GetSize(); i++) + { + // shouldn't have duplicates in the update UI map + ATLASSERT(m_arrUIMap[i].m_nID != nID); + if(m_arrUIMap[i].m_nID == nID) + return false; + } + + bool bRetVal = false; + + // Add new end element + _AtlUpdateUIMap uumEnd = { (WORD)-1, 0 }; + BOOL bRet = m_arrUIMap.Add(uumEnd); + ATLASSERT(bRet); + + if(bRet != FALSE) + { + _AtlUpdateUIData uud = { 0, NULL }; + bRet = m_arrUIData.Add(uud); + ATLASSERT(bRet); + + // Set new data to the previous end element + if(bRet != FALSE) + { + int nSize = m_arrUIMap.GetSize(); + _AtlUpdateUIMap uum = { nID, wType }; + m_arrUIMap.SetAtIndex(nSize - 2, uum); + m_arrUIData.SetAtIndex(nSize - 2, uud); + + // Set internal data pointers again, just in case that memory moved + m_pUIMap = m_arrUIMap.m_aT; + m_pUIData = m_arrUIData.m_aT; + + bRetVal = true; + } + } + + return bRetVal; + } + + bool UIRemoveUpdateElement(WORD nID) + { + bool bRetVal = false; + + for(int i = 0; i < m_arrUIMap.GetSize(); i++) + { + if(m_arrUIMap[i].m_nID == nID) + { + BOOL bRet = m_arrUIMap.RemoveAt(i); + ATLASSERT(bRet); + bRet = m_arrUIData.RemoveAt(i); + ATLASSERT(bRet); + + bRetVal = true; + break; + } + } + + return bRetVal; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CAutoUpdateUI : Automatic mapping of UI elements + +template +class CAutoUpdateUI : public CDynamicUpdateUI +{ +public: + LPCTSTR UIGetText(int nID) + { + for(int i = 0; i < m_arrUIMap.GetSize(); i++) + { + if(m_arrUIMap[i].m_nID == nID) + return m_arrUIData[i].m_lpstrText; + } + + return NULL; + } + +// Element + template + bool UIAddElement(UINT nID) + { + // check for existing UI map element + for(int i = 0; i < m_arrUIMap.GetSize(); i++) + { + if(m_arrUIMap[i].m_nID == nID) + { + // set requested type + m_arrUIMap[i].m_wType |= t_wType; + return true; + } + } + + // Add element to UI map with requested type + return UIAddUpdateElement((WORD)nID, t_wType); + } + + template + bool UIRemoveElement(UINT nID) + { + for(int i = 0; i < m_arrUIMap.GetSize(); i++) + { + if(m_arrUIMap[i].m_nID == nID) // matching UI map element + { + WORD wType = m_arrUIMap[i].m_wType & ~t_wType; + if (wType) // has other types + { + m_arrUIMap[i].m_wType = wType; // keep other types + return true; + } + else + { + return UIRemoveUpdateElement((WORD)nID); + } + } + } + + return false; + } + +// Menu + bool UIAddMenu(HMENU hMenu, bool bSetText = false) + { +#if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) + using ATL::GetMenuString; +#endif + ATLASSERT(::IsMenu(hMenu)); + MENUITEMINFO mii = {sizeof(MENUITEMINFO), MIIM_TYPE | MIIM_ID | MIIM_SUBMENU}; + + // Complete the UI map + for (INT uItem = 0; CMenuHandle(hMenu).GetMenuItemInfo(uItem, TRUE, &mii); uItem++) + { + if(mii.hSubMenu) + { + // Add submenu to UI map + UIAddMenu(mii.hSubMenu, bSetText); + } + else if (mii.wID) + { + // Add element to UI map + UIAddElement(mii.wID); +#if !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800) + if (bSetText) + { + TCHAR sText[64] = { 0 }; + if (GetMenuString(hMenu, uItem, sText, 64, MF_BYPOSITION)) + UISetText(mii.wID, sText); + } +#else + bSetText; +#endif // !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800) + } + } + + return true; + } + + bool UIAddMenu(UINT uID, bool bSetText = false) + { + CMenu menu; + ATLVERIFY(menu.LoadMenu(uID)); + return UIAddMenu(menu, bSetText); + } + +// ToolBar +#ifndef BTNS_SEP + #define BTNS_SEP TBSTYLE_SEP +#endif // BTNS_SEP compatibility + +#if !defined(_WIN32_WCE) || (defined(_AUTOUI_CE_TOOLBAR) && defined(TBIF_BYINDEX)) + bool UIAddToolBar(HWND hWndToolBar) + { + ATLASSERT(::IsWindow(hWndToolBar)); + TBBUTTONINFO tbbi = {sizeof TBBUTTONINFO, TBIF_COMMAND | TBIF_STYLE | TBIF_BYINDEX}; + + // Add toolbar buttons + for (int uItem = 0; ::SendMessage(hWndToolBar, TB_GETBUTTONINFO, uItem, (LPARAM)&tbbi) != -1; uItem++) + { + if (tbbi.fsStyle ^ BTNS_SEP) + UIAddElement(tbbi.idCommand); + } + + // Add embedded controls if any + if (::GetWindow(hWndToolBar, GW_CHILD)) + UIAddChildWindowContainer(hWndToolBar); + + return (CUpdateUIBase::UIAddToolBar(hWndToolBar) != FALSE); + } +#endif // !defined(_WIN32_WCE) || (defined(_AUTOUI_CE_TOOLBAR) && defined(TBIF_BYINDEX)) + +// Container + bool UIAddChildWindowContainer(HWND hWnd) + { + ATLASSERT(::IsWindow(hWnd)); + + // Add children controls if any + for (ATL::CWindow wCtl = ::GetWindow(hWnd, GW_CHILD); wCtl.IsWindow(); wCtl = wCtl.GetWindow(GW_HWNDNEXT)) + { + if (int id = wCtl.GetDlgCtrlID()) + UIAddElement(id); + } + + return (CUpdateUIBase::UIAddChildWindowContainer(hWnd) != FALSE); + } + +// StatusBar + BOOL UIUpdateStatusBar(BOOL bForceUpdate = FALSE) + { + if(!(m_wDirtyType & UPDUI_STATUSBAR) && !bForceUpdate) + return TRUE; + + for(int i = 0; i < m_arrUIMap.GetSize(); i++) + { + for(int e = 0; e < m_UIElements.GetSize(); e++) + { + if((m_UIElements[e].m_wType == UPDUI_STATUSBAR) && + (m_arrUIMap[i].m_wType & UPDUI_STATUSBAR) && + (m_arrUIData[i].m_wState & UPDUI_STATUSBAR)) + { + UIUpdateStatusBarElement(m_arrUIMap[i].m_nID, &m_arrUIData[i], m_UIElements[e].m_hWnd); + m_arrUIData[i].m_wState &= ~UPDUI_STATUSBAR; + if(m_arrUIData[i].m_wState & UPDUI_TEXT) + m_arrUIData[i].m_wState &= ~UPDUI_TEXT; + } + } + } + + m_wDirtyType &= ~UPDUI_STATUSBAR; + return TRUE; + } + + bool UIAddStatusBar(HWND hWndStatusBar, INT nPanes = 1) + { + ATLASSERT(::IsWindow(hWndStatusBar)); + + // Add StatusBar panes + for (int iPane = 0; iPane < nPanes; iPane++) + UIAddElement(ID_DEFAULT_PANE + iPane); + + return (CUpdateUIBase::UIAddStatusBar(hWndStatusBar) != FALSE); + } + +// UI Map used if derived class has none + BEGIN_UPDATE_UI_MAP(CAutoUpdateUI) + END_UPDATE_UI_MAP() +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CDialogResize - provides support for resizing dialog controls +// (works for any window that has child controls) + +// Put CDialogResize in the list of base classes for a dialog (or even plain window), +// then implement DLGRESIZE map by specifying controls and groups of control +// and using DLSZ_* values to specify how are they supposed to be resized. +// +// Notes: +// - Resizeable border (WS_THICKFRAME style) should be set in the dialog template +// for top level dialogs (popup or overlapped), so that users can resize the dialog. +// - Some flags cannot be combined; for instance DLSZ_CENTER_X overrides DLSZ_SIZE_X, +// DLSZ_SIZE_X overrides DLSZ_MOVE_X. X and Y flags can be combined. +// - Order of controls is important - group controls are resized and moved based +// on the position of the previous control in a group. + +// dialog resize map macros +#define BEGIN_DLGRESIZE_MAP(thisClass) \ + static const _AtlDlgResizeMap* GetDlgResizeMap() \ + { \ + static const _AtlDlgResizeMap theMap[] = \ + { + +#define END_DLGRESIZE_MAP() \ + { -1, 0 }, \ + }; \ + return theMap; \ + } + +#define DLGRESIZE_CONTROL(id, flags) \ + { id, flags }, + +#define BEGIN_DLGRESIZE_GROUP() \ + { -1, _DLSZ_BEGIN_GROUP }, + +#define END_DLGRESIZE_GROUP() \ + { -1, _DLSZ_END_GROUP }, + + +template +class CDialogResize +{ +public: +// Data declarations and members + enum + { + DLSZ_SIZE_X = 0x00000001, + DLSZ_SIZE_Y = 0x00000002, + DLSZ_MOVE_X = 0x00000004, + DLSZ_MOVE_Y = 0x00000008, + DLSZ_REPAINT = 0x00000010, + DLSZ_CENTER_X = 0x00000020, + DLSZ_CENTER_Y = 0x00000040, + + // internal use only + _DLSZ_BEGIN_GROUP = 0x00001000, + _DLSZ_END_GROUP = 0x00002000, + _DLSZ_GRIPPER = 0x00004000 + }; + + struct _AtlDlgResizeMap + { + int m_nCtlID; + DWORD m_dwResizeFlags; + }; + + struct _AtlDlgResizeData + { + int m_nCtlID; + DWORD m_dwResizeFlags; + RECT m_rect; + + int GetGroupCount() const + { + return (int)LOBYTE(HIWORD(m_dwResizeFlags)); + } + + void SetGroupCount(int nCount) + { + ATLASSERT(nCount > 0 && nCount < 256); + DWORD dwCount = (DWORD)MAKELONG(0, MAKEWORD(nCount, 0)); + m_dwResizeFlags &= 0xFF00FFFF; + m_dwResizeFlags |= dwCount; + } + + bool operator ==(const _AtlDlgResizeData& r) const + { return (m_nCtlID == r.m_nCtlID && m_dwResizeFlags == r.m_dwResizeFlags); } + }; + + ATL::CSimpleArray<_AtlDlgResizeData> m_arrData; + SIZE m_sizeDialog; + POINT m_ptMinTrackSize; + bool m_bGripper; + + +// Constructor + CDialogResize() : m_bGripper(false) + { + m_sizeDialog.cx = 0; + m_sizeDialog.cy = 0; + m_ptMinTrackSize.x = -1; + m_ptMinTrackSize.y = -1; + } + +// Operations + void DlgResize_Init(bool bAddGripper = true, bool bUseMinTrackSize = true, DWORD dwForceStyle = WS_CLIPCHILDREN) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + + DWORD dwStyle = pT->GetStyle(); + +#ifdef _DEBUG + // Debug only: Check if top level dialogs have a resizeable border. + if(((dwStyle & WS_CHILD) == 0) && ((dwStyle & WS_THICKFRAME) == 0)) + ATLTRACE2(atlTraceUI, 0, _T("DlgResize_Init - warning: top level dialog without the WS_THICKFRAME style - user cannot resize it\n")); +#endif // _DEBUG + + // Force specified styles (default WS_CLIPCHILDREN reduces flicker) + if((dwStyle & dwForceStyle) != dwForceStyle) + pT->ModifyStyle(0, dwForceStyle); + + // Adding this style removes an empty icon that dialogs with WS_THICKFRAME have. + // Setting icon to NULL is required when XP themes are active. + // Note: This will not prevent adding an icon for the dialog using SetIcon() + if((dwStyle & WS_CHILD) == 0) + { + pT->ModifyStyleEx(0, WS_EX_DLGMODALFRAME); + if(pT->GetIcon(FALSE) == NULL) + pT->SetIcon(NULL, FALSE); + } + + // Cleanup in case of multiple initialization + // block: first check for the gripper control, destroy it if needed + { + ATL::CWindow wndGripper = pT->GetDlgItem(ATL_IDW_STATUS_BAR); + if(wndGripper.IsWindow() && m_arrData.GetSize() > 0 && (m_arrData[0].m_dwResizeFlags & _DLSZ_GRIPPER) != 0) + wndGripper.DestroyWindow(); + } + // clear out everything else + m_arrData.RemoveAll(); + m_sizeDialog.cx = 0; + m_sizeDialog.cy = 0; + m_ptMinTrackSize.x = -1; + m_ptMinTrackSize.y = -1; + + // Get initial dialog client size + RECT rectDlg = { 0 }; + pT->GetClientRect(&rectDlg); + m_sizeDialog.cx = rectDlg.right; + m_sizeDialog.cy = rectDlg.bottom; + +#ifndef _WIN32_WCE + // Create gripper if requested + m_bGripper = false; + if(bAddGripper) + { + // shouldn't exist already + ATLASSERT(!::IsWindow(pT->GetDlgItem(ATL_IDW_STATUS_BAR))); + if(!::IsWindow(pT->GetDlgItem(ATL_IDW_STATUS_BAR))) + { + ATL::CWindow wndGripper; + wndGripper.Create(_T("SCROLLBAR"), pT->m_hWnd, rectDlg, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SBS_SIZEBOX | SBS_SIZEGRIP | SBS_SIZEBOXBOTTOMRIGHTALIGN, 0, ATL_IDW_STATUS_BAR); + ATLASSERT(wndGripper.IsWindow()); + if(wndGripper.IsWindow()) + { + m_bGripper = true; + RECT rectCtl = { 0 }; + wndGripper.GetWindowRect(&rectCtl); + ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rectCtl, 2); + _AtlDlgResizeData data = { ATL_IDW_STATUS_BAR, DLSZ_MOVE_X | DLSZ_MOVE_Y | DLSZ_REPAINT | _DLSZ_GRIPPER, { rectCtl.left, rectCtl.top, rectCtl.right, rectCtl.bottom } }; + m_arrData.Add(data); + } + } + } +#else // CE specific + bAddGripper; // avoid level 4 warning +#endif // _WIN32_WCE + + // Get min track position if requested + if(bUseMinTrackSize) + { + if((dwStyle & WS_CHILD) != 0) + { + RECT rect = { 0 }; + pT->GetClientRect(&rect); + m_ptMinTrackSize.x = rect.right - rect.left; + m_ptMinTrackSize.y = rect.bottom - rect.top; + } + else + { + RECT rect = { 0 }; + pT->GetWindowRect(&rect); + m_ptMinTrackSize.x = rect.right - rect.left; + m_ptMinTrackSize.y = rect.bottom - rect.top; + } + } + + // Walk the map and initialize data + const _AtlDlgResizeMap* pMap = pT->GetDlgResizeMap(); + ATLASSERT(pMap != NULL); + int nGroupStart = -1; + for(int nCount = 1; !(pMap->m_nCtlID == -1 && pMap->m_dwResizeFlags == 0); nCount++, pMap++) + { + if(pMap->m_nCtlID == -1) + { + switch(pMap->m_dwResizeFlags) + { + case _DLSZ_BEGIN_GROUP: + ATLASSERT(nGroupStart == -1); + nGroupStart = m_arrData.GetSize(); + break; + case _DLSZ_END_GROUP: + { + ATLASSERT(nGroupStart != -1); + int nGroupCount = m_arrData.GetSize() - nGroupStart; + m_arrData[nGroupStart].SetGroupCount(nGroupCount); + nGroupStart = -1; + } + break; + default: + ATLASSERT(FALSE && _T("Invalid DLGRESIZE Map Entry")); + break; + } + } + else + { + // this ID conflicts with the default gripper one + ATLASSERT(m_bGripper ? (pMap->m_nCtlID != ATL_IDW_STATUS_BAR) : TRUE); + + ATL::CWindow ctl = pT->GetDlgItem(pMap->m_nCtlID); + ATLASSERT(ctl.IsWindow()); + RECT rectCtl = { 0 }; + ctl.GetWindowRect(&rectCtl); + ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rectCtl, 2); + + DWORD dwGroupFlag = (nGroupStart != -1 && m_arrData.GetSize() == nGroupStart) ? _DLSZ_BEGIN_GROUP : 0; + _AtlDlgResizeData data = { pMap->m_nCtlID, pMap->m_dwResizeFlags | dwGroupFlag, { rectCtl.left, rectCtl.top, rectCtl.right, rectCtl.bottom } }; + m_arrData.Add(data); + } + } + ATLASSERT((nGroupStart == -1) && _T("No End Group Entry in the DLGRESIZE Map")); + } + + void DlgResize_UpdateLayout(int cxWidth, int cyHeight) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + + // Restrict minimum size if requested + if(((pT->GetStyle() & WS_CHILD) != 0) && m_ptMinTrackSize.x != -1 && m_ptMinTrackSize.y != -1) + { + if(cxWidth < m_ptMinTrackSize.x) + cxWidth = m_ptMinTrackSize.x; + if(cyHeight < m_ptMinTrackSize.y) + cyHeight = m_ptMinTrackSize.y; + } + + BOOL bVisible = pT->IsWindowVisible(); + if(bVisible) + pT->SetRedraw(FALSE); + + for(int i = 0; i < m_arrData.GetSize(); i++) + { + if((m_arrData[i].m_dwResizeFlags & _DLSZ_BEGIN_GROUP) != 0) // start of a group + { + int nGroupCount = m_arrData[i].GetGroupCount(); + ATLASSERT(nGroupCount > 0 && i + nGroupCount - 1 < m_arrData.GetSize()); + RECT rectGroup = m_arrData[i].m_rect; + + int j = 1; + for(j = 1; j < nGroupCount; j++) + { + rectGroup.left = min(rectGroup.left, m_arrData[i + j].m_rect.left); + rectGroup.top = min(rectGroup.top, m_arrData[i + j].m_rect.top); + rectGroup.right = max(rectGroup.right, m_arrData[i + j].m_rect.right); + rectGroup.bottom = max(rectGroup.bottom, m_arrData[i + j].m_rect.bottom); + } + + for(j = 0; j < nGroupCount; j++) + { + _AtlDlgResizeData* pDataPrev = NULL; + if(j > 0) + pDataPrev = &(m_arrData[i + j - 1]); + pT->DlgResize_PositionControl(cxWidth, cyHeight, rectGroup, m_arrData[i + j], true, pDataPrev); + } + + i += nGroupCount - 1; // increment to skip all group controls + } + else // one control entry + { + RECT rectGroup = { 0, 0, 0, 0 }; + pT->DlgResize_PositionControl(cxWidth, cyHeight, rectGroup, m_arrData[i], false); + } + } + + if(bVisible) + pT->SetRedraw(TRUE); + + pT->RedrawWindow(NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); + } + +// Message map and handlers + BEGIN_MSG_MAP(CDialogResize) + MESSAGE_HANDLER(WM_SIZE, OnSize) +#ifndef _WIN32_WCE + MESSAGE_HANDLER(WM_GETMINMAXINFO, OnGetMinMaxInfo) +#endif // _WIN32_WCE + END_MSG_MAP() + + LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); +#ifndef _WIN32_WCE + if(m_bGripper) + { + ATL::CWindow wndGripper = pT->GetDlgItem(ATL_IDW_STATUS_BAR); + if(wParam == SIZE_MAXIMIZED) + wndGripper.ShowWindow(SW_HIDE); + else if(wParam == SIZE_RESTORED) + wndGripper.ShowWindow(SW_SHOW); + } +#endif // _WIN32_WCE + if(wParam != SIZE_MINIMIZED) + { + ATLASSERT(::IsWindow(pT->m_hWnd)); + pT->DlgResize_UpdateLayout(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + } + return 0; + } + +#ifndef _WIN32_WCE + LRESULT OnGetMinMaxInfo(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) + { + if(m_ptMinTrackSize.x != -1 && m_ptMinTrackSize.y != -1) + { + LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam; + lpMMI->ptMinTrackSize = m_ptMinTrackSize; + } + return 0; + } +#endif // _WIN32_WCE + +// Implementation + bool DlgResize_PositionControl(int cxWidth, int cyHeight, RECT& rectGroup, _AtlDlgResizeData& data, bool bGroup, + _AtlDlgResizeData* pDataPrev = NULL) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + ATL::CWindow ctl; + RECT rectCtl = { 0 }; + + ctl = pT->GetDlgItem(data.m_nCtlID); + if(!ctl.GetWindowRect(&rectCtl)) + return false; + ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rectCtl, 2); + + if(bGroup) + { + if((data.m_dwResizeFlags & DLSZ_CENTER_X) != 0) + { + int cxRight = rectGroup.right + cxWidth - m_sizeDialog.cx; + int cxCtl = data.m_rect.right - data.m_rect.left; + rectCtl.left = rectGroup.left + (cxRight - rectGroup.left - cxCtl) / 2; + rectCtl.right = rectCtl.left + cxCtl; + } + else if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_MOVE_X)) != 0) + { + rectCtl.left = rectGroup.left + ::MulDiv(data.m_rect.left - rectGroup.left, rectGroup.right - rectGroup.left + (cxWidth - m_sizeDialog.cx), rectGroup.right - rectGroup.left); + + if((data.m_dwResizeFlags & DLSZ_SIZE_X) != 0) + { + rectCtl.right = rectGroup.left + ::MulDiv(data.m_rect.right - rectGroup.left, rectGroup.right - rectGroup.left + (cxWidth - m_sizeDialog.cx), rectGroup.right - rectGroup.left); + + if(pDataPrev != NULL) + { + ATL::CWindow ctlPrev = pT->GetDlgItem(pDataPrev->m_nCtlID); + RECT rcPrev = { 0 }; + ctlPrev.GetWindowRect(&rcPrev); + ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rcPrev, 2); + int dxAdjust = (rectCtl.left - rcPrev.right) - (data.m_rect.left - pDataPrev->m_rect.right); + rcPrev.right += dxAdjust; + ctlPrev.SetWindowPos(NULL, &rcPrev, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE); + } + } + else + { + rectCtl.right = rectCtl.left + (data.m_rect.right - data.m_rect.left); + } + } + + if((data.m_dwResizeFlags & DLSZ_CENTER_Y) != 0) + { + int cyBottom = rectGroup.bottom + cyHeight - m_sizeDialog.cy; + int cyCtl = data.m_rect.bottom - data.m_rect.top; + rectCtl.top = rectGroup.top + (cyBottom - rectGroup.top - cyCtl) / 2; + rectCtl.bottom = rectCtl.top + cyCtl; + } + else if((data.m_dwResizeFlags & (DLSZ_SIZE_Y | DLSZ_MOVE_Y)) != 0) + { + rectCtl.top = rectGroup.top + ::MulDiv(data.m_rect.top - rectGroup.top, rectGroup.bottom - rectGroup.top + (cyHeight - m_sizeDialog.cy), rectGroup.bottom - rectGroup.top); + + if((data.m_dwResizeFlags & DLSZ_SIZE_Y) != 0) + { + rectCtl.bottom = rectGroup.top + ::MulDiv(data.m_rect.bottom - rectGroup.top, rectGroup.bottom - rectGroup.top + (cyHeight - m_sizeDialog.cy), rectGroup.bottom - rectGroup.top); + + if(pDataPrev != NULL) + { + ATL::CWindow ctlPrev = pT->GetDlgItem(pDataPrev->m_nCtlID); + RECT rcPrev = { 0 }; + ctlPrev.GetWindowRect(&rcPrev); + ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rcPrev, 2); + int dxAdjust = (rectCtl.top - rcPrev.bottom) - (data.m_rect.top - pDataPrev->m_rect.bottom); + rcPrev.bottom += dxAdjust; + ctlPrev.SetWindowPos(NULL, &rcPrev, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE); + } + } + else + { + rectCtl.bottom = rectCtl.top + (data.m_rect.bottom - data.m_rect.top); + } + } + } + else // no group + { + if((data.m_dwResizeFlags & DLSZ_CENTER_X) != 0) + { + int cxCtl = data.m_rect.right - data.m_rect.left; + rectCtl.left = (cxWidth - cxCtl) / 2; + rectCtl.right = rectCtl.left + cxCtl; + } + else if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_MOVE_X)) != 0) + { + rectCtl.right = data.m_rect.right + (cxWidth - m_sizeDialog.cx); + + if((data.m_dwResizeFlags & DLSZ_MOVE_X) != 0) + rectCtl.left = rectCtl.right - (data.m_rect.right - data.m_rect.left); + } + + if((data.m_dwResizeFlags & DLSZ_CENTER_Y) != 0) + { + int cyCtl = data.m_rect.bottom - data.m_rect.top; + rectCtl.top = (cyHeight - cyCtl) / 2; + rectCtl.bottom = rectCtl.top + cyCtl; + } + else if((data.m_dwResizeFlags & (DLSZ_SIZE_Y | DLSZ_MOVE_Y)) != 0) + { + rectCtl.bottom = data.m_rect.bottom + (cyHeight - m_sizeDialog.cy); + + if((data.m_dwResizeFlags & DLSZ_MOVE_Y) != 0) + rectCtl.top = rectCtl.bottom - (data.m_rect.bottom - data.m_rect.top); + } + } + + if((data.m_dwResizeFlags & DLSZ_REPAINT) != 0) + ctl.Invalidate(); + + if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_SIZE_Y | DLSZ_MOVE_X | DLSZ_MOVE_Y | DLSZ_REPAINT | DLSZ_CENTER_X | DLSZ_CENTER_Y)) != 0) + ctl.SetWindowPos(NULL, &rectCtl, SWP_NOZORDER | SWP_NOACTIVATE); + + return true; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CDoubleBufferImpl - Provides double-buffer painting support to any window + +template +class CDoubleBufferImpl +{ +public: +// Overrideables + void DoPaint(CDCHandle /*dc*/) + { + // must be implemented in a derived class + ATLASSERT(FALSE); + } + +// Message map and handlers + BEGIN_MSG_MAP(CDoubleBufferImpl) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) + MESSAGE_HANDLER(WM_PAINT, OnPaint) +#ifndef _WIN32_WCE + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) +#endif // !_WIN32_WCE + END_MSG_MAP() + + LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return 1; // no background painting needed + } + + LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + + if(wParam != NULL) + { + RECT rect = { 0 }; + pT->GetClientRect(&rect); + CMemoryDC dcMem((HDC)wParam, rect); + pT->DoPaint(dcMem.m_hDC); + } + else + { + CPaintDC dc(pT->m_hWnd); + CMemoryDC dcMem(dc.m_hDC, dc.m_ps.rcPaint); + pT->DoPaint(dcMem.m_hDC); + } + + return 0; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CDoubleBufferWindowImpl - Implements a double-buffer painting window + +template +class ATL_NO_VTABLE CDoubleBufferWindowImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CDoubleBufferImpl< T > +{ +public: + BEGIN_MSG_MAP(CDoubleBufferWindowImpl) + CHAIN_MSG_MAP(CDoubleBufferImpl< T >) + END_MSG_MAP() +}; + + +// command bar support +#if !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE) + #undef CBRM_GETMENU + #undef CBRM_TRACKPOPUPMENU + #undef CBRM_GETCMDBAR + #undef CBRPOPUPMENU +#endif // !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE) + +}; // namespace WTL + +#endif // __ATLFRAME_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlgdi.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlgdi.h new file mode 100644 index 0000000000..1e452c4d9b --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlgdi.h @@ -0,0 +1,3891 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLGDI_H__ +#define __ATLGDI_H__ + +#pragma once + +#ifndef __ATLAPP_H__ + #error atlgdi.h requires atlapp.h to be included first +#endif + + +// protect template members from windowsx.h macros +#ifdef _INC_WINDOWSX + #undef CopyRgn + #undef CreateBrush + #undef CreatePen + #undef SelectBrush + #undef SelectPen + #undef SelectFont + #undef SelectBitmap +#endif // _INC_WINDOWSX + +// required libraries +#if !defined(_ATL_NO_MSIMG) && !defined(_WIN32_WCE) + #pragma comment(lib, "msimg32.lib") +#endif // !defined(_ATL_NO_MSIMG) && !defined(_WIN32_WCE) +#if !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE) + #pragma comment(lib, "opengl32.lib") +#endif // !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE) + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CPenT +// CBrushT +// CLogFont +// CFontT +// CBitmapT +// CPaletteT +// CRgnT +// CDCT +// CPaintDC +// CClientDC +// CWindowDC +// CMemoryDC +// CEnhMetaFileInfo +// CEnhMetaFileT +// CEnhMetaFileDC +// +// Global functions: +// AtlGetBitmapResourceInfo() +// AtlGetBitmapResourceBitsPerPixel() +// AtlIsAlphaBitmapResource() +// AtlIsDib16() +// AtlGetDibColorTableSize() +// AtlGetDibNumColors(), +// AtlGetDibBitmap() +// AtlCopyBitmap() +// AtlCreatePackedDib16() +// AtlSetClipboardDib16() +// AtlGetClipboardDib() + + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// Bitmap resource helpers to extract bitmap information for a bitmap resource + +inline LPBITMAPINFOHEADER AtlGetBitmapResourceInfo(HMODULE hModule, ATL::_U_STRINGorID image) +{ + HRSRC hResource = ::FindResource(hModule, image.m_lpstr, RT_BITMAP); + ATLASSERT(hResource != NULL); + HGLOBAL hGlobal = ::LoadResource(hModule, hResource); + ATLASSERT(hGlobal != NULL); + LPBITMAPINFOHEADER pBitmapInfoHeader = (LPBITMAPINFOHEADER)::LockResource(hGlobal); + ATLASSERT(pBitmapInfoHeader != NULL); + return pBitmapInfoHeader; +} + +inline WORD AtlGetBitmapResourceBitsPerPixel(HMODULE hModule, ATL::_U_STRINGorID image) +{ + LPBITMAPINFOHEADER pBitmapInfoHeader = AtlGetBitmapResourceInfo(hModule, image); + ATLASSERT(pBitmapInfoHeader != NULL); + return pBitmapInfoHeader->biBitCount; +} + +inline WORD AtlGetBitmapResourceBitsPerPixel(ATL::_U_STRINGorID image) +{ + return AtlGetBitmapResourceBitsPerPixel(ModuleHelper::GetResourceInstance(), image); +} + +/////////////////////////////////////////////////////////////////////////////// +// 32-bit (alpha channel) bitmap resource helper + +// Note: 32-bit (alpha channel) images work only on Windows XP with Common Controls version 6. +// If you want your app to work on older version of Windows, load non-alpha images if Common +// Controls version is less than 6. + +inline bool AtlIsAlphaBitmapResource(ATL::_U_STRINGorID image) +{ + return (AtlGetBitmapResourceBitsPerPixel(image) == 32); +} + + +/////////////////////////////////////////////////////////////////////////////// +// CPen + +template +class CPenT +{ +public: +// Data members + HPEN m_hPen; + +// Constructor/destructor/operators + CPenT(HPEN hPen = NULL) : m_hPen(hPen) + { } + + ~CPenT() + { + if(t_bManaged && m_hPen != NULL) + DeleteObject(); + } + + CPenT& operator =(HPEN hPen) + { + Attach(hPen); + return *this; + } + + void Attach(HPEN hPen) + { + if(t_bManaged && m_hPen != NULL && m_hPen != hPen) + ::DeleteObject(m_hPen); + m_hPen = hPen; + } + + HPEN Detach() + { + HPEN hPen = m_hPen; + m_hPen = NULL; + return hPen; + } + + operator HPEN() const { return m_hPen; } + + bool IsNull() const { return (m_hPen == NULL); } + +// Create methods + HPEN CreatePen(int nPenStyle, int nWidth, COLORREF crColor) + { + ATLASSERT(m_hPen == NULL); + m_hPen = ::CreatePen(nPenStyle, nWidth, crColor); + return m_hPen; + } + +#ifndef _WIN32_WCE + HPEN CreatePen(int nPenStyle, int nWidth, const LOGBRUSH* pLogBrush, int nStyleCount = 0, const DWORD* lpStyle = NULL) + { + ATLASSERT(m_hPen == NULL); + m_hPen = ::ExtCreatePen(nPenStyle, nWidth, pLogBrush, nStyleCount, lpStyle); + return m_hPen; + } +#endif // !_WIN32_WCE + + HPEN CreatePenIndirect(LPLOGPEN lpLogPen) + { + ATLASSERT(m_hPen == NULL); + m_hPen = ::CreatePenIndirect(lpLogPen); + return m_hPen; + } + + BOOL DeleteObject() + { + ATLASSERT(m_hPen != NULL); + BOOL bRet = ::DeleteObject(m_hPen); + if(bRet) + m_hPen = NULL; + return bRet; + } + +// Attributes + int GetLogPen(LOGPEN* pLogPen) const + { + ATLASSERT(m_hPen != NULL); + return ::GetObject(m_hPen, sizeof(LOGPEN), pLogPen); + } + + bool GetLogPen(LOGPEN& LogPen) const + { + ATLASSERT(m_hPen != NULL); + return (::GetObject(m_hPen, sizeof(LOGPEN), &LogPen) == sizeof(LOGPEN)); + } + +#ifndef _WIN32_WCE + int GetExtLogPen(EXTLOGPEN* pLogPen) const + { + ATLASSERT(m_hPen != NULL); + return ::GetObject(m_hPen, sizeof(EXTLOGPEN), pLogPen); + } + + bool GetExtLogPen(EXTLOGPEN& ExtLogPen) const + { + ATLASSERT(m_hPen != NULL); + return (::GetObject(m_hPen, sizeof(EXTLOGPEN), &ExtLogPen) == sizeof(EXTLOGPEN)); + } +#endif // !_WIN32_WCE +}; + +typedef CPenT CPenHandle; +typedef CPenT CPen; + + +/////////////////////////////////////////////////////////////////////////////// +// CBrush + +template +class CBrushT +{ +public: +// Data members + HBRUSH m_hBrush; + +// Constructor/destructor/operators + CBrushT(HBRUSH hBrush = NULL) : m_hBrush(hBrush) + { } + + ~CBrushT() + { + if(t_bManaged && m_hBrush != NULL) + DeleteObject(); + } + + CBrushT& operator =(HBRUSH hBrush) + { + Attach(hBrush); + return *this; + } + + void Attach(HBRUSH hBrush) + { + if(t_bManaged && m_hBrush != NULL && m_hBrush != hBrush) + ::DeleteObject(m_hBrush); + m_hBrush = hBrush; + } + + HBRUSH Detach() + { + HBRUSH hBrush = m_hBrush; + m_hBrush = NULL; + return hBrush; + } + + operator HBRUSH() const { return m_hBrush; } + + bool IsNull() const { return (m_hBrush == NULL); } + +// Create methods + HBRUSH CreateSolidBrush(COLORREF crColor) + { + ATLASSERT(m_hBrush == NULL); + m_hBrush = ::CreateSolidBrush(crColor); + return m_hBrush; + } + +#ifndef _WIN32_WCE + HBRUSH CreateHatchBrush(int nIndex, COLORREF crColor) + { + ATLASSERT(m_hBrush == NULL); + m_hBrush = ::CreateHatchBrush(nIndex, crColor); + return m_hBrush; + } +#endif // !_WIN32_WCE + +#if !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800) + HBRUSH CreateBrushIndirect(const LOGBRUSH* lpLogBrush) + { + ATLASSERT(m_hBrush == NULL); +#ifndef _WIN32_WCE + m_hBrush = ::CreateBrushIndirect(lpLogBrush); +#else // CE specific + m_hBrush = ATL::CreateBrushIndirect(lpLogBrush); +#endif // _WIN32_WCE + return m_hBrush; + } +#endif // !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800) + + HBRUSH CreatePatternBrush(HBITMAP hBitmap) + { + ATLASSERT(m_hBrush == NULL); + m_hBrush = ::CreatePatternBrush(hBitmap); + return m_hBrush; + } + + HBRUSH CreateDIBPatternBrush(HGLOBAL hPackedDIB, UINT nUsage) + { + ATLASSERT(hPackedDIB != NULL); + const void* lpPackedDIB = GlobalLock(hPackedDIB); + ATLASSERT(lpPackedDIB != NULL); + m_hBrush = ::CreateDIBPatternBrushPt(lpPackedDIB, nUsage); + GlobalUnlock(hPackedDIB); + return m_hBrush; + } + + HBRUSH CreateDIBPatternBrush(const void* lpPackedDIB, UINT nUsage) + { + ATLASSERT(m_hBrush == NULL); + m_hBrush = ::CreateDIBPatternBrushPt(lpPackedDIB, nUsage); + return m_hBrush; + } + + HBRUSH CreateSysColorBrush(int nIndex) + { + ATLASSERT(m_hBrush == NULL); + m_hBrush = ::GetSysColorBrush(nIndex); + return m_hBrush; + } + + BOOL DeleteObject() + { + ATLASSERT(m_hBrush != NULL); + BOOL bRet = ::DeleteObject(m_hBrush); + if(bRet) + m_hBrush = NULL; + return bRet; + } + +// Attributes + int GetLogBrush(LOGBRUSH* pLogBrush) const + { + ATLASSERT(m_hBrush != NULL); + return ::GetObject(m_hBrush, sizeof(LOGBRUSH), pLogBrush); + } + + bool GetLogBrush(LOGBRUSH& LogBrush) const + { + ATLASSERT(m_hBrush != NULL); + return (::GetObject(m_hBrush, sizeof(LOGBRUSH), &LogBrush) == sizeof(LOGBRUSH)); + } +}; + +typedef CBrushT CBrushHandle; +typedef CBrushT CBrush; + + +/////////////////////////////////////////////////////////////////////////////// +// CFont + +class CLogFont : public LOGFONT +{ +public: + CLogFont() + { + memset(this, 0, sizeof(LOGFONT)); + } + + CLogFont(const LOGFONT& lf) + { + Copy(&lf); + } + + CLogFont(HFONT hFont) + { + ATLASSERT(::GetObjectType(hFont) == OBJ_FONT); + ::GetObject(hFont, sizeof(LOGFONT), (LOGFONT*)this); + } + + HFONT CreateFontIndirect() + { + return ::CreateFontIndirect(this); + } + + void SetBold() + { + lfWeight = FW_BOLD; + } + + bool IsBold() const + { + return (lfWeight >= FW_BOLD); + } + + void MakeBolder(int iScale = 1) + { + lfWeight += FW_BOLD * iScale; + } + + void MakeLarger(int iScale) + { + if(lfHeight > 0) + lfHeight += iScale; + else + lfHeight -= iScale; + } + + void SetHeight(LONG nPointSize, HDC hDC = NULL) + { + HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL); + // For MM_TEXT mapping mode + lfHeight = -::MulDiv(nPointSize, ::GetDeviceCaps(hDC1, LOGPIXELSY), 72); + if(hDC == NULL) + ::ReleaseDC(NULL, hDC1); + } + + LONG GetHeight(HDC hDC = NULL) const + { + HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL); + // For MM_TEXT mapping mode + LONG nPointSize = ::MulDiv(-lfHeight, 72, ::GetDeviceCaps(hDC1, LOGPIXELSY)); + if(hDC == NULL) + ::ReleaseDC(NULL, hDC1); + + return nPointSize; + } + + LONG GetDeciPointHeight(HDC hDC = NULL) const + { + HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL); +#ifndef _WIN32_WCE + POINT ptOrg = { 0, 0 }; + ::DPtoLP(hDC1, &ptOrg, 1); + POINT pt = { 0, 0 }; + pt.y = abs(lfHeight) + ptOrg.y; + ::LPtoDP(hDC1, &pt,1); + LONG nDeciPoint = ::MulDiv(pt.y, 720, ::GetDeviceCaps(hDC1, LOGPIXELSY)); // 72 points/inch, 10 decipoints/point +#else // CE specific + // DP and LP are always the same on CE + LONG nDeciPoint = ::MulDiv(abs(lfHeight), 720, ::GetDeviceCaps(hDC1, LOGPIXELSY)); // 72 points/inch, 10 decipoints/point +#endif // _WIN32_WCE + if(hDC == NULL) + ::ReleaseDC(NULL, hDC1); + + return nDeciPoint; + } + + void SetHeightFromDeciPoint(LONG nDeciPtHeight, HDC hDC = NULL) + { + HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL); +#ifndef _WIN32_WCE + POINT pt = { 0, 0 }; + pt.y = ::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), nDeciPtHeight, 720); // 72 points/inch, 10 decipoints/point + ::DPtoLP(hDC1, &pt, 1); + POINT ptOrg = { 0, 0 }; + ::DPtoLP(hDC1, &ptOrg, 1); + lfHeight = -abs(pt.y - ptOrg.y); +#else // CE specific + // DP and LP are always the same on CE + lfHeight = -abs(::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), nDeciPtHeight, 720)); // 72 points/inch, 10 decipoints/point +#endif // _WIN32_WCE + if(hDC == NULL) + ::ReleaseDC(NULL, hDC1); + } + +#ifndef _WIN32_WCE + void SetCaptionFont() + { + NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() }; + ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)); + Copy(&ncm.lfCaptionFont); + } + + void SetMenuFont() + { + NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() }; + ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)); + Copy(&ncm.lfMenuFont); + } + + void SetStatusFont() + { + NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() }; + ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)); + Copy(&ncm.lfStatusFont); + } + + void SetMessageBoxFont() + { + NONCLIENTMETRICS ncm = { RunTimeHelper::SizeOf_NONCLIENTMETRICS() }; + ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)); + Copy(&ncm.lfMessageFont); + } +#endif // !_WIN32_WCE + + void Copy(const LOGFONT* pLogFont) + { + ATLASSERT(pLogFont != NULL); + *(LOGFONT*)this = *pLogFont; + } + + CLogFont& operator =(const CLogFont& src) + { + Copy(&src); + return *this; + } + + CLogFont& operator =(const LOGFONT& src) + { + Copy(&src); + return *this; + } + + CLogFont& operator =(HFONT hFont) + { + ATLASSERT(::GetObjectType(hFont) == OBJ_FONT); + ::GetObject(hFont, sizeof(LOGFONT), (LOGFONT*)this); + return *this; + } + + bool operator ==(const LOGFONT& logfont) const + { + return(logfont.lfHeight == lfHeight && + logfont.lfWidth == lfWidth && + logfont.lfEscapement == lfEscapement && + logfont.lfOrientation == lfOrientation && + logfont.lfWeight == lfWeight && + logfont.lfItalic == lfItalic && + logfont.lfUnderline == lfUnderline && + logfont.lfStrikeOut == lfStrikeOut && + logfont.lfCharSet == lfCharSet && + logfont.lfOutPrecision == lfOutPrecision && + logfont.lfClipPrecision == lfClipPrecision && + logfont.lfQuality == lfQuality && + logfont.lfPitchAndFamily == lfPitchAndFamily && + lstrcmp(logfont.lfFaceName, lfFaceName) == 0); + } +}; + + +template +class CFontT +{ +public: +// Data members + HFONT m_hFont; + +// Constructor/destructor/operators + CFontT(HFONT hFont = NULL) : m_hFont(hFont) + { } + + ~CFontT() + { + if(t_bManaged && m_hFont != NULL) + DeleteObject(); + } + + CFontT& operator =(HFONT hFont) + { + Attach(hFont); + return *this; + } + + void Attach(HFONT hFont) + { + if(t_bManaged && m_hFont != NULL && m_hFont != hFont) + ::DeleteObject(m_hFont); + m_hFont = hFont; + } + + HFONT Detach() + { + HFONT hFont = m_hFont; + m_hFont = NULL; + return hFont; + } + + operator HFONT() const { return m_hFont; } + + bool IsNull() const { return (m_hFont == NULL); } + +// Create methods + HFONT CreateFontIndirect(const LOGFONT* lpLogFont) + { + ATLASSERT(m_hFont == NULL); + m_hFont = ::CreateFontIndirect(lpLogFont); + return m_hFont; + } + +#if !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0500) + HFONT CreateFontIndirectEx(CONST ENUMLOGFONTEXDV* penumlfex) + { + ATLASSERT(m_hFont == NULL); + m_hFont = ::CreateFontIndirectEx(penumlfex); + return m_hFont; + } +#endif // !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0500) + +#if !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800) + HFONT CreateFont(int nHeight, int nWidth, int nEscapement, + int nOrientation, int nWeight, BYTE bItalic, BYTE bUnderline, + BYTE cStrikeOut, BYTE nCharSet, BYTE nOutPrecision, + BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily, + LPCTSTR lpszFacename) + { + ATLASSERT(m_hFont == NULL); +#ifndef _WIN32_WCE + m_hFont = ::CreateFont(nHeight, nWidth, nEscapement, + nOrientation, nWeight, bItalic, bUnderline, cStrikeOut, + nCharSet, nOutPrecision, nClipPrecision, nQuality, + nPitchAndFamily, lpszFacename); +#else // CE specific + m_hFont = ATL::CreateFont(nHeight, nWidth, nEscapement, + nOrientation, nWeight, bItalic, bUnderline, cStrikeOut, + nCharSet, nOutPrecision, nClipPrecision, nQuality, + nPitchAndFamily, lpszFacename); +#endif // _WIN32_WCE + return m_hFont; + } +#endif // !defined(_WIN32_WCE) || (_ATL_VER >= 0x0800) + + HFONT CreatePointFont(int nPointSize, LPCTSTR lpszFaceName, HDC hDC = NULL, bool bBold = false, bool bItalic = false) + { + LOGFONT logFont = { 0 }; + logFont.lfCharSet = DEFAULT_CHARSET; + logFont.lfHeight = nPointSize; + SecureHelper::strncpy_x(logFont.lfFaceName, _countof(logFont.lfFaceName), lpszFaceName, _TRUNCATE); + + if(bBold) + logFont.lfWeight = FW_BOLD; + if(bItalic) + logFont.lfItalic = (BYTE)TRUE; + + return CreatePointFontIndirect(&logFont, hDC); + } + + HFONT CreatePointFontIndirect(const LOGFONT* lpLogFont, HDC hDC = NULL) + { + HDC hDC1 = (hDC != NULL) ? hDC : ::GetDC(NULL); + + // convert nPointSize to logical units based on hDC + LOGFONT logFont = *lpLogFont; +#ifndef _WIN32_WCE + POINT pt = { 0, 0 }; + pt.y = ::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), logFont.lfHeight, 720); // 72 points/inch, 10 decipoints/point + ::DPtoLP(hDC1, &pt, 1); + POINT ptOrg = { 0, 0 }; + ::DPtoLP(hDC1, &ptOrg, 1); + logFont.lfHeight = -abs(pt.y - ptOrg.y); +#else // CE specific + // DP and LP are always the same on CE + logFont.lfHeight = -abs(::MulDiv(::GetDeviceCaps(hDC1, LOGPIXELSY), logFont.lfHeight, 720)); // 72 points/inch, 10 decipoints/point +#endif // _WIN32_WCE + + if(hDC == NULL) + ::ReleaseDC(NULL, hDC1); + + return CreateFontIndirect(&logFont); + } + + BOOL DeleteObject() + { + ATLASSERT(m_hFont != NULL); + BOOL bRet = ::DeleteObject(m_hFont); + if(bRet) + m_hFont = NULL; + return bRet; + } + +// Attributes + int GetLogFont(LOGFONT* pLogFont) const + { + ATLASSERT(m_hFont != NULL); + return ::GetObject(m_hFont, sizeof(LOGFONT), pLogFont); + } + + bool GetLogFont(LOGFONT& LogFont) const + { + ATLASSERT(m_hFont != NULL); + return (::GetObject(m_hFont, sizeof(LOGFONT), &LogFont) == sizeof(LOGFONT)); + } +}; + +typedef CFontT CFontHandle; +typedef CFontT CFont; + + +/////////////////////////////////////////////////////////////////////////////// +// CBitmap + +template +class CBitmapT +{ +public: +// Data members + HBITMAP m_hBitmap; + +// Constructor/destructor/operators + CBitmapT(HBITMAP hBitmap = NULL) : m_hBitmap(hBitmap) + { } + + ~CBitmapT() + { + if(t_bManaged && m_hBitmap != NULL) + DeleteObject(); + } + + CBitmapT& operator =(HBITMAP hBitmap) + { + Attach(hBitmap); + return *this; + } + + void Attach(HBITMAP hBitmap) + { + if(t_bManaged && m_hBitmap != NULL&& m_hBitmap != hBitmap) + ::DeleteObject(m_hBitmap); + m_hBitmap = hBitmap; + } + + HBITMAP Detach() + { + HBITMAP hBitmap = m_hBitmap; + m_hBitmap = NULL; + return hBitmap; + } + + operator HBITMAP() const { return m_hBitmap; } + + bool IsNull() const { return (m_hBitmap == NULL); } + +// Create and load methods + HBITMAP LoadBitmap(ATL::_U_STRINGorID bitmap) + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::LoadBitmap(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr); + return m_hBitmap; + } + + HBITMAP LoadOEMBitmap(UINT nIDBitmap) // for OBM_/OCR_/OIC_ + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::LoadBitmap(NULL, MAKEINTRESOURCE(nIDBitmap)); + return m_hBitmap; + } + +#ifndef _WIN32_WCE + HBITMAP LoadMappedBitmap(UINT nIDBitmap, UINT nFlags = 0, LPCOLORMAP lpColorMap = NULL, int nMapSize = 0) + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::CreateMappedBitmap(ModuleHelper::GetResourceInstance(), nIDBitmap, (WORD)nFlags, lpColorMap, nMapSize); + return m_hBitmap; + } +#endif // !_WIN32_WCE + + HBITMAP CreateBitmap(int nWidth, int nHeight, UINT nPlanes, UINT nBitsPerPixel, const void* lpBits) + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::CreateBitmap(nWidth, nHeight, nPlanes, nBitsPerPixel, lpBits); + return m_hBitmap; + } + +#ifndef _WIN32_WCE + HBITMAP CreateBitmapIndirect(LPBITMAP lpBitmap) + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::CreateBitmapIndirect(lpBitmap); + return m_hBitmap; + } +#endif // !_WIN32_WCE + + HBITMAP CreateCompatibleBitmap(HDC hDC, int nWidth, int nHeight) + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::CreateCompatibleBitmap(hDC, nWidth, nHeight); + return m_hBitmap; + } + +#ifndef _WIN32_WCE + HBITMAP CreateDiscardableBitmap(HDC hDC, int nWidth, int nHeight) + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::CreateDiscardableBitmap(hDC, nWidth, nHeight); + return m_hBitmap; + } +#endif // !_WIN32_WCE + + BOOL DeleteObject() + { + ATLASSERT(m_hBitmap != NULL); + BOOL bRet = ::DeleteObject(m_hBitmap); + if(bRet) + m_hBitmap = NULL; + return bRet; + } + +// Attributes + int GetBitmap(BITMAP* pBitMap) const + { + ATLASSERT(m_hBitmap != NULL); + return ::GetObject(m_hBitmap, sizeof(BITMAP), pBitMap); + } + + bool GetBitmap(BITMAP& bm) const + { + ATLASSERT(m_hBitmap != NULL); + return (::GetObject(m_hBitmap, sizeof(BITMAP), &bm) == sizeof(BITMAP)); + } + + bool GetSize(SIZE& size) const + { + ATLASSERT(m_hBitmap != NULL); + BITMAP bm = { 0 }; + if(!GetBitmap(&bm)) + return false; + size.cx = bm.bmWidth; + size.cy = bm.bmHeight; + return true; + } + +#ifndef _WIN32_WCE + DWORD GetBitmapBits(DWORD dwCount, LPVOID lpBits) const + { + ATLASSERT(m_hBitmap != NULL); + return ::GetBitmapBits(m_hBitmap, dwCount, lpBits); + } +#endif // !_WIN32_WCE + +#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 410) + DWORD SetBitmapBits(DWORD dwCount, const void* lpBits) + { + ATLASSERT(m_hBitmap != NULL); + return ::SetBitmapBits(m_hBitmap, dwCount, lpBits); + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 410) + +#ifndef _WIN32_WCE + BOOL GetBitmapDimension(LPSIZE lpSize) const + { + ATLASSERT(m_hBitmap != NULL); + return ::GetBitmapDimensionEx(m_hBitmap, lpSize); + } + + BOOL SetBitmapDimension(int nWidth, int nHeight, LPSIZE lpSize = NULL) + { + ATLASSERT(m_hBitmap != NULL); + return ::SetBitmapDimensionEx(m_hBitmap, nWidth, nHeight, lpSize); + } + +// DIB support + HBITMAP CreateDIBitmap(HDC hDC, CONST BITMAPINFOHEADER* lpbmih, DWORD dwInit, CONST VOID* lpbInit, CONST BITMAPINFO* lpbmi, UINT uColorUse) + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::CreateDIBitmap(hDC, lpbmih, dwInit, lpbInit, lpbmi, uColorUse); + return m_hBitmap; + } +#endif // !_WIN32_WCE + + HBITMAP CreateDIBSection(HDC hDC, CONST BITMAPINFO* lpbmi, UINT uColorUse, VOID** ppvBits, HANDLE hSection, DWORD dwOffset) + { + ATLASSERT(m_hBitmap == NULL); + m_hBitmap = ::CreateDIBSection(hDC, lpbmi, uColorUse, ppvBits, hSection, dwOffset); + return m_hBitmap; + } + +#ifndef _WIN32_WCE + int GetDIBits(HDC hDC, UINT uStartScan, UINT cScanLines, LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT uColorUse) const + { + ATLASSERT(m_hBitmap != NULL); + return ::GetDIBits(hDC, m_hBitmap, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse); + } + + int SetDIBits(HDC hDC, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse) + { + ATLASSERT(m_hBitmap != NULL); + return ::SetDIBits(hDC, m_hBitmap, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse); + } +#endif // !_WIN32_WCE +}; + +typedef CBitmapT CBitmapHandle; +typedef CBitmapT CBitmap; + + +/////////////////////////////////////////////////////////////////////////////// +// CPalette + +template +class CPaletteT +{ +public: +// Data members + HPALETTE m_hPalette; + +// Constructor/destructor/operators + CPaletteT(HPALETTE hPalette = NULL) : m_hPalette(hPalette) + { } + + ~CPaletteT() + { + if(t_bManaged && m_hPalette != NULL) + DeleteObject(); + } + + CPaletteT& operator =(HPALETTE hPalette) + { + Attach(hPalette); + return *this; + } + + void Attach(HPALETTE hPalette) + { + if(t_bManaged && m_hPalette != NULL && m_hPalette != hPalette) + ::DeleteObject(m_hPalette); + m_hPalette = hPalette; + } + + HPALETTE Detach() + { + HPALETTE hPalette = m_hPalette; + m_hPalette = NULL; + return hPalette; + } + + operator HPALETTE() const { return m_hPalette; } + + bool IsNull() const { return (m_hPalette == NULL); } + +// Create methods + HPALETTE CreatePalette(LPLOGPALETTE lpLogPalette) + { + ATLASSERT(m_hPalette == NULL); + m_hPalette = ::CreatePalette(lpLogPalette); + return m_hPalette; + } + +#ifndef _WIN32_WCE + HPALETTE CreateHalftonePalette(HDC hDC) + { + ATLASSERT(m_hPalette == NULL); + ATLASSERT(hDC != NULL); + m_hPalette = ::CreateHalftonePalette(hDC); + return m_hPalette; + } +#endif // !_WIN32_WCE + + BOOL DeleteObject() + { + ATLASSERT(m_hPalette != NULL); + BOOL bRet = ::DeleteObject(m_hPalette); + if(bRet) + m_hPalette = NULL; + return bRet; + } + +// Attributes + int GetEntryCount() const + { + ATLASSERT(m_hPalette != NULL); + WORD nEntries = 0; + ::GetObject(m_hPalette, sizeof(WORD), &nEntries); + return (int)nEntries; + } + + UINT GetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors) const + { + ATLASSERT(m_hPalette != NULL); + return ::GetPaletteEntries(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors); + } + + UINT SetPaletteEntries(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors) + { + ATLASSERT(m_hPalette != NULL); + return ::SetPaletteEntries(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors); + } + +// Operations +#ifndef _WIN32_WCE + void AnimatePalette(UINT nStartIndex, UINT nNumEntries, LPPALETTEENTRY lpPaletteColors) + { + ATLASSERT(m_hPalette != NULL); + ::AnimatePalette(m_hPalette, nStartIndex, nNumEntries, lpPaletteColors); + } + + BOOL ResizePalette(UINT nNumEntries) + { + ATLASSERT(m_hPalette != NULL); + return ::ResizePalette(m_hPalette, nNumEntries); + } +#endif // !_WIN32_WCE + + UINT GetNearestPaletteIndex(COLORREF crColor) const + { + ATLASSERT(m_hPalette != NULL); + return ::GetNearestPaletteIndex(m_hPalette, crColor); + } +}; + +typedef CPaletteT CPaletteHandle; +typedef CPaletteT CPalette; + + +/////////////////////////////////////////////////////////////////////////////// +// CRgn + +template +class CRgnT +{ +public: +// Data members + HRGN m_hRgn; + +// Constructor/destructor/operators + CRgnT(HRGN hRgn = NULL) : m_hRgn(hRgn) + { } + + ~CRgnT() + { + if(t_bManaged && m_hRgn != NULL) + DeleteObject(); + } + + CRgnT& operator =(HRGN hRgn) + { + Attach(hRgn); + return *this; + } + + void Attach(HRGN hRgn) + { + if(t_bManaged && m_hRgn != NULL && m_hRgn != hRgn) + ::DeleteObject(m_hRgn); + m_hRgn = hRgn; + } + + HRGN Detach() + { + HRGN hRgn = m_hRgn; + m_hRgn = NULL; + return hRgn; + } + + operator HRGN() const { return m_hRgn; } + + bool IsNull() const { return (m_hRgn == NULL); } + +// Create methods + HRGN CreateRectRgn(int x1, int y1, int x2, int y2) + { + ATLASSERT(m_hRgn == NULL); + m_hRgn = ::CreateRectRgn(x1, y1, x2, y2); + return m_hRgn; + } + + HRGN CreateRectRgnIndirect(LPCRECT lpRect) + { + ATLASSERT(m_hRgn == NULL); + m_hRgn = ::CreateRectRgnIndirect(lpRect); + return m_hRgn; + } + +#ifndef _WIN32_WCE + HRGN CreateEllipticRgn(int x1, int y1, int x2, int y2) + { + ATLASSERT(m_hRgn == NULL); + m_hRgn = ::CreateEllipticRgn(x1, y1, x2, y2); + return m_hRgn; + } + + HRGN CreateEllipticRgnIndirect(LPCRECT lpRect) + { + ATLASSERT(m_hRgn == NULL); + m_hRgn = ::CreateEllipticRgnIndirect(lpRect); + return m_hRgn; + } + + HRGN CreatePolygonRgn(LPPOINT lpPoints, int nCount, int nMode) + { + ATLASSERT(m_hRgn == NULL); + m_hRgn = ::CreatePolygonRgn(lpPoints, nCount, nMode); + return m_hRgn; + } + + HRGN CreatePolyPolygonRgn(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount, int nPolyFillMode) + { + ATLASSERT(m_hRgn == NULL); + m_hRgn = ::CreatePolyPolygonRgn(lpPoints, lpPolyCounts, nCount, nPolyFillMode); + return m_hRgn; + } + + HRGN CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3) + { + ATLASSERT(m_hRgn == NULL); + m_hRgn = ::CreateRoundRectRgn(x1, y1, x2, y2, x3, y3); + return m_hRgn; + } + + HRGN CreateFromPath(HDC hDC) + { + ATLASSERT(m_hRgn == NULL); + ATLASSERT(hDC != NULL); + m_hRgn = ::PathToRegion(hDC); + return m_hRgn; + } + + HRGN CreateFromData(const XFORM* lpXForm, int nCount, const RGNDATA* pRgnData) + { + ATLASSERT(m_hRgn == NULL); + m_hRgn = ::ExtCreateRegion(lpXForm, nCount, pRgnData); + return m_hRgn; + } +#endif // !_WIN32_WCE + + BOOL DeleteObject() + { + ATLASSERT(m_hRgn != NULL); + BOOL bRet = ::DeleteObject(m_hRgn); + if(bRet) + m_hRgn = NULL; + return bRet; + } + +// Operations + void SetRectRgn(int x1, int y1, int x2, int y2) + { + ATLASSERT(m_hRgn != NULL); + ::SetRectRgn(m_hRgn, x1, y1, x2, y2); + } + + void SetRectRgn(LPCRECT lpRect) + { + ATLASSERT(m_hRgn != NULL); + ::SetRectRgn(m_hRgn, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); + } + + int CombineRgn(HRGN hRgnSrc1, HRGN hRgnSrc2, int nCombineMode) + { + ATLASSERT(m_hRgn != NULL); + return ::CombineRgn(m_hRgn, hRgnSrc1, hRgnSrc2, nCombineMode); + } + + int CombineRgn(HRGN hRgnSrc, int nCombineMode) + { + ATLASSERT(m_hRgn != NULL); + return ::CombineRgn(m_hRgn, m_hRgn, hRgnSrc, nCombineMode); + } + + int CopyRgn(HRGN hRgnSrc) + { + ATLASSERT(m_hRgn != NULL); + return ::CombineRgn(m_hRgn, hRgnSrc, NULL, RGN_COPY); + } + + BOOL EqualRgn(HRGN hRgn) const + { + ATLASSERT(m_hRgn != NULL); + return ::EqualRgn(m_hRgn, hRgn); + } + + int OffsetRgn(int x, int y) + { + ATLASSERT(m_hRgn != NULL); + return ::OffsetRgn(m_hRgn, x, y); + } + + int OffsetRgn(POINT point) + { + ATLASSERT(m_hRgn != NULL); + return ::OffsetRgn(m_hRgn, point.x, point.y); + } + + int GetRgnBox(LPRECT lpRect) const + { + ATLASSERT(m_hRgn != NULL); + return ::GetRgnBox(m_hRgn, lpRect); + } + + BOOL PtInRegion(int x, int y) const + { + ATLASSERT(m_hRgn != NULL); + return ::PtInRegion(m_hRgn, x, y); + } + + BOOL PtInRegion(POINT point) const + { + ATLASSERT(m_hRgn != NULL); + return ::PtInRegion(m_hRgn, point.x, point.y); + } + + BOOL RectInRegion(LPCRECT lpRect) const + { + ATLASSERT(m_hRgn != NULL); + return ::RectInRegion(m_hRgn, lpRect); + } + + int GetRegionData(LPRGNDATA lpRgnData, int nDataSize) const + { + ATLASSERT(m_hRgn != NULL); + return (int)::GetRegionData(m_hRgn, nDataSize, lpRgnData); + } +}; + +typedef CRgnT CRgnHandle; +typedef CRgnT CRgn; + + +/////////////////////////////////////////////////////////////////////////////// +// CDC - The device context class + +template +class CDCT +{ +public: +// Data members + HDC m_hDC; + +// Constructor/destructor/operators + CDCT(HDC hDC = NULL) : m_hDC(hDC) + { + } + + ~CDCT() + { + if(t_bManaged && m_hDC != NULL) + ::DeleteDC(Detach()); + } + + CDCT& operator =(HDC hDC) + { + Attach(hDC); + return *this; + } + + void Attach(HDC hDC) + { + if(t_bManaged && m_hDC != NULL && m_hDC != hDC) + ::DeleteDC(m_hDC); + m_hDC = hDC; + } + + HDC Detach() + { + HDC hDC = m_hDC; + m_hDC = NULL; + return hDC; + } + + operator HDC() const { return m_hDC; } + + bool IsNull() const { return (m_hDC == NULL); } + +// Operations +#ifndef _WIN32_WCE + HWND WindowFromDC() const + { + ATLASSERT(m_hDC != NULL); + return ::WindowFromDC(m_hDC); + } +#endif // !_WIN32_WCE + + CPenHandle GetCurrentPen() const + { + ATLASSERT(m_hDC != NULL); + return CPenHandle((HPEN)::GetCurrentObject(m_hDC, OBJ_PEN)); + } + + CBrushHandle GetCurrentBrush() const + { + ATLASSERT(m_hDC != NULL); + return CBrushHandle((HBRUSH)::GetCurrentObject(m_hDC, OBJ_BRUSH)); + } + + CPaletteHandle GetCurrentPalette() const + { + ATLASSERT(m_hDC != NULL); + return CPaletteHandle((HPALETTE)::GetCurrentObject(m_hDC, OBJ_PAL)); + } + + CFontHandle GetCurrentFont() const + { + ATLASSERT(m_hDC != NULL); + return CFontHandle((HFONT)::GetCurrentObject(m_hDC, OBJ_FONT)); + } + + CBitmapHandle GetCurrentBitmap() const + { + ATLASSERT(m_hDC != NULL); + return CBitmapHandle((HBITMAP)::GetCurrentObject(m_hDC, OBJ_BITMAP)); + } + + HDC CreateDC(LPCTSTR lpszDriverName, LPCTSTR lpszDeviceName, LPCTSTR lpszOutput, const DEVMODE* lpInitData) + { + ATLASSERT(m_hDC == NULL); + m_hDC = ::CreateDC(lpszDriverName, lpszDeviceName, lpszOutput, lpInitData); + return m_hDC; + } + + HDC CreateCompatibleDC(HDC hDC = NULL) + { + ATLASSERT(m_hDC == NULL); + m_hDC = ::CreateCompatibleDC(hDC); + return m_hDC; + } + + BOOL DeleteDC() + { + if(m_hDC == NULL) + return FALSE; + BOOL bRet = ::DeleteDC(m_hDC); + if(bRet) + m_hDC = NULL; + return bRet; + } + +// Device-Context Functions + int SaveDC() + { + ATLASSERT(m_hDC != NULL); + return ::SaveDC(m_hDC); + } + + BOOL RestoreDC(int nSavedDC) + { + ATLASSERT(m_hDC != NULL); + return ::RestoreDC(m_hDC, nSavedDC); + } + + int GetDeviceCaps(int nIndex) const + { + ATLASSERT(m_hDC != NULL); + return ::GetDeviceCaps(m_hDC, nIndex); + } + +#ifndef _WIN32_WCE + UINT SetBoundsRect(LPCRECT lpRectBounds, UINT flags) + { + ATLASSERT(m_hDC != NULL); + return ::SetBoundsRect(m_hDC, lpRectBounds, flags); + } + + UINT GetBoundsRect(LPRECT lpRectBounds, UINT flags) const + { + ATLASSERT(m_hDC != NULL); + return ::GetBoundsRect(m_hDC, lpRectBounds, flags); + } + + BOOL ResetDC(const DEVMODE* lpDevMode) + { + ATLASSERT(m_hDC != NULL); + return ::ResetDC(m_hDC, lpDevMode) != NULL; + } + +// Drawing-Tool Functions + BOOL GetBrushOrg(LPPOINT lpPoint) const + { + ATLASSERT(m_hDC != NULL); + return ::GetBrushOrgEx(m_hDC, lpPoint); + } +#endif // !_WIN32_WCE + + BOOL SetBrushOrg(int x, int y, LPPOINT lpPoint = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::SetBrushOrgEx(m_hDC, x, y, lpPoint); + } + + BOOL SetBrushOrg(POINT point, LPPOINT lpPointRet = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::SetBrushOrgEx(m_hDC, point.x, point.y, lpPointRet); + } + +#ifndef _WIN32_WCE + int EnumObjects(int nObjectType, int (CALLBACK* lpfn)(LPVOID, LPARAM), LPARAM lpData) + { + ATLASSERT(m_hDC != NULL); +#ifdef STRICT + return ::EnumObjects(m_hDC, nObjectType, (GOBJENUMPROC)lpfn, lpData); +#else + return ::EnumObjects(m_hDC, nObjectType, (GOBJENUMPROC)lpfn, (LPVOID)lpData); +#endif + } +#endif // !_WIN32_WCE + +// Type-safe selection helpers + HPEN SelectPen(HPEN hPen) + { + ATLASSERT(m_hDC != NULL); +#ifndef _WIN32_WCE + ATLASSERT(hPen == NULL || ::GetObjectType(hPen) == OBJ_PEN || ::GetObjectType(hPen) == OBJ_EXTPEN); +#else // CE specific + ATLASSERT(hPen == NULL || ::GetObjectType(hPen) == OBJ_PEN); +#endif // _WIN32_WCE + return (HPEN)::SelectObject(m_hDC, hPen); + } + + HBRUSH SelectBrush(HBRUSH hBrush) + { + ATLASSERT(m_hDC != NULL); + ATLASSERT(hBrush == NULL || ::GetObjectType(hBrush) == OBJ_BRUSH); + return (HBRUSH)::SelectObject(m_hDC, hBrush); + } + + HFONT SelectFont(HFONT hFont) + { + ATLASSERT(m_hDC != NULL); + ATLASSERT(hFont == NULL || ::GetObjectType(hFont) == OBJ_FONT); + return (HFONT)::SelectObject(m_hDC, hFont); + } + + HBITMAP SelectBitmap(HBITMAP hBitmap) + { + ATLASSERT(m_hDC != NULL); + ATLASSERT(hBitmap == NULL || ::GetObjectType(hBitmap) == OBJ_BITMAP); + return (HBITMAP)::SelectObject(m_hDC, hBitmap); + } + + int SelectRgn(HRGN hRgn) // special return for regions + { + ATLASSERT(m_hDC != NULL); + ATLASSERT(hRgn == NULL || ::GetObjectType(hRgn) == OBJ_REGION); + return PtrToInt(::SelectObject(m_hDC, hRgn)); + } + +// Type-safe selection helpers for stock objects + HPEN SelectStockPen(int nPen) + { + ATLASSERT(m_hDC != NULL); +#if (_WIN32_WINNT >= 0x0500) + ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN || nPen == DC_PEN); +#else + ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN); +#endif // !(_WIN32_WINNT >= 0x0500) + return SelectPen((HPEN)::GetStockObject(nPen)); + } + + HBRUSH SelectStockBrush(int nBrush) + { +#if (_WIN32_WINNT >= 0x0500) + ATLASSERT((nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH) || nBrush == DC_BRUSH); +#else + ATLASSERT(nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH); +#endif // !(_WIN32_WINNT >= 0x0500) + return SelectBrush((HBRUSH)::GetStockObject(nBrush)); + } + + HFONT SelectStockFont(int nFont) + { +#ifndef _WIN32_WCE + ATLASSERT((nFont >= OEM_FIXED_FONT && nFont <= SYSTEM_FIXED_FONT) || nFont == DEFAULT_GUI_FONT); +#else // CE specific + ATLASSERT(nFont == SYSTEM_FONT); +#endif // _WIN32_WCE + return SelectFont((HFONT)::GetStockObject(nFont)); + } + + HPALETTE SelectStockPalette(int nPalette, BOOL bForceBackground) + { + ATLASSERT(nPalette == DEFAULT_PALETTE); // the only one supported + return SelectPalette((HPALETTE)::GetStockObject(nPalette), bForceBackground); + } + +// Color and Color Palette Functions + COLORREF GetNearestColor(COLORREF crColor) const + { + ATLASSERT(m_hDC != NULL); + return ::GetNearestColor(m_hDC, crColor); + } + + HPALETTE SelectPalette(HPALETTE hPalette, BOOL bForceBackground) + { + ATLASSERT(m_hDC != NULL); + + return ::SelectPalette(m_hDC, hPalette, bForceBackground); + } + + UINT RealizePalette() + { + ATLASSERT(m_hDC != NULL); + return ::RealizePalette(m_hDC); + } + +#ifndef _WIN32_WCE + void UpdateColors() + { + ATLASSERT(m_hDC != NULL); + ::UpdateColors(m_hDC); + } +#endif // !_WIN32_WCE + +// Drawing-Attribute Functions + COLORREF GetBkColor() const + { + ATLASSERT(m_hDC != NULL); + return ::GetBkColor(m_hDC); + } + + int GetBkMode() const + { + ATLASSERT(m_hDC != NULL); + return ::GetBkMode(m_hDC); + } + +#ifndef _WIN32_WCE + int GetPolyFillMode() const + { + ATLASSERT(m_hDC != NULL); + return ::GetPolyFillMode(m_hDC); + } + + int GetROP2() const + { + ATLASSERT(m_hDC != NULL); + return ::GetROP2(m_hDC); + } + + int GetStretchBltMode() const + { + ATLASSERT(m_hDC != NULL); + return ::GetStretchBltMode(m_hDC); + } +#endif // !_WIN32_WCE + + COLORREF GetTextColor() const + { + ATLASSERT(m_hDC != NULL); + return ::GetTextColor(m_hDC); + } + + COLORREF SetBkColor(COLORREF crColor) + { + ATLASSERT(m_hDC != NULL); + return ::SetBkColor(m_hDC, crColor); + } + + int SetBkMode(int nBkMode) + { + ATLASSERT(m_hDC != NULL); + return ::SetBkMode(m_hDC, nBkMode); + } + +#ifndef _WIN32_WCE + int SetPolyFillMode(int nPolyFillMode) + { + ATLASSERT(m_hDC != NULL); + return ::SetPolyFillMode(m_hDC, nPolyFillMode); + } +#endif // !_WIN32_WCE + + int SetROP2(int nDrawMode) + { + ATLASSERT(m_hDC != NULL); + return ::SetROP2(m_hDC, nDrawMode); + } + +#ifndef _WIN32_WCE + int SetStretchBltMode(int nStretchMode) + { + ATLASSERT(m_hDC != NULL); + return ::SetStretchBltMode(m_hDC, nStretchMode); + } +#endif // !_WIN32_WCE + + COLORREF SetTextColor(COLORREF crColor) + { + ATLASSERT(m_hDC != NULL); + return ::SetTextColor(m_hDC, crColor); + } + +#ifndef _WIN32_WCE + BOOL GetColorAdjustment(LPCOLORADJUSTMENT lpColorAdjust) const + { + ATLASSERT(m_hDC != NULL); + return ::GetColorAdjustment(m_hDC, lpColorAdjust); + } + + BOOL SetColorAdjustment(const COLORADJUSTMENT* lpColorAdjust) + { + ATLASSERT(m_hDC != NULL); + return ::SetColorAdjustment(m_hDC, lpColorAdjust); + } + +// Mapping Functions + int GetMapMode() const + { + ATLASSERT(m_hDC != NULL); + return ::GetMapMode(m_hDC); + } + + BOOL GetViewportOrg(LPPOINT lpPoint) const + { + ATLASSERT(m_hDC != NULL); + return ::GetViewportOrgEx(m_hDC, lpPoint); + } + + int SetMapMode(int nMapMode) + { + ATLASSERT(m_hDC != NULL); + return ::SetMapMode(m_hDC, nMapMode); + } +#endif // !_WIN32_WCE + + // Viewport Origin + BOOL SetViewportOrg(int x, int y, LPPOINT lpPoint = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::SetViewportOrgEx(m_hDC, x, y, lpPoint); + } + + BOOL SetViewportOrg(POINT point, LPPOINT lpPointRet = NULL) + { + ATLASSERT(m_hDC != NULL); + return SetViewportOrg(point.x, point.y, lpPointRet); + } + +#ifndef _WIN32_WCE + BOOL OffsetViewportOrg(int nWidth, int nHeight, LPPOINT lpPoint = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::OffsetViewportOrgEx(m_hDC, nWidth, nHeight, lpPoint); + } + + // Viewport Extent + BOOL GetViewportExt(LPSIZE lpSize) const + { + ATLASSERT(m_hDC != NULL); + return ::GetViewportExtEx(m_hDC, lpSize); + } + + BOOL SetViewportExt(int x, int y, LPSIZE lpSize = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::SetViewportExtEx(m_hDC, x, y, lpSize); + } + + BOOL SetViewportExt(SIZE size, LPSIZE lpSizeRet = NULL) + { + ATLASSERT(m_hDC != NULL); + return SetViewportExt(size.cx, size.cy, lpSizeRet); + } + + BOOL ScaleViewportExt(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::ScaleViewportExtEx(m_hDC, xNum, xDenom, yNum, yDenom, lpSize); + } +#endif // !_WIN32_WCE + + // Window Origin +#ifndef _WIN32_WCE + BOOL GetWindowOrg(LPPOINT lpPoint) const + { + ATLASSERT(m_hDC != NULL); + return ::GetWindowOrgEx(m_hDC, lpPoint); + } + + BOOL SetWindowOrg(int x, int y, LPPOINT lpPoint = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::SetWindowOrgEx(m_hDC, x, y, lpPoint); + } + + BOOL SetWindowOrg(POINT point, LPPOINT lpPointRet = NULL) + { + ATLASSERT(m_hDC != NULL); + return SetWindowOrg(point.x, point.y, lpPointRet); + } + + BOOL OffsetWindowOrg(int nWidth, int nHeight, LPPOINT lpPoint = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::OffsetWindowOrgEx(m_hDC, nWidth, nHeight, lpPoint); + } + + // Window extent + BOOL GetWindowExt(LPSIZE lpSize) const + { + ATLASSERT(m_hDC != NULL); + return ::GetWindowExtEx(m_hDC, lpSize); + } + + BOOL SetWindowExt(int x, int y, LPSIZE lpSize = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::SetWindowExtEx(m_hDC, x, y, lpSize); + } + + BOOL SetWindowExt(SIZE size, LPSIZE lpSizeRet = NULL) + { + ATLASSERT(m_hDC != NULL); + return SetWindowExt(size.cx, size.cy, lpSizeRet); + } + + BOOL ScaleWindowExt(int xNum, int xDenom, int yNum, int yDenom, LPSIZE lpSize = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::ScaleWindowExtEx(m_hDC, xNum, xDenom, yNum, yDenom, lpSize); + } + +// Coordinate Functions + BOOL DPtoLP(LPPOINT lpPoints, int nCount = 1) const + { + ATLASSERT(m_hDC != NULL); + return ::DPtoLP(m_hDC, lpPoints, nCount); + } + + BOOL DPtoLP(LPRECT lpRect) const + { + ATLASSERT(m_hDC != NULL); + return ::DPtoLP(m_hDC, (LPPOINT)lpRect, 2); + } + + BOOL DPtoLP(LPSIZE lpSize) const + { + SIZE sizeWinExt = { 0, 0 }; + if(!GetWindowExt(&sizeWinExt)) + return FALSE; + SIZE sizeVpExt = { 0, 0 }; + if(!GetViewportExt(&sizeVpExt)) + return FALSE; + lpSize->cx = ::MulDiv(lpSize->cx, abs(sizeWinExt.cx), abs(sizeVpExt.cx)); + lpSize->cy = ::MulDiv(lpSize->cy, abs(sizeWinExt.cy), abs(sizeVpExt.cy)); + return TRUE; + } + + BOOL LPtoDP(LPPOINT lpPoints, int nCount = 1) const + { + ATLASSERT(m_hDC != NULL); + return ::LPtoDP(m_hDC, lpPoints, nCount); + } + + BOOL LPtoDP(LPRECT lpRect) const + { + ATLASSERT(m_hDC != NULL); + return ::LPtoDP(m_hDC, (LPPOINT)lpRect, 2); + } + + BOOL LPtoDP(LPSIZE lpSize) const + { + SIZE sizeWinExt = { 0, 0 }; + if(!GetWindowExt(&sizeWinExt)) + return FALSE; + SIZE sizeVpExt = { 0, 0 }; + if(!GetViewportExt(&sizeVpExt)) + return FALSE; + lpSize->cx = ::MulDiv(lpSize->cx, abs(sizeVpExt.cx), abs(sizeWinExt.cx)); + lpSize->cy = ::MulDiv(lpSize->cy, abs(sizeVpExt.cy), abs(sizeWinExt.cy)); + return TRUE; + } + +// Special Coordinate Functions (useful for dealing with metafiles and OLE) + #define HIMETRIC_INCH 2540 // HIMETRIC units per inch + + void DPtoHIMETRIC(LPSIZE lpSize) const + { + ATLASSERT(m_hDC != NULL); + int nMapMode; + if((nMapMode = GetMapMode()) < MM_ISOTROPIC && nMapMode != MM_TEXT) + { + // when using a constrained map mode, map against physical inch + ((CDCHandle*)this)->SetMapMode(MM_HIMETRIC); + DPtoLP(lpSize); + ((CDCHandle*)this)->SetMapMode(nMapMode); + } + else + { + // map against logical inch for non-constrained mapping modes + int cxPerInch = GetDeviceCaps(LOGPIXELSX); + int cyPerInch = GetDeviceCaps(LOGPIXELSY); + ATLASSERT(cxPerInch != 0 && cyPerInch != 0); + lpSize->cx = ::MulDiv(lpSize->cx, HIMETRIC_INCH, cxPerInch); + lpSize->cy = ::MulDiv(lpSize->cy, HIMETRIC_INCH, cyPerInch); + } + } + + void HIMETRICtoDP(LPSIZE lpSize) const + { + ATLASSERT(m_hDC != NULL); + int nMapMode; + if((nMapMode = GetMapMode()) < MM_ISOTROPIC && nMapMode != MM_TEXT) + { + // when using a constrained map mode, map against physical inch + ((CDCHandle*)this)->SetMapMode(MM_HIMETRIC); + LPtoDP(lpSize); + ((CDCHandle*)this)->SetMapMode(nMapMode); + } + else + { + // map against logical inch for non-constrained mapping modes + int cxPerInch = GetDeviceCaps(LOGPIXELSX); + int cyPerInch = GetDeviceCaps(LOGPIXELSY); + ATLASSERT(cxPerInch != 0 && cyPerInch != 0); + lpSize->cx = ::MulDiv(lpSize->cx, cxPerInch, HIMETRIC_INCH); + lpSize->cy = ::MulDiv(lpSize->cy, cyPerInch, HIMETRIC_INCH); + } + } + + void LPtoHIMETRIC(LPSIZE lpSize) const + { + LPtoDP(lpSize); + DPtoHIMETRIC(lpSize); + } + + void HIMETRICtoLP(LPSIZE lpSize) const + { + HIMETRICtoDP(lpSize); + DPtoLP(lpSize); + } +#endif // !_WIN32_WCE + +// Region Functions + BOOL FillRgn(HRGN hRgn, HBRUSH hBrush) + { + ATLASSERT(m_hDC != NULL); + return ::FillRgn(m_hDC, hRgn, hBrush); + } + +#ifndef _WIN32_WCE + BOOL FrameRgn(HRGN hRgn, HBRUSH hBrush, int nWidth, int nHeight) + { + ATLASSERT(m_hDC != NULL); + return ::FrameRgn(m_hDC, hRgn, hBrush, nWidth, nHeight); + } + + BOOL InvertRgn(HRGN hRgn) + { + ATLASSERT(m_hDC != NULL); + return ::InvertRgn(m_hDC, hRgn); + } + + BOOL PaintRgn(HRGN hRgn) + { + ATLASSERT(m_hDC != NULL); + return ::PaintRgn(m_hDC, hRgn); + } +#endif // !_WIN32_WCE + +// Clipping Functions + int GetClipBox(LPRECT lpRect) const + { + ATLASSERT(m_hDC != NULL); + return ::GetClipBox(m_hDC, lpRect); + } + + int GetClipRgn(CRgn& region) const + { + ATLASSERT(m_hDC != NULL); + if(region.IsNull()) + region.CreateRectRgn(0, 0, 0, 0); + + int nRet = ::GetClipRgn(m_hDC, region); + if(nRet != 1) + region.DeleteObject(); + + return nRet; + } + +#ifndef _WIN32_WCE + BOOL PtVisible(int x, int y) const + { + ATLASSERT(m_hDC != NULL); + return ::PtVisible(m_hDC, x, y); + } + + BOOL PtVisible(POINT point) const + { + ATLASSERT(m_hDC != NULL); + return ::PtVisible(m_hDC, point.x, point.y); + } +#endif // !_WIN32_WCE + + BOOL RectVisible(LPCRECT lpRect) const + { + ATLASSERT(m_hDC != NULL); + return ::RectVisible(m_hDC, lpRect); + } + + int SelectClipRgn(HRGN hRgn) + { + ATLASSERT(m_hDC != NULL); + return ::SelectClipRgn(m_hDC, (HRGN)hRgn); + } + + int ExcludeClipRect(int x1, int y1, int x2, int y2) + { + ATLASSERT(m_hDC != NULL); + return ::ExcludeClipRect(m_hDC, x1, y1, x2, y2); + } + + int ExcludeClipRect(LPCRECT lpRect) + { + ATLASSERT(m_hDC != NULL); + return ::ExcludeClipRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); + } + +#ifndef _WIN32_WCE + int ExcludeUpdateRgn(HWND hWnd) + { + ATLASSERT(m_hDC != NULL); + return ::ExcludeUpdateRgn(m_hDC, hWnd); + } +#endif // !_WIN32_WCE + + int IntersectClipRect(int x1, int y1, int x2, int y2) + { + ATLASSERT(m_hDC != NULL); + return ::IntersectClipRect(m_hDC, x1, y1, x2, y2); + } + + int IntersectClipRect(LPCRECT lpRect) + { + ATLASSERT(m_hDC != NULL); + return ::IntersectClipRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); + } + +#ifndef _WIN32_WCE + int OffsetClipRgn(int x, int y) + { + ATLASSERT(m_hDC != NULL); + return ::OffsetClipRgn(m_hDC, x, y); + } + + int OffsetClipRgn(SIZE size) + { + ATLASSERT(m_hDC != NULL); + return ::OffsetClipRgn(m_hDC, size.cx, size.cy); + } + + int SelectClipRgn(HRGN hRgn, int nMode) + { + ATLASSERT(m_hDC != NULL); + return ::ExtSelectClipRgn(m_hDC, hRgn, nMode); + } +#endif // !_WIN32_WCE + +// Line-Output Functions +#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) + BOOL GetCurrentPosition(LPPOINT lpPoint) const + { + ATLASSERT(m_hDC != NULL); + return ::GetCurrentPositionEx(m_hDC, lpPoint); + } + + BOOL MoveTo(int x, int y, LPPOINT lpPoint = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::MoveToEx(m_hDC, x, y, lpPoint); + } + + BOOL MoveTo(POINT point, LPPOINT lpPointRet = NULL) + { + ATLASSERT(m_hDC != NULL); + return MoveTo(point.x, point.y, lpPointRet); + } + + BOOL LineTo(int x, int y) + { + ATLASSERT(m_hDC != NULL); + return ::LineTo(m_hDC, x, y); + } + + BOOL LineTo(POINT point) + { + ATLASSERT(m_hDC != NULL); + return LineTo(point.x, point.y); + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) + +#ifndef _WIN32_WCE + BOOL Arc(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) + { + ATLASSERT(m_hDC != NULL); + return ::Arc(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4); + } + + BOOL Arc(LPCRECT lpRect, POINT ptStart, POINT ptEnd) + { + ATLASSERT(m_hDC != NULL); + return ::Arc(m_hDC, lpRect->left, lpRect->top, + lpRect->right, lpRect->bottom, ptStart.x, ptStart.y, + ptEnd.x, ptEnd.y); + } +#endif // !_WIN32_WCE + + BOOL Polyline(LPPOINT lpPoints, int nCount) + { + ATLASSERT(m_hDC != NULL); + return ::Polyline(m_hDC, lpPoints, nCount); + } + +#ifndef _WIN32_WCE + BOOL AngleArc(int x, int y, int nRadius, float fStartAngle, float fSweepAngle) + { + ATLASSERT(m_hDC != NULL); + return ::AngleArc(m_hDC, x, y, nRadius, fStartAngle, fSweepAngle); + } + + BOOL ArcTo(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) + { + ATLASSERT(m_hDC != NULL); + return ::ArcTo(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4); + } + + BOOL ArcTo(LPCRECT lpRect, POINT ptStart, POINT ptEnd) + { + ATLASSERT(m_hDC != NULL); + return ArcTo(lpRect->left, lpRect->top, lpRect->right, + lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y); + } + + int GetArcDirection() const + { + ATLASSERT(m_hDC != NULL); + return ::GetArcDirection(m_hDC); + } + + int SetArcDirection(int nArcDirection) + { + ATLASSERT(m_hDC != NULL); + return ::SetArcDirection(m_hDC, nArcDirection); + } + + BOOL PolyDraw(const POINT* lpPoints, const BYTE* lpTypes, int nCount) + { + ATLASSERT(m_hDC != NULL); + return ::PolyDraw(m_hDC, lpPoints, lpTypes, nCount); + } + + BOOL PolylineTo(const POINT* lpPoints, int nCount) + { + ATLASSERT(m_hDC != NULL); + return ::PolylineTo(m_hDC, lpPoints, nCount); + } + + BOOL PolyPolyline(const POINT* lpPoints, + const DWORD* lpPolyPoints, int nCount) + { + ATLASSERT(m_hDC != NULL); + return ::PolyPolyline(m_hDC, lpPoints, lpPolyPoints, nCount); + } + + BOOL PolyBezier(const POINT* lpPoints, int nCount) + { + ATLASSERT(m_hDC != NULL); + return ::PolyBezier(m_hDC, lpPoints, nCount); + } + + BOOL PolyBezierTo(const POINT* lpPoints, int nCount) + { + ATLASSERT(m_hDC != NULL); + return ::PolyBezierTo(m_hDC, lpPoints, nCount); + } +#endif // !_WIN32_WCE + +// Simple Drawing Functions + BOOL FillRect(LPCRECT lpRect, HBRUSH hBrush) + { + ATLASSERT(m_hDC != NULL); + return ::FillRect(m_hDC, lpRect, hBrush); + } + + BOOL FillRect(LPCRECT lpRect, int nColorIndex) + { + ATLASSERT(m_hDC != NULL); +#ifndef _WIN32_WCE + return ::FillRect(m_hDC, lpRect, (HBRUSH)LongToPtr(nColorIndex + 1)); +#else // CE specific + return ::FillRect(m_hDC, lpRect, ::GetSysColorBrush(nColorIndex)); +#endif // _WIN32_WCE + } + +#ifndef _WIN32_WCE + BOOL FrameRect(LPCRECT lpRect, HBRUSH hBrush) + { + ATLASSERT(m_hDC != NULL); + return ::FrameRect(m_hDC, lpRect, hBrush); + } +#endif // !_WIN32_WCE + +#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 420) + BOOL InvertRect(LPCRECT lpRect) + { + ATLASSERT(m_hDC != NULL); + return ::InvertRect(m_hDC, lpRect); + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 420) + + BOOL DrawIcon(int x, int y, HICON hIcon) + { + ATLASSERT(m_hDC != NULL); +#ifndef _WIN32_WCE + return ::DrawIcon(m_hDC, x, y, hIcon); +#else // CE specific + return ::DrawIconEx(m_hDC, x, y, hIcon, 0, 0, 0, NULL, DI_NORMAL); +#endif // _WIN32_WCE + } + + BOOL DrawIcon(POINT point, HICON hIcon) + { + ATLASSERT(m_hDC != NULL); +#ifndef _WIN32_WCE + return ::DrawIcon(m_hDC, point.x, point.y, hIcon); +#else // CE specific + return ::DrawIconEx(m_hDC, point.x, point.y, hIcon, 0, 0, 0, NULL, DI_NORMAL); +#endif // _WIN32_WCE + } + + BOOL DrawIconEx(int x, int y, HICON hIcon, int cxWidth, int cyWidth, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL) + { + ATLASSERT(m_hDC != NULL); + return ::DrawIconEx(m_hDC, x, y, hIcon, cxWidth, cyWidth, uStepIfAniCur, hbrFlickerFreeDraw, uFlags); + } + + BOOL DrawIconEx(POINT point, HICON hIcon, SIZE size, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL) + { + ATLASSERT(m_hDC != NULL); + return ::DrawIconEx(m_hDC, point.x, point.y, hIcon, size.cx, size.cy, uStepIfAniCur, hbrFlickerFreeDraw, uFlags); + } + +#ifndef _WIN32_WCE + BOOL DrawState(POINT pt, SIZE size, HBITMAP hBitmap, UINT nFlags, HBRUSH hBrush = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)hBitmap, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_BITMAP); + } + + BOOL DrawState(POINT pt, SIZE size, HICON hIcon, UINT nFlags, HBRUSH hBrush = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)hIcon, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_ICON); + } + + BOOL DrawState(POINT pt, SIZE size, LPCTSTR lpszText, UINT nFlags, BOOL bPrefixText = TRUE, int nTextLen = 0, HBRUSH hBrush = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::DrawState(m_hDC, hBrush, NULL, (LPARAM)lpszText, (WPARAM)nTextLen, pt.x, pt.y, size.cx, size.cy, nFlags | (bPrefixText ? DST_PREFIXTEXT : DST_TEXT)); + } + + BOOL DrawState(POINT pt, SIZE size, DRAWSTATEPROC lpDrawProc, LPARAM lData, UINT nFlags, HBRUSH hBrush = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::DrawState(m_hDC, hBrush, lpDrawProc, lData, 0, pt.x, pt.y, size.cx, size.cy, nFlags | DST_COMPLEX); + } +#endif // !_WIN32_WCE + +// Ellipse and Polygon Functions +#ifndef _WIN32_WCE + BOOL Chord(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) + { + ATLASSERT(m_hDC != NULL); + return ::Chord(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4); + } + + BOOL Chord(LPCRECT lpRect, POINT ptStart, POINT ptEnd) + { + ATLASSERT(m_hDC != NULL); + return ::Chord(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y); + } +#endif // !_WIN32_WCE + + void DrawFocusRect(LPCRECT lpRect) + { + ATLASSERT(m_hDC != NULL); + ::DrawFocusRect(m_hDC, lpRect); + } + + BOOL Ellipse(int x1, int y1, int x2, int y2) + { + ATLASSERT(m_hDC != NULL); + return ::Ellipse(m_hDC, x1, y1, x2, y2); + } + + BOOL Ellipse(LPCRECT lpRect) + { + ATLASSERT(m_hDC != NULL); + return ::Ellipse(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); + } + +#ifndef _WIN32_WCE + BOOL Pie(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) + { + ATLASSERT(m_hDC != NULL); + return ::Pie(m_hDC, x1, y1, x2, y2, x3, y3, x4, y4); + } + + BOOL Pie(LPCRECT lpRect, POINT ptStart, POINT ptEnd) + { + ATLASSERT(m_hDC != NULL); + return ::Pie(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y); + } +#endif // !_WIN32_WCE + + BOOL Polygon(LPPOINT lpPoints, int nCount) + { + ATLASSERT(m_hDC != NULL); + return ::Polygon(m_hDC, lpPoints, nCount); + } + +#ifndef _WIN32_WCE + BOOL PolyPolygon(LPPOINT lpPoints, LPINT lpPolyCounts, int nCount) + { + ATLASSERT(m_hDC != NULL); + return ::PolyPolygon(m_hDC, lpPoints, lpPolyCounts, nCount); + } +#endif // !_WIN32_WCE + + BOOL Rectangle(int x1, int y1, int x2, int y2) + { + ATLASSERT(m_hDC != NULL); + return ::Rectangle(m_hDC, x1, y1, x2, y2); + } + + BOOL Rectangle(LPCRECT lpRect) + { + ATLASSERT(m_hDC != NULL); + return ::Rectangle(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); + } + + BOOL RoundRect(int x1, int y1, int x2, int y2, int x3, int y3) + { + ATLASSERT(m_hDC != NULL); + return ::RoundRect(m_hDC, x1, y1, x2, y2, x3, y3); + } + + BOOL RoundRect(LPCRECT lpRect, POINT point) + { + ATLASSERT(m_hDC != NULL); + return ::RoundRect(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, point.x, point.y); + } + +// Bitmap Functions + BOOL PatBlt(int x, int y, int nWidth, int nHeight, DWORD dwRop) + { + ATLASSERT(m_hDC != NULL); + return ::PatBlt(m_hDC, x, y, nWidth, nHeight, dwRop); + } + + BOOL BitBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, + int xSrc, int ySrc, DWORD dwRop) + { + ATLASSERT(m_hDC != NULL); + return ::BitBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, dwRop); + } + + BOOL StretchBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop) + { + ATLASSERT(m_hDC != NULL); + return ::StretchBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, dwRop); + } + + COLORREF GetPixel(int x, int y) const + { + ATLASSERT(m_hDC != NULL); + return ::GetPixel(m_hDC, x, y); + } + + COLORREF GetPixel(POINT point) const + { + ATLASSERT(m_hDC != NULL); + return ::GetPixel(m_hDC, point.x, point.y); + } + + COLORREF SetPixel(int x, int y, COLORREF crColor) + { + ATLASSERT(m_hDC != NULL); + return ::SetPixel(m_hDC, x, y, crColor); + } + + COLORREF SetPixel(POINT point, COLORREF crColor) + { + ATLASSERT(m_hDC != NULL); + return ::SetPixel(m_hDC, point.x, point.y, crColor); + } + +#ifndef _WIN32_WCE + BOOL FloodFill(int x, int y, COLORREF crColor) + { + ATLASSERT(m_hDC != NULL); + return ::FloodFill(m_hDC, x, y, crColor); + } + + BOOL ExtFloodFill(int x, int y, COLORREF crColor, UINT nFillType) + { + ATLASSERT(m_hDC != NULL); + return ::ExtFloodFill(m_hDC, x, y, crColor, nFillType); + } +#endif // !_WIN32_WCE + + BOOL MaskBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, HBITMAP hMaskBitmap, int xMask, int yMask, DWORD dwRop) + { + ATLASSERT(m_hDC != NULL); + return ::MaskBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, hMaskBitmap, xMask, yMask, dwRop); + } + +#ifndef _WIN32_WCE + BOOL PlgBlt(LPPOINT lpPoint, HDC hSrcDC, int xSrc, int ySrc, int nWidth, int nHeight, HBITMAP hMaskBitmap, int xMask, int yMask) + { + ATLASSERT(m_hDC != NULL); + return ::PlgBlt(m_hDC, lpPoint, hSrcDC, xSrc, ySrc, nWidth, nHeight, hMaskBitmap, xMask, yMask); + } + + BOOL SetPixelV(int x, int y, COLORREF crColor) + { + ATLASSERT(m_hDC != NULL); + return ::SetPixelV(m_hDC, x, y, crColor); + } + + BOOL SetPixelV(POINT point, COLORREF crColor) + { + ATLASSERT(m_hDC != NULL); + return ::SetPixelV(m_hDC, point.x, point.y, crColor); + } +#endif // !_WIN32_WCE + +#if !defined(_ATL_NO_MSIMG) || defined(_WIN32_WCE) +#ifndef _WIN32_WCE + BOOL TransparentBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, UINT crTransparent) + { + ATLASSERT(m_hDC != NULL); + return ::TransparentBlt(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, crTransparent); + } +#else // CE specific + BOOL TransparentImage(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, UINT crTransparent) + { + ATLASSERT(m_hDC != NULL); + return ::TransparentImage(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, crTransparent); + } +#endif // _WIN32_WCE + +#if (!defined(_WIN32_WCE) || (_WIN32_WCE >= 420)) + BOOL GradientFill(const PTRIVERTEX pVertices, DWORD nVertices, void* pMeshElements, DWORD nMeshElements, DWORD dwMode) + { + ATLASSERT(m_hDC != NULL); + return ::GradientFill(m_hDC, pVertices, nVertices, pMeshElements, nMeshElements, dwMode); + } + + BOOL GradientFillRect(RECT& rect, COLORREF clr1, COLORREF clr2, bool bHorizontal) + { + ATLASSERT(m_hDC != NULL); + + TRIVERTEX arrTvx[2] = { { 0 }, { 0 } }; + + arrTvx[0].x = rect.left; + arrTvx[0].y = rect.top; + arrTvx[0].Red = MAKEWORD(0, GetRValue(clr1)); + arrTvx[0].Green = MAKEWORD(0, GetGValue(clr1)); + arrTvx[0].Blue = MAKEWORD(0, GetBValue(clr1)); + arrTvx[0].Alpha = 0; + + arrTvx[1].x = rect.right; + arrTvx[1].y = rect.bottom; + arrTvx[1].Red = MAKEWORD(0, GetRValue(clr2)); + arrTvx[1].Green = MAKEWORD(0, GetGValue(clr2)); + arrTvx[1].Blue = MAKEWORD(0, GetBValue(clr2)); + arrTvx[1].Alpha = 0; + + GRADIENT_RECT gr = { 0, 1 }; + + return ::GradientFill(m_hDC, arrTvx, 2, &gr, 1, bHorizontal ? GRADIENT_FILL_RECT_H : GRADIENT_FILL_RECT_V); + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 420) + +#if !defined(_WIN32_WCE) || (_WIN32_WCE > 0x500) + BOOL AlphaBlend(int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, BLENDFUNCTION bf) + { + ATLASSERT(m_hDC != NULL); + return ::AlphaBlend(m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, nSrcWidth, nSrcHeight, bf); + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE > 0x500) +#endif // !defined(_ATL_NO_MSIMG) || defined(_WIN32_WCE) + +// Extra bitmap functions + // Helper function for painting a disabled toolbar or menu bitmap + // This function can take either an HBITMAP (for SS) or a DC with + // the bitmap already painted (for cmdbar) + BOOL DitherBlt(int x, int y, int nWidth, int nHeight, HDC hSrcDC, HBITMAP hBitmap, int xSrc, int ySrc, + HBRUSH hBrushBackground = ::GetSysColorBrush(COLOR_3DFACE), + HBRUSH hBrush3DEffect = ::GetSysColorBrush(COLOR_3DHILIGHT), + HBRUSH hBrushDisabledImage = ::GetSysColorBrush(COLOR_3DSHADOW)) + { + ATLASSERT(m_hDC != NULL || hBitmap != NULL); + ATLASSERT(nWidth > 0 && nHeight > 0); + + // Create a generic DC for all BitBlts + CDCHandle dc = (hSrcDC != NULL) ? hSrcDC : ::CreateCompatibleDC(m_hDC); + ATLASSERT(dc.m_hDC != NULL); + if(dc.m_hDC == NULL) + return FALSE; + + // Create a DC for the monochrome DIB section + CDC dcBW = ::CreateCompatibleDC(m_hDC); + ATLASSERT(dcBW.m_hDC != NULL); + if(dcBW.m_hDC == NULL) + { + if(hSrcDC == NULL) + dc.DeleteDC(); + return FALSE; + } + + // Create the monochrome DIB section with a black and white palette + struct RGBBWBITMAPINFO + { + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[2]; + }; + + RGBBWBITMAPINFO rgbBWBitmapInfo = + { + { sizeof(BITMAPINFOHEADER), nWidth, nHeight, 1, 1, BI_RGB, 0, 0, 0, 0, 0 }, + { { 0x00, 0x00, 0x00, 0x00 }, { 0xFF, 0xFF, 0xFF, 0x00 } } + }; + + VOID* pbitsBW; + CBitmap bmpBW = ::CreateDIBSection(dcBW, (LPBITMAPINFO)&rgbBWBitmapInfo, DIB_RGB_COLORS, &pbitsBW, NULL, 0); + ATLASSERT(bmpBW.m_hBitmap != NULL); + if(bmpBW.m_hBitmap == NULL) + { + if(hSrcDC == NULL) + dc.DeleteDC(); + return FALSE; + } + + // Attach the monochrome DIB section and the bitmap to the DCs + HBITMAP hbmOldBW = dcBW.SelectBitmap(bmpBW); + HBITMAP hbmOldDC = NULL; + if(hBitmap != NULL) + hbmOldDC = dc.SelectBitmap(hBitmap); + + // Block: Dark gray removal: we want (128, 128, 128) pixels to become black and not white + { + CDC dcTemp1 = ::CreateCompatibleDC(m_hDC); + CDC dcTemp2 = ::CreateCompatibleDC(m_hDC); + CBitmap bmpTemp1; + bmpTemp1.CreateCompatibleBitmap(dc, nWidth, nHeight); + CBitmap bmpTemp2; + bmpTemp2.CreateBitmap(nWidth, nHeight, 1, 1, NULL); + HBITMAP hOldBmp1 = dcTemp1.SelectBitmap(bmpTemp1); + HBITMAP hOldBmp2 = dcTemp2.SelectBitmap(bmpTemp2); + // Let's copy our image, it will be altered + dcTemp1.BitBlt(0, 0, nWidth, nHeight, dc, xSrc, ySrc, SRCCOPY); + + // All dark gray pixels will become white, the others black + dcTemp1.SetBkColor(RGB(128, 128, 128)); + dcTemp2.BitBlt(0, 0, nWidth, nHeight, dcTemp1, 0, 0, SRCCOPY); + // Do an XOR to set to black these white pixels + dcTemp1.BitBlt(0, 0, nWidth, nHeight, dcTemp2, 0, 0, SRCINVERT); + + // BitBlt the bitmap into the monochrome DIB section + // The DIB section will do a true monochrome conversion + // The magenta background being closer to white will become white + dcBW.BitBlt(0, 0, nWidth, nHeight, dcTemp1, 0, 0, SRCCOPY); + + // Cleanup + dcTemp1.SelectBitmap(hOldBmp1); + dcTemp2.SelectBitmap(hOldBmp2); + } + + // Paint the destination rectangle using hBrushBackground + if(hBrushBackground != NULL) + { + RECT rc = { x, y, x + nWidth, y + nHeight }; + FillRect(&rc, hBrushBackground); + } + + // BitBlt the black bits in the monochrome bitmap into hBrush3DEffect color in the destination DC + // The magic ROP comes from the Charles Petzold's book + HBRUSH hOldBrush = SelectBrush(hBrush3DEffect); + BitBlt(x + 1, y + 1, nWidth, nHeight, dcBW, 0, 0, 0xB8074A); + + // BitBlt the black bits in the monochrome bitmap into hBrushDisabledImage color in the destination DC + SelectBrush(hBrushDisabledImage); + BitBlt(x, y, nWidth, nHeight, dcBW, 0, 0, 0xB8074A); + + SelectBrush(hOldBrush); + dcBW.SelectBitmap(hbmOldBW); + dc.SelectBitmap(hbmOldDC); + + if(hSrcDC == NULL) + dc.DeleteDC(); + + return TRUE; + } + +// Text Functions +#ifndef _WIN32_WCE + BOOL TextOut(int x, int y, LPCTSTR lpszString, int nCount = -1) + { + ATLASSERT(m_hDC != NULL); + if(nCount == -1) + nCount = lstrlen(lpszString); + return ::TextOut(m_hDC, x, y, lpszString, nCount); + } +#endif // !_WIN32_WCE + + BOOL ExtTextOut(int x, int y, UINT nOptions, LPCRECT lpRect, LPCTSTR lpszString, UINT nCount = -1, LPINT lpDxWidths = NULL) + { + ATLASSERT(m_hDC != NULL); + if(nCount == -1) + nCount = lstrlen(lpszString); + return ::ExtTextOut(m_hDC, x, y, nOptions, lpRect, lpszString, nCount, lpDxWidths); + } + +#ifndef _WIN32_WCE + SIZE TabbedTextOut(int x, int y, LPCTSTR lpszString, int nCount = -1, int nTabPositions = 0, LPINT lpnTabStopPositions = NULL, int nTabOrigin = 0) + { + ATLASSERT(m_hDC != NULL); + if(nCount == -1) + nCount = lstrlen(lpszString); + LONG lRes = ::TabbedTextOut(m_hDC, x, y, lpszString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin); + SIZE size = { GET_X_LPARAM(lRes), GET_Y_LPARAM(lRes) }; + return size; + } +#endif // !_WIN32_WCE + + int DrawText(LPCTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat) + { + ATLASSERT(m_hDC != NULL); +#ifndef _WIN32_WCE + ATLASSERT((uFormat & DT_MODIFYSTRING) == 0); +#endif // !_WIN32_WCE + return ::DrawText(m_hDC, lpstrText, cchText, lpRect, uFormat); + } + + int DrawText(LPTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat) + { + ATLASSERT(m_hDC != NULL); + return ::DrawText(m_hDC, lpstrText, cchText, lpRect, uFormat); + } + +#ifndef _WIN32_WCE + int DrawTextEx(LPTSTR lpstrText, int cchText, LPRECT lpRect, UINT uFormat, LPDRAWTEXTPARAMS lpDTParams = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::DrawTextEx(m_hDC, lpstrText, cchText, lpRect, uFormat, lpDTParams); + } +#endif // !_WIN32_WCE + +#if (_WIN32_WINNT >= 0x0501) + int DrawShadowText(LPCWSTR lpstrText, int cchText, LPRECT lpRect, DWORD dwFlags, COLORREF clrText, COLORREF clrShadow, int xOffset, int yOffset) + { + ATLASSERT(m_hDC != NULL); + // This function is present only if comctl32.dll version 6 is loaded; + // we use LoadLibrary/GetProcAddress to allow apps compiled with + // _WIN32_WINNT >= 0x0501 to run on older Windows/CommCtrl + int nRet = 0; + HMODULE hCommCtrlDLL = ::LoadLibrary(_T("comctl32.dll")); + ATLASSERT(hCommCtrlDLL != NULL); + if(hCommCtrlDLL != NULL) + { + typedef int (WINAPI *PFN_DrawShadowText)(HDC hDC, LPCWSTR lpstrText, UINT cchText, LPRECT lpRect, DWORD dwFlags, COLORREF clrText, COLORREF clrShadow, int xOffset, int yOffset); + PFN_DrawShadowText pfnDrawShadowText = (PFN_DrawShadowText)::GetProcAddress(hCommCtrlDLL, "DrawShadowText"); + ATLASSERT(pfnDrawShadowText != NULL); // this function requires CommCtrl6 + if(pfnDrawShadowText != NULL) + nRet = pfnDrawShadowText(m_hDC, lpstrText, cchText, lpRect, dwFlags, clrText, clrShadow, xOffset, yOffset); + ::FreeLibrary(hCommCtrlDLL); + } + return nRet; + } +#endif // (_WIN32_WINNT >= 0x0501) + + BOOL GetTextExtent(LPCTSTR lpszString, int nCount, LPSIZE lpSize) const + { + ATLASSERT(m_hDC != NULL); + if(nCount == -1) + nCount = lstrlen(lpszString); + return ::GetTextExtentPoint32(m_hDC, lpszString, nCount, lpSize); + } + + BOOL GetTextExtentExPoint(LPCTSTR lpszString, int cchString, LPSIZE lpSize, int nMaxExtent, LPINT lpnFit = NULL, LPINT alpDx = NULL) + { + ATLASSERT(m_hDC != NULL); + return ::GetTextExtentExPoint(m_hDC, lpszString, cchString, nMaxExtent, lpnFit, alpDx, lpSize); + } + +#ifndef _WIN32_WCE + DWORD GetTabbedTextExtent(LPCTSTR lpszString, int nCount = -1, int nTabPositions = 0, LPINT lpnTabStopPositions = NULL) const + { + ATLASSERT(m_hDC != NULL); + if(nCount == -1) + nCount = lstrlen(lpszString); + return ::GetTabbedTextExtent(m_hDC, lpszString, nCount, nTabPositions, lpnTabStopPositions); + } + + BOOL GrayString(HBRUSH hBrush, BOOL (CALLBACK* lpfnOutput)(HDC, LPARAM, int), LPARAM lpData, int nCount, int x, int y, int nWidth, int nHeight) + { + ATLASSERT(m_hDC != NULL); + return ::GrayString(m_hDC, hBrush, (GRAYSTRINGPROC)lpfnOutput, lpData, nCount, x, y, nWidth, nHeight); + } +#endif // !_WIN32_WCE + +#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) + UINT GetTextAlign() const + { + ATLASSERT(m_hDC != NULL); + return ::GetTextAlign(m_hDC); + } + + UINT SetTextAlign(UINT nFlags) + { + ATLASSERT(m_hDC != NULL); + return ::SetTextAlign(m_hDC, nFlags); + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) + + int GetTextFace(LPTSTR lpszFacename, int nCount) const + { + ATLASSERT(m_hDC != NULL); + return ::GetTextFace(m_hDC, nCount, lpszFacename); + } + + int GetTextFaceLen() const + { + ATLASSERT(m_hDC != NULL); + return ::GetTextFace(m_hDC, 0, NULL); + } + +#ifndef _ATL_NO_COM +#ifdef _OLEAUTO_H_ + BOOL GetTextFace(BSTR& bstrFace) const + { + USES_CONVERSION; + ATLASSERT(m_hDC != NULL); + ATLASSERT(bstrFace == NULL); + + int nLen = GetTextFaceLen(); + if(nLen == 0) + return FALSE; + + CTempBuffer buff; + LPTSTR lpszText = buff.Allocate(nLen); + if(lpszText == NULL) + return FALSE; + + if(!GetTextFace(lpszText, nLen)) + return FALSE; + + bstrFace = ::SysAllocString(T2OLE(lpszText)); + return (bstrFace != NULL) ? TRUE : FALSE; + } +#endif +#endif // !_ATL_NO_COM + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + int GetTextFace(_CSTRING_NS::CString& strFace) const + { + ATLASSERT(m_hDC != NULL); + + int nLen = GetTextFaceLen(); + if(nLen == 0) + return 0; + + LPTSTR lpstr = strFace.GetBufferSetLength(nLen); + if(lpstr == NULL) + return 0; + int nRet = GetTextFace(lpstr, nLen); + strFace.ReleaseBuffer(); + return nRet; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + BOOL GetTextMetrics(LPTEXTMETRIC lpMetrics) const + { + ATLASSERT(m_hDC != NULL); + return ::GetTextMetrics(m_hDC, lpMetrics); + } + +#ifndef _WIN32_WCE + int SetTextJustification(int nBreakExtra, int nBreakCount) + { + ATLASSERT(m_hDC != NULL); + return ::SetTextJustification(m_hDC, nBreakExtra, nBreakCount); + } + + int GetTextCharacterExtra() const + { + ATLASSERT(m_hDC != NULL); + return ::GetTextCharacterExtra(m_hDC); + } + + int SetTextCharacterExtra(int nCharExtra) + { + ATLASSERT(m_hDC != NULL); + return ::SetTextCharacterExtra(m_hDC, nCharExtra); + } +#endif // !_WIN32_WCE + +// Advanced Drawing + BOOL DrawEdge(LPRECT lpRect, UINT nEdge, UINT nFlags) + { + ATLASSERT(m_hDC != NULL); + return ::DrawEdge(m_hDC, lpRect, nEdge, nFlags); + } + + BOOL DrawFrameControl(LPRECT lpRect, UINT nType, UINT nState) + { + ATLASSERT(m_hDC != NULL); + return ::DrawFrameControl(m_hDC, lpRect, nType, nState); + } + +// Scrolling Functions + BOOL ScrollDC(int dx, int dy, LPCRECT lpRectScroll, LPCRECT lpRectClip, HRGN hRgnUpdate, LPRECT lpRectUpdate) + { + ATLASSERT(m_hDC != NULL); + return ::ScrollDC(m_hDC, dx, dy, lpRectScroll, lpRectClip, hRgnUpdate, lpRectUpdate); + } + +// Font Functions +#ifndef _WIN32_WCE + BOOL GetCharWidth(UINT nFirstChar, UINT nLastChar, LPINT lpBuffer) const + { + ATLASSERT(m_hDC != NULL); + return ::GetCharWidth(m_hDC, nFirstChar, nLastChar, lpBuffer); + } + + // GetCharWidth32 is not supported under Win9x + BOOL GetCharWidth32(UINT nFirstChar, UINT nLastChar, LPINT lpBuffer) const + { + ATLASSERT(m_hDC != NULL); + return ::GetCharWidth32(m_hDC, nFirstChar, nLastChar, lpBuffer); + } + + DWORD SetMapperFlags(DWORD dwFlag) + { + ATLASSERT(m_hDC != NULL); + return ::SetMapperFlags(m_hDC, dwFlag); + } + + BOOL GetAspectRatioFilter(LPSIZE lpSize) const + { + ATLASSERT(m_hDC != NULL); + return ::GetAspectRatioFilterEx(m_hDC, lpSize); + } + + BOOL GetCharABCWidths(UINT nFirstChar, UINT nLastChar, LPABC lpabc) const + { + ATLASSERT(m_hDC != NULL); + return ::GetCharABCWidths(m_hDC, nFirstChar, nLastChar, lpabc); + } + + DWORD GetFontData(DWORD dwTable, DWORD dwOffset, LPVOID lpData, DWORD cbData) const + { + ATLASSERT(m_hDC != NULL); + return ::GetFontData(m_hDC, dwTable, dwOffset, lpData, cbData); + } + + int GetKerningPairs(int nPairs, LPKERNINGPAIR lpkrnpair) const + { + ATLASSERT(m_hDC != NULL); + return ::GetKerningPairs(m_hDC, nPairs, lpkrnpair); + } + + UINT GetOutlineTextMetrics(UINT cbData, LPOUTLINETEXTMETRIC lpotm) const + { + ATLASSERT(m_hDC != NULL); + return ::GetOutlineTextMetrics(m_hDC, cbData, lpotm); + } + + DWORD GetGlyphOutline(UINT nChar, UINT nFormat, LPGLYPHMETRICS lpgm, DWORD cbBuffer, LPVOID lpBuffer, const MAT2* lpmat2) const + { + ATLASSERT(m_hDC != NULL); + return ::GetGlyphOutline(m_hDC, nChar, nFormat, lpgm, cbBuffer, lpBuffer, lpmat2); + } + + BOOL GetCharABCWidths(UINT nFirstChar, UINT nLastChar, LPABCFLOAT lpABCF) const + { + ATLASSERT(m_hDC != NULL); + return ::GetCharABCWidthsFloat(m_hDC, nFirstChar, nLastChar, lpABCF); + } + + BOOL GetCharWidth(UINT nFirstChar, UINT nLastChar, float* lpFloatBuffer) const + { + ATLASSERT(m_hDC != NULL); + return ::GetCharWidthFloat(m_hDC, nFirstChar, nLastChar, lpFloatBuffer); + } +#endif // !_WIN32_WCE + +// Printer/Device Escape Functions +#ifndef _WIN32_WCE + int Escape(int nEscape, int nCount, LPCSTR lpszInData, LPVOID lpOutData) + { + ATLASSERT(m_hDC != NULL); + return ::Escape(m_hDC, nEscape, nCount, lpszInData, lpOutData); + } +#endif // !_WIN32_WCE + + int Escape(int nEscape, int nInputSize, LPCSTR lpszInputData, + int nOutputSize, LPSTR lpszOutputData) + { + ATLASSERT(m_hDC != NULL); + return ::ExtEscape(m_hDC, nEscape, nInputSize, lpszInputData, nOutputSize, lpszOutputData); + } + +#ifndef _WIN32_WCE + int DrawEscape(int nEscape, int nInputSize, LPCSTR lpszInputData) + { + ATLASSERT(m_hDC != NULL); + return ::DrawEscape(m_hDC, nEscape, nInputSize, lpszInputData); + } +#endif // !_WIN32_WCE + + // Escape helpers +#if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 200) && defined(StartDoc)) + int StartDoc(LPCTSTR lpszDocName) // old Win3.0 version + { + DOCINFO di = { 0 }; + di.cbSize = sizeof(DOCINFO); + di.lpszDocName = lpszDocName; + return StartDoc(&di); + } + + int StartDoc(LPDOCINFO lpDocInfo) + { + ATLASSERT(m_hDC != NULL); + return ::StartDoc(m_hDC, lpDocInfo); + } + + int StartPage() + { + ATLASSERT(m_hDC != NULL); + return ::StartPage(m_hDC); + } + + int EndPage() + { + ATLASSERT(m_hDC != NULL); + return ::EndPage(m_hDC); + } + + int SetAbortProc(BOOL (CALLBACK* lpfn)(HDC, int)) + { + ATLASSERT(m_hDC != NULL); + return ::SetAbortProc(m_hDC, (ABORTPROC)lpfn); + } + + int AbortDoc() + { + ATLASSERT(m_hDC != NULL); + return ::AbortDoc(m_hDC); + } + + int EndDoc() + { + ATLASSERT(m_hDC != NULL); + return ::EndDoc(m_hDC); + } +#endif // !defined(_WIN32_WCE) || ((_WIN32_WCE >= 200) && defined(StartDoc)) + +// MetaFile Functions +#ifndef _WIN32_WCE + BOOL PlayMetaFile(HMETAFILE hMF) + { + ATLASSERT(m_hDC != NULL); + if(::GetDeviceCaps(m_hDC, TECHNOLOGY) == DT_METAFILE) + { + // playing metafile in metafile, just use core windows API + return ::PlayMetaFile(m_hDC, hMF); + } + + // for special playback, lParam == pDC + return ::EnumMetaFile(m_hDC, hMF, EnumMetaFileProc, (LPARAM)this); + } + + BOOL PlayMetaFile(HENHMETAFILE hEnhMetaFile, LPCRECT lpBounds) + { + ATLASSERT(m_hDC != NULL); + return ::PlayEnhMetaFile(m_hDC, hEnhMetaFile, lpBounds); + } + + BOOL AddMetaFileComment(UINT nDataSize, const BYTE* pCommentData) // can be used for enhanced metafiles only + { + ATLASSERT(m_hDC != NULL); + return ::GdiComment(m_hDC, nDataSize, pCommentData); + } + + // Special handling for metafile playback + static int CALLBACK EnumMetaFileProc(HDC hDC, HANDLETABLE* pHandleTable, METARECORD* pMetaRec, int nHandles, LPARAM lParam) + { + CDCHandle* pDC = (CDCHandle*)lParam; + + switch (pMetaRec->rdFunction) + { + case META_SETMAPMODE: + pDC->SetMapMode((int)(short)pMetaRec->rdParm[0]); + break; + case META_SETWINDOWEXT: + pDC->SetWindowExt((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); + break; + case META_SETWINDOWORG: + pDC->SetWindowOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); + break; + case META_SETVIEWPORTEXT: + pDC->SetViewportExt((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); + break; + case META_SETVIEWPORTORG: + pDC->SetViewportOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); + break; + case META_SCALEWINDOWEXT: + pDC->ScaleWindowExt((int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2], + (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); + break; + case META_SCALEVIEWPORTEXT: + pDC->ScaleViewportExt((int)(short)pMetaRec->rdParm[3], (int)(short)pMetaRec->rdParm[2], + (int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); + break; + case META_OFFSETVIEWPORTORG: + pDC->OffsetViewportOrg((int)(short)pMetaRec->rdParm[1], (int)(short)pMetaRec->rdParm[0]); + break; + case META_SAVEDC: + pDC->SaveDC(); + break; + case META_RESTOREDC: + pDC->RestoreDC((int)(short)pMetaRec->rdParm[0]); + break; + case META_SETBKCOLOR: + pDC->SetBkColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]); + break; + case META_SETTEXTCOLOR: + pDC->SetTextColor(*(UNALIGNED COLORREF*)&pMetaRec->rdParm[0]); + break; + + // need to watch out for SelectObject(HFONT), for custom font mapping + case META_SELECTOBJECT: + { + HGDIOBJ hObject = pHandleTable->objectHandle[pMetaRec->rdParm[0]]; + UINT nObjType = ::GetObjectType(hObject); + if(nObjType == 0) + { + // object type is unknown, determine if it is a font + HFONT hStockFont = (HFONT)::GetStockObject(SYSTEM_FONT); + HFONT hFontOld = (HFONT)::SelectObject(pDC->m_hDC, hStockFont); + HGDIOBJ hObjOld = ::SelectObject(pDC->m_hDC, hObject); + if(hObjOld == hStockFont) + { + // got the stock object back, so must be selecting a font + pDC->SelectFont((HFONT)hObject); + break; // don't play the default record + } + else + { + // didn't get the stock object back, so restore everything + ::SelectObject(pDC->m_hDC, hFontOld); + ::SelectObject(pDC->m_hDC, hObjOld); + } + // and fall through to PlayMetaFileRecord... + } + else if(nObjType == OBJ_FONT) + { + // play back as CDCHandle::SelectFont(HFONT) + pDC->SelectFont((HFONT)hObject); + break; // don't play the default record + } + } + // fall through... + + default: + ::PlayMetaFileRecord(hDC, pHandleTable, pMetaRec, nHandles); + break; + } + + return 1; + } +#endif // !_WIN32_WCE + +// Path Functions +#ifndef _WIN32_WCE + BOOL AbortPath() + { + ATLASSERT(m_hDC != NULL); + return ::AbortPath(m_hDC); + } + + BOOL BeginPath() + { + ATLASSERT(m_hDC != NULL); + return ::BeginPath(m_hDC); + } + + BOOL CloseFigure() + { + ATLASSERT(m_hDC != NULL); + return ::CloseFigure(m_hDC); + } + + BOOL EndPath() + { + ATLASSERT(m_hDC != NULL); + return ::EndPath(m_hDC); + } + + BOOL FillPath() + { + ATLASSERT(m_hDC != NULL); + return ::FillPath(m_hDC); + } + + BOOL FlattenPath() + { + ATLASSERT(m_hDC != NULL); + return ::FlattenPath(m_hDC); + } + + BOOL StrokeAndFillPath() + { + ATLASSERT(m_hDC != NULL); + return ::StrokeAndFillPath(m_hDC); + } + + BOOL StrokePath() + { + ATLASSERT(m_hDC != NULL); + return ::StrokePath(m_hDC); + } + + BOOL WidenPath() + { + ATLASSERT(m_hDC != NULL); + return ::WidenPath(m_hDC); + } + + BOOL GetMiterLimit(PFLOAT pfMiterLimit) const + { + ATLASSERT(m_hDC != NULL); + return ::GetMiterLimit(m_hDC, pfMiterLimit); + } + + BOOL SetMiterLimit(float fMiterLimit) + { + ATLASSERT(m_hDC != NULL); + return ::SetMiterLimit(m_hDC, fMiterLimit, NULL); + } + + int GetPath(LPPOINT lpPoints, LPBYTE lpTypes, int nCount) const + { + ATLASSERT(m_hDC != NULL); + return ::GetPath(m_hDC, lpPoints, lpTypes, nCount); + } + + BOOL SelectClipPath(int nMode) + { + ATLASSERT(m_hDC != NULL); + return ::SelectClipPath(m_hDC, nMode); + } +#endif // !_WIN32_WCE + +// Misc Helper Functions + static CBrushHandle PASCAL GetHalftoneBrush() + { + HBRUSH halftoneBrush = NULL; + WORD grayPattern[8]; + for(int i = 0; i < 8; i++) + grayPattern[i] = (WORD)(0x5555 << (i & 1)); + HBITMAP grayBitmap = CreateBitmap(8, 8, 1, 1, &grayPattern); + if(grayBitmap != NULL) + { + halftoneBrush = ::CreatePatternBrush(grayBitmap); + DeleteObject(grayBitmap); + } + return CBrushHandle(halftoneBrush); + } + + void DrawDragRect(LPCRECT lpRect, SIZE size, LPCRECT lpRectLast, SIZE sizeLast, HBRUSH hBrush = NULL, HBRUSH hBrushLast = NULL) + { + // first, determine the update region and select it + CRgn rgnOutside; + rgnOutside.CreateRectRgnIndirect(lpRect); + RECT rect = *lpRect; + ::InflateRect(&rect, -size.cx, -size.cy); + ::IntersectRect(&rect, &rect, lpRect); + CRgn rgnInside; + rgnInside.CreateRectRgnIndirect(&rect); + CRgn rgnNew; + rgnNew.CreateRectRgn(0, 0, 0, 0); + rgnNew.CombineRgn(rgnOutside, rgnInside, RGN_XOR); + + HBRUSH hBrushOld = NULL; + CBrush brushHalftone; + if(hBrush == NULL) + brushHalftone = hBrush = CDCHandle::GetHalftoneBrush(); + if(hBrushLast == NULL) + hBrushLast = hBrush; + + CRgn rgnLast; + CRgn rgnUpdate; + if(lpRectLast != NULL) + { + // find difference between new region and old region + rgnLast.CreateRectRgn(0, 0, 0, 0); + rgnOutside.SetRectRgn(lpRectLast->left, lpRectLast->top, lpRectLast->right, lpRectLast->bottom); + rect = *lpRectLast; + ::InflateRect(&rect, -sizeLast.cx, -sizeLast.cy); + ::IntersectRect(&rect, &rect, lpRectLast); + rgnInside.SetRectRgn(rect.left, rect.top, rect.right, rect.bottom); + rgnLast.CombineRgn(rgnOutside, rgnInside, RGN_XOR); + + // only diff them if brushes are the same + if(hBrush == hBrushLast) + { + rgnUpdate.CreateRectRgn(0, 0, 0, 0); + rgnUpdate.CombineRgn(rgnLast, rgnNew, RGN_XOR); + } + } + if(hBrush != hBrushLast && lpRectLast != NULL) + { + // brushes are different -- erase old region first + SelectClipRgn(rgnLast); + GetClipBox(&rect); + hBrushOld = SelectBrush(hBrushLast); + PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT); + SelectBrush(hBrushOld); + hBrushOld = NULL; + } + + // draw into the update/new region + SelectClipRgn(rgnUpdate.IsNull() ? rgnNew : rgnUpdate); + GetClipBox(&rect); + hBrushOld = SelectBrush(hBrush); + PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT); + + // cleanup DC + if(hBrushOld != NULL) + SelectBrush(hBrushOld); + SelectClipRgn(NULL); + } + + void FillSolidRect(LPCRECT lpRect, COLORREF clr) + { + ATLASSERT(m_hDC != NULL); + + COLORREF clrOld = ::SetBkColor(m_hDC, clr); + ATLASSERT(clrOld != CLR_INVALID); + if(clrOld != CLR_INVALID) + { + ::ExtTextOut(m_hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL); + ::SetBkColor(m_hDC, clrOld); + } + } + + void FillSolidRect(int x, int y, int cx, int cy, COLORREF clr) + { + ATLASSERT(m_hDC != NULL); + + RECT rect = { x, y, x + cx, y + cy }; + FillSolidRect(&rect, clr); + } + + void Draw3dRect(LPCRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight) + { + Draw3dRect(lpRect->left, lpRect->top, lpRect->right - lpRect->left, + lpRect->bottom - lpRect->top, clrTopLeft, clrBottomRight); + } + + void Draw3dRect(int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight) + { + FillSolidRect(x, y, cx - 1, 1, clrTopLeft); + FillSolidRect(x, y, 1, cy - 1, clrTopLeft); + FillSolidRect(x + cx, y, -1, cy, clrBottomRight); + FillSolidRect(x, y + cy, cx, -1, clrBottomRight); + } + +// DIB support +#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 410) + int SetDIBitsToDevice(int x, int y, DWORD dwWidth, DWORD dwHeight, int xSrc, int ySrc, UINT uStartScan, UINT cScanLines, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse) + { + ATLASSERT(m_hDC != NULL); + return ::SetDIBitsToDevice(m_hDC, x, y, dwWidth, dwHeight, xSrc, ySrc, uStartScan, cScanLines, lpvBits, lpbmi, uColorUse); + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 410) + +#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) + int StretchDIBits(int x, int y, int nWidth, int nHeight, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, CONST VOID* lpvBits, CONST BITMAPINFO* lpbmi, UINT uColorUse, DWORD dwRop) + { + ATLASSERT(m_hDC != NULL); + return ::StretchDIBits(m_hDC, x, y, nWidth, nHeight, xSrc, ySrc, nSrcWidth, nSrcHeight, lpvBits, lpbmi, uColorUse, dwRop); + } + + UINT GetDIBColorTable(UINT uStartIndex, UINT cEntries, RGBQUAD* pColors) const + { + ATLASSERT(m_hDC != NULL); + return ::GetDIBColorTable(m_hDC, uStartIndex, cEntries, pColors); + } + + UINT SetDIBColorTable(UINT uStartIndex, UINT cEntries, CONST RGBQUAD* pColors) + { + ATLASSERT(m_hDC != NULL); + return ::SetDIBColorTable(m_hDC, uStartIndex, cEntries, pColors); + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) + +// OpenGL support +#if !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE) + int ChoosePixelFormat(CONST PIXELFORMATDESCRIPTOR* ppfd) + { + ATLASSERT(m_hDC != NULL); + return ::ChoosePixelFormat(m_hDC, ppfd); + } + + int DescribePixelFormat(int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd) + { + ATLASSERT(m_hDC != NULL); + return ::DescribePixelFormat(m_hDC, iPixelFormat, nBytes, ppfd); + } + + int GetPixelFormat() const + { + ATLASSERT(m_hDC != NULL); + return ::GetPixelFormat(m_hDC); + } + + BOOL SetPixelFormat(int iPixelFormat, CONST PIXELFORMATDESCRIPTOR* ppfd) + { + ATLASSERT(m_hDC != NULL); + return ::SetPixelFormat(m_hDC, iPixelFormat, ppfd); + } + + BOOL SwapBuffers() + { + ATLASSERT(m_hDC != NULL); + return ::SwapBuffers(m_hDC); + } + + HGLRC wglCreateContext() + { + ATLASSERT(m_hDC != NULL); + return ::wglCreateContext(m_hDC); + } + + HGLRC wglCreateLayerContext(int iLayerPlane) + { + ATLASSERT(m_hDC != NULL); + return ::wglCreateLayerContext(m_hDC, iLayerPlane); + } + + BOOL wglMakeCurrent(HGLRC hglrc) + { + ATLASSERT(m_hDC != NULL); + return ::wglMakeCurrent(m_hDC, hglrc); + } + + BOOL wglUseFontBitmaps(DWORD dwFirst, DWORD dwCount, DWORD listBase) + { + ATLASSERT(m_hDC != NULL); + return ::wglUseFontBitmaps(m_hDC, dwFirst, dwCount, listBase); + } + + BOOL wglUseFontOutlines(DWORD dwFirst, DWORD dwCount, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf) + { + ATLASSERT(m_hDC != NULL); + return ::wglUseFontOutlines(m_hDC, dwFirst, dwCount, listBase, deviation, extrusion, format, lpgmf); + } + + BOOL wglDescribeLayerPlane(int iPixelFormat, int iLayerPlane, UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd) + { + ATLASSERT(m_hDC != NULL); + return ::wglDescribeLayerPlane(m_hDC, iPixelFormat, iLayerPlane, nBytes, plpd); + } + + int wglSetLayerPaletteEntries(int iLayerPlane, int iStart, int cEntries, CONST COLORREF* pclr) + { + ATLASSERT(m_hDC != NULL); + return ::wglSetLayerPaletteEntries(m_hDC, iLayerPlane, iStart, cEntries, pclr); + } + + int wglGetLayerPaletteEntries(int iLayerPlane, int iStart, int cEntries, COLORREF* pclr) + { + ATLASSERT(m_hDC != NULL); + return ::wglGetLayerPaletteEntries(m_hDC, iLayerPlane, iStart, cEntries, pclr); + } + + BOOL wglRealizeLayerPalette(int iLayerPlane, BOOL bRealize) + { + ATLASSERT(m_hDC != NULL); + return ::wglRealizeLayerPalette(m_hDC, iLayerPlane, bRealize); + } + + BOOL wglSwapLayerBuffers(UINT uPlanes) + { + ATLASSERT(m_hDC != NULL); + return ::wglSwapLayerBuffers(m_hDC, uPlanes); + } +#endif // !defined(_ATL_NO_OPENGL) && !defined(_WIN32_WCE) + +// New for Windows 2000 only +#if (_WIN32_WINNT >= 0x0500) + COLORREF GetDCPenColor() const + { + ATLASSERT(m_hDC != NULL); + return ::GetDCPenColor(m_hDC); + } + + COLORREF SetDCPenColor(COLORREF clr) + { + ATLASSERT(m_hDC != NULL); + return ::SetDCPenColor(m_hDC, clr); + } + + COLORREF GetDCBrushColor() const + { + ATLASSERT(m_hDC != NULL); + return ::GetDCBrushColor(m_hDC); + } + + COLORREF SetDCBrushColor(COLORREF clr) + { + ATLASSERT(m_hDC != NULL); + return ::SetDCBrushColor(m_hDC, clr); + } + +#ifndef _WIN32_WCE + DWORD GetFontUnicodeRanges(LPGLYPHSET lpgs) const + { + ATLASSERT(m_hDC != NULL); + return ::GetFontUnicodeRanges(m_hDC, lpgs); + } +#endif // !_WIN32_WCE + + DWORD GetGlyphIndices(LPCTSTR lpstr, int cch, LPWORD pgi, DWORD dwFlags) const + { + ATLASSERT(m_hDC != NULL); + return ::GetGlyphIndices(m_hDC, lpstr, cch, pgi, dwFlags); + } + + BOOL GetTextExtentPointI(LPWORD pgiIn, int cgi, LPSIZE lpSize) const + { + ATLASSERT(m_hDC != NULL); + return ::GetTextExtentPointI(m_hDC, pgiIn, cgi, lpSize); + } + + BOOL GetTextExtentExPointI(LPWORD pgiIn, int cgi, int nMaxExtent, LPINT lpnFit, LPINT alpDx, LPSIZE lpSize) const + { + ATLASSERT(m_hDC != NULL); + return ::GetTextExtentExPointI(m_hDC, pgiIn, cgi, nMaxExtent, lpnFit, alpDx, lpSize); + } + + BOOL GetCharWidthI(UINT giFirst, UINT cgi, LPWORD pgi, LPINT lpBuffer) const + { + ATLASSERT(m_hDC != NULL); + return ::GetCharWidthI(m_hDC, giFirst, cgi, pgi, lpBuffer); + } + + BOOL GetCharABCWidthsI(UINT giFirst, UINT cgi, LPWORD pgi, LPABC lpabc) const + { + ATLASSERT(m_hDC != NULL); + return ::GetCharABCWidthsI(m_hDC, giFirst, cgi, pgi, lpabc); + } +#endif // (_WIN32_WINNT >= 0x0500) + +// New for Windows 2000 and Windows 98 +#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) + BOOL ColorCorrectPalette(HPALETTE hPalette, DWORD dwFirstEntry, DWORD dwNumOfEntries) + { + ATLASSERT(m_hDC != NULL); + return ::ColorCorrectPalette(m_hDC, hPalette, dwFirstEntry, dwNumOfEntries); + } +#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) +}; + +typedef CDCT CDCHandle; +typedef CDCT CDC; + + +/////////////////////////////////////////////////////////////////////////////// +// CDC Helpers + +class CPaintDC : public CDC +{ +public: +// Data members + HWND m_hWnd; + PAINTSTRUCT m_ps; + +// Constructor/destructor + CPaintDC(HWND hWnd) + { + ATLASSERT(::IsWindow(hWnd)); + m_hWnd = hWnd; + m_hDC = ::BeginPaint(hWnd, &m_ps); + } + + ~CPaintDC() + { + ATLASSERT(m_hDC != NULL); + ATLASSERT(::IsWindow(m_hWnd)); + ::EndPaint(m_hWnd, &m_ps); + Detach(); + } +}; + +class CClientDC : public CDC +{ +public: +// Data members + HWND m_hWnd; + +// Constructor/destructor + CClientDC(HWND hWnd) + { + ATLASSERT(hWnd == NULL || ::IsWindow(hWnd)); + m_hWnd = hWnd; + m_hDC = ::GetDC(hWnd); + } + + ~CClientDC() + { + ATLASSERT(m_hDC != NULL); + ::ReleaseDC(m_hWnd, Detach()); + } +}; + +class CWindowDC : public CDC +{ +public: +// Data members + HWND m_hWnd; + +// Constructor/destructor + CWindowDC(HWND hWnd) + { + ATLASSERT(hWnd == NULL || ::IsWindow(hWnd)); + m_hWnd = hWnd; + m_hDC = ::GetWindowDC(hWnd); + } + + ~CWindowDC() + { + ATLASSERT(m_hDC != NULL); + ::ReleaseDC(m_hWnd, Detach()); + } +}; + +class CMemoryDC : public CDC +{ +public: +// Data members + HDC m_hDCOriginal; + RECT m_rcPaint; + CBitmap m_bmp; + HBITMAP m_hBmpOld; + +// Constructor/destructor + CMemoryDC(HDC hDC, RECT& rcPaint) : m_hDCOriginal(hDC), m_hBmpOld(NULL) + { + m_rcPaint = rcPaint; + CreateCompatibleDC(m_hDCOriginal); + ATLASSERT(m_hDC != NULL); + m_bmp.CreateCompatibleBitmap(m_hDCOriginal, m_rcPaint.right - m_rcPaint.left, m_rcPaint.bottom - m_rcPaint.top); + ATLASSERT(m_bmp.m_hBitmap != NULL); + m_hBmpOld = SelectBitmap(m_bmp); + SetViewportOrg(-m_rcPaint.left, -m_rcPaint.top); + } + + ~CMemoryDC() + { + ::BitBlt(m_hDCOriginal, m_rcPaint.left, m_rcPaint.top, m_rcPaint.right - m_rcPaint.left, m_rcPaint.bottom - m_rcPaint.top, m_hDC, m_rcPaint.left, m_rcPaint.top, SRCCOPY); + SelectBitmap(m_hBmpOld); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// Enhanced metafile support + +#ifndef _WIN32_WCE + +class CEnhMetaFileInfo +{ +public: +// Data members + HENHMETAFILE m_hEMF; + BYTE* m_pBits; + TCHAR* m_pDesc; + ENHMETAHEADER m_header; + PIXELFORMATDESCRIPTOR m_pfd; + +// Constructor/destructor + CEnhMetaFileInfo(HENHMETAFILE hEMF) : m_pBits(NULL), m_pDesc(NULL), m_hEMF(hEMF) + { } + + ~CEnhMetaFileInfo() + { + delete [] m_pBits; + delete [] m_pDesc; + } + +// Operations + BYTE* GetEnhMetaFileBits() + { + ATLASSERT(m_hEMF != NULL); + UINT nBytes = ::GetEnhMetaFileBits(m_hEMF, 0, NULL); + delete [] m_pBits; + m_pBits = NULL; + ATLTRY(m_pBits = new BYTE[nBytes]); + if (m_pBits != NULL) + ::GetEnhMetaFileBits(m_hEMF, nBytes, m_pBits); + return m_pBits; + } + + LPTSTR GetEnhMetaFileDescription() + { + ATLASSERT(m_hEMF != NULL); + UINT nLen = ::GetEnhMetaFileDescription(m_hEMF, 0, NULL); + delete [] m_pDesc; + m_pDesc = NULL; + ATLTRY(m_pDesc = new TCHAR[nLen]); + if (m_pDesc != NULL) + nLen = ::GetEnhMetaFileDescription(m_hEMF, nLen, m_pDesc); + return m_pDesc; + } + + ENHMETAHEADER* GetEnhMetaFileHeader() + { + ATLASSERT(m_hEMF != NULL); + memset(&m_header, 0, sizeof(m_header)); + m_header.iType = EMR_HEADER; + m_header.nSize = sizeof(ENHMETAHEADER); + UINT n = ::GetEnhMetaFileHeader(m_hEMF, sizeof(ENHMETAHEADER), &m_header); + return (n != 0) ? &m_header : NULL; + } + + PIXELFORMATDESCRIPTOR* GetEnhMetaFilePixelFormat() + { + ATLASSERT(m_hEMF != NULL); + memset(&m_pfd, 0, sizeof(m_pfd)); + UINT n = ::GetEnhMetaFilePixelFormat(m_hEMF, sizeof(m_pfd), &m_pfd); + return (n != 0) ? &m_pfd : NULL; + } +}; + + +template +class CEnhMetaFileT +{ +public: +// Data members + HENHMETAFILE m_hEMF; + +// Constructor/destructor + CEnhMetaFileT(HENHMETAFILE hEMF = NULL) : m_hEMF(hEMF) + { + } + + ~CEnhMetaFileT() + { + if(t_bManaged && m_hEMF != NULL) + DeleteObject(); + } + +// Operations + CEnhMetaFileT& operator =(HENHMETAFILE hEMF) + { + Attach(hEMF); + return *this; + } + + void Attach(HENHMETAFILE hEMF) + { + if(t_bManaged && m_hEMF != NULL && m_hEMF != hEMF) + DeleteObject(); + m_hEMF = hEMF; + } + + HENHMETAFILE Detach() + { + HENHMETAFILE hEMF = m_hEMF; + m_hEMF = NULL; + return hEMF; + } + + operator HENHMETAFILE() const { return m_hEMF; } + + bool IsNull() const { return (m_hEMF == NULL); } + + BOOL DeleteObject() + { + ATLASSERT(m_hEMF != NULL); + BOOL bRet = ::DeleteEnhMetaFile(m_hEMF); + m_hEMF = NULL; + return bRet; + } + + UINT GetEnhMetaFileBits(UINT cbBuffer, LPBYTE lpbBuffer) const + { + ATLASSERT(m_hEMF != NULL); + return ::GetEnhMetaFileBits(m_hEMF, cbBuffer, lpbBuffer); + } + + UINT GetEnhMetaFileDescription(UINT cchBuffer, LPTSTR lpszDescription) const + { + ATLASSERT(m_hEMF != NULL); + return ::GetEnhMetaFileDescription(m_hEMF, cchBuffer, lpszDescription); + } + + UINT GetEnhMetaFileHeader(LPENHMETAHEADER lpemh) const + { + ATLASSERT(m_hEMF != NULL); + lpemh->iType = EMR_HEADER; + lpemh->nSize = sizeof(ENHMETAHEADER); + return ::GetEnhMetaFileHeader(m_hEMF, sizeof(ENHMETAHEADER), lpemh); + } + + UINT GetEnhMetaFilePaletteEntries(UINT cEntries, LPPALETTEENTRY lppe) const + { + ATLASSERT(m_hEMF != NULL); + return ::GetEnhMetaFilePaletteEntries(m_hEMF, cEntries, lppe); + } + + UINT GetEnhMetaFilePixelFormat(DWORD cbBuffer, PIXELFORMATDESCRIPTOR* ppfd) const + { + ATLASSERT(m_hEMF != NULL); + return ::GetEnhMetaFilePixelFormat(m_hEMF, cbBuffer, ppfd); + } +}; + +typedef CEnhMetaFileT CEnhMetaFileHandle; +typedef CEnhMetaFileT CEnhMetaFile; + + +class CEnhMetaFileDC : public CDC +{ +public: +// Constructor/destructor + CEnhMetaFileDC() + { + } + + CEnhMetaFileDC(HDC hdc, LPCRECT lpRect) + { + Create(hdc, NULL, lpRect, NULL); + ATLASSERT(m_hDC != NULL); + } + + CEnhMetaFileDC(HDC hdcRef, LPCTSTR lpFilename, LPCRECT lpRect, LPCTSTR lpDescription) + { + Create(hdcRef, lpFilename, lpRect, lpDescription); + ATLASSERT(m_hDC != NULL); + } + + ~CEnhMetaFileDC() + { + HENHMETAFILE hEMF = Close(); + if (hEMF != NULL) + ::DeleteEnhMetaFile(hEMF); + } + +// Operations + void Create(HDC hdcRef, LPCTSTR lpFilename, LPCRECT lpRect, LPCTSTR lpDescription) + { + ATLASSERT(m_hDC == NULL); + m_hDC = ::CreateEnhMetaFile(hdcRef, lpFilename, lpRect, lpDescription); + } + + HENHMETAFILE Close() + { + HENHMETAFILE hEMF = NULL; + if (m_hDC != NULL) + { + hEMF = ::CloseEnhMetaFile(m_hDC); + m_hDC = NULL; + } + return hEMF; + } +}; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// WinCE compatible clipboard CF_DIB format support functions + +#ifndef _WTL_NO_DIB16 + +#define DIBINFO16_BITFIELDS { 31744, 992, 31 } + +// DIBINFO16 - To avoid color table problems in WinCE we only create this type of Dib +struct DIBINFO16 // a BITMAPINFO with 2 additional color bitfields +{ + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[3]; + + DIBINFO16(SIZE size) + { + BITMAPINFOHEADER bmih = { sizeof(BITMAPINFOHEADER), size.cx, size.cy, + 1, 16, BI_BITFIELDS, 2 * size.cx * size.cy , 0, 0, 3 }; + DWORD dw[3] = DIBINFO16_BITFIELDS ; + + bmiHeader = bmih; + SecureHelper::memcpy_x(bmiColors, sizeof(bmiColors), dw, 3 * sizeof(DWORD)); + } +}; + + +// AtlxxxDibxxx minimal packed DIB implementation and helpers to copy and paste CF_DIB + +inline bool AtlIsDib16(LPBITMAPINFOHEADER pbmih) +{ + return (pbmih->biBitCount == 16) && (pbmih->biCompression == BI_BITFIELDS); +} + +inline int AtlGetDibColorTableSize(LPBITMAPINFOHEADER pbmih) +{ + switch (pbmih->biBitCount) + { + case 2: + case 4: + case 8: + return pbmih->biClrUsed ? pbmih->biClrUsed : 1 << pbmih->biBitCount; + case 24: + break; + case 16: + case 32: + return pbmih->biCompression == BI_BITFIELDS ? 3 : 0; + default: + ATLASSERT(FALSE); // should never come here + } + + return 0; +} + +inline int AtlGetDibNumColors(LPBITMAPINFOHEADER pbmih) +{ + switch (pbmih->biBitCount) + { + case 2: + case 4: + case 8: + if (pbmih->biClrUsed) + return pbmih->biClrUsed; + else + break; + case 16: + if (pbmih->biCompression == BI_BITFIELDS ) + return 1 << 15; + else + break; + case 24: + break; + case 32: + if (pbmih->biCompression == BI_BITFIELDS ) + return 1 << 24; + else + break; + default: + ATLASSERT(FALSE); + } + + return 1 << pbmih->biBitCount; +} + +inline HBITMAP AtlGetDibBitmap(LPBITMAPINFO pbmi) +{ + CDC dc(NULL); + void* pBits = NULL; + + LPBYTE pDibBits = (LPBYTE)pbmi + sizeof(BITMAPINFOHEADER) + AtlGetDibColorTableSize(&pbmi->bmiHeader) * sizeof(RGBQUAD); + HBITMAP hbm = CreateDIBSection(dc, pbmi, DIB_RGB_COLORS, &pBits, NULL, NULL); + if (hbm != NULL) + { + int cbBits = pbmi->bmiHeader.biWidth * pbmi->bmiHeader.biHeight * pbmi->bmiHeader.biBitCount / 8; + SecureHelper::memcpy_x(pBits, cbBits, pDibBits, pbmi->bmiHeader.biSizeImage); + } + + return hbm; +} + +inline HBITMAP AtlCopyBitmap(HBITMAP hbm, SIZE sizeDst, bool bAsBitmap = false) +{ + CDC hdcSrc = CreateCompatibleDC(NULL); + CDC hdcDst = CreateCompatibleDC(NULL); + + CBitmapHandle hbmOld = NULL, hbmOld2 = NULL, bmSrc = hbm; + + CBitmap bmNew = NULL; + + SIZE sizeSrc = { 0 }; + bmSrc.GetSize(sizeSrc); + + hbmOld = hdcSrc.SelectBitmap(bmSrc); + + if (bAsBitmap) + { + bmNew.CreateCompatibleBitmap(hdcSrc, sizeDst.cx, sizeDst.cy); + } + else + { + DIBINFO16 dib16(sizeDst); + LPVOID pBits = NULL; + bmNew = CreateDIBSection(hdcDst, (const BITMAPINFO*)&dib16, DIB_RGB_COLORS, &pBits, NULL, NULL); + } + + ATLASSERT(!bmNew.IsNull()); + + hbmOld2 = hdcDst.SelectBitmap(bmNew); + BOOL bOK = FALSE; + + if ((sizeDst.cx == sizeSrc.cx) && (sizeDst.cy == sizeSrc.cy)) + bOK = hdcDst.BitBlt(0, 0, sizeDst.cx, sizeDst.cy, hdcSrc, 0, 0, SRCCOPY); + else + bOK = hdcDst.StretchBlt(0, 0, sizeDst.cx, sizeDst.cy, hdcSrc, 0, 0, sizeSrc.cx, sizeSrc.cy, SRCCOPY); + + hdcSrc.SelectBitmap(hbmOld); + hdcDst.SelectBitmap(hbmOld2); + + if (bOK == FALSE) + bmNew.DeleteObject(); + + return bmNew.Detach(); +} + +inline HLOCAL AtlCreatePackedDib16(HBITMAP hbm, SIZE size) +{ + DIBSECTION ds = { 0 }; + LPBYTE pDib = NULL; + bool bCopied = false; + + bool bOK = GetObject(hbm, sizeof(ds), &ds) == sizeof(ds); + if ((bOK == FALSE) || (ds.dsBm.bmBits == NULL) || (AtlIsDib16(&ds.dsBmih) == FALSE) || + (ds.dsBmih.biWidth != size.cx ) || (ds.dsBmih.biHeight != size.cy )) + { + if ((hbm = AtlCopyBitmap(hbm, size)) != NULL) + { + bCopied = true; + bOK = GetObject(hbm, sizeof(ds), &ds) == sizeof(ds); + } + else + { + bOK = FALSE; + } + } + + if((bOK != FALSE) && (AtlIsDib16(&ds.dsBmih) != FALSE) && (ds.dsBm.bmBits != NULL)) + { + pDib = (LPBYTE)LocalAlloc(LMEM_ZEROINIT, sizeof(DIBINFO16) + ds.dsBmih.biSizeImage); + if (pDib != NULL) + { + SecureHelper::memcpy_x(pDib, sizeof(DIBINFO16) + ds.dsBmih.biSizeImage, &ds.dsBmih, sizeof(DIBINFO16)); + SecureHelper::memcpy_x(pDib + sizeof(DIBINFO16), ds.dsBmih.biSizeImage, ds.dsBm.bmBits, ds.dsBmih.biSizeImage); + } + } + + if (bCopied == true) + DeleteObject(hbm); + + return (HLOCAL)pDib; +} + +inline bool AtlSetClipboardDib16(HBITMAP hbm, SIZE size, HWND hWnd) +{ + ATLASSERT(::IsWindow(hWnd)); + BOOL bOK = OpenClipboard(hWnd); + if (bOK != FALSE) + { + bOK = EmptyClipboard(); + if (bOK != FALSE) + { + HLOCAL hDib = AtlCreatePackedDib16(hbm, size); + if (hDib != NULL) + { + bOK = SetClipboardData(CF_DIB, hDib) != NULL; + if (bOK == FALSE) + LocalFree(hDib); + } + else + { + bOK = FALSE; + } + } + CloseClipboard(); + } + + return (bOK != FALSE); +} + +inline HBITMAP AtlGetClipboardDib(HWND hWnd) +{ + ATLASSERT(::IsWindow(hWnd) != FALSE); + HBITMAP hbm = NULL; + if (OpenClipboard(hWnd) != FALSE) + { + LPBITMAPINFO pbmi = (LPBITMAPINFO)GetClipboardData(CF_DIB); + if (pbmi != NULL) + hbm = AtlGetDibBitmap(pbmi); + CloseClipboard(); + } + + return hbm; +} + +#endif // _WTL_NO_DIB16 + +}; // namespace WTL + +#endif // __ATLGDI_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlmisc.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlmisc.h new file mode 100644 index 0000000000..3519b348fd --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlmisc.h @@ -0,0 +1,3817 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLMISC_H__ +#define __ATLMISC_H__ + +#pragma once + +#ifndef __ATLAPP_H__ + #error atlmisc.h requires atlapp.h to be included first +#endif + + +#ifdef _ATL_TMP_NO_CSTRING + #define _WTL_NO_CSTRING +#endif + +#if defined(_WTL_USE_CSTRING) && defined(_WTL_NO_CSTRING) + #error Conflicting options - both _WTL_USE_CSTRING and _WTL_NO_CSTRING are defined +#endif // defined(_WTL_USE_CSTRING) && defined(_WTL_NO_CSTRING) + +#if !defined(_WTL_USE_CSTRING) && !defined(_WTL_NO_CSTRING) + #define _WTL_USE_CSTRING +#endif // !defined(_WTL_USE_CSTRING) && !defined(_WTL_NO_CSTRING) + +#ifndef _WTL_NO_CSTRING + #if defined(_ATL_USE_CSTRING_FLOAT) && defined(_ATL_MIN_CRT) + #error Cannot use CString floating point formatting with _ATL_MIN_CRT defined + #endif // defined(_ATL_USE_CSTRING_FLOAT) && defined(_ATL_MIN_CRT) +#endif // !_WTL_NO_CSTRING + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CSize +// CPoint +// CRect +// CString +// +// CRecentDocumentListBase +// CRecentDocumentList +// CFindFile +// +// Global functions: +// AtlGetStockPen() +// AtlGetStockBrush() +// AtlGetStockFont() +// AtlGetStockPalette() +// +// AtlCompactPath() + + +namespace WTL +{ + +#ifndef _WTL_NO_WTYPES + +// forward declarations +class CSize; +class CPoint; +class CRect; + +/////////////////////////////////////////////////////////////////////////////// +// CSize - Wrapper for Windows SIZE structure. + +class CSize : public SIZE +{ +public: +// Constructors + CSize() + { + cx = 0; + cy = 0; + } + + CSize(int initCX, int initCY) + { + cx = initCX; + cy = initCY; + } + + CSize(SIZE initSize) + { + *(SIZE*)this = initSize; + } + + CSize(POINT initPt) + { + *(POINT*)this = initPt; + } + + CSize(DWORD dwSize) + { + cx = (short)LOWORD(dwSize); + cy = (short)HIWORD(dwSize); + } + +// Operations + BOOL operator ==(SIZE size) const + { + return (cx == size.cx && cy == size.cy); + } + + BOOL operator !=(SIZE size) const + { + return (cx != size.cx || cy != size.cy); + } + + void operator +=(SIZE size) + { + cx += size.cx; + cy += size.cy; + } + + void operator -=(SIZE size) + { + cx -= size.cx; + cy -= size.cy; + } + + void SetSize(int CX, int CY) + { + cx = CX; + cy = CY; + } + +// Operators returning CSize values + CSize operator +(SIZE size) const + { + return CSize(cx + size.cx, cy + size.cy); + } + + CSize operator -(SIZE size) const + { + return CSize(cx - size.cx, cy - size.cy); + } + + CSize operator -() const + { + return CSize(-cx, -cy); + } + +// Operators returning CPoint values + CPoint operator +(POINT point) const; + CPoint operator -(POINT point) const; + +// Operators returning CRect values + CRect operator +(const RECT* lpRect) const; + CRect operator -(const RECT* lpRect) const; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CPoint - Wrapper for Windows POINT structure. + +class CPoint : public POINT +{ +public: +// Constructors + CPoint() + { + x = 0; + y = 0; + } + + CPoint(int initX, int initY) + { + x = initX; + y = initY; + } + + CPoint(POINT initPt) + { + *(POINT*)this = initPt; + } + + CPoint(SIZE initSize) + { + *(SIZE*)this = initSize; + } + + CPoint(DWORD dwPoint) + { + x = (short)LOWORD(dwPoint); + y = (short)HIWORD(dwPoint); + } + +// Operations + void Offset(int xOffset, int yOffset) + { + x += xOffset; + y += yOffset; + } + + void Offset(POINT point) + { + x += point.x; + y += point.y; + } + + void Offset(SIZE size) + { + x += size.cx; + y += size.cy; + } + + BOOL operator ==(POINT point) const + { + return (x == point.x && y == point.y); + } + + BOOL operator !=(POINT point) const + { + return (x != point.x || y != point.y); + } + + void operator +=(SIZE size) + { + x += size.cx; + y += size.cy; + } + + void operator -=(SIZE size) + { + x -= size.cx; + y -= size.cy; + } + + void operator +=(POINT point) + { + x += point.x; + y += point.y; + } + + void operator -=(POINT point) + { + x -= point.x; + y -= point.y; + } + + void SetPoint(int X, int Y) + { + x = X; + y = Y; + } + +// Operators returning CPoint values + CPoint operator +(SIZE size) const + { + return CPoint(x + size.cx, y + size.cy); + } + + CPoint operator -(SIZE size) const + { + return CPoint(x - size.cx, y - size.cy); + } + + CPoint operator -() const + { + return CPoint(-x, -y); + } + + CPoint operator +(POINT point) const + { + return CPoint(x + point.x, y + point.y); + } + +// Operators returning CSize values + CSize operator -(POINT point) const + { + return CSize(x - point.x, y - point.y); + } + +// Operators returning CRect values + CRect operator +(const RECT* lpRect) const; + CRect operator -(const RECT* lpRect) const; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CRect - Wrapper for Windows RECT structure. + +class CRect : public RECT +{ +public: +// Constructors + CRect() + { + left = 0; + top = 0; + right = 0; + bottom = 0; + } + + CRect(int l, int t, int r, int b) + { + left = l; + top = t; + right = r; + bottom = b; + } + + CRect(const RECT& srcRect) + { + ::CopyRect(this, &srcRect); + } + + CRect(LPCRECT lpSrcRect) + { + ::CopyRect(this, lpSrcRect); + } + + CRect(POINT point, SIZE size) + { + right = (left = point.x) + size.cx; + bottom = (top = point.y) + size.cy; + } + + CRect(POINT topLeft, POINT bottomRight) + { + left = topLeft.x; + top = topLeft.y; + right = bottomRight.x; + bottom = bottomRight.y; + } + +// Attributes (in addition to RECT members) + int Width() const + { + return right - left; + } + + int Height() const + { + return bottom - top; + } + + CSize Size() const + { + return CSize(right - left, bottom - top); + } + + CPoint& TopLeft() + { + return *((CPoint*)this); + } + + CPoint& BottomRight() + { + return *((CPoint*)this + 1); + } + + const CPoint& TopLeft() const + { + return *((CPoint*)this); + } + + const CPoint& BottomRight() const + { + return *((CPoint*)this + 1); + } + + CPoint CenterPoint() const + { + return CPoint((left + right) / 2, (top + bottom) / 2); + } + + // convert between CRect and LPRECT/LPCRECT (no need for &) + operator LPRECT() + { + return this; + } + + operator LPCRECT() const + { + return this; + } + + BOOL IsRectEmpty() const + { + return ::IsRectEmpty(this); + } + + BOOL IsRectNull() const + { + return (left == 0 && right == 0 && top == 0 && bottom == 0); + } + + BOOL PtInRect(POINT point) const + { + return ::PtInRect(this, point); + } + +// Operations + void SetRect(int x1, int y1, int x2, int y2) + { + ::SetRect(this, x1, y1, x2, y2); + } + + void SetRect(POINT topLeft, POINT bottomRight) + { + ::SetRect(this, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y); + } + + void SetRectEmpty() + { + ::SetRectEmpty(this); + } + + void CopyRect(LPCRECT lpSrcRect) + { + ::CopyRect(this, lpSrcRect); + } + + BOOL EqualRect(LPCRECT lpRect) const + { + return ::EqualRect(this, lpRect); + } + + void InflateRect(int x, int y) + { + ::InflateRect(this, x, y); + } + + void InflateRect(SIZE size) + { + ::InflateRect(this, size.cx, size.cy); + } + + void InflateRect(LPCRECT lpRect) + { + left -= lpRect->left; + top -= lpRect->top; + right += lpRect->right; + bottom += lpRect->bottom; + } + + void InflateRect(int l, int t, int r, int b) + { + left -= l; + top -= t; + right += r; + bottom += b; + } + + void DeflateRect(int x, int y) + { + ::InflateRect(this, -x, -y); + } + + void DeflateRect(SIZE size) + { + ::InflateRect(this, -size.cx, -size.cy); + } + + void DeflateRect(LPCRECT lpRect) + { + left += lpRect->left; + top += lpRect->top; + right -= lpRect->right; + bottom -= lpRect->bottom; + } + + void DeflateRect(int l, int t, int r, int b) + { + left += l; + top += t; + right -= r; + bottom -= b; + } + + void OffsetRect(int x, int y) + { + ::OffsetRect(this, x, y); + } + void OffsetRect(SIZE size) + { + ::OffsetRect(this, size.cx, size.cy); + } + + void OffsetRect(POINT point) + { + ::OffsetRect(this, point.x, point.y); + } + + void NormalizeRect() + { + int nTemp; + if (left > right) + { + nTemp = left; + left = right; + right = nTemp; + } + if (top > bottom) + { + nTemp = top; + top = bottom; + bottom = nTemp; + } + } + + // absolute position of rectangle + void MoveToY(int y) + { + bottom = Height() + y; + top = y; + } + + void MoveToX(int x) + { + right = Width() + x; + left = x; + } + + void MoveToXY(int x, int y) + { + MoveToX(x); + MoveToY(y); + } + + void MoveToXY(POINT pt) + { + MoveToX(pt.x); + MoveToY(pt.y); + } + + // operations that fill '*this' with result + BOOL IntersectRect(LPCRECT lpRect1, LPCRECT lpRect2) + { + return ::IntersectRect(this, lpRect1, lpRect2); + } + + BOOL UnionRect(LPCRECT lpRect1, LPCRECT lpRect2) + { + return ::UnionRect(this, lpRect1, lpRect2); + } + + BOOL SubtractRect(LPCRECT lpRectSrc1, LPCRECT lpRectSrc2) + { + return ::SubtractRect(this, lpRectSrc1, lpRectSrc2); + } + +// Additional Operations + void operator =(const RECT& srcRect) + { + ::CopyRect(this, &srcRect); + } + + BOOL operator ==(const RECT& rect) const + { + return ::EqualRect(this, &rect); + } + + BOOL operator !=(const RECT& rect) const + { + return !::EqualRect(this, &rect); + } + + void operator +=(POINT point) + { + ::OffsetRect(this, point.x, point.y); + } + + void operator +=(SIZE size) + { + ::OffsetRect(this, size.cx, size.cy); + } + + void operator +=(LPCRECT lpRect) + { + InflateRect(lpRect); + } + + void operator -=(POINT point) + { + ::OffsetRect(this, -point.x, -point.y); + } + + void operator -=(SIZE size) + { + ::OffsetRect(this, -size.cx, -size.cy); + } + + void operator -=(LPCRECT lpRect) + { + DeflateRect(lpRect); + } + + void operator &=(const RECT& rect) + { + ::IntersectRect(this, this, &rect); + } + + void operator |=(const RECT& rect) + { + ::UnionRect(this, this, &rect); + } + +// Operators returning CRect values + CRect operator +(POINT pt) const + { + CRect rect(*this); + ::OffsetRect(&rect, pt.x, pt.y); + return rect; + } + + CRect operator -(POINT pt) const + { + CRect rect(*this); + ::OffsetRect(&rect, -pt.x, -pt.y); + return rect; + } + + CRect operator +(LPCRECT lpRect) const + { + CRect rect(this); + rect.InflateRect(lpRect); + return rect; + } + + CRect operator +(SIZE size) const + { + CRect rect(*this); + ::OffsetRect(&rect, size.cx, size.cy); + return rect; + } + + CRect operator -(SIZE size) const + { + CRect rect(*this); + ::OffsetRect(&rect, -size.cx, -size.cy); + return rect; + } + + CRect operator -(LPCRECT lpRect) const + { + CRect rect(this); + rect.DeflateRect(lpRect); + return rect; + } + + CRect operator &(const RECT& rect2) const + { + CRect rect; + ::IntersectRect(&rect, this, &rect2); + return rect; + } + + CRect operator |(const RECT& rect2) const + { + CRect rect; + ::UnionRect(&rect, this, &rect2); + return rect; + } + + CRect MulDiv(int nMultiplier, int nDivisor) const + { + return CRect( + ::MulDiv(left, nMultiplier, nDivisor), + ::MulDiv(top, nMultiplier, nDivisor), + ::MulDiv(right, nMultiplier, nDivisor), + ::MulDiv(bottom, nMultiplier, nDivisor)); + } +}; + + +// CSize implementation + +inline CPoint CSize::operator +(POINT point) const +{ return CPoint(cx + point.x, cy + point.y); } + +inline CPoint CSize::operator -(POINT point) const +{ return CPoint(cx - point.x, cy - point.y); } + +inline CRect CSize::operator +(const RECT* lpRect) const +{ return CRect(lpRect) + *this; } + +inline CRect CSize::operator -(const RECT* lpRect) const +{ return CRect(lpRect) - *this; } + + +// CPoint implementation + +inline CRect CPoint::operator +(const RECT* lpRect) const +{ return CRect(lpRect) + *this; } + +inline CRect CPoint::operator -(const RECT* lpRect) const +{ return CRect(lpRect) - *this; } + +#endif // !_WTL_NO_WTYPES + + +// WTL::CSize or ATL::CSize scalar operators + +#if !defined(_WTL_NO_SIZE_SCALAR) && (!defined(_WTL_NO_WTYPES) || defined(__ATLTYPES_H__)) + +template +inline CSize operator *(SIZE s, Num n) +{ + return CSize((int)(s.cx * n), (int)(s.cy * n)); +}; + +template +inline void operator *=(SIZE & s, Num n) +{ + s = s * n; +}; + +template +inline CSize operator /(SIZE s, Num n) +{ + return CSize((int)(s.cx / n), (int)(s.cy / n)); +}; + +template +inline void operator /=(SIZE & s, Num n) +{ + s = s / n; +}; + +#endif // !defined(_WTL_NO_SIZE_SCALAR) && (!defined(_WTL_NO_WTYPES) || defined(__ATLTYPES_H__)) + + +/////////////////////////////////////////////////////////////////////////////// +// CString - String class + +#ifndef _WTL_NO_CSTRING + +struct CStringData +{ + long nRefs; // reference count + int nDataLength; + int nAllocLength; + // TCHAR data[nAllocLength] + + TCHAR* data() + { return (TCHAR*)(this + 1); } +}; + +// Globals + +// For an empty string, m_pchData will point here +// (note: avoids special case of checking for NULL m_pchData) +// empty string data (and locked) +_declspec(selectany) int rgInitData[] = { -1, 0, 0, 0 }; +_declspec(selectany) CStringData* _atltmpDataNil = (CStringData*)&rgInitData; +_declspec(selectany) LPCTSTR _atltmpPchNil = (LPCTSTR)(((BYTE*)&rgInitData) + sizeof(CStringData)); + + +class CString +{ +public: +// Constructors + CString() + { + Init(); + } + + CString(const CString& stringSrc) + { + ATLASSERT(stringSrc.GetData()->nRefs != 0); + if (stringSrc.GetData()->nRefs >= 0) + { + ATLASSERT(stringSrc.GetData() != _atltmpDataNil); + m_pchData = stringSrc.m_pchData; + InterlockedIncrement(&GetData()->nRefs); + } + else + { + Init(); + *this = stringSrc.m_pchData; + } + } + + CString(TCHAR ch, int nRepeat = 1) + { + ATLASSERT(!_istlead(ch)); // can't create a lead byte string + Init(); + if (nRepeat >= 1) + { + if(AllocBuffer(nRepeat)) + { +#ifdef _UNICODE + for (int i = 0; i < nRepeat; i++) + m_pchData[i] = ch; +#else + memset(m_pchData, ch, nRepeat); +#endif + } + } + } + + CString(LPCTSTR lpsz) + { + Init(); + if (lpsz != NULL && HIWORD(lpsz) == NULL) + { + UINT nID = LOWORD((DWORD_PTR)lpsz); + if (!LoadString(nID)) + ATLTRACE2(atlTraceUI, 0, _T("Warning: implicit LoadString(%u) in CString failed\n"), nID); + } + else + { + int nLen = SafeStrlen(lpsz); + if (nLen != 0) + { + if(AllocBuffer(nLen)) + SecureHelper::memcpy_x(m_pchData, (nLen + 1) * sizeof(TCHAR), lpsz, nLen * sizeof(TCHAR)); + } + } + } + +#ifdef _UNICODE + CString(LPCSTR lpsz) + { + Init(); +#if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) + int nSrcLen = (lpsz != NULL) ? ATL::lstrlenA(lpsz) : 0; +#else + int nSrcLen = (lpsz != NULL) ? lstrlenA(lpsz) : 0; +#endif + if (nSrcLen != 0) + { + if(AllocBuffer(nSrcLen)) + { + _mbstowcsz(m_pchData, lpsz, nSrcLen + 1); + ReleaseBuffer(); + } + } + } +#else // !_UNICODE + CString(LPCWSTR lpsz) + { + Init(); + int nSrcLen = (lpsz != NULL) ? (int)wcslen(lpsz) : 0; + if (nSrcLen != 0) + { + if(AllocBuffer(nSrcLen * 2)) + { + _wcstombsz(m_pchData, lpsz, (nSrcLen * 2) + 1); + ReleaseBuffer(); + } + } + } +#endif // !_UNICODE + + CString(LPCTSTR lpch, int nLength) + { + Init(); + if (nLength != 0) + { + if(AllocBuffer(nLength)) + SecureHelper::memcpy_x(m_pchData, (nLength + 1) * sizeof(TCHAR), lpch, nLength * sizeof(TCHAR)); + } + } + +#ifdef _UNICODE + CString(LPCSTR lpsz, int nLength) + { + Init(); + if (nLength != 0) + { + if(AllocBuffer(nLength)) + { + int n = ::MultiByteToWideChar(CP_ACP, 0, lpsz, nLength, m_pchData, nLength + 1); + ReleaseBuffer((n >= 0) ? n : -1); + } + } + } +#else // !_UNICODE + CString(LPCWSTR lpsz, int nLength) + { + Init(); + if (nLength != 0) + { + if(((nLength * 2) > nLength) && AllocBuffer(nLength * 2)) + { + int n = ::WideCharToMultiByte(CP_ACP, 0, lpsz, nLength, m_pchData, (nLength * 2) + 1, NULL, NULL); + ReleaseBuffer((n >= 0) ? n : -1); + } + } + } +#endif // !_UNICODE + + CString(const unsigned char* lpsz) + { + Init(); + *this = (LPCSTR)lpsz; + } + +// Attributes & Operations + int GetLength() const // as an array of characters + { + return GetData()->nDataLength; + } + + BOOL IsEmpty() const + { + return GetData()->nDataLength == 0; + } + + void Empty() // free up the data + { + if (GetData()->nDataLength == 0) + return; + + if (GetData()->nRefs >= 0) + Release(); + else + *this = _T(""); + + ATLASSERT(GetData()->nDataLength == 0); + ATLASSERT(GetData()->nRefs < 0 || GetData()->nAllocLength == 0); + } + + TCHAR GetAt(int nIndex) const // 0 based + { + ATLASSERT(nIndex >= 0); + ATLASSERT(nIndex < GetData()->nDataLength); + return m_pchData[nIndex]; + } + + TCHAR operator [](int nIndex) const // same as GetAt + { + // same as GetAt + ATLASSERT(nIndex >= 0); + ATLASSERT(nIndex < GetData()->nDataLength); + return m_pchData[nIndex]; + } + + void SetAt(int nIndex, TCHAR ch) + { + ATLASSERT(nIndex >= 0); + ATLASSERT(nIndex < GetData()->nDataLength); + + CopyBeforeWrite(); + m_pchData[nIndex] = ch; + } + + operator LPCTSTR() const // as a C string + { + return m_pchData; + } + + // overloaded assignment + CString& operator =(const CString& stringSrc) + { + if (m_pchData != stringSrc.m_pchData) + { + if ((GetData()->nRefs < 0 && GetData() != _atltmpDataNil) || stringSrc.GetData()->nRefs < 0) + { + // actual copy necessary since one of the strings is locked + AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData); + } + else + { + // can just copy references around + Release(); + ATLASSERT(stringSrc.GetData() != _atltmpDataNil); + m_pchData = stringSrc.m_pchData; + InterlockedIncrement(&GetData()->nRefs); + } + } + return *this; + } + + CString& operator =(TCHAR ch) + { + ATLASSERT(!_istlead(ch)); // can't set single lead byte + AssignCopy(1, &ch); + return *this; + } + +#ifdef _UNICODE + CString& operator =(char ch) + { + *this = (TCHAR)ch; + return *this; + } +#endif + + CString& operator =(LPCTSTR lpsz) + { + ATLASSERT(lpsz == NULL || _IsValidString(lpsz)); + AssignCopy(SafeStrlen(lpsz), lpsz); + return *this; + } + +#ifdef _UNICODE + CString& operator =(LPCSTR lpsz) + { +#if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) + int nSrcLen = (lpsz != NULL) ? ATL::lstrlenA(lpsz) : 0; +#else + int nSrcLen = (lpsz != NULL) ? lstrlenA(lpsz) : 0; +#endif + if(AllocBeforeWrite(nSrcLen)) + { + _mbstowcsz(m_pchData, lpsz, nSrcLen + 1); + ReleaseBuffer(); + } + return *this; + } +#else // !_UNICODE + CString& operator =(LPCWSTR lpsz) + { + int nSrcLen = (lpsz != NULL) ? (int)wcslen(lpsz) : 0; + if(AllocBeforeWrite(nSrcLen * 2)) + { + _wcstombsz(m_pchData, lpsz, (nSrcLen * 2) + 1); + ReleaseBuffer(); + } + return *this; + } +#endif // !_UNICODE + + CString& operator =(const unsigned char* lpsz) + { + *this = (LPCSTR)lpsz; + return *this; + } + + // string concatenation + CString& operator +=(const CString& string) + { + ConcatInPlace(string.GetData()->nDataLength, string.m_pchData); + return *this; + } + + CString& operator +=(TCHAR ch) + { + ConcatInPlace(1, &ch); + return *this; + } + +#ifdef _UNICODE + CString& operator +=(char ch) + { + *this += (TCHAR)ch; + return *this; + } +#endif + + CString& operator +=(LPCTSTR lpsz) + { + ATLASSERT(lpsz == NULL || _IsValidString(lpsz)); + ConcatInPlace(SafeStrlen(lpsz), lpsz); + return *this; + } + + friend CString __stdcall operator +(const CString& string1, const CString& string2); + friend CString __stdcall operator +(const CString& string, TCHAR ch); + friend CString __stdcall operator +(TCHAR ch, const CString& string); +#ifdef _UNICODE + friend CString __stdcall operator +(const CString& string, char ch); + friend CString __stdcall operator +(char ch, const CString& string); +#endif + friend CString __stdcall operator +(const CString& string, LPCTSTR lpsz); + friend CString __stdcall operator +(LPCTSTR lpsz, const CString& string); + + // string comparison + int Compare(LPCTSTR lpsz) const // straight character (MBCS/Unicode aware) + { + return _cstrcmp(m_pchData, lpsz); + } + + int CompareNoCase(LPCTSTR lpsz) const // ignore case (MBCS/Unicode aware) + { + return _cstrcmpi(m_pchData, lpsz); + } + +#ifndef _WIN32_WCE + // CString::Collate is often slower than Compare but is MBSC/Unicode + // aware as well as locale-sensitive with respect to sort order. + int Collate(LPCTSTR lpsz) const // NLS aware + { + return _cstrcoll(m_pchData, lpsz); + } + + int CollateNoCase(LPCTSTR lpsz) const // ignore case + { + return _cstrcolli(m_pchData, lpsz); + } +#endif // !_WIN32_WCE + + // simple sub-string extraction + CString Mid(int nFirst, int nCount) const + { + // out-of-bounds requests return sensible things + if (nFirst < 0) + nFirst = 0; + if (nCount < 0) + nCount = 0; + + if (nFirst + nCount > GetData()->nDataLength) + nCount = GetData()->nDataLength - nFirst; + if (nFirst > GetData()->nDataLength) + nCount = 0; + + CString dest; + AllocCopy(dest, nCount, nFirst, 0); + return dest; + } + + CString Mid(int nFirst) const + { + return Mid(nFirst, GetData()->nDataLength - nFirst); + } + + CString Left(int nCount) const + { + if (nCount < 0) + nCount = 0; + else if (nCount > GetData()->nDataLength) + nCount = GetData()->nDataLength; + + CString dest; + AllocCopy(dest, nCount, 0, 0); + return dest; + } + + CString Right(int nCount) const + { + if (nCount < 0) + nCount = 0; + else if (nCount > GetData()->nDataLength) + nCount = GetData()->nDataLength; + + CString dest; + AllocCopy(dest, nCount, GetData()->nDataLength-nCount, 0); + return dest; + } + + CString SpanIncluding(LPCTSTR lpszCharSet) const // strspn equivalent + { + ATLASSERT(_IsValidString(lpszCharSet)); + return Left(_cstrspn(m_pchData, lpszCharSet)); + } + + CString SpanExcluding(LPCTSTR lpszCharSet) const // strcspn equivalent + { + ATLASSERT(_IsValidString(lpszCharSet)); + return Left(_cstrcspn(m_pchData, lpszCharSet)); + } + + // upper/lower/reverse conversion + void MakeUpper() + { + CopyBeforeWrite(); + CharUpper(m_pchData); + } + + void MakeLower() + { + CopyBeforeWrite(); + CharLower(m_pchData); + } + + void MakeReverse() + { + CopyBeforeWrite(); + _cstrrev(m_pchData); + } + + // trimming whitespace (either side) + void TrimRight() + { + CopyBeforeWrite(); + + // find beginning of trailing spaces by starting at beginning (DBCS aware) + LPTSTR lpsz = m_pchData; + LPTSTR lpszLast = NULL; + while (*lpsz != _T('\0')) + { + if (_cstrisspace(*lpsz)) + { + if (lpszLast == NULL) + lpszLast = lpsz; + } + else + { + lpszLast = NULL; + } + lpsz = ::CharNext(lpsz); + } + + if (lpszLast != NULL) + { + // truncate at trailing space start + *lpszLast = _T('\0'); + GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData); + } + } + + void TrimLeft() + { + CopyBeforeWrite(); + + // find first non-space character + LPCTSTR lpsz = m_pchData; + while (_cstrisspace(*lpsz)) + lpsz = ::CharNext(lpsz); + + // fix up data and length + int nDataLength = GetData()->nDataLength - (int)(DWORD_PTR)(lpsz - m_pchData); + SecureHelper::memmove_x(m_pchData, (GetData()->nAllocLength + 1) * sizeof(TCHAR), lpsz, (nDataLength + 1) * sizeof(TCHAR)); + GetData()->nDataLength = nDataLength; + } + + // remove continuous occurrences of chTarget starting from right + void TrimRight(TCHAR chTarget) + { + // find beginning of trailing matches + // by starting at beginning (DBCS aware) + + CopyBeforeWrite(); + LPTSTR lpsz = m_pchData; + LPTSTR lpszLast = NULL; + + while (*lpsz != _T('\0')) + { + if (*lpsz == chTarget) + { + if (lpszLast == NULL) + lpszLast = lpsz; + } + else + lpszLast = NULL; + lpsz = ::CharNext(lpsz); + } + + if (lpszLast != NULL) + { + // truncate at left-most matching character + *lpszLast = _T('\0'); + GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData); + } + } + + // remove continuous occcurrences of characters in passed string, starting from right + void TrimRight(LPCTSTR lpszTargetList) + { + // find beginning of trailing matches by starting at beginning (DBCS aware) + + CopyBeforeWrite(); + LPTSTR lpsz = m_pchData; + LPTSTR lpszLast = NULL; + + while (*lpsz != _T('\0')) + { + TCHAR* pNext = ::CharNext(lpsz); + if(pNext > lpsz + 1) + { + if (_cstrchr_db(lpszTargetList, *lpsz, *(lpsz + 1)) != NULL) + { + if (lpszLast == NULL) + lpszLast = lpsz; + } + else + { + lpszLast = NULL; + } + } + else + { + if (_cstrchr(lpszTargetList, *lpsz) != NULL) + { + if (lpszLast == NULL) + lpszLast = lpsz; + } + else + { + lpszLast = NULL; + } + } + + lpsz = pNext; + } + + if (lpszLast != NULL) + { + // truncate at left-most matching character + *lpszLast = _T('\0'); + GetData()->nDataLength = (int)(DWORD_PTR)(lpszLast - m_pchData); + } + } + + // remove continuous occurrences of chTarget starting from left + void TrimLeft(TCHAR chTarget) + { + // find first non-matching character + + CopyBeforeWrite(); + LPCTSTR lpsz = m_pchData; + + while (chTarget == *lpsz) + lpsz = ::CharNext(lpsz); + + if (lpsz != m_pchData) + { + // fix up data and length + int nDataLength = GetData()->nDataLength - (int)(DWORD_PTR)(lpsz - m_pchData); + SecureHelper::memmove_x(m_pchData, (GetData()->nAllocLength + 1) * sizeof(TCHAR), lpsz, (nDataLength + 1) * sizeof(TCHAR)); + GetData()->nDataLength = nDataLength; + } + } + + // remove continuous occcurrences of characters in passed string, starting from left + void TrimLeft(LPCTSTR lpszTargets) + { + // if we're not trimming anything, we're not doing any work + if (SafeStrlen(lpszTargets) == 0) + return; + + CopyBeforeWrite(); + LPCTSTR lpsz = m_pchData; + + while (*lpsz != _T('\0')) + { + TCHAR* pNext = ::CharNext(lpsz); + if(pNext > lpsz + 1) + { + if (_cstrchr_db(lpszTargets, *lpsz, *(lpsz + 1)) == NULL) + break; + } + else + { + if (_cstrchr(lpszTargets, *lpsz) == NULL) + break; + } + lpsz = pNext; + } + + if (lpsz != m_pchData) + { + // fix up data and length + int nDataLength = GetData()->nDataLength - (int)(DWORD_PTR)(lpsz - m_pchData); + SecureHelper::memmove_x(m_pchData, (GetData()->nAllocLength + 1) * sizeof(TCHAR), lpsz, (nDataLength + 1) * sizeof(TCHAR)); + GetData()->nDataLength = nDataLength; + } + } + + // advanced manipulation + // replace occurrences of chOld with chNew + int Replace(TCHAR chOld, TCHAR chNew) + { + int nCount = 0; + + // short-circuit the nop case + if (chOld != chNew) + { + // otherwise modify each character that matches in the string + CopyBeforeWrite(); + LPTSTR psz = m_pchData; + LPTSTR pszEnd = psz + GetData()->nDataLength; + while (psz < pszEnd) + { + // replace instances of the specified character only + if (*psz == chOld) + { + *psz = chNew; + nCount++; + } + psz = ::CharNext(psz); + } + } + return nCount; + } + + // replace occurrences of substring lpszOld with lpszNew; + // empty lpszNew removes instances of lpszOld + int Replace(LPCTSTR lpszOld, LPCTSTR lpszNew) + { + // can't have empty or NULL lpszOld + + int nSourceLen = SafeStrlen(lpszOld); + if (nSourceLen == 0) + return 0; + int nReplacementLen = SafeStrlen(lpszNew); + + // loop once to figure out the size of the result string + int nCount = 0; + LPTSTR lpszStart = m_pchData; + LPTSTR lpszEnd = m_pchData + GetData()->nDataLength; + LPTSTR lpszTarget = NULL; + while (lpszStart < lpszEnd) + { + while ((lpszTarget = (TCHAR*)_cstrstr(lpszStart, lpszOld)) != NULL) + { + nCount++; + lpszStart = lpszTarget + nSourceLen; + } + lpszStart += lstrlen(lpszStart) + 1; + } + + // if any changes were made, make them + if (nCount > 0) + { + CopyBeforeWrite(); + + // if the buffer is too small, just allocate a new buffer (slow but sure) + int nOldLength = GetData()->nDataLength; + int nNewLength = nOldLength + (nReplacementLen - nSourceLen) * nCount; + if (GetData()->nAllocLength < nNewLength || GetData()->nRefs > 1) + { + CStringData* pOldData = GetData(); + LPTSTR pstr = m_pchData; + if(!AllocBuffer(nNewLength)) + return -1; + SecureHelper::memcpy_x(m_pchData, (nNewLength + 1) * sizeof(TCHAR), pstr, pOldData->nDataLength * sizeof(TCHAR)); + CString::Release(pOldData); + } + // else, we just do it in-place + lpszStart = m_pchData; + lpszEnd = m_pchData + GetData()->nDataLength; + + // loop again to actually do the work + while (lpszStart < lpszEnd) + { + while ((lpszTarget = (TCHAR*)_cstrstr(lpszStart, lpszOld)) != NULL) + { + int nBalance = nOldLength - ((int)(DWORD_PTR)(lpszTarget - m_pchData) + nSourceLen); + int cchBuffLen = GetData()->nAllocLength - (int)(DWORD_PTR)(lpszTarget - m_pchData); + SecureHelper::memmove_x(lpszTarget + nReplacementLen, (cchBuffLen - nReplacementLen + 1) * sizeof(TCHAR), lpszTarget + nSourceLen, nBalance * sizeof(TCHAR)); + SecureHelper::memcpy_x(lpszTarget, (cchBuffLen + 1) * sizeof(TCHAR), lpszNew, nReplacementLen * sizeof(TCHAR)); + lpszStart = lpszTarget + nReplacementLen; + lpszStart[nBalance] = _T('\0'); + nOldLength += (nReplacementLen - nSourceLen); + } + lpszStart += lstrlen(lpszStart) + 1; + } + ATLASSERT(m_pchData[nNewLength] == _T('\0')); + GetData()->nDataLength = nNewLength; + } + + return nCount; + } + + // remove occurrences of chRemove + int Remove(TCHAR chRemove) + { + CopyBeforeWrite(); + + LPTSTR pstrSource = m_pchData; + LPTSTR pstrDest = m_pchData; + LPTSTR pstrEnd = m_pchData + GetData()->nDataLength; + + while (pstrSource < pstrEnd) + { + if (*pstrSource != chRemove) + { + *pstrDest = *pstrSource; + pstrDest = ::CharNext(pstrDest); + } + pstrSource = ::CharNext(pstrSource); + } + *pstrDest = _T('\0'); + int nCount = (int)(DWORD_PTR)(pstrSource - pstrDest); + GetData()->nDataLength -= nCount; + + return nCount; + } + + // insert character at zero-based index; concatenates if index is past end of string + int Insert(int nIndex, TCHAR ch) + { + CopyBeforeWrite(); + + if (nIndex < 0) + nIndex = 0; + + int nNewLength = GetData()->nDataLength; + if (nIndex > nNewLength) + nIndex = nNewLength; + nNewLength++; + + if (GetData()->nAllocLength < nNewLength) + { + CStringData* pOldData = GetData(); + LPTSTR pstr = m_pchData; + if(!AllocBuffer(nNewLength)) + return -1; + SecureHelper::memcpy_x(m_pchData, (nNewLength + 1) * sizeof(TCHAR), pstr, (pOldData->nDataLength + 1) * sizeof(TCHAR)); + CString::Release(pOldData); + } + + // move existing bytes down + SecureHelper::memmove_x(m_pchData + nIndex + 1, (GetData()->nAllocLength - nIndex) * sizeof(TCHAR), m_pchData + nIndex, (nNewLength - nIndex) * sizeof(TCHAR)); + m_pchData[nIndex] = ch; + GetData()->nDataLength = nNewLength; + + return nNewLength; + } + + // insert substring at zero-based index; concatenates if index is past end of string + int Insert(int nIndex, LPCTSTR pstr) + { + if (nIndex < 0) + nIndex = 0; + + int nInsertLength = SafeStrlen(pstr); + int nNewLength = GetData()->nDataLength; + if (nInsertLength > 0) + { + CopyBeforeWrite(); + if (nIndex > nNewLength) + nIndex = nNewLength; + nNewLength += nInsertLength; + + if (GetData()->nAllocLength < nNewLength) + { + CStringData* pOldData = GetData(); + LPTSTR pstr = m_pchData; + if(!AllocBuffer(nNewLength)) + return -1; + SecureHelper::memcpy_x(m_pchData, (nNewLength + 1) * sizeof(TCHAR), pstr, (pOldData->nDataLength + 1) * sizeof(TCHAR)); + CString::Release(pOldData); + } + + // move existing bytes down + SecureHelper::memmove_x(m_pchData + nIndex + nInsertLength, (GetData()->nAllocLength + 1 - nIndex - nInsertLength) * sizeof(TCHAR), m_pchData + nIndex, (nNewLength - nIndex - nInsertLength + 1) * sizeof(TCHAR)); + SecureHelper::memcpy_x(m_pchData + nIndex, (GetData()->nAllocLength + 1 - nIndex) * sizeof(TCHAR), pstr, nInsertLength * sizeof(TCHAR)); + GetData()->nDataLength = nNewLength; + } + + return nNewLength; + } + + // delete nCount characters starting at zero-based index + int Delete(int nIndex, int nCount = 1) + { + if (nIndex < 0) + nIndex = 0; + int nLength = GetData()->nDataLength; + if (nCount > 0 && nIndex < nLength) + { + if((nIndex + nCount) > nLength) + nCount = nLength - nIndex; + CopyBeforeWrite(); + int nBytesToCopy = nLength - (nIndex + nCount) + 1; + + SecureHelper::memmove_x(m_pchData + nIndex, (GetData()->nAllocLength + 1 - nIndex) * sizeof(TCHAR), m_pchData + nIndex + nCount, nBytesToCopy * sizeof(TCHAR)); + nLength -= nCount; + GetData()->nDataLength = nLength; + } + + return nLength; + } + + // searching (return starting index, or -1 if not found) + // look for a single character match + int Find(TCHAR ch) const // like "C" strchr + { + return Find(ch, 0); + } + + int ReverseFind(TCHAR ch) const + { + // find last single character + LPCTSTR lpsz = _cstrrchr(m_pchData, (_TUCHAR)ch); + + // return -1 if not found, distance from beginning otherwise + return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData); + } + + int Find(TCHAR ch, int nStart) const // starting at index + { + int nLength = GetData()->nDataLength; + if (nStart < 0 || nStart >= nLength) + return -1; + + // find first single character + LPCTSTR lpsz = _cstrchr(m_pchData + nStart, (_TUCHAR)ch); + + // return -1 if not found and index otherwise + return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData); + } + + int FindOneOf(LPCTSTR lpszCharSet) const + { + ATLASSERT(_IsValidString(lpszCharSet)); + LPCTSTR lpsz = _cstrpbrk(m_pchData, lpszCharSet); + return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData); + } + + // look for a specific sub-string + // find a sub-string (like strstr) + int Find(LPCTSTR lpszSub) const // like "C" strstr + { + return Find(lpszSub, 0); + } + + int Find(LPCTSTR lpszSub, int nStart) const // starting at index + { + ATLASSERT(_IsValidString(lpszSub)); + + int nLength = GetData()->nDataLength; + if (nStart < 0 || nStart > nLength) + return -1; + + // find first matching substring + LPCTSTR lpsz = _cstrstr(m_pchData + nStart, lpszSub); + + // return -1 for not found, distance from beginning otherwise + return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData); + } + + // Concatentation for non strings + CString& Append(int n) + { + const int cchBuff = 12; + TCHAR szBuffer[cchBuff] = { 0 }; + SecureHelper::wsprintf_x(szBuffer, cchBuff, _T("%d"), n); + ConcatInPlace(SafeStrlen(szBuffer), szBuffer); + return *this; + } + + // simple formatting + // formatting (using wsprintf style formatting) + BOOL __cdecl Format(LPCTSTR lpszFormat, ...) + { + ATLASSERT(_IsValidString(lpszFormat)); + + va_list argList; + va_start(argList, lpszFormat); + BOOL bRet = FormatV(lpszFormat, argList); + va_end(argList); + return bRet; + } + + BOOL __cdecl Format(UINT nFormatID, ...) + { + CString strFormat; + BOOL bRet = strFormat.LoadString(nFormatID); + ATLASSERT(bRet != 0); + + va_list argList; + va_start(argList, nFormatID); + bRet = FormatV(strFormat, argList); + va_end(argList); + return bRet; + } + + BOOL FormatV(LPCTSTR lpszFormat, va_list argList) + { + ATLASSERT(_IsValidString(lpszFormat)); + + enum _FormatModifiers + { + FORCE_ANSI = 0x10000, + FORCE_UNICODE = 0x20000, + FORCE_INT64 = 0x40000 + }; + + va_list argListSave = argList; + + // make a guess at the maximum length of the resulting string + int nMaxLen = 0; + for (LPCTSTR lpsz = lpszFormat; *lpsz != _T('\0'); lpsz = ::CharNext(lpsz)) + { + // handle '%' character, but watch out for '%%' + if (*lpsz != _T('%') || *(lpsz = ::CharNext(lpsz)) == _T('%')) + { + nMaxLen += (int)(::CharNext(lpsz) - lpsz); + continue; + } + + int nItemLen = 0; + + // handle '%' character with format + int nWidth = 0; + for (; *lpsz != _T('\0'); lpsz = ::CharNext(lpsz)) + { + // check for valid flags + if (*lpsz == _T('#')) + nMaxLen += 2; // for '0x' + else if (*lpsz == _T('*')) + nWidth = va_arg(argList, int); + else if (*lpsz == _T('-') || *lpsz == _T('+') || *lpsz == _T('0') || *lpsz == _T(' ')) + ; + else // hit non-flag character + break; + } + // get width and skip it + if (nWidth == 0) + { + // width indicated by + nWidth = _cstrtoi(lpsz); + for (; *lpsz != _T('\0') && _cstrisdigit(*lpsz); lpsz = ::CharNext(lpsz)) + ; + } + ATLASSERT(nWidth >= 0); + + int nPrecision = 0; + if (*lpsz == _T('.')) + { + // skip past '.' separator (width.precision) + lpsz = ::CharNext(lpsz); + + // get precision and skip it + if (*lpsz == _T('*')) + { + nPrecision = va_arg(argList, int); + lpsz = ::CharNext(lpsz); + } + else + { + nPrecision = _cstrtoi(lpsz); + for (; *lpsz != _T('\0') && _cstrisdigit(*lpsz); lpsz = ::CharNext(lpsz)) + ; + } + ATLASSERT(nPrecision >= 0); + } + + // should be on type modifier or specifier + int nModifier = 0; + if(lpsz[0] == _T('I') && lpsz[1] == _T('6') && lpsz[2] == _T('4')) + { + lpsz += 3; + nModifier = FORCE_INT64; + } + else + { + switch (*lpsz) + { + // modifiers that affect size + case _T('h'): + nModifier = FORCE_ANSI; + lpsz = ::CharNext(lpsz); + break; + case _T('l'): + nModifier = FORCE_UNICODE; + lpsz = ::CharNext(lpsz); + break; + + // modifiers that do not affect size + case _T('F'): + case _T('N'): + case _T('L'): + lpsz = ::CharNext(lpsz); + break; + } + } + + // now should be on specifier + switch (*lpsz | nModifier) + { + // single characters + case _T('c'): + case _T('C'): + nItemLen = 2; + va_arg(argList, TCHAR); + break; + case _T('c') | FORCE_ANSI: + case _T('C') | FORCE_ANSI: + nItemLen = 2; + va_arg(argList, char); + break; + case _T('c') | FORCE_UNICODE: + case _T('C') | FORCE_UNICODE: + nItemLen = 2; + va_arg(argList, WCHAR); + break; + + // strings + case _T('s'): + { + LPCTSTR pstrNextArg = va_arg(argList, LPCTSTR); + if (pstrNextArg == NULL) + { + nItemLen = 6; // "(null)" + } + else + { + nItemLen = lstrlen(pstrNextArg); + nItemLen = max(1, nItemLen); + } + break; + } + + case _T('S'): + { +#ifndef _UNICODE + LPWSTR pstrNextArg = va_arg(argList, LPWSTR); + if (pstrNextArg == NULL) + { + nItemLen = 6; // "(null)" + } + else + { + nItemLen = (int)wcslen(pstrNextArg); + nItemLen = max(1, nItemLen); + } +#else // _UNICODE + LPCSTR pstrNextArg = va_arg(argList, LPCSTR); + if (pstrNextArg == NULL) + { + nItemLen = 6; // "(null)" + } + else + { +#if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) + nItemLen = ATL::lstrlenA(pstrNextArg); +#else + nItemLen = lstrlenA(pstrNextArg); +#endif + nItemLen = max(1, nItemLen); + } +#endif // _UNICODE + break; + } + + case _T('s') | FORCE_ANSI: + case _T('S') | FORCE_ANSI: + { + LPCSTR pstrNextArg = va_arg(argList, LPCSTR); + if (pstrNextArg == NULL) + { + nItemLen = 6; // "(null)" + } + else + { +#if defined(_WIN32_WCE) && (_ATL_VER >= 0x0800) + nItemLen = ATL::lstrlenA(pstrNextArg); +#else + nItemLen = lstrlenA(pstrNextArg); +#endif + nItemLen = max(1, nItemLen); + } + break; + } + + case _T('s') | FORCE_UNICODE: + case _T('S') | FORCE_UNICODE: + { + LPWSTR pstrNextArg = va_arg(argList, LPWSTR); + if (pstrNextArg == NULL) + { + nItemLen = 6; // "(null)" + } + else + { + nItemLen = (int)wcslen(pstrNextArg); + nItemLen = max(1, nItemLen); + } + break; + } + } + + // adjust nItemLen for strings + if (nItemLen != 0) + { + nItemLen = max(nItemLen, nWidth); + if (nPrecision != 0) + nItemLen = min(nItemLen, nPrecision); + } + else + { + switch (*lpsz) + { + // integers + case _T('d'): + case _T('i'): + case _T('u'): + case _T('x'): + case _T('X'): + case _T('o'): + if (nModifier & FORCE_INT64) + va_arg(argList, __int64); + else + va_arg(argList, int); + nItemLen = 32; + nItemLen = max(nItemLen, nWidth + nPrecision); + break; + +#ifndef _ATL_USE_CSTRING_FLOAT + case _T('e'): + case _T('E'): + case _T('f'): + case _T('g'): + case _T('G'): + ATLASSERT(!"Floating point (%%e, %%E, %%f, %%g, and %%G) is not supported by the WTL::CString class."); +#ifndef _DEBUG + ::OutputDebugString(_T("Floating point (%%e, %%f, %%g, and %%G) is not supported by the WTL::CString class.")); +#ifndef _WIN32_WCE + ::DebugBreak(); +#else // CE specific + DebugBreak(); +#endif // _WIN32_WCE +#endif // !_DEBUG + break; +#else // _ATL_USE_CSTRING_FLOAT + case _T('e'): + case _T('E'): + case _T('g'): + case _T('G'): + va_arg(argList, double); + nItemLen = 128; + nItemLen = max(nItemLen, nWidth + nPrecision); + break; + case _T('f'): + { + double f = va_arg(argList, double); + // 312 == strlen("-1+(309 zeroes).") + // 309 zeroes == max precision of a double + // 6 == adjustment in case precision is not specified, + // which means that the precision defaults to 6 + int cchLen = max(nWidth, 312 + nPrecision + 6); + CTempBuffer buff; + LPTSTR pszTemp = buff.Allocate(cchLen); + if(pszTemp != NULL) + { + SecureHelper::sprintf_x(pszTemp, cchLen, _T("%*.*f"), nWidth, nPrecision + 6, f); + nItemLen = (int)_tcslen(pszTemp); + } + else + { + nItemLen = cchLen; + } + } + break; +#endif // _ATL_USE_CSTRING_FLOAT + + case _T('p'): + va_arg(argList, void*); + nItemLen = 32; + nItemLen = max(nItemLen, nWidth + nPrecision); + break; + + // no output + case _T('n'): + va_arg(argList, int*); + break; + + default: + ATLASSERT(FALSE); // unknown formatting option + } + } + + // adjust nMaxLen for output nItemLen + nMaxLen += nItemLen; + } + + if(GetBuffer(nMaxLen) == NULL) + return FALSE; +#ifndef _ATL_USE_CSTRING_FLOAT + int nRet = SecureHelper::wvsprintf_x(m_pchData, GetAllocLength() + 1, lpszFormat, argListSave); +#else // _ATL_USE_CSTRING_FLOAT + int nRet = SecureHelper::vsprintf_x(m_pchData, GetAllocLength() + 1, lpszFormat, argListSave); +#endif // _ATL_USE_CSTRING_FLOAT + nRet; // ref + ATLASSERT(nRet <= GetAllocLength()); + ReleaseBuffer(); + + va_end(argListSave); + return TRUE; + } + + // formatting for localization (uses FormatMessage API) + // formatting (using FormatMessage style formatting) + BOOL __cdecl FormatMessage(LPCTSTR lpszFormat, ...) + { + // format message into temporary buffer lpszTemp + va_list argList; + va_start(argList, lpszFormat); + LPTSTR lpszTemp; + BOOL bRet = TRUE; + + if (::FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, + lpszFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0 || lpszTemp == NULL) + bRet = FALSE; + + // assign lpszTemp into the resulting string and free the temporary + *this = lpszTemp; + LocalFree(lpszTemp); + va_end(argList); + return bRet; + } + + BOOL __cdecl FormatMessage(UINT nFormatID, ...) + { + // get format string from string table + CString strFormat; + BOOL bRetTmp = strFormat.LoadString(nFormatID); + bRetTmp; // ref + ATLASSERT(bRetTmp != 0); + + // format message into temporary buffer lpszTemp + va_list argList; + va_start(argList, nFormatID); + LPTSTR lpszTemp; + BOOL bRet = TRUE; + + if (::FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, + strFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0 || lpszTemp == NULL) + bRet = FALSE; + + // assign lpszTemp into the resulting string and free lpszTemp + *this = lpszTemp; + LocalFree(lpszTemp); + va_end(argList); + return bRet; + } + + // Windows support + BOOL LoadString(UINT nID) // load from string resource (255 chars max.) + { +#ifdef _UNICODE + const int CHAR_FUDGE = 1; // one TCHAR unused is good enough +#else + const int CHAR_FUDGE = 2; // two BYTES unused for case of DBC last char +#endif + + // try fixed buffer first (to avoid wasting space in the heap) + TCHAR szTemp[256]; + int nCount = sizeof(szTemp) / sizeof(szTemp[0]); + int nLen = _LoadString(nID, szTemp, nCount); + if (nCount - nLen > CHAR_FUDGE) + { + *this = szTemp; + return (nLen > 0); + } + + // try buffer size of 512, then larger size until entire string is retrieved + int nSize = 256; + do + { + nSize += 256; + LPTSTR lpstr = GetBuffer(nSize - 1); + if(lpstr == NULL) + { + nLen = 0; + break; + } + nLen = _LoadString(nID, lpstr, nSize); + } while (nSize - nLen <= CHAR_FUDGE); + ReleaseBuffer(); + + return (nLen > 0); + } + +#ifndef _UNICODE + // ANSI <-> OEM support (convert string in place) + void AnsiToOem() + { + CopyBeforeWrite(); + ::AnsiToOem(m_pchData, m_pchData); + } + + void OemToAnsi() + { + CopyBeforeWrite(); + ::OemToAnsi(m_pchData, m_pchData); + } +#endif + +#ifndef _ATL_NO_COM + // OLE BSTR support (use for OLE automation) + BSTR AllocSysString() const + { +#if defined(_UNICODE) || defined(OLE2ANSI) + BSTR bstr = ::SysAllocStringLen(m_pchData, GetData()->nDataLength); +#else + int nLen = MultiByteToWideChar(CP_ACP, 0, m_pchData, + GetData()->nDataLength, NULL, NULL); + BSTR bstr = ::SysAllocStringLen(NULL, nLen); + if(bstr != NULL) + MultiByteToWideChar(CP_ACP, 0, m_pchData, GetData()->nDataLength, bstr, nLen); +#endif + return bstr; + } + + BSTR SetSysString(BSTR* pbstr) const + { +#if defined(_UNICODE) || defined(OLE2ANSI) + ::SysReAllocStringLen(pbstr, m_pchData, GetData()->nDataLength); +#else + int nLen = MultiByteToWideChar(CP_ACP, 0, m_pchData, + GetData()->nDataLength, NULL, NULL); + if(::SysReAllocStringLen(pbstr, NULL, nLen)) + MultiByteToWideChar(CP_ACP, 0, m_pchData, GetData()->nDataLength, *pbstr, nLen); +#endif + ATLASSERT(*pbstr != NULL); + return *pbstr; + } +#endif // !_ATL_NO_COM + + // Access to string implementation buffer as "C" character array + LPTSTR GetBuffer(int nMinBufLength) + { + ATLASSERT(nMinBufLength >= 0); + + if (GetData()->nRefs > 1 || nMinBufLength > GetData()->nAllocLength) + { + // we have to grow the buffer + CStringData* pOldData = GetData(); + int nOldLen = GetData()->nDataLength; // AllocBuffer will tromp it + if (nMinBufLength < nOldLen) + nMinBufLength = nOldLen; + + if(!AllocBuffer(nMinBufLength)) + return NULL; + + SecureHelper::memcpy_x(m_pchData, (nMinBufLength + 1) * sizeof(TCHAR), pOldData->data(), (nOldLen + 1) * sizeof(TCHAR)); + GetData()->nDataLength = nOldLen; + CString::Release(pOldData); + } + ATLASSERT(GetData()->nRefs <= 1); + + // return a pointer to the character storage for this string + ATLASSERT(m_pchData != NULL); + return m_pchData; + } + + void ReleaseBuffer(int nNewLength = -1) + { + CopyBeforeWrite(); // just in case GetBuffer was not called + + if (nNewLength == -1) + nNewLength = lstrlen(m_pchData); // zero terminated + + ATLASSERT(nNewLength <= GetData()->nAllocLength); + GetData()->nDataLength = nNewLength; + m_pchData[nNewLength] = _T('\0'); + } + + LPTSTR GetBufferSetLength(int nNewLength) + { + ATLASSERT(nNewLength >= 0); + + if(GetBuffer(nNewLength) == NULL) + return NULL; + + GetData()->nDataLength = nNewLength; + m_pchData[nNewLength] = _T('\0'); + return m_pchData; + } + + void FreeExtra() + { + ATLASSERT(GetData()->nDataLength <= GetData()->nAllocLength); + if (GetData()->nDataLength != GetData()->nAllocLength) + { + CStringData* pOldData = GetData(); + if(AllocBuffer(GetData()->nDataLength)) + { + SecureHelper::memcpy_x(m_pchData, (GetData()->nAllocLength + 1) * sizeof(TCHAR), pOldData->data(), pOldData->nDataLength * sizeof(TCHAR)); + ATLASSERT(m_pchData[GetData()->nDataLength] == _T('\0')); + CString::Release(pOldData); + } + } + ATLASSERT(GetData() != NULL); + } + + // Use LockBuffer/UnlockBuffer to turn refcounting off + LPTSTR LockBuffer() + { + LPTSTR lpsz = GetBuffer(0); + if(lpsz != NULL) + GetData()->nRefs = -1; + return lpsz; + } + + void UnlockBuffer() + { + ATLASSERT(GetData()->nRefs == -1); + if (GetData() != _atltmpDataNil) + GetData()->nRefs = 1; + } + +// Implementation +public: + ~CString() // free any attached data + { + if (GetData() != _atltmpDataNil) + { + if (InterlockedDecrement(&GetData()->nRefs) <= 0) + delete[] (BYTE*)GetData(); + } + } + + int GetAllocLength() const + { + return GetData()->nAllocLength; + } + + static BOOL __stdcall _IsValidString(LPCTSTR lpsz, int /*nLength*/ = -1) + { + return (lpsz != NULL) ? TRUE : FALSE; + } + +protected: + LPTSTR m_pchData; // pointer to ref counted string data + + // implementation helpers + CStringData* GetData() const + { + ATLASSERT(m_pchData != NULL); + return ((CStringData*)m_pchData) - 1; + } + + void Init() + { + m_pchData = _GetEmptyString().m_pchData; + } + + BOOL AllocCopy(CString& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const + { + // will clone the data attached to this string + // allocating 'nExtraLen' characters + // Places results in uninitialized string 'dest' + // Will copy the part or all of original data to start of new string + + BOOL bRet = FALSE; + int nNewLen = nCopyLen + nExtraLen; + if (nNewLen == 0) + { + dest.Init(); + bRet = TRUE; + } + else if(nNewLen >= nCopyLen) + { + if(dest.AllocBuffer(nNewLen)) + { + SecureHelper::memcpy_x(dest.m_pchData, (nNewLen + 1) * sizeof(TCHAR), m_pchData + nCopyIndex, nCopyLen * sizeof(TCHAR)); + bRet = TRUE; + } + } + + return bRet; + } + + // always allocate one extra character for '\0' termination + // assumes [optimistically] that data length will equal allocation length + BOOL AllocBuffer(int nLen) + { + ATLASSERT(nLen >= 0); + ATLASSERT(nLen <= INT_MAX - 1); // max size (enough room for 1 extra) + + if (nLen == 0) + { + Init(); + } + else + { + CStringData* pData = NULL; + ATLTRY(pData = (CStringData*)new BYTE[sizeof(CStringData) + (nLen + 1) * sizeof(TCHAR)]); + if(pData == NULL) + return FALSE; + + pData->nRefs = 1; + pData->data()[nLen] = _T('\0'); + pData->nDataLength = nLen; + pData->nAllocLength = nLen; + m_pchData = pData->data(); + } + + return TRUE; + } + + // Assignment operators + // All assign a new value to the string + // (a) first see if the buffer is big enough + // (b) if enough room, copy on top of old buffer, set size and type + // (c) otherwise free old string data, and create a new one + // + // All routines return the new string (but as a 'const CString&' so that + // assigning it again will cause a copy, eg: s1 = s2 = "hi there". + // + void AssignCopy(int nSrcLen, LPCTSTR lpszSrcData) + { + if(AllocBeforeWrite(nSrcLen)) + { + SecureHelper::memcpy_x(m_pchData, (nSrcLen + 1) * sizeof(TCHAR), lpszSrcData, nSrcLen * sizeof(TCHAR)); + GetData()->nDataLength = nSrcLen; + m_pchData[nSrcLen] = _T('\0'); + } + } + + // Concatenation + // NOTE: "operator +" is done as friend functions for simplicity + // There are three variants: + // CString + CString + // and for ? = TCHAR, LPCTSTR + // CString + ? + // ? + CString + BOOL ConcatCopy(int nSrc1Len, LPCTSTR lpszSrc1Data, int nSrc2Len, LPCTSTR lpszSrc2Data) + { + // -- master concatenation routine + // Concatenate two sources + // -- assume that 'this' is a new CString object + + BOOL bRet = TRUE; + int nNewLen = nSrc1Len + nSrc2Len; + if(nNewLen < nSrc1Len || nNewLen < nSrc2Len) + { + bRet = FALSE; + } + else if(nNewLen != 0) + { + bRet = AllocBuffer(nNewLen); + if (bRet) + { + SecureHelper::memcpy_x(m_pchData, (nNewLen + 1) * sizeof(TCHAR), lpszSrc1Data, nSrc1Len * sizeof(TCHAR)); + SecureHelper::memcpy_x(m_pchData + nSrc1Len, (nNewLen + 1 - nSrc1Len) * sizeof(TCHAR), lpszSrc2Data, nSrc2Len * sizeof(TCHAR)); + } + } + return bRet; + } + + void ConcatInPlace(int nSrcLen, LPCTSTR lpszSrcData) + { + // -- the main routine for += operators + + // concatenating an empty string is a no-op! + if (nSrcLen == 0) + return; + + // if the buffer is too small, or we have a width mis-match, just + // allocate a new buffer (slow but sure) + if (GetData()->nRefs > 1 || GetData()->nDataLength + nSrcLen > GetData()->nAllocLength) + { + // we have to grow the buffer, use the ConcatCopy routine + CStringData* pOldData = GetData(); + if (ConcatCopy(GetData()->nDataLength, m_pchData, nSrcLen, lpszSrcData)) + { + ATLASSERT(pOldData != NULL); + CString::Release(pOldData); + } + } + else + { + // fast concatenation when buffer big enough + SecureHelper::memcpy_x(m_pchData + GetData()->nDataLength, (GetData()->nAllocLength + 1) * sizeof(TCHAR), lpszSrcData, nSrcLen * sizeof(TCHAR)); + GetData()->nDataLength += nSrcLen; + ATLASSERT(GetData()->nDataLength <= GetData()->nAllocLength); + m_pchData[GetData()->nDataLength] = _T('\0'); + } + } + + void CopyBeforeWrite() + { + if (GetData()->nRefs > 1) + { + CStringData* pData = GetData(); + Release(); + if(AllocBuffer(pData->nDataLength)) + SecureHelper::memcpy_x(m_pchData, (GetData()->nAllocLength + 1) * sizeof(TCHAR), pData->data(), (pData->nDataLength + 1) * sizeof(TCHAR)); + } + ATLASSERT(GetData()->nRefs <= 1); + } + + BOOL AllocBeforeWrite(int nLen) + { + BOOL bRet = TRUE; + if (GetData()->nRefs > 1 || nLen > GetData()->nAllocLength) + { + Release(); + bRet = AllocBuffer(nLen); + } + ATLASSERT(GetData()->nRefs <= 1); + return bRet; + } + + void Release() + { + if (GetData() != _atltmpDataNil) + { + ATLASSERT(GetData()->nRefs != 0); + if (InterlockedDecrement(&GetData()->nRefs) <= 0) + delete[] (BYTE*)GetData(); + Init(); + } + } + + static void PASCAL Release(CStringData* pData) + { + if (pData != _atltmpDataNil) + { + ATLASSERT(pData->nRefs != 0); + if (InterlockedDecrement(&pData->nRefs) <= 0) + delete[] (BYTE*)pData; + } + } + + static int PASCAL SafeStrlen(LPCTSTR lpsz) + { + return (lpsz == NULL) ? 0 : lstrlen(lpsz); + } + + static int __stdcall _LoadString(UINT nID, LPTSTR lpszBuf, UINT nMaxBuf) + { +#ifdef _DEBUG + // LoadString without annoying warning from the Debug kernel if the + // segment containing the string is not present + if (::FindResource(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE((nID >> 4) + 1), RT_STRING) == NULL) + { + lpszBuf[0] = _T('\0'); + return 0; // not found + } +#endif // _DEBUG + + int nLen = ::LoadString(ModuleHelper::GetResourceInstance(), nID, lpszBuf, nMaxBuf); + if (nLen == 0) + lpszBuf[0] = _T('\0'); + + return nLen; + } + + static const CString& __stdcall _GetEmptyString() + { + return *(CString*)&_atltmpPchNil; + } + +// CString conversion helpers + static int __cdecl _wcstombsz(char* mbstr, const wchar_t* wcstr, size_t count) + { + if (count == 0 && mbstr != NULL) + return 0; + + int result = ::WideCharToMultiByte(CP_ACP, 0, wcstr, -1, mbstr, (int)count, NULL, NULL); + ATLASSERT(mbstr == NULL || result <= (int)count); + if (result > 0) + mbstr[result - 1] = 0; + return result; + } + + static int __cdecl _mbstowcsz(wchar_t* wcstr, const char* mbstr, size_t count) + { + if (count == 0 && wcstr != NULL) + return 0; + + int result = ::MultiByteToWideChar(CP_ACP, 0, mbstr, -1, wcstr, (int)count); + ATLASSERT(wcstr == NULL || result <= (int)count); + if (result > 0) + wcstr[result - 1] = 0; + return result; + } + +// Helpers to avoid CRT startup code +#ifdef _ATL_MIN_CRT + static const TCHAR* _cstrchr(const TCHAR* p, TCHAR ch) + { + // strchr for '\0' should succeed + while (*p != 0) + { + if (*p == ch) + break; + p = ::CharNext(p); + } + return (*p == ch) ? p : NULL; + } + + static const TCHAR* _cstrrchr(const TCHAR* p, TCHAR ch) + { + const TCHAR* lpsz = NULL; + while (*p != 0) + { + if (*p == ch) + lpsz = p; + p = ::CharNext(p); + } + return lpsz; + } + + static TCHAR* _cstrrev(TCHAR* pStr) + { + // optimize NULL, zero-length, and single-char case + if ((pStr == NULL) || (pStr[0] == _T('\0')) || (pStr[1] == _T('\0'))) + return pStr; + + TCHAR* p = pStr; + + while (*p != 0) + { + TCHAR* pNext = ::CharNext(p); + if(pNext > p + 1) + { + char p1 = *(char*)p; + *(char*)p = *(char*)(p + 1); + *(char*)(p + 1) = p1; + } + p = pNext; + } + + p--; + TCHAR* q = pStr; + + while (q < p) + { + TCHAR t = *q; + *q = *p; + *p = t; + q++; + p--; + } + return pStr; + } + + static const TCHAR* _cstrstr(const TCHAR* pStr, const TCHAR* pCharSet) + { + int nLen = lstrlen(pCharSet); + if (nLen == 0) + return (TCHAR*)pStr; + + const TCHAR* pRet = NULL; + const TCHAR* pCur = pStr; + while((pCur = _cstrchr(pCur, *pCharSet)) != NULL) + { + if(memcmp(pCur, pCharSet, nLen * sizeof(TCHAR)) == 0) + { + pRet = pCur; + break; + } + pCur = ::CharNext(pCur); + } + return pRet; + } + + static int _cstrspn(const TCHAR* pStr, const TCHAR* pCharSet) + { + int nRet = 0; + const TCHAR* p = pStr; + while (*p != 0) + { + const TCHAR* pNext = ::CharNext(p); + if(pNext > p + 1) + { + if(_cstrchr_db(pCharSet, *p, *(p + 1)) == NULL) + break; + nRet += 2; + } + else + { + if(_cstrchr(pCharSet, *p) == NULL) + break; + nRet++; + } + p = pNext; + } + return nRet; + } + + static int _cstrcspn(const TCHAR* pStr, const TCHAR* pCharSet) + { + int nRet = 0; + TCHAR* p = (TCHAR*)pStr; + while (*p != 0) + { + TCHAR* pNext = ::CharNext(p); + if(pNext > p + 1) + { + if(_cstrchr_db(pCharSet, *p, *(p + 1)) != NULL) + break; + nRet += 2; + } + else + { + if(_cstrchr(pCharSet, *p) != NULL) + break; + nRet++; + } + p = pNext; + } + return nRet; + } + + static const TCHAR* _cstrpbrk(const TCHAR* p, const TCHAR* lpszCharSet) + { + int n = _cstrcspn(p, lpszCharSet); + return (p[n] != 0) ? &p[n] : NULL; + } + + static int _cstrisdigit(TCHAR ch) + { + WORD type; + GetStringTypeEx(GetThreadLocale(), CT_CTYPE1, &ch, 1, &type); + return (type & C1_DIGIT) == C1_DIGIT; + } + + static int _cstrisspace(TCHAR ch) + { + WORD type; + GetStringTypeEx(GetThreadLocale(), CT_CTYPE1, &ch, 1, &type); + return (type & C1_SPACE) == C1_SPACE; + } + + static int _cstrcmp(const TCHAR* pstrOne, const TCHAR* pstrOther) + { + return lstrcmp(pstrOne, pstrOther); + } + + static int _cstrcmpi(const TCHAR* pstrOne, const TCHAR* pstrOther) + { + return lstrcmpi(pstrOne, pstrOther); + } + + static int _cstrcoll(const TCHAR* pstrOne, const TCHAR* pstrOther) + { + int nRet = CompareString(GetThreadLocale(), 0, pstrOne, -1, pstrOther, -1); + ATLASSERT(nRet != 0); + return nRet - 2; // convert to strcmp convention + } + + static int _cstrcolli(const TCHAR* pstrOne, const TCHAR* pstrOther) + { + int nRet = CompareString(GetThreadLocale(), NORM_IGNORECASE, pstrOne, -1, pstrOther, -1); + ATLASSERT(nRet != 0); + return nRet - 2; // convert to strcmp convention + } + + static int _cstrtoi(const TCHAR* nptr) + { + int c; // current char + int total; // current total + int sign; // if '-', then negative, otherwise positive + + while (_cstrisspace(*nptr)) + ++nptr; + + c = (int)(_TUCHAR)*nptr++; + sign = c; // save sign indication + if (c == _T('-') || c == _T('+')) + c = (int)(_TUCHAR)*nptr++; // skip sign + + total = 0; + + while (_cstrisdigit((TCHAR)c)) + { + total = 10 * total + (c - '0'); // accumulate digit + c = (int)(_TUCHAR)*nptr++; // get next char + } + + if (sign == '-') + return -total; + else + return total; // return result, negated if necessary + } +#else // !_ATL_MIN_CRT + static const TCHAR* _cstrchr(const TCHAR* p, TCHAR ch) + { + return _tcschr(p, ch); + } + + static const TCHAR* _cstrrchr(const TCHAR* p, TCHAR ch) + { + return _tcsrchr(p, ch); + } + + static TCHAR* _cstrrev(TCHAR* pStr) + { + return _tcsrev(pStr); + } + + static const TCHAR* _cstrstr(const TCHAR* pStr, const TCHAR* pCharSet) + { + return _tcsstr(pStr, pCharSet); + } + + static int _cstrspn(const TCHAR* pStr, const TCHAR* pCharSet) + { + return (int)_tcsspn(pStr, pCharSet); + } + + static int _cstrcspn(const TCHAR* pStr, const TCHAR* pCharSet) + { + return (int)_tcscspn(pStr, pCharSet); + } + + static const TCHAR* _cstrpbrk(const TCHAR* p, const TCHAR* lpszCharSet) + { + return _tcspbrk(p, lpszCharSet); + } + + static int _cstrisdigit(TCHAR ch) + { + return _istdigit(ch); + } + + static int _cstrisspace(TCHAR ch) + { + return _istspace((_TUCHAR)ch); + } + + static int _cstrcmp(const TCHAR* pstrOne, const TCHAR* pstrOther) + { + return _tcscmp(pstrOne, pstrOther); + } + + static int _cstrcmpi(const TCHAR* pstrOne, const TCHAR* pstrOther) + { + return _tcsicmp(pstrOne, pstrOther); + } + +#ifndef _WIN32_WCE + static int _cstrcoll(const TCHAR* pstrOne, const TCHAR* pstrOther) + { + return _tcscoll(pstrOne, pstrOther); + } + + static int _cstrcolli(const TCHAR* pstrOne, const TCHAR* pstrOther) + { + return _tcsicoll(pstrOne, pstrOther); + } +#endif // !_WIN32_WCE + + static int _cstrtoi(const TCHAR* nptr) + { + return _ttoi(nptr); + } +#endif // !_ATL_MIN_CRT + + static const TCHAR* _cstrchr_db(const TCHAR* p, TCHAR ch1, TCHAR ch2) + { + const TCHAR* lpsz = NULL; + while (*p != 0) + { + if (*p == ch1 && *(p + 1) == ch2) + { + lpsz = p; + break; + } + p = ::CharNext(p); + } + return lpsz; + } +}; + + +// Compare helpers + +inline bool __stdcall operator ==(const CString& s1, const CString& s2) +{ return s1.Compare(s2) == 0; } + +inline bool __stdcall operator ==(const CString& s1, LPCTSTR s2) +{ return s1.Compare(s2) == 0; } + +inline bool __stdcall operator ==(LPCTSTR s1, const CString& s2) +{ return s2.Compare(s1) == 0; } + +inline bool __stdcall operator !=(const CString& s1, const CString& s2) +{ return s1.Compare(s2) != 0; } + +inline bool __stdcall operator !=(const CString& s1, LPCTSTR s2) +{ return s1.Compare(s2) != 0; } + +inline bool __stdcall operator !=(LPCTSTR s1, const CString& s2) +{ return s2.Compare(s1) != 0; } + +inline bool __stdcall operator <(const CString& s1, const CString& s2) +{ return s1.Compare(s2) < 0; } + +inline bool __stdcall operator <(const CString& s1, LPCTSTR s2) +{ return s1.Compare(s2) < 0; } + +inline bool __stdcall operator <(LPCTSTR s1, const CString& s2) +{ return s2.Compare(s1) > 0; } + +inline bool __stdcall operator >(const CString& s1, const CString& s2) +{ return s1.Compare(s2) > 0; } + +inline bool __stdcall operator >(const CString& s1, LPCTSTR s2) +{ return s1.Compare(s2) > 0; } + +inline bool __stdcall operator >(LPCTSTR s1, const CString& s2) +{ return s2.Compare(s1) < 0; } + +inline bool __stdcall operator <=(const CString& s1, const CString& s2) +{ return s1.Compare(s2) <= 0; } + +inline bool __stdcall operator <=(const CString& s1, LPCTSTR s2) +{ return s1.Compare(s2) <= 0; } + +inline bool __stdcall operator <=(LPCTSTR s1, const CString& s2) +{ return s2.Compare(s1) >= 0; } + +inline bool __stdcall operator >=(const CString& s1, const CString& s2) +{ return s1.Compare(s2) >= 0; } + +inline bool __stdcall operator >=(const CString& s1, LPCTSTR s2) +{ return s1.Compare(s2) >= 0; } + +inline bool __stdcall operator >=(LPCTSTR s1, const CString& s2) +{ return s2.Compare(s1) <= 0; } + + +// CString "operator +" functions + +inline CString __stdcall operator +(const CString& string1, const CString& string2) +{ + CString s; + s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, string2.GetData()->nDataLength, string2.m_pchData); + return s; +} + +inline CString __stdcall operator +(const CString& string, TCHAR ch) +{ + CString s; + s.ConcatCopy(string.GetData()->nDataLength, string.m_pchData, 1, &ch); + return s; +} + +inline CString __stdcall operator +(TCHAR ch, const CString& string) +{ + CString s; + s.ConcatCopy(1, &ch, string.GetData()->nDataLength, string.m_pchData); + return s; +} + +#ifdef _UNICODE +inline CString __stdcall operator +(const CString& string, char ch) +{ + return string + (TCHAR)ch; +} + +inline CString __stdcall operator +(char ch, const CString& string) +{ + return (TCHAR)ch + string; +} +#endif // _UNICODE + +inline CString __stdcall operator +(const CString& string, LPCTSTR lpsz) +{ + ATLASSERT(lpsz == NULL || CString::_IsValidString(lpsz)); + CString s; + s.ConcatCopy(string.GetData()->nDataLength, string.m_pchData, CString::SafeStrlen(lpsz), lpsz); + return s; +} + +inline CString __stdcall operator +(LPCTSTR lpsz, const CString& string) +{ + ATLASSERT(lpsz == NULL || CString::_IsValidString(lpsz)); + CString s; + s.ConcatCopy(CString::SafeStrlen(lpsz), lpsz, string.GetData()->nDataLength, string.m_pchData); + return s; +} + +#endif // !_WTL_NO_CSTRING + + +/////////////////////////////////////////////////////////////////////////////// +// CRecentDocumentList - MRU List Support + +#ifndef _WIN32_WCE + +#ifndef _WTL_MRUEMPTY_TEXT + #define _WTL_MRUEMPTY_TEXT _T("(empty)") +#endif + +// forward declaration +inline bool AtlCompactPath(LPTSTR lpstrOut, LPCTSTR lpstrIn, int cchLen); + +template +class CRecentDocumentListBase +{ +public: +// Declarations + struct _DocEntry + { + TCHAR szDocName[t_cchItemLen]; + bool operator ==(const _DocEntry& de) const + { return (lstrcmpi(szDocName, de.szDocName) == 0); } + }; + + enum + { + m_nMaxEntries_Min = 2, + m_nMaxEntries_Max = t_nLastID - t_nFirstID + 1, + m_cchMaxItemLen_Min = 6, + m_cchMaxItemLen_Max = t_cchItemLen, + m_cchItemNameLen = 11 + }; + +// Data members + ATL::CSimpleArray<_DocEntry> m_arrDocs; + int m_nMaxEntries; // default is 4 + HMENU m_hMenu; + + TCHAR m_szNoEntries[t_cchItemLen]; + + int m_cchMaxItemLen; + +// Constructor + CRecentDocumentListBase() : m_hMenu(NULL), m_nMaxEntries(4), m_cchMaxItemLen(-1) + { + // These ASSERTs verify values of the template arguments + ATLASSERT(t_cchItemLen > m_cchMaxItemLen_Min); + ATLASSERT(m_nMaxEntries_Max > m_nMaxEntries_Min); + } + +// Attributes + HMENU GetMenuHandle() const + { + return m_hMenu; + } + + void SetMenuHandle(HMENU hMenu) + { + ATLASSERT(hMenu == NULL || ::IsMenu(hMenu)); + m_hMenu = hMenu; + if(m_hMenu == NULL || (::GetMenuString(m_hMenu, t_nFirstID, m_szNoEntries, t_cchItemLen, MF_BYCOMMAND) == 0)) + { + T* pT = static_cast(this); + pT; // avoid level 4 warning + SecureHelper::strncpy_x(m_szNoEntries, _countof(m_szNoEntries), pT->GetMRUEmptyText(), _TRUNCATE); + } + } + + int GetMaxEntries() const + { + return m_nMaxEntries; + } + + void SetMaxEntries(int nMaxEntries) + { + ATLASSERT(nMaxEntries >= m_nMaxEntries_Min && nMaxEntries <= m_nMaxEntries_Max); + if(nMaxEntries < m_nMaxEntries_Min) + nMaxEntries = m_nMaxEntries_Min; + else if(nMaxEntries > m_nMaxEntries_Max) + nMaxEntries = m_nMaxEntries_Max; + m_nMaxEntries = nMaxEntries; + } + + int GetMaxItemLength() const + { + return m_cchMaxItemLen; + } + + void SetMaxItemLength(int cchMaxLen) + { + ATLASSERT((cchMaxLen >= m_cchMaxItemLen_Min && cchMaxLen <= m_cchMaxItemLen_Max) || cchMaxLen == -1); + if(cchMaxLen != -1) + { + if(cchMaxLen < m_cchMaxItemLen_Min) + cchMaxLen = m_cchMaxItemLen_Min; + else if(cchMaxLen > m_cchMaxItemLen_Max) + cchMaxLen = m_cchMaxItemLen_Max; + } + m_cchMaxItemLen = cchMaxLen; + T* pT = static_cast(this); + pT->UpdateMenu(); + } + +// Operations + BOOL AddToList(LPCTSTR lpstrDocName) + { + _DocEntry de; + errno_t nRet = SecureHelper::strncpy_x(de.szDocName, _countof(de.szDocName), lpstrDocName, _TRUNCATE); + if(nRet != 0 && nRet != STRUNCATE) + return FALSE; + + for(int i = 0; i < m_arrDocs.GetSize(); i++) + { + if(lstrcmpi(m_arrDocs[i].szDocName, lpstrDocName) == 0) + { + m_arrDocs.RemoveAt(i); + break; + } + } + + if(m_arrDocs.GetSize() == m_nMaxEntries) + m_arrDocs.RemoveAt(0); + + BOOL bRet = m_arrDocs.Add(de); + if(bRet) + { + T* pT = static_cast(this); + bRet = pT->UpdateMenu(); + } + return bRet; + } + + // This function is deprecated because it is not safe. + // Use the version below that accepts the buffer length. +#if (_MSC_VER >= 1300) + __declspec(deprecated) +#endif + BOOL GetFromList(int /*nItemID*/, LPTSTR /*lpstrDocName*/) + { + ATLASSERT(FALSE); + return FALSE; + } + + BOOL GetFromList(int nItemID, LPTSTR lpstrDocName, int cchLength) + { + int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1; + if(nIndex < 0 || nIndex >= m_arrDocs.GetSize()) + return FALSE; + if(lstrlen(m_arrDocs[nIndex].szDocName) >= cchLength) + return FALSE; + SecureHelper::strcpy_x(lpstrDocName, cchLength, m_arrDocs[nIndex].szDocName); + + return TRUE; + } + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + BOOL GetFromList(int nItemID, _CSTRING_NS::CString& strDocName) + { + int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1; + if(nIndex < 0 || nIndex >= m_arrDocs.GetSize()) + return FALSE; + strDocName = m_arrDocs[nIndex].szDocName; + return TRUE; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + BOOL RemoveFromList(int nItemID) + { + int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1; + BOOL bRet = m_arrDocs.RemoveAt(nIndex); + if(bRet) + { + T* pT = static_cast(this); + bRet = pT->UpdateMenu(); + } + return bRet; + } + + BOOL MoveToTop(int nItemID) + { + int nIndex = m_arrDocs.GetSize() - (nItemID - t_nFirstID) - 1; + if(nIndex < 0 || nIndex >= m_arrDocs.GetSize()) + return FALSE; + _DocEntry de; + de = m_arrDocs[nIndex]; + m_arrDocs.RemoveAt(nIndex); + BOOL bRet = m_arrDocs.Add(de); + if(bRet) + { + T* pT = static_cast(this); + bRet = pT->UpdateMenu(); + } + return bRet; + } + + BOOL ReadFromRegistry(LPCTSTR lpstrRegKey) + { + T* pT = static_cast(this); + CRegKeyEx rkParent; + CRegKeyEx rk; + + LONG lRet = rkParent.Open(HKEY_CURRENT_USER, lpstrRegKey); + if(lRet != ERROR_SUCCESS) + return FALSE; + lRet = rk.Open(rkParent, pT->GetRegKeyName()); + if(lRet != ERROR_SUCCESS) + return FALSE; + + DWORD dwRet = 0; + lRet = rk.QueryDWORDValue(pT->GetRegCountName(), dwRet); + if(lRet != ERROR_SUCCESS) + return FALSE; + SetMaxEntries(dwRet); + + m_arrDocs.RemoveAll(); + + TCHAR szRetString[t_cchItemLen] = { 0 }; + _DocEntry de; + + for(int nItem = m_nMaxEntries; nItem > 0; nItem--) + { + TCHAR szBuff[m_cchItemNameLen] = { 0 }; + SecureHelper::wsprintf_x(szBuff, m_cchItemNameLen, pT->GetRegItemName(), nItem); + ULONG ulCount = t_cchItemLen; + lRet = rk.QueryStringValue(szBuff, szRetString, &ulCount); + if(lRet == ERROR_SUCCESS) + { + SecureHelper::strcpy_x(de.szDocName, _countof(de.szDocName), szRetString); + m_arrDocs.Add(de); + } + } + + rk.Close(); + rkParent.Close(); + + return pT->UpdateMenu(); + } + + BOOL WriteToRegistry(LPCTSTR lpstrRegKey) + { + T* pT = static_cast(this); + pT; // avoid level 4 warning + CRegKeyEx rkParent; + CRegKeyEx rk; + + LONG lRet = rkParent.Create(HKEY_CURRENT_USER, lpstrRegKey); + if(lRet != ERROR_SUCCESS) + return FALSE; + lRet = rk.Create(rkParent, pT->GetRegKeyName()); + if(lRet != ERROR_SUCCESS) + return FALSE; + + lRet = rk.SetDWORDValue(pT->GetRegCountName(), m_nMaxEntries); + ATLASSERT(lRet == ERROR_SUCCESS); + + // set new values + int nItem; + for(nItem = m_arrDocs.GetSize(); nItem > 0; nItem--) + { + TCHAR szBuff[m_cchItemNameLen] = { 0 }; + SecureHelper::wsprintf_x(szBuff, m_cchItemNameLen, pT->GetRegItemName(), nItem); + TCHAR szDocName[t_cchItemLen] = { 0 }; + GetFromList(t_nFirstID + nItem - 1, szDocName, t_cchItemLen); + lRet = rk.SetStringValue(szBuff, szDocName); + ATLASSERT(lRet == ERROR_SUCCESS); + } + + // delete unused keys + for(nItem = m_arrDocs.GetSize() + 1; nItem < m_nMaxEntries_Max; nItem++) + { + TCHAR szBuff[m_cchItemNameLen] = { 0 }; + SecureHelper::wsprintf_x(szBuff, m_cchItemNameLen, pT->GetRegItemName(), nItem); + rk.DeleteValue(szBuff); + } + + rk.Close(); + rkParent.Close(); + + return TRUE; + } + +// Implementation + BOOL UpdateMenu() + { + if(m_hMenu == NULL) + return FALSE; + ATLASSERT(::IsMenu(m_hMenu)); + + int nItems = ::GetMenuItemCount(m_hMenu); + int nInsertPoint; + for(nInsertPoint = 0; nInsertPoint < nItems; nInsertPoint++) + { + CMenuItemInfo mi; + mi.fMask = MIIM_ID; + ::GetMenuItemInfo(m_hMenu, nInsertPoint, TRUE, &mi); + if (mi.wID == t_nFirstID) + break; + } + ATLASSERT(nInsertPoint < nItems && "You need a menu item with an ID = t_nFirstID"); + + int nItem; + for(nItem = t_nFirstID; nItem < t_nFirstID + m_nMaxEntries; nItem++) + { + // keep the first one as an insertion point + if (nItem != t_nFirstID) + ::DeleteMenu(m_hMenu, nItem, MF_BYCOMMAND); + } + + TCHAR szItemText[t_cchItemLen + 6] = { 0 }; // add space for &, 2 digits, and a space + int nSize = m_arrDocs.GetSize(); + nItem = 0; + if(nSize > 0) + { + for(nItem = 0; nItem < nSize; nItem++) + { + if(m_cchMaxItemLen == -1) + { + SecureHelper::wsprintf_x(szItemText, t_cchItemLen + 6, _T("&%i %s"), nItem + 1, m_arrDocs[nSize - 1 - nItem].szDocName); + } + else + { + TCHAR szBuff[t_cchItemLen] = { 0 }; + T* pT = static_cast(this); + pT; // avoid level 4 warning + bool bRet = pT->CompactDocumentName(szBuff, m_arrDocs[nSize - 1 - nItem].szDocName, m_cchMaxItemLen); + bRet; // avoid level 4 warning + ATLASSERT(bRet); + SecureHelper::wsprintf_x(szItemText, t_cchItemLen + 6, _T("&%i %s"), nItem + 1, szBuff); + } + ::InsertMenu(m_hMenu, nInsertPoint + nItem, MF_BYPOSITION | MF_STRING, t_nFirstID + nItem, szItemText); + } + } + else // empty + { + ::InsertMenu(m_hMenu, nInsertPoint, MF_BYPOSITION | MF_STRING, t_nFirstID, m_szNoEntries); + ::EnableMenuItem(m_hMenu, t_nFirstID, MF_GRAYED); + nItem++; + } + ::DeleteMenu(m_hMenu, nInsertPoint + nItem, MF_BYPOSITION); + + return TRUE; + } + +// Overrideables + // override to provide a different method of compacting document names + static bool CompactDocumentName(LPTSTR lpstrOut, LPCTSTR lpstrIn, int cchLen) + { + return AtlCompactPath(lpstrOut, lpstrIn, cchLen); + } + + static LPCTSTR GetRegKeyName() + { + return _T("Recent Document List"); + } + + static LPCTSTR GetRegCountName() + { + return _T("DocumentCount"); + } + + static LPCTSTR GetRegItemName() + { + // Note: This string is a format string used with wsprintf(). + // Resulting formatted string must be m_cchItemNameLen or less + // characters long, including the terminating null character. + return _T("Document%i"); + } + + static LPCTSTR GetMRUEmptyText() + { + return _WTL_MRUEMPTY_TEXT; + } +}; + +class CRecentDocumentList : public CRecentDocumentListBase +{ +public: +// nothing here +}; + +#endif // _WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CFindFile - file search helper class + +class CFindFile +{ +public: +// Data members + WIN32_FIND_DATA m_fd; + TCHAR m_lpszRoot[MAX_PATH]; + TCHAR m_chDirSeparator; + HANDLE m_hFind; + BOOL m_bFound; + +// Constructor/destructor + CFindFile() : m_hFind(NULL), m_chDirSeparator(_T('\\')), m_bFound(FALSE) + { } + + ~CFindFile() + { + Close(); + } + +// Attributes + ULONGLONG GetFileSize() const + { + ATLASSERT(m_hFind != NULL); + + ULARGE_INTEGER nFileSize = { 0 }; + + if(m_bFound) + { + nFileSize.LowPart = m_fd.nFileSizeLow; + nFileSize.HighPart = m_fd.nFileSizeHigh; + } + else + { + nFileSize.QuadPart = 0; + } + + return nFileSize.QuadPart; + } + + BOOL GetFileName(LPTSTR lpstrFileName, int cchLength) const + { + ATLASSERT(m_hFind != NULL); + if(lstrlen(m_fd.cFileName) >= cchLength) + return FALSE; + + if(m_bFound) + SecureHelper::strcpy_x(lpstrFileName, cchLength, m_fd.cFileName); + + return m_bFound; + } + + BOOL GetFilePath(LPTSTR lpstrFilePath, int cchLength) const + { + ATLASSERT(m_hFind != NULL); + + int nLen = lstrlen(m_lpszRoot); +#ifndef _WIN32_WCE + ATLASSERT(nLen > 0); + if(nLen == 0) + return FALSE; + + bool bAddSep = (m_lpszRoot[nLen - 1] != _T('\\') && m_lpszRoot[nLen - 1] !=_T('/')); +#else // CE specific + // allow diskless devices (nLen == 0) + bool bAddSep = ((nLen == 0) || (m_lpszRoot[nLen - 1] != _T('\\') && m_lpszRoot[nLen - 1] !=_T('/'))); +#endif // _WIN32_WCE + + if((lstrlen(m_lpszRoot) + (bAddSep ? 1 : 0)) >= cchLength) + return FALSE; + + SecureHelper::strcpy_x(lpstrFilePath, cchLength, m_lpszRoot); + + if(bAddSep) + { + TCHAR szSeparator[2] = { m_chDirSeparator, 0 }; + SecureHelper::strcat_x(lpstrFilePath, cchLength, szSeparator); + } + + SecureHelper::strcat_x(lpstrFilePath, cchLength, m_fd.cFileName); + + return TRUE; + } + +#ifndef _WIN32_WCE + BOOL GetFileTitle(LPTSTR lpstrFileTitle, int cchLength) const + { + ATLASSERT(m_hFind != NULL); + + TCHAR szBuff[MAX_PATH] = { 0 }; + if(!GetFileName(szBuff, MAX_PATH)) + return FALSE; + + if(lstrlen(szBuff) >= cchLength || cchLength < 1) + return FALSE; + + // find the last dot + LPTSTR pstrDot = (LPTSTR)_cstrrchr(szBuff, _T('.')); + if(pstrDot != NULL) + *pstrDot = 0; + + SecureHelper::strcpy_x(lpstrFileTitle, cchLength, szBuff); + + return TRUE; + } +#endif // !_WIN32_WCE + + BOOL GetFileURL(LPTSTR lpstrFileURL, int cchLength) const + { + ATLASSERT(m_hFind != NULL); + + TCHAR szBuff[MAX_PATH] = { 0 }; + if(!GetFilePath(szBuff, MAX_PATH)) + return FALSE; + LPCTSTR lpstrFileURLPrefix = _T("file://"); + if(lstrlen(szBuff) + lstrlen(lpstrFileURLPrefix) >= cchLength) + return FALSE; + SecureHelper::strcpy_x(lpstrFileURL, cchLength, lpstrFileURLPrefix); + SecureHelper::strcat_x(lpstrFileURL, cchLength, szBuff); + + return TRUE; + } + + BOOL GetRoot(LPTSTR lpstrRoot, int cchLength) const + { + ATLASSERT(m_hFind != NULL); + if(lstrlen(m_lpszRoot) >= cchLength) + return FALSE; + + SecureHelper::strcpy_x(lpstrRoot, cchLength, m_lpszRoot); + + return TRUE; + } + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + _CSTRING_NS::CString GetFileName() const + { + ATLASSERT(m_hFind != NULL); + + _CSTRING_NS::CString ret; + + if(m_bFound) + ret = m_fd.cFileName; + return ret; + } + + _CSTRING_NS::CString GetFilePath() const + { + ATLASSERT(m_hFind != NULL); + + _CSTRING_NS::CString strResult = m_lpszRoot; + int nLen = strResult.GetLength(); +#ifndef _WIN32_WCE + ATLASSERT(nLen > 0); + if(nLen == 0) + return strResult; + + if((strResult[nLen - 1] != _T('\\')) && (strResult[nLen - 1] != _T('/'))) +#else // CE specific + // allow diskless devices (nLen == 0) + if((nLen == 0) || ((strResult[nLen - 1] != _T('\\')) && (strResult[nLen - 1] != _T('/')))) +#endif // _WIN32_WCE + strResult += m_chDirSeparator; + strResult += GetFileName(); + return strResult; + } + +#ifndef _WIN32_WCE + _CSTRING_NS::CString GetFileTitle() const + { + ATLASSERT(m_hFind != NULL); + + _CSTRING_NS::CString strResult; + GetFileTitle(strResult.GetBuffer(MAX_PATH), MAX_PATH); + strResult.ReleaseBuffer(); + + return strResult; + } +#endif // !_WIN32_WCE + + _CSTRING_NS::CString GetFileURL() const + { + ATLASSERT(m_hFind != NULL); + + _CSTRING_NS::CString strResult("file://"); + strResult += GetFilePath(); + return strResult; + } + + _CSTRING_NS::CString GetRoot() const + { + ATLASSERT(m_hFind != NULL); + + _CSTRING_NS::CString str = m_lpszRoot; + return str; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + BOOL GetLastWriteTime(FILETIME* pTimeStamp) const + { + ATLASSERT(m_hFind != NULL); + ATLASSERT(pTimeStamp != NULL); + + if(m_bFound && pTimeStamp != NULL) + { + *pTimeStamp = m_fd.ftLastWriteTime; + return TRUE; + } + + return FALSE; + } + + BOOL GetLastAccessTime(FILETIME* pTimeStamp) const + { + ATLASSERT(m_hFind != NULL); + ATLASSERT(pTimeStamp != NULL); + + if(m_bFound && pTimeStamp != NULL) + { + *pTimeStamp = m_fd.ftLastAccessTime; + return TRUE; + } + + return FALSE; + } + + BOOL GetCreationTime(FILETIME* pTimeStamp) const + { + ATLASSERT(m_hFind != NULL); + + if(m_bFound && pTimeStamp != NULL) + { + *pTimeStamp = m_fd.ftCreationTime; + return TRUE; + } + + return FALSE; + } + + BOOL MatchesMask(DWORD dwMask) const + { + ATLASSERT(m_hFind != NULL); + + if(m_bFound) + return ((m_fd.dwFileAttributes & dwMask) != 0); + + return FALSE; + } + + BOOL IsDots() const + { + ATLASSERT(m_hFind != NULL); + + // return TRUE if the file name is "." or ".." and + // the file is a directory + + BOOL bResult = FALSE; + if(m_bFound && IsDirectory()) + { + if(m_fd.cFileName[0] == _T('.') && (m_fd.cFileName[1] == _T('\0') || (m_fd.cFileName[1] == _T('.') && m_fd.cFileName[2] == _T('\0')))) + bResult = TRUE; + } + + return bResult; + } + + BOOL IsReadOnly() const + { + return MatchesMask(FILE_ATTRIBUTE_READONLY); + } + + BOOL IsDirectory() const + { + return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); + } + + BOOL IsCompressed() const + { + return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); + } + + BOOL IsSystem() const + { + return MatchesMask(FILE_ATTRIBUTE_SYSTEM); + } + + BOOL IsHidden() const + { + return MatchesMask(FILE_ATTRIBUTE_HIDDEN); + } + + BOOL IsTemporary() const + { + return MatchesMask(FILE_ATTRIBUTE_TEMPORARY); + } + + BOOL IsNormal() const + { + return MatchesMask(FILE_ATTRIBUTE_NORMAL); + } + + BOOL IsArchived() const + { + return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); + } + +// Operations + BOOL FindFile(LPCTSTR pstrName = NULL) + { + Close(); + + if(pstrName == NULL) + { + pstrName = _T("*.*"); + } + else if(lstrlen(pstrName) >= MAX_PATH) + { + ATLASSERT(FALSE); + return FALSE; + } + + SecureHelper::strcpy_x(m_fd.cFileName, _countof(m_fd.cFileName), pstrName); + + m_hFind = ::FindFirstFile(pstrName, &m_fd); + + if(m_hFind == INVALID_HANDLE_VALUE) + return FALSE; + +#ifndef _WIN32_WCE + bool bFullPath = (::GetFullPathName(pstrName, MAX_PATH, m_lpszRoot, NULL) != 0); +#else // CE specific + errno_t nRet = SecureHelper::strncpy_x(m_lpszRoot, _countof(m_lpszRoot), pstrName, _TRUNCATE); + bool bFullPath = (nRet == 0 || nRet == STRUNCATE); +#endif // _WIN32_WCE + + // passed name isn't a valid path but was found by the API + ATLASSERT(bFullPath); + if(!bFullPath) + { + Close(); + ::SetLastError(ERROR_INVALID_NAME); + return FALSE; + } + else + { + // find the last forward or backward whack + LPTSTR pstrBack = (LPTSTR)_cstrrchr(m_lpszRoot, _T('\\')); + LPTSTR pstrFront = (LPTSTR)_cstrrchr(m_lpszRoot, _T('/')); + + if(pstrFront != NULL || pstrBack != NULL) + { + if(pstrFront == NULL) + pstrFront = m_lpszRoot; + if(pstrBack == NULL) + pstrBack = m_lpszRoot; + + // from the start to the last whack is the root + + if(pstrFront >= pstrBack) + *pstrFront = _T('\0'); + else + *pstrBack = _T('\0'); + } + } + + m_bFound = TRUE; + + return TRUE; + } + + BOOL FindNextFile() + { + ATLASSERT(m_hFind != NULL); + + if(m_hFind == NULL) + return FALSE; + + if(!m_bFound) + return FALSE; + + m_bFound = ::FindNextFile(m_hFind, &m_fd); + + return m_bFound; + } + + void Close() + { + m_bFound = FALSE; + + if(m_hFind != NULL && m_hFind != INVALID_HANDLE_VALUE) + { + ::FindClose(m_hFind); + m_hFind = NULL; + } + } + +// Helper + static const TCHAR* _cstrrchr(const TCHAR* p, TCHAR ch) + { +#ifdef _ATL_MIN_CRT + const TCHAR* lpsz = NULL; + while (*p != 0) + { + if (*p == ch) + lpsz = p; + p = ::CharNext(p); + } + return lpsz; +#else // !_ATL_MIN_CRT + return _tcsrchr(p, ch); +#endif // !_ATL_MIN_CRT + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// Global functions for stock GDI objects + +inline HPEN AtlGetStockPen(int nPen) +{ +#if (_WIN32_WINNT >= 0x0500) && !defined(_WIN32_WCE) + ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN || nPen == DC_PEN); +#else + ATLASSERT(nPen == WHITE_PEN || nPen == BLACK_PEN || nPen == NULL_PEN); +#endif + return (HPEN)::GetStockObject(nPen); +} + +inline HBRUSH AtlGetStockBrush(int nBrush) +{ +#if (_WIN32_WINNT >= 0x0500) && !defined(_WIN32_WCE) + ATLASSERT((nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH) || nBrush == DC_BRUSH); +#else + ATLASSERT(nBrush >= WHITE_BRUSH && nBrush <= HOLLOW_BRUSH); +#endif + return (HBRUSH)::GetStockObject(nBrush); +} + +inline HFONT AtlGetStockFont(int nFont) +{ +#ifndef _WIN32_WCE + ATLASSERT((nFont >= OEM_FIXED_FONT && nFont <= SYSTEM_FIXED_FONT) || nFont == DEFAULT_GUI_FONT); +#else // CE specific + ATLASSERT(nFont == SYSTEM_FONT); +#endif // _WIN32_WCE + return (HFONT)::GetStockObject(nFont); +} + +inline HPALETTE AtlGetStockPalette(int nPalette) +{ + ATLASSERT(nPalette == DEFAULT_PALETTE); // the only one supported + return (HPALETTE)::GetStockObject(nPalette); +} + + +/////////////////////////////////////////////////////////////////////////////// +// Global function for compacting a path by replacing parts with ellipsis + +// helper for multi-byte character sets +inline bool _IsDBCSTrailByte(LPCTSTR lpstr, int nChar) +{ +#ifndef _UNICODE + int i = nChar; + for( ; i > 0; i--) + { + if(!::IsDBCSLeadByte(lpstr[i - 1])) + break; + } + return ((nChar > 0) && (((nChar - i) & 1) != 0)); +#else // _UNICODE + lpstr; nChar; + return false; +#endif // _UNICODE +} + +inline bool AtlCompactPath(LPTSTR lpstrOut, LPCTSTR lpstrIn, int cchLen) +{ + ATLASSERT(lpstrOut != NULL); + ATLASSERT(lpstrIn != NULL); + ATLASSERT(cchLen > 0); + + LPCTSTR szEllipsis = _T("..."); + const int cchEndEllipsis = 3; + const int cchMidEllipsis = 4; + + if(lstrlen(lpstrIn) < cchLen) + { + SecureHelper::strcpy_x(lpstrOut, cchLen, lpstrIn); + return true; + } + + lpstrOut[0] = 0; + + // check if the separator is a slash or a backslash + TCHAR chSlash = _T('\\'); + for(LPTSTR lpstr = (LPTSTR)lpstrIn; *lpstr != 0; lpstr = ::CharNext(lpstr)) + { + if((*lpstr == _T('/')) || (*lpstr == _T('\\'))) + chSlash = *lpstr; + } + + // find the filename portion of the path + LPCTSTR lpstrFileName = lpstrIn; + for(LPCTSTR pPath = lpstrIn; *pPath; pPath = ::CharNext(pPath)) + { + if((pPath[0] == _T('\\') || pPath[0] == _T(':') || pPath[0] == _T('/')) + && pPath[1] && pPath[1] != _T('\\') && pPath[1] != _T('/')) + lpstrFileName = pPath + 1; + } + int cchFileName = lstrlen(lpstrFileName); + + // handle just the filename without a path + if(lpstrFileName == lpstrIn && cchLen > cchEndEllipsis) + { + bool bRet = (SecureHelper::strncpy_x(lpstrOut, cchLen, lpstrIn, cchLen - cchEndEllipsis - 1) == 0); + if(bRet) + { +#ifndef _UNICODE + if(_IsDBCSTrailByte(lpstrIn, cchLen - cchEndEllipsis)) + lpstrOut[cchLen - cchEndEllipsis - 1] = 0; +#endif // _UNICODE + SecureHelper::strcat_x(lpstrOut, cchLen, szEllipsis); + } + return bRet; + } + + // handle just ellipsis + if((cchLen < (cchMidEllipsis + cchEndEllipsis))) + { + for(int i = 0; i < cchLen - 1; i++) + lpstrOut[i] = ((i + 1) == cchMidEllipsis) ? chSlash : _T('.'); + lpstrOut[cchLen - 1] = 0; + return true; + } + + // calc how much we have to copy + int cchToCopy = cchLen - (cchMidEllipsis + cchFileName) - 1; + + if(cchToCopy < 0) + cchToCopy = 0; + +#ifndef _UNICODE + if(cchToCopy > 0 && _IsDBCSTrailByte(lpstrIn, cchToCopy)) + cchToCopy--; +#endif // _UNICODE + + bool bRet = (SecureHelper::strncpy_x(lpstrOut, cchLen, lpstrIn, cchToCopy) == 0); + if(!bRet) + return false; + + // add ellipsis + SecureHelper::strcat_x(lpstrOut, cchLen, szEllipsis); + if(!bRet) + return false; + TCHAR szSlash[2] = { chSlash, 0 }; + SecureHelper::strcat_x(lpstrOut, cchLen, szSlash); + if(!bRet) + return false; + + // add filename (and ellipsis, if needed) + if(cchLen > (cchMidEllipsis + cchFileName)) + { + SecureHelper::strcat_x(lpstrOut, cchLen, lpstrFileName); + } + else + { + cchToCopy = cchLen - cchMidEllipsis - cchEndEllipsis - 1; +#ifndef _UNICODE + if(cchToCopy > 0 && _IsDBCSTrailByte(lpstrFileName, cchToCopy)) + cchToCopy--; +#endif // _UNICODE + bRet = (SecureHelper::strncpy_x(&lpstrOut[cchMidEllipsis], cchLen - cchMidEllipsis, lpstrFileName, cchToCopy) == 0); + if(bRet) + SecureHelper::strcat_x(lpstrOut, cchLen, szEllipsis); + } + + return bRet; +} + +}; // namespace WTL + +#endif // __ATLMISC_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlprint.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlprint.h new file mode 100644 index 0000000000..50a7fb17dc --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlprint.h @@ -0,0 +1,1109 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLPRINT_H__ +#define __ATLPRINT_H__ + +#pragma once + +#ifdef _WIN32_WCE + #error atlprint.h is not supported on Windows CE +#endif + +#ifndef __ATLAPP_H__ + #error atlprint.h requires atlapp.h to be included first +#endif + +#ifndef __ATLWIN_H__ + #error atlprint.h requires atlwin.h to be included first +#endif + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CPrinterInfo +// CPrinterT +// CDevModeT +// CPrinterDC +// CPrintJobInfo +// CPrintJob +// CPrintPreview +// CPrintPreviewWindowImpl +// CPrintPreviewWindow +// CZoomPrintPreviewWindowImpl +// CZoomPrintPreviewWindow + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// CPrinterInfo - This class wraps all of the PRINTER_INFO_* structures +// and provided by ::GetPrinter. + +template +class _printer_info +{ +public: + typedef void infotype; +}; + +template <> class _printer_info<1> { public: typedef PRINTER_INFO_1 infotype; }; +template <> class _printer_info<2> { public: typedef PRINTER_INFO_2 infotype; }; +template <> class _printer_info<3> { public: typedef PRINTER_INFO_3 infotype; }; +template <> class _printer_info<4> { public: typedef PRINTER_INFO_4 infotype; }; +template <> class _printer_info<5> { public: typedef PRINTER_INFO_5 infotype; }; +template <> class _printer_info<6> { public: typedef PRINTER_INFO_6 infotype; }; +template <> class _printer_info<7> { public: typedef PRINTER_INFO_7 infotype; }; +// these are not in the old (vc6.0) headers +#ifdef _ATL_USE_NEW_PRINTER_INFO +template <> class _printer_info<8> { public: typedef PRINTER_INFO_8 infotype; }; +template <> class _printer_info<9> { public: typedef PRINTER_INFO_9 infotype; }; +#endif // _ATL_USE_NEW_PRINTER_INFO + + +template +class CPrinterInfo +{ +public: +// Data members + typename _printer_info::infotype* m_pi; + +// Constructor/destructor + CPrinterInfo() : m_pi(NULL) + { } + + CPrinterInfo(HANDLE hPrinter) : m_pi(NULL) + { + GetPrinterInfo(hPrinter); + } + + ~CPrinterInfo() + { + Cleanup(); + } + +// Operations + bool GetPrinterInfo(HANDLE hPrinter) + { + Cleanup(); + return GetPrinterInfoHelper(hPrinter, (BYTE**)&m_pi, t_nInfo); + } + +// Implementation + void Cleanup() + { + delete [] (BYTE*)m_pi; + m_pi = NULL; + } + + static bool GetPrinterInfoHelper(HANDLE hPrinter, BYTE** pi, int nIndex) + { + ATLASSERT(pi != NULL); + DWORD dw = 0; + BYTE* pb = NULL; + ::GetPrinter(hPrinter, nIndex, NULL, 0, &dw); + if (dw > 0) + { + ATLTRY(pb = new BYTE[dw]); + if (pb != NULL) + { + memset(pb, 0, dw); + DWORD dwNew; + if (!::GetPrinter(hPrinter, nIndex, pb, dw, &dwNew)) + { + delete [] pb; + pb = NULL; + } + } + } + *pi = pb; + return (pb != NULL); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CPrinter - Wrapper class for a HANDLE to a printer + +template +class CPrinterT +{ +public: +// Data members + HANDLE m_hPrinter; + +// Constructor/destructor + CPrinterT(HANDLE hPrinter = NULL) : m_hPrinter(hPrinter) + { } + + ~CPrinterT() + { + ClosePrinter(); + } + +// Operations + CPrinterT& operator =(HANDLE hPrinter) + { + if (hPrinter != m_hPrinter) + { + ClosePrinter(); + m_hPrinter = hPrinter; + } + return *this; + } + + bool IsNull() const { return (m_hPrinter == NULL); } + + bool OpenPrinter(HANDLE hDevNames, const DEVMODE* pDevMode = NULL) + { + bool b = false; + DEVNAMES* pdn = (DEVNAMES*)::GlobalLock(hDevNames); + if (pdn != NULL) + { + LPTSTR lpszPrinterName = (LPTSTR)pdn + pdn->wDeviceOffset; + b = OpenPrinter(lpszPrinterName, pDevMode); + ::GlobalUnlock(hDevNames); + } + return b; + } + + bool OpenPrinter(LPCTSTR lpszPrinterName, const DEVMODE* pDevMode = NULL) + { + ClosePrinter(); + PRINTER_DEFAULTS pdefs = { NULL, (DEVMODE*)pDevMode, PRINTER_ACCESS_USE }; + ::OpenPrinter((LPTSTR) lpszPrinterName, &m_hPrinter, (pDevMode == NULL) ? NULL : &pdefs); + + return (m_hPrinter != NULL); + } + + bool OpenPrinter(LPCTSTR lpszPrinterName, PRINTER_DEFAULTS* pprintdefs) + { + ClosePrinter(); + ::OpenPrinter((LPTSTR) lpszPrinterName, &m_hPrinter, pprintdefs); + return (m_hPrinter != NULL); + } + + bool OpenDefaultPrinter(const DEVMODE* pDevMode = NULL) + { + ClosePrinter(); + const int cchBuff = 512; + TCHAR buffer[cchBuff]; + buffer[0] = 0; + ::GetProfileString(_T("windows"), _T("device"), _T(",,,"), buffer, cchBuff); + int nLen = lstrlen(buffer); + if (nLen != 0) + { + LPTSTR lpsz = buffer; + while (*lpsz) + { + if (*lpsz == _T(',')) + { + *lpsz = 0; + break; + } + lpsz = CharNext(lpsz); + } + PRINTER_DEFAULTS pdefs = { NULL, (DEVMODE*)pDevMode, PRINTER_ACCESS_USE }; + ::OpenPrinter(buffer, &m_hPrinter, (pDevMode == NULL) ? NULL : &pdefs); + } + return m_hPrinter != NULL; + } + + void ClosePrinter() + { + if (m_hPrinter != NULL) + { + if (t_bManaged) + ::ClosePrinter(m_hPrinter); + m_hPrinter = NULL; + } + } + + bool PrinterProperties(HWND hWnd = NULL) + { + if (hWnd == NULL) + hWnd = ::GetActiveWindow(); + return !!::PrinterProperties(hWnd, m_hPrinter); + } + + HANDLE CopyToHDEVNAMES() const + { + HANDLE h = NULL; + CPrinterInfo<5> pinfon5; + CPrinterInfo<2> pinfon2; + LPTSTR lpszPrinterName = NULL; + // Some printers fail for PRINTER_INFO_5 in some situations + if (pinfon5.GetPrinterInfo(m_hPrinter)) + lpszPrinterName = pinfon5.m_pi->pPrinterName; + else if (pinfon2.GetPrinterInfo(m_hPrinter)) + lpszPrinterName = pinfon2.m_pi->pPrinterName; + if (lpszPrinterName != NULL) + { + int nLen = sizeof(DEVNAMES) + (lstrlen(lpszPrinterName) + 1) * sizeof(TCHAR); + h = ::GlobalAlloc(GMEM_MOVEABLE, nLen); + BYTE* pv = (BYTE*)::GlobalLock(h); + DEVNAMES* pdev = (DEVNAMES*)pv; + if (pv != NULL) + { + memset(pv, 0, nLen); + pdev->wDeviceOffset = sizeof(DEVNAMES) / sizeof(TCHAR); + pv = pv + sizeof(DEVNAMES); // now points to end + SecureHelper::strcpy_x((LPTSTR)pv, lstrlen(lpszPrinterName) + 1, lpszPrinterName); + ::GlobalUnlock(h); + } + } + return h; + } + + HDC CreatePrinterDC(const DEVMODE* pdm = NULL) const + { + CPrinterInfo<5> pinfo5; + CPrinterInfo<2> pinfo2; + HDC hDC = NULL; + LPTSTR lpszPrinterName = NULL; + // Some printers fail for PRINTER_INFO_5 in some situations + if (pinfo5.GetPrinterInfo(m_hPrinter)) + lpszPrinterName = pinfo5.m_pi->pPrinterName; + else if (pinfo2.GetPrinterInfo(m_hPrinter)) + lpszPrinterName = pinfo2.m_pi->pPrinterName; + if (lpszPrinterName != NULL) + hDC = ::CreateDC(NULL, lpszPrinterName, NULL, pdm); + return hDC; + } + + HDC CreatePrinterIC(const DEVMODE* pdm = NULL) const + { + CPrinterInfo<5> pinfo5; + CPrinterInfo<2> pinfo2; + HDC hDC = NULL; + LPTSTR lpszPrinterName = NULL; + // Some printers fail for PRINTER_INFO_5 in some situations + if (pinfo5.GetPrinterInfo(m_hPrinter)) + lpszPrinterName = pinfo5.m_pi->pPrinterName; + else if (pinfo2.GetPrinterInfo(m_hPrinter)) + lpszPrinterName = pinfo2.m_pi->pPrinterName; + if (lpszPrinterName != NULL) + hDC = ::CreateIC(NULL, lpszPrinterName, NULL, pdm); + return hDC; + } + + void Attach(HANDLE hPrinter) + { + ClosePrinter(); + m_hPrinter = hPrinter; + } + + HANDLE Detach() + { + HANDLE hPrinter = m_hPrinter; + m_hPrinter = NULL; + return hPrinter; + } + + operator HANDLE() const { return m_hPrinter; } +}; + +typedef CPrinterT CPrinterHandle; +typedef CPrinterT CPrinter; + + +/////////////////////////////////////////////////////////////////////////////// +// CDevMode - Wrapper class for DEVMODE + +template +class CDevModeT +{ +public: +// Data members + HANDLE m_hDevMode; + DEVMODE* m_pDevMode; + +// Constructor/destructor + CDevModeT(HANDLE hDevMode = NULL) : m_hDevMode(hDevMode) + { + m_pDevMode = (m_hDevMode != NULL) ? (DEVMODE*)::GlobalLock(m_hDevMode) : NULL; + } + + ~CDevModeT() + { + Cleanup(); + } + +// Operations + CDevModeT& operator =(HANDLE hDevMode) + { + Attach(hDevMode); + return *this; + } + + void Attach(HANDLE hDevModeNew) + { + Cleanup(); + m_hDevMode = hDevModeNew; + m_pDevMode = (m_hDevMode != NULL) ? (DEVMODE*)::GlobalLock(m_hDevMode) : NULL; + } + + HANDLE Detach() + { + if (m_hDevMode != NULL) + ::GlobalUnlock(m_hDevMode); + HANDLE hDevMode = m_hDevMode; + m_hDevMode = NULL; + return hDevMode; + } + + bool IsNull() const { return (m_hDevMode == NULL); } + + bool CopyFromPrinter(HANDLE hPrinter) + { + CPrinterInfo<2> pinfo; + bool b = pinfo.GetPrinterInfo(hPrinter); + if (b) + b = CopyFromDEVMODE(pinfo.m_pi->pDevMode); + return b; + } + + bool CopyFromDEVMODE(const DEVMODE* pdm) + { + if (pdm == NULL) + return false; + int nSize = pdm->dmSize + pdm->dmDriverExtra; + HANDLE h = ::GlobalAlloc(GMEM_MOVEABLE, nSize); + if (h != NULL) + { + void* p = ::GlobalLock(h); + SecureHelper::memcpy_x(p, nSize, pdm, nSize); + ::GlobalUnlock(h); + } + Attach(h); + return (h != NULL); + } + + bool CopyFromHDEVMODE(HANDLE hdm) + { + bool b = false; + if (hdm != NULL) + { + DEVMODE* pdm = (DEVMODE*)::GlobalLock(hdm); + b = CopyFromDEVMODE(pdm); + ::GlobalUnlock(hdm); + } + return b; + } + + HANDLE CopyToHDEVMODE() + { + if ((m_hDevMode == NULL) || (m_pDevMode == NULL)) + return NULL; + int nSize = m_pDevMode->dmSize + m_pDevMode->dmDriverExtra; + HANDLE h = ::GlobalAlloc(GMEM_MOVEABLE, nSize); + if (h != NULL) + { + void* p = ::GlobalLock(h); + SecureHelper::memcpy_x(p, nSize, m_pDevMode, nSize); + ::GlobalUnlock(h); + } + return h; + } + + // If this devmode was for another printer, this will create a new devmode + // based on the existing devmode, but retargeted at the new printer + bool UpdateForNewPrinter(HANDLE hPrinter) + { + bool bRet = false; + LONG nLen = ::DocumentProperties(NULL, hPrinter, NULL, NULL, NULL, 0); + CTempBuffer buff; + DEVMODE* pdm = buff.AllocateBytes(nLen); + if(pdm != NULL) + { + memset(pdm, 0, nLen); + LONG l = ::DocumentProperties(NULL, hPrinter, NULL, pdm, m_pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER); + if (l == IDOK) + bRet = CopyFromDEVMODE(pdm); + } + + return bRet; + } + + bool DocumentProperties(HANDLE hPrinter, HWND hWnd = NULL) + { + CPrinterInfo<1> pi; + pi.GetPrinterInfo(hPrinter); + if (hWnd == NULL) + hWnd = ::GetActiveWindow(); + + bool bRet = false; + LONG nLen = ::DocumentProperties(hWnd, hPrinter, pi.m_pi->pName, NULL, NULL, 0); + CTempBuffer buff; + DEVMODE* pdm = buff.AllocateBytes(nLen); + if(pdm != NULL) + { + memset(pdm, 0, nLen); + LONG l = ::DocumentProperties(hWnd, hPrinter, pi.m_pi->pName, pdm, m_pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER | DM_PROMPT); + if (l == IDOK) + bRet = CopyFromDEVMODE(pdm); + } + + return bRet; + } + + operator HANDLE() const { return m_hDevMode; } + + operator DEVMODE*() const { return m_pDevMode; } + +// Implementation + void Cleanup() + { + if (m_hDevMode != NULL) + { + ::GlobalUnlock(m_hDevMode); + if(t_bManaged) + ::GlobalFree(m_hDevMode); + m_hDevMode = NULL; + } + } +}; + +typedef CDevModeT CDevModeHandle; +typedef CDevModeT CDevMode; + + +/////////////////////////////////////////////////////////////////////////////// +// CPrinterDC + +class CPrinterDC : public CDC +{ +public: +// Constructors/destructor + CPrinterDC() + { + CPrinter printer; + printer.OpenDefaultPrinter(); + Attach(printer.CreatePrinterDC()); + ATLASSERT(m_hDC != NULL); + } + + CPrinterDC(HANDLE hPrinter, const DEVMODE* pdm = NULL) + { + CPrinterHandle p; + p.Attach(hPrinter); + Attach(p.CreatePrinterDC(pdm)); + ATLASSERT(m_hDC != NULL); + } + + ~CPrinterDC() + { + DeleteDC(); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CPrintJob - Wraps a set of tasks for a specific printer (StartDoc/EndDoc) +// Handles aborting, background printing + +// Defines callbacks used by CPrintJob (not a COM interface) +class ATL_NO_VTABLE IPrintJobInfo +{ +public: + virtual void BeginPrintJob(HDC hDC) = 0; // allocate handles needed, etc. + virtual void EndPrintJob(HDC hDC, bool bAborted) = 0; // free handles, etc. + virtual void PrePrintPage(UINT nPage, HDC hDC) = 0; + virtual bool PrintPage(UINT nPage, HDC hDC) = 0; + virtual void PostPrintPage(UINT nPage, HDC hDC) = 0; + // If you want per page devmodes, return the DEVMODE* to use for nPage. + // You can optimize by only returning a new DEVMODE* when it is different + // from the one for nLastPage, otherwise return NULL. + // When nLastPage==0, the current DEVMODE* will be the default passed to + // StartPrintJob. + // Note: During print preview, nLastPage will always be "0". + virtual DEVMODE* GetNewDevModeForPage(UINT nLastPage, UINT nPage) = 0; + virtual bool IsValidPage(UINT nPage) = 0; +}; + +// Provides a default implementatin for IPrintJobInfo +// Typically, MI'd into a document or view class +class ATL_NO_VTABLE CPrintJobInfo : public IPrintJobInfo +{ +public: + virtual void BeginPrintJob(HDC /*hDC*/) // allocate handles needed, etc + { + } + + virtual void EndPrintJob(HDC /*hDC*/, bool /*bAborted*/) // free handles, etc + { + } + + virtual void PrePrintPage(UINT /*nPage*/, HDC hDC) + { + m_nPJState = ::SaveDC(hDC); + } + + virtual bool PrintPage(UINT /*nPage*/, HDC /*hDC*/) = 0; + + virtual void PostPrintPage(UINT /*nPage*/, HDC hDC) + { + RestoreDC(hDC, m_nPJState); + } + + virtual DEVMODE* GetNewDevModeForPage(UINT /*nLastPage*/, UINT /*nPage*/) + { + return NULL; + } + + virtual bool IsValidPage(UINT /*nPage*/) + { + return true; + } + +// Implementation - data + int m_nPJState; +}; + + +class CPrintJob +{ +public: +// Data members + CPrinterHandle m_printer; + IPrintJobInfo* m_pInfo; + DEVMODE* m_pDefDevMode; + DOCINFO m_docinfo; + int m_nJobID; + bool m_bCancel; + bool m_bComplete; + unsigned long m_nStartPage; + unsigned long m_nEndPage; + +// Constructor/destructor + CPrintJob() : m_nJobID(0), m_bCancel(false), m_bComplete(true) + { } + + ~CPrintJob() + { + ATLASSERT(IsJobComplete()); // premature destruction? + } + +// Operations + bool IsJobComplete() const + { + return m_bComplete; + } + + bool StartPrintJob(bool bBackground, HANDLE hPrinter, DEVMODE* pDefaultDevMode, + IPrintJobInfo* pInfo, LPCTSTR lpszDocName, + unsigned long nStartPage, unsigned long nEndPage, + bool bPrintToFile = false, LPCTSTR lpstrOutputFile = NULL) + { + ATLASSERT(m_bComplete); // previous job not done yet? + if (pInfo == NULL) + return false; + + memset(&m_docinfo, 0, sizeof(m_docinfo)); + m_docinfo.cbSize = sizeof(m_docinfo); + m_docinfo.lpszDocName = lpszDocName; + m_pInfo = pInfo; + m_nStartPage = nStartPage; + m_nEndPage = nEndPage; + m_printer.Attach(hPrinter); + m_pDefDevMode = pDefaultDevMode; + m_bComplete = false; + + if(bPrintToFile) + m_docinfo.lpszOutput = (lpstrOutputFile != NULL) ? lpstrOutputFile : _T("FILE:"); + + if (!bBackground) + { + m_bComplete = true; + return StartHelper(); + } + + // Create a thread and return + DWORD dwThreadID = 0; +#if !defined(_ATL_MIN_CRT) && defined(_MT) + HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, (UINT (WINAPI*)(void*))StartProc, this, 0, (UINT*)&dwThreadID); +#else + HANDLE hThread = ::CreateThread(NULL, 0, StartProc, (void*)this, 0, &dwThreadID); +#endif + if (hThread == NULL) + return false; + + ::CloseHandle(hThread); + + return true; + } + +// Implementation + static DWORD WINAPI StartProc(void* p) + { + CPrintJob* pThis = (CPrintJob*)p; + pThis->StartHelper(); + pThis->m_bComplete = true; + return 0; + } + + bool StartHelper() + { + CDC dcPrinter; + dcPrinter.Attach(m_printer.CreatePrinterDC(m_pDefDevMode)); + if (dcPrinter.IsNull()) + return false; + + m_nJobID = ::StartDoc(dcPrinter, &m_docinfo); + if (m_nJobID <= 0) + return false; + + m_pInfo->BeginPrintJob(dcPrinter); + + // print all the pages now + unsigned long nLastPage = 0; + for (unsigned long nPage = m_nStartPage; nPage <= m_nEndPage; nPage++) + { + if (!m_pInfo->IsValidPage(nPage)) + break; + DEVMODE* pdm = m_pInfo->GetNewDevModeForPage(nLastPage, nPage); + if (pdm != NULL) + dcPrinter.ResetDC(pdm); + dcPrinter.StartPage(); + m_pInfo->PrePrintPage(nPage, dcPrinter); + if (!m_pInfo->PrintPage(nPage, dcPrinter)) + m_bCancel = true; + m_pInfo->PostPrintPage(nPage, dcPrinter); + dcPrinter.EndPage(); + if (m_bCancel) + break; + nLastPage = nPage; + } + + m_pInfo->EndPrintJob(dcPrinter, m_bCancel); + if (m_bCancel) + ::AbortDoc(dcPrinter); + else + ::EndDoc(dcPrinter); + m_nJobID = 0; + return true; + } + + // Cancels a print job. Can be called asynchronously. + void CancelPrintJob() + { + m_bCancel = true; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CPrintPreview - Adds print preview support to an existing window + +class CPrintPreview +{ +public: +// Data members + IPrintJobInfo* m_pInfo; + CPrinterHandle m_printer; + CEnhMetaFile m_meta; + DEVMODE* m_pDefDevMode; + DEVMODE* m_pCurDevMode; + SIZE m_sizeCurPhysOffset; + +// Constructor + CPrintPreview() : m_pInfo(NULL), m_pDefDevMode(NULL), m_pCurDevMode(NULL) + { + m_sizeCurPhysOffset.cx = 0; + m_sizeCurPhysOffset.cy = 0; + } + +// Operations + void SetPrintPreviewInfo(HANDLE hPrinter, DEVMODE* pDefaultDevMode, IPrintJobInfo* pji) + { + m_printer.Attach(hPrinter); + m_pDefDevMode = pDefaultDevMode; + m_pInfo = pji; + m_nCurPage = 0; + m_pCurDevMode = NULL; + } + + void SetEnhMetaFile(HENHMETAFILE hEMF) + { + m_meta = hEMF; + } + + void SetPage(int nPage) + { + if (!m_pInfo->IsValidPage(nPage)) + return; + m_nCurPage = nPage; + m_pCurDevMode = m_pInfo->GetNewDevModeForPage(0, nPage); + if (m_pCurDevMode == NULL) + m_pCurDevMode = m_pDefDevMode; + CDC dcPrinter = m_printer.CreatePrinterDC(m_pCurDevMode); + + int iWidth = dcPrinter.GetDeviceCaps(PHYSICALWIDTH); + int iHeight = dcPrinter.GetDeviceCaps(PHYSICALHEIGHT); + int nLogx = dcPrinter.GetDeviceCaps(LOGPIXELSX); + int nLogy = dcPrinter.GetDeviceCaps(LOGPIXELSY); + + RECT rcMM = { 0, 0, ::MulDiv(iWidth, 2540, nLogx), ::MulDiv(iHeight, 2540, nLogy) }; + + m_sizeCurPhysOffset.cx = dcPrinter.GetDeviceCaps(PHYSICALOFFSETX); + m_sizeCurPhysOffset.cy = dcPrinter.GetDeviceCaps(PHYSICALOFFSETY); + + CEnhMetaFileDC dcMeta(dcPrinter, &rcMM); + m_pInfo->PrePrintPage(nPage, dcMeta); + m_pInfo->PrintPage(nPage, dcMeta); + m_pInfo->PostPrintPage(nPage, dcMeta); + m_meta.Attach(dcMeta.Close()); + } + + void GetPageRect(RECT& rc, LPRECT prc) + { + int x1 = rc.right-rc.left; + int y1 = rc.bottom - rc.top; + if ((x1 < 0) || (y1 < 0)) + return; + + CEnhMetaFileInfo emfinfo(m_meta); + ENHMETAHEADER* pmh = emfinfo.GetEnhMetaFileHeader(); + + // Compute whether we are OK vertically or horizontally + int x2 = pmh->szlDevice.cx; + int y2 = pmh->szlDevice.cy; + int y1p = MulDiv(x1, y2, x2); + int x1p = MulDiv(y1, x2, y2); + ATLASSERT((x1p <= x1) || (y1p <= y1)); + if (x1p <= x1) + { + prc->left = rc.left + (x1 - x1p) / 2; + prc->right = prc->left + x1p; + prc->top = rc.top; + prc->bottom = rc.bottom; + } + else + { + prc->left = rc.left; + prc->right = rc.right; + prc->top = rc.top + (y1 - y1p) / 2; + prc->bottom = prc->top + y1p; + } + } + +// Painting helpers + void DoPaint(CDCHandle dc) + { + // this one is not used + } + + void DoPaint(CDCHandle dc, RECT& rc) + { + CEnhMetaFileInfo emfinfo(m_meta); + ENHMETAHEADER* pmh = emfinfo.GetEnhMetaFileHeader(); + int nOffsetX = MulDiv(m_sizeCurPhysOffset.cx, rc.right-rc.left, pmh->szlDevice.cx); + int nOffsetY = MulDiv(m_sizeCurPhysOffset.cy, rc.bottom-rc.top, pmh->szlDevice.cy); + + dc.OffsetWindowOrg(-nOffsetX, -nOffsetY); + dc.PlayMetaFile(m_meta, &rc); + } + +// Implementation - data + int m_nCurPage; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CPrintPreviewWindow - Implements a print preview window + +template +class ATL_NO_VTABLE CPrintPreviewWindowImpl : public ATL::CWindowImpl, public CPrintPreview +{ +public: + DECLARE_WND_CLASS_EX(NULL, CS_VREDRAW | CS_HREDRAW, -1) + + enum { m_cxOffset = 10, m_cyOffset = 10 }; + +// Constructor + CPrintPreviewWindowImpl() : m_nMaxPage(0), m_nMinPage(0) + { } + +// Operations + void SetPrintPreviewInfo(HANDLE hPrinter, DEVMODE* pDefaultDevMode, + IPrintJobInfo* pji, int nMinPage, int nMaxPage) + { + CPrintPreview::SetPrintPreviewInfo(hPrinter, pDefaultDevMode, pji); + m_nMinPage = nMinPage; + m_nMaxPage = nMaxPage; + } + + bool NextPage() + { + if (m_nCurPage == m_nMaxPage) + return false; + SetPage(m_nCurPage + 1); + Invalidate(); + return true; + } + + bool PrevPage() + { + if (m_nCurPage == m_nMinPage) + return false; + if (m_nCurPage == 0) + return false; + SetPage(m_nCurPage - 1); + Invalidate(); + return true; + } + +// Message map and handlers + BEGIN_MSG_MAP(CPrintPreviewWindowImpl) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd) + MESSAGE_HANDLER(WM_PAINT, OnPaint) + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) + END_MSG_MAP() + + LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return 1; // no need for the background + } + + LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + RECT rc = { 0 }; + + if(wParam != NULL) + { + pT->DoPrePaint((HDC)wParam, rc); + pT->DoPaint((HDC)wParam, rc); + } + else + { + CPaintDC dc(m_hWnd); + pT->DoPrePaint(dc.m_hDC, rc); + pT->DoPaint(dc.m_hDC, rc); + } + + return 0; + } + +// Painting helper + void DoPrePaint(CDCHandle dc, RECT& rc) + { + RECT rcClient = { 0 }; + GetClientRect(&rcClient); + RECT rcArea = rcClient; + T* pT = static_cast(this); + pT; // avoid level 4 warning + ::InflateRect(&rcArea, -pT->m_cxOffset, -pT->m_cyOffset); + if (rcArea.left > rcArea.right) + rcArea.right = rcArea.left; + if (rcArea.top > rcArea.bottom) + rcArea.bottom = rcArea.top; + GetPageRect(rcArea, &rc); + CRgn rgn1, rgn2; + rgn1.CreateRectRgnIndirect(&rc); + rgn2.CreateRectRgnIndirect(&rcClient); + rgn2.CombineRgn(rgn1, RGN_DIFF); + dc.SelectClipRgn(rgn2); + dc.FillRect(&rcClient, COLOR_BTNSHADOW); + dc.SelectClipRgn(NULL); + dc.FillRect(&rc, (HBRUSH)::GetStockObject(WHITE_BRUSH)); + } + +// Implementation - data + int m_nMinPage; + int m_nMaxPage; +}; + + +class CPrintPreviewWindow : public CPrintPreviewWindowImpl +{ +public: + DECLARE_WND_CLASS_EX(_T("WTL_PrintPreview"), CS_VREDRAW | CS_HREDRAW, -1) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CZoomPrintPreviewWindowImpl - Implements print preview window with zooming + +#ifdef __ATLSCRL_H__ + +template +class ATL_NO_VTABLE CZoomPrintPreviewWindowImpl : public CPrintPreviewWindowImpl< T, TBase, TWinTraits >, public CZoomScrollImpl< T > +{ +public: + bool m_bSized; + + CZoomPrintPreviewWindowImpl() + { + SetScrollExtendedStyle(SCRL_DISABLENOSCROLL); + InitZoom(); + } + + // should be called to reset data members before recreating window + void InitZoom() + { + m_bSized = false; + m_nZoomMode = ZOOMMODE_OFF; + m_fZoomScaleMin = 1.0; + m_fZoomScale = 1.0; + } + + BEGIN_MSG_MAP(CZoomPrintPreviewWindowImpl) + MESSAGE_HANDLER(WM_SETCURSOR, CZoomScrollImpl< T >::OnSetCursor) + MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll) + MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll) + MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel) +#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) + MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel) +#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) + MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange) + MESSAGE_HANDLER(WM_LBUTTONDOWN, CZoomScrollImpl< T >::OnLButtonDown) + MESSAGE_HANDLER(WM_MOUSEMOVE, CZoomScrollImpl< T >::OnMouseMove) + MESSAGE_HANDLER(WM_LBUTTONUP, CZoomScrollImpl< T >::OnLButtonUp) + MESSAGE_HANDLER(WM_CAPTURECHANGED, CZoomScrollImpl< T >::OnCaptureChanged) + MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd) + MESSAGE_HANDLER(WM_PAINT, OnPaint) + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) + ALT_MSG_MAP(1) + COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp) + COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown) + COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop) + COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom) + COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft) + COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight) + COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft) + COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight) + END_MSG_MAP() + + LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + SIZE sizeClient = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)}; + POINT ptOffset = m_ptOffset; + SIZE sizeAll = m_sizeAll; + SetScrollSize(sizeClient); + if(sizeAll.cx > 0) + ptOffset.x = ::MulDiv(ptOffset.x, m_sizeAll.cx, sizeAll.cx); + if(sizeAll.cy > 0) + ptOffset.y = ::MulDiv(ptOffset.y, m_sizeAll.cy, sizeAll.cy); + SetScrollOffset(ptOffset); + CScrollImpl< T >::OnSize(uMsg, wParam, lParam, bHandled); + if(!m_bSized) + { + m_bSized = true; + T* pT = static_cast(this); + pT->ShowScrollBar(SB_HORZ, TRUE); + pT->ShowScrollBar(SB_VERT, TRUE); + } + return 0; + } + + LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return 1; + } + + LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + RECT rc = { 0 }; + + if(wParam != NULL) + { + CDCHandle dc = (HDC)wParam; + int nMapModeSav = dc.GetMapMode(); + dc.SetMapMode(MM_ANISOTROPIC); + SIZE szWindowExt = { 0, 0 }; + dc.SetWindowExt(m_sizeLogAll, &szWindowExt); + SIZE szViewportExt = { 0, 0 }; + dc.SetViewportExt(m_sizeAll, &szViewportExt); + POINT ptViewportOrg = { 0, 0 }; + dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewportOrg); + + pT->DoPrePaint(dc, rc); + pT->DoPaint(dc, rc); + + dc.SetMapMode(nMapModeSav); + dc.SetWindowExt(szWindowExt); + dc.SetViewportExt(szViewportExt); + dc.SetViewportOrg(ptViewportOrg); + } + else + { + CPaintDC dc(pT->m_hWnd); + pT->PrepareDC(dc.m_hDC); + pT->DoPrePaint(dc.m_hDC, rc); + pT->DoPaint(dc.m_hDC, rc); + } + + return 0; + } + + // Painting helpers + void DoPaint(CDCHandle dc) + { + // this one is not used + } + + void DoPrePaint(CDCHandle dc, RECT& rc) + { + RECT rcClient; + GetClientRect(&rcClient); + RECT rcArea = rcClient; + T* pT = static_cast(this); + pT; // avoid level 4 warning + ::InflateRect(&rcArea, -pT->m_cxOffset, -pT->m_cyOffset); + if (rcArea.left > rcArea.right) + rcArea.right = rcArea.left; + if (rcArea.top > rcArea.bottom) + rcArea.bottom = rcArea.top; + GetPageRect(rcArea, &rc); + HBRUSH hbrOld = dc.SelectBrush(::GetSysColorBrush(COLOR_BTNSHADOW)); + dc.PatBlt(rcClient.left, rcClient.top, rc.left - rcClient.left, rcClient.bottom - rcClient.top, PATCOPY); + dc.PatBlt(rc.left, rcClient.top, rc.right - rc.left, rc.top - rcClient.top, PATCOPY); + dc.PatBlt(rc.right, rcClient.top, rcClient.right - rc.right, rcClient.bottom - rcClient.top, PATCOPY); + dc.PatBlt(rc.left, rc.bottom, rc.right - rc.left, rcClient.bottom - rc.bottom, PATCOPY); + dc.SelectBrush((HBRUSH)::GetStockObject(WHITE_BRUSH)); + dc.PatBlt(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); + dc.SelectBrush(::GetSysColorBrush(COLOR_3DDKSHADOW)); + dc.PatBlt(rc.right, rc.top + 4, 4, rc.bottom - rc.top, PATCOPY); + dc.PatBlt(rc.left + 4, rc.bottom, rc.right - rc.left, 4, PATCOPY); + dc.SelectBrush(hbrOld); + } + + void DoPaint(CDCHandle dc, RECT& rc) + { + CEnhMetaFileInfo emfinfo(m_meta); + ENHMETAHEADER* pmh = emfinfo.GetEnhMetaFileHeader(); + int nOffsetX = MulDiv(m_sizeCurPhysOffset.cx, rc.right-rc.left, pmh->szlDevice.cx); + int nOffsetY = MulDiv(m_sizeCurPhysOffset.cy, rc.bottom-rc.top, pmh->szlDevice.cy); + + dc.OffsetWindowOrg(-nOffsetX, -nOffsetY); + dc.PlayMetaFile(m_meta, &rc); + } +}; + +class CZoomPrintPreviewWindow : public CZoomPrintPreviewWindowImpl +{ +public: + DECLARE_WND_CLASS_EX(_T("WTL_ZoomPrintPreview"), CS_VREDRAW | CS_HREDRAW, -1) +}; + +#endif // __ATLSCRL_H__ + +}; // namespace WTL + +#endif // __ATLPRINT_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlres.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlres.h new file mode 100644 index 0000000000..22fb3e6fdd --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlres.h @@ -0,0 +1,263 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLRES_H__ +#define __ATLRES_H__ + +#pragma once + +#if defined(_WIN32_WCE) && !defined(__ATLRESCE_H__) + #error Use atlresCE.h instead of atlres.h for Windows CE +#endif + + +#ifdef RC_INVOKED +#ifndef _INC_WINDOWS + + #define _INC_WINDOWS + + #ifndef _WIN32_WCE + #define VS_VERSION_INFO 1 + + #ifdef APSTUDIO_INVOKED + #define APSTUDIO_HIDDEN_SYMBOLS // Ignore following symbols + #endif // APSTUDIO_INVOKED + + #ifndef WINVER + #define WINVER 0x0400 // default to Windows Version 4.0 + #endif // !WINVER + + #include + + // operation messages sent to DLGINIT + #define LB_ADDSTRING (WM_USER+1) + #define CB_ADDSTRING (WM_USER+3) + #endif // !_WIN32_WCE + + #ifdef APSTUDIO_INVOKED + #undef APSTUDIO_HIDDEN_SYMBOLS + #endif // APSTUDIO_INVOKED + + #ifdef IDC_STATIC + #undef IDC_STATIC + #endif // IDC_STATIC + #define IDC_STATIC (-1) + +#endif // !_INC_WINDOWS +#endif // RC_INVOKED + +#ifdef APSTUDIO_INVOKED + #define APSTUDIO_HIDDEN_SYMBOLS +#endif // APSTUDIO_INVOKED + +/////////////////////////////////////////////////////////////////////////////// +// ATL resource types + +#ifndef RC_INVOKED + #define RT_DLGINIT MAKEINTRESOURCE(240) + #define RT_TOOLBAR MAKEINTRESOURCE(241) +#endif // RC_INVOKED + +/////////////////////////////////////////////////////////////////////////////// + +#ifdef APSTUDIO_INVOKED + #undef APSTUDIO_HIDDEN_SYMBOLS +#endif // APSTUDIO_INVOKED + +/////////////////////////////////////////////////////////////////////////////// +// Standard window components + +#define ID_SEPARATOR 0 // special separator value +#define ID_DEFAULT_PANE 0 // default status bar pane + +#ifndef RC_INVOKED // code only +// standard control bars (IDW = window ID) + #define ATL_IDW_TOOLBAR 0xE800 // main Toolbar for window + #define ATL_IDW_STATUS_BAR 0xE801 // Status bar window + #define ATL_IDW_COMMAND_BAR 0xE802 // Command bar window + +// parts of a frame window + #define ATL_IDW_CLIENT 0xE900 + #define ATL_IDW_PANE_FIRST 0xE900 // first pane (256 max) + #define ATL_IDW_PANE_LAST 0xE9FF + #define ATL_IDW_HSCROLL_FIRST 0xEA00 // first Horz scrollbar (16 max) + #define ATL_IDW_VSCROLL_FIRST 0xEA10 // first Vert scrollbar (16 max) + + #define ATL_IDW_SIZE_BOX 0xEA20 // size box for splitters + #define ATL_IDW_PANE_SAVE 0xEA21 // to shift ATL_IDW_PANE_FIRST + +// bands for a rebar + #define ATL_IDW_BAND_FIRST 0xEB00 + #define ATL_IDW_BAND_LAST 0xEBFF +#endif // !RC_INVOKED + +/////////////////////////////////////////////////////////////////////////////// +// Standard Commands + +// File commands +#define ID_FILE_NEW 0xE100 +#define ID_FILE_OPEN 0xE101 +#define ID_FILE_CLOSE 0xE102 +#define ID_FILE_SAVE 0xE103 +#define ID_FILE_SAVE_AS 0xE104 +#define ID_FILE_PAGE_SETUP 0xE105 +#define ID_FILE_PRINT_SETUP 0xE106 +#define ID_FILE_PRINT 0xE107 +#define ID_FILE_PRINT_DIRECT 0xE108 +#define ID_FILE_PRINT_PREVIEW 0xE109 +#define ID_FILE_UPDATE 0xE10A +#define ID_FILE_SAVE_COPY_AS 0xE10B +#define ID_FILE_SEND_MAIL 0xE10C + +#define ID_FILE_MRU_FIRST 0xE110 +#define ID_FILE_MRU_FILE1 0xE110 // range - 16 max +#define ID_FILE_MRU_FILE2 0xE111 +#define ID_FILE_MRU_FILE3 0xE112 +#define ID_FILE_MRU_FILE4 0xE113 +#define ID_FILE_MRU_FILE5 0xE114 +#define ID_FILE_MRU_FILE6 0xE115 +#define ID_FILE_MRU_FILE7 0xE116 +#define ID_FILE_MRU_FILE8 0xE117 +#define ID_FILE_MRU_FILE9 0xE118 +#define ID_FILE_MRU_FILE10 0xE119 +#define ID_FILE_MRU_FILE11 0xE11A +#define ID_FILE_MRU_FILE12 0xE11B +#define ID_FILE_MRU_FILE13 0xE11C +#define ID_FILE_MRU_FILE14 0xE11D +#define ID_FILE_MRU_FILE15 0xE11E +#define ID_FILE_MRU_FILE16 0xE11F +#define ID_FILE_MRU_LAST 0xE11F + +// Edit commands +#define ID_EDIT_CLEAR 0xE120 +#define ID_EDIT_CLEAR_ALL 0xE121 +#define ID_EDIT_COPY 0xE122 +#define ID_EDIT_CUT 0xE123 +#define ID_EDIT_FIND 0xE124 +#define ID_EDIT_PASTE 0xE125 +#define ID_EDIT_PASTE_LINK 0xE126 +#define ID_EDIT_PASTE_SPECIAL 0xE127 +#define ID_EDIT_REPEAT 0xE128 +#define ID_EDIT_REPLACE 0xE129 +#define ID_EDIT_SELECT_ALL 0xE12A +#define ID_EDIT_UNDO 0xE12B +#define ID_EDIT_REDO 0xE12C + +// Window commands +#define ID_WINDOW_NEW 0xE130 +#define ID_WINDOW_ARRANGE 0xE131 +#define ID_WINDOW_CASCADE 0xE132 +#define ID_WINDOW_TILE_HORZ 0xE133 +#define ID_WINDOW_TILE_VERT 0xE134 +#define ID_WINDOW_SPLIT 0xE135 +#ifndef RC_INVOKED // code only + #define ATL_IDM_WINDOW_FIRST 0xE130 + #define ATL_IDM_WINDOW_LAST 0xE13F + #define ATL_IDM_FIRST_MDICHILD 0xFF00 // window list starts here + #define ATL_IDM_LAST_MDICHILD 0xFFFD +#endif // !RC_INVOKED +// TabView +#define ID_WINDOW_TABFIRST 0xFF00 // = ATL_IDM_FIRST_MDICHILD +#define ID_WINDOW_TABLAST 0xFFFD +#define ID_WINDOW_SHOWTABLIST 0xFFFE + +// Help and App commands +#define ID_APP_ABOUT 0xE140 +#define ID_APP_EXIT 0xE141 +#define ID_HELP_INDEX 0xE142 +#define ID_HELP_FINDER 0xE143 +#define ID_HELP_USING 0xE144 +#define ID_CONTEXT_HELP 0xE145 // shift-F1 +// special commands for processing help +#define ID_HELP 0xE146 // first attempt for F1 +#define ID_DEFAULT_HELP 0xE147 // last attempt + +// Misc +#define ID_NEXT_PANE 0xE150 +#define ID_PREV_PANE 0xE151 +#define ID_PANE_CLOSE 0xE152 + +// Format +#define ID_FORMAT_FONT 0xE160 + +// Scroll +#define ID_SCROLL_UP 0xE170 +#define ID_SCROLL_DOWN 0xE171 +#define ID_SCROLL_PAGE_UP 0xE172 +#define ID_SCROLL_PAGE_DOWN 0xE173 +#define ID_SCROLL_TOP 0xE174 +#define ID_SCROLL_BOTTOM 0xE175 +#define ID_SCROLL_LEFT 0xE176 +#define ID_SCROLL_RIGHT 0xE177 +#define ID_SCROLL_PAGE_LEFT 0xE178 +#define ID_SCROLL_PAGE_RIGHT 0xE179 +#define ID_SCROLL_ALL_LEFT 0xE17A +#define ID_SCROLL_ALL_RIGHT 0xE17B + +// OLE commands +#define ID_OLE_INSERT_NEW 0xE200 +#define ID_OLE_EDIT_LINKS 0xE201 +#define ID_OLE_EDIT_CONVERT 0xE202 +#define ID_OLE_EDIT_CHANGE_ICON 0xE203 +#define ID_OLE_EDIT_PROPERTIES 0xE204 +#define ID_OLE_VERB_FIRST 0xE210 // range - 16 max +#ifndef RC_INVOKED // code only + #define ID_OLE_VERB_LAST 0xE21F +#endif // !RC_INVOKED + +// View commands (same number used as IDW used for toolbar and status bar) +#define ID_VIEW_TOOLBAR 0xE800 +#define ID_VIEW_STATUS_BAR 0xE801 +#define ID_VIEW_REFRESH 0xE803 +#define ID_VIEW_RIBBON 0xE804 // Ribbon + +/////////////////////////////////////////////////////////////////////////////// +// Standard control IDs + +#ifdef IDC_STATIC + #undef IDC_STATIC +#endif // IDC_STATIC +#define IDC_STATIC (-1) // all static controls + +/////////////////////////////////////////////////////////////////////////////// +// Standard string error/warnings + +// idle status bar message +#define ATL_IDS_IDLEMESSAGE 0xE001 + +#ifndef RC_INVOKED // code only + #define ATL_IDS_SCFIRST 0xEF00 +#endif // !RC_INVOKED + +#define ATL_IDS_SCSIZE 0xEF00 +#define ATL_IDS_SCMOVE 0xEF01 +#define ATL_IDS_SCMINIMIZE 0xEF02 +#define ATL_IDS_SCMAXIMIZE 0xEF03 +#define ATL_IDS_SCNEXTWINDOW 0xEF04 +#define ATL_IDS_SCPREVWINDOW 0xEF05 +#define ATL_IDS_SCCLOSE 0xEF06 +#define ATL_IDS_SCRESTORE 0xEF12 +#define ATL_IDS_SCTASKLIST 0xEF13 + +#define ATL_IDS_MDICHILD 0xEF1F +#define ATL_IDS_MRU_FILE 0xEFDA + +/////////////////////////////////////////////////////////////////////////////// +// Misc. control IDs + +// Property Sheet control id's (determined with Spy++) +#define ID_APPLY_NOW 0x3021 +#define ID_WIZBACK 0x3023 +#define ID_WIZNEXT 0x3024 +#define ID_WIZFINISH 0x3025 +#define ATL_IDC_TAB_CONTROL 0x3020 + +#endif // __ATLRES_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlresce.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlresce.h new file mode 100644 index 0000000000..3b2b93388f --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlresce.h @@ -0,0 +1,93 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLRESCE_H__ +#define __ATLRESCE_H__ + +#pragma once + +#ifndef _WIN32_WCE + #error atlresCE.h is only for Windows CE +#endif + + +#ifdef RC_INVOKED +#ifndef _INC_WINDOWS + + #define VS_VERSION_INFO 1 + + #ifdef APSTUDIO_INVOKED + #define APSTUDIO_HIDDEN_SYMBOLS // Ignore following symbols + #endif // APSTUDIO_INVOKED + + #ifndef WINVER + #define WINVER 0x0400 // default to Windows Version 4.0 + #endif // !WINVER + + #if !defined(WCEOLE_ENABLE_DIALOGEX) + #define DIALOGEX DIALOG DISCARDABLE + #endif + + #include + #define SHMENUBAR RCDATA + + #if defined(SHELLSDK_MODULES_AYGSHELL) + #include + #else + #define NOMENU 0xFFFF + #define IDS_SHNEW 1 + #define IDM_SHAREDNEW 10 + #define IDM_SHAREDNEWDEFAULT 11 + #endif + #ifndef I_IMAGENONE + #define I_IMAGENONE (-2) + #endif + + #include + +#endif // !_INC_WINDOWS +#endif // RC_INVOKED + +#include "atlres.h" + +#ifdef APSTUDIO_INVOKED + #undef APSTUDIO_HIDDEN_SYMBOLS +#endif // APSTUDIO_INVOKED + +// Visual Studio dialog editor bug fix +#ifndef DS_FIXEDSYS + #define DS_FIXEDSYS 0 +#endif + +#define IDC_INFOSTATIC 0xFFFE // == IDC_STATIC -1 + +/////////////////////////////////////////////////////////////////////////////// +// Smartphone and PPC 2005 Resource IDs + +// Command and associated string resource IDs +#define ID_MENU_OK 0xE790 +#define ID_MENU_CANCEL 0xE791 +#define ID_MENU 0xE792 +#define ID_ACTION 0xE793 +#define ID_VIEW_FULLSCREEN 0xE802 + +// MenuBar resource IDs +#define ATL_IDM_MENU_DONE 0xE701 +#define ATL_IDM_MENU_CANCEL 0xE702 +#define ATL_IDM_MENU_DONECANCEL 0xE703 + +// Default device MenuBar control ID and MenuBar resource ID +#define ATL_IDW_MENU_BAR 0xE802 + +// SmartPhone spinned controls ID offset for CSpinCtrl +#define ATL_IDW_SPIN_ID 9999 + +#endif // __ATLRESCE_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlribbon.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlribbon.h new file mode 100644 index 0000000000..2b21026441 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlribbon.h @@ -0,0 +1,3446 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLRIBBON_H__ +#define __ATLRIBBON_H__ + +#pragma once + +#if (_MSC_VER < 1500) + #error atlribbon.h requires Visual C++ 2008 compiler or higher +#endif + +#ifndef _UNICODE + #error atlribbon.h requires the Unicode character set +#endif + +#if !defined(NTDDI_WIN7) || (NTDDI_VERSION < NTDDI_WIN7) + #error atlribbon.h requires the Windows 7 SDK or higher +#endif + +#ifdef _WIN32_WCE + #error atlribbon.h is not supported on Windows CE +#endif + +#ifndef __ATLAPP_H__ + #error atlribbon.h requires atlapp.h to be included first +#endif + +#if (_ATL_VER < 0x0700) + #include + #pragma comment(lib, "shlwapi.lib") +#endif + +#include // for RecentDocumentList classes +#include // for Frame and UpdateUI classes +#include // required for atlctrlw.h +#include // for CCommandBarCtrl + +#if !defined(_WTL_USE_CSTRING) && !defined(__ATLSTR_H__) + #pragma warning(disable : 4530) // unwind semantics not enabled + #include + #pragma warning(default : 4530) +#endif + +#include +#pragma comment(lib, "dwmapi.lib") + +#include +#include +#pragma comment(lib, "propsys.lib") + +#include // for CHARFORMAT2 + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CRibbonUpdateUI : Automatic mapping of ribbon UI elements +// +// RibbonUI::Text +// RibbonUI::CharFormat +// RibbonUI::ICtrl +// RibbonUI::CtrlImpl +// RibbonUI::CommandCtrlImpl +// RibbonUI::ItemProperty +// RibbonUI::CollectionImplBase +// RibbonUI::CollectionImpl +// RibbonUI::TextCollectionImpl +// RibbonUI::ItemCollectionImpl +// RibbonUI::ComboCollectionImpl +// RibbonUI::CommandCollectionImpl +// RibbonUI::ToolbarCollectionImpl +// RibbonUI::SimpleCollectionImpl +// RibbonUI::CollectionCtrlImpl +// RibbonUI::ToolbarGalleryCtrlImpl +// RibbonUI::SimpleCollectionCtrlImpl +// RibbonUI::RecentItemsCtrlImpl +// RibbonUI::FontCtrlImpl +// RibbonUI::ColorCtrlImpl +// RibbonUI::SpinnerCtrlImpl +// +// RibbonUI::CRibbonImpl +// CRibbonImpl::CRibbonComboCtrl +// CRibbonImpl::CRibbonItemGalleryCtrl +// CRibbonImpl::CRibbonCommandGalleryCtrl +// CRibbonImpl::CRibbonToolbarGalleryCtrl +// CRibbonImpl::CRibbonSimpleComboCtrl +// CRibbonImpl::CRibbonSimpleGalleryCtrl +// CRibbonImpl::CRibbonRecentItemsCtrl +// CRibbonImpl::CRibbonColorCtrl +// CRibbonImpl::CRibbonFontCtrl +// CRibbonImpl::CRibbonSpinnerCtrl +// CRibbonImpl::CRibbonFloatSpinnerCtrl +// CRibbonImpl::CRibbonCommandCtrl +// +// CRibbonFrameWindowImplBase +// CRibbonFrameWindowImpl +// CRibbonMDIFrameWindowImpl +// CRibbonPersist +// +// Global functions: +// RibbonUI::SetPropertyVal() +// RibbonUI::GetImage() + + +// Constants + +#ifndef RIBBONUI_MAX_TEXT + #define RIBBONUI_MAX_TEXT 128 +#endif + +#define TWIPS_PER_POINT 20 // For font size + + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// CRibbonUpdateUI : Automatic mapping of ribbon UI elements + +template +class CRibbonUpdateUI : public CAutoUpdateUI +{ +public: + enum + { + UPDUI_RIBBON = 0x0080, + UPDUI_PERSIST = 0x0020 + }; + + bool IsRibbonElement(const _AtlUpdateUIMap& UIMap) + { + return (UIMap.m_wType & UPDUI_RIBBON) != 0; + } + + bool IsRibbonID(UINT nID) + { + for(int i = 0; i < m_arrUIMap.GetSize(); i++) + { + if(m_arrUIMap[i].m_nID == nID) + return IsRibbonElement(m_arrUIMap[i]); + } + + return false; + } + +// Element + bool UIAddRibbonElement(UINT nID) + { + return UIAddElement(nID); + } + + bool UIRemoveRibbonElement(UINT nID) + { + return UIRemoveElement(nID); + } + + bool UIPersistElement(UINT nID, bool bPersist = true) + { + return bPersist ? + UIAddElement(nID) : + UIRemoveElement(nID); + } + +// methods for Ribbon elements + BOOL UISetText(int nID, LPCWSTR sText, BOOL bForceUpdate = FALSE) + { + T* pT = static_cast(this); + BOOL bRes = CUpdateUIBase::UISetText(nID, sText, bForceUpdate); + if (pT->IsRibbonUI() && IsRibbonID(nID)) + bRes = SUCCEEDED(pT->InvalidateProperty(nID, UI_PKEY_Label)); + return bRes; + } + + BOOL UISetText(int nID, UINT uIdResource, BOOL bForceUpdate = FALSE) + { + CTempBuffer sText(RIBBONUI_MAX_TEXT); + return AtlLoadString(uIdResource, sText, RIBBONUI_MAX_TEXT) ? + UISetText(nID, sText, bForceUpdate) : + E_FAIL; + } + + LPCTSTR UIGetText(int nID) + { + T* pT = static_cast(this); + LPCTSTR sUI = CAutoUpdateUI::UIGetText(nID); + + // replace 'tab' by 'space' for RibbonUI elements + if (sUI && pT->IsRibbonUI() && IsRibbonID(nID) && wcschr(sUI, L'\t')) + { + static WCHAR sText[RIBBONUI_MAX_TEXT] = { 0 }; + wcscpy_s(sText, sUI); + *wcschr(sText, L'\t') = L' '; + return sText; + } + else + { + return sUI; + } + } + + BOOL UIEnable(int nID, BOOL bEnable, BOOL bForceUpdate = FALSE) + { + T* pT = static_cast(this); + BOOL bRes = CUpdateUIBase::UIEnable(nID, bEnable, bForceUpdate); + if (pT->IsRibbonUI() && IsRibbonID(nID)) + bRes = SUCCEEDED(pT->SetProperty((WORD)nID, UI_PKEY_Enabled, bEnable)); + return bRes; + } + + BOOL UISetCheck(int nID, INT nCheck, BOOL bForceUpdate = FALSE) + { + if ((nCheck == 0) || (nCheck == 1)) + return UISetCheck(nID, nCheck != 0, bForceUpdate); + else + return CUpdateUIBase::UISetCheck(nID, nCheck, bForceUpdate); + } + + BOOL UISetCheck(int nID, bool bCheck, BOOL bForceUpdate = FALSE) + { + T* pT = static_cast(this); + BOOL bRes = CUpdateUIBase::UISetCheck(nID, bCheck, bForceUpdate); + if (bRes && pT->IsRibbonUI() && IsRibbonID(nID)) + bRes = SUCCEEDED(pT->SetProperty((WORD)nID, UI_PKEY_BooleanValue, bCheck)); + return bRes; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// RibbonUI namespace +// + +namespace RibbonUI +{ + +// Minimal string allocation support for various PROPERTYKEY values +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + typedef _CSTRING_NS::CString Text; +#else + class Text : public std::wstring + { + public: + Text(std::wstring& s) : std::wstring(s) + { } + Text(LPCWSTR s) : std::wstring(s) + { } + Text() + { } + bool IsEmpty() + { + return empty(); + } + operator LPCWSTR() + { + return c_str(); + } + Text& operator =(LPCWSTR s) + { + return static_cast(std::wstring::operator =(s)); + } + }; +#endif + +// PROPERTYKEY enum and helpers +enum k_KEY +{ + // state + k_Enabled = 1, k_BooleanValue = 200, + // text properties + k_LabelDescription = 2, k_Keytip = 3, k_Label = 4, k_TooltipDescription = 5, k_TooltipTitle = 6, + // image properties + k_LargeImage = 7, k_LargeHighContrastImage = 8, k_SmallImage = 9, k_SmallHighContrastImage = 10, + // collection properties + k_ItemsSource = 101, k_Categories = 102, k_SelectedItem = 104, + // collection item properties + k_CommandId = 100, k_CategoryId = 103, k_CommandType = 105, k_ItemImage = 106, + // combo control property + k_StringValue = 202, + // spinner control properties + k_DecimalValue = 201, k_MaxValue = 203, k_MinValue, k_Increment, k_DecimalPlaces, k_FormatString, k_RepresentativeString = 208, + // font control properties + k_FontProperties = 300, k_FontProperties_Family, k_FontProperties_Size, k_FontProperties_Bold, k_FontProperties_Italic = 304, + k_FontProperties_Underline = 305, k_FontProperties_Strikethrough, k_FontProperties_VerticalPositioning, k_FontProperties_ForegroundColor = 308, + k_FontProperties_BackgroundColor = 309, k_FontProperties_ForegroundColorType, k_FontProperties_BackgroundColorType, k_FontProperties_ChangedProperties = 312, + k_FontProperties_DeltaSize = 313, + // recent items properties + k_RecentItems = 350, k_Pinned = 351, + // color control properties + k_Color = 400, k_ColorType = 401, k_ColorMode, + k_ThemeColorsCategoryLabel = 403, k_StandardColorsCategoryLabel, k_RecentColorsCategoryLabel = 405, k_AutomaticColorLabel = 406, + k_NoColorLabel = 407, k_MoreColorsLabel = 408, + k_ThemeColors = 409, k_StandardColors = 410, k_ThemeColorsTooltips = 411, k_StandardColorsTooltips = 412, + // Ribbon state + k_Viewable = 1000, k_Minimized = 1001, k_QuickAccessToolbarDock = 1002, k_ContextAvailable = 1100, + // Ribbon UI colors + k_GlobalBackgroundColor = 2000, k_GlobalHighlightColor, k_GlobalTextColor = 2002 +}; + +inline k_KEY k_(REFPROPERTYKEY key) +{ + return (k_KEY)key.fmtid.Data1; +} + +// PROPERTYKEY value assignment and specializations +// +template +HRESULT SetPropertyVal(REFPROPERTYKEY key, V val, PROPVARIANT* ppv) +{ + switch (k_(key)) + { + case k_Enabled: + case k_BooleanValue: + return InitPropVariantFromBoolean(val, ppv); + default: + return UIInitPropertyFromUInt32(key, val, ppv); + } +} + +inline HRESULT SetPropertyVal(REFPROPERTYKEY key, DOUBLE val, PROPVARIANT* ppv) +{ + return SetPropertyVal(key, (LONG)val, ppv); +} + +inline HRESULT SetPropertyVal(REFPROPERTYKEY key, IUIImage* val, PROPVARIANT* ppv) +{ + HRESULT hr = UIInitPropertyFromImage(key, val, ppv); + ATLVERIFY(val->Release() == 1); + return hr; +} + +inline HRESULT SetPropertyVal(REFPROPERTYKEY key, IUnknown* val, PROPVARIANT* ppv) +{ + return UIInitPropertyFromInterface(key, val, ppv); +} + +inline HRESULT SetPropertyVal(REFPROPERTYKEY key, IPropertyStore* val, PROPVARIANT* ppv) +{ + return UIInitPropertyFromInterface(key, val, ppv); +} + +inline HRESULT SetPropertyVal(REFPROPERTYKEY key, SAFEARRAY* val, PROPVARIANT* ppv) +{ + return UIInitPropertyFromIUnknownArray(key, val, ppv); +} + +inline HRESULT SetPropertyVal(REFPROPERTYKEY key, DECIMAL* val, PROPVARIANT* ppv) +{ + return UIInitPropertyFromDecimal(key, *val, ppv); +} + +inline HRESULT SetPropertyVal(REFPROPERTYKEY key, bool val, PROPVARIANT* ppv) +{ + return UIInitPropertyFromBoolean(key, val, ppv); +} + +inline HRESULT SetPropertyVal(REFPROPERTYKEY key, LPCWSTR val, PROPVARIANT* ppv) +{ + return UIInitPropertyFromString(key, val, ppv); +} + +// CharFormat helper struct for RibbonUI font control +// +struct CharFormat : CHARFORMAT2 +{ + // Default constructor + CharFormat() + { + cbSize = sizeof CHARFORMAT2; + Reset(); + } + + // Copy constructor + CharFormat(const CharFormat& cf) + { + CopyMemory(this, &cf, sizeof CHARFORMAT2); + } + + // Assign operator + CharFormat& operator =(const CharFormat& cf) + { + CopyMemory(this, &cf, sizeof CHARFORMAT2); + return (*this); + } + + void Reset() + { + uValue = dwMask = dwEffects = 0; + PropVariantInit(&propvar); + } + + void operator <<(IPropertyStore* pStore) + { + if (pStore == NULL) + { + ATLASSERT(FALSE); + return; + } + + static void (CharFormat::*Getk_[])(IPropertyStore*) = + { + &CharFormat::Getk_Family, + &CharFormat::Getk_FontProperties_Size, + &CharFormat::Getk_MaskEffect, + &CharFormat::Getk_MaskEffect, + &CharFormat::Getk_MaskEffect, + &CharFormat::Getk_MaskEffect, + &CharFormat::Getk_VerticalPositioning, + &CharFormat::Getk_Color, + &CharFormat::Getk_Color, + &CharFormat::Getk_ColorType, + &CharFormat::Getk_ColorType, + }; + + DWORD nProps = 0; + Reset(); + + ATLVERIFY(SUCCEEDED(pStore->GetCount(&nProps))); + for (DWORD iProp = 0; iProp < nProps; iProp++) + { + PROPERTYKEY key; + ATLVERIFY(SUCCEEDED(pStore->GetAt(iProp, &key))); + ATLASSERT(k_(key) >= k_FontProperties_Family); + + if (k_(key) <= k_FontProperties_BackgroundColorType) + (this->*Getk_[k_(key) - k_FontProperties_Family])(pStore); + } + } + + void operator >>(IPropertyStore* pStore) + { + if (pStore == NULL) + { + ATLASSERT(FALSE); + return; + } + + PutFace(pStore); + PutSize(pStore); + PutMaskEffect(CFM_BOLD, CFE_BOLD, UI_PKEY_FontProperties_Bold, pStore); + PutMaskEffect(CFM_ITALIC, CFE_ITALIC, UI_PKEY_FontProperties_Italic, pStore); + PutMaskEffect(CFM_UNDERLINE, CFE_UNDERLINE, UI_PKEY_FontProperties_Underline, pStore); + PutMaskEffect(CFM_STRIKEOUT, CFE_STRIKEOUT, UI_PKEY_FontProperties_Strikethrough, pStore); + PutVerticalPos(pStore); + PutColor(pStore); + PutBackColor(pStore); + } + +private: + PROPVARIANT propvar; + UINT uValue; + + // Getk_ functions + void Getk_Family(IPropertyStore* pStore) + { + if (SUCCEEDED(pStore->GetValue(UI_PKEY_FontProperties_Family, &propvar))) + { + PropVariantToString(propvar, szFaceName, LF_FACESIZE); + if (*szFaceName) + dwMask |= CFM_FACE; + } + } + + void Getk_FontProperties_Size(IPropertyStore* pStore) + { + if (SUCCEEDED(pStore->GetValue(UI_PKEY_FontProperties_Size, &propvar))) + { + DECIMAL decSize; + UIPropertyToDecimal(UI_PKEY_FontProperties_Size, propvar, &decSize); + DOUBLE dSize; + VarR8FromDec(&decSize, &dSize); + if (dSize > 0) + { + dwMask |= CFM_SIZE; + yHeight = (LONG)(dSize * TWIPS_PER_POINT); + } + } + } + + template + void Getk_MaskEffect(IPropertyStore* pStore) + { + if (SUCCEEDED(pStore->GetValue(key, &propvar))) + { + UIPropertyToUInt32(key, propvar, &uValue); + if ((UI_FONTPROPERTIES)uValue != UI_FONTPROPERTIES_NOTAVAILABLE) + { + dwMask |= t_dwMask; + dwEffects |= ((UI_FONTPROPERTIES) uValue == UI_FONTPROPERTIES_SET) ? t_dwEffects : 0; + } + } + } + + void Getk_VerticalPositioning(IPropertyStore* pStore) + { + if (SUCCEEDED(pStore->GetValue(UI_PKEY_FontProperties_VerticalPositioning, &propvar))) + { + UIPropertyToUInt32(UI_PKEY_FontProperties_VerticalPositioning, propvar, &uValue); + UI_FONTVERTICALPOSITION uVerticalPosition = (UI_FONTVERTICALPOSITION) uValue; + if ((uVerticalPosition != UI_FONTVERTICALPOSITION_NOTAVAILABLE)) + { + dwMask |= (CFM_SUPERSCRIPT | CFM_SUBSCRIPT); + if (uVerticalPosition != UI_FONTVERTICALPOSITION_NOTSET) + { + dwEffects |= (uVerticalPosition == UI_FONTVERTICALPOSITION_SUPERSCRIPT) ? CFE_SUPERSCRIPT : CFE_SUBSCRIPT; + } + } + } + } + + template + void Getk_Color(IPropertyStore* pStore) + { + UINT32 color; + if (SUCCEEDED(pStore->GetValue(key, &propvar))) + { + UIPropertyToUInt32(key, propvar, &color); + dwMask |= t_dwMask; + + if (t_dwMask == CFM_COLOR) + crTextColor = color; + else + crBackColor = color; + } + } + + template + void Getk_ColorType(IPropertyStore* pStore) + { + if (SUCCEEDED(pStore->GetValue(key, &propvar))) + { + UIPropertyToUInt32(key, propvar, &uValue); + if (t_type == (UI_SWATCHCOLORTYPE)uValue) + { + dwMask |= t_dwMask; + dwEffects |= t_dwEffects; + } + } + } + + // Put functions + void PutMaskEffect(WORD dwMaskVal, WORD dwEffectVal, REFPROPERTYKEY key, IPropertyStore* pStore) + { + PROPVARIANT propvar; + UI_FONTPROPERTIES uProp = UI_FONTPROPERTIES_NOTAVAILABLE; + if ((dwMask & dwMaskVal) != 0) + uProp = dwEffects & dwEffectVal ? UI_FONTPROPERTIES_SET : UI_FONTPROPERTIES_NOTSET; + SetPropertyVal(key, uProp, &propvar); + pStore->SetValue(key, propvar); + } + + void PutVerticalPos(IPropertyStore* pStore) + { + PROPVARIANT propvar; + UI_FONTVERTICALPOSITION uProp = UI_FONTVERTICALPOSITION_NOTAVAILABLE; + + if ((dwMask & CFE_SUBSCRIPT) != 0) + { + if ((dwMask & CFM_SUBSCRIPT) && (dwEffects & CFE_SUBSCRIPT)) + uProp = UI_FONTVERTICALPOSITION_SUBSCRIPT; + else + uProp = UI_FONTVERTICALPOSITION_SUPERSCRIPT; + } + else if ((dwMask & CFM_OFFSET) != 0) + { + if (yOffset > 0) + uProp = UI_FONTVERTICALPOSITION_SUPERSCRIPT; + else if (yOffset < 0) + uProp = UI_FONTVERTICALPOSITION_SUBSCRIPT; + } + + SetPropertyVal(UI_PKEY_FontProperties_VerticalPositioning, uProp, &propvar); + pStore->SetValue(UI_PKEY_FontProperties_VerticalPositioning, propvar); + } + + void PutFace(IPropertyStore* pStore) + { + PROPVARIANT propvar; + SetPropertyVal(UI_PKEY_FontProperties_Family, + dwMask & CFM_FACE ? szFaceName : L"", &propvar); + pStore->SetValue(UI_PKEY_FontProperties_Family, propvar); + } + + void PutSize(IPropertyStore* pStore) + { + PROPVARIANT propvar; + DECIMAL decVal; + + if ((dwMask & CFM_SIZE) != 0) + VarDecFromR8((DOUBLE)yHeight / TWIPS_PER_POINT, &decVal); + else + VarDecFromI4(0, &decVal); + + SetPropertyVal(UI_PKEY_FontProperties_Size, &decVal, &propvar); + pStore->SetValue(UI_PKEY_FontProperties_Size, propvar); + } + + void PutColor(IPropertyStore* pStore) + { + if ((dwMask & CFM_COLOR) != 0) + if ((dwEffects & CFE_AUTOCOLOR) == 0) + { + SetPropertyVal(UI_PKEY_FontProperties_ForegroundColorType, UI_SWATCHCOLORTYPE_RGB, &propvar); + pStore->SetValue(UI_PKEY_FontProperties_ForegroundColorType, propvar); + + SetPropertyVal(UI_PKEY_FontProperties_ForegroundColor, crTextColor, &propvar); + pStore->SetValue(UI_PKEY_FontProperties_ForegroundColor, propvar); + } + else + { + SetPropertyVal(UI_PKEY_FontProperties_ForegroundColorType, UI_SWATCHCOLORTYPE_AUTOMATIC, &propvar); + pStore->SetValue(UI_PKEY_FontProperties_ForegroundColorType, propvar); + } + } + + void PutBackColor(IPropertyStore* pStore) + { + if (((dwMask & CFM_BACKCOLOR) != 0) && ((dwEffects & CFE_AUTOBACKCOLOR) == 0)) + { + SetPropertyVal(UI_PKEY_FontProperties_BackgroundColorType, UI_SWATCHCOLORTYPE_RGB, &propvar); + pStore->SetValue(UI_PKEY_FontProperties_BackgroundColorType, propvar); + + SetPropertyVal(UI_PKEY_FontProperties_BackgroundColor, crBackColor, &propvar); + pStore->SetValue(UI_PKEY_FontProperties_BackgroundColor, propvar); + } + else + { + SetPropertyVal(UI_PKEY_FontProperties_BackgroundColorType, UI_SWATCHCOLORTYPE_NOCOLOR, &propvar); + pStore->SetValue(UI_PKEY_FontProperties_BackgroundColorType, propvar); + } + } +}; + +// IUIImage helper +// +inline IUIImage* GetImage(HBITMAP hbm, UI_OWNERSHIP owner) +{ + ATLASSERT(hbm); + IUIImage* pIUII = NULL; + ATL::CComPtr pIFB; + + if SUCCEEDED(pIFB.CoCreateInstance(CLSID_UIRibbonImageFromBitmapFactory)) + ATLVERIFY(SUCCEEDED(pIFB->CreateImage(hbm, owner, &pIUII))); + + return pIUII; +} + + +/////////////////////////////////////////////////////////////////////////////// +// Ribbon control classes + +// RibbonUI::ICtrl abstract interface of RibbonUI::CRibbonImpl and all RibbonUI control classes +// +struct ICtrl +{ + virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, + const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, + IUISimplePropertySet* pCommandExecutionProperties) = 0; + + virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, + const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) = 0; +}; + +// RibbonUI::CtrlImpl base class for all ribbon controls +// +template +class ATL_NO_VTABLE CtrlImpl : public ICtrl +{ +protected: + T* m_pWndRibbon; + +public: + typedef T WndRibbon; + + CtrlImpl() : m_pWndRibbon(T::pWndRibbon) + { } + + WndRibbon& GetWndRibbon() + { + return *m_pWndRibbon; + } + + static WORD GetID() + { + return t_ID; + } + + Text m_sTxt[5]; + + // Operations + HRESULT Invalidate() + { + return GetWndRibbon().InvalidateCtrl(GetID()); + } + + HRESULT Invalidate(REFPROPERTYKEY key, UI_INVALIDATIONS flags = UI_INVALIDATIONS_PROPERTY) + { + return GetWndRibbon().InvalidateProperty(GetID(), key, flags); + } + + HRESULT SetText(REFPROPERTYKEY key, LPCWSTR sTxt, bool bUpdate = false) + { + ATLASSERT((k_(key) <= k_TooltipTitle) && (k_(key) >= k_LabelDescription)); + + m_sTxt[k_(key) - k_LabelDescription] = sTxt; + + return bUpdate ? + GetWndRibbon().InvalidateProperty(GetID(), key) : + S_OK; + } + + // Implementation + template + HRESULT SetProperty(REFPROPERTYKEY key, V val) + { + return GetWndRibbon().SetProperty(GetID(), key, val); + } + + HRESULT OnGetText(REFPROPERTYKEY key, PROPVARIANT* ppv) + { + ATLASSERT((k_(key) <= k_TooltipTitle) && (k_(key) >= k_LabelDescription)); + + const INT iText = k_(key) - k_LabelDescription; + if (m_sTxt[iText].IsEmpty()) + if (LPCWSTR sText = GetWndRibbon().OnRibbonQueryText(GetID(), key)) + m_sTxt[iText] = sText; + + return !m_sTxt[iText].IsEmpty() ? + SetPropertyVal(key, (LPCWSTR)m_sTxt[iText], ppv) : + S_OK; + } + + virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, + const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, + IUISimplePropertySet* pCommandExecutionProperties) + { + ATLASSERT(nCmdID == t_ID); + return GetWndRibbon().DoExecute(nCmdID, verb, key, ppropvarValue, pCommandExecutionProperties); + } + + virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, + const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) + { + ATLASSERT(nCmdID == t_ID); + + const INT iMax = k_TooltipTitle - k_LabelDescription; + const INT iVal = k_(key) - k_LabelDescription; + + return (iVal <= iMax) && (iVal >= 0) ? + OnGetText(key, ppropvarNewValue) : + GetWndRibbon().DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); + } +}; + +// CommandCtrlImpl base class for most ribbon controls +// +template +class CommandCtrlImpl : public CtrlImpl +{ +public: + CBitmap m_hbm[4]; + + HRESULT SetImage(REFPROPERTYKEY key, HBITMAP hbm, bool bUpdate = false) + { + ATLASSERT((k_(key) <= k_SmallHighContrastImage) && (k_(key) >= k_LargeImage)); + + m_hbm[k_(key) - k_LargeImage].Attach(hbm); + + return bUpdate ? + GetWndRibbon().InvalidateProperty(GetID(), key) : + S_OK; + } + + HRESULT OnGetImage(REFPROPERTYKEY key, PROPVARIANT* ppv) + { + ATLASSERT((k_(key) <= k_SmallHighContrastImage) && (k_(key) >= k_LargeImage)); + + const INT iImage = k_(key) - k_LargeImage; + + if (m_hbm[iImage].IsNull()) + m_hbm[iImage] = GetWndRibbon().OnRibbonQueryImage(GetID(), key); + + return m_hbm[iImage].IsNull() ? + E_NOTIMPL : + SetPropertyVal(key, GetImage(m_hbm[iImage], UI_OWNERSHIP_COPY), ppv); + } + + virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, + const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) + { + ATLASSERT (nCmdID == GetID()); + + return (k_(key) <= k_SmallHighContrastImage) && (k_(key) >= k_LargeImage) ? + OnGetImage(key, ppropvarNewValue) : + CtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// Ribbon collection base classes + +// ItemProperty class: ribbon callback for each item in a collection +// +template +class ItemProperty : public IUISimplePropertySet +{ +public: + ItemProperty(UINT i, TCollection* pCollection) : m_Index(i), m_pCollection(pCollection) + { } + + const UINT m_Index; + TCollection* m_pCollection; + + // IUISimplePropertySet method. + STDMETHODIMP GetValue(REFPROPERTYKEY key, PROPVARIANT *value) + { + return m_pCollection->OnGetItem(m_Index, key, value); + } + + // IUnknown methods. + STDMETHODIMP_(ULONG) AddRef() + { + return 1; + } + + STDMETHODIMP_(ULONG) Release() + { + return 1; + } + + STDMETHODIMP QueryInterface(REFIID iid, void** ppv) + { + if ((iid == __uuidof(IUnknown)) || (iid == __uuidof(IUISimplePropertySet))) + { + *ppv = this; + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } +}; + + +// CollectionImplBase: base class for all RibbonUI collections +// +template +class CollectionImplBase +{ + typedef CollectionImplBase thisClass; + +public: + CollectionImplBase() + { + for (int i = 0; i < t_size; i++) + m_apItems[i] = new ItemProperty(i, static_cast(this)); + } + + ~CollectionImplBase() + { + for (int i = 0; i < t_size; i++) + delete m_apItems[i]; + } + +// Data members + ItemProperty* m_apItems[t_size]; +}; + +// CollectionImpl: handles categories and collecton resizing +// +template +class CollectionImpl : public CollectionImplBase, t_items + t_categories> +{ + typedef CollectionImpl thisClass; +public: + typedef thisClass Collection; + + CollectionImpl() : m_size(t_items) + { + FillMemory(m_auItemCat, sizeof m_auItemCat, 0xff); // UI_COLLECTION_INVALIDINDEX + } + + UINT32 m_auItemCat[t_items]; + Text m_asCatName[max(t_categories, 1)]; + size_t m_size; + +// Operations + HRESULT SetItemCategory(UINT uItem, UINT uCat, bool bUpdate = false) + { + ATLASSERT((uItem < t_items) && (uCat < t_categories)); + + m_auItemCat[uItem] = uCat; + + return bUpdate ? InvalidateItems() : S_OK; + } + + HRESULT SetCategoryText(UINT uCat, LPCWSTR sText, bool bUpdate = false) + { + ATLASSERT(uCat < t_categories); + + m_asCatName[uCat] = sText; + + return bUpdate ? InvalidateCategories() : S_OK; + } + + HRESULT Resize(size_t size, bool bUpdate = false) + { + ATLASSERT(size <= t_items); + + m_size = size; + + return bUpdate ? InvalidateItems() : S_OK; + } + +// Implementation + HRESULT OnGetItem(UINT uIndex, REFPROPERTYKEY key, PROPVARIANT *value) + { + ATLASSERT(uIndex < t_items + t_categories); + TCtrl* pCtrl = static_cast(this); + + return uIndex < t_items ? + pCtrl->DoGetItem(uIndex, key, value) : + pCtrl->DoGetCategory(uIndex - t_items, key, value); + } + + HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) + { + ATLASSERT(k_(key) == k_CategoryId); + UINT32 uCat = UI_COLLECTION_INVALIDINDEX; + + if (t_categories != 0) + { + if (m_auItemCat[uItem] == UI_COLLECTION_INVALIDINDEX) + { + TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); + m_auItemCat[uItem] = ribbon.OnRibbonQueryItemCategory(TCtrl::GetID(), uItem); + } + uCat = m_auItemCat[uItem]; + } + + return SetPropertyVal(key, uCat, value); + } + + HRESULT DoGetCategory(UINT uCat, REFPROPERTYKEY key, PROPVARIANT *value) + { + HRESULT hr = S_OK; + + switch (k_(key)) + { + case k_Label: + if (m_asCatName[uCat].IsEmpty()) + { + TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); + m_asCatName[uCat] = ribbon.OnRibbonQueryCategoryText(TCtrl::GetID(), uCat); + } + hr = SetPropertyVal(key, (LPCWSTR)m_asCatName[uCat], value); + break; + case k_CategoryId: + hr = SetPropertyVal(key, uCat, value); + break; + default: + ATLASSERT(FALSE); + break; + } + + return hr; + } + + HRESULT InvalidateItems() + { + return static_cast(this)->Invalidate(UI_PKEY_ItemsSource); + } + + HRESULT InvalidateCategories() + { + return static_cast(this)->Invalidate(UI_PKEY_Categories); + } + + HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, + const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* /*ppropvarNewValue*/) + { + ATLASSERT(nCmdID == TCtrl::GetID()); + nCmdID; // avoid level 4 warning + + HRESULT hr = E_NOTIMPL; + switch (k_(key)) + { + case k_ItemsSource: + { + ATL::CComQIPtr pIUICollection(ppropvarCurrentValue->punkVal); + ATLASSERT(pIUICollection); + hr = pIUICollection->Clear(); + for (UINT i = 0; i < m_size; i++) + { + if FAILED(hr = pIUICollection->Add(m_apItems[i])) + break; + } + ATLASSERT(SUCCEEDED(hr)); + } + break; + case k_Categories: + if (t_categories != 0) + { + ATL::CComQIPtr pIUICategory(ppropvarCurrentValue->punkVal); + ATLASSERT(pIUICategory.p); + hr = pIUICategory->Clear(); + for (UINT i = t_items; i < t_items + t_categories; i++) + { + if FAILED(hr = pIUICategory->Add(m_apItems[i])) + break; + } + ATLASSERT(SUCCEEDED(hr)); + } + break; + } + + return hr; + } +}; + +// TextCollectionImpl: handles item labels and selection +// +template +class TextCollectionImpl : public CollectionImpl +{ + typedef TextCollectionImpl thisClass; +public: + typedef thisClass TextCollection; + + TextCollectionImpl() : m_uSelected(UI_COLLECTION_INVALIDINDEX) + { } + + Text m_asText[t_items]; + UINT m_uSelected; + + // Operations + HRESULT SetItemText(UINT uItem, LPCWSTR sText, bool bUpdate = false) + { + ATLASSERT(uItem < t_items); + + m_asText[uItem] = sText; + + return bUpdate ? InvalidateItems() : S_OK; + } + + UINT GetSelected() + { + return m_uSelected; + } + + HRESULT Select(UINT uItem, bool bUpdate = false) + { + ATLASSERT((uItem < t_items) || (uItem == UI_COLLECTION_INVALIDINDEX)); + + m_uSelected = uItem; + + TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); + return bUpdate ? + ribbon.SetProperty(TCtrl::GetID(), UI_PKEY_SelectedItem, uItem) : + S_OK; + } + +// Implementation + HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) + { + ATLASSERT(uItem < t_items); + + if (k_(key) == k_Label) + { + if (m_asText[uItem].IsEmpty()) + { + TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); + m_asText[uItem] = ribbon.OnRibbonQueryItemText(TCtrl::GetID(), uItem); + } + return SetPropertyVal(key, (LPCWSTR)m_asText[uItem], value); + } + else + { + return Collection::DoGetItem(uItem, key, value); + } + } + + HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, + const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) + { + ATLASSERT(nCmdID == TCtrl::GetID()); + + if (k_(key) == k_SelectedItem) + { + TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); + UINT uSel = UI_COLLECTION_INVALIDINDEX; + if ((m_uSelected == UI_COLLECTION_INVALIDINDEX) && + ribbon.OnRibbonQuerySelectedItem(TCtrl::GetID(), uSel)) + m_uSelected = uSel; + + return SetPropertyVal(key, m_uSelected, ppropvarNewValue); + } + else + { + return Collection::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); + } + } +}; + +// ItemCollectionImpl: handles item image +// +template +class ItemCollectionImpl : public TextCollectionImpl +{ + typedef ItemCollectionImpl thisClass; +public: + typedef thisClass ItemCollection; + + ItemCollectionImpl() + { + ZeroMemory(m_aBitmap, sizeof m_aBitmap); + } + + CBitmap m_aBitmap[t_items]; + + // Operations + HRESULT SetItemImage(UINT uIndex, HBITMAP hbm, bool bUpdate = false) + { + ATLASSERT(uIndex < t_items); + + m_aBitmap[uIndex] = hbm; + + return bUpdate ? InvalidateItems() : S_OK; + } + +// Implementation + HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) + { + ATLASSERT(uItem < t_items); + + if (k_(key) == k_ItemImage) + { + if (m_aBitmap[uItem].IsNull()) + { + TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); + m_aBitmap[uItem] = ribbon.OnRibbonQueryItemImage(TCtrl::GetID(), uItem); + } + return m_aBitmap[uItem].IsNull() ? + E_NOTIMPL : + SetPropertyVal(key, GetImage(m_aBitmap[uItem], UI_OWNERSHIP_COPY), value); + } + else + { + return TextCollection::DoGetItem(uItem, key, value); + } + } +}; + +// ComboCollectionImpl: handles combo text +// +template +class ComboCollectionImpl : public ItemCollectionImpl +{ + typedef ComboCollectionImpl thisClass; +public: + typedef thisClass ComboCollection; + + // Operations + HRESULT SetComboText(LPCWSTR sText) + { + TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); + return ribbon.IsRibbonUI() ? + ribbon.SetProperty(TCtrl::GetID(), UI_PKEY_StringValue, sText) : + S_OK; + } + + LPCWSTR GetComboText() + { + static WCHAR sCombo[RIBBONUI_MAX_TEXT] = { 0 }; + TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); + PROPVARIANT var; + if (ribbon.IsRibbonUI()) + { + HRESULT hr = ribbon.GetIUIFrameworkPtr()->GetUICommandProperty(TCtrl::GetID(), UI_PKEY_StringValue, &var); + hr = PropVariantToString(var, sCombo, RIBBONUI_MAX_TEXT); + return sCombo; + } + return NULL; + } +}; + +// CommandCollectionImpl: handles RibbonUI command collection controls +// +template +class CommandCollectionImpl : public CollectionImpl +{ + typedef CommandCollectionImpl thisClass; +public: + typedef thisClass CommandCollection; + + CommandCollectionImpl() + { + ZeroMemory(m_auCmd, sizeof m_auCmd); + ZeroMemory(m_aCmdType, sizeof m_aCmdType); + } + + UINT32 m_auCmd[t_items]; + BYTE m_aCmdType[t_items]; + + // Operations + HRESULT SetItemCommand(UINT uItem, UINT32 uCommandID, bool bUpdate = false) + { + ATLASSERT(uItem < t_items); + + if (uCommandID == m_auCmd[uItem]) + return S_OK; + + TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); + + m_auCmd[uItem] = uCommandID; + if (uCommandID != 0) + ribbon.UIAddRibbonElement(uCommandID); + + return bUpdate ? InvalidateItems() : S_OK; + } + + HRESULT SetItemCommandType(UINT uItem, UI_COMMANDTYPE type, bool bUpdate = false) + { + ATLASSERT(uItem < t_items); + + m_aCmdType[uItem] = (BYTE)type; + + return bUpdate ? InvalidateItems() : S_OK; + } + +// Implementation + HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) + { + ATLASSERT(uItem < t_items); + TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); + + HRESULT hr = E_FAIL; + switch (k_(key)) + { + case k_CommandId: + if (m_auCmd[uItem] == 0) + SetItemCommand(uItem, ribbon.OnRibbonQueryItemCommand(TCtrl::GetID(), uItem)); + hr = SetPropertyVal(key, m_auCmd[uItem], value); + break; + case k_CommandType: + if (m_aCmdType[uItem] == UI_COMMANDTYPE_UNKNOWN) + SetItemCommandType(uItem, ribbon.OnRibbonQueryItemCommandType(TCtrl::GetID(), uItem)); + hr = SetPropertyVal(key, UINT32(m_aCmdType[uItem]), value); + break; + case k_CategoryId: + default: + hr = Collection::DoGetItem(uItem, key, value); + break; + } + + return hr; + } + + HRESULT Select(UINT /*uItem*/, bool /*bUpdate*/ = false) + { + ATLASSERT(FALSE); + return S_OK; + } +}; + +// SimpleCollectionImpl: collection class for ribbon simple collection controls +// +template +class SimpleCollectionImpl : public CollectionImplBase, t_size> +{ + typedef SimpleCollectionImpl thisClass; +public: + typedef CollectionImplBase CollectionBase; + typedef thisClass SimpleCollection; + +// Implementation + HRESULT OnGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) + { + ATLASSERT(uItem < t_size); + TCtrl::WndRibbon& ribbon = static_cast(this)->GetWndRibbon(); + + HRESULT hr = E_NOTIMPL; + switch (k_(key)) + { + case k_ItemImage: + if (HBITMAP hbm = ribbon.DefRibbonQueryItemImage(TCtrl::GetID(), uItem)) + hr = SetPropertyVal(key, GetImage(hbm, UI_OWNERSHIP_TRANSFER), value); + break; + case k_Label: + if (LPCWSTR sText = ribbon.DefRibbonQueryItemText(TCtrl::GetID(), uItem)) + hr = SetPropertyVal(key, (LPCWSTR)sText, value); + break; + case k_CommandType: + hr = SetPropertyVal(key, t_CommandType, value); + break; + case k_CommandId: + hr = SetPropertyVal(key, ribbon.DefRibbonQueryItemCommand(TCtrl::GetID(), uItem), value); + break; + case k_CategoryId: + hr = SetPropertyVal(key, UI_COLLECTION_INVALIDINDEX, value); + break; + default: + ATLASSERT(FALSE); + break; + } + + return hr; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// Ribbon collection control classes + +// CollectionCtrlImpl: specializable class for ribbon collection controls +// +template +class CollectionCtrlImpl : public CommandCtrlImpl, public TCollection +{ + typedef CollectionCtrlImpl thisClass; +public: + typedef CommandCtrlImpl CommandCtrl; + typedef TCollection Collection; + + // Implementation + virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, + const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) + { + ATLASSERT(nCmdID == GetID()); + ATLASSERT(ppropvarNewValue); + + HRESULT hr = Collection::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); + if FAILED(hr) + hr = CommandCtrl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); + + return hr; + } + + virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, + const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, + IUISimplePropertySet* /*pCommandExecutionProperties*/) + { + ATLASSERT (nCmdID == GetID()); + nCmdID; // avoid level4 warning + + if (key == NULL) // gallery button pressed + { + GetWndRibbon().OnRibbonItemSelected(GetID(), UI_EXECUTIONVERB_EXECUTE, UI_COLLECTION_INVALIDINDEX); + return S_OK; + } + + ATLASSERT(k_(*key) == k_SelectedItem); + ATLASSERT(ppropvarValue); + + HRESULT hr = S_OK; + UINT32 uSel = 0xffff; + hr = UIPropertyToUInt32(*key, *ppropvarValue, &uSel); + + if (SUCCEEDED(hr)) + { + if (GetWndRibbon().OnRibbonItemSelected(GetID(), verb, uSel)) + TCollection::Select(uSel); + } + + return hr; + } +}; + +// ToolbarGalleryCtrlImpl: base class for ribbon toolbar gallery controls +// +template +class ToolbarGalleryCtrlImpl : public CollectionCtrlImpl, t_size>> +{ +public: + ToolbarGalleryCtrlImpl() + { + CResource tbres; + ATLVERIFY(tbres.Load(RT_TOOLBAR, t_idTB)); + _AtlToolBarData* pData = (_AtlToolBarData*)tbres.Lock(); + ATLASSERT(pData); + ATLASSERT(pData->wVersion == 1); + + WORD* pItems = pData->items(); + INT j = 0; + for (int i = 0; (i < pData->wItemCount) && (j < t_size); i++) + { + if (pItems[i] != 0) + { + m_aCmdType[j] = UI_COMMANDTYPE_ACTION; + m_auCmd[j++] = pItems[i]; + } + } + + if (j < t_size) + Resize(j); + } + + HRESULT DoGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) + { + ATLASSERT(uItem < m_size); + ATLASSERT(m_auCmd[uItem]); + + HRESULT hr = E_FAIL; + switch (k_(key)) + { + case k_CommandId: + hr = SetPropertyVal(key, m_auCmd[uItem], value); + break; + case k_CommandType: + hr = SetPropertyVal(key, UINT32(m_aCmdType[uItem]), value); + break; + case k_CategoryId: + hr = SetPropertyVal(key, UI_COLLECTION_INVALIDINDEX, value); + break; + default: + ATLASSERT(FALSE); + break; + } + + return hr; + } +}; + + +// SimpleCollectionCtrlImpl: base class for simple gallery and listbox controls +// +template +class SimpleCollectionCtrlImpl : + public CommandCtrlImpl, + public SimpleCollectionImpl, t_size, t_CommandType> +{ + typedef SimpleCollectionCtrlImpl thisClass; +public: + typedef thisClass SimpleCollection; + + SimpleCollectionCtrlImpl() : m_uSelected(0) + { } + + UINT m_uSelected; + + HRESULT Select(UINT uItem, bool bUpdate = false) + { + ATLASSERT((uItem < t_size) || (uItem == UI_COLLECTION_INVALIDINDEX)); + + m_uSelected = uItem; + + return bUpdate ? + GetWndRibbon().SetProperty(GetID(), UI_PKEY_SelectedItem, uItem) : + S_OK; + } + + // Implementation + virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, + const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) + { + ATLASSERT(nCmdID == GetID()); + ATLASSERT(ppropvarNewValue != NULL); + + HRESULT hr = S_OK; + switch (k_(key)) + { + case k_ItemsSource: + { + ATL::CComQIPtr pIUICollection(ppropvarCurrentValue->punkVal); + ATLASSERT(pIUICollection.p); + hr = pIUICollection->Clear(); + for (UINT i = 0; i < t_size; i++) + { + if FAILED(hr = pIUICollection->Add(m_apItems[i])) + break; + } + ATLASSERT(SUCCEEDED(hr)); + } + break; + case k_SelectedItem: + hr = SetPropertyVal(UI_PKEY_SelectedItem, m_uSelected, ppropvarNewValue); + break; + default: + hr = CommandCtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); + break; + } + + return hr; + } + + virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, + const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, + IUISimplePropertySet* /*pCommandExecutionProperties*/) + { + ATLASSERT (nCmdID == GetID()); + nCmdID; // avoid level 4 warning + + HRESULT hr = S_OK; + if (key == NULL) // gallery button pressed + { + GetWndRibbon().OnRibbonItemSelected(GetID(), UI_EXECUTIONVERB_EXECUTE, UI_COLLECTION_INVALIDINDEX); + return hr; + } + ATLASSERT(k_(*key) == k_SelectedItem); + ATLASSERT(ppropvarValue); + + if SUCCEEDED(hr = UIPropertyToUInt32(*key, *ppropvarValue, &m_uSelected)) + GetWndRibbon().OnRibbonItemSelected(GetID(), verb, m_uSelected); + + return hr; + } +}; + +// RecentItemsCtrlImpl +// +template +class RecentItemsCtrlImpl : + public CtrlImpl, + public CollectionImplBase, TDocList::m_nMaxEntries_Max>, + public TDocList +{ + typedef RecentItemsCtrlImpl thisClass; +public: + typedef thisClass RecentItems; + + // Implementation + HRESULT OnGetItem(UINT uItem, REFPROPERTYKEY key, PROPVARIANT *value) + { + ATLASSERT((INT)uItem < GetMaxEntries()); + + LPCWSTR sPath = m_arrDocs[uItem].szDocName; + HRESULT hr = E_NOTIMPL; + switch (k_(key)) + { + case k_Label: + hr = SetPropertyVal(key, GetWndRibbon().OnRibbonQueryRecentItemName(sPath), value); + break; + case k_LabelDescription: + hr = SetPropertyVal(key, sPath, value); + break; + default: + ATLASSERT(FALSE); + break; + } + + return hr; + } + + virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, + const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) + { + ATLASSERT(nCmdID == GetID()); + ATLASSERT(ppropvarNewValue); + + HRESULT hr = S_OK; + switch (k_(key)) + { + case k_RecentItems: + if (SAFEARRAY* psa = SafeArrayCreateVector(VT_UNKNOWN, 0, m_arrDocs.GetSize())) + { + const int iLastIndex = m_arrDocs.GetSize() - 1; + for (LONG i = 0; i <= iLastIndex; i++) + SafeArrayPutElement(psa, &i, m_apItems[iLastIndex - i]); // reverse order + + hr = SetPropertyVal(key, psa, ppropvarNewValue); + SafeArrayDestroy(psa); + } + break; + default: + hr = CtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); + break; + } + + return hr; + } + + virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, + const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, + IUISimplePropertySet* /*pCommandExecutionProperties*/) + { + ATLASSERT(nCmdID == GetID()); + nCmdID; // avoid level 4 warning + ATLASSERT(verb == UI_EXECUTIONVERB_EXECUTE); + verb; // avoid level 4 warning + ATLASSERT((key) && (k_(*key) == k_SelectedItem)); + ATLASSERT(ppropvarValue); + + UINT32 uSel = 0xffff; + HRESULT hr = UIPropertyToUInt32(*key, *ppropvarValue, &uSel); + if SUCCEEDED(hr) + { + ATLASSERT(uSel < (UINT)GetMaxEntries()); + GetWndRibbon().DefCommandExecute(ID_FILE_MRU_FIRST + uSel); + } + + return hr; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// Ribbon stand-alone control classes + +// FontCtrlImpl +// +template +class FontCtrlImpl : public CtrlImpl +{ +public: + + CharFormat m_cf; + +// Implementation + virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, + const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, + IUISimplePropertySet* pCommandExecutionProperties) + { + ATLASSERT (nCmdID == GetID()); + nCmdID; // avoid level 4 warning + ATLASSERT ((key) && (k_(*key) == k_FontProperties)); + key; // avoid level 4 warning + + HRESULT hr = E_INVALIDARG; + switch (verb) + { + case UI_EXECUTIONVERB_PREVIEW: + case UI_EXECUTIONVERB_EXECUTE: + ATLASSERT(pCommandExecutionProperties); + PROPVARIANT propvar; + + if (SUCCEEDED(hr = pCommandExecutionProperties->GetValue(UI_PKEY_FontProperties_ChangedProperties, &propvar))) + m_cf << ATL::CComQIPtr(propvar.punkVal); + break; + + case UI_EXECUTIONVERB_CANCELPREVIEW: + ATLASSERT(ppropvarValue); + ATL::CComPtr pStore; + + if (SUCCEEDED(hr = UIPropertyToInterface(UI_PKEY_FontProperties, *ppropvarValue, &pStore))) + m_cf << pStore; + break; + } + + if (SUCCEEDED(hr)) + GetWndRibbon().OnRibbonFontCtrlExecute(GetID(), verb, &m_cf); + else + ATLASSERT(FALSE); + + return hr; + } + + virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, + const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) + { + if ((k_(key) == k_FontProperties) && (GetWndRibbon().OnRibbonQueryFont(t_ID, m_cf))) + { + ATL::CComQIPtr pStore(ppropvarCurrentValue->punkVal); + m_cf >> pStore; + return SetPropertyVal(key, pStore.p, ppropvarNewValue); + } + else + { + return CtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); + } + } +}; + +// ColorCtrlImpl +// +template +class ColorCtrlImpl : public CommandCtrlImpl +{ +public: + ColorCtrlImpl() : m_colorType(UI_SWATCHCOLORTYPE_NOCOLOR), m_color(0x800080) /*MAGENTA*/ + { } + + COLORREF m_color; + UINT32 m_colorType; // value in UI_SWATCHCOLORTYPE + Text m_sLabels[6]; // k_MoreColorsLabel to k_ThemeColorsCategoryLabel + ATL::CSimpleArray m_aColors[2]; + ATL::CSimpleArray m_aTooltips[2]; + + // Operations + HRESULT SetColor(COLORREF color, bool bUpdate = false) + { + if (m_colorType != UI_SWATCHCOLORTYPE_RGB) + SetColorType(UI_SWATCHCOLORTYPE_RGB, bUpdate); + m_color = color; + return bUpdate ? SetProperty(UI_PKEY_Color, color) : S_OK; + } + + HRESULT SetColorType(UI_SWATCHCOLORTYPE type, bool bUpdate = false) + { + m_colorType = type; + return bUpdate ? SetProperty(UI_PKEY_ColorType, type) : S_OK; + } + + HRESULT SetColorLabel(REFPROPERTYKEY key, LPCWSTR sLabel, bool bUpdate = false) + { + ATLASSERT((k_(key) >= k_ThemeColorsCategoryLabel) && (k_(key) <= k_MoreColorsLabel)); + m_sLabels[k_(key) - k_ThemeColorsCategoryLabel] = sLabel; + return bUpdate ? SetProperty(key, sLabel) : S_OK; + } + + HRESULT SetColorArray(REFPROPERTYKEY key, COLORREF* pColor, bool bUpdate = false) + { + ATLASSERT((k_(key) == k_ThemeColors) || (k_(key) == k_StandardColors)); + + const INT ic = k_(key) - k_ThemeColors; + m_aColors[ic].RemoveAll(); + while (*pColor != 0x800080) /*MAGENTA*/ + m_aColors[ic].Add(*pColor++); + + if (bUpdate) + { + PROPVARIANT var; + if SUCCEEDED(InitPropVariantFromUInt32Vector(m_aColors[ic].GetData(), m_aColors[ic].GetSize(), &var)) + return SetProperty(key, var); + else + return E_INVALIDARG; + } + else + { + return S_OK; + } + } + + HRESULT SetColorTooltips(REFPROPERTYKEY key, LPCWSTR* ppsTT, bool bUpdate = false) + { + ATLASSERT((k_(key) == k_ThemeColorsTooltips) || (k_(key) == k_StandardColorsTooltips)); + + const INT ic = k_(key) - k_ThemeColorsTooltips; + m_aTooltips[ic].RemoveAll(); + while (*ppsTT) + m_aTooltips[ic].Add(*ppsTT++); + + if (bUpdate) + { + PROPVARIANT var; + if SUCCEEDED(InitPropVariantFromStringVector(m_aTooltips[ic].GetData(), m_aTooltips[ic].GetSize(), &var)) + return SetProperty(key, var); + else + return E_INVALIDARG; + } + else + { + return S_OK; + } + } + + // Implementation + virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, + const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, + IUISimplePropertySet* pCommandExecutionProperties) + { + ATLASSERT (nCmdID == GetID()); + nCmdID; // avoid level 4 warning + ATLASSERT (key && (k_(*key) == k_ColorType)); + key; // avoid level 4 warning + ATLASSERT (ppropvarValue); + + HRESULT hr = PropVariantToUInt32(*ppropvarValue, &m_colorType); + ATLASSERT(SUCCEEDED(hr)); + + if (SUCCEEDED(hr) && (m_colorType == UI_SWATCHCOLORTYPE_RGB)) + { + ATLASSERT(pCommandExecutionProperties); + PROPVARIANT var; + if SUCCEEDED(hr = pCommandExecutionProperties->GetValue(UI_PKEY_Color, &var)) + hr = PropVariantToUInt32(var, &m_color); + } + + if SUCCEEDED(hr) + GetWndRibbon().OnRibbonColorCtrlExecute(GetID(), verb, (UI_SWATCHCOLORTYPE)m_colorType/*uType*/, m_color); + else + ATLASSERT(FALSE); // something was wrong + + return hr; + } + + virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, + const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) + { + ATLASSERT (nCmdID == GetID()); + + HRESULT hr = E_NOTIMPL; + + switch (k_(key)) + { + case k_ColorType: + hr = SetPropertyVal(key, m_colorType, ppropvarNewValue); + break; + case k_Color: + if (m_color == 0x800080) /*MAGENTA*/ + m_color = GetWndRibbon().OnRibbonQueryColor(GetID()); + hr = SetPropertyVal(key, m_color, ppropvarNewValue); + break; + case k_ColorMode: + break; + case k_ThemeColorsCategoryLabel: + case k_StandardColorsCategoryLabel: + case k_RecentColorsCategoryLabel: + case k_AutomaticColorLabel: + case k_NoColorLabel: + case k_MoreColorsLabel: + { + const UINT iLabel = k_(key) - k_ThemeColorsCategoryLabel; + if (m_sLabels[iLabel].IsEmpty()) + if (LPCWSTR psLabel = GetWndRibbon().OnRibbonQueryColorLabel(GetID(), key)) + m_sLabels[iLabel] = psLabel; + if (!m_sLabels[iLabel].IsEmpty()) + hr = SetPropertyVal(key, (LPCWSTR)m_sLabels[iLabel], ppropvarNewValue); + } + break; + case k_ThemeColors: + case k_StandardColors: + { + const INT ic = k_(key) - k_ThemeColors; + if (!m_aColors[ic].GetSize()) + if (COLORREF* pColor = GetWndRibbon().OnRibbonQueryColorArray(GetID(), key)) + SetColorArray(key, pColor); + if (INT iMax = m_aColors[ic].GetSize()) + hr = InitPropVariantFromUInt32Vector(m_aColors[ic].GetData(), iMax, ppropvarNewValue); + } + break; + case k_ThemeColorsTooltips: + case k_StandardColorsTooltips: + { + const INT ic = k_(key) - k_ThemeColorsTooltips; + if (m_aTooltips[ic].GetSize() == 0) + if (LPCWSTR* ppsTT = GetWndRibbon().OnRibbonQueryColorTooltips(GetID(), key)) + SetColorTooltips(key, ppsTT); + if (INT iMax = m_aTooltips[ic].GetSize()) + hr = InitPropVariantFromStringVector(m_aTooltips[ic].GetData(), iMax, ppropvarNewValue); + } + break; + default: + hr = CommandCtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); + break; + } + + return hr; + } +}; + +// SpinnerCtrlImpl +// +template +class SpinnerCtrlImpl : public CtrlImpl +{ +public: + SpinnerCtrlImpl() + { + m_Values[0] = m_Values[2] = m_Values[4] = 0; + m_Values[1] = 100; + m_Values[3] = 1; + } + + V m_Values[5]; + // k_DecimalValue = 201, k_MaxValue = 203, k_MinValue, k_Increment, k_DecimalPlaces + + Text m_FormatString; + Text m_RepresentativeString; + + // Operations + HRESULT SetDecimalPlaces(V vPlaces, bool bUpdate = false) + { + return SetValue(UI_PKEY_DecimalPlaces, vPlaces, bUpdate); + } + + HRESULT SetMin(V vMin, bool bUpdate = false) + { + return SetValue(UI_PKEY_MinValue, vMin, bUpdate); + } + + HRESULT SetMax(V vMax, bool bUpdate = false) + { + return SetValue(UI_PKEY_MaxValue, vMax, bUpdate); + } + + HRESULT SetVal(V vVal, bool bUpdate = false) + { + return SetValue(UI_PKEY_DecimalValue, vVal, bUpdate); + } + + HRESULT SetIncrement(V vIncrement, bool bUpdate = false) + { + return SetValue(UI_PKEY_Increment, vIncrement, bUpdate); + } + + HRESULT SetFormatString(LPCWSTR sFormat, bool bUpdate = false) + { + return SetText(UI_PKEY_FormatString, sFormat, bUpdate); + } + + HRESULT SetRepresentativeString(LPCWSTR sRepresentative, bool bUpdate = false) + { + return SetText(UI_PKEY_RepresentativeString, sRepresentative, bUpdate); + } + + // Implementation + HRESULT SetText(REFPROPERTYKEY key, LPCWSTR sText, bool bUpdate = false) + { + switch (k_(key)) + { + case k_FormatString: + m_FormatString = sText; + break; + case k_RepresentativeString: + m_RepresentativeString = sText; + break; + default: + return CtrlImpl::SetText(key, sText, bUpdate); + } + + return bUpdate ? + GetWndRibbon().InvalidateProperty(GetID(), key) : + S_OK; + } + + HRESULT SetValue(REFPROPERTYKEY key, V val, bool bUpdate = false) + { + ATLASSERT((k_(key) <= k_DecimalPlaces) && (k_(key) >= k_DecimalValue)); + + const INT iVal = k_(key) == k_DecimalValue ? 0 : k_(key) - k_StringValue; + m_Values[iVal] = val; + + if (bUpdate) + { + if(k_(key) == k_DecimalValue) + { + DECIMAL decVal; + InitDecimal(val, &decVal); + return SetProperty(key, &decVal); + } + else + { + return GetWndRibbon().InvalidateProperty(GetID(), key); + } + } + else + { + return S_OK; + } + } + + HRESULT QueryValue(REFPROPERTYKEY key, LONG* plVal) + { + return GetWndRibbon().OnRibbonQuerySpinnerValue(GetID(), key, plVal); + } + + HRESULT QueryValue(REFPROPERTYKEY key, DOUBLE* pdVal) + { + return GetWndRibbon().OnRibbonQueryFloatSpinnerValue(GetID(), key, pdVal); + } + + HRESULT OnGetValue(REFPROPERTYKEY key, PROPVARIANT* ppv) + { + ATLASSERT((k_(key) <= k_DecimalPlaces) && (k_(key) >= k_DecimalValue)); + + const INT iVal = k_(key) == k_DecimalValue ? 0 : k_(key) - k_StringValue; + + QueryValue(key, m_Values + iVal); + + if (k_(key) == k_DecimalPlaces) + { + return SetPropertyVal(key, m_Values[iVal], ppv); + } + else + { + DECIMAL decVal; + InitDecimal(m_Values[iVal], &decVal); + return SetPropertyVal(key, &decVal, ppv); + } + } + + HRESULT OnGetText(REFPROPERTYKEY key, Text& sVal, PROPVARIANT* ppv) + { + if (LPCWSTR sNew = GetWndRibbon().OnRibbonQueryText(GetID(), key)) + sVal = sNew; + return SetPropertyVal(key, (LPCWSTR)sVal, ppv); + } + + virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, + const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, + IUISimplePropertySet* /*pCommandExecutionProperties*/) + { + ATLASSERT (nCmdID == GetID()); + nCmdID; // avoid level 4 warning + ATLASSERT (key && (k_(*key) == k_DecimalValue)); + key; // avoid level 4 warning + ATLASSERT (verb == UI_EXECUTIONVERB_EXECUTE); + verb; // avoid level 4 warning + + DECIMAL decVal; + + HRESULT hr = UIPropertyToDecimal(UI_PKEY_DecimalValue, *ppropvarValue, &decVal); + hr = InitVal(m_Values[0], &decVal); + + GetWndRibbon().OnRibbonSpinnerCtrlExecute(GetID(), &m_Values[0]); + + return hr; + } + + virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, + const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) + { + ATLASSERT (nCmdID == GetID()); + + HRESULT hr = E_NOTIMPL; + switch (k_(key)) + { + case k_DecimalPlaces: + case k_DecimalValue: + case k_Increment: + case k_MaxValue: + case k_MinValue: + hr = OnGetValue(key, ppropvarNewValue); + break; + case k_FormatString: + if (m_FormatString.IsEmpty()) + return OnGetText(key, m_FormatString, ppropvarNewValue); + break; + case k_RepresentativeString: + if (m_RepresentativeString.IsEmpty()) + return OnGetText(key, m_RepresentativeString, ppropvarNewValue); + break; + default: + hr = CtrlImpl::DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); + break; + } + + return hr; + } + + // decimal conversion helpers + static HRESULT InitDecimal(LONG& val, DECIMAL* pDecimal) + { + return ::VarDecFromI4(val, pDecimal); + } + + static HRESULT InitDecimal(DOUBLE& val, DECIMAL* pDecimal) + { + return ::VarDecFromR8(val, pDecimal); + } + + static HRESULT InitVal(LONG& val, const DECIMAL* pDecimal) + { + return ::VarI4FromDec(pDecimal, &val); + } + + static HRESULT InitVal(DOUBLE& val, const DECIMAL* pDecimal) + { + return ::VarR8FromDec(pDecimal, &val); + } +}; + +// CRibbonImpl Ribbon implementation class +// +template +class CRibbonImpl : + public CRibbonUpdateUI, + public ICtrl, + public IUIApplication, + public IUICommandHandler +{ + typedef CRibbonImpl thisClass; +public: + typedef thisClass Ribbon; + typedef T WndRibbon; + + CRibbonImpl() : m_bRibbonUI(false), m_hgRibbonSettings(NULL) + { +#ifdef _DEBUG + m_cRef = 1; +#endif + pWndRibbon = static_cast(this); + HRESULT hr = ::CoInitialize(NULL); + if(SUCCEEDED(hr)) + if (RunTimeHelper::IsRibbonUIAvailable()) + hr = m_pIUIFramework.CoCreateInstance(CLSID_UIRibbonFramework); + else + ATLTRACE(L"Ribbon UI not available\n"); + + if FAILED(hr) + ATLTRACE(L"Ribbon construction failed\n"); + + ATLASSERT(SUCCEEDED(hr)); + } + + ~CRibbonImpl() + { + ::GlobalFree(m_hgRibbonSettings); + m_pIUIFramework.Release(); + ::CoUninitialize(); + } + + ICtrl& GetRibbonCtrl(UINT) + { + return static_cast(*this); + } + + ATL::CComPtr m_pIUIFramework; + HGLOBAL m_hgRibbonSettings; + bool m_bRibbonUI; + + bool IsRibbonUI() + { + return m_bRibbonUI; + } + + IUIFramework* GetIUIFrameworkPtr() + { + return m_pIUIFramework; + } + + template + I* GetRibbonViewPtr(UINT32 uID) + { + ATLASSERT(m_pIUIFramework); + ATL::CComPtr pI; + return m_pIUIFramework->GetView(uID, __uuidof(I), (void**) &pI) == S_OK ? + pI : + NULL; + } + + IUIRibbon* GetRibbonPtr() + { + return GetRibbonViewPtr(0); + } + + IUIContextualUI* GetMenuPtr(UINT32 uID) + { + ATLASSERT(uID); + return GetRibbonViewPtr(uID); + } + + UINT GetRibbonHeight() + { + ATLASSERT(IsRibbonUI()); + + UINT32 cy = 0; + if (ATL::CComPtr pIUIRibbon = GetRibbonPtr()) + pIUIRibbon->GetHeight(&cy); + return cy; + } + + HRESULT CreateRibbon(LPCWSTR sResName = L"APPLICATION_RIBBON") + { + T* pT = static_cast(this); + ATLASSERT(GetIUIFrameworkPtr() && !IsRibbonUI()); + ATLASSERT(pT->IsWindow()); + + HRESULT hr = m_pIUIFramework->Initialize(pT->m_hWnd, this); + + if (hr == S_OK) + hr = m_pIUIFramework->LoadUI(ModuleHelper::GetResourceInstance(), sResName); + + return hr; + } + + HRESULT DestroyRibbon() + { + T* pT = static_cast(this); + ATLASSERT(GetIUIFrameworkPtr() && IsRibbonUI()); + ATLASSERT(pT->IsWindow()); + + HRESULT hRes = m_pIUIFramework->Destroy(); + if (!RunTimeHelper::IsWin7()) + pT->SetWindowRgn(NULL, TRUE); // Vista Basic bug workaround + return hRes; + } + +// Ribbon persistency + HRESULT operator >>(IStream* pIStream) + { + ATLASSERT(GetIUIFrameworkPtr()); + ATLASSERT(pIStream); + + HRESULT hr = E_FAIL; + if (ATL::CComPtr pIUIRibbon = GetRibbonPtr()) + { + const LARGE_INTEGER li0 = { 0 }; + pIStream->Seek(li0, STREAM_SEEK_SET, NULL); + hr = pIUIRibbon->SaveSettingsToStream(pIStream); + pIStream->Commit(STGC_DEFAULT); + } + + return hr; + } + + HRESULT operator <<(IStream* pIStream) + { + ATLASSERT(GetIUIFrameworkPtr()); + ATLASSERT(pIStream); + + HRESULT hr = E_FAIL; + if (ATL::CComPtr pIUIRibbon = GetRibbonPtr()) + { + const LARGE_INTEGER li0 = { 0 }; + pIStream->Seek(li0, STREAM_SEEK_SET, NULL); + hr = pIUIRibbon->LoadSettingsFromStream(pIStream); + } + + return hr; + } + + void ResetRibbonSettings() + { + if (m_hgRibbonSettings != NULL) + { + ::GlobalFree(m_hgRibbonSettings); + m_hgRibbonSettings = NULL; + } + } + + HRESULT SaveRibbonSettings() + { + ATLASSERT(GetIUIFrameworkPtr()); + ATLASSERT(static_cast(this)->IsWindow()); + + HRESULT hr = E_FAIL; + ATL::CComPtr pIStream; + + if SUCCEEDED(hr = ::CreateStreamOnHGlobal(m_hgRibbonSettings, FALSE, &pIStream)) + hr = *this >> pIStream; + + if (SUCCEEDED(hr) && (m_hgRibbonSettings == NULL)) + hr = ::GetHGlobalFromStream(pIStream, &m_hgRibbonSettings); + + if FAILED(hr) + ResetRibbonSettings(); + + return hr; + } + + HRESULT RestoreRibbonSettings() + { + ATLASSERT(GetIUIFrameworkPtr()); + ATLASSERT(m_hgRibbonSettings); + ATLASSERT(static_cast(this)->IsWindow()); + + HRESULT hr = E_FAIL; + ATL::CComPtr pIStream; + + if SUCCEEDED(hr = ::CreateStreamOnHGlobal(m_hgRibbonSettings, FALSE, &pIStream)) + hr = *this << pIStream; + + if FAILED(hr) + ResetRibbonSettings(); + + return hr; + } + +// QAT dock states + UI_CONTROLDOCK GetQATDock() + { + ATLASSERT(GetIUIFrameworkPtr()); + ATLASSERT(IsRibbonUI()); + + UINT32 uDock = 0; + PROPVARIANT propvar; + ATL::CComQIPtrpIPS(GetRibbonPtr()); + + if ((pIPS != NULL) && SUCCEEDED(pIPS->GetValue(UI_PKEY_QuickAccessToolbarDock, &propvar)) && + SUCCEEDED(UIPropertyToUInt32(UI_PKEY_QuickAccessToolbarDock, propvar, &uDock))) + return (UI_CONTROLDOCK)uDock; + + ATLASSERT(FALSE); // something was wrong + return (UI_CONTROLDOCK)0; + } + + bool SetQATDock(UI_CONTROLDOCK dockState) + { + ATLASSERT(GetIUIFrameworkPtr()); + ATLASSERT(IsRibbonUI()); + + PROPVARIANT propvar; + ATLVERIFY(SUCCEEDED(SetPropertyVal(UI_PKEY_QuickAccessToolbarDock, dockState, &propvar))); + + ATL::CComQIPtrpIPS(GetRibbonPtr()); + if ((pIPS != NULL) && SUCCEEDED(pIPS->SetValue(UI_PKEY_QuickAccessToolbarDock, propvar))) + { + pIPS->Commit(); + return true; + } + + ATLASSERT(FALSE); // something was wrong + return false; + } + +// Ribbon display states + bool GetRibbonDisplayState(REFPROPERTYKEY key) + { + ATLASSERT(GetIUIFrameworkPtr()); + ATLASSERT(IsRibbonUI()); + ATLASSERT((k_(key) == k_Viewable) || (k_(key) == k_Minimized)); + + PROPVARIANT propvar; + ATL::CComQIPtrpIPS(GetRibbonPtr()); + + if ((pIPS != NULL) && SUCCEEDED(pIPS->GetValue(key, &propvar))) + { + BOOL bState = FALSE; + if SUCCEEDED(UIPropertyToBoolean(key, propvar, &bState)) + return (bState != FALSE); + } + + ATLASSERT(FALSE); // something was wrong + return false; + } + + bool SetRibbonDisplayState(REFPROPERTYKEY key, bool bState = true) + { + ATLASSERT(GetIUIFrameworkPtr()); + ATLASSERT(IsRibbonUI()); + ATLASSERT((k_(key) == k_Viewable) || (k_(key) == k_Minimized)); + + PROPVARIANT propvar; + ATLVERIFY(SUCCEEDED(SetPropertyVal(key, bState, &propvar))); + + ATL::CComQIPtrpIPS(GetRibbonPtr()); + + if ((pIPS != NULL) && SUCCEEDED(pIPS->SetValue(key, propvar))) + { + pIPS->Commit(); + return true; + } + + ATLASSERT(FALSE); // something was wrong + return false; + } + + bool IsRibbonMinimized() + { + return GetRibbonDisplayState(UI_PKEY_Minimized); + } + + bool MinimizeRibbon(bool bMinimize = true) + { + return SetRibbonDisplayState(UI_PKEY_Minimized, bMinimize); + } + + bool IsRibbonHidden() + { + return !GetRibbonDisplayState(UI_PKEY_Viewable); + } + + bool HideRibbon(bool bHide = true) + { + return SetRibbonDisplayState(UI_PKEY_Viewable, !bHide); + } + +// Ribbon colors + UI_HSBCOLOR GetRibbonColor(REFPROPERTYKEY key) + { + ATLASSERT(GetIUIFrameworkPtr()); + ATLASSERT(IsRibbonUI()); + ATLASSERT((k_(key) >= k_GlobalBackgroundColor) && (k_(key) <= k_GlobalTextColor)); + + PROPVARIANT propvar; + ATL::CComQIPtrpIPS(GetIUIFrameworkPtr()); + + if ((pIPS != NULL) && SUCCEEDED(pIPS->GetValue(key, &propvar))) + { + UINT32 color = 0; + if SUCCEEDED(UIPropertyToUInt32(key, propvar, &color)) + return color; + } + + ATLASSERT(FALSE); // something was wrong + return 0; + } + + bool SetRibbonColor(REFPROPERTYKEY key, UI_HSBCOLOR color) + { + ATLASSERT(GetIUIFrameworkPtr()); + ATLASSERT(IsRibbonUI()); + ATLASSERT((k_(key) >= k_GlobalBackgroundColor) && (k_(key) <= k_GlobalTextColor)); + + PROPVARIANT propvar; + ATLVERIFY(SUCCEEDED(SetPropertyVal(key, color, &propvar))); + + ATL::CComQIPtrpIPS(GetIUIFrameworkPtr()); + + if ((pIPS != NULL) && SUCCEEDED(pIPS->SetValue(key, propvar))) + { + pIPS->Commit(); + return true; + } + + ATLASSERT(FALSE); // something was wrong + return false; + } + +// Ribbon modes + HRESULT SetRibbonModes(INT32 iModes) + { + ATLASSERT(IsRibbonUI()); + return GetIUIFrameworkPtr()->SetModes(iModes); + } + +// Ribbon contextual tab + UI_CONTEXTAVAILABILITY GetRibbonContextAvail(UINT32 uID) + { + ATLASSERT(GetIUIFrameworkPtr()); + + PROPVARIANT propvar; + if (IsRibbonUI() && + SUCCEEDED(GetIUIFrameworkPtr()->GetUICommandProperty(uID, UI_PKEY_ContextAvailable, &propvar))) + { + UINT uav; + if (SUCCEEDED(PropVariantToUInt32(propvar, &uav))) + { + CUpdateUIBase::UIEnable(uID, uav != UI_CONTEXTAVAILABILITY_NOTAVAILABLE); + CUpdateUIBase::UISetCheck(uID, uav == UI_CONTEXTAVAILABILITY_ACTIVE); + return (UI_CONTEXTAVAILABILITY)uav; + } + } + + return UI_CONTEXTAVAILABILITY_NOTAVAILABLE; + } + + HRESULT SetRibbonContextAvail(UINT32 uID, UI_CONTEXTAVAILABILITY cav) + { + CUpdateUIBase::UIEnable(uID, cav != UI_CONTEXTAVAILABILITY_NOTAVAILABLE); + CUpdateUIBase::UISetCheck(uID, cav == UI_CONTEXTAVAILABILITY_ACTIVE); + + return SetProperty((WORD)uID, UI_PKEY_ContextAvailable, UINT32(cav)); + } + +// Ribbon context menu + bool HasRibbonMenu(UINT32 uID) + { + ATL::CComPtr pI = GetMenuPtr(uID); + return pI != NULL; + } + + HRESULT TrackRibbonMenu(UINT32 uID, INT32 x, INT32 y) + { + ATLASSERT(HasRibbonMenu(uID)); + + return IsRibbonUI() ? + ATL::CComPtr(GetMenuPtr(uID))->ShowAtLocation(x, y) : + E_FAIL; + } + + HRESULT TrackRibbonMenu(UINT32 uID, LPARAM lParam) + { + return TrackRibbonMenu(uID, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + } + +// Overrideables + HBITMAP OnRibbonQueryImage(UINT nCmdID, REFPROPERTYKEY /*key*/) + { + return DefRibbonQueryImage(nCmdID); + } + + LPCWSTR OnRibbonQueryText(UINT nCmdID, REFPROPERTYKEY key) + { + return DefRibbonQueryText(nCmdID, key); + } + + bool OnRibbonQueryState(UINT nCmdID, REFPROPERTYKEY key) + { + return DefRibbonQueryState(nCmdID, key); + } + + UI_CONTEXTAVAILABILITY OnRibbonQueryTabAvail(UINT nCmdID) + { + DWORD dwState = UIGetState(nCmdID); + return ((dwState & UPDUI_DISABLED) == UPDUI_DISABLED) ? + UI_CONTEXTAVAILABILITY_NOTAVAILABLE : + (((dwState & UPDUI_CHECKED) == UPDUI_CHECKED) ? + UI_CONTEXTAVAILABILITY_ACTIVE : + UI_CONTEXTAVAILABILITY_AVAILABLE); + } + + LPCWSTR OnRibbonQueryComboText(UINT32 /*uCtrlID*/) + { + return NULL; + } + + LPCWSTR OnRibbonQueryCategoryText(UINT32 /*uCtrlID*/, UINT32 /*uCat*/) + { + return L"Category"; + } + + UINT32 OnRibbonQueryItemCategory(UINT32 /*uCtrlID*/, UINT32 /*uItem*/) + { + return 0; + } + + LPCWSTR OnRibbonQueryItemText(UINT32 uCtrlID, UINT32 uItem) + { + return DefRibbonQueryItemText(uCtrlID, uItem); + } + + bool OnRibbonQuerySelectedItem(UINT32 /*uCtrlID*/, UINT32& /*uSel*/) + { + return false; + } + + HBITMAP OnRibbonQueryItemImage(UINT32 uCtrlID, UINT32 uItem) + { + return DefRibbonQueryItemImage(uCtrlID, uItem); + } + + UINT32 OnRibbonQueryItemCommand(UINT32 uCtrlID, UINT32 uItem) + { + return DefRibbonQueryItemCommand(uCtrlID, uItem); + } + + UI_COMMANDTYPE OnRibbonQueryItemCommandType(UINT32 /*uCtrlID*/, UINT32 /*uItem*/) + { + return UI_COMMANDTYPE_ACTION; + } + + LPCWSTR OnRibbonQueryRecentItemName(LPCWSTR sPath) + { + return ::PathFindFileName(sPath); + } + + bool OnRibbonQueryFont(UINT /*nId*/, CHARFORMAT2& /*cf*/) + { + return false; + } + + bool OnRibbonQuerySpinnerValue(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/, LONG* /*pVal*/) + { + return false; + } + + bool OnRibbonQueryFloatSpinnerValue(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/, DOUBLE* /*pVal*/) + { + return false; + } + + COLORREF OnRibbonQueryColor(UINT /*nCmdID*/) + { + return 0x800080; /*MAGENTA*/ + } + + LPCWSTR OnRibbonQueryColorLabel(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/) + { + return NULL; + } + + COLORREF* OnRibbonQueryColorArray(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/) + { + return NULL; + } + + LPCWSTR* OnRibbonQueryColorTooltips(UINT /*nCmdID*/, REFPROPERTYKEY /*key*/) + { + return NULL; + } + + bool OnRibbonItemSelected(UINT32 uCtrlID, UI_EXECUTIONVERB verb, UINT32 uItem) + { + DefCommandExecute(MAKELONG(uCtrlID, verb), uItem); + return true; + } + + void OnRibbonColorCtrlExecute(UINT32 uCtrlID, UI_EXECUTIONVERB verb, UI_SWATCHCOLORTYPE uType, COLORREF color) + { + DefRibbonColorCtrlExecute(uCtrlID, verb, uType, color); + } + + void OnRibbonFontCtrlExecute(UINT32 uCtrlID, UI_EXECUTIONVERB verb, CHARFORMAT2* pcf) + { + DefCommandExecute(MAKELONG(uCtrlID, verb), (LPARAM)pcf); + } + + void OnRibbonSpinnerCtrlExecute(UINT32 uCtrlID, LONG* pVal) + { + DefCommandExecute(uCtrlID, *pVal); + } + + void OnRibbonSpinnerCtrlExecute(UINT32 uCtrlID, DOUBLE* pVal) + { + DefCommandExecute(uCtrlID, (LPARAM)pVal); + } + + void OnRibbonCommandExecute(UINT32 uCmdID) + { + DefCommandExecute(uCmdID); + } + +// Default implementations + HBITMAP DefRibbonQueryImage(UINT nCmdID) + { + return AtlLoadBitmapImage(nCmdID, LR_CREATEDIBSECTION); + } + + bool DefRibbonQueryState(UINT nCmdID, REFPROPERTYKEY key) + { + DWORD dwState = UIGetState(nCmdID); + bool bRet = false; + switch (k_(key)) + { + case k_BooleanValue: + bRet = (dwState & UPDUI_CHECKED) == UPDUI_CHECKED; + break; + case k_Enabled: + bRet = (dwState & UPDUI_DISABLED) != UPDUI_DISABLED; + break; + default: + ATLASSERT(FALSE); + break; + } + + return bRet; + } + + LPCTSTR DefRibbonQueryText(UINT nCmdID, REFPROPERTYKEY key) + { + static WCHAR sText[RIBBONUI_MAX_TEXT] = { 0 }; + + if (k_(key) == k_Label) + return UIGetText(nCmdID); + + if (AtlLoadString(nCmdID, sText, RIBBONUI_MAX_TEXT)) + { + PWCHAR pTitle = wcschr(sText, L'\n'); + switch (k_(key)) + { + case k_Keytip: + if (PWCHAR pAmp = wcschr(sText, L'&')) + pTitle = pAmp; + if (pTitle != NULL) + *(pTitle + 2) = NULL; // fall through + case k_TooltipTitle: + return pTitle ? ++pTitle : NULL; + case k_TooltipDescription: + case k_LabelDescription: + if (pTitle != NULL) + *pTitle = NULL; + return sText; + } + } + + return NULL; + } + + LPCWSTR DefRibbonQueryItemText(UINT32 uCtrlID, UINT32 uItem) + { + return DefRibbonQueryText(uCtrlID + 1 + uItem, UI_PKEY_LabelDescription); + } + + HBITMAP DefRibbonQueryItemImage(UINT32 uCtrlID, UINT32 uItem) + { + return DefRibbonQueryImage(uCtrlID + 1 + uItem); + } + + UINT32 DefRibbonQueryItemCommand(UINT32 uCtrlID, UINT32 uItem) + { + return uCtrlID + 1 + uItem; + } + + void DefRibbonColorCtrlExecute(UINT32 uCtrlID, UI_EXECUTIONVERB verb, UI_SWATCHCOLORTYPE uType, COLORREF color) + { + switch(uType) + { + case UI_SWATCHCOLORTYPE_RGB: + break; + case UI_SWATCHCOLORTYPE_AUTOMATIC: + color = ::GetSysColor(COLOR_WINDOWTEXT); + break; + case UI_SWATCHCOLORTYPE_NOCOLOR: + color = ::GetSysColor(COLOR_WINDOW); + break; + default: + ATLASSERT(FALSE); + break; + } + + DefCommandExecute(MAKELONG(uCtrlID, verb), color); + } + + void DefCommandExecute(UINT32 uCmd, LPARAM lParam = 0) + { + static_cast(this)->PostMessage(WM_COMMAND, uCmd, lParam); + } + +// Elements setting helpers + HRESULT InvalidateCtrl(UINT32 nID) + { + return IsRibbonUI() ? + GetIUIFrameworkPtr()->InvalidateUICommand(nID, UI_INVALIDATIONS_ALLPROPERTIES, NULL) : + E_FAIL; + } + + HRESULT InvalidateProperty(UINT32 nID, REFPROPERTYKEY key, UI_INVALIDATIONS flags = UI_INVALIDATIONS_PROPERTY) + { + return IsRibbonUI() ? + GetIUIFrameworkPtr()->InvalidateUICommand(nID, flags, &key) : + E_FAIL; + } + + template + HRESULT SetProperty(WORD wID, REFPROPERTYKEY key, V val) + { + if (IsRibbonUI()) + { + PROPVARIANT var; + if (SUCCEEDED(RibbonUI::SetPropertyVal(key, val, &var))) + { + return SetProperty(wID, key, var); + } + return E_INVALIDARG; + } + else + { + return E_FAIL; + } + } + + template <> + HRESULT SetProperty(WORD nID, REFPROPERTYKEY key, PROPVARIANT var) + { + return IsRibbonUI() ? + GetIUIFrameworkPtr()->SetUICommandProperty(nID, key, var) : + E_FAIL; + } + +// Interfaces + // IUIApplication + STDMETHODIMP OnViewChanged(UINT32, UI_VIEWTYPE, IUnknown*, UI_VIEWVERB verb, INT32) + { + switch (verb) + { + case UI_VIEWVERB_CREATE: + m_bRibbonUI = true; + if (m_hgRibbonSettings != NULL) + RestoreRibbonSettings(); + break; + case UI_VIEWVERB_SIZE: + static_cast(this)->UpdateLayout(FALSE); + break; + case UI_VIEWVERB_DESTROY: + SaveRibbonSettings(); + m_bRibbonUI = false; + break; + } + + return S_OK; + } + + STDMETHODIMP OnCreateUICommand(UINT32 nCmdID, UI_COMMANDTYPE typeID, IUICommandHandler** ppCommandHandler) + { + UIAddRibbonElement(nCmdID); + if (typeID == UI_COMMANDTYPE_CONTEXT) + CUpdateUIBase::UIEnable(nCmdID, false); + *ppCommandHandler = this; + return S_OK; + } + + STDMETHODIMP OnDestroyUICommand(UINT32 nCmdID, UI_COMMANDTYPE, IUICommandHandler*) + { + UIRemoveRibbonElement(nCmdID); + return S_OK; + } + + // IUICommandHandler + STDMETHODIMP Execute(UINT nCmdID, + UI_EXECUTIONVERB verb, + const PROPERTYKEY* key, + const PROPVARIANT* ppropvarValue, + IUISimplePropertySet* pCommandExecutionProperties) + { + T* pT =static_cast(this); + return pT->GetRibbonCtrl(nCmdID).DoExecute(nCmdID, verb, key, ppropvarValue, pCommandExecutionProperties); + } + + STDMETHODIMP UpdateProperty(UINT nCmdID, REFPROPERTYKEY key, + const PROPVARIANT* ppropvarCurrentValue, PROPVARIANT* ppropvarNewValue) + { + T* pT =static_cast(this); + return pT->GetRibbonCtrl(nCmdID).DoUpdateProperty(nCmdID, key, ppropvarCurrentValue, ppropvarNewValue); + } + +#ifdef _DEBUG + // IUnknown methods (heavyweight) + STDMETHODIMP_(ULONG) AddRef() + { + return InterlockedIncrement(&m_cRef); + } + + STDMETHODIMP_(ULONG) Release() + { + LONG cRef = InterlockedDecrement(&m_cRef); + if (cRef == 0) // NoOp for breakpoint + { + cRef = 0; + } + + return cRef; + } + + STDMETHODIMP QueryInterface(REFIID iid, void** ppv) + { + if (ppv == NULL) + { + return E_POINTER; + } + else if ((iid == __uuidof(IUnknown)) || + (iid == __uuidof(IUICommandHandler)) || + (iid == __uuidof(IUIApplication))) + { + *ppv = this; + AddRef(); + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + + LONG m_cRef; +#else + // IUnknown methods (lightweight) + STDMETHODIMP QueryInterface(REFIID iid, void** ppv) + { + if ((iid == __uuidof(IUnknown)) || + (iid == __uuidof(IUICommandHandler)) || + (iid == __uuidof(IUIApplication))) + { + *ppv = this; + return S_OK; + } + return E_NOINTERFACE; + } + ULONG STDMETHODCALLTYPE AddRef() + { + return 1; + } + ULONG STDMETHODCALLTYPE Release() + { + return 1; + } +#endif + +// CRibbonImpl ICtrl implementation + virtual HRESULT DoExecute(UINT nCmdID, UI_EXECUTIONVERB verb, + const PROPERTYKEY* key, const PROPVARIANT* ppropvarValue, + IUISimplePropertySet* /*pCommandExecutionProperties*/) + { + if (key != NULL) + { + if(k_(*key) != k_BooleanValue) + { + ATLTRACE(L"Control ID %d is not handled\n", nCmdID); + return E_NOTIMPL; + } + BOOL bChecked = FALSE; + ATLVERIFY(SUCCEEDED(PropVariantToBoolean(*ppropvarValue, &bChecked))); + CUpdateUIBase::UISetCheck(nCmdID, bChecked); + } + + ATLASSERT(verb == UI_EXECUTIONVERB_EXECUTE); + verb; // avoid level 4 warning + + static_cast(this)->OnRibbonCommandExecute(nCmdID); + + return S_OK; + } + + virtual HRESULT DoUpdateProperty(UINT nCmdID, REFPROPERTYKEY key, + const PROPVARIANT* /*ppropvarCurrentValue*/, PROPVARIANT* ppropvarNewValue) + { + T* pT = static_cast(this); + HRESULT hr = E_NOTIMPL; + switch (k_(key)) + { + case k_LargeImage: + case k_LargeHighContrastImage: + case k_SmallImage: + case k_SmallHighContrastImage: + if (HBITMAP hbm = pT->OnRibbonQueryImage(nCmdID, key)) + hr = SetPropertyVal(key, GetImage(hbm, UI_OWNERSHIP_TRANSFER), ppropvarNewValue); + break; + case k_Label: + case k_Keytip: + case k_TooltipTitle: + case k_TooltipDescription: + case k_LabelDescription: + if (LPCWSTR sText = pT->OnRibbonQueryText(nCmdID, key)) + hr = SetPropertyVal(key, sText, ppropvarNewValue); + break; + case k_BooleanValue: + case k_Enabled: + hr = SetPropertyVal(key, pT->OnRibbonQueryState(nCmdID, key), ppropvarNewValue); + break; + case k_ContextAvailable: + hr = SetPropertyVal(key, pT->OnRibbonQueryTabAvail(nCmdID), ppropvarNewValue); + break; + } + + return hr; + } + +// CRibbonImpl::CRibbonXXXCtrl specialized classes + //CRibbonComboCtrl + template + class CRibbonComboCtrl : public CollectionCtrlImpl, t_items, t_categories>> + { + public: + CRibbonComboCtrl() + { } + }; + + // CRibbonItemGalleryCtrl + template + class CRibbonItemGalleryCtrl : public CollectionCtrlImpl, t_items, t_categories>> + { + public: + CRibbonItemGalleryCtrl() + { } + }; + + // CRibbonCommandGalleryCtrl + template + class CRibbonCommandGalleryCtrl : public CollectionCtrlImpl, t_items, t_categories>> + { + public: + CRibbonCommandGalleryCtrl() + { } + }; + + // CRibbonToolbarGalleryCtrl + template + class CRibbonToolbarGalleryCtrl : public ToolbarGalleryCtrlImpl + { }; + + // CRibbonSimpleComboCtrl + template + class CRibbonSimpleComboCtrl : public SimpleCollectionCtrlImpl + { }; + + // CRibbonSimpleGalleryCtrl + template + class CRibbonSimpleGalleryCtrl : public SimpleCollectionCtrlImpl + { }; + + //CRibbonRecentItemsCtrl + template + class CRibbonRecentItemsCtrl : public RecentItemsCtrlImpl + { + public: + CRibbonRecentItemsCtrl() + { } + }; + + // CRibbonColorCtrl + template + class CRibbonColorCtrl : public ColorCtrlImpl + { + public: + CRibbonColorCtrl() + { } + }; + + //CRibbonFontCtrl + template + class CRibbonFontCtrl : public FontCtrlImpl + { + public: + CRibbonFontCtrl() + { } + }; + + // CRibbonSpinnerCtrl + template + class CRibbonSpinnerCtrl : public SpinnerCtrlImpl + { + public: + CRibbonSpinnerCtrl() + { } + }; + + // CRibbonFloatSpinnerCtrl + template + class CRibbonFloatSpinnerCtrl : public SpinnerCtrlImpl + { + public: + CRibbonFloatSpinnerCtrl() + { + m_Values[4] = 1; // 1 decimal + } + }; + + // CRibbonCommandCtrl + template + class CRibbonCommandCtrl : public CommandCtrlImpl + { + public: + CRibbonCommandCtrl() + { } + }; + +// Control classes access to T instance (re-initialized in constructor) + static T* pWndRibbon; +}; + +template +__declspec(selectany) T* CRibbonImpl::pWndRibbon; + +// Control map element +#pragma warning (disable : 4510 610) // missing default constructor +typedef struct +{ + UINT uID; + ICtrl& ctrl; +} _ribbonCtrl; +#pragma warning (default : 4510 610) // missing default constructor + +}; // namespace RibbonUI + + +/////////////////////////////////////////////////////////////////////////////// +// RibbonUI Control map + +// Control map macros +#define BEGIN_RIBBON_CONTROL_MAP(theClass) \ + RibbonUI::ICtrl& GetRibbonCtrl(UINT id) \ + { \ + RibbonUI::_ribbonCtrl _ctrls[] = \ + { + +#define RIBBON_CONTROL(member) {member.GetID(), static_cast(member)}, + +#define END_RIBBON_CONTROL_MAP() \ + {0, *this} \ + }; \ + int i = 0; \ + for(; i < _countof(_ctrls) - 1; i++) \ + if (_ctrls[i].uID == id) \ + break; \ + return _ctrls[i].ctrl; \ +} + +// Control message map macros +#define RIBBON_GALLERY_CONTROL_HANDLER(id, func) \ + if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \ + { \ + bHandled = TRUE; \ + lResult = func((UI_EXECUTIONVERB)HIWORD(wParam), LOWORD(wParam), (UINT)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define RIBBON_COMBO_CONTROL_HANDLER(id, func) \ + RIBBON_GALLERY_CONTROL_HANDLER(id, func) + +#define RIBBON_FONT_CONTROL_HANDLER(id, func) \ + if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \ + { \ + bHandled = TRUE; \ + lResult = func((UI_EXECUTIONVERB)HIWORD(wParam), LOWORD(wParam), (CHARFORMAT2*)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define RIBBON_COLOR_CONTROL_HANDLER(id, func) \ + if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \ + { \ + bHandled = TRUE; \ + lResult = func((UI_EXECUTIONVERB)HIWORD(wParam), LOWORD(wParam), (COLORREF)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define RIBBON_SPINNER_CONTROL_HANDLER(id, func) \ + if(uMsg == WM_COMMAND && id == wParam) \ + { \ + bHandled = TRUE; \ + lResult = func((WORD)wParam, (LONG)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define RIBBON_FLOATSPINNER_CONTROL_HANDLER(id, func) \ + if(uMsg == WM_COMMAND && id == wParam) \ + { \ + bHandled = TRUE; \ + lResult = func((WORD)wParam, (DOUBLE*)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +// Handler prototypes +/* + LRESULT OnRibbonGalleryCtrl(UI_EXECUTIONVERB verb, WORD wID, UINT uSel, BOOL& bHandled); + LRESULT OnRibbonComboCtrl(UI_EXECUTIONVERB verb, WORD wID, UINT uSel, BOOL& bHandled); + LRESULT OnRibbonFontCtrl(UI_EXECUTIONVERB verb, WORD wID, CHARFORMAT2* pcf, BOOL& bHandled); + LRESULT OnRibbonColorCtrl(UI_EXECUTIONVERB verb, WORD wID, COLORREF color, BOOL& bHandled); + LRESULT OnRibbonSpinnerCtrl(WORD wID, LONG lVal, BOOL& bHandled); + LRESULT OnRibbonFloatSpinnerCtrl(WORD wID, DOUBLE* pdVal, BOOL& bHandled); +*/ + + +/////////////////////////////////////////////////////////////////////////////// +// Ribbon frame classes + +// CRibbonFrameWindowImplBase +// +template +class ATL_NO_VTABLE CRibbonFrameWindowImplBase : public TFrameImpl, public RibbonUI::CRibbonImpl +{ + typedef TFrameImpl baseFrame; + bool m_bUseCommandBarBitmaps; + bool m_bWin7Fix; + +public: +// Construction + CRibbonFrameWindowImplBase(bool bUseCommandBarBitmaps = true) : + m_bUseCommandBarBitmaps(bUseCommandBarBitmaps), m_bWin7Fix(false) + { + __if_not_exists(T::m_CmdBar) + { + m_bUseCommandBarBitmaps = false; + } + } + +// Win7 Aero fix helpers + void ResetFrame() + { + const MARGINS margins = { 0 }; + ::DwmExtendFrameIntoClientArea(m_hWnd, &margins); + } + + INT CalcWin7Fix() + { + ResetFrame(); + RECT rc = { 0 }; + ::AdjustWindowRectEx(&rc, T::GetWndStyle(0), GetMenu() != NULL, T::GetWndExStyle(0)); + return -rc.top; + } + + bool NeedWin7Fix() + { + BOOL bComp = FALSE; + return m_bWin7Fix && RunTimeHelper::IsWin7() && SUCCEEDED(DwmIsCompositionEnabled(&bComp)) && bComp; + } + +// Operations + bool UseCommandBarBitmaps(bool bUse) + { + __if_exists(T::m_CmdBar) + { + return m_bUseCommandBarBitmaps = bUse; + } + __if_not_exists(T::m_CmdBar) + { + bUse; // avoid level 4 warning + return false; + } + } + + bool ShowRibbonUI(bool bShow, INT32 imodes = UI_MAKEAPPMODE(0), LPCWSTR sResName = L"APPLICATION_RIBBON") + { + if (!RunTimeHelper::IsRibbonUIAvailable()) + return false; + + ATLASSERT(GetIUIFrameworkPtr()); + + if (IsRibbonUI() == bShow) + return bShow; + + bool bVisible = (IsWindowVisible() != FALSE); + if(bVisible && !bShow) + SetRedraw(FALSE); + + if (bShow && ::IsWindow(m_hWndToolBar)) + { + ::ShowWindow(m_hWndToolBar, SW_HIDE); + UpdateLayout(); + } + + m_bWin7Fix = !bShow; + + HRESULT hr = bShow ? CreateRibbon(sResName) : DestroyRibbon(); + + m_bWin7Fix = SUCCEEDED(hr) && !bShow; + + if (SUCCEEDED(hr)) + { + if(::IsWindow(m_hWndToolBar) && !bShow) + { + ::ShowWindow(m_hWndToolBar, SW_SHOWNA); + UpdateLayout(); + } + else if (bShow) + { + PostMessage(WM_SIZE); + SetRibbonModes(imodes); + } + } + + if(bVisible && !bShow) + { + SetRedraw(TRUE); + RedrawWindow(NULL, NULL, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); + } + + return SUCCEEDED(hr) ? bShow : !bShow; + } + +// Overrideables + HBITMAP OnRibbonQueryImage(UINT nCmdID, REFPROPERTYKEY key) + { + if ((key == UI_PKEY_SmallImage) && m_bUseCommandBarBitmaps) + { + if (HBITMAP hbm = GetCommandBarBitmap(nCmdID)) + return (HBITMAP)::CopyImage(hbm, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); + } + + return DefRibbonQueryImage(nCmdID); + } + + BEGIN_MSG_MAP(CRibbonFrameWindowImplBase) + if (!IsRibbonUI() && NeedWin7Fix()) + { + MESSAGE_HANDLER(WM_SIZING, OnSizing) + MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_ACTIVATE, OnActivate) + MESSAGE_HANDLER(WM_NCCALCSIZE, OnNCCalcSize) + } + CHAIN_MSG_MAP(CRibbonUpdateUI) + CHAIN_MSG_MAP(baseFrame) + END_MSG_MAP() + +// Message handlers for Win7 Aero + LRESULT OnSizing(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + switch (wParam) + { + case WMSZ_TOP: + case WMSZ_TOPLEFT: + case WMSZ_TOPRIGHT: + SetWindowPos(NULL, (LPRECT)lParam, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED); + break; + default: + DefWindowProc(); + break; + } + + return 1; // handled + } + + LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if (wParam != SIZE_MINIMIZED) + SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); + + bHandled = FALSE; + return 1; + } + + LRESULT OnActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if(wParam != WA_INACTIVE) + SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); + + bHandled = FALSE; + return 1; + } + + LRESULT OnNCCalcSize(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + ATLASSERT(!IsRibbonUI() && NeedWin7Fix()); + + LRESULT lRet = DefWindowProc(); + + if(wParam) + { + LPNCCALCSIZE_PARAMS pParams = (LPNCCALCSIZE_PARAMS)lParam; + pParams->rgrc[0].top = pParams->rgrc[1].top + CalcWin7Fix(); + } + + return lRet; + } + +// Overrides + void UpdateLayout(BOOL bResizeBars = TRUE) + { + RECT rect = { 0 }; + GetClientRect(&rect); + + if (IsRibbonUI() && !IsRibbonHidden()) + { + rect.top += GetRibbonHeight(); + } + else if (!IsRibbonUI() && NeedWin7Fix()) + { + ResetFrame(); + } + + // position bars and offset their dimensions + UpdateBarsPosition(rect, bResizeBars); + + // resize client window + if(m_hWndClient != NULL) + ::SetWindowPos(m_hWndClient, NULL, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, + SWP_NOZORDER | SWP_NOACTIVATE); + } + + // Implementation + HBITMAP GetCommandBarBitmap(UINT nCmdID) + { + __if_exists (T::m_CmdBar) + { + ATLASSERT(RunTimeHelper::IsVista()); + T* pT =static_cast(this); + int nIndex = pT->m_CmdBar.m_arrCommand.Find((WORD&)nCmdID); + return (nIndex == -1) ? NULL : pT->m_CmdBar.m_arrVistaBitmap[nIndex]; + } + __if_not_exists (T::m_CmdBar) + { + nCmdID; // avoid level 4 warning + return NULL; + } + } +}; + +// CRibbonFrameWindowImpl +// +template +class ATL_NO_VTABLE CRibbonFrameWindowImpl : public CRibbonFrameWindowImplBase> +{ }; + +// CRibbonMDIFrameWindowImpl +// +template +class ATL_NO_VTABLE CRibbonMDIFrameWindowImpl : public CRibbonFrameWindowImplBase> +{ }; + + +/////////////////////////////////////////////////////////////////////////////// +// CRibbonPersist helper for RibbonUI persistency + +class CRibbonPersist +{ +public: + CRibbonPersist(LPCWSTR sAppKey) + { + ATLASSERT(sAppKey && *sAppKey); + m_Key.Create(HKEY_CURRENT_USER, sAppKey); + ATLASSERT(m_Key.m_hKey); + } + + CRegKeyEx m_Key; + + LONG Save(bool bRibbonUI, HGLOBAL hgSettings = NULL) + { + CRegKeyEx key; + const DWORD dwUI = bRibbonUI; + + LONG lRet = key.Create(m_Key, L"Ribbon"); + if(lRet != ERROR_SUCCESS) + return lRet; + + lRet = key.SetDWORDValue(L"UI", dwUI); + if(lRet != ERROR_SUCCESS) + return lRet; + + if (hgSettings != NULL) + { + LPBYTE pVal = (LPBYTE)::GlobalLock(hgSettings); + if (pVal != NULL) + { + lRet = key.SetBinaryValue(L"Settings", pVal, ::GlobalSize(hgSettings)); + ::GlobalUnlock(hgSettings); + } + else + { + lRet = GetLastError(); + } + } + + return lRet; + } + + LONG Restore(bool& bRibbonUI, HGLOBAL& hgSettings) + { + ATLASSERT(hgSettings == NULL); + + CRegKeyEx key; + + LONG lRet = key.Open(m_Key, L"Ribbon"); + if(lRet != ERROR_SUCCESS) + return lRet; + + DWORD dwUI = 0xffff; + lRet = key.QueryDWORDValue(L"UI", dwUI); + if(lRet == ERROR_SUCCESS) + bRibbonUI = dwUI == 1; + else + return lRet; + + ULONG ulSize = 0; + lRet = key.QueryBinaryValue(L"Settings", NULL, &ulSize); + if (lRet == ERROR_SUCCESS) + { + ATLASSERT(ulSize != 0); + + hgSettings = ::GlobalAlloc(GHND, ulSize); + if (hgSettings != NULL) + { + LPBYTE pData = (LPBYTE)::GlobalLock(hgSettings); + if (pData != NULL) + { + lRet = key.QueryBinaryValue(L"Settings", pData, &ulSize); + } + else + { + lRet = GetLastError(); + ::GlobalFree(hgSettings); + hgSettings = NULL; + } + } + else + { + lRet = GetLastError(); + } + } + return lRet; + } + + LONG Delete() + { + return m_Key.DeleteSubKey(L"Ribbon"); + } +}; + +} // namespace WTL + +#endif // __ATLRIBBON_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlscrl.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlscrl.h new file mode 100644 index 0000000000..0f59c9dd58 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlscrl.h @@ -0,0 +1,2011 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLSCRL_H__ +#define __ATLSCRL_H__ + +#pragma once + +#ifndef __ATLAPP_H__ + #error atlscrl.h requires atlapp.h to be included first +#endif + +#ifndef __ATLWIN_H__ + #error atlscrl.h requires atlwin.h to be included first +#endif + +#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) + #include +#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) + +#ifndef GET_WHEEL_DELTA_WPARAM + #define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam)) +#endif + +#ifndef WM_MOUSEHWHEEL + #define WM_MOUSEHWHEEL 0x020E +#endif + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CScrollImpl +// CScrollWindowImpl +// CMapScrollImpl +// CMapScrollWindowImpl +// CFSBWindowT +// CZoomScrollImpl +// CZoomScrollWindowImpl +// CScrollContainerImpl +// CScrollContainer + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// CScrollImpl - Provides scrolling support to any window + +// Scroll extended styles +#define SCRL_SCROLLCHILDREN 0x00000001 +#define SCRL_ERASEBACKGROUND 0x00000002 +#define SCRL_NOTHUMBTRACKING 0x00000004 +#if (WINVER >= 0x0500) +#define SCRL_SMOOTHSCROLL 0x00000008 +#endif // (WINVER >= 0x0500) +#define SCRL_DISABLENOSCROLLV 0x00000010 +#define SCRL_DISABLENOSCROLLH 0x00000020 +#define SCRL_DISABLENOSCROLL (SCRL_DISABLENOSCROLLV | SCRL_DISABLENOSCROLLH) + + +template +class CScrollImpl +{ +public: + enum { uSCROLL_FLAGS = SW_INVALIDATE }; + + POINT m_ptOffset; + SIZE m_sizeAll; + SIZE m_sizeLine; + SIZE m_sizePage; + SIZE m_sizeClient; + int m_zDelta; // current wheel value + int m_nWheelLines; // number of lines to scroll on wheel +#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) + // Note that this message must be forwarded from a top level window + UINT m_uMsgMouseWheel; // MSH_MOUSEWHEEL +#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) + int m_zHDelta; // current horizontal wheel value + int m_nHWheelChars; // number of chars to scroll on horizontal wheel + UINT m_uScrollFlags; + DWORD m_dwExtendedStyle; // scroll specific extended styles + +// Constructor + CScrollImpl() : m_zDelta(0), m_nWheelLines(3), +#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) + m_uMsgMouseWheel(0U), +#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) + m_zHDelta(0), m_nHWheelChars(3), + m_uScrollFlags(0U), m_dwExtendedStyle(0) + { + m_ptOffset.x = 0; + m_ptOffset.y = 0; + m_sizeAll.cx = 0; + m_sizeAll.cy = 0; + m_sizePage.cx = 0; + m_sizePage.cy = 0; + m_sizeLine.cx = 0; + m_sizeLine.cy = 0; + m_sizeClient.cx = 0; + m_sizeClient.cy = 0; + + SetScrollExtendedStyle(SCRL_SCROLLCHILDREN | SCRL_ERASEBACKGROUND); + } + +// Attributes & Operations + DWORD GetScrollExtendedStyle() const + { + return m_dwExtendedStyle; + } + + DWORD SetScrollExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) + { + DWORD dwPrevStyle = m_dwExtendedStyle; + if(dwMask == 0) + m_dwExtendedStyle = dwExtendedStyle; + else + m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); + // cache scroll flags + T* pT = static_cast(this); + pT; // avoid level 4 warning + m_uScrollFlags = pT->uSCROLL_FLAGS | (IsScrollingChildren() ? SW_SCROLLCHILDREN : 0) | (IsErasingBackground() ? SW_ERASE : 0); +#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) + m_uScrollFlags |= (IsSmoothScroll() ? SW_SMOOTHSCROLL : 0); +#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) + return dwPrevStyle; + } + + // offset operations + void SetScrollOffset(int x, int y, BOOL bRedraw = TRUE) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + + pT->AdjustScrollOffset(x, y); + + int dx = m_ptOffset.x - x; + int dy = m_ptOffset.y - y; + m_ptOffset.x = x; + m_ptOffset.y = y; + + // block: set horizontal scroll bar + { + SCROLLINFO si = { sizeof(SCROLLINFO) }; + si.fMask = SIF_POS; + if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLH) != 0) + si.fMask |= SIF_DISABLENOSCROLL; + si.nPos = m_ptOffset.x; + pT->SetScrollInfo(SB_HORZ, &si, bRedraw); + } + + // block: set vertical scroll bar + { + SCROLLINFO si = { sizeof(SCROLLINFO) }; + si.fMask = SIF_POS; + if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLV) != 0) + si.fMask |= SIF_DISABLENOSCROLL; + si.nPos = m_ptOffset.y; + pT->SetScrollInfo(SB_VERT, &si, bRedraw); + } + + // Move all children if needed + if(IsScrollingChildren() && (dx != 0 || dy != 0)) + { + for(HWND hWndChild = ::GetWindow(pT->m_hWnd, GW_CHILD); hWndChild != NULL; hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT)) + { + RECT rect = { 0 }; + ::GetWindowRect(hWndChild, &rect); + ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rect, 1); + ::SetWindowPos(hWndChild, NULL, rect.left + dx, rect.top + dy, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); + } + } + + if(bRedraw) + pT->Invalidate(); + } + + void SetScrollOffset(POINT ptOffset, BOOL bRedraw = TRUE) + { + SetScrollOffset(ptOffset.x, ptOffset.y, bRedraw); + } + + void GetScrollOffset(POINT& ptOffset) const + { + ptOffset = m_ptOffset; + } + + // size operations + void SetScrollSize(int cx, int cy, BOOL bRedraw = TRUE, bool bResetOffset = true) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + + m_sizeAll.cx = cx; + m_sizeAll.cy = cy; + + int x = 0; + int y = 0; + if(!bResetOffset) + { + x = m_ptOffset.x; + y = m_ptOffset.y; + pT->AdjustScrollOffset(x, y); + } + + int dx = m_ptOffset.x - x; + int dy = m_ptOffset.y - y; + m_ptOffset.x = x; + m_ptOffset.y = y; + + // block: set horizontal scroll bar + { + SCROLLINFO si = { sizeof(SCROLLINFO) }; + si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; + if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLH) != 0) + si.fMask |= SIF_DISABLENOSCROLL; + si.nMin = 0; + si.nMax = m_sizeAll.cx - 1; + si.nPage = m_sizeClient.cx; + si.nPos = m_ptOffset.x; + pT->SetScrollInfo(SB_HORZ, &si, bRedraw); + } + + // block: set vertical scroll bar + { + SCROLLINFO si = { sizeof(SCROLLINFO) }; + si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; + if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLV) != 0) + si.fMask |= SIF_DISABLENOSCROLL; + si.nMin = 0; + si.nMax = m_sizeAll.cy - 1; + si.nPage = m_sizeClient.cy; + si.nPos = m_ptOffset.y; + pT->SetScrollInfo(SB_VERT, &si, bRedraw); + } + + // Move all children if needed + if(IsScrollingChildren() && (dx != 0 || dy != 0)) + { + for(HWND hWndChild = ::GetWindow(pT->m_hWnd, GW_CHILD); hWndChild != NULL; hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT)) + { + RECT rect = { 0 }; + ::GetWindowRect(hWndChild, &rect); + ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rect, 1); + ::SetWindowPos(hWndChild, NULL, rect.left + dx, rect.top + dy, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); + } + } + + SetScrollLine(0, 0); + SetScrollPage(0, 0); + + if(bRedraw) + pT->Invalidate(); + } + + void SetScrollSize(SIZE size, BOOL bRedraw = TRUE, bool bResetOffset = true) + { + SetScrollSize(size.cx, size.cy, bRedraw, bResetOffset); + } + + void GetScrollSize(SIZE& sizeWnd) const + { + sizeWnd = m_sizeAll; + } + + // line operations + void SetScrollLine(int cxLine, int cyLine) + { + ATLASSERT(cxLine >= 0 && cyLine >= 0); + ATLASSERT(m_sizeAll.cx != 0 && m_sizeAll.cy != 0); + + m_sizeLine.cx = T::CalcLineOrPage(cxLine, m_sizeAll.cx, 100); + m_sizeLine.cy = T::CalcLineOrPage(cyLine, m_sizeAll.cy, 100); + } + + void SetScrollLine(SIZE sizeLine) + { + SetScrollLine(sizeLine.cx, sizeLine.cy); + } + + void GetScrollLine(SIZE& sizeLine) const + { + sizeLine = m_sizeLine; + } + + // page operations + void SetScrollPage(int cxPage, int cyPage) + { + ATLASSERT(cxPage >= 0 && cyPage >= 0); + ATLASSERT(m_sizeAll.cx != 0 && m_sizeAll.cy != 0); + + m_sizePage.cx = T::CalcLineOrPage(cxPage, m_sizeAll.cx, 10); + m_sizePage.cy = T::CalcLineOrPage(cyPage, m_sizeAll.cy, 10); + } + + void SetScrollPage(SIZE sizePage) + { + SetScrollPage(sizePage.cx, sizePage.cy); + } + + void GetScrollPage(SIZE& sizePage) const + { + sizePage = m_sizePage; + } + + // commands + void ScrollLineDown() + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + pT->DoScroll(SB_VERT, SB_LINEDOWN, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy); + } + + void ScrollLineUp() + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + pT->DoScroll(SB_VERT, SB_LINEUP, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy); + } + + void ScrollPageDown() + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + pT->DoScroll(SB_VERT, SB_PAGEDOWN, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy); + } + + void ScrollPageUp() + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + pT->DoScroll(SB_VERT, SB_PAGEUP, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy); + } + + void ScrollTop() + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + pT->DoScroll(SB_VERT, SB_TOP, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy); + } + + void ScrollBottom() + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + pT->DoScroll(SB_VERT, SB_BOTTOM, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy); + } + + void ScrollLineRight() + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + pT->DoScroll(SB_HORZ, SB_LINEDOWN, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); + } + + void ScrollLineLeft() + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + pT->DoScroll(SB_HORZ, SB_LINEUP, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); + } + + void ScrollPageRight() + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + pT->DoScroll(SB_HORZ, SB_PAGEDOWN, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); + } + + void ScrollPageLeft() + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + pT->DoScroll(SB_HORZ, SB_PAGEUP, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); + } + + void ScrollAllLeft() + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + pT->DoScroll(SB_HORZ, SB_TOP, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); + } + + void ScrollAllRight() + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + pT->DoScroll(SB_HORZ, SB_BOTTOM, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); + } + + // scroll to make point/view/window visible + void ScrollToView(POINT pt) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + RECT rect = { pt.x, pt.y, pt.x, pt.y }; + pT->ScrollToView(rect); + } + + void ScrollToView(RECT& rect) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + + RECT rcClient = { 0 }; + pT->GetClientRect(&rcClient); + + int x = m_ptOffset.x; + if(rect.left < m_ptOffset.x) + x = rect.left; + else if(rect.right > (m_ptOffset.x + rcClient.right)) + x = rect.right - rcClient.right; + + int y = m_ptOffset.y; + if(rect.top < m_ptOffset.y) + y = rect.top; + else if(rect.bottom > (m_ptOffset.y + rcClient.bottom)) + y = rect.bottom - rcClient.bottom; + + SetScrollOffset(x, y); + } + + void ScrollToView(HWND hWnd) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + + RECT rect = { 0 }; + ::GetWindowRect(hWnd, &rect); + ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rect, 2); + ScrollToView(rect); + } + + BEGIN_MSG_MAP(CScrollImpl) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_VSCROLL, OnVScroll) + MESSAGE_HANDLER(WM_HSCROLL, OnHScroll) + MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel) +#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) + MESSAGE_HANDLER(m_uMsgMouseWheel, OnMouseWheel) +#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) + MESSAGE_HANDLER(WM_MOUSEHWHEEL, OnMouseHWheel) + MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) + MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_PAINT, OnPaint) +#ifndef _WIN32_WCE + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) +#endif // !_WIN32_WCE + // standard scroll commands + ALT_MSG_MAP(1) + COMMAND_ID_HANDLER(ID_SCROLL_UP, OnScrollUp) + COMMAND_ID_HANDLER(ID_SCROLL_DOWN, OnScrollDown) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, OnScrollPageUp) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, OnScrollPageDown) + COMMAND_ID_HANDLER(ID_SCROLL_TOP, OnScrollTop) + COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, OnScrollBottom) + COMMAND_ID_HANDLER(ID_SCROLL_LEFT, OnScrollLeft) + COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, OnScrollRight) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, OnScrollPageLeft) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, OnScrollPageRight) + COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, OnScrollAllLeft) + COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, OnScrollAllRight) + END_MSG_MAP() + + LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + GetSystemSettings(); + bHandled = FALSE; + return 1; + } + + LRESULT OnVScroll(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + pT->DoScroll(SB_VERT, (int)(short)LOWORD(wParam), (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy); + return 0; + } + + LRESULT OnHScroll(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + pT->DoScroll(SB_HORZ, (int)(short)LOWORD(wParam), (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); + return 0; + } + + LRESULT OnMouseWheel(UINT uMsg, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + +#if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400) || defined(_WIN32_WCE) + uMsg; + int zDelta = (int)GET_WHEEL_DELTA_WPARAM(wParam); +#else + int zDelta = (uMsg == WM_MOUSEWHEEL) ? (int)GET_WHEEL_DELTA_WPARAM(wParam) : (int)wParam; +#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400) || defined(_WIN32_WCE)) + int nScrollCode = (m_nWheelLines == WHEEL_PAGESCROLL) ? ((zDelta > 0) ? SB_PAGEUP : SB_PAGEDOWN) : ((zDelta > 0) ? SB_LINEUP : SB_LINEDOWN); + m_zDelta += zDelta; // cumulative + int zTotal = (m_nWheelLines == WHEEL_PAGESCROLL) ? abs(m_zDelta) : abs(m_zDelta) * m_nWheelLines; + if(m_sizeAll.cy > m_sizeClient.cy) + { + for(int i = 0; i < zTotal; i += WHEEL_DELTA) + { + pT->DoScroll(SB_VERT, nScrollCode, (int&)m_ptOffset.y, m_sizeAll.cy, m_sizePage.cy, m_sizeLine.cy); + pT->UpdateWindow(); + } + } + else // can't scroll vertically, scroll horizontally + { + for(int i = 0; i < zTotal; i += WHEEL_DELTA) + { + pT->DoScroll(SB_HORZ, nScrollCode, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); + pT->UpdateWindow(); + } + } + m_zDelta %= WHEEL_DELTA; + + return 0; + } + + LRESULT OnMouseHWheel(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + + int zDelta = (int)GET_WHEEL_DELTA_WPARAM(wParam); + int nScrollCode = (m_nHWheelChars == WHEEL_PAGESCROLL) ? ((zDelta > 0) ? SB_PAGERIGHT : SB_PAGELEFT) : ((zDelta > 0) ? SB_LINERIGHT : SB_LINELEFT); + m_zHDelta += zDelta; // cumulative + int zTotal = (m_nHWheelChars == WHEEL_PAGESCROLL) ? abs(m_zHDelta) : abs(m_zHDelta) * m_nHWheelChars; + if(m_sizeAll.cx > m_sizeClient.cx) + { + for(int i = 0; i < zTotal; i += WHEEL_DELTA) + { + pT->DoScroll(SB_HORZ, nScrollCode, (int&)m_ptOffset.x, m_sizeAll.cx, m_sizePage.cx, m_sizeLine.cx); + pT->UpdateWindow(); + } + } + m_zHDelta %= WHEEL_DELTA; + + return 0; + } + + LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + GetSystemSettings(); + return 0; + } + + LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + + m_sizeClient.cx = GET_X_LPARAM(lParam); + m_sizeClient.cy = GET_Y_LPARAM(lParam); + + // block: set horizontal scroll bar + { + SCROLLINFO si = { sizeof(SCROLLINFO) }; + si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; + si.nMin = 0; + si.nMax = m_sizeAll.cx - 1; + if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLH) != 0) + si.fMask |= SIF_DISABLENOSCROLL; + si.nPage = m_sizeClient.cx; + si.nPos = m_ptOffset.x; + pT->SetScrollInfo(SB_HORZ, &si, TRUE); + } + + // block: set vertical scroll bar + { + SCROLLINFO si = { sizeof(SCROLLINFO) }; + si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; + si.nMin = 0; + si.nMax = m_sizeAll.cy - 1; + if((m_dwExtendedStyle & SCRL_DISABLENOSCROLLV) != 0) + si.fMask |= SIF_DISABLENOSCROLL; + si.nPage = m_sizeClient.cy; + si.nPos = m_ptOffset.y; + pT->SetScrollInfo(SB_VERT, &si, TRUE); + } + + int x = m_ptOffset.x; + int y = m_ptOffset.y; + if(pT->AdjustScrollOffset(x, y)) + { + // Children will be moved in SetScrollOffset, if needed + pT->ScrollWindowEx(m_ptOffset.x - x, m_ptOffset.y - y, (m_uScrollFlags & ~SCRL_SCROLLCHILDREN)); + SetScrollOffset(x, y, FALSE); + } + + bHandled = FALSE; + return 1; + } + + LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + if(wParam != NULL) + { + CDCHandle dc = (HDC)wParam; + POINT ptViewportOrg = { 0, 0 }; + dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewportOrg); + pT->DoPaint(dc); + dc.SetViewportOrg(ptViewportOrg); + } + else + { + CPaintDC dc(pT->m_hWnd); + dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y); + pT->DoPaint(dc.m_hDC); + } + return 0; + } + + // scrolling handlers + LRESULT OnScrollUp(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + ScrollLineUp(); + return 0; + } + + LRESULT OnScrollDown(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + ScrollLineDown(); + return 0; + } + + LRESULT OnScrollPageUp(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + ScrollPageUp(); + return 0; + } + + LRESULT OnScrollPageDown(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + ScrollPageDown(); + return 0; + } + + LRESULT OnScrollTop(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + ScrollTop(); + return 0; + } + + LRESULT OnScrollBottom(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + ScrollBottom(); + return 0; + } + + LRESULT OnScrollLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + ScrollLineLeft(); + return 0; + } + + LRESULT OnScrollRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + ScrollLineRight(); + return 0; + } + + LRESULT OnScrollPageLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + ScrollPageLeft(); + return 0; + } + + LRESULT OnScrollPageRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + ScrollPageRight(); + return 0; + } + + LRESULT OnScrollAllLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + ScrollAllLeft(); + return 0; + } + + LRESULT OnScrollAllRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + ScrollAllRight(); + return 0; + } + +// Overrideables + void DoPaint(CDCHandle /*dc*/) + { + // must be implemented in a derived class + ATLASSERT(FALSE); + } + +// Implementation + void DoScroll(int nType, int nScrollCode, int& cxyOffset, int cxySizeAll, int cxySizePage, int cxySizeLine) + { + T* pT = static_cast(this); + RECT rect = { 0 }; + pT->GetClientRect(&rect); + int cxyClient = (nType == SB_VERT) ? rect.bottom : rect.right; + int cxyMax = cxySizeAll - cxyClient; + + if(cxyMax < 0) // can't scroll, client area is bigger + return; + + bool bUpdate = true; + int cxyScroll = 0; + + switch(nScrollCode) + { + case SB_TOP: // top or all left + cxyScroll = cxyOffset; + cxyOffset = 0; + break; + case SB_BOTTOM: // bottom or all right + cxyScroll = cxyOffset - cxyMax; + cxyOffset = cxyMax; + break; + case SB_LINEUP: // line up or line left + if(cxyOffset >= cxySizeLine) + { + cxyScroll = cxySizeLine; + cxyOffset -= cxySizeLine; + } + else + { + cxyScroll = cxyOffset; + cxyOffset = 0; + } + break; + case SB_LINEDOWN: // line down or line right + if(cxyOffset < cxyMax - cxySizeLine) + { + cxyScroll = -cxySizeLine; + cxyOffset += cxySizeLine; + } + else + { + cxyScroll = cxyOffset - cxyMax; + cxyOffset = cxyMax; + } + break; + case SB_PAGEUP: // page up or page left + if(cxyOffset >= cxySizePage) + { + cxyScroll = cxySizePage; + cxyOffset -= cxySizePage; + } + else + { + cxyScroll = cxyOffset; + cxyOffset = 0; + } + break; + case SB_PAGEDOWN: // page down or page right + if(cxyOffset < cxyMax - cxySizePage) + { + cxyScroll = -cxySizePage; + cxyOffset += cxySizePage; + } + else + { + cxyScroll = cxyOffset - cxyMax; + cxyOffset = cxyMax; + } + break; + case SB_THUMBTRACK: + if(IsNoThumbTracking()) + break; + // else fall through + case SB_THUMBPOSITION: + { + SCROLLINFO si = { sizeof(SCROLLINFO), SIF_TRACKPOS }; + if(pT->GetScrollInfo(nType, &si)) + { + cxyScroll = cxyOffset - si.nTrackPos; + cxyOffset = si.nTrackPos; + } + } + break; + case SB_ENDSCROLL: + default: + bUpdate = false; + break; + } + + if(bUpdate && cxyScroll != 0) + { + pT->SetScrollPos(nType, cxyOffset, TRUE); + if(nType == SB_VERT) + pT->ScrollWindowEx(0, cxyScroll, m_uScrollFlags); + else + pT->ScrollWindowEx(cxyScroll, 0, m_uScrollFlags); + } + } + + static int CalcLineOrPage(int nVal, int nMax, int nDiv) + { + if(nVal == 0) + { + nVal = nMax / nDiv; + if(nVal < 1) + nVal = 1; + } + else if(nVal > nMax) + { + nVal = nMax; + } + + return nVal; + } + + bool AdjustScrollOffset(int& x, int& y) + { + int xOld = x; + int yOld = y; + + int cxMax = m_sizeAll.cx - m_sizeClient.cx; + if(x > cxMax) + x = (cxMax >= 0) ? cxMax : 0; + else if(x < 0) + x = 0; + + int cyMax = m_sizeAll.cy - m_sizeClient.cy; + if(y > cyMax) + y = (cyMax >= 0) ? cyMax : 0; + else if(y < 0) + y = 0; + + return (x != xOld || y != yOld); + } + + void GetSystemSettings() + { +#ifndef _WIN32_WCE +#ifndef SPI_GETWHEELSCROLLLINES + const UINT SPI_GETWHEELSCROLLLINES = 104; +#endif // !SPI_GETWHEELSCROLLLINES + ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &m_nWheelLines, 0); + +#ifndef SPI_GETWHEELSCROLLCHARS + const UINT SPI_GETWHEELSCROLLCHARS = 0x006C; +#endif // !SPI_GETWHEELSCROLLCHARS + ::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &m_nHWheelChars, 0); + +#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) + if(m_uMsgMouseWheel != 0) + m_uMsgMouseWheel = ::RegisterWindowMessage(MSH_MOUSEWHEEL); + + HWND hWndWheel = FindWindow(MSH_WHEELMODULE_CLASS, MSH_WHEELMODULE_TITLE); + if(::IsWindow(hWndWheel)) + { + UINT uMsgScrollLines = ::RegisterWindowMessage(MSH_SCROLL_LINES); + if(uMsgScrollLines != 0) + m_nWheelLines = (int)::SendMessage(hWndWheel, uMsgScrollLines, 0, 0L); + } +#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) +#endif // !_WIN32_WCE + } + + bool IsScrollingChildren() const + { + return (m_dwExtendedStyle & SCRL_SCROLLCHILDREN) != 0; + } + + bool IsErasingBackground() const + { + return (m_dwExtendedStyle & SCRL_ERASEBACKGROUND) != 0; + } + + bool IsNoThumbTracking() const + { + return (m_dwExtendedStyle & SCRL_NOTHUMBTRACKING) != 0; + } + +#if (WINVER >= 0x0500) + bool IsSmoothScroll() const + { + return (m_dwExtendedStyle & SCRL_SMOOTHSCROLL) != 0; + } +#endif // (WINVER >= 0x0500) +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CScrollWindowImpl - Implements a scrollable window + +template +class ATL_NO_VTABLE CScrollWindowImpl : public ATL::CWindowImpl, public CScrollImpl< T > +{ +public: + BEGIN_MSG_MAP(CScrollWindowImpl) + MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll) + MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll) + MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel) +#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) + MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel) +#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) && !defined(_WIN32_WCE) + MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel) + MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange) + MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize) + MESSAGE_HANDLER(WM_PAINT, CScrollImpl< T >::OnPaint) +#ifndef _WIN32_WCE + MESSAGE_HANDLER(WM_PRINTCLIENT, CScrollImpl< T >::OnPaint) +#endif // !_WIN32_WCE + ALT_MSG_MAP(1) + COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp) + COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown) + COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop) + COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom) + COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft) + COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight) + COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft) + COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight) + END_MSG_MAP() +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CMapScrollImpl - Provides mapping and scrolling support to any window + +#ifndef _WIN32_WCE + +template +class CMapScrollImpl : public CScrollImpl< T > +{ +public: + int m_nMapMode; + RECT m_rectLogAll; + SIZE m_sizeLogLine; + SIZE m_sizeLogPage; + +// Constructor + CMapScrollImpl() : m_nMapMode(MM_TEXT) + { + ::SetRectEmpty(&m_rectLogAll); + m_sizeLogPage.cx = 0; + m_sizeLogPage.cy = 0; + m_sizeLogLine.cx = 0; + m_sizeLogLine.cy = 0; + } + +// Attributes & Operations + // mapping mode operations + void SetScrollMapMode(int nMapMode) + { + ATLASSERT(nMapMode >= MM_MIN && nMapMode <= MM_MAX_FIXEDSCALE); + m_nMapMode = nMapMode; + } + + int GetScrollMapMode() const + { + ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); + return m_nMapMode; + } + + // offset operations + void SetScrollOffset(int x, int y, BOOL bRedraw = TRUE) + { + ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); + POINT ptOff = { x, y }; + // block: convert logical to device units + { + CWindowDC dc(NULL); + dc.SetMapMode(m_nMapMode); + dc.LPtoDP(&ptOff); + } + CScrollImpl< T >::SetScrollOffset(ptOff, bRedraw); + } + + void SetScrollOffset(POINT ptOffset, BOOL bRedraw = TRUE) + { + SetScrollOffset(ptOffset.x, ptOffset.y, bRedraw); + } + + void GetScrollOffset(POINT& ptOffset) const + { + ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); + ptOffset = m_ptOffset; + // block: convert device to logical units + { + CWindowDC dc(NULL); + dc.SetMapMode(m_nMapMode); + dc.DPtoLP(&ptOffset); + } + } + + // size operations + void SetScrollSize(int xMin, int yMin, int xMax, int yMax, BOOL bRedraw = TRUE, bool bResetOffset = true) + { + ATLASSERT(xMax > xMin && yMax > yMin); + ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); + + ::SetRect(&m_rectLogAll, xMin, yMin, xMax, yMax); + + SIZE sizeAll = { 0 }; + sizeAll.cx = xMax - xMin + 1; + sizeAll.cy = yMax - yMin + 1; + // block: convert logical to device units + { + CWindowDC dc(NULL); + dc.SetMapMode(m_nMapMode); + dc.LPtoDP(&sizeAll); + } + CScrollImpl< T >::SetScrollSize(sizeAll, bRedraw, bResetOffset); + SetScrollLine(0, 0); + SetScrollPage(0, 0); + } + + void SetScrollSize(RECT& rcScroll, BOOL bRedraw = TRUE, bool bResetOffset = true) + { + SetScrollSize(rcScroll.left, rcScroll.top, rcScroll.right, rcScroll.bottom, bRedraw, bResetOffset); + } + + void SetScrollSize(int cx, int cy, BOOL bRedraw = TRUE, bool bResetOffset = true) + { + SetScrollSize(0, 0, cx, cy, bRedraw, bResetOffset); + } + + void SetScrollSize(SIZE size, BOOL bRedraw = TRUE, bool bResetOffset = true) + { + SetScrollSize(0, 0, size.cx, size.cy, bRedraw, bResetOffset); + } + + void GetScrollSize(RECT& rcScroll) const + { + ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); + rcScroll = m_rectLogAll; + } + + // line operations + void SetScrollLine(int cxLine, int cyLine) + { + ATLASSERT(cxLine >= 0 && cyLine >= 0); + ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); + + m_sizeLogLine.cx = cxLine; + m_sizeLogLine.cy = cyLine; + SIZE sizeLine = m_sizeLogLine; + // block: convert logical to device units + { + CWindowDC dc(NULL); + dc.SetMapMode(m_nMapMode); + dc.LPtoDP(&sizeLine); + } + CScrollImpl< T >::SetScrollLine(sizeLine); + } + + void SetScrollLine(SIZE sizeLine) + { + SetScrollLine(sizeLine.cx, sizeLine.cy); + } + + void GetScrollLine(SIZE& sizeLine) const + { + ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); + sizeLine = m_sizeLogLine; + } + + // page operations + void SetScrollPage(int cxPage, int cyPage) + { + ATLASSERT(cxPage >= 0 && cyPage >= 0); + ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); + + m_sizeLogPage.cx = cxPage; + m_sizeLogPage.cy = cyPage; + SIZE sizePage = m_sizeLogPage; + // block: convert logical to device units + { + CWindowDC dc(NULL); + dc.SetMapMode(m_nMapMode); + dc.LPtoDP(&sizePage); + } + CScrollImpl< T >::SetScrollPage(sizePage); + } + + void SetScrollPage(SIZE sizePage) + { + SetScrollPage(sizePage.cx, sizePage.cy); + } + + void GetScrollPage(SIZE& sizePage) const + { + ATLASSERT(m_nMapMode >= MM_MIN && m_nMapMode <= MM_MAX_FIXEDSCALE); + sizePage = m_sizeLogPage; + } + + BEGIN_MSG_MAP(CMapScrollImpl) + MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll) + MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll) + MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel) +#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) + MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel) +#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) + MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel) + MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange) + MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize) + MESSAGE_HANDLER(WM_PAINT, OnPaint) + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) + ALT_MSG_MAP(1) + COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp) + COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown) + COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop) + COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom) + COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft) + COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight) + COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft) + COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight) + END_MSG_MAP() + + LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + if(wParam != NULL) + { + CDCHandle dc = (HDC)wParam; + int nMapModeSav = dc.GetMapMode(); + dc.SetMapMode(m_nMapMode); + POINT ptViewportOrg = { 0, 0 }; + if(m_nMapMode == MM_TEXT) + dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewportOrg); + else + dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y + m_sizeAll.cy, &ptViewportOrg); + POINT ptWindowOrg = { 0, 0 }; + dc.SetWindowOrg(m_rectLogAll.left, m_rectLogAll.top, &ptWindowOrg); + + pT->DoPaint(dc); + + dc.SetMapMode(nMapModeSav); + dc.SetViewportOrg(ptViewportOrg); + dc.SetWindowOrg(ptWindowOrg); + } + else + { + CPaintDC dc(pT->m_hWnd); + dc.SetMapMode(m_nMapMode); + if(m_nMapMode == MM_TEXT) + dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y); + else + dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y + m_sizeAll.cy); + dc.SetWindowOrg(m_rectLogAll.left, m_rectLogAll.top); + pT->DoPaint(dc.m_hDC); + } + return 0; + } +}; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CMapScrollWindowImpl - Implements scrolling window with mapping + +#ifndef _WIN32_WCE + +template +class ATL_NO_VTABLE CMapScrollWindowImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CMapScrollImpl< T > +{ +public: + BEGIN_MSG_MAP(CMapScrollWindowImpl) + MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll) + MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll) + MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel) +#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) + MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel) +#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) + MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel) + MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange) + MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize) + MESSAGE_HANDLER(WM_PAINT, CMapScrollImpl< T >::OnPaint) + MESSAGE_HANDLER(WM_PRINTCLIENT, CMapScrollImpl< T >::OnPaint) + ALT_MSG_MAP(1) + COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp) + COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown) + COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop) + COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom) + COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft) + COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight) + COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft) + COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight) + END_MSG_MAP() +}; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CFSBWindow - Use as a base instead of CWindow to get flat scroll bar support + +#if defined(__ATLCTRLS_H__) && (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + +template +class CFSBWindowT : public TBase, public CFlatScrollBarImpl > +{ +public: +// Constructors + CFSBWindowT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CFSBWindowT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + +// CWindow overrides that use flat scroll bar API +// (only those methods that are used by scroll window classes) + int SetScrollPos(int nBar, int nPos, BOOL bRedraw = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return FlatSB_SetScrollPos(nBar, nPos, bRedraw); + } + + BOOL GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + return FlatSB_GetScrollInfo(nBar, lpScrollInfo); + } + + BOOL SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + return FlatSB_SetScrollInfo(nBar, lpScrollInfo, bRedraw); + } +}; + +typedef CFSBWindowT CFSBWindow; + +#endif // defined(__ATLCTRLS_H__) && (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) + + +/////////////////////////////////////////////////////////////////////////////// +// CZoomScrollImpl - Provides zooming and scrolling support to any window + +#ifndef _WIN32_WCE + +// The zoom modes that can be set with the SetZoomMode method +enum +{ + ZOOMMODE_OFF, + ZOOMMODE_IN, // If left mouse button is clicked or dragged, zoom in on point clicked or rectangle dragged. + ZOOMMODE_OUT // If left mouse button clicked, zoom out on point clicked. +}; + +// Notification to parent that zoom scale changed as a result of user mouse action. +#define ZSN_ZOOMCHANGED (NM_FIRST - 50) + +template +class CZoomScrollImpl : public CScrollImpl< T > +{ +public: + enum { m_cxyMinZoomRect = 12 }; // min rect size to zoom in on rect. + +// Data members + SIZE m_sizeLogAll; + SIZE m_sizeLogLine; + SIZE m_sizeLogPage; + float m_fZoomScale; + float m_fZoomScaleMin; + float m_fZoomDelta; // Used in ZOOMMODE_IN and ZOOMMODE_OUT on left-button click. + int m_nZoomMode; + RECT m_rcTrack; + bool m_bTracking; + +// Constructor + CZoomScrollImpl(): + m_fZoomScale(1.0), + m_fZoomScaleMin(0.5), + m_fZoomDelta(0.5), + m_nZoomMode(ZOOMMODE_OFF), + m_bTracking(false) + { + m_sizeLogAll.cx = 0; + m_sizeLogAll.cy = 0; + m_sizeLogPage.cx = 0; + m_sizeLogPage.cy = 0; + m_sizeLogLine.cx = 0; + m_sizeLogLine.cy = 0; + ::SetRectEmpty(&m_rcTrack); + } + +// Attributes & Operations + + // size operations + void SetScrollSize(int cxLog, int cyLog, BOOL bRedraw = TRUE, bool bResetOffset = true) + { + ATLASSERT(cxLog >= 0 && cyLog >= 0); + + // Set up the defaults + if (cxLog == 0 && cyLog == 0) + { + cxLog = 1; + cyLog = 1; + } + + m_sizeLogAll.cx = cxLog; + m_sizeLogAll.cy = cyLog; + SIZE sizeAll = { 0 }; + sizeAll.cx = (int)((float)m_sizeLogAll.cx * m_fZoomScale); + sizeAll.cy = (int)((float)m_sizeLogAll.cy * m_fZoomScale); + + CScrollImpl< T >::SetScrollSize(sizeAll, bRedraw, bResetOffset); + } + + void SetScrollSize(SIZE sizeLog, BOOL bRedraw = TRUE, bool bResetOffset = true) + { + SetScrollSize(sizeLog.cx, sizeLog.cy, bRedraw, bResetOffset); + } + + void GetScrollSize(SIZE& sizeLog) const + { + sizeLog = m_sizeLogAll; + } + + // line operations + void SetScrollLine(int cxLogLine, int cyLogLine) + { + ATLASSERT(cxLogLine >= 0 && cyLogLine >= 0); + + m_sizeLogLine.cx = cxLogLine; + m_sizeLogLine.cy = cyLogLine; + + SIZE sizeLine = { 0 }; + sizeLine.cx = (int)((float)m_sizeLogLine.cx * m_fZoomScale); + sizeLine.cy = (int)((float)m_sizeLogLine.cy * m_fZoomScale); + CScrollImpl< T >::SetScrollLine(sizeLine); + } + + void SetScrollLine(SIZE sizeLogLine) + { + SetScrollLine(sizeLogLine.cx, sizeLogLine.cy); + } + + void GetScrollLine(SIZE& sizeLogLine) const + { + sizeLogLine = m_sizeLogLine; + } + + // page operations + void SetScrollPage(int cxLogPage, int cyLogPage) + { + ATLASSERT(cxLogPage >= 0 && cyLogPage >= 0); + + m_sizeLogPage.cx = cxLogPage; + m_sizeLogPage.cy = cyLogPage; + + SIZE sizePage = { 0 }; + sizePage.cx = (int)((float)m_sizeLogPage.cx * m_fZoomScale); + sizePage.cy = (int)((float)m_sizeLogPage.cy * m_fZoomScale); + + CScrollImpl< T >::SetScrollPage(sizePage); + } + + void SetScrollPage(SIZE sizeLogPage) + { + SetScrollPage(sizeLogPage.cx, sizeLogPage.cy); + } + + void GetScrollPage(SIZE& sizeLogPage) const + { + sizeLogPage = m_sizeLogPage; + } + + void SetZoomScale(float fZoomScale) + { + ATLASSERT(fZoomScale > 0); + + if(fZoomScale > 0 && fZoomScale >= m_fZoomScaleMin) + m_fZoomScale = fZoomScale; + } + + float GetZoomScale() const + { + return m_fZoomScale; + } + + void SetZoomScaleMin(float fZoomScaleMin) + { + m_fZoomScaleMin = fZoomScaleMin; + } + + float GetZoomScaleMin() const + { + return m_fZoomScaleMin; + } + + void SetZoomDelta(float fZoomDelta) + { + ATLASSERT(fZoomDelta >= 0); + + if(fZoomDelta >= 0) + m_fZoomDelta = fZoomDelta; + } + + float GetZoomDelta() const + { + return m_fZoomDelta; + } + + void SetZoomMode(int nZoomMode) + { + m_nZoomMode = nZoomMode; + } + + int GetZoomMode() const + { + return m_nZoomMode; + } + + void Zoom(int x, int y, float fZoomScale) + { + if(fZoomScale <= 0) + return; + + fZoomScale = max(fZoomScale, m_fZoomScaleMin); + + T* pT = static_cast(this); + POINT pt = { x, y }; + if(!pT->PtInDevRect(pt)) + return; + + pT->ViewDPtoLP(&pt); + pT->Zoom(fZoomScale, false); + pT->CenterOnLogicalPoint(pt); + } + + void Zoom(POINT pt, float fZoomScale) + { + T* pT = static_cast(this); + pT->Zoom(pt.x, pt.y, fZoomScale); + } + + void Zoom(RECT& rc) + { + T* pT = static_cast(this); + RECT rcZoom = rc; + pT->NormalizeRect(rcZoom); + SIZE size = { rcZoom.right - rcZoom.left, rcZoom.bottom - rcZoom.top }; + POINT pt = { rcZoom.left + size.cx / 2, rcZoom.top + size.cy / 2 }; + if(size.cx < m_cxyMinZoomRect || size.cy < m_cxyMinZoomRect) + { + pT->Zoom(pt, m_fZoomScale + m_fZoomDelta); + return; + } + + ATLASSERT(size.cx > 0 && size.cy > 0); + + float fScaleH = (float)(m_sizeClient.cx + 1) / (float)size.cx; + float fScaleV = (float)(m_sizeClient.cy + 1) / (float)size.cy; + float fZoomScale = min(fScaleH, fScaleV) * m_fZoomScale; + pT->Zoom(pt, fZoomScale); + } + + void Zoom(float fZoomScale, bool bCenter = true) + { + if(fZoomScale <= 0) + return; + + fZoomScale = max(fZoomScale, m_fZoomScaleMin); + + + T* pT = static_cast(this); + POINT pt = { 0 }; + if(bCenter) + { + RECT rc; + ::GetClientRect(pT->m_hWnd, &rc); + pt.x = rc.right / 2; + pt.y = rc.bottom / 2; + pT->ViewDPtoLP(&pt); + } + + // Modify the Viewport extent + m_fZoomScale = fZoomScale; + SIZE sizeAll = { 0 }; + sizeAll.cx = (int)((float)m_sizeLogAll.cx * fZoomScale); + sizeAll.cy = (int)((float)m_sizeLogAll.cy * fZoomScale); + + // Update scroll bars and window + CScrollImpl< T >::SetScrollSize(sizeAll); + + if(bCenter) + pT->CenterOnLogicalPoint(pt); + } + + // Helper functions + void PrepareDC(CDCHandle dc) + { + ATLASSERT(m_sizeAll.cx >= 0 && m_sizeAll.cy >= 0); + dc.SetMapMode(MM_ANISOTROPIC); + dc.SetWindowExt(m_sizeLogAll); + dc.SetViewportExt(m_sizeAll); + dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y); + } + + void ViewDPtoLP(LPPOINT lpPoints, int nCount = 1) + { + ATLASSERT(lpPoints); + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + + CWindowDC dc(pT->m_hWnd); + pT->PrepareDC(dc.m_hDC); + dc.DPtoLP(lpPoints, nCount); + } + + void ViewLPtoDP(LPPOINT lpPoints, int nCount = 1) + { + ATLASSERT(lpPoints); + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + + CWindowDC dc(pT->m_hWnd); + pT->PrepareDC(dc.m_hDC); + dc.LPtoDP(lpPoints, nCount); + } + + void ClientToDevice(POINT &pt) + { + pt.x += m_ptOffset.x; + pt.y += m_ptOffset.y; + } + + void DeviceToClient(POINT &pt) + { + pt.x -= m_ptOffset.x; + pt.y -= m_ptOffset.y; + } + + void CenterOnPoint(POINT pt) + { + T* pT = static_cast(this); + RECT rect; + pT->GetClientRect(&rect); + + int xOfs = pt.x - (rect.right / 2) + m_ptOffset.x; + if(xOfs < 0) + { + xOfs = 0; + } + else + { + int xMax = max((int)(m_sizeAll.cx - rect.right), 0); + if(xOfs > xMax) + xOfs = xMax; + } + + int yOfs = pt.y - (rect.bottom / 2) + m_ptOffset.y; + if(yOfs < 0) + { + yOfs = 0; + } + else + { + int yMax = max((int)(m_sizeAll.cy - rect.bottom), 0); + if(yOfs > yMax) + yOfs = yMax; + } + + CScrollImpl< T >::SetScrollOffset(xOfs, yOfs); + } + + void CenterOnLogicalPoint(POINT ptLog) + { + T* pT = static_cast(this); + pT->ViewLPtoDP(&ptLog); + pT->DeviceToClient(ptLog); + pT->CenterOnPoint(ptLog); + } + + BOOL PtInDevRect(POINT pt) + { + RECT rc = { 0, 0, m_sizeAll.cx, m_sizeAll.cy }; + ::OffsetRect(&rc, -m_ptOffset.x, -m_ptOffset.y); + return ::PtInRect(&rc, pt); + } + + void NormalizeRect(RECT& rc) + { + if(rc.left > rc.right) + { + int r = rc.right; + rc.right = rc.left; + rc.left = r; + } + if(rc.top > rc.bottom) + { + int b = rc.bottom; + rc.bottom = rc.top; + rc.top = b; + } + } + + void DrawTrackRect() + { + T* pT = static_cast(this); + const SIZE sizeLines = { 2, 2 }; + RECT rc = m_rcTrack; + pT->NormalizeRect(rc); + if(!::IsRectEmpty(&rc)) + { + ::MapWindowPoints(pT->m_hWnd, NULL, (LPPOINT)&rc, 2); + CWindowDC dc(NULL); + dc.DrawDragRect(&rc, sizeLines, NULL, sizeLines); + } + } + + void NotifyParentZoomChanged() + { + T* pT = static_cast(this); + int nId = pT->GetDlgCtrlID(); + NMHDR nmhdr = { pT->m_hWnd, nId, ZSN_ZOOMCHANGED }; + ::SendMessage(pT->GetParent(), WM_NOTIFY, (WPARAM)nId, (LPARAM)&nmhdr); + } + + BEGIN_MSG_MAP(CZoomScrollImpl) + MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor) + MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll) + MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll) + MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel) +#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) + MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel) +#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) + MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel) + MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange) + MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize) + MESSAGE_HANDLER(WM_PAINT, OnPaint) + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) + MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) + MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) + MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) + MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged) + ALT_MSG_MAP(1) + COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp) + COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown) + COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop) + COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom) + COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft) + COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight) + COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft) + COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight) + END_MSG_MAP() + + LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + ATLASSERT(m_sizeLogAll.cx >= 0 && m_sizeLogAll.cy >= 0); + ATLASSERT(m_sizeAll.cx >= 0 && m_sizeAll.cy >= 0); + + if(wParam != NULL) + { + CDCHandle dc = (HDC)wParam; + int nMapModeSav = dc.GetMapMode(); + dc.SetMapMode(MM_ANISOTROPIC); + SIZE szWindowExt = { 0, 0 }; + dc.SetWindowExt(m_sizeLogAll, &szWindowExt); + SIZE szViewportExt = { 0, 0 }; + dc.SetViewportExt(m_sizeAll, &szViewportExt); + POINT ptViewportOrg = { 0, 0 }; + dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y, &ptViewportOrg); + + pT->DoPaint(dc); + + dc.SetMapMode(nMapModeSav); + dc.SetWindowExt(szWindowExt); + dc.SetViewportExt(szViewportExt); + dc.SetViewportOrg(ptViewportOrg); + } + else + { + CPaintDC dc(pT->m_hWnd); + pT->PrepareDC(dc.m_hDC); + pT->DoPaint(dc.m_hDC); + } + return 0; + } + + LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + if(m_nZoomMode == ZOOMMODE_IN && !m_bTracking) + { + T* pT = static_cast(this); + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + if(pT->PtInDevRect(pt)) + { + pT->SetCapture(); + m_bTracking = true; + ::SetRect(&m_rcTrack, pt.x, pt.y, pt.x, pt.y); + } + } + bHandled = FALSE; + return 0; + } + + LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + if(m_bTracking) + { + T* pT = static_cast(this); + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + if(pT->PtInDevRect(pt)) + { + pT->DrawTrackRect(); + m_rcTrack.right = pt.x; + m_rcTrack.bottom = pt.y; + pT->DrawTrackRect(); + } + } + bHandled = FALSE; + return 0; + } + + LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + ::ReleaseCapture(); + if(m_nZoomMode == ZOOMMODE_OUT) + { + T* pT = static_cast(this); + pT->Zoom(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), m_fZoomScale - m_fZoomDelta); + pT->NotifyParentZoomChanged(); + } + bHandled = FALSE; + return 0; + } + + LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_bTracking) + { + m_bTracking = false; + T* pT = static_cast(this); + pT->DrawTrackRect(); + pT->Zoom(m_rcTrack); + pT->NotifyParentZoomChanged(); + ::SetRectEmpty(&m_rcTrack); + } + bHandled = FALSE; + return 0; + } + + LRESULT OnSetCursor(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + if(LOWORD(lParam) == HTCLIENT && m_nZoomMode != ZOOMMODE_OFF) + { + T* pT = static_cast(this); + if((HWND)wParam == pT->m_hWnd) + { + DWORD dwPos = ::GetMessagePos(); + POINT pt = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos) }; + pT->ScreenToClient(&pt); + if(pT->PtInDevRect(pt)) + { + ::SetCursor(::LoadCursor(NULL, IDC_CROSS)); + return 1; + } + } + } + bHandled = FALSE; + return 0; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// CZoomScrollWindowImpl - Implements scrolling window with zooming + +template +class ATL_NO_VTABLE CZoomScrollWindowImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CZoomScrollImpl< T > +{ +public: + BEGIN_MSG_MAP(CZoomScrollWindowImpl) + MESSAGE_HANDLER(WM_SETCURSOR, CZoomScrollImpl< T >::OnSetCursor) + MESSAGE_HANDLER(WM_VSCROLL, CScrollImpl< T >::OnVScroll) + MESSAGE_HANDLER(WM_HSCROLL, CScrollImpl< T >::OnHScroll) + MESSAGE_HANDLER(WM_MOUSEWHEEL, CScrollImpl< T >::OnMouseWheel) +#if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) + MESSAGE_HANDLER(m_uMsgMouseWheel, CScrollImpl< T >::OnMouseWheel) +#endif // !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)) + MESSAGE_HANDLER(WM_MOUSEHWHEEL, CScrollImpl< T >::OnMouseHWheel) + MESSAGE_HANDLER(WM_SETTINGCHANGE, CScrollImpl< T >::OnSettingChange) + MESSAGE_HANDLER(WM_SIZE, CScrollImpl< T >::OnSize) + MESSAGE_HANDLER(WM_PAINT, CZoomScrollImpl< T >::OnPaint) + MESSAGE_HANDLER(WM_PRINTCLIENT, CZoomScrollImpl< T >::OnPaint) + MESSAGE_HANDLER(WM_LBUTTONDOWN, CZoomScrollImpl< T >::OnLButtonDown) + MESSAGE_HANDLER(WM_MOUSEMOVE, CZoomScrollImpl< T >::OnMouseMove) + MESSAGE_HANDLER(WM_LBUTTONUP, CZoomScrollImpl< T >::OnLButtonUp) + MESSAGE_HANDLER(WM_CAPTURECHANGED, CZoomScrollImpl< T >::OnCaptureChanged) + ALT_MSG_MAP(1) + COMMAND_ID_HANDLER(ID_SCROLL_UP, CScrollImpl< T >::OnScrollUp) + COMMAND_ID_HANDLER(ID_SCROLL_DOWN, CScrollImpl< T >::OnScrollDown) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_UP, CScrollImpl< T >::OnScrollPageUp) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_DOWN, CScrollImpl< T >::OnScrollPageDown) + COMMAND_ID_HANDLER(ID_SCROLL_TOP, CScrollImpl< T >::OnScrollTop) + COMMAND_ID_HANDLER(ID_SCROLL_BOTTOM, CScrollImpl< T >::OnScrollBottom) + COMMAND_ID_HANDLER(ID_SCROLL_LEFT, CScrollImpl< T >::OnScrollLeft) + COMMAND_ID_HANDLER(ID_SCROLL_RIGHT, CScrollImpl< T >::OnScrollRight) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_LEFT, CScrollImpl< T >::OnScrollPageLeft) + COMMAND_ID_HANDLER(ID_SCROLL_PAGE_RIGHT, CScrollImpl< T >::OnScrollPageRight) + COMMAND_ID_HANDLER(ID_SCROLL_ALL_LEFT, CScrollImpl< T >::OnScrollAllLeft) + COMMAND_ID_HANDLER(ID_SCROLL_ALL_RIGHT, CScrollImpl< T >::OnScrollAllRight) + END_MSG_MAP() +}; + +#endif // !_WIN32_WCE + + +/////////////////////////////////////////////////////////////////////////////// +// CScrollContainer + +template +class ATL_NO_VTABLE CScrollContainerImpl : public CScrollWindowImpl< T, TBase, TWinTraits > +{ +public: + DECLARE_WND_CLASS_EX(NULL, 0, -1) + + typedef CScrollWindowImpl< T, TBase, TWinTraits > _baseClass; + +// Data members + ATL::CWindow m_wndClient; + bool m_bAutoSizeClient; + bool m_bDrawEdgeIfEmpty; + +// Constructor + CScrollContainerImpl() : m_bAutoSizeClient(true), m_bDrawEdgeIfEmpty(false) + { + // Set CScrollWindowImpl extended style + SetScrollExtendedStyle(SCRL_SCROLLCHILDREN); + } + +// Attributes + HWND GetClient() const + { + return m_wndClient; + } + + HWND SetClient(HWND hWndClient, bool bClientSizeAsMin = true) + { + ATLASSERT(::IsWindow(m_hWnd)); + + HWND hWndOldClient = m_wndClient; + m_wndClient = hWndClient; + + SetRedraw(FALSE); + SetScrollSize(1, 1, FALSE); + + if(m_wndClient.m_hWnd != NULL) + { + m_wndClient.SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE); + + if(bClientSizeAsMin) + { + RECT rect = { 0 }; + m_wndClient.GetWindowRect(&rect); + if((rect.right - rect.left) > 0 && (rect.bottom - rect.top) > 0) + SetScrollSize(rect.right - rect.left, rect.bottom - rect.top, FALSE); + } + + T* pT = static_cast(this); + pT->UpdateLayout(); + } + + SetRedraw(TRUE); + RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW | RDW_ALLCHILDREN); + + return hWndOldClient; + } + +// Message map and handlers + BEGIN_MSG_MAP(CScrollContainerImpl) + MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) + MESSAGE_HANDLER(WM_SIZE, OnSize) + CHAIN_MSG_MAP(_baseClass) + FORWARD_NOTIFICATIONS() + ALT_MSG_MAP(1) + CHAIN_MSG_MAP_ALT(_baseClass, 1) + END_MSG_MAP() + + LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + if(m_wndClient.m_hWnd != NULL) + m_wndClient.SetFocus(); + + return 0; + } + + LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return 1; // no background needed + } + + LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + BOOL bTmp = TRUE; + LRESULT lRet = _baseClass::OnSize(uMsg, wParam, lParam, bTmp); + + T* pT = static_cast(this); + pT->UpdateLayout(); + + return lRet; + } + +// Overrides for CScrollWindowImpl + void DoPaint(CDCHandle dc) + { + if(!m_bAutoSizeClient || m_wndClient.m_hWnd == NULL) + { + T* pT = static_cast(this); + RECT rect = { 0 }; + pT->GetContainerRect(rect); + + if(m_bDrawEdgeIfEmpty && m_wndClient.m_hWnd == NULL) + dc.DrawEdge(&rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); + + dc.FillRect(&rect, COLOR_APPWORKSPACE); + } + } + + void ScrollToView(POINT pt) + { + CScrollWindowImpl< T, TBase, TWinTraits >::ScrollToView(pt); + } + + void ScrollToView(RECT& rect) + { + CScrollWindowImpl< T, TBase, TWinTraits >::ScrollToView(rect); + } + + void ScrollToView(HWND hWnd) // client window coordinates + { + T* pT = static_cast(this); + pT; // avoid level 4 warning + ATLASSERT(::IsWindow(pT->m_hWnd)); + ATLASSERT(m_wndClient.IsWindow()); + + RECT rect = { 0 }; + ::GetWindowRect(hWnd, &rect); + ::MapWindowPoints(NULL, m_wndClient.m_hWnd, (LPPOINT)&rect, 2); + ScrollToView(rect); + } + +// Implementation - overrideable methods + void UpdateLayout() + { + ATLASSERT(::IsWindow(m_hWnd)); + + if(m_bAutoSizeClient && m_wndClient.m_hWnd != NULL) + { + T* pT = static_cast(this); + RECT rect = { 0 }; + pT->GetContainerRect(rect); + + m_wndClient.SetWindowPos(NULL, &rect, SWP_NOZORDER | SWP_NOMOVE); + } + else + { + Invalidate(); + } + } + + void GetContainerRect(RECT& rect) + { + GetClientRect(&rect); + + if(rect.right < m_sizeAll.cx) + rect.right = m_sizeAll.cx; + + if(rect.bottom < m_sizeAll.cy) + rect.bottom = m_sizeAll.cy; + } +}; + +class CScrollContainer : public CScrollContainerImpl +{ +public: + DECLARE_WND_CLASS_EX(_T("WTL_ScrollContainer"), 0, -1) +}; + +}; // namespace WTL + +#endif // __ATLSCRL_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlsplit.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlsplit.h new file mode 100644 index 0000000000..f94fa099e9 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlsplit.h @@ -0,0 +1,917 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLSPLIT_H__ +#define __ATLSPLIT_H__ + +#pragma once + +#ifndef __ATLAPP_H__ + #error atlsplit.h requires atlapp.h to be included first +#endif + +#ifndef __ATLWIN_H__ + #error atlsplit.h requires atlwin.h to be included first +#endif + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CSplitterImpl +// CSplitterWindowImpl +// CSplitterWindowT + + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// CSplitterImpl - Provides splitter support to any window + +// Splitter panes constants +#define SPLIT_PANE_LEFT 0 +#define SPLIT_PANE_RIGHT 1 +#define SPLIT_PANE_TOP SPLIT_PANE_LEFT +#define SPLIT_PANE_BOTTOM SPLIT_PANE_RIGHT +#define SPLIT_PANE_NONE -1 + +// Splitter extended styles +#define SPLIT_PROPORTIONAL 0x00000001 +#define SPLIT_NONINTERACTIVE 0x00000002 +#define SPLIT_RIGHTALIGNED 0x00000004 +#define SPLIT_BOTTOMALIGNED SPLIT_RIGHTALIGNED +#define SPLIT_GRADIENTBAR 0x00000008 +#define SPLIT_FIXEDBARSIZE 0x00000010 + +// Note: SPLIT_PROPORTIONAL and SPLIT_RIGHTALIGNED/SPLIT_BOTTOMALIGNED are +// mutually exclusive. If both are set, splitter defaults to SPLIT_PROPORTIONAL + + +template +class CSplitterImpl +{ +public: + enum { m_nPanesCount = 2, m_nPropMax = 10000 }; + + HWND m_hWndPane[m_nPanesCount]; + RECT m_rcSplitter; + int m_xySplitterPos; + int m_nDefActivePane; + int m_cxySplitBar; // splitter bar width/height + static HCURSOR m_hCursor; + int m_cxyMin; // minimum pane size + int m_cxyBarEdge; // splitter bar edge + bool m_bFullDrag; + int m_cxyDragOffset; + int m_nProportionalPos; + bool m_bUpdateProportionalPos; + DWORD m_dwExtendedStyle; // splitter specific extended styles + int m_nSinglePane; // single pane mode + +// Constructor + CSplitterImpl() : + m_xySplitterPos(-1), m_nDefActivePane(SPLIT_PANE_NONE), + m_cxySplitBar(4), m_cxyMin(0), m_cxyBarEdge(0), m_bFullDrag(true), + m_cxyDragOffset(0), m_nProportionalPos(0), m_bUpdateProportionalPos(true), + m_dwExtendedStyle(SPLIT_PROPORTIONAL), + m_nSinglePane(SPLIT_PANE_NONE) + { + m_hWndPane[SPLIT_PANE_LEFT] = NULL; + m_hWndPane[SPLIT_PANE_RIGHT] = NULL; + + ::SetRectEmpty(&m_rcSplitter); + + if(m_hCursor == NULL) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CSplitterImpl::CSplitterImpl.\n")); + ATLASSERT(FALSE); + return; + } + + if(m_hCursor == NULL) + m_hCursor = ::LoadCursor(NULL, t_bVertical ? IDC_SIZEWE : IDC_SIZENS); + + lock.Unlock(); + } + } + +// Attributes + void SetSplitterRect(LPRECT lpRect = NULL, bool bUpdate = true) + { + if(lpRect == NULL) + { + T* pT = static_cast(this); + pT->GetClientRect(&m_rcSplitter); + } + else + { + m_rcSplitter = *lpRect; + } + + if(IsProportional()) + UpdateProportionalPos(); + else if(IsRightAligned()) + UpdateRightAlignPos(); + + if(bUpdate) + UpdateSplitterLayout(); + } + + void GetSplitterRect(LPRECT lpRect) const + { + ATLASSERT(lpRect != NULL); + *lpRect = m_rcSplitter; + } + + bool SetSplitterPos(int xyPos = -1, bool bUpdate = true) + { + if(xyPos == -1) // -1 == middle + { + if(t_bVertical) + xyPos = (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) / 2; + else + xyPos = (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge) / 2; + } + + // Adjust if out of valid range + int cxyMax = 0; + if(t_bVertical) + cxyMax = m_rcSplitter.right - m_rcSplitter.left; + else + cxyMax = m_rcSplitter.bottom - m_rcSplitter.top; + + if(xyPos < m_cxyMin + m_cxyBarEdge) + xyPos = m_cxyMin; + else if(xyPos > (cxyMax - m_cxySplitBar - m_cxyBarEdge - m_cxyMin)) + xyPos = cxyMax - m_cxySplitBar - m_cxyBarEdge - m_cxyMin; + + // Set new position and update if requested + bool bRet = (m_xySplitterPos != xyPos); + m_xySplitterPos = xyPos; + + if(m_bUpdateProportionalPos) + { + if(IsProportional()) + StoreProportionalPos(); + else if(IsRightAligned()) + StoreRightAlignPos(); + } + else + { + m_bUpdateProportionalPos = true; + } + + if(bUpdate && bRet) + UpdateSplitterLayout(); + + return bRet; + } + + void SetSplitterPosPct(int nPct, bool bUpdate = true) + { + ATLASSERT(nPct >= 0 && nPct <= 100); + + m_nProportionalPos = ::MulDiv(nPct, m_nPropMax, 100); + UpdateProportionalPos(); + + if(bUpdate) + UpdateSplitterLayout(); + } + + int GetSplitterPos() const + { + return m_xySplitterPos; + } + + bool SetSinglePaneMode(int nPane = SPLIT_PANE_NONE) + { + ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT || nPane == SPLIT_PANE_NONE); + if(!(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT || nPane == SPLIT_PANE_NONE)) + return false; + + if(nPane != SPLIT_PANE_NONE) + { + if(!::IsWindowVisible(m_hWndPane[nPane])) + ::ShowWindow(m_hWndPane[nPane], SW_SHOW); + int nOtherPane = (nPane == SPLIT_PANE_LEFT) ? SPLIT_PANE_RIGHT : SPLIT_PANE_LEFT; + ::ShowWindow(m_hWndPane[nOtherPane], SW_HIDE); + if(m_nDefActivePane != nPane) + m_nDefActivePane = nPane; + } + else if(m_nSinglePane != SPLIT_PANE_NONE) + { + int nOtherPane = (m_nSinglePane == SPLIT_PANE_LEFT) ? SPLIT_PANE_RIGHT : SPLIT_PANE_LEFT; + ::ShowWindow(m_hWndPane[nOtherPane], SW_SHOW); + } + + m_nSinglePane = nPane; + UpdateSplitterLayout(); + return true; + } + + int GetSinglePaneMode() const + { + return m_nSinglePane; + } + + DWORD GetSplitterExtendedStyle() const + { + return m_dwExtendedStyle; + } + + DWORD SetSplitterExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) + { + DWORD dwPrevStyle = m_dwExtendedStyle; + if(dwMask == 0) + m_dwExtendedStyle = dwExtendedStyle; + else + m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); +#ifdef _DEBUG + if(IsProportional() && IsRightAligned()) + ATLTRACE2(atlTraceUI, 0, _T("CSplitterImpl::SetSplitterExtendedStyle - SPLIT_PROPORTIONAL and SPLIT_RIGHTALIGNED are mutually exclusive, defaulting to SPLIT_PROPORTIONAL.\n")); +#endif // _DEBUG + return dwPrevStyle; + } + +// Splitter operations + void SetSplitterPanes(HWND hWndLeftTop, HWND hWndRightBottom, bool bUpdate = true) + { + m_hWndPane[SPLIT_PANE_LEFT] = hWndLeftTop; + m_hWndPane[SPLIT_PANE_RIGHT] = hWndRightBottom; + ATLASSERT(m_hWndPane[SPLIT_PANE_LEFT] == NULL || m_hWndPane[SPLIT_PANE_RIGHT] == NULL || m_hWndPane[SPLIT_PANE_LEFT] != m_hWndPane[SPLIT_PANE_RIGHT]); + if(bUpdate) + UpdateSplitterLayout(); + } + + bool SetSplitterPane(int nPane, HWND hWnd, bool bUpdate = true) + { + ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT); + + if(nPane != SPLIT_PANE_LEFT && nPane != SPLIT_PANE_RIGHT) + return false; + m_hWndPane[nPane] = hWnd; + ATLASSERT(m_hWndPane[SPLIT_PANE_LEFT] == NULL || m_hWndPane[SPLIT_PANE_RIGHT] == NULL || m_hWndPane[SPLIT_PANE_LEFT] != m_hWndPane[SPLIT_PANE_RIGHT]); + if(bUpdate) + UpdateSplitterLayout(); + return true; + } + + HWND GetSplitterPane(int nPane) const + { + ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT); + + if(nPane != SPLIT_PANE_LEFT && nPane != SPLIT_PANE_RIGHT) + return false; + return m_hWndPane[nPane]; + } + + bool SetActivePane(int nPane) + { + ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT); + + if(nPane != SPLIT_PANE_LEFT && nPane != SPLIT_PANE_RIGHT) + return false; + if(m_nSinglePane != SPLIT_PANE_NONE && nPane != m_nSinglePane) + return false; + ::SetFocus(m_hWndPane[nPane]); + m_nDefActivePane = nPane; + return true; + } + + int GetActivePane() const + { + int nRet = SPLIT_PANE_NONE; + HWND hWndFocus = ::GetFocus(); + if(hWndFocus != NULL) + { + for(int nPane = 0; nPane < m_nPanesCount; nPane++) + { + if(hWndFocus == m_hWndPane[nPane] || ::IsChild(m_hWndPane[nPane], hWndFocus)) + { + nRet = nPane; + break; + } + } + } + return nRet; + } + + bool ActivateNextPane(bool bNext = true) + { + int nPane = m_nSinglePane; + if(nPane == SPLIT_PANE_NONE) + { + switch(GetActivePane()) + { + case SPLIT_PANE_LEFT: + nPane = SPLIT_PANE_RIGHT; + break; + case SPLIT_PANE_RIGHT: + nPane = SPLIT_PANE_LEFT; + break; + default: + nPane = bNext ? SPLIT_PANE_LEFT : SPLIT_PANE_RIGHT; + break; + } + } + return SetActivePane(nPane); + } + + bool SetDefaultActivePane(int nPane) + { + ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT); + + if(nPane != SPLIT_PANE_LEFT && nPane != SPLIT_PANE_RIGHT) + return false; + m_nDefActivePane = nPane; + return true; + } + + bool SetDefaultActivePane(HWND hWnd) + { + for(int nPane = 0; nPane < m_nPanesCount; nPane++) + { + if(hWnd == m_hWndPane[nPane]) + { + m_nDefActivePane = nPane; + return true; + } + } + return false; // not found + } + + int GetDefaultActivePane() const + { + return m_nDefActivePane; + } + + void DrawSplitter(CDCHandle dc) + { + ATLASSERT(dc.m_hDC != NULL); + if(m_nSinglePane == SPLIT_PANE_NONE && m_xySplitterPos == -1) + return; + + T* pT = static_cast(this); + if(m_nSinglePane == SPLIT_PANE_NONE) + { + pT->DrawSplitterBar(dc); + + for(int nPane = 0; nPane < m_nPanesCount; nPane++) + { + if(m_hWndPane[nPane] == NULL) + pT->DrawSplitterPane(dc, nPane); + } + } + else + { + if(m_hWndPane[m_nSinglePane] == NULL) + pT->DrawSplitterPane(dc, m_nSinglePane); + } + } + +// Overrideables + void DrawSplitterBar(CDCHandle dc) + { + RECT rect = { 0 }; + if(GetSplitterBarRect(&rect)) + { + dc.FillRect(&rect, COLOR_3DFACE); + +#if (!defined(_WIN32_WCE) || (_WIN32_WCE >= 420)) + if((m_dwExtendedStyle & SPLIT_GRADIENTBAR) != 0) + { + RECT rect2 = rect; + if(t_bVertical) + rect2.left = (rect.left + rect.right) / 2 - 1; + else + rect2.top = (rect.top + rect.bottom) / 2 - 1; + + dc.GradientFillRect(rect2, ::GetSysColor(COLOR_3DFACE), ::GetSysColor(COLOR_3DSHADOW), t_bVertical); + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 420) + + // draw 3D edge if needed + T* pT = static_cast(this); + if((pT->GetExStyle() & WS_EX_CLIENTEDGE) != 0) + dc.DrawEdge(&rect, EDGE_RAISED, t_bVertical ? (BF_LEFT | BF_RIGHT) : (BF_TOP | BF_BOTTOM)); + } + } + + // called only if pane is empty + void DrawSplitterPane(CDCHandle dc, int nPane) + { + RECT rect = { 0 }; + if(GetSplitterPaneRect(nPane, &rect)) + { + T* pT = static_cast(this); + if((pT->GetExStyle() & WS_EX_CLIENTEDGE) == 0) + dc.DrawEdge(&rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); + dc.FillRect(&rect, COLOR_APPWORKSPACE); + } + } + +// Message map and handlers + BEGIN_MSG_MAP(CSplitterImpl) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_PAINT, OnPaint) +#ifndef _WIN32_WCE + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) +#endif // !_WIN32_WCE + if(IsInteractive()) + { + MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor) + MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) + MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) + MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) + MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDoubleClick) + MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged) + } + MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) +#ifndef _WIN32_WCE + MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate) +#endif // !_WIN32_WCE + MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) + END_MSG_MAP() + + LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + T* pT = static_cast(this); + pT->GetSystemSettings(false); + + bHandled = FALSE; + return 1; + } + + LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + // try setting position if not set + if(m_nSinglePane == SPLIT_PANE_NONE && m_xySplitterPos == -1) + pT->SetSplitterPos(); + // do painting + CPaintDC dc(pT->m_hWnd); + pT->DrawSplitter(dc.m_hDC); + return 0; + } + + LRESULT OnSetCursor(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + T* pT = static_cast(this); + if((HWND)wParam == pT->m_hWnd && LOWORD(lParam) == HTCLIENT) + { + DWORD dwPos = ::GetMessagePos(); + POINT ptPos = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos) }; + pT->ScreenToClient(&ptPos); + if(IsOverSplitterBar(ptPos.x, ptPos.y)) + return 1; + } + + bHandled = FALSE; + return 0; + } + + LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + T* pT = static_cast(this); + int xPos = GET_X_LPARAM(lParam); + int yPos = GET_Y_LPARAM(lParam); + if((wParam & MK_LBUTTON) && ::GetCapture() == pT->m_hWnd) + { + int xyNewSplitPos = 0; + if(t_bVertical) + xyNewSplitPos = xPos - m_rcSplitter.left - m_cxyDragOffset; + else + xyNewSplitPos = yPos - m_rcSplitter.top - m_cxyDragOffset; + + if(xyNewSplitPos == -1) // avoid -1, that means middle + xyNewSplitPos = -2; + + if(m_xySplitterPos != xyNewSplitPos) + { + if(m_bFullDrag) + { + if(pT->SetSplitterPos(xyNewSplitPos, true)) + pT->UpdateWindow(); + } + else + { + DrawGhostBar(); + pT->SetSplitterPos(xyNewSplitPos, false); + DrawGhostBar(); + } + } + } + else // not dragging, just set cursor + { + if(IsOverSplitterBar(xPos, yPos)) + ::SetCursor(m_hCursor); + bHandled = FALSE; + } + + return 0; + } + + LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) + { + int xPos = GET_X_LPARAM(lParam); + int yPos = GET_Y_LPARAM(lParam); + if(IsOverSplitterBar(xPos, yPos)) + { + T* pT = static_cast(this); + pT->SetCapture(); + ::SetCursor(m_hCursor); + if(!m_bFullDrag) + DrawGhostBar(); + if(t_bVertical) + m_cxyDragOffset = xPos - m_rcSplitter.left - m_xySplitterPos; + else + m_cxyDragOffset = yPos - m_rcSplitter.top - m_xySplitterPos; + } + bHandled = FALSE; + return 1; + } + + LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + ::ReleaseCapture(); + bHandled = FALSE; + return 1; + } + + LRESULT OnLButtonDoubleClick(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->SetSplitterPos(); // middle + return 0; + } + + LRESULT OnCaptureChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + if(!m_bFullDrag) + { + DrawGhostBar(); + UpdateSplitterLayout(); + T* pT = static_cast(this); + pT->UpdateWindow(); + } + return 0; + } + + LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM, BOOL& bHandled) + { + if(m_nSinglePane == SPLIT_PANE_NONE) + { + if(m_nDefActivePane == SPLIT_PANE_LEFT || m_nDefActivePane == SPLIT_PANE_RIGHT) + ::SetFocus(m_hWndPane[m_nDefActivePane]); + } + else + { + ::SetFocus(m_hWndPane[m_nSinglePane]); + } + bHandled = FALSE; + return 1; + } + +#ifndef _WIN32_WCE + LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + LRESULT lRet = pT->DefWindowProc(uMsg, wParam, lParam); + if(lRet == MA_ACTIVATE || lRet == MA_ACTIVATEANDEAT) + { + DWORD dwPos = ::GetMessagePos(); + POINT pt = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos) }; + pT->ScreenToClient(&pt); + RECT rcPane = { 0 }; + for(int nPane = 0; nPane < m_nPanesCount; nPane++) + { + if(GetSplitterPaneRect(nPane, &rcPane) && ::PtInRect(&rcPane, pt)) + { + m_nDefActivePane = nPane; + break; + } + } + } + return lRet; + } +#endif // !_WIN32_WCE + + LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->GetSystemSettings(true); + + return 0; + } + +// Implementation - internal helpers + void UpdateSplitterLayout() + { + if(m_nSinglePane == SPLIT_PANE_NONE && m_xySplitterPos == -1) + return; + + T* pT = static_cast(this); + RECT rect = { 0 }; + if(m_nSinglePane == SPLIT_PANE_NONE) + { + if(GetSplitterBarRect(&rect)) + pT->InvalidateRect(&rect); + + for(int nPane = 0; nPane < m_nPanesCount; nPane++) + { + if(GetSplitterPaneRect(nPane, &rect)) + { + if(m_hWndPane[nPane] != NULL) + ::SetWindowPos(m_hWndPane[nPane], NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER); + else + pT->InvalidateRect(&rect); + } + } + } + else + { + if(GetSplitterPaneRect(m_nSinglePane, &rect)) + { + if(m_hWndPane[m_nSinglePane] != NULL) + ::SetWindowPos(m_hWndPane[m_nSinglePane], NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER); + else + pT->InvalidateRect(&rect); + } + } + } + + bool GetSplitterBarRect(LPRECT lpRect) const + { + ATLASSERT(lpRect != NULL); + if(m_nSinglePane != SPLIT_PANE_NONE || m_xySplitterPos == -1) + return false; + + if(t_bVertical) + { + lpRect->left = m_rcSplitter.left + m_xySplitterPos; + lpRect->top = m_rcSplitter.top; + lpRect->right = m_rcSplitter.left + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge; + lpRect->bottom = m_rcSplitter.bottom; + } + else + { + lpRect->left = m_rcSplitter.left; + lpRect->top = m_rcSplitter.top + m_xySplitterPos; + lpRect->right = m_rcSplitter.right; + lpRect->bottom = m_rcSplitter.top + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge; + } + + return true; + } + + bool GetSplitterPaneRect(int nPane, LPRECT lpRect) const + { + ATLASSERT(nPane == SPLIT_PANE_LEFT || nPane == SPLIT_PANE_RIGHT); + ATLASSERT(lpRect != NULL); + bool bRet = true; + if(m_nSinglePane != SPLIT_PANE_NONE) + { + if(nPane == m_nSinglePane) + *lpRect = m_rcSplitter; + else + bRet = false; + } + else if(nPane == SPLIT_PANE_LEFT) + { + if(t_bVertical) + { + lpRect->left = m_rcSplitter.left; + lpRect->top = m_rcSplitter.top; + lpRect->right = m_rcSplitter.left + m_xySplitterPos; + lpRect->bottom = m_rcSplitter.bottom; + } + else + { + lpRect->left = m_rcSplitter.left; + lpRect->top = m_rcSplitter.top; + lpRect->right = m_rcSplitter.right; + lpRect->bottom = m_rcSplitter.top + m_xySplitterPos; + } + } + else if(nPane == SPLIT_PANE_RIGHT) + { + if(t_bVertical) + { + lpRect->left = m_rcSplitter.left + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge; + lpRect->top = m_rcSplitter.top; + lpRect->right = m_rcSplitter.right; + lpRect->bottom = m_rcSplitter.bottom; + } + else + { + lpRect->left = m_rcSplitter.left; + lpRect->top = m_rcSplitter.top + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge; + lpRect->right = m_rcSplitter.right; + lpRect->bottom = m_rcSplitter.bottom; + } + } + else + { + bRet = false; + } + return bRet; + } + + bool IsOverSplitterRect(int x, int y) const + { + // -1 == don't check + return ((x == -1 || (x >= m_rcSplitter.left && x <= m_rcSplitter.right)) && + (y == -1 || (y >= m_rcSplitter.top && y <= m_rcSplitter.bottom))); + } + + bool IsOverSplitterBar(int x, int y) const + { + if(m_nSinglePane != SPLIT_PANE_NONE) + return false; + if(m_xySplitterPos == -1 || !IsOverSplitterRect(x, y)) + return false; + int xy = t_bVertical ? x : y; + int xyOff = t_bVertical ? m_rcSplitter.left : m_rcSplitter.top; + return ((xy >= (xyOff + m_xySplitterPos)) && (xy < xyOff + m_xySplitterPos + m_cxySplitBar + m_cxyBarEdge)); + } + + void DrawGhostBar() + { + RECT rect = { 0 }; + if(GetSplitterBarRect(&rect)) + { + // convert client to window coordinates + T* pT = static_cast(this); + RECT rcWnd = { 0 }; + pT->GetWindowRect(&rcWnd); + ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rcWnd, 2); + ::OffsetRect(&rect, -rcWnd.left, -rcWnd.top); + + // invert the brush pattern (looks just like frame window sizing) + CWindowDC dc(pT->m_hWnd); + CBrush brush = CDCHandle::GetHalftoneBrush(); + if(brush.m_hBrush != NULL) + { + CBrushHandle brushOld = dc.SelectBrush(brush); + dc.PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT); + dc.SelectBrush(brushOld); + } + } + } + + void GetSystemSettings(bool bUpdate) + { + if((m_dwExtendedStyle & SPLIT_FIXEDBARSIZE) == 0) + { +#ifndef _WIN32_WCE + m_cxySplitBar = ::GetSystemMetrics(t_bVertical ? SM_CXSIZEFRAME : SM_CYSIZEFRAME); +#else // CE specific + m_cxySplitBar = 2 * ::GetSystemMetrics(t_bVertical ? SM_CXEDGE : SM_CYEDGE); +#endif // _WIN32_WCE + } + + T* pT = static_cast(this); + if((pT->GetExStyle() & WS_EX_CLIENTEDGE)) + { + m_cxyBarEdge = 2 * ::GetSystemMetrics(t_bVertical ? SM_CXEDGE : SM_CYEDGE); + m_cxyMin = 0; + } + else + { + m_cxyBarEdge = 0; + m_cxyMin = 2 * ::GetSystemMetrics(t_bVertical ? SM_CXEDGE : SM_CYEDGE); + } + +#ifndef _WIN32_WCE + ::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &m_bFullDrag, 0); +#endif // !_WIN32_WCE + + if(bUpdate) + UpdateSplitterLayout(); + } + + bool IsProportional() const + { + return ((m_dwExtendedStyle & SPLIT_PROPORTIONAL) != 0); + } + + void StoreProportionalPos() + { + int cxyTotal = t_bVertical ? (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge); + if(cxyTotal > 0) + m_nProportionalPos = ::MulDiv(m_xySplitterPos, m_nPropMax, cxyTotal); + else + m_nProportionalPos = 0; + ATLTRACE2(atlTraceUI, 0, _T("CSplitterImpl::StoreProportionalPos - %i\n"), m_nProportionalPos); + } + + void UpdateProportionalPos() + { + int cxyTotal = t_bVertical ? (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge); + if(cxyTotal > 0) + { + int xyNewPos = ::MulDiv(m_nProportionalPos, cxyTotal, m_nPropMax); + m_bUpdateProportionalPos = false; + T* pT = static_cast(this); + pT->SetSplitterPos(xyNewPos, false); + } + } + + bool IsRightAligned() const + { + return ((m_dwExtendedStyle & SPLIT_RIGHTALIGNED) != 0); + } + + void StoreRightAlignPos() + { + int cxyTotal = t_bVertical ? (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge); + if(cxyTotal > 0) + m_nProportionalPos = cxyTotal - m_xySplitterPos; + else + m_nProportionalPos = 0; + ATLTRACE2(atlTraceUI, 0, _T("CSplitterImpl::StoreRightAlignPos - %i\n"), m_nProportionalPos); + } + + void UpdateRightAlignPos() + { + int cxyTotal = t_bVertical ? (m_rcSplitter.right - m_rcSplitter.left - m_cxySplitBar - m_cxyBarEdge) : (m_rcSplitter.bottom - m_rcSplitter.top - m_cxySplitBar - m_cxyBarEdge); + if(cxyTotal > 0) + { + m_bUpdateProportionalPos = false; + T* pT = static_cast(this); + pT->SetSplitterPos(cxyTotal - m_nProportionalPos, false); + } + } + + bool IsInteractive() const + { + return ((m_dwExtendedStyle & SPLIT_NONINTERACTIVE) == 0); + } +}; + +template HCURSOR CSplitterImpl< T, t_bVertical>::m_hCursor = NULL; + + +/////////////////////////////////////////////////////////////////////////////// +// CSplitterWindowImpl - Implements a splitter window + +template +class ATL_NO_VTABLE CSplitterWindowImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CSplitterImpl< T , t_bVertical > +{ +public: + DECLARE_WND_CLASS_EX(NULL, CS_DBLCLKS, COLOR_WINDOW) + + typedef CSplitterImpl< T , t_bVertical > _baseClass; + + BEGIN_MSG_MAP(CSplitterWindowImpl) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) + MESSAGE_HANDLER(WM_SIZE, OnSize) + CHAIN_MSG_MAP(_baseClass) + FORWARD_NOTIFICATIONS() + END_MSG_MAP() + + LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + // handled, no background painting needed + return 1; + } + + LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if(wParam != SIZE_MINIMIZED) + SetSplitterRect(); + + bHandled = FALSE; + return 1; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CSplitterWindow - Implements a splitter window to be used as is + +template +class CSplitterWindowT : public CSplitterWindowImpl, t_bVertical> +{ +public: + DECLARE_WND_CLASS_EX(_T("WTL_SplitterWindow"), CS_DBLCLKS, COLOR_WINDOW) +}; + +typedef CSplitterWindowT CSplitterWindow; +typedef CSplitterWindowT CHorSplitterWindow; + +}; // namespace WTL + +#endif // __ATLSPLIT_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atltheme.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atltheme.h new file mode 100644 index 0000000000..ff7ee59817 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atltheme.h @@ -0,0 +1,1218 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLTHEME_H__ +#define __ATLTHEME_H__ + +#pragma once + +#ifdef _WIN32_WCE + #error atltheme.h is not supported on Windows CE +#endif + +#ifndef __ATLAPP_H__ + #error atltheme.h requires atlapp.h to be included first +#endif + +#ifndef __ATLWIN_H__ + #error atltheme.h requires atlwin.h to be included first +#endif + +#if (_WIN32_WINNT < 0x0501) + #error atltheme.h requires _WIN32_WINNT >= 0x0501 +#endif // (_WIN32_WINNT < 0x0501) + +#if defined(_WTL_USE_VSSYM32) || (defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)) + #include +#else + #ifndef TMSCHEMA_H + #include + #endif +#endif + +#ifndef _UXTHEME_H_ +#include +#endif +#pragma comment(lib, "uxtheme.lib") + +// Note: To create an application that also runs on older versions of Windows, +// use delay load of uxtheme.dll and ensure that no calls to the Theme API are +// made if theming is not supported. It is enough to check if m_hTheme is NULL. +// Example: +// if(m_hTheme != NULL) +// { +// DrawThemeBackground(dc, BP_PUSHBUTTON, PBS_NORMAL, &rect, NULL); +// DrawThemeText(dc, BP_PUSHBUTTON, PBS_NORMAL, L"Button", -1, DT_SINGLELINE | DT_CENTER | DT_VCENTER, 0, &rect); +// } +// else +// { +// dc.DrawFrameControl(&rect, DFC_BUTTON, DFCS_BUTTONPUSH); +// dc.DrawText(_T("Button"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); +// } +// +// Delay load is NOT AUTOMATIC for VC++ 7, you have to link to delayimp.lib, +// and add uxtheme.dll in the Linker.Input.Delay Loaded DLLs section of the +// project properties. +#if (_MSC_VER < 1300) && !defined(_WTL_NO_THEME_DELAYLOAD) + #pragma comment(lib, "delayimp.lib") + #pragma comment(linker, "/delayload:uxtheme.dll") +#endif // (_MSC_VER < 1300) && !defined(_WTL_NO_THEME_DELAYLOAD) + +// Hack: Signatures in uxtheme.h changed - the only way to check which variant of uxtheme.h +// is included is to check for presence of new defines MAX_THEMECOLOR and MAX_THEMESIZE +#ifndef _WTL_NEW_UXTHEME + #if defined(MAX_THEMECOLOR) && defined(MAX_THEMESIZE) + #define _WTL_NEW_UXTHEME + #endif // defined(MAX_THEMECOLOR) && defined(MAX_THEMESIZE) +#endif // _WTL_NEW_UXTHEME + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CTheme +// CThemeImpl +// +// CBufferedPaint +// CBufferedPaintImpl +// CBufferedPaintWindowImpl +// CBufferedAnimation +// CBufferedAnimationImpl +// CBufferedAnimationWindowImpl +// +// Global functions: +// AtlDrawThemeClientEdge() + + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// CTheme - wrapper for theme handle + +class CTheme +{ +public: +// Data members + HTHEME m_hTheme; + static int m_nIsThemingSupported; + +// Constructor + CTheme(HTHEME hTheme = NULL) : m_hTheme(hTheme) + { + IsThemingSupported(); + } + +// Operators and helpers + bool IsThemeNull() const + { + return (m_hTheme == NULL); + } + + CTheme& operator =(HTHEME hTheme) + { + m_hTheme = hTheme; + return *this; + } + + operator HTHEME() const + { + return m_hTheme; + } + + void Attach(HTHEME hTheme) + { + m_hTheme = hTheme; + } + + HTHEME Detach() + { + HTHEME hTheme = m_hTheme; + m_hTheme = NULL; + return hTheme; + } + +// Theme support helper + static bool IsThemingSupported() + { + if(m_nIsThemingSupported == -1) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CTheme::IsThemingSupported.\n")); + ATLASSERT(FALSE); + return false; + } + + if(m_nIsThemingSupported == -1) + { + HMODULE hThemeDLL = ::LoadLibrary(_T("uxtheme.dll")); + m_nIsThemingSupported = (hThemeDLL != NULL) ? 1 : 0; + if(hThemeDLL != NULL) + ::FreeLibrary(hThemeDLL); + } + + lock.Unlock(); + } + + ATLASSERT(m_nIsThemingSupported != -1); + return (m_nIsThemingSupported == 1); + } + +// Operations and theme properties + HTHEME OpenThemeData(HWND hWnd, LPCWSTR pszClassList) + { + if(!IsThemingSupported()) + return NULL; + + ATLASSERT(m_hTheme == NULL); + m_hTheme = ::OpenThemeData(hWnd, pszClassList); + return m_hTheme; + } + + HRESULT CloseThemeData() + { + HRESULT hRet = S_FALSE; + if(m_hTheme != NULL) + { + hRet = ::CloseThemeData(m_hTheme); + if(SUCCEEDED(hRet)) + m_hTheme = NULL; + } + return hRet; + } + + HRESULT DrawThemeBackground(HDC hDC, int nPartID, int nStateID, LPCRECT pRect, LPCRECT pClipRect = NULL) + { + ATLASSERT(m_hTheme != NULL); + return ::DrawThemeBackground(m_hTheme, hDC, nPartID, nStateID, pRect, pClipRect); + } + + HRESULT DrawThemeBackgroundEx(HDC hDC, int nPartID, int nStateID, LPCRECT pRect, const DTBGOPTS* pOptions = NULL) + { + ATLASSERT(m_hTheme != NULL); + return ::DrawThemeBackgroundEx(m_hTheme, hDC, nPartID, nStateID, pRect, pOptions); + } + + HRESULT DrawThemeText(HDC hDC, int nPartID, int nStateID, LPCWSTR pszText, int nCharCount, DWORD dwTextFlags, DWORD dwTextFlags2, LPCRECT pRect) + { + ATLASSERT(m_hTheme != NULL); + return ::DrawThemeText(m_hTheme, hDC, nPartID, nStateID, pszText, nCharCount, dwTextFlags, dwTextFlags2, pRect); + } + + HRESULT GetThemeBackgroundContentRect(HDC hDC, int nPartID, int nStateID, LPCRECT pBoundingRect, LPRECT pContentRect) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeBackgroundContentRect(m_hTheme, hDC, nPartID, nStateID, pBoundingRect, pContentRect); + } + + HRESULT GetThemeBackgroundExtent(HDC hDC, int nPartID, int nStateID, LPCRECT pContentRect, LPRECT pExtentRect) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeBackgroundExtent(m_hTheme, hDC, nPartID, nStateID, pContentRect, pExtentRect); + } + + HRESULT GetThemePartSize(HDC hDC, int nPartID, int nStateID, LPRECT pRect, enum THEMESIZE eSize, LPSIZE pSize) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemePartSize(m_hTheme, hDC, nPartID, nStateID, pRect, eSize, pSize); + } + + HRESULT GetThemeTextExtent(HDC hDC, int nPartID, int nStateID, LPCWSTR pszText, int nCharCount, DWORD dwTextFlags, LPCRECT pBoundingRect, LPRECT pExtentRect) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeTextExtent(m_hTheme, hDC, nPartID, nStateID, pszText, nCharCount, dwTextFlags, pBoundingRect, pExtentRect); + } + + HRESULT GetThemeTextMetrics(HDC hDC, int nPartID, int nStateID, PTEXTMETRICW pTextMetric) const + { + ATLASSERT(m_hTheme != NULL); +#ifdef _WTL_NEW_UXTHEME + return ::GetThemeTextMetrics(m_hTheme, hDC, nPartID, nStateID, pTextMetric); +#else // !_WTL_NEW_UXTHEME + // Note: The cast to PTEXTMETRIC is because uxtheme.h incorrectly uses it instead of PTEXTMETRICW + return ::GetThemeTextMetrics(m_hTheme, hDC, nPartID, nStateID, (PTEXTMETRIC)pTextMetric); +#endif // !_WTL_NEW_UXTHEME + } + + HRESULT GetThemeBackgroundRegion(HDC hDC, int nPartID, int nStateID, LPCRECT pRect, HRGN* pRegion) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeBackgroundRegion(m_hTheme, hDC, nPartID, nStateID, pRect, pRegion); + } + + HRESULT HitTestThemeBackground(HDC hDC, int nPartID, int nStateID, DWORD dwOptions, LPCRECT pRect, HRGN hrgn, POINT ptTest, WORD* pwHitTestCode) const + { + ATLASSERT(m_hTheme != NULL); + return ::HitTestThemeBackground(m_hTheme, hDC, nPartID, nStateID, dwOptions, pRect, hrgn, ptTest, pwHitTestCode); + } + + HRESULT DrawThemeEdge(HDC hDC, int nPartID, int nStateID, LPCRECT pDestRect, UINT uEdge, UINT uFlags, LPRECT pContentRect = NULL) + { + ATLASSERT(m_hTheme != NULL); + return ::DrawThemeEdge(m_hTheme, hDC, nPartID, nStateID, pDestRect, uEdge, uFlags, pContentRect); + } + + HRESULT DrawThemeIcon(HDC hDC, int nPartID, int nStateID, LPCRECT pRect, HIMAGELIST himl, int nImageIndex) + { + ATLASSERT(m_hTheme != NULL); + return ::DrawThemeIcon(m_hTheme, hDC, nPartID, nStateID, pRect, himl, nImageIndex); + } + + BOOL IsThemePartDefined(int nPartID, int nStateID) const + { + ATLASSERT(m_hTheme != NULL); + return ::IsThemePartDefined(m_hTheme, nPartID, nStateID); + } + + BOOL IsThemeBackgroundPartiallyTransparent(int nPartID, int nStateID) const + { + ATLASSERT(m_hTheme != NULL); + return ::IsThemeBackgroundPartiallyTransparent(m_hTheme, nPartID, nStateID); + } + + HRESULT GetThemeColor(int nPartID, int nStateID, int nPropID, COLORREF* pColor) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeColor(m_hTheme, nPartID, nStateID, nPropID, pColor); + } + + HRESULT GetThemeMetric(HDC hDC, int nPartID, int nStateID, int nPropID, int* pnVal) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeMetric(m_hTheme, hDC, nPartID, nStateID, nPropID, pnVal); + } + + HRESULT GetThemeString(int nPartID, int nStateID, int nPropID, LPWSTR pszBuff, int cchMaxBuffChars) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeString(m_hTheme, nPartID, nStateID, nPropID, pszBuff, cchMaxBuffChars); + } + + HRESULT GetThemeBool(int nPartID, int nStateID, int nPropID, BOOL* pfVal) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeBool(m_hTheme, nPartID, nStateID, nPropID, pfVal); + } + + HRESULT GetThemeInt(int nPartID, int nStateID, int nPropID, int* pnVal) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeInt(m_hTheme, nPartID, nStateID, nPropID, pnVal); + } + + HRESULT GetThemeEnumValue(int nPartID, int nStateID, int nPropID, int* pnVal) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeEnumValue(m_hTheme, nPartID, nStateID, nPropID, pnVal); + } + + HRESULT GetThemePosition(int nPartID, int nStateID, int nPropID, LPPOINT pPoint) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemePosition(m_hTheme, nPartID, nStateID, nPropID, pPoint); + } + + // deprecated + HRESULT GetThemeFont(int nPartID, HDC hDC, int nStateID, int nPropID, LOGFONTW* pFont) const + { + ATLASSERT(m_hTheme != NULL); +#ifdef _WTL_NEW_UXTHEME + return ::GetThemeFont(m_hTheme, hDC, nPartID, nStateID, nPropID, pFont); +#else // !_WTL_NEW_UXTHEME + // Note: The cast to LOGFONT* is because uxtheme.h incorrectly uses it instead of LOGFONTW* + return ::GetThemeFont(m_hTheme, hDC, nPartID, nStateID, nPropID, (LOGFONT*)pFont); +#endif // !_WTL_NEW_UXTHEME + } + + HRESULT GetThemeFont(HDC hDC, int nPartID, int nStateID, int nPropID, LOGFONTW* pFont) const + { + ATLASSERT(m_hTheme != NULL); +#ifdef _WTL_NEW_UXTHEME + return ::GetThemeFont(m_hTheme, hDC, nPartID, nStateID, nPropID, pFont); +#else // !_WTL_NEW_UXTHEME + // Note: The cast to LOGFONT* is because uxtheme.h incorrectly uses it instead of LOGFONTW* + return ::GetThemeFont(m_hTheme, hDC, nPartID, nStateID, nPropID, (LOGFONT*)pFont); +#endif // !_WTL_NEW_UXTHEME + } + + HRESULT GetThemeRect(int nPartID, int nStateID, int nPropID, LPRECT pRect) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeRect(m_hTheme, nPartID, nStateID, nPropID, pRect); + } + + HRESULT GetThemeMargins(HDC hDC, int nPartID, int nStateID, int nPropID, LPRECT pRect, PMARGINS pMargins) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeMargins(m_hTheme, hDC, nPartID, nStateID, nPropID, pRect, pMargins); + } + + HRESULT GetThemeIntList(int nPartID, int nStateID, int nPropID, INTLIST* pIntList) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeIntList(m_hTheme, nPartID, nStateID, nPropID, pIntList); + } + + HRESULT GetThemePropertyOrigin(int nPartID, int nStateID, int nPropID, enum PROPERTYORIGIN* pOrigin) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemePropertyOrigin(m_hTheme, nPartID, nStateID, nPropID, pOrigin); + } + + HRESULT GetThemeFilename(int nPartID, int nStateID, int nPropID, LPWSTR pszThemeFileName, int cchMaxBuffChars) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeFilename(m_hTheme, nPartID, nStateID, nPropID, pszThemeFileName, cchMaxBuffChars); + } + + COLORREF GetThemeSysColor(int nColorID) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeSysColor(m_hTheme, nColorID); + } + + HBRUSH GetThemeSysColorBrush(int nColorID) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeSysColorBrush(m_hTheme, nColorID); + } + + int GetThemeSysSize(int nSizeID) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeSysSize(m_hTheme, nSizeID); + } + + BOOL GetThemeSysBool(int nBoolID) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeSysBool(m_hTheme, nBoolID); + } + + HRESULT GetThemeSysFont(int nFontID, LOGFONTW* plf) const + { + ATLASSERT(m_hTheme != NULL); +#ifdef _WTL_NEW_UXTHEME + return ::GetThemeSysFont(m_hTheme, nFontID, plf); +#else // !_WTL_NEW_UXTHEME + // Note: The cast to LOGFONT* is because uxtheme.h incorrectly uses it instead of LOGFONTW* + return ::GetThemeSysFont(m_hTheme, nFontID, (LOGFONT*)plf); +#endif // !_WTL_NEW_UXTHEME + } + + HRESULT GetThemeSysString(int nStringID, LPWSTR pszStringBuff, int cchMaxStringChars) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeSysString(m_hTheme, nStringID, pszStringBuff, cchMaxStringChars); + } + + HRESULT GetThemeSysInt(int nIntID, int* pnValue) const + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeSysInt(m_hTheme, nIntID, pnValue); + } + +#ifdef _WTL_NEW_UXTHEME + HTHEME OpenThemeDataEx(HWND hWnd, LPCWSTR pszClassList, DWORD dwFlags) + { + if(!IsThemingSupported()) + return NULL; + + ATLASSERT(m_hTheme == NULL); + m_hTheme = ::OpenThemeDataEx(hWnd, pszClassList, dwFlags); + return m_hTheme; + } + + HRESULT DrawThemeTextEx(HDC hDC, int nPartID, int nStateID, LPCWSTR pszText, int cchText, DWORD dwTextFlags, LPRECT lpRect, const DTTOPTS* pOptions) + { + ATLASSERT(m_hTheme != NULL); + return ::DrawThemeTextEx(m_hTheme, hDC, nPartID, nStateID, pszText, cchText, dwTextFlags, lpRect, pOptions); + } + + HRESULT GetThemeTransitionDuration(int nPartID, int nFromStateID, int nToStateID, int nPropID, DWORD& dwDuration) + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeTransitionDuration(m_hTheme, nPartID, nFromStateID, nToStateID, nPropID, &dwDuration); + } +#endif // _WTL_NEW_UXTHEME + +#if (_WIN32_WINNT >= 0x0600) + HRESULT GetThemeBitmap(int nPartID, int nStateID, int nPropID, ULONG uFlags, HBITMAP& hBitmap) + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeBitmap(m_hTheme, nPartID, nStateID, nPropID, uFlags, &hBitmap); + } + + HRESULT GetThemeStream(int nPartID, int nStateID, int nPropID, VOID** ppvStream, DWORD* pcbStream, HINSTANCE hInstance) + { + ATLASSERT(m_hTheme != NULL); + return ::GetThemeStream(m_hTheme, nPartID, nStateID, nPropID, ppvStream, pcbStream, hInstance); + } +#endif // (_WIN32_WINNT >= 0x0600) +}; + +__declspec(selectany) int CTheme::m_nIsThemingSupported = -1; + + +/////////////////////////////////////////////////////////////////////////////// +// CThemeImpl - theme support implementation + +// Derive from this class to implement window with theme support. +// Example: +// class CMyThemeWindow : public CWindowImpl, public CThemeImpl +// { +// ... +// BEGIN_MSG_MAP(CMyThemeWindow) +// CHAIN_MSG_MAP(CThemeImpl) +// ... +// END_MSG_MAP() +// ... +// }; +// +// If you set theme class list, the class will automaticaly open/close/reopen theme data. + + +// Helper for drawing theme client edge +inline bool AtlDrawThemeClientEdge(HTHEME hTheme, HWND hWnd, HRGN hRgnUpdate = NULL, HBRUSH hBrush = NULL, int nPartID = 0, int nStateID = 0) +{ + ATLASSERT(hTheme != NULL); + ATLASSERT(::IsWindow(hWnd)); + + CWindowDC dc(hWnd); + if(dc.IsNull()) + return false; + + // Get border size + int cxBorder = GetSystemMetrics(SM_CXBORDER); + int cyBorder = GetSystemMetrics(SM_CYBORDER); + if(SUCCEEDED(::GetThemeInt(hTheme, nPartID, nStateID, TMT_SIZINGBORDERWIDTH, &cxBorder))) + cyBorder = cxBorder; + + RECT rect; + ::GetWindowRect(hWnd, &rect); + + // Remove the client edge from the update region + int cxEdge = GetSystemMetrics(SM_CXEDGE); + int cyEdge = GetSystemMetrics(SM_CYEDGE); + ::InflateRect(&rect, -cxEdge, -cyEdge); + CRgn rgn; + rgn.CreateRectRgnIndirect(&rect); + if(rgn.IsNull()) + return false; + + if(hRgnUpdate != NULL) + rgn.CombineRgn(hRgnUpdate, rgn, RGN_AND); + + ::OffsetRect(&rect, -rect.left, -rect.top); + + ::OffsetRect(&rect, cxEdge, cyEdge); + dc.ExcludeClipRect(&rect); + ::InflateRect(&rect, cxEdge, cyEdge); + + ::DrawThemeBackground(hTheme, dc, nPartID, nStateID, &rect, NULL); + + // Use background brush too, since theme border might not cover everything + if(cxBorder < cxEdge && cyBorder < cyEdge) + { + if(hBrush == NULL) +// need conditional code because types don't match in winuser.h +#ifdef _WIN64 + hBrush = (HBRUSH)::GetClassLongPtr(hWnd, GCLP_HBRBACKGROUND); +#else + hBrush = (HBRUSH)UlongToPtr(::GetClassLongPtr(hWnd, GCLP_HBRBACKGROUND)); +#endif + + ::InflateRect(&rect, cxBorder - cxEdge, cyBorder - cyEdge); + dc.FillRect(&rect, hBrush); + } + + ::DefWindowProc(hWnd, WM_NCPAINT, (WPARAM)rgn.m_hRgn, 0L); + + return true; +} + + +// Theme extended styles +#define THEME_EX_3DCLIENTEDGE 0x00000001 +#define THEME_EX_THEMECLIENTEDGE 0x00000002 + +template +class CThemeImpl : public TBase +{ +public: +// Data members + LPWSTR m_lpstrThemeClassList; + DWORD m_dwExtendedStyle; // theme specific extended styles + +// Constructor & destructor + CThemeImpl() : m_lpstrThemeClassList(NULL), m_dwExtendedStyle(0) + { } + + ~CThemeImpl() + { + delete [] m_lpstrThemeClassList; + } + +// Attributes + bool SetThemeClassList(LPCWSTR lpstrThemeClassList) + { + if(m_lpstrThemeClassList != NULL) + { + delete [] m_lpstrThemeClassList; + m_lpstrThemeClassList = NULL; + } + + if(lpstrThemeClassList == NULL) + return true; + + int cchLen = lstrlenW(lpstrThemeClassList) + 1; + ATLTRY(m_lpstrThemeClassList = new WCHAR[cchLen]); + if(m_lpstrThemeClassList == NULL) + return false; + + SecureHelper::strcpyW_x(m_lpstrThemeClassList, cchLen, lpstrThemeClassList); + + return true; + } + + bool GetThemeClassList(LPWSTR lpstrThemeClassList, int cchListBuffer) const + { + int cchLen = lstrlenW(m_lpstrThemeClassList) + 1; + if(cchListBuffer < cchLen) + return false; + + SecureHelper::strcpyW_x(lpstrThemeClassList, cchListBuffer, m_lpstrThemeClassList); + + return true; + } + + LPCWSTR GetThemeClassList() const + { + return m_lpstrThemeClassList; + } + + DWORD SetThemeExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0) + { + DWORD dwPrevStyle = m_dwExtendedStyle; + if(dwMask == 0) + m_dwExtendedStyle = dwExtendedStyle; + else + m_dwExtendedStyle = (m_dwExtendedStyle & ~dwMask) | (dwExtendedStyle & dwMask); + return dwPrevStyle; + } + + DWORD GetThemeExtendedStyle() const + { + return m_dwExtendedStyle; + } + +// Operations + HTHEME OpenThemeData() + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + ATLASSERT(m_lpstrThemeClassList != NULL); + if(m_lpstrThemeClassList == NULL) + return NULL; + CloseThemeData(); + return TBase::OpenThemeData(pT->m_hWnd, m_lpstrThemeClassList); + } + + HTHEME OpenThemeData(LPCWSTR pszClassList) + { + if(!SetThemeClassList(pszClassList)) + return NULL; + return OpenThemeData(); + } + + HRESULT SetWindowTheme(LPCWSTR pszSubAppName, LPCWSTR pszSubIDList) + { + if(!IsThemingSupported()) + return S_FALSE; + + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::SetWindowTheme(pT->m_hWnd, pszSubAppName, pszSubIDList); + } + + HTHEME GetWindowTheme() const + { + if(!IsThemingSupported()) + return NULL; + + const T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::GetWindowTheme(pT->m_hWnd); + } + + HRESULT EnableThemeDialogTexture(DWORD dwFlags) + { + if(!IsThemingSupported()) + return S_FALSE; + + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::EnableThemeDialogTexture(pT->m_hWnd, dwFlags); + } + + BOOL IsThemeDialogTextureEnabled() const + { + if(!IsThemingSupported()) + return FALSE; + + const T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::IsThemeDialogTextureEnabled(pT->m_hWnd); + } + + HRESULT DrawThemeParentBackground(HDC hDC, const RECT* pRect = NULL) + { + if(!IsThemingSupported()) + return S_FALSE; + + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); +#ifdef _WTL_NEW_UXTHEME + return ::DrawThemeParentBackground(pT->m_hWnd, hDC, pRect); +#else + return ::DrawThemeParentBackground(pT->m_hWnd, hDC, (RECT*)pRect); +#endif + } + +#ifdef _WTL_NEW_UXTHEME + HRESULT SetWindowThemeAttribute(WINDOWTHEMEATTRIBUTETYPE type, PVOID pvAttribute, DWORD cbAttribute) + { + if(!IsThemingSupported()) + return S_FALSE; + + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::SetWindowThemeAttribute(pT->m_hWnd, type, pvAttribute, cbAttribute); + } + + HRESULT SetWindowThemeNonClientAttributes(DWORD dwAttributes, DWORD dwMask) + { + if(!IsThemingSupported()) + return S_FALSE; + + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + WTA_OPTIONS opt = { dwAttributes, dwMask }; + return ::SetWindowThemeAttribute(pT->m_hWnd, WTA_NONCLIENT, (PVOID)&opt, sizeof(opt)); + } + + HRESULT DrawThemeParentBackgroundEx(HDC hDC, DWORD dwFlags, const RECT* lpRect = NULL) + { + if(!IsThemingSupported()) + return S_FALSE; + + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + return ::DrawThemeParentBackgroundEx(pT->m_hWnd, hDC, dwFlags, lpRect); + } +#endif // _WTL_NEW_UXTHEME + +// Message map and handlers + // Note: If you handle any of these messages in your derived class, + // it is better to put CHAIN_MSG_MAP at the start of your message map. + BEGIN_MSG_MAP(CThemeImpl) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged) + MESSAGE_HANDLER(WM_NCPAINT, OnNcPaint) + END_MSG_MAP() + + LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_lpstrThemeClassList != NULL) + OpenThemeData(); + bHandled = FALSE; + return 1; + } + + LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + CloseThemeData(); + bHandled = FALSE; + return 1; + } + + LRESULT OnThemeChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + CloseThemeData(); + if(m_lpstrThemeClassList != NULL) + OpenThemeData(); + bHandled = FALSE; + return 1; + } + + LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + LRESULT lRet = 0; + bHandled = FALSE; + if(IsThemingSupported() && ((pT->GetExStyle() & WS_EX_CLIENTEDGE) != 0)) + { + if((m_dwExtendedStyle & THEME_EX_3DCLIENTEDGE) != 0) + { + lRet = ::DefWindowProc(pT->m_hWnd, uMsg, wParam, lParam); + bHandled = TRUE; + } + else if((m_hTheme != NULL) && ((m_dwExtendedStyle & THEME_EX_THEMECLIENTEDGE) != 0)) + { + HRGN hRgn = (wParam != 1) ? (HRGN)wParam : NULL; + if(pT->DrawThemeClientEdge(hRgn)) + bHandled = TRUE; + } + } + return lRet; + } + +// Drawing helper + bool DrawThemeClientEdge(HRGN hRgnUpdate) + { + T* pT = static_cast(this); + return AtlDrawThemeClientEdge(m_hTheme, pT->m_hWnd, hRgnUpdate, NULL, 0, 0); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// Buffered Paint and Animation + +#ifdef _WTL_NEW_UXTHEME + +/////////////////////////////////////////////////////////////////////////////// +// CBufferedPaintBase - Buffered Paint support for othe classes + +class CBufferedPaintBase +{ +public: + static int m_nIsBufferedPaintSupported; + + CBufferedPaintBase() + { + if(IsBufferedPaintSupported()) + ATLVERIFY(SUCCEEDED(::BufferedPaintInit())); + } + + ~CBufferedPaintBase() + { + if(IsBufferedPaintSupported()) + ATLVERIFY(SUCCEEDED(::BufferedPaintUnInit())); + } + + static bool IsBufferedPaintSupported() + { + if(m_nIsBufferedPaintSupported == -1) + { + CStaticDataInitCriticalSectionLock lock; + if(FAILED(lock.Lock())) + { + ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CBufferedPaintBase::IsBufferedPaintSupported.\n")); + ATLASSERT(FALSE); + return false; + } + + if(m_nIsBufferedPaintSupported == -1) + m_nIsBufferedPaintSupported = RunTimeHelper::IsVista() ? 1 : 0; + + lock.Unlock(); + } + + ATLASSERT(m_nIsBufferedPaintSupported != -1); + return (m_nIsBufferedPaintSupported == 1); + } +}; + +__declspec(selectany) int CBufferedPaintBase::m_nIsBufferedPaintSupported = -1; + + +/////////////////////////////////////////////////////////////////////////////// +// CBufferedPaint - support for buffered paint functions + +class CBufferedPaint +{ +public: + HPAINTBUFFER m_hPaintBuffer; + + CBufferedPaint() : m_hPaintBuffer(NULL) + { } + + ~CBufferedPaint() + { + ATLVERIFY(SUCCEEDED(End())); + } + + bool IsNull() const + { + return (m_hPaintBuffer == NULL); + } + + HPAINTBUFFER Begin(HDC hdcTarget, const RECT* prcTarget, BP_BUFFERFORMAT dwFormat, BP_PAINTPARAMS* pPaintParams, HDC* phdcPaint) + { + ATLASSERT(m_hPaintBuffer == NULL); + m_hPaintBuffer = ::BeginBufferedPaint(hdcTarget, prcTarget, dwFormat, pPaintParams, phdcPaint); + return m_hPaintBuffer; + } + + HRESULT End(BOOL bUpdate = TRUE) + { + HRESULT hRet = S_FALSE; + if(m_hPaintBuffer != NULL) + { + hRet = ::EndBufferedPaint(m_hPaintBuffer, bUpdate); + m_hPaintBuffer = NULL; + } + return hRet; + } + + HRESULT GetTargetRect(LPRECT pRect) const + { + ATLASSERT(m_hPaintBuffer != NULL); + return ::GetBufferedPaintTargetRect(m_hPaintBuffer, pRect); + } + + HDC GetTargetDC() const + { + ATLASSERT(m_hPaintBuffer != NULL); + return ::GetBufferedPaintTargetDC(m_hPaintBuffer); + } + + HDC GetPaintDC() const + { + ATLASSERT(m_hPaintBuffer != NULL); + return ::GetBufferedPaintDC(m_hPaintBuffer); + } + + HRESULT GetBits(RGBQUAD** ppbBuffer, int* pcxRow) const + { + ATLASSERT(m_hPaintBuffer != NULL); + return ::GetBufferedPaintBits(m_hPaintBuffer, ppbBuffer, pcxRow); + } + + HRESULT Clear(const RECT* pRect = NULL) + { + ATLASSERT(m_hPaintBuffer != NULL); + return ::BufferedPaintClear(m_hPaintBuffer, pRect); + } + + HRESULT SetAlpha(BYTE alpha, const RECT* pRect = NULL) + { + ATLASSERT(m_hPaintBuffer != NULL); + return ::BufferedPaintSetAlpha(m_hPaintBuffer, pRect, alpha); + } + + HRESULT MakeOpaque(const RECT* pRect = NULL) + { + ATLASSERT(m_hPaintBuffer != NULL); + return ::BufferedPaintSetAlpha(m_hPaintBuffer, pRect, 255); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CBufferedPaintImpl - provides buffered paint for any window + +template +class ATL_NO_VTABLE CBufferedPaintImpl : public CBufferedPaintBase +{ +public: + CBufferedPaint m_BufferedPaint; + BP_BUFFERFORMAT m_dwFormat; + BP_PAINTPARAMS m_PaintParams; + + CBufferedPaintImpl() : m_dwFormat(BPBF_TOPDOWNDIB) + { + memset(&m_PaintParams, 0, sizeof(BP_PAINTPARAMS)); + m_PaintParams.cbSize = sizeof(BP_PAINTPARAMS); + } + +// Message map and handlers + BEGIN_MSG_MAP(CBufferedPaintImpl) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) + MESSAGE_HANDLER(WM_PAINT, OnPaint) + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) + END_MSG_MAP() + + LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return 1; // no background needed + } + + LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + if(wParam != NULL) + { + RECT rect = { 0 }; + pT->GetClientRect(&rect); + pT->DoPaint((HDC)wParam, rect); + } + else + { + CPaintDC dc(pT->m_hWnd); + pT->DoBufferedPaint(dc.m_hDC, dc.m_ps.rcPaint); + } + + return 0; + } + +// Overrideables + void DoBufferedPaint(CDCHandle dc, RECT& rect) + { + HDC hDCPaint = NULL; + if(IsBufferedPaintSupported()) + m_BufferedPaint.Begin(dc, &rect, m_dwFormat, &m_PaintParams, &hDCPaint); + + T* pT = static_cast(this); + if(hDCPaint != NULL) + pT->DoPaint(hDCPaint, rect); + else + pT->DoPaint(dc.m_hDC, rect); + + if(IsBufferedPaintSupported()) + m_BufferedPaint.End(); + } + + void DoPaint(CDCHandle /*dc*/, RECT& /*rect*/) + { + // must be implemented in a derived class + ATLASSERT(FALSE); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CBufferedPaintWindowImpl - implements a window that uses buffered paint + +template +class ATL_NO_VTABLE CBufferedPaintWindowImpl : + public ATL::CWindowImpl, + public CBufferedPaintImpl< T > +{ +public: + BEGIN_MSG_MAP(CBufferedPaintWindowImpl) + CHAIN_MSG_MAP(CBufferedPaintImpl< T >) + END_MSG_MAP() +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CBufferedAnimation - support for buffered animation + +class CBufferedAnimation +{ +public: + HANIMATIONBUFFER m_hAnimationBuffer; + + CBufferedAnimation() : m_hAnimationBuffer(NULL) + { } + + ~CBufferedAnimation() + { + ATLVERIFY(SUCCEEDED(End())); + } + + bool IsNull() const + { + return (m_hAnimationBuffer == NULL); + } + + HANIMATIONBUFFER Begin(HWND hWnd, HDC hDCTarget, const RECT* pRectTarget, BP_BUFFERFORMAT dwFormat, BP_PAINTPARAMS* pPaintParams, BP_ANIMATIONPARAMS* pAnimationParams, HDC* phdcFrom, HDC* phdcTo) + { + ATLASSERT(m_hAnimationBuffer == NULL); + m_hAnimationBuffer = ::BeginBufferedAnimation(hWnd, hDCTarget, pRectTarget, dwFormat, pPaintParams, pAnimationParams, phdcFrom, phdcTo); + return m_hAnimationBuffer; + } + + HRESULT End(BOOL bUpdate = TRUE) + { + HRESULT hRet = S_FALSE; + if(m_hAnimationBuffer != NULL) + { + hRet = ::EndBufferedAnimation(m_hAnimationBuffer, bUpdate); + m_hAnimationBuffer = NULL; + } + return hRet; + } + + static bool IsRendering(HWND hWnd, HDC hDC) + { + return (::BufferedPaintRenderAnimation(hWnd, hDC) != FALSE); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CBufferedAnimationImpl - provides buffered animation support for any window + +// Note: You can either use m_State and m_NewState to store the state information +// for the animation change, or map your state to those data members. DoPaint() +// should only rely on the state information that is passed to it. + +template +class ATL_NO_VTABLE CBufferedAnimationImpl : public CBufferedPaintBase +{ +public: + BP_BUFFERFORMAT m_dwFormat; + BP_PAINTPARAMS m_PaintParams; + BP_ANIMATIONPARAMS m_AnimationParams; + + TState m_State; + TState m_NewState; + + CBufferedAnimationImpl(TState InitialState) : m_dwFormat(BPBF_TOPDOWNDIB) + { + memset(&m_PaintParams, 0, sizeof(BP_PAINTPARAMS)); + m_PaintParams.cbSize = sizeof(BP_PAINTPARAMS); + + memset(&m_AnimationParams, 0, sizeof(BP_ANIMATIONPARAMS)); + m_AnimationParams.cbSize = sizeof(BP_ANIMATIONPARAMS); + m_AnimationParams.style = BPAS_LINEAR; + m_AnimationParams.dwDuration = 500; + + T* pT = static_cast(this); + pT->SetState(InitialState); + pT->SetNewState(InitialState); + } + + DWORD GetDuration() const + { + return m_AnimationParams.dwDuration; + } + + void SetDuration(DWORD dwDuration) + { + m_AnimationParams.dwDuration = dwDuration; + } + + void DoAnimation(TState NewState, const RECT* pRect = NULL) + { + T* pT = static_cast(this); + pT->SetNewState(NewState); + + pT->InvalidateRect(pRect, FALSE); + pT->UpdateWindow(); + + pT->SetState(NewState); + } + +// Message map and handlers + BEGIN_MSG_MAP(CBufferedAnimationImpl) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) + MESSAGE_HANDLER(WM_PAINT, OnPaint) + MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) + END_MSG_MAP() + + LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + return 1; // no background needed + } + + LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + if(wParam != NULL) + { + RECT rect = { 0 }; + pT->GetClientRect(&rect); + pT->DoPaint((HDC)wParam, rect, m_NewState); + } + else + { + CPaintDC dc(pT->m_hWnd); + pT->DoAnimationPaint(dc.m_hDC, dc.m_ps.rcPaint); + } + + return 0; + } + +// Overrideables + void SetState(TState State) + { + m_State = State; + } + + void SetNewState(TState State) + { + m_NewState = State; + } + + bool AreStatesEqual() const + { + return (m_State == m_NewState); + } + + void DoAnimationPaint(CDCHandle dc, RECT& rect) + { + T* pT = static_cast(this); + if(IsBufferedPaintSupported() && CBufferedAnimation::IsRendering(pT->m_hWnd, dc)) + return; + + DWORD dwDurationSave = m_AnimationParams.dwDuration; + if(pT->AreStatesEqual()) + m_AnimationParams.dwDuration = 0; + + HDC hdcFrom = NULL, hdcTo = NULL; + CBufferedAnimation ba; + if(IsBufferedPaintSupported()) + ba.Begin(pT->m_hWnd, dc, &rect, m_dwFormat, &m_PaintParams, &m_AnimationParams, &hdcFrom, &hdcTo); + + if(!ba.IsNull()) + { + if(hdcFrom != NULL) + pT->DoPaint(hdcFrom, rect, m_State); + + if (hdcTo != NULL) + pT->DoPaint(hdcTo, rect, m_NewState); + } + else + { + pT->DoPaint(dc.m_hDC, rect, m_NewState); + } + + m_AnimationParams.dwDuration = dwDurationSave; + } + + void DoPaint(CDCHandle /*dc*/, RECT& /*rect*/, TState /*State*/) + { + // must be implemented in a derived class + ATLASSERT(FALSE); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CBufferedAnimationWindowImpl - implements a window that uses buffered animation + +template +class ATL_NO_VTABLE CBufferedAnimationWindowImpl : + public ATL::CWindowImpl, + public CBufferedAnimationImpl< T, TState > +{ +public: + CBufferedAnimationWindowImpl(TState InitialState) : CBufferedAnimationImpl< T, TState >(InitialState) + { } + + typedef CBufferedAnimationImpl< T, TState > _baseBufferedAnimation; + BEGIN_MSG_MAP(CBufferedAnimationWindowImpl) + CHAIN_MSG_MAP(_baseBufferedAnimation) + END_MSG_MAP() +}; + +#endif // _WTL_NEW_UXTHEME + +}; // namespace WTL + +#endif // __ATLTHEME_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atluser.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atluser.h new file mode 100644 index 0000000000..6cd8205a73 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atluser.h @@ -0,0 +1,1391 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLUSER_H__ +#define __ATLUSER_H__ + +#pragma once + +#ifndef __ATLAPP_H__ + #error atluser.h requires atlapp.h to be included first +#endif + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CMenuItemInfo +// CMenuT +// CAcceleratorT +// CIconT +// CCursorT +// CResource +// +// Global functions: +// AtlMessageBox() +// +// AtlLoadAccelerators() +// AtlLoadMenu() +// AtlLoadBitmap() +// AtlLoadSysBitmap() +// AtlLoadCursor() +// AtlLoadSysCursor() +// AtlLoadIcon() +// AtlLoadSysIcon() +// AtlLoadBitmapImage() +// AtlLoadCursorImage() +// AtlLoadIconImage() +// AtlLoadSysBitmapImage() +// AtlLoadSysCursorImage() +// AtlLoadSysIconImage() +// AtlLoadString() + + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// AtlMessageBox - accepts both memory and resource based strings + +inline int AtlMessageBox(HWND hWndOwner, ATL::_U_STRINGorID message, ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uType = MB_OK | MB_ICONINFORMATION) +{ + ATLASSERT(hWndOwner == NULL || ::IsWindow(hWndOwner)); + + LPTSTR lpstrMessage = NULL; + if(IS_INTRESOURCE(message.m_lpstr)) + { + for(int nLen = 256; ; nLen *= 2) + { + ATLTRY(lpstrMessage = new TCHAR[nLen]); + if(lpstrMessage == NULL) + { + ATLASSERT(FALSE); + return 0; + } + int nRes = ::LoadString(ModuleHelper::GetResourceInstance(), LOWORD(message.m_lpstr), lpstrMessage, nLen); + if(nRes < nLen - 1) + break; + delete [] lpstrMessage; + lpstrMessage = NULL; + } + + message.m_lpstr = lpstrMessage; + } + + LPTSTR lpstrTitle = NULL; + if(IS_INTRESOURCE(title.m_lpstr) && LOWORD(title.m_lpstr) != 0) + { + for(int nLen = 256; ; nLen *= 2) + { + ATLTRY(lpstrTitle = new TCHAR[nLen]); + if(lpstrTitle == NULL) + { + ATLASSERT(FALSE); + return 0; + } + int nRes = ::LoadString(ModuleHelper::GetResourceInstance(), LOWORD(title.m_lpstr), lpstrTitle, nLen); + if(nRes < nLen - 1) + break; + delete [] lpstrTitle; + lpstrTitle = NULL; + } + + title.m_lpstr = lpstrTitle; + } + + int nRet = ::MessageBox(hWndOwner, message.m_lpstr, title.m_lpstr, uType); + + delete [] lpstrMessage; + delete [] lpstrTitle; + + return nRet; +} + + +/////////////////////////////////////////////////////////////////////////////// +// CMenu + +#if (WINVER >= 0x0500) + #ifndef MII_SIZEOF_STRUCT + #define MII_SIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member)) + #endif + #define MENUITEMINFO_SIZE_VERSION_400A MII_SIZEOF_STRUCT(MENUITEMINFOA, cch) + #define MENUITEMINFO_SIZE_VERSION_400W MII_SIZEOF_STRUCT(MENUITEMINFOW, cch) + #ifdef UNICODE + #define MENUITEMINFO_SIZE_VERSION_400 MENUITEMINFO_SIZE_VERSION_400W + #else + #define MENUITEMINFO_SIZE_VERSION_400 MENUITEMINFO_SIZE_VERSION_400A + #endif // !UNICODE +#endif // (WINVER >= 0x0500) + +class CMenuItemInfo : public MENUITEMINFO +{ +public: + CMenuItemInfo() + { + memset(this, 0, sizeof(MENUITEMINFO)); + cbSize = sizeof(MENUITEMINFO); +#if (WINVER >= 0x0500) + // adjust struct size if running on older version of Windows + if(AtlIsOldWindows()) + { + ATLASSERT(cbSize > MENUITEMINFO_SIZE_VERSION_400); // must be + cbSize = MENUITEMINFO_SIZE_VERSION_400; + } +#endif // (WINVER >= 0x0500) + } +}; + + +// forward declarations +template class CMenuT; +typedef CMenuT CMenuHandle; +typedef CMenuT CMenu; + + +template +class CMenuT +{ +public: +// Data members + HMENU m_hMenu; + +// Constructor/destructor/operators + CMenuT(HMENU hMenu = NULL) : m_hMenu(hMenu) + { } + + ~CMenuT() + { + if(t_bManaged && m_hMenu != NULL) + DestroyMenu(); + } + + CMenuT& operator =(HMENU hMenu) + { + Attach(hMenu); + return *this; + } + + void Attach(HMENU hMenuNew) + { + ATLASSERT(::IsMenu(hMenuNew)); + if(t_bManaged && m_hMenu != NULL && m_hMenu != hMenuNew) + ::DestroyMenu(m_hMenu); + m_hMenu = hMenuNew; + } + + HMENU Detach() + { + HMENU hMenu = m_hMenu; + m_hMenu = NULL; + return hMenu; + } + + operator HMENU() const { return m_hMenu; } + + bool IsNull() const { return (m_hMenu == NULL); } + + BOOL IsMenu() const + { + return ::IsMenu(m_hMenu); + } + +// Create/destroy methods + BOOL CreateMenu() + { + ATLASSERT(m_hMenu == NULL); + m_hMenu = ::CreateMenu(); + return (m_hMenu != NULL) ? TRUE : FALSE; + } + + BOOL CreatePopupMenu() + { + ATLASSERT(m_hMenu == NULL); + m_hMenu = ::CreatePopupMenu(); + return (m_hMenu != NULL) ? TRUE : FALSE; + } + + BOOL LoadMenu(ATL::_U_STRINGorID menu) + { + ATLASSERT(m_hMenu == NULL); + m_hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), menu.m_lpstr); + return (m_hMenu != NULL) ? TRUE : FALSE; + } + +#ifndef _WIN32_WCE + BOOL LoadMenuIndirect(const void* lpMenuTemplate) + { + ATLASSERT(m_hMenu == NULL); + m_hMenu = ::LoadMenuIndirect(lpMenuTemplate); + return (m_hMenu != NULL) ? TRUE : FALSE; + } +#endif // !_WIN32_WCE + + BOOL DestroyMenu() + { + if (m_hMenu == NULL) + return FALSE; + BOOL bRet = ::DestroyMenu(m_hMenu); + if(bRet) + m_hMenu = NULL; + return bRet; + } + +// Menu Operations + BOOL DeleteMenu(UINT nPosition, UINT nFlags) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::DeleteMenu(m_hMenu, nPosition, nFlags); + } + + BOOL TrackPopupMenu(UINT nFlags, int x, int y, HWND hWnd, LPCRECT lpRect = NULL) + { + ATLASSERT(::IsMenu(m_hMenu)); +#ifndef _WIN32_WCE +#if (WINVER >= 0x0500) + x = _FixTrackMenuPopupX(x, y); +#endif // !(WINVER >= 0x0500) + return ::TrackPopupMenu(m_hMenu, nFlags, x, y, 0, hWnd, lpRect); +#else // CE specific + lpRect; + return ::TrackPopupMenuEx(m_hMenu, nFlags, x, y, hWnd, NULL); +#endif // _WIN32_WCE + } + + BOOL TrackPopupMenuEx(UINT uFlags, int x, int y, HWND hWnd, LPTPMPARAMS lptpm = NULL) + { + ATLASSERT(::IsMenu(m_hMenu)); +#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) + x = _FixTrackMenuPopupX(x, y); +#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) + return ::TrackPopupMenuEx(m_hMenu, uFlags, x, y, hWnd, lptpm); + } + +#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) + // helper that fixes popup menu X position when it's off-screen + static int _FixTrackMenuPopupX(int x, int y) + { + POINT pt = { x, y }; + HMONITOR hMonitor = ::MonitorFromPoint(pt, MONITOR_DEFAULTTONULL); + if(hMonitor == NULL) + { + HMONITOR hMonitorNear = ::MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); + if(hMonitorNear != NULL) + { + MONITORINFO mi = { 0 }; + mi.cbSize = sizeof(MONITORINFO); + if(::GetMonitorInfo(hMonitorNear, &mi) != FALSE) + { + if(x < mi.rcWork.left) + x = mi.rcWork.left; + else if(x > mi.rcWork.right) + x = mi.rcWork.right; + } + } + } + + return x; + } + + BOOL GetMenuInfo(LPMENUINFO lpMenuInfo) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuInfo(m_hMenu, lpMenuInfo); + } + + BOOL SetMenuInfo(LPCMENUINFO lpMenuInfo) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::SetMenuInfo(m_hMenu, lpMenuInfo); + } +#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) + +// Menu Item Operations + BOOL AppendMenu(UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::AppendMenu(m_hMenu, nFlags, nIDNewItem, lpszNewItem); + } + + BOOL AppendMenu(UINT nFlags, HMENU hSubMenu, LPCTSTR lpszNewItem) + { + ATLASSERT(::IsMenu(m_hMenu)); + ATLASSERT(::IsMenu(hSubMenu)); + return ::AppendMenu(m_hMenu, nFlags | MF_POPUP, (UINT_PTR)hSubMenu, lpszNewItem); + } + +#ifndef _WIN32_WCE + BOOL AppendMenu(UINT nFlags, UINT_PTR nIDNewItem, HBITMAP hBmp) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::AppendMenu(m_hMenu, nFlags | MF_BITMAP, nIDNewItem, (LPCTSTR)hBmp); + } + + BOOL AppendMenu(UINT nFlags, HMENU hSubMenu, HBITMAP hBmp) + { + ATLASSERT(::IsMenu(m_hMenu)); + ATLASSERT(::IsMenu(hSubMenu)); + return ::AppendMenu(m_hMenu, nFlags | (MF_BITMAP | MF_POPUP), (UINT_PTR)hSubMenu, (LPCTSTR)hBmp); + } +#endif // !_WIN32_WCE + + UINT CheckMenuItem(UINT nIDCheckItem, UINT nCheck) + { + ATLASSERT(::IsMenu(m_hMenu)); + return (UINT)::CheckMenuItem(m_hMenu, nIDCheckItem, nCheck); + } + + UINT EnableMenuItem(UINT nIDEnableItem, UINT nEnable) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::EnableMenuItem(m_hMenu, nIDEnableItem, nEnable); + } + +#ifndef _WIN32_WCE + BOOL HiliteMenuItem(HWND hWnd, UINT uIDHiliteItem, UINT uHilite) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::HiliteMenuItem(hWnd, m_hMenu, uIDHiliteItem, uHilite); + } + + int GetMenuItemCount() const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuItemCount(m_hMenu); + } + + UINT GetMenuItemID(int nPos) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuItemID(m_hMenu, nPos); + } + + UINT GetMenuState(UINT nID, UINT nFlags) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuState(m_hMenu, nID, nFlags); + } + + int GetMenuString(UINT nIDItem, LPTSTR lpString, int nMaxCount, UINT nFlags) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuString(m_hMenu, nIDItem, lpString, nMaxCount, nFlags); + } + + int GetMenuStringLen(UINT nIDItem, UINT nFlags) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuString(m_hMenu, nIDItem, NULL, 0, nFlags); + } + +#ifndef _ATL_NO_COM + BOOL GetMenuString(UINT nIDItem, BSTR& bstrText, UINT nFlags) const + { + USES_CONVERSION; + ATLASSERT(::IsMenu(m_hMenu)); + ATLASSERT(bstrText == NULL); + + int nLen = GetMenuStringLen(nIDItem, nFlags); + if(nLen == 0) + { + bstrText = ::SysAllocString(OLESTR("")); + return (bstrText != NULL) ? TRUE : FALSE; + } + + nLen++; // increment to include terminating NULL char + CTempBuffer buff; + LPTSTR lpszText = buff.Allocate(nLen); + if(lpszText == NULL) + return FALSE; + + if(!GetMenuString(nIDItem, lpszText, nLen, nFlags)) + return FALSE; + + bstrText = ::SysAllocString(T2OLE(lpszText)); + return (bstrText != NULL) ? TRUE : FALSE; + } +#endif // !_ATL_NO_COM + +#elif (_ATL_VER >= 0x0800) + int GetMenuItemCount() const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ATL::GetMenuItemCount(m_hMenu); + } + + UINT GetMenuItemID(int nPos) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ATL::GetMenuItemID(m_hMenu, nPos); + } + + UINT GetMenuState(UINT nID, UINT nFlags) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ATL::GetMenuState(m_hMenu, nID, nFlags); + } + + int GetMenuString(UINT nIDItem, LPTSTR lpString, int nMaxCount, UINT nFlags) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ATL::GetMenuString(m_hMenu, nIDItem, lpString, nMaxCount, nFlags); + } + + int GetMenuStringLen(UINT nIDItem, UINT nFlags) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ATL::GetMenuString(m_hMenu, nIDItem, NULL, 0, nFlags); + } +#endif // (_ATL_VER >= 0x0800) + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + int GetMenuString(UINT nIDItem, _CSTRING_NS::CString& strText, UINT nFlags) const + { + ATLASSERT(::IsMenu(m_hMenu)); + + int nLen = GetMenuStringLen(nIDItem, nFlags); + if(nLen == 0) + return 0; + + nLen++; // increment to include terminating NULL char + LPTSTR lpstr = strText.GetBufferSetLength(nLen); + if(lpstr == NULL) + return 0; + int nRet = GetMenuString(nIDItem, lpstr, nLen, nFlags); + strText.ReleaseBuffer(); + return nRet; + } +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + CMenuHandle GetSubMenu(int nPos) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return CMenuHandle(::GetSubMenu(m_hMenu, nPos)); + } + + BOOL InsertMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::InsertMenu(m_hMenu, nPosition, nFlags, nIDNewItem, lpszNewItem); + } + + BOOL InsertMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, LPCTSTR lpszNewItem) + { + ATLASSERT(::IsMenu(m_hMenu)); + ATLASSERT(::IsMenu(hSubMenu)); + return ::InsertMenu(m_hMenu, nPosition, nFlags | MF_POPUP, (UINT_PTR)hSubMenu, lpszNewItem); + } + +#ifndef _WIN32_WCE + BOOL InsertMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem, HBITMAP hBmp) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::InsertMenu(m_hMenu, nPosition, nFlags | MF_BITMAP, nIDNewItem, (LPCTSTR)hBmp); + } + + BOOL InsertMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, HBITMAP hBmp) + { + ATLASSERT(::IsMenu(m_hMenu)); + ATLASSERT(::IsMenu(hSubMenu)); + return ::InsertMenu(m_hMenu, nPosition, nFlags | (MF_BITMAP | MF_POPUP), (UINT_PTR)hSubMenu, (LPCTSTR)hBmp); + } + + BOOL ModifyMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::ModifyMenu(m_hMenu, nPosition, nFlags, nIDNewItem, lpszNewItem); + } + + BOOL ModifyMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, LPCTSTR lpszNewItem) + { + ATLASSERT(::IsMenu(m_hMenu)); + ATLASSERT(::IsMenu(hSubMenu)); + return ::ModifyMenu(m_hMenu, nPosition, nFlags | MF_POPUP, (UINT_PTR)hSubMenu, lpszNewItem); + } + + BOOL ModifyMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem, HBITMAP hBmp) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::ModifyMenu(m_hMenu, nPosition, nFlags | MF_BITMAP, nIDNewItem, (LPCTSTR)hBmp); + } + + BOOL ModifyMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, HBITMAP hBmp) + { + ATLASSERT(::IsMenu(m_hMenu)); + ATLASSERT(::IsMenu(hSubMenu)); + return ::ModifyMenu(m_hMenu, nPosition, nFlags | (MF_BITMAP | MF_POPUP), (UINT_PTR)hSubMenu, (LPCTSTR)hBmp); + } +#endif // !_WIN32_WCE + + BOOL RemoveMenu(UINT nPosition, UINT nFlags) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::RemoveMenu(m_hMenu, nPosition, nFlags); + } + +#ifndef _WIN32_WCE + BOOL SetMenuItemBitmaps(UINT nPosition, UINT nFlags, HBITMAP hBmpUnchecked, HBITMAP hBmpChecked) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::SetMenuItemBitmaps(m_hMenu, nPosition, nFlags, hBmpUnchecked, hBmpChecked); + } +#endif // !_WIN32_WCE + + BOOL CheckMenuRadioItem(UINT nIDFirst, UINT nIDLast, UINT nIDItem, UINT nFlags) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::CheckMenuRadioItem(m_hMenu, nIDFirst, nIDLast, nIDItem, nFlags); + } + + BOOL GetMenuItemInfo(UINT uItem, BOOL bByPosition, LPMENUITEMINFO lpmii) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return (BOOL)::GetMenuItemInfo(m_hMenu, uItem, bByPosition, lpmii); + } + + BOOL SetMenuItemInfo(UINT uItem, BOOL bByPosition, LPMENUITEMINFO lpmii) + { + ATLASSERT(::IsMenu(m_hMenu)); + return (BOOL)::SetMenuItemInfo(m_hMenu, uItem, bByPosition, lpmii); + } + +#ifndef _WIN32_WCE + BOOL InsertMenuItem(UINT uItem, BOOL bByPosition, LPMENUITEMINFO lpmii) + { + ATLASSERT(::IsMenu(m_hMenu)); + return (BOOL)::InsertMenuItem(m_hMenu, uItem, bByPosition, lpmii); + } + + UINT GetMenuDefaultItem(BOOL bByPosition = FALSE, UINT uFlags = 0U) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuDefaultItem(m_hMenu, (UINT)bByPosition, uFlags); + } + + BOOL SetMenuDefaultItem(UINT uItem = (UINT)-1, BOOL bByPosition = FALSE) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::SetMenuDefaultItem(m_hMenu, uItem, (UINT)bByPosition); + } + + BOOL GetMenuItemRect(HWND hWnd, UINT uItem, LPRECT lprcItem) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuItemRect(hWnd, m_hMenu, uItem, lprcItem); + } + + int MenuItemFromPoint(HWND hWnd, POINT point) const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::MenuItemFromPoint(hWnd, m_hMenu, point); + } + +// Context Help Functions + BOOL SetMenuContextHelpId(DWORD dwContextHelpId) + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::SetMenuContextHelpId(m_hMenu, dwContextHelpId); + } + + DWORD GetMenuContextHelpId() const + { + ATLASSERT(::IsMenu(m_hMenu)); + return ::GetMenuContextHelpId(m_hMenu); + } +#endif // !_WIN32_WCE +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CAccelerator + +template +class CAcceleratorT +{ +public: + HACCEL m_hAccel; + +// Constructor/destructor/operators + CAcceleratorT(HACCEL hAccel = NULL) : m_hAccel(hAccel) + { } + + ~CAcceleratorT() + { + if(t_bManaged && m_hAccel != NULL) + ::DestroyAcceleratorTable(m_hAccel); + } + + CAcceleratorT& operator =(HACCEL hAccel) + { + Attach(hAccel); + return *this; + } + + void Attach(HACCEL hAccel) + { + if(t_bManaged && m_hAccel != NULL) + ::DestroyAcceleratorTable(m_hAccel); + m_hAccel = hAccel; + } + + HACCEL Detach() + { + HACCEL hAccel = m_hAccel; + m_hAccel = NULL; + return hAccel; + } + + operator HACCEL() const { return m_hAccel; } + + bool IsNull() const { return m_hAccel == NULL; } + +// Create/destroy methods + HACCEL LoadAccelerators(ATL::_U_STRINGorID accel) + { + ATLASSERT(m_hAccel == NULL); + m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), accel.m_lpstr); + return m_hAccel; + } + + HACCEL CreateAcceleratorTable(LPACCEL pAccel, int cEntries) + { + ATLASSERT(m_hAccel == NULL); + ATLASSERT(pAccel != NULL); + m_hAccel = ::CreateAcceleratorTable(pAccel, cEntries); + return m_hAccel; + } + + void DestroyObject() + { + if(m_hAccel != NULL) + { + ::DestroyAcceleratorTable(m_hAccel); + m_hAccel = NULL; + } + } + +// Operations +#ifndef _WIN32_WCE + int CopyAcceleratorTable(LPACCEL lpAccelDst, int cEntries) + { + ATLASSERT(m_hAccel != NULL); + ATLASSERT(lpAccelDst != NULL); + return ::CopyAcceleratorTable(m_hAccel, lpAccelDst, cEntries); + } + + int GetEntriesCount() const + { + ATLASSERT(m_hAccel != NULL); + return ::CopyAcceleratorTable(m_hAccel, NULL, 0); + } +#endif // !_WIN32_WCE + + BOOL TranslateAccelerator(HWND hWnd, LPMSG pMsg) + { + ATLASSERT(m_hAccel != NULL); + ATLASSERT(::IsWindow(hWnd)); + ATLASSERT(pMsg != NULL); + return ::TranslateAccelerator(hWnd, m_hAccel, pMsg); + } +}; + +typedef CAcceleratorT CAcceleratorHandle; +typedef CAcceleratorT CAccelerator; + + +/////////////////////////////////////////////////////////////////////////////// +// CIcon + +template +class CIconT +{ +public: + HICON m_hIcon; + +// Constructor/destructor/operators + CIconT(HICON hIcon = NULL) : m_hIcon(hIcon) + { } + + ~CIconT() + { + if(t_bManaged && m_hIcon != NULL) + ::DestroyIcon(m_hIcon); + } + + CIconT& operator =(HICON hIcon) + { + Attach(hIcon); + return *this; + } + + void Attach(HICON hIcon) + { + if(t_bManaged && m_hIcon != NULL) + ::DestroyIcon(m_hIcon); + m_hIcon = hIcon; + } + + HICON Detach() + { + HICON hIcon = m_hIcon; + m_hIcon = NULL; + return hIcon; + } + + operator HICON() const { return m_hIcon; } + + bool IsNull() const { return m_hIcon == NULL; } + +// Create/destroy methods + HICON LoadIcon(ATL::_U_STRINGorID icon) + { + ATLASSERT(m_hIcon == NULL); + m_hIcon = ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr); + return m_hIcon; + } + + HICON LoadIcon(ATL::_U_STRINGorID icon, int cxDesired, int cyDesired, UINT fuLoad = 0) + { + ATLASSERT(m_hIcon == NULL); + m_hIcon = (HICON) ::LoadImage(ModuleHelper::GetResourceInstance(), icon.m_lpstr, IMAGE_ICON, cxDesired, cyDesired, fuLoad); + return m_hIcon; + } + +#ifndef _WIN32_WCE + HICON LoadOEMIcon(LPCTSTR lpstrIconName) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(IsOEMIcon(lpstrIconName)); + m_hIcon = ::LoadIcon(NULL, lpstrIconName); + return m_hIcon; + } + + HICON CreateIcon(int nWidth, int nHeight, BYTE cPlanes, BYTE cBitsPixel, CONST BYTE* lpbANDbits, CONST BYTE *lpbXORbits) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(lpbANDbits != NULL); + ATLASSERT(lpbXORbits != NULL); + m_hIcon = ::CreateIcon(ModuleHelper::GetResourceInstance(), nWidth, nHeight, cPlanes, cBitsPixel, lpbANDbits, lpbXORbits); + return m_hIcon; + } + + HICON CreateIconFromResource(PBYTE pBits, DWORD dwResSize, DWORD dwVersion = 0x00030000) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(pBits != NULL); + m_hIcon = ::CreateIconFromResource(pBits, dwResSize, TRUE, dwVersion); + return m_hIcon; + } + + HICON CreateIconFromResourceEx(PBYTE pbBits, DWORD cbBits, DWORD dwVersion = 0x00030000, int cxDesired = 0, int cyDesired = 0, UINT uFlags = LR_DEFAULTCOLOR) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(pbBits != NULL); + ATLASSERT(cbBits > 0); + m_hIcon = ::CreateIconFromResourceEx(pbBits, cbBits, TRUE, dwVersion, cxDesired, cyDesired, uFlags); + return m_hIcon; + } +#endif // !_WIN32_WCE + + HICON CreateIconIndirect(PICONINFO pIconInfo) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(pIconInfo != NULL); + m_hIcon = ::CreateIconIndirect(pIconInfo); + return m_hIcon; + } + +#ifndef _WIN32_WCE + HICON ExtractIcon(LPCTSTR lpszExeFileName, UINT nIconIndex) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(lpszExeFileName != NULL); + m_hIcon = ::ExtractIcon(ModuleHelper::GetModuleInstance(), lpszExeFileName, nIconIndex); + return m_hIcon; + } + + HICON ExtractAssociatedIcon(HINSTANCE hInst, LPTSTR lpIconPath, LPWORD lpiIcon) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(lpIconPath != NULL); + ATLASSERT(lpiIcon != NULL); + m_hIcon = ::ExtractAssociatedIcon(hInst, lpIconPath, lpiIcon); + return m_hIcon; + } +#endif // !_WIN32_WCE + + BOOL DestroyIcon() + { + ATLASSERT(m_hIcon != NULL); + BOOL bRet = ::DestroyIcon(m_hIcon); + if(bRet != FALSE) + m_hIcon = NULL; + return bRet; + } + +// Operations +#ifndef _WIN32_WCE + HICON CopyIcon() + { + ATLASSERT(m_hIcon != NULL); + return ::CopyIcon(m_hIcon); + } + + HICON DuplicateIcon() + { + ATLASSERT(m_hIcon != NULL); + return ::DuplicateIcon(NULL, m_hIcon); + } +#endif // !_WIN32_WCE + + BOOL DrawIcon(HDC hDC, int x, int y) + { + ATLASSERT(m_hIcon != NULL); +#ifndef _WIN32_WCE + return ::DrawIcon(hDC, x, y, m_hIcon); +#else // CE specific + return ::DrawIconEx(hDC, x, y, m_hIcon, 0, 0, 0, NULL, DI_NORMAL); +#endif // _WIN32_WCE + } + + BOOL DrawIcon(HDC hDC, POINT pt) + { + ATLASSERT(m_hIcon != NULL); +#ifndef _WIN32_WCE + return ::DrawIcon(hDC, pt.x, pt.y, m_hIcon); +#else // CE specific + return ::DrawIconEx(hDC, pt.x, pt.y, m_hIcon, 0, 0, 0, NULL, DI_NORMAL); +#endif // _WIN32_WCE + } + + BOOL DrawIconEx(HDC hDC, int x, int y, int cxWidth, int cyWidth, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL) + { + ATLASSERT(m_hIcon != NULL); + return ::DrawIconEx(hDC, x, y, m_hIcon, cxWidth, cyWidth, uStepIfAniCur, hbrFlickerFreeDraw, uFlags); + } + + BOOL DrawIconEx(HDC hDC, POINT pt, SIZE size, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL) + { + ATLASSERT(m_hIcon != NULL); + return ::DrawIconEx(hDC, pt.x, pt.y, m_hIcon, size.cx, size.cy, uStepIfAniCur, hbrFlickerFreeDraw, uFlags); + } + +#ifndef _WIN32_WCE + BOOL GetIconInfo(PICONINFO pIconInfo) const + { + ATLASSERT(m_hIcon != NULL); + ATLASSERT(pIconInfo != NULL); + return ::GetIconInfo(m_hIcon, pIconInfo); + } + +#if (_WIN32_WINNT >= 0x0600) + BOOL GetIconInfoEx(PICONINFOEX pIconInfo) const + { + ATLASSERT(m_hIcon != NULL); + ATLASSERT(pIconInfo != NULL); + return ::GetIconInfoEx(m_hIcon, pIconInfo); + } +#endif // (_WIN32_WINNT >= 0x0600) + +#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) + HRESULT LoadIconMetric(ATL::_U_STRINGorID icon, int lims) + { + ATLASSERT(m_hIcon == NULL); + USES_CONVERSION; + return ::LoadIconMetric(ModuleHelper::GetResourceInstance(), T2CW(icon.m_lpstr), lims, &m_hIcon); + } + + HRESULT LoadIconWithScaleDown(ATL::_U_STRINGorID icon, int cx, int cy) + { + ATLASSERT(m_hIcon == NULL); + USES_CONVERSION; + return ::LoadIconWithScaleDown(ModuleHelper::GetResourceInstance(), T2CW(icon.m_lpstr), cx, cy, &m_hIcon); + } + + HRESULT LoadOEMIconMetric(LPCTSTR lpstrIconName, int lims) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(IsOEMIcon(lpstrIconName)); + return ::LoadIconMetric(NULL, (LPCWSTR)lpstrIconName, lims, &m_hIcon); + } + + HRESULT LoadOEMIconWithScaleDown(LPCTSTR lpstrIconName, int cx, int cy) + { + ATLASSERT(m_hIcon == NULL); + ATLASSERT(IsOEMIcon(lpstrIconName)); + USES_CONVERSION; + return ::LoadIconWithScaleDown(NULL, (LPCWSTR)lpstrIconName, cx, cy, &m_hIcon); + } +#endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) +#endif // !_WIN32_WCE + + // Helper +#ifndef _WIN32_WCE + static bool IsOEMIcon(LPCTSTR lpstrIconName) + { +#if (WINVER >= 0x0600) + return (lpstrIconName == IDI_APPLICATION || lpstrIconName == IDI_ASTERISK || lpstrIconName == IDI_EXCLAMATION || + lpstrIconName == IDI_HAND || lpstrIconName == IDI_QUESTION || lpstrIconName == IDI_WINLOGO || + lpstrIconName == IDI_SHIELD); +#else // !(WINVER >= 0x0600) + return (lpstrIconName == IDI_APPLICATION || lpstrIconName == IDI_ASTERISK || lpstrIconName == IDI_EXCLAMATION || + lpstrIconName == IDI_HAND || lpstrIconName == IDI_QUESTION || lpstrIconName == IDI_WINLOGO); +#endif // !(WINVER >= 0x0600) + } +#endif // !_WIN32_WCE +}; + +typedef CIconT CIconHandle; +typedef CIconT CIcon; + + +/////////////////////////////////////////////////////////////////////////////// +// CCursor + +// protect template member from a winuser.h macro +#ifdef CopyCursor + #undef CopyCursor +#endif + +template +class CCursorT +{ +public: + HCURSOR m_hCursor; + +// Constructor/destructor/operators + CCursorT(HCURSOR hCursor = NULL) : m_hCursor(hCursor) + { } + + ~CCursorT() + { + if(t_bManaged && m_hCursor != NULL) + DestroyCursor(); + } + + CCursorT& operator =(HCURSOR hCursor) + { + Attach(hCursor); + return *this; + } + + void Attach(HCURSOR hCursor) + { + if(t_bManaged && m_hCursor != NULL) + DestroyCursor(); + m_hCursor = hCursor; + } + + HCURSOR Detach() + { + HCURSOR hCursor = m_hCursor; + m_hCursor = NULL; + return hCursor; + } + + operator HCURSOR() const { return m_hCursor; } + + bool IsNull() const { return m_hCursor == NULL; } + +// Create/destroy methods + HCURSOR LoadCursor(ATL::_U_STRINGorID cursor) + { + ATLASSERT(m_hCursor == NULL); + m_hCursor = ::LoadCursor(ModuleHelper::GetResourceInstance(), cursor.m_lpstr); + return m_hCursor; + } + + HCURSOR LoadSysCursor(LPCTSTR lpstrCursorName) + { + ATLASSERT(m_hCursor == NULL); +#if (WINVER >= 0x0500) + ATLASSERT(lpstrCursorName == IDC_ARROW || lpstrCursorName == IDC_IBEAM || lpstrCursorName == IDC_WAIT || + lpstrCursorName == IDC_CROSS || lpstrCursorName == IDC_UPARROW || lpstrCursorName == IDC_SIZE || + lpstrCursorName == IDC_ICON || lpstrCursorName == IDC_SIZENWSE || lpstrCursorName == IDC_SIZENESW || + lpstrCursorName == IDC_SIZEWE || lpstrCursorName == IDC_SIZENS || lpstrCursorName == IDC_SIZEALL || + lpstrCursorName == IDC_NO || lpstrCursorName == IDC_APPSTARTING || lpstrCursorName == IDC_HELP || + lpstrCursorName == IDC_HAND); +#else // !(WINVER >= 0x0500) + ATLASSERT(lpstrCursorName == IDC_ARROW || lpstrCursorName == IDC_IBEAM || lpstrCursorName == IDC_WAIT || + lpstrCursorName == IDC_CROSS || lpstrCursorName == IDC_UPARROW || lpstrCursorName == IDC_SIZE || + lpstrCursorName == IDC_ICON || lpstrCursorName == IDC_SIZENWSE || lpstrCursorName == IDC_SIZENESW || + lpstrCursorName == IDC_SIZEWE || lpstrCursorName == IDC_SIZENS || lpstrCursorName == IDC_SIZEALL || + lpstrCursorName == IDC_NO || lpstrCursorName == IDC_APPSTARTING || lpstrCursorName == IDC_HELP); +#endif // !(WINVER >= 0x0500) + m_hCursor = ::LoadCursor(NULL, lpstrCursorName); + return m_hCursor; + } + + // deprecated + HCURSOR LoadOEMCursor(LPCTSTR lpstrCursorName) + { + return LoadSysCursor(lpstrCursorName); + } + + HCURSOR LoadCursor(ATL::_U_STRINGorID cursor, int cxDesired, int cyDesired, UINT fuLoad = 0) + { + ATLASSERT(m_hCursor == NULL); + m_hCursor = (HCURSOR) ::LoadImage(ModuleHelper::GetResourceInstance(), cursor.m_lpstr, IMAGE_CURSOR, cxDesired, cyDesired, fuLoad); + return m_hCursor; + } + +#ifndef _WIN32_WCE + HCURSOR LoadCursorFromFile(LPCTSTR pstrFilename) + { + ATLASSERT(m_hCursor == NULL); + ATLASSERT(pstrFilename != NULL); + m_hCursor = ::LoadCursorFromFile(pstrFilename); + return m_hCursor; + } +#endif // !_WIN32_WCE + +#if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))) + HCURSOR CreateCursor(int xHotSpot, int yHotSpot, int nWidth, int nHeight, CONST VOID *pvANDPlane, CONST VOID *pvXORPlane) + { + ATLASSERT(m_hCursor == NULL); + m_hCursor = ::CreateCursor(ModuleHelper::GetResourceInstance(), xHotSpot, yHotSpot, nWidth, nHeight, pvANDPlane, pvXORPlane); + return m_hCursor; + } +#endif // !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))) + +#ifndef _WIN32_WCE + HCURSOR CreateCursorFromResource(PBYTE pBits, DWORD dwResSize, DWORD dwVersion = 0x00030000) + { + ATLASSERT(m_hCursor == NULL); + ATLASSERT(pBits != NULL); + m_hCursor = (HCURSOR)::CreateIconFromResource(pBits, dwResSize, FALSE, dwVersion); + return m_hCursor; + } + + HCURSOR CreateCursorFromResourceEx(PBYTE pbBits, DWORD cbBits, DWORD dwVersion = 0x00030000, int cxDesired = 0, int cyDesired = 0, UINT uFlags = LR_DEFAULTCOLOR) + { + ATLASSERT(m_hCursor == NULL); + ATLASSERT(pbBits != NULL); + ATLASSERT(cbBits > 0); + m_hCursor = (HCURSOR)::CreateIconFromResourceEx(pbBits, cbBits, FALSE, dwVersion, cxDesired, cyDesired, uFlags); + return m_hCursor; + } +#endif // !_WIN32_WCE + + BOOL DestroyCursor() + { + ATLASSERT(m_hCursor != NULL); +#if !defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP))) + BOOL bRet = ::DestroyCursor(m_hCursor); + if(bRet != FALSE) + m_hCursor = NULL; + return bRet; +#else // !(!defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)))) + ATLTRACE2(atlTraceUI, 0, _T("Warning: This version of Windows CE does not have ::DestroyCursor()\n")); + return FALSE; +#endif // !(!defined(_WIN32_WCE) || ((_WIN32_WCE >= 0x400) && !(defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)))) + } + +// Operations +#ifndef _WIN32_WCE + HCURSOR CopyCursor() + { + ATLASSERT(m_hCursor != NULL); + return (HCURSOR)::CopyIcon((HICON)m_hCursor); + } +#endif // !_WIN32_WCE + +#if (WINVER >= 0x0500) && !defined(_WIN32_WCE) + BOOL GetCursorInfo(LPCURSORINFO pCursorInfo) + { + ATLASSERT(m_hCursor != NULL); + ATLASSERT(pCursorInfo != NULL); + return ::GetCursorInfo(pCursorInfo); + } +#endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) +}; + +typedef CCursorT CCursorHandle; +typedef CCursorT CCursor; + + +/////////////////////////////////////////////////////////////////////////////// +// CResource - Wraps a generic Windows resource. +// Use it with custom resource types other than the +// standard RT_CURSOR, RT_BITMAP, etc. + +class CResource +{ +public: + HGLOBAL m_hGlobal; + HRSRC m_hResource; + +// Constructor/destructor + CResource() : m_hGlobal(NULL), m_hResource(NULL) + { } + + ~CResource() + { + Release(); + } + +// Load methods + bool Load(ATL::_U_STRINGorID Type, ATL::_U_STRINGorID ID) + { + ATLASSERT(m_hResource == NULL); + ATLASSERT(m_hGlobal == NULL); + + m_hResource = ::FindResource(ModuleHelper::GetResourceInstance(), ID.m_lpstr, Type.m_lpstr); + if(m_hResource == NULL) + return false; + + m_hGlobal = ::LoadResource(ModuleHelper::GetResourceInstance(), m_hResource); + if(m_hGlobal == NULL) + { + m_hResource = NULL; + return false; + } + + return true; + } + +#ifndef _WIN32_WCE + bool LoadEx(ATL::_U_STRINGorID Type, ATL::_U_STRINGorID ID, WORD wLanguage) + { + ATLASSERT(m_hResource == NULL); + ATLASSERT(m_hGlobal == NULL); + + m_hResource = ::FindResourceEx(ModuleHelper::GetResourceInstance(), ID.m_lpstr, Type.m_lpstr, wLanguage); + if(m_hResource == NULL) + return false; + + m_hGlobal = ::LoadResource(ModuleHelper::GetResourceInstance(), m_hResource); + if(m_hGlobal == NULL) + { + m_hResource = NULL; + return false; + } + + return true; + } +#endif // !_WIN32_WCE + +// Misc. operations + DWORD GetSize() const + { + ATLASSERT(m_hResource != NULL); + return ::SizeofResource(ModuleHelper::GetResourceInstance(), m_hResource); + } + + LPVOID Lock() + { + ATLASSERT(m_hResource != NULL); + ATLASSERT(m_hGlobal != NULL); + LPVOID pVoid = ::LockResource(m_hGlobal); + ATLASSERT(pVoid != NULL); + return pVoid; + } + + void Release() + { + if(m_hGlobal != NULL) + { + FreeResource(m_hGlobal); + m_hGlobal = NULL; + m_hResource = NULL; + } + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// Toolbar resource descriptor + +struct _AtlToolBarData +{ + WORD wVersion; + WORD wWidth; + WORD wHeight; + WORD wItemCount; + + WORD* items() + { return (WORD*)(this+1); } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// Global functions for loading resources + +inline HACCEL AtlLoadAccelerators(ATL::_U_STRINGorID table) +{ + return ::LoadAccelerators(ModuleHelper::GetResourceInstance(), table.m_lpstr); +} + +inline HMENU AtlLoadMenu(ATL::_U_STRINGorID menu) +{ + return ::LoadMenu(ModuleHelper::GetResourceInstance(), menu.m_lpstr); +} + +inline HBITMAP AtlLoadBitmap(ATL::_U_STRINGorID bitmap) +{ + return ::LoadBitmap(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr); +} + +#ifdef OEMRESOURCE +inline HBITMAP AtlLoadSysBitmap(ATL::_U_STRINGorID bitmap) +{ +#ifdef _DEBUG + WORD wID = (WORD)bitmap.m_lpstr; + ATLASSERT(wID >= 32734 && wID <= 32767); +#endif // _DEBUG + return ::LoadBitmap(NULL, bitmap.m_lpstr); +} +#endif // OEMRESOURCE + +inline HCURSOR AtlLoadCursor(ATL::_U_STRINGorID cursor) +{ + return ::LoadCursor(ModuleHelper::GetResourceInstance(), cursor.m_lpstr); +} + +inline HCURSOR AtlLoadSysCursor(LPCTSTR lpCursorName) +{ +#if (WINVER >= 0x0500) + ATLASSERT(lpCursorName == IDC_ARROW || lpCursorName == IDC_IBEAM || lpCursorName == IDC_WAIT || + lpCursorName == IDC_CROSS || lpCursorName == IDC_UPARROW || lpCursorName == IDC_SIZE || + lpCursorName == IDC_ICON || lpCursorName == IDC_SIZENWSE || lpCursorName == IDC_SIZENESW || + lpCursorName == IDC_SIZEWE || lpCursorName == IDC_SIZENS || lpCursorName == IDC_SIZEALL || + lpCursorName == IDC_NO || lpCursorName == IDC_APPSTARTING || lpCursorName == IDC_HELP || + lpCursorName == IDC_HAND); +#else // !(WINVER >= 0x0500) + ATLASSERT(lpCursorName == IDC_ARROW || lpCursorName == IDC_IBEAM || lpCursorName == IDC_WAIT || + lpCursorName == IDC_CROSS || lpCursorName == IDC_UPARROW || lpCursorName == IDC_SIZE || + lpCursorName == IDC_ICON || lpCursorName == IDC_SIZENWSE || lpCursorName == IDC_SIZENESW || + lpCursorName == IDC_SIZEWE || lpCursorName == IDC_SIZENS || lpCursorName == IDC_SIZEALL || + lpCursorName == IDC_NO || lpCursorName == IDC_APPSTARTING || lpCursorName == IDC_HELP); +#endif // !(WINVER >= 0x0500) + return ::LoadCursor(NULL, lpCursorName); +} + +inline HICON AtlLoadIcon(ATL::_U_STRINGorID icon) +{ + return ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr); +} + +#ifndef _WIN32_WCE +inline HICON AtlLoadSysIcon(LPCTSTR lpIconName) +{ +#if (WINVER >= 0x0600) + ATLASSERT(lpIconName == IDI_APPLICATION || lpIconName == IDI_ASTERISK || lpIconName == IDI_EXCLAMATION || + lpIconName == IDI_HAND || lpIconName == IDI_QUESTION || lpIconName == IDI_WINLOGO || + lpIconName == IDI_SHIELD); +#else // !(WINVER >= 0x0600) + ATLASSERT(lpIconName == IDI_APPLICATION || lpIconName == IDI_ASTERISK || lpIconName == IDI_EXCLAMATION || + lpIconName == IDI_HAND || lpIconName == IDI_QUESTION || lpIconName == IDI_WINLOGO); +#endif // !(WINVER >= 0x0600) + return ::LoadIcon(NULL, lpIconName); +} +#endif // !_WIN32_WCE + +inline HBITMAP AtlLoadBitmapImage(ATL::_U_STRINGorID bitmap, UINT fuLoad = LR_DEFAULTCOLOR) +{ + return (HBITMAP)::LoadImage(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr, IMAGE_BITMAP, 0, 0, fuLoad); +} + +inline HCURSOR AtlLoadCursorImage(ATL::_U_STRINGorID cursor, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0) +{ + return (HCURSOR)::LoadImage(ModuleHelper::GetResourceInstance(), cursor.m_lpstr, IMAGE_CURSOR, cxDesired, cyDesired, fuLoad); +} + +inline HICON AtlLoadIconImage(ATL::_U_STRINGorID icon, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0) +{ + return (HICON)::LoadImage(ModuleHelper::GetResourceInstance(), icon.m_lpstr, IMAGE_ICON, cxDesired, cyDesired, fuLoad); +} + +#ifdef OEMRESOURCE +inline HBITMAP AtlLoadSysBitmapImage(WORD wBitmapID, UINT fuLoad = LR_DEFAULTCOLOR) +{ + ATLASSERT(wBitmapID >= 32734 && wBitmapID <= 32767); + ATLASSERT((fuLoad & LR_LOADFROMFILE) == 0); // this one doesn't load from a file + return (HBITMAP)::LoadImage(NULL, MAKEINTRESOURCE(wBitmapID), IMAGE_BITMAP, 0, 0, fuLoad); +} +#endif // OEMRESOURCE + +inline HCURSOR AtlLoadSysCursorImage(ATL::_U_STRINGorID cursor, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0) +{ +#ifdef _DEBUG + WORD wID = (WORD)cursor.m_lpstr; + ATLASSERT((wID >= 32512 && wID <= 32516) || (wID >= 32640 && wID <= 32648) || (wID == 32650) || (wID == 32651)); + ATLASSERT((fuLoad & LR_LOADFROMFILE) == 0); // this one doesn't load from a file +#endif // _DEBUG + return (HCURSOR)::LoadImage(NULL, cursor.m_lpstr, IMAGE_CURSOR, cxDesired, cyDesired, fuLoad); +} + +inline HICON AtlLoadSysIconImage(ATL::_U_STRINGorID icon, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0) +{ +#ifdef _DEBUG + WORD wID = (WORD)icon.m_lpstr; + ATLASSERT(wID >= 32512 && wID <= 32517); + ATLASSERT((fuLoad & LR_LOADFROMFILE) == 0); // this one doesn't load from a file +#endif // _DEBUG + return (HICON)::LoadImage(NULL, icon.m_lpstr, IMAGE_ICON, cxDesired, cyDesired, fuLoad); +} + +#if (_ATL_VER < 0x0700) +inline int AtlLoadString(UINT uID, LPTSTR lpBuffer, int nBufferMax) +{ + return ::LoadString(ModuleHelper::GetResourceInstance(), uID, lpBuffer, nBufferMax); +} +#else + +using ATL::AtlLoadString; + +#endif // (_ATL_VER < 0x0700) + +#ifdef _WIN32_WCE // CE only direct access to the resource +inline LPCTSTR AtlLoadString(UINT uID) +{ + LPCTSTR s = (LPCTSTR)::LoadString(ModuleHelper::GetResourceInstance(), uID, NULL, 0); +#ifdef DEBUG // Check for null-termination + if(s != NULL) + // Note: RC -n compiles null-terminated resource strings + ATLASSERT(s[*((WORD*)s -1) - 1] == L'\0'); +#endif + return s; +} +#endif // _WIN32_WCE + +inline bool AtlLoadString(UINT uID, BSTR& bstrText) +{ + USES_CONVERSION; + ATLASSERT(bstrText == NULL); + + LPTSTR lpstrText = NULL; + int nRes = 0; + for(int nLen = 256; ; nLen *= 2) + { + ATLTRY(lpstrText = new TCHAR[nLen]); + if(lpstrText == NULL) + break; + nRes = ::LoadString(ModuleHelper::GetResourceInstance(), uID, lpstrText, nLen); + if(nRes < nLen - 1) + break; + delete [] lpstrText; + lpstrText = NULL; + } + + if(lpstrText != NULL) + { + if(nRes != 0) + bstrText = ::SysAllocString(T2OLE(lpstrText)); + delete [] lpstrText; + } + + return (bstrText != NULL) ? true : false; +} + +}; // namespace WTL + +#endif // __ATLUSER_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlwince.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlwince.h new file mode 100644 index 0000000000..a845949217 --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlwince.h @@ -0,0 +1,2987 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLWINCE_H__ +#define __ATLWINCE_H__ + +#pragma once + +#ifndef __ATLAPP_H__ + #error atlwince.h requires atlapp.h to be included first +#endif + +#ifndef __ATLWIN_H__ + #error atlwince.h requires atlwin.h to be included first +#endif + +#ifndef _WIN32_WCE + #error atlwince.h compiles under Windows CE only +#endif + +#if (_WIN32_WCE < 300) + #error atlwince.h requires Windows CE 3.0 or higher. +#endif + +#if defined(WIN32_PLATFORM_WFSP) && _MSC_VER < 1400 // EVC compiling SmartPhone code + #if (WIN32_PLATFORM_WFSP < 200) + #error atlwince.h requires Smartphone 2003 or higher + #endif +#endif // WIN32_PLATFORM_WFSP + +#if defined(WIN32_PLATFORM_PSPC) && _MSC_VER < 1400 // EVC compiling Pocket PC code + #if (WIN32_PLATFORM_PSPC < 310) + #error atlwince.h requires Pocket PC 2002 or higher + #endif +#endif // WIN32_PLATFORM_PSPC + +#if !defined(_AYGSHELL_H_) && !defined(__AYGSHELL_H__) + #error atlwince.h requires aygshell.h to be included first +#else + #if defined(WIN32_PLATFORM_WFSP) && !defined(_TPCSHELL_H_) + #error SmartPhone dialog classes require tpcshell.h to be included first + #endif +#endif + +#if (_MSC_VER >= 1400) // VS2005 + #include + #define _WTL_CE_DRA +#endif // (_MSC_VER >= 1400) + +#if !defined(_WTL_CE_NO_DIALOGS) && !defined(__ATLFRAME_H__) + #error Orientation aware dialog classes require atlframe.h to be included first +#endif + +#if !defined(_WTL_CE_NO_APPWINDOW) && !defined(__ATLFRAME_H__) + #error Application window class require atlframe.h to be included first +#endif + +#if !defined(_WTL_CE_NO_ZOOMSCROLL) && !defined(__ATLSCRL_H__) + #error ZoomScroll implementation requires atlscrl.h to be included first +#endif + +#if !defined(_WTL_CE_NO_ZOOMSCROLL) + #if !(defined(__ATLTYPES_H__) || (defined(__ATLMISC_H__) && !defined(_WTL_NO_WTYPES))) + #error ZoomScroll requires _WTL_NO_WTYPES not to be defined and either atlmisc.h or atltypes.h to be included first + #endif // !(defined(__ATLTYPES_H__) || (defined(__ATLMISC_H__) && !defined(_WTL_NO_WTYPES))) +#endif // !defined(_WTL_CE_NO_ZOOMSCROLL) + +#if !defined(WIN32_PLATFORM_WFSP) && !defined(WIN32_PLATFORM_PSPC) + #define _WTL_CE_NO_CONTROLS +#endif // !defined(WIN32_PLATFORM_WFSP) && !defined(WIN32_PLATFORM_PSPC) + +#ifndef _WTL_CE_NO_CONTROLS + #ifndef __ATLCTRLS_H__ + #error The PPC/SmartPhone controls classes require atlctrls.h to be included first + #endif + + #include + #pragma comment(lib, "htmlview.lib") + + #include + #pragma comment(lib, "voicectl.lib") + + #ifdef WIN32_PLATFORM_PSPC + #include + #pragma comment(lib, "richink.lib") + + #include + #pragma comment(lib, "inkx.lib") + + #include + #pragma comment(lib, "doclist.lib") + #endif +#endif + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// CStdDialogBase : Standard PPC/SmartPhone dialog base class +// CStdDialogImplBase - Base implementation of standard dialog +// CStdDialogImpl : Standard dialog implementation +// CStdIndirectDialogImpl - implementation of standard indirect PPC/SmartPhone dialog +// CStdAxDialogImpl : Standard AxDialog implementation +// CStdSimpleDialog : Standard simple dialog +// CStdDialogResizeImplBase - Base implementation of orientation resizing standard dialog +// CStdDialogResizeImpl : Orientation resizing standard dialog implementation +// CStdAxDialogResizeImpl - implementation of orientation resizing standard AxDialog +// CStdSimpleDialogResizeImpl : Standard resizing simple dialog implementation +// CStdOrientedDialogBase - Oriented PPC standard dialog base class +// CStdOrientedDialogImplBase - Oriented PPC standard dialog base implementation +// CStdOrientedDialogImpl : Oriented PPC standard dialog implementation +// CStdAxOrientedDialogImpl - Oriented PPC standard AxDialog implementation +// CStdSimpleOrientedDialog : Standard simple orientable dialog +// +// CAppInfoBase : Helper for application state save/restore to registry +// CAppInfoT : CAppInfoBase constructed from a CAppWindow +// CAppWindowBase : Base class for PPC/SmartPhone well-behaved application window or dialog +// CAppWindow : PPC/SmartPhone well-behaved application window class +// CAppDialog : PPC/SmartPhone well-behaved application dialog class +// CAppStdDialogImplBase - Base implementation of standard application dialogs +// CAppStdDialogImpl : Implementation of standard application dialog +// CAppStdDialogResizeImpl - implementation of orientation resizing standard application dialog +// CAppStdAxDialogImpl - Implementation of standard application AxDialog +// CAppStdAxDialogResizeImpl - implementation of orientation resizing standard application AxDialog +// CAppStdOrientedDialogImpl - implementation of oriented PPC standard application dialog +// CAppStdAxOrientedDialogImpl - implementation of oriented PPC standard application AxDialog +// +// CFullScreenFrame : Full screen frame class +// +// CZoomScrollImpl : WinCE zooming implementation +// +// CBottomTabViewImpl - CBottomTabView +// CHtmlCtrlT - CHtmlCtrl +// CRichInkCtrlT - CRichInkCtrl +// CInkXCtrlT - CInkXCtrl +// CVoiceRecorderCtrlT - CVoiceRecorderCtrl +// CDocListCtrlT - CDocListCtrl +// CCapEditT - CCapEdit +// CTTStaticT - CTTStatic +// CTTButtonT - CTTButton +// +// CSpinCtrlT - CSpinCtrl : SmartPhone specific UpDown control +// CSpinned : SmartPhone association of control and Spin +// CSpinListBox : SmartPhone spinned ListBox control +// CExpandListBox : SmartPhone expandable ListBox control +// CExpandEdit : SmartPhone expandable Edit control +// CExpandCapEdit : SmartPhone expandable CapEdit control +// +// Global functions: +// AtlCreateMenuBar() +// AtlCreateEmptyMenuBar() +// AtlIsEditFocus() +// AtlActivateBackKey() + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// MenuBar creation functions for property sheets and dialogs +// Frame windows use CreateSimpleCEMenuBar + +inline HWND AtlCreateMenuBar(SHMENUBARINFO& mbi) +{ + ATLASSERT(::IsWindow(mbi.hwndParent)); + ATLVERIFY(::SHCreateMenuBar(&mbi) != FALSE); + return mbi.hwndMB; +}; + +inline HWND AtlCreateMenuBar(HWND hWnd, UINT nToolBarId = ATL_IDW_TOOLBAR, DWORD dwFlags = 0, int nBmpId = 0, int cBmpImages = 0, COLORREF clrBk = 0) +{ + SHMENUBARINFO mbi = { sizeof(mbi), hWnd, dwFlags, nToolBarId, ModuleHelper::GetResourceInstance(), nBmpId, cBmpImages, 0, clrBk }; + return AtlCreateMenuBar(mbi); +} + +inline HWND AtlCreateEmptyMenuBar(HWND hWnd, bool bSip = true) +{ + SHMENUBARINFO embi = { sizeof(SHMENUBARINFO), hWnd, SHCMBF_EMPTYBAR }; + if (!bSip) + embi.dwFlags |= SHCMBF_HIDESIPBUTTON; + + return AtlCreateMenuBar(embi); +} + +/////////////////////////////////////////////////////////////////////////////// +// Helper functions for SmartPhone back key handling + +inline bool AtlIsEditFocus() +{ + ATL::CWindow wCtrl = GetFocus(); + if (wCtrl.IsWindow()) + { + TCHAR szClassName[8] = {0}; + ATLVERIFY(::GetClassName(wCtrl.m_hWnd, szClassName, 8)); + return !_tcscmp(szClassName, _T("Edit")) || !_tcscmp(szClassName, WC_CAPEDIT); + } + return false; +} + +#if defined WIN32_PLATFORM_WFSP +inline void AtlActivateBackKey(HWND hMenuBar) +{ + ATLASSERT(::IsWindow(hMenuBar)); + ::SendMessage(hMenuBar, SHCMBM_OVERRIDEKEY, VK_TBACK, + MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY, SHMBOF_NODEFAULT | SHMBOF_NOTIFY)); +} +#endif // WIN32_PLATFORM_WFSP + +// --- Standard PPC/SmartPhone dialogs --- + +#ifndef _WTL_CE_NO_DIALOGS + +/////////////////////////////////////////////////////////////////////////////// +// CStdDialogBase - base class for standard PPC/SmartPhone dialogs + +#define WTL_STD_SHIDIF SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN +#define WTL_SP_SHIDIF SHIDIF_SIZEDLGFULLSCREEN + +// Title setting macros +#define WTL_DLG_TITLEHEIGHT(iHeight) static const int GetTitleHeight(){return iHeight;} +#define WTL_DLG_NOTITLE WTL_DLG_TITLEHEIGHT(0) + +/////////////////////////////////////////////////////////////////////////////// +// CStdDialogBase - Base class for standard PPC/SmartPhone dialog + +template +class CStdDialogBase +{ +public: +#ifdef WIN32_PLATFORM_PSPC +// Pocket PC only Dialog title handling + const int nTitleHeight; + + CStdDialogBase() : nTitleHeight(T::GetTitleHeight()) + { } + +// Overloads + BOOL GetClientRect(LPRECT lpRect) + { + T* pT = static_cast(this); + ATLASSERT(pT->IsWindow()); + BOOL bRes = ::GetClientRect(pT->m_hWnd, lpRect); + if (nTitleHeight) + lpRect->top += nTitleHeight + 1; + return bRes; + } + + BOOL SetWindowText(LPCTSTR lpszString) + { + T* pT = static_cast(this); + ATLASSERT(pT->IsWindow()); + BOOL bRes = ::SetWindowText(pT->m_hWnd, lpszString); + if (nTitleHeight != 0) + pT->DoPaintTitle(); + return bRes; + } + +// Overrideables + static const int GetTitleHeight() + { + #ifdef _WTL_CE_DRA + return DRA::SCALEY(24); + #else // !_WTL_CE_DRA + CWindowDC dc(NULL); + return dc.GetDeviceCaps(LOGPIXELSY) >> 2; // LOGPIXELSY * 24 / 96, + #endif // !_WTL_CE_DRA + } + + // Title painting + bool DoPaintTitle() + { + T* pT = static_cast(this); + ATLASSERT(pT->IsWindow()); + TCHAR sTitle[48]; + + // Preparation + CPaintDC dc(pT->m_hWnd); + CFont fontTitle = AtlCreateBoldFont(); + CFontHandle fontOld = dc.SelectFont(fontTitle); + dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHT)); + int nLen = pT->GetWindowText(sTitle, 48); + int nWidth = dc.GetDeviceCaps(HORZRES); + + // Display title text + RECT rTitle = { 0, 0, nWidth, nTitleHeight }; + dc.FillRect(&rTitle, COLOR_3DHIGHLIGHT); + #ifdef _WTL_CE_DRA + rTitle.left = DRA::SCALEX(8); + #else // !_WTL_CE_DRA + rTitle.left = nTitleHeight / 3; // 8 == 24 / 3 + #endif // !_WTL_CE_DRA + dc.DrawText(sTitle, nLen, &rTitle, DT_VCENTER | DT_SINGLELINE); + dc.SelectFont(fontOld); + + // Draw bottom line, 2 pixels thick if HI_RES_AWARE + CPenHandle penOld = dc.SelectStockPen(BLACK_PEN); + POINT line[4] = {{0, nTitleHeight}, {nWidth, nTitleHeight}, {0, nTitleHeight - 1}, {nWidth, nTitleHeight - 1}}; + + #ifdef _WTL_CE_DRA + int nSeg = DRA::SCALEY(1); + #else // !_WTL_CE_DRA + int nSeg = nTitleHeight / 24; + #endif // !_WTL_CE_DRA + + dc.Polyline(line, nSeg <= 2 ? nSeg * 2 : 4); + dc.SelectPen(penOld); + + return false; + } + + // Title preparation: move the dialog controls down to make room for title + void DialogTitleInit() + { + T* pT = static_cast(this); + ATLASSERT(pT->IsWindow()); + + ATL::CWindow wCtl = pT->GetWindow(GW_CHILD); + while (wCtl.IsWindow()) + { + RECT rCtl = { 0 }; + wCtl.GetWindowRect(&rCtl); + ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rCtl, 2); + ::OffsetRect(&rCtl, 0, nTitleHeight); + wCtl.MoveWindow(&rCtl, FALSE); + wCtl = wCtl.GetWindow(GW_HWNDNEXT); + } + } + + // SIP management + void DoSipInfo() + { + T* pT = static_cast(this); + ATLASSERT(pT->IsWindow()); + + SIPINFO si = {sizeof(SIPINFO)}; + SipGetInfo(&si); + if ((si.fdwFlags & SIPF_ON) ^ SIPF_ON) + si.rcVisibleDesktop.bottom = si.rcSipRect.bottom; + pT->MoveWindow(&si.rcVisibleDesktop, FALSE); + } + +// Title painting handler + LRESULT OnPaintTitle(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + T* pT = static_cast(this); + return bHandled = nTitleHeight ? pT->DoPaintTitle() : FALSE; + } + +// SIP handler + LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + T* pT = static_cast(this); + if (wParam == SPI_SETSIPINFO) + { + pT->DoSipInfo(); + return TRUE; + } + return bHandled = FALSE; + } + +#elif defined WIN32_PLATFORM_WFSP +// SmartPhone VK_TBACK key standard management + LRESULT OnHotKey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + const UINT uModif = (UINT)LOWORD(lParam); + const UINT uVirtKey = (UINT)HIWORD(lParam); + + if(uVirtKey == VK_TBACK) + if (AtlIsEditFocus()) + ::SHSendBackToFocusWindow(uMsg, wParam, lParam); + else if (uModif & MOD_KEYUP) + pT->StdCloseDialog(IDCANCEL); + return 1; + } + + // SmartPhone MenuBar and VK_TBACK key initialization + void StdSPInit() + { + T* pT = static_cast(this); + HWND hMenuBar = ::SHFindMenuBar(pT->m_hWnd); + + if (!hMenuBar && (t_shidiFlags & SHIDIF_DONEBUTTON)) + hMenuBar = CreateMenuBar(ATL_IDM_MENU_DONE); + + if(hMenuBar != NULL) + AtlActivateBackKey(hMenuBar); + } + + void SetStaticBold() + { + T* pT = static_cast(this); + ATLASSERT(pT->IsWindow()); + + CFontHandle fontBold = AtlCreateBoldFont(pT->GetFont()); + + ATL::CWindow wCtl = pT->GetWindow(GW_CHILD); + + while (wCtl.IsWindow()) + { + if ((short int)wCtl.GetDlgCtrlID() == IDC_STATIC) + wCtl.SetFont(fontBold); + wCtl = wCtl.GetWindow(GW_HWNDNEXT); + } + } +#endif // WIN32_PLATFORM_WFSP + +// Platform dependant initialization + void StdPlatformInit() + { + T* pT = static_cast(this); +#ifdef WIN32_PLATFORM_PSPC // Pocket PC title initialization + if (nTitleHeight != 0) + pT->DialogTitleInit(); +#elif defined(WIN32_PLATFORM_WFSP) + pT->StdSPInit(); + SetStaticBold(); +#endif // WIN32_PLATFORM_WFSP + } + + // Menu bar creation + HWND CreateMenuBar(UINT uiMB = T::IDD, int nBmpImages = 0) + { + T* pT = static_cast(this); + return AtlCreateMenuBar(pT->m_hWnd, uiMB, 0, nBmpImages ? uiMB : 0, nBmpImages); + } + + // Dialog closing + void StdCloseDialog(WORD wID) + { + T* pT = static_cast(this); + if (t_bModal) + ::EndDialog(pT->m_hWnd, wID); + else + pT->DestroyWindow(); + } + + // Shell dialog layout initialization + void StdShidInit() + { + T* pT = static_cast(this); + SHINITDLGINFO shidi = { SHIDIM_FLAGS, pT->m_hWnd, t_shidiFlags }; + ::SHInitDialog(&shidi); + } + +// IDC_INFOSTATIC background setting + LRESULT OnColorStatic(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + if (::GetDlgCtrlID((HWND)lParam) == IDC_INFOSTATIC) + { + ::SetBkMode((HDC)wParam, TRANSPARENT); + return (LRESULT)::GetSysColorBrush(COLOR_INFOBK); + } + return bHandled = FALSE; + } + +// Menu dialog ending + LRESULT OnMenuClose(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->StdCloseDialog((WORD)(wID - ID_MENU_OK + IDOK)); + return 0; + } + +// Standard dialog ending: may be used with any command + LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->StdCloseDialog(wID); + return 0; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CStdDialogImplBase - Base implementation of standard PPC/SmartPhone dialog + +template > +class ATL_NO_VTABLE CStdDialogImplBase : + public TBase, + public CStdDialogBase +{ +public: +#ifdef WIN32_PLATFORM_PSPC + BOOL GetClientRect(LPRECT lpRect) + { + return CStdDialogBase::GetClientRect(lpRect); + } + + BOOL SetWindowText(LPCTSTR lpszString) + { + return CStdDialogBase::SetWindowText(lpszString); + } +#endif + + BEGIN_MSG_MAP(CStdDialogImplBase) +#ifdef WIN32_PLATFORM_PSPC // Pocket PC title and SIP + MESSAGE_HANDLER(WM_PAINT, OnPaintTitle) + MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) +#elif defined(WIN32_PLATFORM_WFSP) // SmartPhone VK_TBACK key + MESSAGE_HANDLER(WM_HOTKEY, OnHotKey) +#endif + MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, OnCloseCmd) + COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose) + END_MSG_MAP() + + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { +#ifdef _DEBUG + T* pT = static_cast(this); + ATLASSERT(t_bModal == pT->m_bModal); +#endif + StdPlatformInit(); + StdShidInit(); + return bHandled = FALSE; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// CStdDialogImpl - implementation of standard PPC/SmartPhone dialog + +template +class ATL_NO_VTABLE CStdDialogImpl : public CStdDialogImplBase< T, t_shidiFlags, t_bModal> +{}; + +/////////////////////////////////////////////////////////////////////////////// +// CStdIndirectDialogImpl - implementation of standard indirect PPC/SmartPhone dialog + +#if defined __ATLDLGS_H__ + +template +class ATL_NO_VTABLE CStdIndirectDialogImpl : + public CIndirectDialogImpl< T, CMemDlgTemplate, CStdDialogImpl > +{ +public: + typedef CIndirectDialogImpl< T, CMemDlgTemplate, CStdDialogImpl > _baseClass; + typedef CStdDialogImpl _baseStd; + + void CheckStyle() + { + // Mobile devices don't support DLGTEMPLATEEX + ATLASSERT(!m_Template.IsTemplateEx()); + + // Standard dialogs need only DS_CENTER + DWORD &dwStyle = m_Template.GetTemplatePtr()->style; + if (dwStyle & DS_CENTER) + if(t_bModal) + { + ATLASSERT((dwStyle & WS_CHILD) != WS_CHILD); + dwStyle |= WS_POPUP; + } + else + { + if((dwStyle & WS_CHILD) != WS_CHILD) + dwStyle |= WS_POPUP; + } + } + + INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow(), LPARAM dwInitParam = NULL) + { + ATLASSERT(t_bModal); + + if (!m_Template.IsValid()) + CreateTemplate(); + + CheckStyle(); + + return _baseClass::DoModal(hWndParent, dwInitParam); + } + + HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL) + { + ATLASSERT(!t_bModal); + + if (!m_Template.IsValid()) + CreateTemplate(); + + CheckStyle(); + + return _baseClass::Create(hWndParent, dwInitParam); + } + + BEGIN_MSG_MAP(CStdIndirectDialogImpl) + CHAIN_MSG_MAP(_baseStd) + END_MSG_MAP() + +}; + +#endif // defined __ATLDLGS_H__ + +#ifndef _ATL_NO_HOSTING + +/////////////////////////////////////////////////////////////////////////////// +// CStdAxDialogImpl - implementation of standard PPC/SmartPhone AxDialog + +template +class ATL_NO_VTABLE CStdAxDialogImpl : public CStdDialogImplBase< T, t_shidiFlags, t_bModal, ATL::CAxDialogImpl< T > > +{}; +#endif // _ATL_NO_HOSTING + +/////////////////////////////////////////////////////////////////////////////// +// CStdSimpleDialog - standard PPC/SmartPhone simple dialog with SHIDIF_xxx flags + +template +class CStdSimpleDialog : + public ATL::CSimpleDialog, + public CStdDialogBase, t_shidiFlags> +{ +public: + typedef CStdDialogBase, t_shidiFlags> baseClass; + +#ifdef WIN32_PLATFORM_PSPC + BOOL GetClientRect(LPRECT lpRect) + { + return baseClass::GetClientRect(lpRect); + } + + BOOL SetWindowText(LPCTSTR lpszString) + { + return baseClass::SetWindowText(lpszString); + } +#endif + + BEGIN_MSG_MAP(CStdSimpleDialog) +#ifdef WIN32_PLATFORM_PSPC // Pocket PC title and SIP + MESSAGE_HANDLER(WM_PAINT, OnPaintTitle) + MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) +#elif defined(WIN32_PLATFORM_WFSP) // SmartPhone VK_TBACK key + MESSAGE_HANDLER(WM_HOTKEY, OnHotKey) +#endif + MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose) + COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, baseClass::OnCloseCmd) + END_MSG_MAP() + + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + StdPlatformInit(); + StdShidInit(); + return bHandled = FALSE; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// CStdDialogResizeImplBase - Base implementation of orientation resizing standard PPC/SmartPhone dialog + +template > +class ATL_NO_VTABLE CStdDialogResizeImplBase : + public CStdDialogImplBase< T, t_shidiFlags, t_bModal, TBase>, + public CDialogResize +{ +public: + // Note: BEGIN_DLGRESIZE_MAP is required in the derived class. + + BEGIN_MSG_MAP(CStdResizeDialogImplBase) +#ifdef WIN32_PLATFORM_PSPC // Pocket PC title + MESSAGE_HANDLER(WM_PAINT, OnPaintTitle) +#elif defined(WIN32_PLATFORM_WFSP) // SmartPhone VK_TBACK key + MESSAGE_HANDLER(WM_HOTKEY, OnHotKey) +#endif + MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, OnCloseCmd) + COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose) + CHAIN_MSG_MAP(CDialogResize< T >) + END_MSG_MAP() + + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { +#ifdef _DEBUG + T* pT = static_cast(this); + ATLASSERT(t_bModal == pT->m_bModal); +#endif + StdPlatformInit(); + DlgResize_Init(FALSE); + StdShidInit(); + return bHandled = FALSE; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// CStdDialogResizeImpl - implementation of orientation resizing standard PPC/SmartPhone dialog + +template +class ATL_NO_VTABLE CStdDialogResizeImpl : public CStdDialogResizeImplBase< T, t_shidiFlags, t_bModal> +{}; + +#ifndef _ATL_NO_HOSTING + +/////////////////////////////////////////////////////////////////////////////// +// CStdAxDialogResizeImpl - implementation of orientation resizing standard PPC/SmartPhone AxDialog + +template +class ATL_NO_VTABLE CStdAxDialogResizeImpl : public CStdDialogResizeImplBase< T, t_shidiFlags, t_bModal, ATL::CAxDialogImpl > +{}; +#endif // _ATL_NO_HOSTING + +/////////////////////////////////////////////////////////////////////////////// +// CStdSimpleDialogResizeImpl - implementation of standard resizing simple dialog with SHIDIF_xxx flags + +// Usage: +// class CMyDlg : public CStdSimpleDialogResize +// { +// public: +// BEGIN_DLGRESIZE_MAP(CMyDlg) +// ... +// END_DLGRESIZE_MAP() +// }; + +template +class ATL_NO_VTABLE CStdSimpleDialogResizeImpl : + public CStdSimpleDialog, + public CDialogResize< T > +{ +public: + typedef CStdSimpleDialog::baseClass baseClass; + + BEGIN_MSG_MAP(CStdSimpleDialogResizeImpl) +#ifdef WIN32_PLATFORM_PSPC // Pocket PC title + MESSAGE_HANDLER(WM_PAINT, OnPaintTitle) +#elif defined(WIN32_PLATFORM_WFSP) // SmartPhone VK_TBACK key + MESSAGE_HANDLER(WM_HOTKEY, OnHotKey) +#endif + MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, baseClass::OnCloseCmd) + COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose) + CHAIN_MSG_MAP(CDialogResize< T >) + END_MSG_MAP() + + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + StdPlatformInit(); + DlgResize_Init(FALSE); + StdShidInit(); + return bHandled = FALSE; + } +}; + +#if defined(_WTL_CE_DRA) && defined(WIN32_PLATFORM_PSPC) + +/////////////////////////////////////////////////////////////////////////////// +// CStdOrientedDialogBase - Oriented PPC standard dialog base class + +template +class CStdOrientedDialogBase +{ +public: +// Operation + BOOL SetOrientation(DRA::DisplayMode mode) + { + T* pT = static_cast(this); + ATLASSERT(pT->IsWindow()); + ATLASSERT(mode == DRA::GetDisplayMode()); + + // Derived dialog must enumerate TWO dialog templates with the same control ids and types ie: + // enum { IDD = IDD_MYDLG, IDD_LANDSCAPE = IDD_MYDLG_L }; + UINT iResource = (mode == DRA::Landscape)? T::IDD_LANDSCAPE : T::IDD; + + BOOL bRes = DRA::RelayoutDialog(ModuleHelper::GetResourceInstance(), pT->m_hWnd, MAKEINTRESOURCE(iResource)); + pT->OnOrientation(mode); + return bRes; + } + +// Override + void OnOrientation(DRA::DisplayMode /*mode*/) + {} + +// Message handlers + LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + T* pT = static_cast(this); + ATLASSERT(pT->IsWindow()); + if (wParam == SETTINGCHANGE_RESET) + { + SetOrientation(DRA::GetDisplayMode()); + pT->StdPlatformInit(); + pT->StdShidInit(); + } + else if (wParam == SPI_SETSIPINFO) + { + pT->DoSipInfo(); + return TRUE; + } + return bHandled = FALSE; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// CStdOrientedDialogImplBase - Oriented PPC standard dialog base implementation + +template > +class ATL_NO_VTABLE CStdOrientedDialogImplBase : + public CStdDialogImplBase< T, t_shidiFlags, t_bModal, TBase>, + public CStdOrientedDialogBase +{ +public: + BEGIN_MSG_MAP(CStdOrientedDialogImpl) + MESSAGE_HANDLER(WM_PAINT, OnPaintTitle) + MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic) + MESSAGE_HANDLER(WM_SETTINGCHANGE, CStdOrientedDialogBase::OnSettingChange) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, OnCloseCmd) + COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose) + END_MSG_MAP() + + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + T* pT = static_cast(this); +#ifdef _DEBUG + ATLASSERT(t_bModal == pT->m_bModal); +#endif + if (DRA::GetDisplayMode() == DRA::Landscape) + SetOrientation(DRA::Landscape); + pT->StdPlatformInit(); + pT->StdShidInit(); + return bHandled = FALSE; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// CStdOrientedDialogImpl - Oriented PPC standard dialog implementation + +template +class ATL_NO_VTABLE CStdOrientedDialogImpl : public CStdOrientedDialogImplBase< T, t_shidiFlags, t_bModal> +{}; + +#ifndef _ATL_NO_HOSTING +/////////////////////////////////////////////////////////////////////////////// +// CStdAxOrientedDialogImpl - Oriented PPC standard AxDialog implementation + +template +class ATL_NO_VTABLE CStdAxOrientedDialogImpl : public CStdOrientedDialogImplBase< T, t_shidiFlags, t_bModal, ATL::CAxDialogImpl > +{}; +#endif // _ATL_NO_HOSTING + +/////////////////////////////////////////////////////////////////////////////// +// CStdSimpleOrientedDialog - Standard simple orientable dialog + +template +class CStdSimpleOrientedDialog : + public CStdSimpleDialog, + public CStdOrientedDialogBase > +{ +public: + typedef CStdSimpleDialog::baseClass baseClass; + typedef CStdOrientedDialogBase > baseOriented; + + enum {IDD = t_wDlgTemplateID, IDD_LANDSCAPE = t_wDlgLandscapeID}; + + BEGIN_MSG_MAP(CStdSimpleDialog) + MESSAGE_HANDLER(WM_PAINT, OnPaintTitle) + MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic) + MESSAGE_HANDLER(WM_SETTINGCHANGE, baseOriented::OnSettingChange) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_RANGE_HANDLER(IDOK, IDCANCEL, baseClass::OnCloseCmd) + COMMAND_RANGE_HANDLER(ID_MENU_OK, ID_MENU_CANCEL, OnMenuClose) + END_MSG_MAP() + + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if (DRA::GetDisplayMode() == DRA::Landscape) + SetOrientation(DRA::Landscape); + StdPlatformInit(); + StdShidInit(); + return bHandled = FALSE; + } +}; + +#endif // _WTL_CE_DRA + + +#endif // _WTL_CE_NO_DIALOGS + + +// --- PPC/SmartPhone application window and helpers --- + +#ifndef _WTL_CE_NO_APPWINDOW + +/////////////////////////////////////////////////////////////////////////////// +// CAppInfoBase - Helper for application state save/restore to registry + +class CAppInfoBase +{ +public: + CRegKeyEx m_Key; + + CAppInfoBase(ATL::_U_STRINGorID sAppKey) + { + m_Key.Create(HKEY_CURRENT_USER, sAppKey.m_lpstr); + ATLASSERT(m_Key.m_hKey); + } + + template + LONG Save(V& val, ATL::_U_STRINGorID sName) + { + return m_Key.SetBinaryValue(sName.m_lpstr, &val, sizeof(V)); + } + + template + LONG Save(int nb, V& val0, ATL::_U_STRINGorID sName) + { + return m_Key.SetBinaryValue(sName.m_lpstr, &val0, nb * sizeof(V)); + } + + template + LONG Restore(V& val, ATL::_U_STRINGorID sName) + { + ULONG bufSize = sizeof(V); + return m_Key.QueryBinaryValue(sName.m_lpstr, &val, &bufSize); + } + + template + LONG Restore(int nb, V& val0, ATL::_U_STRINGorID sName) + { + ULONG bufSize = nb * sizeof(V); + return m_Key.QueryBinaryValue(sName.m_lpstr, &val0, &bufSize); + } + +#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + LONG Save(_CSTRING_NS::CString& sval, ATL::_U_STRINGorID sName) + { + return m_Key.SetStringValue(sName.m_lpstr, sval); + } + + LONG Restore(_CSTRING_NS::CString& sval, ATL::_U_STRINGorID sName) + { + DWORD size = MAX_PATH; + LONG res = m_Key.QueryStringValue(sName.m_lpstr, sval.GetBuffer(size), &size); + sval.ReleaseBuffer(); + return res; + } +#else + #pragma message("Warning: CAppInfoBase compiles without CString support. Do not use CString in Save or Restore.") +#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) + + LONG Save(LPCTSTR sval, ATL::_U_STRINGorID sName) + { + return m_Key.SetStringValue(sName.m_lpstr, sval); + } + + LONG Restore(LPTSTR sval, ATL::_U_STRINGorID sName, DWORD *plength) + { + return m_Key.QueryStringValue(sName.m_lpstr, sval, plength); + } + + LONG Delete(ATL::_U_STRINGorID sName) + { + return m_Key.DeleteValue(sName.m_lpstr); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CAppInfoT - CAppInfoBase constructed from a class with T::GetAppKey() + +// Macro for declaring AppKey +#define DECLARE_APPKEY(uAppKey) \ + static LPCTSTR GetAppKey() \ + { \ + static LPCTSTR sAppKey = ATL::_U_STRINGorID(uAppKey).m_lpstr; \ + return sAppKey; \ + } + +template +class CAppInfoT : public CAppInfoBase +{ +public: + CAppInfoT() : CAppInfoBase(T::GetAppKey()){} +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CAppWindowBase - Base class for PPC/SmartPhone "well-behaved" application window or dialog + +// Macros for declaring frame WNDCLASS and AppKey +#define DECLARE_APP_FRAME_CLASS(WndClassName, uCommonResourceID, uAppKey) \ + DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) \ + DECLARE_APPKEY(uAppKey) + +#define DECLARE_APP_FRAME_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd, uAppKey) \ + DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd) \ + DECLARE_APPKEY(uAppKey) + +template +class CAppWindowBase +{ +public: + typedef class CAppInfoT< T > CAppInfo; + +#ifndef WIN32_PLATFORM_WFSP + SHACTIVATEINFO m_sai; // NoOp on SmartPhones +#endif // WIN32_PLATFORM_WFSP + + bool m_bHibernate; + + CAppWindowBase< T >() : m_bHibernate(false) + { +#ifndef WIN32_PLATFORM_WFSP + SHACTIVATEINFO sai = { sizeof(SHACTIVATEINFO) }; + m_sai = sai; +#endif // WIN32_PLATFORM_WFSP + }; + + // Same as WTL 7.1 AppWizard generated ActivatePreviousInstance + SendMessage WM_COPYDATA + static HRESULT ActivatePreviousInstance(HINSTANCE hInstance, LPCTSTR lpstrCmdLine, bool bDialog) + { + // requires T does DECLARE_APP_FRAME_CLASS, DECLARE_APP_FRAME_CLASS_EX or DECLARE_APP_DLG_CLASS + CFrameWndClassInfo& classInfo = T::GetWndClassInfo(); + + ATLVERIFY(::LoadString(hInstance, classInfo.m_uCommonResourceID, classInfo.m_szAutoName, sizeof(classInfo.m_szAutoName)/sizeof(classInfo.m_szAutoName[0])) != 0); + + classInfo.m_wc.lpszClassName = classInfo.m_szAutoName; + + const TCHAR* pszClass = classInfo.m_wc.lpszClassName; + + if(NULL == pszClass || '\0' == *pszClass) + { + return E_FAIL; + } + + const DWORD dRetryInterval = 100; + const int iMaxRetries = 25; + + for(int i = 0; i < iMaxRetries; ++i) + { + HANDLE hMutex = CreateMutex(NULL, FALSE, pszClass); + + DWORD dw = GetLastError(); + + if(NULL == hMutex) + { + HRESULT hr; + + switch(dw) + { + case ERROR_INVALID_HANDLE: + // A non-mutext object with this name already exists. + hr = E_INVALIDARG; + break; + default: + // This should never happen... + hr = E_FAIL; + } + + return hr; + } + + // If the mutex already exists, then there should be another instance running + if(dw == ERROR_ALREADY_EXISTS) + { + CloseHandle(hMutex); + + HWND hwnd = NULL; + if (bDialog) + hwnd = FindWindow(NULL, pszClass); + else + hwnd = FindWindow(pszClass, NULL); + + if(hwnd == NULL) + { + Sleep(dRetryInterval); + continue; + } + else + { + // Transmit our params to previous instance + if (lpstrCmdLine && *lpstrCmdLine) + { + COPYDATASTRUCT cd = { NULL, sizeof(TCHAR) * (wcslen(lpstrCmdLine) + 1), (PVOID)lpstrCmdLine }; + ::SendMessage(hwnd, WM_COPYDATA, NULL, (LPARAM)&cd); + } + // Set the previous instance as the foreground window + if(0 != SetForegroundWindow(reinterpret_cast(reinterpret_cast(hwnd) | 0x1))) + return S_FALSE; + } + } + else + { + return S_OK; + } + } + return S_OK; + } + +// Operations overriden in derived class + bool AppHibernate(bool /*bHibernate*/) + { + return false; + } + + bool AppNewInstance(LPCTSTR /*lpstrCmdLine*/) + { + return false; + } + + void AppSave() + { + } + +#ifdef WIN32_PLATFORM_WFSP + void AppBackKey() + { + ::SHNavigateBack(); + } +#endif + +// Message map and handlers + BEGIN_MSG_MAP(CAppWindowBase) + MESSAGE_HANDLER(WM_ACTIVATE, OnActivate) +#ifdef WIN32_PLATFORM_WFSP + MESSAGE_HANDLER(WM_HOTKEY, OnHotKey) +#else + MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) +#endif // WIN32_PLATFORM_WFSP + MESSAGE_HANDLER(WM_HIBERNATE, OnHibernate) + MESSAGE_HANDLER(WM_COPYDATA, OnNewInstance) + MESSAGE_HANDLER(WM_CLOSE, OnClose) + END_MSG_MAP() + + LRESULT OnActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + T* pT = static_cast(this); + if (m_bHibernate) + m_bHibernate = pT->AppHibernate(false); +#ifndef WIN32_PLATFORM_WFSP + ::SHHandleWMActivate(pT->m_hWnd, wParam, lParam, &m_sai, 0); +#else + wParam; + lParam; +#endif // WIN32_PLATFORM_WFSP + return bHandled = FALSE; + } + +#ifdef WIN32_PLATFORM_WFSP +// SmartPhone VK_TBACK key standard management + LRESULT OnHotKey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + const UINT uModif = (UINT)LOWORD(lParam); + const UINT uVirtKey = (UINT)HIWORD(lParam); + if(uVirtKey == VK_TBACK) + if (AtlIsEditFocus()) + ::SHSendBackToFocusWindow(uMsg, wParam, lParam); + else if (uModif & MOD_KEYUP) + pT->AppBackKey(); + return 1; + } + +#else // !WIN32_PLATFORM_WFSP +// PPC SIP handling + LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled) + { + T* pT = static_cast(this); + bHandled = FALSE; + return ::SHHandleWMSettingChange(pT->m_hWnd, wParam, lParam, &m_sai); + } +#endif // !WIN32_PLATFORM_WFSP + + LRESULT OnHibernate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + return m_bHibernate = pT->AppHibernate(true); + } + + LRESULT OnNewInstance(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + PCOPYDATASTRUCT pcds = (PCOPYDATASTRUCT)lParam; + return pT->AppNewInstance((LPCTSTR)pcds->lpData); + } + + LRESULT OnClose(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + T* pT = static_cast(this); + pT->AppSave(); + bHandled = FALSE; + return 1; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CAppWindow - PPC/SmartPhone "well-behaved" application window class + +template +class CAppWindow : public CAppWindowBase< T > +{ +public: + // Same as WTL 7.1 AppWizard generated Run + lpstrCmdLine in CreateEx + static int AppRun(LPTSTR lpstrCmdLine = NULL, int nCmdShow = SW_SHOWNORMAL) + { + CMessageLoop theLoop; + _Module.AddMessageLoop(&theLoop); + + T wndMain; + + if(wndMain.CreateEx(NULL, NULL, 0, 0, lpstrCmdLine) == NULL) + { + ATLTRACE2(atlTraceUI, 0, _T("Main window creation failed!\n")); + return 0; + } + + wndMain.ShowWindow(nCmdShow); + + int nRet = theLoop.Run(); + + _Module.RemoveMessageLoop(); + return nRet; + } + + static HRESULT ActivatePreviousInstance(HINSTANCE hInstance, LPCTSTR lpstrCmdLine) + { + return CAppWindowBase< T >::ActivatePreviousInstance(hInstance, lpstrCmdLine, false); + } +}; + + +#ifndef _WTL_CE_NO_DIALOGS + +/////////////////////////////////////////////////////////////////////////////// +// CAppDialog - PPC/SmartPhone "well-behaved" dialog application class + +// Macro for declaring dialog WNDCLASS and AppKey +#define DECLARE_APP_DLG_CLASS(WndClassName, uCommonResourceID, uAppKey) \ + static WTL::CFrameWndClassInfo& GetWndClassInfo() \ + { \ + static WTL::CFrameWndClassInfo wc = \ + { \ + { 0, (WNDPROC)StartDialogProc, \ + 0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndClassName }, \ + NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \ + }; \ + return wc; \ + }; \ + DECLARE_APPKEY(uAppKey) + +template +class CAppDialog : public CAppWindowBase< T > +{ +public: + static int AppRun(LPTSTR lpstrCmdLine = NULL, int nCmdShow = SW_SHOWNORMAL) + { + CMessageLoop theLoop; + _Module.AddMessageLoop(&theLoop); + + T dlgMain; + + if(dlgMain.Create(NULL, (LPARAM)lpstrCmdLine) == NULL) + { + ATLTRACE2(atlTraceUI, 0, _T("Main dialog creation failed!\n")); + return 0; + } + + dlgMain.ShowWindow(nCmdShow); + + int nRet = theLoop.Run(); + + _Module.RemoveMessageLoop(); + return nRet; + } + + static HRESULT ActivatePreviousInstance(HINSTANCE hInstance, LPCTSTR lpstrCmdLine) + { + return CAppWindowBase< T >::ActivatePreviousInstance(hInstance, lpstrCmdLine, true); + }; +}; + +// PPC/SmartPhone standard application dialogs + +#ifdef WIN32_PLATFORM_WFSP +#define WTL_APP_SHIDIF WTL_SP_SHIDIF +#else +#define WTL_APP_SHIDIF WTL_STD_SHIDIF +#endif + +/////////////////////////////////////////////////////////////////////////////// +// CAppStdDialogImplBase - Base implementation of standard application dialogs + +template +class ATL_NO_VTABLE CAppStdDialogImplBase : + public TImplBase, + public CAppDialog< T > +{ +public: + WTL_DLG_NOTITLE; + + void StdCloseDialog(int nVal) + { + T* pT = static_cast(this); + if (nVal != IDCANCEL) + pT->AppSave(); + if (t_bModal == false) + { + pT->DestroyWindow(); + ::PostQuitMessage(nVal); + } + else + ::EndDialog(pT->m_hWnd, nVal); + } + + BEGIN_MSG_MAP(CAppStdDialogImplBase) + MESSAGE_HANDLER(WM_CLOSE, OnSystemClose) + CHAIN_MSG_MAP(TImplBase) + CHAIN_MSG_MAP(CAppDialog< T >) + END_MSG_MAP() + + LRESULT OnSystemClose(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + { + T* pT = static_cast(this); + pT->StdCloseDialog(IDCANCEL); + return 0; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// CAppStdDialogImpl - Implementation of standard application dialog + +template +class ATL_NO_VTABLE CAppStdDialogImpl : + public CAppStdDialogImplBase, t_shidiFlags, t_bModal> +{}; + +/////////////////////////////////////////////////////////////////////////////// +// CAppStdDialogResizeImpl - implementation of orientation resizing standard application dialog + +template +class ATL_NO_VTABLE CAppStdDialogResizeImpl : + public CAppStdDialogImplBase, t_shidiFlags, t_bModal> +{}; + +#ifndef _ATL_NO_HOSTING +/////////////////////////////////////////////////////////////////////////////// +// CAppStdAxDialogImpl - Implementation of standard application AxDialog + +template +class ATL_NO_VTABLE CAppStdAxDialogImpl : + public CAppStdDialogImplBase, t_shidiFlags, t_bModal> +{}; + +/////////////////////////////////////////////////////////////////////////////// +// CAppStdAxDialogResizeImpl - implementation of orientation resizing standard application AxDialog + +template +class ATL_NO_VTABLE CAppStdAxDialogResizeImpl : + public CAppStdDialogImplBase, t_shidiFlags, t_bModal> +{}; +#endif // _ATL_NO_HOSTING + +#if defined(_WTL_CE_DRA) && defined(WIN32_PLATFORM_PSPC) +/////////////////////////////////////////////////////////////////////////////// +// CAppStdOrientedDialogImpl - implementation of oriented PPC standard application dialog + +template +class ATL_NO_VTABLE CAppStdOrientedDialogImpl : + public CAppStdDialogImplBase, t_shidiFlags, t_bModal> +{}; + +#ifndef _ATL_NO_HOSTING +/////////////////////////////////////////////////////////////////////////////// +// CAppStdAxOrientedDialogImpl - implementation of oriented PPC standard application AxDialog + +template +class ATL_NO_VTABLE CAppStdAxOrientedDialogImpl : + public CAppStdDialogImplBase, t_shidiFlags, t_bModal> +{}; +#endif // _ATL_NO_HOSTING + +#endif // defined(_WTL_CE_DRA) && defined(WIN32_PLATFORM_PSPC) + +#endif // _WTL_CE_NO_DIALOGS + +#endif // _WTL_CE_NO_APPWINDOW + + +// --- Full screen support --- + +#ifndef _WTL_CE_NO_FULLSCREEN + +/////////////////////////////////////////////////////////////////////////////// +// CFullScreenFrame - full screen frame implementation + +template +class CFullScreenFrame +{ +public: + bool m_bFullScreen; + + CFullScreenFrame() : m_bFullScreen(false) + { } + +// Operation + void SetFullScreen(bool bFull) + { + m_bFullScreen = bFull; + ShowTaskBar(!bFull, false); + ShowMenuBar(!bFull); + } + +// Manage TaskBar for modal dialogs and property sheets + template + int FSDoModal(D& dlg) + { + T* pT = static_cast(this); + pT; // avoid level 4 warning + ATLASSERT(pT->IsWindow()); + if (m_bFullScreen) // Show taskbar if hidden + ShowTaskBar(true, false); + int iRet = dlg.DoModal(); + if (m_bFullScreen) // Hide taskbar if restored + ShowTaskBar(false); + return iRet; + } + +// Implementation + void ShowMenuBar(bool bShow) + { + T* pT = static_cast(this); + ATLASSERT(pT->IsWindow()); + ATL::CWindow MenuBar = pT->m_hWndCECommandBar; + ATLASSERT(MenuBar.IsWindow()); + MenuBar.ShowWindow(bShow ? SW_SHOWNORMAL : SW_HIDE); + pT->SizeToMenuBar(); + } + + void ShowTaskBar(bool bShow, bool bRepaint = true) + { + T* pT = static_cast(this); + ATLASSERT(pT->IsWindow()); + RECT rect = { 0 }; + SystemParametersInfo(SPI_GETWORKAREA, NULL, &rect, FALSE); + if (!bShow) + rect.top = 0; + +#ifdef WIN32_PLATFORM_PSPC // Pocket PC code + UINT uShow = t_bHasSip ? SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON : SHFS_SHOWTASKBAR | SHFS_HIDESIPBUTTON; + SHFullScreen(pT->m_hWnd, bShow ? uShow : SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON); +#elif _WIN32_WCE > 0x500 // Smartphone 2005 code + SHFullScreen(pT->m_hWnd, bShow ? SHFS_SHOWTASKBAR : SHFS_HIDETASKBAR); +#else // Smartphone 2003 + HWND hTaskBar = FindWindow(_T("tray"), NULL); + ATLASSERT(::IsWindow(hTaskBar)); + ::ShowWindow(hTaskBar, bShow ? SW_SHOW : SW_HIDE); +#endif // WIN32_PLATFORM_PSPC + + pT->MoveWindow(&rect, bRepaint); + } + +// Message map and handler + BEGIN_MSG_MAP(CFullScreenFrame) + MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange) + MESSAGE_HANDLER(WM_ACTIVATE, OnActivate) + END_MSG_MAP() + + LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { +#ifndef SETTINGCHANGE_RESET // not defined for PPC 2002 + #define SETTINGCHANGE_RESET SPI_SETWORKAREA +#endif + if (m_bFullScreen && (wParam == SETTINGCHANGE_RESET)) + SetFullScreen(m_bFullScreen); + return bHandled = FALSE; + } + + LRESULT OnActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + if (m_bFullScreen) + { + ShowTaskBar(!wParam); + ShowMenuBar(!wParam); + } + return bHandled = FALSE; + } +}; + +#endif // _WTL_CE_NO_FULLSCREEN + + +// --- WinCE zoom support --- + +#ifndef _WTL_CE_NO_ZOOMSCROLL + +/////////////////////////////////////////////////////////////////////////////// +// CZoomScrollImpl - WinCE zooming implementation on top of CScrollImpl + +template +class CZoomScrollImpl: public CScrollImpl< T > +{ +public: +// Data members + _WTYPES_NS::CSize m_sizeTrue; + double m_fzoom; + +// Creation + CZoomScrollImpl() : m_sizeTrue(0), m_fzoom(1.) + { } + +// Zoom operations and access + void SetZoomScrollSize(_WTYPES_NS::CSize sizeTrue, double fzoom = 1., BOOL bRedraw = TRUE) + { + ATLASSERT(fzoom > 0.); + m_sizeTrue = sizeTrue; + m_fzoom = fzoom; + + CScrollImpl< T >::SetScrollSize(sizeTrue / fzoom, bRedraw); + } + + void SetZoomScrollSize(int cx, int cy, double fzoom=1., BOOL bRedraw = TRUE) + { + SetZoomScrollSize(_WTYPES_NS::CSize(cx, cy), fzoom, bRedraw); + } + + void SetZoom(double fzoom, BOOL bRedraw = TRUE) + { + _WTYPES_NS::CPoint ptCenter = WndtoTrue(m_sizeClient / 2); + _WTYPES_NS::CSize sizePage = GetScrollPage(); + _WTYPES_NS::CSize sizeLine = GetScrollLine(); + + SetZoomScrollSize(GetScrollSize(), fzoom, bRedraw); + + SetScrollLine(sizeLine); + SetScrollPage(sizePage); + _WTYPES_NS::CPoint ptOffset = ptCenter - (m_sizeClient / 2) * fzoom; + SetScrollOffset(ptOffset, bRedraw); + } + + double GetZoom() + { + return m_fzoom; + } + +// CScrollImpl overrides + void SetScrollOffset(int x, int y, BOOL bRedraw = TRUE) + { + CScrollImpl< T >::SetScrollOffset((int)(x / m_fzoom), (int)(y / m_fzoom), bRedraw); + } + + void SetScrollOffset(POINT ptOffset, BOOL bRedraw = TRUE) + { + SetScrollOffset(ptOffset.x, ptOffset.y, bRedraw); + } + + void GetScrollOffset(POINT& ptOffset) + { + ptOffset.x = (LONG)(m_ptOffset.x * m_fzoom); + ptOffset.y = (LONG)(m_ptOffset.y * m_fzoom); + } + + void SetScrollSize(int cx, int cy, BOOL bRedraw = TRUE) + { + SetZoomScrollSize(cx, cy, GetZoom(), bRedraw); + } + + void SetScrollSize(SIZE sizeTrue, BOOL bRedraw = TRUE) + { + SetZoomScrollSize(sizeTrue, GetZoom(), bRedraw); + } + + void GetScrollSize(SIZE& sizeTrue) const + { + sizeTrue = m_sizeTrue; + } + + void SetScrollPage(int cxPage, int cyPage) + { + SetScrollPage(_WTYPES_NS::CSize(cxPage, cyPage)); + } + + void SetScrollPage(SIZE sizePage) + { + CScrollImpl< T >::SetScrollPage(sizePage / m_fzoom); + } + + void GetScrollPage(SIZE& sizePage) const + { + sizePage = m_sizePage * m_fzoom; + } + + void SetScrollLine(int cxLine, int cyLine) + { + SetScrollLine(_WTYPES_NS::CSize(cxLine, cyLine)); + } + + void SetScrollLine(SIZE sizeLine) + { + CScrollImpl< T >::SetScrollLine(sizeLine / m_fzoom); + } + + void GetScrollLine(SIZE& sizeLine) const + { + sizeLine = m_sizeLine * m_fzoom; + } + +// Data access complements + _WTYPES_NS::CSize GetScrollSize() + { + return m_sizeTrue; + } + + _WTYPES_NS::CSize GetScrollPage() + { + return m_sizePage * m_fzoom; + } + + _WTYPES_NS::CSize GetScrollLine() + { + return m_sizeLine * m_fzoom; + } + + _WTYPES_NS::CPoint GetScrollOffset() + { + return (_WTYPES_NS::CSize)m_ptOffset * m_fzoom; + } + +// Helper coordinate functions + _WTYPES_NS::CPoint WndtoTrue(CPoint ptW) + { + return (_WTYPES_NS::CSize)ptW * GetZoom() + GetScrollOffset(); + } + + void WndtoTrue(LPPOINT aptW, int nPts) // in place coord transformation + { + for (int i = 0 ; i < nPts ; i++) + aptW[i] = WndtoTrue(aptW[i]); + } + + void WndtoTrue(LPRECT prectW) // in place coord transformation + { + WndtoTrue((LPPOINT)prectW, 2); + } + + _WTYPES_NS::CPoint TruetoWnd(CPoint ptT) + { + return (ptT - GetScrollOffset()) / GetZoom(); + } + + void TruetoWnd(LPPOINT aptT, int nPts) // in place coord transformation + { + for (int i = 0 ; i < nPts ; i++) + aptT[i] = TruetoWnd(aptT[i]); + } + + void TruetoWnd(LPRECT prectT) // in place coord transformation + { + TruetoWnd((LPPOINT)prectT, 2); + } + +// Drawing operations : assume adequate setting of data members + BOOL Draw(HBITMAP hbm, HDC hdestDC, DWORD dwROP = SRCCOPY) + { + CDC memDC = CreateCompatibleDC(hdestDC); + CBitmapHandle bmpOld = memDC.SelectBitmap(hbm); + BOOL bRes = Draw(memDC, hdestDC, dwROP); + memDC.SelectBitmap(bmpOld); + return bRes; + } + + BOOL Draw(HDC hsourceDC, HDC hdestDC, DWORD dwROP = SRCCOPY) + { + CDCHandle destDC = hdestDC; + destDC.SetViewportOrg(0,0); + _WTYPES_NS::CPoint ptOffset = GetScrollOffset(); + _WTYPES_NS::CSize sizeZClient = m_sizeClient * GetZoom(); + return destDC.StretchBlt(0, 0, m_sizeClient.cx, m_sizeClient.cy, hsourceDC, ptOffset.x, ptOffset.y, sizeZClient.cx, sizeZClient.cy, dwROP); + } + +#ifdef _IMAGING_H + BOOL Draw(IImage* pIImage, HDC hdestDC) + { + CDCHandle destDC = hdestDC; + destDC.SetViewportOrg(0,0); + return SUCCEEDED(pIImage->Draw(destDC, _WTYPES_NS::CRect(-_WTYPES_NS::CPoint(m_ptOffset), m_sizeAll), NULL)); + } +#endif + +// Message map and handlers + BEGIN_MSG_MAP(CZoomScrollImpl< T >) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd) + CHAIN_MSG_MAP(CScrollImpl< T >) + END_MSG_MAP() + + LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) + { + T* pT = static_cast(this); + ATLASSERT(::IsWindow(pT->m_hWnd)); + if ((GetScrollExtendedStyle() & SCRL_ERASEBACKGROUND)) + { + _WTYPES_NS::CRect rect; + pT->GetClientRect(rect); + _WTYPES_NS::CSize sizeClient=rect.Size(); + + if (m_sizeAll.cx < sizeClient.cx || m_sizeAll.cy < sizeClient.cy) + { + CDCHandle hdc = (HDC)wParam; + HBRUSH hbr = GetSysColorBrush((int)T::GetWndClassInfo().m_wc.hbrBackground - 1); + + if (m_sizeAll.cx < sizeClient.cx) + { + _WTYPES_NS::CRect rectBG(_WTYPES_NS::CPoint(m_sizeAll.cx, 0), sizeClient); + hdc.FillRect(rectBG, hbr); + } + + if (m_sizeAll.cy < sizeClient.cy) + { + _WTYPES_NS::CRect rectBG(_WTYPES_NS::CPoint(0, m_sizeAll.cy), sizeClient); + hdc.FillRect(rectBG, hbr); + } + } + } + else + { + bHandled = FALSE; + } + + return 1; + } +}; + +#endif // _WTL_CE_NO_ZOOMSCROLL + +#ifndef _WTL_CE_NO_CONTROLS + +// --- PPC bottom TabView control --- + +#if defined(__ATLCTRLX_H__) && defined(WIN32_PLATFORM_PSPC) + +/////////////////////////////////////////////////////////////////////////////// +// CBottomTabViewImpl + +template +class ATL_NO_VTABLE CBottomTabViewImpl : public CTabViewImpl +{ +public: + DECLARE_WND_CLASS_EX(NULL, 0, COLOR_APPWORKSPACE) + +// Implementation overrideables + bool CreateTabControl() + { + m_tab.Create(m_hWnd, rcDefault, NULL, WS_CHILD | TCS_BOTTOM, 0, m_nTabID); + + ATLASSERT(m_tab.m_hWnd != NULL); + if(m_tab.m_hWnd == NULL) + return false; + + m_tab.SendMessage(CCM_SETVERSION, COMCTL32_VERSION); + m_tab.SetItemExtra(sizeof(TABVIEWPAGE)); + + T* pT = static_cast(this); + m_cyTabHeight = pT->CalcTabHeight(); + + return true; + } + + int CalcTabHeight() + { + int nCount = m_tab.GetItemCount(); + TCITEMEXTRA tcix = { 0 }; + tcix.tciheader.mask = TCIF_TEXT; + tcix.tciheader.pszText = _T("NS"); + int nIndex = m_tab.InsertItem(nCount, tcix); + + RECT rect = { 0 }; + SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0); + RECT rcWnd = rect; + + m_tab.AdjustRect(FALSE, &rect); + rcWnd.top = rect.bottom; + ::AdjustWindowRectEx(&rcWnd, m_tab.GetStyle(), FALSE, m_tab.GetExStyle()); + m_tab.DeleteItem(nIndex); + + return rcWnd.bottom - rcWnd.top; + } + + void UpdateLayout() + { + RECT rect; + GetClientRect(&rect); + + if(m_tab.IsWindow() && ((m_tab.GetStyle() & WS_VISIBLE) != 0)) + m_tab.SetWindowPos(NULL, 0, rect.bottom - m_cyTabHeight, rect.right - rect.left, m_cyTabHeight, SWP_NOZORDER /*| SWP_SHOWWINDOW*/); + + if(m_nActivePage != -1) + ::SetWindowPos(GetPageHWND(m_nActivePage), NULL, 0, 0, rect.right - rect.left, rect.bottom - m_cyTabHeight, SWP_NOZORDER); + } + +}; + +class CBottomTabView : public CBottomTabViewImpl +{ +public: + DECLARE_WND_CLASS_EX(_T("WTL_BottomTabView"), 0, COLOR_APPWORKSPACE) +}; + +#endif // defined(__ATLCTRLX_H__) && defined(WIN32_PLATFORM_PSPC) + + +// --- PPC/SmartPhone controls --- + +//////////////////////////////////////////////////////////////////////////////// +// These are wrapper classes for the Pocket PC 2002/2003 and SmartPhone 2003 controls +// To implement a window based on a control, use following: +// Example: Implementing a window based on a Html control +// +// class CMyHtml : CWindowImpl +// { +// public: +// BEGIN_MSG_MAP(CMyHtml) +// // put your message handler entries here +// END_MSG_MAP() +// }; +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// CHtmlCtrl + +template +class CHtmlCtrlT : public TBase +{ +public: +// Constructors + CHtmlCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CHtmlCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + HWND hWnd = TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + ATLASSERT(hWnd != NULL); // Did you remember to call InitHTMLControl(hInstance) ?? + return hWnd; + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_HTML; + } + +#if (_WIN32_WCE >= 400) + void AddStyle(LPCWSTR pszStyle) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_ADDSTYLE, 0, (LPARAM)pszStyle); + } +#endif // (_WIN32_WCE >= 400) + + void AddText(BOOL bPlainText, LPCSTR pszText) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_ADDTEXT, (WPARAM)bPlainText, (LPARAM)pszText); + } + + void AddHTML(LPCSTR pszHTML) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_ADDTEXT, (WPARAM)FALSE, (LPARAM)pszHTML); + } + + void AddText(BOOL bPlainText, LPCWSTR pszText) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_ADDTEXTW, (WPARAM)bPlainText, (LPARAM)pszText); + } + + void AddHTML(LPCWSTR pszHTML) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_ADDTEXTW, (WPARAM)FALSE, (LPARAM)pszHTML); + } + + void Anchor(LPCSTR pszAnchor) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_ANCHOR, 0, (LPARAM)pszAnchor); + } + + void Anchor(LPCWSTR pszAnchor) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_ANCHORW, 0, (LPARAM)pszAnchor); + } + +#if (_WIN32_WCE >= 420) + void GetBrowserDispatch(IDispatch** ppDispatch) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(ppDispatch); + ATLASSERT(*ppDispatch==NULL); + ::SendMessage(m_hWnd, DTM_BROWSERDISPATCH, 0, (LPARAM)ppDispatch); + } + void GetDocumentDispatch(IDispatch** ppDispatch) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(ppDispatch); + ATLASSERT(*ppDispatch==NULL); + ::SendMessage(m_hWnd, DTM_DOCUMENTDISPATCH , 0, (LPARAM)ppDispatch); + } +#endif // (_WIN32_WCE >= 420) + + void Clear() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_CLEAR, 0, 0L); + } + + void EnableClearType(BOOL bEnable = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_ENABLECLEARTYPE, 0, (LPARAM)bEnable); + } + + void EnableContextMenu(BOOL bEnable = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_ENABLECONTEXTMENU, 0, (LPARAM)bEnable); + } + + void EnableScripting(BOOL bEnable = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_ENABLESCRIPTING, 0, (LPARAM)bEnable); + } + + void EnableShrink(BOOL bEnable = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_ENABLESHRINK, 0, (LPARAM)bEnable); + } + + void EndOfSource() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_ENDOFSOURCE, 0, 0L); + } + + void ImageFail(DWORD dwCookie) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_IMAGEFAIL, 0, (LPARAM)dwCookie); + } + + int GetLayoutHeight() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, DTM_LAYOUTHEIGHT, 0, 0L); + } + + int GetLayoutWidth() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, DTM_LAYOUTWIDTH, 0, 0L); + } + + void Navigate(LPCTSTR pstrURL, UINT uFlags = 0) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pstrURL); + ::SendMessage(m_hWnd, DTM_NAVIGATE, (WPARAM)uFlags, (LPARAM)pstrURL); + } + + void SelectAll() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_SELECTALL, 0, 0L); + } + + void SetImage(INLINEIMAGEINFO* pImageInfo) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pImageInfo); + ::SendMessage(m_hWnd, DTM_SETIMAGE, 0, (LPARAM)pImageInfo); + } + + void ZoomLevel(int iLevel) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_ZOOMLEVEL, 0, (LPARAM)iLevel); + } + +#if (_WIN32_WCE >= 400) + void Stop() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DTM_STOP, 0, 0L); + } +#endif // (_WIN32_WCE >= 400) + + void GetScriptDispatch(IDispatch** ppDispatch) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(ppDispatch); + ATLASSERT(*ppDispatch==NULL); + ::SendMessage(m_hWnd, DTM_SCRIPTDISPATCH, 0, (LPARAM)ppDispatch); + } +}; + +typedef CHtmlCtrlT CHtmlCtrl; + + +#ifdef WIN32_PLATFORM_PSPC + +/////////////////////////////////////////////////////////////////////////////// +// CRichInkCtrl + +template +class CRichInkCtrlT : public TBase +{ +public: +// Constructors + CRichInkCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CRichInkCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + HWND hWnd = TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + ATLASSERT(hWnd != NULL); // Did you remember to call InitRichInkDLL() ?? + return hWnd; + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_RICHINK; + } + + BOOL CanPaste(UINT uFormat = 0) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_CANPASTE, (WPARAM)uFormat, 0L); + } + + BOOL CanRedo() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_CANREDO, 0, 0L); + } + + BOOL CanUndo() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_CANUNDO, 0, 0L); + } + + void ClearAll(BOOL bRepaint = TRUE) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_CLEARALL, (WPARAM)bRepaint, 0L); + } + + BOOL GetModify() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, EM_GETMODIFY, 0, 0L); + } + + UINT GetPageStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, EM_GETPAGESTYLE, 0, 0L); + } + + UINT GetPenMode() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, EM_GETPENMODE, 0, 0L); + } + + UINT GetViewStyle() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, EM_GETVIEW, 0, 0L); + } + + UINT GetWrapMode() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, EM_GETWRAPMODE, 0, 0L); + } + + UINT GetZoomPercent() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, EM_GETZOOMPERCENT, 0, 0L); + } + + void InsertLinks(LPWSTR lpString, int cchLength = -1) + { + ATLASSERT(::IsWindow(m_hWnd)); + if(cchLength == -1) + cchLength = lstrlen(lpString); + ::SendMessage(m_hWnd, EM_INSERTLINKS, (WPARAM)cchLength, (LPARAM)lpString); + } + + void RedoEvent() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_REDOEVENT, 0, 0L); + } + + UINT SetInkLayer(UINT uLayer) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (UINT)::SendMessage(m_hWnd, EM_SETINKLAYER, (WPARAM)uLayer, 0L); + } + + void SetPageStyle(UINT uStyle) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETPAGESTYLE, (WPARAM)uStyle, 0L); + } + + void SetPenMode(UINT uMode) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETPENMODE, (WPARAM)uMode, 0L); + } + + void SetViewStyle(UINT uStyle) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETVIEW, (WPARAM)uStyle, 0L); + } + + void SetViewAttributes(VIEWATTRIBUTES* pAttribs) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pAttribs); + ::SendMessage(m_hWnd, EM_SETVIEWATTRIBUTES, 0, (LPARAM)pAttribs); + } + + void SetWrapMode(UINT uMode) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETWRAPMODE, (WPARAM)uMode, 0L); + } + + void SetZoomPercent(UINT uPercent) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETZOOMPERCENT, (WPARAM)uPercent, 0L); + } + + LONG StreamIn(UINT uFormat, EDITSTREAM& es) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LONG)::SendMessage(m_hWnd, EM_STREAMIN, (WPARAM)uFormat, (LPARAM)&es); + } + + LONG StreamOut(UINT uFormat, EDITSTREAM& es) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (LONG)::SendMessage(m_hWnd, EM_STREAMOUT, (WPARAM)uFormat, (LPARAM)&es); + } + + void UndoEvent() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_UNDOEVENT, 0, 0L); + } + + void Undo() + { + UndoEvent(); + } + +// Standard EM_xxx messages + DWORD GetSel() const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetViewStyle() != VT_DRAWINGVIEW); + return (DWORD)::SendMessage(m_hWnd, EM_GETSEL, 0, 0L); + } + + void GetSel(int& nStartChar, int& nEndChar) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetViewStyle() != VT_DRAWINGVIEW); + ::SendMessage(m_hWnd, EM_GETSEL, (WPARAM)&nStartChar, (LPARAM)&nEndChar); + } + + void SetSel(int nStartChar, int nEndChar) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetViewStyle() != VT_DRAWINGVIEW); + ::SendMessage(m_hWnd, EM_SETSEL, nStartChar, nEndChar); + } + + void ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo = FALSE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(GetViewStyle() != VT_DRAWINGVIEW); + ::SendMessage(m_hWnd, EM_REPLACESEL, (WPARAM)bCanUndo, (LPARAM)lpszNewText); + } + + void SetModify(BOOL bModified = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, EM_SETMODIFY, (WPARAM)bModified, 0L); + } + + int GetTextLength() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, WM_GETTEXTLENGTH, 0, 0L); + } + +// Clipboard operations + void Clear() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_CLEAR, 0, 0L); + } + + void Copy() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_COPY, 0, 0L); + } + + void Cut() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_CUT, 0, 0L); + } + + void Paste() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, WM_PASTE, 0, 0L); + } +}; + +typedef CRichInkCtrlT CRichInkCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CInkXCtrl + +template +class CInkXCtrlT : public TBase +{ +public: +// Constructors + CInkXCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CInkXCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + HWND hWnd = TBase::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + ATLASSERT(hWnd != NULL); // Did you remember to call InitInkX() ?? + return hWnd; + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_INKX; + } + + static UINT GetHotRecordingMessage() + { + return ::RegisterWindowMessage(szHotRecording); + } + + void ClearAll() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, IM_CLEARALL, 0, 0L); + } + + int GetData(BYTE* lpBuffer, INT cbBuffer) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpBuffer); + return (int)::SendMessage(m_hWnd, IM_GETDATA, (WPARAM)cbBuffer, (LPARAM)lpBuffer); + } + + int GetDataLen() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, IM_GETDATALEN, 0, 0L); + } + + CRichInkCtrl GetRichInk() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HWND)::SendMessage(m_hWnd, IM_GETRICHINK, 0, 0L); + } + + BOOL IsRecording() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, IM_RECORDING, 0, 0L); + } + + void ReInit() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, IM_REINIT, 0, 0L); + } + + void SetData(const BYTE* lpInkData, INT cbInkData) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(lpInkData); + ::SendMessage(m_hWnd, IM_SETDATA, (WPARAM)cbInkData, (LPARAM)lpInkData); + } + + void VoicePlay() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, IM_VOICE_PLAY, 0, 0L); + } + + BOOL IsVoicePlaying() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, IM_VOICE_PLAYING, 0, 0L); + } + + BOOL VoiceRecord() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, IM_VOICE_RECORD, 0, 0L); + } + + void VoiceStop() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, IM_VOICE_STOP, 0, 0L); + } + + void ShowVoiceBar(BOOL bShow = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, IM_VOICEBAR, (WPARAM)bShow, 0L); + } +}; + +typedef CInkXCtrlT CInkXCtrl; + +#endif // WIN32_PLATFORM_PSPC + + +/////////////////////////////////////////////////////////////////////////////// +// CVoiceRecorderCtrl + +template +class CVoiceRecorderCtrlT : public TBase +{ +public: +// Constructors + CVoiceRecorderCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CVoiceRecorderCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, const POINT pt, LPTSTR pstrFileName, UINT nID, DWORD dwStyle = 0) + { + ATLASSERT(pstrFileName != NULL); + CM_VOICE_RECORDER cmvr = { 0 }; + cmvr.cb = sizeof(CM_VOICE_RECORDER); + cmvr.dwStyle = dwStyle; + cmvr.xPos = pt.x; + cmvr.yPos = pt.y; + cmvr.hwndParent = hWndParent; + cmvr.id = nID; + cmvr.lpszRecordFileName = pstrFileName; + m_hWnd = VoiceRecorder_Create(&cmvr); + return m_hWnd; + } + + HWND Create(LPCM_VOICE_RECORDER pAttribs) + { + ATLASSERT(pAttribs); + m_hWnd = VoiceRecorder_Create(pAttribs); + return m_hWnd; + } + +// Attributes + void Record() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, VRM_RECORD, 0, 0L); + } + + void Play() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, VRM_PLAY, 0, 0L); + } + + void Stop() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, VRM_STOP, 0, 0L); + } + + void Cancel() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, VRM_CANCEL, 0, 0L); + } + + void Done() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, VRM_OK, 0, 0L); + } +}; + +typedef CVoiceRecorderCtrlT CVoiceRecorderCtrl; + + +#ifdef WIN32_PLATFORM_PSPC + +/////////////////////////////////////////////////////////////////////////////// +// CDocListCtrl + +template +class CDocListCtrlT : public TBase +{ +public: +// Attributes + DOCLISTCREATE m_dlc; + TCHAR m_szPath[MAX_PATH]; + +// Constructors + CDocListCtrlT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CDocListCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, WORD wId, LPCTSTR pszFolder = NULL, LPCTSTR pstrFilter = NULL, + WORD wFilterIndex = 0, DWORD dwFlags = DLF_SHOWEXTENSION) + { + ATLASSERT(pstrFilter != NULL); // It seems to need a filter badly!! + ::ZeroMemory(&m_dlc, sizeof(DOCLISTCREATE)); + ::ZeroMemory(m_szPath, sizeof(m_szPath)); + if(pszFolder != NULL) + SecureHelper::strncpy_x(m_szPath, MAX_PATH, pszFolder, MAX_PATH - 1); + m_dlc.dwStructSize = sizeof(DOCLISTCREATE); + m_dlc.hwndParent = hWndParent; + m_dlc.pszFolder = m_szPath; + m_dlc.pstrFilter = pstrFilter; + m_dlc.wFilterIndex = wFilterIndex; + m_dlc.wId = wId; + m_dlc.dwFlags = dwFlags; + m_hWnd = DocList_Create(&m_dlc); + return m_hWnd; + } + + HWND Create(DOCLISTCREATE* pDlc) + { + m_dlc = *pDlc; + m_hWnd = DocList_Create(&m_dlc); + return m_hWnd; + } + +// Attributes + void DeleteSel() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DLM_DELETESEL, 0, 0L); + } + + void DisableUpdates() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DLM_DISABLEUPDATES, 0, 0L); + } + + void EnableUpdates() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DLM_ENABLEUPDATES, 0, 0L); + } + + int GetFilterIndex() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, DLM_GETFILTERINDEX, 0, 0L); + } + + int GetItemCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, DLM_GETITEMCOUNT, 0, 0L); + } + + int GetNextItem(int iIndex, DWORD dwRelation = LVNI_ALL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, DLM_GETNEXTITEM, (WPARAM)iIndex, (LPARAM)dwRelation); + } + + int GetFirstItem(DWORD dwRelation = LVNI_ALL) const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, DLM_GETNEXTITEM, (WPARAM)-1, (LPARAM)dwRelation); + } + + BOOL GetNextWave(int* pIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pIndex); + return (BOOL)::SendMessage(m_hWnd, DLM_GETNEXTWAVE, 0, (LPARAM)pIndex); + } + + BOOL GetPrevWave(int* pIndex) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pIndex); + return (BOOL)::SendMessage(m_hWnd, DLM_GETPREVWAVE, 0, (LPARAM)pIndex); + } + + int GetSelCount() const + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, DLM_GETSELCOUNT, 0, 0L); + } + + BOOL GetSelPathName(LPTSTR pstrPath, int cchMax) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pstrPath); + return (BOOL)::SendMessage(m_hWnd, DLM_GETSELPATHNAME, (WPARAM)cchMax, (LPARAM)pstrPath); + } + + void ReceiveIR(LPCTSTR pstrPath) const + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pstrPath); + ::SendMessage(m_hWnd, DLM_RECEIVEIR, 0, (LPARAM)pstrPath); + } + + void Refresh() + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DLM_REFRESH, 0, 0L); + } + + BOOL RenameMoveSelectedItems() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, DLM_RENAMEMOVE, 0, 0L); + } + + int SelectAll() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (int)::SendMessage(m_hWnd, DLM_SELECTALL, 0, 0L); + } + + HRESULT SelectItem(LPCTSTR pstrPath, BOOL bVisible = TRUE) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pstrPath); + return (HRESULT)::SendMessage(m_hWnd, DLM_SELECTITEM, (WPARAM)bVisible, (LPARAM)pstrPath); + } + + void SendEMail(LPCTSTR pstrAttachment) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DLM_SENDEMAIL, 0, (LPARAM)pstrAttachment); + } + + void SendIR(LPCTSTR pstrPath) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DLM_SENDIR, 0, (LPARAM)pstrPath); + } + + HRESULT SetFilterIndex(int iIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HRESULT)::SendMessage(m_hWnd, DLM_SETFILTERINDEX, (WPARAM)iIndex, 0L); + } + + void SetFolder(LPCTSTR pstrPath) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pstrPath); + ::SendMessage(m_hWnd, DLM_SETFOLDER, 0, (LPARAM)pstrPath); + } + + BOOL SetItemState(int iIndex, const LVITEM* pItem) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pItem); + return (BOOL)::SendMessage(m_hWnd, DLM_SETITEMSTATE, (WPARAM)iIndex, (LPARAM)pItem); + } + + BOOL SetItemState(int iIndex, UINT uState, UINT uMask) + { + ATLASSERT(::IsWindow(m_hWnd)); + LV_ITEM lvi = { 0 }; + lvi.stateMask = uMask; + lvi.state = uState; + return (BOOL)::SendMessage(m_hWnd, DLM_SETITEMSTATE, (WPARAM)iIndex, (LPARAM)&lvi); + } + + void SetOneItem(int iIndex, LPCVOID pPA) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DLM_SETONEITEM, (WPARAM)iIndex, (LPARAM)pPA); + } + + void SetSelect(int iIndex) + { + ATLASSERT(::IsWindow(m_hWnd)); + ::SendMessage(m_hWnd, DLM_SETSELECT, (WPARAM)iIndex, 0L); + } + + void SetSelPathName(LPCTSTR pstrPath) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pstrPath); + ::SendMessage(m_hWnd, DLM_SETSELPATHNAME, 0, (LPARAM)pstrPath); + } + + BOOL SetSortOrder() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, DLM_SETSORTORDER, 0, 0L); + } + + HRESULT Update() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (HRESULT)::SendMessage(m_hWnd, DLM_UPDATE, 0, 0L); + } + + BOOL ValidateFolder() + { + ATLASSERT(::IsWindow(m_hWnd)); + return (BOOL)::SendMessage(m_hWnd, DLM_VALIDATEFOLDER, 0, 0L); + } + +// Functions + BOOL GetFirstSelectedWaveFile(int* pIndex, LPTSTR szPath, const size_t cchPath) + { + ATLASSERT(::IsWindow(m_hWnd)); + return DocList_GetFirstSelectedWaveFile(m_hWnd, pIndex, szPath, cchPath); + } + + BOOL GetNextSelectedWaveFile(int* pIndex, LPTSTR szPath, const size_t cchPath) + { + ATLASSERT(::IsWindow(m_hWnd)); + return DocList_GetNextSelectedWaveFile(m_hWnd, pIndex, szPath, cchPath); + } +}; + +typedef CDocListCtrlT CDocListCtrl; + +#endif // WIN32_PLATFORM_PSPC + + +/////////////////////////////////////////////////////////////////////////////// +// CCapEdit + +template +class CCapEditT : public TBase +{ +public: +// Constructors + CCapEditT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CCapEditT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + HWND hWnd = /*TBase*/CWindow::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + ATLASSERT(hWnd != NULL); // Did you remember to call SHInitExtraControls() ?? + return hWnd; + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_CAPEDIT; + } +}; + +typedef CCapEditT CCapEdit; + +/////////////////////////////////////////////////////////////////////////////// +// CTTStatic + +#ifndef WIN32_PLATFORM_WFSP // Tooltips not supported on SmartPhone + +template +class CTTStaticT : public TBase +{ +public: +// Constructors + CTTStaticT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CTTStaticT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + HWND hWnd = TBase::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + ATLASSERT(hWnd != NULL); // Did you remember to call SHInitExtraControls() ?? + return hWnd; + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_TSTATIC; + } + +// Operations + BOOL SetToolTipText(LPCTSTR pstrTipText) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pstrTipText); + ATLASSERT(lstrlen(pstrTipText) <= 253); + CTempBuffer buff; + int cchLen = lstrlen(pstrTipText) + 3; + LPTSTR pstr = buff.Allocate(cchLen); + if(pstr == NULL) + return FALSE; + SecureHelper::strcpy_x(pstr, cchLen, _T("~~")); + SecureHelper::strcat_x(pstr, cchLen, pstrTipText); + return SetWindowText(pstr); + } +}; + +typedef CTTStaticT CTTStatic; + + +/////////////////////////////////////////////////////////////////////////////// +// CTTButton + +template +class CTTButtonT : public TBase +{ +public: +// Constructors + CTTButtonT(HWND hWnd = NULL) : TBase(hWnd) + { } + + CTTButtonT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + HWND hWnd = TBase::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); + ATLASSERT(hWnd != NULL); // Did you remember to call SHInitExtraControls() ?? + return hWnd; + } + +// Attributes + static LPCTSTR GetWndClassName() + { + return WC_TBUTTON; + } + +// Operations + BOOL SetToolTipText(LPCTSTR pstrTipText) + { + ATLASSERT(::IsWindow(m_hWnd)); + ATLASSERT(pstrTipText); + ATLASSERT(lstrlen(pstrTipText) <= 253); + CTempBuffer buff; + int cchLen = lstrlen(pstrTipText) + 3; + LPTSTR pstr = buff.Allocate(cchLen); + if(pstr == NULL) + return FALSE; + SecureHelper::strcpy_x(pstr, cchLen, _T("~~")); + SecureHelper::strcat_x(pstr, cchLen, pstrTipText); + return SetWindowText(pstr); + } +}; + +typedef CTTButtonT CTTButton; + +#endif // !WIN32_PLATFORM_WFSP + + +// --- SmartPhone specific controls --- + +#ifdef WIN32_PLATFORM_WFSP + +/////////////////////////////////////////////////////////////////////////////// +// CSpinCtrlT - CSpinCtrl : SmartPhone adapted UpDown control + +template +class CSpinCtrlT : public CUpDownCtrlT< TBase > +{ +public: +// Constructors + CSpinCtrlT(HWND hWnd = NULL) : CUpDownCtrlT< TBase >(hWnd) + { } + + CSpinCtrlT< TBase >& operator =(HWND hWnd) + { + m_hWnd = hWnd; + return *this; + } + + HWND Create(HWND hWndParent, HWND hBuddy, DWORD dwStyle, int nID, LPCTSTR szExpandedName = NULL) + { + ATLASSERT(::IsWindow(hWndParent)); + CUpDownCtrlT< TBase >::Create(hWndParent, NULL, szExpandedName, dwStyle, 0, nID, NULL); + ATLASSERT(m_hWnd != NULL); // Did you remember to call AtlInitCommonControls(ICC_UPDOWN_CLASS)? + if (hBuddy != NULL) + { + ATLASSERT(::IsWindow(hBuddy)); + SetBuddy(hBuddy); + } + return m_hWnd; + } +}; + +typedef CSpinCtrlT CSpinCtrl; + + +/////////////////////////////////////////////////////////////////////////////// +// CSpinned - SmartPhone association of control and Spin + +template +class CSpinned : public TBase +{ +public: + CSpinCtrl m_SpinCtrl; + DWORD m_dwSpinnedStyle; + +// Constructors + CSpinned(HWND hWnd = NULL) : TBase(hWnd) + { + m_dwSpinnedStyle = WS_VISIBLE | UDS_ALIGNRIGHT | UDS_EXPANDABLE; + + if (t_bExpandOnly == true) + m_dwSpinnedStyle |= UDS_NOSCROLL; + else + m_dwSpinnedStyle |= UDS_HORZ | UDS_ARROWKEYS | UDS_SETBUDDYINT | UDS_WRAP; + + if (hWnd != NULL) + AttachOrCreateSpinCtrl(); + } + + CSpinned& operator =(HWND hWnd) + { + Attach(hWnd); + return *this; + } + + void Attach(HWND hWnd) + { + ATLASSERT(!IsWindow()); + TBase* pT = static_cast(this); + pT->m_hWnd = hWnd; + if (hWnd != NULL) + AttachOrCreateSpinCtrl(); + } + + HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szExpandedName = NULL, + DWORD dwStyle = 0, DWORD dwExStyle = 0, + ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) + { + + TBase* pT = static_cast(this); + TBase::Create(hWndParent, rect, NULL, dwStyle, dwExStyle, MenuOrID, lpCreateParam); + ATLASSERT(pT->m_hWnd != NULL); + + m_SpinCtrl.Create(hWndParent, pT->m_hWnd, m_dwSpinnedStyle, ATL_IDW_SPIN_ID + (int)MenuOrID.m_hMenu, szExpandedName); + + ATLASSERT(m_SpinCtrl.m_hWnd != NULL); // Did you remember to call AtlInitCommonControls(ICC_UPDOWN_CLASS)? + + return pT->m_hWnd; + } + +// Attributes + CSpinCtrl& GetSpinCtrl() + { + return m_SpinCtrl; + } + +// Implementation + // Attach our existing SpinCtrl or create one + bool AttachOrCreateSpinCtrl() + { + TBase* pT = static_cast(this); + + HWND hSpin = ::GetDlgItem(pT->GetParent(), ATL_IDW_SPIN_ID + pT->GetDlgCtrlID()); + + if (hSpin != NULL) + { + m_SpinCtrl.Attach(hSpin); +#ifdef DEBUG + TCHAR sClassName[16]; + ::GetClassName(hSpin, sClassName, 16); + ATLASSERT(!_tcscmp(sClassName, UPDOWN_CLASS)); + ATLASSERT(m_SpinCtrl.GetBuddy().m_hWnd == pT->m_hWnd); +#endif // DEBUG + } + else + { + m_SpinCtrl.Create(pT->GetParent(), pT->m_hWnd, m_dwSpinnedStyle, ATL_IDW_SPIN_ID + pT->GetDlgCtrlID()); + } + + return m_SpinCtrl.m_hWnd != NULL; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// CSpinListBox - SmartPhone spinned ListBox control +// CExpandListBox - SmartPhone expandable ListBox control +// CExpandEdit - SmartPhone expandable Edit control +// CExpandCapEdit - SmartPhone expandable CapEdit control + +typedef CSpinned CSpinListBox; +typedef CSpinned CExpandListBox; +typedef CSpinned CExpandEdit; +typedef CSpinned CExpandCapEdit; + +#endif // WIN32_PLATFORM_WFSP + +#endif // _WTL_CE_NO_CONTROLS + +}; // namespace WTL + +#endif // __ATLWINCE_H__ diff --git a/plugins/!NotAdopted/SmartAutoReplier/wtl/atlwinx.h b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlwinx.h new file mode 100644 index 0000000000..629d29778f --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/wtl/atlwinx.h @@ -0,0 +1,525 @@ +// Windows Template Library - WTL version 8.1 +// Copyright (C) Microsoft Corporation. All rights reserved. +// +// This file is a part of the Windows Template Library. +// The use and distribution terms for this software are covered by the +// Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php) +// which can be found in the file CPL.TXT at the root of this distribution. +// By using this software in any fashion, you are agreeing to be bound by +// the terms of this license. You must not remove this notice, or +// any other, from this software. + +#ifndef __ATLWINX_H__ +#define __ATLWINX_H__ + +#pragma once + +#ifndef __ATLAPP_H__ + #error atlwinx.h requires atlapp.h to be included first +#endif + +#if (_ATL_VER >= 0x0700) + #include +#endif // (_ATL_VER >= 0x0700) + + +/////////////////////////////////////////////////////////////////////////////// +// Classes in this file: +// +// _U_RECT +// _U_MENUorID +// _U_STRINGorID + + +/////////////////////////////////////////////////////////////////////////////// +// Command Chaining Macros + +#define CHAIN_COMMANDS(theChainClass) \ + if(uMsg == WM_COMMAND) \ + CHAIN_MSG_MAP(theChainClass) + +#define CHAIN_COMMANDS_ALT(theChainClass, msgMapID) \ + if(uMsg == WM_COMMAND) \ + CHAIN_MSG_MAP_ALT(theChainClass, msgMapID) + +#define CHAIN_COMMANDS_MEMBER(theChainMember) \ + if(uMsg == WM_COMMAND) \ + CHAIN_MSG_MAP_MEMBER(theChainMember) + +#define CHAIN_COMMANDS_ALT_MEMBER(theChainMember, msgMapID) \ + if(uMsg == WM_COMMAND) \ + CHAIN_MSG_MAP_ALT_MEMBER(theChainMember, msgMapID) + + +/////////////////////////////////////////////////////////////////////////////// +// Macros for parent message map to selectively reflect control messages + +// NOTE: ReflectNotifications is a member of ATL's CWindowImplRoot +// (and overridden in 2 cases - CContainedWindowT and CAxHostWindow) +// Since we can't modify ATL, we'll provide the needed additions +// in a separate function (that is not a member of CWindowImplRoot) + +namespace WTL +{ + +inline LRESULT WtlReflectNotificationsFiltered(HWND hWndParent, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled, + UINT uMsgFilter = WM_NULL, UINT_PTR idFromFilter = 0, HWND hWndChildFilter = NULL) +{ + if((uMsgFilter != WM_NULL) && (uMsgFilter != uMsg)) + { + // The notification message doesn't match the filter. + bHandled = FALSE; + return 1; + } + + HWND hWndChild = NULL; + UINT_PTR idFrom = 0; + + switch(uMsg) + { + case WM_COMMAND: + if(lParam != NULL) // not from a menu + { + hWndChild = (HWND)lParam; + idFrom = (UINT_PTR)LOWORD(wParam); + } + break; + case WM_NOTIFY: + hWndChild = ((LPNMHDR)lParam)->hwndFrom; + idFrom = ((LPNMHDR)lParam)->idFrom; + break; +#ifndef _WIN32_WCE + case WM_PARENTNOTIFY: + switch(LOWORD(wParam)) + { + case WM_CREATE: + case WM_DESTROY: + hWndChild = (HWND)lParam; + idFrom = (UINT_PTR)HIWORD(wParam); + break; + default: + hWndChild = ::GetDlgItem(hWndParent, HIWORD(wParam)); + idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild); + break; + } + break; +#endif // !_WIN32_WCE + case WM_DRAWITEM: + if(wParam) // not from a menu + { + hWndChild = ((LPDRAWITEMSTRUCT)lParam)->hwndItem; + idFrom = (UINT_PTR)wParam; + } + break; + case WM_MEASUREITEM: + if(wParam) // not from a menu + { + hWndChild = ::GetDlgItem(hWndParent, ((LPMEASUREITEMSTRUCT)lParam)->CtlID); + idFrom = (UINT_PTR)wParam; + } + break; + case WM_COMPAREITEM: + if(wParam) // not from a menu + { + hWndChild = ((LPCOMPAREITEMSTRUCT)lParam)->hwndItem; + idFrom = (UINT_PTR)wParam; + } + break; + case WM_DELETEITEM: + if(wParam) // not from a menu + { + hWndChild = ((LPDELETEITEMSTRUCT)lParam)->hwndItem; + idFrom = (UINT_PTR)wParam; + } + break; + case WM_VKEYTOITEM: + case WM_CHARTOITEM: + case WM_HSCROLL: + case WM_VSCROLL: + hWndChild = (HWND)lParam; + idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild); + break; + case WM_CTLCOLORBTN: + case WM_CTLCOLORDLG: + case WM_CTLCOLOREDIT: + case WM_CTLCOLORLISTBOX: + case WM_CTLCOLORMSGBOX: + case WM_CTLCOLORSCROLLBAR: + case WM_CTLCOLORSTATIC: + hWndChild = (HWND)lParam; + idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild); + break; + default: + break; + } + + if((hWndChild == NULL) || + ((hWndChildFilter != NULL) && (hWndChildFilter != hWndChild))) + { + // Either hWndChild isn't valid, or + // hWndChild doesn't match the filter. + bHandled = FALSE; + return 1; + } + + if((idFromFilter != 0) && (idFromFilter != idFrom)) + { + // The dialog control id doesn't match the filter. + bHandled = FALSE; + return 1; + } + + ATLASSERT(::IsWindow(hWndChild)); + LRESULT lResult = ::SendMessage(hWndChild, OCM__BASE + uMsg, wParam, lParam); + if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC)) + { + // Try to prevent problems with WM_CTLCOLOR* messages when + // the message wasn't really handled + bHandled = FALSE; + } + + return lResult; +} + +}; // namespace WTL + +// Try to prevent problems with WM_CTLCOLOR* messages when +// the message wasn't really handled +#define REFLECT_NOTIFICATIONS_EX() \ +{ \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC)) \ + bHandled = FALSE; \ + if(bHandled) \ + return TRUE; \ +} + +#define REFLECT_NOTIFICATIONS_MSG_FILTERED(uMsgFilter) \ + { \ + bHandled = TRUE; \ + lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, NULL); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFICATIONS_ID_FILTERED(idFromFilter) \ + { \ + bHandled = TRUE; \ + lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, idFromFilter, NULL); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFICATIONS_HWND_FILTERED(hWndChildFilter) \ + { \ + bHandled = TRUE; \ + lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, 0, hWndChildFilter); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFICATIONS_MSG_ID_FILTERED(uMsgFilter, idFromFilter) \ + { \ + bHandled = TRUE; \ + lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, idFromFilter, NULL); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFICATIONS_MSG_HWND_FILTERED(uMsgFilter, hWndChildFilter) \ + { \ + bHandled = TRUE; \ + lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, hWndChildFilter); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_COMMAND(id, code) \ + if(uMsg == WM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_COMMAND_ID(id) \ + if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_COMMAND_CODE(code) \ + if(uMsg == WM_COMMAND && code == HIWORD(wParam)) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_COMMAND_RANGE(idFirst, idLast) \ + if(uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_COMMAND_RANGE_CODE(idFirst, idLast, code) \ + if(uMsg == WM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFY(id, cd) \ + if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFY_ID(id) \ + if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFY_CODE(cd) \ + if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFY_RANGE(idFirst, idLast) \ + if(uMsg == WM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECT_NOTIFY_RANGE_CODE(idFirst, idLast, cd) \ + if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ + { \ + bHandled = TRUE; \ + lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + + +/////////////////////////////////////////////////////////////////////////////// +// Reflected message handler macros for message maps (for ATL 3.0) + +#if (_ATL_VER < 0x0700) + +#define REFLECTED_COMMAND_HANDLER(id, code, func) \ + if(uMsg == OCM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \ + { \ + bHandled = TRUE; \ + lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_COMMAND_ID_HANDLER(id, func) \ + if(uMsg == OCM_COMMAND && id == LOWORD(wParam)) \ + { \ + bHandled = TRUE; \ + lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_COMMAND_CODE_HANDLER(code, func) \ + if(uMsg == OCM_COMMAND && code == HIWORD(wParam)) \ + { \ + bHandled = TRUE; \ + lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_COMMAND_RANGE_HANDLER(idFirst, idLast, func) \ + if(uMsg == OCM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ + { \ + bHandled = TRUE; \ + lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_COMMAND_RANGE_CODE_HANDLER(idFirst, idLast, code, func) \ + if(uMsg == OCM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ + { \ + bHandled = TRUE; \ + lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_NOTIFY_HANDLER(id, cd, func) \ + if(uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \ + { \ + bHandled = TRUE; \ + lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_NOTIFY_ID_HANDLER(id, func) \ + if(uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \ + { \ + bHandled = TRUE; \ + lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_NOTIFY_CODE_HANDLER(cd, func) \ + if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \ + { \ + bHandled = TRUE; \ + lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_NOTIFY_RANGE_HANDLER(idFirst, idLast, func) \ + if(uMsg == OCM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ + { \ + bHandled = TRUE; \ + lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#define REFLECTED_NOTIFY_RANGE_CODE_HANDLER(idFirst, idLast, cd, func) \ + if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ + { \ + bHandled = TRUE; \ + lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +#endif // (_ATL_VER < 0x0700) + + +/////////////////////////////////////////////////////////////////////////////// +// Dual argument helper classes (for ATL 3.0) + +#if (_ATL_VER < 0x0700) + +namespace ATL +{ + +class _U_RECT +{ +public: + _U_RECT(LPRECT lpRect) : m_lpRect(lpRect) + { } + _U_RECT(RECT& rc) : m_lpRect(&rc) + { } + LPRECT m_lpRect; +}; + +class _U_MENUorID +{ +public: + _U_MENUorID(HMENU hMenu) : m_hMenu(hMenu) + { } + _U_MENUorID(UINT nID) : m_hMenu((HMENU)LongToHandle(nID)) + { } + HMENU m_hMenu; +}; + +class _U_STRINGorID +{ +public: + _U_STRINGorID(LPCTSTR lpString) : m_lpstr(lpString) + { } + _U_STRINGorID(UINT nID) : m_lpstr(MAKEINTRESOURCE(nID)) + { } + LPCTSTR m_lpstr; +}; + +}; // namespace ATL + +#endif // (_ATL_VER < 0x0700) + + +namespace WTL +{ + +/////////////////////////////////////////////////////////////////////////////// +// Forward notifications support for message maps (for ATL 3.0) + +#if (_ATL_VER < 0x0700) + +// forward notifications support +#define FORWARD_NOTIFICATIONS() \ + { \ + bHandled = TRUE; \ + lResult = WTL::Atl3ForwardNotifications(m_hWnd, uMsg, wParam, lParam, bHandled); \ + if(bHandled) \ + return TRUE; \ + } + +static LRESULT Atl3ForwardNotifications(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + LRESULT lResult = 0; + switch(uMsg) + { + case WM_COMMAND: + case WM_NOTIFY: +#ifndef _WIN32_WCE + case WM_PARENTNOTIFY: +#endif // !_WIN32_WCE + case WM_DRAWITEM: + case WM_MEASUREITEM: + case WM_COMPAREITEM: + case WM_DELETEITEM: + case WM_VKEYTOITEM: + case WM_CHARTOITEM: + case WM_HSCROLL: + case WM_VSCROLL: + case WM_CTLCOLORBTN: + case WM_CTLCOLORDLG: + case WM_CTLCOLOREDIT: + case WM_CTLCOLORLISTBOX: + case WM_CTLCOLORMSGBOX: + case WM_CTLCOLORSCROLLBAR: + case WM_CTLCOLORSTATIC: + lResult = ::SendMessage(::GetParent(hWnd), uMsg, wParam, lParam); + break; + default: + bHandled = FALSE; + break; + } + return lResult; +} + +#endif // (_ATL_VER < 0x0700) + +}; // namespace WTL + +#endif // __ATLWINX_H__ diff --git a/plugins/!NotAdopted/Tlen/codec/gsm.h b/plugins/!NotAdopted/Tlen/codec/gsm.h new file mode 100644 index 0000000000..fba1bcb1ac --- /dev/null +++ b/plugins/!NotAdopted/Tlen/codec/gsm.h @@ -0,0 +1,65 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is based on GSM 06.10 source code developed by +Jutta Degener and Carsten Bormann, +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#include + +#define P_MAX 8 /* order p of LPC analysis, typically 8..14 */ + +typedef struct { + int LARpp[2][8]; /* LAR coefficients for previous and current frame */ + int j; /* current frame index in LARpp[j][] */ + int qLARs[8]; /* quantized LARs for current frame */ + int u[8]; /* used by short term analysis filter */ + int v[9]; /* used by short term synthesis filter */ + int subframe; /* subframe index (0..3)*/ + short dp0[ 280 ]; /* previous short-term filter output/prediction, used by long term analysis*/ + int e[160]; /* errors (residuals) */ + int nrp; /* long term synthesis */ + int Nc[4], bc[4]; /* long-term lag and gain for current frame */ + int Mc[4]; /* RPE grid index (0..3) */ + int xMaxc[4]; /* RPE maximum error quantized and encoded (mantissa + exp) */ + int xMc[52]; /* quantized residuals (errors) 4 * 13 */ + + int z1; /* preprocessing.c, Offset_com. */ + int z2; /* Offset_com. */ + int mp; /* Preemphasis */ + int msr; /* decoder.c, Postprocessing */ + + unsigned char gsmFrame[33]; +}gsm_state; + +extern gsm_state * gsm_create() ; +extern void gsm_release(gsm_state *ptr); +extern void gsm_encode(gsm_state *state, short *in); +extern void gsm_decode(gsm_state *state, short *out); + +extern void gsm_preprocessing( gsm_state *state, short *in, short *out); +extern void shortTermAnalysis(gsm_state *state, short *in); +extern void longTermAnalysis(gsm_state *state, short *in); +extern void encodeRPE(gsm_state *state); +extern void decodeRPE(gsm_state *state); +extern void longTermSynthesis(gsm_state *state); +extern void shortTermSynthesis(gsm_state *state, short *in, short *out); +extern void gsm_postprocessing( gsm_state *state, short *in, short *out); diff --git a/plugins/!NotAdopted/Tlen/codec/gsm_codec.c b/plugins/!NotAdopted/Tlen/codec/gsm_codec.c new file mode 100644 index 0000000000..1d0a08a41e --- /dev/null +++ b/plugins/!NotAdopted/Tlen/codec/gsm_codec.c @@ -0,0 +1,283 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is based on GSM 06.10 source code developed by +Jutta Degener and Carsten Bormann, +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "gsm.h" +#include +#include +#include +#define GSM_MAGIC 0xD + +gsm_state * gsm_create() +{ + gsm_state * state = (gsm_state *)malloc(sizeof(gsm_state)); + memset(state, 0, sizeof(gsm_state)); + state->nrp = 40; + return state; +} + +void gsm_release(gsm_state *ptr) +{ + free(ptr); +} + +void gsm_encode(gsm_state *state, short *in) +{ int i, j; + unsigned char *c = state->gsmFrame; + short temp_in[160]; + + gsm_preprocessing(state, in, temp_in); + shortTermAnalysis(state, temp_in); + for (i = 0; i < 4; i++) { + state->subframe = i; + longTermAnalysis(state, temp_in + 40 * i); + encodeRPE(state); + for (j = 0; j < 40; j++) { + int ii = (int) state->dp0[120 + i * 40 + j] + state->e[i * 40 + j]; + if (ii<-32768) ii = -32768; + else if (ii>32767) ii=32767; + state->dp0[120 + i * 40 + j] = ii; + } + } + memcpy(state->dp0, state->dp0 + 160, 120 * sizeof(short)); + state->j ^= 1; + *c++ = ((GSM_MAGIC & 0xF) << 4) + | ((state->qLARs[0] >> 2) & 0xF); + *c++ = ((state->qLARs[0] & 0x3) << 6) + | (state->qLARs[1] & 0x3F); + *c++ = ((state->qLARs[2] & 0x1F) << 3) + | ((state->qLARs[3] >> 2) & 0x7); + *c++ = ((state->qLARs[3] & 0x3) << 6) + | ((state->qLARs[4] & 0xF) << 2) + | ((state->qLARs[5] >> 2) & 0x3); + *c++ = ((state->qLARs[5] & 0x3) << 6) + | ((state->qLARs[6] & 0x7) << 3) + | (state->qLARs[7] & 0x7); + *c++ = ((state->Nc[0] & 0x7F) << 1) + | ((state->bc[0] >> 1) & 0x1); + *c++ = ((state->bc[0] & 0x1) << 7) + | ((state->Mc[0] & 0x3) << 5) + | ((state->xMaxc[0] >> 1) & 0x1F); + *c++ = ((state->xMaxc[0] & 0x1) << 7) + | ((state->xMc[0] & 0x7) << 4) + | ((state->xMc[1] & 0x7) << 1) + | ((state->xMc[2] >> 2) & 0x1); + *c++ = ((state->xMc[2] & 0x3) << 6) + | ((state->xMc[3] & 0x7) << 3) + | (state->xMc[4] & 0x7); + *c++ = ((state->xMc[5] & 0x7) << 5) + | ((state->xMc[6] & 0x7) << 2) + | ((state->xMc[7] >> 1) & 0x3); + *c++ = ((state->xMc[7] & 0x1) << 7) + | ((state->xMc[8] & 0x7) << 4) + | ((state->xMc[9] & 0x7) << 1) + | ((state->xMc[10] >> 2) & 0x1); + *c++ = ((state->xMc[10] & 0x3) << 6) + | ((state->xMc[11] & 0x7) << 3) + | (state->xMc[12] & 0x7); + *c++ = ((state->Nc[1] & 0x7F) << 1) + | ((state->bc[1] >> 1) & 0x1); + *c++ = ((state->bc[1] & 0x1) << 7) + | ((state->Mc[1] & 0x3) << 5) + | ((state->xMaxc[1] >> 1) & 0x1F); + *c++ = ((state->xMaxc[1] & 0x1) << 7) + | ((state->xMc[13] & 0x7) << 4) + | ((state->xMc[14] & 0x7) << 1) + | ((state->xMc[15] >> 2) & 0x1); + *c++ = ((state->xMc[15] & 0x3) << 6) + | ((state->xMc[16] & 0x7) << 3) + | (state->xMc[17] & 0x7); + *c++ = ((state->xMc[18] & 0x7) << 5) + | ((state->xMc[19] & 0x7) << 2) + | ((state->xMc[20] >> 1) & 0x3); + *c++ = ((state->xMc[20] & 0x1) << 7) + | ((state->xMc[21] & 0x7) << 4) + | ((state->xMc[22] & 0x7) << 1) + | ((state->xMc[23] >> 2) & 0x1); + *c++ = ((state->xMc[23] & 0x3) << 6) + | ((state->xMc[24] & 0x7) << 3) + | (state->xMc[25] & 0x7); + *c++ = ((state->Nc[2] & 0x7F) << 1) + | ((state->bc[2] >> 1) & 0x1); + *c++ = ((state->bc[2] & 0x1) << 7) + | ((state->Mc[2] & 0x3) << 5) + | ((state->xMaxc[2] >> 1) & 0x1F); + *c++ = ((state->xMaxc[2] & 0x1) << 7) + | ((state->xMc[26] & 0x7) << 4) + | ((state->xMc[27] & 0x7) << 1) + | ((state->xMc[28] >> 2) & 0x1); + *c++ = ((state->xMc[28] & 0x3) << 6) + | ((state->xMc[29] & 0x7) << 3) + | (state->xMc[30] & 0x7); + *c++ = ((state->xMc[31] & 0x7) << 5) + | ((state->xMc[32] & 0x7) << 2) + | ((state->xMc[33] >> 1) & 0x3); + *c++ = ((state->xMc[33] & 0x1) << 7) + | ((state->xMc[34] & 0x7) << 4) + | ((state->xMc[35] & 0x7) << 1) + | ((state->xMc[36] >> 2) & 0x1); + *c++ = ((state->xMc[36] & 0x3) << 6) + | ((state->xMc[37] & 0x7) << 3) + | (state->xMc[38] & 0x7); + *c++ = ((state->Nc[3] & 0x7F) << 1) + | ((state->bc[3] >> 1) & 0x1); + *c++ = ((state->bc[3] & 0x1) << 7) + | ((state->Mc[3] & 0x3) << 5) + | ((state->xMaxc[3] >> 1) & 0x1F); + *c++ = ((state->xMaxc[3] & 0x1) << 7) + | ((state->xMc[39] & 0x7) << 4) + | ((state->xMc[40] & 0x7) << 1) + | ((state->xMc[41] >> 2) & 0x1); + *c++ = ((state->xMc[41] & 0x3) << 6) + | ((state->xMc[42] & 0x7) << 3) + | (state->xMc[43] & 0x7); + *c++ = ((state->xMc[44] & 0x7) << 5) + | ((state->xMc[45] & 0x7) << 2) + | ((state->xMc[46] >> 1) & 0x3); + *c++ = ((state->xMc[46] & 0x1) << 7) + | ((state->xMc[47] & 0x7) << 4) + | ((state->xMc[48] & 0x7) << 1) + | ((state->xMc[49] >> 2) & 0x1); + *c++ = ((state->xMc[49] & 0x3) << 6) + | ((state->xMc[50] & 0x7) << 3) + | (state->xMc[51] & 0x7); +} + +void gsm_decode(gsm_state *state, short *out) +{ + int i; + unsigned char *c = state->gsmFrame; + + if (((*c >> 4) & 0x0F) != GSM_MAGIC) return ; + state->qLARs[0] = (*c++ & 0xF) << 2; + state->qLARs[0] |= (*c >> 6) & 0x3; + state->qLARs[1] = *c++ & 0x3F; + state->qLARs[2] = (*c >> 3) & 0x1F; + state->qLARs[3] = (*c++ & 0x7) << 2; + state->qLARs[3] |= (*c >> 6) & 0x3; + state->qLARs[4] = (*c >> 2) & 0xF; + state->qLARs[5] = (*c++ & 0x3) << 2; + state->qLARs[5] |= (*c >> 6) & 0x3; + state->qLARs[6] = (*c >> 3) & 0x7; + state->qLARs[7] = *c++ & 0x7; + state->Nc[0] = (*c >> 1) & 0x7F; + state->bc[0] = (*c++ & 0x1) << 1; + state->bc[0] |= (*c >> 7) & 0x1; + state->Mc[0] = (*c >> 5) & 0x3; + state->xMaxc[0] = (*c++ & 0x1F) << 1; + state->xMaxc[0] |= (*c >> 7) & 0x1; + state->xMc[0] = (*c >> 4) & 0x7; + state->xMc[1] = (*c >> 1) & 0x7; + state->xMc[2] = (*c++ & 0x1) << 2; + state->xMc[2] |= (*c >> 6) & 0x3; + state->xMc[3] = (*c >> 3) & 0x7; + state->xMc[4] = *c++ & 0x7; + state->xMc[5] = (*c >> 5) & 0x7; + state->xMc[6] = (*c >> 2) & 0x7; + state->xMc[7] = (*c++ & 0x3) << 1; + state->xMc[7] |= (*c >> 7) & 0x1; + state->xMc[8] = (*c >> 4) & 0x7; + state->xMc[9] = (*c >> 1) & 0x7; + state->xMc[10] = (*c++ & 0x1) << 2; + state->xMc[10] |= (*c >> 6) & 0x3; + state->xMc[11] = (*c >> 3) & 0x7; + state->xMc[12] = *c++ & 0x7; + state->Nc[1] = (*c >> 1) & 0x7F; + state->bc[1] = (*c++ & 0x1) << 1; + state->bc[1] |= (*c >> 7) & 0x1; + state->Mc[1] = (*c >> 5) & 0x3; + state->xMaxc[1] = (*c++ & 0x1F) << 1; + state->xMaxc[1] |= (*c >> 7) & 0x1; + state->xMc[13] = (*c >> 4) & 0x7; + state->xMc[14] = (*c >> 1) & 0x7; + state->xMc[15] = (*c++ & 0x1) << 2; + state->xMc[15] |= (*c >> 6) & 0x3; + state->xMc[16] = (*c >> 3) & 0x7; + state->xMc[17] = *c++ & 0x7; + state->xMc[18] = (*c >> 5) & 0x7; + state->xMc[19] = (*c >> 2) & 0x7; + state->xMc[20] = (*c++ & 0x3) << 1; + state->xMc[20] |= (*c >> 7) & 0x1; + state->xMc[21] = (*c >> 4) & 0x7; + state->xMc[22] = (*c >> 1) & 0x7; + state->xMc[23] = (*c++ & 0x1) << 2; + state->xMc[23] |= (*c >> 6) & 0x3; + state->xMc[24] = (*c >> 3) & 0x7; + state->xMc[25] = *c++ & 0x7; + state->Nc[2] = (*c >> 1) & 0x7F; + state->bc[2] = (*c++ & 0x1) << 1; + state->bc[2] |= (*c >> 7) & 0x1; + state->Mc[2] = (*c >> 5) & 0x3; + state->xMaxc[2] = (*c++ & 0x1F) << 1; + state->xMaxc[2] |= (*c >> 7) & 0x1; + state->xMc[26] = (*c >> 4) & 0x7; + state->xMc[27] = (*c >> 1) & 0x7; + state->xMc[28] = (*c++ & 0x1) << 2; + state->xMc[28] |= (*c >> 6) & 0x3; + state->xMc[29] = (*c >> 3) & 0x7; + state->xMc[30] = *c++ & 0x7; + state->xMc[31] = (*c >> 5) & 0x7; + state->xMc[32] = (*c >> 2) & 0x7; + state->xMc[33] = (*c++ & 0x3) << 1; + state->xMc[33] |= (*c >> 7) & 0x1; + state->xMc[34] = (*c >> 4) & 0x7; + state->xMc[35] = (*c >> 1) & 0x7; + state->xMc[36] = (*c++ & 0x1) << 2; + state->xMc[36] |= (*c >> 6) & 0x3; + state->xMc[37] = (*c >> 3) & 0x7; + state->xMc[38] = *c++ & 0x7; + state->Nc[3] = (*c >> 1) & 0x7F; + state->bc[3] = (*c++ & 0x1) << 1; + state->bc[3] |= (*c >> 7) & 0x1; + state->Mc[3] = (*c >> 5) & 0x3; + state->xMaxc[3] = (*c++ & 0x1F) << 1; + state->xMaxc[3] |= (*c >> 7) & 0x1; + state->xMc[39] = (*c >> 4) & 0x7; + state->xMc[40] = (*c >> 1) & 0x7; + state->xMc[41] = (*c++ & 0x1) << 2; + state->xMc[41] |= (*c >> 6) & 0x3; + state->xMc[42] = (*c >> 3) & 0x7; + state->xMc[43] = *c++ & 0x7; + state->xMc[44] = (*c >> 5) & 0x7; + state->xMc[45] = (*c >> 2) & 0x7; + state->xMc[46] = (*c++ & 0x3) << 1; + state->xMc[46] |= (*c >> 7) & 0x1; + state->xMc[47] = (*c >> 4) & 0x7; + state->xMc[48] = (*c >> 1) & 0x7; + state->xMc[49] = (*c++ & 0x1) << 2; + state->xMc[49] |= (*c >> 6) & 0x3; + state->xMc[50] = (*c >> 3) & 0x7; + state->xMc[51] = *c & 0x7; + + for (i = 0; i < 4; i++) { + state->subframe = i; + decodeRPE(state); + longTermSynthesis(state); + } + memcpy(state->dp0, state->dp0 + 160, 120 * sizeof(short)); + shortTermSynthesis(state, &state->dp0[120], out); + gsm_postprocessing(state, out, out); + state->j ^= 1; +} diff --git a/plugins/!NotAdopted/Tlen/codec/gsm_long.c b/plugins/!NotAdopted/Tlen/codec/gsm_long.c new file mode 100644 index 0000000000..7d9148061c --- /dev/null +++ b/plugins/!NotAdopted/Tlen/codec/gsm_long.c @@ -0,0 +1,183 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is based on GSM 06.10 source code developed by +Jutta Degener and Carsten Bormann, +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#include "gsm.h" +#include +#include +#include + +/* Decision levels */ +const static int gsm_DLB[4] = { 6554, 16384, 26214, 32767 }; +/* Quantization levels */ +const static int gsm_QLB[4] = { 3277, 11469, 21299, 32767 }; + +/* + * Long term parameters calculation - lag (Nc) and gain (bc). + */ +static void longTermLTPCalculation(gsm_state *state, short *in, short *in_1) +{ + int k, lambda; + int Nc, bc; + float in_1_float_base[120], * in_1_float = in_1_float_base + 120; + float in_float[40]; + float L_result, L_max, L_power; + + for (k = -120; k < 0; k++) in_1_float[k] = (float)in_1[k]; + for (k = 0; k < 40; k++) in_float[k] = (float)in[k]; + + /* Search for the maximum cross-correlation and coding of the LTP lag */ + + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda < 121; lambda++) { + for (L_result = 0, L_power = 0, k = 0; k < 40; k++) { + L_result += in_float[k] * in_1_float[k - lambda]; +// L_power += in_1_float[k - lambda] * in_1_float[k - lambda]; + } +// L_result = L_result / L_power; + if (L_result > L_max) { + Nc = lambda; + L_max = L_result; + } + } + state->Nc[state->subframe] = Nc; + if (L_max <= 0.) { + state->bc[state->subframe] = 0; + return; + } + /* Compute the power of the reconstructed short term residual signal dp[..] */ + in_1_float -= Nc; + L_power = 0; + for (k = 0; k < 40; k++) { + float f = in_1_float[k]; + L_power += f * f; + } + if (L_max >= L_power) { //1.0 + state->bc[state->subframe] = 3; + return; + } + /* Coding of the LTP gain + * Table gsm_DLB must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ +// lambda = L_max * 32768.; + lambda = (int)(L_max * 32768. / L_power); + for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break; + state->bc[state->subframe] = bc; +} + +/* + * Here we decode the bc parameter and compute samples of the estimate out[0..39]. + * The decoding of bc needs the gsm_QLB table. + * The long term residual signal e[0..39] is then calculated to be fed to the + * RPE encoding section. + */ +static void longTermAnalysisFilter(int Nc, int bc, short *in, short *in_1, short *out, int *e) +{ + int gain, k, l; + gain = gsm_QLB[bc]; + for (k = 0; k < 40; k++) { + l = (gain * (int)in_1[k - Nc] + 16384) >> 15; + if (l < -32768) l = -32768; + else if (l > 32767) l = 32767; + out[k] = l; + e[k] = in[k] - l; + } +} + +/* + * This procedure uses the bcr and Ncr parameter to realize the + * long term synthesis filtering. The decoding of bcr needs table gsm_QLB. + */ +static void longTermSynthesisFilter(gsm_state * state, int Ncr, int bcr, int *e, short *out) +{ + int k; + int brp, Nr; + + /* Check the limits of Nr. */ + Nr = Ncr < 40 || Ncr > 120 ? state->nrp : Ncr; + state->nrp = Nr; + /* Decoding of the LTP gain bcr */ + brp = gsm_QLB[ bcr ]; + + /* Computation of the reconstructed short term residual + * signal drp[0..39] + */ + for (k = 0; k < 40; k++) { + int temp = (brp * (int)out[ k-Nr ] + 16384) >> 15; + out[k] = e[k] + temp; + } +} + +/* + * This procedure performs long term analysis. + */ +void longTermAnalysis(gsm_state *state, short *in) +{ + short *in_1 = state->dp0 + 120 + state->subframe * 40; + short *out = state->dp0 + 120 + state->subframe * 40; + int *e = state->e + state->subframe * 40; +/* + + int i; + printf("Long-term in: \n"); + for (i=0;i<40;i++) { + printf("%7d ", in[i]); + } + printf("\n"); + */ + longTermLTPCalculation(state, in, in_1); + /* printf("Nc: %d, bc: %d \n", state->Nc[state->subframe], state->bc[state->subframe]); + */ + longTermAnalysisFilter(state->Nc[state->subframe], state->bc[state->subframe], in, in_1, out, e); +/* + printf("Long-term out: \n"); + for (i=0;i<40;i++) { + printf("%7d ", out[i]); + } + printf("\n"); + */ +} + +/* + * This procedure performs long term synthesis. + */ +void longTermSynthesis(gsm_state *state) +{ + int Nc = state->Nc[state->subframe]; + int bc = state->bc[state->subframe]; + int *e = state->e + state->subframe * 40; + short *out = state->dp0 + 120 + state->subframe * 40; + //int i; + longTermSynthesisFilter(state, Nc, bc, e, out); + /* + printf("Long-term reconstructed: \n"); + for (i=0;i<160;i++) { + printf("%7d ", state->dp0[i]); + } + printf("\n"); + */ +} diff --git a/plugins/!NotAdopted/Tlen/codec/gsm_lpc.c b/plugins/!NotAdopted/Tlen/codec/gsm_lpc.c new file mode 100644 index 0000000000..519612baff --- /dev/null +++ b/plugins/!NotAdopted/Tlen/codec/gsm_lpc.c @@ -0,0 +1,208 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is based on GSM 06.10 source code developed by +Jutta Degener and Carsten Bormann, +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +/* LPC- and Reflection Coefficients + * The next two functions calculate linear prediction coefficients + * and/or the related reflection coefficients from the first P_MAX+1 + * values of the autocorrelation function. + */ +#include "gsm.h" /* for P_MAX */ +#include +#include +#include + +/* Compute the autocorrelation + * ,--, + * ac(l) = > x(i) * x(i-l) for all i + * `--' + * for lags l between 0 and lag-1, and x(i) == 0 for i < 0 or i >= n + * @param n: number of samples + * @param lax: max lag (order) + * @param in: [0...n-1] samples x + * @param out: [0...lag-1] autocorrelation + */ +static void autocorrelation(int n, float const *x, int lag, float *ac) +{ + float d; + int i, j; + for (j = 0; j < lag; j++) { + for (i = j, d = 0; i < n; i++) d += x[i] * x[i-j]; + ac[j] = d; + } + d = (float)fabs(ac[0]); + if (d != 0) { + for (j = 0; j < lag; j++) ac[j] /= d; + } +} + +/* The Levinson-Durbin algorithm was invented by N. Levinson in 1947 + * and modified by J. Durbin in 1959. + * @param in: [0...p] autocorrelation values + * @param out: [0...p-1] reflection coefficients + * @param lpc: [0...p-1] LPC coefficients + * @return minimum mean square error + */ +/* +static float levinson_durbin (float const *ac, float *ref, float *lpc) +{ + int i, j; + float r, error = ac[0]; + + if (ac[0] == 0) { + for (i = 0; i < P_MAX; i++) ref[i] = 0; + return 0; + } + + for (i = 0; i < P_MAX; i++) { + + r = -ac[i + 1]; + for (j = 0; j < i; j++) r -= lpc[j] * ac[i - j]; + ref[i] = r /= error; + + // Update LPC coefficients and total error. + lpc[i] = r; + for (j = 0; j < i / 2; j++) { + float tmp = lpc[j]; + lpc[j] = r * lpc[i - 1 - j]; + lpc[i - 1 - j] += r * tmp; + } + if (i % 2) lpc[j] += lpc[j] * r; + + error *= 1 - r * r; + } + return error; +} +*/ +/* I. Schur's recursion from 1917 is related to the Levinson-Durbin method, + * but faster on parallel architectures; where Levinson-Durbin would take time + * proportional to p * log(p), Schur only requires time proportional to p. The + * GSM coder uses an integer version of the Schur recursion. + * @param in: [0...p] autocorrelation values + * @param out: [0...p-1] reflection coefficients + * @return the minimum mean square error + */ +static float schur(float const *ac, float *ref) +{ + int i, m; + float error=ac[0], r, G[2][P_MAX]; + + if (ac[0] == 0.0) { + for (i = 0; i < P_MAX; i++) ref[i] = 0; + return 0; + } + + /* Initialize the rows of the generator matrix G to ac[1...p]. */ + for (i = 0; i < P_MAX; i++) G[0][i] = G[1][i] = ac[i + 1]; + + for (i = 0;;) { + /* Calculate this iteration's reflection coefficient and error. */ + ref[i] = r = -G[1][0] / error; + error += G[1][0] * r; + + if (++i >= P_MAX) return error; + + /* Update the generator matrix. Unlike Levinson-Durbin's summing of + * reflection coefficients, this loop could be executed in parallel + * by p processors in constant time. + */ + for (m = 0; m < P_MAX - i; m++) { + G[1][m] = G[1][m + 1] + r * G[0][m]; + G[0][m] = G[1][m + 1] * r + G[0][m]; + } + } +} + + + /* 0..7 IN/OUT */ +static void rToLAR(int *r) +/* + * The following scaling for r[..] and LAR[..] has been used: + * + * r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1. + * LAR[..] = integer( real_LAR[..] * 16384 ); + * with -1.625 <= real_LAR <= 1.625 + */ +{ + int temp; + int i; + + /* Computation of the LAR[0..7] from the r[0..7] + */ + for (i = 0; i < 8; i++) { + temp = abs(r[i]); //GSM_ABS(temp); + if (temp < 22118) { + temp >>= 1; + } else if (temp < 31130) { + temp -= 11059; + } else { + temp -= 26112; + temp <<= 2; + } + r[i] = r[i] < 0 ? -temp : temp; + } +} + +static void quantizeLARs(int *LARs, int *qLARs) +{ int qA[]={20480, 20480, 20480, 20480, 13964, 15360, 8534, 9036}; + int qB[]={0, 0, 2048, -2560, 94, -1792, -341, -1144}; + int qMin[]={-32, -32, -16, -16, -8, -8, -4, -4}; + int qMax[]={31, 31, 15, 15, 7, 7, 3, 3}; + int i; + for (i = 0; i < 8; i++) { + int temp; + temp = (((LARs[i] * qA[i]) >> 15) + qB[i] + 256) >> 9; + if (temp < qMin[i]) temp = 0; + else if (temp > qMax[i]) temp = qMax[i] - qMin[i]; + else temp = temp - qMin[i]; + qLARs[i] = temp; + } +} + +void lpcAnalysis(gsm_state *state, short *in) +{ float error; + float samples[160]; + float ac[9]; + float ref[8]; + int i; + int * qLARs = state->qLARs; + for (i = 0; i < 160; i++) { + samples[i] = in[i]; + } + autocorrelation(160, samples, 9, ac); + error=schur(ac, ref); + /* + printf("reff: "); + for (i=0;i<8;i++) { + printf("%5.5f ", ref[i]);//((float)i_lpc[i])/32768.0f); + } + printf("\n"); + */ + for (i = 0; i < 8; i++) { + qLARs[i] = (int) (32768 * ref[i]); + } + rToLAR(qLARs); + quantizeLARs(qLARs, qLARs); +} diff --git a/plugins/!NotAdopted/Tlen/codec/gsm_preprocess.c b/plugins/!NotAdopted/Tlen/codec/gsm_preprocess.c new file mode 100644 index 0000000000..b3d11bb7b1 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/codec/gsm_preprocess.c @@ -0,0 +1,103 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is based on GSM 06.10 source code developed by +Jutta Degener and Carsten Bormann, +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#include "gsm.h" +#include + +/* 4.2.0 .. 4.2.3 PREPROCESSING SECTION + * + * After A-law to linear conversion (or directly from the + * Ato D converter) the following scaling is assumed for + * input to the RPE-LTP algorithm: + * + * + * Where S is the sign bit, v a valid bit, and * a "don't care" bit. + * The original signal is called sop[..] + * + */ + + +void gsm_preprocessing( gsm_state *state, short *in, short *out) +{ + int z1 = state->z1; + int z2 = state->z2; + int mp = state->mp; + int so, s1; + int msp, lsp; + + int k = 160; + + while (k--) { + /* Downscaling of the input signal + * in: 0.1.....................12 + * S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.* + * out: 0.1................... 12 + * S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0 + */ + so = (*in >> 3) << 2; + in++; + /* 4.2.2 Offset compensation + * + * This part implements a high-pass filter and requires extended + * arithmetic precision for the recursive part of this filter. + * The input of this procedure is the array so[0...159] and the + * output the array sof[ 0...159 ]. + */ + /* Compute the non-recursive part + */ + s1 = (so - z1) << 15; + z1 = so; + msp = z2 >> 15; + lsp = z2 - (msp << 15); + s1 += ((lsp * 32735) + 16384) >> 15; + z2 = msp * 32735 + s1; + /* 4.2.3 Preemphasis + */ + msp = (-28180 * mp + 16384) >> 15; + mp = (z2 + 16384) >> 15; + *out++ = mp + msp; + } + state->z1 = z1; + state->z2 = z2; + state->mp = mp; +/* + printf("preprocessed: \n"); + for (k=0;k<160;k++) { + printf("%7d ", out[k]);//((float)i_lpc[i])/32768.0f); + } + printf("\n"); + */ +} + +void gsm_postprocessing( gsm_state *state, short *in, short *out) +{ + int k; + int msr = state->msr; + for (k = 160; k--; in++, out++) { + msr = *in + ((msr * 28180 + 16384) >>15); /* Deemphasis */ + *out = (msr + msr ) & 0xFFF8; /* Truncation & Upscaling */ + } + state->msr = msr; +} diff --git a/plugins/!NotAdopted/Tlen/codec/gsm_rpe.c b/plugins/!NotAdopted/Tlen/codec/gsm_rpe.c new file mode 100644 index 0000000000..ad7234e606 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/codec/gsm_rpe.c @@ -0,0 +1,248 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is based on GSM 06.10 source code developed by +Jutta Degener and Carsten Bormann, +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#include "gsm.h" +#include +#include +#include + +static const int gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 }; +static const int gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 }; +static const int gsm_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 }; +/* + * The coefficients of the weighting filter are stored in the gsm_H table. + * The following scaling is used: + * + * gsm_H[0..10] = integer( real_H[ 0..10] * 8192 ); + */ +static void weightingFilter (int *e, int *x) +{ + int L_result; + int k, i; + for (k = 0; k < 40; k++) { + L_result = 4096; + for (i = 0; i < 11; i++) { + int ix = i + k; + if (ix>4 && ix<45) L_result += e[ix - 5] * gsm_H[i]; + } + L_result >>= 13; + x[k] = (L_result < -32768 ? -32768 : (L_result > 32767 ? 32767 : L_result)); + } +} + +/* + * The signal x[0..39] is used to select the RPE grid which is + * represented by Mc. + */ +static void gridSelection( int *x, int *xM, int *Mc_out) +{ + int m, i; + int L_result, L_temp; + int EM, Mc; + + EM = 0; + Mc = 0; + + for (m = 0; m < 4; m++) { + L_result = 0; + for (i = 0; i < 13; i++) { + int temp = x[m + 3*i] >> 2; + L_temp = temp * temp << 1; + L_result += L_temp; + } + if (L_result > EM) { + Mc = m; + EM = L_result; + } + } + /* Down-sampling by a factor 3 to get the selected xM[0..12] + * RPE sequence. + */ + for (i = 0; i < 13; i ++) xM[i] = x[Mc + 3*i]; + *Mc_out = Mc; +} + +/* + * This procedure computes the reconstructed long term residual signal + * ep[0..39] for the LTP analysis filter. The inputs are the Mc + * which is the grid position selection and the xMp[0..12] decoded + * RPE samples which are upsampled by a factor of 3 by inserting zero + * values. + */ +static void gridPositioning (int Mc, int *xMp, int *ep) +{ + int i, k; + for (k = 0; k < 40; k++) ep[k] = 0; + for (i = 0; i < 13; i++) { + ep[ Mc + (3*i) ] = xMp[i]; + } +} + +static void APCMXmaxcToExpMant (int xmaxc, int *exp_out, int *mant_out ) +{ + int exp, mant; + /* Compute exponent and mantissa of the decoded version of xmaxc + */ + exp = 0; + if (xmaxc > 15) exp = (xmaxc >> 3) - 1; + mant = xmaxc - (exp << 3); + + if (mant == 0) { + exp = -4; + mant = 7; + } + else { + while (mant < 8) { + mant = mant << 1 | 1; + exp--; + } + mant -= 8; + } + + *exp_out = exp; + *mant_out = mant; +} + +static void APCMQuantization (int *xM, int *xMc, int *mant_out, int *exp_out, int *xmaxc_out) +{ + int i, itest; + int xmax, xmaxc, temp, temp1, temp2; + int exp, mant; + + + /* Find the maximum absolute value xmax of xM[0..12]. + */ + + xmax = 0; + for (i = 0; i < 13; i++) { + temp = abs(xM[i]); + if (temp > xmax) xmax = temp; + } + if (xmax > 32767) xmax = 32767; + /* Qantizing and coding of xmax to get xmaxc. + */ + + exp = 0; + temp = xmax >> 9; + itest = 0; + + for (i = 0; i < 6; i++) { + if (temp != 0) exp++; + temp = temp >> 1; + } + + temp = exp + 5; + + xmaxc = (xmax >> temp) + (exp << 3); + + /* Quantizing and coding of the xM[0..12] RPE sequence + * to get the xMc[0..12] + */ + APCMXmaxcToExpMant( xmaxc, &exp, &mant ); + + /* This computation uses the fact that the decoded version of xmaxc + * can be calculated by using the exponent and the mantissa part of + * xmaxc (logarithmic table). + * So, this method avoids any division and uses only a scaling + * of the RPE samples by a function of the exponent. A direct + * multiplication by the inverse of the mantissa (NRFAC[0..7] + * found in table 4.5) gives the 3 bit coded version xMc[0..12] + * of the RPE samples. + */ + + /* Direct computation of xMc[0..12] using table 4.5 + */ + temp = (mant|8)<<(5+exp); + temp1 = 6 - exp; + temp2 = gsm_NRFAC[ mant ]; + for (i = 0; i < 13; i++) { + xMc[i] = ((xM[i] << temp1) * temp2 >> 27) + 4; + } + + /* NOTE: This equation is used to make all the xMc[i] positive. + */ + + *mant_out = mant; + *exp_out = exp; + *xmaxc_out = xmaxc; +} + +static void APCMDequantization (int *xMc, int mant, int exp, int *xMp) +{ + int i, temp1, temp2, temp3; + temp1 = gsm_FAC[ mant ]; + temp2 = 6 - exp; + if (temp2 <= 0) { + temp3 = 1 >> (1 - temp2); + } else { + temp3 = 1 << (temp2 - 1); + } + for (i = 0; i < 13; i++) { + xMp[i] = ((((((xMc[i]<<1)-7)<<12)*temp1+16384)>>15)+temp3)>>temp2; + } +} + +void encodeRPE(gsm_state *state) +{ int x[40]; + int xM[13], xMp[13]; + int mant, exp; + int *Mc = state->Mc + state->subframe; + int *xMaxc = state->xMaxc + state->subframe; + int *xMc = state->xMc + state->subframe * 13; + int *e = state->e + state->subframe * 40; + //int i; + /* + printf("RPE in: \n"); + for (i=0;i<40;i++) { + printf("%7d ", e[i]); + } + printf("\n"); + */ + weightingFilter(e, x); + /* + printf("RPE weighting filter: \n"); + for (i=0;i<40;i++) { + printf("%7d ", x[i]); + } + printf("\n"); + */ + gridSelection(x, xM, Mc); + APCMQuantization(xM, xMc, &mant, &exp, xMaxc); + /* printf("RPE Mc(grid #)=%d xmaxc=%d mant=%d exp=%d \n", *Mc, *xMaxc, mant, exp); */ + APCMDequantization(xMc, mant, exp, xMp); + gridPositioning(*Mc, xMp, e); +} + +void decodeRPE(gsm_state *state) +{ + int exp, mant; + int xMp[ 13 ]; + int *xMc = state->xMc + state->subframe * 13; + int *e = state->e + state->subframe * 40; + + APCMXmaxcToExpMant(state->xMaxc[state->subframe], &exp, &mant); + APCMDequantization(xMc, mant, exp, xMp); + gridPositioning(state->Mc[state->subframe], xMp, e); +} diff --git a/plugins/!NotAdopted/Tlen/codec/gsm_short.c b/plugins/!NotAdopted/Tlen/codec/gsm_short.c new file mode 100644 index 0000000000..c461484639 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/codec/gsm_short.c @@ -0,0 +1,211 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is based on GSM 06.10 source code developed by +Jutta Degener and Carsten Bormann, +Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, +Technische Universitaet Berlin + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#include "gsm.h" +#include +#include +#include +extern void lpcAnalysis(gsm_state *state, short *in); + +/* + * Dequantize LAR coefficients + */ +static void dequantizeLARs(int *qLARs, int *LARs) +{ + int dqA[]={13107, 13107, 13107, 13107, 19223, 17476, 31454, 29708}; + int dqB[]={0, 0, 2048, -2560, 94, -1792, -341, -1144}; + int dqMin[]={-32, -32, -16, -16, -8, -8, -4, -4}; + int i; + for (i = 0; i < 8; i++) { + int temp; + temp = ((((qLARs[i] + dqMin[i]) << 10) - (dqB[i] << 1)) * dqA[i] + 16384) >> 15; + LARs[i] = temp + temp; + } +} +/* + * Interpolate LAR coefficients (samples 0..12) + */ +static void interpolateLARs_0_12 (int *LARpp_j_1, int *LARpp_j, int *LARp) +{ int i; + for (i = 0; i < 8; i++) { + LARp[i] = (LARpp_j_1[i] >> 1) + (LARpp_j_1[i] >> 2) + (LARpp_j[i] >> 2); + } +} +/* + * Interpolate LAR coefficients (samples 13..26) + */ +static void interpolateLARs_13_26 (int *LARpp_j_1, int *LARpp_j, int *LARp) +{ int i; + for (i = 0; i < 8; i++) { + LARp[i] = (LARpp_j_1[i] >> 1) + (LARpp_j[i] >> 1); + } +} +/* + * Interpolate LAR coefficients (samples 27..39) + */ +static void interpolateLARs_27_39 (int *LARpp_j_1, int *LARpp_j, int *LARp) +{ int i; + for (i = 0; i < 8; i++) { + LARp[i] = (LARpp_j[i] >> 1) + (LARpp_j_1[i] >> 2) + (LARpp_j[i] >> 2); + } +} +/* + * Interpolate LAR coefficients (samples 40..159) + */ +static void interpolateLARs_40_159 (int *LARpp_j_1, int *LARpp_j, int *LARp) +{ int i; + for (i = 0; i < 8; i++) { + LARp[i] = LARpp_j[i]; + } +} +/* + * Convert LAR coefficients to reflection coefficients + */ +static void LARToR( int * LARp) +{ + int i; + int temp; + for (i = 0; i < 8; i++) { + temp = abs(LARp[i]); + if (temp < 11059) temp <<= 1; + else if (temp < 20070) temp += 11059; + else temp = (temp >> 2) + 26112; + LARp[i] = LARp[i] < 0 ? -temp : temp; + } +} + +/* + * This procedure computes the short term residual signal d[..] to be fed + * to the RPE-LTP loop from the s[..] signal and from the local rp[..] + * array (quantized reflection coefficients). As the call of this + * procedure can be done in many ways (see the interpolation of the LAR + * coefficient), it is assumed that the computation begins with index + * k_start (for arrays d[..] and s[..]) and stops with index k_end + * (k_start and k_end are defined in 4.2.9.1). This procedure also + * needs to keep the array u[0..7] in memory for each call. + */ +static void shortTermAnalysisFilter (gsm_state * state, int * rp, int len, short * in) +{ + int * u = state->u; + int i; + int di, ui, sav, rpi; + for (; len--; in++) { + di = sav = *in; + for (i = 0; i < 8; i++) { + ui = u[i]; + rpi = rp[i]; + u[i] = sav; + sav = ui + ((rpi * di + 16384) >> 15); + di = di + ((rpi * ui + 16384) >> 15); + } + *in = di; + } +} + +static void shortTermSynthesisFilter(gsm_state * state, int * rrp, int len, short * in, short *out) +{ + int * v = state->v; + int i; + int sri; + for (; len--; in++, out++) { + sri = *in; + for (i = 8; i--;) { + sri -= (rrp[i] * v[i] + 16384) >> 15; + if (sri < -32768) sri = -32768; + else if (sri > 32767) sri = 32767; + v[i+1] = v[i] + ((rrp[i] * sri + 16384) >> 15); + if (v[i+1] < -32768) v[i+1] = -32768; + else if (v[i+1] > 32767) v[i+1] = 32767; + } + *out = v[0] = sri; + } +} + +void shortTermAnalysis(gsm_state *state, short *in) +{ + int * qLARs = state->qLARs; + int * LARpp_j = state->LARpp[state->j]; + int * LARpp_j_1 = state->LARpp[state->j ^1]; + int LARp[8]; +// int i; + + lpcAnalysis(state, in);//i_samples); +/* + printf("short term in: \n"); + for (i=0;i<160;i++) { + printf("%7d ", in[i]);//((float)i_lpc[i])/32768.0f); + } + printf("\n"); + */ + dequantizeLARs(qLARs, LARpp_j); + interpolateLARs_0_12(LARpp_j_1, LARpp_j, LARp); + LARToR(LARp); + shortTermAnalysisFilter(state, LARp, 13, in); + interpolateLARs_13_26(LARpp_j_1, LARpp_j, LARp); + LARToR(LARp); + shortTermAnalysisFilter(state, LARp, 14, in+13); + interpolateLARs_27_39(LARpp_j_1, LARpp_j, LARp); + LARToR(LARp); + shortTermAnalysisFilter(state, LARp, 13, in+27); + interpolateLARs_40_159(LARpp_j_1, LARpp_j, LARp); + LARToR(LARp); + shortTermAnalysisFilter(state, LARp, 120, in+40); + /* + printf("short-term residuals: \n"); + for (i=0;i<160;i++) { + printf("%7d ", in[i]);//((float)i_lpc[i])/32768.0f); + } + printf("\n"); + */ +} + +void shortTermSynthesis(gsm_state *state, short *in, short *out) +{ + int * qLARs = state->qLARs; + int * LARpp_j = state->LARpp[state->j]; + int * LARpp_j_1 = state->LARpp[state->j ^1]; + int LARp[8]; +// int i; + + dequantizeLARs(qLARs, LARpp_j); + interpolateLARs_0_12(LARpp_j_1, LARpp_j, LARp); + LARToR(LARp); + shortTermSynthesisFilter(state, LARp, 13, in, out); + interpolateLARs_13_26(LARpp_j_1, LARpp_j, LARp); + LARToR(LARp); + shortTermSynthesisFilter(state, LARp, 14, in+13, out+13); + interpolateLARs_27_39(LARpp_j_1, LARpp_j, LARp); + LARToR(LARp); + shortTermSynthesisFilter(state, LARp, 13, in+27, out+27); + interpolateLARs_40_159(LARpp_j_1, LARpp_j, LARp); + LARToR(LARp); + shortTermSynthesisFilter(state, LARp, 120, in+40, out+40); + /* + printf("samples[reconstructed]: \n"); + for (i=0;i<160;i++) { + printf("%7d ", out[i]); + } + */ +} diff --git a/plugins/!NotAdopted/Tlen/commons.h b/plugins/!NotAdopted/Tlen/commons.h new file mode 100644 index 0000000000..af5a9bbcd7 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/commons.h @@ -0,0 +1,32 @@ +#ifndef _TLENCOMMONS_INC +#define _TLENCOMMONS_INC + + +#define TLENMUCC_MAJOR_VERSION 2 +#define TLENMUCC_MINOR_VERSION 0 +#define TLENMUCC_RELEASE_NUM 5 +#define TLENMUCC_BUILD_NUM 0 +#define TLENMUCC_VERSION_STRING "2.0.5.0" + + + +//consts for tlen.dll +#define TLEN_MAJOR_VERSION TLENMUCC_MAJOR_VERSION +#define TLEN_MINOR_VERSION TLENMUCC_MINOR_VERSION +#define TLEN_RELEASE_NUM TLENMUCC_RELEASE_NUM +#define TLEN_BUILD_NUM TLENMUCC_BUILD_NUM + +#define TLEN_FILEVERSION_STRING TLEN_MAJOR_VERSION,TLEN_MINOR_VERSION,TLEN_RELEASE_NUM,TLEN_BUILD_NUM +#define TLEN_VERSION_STRING TLENMUCC_VERSION_STRING + +//consts for tlen_czaty.dll +#define MUCC_MAJOR_VERSION TLENMUCC_MAJOR_VERSION +#define MUCC_MINOR_VERSION TLENMUCC_MINOR_VERSION +#define MUCC_RELEASE_NUM TLENMUCC_RELEASE_NUM +#define MUCC_BUILD_NUM TLENMUCC_BUILD_NUM + +#define MUCC_FILEVERSION_STRING MUCC_MAJOR_VERSION,MUCC_MINOR_VERSION,MUCC_RELEASE_NUM,MUCC_BUILD_NUM +#define MUCC_VERSION_STRING TLENMUCC_VERSION_STRING + + +#endif //ifndef _TLENCOMMONS_INC diff --git a/plugins/!NotAdopted/Tlen/crypto/aes.c b/plugins/!NotAdopted/Tlen/crypto/aes.c new file mode 100644 index 0000000000..7bccdf93a1 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/crypto/aes.c @@ -0,0 +1,1336 @@ +/* + * FIPS-197 compliant AES implementation + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. + * + * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf + * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf + */ + +#include "polarssl/config.h" + +#if defined(POLARSSL_AES_C) + +#include "polarssl/aes.h" +#include "polarssl/padlock.h" + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_ULONG_LE +#define GET_ULONG_LE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] ) \ + | ( (unsigned long) (b)[(i) + 1] << 8 ) \ + | ( (unsigned long) (b)[(i) + 2] << 16 ) \ + | ( (unsigned long) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_ULONG_LE +#define PUT_ULONG_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ +} +#endif + +#if defined(POLARSSL_AES_ROM_TABLES) +/* + * Forward S-box + */ +static const unsigned char FSb[256] = +{ + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, + 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, + 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, + 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, + 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, + 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, + 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, + 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, + 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, + 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, + 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, + 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, + 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, + 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, + 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, + 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, + 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 +}; + +/* + * Forward tables + */ +#define FT \ +\ + V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \ + V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \ + V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \ + V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \ + V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \ + V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \ + V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \ + V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \ + V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \ + V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \ + V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \ + V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \ + V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \ + V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \ + V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \ + V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \ + V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \ + V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \ + V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \ + V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \ + V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \ + V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \ + V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \ + V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \ + V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \ + V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \ + V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \ + V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \ + V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \ + V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \ + V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \ + V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \ + V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \ + V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \ + V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \ + V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \ + V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \ + V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \ + V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \ + V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \ + V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \ + V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \ + V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \ + V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \ + V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \ + V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \ + V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \ + V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \ + V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \ + V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \ + V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \ + V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \ + V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \ + V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \ + V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \ + V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \ + V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \ + V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \ + V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \ + V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \ + V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \ + V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \ + V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \ + V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C) + +#define V(a,b,c,d) 0x##a##b##c##d +static const unsigned long FT0[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##b##c##d##a +static const unsigned long FT1[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +static const unsigned long FT2[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##d##a##b##c +static const unsigned long FT3[256] = { FT }; +#undef V + +#undef FT + +/* + * Reverse S-box + */ +static const unsigned char RSb[256] = +{ + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, + 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, + 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, + 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, + 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, + 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, + 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, + 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, + 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, + 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, + 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, + 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, + 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, + 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, + 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, + 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D +}; + +/* + * Reverse tables + */ +#define RT \ +\ + V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \ + V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \ + V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \ + V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \ + V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \ + V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \ + V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \ + V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \ + V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \ + V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \ + V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \ + V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \ + V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \ + V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \ + V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \ + V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \ + V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \ + V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \ + V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \ + V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \ + V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \ + V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \ + V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \ + V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \ + V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \ + V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \ + V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \ + V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \ + V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \ + V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \ + V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \ + V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \ + V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \ + V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \ + V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \ + V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \ + V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \ + V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \ + V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \ + V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \ + V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \ + V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \ + V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \ + V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \ + V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \ + V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \ + V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \ + V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \ + V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \ + V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \ + V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \ + V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \ + V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \ + V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \ + V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \ + V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \ + V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \ + V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \ + V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \ + V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \ + V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \ + V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \ + V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \ + V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0) + +#define V(a,b,c,d) 0x##a##b##c##d +static const unsigned long RT0[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##b##c##d##a +static const unsigned long RT1[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +static const unsigned long RT2[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##d##a##b##c +static const unsigned long RT3[256] = { RT }; +#undef V + +#undef RT + +/* + * Round constants + */ +static const unsigned long RCON[10] = +{ + 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, + 0x0000001B, 0x00000036 +}; + +#else + +/* + * Forward S-box & tables + */ +static unsigned char FSb[256]; +static unsigned long FT0[256]; +static unsigned long FT1[256]; +static unsigned long FT2[256]; +static unsigned long FT3[256]; + +/* + * Reverse S-box & tables + */ +static unsigned char RSb[256]; +static unsigned long RT0[256]; +static unsigned long RT1[256]; +static unsigned long RT2[256]; +static unsigned long RT3[256]; + +/* + * Round constants + */ +static unsigned long RCON[10]; + +/* + * Tables generation code + */ +#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 ) +#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) +#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 ) + +static int aes_init_done = 0; + +static void aes_gen_tables( void ) +{ + int i, x, y, z; + int pow[256]; + int log[256]; + + /* + * compute pow and log tables over GF(2^8) + */ + for( i = 0, x = 1; i < 256; i++ ) + { + pow[i] = x; + log[x] = i; + x = ( x ^ XTIME( x ) ) & 0xFF; + } + + /* + * calculate the round constants + */ + for( i = 0, x = 1; i < 10; i++ ) + { + RCON[i] = (unsigned long) x; + x = XTIME( x ) & 0xFF; + } + + /* + * generate the forward and reverse S-boxes + */ + FSb[0x00] = 0x63; + RSb[0x63] = 0x00; + + for( i = 1; i < 256; i++ ) + { + x = pow[255 - log[i]]; + + y = x; y = ( (y << 1) | (y >> 7) ) & 0xFF; + x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF; + x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF; + x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF; + x ^= y ^ 0x63; + + FSb[i] = (unsigned char) x; + RSb[x] = (unsigned char) i; + } + + /* + * generate the forward and reverse tables + */ + for( i = 0; i < 256; i++ ) + { + x = FSb[i]; + y = XTIME( x ) & 0xFF; + z = ( y ^ x ) & 0xFF; + + FT0[i] = ( (unsigned long) y ) ^ + ( (unsigned long) x << 8 ) ^ + ( (unsigned long) x << 16 ) ^ + ( (unsigned long) z << 24 ); + + FT1[i] = ROTL8( FT0[i] ); + FT2[i] = ROTL8( FT1[i] ); + FT3[i] = ROTL8( FT2[i] ); + + x = RSb[i]; + + RT0[i] = ( (unsigned long) MUL( 0x0E, x ) ) ^ + ( (unsigned long) MUL( 0x09, x ) << 8 ) ^ + ( (unsigned long) MUL( 0x0D, x ) << 16 ) ^ + ( (unsigned long) MUL( 0x0B, x ) << 24 ); + + RT1[i] = ROTL8( RT0[i] ); + RT2[i] = ROTL8( RT1[i] ); + RT3[i] = ROTL8( RT2[i] ); + } +} + +#endif + +/* + * AES key schedule (encryption) + */ +int aes_setkey_enc( aes_context *ctx, const unsigned char *key, unsigned int keysize ) +{ + unsigned int i; + unsigned long *RK; + +#if !defined(POLARSSL_AES_ROM_TABLES) + if( aes_init_done == 0 ) + { + aes_gen_tables(); + aes_init_done = 1; + } +#endif + + switch( keysize ) + { + case 128: ctx->nr = 10; break; + case 192: ctx->nr = 12; break; + case 256: ctx->nr = 14; break; + default : return( POLARSSL_ERR_AES_INVALID_KEY_LENGTH ); + } + +#if defined(PADLOCK_ALIGN16) + ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf ); +#else + ctx->rk = RK = ctx->buf; +#endif + + for( i = 0; i < (keysize >> 5); i++ ) + { + GET_ULONG_LE( RK[i], key, i << 2 ); + } + + switch( ctx->nr ) + { + case 10: + + for( i = 0; i < 10; i++, RK += 4 ) + { + RK[4] = RK[0] ^ RCON[i] ^ + ( (unsigned long) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^ + ( (unsigned long) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^ + ( (unsigned long) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^ + ( (unsigned long) FSb[ ( RK[3] ) & 0xFF ] << 24 ); + + RK[5] = RK[1] ^ RK[4]; + RK[6] = RK[2] ^ RK[5]; + RK[7] = RK[3] ^ RK[6]; + } + break; + + case 12: + + for( i = 0; i < 8; i++, RK += 6 ) + { + RK[6] = RK[0] ^ RCON[i] ^ + ( (unsigned long) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^ + ( (unsigned long) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^ + ( (unsigned long) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^ + ( (unsigned long) FSb[ ( RK[5] ) & 0xFF ] << 24 ); + + RK[7] = RK[1] ^ RK[6]; + RK[8] = RK[2] ^ RK[7]; + RK[9] = RK[3] ^ RK[8]; + RK[10] = RK[4] ^ RK[9]; + RK[11] = RK[5] ^ RK[10]; + } + break; + + case 14: + + for( i = 0; i < 7; i++, RK += 8 ) + { + RK[8] = RK[0] ^ RCON[i] ^ + ( (unsigned long) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^ + ( (unsigned long) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^ + ( (unsigned long) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^ + ( (unsigned long) FSb[ ( RK[7] ) & 0xFF ] << 24 ); + + RK[9] = RK[1] ^ RK[8]; + RK[10] = RK[2] ^ RK[9]; + RK[11] = RK[3] ^ RK[10]; + + RK[12] = RK[4] ^ + ( (unsigned long) FSb[ ( RK[11] ) & 0xFF ] ) ^ + ( (unsigned long) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^ + ( (unsigned long) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^ + ( (unsigned long) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 ); + + RK[13] = RK[5] ^ RK[12]; + RK[14] = RK[6] ^ RK[13]; + RK[15] = RK[7] ^ RK[14]; + } + break; + + default: + + break; + } + + return( 0 ); +} + +/* + * AES key schedule (decryption) + */ +int aes_setkey_dec( aes_context *ctx, const unsigned char *key, unsigned int keysize ) +{ + int i, j; + aes_context cty; + unsigned long *RK; + unsigned long *SK; + int ret; + + switch( keysize ) + { + case 128: ctx->nr = 10; break; + case 192: ctx->nr = 12; break; + case 256: ctx->nr = 14; break; + default : return( POLARSSL_ERR_AES_INVALID_KEY_LENGTH ); + } + +#if defined(PADLOCK_ALIGN16) + ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf ); +#else + ctx->rk = RK = ctx->buf; +#endif + + ret = aes_setkey_enc( &cty, key, keysize ); + if( ret != 0 ) + return( ret ); + + SK = cty.rk + cty.nr * 4; + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + + for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 ) + { + for( j = 0; j < 4; j++, SK++ ) + { + *RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^ + RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^ + RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^ + RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ]; + } + } + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + + memset( &cty, 0, sizeof( aes_context ) ); + + return( 0 ); +} + +#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ +{ \ + X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \ + FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y3 >> 24 ) & 0xFF ]; \ + \ + X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \ + FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y0 >> 24 ) & 0xFF ]; \ + \ + X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \ + FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y1 >> 24 ) & 0xFF ]; \ + \ + X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \ + FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y2 >> 24 ) & 0xFF ]; \ +} + +#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ +{ \ + X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \ + RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y1 >> 24 ) & 0xFF ]; \ + \ + X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \ + RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y2 >> 24 ) & 0xFF ]; \ + \ + X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \ + RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y3 >> 24 ) & 0xFF ]; \ + \ + X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \ + RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y0 >> 24 ) & 0xFF ]; \ +} + +/* + * AES-ECB block encryption/decryption + */ +int aes_crypt_ecb( aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ + int i; + unsigned long *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; + +#if defined(POLARSSL_PADLOCK_C) && defined(POLARSSL_HAVE_X86) + if( padlock_supports( PADLOCK_ACE ) ) + { + if( padlock_xcryptecb( ctx, mode, input, output ) == 0 ) + return( 0 ); + + // If padlock data misaligned, we just fall back to + // unaccelerated mode + // + } +#endif + + RK = ctx->rk; + + GET_ULONG_LE( X0, input, 0 ); X0 ^= *RK++; + GET_ULONG_LE( X1, input, 4 ); X1 ^= *RK++; + GET_ULONG_LE( X2, input, 8 ); X2 ^= *RK++; + GET_ULONG_LE( X3, input, 12 ); X3 ^= *RK++; + + if( mode == AES_DECRYPT ) + { + for( i = (ctx->nr >> 1) - 1; i > 0; i-- ) + { + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); + } + + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + + X0 = *RK++ ^ \ + ( (unsigned long) RSb[ ( Y0 ) & 0xFF ] ) ^ + ( (unsigned long) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ + ( (unsigned long) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ + ( (unsigned long) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); + + X1 = *RK++ ^ \ + ( (unsigned long) RSb[ ( Y1 ) & 0xFF ] ) ^ + ( (unsigned long) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ + ( (unsigned long) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ + ( (unsigned long) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); + + X2 = *RK++ ^ \ + ( (unsigned long) RSb[ ( Y2 ) & 0xFF ] ) ^ + ( (unsigned long) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ + ( (unsigned long) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ + ( (unsigned long) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); + + X3 = *RK++ ^ \ + ( (unsigned long) RSb[ ( Y3 ) & 0xFF ] ) ^ + ( (unsigned long) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ + ( (unsigned long) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ + ( (unsigned long) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); + } + else /* AES_ENCRYPT */ + { + for( i = (ctx->nr >> 1) - 1; i > 0; i-- ) + { + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); + } + + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + + X0 = *RK++ ^ \ + ( (unsigned long) FSb[ ( Y0 ) & 0xFF ] ) ^ + ( (unsigned long) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ + ( (unsigned long) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ + ( (unsigned long) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); + + X1 = *RK++ ^ \ + ( (unsigned long) FSb[ ( Y1 ) & 0xFF ] ) ^ + ( (unsigned long) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ + ( (unsigned long) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ + ( (unsigned long) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); + + X2 = *RK++ ^ \ + ( (unsigned long) FSb[ ( Y2 ) & 0xFF ] ) ^ + ( (unsigned long) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ + ( (unsigned long) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ + ( (unsigned long) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); + + X3 = *RK++ ^ \ + ( (unsigned long) FSb[ ( Y3 ) & 0xFF ] ) ^ + ( (unsigned long) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ + ( (unsigned long) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ + ( (unsigned long) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); + } + + PUT_ULONG_LE( X0, output, 0 ); + PUT_ULONG_LE( X1, output, 4 ); + PUT_ULONG_LE( X2, output, 8 ); + PUT_ULONG_LE( X3, output, 12 ); + + return( 0 ); +} + +/* + * AES-CBC buffer encryption/decryption + */ +int aes_crypt_cbc( aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int i; + unsigned char temp[16]; + + if( length % 16 ) + return( POLARSSL_ERR_AES_INVALID_INPUT_LENGTH ); + +#if defined(POLARSSL_PADLOCK_C) && defined(POLARSSL_HAVE_X86) + if( padlock_supports( PADLOCK_ACE ) ) + { + if( padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 ) + return( 0 ); + + // If padlock data misaligned, we just fall back to + // unaccelerated mode + // + } +#endif + + if( mode == AES_DECRYPT ) + { + while( length > 0 ) + { + memcpy( temp, input, 16 ); + aes_crypt_ecb( ctx, mode, input, output ); + + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + else + { + while( length > 0 ) + { + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + aes_crypt_ecb( ctx, mode, output, output ); + memcpy( iv, output, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + + return( 0 ); +} + +#if defined(POLARSSL_CIPHER_MODE_CFB) +/* + * AES-CFB128 buffer encryption/decryption + */ +int aes_crypt_cfb128( aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int c; + size_t n = *iv_off; + + if( mode == AES_DECRYPT ) + { + while( length-- ) + { + if( n == 0 ) + aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv ); + + c = *input++; + *output++ = (unsigned char)( c ^ iv[n] ); + iv[n] = (unsigned char) c; + + n = (n + 1) & 0x0F; + } + } + else + { + while( length-- ) + { + if( n == 0 ) + aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv ); + + iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); + + n = (n + 1) & 0x0F; + } + } + + *iv_off = n; + + return( 0 ); +} +#endif /*POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) +/* + * AES-CTR buffer encryption/decryption + */ +int aes_crypt_ctr( aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ) +{ + int c, i, cb; + size_t n = *nc_off; + + while( length-- ) + { + if( n == 0 ) { + aes_crypt_ecb( ctx, AES_ENCRYPT, nonce_counter, stream_block ); + + i = 15; + do { + nonce_counter[i]++; + cb = nonce_counter[i] == 0; + } while( i-- && cb ); + + } + c = *input++; + *output++ = (unsigned char)( c ^ stream_block[n] ); + + n = (n + 1) & 0x0F; + } + + *nc_off = n; + + return( 0 ); +} +#endif /* POLARSSL_CIPHER_MODE_CTR */ + +#if defined(POLARSSL_SELF_TEST) + +#include + +/* + * AES test vectors from: + * + * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip + */ +static const unsigned char aes_test_ecb_dec[3][16] = +{ + { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58, + 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 }, + { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, + 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 }, + { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, + 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE } +}; + +static const unsigned char aes_test_ecb_enc[3][16] = +{ + { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73, + 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F }, + { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11, + 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 }, + { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D, + 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 } +}; + +static const unsigned char aes_test_cbc_dec[3][16] = +{ + { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73, + 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 }, + { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75, + 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B }, + { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75, + 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 } +}; + +static const unsigned char aes_test_cbc_enc[3][16] = +{ + { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84, + 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D }, + { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB, + 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 }, + { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5, + 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 } +}; + +#if defined(POLARSSL_CIPHER_MODE_CFB) +/* + * AES-CFB128 test vectors from: + * + * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + */ +static const unsigned char aes_test_cfb128_key[3][32] = +{ + { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, + { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, + 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, + 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, + { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } +}; + +static const unsigned char aes_test_cfb128_iv[16] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; + +static const unsigned char aes_test_cfb128_pt[64] = +{ + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const unsigned char aes_test_cfb128_ct[3][64] = +{ + { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, + 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, + 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F, + 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B, + 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40, + 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF, + 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E, + 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 }, + { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, + 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, + 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21, + 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A, + 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1, + 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9, + 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0, + 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF }, + { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, + 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, + 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8, + 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B, + 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92, + 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9, + 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8, + 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 } +}; +#endif /* POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) +/* + * AES-CTR test vectors from: + * + * http://www.faqs.org/rfcs/rfc3686.html + */ + +static const unsigned char aes_test_ctr_key[3][16] = +{ + { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, + 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, + { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, + 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, + { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } +}; + +static const unsigned char aes_test_ctr_nonce_counter[3][16] = +{ + { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, + 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, + 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } +}; + +static const unsigned char aes_test_ctr_pt[3][48] = +{ + { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23 } +}; + +static const unsigned char aes_test_ctr_ct[3][48] = +{ + { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, + 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 }, + { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, + 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, + 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, + 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 }, + { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, + 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, + 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, + 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, + 0x25, 0xB2, 0x07, 0x2F } +}; + +static const int aes_test_ctr_len[3] = + { 16, 32, 36 }; +#endif /* POLARSSL_CIPHER_MODE_CTR */ + +/* + * Checkup routine + */ +int aes_self_test( int verbose ) +{ + int i, j, u, v; + unsigned char key[32]; + unsigned char buf[64]; + unsigned char prv[16]; + unsigned char iv[16]; +#if defined(POLARSSL_CIPHER_MODE_CTR) || defined(POLARSSL_CIPHER_MODE_CFB) + size_t offset; +#endif +#if defined(POLARSSL_CIPHER_MODE_CTR) + int len; + unsigned char nonce_counter[16]; + unsigned char stream_block[16]; +#endif + aes_context ctx; + + memset( key, 0, 32 ); + + /* + * ECB mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + printf( " AES-ECB-%3d (%s): ", 128 + u * 64, + ( v == AES_DECRYPT ) ? "dec" : "enc" ); + + memset( buf, 0, 16 ); + + if( v == AES_DECRYPT ) + { + aes_setkey_dec( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + aes_crypt_ecb( &ctx, v, buf, buf ); + + if( memcmp( buf, aes_test_ecb_dec[u], 16 ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + } + else + { + aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + aes_crypt_ecb( &ctx, v, buf, buf ); + + if( memcmp( buf, aes_test_ecb_enc[u], 16 ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + printf( "passed\n" ); + } + + if( verbose != 0 ) + printf( "\n" ); + + /* + * CBC mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + printf( " AES-CBC-%3d (%s): ", 128 + u * 64, + ( v == AES_DECRYPT ) ? "dec" : "enc" ); + + memset( iv , 0, 16 ); + memset( prv, 0, 16 ); + memset( buf, 0, 16 ); + + if( v == AES_DECRYPT ) + { + aes_setkey_dec( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); + + if( memcmp( buf, aes_test_cbc_dec[u], 16 ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + } + else + { + aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + { + unsigned char tmp[16]; + + aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); + + memcpy( tmp, prv, 16 ); + memcpy( prv, buf, 16 ); + memcpy( buf, tmp, 16 ); + } + + if( memcmp( prv, aes_test_cbc_enc[u], 16 ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + printf( "passed\n" ); + } + + if( verbose != 0 ) + printf( "\n" ); + +#if defined(POLARSSL_CIPHER_MODE_CFB) + /* + * CFB128 mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + printf( " AES-CFB128-%3d (%s): ", 128 + u * 64, + ( v == AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( iv, aes_test_cfb128_iv, 16 ); + memcpy( key, aes_test_cfb128_key[u], 16 + u * 8 ); + + offset = 0; + aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + if( v == AES_DECRYPT ) + { + memcpy( buf, aes_test_cfb128_ct[u], 64 ); + aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); + + if( memcmp( buf, aes_test_cfb128_pt, 64 ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + } + else + { + memcpy( buf, aes_test_cfb128_pt, 64 ); + aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); + + if( memcmp( buf, aes_test_cfb128_ct[u], 64 ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + printf( "passed\n" ); + } + + if( verbose != 0 ) + printf( "\n" ); +#endif /* POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) + /* + * CTR mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + printf( " AES-CTR-128 (%s): ", + ( v == AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); + memcpy( key, aes_test_ctr_key[u], 16 ); + + offset = 0; + aes_setkey_enc( &ctx, key, 128 ); + + if( v == AES_DECRYPT ) + { + len = aes_test_ctr_len[u]; + memcpy( buf, aes_test_ctr_ct[u], len ); + + aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, buf, buf ); + + if( memcmp( buf, aes_test_ctr_pt[u], len ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + } + else + { + len = aes_test_ctr_len[u]; + memcpy( buf, aes_test_ctr_pt[u], len ); + + aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, buf, buf ); + + if( memcmp( buf, aes_test_ctr_ct[u], len ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + printf( "passed\n" ); + } + + if( verbose != 0 ) + printf( "\n" ); +#endif /* POLARSSL_CIPHER_MODE_CTR */ + + return( 0 ); +} + +#endif + +#endif diff --git a/plugins/!NotAdopted/Tlen/crypto/bignum.c b/plugins/!NotAdopted/Tlen/crypto/bignum.c new file mode 100644 index 0000000000..eabfbfe6f9 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/crypto/bignum.c @@ -0,0 +1,2097 @@ +/* + * Multi-precision integer library + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * This MPI implementation is based on: + * + * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf + * http://www.stillhq.com/extracted/gnupg-api/mpi/ + * http://math.libtomcrypt.com/files/tommath.pdf + */ + +#include "polarssl/config.h" + +#if defined(POLARSSL_BIGNUM_C) + +#include "polarssl/bignum.h" +#include "polarssl/bn_mul.h" + +#include + +#define ciL (sizeof(t_uint)) /* chars in limb */ +#define biL (ciL << 3) /* bits in limb */ +#define biH (ciL << 2) /* half limb size */ + +/* + * Convert between bits/chars and number of limbs + */ +#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL) +#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL) + +/* + * Initialize one MPI + */ +void mpi_init( mpi *X ) +{ + if( X == NULL ) + return; + + X->s = 1; + X->n = 0; + X->p = NULL; +} + +/* + * Unallocate one MPI + */ +void mpi_free( mpi *X ) +{ + if( X == NULL ) + return; + + if( X->p != NULL ) + { + memset( X->p, 0, X->n * ciL ); + free( X->p ); + } + + X->s = 1; + X->n = 0; + X->p = NULL; +} + +/* + * Enlarge to the specified number of limbs + */ +int mpi_grow( mpi *X, size_t nblimbs ) +{ + t_uint *p; + + if( nblimbs > POLARSSL_MPI_MAX_LIMBS ) + return( 1 ); + + if( X->n < nblimbs ) + { + if( ( p = (t_uint *) malloc( nblimbs * ciL ) ) == NULL ) + return( 1 ); + + memset( p, 0, nblimbs * ciL ); + + if( X->p != NULL ) + { + memcpy( p, X->p, X->n * ciL ); + memset( X->p, 0, X->n * ciL ); + free( X->p ); + } + + X->n = nblimbs; + X->p = p; + } + + return( 0 ); +} + +/* + * Copy the contents of Y into X + */ +int mpi_copy( mpi *X, const mpi *Y ) +{ + int ret; + size_t i; + + if( X == Y ) + return( 0 ); + + for( i = Y->n - 1; i > 0; i-- ) + if( Y->p[i] != 0 ) + break; + i++; + + X->s = Y->s; + + MPI_CHK( mpi_grow( X, i ) ); + + memset( X->p, 0, X->n * ciL ); + memcpy( X->p, Y->p, i * ciL ); + +cleanup: + + return( ret ); +} + +/* + * Swap the contents of X and Y + */ +void mpi_swap( mpi *X, mpi *Y ) +{ + mpi T; + + memcpy( &T, X, sizeof( mpi ) ); + memcpy( X, Y, sizeof( mpi ) ); + memcpy( Y, &T, sizeof( mpi ) ); +} + +/* + * Set value from integer + */ +int mpi_lset( mpi *X, t_sint z ) +{ + int ret; + + MPI_CHK( mpi_grow( X, 1 ) ); + memset( X->p, 0, X->n * ciL ); + + X->p[0] = ( z < 0 ) ? -z : z; + X->s = ( z < 0 ) ? -1 : 1; + +cleanup: + + return( ret ); +} + +/* + * Get a specific bit + */ +int mpi_get_bit( mpi *X, size_t pos ) +{ + if( X->n * biL <= pos ) + return( 0 ); + + return ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01; +} + +/* + * Set a bit to a specific value of 0 or 1 + */ +int mpi_set_bit( mpi *X, size_t pos, unsigned char val ) +{ + int ret = 0; + size_t off = pos / biL; + size_t idx = pos % biL; + + if( val != 0 && val != 1 ) + return POLARSSL_ERR_MPI_BAD_INPUT_DATA; + + if( X->n * biL <= pos ) + { + if( val == 0 ) + return ( 0 ); + + MPI_CHK( mpi_grow( X, off + 1 ) ); + } + + X->p[off] = ( X->p[off] & ~( 0x01 << idx ) ) | ( val << idx ); + +cleanup: + + return( ret ); +} + +/* + * Return the number of least significant bits + */ +size_t mpi_lsb( const mpi *X ) +{ + size_t i, j, count = 0; + + for( i = 0; i < X->n; i++ ) + for( j = 0; j < biL; j++, count++ ) + if( ( ( X->p[i] >> j ) & 1 ) != 0 ) + return( count ); + + return( 0 ); +} + +/* + * Return the number of most significant bits + */ +size_t mpi_msb( const mpi *X ) +{ + size_t i, j; + + for( i = X->n - 1; i > 0; i-- ) + if( X->p[i] != 0 ) + break; + + for( j = biL; j > 0; j-- ) + if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 ) + break; + + return( ( i * biL ) + j ); +} + +/* + * Return the total size in bytes + */ +size_t mpi_size( const mpi *X ) +{ + return( ( mpi_msb( X ) + 7 ) >> 3 ); +} + +/* + * Convert an ASCII character to digit value + */ +static int mpi_get_digit( t_uint *d, int radix, char c ) +{ + *d = 255; + + if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30; + if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37; + if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57; + + if( *d >= (t_uint) radix ) + return( POLARSSL_ERR_MPI_INVALID_CHARACTER ); + + return( 0 ); +} + +/* + * Import from an ASCII string + */ +int mpi_read_string( mpi *X, int radix, const char *s ) +{ + int ret; + size_t i, j, slen, n; + t_uint d; + mpi T; + + if( radix < 2 || radix > 16 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + mpi_init( &T ); + + slen = strlen( s ); + + if( radix == 16 ) + { + n = BITS_TO_LIMBS( slen << 2 ); + + MPI_CHK( mpi_grow( X, n ) ); + MPI_CHK( mpi_lset( X, 0 ) ); + + for( i = slen, j = 0; i > 0; i--, j++ ) + { + if( i == 1 && s[i - 1] == '-' ) + { + X->s = -1; + break; + } + + MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) ); + X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 ); + } + } + else + { + MPI_CHK( mpi_lset( X, 0 ) ); + + for( i = 0; i < slen; i++ ) + { + if( i == 0 && s[i] == '-' ) + { + X->s = -1; + continue; + } + + MPI_CHK( mpi_get_digit( &d, radix, s[i] ) ); + MPI_CHK( mpi_mul_int( &T, X, radix ) ); + + if( X->s == 1 ) + { + MPI_CHK( mpi_add_int( X, &T, d ) ); + } + else + { + MPI_CHK( mpi_sub_int( X, &T, d ) ); + } + } + } + +cleanup: + + mpi_free( &T ); + + return( ret ); +} + +/* + * Helper to write the digits high-order first + */ +static int mpi_write_hlp( mpi *X, int radix, char **p ) +{ + int ret; + t_uint r; + + if( radix < 2 || radix > 16 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + MPI_CHK( mpi_mod_int( &r, X, radix ) ); + MPI_CHK( mpi_div_int( X, NULL, X, radix ) ); + + if( mpi_cmp_int( X, 0 ) != 0 ) + MPI_CHK( mpi_write_hlp( X, radix, p ) ); + + if( r < 10 ) + *(*p)++ = (char)( r + 0x30 ); + else + *(*p)++ = (char)( r + 0x37 ); + +cleanup: + + return( ret ); +} + +/* + * Export into an ASCII string + */ +int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen ) +{ + int ret = 0; + size_t n; + char *p; + mpi T; + + if( radix < 2 || radix > 16 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + n = mpi_msb( X ); + if( radix >= 4 ) n >>= 1; + if( radix >= 16 ) n >>= 1; + n += 3; + + if( *slen < n ) + { + *slen = n; + return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL ); + } + + p = s; + mpi_init( &T ); + + if( X->s == -1 ) + *p++ = '-'; + + if( radix == 16 ) + { + int c; + size_t i, j, k; + + for( i = X->n, k = 0; i > 0; i-- ) + { + for( j = ciL; j > 0; j-- ) + { + c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF; + + if( c == 0 && k == 0 && ( i + j + 3 ) != 0 ) + continue; + + p += sprintf( p, "%02X", c ); + k = 1; + } + } + } + else + { + MPI_CHK( mpi_copy( &T, X ) ); + + if( T.s == -1 ) + T.s = 1; + + MPI_CHK( mpi_write_hlp( &T, radix, &p ) ); + } + + *p++ = '\0'; + *slen = p - s; + +cleanup: + + mpi_free( &T ); + + return( ret ); +} + +#if defined(POLARSSL_FS_IO) +/* + * Read X from an opened file + */ +int mpi_read_file( mpi *X, int radix, FILE *fin ) +{ + t_uint d; + size_t slen; + char *p; + char s[1024]; + + memset( s, 0, sizeof( s ) ); + if( fgets( s, sizeof( s ) - 1, fin ) == NULL ) + return( POLARSSL_ERR_MPI_FILE_IO_ERROR ); + + slen = strlen( s ); + if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; } + if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; } + + p = s + slen; + while( --p >= s ) + if( mpi_get_digit( &d, radix, *p ) != 0 ) + break; + + return( mpi_read_string( X, radix, p + 1 ) ); +} + +/* + * Write X into an opened file (or stdout if fout == NULL) + */ +int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout ) +{ + int ret; + size_t n, slen, plen; + char s[2048]; + + n = sizeof( s ); + memset( s, 0, n ); + n -= 2; + + MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) ); + + if( p == NULL ) p = ""; + + plen = strlen( p ); + slen = strlen( s ); + s[slen++] = '\r'; + s[slen++] = '\n'; + + if( fout != NULL ) + { + if( fwrite( p, 1, plen, fout ) != plen || + fwrite( s, 1, slen, fout ) != slen ) + return( POLARSSL_ERR_MPI_FILE_IO_ERROR ); + } + else + printf( "%s%s", p, s ); + +cleanup: + + return( ret ); +} +#endif /* POLARSSL_FS_IO */ + +/* + * Import X from unsigned binary data, big endian + */ +int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen ) +{ + int ret; + size_t i, j, n; + + for( n = 0; n < buflen; n++ ) + if( buf[n] != 0 ) + break; + + MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) ); + MPI_CHK( mpi_lset( X, 0 ) ); + + for( i = buflen, j = 0; i > n; i--, j++ ) + X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3); + +cleanup: + + return( ret ); +} + +/* + * Export X into unsigned binary data, big endian + */ +int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen ) +{ + size_t i, j, n; + + n = mpi_size( X ); + + if( buflen < n ) + return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL ); + + memset( buf, 0, buflen ); + + for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- ) + buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) ); + + return( 0 ); +} + +/* + * Left-shift: X <<= count + */ +int mpi_shift_l( mpi *X, size_t count ) +{ + int ret; + size_t i, v0, t1; + t_uint r0 = 0, r1; + + v0 = count / (biL ); + t1 = count & (biL - 1); + + i = mpi_msb( X ) + count; + + if( X->n * biL < i ) + MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) ); + + ret = 0; + + /* + * shift by count / limb_size + */ + if( v0 > 0 ) + { + for( i = X->n; i > v0; i-- ) + X->p[i - 1] = X->p[i - v0 - 1]; + + for( ; i > 0; i-- ) + X->p[i - 1] = 0; + } + + /* + * shift by count % limb_size + */ + if( t1 > 0 ) + { + for( i = v0; i < X->n; i++ ) + { + r1 = X->p[i] >> (biL - t1); + X->p[i] <<= t1; + X->p[i] |= r0; + r0 = r1; + } + } + +cleanup: + + return( ret ); +} + +/* + * Right-shift: X >>= count + */ +int mpi_shift_r( mpi *X, size_t count ) +{ + size_t i, v0, v1; + t_uint r0 = 0, r1; + + v0 = count / biL; + v1 = count & (biL - 1); + + /* + * shift by count / limb_size + */ + if( v0 > 0 ) + { + for( i = 0; i < X->n - v0; i++ ) + X->p[i] = X->p[i + v0]; + + for( ; i < X->n; i++ ) + X->p[i] = 0; + } + + /* + * shift by count % limb_size + */ + if( v1 > 0 ) + { + for( i = X->n; i > 0; i-- ) + { + r1 = X->p[i - 1] << (biL - v1); + X->p[i - 1] >>= v1; + X->p[i - 1] |= r0; + r0 = r1; + } + } + + return( 0 ); +} + +/* + * Compare unsigned values + */ +int mpi_cmp_abs( const mpi *X, const mpi *Y ) +{ + size_t i, j; + + for( i = X->n; i > 0; i-- ) + if( X->p[i - 1] != 0 ) + break; + + for( j = Y->n; j > 0; j-- ) + if( Y->p[j - 1] != 0 ) + break; + + if( i == 0 && j == 0 ) + return( 0 ); + + if( i > j ) return( 1 ); + if( j > i ) return( -1 ); + + for( ; i > 0; i-- ) + { + if( X->p[i - 1] > Y->p[i - 1] ) return( 1 ); + if( X->p[i - 1] < Y->p[i - 1] ) return( -1 ); + } + + return( 0 ); +} + +/* + * Compare signed values + */ +int mpi_cmp_mpi( const mpi *X, const mpi *Y ) +{ + size_t i, j; + + for( i = X->n; i > 0; i-- ) + if( X->p[i - 1] != 0 ) + break; + + for( j = Y->n; j > 0; j-- ) + if( Y->p[j - 1] != 0 ) + break; + + if( i == 0 && j == 0 ) + return( 0 ); + + if( i > j ) return( X->s ); + if( j > i ) return( -X->s ); + + if( X->s > 0 && Y->s < 0 ) return( 1 ); + if( Y->s > 0 && X->s < 0 ) return( -1 ); + + for( ; i > 0; i-- ) + { + if( X->p[i - 1] > Y->p[i - 1] ) return( X->s ); + if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s ); + } + + return( 0 ); +} + +/* + * Compare signed values + */ +int mpi_cmp_int( const mpi *X, t_sint z ) +{ + mpi Y; + t_uint p[1]; + + *p = ( z < 0 ) ? -z : z; + Y.s = ( z < 0 ) ? -1 : 1; + Y.n = 1; + Y.p = p; + + return( mpi_cmp_mpi( X, &Y ) ); +} + +/* + * Unsigned addition: X = |A| + |B| (HAC 14.7) + */ +int mpi_add_abs( mpi *X, const mpi *A, const mpi *B ) +{ + int ret; + size_t i, j; + t_uint *o, *p, c; + + if( X == B ) + { + const mpi *T = A; A = X; B = T; + } + + if( X != A ) + MPI_CHK( mpi_copy( X, A ) ); + + /* + * X should always be positive as a result of unsigned additions. + */ + X->s = 1; + + for( j = B->n; j > 0; j-- ) + if( B->p[j - 1] != 0 ) + break; + + MPI_CHK( mpi_grow( X, j ) ); + + o = B->p; p = X->p; c = 0; + + for( i = 0; i < j; i++, o++, p++ ) + { + *p += c; c = ( *p < c ); + *p += *o; c += ( *p < *o ); + } + + while( c != 0 ) + { + if( i >= X->n ) + { + MPI_CHK( mpi_grow( X, i + 1 ) ); + p = X->p + i; + } + + *p += c; c = ( *p < c ); i++; + } + +cleanup: + + return( ret ); +} + +/* + * Helper for mpi substraction + */ +static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d ) +{ + size_t i; + t_uint c, z; + + for( i = c = 0; i < n; i++, s++, d++ ) + { + z = ( *d < c ); *d -= c; + c = ( *d < *s ) + z; *d -= *s; + } + + while( c != 0 ) + { + z = ( *d < c ); *d -= c; + c = z; i++; d++; + } +} + +/* + * Unsigned substraction: X = |A| - |B| (HAC 14.9) + */ +int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B ) +{ + mpi TB; + int ret; + size_t n; + + if( mpi_cmp_abs( A, B ) < 0 ) + return( POLARSSL_ERR_MPI_NEGATIVE_VALUE ); + + mpi_init( &TB ); + + if( X == B ) + { + MPI_CHK( mpi_copy( &TB, B ) ); + B = &TB; + } + + if( X != A ) + MPI_CHK( mpi_copy( X, A ) ); + + /* + * X should always be positive as a result of unsigned substractions. + */ + X->s = 1; + + ret = 0; + + for( n = B->n; n > 0; n-- ) + if( B->p[n - 1] != 0 ) + break; + + mpi_sub_hlp( n, B->p, X->p ); + +cleanup: + + mpi_free( &TB ); + + return( ret ); +} + +/* + * Signed addition: X = A + B + */ +int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B ) +{ + int ret, s = A->s; + + if( A->s * B->s < 0 ) + { + if( mpi_cmp_abs( A, B ) >= 0 ) + { + MPI_CHK( mpi_sub_abs( X, A, B ) ); + X->s = s; + } + else + { + MPI_CHK( mpi_sub_abs( X, B, A ) ); + X->s = -s; + } + } + else + { + MPI_CHK( mpi_add_abs( X, A, B ) ); + X->s = s; + } + +cleanup: + + return( ret ); +} + +/* + * Signed substraction: X = A - B + */ +int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B ) +{ + int ret, s = A->s; + + if( A->s * B->s > 0 ) + { + if( mpi_cmp_abs( A, B ) >= 0 ) + { + MPI_CHK( mpi_sub_abs( X, A, B ) ); + X->s = s; + } + else + { + MPI_CHK( mpi_sub_abs( X, B, A ) ); + X->s = -s; + } + } + else + { + MPI_CHK( mpi_add_abs( X, A, B ) ); + X->s = s; + } + +cleanup: + + return( ret ); +} + +/* + * Signed addition: X = A + b + */ +int mpi_add_int( mpi *X, const mpi *A, t_sint b ) +{ + mpi _B; + t_uint p[1]; + + p[0] = ( b < 0 ) ? -b : b; + _B.s = ( b < 0 ) ? -1 : 1; + _B.n = 1; + _B.p = p; + + return( mpi_add_mpi( X, A, &_B ) ); +} + +/* + * Signed substraction: X = A - b + */ +int mpi_sub_int( mpi *X, const mpi *A, t_sint b ) +{ + mpi _B; + t_uint p[1]; + + p[0] = ( b < 0 ) ? -b : b; + _B.s = ( b < 0 ) ? -1 : 1; + _B.n = 1; + _B.p = p; + + return( mpi_sub_mpi( X, A, &_B ) ); +} + +/* + * Helper for mpi multiplication + */ +static void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b ) +{ + t_uint c = 0, t = 0; + +#if defined(MULADDC_HUIT) + for( ; i >= 8; i -= 8 ) + { + MULADDC_INIT + MULADDC_HUIT + MULADDC_STOP + } + + for( ; i > 0; i-- ) + { + MULADDC_INIT + MULADDC_CORE + MULADDC_STOP + } +#else + for( ; i >= 16; i -= 16 ) + { + MULADDC_INIT + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_STOP + } + + for( ; i >= 8; i -= 8 ) + { + MULADDC_INIT + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_STOP + } + + for( ; i > 0; i-- ) + { + MULADDC_INIT + MULADDC_CORE + MULADDC_STOP + } +#endif + + t++; + + do { + *d += c; c = ( *d < c ); d++; + } + while( c != 0 ); +} + +/* + * Baseline multiplication: X = A * B (HAC 14.12) + */ +int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B ) +{ + int ret; + size_t i, j; + mpi TA, TB; + + mpi_init( &TA ); mpi_init( &TB ); + + if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; } + if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; } + + for( i = A->n; i > 0; i-- ) + if( A->p[i - 1] != 0 ) + break; + + for( j = B->n; j > 0; j-- ) + if( B->p[j - 1] != 0 ) + break; + + MPI_CHK( mpi_grow( X, i + j ) ); + MPI_CHK( mpi_lset( X, 0 ) ); + + for( i++; j > 0; j-- ) + mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] ); + + X->s = A->s * B->s; + +cleanup: + + mpi_free( &TB ); mpi_free( &TA ); + + return( ret ); +} + +/* + * Baseline multiplication: X = A * b + */ +int mpi_mul_int( mpi *X, const mpi *A, t_sint b ) +{ + mpi _B; + t_uint p[1]; + + _B.s = 1; + _B.n = 1; + _B.p = p; + p[0] = b; + + return( mpi_mul_mpi( X, A, &_B ) ); +} + +/* + * Division by mpi: A = Q * B + R (HAC 14.20) + */ +int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ) +{ + int ret; + size_t i, n, t, k; + mpi X, Y, Z, T1, T2; + + if( mpi_cmp_int( B, 0 ) == 0 ) + return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO ); + + mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z ); + mpi_init( &T1 ); mpi_init( &T2 ); + + if( mpi_cmp_abs( A, B ) < 0 ) + { + if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) ); + if( R != NULL ) MPI_CHK( mpi_copy( R, A ) ); + return( 0 ); + } + + MPI_CHK( mpi_copy( &X, A ) ); + MPI_CHK( mpi_copy( &Y, B ) ); + X.s = Y.s = 1; + + MPI_CHK( mpi_grow( &Z, A->n + 2 ) ); + MPI_CHK( mpi_lset( &Z, 0 ) ); + MPI_CHK( mpi_grow( &T1, 2 ) ); + MPI_CHK( mpi_grow( &T2, 3 ) ); + + k = mpi_msb( &Y ) % biL; + if( k < biL - 1 ) + { + k = biL - 1 - k; + MPI_CHK( mpi_shift_l( &X, k ) ); + MPI_CHK( mpi_shift_l( &Y, k ) ); + } + else k = 0; + + n = X.n - 1; + t = Y.n - 1; + mpi_shift_l( &Y, biL * (n - t) ); + + while( mpi_cmp_mpi( &X, &Y ) >= 0 ) + { + Z.p[n - t]++; + mpi_sub_mpi( &X, &X, &Y ); + } + mpi_shift_r( &Y, biL * (n - t) ); + + for( i = n; i > t ; i-- ) + { + if( X.p[i] >= Y.p[t] ) + Z.p[i - t - 1] = ~0; + else + { +#if defined(POLARSSL_HAVE_LONGLONG) + t_dbl r; + + r = (t_dbl) X.p[i] << biL; + r |= (t_dbl) X.p[i - 1]; + r /= Y.p[t]; + if( r > ((t_dbl) 1 << biL) - 1) + r = ((t_dbl) 1 << biL) - 1; + + Z.p[i - t - 1] = (t_uint) r; +#else + /* + * __udiv_qrnnd_c, from gmp/longlong.h + */ + t_uint q0, q1, r0, r1; + t_uint d0, d1, d, m; + + d = Y.p[t]; + d0 = ( d << biH ) >> biH; + d1 = ( d >> biH ); + + q1 = X.p[i] / d1; + r1 = X.p[i] - d1 * q1; + r1 <<= biH; + r1 |= ( X.p[i - 1] >> biH ); + + m = q1 * d0; + if( r1 < m ) + { + q1--, r1 += d; + while( r1 >= d && r1 < m ) + q1--, r1 += d; + } + r1 -= m; + + q0 = r1 / d1; + r0 = r1 - d1 * q0; + r0 <<= biH; + r0 |= ( X.p[i - 1] << biH ) >> biH; + + m = q0 * d0; + if( r0 < m ) + { + q0--, r0 += d; + while( r0 >= d && r0 < m ) + q0--, r0 += d; + } + r0 -= m; + + Z.p[i - t - 1] = ( q1 << biH ) | q0; +#endif + } + + Z.p[i - t - 1]++; + do + { + Z.p[i - t - 1]--; + + MPI_CHK( mpi_lset( &T1, 0 ) ); + T1.p[0] = (t < 1) ? 0 : Y.p[t - 1]; + T1.p[1] = Y.p[t]; + MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) ); + + MPI_CHK( mpi_lset( &T2, 0 ) ); + T2.p[0] = (i < 2) ? 0 : X.p[i - 2]; + T2.p[1] = (i < 1) ? 0 : X.p[i - 1]; + T2.p[2] = X.p[i]; + } + while( mpi_cmp_mpi( &T1, &T2 ) > 0 ); + + MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) ); + MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) ); + MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) ); + + if( mpi_cmp_int( &X, 0 ) < 0 ) + { + MPI_CHK( mpi_copy( &T1, &Y ) ); + MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) ); + MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) ); + Z.p[i - t - 1]--; + } + } + + if( Q != NULL ) + { + mpi_copy( Q, &Z ); + Q->s = A->s * B->s; + } + + if( R != NULL ) + { + mpi_shift_r( &X, k ); + mpi_copy( R, &X ); + + R->s = A->s; + if( mpi_cmp_int( R, 0 ) == 0 ) + R->s = 1; + } + +cleanup: + + mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z ); + mpi_free( &T1 ); mpi_free( &T2 ); + + return( ret ); +} + +/* + * Division by int: A = Q * b + R + * + * Returns 0 if successful + * 1 if memory allocation failed + * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0 + */ +int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b ) +{ + mpi _B; + t_uint p[1]; + + p[0] = ( b < 0 ) ? -b : b; + _B.s = ( b < 0 ) ? -1 : 1; + _B.n = 1; + _B.p = p; + + return( mpi_div_mpi( Q, R, A, &_B ) ); +} + +/* + * Modulo: R = A mod B + */ +int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B ) +{ + int ret; + + if( mpi_cmp_int( B, 0 ) < 0 ) + return POLARSSL_ERR_MPI_NEGATIVE_VALUE; + + MPI_CHK( mpi_div_mpi( NULL, R, A, B ) ); + + while( mpi_cmp_int( R, 0 ) < 0 ) + MPI_CHK( mpi_add_mpi( R, R, B ) ); + + while( mpi_cmp_mpi( R, B ) >= 0 ) + MPI_CHK( mpi_sub_mpi( R, R, B ) ); + +cleanup: + + return( ret ); +} + +/* + * Modulo: r = A mod b + */ +int mpi_mod_int( t_uint *r, const mpi *A, t_sint b ) +{ + size_t i; + t_uint x, y, z; + + if( b == 0 ) + return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO ); + + if( b < 0 ) + return POLARSSL_ERR_MPI_NEGATIVE_VALUE; + + /* + * handle trivial cases + */ + if( b == 1 ) + { + *r = 0; + return( 0 ); + } + + if( b == 2 ) + { + *r = A->p[0] & 1; + return( 0 ); + } + + /* + * general case + */ + for( i = A->n, y = 0; i > 0; i-- ) + { + x = A->p[i - 1]; + y = ( y << biH ) | ( x >> biH ); + z = y / b; + y -= z * b; + + x <<= biH; + y = ( y << biH ) | ( x >> biH ); + z = y / b; + y -= z * b; + } + + /* + * If A is negative, then the current y represents a negative value. + * Flipping it to the positive side. + */ + if( A->s < 0 && y != 0 ) + y = b - y; + + *r = y; + + return( 0 ); +} + +/* + * Fast Montgomery initialization (thanks to Tom St Denis) + */ +static void mpi_montg_init( t_uint *mm, const mpi *N ) +{ + t_uint x, m0 = N->p[0]; + + x = m0; + x += ( ( m0 + 2 ) & 4 ) << 1; + x *= ( 2 - ( m0 * x ) ); + + if( biL >= 16 ) x *= ( 2 - ( m0 * x ) ); + if( biL >= 32 ) x *= ( 2 - ( m0 * x ) ); + if( biL >= 64 ) x *= ( 2 - ( m0 * x ) ); + + *mm = ~x + 1; +} + +/* + * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) + */ +static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, const mpi *T ) +{ + size_t i, n, m; + t_uint u0, u1, *d; + + memset( T->p, 0, T->n * ciL ); + + d = T->p; + n = N->n; + m = ( B->n < n ) ? B->n : n; + + for( i = 0; i < n; i++ ) + { + /* + * T = (T + u0*B + u1*N) / 2^biL + */ + u0 = A->p[i]; + u1 = ( d[0] + u0 * B->p[0] ) * mm; + + mpi_mul_hlp( m, B->p, d, u0 ); + mpi_mul_hlp( n, N->p, d, u1 ); + + *d++ = u0; d[n + 1] = 0; + } + + memcpy( A->p, d, (n + 1) * ciL ); + + if( mpi_cmp_abs( A, N ) >= 0 ) + mpi_sub_hlp( n, N->p, A->p ); + else + /* prevent timing attacks */ + mpi_sub_hlp( n, A->p, T->p ); +} + +/* + * Montgomery reduction: A = A * R^-1 mod N + */ +static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T ) +{ + t_uint z = 1; + mpi U; + + U.n = U.s = z; + U.p = &z; + + mpi_montmul( A, &U, N, mm, T ); +} + +/* + * Sliding-window exponentiation: X = A^E mod N (HAC 14.85) + */ +int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ) +{ + int ret; + size_t wbits, wsize, one = 1; + size_t i, j, nblimbs; + size_t bufsize, nbits; + t_uint ei, mm, state; + mpi RR, T, W[64]; + + if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + /* + * Init temps and window size + */ + mpi_montg_init( &mm, N ); + mpi_init( &RR ); mpi_init( &T ); + memset( W, 0, sizeof( W ) ); + + i = mpi_msb( E ); + + wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 : + ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1; + + j = N->n + 1; + MPI_CHK( mpi_grow( X, j ) ); + MPI_CHK( mpi_grow( &W[1], j ) ); + MPI_CHK( mpi_grow( &T, j * 2 ) ); + + /* + * If 1st call, pre-compute R^2 mod N + */ + if( _RR == NULL || _RR->p == NULL ) + { + MPI_CHK( mpi_lset( &RR, 1 ) ); + MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) ); + MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) ); + + if( _RR != NULL ) + memcpy( _RR, &RR, sizeof( mpi ) ); + } + else + memcpy( &RR, _RR, sizeof( mpi ) ); + + /* + * W[1] = A * R^2 * R^-1 mod N = A * R mod N + */ + if( mpi_cmp_mpi( A, N ) >= 0 ) + mpi_mod_mpi( &W[1], A, N ); + else mpi_copy( &W[1], A ); + + mpi_montmul( &W[1], &RR, N, mm, &T ); + + /* + * X = R^2 * R^-1 mod N = R mod N + */ + MPI_CHK( mpi_copy( X, &RR ) ); + mpi_montred( X, N, mm, &T ); + + if( wsize > 1 ) + { + /* + * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1) + */ + j = one << (wsize - 1); + + MPI_CHK( mpi_grow( &W[j], N->n + 1 ) ); + MPI_CHK( mpi_copy( &W[j], &W[1] ) ); + + for( i = 0; i < wsize - 1; i++ ) + mpi_montmul( &W[j], &W[j], N, mm, &T ); + + /* + * W[i] = W[i - 1] * W[1] + */ + for( i = j + 1; i < (one << wsize); i++ ) + { + MPI_CHK( mpi_grow( &W[i], N->n + 1 ) ); + MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) ); + + mpi_montmul( &W[i], &W[1], N, mm, &T ); + } + } + + nblimbs = E->n; + bufsize = 0; + nbits = 0; + wbits = 0; + state = 0; + + while( 1 ) + { + if( bufsize == 0 ) + { + if( nblimbs-- == 0 ) + break; + + bufsize = sizeof( t_uint ) << 3; + } + + bufsize--; + + ei = (E->p[nblimbs] >> bufsize) & 1; + + /* + * skip leading 0s + */ + if( ei == 0 && state == 0 ) + continue; + + if( ei == 0 && state == 1 ) + { + /* + * out of window, square X + */ + mpi_montmul( X, X, N, mm, &T ); + continue; + } + + /* + * add ei to current window + */ + state = 2; + + nbits++; + wbits |= (ei << (wsize - nbits)); + + if( nbits == wsize ) + { + /* + * X = X^wsize R^-1 mod N + */ + for( i = 0; i < wsize; i++ ) + mpi_montmul( X, X, N, mm, &T ); + + /* + * X = X * W[wbits] R^-1 mod N + */ + mpi_montmul( X, &W[wbits], N, mm, &T ); + + state--; + nbits = 0; + wbits = 0; + } + } + + /* + * process the remaining bits + */ + for( i = 0; i < nbits; i++ ) + { + mpi_montmul( X, X, N, mm, &T ); + + wbits <<= 1; + + if( (wbits & (one << wsize)) != 0 ) + mpi_montmul( X, &W[1], N, mm, &T ); + } + + /* + * X = A^E * R * R^-1 mod N = A^E mod N + */ + mpi_montred( X, N, mm, &T ); + +cleanup: + + for( i = (one << (wsize - 1)); i < (one << wsize); i++ ) + mpi_free( &W[i] ); + + mpi_free( &W[1] ); mpi_free( &T ); + + if( _RR == NULL ) + mpi_free( &RR ); + + return( ret ); +} + +/* + * Greatest common divisor: G = gcd(A, B) (HAC 14.54) + */ +int mpi_gcd( mpi *G, const mpi *A, const mpi *B ) +{ + int ret; + size_t lz, lzt; + mpi TG, TA, TB; + + mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB ); + + MPI_CHK( mpi_copy( &TA, A ) ); + MPI_CHK( mpi_copy( &TB, B ) ); + + lz = mpi_lsb( &TA ); + lzt = mpi_lsb( &TB ); + + if ( lzt < lz ) + lz = lzt; + + MPI_CHK( mpi_shift_r( &TA, lz ) ); + MPI_CHK( mpi_shift_r( &TB, lz ) ); + + TA.s = TB.s = 1; + + while( mpi_cmp_int( &TA, 0 ) != 0 ) + { + MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) ); + MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) ); + + if( mpi_cmp_mpi( &TA, &TB ) >= 0 ) + { + MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) ); + MPI_CHK( mpi_shift_r( &TA, 1 ) ); + } + else + { + MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) ); + MPI_CHK( mpi_shift_r( &TB, 1 ) ); + } + } + + MPI_CHK( mpi_shift_l( &TB, lz ) ); + MPI_CHK( mpi_copy( G, &TB ) ); + +cleanup: + + mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB ); + + return( ret ); +} + +int mpi_fill_random( mpi *X, size_t size, int (*f_rng)(void *), void *p_rng ) +{ + int ret; + size_t k; + unsigned char *p; + + MPI_CHK( mpi_grow( X, size ) ); + MPI_CHK( mpi_lset( X, 0 ) ); + + p = (unsigned char *) X->p; + for( k = 0; k < X->n * ciL; k++ ) + *p++ = (unsigned char) f_rng( p_rng ); + +cleanup: + return( ret ); +} + +#if defined(POLARSSL_GENPRIME) + +/* + * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64) + */ +int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N ) +{ + int ret; + mpi G, TA, TU, U1, U2, TB, TV, V1, V2; + + if( mpi_cmp_int( N, 0 ) <= 0 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 ); + mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV ); + mpi_init( &V1 ); mpi_init( &V2 ); + + MPI_CHK( mpi_gcd( &G, A, N ) ); + + if( mpi_cmp_int( &G, 1 ) != 0 ) + { + ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE; + goto cleanup; + } + + MPI_CHK( mpi_mod_mpi( &TA, A, N ) ); + MPI_CHK( mpi_copy( &TU, &TA ) ); + MPI_CHK( mpi_copy( &TB, N ) ); + MPI_CHK( mpi_copy( &TV, N ) ); + + MPI_CHK( mpi_lset( &U1, 1 ) ); + MPI_CHK( mpi_lset( &U2, 0 ) ); + MPI_CHK( mpi_lset( &V1, 0 ) ); + MPI_CHK( mpi_lset( &V2, 1 ) ); + + do + { + while( ( TU.p[0] & 1 ) == 0 ) + { + MPI_CHK( mpi_shift_r( &TU, 1 ) ); + + if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 ) + { + MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) ); + MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) ); + } + + MPI_CHK( mpi_shift_r( &U1, 1 ) ); + MPI_CHK( mpi_shift_r( &U2, 1 ) ); + } + + while( ( TV.p[0] & 1 ) == 0 ) + { + MPI_CHK( mpi_shift_r( &TV, 1 ) ); + + if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 ) + { + MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) ); + MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) ); + } + + MPI_CHK( mpi_shift_r( &V1, 1 ) ); + MPI_CHK( mpi_shift_r( &V2, 1 ) ); + } + + if( mpi_cmp_mpi( &TU, &TV ) >= 0 ) + { + MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) ); + MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) ); + MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) ); + } + else + { + MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) ); + MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) ); + MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) ); + } + } + while( mpi_cmp_int( &TU, 0 ) != 0 ); + + while( mpi_cmp_int( &V1, 0 ) < 0 ) + MPI_CHK( mpi_add_mpi( &V1, &V1, N ) ); + + while( mpi_cmp_mpi( &V1, N ) >= 0 ) + MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) ); + + MPI_CHK( mpi_copy( X, &V1 ) ); + +cleanup: + + mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 ); + mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV ); + mpi_free( &V1 ); mpi_free( &V2 ); + + return( ret ); +} + +static const int small_prime[] = +{ + 3, 5, 7, 11, 13, 17, 19, 23, + 29, 31, 37, 41, 43, 47, 53, 59, + 61, 67, 71, 73, 79, 83, 89, 97, + 101, 103, 107, 109, 113, 127, 131, 137, + 139, 149, 151, 157, 163, 167, 173, 179, + 181, 191, 193, 197, 199, 211, 223, 227, + 229, 233, 239, 241, 251, 257, 263, 269, + 271, 277, 281, 283, 293, 307, 311, 313, + 317, 331, 337, 347, 349, 353, 359, 367, + 373, 379, 383, 389, 397, 401, 409, 419, + 421, 431, 433, 439, 443, 449, 457, 461, + 463, 467, 479, 487, 491, 499, 503, 509, + 521, 523, 541, 547, 557, 563, 569, 571, + 577, 587, 593, 599, 601, 607, 613, 617, + 619, 631, 641, 643, 647, 653, 659, 661, + 673, 677, 683, 691, 701, 709, 719, 727, + 733, 739, 743, 751, 757, 761, 769, 773, + 787, 797, 809, 811, 821, 823, 827, 829, + 839, 853, 857, 859, 863, 877, 881, 883, + 887, 907, 911, 919, 929, 937, 941, 947, + 953, 967, 971, 977, 983, 991, 997, -103 +}; + +/* + * Miller-Rabin primality test (HAC 4.24) + */ +int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng ) +{ + int ret, xs; + size_t i, j, n, s; + mpi W, R, T, A, RR; + + if( mpi_cmp_int( X, 0 ) == 0 || + mpi_cmp_int( X, 1 ) == 0 ) + return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); + + if( mpi_cmp_int( X, 2 ) == 0 ) + return( 0 ); + + mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A ); + mpi_init( &RR ); + + xs = X->s; X->s = 1; + + /* + * test trivial factors first + */ + if( ( X->p[0] & 1 ) == 0 ) + return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); + + for( i = 0; small_prime[i] > 0; i++ ) + { + t_uint r; + + if( mpi_cmp_int( X, small_prime[i] ) <= 0 ) + return( 0 ); + + MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) ); + + if( r == 0 ) + return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); + } + + /* + * W = |X| - 1 + * R = W >> lsb( W ) + */ + MPI_CHK( mpi_sub_int( &W, X, 1 ) ); + s = mpi_lsb( &W ); + MPI_CHK( mpi_copy( &R, &W ) ); + MPI_CHK( mpi_shift_r( &R, s ) ); + + i = mpi_msb( X ); + /* + * HAC, table 4.4 + */ + n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 : + ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 : + ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 ); + + for( i = 0; i < n; i++ ) + { + /* + * pick a random A, 1 < A < |X| - 1 + */ + mpi_fill_random( &A, X->n, f_rng, p_rng ); + + if( mpi_cmp_mpi( &A, &W ) >= 0 ) + { + j = mpi_msb( &A ) - mpi_msb( &W ); + MPI_CHK( mpi_shift_r( &A, j + 1 ) ); + } + A.p[0] |= 3; + + /* + * A = A^R mod |X| + */ + MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) ); + + if( mpi_cmp_mpi( &A, &W ) == 0 || + mpi_cmp_int( &A, 1 ) == 0 ) + continue; + + j = 1; + while( j < s && mpi_cmp_mpi( &A, &W ) != 0 ) + { + /* + * A = A * A mod |X| + */ + MPI_CHK( mpi_mul_mpi( &T, &A, &A ) ); + MPI_CHK( mpi_mod_mpi( &A, &T, X ) ); + + if( mpi_cmp_int( &A, 1 ) == 0 ) + break; + + j++; + } + + /* + * not prime if A != |X| - 1 or A == 1 + */ + if( mpi_cmp_mpi( &A, &W ) != 0 || + mpi_cmp_int( &A, 1 ) == 0 ) + { + ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE; + break; + } + } + +cleanup: + + X->s = xs; + + mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A ); + mpi_free( &RR ); + + return( ret ); +} + +/* + * Prime number generation + */ +int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag, + int (*f_rng)(void *), void *p_rng ) +{ + int ret; + size_t k, n; + mpi Y; + + if( nbits < 3 || nbits > 4096 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + mpi_init( &Y ); + + n = BITS_TO_LIMBS( nbits ); + + mpi_fill_random( X, n, f_rng, p_rng ); + + k = mpi_msb( X ); + if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) ); + if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) ); + + X->p[0] |= 3; + + if( dh_flag == 0 ) + { + while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 ) + { + if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) + goto cleanup; + + MPI_CHK( mpi_add_int( X, X, 2 ) ); + } + } + else + { + MPI_CHK( mpi_sub_int( &Y, X, 1 ) ); + MPI_CHK( mpi_shift_r( &Y, 1 ) ); + + while( 1 ) + { + if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 ) + { + if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 ) + break; + + if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) + goto cleanup; + } + + if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) + goto cleanup; + + MPI_CHK( mpi_add_int( &Y, X, 1 ) ); + MPI_CHK( mpi_add_int( X, X, 2 ) ); + MPI_CHK( mpi_shift_r( &Y, 1 ) ); + } + } + +cleanup: + + mpi_free( &Y ); + + return( ret ); +} + +#endif + +#if defined(POLARSSL_SELF_TEST) + +#define GCD_PAIR_COUNT 3 + +static const int gcd_pairs[GCD_PAIR_COUNT][3] = +{ + { 693, 609, 21 }, + { 1764, 868, 28 }, + { 768454923, 542167814, 1 } +}; + +/* + * Checkup routine + */ +int mpi_self_test( int verbose ) +{ + int ret, i; + mpi A, E, N, X, Y, U, V; + + mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X ); + mpi_init( &Y ); mpi_init( &U ); mpi_init( &V ); + + MPI_CHK( mpi_read_string( &A, 16, + "EFE021C2645FD1DC586E69184AF4A31E" \ + "D5F53E93B5F123FA41680867BA110131" \ + "944FE7952E2517337780CB0DB80E61AA" \ + "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) ); + + MPI_CHK( mpi_read_string( &E, 16, + "B2E7EFD37075B9F03FF989C7C5051C20" \ + "34D2A323810251127E7BF8625A4F49A5" \ + "F3E27F4DA8BD59C47D6DAABA4C8127BD" \ + "5B5C25763222FEFCCFC38B832366C29E" ) ); + + MPI_CHK( mpi_read_string( &N, 16, + "0066A198186C18C10B2F5ED9B522752A" \ + "9830B69916E535C8F047518A889A43A5" \ + "94B6BED27A168D31D4A52F88925AA8F5" ) ); + + MPI_CHK( mpi_mul_mpi( &X, &A, &N ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "602AB7ECA597A3D6B56FF9829A5E8B85" \ + "9E857EA95A03512E2BAE7391688D264A" \ + "A5663B0341DB9CCFD2C4C5F421FEC814" \ + "8001B72E848A38CAE1C65F78E56ABDEF" \ + "E12D3C039B8A02D6BE593F0BBBDA56F1" \ + "ECF677152EF804370C1A305CAF3B5BF1" \ + "30879B56C61DE584A0F53A2447A51E" ) ); + + if( verbose != 0 ) + printf( " MPI test #1 (mul_mpi): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + + MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "256567336059E52CAE22925474705F39A94" ) ); + + MPI_CHK( mpi_read_string( &V, 16, + "6613F26162223DF488E9CD48CC132C7A" \ + "0AC93C701B001B092E4E5B9F73BCD27B" \ + "9EE50D0657C77F374E903CDFA4C642" ) ); + + if( verbose != 0 ) + printf( " MPI test #2 (div_mpi): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 || + mpi_cmp_mpi( &Y, &V ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + + MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "36E139AEA55215609D2816998ED020BB" \ + "BD96C37890F65171D948E9BC7CBAA4D9" \ + "325D24D6A3C12710F10A09FA08AB87" ) ); + + if( verbose != 0 ) + printf( " MPI test #3 (exp_mod): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + +#if defined(POLARSSL_GENPRIME) + MPI_CHK( mpi_inv_mod( &X, &A, &N ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \ + "C3DBA76456363A10869622EAC2DD84EC" \ + "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) ); + + if( verbose != 0 ) + printf( " MPI test #4 (inv_mod): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); +#endif + + if( verbose != 0 ) + printf( " MPI test #5 (simple gcd): " ); + + for ( i = 0; i < GCD_PAIR_COUNT; i++) + { + MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) ); + MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) ); + + MPI_CHK( mpi_gcd( &A, &X, &Y ) ); + + if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 ) + { + if( verbose != 0 ) + printf( "failed at %d\n", i ); + + return( 1 ); + } + } + + if( verbose != 0 ) + printf( "passed\n" ); + +cleanup: + + if( ret != 0 && verbose != 0 ) + printf( "Unexpected error, return code = %08X\n", ret ); + + mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X ); + mpi_free( &Y ); mpi_free( &U ); mpi_free( &V ); + + if( verbose != 0 ) + printf( "\n" ); + + return( ret ); +} + +#endif + +#endif diff --git a/plugins/!NotAdopted/Tlen/crypto/padlock.c b/plugins/!NotAdopted/Tlen/crypto/padlock.c new file mode 100644 index 0000000000..2e2e4775ff --- /dev/null +++ b/plugins/!NotAdopted/Tlen/crypto/padlock.c @@ -0,0 +1,162 @@ +/* + * VIA PadLock support functions + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * This implementation is based on the VIA PadLock Programming Guide: + * + * http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/ + * programming_guide.pdf + */ + +#include "polarssl/config.h" + +#if defined(POLARSSL_PADLOCK_C) + +#include "polarssl/padlock.h" + +#if defined(POLARSSL_HAVE_X86) + +/* + * PadLock detection routine + */ +int padlock_supports( int feature ) +{ + static int flags = -1; + int ebx, edx; + + if( flags == -1 ) + { + asm( "movl %%ebx, %0 \n" \ + "movl $0xC0000000, %%eax \n" \ + "cpuid \n" \ + "cmpl $0xC0000001, %%eax \n" \ + "movl $0, %%edx \n" \ + "jb unsupported \n" \ + "movl $0xC0000001, %%eax \n" \ + "cpuid \n" \ + "unsupported: \n" \ + "movl %%edx, %1 \n" \ + "movl %2, %%ebx \n" + : "=m" (ebx), "=m" (edx) + : "m" (ebx) + : "eax", "ecx", "edx" ); + + flags = edx; + } + + return( flags & feature ); +} + +/* + * PadLock AES-ECB block en(de)cryption + */ +int padlock_xcryptecb( aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ + int ebx; + unsigned long *rk; + unsigned long *blk; + unsigned long *ctrl; + unsigned char buf[256]; + + rk = ctx->rk; + blk = PADLOCK_ALIGN16( buf ); + memcpy( blk, input, 16 ); + + ctrl = blk + 4; + *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 ); + + asm( "pushfl; popfl \n" \ + "movl %%ebx, %0 \n" \ + "movl $1, %%ecx \n" \ + "movl %2, %%edx \n" \ + "movl %3, %%ebx \n" \ + "movl %4, %%esi \n" \ + "movl %4, %%edi \n" \ + ".byte 0xf3,0x0f,0xa7,0xc8\n" \ + "movl %1, %%ebx \n" + : "=m" (ebx) + : "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk) + : "ecx", "edx", "esi", "edi" ); + + memcpy( output, blk, 16 ); + + return( 0 ); +} + +/* + * PadLock AES-CBC buffer en(de)cryption + */ +int padlock_xcryptcbc( aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int ebx; + size_t count; + unsigned long *rk; + unsigned long *iw; + unsigned long *ctrl; + unsigned char buf[256]; + + if( ( (long) input & 15 ) != 0 || + ( (long) output & 15 ) != 0 ) + return( POLARSSL_ERR_PADLOCK_DATA_MISALIGNED ); + + rk = ctx->rk; + iw = PADLOCK_ALIGN16( buf ); + memcpy( iw, iv, 16 ); + + ctrl = iw + 4; + *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + (mode^1) - 10 ) << 9 ); + + count = (length + 15) >> 4; + + asm( "pushfl; popfl \n" \ + "movl %%ebx, %0 \n" \ + "movl %2, %%ecx \n" \ + "movl %3, %%edx \n" \ + "movl %4, %%ebx \n" \ + "movl %5, %%esi \n" \ + "movl %6, %%edi \n" \ + "movl %7, %%eax \n" \ + ".byte 0xf3,0x0f,0xa7,0xd0\n" \ + "movl %1, %%ebx \n" + : "=m" (ebx) + : "m" (ebx), "m" (count), "m" (ctrl), + "m" (rk), "m" (input), "m" (output), "m" (iw) + : "eax", "ecx", "edx", "esi", "edi" ); + + memcpy( iv, iw, 16 ); + + return( 0 ); +} + +#endif + +#endif diff --git a/plugins/!NotAdopted/Tlen/crypto/polarssl/aes.h b/plugins/!NotAdopted/Tlen/crypto/polarssl/aes.h new file mode 100644 index 0000000000..efc13daf5b --- /dev/null +++ b/plugins/!NotAdopted/Tlen/crypto/polarssl/aes.h @@ -0,0 +1,167 @@ +/** + * \file aes.h + * + * \brief AES block cipher + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_AES_H +#define POLARSSL_AES_H + +#include + +#define AES_ENCRYPT 1 +#define AES_DECRYPT 0 + +#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */ +#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */ + +/** + * \brief AES context structure + */ +typedef struct +{ + int nr; /*!< number of rounds */ + unsigned long *rk; /*!< AES round keys */ + unsigned long buf[68]; /*!< unaligned data */ +} +aes_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief AES key schedule (encryption) + * + * \param ctx AES context to be initialized + * \param key encryption key + * \param keysize must be 128, 192 or 256 + * + * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH + */ +int aes_setkey_enc( aes_context *ctx, const unsigned char *key, unsigned int keysize ); + +/** + * \brief AES key schedule (decryption) + * + * \param ctx AES context to be initialized + * \param key decryption key + * \param keysize must be 128, 192 or 256 + * + * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH + */ +int aes_setkey_dec( aes_context *ctx, const unsigned char *key, unsigned int keysize ); + +/** + * \brief AES-ECB block encryption/decryption + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block + * + * \return 0 if successful + */ +int aes_crypt_ecb( aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ); + +/** + * \brief AES-CBC buffer encryption/decryption + * Length should be a multiple of the block + * size (16 bytes) + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH + */ +int aes_crypt_cbc( aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +/** + * \brief AES-CFB128 buffer encryption/decryption. + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param length length of the input data + * \param iv_off offset in IV (updated after use) + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful + */ +int aes_crypt_cfb128( aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +/* + * \brief AES-CTR buffer encryption/decryption + * + * Warning: You have to keep the maximum use of your counter in mind! + * + * \param length The length of the data + * \param nc_off The offset in the current stream_block (for resuming + * within current cipher stream). The offset pointer to + * should be 0 at the start of a stream. + * \param nonce_counter The 128-bit nonce and counter. + * \param stream_block The saved stream-block for resuming. Is overwritten + * by the function. + * \param input The input data stream + * \param output The output data stream + * + * \return 0 if successful + */ +int aes_crypt_ctr( aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ); +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int aes_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* aes.h */ diff --git a/plugins/!NotAdopted/Tlen/crypto/polarssl/bignum.h b/plugins/!NotAdopted/Tlen/crypto/polarssl/bignum.h new file mode 100644 index 0000000000..7938406708 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/crypto/polarssl/bignum.h @@ -0,0 +1,587 @@ +/** + * \file bignum.h + * + * \brief Multi-precision integer library + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_BIGNUM_H +#define POLARSSL_BIGNUM_H + +#include +#include + +#define POLARSSL_ERR_MPI_FILE_IO_ERROR -0x0002 /**< An error occurred while reading from or writing to a file. */ +#define POLARSSL_ERR_MPI_BAD_INPUT_DATA -0x0004 /**< Bad input parameters to function. */ +#define POLARSSL_ERR_MPI_INVALID_CHARACTER -0x0006 /**< There is an invalid character in the digit string. */ +#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL -0x0008 /**< The output buffer is too small to write too. */ +#define POLARSSL_ERR_MPI_NEGATIVE_VALUE -0x000A /**< The input arguments are negative or result in illegal output. */ +#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO -0x000C /**< The input argument for division is zero, which is not allowed. */ +#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */ + +#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup + +/* + * Maximum size MPIs are allowed to grow to in number of limbs. + */ +#define POLARSSL_MPI_MAX_LIMBS 10000 + +/* + * Define the base integer type, architecture-wise + */ +#if defined(POLARSSL_HAVE_INT8) +typedef signed char t_sint; +typedef unsigned char t_uint; +typedef unsigned short t_udbl; +#else +#if defined(POLARSSL_HAVE_INT16) +typedef signed short t_sint; +typedef unsigned short t_uint; +typedef unsigned long t_udbl; +#else + typedef signed long t_sint; + typedef unsigned long t_uint; + #if defined(_MSC_VER) && defined(_M_IX86) + typedef unsigned __int64 t_udbl; + #else + #if defined(__amd64__) || defined(__x86_64__) || \ + defined(__ppc64__) || defined(__powerpc64__) || \ + defined(__ia64__) || defined(__alpha__) + typedef unsigned int t_udbl __attribute__((mode(TI))); + #else + #if defined(POLARSSL_HAVE_LONGLONG) + typedef unsigned long long t_udbl; + #endif + #endif + #endif +#endif +#endif + +/** + * \brief MPI structure + */ +typedef struct +{ + int s; /*!< integer sign */ + size_t n; /*!< total # of limbs */ + t_uint *p; /*!< pointer to limbs */ +} +mpi; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Initialize one MPI + * + * \param X One MPI to initialize. + */ +void mpi_init( mpi *X ); + +/** + * \brief Unallocate one MPI + * + * \param X One MPI to unallocate. + */ +void mpi_free( mpi *X ); + +/** + * \brief Enlarge to the specified number of limbs + * + * \param X MPI to grow + * \param nblimbs The target number of limbs + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_grow( mpi *X, size_t nblimbs ); + +/** + * \brief Copy the contents of Y into X + * + * \param X Destination MPI + * \param Y Source MPI + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_copy( mpi *X, const mpi *Y ); + +/** + * \brief Swap the contents of X and Y + * + * \param X First MPI value + * \param Y Second MPI value + */ +void mpi_swap( mpi *X, mpi *Y ); + +/** + * \brief Set value from integer + * + * \param X MPI to set + * \param z Value to use + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_lset( mpi *X, t_sint z ); + +/* + * \brief Get a specific bit from X + * + * \param X MPI to use + * \param pos Zero-based index of the bit in X + * + * \return Either a 0 or a 1 + */ +int mpi_get_bit( mpi *X, size_t pos ); + +/* + * \brief Set a bit of X to a specific value of 0 or 1 + * + * \note Will grow X if necessary to set a bit to 1 in a not yet + * existing limb. Will not grow if bit should be set to 0 + * + * \param X MPI to use + * \param pos Zero-based index of the bit in X + * \param val The value to set the bit to (0 or 1) + * + * \return 0 if successful, + * 1 if memory allocation failed, + * POLARSSL_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1 + */ +int mpi_set_bit( mpi *X, size_t pos, unsigned char val ); + +/** + * \brief Return the number of least significant bits + * + * \param X MPI to use + */ +size_t mpi_lsb( const mpi *X ); + +/** + * \brief Return the number of most significant bits + * + * \param X MPI to use + */ +size_t mpi_msb( const mpi *X ); + +/** + * \brief Return the total size in bytes + * + * \param X MPI to use + */ +size_t mpi_size( const mpi *X ); + +/** + * \brief Import from an ASCII string + * + * \param X Destination MPI + * \param radix Input numeric base + * \param s Null-terminated string buffer + * + * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code + */ +int mpi_read_string( mpi *X, int radix, const char *s ); + +/** + * \brief Export into an ASCII string + * + * \param X Source MPI + * \param radix Output numeric base + * \param s String buffer + * \param slen String buffer size + * + * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code. + * *slen is always updated to reflect the amount + * of data that has (or would have) been written. + * + * \note Call this function with *slen = 0 to obtain the + * minimum required buffer size in *slen. + */ +int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen ); + +/** + * \brief Read X from an opened file + * + * \param X Destination MPI + * \param radix Input numeric base + * \param fin Input file handle + * + * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code + */ +int mpi_read_file( mpi *X, int radix, FILE *fin ); + +/** + * \brief Write X into an opened file, or stdout if fout is NULL + * + * \param p Prefix, can be NULL + * \param X Source MPI + * \param radix Output numeric base + * \param fout Output file handle (can be NULL) + * + * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code + * + * \note Set fout == NULL to print X on the console. + */ +int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout ); + +/** + * \brief Import X from unsigned binary data, big endian + * + * \param X Destination MPI + * \param buf Input buffer + * \param buflen Input buffer size + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen ); + +/** + * \brief Export X into unsigned binary data, big endian + * + * \param X Source MPI + * \param buf Output buffer + * \param buflen Output buffer size + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough + */ +int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen ); + +/** + * \brief Left-shift: X <<= count + * + * \param X MPI to shift + * \param count Amount to shift + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_shift_l( mpi *X, size_t count ); + +/** + * \brief Right-shift: X >>= count + * + * \param X MPI to shift + * \param count Amount to shift + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_shift_r( mpi *X, size_t count ); + +/** + * \brief Compare unsigned values + * + * \param X Left-hand MPI + * \param Y Right-hand MPI + * + * \return 1 if |X| is greater than |Y|, + * -1 if |X| is lesser than |Y| or + * 0 if |X| is equal to |Y| + */ +int mpi_cmp_abs( const mpi *X, const mpi *Y ); + +/** + * \brief Compare signed values + * + * \param X Left-hand MPI + * \param Y Right-hand MPI + * + * \return 1 if X is greater than Y, + * -1 if X is lesser than Y or + * 0 if X is equal to Y + */ +int mpi_cmp_mpi( const mpi *X, const mpi *Y ); + +/** + * \brief Compare signed values + * + * \param X Left-hand MPI + * \param z The integer value to compare to + * + * \return 1 if X is greater than z, + * -1 if X is lesser than z or + * 0 if X is equal to z + */ +int mpi_cmp_int( const mpi *X, t_sint z ); + +/** + * \brief Unsigned addition: X = |A| + |B| + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_add_abs( mpi *X, const mpi *A, const mpi *B ); + +/** + * \brief Unsigned substraction: X = |A| - |B| + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A + */ +int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B ); + +/** + * \brief Signed addition: X = A + B + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B ); + +/** + * \brief Signed substraction: X = A - B + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B ); + +/** + * \brief Signed addition: X = A + b + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param b The integer value to add + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_add_int( mpi *X, const mpi *A, t_sint b ); + +/** + * \brief Signed substraction: X = A - b + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param b The integer value to subtract + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_sub_int( mpi *X, const mpi *A, t_sint b ); + +/** + * \brief Baseline multiplication: X = A * B + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B ); + +/** + * \brief Baseline multiplication: X = A * b + * Note: b is an unsigned integer type, thus + * Negative values of b are ignored. + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param b The integer value to multiply with + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_mul_int( mpi *X, const mpi *A, t_sint b ); + +/** + * \brief Division by mpi: A = Q * B + R + * + * \param Q Destination MPI for the quotient + * \param R Destination MPI for the rest value + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * 1 if memory allocation failed, + * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0 + * + * \note Either Q or R can be NULL. + */ +int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ); + +/** + * \brief Division by int: A = Q * b + R + * + * \param Q Destination MPI for the quotient + * \param R Destination MPI for the rest value + * \param A Left-hand MPI + * \param b Integer to divide by + * + * \return 0 if successful, + * 1 if memory allocation failed, + * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0 + * + * \note Either Q or R can be NULL. + */ +int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b ); + +/** + * \brief Modulo: R = A mod B + * + * \param R Destination MPI for the rest value + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * 1 if memory allocation failed, + * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0, + * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0 + */ +int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B ); + +/** + * \brief Modulo: r = A mod b + * + * \param r Destination t_uint + * \param A Left-hand MPI + * \param b Integer to divide by + * + * \return 0 if successful, + * 1 if memory allocation failed, + * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0, + * POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0 + */ +int mpi_mod_int( t_uint *r, const mpi *A, t_sint b ); + +/** + * \brief Sliding-window exponentiation: X = A^E mod N + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param E Exponent MPI + * \param N Modular MPI + * \param _RR Speed-up MPI used for recalculations + * + * \return 0 if successful, + * 1 if memory allocation failed, + * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even + * + * \note _RR is used to avoid re-computing R*R mod N across + * multiple calls, which speeds up things a bit. It can + * be set to NULL if the extra performance is unneeded. + */ +int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ); + +/** + * \brief Fill an MPI X with size bytes of random + * + * \param X Destination MPI + * \param size Size in bytes + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_fill_random( mpi *X, size_t size, int (*f_rng)(void *), void *p_rng ); + +/** + * \brief Greatest common divisor: G = gcd(A, B) + * + * \param G Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * 1 if memory allocation failed + */ +int mpi_gcd( mpi *G, const mpi *A, const mpi *B ); + +/** + * \brief Modular inverse: X = A^-1 mod N + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param N Right-hand MPI + * + * \return 0 if successful, + * 1 if memory allocation failed, + * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil + POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N + */ +int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N ); + +/** + * \brief Miller-Rabin primality test + * + * \param X MPI to check + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful (probably prime), + * 1 if memory allocation failed, + * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime + */ +int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng ); + +/** + * \brief Prime number generation + * + * \param X Destination MPI + * \param nbits Required size of X in bits ( 3 <= nbits <= 4096 ) + * \param dh_flag If 1, then (X-1)/2 will be prime too + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful (probably prime), + * 1 if memory allocation failed, + * POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3 + */ +int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag, + int (*f_rng)(void *), void *p_rng ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mpi_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* bignum.h */ diff --git a/plugins/!NotAdopted/Tlen/crypto/polarssl/bn_mul.h b/plugins/!NotAdopted/Tlen/crypto/polarssl/bn_mul.h new file mode 100644 index 0000000000..59a32857cb --- /dev/null +++ b/plugins/!NotAdopted/Tlen/crypto/polarssl/bn_mul.h @@ -0,0 +1,738 @@ +/** + * \file bn_mul.h + * + * \brief Multi-precision integer library + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * Multiply source vector [s] with b, add result + * to destination vector [d] and set carry c. + * + * Currently supports: + * + * . IA-32 (386+) . AMD64 / EM64T + * . IA-32 (SSE2) . Motorola 68000 + * . PowerPC, 32-bit . MicroBlaze + * . PowerPC, 64-bit . TriCore + * . SPARC v8 . ARM v3+ + * . Alpha . MIPS32 + * . C, longlong . C, generic + */ +#ifndef POLARSSL_BN_MUL_H +#define POLARSSL_BN_MUL_H + +#include "polarssl/config.h" + +#if defined(POLARSSL_HAVE_ASM) + +#if defined(__GNUC__) +#if defined(__i386__) + +#define MULADDC_INIT \ + asm( " \ + movl %%ebx, %0; \ + movl %5, %%esi; \ + movl %6, %%edi; \ + movl %7, %%ecx; \ + movl %8, %%ebx; \ + " + +#define MULADDC_CORE \ + " \ + lodsl; \ + mull %%ebx; \ + addl %%ecx, %%eax; \ + adcl $0, %%edx; \ + addl (%%edi), %%eax; \ + adcl $0, %%edx; \ + movl %%edx, %%ecx; \ + stosl; \ + " + +#if defined(POLARSSL_HAVE_SSE2) + +#define MULADDC_HUIT \ + " \ + movd %%ecx, %%mm1; \ + movd %%ebx, %%mm0; \ + movd (%%edi), %%mm3; \ + paddq %%mm3, %%mm1; \ + movd (%%esi), %%mm2; \ + pmuludq %%mm0, %%mm2; \ + movd 4(%%esi), %%mm4; \ + pmuludq %%mm0, %%mm4; \ + movd 8(%%esi), %%mm6; \ + pmuludq %%mm0, %%mm6; \ + movd 12(%%esi), %%mm7; \ + pmuludq %%mm0, %%mm7; \ + paddq %%mm2, %%mm1; \ + movd 4(%%edi), %%mm3; \ + paddq %%mm4, %%mm3; \ + movd 8(%%edi), %%mm5; \ + paddq %%mm6, %%mm5; \ + movd 12(%%edi), %%mm4; \ + paddq %%mm4, %%mm7; \ + movd %%mm1, (%%edi); \ + movd 16(%%esi), %%mm2; \ + pmuludq %%mm0, %%mm2; \ + psrlq $32, %%mm1; \ + movd 20(%%esi), %%mm4; \ + pmuludq %%mm0, %%mm4; \ + paddq %%mm3, %%mm1; \ + movd 24(%%esi), %%mm6; \ + pmuludq %%mm0, %%mm6; \ + movd %%mm1, 4(%%edi); \ + psrlq $32, %%mm1; \ + movd 28(%%esi), %%mm3; \ + pmuludq %%mm0, %%mm3; \ + paddq %%mm5, %%mm1; \ + movd 16(%%edi), %%mm5; \ + paddq %%mm5, %%mm2; \ + movd %%mm1, 8(%%edi); \ + psrlq $32, %%mm1; \ + paddq %%mm7, %%mm1; \ + movd 20(%%edi), %%mm5; \ + paddq %%mm5, %%mm4; \ + movd %%mm1, 12(%%edi); \ + psrlq $32, %%mm1; \ + paddq %%mm2, %%mm1; \ + movd 24(%%edi), %%mm5; \ + paddq %%mm5, %%mm6; \ + movd %%mm1, 16(%%edi); \ + psrlq $32, %%mm1; \ + paddq %%mm4, %%mm1; \ + movd 28(%%edi), %%mm5; \ + paddq %%mm5, %%mm3; \ + movd %%mm1, 20(%%edi); \ + psrlq $32, %%mm1; \ + paddq %%mm6, %%mm1; \ + movd %%mm1, 24(%%edi); \ + psrlq $32, %%mm1; \ + paddq %%mm3, %%mm1; \ + movd %%mm1, 28(%%edi); \ + addl $32, %%edi; \ + addl $32, %%esi; \ + psrlq $32, %%mm1; \ + movd %%mm1, %%ecx; \ + " + +#define MULADDC_STOP \ + " \ + emms; \ + movl %4, %%ebx; \ + movl %%ecx, %1; \ + movl %%edi, %2; \ + movl %%esi, %3; \ + " \ + : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ + : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ + : "eax", "ecx", "edx", "esi", "edi" \ + ); + +#else + +#define MULADDC_STOP \ + " \ + movl %4, %%ebx; \ + movl %%ecx, %1; \ + movl %%edi, %2; \ + movl %%esi, %3; \ + " \ + : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ + : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ + : "eax", "ecx", "edx", "esi", "edi" \ + ); +#endif /* SSE2 */ +#endif /* i386 */ + +#if defined(__amd64__) || defined (__x86_64__) + +#define MULADDC_INIT \ + asm( "movq %0, %%rsi " :: "m" (s)); \ + asm( "movq %0, %%rdi " :: "m" (d)); \ + asm( "movq %0, %%rcx " :: "m" (c)); \ + asm( "movq %0, %%rbx " :: "m" (b)); \ + asm( "xorq %r8, %r8 " ); + +#define MULADDC_CORE \ + asm( "movq (%rsi),%rax " ); \ + asm( "mulq %rbx " ); \ + asm( "addq $8, %rsi " ); \ + asm( "addq %rcx, %rax " ); \ + asm( "movq %r8, %rcx " ); \ + asm( "adcq $0, %rdx " ); \ + asm( "nop " ); \ + asm( "addq %rax, (%rdi) " ); \ + asm( "adcq %rdx, %rcx " ); \ + asm( "addq $8, %rdi " ); + +#define MULADDC_STOP \ + asm( "movq %%rcx, %0 " : "=m" (c)); \ + asm( "movq %%rdi, %0 " : "=m" (d)); \ + asm( "movq %%rsi, %0 " : "=m" (s) :: \ + "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" ); + +#endif /* AMD64 */ + +#if defined(__mc68020__) || defined(__mcpu32__) + +#define MULADDC_INIT \ + asm( "movl %0, %%a2 " :: "m" (s)); \ + asm( "movl %0, %%a3 " :: "m" (d)); \ + asm( "movl %0, %%d3 " :: "m" (c)); \ + asm( "movl %0, %%d2 " :: "m" (b)); \ + asm( "moveq #0, %d0 " ); + +#define MULADDC_CORE \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d4:%d1 " ); \ + asm( "addl %d3, %d1 " ); \ + asm( "addxl %d0, %d4 " ); \ + asm( "moveq #0, %d3 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "addxl %d4, %d3 " ); + +#define MULADDC_STOP \ + asm( "movl %%d3, %0 " : "=m" (c)); \ + asm( "movl %%a3, %0 " : "=m" (d)); \ + asm( "movl %%a2, %0 " : "=m" (s) :: \ + "d0", "d1", "d2", "d3", "d4", "a2", "a3" ); + +#define MULADDC_HUIT \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d4:%d1 " ); \ + asm( "addxl %d3, %d1 " ); \ + asm( "addxl %d0, %d4 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d3:%d1 " ); \ + asm( "addxl %d4, %d1 " ); \ + asm( "addxl %d0, %d3 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d4:%d1 " ); \ + asm( "addxl %d3, %d1 " ); \ + asm( "addxl %d0, %d4 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d3:%d1 " ); \ + asm( "addxl %d4, %d1 " ); \ + asm( "addxl %d0, %d3 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d4:%d1 " ); \ + asm( "addxl %d3, %d1 " ); \ + asm( "addxl %d0, %d4 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d3:%d1 " ); \ + asm( "addxl %d4, %d1 " ); \ + asm( "addxl %d0, %d3 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d4:%d1 " ); \ + asm( "addxl %d3, %d1 " ); \ + asm( "addxl %d0, %d4 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "movel %a2@+, %d1 " ); \ + asm( "mulul %d2, %d3:%d1 " ); \ + asm( "addxl %d4, %d1 " ); \ + asm( "addxl %d0, %d3 " ); \ + asm( "addl %d1, %a3@+ " ); \ + asm( "addxl %d0, %d3 " ); + +#endif /* MC68000 */ + +#if defined(__powerpc__) || defined(__ppc__) +#if defined(__powerpc64__) || defined(__ppc64__) + +#if defined(__MACH__) && defined(__APPLE__) + +#define MULADDC_INIT \ + asm( "ld r3, %0 " :: "m" (s)); \ + asm( "ld r4, %0 " :: "m" (d)); \ + asm( "ld r5, %0 " :: "m" (c)); \ + asm( "ld r6, %0 " :: "m" (b)); \ + asm( "addi r3, r3, -8 " ); \ + asm( "addi r4, r4, -8 " ); \ + asm( "addic r5, r5, 0 " ); + +#define MULADDC_CORE \ + asm( "ldu r7, 8(r3) " ); \ + asm( "mulld r8, r7, r6 " ); \ + asm( "mulhdu r9, r7, r6 " ); \ + asm( "adde r8, r8, r5 " ); \ + asm( "ld r7, 8(r4) " ); \ + asm( "addze r5, r9 " ); \ + asm( "addc r8, r8, r7 " ); \ + asm( "stdu r8, 8(r4) " ); + +#define MULADDC_STOP \ + asm( "addze r5, r5 " ); \ + asm( "addi r4, r4, 8 " ); \ + asm( "addi r3, r3, 8 " ); \ + asm( "std r5, %0 " : "=m" (c)); \ + asm( "std r4, %0 " : "=m" (d)); \ + asm( "std r3, %0 " : "=m" (s) :: \ + "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); + +#else + +#define MULADDC_INIT \ + asm( "ld %%r3, %0 " :: "m" (s)); \ + asm( "ld %%r4, %0 " :: "m" (d)); \ + asm( "ld %%r5, %0 " :: "m" (c)); \ + asm( "ld %%r6, %0 " :: "m" (b)); \ + asm( "addi %r3, %r3, -8 " ); \ + asm( "addi %r4, %r4, -8 " ); \ + asm( "addic %r5, %r5, 0 " ); + +#define MULADDC_CORE \ + asm( "ldu %r7, 8(%r3) " ); \ + asm( "mulld %r8, %r7, %r6 " ); \ + asm( "mulhdu %r9, %r7, %r6 " ); \ + asm( "adde %r8, %r8, %r5 " ); \ + asm( "ld %r7, 8(%r4) " ); \ + asm( "addze %r5, %r9 " ); \ + asm( "addc %r8, %r8, %r7 " ); \ + asm( "stdu %r8, 8(%r4) " ); + +#define MULADDC_STOP \ + asm( "addze %r5, %r5 " ); \ + asm( "addi %r4, %r4, 8 " ); \ + asm( "addi %r3, %r3, 8 " ); \ + asm( "std %%r5, %0 " : "=m" (c)); \ + asm( "std %%r4, %0 " : "=m" (d)); \ + asm( "std %%r3, %0 " : "=m" (s) :: \ + "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); + +#endif + +#else /* PPC32 */ + +#if defined(__MACH__) && defined(__APPLE__) + +#define MULADDC_INIT \ + asm( "lwz r3, %0 " :: "m" (s)); \ + asm( "lwz r4, %0 " :: "m" (d)); \ + asm( "lwz r5, %0 " :: "m" (c)); \ + asm( "lwz r6, %0 " :: "m" (b)); \ + asm( "addi r3, r3, -4 " ); \ + asm( "addi r4, r4, -4 " ); \ + asm( "addic r5, r5, 0 " ); + +#define MULADDC_CORE \ + asm( "lwzu r7, 4(r3) " ); \ + asm( "mullw r8, r7, r6 " ); \ + asm( "mulhwu r9, r7, r6 " ); \ + asm( "adde r8, r8, r5 " ); \ + asm( "lwz r7, 4(r4) " ); \ + asm( "addze r5, r9 " ); \ + asm( "addc r8, r8, r7 " ); \ + asm( "stwu r8, 4(r4) " ); + +#define MULADDC_STOP \ + asm( "addze r5, r5 " ); \ + asm( "addi r4, r4, 4 " ); \ + asm( "addi r3, r3, 4 " ); \ + asm( "stw r5, %0 " : "=m" (c)); \ + asm( "stw r4, %0 " : "=m" (d)); \ + asm( "stw r3, %0 " : "=m" (s) :: \ + "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); + +#else + +#define MULADDC_INIT \ + asm( "lwz %%r3, %0 " :: "m" (s)); \ + asm( "lwz %%r4, %0 " :: "m" (d)); \ + asm( "lwz %%r5, %0 " :: "m" (c)); \ + asm( "lwz %%r6, %0 " :: "m" (b)); \ + asm( "addi %r3, %r3, -4 " ); \ + asm( "addi %r4, %r4, -4 " ); \ + asm( "addic %r5, %r5, 0 " ); + +#define MULADDC_CORE \ + asm( "lwzu %r7, 4(%r3) " ); \ + asm( "mullw %r8, %r7, %r6 " ); \ + asm( "mulhwu %r9, %r7, %r6 " ); \ + asm( "adde %r8, %r8, %r5 " ); \ + asm( "lwz %r7, 4(%r4) " ); \ + asm( "addze %r5, %r9 " ); \ + asm( "addc %r8, %r8, %r7 " ); \ + asm( "stwu %r8, 4(%r4) " ); + +#define MULADDC_STOP \ + asm( "addze %r5, %r5 " ); \ + asm( "addi %r4, %r4, 4 " ); \ + asm( "addi %r3, %r3, 4 " ); \ + asm( "stw %%r5, %0 " : "=m" (c)); \ + asm( "stw %%r4, %0 " : "=m" (d)); \ + asm( "stw %%r3, %0 " : "=m" (s) :: \ + "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); + +#endif + +#endif /* PPC32 */ +#endif /* PPC64 */ + +#if defined(__sparc__) + +#define MULADDC_INIT \ + asm( "ld %0, %%o0 " :: "m" (s)); \ + asm( "ld %0, %%o1 " :: "m" (d)); \ + asm( "ld %0, %%o2 " :: "m" (c)); \ + asm( "ld %0, %%o3 " :: "m" (b)); + +#define MULADDC_CORE \ + asm( "ld [%o0], %o4 " ); \ + asm( "inc 4, %o0 " ); \ + asm( "ld [%o1], %o5 " ); \ + asm( "umul %o3, %o4, %o4 " ); \ + asm( "addcc %o4, %o2, %o4 " ); \ + asm( "rd %y, %g1 " ); \ + asm( "addx %g1, 0, %g1 " ); \ + asm( "addcc %o4, %o5, %o4 " ); \ + asm( "st %o4, [%o1] " ); \ + asm( "addx %g1, 0, %o2 " ); \ + asm( "inc 4, %o1 " ); + +#define MULADDC_STOP \ + asm( "st %%o2, %0 " : "=m" (c)); \ + asm( "st %%o1, %0 " : "=m" (d)); \ + asm( "st %%o0, %0 " : "=m" (s) :: \ + "g1", "o0", "o1", "o2", "o3", "o4", "o5" ); + +#endif /* SPARCv8 */ + +#if defined(__microblaze__) || defined(microblaze) + +#define MULADDC_INIT \ + asm( "lwi r3, %0 " :: "m" (s)); \ + asm( "lwi r4, %0 " :: "m" (d)); \ + asm( "lwi r5, %0 " :: "m" (c)); \ + asm( "lwi r6, %0 " :: "m" (b)); \ + asm( "andi r7, r6, 0xffff" ); \ + asm( "bsrli r6, r6, 16 " ); + +#define MULADDC_CORE \ + asm( "lhui r8, r3, 0 " ); \ + asm( "addi r3, r3, 2 " ); \ + asm( "lhui r9, r3, 0 " ); \ + asm( "addi r3, r3, 2 " ); \ + asm( "mul r10, r9, r6 " ); \ + asm( "mul r11, r8, r7 " ); \ + asm( "mul r12, r9, r7 " ); \ + asm( "mul r13, r8, r6 " ); \ + asm( "bsrli r8, r10, 16 " ); \ + asm( "bsrli r9, r11, 16 " ); \ + asm( "add r13, r13, r8 " ); \ + asm( "add r13, r13, r9 " ); \ + asm( "bslli r10, r10, 16 " ); \ + asm( "bslli r11, r11, 16 " ); \ + asm( "add r12, r12, r10 " ); \ + asm( "addc r13, r13, r0 " ); \ + asm( "add r12, r12, r11 " ); \ + asm( "addc r13, r13, r0 " ); \ + asm( "lwi r10, r4, 0 " ); \ + asm( "add r12, r12, r10 " ); \ + asm( "addc r13, r13, r0 " ); \ + asm( "add r12, r12, r5 " ); \ + asm( "addc r5, r13, r0 " ); \ + asm( "swi r12, r4, 0 " ); \ + asm( "addi r4, r4, 4 " ); + +#define MULADDC_STOP \ + asm( "swi r5, %0 " : "=m" (c)); \ + asm( "swi r4, %0 " : "=m" (d)); \ + asm( "swi r3, %0 " : "=m" (s) :: \ + "r3", "r4" , "r5" , "r6" , "r7" , "r8" , \ + "r9", "r10", "r11", "r12", "r13" ); + +#endif /* MicroBlaze */ + +#if defined(__tricore__) + +#define MULADDC_INIT \ + asm( "ld.a %%a2, %0 " :: "m" (s)); \ + asm( "ld.a %%a3, %0 " :: "m" (d)); \ + asm( "ld.w %%d4, %0 " :: "m" (c)); \ + asm( "ld.w %%d1, %0 " :: "m" (b)); \ + asm( "xor %d5, %d5 " ); + +#define MULADDC_CORE \ + asm( "ld.w %d0, [%a2+] " ); \ + asm( "madd.u %e2, %e4, %d0, %d1 " ); \ + asm( "ld.w %d0, [%a3] " ); \ + asm( "addx %d2, %d2, %d0 " ); \ + asm( "addc %d3, %d3, 0 " ); \ + asm( "mov %d4, %d3 " ); \ + asm( "st.w [%a3+], %d2 " ); + +#define MULADDC_STOP \ + asm( "st.w %0, %%d4 " : "=m" (c)); \ + asm( "st.a %0, %%a3 " : "=m" (d)); \ + asm( "st.a %0, %%a2 " : "=m" (s) :: \ + "d0", "d1", "e2", "d4", "a2", "a3" ); + +#endif /* TriCore */ + +#if defined(__arm__) + +#define MULADDC_INIT \ + asm( "ldr r0, %0 " :: "m" (s)); \ + asm( "ldr r1, %0 " :: "m" (d)); \ + asm( "ldr r2, %0 " :: "m" (c)); \ + asm( "ldr r3, %0 " :: "m" (b)); + +#define MULADDC_CORE \ + asm( "ldr r4, [r0], #4 " ); \ + asm( "mov r5, #0 " ); \ + asm( "ldr r6, [r1] " ); \ + asm( "umlal r2, r5, r3, r4 " ); \ + asm( "adds r7, r6, r2 " ); \ + asm( "adc r2, r5, #0 " ); \ + asm( "str r7, [r1], #4 " ); + +#define MULADDC_STOP \ + asm( "str r2, %0 " : "=m" (c)); \ + asm( "str r1, %0 " : "=m" (d)); \ + asm( "str r0, %0 " : "=m" (s) :: \ + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" ); + +#endif /* ARMv3 */ + +#if defined(__alpha__) + +#define MULADDC_INIT \ + asm( "ldq $1, %0 " :: "m" (s)); \ + asm( "ldq $2, %0 " :: "m" (d)); \ + asm( "ldq $3, %0 " :: "m" (c)); \ + asm( "ldq $4, %0 " :: "m" (b)); + +#define MULADDC_CORE \ + asm( "ldq $6, 0($1) " ); \ + asm( "addq $1, 8, $1 " ); \ + asm( "mulq $6, $4, $7 " ); \ + asm( "umulh $6, $4, $6 " ); \ + asm( "addq $7, $3, $7 " ); \ + asm( "cmpult $7, $3, $3 " ); \ + asm( "ldq $5, 0($2) " ); \ + asm( "addq $7, $5, $7 " ); \ + asm( "cmpult $7, $5, $5 " ); \ + asm( "stq $7, 0($2) " ); \ + asm( "addq $2, 8, $2 " ); \ + asm( "addq $6, $3, $3 " ); \ + asm( "addq $5, $3, $3 " ); + +#define MULADDC_STOP \ + asm( "stq $3, %0 " : "=m" (c)); \ + asm( "stq $2, %0 " : "=m" (d)); \ + asm( "stq $1, %0 " : "=m" (s) :: \ + "$1", "$2", "$3", "$4", "$5", "$6", "$7" ); + +#endif /* Alpha */ + +#if defined(__mips__) + +#define MULADDC_INIT \ + asm( "lw $10, %0 " :: "m" (s)); \ + asm( "lw $11, %0 " :: "m" (d)); \ + asm( "lw $12, %0 " :: "m" (c)); \ + asm( "lw $13, %0 " :: "m" (b)); + +#define MULADDC_CORE \ + asm( "lw $14, 0($10) " ); \ + asm( "multu $13, $14 " ); \ + asm( "addi $10, $10, 4 " ); \ + asm( "mflo $14 " ); \ + asm( "mfhi $9 " ); \ + asm( "addu $14, $12, $14 " ); \ + asm( "lw $15, 0($11) " ); \ + asm( "sltu $12, $14, $12 " ); \ + asm( "addu $15, $14, $15 " ); \ + asm( "sltu $14, $15, $14 " ); \ + asm( "addu $12, $12, $9 " ); \ + asm( "sw $15, 0($11) " ); \ + asm( "addu $12, $12, $14 " ); \ + asm( "addi $11, $11, 4 " ); + +#define MULADDC_STOP \ + asm( "sw $12, %0 " : "=m" (c)); \ + asm( "sw $11, %0 " : "=m" (d)); \ + asm( "sw $10, %0 " : "=m" (s) :: \ + "$9", "$10", "$11", "$12", "$13", "$14", "$15" ); + +#endif /* MIPS */ +#endif /* GNUC */ + +#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) + +#define MULADDC_INIT \ + __asm mov esi, s \ + __asm mov edi, d \ + __asm mov ecx, c \ + __asm mov ebx, b + +#define MULADDC_CORE \ + __asm lodsd \ + __asm mul ebx \ + __asm add eax, ecx \ + __asm adc edx, 0 \ + __asm add eax, [edi] \ + __asm adc edx, 0 \ + __asm mov ecx, edx \ + __asm stosd + +#if defined(POLARSSL_HAVE_SSE2) + +#define EMIT __asm _emit + +#define MULADDC_HUIT \ + EMIT 0x0F EMIT 0x6E EMIT 0xC9 \ + EMIT 0x0F EMIT 0x6E EMIT 0xC3 \ + EMIT 0x0F EMIT 0x6E EMIT 0x1F \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ + EMIT 0x0F EMIT 0x6E EMIT 0x16 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ + EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ + EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ + EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \ + EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ + EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xDC \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xEE \ + EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \ + EMIT 0x0F EMIT 0xD4 EMIT 0xFC \ + EMIT 0x0F EMIT 0x7E EMIT 0x0F \ + EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ + EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \ + EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCD \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCF \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCC \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \ + EMIT 0x0F EMIT 0xD4 EMIT 0xDD \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCE \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \ + EMIT 0x83 EMIT 0xC7 EMIT 0x20 \ + EMIT 0x83 EMIT 0xC6 EMIT 0x20 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0x7E EMIT 0xC9 + +#define MULADDC_STOP \ + EMIT 0x0F EMIT 0x77 \ + __asm mov c, ecx \ + __asm mov d, edi \ + __asm mov s, esi \ + +#else + +#define MULADDC_STOP \ + __asm mov c, ecx \ + __asm mov d, edi \ + __asm mov s, esi \ + +#endif /* SSE2 */ +#endif /* MSVC */ + +#endif /* POLARSSL_HAVE_ASM */ + +#if !defined(MULADDC_CORE) +#if defined(POLARSSL_HAVE_LONGLONG) + +#define MULADDC_INIT \ +{ \ + t_udbl r; \ + t_uint r0, r1; + +#define MULADDC_CORE \ + r = *(s++) * (t_udbl) b; \ + r0 = r; \ + r1 = r >> biL; \ + r0 += c; r1 += (r0 < c); \ + r0 += *d; r1 += (r0 < *d); \ + c = r1; *(d++) = r0; + +#define MULADDC_STOP \ +} + +#else +#define MULADDC_INIT \ +{ \ + t_uint s0, s1, b0, b1; \ + t_uint r0, r1, rx, ry; \ + b0 = ( b << biH ) >> biH; \ + b1 = ( b >> biH ); + +#define MULADDC_CORE \ + s0 = ( *s << biH ) >> biH; \ + s1 = ( *s >> biH ); s++; \ + rx = s0 * b1; r0 = s0 * b0; \ + ry = s1 * b0; r1 = s1 * b1; \ + r1 += ( rx >> biH ); \ + r1 += ( ry >> biH ); \ + rx <<= biH; ry <<= biH; \ + r0 += rx; r1 += (r0 < rx); \ + r0 += ry; r1 += (r0 < ry); \ + r0 += c; r1 += (r0 < c); \ + r0 += *d; r1 += (r0 < *d); \ + c = r1; *(d++) = r0; + +#define MULADDC_STOP \ +} + +#endif /* C (generic) */ +#endif /* C (longlong) */ + +#endif /* bn_mul.h */ diff --git a/plugins/!NotAdopted/Tlen/crypto/polarssl/config.h b/plugins/!NotAdopted/Tlen/crypto/polarssl/config.h new file mode 100644 index 0000000000..61500a75ee --- /dev/null +++ b/plugins/!NotAdopted/Tlen/crypto/polarssl/config.h @@ -0,0 +1,625 @@ +/** + * \file config.h + * + * \brief Configuration options (set of defines) + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * This set of compile-time options may be used to enable + * or disable features selectively, and reduce the global + * memory footprint. + */ +#ifndef POLARSSL_CONFIG_H +#define POLARSSL_CONFIG_H + +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + +/** + * \name SECTION: System support + * + * This section sets system specific settings. + * \{ + */ + +/** + * \def POLARSSL_HAVE_INT8 + * + * The system uses 8-bit wide native integers. + * + * Uncomment if native integers are 8-bit wide. +#define POLARSSL_HAVE_INT8 + */ + +/** + * \def POLARSSL_HAVE_INT16 + * + * The system uses 16-bit wide native integers. + * + * Uncomment if native integers are 16-bit wide. +#define POLARSSL_HAVE_INT16 + */ + +/** + * \def POLARSSL_HAVE_LONGLONG + * + * The compiler supports the use of long long. + * + * Uncomment if the compiler supports long long. +#define POLARSSL_HAVE_LONGLONG + */ + +/** + * \def POLARSSL_HAVE_ASM + * + * The compiler has support for asm() + * + * Uncomment to enable the use of assembly code. + * + * Requires support for asm() in compiler. + * + * Used in: + * library/timing.c + * library/padlock.c + * include/polarssl/bn_mul.h + * + */ +#define POLARSSL_HAVE_ASM + +/** + * \def POLARSSL_HAVE_SSE2 + * + * CPI supports SSE2 instruction set. + * + * Uncomment if the CPU supports SSE2 (IA-32 specific). + * +#define POLARSSL_HAVE_SSE2 + */ +/* \} name */ + +/** + * \name SECTION: PolarSSL feature support + * + * This section sets support for features that are or are not needed + * within the modules that are enabled. + * \{ + */ + +/** + * \def POLARSSL_AES_ROM_TABLES + * + * Store the AES tables in ROM. + * + * Uncomment this macro to store the AES tables in ROM. + * +#define POLARSSL_AES_ROM_TABLES + */ + +/** + * \def POLARSSL_CIPHER_MODE_CFB + * + * Enable Cipher Feedback mode (CFB) for symmetric ciphers. + */ +#define POLARSSL_CIPHER_MODE_CFB + +/** + * \def POLARSSL_CIPHER_MODE_CTR + * + * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. + */ +#define POLARSSL_CIPHER_MODE_CTR + +/** + * \def POLARSSL_DEBUG_MSG + * + * Requires: POLARSSL_DEBUG_C + * + * Enable all SSL/TLS debugging messages. + */ +#define POLARSSL_DEBUG_MSG + +/** + * \def POLARSSL_GENPRIME + * + * Requires: POLARSSL_BIGNUM_C, POLARSSL_RSA_C + * + * Enable the RSA prime-number generation code. + */ +#define POLARSSL_GENPRIME + +/** + * \def POLARSSL_FS_IO + * + * Enable functions that use the filesystem. + */ +#define POLARSSL_FS_IO + +/** + * \def POLARSSL_PKCS1_V21 + * + * Requires: POLARSSL_MD_C, POLARSSL_RSA_C + * + * Enable support for PKCS#1 v2.1 encoding. + * This enables support for RSAES-OAEP and RSASSA-PSS operations. + */ +#define POLARSSL_PKCS1_V21 + +/** + * \def POLARSSL_RSA_NO_CRT + * + * Do not use the Chinese Remainder Theorem for the RSA private operation. + * + * Uncomment this macro to disable the use of CRT in RSA. + * +#define POLARSSL_RSA_NO_CRT + */ + +/** + * \def POLARSSL_SELF_TEST + * + * Enable the checkup functions (*_self_test). + */ +#define POLARSSL_SELF_TEST + +/** + * \def POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an unknown critical extension. + * + * Uncomment to prevent an error. + * +#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + */ +/* \} name */ + +/** + * \name SECTION: PolarSSL modules + * + * This section enables or disables entire modules in PolarSSL + * \{ + */ + +/** + * \def POLARSSL_AES_C + * + * Enable the AES block cipher. + * + * Module: library/aes.c + * Caller: library/ssl_tls.c + * library/pem.c + * + * This module enables the following ciphersuites: + * SSL_RSA_AES_128_SHA + * SSL_RSA_AES_256_SHA + * SSL_EDH_RSA_AES_256_SHA + */ +#define POLARSSL_AES_C + +/** + * \def POLARSSL_ARC4_C + * + * Enable the ARCFOUR stream cipher. + * + * Module: library/arc4.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites: + * SSL_RSA_RC4_128_MD5 + * SSL_RSA_RC4_128_SHA + */ +#define POLARSSL_ARC4_C + +/** + * \def POLARSSL_BASE64_C + * + * Enable the Base64 module. + * + * Module: library/base64.c + * Caller: library/pem.c + * + * This module is required for PEM support (required by X.509). + */ +#define POLARSSL_BASE64_C + +/** + * \def POLARSSL_BIGNUM_C + * + * Enable the multo-precision integer library. + * + * Module: library/bignum.c + * Caller: library/dhm.c + * library/rsa.c + * library/ssl_tls.c + * library/x509parse.c + * + * This module is required for RSA and DHM support. + */ +#define POLARSSL_BIGNUM_C + +/** + * \def POLARSSL_CAMELLIA_C + * + * Enable the Camellia block cipher. + * + * Module: library/camellia.c + * Caller: library/ssl_tls.c + * + * This module enabled the following cipher suites: + * SSL_RSA_CAMELLIA_128_SHA + * SSL_RSA_CAMELLIA_256_SHA + * SSL_EDH_RSA_CAMELLIA_256_SHA + */ +#define POLARSSL_CAMELLIA_C + +/** + * \def POLARSSL_CERTS_C + * + * Enable the test certificates. + * + * Module: library/certs.c + * Caller: + * + * This module is used for testing (ssl_client/server). + */ +#define POLARSSL_CERTS_C + +/** + * \def POLARSSL_CIPHER_C + * + * Enable the generic cipher layer. + * + * Module: library/cipher.c + * Caller: + * + * Uncomment to enable generic cipher wrappers. + */ +#define POLARSSL_CIPHER_C + +/** + * \def POLARSSL_DEBUG_C + * + * Enable the debug functions. + * + * Module: library/debug.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module provides debugging functions. + */ +#define POLARSSL_DEBUG_C + +/** + * \def POLARSSL_DES_C + * + * Enable the DES block cipher. + * + * Module: library/des.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites: + * SSL_RSA_DES_168_SHA + * SSL_EDH_RSA_DES_168_SHA + */ +#define POLARSSL_DES_C + +/** + * \def POLARSSL_DHM_C + * + * Enable the Diffie-Hellman-Merkle key exchange. + * + * Module: library/dhm.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module enables the following ciphersuites: + * SSL_EDH_RSA_DES_168_SHA + * SSL_EDH_RSA_AES_256_SHA + * SSL_EDH_RSA_CAMELLIA_256_SHA + */ +#define POLARSSL_DHM_C + +/** + * \def POLARSSL_ERROR_C + * + * Enable error code to error string conversion. + * + * Module: library/error.c + * Caller: + * + * This module enables err_strerror(). + */ +#define POLARSSL_ERROR_C + +/** + * \def POLARSSL_HAVEGE_C + * + * Enable the HAVEGE random generator. + * + * Module: library/havege.c + * Caller: + * + * Requires: POLARSSL_TIMING_C + * + * This module enables the HAVEGE random number generator. + */ +#define POLARSSL_HAVEGE_C + +/** + * \def POLARSSL_MD_C + * + * Enable the generic message digest layer. + * + * Module: library/md.c + * Caller: + * + * Uncomment to enable generic message digest wrappers. + */ +#define POLARSSL_MD_C + +/** + * \def POLARSSL_MD2_C + * + * Enable the MD2 hash algorithm + * + * Module: library/md2.c + * Caller: library/x509parse.c + * + * Uncomment to enable support for (rare) MD2-signed X.509 certs. + * +#define POLARSSL_MD2_C + */ + +/** + * \def POLARSSL_MD4_C + * + * Enable the MD4 hash algorithm + * + * Module: library/md4.c + * Caller: library/x509parse.c + * + * Uncomment to enable support for (rare) MD4-signed X.509 certs. + * +#define POLARSSL_MD4_C + */ + +/** + * \def POLARSSL_MD5_C + * + * Enable the MD5 hash algorithm + * + * Module: library/md5.c + * Caller: library/ssl_tls.c + * library/x509parse.c + * + * This module is required for SSL/TLS and X.509. + */ +#define POLARSSL_MD5_C + +/** + * \def POLARSSL_NET_C + * + * Enable the TCP/IP networking routines. + * + * Module: library/net.c + * Caller: + * + * This module provides TCP/IP networking routines. + */ +#define POLARSSL_NET_C + +/** + * \def POLARSSL_PADLOCK_C + * + * Enable VIA Padlock support on x86. + * + * Module: library/padlock.c + * Caller: library/aes.c + * + * This modules adds support for the VIA PadLock on x86. + */ +#define POLARSSL_PADLOCK_C + +/** + * \def POLARSSL_PEM_C + * + * Enable PEM decoding + * + * Module: library/pem.c + * Caller: library/x509parse.c + * + * Requires: POLARSSL_BASE64_C + * + * This modules adds support for decoding PEM files. + */ +#define POLARSSL_PEM_C + +/** + * \def POLARSSL_PKCS11_C + * + * Enable support for PKCS#11 smartcard support. + * + * Module: library/ssl_srv.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: POLARSSL_SSL_TLS_C + * + * This module is required for SSL/TLS PKCS #11 smartcard support. + * Requires the presence of the PKCS#11 helper library (libpkcs11-helper) +#define POLARSSL_PKCS11_C + */ + +/** + * \def POLARSSL_RSA_C + * + * Enable the RSA public-key cryptosystem. + * + * Module: library/rsa.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509.c + * + * Requires: POLARSSL_BIGNUM_C + * + * This module is required for SSL/TLS and MD5-signed certificates. + */ +#define POLARSSL_RSA_C + +/** + * \def POLARSSL_SHA1_C + * + * Enable the SHA1 cryptographic hash algorithm. + * + * Module: library/sha1.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509parse.c + * + * This module is required for SSL/TLS and SHA1-signed certificates. + */ +#define POLARSSL_SHA1_C + +/** + * \def POLARSSL_SHA2_C + * + * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. + * + * Module: library/sha2.c + * Caller: library/md_wrap.c + * library/x509parse.c + * + * This module adds support for SHA-224 and SHA-256. + */ +#define POLARSSL_SHA2_C + +/** + * \def POLARSSL_SHA4_C + * + * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. + * + * Module: library/sha4.c + * Caller: library/md_wrap.c + * library/x509parse.c + * + * This module adds support for SHA-384 and SHA-512. + */ +#define POLARSSL_SHA4_C + +/** + * \def POLARSSL_SSL_CLI_C + * + * Enable the SSL/TLS client code. + * + * Module: library/ssl_cli.c + * Caller: + * + * Requires: POLARSSL_SSL_TLS_C + * + * This module is required for SSL/TLS client support. + */ +#define POLARSSL_SSL_CLI_C + +/* + * \def POLARSSL_SSL_SRV_C + * + * Enable the SSL/TLS server code. + * + * Module: library/ssl_srv.c + * Caller: + * + * Requires: POLARSSL_SSL_TLS_C + * + * This module is required for SSL/TLS server support. + */ +#define POLARSSL_SSL_SRV_C + +/** + * \def POLARSSL_SSL_TLS_C + * + * Enable the generic SSL/TLS code. + * + * Module: library/ssl_tls.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: POLARSSL_MD5_C, POLARSSL_SHA1_C, POLARSSL_X509_PARSE_C + * + * This module is required for SSL/TLS. + */ +#define POLARSSL_SSL_TLS_C + +/** + * \def POLARSSL_TIMING_C + * + * Enable the portable timing interface. + * + * Module: library/timing.c + * Caller: library/havege.c + * + * This module is used by the HAVEGE random number generator. + */ +#define POLARSSL_TIMING_C + +/** + * \def POLARSSL_VERSION_C + * + * Enable run-time version information. + * + * Module: library/version.c + * + * This module provides run-time version information. + */ +#define POLARSSL_VERSION_C + +/** + * \def POLARSSL_X509_PARSE_C + * + * Enable X.509 certificate parsing. + * + * Module: library/x509parse.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * Requires: POLARSSL_BIGNUM_C, POLARSSL_RSA_C + * + * This module is required for X.509 certificate parsing. + */ +#define POLARSSL_X509_PARSE_C + +/** + * \def POLARSSL_XTEA_C + * + * Enable the XTEA block cipher. + * + * Module: library/xtea.c + * Caller: + */ +#define POLARSSL_XTEA_C +/* \} name */ + +#endif /* config.h */ diff --git a/plugins/!NotAdopted/Tlen/crypto/polarssl/padlock.h b/plugins/!NotAdopted/Tlen/crypto/polarssl/padlock.h new file mode 100644 index 0000000000..08fbe825c9 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/crypto/polarssl/padlock.h @@ -0,0 +1,100 @@ +/** + * \file padlock.h + * + * \brief VIA PadLock ACE for HW encryption/decryption supported by some processors + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_PADLOCK_H +#define POLARSSL_PADLOCK_H + +#include "polarssl/aes.h" + +#define POLARSSL_ERR_PADLOCK_DATA_MISALIGNED -0x0030 /**< Input data should be aligned. */ + +#if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && defined(__i386__) + +#ifndef POLARSSL_HAVE_X86 +#define POLARSSL_HAVE_X86 +#endif + +#define PADLOCK_RNG 0x000C +#define PADLOCK_ACE 0x00C0 +#define PADLOCK_PHE 0x0C00 +#define PADLOCK_PMM 0x3000 + +#define PADLOCK_ALIGN16(x) (unsigned long *) (16 + ((long) x & ~15)) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief PadLock detection routine + * + * \param The feature to detect + * + * \return 1 if CPU has support for the feature, 0 otherwise + */ +int padlock_supports( int feature ); + +/** + * \brief PadLock AES-ECB block en(de)cryption + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block + * + * \return 0 if success, 1 if operation failed + */ +int padlock_xcryptecb( aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ); + +/** + * \brief PadLock AES-CBC buffer en(de)cryption + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if success, 1 if operation failed + */ +int padlock_xcryptcbc( aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +#ifdef __cplusplus +} +#endif + +#endif /* HAVE_X86 */ + +#endif /* padlock.h */ diff --git a/plugins/!NotAdopted/Tlen/docs/InstallScript.xml b/plugins/!NotAdopted/Tlen/docs/InstallScript.xml new file mode 100644 index 0000000000..7d8a8f28fe --- /dev/null +++ b/plugins/!NotAdopted/Tlen/docs/InstallScript.xml @@ -0,0 +1,27 @@ + + + + Tlen Protocol + Santithorn Bunchua + 0.1.0.2 + Plugin + + + + Main Files + tlen.dll + tlen_czaty.dll + + + + + Documentation + readme_tlen.txt + + + + + readme_tlen.txt + + + diff --git a/plugins/!NotAdopted/Tlen/docs/changelog_tlen.txt b/plugins/!NotAdopted/Tlen/docs/changelog_tlen.txt new file mode 100644 index 0000000000..b2c05c760a --- /dev/null +++ b/plugins/!NotAdopted/Tlen/docs/changelog_tlen.txt @@ -0,0 +1,269 @@ +Version 2.0.5.0 +------- +* Project cleanup + + change mucc.dll to tlen_czaty.dll + + compile tlen_czaty in Unicode and x64 +* fix warnings, project files changes +Version 2.0.4.1 +------- +- fix accounts... dialog +Version 2.0.4.0 +------- ++ x64 version +* set timeout to NETLIBOPENCONNECTION (patch by piotrw) +* fix for display texts at comboboxes in unicode (patch by piotrw) +* fixes in Find/Add Contacts search (by piotrw, dezeath and wsx22) +* fix warnings, project files changes (add VS2010) +Version 2.0.3.2 +------- +* update PolarSSL library to polarssl-1.0.0 +* change compile options to not require microsoft visual studio runtime libs on user system, (100KB larger file but no problems with msvcr90.dll not found on user system) +Version 2.0.2.0 +------- +* "Leave status message after disconnection", "Send and receive client version information" and "Log alerts as messages" options enabled by default (AL|EN suggestion) +Version 2.0.1.0 +------- +merge changes from wsx22 mod +* fix in typing notify message handling +* fix in logging to server message +Version 2.0.0.0 +------- ++ Image transfer +* other bug fixes and improvements +Version 1.8.0.2 +------- +improved icons handling +minor fixes on account unloading +1.8.0.1 +------- +* bugfix: removed ME_SYSTEM_MODULESLOADED hook +1.8.0.0 +------- ++ support for account manager (requires MIM 0.8) +* many bugfixes and small improvements +1.1.0.0 +------- +* avatar support improvements +1.0.9.2 +------- +* avatar management UI changes +* user info page changes +* some clean-up and bugfixes +* fix for advertisement blocking +* fix for file transfers +1.0.9.1 +------- +* avatar management improvements +1.0.9.0 +------- ++ message encryption +* improved search (up to 200 results displayed) +* some avatar-related fixes +* MIM 0.7 compatibility +1.0.7.7 +------- +* new icons by Angelika +1.0.7.6 +------- ++ support for Tlen avatars +1.0.7.5 +------- +* bugfix: settings changes were not loaded properly +1.0.7.4 +------- +* p2p connections refactoring +* UPnP support +* managed services/hooks +* support for IcoLib +* new icons +* support for Miranda Memory Manager +1.0.7.3 +-------- +* bugfix: offline status message +1.0.7.2 +-------- +! fixed compatibility issues with new versions of IEView (1.0.9.0 or higher) ++ support for Nudge plugin +* improved avatar support +* improved sending/receiving client version info +1.0.7.1 +--------- +* bugfix: sending/receiving client version info +1.0.7.0 +--------- ++ full support for avatars (compatible with tAvatar 0.0.2.1 or higher) ++ sending and receiving full client version info +* optimized DB usage +* code cleanup +1.0.6.9 +--------- ++ experimental client recognition ++ voice chat notification sound +* bugfix: offline message timestamp +* code clean-up +1.0.6.8 +--------- +* bugfix: compatibility with Unicode contact lists +* bugfix: user login is always converted to lower case +* bugfix: typing notifications +* other bugfixes +1.0.6.7 +--------- ++ possibility to send files to offline users ++ public status visibility settings +* bugfixes +1.0.6.6 +--------- +* fixed IEView support (text scrolling issue) +* code cleanup +1.0.6.5 +--------- ++ option to ignore advertisements +* bugfixes +1.0.6.4 +--------- ++ alert, voice chat and group chat policies ++ received alerts are logged as messages +* offline message timestamp improvements (thanks to Atay for the idea) +* removed obsolete, Jabber-specific code +* a lot of more or less important bugfixes +1.0.6.3 +--------- ++ group names encoding ++ log saving in IEView mode +* simplified option page +1.0.6.2 +--------- ++ support for IEView group chats (IEView 1.0.3.0 or later) ++ improvements of group chats in RichEdit mode (context menu, better scrolling) +1.0.6.1 +--------- +* bugfix: proper filename encoding +* options page rearranged +* code cleanup, other fixes and improvements +1.0.6.0 +--------- ++ group chat window flashing ++ message icons in tabbed mode ++ web messages grouped as a single contact +* offline message timestamp handling fixed (again) +1.0.5.10 RC2 +--------- ++ tabbed mode available in group chat window ++ saving chat log to file ++ smiley selection button in group chat window ++ new shortcuts: ctrl+w (close), ctrl+a (select all) ++ saving chat fonts setting ++ new menu items: request and grant authorization +* several bugfixes in MUCC plugin, better MUCC architecture +1.0.5.9 RC +--------- ++ voice chat improvements (better sound quality and smarter delay reduction, bugfixes) ++ separate group for Global Owners in chat user list +* bugfix: web messages receiving (fix by MoMaT) +1.0.5.8 +--------- ++ playback and recording device selection ++ sending and receiving alerts (use to send) ++ enabling/disabling Always Visible support +* bugfixes +1.0.5.7 +--------- ++ chat room administration window (user administration and browser) ++ unban option ++ dynamic user groups ++ voice chat p2p connection negotiation ++ voice chat status display ++ incoming voice chat invitation dialog ++ removing contacts from roster on authorization denial ++ offline status message selection +* a lot of fixes in group chats interface +1.0.5.6 +--------- ++ voice chats ! (experimental) ++ chat room administration: destroying room, changing users' roles, kick & ban ++ MUCC option: send on Enter ++ status messages of offline contacts (use mToolTip to read them) +* bugfix: contact name encoding when adding new contact +* bugfix: offline messages time ('more inteligent' Daylight Saving Time handling) +* bugfix: closing all file transfers at shutdown +* other minor fixes +1.0.5.5 +--------- ++ improved file transfer (p2p connection negotiation, error notification) ++ MUCC options page (fonts, colors, default filters) ++ chat room events logging (user has joined etc.) ++ registering and uregistering nick names ++ creating chat rooms ++ chat room topic displaying and setting ++ improved errors handling +* look & feel improvements +* bugfix: correct chat room name returned by search +* bugfix: removing users from contact list groups +* source code refactoring +1.0.5.4 +--------- ++ group chats error handling ++ message log formatting options ++ chat room searching ++ list of contacts in 'invite to group chat' dialog ++ Multi-User Conference item in contact menu ++ some look & feel improvements (better resizing, new icons) ++ internal history of messages +* a lot of bugfixes and code improvements +* code clean-up +1.0.5.3 +--------- ++ full text formatting (font name, font size) ++ private messaging sessions ++ displaying user details (administrator/moderator/registered nickname) ++ displaying chat room details icons (moderated/members only/anonymous nicknames not allowed) ++ browsing own chat rooms/registered nicknames +* code clean-up +* bugfixes +1.0.5.2 +--------- ++ text formatting (bold, italic, underline, text color for now) ++ chat rooms browsing page by page +* bugfixes and code clean-up +1.0.5.1 +--------- ++ initial multi-user conferences and chats support ++ MUCC plugin responsible for chats GUI (manager window (groups/rooms), messanging window, helper dialogs) + +2004-09-23 Version 1.0.4.0 + Jabber and Tlen now have separate source trees (Tlen plugin is compliant with GCC now) + File transfer with forwarding and SOCKS4/5 proxy support + vCard viewing and editing + Web messages receiving + Incoming email notification through the popup plugin and sounds + User typing notification (patch by Adam Libura) + Searching users by login + New user details page + Invisible status message + Option to leave offline status message + Option to show offline users with status message as invisible + Link to create new account + Fixed bug: adjust offline message time + A lot of other fixes and improvements + +2003-08-19 Version 0.1.0.2 + Fixed bug: crash when receiving some invisible presence + Fixed bug: incorrect newline encoding/decoding (tlen uses \r\n while jabber uses \n) + Fixed bug: User detail text is not decoded + Use new invisible presence (now conform to Jabber invisible presence) + Advanced search + Based on Jabber plugin 0.1.1.2 + +2003-05-12 Version 0.1.0.1 + Fixed bug: slightly incorrect online presence + Based on Jabber plugin 0.1.1.0 + +2003-01-19 Version 0.1.0.0 + Based on Jabber plugin 0.1.0.7 + Tlen basic user info + Tlen invisible status + Tlen visible/invisible list + Option to show invisible users as invisible + Find/add users using tlen user database + Rebase DLL to 0x32600000 diff --git a/plugins/!NotAdopted/Tlen/docs/gpl.txt b/plugins/!NotAdopted/Tlen/docs/gpl.txt new file mode 100644 index 0000000000..45645b4b53 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/docs/gpl.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/plugins/!NotAdopted/Tlen/docs/gpl_comment.txt b/plugins/!NotAdopted/Tlen/docs/gpl_comment.txt new file mode 100644 index 0000000000..ecacc17720 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/docs/gpl_comment.txt @@ -0,0 +1,20 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2012 Santithorn Bunchua, Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ diff --git a/plugins/!NotAdopted/Tlen/docs/readme_tlen.txt b/plugins/!NotAdopted/Tlen/docs/readme_tlen.txt new file mode 100644 index 0000000000..234e9b098b --- /dev/null +++ b/plugins/!NotAdopted/Tlen/docs/readme_tlen.txt @@ -0,0 +1,60 @@ +Tlen Protocol Plugin for Miranda IM +=================================== + +Introduction: + Tlen is a protocol used by a propritary instant messaging network + at tlen.pl. It is based on Jabber, and, therefore, this plugin + is very much based on Jabber protocol plugin for Miranda. All + necessary helps to create this Tlen plugin are from Adam Strzelecki. + +Installation: + Copy tlen.dll and (optional) tlen_czaty.dll to Miranda's plugins directory. + + If you want to have multiple Tlen accounts online at the same time, + you need to have multiple copies of tlen.dll, each with different name, + all in Miranda's plugins directory. Note that all configurations for a + Tlen account (including your contact list) are associated with the + DLL's name. In addition, it is highly recommended that you do NOT choose + the name that is in conflict with other plugins or any database categories + used by Miranda core (use DatabaseViewer or DatabaseEditor to see what + database categories are already in use). + +More information: + Web: http://mtlen.berlios.de + E-mail: the_leech@users.berlios.de + +Copyright (c) 2002-2012 Santithorn Bunchua (keh@au.edu), Piotr Piastucki + +Acknowledgement: + We would like to thank the following people for their helps and/or comments + (alphabetically listed): + Dmitry Balabanov + Nikola Dachev + Sam Kothari + Adam Libura + Jцrgen Persson + Robert Rainwater + Adam Strzelecki + Michal Wojciechowski + Szymon Tokarz (wsx22) + +================================================================ + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2012 Santithorn Bunchua, Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +================================================================ diff --git a/plugins/!NotAdopted/Tlen/docs/tlen-translation.txt b/plugins/!NotAdopted/Tlen/docs/tlen-translation.txt new file mode 100644 index 0000000000..6406f204c7 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/docs/tlen-translation.txt @@ -0,0 +1,153 @@ +;*********************************** +;******* Tlen language by raq ****** + +[Tlen czaty] +;[Authentication failed for] +;[Tlen Authentication] +[Network] +[Advanced] +[PopUps] +[Accept all alerts] +[Ignore alerts from unauthorized contacts] +[Ignore all alerts] +[Always ask me] +[Accept invitations from authorized contacts] +[Accept all invitations] +[Ignore invitations from unauthorized contacts] +[Ignore all invitation] +[Always ask me] +[] +[] +[Online] +[Away] +[NA] +[DND] +[Free for chat] +[Invisible] +[These changes will take effect the next time you connect to the Tlen network.] +[Tlen Protocol Option] +[Forwarding] +;[SOCKS4] +;[SOCKS5] +;[Tlen login] +[Enter password for] +[Error: Not enough memory] +[Error: Cannot connect to the server] +[The connection requires an OpenSSL library, which is not installed.] +;[Jabber Connection Error] +[%s Web Messages] +[Web message] +[From] +;[E-mail] +[An alert has been received.] +[Private conference] +[New mail] +[Subject] +;[both] +[to] +[from] +[none] +;[not on roster] +[Error] +[Unknown error message] +[connection] +[Incoming mail] +;[Alert] +[Multi-User Conference] +[Tlen Chats...] +[Voice Chat] +[Voice chat] +[Request authorization] +[Grant authorization] +[You have been kicked. Reason: %s ] +[You cannot join this chat room, because you are banned.] +[Chat room not found.] +[This is a private chat room and you are not one of the members.] +[You cannot send any message unless you join this chat room.] +[Chat room with already created.] +[Nickname '%s' is already registered.] +[Nickname already in use, please try another one. Hint: '%s' is free.] +[You cannot register more than %s nicknames.] +[You cannot create more than %s chat rooms.] +[You cannot join more than %s chat rooms.] +[Anonymous nicknames are not allowed in this chat room.] +[Unknown error code : %d] +[Default] + +;tlen.rc + +[Username:] +[Create a new account] +[Password:] +[Save password] +[Use SSL] +[Options] +[Automatically reconnect after unintentional disconnection] +[Leave status message after disconnection] +[Ignore advertisements] +[Automatically delete contacts not in my roster] +[Show offline users with status messages as invisible in contact list] +[Enable avatars] +[Send and receive version information] +[Use Nudge plugin] +[Log alerts as messages] +[Alert policy] +[Group chat policy] +[Voice Chats] +[Voice chat policy] +[Recording device:] +[Playback device:] +[Expert Options] +[Login server:] +[Connection Host:] +;[Port:] +[Keep connection alive] +[Enable Always Visible and Never Visible] +[File Transfer and Voice Chats] +[Use proxy for incoming connections] +[Proxy type:] +[Proxy server:] +[Proxy requires authorization] +[Delay] +[&From PopUp plugin] +[&Custom] +[P&ermanent] +[Colours] +[Background] +[Text] +[General Options] +[Preview] +[Enable incoming mail notification] +;[OK] +[Cancel] +[Nick name:] +[First name:] +[Last name:] +;[E-mail:] +[Gender:] +[Year of birth:] +[City:] +[School:] +[Occupation:] +[Looking for:] +[Voice chats] +[Save changes] +;[Subscription:] +[Age:] +[Personal Information] +;[Status:] +[Plan:] +[&Accept] +[From:] +[Software:] +[Version:] +[System:] +[The following invitation to join a voice chat is received.] +[Current Avatar] +[New Avatar] +[Public] +[Browse...] +[Set] +[Delete] +[Note: Image size max. 64x64] +[Enable encryption] diff --git a/plugins/!NotAdopted/Tlen/icos/auth_grant.ico b/plugins/!NotAdopted/Tlen/icos/auth_grant.ico new file mode 100644 index 0000000000..8d1ba94308 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/icos/auth_grant.ico differ diff --git a/plugins/!NotAdopted/Tlen/icos/auth_request.ico b/plugins/!NotAdopted/Tlen/icos/auth_request.ico new file mode 100644 index 0000000000..116ed47baf Binary files /dev/null and b/plugins/!NotAdopted/Tlen/icos/auth_request.ico differ diff --git a/plugins/!NotAdopted/Tlen/icos/groupchats.ico b/plugins/!NotAdopted/Tlen/icos/groupchats.ico new file mode 100644 index 0000000000..ecd2070d20 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/icos/groupchats.ico differ diff --git a/plugins/!NotAdopted/Tlen/icos/image.ico b/plugins/!NotAdopted/Tlen/icos/image.ico new file mode 100644 index 0000000000..832b9a8b69 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/icos/image.ico differ diff --git a/plugins/!NotAdopted/Tlen/icos/mail.ico b/plugins/!NotAdopted/Tlen/icos/mail.ico new file mode 100644 index 0000000000..c5ded81702 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/icos/mail.ico differ diff --git a/plugins/!NotAdopted/Tlen/icos/microphone.ico b/plugins/!NotAdopted/Tlen/icos/microphone.ico new file mode 100644 index 0000000000..1edeb90d1f Binary files /dev/null and b/plugins/!NotAdopted/Tlen/icos/microphone.ico differ diff --git a/plugins/!NotAdopted/Tlen/icos/speaker.ico b/plugins/!NotAdopted/Tlen/icos/speaker.ico new file mode 100644 index 0000000000..77545c0598 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/icos/speaker.ico differ diff --git a/plugins/!NotAdopted/Tlen/icos/tlen.ico b/plugins/!NotAdopted/Tlen/icos/tlen.ico new file mode 100644 index 0000000000..a166dd4c5b Binary files /dev/null and b/plugins/!NotAdopted/Tlen/icos/tlen.ico differ diff --git a/plugins/!NotAdopted/Tlen/icos/tlenchats.ico b/plugins/!NotAdopted/Tlen/icos/tlenchats.ico new file mode 100644 index 0000000000..52ab77ff63 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/icos/tlenchats.ico differ diff --git a/plugins/!NotAdopted/Tlen/icos/voicechat.ico b/plugins/!NotAdopted/Tlen/icos/voicechat.ico new file mode 100644 index 0000000000..f989d5b212 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/icos/voicechat.ico differ diff --git a/plugins/!NotAdopted/Tlen/jabber.h b/plugins/!NotAdopted/Tlen/jabber.h new file mode 100644 index 0000000000..fdaabf5e43 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/jabber.h @@ -0,0 +1,438 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef _JABBER_H_ +#define _JABBER_H_ + +#if defined(UNICODE) + #ifndef _UNICODE + #define _UNICODE + #endif +#endif + +#define MIRANDA_VER 0x0800 + +#undef _WIN32_WINNT +#undef _WIN32_IE +#define _WIN32_WINNT 0x0501 +#define _WIN32_IE 0x0501 + +#define __try +#define __except(x) if (0) +#define __finally + +#define _try __try +#define _except __except +#define _finally __finally + +#ifdef _DEBUG +#define _CRTDBG_MAP_ALLOC +#include +#include +#endif +#define ENABLE_LOGGING + +/******************************************************************* + * Global compilation flags + *******************************************************************/ + +/******************************************************************* + * Global header files + *******************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "jabber_xml.h" +#include "crypto/polarssl/aes.h" +#include "crypto/polarssl/bignum.h" + +/******************************************************************* + * Global constants + *******************************************************************/ +#define TLEN_DEFAULT_PORT 443 +#define JABBER_IQID "mim_" +#define TLEN_REGISTER "http://reg.tlen.pl/" +#define TLEN_MAX_SEARCH_RESULTS_PER_PAGE 20 + +// User-defined message +#define WM_TLEN_REFRESH (WM_USER + 100) +// Error code +#define JABBER_ERROR_REDIRECT 302 +#define JABBER_ERROR_BAD_REQUEST 400 +#define JABBER_ERROR_UNAUTHORIZED 401 +#define JABBER_ERROR_PAYMENT_REQUIRED 402 +#define JABBER_ERROR_FORBIDDEN 403 +#define JABBER_ERROR_NOT_FOUND 404 +#define JABBER_ERROR_NOT_ALLOWED 405 +#define JABBER_ERROR_NOT_ACCEPTABLE 406 +#define JABBER_ERROR_REGISTRATION_REQUIRED 407 +#define JABBER_ERROR_REQUEST_TIMEOUT 408 +#define JABBER_ERROR_CONFLICT 409 +#define JABBER_ERROR_INTERNAL_SERVER_ERROR 500 +#define JABBER_ERROR_NOT_IMPLEMENTED 501 +#define JABBER_ERROR_REMOTE_SERVER_ERROR 502 +#define JABBER_ERROR_SERVICE_UNAVAILABLE 503 +#define JABBER_ERROR_REMOTE_SERVER_TIMEOUT 504 + +#define TLEN_ALERTS_ACCEPT_ALL 0 +#define TLEN_ALERTS_IGNORE_NIR 1 +#define TLEN_ALERTS_IGNORE_ALL 2 + +#define TLEN_IMAGES_ACCEPT_ALL 0 +#define TLEN_IMAGES_IGNORE_NIR 1 +#define TLEN_IMAGES_IGNORE_ALL 2 + +#define TLEN_MUC_ASK 0 +#define TLEN_MUC_ACCEPT_IR 1 +#define TLEN_MUC_ACCEPT_ALL 2 +#define TLEN_MUC_IGNORE_NIR 3 +#define TLEN_MUC_IGNORE_ALL 4 + +#define IDC_STATIC (-1) + +/******************************************************************* + * Global data structures and data type definitions + *******************************************************************/ +typedef HANDLE JABBER_SOCKET; + +typedef enum { + LIST_ROSTER, // Roster list + LIST_CHATROOM, // Groupchat room currently joined + LIST_FILE, // Current file transfer session + LIST_INVITATIONS,// Invitations to be sent + LIST_SEARCH, // Rooms names being searched + LIST_VOICE, + LIST_PICTURE +} JABBER_LIST; + +typedef enum { + IQ_PROC_NONE, + IQ_PROC_GETSEARCH +} JABBER_IQ_PROCID; + +typedef enum { + SUB_NONE, + SUB_TO, + SUB_FROM, + SUB_BOTH +} JABBER_SUBSCRIPTION; + +typedef struct { + char *szOnline; + char *szAway; + char *szNa; + char *szDnd; + char *szFreechat; + char *szInvisible; +} JABBER_MODEMSGS; + +typedef struct { + char mailBase[256]; + char mailMsg[256]; + int mailMsgMthd; + char mailIndex[256]; + int mailIndexMthd; + char mailLogin[256]; + int mailLoginMthd; + char mailCompose[256]; + int mailComposeMthd; + char avatarGet[256]; + int avatarGetMthd; + char avatarUpload[256]; + int avatarUploadMthd; + char avatarRemove[256]; + int avatarRemoveMthd; +} TlenConfiguration; + +typedef struct { + BOOL useEncryption; + BOOL reconnect; + BOOL rosterSync; + BOOL offlineAsInvisible; + BOOL leaveOfflineMessage; + int offlineMessageOption; + BOOL ignoreAdvertisements; + int alertPolicy; + int groupChatPolicy; + int voiceChatPolicy; + int imagePolicy; + BOOL enableAvatars; + BOOL enableVersion; + BOOL useNudge; + BOOL logAlerts; + BOOL useNewP2P; + BOOL sendKeepAlive; + BOOL savePassword; +} TlenOptions; + +struct JABBER_IQ_FUNC_STRUCT; +struct JABBER_LIST_ITEM_STRUCT; +struct TLEN_VOICE_CONTROL_STRUCT; + +typedef struct { + PROTO_INTERFACE iface; + HANDLE hNetlibUser; + HANDLE hFileNetlibUser; + + JABBER_MODEMSGS modeMsgs; + + struct ThreadDataStruct *threadData; + HANDLE hTlenNudge; + HANDLE hMenuMUC; + HANDLE hMenuChats; + HANDLE hMenuInbox; + HANDLE hMenuContactMUC; + HANDLE hMenuContactVoice; + HANDLE hMenuContactGrantAuth; + HANDLE hMenuContactRequestAuth; + HANDLE hMenuPicture; + + HANDLE* hServices; + unsigned serviceNum; + HANDLE* hHooks; + unsigned hookNum; + + int listsCount; + struct JABBER_LIST_ITEM_STRUCT *lists; + CRITICAL_SECTION csLists; + + int iqCount; + int iqAlloced; + struct JABBER_IQ_FUNC_STRUCT *iqList; + CRITICAL_SECTION csIqList; + + CRITICAL_SECTION csSerial; + unsigned int serial; + BOOL isOnline; + BOOL isConnected; + + CRITICAL_SECTION modeMsgMutex; + + HANDLE hMenuRoot; + + char *searchJID; + int searchID; + int searchIndex; + char *searchQuery; + int searchQueryLen; + + CRITICAL_SECTION csSend; + + HWND voiceDlgHWND; + struct TLEN_VOICE_CONTROL_STRUCT *playbackControl; + struct TLEN_VOICE_CONTROL_STRUCT *recordingControl; + int framesAvailableForPlayback; + int availOverrunValue; + + TlenOptions tlenOptions; +} TlenProtocol; + + +typedef struct ThreadDataStruct{ + HANDLE hThread; + char *streamId; + char username[128]; + char password[128]; + char server[128]; + char manualHost[128]; + char avatarToken[128]; + char avatarHash[64]; + int avatarFormat; + WORD port; + BOOL useEncryption; + + JABBER_SOCKET s; //HANDLE from CallService(MS_NETLIB_OPENCONNECTION (jabber_ws.c:68) + aes_context aes_in_context; + aes_context aes_out_context; + unsigned char aes_in_iv[16]; + unsigned char aes_out_iv[16]; + + BOOL useAES; + TlenConfiguration tlenConfig; + TlenProtocol *proto; +} ThreadData; + + +typedef enum { FT_CONNECTING, FT_INITIALIZING, FT_RECEIVING, FT_DONE, FT_ERROR, FT_DENIED, FT_SWITCH } JABBER_FILE_STATE; +typedef enum { FT_RECV, FT_SEND} JABBER_FILE_MODE; +typedef struct TLEN_FILE_TRANSFER_STRUCT{ + HANDLE hContact; + JABBER_SOCKET s; + NETLIBNEWCONNECTIONPROC_V2 pfnNewConnectionV2; + JABBER_FILE_STATE state; + char *jid; + int fileId; + char *iqId; + int mode; + + // Used by file receiving only + char *hostName; + WORD wPort; + char *localName; + WORD wLocalPort; + char *szSavePath; + long fileReceivedBytes; + long fileTotalSize; + + // Used by file sending only + HANDLE hFileEvent; + int fileCount; + char **files; + long *filesSize; + //long fileTotalSize; // Size of the current file (file being sent) + long allFileTotalSize; + long allFileReceivedBytes; + char *szDescription; + int currentFile; + + // New p2p + BOOL newP2P; + char *id2; + SOCKET udps; + aes_context aes_context; + unsigned char aes_iv[16]; + TlenProtocol *proto; + +} TLEN_FILE_TRANSFER; + +typedef struct { + PROTOSEARCHRESULT hdr; + char jid[256]; +} JABBER_SEARCH_RESULT; + +typedef struct { + char *iqId; + PROTOSEARCHRESULT hdr; + char jid[256]; +} TLEN_CONFERENCE; + + +typedef struct { + int id; + TCHAR *name; +} JABBER_FIELD_MAP; + + +/******************************************************************* + * Global variables + *******************************************************************/ +extern HINSTANCE hInst; +extern HANDLE hMainThread; + +/******************************************************************* + * Function declarations + *******************************************************************/ +HICON GetIcolibIcon(int iconId); +void ReleaseIcolibIcon(HICON hIcon); + +void JabberLog(TlenProtocol *proto, const char *fmt, ...); +void __cdecl JabberServerThread(ThreadData *info); +// jabber_ws.c +BOOL JabberWsInit(TlenProtocol *proto); +void JabberWsUninit(TlenProtocol *proto); +JABBER_SOCKET JabberWsConnect(TlenProtocol *proto, char *host, WORD port); +int JabberWsSend(TlenProtocol *proto, JABBER_SOCKET s, char *data, int datalen); +int JabberWsRecv(TlenProtocol *proto, JABBER_SOCKET s, char *data, long datalen); +int JabberWsSendAES(TlenProtocol *proto, char *data, int datalen, aes_context *aes_ctx, unsigned char *aes_iv); +int JabberWsRecvAES(TlenProtocol *proto, char *data, long datalen, aes_context *aes_ctx, unsigned char *aes_iv); +// jabber_util.c +HANDLE HookEventObj_Ex(const char *name, TlenProtocol *proto, MIRANDAHOOKOBJ hook); +HANDLE CreateServiceFunction_Ex(const char *name, TlenProtocol *proto, MIRANDASERVICEOBJ service); +void UnhookEvents_Ex(TlenProtocol *proto); +void DestroyServices_Ex(TlenProtocol *proto); +void JabberSerialInit(TlenProtocol *proto); +void JabberSerialUninit(TlenProtocol *proto); +unsigned int JabberSerialNext(TlenProtocol *proto); +int JabberSend(TlenProtocol *proto, const char *fmt, ...); +HANDLE JabberHContactFromJID(TlenProtocol *proto, const char *jid); +char *JabberJIDFromHContact(TlenProtocol *proto, HANDLE hContact); +char *JabberLoginFromJID(const char *jid); +char *JabberResourceFromJID(const char *jid); +char *JabberNickFromJID(const char *jid); +char *JabberLocalNickFromJID(const char *jid); +char *TlenGroupEncode(const char *str); +char *TlenGroupDecode(const char *str); +char *JabberSha1(char *str); +char *TlenSha1(char *str, int len); +char *TlenPasswordHash(const char *str); +void TlenUrlDecode(char *str); +char *TlenUrlEncode(const char *str); +char *JabberTextEncode(const char *str); +char *JabberTextDecode(const char *str); +char *JabberBase64Encode(const char *buffer, int bufferLen); +char *JabberBase64Decode(const char *buffer, int *resultLen); +int JabberGetPictureType(const char* buf); +void TlenLogMessage(TlenProtocol *proto, HANDLE hContact, DWORD flags, const char *message); +BOOL IsAuthorized(TlenProtocol *proto, const char *jid); +//char *JabberGetVersionText(); +time_t JabberIsoToUnixTime(char *stamp); +time_t TlenTimeToUTC(time_t time); +void JabberSendPresence(TlenProtocol *proto,int status); +void JabberStringAppend(char **str, int *sizeAlloced, const char *fmt, ...); +//char *JabberGetClientJID(char *jid); +// jabber_misc.c +void JabberDBAddEvent(TlenProtocol *proto, HANDLE hContact, int eventType, DWORD flags, PBYTE pBlob, DWORD cbBlob); +void JabberDBAddAuthRequest(TlenProtocol *proto, char *jid, char *nick); +HANDLE JabberDBCreateContact(TlenProtocol *proto, char *jid, char *nick, BOOL temporary); +void JabberContactListCreateGroup(char *groupName); +unsigned long JabberForkThread(void (__cdecl *threadcode)(void*), unsigned long stacksize, void *arg); +// jabber_svc.c +int JabberGetInfo(PROTO_INTERFACE *ptr, HANDLE hContact, int infoType); +int TlenRunSearch(TlenProtocol *proto); +// jabber_advsearch.c +extern JABBER_FIELD_MAP tlenFieldGender[]; +extern JABBER_FIELD_MAP tlenFieldLookfor[]; +extern JABBER_FIELD_MAP tlenFieldStatus[]; +extern JABBER_FIELD_MAP tlenFieldOccupation[]; +extern JABBER_FIELD_MAP tlenFieldPlan[]; + +INT_PTR CALLBACK TlenAdvSearchDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +char *TlenAdvSearchCreateQuery(HWND hwndDlg, int iqId); + + +#endif + diff --git a/plugins/!NotAdopted/Tlen/jabber_iq.c b/plugins/!NotAdopted/Tlen/jabber_iq.c new file mode 100644 index 0000000000..219f60e53d --- /dev/null +++ b/plugins/!NotAdopted/Tlen/jabber_iq.c @@ -0,0 +1,114 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" +#include "jabber_iq.h" + + +void JabberIqInit(TlenProtocol *proto) +{ + InitializeCriticalSection(&proto->csIqList); + proto->iqList = NULL; + proto->iqCount = 0; + proto->iqAlloced = 0; +} + +void JabberIqUninit(TlenProtocol *proto) +{ + if (proto->iqList) mir_free(proto->iqList); + proto->iqList = NULL; + proto->iqCount = 0; + proto->iqAlloced = 0; + DeleteCriticalSection(&proto->csIqList); +} + +static void JabberIqRemove(TlenProtocol *proto, int index) +{ + EnterCriticalSection(&proto->csIqList); + if (index>=0 && indexiqCount) { + memmove(proto->iqList+index, proto->iqList+index+1, sizeof(JABBER_IQ_FUNC)*(proto->iqCount-index-1)); + proto->iqCount--; + } + LeaveCriticalSection(&proto->csIqList); +} + +static void JabberIqExpire(TlenProtocol *proto) +{ + int i; + time_t expire; + + EnterCriticalSection(&proto->csIqList); + expire = time(NULL) - 120; // 2 minute + i = 0; + while (i < proto->iqCount) { + if (proto->iqList[i].requestTime < expire) + JabberIqRemove(proto, i); + else + i++; + } + LeaveCriticalSection(&proto->csIqList); +} + +JABBER_IQ_PFUNC JabberIqFetchFunc(TlenProtocol *proto, int iqId) +{ + int i; + JABBER_IQ_PFUNC res; + + EnterCriticalSection(&proto->csIqList); + JabberIqExpire(proto); + for (i=0; iiqCount && proto->iqList[i].iqId!=iqId; i++); + if (i < proto->iqCount) { + res = proto->iqList[i].func; + JabberIqRemove(proto, i); + } + else { + res = (JABBER_IQ_PFUNC) NULL; + } + LeaveCriticalSection(&proto->csIqList); + return res; +} + +void JabberIqAdd(TlenProtocol *proto, unsigned int iqId, JABBER_IQ_PROCID procId, JABBER_IQ_PFUNC func) +{ + int i; + + EnterCriticalSection(&proto->csIqList); + if (procId == IQ_PROC_NONE) + i = proto->iqCount; + else + for (i=0; iiqCount && proto->iqList[i].procId!=procId; i++); + + if (i>=proto->iqCount && proto->iqCount>=proto->iqAlloced) { + proto->iqAlloced = proto->iqCount + 8; + proto->iqList = mir_realloc(proto->iqList, sizeof(JABBER_IQ_FUNC)*proto->iqAlloced); + } + + if (proto->iqList != NULL) { + proto->iqList[i].iqId = iqId; + proto->iqList[i].procId = procId; + proto->iqList[i].func = func; + proto->iqList[i].requestTime = time(NULL); + if (i == proto->iqCount) proto->iqCount++; + } + LeaveCriticalSection(&proto->csIqList); +} + diff --git a/plugins/!NotAdopted/Tlen/jabber_iq.h b/plugins/!NotAdopted/Tlen/jabber_iq.h new file mode 100644 index 0000000000..dfdcf9e91a --- /dev/null +++ b/plugins/!NotAdopted/Tlen/jabber_iq.h @@ -0,0 +1,61 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#ifndef _JABBER_IQ_H_ +#define _JABBER_IQ_H_ + +#include "jabber_xml.h" +#include "jabber.h" + +typedef void (*JABBER_IQ_PFUNC)(TlenProtocol *proto, XmlNode *iqNode); + +typedef struct JABBER_IQ_FUNC_STRUCT { + int iqId; // id to match IQ get/set with IQ result + JABBER_IQ_PROCID procId; // must be unique in the list, except for IQ_PROC_NONE which can have multiple entries + JABBER_IQ_PFUNC func; // callback function + time_t requestTime; // time the request was sent, used to remove relinquent entries +} JABBER_IQ_FUNC; + +void JabberIqInit(TlenProtocol *proto); +void JabberIqUninit(TlenProtocol *proto); +JABBER_IQ_PFUNC JabberIqFetchFunc(TlenProtocol *proto, int iqId); +void JabberIqAdd(TlenProtocol *proto, unsigned int iqId, JABBER_IQ_PROCID procId, JABBER_IQ_PFUNC func); + +void JabberIqResultAuth(TlenProtocol *proto, XmlNode *iqNode); +void JabberIqResultRoster(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultVcard(TlenProtocol *proto, XmlNode *iqNode); +void JabberIqResultSearch(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultVersion(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultInfo(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultTcfg(TlenProtocol *proto, XmlNode *iqNode); + +void TlenIqResultChatGroups(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultChatRooms(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultUserRooms(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultUserNicks(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultRoomSearch(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultRoomInfo(TlenProtocol *proto, XmlNode *iqNode); +void TlenIqResultChatRoomUsers(TlenProtocol *proto, XmlNode *iqNode); +//void JabberIqResultSetPassword(XmlNode *iqNode, void *userdata); + +#endif + diff --git a/plugins/!NotAdopted/Tlen/jabber_iqid.c b/plugins/!NotAdopted/Tlen/jabber_iqid.c new file mode 100644 index 0000000000..2c16054038 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/jabber_iqid.c @@ -0,0 +1,629 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" +#include "resource.h" +#include "jabber_list.h" +#include "jabber_iq.h" +#include "tlen_muc.h" + +void JabberIqResultAuth(TlenProtocol *proto, XmlNode *iqNode) +{ + char *type; + + // RECVED: authentication result + // ACTION: if successfully logged in, continue by requesting roster list and set my initial status + if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; + + if (!strcmp(type, "result")) { + DBVARIANT dbv; + + if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "Nick", &dbv)) + DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "Nick", proto->threadData->username); + else + DBFreeVariant(&dbv); +// iqId = JabberSerialNext(); +// JabberIqAdd(iqId, IQ_PROC_NONE, JabberIqResultGetRoster); +// JabberSend(info, "", iqId); + + JabberSend(proto, ""); + JabberSend(proto, ""); + } + // What to do if password error? etc... + else if (!strcmp(type, "error")) { + char text[128]; + + JabberSend(proto, ""); + _snprintf(text, sizeof(text), "%s %s@%s.", TranslateT("Authentication failed for"), proto->threadData->username, proto->threadData->server); + MessageBoxA(NULL, text, Translate("Tlen Authentication"), MB_OK|MB_ICONSTOP|MB_SETFOREGROUND); + ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGINERR_WRONGPASSWORD); + proto->threadData = NULL; // To disallow auto reconnect + } +} + +void JabberResultSetRoster(TlenProtocol *proto, XmlNode *queryNode) { + DBVARIANT dbv; + XmlNode *itemNode, *groupNode; + JABBER_LIST_ITEM *item; + HANDLE hContact; + char *jid, *name, *nick; + int i; + char *str; + + for (i=0; inumChild; i++) { + itemNode = queryNode->child[i]; + if (!strcmp(itemNode->name, "item")) { + if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { + str = JabberXmlGetAttrValue(itemNode, "subscription"); + if (!strcmp(str, "remove")) { + if ((hContact=JabberHContactFromJID(proto, jid)) != NULL) { + if (DBGetContactSettingWord(hContact, proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) + DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE); + } + JabberListRemove(proto, LIST_ROSTER, jid); + } else { + item = JabberListAdd(proto, LIST_ROSTER, jid); + if (item != NULL) { + if (str == NULL) item->subscription = SUB_NONE; + else if (!strcmp(str, "both")) item->subscription = SUB_BOTH; + else if (!strcmp(str, "to")) item->subscription = SUB_TO; + else if (!strcmp(str, "from")) item->subscription = SUB_FROM; + else item->subscription = SUB_NONE; + if ((name=JabberXmlGetAttrValue(itemNode, "name")) != NULL) { + nick = JabberTextDecode(name); + } else { + nick = JabberLocalNickFromJID(jid); + } + if (nick != NULL) { + if (item->nick) mir_free(item->nick); + item->nick = nick; + + if ((hContact=JabberHContactFromJID(proto, jid)) == NULL) { + // Received roster has a new JID. + // Add the jid (with empty resource) to Miranda contact list. + hContact = JabberDBCreateContact(proto, jid, nick, FALSE); + } + DBWriteContactSettingString(hContact, "CList", "MyHandle", nick); + if (item->group) mir_free(item->group); + if ((groupNode=JabberXmlGetChild(itemNode, "group"))!=NULL && groupNode->text!=NULL) { + item->group = TlenGroupDecode(groupNode->text); + JabberContactListCreateGroup(item->group); + // Don't set group again if already correct, or Miranda may show wrong group count in some case + if (!DBGetContactSetting(hContact, "CList", "Group", &dbv)) { + if (strcmp(dbv.pszVal, item->group)) + DBWriteContactSettingString(hContact, "CList", "Group", item->group); + DBFreeVariant(&dbv); + } else + DBWriteContactSettingString(hContact, "CList", "Group", item->group); + } else { + item->group = NULL; + DBDeleteContactSetting(hContact, "CList", "Group"); + } + } + } + } + } + } + } +} + +void JabberIqResultRoster(TlenProtocol *proto, XmlNode *iqNode) +{ + XmlNode *queryNode; + char *type; + char *str; + + // RECVED: roster information + // ACTION: populate LIST_ROSTER and create contact for any new rosters + if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; + if ((queryNode=JabberXmlGetChild(iqNode, "query")) == NULL) return; + + if (!strcmp(type, "result")) { + str = JabberXmlGetAttrValue(queryNode, "xmlns"); + if (str!=NULL && !strcmp(str, "jabber:iq:roster")) { + DBVARIANT dbv; + XmlNode *itemNode, *groupNode; + JABBER_SUBSCRIPTION sub; + JABBER_LIST_ITEM *item; + HANDLE hContact; + char *jid, *name, *nick; + int i, oldStatus; + + for (i=0; inumChild; i++) { + itemNode = queryNode->child[i]; + if (!strcmp(itemNode->name, "item")) { + str = JabberXmlGetAttrValue(itemNode, "subscription"); + if (str==NULL) sub = SUB_NONE; + else if (!strcmp(str, "both")) sub = SUB_BOTH; + else if (!strcmp(str, "to")) sub = SUB_TO; + else if (!strcmp(str, "from")) sub = SUB_FROM; + else sub = SUB_NONE; + //if (str!=NULL && (!strcmp(str, "to") || !strcmp(str, "both"))) { + if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { + if ((name=JabberXmlGetAttrValue(itemNode, "name")) != NULL) { + nick = JabberTextDecode(name); + } else { + nick = JabberLocalNickFromJID(jid); + } + if (nick != NULL) { + item = JabberListAdd(proto, LIST_ROSTER, jid); + if (item->nick) mir_free(item->nick); + item->nick = nick; + item->subscription = sub; + if ((hContact=JabberHContactFromJID(proto, jid)) == NULL) { + // Received roster has a new JID. + // Add the jid (with empty resource) to Miranda contact list. + hContact = JabberDBCreateContact(proto, jid, nick, FALSE); + } + DBWriteContactSettingString(hContact, "CList", "MyHandle", nick); + if (item->group) mir_free(item->group); + if ((groupNode=JabberXmlGetChild(itemNode, "group"))!=NULL && groupNode->text!=NULL) { + item->group = TlenGroupDecode(groupNode->text); + JabberContactListCreateGroup(item->group); + // Don't set group again if already correct, or Miranda may show wrong group count in some case + if (!DBGetContactSetting(hContact, "CList", "Group", &dbv)) { + if (strcmp(dbv.pszVal, item->group)) + DBWriteContactSettingString(hContact, "CList", "Group", item->group); + DBFreeVariant(&dbv); + } + else + DBWriteContactSettingString(hContact, "CList", "Group", item->group); + } + else { + item->group = NULL; + DBDeleteContactSetting(hContact, "CList", "Group"); + } + if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "AvatarHash", &dbv)) { + if (item->avatarHash) mir_free(item->avatarHash); + item->avatarHash = mir_strdup(dbv.pszVal); + JabberLog(proto, "Setting hash [%s] = %s", nick, item->avatarHash); + DBFreeVariant(&dbv); + } + item->avatarFormat = DBGetContactSettingDword(hContact, proto->iface.m_szModuleName, "AvatarFormat", PA_FORMAT_UNKNOWN); + } + } + } + } + // Delete orphaned contacts (if roster sync is enabled) + if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "RosterSync", FALSE) == TRUE) { + HANDLE *list; + int listSize, listAllocSize; + + listSize = listAllocSize = 0; + list = NULL; + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact != NULL) { + str = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if(str!=NULL && !strcmp(str, proto->iface.m_szModuleName)) { + if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { + if (!JabberListExist(proto, LIST_ROSTER, dbv.pszVal)) { + JabberLog(proto, "Syncing roster: preparing to delete %s (hContact=0x%x)", dbv.pszVal, hContact); + if (listSize >= listAllocSize) { + listAllocSize = listSize + 100; + if ((list=(HANDLE *) mir_realloc(list, listAllocSize)) == NULL) { + listSize = 0; + break; + } + } + list[listSize++] = hContact; + } + DBFreeVariant(&dbv); + } + } + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); + } + for (i=0; ihMenuMUC, (LPARAM) &clmi); + if (proto->hMenuChats != NULL){ + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuChats, (LPARAM) &clmi); + } + } + + proto->isOnline = TRUE; + JabberLog(proto, "Status changed via THREADSTART"); + oldStatus = proto->iface.m_iStatus; + JabberSendPresence(proto, proto->iface.m_iDesiredStatus); + ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, proto->iface.m_iStatus); + ////////////////////////////////// + } + } +} + + +// Tlen actually use jabber:iq:search for other users vCard or jabber:iq:register for own vCard +void TlenIqResultVcard(TlenProtocol *proto, XmlNode *iqNode) +{ + XmlNode *queryNode, *itemNode, *n; + char *type, *jid; + char text[128]; + HANDLE hContact; + char *nText; + +// JabberLog(" iqIdGetVcard (tlen)"); + if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; + + if (!strcmp(type, "result")) { + BOOL hasFirst, hasLast, hasNick, hasEmail, hasCity, hasAge, hasGender, hasSchool, hasLookFor, hasOccupation; + DBVARIANT dbv; + int i; + + if ((queryNode=JabberXmlGetChild(iqNode, "query")) == NULL) return; + if ((itemNode=JabberXmlGetChild(queryNode, "item")) == NULL) return; + if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { + if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) return; + if (strchr(jid, '@') != NULL) { + sprintf(text, "%s", jid); + } else { + sprintf(text, "%s@%s", jid, dbv.pszVal); // Add @tlen.pl + } + DBFreeVariant(&dbv); + if ((hContact=JabberHContactFromJID(proto, text)) == NULL) { + if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginName", &dbv)) return; + if (strcmp(dbv.pszVal, jid)) { + DBFreeVariant(&dbv); + return; + } + DBFreeVariant(&dbv); + } + } else { + hContact = NULL; + } + hasFirst = hasLast = hasNick = hasEmail = hasCity = hasAge = hasGender = hasOccupation = hasLookFor = hasSchool = FALSE; + for (i=0; inumChild; i++) { + n = itemNode->child[i]; + if (n==NULL || n->name==NULL) continue; + if (!strcmp(n->name, "first")) { + if (n->text != NULL) { + hasFirst = TRUE; + nText = JabberTextDecode(n->text); + DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "FirstName", nText); + mir_free(nText); + } + } + else if (!strcmp(n->name, "last")) { + if (n->text != NULL) { + hasLast = TRUE; + nText = JabberTextDecode(n->text); + DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "LastName", nText); + mir_free(nText); + } + } + else if (!strcmp(n->name, "nick")) { + if (n->text != NULL) { + hasNick = TRUE; + nText = JabberTextDecode(n->text); + DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "Nick", nText); + mir_free(nText); + } + } + else if (!strcmp(n->name, "email")) { + if (n->text != NULL) { + hasEmail = TRUE; + nText = JabberTextDecode(n->text); + DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "e-mail", nText); + mir_free(nText); + } + } + else if (!strcmp(n->name, "c")) { + if (n->text != NULL) { + hasCity = TRUE; + nText = JabberTextDecode(n->text); + DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "City", nText); + mir_free(nText); + } + } + else if (!strcmp(n->name, "b")) { + if (n->text != NULL) { + WORD nAge; + hasAge = TRUE; + nAge = atoi(n->text); + DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "Age", nAge); + } + } + else if (!strcmp(n->name, "s")) { + if (n->text!=NULL && n->text[1]=='\0' && (n->text[0]=='1' || n->text[0]=='2')) { + hasGender = TRUE; + DBWriteContactSettingByte(hContact, proto->iface.m_szModuleName, "Gender", (BYTE) (n->text[0]=='1'?'M':'F')); + } + } + else if (!strcmp(n->name, "e")) { + if (n->text != NULL) { + hasSchool = TRUE; + nText = JabberTextDecode(n->text); + DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "School", nText); + mir_free(nText); + } + } + else if (!strcmp(n->name, "j")) { + if (n->text != NULL) { + WORD nOccupation; + hasOccupation = TRUE; + nOccupation = atoi(n->text); + DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "Occupation", nOccupation); + } + } + else if (!strcmp(n->name, "r")) { + if (n->text != NULL) { + WORD nLookFor; + hasLookFor = TRUE; + nLookFor = atoi(n->text); + DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "LookingFor", nLookFor); + } + } + else if (!strcmp(n->name, "g")) { // voice chat enabled + if (n->text != NULL) { + BYTE bVoice; + bVoice = atoi(n->text); + DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "VoiceChat", bVoice); + } + } + else if (!strcmp(n->name, "v")) { // status visibility + if (n->text != NULL) { + BYTE bPublic; + bPublic = atoi(n->text); + DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "PublicStatus", bPublic); + } + } + } + if (!hasFirst) + DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "FirstName"); + if (!hasLast) + DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "LastName"); + // We are not removing "Nick" +// if (!hasNick) +// DBDeleteContactSetting(hContact, iface.m_szModuleName, "Nick"); + if (!hasEmail) + DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "e-mail"); + if (!hasCity) + DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "City"); + if (!hasAge) + DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "Age"); + if (!hasGender) + DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "Gender"); + if (!hasSchool) + DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "School"); + if (!hasOccupation) + DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "Occupation"); + if (!hasLookFor) + DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "LookingFor"); + ProtoBroadcastAck(proto->iface.m_szModuleName, hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE) 1, 0); + } +} + +void JabberIqResultSearch(TlenProtocol *proto, XmlNode *iqNode) +{ + XmlNode *queryNode, *itemNode, *n; + char *type, *jid, *str; + int id, i, found; + JABBER_SEARCH_RESULT jsr = {0}; + DBVARIANT dbv = {0}; + + found = 0; +// JabberLog(" iqIdGetSearch"); + if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; + if ((str=JabberXmlGetAttrValue(iqNode, "id")) == NULL) return; + id = atoi(str+strlen(JABBER_IQID)); + + if (!strcmp(type, "result")) { + if ((queryNode=JabberXmlGetChild(iqNode, "query")) == NULL) return; + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { + jsr.hdr.cbSize = sizeof(JABBER_SEARCH_RESULT); + for (i=0; inumChild; i++) { + itemNode = queryNode->child[i]; + if (!strcmp(itemNode->name, "item")) { + if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { + if (strchr(jid, '@') != NULL) { + _snprintf(jsr.jid, sizeof(jsr.jid), "%s", jid); + } else { + _snprintf(jsr.jid, sizeof(jsr.jid), "%s@%s", jid, dbv.pszVal); + } + jsr.jid[sizeof(jsr.jid)-1] = '\0'; + jsr.hdr.id = jid; + jsr.hdr.flags = 0; //results are ansi + if ((n=JabberXmlGetChild(itemNode, "nick"))!=NULL && n->text!=NULL) + jsr.hdr.nick = JabberTextDecode(n->text); + else + jsr.hdr.nick = mir_strdup(""); + if ((n=JabberXmlGetChild(itemNode, "first"))!=NULL && n->text!=NULL) + jsr.hdr.firstName = JabberTextDecode(n->text); + else + jsr.hdr.firstName = mir_strdup(""); + if ((n=JabberXmlGetChild(itemNode, "last"))!=NULL && n->text!=NULL) + jsr.hdr.lastName = JabberTextDecode(n->text); + else + jsr.hdr.lastName = mir_strdup(""); + if ((n=JabberXmlGetChild(itemNode, "email"))!=NULL && n->text!=NULL) + jsr.hdr.email = JabberTextDecode(n->text); + else + jsr.hdr.email = mir_strdup(""); + + ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE) id, (LPARAM) &jsr); + found = 1; + mir_free(jsr.hdr.nick); + mir_free(jsr.hdr.firstName); + mir_free(jsr.hdr.lastName); + mir_free(jsr.hdr.email); + } + } + } + if (proto->searchJID!=NULL) { + if (!found) { + if (strchr(proto->searchJID, '@') != NULL) { + _snprintf(jsr.jid, sizeof(jsr.jid), "%s", proto->searchJID); + } else { + _snprintf(jsr.jid, sizeof(jsr.jid), "%s@%s", proto->searchJID, dbv.pszVal); + } + jsr.jid[sizeof(jsr.jid)-1] = '\0'; + jsr.hdr.nick = mir_strdup(""); + jsr.hdr.firstName = mir_strdup(""); + jsr.hdr.lastName = mir_strdup(""); + jsr.hdr.email = mir_strdup(""); + jsr.hdr.id = mir_strdup(""); + ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE) id, (LPARAM) &jsr); + mir_free(jsr.hdr.nick); + mir_free(jsr.hdr.firstName); + mir_free(jsr.hdr.lastName); + mir_free(jsr.hdr.email); + } + mir_free(proto->searchJID); + proto->searchJID = NULL; + } + DBFreeVariant(&dbv); + } + found = 0; + if (queryNode->numChild == TLEN_MAX_SEARCH_RESULTS_PER_PAGE) { + found = TlenRunSearch(proto); + } + if (!found) { + ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE) id, 0); + } + } else if (!strcmp(type, "error")) { + // ProtoBroadcastAck(iface.m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HANDLE) id, 0); + // There is no ACKRESULT_FAILED for ACKTYPE_SEARCH :) look at findadd.c + // So we will just send a SUCCESS + ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE) id, 0); + } +} + + +void GetConfigItem(XmlNode *node, char *dest, BOOL bMethod, int *methodDest) { + strcpy(dest, node->text); + TlenUrlDecode(dest); + if (bMethod) { + char *method = JabberXmlGetAttrValue(node, "method"); + if (method != NULL && !strcmpi(method, "POST")) { + *methodDest = REQUEST_POST; + } else { + *methodDest = REQUEST_GET; + } + } +} + +void TlenIqResultTcfg(TlenProtocol *proto, XmlNode *iqNode) +{ + XmlNode *queryNode, *miniMailNode, *node; + char *type; + + if ((type=JabberXmlGetAttrValue(iqNode, "type")) == NULL) return; + if (!strcmp(type, "result")) { + if ((queryNode=JabberXmlGetChild(iqNode, "query")) == NULL) return; + if ((miniMailNode=JabberXmlGetChild(queryNode, "mini-mail")) == NULL) return; + if ((node=JabberXmlGetChild(miniMailNode, "base")) != NULL) { + GetConfigItem(node, proto->threadData->tlenConfig.mailBase, FALSE, NULL); + } + if ((node=JabberXmlGetChild(miniMailNode, "msg")) != NULL) { + GetConfigItem(node, proto->threadData->tlenConfig.mailMsg, TRUE, &proto->threadData->tlenConfig.mailMsgMthd); + } + if ((node=JabberXmlGetChild(miniMailNode, "index")) != NULL) { + GetConfigItem(node, proto->threadData->tlenConfig.mailIndex, TRUE, &proto->threadData->tlenConfig.mailIndexMthd); + } + if ((node=JabberXmlGetChild(miniMailNode, "login")) != NULL) { + GetConfigItem(node, proto->threadData->tlenConfig.mailLogin, TRUE, &proto->threadData->tlenConfig.mailLoginMthd); + } + if ((node=JabberXmlGetChild(miniMailNode, "compose")) != NULL) { + GetConfigItem(node, proto->threadData->tlenConfig.mailCompose, TRUE, &proto->threadData->tlenConfig.mailComposeMthd); + } + if ((node=JabberXmlGetChild(miniMailNode, "avatar-get")) != NULL) { + GetConfigItem(node, proto->threadData->tlenConfig.avatarGet, TRUE, &proto->threadData->tlenConfig.avatarGetMthd); + } + if ((node=JabberXmlGetChild(miniMailNode, "avatar-upload")) != NULL) { + GetConfigItem(node, proto->threadData->tlenConfig.avatarUpload, TRUE, &proto->threadData->tlenConfig.avatarUploadMthd); + } + if ((node=JabberXmlGetChild(miniMailNode, "avatar-remove")) != NULL) { + GetConfigItem(node, proto->threadData->tlenConfig.avatarRemove, TRUE, &proto->threadData->tlenConfig.avatarRemoveMthd); + } + } +} + +void TlenIqResultVersion(TlenProtocol *proto, XmlNode *iqNode) +{ + XmlNode *queryNode = JabberXmlGetChild(iqNode, "query"); + if (queryNode != NULL) { + char* from; + if (( from=JabberXmlGetAttrValue( iqNode, "from" )) != NULL ) { + JABBER_LIST_ITEM *item; + if (( item=JabberListGetItemPtr( proto, LIST_ROSTER, from ))!=NULL) { + HANDLE hContact; + XmlNode *n; + if ( item->software ) mir_free( item->software ); + if ( item->version ) mir_free( item->version ); + if ( item->system ) mir_free( item->system ); + if (( n=JabberXmlGetChild( queryNode, "name" ))!=NULL && n->text ) { + item->software = JabberTextDecode( n->text ); + } else + item->software = NULL; + if (( n=JabberXmlGetChild( queryNode, "version" ))!=NULL && n->text ) + item->version = JabberTextDecode( n->text ); + else + item->version = NULL; + if (( n=JabberXmlGetChild( queryNode, "os" ))!=NULL && n->text ) + item->system = JabberTextDecode( n->text ); + else + item->system = NULL; + if (( hContact=JabberHContactFromJID(proto, item->jid )) != NULL ) { + if (item->software != NULL) { + DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "MirVer", item->software); + } else { + DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "MirVer"); + } + } + } + } + } +} + +void TlenIqResultInfo(TlenProtocol *proto, XmlNode *iqNode) +{ + XmlNode *queryNode = JabberXmlGetChild(iqNode, "query"); + if (queryNode != NULL) { + char* from; + if (( from=JabberXmlGetAttrValue( queryNode, "from" )) != NULL ) { + JABBER_LIST_ITEM *item; + if (( item=JabberListGetItemPtr( proto, LIST_ROSTER, from ))!=NULL) { + HANDLE hContact; + XmlNode *version = JabberXmlGetChild(queryNode, "version"); + item->protocolVersion = JabberTextDecode(version->text); + if (( hContact=JabberHContactFromJID(proto, item->jid )) != NULL ) { + if (item->software == NULL) { + char str[128]; + mir_snprintf(str, sizeof(str), "Tlen Protocol %s", item->protocolVersion); + DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "MirVer", str); + } + } + } + } + } +} + diff --git a/plugins/!NotAdopted/Tlen/jabber_list.c b/plugins/!NotAdopted/Tlen/jabber_list.c new file mode 100644 index 0000000000..8b916b6584 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/jabber_list.c @@ -0,0 +1,314 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" +#include "jabber_list.h" + + +static void JabberListFreeItemInternal(JABBER_LIST_ITEM *item); + +void JabberListInit(TlenProtocol *proto) +{ + proto->lists = NULL; + proto->listsCount = 0; + InitializeCriticalSection(&proto->csLists); +} + +void JabberListUninit(TlenProtocol *proto) +{ + JabberListWipe(proto); + DeleteCriticalSection(&proto->csLists); +} + +void JabberListWipe(TlenProtocol *proto) +{ + int i; + + EnterCriticalSection(&proto->csLists); + for(i=0; ilistsCount; i++) + JabberListFreeItemInternal(&(proto->lists[i])); + if (proto->lists != NULL) { + mir_free(proto->lists); + proto->lists = NULL; + } + proto->listsCount=0; + LeaveCriticalSection(&proto->csLists); +} + +void JabberListWipeSpecial(TlenProtocol *proto) +{ + int i; + EnterCriticalSection(&proto->csLists); + for(i=0; ilistsCount; i++) { + if (proto->lists[i].list != LIST_FILE && proto->lists[i].list != LIST_VOICE) { + JabberListFreeItemInternal(&(proto->lists[i])); + proto->listsCount--; + memmove(proto->lists+i, proto->lists+i+1, sizeof(JABBER_LIST_ITEM)*(proto->listsCount-i)); + i--; + } + } + proto->lists = (JABBER_LIST_ITEM *) mir_realloc(proto->lists, sizeof(JABBER_LIST_ITEM)*proto->listsCount); + LeaveCriticalSection(&proto->csLists); +} + +static void JabberListFreeItemInternal(JABBER_LIST_ITEM *item) +{ + if (item == NULL) + return; + + if (item->jid) mir_free(item->jid); + if (item->nick) mir_free(item->nick); + if (item->statusMessage) mir_free(item->statusMessage); + if (item->group) mir_free(item->group); + if (item->messageEventIdStr) mir_free(item->messageEventIdStr); +// if (item->type) mir_free(item->type); + //if (item->ft) JabberFileFreeFt(item->ft); // No need to free (it is always free when exit from JabberFileServerThread()) + if (item->roomName) mir_free(item->roomName); + if (item->version) mir_free(item->version); + if (item->software) mir_free(item->software); + if (item->system) mir_free(item->system); + if (item->avatarHash) mir_free(item->avatarHash); + + if (item->protocolVersion) mir_free(item->protocolVersion); + if (item->id2) mir_free(item->id2); +} + +static char * GetItemId(JABBER_LIST list, const char *jid) +{ + char *s, *p, *q; + s = mir_strdup(jid); + if (list != LIST_PICTURE) { + _strlwr(s); + // strip resouce name if any + if ((p=strchr(s, '@')) != NULL) { + if ((q=strchr(p, '/')) != NULL) + *q = '\0'; + } + } + return s; +} + +int JabberListExist(TlenProtocol *proto, JABBER_LIST list, const char *jid) +{ + int i; + size_t len; + char *s, *p; + s = GetItemId(list, jid); + len = strlen(s); + + EnterCriticalSection(&proto->csLists); + for(i=0; ilistsCount; i++) + if (proto->lists[i].list==list) { + p = proto->lists[i].jid; + if (p && strlen(p)>=len && (p[(int)len]=='\0'||p[(int)len]=='/') && !strncmp(p, s, len)) { + LeaveCriticalSection(&proto->csLists); + mir_free(s); + return i+1; + } + } + LeaveCriticalSection(&proto->csLists); + mir_free(s); + return 0; +} + +JABBER_LIST_ITEM *JabberListAdd(TlenProtocol *proto, JABBER_LIST list, const char *jid) +{ + char *s; + JABBER_LIST_ITEM *item; + + EnterCriticalSection(&proto->csLists); + if ((item=JabberListGetItemPtr(proto, list, jid)) != NULL) { + LeaveCriticalSection(&proto->csLists); + return item; + } + + s = GetItemId(list, jid); + proto->lists = (JABBER_LIST_ITEM *) mir_realloc(proto->lists, sizeof(JABBER_LIST_ITEM)*(proto->listsCount+1)); + item = &(proto->lists[proto->listsCount]); + memset(item, 0, sizeof(JABBER_LIST_ITEM)); + item->list = list; + item->jid = s; + item->nick = NULL; + item->status = ID_STATUS_OFFLINE; + item->statusMessage = NULL; + item->group = NULL; + item->messageEventIdStr = NULL; + item->wantComposingEvent = FALSE; + item->isTyping = FALSE; +// item->type = NULL; + item->ft = NULL; + item->roomName = NULL; + item->version = NULL; + item->software = NULL; + item->system = NULL; + item->avatarHash = NULL; + item->avatarFormat = PA_FORMAT_UNKNOWN; + item->newAvatarDownloading = FALSE; + item->versionRequested = FALSE; + item->infoRequested = FALSE; + proto->listsCount++; + LeaveCriticalSection(&proto->csLists); + + return item; +} + +void JabberListRemove(TlenProtocol *proto, JABBER_LIST list, const char *jid) +{ + int i; + + EnterCriticalSection(&proto->csLists); + i = JabberListExist(proto, list, jid); + if (!i) { + LeaveCriticalSection(&proto->csLists); + return; + } + i--; + JabberListFreeItemInternal(&(proto->lists[i])); + proto->listsCount--; + memmove(proto->lists+i, proto->lists+i+1, sizeof(JABBER_LIST_ITEM)*(proto->listsCount-i)); + proto->lists = (JABBER_LIST_ITEM *) mir_realloc(proto->lists, sizeof(JABBER_LIST_ITEM)*proto->listsCount); + LeaveCriticalSection(&proto->csLists); +} + +void JabberListRemoveList(TlenProtocol *proto, JABBER_LIST list) +{ + int i; + + i = 0; + while ((i=JabberListFindNext(proto, list, i)) >= 0) { + JabberListRemoveByIndex(proto, i); + } +} + +void JabberListRemoveByIndex(TlenProtocol *proto, int index) +{ + EnterCriticalSection(&proto->csLists); + if (index>=0 && indexlistsCount) { + JabberListFreeItemInternal(&(proto->lists[index])); + proto->listsCount--; + memmove(proto->lists+index, proto->lists+index+1, sizeof(JABBER_LIST_ITEM)*(proto->listsCount-index)); + proto->lists = (JABBER_LIST_ITEM *) mir_realloc(proto->lists, sizeof(JABBER_LIST_ITEM)*proto->listsCount); + } + LeaveCriticalSection(&proto->csLists); +} + +void JabberListAddResource(TlenProtocol *proto, JABBER_LIST list, const char *jid, int status, const char *statusMessage) +{ + int i; + + EnterCriticalSection(&proto->csLists); + i = JabberListExist(proto, list, jid); + if (!i) { + LeaveCriticalSection(&proto->csLists); + return; + } + i--; + + if (proto->lists[i].statusMessage != NULL) + mir_free(proto->lists[i].statusMessage); + if (statusMessage) + proto->lists[i].statusMessage = mir_strdup(statusMessage); + else + proto->lists[i].statusMessage = NULL; + LeaveCriticalSection(&proto->csLists); +} + +void JabberListRemoveResource(TlenProtocol *proto, JABBER_LIST list, const char *jid) +{ + int i; + EnterCriticalSection(&proto->csLists); + i = JabberListExist(proto, list, jid); + if (!i) { + LeaveCriticalSection(&proto->csLists); + return; + } + i--; + LeaveCriticalSection(&proto->csLists); +} + +int JabberListFindNext(TlenProtocol *proto, JABBER_LIST list, int fromOffset) +{ + int i; + + EnterCriticalSection(&proto->csLists); + i = (fromOffset>=0) ? fromOffset : 0; + for(; ilistsCount; i++) + if (proto->lists[i].list == list) { + LeaveCriticalSection(&proto->csLists); + return i; + } + LeaveCriticalSection(&proto->csLists); + return -1; +} + +JABBER_LIST_ITEM *JabberListGetItemPtr(TlenProtocol *proto, JABBER_LIST list, const char *jid) +{ + int i; + + EnterCriticalSection(&proto->csLists); + i = JabberListExist(proto, list, jid); + if (!i) { + LeaveCriticalSection(&proto->csLists); + return NULL; + } + i--; + LeaveCriticalSection(&proto->csLists); + return &(proto->lists[i]); +} + +JABBER_LIST_ITEM *JabberListFindItemPtrById2(TlenProtocol *proto, JABBER_LIST list, const char *id) +{ + + int i; + size_t len; + char *p; + + len = strlen(id); + + EnterCriticalSection(&proto->csLists); + for(i=0; ilistsCount; i++) { + if (proto->lists[i].list==list) { + p = proto->lists[i].id2; + if (p != NULL) { + if (!strncmp(p, id, len)) { + LeaveCriticalSection(&proto->csLists); + return &(proto->lists[i]); + } + } + } + } + LeaveCriticalSection(&proto->csLists); + return NULL; +} + +JABBER_LIST_ITEM *JabberListGetItemPtrFromIndex(TlenProtocol *proto, int index) +{ + EnterCriticalSection(&proto->csLists); + if (index>=0 && indexlistsCount) { + LeaveCriticalSection(&proto->csLists); + return &(proto->lists[index]); + } + LeaveCriticalSection(&proto->csLists); + return NULL; +} + diff --git a/plugins/!NotAdopted/Tlen/jabber_list.h b/plugins/!NotAdopted/Tlen/jabber_list.h new file mode 100644 index 0000000000..116440a6a1 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/jabber_list.h @@ -0,0 +1,90 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" + +#ifndef _JABBER_LIST_H_ +#define _JABBER_LIST_H_ + +typedef struct JABBER_LIST_ITEM_STRUCT { + JABBER_LIST list; + char *jid; + char *id2; + + // LIST_ROSTER + // jid = jid of the contact + char *nick; + int status; // Main status, currently useful for transport where no resource information is kept. + // On normal contact, this is the same status as shown on contact list. + JABBER_SUBSCRIPTION subscription; + char *statusMessage; // Status message when the update is to JID with no resource specified (e.g. transport user) + char *software; + char *version; + char *system; + char *group; + char *protocolVersion; + int avatarFormat; + char *avatarHash; + BOOL newAvatarDownloading; + BOOL versionRequested; + BOOL infoRequested; + int idMsgAckPending; + char *messageEventIdStr; + BOOL wantComposingEvent; + BOOL isTyping; + + // LIST_ROOM + // jid = room JID + // char *name; // room name + //char *type; // room type + + // LIST_CHATROOM + // jid = room JID + // char *nick; // my nick in this chat room (SPECIAL: in UTF8) + // JABBER_RESOURCE_STATUS *resource; // participant nicks in this room + char *roomName; + + // LIST_FILE + struct TLEN_FILE_TRANSFER_STRUCT *ft; +} JABBER_LIST_ITEM; + + +void JabberListInit(TlenProtocol *proto); +void JabberListUninit(TlenProtocol *proto); +void JabberListWipe(TlenProtocol *proto); +void JabberListWipeSpecial(TlenProtocol *proto); +int JabberListExist(TlenProtocol *proto, JABBER_LIST list, const char *jid); +JABBER_LIST_ITEM *JabberListAdd(TlenProtocol *proto, JABBER_LIST list, const char *jid); +void JabberListRemove(TlenProtocol *proto, JABBER_LIST list, const char *jid); +void JabberListRemoveList(TlenProtocol *proto, JABBER_LIST list); +void JabberListRemoveByIndex(TlenProtocol *proto, int index); +int JabberListFindNext(TlenProtocol *proto, JABBER_LIST list, int fromOffset); +JABBER_LIST_ITEM *JabberListGetItemPtr(TlenProtocol *proto, JABBER_LIST list, const char *jid); +JABBER_LIST_ITEM *JabberListGetItemPtrFromIndex(TlenProtocol *proto, int index); +JABBER_LIST_ITEM *JabberListFindItemPtrById2(TlenProtocol *proto, JABBER_LIST list, const char *id); + +void JabberListAddResource(TlenProtocol *proto, JABBER_LIST list, const char *jid, int status, const char *statusMessage); +void JabberListRemoveResource(TlenProtocol *proto, JABBER_LIST list, const char *jid); + +#endif + diff --git a/plugins/!NotAdopted/Tlen/jabber_misc.c b/plugins/!NotAdopted/Tlen/jabber_misc.c new file mode 100644 index 0000000000..33ddf80f1e --- /dev/null +++ b/plugins/!NotAdopted/Tlen/jabber_misc.c @@ -0,0 +1,219 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" +#include "jabber_list.h" + +void JabberDBAddEvent(TlenProtocol *proto, HANDLE hContact, int eventType, DWORD flags, PBYTE pBlob, DWORD cbBlob) +{ + DBEVENTINFO dbei = {0}; + dbei.cbSize = sizeof(DBEVENTINFO); + dbei.szModule = proto->iface.m_szModuleName; + dbei.timestamp = (DWORD) time(NULL); + dbei.flags = flags; + dbei.eventType = eventType; + dbei.cbBlob = cbBlob; + dbei.pBlob = pBlob; + CallService(MS_DB_EVENT_ADD, (WPARAM) hContact, (LPARAM) &dbei); +} +void JabberDBAddAuthRequest(TlenProtocol *proto, char *jid, char *nick) +{ + char *s; + PBYTE pCurBlob; + PBYTE pBlob; + DWORD cbBlob; + HANDLE hContact; + + if ((hContact=JabberHContactFromJID(proto, jid)) == NULL) { + hContact = (HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0); + CallService(MS_PROTO_ADDTOCONTACT, (WPARAM) hContact, (LPARAM) proto->iface.m_szModuleName); + // strip resource if present + s = JabberLoginFromJID(jid); + _strlwr(s); + DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "jid", s); + mir_free(s); + } + else { + DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "Hidden"); + } + DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "Nick", nick); + JabberLog(proto, "auth request: %s, %s", jid, nick); + //blob is: uin(DWORD), hContact(HANDLE), nick(ASCIIZ), first(ASCIIZ), last(ASCIIZ), email(ASCIIZ), reason(ASCIIZ) + //blob is: 0(DWORD), hContact(HANDLE), nick(ASCIIZ), ""(ASCIIZ), ""(ASCIIZ), email(ASCIIZ), ""(ASCIIZ) + cbBlob = sizeof(DWORD) + sizeof(HANDLE) + (int)strlen(nick) + (int)strlen(jid) + 5; + pBlob = pCurBlob = (PBYTE) mir_alloc(cbBlob); + *((PDWORD) pCurBlob) = 0; pCurBlob += sizeof(DWORD); + *((PHANDLE) pCurBlob) = hContact; pCurBlob += sizeof(HANDLE); + strcpy((char *) pCurBlob, nick); pCurBlob += strlen(nick)+1; + *pCurBlob = '\0'; pCurBlob++; //firstName + *pCurBlob = '\0'; pCurBlob++; //lastName + strcpy((char *) pCurBlob, jid); pCurBlob += strlen(jid)+1; + *pCurBlob = '\0'; //reason + JabberDBAddEvent(proto, NULL, EVENTTYPE_AUTHREQUEST, 0, pBlob, cbBlob); +} + +char *JabberJIDFromHContact(TlenProtocol *proto, HANDLE hContact) +{ + char *p = NULL; + DBVARIANT dbv; + if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { + p = mir_strdup(dbv.pszVal); + DBFreeVariant(&dbv); + } + return p; +} + + +HANDLE JabberHContactFromJID(TlenProtocol *proto, const char *jid) +{ + HANDLE hContact, hContactMatched; + DBVARIANT dbv; + char *szProto; + char *p; + if (jid == NULL) return (HANDLE) NULL; + hContactMatched = NULL; + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact != NULL) { + szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if (szProto!=NULL && !strcmp(proto->iface.m_szModuleName, szProto)) { + if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { + if ((p=dbv.pszVal) != NULL) { + if (!stricmp(p, jid)) { // exact match (node@domain/resource) + hContactMatched = hContact; + DBFreeVariant(&dbv); + break; + } + } + DBFreeVariant(&dbv); + } + } + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); + } + if (hContactMatched != NULL) { + return hContactMatched; + } + return NULL; +} + +HANDLE JabberDBCreateContact(TlenProtocol *proto, char *jid, char *nick, BOOL temporary) +{ + HANDLE hContact; + if (jid==NULL || jid[0]=='\0') + return NULL; + + if ((hContact=JabberHContactFromJID(proto, jid)) == NULL) { + hContact = (HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0); + CallService(MS_PROTO_ADDTOCONTACT, (WPARAM) hContact, (LPARAM) proto->iface.m_szModuleName); + DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "jid", jid); + if (nick!=NULL && nick[0]!='\0') + DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "Nick", nick); + if (temporary) + DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1); + } + return hContact; +} + +static void JabberContactListCreateClistGroup(char *groupName) +{ + char str[33], newName[128]; + int i; + DBVARIANT dbv; + char *name; + + for (i=0;;i++) { + itoa(i, str, 10); + if (DBGetContactSetting(NULL, "CListGroups", str, &dbv)) + break; + name = dbv.pszVal; + if (name[0]!='\0' && !strcmp(name+1, groupName)) { + // Already exist, no need to create + DBFreeVariant(&dbv); + return; + } + DBFreeVariant(&dbv); + } + + // Create new group with id = i (str is the text representation of i) + newName[0] = 1 | GROUPF_EXPANDED; + strncpy(newName+1, groupName, sizeof(newName)-1); + newName[sizeof(newName)-1] = '\0'; + DBWriteContactSettingString(NULL, "CListGroups", str, newName); + CallService(MS_CLUI_GROUPADDED, i+1, 0); +} + +void JabberContactListCreateGroup(char *groupName) +{ + char name[128]; + char *p; + + if (groupName==NULL || groupName[0]=='\0' || groupName[0]=='\\') return; + + strncpy(name, groupName, sizeof(name)); + name[sizeof(name)-1] = '\0'; + for (p=name; *p!='\0'; p++) { + if (*p == '\\') { + *p = '\0'; + JabberContactListCreateClistGroup(name); + *p = '\\'; + } + } + JabberContactListCreateClistGroup(name); +} + + +struct FORK_ARG { + HANDLE hEvent; + void (__cdecl *threadcode)(void*); + void *arg; +}; + +static void __cdecl forkthread_r(struct FORK_ARG *fa) +{ + void (*callercode)(void*) = fa->threadcode; + void *arg = fa->arg; + CallService(MS_SYSTEM_THREAD_PUSH, 0, 0); + SetEvent(fa->hEvent); + callercode(arg); + CallService(MS_SYSTEM_THREAD_POP, 0, 0); + return; +} + +unsigned long JabberForkThread( + void (__cdecl *threadcode)(void*), + unsigned long stacksize, + void *arg +) +{ + unsigned long rc; + struct FORK_ARG fa; + + fa.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + fa.threadcode = threadcode; + fa.arg = arg; + rc = _beginthread((void (__cdecl *)(void*))forkthread_r, stacksize, &fa); + if ((unsigned long) -1L != rc) { + WaitForSingleObject(fa.hEvent, INFINITE); + } + CloseHandle(fa.hEvent); + return rc; +} diff --git a/plugins/!NotAdopted/Tlen/jabber_opt.c b/plugins/!NotAdopted/Tlen/jabber_opt.c new file mode 100644 index 0000000000..3ef45e4289 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/jabber_opt.c @@ -0,0 +1,708 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" +#include "jabber_list.h" +#include "tlen_voice.h" +#include +#include "resource.h" + +static INT_PTR CALLBACK TlenBasicOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK TlenVoiceOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK TlenAdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK TlenPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +typedef struct TabDefStruct { + DLGPROC dlgProc; + DWORD dlgId; + TCHAR *tabName; +} TabDef; + +static TabDef tabPages[] = { + {TlenBasicOptDlgProc, IDD_OPTIONS_BASIC, _T("General")}, + {TlenVoiceOptDlgProc, IDD_OPTIONS_VOICE, _T("Voice Chats")}, + {TlenAdvOptDlgProc, IDD_OPTIONS_ADVANCED, _T("Advanced")}, + {TlenPopupsDlgProc, IDD_OPTIONS_POPUPS, _T("Notifications")} + }; + +void TlenLoadOptions(TlenProtocol *proto) +{ + proto->tlenOptions.savePassword = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "SavePassword", TRUE); + proto->tlenOptions.useEncryption = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "UseEncryption", TRUE); + proto->tlenOptions.reconnect = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "Reconnect", TRUE); + proto->tlenOptions.alertPolicy = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "AlertPolicy", TLEN_ALERTS_IGNORE_NIR); + proto->tlenOptions.rosterSync = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "RosterSync", FALSE); + proto->tlenOptions.offlineAsInvisible = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "OfflineAsInvisible", FALSE); + proto->tlenOptions.leaveOfflineMessage = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "LeaveOfflineMessage", TRUE); + proto->tlenOptions.offlineMessageOption = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "OfflineMessageOption", 0); + proto->tlenOptions.ignoreAdvertisements = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "IgnoreAdvertisements", TRUE); + proto->tlenOptions.groupChatPolicy = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "GroupChatPolicy", TLEN_MUC_ASK); + proto->tlenOptions.voiceChatPolicy = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "VoiceChatPolicy", TLEN_MUC_ASK); + proto->tlenOptions.imagePolicy = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "ImagePolicy",TLEN_IMAGES_IGNORE_NIR); + proto->tlenOptions.enableAvatars = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "EnableAvatars", TRUE); + proto->tlenOptions.enableVersion = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "EnableVersion", TRUE); + proto->tlenOptions.useNudge = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "UseNudge", FALSE); + proto->tlenOptions.logAlerts = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "LogAlerts", TRUE); + proto->tlenOptions.sendKeepAlive = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "KeepAlive", TRUE); + proto->tlenOptions.useNewP2P = TRUE; +} + +static int changed = 0; + +static void ApplyChanges(TlenProtocol *proto, int i) { + changed &= ~i; + if (changed == 0) { + TlenLoadOptions(proto); + } +} + +static void MarkChanges(int i, HWND hWnd) { + SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0); + changed |= i; +} + + +int TlenOptionsInit(TlenProtocol *proto, WPARAM wParam, LPARAM lParam) +{ + int i; + OPTIONSDIALOGPAGE odp = { 0 }; + odp.cbSize = sizeof(odp); + odp.hInstance = hInst; + odp.ptszGroup = TranslateT("Network"); + odp.ptszTitle = proto->iface.m_tszUserName; + odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR; + odp.dwInitParam = (LPARAM)proto; + for (i = 0; i < SIZEOF(tabPages); i++) { + odp.pszTemplate = MAKEINTRESOURCEA(tabPages[i].dlgId); + odp.pfnDlgProc = tabPages[i].dlgProc; + odp.ptszTab = tabPages[i].tabName; + CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) & odp); + } +/* + if (ServiceExists(MS_POPUP_ADDPOPUP)) { + ZeroMemory(&odp,sizeof(odp)); + odp.cbSize = sizeof(odp); + odp.position = 100000000; + odp.hInstance = hInst; + odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR; + odp.ptszGroup = TranslateT("PopUps"); + odp.ptszTitle = proto->iface.m_tszUserName; + odp.dwInitParam = (LPARAM)proto; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS_POPUPS); + odp.pfnDlgProc = TlenPopupsDlgProc; + CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp); + } + */ + return 0; +} + +static LRESULT CALLBACK JabberValidateUsernameWndProc(HWND hwndEdit, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WNDPROC oldProc = (WNDPROC) GetWindowLongPtr(hwndEdit, GWLP_USERDATA); + + switch (msg) { + case WM_CHAR: + if (strchr("\"&'/:<>@", wParam&0xff) != NULL) + return 0; + break; + } + return CallWindowProc(oldProc, hwndEdit, msg, wParam, lParam); +} + +INT_PTR CALLBACK TlenAccMgrUIDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char text[256]; + WNDPROC oldProc; + + TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + { + DBVARIANT dbv; + proto = (TlenProtocol *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); + TranslateDialogDefault(hwndDlg); + if (!DBGetContactSettingTString(NULL, proto->iface.m_szModuleName, "LoginName", &dbv)) { + SetDlgItemText(hwndDlg, IDC_EDIT_USERNAME, dbv.ptszVal); + DBFreeVariant(&dbv); + } + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "Password", &dbv)) { + CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); + SetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, dbv.pszVal); + DBFreeVariant(&dbv); + } + CheckDlgButton(hwndDlg, IDC_SAVEPASSWORD, DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "SavePassword", TRUE)); + + oldProc = (WNDPROC) GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_WNDPROC); + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_USERDATA, (LONG_PTR) oldProc); + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_WNDPROC, (LONG_PTR) JabberValidateUsernameWndProc); + return TRUE; + } + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_EDIT_USERNAME: + case IDC_EDIT_PASSWORD: + if ((HWND)lParam==GetFocus() && HIWORD(wParam)==EN_CHANGE) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_SAVEPASSWORD: + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_REGISTERACCOUNT: + CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) TLEN_REGISTER); + break; + } + break; + case WM_NOTIFY: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: + { + BOOL reconnectRequired = FALSE; + DBVARIANT dbv; + + GetDlgItemTextA(hwndDlg, IDC_EDIT_USERNAME, text, sizeof(text)); + if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginName", &dbv) || strcmp(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) DBFreeVariant(&dbv); + DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "LoginName", strlwr(text)); + + if (IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)) { + GetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, text, sizeof(text)); + CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(text), (LPARAM) text); + if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "Password", &dbv) || strcmp(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) DBFreeVariant(&dbv); + DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "Password", text); + } + else + DBDeleteContactSetting(NULL, proto->iface.m_szModuleName, "Password"); + + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "SavePassword", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)); + if (reconnectRequired && proto->isConnected) + MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); + TlenLoadOptions(proto); + return TRUE; + } + } + break; + } + return FALSE; +} + +static INT_PTR CALLBACK TlenBasicOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char text[256]; + WNDPROC oldProc; + + TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + { + DBVARIANT dbv; + proto = (TlenProtocol *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); + TranslateDialogDefault(hwndDlg); + if (!DBGetContactSettingTString(NULL, proto->iface.m_szModuleName, "LoginName", &dbv)) { + SetDlgItemText(hwndDlg, IDC_EDIT_USERNAME, dbv.ptszVal); + DBFreeVariant(&dbv); + } + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "Password", &dbv)) { + CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); + SetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, dbv.pszVal); + DBFreeVariant(&dbv); + } + CheckDlgButton(hwndDlg, IDC_SAVEPASSWORD, DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "SavePassword", TRUE)); + + CheckDlgButton(hwndDlg, IDC_RECONNECT, proto->tlenOptions.reconnect); + CheckDlgButton(hwndDlg, IDC_ROSTER_SYNC, proto->tlenOptions.rosterSync); + CheckDlgButton(hwndDlg, IDC_SHOW_OFFLINE, proto->tlenOptions.offlineAsInvisible); + CheckDlgButton(hwndDlg, IDC_OFFLINE_MESSAGE, proto->tlenOptions.leaveOfflineMessage); + CheckDlgButton(hwndDlg, IDC_IGNORE_ADVERTISEMENTS, proto->tlenOptions.ignoreAdvertisements); + CheckDlgButton(hwndDlg, IDC_AVATARS, proto->tlenOptions.enableAvatars); + CheckDlgButton(hwndDlg, IDC_VERSIONINFO, proto->tlenOptions.enableVersion); + CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, proto->tlenOptions.useNudge); + CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, proto->tlenOptions.logAlerts); + + SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all alerts")); + SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore alerts from unauthorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all alerts")); + SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_SETCURSEL, proto->tlenOptions.alertPolicy, 0); + + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Always ask me")); + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept invitations from authorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all invitations")); + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore invitations from unauthorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all invitation")); + SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_SETCURSEL, proto->tlenOptions.groupChatPolicy, 0); + + SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all images")); + SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore images from unauthorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all images")); + SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_SETCURSEL, proto->tlenOptions.imagePolicy, 0); + + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("")); + //SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("")); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("Online")); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("Away")); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("NA")); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("DND")); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("Free for chat")); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_ADDSTRING, 0, (LPARAM)TranslateT("Invisible")); + SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_SETCURSEL, proto->tlenOptions.offlineMessageOption, 0); + + oldProc = (WNDPROC) GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_WNDPROC); + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_USERDATA, (LONG_PTR) oldProc); + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT_USERNAME), GWLP_WNDPROC, (LONG_PTR) JabberValidateUsernameWndProc); + return TRUE; + } + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_EDIT_USERNAME: + case IDC_EDIT_PASSWORD: + if ((HWND)lParam==GetFocus() && HIWORD(wParam)==EN_CHANGE) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + // Fall through + case IDC_SAVEPASSWORD: + case IDC_RECONNECT: + case IDC_ROSTER_SYNC: + case IDC_IGNORE_ADVERTISEMENTS: + case IDC_SHOW_OFFLINE: + case IDC_OFFLINE_MESSAGE: + MarkChanges(1, hwndDlg); + break; + case IDC_LOG_ALERTS: + CheckDlgButton(hwndDlg, IDC_NUDGE_SUPPORT, BST_UNCHECKED); + MarkChanges(1, hwndDlg); + break; + case IDC_NUDGE_SUPPORT: + CheckDlgButton(hwndDlg, IDC_LOG_ALERTS, BST_UNCHECKED); + MarkChanges(1, hwndDlg); + break; + case IDC_REGISTERACCOUNT: + CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) TLEN_REGISTER); + break; + case IDC_OFFLINE_MESSAGE_OPTION: + case IDC_ALERT_POLICY: + case IDC_MUC_POLICY: + if (HIWORD(wParam) == CBN_SELCHANGE) + MarkChanges(1, hwndDlg); + break; + default: + MarkChanges(1, hwndDlg); + break; + } + break; + case WM_NOTIFY: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: + { + BOOL reconnectRequired = FALSE; + DBVARIANT dbv; + + GetDlgItemTextA(hwndDlg, IDC_EDIT_USERNAME, text, sizeof(text)); + if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginName", &dbv) || strcmp(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) DBFreeVariant(&dbv); + DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "LoginName", strlwr(text)); + + if (IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)) { + GetDlgItemTextA(hwndDlg, IDC_EDIT_PASSWORD, text, sizeof(text)); + CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(text), (LPARAM) text); + if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "Password", &dbv) || strcmp(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) DBFreeVariant(&dbv); + DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "Password", text); + } + else + DBDeleteContactSetting(NULL, proto->iface.m_szModuleName, "Password"); + + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "SavePassword", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SAVEPASSWORD)); + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "Reconnect", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_RECONNECT)); + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "RosterSync", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ROSTER_SYNC)); + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "OfflineAsInvisible", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_SHOW_OFFLINE)); + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "IgnoreAdvertisements", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_IGNORE_ADVERTISEMENTS)); + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "LeaveOfflineMessage", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_OFFLINE_MESSAGE)); + DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "OfflineMessageOption", (WORD) SendDlgItemMessage(hwndDlg, IDC_OFFLINE_MESSAGE_OPTION, CB_GETCURSEL, 0, 0)); + DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "AlertPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_ALERT_POLICY, CB_GETCURSEL, 0, 0)); + DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "GroupChatPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_MUC_POLICY, CB_GETCURSEL, 0, 0)); + DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "ImagePolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_IMAGE_POLICY, CB_GETCURSEL, 0, 0)); + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "EnableAvatars", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_AVATARS)); + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "EnableVersion", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VERSIONINFO)); + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "UseNudge", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_NUDGE_SUPPORT)); + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "LogAlerts", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_LOG_ALERTS)); + if (reconnectRequired && proto->isConnected) + MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); + ApplyChanges(proto, 1); + return TRUE; + } + } + break; + } + return FALSE; +} + +static INT_PTR CALLBACK TlenVoiceOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + { + proto = (TlenProtocol *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Always ask me")); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept invitations from authorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Accept all invitations")); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore invitations from unauthorized contacts")); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_ADDSTRING, 0, (LPARAM)TranslateT("Ignore all invitation")); + SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_SETCURSEL, proto->tlenOptions.voiceChatPolicy, 0); + TlenVoiceBuildInDeviceList(proto, GetDlgItem(hwndDlg, IDC_VOICE_DEVICE_IN)); + TlenVoiceBuildOutDeviceList(proto, GetDlgItem(hwndDlg, IDC_VOICE_DEVICE_OUT)); + return TRUE; + } + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_VOICE_POLICY: + case IDC_VOICE_DEVICE_IN: + case IDC_VOICE_DEVICE_OUT: + if (HIWORD(wParam) == CBN_SELCHANGE) + MarkChanges(2, hwndDlg); + break; + } + break; + case WM_NOTIFY: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: + { + DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "VoiceChatPolicy", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_POLICY, CB_GETCURSEL, 0, 0)); + DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "VoiceDeviceIn", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_DEVICE_IN, CB_GETCURSEL, 0, 0)); + DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "VoiceDeviceOut", (WORD) SendDlgItemMessage(hwndDlg, IDC_VOICE_DEVICE_OUT, CB_GETCURSEL, 0, 0)); + ApplyChanges(proto, 2); + return TRUE; + } + } + break; + } + + return FALSE; +} + +static INT_PTR CALLBACK TlenAdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char text[256]; + BOOL bChecked; + TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + + switch (msg) { + case WM_INITDIALOG: + { + DBVARIANT dbv; + proto = (TlenProtocol *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); + TranslateDialogDefault(hwndDlg); + if (!DBGetContactSettingTString(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { + SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, dbv.ptszVal); + DBFreeVariant(&dbv); + } else { + SetDlgItemText(hwndDlg, IDC_EDIT_LOGIN_SERVER, _T("tlen.pl")); + } + + EnableWindow(GetDlgItem(hwndDlg, IDC_HOST), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_HOSTPORT), TRUE); + + if (!DBGetContactSettingTString(NULL, proto->iface.m_szModuleName, "ManualHost", &dbv)) { + SetDlgItemText(hwndDlg, IDC_HOST, dbv.ptszVal); + DBFreeVariant(&dbv); + } else + SetDlgItemText(hwndDlg, IDC_HOST, _T("s1.tlen.pl")); + SetDlgItemInt(hwndDlg, IDC_HOSTPORT, DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT), FALSE); + + CheckDlgButton(hwndDlg, IDC_KEEPALIVE, DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "KeepAlive", TRUE)); + + CheckDlgButton(hwndDlg, IDC_USE_SSL, DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "UseEncryption", TRUE)); + + CheckDlgButton(hwndDlg, IDC_VISIBILITY_SUPPORT, DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "VisibilitySupport", FALSE)); + // File transfer options + bChecked = FALSE; + if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "UseFileProxy", FALSE) == TRUE) { + bChecked = TRUE; + CheckDlgButton(hwndDlg, IDC_FILE_USE_PROXY, TRUE); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked); + if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "FileProxyAuth", FALSE) == TRUE) { + CheckDlgButton(hwndDlg, IDC_FILE_PROXY_USE_AUTH, TRUE); + } else { + bChecked = FALSE; + } + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked); + + SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateT("Forwarding")); + SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateT("SOCKS4")); + SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_ADDSTRING, 0, (LPARAM)TranslateT("SOCKS5")); + SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_SETCURSEL, DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "FileProxyType", 0), 0); + if (!DBGetContactSettingTString(NULL, proto->iface.m_szModuleName, "FileProxyHost", &dbv)) { + SetDlgItemText(hwndDlg, IDC_FILE_PROXY_HOST, dbv.ptszVal); + DBFreeVariant(&dbv); + } + SetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "FileProxyPort", 0), FALSE); + if (!DBGetContactSettingTString(NULL, proto->iface.m_szModuleName, "FileProxyUsername", &dbv)) { + SetDlgItemText(hwndDlg, IDC_FILE_PROXY_USER, dbv.ptszVal); + DBFreeVariant(&dbv); + } + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "FileProxyPassword", &dbv)) { + CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); + SetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, dbv.pszVal); + DBFreeVariant(&dbv); + } + return TRUE; + } + case WM_COMMAND: + { + switch (LOWORD(wParam)) { + case IDC_FILE_PROXY_TYPE: + if (HIWORD(wParam) == CBN_SELCHANGE) + MarkChanges(4, hwndDlg); + break; + case IDC_EDIT_LOGIN_SERVER: + case IDC_HOST: + case IDC_HOSTPORT: + case IDC_FILE_PROXY_HOST: + case IDC_FILE_PROXY_PORT: + case IDC_FILE_PROXY_USER: + case IDC_FILE_PROXY_PASSWORD: + if ((HWND)lParam==GetFocus() && HIWORD(wParam)==EN_CHANGE) + MarkChanges(4, hwndDlg); + break; + case IDC_FILE_USE_PROXY: + bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_TYPE), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_HOST), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PORT), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USE_AUTH), bChecked); + case IDC_FILE_PROXY_USE_AUTH: + bChecked = IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH) & IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_USER), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD_LABEL), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_FILE_PROXY_PASSWORD), bChecked); + MarkChanges(4, hwndDlg); + break; + case IDC_KEEPALIVE: + case IDC_VISIBILITY_SUPPORT: + case IDC_USE_SSL: + MarkChanges(4, hwndDlg); + break; + } + } + break; + case WM_NOTIFY: + { + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: + { + WORD port; + BOOL useEncryption; + BOOL reconnectRequired = FALSE; + DBVARIANT dbv; + GetDlgItemTextA(hwndDlg, IDC_EDIT_LOGIN_SERVER, text, sizeof(text)); + if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv) || strcmp(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) DBFreeVariant(&dbv); + DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "LoginServer", strlwr(text)); + + GetDlgItemTextA(hwndDlg, IDC_HOST, text, sizeof(text)); + if (DBGetContactSetting(NULL, proto->iface.m_szModuleName, "ManualHost", &dbv) || strcmp(text, dbv.pszVal)) + reconnectRequired = TRUE; + if (dbv.pszVal != NULL) DBFreeVariant(&dbv); + DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "ManualHost", text); + + port = (WORD) GetDlgItemInt(hwndDlg, IDC_HOSTPORT, NULL, FALSE); + if (DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT) != port) + reconnectRequired = TRUE; + DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "ManualPort", port); + + proto->tlenOptions.sendKeepAlive = IsDlgButtonChecked(hwndDlg, IDC_KEEPALIVE); + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "KeepAlive", (BYTE) proto->tlenOptions.sendKeepAlive); + + useEncryption = IsDlgButtonChecked(hwndDlg, IDC_USE_SSL); + if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "UseEncryption", TRUE) != useEncryption) + reconnectRequired = TRUE; + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "UseEncryption", (BYTE) useEncryption); + + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "VisibilitySupport", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_VISIBILITY_SUPPORT)); + // File transfer options + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "UseFileProxy", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_USE_PROXY)); + DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "FileProxyType", (WORD) SendDlgItemMessage(hwndDlg, IDC_FILE_PROXY_TYPE, CB_GETCURSEL, 0, 0)); + GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_HOST, text, sizeof(text)); + DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "FileProxyHost", text); + DBWriteContactSettingWord(NULL, proto->iface.m_szModuleName, "FileProxyPort", (WORD) GetDlgItemInt(hwndDlg, IDC_FILE_PROXY_PORT, NULL, FALSE)); + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "FileProxyAuth", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_FILE_PROXY_USE_AUTH)); + GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_USER, text, sizeof(text)); + DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "FileProxyUsername", text); + GetDlgItemTextA(hwndDlg, IDC_FILE_PROXY_PASSWORD, text, sizeof(text)); + CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(text), (LPARAM) text); + DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "FileProxyPassword", text); + if (reconnectRequired && proto->isConnected) + MessageBox(hwndDlg, TranslateT("These changes will take effect the next time you connect to the Tlen network."), TranslateT("Tlen Protocol Option"), MB_OK|MB_SETFOREGROUND); + ApplyChanges(proto, 4); + return TRUE; + } + } + } + break; + case WM_DESTROY: + break; + } + + return FALSE; +} + +#define POPUP_DEFAULT_COLORBKG 0xDCBDA5 +#define POPUP_DEFAULT_COLORTXT 0x000000 + +static void MailPopupPreview(DWORD colorBack, DWORD colorText, char *title, char *emailInfo, int delay) +{ + POPUPDATAEX ppd; + char * lpzContactName; + char * lpzText; + HICON hIcon; + lpzContactName = title; + lpzText = emailInfo; + ZeroMemory(&ppd, sizeof(ppd)); + ppd.lchContact = NULL; + hIcon = GetIcolibIcon(IDI_MAIL); + ppd.lchIcon = CopyIcon(hIcon); + ReleaseIcolibIcon(hIcon); + strcpy(ppd.lpzContactName, lpzContactName); + strcpy(ppd.lpzText, lpzText); + ppd.colorBack = colorBack; + ppd.colorText = colorText; + ppd.PluginWindowProc = NULL; + ppd.PluginData=NULL; + if ( ServiceExists( MS_POPUP_ADDPOPUPEX )) { + ppd.iSeconds = delay; + CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0); + + } + else if ( ServiceExists( MS_POPUP_ADDPOPUP )) { + CallService(MS_POPUP_ADDPOPUP, (WPARAM)&ppd, 0); + } +} + +static INT_PTR CALLBACK TlenPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + { + BYTE delayMode; + proto = (TlenProtocol *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); + TranslateDialogDefault(hwndDlg); + CheckDlgButton(hwndDlg, IDC_ENABLEPOPUP, DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "MailPopupEnabled", TRUE)); + SendDlgItemMessage(hwndDlg, IDC_COLORBKG, CPM_SETCOLOUR, 0, DBGetContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupBack", POPUP_DEFAULT_COLORBKG)); + SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETCOLOUR, 0, DBGetContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupText", POPUP_DEFAULT_COLORTXT)); + SetDlgItemInt(hwndDlg, IDC_DELAY, DBGetContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupDelay", 4), FALSE); + delayMode = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "MailPopupDelayMode", 0); + if (delayMode==1) { + CheckDlgButton(hwndDlg, IDC_DELAY_CUSTOM, TRUE); + } else if (delayMode==2) { + CheckDlgButton(hwndDlg, IDC_DELAY_PERMANENT, TRUE); + } else { + CheckDlgButton(hwndDlg, IDC_DELAY_POPUP, TRUE); + } + return TRUE; + } + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_COLORTXT: + case IDC_COLORBKG: + case IDC_ENABLEPOPUP: + case IDC_DELAY: + case IDC_DELAY_POPUP: + case IDC_DELAY_CUSTOM: + case IDC_DELAY_PERMANENT: + MarkChanges(8, hwndDlg); + break; + case IDC_PREVIEW: + { + int delay; + char title[256]; + if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_POPUP)) { + delay=0; + } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) { + delay=-1; + } else { + delay=GetDlgItemInt(hwndDlg, IDC_DELAY, NULL, FALSE); + } + _snprintf(title, sizeof(title), Translate("%s mail"), proto->iface.m_szProtoName); + MailPopupPreview((DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0), + (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0), + title, + "From: test@test.test\nSubject: test", + delay); + } + + } + break; + + + case WM_NOTIFY: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: + { + BYTE delayMode; + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "MailPopupEnabled", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ENABLEPOPUP)); + DBWriteContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupBack", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0)); + DBWriteContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupText", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0)); + DBWriteContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupDelay", (DWORD) GetDlgItemInt(hwndDlg,IDC_DELAY, NULL, FALSE)); + delayMode=0; + if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_CUSTOM)) { + delayMode=1; + } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) { + delayMode=2; + + } + DBWriteContactSettingByte(NULL, proto->iface.m_szModuleName, "MailPopupDelayMode", delayMode); + ApplyChanges(proto, 8); + return TRUE; + } + } + break; + + } + return FALSE; +} + diff --git a/plugins/!NotAdopted/Tlen/jabber_svc.c b/plugins/!NotAdopted/Tlen/jabber_svc.c new file mode 100644 index 0000000000..ecc3b26bfb --- /dev/null +++ b/plugins/!NotAdopted/Tlen/jabber_svc.c @@ -0,0 +1,1300 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" +#include +#include +#include +#include +#include "resource.h" +#include "jabber_list.h" +#include "jabber_iq.h" +#include "tlen_p2p_old.h" +#include "tlen_avatar.h" +#include "tlen_file.h" + +extern int TlenOnModulesLoaded(void *ptr, WPARAM wParam, LPARAM lParam); +extern int TlenOptionsInit(void *ptr, WPARAM wParam, LPARAM lParam); +extern int TlenPreShutdown(void *ptr, WPARAM wParam, LPARAM lParam); +DWORD_PTR TlenGetCaps(PROTO_INTERFACE *ptr, int type, HANDLE hContact) +{ + if (type == PFLAGNUM_1) + return PF1_IM|PF1_AUTHREQ|PF1_SERVERCLIST|PF1_MODEMSG|PF1_BASICSEARCH|PF1_SEARCHBYEMAIL|PF1_EXTSEARCH|PF1_EXTSEARCHUI|PF1_SEARCHBYNAME|PF1_FILE;//|PF1_VISLIST|PF1_INVISLIST; + if (type == PFLAGNUM_2) + return PF2_ONLINE|PF2_INVISIBLE|PF2_SHORTAWAY|PF2_LONGAWAY|PF2_HEAVYDND|PF2_FREECHAT; + if (type == PFLAGNUM_3) + return PF2_ONLINE|PF2_INVISIBLE|PF2_SHORTAWAY|PF2_LONGAWAY|PF2_HEAVYDND|PF2_FREECHAT; + if (type == PFLAGNUM_4) + return PF4_FORCEAUTH|PF4_NOCUSTOMAUTH|PF4_SUPPORTTYPING|PF4_AVATARS|PF4_IMSENDOFFLINE|PF4_OFFLINEFILES; + if (type == PFLAG_UNIQUEIDTEXT) + return (DWORD_PTR) Translate("Tlen login"); + if (type == PFLAG_UNIQUEIDSETTING) + return (DWORD_PTR) "jid"; + return 0; +} + +INT_PTR TlenGetName(void *ptr, WPARAM wParam, LPARAM lParam) +{ + TlenProtocol *proto = (TlenProtocol *)ptr; + strncpy((char *) lParam, proto->iface.m_szProtoName, wParam); + return 0; +} + +HICON TlenGetIcon(PROTO_INTERFACE *ptr, int iconIndex) +{ + if ((iconIndex&0xffff) == PLI_PROTOCOL) { + HICON hIcon = GetIcolibIcon(IDI_TLEN); + HICON hIconCopy = CopyIcon(hIcon); + ReleaseIcolibIcon(hIcon); + return hIconCopy; + } + return (HICON) NULL; +} + +int TlenRunSearch(TlenProtocol *proto) { + int iqId = 0; + if (!proto->isOnline) return 0; + if (proto->searchQuery != NULL && proto->searchIndex < 10) { + iqId = proto->searchID; + JabberIqAdd(proto, iqId, IQ_PROC_GETSEARCH, JabberIqResultSearch); + if (proto->searchIndex == 0) { + JabberSend(proto, "%s", iqId, proto->searchQuery); + } else { + JabberSend(proto, "%s%d", iqId, proto->searchQuery, proto->searchIndex * TLEN_MAX_SEARCH_RESULTS_PER_PAGE); + } + proto->searchIndex ++; + } + return iqId; +} + +void TlenResetSearchQuery(TlenProtocol *proto) { + if (proto->searchQuery != NULL) { + mir_free(proto->searchQuery); + proto->searchQuery = NULL; + } + proto->searchQueryLen = 0; + proto->searchIndex = 0; + proto->searchID = JabberSerialNext(proto); +} + +HANDLE TlenBasicSearch(PROTO_INTERFACE *ptr, const char *id) +{ + char *jid; + int iqId = 0; + TlenProtocol *proto = (TlenProtocol *)ptr; + if (!proto->isOnline) return 0; + if (id == NULL) return 0; + if ((jid=JabberTextEncode(id)) != NULL) { + proto->searchJID = mir_strdup(id); + TlenResetSearchQuery(proto); + JabberStringAppend(&proto->searchQuery, &proto->searchQueryLen, "%s", jid); + iqId = TlenRunSearch(proto); + mir_free(jid); + } + return (HANDLE)iqId; +} + +HANDLE TlenSearchByEmail(PROTO_INTERFACE *ptr, const char* email) +{ + char *emailEnc; + int iqId = 0; + TlenProtocol *proto = (TlenProtocol *)ptr; + + if (!proto->isOnline) return 0; + if (email == NULL) return 0; + + if ((emailEnc=JabberTextEncode(email)) != NULL) { + TlenResetSearchQuery(proto); + JabberStringAppend(&proto->searchQuery, &proto->searchQueryLen, "%s", emailEnc); + iqId = TlenRunSearch(proto); + mir_free(emailEnc); + } + return (HANDLE)iqId; +} + +HANDLE TlenSearchByName(PROTO_INTERFACE *ptr, const char* nick, const char* firstName, const char* lastName) +{ + char *p; + int iqId = 0; + + TlenProtocol *proto = (TlenProtocol *)ptr; + if (!proto->isOnline) return 0; + + TlenResetSearchQuery(proto); + + if (nick != NULL && nick[0] != '\0') { + if ((p=JabberTextEncode(nick)) != NULL) { + JabberStringAppend(&proto->searchQuery, &proto->searchQueryLen, "%s", p); + mir_free(p); + } + } + if (firstName != NULL && firstName[0] != '\0') { + if ((p=JabberTextEncode(firstName)) != NULL) { + JabberStringAppend(&proto->searchQuery, &proto->searchQueryLen, "%s", p); + mir_free(p); + } + } + if (lastName != NULL && lastName[0] != '\0') { + if ((p=JabberTextEncode(lastName)) != NULL) { + JabberStringAppend(&proto->searchQuery, &proto->searchQueryLen, "%s", p); + mir_free(p); + } + } + + iqId = TlenRunSearch(proto); + return (HANDLE)iqId; +} + +HWND TlenCreateAdvSearchUI(PROTO_INTERFACE *ptr, HWND owner) +{ + return (HWND) CreateDialog(hInst, MAKEINTRESOURCE(IDD_ADVSEARCH), owner, TlenAdvSearchDlgProc); +} + +HWND TlenSearchAdvanced(PROTO_INTERFACE *ptr, HWND owner) +{ + int iqId; + TlenProtocol *proto = (TlenProtocol *)ptr; + if (!proto->isOnline) return 0; + + TlenResetSearchQuery(proto); + iqId = JabberSerialNext(proto); + if ((proto->searchQuery = TlenAdvSearchCreateQuery(owner, iqId)) != NULL) { + iqId = TlenRunSearch(proto); + } + return (HWND)iqId; +} + +static HANDLE AddToListByJID(TlenProtocol *proto, const char *newJid, DWORD flags) +{ + HANDLE hContact; + char *jid, *nick; + + if ((hContact=JabberHContactFromJID(proto, newJid)) == NULL) { + // not already there: add + jid = mir_strdup(newJid); _strlwr(jid); + hContact = (HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0); + CallService(MS_PROTO_ADDTOCONTACT, (WPARAM) hContact, (LPARAM) proto->iface.m_szModuleName); + DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "jid", jid); + if ((nick=JabberNickFromJID(newJid)) == NULL) + nick = mir_strdup(newJid); + DBWriteContactSettingString(hContact, "CList", "MyHandle", nick); + mir_free(nick); + mir_free(jid); + + // Note that by removing or disable the "NotOnList" will trigger + // the plugin to add a particular contact to the roster list. + // See DBSettingChanged hook at the bottom part of this source file. + // But the add module will delete "NotOnList". So we will not do it here. + // Also because we need "MyHandle" and "Group" info, which are set after + // PS_ADDTOLIST is called but before the add dialog issue deletion of + // "NotOnList". + // If temporary add, "NotOnList" won't be deleted, and that's expected. + DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1); + if (flags & PALF_TEMPORARY) + DBWriteContactSettingByte(hContact, "CList", "Hidden", 1); + } + else { + // already exist + // Set up a dummy "NotOnList" when adding permanently only + if (!(flags&PALF_TEMPORARY)) + DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1); + } + + return hContact; +} + +HANDLE TlenAddToList(PROTO_INTERFACE *ptr, int flags, PROTOSEARCHRESULT *psr) +{ + HANDLE hContact; + TlenProtocol *proto = (TlenProtocol *)ptr; + JABBER_SEARCH_RESULT *jsr = (JABBER_SEARCH_RESULT*)psr; + if (jsr->hdr.cbSize != sizeof(JABBER_SEARCH_RESULT)) + return (int) NULL; + hContact = AddToListByJID(proto, jsr->jid, flags); // wParam is flag e.g. PALF_TEMPORARY + return hContact; +} + +HANDLE TlenAddToListByEvent(PROTO_INTERFACE *ptr, int flags, int iContact, HANDLE hDbEvent) +{ + DBEVENTINFO dbei; + HANDLE hContact; + char *nick, *firstName, *lastName, *jid; + TlenProtocol *proto = (TlenProtocol *)ptr; + + ZeroMemory(&dbei, sizeof(dbei)); + dbei.cbSize = sizeof(dbei); + if ((dbei.cbBlob=CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0)) == (DWORD)(-1)) + return (int)(HANDLE) NULL; + if ((dbei.pBlob=(PBYTE) mir_alloc(dbei.cbBlob)) == NULL) + return (int)(HANDLE) NULL; + if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM) &dbei)) { + mir_free(dbei.pBlob); + return (int)(HANDLE) NULL; + } + if (strcmp(dbei.szModule, proto->iface.m_szModuleName)) { + mir_free(dbei.pBlob); + return (int)(HANDLE) NULL; + } + +/* + // EVENTTYPE_CONTACTS is when adding from when we receive contact list (not used in Jabber) + // EVENTTYPE_ADDED is when adding from when we receive "You are added" (also not used in Jabber) + // Jabber will only handle the case of EVENTTYPE_AUTHREQUEST + // EVENTTYPE_AUTHREQUEST is when adding from the authorization request dialog +*/ + + if (dbei.eventType != EVENTTYPE_AUTHREQUEST) { + mir_free(dbei.pBlob); + return (int)(HANDLE) NULL; + } + + nick = (char *) (dbei.pBlob + sizeof(DWORD) + sizeof(HANDLE)); + firstName = nick + strlen(nick) + 1; + lastName = firstName + strlen(firstName) + 1; + jid = lastName + strlen(lastName) + 1; + + hContact = (HANDLE) AddToListByJID(proto, jid, flags); + mir_free(dbei.pBlob); + + return hContact; +} + +int TlenAuthAllow(PROTO_INTERFACE *ptr, HANDLE hContact) +{ + DBEVENTINFO dbei; + char *nick, *firstName, *lastName, *jid; + TlenProtocol *proto = (TlenProtocol *)ptr; + + if (!proto->isOnline) + return 1; + + memset(&dbei, sizeof(dbei), 0); + dbei.cbSize = sizeof(dbei); + if ((dbei.cbBlob=CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hContact, 0)) == (DWORD)(-1)) + return 1; + if ((dbei.pBlob=(PBYTE) mir_alloc(dbei.cbBlob)) == NULL) + return 1; + if (CallService(MS_DB_EVENT_GET, (WPARAM)hContact, (LPARAM) &dbei)) { + mir_free(dbei.pBlob); + return 1; + } + if (dbei.eventType != EVENTTYPE_AUTHREQUEST) { + mir_free(dbei.pBlob); + return 1; + } + if (strcmp(dbei.szModule, proto->iface.m_szModuleName)) { + mir_free(dbei.pBlob); + return 1; + } + + nick = (char *) (dbei.pBlob + sizeof(DWORD) + sizeof(HANDLE)); + firstName = nick + strlen(nick) + 1; + lastName = firstName + strlen(firstName) + 1; + jid = lastName + strlen(lastName) + 1; + + JabberSend(proto, "", jid); + + // Automatically add this user to my roster if option is enabled + if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "AutoAdd", TRUE) == TRUE) { + HANDLE hContact; + JABBER_LIST_ITEM *item; + + if ((item=JabberListGetItemPtr(proto, LIST_ROSTER, jid))==NULL || (item->subscription!=SUB_BOTH && item->subscription!=SUB_TO)) { + JabberLog(proto, "Try adding contact automatically jid=%s", jid); + if ((hContact=AddToListByJID(proto, jid, 0)) != NULL) { + // Trigger actual add by removing the "NotOnList" added by AddToListByJID() + // See AddToListByJID() and JabberDbSettingChanged(). + DBDeleteContactSetting(hContact, "CList", "NotOnList"); + } + } + } + + mir_free(dbei.pBlob); + return 0; +} + +int TlenAuthDeny(PROTO_INTERFACE *ptr, HANDLE hContact, const TCHAR* szReason) +{ + DBEVENTINFO dbei; + char *nick, *firstName, *lastName, *jid; + TlenProtocol *proto = (TlenProtocol *)ptr; + + if (!proto->isOnline) + return 1; + + memset(&dbei, sizeof(dbei), 0); + dbei.cbSize = sizeof(dbei); + if ((dbei.cbBlob=CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hContact, 0)) == (DWORD)(-1)) + return 1; + if ((dbei.pBlob=(PBYTE) mir_alloc(dbei.cbBlob)) == NULL) + return 1; + if (CallService(MS_DB_EVENT_GET, (WPARAM)hContact, (LPARAM) &dbei)) { + mir_free(dbei.pBlob); + return 1; + } + if (dbei.eventType != EVENTTYPE_AUTHREQUEST) { + mir_free(dbei.pBlob); + return 1; + } + if (strcmp(dbei.szModule, proto->iface.m_szModuleName)) { + mir_free(dbei.pBlob); + return 1; + } + + nick = (char *) (dbei.pBlob + sizeof(DWORD) + sizeof(HANDLE)); + firstName = nick + strlen(nick) + 1; + lastName = firstName + strlen(firstName) + 1; + jid = lastName + strlen(lastName) + 1; + + JabberSend(proto, "", jid); + JabberSend(proto, "", jid); + mir_free(dbei.pBlob); + return 0; +} + +static void TlenConnect(TlenProtocol *proto, int initialStatus) +{ + if (!proto->isConnected) { + ThreadData *thread; + int oldStatus; + + thread = (ThreadData *) mir_alloc(sizeof(ThreadData)); + memset(thread, 0, sizeof(ThreadData)); + thread->proto = proto; + proto->iface.m_iDesiredStatus = initialStatus; + + oldStatus = proto->iface.m_iStatus; + proto->iface.m_iStatus = ID_STATUS_CONNECTING; + ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, proto->iface.m_iStatus); + thread->hThread = (HANDLE) JabberForkThread((void (__cdecl *)(void*))JabberServerThread, 0, thread); + } +} + +int TlenSetStatus(PROTO_INTERFACE *ptr, int iNewStatus) +{ + int oldStatus; + HANDLE s; + TlenProtocol *proto = (TlenProtocol *)ptr; + + proto->iface.m_iDesiredStatus = iNewStatus; + + if (iNewStatus == ID_STATUS_OFFLINE) { + if (proto->threadData) { + if (proto->isConnected) { + JabberSendPresence(proto, ID_STATUS_OFFLINE); + } + s = proto; + proto->threadData = NULL; + if (proto->isConnected) { + Sleep(200); +// JabberSend(s, ""); + // Force closing connection + proto->isConnected = FALSE; + proto->isOnline = FALSE; + Netlib_CloseHandle(s); + } + } + else { + if (proto->iface.m_iStatus != ID_STATUS_OFFLINE) { + oldStatus = proto->iface.m_iStatus; + proto->iface.m_iStatus = ID_STATUS_OFFLINE; + ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, proto->iface.m_iStatus); + } + } + } + else if (iNewStatus != proto->iface.m_iStatus) { + if (!proto->isConnected) + TlenConnect(proto, iNewStatus); + else { + // change status + oldStatus = proto->iface.m_iStatus; + // send presence update + JabberSendPresence(proto, iNewStatus); + ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, proto->iface.m_iStatus); + } + } + return 0; +} + +INT_PTR TlenGetStatus(void *ptr, WPARAM wParam, LPARAM lParam) +{ + TlenProtocol *proto = (TlenProtocol *)ptr; + return proto->iface.m_iStatus; +} + + +int TlenSetAwayMsg(PROTO_INTERFACE *ptr, int iStatus, const char* msg ) +{ + char **szMsg; + char *newModeMsg; + TlenProtocol *proto = (TlenProtocol *)ptr; + + JabberLog(proto, "SetAwayMsg called, wParam=%d lParam=%s", iStatus, msg); + + newModeMsg = JabberTextEncode(msg); + + EnterCriticalSection(&proto->modeMsgMutex); + + switch (iStatus) { + case ID_STATUS_ONLINE: + szMsg = &proto->modeMsgs.szOnline; + break; + case ID_STATUS_AWAY: + case ID_STATUS_ONTHEPHONE: + case ID_STATUS_OUTTOLUNCH: + szMsg = &proto->modeMsgs.szAway; + break; + case ID_STATUS_NA: + szMsg = &proto->modeMsgs.szNa; + break; + case ID_STATUS_DND: + case ID_STATUS_OCCUPIED: + szMsg = &proto->modeMsgs.szDnd; + break; + case ID_STATUS_FREECHAT: + szMsg = &proto->modeMsgs.szFreechat; + break; + case ID_STATUS_INVISIBLE: + szMsg = &proto->modeMsgs.szInvisible; + break; + default: + LeaveCriticalSection(&proto->modeMsgMutex); + return 1; + } + + if ((*szMsg==NULL && newModeMsg==NULL) || + (*szMsg!=NULL && newModeMsg!=NULL && !strcmp(*szMsg, newModeMsg))) { + // Message is the same, no update needed + if (newModeMsg != NULL) mir_free(newModeMsg); + } + else { + // Update with the new mode message + if (*szMsg != NULL) mir_free(*szMsg); + *szMsg = newModeMsg; + // Send a presence update if needed + if (iStatus == proto->iface.m_iStatus) { + JabberSendPresence(proto, proto->iface.m_iStatus); + } + } + + LeaveCriticalSection(&proto->modeMsgMutex); + return 0; +} + +int JabberGetInfo(PROTO_INTERFACE *ptr, HANDLE hContact, int infoType) +{ + DBVARIANT dbv; + int iqId; + char *nick, *pNick; + TlenProtocol *proto = (TlenProtocol *)ptr; + + if (!proto->isOnline) return 1; + if (hContact==NULL) { + iqId = JabberSerialNext(proto); + JabberIqAdd(proto, iqId, IQ_PROC_NONE, TlenIqResultVcard); + JabberSend(proto, "", iqId); + } else { + if (DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) return 1; + if ((nick=JabberNickFromJID(dbv.pszVal)) != NULL) { + if ((pNick=JabberTextEncode(nick)) != NULL) { + iqId = JabberSerialNext(proto); + JabberIqAdd(proto, iqId, IQ_PROC_NONE, TlenIqResultVcard); + JabberSend(proto, "%s", iqId, pNick); + mir_free(pNick); + } + mir_free(nick); + } + DBFreeVariant(&dbv); + } + return 0; +} + +int TlenSetApparentMode(PROTO_INTERFACE *ptr, HANDLE hContact, int mode) +{ + DBVARIANT dbv; + int oldMode; + char *jid; + TlenProtocol *proto = (TlenProtocol *)ptr; + + if (!proto->isOnline) return 0; + if (!DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "VisibilitySupport", FALSE)) return 0; + if (mode!=0 && mode!=ID_STATUS_ONLINE && mode!=ID_STATUS_OFFLINE) return 1; + oldMode = DBGetContactSettingWord(hContact, proto->iface.m_szModuleName, "ApparentMode", 0); + if ((int) mode == oldMode) return 1; + DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "ApparentMode", (WORD) mode); + if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { + jid = dbv.pszVal; + switch (mode) { + case ID_STATUS_ONLINE: + if (proto->iface.m_iStatus==ID_STATUS_INVISIBLE || oldMode==ID_STATUS_OFFLINE) + JabberSend(proto, "available", jid); + break; + case ID_STATUS_OFFLINE: + if (proto->iface.m_iStatus!=ID_STATUS_INVISIBLE || oldMode==ID_STATUS_ONLINE) + JabberSend(proto, "", jid); + break; + case 0: + if (oldMode==ID_STATUS_ONLINE && proto->iface.m_iStatus==ID_STATUS_INVISIBLE) + JabberSend(proto, "", jid); + else if (oldMode==ID_STATUS_OFFLINE && proto->iface.m_iStatus!=ID_STATUS_INVISIBLE) + JabberSend(proto, "available", jid); + break; + } + DBFreeVariant(&dbv); + } + return 0; +} + +typedef struct{ + TlenProtocol *proto; + HANDLE hContact; +} SENDACKTHREADDATA; + +static void __cdecl JabberSendMessageAckThread(void *ptr) +{ + SENDACKTHREADDATA *data = (SENDACKTHREADDATA *)ptr; + SleepEx(10, TRUE); + ProtoBroadcastAck(data->proto->iface.m_szModuleName, data->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE) 1, 0); + mir_free(data); +} + +static void __cdecl TlenSendMessageFailedThread(void *ptr) +{ + SENDACKTHREADDATA *data = (SENDACKTHREADDATA *)ptr; + SleepEx(10, TRUE); + ProtoBroadcastAck(data->proto->iface.m_szModuleName, data->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE) 2, 0); + mir_free(data); +} + +static void __cdecl TlenGetAwayMsgThread(void *ptr) +{ + DBVARIANT dbv; + JABBER_LIST_ITEM *item; + SENDACKTHREADDATA *data = (SENDACKTHREADDATA *)ptr; + if (!DBGetContactSetting(data->hContact, data->proto->iface.m_szModuleName, "jid", &dbv)) { + if ((item=JabberListGetItemPtr(data->proto, LIST_ROSTER, dbv.pszVal)) != NULL) { + DBFreeVariant(&dbv); + if (item->statusMessage != NULL) { + ProtoBroadcastAck(data->proto->iface.m_szModuleName, data->hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE) 1, (LPARAM) item->statusMessage); + return; + } + } + else { + DBFreeVariant(&dbv); + } + } + ProtoBroadcastAck(data->proto->iface.m_szModuleName, data->hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE) 1, (LPARAM) ""); + mir_free(data); +} + +INT_PTR TlenSendAlert(void *ptr, WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = ( HANDLE )wParam; + DBVARIANT dbv; + TlenProtocol *proto = (TlenProtocol *)ptr; + if (proto->isOnline && !DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { + JabberSend(proto, "", dbv.pszVal); + + DBFreeVariant(&dbv); + } + return 0; +} + + +int TlenSendMessage(PROTO_INTERFACE *ptr, HANDLE hContact, int flags, const char* msg) +{ + DBVARIANT dbv; + char *msgEnc; + JABBER_LIST_ITEM *item; + int id; + char msgType[16]; + TlenProtocol *proto = (TlenProtocol *)ptr; + + if (!proto->isOnline || DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { + SENDACKTHREADDATA *tdata = (SENDACKTHREADDATA*) mir_alloc(sizeof(SENDACKTHREADDATA)); + tdata->proto = proto; + tdata->hContact = hContact; + JabberForkThread(TlenSendMessageFailedThread, 0, (void *) tdata); + return 2; + } + if (!strcmp(msg, "")) { + SENDACKTHREADDATA *tdata = (SENDACKTHREADDATA*) mir_alloc(sizeof(SENDACKTHREADDATA)); + tdata->proto = proto; + tdata->hContact = hContact; + JabberSend(proto, "", dbv.pszVal); + JabberForkThread(JabberSendMessageAckThread, 0, (void *) tdata); + } else if (!strcmp(msg, "")) { + SENDACKTHREADDATA *tdata = (SENDACKTHREADDATA*) mir_alloc(sizeof(SENDACKTHREADDATA)); + tdata->proto = proto; + tdata->hContact = hContact; + id = JabberSerialNext(proto); + JabberSend(proto, "", dbv.pszVal, "pic", 0x757f044, id); + JabberForkThread(JabberSendMessageAckThread, 0, (void *) tdata); + } else { + if ((msgEnc=JabberTextEncode(msg)) != NULL) { + if (JabberListExist(proto, LIST_CHATROOM, dbv.pszVal) && strchr(dbv.pszVal, '/')==NULL) { + strcpy(msgType, "groupchat"); + } else if (DBGetContactSettingByte(hContact, proto->iface.m_szModuleName, "bChat", FALSE)) { + strcpy(msgType, "privchat"); + } else { + strcpy(msgType, "chat"); + } + if (!strcmp(msgType, "groupchat") || DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "MsgAck", FALSE) == FALSE) { + SENDACKTHREADDATA *tdata = (SENDACKTHREADDATA*) mir_alloc(sizeof(SENDACKTHREADDATA)); + tdata->proto = proto; + tdata->hContact = hContact; + if (!strcmp(msgType, "groupchat")) { + JabberSend(proto, "%s", dbv.pszVal, msgType, msgEnc); + } else if (!strcmp(msgType, "privchat")) { + JabberSend(proto, "%s", dbv.pszVal, msgEnc); + } else { + id = JabberSerialNext(proto); + JabberSend(proto, "%s", dbv.pszVal, msgType, id, msgEnc); + } + JabberForkThread(JabberSendMessageAckThread, 0, (void *) tdata); + } + else { + id = JabberSerialNext(proto); + if ((item=JabberListGetItemPtr(proto, LIST_ROSTER, dbv.pszVal)) != NULL) + item->idMsgAckPending = id; + JabberSend(proto, "%s", dbv.pszVal, msgType, id, msgEnc); + } + } + mir_free(msgEnc); + } + DBFreeVariant(&dbv); + return 1; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// JabberGetAvatarInfo - retrieves the avatar info + +static INT_PTR TlenGetAvatarInfo(void *ptr, WPARAM wParam, LPARAM lParam) +{ + BOOL downloadingAvatar = FALSE; + char *avatarHash = NULL; + JABBER_LIST_ITEM *item = NULL; + DBVARIANT dbv; + TlenProtocol *proto = (TlenProtocol *)ptr; + PROTO_AVATAR_INFORMATION* AI = ( PROTO_AVATAR_INFORMATION* )lParam; + if (!proto->tlenOptions.enableAvatars) return GAIR_NOAVATAR; + + if (AI->hContact != NULL) { + if (!DBGetContactSetting(AI->hContact, proto->iface.m_szModuleName, "jid", &dbv)) { + item = JabberListGetItemPtr(proto, LIST_ROSTER, dbv.pszVal); + DBFreeVariant(&dbv); + if (item != NULL) { + downloadingAvatar = item->newAvatarDownloading; + avatarHash = item->avatarHash; + } + } + } else { + if (proto->threadData != NULL) { + avatarHash = proto->threadData->avatarHash; + } + } + if ((avatarHash == NULL || avatarHash[0] == '\0') && !downloadingAvatar) { + return GAIR_NOAVATAR; + } + if (avatarHash != NULL && !downloadingAvatar) { + TlenGetAvatarFileName(proto, item, AI->filename, sizeof(AI->filename)); + AI->format = ( AI->hContact == NULL ) ? proto->threadData->avatarFormat : item->avatarFormat; + return GAIR_SUCCESS; + } + if (( wParam & GAIF_FORCE ) != 0 && AI->hContact != NULL && proto->isOnline) { + /* get avatar */ + return GAIR_WAITFOR; + } + return GAIR_NOAVATAR; +} + +HANDLE TlenGetAwayMsg(PROTO_INTERFACE *ptr, HANDLE hContact) +{ + TlenProtocol *proto = (TlenProtocol *)ptr; + SENDACKTHREADDATA *tdata = (SENDACKTHREADDATA*) mir_alloc(sizeof(SENDACKTHREADDATA)); + tdata->proto = proto; + tdata->hContact = hContact; + JabberForkThread((void (__cdecl *)(void*))TlenGetAwayMsgThread, 0, (void *) tdata); + return (HANDLE)1; +} + +HANDLE TlenFileAllow(PROTO_INTERFACE *ptr, HANDLE hContact, HANDLE hTransfer, const char* szPath) +{ + TLEN_FILE_TRANSFER *ft; + JABBER_LIST_ITEM *item; + char *nick; + TlenProtocol *proto = (TlenProtocol *)ptr; + + if (!proto->isOnline) return 0; + + ft = (TLEN_FILE_TRANSFER *) hTransfer; + ft->szSavePath = mir_strdup(szPath); + if ((item=JabberListAdd(proto, LIST_FILE, ft->iqId)) != NULL) { + item->ft = ft; + } + nick = JabberNickFromJID(ft->jid); + if (ft->newP2P) { + JabberSend(proto, "", ft->jid, ft->jid, ft->iqId); + } else { + JabberSend(proto, "", nick, ft->iqId); + } + mir_free(nick); + return (HANDLE)hTransfer; +} + +int TlenFileDeny(PROTO_INTERFACE *ptr, HANDLE hContact, HANDLE hTransfer, const char* szReason) +{ + TLEN_FILE_TRANSFER *ft; + char *nick; + TlenProtocol *proto = (TlenProtocol *)ptr; + + if (!proto->isOnline) return 1; + + ft = (TLEN_FILE_TRANSFER *) hTransfer; + nick = JabberNickFromJID(ft->jid); + if (ft->newP2P) { + JabberSend(proto, "", ft->iqId, nick);\ + } else { + JabberSend(proto, "", ft->iqId, nick);\ + } + mir_free(nick); + TlenP2PFreeFileTransfer(ft); + return 0; +} + +int TlenFileCancel(PROTO_INTERFACE *ptr, HANDLE hContact, HANDLE hTransfer) +{ + TLEN_FILE_TRANSFER *ft = (TLEN_FILE_TRANSFER *) hTransfer; + TlenProtocol *proto = (TlenProtocol *)ptr; + JabberLog(proto, "Invoking FileCancel()"); + if (ft->s != NULL) { + ft->state = FT_ERROR; + Netlib_CloseHandle(ft->s); + ft->s = NULL; + if (ft->hFileEvent != NULL) { + HANDLE hEvent = ft->hFileEvent; + ft->hFileEvent = NULL; + SetEvent(hEvent); + } + } else { + TlenP2PFreeFileTransfer(ft); + } + return 0; +} + +HANDLE TlenSendFile(PROTO_INTERFACE *ptr, HANDLE hContact, const char* szDescription, char** ppszFiles) +{ + TLEN_FILE_TRANSFER *ft; + int i, j; + struct _stat statbuf; + DBVARIANT dbv; + char *nick, *p, idStr[10]; + JABBER_LIST_ITEM *item; + int id; + TlenProtocol *proto = (TlenProtocol *)ptr; + + if (!proto->isOnline) return 0; +// if (DBGetContactSettingWord(ccs->hContact, iface.m_szModuleName, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE) return 0; + if (DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) return 0; + ft = TlenFileCreateFT(proto, dbv.pszVal); + for(ft->fileCount=0; ppszFiles[ft->fileCount]; ft->fileCount++); + ft->files = (char **) mir_alloc(sizeof(char *) * ft->fileCount); + ft->filesSize = (long *) mir_alloc(sizeof(long) * ft->fileCount); + ft->allFileTotalSize = 0; + for(i=j=0; ifileCount; i++) { + if (_stat(ppszFiles[i], &statbuf)) + JabberLog(proto, "'%s' is an invalid filename", ppszFiles[i]); + else { + ft->filesSize[j] = statbuf.st_size; + ft->files[j++] = mir_strdup(ppszFiles[i]); + ft->allFileTotalSize += statbuf.st_size; + } + } + ft->fileCount = j; + ft->szDescription = mir_strdup(szDescription); + ft->hContact = hContact; + ft->currentFile = 0; + DBFreeVariant(&dbv); + + id = JabberSerialNext(proto); + _snprintf(idStr, sizeof(idStr), "%d", id); + if ((item=JabberListAdd(proto, LIST_FILE, idStr)) != NULL) { + ft->iqId = mir_strdup(idStr); + nick = JabberNickFromJID(ft->jid); + item->ft = ft; + if (proto->tlenOptions.useNewP2P) { + JabberSend(proto, "", + ft->jid, ft->jid, idStr, ft->fileCount, ft->allFileTotalSize, ft->fileCount); + + ft->newP2P = TRUE; + } else { + if (ft->fileCount == 1) { + if ((p=strrchr(ppszFiles[0], '\\')) != NULL) + p++; + else + p = ppszFiles[0]; + p = JabberTextEncode(p); + JabberSend(proto, "", nick, p, idStr, ft->allFileTotalSize); + mir_free(p); + } + else + JabberSend(proto, "", nick, idStr, ft->fileCount, ft->allFileTotalSize); + } + mir_free(nick); + } + + return (HANDLE) ft; +} + +int TlenRecvMessage(PROTO_INTERFACE *ptr, HANDLE hContact, PROTORECVEVENT* evt) +{ + CCSDATA ccs = { hContact, PSR_MESSAGE, 0, ( LPARAM )evt }; + return CallService( MS_PROTO_RECVMSG, 0, ( LPARAM )&ccs ); +} + +int TlenRecvFile(PROTO_INTERFACE *ptr, HANDLE hContact, PROTORECVFILE* evt) +{ + CCSDATA ccs = { hContact, PSR_FILE, 0, ( LPARAM )evt }; + return CallService( MS_PROTO_RECVFILE, 0, ( LPARAM )&ccs ); +} + + +static char* settingToChar( DBCONTACTWRITESETTING* cws ) +{ + switch( cws->value.type ) { + case DBVT_ASCIIZ: + return mir_strdup( cws->value.pszVal ); + case DBVT_UTF8: + return mir_utf8decode(mir_strdup(cws->value.pszVal), NULL); + } + return NULL; +} + +int JabberDbSettingChanged(void *ptr, WPARAM wParam, LPARAM lParam) +{ + DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING *) lParam; + TlenProtocol *proto = (TlenProtocol *)ptr; + // no action for hContact == NULL or when offline + if ((HANDLE) wParam == NULL) return 0; + if (!proto->isConnected) return 0; + + if (!strcmp(cws->szModule, "CList")) { + HANDLE hContact; + DBVARIANT dbv; + JABBER_LIST_ITEM *item; + char *szProto, *nick, *jid, *group; + + hContact = (HANDLE) wParam; + szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if (szProto==NULL || strcmp(szProto, proto->iface.m_szModuleName)) return 0; +// if (DBGetContactSettingByte(hContact, iface.m_szModuleName, "ChatRoom", 0) != 0) return 0; + // A contact's group is changed + if (!strcmp(cws->szSetting, "Group")) { + if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { + if ((item=JabberListGetItemPtr(proto, LIST_ROSTER, dbv.pszVal)) != NULL) { + DBFreeVariant(&dbv); + if (!DBGetContactSetting(hContact, "CList", "MyHandle", &dbv)) { + nick = JabberTextEncode(dbv.pszVal); + DBFreeVariant(&dbv); + } else if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "Nick", &dbv)) { + nick = JabberTextEncode(dbv.pszVal); + DBFreeVariant(&dbv); + } else { + nick = JabberNickFromJID(item->jid); + } + if (nick != NULL) { + // Note: we need to compare with item->group to prevent infinite loop + if (cws->value.type==DBVT_DELETED && item->group!=NULL) { + JabberLog(proto, "Group set to nothing"); + JabberSend(proto, "", nick, item->jid); + } else if (cws->value.pszVal != NULL) { + char *newGroup = settingToChar(cws); + if (item->group==NULL || strcmp(newGroup, item->group)) { + JabberLog(proto, "Group set to %s", newGroup); + if ((group=TlenGroupEncode(newGroup)) != NULL) { + JabberSend(proto, "%s", nick, item->jid, group); + mir_free(group); + } + } + mir_free(newGroup); + } + mir_free(nick); + } + } + else { + DBFreeVariant(&dbv); + } + } + } + // A contact is renamed + else if (!strcmp(cws->szSetting, "MyHandle")) { + char *newNick; + +// hContact = (HANDLE) wParam; +// szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); +// if (szProto==NULL || strcmp(szProto, iface.m_szModuleName)) return 0; + + if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { + jid = dbv.pszVal; + if ((item=JabberListGetItemPtr(proto, LIST_ROSTER, dbv.pszVal)) != NULL) { + if (cws->value.type == DBVT_DELETED) { + newNick = mir_strdup((char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_NOMYHANDLE)); + } else if (cws->value.pszVal!=NULL) { + newNick = settingToChar(cws); + } else { + newNick = NULL; + } + // Note: we need to compare with item->nick to prevent infinite loop + if (newNick!=NULL && (item->nick==NULL || (item->nick!=NULL && strcmp(item->nick, newNick)))) { + if ((nick=JabberTextEncode(newNick)) != NULL) { + JabberLog(proto, "Nick set to %s", newNick); + if (item->group!=NULL && (group=TlenGroupEncode(item->group))!=NULL) { + JabberSend(proto, "%s", nick, jid, group); + mir_free(group); + } else { + JabberSend(proto, "", nick, jid); + } + mir_free(nick); + } + } + if (newNick != NULL) mir_free(newNick); + } + DBFreeVariant(&dbv); + } + } + // A temporary contact has been added permanently + else if (!strcmp(cws->szSetting, "NotOnList")) { + char *jid, *nick, *pGroup; + + if (cws->value.type==DBVT_DELETED || (cws->value.type==DBVT_BYTE && cws->value.bVal==0)) { + if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { + jid = mir_strdup(dbv.pszVal); + DBFreeVariant(&dbv); + JabberLog(proto, "Add %s permanently to list", jid); + if (!DBGetContactSetting(hContact, "CList", "MyHandle", &dbv)) { + nick = JabberTextEncode(dbv.pszVal); //Utf8Encode + DBFreeVariant(&dbv); + } + else { + nick = JabberNickFromJID(jid); + } + if (nick != NULL) { + JabberLog(proto, "jid=%s nick=%s", jid, nick); + if (!DBGetContactSetting(hContact, "CList", "Group", &dbv)) { + if ((pGroup=TlenGroupEncode(dbv.pszVal)) != NULL) { + JabberSend(proto, "%s", nick, jid, pGroup); + JabberSend(proto, "", jid); + mir_free(pGroup); + } + DBFreeVariant(&dbv); + } + else { + JabberSend(proto, "", nick, jid); + JabberSend(proto, "", jid); + } + mir_free(nick); + DBDeleteContactSetting(hContact, "CList", "Hidden"); + } + mir_free(jid); + } + } + } + } + + return 0; +} + +int JabberContactDeleted(void *ptr, WPARAM wParam, LPARAM lParam) +{ + char *szProto; + DBVARIANT dbv; + TlenProtocol *proto = (TlenProtocol *)ptr; + + if(!proto->isOnline) // should never happen + return 0; + szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0); + if (szProto==NULL || strcmp(szProto, proto->iface.m_szModuleName)) + return 0; + if (!DBGetContactSetting((HANDLE) wParam, proto->iface.m_szModuleName, "jid", &dbv)) { + char *jid, *p, *q; + + jid = dbv.pszVal; + if ((p=strchr(jid, '@')) != NULL) { + if ((q=strchr(p, '/')) != NULL) + *q = '\0'; + } + if (JabberListExist(proto, LIST_ROSTER, jid)) { + // Remove from roster, server also handles the presence unsubscription process. + JabberSend(proto, "", jid); + } + + DBFreeVariant(&dbv); + } + return 0; +} + +int TlenUserIsTyping(PROTO_INTERFACE *ptr, HANDLE hContact, int type) +{ + DBVARIANT dbv; + JABBER_LIST_ITEM *item; + TlenProtocol *proto = (TlenProtocol *)ptr; + + if (!proto->isOnline) return 0; + if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { + if ((item=JabberListGetItemPtr(proto, LIST_ROSTER, dbv.pszVal))!=NULL /*&& item->wantComposingEvent==TRUE*/) { + switch (type) { + case PROTOTYPE_SELFTYPING_OFF: + JabberSend(proto, "", dbv.pszVal); + break; + case PROTOTYPE_SELFTYPING_ON: + JabberSend(proto, "", dbv.pszVal); + break; + } + } + DBFreeVariant(&dbv); + } + return 0; +} + +INT_PTR TlenGetMyAvatar(void *ptr, WPARAM wParam, LPARAM lParam) +{ + char* buf = ( char* )wParam; + int size = ( int )lParam; + TlenProtocol *proto = (TlenProtocol *)ptr; + + if ( buf == NULL || size <= 0 ) + return -1; + + TlenGetAvatarFileName( proto, NULL, buf, size ); + return 0; +} + +static INT_PTR CALLBACK TlenChangeAvatarDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + switch ( msg ) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + { + HICON hIcon = GetIcolibIcon(IDI_TLEN); + SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) hIcon); + ReleaseIcolibIcon(hIcon); + } + CheckDlgButton(hwndDlg, IDC_PUBLICAVATAR, TRUE); + return TRUE; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + { + int result = LOWORD(wParam); + if (IsDlgButtonChecked(hwndDlg, IDC_PUBLICAVATAR)) { + result |= 0x10000; + } + EndDialog(hwndDlg, result); + } + return TRUE; + } + break; + } + return 0; +} + +INT_PTR TlenSetMyAvatar(void *ptr, WPARAM wParam, LPARAM lParam) +{ + char* szFileName = ( char* )lParam; + char tFileName[ MAX_PATH ]; + int fileIn; + TlenProtocol *proto = (TlenProtocol *)ptr; + if(!proto->isOnline) return 1; + if (szFileName != NULL) { + int result = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_USER_CHANGEAVATAR), NULL, TlenChangeAvatarDlgProc, (LPARAM) NULL); + TlenGetAvatarFileName( proto, NULL, tFileName, MAX_PATH); + if ( CopyFileA( szFileName, tFileName, FALSE ) == FALSE ) { + return 1; + } + fileIn = open( tFileName, O_RDWR | O_BINARY, S_IREAD | S_IWRITE ); + if ( fileIn != -1 ) { + long dwPngSize = filelength(fileIn); + BYTE* pResult = (BYTE *)mir_alloc(dwPngSize); + if (pResult != NULL) { + read( fileIn, pResult, dwPngSize ); + close( fileIn ); + TlenUploadAvatar(proto, pResult, dwPngSize, (result & 0x10000) != 0); + mir_free(pResult); + } + } + } else { + TlenRemoveAvatar(proto); + } + return 0; +} + +INT_PTR TlenGetAvatarCaps(void *ptr, WPARAM wParam, LPARAM lParam) +{ + TlenProtocol *proto = (TlenProtocol *)ptr; + switch (wParam) { + case AF_MAXSIZE: + { + POINT* size = (POINT*)lParam; + if ( size ) + size->x = size->y = 64; + } + return 0; + case AF_PROPORTION: + return PIP_SQUARE; + case AF_FORMATSUPPORTED: + return (lParam == PA_FORMAT_PNG) ? 1 : 0; + case AF_ENABLED: + return (proto->tlenOptions.enableAvatars && proto->isOnline) ? 1 : 0; + case AF_DONTNEEDDELAYS: + return 1; + case AF_MAXFILESIZE: + return 10 * 1024; + case AF_DELAYAFTERFAIL: + return 0; + } + return 0; +} + + +int TlenOnEvent( PROTO_INTERFACE *ptr, PROTOEVENTTYPE eventType, WPARAM wParam, LPARAM lParam ) +{ + TlenProtocol *proto = (TlenProtocol *)ptr; + switch( eventType ) { + case EV_PROTO_ONLOAD: return TlenOnModulesLoaded(proto, 0, 0 ); + case EV_PROTO_ONOPTIONS: return TlenOptionsInit(proto, wParam, lParam ); + case EV_PROTO_ONEXIT: return TlenPreShutdown(proto, 0, 0 ); + case EV_PROTO_ONRENAME: + { + CLISTMENUITEM clmi = { 0 }; + clmi.cbSize = sizeof( CLISTMENUITEM ); + clmi.flags = CMIM_NAME | CMIF_TCHAR; + clmi.ptszName = proto->iface.m_tszUserName; + CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )proto->hMenuRoot, ( LPARAM )&clmi ); + /* FIXME: Rename network user as well */ + } + } + return 1; +} + +// PSS_ADDED +int TlenAuthRecv(PROTO_INTERFACE *ptr, HANDLE hContact, PROTORECVEVENT* evt ) +{ + return 1; +} + +// PSS_AUTHREQUEST +int TlenAuthRequest(PROTO_INTERFACE *ptr, HANDLE hContact, const TCHAR* szMessage ) +{ + return 1; +} + +HANDLE TlenChangeInfo(PROTO_INTERFACE *ptr, int iInfoType, void* pInfoData ) +{ + return NULL; +} + +int TlenRecvContacts(PROTO_INTERFACE *ptr, HANDLE hContact, PROTORECVEVENT* evt) +{ + return 1; +} + + +extern INT_PTR CALLBACK TlenAccMgrUIDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +INT_PTR TlenAccMgrUI(void *ptr, WPARAM wParam, LPARAM lParam) +{ + return (INT_PTR) CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_ACCMGRUI), (HWND)lParam, TlenAccMgrUIDlgProc, (LPARAM) ptr); +} + +void TlenInitServicesVTbl(TlenProtocol *proto) { + char s[128]; + proto->iface.vtbl = (PROTO_INTERFACE_VTBL*) mir_alloc(sizeof(PROTO_INTERFACE_VTBL)); + proto->iface.vtbl->AddToList = TlenAddToList; + proto->iface.vtbl->AddToListByEvent = TlenAddToListByEvent; + proto->iface.vtbl->AuthDeny = TlenAuthDeny; + proto->iface.vtbl->AuthRecv = TlenAuthRecv; + proto->iface.vtbl->AuthRequest = TlenAuthRequest; + proto->iface.vtbl->Authorize = TlenAuthAllow; + proto->iface.vtbl->ChangeInfo = TlenChangeInfo; + proto->iface.vtbl->FileAllow = TlenFileAllow; + proto->iface.vtbl->FileCancel = TlenFileCancel; + proto->iface.vtbl->FileDeny = TlenFileDeny; + proto->iface.vtbl->FileResume = NULL; + proto->iface.vtbl->SearchBasic = TlenBasicSearch; + proto->iface.vtbl->SearchByEmail = TlenSearchByEmail; + proto->iface.vtbl->SearchByName = TlenSearchByName; + proto->iface.vtbl->SearchAdvanced = TlenSearchAdvanced; + proto->iface.vtbl->CreateExtendedSearchUI = TlenCreateAdvSearchUI; + + proto->iface.vtbl->RecvContacts = TlenRecvContacts; + proto->iface.vtbl->RecvFile = TlenRecvFile; + proto->iface.vtbl->RecvMsg = TlenRecvMessage; + proto->iface.vtbl->RecvUrl = NULL; + + proto->iface.vtbl->SendContacts = NULL; + proto->iface.vtbl->SendFile = TlenSendFile; + proto->iface.vtbl->SendMsg = TlenSendMessage; + proto->iface.vtbl->SendUrl = NULL; + + proto->iface.vtbl->GetCaps = TlenGetCaps; + proto->iface.vtbl->GetIcon = TlenGetIcon; + proto->iface.vtbl->GetInfo = JabberGetInfo; + proto->iface.vtbl->SetApparentMode = TlenSetApparentMode; + proto->iface.vtbl->SetStatus = TlenSetStatus; + + + proto->iface.vtbl->GetAwayMsg = TlenGetAwayMsg; + proto->iface.vtbl->RecvAwayMsg = NULL; + proto->iface.vtbl->SendAwayMsg = NULL; + proto->iface.vtbl->SetAwayMsg = TlenSetAwayMsg; + + proto->iface.vtbl->UserIsTyping = TlenUserIsTyping; + + proto->iface.vtbl->OnEvent = TlenOnEvent; + + sprintf(s, "%s%s", proto->iface.m_szModuleName, PS_GETNAME); + CreateServiceFunction_Ex(s, proto, TlenGetName); + + sprintf(s, "%s%s", proto->iface.m_szModuleName, PS_GETAVATARINFO); + CreateServiceFunction_Ex(s, proto, TlenGetAvatarInfo); + + sprintf(s, "%s%s", proto->iface.m_szModuleName, "/SendNudge"); + CreateServiceFunction_Ex(s, proto, TlenSendAlert); + + sprintf(s, "%s%s", proto->iface.m_szModuleName, PS_GETAVATARCAPS); + CreateServiceFunction_Ex(s, proto, TlenGetAvatarCaps); + + sprintf(s, "%s%s", proto->iface.m_szModuleName, PS_SETMYAVATAR); + CreateServiceFunction_Ex(s, proto, TlenSetMyAvatar); + + sprintf(s, "%s%s", proto->iface.m_szModuleName, PS_GETMYAVATAR); + CreateServiceFunction_Ex(s, proto, TlenGetMyAvatar); + + sprintf(s, "%s%s", proto->iface.m_szModuleName, PS_GETSTATUS); + CreateServiceFunction_Ex(s, proto, TlenGetStatus); + + sprintf(s, "%s%s", proto->iface.m_szModuleName, PS_CREATEACCMGRUI); + CreateServiceFunction_Ex(s, proto, TlenAccMgrUI); + +} + diff --git a/plugins/!NotAdopted/Tlen/jabber_thread.c b/plugins/!NotAdopted/Tlen/jabber_thread.c new file mode 100644 index 0000000000..b78cb1e9b5 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/jabber_thread.c @@ -0,0 +1,1465 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" + +#include "commons.h" +#include "jabber_list.h" +#include "jabber_iq.h" +#include "resource.h" +#include "tlen_p2p_old.h" +#include "tlen_file.h" +#include "tlen_muc.h" +#include "tlen_voice.h" +#include "tlen_avatar.h" +#include "tlen_presence.h" +#include "tlen_picture.h" +#include +#include +#include + +extern void TlenProcessP2P(XmlNode *node, void *userdata); + +//static void __cdecl TlenProcessInvitation(struct ThreadData *info); +static void __cdecl JabberKeepAliveThread(void *ptr); +static void JabberProcessStreamOpening(XmlNode *node, ThreadData *info); +static void JabberProcessStreamClosing(XmlNode *node, ThreadData *info); +static void JabberProcessProtocol(XmlNode *node, ThreadData *info); +static void JabberProcessMessage(XmlNode *node, ThreadData *info); +static void JabberProcessIq(XmlNode *node, ThreadData *info); +static void TlenProcessW(XmlNode *node, ThreadData *info); +static void TlenProcessM(XmlNode *node, ThreadData *info); +static void TlenProcessN(XmlNode *node, ThreadData *info); +static void TlenProcessP(XmlNode *node, ThreadData *info); +static void TlenProcessV(XmlNode *node, ThreadData *info); +static void TlenProcessAvatar(XmlNode* node, ThreadData *info); +static void TlenProcessCipher(XmlNode *node, ThreadData *info); + +static VOID NTAPI JabberDummyApcFunc(ULONG_PTR param) +{ + return; +} + +static char onlinePassword[128]; +static HANDLE hEventPasswdDlg; + +static INT_PTR CALLBACK JabberPasswordDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char text[128]; + + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + sprintf(text, "%s %s", Translate("Enter password for"), (char *) lParam); + SetDlgItemTextA(hwndDlg, IDC_JID, text); + return TRUE; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + GetDlgItemTextA(hwndDlg, IDC_PASSWORD, onlinePassword, sizeof(onlinePassword)); + //EndDialog(hwndDlg, (int) onlinePassword); + //return TRUE; + // Fall through + case IDCANCEL: + //EndDialog(hwndDlg, 0); + SetEvent(hEventPasswdDlg); + DestroyWindow(hwndDlg); + return TRUE; + } + break; + } + + return FALSE; +} + +static VOID NTAPI JabberPasswordCreateDialogApcProc(ULONG_PTR param) +{ + CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_PASSWORD), NULL, JabberPasswordDlgProc, (LPARAM) param); +} + +void __cdecl JabberServerThread(ThreadData *info) +{ + DBVARIANT dbv; + char jidStr[128]; + char *connectHost; + char *buffer; + int datalen; + XmlState xmlState; + HANDLE hContact; + int jabberNetworkBufferSize; + int oldStatus = ID_STATUS_OFFLINE; + int reconnectMaxTime; + int numRetry; + int reconnectTime; + char *str; + CLISTMENUITEM clmi; + int loginErr = 0; + JabberLog(info->proto, "Thread started"); + + + // Normal server connection, we will fetch all connection parameters + // e.g. username, password, etc. from the database. + + if (info->proto->threadData != NULL) { + // Will not start another connection thread if a thread is already running. + // Make APC call to the main thread. This will immediately wake the thread up + // in case it is asleep in the reconnect loop so that it will immediately + // reconnect. + QueueUserAPC(JabberDummyApcFunc, info->proto->threadData->hThread, 0); + JabberLog(info->proto, "Thread ended, another normal thread is running"); + mir_free(info); + return; + } + + info->proto->threadData = info; + + if (!DBGetContactSetting(NULL, info->proto->iface.m_szModuleName, "LoginName", &dbv)) { + strncpy(info->username, dbv.pszVal, sizeof(info->username)); + info->username[sizeof(info->username)-1] = '\0'; + _strlwr(info->username); + DBWriteContactSettingString(NULL, info->proto->iface.m_szModuleName, "LoginName", info->username); + DBFreeVariant(&dbv); + + } else { + JabberLog(info->proto, "Thread ended, login name is not configured"); + loginErr = LOGINERR_BADUSERID; + } + + if (loginErr == 0) { + if (!DBGetContactSetting(NULL, info->proto->iface.m_szModuleName, "LoginServer", &dbv)) { + strncpy(info->server, dbv.pszVal, sizeof(info->server)); + info->server[sizeof(info->server)-1] = '\0'; + _strlwr(info->server); + DBWriteContactSettingString(NULL, info->proto->iface.m_szModuleName, "LoginServer", info->server); + DBFreeVariant(&dbv); + } else { + JabberLog(info->proto, "Thread ended, login server is not configured"); + loginErr = LOGINERR_NONETWORK; + } + } + + if (loginErr == 0) { + if (!info->proto->tlenOptions.savePassword) { + // Ugly hack: continue logging on only the return value is &(onlinePassword[0]) + // because if WM_QUIT while dialog box is still visible, p is returned with some + // exit code which may not be NULL. + // Should be better with modeless. + onlinePassword[0] = (char) -1; + hEventPasswdDlg = CreateEvent(NULL, FALSE, FALSE, NULL); + QueueUserAPC(JabberPasswordCreateDialogApcProc, hMainThread, (DWORD) jidStr); + WaitForSingleObject(hEventPasswdDlg, INFINITE); + CloseHandle(hEventPasswdDlg); + //if ((p=(char *)DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_PASSWORD), NULL, JabberPasswordDlgProc, (LPARAM) jidStr)) != onlinePassword) { + if (onlinePassword[0] != (char) -1) { + strncpy(info->password, onlinePassword, sizeof(info->password)); + info->password[sizeof(info->password)-1] = '\0'; + } else { + JabberLog(info->proto, "Thread ended, password request dialog was canceled"); + loginErr = LOGINERR_BADUSERID; + } + } else { + if (!DBGetContactSetting(NULL, info->proto->iface.m_szModuleName, "Password", &dbv)) { + CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); + strncpy(info->password, dbv.pszVal, sizeof(info->password)); + info->password[sizeof(info->password)-1] = '\0'; + DBFreeVariant(&dbv); + } else { + JabberLog(info->proto, "Thread ended, password is not configured"); + loginErr = LOGINERR_BADUSERID; + } + } + } + + jabberNetworkBufferSize = 2048; + if ((buffer=(char *) mir_alloc(jabberNetworkBufferSize+1)) == NULL) { // +1 is for '\0' when debug logging this buffer + JabberLog(info->proto, "Thread ended, network buffer cannot be allocated"); + loginErr = LOGINERR_NONETWORK; + } + + if (loginErr != 0) { + info->proto->threadData = NULL; + oldStatus = info->proto->iface.m_iStatus; + info->proto->iface.m_iStatus = ID_STATUS_OFFLINE; + ProtoBroadcastAck(info->proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->iface.m_iStatus); + ProtoBroadcastAck(info->proto->iface.m_szModuleName, NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, loginErr); + mir_free(info); + return; + } + + _snprintf(jidStr, sizeof(jidStr), "%s@%s", info->username, info->server); + DBWriteContactSettingString(NULL, info->proto->iface.m_szModuleName, "jid", jidStr); + + if (!DBGetContactSetting(NULL, info->proto->iface.m_szModuleName, "ManualHost", &dbv)) { + strncpy(info->manualHost, dbv.pszVal, sizeof(info->manualHost)); + info->manualHost[sizeof(info->manualHost)-1] = '\0'; + DBFreeVariant(&dbv); + } + info->port = DBGetContactSettingWord(NULL, info->proto->iface.m_szModuleName, "ManualPort", TLEN_DEFAULT_PORT); + info->useEncryption = info->proto->tlenOptions.useEncryption; + + if (info->manualHost[0]) + connectHost = info->manualHost; + else + connectHost = info->server; + + JabberLog(info->proto, "Thread server='%s' port='%d'", connectHost, info->port); + + + if (!DBGetContactSetting(NULL, info->proto->iface.m_szModuleName, "AvatarHash", &dbv)) { + strcpy(info->proto->threadData->avatarHash, dbv.pszVal); + DBFreeVariant(&dbv); + } + info->avatarFormat = DBGetContactSettingDword(NULL, info->proto->iface.m_szModuleName, "AvatarFormat", PA_FORMAT_UNKNOWN); + + + reconnectMaxTime = 10; + numRetry = 0; + + for (;;) { // Reconnect loop + + info->s = JabberWsConnect(info->proto, connectHost, info->port); + if (info->s == NULL) { + JabberLog(info->proto, "Connection failed (%d)", WSAGetLastError()); + if (info->proto->threadData == info) { + oldStatus = info->proto->iface.m_iStatus; + info->proto->iface.m_iStatus = ID_STATUS_OFFLINE; + ProtoBroadcastAck(info->proto->iface.m_szModuleName, NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGINERR_NONETWORK); + ProtoBroadcastAck(info->proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->iface.m_iStatus); + if (info->proto->tlenOptions.reconnect == TRUE) { + reconnectTime = rand() % reconnectMaxTime; + JabberLog(info->proto, "Sleeping %d seconds before automatic reconnecting...", reconnectTime); + SleepEx(reconnectTime * 1000, TRUE); + if (reconnectMaxTime < 10*60) // Maximum is 10 minutes + reconnectMaxTime *= 2; + if (info->proto->threadData == info) { // Make sure this is still the active thread for the main Jabber connection + JabberLog(info->proto, "Reconnecting to the network..."); + if (numRetry < MAX_CONNECT_RETRIES) + numRetry++; + oldStatus = info->proto->iface.m_iStatus; + info->proto->iface.m_iStatus = ID_STATUS_CONNECTING + numRetry; + ProtoBroadcastAck(info->proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->iface.m_iStatus); + continue; + } + else { + JabberLog(info->proto, "Thread ended, connection failed"); + mir_free(buffer); + mir_free(info); + return; + } + } + info->proto->threadData = NULL; + } + JabberLog(info->proto, "Thread ended, connection failed"); + mir_free(buffer); + mir_free(info); + return; + } + + // Determine local IP + /* + socket = CallService(MS_NETLIB_GETSOCKET, (WPARAM) proto, 0); + struct sockaddr_in saddr; + int len; + + len = sizeof(saddr); + getsockname(socket, (struct sockaddr *) &saddr, &len); + jabberLocalIP = saddr.sin_addr.S_un.S_addr; + JabberLog("Local IP = %s", inet_ntoa(saddr.sin_addr)); + */ + + // User may change status to OFFLINE while we are connecting above + if (info->proto->iface.m_iDesiredStatus!=ID_STATUS_OFFLINE) { + + info->proto->isConnected = TRUE; + JabberForkThread(JabberKeepAliveThread, 0, info->proto); + + JabberXmlInitState(&xmlState); + JabberXmlSetCallback(&xmlState, 1, ELEM_OPEN, JabberProcessStreamOpening, info); + JabberXmlSetCallback(&xmlState, 1, ELEM_CLOSE, JabberProcessStreamClosing, info); + JabberXmlSetCallback(&xmlState, 2, ELEM_CLOSE, JabberProcessProtocol, info); + + info->useAES = FALSE; + + if (info->useEncryption) { + JabberSend(info->proto, ""); + + } else { + JabberSend(info->proto, ""); + } + + JabberLog(info->proto, "Entering main recv loop"); + datalen = 0; + + for (;;) { + int recvResult, bytesParsed; + + if (info->useAES) { + recvResult = JabberWsRecvAES(info->proto, buffer+datalen, jabberNetworkBufferSize-datalen, &info->aes_in_context, info->aes_in_iv); + } else { + recvResult = JabberWsRecv(info->proto, info->s, buffer+datalen, jabberNetworkBufferSize-datalen); + } + + if (recvResult <= 0) + break; + datalen += recvResult; + + buffer[datalen] = '\0'; + JabberLog(info->proto, "RECV:%s", buffer); + + bytesParsed = JabberXmlParse(&xmlState, buffer, datalen); + JabberLog(info->proto, "bytesParsed = %d", bytesParsed); + if (bytesParsed > 0) { + if (bytesParsed < datalen) + memmove(buffer, buffer+bytesParsed, datalen-bytesParsed); + datalen -= bytesParsed; + } + else if (datalen == jabberNetworkBufferSize) { + jabberNetworkBufferSize += 2048; + JabberLog(info->proto, "Increasing network buffer size to %d", jabberNetworkBufferSize); + if ((buffer=(char *) mir_realloc(buffer, jabberNetworkBufferSize+1)) == NULL) { + JabberLog(info->proto, "Cannot reallocate more network buffer, go offline now"); + break; + } + } + else { + JabberLog(info->proto, "Unknown state: bytesParsed=%d, datalen=%d, jabberNetworkBufferSize=%d", bytesParsed, datalen, jabberNetworkBufferSize); + } + } + + JabberXmlDestroyState(&xmlState); + + info->proto->isOnline = FALSE; + info->proto->isConnected = FALSE; + + memset(&clmi, 0, sizeof(CLISTMENUITEM)); + clmi.cbSize = sizeof(CLISTMENUITEM); + clmi.flags = CMIM_FLAGS | CMIF_GRAYED; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) info->proto->hMenuMUC, (LPARAM) &clmi); + if (info->proto->hMenuChats != NULL){ + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) info->proto->hMenuChats, (LPARAM) &clmi); + } + + // Set status to offline + oldStatus = info->proto->iface.m_iStatus; + info->proto->iface.m_iStatus = ID_STATUS_OFFLINE; + ProtoBroadcastAck(info->proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->iface.m_iStatus); + + // Set all contacts to offline + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact != NULL) { + str = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if(str!=NULL && !strcmp(str, info->proto->iface.m_szModuleName)) { + if (DBGetContactSettingWord(hContact, info->proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) { + DBWriteContactSettingWord(hContact, info->proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE); + } + } + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); + } + + JabberListWipeSpecial(info->proto); + } + else { + oldStatus = info->proto->iface.m_iStatus; + info->proto->iface.m_iStatus = ID_STATUS_OFFLINE; + ProtoBroadcastAck(info->proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->iface.m_iStatus); + } + + Netlib_CloseHandle(info->s); + + if (info->proto->tlenOptions.reconnect==FALSE) + break; + + if (info->proto->threadData != info) // Make sure this is still the main Jabber connection thread + break; + reconnectTime = rand() % 10; + JabberLog(info->proto, "Sleeping %d seconds before automatic reconnecting...", reconnectTime); + SleepEx(reconnectTime * 1000, TRUE); + reconnectMaxTime = 20; + if (info->proto->threadData != info) // Make sure this is still the main Jabber connection thread + break; + JabberLog(info->proto, "Reconnecting to the network..."); + info->proto->iface.m_iDesiredStatus = oldStatus; // Reconnect to my last status + oldStatus = info->proto->iface.m_iStatus; + info->proto->iface.m_iStatus = ID_STATUS_CONNECTING; + numRetry = 1; + ProtoBroadcastAck(info->proto->iface.m_szModuleName, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) oldStatus, info->proto->iface.m_iStatus); + } + + JabberLog(info->proto, "Thread ended: server='%s'", info->server); + + if (info->proto->threadData==info) { + info->proto->threadData = NULL; + } + + mir_free(buffer); + if (info->streamId) mir_free(info->streamId); + JabberLog(info->proto, "Exiting ServerThread"); + mir_free(info); +} + +static void TlenSendAuth(TlenProtocol *proto) { + int iqId; + char *p; + char *str; + char text[128]; + str = TlenPasswordHash(proto->threadData->password); + sprintf(text, "%s%s", proto->threadData->streamId, str); + mir_free(str); + str = JabberSha1(text); + if ((p=JabberTextEncode(proto->threadData->username)) != NULL) { + iqId = JabberSerialNext(proto->threadData->proto); + JabberIqAdd(proto, iqId, IQ_PROC_NONE, JabberIqResultAuth); + JabberSend(proto, "%s%sttlen.pl", iqId, p /*info->username*/, str); + mir_free(p); + } + mir_free(str); +} + +static void JabberProcessStreamOpening(XmlNode *node, ThreadData *info) +{ + char *sid, *s; + + if (node->name==NULL || strcmp(node->name, "s")) + return; + + if ((sid=JabberXmlGetAttrValue(node, "i")) != NULL) { + if (info->streamId) mir_free(info->streamId); + info->streamId = mir_strdup(sid); + } + if ((s=JabberXmlGetAttrValue(node, "s")) != NULL && !strcmp(s, "1")) { + int i; + char *k1, *k2, *k3; + unsigned char aes_key[32]; + char aes_key_str[140], aes_iv_str[40]; + mpi k1_mpi, k2_mpi, aes_mpi; + size_t slen; + + k1=JabberXmlGetAttrValue(node, "k1"); + k2=JabberXmlGetAttrValue(node, "k2"); + k3=JabberXmlGetAttrValue(node, "k3"); + + memset(&info->aes_in_context, 0, sizeof (aes_context)); + memset(&info->aes_out_context, 0, sizeof (aes_context)); + memset(&aes_mpi, 0, sizeof (mpi)); + mpi_read_string(&aes_mpi, 16, k3); + mpi_write_binary(&aes_mpi, info->aes_in_iv, 16); + for (i = 0; i < 16; i++) { + info->aes_out_iv[i] = rand(); + aes_key[i] = rand(); + } + memset(&aes_mpi, 0, sizeof (mpi)); + mpi_read_binary(&aes_mpi, info->aes_out_iv, 16); + slen = 40; + mpi_write_string(&aes_mpi, 16, aes_iv_str, &slen); + aes_setkey_dec(&info->aes_in_context, aes_key, 128); + aes_setkey_enc(&info->aes_out_context, aes_key, 128); + memset(&aes_mpi, 0, sizeof (mpi)); + mpi_read_binary(&aes_mpi, aes_key, 16); + memset(&k1_mpi, 0, sizeof (mpi)); + mpi_read_string( &k1_mpi, 16, k1 ); + memset(&k2_mpi, 0, sizeof (mpi)); + mpi_read_string( &k2_mpi, 16, k2 ); + memset(&aes_mpi, 0, sizeof (mpi)); + mpi_read_binary(&aes_mpi, (unsigned char *)aes_key, 16); + mpi_exp_mod( &aes_mpi, &aes_mpi, &k1_mpi, &k2_mpi, NULL ); + slen = 140; + mpi_write_string(&aes_mpi, 16, aes_key_str, &slen); + JabberSend(info->proto, "", aes_key_str, aes_iv_str); + } else { + TlenSendAuth(info->proto); + } +} + +static void JabberProcessStreamClosing(XmlNode *node, ThreadData *info) +{ + Netlib_CloseHandle(info->proto); + if (node->name && !strcmp(node->name, "stream:error") && node->text) + MessageBoxA(NULL, Translate(node->text), Translate("Jabber Connection Error"), MB_OK|MB_ICONERROR|MB_SETFOREGROUND); +} + +static void JabberProcessProtocol(XmlNode *node, ThreadData *info) +{ + if (!strcmp(node->name, "message")) + JabberProcessMessage(node, info); + else if (!strcmp(node->name, "presence")) + TlenProcessPresence(node, info->proto); + else if (!strcmp(node->name, "iq")) + JabberProcessIq(node, info); + else if (!strcmp(node->name, "f")) + TlenProcessF(node, info); + else if (!strcmp(node->name, "w")) + TlenProcessW(node, info); + else if (!strcmp(node->name, "m")) + TlenProcessM(node, info); + else if (!strcmp(node->name, "n")) + TlenProcessN(node, info); + else if (!strcmp(node->name, "p")) + TlenProcessP(node, info); + else if (!strcmp(node->name, "v")) + TlenProcessV(node, info); + else if (!strcmp(node->name, "avatar")) + TlenProcessAvatar(node, info); + else if (!strcmp(node->name, "cipher")) + TlenProcessCipher(node, info); + else + JabberLog(info->proto, "Invalid top-level tag (only

and allowed)"); + +} + +static void TlenProcessCipher(XmlNode *node, ThreadData *info) +{ + char *type; + type=JabberXmlGetAttrValue(node, "type"); + info->useAES = TRUE; + JabberSend(info->proto, ""); + TlenSendAuth(info->proto); +} + +static void TlenProcessIqGetVersion(TlenProtocol *proto, XmlNode* node) +{ + OSVERSIONINFO osvi = { 0 }; + char mversion[256]; + char* from, *version, *mver; + char* os = NULL; + JABBER_LIST_ITEM *item; + + if (proto->iface.m_iStatus == ID_STATUS_INVISIBLE) return; + if (!proto->tlenOptions.enableVersion) return; + if (( from=JabberXmlGetAttrValue( node, "from" )) == NULL ) return; + if (( item=JabberListGetItemPtr( proto, LIST_ROSTER, from )) ==NULL) return; + version = JabberTextEncode( TLEN_VERSION_STRING ); + osvi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); + if ( GetVersionEx( &osvi )) { + switch ( osvi.dwPlatformId ) { + case VER_PLATFORM_WIN32_NT: + if ( osvi.dwMajorVersion == 5 ) { + if ( osvi.dwMinorVersion == 2 ) os = JabberTextEncode( Translate( "Windows Server 2003" )); + else if ( osvi.dwMinorVersion == 1 ) os = JabberTextEncode( Translate( "Windows XP" )); + else if ( osvi.dwMinorVersion == 0 ) os = JabberTextEncode( Translate( "Windows 2000" )); + } + else if ( osvi.dwMajorVersion <= 4 ) { + os = JabberTextEncode( Translate( "Windows NT" )); + } + break; + case VER_PLATFORM_WIN32_WINDOWS: + if ( osvi.dwMajorVersion == 4 ) { + if ( osvi.dwMinorVersion == 0 ) os = JabberTextEncode( Translate( "Windows 95" )); + if ( osvi.dwMinorVersion == 10 ) os = JabberTextEncode( Translate( "Windows 98" )); + if ( osvi.dwMinorVersion == 90 ) os = JabberTextEncode( Translate( "Windows ME" )); + } + break; + } } + + if ( os == NULL ) os = JabberTextEncode( Translate( "Windows" )); + + strcpy(mversion, "Miranda IM "); + CallService( MS_SYSTEM_GETVERSIONTEXT, sizeof( mversion ) - 11, ( LPARAM )mversion + 11 ); + strcat(mversion, " (Tlen v."); + strcat(mversion, TLEN_VERSION_STRING); + strcat(mversion, ")"); + mver = JabberTextEncode( mversion ); + JabberSend( proto, "%s%s%s", from, mver?mver:"", version?version:"", os?os:"" ); + if (!item->versionRequested) { + item->versionRequested = TRUE; + JabberSend(proto, "", from); + } + + if ( mver ) mir_free( mver ); + if ( version ) mir_free( version ); + if ( os ) mir_free( os ); +} + +// Support for Tlen avatars - avatar token used to access web interface +static void TlenProcessAvatar(XmlNode* node, ThreadData *info) +{ + XmlNode *tokenNode, *aNode; + tokenNode = JabberXmlGetChild(node, "token"); + aNode = JabberXmlGetChild(node, "a"); + if (tokenNode != NULL) { + char *token = tokenNode->text; + strcpy(info->avatarToken, token); + } + if (aNode != NULL) { + if (TlenProcessAvatarNode(info->proto, node, NULL)) { + } + } +} + +static void JabberProcessMessage(XmlNode *node, ThreadData *info) +{ + HANDLE hContact; + CCSDATA ccs; + PROTORECVEVENT recv; + XmlNode *bodyNode, *subjectNode, *xNode, *n; + char *from, *type, *nick, *p, *localMessage, *idStr; + DWORD msgTime; + BOOL delivered, composing; + int i; + JABBER_LIST_ITEM *item; + BOOL isChatRoomJid; + + if (!node->name || strcmp(node->name, "message")) return; + + if ((type=JabberXmlGetAttrValue(node, "type"))!=NULL && !strcmp(type, "error")) { + } + else { + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + char *fromJid = JabberLoginFromJID(from); + if (info->proto->tlenOptions.ignoreAdvertisements && strstr(from, "b73@tlen.pl") == from) { + return; + } + // If message is from a stranger (not in roster), item is NULL + item = JabberListGetItemPtr(info->proto, LIST_ROSTER, fromJid); + isChatRoomJid = JabberListExist(info->proto, LIST_CHATROOM, from); + + if (isChatRoomJid && type!=NULL && !strcmp(type, "groupchat")) { + //JabberGroupchatProcessMessage(node, userdata); + } else if (type!=NULL && !strcmp(type, "pic")) { + TlenProcessPic(node, info->proto); + } else if (type!=NULL && !strcmp(type, "iq")) { + XmlNode *iqNode; + // Jabber-compatible iq + if ((iqNode=JabberXmlGetChild(node, "iq")) != NULL) { + JabberXmlAddAttr(iqNode, "from", from); + JabberProcessIq(iqNode, info); + } + } else { + if ((bodyNode=JabberXmlGetChild(node, "body")) != NULL) { + if (bodyNode->text != NULL) { + if ((subjectNode=JabberXmlGetChild(node, "subject"))!=NULL && subjectNode->text!=NULL && subjectNode->text[0]!='\0') { + p = (char *) mir_alloc(strlen(subjectNode->text)+strlen(bodyNode->text)+5); + sprintf(p, "%s\r\n%s", subjectNode->text, bodyNode->text); + localMessage = JabberTextDecode(p); + mir_free(p); + } else { + localMessage = JabberTextDecode(bodyNode->text); + } + + msgTime = 0; + delivered = composing = FALSE; + i = 1; + while ((xNode=JabberXmlGetNthChild(node, "x", i)) != NULL) { + if ((p=JabberXmlGetAttrValue(xNode, "xmlns")) != NULL) { + if (!strcmp(p, "jabber:x:delay") && msgTime==0) { + if ((p=JabberXmlGetAttrValue(xNode, "stamp")) != NULL) { + msgTime = JabberIsoToUnixTime(p); + } + } + else if (!strcmp(p, "jabber:x:event")) { + // Check whether any event is requested + if (!delivered && (n=JabberXmlGetChild(xNode, "delivered"))!=NULL) { + delivered = TRUE; + idStr = JabberXmlGetAttrValue(node, "id"); + JabberSend(info->proto, "%s", from, (idStr!=NULL)?idStr:""); + } + if (item!=NULL && JabberXmlGetChild(xNode, "composing")!=NULL) { + composing = TRUE; + if (item->messageEventIdStr) + mir_free(item->messageEventIdStr); + idStr = JabberXmlGetAttrValue(node, "id"); + item->messageEventIdStr = (idStr==NULL)?NULL:mir_strdup(idStr); + } + } + } + i++; + } + + if (item != NULL) { + item->wantComposingEvent = composing; + if (item->isTyping) { + item->isTyping = FALSE; + if ((hContact=JabberHContactFromJID(info->proto, fromJid)) != NULL) + CallService(MS_PROTO_CONTACTISTYPING, (WPARAM) hContact, PROTOTYPE_CONTACTTYPING_OFF); + } + } + + if ((hContact=JabberHContactFromJID(info->proto, fromJid)) == NULL) { + // Create a temporary contact + if (isChatRoomJid) { + if ((p=strchr(from, '/'))!=NULL && p[1]!='\0') + p++; + else + p = from; + nick = JabberTextEncode(p); + hContact = JabberDBCreateContact(info->proto, from, nick, TRUE); + } + else { + nick = JabberLocalNickFromJID(from); + hContact = JabberDBCreateContact(info->proto, from, nick, TRUE); + } + mir_free(nick); + } + + if (msgTime == 0) { + msgTime = time(NULL); + } else { + HANDLE hDbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDLAST, (WPARAM) hContact, 0); + if (hDbEvent != NULL) { + DBEVENTINFO dbei = { 0 }; + dbei.cbSize = sizeof(dbei); + CallService(MS_DB_EVENT_GET, (WPARAM) hDbEvent, (LPARAM) &dbei); + if (msgTime < dbei.timestamp) { + msgTime = dbei.timestamp + 1; + } + } + if (msgTime > (DWORD)time(NULL)) { + msgTime = time(NULL); + } + } + recv.flags = 0; + recv.timestamp = (DWORD) msgTime; + recv.szMessage = localMessage; + recv.lParam = 0; + ccs.hContact = hContact; + ccs.wParam = 0; + ccs.szProtoService = PSR_MESSAGE; + ccs.lParam = (LPARAM) &recv; + CallService(MS_PROTO_CHAINRECV, 0, (LPARAM) &ccs); + + mir_free(localMessage); + } + } + } + mir_free(fromJid); + } + } +} + +static void JabberProcessIq(XmlNode *node, ThreadData *info) +{ + HANDLE hContact; + XmlNode *queryNode = NULL; + char *type, *jid, *nick; + char *xmlns = NULL; + char *idStr, *str; + int id; + int i; + JABBER_IQ_PFUNC pfunc; + + if (!node->name || strcmp(node->name, "iq")) return; + type=JabberXmlGetAttrValue(node, "type"); +// if ((type=JabberXmlGetAttrValue(node, "type")) == NULL) return; + + id = -1; + if ((idStr=JabberXmlGetAttrValue(node, "id")) != NULL) { + if (!strncmp(idStr, JABBER_IQID, strlen(JABBER_IQID))) + id = atoi(idStr+strlen(JABBER_IQID)); + } + + queryNode = JabberXmlGetChild(node, "query"); + if (queryNode != NULL) { + xmlns = JabberXmlGetAttrValue(queryNode, "xmlns"); + } + + + ///////////////////////////////////////////////////////////////////////// + // MATCH BY ID + ///////////////////////////////////////////////////////////////////////// + if ((pfunc=JabberIqFetchFunc(info->proto, id)) != NULL) { + JabberLog(info->proto, "Handling iq request for id=%d", id); + pfunc(info->proto, node); + ///////////////////////////////////////////////////////////////////////// + // MORE GENERAL ROUTINES, WHEN ID DOES NOT MATCH + ///////////////////////////////////////////////////////////////////////// + // new p2p connections + } else if (xmlns != NULL && !strcmp(xmlns, "p2p")) { + if (info->proto->tlenOptions.useNewP2P) { + TlenProcessP2P(node, info); + } + } + // RECVED: proto, " Got roster push, query has %d children", queryNode->numChild); + for (i=0; inumChild; i++) { + itemNode = queryNode->child[i]; + if (!strcmp(itemNode->name, "item")) { + if ((jid=JabberXmlGetAttrValue(itemNode, "jid")) != NULL) { + if ((str=JabberXmlGetAttrValue(itemNode, "subscription")) != NULL) { + // we will not add new account when subscription=remove + if (!strcmp(str, "to") || !strcmp(str, "both") || !strcmp(str, "from") || !strcmp(str, "none")) { + if ((name=JabberXmlGetAttrValue(itemNode, "name")) != NULL) { + nick = JabberTextDecode(name); + } else { + nick = JabberLocalNickFromJID(jid); + } + if (nick != NULL) { + if ((item=JabberListAdd(info->proto, LIST_ROSTER, jid)) != NULL) { + if (item->nick) mir_free(item->nick); + item->nick = nick; + if ((hContact=JabberHContactFromJID(info->proto, jid)) == NULL) { + // Received roster has a new JID. + // Add the jid (with empty resource) to Miranda contact list. + hContact = JabberDBCreateContact(info->proto, jid, nick, FALSE); + } + DBWriteContactSettingString(hContact, "CList", "MyHandle", nick); + if (item->group) mir_free(item->group); + if ((groupNode=JabberXmlGetChild(itemNode, "group"))!=NULL && groupNode->text!=NULL) { + item->group = TlenGroupDecode(groupNode->text); + JabberContactListCreateGroup(item->group); + DBWriteContactSettingString(hContact, "CList", "Group", item->group); + } + else { + item->group = NULL; + DBDeleteContactSetting(hContact, "CList", "Group"); + } + if (!strcmp(str, "none") || (!strcmp(str, "from") && strchr(jid, '@')!=NULL)) { + if (DBGetContactSettingWord(hContact, info->proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) + DBWriteContactSettingWord(hContact, info->proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE); + } + } + else { + mir_free(nick); + } + } + } + if ((item=JabberListGetItemPtr(info->proto, LIST_ROSTER, jid)) != NULL) { + if (!strcmp(str, "both")) item->subscription = SUB_BOTH; + else if (!strcmp(str, "to")) item->subscription = SUB_TO; + else if (!strcmp(str, "from")) item->subscription = SUB_FROM; + else item->subscription = SUB_NONE; + JabberLog(info->proto, "Roster push for jid=%s, set subscription to %s", jid, str); + // subscription = remove is to remove from roster list + // but we will just set the contact to offline and not actually + // remove, so that history will be retained. + if (!strcmp(str, "remove")) { + if ((hContact=JabberHContactFromJID(info->proto, jid)) != NULL) { + if (DBGetContactSettingWord(hContact, info->proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) + DBWriteContactSettingWord(hContact, info->proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE); + JabberListRemove(info->proto, LIST_ROSTER, jid); + } + } + } + } + } + } + } + } + + } + // RECVED: proto, node); + } + // RECVED: proto, node); + } else if ( !strcmp( xmlns, "jabber:iq:version" )) { + TlenIqResultVersion(info->proto, node); + } else if ( !strcmp( xmlns, "jabber:iq:info" )) { + TlenIqResultInfo(info->proto, node); + } + } else { + char *from; + if (( from=JabberXmlGetAttrValue( node, "from" )) != NULL ) { + if ( !strcmp(from, "tcfg" )) { + TlenIqResultTcfg(info->proto, node); + } + } + } + } + // RECVED: ... + else if (!strcmp(type, "error")) { + JABBER_LIST_ITEM *item; + // Check for multi-user chat errors + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strstr(from, "@c")!=NULL || !strcmp(from, "c")) { + TlenMUCRecvError(info->proto, from, node); + return; + } + } + + // Check for file transfer deny by comparing idStr with ft->iqId + i = 0; + while ((i=JabberListFindNext(info->proto, LIST_FILE, i)) >= 0) { + item = JabberListGetItemPtrFromIndex(info->proto,i); + if (item->ft->state==FT_CONNECTING && !strcmp(idStr, item->ft->iqId)) { + item->ft->state = FT_DENIED; + if (item->ft->hFileEvent != NULL) + SetEvent(item->ft->hFileEvent); // Simulate the termination of file server connection + } + i++; + } + } + // RECVED: ... + else if (!strcmp(type, "1")) { // Chat groups list result + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strcmp(from, "c")==0) { + TlenIqResultChatGroups(info->proto, node); + } + } + } + else if (!strcmp(type, "2")) { // Chat rooms list result + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strcmp(from, "c")==0) { + TlenIqResultChatRooms(info->proto, node); + } + } + } else if (!strcmp(type, "3")) { // room search result - result to iq type 3 query + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strcmp(from, "c")==0) { + TlenIqResultRoomSearch(info->proto, node); + } + } + } else if (!strcmp(type, "4")) { // chat room users list + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strstr(from, "@c")!=NULL) { + TlenIqResultChatRoomUsers(info->proto, node); + } + } + } else if (!strcmp(type, "5")) { // room name & group & flags info - sent on joining the room + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strstr(from, "@c")!=NULL) { + TlenIqResultRoomInfo(info->proto, node); + } + } + } else if (!strcmp(type, "6")) { // new nick registered + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strcmp(from, "c")==0) { + TlenIqResultUserNicks(info->proto, node); + } + } + } else if (!strcmp(type, "7")) { // user nicknames list + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strcmp(from, "c")==0) { + TlenIqResultUserNicks(info->proto, node); + } + } + } else if (!strcmp(type, "8")) { // user chat rooms list + char *from; + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (strcmp(from, "c")==0) { + TlenIqResultUserRooms(info->proto, node); + } + } + } +} + +/* + * Web messages + */ +static void TlenProcessW(XmlNode *node, ThreadData *info) +{ + HANDLE hContact; + CCSDATA ccs; + PROTORECVEVENT recv; + char *f, *e, *s, *body; + char *str, *localMessage; + int strSize; + + if (!node->name || strcmp(node->name, "w")) return; + if ((body=node->text) == NULL) return; + + if ((f=JabberXmlGetAttrValue(node, "f")) != NULL) { + + char webContactName[128]; + sprintf(webContactName, Translate("%s Web Messages"), info->proto->iface.m_szProtoName); + if ((hContact=JabberHContactFromJID(info->proto, webContactName)) == NULL) { + hContact = JabberDBCreateContact(info->proto, webContactName, webContactName, TRUE); + } + + s = JabberXmlGetAttrValue(node, "s"); + e = JabberXmlGetAttrValue(node, "e"); + + str = NULL; + strSize = 0; + JabberStringAppend(&str, &strSize, "%s\r\n%s: ", Translate("Web message"), Translate("From")); + + if (f != NULL) + JabberStringAppend(&str, &strSize, "%s", f); + JabberStringAppend(&str, &strSize, "\r\n%s: ", Translate("E-mail")); + if (e != NULL) + JabberStringAppend(&str, &strSize, "%s", e); + JabberStringAppend(&str, &strSize, "\r\n\r\n%s", body); + + localMessage = JabberTextDecode(str); + + recv.flags = 0; + recv.timestamp = (DWORD) time(NULL); + recv.szMessage = localMessage; + recv.lParam = 0; + ccs.hContact = hContact; + ccs.wParam = 0; + ccs.szProtoService = PSR_MESSAGE; + ccs.lParam = (LPARAM) &recv; + CallService(MS_PROTO_CHAINRECV, 0, (LPARAM) &ccs); + + mir_free(localMessage); + mir_free(str); + } +} + +/* + * Typing notification, multi-user conference messages and invitations + */ +static void TlenProcessM(XmlNode *node, ThreadData *info) +{ + HANDLE hContact; + CCSDATA ccs; + PROTORECVEVENT recv; + char *f;//, *from;//username + char *tp;//typing start/stop + char *p, *n, *r, *s, *str, *localMessage; + int i; + XmlNode *xNode, *invNode, *bNode, *subjectNode; + + if (!node->name || strcmp(node->name, "m")) return; + + if ((f=JabberXmlGetAttrValue(node, "f")) != NULL) { + char *fLogin = JabberLoginFromJID(f); + if ((hContact=JabberHContactFromJID(info->proto, fLogin)) != NULL) { + if ((tp=JabberXmlGetAttrValue(node, "tp")) != NULL) { + JABBER_LIST_ITEM *item = JabberListGetItemPtr(info->proto, LIST_ROSTER, fLogin); + if(!strcmp(tp, "t")) { //contact is writing + if (item!=NULL ) { + item->isTyping = TRUE; + CallService(MS_PROTO_CONTACTISTYPING, (WPARAM)hContact, (LPARAM)PROTOTYPE_CONTACTTYPING_INFINITE); + } + } + else if(!strcmp(tp, "u")) {//contact stopped writing + if (item!=NULL) { + item->isTyping = FALSE; + CallService(MS_PROTO_CONTACTISTYPING, (WPARAM)hContact, (LPARAM)PROTOTYPE_CONTACTTYPING_OFF); + } + } + else if(!strcmp(tp, "a")) {//alert was received + int bAlert = TRUE; + if (info->proto->tlenOptions.alertPolicy == TLEN_ALERTS_IGNORE_ALL) { + bAlert = FALSE; + } else if (info->proto->tlenOptions.alertPolicy == TLEN_ALERTS_IGNORE_NIR) { + bAlert = IsAuthorized(info->proto, fLogin); + } + if (bAlert) { + if (info->proto->tlenOptions.useNudge) { + NotifyEventHooks(info->proto->hTlenNudge,(WPARAM) hContact,0); + } else { + if (info->proto->tlenOptions.logAlerts) { + TlenLogMessage(info->proto, hContact, 0, Translate("An alert has been received.")); + } + SkinPlaySound("TlenAlertNotify"); + } + } + } + } + } + mir_free(fLogin); + if ((p=strchr(f, '@')) != NULL) { + if ((p=strchr(p, '/'))!=NULL && p[1]!='\0') { // message from user + time_t timestamp; + s = JabberXmlGetAttrValue(node, "s"); + if (s != NULL) { + timestamp = TlenTimeToUTC(atol(s)); + if (timestamp > time(NULL)) { + timestamp = time(NULL); + } + } else { + timestamp = time(NULL); + } + tp=JabberXmlGetAttrValue(node, "tp"); + bNode = JabberXmlGetChild(node, "b"); + f = JabberTextDecode(f); + if (bNode != NULL && bNode->text != NULL) { + if (tp != NULL && !strcmp(tp, "p")) { + /* MUC private message */ + str = JabberResourceFromJID(f); + hContact = JabberDBCreateContact(info->proto, f, str, TRUE); + DBWriteContactSettingByte(hContact, info->proto->iface.m_szModuleName, "bChat", TRUE); + mir_free(str); + localMessage = JabberTextDecode(bNode->text); + recv.flags = 0; + recv.timestamp = (DWORD) timestamp; + recv.szMessage = localMessage; + recv.lParam = 0; + ccs.hContact = hContact; + ccs.wParam = 0; + ccs.szProtoService = PSR_MESSAGE; + ccs.lParam = (LPARAM) &recv; + CallService(MS_PROTO_CHAINRECV, 0, (LPARAM) &ccs); + mir_free(localMessage); + } else { + /* MUC message */ + TlenMUCRecvMessage(info->proto, f, timestamp, bNode); + } + } + mir_free(f); + } else { // message from chat room (system) + subjectNode = JabberXmlGetChild(node, "subject"); + if (subjectNode != NULL) { + f = JabberTextDecode(f); + localMessage = ""; + if (subjectNode->text!=NULL) { + localMessage = subjectNode->text; + } + localMessage = JabberTextDecode(localMessage); + TlenMUCRecvTopic(info->proto, f, localMessage); + mir_free(localMessage); + mir_free(f); + } + } + } + i=1; + while ((xNode=JabberXmlGetNthChild(node, "x", i)) != NULL) { + invNode=JabberXmlGetChild(xNode, "inv"); + if (invNode != NULL) { + r = JabberTextDecode(f); + f = JabberXmlGetAttrValue(invNode, "f"); + f = JabberTextDecode(f); + n = JabberXmlGetAttrValue(invNode, "n"); + if (n!=NULL && strstr(r, n)!=r) { + n = JabberTextDecode(n); + } else { + n = mir_strdup(Translate("Private conference")); + //n = JabberNickFromJID(r); + } + TlenMUCRecvInvitation(info->proto, r, n, f, ""); + mir_free(n); + mir_free(r); + mir_free(f); + break; + } + i++; + } + } +} + +static void TlenMailPopup(TlenProtocol *proto, char *title, char *emailInfo) +{ + POPUPDATAEX ppd; + char * lpzContactName; + char * lpzText; + + if (!DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "MailPopupEnabled", TRUE)) { + return; + } + lpzContactName = title; + lpzText = emailInfo; + ZeroMemory(&ppd, sizeof(ppd)); + ppd.lchContact = NULL; + ppd.lchIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_MAIL)); + strcpy(ppd.lpzContactName, lpzContactName); + strcpy(ppd.lpzText, lpzText); + ppd.colorBack = DBGetContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupBack", 0); + ppd.colorText = DBGetContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupText", 0); + ppd.PluginWindowProc = NULL; + ppd.PluginData=NULL; + if ( ServiceExists( MS_POPUP_ADDPOPUPEX )) { + BYTE delayMode; + int delay; + delayMode = DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "MailPopupDelayMode", 0); + delay = 0; + if (delayMode==1) { + delay = DBGetContactSettingDword(NULL, proto->iface.m_szModuleName, "MailPopupDelay", 4); + } else if (delayMode==2) { + delay = -1; + } + ppd.iSeconds = delay; + CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0); + + } + else if ( ServiceExists( MS_POPUP_ADDPOPUP )) { + CallService(MS_POPUP_ADDPOPUP, (WPARAM)&ppd, 0); + } +} +/* + * Incoming e-mail notification + */ +static void TlenProcessN(XmlNode *node, ThreadData *info) +{ + char *f, *s; + char *str, *popupTitle, *popupText; + int strSize; + + if (!node->name || strcmp(node->name, "n")) return; + + s = JabberXmlGetAttrValue(node, "s"); + f = JabberXmlGetAttrValue(node, "f"); + if (s != NULL && f!=NULL) { + str = NULL; + strSize = 0; + + JabberStringAppend(&str, &strSize, Translate("%s mail"), info->proto->iface.m_szProtoName); + popupTitle = JabberTextDecode(str); + mir_free(str); + + str = NULL; + strSize = 0; + + JabberStringAppend(&str, &strSize, "%s: %s\n", Translate("From"), f); + JabberStringAppend(&str, &strSize, "%s: %s", Translate("Subject"), s); + popupText = JabberTextDecode(str); + TlenMailPopup(info->proto, popupTitle, popupText); + SkinPlaySound("TlenMailNotify"); + + mir_free(popupTitle); + mir_free(popupText); + mir_free(str); + } +} + +/* + * Presence is chat rooms + */ +static void TlenProcessP(XmlNode *node, ThreadData *info) +{ + char jid[512]; + char *f, *id, *tp, *a, *n, *k; + XmlNode *sNode, *xNode, *iNode, *kNode; + int status, flags; + + if (!node->name || strcmp(node->name, "p")) return; + + // presence from users in chat room + flags = 0; + status = ID_STATUS_ONLINE; + f = JabberXmlGetAttrValue(node, "f"); + xNode = JabberXmlGetChild(node, "x"); + if (xNode != NULL) { // x subtag present (message from chat room) - change user rights only + char *temp, *iStr; + iNode = JabberXmlGetChild(xNode, "i"); + if (iNode != NULL) { + iStr = JabberXmlGetAttrValue(iNode, "i"); + temp = mir_alloc(strlen(f)+strlen(iStr)+2); + strcpy(temp, f); + strcat(temp, "/"); + strcat(temp, iStr); + f = JabberTextDecode(temp); + mir_free(temp); + node = iNode; + status = 0; + } else { + f = JabberTextDecode(f); + } + } else { + f = JabberTextDecode(f); + } + a = JabberXmlGetAttrValue(node, "z"); + if (a!=NULL) { + if (atoi(a) &1 ) { + flags |= USER_FLAGS_REGISTERED; + } + } + a = JabberXmlGetAttrValue(node, "a"); + if (a!=NULL) { + if (atoi(a) == 2) { + flags |= USER_FLAGS_ADMIN; + } + if (atoi(a) == 1) { + flags |= USER_FLAGS_OWNER; + } + if (atoi(a) == 3) { + //flags |= USER_FLAGS_MEMBER; + } + if (atoi(a) == 5) { + flags |= USER_FLAGS_GLOBALOWNER; + } + } + sNode = JabberXmlGetChild(node, "s"); + if (sNode != NULL) { + if (!strcmp(sNode->text, "unavailable")) { + status = ID_STATUS_OFFLINE; + } + } + kNode = JabberXmlGetChild(node, "kick"); + k = NULL; + if (kNode != NULL) { + k = JabberXmlGetAttrValue(kNode, "r"); + if (k==NULL) { + k = ""; + } + k = JabberTextDecode(k); + } + tp = JabberXmlGetAttrValue(node, "tp"); + if (tp!=NULL && !strcmp(tp, "c")) { // new chat room has just been created + id = JabberXmlGetAttrValue(node, "id"); + if (id != NULL) { + n = JabberXmlGetAttrValue(node, "n"); + if (n!=NULL) { + n = JabberTextDecode(n); + } else { + n = mir_strdup(Translate("Private conference"));// JabberNickFromJID(f); + } + sprintf(jid, "%s/%s", f, info->username); +// if (!DBGetContactSetting(NULL, iface.m_szModuleName, "LoginName", &dbv)) { + // always real username +// sprintf(jid, "%s/%s", f, dbv.pszVal); + TlenMUCCreateWindow(info->proto, f, n, 0, NULL, id); + TlenMUCRecvPresence(info->proto, jid, ID_STATUS_ONLINE, flags, k); +// DBFreeVariant(&dbv); +// } + mir_free(n); + } + } else { + TlenMUCRecvPresence(info->proto, f, status, flags, k); // user presence + } + if (k!=NULL) { + mir_free(k); + } + mir_free(f); +} +/* + * Voice chat + */ +static void TlenProcessV(XmlNode *node, ThreadData *info) +{ + char jid[128]; + JABBER_LIST_ITEM *item; + char *from, *id, *e, *p; +// if (!node->name || strcmp(node->name, "v")) return; + + if ((from=JabberXmlGetAttrValue(node, "f")) != NULL) { + if (strchr(from, '@') == NULL) { + _snprintf(jid, sizeof(jid), "%s@%s", from, info->server); + } else { + _snprintf(jid, sizeof(jid), "%s", from); + } + if ((e=JabberXmlGetAttrValue(node, "e")) != NULL) { + if (!strcmp(e, "1")) { + if ((id=JabberXmlGetAttrValue(node, "i")) != NULL) { + SkinPlaySound("TlenVoiceNotify"); + TlenVoiceAccept(info->proto, id, from); + } + } else if (!strcmp(e, "3")) { + // FILE_RECV : e='3' : invalid transfer error + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { + if (item->ft != NULL) { + HANDLE hEvent = item->ft->hFileEvent; + item->ft->hFileEvent = NULL; + item->ft->state = FT_ERROR; + if (item->ft->s != NULL) { + Netlib_CloseHandle(item->ft->s); + item->ft->s = NULL; + if (hEvent != NULL) { + SetEvent(hEvent); + } + } else { + TlenP2PFreeFileTransfer(item->ft); + } + } else { + JabberListRemove(info->proto, LIST_VOICE, p); + } + } + } + } else if (!strcmp(e, "4")) { + // FILE_SEND : e='4' : File sending request was denied by the remote client + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { + if (!strcmp(item->ft->jid, jid)) { + TlenVoiceCancelAll(info->proto); + //JabberListRemove(info->proto, LIST_VOICE, p); + } + } + } + } else if (!strcmp(e, "5")) { + // FILE_SEND : e='5' : Voice request was accepted + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { + JabberLog(info->proto, "should start voice 1 ? %s ?? %s", jid, item->ft->jid); + if (!strcmp(item->ft->jid, jid)) { + JabberLog(info->proto, "starting voice 1"); + TlenVoiceStart(item->ft, 1); + } + } + } + } else if (!strcmp(e, "6")) { + // FILE_RECV : e='6' : IP and port information to connect to get file + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { + if ((p=JabberXmlGetAttrValue(node, "a")) != NULL) { + item->ft->hostName = mir_strdup(p); + if ((p=JabberXmlGetAttrValue(node, "p")) != NULL) { + item->ft->wPort = atoi(p); + TlenVoiceStart(item->ft, 0); + //JabberForkThread((void (__cdecl *)(void*))TlenVoiceReceiveThread, 0, item->ft); + } + } + } + } + } + else if (!strcmp(e, "7")) { + // FILE_RECV : e='7' : IP and port information to connect to send file + // in case the conection to the given server was not successful + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { + if ((p=JabberXmlGetAttrValue(node, "a")) != NULL) { + if (item->ft->hostName!=NULL) mir_free(item->ft->hostName); + item->ft->hostName = mir_strdup(p); + if ((p=JabberXmlGetAttrValue(node, "p")) != NULL) { + item->ft->wPort = atoi(p); + item->ft->state = FT_SWITCH; + SetEvent(item->ft->hFileEvent); + } + } + } + } + } + else if (!strcmp(e, "8")) { + // FILE_RECV : e='8' : transfer error + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_VOICE, p)) != NULL) { + item->ft->state = FT_ERROR; + SetEvent(item->ft->hFileEvent); + } + } + } + + } + } +} + +static void __cdecl JabberKeepAliveThread(void *ptr) +{ + NETLIBSELECT nls = {0}; + + TlenProtocol *proto = (TlenProtocol *)ptr; + nls.cbSize = sizeof(NETLIBSELECT); + nls.dwTimeout = 60000; // 60000 millisecond (1 minute) + nls.hExceptConns[0] = proto->threadData->s; + for (;;) { + if (CallService(MS_NETLIB_SELECT, 0, (LPARAM) &nls) != 0) + break; + if (proto->tlenOptions.sendKeepAlive) + JabberSend(proto, " \t "); + } + JabberLog(proto, "Exiting KeepAliveThread"); +} + diff --git a/plugins/!NotAdopted/Tlen/jabber_util.c b/plugins/!NotAdopted/Tlen/jabber_util.c new file mode 100644 index 0000000000..1caa390f10 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/jabber_util.c @@ -0,0 +1,635 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" +#include "jabber_list.h" +#include +#include + +HANDLE HookEventObj_Ex(const char *name, TlenProtocol *proto, MIRANDAHOOKOBJ hook) { + proto->hookNum ++; + proto->hHooks = (HANDLE *) mir_realloc(proto->hHooks, sizeof(HANDLE) * (proto->hookNum)); + proto->hHooks[proto->hookNum - 1] = HookEventObj(name, hook, proto); + return proto->hHooks[proto->hookNum - 1] ; +} + +HANDLE CreateServiceFunction_Ex(const char *name, TlenProtocol *proto, MIRANDASERVICEOBJ service) { + proto->serviceNum++; + proto->hServices = (HANDLE *) mir_realloc(proto->hServices, sizeof(HANDLE) * (proto->serviceNum)); + proto->hServices[proto->serviceNum - 1] = CreateServiceFunctionObj(name, service, proto); + return proto->hServices[proto->serviceNum - 1] ; +} + +void UnhookEvents_Ex(TlenProtocol *proto) { + unsigned int i; + for (i=0; ihookNum; ++i) { + if (proto->hHooks[i] != NULL) { + UnhookEvent(proto->hHooks[i]); + } + } + mir_free(proto->hHooks); + proto->hookNum = 0; + proto->hHooks = NULL; +} + +void DestroyServices_Ex(TlenProtocol *proto) { + unsigned int i; + for (i=0; iserviceNum; ++i) { + if (proto->hServices[i] != NULL) { + DestroyServiceFunction(proto->hServices[i]); + } + } + mir_free(proto->hServices); + proto->serviceNum = 0; + proto->hServices = NULL; +} + +void JabberSerialInit(TlenProtocol *proto) +{ + InitializeCriticalSection(&proto->csSerial); + proto->serial = 0; +} + +void JabberSerialUninit(TlenProtocol *proto) +{ + DeleteCriticalSection(&proto->csSerial); +} + +unsigned int JabberSerialNext(TlenProtocol *proto) +{ + unsigned int ret; + + EnterCriticalSection(&proto->csSerial); + ret = proto->serial; + proto->serial++; + LeaveCriticalSection(&proto->csSerial); + return ret; +} + +void JabberLog(TlenProtocol *proto, const char *fmt, ...) +{ +#ifdef ENABLE_LOGGING + char *str; + va_list vararg; + int strsize; + char *text; + char *p, *q; + int extra; + + va_start(vararg, fmt); + str = (char *) mir_alloc(strsize=2048); + while (_vsnprintf(str, strsize, fmt, vararg) == -1) + str = (char *) mir_realloc(str, strsize+=2048); + va_end(vararg); + + extra = 0; + for (p=str; *p!='\0'; p++) + if (*p=='\n' || *p=='\r') + extra++; + text = (char *) mir_alloc(strlen("TLEN")+2+strlen(str)+2+extra); + sprintf(text, "[%s]", "TLEN"); + for (p=str,q=text+strlen(text); *p!='\0'; p++,q++) { + if (*p == '\r') { + *q = '\\'; + *(q+1) = 'r'; + q++; + } + else if (*p == '\n') { + *q = '\\'; + *(q+1) = 'n'; + q++; + } + else + *q = *p; + } + *q = '\n'; + *(q+1) = '\0'; + if (proto->hNetlibUser!=NULL) { + CallService(MS_NETLIB_LOG, (WPARAM) proto->hNetlibUser, (LPARAM) text); + } + //OutputDebugString(text); + mir_free(text); + mir_free(str); +#endif +} + +// Caution: DO NOT use JabberSend() to send binary (non-string) data +int JabberSend(TlenProtocol *proto, const char *fmt, ...) +{ + char *str; + int size; + va_list vararg; + int result = 0; + + EnterCriticalSection(&proto->csSend); + + va_start(vararg,fmt); + size = 512; + str = (char *) mir_alloc(size); + while (_vsnprintf(str, size, fmt, vararg) == -1) { + size += 512; + str = (char *) mir_realloc(str, size); + } + va_end(vararg); + + JabberLog(proto, "SEND:%s", str); + size = (int)strlen(str); + if (proto->threadData != NULL) { + if (proto->threadData->useAES) { + result = JabberWsSendAES(proto, str, size, &proto->threadData->aes_out_context, proto->threadData->aes_out_iv); + } else { + result = JabberWsSend(proto, proto->threadData->s, str, size); + } + } + LeaveCriticalSection(&proto->csSend); + + mir_free(str); + return result; +} + + +char *JabberResourceFromJID(const char *jid) +{ + char *p; + char *nick; + + p=strchr(jid, '/'); + if (p != NULL && p[1]!='\0') { + p++; + if ((nick=(char *) mir_alloc(1+strlen(jid)-(p-jid))) != NULL) { + strncpy(nick, p, strlen(jid)-(p-jid)); + nick[strlen(jid)-(p-jid)] = '\0'; + } + } + else { + nick = mir_strdup(jid); + } + + return nick; +} + +char *JabberNickFromJID(const char *jid) +{ + char *p; + char *nick; + + if ((p=strchr(jid, '@')) == NULL) + p = strchr(jid, '/'); + if (p != NULL) { + if ((nick=(char *) mir_alloc((p-jid)+1)) != NULL) { + strncpy(nick, jid, p-jid); + nick[p-jid] = '\0'; + } + } + else { + nick = mir_strdup(jid); + } + + return nick; +} + +char *JabberLoginFromJID(const char *jid) +{ + char *p; + char *nick; + + p = strchr(jid, '/'); + if (p != NULL) { + if ((nick=(char *) mir_alloc((p-jid)+1)) != NULL) { + strncpy(nick, jid, p-jid); + nick[p-jid] = '\0'; + } + } + else { + nick = mir_strdup(jid); + } + return nick; +} + +char *JabberLocalNickFromJID(const char *jid) +{ + char *p; + char *localNick; + + p = JabberNickFromJID(jid); + localNick = JabberTextDecode(p); + mir_free(p); + return localNick; +} + +char *JabberSha1(char *str) +{ + mir_sha1_ctx sha; + DWORD digest[5]; + char* result; + + if ( str == NULL ) + return NULL; + + mir_sha1_init( &sha ); + mir_sha1_append( &sha, (mir_sha1_byte_t* )str, (int)strlen( str )); + mir_sha1_finish( &sha, (mir_sha1_byte_t* )digest ); + if ((result=(char *)mir_alloc(41)) == NULL) + return NULL; + sprintf(result, "%08x%08x%08x%08x%08x", (int)htonl(digest[0]), (int)htonl(digest[1]), (int)htonl(digest[2]), (int)htonl(digest[3]), (int)htonl(digest[4])); + return result; +} + +char *TlenSha1(char *str, int len) +{ + mir_sha1_ctx sha; + mir_sha1_byte_t digest[20]; + char* result; + int i; + + if ( str == NULL ) + return NULL; + + mir_sha1_init( &sha ); + mir_sha1_append( &sha, (mir_sha1_byte_t* )str, len); + mir_sha1_finish( &sha, digest ); + if (( result=( char* )mir_alloc( 20 )) == NULL ) + return NULL; + for (i=0; i<20; i++) + result[i]=digest[4*(i>>2)+(3-(i&0x3))]; + return result; +} + +char *TlenPasswordHash(const char *str) +{ + int magic1 = 0x50305735, magic2 = 0x12345671, sum = 7; + char *p, *res; + + if (str == NULL) return NULL; + for (p=(char *)str; *p!='\0'; p++) { + if (*p!=' ' && *p!='\t') { + magic1 ^= (((magic1 & 0x3f) + sum) * ((char) *p)) + (magic1 << 8); + magic2 += (magic2 << 8) ^ magic1; + sum += ((char) *p); + } + } + magic1 &= 0x7fffffff; + magic2 &= 0x7fffffff; + res = (char *) mir_alloc(17); + sprintf(res, "%08x%08x", magic1, magic2); + return res; +} + +char *TlenUrlEncode(const char *str) +{ + char *p, *q, *res; + unsigned char c; + + if (str == NULL) return NULL; + res = (char *) mir_alloc(3*strlen(str) + 1); + for (p=(char *)str,q=res; *p!='\0'; p++,q++) { + if (*p == ' ') { + *q = '+'; + } + else if (*p<0x20 || *p>=0x7f || strchr("%&+:'<>\"", *p)!=NULL) { + // Convert first from CP1252 to ISO8859-2 + switch ((unsigned char) *p) { + case 0xa5: c = (unsigned char) 0xa1; break; + case 0x8c: c = (unsigned char) 0xa6; break; + case 0x8f: c = (unsigned char) 0xac; break; + case 0xb9: c = (unsigned char) 0xb1; break; + case 0x9c: c = (unsigned char) 0xb6; break; + case 0x9f: c = (unsigned char) 0xbc; break; + default: c = (unsigned char) *p; break; + } + sprintf(q, "%%%02X", c); + q += 2; + } + else { + *q = *p; + } + } + *q = '\0'; + return res; +} + +void TlenUrlDecode(char *str) +{ + char *p, *q; + unsigned int code; + + if (str == NULL) return; + for (p=q=str; *p!='\0'; p++,q++) { + if (*p == '+') { + *q = ' '; + } + else if (*p=='%' && *(p+1)!='\0' && isxdigit(*(p+1)) && *(p+2)!='\0' && isxdigit(*(p+2))) { + sscanf(p+1, "%2x", &code); + *q = (char) code; + // Convert from ISO8859-2 to CP1252 + switch ((unsigned char) *q) { + case 0xa1: *q = (char) 0xa5; break; + case 0xa6: *q = (char) 0x8c; break; + case 0xac: *q = (char) 0x8f; break; + case 0xb1: *q = (char) 0xb9; break; + case 0xb6: *q = (char) 0x9c; break; + case 0xbc: *q = (char) 0x9f; break; + } + p += 2; + } + else { + *q = *p; + } + } + *q = '\0'; +} + +char * TlenGroupDecode(const char *str) +{ + char *p, *q; + if (str == NULL) return NULL; + p = q = JabberTextDecode(str); + for (; *p!='\0'; p++) { + if (*p == '/') { + *p = '\\'; + } + } + return q; +} + +char * TlenGroupEncode(const char *str) +{ + char *p, *q; + if (str == NULL) return NULL; + p = q = mir_strdup(str); + for (; *p!='\0'; p++) { + if (*p == '\\') { + *p = '/'; + } + } + p = JabberTextEncode(q); + mir_free(q); + return p; +} + +char *JabberTextEncode(const char *str) +{ + char *s1; + + if (str == NULL) return NULL; + if ((s1=TlenUrlEncode(str)) == NULL) + return NULL; + return s1; +} + +char *JabberTextDecode(const char *str) +{ + char *s1; + + if (str == NULL) return NULL; + s1 = mir_strdup(str); + TlenUrlDecode(s1); + return s1; +} + +static char b64table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +char *JabberBase64Encode(const char *buffer, int bufferLen) +{ + int n; + unsigned char igroup[3]; + char *p, *peob; + char *res, *r; + + if (buffer==NULL || bufferLen<=0) return NULL; + if ((res=(char *) mir_alloc((((bufferLen+2)/3)*4) + 1)) == NULL) return NULL; + + for (p=(char*)buffer,peob=p+bufferLen,r=res; p= peob) break; + igroup[n] = (unsigned char) *p; + p++; + } + if (n > 0) { + r[0] = b64table[ igroup[0]>>2 ]; + r[1] = b64table[ ((igroup[0]&3)<<4) | (igroup[1]>>4) ]; + r[2] = b64table[ ((igroup[1]&0xf)<<2) | (igroup[2]>>6) ]; + r[3] = b64table[ igroup[2]&0x3f ]; + if (n < 3) { + r[3] = '='; + if (n < 2) + r[2] = '='; + } + r += 4; + } + } + *r = '\0'; + + return res; +} + +static unsigned char b64rtable[256]; + +char *JabberBase64Decode(const char *str, int *resultLen) +{ + char *res; + unsigned char *p, *r, igroup[4], a[4]; + int n, num, count; + + if (str==NULL || resultLen==NULL) return NULL; + if ((res=(char *) mir_alloc(((strlen(str)+3)/4)*3)) == NULL) return NULL; + + for (n=0; n<256; n++) + b64rtable[n] = (unsigned char) 0x80; + for (n=0; n<26; n++) + b64rtable['A'+n] = n; + for (n=0; n<26; n++) + b64rtable['a'+n] = n + 26; + for (n=0; n<10; n++) + b64rtable['0'+n] = n + 52; + b64rtable['+'] = 62; + b64rtable['/'] = 63; + b64rtable['='] = 0; + count = 0; + for (p=(unsigned char *)str,r=(unsigned char *)res; *p!='\0';) { + for (n=0; n<4; n++) { + if ( *p == '\r' || *p == '\n' ) { + n--; p++; + continue; + } + + if ( *p=='\0' ) { + if ( n == 0 ) + goto LBL_Exit; + mir_free( res ); + return NULL; + } + + if ( b64rtable[*p]==0x80 ) { + mir_free( res ); + return NULL; + } + + a[n] = *p; + igroup[n] = b64rtable[*p]; + p++; + } + r[0] = igroup[0]<<2 | igroup[1]>>4; + r[1] = igroup[1]<<4 | igroup[2]>>2; + r[2] = igroup[2]<<6 | igroup[3]; + r += 3; + num = ( a[2]=='='?1:( a[3]=='='?2:3 )); + count += num; + if ( num < 3 ) break; + } +LBL_Exit: + *resultLen = count; + return res; +} + +/* + * Apply Polish Daylight Saving Time rules to get "DST-unbiased" timestamp + */ + +time_t TlenTimeToUTC(time_t time) { + struct tm *timestamp; + timestamp = gmtime(&time); + if ( (timestamp->tm_mon > 2 && timestamp->tm_mon < 9) || + (timestamp->tm_mon == 2 && timestamp->tm_mday - timestamp->tm_wday >= 25) || + (timestamp->tm_mon == 9 && timestamp->tm_mday - timestamp->tm_wday < 25)) { + //time -= 3600; + } else { + //time += 3600; + } + return time; +} + +time_t JabberIsoToUnixTime(char *stamp) +{ + struct tm timestamp; + char date[9]; + char *p; + int i, y; + time_t t; + + if (stamp == NULL) return (time_t) 0; + + p = stamp; + + // Get the date part + for (i=0; *p!='\0' && i<8 && isdigit(*p); p++,i++) + date[i] = *p; + + // Parse year + if (i == 6) { + // 2-digit year (1970-2069) + y = (date[0]-'0')*10 + (date[1]-'0'); + if (y < 70) y += 100; + } + else if (i == 8) { + // 4-digit year + y = (date[0]-'0')*1000 + (date[1]-'0')*100 + (date[2]-'0')*10 + date[3]-'0'; + y -= 1900; + } + else + return (time_t) 0; + timestamp.tm_year = y; + // Parse month + timestamp.tm_mon = (date[i-4]-'0')*10 + date[i-3]-'0' - 1; + // Parse date + timestamp.tm_mday = (date[i-2]-'0')*10 + date[i-1]-'0'; + + // Skip any date/time delimiter + for (; *p!='\0' && !isdigit(*p); p++); + + // Parse time + if (sscanf(p, "%d:%d:%d", &(timestamp.tm_hour), &(timestamp.tm_min), &(timestamp.tm_sec)) != 3) + return (time_t) 0; + + timestamp.tm_isdst = 0; // DST is already present in _timezone below + _tzset(); + t = mktime(×tamp); + t -= _timezone; + t = TlenTimeToUTC(t); + + if (t >= 0) + return t; + else + return (time_t) 0; +} + +void JabberStringAppend(char **str, int *sizeAlloced, const char *fmt, ...) +{ + va_list vararg; + char *p; + int size, len; + + if (str == NULL) return; + + if (*str==NULL || *sizeAlloced<=0) { + *sizeAlloced = size = 2048; + *str = (char *) mir_alloc(size); + len = 0; + } + else { + len = (int)strlen(*str); + size = *sizeAlloced - (int)strlen(*str); + } + + p = *str + len; + va_start(vararg, fmt); + while (_vsnprintf(p, size, fmt, vararg) == -1) { + size += 2048; + (*sizeAlloced) += 2048; + *str = (char *) mir_realloc(*str, *sizeAlloced); + p = *str + len; + } + va_end(vararg); +} + +int JabberGetPictureType( const char* buf ) +{ + if ( buf != NULL ) { + if ( memcmp( buf, "GIF89", 5 ) == 0 ) return PA_FORMAT_GIF; + if ( memcmp( buf, "\x89PNG", 4 ) == 0 ) return PA_FORMAT_PNG; + if ( memcmp( buf, "BM", 2 ) == 0 ) return PA_FORMAT_BMP; + if ( memcmp( buf, "\xFF\xD8", 2 ) == 0 ) return PA_FORMAT_JPEG; + } + return PA_FORMAT_UNKNOWN; +} + +BOOL IsAuthorized(TlenProtocol *proto, const char *jid) +{ + JABBER_LIST_ITEM *item = JabberListGetItemPtr(proto, LIST_ROSTER, jid); + if (item != NULL) { + return item->subscription == SUB_BOTH || item->subscription == SUB_FROM; + } + return FALSE; +} + + +void TlenLogMessage(TlenProtocol *proto, HANDLE hContact, DWORD flags, const char *message) +{ + int size = (int)strlen(message) + 2; + char *localMessage = (char *)mir_alloc(size); + strcpy(localMessage, message); + localMessage[size - 1] = '\0'; + JabberDBAddEvent(proto, hContact, EVENTTYPE_MESSAGE, flags, (PBYTE)message, (DWORD)size); + mir_free(localMessage); +} diff --git a/plugins/!NotAdopted/Tlen/jabber_ws.c b/plugins/!NotAdopted/Tlen/jabber_ws.c new file mode 100644 index 0000000000..49599fa0e3 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/jabber_ws.c @@ -0,0 +1,159 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" + +BOOL JabberWsInit(TlenProtocol *proto) +{ + NETLIBUSER nlu = {0}; + NETLIBUSERSETTINGS nlus = {0}; + TCHAR name[128]; + + + nlu.cbSize = sizeof(nlu); + nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_HTTPCONNS | NUF_TCHAR; // | NUF_HTTPGATEWAY; + mir_sntprintf( name, SIZEOF(name), TranslateT("%s connection"), proto->iface.m_tszUserName); + nlu.ptszDescriptiveName = name; + nlu.szSettingsModule = proto->iface.m_szModuleName; + proto->hNetlibUser = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) &nlu); + + nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_NOOPTIONS | NUF_TCHAR; + mir_sntprintf( name, SIZEOF(name), TranslateT("%s SOCKS connection"), proto->iface.m_tszUserName); + nlu.ptszDescriptiveName = name; + proto->hFileNetlibUser = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) &nlu); + nlus.cbSize = sizeof(nlus); + nlus.useProxy = 0; + CallService(MS_NETLIB_SETUSERSETTINGS, (WPARAM) proto->hFileNetlibUser, (LPARAM) &nlus); + + return (proto->hNetlibUser!=NULL)?TRUE:FALSE; +} + +void JabberWsUninit(TlenProtocol *proto) +{ + if (proto->hNetlibUser!=NULL) Netlib_CloseHandle(proto->hNetlibUser); + if (proto->hFileNetlibUser!=NULL) Netlib_CloseHandle(proto->hFileNetlibUser); + proto->hNetlibUser = NULL; + proto->hFileNetlibUser = NULL; +} + +JABBER_SOCKET JabberWsConnect(TlenProtocol *proto, char *host, WORD port) +{ + NETLIBOPENCONNECTION nloc = {0}; + + nloc.cbSize = sizeof(NETLIBOPENCONNECTION); //NETLIBOPENCONNECTION_V1_SIZE; + nloc.szHost = host; + nloc.wPort = port; + nloc.flags = 0; + nloc.timeout = 6; + return (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, (WPARAM) proto->hNetlibUser, (LPARAM) &nloc); +} + +int JabberWsSend(TlenProtocol *proto, JABBER_SOCKET s, char *data, int datalen) +{ + int len; + if ((len=Netlib_Send(s, data, datalen, /*MSG_NODUMP|*/MSG_DUMPASTEXT))==SOCKET_ERROR || len!=datalen) { + JabberLog(proto, "Netlib_Send() failed, error=%d", WSAGetLastError()); + return FALSE; + } + return TRUE; +} + +int JabberWsRecv(TlenProtocol *proto, JABBER_SOCKET s, char *data, long datalen) +{ + int ret; + ret = Netlib_Recv(s, data, datalen, /*MSG_NODUMP|*/MSG_DUMPASTEXT); + if(ret == SOCKET_ERROR) { + JabberLog(proto, "Netlib_Recv() failed, error=%d", WSAGetLastError()); + return 0; + } + if(ret == 0) { + JabberLog(proto, "Connection closed gracefully"); + return 0; + } + return ret; +} + + +int JabberWsSendAES(TlenProtocol *proto, char *data, int datalen, aes_context *aes_ctx, unsigned char *aes_iv) +{ + int len, sendlen; + unsigned char aes_input[16]; + unsigned char aes_output[256]; + if (proto->threadData == NULL) { + return FALSE; + } + while (datalen > 0) { + len = 0; + while (datalen > 0 && len < 256) { + int pad = datalen < 16 ? 16 - datalen : 0; + memcpy(aes_input, data, datalen < 16 ? datalen : 16); + memset(aes_input + 16 - pad, ' ', pad); + aes_crypt_cbc(aes_ctx, AES_ENCRYPT, 16, aes_iv, aes_input, aes_output + len); + datalen -= 16; + data += 16; + len += 16; + } + if (len > 0) { + JabberLog(proto, "Sending %d bytes", len); + if ((sendlen=Netlib_Send(proto->threadData->s, (char *)aes_output, len, MSG_NODUMP))==SOCKET_ERROR || len!=sendlen) { + JabberLog(proto, "Netlib_Send() failed, error=%d", WSAGetLastError()); + return FALSE; + } + } + } + return TRUE; +} + +int JabberWsRecvAES(TlenProtocol *proto, char *data, long datalen, aes_context *aes_ctx, unsigned char *aes_iv) +{ + int ret, len = 0, maxlen = datalen; + unsigned char aes_input[16]; + unsigned char *aes_output = (unsigned char *)data; + if (proto->threadData == NULL) { + return 0; + } + for (maxlen = maxlen & ~0xF; maxlen != 0; maxlen = maxlen & 0xF) { + ret = Netlib_Recv(proto->threadData->s, data, maxlen, MSG_NODUMP); + if(ret == SOCKET_ERROR) { + JabberLog(proto, "Netlib_Recv() failed, error=%d", WSAGetLastError()); + return 0; + } + if(ret == 0) { + JabberLog(proto, "Connection closed gracefully"); + return 0; + } + data += ret; + len += ret; + maxlen -= ret; + } + + ret = len; + while (len > 15) { + memcpy(aes_input, aes_output, 16); + aes_crypt_cbc(aes_ctx, AES_DECRYPT, 16, aes_iv, aes_input, aes_output); + aes_output += 16; + len -= 16; + } + return ret; +} + diff --git a/plugins/!NotAdopted/Tlen/jabber_xml.c b/plugins/!NotAdopted/Tlen/jabber_xml.c new file mode 100644 index 0000000000..6925e60eb1 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/jabber_xml.c @@ -0,0 +1,568 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" +#include + +static BOOL JabberXmlProcessElem(XmlState *xmlState, XmlElemType elemType, char *elemText, char *elemAttr); +static void JabberXmlRemoveChild(XmlNode *node, XmlNode *child); + +void JabberXmlInitState(XmlState *xmlState) +{ + if (xmlState == NULL) return; + xmlState->root.name = NULL; + xmlState->root.depth = 0; + xmlState->root.numAttr = 0; + xmlState->root.maxNumAttr = 0; + xmlState->root.attr = NULL; + xmlState->root.numChild = 0; + xmlState->root.maxNumChild = 0; + xmlState->root.child = NULL; + xmlState->root.text = NULL; + xmlState->root.state = NODE_OPEN; + xmlState->callback1_open = NULL; + xmlState->callback1_close = NULL; + xmlState->callback2_open = NULL; + xmlState->callback2_close = NULL; + xmlState->userdata1_open = NULL; + xmlState->userdata1_close = NULL; + xmlState->userdata2_open = NULL; + xmlState->userdata2_close = NULL; +} + +void JabberXmlDestroyState(XmlState *xmlState) +{ + int i; + XmlNode *node; + + if (xmlState == NULL) return; + // Note: cannot use JabberXmlFreeNode() to free xmlState->root + // because it will do mir_free(xmlState->root) which is not freeable. + node = &(xmlState->root); + // Free all children first + for (i=0; inumChild; i++) + JabberXmlFreeNode(node->child[i]); + if (node->child) mir_free(node->child); + // Free all attributes + for (i=0; inumAttr; i++) { + if (node->attr[i]->name) mir_free(node->attr[i]->name); + if (node->attr[i]->value) mir_free(node->attr[i]->value); + mir_free(node->attr[i]); + } + if (node->attr) mir_free(node->attr); + // Free string field + if (node->text) mir_free(node->text); + if (node->name) mir_free(node->name); +} + +BOOL JabberXmlSetCallback(XmlState *xmlState, int depth, XmlElemType type, void (*callback)(), void *userdata) +{ + if (depth==1 && type==ELEM_OPEN) { + xmlState->callback1_open = callback; + xmlState->userdata1_open = userdata; + } + else if (depth==1 && type==ELEM_CLOSE) { + xmlState->callback1_close = callback; + xmlState->userdata1_close = userdata; + } + else if (depth==2 && type==ELEM_OPEN) { + xmlState->callback2_open = callback; + xmlState->userdata2_open = userdata; + } + else if (depth==2 && type==ELEM_CLOSE) { + xmlState->callback2_close = callback; + xmlState->userdata2_close = userdata; + } + else + return FALSE; + + return TRUE; +} + +#define TAG_MAX_LEN 50 +#define ATTR_MAX_LEN 1024 +int JabberXmlParse(XmlState *xmlState, char *buffer, int datalen) +{ + char *p, *q, *r, *eob; + char *str; + int num; + char tag[TAG_MAX_LEN]; + char attr[ATTR_MAX_LEN]; + XmlElemType elemType = 0; + + eob = buffer + datalen; + num = 0; + // Skip leading whitespaces + for (p=buffer; p TAG_MAX_LEN) { +// JabberLog("TAG_MAX_LEN too small, ignore current tag"); + } + else { + if (*(p+1) == '/') { // closing tag + strncpy(tag, p+2, r-(p+2)); + tag[r-(p+2)] = '\0'; + elemType = ELEM_CLOSE; + } + else { + if (*(r-1) == '/') { // single open/close tag + strncpy(tag, p+1, r-(p+1)-1); + tag[r-(p+1)-1] = '\0'; + elemType = ELEM_OPENCLOSE; + } + else { + strncpy(tag, p+1, r-(p+1)); + tag[r-(p+1)] = '\0'; + elemType = ELEM_OPEN; + } + } + for (;r ATTR_MAX_LEN) { +// JabberLog("ATTR_MAX_LEN too small, ignore current tag"); + } + else { + strncpy(attr, r, q-r); + if ((q-r)>0 && attr[q-r-1]=='/') { + attr[q-r-1] = '\0'; + elemType = ELEM_OPENCLOSE; + } + else + attr[q-r] = '\0'; + JabberXmlProcessElem(xmlState, elemType, tag, attr); + } + } + num += (q-p+1); + p = q + 1; + if (elemType==ELEM_CLOSE || elemType==ELEM_OPENCLOSE) { + // Skip whitespaces after end tags + for (; pnumAttr >= node->maxNumAttr) { + node->maxNumAttr = node->numAttr + 20; + node->attr = (XmlAttr **) mir_realloc(node->attr, node->maxNumAttr*sizeof(XmlAttr *)); + } + a = node->attr[node->numAttr] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); + node->numAttr++; + + // Skip possible whitespaces between key and '=' + for (;*p!='\0' && (*p==' ' || *p=='\t'); p++); + + if (*p == '\0') { + a->name = (char *) mir_alloc(klen+1); + strncpy(a->name, kstart, klen); + a->name[klen] = '\0'; + a->value = mir_strdup(""); + break; + } + + if (*p != '=') { + a->name = (char *) mir_alloc(klen+1); + strncpy(a->name, kstart, klen); + a->name[klen] = '\0'; + a->value = mir_strdup(""); + continue; + } + + // Found '=' + p++; + + // Skip possible whitespaces between '=' and value + for (;*p!='\0' && (*p==' ' || *p=='\t'); p++); + + if (*p == '\0') { + a->name = (char *) mir_alloc(klen+1); + strncpy(a->name, kstart, klen); + a->name[klen] = '\0'; + a->value = mir_strdup(""); + break; + } + + // Fetch value + if (*p=='\'' || *p=='"') { + p++; + vstart = p; + for (;*p!='\0' && *p!=*(vstart-1); p++); + vlen = p-vstart; + if (*p != '\0') p++; + } + else { + vstart = p; + for (;*p!='\0' && *p!=' ' && *p!='\t'; p++); + vlen = p-vstart; + } + + a->name = (char *) mir_alloc(klen+1); + strncpy(a->name, kstart, klen); + a->name[klen] = '\0'; + a->value = (char *) mir_alloc(vlen+1); + strncpy(a->value, vstart, vlen); + a->value[vlen] = '\0'; + } +} + +static BOOL JabberXmlProcessElem(XmlState *xmlState, XmlElemType elemType, char *elemText, char *elemAttr) +{ + XmlNode *node, *parentNode, *n; + //BOOL activateCallback = FALSE; + char *text, *attr; + + if (elemText == NULL) return FALSE; + + if (elemType==ELEM_OPEN && !strcmp(elemText, "?xml")) { +// JabberLog("XML: skip tag"); + return TRUE; + } + + // Find active node + node = &(xmlState->root); + parentNode = NULL; + while (node->numChild>0 && node->child[node->numChild-1]->state==NODE_OPEN) { + parentNode = node; + node = node->child[node->numChild-1]; + } + + if (node->state != NODE_OPEN) return FALSE; + + text = mir_strdup(elemText); + + if (elemAttr) + attr = mir_strdup(elemAttr); + else + attr = NULL; + + switch (elemType) { + case ELEM_OPEN: + if (node->numChild >= node->maxNumChild) { + node->maxNumChild = node->numChild + 20; + node->child = (XmlNode **) mir_realloc(node->child, node->maxNumChild*sizeof(XmlNode *)); + } + n = node->child[node->numChild] = (XmlNode *) mir_alloc(sizeof(XmlNode)); + node->numChild++; + n->name = text; + n->depth = node->depth + 1; + n->state = NODE_OPEN; + n->numChild = n->maxNumChild = 0; + n->child = NULL; + n->numAttr = n->maxNumAttr = 0; + n->attr = NULL; + JabberXmlParseAttr(n, attr); + n->text = NULL; + if (n->depth==1 && xmlState->callback1_open!=NULL) + (*(xmlState->callback1_open))(n, xmlState->userdata1_open); + if (n->depth==2 && xmlState->callback2_open!=NULL) + (*xmlState->callback2_open)(n, xmlState->userdata2_open); + break; + case ELEM_OPENCLOSE: + if (node->numChild >= node->maxNumChild) { + node->maxNumChild = node->numChild + 20; + node->child = (XmlNode **) mir_realloc(node->child, node->maxNumChild*sizeof(XmlNode *)); + } + n = node->child[node->numChild] = (XmlNode *) mir_alloc(sizeof(XmlNode)); + node->numChild++; + n->name = text; + n->depth = node->depth + 1; + n->state = NODE_CLOSE; + n->numChild = n->maxNumAttr = 0; + n->child = NULL; + n->numAttr = n->maxNumAttr = 0; + n->attr = NULL; + JabberXmlParseAttr(n, attr); + n->text = NULL; + if (n->depth==1 && xmlState->callback1_close!=NULL) { + (*(xmlState->callback1_close))(n, xmlState->userdata1_close); + JabberXmlRemoveChild(node, n); + } + if (n->depth==2 && xmlState->callback2_close!=NULL) { + (*xmlState->callback2_close)(n, xmlState->userdata2_close); + JabberXmlRemoveChild(node, n); + } + break; + case ELEM_CLOSE: + if (node->name!=NULL && !strcmp(node->name, text)) { + node->state = NODE_CLOSE; + if (node->depth==1 && xmlState->callback1_close!=NULL) { + (*(xmlState->callback1_close))(node, xmlState->userdata1_close); + JabberXmlRemoveChild(parentNode, node); + } + if (node->depth==2 && xmlState->callback2_close!=NULL) { + (*xmlState->callback2_close)(node, xmlState->userdata2_close); + JabberXmlRemoveChild(parentNode, node); + } + mir_free(text); + } + else { +// JabberLog("XML: Closing without opening tag", text); + mir_free(text); + if (attr) mir_free(attr); + return FALSE; + } + break; + case ELEM_TEXT: + node->text = text; + break; + default: + mir_free(text); + if (attr) mir_free(attr); + return FALSE; + } + + if (attr) mir_free(attr); + + return TRUE; +} + +char *JabberXmlGetAttrValue(XmlNode *node, char *key) +{ + int i; + + if (node==NULL || node->numAttr<=0 || key==NULL || strlen(key)<=0) + return NULL; + for (i=0; inumAttr; i++) { + if (node->attr[i]->name && !strcmp(key, node->attr[i]->name)) + return node->attr[i]->value; + } + return NULL; +} + +XmlNode *JabberXmlGetChild(XmlNode *node, char *tag) +{ + return JabberXmlGetNthChild(node, tag, 1); +} + +XmlNode *JabberXmlGetNthChild(XmlNode *node, char *tag, int nth) +{ + int i, num; + + if (node==NULL || node->numChild<=0 || tag==NULL || strlen(tag)<=0 || nth<1) + return NULL; + num = 1; + for (i=0; inumChild; i++) { + if (node->child[i]->name && !strcmp(tag, node->child[i]->name)) { + if (num == nth) { + return node->child[i]; + } + num++; + } + } + return NULL; +} + +XmlNode *JabberXmlGetChildWithGivenAttrValue(XmlNode *node, char *tag, char *attrKey, char *attrValue) +{ + int i; + char *str; + + if (node==NULL || node->numChild<=0 || tag==NULL || strlen(tag)<=0 || attrKey==NULL || strlen(attrKey)<=0 || attrValue==NULL || strlen(attrValue)<=0) + return NULL; + for (i=0; inumChild; i++) { + if (node->child[i]->name && !strcmp(tag, node->child[i]->name)) { + if ((str=JabberXmlGetAttrValue(node->child[i], attrKey)) != NULL) + if (!strcmp(str, attrValue)) + return node->child[i]; + } + } + return NULL; +} + +static void JabberXmlRemoveChild(XmlNode *node, XmlNode *child) +{ + int i; + + if (node==NULL || child==NULL || node->numChild<=0) return; + for (i=0; inumChild; i++) { + if (node->child[i] == child) + break; + } + if (i < node->numChild) { + for (++i; inumChild; i++) + node->child[i-1] = node->child[i]; + node->numChild--; + JabberXmlFreeNode(child); + } +} + +void JabberXmlFreeNode(XmlNode *node) +{ + int i; + + if (node == NULL) return; + // Free all children first + for (i=0; inumChild; i++) + JabberXmlFreeNode(node->child[i]); + if (node->child) mir_free(node->child); + // Free all attributes + for (i=0; inumAttr; i++) { + if (node->attr[i]->name) mir_free(node->attr[i]->name); + if (node->attr[i]->value) mir_free(node->attr[i]->value); + mir_free(node->attr[i]); + } + if (node->attr) mir_free(node->attr); + // Free string field + if (node->text) mir_free(node->text); + if (node->name) mir_free(node->name); + // Free the node itself + mir_free(node); +} + +XmlNode *JabberXmlCopyNode(XmlNode *node) +{ + XmlNode *n; + int i; + + if (node == NULL) return NULL; + n = (XmlNode *) mir_alloc(sizeof(XmlNode)); + // Copy attributes + if (node->numAttr > 0) { + n->attr = (XmlAttr **) mir_alloc(node->numAttr*sizeof(XmlAttr *)); + for (i=0; inumAttr; i++) { + n->attr[i] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); + if (node->attr[i]->name) n->attr[i]->name = mir_strdup(node->attr[i]->name); + else n->attr[i]->name = NULL; + if (node->attr[i]->value) n->attr[i]->value = mir_strdup(node->attr[i]->value); + else n->attr[i]->value = NULL; + } + } + else + n->attr = NULL; + // Recursively copy children + if (node->numChild > 0) { + n->child = (XmlNode **) mir_alloc(node->numChild*sizeof(XmlNode *)); + for (i=0; inumChild; i++) + n->child[i] = JabberXmlCopyNode(node->child[i]); + } + else + n->child = NULL; + // Copy other fields + n->numAttr = node->numAttr; + n->maxNumAttr = node->numAttr; + n->numChild = node->numChild; + n->maxNumChild = node->numChild; + n->depth = node->depth; + n->state = node->state; + n->name = (node->name)?mir_strdup(node->name):NULL; + n->text = (node->text)?mir_strdup(node->text):NULL; + + return n; +} + +XmlNode *JabberXmlCreateNode(char *name) +{ + XmlNode *n; + + if (name == NULL) + return NULL; + + n = (XmlNode *) mir_alloc(sizeof(XmlNode)); + memset(n, 0, sizeof(XmlNode)); + n->name = mir_strdup(name); + return n; +} + +void JabberXmlAddAttr(XmlNode *n, char *name, char *value) +{ + int i; + + if (n==NULL || name==NULL || value==NULL) + return; + + i = n->numAttr; + (n->numAttr)++; + n->attr = (XmlAttr **) mir_realloc(n->attr, sizeof(XmlAttr *) * n->numAttr); + n->attr[i] = (XmlAttr *) mir_alloc(sizeof(XmlAttr)); + n->attr[i]->name = mir_strdup(name); + n->attr[i]->value = mir_strdup(value); +} + +XmlNode *JabberXmlAddChild(XmlNode *n, char *name) +{ + int i; + + if (n==NULL || name==NULL) + return NULL; + + i = n->numChild; + n->numChild++; + n->child = (XmlNode **) mir_realloc(n->child, sizeof(XmlNode *) * n->numChild); + n->child[i] = (XmlNode *) mir_alloc(sizeof(XmlNode)); + memset(n->child[i], 0, sizeof(XmlNode)); + n->child[i]->name = mir_strdup(name); + return n->child[i]; +} + +void JabberXmlAddText(XmlNode *n, char *text) +{ + if (n!=NULL && text!=NULL) { + if (n->text) mir_free(n->text); + n->text = mir_strdup(text); + } +} + diff --git a/plugins/!NotAdopted/Tlen/jabber_xml.h b/plugins/!NotAdopted/Tlen/jabber_xml.h new file mode 100644 index 0000000000..98949b92f6 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/jabber_xml.h @@ -0,0 +1,78 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef _JABBER_XML_H_ +#define _JABBER_XML_H_ + +typedef enum { ELEM_OPEN, ELEM_CLOSE, ELEM_OPENCLOSE, ELEM_TEXT } XmlElemType; +typedef enum { NODE_OPEN, NODE_CLOSE } XmlNodeType; + +typedef struct tagXmlAttr { + char *name; + char *value; +} XmlAttr; + +typedef struct tagXmlNode { + int depth; // depth of the current node (1=root) + char *name; // tag name of the current node + int numAttr; // number of attributes + int maxNumAttr; // internal use (num of slots currently allocated to attr) + XmlAttr **attr; // attribute list + int numChild; // number of direct child nodes + int maxNumChild; // internal use (num of slots currently allocated to child) + struct tagXmlNode **child; // child node list + char *text; + XmlNodeType state; // internal use by parser +} XmlNode; + +typedef struct tagXmlState { + XmlNode root; // root is the document (depth = 0); + // callback for depth=n element on opening/closing + void (*callback1_open)(); + void (*callback1_close)(); + void (*callback2_open)(); + void (*callback2_close)(); + void *userdata1_open; + void *userdata1_close; + void *userdata2_open; + void *userdata2_close; +} XmlState; + +void JabberXmlInitState(XmlState *xmlState); +void JabberXmlDestroyState(XmlState *xmlState); +BOOL JabberXmlSetCallback(XmlState *xmlState, int depth, XmlElemType type, void (*callback)(), void *userdata); +int JabberXmlParse(XmlState *xmlState, char *buffer, int datalen); +char *JabberXmlGetAttrValue(XmlNode *node, char *key); +XmlNode *JabberXmlGetChild(XmlNode *node, char *tag); +XmlNode *JabberXmlGetNthChild(XmlNode *node, char *tag, int nth); +XmlNode *JabberXmlGetChildWithGivenAttrValue(XmlNode *node, char *tag, char *attrKey, char *attrValue); +void JabberXmlFreeNode(XmlNode *node); +XmlNode *JabberXmlCopyNode(XmlNode *node); + +XmlNode *JabberXmlCreateNode(char *name); +void JabberXmlAddAttr(XmlNode *n, char *name, char *value); +XmlNode *JabberXmlAddChild(XmlNode *n, char *name); +void JabberXmlAddText(XmlNode *n, char *text); + +#endif + diff --git a/plugins/!NotAdopted/Tlen/resource.h b/plugins/!NotAdopted/Tlen/resource.h new file mode 100644 index 0000000000..f3a350630e --- /dev/null +++ b/plugins/!NotAdopted/Tlen/resource.h @@ -0,0 +1,147 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Tlen.rc +// + +#define IDI_TLEN 100 +#define IDI_MAIL 101 +#define IDI_MUC 102 +#define IDI_CHATS 103 +#define IDI_GRANT 104 +#define IDI_REQUEST 105 +#define IDI_VOICE 106 +#define IDI_MICROPHONE 107 +#define IDI_SPEAKER 108 +#define IDI_IMAGE 109 + +#define IDD_OPTIONS_BASIC 151 +#define IDD_OPTIONS_VOICE 152 +#define IDD_OPTIONS_POPUPS 153 +#define IDD_OPTIONS_ADVANCED 154 +#define IDD_USER_INFO 155 +#define IDD_USER_VCARD 156 +#define IDD_PASSWORD 157 +#define IDD_ADVSEARCH 158 +#define IDD_VOICE 159 +#define IDD_ACCEPT_VOICE 160 +#define IDD_USER_CHANGEAVATAR 161 +#define IDD_ACCMGRUI 162 + +#define IDC_TABS 1000 +#define IDC_EDIT_USERNAME 1001 +#define IDC_SAVE 1002 +#define IDC_EDIT_PASSWORD 1003 +#define IDC_EDIT_LOGIN_SERVER 1004 +#define IDC_INFO_JID 1007 +#define IDC_INFO_RESOURCE 1008 +#define IDC_SHOW_OFFLINE 1012 +#define IDC_OFFLINE_MESSAGE 1013 +#define IDC_OFFLINE_MESSAGE_OPTION 1014 +#define IDC_VISIBILITY_SUPPORT 1015 +#define IDC_NUDGE_SUPPORT 1016 +#define IDC_LOG_ALERTS 1017 + +#define IDC_SUBSCRIPTION 1039 +#define IDC_REGISTERACCOUNT 1040 +#define IDC_SIMPLE 1041 +#define IDC_KEEPALIVE 1042 +#define IDC_HOST 1043 +#define IDC_HOSTPORT 1044 +#define IDC_USE_SSL 1045 +#define IDC_SAVEPASSWORD 1048 +#define IDC_ROSTER_ALERTS 1049 +#define IDC_PASSWORD 1050 +#define IDC_RECONNECT 1050 +#define IDC_JID 1051 +#define IDC_ROSTER_SYNC 1052 +#define IDC_ALERT_POLICY 1053 +#define IDC_MUC_POLICY 1054 +#define IDC_VOICE_POLICY 1055 +#define IDC_IGNORE_ADVERTISEMENTS 1056 +#define IDC_AVATARS 1057 +#define IDC_VERSIONINFO 1058 +#define IDC_IMAGE_POLICY 1059 +#define IDC_CITY 1060 +#define IDC_FULLNAME 1061 +#define IDC_NICKNAME 1062 +#define IDC_FIRSTNAME 1063 +#define IDC_LASTNAME 1064 +#define IDC_BIRTH 1065 +#define IDC_AGE 1065 +#define IDC_OCCUPATION 1066 +#define IDC_EMAIL 1073 +#define IDC_GENDER 1096 +#define IDC_VOICECONVERSATIONS 1097 +#define IDC_PUBLICSTATUS 1098 +#define IDC_VCQUALITY 1100 +#define IDC_VUMETERIN 1101 +#define IDC_VUMETEROUT 1102 +#define IDC_BYTESIN 1103 +#define IDC_BYTESOUT 1104 +#define IDC_MICROPHONE 1105 +#define IDC_SPEAKER 1106 +#define IDC_ACCEPT 1107 + +#define IDC_FILE_PROXY_TYPE_LABEL 1108 +#define IDC_FILE_PROXY_TYPE 1109 +#define IDC_FILE_PROXY_HOST_LABEL 1110 +#define IDC_FILE_PROXY_HOST 1111 +#define IDC_FILE_PROXY_PORT_LABEL 1112 +#define IDC_FILE_PROXY_PORT 1113 +#define IDC_FILE_PROXY_USE_AUTH 1114 +#define IDC_FILE_PROXY_USER 1115 +#define IDC_FILE_PROXY_USER_LABEL 1116 +#define IDC_FILE_PROXY_PASSWORD_LABEL 1117 +#define IDC_FILE_PROXY_PASSWORD 1118 +#define IDC_FILE_USE_PROXY 1119 +#define IDC_VOICE_DEVICE_IN 1120 +#define IDC_VOICE_DEVICE_OUT 1121 + +#define IDC_MSG_ACK 1124 +#define IDC_SERVER 1125 +#define IDC_NICK 1129 +#define IDC_LIST 1133 +#define IDC_ENTER 1144 +#define IDC_AGEFROM 1152 +#define IDC_AGETO 1153 +#define IDC_LOOKFOR 1154 +#define IDC_SCHOOL 1155 +#define IDC_FROM 1175 +#define IDC_DELAY 1180 +#define IDC_COLORBKG 1181 +#define IDC_COLORTXT 1182 +#define IDC_PREVIEW 1183 +#define IDC_ENABLEPOPUP 1184 +#define IDC_DELAY_PERMANENT 1185 +#define IDC_DELAY_CUSTOM 1186 +#define IDC_DELAY_POPUP 1187 +#define IDC_TLEN 1190 +#define IDC_GENDER_TEXT 1195 +#define IDC_OCCUPATION_TEXT 1199 +#define IDC_LOOKFOR_TEXT 1200 +#define IDC_GROUP 1203 +#define IDC_SOFTWARE 1204 +#define IDC_VERSION 1205 +#define IDC_SYSTEM 1206 +#define IDC_AVATAR 1210 +#define IDC_SETAVATAR 1211 +#define IDC_DELETEAVATAR 1212 +#define IDC_AVATAR_LIST 1213 +#define IDC_OLD_AVATAR 1214 +#define IDC_BROWSEAVATAR 1215 +#define IDC_PUBLICAVATAR 1216 + +#define IDC_STATUS 1414 +#define IDC_PLAN 1415 +#define IDC_PERSONALGROUP 1434 +#define IDC_EXTRAGROUP 1435 +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 190 +#define _APS_NEXT_COMMAND_VALUE 40017 +#define _APS_NEXT_CONTROL_VALUE 1204 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/!NotAdopted/Tlen/tlen.c b/plugins/!NotAdopted/Tlen/tlen.c new file mode 100644 index 0000000000..2f8d860a64 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen.c @@ -0,0 +1,636 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "commons.h" +#include "jabber.h" +#include "tlen_muc.h" +#include "tlen_file.h" +#include "tlen_voice.h" +#include "jabber_list.h" +#include "jabber_iq.h" +#include "resource.h" +#include "tlen_picture.h" +#include +#include +#include +#include +#include +#include "m_mucc.h" +#include "m_updater.h" + + +struct MM_INTERFACE mmi; +struct SHA1_INTERFACE sha1i; +struct MD5_INTERFACE md5i; +struct UTF8_INTERFACE utfi; +HINSTANCE hInst; +PLUGINLINK *pluginLink; +HANDLE hMainThread; + +PLUGININFOEX pluginInfoEx = { + sizeof(PLUGININFOEX), +#ifdef _UNICODE +#ifdef _X64 + "Tlen Protocol (x64, Unicode)", +#else + "Tlen Protocol (Unicode)", +#endif +#else + "Tlen Protocol", +#endif + PLUGIN_MAKE_VERSION(TLEN_MAJOR_VERSION,TLEN_MINOR_VERSION,TLEN_RELEASE_NUM,TLEN_BUILD_NUM), + "Tlen protocol plugin for Miranda IM (version: "TLEN_VERSION_STRING" ; compiled: "__DATE__" "__TIME__")", + "Santithorn Bunchua, Adam Strzelecki, Piotr Piastucki", + "the_leech@users.berlios.de", + "(c) 2002-2012 Santithorn Bunchua, Piotr Piastucki", + "http://mtlen.berlios.de", + 0, + 0, +#if defined( _UNICODE ) +#ifdef _X64 + {0x3ba4a3c6, 0x27b5, 0x4c78, { 0x92, 0x8c, 0x38, 0x2a, 0xe1, 0xd3, 0x2a, 0xb5 }} +#else + {0x748f8934, 0x781a, 0x528d, { 0x52, 0x08, 0x00, 0x12, 0x65, 0x40, 0x4a, 0xb3 }} +#endif +#else + {0x11fc3484, 0x475c, 0x11dc, { 0x83, 0x14, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 }} +#endif +}; + +// Main jabber server connection thread global variables + +void TlenLoadOptions(TlenProtocol *proto); +int TlenOptionsInit(void *ptr, WPARAM wParam, LPARAM lParam); +int TlenUserInfoInit(void *ptr, WPARAM wParam, LPARAM lParam); +int TlenSystemModulesLoaded(void *ptr, WPARAM wParam, LPARAM lParam); +extern void TlenInitServicesVTbl(TlenProtocol *proto); +extern int JabberContactDeleted(void *ptr, WPARAM wParam, LPARAM lParam); +extern int JabberDbSettingChanged(void *ptr, WPARAM wParam, LPARAM lParam); + +BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpvReserved) +{ +#ifdef _DEBUG + _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); +#endif + + hInst = hModule; + return TRUE; +} + +__declspec(dllexport) PLUGININFOEX *MirandaPluginInfoEx( DWORD mirandaVersion ) +{ + if ( mirandaVersion < PLUGIN_MAKE_VERSION( 0,8,0,15 )) { + MessageBox( NULL, TranslateT("The Tlen protocol plugin cannot be loaded. It requires Miranda IM 0.8.0.15 or later."), TranslateT("Tlen Protocol Plugin"), MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_TOPMOST ); + return NULL; + } + + return &pluginInfoEx; +} + +extern "C" __declspec(dllexport) const MUUID interfaces[] = {MIID_PROTOCOL, MIID_LAST}; +__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + +struct +{ + TCHAR* szDescr; + char* szName; + int defIconID; + HANDLE hIconLibItem; +} +static iconList[] = +{ + { _T("Protocol icon"), "PROTO", IDI_TLEN }, + { _T("Tlen inbox"), "MAIL", IDI_MAIL }, + { _T("Group chats"), "MUC", IDI_MUC }, + { _T("Tlen chats"), "CHATS", IDI_CHATS }, + { _T("Grant authorization"), "GRANT", IDI_GRANT }, + { _T("Request authorization"),"REQUEST", IDI_REQUEST }, + { _T("Voice chat"), "VOICE", IDI_VOICE }, + { _T("Microphone"), "MICROPHONE", IDI_MICROPHONE }, + { _T("Speaker"), "SPEAKER", IDI_SPEAKER }, + { _T("Send image"), "IMAGE", IDI_IMAGE } +}; + +static HANDLE GetIconHandle(int iconId) { + int i; + for(i = 0; i < SIZEOF(iconList); i++) + if(iconList[i].defIconID == iconId) + return iconList[i].hIconLibItem; + return NULL; +} + +HICON GetIcolibIcon(int iconId) { + HANDLE handle = GetIconHandle(iconId); + if (handle != NULL) { + return (HICON) CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)handle); + } + return NULL; +} + +void ReleaseIcolibIcon(HICON hIcon) { + CallService( MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0 ); +} + +/* +static int TlenIconsChanged(void *ptr, WPARAM wParam, LPARAM lParam) +{ + return 0; +} +*/ + +static void TlenRegisterIcons() +{ + SKINICONDESC sid = { 0 }; + char path[MAX_PATH]; + TCHAR szSectionName[100]; + int i; + mir_sntprintf(szSectionName, SIZEOF( szSectionName ), _T("%s/%s"), _T("Protocols"), _T("Tlen")); + + GetModuleFileNameA(hInst, path, MAX_PATH); + sid.cbSize = sizeof(SKINICONDESC); + sid.cx = sid.cy = 16; + sid.ptszSection = szSectionName; + sid.pszDefaultFile = path; + sid.flags = SIDF_TCHAR; + + for ( i = 0; i < SIZEOF(iconList); i++ ) { + char szSettingName[100]; + mir_snprintf( szSettingName, sizeof( szSettingName ), "TLEN_%s", iconList[i].szName ); + sid.pszName = szSettingName; + sid.pszDescription = (char*)iconList[i].szDescr; + sid.iDefaultIndex = -iconList[i].defIconID; + iconList[i].hIconLibItem = ( HANDLE )CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid); + } +} + +static int TlenPrebuildContactMenu(void *ptr, WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact; + DBVARIANT dbv; + CLISTMENUITEM clmi = {0}; + JABBER_LIST_ITEM *item; + TlenProtocol *proto = (TlenProtocol *)ptr; + clmi.cbSize = sizeof(CLISTMENUITEM); + if ((hContact=(HANDLE) wParam)!=NULL && proto->isOnline) { + if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { + if ((item=JabberListGetItemPtr(proto, LIST_ROSTER, dbv.pszVal)) != NULL) { + if (item->subscription==SUB_NONE || item->subscription==SUB_FROM) + clmi.flags = CMIM_FLAGS; + else + clmi.flags = CMIM_FLAGS|CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuContactRequestAuth, (LPARAM) &clmi); + + if (item->subscription==SUB_NONE || item->subscription==SUB_TO) + clmi.flags = CMIM_FLAGS; + else + clmi.flags = CMIM_FLAGS|CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuContactGrantAuth, (LPARAM) &clmi); + + if (item->status!=ID_STATUS_OFFLINE) + clmi.flags = CMIM_FLAGS; + else + clmi.flags = CMIM_FLAGS|CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuContactMUC, (LPARAM) &clmi); + + if (item->status!=ID_STATUS_OFFLINE && !TlenVoiceIsInUse(proto)) + clmi.flags = CMIM_FLAGS; + else + clmi.flags = CMIM_FLAGS|CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuContactVoice, (LPARAM) &clmi); + + if (item->status!=ID_STATUS_OFFLINE) + clmi.flags = CMIM_FLAGS; + else + clmi.flags = CMIM_FLAGS|CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuPicture, (LPARAM) &clmi); + + DBFreeVariant(&dbv); + return 0; + } + DBFreeVariant(&dbv); + } + } + clmi.flags = CMIM_FLAGS|CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuContactMUC, (LPARAM) &clmi); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuContactVoice, (LPARAM) &clmi); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuContactRequestAuth, (LPARAM) &clmi); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuContactGrantAuth, (LPARAM) &clmi); + return 0; +} + +INT_PTR TlenContactMenuHandleRequestAuth(void *ptr, WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact; + DBVARIANT dbv; + TlenProtocol *proto = (TlenProtocol *)ptr; + if ((hContact=(HANDLE) wParam)!=NULL && proto->isOnline) { + if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { + JabberSend(proto, "", dbv.pszVal); + DBFreeVariant(&dbv); + } + } + return 0; +} + +INT_PTR TlenContactMenuHandleGrantAuth(void *ptr, WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact; + DBVARIANT dbv; + TlenProtocol *proto = (TlenProtocol *)ptr; + if ((hContact=(HANDLE) wParam)!=NULL && proto->isOnline) { + if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { + JabberSend(proto, "", dbv.pszVal); + DBFreeVariant(&dbv); + } + } + return 0; +} + +INT_PTR TlenContactMenuHandleSendPicture(void *ptr, WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact; + TlenProtocol *proto = (TlenProtocol *)ptr; + if ((hContact=(HANDLE) wParam)!=NULL && proto->isOnline) { + SendPicture(proto, hContact); + } + return 0; +} + +INT_PTR TlenMenuHandleInbox(void *ptr, WPARAM wParam, LPARAM lParam) +{ + char szFileName[ MAX_PATH ]; + DBVARIANT dbv; + NETLIBHTTPREQUEST req; + NETLIBHTTPHEADER headers[2]; + NETLIBHTTPREQUEST *resp; + char *login = NULL, *password = NULL; + char form[1024]; + char cookie[1024]; + TlenProtocol *proto = (TlenProtocol *)ptr; + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginName", &dbv)) { + login = mir_strdup(dbv.pszVal); + DBFreeVariant(&dbv); + } + if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "SavePassword", TRUE) == TRUE) { + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "Password", &dbv)) { + CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); + password = mir_strdup(dbv.pszVal); + DBFreeVariant(&dbv); + } + } else if (proto->threadData != NULL && strlen(proto->threadData->password) > 0) { + password = mir_strdup(proto->threadData->password); + } + + ZeroMemory(&cookie, sizeof(cookie)); + if (login != NULL && password != NULL) { + mir_snprintf( form, SIZEOF(form), "username=%s&password=%s", login, password); + headers[0].szName = "Content-Type"; + headers[0].szValue = "application/x-www-form-urlencoded"; + ZeroMemory(&req, sizeof(req)); + req.cbSize = sizeof(req); + req.requestType = REQUEST_POST; + req.flags = 0; + req.headersCount = 1; + req.headers = headers; + req.pData = form; + req.dataLength = (int)strlen(form); + req.szUrl = "http://poczta.o2.pl/login.html"; + resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)proto->hNetlibUser, (LPARAM)&req); + if (resp != NULL) { + if (resp->resultCode/100==2 || resp->resultCode == 302) { + int i; + for (i=0; iheadersCount; i++ ) { + if (strcmpi(resp->headers[i].szName, "Set-Cookie")==0) { + char *start = strstr(resp->headers[i].szValue, "ssid="); + if (start != NULL) { + char *end = strstr(resp->headers[i].szValue, ";"); + start = start + 5; + if (end == NULL) { + end = resp->headers[i].szValue + strlen(resp->headers[i].szValue); + } + strncpy(cookie, start, (end - start)); + break; + } + } + } + } + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); + } + } + mir_free(login); + mir_free(password); + _snprintf(szFileName, sizeof(szFileName), "http://poczta.o2.pl/login.html?sid=%s", cookie); + CallService(MS_UTILS_OPENURL, (WPARAM) 1, (LPARAM) szFileName); + return 0; +} + +int TlenOnModulesLoaded(void *ptr, WPARAM wParam, LPARAM lParam) { + + char str[128]; + TlenProtocol *proto = (TlenProtocol *)ptr; + /* Set all contacts to offline */ + HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact != NULL) { + char *szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if(szProto!=NULL && !strcmp(szProto, proto->iface.m_szModuleName)) { + if (DBGetContactSettingWord(hContact, proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) { + DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE); + } + } + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); + } + TlenMUCInit(proto); + sprintf(str, "%s", Translate("Incoming mail")); + SkinAddNewSoundEx("TlenMailNotify", proto->iface.m_szProtoName, str); + sprintf(str, "%s", Translate("Alert")); + SkinAddNewSoundEx("TlenAlertNotify", proto->iface.m_szProtoName, str); + sprintf(str, "%s", Translate("Voice chat")); + SkinAddNewSoundEx("TlenVoiceNotify", proto->iface.m_szProtoName, str); + + HookEventObj_Ex(ME_USERINFO_INITIALISE, proto, TlenUserInfoInit); + + return 0; +} + +int TlenPreShutdown(void *ptr, WPARAM wParam, LPARAM lParam) +{ + JabberLog(ptr, "TLEN TlenPreShutdown"); + //TlenProtocol *proto = (TlenProtocol *)ptr; + return 0; +} + + +static void initMenuItems(TlenProtocol *proto) +{ + + char text[_MAX_PATH]; + CLISTMENUITEM mi, clmi; + memset(&mi, 0, sizeof(CLISTMENUITEM)); + mi.cbSize = sizeof(CLISTMENUITEM); + memset(&clmi, 0, sizeof(CLISTMENUITEM)); + clmi.cbSize = sizeof(CLISTMENUITEM); + clmi.flags = CMIM_FLAGS | CMIF_GRAYED; + + mi.pszContactOwner = proto->iface.m_szModuleName; + mi.popupPosition = 500090000; + + strcpy(text, proto->iface.m_szModuleName); + mi.pszService = text; + mi.ptszName = proto->iface.m_tszUserName; + mi.position = -1999901009; + mi.pszPopupName = (char *)-1; + mi.flags = CMIF_ROOTPOPUP | CMIF_TCHAR | CMIF_ICONFROMICOLIB; + mi.icolibItem = GetIconHandle(IDI_TLEN); + proto->hMenuRoot = (HANDLE)CallService( MS_CLIST_ADDMAINMENUITEM, (WPARAM)0, (LPARAM)&mi); + + mi.flags = CMIF_CHILDPOPUP | CMIF_ICONFROMICOLIB; + //mi.pszPopupName = (char *)proto->hMenuRoot; + mi.hParentMenu = (HGENMENU)proto->hMenuRoot; + + proto->hMenuChats = NULL; + if(ServiceExists(MS_MUCC_NEW_WINDOW)) + { + sprintf(text, "%s/MainMenuChats", proto->iface.m_szModuleName); + CreateServiceFunction_Ex(text, proto, TlenMUCMenuHandleChats); + mi.pszName = "Tlen Chats"; + mi.position = 2000050001; + mi.icolibItem = GetIconHandle(IDI_CHATS); + mi.pszService = text; + proto->hMenuChats = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) &mi); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuChats, (LPARAM) &clmi); + } + + // "Multi-User Conference" + sprintf(text, "%s/MainMenuMUC", proto->iface.m_szModuleName); + CreateServiceFunction_Ex(text, proto, TlenMUCMenuHandleMUC); + mi.pszName = "Multi-User Conference"; + mi.position = 2000050002; + mi.icolibItem = GetIconHandle(IDI_MUC); + mi.pszService = text; + proto->hMenuMUC = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) &mi); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) proto->hMenuMUC, (LPARAM) &clmi); + + sprintf(text, "%s/MainMenuInbox", proto->iface.m_szModuleName); + CreateServiceFunction_Ex(text, proto, TlenMenuHandleInbox); + mi.pszName = "Tlen Mail"; + mi.position = 2000050003; + mi.icolibItem = GetIconHandle(IDI_MAIL); + mi.pszService = text; + proto->hMenuInbox = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM) &mi); + + mi.hParentMenu = NULL; + + + // "Send picture" + sprintf(text, "%s/SendPicture", proto->iface.m_szModuleName); + CreateServiceFunction_Ex(text, proto, TlenContactMenuHandleSendPicture); + mi.flags = CMIF_ICONFROMICOLIB; + mi.pszName = "Send picture"; + mi.position = -2000019030; + mi.icolibItem = GetIconHandle(IDI_IMAGE); + mi.pszService = text; + proto->hMenuPicture = (HANDLE) CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM) &mi); + + // "Invite to MUC" + sprintf(text, "%s/ContactMenuMUC", proto->iface.m_szModuleName); + CreateServiceFunction_Ex(text, proto, TlenMUCContactMenuHandleMUC); + mi.pszName = "Multi-User Conference"; + mi.position = -2000019020; + mi.icolibItem = GetIconHandle(IDI_MUC); + mi.pszService = text; + proto->hMenuContactMUC = (HANDLE) CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM) &mi); + + // "Invite to voice chat" + sprintf(text, "%s/ContactMenuVoice", proto->iface.m_szModuleName); + CreateServiceFunction_Ex(text, proto, TlenVoiceContactMenuHandleVoice); + mi.pszName = "Voice Chat"; + mi.position = -2000019010; + mi.icolibItem = GetIconHandle(IDI_VOICE); + mi.pszService = text; + proto->hMenuContactVoice = (HANDLE) CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM) &mi); + + // "Request authorization" + sprintf(text, "%s/RequestAuth", proto->iface.m_szModuleName); + CreateServiceFunction_Ex(text, proto, TlenContactMenuHandleRequestAuth); + mi.pszName = "Request authorization"; + mi.position = -2000001001; + mi.icolibItem = GetIconHandle(IDI_REQUEST); + mi.pszService = text; + proto->hMenuContactRequestAuth = (HANDLE) CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM) &mi); + + // "Grant authorization" + sprintf(text, "%s/GrantAuth", proto->iface.m_szModuleName); + CreateServiceFunction_Ex(text, proto, TlenContactMenuHandleGrantAuth); + mi.pszName = "Grant authorization"; + mi.position = -2000001000; + mi.icolibItem = GetIconHandle(IDI_GRANT); + mi.pszService = text; + proto->hMenuContactGrantAuth = (HANDLE) CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM) &mi); +} + +static void uninitMenuItems(TlenProtocol *proto) { + CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM)proto->hMenuChats, (LPARAM) 0); + CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM)proto->hMenuMUC, (LPARAM) 0); + CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM)proto->hMenuInbox, (LPARAM) 0); + CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM)proto->hMenuRoot, (LPARAM) 0); + CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)proto->hMenuContactMUC, (LPARAM) 0); + CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)proto->hMenuPicture, (LPARAM) 0); + CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)proto->hMenuContactVoice, (LPARAM) 0); + CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)proto->hMenuContactRequestAuth, (LPARAM) 0); + CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)proto->hMenuContactGrantAuth, (LPARAM) 0); +} + + +static TlenProtocol *tlenProtoInit( const char* pszProtoName, const TCHAR* tszUserName ) +{ + DBVARIANT dbv; + char text[_MAX_PATH]; + TlenProtocol *proto = (TlenProtocol *)mir_alloc(sizeof(TlenProtocol)); + memset(proto, 0, sizeof(TlenProtocol)); + proto->iface.m_tszUserName = mir_tstrdup( tszUserName ); + proto->iface.m_szModuleName = mir_strdup(pszProtoName); + proto->iface.m_szProtoName = mir_strdup(pszProtoName); + _strlwr( proto->iface.m_szProtoName ); + proto->iface.m_szProtoName[0] = toupper( proto->iface.m_szProtoName[0] ); + proto->iface.m_iStatus = ID_STATUS_OFFLINE; + TlenInitServicesVTbl(proto); + + InitializeCriticalSection(&proto->modeMsgMutex); + InitializeCriticalSection(&proto->csSend); + + sprintf(text, "%s/%s", proto->iface.m_szModuleName, "Nudge"); + proto->hTlenNudge = CreateHookableEvent(text); + + HookEventObj_Ex(ME_SYSTEM_MODULESLOADED, proto, TlenSystemModulesLoaded); + HookEventObj_Ex(ME_OPT_INITIALISE, proto, TlenOptionsInit); + HookEventObj_Ex(ME_DB_CONTACT_SETTINGCHANGED, proto, JabberDbSettingChanged); + HookEventObj_Ex(ME_DB_CONTACT_DELETED, proto, JabberContactDeleted); + HookEventObj_Ex(ME_CLIST_PREBUILDCONTACTMENU, proto, TlenPrebuildContactMenu); +// HookEventObj_Ex(ME_SKIN2_ICONSCHANGED, proto, TlenIconsChanged); + HookEventObj_Ex(ME_SYSTEM_PRESHUTDOWN, proto, TlenPreShutdown); + + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { + DBFreeVariant(&dbv); + } else { + DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "LoginServer", "tlen.pl"); + } + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "ManualHost", &dbv)) { + DBFreeVariant(&dbv); + } else { + DBWriteContactSettingString(NULL, proto->iface.m_szModuleName, "ManualHost", "s1.tlen.pl"); + } + + TlenLoadOptions(proto); + + JabberWsInit(proto); + JabberSerialInit(proto); + JabberIqInit(proto); + JabberListInit(proto); + + return proto; +} + +int TlenSystemModulesLoaded(void *ptr, WPARAM wParam, LPARAM lParam) +{ + + TlenProtocol *proto = (TlenProtocol *)ptr; + initMenuItems(proto); + + // updater plugin support + if(ServiceExists(MS_UPDATE_REGISTERFL)) + { + PLUGININFO* pluginInfoPtr = (PLUGININFO*)&pluginInfoEx; + #ifdef _UNICODE + #ifdef _X64 + CallService(MS_UPDATE_REGISTERFL, (WPARAM)4435, (LPARAM)pluginInfoPtr); //x64 version + #else + CallService(MS_UPDATE_REGISTERFL, (WPARAM)4405, (LPARAM)pluginInfoPtr); //Unicode version + #endif + #else + CallService(MS_UPDATE_REGISTERFL, (WPARAM)4404, (LPARAM)pluginInfoPtr); //ANSI version + #endif + } + + return 0; +} + +static int tlenProtoUninit( TlenProtocol *proto ) +{ + uninitMenuItems(proto); + TlenVoiceCancelAll(proto); + TlenFileCancelAll(proto); + if (proto->hTlenNudge) + DestroyHookableEvent(proto->hTlenNudge); + UnhookEvents_Ex(proto); + JabberListUninit(proto); + JabberIqUninit(proto); + JabberSerialUninit(proto); + DeleteCriticalSection(&proto->modeMsgMutex); + DeleteCriticalSection(&proto->csSend); + //DestroyServices_Ex(proto); + JabberWsUninit(proto); + mir_free(proto->modeMsgs.szOnline); + mir_free(proto->modeMsgs.szAway); + mir_free(proto->modeMsgs.szNa); + mir_free(proto->modeMsgs.szDnd); + mir_free(proto->modeMsgs.szFreechat); + mir_free(proto->modeMsgs.szInvisible); + mir_free(proto); + return 0; +} + +int __declspec(dllexport) Load(PLUGINLINK *link) +{ + PROTOCOLDESCRIPTOR pd; + + pluginLink = link; + mir_getMMI( &mmi ); + mir_getMD5I( &md5i ); + mir_getSHA1I( &sha1i ); + mir_getUTFI( &utfi ); + + DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hMainThread, THREAD_SET_CONTEXT, FALSE, 0); + + srand((unsigned) time(NULL)); + + TlenRegisterIcons(); + + // Register protocol module + ZeroMemory(&pd, sizeof(PROTOCOLDESCRIPTOR)); + pd.cbSize = sizeof(PROTOCOLDESCRIPTOR); + pd.szName = "TLEN"; + pd.fnInit = ( pfnInitProto )tlenProtoInit; + pd.fnUninit = ( pfnUninitProto )tlenProtoUninit; + pd.type = PROTOTYPE_PROTOCOL; + CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM) &pd); + + return 0; +} + +int __declspec(dllexport) Unload(void) +{ + return 0; +} + diff --git a/plugins/!NotAdopted/Tlen/tlen.rc b/plugins/!NotAdopted/Tlen/tlen.rc new file mode 100644 index 0000000000..ba930c75be --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen.rc @@ -0,0 +1,439 @@ +#include "resource.h" +#include "commons.h" +#ifdef __MINGW32__ + #define WINVER 0x500 + #define _WIN32_IE 0x500 +#endif +#include +#ifndef IDC_STATIC +#define IDC_STATIC (-1) +#endif +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif +#ifdef APSTUDIO_INVOKED + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ACCMGRUI DIALOGEX 0, 0, 186, 134 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "Username:",IDC_STATIC,0,14,38,12,SS_CENTERIMAGE + EDITTEXT IDC_EDIT_USERNAME,65,14,115,12,ES_AUTOHSCROLL + LTEXT "Password:",IDC_STATIC,0,30,38,12,SS_CENTERIMAGE + EDITTEXT IDC_EDIT_PASSWORD,65,30,115,12,ES_PASSWORD | ES_AUTOHSCROLL + CONTROL "Save password",IDC_SAVEPASSWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,46,115,10 + CONTROL "Create new account",IDC_REGISTERACCOUNT,"Hyperlink", + 0x0,0,62,100,8 +END + + +IDD_OPTIONS_BASIC DIALOGEX 0, 0, 304, 200 +STYLE DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX "Tlen",IDC_TLEN,0,0,304,42 + LTEXT "Username:",IDC_STATIC,8,12,52,8 + EDITTEXT IDC_EDIT_USERNAME,70,10,86,12,ES_AUTOHSCROLL + CONTROL "Create new account",IDC_REGISTERACCOUNT,"Hyperlink", + 0x0,170,12,100,8 + LTEXT "Password:",IDC_STATIC,8,26,52,8 + EDITTEXT IDC_EDIT_PASSWORD,70,24,86,12,ES_PASSWORD | + ES_AUTOHSCROLL + CONTROL "Save password",IDC_SAVEPASSWORD,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,170,26,100,10 + GROUPBOX "Options",IDC_SIMPLE,0,44,304,156 + CONTROL "Automatically reconnect after unintentional disconnection", + IDC_RECONNECT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8, 56,239,10 + CONTROL "Leave status message after disconnection", + IDC_OFFLINE_MESSAGE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,8,68,168,10 + COMBOBOX IDC_OFFLINE_MESSAGE_OPTION,190,67,75,140, + CBS_DROPDOWNLIST | WS_TABSTOP + CONTROL "Ignore advertisements", + IDC_IGNORE_ADVERTISEMENTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8, 80,250,10 + CONTROL "Automatically delete contacts not in my roster", + IDC_ROSTER_SYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8, 92,250,10 + CONTROL "Show offline users with status messages as invisible in contact list", + IDC_SHOW_OFFLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 8,104,250,10 + CONTROL "Enable avatars", + IDC_AVATARS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 8,116,250,10 + CONTROL "Send and receive client version information", + IDC_VERSIONINFO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 8,128,250,10 + LTEXT "Alert policy",IDC_STATIC,8,140,70,8 + COMBOBOX IDC_ALERT_POLICY,95,139,190,100, + CBS_DROPDOWNLIST | WS_TABSTOP + CONTROL "Use Nudge plugin", + IDC_NUDGE_SUPPORT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 24,153,120,10 + CONTROL "Log alerts as messages", + IDC_LOG_ALERTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 150,153,130,10 + LTEXT "Group chat policy",IDC_STATIC,8,168,70,8 + COMBOBOX IDC_MUC_POLICY,95,166,190,100, + CBS_DROPDOWNLIST | WS_TABSTOP + LTEXT "Image transfer policy",IDC_STATIC,8,183,70,8 + COMBOBOX IDC_IMAGE_POLICY,95,181,190,100, + CBS_DROPDOWNLIST | WS_TABSTOP +END + + +IDD_OPTIONS_VOICE DIALOGEX 0, 0, 304, 200 +STYLE DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX "Voice Chats",IDC_STATIC,0,0,304,57 + LTEXT "Voice chat policy",IDC_STATIC,8,12,70,8 + COMBOBOX IDC_VOICE_POLICY,95,10,190,100, + CBS_DROPDOWNLIST | WS_TABSTOP + LTEXT "Recording device:",IDC_STATIC,8,26,105,8 + COMBOBOX IDC_VOICE_DEVICE_IN,120,24,110,100,CBS_DROPDOWNLIST | + WS_TABSTOP + LTEXT "Playback device:",IDC_STATIC,8,40,105,8 + COMBOBOX IDC_VOICE_DEVICE_OUT,120,38,110,100,CBS_DROPDOWNLIST | + WS_TABSTOP +END + +IDD_OPTIONS_ADVANCED DIALOGEX 0, 0, 304, 200 +STYLE DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX "Expert Options",IDC_STATIC,0,0,304,74 + LTEXT "Login server:",IDC_STATIC,8,18,75,8 + EDITTEXT IDC_EDIT_LOGIN_SERVER,90,16,90,12,ES_AUTOHSCROLL + LTEXT "Connection Host:",IDC_STATIC,8,32,75,8 + EDITTEXT IDC_HOST,90,30,90,12,ES_AUTOHSCROLL | WS_DISABLED + LTEXT "Port:",IDC_STATIC,194,32,35,8 + EDITTEXT IDC_HOSTPORT,230,30,26,12,ES_AUTOHSCROLL | ES_NUMBER | + WS_DISABLED + CONTROL "Keep connection alive",IDC_KEEPALIVE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,8,47,250,10 + CONTROL "Enable encryption",IDC_USE_SSL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,8,60,250,10 + + CONTROL "Enable Always Visible and Never Visible", + IDC_VISIBILITY_SUPPORT,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | + WS_TABSTOP,8,60,250,10 + + GROUPBOX "P2P Connections",IDC_STATIC,0,100,304,98 + CONTROL "Use proxy for incoming connections",IDC_FILE_USE_PROXY, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,114,271,10 + LTEXT "Proxy type:",IDC_FILE_PROXY_TYPE_LABEL,10,130,48,8, + WS_DISABLED + COMBOBOX IDC_FILE_PROXY_TYPE,68,128,80,48,CBS_DROPDOWNLIST | + WS_DISABLED | WS_VSCROLL | WS_TABSTOP + LTEXT "Proxy server:",IDC_FILE_PROXY_HOST_LABEL,10,145,48,8, + WS_DISABLED + EDITTEXT IDC_FILE_PROXY_HOST,68,143,80,12,ES_AUTOHSCROLL | + WS_DISABLED | WS_GROUP + LTEXT "Port:",IDC_FILE_PROXY_PORT_LABEL,174,145,25,8, + WS_DISABLED + EDITTEXT IDC_FILE_PROXY_PORT,204,143,30,12,ES_AUTOHSCROLL | + ES_NUMBER | WS_DISABLED + CONTROL "Proxy requires authorization",IDC_FILE_PROXY_USE_AUTH, + "Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,8, + 160,271,10 + LTEXT "Username:",IDC_FILE_PROXY_USER_LABEL,10,176,47,8, + WS_DISABLED + EDITTEXT IDC_FILE_PROXY_USER,68,175,80,12,ES_AUTOHSCROLL | + WS_DISABLED + LTEXT "Password:",IDC_FILE_PROXY_PASSWORD_LABEL,153,176,45,8, + WS_DISABLED + EDITTEXT IDC_FILE_PROXY_PASSWORD,204,175,81,12,ES_PASSWORD | + ES_AUTOHSCROLL | WS_DISABLED + + +END + +IDD_OPTIONS_POPUPS DIALOG DISCARDABLE 0, 0, 304, 143 +STYLE WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + + GROUPBOX "Mail Notification",IDC_STATIC,0,0,304,110 + CONTROL "Enable incoming mail notification",IDC_ENABLEPOPUP, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,12,267,10 + GROUPBOX "Colours",IDC_STATIC,8,26,140,55 + LTEXT "Background",IDC_STATIC,47,43,95,8 + LTEXT "Text",IDC_STATIC,47,62,96,8 + CONTROL "",IDC_COLORBKG,"ColourPicker",WS_TABSTOP,17,41,24,12 + CONTROL "",IDC_COLORTXT,"ColourPicker",WS_TABSTOP,17,59,24,12 + GROUPBOX "Delay",IDC_STATIC,157,26,140,55 + CONTROL "&From PopUp plugin",IDC_DELAY_POPUP,"Button", + BS_AUTORADIOBUTTON,164,40,125,10 + CONTROL "&Custom",IDC_DELAY_CUSTOM,"Button",BS_AUTORADIOBUTTON, + 164,53,98,10 + EDITTEXT IDC_DELAY,267,51,21,14,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "P&ermanent",IDC_DELAY_PERMANENT,"Button", + BS_AUTORADIOBUTTON,164,67,123,10 + PUSHBUTTON "Preview",IDC_PREVIEW,119,90,70,14 +END + +IDD_PASSWORD DIALOG DISCARDABLE 0, 0, 151, 63 +STYLE DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_VISIBLE | WS_CAPTION +CAPTION "Jabber Password" +FONT 8, "MS Shell Dlg" +BEGIN + EDITTEXT IDC_JID,7,7,137,12,ES_READONLY | NOT WS_BORDER | NOT + WS_TABSTOP + EDITTEXT IDC_PASSWORD,7,22,137,12,ES_PASSWORD | ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDOK,23,42,50,14 + PUSHBUTTON "Cancel",IDCANCEL,77,42,50,14 +END + +IDD_USER_VCARD DIALOGEX 0, 0, 222, 140 +STYLE DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "Nick name:",IDC_STATIC,5,8,51,8 + EDITTEXT IDC_NICKNAME,58,6,102,12,ES_AUTOHSCROLL + LTEXT "First name:",IDC_STATIC,5,21,51,8 + EDITTEXT IDC_FIRSTNAME,58,19,102,12,ES_AUTOHSCROLL + LTEXT "Last name:",IDC_STATIC,5,34,51,8 + EDITTEXT IDC_LASTNAME,58,32,102,12,ES_AUTOHSCROLL + LTEXT "E-mail:",IDC_STATIC,5,47,51,8 + EDITTEXT IDC_EMAIL,58,45,102,12,ES_AUTOHSCROLL + LTEXT "Gender:",IDC_STATIC,5,61,51,8 + COMBOBOX IDC_GENDER,58,59,55,52,CBS_DROPDOWN | WS_VSCROLL | + WS_TABSTOP + LTEXT "Year of birth:",IDC_STATIC,120,61,53,8 + EDITTEXT IDC_AGE,176,59,27,12,ES_AUTOHSCROLL + LTEXT "City:",IDC_STATIC,6,75,51,8 + EDITTEXT IDC_CITY,58,73,102,12,ES_AUTOHSCROLL + LTEXT "School:",IDC_STATIC,5,88,51,8 + EDITTEXT IDC_SCHOOL,58,86,102,12,ES_AUTOHSCROLL + LTEXT "Occupation:",IDC_STATIC,5,102,51,8 + COMBOBOX IDC_OCCUPATION,57,100,102,96,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Looking for:",IDC_STATIC,5,116,51,8 + COMBOBOX IDC_LOOKFOR,57,114,102,96,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + CONTROL "Voice chats",IDC_VOICECONVERSATIONS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,5,130,107,10 + CONTROL "Publicly visible status",IDC_PUBLICSTATUS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,112,130,107,10 + PUSHBUTTON "Save changes",IDC_SAVE,164,111,53,16 +END + +IDD_USER_CHANGEAVATAR DIALOGEX 0, 0, 180, 80 +STYLE DS_SETFONT | DS_3DLOOK | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +CAPTION "Avatar" +BEGIN + GROUPBOX "Avatar Options",IDC_STATIC,5,2,170,55 + CONTROL "Public avatar",IDC_PUBLICAVATAR,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,15,15,150,13 + PUSHBUTTON "OK",IDOK,115,62,60,13 +END + + +IDD_USER_INFO DIALOG DISCARDABLE 0, 0, 222, 146 +STYLE DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Tlen login:",IDC_STATIC,5,2,48,8 + EDITTEXT IDC_INFO_JID,53,2,73,12,ES_AUTOHSCROLL | ES_READONLY | + NOT WS_BORDER + LTEXT "Subscription:",IDC_STATIC,5,14,48,8,NOT WS_GROUP + EDITTEXT IDC_SUBSCRIPTION,53,14,131,12,ES_READONLY | NOT WS_BORDER | + NOT WS_TABSTOP + LTEXT "School:",IDC_STATIC,5,44,48,8 + EDITTEXT IDC_SCHOOL,53,44,131,12,ES_AUTOHSCROLL | ES_READONLY | + NOT WS_BORDER + LTEXT "Occupation:",IDC_STATIC,5,56,48,8 + EDITTEXT IDC_OCCUPATION_TEXT,53,56,135,12,ES_AUTOHSCROLL | + ES_READONLY | NOT WS_BORDER + LTEXT "Looking for:",IDC_STATIC,5,68,48,8 + EDITTEXT IDC_LOOKFOR_TEXT,53,68,136,12,ES_AUTOHSCROLL | + ES_READONLY | NOT WS_BORDER + LTEXT "Software:",IDC_STATIC,5,100,48,8 + EDITTEXT IDC_SOFTWARE,54,100,140,12,ES_AUTOHSCROLL | ES_READONLY | + NOT WS_BORDER | NOT WS_TABSTOP + LTEXT "Version:",IDC_STATIC,5,112,48,8 + EDITTEXT IDC_VERSION,54,112,140,12,ES_AUTOHSCROLL | ES_READONLY | + NOT WS_BORDER | NOT WS_TABSTOP + LTEXT "System:",IDC_STATIC,5,124,48,8 + EDITTEXT IDC_SYSTEM,54,124,140,12,ES_AUTOHSCROLL | ES_READONLY | + NOT WS_BORDER | NOT WS_TABSTOP +END + +IDD_ADVSEARCH DIALOGEX 0, 0, 334, 178 +STYLE DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_BORDER +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Personal Information",IDC_PERSONALGROUP,7,7,156,164 + LTEXT "First name:",IDC_STATIC,15,22,50,8 + EDITTEXT IDC_FIRSTNAME,65,20,91,12,ES_AUTOHSCROLL + LTEXT "Last name:",IDC_STATIC,15,37,50,8 + EDITTEXT IDC_LASTNAME,65,35,91,12,ES_AUTOHSCROLL + LTEXT "Nickname:",IDC_STATIC,15,52,50,8 + EDITTEXT IDC_NICK,65,50,91,12,ES_AUTOHSCROLL + LTEXT "E-mail:",IDC_STATIC,15,67,50,8 + EDITTEXT IDC_EMAIL,65,65,91,12,ES_AUTOHSCROLL + LTEXT "Gender:",IDC_STATIC,15,85,50,8 + COMBOBOX IDC_GENDER,65,83,91,51,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Age:",IDC_STATIC,15,100,50,8 + EDITTEXT IDC_AGEFROM,65,98,27,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "to",IDC_STATIC,98,100,21,8 + EDITTEXT IDC_AGETO,123,98,27,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "City:",IDC_STATIC,15,118,50,8 + EDITTEXT IDC_CITY,65,116,91,12,ES_AUTOHSCROLL + LTEXT "Occupation:",IDC_STATIC,15,135,50,8 + COMBOBOX IDC_OCCUPATION,65,133,91,93,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "School:",IDC_STATIC,15,150,50,8 + EDITTEXT IDC_SCHOOL,65,148,91,12,ES_AUTOHSCROLL + GROUPBOX "Extra Search Criterias",IDC_EXTRAGROUP,171,7,156,67 + LTEXT "Status:",IDC_STATIC,177,22,50,8 + COMBOBOX IDC_STATUS,227,20,91,113,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Looking for:",IDC_STATIC,177,37,50,8 + COMBOBOX IDC_LOOKFOR,227,35,91,172,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Plan:",IDC_STATIC,177,52,50,8,WS_DISABLED + COMBOBOX IDC_PLAN,227,50,91,113,CBS_DROPDOWNLIST | WS_DISABLED | + WS_VSCROLL | WS_TABSTOP +END + +IDD_VOICE DIALOG DISCARDABLE 0, 0, 151, 122 +STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | + WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Tlen Voice Chat" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "",IDC_MICROPHONE,"MButtonClass",0x0,12,7,16,16, + 0x18000000L + CONTROL "",IDC_VUMETERIN,"Static",SS_OWNERDRAW,47,10,120,8 + CONTROL "",IDC_SPEAKER,"MButtonClass",0x0,12,29,16,16, + 0x18000000L + CONTROL "",IDC_VUMETEROUT,"Static",SS_OWNERDRAW,47,31,120,8 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,7,53,140,4 + LTEXT "Quality",IDC_STATIC,10,64,45,8 + COMBOBOX IDC_VCQUALITY,55,62,88,100,CBS_DROPDOWNLIST | WS_VSCROLL + LTEXT "In",IDC_STATIC,10,80,25,8 + LTEXT "",IDC_BYTESIN,35,80,30,8 + LTEXT "Out",IDC_STATIC,90,80,25,8 + LTEXT "",IDC_BYTESOUT,115,80,30,8 + EDITTEXT IDC_STATUS,10,91,131,8,ES_CENTER | ES_AUTOHSCROLL | + WS_DISABLED | NOT WS_BORDER + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,7,100,140,4 + PUSHBUTTON "Finish",IDCANCEL,50,106,50,14 +END + +IDD_ACCEPT_VOICE DIALOG DISCARDABLE 0, 0, 210, 70 +STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Tlen Voice Chat Invitation" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "&Accept",IDC_ACCEPT,98,50,50,14 + PUSHBUTTON "Cancel",IDCANCEL,155,50,50,14 + LTEXT "From:",IDC_STATIC,25,24,60,8 + LTEXT "The following invitation to join a voice chat is received.", + IDC_STATIC,3,4,204,8 + EDITTEXT IDC_FROM,85,20,100,12,ES_AUTOHSCROLL | ES_READONLY + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,3,40,203,4 +END + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION TLEN_FILEVERSION_STRING + PRODUCTVERSION TLEN_FILEVERSION_STRING + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041504e3" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "http://mtlen.berlios.de\0" + VALUE "FileDescription", "Tlen Protocol Plugin for Miranda IM\0" + VALUE "FileVersion", TLEN_VERSION_STRING + VALUE "InternalName", "tlen\0" + VALUE "LegalCopyright", "Copyright (c) 2002-2011 Santithorn Bunchua, Piotr Piastucki\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "tlen.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "Tlen Protocol Plugin\0" + VALUE "ProductVersion", TLEN_VERSION_STRING + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x415, 1251 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_TLEN ICON DISCARDABLE "icos/tlen.ico" +IDI_MAIL ICON DISCARDABLE "icos/mail.ico" +IDI_MUC ICON DISCARDABLE "icos/groupchats.ico" +IDI_CHATS ICON DISCARDABLE "icos/tlenchats.ico" +IDI_GRANT ICON DISCARDABLE "icos/auth_grant.ico" +IDI_REQUEST ICON DISCARDABLE "icos/auth_request.ico" +IDI_VOICE ICON DISCARDABLE "icos/voicechat.ico" +IDI_MICROPHONE ICON DISCARDABLE "icos/microphone.ico" +IDI_SPEAKER ICON DISCARDABLE "icos/speaker.ico" +IDI_IMAGE ICON DISCARDABLE "icos/image.ico" +#endif // English (U.S.) resources + + + diff --git a/plugins/!NotAdopted/Tlen/tlen_10.vcxproj b/plugins/!NotAdopted/Tlen/tlen_10.vcxproj new file mode 100644 index 0000000000..606d56b8d8 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_10.vcxproj @@ -0,0 +1,928 @@ +п»ї + + + + Debug Ansi + x64 + + + Debug Unicode + Win32 + + + Debug Unicode + x64 + + + Debug x64 + Win32 + + + Debug Ansi + Win32 + + + Debug x64 + x64 + + + Release Ansi + x64 + + + Release Unicode + Win32 + + + Release Unicode + x64 + + + Release x64 + Win32 + + + Release Ansi + Win32 + + + Release x64 + x64 + + + + tlen + {33276462-8313-4192-8306-13717ECCA60A} + jabber + + + + DynamicLibrary + false + Unicode + Windows7.1SDK + + + DynamicLibrary + false + Unicode + Windows7.1SDK + + + DynamicLibrary + false + Unicode + Windows7.1SDK + + + DynamicLibrary + false + Unicode + Windows7.1SDK + + + DynamicLibrary + false + Unicode + true + Windows7.1SDK + + + DynamicLibrary + false + Unicode + true + Windows7.1SDK + + + DynamicLibrary + false + Unicode + true + Windows7.1SDK + + + DynamicLibrary + false + Unicode + true + Windows7.1SDK + + + DynamicLibrary + false + MultiByte + true + Windows7.1SDK + + + DynamicLibrary + false + MultiByte + true + Windows7.1SDK + + + DynamicLibrary + false + MultiByte + Windows7.1SDK + + + DynamicLibrary + false + MultiByte + Windows7.1SDK + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)/Plugins\ + $(SolutionDir)$(Configuration)/Plugins\ + $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ + $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ + true + true + $(SolutionDir)$(Configuration)/Plugins\ + $(SolutionDir)$(Configuration)/Plugins\ + $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ + $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ + true + true + $(SolutionDir)$(Configuration)/Plugins\ + $(SolutionDir)$(Configuration)/Plugins\ + $(SolutionDir)$(Configuration)/Plugins\ + $(SolutionDir)$(Configuration)/Plugins\ + $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ + $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ + $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ + $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ + true + true + true + true + $(SolutionDir)$(Configuration)/Plugins\ + $(SolutionDir)$(Configuration)/Plugins\ + $(SolutionDir)$(Configuration)/Plugins\ + $(SolutionDir)$(Configuration)/Plugins\ + $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ + $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ + $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ + $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ + true + true + true + true + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/jabber.tlb + + + + + Disabled + ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + + + EnableFastChecks + MultiThreadedDebugDLL + true + + + jabber.h + + + + + Level3 + true + EditAndContinue + Default + 4996;%(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) + true + true + false + + + 0x32500000 + false + + + $(IntDir)$(TargetName).lib + MachineX86 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/jabber.tlb + + + + + Disabled + ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + + + EnableFastChecks + MultiThreadedDebugDLL + true + + + jabber.h + + + + + Level3 + true + ProgramDatabase + Default + 4996;%(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) + true + true + false + + + 0x32500000 + false + + + $(IntDir)$(TargetName).lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/jabber.tlb + + + + + Full + OnlyExplicitInline + Size + true + ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + true + + + MultiThreaded + true + + + jabber.h + + + + + Level3 + true + ProgramDatabase + Default + 4996;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + /ALIGN:4096 /ignore:4108 %(AdditionalOptions) + wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) + true + true + false + + + true + true + UseLinkTimeCodeGeneration + 0x32500000 + false + + + $(IntDir)$(TargetName).lib + MachineX86 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/jabber.tlb + + + + + Full + OnlyExplicitInline + Size + true + ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + true + + + MultiThreaded + true + + + jabber.h + + + + + Level3 + true + ProgramDatabase + Default + 4996;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + /ALIGN:4096 /ignore:4108 %(AdditionalOptions) + wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) + true + true + false + + + true + true + UseLinkTimeCodeGeneration + 0x32500000 + false + + + $(IntDir)$(TargetName).lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/jabber.tlb + + + + + Full + OnlyExplicitInline + Size + true + ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + true + + + MultiThreaded + true + + + jabber.h + AssemblyAndSourceCode + + + Level3 + true + ProgramDatabase + Default + 4996;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + /ALIGN:4096 /ignore:4108 %(AdditionalOptions) + wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) + type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27X86%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies) + true + true + true + UseLinkTimeCodeGeneration + 0x32500000 + false + + + $(IntDir)$(TargetName).lib + MachineX86 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/jabber.tlb + + + + + Full + OnlyExplicitInline + Size + true + ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + true + + + MultiThreaded + true + + + jabber.h + AssemblyAndSourceCode + + + Level3 + true + ProgramDatabase + Default + 4996;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + /ALIGN:4096 /ignore:4108 %(AdditionalOptions) + wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) + type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27X86%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies) + true + true + true + UseLinkTimeCodeGeneration + 0x32500000 + false + + + $(IntDir)$(TargetName).lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/jabber.tlb + + + + + Full + OnlyExplicitInline + Size + true + ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_X64;X64;NDEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + true + + + MultiThreaded + true + + + jabber.h + AssemblyAndSourceCode + + + Level3 + true + ProgramDatabase + Default + 4996;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + /ALIGN:4096 /ignore:4108 %(AdditionalOptions) + wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) + type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27X86%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies) + true + true + true + UseLinkTimeCodeGeneration + 0x32500000 + false + + + $(IntDir)$(TargetName).lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/jabber.tlb + + + + + Full + OnlyExplicitInline + Size + true + ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_X64;X64;NDEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + true + + + MultiThreaded + true + + + jabber.h + AssemblyAndSourceCode + + + Level3 + true + ProgramDatabase + Default + 4996;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + /ALIGN:4096 /ignore:4108 %(AdditionalOptions) + wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) + type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27X86%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies) + true + true + true + UseLinkTimeCodeGeneration + 0x32500000 + false + + + $(IntDir)$(TargetName).lib + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/jabber.tlb + + + + + Disabled + ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + false + + + EnableFastChecks + MultiThreadedDebugDLL + true + Precise + + + jabber.h + + + + + Level3 + true + EditAndContinue + Default + 4996;%(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) + true + true + $(TargetDir)$(TargetName).pdb + false + + + 0x32500000 + false + + + $(IntDir)$(TargetName).lib + MachineX86 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/jabber.tlb + + + + + Disabled + ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + false + + + EnableFastChecks + MultiThreadedDebugDLL + true + Precise + + + jabber.h + + + + + Level3 + true + ProgramDatabase + Default + 4996;%(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) + true + true + $(TargetDir)$(TargetName).pdb + false + + + 0x32500000 + false + + + $(IntDir)$(TargetName).lib + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/jabber.tlb + + + + + Disabled + ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_X64;X64;_DEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + false + + + EnableFastChecks + MultiThreadedDebugDLL + true + Precise + + + jabber.h + + + + + Level3 + true + ProgramDatabase + Default + 4996;%(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) + true + true + $(TargetDir)$(TargetName).pdb + false + + + 0x32500000 + false + + + $(IntDir)$(TargetName).lib + MachineX64 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/jabber.tlb + + + + + Disabled + ../../include;./ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_X64;X64;_DEBUG;_WINDOWS;_USRDLL;JABBER_EXPORTS;%(PreprocessorDefinitions) + false + + + EnableFastChecks + MultiThreadedDebugDLL + true + Precise + + + jabber.h + + + + + Level3 + true + ProgramDatabase + Default + 4996;%(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + wsock32.lib;version.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies) + true + true + $(TargetDir)$(TargetName).pdb + false + + + 0x32500000 + false + + + $(IntDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/!NotAdopted/Tlen/tlen_advsearch.c b/plugins/!NotAdopted/Tlen/tlen_advsearch.c new file mode 100644 index 0000000000..5e3d5465b8 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_advsearch.c @@ -0,0 +1,113 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" +#include "resource.h" + +static void InitComboBox(HWND hwndCombo, JABBER_FIELD_MAP *fieldMap) +{ + int i, n; + + n = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)_T("")); + SendMessage(hwndCombo, CB_SETITEMDATA, n, 0); + SendMessage(hwndCombo, CB_SETCURSEL, n, 0); + for(i=0;;i++) { + if (fieldMap[i].name == NULL) + break; + n = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) TranslateTS(fieldMap[i].name)); + SendMessage(hwndCombo, CB_SETITEMDATA, n, fieldMap[i].id); + } +} + +INT_PTR CALLBACK TlenAdvSearchDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + InitComboBox(GetDlgItem(hwndDlg, IDC_GENDER), tlenFieldGender); + InitComboBox(GetDlgItem(hwndDlg, IDC_LOOKFOR), tlenFieldLookfor); + InitComboBox(GetDlgItem(hwndDlg, IDC_STATUS), tlenFieldStatus); + InitComboBox(GetDlgItem(hwndDlg, IDC_OCCUPATION), tlenFieldOccupation); + InitComboBox(GetDlgItem(hwndDlg, IDC_PLAN), tlenFieldPlan); + return TRUE; + } + return FALSE; +} + +static void FetchField(HWND hwndDlg, UINT idCtrl, char *fieldName, char **str, int *strSize) +{ + char text[512]; + char *localFieldName, *localText; + + if (hwndDlg==NULL || fieldName==NULL || str==NULL || strSize==NULL) + return; + GetDlgItemTextA(hwndDlg, idCtrl, text, sizeof(text)); + if (text[0]) { + if ((localFieldName=JabberTextEncode(fieldName)) != NULL) { + if ((localText=JabberTextEncode(text)) != NULL) { + JabberStringAppend(str, strSize, "<%s>%s", localFieldName, localText, localFieldName); + mir_free(localText); + } + mir_free(localFieldName); + } + } +} + +static void FetchCombo(HWND hwndDlg, UINT idCtrl, char *fieldName, char **str, int *strSize) +{ + int value; + char *localFieldName; + + if (hwndDlg==NULL || fieldName==NULL || str==NULL || strSize==NULL) + return; + value = (int) SendDlgItemMessage(hwndDlg, idCtrl, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, idCtrl, CB_GETCURSEL, 0, 0), 0); + if (value > 0) { + if ((localFieldName=JabberTextEncode(fieldName)) != NULL) { + JabberStringAppend(str, strSize, "<%s>%d", localFieldName, value, localFieldName); + mir_free(localFieldName); + } + } +} + +char *TlenAdvSearchCreateQuery(HWND hwndDlg, int iqId) +{ + char *str; + int strSize; + + if (hwndDlg == NULL) return NULL; + str = NULL; + FetchField(hwndDlg, IDC_FIRSTNAME, "first", &str, &strSize); + FetchField(hwndDlg, IDC_LASTNAME, "last", &str, &strSize); + FetchField(hwndDlg, IDC_NICK, "nick", &str, &strSize); + FetchField(hwndDlg, IDC_EMAIL, "email", &str, &strSize); + FetchCombo(hwndDlg, IDC_GENDER, "s", &str, &strSize); + FetchField(hwndDlg, IDC_AGEFROM, "d", &str, &strSize); + FetchField(hwndDlg, IDC_AGETO, "u", &str, &strSize); + FetchField(hwndDlg, IDC_CITY, "c", &str, &strSize); + FetchCombo(hwndDlg, IDC_OCCUPATION, "j", &str, &strSize); + FetchField(hwndDlg, IDC_SCHOOL, "e", &str, &strSize); + FetchCombo(hwndDlg, IDC_STATUS, "m", &str, &strSize); + FetchCombo(hwndDlg, IDC_LOOKFOR, "r", &str, &strSize); + FetchCombo(hwndDlg, IDC_PLAN, "p", &str, &strSize); + return str; +} diff --git a/plugins/!NotAdopted/Tlen/tlen_avatar.c b/plugins/!NotAdopted/Tlen/tlen_avatar.c new file mode 100644 index 0000000000..e06c793344 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_avatar.c @@ -0,0 +1,422 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include +#include "jabber.h" +#include "jabber_list.h" +#include "tlen_avatar.h" +#include +#include +#include +#include + +/* TlenGetAvatarFileName() - gets a file name for the avatar image */ + +void TlenGetAvatarFileName(TlenProtocol *proto, JABBER_LIST_ITEM *item, char* pszDest, int cbLen) +{ + DWORD dwAttributes; + int tPathLen; + int format = PA_FORMAT_PNG; + char* szFileType; + char *tmpPath = Utils_ReplaceVars( "%miranda_avatarcache%" ); + tPathLen = mir_snprintf( pszDest, cbLen, "%s\\Tlen", tmpPath ); + mir_free(tmpPath); + dwAttributes = GetFileAttributesA( pszDest ); + if ( dwAttributes == 0xffffffff || ( dwAttributes & FILE_ATTRIBUTE_DIRECTORY ) == 0 ) { + CallService( MS_UTILS_CREATEDIRTREE, 0, ( LPARAM )pszDest ); + } + pszDest[ tPathLen++ ] = '\\'; + if (item != NULL) { + format = item->avatarFormat; + } else if (proto->threadData != NULL) { + format = proto->threadData->avatarFormat; + } else { + format = DBGetContactSettingDword(NULL, proto->iface.m_szModuleName, "AvatarFormat", PA_FORMAT_UNKNOWN); + } + szFileType = "png"; + switch(format) { + case PA_FORMAT_JPEG: szFileType = "jpg"; break; + case PA_FORMAT_ICON: szFileType = "ico"; break; + case PA_FORMAT_PNG: szFileType = "png"; break; + case PA_FORMAT_GIF: szFileType = "gif"; break; + case PA_FORMAT_BMP: szFileType = "bmp"; break; + } + if ( item != NULL ) { + char* hash; + hash = JabberSha1(item->jid); + mir_snprintf( pszDest + tPathLen, MAX_PATH - tPathLen, "%s.%s", hash, szFileType ); + mir_free( hash ); + } else { + mir_snprintf( pszDest + tPathLen, MAX_PATH - tPathLen, "%s_avatar.%s", proto->iface.m_szModuleName, szFileType ); + } +} + +static void RemoveAvatar(TlenProtocol *proto, HANDLE hContact) { + char tFileName[ MAX_PATH ]; + if (hContact == NULL) { + proto->threadData->avatarHash[0] = '\0'; + } + TlenGetAvatarFileName( proto, NULL, tFileName, sizeof tFileName ); + DeleteFileA(tFileName); + DBDeleteContactSetting(hContact, "ContactPhoto", "File"); + DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "AvatarHash"); + DBDeleteContactSetting(hContact, proto->iface.m_szModuleName, "AvatarFormat"); + ProtoBroadcastAck(proto->iface.m_szModuleName, NULL, ACKTYPE_AVATAR, ACKRESULT_STATUS, NULL, 0); +} + +static void SetAvatar(TlenProtocol *proto, HANDLE hContact, JABBER_LIST_ITEM *item, char *data, int len, DWORD format) { + FILE* out; + char filename[MAX_PATH]; + char md5[33]; + mir_md5_state_t ctx; + DWORD digest[4]; + + if (format == PA_FORMAT_UNKNOWN && len > 4) { + format = JabberGetPictureType(data); + } + + mir_md5_init( &ctx ); + mir_md5_append( &ctx, ( BYTE* )data, len); + mir_md5_finish( &ctx, ( BYTE* )digest ); + + sprintf( md5, "%08x%08x%08x%08x", (int)htonl(digest[0]), (int)htonl(digest[1]), (int)htonl(digest[2]), (int)htonl(digest[3])); + if (item != NULL) { + char *hash = item->avatarHash; + item->avatarFormat = format; + item->avatarHash = mir_strdup(md5); + mir_free(hash); + } else { + proto->threadData->avatarFormat = format; + strcpy(proto->threadData->avatarHash, md5); + } + TlenGetAvatarFileName(proto, item, filename, sizeof filename ); + DeleteFileA(filename); + out = fopen( filename, "wb" ); + if ( out != NULL ) { + fwrite( data, len, 1, out ); + fclose( out ); + DBWriteContactSettingString(hContact, "ContactPhoto", "File", filename ); + DBWriteContactSettingString(hContact, proto->iface.m_szModuleName, "AvatarHash", md5); + DBWriteContactSettingDword(hContact, proto->iface.m_szModuleName, "AvatarFormat", format); + } + ProtoBroadcastAck( proto->iface.m_szModuleName, hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, NULL , 0); +} + +int TlenProcessAvatarNode(TlenProtocol *proto, XmlNode *avatarNode, JABBER_LIST_ITEM *item) { + XmlNode *aNode; + char *oldHash = NULL; + char *md5 = NULL, *type = NULL; + HANDLE hContact; + hContact = NULL; + if (item != NULL) { + if ((hContact=JabberHContactFromJID(proto, item->jid)) == NULL) return 0; + } + if (item == NULL) { + oldHash = proto->threadData->avatarHash; + } else { + oldHash = item->avatarHash; + } + if (avatarNode != NULL) { + aNode = JabberXmlGetChild(avatarNode, "a"); + if (aNode != NULL) { + type = JabberXmlGetAttrValue(aNode, "type"); + md5 = JabberXmlGetAttrValue(aNode, "md5"); + } + } + if (md5 != NULL) { + /* check contact's avatar hash - md5 */ + if (oldHash == NULL || strcmp(oldHash, md5)) { + if (item != NULL) { + item->newAvatarDownloading = TRUE; + } + TlenGetAvatar(proto, hContact); + return 1; + } + } else { + /* remove avatar */ + if (oldHash != NULL) { + if (item != NULL) { + item->avatarHash = NULL; + mir_free(oldHash); + item->newAvatarDownloading = FALSE; + } + RemoveAvatar(proto, hContact); + return 1; + } + } + return 0; +} + +void TlenProcessPresenceAvatar(TlenProtocol *proto, XmlNode *node, JABBER_LIST_ITEM *item) { + HANDLE hContact; + if ((hContact=JabberHContactFromJID(proto, item->jid)) == NULL) return; + TlenProcessAvatarNode(proto, JabberXmlGetChild(node, "avatar"), item); +} + + +static char *replaceTokens(const char *base, const char *uri, const char *login, const char* token, int type, int access) { + char *result; + int i, l, size; + l = (int)strlen(uri); + size = (int)strlen(base); + for (i = 0; i < l; ) { + if (!strncmp(uri + i, "^login^", 7)) { + size += (int)strlen(login); + i += 7; + } else if (!strncmp(uri + i, "^type^", 6)) { + size++; + i += 6; + } else if (!strncmp(uri + i, "^token^", 7)) { + size += (int)strlen(token); + i += 7; + } else if (!strncmp(uri + i, "^access^", 8)) { + size++; + i += 8; + } else { + size++; + i++; + } + } + result = (char *)mir_alloc(size +1); + strcpy(result, base); + size = (int)strlen(base); + for (i = 0; i < l; ) { + if (!strncmp(uri + i, "^login^", 7)) { + strcpy(result + size, login); + size += (int)strlen(login); + i += 7; + } else if (!strncmp(uri + i, "^type^", 6)) { + result[size++] = '0' + type; + i += 6; + } else if (!strncmp(uri + i, "^token^", 7)) { + strcpy(result + size, token); + size += (int)strlen(token); + i += 7; + } else if (!strncmp(uri + i, "^access^", 8)) { + result[size++] = '0' + access; + i += 8; + } else { + result[size++] = uri[i++]; + } + } + result[size] = '\0'; + return result; +} + + +static int getAvatarMutex = 0; + +typedef struct { + TlenProtocol *proto; + HANDLE hContact; +} TLENGETAVATARTHREADDATA; + +static void TlenGetAvatarThread(void *ptr) { + + JABBER_LIST_ITEM *item = NULL; + NETLIBHTTPREQUEST req; + NETLIBHTTPREQUEST *resp; + TLENGETAVATARTHREADDATA *data = (TLENGETAVATARTHREADDATA *)ptr; + HANDLE hContact = data->hContact; + char *request; + char *login = NULL; + if (hContact != NULL) { + char *jid = JabberJIDFromHContact(data->proto, hContact); + login = JabberNickFromJID(jid); + item = JabberListGetItemPtr(data->proto, LIST_ROSTER, jid); + mir_free(jid); + } else { + login = mir_strdup(data->proto->threadData->username); + } + if ((data->proto->threadData != NULL && hContact == NULL) || item != NULL) { + DWORD format = PA_FORMAT_UNKNOWN; + if (item!= NULL) { + item->newAvatarDownloading = TRUE; + } + request = replaceTokens(data->proto->threadData->tlenConfig.mailBase, data->proto->threadData->tlenConfig.avatarGet, login, data->proto->threadData->avatarToken, 0, 0); + ZeroMemory(&req, sizeof(req)); + req.cbSize = sizeof(req); + req.requestType = data->proto->threadData->tlenConfig.avatarGetMthd; + req.flags = 0; + req.headersCount = 0; + req.headers = NULL; + req.dataLength = 0; + req.szUrl = request; + resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->hNetlibUser, (LPARAM)&req); + if (item!= NULL) { + item->newAvatarDownloading = FALSE; + } + if (resp != NULL) { + if (resp->resultCode/100==2) { + if (resp->dataLength > 0) { + int i; + for (i=0; iheadersCount; i++ ) { + if (strcmpi(resp->headers[i].szName, "Content-Type")==0) { + if (strcmpi(resp->headers[i].szValue, "image/png")==0) { + format = PA_FORMAT_PNG; + } else if (strcmpi(resp->headers[i].szValue, "image/x-png")==0) { + format = PA_FORMAT_PNG; + } else if (strcmpi(resp->headers[i].szValue, "image/jpeg")==0) { + format = PA_FORMAT_JPEG; + } else if (strcmpi(resp->headers[i].szValue, "image/jpg")==0) { + format = PA_FORMAT_JPEG; + } else if (strcmpi(resp->headers[i].szValue, "image/gif")==0) { + format = PA_FORMAT_GIF; + } else if (strcmpi(resp->headers[i].szValue, "image/bmp")==0) { + format = PA_FORMAT_BMP; + } + break; + } + } + SetAvatar(data->proto, hContact, item, resp->pData, resp->dataLength, format); + } else { + RemoveAvatar(data->proto, hContact); + } + } + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)resp); + } + mir_free(request); + mir_free(login); + } + if (hContact == NULL) { + getAvatarMutex = 0; + } + mir_free(data); +} + +void TlenGetAvatar(TlenProtocol *proto, HANDLE hContact) { + if (hContact == NULL) { + if (getAvatarMutex != 0) { + return; + } + getAvatarMutex = 1; + } + { + TLENGETAVATARTHREADDATA *data = (TLENGETAVATARTHREADDATA *)mir_alloc(sizeof(TLENGETAVATARTHREADDATA)); + data->proto = proto; + data->hContact = hContact; + JabberForkThread(TlenGetAvatarThread, 0, data); + } +} + +typedef struct { + TlenProtocol *proto; + NETLIBHTTPREQUEST *req; +}TLENREMOVEAVATARTHREADDATA; + +static void TlenRemoveAvatarRequestThread(void *ptr) { + NETLIBHTTPREQUEST *resp; + TLENREMOVEAVATARTHREADDATA *data = ptr; + NETLIBHTTPREQUEST *req = (NETLIBHTTPREQUEST *)data->req; + resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->hNetlibUser, (LPARAM)req); + mir_free(req->szUrl); + mir_free(req->headers); + mir_free(req->pData); + mir_free(req); + if (resp != NULL) { + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, (WPARAM)0, (LPARAM)resp); + RemoveAvatar(data->proto, NULL); + } + mir_free(data); + +} + +typedef struct { + TlenProtocol *proto; + NETLIBHTTPREQUEST *req; + char *data; + int length; +}TLENUPLOADAVATARTHREADDATA; + +static void TlenUploadAvatarRequestThread(void *ptr) { + NETLIBHTTPREQUEST *resp; + TLENUPLOADAVATARTHREADDATA * data = (TLENUPLOADAVATARTHREADDATA *) ptr; + NETLIBHTTPREQUEST *req = data->req; + resp = (NETLIBHTTPREQUEST *)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)data->proto->hNetlibUser, (LPARAM)req); + if (resp != NULL) { + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, (WPARAM)0, (LPARAM)resp); + SetAvatar(data->proto, NULL, NULL, data->data, data->length, PA_FORMAT_PNG); + } + mir_free(req->szUrl); + mir_free(req->headers); + mir_free(req->pData); + mir_free(req); + mir_free(data->data); + mir_free(data); +} + +void TlenRemoveAvatar(TlenProtocol *proto) { + NETLIBHTTPREQUEST *req; + char *request; + if (proto->threadData != NULL) { + TLENREMOVEAVATARTHREADDATA *data = (TLENREMOVEAVATARTHREADDATA *)mir_alloc(sizeof(TLENREMOVEAVATARTHREADDATA)); + req = (NETLIBHTTPREQUEST *)mir_alloc(sizeof(NETLIBHTTPREQUEST)); + data->proto =proto; + data->req = req; + request = replaceTokens(proto->threadData->tlenConfig.mailBase, proto->threadData->tlenConfig.avatarRemove, "", proto->threadData->avatarToken, 0, 0); + ZeroMemory(req, sizeof(NETLIBHTTPREQUEST)); + req->cbSize = sizeof(NETLIBHTTPREQUEST); + req->requestType = proto->threadData->tlenConfig.avatarGetMthd; + req->szUrl = request; + JabberForkThread(TlenRemoveAvatarRequestThread, 0, data); + } +} + + +void TlenUploadAvatar(TlenProtocol *proto, unsigned char *data, int dataLen, int access) { + NETLIBHTTPREQUEST *req; + NETLIBHTTPHEADER *headers; + TLENUPLOADAVATARTHREADDATA *threadData; + char *request; + unsigned char *buffer; + if (proto->threadData != NULL && dataLen > 0 && data != NULL) { + char *mpartHead = "--AaB03x\r\nContent-Disposition: form-data; name=\"filename\"; filename=\"plik.png\"\r\nContent-Type: image/png\r\n\r\n"; + char *mpartTail = "\r\n--AaB03x--\r\n"; + int size, sizeHead = (int)strlen(mpartHead), sizeTail = (int)strlen(mpartTail); + request = replaceTokens(proto->threadData->tlenConfig.mailBase, proto->threadData->tlenConfig.avatarUpload, "", proto->threadData->avatarToken, 0, access); + threadData = (TLENUPLOADAVATARTHREADDATA *)mir_alloc(sizeof(TLENUPLOADAVATARTHREADDATA)); + threadData->proto = proto; + req = (NETLIBHTTPREQUEST *)mir_alloc(sizeof(NETLIBHTTPREQUEST)); + headers = (NETLIBHTTPHEADER *)mir_alloc(sizeof(NETLIBHTTPHEADER)); + ZeroMemory(req, sizeof(NETLIBHTTPREQUEST)); + req->cbSize = sizeof(NETLIBHTTPREQUEST); + req->requestType = proto->threadData->tlenConfig.avatarUploadMthd; + req->szUrl = request; + req->flags = 0; + headers[0].szName = "Content-Type"; + headers[0].szValue = "multipart/form-data; boundary=AaB03x"; + req->headersCount = 1; + req->headers = headers; + size = dataLen + sizeHead + sizeTail; + buffer = mir_alloc(size); + memcpy(buffer, mpartHead, sizeHead); + memcpy(buffer + sizeHead, data, dataLen); + memcpy(buffer + sizeHead + dataLen, mpartTail, sizeTail); + req->dataLength = size; + req->pData = buffer; + threadData->req = req; + threadData->data = (char *) mir_alloc(dataLen); + memcpy(threadData->data, data, dataLen); + threadData->length = dataLen; + JabberForkThread(TlenUploadAvatarRequestThread, 0, threadData); + } +} + diff --git a/plugins/!NotAdopted/Tlen/tlen_avatar.h b/plugins/!NotAdopted/Tlen/tlen_avatar.h new file mode 100644 index 0000000000..48a258ed38 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_avatar.h @@ -0,0 +1,34 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef _TLEN_AVATAR_H_ +#define _TLEN_AVATAR_H_ + +void TlenProcessPresenceAvatar(TlenProtocol *proto, XmlNode *node, JABBER_LIST_ITEM *item); +int TlenProcessAvatarNode(TlenProtocol *proto, XmlNode *avatarNode, JABBER_LIST_ITEM *item); +void TlenGetAvatarFileName(TlenProtocol *proto, JABBER_LIST_ITEM *item, char* pszDest, int cbLen); +void TlenGetAvatar(TlenProtocol *proto, HANDLE hContact); +void TlenUploadAvatar(TlenProtocol *proto, unsigned char *data, int dataLen, int access); +void TlenRemoveAvatar(TlenProtocol *proto); + +#endif // TLEN_AVATAR_H_INCLUDED diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/AdminWindow.cpp b/plugins/!NotAdopted/Tlen/tlen_czaty/AdminWindow.cpp new file mode 100644 index 0000000000..a29c6fa2f2 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/AdminWindow.cpp @@ -0,0 +1,490 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "AdminWindow.h" +#include "Utils.h" + + +static INT_PTR CALLBACK UserKickDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + int i; + const char *banOptions[]={"No ban", "1 minute", "5 minutes", "15 minutes", "30 minutes", + "1 hour", "6 hours", "1 day", "3 days", "1 week", "2 weeks", "4 weeks"}; + const int banTime[] = {0, 1, 5, 15, 30, 60, 360, 1440, 4320, 10080, 20160, 40320}; + const char *roleOptions[]={"No role", "Member", "Admin", "Moderator"}; + const int roleMask[] = {0, MUCC_EF_USER_MEMBER, MUCC_EF_USER_ADMIN, MUCC_EF_USER_MODERATOR}; + AdminWindow *adminWindow; + adminWindow = (AdminWindow *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + adminWindow = (AdminWindow *) lParam; + TranslateDialogDefault(hwndDlg); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) adminWindow); + adminWindow->setKickTabHWND(hwndDlg); + for (i=0;i<12;i++) { + SendDlgItemMessage(hwndDlg, IDC_KICK_OPTIONS, CB_ADDSTRING, 0, (LPARAM) banOptions[i]); + } + SendDlgItemMessage(hwndDlg, IDC_KICK_OPTIONS, CB_SETCURSEL, 0, 0); + for (i=0;i<3;i++) { + SendDlgItemMessage(hwndDlg, IDC_ROLE_OPTIONS, CB_ADDSTRING, 0, (LPARAM) roleOptions[i]); + } + SendDlgItemMessage(hwndDlg, IDC_ROLE_OPTIONS, CB_SETCURSEL, 0, 0); + SetDlgItemTextA(hwndDlg, IDC_NICK, adminWindow->getNick()); + return FALSE; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + { + char nick[256], reason[256]; + GetDlgItemTextA(hwndDlg, IDC_NICK, nick, sizeof(nick)); + GetDlgItemTextA(hwndDlg, IDC_REASON, reason, sizeof(reason)); + if (strlen(nick)>0) { + int iSel = SendDlgItemMessage(hwndDlg, IDC_KICK_OPTIONS, CB_GETCURSEL, 0, 0); + if (iSel>=0 && iSel<12) { + adminWindow->getParent()->kickAndBan(nick, banTime[iSel] * 60, reason); + } + } + } +// EndDialog(hwndDlg, 1); +// return TRUE; + break; + case IDC_SET_ROLE: + { + char nick[256]; + GetDlgItemTextA(hwndDlg, IDC_NICK, nick, sizeof(nick)); + if (strlen(nick)>0) { + int iSel = SendDlgItemMessage(hwndDlg, IDC_ROLE_OPTIONS, CB_GETCURSEL, 0, 0); + if (iSel>=0 && iSel<3) { + adminWindow->getParent()->setRights(nick, roleMask[iSel]); + } + } + } + break; +// EndDialog(hwndDlg, 1); +// return TRUE; + case IDCANCEL: +// EndDialog(hwndDlg, 0); + return TRUE; + } + break; + case WM_CLOSE: +// EndDialog(hwndDlg, 0); + break; + } + return FALSE; +} + +static INT_PTR CALLBACK UserBrowserDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ int i; + const char *browseOptions[]={"Banned", "Owners", "Administrators", "Members", "Moderators"}; + const int browserFlags[]={MUCC_EF_USER_BANNED, MUCC_EF_USER_OWNER, MUCC_EF_USER_ADMIN, MUCC_EF_USER_MEMBER, MUCC_EF_USER_MODERATOR}; + LVCOLUMN lvCol; + HWND lv; + AdminWindow *adminWindow; + adminWindow = (AdminWindow *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + adminWindow = (AdminWindow *) lParam; + TranslateDialogDefault(hwndDlg); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) adminWindow); + adminWindow->setBrowserTabHWND(hwndDlg); + lv = GetDlgItem(hwndDlg, IDC_LIST); + ListView_SetExtendedListViewStyle(lv, LVS_EX_FULLROWSELECT); + lvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; + lvCol.pszText = TranslateT("Login"); + lvCol.cx = 80; + lvCol.iSubItem = 0; + ListView_InsertColumn(lv, 0, &lvCol); + lvCol.pszText = TranslateT("Nick name"); + lvCol.cx = 80; + lvCol.iSubItem = 1; + ListView_InsertColumn(lv, 1, &lvCol); + lvCol.pszText = TranslateT("When"); + lvCol.cx = 95; + lvCol.iSubItem = 2; + ListView_InsertColumn(lv, 2, &lvCol); + lvCol.pszText = TranslateT("Admin"); + lvCol.cx = 80; + lvCol.iSubItem = 2; + ListView_InsertColumn(lv, 3, &lvCol); + lvCol.pszText = TranslateT("Reason"); + lvCol.cx = 70; + lvCol.iSubItem = 2; + ListView_InsertColumn(lv, 5, &lvCol); + lvCol.pszText = TranslateT("Remaining"); + lvCol.cx = 80; + lvCol.iSubItem = 2; + ListView_InsertColumn(lv, 4, &lvCol); + for (i=0;i<(adminWindow->getParent()->getRoomFlags() & MUCC_EF_ROOM_MEMBERS_ONLY ? 4 : 3);i++) { + SendDlgItemMessage(hwndDlg, IDC_OPTIONS, CB_ADDSTRING, 0, (LPARAM) browseOptions[i]); + } + SendDlgItemMessage(hwndDlg, IDC_OPTIONS, CB_SETCURSEL, 0, 0); + return FALSE; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_SHOW: + int iSel; + iSel = SendDlgItemMessage(hwndDlg, IDC_OPTIONS, CB_GETCURSEL, 0, 0); + if (iSel< 5) { + adminWindow->queryUsers(browserFlags[iSel]); + } + break; +// return TRUE; + case IDCANCEL: +// EndDialog(hwndDlg, 0); + return TRUE; + } + break; + case WM_CLOSE: +// EndDialog(hwndDlg, 0); + break; + case WM_MEASUREITEM: + if (wParam == IDC_LIST) { + MEASUREITEMSTRUCT *lpMis = (MEASUREITEMSTRUCT *) lParam; + lpMis->itemHeight = 16;//GetSystemMetrics(SM_CYSMICON); + return TRUE; + } + break; + case WM_DRAWITEM: + if (wParam == IDC_LIST) { + RECT rc; + int x, w; + TCHAR text[256]; + DRAWITEMSTRUCT *lpDis = (DRAWITEMSTRUCT *) lParam; + switch (lpDis->itemAction) { + default: + case ODA_SELECT: + case ODA_DRAWENTIRE: + if (lpDis->itemState & ODS_SELECTED) { + HBRUSH hBrush = CreateSolidBrush(RGB(0xC2, 0xC8, 0xDA));//0xDAC8C2); + FillRect(lpDis->hDC, &(lpDis->rcItem), hBrush);//(HBRUSH) (COLOR_HIGHLIGHT+1)); + DeleteObject(hBrush); + SetTextColor(lpDis->hDC, 0); + SetBkMode(lpDis->hDC, TRANSPARENT); + } + else { + FillRect(lpDis->hDC, &(lpDis->rcItem), (HBRUSH) (COLOR_WINDOW+1)); + SetTextColor(lpDis->hDC, RGB(0, 0, 0));//GetSysColor(COLOR_WINDOWTEXT)); + SetBkMode(lpDis->hDC, TRANSPARENT); + } + x = lpDis->rcItem.left + 1; + for (int col=0;col<6;col++) { + w = ListView_GetColumnWidth(GetDlgItem(hwndDlg, IDC_LIST), col); + rc.left = x; + rc.top = lpDis->rcItem.top; + rc.bottom = lpDis->rcItem.bottom; + rc.right = x+w-2; + ListView_GetItemText(GetDlgItem(hwndDlg, IDC_LIST), lpDis->itemID, col, text, sizeof(text)/sizeof(TCHAR)); + if (_tcslen(text)==0) { + _tcscpy(text, _TEXT("-")); + } + DrawText(lpDis->hDC, text, (int)_tcslen(text), &rc, DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER); + x+=w; + } + break; + } + } + break; + case WM_NOTIFY: + LPNMHDR pNmhdr; + pNmhdr = (LPNMHDR)lParam; + if (pNmhdr->idFrom == IDC_LIST && adminWindow->getBrowserMode() == MUCC_EF_USER_BANNED) { + switch (pNmhdr->code) { + case NM_RCLICK: + { + LVHITTESTINFO hti; + int hitItem; + hti.pt.x=(short)LOWORD(GetMessagePos()); + hti.pt.y=(short)HIWORD(GetMessagePos()); + ScreenToClient(pNmhdr->hwndFrom, &hti.pt); + if ((hitItem = ListView_HitTest(pNmhdr->hwndFrom,&hti)) !=-1) { + LVITEM lvi = {0}; + HMENU hMenu; + int iSelection; + TCHAR nick[256]; + lvi.mask = TVIF_TEXT; + lvi.iItem = hitItem; + lvi.iSubItem = 0; + lvi.pszText = nick; + lvi.cchTextMax = sizeof(nick)/sizeof(TCHAR); + ListView_GetItem(pNmhdr->hwndFrom, &lvi); + hMenu=GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(IDR_CHATOPTIONS)), 3); + CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)hMenu,0); + iSelection = TrackPopupMenu(hMenu, TPM_RETURNCMD | TPM_TOPALIGN | TPM_LEFTALIGN, (short)LOWORD(GetMessagePos()), (short)HIWORD(GetMessagePos()), 0, hwndDlg, NULL); + DestroyMenu(hMenu); + if (iSelection == ID_USERMENU_UNBAN) { + char* lps1 = Utils::mucc_mir_t2a(nick); + adminWindow->getParent()->unban(lps1); + Utils::mucc_mir_free(lps1); + } + } + + } + break; + } + } + + } + return FALSE; +} + +static INT_PTR CALLBACK AdminDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND hwnd; + TCITEM tci; + HWND tc; + AdminWindow *adminWindow; + adminWindow = (AdminWindow *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + adminWindow = (AdminWindow *) lParam; + TranslateDialogDefault(hwndDlg); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) adminWindow); + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) muccIcon[MUCC_IDI_ADMINISTRATION]); + + hwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_USER_KICK), hwndDlg, UserKickDlgProc, (LPARAM) adminWindow); + SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + ShowWindow(hwnd, SW_SHOW); + + hwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_USER_BROWSER), hwndDlg, UserBrowserDlgProc, (LPARAM) adminWindow); + SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + adminWindow->setCurrentTab(0); + adminWindow->setHWND(hwndDlg); + + tc = GetDlgItem(hwndDlg, IDC_TABS); + tci.mask = TCIF_TEXT; + tci.pszText = TranslateT("Administration"); + TabCtrl_InsertItem(tc, 0, &tci); + tci.pszText = TranslateT("Browser"); + TabCtrl_InsertItem(tc, 1, &tci); + + return FALSE; + case WM_NOTIFY: + switch (wParam) { + case IDC_TABS: + switch (((LPNMHDR) lParam)->code) { + case TCN_SELCHANGE: + switch (adminWindow->getCurrentTab()) { + case 0: + ShowWindow(adminWindow->getKickTabHWND(), SW_HIDE); + break; + case 1: + ShowWindow(adminWindow->getBrowserTabHWND(), SW_HIDE); + break; + } + adminWindow->setCurrentTab(TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_TABS))); + switch (adminWindow->getCurrentTab()) { + case 0: + ShowWindow(adminWindow->getKickTabHWND(), SW_SHOW); + break; + case 1: + ShowWindow(adminWindow->getBrowserTabHWND(), SW_SHOW); + break; + } + break; + } + break; + } + break; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDCANCEL: + delete adminWindow; + // EndDialog(hwndDlg, 0); + return TRUE; + } + break; + case WM_CLOSE: + delete adminWindow; + // EndDialog(hwndDlg, 0); + break; + } + return FALSE; +} + + + +AdminWindow::AdminWindow(ChatWindow *parent, const char *nick, int mode) { + this->parent = parent; + hWnd = NULL; + browserMode = 0; + this->nick = NULL; + Utils::copyString(&this->nick, nick); +} + +AdminWindow::~AdminWindow() { + + if (hWnd != NULL) { + EndDialog(hWnd, 0); + } + if (parent != NULL) { + parent->setAdminWindow(NULL); + } + if (nick != NULL) { + delete nick; + } +} + +void AdminWindow::start() { + DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_USER_ADMIN), NULL, AdminDlgProc, (LPARAM) this); +} + +void AdminWindow::setHWND(HWND hWnd) { + this->hWnd = hWnd; +} + +void AdminWindow::setCurrentTab(int t) { + currentTab = t; +} + +int AdminWindow::getCurrentTab() { + return currentTab; +} + + +void AdminWindow::setKickTabHWND(HWND hWnd) { + hKickTabWnd = hWnd; +} + +void AdminWindow::setBrowserTabHWND(HWND hWnd) { + hBrowserTabWnd = hWnd; +} + +HWND AdminWindow::getKickTabHWND() { + return hKickTabWnd; +} + +HWND AdminWindow::getBrowserTabHWND() { + return hBrowserTabWnd; +} + +void AdminWindow::queryUsers(int queryType) { + MUCCEVENT muce; + EnableWindow(GetDlgItem(getBrowserTabHWND(), IDC_SHOW), FALSE); + muce.cbSize = sizeof(MUCCEVENT); + muce.iType = MUCC_EVENT_QUERY_USERS; + muce.pszModule = parent->getModule(); + muce.pszID = parent->getRoomId(); + muce.dwFlags = queryType; + browserMode = queryType; + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); +} + +ChatWindow * AdminWindow::getParent() { + return parent; +} + +void AdminWindow::queryResultUsers(MUCCQUERYRESULT *queryResult) { + ListView_DeleteAllItems(GetDlgItem(getBrowserTabHWND(), IDC_LIST)); + for (int i=0;iiItemsNum;i++) { + + char timestampStr[100]; + DBTIMETOSTRING dbtts; + LVITEM lvItem; + + lvItem.mask = LVIF_TEXT;// | LVIF_PARAM; + lvItem.iSubItem = 0; + lvItem.iItem = ListView_GetItemCount(GetDlgItem(getBrowserTabHWND(), IDC_LIST)); + lvItem.pszText = Utils::mucc_mir_a2t(queryResult->pItems[i].pszID); + if (lvItem.pszText == NULL) lvItem.pszText = _TEXT(""); +// lvItem.lParam = (LPARAM) room; + ListView_InsertItem(GetDlgItem(getBrowserTabHWND(), IDC_LIST), &lvItem); + Utils::mucc_mir_free(lvItem.pszText); + + lvItem.iSubItem = 1; + lvItem.pszText = Utils::mucc_mir_a2t(queryResult->pItems[i].pszName); + if (lvItem.pszText == NULL) lvItem.pszText = _TEXT(""); + ListView_InsertItem(GetDlgItem(getBrowserTabHWND(), IDC_LIST), &lvItem); + ListView_SetItemText(GetDlgItem(getBrowserTabHWND(), IDC_LIST), lvItem.iItem, lvItem.iSubItem, lvItem.pszText); + Utils::mucc_mir_free(lvItem.pszText); + + lvItem.iSubItem = 2; + dbtts.cbDest = 90; + dbtts.szDest = timestampStr; + dbtts.szFormat = (char *)"d t"; + timestampStr[0]='\0'; + if (queryResult->pItems[i].dwFlags) { + CallService(MS_DB_TIME_TIMESTAMPTOSTRING, (WPARAM)queryResult->pItems[i].dwFlags, (LPARAM) & dbtts); + } + lvItem.pszText = Utils::mucc_mir_a2t(timestampStr); + if (lvItem.pszText == NULL) lvItem.pszText = _TEXT(""); + ListView_InsertItem(GetDlgItem(getBrowserTabHWND(), IDC_LIST), &lvItem); + ListView_SetItemText(GetDlgItem(getBrowserTabHWND(), IDC_LIST), lvItem.iItem, lvItem.iSubItem, lvItem.pszText); + Utils::mucc_mir_free(lvItem.pszText); + + lvItem.iSubItem = 3; + lvItem.pszText = Utils::mucc_mir_a2t(queryResult->pItems[i].pszNick); + if (lvItem.pszText == NULL) lvItem.pszText = _TEXT(""); + ListView_InsertItem(GetDlgItem(getBrowserTabHWND(), IDC_LIST), &lvItem); + ListView_SetItemText(GetDlgItem(getBrowserTabHWND(), IDC_LIST), lvItem.iItem, lvItem.iSubItem, lvItem.pszText); + Utils::mucc_mir_free(lvItem.pszText); + + lvItem.iSubItem = 4; + timestampStr[0] = '\0'; + if (queryResult->pItems[i].iCount > 0) { + int days = queryResult->pItems[i].iCount / (60*60*24); + int hours = (queryResult->pItems[i].iCount % (60*60*24)) / (60*60); + int minutes = (queryResult->pItems[i].iCount % (60*60)) / 60; + int seconds = queryResult->pItems[i].iCount % 60; + if (days != 0) { + sprintf(timestampStr, "%dd%dh%dm%ds", days, hours, minutes, seconds); + } else if (hours != 0) { + sprintf(timestampStr, "%dh%dm%ds", hours, minutes, seconds); + } else if (minutes != 0) { + sprintf(timestampStr, "%dm%ds", minutes, seconds); + } else { + sprintf(timestampStr, "%ds", seconds); + } + } + lvItem.pszText = Utils::mucc_mir_a2t(timestampStr); + if (lvItem.pszText == NULL) lvItem.pszText = _TEXT(""); + ListView_InsertItem(GetDlgItem(getBrowserTabHWND(), IDC_LIST), &lvItem); + ListView_SetItemText(GetDlgItem(getBrowserTabHWND(), IDC_LIST), lvItem.iItem, lvItem.iSubItem, lvItem.pszText); + Utils::mucc_mir_free(lvItem.pszText); + + lvItem.iSubItem = 5; + lvItem.pszText = Utils::mucc_mir_a2t(queryResult->pItems[i].pszText); + if (lvItem.pszText == NULL) lvItem.pszText = _TEXT(""); + ListView_InsertItem(GetDlgItem(getBrowserTabHWND(), IDC_LIST), &lvItem); + ListView_SetItemText(GetDlgItem(getBrowserTabHWND(), IDC_LIST), lvItem.iItem, lvItem.iSubItem, lvItem.pszText); + Utils::mucc_mir_free(lvItem.pszText); + +/* + ptr = new HelperContact(queryResult->pItems[i].pszID, queryResult->pItems[i].pszName); + if (lastptr !=NULL) { + lastptr->setNext(ptr); + } else { + contactList=ptr; + } + lastptr=ptr; + + */ + } + EnableWindow(GetDlgItem(getBrowserTabHWND(), IDC_SHOW), TRUE); +} + +const char *AdminWindow::getNick() { + return nick; +} + +int AdminWindow::getBrowserMode() { + return browserMode; +} diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/AdminWindow.h b/plugins/!NotAdopted/Tlen/tlen_czaty/AdminWindow.h new file mode 100644 index 0000000000..a73cdb9285 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/AdminWindow.h @@ -0,0 +1,63 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +class AdminWindow; +#ifndef ADMINWINDOW_INCLUDED +#define ADMINWINDOW_INCLUDED + +#include "mucc.h" +#include "ChatWindow.h" + +class AdminWindow { +private: + HWND hWnd; + HWND hKickTabWnd, hBrowserTabWnd; + int currentTab; + int browserMode; + ChatWindow *parent; + char *nick; +public: + enum BROWSER_MODE { + BROWSE_BANNED = 1, + BROWSE_OWNERS = 2, + BROWSE_ADMINS = 3, + BROWSE_MEMBERS = 4, + BROWSE_MODERATORS = 5 + }; + AdminWindow (ChatWindow *parent, const char *nick, int mode); + ~AdminWindow(); + void start(); + void setHWND(HWND); + void setKickTabHWND(HWND); + void setBrowserTabHWND(HWND); + HWND getKickTabHWND(); + HWND getBrowserTabHWND(); + int getCurrentTab(); + int getBrowserMode(); + void setCurrentTab(int); + void queryUsers(int); + ChatWindow* getParent(); + const char *getNick(); + void queryResultUsers(MUCCQUERYRESULT *queryResult); +}; + +#endif + diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/ChatContainer.cpp b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatContainer.cpp new file mode 100644 index 0000000000..11e523e337 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatContainer.cpp @@ -0,0 +1,480 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "ChatContainer.h" +#include "Utils.h" +#include "Options.h" + +#define DM_CREATECHILD (WM_USER+10) +#define DM_ADDCHILD (WM_USER+11) +#define DM_ACTIVATECHILD (WM_USER+12) +#define DM_CHANGECHILDDATA (WM_USER+13) +#define DM_REMOVECHILD (WM_USER+14) + +#define DM_SETUNREAD (WM_USER+15) +#define DM_FLASHWINDOW (WM_USER+16) + +#define TIMERID_FLASHWND 1 +#define TIMEOUT_FLASHWND 900 + +ChatContainer * ChatContainer::list = NULL; +bool ChatContainer::released = false; +CRITICAL_SECTION ChatContainer::mutex; + +//BOOL CALLBACK ContainerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static void __cdecl StartThread(void *vContainer); + +void ChatContainer::release() { + released = true; + for (ChatContainer *ptr2, *ptr = list; ptr!=NULL; ptr=ptr2) { + ptr2 = ptr->getNext(); + SendMessage(ptr->getHWND(), WM_CLOSE, 0, 0); + } + DeleteCriticalSection(&mutex); +} + +void ChatContainer::init() { + released = false; + InitializeCriticalSection(&mutex); +} + +int ChatContainer::getDefaultOptions() { + return FLAG_USE_TABS; +} + +ChatContainer * ChatContainer::getWindow() { + ChatContainer *ptr; + EnterCriticalSection(&mutex); + if (list == NULL || !(Options::getChatContainerOptions() & ChatContainer::FLAG_USE_TABS)) { + ptr = new ChatContainer(); + } else { + ptr = list; + } + LeaveCriticalSection(&mutex); + return ptr; +} + +ChatContainer::ChatContainer() { + hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + hWnd = NULL; + prev = next =NULL; + active = NULL; + childCount = 0; + nFlash = 0; + nFlashMax = 3; + Utils::forkThread((void (__cdecl *)(void *))StartThread, 0, (void *) this); + WaitForSingleObject(hEvent, INFINITE); + EnterCriticalSection(&mutex); + setNext(list); + if (next!=NULL) { + next->setPrev(this); + } + list = this; + LeaveCriticalSection(&mutex); +} + +ChatContainer::~ChatContainer() { + if (!released) { + EnterCriticalSection(&mutex); + if (getPrev()!=NULL) { + getPrev()->setNext(next); + } else if (list==this) { + list = getNext(); + } + if (getNext()!=NULL) { + getNext()->setPrev(prev); + } + LeaveCriticalSection(&mutex); + } + if (hEvent!=NULL) { + CloseHandle(hEvent); + } +} + +void ChatContainer::setHWND(HWND hWnd) { + this->hWnd = hWnd; +} + +HWND ChatContainer::getHWND() { + return hWnd; +} + +HANDLE ChatContainer::getEvent() { + return hEvent; +} + +ChatContainer * ChatContainer::getNext() { + return next; +} + +void ChatContainer::setNext(ChatContainer * next) { + this->next = next; +} + +ChatContainer * ChatContainer::getPrev() { + return prev; +} + +void ChatContainer::setPrev(ChatContainer * prev) { + this->prev = prev; +} + +void ChatContainer::show(bool bShow) { + ShowWindow(hWnd, bShow ? SW_SHOW : SW_HIDE); +} + +ChatWindow * ChatContainer::getActive() { + return active; +} + +int ChatContainer::getFlash() { + return nFlash; +} + +int ChatContainer::getFlashMax() { + return nFlashMax; +} + +int ChatContainer::getFlashTimeout() { + return TIMEOUT_FLASHWND; +} + +void ChatContainer::setFlash(int n) { + nFlash = n; +} + +void ChatContainer::activateChild(ChatWindow *window) { + RECT rcChild; + getChildWindowRect(&rcChild); + if (window!=NULL) { + SetWindowPos(window->getHWND(), HWND_TOP, rcChild.left, rcChild.top, rcChild.right-rcChild.left, rcChild.bottom - rcChild.top, SWP_NOSIZE); + } + if(window != active) { + ChatWindow *prev = active; + active = window; + SendMessage(hWnd, WM_SIZE, 0, 0); + ShowWindow(active->getHWND(), SW_SHOW); +// SendMessage(active->getHWND(), DM_UPDATETITLE, 0, 0); + if (prev!=NULL) { + ShowWindow(prev->getHWND(), SW_HIDE); + } + SetWindowTextA(hWnd, window->getRoomName()); + } + TCITEM tci; + tci.mask = TCIF_IMAGE; + tci.iImage = -1; + TabCtrl_SetItem(GetDlgItem(hWnd, IDC_TABS), getChildTab(window), &tci); + SendMessage(active->getHWND(), WM_ACTIVATE, WA_ACTIVE, 0); + SetFocus(active->getHWND()); +} + + +void ChatContainer::addChild(ChatWindow *child) { + TCITEM tci; + int tabId; + HWND hwndTabs = GetDlgItem(hWnd, IDC_TABS); + childCount++; + tci.mask = TCIF_TEXT | TCIF_PARAM; + LPTSTR lps1 = Utils::mucc_mir_a2t(child->getRoomName()); + tci.pszText = lps1; + tci.lParam = (LPARAM) child; + tabId = TabCtrl_InsertItem(hwndTabs, childCount-1, &tci); + TabCtrl_SetCurSel(hwndTabs, tabId); + Utils::mucc_mir_free(lps1); + activateChild(child); + SendMessage(hWnd, WM_SIZE, 0, 0); + ShowWindow(hWnd, SW_SHOWNORMAL); + SetForegroundWindow(hWnd); +} + +void ChatContainer::changeChildData(ChatWindow *child) { + int tabId; + HWND hwndTabs = GetDlgItem(hWnd, IDC_TABS); + tabId = getChildTab(child); + if (tabId >=0) { + TCITEM tci; + tci.mask = TCIF_TEXT; + LPTSTR lps1 = Utils::mucc_mir_a2t(child->getRoomName()); + tci.pszText = lps1; + TabCtrl_SetItem(hwndTabs, childCount-1, &tci); + Utils::mucc_mir_free(lps1); + } + if (child == active) { + SetWindowTextA(hWnd, child->getRoomName()); + } +} + + +void ChatContainer::removeChild(ChatWindow *child) { + HWND hwndTabs = GetDlgItem(hWnd, IDC_TABS); + int iSel = getChildTab(child); + if (iSel >= 0) { + TabCtrl_DeleteItem(hwndTabs, iSel); + } + childCount--; + if (childCount > 0) { + TCITEM tci; + if (iSel == childCount) iSel--; + TabCtrl_SetCurSel(hwndTabs, iSel); + tci.mask = TCIF_PARAM; + if (TabCtrl_GetItem(hwndTabs, iSel, &tci)) { + child = (ChatWindow *)tci.lParam; + activateChild(child); + } + } else {//if (!released) { + SendMessage(hWnd, WM_CLOSE, 0, 0); + } +} + +void ChatContainer::setUnread(ChatWindow *child, int unread) { + if (!unread || child != active) { + TCITEM tci; + tci.mask = TCIF_IMAGE; + if (unread) { + tci.iImage = 0; + } else { + tci.iImage = -1; + } + TabCtrl_SetItem(GetDlgItem(hWnd, IDC_TABS), getChildTab(child), &tci); + } +} + + +void ChatContainer::getChildWindowRect(RECT *rcChild) +{ + RECT rc, rcTabs; //rcStatus, + HWND hwndTabs = GetDlgItem(hWnd, IDC_TABS); + int l = TabCtrl_GetItemCount(hwndTabs); + GetClientRect(hWnd, &rc); + GetClientRect(hwndTabs, &rcTabs); + TabCtrl_AdjustRect(hwndTabs, FALSE, &rcTabs); +// GetWindowRect(dat->hwndStatus, &rcStatus); + rcChild->left = 0; + rcChild->right = rc.right; + if (l > 1) { + rcChild->top = rcTabs.top - 1; + } else { + rcChild->top = 0; + } + rcChild->bottom = rc.bottom - rc.top;// - (rcStatus.bottom - rcStatus.top); +} + +ChatWindow * ChatContainer::getChildFromTab(int tabId) { + TCITEM tci; + tci.mask = TCIF_PARAM; + TabCtrl_GetItem(GetDlgItem(hWnd, IDC_TABS), tabId, &tci); + return (ChatWindow *)tci.lParam; +} + +int ChatContainer::getChildTab(ChatWindow *child) { + TCITEM tci; + int l, i; + HWND hwndTabs = GetDlgItem(hWnd, IDC_TABS); + l = TabCtrl_GetItemCount(hwndTabs); + for (i = 0; i < l; i++) { + tci.mask = TCIF_PARAM; + TabCtrl_GetItem(hwndTabs, i, &tci); + if (child == (ChatWindow *) tci.lParam) { + return i; + } + } + return -1; + +} + +HWND ChatContainer::remoteCreateChild(DLGPROC proc, ChatWindow *ptr) { + return (HWND) SendMessage(hWnd, DM_CREATECHILD, (WPARAM)proc, (LPARAM) ptr); +} + +void ChatContainer::remoteAddChild(ChatWindow *ptr) { + SendMessage(hWnd, DM_ADDCHILD, (WPARAM)0, (LPARAM) ptr); +} + +void ChatContainer::remoteChangeChildData(ChatWindow *ptr) { + SendMessage(hWnd, DM_CHANGECHILDDATA, (WPARAM)0, (LPARAM) ptr); +} + +void ChatContainer::remoteRemoveChild(ChatWindow *ptr) { + SendMessage(hWnd, DM_REMOVECHILD, (WPARAM)0, (LPARAM) ptr); +} + +void ChatContainer::remoteSetUnread(ChatWindow *ptr, int unread) { + SendMessage(hWnd, DM_SETUNREAD, (WPARAM)unread, (LPARAM) ptr); +} + +void ChatContainer::remoteFlashWindow() { + SendMessage(hWnd, DM_FLASHWINDOW, 0, 0); +} + +INT_PTR CALLBACK ContainerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + ChatContainer *container; + container = (ChatContainer *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + if (container==NULL && msg!=WM_INITDIALOG) return FALSE; + switch (msg) { + case WM_INITDIALOG: + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) muccIcon[MUCC_IDI_CHAT]); + container = (ChatContainer *) lParam; + container->setHWND(hwndDlg); + TabCtrl_SetImageList(GetDlgItem(hwndDlg, IDC_TABS), hImageList); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) container); + ShowWindow(hwndDlg, SW_SHOW); + SetEvent(container->getEvent()); + return TRUE; + case WM_GETMINMAXINFO: + MINMAXINFO *mmi; + RECT rcChild, rcWindow; + mmi = (MINMAXINFO *) lParam; + GetWindowRect(hwndDlg, &rcWindow); + container->getChildWindowRect(&rcChild); + mmi->ptMinTrackSize.x = 380; + mmi->ptMinTrackSize.y = 130 + (rcWindow.bottom - rcWindow.top) - (rcChild.bottom - rcChild.top); + return FALSE; + case WM_SIZE: + if (IsIconic(hwndDlg) || wParam == SIZE_MINIMIZED) break; + { + RECT rc, rcChild, rcWindow; + GetClientRect(hwndDlg, &rc); + HWND hwndTabs = GetDlgItem(hwndDlg, IDC_TABS); + MoveWindow(hwndTabs, 0, 0, (rc.right - rc.left), (rc.bottom - rc.top) - 0, FALSE); + RedrawWindow(hwndTabs, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE); + container->getChildWindowRect(&rcChild); + if ((rcChild.bottom-rcChild.top) < 130 || (rcChild.right-rcChild.left) < 380) { + GetWindowRect(hwndDlg, &rcWindow); + if ((rcChild.bottom-rcChild.top) < 130) { + rcWindow.bottom = rcWindow.top + 130 + (rcWindow.bottom - rcWindow.top) - (rcChild.bottom - rcChild.top); + } + if ((rcChild.right-rcChild.left) < 380) { + rcWindow.right = rcWindow.left + 380; + } + MoveWindow(hwndDlg, rcWindow.left, rcWindow.top, rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top, TRUE); + container->getChildWindowRect(&rcChild); + } + if (container->getActive()!=NULL) { + MoveWindow(container->getActive()->getHWND(), rcChild.left, rcChild.top, rcChild.right-rcChild.left, rcChild.bottom - rcChild.top, TRUE); + } + } + return TRUE; + case DM_CREATECHILD: + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_GROUPCHAT_LOG), hwndDlg, (DLGPROC) wParam, (LPARAM) lParam)); + return TRUE; + case DM_ADDCHILD: + container->addChild((ChatWindow *) lParam); + return TRUE; + case DM_REMOVECHILD: + container->removeChild((ChatWindow *) lParam); + return TRUE; + case DM_CHANGECHILDDATA: + container->removeChild((ChatWindow *) lParam); + return TRUE; + case DM_SETUNREAD: + container->setUnread((ChatWindow *) lParam, (int)wParam); + return TRUE; + case DM_FLASHWINDOW: + if (GetActiveWindow() != hwndDlg && GetForegroundWindow() != hwndDlg) { + container->setFlash(0); + SetTimer(hwndDlg, TIMERID_FLASHWND, container->getFlashTimeout(), NULL); + } + return TRUE; + case WM_NOTIFY: + { + NMHDR* pNMHDR = (NMHDR*) lParam; + switch (pNMHDR->code) { + case TCN_SELCHANGE: + { + TCITEM tci = {0}; + HWND hwndTabs = GetDlgItem(hwndDlg, IDC_TABS); + int iSel = TabCtrl_GetCurSel(hwndTabs); + tci.mask = TCIF_PARAM; + if (TabCtrl_GetItem(hwndTabs, iSel, &tci)) { + ChatWindow * chatWindow = (ChatWindow *) tci.lParam; + container->activateChild(chatWindow); + } + } + break; + case NM_CLICK: + { + FILETIME ft; + TCHITTESTINFO thinfo; + int tabId; + HWND hwndTabs = GetDlgItem(hwndDlg, IDC_TABS); + GetSystemTimeAsFileTime(&ft); + GetCursorPos(&thinfo.pt); + ScreenToClient(hwndTabs, &thinfo.pt); + tabId = TabCtrl_HitTest(hwndTabs, &thinfo); + if (tabId != -1 && tabId == container->lastClickTab && + (ft.dwLowDateTime - container->lastClickTime) < (GetDoubleClickTime() * 10000)) { + SendMessage(container->getChildFromTab(tabId)->getHWND(), WM_CLOSE, 0, 0); + container->lastClickTab = -1; + } else { + container->lastClickTab = tabId; + } + container->lastClickTime = ft.dwLowDateTime; + } + break; + } + + } + break; + case WM_ACTIVATE: + if (LOWORD(wParam) != WA_ACTIVE) + break; + case WM_MOUSEACTIVATE: + if (KillTimer(hwndDlg, TIMERID_FLASHWND)) { + FlashWindow(hwndDlg, FALSE); + } + /* + if (container->getActive()!=NULL) { + container->setUnread(container->getActive(), 0); + SendMessage(container->getActive()->getHWND(), WM_ACTIVATE, WA_ACTIVE, 0); + }*/ + break; + case WM_CLOSE: + EndDialog(hwndDlg, 0); + return FALSE; + case WM_TIMER: + if (wParam == TIMERID_FLASHWND) { + if ((container->getFlash() > container->getFlashMax()) || (GetActiveWindow() == hwndDlg) || (GetForegroundWindow() == hwndDlg)) { + KillTimer(hwndDlg, TIMERID_FLASHWND); + FlashWindow(hwndDlg, FALSE); + } else if (container->getFlash() < container->getFlashMax()) { + FlashWindow(hwndDlg, TRUE); + container->setFlash(container->getFlash()+1); + } + } + break; + case WM_DESTROY: + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)0); + delete container; + return TRUE; + + } + return FALSE; +} + + +static void __cdecl StartThread(void *vContainer) { + OleInitialize(NULL); + DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_GROUPCHAT_CONTAINER), NULL, ContainerDlgProc, (LPARAM) vContainer); + //MessageBox(NULL, "ChatContainer dies.", "MW", MB_OK); + OleUninitialize(); + +} diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/ChatContainer.h b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatContainer.h new file mode 100644 index 0000000000..4414068033 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatContainer.h @@ -0,0 +1,100 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +class ChatContainer; + +#ifndef CHATCONTAINER_INCLUDED +#define CHATCONTAINER_INCLUDED +#include "mucc.h" +#include "ChatEvent.h" +#include "ChatUser.h" +#include "AdminWindow.h" + +class ChatContainerChild { +public: + ChatWindow *window; + ChatContainerChild *next; + ChatContainerChild *prev; +}; + +class ChatContainer{ + +private: + static ChatContainer * list; + static bool released; + static CRITICAL_SECTION mutex; + HWND hWnd; + HANDLE hEvent; + int childCount; + int width, height; + int nFlash, nFlashMax; + ChatContainer *next, *prev; + ChatWindow * active; + ChatContainer(); +protected: + friend INT_PTR CALLBACK ContainerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + void addChild(ChatWindow *); + void activateChild(ChatWindow *); + void changeChildData(ChatWindow *); + void removeChild(ChatWindow *); + void setUnread(ChatWindow *child, int unread); + void getChildWindowRect(RECT *rcChild); + ChatWindow * getChildFromTab(int tabId); + int getChildTab(ChatWindow *); + int getChildCount(); + void setChildCount(int); + ChatWindow * getActive(); + ChatContainerChild *getChildren(); + ChatContainer * getNext(); + void setNext(ChatContainer *); + ChatContainer * getPrev(); + void setPrev(ChatContainer *); + int lastClickTime; + int lastClickTab; + HANDLE getEvent(); + void setHWND(HWND); + int getFlash(); + int getFlashMax(); + int getFlashTimeout(); + void setFlash(int); +public: + enum FLAGS { + FLAG_USE_TABS = 0x00000001, + }; + + ~ChatContainer(); + static void init(); + static void release(); + static ChatContainer * getWindow(); + static int getDefaultOptions(); + void show(bool bShow); + HWND getHWND(); + + HWND remoteCreateChild(DLGPROC proc, ChatWindow *); + void remoteAddChild(ChatWindow *); + void remoteChangeChildData(ChatWindow *); + void remoteRemoveChild(ChatWindow *); + void remoteSetUnread(ChatWindow *ptr, int unread); + void remoteFlashWindow(); +}; + + +#endif diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/ChatEvent.cpp b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatEvent.cpp new file mode 100644 index 0000000000..246c168f22 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatEvent.cpp @@ -0,0 +1,174 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "ChatEvent.h" +#include "Options.h" +#include "Utils.h" +#include + +ChatEvent::ChatEvent() { + + next = prev = NULL; + event.cbSize = sizeof(MUCCEVENT); + event.iType = 0; + event.pszID = NULL; + event.pszModule = NULL; + event.pszName = NULL; + event.pszNick = NULL; + event.pszText = NULL; + event.pszUID = NULL; +} + +ChatEvent::ChatEvent(const MUCCEVENT *e) { + + event.cbSize = sizeof(MUCCEVENT); + event.iType = e->iType; + event.bIsMe = e->bIsMe; + event.color = e->color; + event.dwData = e->dwData; + event.dwFlags = e->dwFlags; + event.iFont = e->iFont; + event.iFontSize = e->iFontSize; + event.time = e->time; + event.pszID = NULL; + event.pszModule = NULL; + event.pszName = NULL; + event.pszNick = NULL; + event.pszText = NULL; + event.pszUID = NULL; +// Utils::copyString((char **)&(event.pszID), e->pszID); +// Utils::copyString((char **)&(event.pszModule), e->pszModule); +// Utils::copyString((char **)&(event.pszName), e->pszName); + if (e->iType == MUCC_EVENT_STATUS || e->iType == MUCC_EVENT_MESSAGE) { + Utils::copyString((char **)&(event.pszNick), e->pszNick); + } + if (e->iType == MUCC_EVENT_ERROR || e->iType == MUCC_EVENT_MESSAGE || e->iType == MUCC_EVENT_TOPIC) { + Utils::copyString((char **)&(event.pszText), e->pszText); + } +// Utils::copyString((char **)&(event.pszUID), e->pszUID); + next = prev = NULL; +} + +ChatEvent::~ChatEvent() { + + if (event.pszID != NULL) { + delete (char *)event.pszID; + } + if (event.pszModule != NULL) { + delete (char *)event.pszModule; + } + if (event.pszName != NULL) { + delete (char *)event.pszName; + } + if (event.pszNick != NULL) { + delete (char *)event.pszNick; + } + if (event.pszText != NULL) { + delete (char *)event.pszText; + } + if (event.pszUID != NULL) { + delete (char *)event.pszUID; + } + if (next != NULL) { + next->setPrev(prev); + } + if (prev != NULL) { + prev->setNext(next); + } +} + +ChatEvent * ChatEvent::getNext() { + return next; +} + +ChatEvent * ChatEvent::getPrev() { + return prev; +} + +void ChatEvent::setNext(ChatEvent *next) { + this->next = next; +} + +void ChatEvent::setPrev(ChatEvent * prev) { + this->prev = prev; +} + +const MUCCEVENT * ChatEvent::getEvent() { + return &event; +} + +ChatEventList::ChatEventList() { + eventListEnd = &eventListRoot; + setMaxSize(DEFAULT_MAX_SIZE); + currentSize = 0; +} + +ChatEventList::~ChatEventList() { + while (eventListRoot.getNext()!=NULL) { + delete eventListRoot.getNext(); + } +} + +int ChatEventList::addEvent(const MUCCEVENT *muccevent) { + int trimmed = 0; + ChatEvent *event = new ChatEvent(muccevent); + event->setPrev(eventListEnd); + eventListEnd->setNext(event); + eventListEnd=event; + currentSize++; + if (currentSize>hiMaxSize) { + while (currentSize>loMaxSize && eventListRoot.getNext()!=NULL) { + delete eventListRoot.getNext(); + currentSize--; + trimmed = 1; + } + } + return trimmed; +} + +ChatEvent * ChatEventList::getEvents() { + return eventListRoot.getNext(); +} + +void ChatEventList::setMaxSize(int s) { + loMaxSize = s; + if (s>200) { + hiMaxSize = s + s/10; + } else { + hiMaxSize = s + 20; + } +} + +void ChatEventList::clear() { + ChatEvent *event = eventListRoot.getNext(); + eventListRoot.setNext(NULL); + eventListEnd = &eventListRoot; + currentSize = 0; + if (event!=NULL) { + event->setPrev(NULL); + while (event->getNext()!=NULL) { + delete event->getNext(); + } + delete event; + } +} + + diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/ChatEvent.h b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatEvent.h new file mode 100644 index 0000000000..37e045380f --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatEvent.h @@ -0,0 +1,60 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#ifndef CHATEVENT_INCLUDED +#define CHATEVENT_INCLUDED +#include "mucc.h" + +class ChatEvent { +private: + ChatEvent * prev; + ChatEvent * next; + MUCCEVENT event; +public: + ChatEvent(); + ChatEvent(const MUCCEVENT *); + ~ChatEvent(); + ChatEvent * getPrev(); + ChatEvent * getNext(); + void setPrev(ChatEvent *); + void setNext(ChatEvent *); + const MUCCEVENT *getEvent(); +}; + +class ChatEventList { +private: + ChatEvent eventListRoot; + ChatEvent * eventListEnd; + int loMaxSize; + int hiMaxSize; + int currentSize; +public: + enum { + DEFAULT_MAX_SIZE = 100 + }; + ChatEventList(); + ~ChatEventList(); + ChatEvent * getEvents(); + int addEvent(const MUCCEVENT *); + void clear(); + void setMaxSize(int s); +}; + +#endif diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/ChatGroup.cpp b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatGroup.cpp new file mode 100644 index 0000000000..a5c47d724f --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatGroup.cpp @@ -0,0 +1,99 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "ChatGroup.h" +#include "Utils.h" + +ChatGroup::ChatGroup() { + prev = next = NULL; + parent = child =NULL; + name = NULL; + id = 0; +} + +ChatGroup::~ChatGroup() { + if (name!=NULL) delete name; + if (id!=NULL) delete id; +} +ChatGroup * ChatGroup::getNext() { + return next; +} + +void ChatGroup::setNext(ChatGroup *next) { + this->next = next; +} + +ChatGroup * ChatGroup::getPrev() { + return prev; +} + +void ChatGroup::setPrev(ChatGroup *prev) { + this->prev = prev; +} + +ChatGroup * ChatGroup::getChild() { + return child; +} + +void ChatGroup::addChild(ChatGroup *child) { + ChatGroup *group; + for (group=getChild();group!=NULL && group->getNext()!=NULL;group=group->getNext()) { + } + if (group==NULL) this->child = child; + else { + group->setNext(child); + } + child->setPrev(group); + child->setNext(NULL); +} + +ChatGroup * ChatGroup::getListNext() { + return listNext; +} + +void ChatGroup::setListNext(ChatGroup *next) { + this->listNext = next; +} + +const char *ChatGroup::getId() { + return id; +} + +void ChatGroup::setId(const char *id) { + Utils::copyString(&this->id, id); +} + +HTREEITEM ChatGroup::getTreeItem() { + return hItem; +} + +void ChatGroup::setTreeItem(HTREEITEM hItem) { + this->hItem=hItem; +} + +const char *ChatGroup::getName() { + return name; +} + +void ChatGroup::setName(const char *name) { + Utils::copyString(&this->name, name); +} + diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/ChatGroup.h b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatGroup.h new file mode 100644 index 0000000000..c04abf81ba --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatGroup.h @@ -0,0 +1,55 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#ifndef CHATGROUP_INCLUDED +#define CHATGROUP_INCLUDED +#include "mucc.h" + +class ChatGroup { +private: + HTREEITEM hItem; + ChatGroup * parent; + ChatGroup * child; + ChatGroup * prev; + ChatGroup * next; + ChatGroup * listNext; + char * name; + char * id; +public: + ChatGroup(); + ~ChatGroup(); + ChatGroup * getPrev(); + ChatGroup * getNext(); + ChatGroup * getListNext(); + ChatGroup * getChild(); + ChatGroup * getParent(); + HTREEITEM getTreeItem(); + const char * getName(); + const char * getId(); + void setPrev(ChatGroup *); + void setNext(ChatGroup *); + void setListNext(ChatGroup *); + void addChild(ChatGroup *); + void setParent(ChatGroup *); + void setName(const char *); + void setTreeItem(HTREEITEM ); + void setId(const char *); +}; +#endif diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/ChatRoom.cpp b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatRoom.cpp new file mode 100644 index 0000000000..2f9c1389c2 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatRoom.cpp @@ -0,0 +1,68 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "ChatRoom.h" +#include "Utils.h" + + +ChatRoom::ChatRoom() { + next = prev = NULL; + name = NULL; + id = NULL; +} + +ChatRoom::~ChatRoom() { + if (name!=NULL) delete name; + if (id!=NULL) delete id; +} + +void ChatRoom::setId(const char *id) { + Utils::copyString(&this->id, id); +} + +void ChatRoom::setName(const char *name) { + Utils::copyString(&this->name, name); +} + +const char* ChatRoom::getId() { + return id; +} + +const char* ChatRoom::getName() { + return name; +} + +ChatRoom *ChatRoom::getNext() { + return next; +} + +void ChatRoom::setNext(ChatRoom *next) { + this->next = next; +} + +void ChatRoom::setFlags(int flags) { + this->flags = flags; +} + +int ChatRoom::getFlags() { + return flags; +} + diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/ChatRoom.h b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatRoom.h new file mode 100644 index 0000000000..51593f00c2 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatRoom.h @@ -0,0 +1,51 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#ifndef CHATROOM_INCLUDED +#define CHATROOM_INCLUDED +#include "mucc.h" + + +class ChatRoom { +private: + HTREEITEM hItem; + ChatRoom * prev; + ChatRoom * next; + char * name; + char * id; + int flags; +public: + ChatRoom(); + ~ChatRoom(); + ChatRoom * getPrev(); + ChatRoom * getNext(); + HTREEITEM getTreeItem(); + const char * getName(); + const char * getId(); + int getFlags(); + void setPrev(ChatRoom *); + void setNext(ChatRoom *); + void setName(const char *); + void setTreeItem(HTREEITEM ); + void setId(const char *); + void setFlags(int); +}; + +#endif diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/ChatUser.cpp b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatUser.cpp new file mode 100644 index 0000000000..cb5baea1a8 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatUser.cpp @@ -0,0 +1,83 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "ChatUser.h" +#include "Utils.h" + +ChatUser::ChatUser() { + id = NULL; + nick = NULL; + hTreeItem = NULL; + me = 0; +} + +ChatUser::~ChatUser() { + if (id!=NULL) delete id; + if (nick!=NULL) delete nick; +} + +void ChatUser::setNick(const char *nick) { + Utils::copyString(&this->nick, nick); +} + +void ChatUser::setId(const char *id) { + Utils::copyString(&this->id, id); +} + +const char *ChatUser::getNick() { + return nick; +} + +const char *ChatUser::getId() { + return id; +} + +void ChatUser::setNext(ChatUser *next) { + this->next = next; +} + +ChatUser * ChatUser::getNext() { + return next; +} + +void ChatUser::setFlags(int flags) { + this->flags = flags; +} + +int ChatUser::getFlags() { + return flags; +} + +void ChatUser::setMe(int me) { + this->me = me; +} + +int ChatUser::isMe() { + return me; +} + +void ChatUser::setHTreeItem(HTREEITEM hti) { + hTreeItem = hti; +} + +HTREEITEM ChatUser::getHTreeItem() { + return hTreeItem; +} diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/ChatUser.h b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatUser.h new file mode 100644 index 0000000000..0084a14608 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatUser.h @@ -0,0 +1,49 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#ifndef CHATUSER_INCLUDED +#define CHATUSER_INCLUDED +#include "mucc.h" + +class ChatUser { +private: + char * nick; + char * id; + int flags; + int me; + ChatUser * next; + HTREEITEM hTreeItem; +public: + ChatUser(); + ~ChatUser(); + void setNick(const char *); + void setId(const char *); + const char * getNick(); + const char * getId(); + void setNext(ChatUser *); + int getFlags(); + void setFlags(int ); + HTREEITEM getHTreeItem(); + void setHTreeItem(HTREEITEM); + ChatUser * getNext(); + void setMe(int); + int isMe(); +}; +#endif diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/ChatWindow.cpp b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatWindow.cpp new file mode 100644 index 0000000000..97dc986381 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatWindow.cpp @@ -0,0 +1,2108 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "ChatWindow.h" +#include "HelperDialog.h" +#include "Utils.h" +#include "Options.h" +#include "m_smileyadd.h" +#include "m_ieview.h" +//#include "m_chat.h" + +static int logPixelSY; +static INT_PTR CALLBACK LogDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static void JabberStringAppend(char **str, int *sizeAlloced, const char *fmt, ...); +static char *JabberRtfEscape(char *str); +//static DWORD CALLBACK Log_StreamCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb); + +COLORREF ChatWindow::colorListBg, ChatWindow::colorListText, ChatWindow::colorListGroupText; +HFONT ChatWindow::hListGroupFont=NULL; +HFONT ChatWindow::hListFont=NULL; + +ChatWindow * ChatWindow::list = NULL; +bool ChatWindow::released = false; +CRITICAL_SECTION ChatWindow::mutex; + +static WNDPROC oldSplitterWndProc, oldEditWndProc; +static HCURSOR hCurSplitNS, hCurSplitWE, hCurHyperlinkHand; + +void ChatWindow::release() { + released = true; + for (ChatWindow *ptr2, *ptr = list; ptr!=NULL; ptr=ptr2) { + ptr2 = ptr->getNext(); + //SendMessage(ptr->getHWND(), WM_CLOSE, 0, 0); + } + DeleteCriticalSection(&mutex); + DestroyCursor(hCurSplitNS); + DestroyCursor(hCurSplitWE); + DestroyCursor(hCurHyperlinkHand); +} + +void ChatWindow::init() { + hCurSplitNS = LoadCursor(NULL, IDC_SIZENS); + hCurSplitWE = LoadCursor(NULL, IDC_SIZEWE); + hCurHyperlinkHand = LoadCursor(NULL, IDC_HAND); + if (hCurHyperlinkHand == NULL) { + hCurHyperlinkHand = LoadCursor(NULL, IDC_ARROW); + } + released = false; + InitializeCriticalSection(&mutex); +} + +/* chat.dll mod*/ +/* +static bool gcRegistered = false; + +static void __stdcall StartThread(void *vChat) { //__cdecl + ChatWindow *chat = (ChatWindow *)vChat; + if (!gcRegistered) { + gcRegistered = true; + GCREGISTER gcr = {0}; + gcr.cbSize = sizeof(GCREGISTER); + gcr.dwFlags = 0; + gcr.iMaxText = 0; + gcr.nColors = 0; + gcr.pColors = 0; + gcr.pszModuleDispName = chat->getModule(); + gcr.pszModule = chat->getModule(); + if (CallService(MS_GC_REGISTER, 0, (LPARAM)&gcr)) { + MessageBox(NULL, "cannot register", "CHAT", MB_OK); + } + } + GCWINDOW gcw = {0}; + gcw.cbSize = sizeof(GCWINDOW); + gcw.iType = GCW_CHATROOM; + gcw.pszModule = chat->getModule(); + gcw.pszName = chat->getRoomName(); + gcw.pszID = chat->getRoomId(); + gcw.pszStatusbarText = "status"; + gcw.bDisableNickList = FALSE; + gcw.dwItemData = (DWORD) chat; + if(CallService(MS_GC_NEWCHAT, 0, (LPARAM) &gcw)) { + MessageBox(NULL, "cannot create", "CHAT", MB_OK); + } + + GCDEST gcdest; + GCEVENT gcevent = {sizeof(GCEVENT), &gcdest}; + const char *groupNames[] = {"Global Owners", "Owners", "Admins", "Moderators", "Users"}; + gcdest.pszModule = (char *)chat->getModule(); + gcdest.pszID = (char *)chat->getRoomId(); + gcevent.bAddToLog = FALSE; + gcevent.time = 0; + gcdest.iType = GC_EVENT_ADDGROUP; + for (int i=0;i<5;i++) { + gcevent.pszStatus = Translate(groupNames[i]); + CallService(MS_GC_EVENT, 0, (LPARAM)&gcevent); + } + + + gcdest.iType = GC_EVENT_CONTROL; + CallService(MS_GC_EVENT, WINDOW_INITDONE, (LPARAM)&gcevent); + CallService(MS_GC_EVENT, WINDOW_ONLINE, (LPARAM)&gcevent); +} +*/ + +ChatWindow::ChatWindow(MUCCWINDOW *mucw) { + prev = next = NULL; + adminWindow = NULL; + hWnd = NULL; + hWndLog = NULL; + module = roomId = roomName = topic = NULL; + hSplitterPos = 0; + vSplitterPos = 0; + wasFirstMessage = 0; + isEmpty = true; + isStarted = 0; + options = Options::getChatWindowOptions(); + bBold = bItalic = bUnderline = 0; + hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + hEditFont = NULL; + userMe = NULL; + users = NULL; + for (int i=0;i<5;i++) { + hUserGroups[i] = NULL; + } + setModule(mucw->pszModule); + setRoomId(mucw->pszID); + setRoomName(mucw->pszName); + EnterCriticalSection(&mutex); + setNext(list); + if (next!=NULL) { + next->setPrev(this); + } + list = this; + LeaveCriticalSection(&mutex); + container = ChatContainer::getWindow(); + hWnd = container->remoteCreateChild(LogDlgProc, this); + container->remoteAddChild(this); + /* chat.dll mod*/ +/* CallFunctionAsync(StartThread, (void *)this);*/ +} + +ChatWindow::~ChatWindow () { + if (!released) { + EnterCriticalSection(&mutex); + if (getPrev()!=NULL) { + getPrev()->setNext(next); + } else if (list==this) { + list = getNext(); + } + if (getNext()!=NULL) { + getNext()->setPrev(prev); + } + LeaveCriticalSection(&mutex); + } + if (adminWindow!=NULL) { + delete adminWindow; + } + if (hEvent!=NULL) { + CloseHandle(hEvent); + } + while (users!=NULL) { + ChatUser *user = users; + users = users->getNext(); + delete user; + } + if (module!=NULL) { + delete module; + } + if (roomId!=NULL) { + delete roomId; + } + if (roomName!=NULL) { + delete roomName; + } + if (topic!=NULL) { + delete topic; + } + container->remoteRemoveChild(this); +}; + + +void ChatWindow::setPrev(ChatWindow *prev) { + this->prev = prev; +} + +ChatWindow * ChatWindow::getPrev() { + return prev; +} + +void ChatWindow::setNext(ChatWindow *next) { + this->next = next; +} + +ChatWindow * ChatWindow::getNext() { + return next; +} + +void ChatWindow::setHWND(HWND hWnd) { + this->hWnd = hWnd; +} + +HWND ChatWindow::getHWND() { + return hWnd; +} + +void ChatWindow::setHWNDLog(HWND hWnd) { + this->hWndLog = hWnd; +} + +HWND ChatWindow::getHWNDLog() { + return hWndLog; +} + +HANDLE ChatWindow::getEvent() { + return hEvent; +} + +ChatContainer * ChatWindow::getContainer() { + return container; +} + +void ChatWindow::setAdminWindow(AdminWindow *aw) { + this->adminWindow = aw; +} + +AdminWindow* ChatWindow::getAdminWindow() { + return adminWindow; +} + +void ChatWindow::setModule(const char *module) { + Utils::copyString(&this->module, module); +} + +const char * ChatWindow::getModule() { + return module; +} + +void ChatWindow::setRoomId(const char *roomId) { + Utils::copyString(&this->roomId, roomId); +} + +const char * ChatWindow::getRoomId() { + return roomId; +} + +void ChatWindow::setRoomName(const char *roomName) { +// char str[300]; + Utils::copyString(&this->roomName, roomName); +// sprintf(str, "%s %08X", roomName, roomFlags); +// SetWindowText(hWnd, str); + SetWindowTextA(hWnd, roomName); +} + +void ChatWindow::setRoomFlags(int flags) { +// char str[300]; + roomFlags = flags; +// sprintf(str, "%s %08X", roomName, roomFlags); +// SetWindowText(hWnd, str); +} + +int ChatWindow::getRoomFlags() { + return roomFlags; +} + +const char * ChatWindow::getRoomName() { + return roomName; +} + +void ChatWindow::setOptions(int options) { + if (options != this->options) { + this->options = options; + rebuildLog(); + } +} + +int ChatWindow::getOptions() { + return options; +} + +static void __cdecl StartAdminThread(void *vChat) { + ChatWindow *chat = (ChatWindow *)vChat; + chat->getAdminWindow()->start(); +} + +void ChatWindow::startAdminDialog(int mode) { + if (adminWindow==NULL) { + ChatUser *user = getSelectedUser(); + if (user != NULL) { + adminWindow = new AdminWindow(this, user->getId(), mode); + } else { + adminWindow = new AdminWindow(this, "", mode); + } + Utils::forkThread((void (__cdecl *)(void *))StartAdminThread, 0, (void *) this); + } +} +void ChatWindow::addUser(ChatUser *user) { + user->setNext(users); + users = user; +} +void ChatWindow::removeUser(ChatUser *user) { + ChatUser *user2; + for (user2=users;user2!=NULL;user2=user2->getNext()) { + if (user2->getNext()==user) break; + } + if (user2!=NULL) { + user2->setNext(user->getNext()); + } else if (users==user) { + users = user->getNext(); + } +} + +ChatUser * ChatWindow::getMe() { + return userMe; +} + +ChatUser * ChatWindow::findUser(const char *userId) { + ChatUser *user; + for (user=users;user!=NULL;user=user->getNext()) { + if (!(strcmp(user->getId(), userId))) break; + } + return user; +} + +ChatUser * ChatWindow::findUserByNick(const char *nick) { + ChatUser *user; + for (user=users;user!=NULL;user=user->getNext()) { + if (!(strcmp(user->getNick(), nick))) break; + } + return user; +} + +ChatUser *ChatWindow::getSelectedUser() { + HTREEITEM hTreeItem = TreeView_GetSelection(GetDlgItem(hWnd, IDC_TREELIST)); + if (hTreeItem!=NULL) { + TVITEM tvi; + tvi.mask = TVIF_PARAM; + tvi.hItem = hTreeItem; + TreeView_GetItem(GetDlgItem(hWnd, IDC_TREELIST), &tvi); + return (ChatUser *) tvi.lParam; + } + return NULL; +} + +int ChatWindow::startPriv() { + ChatUser *user = getSelectedUser(); + if (user!=NULL) { + MUCCEVENT mucce; + mucce.cbSize = sizeof(MUCCEVENT); + mucce.iType = MUCC_EVENT_START_PRIV; + mucce.pszModule = getModule(); + mucce.pszID = getRoomId(); + mucce.pszUID = user->getId(); + NotifyEventHooks(hHookEvent, 0,(WPARAM)&mucce); + } + return 0; +} + +int ChatWindow::unban(const char *id) { + if (id!=NULL) { + MUCCEVENT mucce; + mucce.cbSize = sizeof(MUCCEVENT); + mucce.iType = MUCC_EVENT_UNBAN; + mucce.pszModule = getModule(); + mucce.pszID = getRoomId(); + mucce.pszUID = id; + NotifyEventHooks(hHookEvent, 0,(WPARAM)&mucce); + } + return 0; +} + + +int ChatWindow::kickAndBan(const char *id, int time, const char *reason) { + if (id!=NULL) { + MUCCEVENT mucce; + mucce.cbSize = sizeof(MUCCEVENT); + mucce.iType = MUCC_EVENT_KICK_BAN; + mucce.pszModule = getModule(); + mucce.pszID = getRoomId(); + mucce.pszUID = id; + mucce.dwData = time; + mucce.pszText = reason; + NotifyEventHooks(hHookEvent, 0,(WPARAM)&mucce); + } + return 0; +} + +int ChatWindow::kickAndBan(int time) { + ChatUser *user = getSelectedUser(); + if (user!=NULL) { + kickAndBan(user->getId(), time, ""); + } + return 0; +} + +int ChatWindow::setRights(const char *id, int flags) { + if (id!=NULL) { + MUCCEVENT mucce; + mucce.cbSize = sizeof(MUCCEVENT); + mucce.iType = MUCC_EVENT_SET_USER_ROLE; + mucce.pszModule = getModule(); + mucce.pszID = getRoomId(); + mucce.pszUID = id; + mucce.dwFlags = flags; + NotifyEventHooks(hHookEvent, 0,(WPARAM)&mucce); + } + return 0; +} + +int ChatWindow::setRights(int flags) { + ChatUser *user = getSelectedUser(); + if (user!=NULL) { + setRights(user->getId(), flags); + } + return 0; +} + +int ChatWindow::getUserGroup(ChatUser *user) { + int group = 4; + if (user->getFlags()&MUCC_EF_USER_GLOBALOWNER) { + group = 0; + } else if (user->getFlags()&MUCC_EF_USER_OWNER) { + group = 1; + } else if (user->getFlags()&MUCC_EF_USER_ADMIN) { + group = 2; + } else if (user->getFlags()&MUCC_EF_USER_MODERATOR) { + group = 3; + } + return group; +} + +int ChatWindow::changePresence(const MUCCEVENT *event) { + int i, group, bLogEvent = FALSE; + const char *groupNames[] = {"Global Owners", "Owners", "Admins", "Moderators", "Users"}; + ChatUser *user = findUser(event->pszUID); + if (event->dwData == ID_STATUS_ONLINE || (user!=NULL && event->dwData!=ID_STATUS_OFFLINE)) { + if (user == NULL) { + user = new ChatUser(); + user->setId(event->pszUID); + user->setNick(event->pszNick); + user->setFlags(event->dwFlags); + user->setMe(event->bIsMe); + addUser(user); + if (user->isMe()) { + userMe = user; + } + bLogEvent = TRUE; + } else { + group = getUserGroup(user); + user->setFlags(event->dwFlags); + TreeView_DeleteItem(GetDlgItem(hWnd, IDC_TREELIST), user->getHTreeItem()); + if (TreeView_GetChild(GetDlgItem(hWnd, IDC_TREELIST), getTreeItem(group))==NULL) { + TreeView_DeleteItem(GetDlgItem(hWnd, IDC_TREELIST), getTreeItem(group)); + setTreeItem(group, NULL); + } + } + if (user->isMe()) { + if (user->getFlags() & MUCC_EF_USER_OWNER || user->getFlags() & MUCC_EF_USER_ADMIN) { + EnableWindow(GetDlgItem(hWnd, IDC_TOPIC_BUTTON), TRUE); + } else { + EnableWindow(GetDlgItem(hWnd, IDC_TOPIC_BUTTON), FALSE); + } + } + group = getUserGroup(user); + TVINSERTSTRUCT tvis; + if (getTreeItem(group)==NULL) { + for (i=group-1;i>=0;i--) { + if (getTreeItem(i)!=NULL) break; + } + tvis.hParent = NULL; + if (i>=0) { + tvis.hInsertAfter = getTreeItem(i); + } else { + tvis.hInsertAfter = TVI_FIRST; + } + tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_CHILDREN; + tvis.item.lParam = (LPARAM) NULL; + tvis.item.cChildren = 1; + LPTSTR lps1 = Utils::mucc_mir_a2t(Translate(groupNames[group])); + tvis.item.pszText = lps1; + //tvis.item.state = INDEXTOSTATEIMAGEMASK(1); + //tvis.item.stateMask = TVIS_STATEIMAGEMASK ; + setTreeItem(group, TreeView_InsertItem(GetDlgItem(hWnd, IDC_TREELIST), &tvis)); + Utils::mucc_mir_free(lps1); + } + tvis.hParent = getTreeItem(group); + tvis.hInsertAfter = TVI_SORT; + tvis.item.mask = TVIF_TEXT | TVIF_PARAM; + LPTSTR lps2 = Utils::mucc_mir_a2t(user->getNick()); + tvis.item.pszText = lps2; + tvis.item.lParam = (LPARAM) user; + user->setHTreeItem(TreeView_InsertItem(GetDlgItem(hWnd, IDC_TREELIST), &tvis)); + TreeView_Expand(GetDlgItem(hWnd, IDC_TREELIST), getTreeItem(group), TVE_EXPAND); + Utils::mucc_mir_free(lps2); + } + else { + if (user != NULL) { + group = getUserGroup(user); + TreeView_DeleteItem(GetDlgItem(hWnd, IDC_TREELIST), user->getHTreeItem()); + if (TreeView_GetChild(GetDlgItem(hWnd, IDC_TREELIST), getTreeItem(group))==NULL) { + TreeView_DeleteItem(GetDlgItem(hWnd, IDC_TREELIST), getTreeItem(group)); + setTreeItem(group, NULL); + } + removeUser(user); + delete user; + bLogEvent = TRUE; + } + } + if (bLogEvent && wasFirstMessage) { + logEvent(event); + } + return 1; +} +int ChatWindow::changeTopic(const MUCCEVENT *event) { + + SetDlgItemTextA(hWnd, IDC_TOPIC, event->pszText); +//if (wasFirstMessage) { + logEvent(event); +// } + return 1; +} + +int ChatWindow::changeRoomInfo(const MUCCEVENT *event) { + + Utils::log("setting room info !"); + setRoomName(event->pszName); + setRoomFlags(event->dwFlags); + return 1; +} + +const char * ChatWindow::getFontName(int index) { + const char *fontNames[] = {"Arial", + "Comic Sans MS", + "Courier New", + "Impact", + "Lucida Console", + "MS Sans Serif", + "Tahoma", + "Times New Roman", + "Trebuchet MS", + "Verdana"}; + if (index>9 || index<0) index = 0; + return fontNames[index]; +} +int ChatWindow::getFontNameNum() { + return 10; +} +int ChatWindow::getFontSize(int index) { + return index+7; +} +int ChatWindow::getFontSizeNum() { + return 10; +} + +void ChatWindow::refreshSettings() { + SendDlgItemMessage(hWnd, IDC_LOG, EM_SETBKGNDCOLOR , 0, Options::getLogBgColor()); + SendDlgItemMessage(hWnd, IDC_TREELIST, TVM_SETBKCOLOR, 0, Options::getListBgColor()); + eventList.setMaxSize(Options::getLogLimit()); +} + +void ChatWindow::refreshSettings(int force) { + + if (hListFont!=NULL && !force) { + return; + } + EnterCriticalSection(&mutex); + if (hListFont!=NULL) { + DeleteObject(hListFont); + } + if (hListGroupFont!=NULL) { + DeleteObject(hListGroupFont); + } + Font * font = Options::getFont(Options::FONT_USERLIST); + colorListText = font->getColor(); + hListFont = CreateFontA(font->getSize(), 0, 0, 0, + font->getStyle() & Font::BOLD ? FW_BOLD : FW_NORMAL, + font->getStyle() & Font::ITALIC ? 1 : 0, + font->getStyle() & Font::UNDERLINE ? 1 : 0, 0, + font->getCharSet(), + OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_ROMAN, + font->getFace()); + font = Options::getFont(Options::FONT_USERLISTGROUP); + colorListGroupText = font->getColor(); + hListGroupFont = CreateFontA(font->getSize(), 0, 0, 0, + font->getStyle() & Font::BOLD ? FW_BOLD : FW_NORMAL, + font->getStyle() & Font::ITALIC ? 1 : 0, + font->getStyle() & Font::UNDERLINE ? 1 : 0, 0, + font->getCharSet(), + OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_ROMAN, + font->getFace()); + + for (ChatWindow *ptr=list;ptr!=NULL;ptr=ptr->getNext()) { + ptr->refreshSettings(); + InvalidateRect(ptr->getHWND(), NULL, FALSE); + } + LeaveCriticalSection(&mutex); +} +HFONT ChatWindow::getListFont() { + return hListFont; +} + +HFONT ChatWindow::getListGroupFont() { + return hListGroupFont; +} + +COLORREF ChatWindow::getListTextColor() { + return colorListText; +} + +COLORREF ChatWindow::getListGroupTextColor() { + return colorListGroupText; +} + +HTREEITEM ChatWindow::getTreeItem(int index) { + return hUserGroups[index]; +} + +void ChatWindow::setTreeItem(int index, HTREEITEM hTreeItem) { + hUserGroups[index]=hTreeItem; +} + +int ChatWindow::getDefaultOptions() { + return FLAG_SHOW_NICKNAMES | FLAG_SHOW_TIMESTAMP | FLAG_FORMAT_ALL | FLAG_LOG_MESSAGES | FLAG_OPT_SENDONENTER; +} + +void ChatWindow::clearLog() { + if (getHWNDLog()!=NULL) { + IEVIEWEVENT iee; + ZeroMemory(&iee, sizeof(iee)); + iee.cbSize = sizeof(iee); + iee.iType = IEE_CLEAR_LOG; + iee.dwFlags = IEEF_NO_UNICODE; + iee.hwnd = hWndLog; + iee.hContact = NULL; + iee.codepage = CP_ACP; + iee.pszProto = getModule(); + CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&iee); + } else { + SetDlgItemTextA(getHWND(), IDC_LOG, ""); + } + isEmpty = true; + eventList.clear(); +} + +void ChatWindow::rebuildLog() { + int nMin, nMax; + HWND hwndLog; + if (getHWNDLog()!=NULL) { + IEVIEWEVENT iee; + ZeroMemory(&iee, sizeof(iee)); + iee.cbSize = sizeof(iee); + iee.iType = IEE_CLEAR_LOG; + iee.dwFlags = IEEF_NO_UNICODE; + iee.hwnd = hWndLog; + iee.hContact = NULL; + iee.codepage = CP_ACP; + iee.pszProto = getModule(); + CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&iee); + } else { + SetDlgItemTextA(getHWND(), IDC_LOG, ""); + } + isEmpty = true; + for (ChatEvent* event=eventList.getEvents();event!=NULL;event=event->getNext()) { + appendMessage(event->getEvent()); + } + if (getHWNDLog()==NULL) { + if (ServiceExists(MS_SMILEYADD_REPLACESMILEYS)) PostMessage(getHWND(), WM_TLEN_SMILEY, 0, 0); + hwndLog = GetDlgItem(getHWND(), IDC_LOG); + int len = GetWindowTextLengthA(hwndLog); + SendMessage(hwndLog, EM_SETSEL, len - 1, len - 1); + GetScrollRange(hwndLog, SB_VERT, &nMin, &nMax); + SetScrollPos(hwndLog, SB_VERT, nMax, TRUE); + PostMessage(hwndLog, WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, nMax), (LPARAM) NULL); + } +} + +int ChatWindow::logEvent(const MUCCEVENT *event) { + /* chat.dll mod*/ + /* + if (event->iType == MUCC_EVENT_MESSAGE) { + GCDEST gcdest; + GCEVENT gcevent = {sizeof(GCEVENT), &gcdest}; + gcdest.pszModule = (char *)this->getModule(); + gcdest.pszID = (char *)this->getRoomId(); + gcdest.iType = GC_EVENT_MESSAGE; + gcevent.pszText = event->pszText; + gcevent.pszNick = event->pszNick; + gcevent.pszUID = event->pszUID; + gcevent.bIsMe = event->bIsMe; + gcevent.bAddToLog = TRUE; + gcevent.time = event->time; + CallService(MS_GC_EVENT, 0, (LPARAM)&gcevent); + + } + if (event->iType == MUCC_EVENT_STATUS) { + const char *groupNames[] = {"Global Owners", "Owners", "Admins", "Moderators", "Users"}; + GCDEST gcdest; + GCEVENT gcevent = {sizeof(GCEVENT), &gcdest}; + gcdest.pszModule = (char *)this->getModule(); + gcdest.pszID = (char *)this->getRoomId(); + gcevent.pszText = event->pszText; + gcevent.pszNick = event->pszNick; + int group = 4; + if (event->dwFlags&MUCC_EF_USER_GLOBALOWNER) { + group = 0; + } else if (event->dwFlags&MUCC_EF_USER_OWNER) { + group = 1; + } else if (event->dwFlags&MUCC_EF_USER_ADMIN) { + group = 2; + } else if (event->dwFlags&MUCC_EF_USER_MODERATOR) { + group = 3; + } + gcevent.pszStatus = Translate(groupNames[group]); + gcevent.pszUID = event->pszUID; + gcevent.bIsMe = event->bIsMe; + gcevent.bAddToLog = TRUE; + gcevent.time = event->time; + if (event->dwData == ID_STATUS_ONLINE) { + gcdest.iType = GC_EVENT_JOIN; + } else { + gcdest.iType = GC_EVENT_PART; + } + CallService(MS_GC_EVENT, 0, (LPARAM)&gcevent); + } + */ + /* chat.dll mod*/ + + int nMin, nMax; + HWND hwndLog; + if (event->iType != MUCC_EVENT_ERROR) { + if (eventList.addEvent(event)) { + rebuildLog(); + return 1; + } + } + if (event->iType == MUCC_EVENT_MESSAGE) { + wasFirstMessage = 1; + appendMessage(event); + container->remoteSetUnread(this, 1); + } else { + appendMessage(event); + } + if (event->iType==MUCC_EVENT_MESSAGE && getOptions() & FLAG_FLASH_MESSAGES) { + container->remoteFlashWindow(); + } else if (event->iType==MUCC_EVENT_STATUS && event->dwData==ID_STATUS_ONLINE && getOptions() & FLAG_FLASH_JOINED) { + container->remoteFlashWindow(); + } else if (event->iType==MUCC_EVENT_STATUS && event->dwData==ID_STATUS_OFFLINE && getOptions() & FLAG_FLASH_LEFT) { + container->remoteFlashWindow(); + } else if (event->iType==MUCC_EVENT_TOPIC && getOptions() & FLAG_FLASH_TOPIC) { + container->remoteFlashWindow(); + } + if (getHWNDLog()==NULL) { + if (ServiceExists(MS_SMILEYADD_REPLACESMILEYS)) PostMessage(getHWND(), WM_TLEN_SMILEY, 0, 0); + hwndLog = GetDlgItem(getHWND(), IDC_LOG); + int len = GetWindowTextLengthA(hwndLog); + SendMessage(hwndLog, EM_SETSEL, len - 1, len - 1); + GetScrollRange(hwndLog, SB_VERT, &nMin, &nMax); + SetScrollPos(hwndLog, SB_VERT, nMax, TRUE); + PostMessage(hwndLog, WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, nMax), (LPARAM) NULL); + } + return 1; +} + +void ChatWindow::createRTFHeader() { + char *rtf; + int i, msgSize; + //, , iFontSize, bItalic, bBold, bUnderline; + rtf = NULL; + JabberStringAppend(&rtf, &msgSize, "{\\rtf1\\ansi\\deff0{\\fonttbl"); + + for (i=0;igetCharSet(), font->getFace()); + } + JabberStringAppend(&rtf, &msgSize, "}{\\colortbl "); + for (i=0;igetColor(); + JabberStringAppend(&rtf, &msgSize, "\\red%d\\green%d\\blue%d;", color&0xFF, (color>>8)&0xFF, (color>>16)&0xFF); + } + JabberStringAppend(&rtf, &msgSize, "}"); +} + + +int ChatWindow::appendMessage(const MUCCEVENT *event) { + char timestampStr[100], str[512]; + char *rtf, *escapedStr = NULL, *escapedNick = NULL; + Font *fontTimestamp, *fontName, *fontMessage; //*fontColon, + int msgSize; + DWORD color; + int iFontSize, bItalic, bBold, bUnderline; + HWND hwndLog; + DBTIMETOSTRING dbtts; + CHARRANGE sel; + SETTEXTEX stt; + //tm *ltime; + + if (event->iType!=MUCC_EVENT_STATUS && event->iType!=MUCC_EVENT_STATUS && event->iType!=MUCC_EVENT_ERROR + && event->iType!=MUCC_EVENT_TOPIC && event->iType != MUCC_EVENT_MESSAGE) { + return 0; + } + if (event->iType==MUCC_EVENT_MESSAGE && !(getOptions() & FLAG_LOG_MESSAGES)) { + return 0; + } else if (event->iType==MUCC_EVENT_STATUS && event->dwData==ID_STATUS_ONLINE && !(getOptions() & FLAG_LOG_JOINED)) { + return 0; + } else if (event->iType==MUCC_EVENT_STATUS && event->dwData==ID_STATUS_OFFLINE && !(getOptions() & FLAG_LOG_LEFT)) { + return 0; + } else if (event->iType==MUCC_EVENT_TOPIC && !(getOptions() & FLAG_LOG_TOPIC)) { + return 0; + } + + if (getHWNDLog()!=NULL) { + IEVIEWEVENTDATA ied; + IEVIEWEVENT iee; + IEVIEWWINDOW iew; + ZeroMemory(&iee, sizeof(iee)); + iee.cbSize = sizeof(iee); + iee.dwFlags = IEEF_NO_UNICODE; + iee.hwnd = hWndLog; + iee.hContact = NULL; + iee.iType = IEE_LOG_MEM_EVENTS; + iee.codepage = CP_ACP; + iee.pszProto = getModule(); + iee.eventData = &ied; + iee.count = 1; + + ied.cbSize = sizeof(IEVIEWEVENTDATA); + if (event->iType==MUCC_EVENT_MESSAGE) { + ied.iType = IEED_MUCC_EVENT_MESSAGE; + } else if (event->iType==MUCC_EVENT_STATUS && event->dwData==ID_STATUS_ONLINE) { + ied.iType = IEED_MUCC_EVENT_JOINED; + } else if (event->iType==MUCC_EVENT_STATUS && event->dwData==ID_STATUS_OFFLINE) { + ied.iType = IEED_MUCC_EVENT_LEFT; + } else if (event->iType==MUCC_EVENT_TOPIC) { + ied.iType = IEED_MUCC_EVENT_TOPIC; + } else if (event->iType==MUCC_EVENT_ERROR) { + ied.iType = IEED_MUCC_EVENT_ERROR; + } + ied.dwFlags = getOptions() & FLAG_FORMAT_ALL; + ied.next = NULL; + ied.color = event->color; + ied.fontSize = event->iFontSize; + ied.fontStyle = event->dwFlags; + ied.fontName = getFontName(event->iFont); + ied.pszNick = event->pszNick; + ied.pszText = event->pszText; + ied.time = event->time; + ied.dwData = getOptions(); // event->dwData; + ied.bIsMe = event->bIsMe; + CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&iee); + + iew.cbSize = sizeof(IEVIEWWINDOW); + iew.iType = IEW_SCROLLBOTTOM; + iew.hwnd = hWndLog; + CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&iew); + return 1; + } + rtf = NULL; + fontTimestamp = FontList::getFont(FontList::FONT_TIMESTAMP); +// fontColon = FontList::getFont(FontList::FONT_COLON); + if (event->iType == MUCC_EVENT_MESSAGE) { + escapedStr=JabberRtfEscape((char *)event->pszText); + escapedNick=JabberRtfEscape((char *)event->pszNick); + if (event->bIsMe) { + fontName = FontList::getFont(FontList::FONT_MYNAME); + fontMessage = FontList::getFont(FontList::FONT_OUTMESSAGE); + } else { + fontName = FontList::getFont(FontList::FONT_OTHERSNAMES); + fontMessage = FontList::getFont(FontList::FONT_INMESSAGE); + } + } else { + fontName = FontList::getFont(FontList::FONT_ERROR); + if (event->iType == MUCC_EVENT_ERROR) { + escapedStr = JabberRtfEscape((char *)event->pszText); + fontMessage = FontList::getFont(FontList::FONT_ERROR); + } else if (event->iType == MUCC_EVENT_STATUS) { + if (event->dwData == ID_STATUS_ONLINE) { + fontMessage = FontList::getFont(FontList::FONT_JOINED); + _snprintf(str, sizeof(str), Translate("%s has joined."), event->pszNick); + } else { + fontMessage = FontList::getFont(FontList::FONT_LEFT); + _snprintf(str, sizeof(str), Translate("%s has left."), event->pszNick); + } + escapedStr = JabberRtfEscape(str); + } else if (event->iType == MUCC_EVENT_TOPIC) { + fontMessage = FontList::getFont(FontList::FONT_TOPIC); + _snprintf(str, sizeof(str), Translate("The topic is %s."), event->pszText); + escapedStr = JabberRtfEscape(str); + } + } + //ltime = localtime(&event->time); + JabberStringAppend(&rtf, &msgSize, "{\\rtf1\\ansi\\deff0{\\fonttbl"); + JabberStringAppend(&rtf, &msgSize, "{\\f0\\fnil\\fcharset%u %s;}", fontTimestamp->getCharSet(), fontTimestamp->getFace()); + JabberStringAppend(&rtf, &msgSize, "{\\f1\\fnil\\fcharset%u %s;}", fontName->getCharSet(), fontName->getFace()); + if (event->iType == MUCC_EVENT_MESSAGE && getOptions()&FLAG_FORMAT_FONT) { + JabberStringAppend(&rtf, &msgSize, "{\\f2\\fnil\\fcharset%u %s;}", fontMessage->getCharSet(), getFontName(event->iFont)); + } else { + JabberStringAppend(&rtf, &msgSize, "{\\f2\\fnil\\fcharset%u %s;}", fontMessage->getCharSet(), fontMessage->getFace()); + } + JabberStringAppend(&rtf, &msgSize, "}{\\colortbl "); + color = fontTimestamp->getColor(); + JabberStringAppend(&rtf, &msgSize, "\\red%d\\green%d\\blue%d;", color&0xFF, (color>>8)&0xFF, (color>>16)&0xFF); + color = fontName->getColor(); + JabberStringAppend(&rtf, &msgSize, "\\red%d\\green%d\\blue%d;", color&0xFF, (color>>8)&0xFF, (color>>16)&0xFF); + if (event->iType == MUCC_EVENT_MESSAGE && getOptions()&FLAG_FORMAT_COLOR && event->color!=0xFFFFFFFF) { + color = event->color; + } else { + color = fontMessage->getColor(); + } + JabberStringAppend(&rtf, &msgSize, "\\red%d\\green%d\\blue%d;", color&0xFF, (color>>8)&0xFF, (color>>16)&0xFF); + JabberStringAppend(&rtf, &msgSize, "}\\pard"); + if (!isEmpty) { + JabberStringAppend(&rtf, &msgSize, "\\par"); + } + isEmpty = false; + if (event->iType == MUCC_EVENT_MESSAGE) { + if (getOptions()&FLAG_SHOW_DATE || getOptions()&FLAG_SHOW_TIMESTAMP) { + bBold = fontTimestamp->getStyle() & Font::BOLD ? 1 : 0; + bItalic = fontTimestamp->getStyle() & Font::ITALIC ? 1 : 0; + bUnderline = fontTimestamp->getStyle() & Font::UNDERLINE ? 1 : 0; + iFontSize = fontTimestamp->getSize(); + iFontSize = 2 * abs((signed char)iFontSize) * 74 / logPixelSY; + dbtts.cbDest = 90; + dbtts.szDest = timestampStr; + timestampStr[0]='\0'; + //time_t time = time + if (getOptions()&FLAG_SHOW_DATE && getOptions()&FLAG_SHOW_TIMESTAMP) { + if (getOptions()&FLAG_LONG_DATE) { + dbtts.szFormat = getOptions()&FLAG_SHOW_SECONDS ? (char *)"D s" : (char *)"D t"; + } else { + dbtts.szFormat = getOptions()&FLAG_SHOW_SECONDS ? (char *)"d s" : (char *)"d t"; + } + } else if (getOptions()&FLAG_SHOW_DATE) { + dbtts.szFormat = getOptions()&FLAG_LONG_DATE ? (char *)"D" : (char *)"d"; + } else if (getOptions()&FLAG_SHOW_TIMESTAMP) { + dbtts.szFormat = getOptions()&FLAG_SHOW_SECONDS ? (char *)"s" : (char *)"t"; + } else { + dbtts.szFormat = (char *)""; + } + CallService(MS_DB_TIME_TIMESTAMPTOSTRING, (WPARAM)event->time, (LPARAM) & dbtts); + JabberStringAppend(&rtf, &msgSize, "\\f0\\cf0\\fs%d\\b%d\\i%d%s %s ", + iFontSize, + bBold, + bItalic, + bUnderline?"\\ul":"", + timestampStr); + } + bBold = fontName->getStyle() & Font::BOLD ? 1 : 0; + bItalic = fontName->getStyle() & Font::ITALIC ? 1 : 0; + bUnderline = fontName->getStyle() & Font::UNDERLINE ? 1 : 0; + iFontSize = fontName->getSize(); + iFontSize = 2 * abs((signed char)iFontSize) * 74 / logPixelSY; + if (getOptions()&FLAG_SHOW_NICKNAMES) { + JabberStringAppend(&rtf, &msgSize, "\\f1\\cf1\\fs%d\\b%d\\i%d%s %s: ", + iFontSize, + bBold, + bItalic, + bUnderline?"\\ul":"", + escapedNick); + } + bBold = fontMessage->getStyle() & Font::BOLD ? 1 : 0; + bItalic = fontMessage->getStyle() & Font::ITALIC ? 1 : 0; + bUnderline = fontMessage->getStyle() & Font::UNDERLINE ? 1 : 0; + iFontSize = fontMessage->getSize(); + iFontSize = 2 * abs((signed char)iFontSize) * 74 / logPixelSY; + if (getOptions()&FLAG_FORMAT_STYLE) { + bBold = bItalic = bUnderline = 0; + if (event->dwFlags & MUCC_EF_FONT_BOLD) bBold = 1; + if (event->dwFlags & MUCC_EF_FONT_ITALIC) bItalic = 1; + if (event->dwFlags & MUCC_EF_FONT_UNDERLINE) bUnderline = 1; + } + if (getOptions()&FLAG_FORMAT_SIZE) { + if (event->iFontSize != 0) iFontSize = 2 * event->iFontSize; + } + if (getOptions()&FLAG_MSGINNEWLINE) { + JabberStringAppend(&rtf, &msgSize, "\\line"); + } + JabberStringAppend(&rtf, &msgSize, "\\f2\\cf2\\fs%d\\b%d\\i%d%s %s", + iFontSize, + bBold, + bItalic, + bUnderline?"\\ul":"", + escapedStr); + } else { + if (event->iType == MUCC_EVENT_ERROR) { + bBold = fontName->getStyle() & Font::BOLD ? 1 : 0; + bItalic = fontName->getStyle() & Font::ITALIC ? 1 : 0; + bUnderline = fontName->getStyle() & Font::UNDERLINE ? 1 : 0; + iFontSize = fontName->getSize(); + iFontSize = 2 * abs((signed char)iFontSize) * 74 / logPixelSY; + JabberStringAppend(&rtf, &msgSize, "\\f1\\cf1\\fs%d\\b%d\\i%d%s %s: ", + iFontSize, + bBold, + bItalic, + bUnderline?"\\ul":"", + Translate("Error")); + } else { + if (getOptions()&FLAG_SHOW_DATE || getOptions()&FLAG_SHOW_TIMESTAMP) { + bBold = fontTimestamp->getStyle() & Font::BOLD ? 1 : 0; + bItalic = fontTimestamp->getStyle() & Font::ITALIC ? 1 : 0; + bUnderline = fontTimestamp->getStyle() & Font::UNDERLINE ? 1 : 0; + iFontSize = fontTimestamp->getSize(); + iFontSize = 2 * abs((signed char)iFontSize) * 74 / logPixelSY; + dbtts.cbDest = 90; + dbtts.szDest = timestampStr; + timestampStr[0]='\0'; + //time_t time = time + if (getOptions()&FLAG_SHOW_DATE && getOptions()&FLAG_SHOW_TIMESTAMP) { + if (getOptions()&FLAG_LONG_DATE) { + dbtts.szFormat = getOptions()&FLAG_SHOW_SECONDS ? (char *)"D s" : (char *)"D t"; + } else { + dbtts.szFormat = getOptions()&FLAG_SHOW_SECONDS ? (char *)"d s" : (char *)"d t"; + } + } else if (getOptions()&FLAG_SHOW_DATE) { + dbtts.szFormat = getOptions()&FLAG_LONG_DATE ? (char *)"D" : (char *)"d"; + } else if (getOptions()&FLAG_SHOW_TIMESTAMP) { + dbtts.szFormat = getOptions()&FLAG_SHOW_SECONDS ? (char *)"s" : (char *)"t"; + } else { + dbtts.szFormat = (char *)""; + } + CallService(MS_DB_TIME_TIMESTAMPTOSTRING, (WPARAM)event->time, (LPARAM) & dbtts); + JabberStringAppend(&rtf, &msgSize, "\\f0\\cf0\\fs%d\\b%d\\i%d%s %s ", + iFontSize, + bBold, + bItalic, + bUnderline?"\\ul":"", + timestampStr); + } + } + bBold = fontMessage->getStyle() & Font::BOLD ? 1 : 0; + bItalic = fontMessage->getStyle() & Font::ITALIC ? 1 : 0; + bUnderline = fontMessage->getStyle() & Font::UNDERLINE ? 1 : 0; + iFontSize = fontMessage->getSize(); + iFontSize = 2 * abs((signed char)iFontSize) * 74 / logPixelSY; + JabberStringAppend(&rtf, &msgSize, "\\f2\\cf2\\fs%d\\b%d\\i%d%s %s", + iFontSize, + bBold, + bItalic, + bUnderline?"\\ul":"", + escapedStr); + } + JabberStringAppend(&rtf, &msgSize, "}"); + hwndLog = GetDlgItem(getHWND(), IDC_LOG); + sel.cpMin = sel.cpMax = GetWindowTextLength(hwndLog); + SendMessage(hwndLog, EM_EXSETSEL, 0, (LPARAM) &sel); + stt.flags = ST_SELECTION; + stt.codepage = CP_ACP; + SendMessage(hwndLog, EM_SETTEXTEX, (WPARAM) &stt, (LPARAM) rtf); + free(rtf); + if (escapedStr!=NULL) free(escapedStr); + if (escapedNick!=NULL) free(escapedNick); + return 1; +} + +void ChatWindow::setFont(int font, int size, int bBold, int bItalic, int bUnderline, COLORREF color) { + if (hEditFont!=NULL) { + DeleteObject(hEditFont); + } + hEditFont = CreateFontA(MulDiv(-size, logPixelSY, 74), 0, 0, 0, bBold?FW_BOLD:FW_NORMAL, + bItalic, bUnderline, 0, 238, OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, + FIXED_PITCH | FF_ROMAN, + getFontName(font)); + SendDlgItemMessage(hWnd, IDC_EDIT, WM_SETFONT, (WPARAM) hEditFont, TRUE); + this->font = font; + this->fontSize = size; + this->bBold = bBold; + this->bItalic = bItalic; + this->bUnderline = bUnderline; + this->fontColor = color; +} + +int ChatWindow::getFontStyle() { + int style = 0; + if (bBold) style |= MUCC_EF_FONT_BOLD; + if (bItalic) style |= MUCC_EF_FONT_ITALIC; + if (bUnderline) style |= MUCC_EF_FONT_UNDERLINE; + return style; +} + +int ChatWindow::getFont() { + return font; +} + +int ChatWindow::getFontSize() { + return fontSize; +} + +COLORREF ChatWindow::getFontColor() { + return fontColor; +} + +void ChatWindow ::queryResultContacts(MUCCQUERYRESULT *queryResult) { + HelperDialog::inviteDlg(this, queryResult); +} + +void ChatWindow ::queryResultUsers(MUCCQUERYRESULT *queryResult) { + if (adminWindow!=NULL) { + adminWindow->queryResultUsers(queryResult); + } +} + +ChatWindow * ChatWindow::getWindow(const char *module, const char *roomId) { + ChatWindow *ptr; + EnterCriticalSection(&mutex); + for (ptr=list;ptr!=NULL;ptr=ptr->getNext()) { + if (strcmp(ptr->getRoomId(), roomId)==0 && strcmp(ptr->getModule(), module)==0) { + break; + } + } + LeaveCriticalSection(&mutex); + return ptr; +} + + +static DWORD CALLBACK EditStreamCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb) +{ + char *szFilename = (char *)dwCookie; + FILE *file; + file = fopen(szFilename, "ab"); + if (file != NULL) { + *pcb = (LONG)fwrite(pbBuff, (size_t)cb, (size_t)1, file); + fclose(file); + return 0; + } + return 1; +} + +static BOOL CALLBACK EditWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + ChatWindow *chat; + chat = (ChatWindow *) GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); + switch (msg) { +// case WM_GETDLGCODE: +// return DLGC_WANTALLKEYS; //DLGC_WANTARROWS|DLGC_WANTCHARS|DLGC_HASSETSEL|DLGC_WANTALLKEYS; + case WM_CHAR: + if (wParam=='\r' || wParam=='\n') { + if (((GetKeyState(VK_CONTROL)&0x8000)==0) == ((Options::getChatWindowOptions() & ChatWindow::FLAG_OPT_SENDONENTER) != 0)) { + PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0); + return FALSE; + } + } + if (wParam == 1 && GetKeyState(VK_CONTROL) & 0x8000) { //ctrl-a + SendMessage(hwnd, EM_SETSEL, 0, -1); + return 0; + } + if (wParam == 23 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-w + SendMessage(GetParent(hwnd), WM_CLOSE, 0, 0); + return 0; + } + break; + } + return CallWindowProc(oldEditWndProc, hwnd, msg, wParam, lParam); +} + +static BOOL CALLBACK SplitterWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + ChatWindow *chat; + chat = (ChatWindow *) GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); + switch (msg) { + case WM_NCHITTEST: + return HTCLIENT; + case WM_SETCURSOR: + RECT rc; + GetClientRect(hwnd, &rc); + SetCursor(rc.right > rc.bottom ? hCurSplitNS : hCurSplitWE); + return TRUE; + case WM_LBUTTONDOWN: + SetCapture(hwnd); + return 0; + case WM_MOUSEMOVE: + if (GetCapture() == hwnd) { + HWND hParent; + RECT rc; + POINT pt; + hParent = GetParent(hwnd); + GetClientRect(hwnd, &rc); + if (rc.right < rc.bottom) { + pt.x = LOWORD(GetMessagePos()); + GetClientRect(hParent, &rc); + ScreenToClient(hParent, &pt); + if (pt.x < chat->vSplitterMinLeft) + pt.x = chat->vSplitterMinLeft; + if (rc.right-pt.x < chat->vSplitterMinRight) + pt.x = rc.right-chat->vSplitterMinRight; + if (chat->vSplitterPos != rc.right-pt.x) { + chat->vSplitterPos = rc.right-pt.x; + SendMessage(hParent, WM_SIZE, SIZE_RESTORED, (rc.bottom<<16)+rc.right); + } + } else { + pt.y = HIWORD(GetMessagePos()); + GetClientRect(hParent, &rc); + ScreenToClient(hParent, &pt); + if (pt.y < chat->hSplitterMinTop) + pt.y = chat->hSplitterMinTop; + if (rc.bottom-pt.y < chat->hSplitterMinBottom) + pt.y = rc.bottom-chat->hSplitterMinBottom; + if (chat->hSplitterPos != rc.bottom-pt.y) { + chat->hSplitterPos = rc.bottom-pt.y; + SendMessage(hParent, WM_SIZE, SIZE_RESTORED, (rc.bottom<<16)+rc.right); + } + } + } + return 0; + case WM_LBUTTONUP: + ReleaseCapture(); + return 0; + } + return CallWindowProc(oldSplitterWndProc, hwnd, msg, wParam, lParam); +} + + + + +static INT_PTR CALLBACK LogDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + int i; + ChatWindow *chatWindow; + chatWindow = (ChatWindow *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + if (msg!=WM_INITDIALOG && chatWindow==NULL) { + return FALSE; + } + switch (msg) { + case WM_INITDIALOG: + HDC hdc; + TranslateDialogDefault(hwndDlg); + hdc = GetDC(NULL); + logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY); + ReleaseDC(NULL, hdc); + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) muccIcon[MUCC_IDI_CHAT]); + + chatWindow = (ChatWindow *) lParam; + chatWindow->setHWND(hwndDlg); + ChatWindow::refreshSettings(0); + oldSplitterWndProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_HSPLIT), GWLP_WNDPROC, (LONG_PTR) SplitterWndProc); + oldSplitterWndProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_VSPLIT), GWLP_WNDPROC, (LONG_PTR) SplitterWndProc); + oldEditWndProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT), GWLP_WNDPROC, (LONG_PTR) EditWndProc); + ShowWindow(GetDlgItem(hwndDlg, IDC_LIST), SW_HIDE); + chatWindow->hSplitterMinTop = 90; + chatWindow->hSplitterMinBottom = 40; + chatWindow->hSplitterPos=50; + chatWindow->vSplitterMinLeft = 100; + chatWindow->vSplitterMinRight = 80; + chatWindow->vSplitterPos=110; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) chatWindow); + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT), GWLP_USERDATA, (LONG_PTR) chatWindow); + chatWindow->refreshSettings(); + + SetWindowTextA(hwndDlg, chatWindow->getRoomName()); + SendDlgItemMessage(hwndDlg, IDC_BOLD, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_BOLD]); + SendDlgItemMessage(hwndDlg, IDC_ITALIC, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_ITALIC]); + SendDlgItemMessage(hwndDlg, IDC_UNDERLINE, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_UNDERLINE]); + SendDlgItemMessage(hwndDlg, IDC_SMILEYBTN, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_SMILEY]); + + SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_LINK); + SendDlgItemMessage(hwndDlg, IDC_LOG, EM_SETUNDOLIMIT, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_LOG, EM_AUTOURLDETECT, (WPARAM) TRUE, 0); + + // LoadImage(hInst, smadd_iconinfo.SmileyIcon, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0)); + SendDlgItemMessage(hwndDlg, IDC_OPTIONS, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_OPTIONS]); + SendDlgItemMessage(hwndDlg, IDC_INVITE, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_INVITE]); + + SendDlgItemMessage(hwndDlg, IDC_TOPIC_BUTTON, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_INVITE, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_BOLD, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_BOLD, BUTTONSETASPUSHBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_ITALIC, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_ITALIC, BUTTONSETASPUSHBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_UNDERLINE, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_UNDERLINE, BUTTONSETASPUSHBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_OPTIONS, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_SMILEYBTN, BUTTONSETASFLATBTN, 0, 0); + + SetWindowLong(GetDlgItem(hwndDlg,IDC_TREELIST),GWL_STYLE,GetWindowLong(GetDlgItem(hwndDlg,IDC_TREELIST),GWL_STYLE)|TVS_NOHSCROLL); + SendDlgItemMessage(hwndDlg,IDC_TREELIST, CCM_SETVERSION,(WPARAM)5,0); + //TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_TREELIST), hImageList, TVSIL_STATE); + TreeView_SetItemHeight(GetDlgItem(hwndDlg, IDC_TREELIST), 16); + TreeView_SetIndent(GetDlgItem(hwndDlg, IDC_TREELIST), 16); + for(i=0;igetFontSizeNum();i++) { + char str[10]; + sprintf(str, "%d", chatWindow->getFontSize(i)); + int n = SendDlgItemMessageA(hwndDlg, IDC_FONTSIZE, CB_ADDSTRING, 0, (LPARAM) str); + SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_SETITEMDATA, n, chatWindow->getFontSize(i)); + } + SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_SETCURSEL, Options::getChatWindowFontSize(), 0); + for(i=0;igetFontNameNum();i++) { + int n = SendDlgItemMessageA(hwndDlg, IDC_FONT, CB_ADDSTRING, 0, (LPARAM) chatWindow->getFontName(i)); + SendDlgItemMessage(hwndDlg, IDC_FONT, CB_SETITEMDATA, n, i); + } + SendDlgItemMessage(hwndDlg, IDC_FONT, CB_SETCURSEL, Options::getChatWindowFont(), 0); + CheckDlgButton(hwndDlg, IDC_BOLD, Options::getChatWindowFontStyle()&Font::BOLD ? TRUE : FALSE); + CheckDlgButton(hwndDlg, IDC_ITALIC, Options::getChatWindowFontStyle()&Font::ITALIC ? TRUE : FALSE); + CheckDlgButton(hwndDlg, IDC_UNDERLINE, Options::getChatWindowFontStyle()&Font::UNDERLINE ? TRUE : FALSE); + SendDlgItemMessage(hwndDlg, IDC_COLOR, CPM_SETCOLOUR, 0, (LPARAM)Options::getChatWindowFontColor()); + chatWindow->setFont(Options::getChatWindowFont(), + chatWindow->getFontSize(Options::getChatWindowFontSize()), + Options::getChatWindowFontStyle()&Font::BOLD ? 1 : 0, + Options::getChatWindowFontStyle()&Font::ITALIC ? 1 : 0, + Options::getChatWindowFontStyle()&Font::UNDERLINE ? 1 : 0, + Options::getChatWindowFontColor()); + if (ServiceExists(MS_IEVIEW_WINDOW) && Options::getChatWindowOptions() & ChatWindow::FLAG_OPT_ENABLEIEVIEW) { + IEVIEWWINDOW ieWindow; + ieWindow.cbSize = sizeof(IEVIEWWINDOW); + ieWindow.iType = IEW_CREATE; + ieWindow.dwFlags = 0; + ieWindow.dwMode = IEWM_MUCC; + ieWindow.parent = hwndDlg; + ieWindow.x = 0; + ieWindow.y = 0; + ieWindow.cx = 200; + ieWindow.cy = 300; + CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); + chatWindow->setHWNDLog(ieWindow.hwnd); + ShowWindow(GetDlgItem(hwndDlg, IDC_LOG), SW_HIDE); + } + SetWindowPos(hwndDlg, HWND_TOP, 0, 0, 540, 370, SWP_NOMOVE | SWP_SHOWWINDOW); + SetFocus(GetDlgItem(hwndDlg, IDC_EDIT)); + chatWindow->clearLog(); + SetEvent(chatWindow->getEvent()); + return TRUE; + break; + case DM_CHAT_EVENT: + MUCCEVENT *mucEvent; + mucEvent = (MUCCEVENT *) lParam; + switch (mucEvent->iType) { + case MUCC_EVENT_MESSAGE: + chatWindow->logEvent(mucEvent); + break; + case MUCC_EVENT_TOPIC: + chatWindow->changeTopic(mucEvent); + break; + case MUCC_EVENT_STATUS: + chatWindow->changePresence(mucEvent); + break; + case MUCC_EVENT_ERROR: + chatWindow->logEvent(mucEvent); + break; + //case MUCC_EVENT_LEAVE: + // DestroyWindow(hwndDlg); + // break; + case MUCC_EVENT_ROOM_INFO: + chatWindow->changeRoomInfo(mucEvent); + break; + } + return TRUE; + case DM_CHAT_QUERY: + MUCCQUERYRESULT *queryResult; + queryResult = (MUCCQUERYRESULT *)lParam; + switch (queryResult->iType) { + case MUCC_EVENT_QUERY_CONTACTS: + chatWindow->queryResultContacts(queryResult); + break; + case MUCC_EVENT_QUERY_USERS: + chatWindow->queryResultUsers(queryResult); + break; + + } + return TRUE; + case WM_SETFOCUS: + SetFocus(GetDlgItem(hwndDlg, IDC_EDIT)); + return TRUE; + case WM_GETMINMAXINFO: + MINMAXINFO *mmi; + mmi = (MINMAXINFO *) lParam; + mmi->ptMinTrackSize.x = 370; + mmi->ptMinTrackSize.y = 130; + return FALSE; + case WM_SIZE: + if (wParam!=SIZE_MINIMIZED) { + int dlgWidth, dlgHeight; + RECT rc; + HDWP hdwp; + GetClientRect(hwndDlg, &rc); + dlgWidth = rc.right-rc.left; + dlgHeight = rc.bottom-rc.top; + if (dlgHeight-chatWindow->hSplitterPos < chatWindow->hSplitterMinTop) { + chatWindow->hSplitterPos = dlgHeight-chatWindow->hSplitterMinTop; + } + if (chatWindow->hSplitterPos < chatWindow->hSplitterMinBottom) { + chatWindow->hSplitterPos = chatWindow->hSplitterMinBottom; + } + if (dlgWidth-chatWindow->vSplitterPos < chatWindow->vSplitterMinLeft) { + chatWindow->vSplitterPos = dlgWidth-chatWindow->vSplitterMinLeft; + } + if (chatWindow->vSplitterPos < chatWindow->vSplitterMinRight) { + chatWindow->vSplitterPos = chatWindow->vSplitterMinRight; + } + + hdwp = BeginDeferWindowPos(15); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_TOPIC), 0, 70, 7, dlgWidth-140, 18, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_LOG), 0, 0, 30, dlgWidth-(chatWindow->vSplitterPos)-2, dlgHeight-(chatWindow->hSplitterPos)-30-26-2, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_TREELIST), 0, dlgWidth-(chatWindow->vSplitterPos)+2, 30, (chatWindow->vSplitterPos)-2, dlgHeight-(chatWindow->hSplitterPos)-30-26-2, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_EDIT), 0, 0, dlgHeight-(chatWindow->hSplitterPos)+2, dlgWidth, (chatWindow->hSplitterPos)-5, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_INVITE), 0, dlgWidth-31, dlgHeight-(chatWindow->hSplitterPos)-26, 31, 24, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_BOLD), 0, 0, dlgHeight-(chatWindow->hSplitterPos)-26, 24, 24, SWP_NOZORDER ); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_ITALIC), 0, 24, dlgHeight-(chatWindow->hSplitterPos)-26, 24, 24, SWP_NOZORDER ); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_UNDERLINE), 0, 48, dlgHeight-(chatWindow->hSplitterPos)-26, 24, 24, SWP_NOZORDER ); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_COLOR), 0, 73, dlgHeight-(chatWindow->hSplitterPos)-25, 22, 22, SWP_NOZORDER ); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_FONT), 0, 98, dlgHeight-(chatWindow->hSplitterPos)-24, 110, 13, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_FONTSIZE), 0, 213, dlgHeight-(chatWindow->hSplitterPos)-24, 38, 13, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_SMILEYBTN), 0, 265, dlgHeight-(chatWindow->hSplitterPos)-26, 24, 24, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_OPTIONS), 0, dlgWidth-79, dlgHeight-(chatWindow->hSplitterPos)-26, 24, 24, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_VSPLIT), 0, dlgWidth-(chatWindow->vSplitterPos)-2, 30, 4, dlgHeight-(chatWindow->hSplitterPos)-30-26-2, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_HSPLIT), 0, 0, dlgHeight-(chatWindow->hSplitterPos)-2, dlgWidth-8, 4, SWP_NOZORDER); + EndDeferWindowPos(hdwp); + if (chatWindow->getHWNDLog()!=NULL) { + IEVIEWWINDOW ieWindow; + ieWindow.cbSize = sizeof(IEVIEWWINDOW); + ieWindow.iType = IEW_SETPOS; + ieWindow.parent = hwndDlg; + ieWindow.hwnd = chatWindow->getHWNDLog(); + ieWindow.x = 0; + ieWindow.y = 30; + ieWindow.cx = dlgWidth-(chatWindow->vSplitterPos)-2; + ieWindow.cy = dlgHeight-(chatWindow->hSplitterPos)-30-26-2; + CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); + } + } + break; + /* + case WM_SYSCOMMAND: + if (wParam == SC_CLOSE) { + SendMessage(hwndDlg, WM_CLOSE, 1, 0); +// muce.iType = MUCC_EVENT_LEAVE; +// muce.pszModule = chatWindow->getModule(); +// muce.pszID = chatWindow->getRoomId(); +// NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); +// delete chatWindow; + return TRUE; + } + break; + */ + case WM_CLOSE: + //if (wParam != 1) { // esc + //return FALSE; + //} + DestroyWindow(hwndDlg); + return TRUE; + case WM_DESTROY: + { + MUCCEVENT muce; + muce.cbSize = sizeof(MUCCEVENT); + muce.iType = MUCC_EVENT_LEAVE; + muce.pszModule = chatWindow->getModule(); + muce.pszID = chatWindow->getRoomId(); + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + if (chatWindow->getHWNDLog()!=NULL) { + IEVIEWWINDOW ieWindow; + ieWindow.cbSize = sizeof(IEVIEWWINDOW); + ieWindow.iType = IEW_DESTROY; + ieWindow.hwnd = chatWindow->getHWNDLog(); + CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); + } + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) NULL); + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_HSPLIT), GWLP_WNDPROC, (LONG_PTR) oldSplitterWndProc); + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_VSPLIT), GWLP_WNDPROC, (LONG_PTR) oldSplitterWndProc); + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT), GWLP_WNDPROC, (LONG_PTR) oldEditWndProc); + delete chatWindow; + break; + } + case WM_TLEN_SMILEY: + if (ServiceExists(MS_SMILEYADD_REPLACESMILEYS)) { + SMADD_RICHEDIT2 smre; + smre.cbSize = sizeof(SMADD_RICHEDIT2); + smre.hwndRichEditControl = GetDlgItem(hwndDlg, IDC_LOG); + smre.Protocolname = (char *)chatWindow->getModule(); + smre.rangeToReplace = NULL; + smre.useSounds = FALSE; + smre.disableRedraw = FALSE; + CallService(MS_SMILEYADD_REPLACESMILEYS, 0, (LPARAM) &smre); + } + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_OPTIONS: + { + MUCCEVENT muce; + HMENU hMenu; + RECT rc; + int iSelection; + hMenu=GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(IDR_CHATOPTIONS)),0); + CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)hMenu,0); + GetWindowRect(GetDlgItem(hwndDlg, IDC_OPTIONS), &rc); + CheckMenuItem(hMenu, ID_OPTIONMENU_SHOWNICKNAMES, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_SHOW_NICKNAMES ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_OPTIONMENU_MSGINNEWLINE, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_MSGINNEWLINE ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_OPTIONMENU_SHOWDATE, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_SHOW_DATE ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_OPTIONMENU_SHOWTIMESTAMP, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_SHOW_TIMESTAMP ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_OPTIONMENU_SHOWSECONDS, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_SHOW_SECONDS ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_OPTIONMENU_USELONGDATE, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_LONG_DATE ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_OPTIONMENU_FORMATFONT, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_FORMAT_FONT ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_OPTIONMENU_FORMATSIZE, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_FORMAT_SIZE ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_OPTIONMENU_FORMATCOLOR, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_FORMAT_COLOR ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_OPTIONMENU_FORMATSTYLE, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_FORMAT_STYLE ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_OPTIONMENU_LOGMESSAGES, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_LOG_MESSAGES ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_OPTIONMENU_LOGJOINED, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_LOG_JOINED ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_OPTIONMENU_LOGLEFT, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_LOG_LEFT ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_OPTIONMENU_LOGTOPIC, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_LOG_TOPIC ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_OPTIONMENU_FLASHMESSAGES, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_FLASH_MESSAGES ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_OPTIONMENU_FLASHJOINED, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_FLASH_JOINED ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_OPTIONMENU_FLASHLEFT, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_FLASH_LEFT ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, ID_OPTIONMENU_FLASHTOPIC, MF_BYCOMMAND | chatWindow->getOptions()&ChatWindow::FLAG_FLASH_TOPIC ? MF_CHECKED : MF_UNCHECKED); + if (chatWindow->getMe()!=NULL) { + if (chatWindow->getMe()->getFlags() & (MUCC_EF_USER_OWNER | MUCC_EF_USER_ADMIN)) { + EnableMenuItem(hMenu, ID_ADMINMENU_ADMIN, MF_BYCOMMAND | MF_ENABLED); + EnableMenuItem(hMenu, ID_ADMINMENU_BROWSE, MF_BYCOMMAND | MF_ENABLED); + } + if (chatWindow->getMe()->getFlags() & MUCC_EF_USER_OWNER) { + EnableMenuItem(hMenu, ID_ADMINMENU_DESTROY, MF_BYCOMMAND | MF_ENABLED); + } + } + iSelection = TrackPopupMenu(hMenu, TPM_RETURNCMD | TPM_TOPALIGN | TPM_LEFTALIGN, rc.left, rc.bottom, 0, hwndDlg, NULL); + DestroyMenu(hMenu); + switch (iSelection) { + case ID_OPTIONMENU_SHOWNICKNAMES: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_SHOW_NICKNAMES); + break; + case ID_OPTIONMENU_MSGINNEWLINE: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_MSGINNEWLINE); + break; + case ID_OPTIONMENU_SHOWDATE: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_SHOW_DATE); + break; + case ID_OPTIONMENU_SHOWTIMESTAMP: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_SHOW_TIMESTAMP); + break; + case ID_OPTIONMENU_SHOWSECONDS: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_SHOW_SECONDS); + break; + case ID_OPTIONMENU_USELONGDATE: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_LONG_DATE); + break; + case ID_OPTIONMENU_FORMATFONT: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_FORMAT_FONT); + break; + case ID_OPTIONMENU_FORMATSIZE: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_FORMAT_SIZE); + break; + case ID_OPTIONMENU_FORMATCOLOR: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_FORMAT_COLOR); + break; + case ID_OPTIONMENU_FORMATSTYLE: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_FORMAT_STYLE); + break; + case ID_OPTIONMENU_LOGMESSAGES: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_LOG_MESSAGES); + break; + case ID_OPTIONMENU_LOGJOINED: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_LOG_JOINED); + break; + case ID_OPTIONMENU_LOGLEFT: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_LOG_LEFT); + break; + case ID_OPTIONMENU_LOGTOPIC: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_LOG_TOPIC); + break; + case ID_OPTIONMENU_FLASHMESSAGES: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_FLASH_MESSAGES); + break; + case ID_OPTIONMENU_FLASHJOINED: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_FLASH_JOINED); + break; + case ID_OPTIONMENU_FLASHLEFT: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_FLASH_LEFT); + break; + case ID_OPTIONMENU_FLASHTOPIC: + chatWindow->setOptions(chatWindow->getOptions()^ChatWindow::FLAG_FLASH_TOPIC); + break; + case ID_OPTIONMENU_SAVEDEFAULT: + Options::setChatWindowOptions(chatWindow->getOptions()); + Options::setChatWindowFont((int)SendDlgItemMessage(hwndDlg, IDC_FONT, CB_GETCURSEL, 0, 0)); + Options::setChatWindowFontSize((int)SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_GETCURSEL, 0, 0)); + Options::setChatWindowFontStyle( + (IsDlgButtonChecked(hwndDlg, IDC_BOLD) ? Font::BOLD : 0) | + (IsDlgButtonChecked(hwndDlg, IDC_ITALIC) ? Font::ITALIC : 0) | + (IsDlgButtonChecked(hwndDlg, IDC_UNDERLINE) ? Font::UNDERLINE : 0) + ); + Options::setChatWindowFontColor((COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLOR, CPM_GETCOLOUR,0,0)); + Options::saveSettings(); + break; + case ID_ADMINMENU_DESTROY: + muce.cbSize = sizeof(MUCCEVENT); + muce.iType = MUCC_EVENT_REMOVE_ROOM; + muce.pszModule = chatWindow->getModule(); + muce.pszID = chatWindow->getRoomId(); + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + DestroyWindow(hwndDlg); + break; + case ID_ADMINMENU_ADMIN: + chatWindow->startAdminDialog(ChatWindow::ADMIN_MODE_KICK); + break; + case ID_ADMINMENU_BROWSE: + chatWindow->startAdminDialog(ChatWindow::ADMIN_MODE_ROLE); + break; + case ID_ADMINMENU_SAVELOG: + if (chatWindow->getHWNDLog()!=NULL) { + IEVIEWEVENT iee; + ZeroMemory(&iee, sizeof(iee)); + iee.cbSize = sizeof(iee); + iee.dwFlags = 0; + iee.hwnd = chatWindow->getHWNDLog(); + iee.hContact = NULL; + iee.iType = IEE_SAVE_DOCUMENT; + CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&iee); + } else { + char szFilename[MAX_PATH]; + strcpy(szFilename, ""); + OPENFILENAMEA ofn={0}; + ofn.lStructSize=sizeof(OPENFILENAME); + ofn.hwndOwner=hwndDlg; + ofn.lpstrFile = szFilename; + ofn.lpstrFilter = "Rich Text File\0*.rtf\0\0"; + ofn.nMaxFile = MAX_PATH; + ofn.nMaxFileTitle = MAX_PATH; + ofn.Flags = OFN_HIDEREADONLY; + ofn.lpstrDefExt = "rtf"; + if (GetSaveFileNameA(&ofn)) { + //remove(szFilename); + EDITSTREAM stream = { 0 }; + stream.dwCookie = (DWORD_PTR)szFilename; + stream.dwError = 0; + stream.pfnCallback = EditStreamCallback; + SendDlgItemMessage(hwndDlg, IDC_LOG, EM_STREAMOUT, SF_RTF | SF_USECODEPAGE, (LPARAM) & stream); + } + } + break; + } + } + break; + case IDC_SMILEYBTN: + SMADD_SHOWSEL smaddInfo; + RECT rc; + smaddInfo.cbSize = sizeof(SMADD_SHOWSEL); + smaddInfo.hwndTarget = GetDlgItem(hwndDlg, IDC_EDIT); + smaddInfo.targetMessage = EM_REPLACESEL; + smaddInfo.targetWParam = TRUE; + smaddInfo.Protocolname = chatWindow->getModule(); + GetWindowRect(GetDlgItem(hwndDlg, IDC_SMILEYBTN), &rc); + smaddInfo.Direction = 0; + smaddInfo.xPosition = rc.left; + smaddInfo.yPosition = rc.top + 24; + if (chatWindow->getHWNDLog() != NULL) { + CallService(MS_IEVIEW_SHOWSMILEYSELECTION, 0, (LPARAM) &smaddInfo); + } else { + CallService(MS_SMILEYADD_SHOWSELECTION, 0, (LPARAM) &smaddInfo); + } + break; + case IDC_INVITE: + { + MUCCEVENT muce; + muce.cbSize = sizeof(MUCCEVENT); + muce.iType = MUCC_EVENT_QUERY_CONTACTS; + muce.pszModule = chatWindow->getModule(); + muce.pszID = chatWindow->getRoomId(); + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + } + break; + case IDC_TOPIC_BUTTON: + HelperDialog::topicDlg(chatWindow); + break; + case IDCANCEL: + DestroyWindow(hwndDlg); + return TRUE; + case IDOK: + { + MUCCEVENT muce; + char text[2048]; + GetDlgItemTextA(hwndDlg, IDC_EDIT, text, sizeof(text)); + SetDlgItemTextA(hwndDlg, IDC_EDIT, ""); + muce.cbSize = sizeof(MUCCEVENT); + muce.iType = MUCC_EVENT_MESSAGE; + muce.pszModule = chatWindow->getModule(); + muce.pszID = chatWindow->getRoomId(); + muce.pszText = text; + muce.iFont = chatWindow->getFont(); + muce.iFontSize = chatWindow->getFontSize(); + muce.dwFlags = chatWindow->getFontStyle(); + muce.color = chatWindow->getFontColor(); + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + } + break; + case IDC_BOLD: + case IDC_ITALIC: + case IDC_UNDERLINE: + if (HIWORD(wParam)==BN_CLICKED) { + chatWindow->setFont((int) SendDlgItemMessage(hwndDlg, IDC_FONT, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONT, CB_GETCURSEL, 0, 0), 0), + (int) SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_GETCURSEL, 0, 0), 0), + IsDlgButtonChecked(hwndDlg, IDC_BOLD), + IsDlgButtonChecked(hwndDlg, IDC_ITALIC), + IsDlgButtonChecked(hwndDlg, IDC_UNDERLINE), + (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLOR, CPM_GETCOLOUR,0,0)); + } + case IDC_FONT: + case IDC_FONTSIZE: + if (HIWORD(wParam)==CBN_SELCHANGE) { + chatWindow->setFont((int) SendDlgItemMessage(hwndDlg, IDC_FONT, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONT, CB_GETCURSEL, 0, 0), 0), + (int) SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_GETCURSEL, 0, 0), 0), + IsDlgButtonChecked(hwndDlg, IDC_BOLD), + IsDlgButtonChecked(hwndDlg, IDC_ITALIC), + IsDlgButtonChecked(hwndDlg, IDC_UNDERLINE), + (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLOR, CPM_GETCOLOUR,0,0)); + } + break; + case IDC_COLOR: + if (HIWORD(wParam)==CPN_COLOURCHANGED) { + InvalidateRect(GetDlgItem(hwndDlg, IDC_EDIT), NULL, FALSE); + chatWindow->setFont((int) SendDlgItemMessage(hwndDlg, IDC_FONT, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONT, CB_GETCURSEL, 0, 0), 0), + (int) SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONTSIZE, CB_GETCURSEL, 0, 0), 0), + IsDlgButtonChecked(hwndDlg, IDC_BOLD), + IsDlgButtonChecked(hwndDlg, IDC_ITALIC), + IsDlgButtonChecked(hwndDlg, IDC_UNDERLINE), + (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLOR, CPM_GETCOLOUR,0,0)); + } + break; + + } + break; + case WM_CTLCOLOREDIT: + if ((HWND) lParam == GetDlgItem(hwndDlg, IDC_EDIT)) { + SetTextColor((HDC) wParam, (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLOR, CPM_GETCOLOUR,0,0)); + SetBkColor((HDC) wParam, Options::getInputBgColor()); + //SelectObject((HDC) wParam, Options::getInputBgBrush()); + return (BOOL) Options::getInputBgBrush(); + } + + break; + case WM_NOTIFY: + LPNMHDR pNmhdr; + pNmhdr = (LPNMHDR)lParam; + if (pNmhdr->idFrom == IDC_TREELIST) { + switch (pNmhdr->code) { + case TVN_ITEMEXPANDING: + { + LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) lParam; + if (pnmtv->action==TVE_COLLAPSE) { + SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT, TRUE); + return TRUE; + } + } + break; + case NM_RCLICK: + { + TVHITTESTINFO hti; + hti.pt.x=(short)LOWORD(GetMessagePos()); + hti.pt.y=(short)HIWORD(GetMessagePos()); + ScreenToClient(pNmhdr->hwndFrom,&hti.pt); + if(TreeView_HitTest(pNmhdr->hwndFrom, &hti) && hti.flags&TVHT_ONITEM) { + TVITEM tvi = {0}; + tvi.mask = TVIF_PARAM|TVIF_HANDLE; + tvi.hItem = hti.hItem; + TreeView_GetItem(pNmhdr->hwndFrom, &tvi); + ChatUser *user = (ChatUser *) tvi.lParam; + if (user!=NULL) { + TreeView_Select(pNmhdr->hwndFrom, tvi.hItem, TVGN_CARET); + if (!user->isMe()) { + HMENU hMenu; + int iSelection; + hMenu = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(IDR_CHATOPTIONS)),1); + CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)hMenu,0); + if (chatWindow->getMe()!=NULL) { + if (chatWindow->getMe()->getFlags() & MUCC_EF_USER_OWNER) { + EnableMenuItem(hMenu, 2, MF_BYPOSITION | MF_ENABLED); + EnableMenuItem(hMenu, 3, MF_BYPOSITION | MF_ENABLED); + EnableMenuItem(hMenu, ID_USERMENU_ADMINISTRATION, MF_BYCOMMAND | MF_ENABLED); + + } else if (chatWindow->getMe()->getFlags() & MUCC_EF_USER_ADMIN) { + if (!(user->getFlags() & (MUCC_EF_USER_OWNER | MUCC_EF_USER_OWNER))) { + EnableMenuItem(hMenu, 2, MF_BYPOSITION | MF_ENABLED); + //EnableMenuItem(hMenu, 3, MF_BYPOSITION | MF_ENABLED); + EnableMenuItem(hMenu, ID_USERMENU_ADMINISTRATION, MF_BYCOMMAND | MF_ENABLED); + } + } + } + //CheckMenuItem(hMenu, ID_USERMENU_MESSAGE, MF_BYCOMMAND | MF_CHECKED : MF_UNCHECKED); + //EnableMenuItem(hMenu, ID_USERMENU_MESSAGE, MF_BYCOMMAND | MF_GRAYED); + iSelection = TrackPopupMenu(hMenu, TPM_RETURNCMD | TPM_TOPALIGN | TPM_LEFTALIGN, (short)LOWORD(GetMessagePos()), (short)HIWORD(GetMessagePos()), 0, hwndDlg, NULL); + DestroyMenu(hMenu); + if (iSelection == ID_USERMENU_MESSAGE) { + chatWindow->startPriv(); + } else if (iSelection >= ID_USERMENU_KICK_NO_BAN && iSelection <= ID_USERMENU_KICK_BAN_4_W) { + int banTime[] = {0, 1, 5, 15, 30, 60, 360, 1440, 4320, 10080, 20160, 40320}; + chatWindow->kickAndBan(banTime[iSelection-ID_USERMENU_KICK_NO_BAN] *60); + } else if (iSelection == ID_USERMENU_RIGHTS_MEMBER) { + chatWindow->setRights(MUCC_EF_USER_MEMBER); + } else if (iSelection == ID_USERMENU_RIGHTS_ADMIN) { + chatWindow->setRights(MUCC_EF_USER_ADMIN); + } else if (iSelection == ID_USERMENU_RIGHTS_NO) { + chatWindow->setRights(0); + } else if (iSelection == ID_USERMENU_ADMINISTRATION) { + chatWindow->startAdminDialog(ChatWindow::ADMIN_MODE_KICK); + } + } + } + } + + } + break; + case NM_CUSTOMDRAW: + LPNMTVCUSTOMDRAW pCustomDraw = (LPNMTVCUSTOMDRAW)lParam; + switch (pCustomDraw->nmcd.dwDrawStage) { + case CDDS_PREPAINT: + SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT,CDRF_NOTIFYITEMDRAW); + return TRUE; + case CDDS_ITEMPREPAINT: + { + TVITEM tvi;; + HICON hIcon; + TCHAR str[200]; + RECT rc = pCustomDraw->nmcd.rc; + tvi.mask = TVIF_HANDLE | TVIF_STATE | TVIF_TEXT | TVIF_PARAM; + tvi.pszText = str; + tvi.cchTextMax = sizeof(str)/sizeof(TCHAR); + tvi.hItem = (HTREEITEM)pCustomDraw->nmcd.dwItemSpec; + TreeView_GetItem(pCustomDraw->nmcd.hdr.hwndFrom, &tvi); + ChatUser * user= (ChatUser *)pCustomDraw->nmcd.lItemlParam; + hIcon = NULL; + pCustomDraw->clrTextBk = Options::getListBgColor(); + switch (pCustomDraw->iLevel) { + case 0: + pCustomDraw->clrText = ChatWindow::getListGroupTextColor(); + SelectObject(pCustomDraw->nmcd.hdc, ChatWindow::getListGroupFont()); + break; + case 1: + pCustomDraw->clrText = ChatWindow::getListTextColor(); + if (pCustomDraw->nmcd.uItemState & CDIS_SELECTED) { // selected (CDIS_FOCUS | + pCustomDraw->clrTextBk = 0xDAC8C2; + } else { + pCustomDraw->clrTextBk = Options::getListBgColor(); + } + if (user!=NULL) { + if (user->getFlags()&MUCC_EF_USER_GLOBALOWNER) { + hIcon = muccIcon[MUCC_IDI_U_GLOBALOWNER]; + } else if (user->getFlags()&MUCC_EF_USER_OWNER) { + hIcon = muccIcon[MUCC_IDI_U_OWNER]; + } else if (user->getFlags()&MUCC_EF_USER_ADMIN) { + hIcon = muccIcon[MUCC_IDI_U_ADMIN]; + } else if (user->getFlags()&MUCC_EF_USER_REGISTERED) { + hIcon = muccIcon[MUCC_IDI_U_REGISTERED]; + } + } + SelectObject(pCustomDraw->nmcd.hdc, ChatWindow::getListFont()); + break; + } + if (rc.bottom-rc.top!=0 && rc.right-rc.left!=0) { + HBRUSH hBr; + hBr = CreateSolidBrush(pCustomDraw->clrTextBk); + FillRect(pCustomDraw->nmcd.hdc, &rc, hBr); + DeleteObject(hBr); + if (hIcon!=NULL) { + DrawIconEx(pCustomDraw->nmcd.hdc, rc.left, rc.top, hIcon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL); + } + SetBkMode(pCustomDraw->nmcd.hdc, TRANSPARENT); + SetTextColor(pCustomDraw->nmcd.hdc, pCustomDraw->clrText); + TextOut(pCustomDraw->nmcd.hdc, + rc.left+pCustomDraw->iLevel*GetSystemMetrics(SM_CXSMICON)+2, + rc.top, tvi.pszText, (int)_tcslen(tvi.pszText)); + } + SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT, CDRF_SKIPDEFAULT ); + return TRUE; + } + } + break; + } + } else if (pNmhdr->idFrom == IDC_LOG) { + switch (((NMHDR *) lParam)->code) { + case EN_MSGFILTER: + switch (((MSGFILTER *) lParam)->msg) { + /* + case WM_LBUTTONDOWN: + { + HCURSOR hCur = GetCursor(); + if (hCur == LoadCursor(NULL, IDC_SIZENS) || hCur == LoadCursor(NULL, IDC_SIZEWE) + || hCur == LoadCursor(NULL, IDC_SIZENESW) || hCur == LoadCursor(NULL, IDC_SIZENWSE)) { + SetWindowLong(hwndDlg, DWL_MSGRESULT, TRUE); + return TRUE; + } + break; + } + case WM_MOUSEMOVE: + { + HCURSOR hCur = GetCursor(); + if (hCur == LoadCursor(NULL, IDC_SIZENS) || hCur == LoadCursor(NULL, IDC_SIZEWE) + || hCur == LoadCursor(NULL, IDC_SIZENESW) || hCur == LoadCursor(NULL, IDC_SIZENWSE)) + SetCursor(LoadCursor(NULL, IDC_ARROW)); + break; + } + */ + case WM_RBUTTONUP: + { + HMENU hMenu, hSubMenu; + POINT pt; + CHARRANGE sel, all = { 0, -1 }; + + hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXT)); + hSubMenu = GetSubMenu(hMenu, 0); + CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM) hSubMenu, 0); + SendMessage(((NMHDR *) lParam)->hwndFrom, EM_EXGETSEL, 0, (LPARAM) & sel); + if (sel.cpMin == sel.cpMax) + EnableMenuItem(hSubMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED); + pt.x = (short) LOWORD(((ENLINK *) lParam)->lParam); + pt.y = (short) HIWORD(((ENLINK *) lParam)->lParam); + ClientToScreen(((NMHDR *) lParam)->hwndFrom, &pt); + switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL)) { + case IDM_COPY: + SendMessage(((NMHDR *) lParam)->hwndFrom, WM_COPY, 0, 0); + break; + case IDM_COPYALL: + SendMessage(((NMHDR *) lParam)->hwndFrom, EM_EXSETSEL, 0, (LPARAM) & all); + SendMessage(((NMHDR *) lParam)->hwndFrom, WM_COPY, 0, 0); + SendMessage(((NMHDR *) lParam)->hwndFrom, EM_EXSETSEL, 0, (LPARAM) & sel); + break; + case IDM_SELECTALL: + SendMessage(((NMHDR *) lParam)->hwndFrom, EM_EXSETSEL, 0, (LPARAM) & all); + break; + case IDM_CLEAR: + chatWindow->clearLog(); + break; + } + DestroyMenu(hMenu); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); + return TRUE; + } + } + break; + case EN_LINK: + switch (((ENLINK *) lParam)->msg) { + case WM_SETCURSOR: + SetCursor(hCurHyperlinkHand); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); + return TRUE; + case WM_RBUTTONDOWN: + case WM_LBUTTONUP: + { + TEXTRANGEA tr; + CHARRANGE sel; + + SendDlgItemMessage(hwndDlg, IDC_LOG, EM_EXGETSEL, 0, (LPARAM) & sel); + if (sel.cpMin != sel.cpMax) + break; + tr.chrg = ((ENLINK *) lParam)->chrg; + tr.lpstrText = (char *)malloc(tr.chrg.cpMax - tr.chrg.cpMin + 8); + SendDlgItemMessageA(hwndDlg, IDC_LOG, EM_GETTEXTRANGE, 0, (LPARAM) & tr); + if (strchr(tr.lpstrText, '@') != NULL && strchr(tr.lpstrText, ':') == NULL && strchr(tr.lpstrText, '/') == NULL) { + MoveMemory(tr.lpstrText + 7, tr.lpstrText, tr.chrg.cpMax - tr.chrg.cpMin + 1); + CopyMemory(tr.lpstrText, "mailto:", 7); + } + if (((ENLINK *) lParam)->msg == WM_RBUTTONDOWN) { + HMENU hMenu, hSubMenu; + POINT pt; + + hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXT)); + hSubMenu = GetSubMenu(hMenu, 1); + CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM) hSubMenu, 0); + pt.x = (short) LOWORD(((ENLINK *) lParam)->lParam); + pt.y = (short) HIWORD(((ENLINK *) lParam)->lParam); + ClientToScreen(((NMHDR *) lParam)->hwndFrom, &pt); + switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL)) { + case IDM_OPENNEW: + CallService(MS_UTILS_OPENURL, 1, (LPARAM) tr.lpstrText); + break; + case IDM_OPENEXISTING: + CallService(MS_UTILS_OPENURL, 0, (LPARAM) tr.lpstrText); + break; + case IDM_COPYLINK: + { + HGLOBAL hData; + if (!OpenClipboard(hwndDlg)) + break; + EmptyClipboard(); + hData = GlobalAlloc(GMEM_MOVEABLE, lstrlenA(tr.lpstrText) + 1); + lstrcpyA((char *)GlobalLock(hData), tr.lpstrText); + GlobalUnlock(hData); + SetClipboardData(CF_TEXT, hData); + CloseClipboard(); + break; + } + } + free(tr.lpstrText); + DestroyMenu(hMenu); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); + return TRUE; + } + else { + CallService(MS_UTILS_OPENURL, 1, (LPARAM) tr.lpstrText); + SetFocus(GetDlgItem(hwndDlg, IDC_EDIT)); + } + free(tr.lpstrText); + break; + } + } + break; + } + } + break; + } + return FALSE; +} + +static char *JabberRtfEscape(char *str) { + char *escapedStr; + int size; + char *p, *q; + + if (str == NULL) + return NULL; + + for (p=str,size=0; *p!='\0'; p++) { + if (*p=='\\' || *p=='{' || *p=='}') + size += 2; + else if (*p=='\n' || *p=='\t') + size += 5; + else + size++; + } + + if ((escapedStr=(char *)malloc(size+1)) == NULL) + return NULL; + + for (p=str,q=escapedStr; *p!='\0'; p++) { + if (strchr("\\{}", *p) != NULL) { + *q++ = '\\'; + *q++ = *p; + } + else if (*p == '\n') { + strcpy(q, "\\par "); + q += 5; + } + else if (*p == '\t') { + strcpy(q, "\\tab "); + q += 5; + } + else { + *q++ = *p; + } + } + *q = '\0'; + + return escapedStr; +} + +static void JabberStringAppend(char **str, int *sizeAlloced, const char *fmt, ...) { + va_list vararg; + char *p; + int size, len; + + if (str == NULL) return; + + if (*str==NULL || *sizeAlloced<=0) { + *sizeAlloced = size = 2048; + *str = (char *) malloc(size); + len = 0; + } + else { + len = (int)strlen(*str); + size = *sizeAlloced - (int)strlen(*str); + } + + p = *str + len; + va_start(vararg, fmt); + while (_vsnprintf(p, size, fmt, vararg) == -1) { + size += 2048; + (*sizeAlloced) += 2048; + *str = (char *) realloc(*str, *sizeAlloced); + p = *str + len; + } + va_end(vararg); +} + + +//static DWORD CALLBACK Log_StreamCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb) +//{ +// StreamData *stream = (StreamData *) dwCookie; +/* + if (lstrdat->buffer == NULL) + { + lstrdat->iColCount = 4; + lstrdat->bufferOffset = 0; + lstrdat->buffer = Log_CreateBody(lstrdat); + lstrdat->bufferLen = lstrlen(lstrdat->buffer); + } + *pcb = min(cb, lstrdat->bufferLen - lstrdat->bufferOffset); + CopyMemory(pbBuff, lstrdat->buffer + lstrdat->bufferOffset, *pcb); + lstrdat->bufferOffset += *pcb; + if (lstrdat->bufferOffset == lstrdat->bufferLen) + { + free(lstrdat->buffer); + lstrdat->buffer = NULL; + } +*/ +// return 0; +//} diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/ChatWindow.h b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatWindow.h new file mode 100644 index 0000000000..37b0b29d6e --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/ChatWindow.h @@ -0,0 +1,196 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +class ChatWindow; + +#ifndef CHATWINDOW_INCLUDED +#define CHATWINDOW_INCLUDED +#include "mucc.h" +#include "ChatEvent.h" +#include "ChatUser.h" +#include "AdminWindow.h" +#include "ChatContainer.h" + +#define DM_CHAT_EVENT (WM_USER+1) +#define DM_CHAT_QUERY (WM_USER+2) +#define WM_TLEN_SMILEY (WM_USER+200) + + +class StreamData { +public: + ChatWindow *chat; + MUCCEVENT *event; +}; + +class ChatWindow{ +private: + static ChatWindow * list; + static CRITICAL_SECTION mutex; + static bool released; + static HFONT hListGroupFont, hListFont; + static COLORREF colorListBg, colorListText, colorListGroupText; + static COLORREF colorInputBg, colorLogBg; + ChatContainer * container; + HANDLE hEvent; + HWND hWnd; + HWND hWndLog; + HFONT hEditFont; + HTREEITEM hUserGroups[5]; + char * module; + char * roomId; + char * roomName; + char * topic; + int options; + int roomFlags; + int font, fontSize; + int bBold, bItalic, bUnderline; + int wasFirstMessage; + bool isEmpty; + COLORREF fontColor; + int isStarted; + ChatWindow * prev; + ChatWindow * next; + int adminDialogMode; + AdminWindow * adminWindow; + ChatUser * users; + ChatUser * userMe; + void addUser(ChatUser *); + void removeUser(ChatUser *); + ChatUser * findUser(const char *); + int getUserGroup(ChatUser *); + ChatUser * getSelectedUser(); + ChatEventList eventList; + void createRTFHeader(); + int appendMessage(const MUCCEVENT *event); + int logMessage(const MUCCEVENT *event); +public: + enum LOGFLAGS { + FLAG_SHOW_NICKNAMES = 0x00000001, + FLAG_MSGINNEWLINE = 0x00000002, + FLAG_OPT_SENDONENTER= 0x00000004, + FLAG_OPT_ENABLEIEVIEW=0x00000008, + + FLAG_SHOW_DATE = 0x00000010, + FLAG_SHOW_TIMESTAMP = 0x00000020, + FLAG_SHOW_SECONDS = 0x00000040, + FLAG_LONG_DATE = 0x00000080, + + FLAG_FORMAT_FONT = 0x00000100, + FLAG_FORMAT_SIZE = 0x00000200, + FLAG_FORMAT_COLOR = 0x00000400, + FLAG_FORMAT_STYLE = 0x00000800, + FLAG_FORMAT_ALL = 0x00000F00, + + FLAG_LOG_MESSAGES = 0x00001000, + FLAG_LOG_JOINED = 0x00002000, + FLAG_LOG_LEFT = 0x00004000, + FLAG_LOG_TOPIC = 0x00008000, + FLAG_LOG_ALL = 0x0000F000, + + FLAG_FLASH_MESSAGES = 0x00010000, + FLAG_FLASH_JOINED = 0x00020000, + FLAG_FLASH_LEFT = 0x00040000, + FLAG_FLASH_TOPIC = 0x00080000, + FLAG_FLASH_ALL = 0x000F0000, + + + }; + + enum ADMINMODES { + ADMIN_MODE_KICK = 1, + ADMIN_MODE_ROLE = 2, + ADMIN_MODE_BROWSER = 3 + }; + int hSplitterPos; + int vSplitterPos; + int hSplitterMinBottom; + int hSplitterMinTop; + int vSplitterMinLeft; + int vSplitterMinRight; + ChatWindow (MUCCWINDOW *); + ~ChatWindow (); + ChatWindow * getNext(); + void setNext(ChatWindow *); + ChatWindow * getPrev(); + ChatContainer* getContainer(); + void setPrev(ChatWindow *); + void setHWND(HWND); + HWND getHWND(); + void setHWNDLog(HWND); + HWND getHWNDLog(); + HANDLE getEvent(); + const char * getModule(); + void setModule(const char *); + const char * getRoomId(); + void setRoomId(const char *); + const char * getRoomName(); + void setRoomName(const char *); + void setOptions(int); + int getOptions(); + void setRoomFlags(int); + int getRoomFlags(); + int getFontSizeNum(); + int getFontSize(int); + int getFontNameNum(); + const char * getFontName(int); + void setFont(int font, int size, int bBold, int bItalic, int bUnderline, COLORREF color); + int getFont(); + int getFontSize(); + int getFontStyle(); + COLORREF getFontColor(); + int start(); + int startPriv(); + void startAdminDialog(int mode); + int kickAndBan(int time); + int kickAndBan(const char *id, int time, const char *); + int unban(const char *id); + int setRights(int flags); + int setRights(const char *id, int flags); + void queryResultContacts(MUCCQUERYRESULT *queryResult); + void queryResultUsers(MUCCQUERYRESULT *queryResult); + void setTreeItem(int, HTREEITEM); + HTREEITEM getTreeItem(int); + ChatUser * findUserByNick(const char *); + ChatUser * getMe(); + void refreshSettings(); + void setAdminWindow(AdminWindow *); + AdminWindow * getAdminWindow(); + void rebuildLog(); + void clearLog(); + int logEvent(const MUCCEVENT *event); + int changePresence(const MUCCEVENT *event); + int changeTopic(const MUCCEVENT *event); + int changeRoomInfo(const MUCCEVENT *event); + int leave(); + + static void refreshSettings(int force); + static HFONT getListGroupFont(); + static HFONT getListFont(); + static COLORREF getListTextColor(); + static COLORREF getListGroupTextColor(); + static int getDefaultOptions(); + + static void init(); + static void release(); + static ChatWindow * getWindow(const char *module, const char *roomId); + +}; +#endif diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/FontList.cpp b/plugins/!NotAdopted/Tlen/tlen_czaty/FontList.cpp new file mode 100644 index 0000000000..4d57617013 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/FontList.cpp @@ -0,0 +1,206 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#include "FontList.h" +#include "Utils.h" + +#define FONTCOUNT 12 +static Font defFonts[] = { + Font("Timestamp","Verdana", DEFAULT_CHARSET, -9, Font::BOLD, 0x000000), +// Font("Colon","Verdana", DEFAULT_CHARSET, -13, 0, 0x808080), + Font("Others names","Verdana", DEFAULT_CHARSET, -13, 0, 0x723732), + Font("Your name","Verdana", DEFAULT_CHARSET, -13, 0, 0x4453A4), + Font("Incoming message","Verdana", DEFAULT_CHARSET, -13, 0, 0x000000), + Font("Outgoing message","Verdana", DEFAULT_CHARSET, -13, 0, 0x505080), + Font("User has joined","Verdana", DEFAULT_CHARSET, -11, Font::ITALIC, 0x0F880F), + Font("User has left","Verdana", DEFAULT_CHARSET, -11, Font::ITALIC, 0x1313B9), + Font("The topic is ...","Verdana", DEFAULT_CHARSET, -13, Font::ITALIC, 0x991A53), + Font("Error","Verdana", DEFAULT_CHARSET, -13, Font::BOLD, 0x1010D0), + Font("Message typing area","Verdana", DEFAULT_CHARSET, -13, 0, 0x000000), + Font("User list","Tahoma", DEFAULT_CHARSET, -11, 0, 0x000000), + Font("User list group","Tahoma", DEFAULT_CHARSET, -11, Font::BOLD, 0x000000) + +}; + +Font::Font() { + name = NULL; + face = NULL; + size = 0; + style = 0; + color = 0; + charSet = DEFAULT_CHARSET; +} + +Font::Font(const char *n, const char *f, int cs, int s, int st, COLORREF c) { + name = NULL; + face = NULL; + size = 0; + style = 0; + color = 0; + setName(n); + setFace(f); + setCharSet(cs); + setSize(s); + setStyle(st); + setColor(c); +} + + +COLORREF Font::getColor() { + return color; +} + +void Font::setColor(COLORREF c) { + color = c; +} + +int Font::getSize() { + return size; +} + +void Font::setSize(int s) { + size = s; +} + +int Font::getStyle() { + return style; +} + +void Font::setStyle(int s) { + style = s; +} + +int Font::getCharSet() { + return charSet; +} + +void Font::setCharSet(int s) { + charSet = s; +} + +void Font::setName(const char *s) { + Utils::copyString(&name, s); +} + +const char *Font::getName() { + return name; +} + +void Font::setFace(const char *s) { + Utils::copyString(&face, s); +} + +const char *Font::getFace() { + return face; +} + +Font *FontList::fonts = NULL; +Font *FontList::fontsSettings = NULL; + +Font *FontList::getFont(int index) { + if (index < FONTCOUNT) return &fonts[index]; + else return NULL; +} + +Font *FontList::getFontSettings(int index) { + if (index < FONTCOUNT) return &fontsSettings[index]; + else return NULL; +} + +void FontList::loadSettings() { + char fontParam[512]; + for (int i=0;iid = NULL; + this->name = NULL; + next = NULL; + Utils::copyString(&this->id, id); + Utils::copyString(&this->name, name); +} +HelperDialog::HelperContact::~HelperContact() { + if (id != NULL) delete id; + if (name != NULL) delete name; +} + +void HelperDialog::HelperContact::setNext(HelperContact *next) { + this->next = next; +} + +const char *HelperDialog::HelperContact::getId() { + return id; +} + +const char *HelperDialog::HelperContact::getName() { + return name; +} + +HelperDialog::HelperContact* HelperDialog::HelperContact::getNext() { + return next; +} + +void HelperDialog::init() { + InitializeCriticalSection(&mutex); +} + +void HelperDialog::release() { + while (list!=NULL) { + delete list; + } + DeleteCriticalSection(&mutex); +} + +HelperDialog::HelperDialog() { + module = nick = reason = roomId = roomName = NULL; + prev = next = NULL; + contactList = NULL; + hWnd = NULL; + hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + EnterCriticalSection(&mutex); + setNext(list); + if (next!=NULL) { + next->setPrev(this); + } + list = this; + LeaveCriticalSection(&mutex); +} + +HelperDialog::HelperDialog(ChatWindow *chat) { + module = nick = reason = roomId = roomName = NULL; + prev = next = NULL; + contactList = NULL; + hWnd = NULL; + hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + setModule(chat->getModule()); + setRoomId(chat->getRoomId()); + setRoomName(chat->getRoomName()); + setRoomFlags(chat->getRoomFlags()); + EnterCriticalSection(&mutex); + setNext(list); + if (next!=NULL) { + next->setPrev(this); + } + list = this; + LeaveCriticalSection(&mutex); +} + +HelperDialog::~HelperDialog() +{ + EnterCriticalSection(&mutex); + if (getPrev()!=NULL) { + getPrev()->setNext(next); + } else { + list = getNext(); + } + if (getNext()!=NULL) { + getNext()->setPrev(prev); + } + LeaveCriticalSection(&mutex); + if (hEvent!=NULL) CloseHandle(hEvent); + if (module!=NULL) delete module; + if (roomId!=NULL) delete roomId; + if (roomName!=NULL) delete roomName; + if (nick!=NULL) delete nick; + if (reason!=NULL) delete reason; + for (HelperContact *ptr2, *ptr=contactList;ptr!=NULL;ptr=ptr2) { + ptr2 = ptr->getNext(); + delete ptr; + } +} +void HelperDialog::setHWND(HWND hWnd) { + this->hWnd = hWnd; +} +HWND HelperDialog::getHWND() { + return hWnd; +} +void HelperDialog::setPrev(HelperDialog *prev) { + this->prev = prev; +} +void HelperDialog::setNext(HelperDialog *next) { + this->next = next; +} +HelperDialog * HelperDialog::getPrev() { + return prev; +} +HelperDialog * HelperDialog::getNext() { + return next; +} +const char *HelperDialog::getModule() +{ + return module; +} +const char *HelperDialog::getRoomId() +{ + return roomId; +} +const char *HelperDialog::getRoomName() +{ + return roomName; +} +const char *HelperDialog::getNick() +{ + return nick; +} +const char *HelperDialog::getReason() +{ + return reason; +} +void HelperDialog::setModule(const char *module) +{ + Utils::copyString(&this->module, module); +} +void HelperDialog::setRoomId(const char *roomId) +{ + Utils::copyString(&this->roomId, roomId); +} +void HelperDialog::setRoomName(const char *roomName) +{ + Utils::copyString(&this->roomName, roomName); +} +void HelperDialog::setNick(const char *nick) +{ + Utils::copyString(&this->nick, nick); +} +void HelperDialog::setReason(const char *reason) +{ + Utils::copyString(&this->reason, reason); +} +void HelperDialog::setRoomFlags(DWORD flags) +{ + this->roomFlags = flags; +} +void HelperDialog::setContactList(MUCCQUERYRESULT *queryResult) { + HelperContact *ptr, *lastptr; + for (ptr=contactList;ptr!=NULL;ptr=ptr->getNext()) { + delete ptr; + } + contactList = NULL; + lastptr = NULL; + for (int i=0;iiItemsNum;i++) { + ptr = new HelperContact(queryResult->pItems[i].pszID, queryResult->pItems[i].pszName); + if (lastptr != NULL) { + lastptr->setNext(ptr); + } else { + contactList = ptr; + } + lastptr = ptr; + } +} + +HelperDialog::HelperContact * HelperDialog::getContactList() { + return contactList; +} + +DWORD HelperDialog::getRoomFlags() { + return roomFlags; +} + +void HelperDialog::inviteDlg(ChatWindow *chat, MUCCQUERYRESULT *queryResult) { + HelperDialog *dialog=new HelperDialog(chat); + dialog->setContactList(queryResult); + Utils::forkThread((void (__cdecl *)(void *))InviteDlgThread, 0, (void *) dialog); + //WaitForSingleObject(dialog->getEvent(), INFINITE); +} + +void HelperDialog::acceptDlg(MUCCEVENT *event) { + HelperDialog *dialog=new HelperDialog(); + dialog->setModule(event->pszModule); + dialog->setRoomId(event->pszID); + dialog->setRoomName(event->pszName); + dialog->setRoomFlags(event->dwFlags); + dialog->setNick(event->pszNick); + // dialog->setReason(event->pszText); + Utils::forkThread((void (__cdecl *)(void *))AcceptInvitationDlgThread, 0, (void *) dialog); +// WaitForSingleObject(hEvent, INFINITE); +} + +void HelperDialog::joinDlg(MUCCEVENT *event) { + HelperDialog *dialog=new HelperDialog(); + dialog->setModule(event->pszModule); + dialog->setRoomId(event->pszID); + dialog->setRoomName(event->pszName); + dialog->setRoomFlags(event->dwFlags); + dialog->setNick(event->pszNick); + Utils::forkThread((void (__cdecl *)(void *))JoinDlgThread, 0, (void *) dialog); + //WaitForSingleObject(dialog->getEvent(), INFINITE); +} + +void HelperDialog::errorDlg(MUCCEVENT *event) { + HelperDialog *dialog=new HelperDialog(); + dialog->setReason(event->pszText); + Utils::forkThread((void (__cdecl *)(void *))ErrorDlgThread, 0, (void *) dialog); + //WaitForSingleObject(dialog->getEvent(), INFINITE); +} + +void HelperDialog::topicDlg(ChatWindow *chat) +{ + HelperDialog *dialog=new HelperDialog(); + dialog->setModule(chat->getModule()); + dialog->setRoomId(chat->getRoomId()); + Utils::forkThread((void (__cdecl *)(void *))TopicDlgThread, 0, (void *) dialog); +} + +static void __cdecl InviteDlgThread(void *vDialog) +{ + DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HELPER_INVITE), NULL, InviteDlgProc, (LPARAM) vDialog); +} + +static void __cdecl AcceptInvitationDlgThread(void *vDialog) +{ + DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HELPER_INVITE_ACCEPT), NULL, AcceptInvitationDlgProc, (LPARAM) vDialog); +} + +static void __cdecl JoinDlgThread(void *vDialog) +{ + DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HELPER_JOIN), NULL, JoinDlgProc, (LPARAM) vDialog); +} + +static void __cdecl TopicDlgThread(void *vDialog) +{ + DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HELPER_TOPIC), NULL, TopicDlgProc, (LPARAM) vDialog); +} + +static INT_PTR CALLBACK InviteDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char str[256]; + HelperDialog::HelperContact *contactList; + HelperDialog *dialog = (HelperDialog *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + dialog = (HelperDialog *) lParam; + TranslateDialogDefault(hwndDlg); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) dialog); + dialog->setHWND(hwndDlg); + SendDlgItemMessage(hwndDlg, IDC_REASON, EM_SETREADONLY, (WPARAM)TRUE, 0); + for (contactList = dialog->getContactList();contactList!=NULL;contactList=contactList->getNext()) { + SendDlgItemMessage(hwndDlg, IDC_USER, CB_ADDSTRING, 0, (LPARAM)contactList->getName()); + } + return TRUE; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_INVITE: + MUCCEVENT muce; + GetDlgItemTextA(hwndDlg, IDC_USER, str, 255); + if (strlen(str)>0) { + for (contactList = dialog->getContactList();contactList!=NULL;contactList=contactList->getNext()) { + if (!strcmp(str, contactList->getName())) { + dialog->setNick(contactList->getId()); + break; + } + } + if (contactList==NULL) { + dialog->setNick(str); + } + } + muce.iType = MUCC_EVENT_INVITE; + muce.pszModule = dialog->getModule(); + muce.pszID = dialog->getRoomId(); + muce.pszNick = dialog->getNick(); + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + case IDCANCEL: + case IDCLOSE: + EndDialog(hwndDlg, 0); + return TRUE; + } + break; + case WM_CLOSE: + EndDialog(hwndDlg, 0); + break; + case WM_DESTROY: + delete dialog; + break; + } + return FALSE; +} + + + + +static INT_PTR CALLBACK AcceptInvitationDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char str[256]; + HelperDialog *dialog; + dialog = (HelperDialog *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + { + dialog = (HelperDialog *) lParam; + TranslateDialogDefault(hwndDlg); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) dialog); + dialog->setHWND(hwndDlg); + if (dialog->getNick() != NULL) { + SetDlgItemTextA(hwndDlg, IDC_FROM, dialog->getNick()); + } + if (dialog->getRoomName() != NULL) { + SetDlgItemTextA(hwndDlg, IDC_ROOM, dialog->getRoomName()); + } + if (dialog->getReason() != NULL) { + SetDlgItemTextA(hwndDlg, IDC_REASON, dialog->getReason()); + } + +// if (!DBGetContactSetting(NULL, jabberProtoName, "LoginName", &dbv)) { +// SetDlgItemText(hwndDlg, IDC_NICK, dbv.pszVal); +// DBFreeVariant(&dbv); +// } + + /* + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) LoadIcon(hInst, MAKEINTRESOURCE(IDI_GROUP))); +*/ + } + return TRUE; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_ACCEPT: + GetDlgItemTextA(hwndDlg, IDC_NICK, str, 255); + dialog->setNick(str); + MUCCEVENT muce; + muce.iType = MUCC_EVENT_JOIN; + muce.pszModule = dialog->getModule(); + muce.pszID = dialog->getRoomId(); + muce.pszName = dialog->getRoomName(); + muce.dwFlags = dialog->getRoomFlags(); + muce.pszNick = NULL; + if (strlen(dialog->getNick())>0) { + muce.pszNick = dialog->getNick(); + } else { + muce.pszNick = NULL; + } + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + case IDCANCEL: + case IDCLOSE: + EndDialog(hwndDlg, 0); + return TRUE; + } + break; + case WM_CLOSE: + EndDialog(hwndDlg, 0); + break; + case WM_DESTROY: + delete dialog; + break; + } + + return FALSE; +} + + +static INT_PTR CALLBACK JoinDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char str[256]; + HelperDialog *dialog; + dialog = (HelperDialog *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + dialog = (HelperDialog *) lParam; + TranslateDialogDefault(hwndDlg); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) dialog); + dialog->setHWND(hwndDlg); + SetFocus(GetDlgItem(hwndDlg, IDOK)); + if (dialog->getRoomFlags() & MUCC_EF_ROOM_NAME) { + SetFocus(GetDlgItem(hwndDlg, IDC_ROOM)); + } else { + SendDlgItemMessage(hwndDlg, IDC_ROOM, EM_SETREADONLY, (WPARAM)TRUE, 0); + } + if (dialog->getRoomFlags() & MUCC_EF_ROOM_NICKNAMES) { + SetFocus(GetDlgItem(hwndDlg, IDC_NICK)); + } else { + SendDlgItemMessage(hwndDlg, IDC_NICK, EM_SETREADONLY, (WPARAM)TRUE, 0); + } + if (dialog->getRoomName()!=NULL) { + SetDlgItemTextA(hwndDlg, IDC_ROOM, dialog->getRoomName()); + } + if (dialog->getNick()!=NULL) { + SetDlgItemTextA(hwndDlg, IDC_NICK, dialog->getNick()); + } + return FALSE; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + MUCCEVENT muce; + if (dialog->getRoomId()==NULL) { + GetDlgItemTextA(hwndDlg, IDC_ROOM, str, 255); + if (strlen(str)>0) { + //dialog->setRoomId(str); + dialog->setRoomName(str); + } + } + GetDlgItemTextA(hwndDlg, IDC_NICK, str, 255); + if (strlen(str)>0) { + dialog->setNick(str); + } else { + dialog->setNick(NULL); + } + muce.iType = MUCC_EVENT_JOIN; + muce.pszModule = dialog->getModule(); + muce.pszID = dialog->getRoomId(); + muce.pszName = dialog->getRoomName(); + muce.pszNick = dialog->getNick(); + muce.dwFlags = dialog->getRoomFlags(); + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + case IDCANCEL: + EndDialog(hwndDlg, 0); + return TRUE; + } + break; + case WM_CLOSE: + EndDialog(hwndDlg, 0); + break; + case WM_DESTROY: + delete dialog; + break; + } + return FALSE; +} + +static void __cdecl ErrorDlgThread(void *vDialog) +{ + HelperDialog *dialog=(HelperDialog *)vDialog; + MessageBoxA(NULL, dialog->getReason(), Translate("Error"), MB_OK | MB_ICONERROR); + /* + int result = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_GROUPCHAT_JOIN), NULL, JoinDlgProc, (LPARAM) dialog); + if (result!=0) { + MUCCEVENT muce; + muce.iType = MUCC_EVENT_JOIN; + muce.pszModule = dialog->getModule(); + muce.pszID = dialog->getRoomId(); + muce.pszName = dialog->getRoomName(); + muce.pszNick = dialog->getNick(); + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + } + */ + delete dialog; +} + +/* +static INT_PTR CALLBACK ErrorDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char str[256]; + HelperDialog *dialog; + dialog = (HelperDialog *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + dialog = (HelperDialog *) lParam; + TranslateDialogDefault(hwndDlg); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) dialog); + dialog->setHWND(hwndDlg); + SetFocus(GetDlgItem(hwndDlg, IDOK)); + if (dialog->getRoomName()!=NULL) { + SetDlgItemTextA(hwndDlg, IDC_ROOM, dialog->getRoomName()); + } + if (dialog->getNick()!=NULL) { + SetDlgItemTextA(hwndDlg, IDC_NICK, dialog->getNick()); + } + return FALSE; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + if (dialog->getRoomId()==NULL) { + GetDlgItemTextA(hwndDlg, IDC_ROOM, str, 255); + if (strlen(str)>0) { + //dialog->setRoomId(str); + dialog->setRoomName(str); + } + } + GetDlgItemTextA(hwndDlg, IDC_NICK, str, 255); + if (strlen(str)>0) { + dialog->setNick(str); + } else { + dialog->setNick(NULL); + } + case IDCANCEL: + EndDialog(hwndDlg, 0); + return TRUE; + } + break; + case WM_CLOSE: + EndDialog(hwndDlg, 0); + break; + case WM_DESTROY: + delete dialog; + break; + } + return FALSE; +} +*/ + +static INT_PTR CALLBACK TopicDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char str[256]; + HelperDialog *dialog; + dialog = (HelperDialog *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + dialog = (HelperDialog *) lParam; + TranslateDialogDefault(hwndDlg); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) dialog); + dialog->setHWND(hwndDlg); + return FALSE; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + MUCCEVENT muce; + GetDlgItemTextA(hwndDlg, IDC_TOPIC, str, 255); + dialog->setReason(str); + muce.cbSize = sizeof(MUCCEVENT); + muce.iType = MUCC_EVENT_TOPIC; + muce.pszID = dialog->getRoomId(); + muce.pszModule = dialog->getModule(); + muce.pszText = dialog->getReason(); + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + case IDCANCEL: + EndDialog(hwndDlg, 0); + return TRUE; + } + break; + case WM_CLOSE: + EndDialog(hwndDlg, 0); + break; + case WM_DESTROY: + delete dialog; + break; + } + return FALSE; +} + diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/HelperDialog.h b/plugins/!NotAdopted/Tlen/tlen_czaty/HelperDialog.h new file mode 100644 index 0000000000..08f856c3a9 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/HelperDialog.h @@ -0,0 +1,95 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#ifndef DIALOGS_INCLUDED +#define DIALOGS_INCLUDED + +#include "mucc.h" +#include "m_mucc.h" +#include "ChatWindow.h" + + +class HelperDialog { +public: + class HelperContact { + private: + char *id; + char *name; + HelperContact *next; + public: + HelperContact(const char *id, const char *name); + ~HelperContact(); + void setNext(HelperContact *); + HelperContact* getNext(); + const char * getId(); + const char * getName(); + }; + +private: + static HelperDialog * list; + static CRITICAL_SECTION mutex; + char * module; + char * roomId; + char * roomName; + DWORD roomFlags; + HelperContact * contactList; + HelperDialog * prev; + HelperDialog * next; + char * nick; + char * reason; + HANDLE hEvent; + HWND hWnd; +public: + HelperDialog(); + HelperDialog(ChatWindow *); + ~HelperDialog(); + void setModule(const char *); + void setRoomId(const char *); + void setRoomName(const char *); + void setRoomFlags(DWORD); + void setNick(const char *); + void setReason(const char *); + void setPrev(HelperDialog *); + HelperDialog* getPrev(); + void setNext(HelperDialog *); + HelperDialog* getNext(); + HWND getHWND(); + void setHWND(HWND hWnd); + void setContactList(MUCCQUERYRESULT *queryResult); + HelperContact* getContactList(); + const char * getModule(); + const char * getRoomId(); + const char * getRoomName(); + DWORD getRoomFlags(); + const char * getNick(); + const char * getReason(); + HANDLE getEvent(); + static void init(); + static void release(); + static void inviteDlg(ChatWindow *chat, MUCCQUERYRESULT *queryResult); + static void acceptDlg(MUCCEVENT *event); + static void joinDlg(MUCCEVENT *event); + static void errorDlg(MUCCEVENT *event); + static void topicDlg(ChatWindow *chat); +}; + + + +#endif diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/ManagerWindow.cpp b/plugins/!NotAdopted/Tlen/tlen_czaty/ManagerWindow.cpp new file mode 100644 index 0000000000..a01caebc15 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/ManagerWindow.cpp @@ -0,0 +1,1067 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#include "ManagerWindow.h" +#include "Utils.h" +#include "HelperDialog.h" + +static INT_PTR CALLBACK ManagerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK ChatRoomsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK MyRoomsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +ManagerWindow * ManagerWindow::list = NULL; +bool ManagerWindow::released = false; +CRITICAL_SECTION ManagerWindow::mutex; + +void ManagerWindow::init() { + released = false; + InitializeCriticalSection(&mutex); +} + +void ManagerWindow::release() { + released = true; + for (ManagerWindow *ptr2, *ptr = list; ptr!=NULL; ptr=ptr2) { + ptr2 = ptr->getNext(); + delete ptr; +// SendMessage(ptr->getHWND(), WM_CLOSE, 0, 0); + } + DeleteCriticalSection(&mutex); +} + +ManagerWindow::ManagerWindow(const char *module) +{ + next = prev = NULL; + groups = NULL; + rooms = NULL; + myRooms = NULL; + currentGroup = NULL; + isStarted = 0; + currentTab = 0; + currentRoomsPage = 0; + lastRoomsPage = 0; + userNickList = userRoomList = 0; + this->module = NULL; + this->moduleName = NULL; + Utils::copyString(&this->module, module); + hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + EnterCriticalSection(&mutex); + setNext(list); + if (next!=NULL) { + next->setPrev(this); + } + list = this; + LeaveCriticalSection(&mutex); +} + +ManagerWindow::~ManagerWindow() +{ + if (!released) { + EnterCriticalSection(&mutex); + if (getPrev()!=NULL) { + getPrev()->setNext(next); + } else { + list = getNext(); + } + if (getNext()!=NULL) { + getNext()->setPrev(prev); + } + LeaveCriticalSection(&mutex); + } + if (hWnd!=NULL) { + EndDialog(hWnd, 0); + } + if (hEvent!=NULL) { + CloseHandle(hEvent); + } + while (groups!=NULL) { + ChatGroup *group = groups; + groups = groups->getListNext(); + delete group; + } + while (rooms!=NULL) { + ChatRoom *room = rooms; + rooms = rooms->getNext(); + delete room; + } + while (myRooms!=NULL) { + ChatRoom *room = myRooms; + myRooms = myRooms->getNext(); + delete room; + } + if (module!=NULL) { + delete module; + } + if (moduleName!=NULL) { + delete moduleName; + } +} +void ManagerWindow::setPrev(ManagerWindow *prev) +{ + this->prev = prev; +} +ManagerWindow * ManagerWindow::getPrev() +{ + return prev; +} +void ManagerWindow::setNext(ManagerWindow *next) +{ + this->next = next; +} +ManagerWindow * ManagerWindow::getNext() +{ + return next; +} +void ManagerWindow::setHWND(HWND h) +{ + hWnd=h; +} +HWND ManagerWindow::getHWND() +{ + return hWnd; +} +void ManagerWindow::setChatRoomsTabHWND(HWND h) +{ + hChatRoomsTabWnd=h; +} +HWND ManagerWindow::getChatRoomsTabHWND() +{ + return hChatRoomsTabWnd; +} +void ManagerWindow::setMyRoomsTabHWND(HWND h) +{ + hMyRoomsTabWnd=h; +} +HWND ManagerWindow::getMyRoomsTabHWND() +{ + return hMyRoomsTabWnd; +} +void ManagerWindow::setMyNicksTabHWND(HWND h) +{ + hMyNicksTabWnd=h; +} +HWND ManagerWindow::getMyNicksTabHWND() +{ + return hMyNicksTabWnd; +} +const char *ManagerWindow::getModule() +{ + return module; +} +const char *ManagerWindow::getModuleName() +{ + return moduleName; +} +void ManagerWindow::setModuleName(const char *moduleName) +{ + Utils::copyString(&this->moduleName, moduleName); +} +ChatGroup *ManagerWindow::getCurrentGroup() +{ + return currentGroup; +} +void ManagerWindow::setCurrentGroup(ChatGroup *group) +{ + currentGroup = group; +} +HANDLE ManagerWindow::getEvent() +{ + return hEvent; +} +int ManagerWindow::getCurrentTab() +{ + return currentTab; +} +void ManagerWindow::setCurrentRoomsPage(int currentRoomsPage) +{ + this->currentRoomsPage = currentRoomsPage; +} +int ManagerWindow::getCurrentRoomsPage() +{ + return currentRoomsPage; +} +void ManagerWindow::setCurrentTab(int currentTab) +{ + this->currentTab = currentTab; +} +void ManagerWindow::setLastRoomsPage(int lastRoomsPage) +{ + this->lastRoomsPage = lastRoomsPage; +} +int ManagerWindow::isLastRoomsPage() +{ + return lastRoomsPage; +} +int ManagerWindow::isUserNickListReceived() +{ + return userNickList; +} +int ManagerWindow::isUserRoomListReceived() +{ + return userRoomList; +} +static void __cdecl StartThread(void *vManager) +{ + OleInitialize(NULL); + DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_CHATMANAGER), NULL, ManagerDlgProc, (LPARAM) vManager); + OleUninitialize(); +} +int ManagerWindow::start() +{ + if (isStarted) { + ShowWindow(hWnd, SW_SHOW); + return 0; + } + isStarted = 1; + Utils::forkThread((void (__cdecl *)(void *))StartThread, 0, (void *) this); + WaitForSingleObject(hEvent, INFINITE); + return 0; +} +void ManagerWindow::queryResultGroups(MUCCQUERYRESULT *queryResult) +{ + TVINSERTSTRUCT tvis; + ChatGroup * par = NULL; + ChatGroup * group; + if (queryResult->pszParent != NULL) { + par = findGroup(queryResult->pszParent); + if (par!=NULL) { + if (par->getChild()!=NULL) return; + } + } + for (int i=0; iiItemsNum; i++) { + group = new ChatGroup(); + group->setId(queryResult->pItems[i].pszID); + group->setName(queryResult->pItems[i].pszName); + if (par!=NULL) { + par->addChild(group); + //group->setParent(par); + tvis.hParent = par->getTreeItem(); + } else { + tvis.hParent = NULL; + } + tvis.hInsertAfter = TVI_SORT; + tvis.item.mask = TVIF_TEXT | TVIF_CHILDREN | TVIF_PARAM; + LPTSTR lps1 = Utils::mucc_mir_a2t(queryResult->pItems[i].pszName); + tvis.item.pszText = lps1; + tvis.item.cChildren = queryResult->pItems[i].iCount; + tvis.item.lParam = (LPARAM) group; + group->setTreeItem(TreeView_InsertItem(GetDlgItem(hWnd, IDC_GROUP), &tvis)); + group->setListNext(groups); + groups = group; + if (par != NULL) { + TreeView_Expand(GetDlgItem(hWnd, IDC_GROUP), par->getTreeItem(), TVE_EXPAND); + } + Utils::mucc_mir_free(lps1); + } +} + +void ManagerWindow::queryResultRooms(MUCCQUERYRESULT *queryResult) +{ + ChatRoom *room; + while (rooms!=NULL) { + room = rooms; + rooms = rooms->getNext(); + delete room; + } + TCHAR str[100]; + if (getCurrentGroup()==NULL || strcmp(getCurrentGroup()->getId(), queryResult->pszParent) || queryResult->iPage!=getCurrentRoomsPage()) return; + setLastRoomsPage(queryResult->iLastPage); + if (queryResult->iLastPage) { + EnableWindow(GetDlgItem(getChatRoomsTabHWND(), IDC_NEXT), FALSE); + } else { + EnableWindow(GetDlgItem(getChatRoomsTabHWND(), IDC_NEXT), TRUE); + } + if (queryResult->iPage>0) { + EnableWindow(GetDlgItem(getChatRoomsTabHWND(), IDC_PREV), TRUE); + } else { + EnableWindow(GetDlgItem(getChatRoomsTabHWND(), IDC_PREV), FALSE); + } + for (int i=0; iiItemsNum; i++) { + LVITEM lvItem; + room = new ChatRoom(); + room->setId(queryResult->pItems[i].pszID); + room->setName(queryResult->pItems[i].pszName); + room->setFlags(queryResult->pItems[i].dwFlags); + room->setNext(rooms); + rooms=room; + lvItem.mask = LVIF_TEXT | LVIF_PARAM; + lvItem.iSubItem = 0; + lvItem.iItem = ListView_GetItemCount(GetDlgItem(getChatRoomsTabHWND(), IDC_ROOM)); + LPTSTR lps1 = Utils::mucc_mir_a2t(queryResult->pItems[i].pszName); + lvItem.pszText = lps1; + lvItem.lParam = (LPARAM) room; + ListView_InsertItem(GetDlgItem(getChatRoomsTabHWND(), IDC_ROOM), &lvItem); + lvItem.iSubItem = 1; + ListView_InsertItem(GetDlgItem(getChatRoomsTabHWND(), IDC_ROOM), &lvItem); + _stprintf(str, _TEXT("%d"), queryResult->pItems[i].iCount); + ListView_SetItemText(GetDlgItem(getChatRoomsTabHWND(), IDC_ROOM), lvItem.iItem, 1, str); + Utils::mucc_mir_free(lps1); + } +} + +void ManagerWindow::queryResultUserRooms(MUCCQUERYRESULT *queryResult) +{ + ChatRoom *room; + ListView_DeleteAllItems(GetDlgItem(getMyRoomsTabHWND(), IDC_LIST)); + while (myRooms!=NULL) { + room = myRooms; + myRooms = myRooms->getNext(); + delete room; + } + for (int i=0; iiItemsNum; i++) { + LVITEM lvItem; + room = new ChatRoom(); + room->setId(queryResult->pItems[i].pszID); + room->setName(queryResult->pItems[i].pszName); + room->setNext(myRooms); + myRooms=room; + lvItem.mask = LVIF_TEXT | LVIF_PARAM; + lvItem.iSubItem = 0; + lvItem.iItem = ListView_GetItemCount(GetDlgItem(getMyRoomsTabHWND(), IDC_LIST)); + LPTSTR lps1 = Utils::mucc_mir_a2t(queryResult->pItems[i].pszName); + lvItem.pszText = lps1; + lvItem.lParam = (LPARAM) room; + ListView_InsertItem(GetDlgItem(getMyRoomsTabHWND(), IDC_LIST), &lvItem); + Utils::mucc_mir_free(lps1); + } + userRoomList = 1; +} + +void ManagerWindow::queryResultUserNick(MUCCQUERYRESULT *queryResult) +{ + ListView_DeleteAllItems(GetDlgItem(getMyNicksTabHWND(), IDC_LIST)); + for (int i=0; iiItemsNum; i++) { + LVITEM lvItem; + lvItem.mask = LVIF_TEXT; + lvItem.iSubItem = 0; + lvItem.iItem = ListView_GetItemCount(GetDlgItem(getMyNicksTabHWND(), IDC_LIST)); + LPTSTR lps1 = Utils::mucc_mir_a2t(queryResult->pItems[i].pszName); + lvItem.pszText = lps1; + ListView_InsertItem(GetDlgItem(getMyNicksTabHWND(), IDC_LIST), &lvItem); + Utils::mucc_mir_free(lps1); + } + userNickList = 1; +} + +ChatGroup *ManagerWindow::findGroup(const char *id) +{ + ChatGroup *group; + for (group = groups;group!=NULL;group=group->getListNext()) { + if (!strcmp(group->getId(), id)) break; + } + return group; +} + + +static INT_PTR CALLBACK ChatRoomsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND lv; + LVCOLUMN lvCol; + ManagerWindow *manager; + manager = (ManagerWindow *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + manager = (ManagerWindow *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) manager); + TranslateDialogDefault(hwndDlg); + manager->setChatRoomsTabHWND(hwndDlg); + SendDlgItemMessage(hwndDlg, IDC_PREV, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_NEXT, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_SEARCH, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_PREV, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_PREV]); + SendDlgItemMessage(hwndDlg, IDC_NEXT, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_NEXT]); + SendDlgItemMessage(hwndDlg, IDC_SEARCH, BM_SETIMAGE, IMAGE_ICON, (LPARAM) muccIcon[MUCC_IDI_SEARCH]); + + lv = GetDlgItem(hwndDlg, IDC_ROOM); + ListView_SetExtendedListViewStyle(lv, LVS_EX_FULLROWSELECT); + lvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; + lvCol.pszText = TranslateT("Name"); + lvCol.cx = 270; + lvCol.iSubItem = 0; + ListView_InsertColumn(lv, 0, &lvCol); + lvCol.pszText = TranslateT("Persons"); + lvCol.cx = 50; + lvCol.iSubItem = 1; + ListView_InsertColumn(lv, 1, &lvCol); + lvCol.pszText = _TEXT("");//Translate(""); + lvCol.cx = 46; + lvCol.iSubItem = 2; + ListView_InsertColumn(lv, 2, &lvCol); + return TRUE; + case WM_NOTIFY: + switch (wParam) { + case IDC_ROOM: + switch (((LPNMHDR)lParam)->code) { + case LVN_COLUMNCLICK: + { + LPNMLISTVIEW pnmlv = (LPNMLISTVIEW) lParam; + if (pnmlv->iSubItem>=0 && pnmlv->iSubItem<=1) { + // if (pnmlv->iSubItem == sortColumn) + // sortAscending = !sortAscending; + // else { + // sortAscending = TRUE; + // sortColumn = pnmlv->iSubItem; + // } + // ListView_SortItems(GetDlgItem(hwndDlg, IDC_ROOM), GroupchatCompare, sortColumn); + } + } + break; + case NM_DBLCLK: + { + LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE) lParam; + LVITEM item; + item.iItem = lpnmitem->iItem; + item.iSubItem = 0; + item.mask = LVIF_PARAM; + if (ListView_GetItem(GetDlgItem(hwndDlg, IDC_ROOM), &item)) { + MUCCEVENT event; + ChatRoom *room = (ChatRoom *)item.lParam; + Utils::log("entering room %s ", room->getId()); + event.cbSize = sizeof(MUCCEVENT); + event.iType = MUCC_EVENT_JOIN; + event.pszModule = manager->getModule(); + event.pszID = room->getId(); + event.pszName = room->getName(); + event.dwFlags = room->getFlags(); + event.pszNick = NULL; + HelperDialog::joinDlg(&event); + } + } + break; + } + break; + } + break; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_NEXT: + if (!manager->isLastRoomsPage()) { + EnableWindow(GetDlgItem(hwndDlg, IDC_PREV), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_NEXT), FALSE); + manager->setCurrentRoomsPage(manager->getCurrentRoomsPage()+1); + SendMessage(GetParent(hwndDlg), WM_MUCC_REFRESH_ROOMS, 0, 0); + } + break; + case IDC_PREV: + if (manager->getCurrentRoomsPage()>0) { + EnableWindow(GetDlgItem(hwndDlg, IDC_PREV), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_NEXT), FALSE); + manager->setCurrentRoomsPage(manager->getCurrentRoomsPage()-1); + } + SendMessage(GetParent(hwndDlg), WM_MUCC_REFRESH_ROOMS, 0, 0); + break; + case IDC_SEARCH: + { + MUCCEVENT event; + event.cbSize = sizeof(MUCCEVENT); + event.iType = MUCC_EVENT_JOIN; + event.dwFlags = MUCC_EF_ROOM_NAME; + event.pszModule = manager->getModule(); + event.pszID = NULL; + event.pszName = NULL; + event.pszNick = NULL; + HelperDialog::joinDlg(&event); + break; + } + } + break; + case WM_MEASUREITEM: + if (wParam == IDC_ROOM) { + MEASUREITEMSTRUCT *lpMis = (MEASUREITEMSTRUCT *) lParam; + lpMis->itemHeight = GetSystemMetrics(SM_CYSMICON); + return TRUE; + } + break; + case WM_DRAWITEM: + if (wParam == IDC_ROOM) { + RECT rc; + int w, x, col; + DRAWITEMSTRUCT *lpDis = (DRAWITEMSTRUCT *) lParam; + ChatRoom *room = NULL; +// if (ListView_GetItem(GetDlgItem(hwndDlg, IDC_ROOM), &item)) { + room = (ChatRoom *)lpDis->itemData;// (ChatRoom *)item.lParam; +// } + TCHAR text[256]; + switch (lpDis->itemAction) { + default: + case ODA_SELECT: + case ODA_DRAWENTIRE: + if (lpDis->itemState & ODS_SELECTED) { + HBRUSH hBrush = CreateSolidBrush(RGB(0xC2, 0xC8, 0xDA));//0xDAC8C2); + FillRect(lpDis->hDC, &(lpDis->rcItem), hBrush);//(HBRUSH) (COLOR_HIGHLIGHT+1)); + DeleteObject(hBrush); + SetTextColor(lpDis->hDC, 0); + SetBkMode(lpDis->hDC, TRANSPARENT); + } + else { +// HBRUSH hBrush = CreateSolidBrush(RGB(0xC2, 0xC8, 0xDA));//0xDAC8C2); + FillRect(lpDis->hDC, &(lpDis->rcItem), (HBRUSH) (COLOR_WINDOW+1)); +// DeleteObject(hBrush); + SetTextColor(lpDis->hDC, RGB(0, 0, 0));//GetSysColor(COLOR_WINDOWTEXT)); +// SetBkColor(lpDis->hDC, GetSysColor(COLOR_WINDOW+1)); + SetBkMode(lpDis->hDC, TRANSPARENT); + } + x = lpDis->rcItem.left; + for (col=0;col<3;col++) { + ListView_GetItemText(GetDlgItem(hwndDlg, IDC_ROOM), lpDis->itemID, col, text, sizeof(text)/sizeof(TCHAR)); + w = ListView_GetColumnWidth(GetDlgItem(hwndDlg, IDC_ROOM), col); + rc.left = x; + rc.top = lpDis->rcItem.top; + rc.bottom = lpDis->rcItem.bottom; + rc.right = x+w; + if (col==0) { + rc.left+=2; + rc.right-=2; + DrawText(lpDis->hDC, text, (int)_tcslen(text), &rc, DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER); + } + else if (col<2) { + DrawText(lpDis->hDC, text, (int)_tcslen(text), &rc, DT_CENTER|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER); + } else { + if (room->getFlags()&MUCC_EF_ROOM_MODERATED) { + DrawIconEx(lpDis->hDC, x, rc.top, muccIcon[MUCC_IDI_R_MODERATED], GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL); + } + if (room->getFlags()&MUCC_EF_ROOM_MEMBERS_ONLY) { + DrawIconEx(lpDis->hDC, x+12+0*GetSystemMetrics(SM_CXSMICON), rc.top, muccIcon[MUCC_IDI_R_MEMBERS], GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL); + } + if (!(room->getFlags()&MUCC_EF_ROOM_NICKNAMES)) { + DrawIconEx(lpDis->hDC, x+24+0*GetSystemMetrics(SM_CXSMICON), rc.top, muccIcon[MUCC_IDI_R_ANONYMOUS], GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL); + } + } + x += w; + } + break; + } + } + break; + } + return FALSE; +} + +static INT_PTR CALLBACK MyRoomsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + RECT rc; + HWND lv; + LVCOLUMN lvCol; + ManagerWindow *manager; + manager = (ManagerWindow *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + manager = (ManagerWindow *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) manager); + TranslateDialogDefault(hwndDlg); + manager->setMyRoomsTabHWND(hwndDlg); + lv = GetDlgItem(hwndDlg, IDC_LIST); + ListView_SetExtendedListViewStyle(lv, LVS_EX_FULLROWSELECT); + GetClientRect(lv, &rc); + lvCol.mask = LVCF_WIDTH; + lvCol.cx = rc.right - rc.left; + ListView_InsertColumn(lv, 0, &lvCol); + return TRUE; + case WM_NOTIFY: + switch (wParam) { + case IDC_LIST: + switch (((LPNMHDR)lParam)->code) { + case NM_DBLCLK: + { + LVITEM item; + item.iItem = ListView_GetSelectionMark(GetDlgItem(hwndDlg, IDC_LIST)); + if (item.iItem >= 0) { + item.iSubItem = 0; + item.mask = LVIF_PARAM; + if (ListView_GetItem(GetDlgItem(hwndDlg, IDC_LIST), &item)) { + ChatRoom *room = (ChatRoom *)item.lParam; + Utils::log("entering room %s (%s)", room->getId(), room->getId()); + MUCCEVENT muce; + muce.cbSize = sizeof(MUCCEVENT); + muce.iType = MUCC_EVENT_JOIN; + muce.pszModule = manager->getModule(); + muce.pszID = room->getId(); + muce.pszName = room->getName(); + muce.dwFlags = MUCC_EF_ROOM_NICKNAMES; + muce.pszNick = NULL; + HelperDialog::joinDlg(&muce); + } + } + } + break; + } + break; + } + break; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_REFRESH: + SendMessage(GetParent(hwndDlg), WM_MUCC_REFRESH_USER_ROOMS, 0, 0); + break; + case IDC_REGISTER: + { + MUCCEVENT muce; + if (manager->getCurrentGroup()!=NULL) { + TCHAR name[256]; + GetDlgItemText(hwndDlg, IDC_NAME, name, 255); + if (_tcslen(name)!=0) { + int flags = 0; + if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_PUBLIC)) { + flags |= MUCC_EF_ROOM_PUBLIC; + } + if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_PERMANENT)) { + flags |= MUCC_EF_ROOM_PERMANENT; + } + if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_MEMBERS)) { + flags |= MUCC_EF_ROOM_MEMBERS_ONLY; + } + if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_NICKNAMES)) { + flags |= MUCC_EF_ROOM_NICKNAMES; + } + muce.cbSize = sizeof(MUCCEVENT); + muce.iType = MUCC_EVENT_REGISTER_ROOM; + muce.pszModule = manager->getModule(); + muce.pszID = manager->getCurrentGroup()->getId(); + char* lps1 = Utils::mucc_mir_t2a(name); + muce.pszName = lps1; + muce.pszNick = NULL; + muce.dwFlags = flags; + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + Utils::mucc_mir_free(lps1); + } + } else { + muce.pszText = "Please select a group first."; + HelperDialog::errorDlg(&muce); + } + } + break; + } + break; + case WM_MEASUREITEM: + if (wParam == IDC_LIST) { + MEASUREITEMSTRUCT *lpMis = (MEASUREITEMSTRUCT *) lParam; + lpMis->itemHeight = 16;//GetSystemMetrics(SM_CYSMICON); + return TRUE; + } + break; + case WM_DRAWITEM: + if (wParam == IDC_LIST) { + TCHAR text[256]; + DRAWITEMSTRUCT *lpDis = (DRAWITEMSTRUCT *) lParam; + switch (lpDis->itemAction) { + default: + case ODA_SELECT: + case ODA_DRAWENTIRE: + if (lpDis->itemState & ODS_SELECTED) { + HBRUSH hBrush = CreateSolidBrush(RGB(0xC2, 0xC8, 0xDA));//0xDAC8C2); + FillRect(lpDis->hDC, &(lpDis->rcItem), hBrush);//(HBRUSH) (COLOR_HIGHLIGHT+1)); + DeleteObject(hBrush); + SetTextColor(lpDis->hDC, 0); + SetBkMode(lpDis->hDC, TRANSPARENT); + } + else { + FillRect(lpDis->hDC, &(lpDis->rcItem), (HBRUSH) (COLOR_WINDOW+1)); + SetTextColor(lpDis->hDC, RGB(0, 0, 0));//GetSysColor(COLOR_WINDOWTEXT)); + SetBkMode(lpDis->hDC, TRANSPARENT); + } + ListView_GetItemText(GetDlgItem(hwndDlg, IDC_LIST), lpDis->itemID, 0, text, sizeof(text)/sizeof(TCHAR)); + DrawText(lpDis->hDC, text, (int)_tcslen(text), &(lpDis->rcItem), DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER); + break; + } + } + break; + + } + return FALSE; +} + +static INT_PTR CALLBACK MyNicksDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + RECT rc; + HWND lv; + LVCOLUMN lvCol; + ManagerWindow *manager; + manager = (ManagerWindow *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + manager = (ManagerWindow *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) manager); + TranslateDialogDefault(hwndDlg); + manager->setMyNicksTabHWND(hwndDlg); + lv = GetDlgItem(hwndDlg, IDC_LIST); + ListView_SetExtendedListViewStyle(lv, LVS_EX_FULLROWSELECT); + GetClientRect(lv, &rc); + lvCol.mask = LVCF_WIDTH; + lvCol.cx = rc.right - rc.left; + ListView_InsertColumn(lv, 0, &lvCol); + return TRUE; + case WM_NOTIFY: + switch (wParam) { + case IDC_LIST: + break; + + } + break; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_REFRESH: + SendMessage(GetParent(hwndDlg), WM_MUCC_REFRESH_USER_NICKS, 0, 0); + break; + case IDC_REGISTER: + { + char nick[256]; + GetDlgItemTextA(hwndDlg, IDC_NICK, nick, 255); + if (strlen(nick)!=0) { + MUCCEVENT muce; + muce.cbSize = sizeof(MUCCEVENT); + muce.iType = MUCC_EVENT_REGISTER_NICK; + muce.pszModule = manager->getModule(); + muce.pszNick = nick; + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + } + } + break; + case IDC_REMOVE: + { + LVITEM item; + item.iItem = ListView_GetSelectionMark(GetDlgItem(hwndDlg, IDC_LIST)); + if (item.iItem >= 0) { + TCHAR text[256]; + item.iSubItem = 0; + item.mask = LVIF_TEXT; + item.pszText = text; + item.cchTextMax = sizeof(text); + if (ListView_GetItem(GetDlgItem(hwndDlg, IDC_LIST), &item)) { + MUCCEVENT muce; + muce.cbSize = sizeof(MUCCEVENT); + muce.iType = MUCC_EVENT_REMOVE_NICK; + muce.pszModule = manager->getModule(); + char* lps2 = Utils::mucc_mir_t2a(text); + muce.pszNick = lps2; + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + Utils::mucc_mir_free(lps2); + } + } + } + } + break; + case WM_MEASUREITEM: + if (wParam == IDC_LIST) { + MEASUREITEMSTRUCT *lpMis = (MEASUREITEMSTRUCT *) lParam; + lpMis->itemHeight = 16;//GetSystemMetrics(SM_CYSMICON); + return TRUE; + } + break; + case WM_DRAWITEM: + if (wParam == IDC_LIST) { + TCHAR text[256]; + DRAWITEMSTRUCT *lpDis = (DRAWITEMSTRUCT *) lParam; + switch (lpDis->itemAction) { + default: + case ODA_SELECT: + case ODA_DRAWENTIRE: + if (lpDis->itemState & ODS_SELECTED) { + HBRUSH hBrush = CreateSolidBrush(RGB(0xC2, 0xC8, 0xDA));//0xDAC8C2); + FillRect(lpDis->hDC, &(lpDis->rcItem), hBrush);//(HBRUSH) (COLOR_HIGHLIGHT+1)); + DeleteObject(hBrush); + SetTextColor(lpDis->hDC, 0); + SetBkMode(lpDis->hDC, TRANSPARENT); + } + else { + FillRect(lpDis->hDC, &(lpDis->rcItem), (HBRUSH) (COLOR_WINDOW+1)); + SetTextColor(lpDis->hDC, RGB(0, 0, 0));//GetSysColor(COLOR_WINDOWTEXT)); + SetBkMode(lpDis->hDC, TRANSPARENT); + } + ListView_GetItemText(GetDlgItem(hwndDlg, IDC_LIST), lpDis->itemID, 0, text, sizeof(text)/sizeof(TCHAR)); + DrawText(lpDis->hDC, text, (int)_tcslen(text), &(lpDis->rcItem), DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER); + break; + } + } + break; + } + return FALSE; +} + +static INT_PTR CALLBACK ManagerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND hwnd, tc; + TCITEM tci; + char text[128]; +// HIMAGELIST hImageList; + ManagerWindow *manager; + MUCCEVENT muce; + int dlgWidth, dlgHeight, tabPos; + RECT rc2; + + manager = (ManagerWindow *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + if (manager==NULL && msg!=WM_INITDIALOG) return FALSE; + switch (msg) { + case WM_INITDIALOG: + // lParam is the initial conference server (if any) + manager = (ManagerWindow *)lParam; + manager->setHWND(hwndDlg); + sprintf(text, "%s Chats", manager->getModuleName()); + SetWindowTextA(hwndDlg, text); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) manager); + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) muccIcon[MUCC_IDI_CHAT]); + + TranslateDialogDefault(hwndDlg); +// sortColumn = -1; + manager->setCurrentTab(0); + tc = GetDlgItem(hwndDlg, IDC_TABS); + tci.mask = TCIF_TEXT; + // Public rooms tab + tci.pszText = TranslateT("Chat rooms"); + TabCtrl_InsertItem(tc, 0, &tci); + // Create room tab + tci.pszText = TranslateT("My rooms"); + TabCtrl_InsertItem(tc, 1, &tci); + tci.pszText = TranslateT("My nicknames"); + TabCtrl_InsertItem(tc, 2, &tci); + hwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_TAB_CHATROOMS), hwndDlg, ChatRoomsDlgProc, (LPARAM) manager); + SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + ShowWindow(hwnd, SW_SHOW); + hwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_TAB_MYROOMS), hwndDlg, MyRoomsDlgProc, (LPARAM) manager); + SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + hwnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_TAB_MYNICKNAMES), hwndDlg, MyNicksDlgProc, (LPARAM) manager); + SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + EnableWindow(GetDlgItem(manager->getChatRoomsTabHWND(), IDC_PREV), FALSE); + EnableWindow(GetDlgItem(manager->getChatRoomsTabHWND(), IDC_NEXT), FALSE); + + GetWindowRect(manager->getMyRoomsTabHWND(), &rc2); + rc2.right-=rc2.left; + rc2.bottom-=rc2.top; + SetWindowPos(hwndDlg, NULL, 0, 0, rc2.right+300, 118+rc2.bottom, SWP_NOMOVE | SWP_NOZORDER); + TreeView_SetItemHeight(GetDlgItem(hwndDlg, IDC_GROUP), 16); +// hImageList=ImageList_Create(100, 100, ILC_COLOR32, 0, 10); +// ListView_SetImageList(GetDlgItem(hwndDlg, IDC_ROOM), hImageList, LVSIL_SMALL); + SetEvent(manager->getEvent()); + muce.cbSize = sizeof(MUCCEVENT); + muce.iType = MUCC_EVENT_QUERY_GROUPS; + muce.pszModule = manager->getModule(); + muce.pszID = NULL; + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + return TRUE; + case WM_SIZING: + RECT *rc, rc2; + rc = (RECT *)lParam; + GetWindowRect(manager->getMyRoomsTabHWND(), &rc2); + rc2.right-=rc2.left; + rc2.bottom-=rc2.top; + if (rc->right-rc->left<(rc2.right+80)) { + if (wParam == WMSZ_RIGHT || wParam == WMSZ_BOTTOMRIGHT || wParam == WMSZ_TOPRIGHT) { + rc->right=rc->left+rc2.right+80; + } else { + rc->left=rc->right-rc2.right-80; + } + } + if (rc->bottom-rc->top<118+rc2.bottom || rc->bottom-rc->top>118+rc2.bottom) { + if (wParam == WMSZ_BOTTOM || wParam == WMSZ_BOTTOMLEFT || wParam == WMSZ_BOTTOMRIGHT) { + rc->bottom=rc->top+118+rc2.bottom; + } else { + rc->top=rc->bottom-118-rc2.bottom; + } + } + return TRUE; + case WM_SIZE: + if (wParam==SIZE_RESTORED || wParam==SIZE_MAXIMIZED) { + HDWP hdwp; + dlgWidth = LOWORD(lParam); + dlgHeight = HIWORD(lParam); + GetWindowRect(manager->getMyRoomsTabHWND(), &rc2); + rc2.right-=rc2.left; + rc2.bottom-=rc2.top; + tabPos = dlgWidth - rc2.right - 15; + hdwp = BeginDeferWindowPos(6); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_TABS), 0, tabPos, 10, 0, 0, SWP_NOZORDER | SWP_NOSIZE); + hdwp = DeferWindowPos(hdwp, manager->getChatRoomsTabHWND(), 0, tabPos+3, 45, 371, 292, SWP_NOZORDER | SWP_NOSIZE); + hdwp = DeferWindowPos(hdwp, manager->getMyRoomsTabHWND() , 0, tabPos+3, 45, 371, 292, SWP_NOZORDER | SWP_NOSIZE); + hdwp = DeferWindowPos(hdwp, manager->getMyNicksTabHWND() , 0, tabPos+3, 45, 371, 292, SWP_NOZORDER | SWP_NOSIZE); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDC_GROUP), 0, 0, 0, tabPos-16, dlgHeight-40, SWP_NOZORDER | SWP_NOMOVE); + hdwp = DeferWindowPos(hdwp, GetDlgItem(hwndDlg, IDCLOSE), 0, dlgWidth-88, dlgHeight-34, 0, 0 , SWP_NOZORDER | SWP_NOSIZE); + EndDeferWindowPos(hdwp); + } + break; + case WM_NOTIFY: + switch (wParam) { + case IDC_GROUP: + switch (((LPNMHDR)lParam)->code) { + case TVN_ITEMEXPANDING: + { + LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) lParam; + if (pnmtv->action==TVE_EXPAND) { + TVITEM item = (TVITEM) pnmtv->itemNew; + ChatGroup *group = (ChatGroup *) item.lParam;// manager->findGroup(item.hItem); + if (group!=NULL) { + if (group->getChild()==NULL) { + muce.cbSize = sizeof(MUCCEVENT); + muce.iType = MUCC_EVENT_QUERY_GROUPS; + muce.pszModule = manager->getModule(); + muce.pszID = group->getId(); + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + } + } + } + } + break; + case TVN_SELCHANGED: + { + LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) lParam; + TVITEM item = (TVITEM) pnmtv->itemNew; + ChatGroup *group = (ChatGroup *) item.lParam;// manager->findGroup(item.hItem); + if (group!=NULL) { + EnableWindow(GetDlgItem(manager->getChatRoomsTabHWND(), IDC_PREV), FALSE); + EnableWindow(GetDlgItem(manager->getChatRoomsTabHWND(), IDC_NEXT), FALSE); + ListView_DeleteAllItems(GetDlgItem(manager->getChatRoomsTabHWND(), IDC_ROOM)); + manager->setCurrentGroup(group); + manager->setCurrentRoomsPage(0); + muce.cbSize = sizeof(MUCCEVENT); + muce.iType = MUCC_EVENT_QUERY_ROOMS; + muce.pszModule = manager->getModule(); + muce.pszID = (char *)group->getId(); + muce.dwData = 0; + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + } + } + break; + case NM_CUSTOMDRAW: + { + if (((LPNMHDR)lParam)->idFrom == IDC_GROUP) { + LPNMTVCUSTOMDRAW pCustomDraw = (LPNMTVCUSTOMDRAW)lParam; + switch (pCustomDraw->nmcd.dwDrawStage) { + case CDDS_PREPAINT: + SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT,CDRF_NOTIFYITEMDRAW); + return TRUE; + case CDDS_ITEMPREPAINT: + { + if (pCustomDraw->nmcd.uItemState & CDIS_FOCUS) { // selected (CDIS_FOCUS | CDIS_SELECTED + pCustomDraw->clrText = 0; + pCustomDraw->clrTextBk = 0xDAC8C2; + } + else { + pCustomDraw->clrText = 0; + } + // HBRUSH hBr; + // hBr = CreateSolidBrush(pCustomDraw->clrTextBk);//g_LogOptions.crUserListBGColor ) ; + // FillRect(pCustomDraw->nmcd.hdc, &rc, hBr); + // DeleteObject(hBr); + SetWindowLongPtr(hwndDlg,DWLP_MSGRESULT, CDRF_NEWFONT); + return TRUE; + } + } + } + } + break; + } + break; + case IDC_TABS: + switch (((LPNMHDR) lParam)->code) { + case TCN_SELCHANGE: + switch (manager->getCurrentTab()) { + case 0: + ShowWindow(manager->getChatRoomsTabHWND(), SW_HIDE); + break; + case 1: + ShowWindow(manager->getMyRoomsTabHWND(), SW_HIDE); + break; + case 2: + ShowWindow(manager->getMyNicksTabHWND(), SW_HIDE); + break; + } + manager->setCurrentTab(TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_TABS))); + switch (manager->getCurrentTab()) { + case 0: + ShowWindow(manager->getChatRoomsTabHWND(), SW_SHOW); + break; + case 1: + ShowWindow(manager->getMyRoomsTabHWND(), SW_SHOW); + if (!manager->isUserRoomListReceived()) { + SendMessage(hwndDlg, WM_MUCC_REFRESH_USER_ROOMS, 0, 0); + } + break; + case 2: + ShowWindow(manager->getMyNicksTabHWND(), SW_SHOW); + if (!manager->isUserNickListReceived()) { + SendMessage(hwndDlg, WM_MUCC_REFRESH_USER_NICKS, 0, 0); + } + break; + } + break; + } + break; + } + break; + case WM_MUCC_REFRESH_USER_ROOMS: + muce.cbSize = sizeof(MUCCEVENT); + muce.iType = MUCC_EVENT_QUERY_USER_ROOMS; + muce.pszModule = manager->getModule(); + muce.pszID = NULL; + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + break; + case WM_MUCC_REFRESH_USER_NICKS: + muce.cbSize = sizeof(MUCCEVENT); + muce.iType = MUCC_EVENT_QUERY_USER_NICKS; + muce.pszModule = manager->getModule(); + muce.pszID = NULL; + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + break; + case WM_MUCC_REFRESH_ROOMS: + { + ChatGroup *group = manager->getCurrentGroup(); + if (manager->getCurrentGroup()!=NULL) { + EnableWindow(GetDlgItem(manager->getChatRoomsTabHWND(), IDC_PREV), FALSE); + EnableWindow(GetDlgItem(manager->getChatRoomsTabHWND(), IDC_NEXT), FALSE); + ListView_DeleteAllItems(GetDlgItem(manager->getChatRoomsTabHWND(), IDC_ROOM)); + /* + * TODO: delete rooms here !!! + */ + muce.cbSize = sizeof(MUCCEVENT); + muce.iType = MUCC_EVENT_QUERY_ROOMS; + muce.pszModule = manager->getModule(); + muce.pszID = (char *)group->getId(); + muce.dwData = manager->getCurrentRoomsPage(); + NotifyEventHooks(hHookEvent, 0,(WPARAM)&muce); + } + } + break; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDCLOSE: + ShowWindow(hwndDlg, SW_HIDE); + break; + } + break; + case WM_CLOSE: + ShowWindow(hwndDlg, SW_HIDE); + break; + + } + return FALSE; +} + +ManagerWindow* ManagerWindow::getWindow(const char *module) { + ManagerWindow *ptr; + EnterCriticalSection(&mutex); + for (ptr=list;ptr!=NULL;ptr=ptr->getNext()) { + if (strcmp(ptr->getModule(), module)==0) { + break; + } + } + LeaveCriticalSection(&mutex); + if (ptr==NULL) { + ptr = new ManagerWindow(module); + } + return ptr; +} + diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/ManagerWindow.h b/plugins/!NotAdopted/Tlen/tlen_czaty/ManagerWindow.h new file mode 100644 index 0000000000..f57d1c1057 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/ManagerWindow.h @@ -0,0 +1,93 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#ifndef MANAGERWINDOW_INCLUDED +#define MANAGERWINDOW_INCLUDED +#include "mucc.h" +#include "ChatGroup.h" +#include "ChatRoom.h" + +class ManagerWindow{ + +private: + static CRITICAL_SECTION mutex; + static bool released; + static ManagerWindow * list; + HWND hWnd; + HWND hChatRoomsTabWnd; + HWND hMyRoomsTabWnd; + HWND hMyNicksTabWnd; + HANDLE hEvent; + ManagerWindow * prev; + ManagerWindow * next; + ChatGroup * groups; + ChatRoom * rooms; + ChatRoom * myRooms; + char * module; + char * moduleName; + ChatGroup * currentGroup; + int isStarted; + int userNickList, userRoomList; + int currentTab; + int currentRoomsPage; + int lastRoomsPage; +public: + ManagerWindow (const char *module); + ~ManagerWindow (); + int start(); + ChatGroup * findGroup(const char *id); + void queryResultGroups(MUCCQUERYRESULT *queryResult); + void queryResultRooms(MUCCQUERYRESULT *queryResult); + void queryResultUserRooms(MUCCQUERYRESULT *queryResult); + void queryResultUserNick(MUCCQUERYRESULT *queryResult); + ManagerWindow * getNext(); + void setNext(ManagerWindow *); + ManagerWindow * getPrev(); + void setPrev(ManagerWindow *); + void setHWND(HWND); + HWND getHWND(); + HANDLE getEvent(); + void setChatRoomsTabHWND(HWND); + HWND getChatRoomsTabHWND(); + void setMyNicksTabHWND(HWND); + HWND getMyNicksTabHWND(); + void setMyRoomsTabHWND(HWND); + HWND getMyRoomsTabHWND(); + void setModuleName(const char *moduleName); + void setCurrentTab(int); + int getCurrentTab(); + const char * getModule(); + const char * getModuleName(); + void setCurrentGroup(ChatGroup *); + ChatGroup * getCurrentGroup(); + void setCurrentRoomsPage(int); + int getCurrentRoomsPage(); + void setLastRoomsPage(int); + int isLastRoomsPage(); + int isUserRoomListReceived(); + int isUserNickListReceived(); + + static ManagerWindow* getWindow(const char *module); + static void release(); + static void init(); + +}; +#endif + diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/Options.cpp b/plugins/!NotAdopted/Tlen/tlen_czaty/Options.cpp new file mode 100644 index 0000000000..8e0f093ddd --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/Options.cpp @@ -0,0 +1,789 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "mucc.h" +#include "Options.h" +#include "ChatWindow.h" +#include "Utils.h" +#include "resource.h" +#include +#include "m_ieview.h" + +static INT_PTR CALLBACK MUCCOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +//static INT_PTR CALLBACK MUCCLogOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +//static INT_PTR CALLBACK MUCCPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + + +COLORREF Options::colorListBg, Options::colorInputBg, Options::colorLogBg, Options::chatWindowFontColor; +HBRUSH Options::brushListBg=NULL, Options::brushInputBg=NULL, Options::brushLogBg=NULL; +int Options::logLimit, Options::chatWindowOptions, Options::chatContainerOptions; +int Options::chatWindowFont, Options::chatWindowFontSize, Options::chatWindowFontStyle; + +void Options::setListBgColor(COLORREF c) { + colorListBg = c; + if (brushListBg != NULL) { + DeleteObject(brushListBg); + } + brushListBg = CreateSolidBrush(colorListBg); +} + +void Options::setInputBgColor(COLORREF c) { + colorInputBg = c; + if (brushInputBg!= NULL) { + DeleteObject(brushInputBg); + } + brushInputBg = CreateSolidBrush(colorInputBg); +} + +void Options::setLogBgColor(COLORREF c) { + colorLogBg = c; + if (brushLogBg!= NULL) { + DeleteObject(brushLogBg); + } + brushLogBg = CreateSolidBrush(colorLogBg); +} + +COLORREF Options::getListBgColor() { + return colorListBg; +} + +COLORREF Options::getInputBgColor() { + return colorInputBg; +} + +COLORREF Options::getLogBgColor() { + return colorLogBg; +} + +HBRUSH Options::getListBgBrush() { + return brushListBg; +} + +HBRUSH Options::getInputBgBrush() { + return brushInputBg; +} + +HBRUSH Options::getLogBgBrush() { + return brushLogBg; +} + +void Options::setLogLimit(int l) { + logLimit = l; +} + +int Options::getLogLimit() { + return logLimit; +} + +void Options::setChatWindowFont(int o) { + chatWindowFont = o; +} + +int Options::getChatWindowFont() { + return chatWindowFont; +} + +void Options::setChatWindowFontSize(int o) { + chatWindowFontSize = o; +} + +int Options::getChatWindowFontSize() { + return chatWindowFontSize; +} + +void Options::setChatWindowFontStyle(int o) { + chatWindowFontStyle = o; +} + +int Options::getChatWindowFontStyle() { + return chatWindowFontStyle; +} + +void Options::setChatWindowFontColor(COLORREF o) { + chatWindowFontColor = o; +} + +COLORREF Options::getChatWindowFontColor() { + return chatWindowFontColor; +} + +void Options::setChatWindowOptions(int o) { + chatWindowOptions = o; +} + +int Options::getChatWindowOptions() { + return chatWindowOptions; +} + +void Options::setChatContainerOptions(int o) { + chatContainerOptions = o; +} + +int Options::getChatContainerOptions() { + return chatContainerOptions; +} + +void Options::setExpandFlags(int o) { + DBWriteContactSettingDword(NULL, muccModuleName, "ExpandFlags", o); +} + +int Options::getExpandFlags() { + return DBGetContactSettingDword(NULL, muccModuleName, "ExpandFlags", 0xFFFFFFFF); +} + +void Options::loadSettings() { + FontList::loadSettings(); + setLogBgColor((COLORREF)DBGetContactSettingDword(NULL, muccModuleName, "BackgroundLog", 0xFFFFFF)); + setListBgColor((COLORREF)DBGetContactSettingDword(NULL, muccModuleName, "BackgroundList", 0xFFFFFF)); + setInputBgColor((COLORREF)DBGetContactSettingDword(NULL, muccModuleName, "BackgroundTyping", 0xFFFFFF)); + setLogLimit(DBGetContactSettingDword(NULL, muccModuleName, "LogSizeLimit", 100)); + setChatContainerOptions(DBGetContactSettingDword(NULL, muccModuleName, "ChatContainerOptions", ChatContainer::getDefaultOptions())); + setChatWindowOptions(DBGetContactSettingDword(NULL, muccModuleName, "ChatWindowOptions", ChatWindow::getDefaultOptions())); + setChatWindowFont(DBGetContactSettingDword(NULL, muccModuleName, "ChatWindowFont", 0)); + setChatWindowFontSize(DBGetContactSettingDword(NULL, muccModuleName, "ChatWindowFontSize", 5)); + setChatWindowFontStyle(DBGetContactSettingDword(NULL, muccModuleName, "ChatWindowFontStyle", 0)); + setChatWindowFontColor(DBGetContactSettingDword(NULL, muccModuleName, "ChatWindowFontColor", 0)); +} + +void Options::saveSettings() { + FontList::saveSettings(); + DBWriteContactSettingDword(NULL, muccModuleName, "BackgroundLog", colorLogBg); + DBWriteContactSettingDword(NULL, muccModuleName, "BackgroundList", colorListBg); + DBWriteContactSettingDword(NULL, muccModuleName, "BackgroundTyping", colorInputBg); + DBWriteContactSettingDword(NULL, muccModuleName, "LogSizeLimit", logLimit); + DBWriteContactSettingDword(NULL, muccModuleName, "ChatContainerOptions", chatContainerOptions); + DBWriteContactSettingDword(NULL, muccModuleName, "ChatWindowOptions", chatWindowOptions); + DBWriteContactSettingDword(NULL, muccModuleName, "ChatWindowFont", chatWindowFont); + DBWriteContactSettingDword(NULL, muccModuleName, "ChatWindowFontSize", chatWindowFontSize); + DBWriteContactSettingDword(NULL, muccModuleName, "ChatWindowFontStyle", chatWindowFontStyle); + DBWriteContactSettingDword(NULL, muccModuleName, "ChatWindowFontColor", chatWindowFontColor); +} + +void Options::init() +{ + FontList::init(); + loadSettings(); +} + +int MUCCOptInit(WPARAM wParam, LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp; + + ZeroMemory(&odp, sizeof(odp)); + odp.cbSize = sizeof(odp); + odp.position = 0; + odp.hInstance = hInst; + odp.pszGroup = Translate("Network"); + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); +// odp.pszTitle = muccModuleName; + odp.pszTitle = "Tlen czaty"; + odp.flags = ODPF_BOLDGROUPS; + odp.pfnDlgProc = MUCCOptDlgProc; + odp.nIDBottomSimpleControl = 0; + CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) &odp); + + /* + odp.pszTemplate = MAKEINTRESOURCE(IDD_OPTIONS_LOG); + _snprintf(str, sizeof(str), "%s %s", muccModuleName, Translate("Log")); + str[sizeof(str)-1] = '\0'; + odp.pszTitle = str; + odp.pfnDlgProc = MUCCLLogOptDlgProc; + odp.flags = ODPF_BOLDGROUPS|ODPF_EXPERTONLY; + odp.nIDBottomSimpleControl = 0; + CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) &odp); + if (ServiceExists(MS_POPUP_ADDPOPUP)) { + ZeroMemory(&odp,sizeof(odp)); + odp.cbSize = sizeof(odp); + odp.position = 100000000; + odp.hInstance = hInst; + odp.pszGroup = Translate("PopUps"); + odp.pszTemplate = MAKEINTRESOURCE(IDD_OPTIONS_POPUPS); + odp.pszTitle = jabberModuleName; + odp.flags=ODPF_BOLDGROUPS; + odp.pfnDlgProc = TlenPopupsDlgProc; + odp.nIDBottomSimpleControl = 0; + CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp); + } + +*/ + return 0; +} + + +static int getOptions(HWND hTreeControl, HTREEITEM hItem, int flags) { + TVITEM tvi = {0}; + tvi.mask = TVIF_HANDLE | TVIF_STATE | TVIF_PARAM; + tvi.stateMask = TVIS_STATEIMAGEMASK; + tvi.hItem = hItem; + TreeView_GetItem(hTreeControl, &tvi); + if ((tvi.state>>12) == 2) { + flags |= tvi.lParam; + } else { + flags &= ~tvi.lParam; + } + tvi.hItem = TreeView_GetChild(hTreeControl, hItem); + if (tvi.hItem != NULL) { + flags = getOptions(hTreeControl, tvi.hItem, flags); + } + tvi.hItem=TreeView_GetNextSibling(hTreeControl, hItem); + if (tvi.hItem != NULL) { + flags = getOptions(hTreeControl, tvi.hItem, flags); + } + return flags; + +} + +static int getExpandFlags(HWND hTreeControl) { + TVITEM tvi = {0}; + int flags =0, mask = 1; + tvi.mask = TVIF_HANDLE | TVIF_STATE; + tvi.stateMask = TVIS_EXPANDED; + tvi.hItem = TreeView_GetRoot(hTreeControl); + while (tvi.hItem != NULL) { + TreeView_GetItem(hTreeControl, &tvi); + if (tvi.state & TVIS_EXPANDED) { + flags |= mask; + } + mask <<= 1; + tvi.hItem=TreeView_GetNextSibling(hTreeControl, tvi.hItem); + } + return flags; +} + + +static int addOption(HWND hTreeControl, HTREEITEM hParent, const char *text, int flag) { + TVINSERTSTRUCT tvis; + tvis.hInsertAfter = TVI_LAST; + tvis.hParent = hParent; + tvis.item.mask = TVIF_TEXT | TVIF_STATE | TVIF_PARAM; + char* textA = Translate(text); + LPTSTR textT = Utils::mucc_mir_a2t(textA); + tvis.item.pszText = textT; + tvis.item.lParam = flag; + tvis.item.stateMask = TVIS_STATEIMAGEMASK; + tvis.item.state = Options::getChatWindowOptions() & flag ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1); + TreeView_InsertItem(hTreeControl, &tvis); + Utils::mucc_mir_free(textT); + return (Options::getChatWindowOptions() & flag) != 0; + +} + +static INT_PTR CALLBACK MUCCOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + int i; + char *pszText; + switch (msg) { + case WM_INITDIALOG: + { + TVINSERTSTRUCT tvis; + TVITEM tvi; + HWND hTreeControl; + HTREEITEM hItem; + int bCheckParent, expandFlags; + + TranslateDialogDefault(hwndDlg); + Options::loadSettings(); + for (i=0;igetColor()); + SendDlgItemMessage(hwndDlg, IDC_COLORBKG, CPM_SETCOLOUR, 0, Options::getLogBgColor()); + SendDlgItemMessage(hwndDlg, IDC_COLORLIST, CPM_SETCOLOUR, 0, Options::getListBgColor()); + SendDlgItemMessage(hwndDlg, IDC_COLORINPUT, CPM_SETCOLOUR, 0, Options::getInputBgColor()); + SendDlgItemMessage(hwndDlg, IDC_LOGLIMITSPIN, UDM_SETRANGE, 0, MAKELONG(1000,20)); + SendDlgItemMessage(hwndDlg, IDC_LOGLIMITSPIN, UDM_SETPOS, 0, MAKELONG(Options::getLogLimit(), 0)); + + SetWindowLong(GetDlgItem(hwndDlg,IDC_TREELIST),GWL_STYLE,GetWindowLong(GetDlgItem(hwndDlg,IDC_TREELIST),GWL_STYLE)|TVS_NOHSCROLL|TVS_CHECKBOXES); + + + hTreeControl = GetDlgItem(hwndDlg, IDC_TREELIST); + expandFlags = Options::getExpandFlags(); + tvis.hInsertAfter = TVI_LAST; + tvis.item.mask = TVIF_TEXT | TVIF_PARAM; + tvis.hParent = NULL; + tvis.item.lParam = 0; + + tvi.mask = TVIF_HANDLE | TVIF_STATE; + tvi.stateMask = TVIS_STATEIMAGEMASK; + + tvis.item.pszText = TranslateT("Default Log Appearence"); + hItem = TreeView_InsertItem(hTreeControl, &tvis); + bCheckParent = 1; + bCheckParent &= addOption(hTreeControl, hItem, "Show nicknames", ChatWindow::FLAG_SHOW_NICKNAMES); + bCheckParent &= addOption(hTreeControl, hItem, "Show message on a new line", ChatWindow::FLAG_MSGINNEWLINE); + tvi.state = (bCheckParent ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1)); + tvi.hItem = hItem; + TreeView_SetItem(hTreeControl, &tvi); + if (expandFlags & 1) { + TreeView_Expand(hTreeControl, hItem, TVE_EXPAND); + } + + tvis.item.pszText = TranslateT("Default Timestamp Settings"); + hItem = TreeView_InsertItem(hTreeControl, &tvis); + bCheckParent = 1; + bCheckParent &= addOption(hTreeControl, hItem, "Show date", ChatWindow::FLAG_SHOW_DATE); + bCheckParent &= addOption(hTreeControl, hItem, "Show timestamp", ChatWindow::FLAG_SHOW_TIMESTAMP); + bCheckParent &= addOption(hTreeControl, hItem, "Show seconds", ChatWindow::FLAG_SHOW_SECONDS); + bCheckParent &= addOption(hTreeControl, hItem, "Use long date format", ChatWindow::FLAG_LONG_DATE); + tvi.state = (bCheckParent ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1)); + tvi.hItem = hItem; + TreeView_SetItem(hTreeControl, &tvi); + if (expandFlags & 2) { + TreeView_Expand(hTreeControl, hItem, TVE_EXPAND); + } + + tvis.item.pszText = TranslateT("Default Text Formatting Filter"); + hItem = TreeView_InsertItem(hTreeControl, &tvis); + bCheckParent = 1; + bCheckParent &= addOption(hTreeControl, hItem, "Font name", ChatWindow::FLAG_FORMAT_FONT); + bCheckParent &= addOption(hTreeControl, hItem, "Font size", ChatWindow::FLAG_FORMAT_SIZE); + bCheckParent &= addOption(hTreeControl, hItem, "Font style", ChatWindow::FLAG_FORMAT_STYLE); + bCheckParent &= addOption(hTreeControl, hItem, "Font color", ChatWindow::FLAG_FORMAT_COLOR); + tvi.state = (bCheckParent ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1)); + tvi.hItem = hItem; + TreeView_SetItem(hTreeControl, &tvi); + if (expandFlags & 4) { + TreeView_Expand(hTreeControl, hItem, TVE_EXPAND); + } + + tvis.item.pszText = TranslateT("Default Event Filter"); + hItem = TreeView_InsertItem(hTreeControl, &tvis); + bCheckParent = 1; + bCheckParent &= addOption(hTreeControl, hItem, "Messages", ChatWindow::FLAG_LOG_MESSAGES); + bCheckParent &= addOption(hTreeControl, hItem, "User has joined", ChatWindow::FLAG_LOG_JOINED); + bCheckParent &= addOption(hTreeControl, hItem, "User has left", ChatWindow::FLAG_LOG_LEFT); + bCheckParent &= addOption(hTreeControl, hItem, "Topic changes", ChatWindow::FLAG_LOG_TOPIC); + tvi.state = (bCheckParent ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1)); + tvi.hItem = hItem; + TreeView_SetItem(hTreeControl, &tvi); + if (expandFlags & 8) { + TreeView_Expand(hTreeControl, hItem, TVE_EXPAND); + } + + tvis.item.pszText = TranslateT("Default Window Flashing"); + hItem = TreeView_InsertItem(hTreeControl, &tvis); + bCheckParent = 1; + bCheckParent &= addOption(hTreeControl, hItem, "Messages", ChatWindow::FLAG_FLASH_MESSAGES); + bCheckParent &= addOption(hTreeControl, hItem, "User has joined", ChatWindow::FLAG_FLASH_JOINED); + bCheckParent &= addOption(hTreeControl, hItem, "User has left", ChatWindow::FLAG_FLASH_LEFT); + bCheckParent &= addOption(hTreeControl, hItem, "Topic changes", ChatWindow::FLAG_FLASH_TOPIC); + tvi.state = (bCheckParent ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1)); + tvi.hItem = hItem; + TreeView_SetItem(hTreeControl, &tvi); + if (expandFlags & 16) { + TreeView_Expand(hTreeControl, hItem, TVE_EXPAND); + } + + CheckDlgButton(hwndDlg, IDC_SENDONENTER, Options::getChatWindowOptions() & ChatWindow::FLAG_OPT_SENDONENTER); + CheckDlgButton(hwndDlg, IDC_ENABLEIEVIEW, Options::getChatWindowOptions() & ChatWindow::FLAG_OPT_ENABLEIEVIEW); + if (!ServiceExists(MS_IEVIEW_WINDOW)) { + EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLEIEVIEW), FALSE); + } + CheckDlgButton(hwndDlg, IDC_USETABS, Options::getChatContainerOptions() & ChatContainer::FLAG_USE_TABS); + + } + case WM_MEASUREITEM: + if (wParam == IDC_FONTLIST) { + MEASUREITEMSTRUCT *lpMis = (MEASUREITEMSTRUCT *) lParam; + HFONT hFont, hoFont; + HDC hDC; + SIZE fontSize; + int iItem = lpMis->itemData - 1; + Font *font = Options::getFontSettings(iItem); + if (font != NULL) { + + LPTSTR lps1 = Utils::mucc_mir_a2t(font->getFace()); + hFont = CreateFont(font->getSize(), 0, 0, 0, + font->getStyle() & Font::BOLD ? FW_BOLD : FW_NORMAL, + font->getStyle() & Font::ITALIC ? 1 : 0, 0, 0, + font->getCharSet(), + OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, lps1); + Utils::mucc_mir_free(lps1); + + hDC = GetDC(GetDlgItem(hwndDlg, lpMis->CtlID)); + hoFont = (HFONT) SelectObject(hDC, hFont); + pszText = Translate(Options::getFontSettings(iItem)->getName()); + LPTSTR pszTextT1 = Utils::mucc_mir_a2t(pszText); + GetTextExtentPoint32(hDC, pszTextT1, lstrlen(pszTextT1), &fontSize); + Utils::mucc_mir_free(pszTextT1); + SelectObject(hDC, hoFont); + ReleaseDC(GetDlgItem(hwndDlg, lpMis->CtlID), hDC); + DeleteObject(hFont); + lpMis->itemWidth = fontSize.cx; + lpMis->itemHeight = fontSize.cy; + return TRUE; + } + break; + } + case WM_DRAWITEM: + if (wParam == IDC_FONTLIST) { + DRAWITEMSTRUCT *lpDis = (DRAWITEMSTRUCT *) lParam; + HFONT hFont; + HBRUSH hBrush; + int iItem = lpDis->itemData - 1; + Font *font = Options::getFontSettings(iItem); + if (font != NULL) { + COLORREF color = (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLORBKG, CPM_GETCOLOUR, 0, 0); + if (iItem == Options::FONT_USERLIST || iItem == Options::FONT_USERLISTGROUP) { + color = (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLORLIST, CPM_GETCOLOUR, 0, 0); + } else if (iItem == Options::FONT_TYPING) { + color = (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLORINPUT, CPM_GETCOLOUR, 0, 0); + } + hBrush = CreateSolidBrush(color); + + LPTSTR lps2 = Utils::mucc_mir_a2t(font->getFace()); + hFont = CreateFont(font->getSize(), 0, 0, 0, + font->getStyle() & Font::BOLD ? FW_BOLD : FW_NORMAL, + font->getStyle() & Font::ITALIC ? 1 : 0, + font->getStyle() & Font::UNDERLINE ? 1 : 0, 0, + font->getCharSet(), + OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, + lps2); + Utils::mucc_mir_free(lps2); + + hFont = (HFONT) SelectObject(lpDis->hDC, hFont); + SetBkMode(lpDis->hDC, TRANSPARENT); + FillRect(lpDis->hDC, &lpDis->rcItem, hBrush); + if (lpDis->itemState & ODS_SELECTED) { + FrameRect(lpDis->hDC, &lpDis->rcItem, GetSysColorBrush(COLOR_HIGHLIGHT)); + } + SetTextColor(lpDis->hDC, font->getColor()); + pszText = Translate(font->getName()); + LPTSTR pszTextT2 = Utils::mucc_mir_a2t(pszText); + TextOut(lpDis->hDC, lpDis->rcItem.left, lpDis->rcItem.top, pszTextT2, lstrlen(pszTextT2)); + Utils::mucc_mir_free(pszTextT2); + hFont = (HFONT) SelectObject(lpDis->hDC, hFont); + DeleteObject(hBrush); + DeleteObject(hFont); + } + return TRUE; + } + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_COLORTXT: + { + int totalCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETCOUNT, 0, 0); + int *selItems= new int[totalCount]; + int selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, totalCount, (LPARAM) selItems); + COLORREF color = (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_GETCOLOUR, 0, 0); + for (int i=0; isetColor(color); + } + } + delete selItems; + InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, FALSE); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + break; + case IDC_LOGLIMIT: + if (HIWORD(wParam) == EN_CHANGE && (HWND)lParam==GetFocus()) { + i = GetDlgItemInt(hwndDlg, IDC_LOGLIMIT, NULL, FALSE); + // if (i>1000) { + // i = 1000; + // SetDlgItemInt(hwndDlg, IDC_LOGLIMIT, i, FALSE); + // } + if (i!=Options::getLogLimit()) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + break; + case IDC_COLORBKG: + case IDC_COLORLIST: + case IDC_COLORINPUT: + InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, FALSE); + case IDC_SENDONENTER: + case IDC_USETABS: + case IDC_ENABLEIEVIEW: + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_FONTLIST: + if (HIWORD(wParam) == LBN_SELCHANGE) { + if (SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELCOUNT, 0, 0) > 1) { + SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETCOLOUR, 0, GetSysColor(COLOR_3DFACE)); + SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_WINDOWTEXT)); + } + else { + int iItem = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, + SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETCURSEL, 0, 0), 0) - 1; + Font *font = Options::getFontSettings(iItem); + if (font != NULL) { + SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETCOLOUR, 0, font->getColor()); + SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETDEFAULTCOLOUR, 0, font->getColor()); + } + } + } + if (HIWORD(wParam) != LBN_DBLCLK) { + return TRUE; + } + case IDC_CHOOSEFONT: + { + CHOOSEFONT cf; + LOGFONT lf; + int iItem = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETCURSEL, 0, 0), 0) - 1; + ZeroMemory(&cf, sizeof(cf)); + ZeroMemory(&lf, sizeof(lf)); + Font *font = Options::getFontSettings(iItem); + if (font != NULL) { + lf.lfHeight = font->getSize(); + lf.lfWeight = font->getStyle() & Font::BOLD ? FW_BOLD : FW_NORMAL; + lf.lfItalic = font->getStyle() & Font::ITALIC ? 1 : 0; + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfOutPrecision = OUT_DEFAULT_PRECIS; + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf.lfQuality = DEFAULT_QUALITY; + lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; + LPTSTR lps3 = Utils::mucc_mir_a2t(font->getFace()); + lstrcpy(lf.lfFaceName, lps3); + Utils::mucc_mir_free(lps3); + cf.lStructSize = sizeof(cf); + cf.hwndOwner = hwndDlg; + cf.lpLogFont = &lf; + cf.Flags = CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS; + if (ChooseFont(&cf)) { + int totalCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETCOUNT, 0, 0); + int *selItems= new int[totalCount]; + int selCount = SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_GETSELITEMS, totalCount, (LPARAM) selItems); + for (int i=0; isetStyle((lf.lfWeight >= FW_BOLD ? Font::BOLD : 0) | (lf.lfItalic ? Font::ITALIC : 0)); + font2->setCharSet(lf.lfCharSet); + font2->setSize(lf.lfHeight); + char* lps4 = Utils::mucc_mir_t2a(lf.lfFaceName); + font2->setFace(lps4); + Utils::mucc_mir_free(lps4); + MEASUREITEMSTRUCT mis; + ZeroMemory(&mis, sizeof(mis)); + mis.CtlID = IDC_FONTLIST; + mis.itemData = iItem + 1; + SendMessage(hwndDlg, WM_MEASUREITEM, (WPARAM)IDC_FONTLIST, (LPARAM) & mis); + SendDlgItemMessage(hwndDlg, IDC_FONTLIST, LB_SETITEMHEIGHT, selItems[i], mis.itemHeight); + } + } + delete selItems; + InvalidateRect(GetDlgItem(hwndDlg, IDC_FONTLIST), NULL, TRUE); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + } + return TRUE; + } + break; + } + break; + case WM_DESTROY: + Options::setExpandFlags(getExpandFlags(GetDlgItem(hwndDlg, IDC_TREELIST))); + break; + case WM_NOTIFY: + { + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: + COLORREF color; + color = (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLORLIST, CPM_GETCOLOUR, 0, 0); + Options::setListBgColor(color); + color = (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLORINPUT, CPM_GETCOLOUR, 0, 0); + Options::setInputBgColor(color); + color = (COLORREF) SendDlgItemMessage(hwndDlg, IDC_COLORBKG, CPM_GETCOLOUR, 0, 0); + Options::setLogBgColor(color); + Options::setLogLimit(SendDlgItemMessage(hwndDlg, IDC_LOGLIMITSPIN, UDM_GETPOS, 0, 0)); + Options::setChatWindowOptions(getOptions(GetDlgItem(hwndDlg, IDC_TREELIST), TreeView_GetRoot(GetDlgItem(hwndDlg, IDC_TREELIST)), 0)); + Options::setChatWindowOptions(Options::getChatWindowOptions() | (IsDlgButtonChecked(hwndDlg, IDC_SENDONENTER) ? ChatWindow::FLAG_OPT_SENDONENTER : 0)); + Options::setChatWindowOptions(Options::getChatWindowOptions() | (IsDlgButtonChecked(hwndDlg, IDC_ENABLEIEVIEW) ? ChatWindow::FLAG_OPT_ENABLEIEVIEW : 0)); + Options::setChatContainerOptions(IsDlgButtonChecked(hwndDlg, IDC_USETABS) ? ChatContainer::FLAG_USE_TABS : 0); + Options::saveSettings(); + ChatWindow::refreshSettings(1); + break; + case NM_CLICK: + /* Handle checking/unchecking options here - update children and parent appropriately */ + if(((LPNMHDR)lParam)->idFrom == IDC_TREELIST) { + TVHITTESTINFO hti; + hti.pt.x = (short)LOWORD(GetMessagePos()); + hti.pt.y = (short)HIWORD(GetMessagePos()); + ScreenToClient(((LPNMHDR)lParam)->hwndFrom, &hti.pt); + if(TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom, &hti)) { + if(hti.flags&TVHT_ONITEMSTATEICON) { + TVITEM tvi = {0}; + tvi.mask = TVIF_HANDLE | TVIF_STATE; + tvi.stateMask = TVIS_STATEIMAGEMASK; + tvi.hItem = hti.hItem; + TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &tvi); + tvi.state ^= INDEXTOSTATEIMAGEMASK(3); + tvi.hItem = TreeView_GetChild(((LPNMHDR)lParam)->hwndFrom, hti.hItem); + if (tvi.hItem!=NULL) { + while(tvi.hItem != NULL) { + TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom, &tvi); + tvi.hItem=TreeView_GetNextSibling(((LPNMHDR)lParam)->hwndFrom, tvi.hItem); + } + } else { + HTREEITEM hParent = TreeView_GetParent(((LPNMHDR)lParam)->hwndFrom, hti.hItem); + if (hParent != NULL) { + if ((tvi.state>>12) == 2) { + tvi.hItem = TreeView_GetNextSibling(((LPNMHDR)lParam)->hwndFrom, hti.hItem); + while(tvi.hItem != NULL) { + TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &tvi); + if ((tvi.state>>12) != 2) { + break; + } + tvi.hItem = TreeView_GetNextSibling(((LPNMHDR)lParam)->hwndFrom, tvi.hItem); + } + if ((tvi.state>>12) == 2) { + tvi.hItem = TreeView_GetPrevSibling(((LPNMHDR)lParam)->hwndFrom, hti.hItem); + while(tvi.hItem != NULL) { + TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &tvi); + if ((tvi.state>>12) != 2) { + break; + } + tvi.hItem = TreeView_GetPrevSibling(((LPNMHDR)lParam)->hwndFrom, tvi.hItem); + } + } + } + tvi.hItem = hParent; + TreeView_SetItem(((LPNMHDR)lParam)->hwndFrom, &tvi); + } + } + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + } + break; + } + } + break; + } + return FALSE; +} + +/* +#define POPUP_DEFAULT_COLORBKG 0xDCBDA5 +#define POPUP_DEFAULT_COLORTXT 0x000000 +static void MailPopupPreview(DWORD colorBack, DWORD colorText, char *title, char *emailInfo, int delay) +{ + POPUPDATAEX ppd; + char * lpzContactName; + char * lpzText; + + lpzContactName = title; + lpzText = emailInfo; + ZeroMemory(&ppd, sizeof(ppd)); + ppd.lchContact = NULL; + ppd.lchIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_MAIL)); + lstrcpy(ppd.lpzContactName, lpzContactName); + lstrcpy(ppd.lpzText, lpzText); + ppd.colorBack = colorBack; + ppd.colorText = colorText; + ppd.PluginWindowProc = NULL; + ppd.PluginData=NULL; + if ( ServiceExists( MS_POPUP_ADDPOPUPEX )) { + ppd.iSeconds = delay; + CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0); + + } + else if ( ServiceExists( MS_POPUP_ADDPOPUP )) { + CallService(MS_POPUP_ADDPOPUP, (WPARAM)&ppd, 0); + } +} +*/ +//static INT_PTR CALLBACK MUCCPopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +//{ + /* + switch (msg) { + case WM_INITDIALOG: + { + BYTE delayMode; + CheckDlgButton(hwndDlg, IDC_ENABLEPOPUP, DBGetContactSettingByte(NULL, jabberProtoName, "MailPopupEnabled", TRUE)); + SendDlgItemMessage(hwndDlg, IDC_COLORBKG, CPM_SETCOLOUR, 0, DBGetContactSettingDword(NULL, jabberProtoName, "MailPopupBack", POPUP_DEFAULT_COLORBKG)); + SendDlgItemMessage(hwndDlg, IDC_COLORTXT, CPM_SETCOLOUR, 0, DBGetContactSettingDword(NULL, jabberProtoName, "MailPopupText", POPUP_DEFAULT_COLORTXT)); + SetDlgItemInt(hwndDlg, IDC_DELAY, DBGetContactSettingDword(NULL, jabberProtoName, "MailPopupDelay", 4), FALSE); + delayMode = DBGetContactSettingByte(NULL, jabberProtoName, "MailPopupDelayMode", 0); + if (delayMode==1) { + CheckDlgButton(hwndDlg, IDC_DELAY_CUSTOM, TRUE); + } else if (delayMode==2) { + CheckDlgButton(hwndDlg, IDC_DELAY_PERMANENT, TRUE); + } else { + CheckDlgButton(hwndDlg, IDC_DELAY_POPUP, TRUE); + } + return TRUE; + } + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_COLORTXT: + case IDC_COLORBKG: + case IDC_ENABLEPOPUP: + case IDC_DELAY: + case IDC_DELAY_POPUP: + case IDC_DELAY_CUSTOM: + case IDC_DELAY_PERMANENT: + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_PREVIEW: + { + int delay; + if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_POPUP)) { + delay=0; + } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) { + delay=-1; + } else { + delay=GetDlgItemInt(hwndDlg, IDC_DELAY, NULL, FALSE); + } + MailPopupPreview((DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0), + (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0), + "New mail", + "From: test@test.test\nSubject: test", + delay); + } + + } + break; + + + case WM_NOTIFY: + switch (((LPNMHDR) lParam)->code) { + case PSN_APPLY: + { + BYTE delayMode; + DBWriteContactSettingByte(NULL, jabberProtoName, "MailPopupEnabled", (BYTE) IsDlgButtonChecked(hwndDlg, IDC_ENABLEPOPUP)); + DBWriteContactSettingDword(NULL, jabberProtoName, "MailPopupBack", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORBKG,CPM_GETCOLOUR,0,0)); + DBWriteContactSettingDword(NULL, jabberProtoName, "MailPopupText", (DWORD) SendDlgItemMessage(hwndDlg,IDC_COLORTXT,CPM_GETCOLOUR,0,0)); + DBWriteContactSettingDword(NULL, jabberProtoName, "MailPopupDelay", (DWORD) GetDlgItemInt(hwndDlg,IDC_DELAY, NULL, FALSE)); + delayMode=0; + if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_CUSTOM)) { + delayMode=1; + } else if (IsDlgButtonChecked(hwndDlg, IDC_DELAY_PERMANENT)) { + delayMode=2; + + } + DBWriteContactSettingByte(NULL, jabberProtoName, "MailPopupDelayMode", delayMode); + return TRUE; + } + } + break; + + }*/ +// return FALSE; +//} + diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/Options.h b/plugins/!NotAdopted/Tlen/tlen_czaty/Options.h new file mode 100644 index 0000000000..90c57099d0 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/Options.h @@ -0,0 +1,75 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#ifndef OPTIONS_INCLUDED +#define OPTIONS_INCLUDED +#include "FontList.h" +#include "mucc.h" + +extern int MUCCOptInit(WPARAM wParam, LPARAM lParam); + +class Options:public FontList { +private: + static COLORREF colorInputBg; + static COLORREF colorLogBg; + static COLORREF colorListBg; + static HBRUSH brushInputBg; + static HBRUSH brushLogBg; + static HBRUSH brushListBg; + static int logLimit; + static int chatContainerOptions; + static int chatWindowOptions; + static COLORREF chatWindowFontColor; + static int chatWindowFont; + static int chatWindowFontSize; + static int chatWindowFontStyle; +public: + static void setListBgColor(COLORREF c); + static void setLogBgColor(COLORREF c); + static void setInputBgColor(COLORREF c); + static COLORREF getListBgColor(); + static COLORREF getLogBgColor(); + static COLORREF getInputBgColor(); + static HBRUSH getListBgBrush(); + static HBRUSH getInputBgBrush(); + static HBRUSH getLogBgBrush(); + static void setLogLimit(int l); + static int getLogLimit(); + static void setChatContainerOptions(int o); + static int getChatContainerOptions(); + static void setChatWindowOptions(int o); + static int getChatWindowOptions(); + static void setChatWindowFontColor(COLORREF o); + static COLORREF getChatWindowFontColor(); + static void setChatWindowFont(int o); + static int getChatWindowFont(); + static void setChatWindowFontSize(int o); + static int getChatWindowFontSize(); + static void setChatWindowFontStyle(int o); + static int getChatWindowFontStyle(); + static void setExpandFlags(int l); + static int getExpandFlags(); + static void init(); + static void loadSettings(); + static void saveSettings(); + +}; + +#endif diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/Utils.cpp b/plugins/!NotAdopted/Tlen/tlen_czaty/Utils.cpp new file mode 100644 index 0000000000..53bddf4488 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/Utils.cpp @@ -0,0 +1,138 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#include "Utils.h" + +struct FORK_ARG { + HANDLE hEvent; + void (__cdecl *threadcode)(void*); + void *arg; +}; + +static void __cdecl forkthread_r(struct FORK_ARG *fa) +{ + void (*callercode)(void*) = fa->threadcode; + void *arg = fa->arg; + CallService(MS_SYSTEM_THREAD_PUSH, 0, 0); + SetEvent(fa->hEvent); + callercode(arg); + CallService(MS_SYSTEM_THREAD_POP, 0, 0); + return; +} + +unsigned long Utils::forkThread(void (__cdecl *threadcode)(void*), unsigned long stacksize, void *arg) { + + unsigned long rc; + struct FORK_ARG fa; + + fa.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + fa.threadcode = threadcode; + fa.arg = arg; + rc = _beginthread((void (__cdecl *)(void*))forkthread_r, stacksize, &fa); + if ((unsigned long) -1L != rc) { + WaitForSingleObject(fa.hEvent, INFINITE); + } + CloseHandle(fa.hEvent); + return rc; +} + +void Utils::copyString(char **a, const char *b) { + char *oldA; + char *newA; + oldA = *a; + if (b!=NULL) { + newA = new char[strlen(b)+1]; + strcpy(newA, b); + } else { + newA = NULL; + } + *a = newA; + if (oldA!=NULL) { + delete oldA; + } + +} + + + +MM_INTERFACE Utils::mmi; + +void Utils::mucc_mir_free(void* ptr) +{ + mir_free(ptr); +} + +char* Utils::mucc_mir_t2a(LPCTSTR src) +{ + return mir_t2a(src); +} + +LPTSTR Utils::mucc_mir_a2t(const char* src) +{ + return mir_a2t(src); +} + + + +void Utils::log(const char *fmt, ...) +{ +#ifdef ENABLE_LOGGING + char *str; + va_list vararg; + int strsize; + char *text; + char *p, *q; + int extra; + + va_start(vararg, fmt); + str = (char *) malloc(strsize=2048); + while (_vsnprintf(str, strsize, fmt, vararg) == -1) + str = (char *) realloc(str, strsize+=2048); + va_end(vararg); + + extra = 0; + for (p=str; *p!='\0'; p++) + if (*p=='\n' || *p=='\r') + extra++; + text = (char *) malloc(strlen(muccModuleName)+2+strlen(str)+2+extra); + wsprintf(text, "[%s]", muccModuleName); + for (p=str,q=text+strlen(text); *p!='\0'; p++,q++) { + if (*p == '\r') { + *q = '\\'; + *(q+1) = 'r'; + q++; + } + else if (*p == '\n') { + *q = '\\'; + *(q+1) = 'n'; + q++; + } + else + *q = *p; + } + *q = '\n'; + *(q+1) = '\0'; +// CallService(MS_NETLIB_LOG, (WPARAM) NULL, (LPARAM) text); + //OutputDebugString(text); + free(text); + free(str); +#endif +} + diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/Utils.h b/plugins/!NotAdopted/Tlen/tlen_czaty/Utils.h new file mode 100644 index 0000000000..6ae4e2a44c --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/Utils.h @@ -0,0 +1,38 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#ifndef UTILS_INCLUDED +#define UTILS_INCLUDED +#include "mucc.h" + +class Utils { +public: + static unsigned long forkThread(void (__cdecl *threadcode)(void*),unsigned long stacksize,void *arg); + static void copyString(char **, const char *b); + static void log(const char *fmt, ...); + + static MM_INTERFACE mmi; + static void mucc_mir_free(void*); + static char* mucc_mir_t2a(LPCTSTR); + static LPTSTR mucc_mir_a2t(const char* ); + +}; + +#endif diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/admin.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/admin.ico new file mode 100644 index 0000000000..9699f55d6f Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/admin.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/administration.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/administration.ico new file mode 100644 index 0000000000..e57884857e Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/administration.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/blank.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/blank.ico new file mode 100644 index 0000000000..7845f62fed Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/blank.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/bold.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/bold.ico new file mode 100644 index 0000000000..01d5adda1d Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/bold.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/chat.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/chat.ico new file mode 100644 index 0000000000..0b388d8f9d Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/chat.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/delete.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/delete.ico new file mode 100644 index 0000000000..59408c5337 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/delete.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/glowner.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/glowner.ico new file mode 100644 index 0000000000..86fdf534e9 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/glowner.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/invite.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/invite.ico new file mode 100644 index 0000000000..bf7dbc4d7a Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/invite.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/italic.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/italic.ico new file mode 100644 index 0000000000..d34418be24 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/italic.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/message.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/message.ico new file mode 100644 index 0000000000..40d183b7b3 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/message.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/next.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/next.ico new file mode 100644 index 0000000000..d817b06cc6 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/next.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/options.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/options.ico new file mode 100644 index 0000000000..2fd2d902d9 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/options.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/owner.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/owner.ico new file mode 100644 index 0000000000..27bea391f0 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/owner.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/prev.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/prev.ico new file mode 100644 index 0000000000..2f171e5783 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/prev.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/r_anon.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/r_anon.ico new file mode 100644 index 0000000000..b5ebd0289e Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/r_anon.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/r_memb.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/r_memb.ico new file mode 100644 index 0000000000..418fd9abf5 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/r_memb.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/r_mod.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/r_mod.ico new file mode 100644 index 0000000000..3b9fa47f60 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/r_mod.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/registered.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/registered.ico new file mode 100644 index 0000000000..3a5182b5d6 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/registered.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/save.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/save.ico new file mode 100644 index 0000000000..48b0581fd5 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/save.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/search.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/search.ico new file mode 100644 index 0000000000..065468e272 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/search.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/sendmail.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/sendmail.ico new file mode 100644 index 0000000000..0b60bf950e Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/sendmail.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/smile.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/smile.ico new file mode 100644 index 0000000000..d4aea87249 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/smile.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/tlenbig.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/tlenbig.ico new file mode 100644 index 0000000000..4d09293560 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/tlenbig.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/tlensmall.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/tlensmall.ico new file mode 100644 index 0000000000..5204d39d21 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/tlensmall.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/icos/underline.ico b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/underline.ico new file mode 100644 index 0000000000..7709f5f7f4 Binary files /dev/null and b/plugins/!NotAdopted/Tlen/tlen_czaty/icos/underline.ico differ diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/mucc.cpp b/plugins/!NotAdopted/Tlen/tlen_czaty/mucc.cpp new file mode 100644 index 0000000000..e5c35c070a --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/mucc.cpp @@ -0,0 +1,188 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "../commons.h" +#include "mucc.h" +#include "mucc_services.h" +#include "HelperDialog.h" +#include "Options.h" +#include "Utils.h" + +char *muccModuleName; +HINSTANCE hInst; +PLUGINLINK *pluginLink; +HANDLE hHookEvent = NULL; +HIMAGELIST hImageList = NULL; +HICON muccIcon[MUCC_ICON_TOTAL]; +static int ModulesLoaded(WPARAM wParam, LPARAM lParam); +static int PreShutdown(WPARAM wParam, LPARAM lParam); + +PLUGININFOEX pluginInfoEx = { + sizeof(PLUGININFOEX), +#ifdef _UNICODE +#ifdef _X64 + "Tlen Czaty (x64, Unicode)", +#else + "Tlen Czaty (Unicode)", +#endif +#else + "Tlen Czaty", +#endif + PLUGIN_MAKE_VERSION(MUCC_MAJOR_VERSION,MUCC_MINOR_VERSION,MUCC_RELEASE_NUM,MUCC_BUILD_NUM), + "Group chats GUI plugin for Miranda IM (formerly known as mucc.dll) (version: "MUCC_VERSION_STRING" ; compiled: "__DATE__" "__TIME__")", + "Piotr Piastucki", + "the_leech@users.berlios.de", + "(c) 2004-2012 Piotr Piastucki", + "http://mtlen.berlios.de", + 0, + 0, +#if defined( _UNICODE ) +#ifdef _X64 + {0x9061ae31, 0x3d33, 0x49ce, { 0xaf, 0x00, 0x78, 0x9c, 0xbc, 0x25, 0xd9, 0xba }} +#else + {0xadd9390c, 0x1dd4, 0x4c0d, { 0x9b, 0xa9, 0xcc, 0x76, 0x5d, 0x3d, 0xe5, 0x97 }} +#endif +#else + {0x5cf4792c, 0xa050, 0x46b6, { 0xaf, 0xd0, 0x03, 0x2d, 0x6e, 0xfc, 0xd3, 0x9c }} +#endif +}; + +extern "C" BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpvReserved) +{ + hInst = hModule; + return TRUE; +} + +extern "C" __declspec(dllexport) PLUGININFOEX *MirandaPluginInfoEx(DWORD mirandaVersion) +{ + if (mirandaVersion < PLUGIN_MAKE_VERSION(0,8,0,15)) { + MessageBox(NULL, _TEXT("The Tlen Czaty plugin cannot be loaded. It requires Miranda IM 0.8.15 or later."), _TEXT("Tlen Czaty plugin (MUCC)"), MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_TOPMOST); + return NULL; + } + return &pluginInfoEx; +} + +#ifndef MIID_TLEN_MUCC +#define MIID_TLEN_MUCC { 0xba658997, 0x0bce, 0x4f96, { 0xba, 0x48, 0x54, 0x55, 0x34, 0x16, 0x73, 0xea } } +#endif + +extern "C" __declspec(dllexport) const MUUID interfaces[] = { + MIID_TLEN_MUCC, + MIID_LAST + }; + +extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + + +static void LoadIcons() { + int i; + static int iconList[] = { + IDI_CHAT, + IDI_GLOBALOWNER, + IDI_OWNER, + IDI_ADMIN, + IDI_REGISTERED, + IDI_R_MODERATED, + IDI_R_MEMBERS, + IDI_R_ANONYMOUS, + IDI_PREV, + IDI_NEXT, + IDI_SEARCH, + IDI_BOLD, + IDI_ITALIC, + IDI_UNDERLINE, + IDI_OPTIONS, + IDI_INVITE, + IDI_ADMINISTRATION, + IDI_SMILEY, + IDI_MESSAGE + + }; + for (i=0; i +#include +#include +#include +#include +#include +#include +#include + +#ifdef __MINGW32__ +#define EM_SETTEXTEX (WM_USER + 97) +#define ST_DEFAULT 0 +#define ST_KEEPUNDO 1 +#define ST_SELECTION 2 +#define ST_NEWCHARS 4 +#else +#include +#endif + +#define MIRANDA_VER 0x0700 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "resource.h" + +enum { + MUCC_IDI_CHAT = 0, + MUCC_IDI_U_GLOBALOWNER, + MUCC_IDI_U_OWNER, + MUCC_IDI_U_ADMIN, + MUCC_IDI_U_REGISTERED, + MUCC_IDI_R_MODERATED, + MUCC_IDI_R_MEMBERS, + MUCC_IDI_R_ANONYMOUS, + MUCC_IDI_PREV, + MUCC_IDI_NEXT, + MUCC_IDI_SEARCH, + MUCC_IDI_BOLD, + MUCC_IDI_ITALIC, + MUCC_IDI_UNDERLINE, + MUCC_IDI_OPTIONS, + MUCC_IDI_INVITE, + MUCC_IDI_ADMINISTRATION, + MUCC_IDI_SMILEY, + MUCC_IDI_MESSAGE, + MUCC_ICON_TOTAL + +}; + +extern PLUGINLINK * pluginLink; +extern char *muccModuleName; +extern HINSTANCE hInst; +extern HANDLE hHookEvent; +extern HIMAGELIST hImageList; +extern HICON muccIcon[MUCC_ICON_TOTAL]; + +#include "m_mucc.h" + +#define WM_MUCC_REFRESH_ROOMS (WM_USER+101) +#define WM_MUCC_REFRESH_USER_ROOMS (WM_USER+102) +#define WM_MUCC_REFRESH_USER_NICKS (WM_USER+103) + +#endif + diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/mucc.rc b/plugins/!NotAdopted/Tlen/tlen_czaty/mucc.rc new file mode 100644 index 0000000000..d50a834649 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/mucc.rc @@ -0,0 +1,579 @@ +#include "resource.h" +#include "../commons.h" +#ifdef __MINGW32__ + #define WINVER 0x500 + #define _WIN32_IE 0x500 + #include + #ifndef IDC_STATIC + #define IDC_STATIC (-1) +#endif +#else +// #define APSTUDIO_READONLY_SYMBOLS +// #include "winres.h" +// #undef APSTUDIO_READONLY_SYMBOLS + #include + #ifndef IDC_STATIC + #define IDC_STATIC (-1) + #endif +#endif +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif +#ifdef APSTUDIO_INVOKED + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +IDR_CHATOPTIONS MENU DISCARDABLE +BEGIN + POPUP "", MENUBREAK + BEGIN + POPUP "Log Appearance" + BEGIN + MENUITEM "Show Nicknames", ID_OPTIONMENU_SHOWNICKNAMES + MENUITEM "Show Message On A New Line", ID_OPTIONMENU_MSGINNEWLINE + END + POPUP "Timestamp Settings" + BEGIN + MENUITEM "Show Date", ID_OPTIONMENU_SHOWDATE + MENUITEM "Show Timestamp", ID_OPTIONMENU_SHOWTIMESTAMP + MENUITEM "Show Seconds", ID_OPTIONMENU_SHOWSECONDS + MENUITEM "Use Long Date Format", ID_OPTIONMENU_USELONGDATE + + END + POPUP "Text Formatting Filter" + BEGIN + MENUITEM "Font Name", ID_OPTIONMENU_FORMATFONT + MENUITEM "Font Size", ID_OPTIONMENU_FORMATSIZE + MENUITEM "Font Style", ID_OPTIONMENU_FORMATSTYLE + MENUITEM "Font Color", ID_OPTIONMENU_FORMATCOLOR + END + POPUP "Event Filter" + BEGIN + MENUITEM "Messages", ID_OPTIONMENU_LOGMESSAGES + MENUITEM "User Has Joined", ID_OPTIONMENU_LOGJOINED + MENUITEM "User Has Left", ID_OPTIONMENU_LOGLEFT + MENUITEM "Topic Changes", ID_OPTIONMENU_LOGTOPIC + END + POPUP "Window Flashing" + BEGIN + MENUITEM "Messages", ID_OPTIONMENU_FLASHMESSAGES + MENUITEM "User Has Joined", ID_OPTIONMENU_FLASHJOINED + MENUITEM "User Has Left", ID_OPTIONMENU_FLASHLEFT + MENUITEM "Topic Changes", ID_OPTIONMENU_FLASHTOPIC + END + MENUITEM SEPARATOR + MENUITEM "Save Settings As Default", ID_OPTIONMENU_SAVEDEFAULT + MENUITEM SEPARATOR + MENUITEM "User Administration", ID_ADMINMENU_ADMIN, GRAYED + MENUITEM "Destroy Chat Room", ID_ADMINMENU_DESTROY, GRAYED + MENUITEM SEPARATOR + MENUITEM "Save Log", ID_ADMINMENU_SAVELOG + END + POPUP "", MENUBREAK + BEGIN + MENUITEM "Message", ID_USERMENU_MESSAGE + MENUITEM SEPARATOR + POPUP "Kick && Ban", GRAYED + BEGIN + MENUITEM "No Ban", ID_USERMENU_KICK_NO_BAN + MENUITEM "Ban For 1 Minute", ID_USERMENU_KICK_BAN_1_MIN + MENUITEM "Ban For 5 Minutes", ID_USERMENU_KICK_BAN_5_MIN + MENUITEM "Ban For 15 Minutes", ID_USERMENU_KICK_BAN_15_MIN + MENUITEM "Ban For 30 Minutes", ID_USERMENU_KICK_BAN_15_MIN + MENUITEM "Ban For 1 Hour", ID_USERMENU_KICK_BAN_1_H + MENUITEM "Ban For 6 Hours", ID_USERMENU_KICK_BAN_6_H + MENUITEM "Ban For 1 Day", ID_USERMENU_KICK_BAN_1_D + MENUITEM "Ban For 3 Days", ID_USERMENU_KICK_BAN_3_D + MENUITEM "Ban For 1 Week", ID_USERMENU_KICK_BAN_1_W + MENUITEM "Ban For 2 Weeks", ID_USERMENU_KICK_BAN_2_W + MENUITEM "Ban For 4 Weeks", ID_USERMENU_KICK_BAN_4_W + END + POPUP "Change User Role", GRAYED + BEGIN + MENUITEM "No Role", ID_USERMENU_RIGHTS_NO + MENUITEM "Member", ID_USERMENU_RIGHTS_MEMBER + + MENUITEM "Admin", ID_USERMENU_RIGHTS_ADMIN + END + MENUITEM "User Administration", ID_USERMENU_ADMINISTRATION, GRAYED + END + POPUP "", MENUBREAK + BEGIN + MENUITEM "Unban", ID_USERMENU_UNBAN + END +END + +IDR_CONTEXT MENU DISCARDABLE +BEGIN + POPUP "Log" + BEGIN + MENUITEM "&Copy", IDM_COPY + MENUITEM "Co&py All", IDM_COPYALL + MENUITEM SEPARATOR + MENUITEM "Select &All", IDM_SELECTALL + MENUITEM SEPARATOR + MENUITEM "C&lear Log", IDM_CLEAR + END + POPUP "LogLink" + BEGIN + MENUITEM "Open in &new window", IDM_OPENNEW + MENUITEM "&Open in existing window", IDM_OPENEXISTING + MENUITEM "&Copy link", IDM_COPYLINK + END + POPUP "Message" + BEGIN + MENUITEM "Undo", IDM_UNDO + MENUITEM "Redo", IDM_REDO + MENUITEM SEPARATOR + MENUITEM "Cut", IDM_CUT + MENUITEM "Copy", IDM_COPY + MENUITEM "Paste", IDM_PASTE + MENUITEM "Delete", IDM_DELETE + MENUITEM SEPARATOR + MENUITEM "Select &All", IDM_SELECTALL + END +END + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPTIONS DIALOGEX 0, 0, 320, 260 +STYLE DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Fonts",IDC_FONTSGB,169,10,143,182 + LTEXT "Background color",IDC_STATIC,175,23,100,8 + CONTROL "",IDC_COLORBKG,"ColourPicker",WS_TABSTOP,277,21,29,12 + LTEXT "Input area background",IDC_STATIC,175,38,100,8 + CONTROL "",IDC_COLORINPUT,"ColourPicker",WS_TABSTOP,277,36,29,12 + LTEXT "User list background",IDC_STATIC,175,53,100,8 + CONTROL "",IDC_COLORLIST,"ColourPicker",WS_TABSTOP,277,51,29,12 + LISTBOX IDC_FONTLIST,175,69,131,95,LBS_OWNERDRAWVARIABLE | + LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL | + WS_TABSTOP + CONTROL "",IDC_COLORTXT,"ColourPicker",WS_TABSTOP,175,170,55,15 + PUSHBUTTON "Choose font",IDC_CHOOSEFONT,251,170,55,15 + GROUPBOX "Options",IDC_OPTIONSGB,5,10,158,182 + CONTROL "",IDC_TREELIST,"SysTreeView32",TVS_HASBUTTONS | + TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP,11, + 23,146,162,WS_EX_STATICEDGE + GROUPBOX "Other",IDC_SIMPLE,5,193,310,57 + CONTROL "Use tabbed mode",IDC_USETABS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,13,206,140,10 + CONTROL "Enable IEView",IDC_ENABLEIEVIEW,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,13,219,140,10 + CONTROL "Send message on 'Enter'",IDC_SENDONENTER,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,13,232,140,10 + LTEXT "Limit log history to (events):",IDC_STATIC,153,234,110,8 + EDITTEXT IDC_LOGLIMIT,263,232,40,14,ES_RIGHT | ES_NUMBER + CONTROL "",IDC_LOGLIMITSPIN,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | + UDS_NOTHOUSANDS | UDS_HOTTRACK,390,218,11,14 +END + +IDD_CHATMANAGER DIALOGEX 0, 0, 473, 234 +STYLE DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | + WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | + WS_THICKFRAME +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Chats" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "Tab1",IDC_TABS,"SysTabControl32",TCS_BUTTONS | + TCS_FIXEDWIDTH | 0x8,214,7,252,20 + PUSHBUTTON "Close",IDCLOSE,416,215,50,14 + CONTROL "Tree1",IDC_GROUP,"SysTreeView32",TVS_HASBUTTONS | + TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | + TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS,5,20,203,209, + WS_EX_STATICEDGE + LTEXT "Groups",IDC_STATIC,7,9,24,8 +END + +IDD_GROUPCHAT_CONTAINER DIALOGEX 0, 0, 300, 200 +STYLE DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | + WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | + WS_THICKFRAME +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Tlen Group Chat" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "",IDC_TABS,"SysTabControl32", WS_CLIPSIBLINGS | TCS_MULTILINE | TCS_FOCUSNEVER | 0x8,0,0,300,200 +END + +IDD_GROUPCHAT_LOG DIALOGEX 0, 0, 294, 178 +STYLE DS_FIXEDSYS | WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN +/* +STYLE DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | + WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | + WS_THICKFRAME + */ +//EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "",IDC_VSPLIT,"Static",SS_ENHMETAFILE,237,20,3,117 + CONTROL "",IDC_HSPLIT,"Static",SS_ENHMETAFILE,156,285,2,0 + CONTROL "",IDC_LOG,"RichEdit20A",WS_VSCROLL | WS_TABSTOP | WS_CLIPSIBLINGS | 0x844, + 3,21,233,117,WS_EX_STATICEDGE + CONTROL "",IDC_TREELIST,"SysTreeView32",TVS_DISABLEDRAGDROP | + TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS | TVS_NONEVENHEIGHT,5, + 20,203,209,WS_EX_STATICEDGE + EDITTEXT IDC_EDIT,3,158,285,13,ES_MULTILINE | ES_AUTOVSCROLL | + NOT WS_BORDER | WS_VSCROLL | ES_WANTRETURN,WS_EX_STATICEDGE + CONTROL "Topic",IDC_TOPIC_BUTTON,"MButtonClass",WS_DISABLED | + WS_TABSTOP,3,3,34,12,0x18000000L + CONTROL "",IDC_BOLD,"MButtonClass",WS_TABSTOP,3,140,16,16, + 0x18000000L + CONTROL "",IDC_ITALIC,"MButtonClass",WS_TABSTOP,21,140,16,16, + 0x18000000L + CONTROL "",IDC_UNDERLINE,"MButtonClass",WS_TABSTOP,39,140,16,16, + 0x18000000L + CONTROL "",IDC_COLOR,"ColourPicker",WS_TABSTOP,57,140,16,16 + COMBOBOX IDC_FONTSIZE,154,142,27,80,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + CONTROL "",IDC_SMILEYBTN,"MButtonClass", WS_TABSTOP,185,140,16,16, + 0x18000000L + CONTROL "Invite",IDC_INVITE,"MButtonClass",WS_TABSTOP,259,141,16, + 16,0x18000000L + EDITTEXT IDC_TOPIC,70,19,86,12,ES_AUTOHSCROLL | ES_READONLY | NOT + WS_BORDER + CONTROL "",IDC_OPTIONS,"MButtonClass",WS_TABSTOP,208,140,16,16, + 0x18000000L + COMBOBOX IDC_FONT,77,142,74,90,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + PUSHBUTTON "Close",IDCANCEL,0,0,20,20,NOT WS_VISIBLE + //,NOT WS_VISIBLE +END + +IDD_HELPER_JOIN DIALOGEX 0, 0, 186, 79 +STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | + WS_POPUP | WS_VISIBLE | WS_CAPTION +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Join Tlen Multi-User Conference Room" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "Room:",IDC_ROOM_LABEL,10,13,43,8 + EDITTEXT IDC_ROOM,54,12,119,12,ES_AUTOHSCROLL + LTEXT "Nickname:",IDC_NICK_LABEL,10,30,40,8 + EDITTEXT IDC_NICK,54,29,119,12,ES_AUTOHSCROLL + DEFPUSHBUTTON "&Join",IDOK,75,59,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,59,50,14 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,7,50,172,4 +END + +IDD_HELPER_INVITE DIALOG DISCARDABLE 0, 0, 186, 79 +STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Invite a User" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "User:",IDC_STATIC,10,13,43,8 + COMBOBOX IDC_USER,54,10,119,120,CBS_DROPDOWN | CBS_AUTOHSCROLL | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Reason:",IDC_STATIC,10,30,40,8 + EDITTEXT IDC_REASON,54,29,119,12,ES_AUTOHSCROLL + DEFPUSHBUTTON "&Invite",IDC_INVITE,75,59,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,59,50,14 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,7,50,172,4 +END + +IDD_HELPER_INVITE_ACCEPT DIALOG DISCARDABLE 0, 0, 232, 112 +STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Multi-User Conference Invitation" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "&Accept",IDC_ACCEPT,124,93,50,14 + PUSHBUTTON "Cancel",IDCANCEL,178,93,50,14 + LTEXT "From:",IDC_STATIC,33,24,63,8 + LTEXT "Room:",IDC_STATIC,33,38,63,8 + LTEXT "Reason:",IDC_STATIC,33,52,63,8 + LTEXT "Nickname:",IDC_STATIC,33,76,62,8 + LTEXT "The following invitation to join a multi-user conference is received.", + IDC_STATIC,3,4,225,8 + EDITTEXT IDC_FROM,99,22,105,12,ES_AUTOHSCROLL | ES_READONLY + EDITTEXT IDC_ROOM,99,36,105,12,ES_AUTOHSCROLL | ES_READONLY + EDITTEXT IDC_REASON,99,50,105,12,ES_AUTOHSCROLL | ES_READONLY + EDITTEXT IDC_NICK,99,74,105,12,ES_AUTOHSCROLL + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,3,65,225,4 +END + +IDD_HELPER_TOPIC DIALOGEX 0, 0, 223, 44 +STYLE DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_VISIBLE | WS_CAPTION +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Change Chat Room Topic" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "New topic:",IDC_STATIC,10,8,43,8 + EDITTEXT IDC_TOPIC,54,7,160,12,ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDOK,108,26,50,14 + PUSHBUTTON "Cancel",IDCANCEL,164,26,50,14 +END + +IDD_USER_ADMIN DIALOG DISCARDABLE 0, 0, 300, 180 +STYLE DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | + WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Chat Room Administration" +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "Tab1",IDC_TABS,"SysTabControl32",TCS_BUTTONS | + TCS_FIXEDWIDTH | 0x8,0,5,220,20 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,20,300,4 + PUSHBUTTON "Close",IDCANCEL,230,162,60,16 + +END + +IDD_USER_KICK DIALOGEX 0, 30, 300, 130 +STYLE WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "Nickname:",IDC_STATIC,30,6,70,10 + EDITTEXT IDC_NICK,100,6,100,12,ES_AUTOHSCROLL | WS_TABSTOP + LTEXT "Ban for:",IDC_STATIC,30,35,70,10 + COMBOBOX IDC_KICK_OPTIONS,100,35,90,150,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Reason:",IDC_STATIC,30,51,70,10 + EDITTEXT IDC_REASON,100,51,100,12,ES_AUTOHSCROLL | WS_TABSTOP + CONTROL "Kick && Ban",IDOK,"MButtonClass",WS_TABSTOP,210,65,60,16 + + LTEXT "User role:",IDC_STATIC,30,90,70,10 + COMBOBOX IDC_ROLE_OPTIONS,100,90,90,60,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + CONTROL "Set Role",IDC_SET_ROLE,"MButtonClass",WS_TABSTOP,210,104,60,16 + + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,128,300,4 +END + +IDD_USER_ROLE DIALOGEX 0, 30, 300, 130 +STYLE WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "Nickname:",IDC_STATIC,30,25,70,10 + EDITTEXT IDC_NICK,100,25,100,12,ES_AUTOHSCROLL | WS_TABSTOP + LTEXT "User role:",IDC_STATIC,30,41,70,10 + COMBOBOX IDC_OPTIONS,100,41,90,60,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + CONTROL "Set Role",IDOK,"MButtonClass",WS_TABSTOP,120,90,60,16 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,128,300,4 +END + +IDD_USER_BROWSER DIALOGEX 0, 30, 300, 130 +STYLE WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + COMBOBOX IDC_OPTIONS,50,0,90,60,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + CONTROL "Show",IDC_SHOW,"MButtonClass",WS_TABSTOP,160,0,50,14 + CONTROL "List1",IDC_LIST,"SysListView32",LVS_REPORT | + LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_AUTOARRANGE | + LVS_OWNERDRAWFIXED | WS_TABSTOP,0,20,299,110, + WS_EX_CLIENTEDGE +END + +IDD_OPT_POPUPS DIALOG DISCARDABLE 0, 0, 317, 141 +STYLE WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + GROUPBOX "Delay",IDC_STATIC,160,46,137,55 + CONTROL "&From PopUp plugin",IDC_DELAY_POPUP,"Button", + BS_AUTORADIOBUTTON,167,60,125,10 + CONTROL "&Custom",IDC_DELAY_CUSTOM,"Button",BS_AUTORADIOBUTTON, + 167,73,98,10 + CONTROL "P&ermanent",IDC_DELAY_PERMANENT,"Button", + BS_AUTORADIOBUTTON,167,87,123,10 + EDITTEXT IDC_DELAY,270,71,21,14,ES_AUTOHSCROLL | ES_NUMBER + GROUPBOX "Colours",IDC_STATIC,15,46,137,55 + LTEXT "Background",IDC_STATIC,53,63,95,8 + LTEXT "Text",IDC_STATIC,53,82,96,8 + CONTROL "",IDC_COLORBKG,"ColourPicker",WS_TABSTOP,23,61,24,12 + GROUPBOX "General Options",IDC_STATIC,15,15,282,26 + CONTROL "",IDC_COLORTXT,"ColourPicker",WS_TABSTOP,23,79,24,12 + PUSHBUTTON "Preview",IDC_PREVIEW,132,112,50,14 + CONTROL "Enable incoming mail notification",IDC_ENABLEPOPUP, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,26,130,10 +END + +IDD_TAB_CHATROOMS DIALOGEX 216, 28, 247, 180 +STYLE WS_CHILD +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + CONTROL "List1",IDC_ROOM,"SysListView32",LVS_REPORT | + LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_AUTOARRANGE | + LVS_OWNERDRAWFIXED | WS_TABSTOP,0,26,247,154, + WS_EX_CLIENTEDGE + CONTROL "prev",IDC_PREV,"MButtonClass",WS_TABSTOP,5,6,20,16 + CONTROL "next",IDC_NEXT,"MButtonClass",WS_TABSTOP,35,6,20,16 + CONTROL "find",IDC_SEARCH,"MButtonClass",WS_TABSTOP,65,6,20,16 +END + +IDD_TAB_MYROOMS DIALOGEX 216, 28, 244, 180 +STYLE WS_CHILD +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + CONTROL "Create",IDC_REGISTER,"MButtonClass",WS_TABSTOP,186,62, + 50,14,0x18000000L + EDITTEXT IDC_NAME,84,20,149,14,ES_AUTOHSCROLL + LTEXT "Room name:",IDC_STATIC,14,23,60,8 + CONTROL "Permanent",IDC_CHECK_PERMANENT,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,111,40,89,10 + CONTROL "Nicknames",IDC_CHECK_NICKNAMES,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,13,52,89,10 + CONTROL "Public",IDC_CHECK_PUBLIC,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,13,40,89,10 + CONTROL "Members only",IDC_CHECK_MEMBERS,"Button", + BS_AUTOCHECKBOX,111,52,89,10 + LTEXT "Chat rooms:",IDC_STATIC,2,90,100,8 + /* + CONTROL "Tree1",IDC_LIST,"SysTreeView32",TVS_DISABLEDRAGDROP | + TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS | TVS_FULLROWSELECT | + TVS_NONEVENHEIGHT,0,100,177,80,WS_EX_STATICEDGE + */ + CONTROL "Refresh",IDC_REFRESH,"MButtonClass",WS_TABSTOP,186,160, + 50,14,0x18000000L + GROUPBOX "New chat room",IDC_STATIC,0,5,244,78 + CONTROL "List1",IDC_LIST,"SysListView32",LVS_REPORT | + LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_AUTOARRANGE | + LVS_NOCOLUMNHEADER | LVS_OWNERDRAWFIXED | WS_TABSTOP,0,100,177,80, + WS_EX_CLIENTEDGE +END + +IDD_TAB_MYNICKNAMES DIALOG DISCARDABLE 216, 28, 244, 180 +STYLE WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "Register",IDC_REGISTER,"MButtonClass",WS_TABSTOP,186,62, + 50,14,0x18000000L + EDITTEXT IDC_NICK,84,20,149,14,ES_AUTOHSCROLL + LTEXT "Nickname:",IDC_STATIC,14,23,60,8 + LTEXT "Nicknames:",IDC_STATIC,2,90,100,8 + CONTROL "Remove",IDC_REMOVE,"MButtonClass",WS_TABSTOP,186,110,50, + 14,0x18000000L + CONTROL "Refresh",IDC_REFRESH,"MButtonClass",WS_TABSTOP,186,160, + 50,14,0x18000000L + GROUPBOX "New nickname",IDC_STATIC,0,5,244,78 + CONTROL "List1",IDC_LIST,"SysListView32",LVS_REPORT | + LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_AUTOARRANGE | + LVS_NOCOLUMNHEADER | LVS_OWNERDRAWFIXED | WS_TABSTOP,0,100,177,80, + WS_EX_CLIENTEDGE + /* + CONTROL "Tree1",IDC_LIST,"SysTreeView32",TVS_DISABLEDRAGDROP | + TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS | TVS_FULLROWSELECT | + TVS_NONEVENHEIGHT,0,100,177,80,WS_EX_STATICEDGE + */ +END + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION MUCC_FILEVERSION_STRING + PRODUCTVERSION MUCC_FILEVERSION_STRING + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041504e3" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "http://mtlen.berlios.de\0" + VALUE "FileDescription", "Group Chats GUI Plugin for Miranda IM\0" + VALUE "FileVersion", MUCC_VERSION_STRING + VALUE "InternalName", "tlen_chat\0" + VALUE "LegalCopyright", "Copyright (c) 2004-2006 Piotr Piastucki\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "tlen_chat.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "Tlen Chat Plugin\0" + VALUE "ProductVersion", MUCC_VERSION_STRING + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x415, 1251 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_CHAT ICON DISCARDABLE "icos\\chat.ico" +IDI_BLANK ICON DISCARDABLE "icos\\blank.ico" +IDI_ITALIC ICON DISCARDABLE "icos\\italic.ico" +IDI_BOLD ICON DISCARDABLE "icos\\bold.ico" +IDI_UNDERLINE ICON DISCARDABLE "icos\\underline.ico" +IDI_OPTIONS ICON DISCARDABLE "icos\\options.ico" +IDI_OWNER ICON DISCARDABLE "icos\\owner.ico" +IDI_GLOBALOWNER ICON DISCARDABLE "icos\\glowner.ico" +IDI_ADMIN ICON DISCARDABLE "icos\\admin.ico" +IDI_REGISTERED ICON DISCARDABLE "icos\\registered.ico" +IDI_R_MODERATED ICON DISCARDABLE "icos\\r_mod.ico" +IDI_R_MEMBERS ICON DISCARDABLE "icos\\r_memb.ico" +IDI_R_ANONYMOUS ICON DISCARDABLE "icos\\r_anon.ico" +IDI_SEARCH ICON DISCARDABLE "icos\\search.ico" +IDI_PREV ICON DISCARDABLE "icos\\prev.ico" +IDI_NEXT ICON DISCARDABLE "icos\\next.ico" +IDI_INVITE ICON DISCARDABLE "icos\\invite.ico" +IDI_ADMINISTRATION ICON DISCARDABLE "icos\\administration.ico" +IDI_SMILEY ICON DISCARDABLE "icos\\smile.ico" +IDI_MESSAGE ICON DISCARDABLE "icos\\message.ico" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/mucc.vcxproj b/plugins/!NotAdopted/Tlen/tlen_czaty/mucc.vcxproj new file mode 100644 index 0000000000..c2fe6e7b70 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/mucc.vcxproj @@ -0,0 +1,1245 @@ +п»ї + + + + Debug Ansi + Win32 + + + Debug Ansi + x64 + + + Debug Unicode + Win32 + + + Debug Unicode + x64 + + + Debug x64 + Win32 + + + Debug x64 + x64 + + + Release Ansi + Win32 + + + Release Ansi + x64 + + + Release Unicode + Win32 + + + Release Unicode + x64 + + + Release x64 + Win32 + + + Release x64 + x64 + + + + {BD1D155A-7A47-4414-80A3-CCCC3C5C583B} + + + + DynamicLibrary + false + Unicode + Windows7.1SDK + + + DynamicLibrary + false + Unicode + Windows7.1SDK + + + DynamicLibrary + false + Unicode + Windows7.1SDK + + + DynamicLibrary + false + Unicode + Windows7.1SDK + + + DynamicLibrary + false + MultiByte + Windows7.1SDK + + + DynamicLibrary + false + MultiByte + Windows7.1SDK + + + DynamicLibrary + false + Unicode + Windows7.1SDK + true + + + DynamicLibrary + false + Unicode + Windows7.1SDK + true + + + DynamicLibrary + false + Unicode + Windows7.1SDK + true + + + DynamicLibrary + false + Unicode + Windows7.1SDK + true + + + DynamicLibrary + false + MultiByte + Windows7.1SDK + true + + + DynamicLibrary + false + MultiByte + Windows7.1SDK + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + $(Configuration)\Obj\ + $(Configuration)\Obj\ + $(Configuration)\Obj\ + $(Configuration)\Obj\ + $(Configuration)\Obj\ + $(Configuration)\Obj\ + true + true + true + true + true + true + false + false + false + false + false + false + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + $(Configuration)\Obj\ + $(Configuration)\Obj\ + $(Configuration)\Obj\ + $(Configuration)\Obj\ + $(Configuration)\Obj\ + $(Configuration)\Obj\ + true + true + true + true + true + true + true + true + true + true + true + true + tlen_czaty + tlen_czaty + tlen_czaty + tlen_czaty + tlen_czaty + tlen_czaty + tlen_czaty + tlen_czaty + tlen_czaty + tlen_czaty + tlen_czaty + tlen_czaty + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/mucc.tlb + + + + + MaxSpeed + OnlyExplicitInline + ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;_X64;X64;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(TargetName).pch + + + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + Level3 + true + 4996;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0415 + + + odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + $(TargetDir)tlen_czaty.pdb + 0x32600000 + false + + + $(IntDir)$(TargetName).lib + MachineX86 + true + + + true + $(OutDir)$(TargetName).bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/mucc.tlb + + + + + MaxSpeed + OnlyExplicitInline + ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;UNICODE;_UNICODE;_X64;X64;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(IntDir)$(TargetName).pch + + + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + Level3 + true + 4996;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0415 + + + odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + $(TargetDir)tlen_czaty.pdb + 0x32600000 + false + + + $(IntDir)$(TargetName).lib + true + + + true + $(OutDir)$(TargetName).bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/mucc.tlb + + + + + MaxSpeed + OnlyExplicitInline + ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(IntDir)$(TargetName).pch + + + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + Level3 + true + 4996;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0415 + + + odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + $(TargetDir)tlen_czaty.pdb + 0x32600000 + false + + + $(IntDir)$(TargetName).lib + MachineX86 + true + + + true + $(OutDir)$(TargetName).bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/mucc.tlb + + + + + MaxSpeed + OnlyExplicitInline + ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;UNICODE;_UNICODE;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(IntDir)$(TargetName).pch + + + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + Level3 + true + 4996;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0415 + + + odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + $(TargetDir)tlen_czaty.pdb + 0x32600000 + false + + + $(IntDir)$(TargetName).lib + true + + + true + $(OutDir)$(TargetName).bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/mucc.tlb + + + + + MaxSpeed + OnlyExplicitInline + ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(IntDir)$(TargetName).pch + + + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + Level3 + true + ProgramDatabase + 4996;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0415 + + + odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + $(TargetDir)tlen_czaty.pdb + 0x32600000 + false + + + $(IntDir)$(TargetName).lib + MachineX86 + true + + + true + $(OutDir)$(TargetName).bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/mucc.tlb + + + + + MaxSpeed + OnlyExplicitInline + ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreaded + true + $(IntDir)$(TargetName).pch + + + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + Level3 + true + ProgramDatabase + 4996;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0415 + + + odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + $(TargetDir)tlen_czaty.pdb + 0x32600000 + false + + + $(IntDir)$(TargetName).lib + true + + + true + $(OutDir)$(TargetName).bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/mucc.tlb + + + + + Disabled + ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;X64;_X64;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + $(IntDir)$(TargetName).pch + + + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + Level3 + true + EditAndContinue + 4996;%(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0415 + + + odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + true + $(TargetDir)tlen_czaty.pdb + false + + + $(IntDir)$(TargetName).lib + MachineX86 + + + true + $(OutDir)$(TargetName).bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/mucc.tlb + + + + + Disabled + ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;UNICODE;_UNICODE;X64;_X64;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + $(IntDir)$(TargetName).pch + + + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + Level3 + true + ProgramDatabase + 4996;%(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0415 + + + odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + true + $(TargetDir)tlen_czaty.pdb + false + + + $(IntDir)$(TargetName).lib + + + true + $(OutDir)$(TargetName).bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/mucc.tlb + + + + + Disabled + ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + $(IntDir)$(TargetName).pch + + + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + Level3 + true + EditAndContinue + 4996;%(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0415 + + + odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + true + $(TargetDir)tlen_czaty.pdb + false + + + $(IntDir)$(TargetName).lib + MachineX86 + + + true + $(OutDir)$(TargetName).bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/mucc.tlb + + + + + Disabled + ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;UNICODE;_UNICODE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + $(IntDir)$(TargetName).pch + + + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + Level3 + true + ProgramDatabase + 4996;%(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0415 + + + odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + true + $(TargetDir)tlen_czaty.pdb + false + + + $(IntDir)$(TargetName).lib + + + true + $(OutDir)$(TargetName).bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/mucc.tlb + + + + + Disabled + ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + $(IntDir)$(TargetName).pch + + + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + Level3 + true + EditAndContinue + 4996;%(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0415 + + + odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + true + $(TargetDir)tlen_czaty.pdb + false + + + $(IntDir)$(TargetName).lib + MachineX86 + + + true + $(OutDir)$(TargetName).bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/mucc.tlb + + + + + Disabled + ../../../include;../ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MUCC_EXPORTS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + $(IntDir)$(TargetName).pch + + + $(IntDir) + $(IntDir)vc$(PlatformToolsetVersion).pdb + Level3 + true + ProgramDatabase + 4996;%(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0415 + + + odbc32.lib;odbccp32.lib;comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + true + $(TargetDir)tlen_czaty.pdb + false + + + $(IntDir)$(TargetName).lib + + + true + $(OutDir)$(TargetName).bsc + + + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/mucc_services.cpp b/plugins/!NotAdopted/Tlen/tlen_czaty/mucc_services.cpp new file mode 100644 index 0000000000..0d4571a633 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/mucc_services.cpp @@ -0,0 +1,140 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#include "mucc_services.h" +#include "Utils.h" +#include "HelperDialog.h" + +int MUCCQueryChatGroups(MUCCQUERYRESULT *queryResult) +{ + ManagerWindow *managerWnd=ManagerWindow::getWindow(queryResult->pszModule); + if (managerWnd!=NULL) { + managerWnd->queryResultGroups(queryResult); + } + return 1; +} + +int MUCCQueryChatRooms(MUCCQUERYRESULT *queryResult) +{ + ManagerWindow *managerWnd=ManagerWindow::getWindow(queryResult->pszModule); + if (managerWnd!=NULL) { + managerWnd->queryResultRooms(queryResult); + } + return 1; +} + +int MUCCQueryUserRooms(MUCCQUERYRESULT *queryResult) +{ + ManagerWindow *managerWnd=ManagerWindow::getWindow(queryResult->pszModule); + if (managerWnd!=NULL) { + managerWnd->queryResultUserRooms(queryResult); + } + return 1; +} + +int MUCCQueryUserNicks(MUCCQUERYRESULT *queryResult) +{ + ManagerWindow *managerWnd=ManagerWindow::getWindow(queryResult->pszModule); + if (managerWnd!=NULL) { + managerWnd->queryResultUserNick(queryResult); + } + return 1; +} + +INT_PTR MUCCQueryResult(WPARAM wParam, LPARAM lParam) +{ + MUCCQUERYRESULT *queryResult=(MUCCQUERYRESULT *)lParam; + ChatWindow * chatWindow = NULL; + switch (queryResult->iType) { + case MUCC_EVENT_QUERY_GROUPS: + MUCCQueryChatGroups(queryResult); + break; + case MUCC_EVENT_QUERY_ROOMS: + MUCCQueryChatRooms(queryResult); + break; + case MUCC_EVENT_QUERY_USER_ROOMS: + MUCCQueryUserRooms(queryResult); + break; + case MUCC_EVENT_QUERY_USER_NICKS: + MUCCQueryUserNicks(queryResult); + break; + case MUCC_EVENT_QUERY_CONTACTS: + case MUCC_EVENT_QUERY_USERS: + chatWindow=ChatWindow::getWindow(queryResult->pszModule, queryResult->pszParent); + if (chatWindow!=NULL) { + SendMessage(chatWindow->getHWND(), DM_CHAT_QUERY, (WPARAM) 0, (LPARAM) queryResult); + } + break; + } + return 0; +} + +INT_PTR MUCCNewWindow(WPARAM wParam, LPARAM lParam) +{ + MUCCWINDOW *mucWindow = (MUCCWINDOW *) lParam; + if (mucWindow->iType == MUCC_WINDOW_CHATROOM) { + ChatWindow *chat = ChatWindow::getWindow(mucWindow->pszModule, mucWindow->pszID); + if (chat == NULL) { + chat = new ChatWindow(mucWindow); + } + } else if (mucWindow->iType == MUCC_WINDOW_CHATLIST) { + ManagerWindow *manager = ManagerWindow::getWindow(mucWindow->pszModule); + if (manager == NULL) { + + } + //Utils::log("setting name: %s", mucWindow->pszModuleName); + manager->setModuleName(mucWindow->pszModuleName); + manager->start(); + } + return 0; +} + +INT_PTR MUCCEvent(WPARAM wParam, LPARAM lParam) +{ + MUCCEVENT* mucEvent = (MUCCEVENT *) lParam; + ChatWindow * chatWindow = NULL; + switch (mucEvent->iType) { + case MUCC_EVENT_STATUS: + case MUCC_EVENT_MESSAGE: + case MUCC_EVENT_ROOM_INFO: + case MUCC_EVENT_LEAVE: + case MUCC_EVENT_TOPIC: + chatWindow = ChatWindow::getWindow(mucEvent->pszModule, mucEvent->pszID); + if (chatWindow!=NULL) { + SendMessage(chatWindow->getHWND(), DM_CHAT_EVENT, (WPARAM) 0, (LPARAM) mucEvent); + } + break; + case MUCC_EVENT_ERROR: + chatWindow = ChatWindow::getWindow(mucEvent->pszModule, mucEvent->pszID); + if (chatWindow!=NULL) { + SendMessage(chatWindow->getHWND(), DM_CHAT_EVENT, (WPARAM) 0, (LPARAM) mucEvent); + } else { + HelperDialog::errorDlg(mucEvent); + } + break; + case MUCC_EVENT_INVITATION: + HelperDialog::acceptDlg(mucEvent); + break; + case MUCC_EVENT_JOIN: + HelperDialog::joinDlg(mucEvent); + break; + } + return 0; +} diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/mucc_services.h b/plugins/!NotAdopted/Tlen/tlen_czaty/mucc_services.h new file mode 100644 index 0000000000..f1db38274b --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/mucc_services.h @@ -0,0 +1,35 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#ifndef MUCCSERVICES_INCLUDED +#define MUCCSERVICES_INCLUDED + +#include "mucc.h" +#include "ManagerWindow.h" +#include "ChatWindow.h" + +extern int MUCCServicesInit(WPARAM wParam, LPARAM lParam); + +extern INT_PTR MUCCQueryResult(WPARAM wParam, LPARAM lParam) ; +extern INT_PTR MUCCNewWindow(WPARAM wParam, LPARAM lParam) ; +extern INT_PTR MUCCEvent(WPARAM wParam, LPARAM lParam) ; + +#endif + diff --git a/plugins/!NotAdopted/Tlen/tlen_czaty/resource.h b/plugins/!NotAdopted/Tlen/tlen_czaty/resource.h new file mode 100644 index 0000000000..c4d2f1945c --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_czaty/resource.h @@ -0,0 +1,218 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#define IDI_CHAT 100 +#define IDI_ITALIC 101 +#define IDI_BOLD 102 +#define IDI_UNDERLINE 103 +#define IDI_OPTIONS 104 +#define IDI_OWNER 105 +#define IDI_ADMIN 106 +#define IDI_REGISTERED 107 +#define IDI_R_MODERATED 108 +#define IDI_R_MEMBERS 109 +#define IDI_R_ANONYMOUS 110 +#define IDI_SEARCH 111 +#define IDI_PREV 112 +#define IDI_NEXT 113 +#define IDI_BLANK 114 +#define IDI_INVITE 115 +#define IDI_ADMINISTRATION 116 +#define IDI_GLOBALOWNER 117 +#define IDI_SMILEY 118 +#define IDI_MESSAGE 119 + +#define IDD_CHATMANAGER 150 +#define IDD_GROUPCHAT_LOG 151 +#define IDD_HELPER_JOIN 152 +#define IDD_HELPER_INPUT 153 +#define IDD_HELPER_INVITE 154 +#define IDD_HELPER_INVITE_ACCEPT 155 +#define IDD_HELPER_TOPIC 156 +#define IDD_OPTIONS 157 +#define IDD_OPT_POPUPS 158 +#define IDD_TAB_CHATROOMS 159 +#define IDD_TAB_MYROOMS 160 +#define IDD_TAB_MYNICKNAMES 161 +#define IDD_USER_ADMIN 162 +#define IDD_USER_KICK 163 +#define IDD_USER_ROLE 164 +#define IDD_USER_BROWSER 165 +#define IDD_GROUPCHAT_CONTAINER 166 + +#define IDR_CHATOPTIONS 200 +#define IDR_CONTEXT 201 + +#define IDC_FONTLIST 1000 +#define IDC_COLORINPUT 1001 +#define IDC_COLORBKG 1002 +#define IDC_COLORLIST 1003 +#define IDC_COLORTXT 1004 +#define IDC_CHOOSEFONT 1005 +#define IDC_FONTSGB 1006 +#define IDC_OPTIONSGB 1007 +#define IDC_LOGLIMITSPIN 1008 +#define IDC_LOGLIMIT 1009 +#define IDC_SENDONENTER 1010 +#define IDC_USETABS 1011 +#define IDC_ENABLEIEVIEW 1012 +#define IDC_REGISTER 1020 +#define IDC_NAME 1021 +#define IDC_FRAME 1037 +#define IDC_SIMPLE 1041 +#define IDC_PASSWORD 1050 +#define IDC_JID 1051 +#define IDC_COUNTRY 1060 +#define IDC_NICKNAME 1062 +#define IDC_MSG 1084 +#define IDC_TITLE 1089 +#define IDC_DESC 1090 +#define IDC_DELETE 1092 +#define IDC_LOAD 1093 +#define IDC_JOIN 1123 +#define IDC_ROOM 1124 +#define IDC_ROOM_LABEL 1125 +#define IDC_BROWSE 1126 +#define IDC_VSCROLL 1128 +#define IDC_NICK 1129 +#define IDC_NICK_LABEL 1130 +#define IDC_EDIT 1131 +#define IDC_TREELIST 1132 +#define IDC_LIST 1133 +#define IDC_HSPLIT 1134 +#define IDC_LOG 1136 +#define IDC_VSPLIT 1137 +#define IDC_SET 1140 +#define IDC_TABS 1141 +#define IDC_TOPIC 1141 +#define IDC_TOPIC_BUTTON 1142 +#define IDC_FONT 1143 +#define IDC_ENTER 1144 +#define IDC_CTRLENTER 1145 +#define IDC_FLASH 1148 +#define IDC_TIME 1156 +#define IDC_DATE 1157 +#define IDC_REASON 1171 +#define IDC_USER 1172 +#define IDC_INVITE 1173 +#define IDC_ACCEPT 1174 +#define IDC_FROM 1175 +#define IDC_DELAY 1180 +#define IDC_PREVIEW 1183 +#define IDC_ENABLEPOPUP 1184 +#define IDC_DELAY_PERMANENT 1185 +#define IDC_DELAY_CUSTOM 1186 +#define IDC_DELAY_POPUP 1187 +#define IDC_GROUP 1203 +#define IDC_BOLD 1204 +#define IDC_SMILEY 1205 +#define IDC_UNDERLINE 1205 +#define IDC_ITALIC 1206 +#define IDC_COLOR 1207 +#define IDC_OPTIONS 1208 +#define IDC_SMILEYBTN 1209 +#define IDC_CHECK_PERMANENT 1210 +#define IDC_CHECK_PUBLIC 1211 +#define IDC_CHECK_NICKNAMES 1212 +#define IDC_CHECK_MEMBERS 1213 +#define IDC_NEXT 1214 +#define IDC_PREV 1215 +#define IDC_FONTSIZE 1215 +#define IDC_SEARCH 1216 +#define IDC_REFRESH 1216 +#define IDC_REMOVE 1217 +#define IDC_KICK_OPTIONS 1218 +#define IDC_ROLE_OPTIONS 1219 +#define IDC_KICK 1220 +#define IDC_SET_ROLE 1221 +#define IDC_UPDATE 1313 +#define IDC_STATUS 1414 +#define IDC_PLAN 1415 +#define IDC_SHOW 1416 + +#define IDC_PERSONALGROUP 1434 +#define IDC_EXTRAGROUP 1436 + +#define ID_OPTIONMENU_SHOWNICKNAMES 40001 +#define ID_OPTIONMENU_MSGINNEWLINE 40002 +#define ID_OPTIONMENU_SHOWTIMESTAMP 40011 +#define ID_OPTIONMENU_SHOWDATE 40012 +#define ID_OPTIONMENU_SHOWSECONDS 40013 +#define ID_OPTIONMENU_USELONGDATE 40014 +#define ID_OPTIONMENU_FORMATFONT 40021 +#define ID_OPTIONMENU_FORMATSIZE 40022 +#define ID_OPTIONMENU_FORMATCOLOR 40023 +#define ID_OPTIONMENU_FORMATSTYLE 40024 +#define ID_OPTIONMENU_LOGMESSAGES 40031 +#define ID_OPTIONMENU_LOGJOINED 40032 +#define ID_OPTIONMENU_LOGLEFT 40033 +#define ID_OPTIONMENU_LOGTOPIC 40034 +#define ID_OPTIONMENU_FLASHMESSAGES 40035 +#define ID_OPTIONMENU_FLASHJOINED 40036 +#define ID_OPTIONMENU_FLASHLEFT 40037 +#define ID_OPTIONMENU_FLASHTOPIC 40038 +#define ID_OPTIONMENU_SAVEDEFAULT 40040 +#define ID_USERMENU_MESSAGE 40050 +#define ID_USERMENU_KICK_POPUP 40051 +#define ID_USERMENU_KICK_NO_BAN 40052 +#define ID_USERMENU_KICK_BAN_1_MIN 40053 +#define ID_USERMENU_KICK_BAN_5_MIN 40054 +#define ID_USERMENU_KICK_BAN_15_MIN 40055 +#define ID_USERMENU_KICK_BAN_30_MIN 40056 +#define ID_USERMENU_KICK_BAN_1_H 40057 +#define ID_USERMENU_KICK_BAN_6_H 40058 +#define ID_USERMENU_KICK_BAN_1_D 40059 +#define ID_USERMENU_KICK_BAN_3_D 40060 +#define ID_USERMENU_KICK_BAN_1_W 40061 +#define ID_USERMENU_KICK_BAN_2_W 40062 +#define ID_USERMENU_KICK_BAN_4_W 40063 +#define ID_USERMENU_RIGHTS_NO 40065 +#define ID_USERMENU_RIGHTS_MEMBER 40066 +#define ID_USERMENU_RIGHTS_ADMIN 40067 +#define ID_USERMENU_ADMINISTRATION 40070 +#define ID_USERMENU_UNBAN 40071 +#define ID_ADMINMENU_DESTROY 40080 +#define ID_ADMINMENU_ADMIN 40081 +#define ID_ADMINMENU_BROWSE 40082 +#define ID_ADMINMENU_SAVELOG 40083 + +#define IDM_CUT 40000 +#define IDM_COPY 40001 +#define IDM_PASTE 40002 +#define IDM_UNDO 40003 +#define IDM_DELETE 40004 +#define IDM_REDO 40005 +#define IDM_COPYALL 40011 +#define IDM_SELECTALL 40012 +#define IDM_CLEAR 40013 +#define IDM_OPENNEW 40014 +#define IDM_OPENEXISTING 40015 +#define IDM_COPYLINK 40016 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 205 +#define _APS_NEXT_COMMAND_VALUE 40090 +#define _APS_NEXT_CONTROL_VALUE 1217 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/!NotAdopted/Tlen/tlen_file.c b/plugins/!NotAdopted/Tlen/tlen_file.c new file mode 100644 index 0000000000..9926a09aa6 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_file.c @@ -0,0 +1,718 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" +#include +#include +#include +#include +#include "jabber_list.h" +#include "tlen_p2p_old.h" + +extern int TlenFileCancel(PROTO_INTERFACE *ptr, HANDLE hContact, HANDLE hTransfer); + + +static void TlenFileReceiveParse(TLEN_FILE_TRANSFER *ft) +{ + int i; + char *p; + TLEN_FILE_PACKET *rpacket, *packet; + + rpacket = NULL; + if (ft->state == FT_CONNECTING) { + rpacket = TlenP2PPacketReceive(ft->s); + if (rpacket != NULL) { + p = rpacket->packet; + if (rpacket->type == TLEN_FILE_PACKET_FILE_LIST) { // list of files (length & name) + ft->fileCount = (int)(*((DWORD*)p)); + ft->files = (char **) mir_alloc(sizeof(char *) * ft->fileCount); + ft->filesSize = (long *) mir_alloc(sizeof(long) * ft->fileCount); + ft->currentFile = 0; + ft->allFileTotalSize = 0; + ft->allFileReceivedBytes = 0; + p += sizeof(DWORD); + for (i=0;ifileCount;i++) { + ft->filesSize[i] = (long)(*((DWORD*)p)); + ft->allFileTotalSize += ft->filesSize[i]; + p += sizeof(DWORD); + ft->files[i] = (char *)mir_alloc(256); + memcpy(ft->files[i], p, 256); + p += 256; + } + if ((packet=TlenP2PPacketCreate(3*sizeof(DWORD))) == NULL) { + ft->state = FT_ERROR; + } + else { + TlenP2PPacketSetType(packet, TLEN_FILE_PACKET_FILE_LIST_ACK); + TlenP2PPacketSend(ft->s, packet); + TlenP2PPacketFree(packet); + ft->state = FT_INITIALIZING; + JabberLog(ft->proto, "Change to FT_INITIALIZING"); + } + } + TlenP2PPacketFree(rpacket); + } + else { + ft->state = FT_ERROR; + } + } + else if (ft->state == FT_INITIALIZING) { + char *fullFileName; + if ((packet=TlenP2PPacketCreate(3*sizeof(DWORD))) != NULL) { + TlenP2PPacketSetType(packet, TLEN_FILE_PACKET_FILE_REQUEST); // file request + TlenP2PPacketPackDword(packet, ft->currentFile); + TlenP2PPacketPackDword(packet, 0); + TlenP2PPacketPackDword(packet, 0); + TlenP2PPacketSend(ft->s, packet); + TlenP2PPacketFree(packet); + + fullFileName = (char *) mir_alloc(strlen(ft->szSavePath) + strlen(ft->files[ft->currentFile]) + 2); + strcpy(fullFileName, ft->szSavePath); + if (fullFileName[strlen(fullFileName)-1] != '\\') + strcat(fullFileName, "\\"); + strcat(fullFileName, ft->files[ft->currentFile]); + ft->fileId = _open(fullFileName, _O_BINARY|_O_WRONLY|_O_CREAT|_O_TRUNC, _S_IREAD|_S_IWRITE); + ft->fileReceivedBytes = 0; + ft->fileTotalSize = ft->filesSize[ft->currentFile]; + JabberLog(ft->proto, "Saving to [%s] [%d]", fullFileName, ft->filesSize[ft->currentFile]); + mir_free(fullFileName); + ft->state = FT_RECEIVING; + JabberLog(ft->proto, "Change to FT_RECEIVING"); + } + else { + ft->state = FT_ERROR; + } + } + else if (ft->state == FT_RECEIVING) { + PROTOFILETRANSFERSTATUS pfts; + memset(&pfts, 0, sizeof(PROTOFILETRANSFERSTATUS)); + pfts.cbSize = sizeof(PROTOFILETRANSFERSTATUS); + pfts.hContact = ft->hContact; + pfts.sending = FALSE; + pfts.files = ft->files; + pfts.totalFiles = ft->fileCount; + pfts.currentFileNumber = ft->currentFile; + pfts.totalBytes = ft->allFileTotalSize; + pfts.workingDir = NULL; + pfts.currentFile = ft->files[ft->currentFile]; + pfts.currentFileSize = ft->filesSize[ft->currentFile]; + pfts.currentFileTime = 0; + JabberLog(ft->proto, "Receiving data..."); + while (ft->state == FT_RECEIVING) { + rpacket = TlenP2PPacketReceive(ft->s); + if (rpacket != NULL) { + p = rpacket->packet; + if (rpacket->type == TLEN_FILE_PACKET_FILE_DATA) { // file data + int writeSize; + writeSize = rpacket->len - 2 * sizeof(DWORD) ; // skip file offset + if (_write(ft->fileId, p + 2 * sizeof(DWORD), writeSize) != writeSize) { + ft->state = FT_ERROR; + } + else { + ft->fileReceivedBytes += writeSize; + ft->allFileReceivedBytes += writeSize; + pfts.totalProgress = ft->allFileReceivedBytes; + pfts.currentFileProgress = ft->fileReceivedBytes; + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM) &pfts); + } + } + else if (rpacket->type == TLEN_FILE_PACKET_END_OF_FILE) { // end of file + _close(ft->fileId); + JabberLog(ft->proto, "Finishing this file..."); + if (ft->currentFile >= ft->fileCount-1) { + ft->state = FT_DONE; + } + else { + ft->currentFile++; + ft->state = FT_INITIALIZING; + JabberLog(ft->proto, "File received, advancing to the next file..."); + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0); + } + } + TlenP2PPacketFree(rpacket); + } + else { + ft->state = FT_ERROR; + } + } + } +} + +static void TlenFileReceivingConnection(JABBER_SOCKET hConnection, DWORD dwRemoteIP, void * pExtra) +{ + JABBER_SOCKET slisten; + TLEN_FILE_TRANSFER *ft; + + TlenProtocol *proto = (TlenProtocol *)pExtra; + ft = TlenP2PEstablishIncomingConnection(proto, hConnection, LIST_FILE, TRUE); + if (ft != NULL) { + slisten = ft->s; + ft->s = hConnection; + JabberLog(ft->proto, "Set ft->s to %d (saving %d)", hConnection, slisten); + JabberLog(ft->proto, "Entering send loop for this file connection... (ft->s is hConnection)"); + while (ft->state!=FT_DONE && ft->state!=FT_ERROR) { + TlenFileReceiveParse(ft); + } + if (ft->state==FT_DONE) + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); + else + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); + JabberLog(ft->proto, "Closing connection for this file transfer... (ft->s is now hBind)"); + ft->s = slisten; + JabberLog(ft->proto, "ft->s is restored to %d", ft->s); + if (ft->s != hConnection) { + Netlib_CloseHandle(hConnection); + } + if (ft->hFileEvent != NULL) + SetEvent(ft->hFileEvent); + } else { + Netlib_CloseHandle(hConnection); + } +} + + +static void __cdecl TlenFileReceiveThread(TLEN_FILE_TRANSFER *ft) +{ + NETLIBOPENCONNECTION nloc; + JABBER_SOCKET s; + JabberLog(ft->proto, "Thread started: type=file_receive server='%s' port='%d'", ft->hostName, ft->wPort); + ft->mode = FT_RECV; + nloc.cbSize = NETLIBOPENCONNECTION_V1_SIZE;//sizeof(NETLIBOPENCONNECTION); + nloc.szHost = ft->hostName; + nloc.wPort = ft->wPort; + nloc.flags = 0; + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, ft, 0); + s = (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, (WPARAM) ft->proto->hNetlibUser, (LPARAM) &nloc); + if (s != NULL) { + ft->s = s; + JabberLog(ft->proto, "Entering file receive loop"); + TlenP2PEstablishOutgoingConnection(ft, TRUE); + while (ft->state!=FT_DONE && ft->state!=FT_ERROR) { + TlenFileReceiveParse(ft); + } + if (ft->s) { + Netlib_CloseHandle(s); + } + ft->s = NULL; + } else { + ft->pfnNewConnectionV2 = TlenFileReceivingConnection; + JabberLog(ft->proto, "Connection failed - receiving as server"); + s = TlenP2PListen(ft); + if (s != NULL) { + HANDLE hEvent; + char *nick; + ft->s = s; + hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + ft->hFileEvent = hEvent; + ft->currentFile = 0; + ft->state = FT_CONNECTING; + nick = JabberNickFromJID(ft->jid); + JabberSend(ft->proto, "", nick, ft->iqId, ft->localName, ft->wLocalPort); + mir_free(nick); + JabberLog(ft->proto, "Waiting for the file to be received..."); + WaitForSingleObject(hEvent, INFINITE); + ft->hFileEvent = NULL; + CloseHandle(hEvent); + JabberLog(ft->proto, "Finish all files"); + Netlib_CloseHandle(s); + } else { + ft->state = FT_ERROR; + } + } + JabberListRemove(ft->proto, LIST_FILE, ft->iqId); + if (ft->state==FT_DONE) + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); + else { + char *nick; + nick = JabberNickFromJID(ft->jid); + JabberSend(ft->proto, "", nick, ft->iqId); + mir_free(nick); + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); + } + + JabberLog(ft->proto, "Thread ended: type=file_receive server='%s'", ft->hostName); + TlenP2PFreeFileTransfer(ft); +} + + + +static void TlenFileSendParse(TLEN_FILE_TRANSFER *ft) +{ + int i; + char *p, *t; + int currentFile, numRead; + char *fileBuffer; + TLEN_FILE_PACKET *rpacket, *packet; + + + if (ft->state == FT_CONNECTING) { + char filename[256]; // Must be 256 (0x100) + if ((packet=TlenP2PPacketCreate(sizeof(DWORD)+(ft->fileCount*(sizeof(filename)+sizeof(DWORD))))) != NULL) { + // Must pause a bit, sending these two packets back to back + // will break the session because the receiver cannot take it :) + SleepEx(1000, TRUE); + TlenP2PPacketSetLen(packet, 0); // Reuse packet + TlenP2PPacketSetType(packet, TLEN_FILE_PACKET_FILE_LIST); + TlenP2PPacketPackDword(packet, (DWORD) ft->fileCount); + for (i=0; ifileCount; i++) { +// struct _stat statbuf; +// _stat(ft->files[i], &statbuf); +// TlenP2PPacketPackDword(packet, statbuf.st_size); + TlenP2PPacketPackDword(packet, ft->filesSize[i]); + memset(filename, 0, sizeof(filename)); + if ((t=strrchr(ft->files[i], '\\')) != NULL) + t++; + else + t = ft->files[i]; + _snprintf(filename, sizeof(filename)-1, t); + TlenP2PPacketPackBuffer(packet, filename, sizeof(filename)); + } + TlenP2PPacketSend(ft->s, packet); + TlenP2PPacketFree(packet); + + ft->allFileReceivedBytes = 0; + ft->state = FT_INITIALIZING; + JabberLog(ft->proto, "Change to FT_INITIALIZING"); + } + else { + ft->state = FT_ERROR; + } + } + else if (ft->state == FT_INITIALIZING) { // FT_INITIALIZING + rpacket = TlenP2PPacketReceive(ft->s); + JabberLog(ft->proto, "FT_INITIALIZING: recv %d", rpacket); + if (rpacket == NULL) { + ft->state = FT_ERROR; + return; + } + JabberLog(ft->proto, "FT_INITIALIZING: recv type %d", rpacket->type); + p = rpacket->packet; + // TYPE: TLEN_FILE_PACKET_FILE_LIST_ACK will be ignored + // LEN: 0 + if (rpacket->type == TLEN_FILE_PACKET_FILE_LIST_ACK) { + + } + // Then the receiver will request each file + // TYPE: TLEN_FILE_PACKET_REQUEST + // LEN: + // (DWORD) file number + // (DWORD) 0 + // (DWORD) 0 + else if (rpacket->type == TLEN_FILE_PACKET_FILE_REQUEST) { + PROTOFILETRANSFERSTATUS pfts; + //struct _stat statbuf; + + currentFile = *((DWORD*)p); + if (currentFile != ft->currentFile) { + JabberLog(ft->proto, "Requested file (#%d) is invalid (must be %d)", currentFile, ft->currentFile); + ft->state = FT_ERROR; + } + else { + // _stat(ft->files[currentFile], &statbuf); // file size in statbuf.st_size + JabberLog(ft->proto, "Sending [%s] [%d]", ft->files[currentFile], ft->filesSize[currentFile]); + if ((ft->fileId=_open(ft->files[currentFile], _O_BINARY|_O_RDONLY)) < 0) { + JabberLog(ft->proto, "File cannot be opened"); + ft->state = FT_ERROR; + } + else { + memset(&pfts, 0, sizeof(PROTOFILETRANSFERSTATUS)); + pfts.cbSize = sizeof(PROTOFILETRANSFERSTATUS); + pfts.hContact = ft->hContact; + pfts.sending = TRUE; + pfts.files = ft->files; + pfts.totalFiles = ft->fileCount; + pfts.currentFileNumber = ft->currentFile; + pfts.totalBytes = ft->allFileTotalSize; + pfts.workingDir = NULL; + pfts.currentFile = ft->files[ft->currentFile]; + pfts.currentFileSize = ft->filesSize[ft->currentFile]; //statbuf.st_size; + pfts.currentFileTime = 0; + ft->fileReceivedBytes = 0; + if ((packet = TlenP2PPacketCreate(2*sizeof(DWORD)+2048)) == NULL) { + ft->state = FT_ERROR; + } + else { + TlenP2PPacketSetType(packet, TLEN_FILE_PACKET_FILE_DATA); + fileBuffer = (char *) mir_alloc(2048); + JabberLog(ft->proto, "Sending file data..."); + while ((numRead=_read(ft->fileId, fileBuffer, 2048)) > 0) { + TlenP2PPacketSetLen(packet, 0); // Reuse packet + TlenP2PPacketPackDword(packet, (DWORD) ft->fileReceivedBytes); + TlenP2PPacketPackDword(packet, 0); + TlenP2PPacketPackBuffer(packet, fileBuffer, numRead); + if (TlenP2PPacketSend(ft->s, packet)) { + ft->fileReceivedBytes += numRead; + ft->allFileReceivedBytes += numRead; + pfts.totalProgress = ft->allFileReceivedBytes; + pfts.currentFileProgress = ft->fileReceivedBytes; + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM) &pfts); + } + else { + ft->state = FT_ERROR; + break; + } + } + mir_free(fileBuffer); + _close(ft->fileId); + if (ft->state != FT_ERROR) { + if (ft->currentFile >= ft->fileCount-1) + ft->state = FT_DONE; + else { + ft->currentFile++; + ft->state = FT_INITIALIZING; + JabberLog(ft->proto, "File sent, advancing to the next file..."); + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0); + } + } + JabberLog(ft->proto, "Finishing this file..."); + TlenP2PPacketSetLen(packet, 0); // Reuse packet + TlenP2PPacketSetType(packet, TLEN_FILE_PACKET_END_OF_FILE); + TlenP2PPacketPackDword(packet, currentFile); + TlenP2PPacketSend(ft->s, packet); + TlenP2PPacketFree(packet); + } + } + } + TlenP2PPacketFree(rpacket); + } + else { + ft->state = FT_ERROR; + } + } +} + +static void TlenFileSendingConnection(JABBER_SOCKET hConnection, DWORD dwRemoteIP, void * pExtra) +{ + JABBER_SOCKET slisten; + TLEN_FILE_TRANSFER *ft; + TlenProtocol *proto = (TlenProtocol *)pExtra; + + ft = TlenP2PEstablishIncomingConnection(proto, hConnection, LIST_FILE, TRUE); + if (ft != NULL) { + slisten = ft->s; + ft->s = hConnection; + JabberLog(ft->proto, "Set ft->s to %d (saving %d)", hConnection, slisten); + + JabberLog(ft->proto, "Entering send loop for this file connection... (ft->s is hConnection)"); + while (ft->state!=FT_DONE && ft->state!=FT_ERROR) { + TlenFileSendParse(ft); + } + if (ft->state==FT_DONE) + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); + else + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); + JabberLog(ft->proto, "Closing connection for this file transfer... (ft->s is now hBind)"); + ft->s = slisten; + JabberLog(ft->proto, "ft->s is restored to %d", ft->s); + if (ft->s != hConnection) { + Netlib_CloseHandle(hConnection); + } + if (ft->hFileEvent != NULL) + SetEvent(ft->hFileEvent); + } else { + Netlib_CloseHandle(hConnection); + } +} + +int TlenFileCancelAll(TlenProtocol *proto) +{ + JABBER_LIST_ITEM *item; + HANDLE hEvent; + int i = 0; + + while ((i=JabberListFindNext(proto, LIST_FILE, 0)) >=0 ) { + if ((item=JabberListGetItemPtrFromIndex(proto, i)) != NULL) { + TLEN_FILE_TRANSFER *ft = item->ft; + JabberListRemoveByIndex(proto, i); + if (ft != NULL) { + if (ft->s) { + //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); + JabberLog(ft->proto, "Closing ft->s = %d", ft->s); + ft->state = FT_ERROR; + Netlib_CloseHandle(ft->s); + ft->s = NULL; + if (ft->hFileEvent != NULL) { + hEvent = ft->hFileEvent; + ft->hFileEvent = NULL; + SetEvent(hEvent); + } + } else { + JabberLog(ft->proto, "freeing ft struct"); + TlenP2PFreeFileTransfer(ft); + } + } + } + } + return 0; +} + +static void __cdecl TlenFileSendingThread(TLEN_FILE_TRANSFER *ft) +{ + JABBER_SOCKET s = NULL; + HANDLE hEvent; + char *nick; + + JabberLog(ft->proto, "Thread started: type=tlen_file_send"); + ft->mode = FT_SEND; + ft->pfnNewConnectionV2 = TlenFileSendingConnection; + s = TlenP2PListen(ft); + if (s != NULL) { + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, ft, 0); + ft->s = s; + //JabberLog("ft->s = %d", s); + //JabberLog("fileCount = %d", ft->fileCount); + + hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + ft->hFileEvent = hEvent; + ft->currentFile = 0; + ft->state = FT_CONNECTING; + + nick = JabberNickFromJID(ft->jid); + JabberSend(ft->proto, "", nick, ft->iqId, ft->localName, ft->wLocalPort); + mir_free(nick); + JabberLog(ft->proto, "Waiting for the file to be sent..."); + WaitForSingleObject(hEvent, INFINITE); + ft->hFileEvent = NULL; + CloseHandle(hEvent); + JabberLog(ft->proto, "Finish all files"); + Netlib_CloseHandle(s); + ft->s = NULL; + JabberLog(ft->proto, "ft->s is NULL"); + + if (ft->state == FT_SWITCH) { + NETLIBOPENCONNECTION nloc; + JABBER_SOCKET s; + JabberLog(ft->proto, "Sending as client..."); + ft->state = FT_CONNECTING; + nloc.cbSize = NETLIBOPENCONNECTION_V1_SIZE;//sizeof(NETLIBOPENCONNECTION); + nloc.szHost = ft->hostName; + nloc.wPort = ft->wPort; + nloc.flags = 0; + s = (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, (WPARAM) ft->proto->hNetlibUser, (LPARAM) &nloc); + if (s != NULL) { + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, ft, 0); + ft->s = s; + TlenP2PEstablishOutgoingConnection(ft, TRUE); + JabberLog(ft->proto, "Entering send loop for this file connection..."); + while (ft->state!=FT_DONE && ft->state!=FT_ERROR) { + TlenFileSendParse(ft); + } + if (ft->state==FT_DONE) + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); + else + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); + JabberLog(ft->proto, "Closing connection for this file transfer... "); + Netlib_CloseHandle(s); + } else { + ft->state = FT_ERROR; + } + } + } else { + JabberLog(ft->proto, "Cannot allocate port to bind for file server thread, thread ended."); + ft->state = FT_ERROR; + } + JabberListRemove(ft->proto, LIST_FILE, ft->iqId); + switch (ft->state) { + case FT_DONE: + JabberLog(ft->proto, "Finish successfully"); + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); + break; + case FT_DENIED: + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_DENIED, ft, 0); + break; + default: // FT_ERROR: + nick = JabberNickFromJID(ft->jid); + JabberSend(ft->proto, "", nick, ft->iqId); + mir_free(nick); + JabberLog(ft->proto, "Finish with errors"); + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); + break; + } + JabberLog(ft->proto, "Thread ended: type=file_send"); + TlenP2PFreeFileTransfer(ft); +} + + +TLEN_FILE_TRANSFER *TlenFileCreateFT(TlenProtocol *proto, const char *jid) { + TLEN_FILE_TRANSFER *ft; + ft = (TLEN_FILE_TRANSFER *) mir_alloc(sizeof(TLEN_FILE_TRANSFER)); + memset(ft, 0, sizeof(TLEN_FILE_TRANSFER)); + ft->proto = proto; + ft->jid = mir_strdup(jid); + return ft; +} + +/* + * File transfer + */ +void TlenProcessF(XmlNode *node, ThreadData *info) +{ + TLEN_FILE_TRANSFER *ft; + CCSDATA ccs; + PROTORECVEVENT pre; + char *szBlob, *from, *p, *e; + char jid[128], szFilename[MAX_PATH]; + int numFiles; + JABBER_LIST_ITEM *item; + +// if (!node->name || strcmp(node->name, "f")) return; + if (info == NULL) return; + + if ((from=JabberXmlGetAttrValue(node, "f")) != NULL) { + + if (strchr(from, '@') == NULL) { + _snprintf(jid, sizeof(jid), "%s@%s", from, info->server); + } else { + _snprintf(jid, sizeof(jid), "%s", from); + } + if ((e=JabberXmlGetAttrValue(node, "e")) != NULL) { + + if (!strcmp(e, "1")) { + // FILE_RECV : e='1' : File transfer request + ft = TlenFileCreateFT(info->proto, jid); + ft->hContact = JabberHContactFromJID(info->proto, jid); + + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) + ft->iqId = mir_strdup(p); + + szFilename[0] = '\0'; + if ((p=JabberXmlGetAttrValue(node, "c")) != NULL) { + numFiles = atoi(p); + if (numFiles == 1) { + if ((p=JabberXmlGetAttrValue(node, "n")) != NULL) { + p = JabberTextDecode(p); + strncpy(szFilename, p, sizeof(szFilename)); + mir_free(p); + } else { + strcpy(szFilename, Translate("1 File")); + } + } + else if (numFiles > 1) { + _snprintf(szFilename, sizeof(szFilename), Translate("%d Files"), numFiles); + } + } + + if (szFilename[0]!='\0' && ft->iqId!=NULL) { + // blob is DWORD(*ft), ASCIIZ(filenames), ASCIIZ(description) + szBlob = (char *) mir_alloc(sizeof(DWORD) + strlen(szFilename) + 2); + *((PDWORD) szBlob) = (DWORD) ft; + strcpy(szBlob + sizeof(DWORD), szFilename); + szBlob[sizeof(DWORD) + strlen(szFilename) + 1] = '\0'; + pre.flags = 0; + pre.timestamp = time(NULL); + pre.szMessage = szBlob; + pre.lParam = 0; + ccs.szProtoService = PSR_FILE; + ccs.hContact = ft->hContact; + ccs.wParam = 0; + ccs.lParam = (LPARAM) ⪯ + JabberLog(ft->proto, "sending chainrecv"); + CallService(MS_PROTO_CHAINRECV, 0, (LPARAM) &ccs); + mir_free(szBlob); + } + else { + // malformed request, reject + if (ft->iqId) + JabberSend(ft->proto, "", ft->iqId, from); + else + JabberSend(ft->proto, "", from); + TlenP2PFreeFileTransfer(ft); + } + } + else if (!strcmp(e, "3")) { + // FILE_RECV : e='3' : invalid transfer error + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_FILE, p)) != NULL) { + if (item->ft != NULL) { + ProtoBroadcastAck(info->proto->iface.m_szModuleName, item->ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, item->ft, 0); + TlenFileCancel((PROTO_INTERFACE *)info->proto, NULL, item->ft); + } + JabberListRemove(info->proto, LIST_FILE, p); + } + } + } + else if (!strcmp(e, "4")) { + // FILE_SEND : e='4' : File sending request was denied by the remote client + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_FILE, p)) != NULL) { + if (!strcmp(item->ft->jid, jid)) { + ProtoBroadcastAck(info->proto->iface.m_szModuleName, item->ft->hContact, ACKTYPE_FILE, ACKRESULT_DENIED, item->ft, 0); + JabberListRemove(info->proto, LIST_FILE, p); + } + } + } + } + else if (!strcmp(e, "5")) { + // FILE_SEND : e='5' : File sending request was accepted + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_FILE, p)) != NULL) { + if (!strcmp(item->ft->jid, jid)) + JabberForkThread((void (__cdecl *)(void*))TlenFileSendingThread, 0, item->ft); + } + } + } + else if (!strcmp(e, "6")) { + // FILE_RECV : e='6' : IP and port information to connect to get file + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_FILE, p)) != NULL) { + if ((p=JabberXmlGetAttrValue(node, "a")) != NULL) { + item->ft->hostName = mir_strdup(p); + if ((p=JabberXmlGetAttrValue(node, "p")) != NULL) { + item->ft->wPort = atoi(p); + JabberForkThread((void (__cdecl *)(void*))TlenFileReceiveThread, 0, item->ft); + } + } + } + } + } + else if (!strcmp(e, "7")) { + // FILE_RECV : e='7' : IP and port information to connect to send file + // in case the conection to the given server was not successful + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_FILE, p)) != NULL) { + if ((p=JabberXmlGetAttrValue(node, "a")) != NULL) { + if (item->ft->hostName!=NULL) mir_free(item->ft->hostName); + item->ft->hostName = mir_strdup(p); + if ((p=JabberXmlGetAttrValue(node, "p")) != NULL) { + item->ft->wPort = atoi(p); + item->ft->state = FT_SWITCH; + SetEvent(item->ft->hFileEvent); + } + } + } + } + } + else if (!strcmp(e, "8")) { + // FILE_RECV : e='8' : transfer error + if ((p=JabberXmlGetAttrValue(node, "i")) != NULL) { + if ((item=JabberListGetItemPtr(info->proto, LIST_FILE, p)) != NULL) { + item->ft->state = FT_ERROR; + if (item->ft->hFileEvent != NULL) { + SetEvent(item->ft->hFileEvent); + } else { + ProtoBroadcastAck(info->proto->iface.m_szModuleName, item->ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, item->ft, 0); + } + } + } + } + } + } +} diff --git a/plugins/!NotAdopted/Tlen/tlen_file.h b/plugins/!NotAdopted/Tlen/tlen_file.h new file mode 100644 index 0000000000..40527a2bcb --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_file.h @@ -0,0 +1,34 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef _TLEN_FILE_H_ +#define _TLEN_FILE_H_ + +#include +#include "jabber.h" + +extern int TlenFileCancelAll(TlenProtocol *proto); +extern void TlenProcessF(XmlNode *node, ThreadData *userdata); +extern TLEN_FILE_TRANSFER *TlenFileCreateFT(TlenProtocol *proto, const char *jid); +#endif + diff --git a/plugins/!NotAdopted/Tlen/tlen_muc.c b/plugins/!NotAdopted/Tlen/tlen_muc.c new file mode 100644 index 0000000000..0b8e7534f5 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_muc.c @@ -0,0 +1,1071 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" +#include "jabber_list.h" +#include "jabber_iq.h" +#include "resource.h" +#include "tlen_muc.h" + +static int TlenMUCHandleEvent(void *ptr, WPARAM wParam, LPARAM lParam); +static int TlenMUCQueryContacts(TlenProtocol *proto, const char *roomId); +static int TlenMUCSendInvitation(TlenProtocol *proto, const char *roomID, const char *user); +static int TlenMUCSendPresence(TlenProtocol *proto, const char *roomID, const char *nick, int desiredStatus); +static int TlenMUCSendMessage(TlenProtocol *proto, MUCCEVENT *event); +static int TlenMUCSendTopic(TlenProtocol *proto, MUCCEVENT *event); +static int TlenMUCSendQuery(TlenProtocol *proto, int type, const char *parent, int page); + +static int isSelf(TlenProtocol *proto, const char *roomID, const char *nick) +{ + JABBER_LIST_ITEM *item; + int result; + result=0; + item = JabberListGetItemPtr(proto, LIST_CHATROOM, roomID); + if (item!=NULL) { + if (item->nick==NULL) { + if (!strcmp(nick, proto->threadData->username)) result = 1; + } else if (nick[0]=='~') { + if (!strcmp(nick+1, item->nick)) { + result = 1; + } + } + } + return result; +} + +static int stringToHex(const char *str) +{ + int i, val; + val = 0; + for (i=0;i<2;i++) { + val <<= 4; + if (str[i]>='A' && str[i]<='F') { + val += 10 + str[i]-'A'; + } else if (str[i]>='0' && str[i]<='9') { + val += str[i]-'0'; + } + } + return val; + +} +static char *getDisplayName(TlenProtocol *proto, const char *id) +{ + CONTACTINFO ci; + char jid[256]; + HANDLE hContact; + DBVARIANT dbv; + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { + _snprintf(jid, sizeof(jid), "%s@%s", id, dbv.pszVal); + DBFreeVariant(&dbv); + if (((hContact=JabberHContactFromJID(proto, jid)) != NULL) || !strcmp(id, proto->threadData->username)) { + ZeroMemory(&ci, sizeof(ci)); + ci.cbSize = sizeof(ci); + ci.hContact = hContact; + ci.szProto = (char *)proto->iface.m_szModuleName; + ci.dwFlag = CNF_DISPLAY; + if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) { + if (ci.type == CNFT_ASCIIZ) { + if (ci.pszVal) { + char * str = mir_strdup((char *)ci.pszVal); + miranda_sys_free(ci.pszVal); + return str; + } + } + } + } + } + return mir_strdup(id); +} + +BOOL TlenMUCInit(TlenProtocol *proto) +{ + HookEventObj_Ex(ME_MUCC_EVENT, proto, TlenMUCHandleEvent); + return 0; +} +static int TlenMUCHandleEvent(void *ptr, WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact; + int id; + MUCCEVENT *mucce=(MUCCEVENT *) lParam; + TlenProtocol *proto = (TlenProtocol *)ptr; + if (!strcmp(mucce->pszModule, proto->iface.m_szModuleName)) { + switch (mucce->iType) { + case MUCC_EVENT_INVITE: + TlenMUCSendInvitation(proto, mucce->pszID, mucce->pszNick); + break; + case MUCC_EVENT_MESSAGE: + TlenMUCSendMessage(proto, mucce); + break; + case MUCC_EVENT_TOPIC: + TlenMUCSendTopic(proto, mucce); + break; + case MUCC_EVENT_LEAVE: + TlenMUCSendPresence(proto, mucce->pszID, NULL, ID_STATUS_OFFLINE); + break; + case MUCC_EVENT_QUERY_GROUPS: + TlenMUCSendQuery(proto, 1, mucce->pszID, 0); + break; + case MUCC_EVENT_QUERY_ROOMS: + TlenMUCSendQuery(proto, 2, mucce->pszID, mucce->dwData); + break; + case MUCC_EVENT_QUERY_SEARCH: + TlenMUCSendQuery(proto, 3, mucce->pszName, 0); + break; + case MUCC_EVENT_QUERY_USERS: + switch (mucce->dwFlags) { + case MUCC_EF_USER_OWNER: + id = 1; + break; + case MUCC_EF_USER_ADMIN: + id = 2; + break; + case MUCC_EF_USER_MEMBER: + id = 3; + break; + case MUCC_EF_USER_BANNED: + id = 4; + break; + case MUCC_EF_USER_MODERATOR: + id = 6; + break; + default: + id = 0; + } + TlenMUCSendQuery(proto, 4, mucce->pszID, id); + break; + case MUCC_EVENT_REGISTER_NICK: + TlenMUCSendQuery(proto, 6, mucce->pszNick, 0); + break; + case MUCC_EVENT_REMOVE_NICK: + TlenMUCSendQuery(proto, 6, mucce->pszNick, 1); + break; + case MUCC_EVENT_REGISTER_ROOM: + id = JabberSerialNext(proto); + if (proto->isOnline) { + if (mucce->pszNick!=NULL) { + JabberSend(proto, "

", id, mucce->dwFlags | 0x10, mucce->pszName, mucce->pszID); + } else { + JabberSend(proto, "

", id, mucce->dwFlags | 0x10, mucce->pszName, mucce->pszID); + } + } + break; + case MUCC_EVENT_REMOVE_ROOM: + if (proto->isOnline) { + JabberSend(proto, "

", mucce->pszID); + JabberListRemove(proto, LIST_CHATROOM, mucce->pszID); + // TlenMUCSendPresence(mucce->pszID, NULL, ID_STATUS_OFFLINE); + } + break; + case MUCC_EVENT_KICK_BAN: + if (proto->isOnline) { + char *nick; + nick = JabberResourceFromJID(mucce->pszUID); + if (!isSelf(proto, mucce->pszID, nick)) { + char *reason = JabberTextEncode(mucce->pszText); + JabberSend(proto, "

", mucce->pszID, nick, mucce->dwData, reason); + mir_free(reason); + } + mir_free(nick); + } + break; + case MUCC_EVENT_UNBAN: + if (proto->isOnline) { + char *nick; + nick = JabberResourceFromJID(mucce->pszUID); + if (!isSelf(proto, mucce->pszID, nick)) { + JabberSend(proto, "

", mucce->pszID, nick); + } + mir_free(nick); + } + break; + case MUCC_EVENT_SET_USER_ROLE: + if (proto->isOnline) { + char *nick; + nick = JabberResourceFromJID(mucce->pszUID); + if (!isSelf(proto, mucce->pszID, nick)) { + if (mucce->dwFlags == MUCC_EF_USER_ADMIN) { + id = 2; + } else if (mucce->dwFlags == MUCC_EF_USER_MEMBER) { + id = 3; + } else { + id = 0; + } + JabberSend(proto, "

", mucce->pszID, nick, id); + } + mir_free(nick); + } + break; + case MUCC_EVENT_QUERY_USER_NICKS: + TlenMUCSendQuery(proto, 7, mucce->pszID, 0); + break; + case MUCC_EVENT_QUERY_USER_ROOMS: + TlenMUCSendQuery(proto, 8, mucce->pszID, 0); + break; + case MUCC_EVENT_QUERY_CONTACTS: + TlenMUCQueryContacts(proto, mucce->pszID); + break; + case MUCC_EVENT_JOIN: + if (proto->isOnline) { + if (mucce->pszID==NULL || strlen(mucce->pszID)==0) { + if (mucce->pszName==NULL || strlen(mucce->pszName)==0) { // create a new chat room + id = JabberSerialNext(proto); + JabberSend(proto, "

", id); + } else { // find a chat room by name + TlenMUCSendQuery(proto, 3, mucce->pszName, 0); + } + } else { // join existing chat room + if (!TlenMUCCreateWindow(proto, mucce->pszID, mucce->pszName, mucce->dwFlags, mucce->pszNick, NULL)) { + TlenMUCSendPresence(proto, mucce->pszID, mucce->pszNick, ID_STATUS_ONLINE); + } + } + } + break; + case MUCC_EVENT_START_PRIV: + if (proto->isOnline) { + JABBER_LIST_ITEM *item; + item = JabberListGetItemPtr(proto, LIST_CHATROOM, mucce->pszID); + if (item!=NULL) { + char *nick; + nick = JabberResourceFromJID(mucce->pszUID); + if (!isSelf(proto, mucce->pszID, nick)) { + if (nick[0]=='~' || item->nick!=NULL) { + char str[256]; + sprintf(str, "%s/%s", mucce->pszID, nick); + hContact = JabberDBCreateContact(proto, str, nick, TRUE); //(char *)mucce->pszUID + DBWriteContactSettingByte(hContact, proto->iface.m_szModuleName, "bChat", TRUE); + CallService(MS_MSG_SENDMESSAGE, (WPARAM) hContact, (LPARAM) NULL); + } else { + DBVARIANT dbv; + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { + char str[512]; + _snprintf(str, sizeof(str), "%s@%s", nick, dbv.pszVal); + DBFreeVariant(&dbv); + hContact = JabberDBCreateContact(proto, str, nick, TRUE); + CallService(MS_MSG_SENDMESSAGE, (WPARAM) hContact, (LPARAM) NULL); + } + } + } + mir_free(nick); + } + } + break; + } + } + return 0; +} + +int TlenMUCRecvInvitation(TlenProtocol *proto, const char *roomId, const char *roomName, const char *from, const char *reason) +{ + char *nick; + int ignore, ask, groupChatPolicy; + if (roomId == NULL) return 1; + groupChatPolicy = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "GroupChatPolicy", 0); + ask = TRUE; + ignore = FALSE; + if (groupChatPolicy == TLEN_MUC_ASK) { + ignore = FALSE; + ask = TRUE; + } else if (groupChatPolicy == TLEN_MUC_IGNORE_ALL) { + ignore = TRUE; + } else if (groupChatPolicy == TLEN_MUC_IGNORE_NIR) { + char jid[256]; + JABBER_LIST_ITEM *item; + DBVARIANT dbv; + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { + _snprintf(jid, sizeof(jid), "%s@%s", from, dbv.pszVal); + DBFreeVariant(&dbv); + } else { + strcpy(jid, from); + } + ignore = !IsAuthorized(proto, jid); + ask = TRUE; + } else if (groupChatPolicy == TLEN_MUC_ACCEPT_IR) { + char jid[256]; + JABBER_LIST_ITEM *item; + DBVARIANT dbv; + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { + _snprintf(jid, sizeof(jid), "%s@%s", from, dbv.pszVal); + DBFreeVariant(&dbv); + } else { + strcpy(jid, from); + } + item = JabberListGetItemPtr(proto, LIST_ROSTER, jid); + ask = !IsAuthorized(proto, jid); + ignore = FALSE; + } else if (groupChatPolicy == TLEN_MUC_ACCEPT_ALL) { + ask = FALSE; + ignore = FALSE; + } + if (!ignore) { + if (ask) { + MUCCEVENT mucce; + mucce.cbSize = sizeof(MUCCEVENT); + mucce.pszModule = proto->iface.m_szModuleName; + mucce.pszID = roomId; + mucce.pszName = roomName; + mucce.iType = MUCC_EVENT_INVITATION; + mucce.pszUID = from; + nick = getDisplayName(proto, from); + mucce.pszNick = nick; + mucce.pszText = reason; + CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); + mir_free(nick); + } else { + if (!TlenMUCCreateWindow(proto, roomId, roomName, 0, NULL, NULL)) { + TlenMUCSendPresence(proto, roomId, NULL, ID_STATUS_ONLINE); + } + } + } + return 0; +} + +int TlenMUCRecvPresence(TlenProtocol *proto, const char *from, int status, int flags, const char *kick) +{ + char str[512]; +// if (JabberListExist(LIST_CHATROOM, from)) { + char *nick, *roomId, *userId; + MUCCEVENT mucce; + roomId = JabberLoginFromJID(from); + userId = JabberResourceFromJID(from); + nick = getDisplayName(proto, userId); + mucce.cbSize = sizeof(MUCCEVENT); + mucce.pszModule = proto->iface.m_szModuleName; + mucce.pszID = roomId; + mucce.iType = MUCC_EVENT_STATUS; + mucce.pszUID = userId;//from; + mucce.pszNick = nick; + mucce.time = time(NULL); + mucce.bIsMe = isSelf(proto, roomId, userId); + mucce.dwData = status; + mucce.dwFlags = 0; + if (flags & USER_FLAGS_GLOBALOWNER) mucce.dwFlags |= MUCC_EF_USER_GLOBALOWNER; + if (flags & USER_FLAGS_OWNER) mucce.dwFlags |= MUCC_EF_USER_OWNER; + if (flags & USER_FLAGS_ADMIN) mucce.dwFlags |= MUCC_EF_USER_ADMIN; + if (flags & USER_FLAGS_REGISTERED) mucce.dwFlags |= MUCC_EF_USER_REGISTERED; + if (status == ID_STATUS_OFFLINE && mucce.bIsMe && kick!=NULL) { + mucce.iType = MUCC_EVENT_ERROR; + sprintf(str, Translate("You have been kicked. Reason: %s "), kick); + mucce.pszText = str; + } + CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); + mir_free(roomId); + mir_free(userId); + mir_free(nick); +// } + return 0; +} + +int TlenMUCRecvMessage(TlenProtocol *proto, const char *from, long timestamp, XmlNode *bodyNode) +{ +// if (JabberListExist(LIST_CHATROOM, from)) { + char *localMessage; + char *nick, *style, *roomId, *userId; + int iStyle; + MUCCEVENT mucce; + roomId = JabberLoginFromJID(from); + userId = JabberResourceFromJID(from); + nick = getDisplayName(proto, userId); + localMessage = JabberTextDecode(bodyNode->text); + mucce.cbSize = sizeof(MUCCEVENT); + mucce.iType = MUCC_EVENT_MESSAGE; + mucce.pszID = roomId; + mucce.pszModule = proto->iface.m_szModuleName; + mucce.pszText = localMessage; + mucce.pszUID = userId;//from; + mucce.pszNick = nick; + mucce.time = timestamp; + mucce.bIsMe = isSelf(proto, roomId, userId); + mucce.dwFlags = 0; + mucce.iFontSize = 0; + style = JabberXmlGetAttrValue(bodyNode, "f"); + if (style!=NULL) { + iStyle = atoi(style); + if (iStyle & 1) mucce.dwFlags |= MUCC_EF_FONT_BOLD; + if (iStyle & 2) mucce.dwFlags |= MUCC_EF_FONT_ITALIC; + if (iStyle & 4) mucce.dwFlags |= MUCC_EF_FONT_UNDERLINE; + } + style = JabberXmlGetAttrValue(bodyNode, "c"); + if (style!=NULL && strlen(style)>5) { + iStyle = (stringToHex(style)<<16) | (stringToHex(style+2)<<8) | stringToHex(style+4); + } else { + iStyle = 0xFFFFFFFF; + } + mucce.color = (COLORREF) iStyle; + style = JabberXmlGetAttrValue(bodyNode, "s"); + if (style!=NULL) { + iStyle = atoi(style); + } else { + iStyle = 0; + } + mucce.iFontSize = iStyle; + style = JabberXmlGetAttrValue(bodyNode, "n"); + if (style!=NULL) { + iStyle = atoi(style)-1; + } else { + iStyle = 0; + } + mucce.iFont = iStyle; + CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); + mir_free(roomId); + mir_free(userId); + mir_free(nick); + mir_free(localMessage); +// } + return 0; +} +int TlenMUCRecvTopic(TlenProtocol *proto, const char *from, const char *subject) +{ +// if (JabberListExist(LIST_CHATROOM, from)) { + MUCCEVENT mucce; + mucce.cbSize = sizeof(MUCCEVENT); + mucce.iType = MUCC_EVENT_TOPIC; + mucce.pszID = from; + mucce.pszModule = proto->iface.m_szModuleName; + mucce.pszText = subject; + mucce.time = time(NULL); + CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); +// } + return 0; +} + +int TlenMUCRecvError(TlenProtocol *proto, const char *from, XmlNode *errorNode) +{ + int errCode; + char str[512]; + JABBER_LIST_ITEM *item; + MUCCEVENT mucce; + mucce.cbSize = sizeof(MUCCEVENT); + mucce.iType = MUCC_EVENT_ERROR; + mucce.pszID = from; + mucce.pszModule = proto->iface.m_szModuleName; + errCode = atoi(JabberXmlGetAttrValue(errorNode, "code")); + switch (errCode) { + case 403: + sprintf(str, Translate("You cannot join this chat room, because you are banned.")); + break; + case 404: + sprintf(str, Translate("Chat room not found.")); + break; + case 407: + sprintf(str, Translate("This is a private chat room and you are not one of the members.")); + break; + case 408: + sprintf(str, Translate("You cannot send any message unless you join this chat room.")); + break; + case 410: + sprintf(str, Translate("Chat room with already created.")); + break; + case 411: + sprintf(str, Translate("Nickname '%s' is already registered."), + JabberXmlGetAttrValue(errorNode, "n")); + break; + case 412: + sprintf(str, Translate("Nickname already in use, please try another one. Hint: '%s' is free."), + JabberXmlGetAttrValue(errorNode, "free")); + break; + case 413: + sprintf(str, Translate("You cannot register more than %s nicknames."), + JabberXmlGetAttrValue(errorNode, "num")); + break; + case 414: + sprintf(str, Translate("You cannot create more than %s chat rooms."), + JabberXmlGetAttrValue(errorNode, "num")); + break; + case 415: + sprintf(str, Translate("You cannot join more than %s chat rooms."), + JabberXmlGetAttrValue(errorNode, "num")); + break; + case 601: + sprintf(str, Translate("Anonymous nicknames are not allowed in this chat room.")); + break; + default: + sprintf(str, Translate("Unknown error code : %d"), errCode); + break; + } + mucce.pszText = str; + CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); + if (proto->isOnline) { + switch (errCode) { + case 412: + item = JabberListGetItemPtr(proto, LIST_CHATROOM, from); + if (item!=NULL) { + mucce.iType = MUCC_EVENT_JOIN; + mucce.dwFlags = MUCC_EF_ROOM_NICKNAMES; + mucce.pszModule = proto->iface.m_szModuleName; + mucce.pszID = from; + mucce.pszName = item->roomName; + mucce.pszNick = JabberXmlGetAttrValue(errorNode, "free"); + CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); + } + break; + case 601: + item = JabberListGetItemPtr(proto, LIST_CHATROOM, from); + if (item!=NULL) { + mucce.iType = MUCC_EVENT_JOIN; + mucce.dwFlags = 0; + mucce.pszModule = proto->iface.m_szModuleName; + mucce.pszID = from; + mucce.pszName = item->roomName; + mucce.pszNick = NULL; + CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); + } + break; + } + } + return 1; +} +static int TlenMUCSendInvitation(TlenProtocol *proto, const char *roomID, const char *user) +{ + if (!proto->isOnline) { + return 1; + } + JabberSend(proto, "", roomID, user); + return 0; +} + +static int TlenMUCSendPresence(TlenProtocol *proto, const char *roomID, const char *nick, int desiredStatus) +{ + char str[512]; + char *jid; + JABBER_LIST_ITEM *item; + if (!proto->isOnline) { + return 1; + } + if (nick!=NULL) { + _snprintf(str, sizeof(str), "%s/%s", roomID, nick); + } else { + _snprintf(str, sizeof(str), "%s", roomID); + } + if ((jid = JabberTextEncode(str))!=NULL) { + switch (desiredStatus) { + case ID_STATUS_ONLINE: + JabberSend(proto, "

", jid); + item = JabberListGetItemPtr(proto, LIST_CHATROOM, roomID); + if (item!=NULL) { + if (item->nick!=NULL) mir_free(item->nick); + item->nick = NULL; + if (nick!=NULL) { + item->nick = mir_strdup(nick); + } + } + break; + default: + item = JabberListGetItemPtr(proto, LIST_CHATROOM, roomID); + if (item!=NULL) { + JabberSend(proto, "

unavailable

", jid); + JabberListRemove(proto, LIST_CHATROOM, roomID); + } + break; + } + mir_free(jid); + } + return 0; +} + +static int TlenMUCSendMessage(TlenProtocol *proto, MUCCEVENT *event) +{ + char *msg, *jid; + int style; + + if (!proto->isOnline) { + return 1; + } + if ((msg = JabberTextEncode(event->pszText))!=NULL) { + if ((jid = JabberTextEncode(event->pszID))!=NULL) { + style = 0; + if (event->dwFlags & MUCC_EF_FONT_BOLD) style |=1; + if (event->dwFlags & MUCC_EF_FONT_ITALIC) style |=2; + if (event->dwFlags & MUCC_EF_FONT_UNDERLINE) style |=4; + JabberSend(proto, "%s", jid, event->iFont+1, event->iFontSize, style, event->color, msg); + mir_free(jid); + } + mir_free(msg); + } + return 0; +} + +static int TlenMUCSendTopic(TlenProtocol *proto, MUCCEVENT *event) +{ + char *msg, *jid; + if (!proto->isOnline) { + return 1; + } + if ((msg = JabberTextEncode(event->pszText))!=NULL) { + if ((jid = JabberTextEncode(event->pszID))!=NULL) { + JabberSend(proto, "%s", jid, msg); + mir_free(jid); + } + mir_free(msg); + } + return 0; +} + +static int TlenMUCSendQuery(TlenProtocol *proto, int type, const char *parent, int page) +{ + if (!proto->isOnline) { + return 1; + } + if (type==3) { // find chat room by name + char serialId[32]; + JABBER_LIST_ITEM *item; + sprintf(serialId, JABBER_IQID"%d", JabberSerialNext(proto)); + item = JabberListAdd(proto, LIST_SEARCH, serialId); + item->roomName = mir_strdup(parent); + JabberSend(proto, "", parent, serialId); + } else { + if (parent==NULL) { + JabberSend(proto, "", type); + } else { // 1 - groups, 2 - chat rooms, 7 - user nicks, 8 - user rooms + if (type==1 || (type==2 && page==0) || type==7 || type==8) { + JabberSend(proto, "", type, parent); + } else if (type==2) { + JabberSend(proto, "", type, parent, page); + } else if (type==6) { + if (page) { + JabberSend(proto, "", type, parent); + } else { + JabberSend(proto, "", type, parent); + } + } else if (type==4) { // list of users, admins etc. + JabberSend(proto, "", parent, type, page); + } + } + } + return 0; +} + +int TlenMUCCreateWindow(TlenProtocol *proto, const char *roomID, const char *roomName, int roomFlags, const char *nick, const char *iqId) +{ + JABBER_LIST_ITEM *item; + MUCCWINDOW mucw; + if (!proto->isOnline || roomID==NULL) { + return 1; + } + if (JabberListExist(proto, LIST_CHATROOM, roomID)) { + return 0; + } + item = JabberListAdd(proto, LIST_CHATROOM, roomID); + if (roomName!=NULL) { + item->roomName = mir_strdup(roomName); + } + if (nick!=NULL) { + item->nick = mir_strdup(nick); + } + mucw.cbSize = sizeof(MUCCWINDOW); + mucw.iType = MUCC_WINDOW_CHATROOM; + mucw.pszModule = proto->iface.m_szModuleName; + mucw.pszModuleName = proto->iface.m_szProtoName; + mucw.pszID = roomID; + mucw.pszName = roomName; + mucw.pszNick = nick; + mucw.dwFlags = roomFlags; + mucw.pszStatusbarText = "hello"; + CallService(MS_MUCC_NEW_WINDOW, 0, (LPARAM) &mucw); + if (iqId != NULL) { + item = JabberListGetItemPtr(proto, LIST_INVITATIONS, iqId); + if (item !=NULL) { + TlenMUCSendInvitation(proto, roomID, item->nick); + } + JabberListRemove(proto, LIST_INVITATIONS, iqId); + } + return 0; +} + +static void TlenMUCFreeQueryResult(MUCCQUERYRESULT *result) +{ int i; + for (i=0; iiItemsNum; i++) { + if (result->pItems[i].pszID != NULL) { + mir_free((char *) result->pItems[i].pszID); + } + if (result->pItems[i].pszName != NULL) { + mir_free((char *) result->pItems[i].pszName); + } + if (result->pItems[i].pszNick != NULL) { + mir_free((char *) result->pItems[i].pszNick); + } + if (result->pItems[i].pszText != NULL) { + mir_free((char *) result->pItems[i].pszText); + } + } + mir_free((MUCCQUERYITEM *)result->pItems); +} + +void TlenIqResultChatGroups(TlenProtocol *proto, XmlNode *iqNode) +{ + XmlNode *lNode, *itemNode; + char *p, *n, *id, *f; + int i, j; + MUCCQUERYRESULT queryResult; + + if ((lNode=JabberXmlGetChild(iqNode, "l")) == NULL) return; + p = JabberXmlGetAttrValue(iqNode, "p"); + if (p==NULL) { + p=""; + } + p = JabberTextDecode(p); + queryResult.cbSize = sizeof (MUCCQUERYRESULT); + queryResult.iType = MUCC_EVENT_QUERY_GROUPS; + queryResult.pszModule = proto->iface.m_szModuleName; + queryResult.pszParent = p; + queryResult.pItems = mir_alloc(sizeof(MUCCQUERYITEM) * lNode->numChild); + memset(queryResult.pItems, 0, sizeof(MUCCQUERYITEM) * lNode->numChild); + for (i=j=0; inumChild; i++) { + itemNode = lNode->child[i]; + if (!strcmp(itemNode->name, "i")) { + queryResult.pItems[j].iCount = 0; + if ((f = JabberXmlGetAttrValue(itemNode, "f")) != NULL) { + queryResult.pItems[j].iCount = !strcmp(f, "3"); + } + n = JabberXmlGetAttrValue(itemNode, "n"); + id = JabberXmlGetAttrValue(itemNode, "i"); + if (n != NULL && id != NULL) { + queryResult.pItems[j].pszID = JabberTextDecode(id); + queryResult.pItems[j].pszName = JabberTextDecode(n); + j++; + } + } + } + queryResult.iItemsNum = j; + CallService(MS_MUCC_QUERY_RESULT, 0, (LPARAM) &queryResult); + TlenMUCFreeQueryResult(&queryResult); + mir_free(p); +} + +void TlenIqResultChatRooms(TlenProtocol *proto, XmlNode *iqNode) +{ + XmlNode *lNode, *itemNode; + char *id, *c, *n, *x, *p, *px, *pn; + int i, j; + MUCCQUERYRESULT queryResult; + + if ((lNode=JabberXmlGetChild(iqNode, "l")) == NULL) return; + if ((p = JabberXmlGetAttrValue(iqNode, "p")) == NULL) return; + pn = JabberXmlGetAttrValue(lNode, "n"); + if (pn == NULL) pn = "0"; + px = JabberXmlGetAttrValue(lNode, "x"); + if (px == NULL) px = "0"; + p = JabberTextDecode(p); + queryResult.cbSize = sizeof (MUCCQUERYRESULT); + queryResult.iType = MUCC_EVENT_QUERY_ROOMS; + queryResult.pszModule = proto->iface.m_szModuleName; + queryResult.pszParent = p; + queryResult.pItems = mir_alloc(sizeof(MUCCQUERYITEM) * lNode->numChild); + memset(queryResult.pItems, 0, sizeof(MUCCQUERYITEM) * lNode->numChild); + queryResult.iPage = atoi(pn); + queryResult.iLastPage = atoi(px)&2?1:0; + for (i=j=0; inumChild; i++) { + itemNode = lNode->child[i]; + if (!strcmp(itemNode->name, "i")) { + n = JabberXmlGetAttrValue(itemNode, "n"); + c = JabberXmlGetAttrValue(itemNode, "c"); + x = JabberXmlGetAttrValue(itemNode, "x"); + if ((id=JabberXmlGetAttrValue(itemNode, "i")) != NULL) { + queryResult.pItems[j].pszID = JabberTextDecode(id); + queryResult.pItems[j].pszName = JabberTextDecode(n); + queryResult.pItems[j].iCount = atoi(c); + queryResult.pItems[j].dwFlags = atoi(x); + j++; + } + } + } + queryResult.iItemsNum = j; + CallService(MS_MUCC_QUERY_RESULT, 0, (LPARAM) &queryResult); + TlenMUCFreeQueryResult(&queryResult); + mir_free(p); +} +void TlenIqResultUserRooms(TlenProtocol *proto, XmlNode *iqNode) +{ + XmlNode *lNode, *itemNode; + char *id, *n; + int i, j; + MUCCQUERYRESULT queryResult; + if ((lNode=JabberXmlGetChild(iqNode, "l")) == NULL) return; + queryResult.cbSize = sizeof (MUCCQUERYRESULT); + queryResult.iType = MUCC_EVENT_QUERY_USER_ROOMS; + queryResult.pszModule = proto->iface.m_szModuleName; + queryResult.pItems = mir_alloc(sizeof(MUCCQUERYITEM) * lNode->numChild); + memset(queryResult.pItems, 0, sizeof(MUCCQUERYITEM) * lNode->numChild); + for (i=j=0; inumChild; i++) { + itemNode = lNode->child[i]; + if (!strcmp(itemNode->name, "i")) { + n = JabberXmlGetAttrValue(itemNode, "n"); + id = JabberXmlGetAttrValue(itemNode, "i"); + if (n != NULL && id != NULL) { + queryResult.pItems[j].pszID = JabberTextDecode(id); + queryResult.pItems[j].pszName = JabberTextDecode(n); + j++; + } + } + } + queryResult.iItemsNum = j; + CallService(MS_MUCC_QUERY_RESULT, 0, (LPARAM) &queryResult); + TlenMUCFreeQueryResult(&queryResult); +} +void TlenIqResultUserNicks(TlenProtocol *proto, XmlNode *iqNode) +{ + XmlNode *lNode, *itemNode; + char *n; + int i, j; + MUCCQUERYRESULT queryResult; + if ((lNode=JabberXmlGetChild(iqNode, "l")) == NULL) return; + queryResult.cbSize = sizeof (MUCCQUERYRESULT); + queryResult.iType = MUCC_EVENT_QUERY_USER_NICKS; + queryResult.pszModule = proto->iface.m_szModuleName; + queryResult.pItems = mir_alloc(sizeof(MUCCQUERYITEM) * lNode->numChild); + memset(queryResult.pItems, 0, sizeof(MUCCQUERYITEM) * lNode->numChild); + for (i=j=0; inumChild; i++) { + itemNode = lNode->child[i]; + if (!strcmp(itemNode->name, "i")) { + n = JabberXmlGetAttrValue(itemNode, "n"); + queryResult.pItems[j].pszID = NULL;//JabberTextDecode(n); + queryResult.pItems[j].pszName = JabberTextDecode(n); + j++; + } + } + queryResult.iItemsNum = j; + CallService(MS_MUCC_QUERY_RESULT, 0, (LPARAM) &queryResult); + TlenMUCFreeQueryResult(&queryResult); +} +void TlenIqResultChatRoomUsers(TlenProtocol *proto, XmlNode *iqNode) +{ + XmlNode *lNode, *itemNode; + char *id, *n; + int i, j; + MUCCQUERYRESULT queryResult; + if ((lNode=JabberXmlGetChild(iqNode, "l")) == NULL) return; + if ((id=JabberXmlGetAttrValue(iqNode, "from")) == NULL) return; + queryResult.cbSize = sizeof (MUCCQUERYRESULT); + queryResult.iType = MUCC_EVENT_QUERY_USERS; + queryResult.pszModule = proto->iface.m_szModuleName; + queryResult.pszParent = id; + queryResult.pItems = mir_alloc(sizeof(MUCCQUERYITEM) * lNode->numChild); + memset(queryResult.pItems, 0, sizeof(MUCCQUERYITEM) * lNode->numChild); + for (i=j=0; inumChild; i++) { + itemNode = lNode->child[i]; + if (!strcmp(itemNode->name, "i")) { + id = JabberXmlGetAttrValue(itemNode, "i"); + if (id != NULL) { + queryResult.pItems[j].pszID = JabberTextDecode(id); + n = JabberXmlGetAttrValue(itemNode, "n"); + if (n!=NULL) { + queryResult.pItems[j].pszName = JabberTextDecode(n); + } + n = JabberXmlGetAttrValue(itemNode, "a"); + if (n!=NULL) { + queryResult.pItems[j].pszNick = JabberTextDecode(n); + } + n = JabberXmlGetAttrValue(itemNode, "r"); + if (n!=NULL) { + queryResult.pItems[j].pszText = JabberTextDecode(n); + } + n = JabberXmlGetAttrValue(itemNode, "e"); + if (n!=NULL) { + queryResult.pItems[j].iCount = atoi(n); + } + n = JabberXmlGetAttrValue(itemNode, "s"); + if (n!=NULL) { + queryResult.pItems[j].dwFlags = atoi(n); + } + j++; + } + } + } + queryResult.iItemsNum = j; + CallService(MS_MUCC_QUERY_RESULT, 0, (LPARAM) &queryResult); + TlenMUCFreeQueryResult(&queryResult); +} + +void TlenIqResultRoomSearch(TlenProtocol *proto, XmlNode *iqNode) +{ + char *iqId, *id; + JABBER_LIST_ITEM *item; + iqId=JabberXmlGetAttrValue(iqNode, "id"); + item=JabberListGetItemPtr(proto, LIST_SEARCH, iqId); + if ((id=JabberXmlGetAttrValue(iqNode, "i")) != NULL) { + MUCCEVENT mucce; + id = JabberTextDecode(id); + mucce.cbSize = sizeof(MUCCEVENT); + mucce.iType = MUCC_EVENT_JOIN; + mucce.pszModule = proto->iface.m_szModuleName; + mucce.pszID = id; + mucce.pszName = id; + if (item!=NULL) { + mucce.pszName = item->roomName; + } + mucce.pszNick = NULL; + mucce.dwFlags = MUCC_EF_ROOM_NICKNAMES; + CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); + mir_free(id); + } + JabberListRemove(proto, LIST_SEARCH, iqId); +} + +void TlenIqResultRoomInfo(TlenProtocol *proto, XmlNode *iqNode) +{ + char *id, *name, *group, *flags; + if ((id=JabberXmlGetAttrValue(iqNode, "from")) != NULL) { + if ((name=JabberXmlGetAttrValue(iqNode, "n")) != NULL) { + MUCCEVENT mucce; + group = JabberXmlGetAttrValue(iqNode, "cn"); + flags = JabberXmlGetAttrValue(iqNode, "x"); + id = JabberTextDecode(id); + name = JabberTextDecode(name); + mucce.cbSize = sizeof(MUCCEVENT); + mucce.iType = MUCC_EVENT_ROOM_INFO; + mucce.pszModule = proto->iface.m_szModuleName; + mucce.pszID = id; + mucce.pszName = name; + mucce.dwFlags = atoi(flags); + CallService(MS_MUCC_EVENT, 0, (LPARAM) &mucce); + mir_free(id); + mir_free(name); + } + } +} + + +typedef struct { + TlenProtocol *proto; + char *roomId; +} MUCSENDQUERYTHREADDATA; + +static void __cdecl TlenMUCCSendQueryResultThread(void *ptr) +{ + HANDLE hContact; + MUCCQUERYRESULT queryResult; + DBVARIANT dbv; + MUCSENDQUERYTHREADDATA* threadData = (MUCSENDQUERYTHREADDATA*)ptr; + queryResult.cbSize = sizeof (MUCCQUERYRESULT); + queryResult.iType = MUCC_EVENT_QUERY_CONTACTS; + queryResult.pszModule = threadData->proto->iface.m_szModuleName; + queryResult.pszParent = threadData->roomId; + queryResult.iItemsNum = 0; + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact != NULL) { + char *str = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if(str!=NULL && !strcmp(str, threadData->proto->iface.m_szModuleName)) { + if (!DBGetContactSettingByte(hContact, threadData->proto->iface.m_szModuleName, "bChat", FALSE)) { + if (!DBGetContactSetting(hContact, threadData->proto->iface.m_szModuleName, "jid", &dbv)) { + if (strcmp(dbv.pszVal, "b73@tlen.pl")) { + queryResult.iItemsNum++; + } + DBFreeVariant(&dbv); + } + } + } + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); + } + queryResult.pItems = mir_alloc(sizeof(MUCCQUERYITEM) * queryResult.iItemsNum); + memset(queryResult.pItems, 0, sizeof(MUCCQUERYITEM) * queryResult.iItemsNum); + queryResult.iItemsNum = 0; + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact != NULL) { + char *baseProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if(baseProto!=NULL && !strcmp(baseProto, threadData->proto->iface.m_szModuleName)) { + if (!DBGetContactSettingByte(hContact, threadData->proto->iface.m_szModuleName, "bChat", FALSE)) { + if (!DBGetContactSetting(hContact, threadData->proto->iface.m_szModuleName, "jid", &dbv)) { + if (strcmp(dbv.pszVal, "b73@tlen.pl")) { + queryResult.pItems[queryResult.iItemsNum].pszID = mir_strdup(dbv.pszVal); + queryResult.pItems[queryResult.iItemsNum].pszName = mir_strdup((char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, 0)); + queryResult.iItemsNum++; + } + DBFreeVariant(&dbv); + } + } + } + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); + } + CallService(MS_MUCC_QUERY_RESULT, 0, (LPARAM) &queryResult); + TlenMUCFreeQueryResult(&queryResult); + mir_free(threadData->roomId); + mir_free(threadData); +} + + +static int TlenMUCQueryContacts(TlenProtocol *proto, const char *roomId) { + + MUCSENDQUERYTHREADDATA *threadData = (MUCSENDQUERYTHREADDATA *)mir_alloc(sizeof(MUCSENDQUERYTHREADDATA)); + threadData->proto = proto; + threadData->roomId = mir_strdup(roomId); + JabberForkThread(TlenMUCCSendQueryResultThread, 0, (void *)threadData); + return 1; +} + + +INT_PTR TlenMUCMenuHandleMUC(void *ptr, WPARAM wParam, LPARAM lParam) +{ + TlenProtocol *proto = (TlenProtocol *)ptr; + if (!proto->isOnline) { + return 1; + } + JabberSend(proto, "

", JabberSerialNext(proto)); + /* + MUCCEVENT *mucce; + mucce = (MUCCEVENT *) mir_alloc (sizeof(MUCCEVENT)); + mucce->cbSize = sizeof(MUCCEVENT); + mucce->iType = MUCC_EVENT_JOIN; + mucce->dwFlags = 0; + mucce->pszModule = iface.m_szModuleName; + mucce->pszID = NULL; + mucce->pszName = NULL; + mucce->pszNick = NULL; + CallService(MS_MUCC_EVENT, 0, (LPARAM) mucce); + mir_free(mucce); + */ + return 0; +} + +INT_PTR TlenMUCMenuHandleChats(void *ptr, WPARAM wParam, LPARAM lParam) +{ + MUCCWINDOW mucw; + TlenProtocol *proto = (TlenProtocol *)ptr; + if (!proto->isOnline) { + return 1; + } + mucw.cbSize = sizeof(MUCCWINDOW); + mucw.iType = MUCC_WINDOW_CHATLIST; + mucw.pszModule = proto->iface.m_szModuleName; + mucw.pszModuleName = proto->iface.m_szProtoName; + CallService(MS_MUCC_NEW_WINDOW, 0, (LPARAM) &mucw); + return 0; +} + +INT_PTR TlenMUCContactMenuHandleMUC(void *ptr, WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact; + DBVARIANT dbv; + JABBER_LIST_ITEM *item; + TlenProtocol *proto = (TlenProtocol *)ptr; + if (!proto->isOnline) { + return 1; + } + if ((hContact=(HANDLE) wParam)!=NULL && proto->isOnline) { + if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { + char serialId[32]; + sprintf(serialId, JABBER_IQID"%d", JabberSerialNext(proto)); + item = JabberListAdd(proto, LIST_INVITATIONS, serialId); + item->nick = mir_strdup(dbv.pszVal); + JabberSend(proto, "

", serialId); + DBFreeVariant(&dbv); + } + } + return 0; +} diff --git a/plugins/!NotAdopted/Tlen/tlen_muc.h b/plugins/!NotAdopted/Tlen/tlen_muc.h new file mode 100644 index 0000000000..fc1713a837 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_muc.h @@ -0,0 +1,45 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef _TLEN_MUC_H_ +#define _TLEN_MUC_H_ + +#include +#include "m_mucc.h" + +#define USER_FLAGS_OWNER 0x01 +#define USER_FLAGS_ADMIN 0x02 +#define USER_FLAGS_REGISTERED 0x04 +#define USER_FLAGS_GLOBALOWNER 0x08 +#define USER_FLAGS_KICKED 0x80 + +extern BOOL TlenMUCInit(TlenProtocol *proto); +extern INT_PTR TlenMUCMenuHandleMUC(void *ptr, WPARAM wParam, LPARAM lParam); +extern INT_PTR TlenMUCMenuHandleChats(void *ptr, WPARAM wParam, LPARAM lParam); +extern INT_PTR TlenMUCContactMenuHandleMUC(void *ptr, WPARAM wParam, LPARAM lParam); +extern int TlenMUCCreateWindow(TlenProtocol *proto, const char *roomID, const char *roomName, int roomFlags, const char *nick, const char *iqId); +extern int TlenMUCRecvInvitation(TlenProtocol *proto, const char *roomJid, const char *roomName, const char *from, const char *reason); +extern int TlenMUCRecvPresence(TlenProtocol *proto, const char *from, int status, int flags, const char *kick); +extern int TlenMUCRecvMessage(TlenProtocol *proto, const char *from, long timestamp, XmlNode *bodyNode); +extern int TlenMUCRecvTopic(TlenProtocol *proto, const char *from, const char *subject); +extern int TlenMUCRecvError(TlenProtocol *proto, const char *from, XmlNode *errorNode); + +#endif diff --git a/plugins/!NotAdopted/Tlen/tlen_p2p_new.c b/plugins/!NotAdopted/Tlen/tlen_p2p_new.c new file mode 100644 index 0000000000..7d9c959a42 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_p2p_new.c @@ -0,0 +1,361 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" +#include +#include +#include +#include +#include "jabber_list.h" +#include "tlen_p2p_old.h" + + +static void logInfo(const char *filename, const char *fmt, ...) { + SYSTEMTIME time; + char *str; + va_list vararg; + int strsize; + FILE *flog=fopen(filename,"at"); + if (flog!=NULL) { + GetLocalTime(&time); + va_start(vararg, fmt); + str = (char *) mir_alloc(strsize=2048); + while (_vsnprintf(str, strsize, fmt, vararg) == -1) + str = (char *) realloc(str, strsize+=2048); + va_end(vararg); + fprintf(flog,"%04d-%02d-%02d %02d:%02d:%02d,%03d [%s]",time.wYear,time.wMonth,time.wDay,time.wHour,time.wMinute,time.wSecond,time.wMilliseconds, "INFO"); + fprintf(flog," %s\n",str); + mir_free(str); + fclose(flog); + } +} + +void __cdecl TlenNewFileReceiveThread(TLEN_FILE_TRANSFER *ft) +{ + JabberLog(ft->proto, "P2P receive thread started"); + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, ft, 0); +// ft->mode = FT_RECV; +// ft->currentFile = 0; +// ft->state = FT_CONNECTING; + { + FILE * fout = fopen("tlen_recv.dxx", "wt"); + SOCKADDR_IN toad; + toad.sin_family = AF_INET; + toad.sin_addr.s_addr = inet_addr(ft->hostName); + toad.sin_port = htons(ft->wPort); + if (fout != NULL) { + fprintf(fout, "START:\n"); + } + if (fout != NULL) { + fclose(fout); + } + while (ft->udps != INVALID_SOCKET) { + SOCKADDR_IN cad; + int alen; + int j, n; + unsigned char buff[1024]; + alen = sizeof(struct sockaddr); + n=recvfrom(ft->udps, (char*)buff,sizeof(buff),0, (struct sockaddr *) &cad, &alen); + if (n<0) { + break; + } + logInfo("tlen_recv.dxx", "UDP"); + fout = fopen("tlen_recv.dxx", "at"); + if (fout != NULL) { + fprintf(fout, "\n|RECV %d bytes from %s:%d|",n, inet_ntoa(cad.sin_addr), cad.sin_port); + for (j = 0; j < n; j++) { + fprintf(fout, "%02X-", buff[j]); + } + } + if (n == 1) { + alen = sizeof(struct sockaddr); + n = sendto(ft->udps, (char*)buff, n, 0,(struct sockaddr *) &toad, alen); + if (fout != NULL) { + fprintf(fout, "\n|SEND |"); + for (j = 0; j < n; j++) { + fprintf(fout, "%02X-", buff[j]); + } + } + } + if (fout != NULL) { + fprintf(fout, "\n"); + fclose(fout); + } + } + } + if (ft->udps != INVALID_SOCKET) { + closesocket(ft->udps); + } + + JabberListRemove(ft->proto, LIST_FILE, ft->iqId); + if (ft->state==FT_DONE) + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); + else { + ProtoBroadcastAck(ft->proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); + } + JabberLog(ft->proto, "P2P receive thread ended"); + TlenP2PFreeFileTransfer(ft); +} + +void __cdecl TlenNewFileSendThread(TLEN_FILE_TRANSFER *ft) +{ + JabberLog(ft->proto, "P2P send thread started"); +// ft->mode = FT_RECV; +// ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, ft, 0); +// ft->currentFile = 0; +// ft->state = FT_CONNECTING; + { + FILE * fout = fopen("tlen_send.gxx", "wt"); + int step = 0; + SOCKADDR_IN toad; + toad.sin_family = AF_INET; + toad.sin_addr.s_addr = inet_addr(ft->hostName); + toad.sin_port = htons(ft->wPort); + + if (fout != NULL) { + fprintf(fout, "START:"); + } + if (fout != NULL) { + fclose(fout); + } + for (step = 0; step < 10; step ++) { +// while (ft->udps != INVALID_SOCKET) { + int alen; + int j, n; + unsigned char buff[1024]; + alen = sizeof(struct sockaddr); + if (step < 3 || step > 5) { + buff[0] = 1; + n = 1; + } else { + buff[0] = '$'; + buff[1] = '^'; + buff[2] = '&'; + buff[3] = '%'; + n = 4; + } + n=sendto(ft->udps, (char*)buff, n, 0, (struct sockaddr *)&toad, alen); + logInfo("tlen_send.dxx", "UDP"); + if (fout != NULL) { + fprintf(fout, "|send: %d %s %d|",n, inet_ntoa(toad.sin_addr), toad.sin_port); + for (j = 0; j < n; j++) { + fprintf(fout, "%02X-", buff[j]); + } + } + if (fout != NULL) { + fprintf(fout, "\n"); + fclose(fout); + } + SleepEx(1000, TRUE); + } + } + JabberLog(ft->proto, "P2P send thread ended"); +} + +void TlenBindUDPSocket(TLEN_FILE_TRANSFER *ft) +{ + JabberLog(ft->proto, "Binding UDP socket"); + ft->udps = socket(PF_INET, SOCK_DGRAM, 0); + if (ft->udps != INVALID_SOCKET) { + SOCKADDR_IN sin; + int len = sizeof(struct sockaddr); + memset((char *)&sin,0,sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_ANY);; + sin.sin_port = 0; + if (bind(ft->udps, (struct sockaddr *)&sin, sizeof(sin)) >= 0) { + if(!getsockname((SOCKET)ft->udps,(SOCKADDR *)&sin,&len)) { + struct hostent *hp; + char host_name[256]; + gethostname(host_name, sizeof(host_name)); + hp = gethostbyname(host_name); + mir_snprintf(host_name, sizeof(host_name), "%u.%u.%u.%u", (unsigned char)hp->h_addr_list[0][0], + (unsigned char)hp->h_addr_list[0][1], + (unsigned char)hp->h_addr_list[0][2], + (unsigned char)hp->h_addr_list[0][3]); + + ft->wLocalPort = ntohs(sin.sin_port); + ft->localName= mir_strdup(host_name); + JabberLog(ft->proto, "UDP socket bound to %s:%d", ft->localName, ft->wLocalPort); + } + } + } +} + + +/* +aaa sends a file to bbb: + +1) aaa wants to SEND bbb a file +A SEND: +B RECV: + +2) bbb ACCEPTs +B SEND: +A RECV: + +3) aaa tries to establish p2p connection: +A SEND: +B SEND: + +3) bbb sends IP/port details +B SEND: + +*/ + +void TlenProcessP2P(XmlNode *node, ThreadData *info) { + XmlNode *queryNode; + JABBER_LIST_ITEM *item; + char *from; + + if (info == NULL) return; + + queryNode = JabberXmlGetChild(node, "query"); + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + XmlNode *fs , *vs, *dcng, *dc; + /* file send */ + fs = JabberXmlGetChild(queryNode, "fs"); + /* voice send */ + vs = JabberXmlGetChild(queryNode, "vs"); + dcng = JabberXmlGetChild(queryNode, "dcng"); + dc = JabberXmlGetChild(queryNode, "dc"); + if (fs != NULL) { + char *e, *id; + /* e - step in the process (starting with 1)*/ + /* i - id of the file */ + /* s - size of the file */ + /* c - number of files */ + /* v - ??? */ + e = JabberXmlGetAttrValue(fs, "e"); + id = JabberXmlGetAttrValue(fs, "i"); + if (e != NULL) { + if (!strcmp(e, "1")) { + CCSDATA ccs; + PROTORECVEVENT pre; + char *c, *s; + TLEN_FILE_TRANSFER * ft = (TLEN_FILE_TRANSFER *) mir_alloc(sizeof(TLEN_FILE_TRANSFER)); + memset(ft, 0, sizeof(TLEN_FILE_TRANSFER)); + c = JabberXmlGetAttrValue(fs, "c"); + s = JabberXmlGetAttrValue(fs, "s"); + ft->jid = mir_strdup(from); + ft->proto = info->proto; + ft->hContact = JabberHContactFromJID(info->proto, from); + ft->iqId = mir_strdup(id); + ft->fileTotalSize = atoi(s); + ft->newP2P = TRUE; + if ((item=JabberListAdd(ft->proto, LIST_FILE, ft->iqId)) != NULL) { + char *szBlob; + char fileInfo[128]; + item->ft = ft; + mir_snprintf(fileInfo, sizeof(fileInfo), "%s file(s), %s bytes", c, s); + // blob is DWORD(*ft), ASCIIZ(filenames), ASCIIZ(description) + szBlob = (char *) mir_alloc(sizeof(DWORD) + strlen(fileInfo) + 2); + *((PDWORD) szBlob) = (DWORD) ft; + strcpy(szBlob + sizeof(DWORD), fileInfo); + szBlob[sizeof(DWORD) + strlen(fileInfo) + 1] = '\0'; + pre.flags = 0; + pre.timestamp = time(NULL); + pre.szMessage = szBlob; + pre.lParam = 0; + ccs.szProtoService = PSR_FILE; + ccs.hContact = ft->hContact; + ccs.wParam = 0; + ccs.lParam = (LPARAM) ⪯ + JabberLog(ft->proto, "sending chainrecv"); + CallService(MS_PROTO_CHAINRECV, 0, (LPARAM) &ccs); + mir_free(szBlob); + } + } else if (!strcmp(e, "3")) { + /* transfer error */ + } else if (!strcmp(e, "4")) { + /* transfer denied */ + } else if (!strcmp(e, "5")) { + /* transfer accepted */ + if ((item=JabberListGetItemPtr(info->proto, LIST_FILE, id)) != NULL) { + item->id2 = mir_strdup("84273372"); + item->ft->id2 = mir_strdup("84273372"); + JabberSend(info->proto, "", from, item->id2, id); + } + } + } + } else if (vs != NULL) { + + } else if (dcng != NULL) { + char *s, *id, *id2; + JabberLog(info->proto, "DCNG"); + s = JabberXmlGetAttrValue(dcng, "s"); + id2 = JabberXmlGetAttrValue(dcng, "i"); + id = JabberXmlGetAttrValue(dcng, "mi"); + if (!strcmp(s, "1")) { + /* Keys */ + /* n - name (file_send) */ + /* k - ??? */ + /* v - ??? */ + /* s - step */ + /* i - id of the file */ + /* ck - aes key */ + /* ks - key size (in bytes) */ + /* iv - aes initial vector */ + /* mi - p2p connection id */ + char *n, *k, *v, *ck, *ks, *iv; + n = JabberXmlGetAttrValue(dcng, "n"); + k = JabberXmlGetAttrValue(dcng, "k"); + v = JabberXmlGetAttrValue(dcng, "v"); + ck = JabberXmlGetAttrValue(dcng, "ck"); + iv = JabberXmlGetAttrValue(dcng, "iv"); + if (!strcmp(n, "file_send")) { + if ((item=JabberListGetItemPtr(info->proto, LIST_FILE, id)) != NULL) { + item->id2 = mir_strdup(id2); + item->ft->id2 = mir_strdup(id2); + TlenBindUDPSocket(item->ft); + JabberSend(info->proto, "", + item->ft->jid, item->ft->localName, item->ft->wLocalPort, item->ft->localName, item->ft->wLocalPort, item->ft->id2); + } + } + } else if (!strcmp(s, "2")) { + JabberLog(info->proto, "step = 2"); + JabberLog(info->proto, "%s",from); + JabberLog(info->proto, "%s",id2); + /* IP and port */ + if ((item=JabberListFindItemPtrById2(info->proto, LIST_FILE, id2)) != NULL) { + item->ft->hostName = mir_strdup(JabberXmlGetAttrValue(dcng, "pa")); + item->ft->wPort = atoi(JabberXmlGetAttrValue(dcng, "pp")); + TlenBindUDPSocket(item->ft); + JabberSend(info->proto, "", + item->ft->jid, item->ft->localName, item->ft->wLocalPort, item->ft->localName, item->ft->wLocalPort, item->ft->id2); + JabberForkThread((void (__cdecl *)(void*))TlenNewFileReceiveThread, 0, item->ft); + JabberForkThread((void (__cdecl *)(void*))TlenNewFileSendThread, 0, item->ft); + } + } else if (!strcmp(s, "4")) { + /* IP and port */ + if ((item=JabberListFindItemPtrById2(info->proto, LIST_FILE, id2)) != NULL) { + JabberLog(info->proto, "step = 4"); + item->ft->hostName = mir_strdup(JabberXmlGetAttrValue(dcng, "pa")); + item->ft->wPort = atoi(JabberXmlGetAttrValue(dcng, "pp")); + JabberForkThread((void (__cdecl *)(void*))TlenNewFileReceiveThread, 0, item->ft); + } + } + + } else if (dc != NULL) { + + } + } +} diff --git a/plugins/!NotAdopted/Tlen/tlen_p2p_old.c b/plugins/!NotAdopted/Tlen/tlen_p2p_old.c new file mode 100644 index 0000000000..0d5c121535 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_p2p_old.c @@ -0,0 +1,536 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" +#include +#include +#include +#include +#include "jabber_list.h" +#include "tlen_p2p_old.h" + +void TlenP2PFreeFileTransfer(TLEN_FILE_TRANSFER *ft) +{ + int i; + if (ft->jid) mir_free(ft->jid); + if (ft->iqId) mir_free(ft->iqId); + if (ft->id2) mir_free(ft->id2); + if (ft->hostName) mir_free(ft->hostName); + if (ft->localName) mir_free(ft->localName); + if (ft->szSavePath) mir_free(ft->szSavePath); + if (ft->szDescription) mir_free(ft->szDescription); + if (ft->filesSize) mir_free(ft->filesSize); + if (ft->files) { + for (i=0; ifileCount; i++) { + if (ft->files[i]) mir_free(ft->files[i]); + } + mir_free(ft->files); + } + mir_free(ft); +} + +TLEN_FILE_PACKET *TlenP2PPacketCreate(int datalen) +{ + TLEN_FILE_PACKET *packet; + + if ((packet=(TLEN_FILE_PACKET *) mir_alloc(sizeof(TLEN_FILE_PACKET))) == NULL) + return NULL; + packet->packet = NULL; + if (datalen > 0) { + if ((packet->packet=(char *) mir_alloc(datalen)) == NULL) { + mir_free(packet); + return NULL; + } + } + packet->maxDataLen = datalen; + packet->type=0; + packet->len=0; + return packet; +} + +void TlenP2PPacketFree(TLEN_FILE_PACKET *packet) +{ + if (packet != NULL) { + if (packet->packet != NULL) + mir_free(packet->packet); + mir_free(packet); + } +} + +void TlenP2PPacketSetType(TLEN_FILE_PACKET *packet, DWORD type) +{ + if (packet!=NULL) { + packet->type = type; + } +} + +void TlenP2PPacketSetLen(TLEN_FILE_PACKET *packet, DWORD len) +{ + if (packet!=NULL) { + packet->len = len; + } +} + +void TlenP2PPacketPackDword(TLEN_FILE_PACKET *packet, DWORD data) +{ + if (packet!=NULL && packet->packet!=NULL) { + if (packet->len + sizeof(DWORD) <= packet->maxDataLen) { + (*((DWORD*)((packet->packet)+(packet->len)))) = data; + packet->len += sizeof(DWORD); + } + } +} + +void TlenP2PPacketPackBuffer(TLEN_FILE_PACKET *packet, char *buffer, int len) +{ + if (packet!=NULL && packet->packet!=NULL) { + if (packet->len + len <= packet->maxDataLen) { + memcpy((packet->packet)+(packet->len), buffer, len); + packet->len += len; + } + } +} + +void TlenP2PInit() { +} + +void TlenP2PUninit() { +} + +int TlenP2PPacketSend(JABBER_SOCKET s, TLEN_FILE_PACKET *packet) +{ + DWORD sendResult; + if (packet!=NULL && packet->packet!=NULL) { + Netlib_Send(s, (char *)&packet->type, 4, MSG_NODUMP); + Netlib_Send(s, (char *)&packet->len, 4, MSG_NODUMP); + sendResult=Netlib_Send(s, packet->packet, packet->len, MSG_NODUMP); + if (sendResult==SOCKET_ERROR || sendResult!=packet->len) return 0; + } + return 1; +} + +TLEN_FILE_PACKET* TlenP2PPacketReceive(JABBER_SOCKET s) +{ + TLEN_FILE_PACKET *packet; + DWORD recvResult; + DWORD type, len, pos; + recvResult = Netlib_Recv(s, (char *)&type, 4, MSG_NODUMP); + if (recvResult==0 || recvResult==SOCKET_ERROR) return NULL; + recvResult = Netlib_Recv(s, (char *)&len, 4, MSG_NODUMP); + if (recvResult==0 || recvResult==SOCKET_ERROR) return NULL; + packet = TlenP2PPacketCreate(len); + TlenP2PPacketSetType(packet, type); + TlenP2PPacketSetLen(packet, len); + pos = 0; + while (len > 0) { + recvResult = Netlib_Recv(s, packet->packet+pos, len, MSG_NODUMP); + if (recvResult==0 || recvResult==SOCKET_ERROR) { + TlenP2PPacketFree(packet); + return NULL; + } + len -= recvResult; + pos += recvResult; + } + return packet; +} + +void TlenP2PEstablishOutgoingConnection(TLEN_FILE_TRANSFER *ft, BOOL sendAck) +{ + char *hash; + char str[300]; + TLEN_FILE_PACKET *packet; + TlenProtocol *proto = ft->proto; + + JabberLog(proto, "Establishing outgoing connection."); + ft->state = FT_ERROR; + if ((packet = TlenP2PPacketCreate(2*sizeof(DWORD) + 20))!=NULL) { + TlenP2PPacketSetType(packet, TLEN_FILE_PACKET_CONNECTION_REQUEST); + TlenP2PPacketPackDword(packet, 1); + TlenP2PPacketPackDword(packet, (DWORD) atoi(ft->iqId)); + _snprintf(str, sizeof(str), "%08X%s%d", atoi(ft->iqId), proto->threadData->username, atoi(ft->iqId)); + hash = TlenSha1(str, (int)strlen(str)); + TlenP2PPacketPackBuffer(packet, hash, 20); + mir_free(hash); + TlenP2PPacketSend(ft->s, packet); + TlenP2PPacketFree(packet); + packet = TlenP2PPacketReceive(ft->s); + if (packet != NULL) { + if (packet->type == TLEN_FILE_PACKET_CONNECTION_REQUEST_ACK) { // acknowledge + if ((int)(*((DWORD*)packet->packet)) == atoi(ft->iqId)) { + ft->state = FT_CONNECTING; + if (sendAck) { + ProtoBroadcastAck(proto->iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, ft, 0); + } + } + } + TlenP2PPacketFree(packet); + } + } +} + +TLEN_FILE_TRANSFER* TlenP2PEstablishIncomingConnection(TlenProtocol *proto, JABBER_SOCKET s, int list, BOOL sendAck) +{ + JABBER_LIST_ITEM *item = NULL; + TLEN_FILE_PACKET *packet; + int i; + char str[300]; + DWORD iqId; + // TYPE: 0x1 + // LEN: + // (DWORD) 0x1 + // (DWORD) id + // (BYTE) hash[20] + packet = TlenP2PPacketReceive(s); + if (packet == NULL || packet->type != TLEN_FILE_PACKET_CONNECTION_REQUEST || packet->len<28) { + if (packet!=NULL) { + TlenP2PPacketFree(packet); + } + return NULL; + } + iqId = *((DWORD *)(packet->packet+sizeof(DWORD))); + i = 0; + while ((i=JabberListFindNext(proto, list, i)) >= 0) { + if ((item=JabberListGetItemPtrFromIndex(proto, i))!=NULL) { + _snprintf(str, sizeof(str), "%d", iqId); + if (!strcmp(item->ft->iqId, str)) { + char *hash, *nick; + int j; + nick = JabberNickFromJID(item->ft->jid); + _snprintf(str, sizeof(str), "%08X%s%d", iqId, nick, iqId); + mir_free(nick); + hash = TlenSha1(str, (int)strlen(str)); + for (j=0;j<20;j++) { + if (hash[j]!=packet->packet[2*sizeof(DWORD)+j]) break; + } + mir_free(hash); + if (j==20) break; + } + } + i++; + } + TlenP2PPacketFree(packet); + if (i >=0) { + if ((packet=TlenP2PPacketCreate(sizeof(DWORD))) != NULL) { + // Send connection establishment acknowledgement + TlenP2PPacketSetType(packet, TLEN_FILE_PACKET_CONNECTION_REQUEST_ACK); + TlenP2PPacketPackDword(packet, (DWORD) atoi(item->ft->iqId)); + TlenP2PPacketSend(s, packet); + TlenP2PPacketFree(packet); + item->ft->state = FT_CONNECTING; + if (sendAck) { + ProtoBroadcastAck(item->ft->proto->iface.m_szModuleName, item->ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, item->ft, 0); + } + return item->ft; + } + } + return NULL; +} + +static void __cdecl TlenFileBindSocks4Thread(TLEN_FILE_TRANSFER* ft) +{ + BYTE buf[8]; + int status; + +// JabberLog("Waiting for the file to be sent via SOCKS..."); + status = Netlib_Recv(ft->s, (char*)buf, 8, MSG_NODUMP); +// JabberLog("accepted connection !!!"); + if ( status == SOCKET_ERROR || status<8 || buf[1]!=90) { + status = 1; + } else { + status = 0; + } + if (!status) { + ft->pfnNewConnectionV2(ft->s, 0, NULL); + } else { + if (ft->state!=FT_SWITCH) { + ft->state = FT_ERROR; + } + } + JabberLog(ft->proto, "Closing connection for this file transfer..."); +// Netlib_CloseHandle(ft->s); + if (ft->hFileEvent != NULL) + SetEvent(ft->hFileEvent); + +} +static void __cdecl TlenFileBindSocks5Thread(TLEN_FILE_TRANSFER* ft) +{ + BYTE buf[256]; + int status; + +// JabberLog("Waiting for the file to be sent via SOCKS..."); + status = Netlib_Recv(ft->s, (char*)buf, sizeof(buf), MSG_NODUMP); +// JabberLog("accepted connection !!!"); + if ( status == SOCKET_ERROR || status<7 || buf[1]!=0) { + status = 1; + } else { + status = 0; + } + if (!status) { + ft->pfnNewConnectionV2(ft->s, 0, NULL); + } else { + if (ft->state!=FT_SWITCH) { + ft->state = FT_ERROR; + } + } +// JabberLog("Closing connection for this file transfer..."); +// Netlib_CloseHandle(ft->s); + if (ft->hFileEvent != NULL) + SetEvent(ft->hFileEvent); + +} + +static JABBER_SOCKET TlenP2PBindSocks4(SOCKSBIND * sb, TLEN_FILE_TRANSFER *ft) +{ //rfc1928 + int len; + BYTE buf[256]; + int status; + struct in_addr in; + NETLIBOPENCONNECTION nloc; + JABBER_SOCKET s; + + nloc.cbSize = NETLIBOPENCONNECTION_V1_SIZE;//sizeof(NETLIBOPENCONNECTION); + nloc.szHost = sb->szHost; + nloc.wPort = sb->wPort; + nloc.flags = 0; + s = (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, (WPARAM) ft->proto->hFileNetlibUser, (LPARAM) &nloc); + if (s==NULL) { +// JabberLog("Connection failed (%d), thread ended", WSAGetLastError()); + return NULL; + } + buf[0] = 4; //socks4 + buf[1] = 2; //2-bind, 1-connect + *(PWORD)(buf+2) = htons(0); // port + *(PDWORD)(buf+4) = INADDR_ANY; + if (sb->useAuth) { + strcpy((char*)buf+8, sb->szUser); + len = (int)strlen(sb->szUser); + } else { + buf[8] = 0; + len = 0; + } + len += 9; + status = Netlib_Send(s, (char*)buf, len, MSG_NODUMP); + if (status==SOCKET_ERROR || statusszHost, inet_ntoa(in)); + sb->wPort = htons(*(PWORD)(buf+2)); + ft->s = s; + JabberForkThread((void (__cdecl *)(void*))TlenFileBindSocks4Thread, 0, ft); + return s; +} + +static JABBER_SOCKET TlenP2PBindSocks5(SOCKSBIND * sb, TLEN_FILE_TRANSFER *ft) +{ //rfc1928 + BYTE buf[512]; + int len, status; + NETLIBOPENCONNECTION nloc; + struct in_addr in; + JABBER_SOCKET s; + + nloc.cbSize = NETLIBOPENCONNECTION_V1_SIZE;//sizeof(NETLIBOPENCONNECTION); + nloc.szHost = sb->szHost; + nloc.wPort = sb->wPort; + nloc.flags = 0; + s = (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, (WPARAM) ft->proto->hFileNetlibUser, (LPARAM) &nloc); + if (s==NULL) { + JabberLog(ft->proto, "Connection failed (%d), thread ended", WSAGetLastError()); + return NULL; + } + buf[0] = 5; //yep, socks5 + buf[1] = 1; //one auth method + buf[2] = sb->useAuth?2:0; // authorization + status = Netlib_Send(s, (char*)buf, 3, MSG_NODUMP); + if (status==SOCKET_ERROR || status<3) { + JabberLog(ft->proto, "Send failed (%d), thread ended", WSAGetLastError()); + Netlib_CloseHandle(s); + return NULL; + } + status = Netlib_Recv(s, (char*)buf, 2, MSG_NODUMP); + if (status==SOCKET_ERROR || status<2 || (buf[1]!=0 && buf[1]!=2)) { + JabberLog(ft->proto, "SOCKS5 negotiation failed"); + Netlib_CloseHandle(s); + return NULL; + } + if(buf[1]==2) { //rfc1929 + int nUserLen, nPassLen; + PBYTE pAuthBuf; + + nUserLen = (int)strlen(sb->szUser); + nPassLen = (int)strlen(sb->szPassword); + pAuthBuf = (PBYTE)mir_alloc(3+nUserLen+nPassLen); + pAuthBuf[0] = 1; //auth version + pAuthBuf[1] = nUserLen; + memcpy(pAuthBuf+2, sb->szUser, nUserLen); + pAuthBuf[2+nUserLen]=nPassLen; + memcpy(pAuthBuf+3+nUserLen,sb->szPassword,nPassLen); + status = Netlib_Send(s, (char*)pAuthBuf, 3+nUserLen+nPassLen, MSG_NODUMP); + mir_free(pAuthBuf); + if (status==SOCKET_ERROR || status<3+nUserLen+nPassLen) { + JabberLog(ft->proto, "Send failed (%d), thread ended", WSAGetLastError()); + Netlib_CloseHandle(s); + return NULL; + } + status = Netlib_Recv(s, (char*)buf, sizeof(buf), MSG_NODUMP); + if (status==SOCKET_ERROR || status<2 || buf[1]!=0) { + JabberLog(ft->proto, "SOCKS5 sub-negotiation failed"); + Netlib_CloseHandle(s); + return NULL; + } + } + + { PBYTE pInit; + int nHostLen=4; + DWORD hostIP=INADDR_ANY; + pInit=(PBYTE)mir_alloc(6+nHostLen); + pInit[0]=5; //SOCKS5 + pInit[1]=2; //bind + pInit[2]=0; //reserved + pInit[3]=1; + *(PDWORD)(pInit+4)=hostIP; + *(PWORD)(pInit+4+nHostLen)=htons(0); + status = Netlib_Send(s, (char*)pInit, 6+nHostLen, MSG_NODUMP); + mir_free(pInit); + if (status==SOCKET_ERROR || status<6+nHostLen) { +// JabberLog("Send failed (%d), thread ended", WSAGetLastError()); + Netlib_CloseHandle(s); + return NULL; + } + } + status = Netlib_Recv(s, (char*)buf, sizeof(buf), MSG_NODUMP); + if ( status == SOCKET_ERROR || status<7 || buf[0]!=5 || buf[1]!=0) { +// JabberLog("SOCKS5 request failed"); + Netlib_CloseHandle(s); + return NULL; + } + if (buf[2]==1) { // domain + len = buf[4]; + memcpy(sb->szHost, buf+5, len); + sb->szHost[len]=0; + len += 4; + } else { // ip address + in.S_un.S_addr = *(PDWORD)(buf+4); + strcpy(sb->szHost, inet_ntoa(in)); + len = 8; + } + sb->wPort = htons(*(PWORD)(buf+len)); + ft->s = s; + + JabberForkThread((void (__cdecl *)(void*))TlenFileBindSocks5Thread, 0, ft); + return s; +} + + +JABBER_SOCKET TlenP2PListen(TLEN_FILE_TRANSFER *ft) +{ + NETLIBBIND nlb = {0}; + JABBER_SOCKET s = NULL; + int useProxy; + DBVARIANT dbv; + SOCKSBIND sb; + struct in_addr in; + TlenProtocol *proto = ft->proto; + useProxy=0; + if (ft->localName!= NULL) mir_free(ft->localName); + ft->localName = NULL; + ft->wPort = 0; + if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "UseFileProxy", FALSE)) { + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "FileProxyHost", &dbv)) { + strcpy(sb.szHost, dbv.pszVal); + DBFreeVariant(&dbv); + sb.wPort = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "FileProxyPort", 0); + sb.useAuth = FALSE; + strcpy(sb.szUser, ""); + strcpy(sb.szPassword, ""); + if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "FileProxyAuth", FALSE)) { + sb.useAuth = TRUE; + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "FileProxyUsername", &dbv)) { + strcpy(sb.szUser, dbv.pszVal); + DBFreeVariant(&dbv); + } + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "FileProxyPassword", &dbv)) { + CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM) dbv.pszVal); + strcpy(sb.szPassword, dbv.pszVal); + DBFreeVariant(&dbv); + } + } + switch (DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "FileProxyType", 0)) { + case 0: // forwarding + useProxy = 1; + break; + case 1: // socks4 + s = TlenP2PBindSocks4(&sb, ft); + useProxy = 2; + break; + case 2: // socks5 + s = TlenP2PBindSocks5(&sb, ft); + useProxy = 2; + break; + } + ft->localName = mir_strdup(sb.szHost); + ft->wPort = sb.wPort; + ft->wLocalPort = sb.wPort; + } + } + if (useProxy<2) { + nlb.cbSize = sizeof(NETLIBBIND); + nlb.pfnNewConnectionV2 = ft->pfnNewConnectionV2; + nlb.wPort = 0; // Use user-specified incoming port ranges, if available + nlb.pExtra = proto; + JabberLog(ft->proto, "Calling MS_NETLIB_BINDPORT"); + s = (HANDLE) CallService(MS_NETLIB_BINDPORT, (WPARAM) ft->proto->hNetlibUser, (LPARAM) &nlb); + JabberLog(ft->proto, "listening on %d",s); + } + if (useProxy==0) { + in.S_un.S_addr = htonl(nlb.dwExternalIP); + ft->localName = mir_strdup(inet_ntoa(in)); + ft->wPort = nlb.wPort; + ft->wLocalPort = nlb.wExPort; + } + if (s != NULL) { +// listenCount++; + } + return s; +} + +void TlenP2PStopListening(JABBER_SOCKET s) { + if (s != NULL) { +// listenCount--; +// if (listenCount <= 0) { +// Netlib_CloseHandle(s); +// } + } +} diff --git a/plugins/!NotAdopted/Tlen/tlen_p2p_old.h b/plugins/!NotAdopted/Tlen/tlen_p2p_old.h new file mode 100644 index 0000000000..d6405a378e --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_p2p_old.h @@ -0,0 +1,66 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" + +#ifndef _TLEN_P2P_OLD_H_ +#define _TLEN_P2P_OLD_H_ + +enum { + TLEN_FILE_PACKET_CONNECTION_REQUEST = 0x01, + TLEN_FILE_PACKET_CONNECTION_REQUEST_ACK = 0x02, + TLEN_FILE_PACKET_FILE_LIST = 0x32, + TLEN_FILE_PACKET_FILE_LIST_ACK = 0x33, + TLEN_FILE_PACKET_FILE_REQUEST = 0x34, + TLEN_FILE_PACKET_FILE_DATA = 0x35, + TLEN_FILE_PACKET_END_OF_FILE = 0x37, + TLEN_VOICE_PACKET = 0x96 +}; + +typedef struct { + unsigned int maxDataLen; + char *packet; + DWORD type; + DWORD len; +} TLEN_FILE_PACKET; + +typedef struct { + char szHost[256]; + int wPort; + int useAuth; + char szUser[256]; + char szPassword[256]; +}SOCKSBIND; + +extern void TlenP2PFreeFileTransfer(TLEN_FILE_TRANSFER *ft); +extern TLEN_FILE_PACKET *TlenP2PPacketCreate(int datalen); +extern void TlenP2PPacketFree(TLEN_FILE_PACKET *packet); +extern void TlenP2PPacketSetType(TLEN_FILE_PACKET *packet, DWORD type); +extern void TlenP2PPacketSetLen(TLEN_FILE_PACKET *packet, DWORD len); +extern void TlenP2PPacketPackDword(TLEN_FILE_PACKET *packet, DWORD data); +extern void TlenP2PPacketPackBuffer(TLEN_FILE_PACKET *packet, char *buffer, int len); +extern int TlenP2PPacketSend(JABBER_SOCKET s, TLEN_FILE_PACKET *packet); +extern TLEN_FILE_PACKET* TlenP2PPacketReceive(JABBER_SOCKET s); +extern void TlenP2PEstablishOutgoingConnection(TLEN_FILE_TRANSFER *ft, BOOL sendAck); +extern TLEN_FILE_TRANSFER* TlenP2PEstablishIncomingConnection(TlenProtocol *proto, JABBER_SOCKET s, int list, BOOL sendAck); +extern JABBER_SOCKET TlenP2PListen(TLEN_FILE_TRANSFER *ft); +extern void TlenP2PStopListening(JABBER_SOCKET s); +#endif diff --git a/plugins/!NotAdopted/Tlen/tlen_picture.c b/plugins/!NotAdopted/Tlen/tlen_picture.c new file mode 100644 index 0000000000..c8f8d6f3e2 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_picture.c @@ -0,0 +1,320 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2009 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" +#include "jabber_list.h" +#include "tlen_file.h" +#include "tlen_p2p_old.h" + +typedef struct { + TlenProtocol *proto; + JABBER_LIST_ITEM *item; +} TLENPSREQUESTTHREADDATA; + +static void LogPictureMessage(TlenProtocol *proto, const char *jid, const char *filename, BOOL isSent) +{ + char message[1024]; + const char *msg = isSent ? "Image sent file://%s" : "Image received file://%s"; + _snprintf(message, sizeof(message), Translate(msg), filename); + TlenLogMessage(proto, JabberHContactFromJID(proto, jid), isSent ? DBEF_SENT : 0, message); +} + +static void TlenPsPostThread(void *ptr) { + TLENPSREQUESTTHREADDATA *data = (TLENPSREQUESTTHREADDATA *)ptr; + TlenProtocol *proto = data->proto; + JABBER_LIST_ITEM *item = data->item; + JABBER_SOCKET socket = JabberWsConnect(proto, "ps.tlen.pl", 443); + BOOL bSent = FALSE; + if (socket != NULL) { + char header[512]; + DWORD ret; + item->ft->s = socket; + item->ft->hFileEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + _snprintf(header, sizeof(header), "", proto->threadData->username, item->ft->jid, item->ft->fileTotalSize, item->jid); + JabberWsSend(proto, socket, header, (int)strlen(header)); + ret = WaitForSingleObject(item->ft->hFileEvent, 1000 * 60 * 5); + if (ret == WAIT_OBJECT_0) { + FILE *fp = fopen( item->ft->files[0], "rb" ); + if (fp) { + int i; + char header[512]; + char fileBuffer[2048]; + _snprintf(header, sizeof(header), "", item->ft->iqId, item->jid); + JabberWsSend(proto, socket, header, (int)strlen(header)); + JabberLog(proto, "Sending picture data..."); + for (i = item->ft->filesSize[0]; i > 0; ) { + int toread = min(2048, i); + int readcount = (int)fread(fileBuffer, (size_t)1, (size_t)toread, fp); + i -= readcount; + if (readcount > 0) { + JabberWsSend(proto, socket, fileBuffer, readcount); + } + if (toread != readcount) { + break; + } + } + fclose(fp); + SleepEx(3000, TRUE); + bSent = TRUE; + } else { + /* picture not found */ + } + } else { + /* 5 minutes passed */ + } + Netlib_CloseHandle(socket); + if (bSent) { + JabberSend(proto, "", item->ft->jid, item->jid, item->ft->id2); + LogPictureMessage(proto, item->ft->jid, item->ft->files[0], TRUE); + } + TlenP2PFreeFileTransfer(item->ft); + JabberListRemove(proto, LIST_PICTURE, item->jid); + } else { + /* cannot connect to ps server */ + } + mir_free(data); +} + +static void TlenPsPost(TlenProtocol *proto, JABBER_LIST_ITEM *item) { + TLENPSREQUESTTHREADDATA *threadData = (TLENPSREQUESTTHREADDATA *)mir_alloc(sizeof(TLENPSREQUESTTHREADDATA)); + threadData->proto = proto; + threadData->item = item; + JabberForkThread(TlenPsPostThread, 0, threadData); +} + +static void TlenPsGetThread(void *ptr) { + TLENPSREQUESTTHREADDATA *data = (TLENPSREQUESTTHREADDATA *)ptr; + TlenProtocol *proto = data->proto; + JABBER_LIST_ITEM *item = data->item; + FILE *fp; + fp = fopen( item->ft->files[0], "wb" ); + if (fp) { + JABBER_SOCKET socket = JabberWsConnect(proto, "ps.tlen.pl", 443); + if (socket != NULL) { + XmlState xmlState; + char header[512]; + char fileBuffer[2048]; + JabberXmlInitState(&xmlState); + _snprintf(header, sizeof(header), "", proto->threadData->username, item->ft->jid, item->jid, item->ft->id2); + JabberWsSend(proto, socket, header, (int)strlen(header)); + JabberLog(proto, "Reveiving picture data..."); + { + int totalcount = 0; + int size = item->ft->filesSize[0]; + BOOL bHeader = TRUE; + while (TRUE) { + int readcount = JabberWsRecv(proto, socket, fileBuffer, 2048 - totalcount); + if (readcount == 0) { + break; + } + totalcount += readcount; + if (bHeader) { + char * tagend = memchr(fileBuffer, '/', totalcount); + tagend = memchr(tagend + 1, '>', totalcount - (tagend - fileBuffer) - 1); + if (tagend != NULL) { + int parsed = JabberXmlParse(&xmlState, fileBuffer, tagend - fileBuffer + 1); + if (parsed == 0) { + continue; + } + bHeader = FALSE; + totalcount -= parsed; + memmove(fileBuffer, fileBuffer+parsed, totalcount); + } + } + if (!bHeader) { + if (totalcount > 0) { + fwrite(fileBuffer, 1, totalcount, fp); + size -= totalcount; + totalcount = 0; + } + if (size == 0) { + break; + } + } + } + } + Netlib_CloseHandle(socket); + JabberLog(proto, "Picture received..."); + LogPictureMessage(proto, item->ft->jid, item->ft->files[0], FALSE); + } else { + /* cannot connect to ps server */ + } + fclose(fp); + } else { + /* cannot create file */ + } + TlenP2PFreeFileTransfer(item->ft); + JabberListRemove(proto, LIST_PICTURE, item->jid); + mir_free(data); +} + +static void TlenPsGet(TlenProtocol *proto, JABBER_LIST_ITEM *item) { + TLENPSREQUESTTHREADDATA *threadData = (TLENPSREQUESTTHREADDATA *)mir_alloc(sizeof(TLENPSREQUESTTHREADDATA)); + threadData->proto = proto; + threadData->item = item; + JabberForkThread(TlenPsGetThread, 0, threadData); +} + +void TlenProcessPic(XmlNode *node, TlenProtocol *proto) { + JABBER_LIST_ITEM *item = NULL; + char *crc, *crc_c, *idt, *size, *from, *fromRaw, *rt; + from = JabberXmlGetAttrValue(node, "from"); + fromRaw = JabberLoginFromJID(from); + idt = JabberXmlGetAttrValue(node, "idt"); + size = JabberXmlGetAttrValue(node, "size"); + crc_c = JabberXmlGetAttrValue(node, "crc_c"); + crc = JabberXmlGetAttrValue(node, "crc"); + rt = JabberXmlGetAttrValue(node, "rt"); + if (idt != NULL) { + item = JabberListGetItemPtr(proto, LIST_PICTURE, idt); + } + if (item != NULL) { + if (!strcmp(from, "ps")) { + char *st = JabberXmlGetAttrValue(node, "st"); + if (st != NULL) { + item->ft->iqId = mir_strdup(st); + item->ft->id2 = mir_strdup(rt); + if (item->ft->hFileEvent != NULL) { + SetEvent(item->ft->hFileEvent); + item->ft->hFileEvent = NULL; + } + } + } else if (!strcmp(item->ft->jid, fromRaw)) { + if (crc_c != NULL) { + if (!strcmp(crc_c, "n")) { + /* crc_c = n, picture transfer accepted */ + TlenPsPost(proto, item); + } else if (!strcmp(crc_c, "f")) { + /* crc_c = f, picture cached, no need to transfer again */ + LogPictureMessage(proto, item->ft->jid, item->ft->files[0], TRUE); + TlenP2PFreeFileTransfer(item->ft); + JabberListRemove(proto, LIST_PICTURE, idt); + } + } else if (rt != NULL) { + item->ft->id2 = mir_strdup(rt); + TlenPsGet(proto, item); + } + } + } else if (crc != NULL) { + BOOL bAccept = proto->tlenOptions.imagePolicy == TLEN_IMAGES_ACCEPT_ALL || (proto->tlenOptions.imagePolicy == TLEN_IMAGES_IGNORE_NIR && IsAuthorized(proto, from)); + if (bAccept) { + FILE* fp; + char fileName[MAX_PATH]; + char *ext = JabberXmlGetAttrValue(node, "ext"); + char *tmpPath = Utils_ReplaceVars( "%miranda_userdata%" ); + int tPathLen = mir_snprintf( fileName, MAX_PATH, "%s\\Images\\Tlen", tmpPath ); + long oldSize = 0, lSize = atol(size); + DWORD dwAttributes = GetFileAttributesA( fileName ); + if ( dwAttributes == 0xffffffff || ( dwAttributes & FILE_ATTRIBUTE_DIRECTORY ) == 0 ) { + CallService( MS_UTILS_CREATEDIRTREE, 0, ( LPARAM )fileName ); + } + mir_free(tmpPath); + fileName[ tPathLen++ ] = '\\'; + mir_snprintf( fileName + tPathLen, MAX_PATH - tPathLen, "%s.%s", crc, ext ); + fp = fopen( fileName, "rb" ); + if (fp) { + fseek(fp, 0, SEEK_END); + oldSize = ftell(fp); + fclose(fp); + } + if (oldSize != lSize) { + item = JabberListAdd(proto, LIST_PICTURE, idt); + item->ft = TlenFileCreateFT(proto, from); + item->ft->files = (char **) mir_alloc(sizeof(char *)); + item->ft->filesSize = (long *) mir_alloc(sizeof(long)); + item->ft->files[0] = mir_strdup(fileName); + item->ft->filesSize[0] = lSize; + item->ft->fileTotalSize = item->ft->filesSize[0]; + JabberSend(proto, "", from, idt); + } else { + JabberSend(proto, "", from, idt); + LogPictureMessage(proto, from, fileName, FALSE); + } + } + } + mir_free(fromRaw); +} + +BOOL SendPicture(TlenProtocol *proto, HANDLE hContact) { + DBVARIANT dbv; + if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { + char *jid = dbv.pszVal; + char szFilter[512]; + char *szFileName = (char*) mir_alloc(_MAX_PATH); + OPENFILENAMEA ofn = {0}; + CallService( MS_UTILS_GETBITMAPFILTERSTRINGS, ( WPARAM ) sizeof( szFilter ), ( LPARAM )szFilter ); + ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; + ofn.hwndOwner = NULL; + ofn.lpstrFilter = szFilter; + ofn.lpstrCustomFilter = NULL; + ofn.lpstrFile = szFileName; + ofn.nMaxFile = _MAX_PATH; + ofn.Flags = OFN_FILEMUSTEXIST; + szFileName[0] = '\0'; + if ( GetOpenFileNameA( &ofn )) { + long size; + FILE* fp = fopen( szFileName, "rb" ); + if (fp) { + fseek(fp, 0, SEEK_END); + size = ftell(fp); + if (size > 0 && size < 256*1024) { + JABBER_LIST_ITEM *item; + mir_sha1_ctx sha; + DWORD digest[5]; + int i; + char idStr[10]; + char fileBuffer[2048]; + int id = JabberSerialNext(proto); + _snprintf(idStr, sizeof(idStr), "%d", id); + item = JabberListAdd(proto, LIST_PICTURE, idStr); + item->ft = TlenFileCreateFT(proto, jid); + item->ft->files = (char **) mir_alloc(sizeof(char *)); + item->ft->filesSize = (long *) mir_alloc(sizeof(long)); + item->ft->files[0] = szFileName; + item->ft->filesSize[0] = size; + item->ft->fileTotalSize = size; + fseek(fp, 0, SEEK_SET); + mir_sha1_init( &sha ); + for (i = item->ft->filesSize[0]; i > 0; ) { + int toread = min(2048, i); + int readcount = (int)fread(fileBuffer, (size_t)1, (size_t)toread, fp); + i -= readcount; + if (readcount > 0) { + mir_sha1_append( &sha, (mir_sha1_byte_t* )fileBuffer, readcount); + } + if (toread != readcount) { + break; + } + } + mir_sha1_finish( &sha, (mir_sha1_byte_t* )digest ); + JabberSend(proto, "", jid, + (int)htonl(digest[0]), (int)htonl(digest[1]), (int)htonl(digest[2]), (int)htonl(digest[3]), (int)htonl(digest[4]), idStr, item->ft->filesSize[0], "jpg"); + } else { + /* file too big */ + } + fclose(fp); + } + } + DBFreeVariant(&dbv); + } + return FALSE; +} diff --git a/plugins/!NotAdopted/Tlen/tlen_picture.h b/plugins/!NotAdopted/Tlen/tlen_picture.h new file mode 100644 index 0000000000..e4836444ee --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_picture.h @@ -0,0 +1,41 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2009 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#ifndef _TLEN_PICTURE_H +#define _TLEN_PICTURE_H + +#include +#include "jabber.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void TlenProcessPic(XmlNode *node, TlenProtocol *proto); +extern BOOL SendPicture(TlenProtocol *, HANDLE hContact); + +#ifdef __cplusplus +} +#endif + +#endif /* _TLEN_PICTURE_H */ + diff --git a/plugins/!NotAdopted/Tlen/tlen_presence.c b/plugins/!NotAdopted/Tlen/tlen_presence.c new file mode 100644 index 0000000000..ca1f14e23c --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_presence.c @@ -0,0 +1,314 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2009 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" +#include "jabber_list.h" +#include "tlen_avatar.h" + +void TlenProcessPresence(XmlNode *node, TlenProtocol *proto) +{ + HANDLE hContact; + XmlNode *showNode, *statusNode; + JABBER_LIST_ITEM *item; + char *from, *type, *nick, *show; + int status, laststatus = ID_STATUS_OFFLINE; + char *p; + + if ((from=JabberXmlGetAttrValue(node, "from")) != NULL) { + if (JabberListExist(proto, LIST_CHATROOM, from)); //JabberGroupchatProcessPresence(node, userdata); + + else { + type = JabberXmlGetAttrValue(node, "type"); + item = JabberListGetItemPtr(proto, LIST_ROSTER, from); + if (item != NULL) { + if (proto->tlenOptions.enableAvatars) { + TlenProcessPresenceAvatar(proto, node, item); + } + } + if (type==NULL || (!strcmp(type, "available"))) { + if ((nick=JabberLocalNickFromJID(from)) != NULL) { + if ((hContact=JabberHContactFromJID(proto, from)) == NULL) + hContact = JabberDBCreateContact(proto, from, nick, FALSE); + if (!JabberListExist(proto, LIST_ROSTER, from)) { + JabberLog(proto, "Receive presence online from %s (who is not in my roster)", from); + JabberListAdd(proto, LIST_ROSTER, from); + } + status = ID_STATUS_ONLINE; + if ((showNode=JabberXmlGetChild(node, "show")) != NULL) { + if ((show=showNode->text) != NULL) { + if (!strcmp(show, "away")) status = ID_STATUS_AWAY; + else if (!strcmp(show, "xa")) status = ID_STATUS_NA; + else if (!strcmp(show, "dnd")) status = ID_STATUS_DND; + else if (!strcmp(show, "chat")) status = ID_STATUS_FREECHAT; + else if (!strcmp(show, "unavailable")) { + // Always show invisible (on old Tlen client) as invisible (not offline) + status = ID_STATUS_OFFLINE; + } + } + } + + statusNode = JabberXmlGetChild(node, "status"); + if (statusNode) + p = JabberTextDecode(statusNode->text); + else + p = NULL; + JabberListAddResource(proto, LIST_ROSTER, from, status, statusNode?p:NULL); + if (p) { + DBWriteContactSettingString(hContact, "CList", "StatusMsg", p); + mir_free(p); + } else { + DBDeleteContactSetting(hContact, "CList", "StatusMsg"); + } + // Determine status to show for the contact and request version information + if (item != NULL) { + laststatus = item->status; + item->status = status; + } + if (strchr(from, '@')!=NULL || DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "ShowTransport", TRUE)==TRUE) { + if (DBGetContactSettingWord(hContact, proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE) != status) + DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "Status", (WORD) status); + } + if (item != NULL) { + if (!item->infoRequested) { + int iqId = JabberSerialNext(proto); + item->infoRequested = TRUE; + JabberSend( proto, "", iqId, from); + } + if (proto->tlenOptions.enableVersion && !item->versionRequested) { + item->versionRequested = TRUE; + if (proto->iface.m_iStatus != ID_STATUS_INVISIBLE) { + JabberSend( proto, "", from ); + } + } + } + JabberLog(proto, "%s (%s) online, set contact status to %d", nick, from, status); + mir_free(nick); + } + } + else if (!strcmp(type, "unavailable")) { + if (!JabberListExist(proto, LIST_ROSTER, from)) { + JabberLog(proto, "Receive presence offline from %s (who is not in my roster)", from); + JabberListAdd(proto, LIST_ROSTER, from); + } + else { + JabberListRemoveResource(proto, LIST_ROSTER, from); + } + status = ID_STATUS_OFFLINE; + statusNode = JabberXmlGetChild(node, "status"); + if (statusNode) { + if (proto->tlenOptions.offlineAsInvisible) { + status = ID_STATUS_INVISIBLE; + } + p = JabberTextDecode(statusNode->text); + JabberListAddResource(proto, LIST_ROSTER, from, status, p); + if ((hContact=JabberHContactFromJID(proto, from)) != NULL) { + if (p) { + DBWriteContactSettingString(hContact, "CList", "StatusMsg", p); + } else { + DBDeleteContactSetting(hContact, "CList", "StatusMsg"); + } + } + if (p) mir_free(p); + } + if ((item=JabberListGetItemPtr(proto, LIST_ROSTER, from)) != NULL) { + // Determine status to show for the contact based on the remaining resources + item->status = status; + item->versionRequested = FALSE; + item->infoRequested = FALSE; + } + if ((hContact=JabberHContactFromJID(proto, from)) != NULL) { + if (strchr(from, '@')!=NULL || DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "ShowTransport", TRUE)==TRUE) { + if (DBGetContactSettingWord(hContact, proto->iface.m_szModuleName, "Status", ID_STATUS_OFFLINE) != status) + DBWriteContactSettingWord(hContact, proto->iface.m_szModuleName, "Status", (WORD) status); + } + if (item != NULL && item->isTyping) { + item->isTyping = FALSE; + CallService(MS_PROTO_CONTACTISTYPING, (WPARAM) hContact, PROTOTYPE_CONTACTTYPING_OFF); + } + JabberLog(proto, "%s offline, set contact status to %d", from, status); + } + } + else if (!strcmp(type, "subscribe")) { + if (strchr(from, '@') == NULL) { + // automatically send authorization allowed to agent/transport + JabberSend(proto, "", from); + } + else if ((nick=JabberNickFromJID(from)) != NULL) { + JabberLog(proto, "%s (%s) requests authorization", nick, from); + JabberDBAddAuthRequest(proto, from, nick); + mir_free(nick); + } + } + else if (!strcmp(type, "subscribed")) { + if ((item=JabberListGetItemPtr(proto, LIST_ROSTER, from)) != NULL) { + if (item->subscription == SUB_FROM) item->subscription = SUB_BOTH; + else if (item->subscription == SUB_NONE) { + item->subscription = SUB_TO; + } + } + } + } + } +} + +static void JabberSendPresenceTo(TlenProtocol *proto, int status, char *to) +{ + char *showBody, *statusMsg, *presenceType; + char *ptr = NULL; + + if (!proto->isOnline) return; + + // Send update for status (we won't handle ID_STATUS_OFFLINE here) + // Note: jabberModeMsg is already encoded using JabberTextEncode() + EnterCriticalSection(&proto->modeMsgMutex); + + showBody = NULL; + statusMsg = NULL; + presenceType = NULL; + switch (status) { + case ID_STATUS_ONLINE: + showBody = "available"; + statusMsg = proto->modeMsgs.szOnline; + break; + case ID_STATUS_AWAY: + case ID_STATUS_ONTHEPHONE: + case ID_STATUS_OUTTOLUNCH: + showBody = "away"; + statusMsg = proto->modeMsgs.szAway; + break; + case ID_STATUS_NA: + showBody = "xa"; + statusMsg = proto->modeMsgs.szNa; + break; + case ID_STATUS_DND: + case ID_STATUS_OCCUPIED: + showBody = "dnd"; + statusMsg = proto->modeMsgs.szDnd; + break; + case ID_STATUS_FREECHAT: + showBody = "chat"; + statusMsg = proto->modeMsgs.szFreechat; + break; + case ID_STATUS_INVISIBLE: + presenceType = "invisible"; + statusMsg = proto->modeMsgs.szInvisible; + break; + case ID_STATUS_OFFLINE: + presenceType = "unavailable"; + if (DBGetContactSettingByte(NULL, proto->iface.m_szModuleName, "LeaveOfflineMessage", FALSE)) { + int offlineMessageOption = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "OfflineMessageOption", 0); + if (offlineMessageOption == 0) { + switch (proto->iface.m_iStatus) { + case ID_STATUS_ONLINE: + ptr = mir_strdup(proto->modeMsgs.szOnline); + break; + case ID_STATUS_AWAY: + case ID_STATUS_ONTHEPHONE: + case ID_STATUS_OUTTOLUNCH: + ptr = mir_strdup(proto->modeMsgs.szAway); + break; + case ID_STATUS_NA: + ptr = mir_strdup(proto->modeMsgs.szNa); + break; + case ID_STATUS_DND: + case ID_STATUS_OCCUPIED: + ptr = mir_strdup(proto->modeMsgs.szDnd); + break; + case ID_STATUS_FREECHAT: + ptr = mir_strdup(proto->modeMsgs.szFreechat); + break; + case ID_STATUS_INVISIBLE: + ptr = mir_strdup(proto->modeMsgs.szInvisible); + break; + } + } else if (offlineMessageOption == 99) { + + } else if (offlineMessageOption < 7) { + DBVARIANT dbv; + const char *statusNames[] = {"OnDefault", "AwayDefault", "NaDefault", "DndDefault", "FreeChatDefault", "InvDefault"}; + if (!DBGetContactSetting(NULL, "SRAway", statusNames[offlineMessageOption-1], &dbv)) { + int i; + char substituteStr[128]; + ptr = mir_strdup(dbv.pszVal); + DBFreeVariant(&dbv); + for(i=0;ptr[i];i++) { + if(ptr[i]!='%') continue; + if(!_strnicmp(ptr+i,"%time%",6)) + GetTimeFormatA(LOCALE_USER_DEFAULT,TIME_NOSECONDS,NULL,NULL,substituteStr,sizeof(substituteStr)); + else if(!_strnicmp(ptr+i,"%date%",6)) + GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,NULL,NULL,substituteStr,sizeof(substituteStr)); + else continue; + if(strlen(substituteStr)>6) ptr=(char*)mir_realloc(ptr,strlen(ptr)+1+strlen(substituteStr)-6); + MoveMemory(ptr+i+strlen(substituteStr),ptr+i+6,strlen(ptr)-i-5); + CopyMemory(ptr+i,substituteStr,strlen(substituteStr)); + } + } + } + } + statusMsg = ptr; + break; + default: + // Should not reach here + break; + } + proto->iface.m_iStatus = status; + if (presenceType) { + if (statusMsg) + JabberSend(proto, "%s", presenceType, statusMsg); + else + JabberSend(proto, "", presenceType); + } else { + if (statusMsg) + JabberSend(proto, "%s%s", showBody, statusMsg); + else + JabberSend(proto, "%s", showBody); + } + if (ptr) { + mir_free(ptr); + } + LeaveCriticalSection(&proto->modeMsgMutex); +} + +void JabberSendPresence(TlenProtocol *proto, int statusIn) +{ + int statusOut; + switch (statusIn) { + case ID_STATUS_ONLINE: + case ID_STATUS_OFFLINE: + case ID_STATUS_NA: + case ID_STATUS_FREECHAT: + case ID_STATUS_INVISIBLE: + statusOut = statusIn; + break; + case ID_STATUS_AWAY: + case ID_STATUS_ONTHEPHONE: + case ID_STATUS_OUTTOLUNCH: + default: + statusOut = ID_STATUS_AWAY; + break; + case ID_STATUS_DND: + case ID_STATUS_OCCUPIED: + statusOut = ID_STATUS_DND; + break; + } + JabberSendPresenceTo(proto, statusOut, NULL); +} diff --git a/plugins/!NotAdopted/Tlen/tlen_presence.h b/plugins/!NotAdopted/Tlen/tlen_presence.h new file mode 100644 index 0000000000..fdc3ea642e --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_presence.h @@ -0,0 +1,37 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2009 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#ifndef _TLEN_PRESENCE_H +#define _TLEN_PRESENCE_H + +#ifdef __cplusplus +extern "C" { +#endif + +void TlenProcessPresence(XmlNode *node, TlenProtocol *proto); + +#ifdef __cplusplus +} +#endif + +#endif /* _TLEN_PRESENCE_H */ + diff --git a/plugins/!NotAdopted/Tlen/tlen_userinfo.c b/plugins/!NotAdopted/Tlen/tlen_userinfo.c new file mode 100644 index 0000000000..50345282a9 --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_userinfo.c @@ -0,0 +1,335 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" +#include +#include +#include +#include +#include +#include "jabber_list.h" +#include "resource.h" +#include "tlen_avatar.h" + +JABBER_FIELD_MAP tlenFieldGender[] = { + { 1, _T("Male") }, + { 2, _T("Female") }, + { 0, NULL } +}; +JABBER_FIELD_MAP tlenFieldLookfor[] = { + { 1, _T("Somebody to talk") }, + { 2, _T("Friendship") }, + { 3, _T("Flirt/romance") }, + { 4, _T("Love") }, + { 5, _T("Nothing") }, + { 0, NULL } +}; +JABBER_FIELD_MAP tlenFieldStatus[] = { + { 1, _T("All") }, + { 2, _T("Available") }, + { 3, _T("Free for chat") }, + { 0, NULL } +}; +JABBER_FIELD_MAP tlenFieldOccupation[] = { + { 1, _T("Student") }, + { 2, _T("College student") }, + { 3, _T("Farmer") }, + { 4, _T("Manager") }, + { 5, _T("Specialist") }, + { 6, _T("Clerk") }, + { 7, _T("Unemployed") }, + { 8, _T("Pensioner") }, + { 9, _T("Housekeeper") }, + { 10, _T("Teacher") }, + { 11, _T("Doctor") }, + { 12, _T("Other") }, + { 0, NULL } +}; +JABBER_FIELD_MAP tlenFieldPlan[] = { + { 1, _T("I'd like to go downtown") }, + { 2, _T("I'd like to go to the cinema") }, + { 3, _T("I'd like to take a walk") }, + { 4, _T("I'd like to go to the disco") }, + { 5, _T("I'd like to go on a blind date") }, + { 6, _T("Waiting for suggestion") }, + { 0, NULL } +}; + +static INT_PTR CALLBACK TlenUserInfoDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +static void InitComboBox(HWND hwndCombo, JABBER_FIELD_MAP *fieldMap) +{ + int i, n; + + n = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)_T("")); + SendMessage(hwndCombo, CB_SETITEMDATA, n, 0); + SendMessage(hwndCombo, CB_SETCURSEL, n, 0); + for(i=0;;i++) { + if (fieldMap[i].name == NULL) + break; + n = SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM) TranslateTS(fieldMap[i].name)); + SendMessage(hwndCombo, CB_SETITEMDATA, n, fieldMap[i].id); + } +} + +static void FetchField(HWND hwndDlg, UINT idCtrl, char *fieldName, char **str, int *strSize) +{ + char text[512]; + char *localFieldName, *localText; + + if (hwndDlg==NULL || fieldName==NULL || str==NULL || strSize==NULL) + return; + GetDlgItemTextA(hwndDlg, idCtrl, text, sizeof(text)); + if (text[0]) { + if ((localFieldName=JabberTextEncode(fieldName)) != NULL) { + if ((localText=JabberTextEncode(text)) != NULL) { + JabberStringAppend(str, strSize, "<%s>%s", localFieldName, localText, localFieldName); + mir_free(localText); + } + mir_free(localFieldName); + } + } +} + +static void FetchCombo(HWND hwndDlg, UINT idCtrl, char *fieldName, char **str, int *strSize) +{ + int value; + char *localFieldName; + + if (hwndDlg==NULL || fieldName==NULL || str==NULL || strSize==NULL) + return; + value = (int) SendDlgItemMessage(hwndDlg, idCtrl, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, idCtrl, CB_GETCURSEL, 0, 0), 0); + if (value > 0) { + if ((localFieldName=JabberTextEncode(fieldName)) != NULL) { + JabberStringAppend(str, strSize, "<%s>%d", localFieldName, value, localFieldName); + mir_free(localFieldName); + } + } +} + + +int TlenUserInfoInit(void *ptr, WPARAM wParam, LPARAM lParam) +{ + char *szProto; + HANDLE hContact; + OPTIONSDIALOGPAGE odp = {0}; + TlenProtocol *proto = (TlenProtocol *)ptr; + + if (!CallService(MS_PROTO_ISPROTOCOLLOADED, 0, (LPARAM) proto->iface.m_szModuleName)) + return 0; + hContact = (HANDLE) lParam; + szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if ((szProto!=NULL && !strcmp(szProto, proto->iface.m_szModuleName)) || !lParam) { + odp.cbSize = sizeof(odp); + odp.hInstance = hInst; + odp.flags = ODPF_TCHAR; + odp.pfnDlgProc = TlenUserInfoDlgProc; + odp.position = -2000000000; + odp.pszTemplate = ((HANDLE)lParam!=NULL) ? MAKEINTRESOURCEA(IDD_USER_INFO):MAKEINTRESOURCEA(IDD_USER_VCARD); + odp.ptszTitle = (hContact != NULL) ? TranslateT("Account") : proto->iface.m_tszUserName; + odp.dwInitParam = (LPARAM)proto; + CallService(MS_USERINFO_ADDPAGE, wParam, (LPARAM) &odp); + + } + if (!lParam && proto->isOnline) { + CCSDATA ccs = {0}; + JabberGetInfo(ptr, 0, (LPARAM) &ccs); + } + return 0; +} + +typedef struct { + TlenProtocol *proto; + HANDLE hContact; +}TLENUSERINFODLGDATA; + + +static INT_PTR CALLBACK TlenUserInfoDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TLENUSERINFODLGDATA *data = (TLENUSERINFODLGDATA *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + + data = (TLENUSERINFODLGDATA*)mir_alloc(sizeof(TLENUSERINFODLGDATA)); + data->hContact = (HANDLE) lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)data); + // lParam is hContact + TranslateDialogDefault(hwndDlg); + InitComboBox(GetDlgItem(hwndDlg, IDC_GENDER), tlenFieldGender); + InitComboBox(GetDlgItem(hwndDlg, IDC_OCCUPATION), tlenFieldOccupation); + InitComboBox(GetDlgItem(hwndDlg, IDC_LOOKFOR), tlenFieldLookfor); + + return TRUE; + case WM_TLEN_REFRESH: + { + DBVARIANT dbv; + char *jid; + int i; + JABBER_LIST_ITEM *item; + + SetDlgItemText(hwndDlg, IDC_INFO_JID, _T("")); + SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, _T("")); + SetFocus(GetDlgItem(hwndDlg, IDC_STATIC)); + + if (!DBGetContactSettingTString(data->hContact, data->proto->iface.m_szModuleName, "FirstName", &dbv)) { + SetDlgItemText(hwndDlg, IDC_FIRSTNAME, dbv.ptszVal); + DBFreeVariant(&dbv); + } else SetDlgItemText(hwndDlg, IDC_FIRSTNAME, _T("")); + if (!DBGetContactSettingTString(data->hContact, data->proto->iface.m_szModuleName, "LastName", &dbv)) { + SetDlgItemText(hwndDlg, IDC_LASTNAME, dbv.ptszVal); + DBFreeVariant(&dbv); + } else SetDlgItemText(hwndDlg, IDC_LASTNAME, _T("")); + if (!DBGetContactSettingTString(data->hContact, data->proto->iface.m_szModuleName, "Nick", &dbv)) { + SetDlgItemText(hwndDlg, IDC_NICKNAME, dbv.ptszVal); + DBFreeVariant(&dbv); + } else SetDlgItemText(hwndDlg, IDC_NICKNAME, _T("")); + if (!DBGetContactSettingTString(data->hContact, data->proto->iface.m_szModuleName, "e-mail", &dbv)) { + SetDlgItemText(hwndDlg, IDC_EMAIL, dbv.ptszVal); + DBFreeVariant(&dbv); + } else SetDlgItemText(hwndDlg, IDC_EMAIL, _T("")); + if (!DBGetContactSetting(data->hContact, data->proto->iface.m_szModuleName, "Age", &dbv)) { + SetDlgItemInt(hwndDlg, IDC_AGE, dbv.wVal, FALSE); + DBFreeVariant(&dbv); + } else SetDlgItemText(hwndDlg, IDC_AGE, _T("")); + if (!DBGetContactSettingTString(data->hContact, data->proto->iface.m_szModuleName, "City", &dbv)) { + SetDlgItemText(hwndDlg, IDC_CITY, dbv.ptszVal); + DBFreeVariant(&dbv); + } else SetDlgItemText(hwndDlg, IDC_CITY, _T("")); + if (!DBGetContactSettingTString(data->hContact, data->proto->iface.m_szModuleName, "School", &dbv)) { + SetDlgItemText(hwndDlg, IDC_SCHOOL, dbv.ptszVal); + DBFreeVariant(&dbv); + } else SetDlgItemText(hwndDlg, IDC_SCHOOL, _T("")); + switch (DBGetContactSettingByte(data->hContact, data->proto->iface.m_szModuleName, "Gender", '?')) { + case 'M': + SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 1, 0); + SetDlgItemText(hwndDlg, IDC_GENDER_TEXT, TranslateTS(tlenFieldGender[0].name)); + break; + case 'F': + SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 2, 0); + SetDlgItemText(hwndDlg, IDC_GENDER_TEXT, TranslateTS(tlenFieldGender[1].name)); + break; + default: + SendDlgItemMessage(hwndDlg, IDC_GENDER, CB_SETCURSEL, 0, 0); + SetDlgItemText(hwndDlg, IDC_GENDER_TEXT, _T("")); + break; + } + i = DBGetContactSettingWord(data->hContact, data->proto->iface.m_szModuleName, "Occupation", 0); + if (i>0 && i<13) { + SetDlgItemText(hwndDlg, IDC_OCCUPATION_TEXT, TranslateTS(tlenFieldOccupation[i-1].name)); + SendDlgItemMessage(hwndDlg, IDC_OCCUPATION, CB_SETCURSEL, i, 0); + } else { + SetDlgItemText(hwndDlg, IDC_OCCUPATION_TEXT, _T("")); + SendDlgItemMessage(hwndDlg, IDC_OCCUPATION, CB_SETCURSEL, 0, 0); + } + i = DBGetContactSettingWord(data->hContact, data->proto->iface.m_szModuleName, "LookingFor", 0); + if (i>0 && i<6) { + SetDlgItemText(hwndDlg, IDC_LOOKFOR_TEXT, TranslateTS(tlenFieldLookfor[i-1].name)); + SendDlgItemMessage(hwndDlg, IDC_LOOKFOR, CB_SETCURSEL, i, 0); + } else { + SetDlgItemText(hwndDlg, IDC_LOOKFOR_TEXT, _T("")); + SendDlgItemMessage(hwndDlg, IDC_LOOKFOR, CB_SETCURSEL, 0, 0); + } + i = DBGetContactSettingWord(data->hContact, data->proto->iface.m_szModuleName, "VoiceChat", 0); + CheckDlgButton(hwndDlg, IDC_VOICECONVERSATIONS, i); + i = DBGetContactSettingWord(data->hContact, data->proto->iface.m_szModuleName, "PublicStatus", 0); + CheckDlgButton(hwndDlg, IDC_PUBLICSTATUS, i); + if (!DBGetContactSetting(data->hContact, data->proto->iface.m_szModuleName, "jid", &dbv)) { + jid = JabberTextDecode(dbv.pszVal); + SetDlgItemTextA(hwndDlg, IDC_INFO_JID, jid); + mir_free(jid); + jid = dbv.pszVal; + if (data->proto->isOnline) { + if ((item=JabberListGetItemPtr(data->proto, LIST_ROSTER, jid)) != NULL) { + switch (item->subscription) { + case SUB_BOTH: + SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, TranslateT("both")); + break; + case SUB_TO: + SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, TranslateT("to")); + break; + case SUB_FROM: + SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, TranslateT("from")); + break; + default: + SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, TranslateT("none")); + break; + } + SetDlgItemTextA(hwndDlg, IDC_SOFTWARE, item->software); + SetDlgItemTextA(hwndDlg, IDC_VERSION, item->version); + SetDlgItemTextA(hwndDlg, IDC_SYSTEM, item->system); + } else { + SetDlgItemText(hwndDlg, IDC_SUBSCRIPTION, TranslateT("not on roster")); + } + } + DBFreeVariant(&dbv); + } + } + break; + case WM_NOTIFY: + switch (((LPNMHDR)lParam)->idFrom) { + case 0: + switch (((LPNMHDR)lParam)->code) { + case PSN_INFOCHANGED: + { + HANDLE hContact = (HANDLE) ((LPPSHNOTIFY) lParam)->lParam; + SendMessage(hwndDlg, WM_TLEN_REFRESH, 0, (LPARAM) hContact); + } + break; + case PSN_PARAMCHANGED: + { + data->proto = ( TlenProtocol* )(( LPPSHNOTIFY )lParam )->lParam; + SendMessage(hwndDlg, WM_TLEN_REFRESH, 0, 0); + } + } + break; + } + break; + case WM_COMMAND: + if (LOWORD(wParam)==IDC_SAVE && HIWORD(wParam)==BN_CLICKED) { + char *str = NULL; + int strSize; + JabberStringAppend(&str, &strSize, "", JabberSerialNext(data->proto)); + FetchField(hwndDlg, IDC_FIRSTNAME, "first", &str, &strSize); + FetchField(hwndDlg, IDC_LASTNAME, "last", &str, &strSize); + FetchField(hwndDlg, IDC_NICKNAME, "nick", &str, &strSize); + FetchField(hwndDlg, IDC_EMAIL, "email", &str, &strSize); + FetchCombo(hwndDlg, IDC_GENDER, "s", &str, &strSize); + FetchField(hwndDlg, IDC_AGE, "b", &str, &strSize); + FetchField(hwndDlg, IDC_CITY, "c", &str, &strSize); + FetchCombo(hwndDlg, IDC_OCCUPATION, "j", &str, &strSize); + FetchField(hwndDlg, IDC_SCHOOL, "e", &str, &strSize); + FetchCombo(hwndDlg, IDC_LOOKFOR, "r", &str, &strSize); + JabberStringAppend(&str, &strSize, "%d", IsDlgButtonChecked(hwndDlg, IDC_VOICECONVERSATIONS) ? 1 : 0); + JabberStringAppend(&str, &strSize, "%d", IsDlgButtonChecked(hwndDlg, IDC_PUBLICSTATUS) ? 1 : 0); + JabberStringAppend(&str, &strSize, ""); + JabberSend(data->proto, "%s", str); + mir_free(str); + JabberGetInfo((PROTO_INTERFACE *)data->proto, NULL, 0); + } + break; + case WM_DESTROY: + mir_free(data); + break; + } + return FALSE; +} diff --git a/plugins/!NotAdopted/Tlen/tlen_voice.c b/plugins/!NotAdopted/Tlen/tlen_voice.c new file mode 100644 index 0000000000..4c4868152c --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_voice.c @@ -0,0 +1,1122 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "jabber.h" +#include +#include +#include +#include +#include +#include +//#include +#include "resource.h" +#include "jabber_list.h" +#include "tlen_voice.h" +#include "tlen_p2p_old.h" +#include "tlen_file.h" + +static int MODE_FREQUENCY[]= {0, 0, 8000, 11025, 22050, 44100}; +static int MODE_FRAME_SIZE[]= {0, 0, 5, 5, 10, 25}; +static int FRAMES_AVAILABLE_MAX_LIMIT = 2; +static int VU_METER_HEIGHT = 64; +static int VU_METER_WIDTH = 20; +static int VU_METER_LEVELS = 16; +static HBITMAP vuMeterBitmaps[100]; + +static void TlenVoiceReceiveParse(TLEN_FILE_TRANSFER *ft); +static void TlenVoiceSendParse(TLEN_FILE_TRANSFER *ft); +static void TlenVoiceReceivingConnection(HANDLE hNewConnection, DWORD dwRemoteIP, void * pExtra); + +static void CALLBACK TlenVoicePlaybackCallback(HWAVEOUT hwo, UINT uMsg, DWORD* dwInstance, DWORD dwParam1, DWORD dwParam2) +{ + if (uMsg == WOM_DONE) { + TLEN_VOICE_CONTROL *control = (TLEN_VOICE_CONTROL *) dwInstance; + waveOutUnprepareHeader(hwo, (WAVEHDR *) dwParam1, sizeof(WAVEHDR)); + if (control->proto->framesAvailableForPlayback > 0) { + control->proto->framesAvailableForPlayback--; + } +// playbackControl->waveHeaders[playbackControl->waveHeadersPos].dwFlags = WHDR_DONE; +// playbackControl->waveHeaders[playbackControl->waveHeadersPos].lpData = (char *) (playbackControl->waveData + playbackControl->waveHeadersPos * playbackControl->waveFrameSize); +// playbackControl->waveHeaders[playbackControl->waveHeadersPos].dwBufferLength = playbackControl->waveFrameSize * 2; +// waveOutPrepareHeader(playbackControl->hWaveOut, &playbackControl->waveHeaders[playbackControl->waveHeadersPos], sizeof(WAVEHDR)); +// waveOutWrite(playbackControl->hWaveOut, &playbackControl->waveHeaders[playbackControl->waveHeadersPos], sizeof(WAVEHDR)); + + } +} + +static DWORD WINAPI TlenVoiceRecordingThreadProc(TLEN_VOICE_CONTROL *control) +{ + MSG msg; + HWAVEIN hWaveIn; + WAVEHDR *hWaveHdr; + control->isRunning = 1; + control->stopThread = 0; + while (TRUE) { + GetMessage(&msg,NULL,0,0); + if (msg.message == MM_WIM_DATA) { +// JabberLog("recording thread running...%d", msg.message); + hWaveIn = (HWAVEIN) msg.wParam; + hWaveHdr = (WAVEHDR *) msg.lParam; + waveInUnprepareHeader(hWaveIn, hWaveHdr, sizeof(WAVEHDR)); + if (hWaveHdr->dwBytesRecorded>0 && !control->bDisable) { + control->recordingData = (short *)hWaveHdr->lpData; + TlenVoiceSendParse(control->ft); + } + if (!control->stopThread) { + waveInPrepareHeader(hWaveIn, &control->waveHeaders[control->waveHeadersPos], sizeof(WAVEHDR)); + waveInAddBuffer(hWaveIn, &control->waveHeaders[control->waveHeadersPos], sizeof(WAVEHDR)); + control->waveHeadersPos = (control->waveHeadersPos +1) % control->waveHeadersNum; + } + } + else if (msg.message == MM_WIM_CLOSE) { + break; + } + } + control->isRunning = 0; + JabberLog(control->proto, "recording thread ended..."); + return 0; +} + + +/*static void CALLBACK TlenVoiceRecordingCallback(HWAVEIN hwi, UINT uMsg, DWORD* dwInstance, DWORD dwParam1, DWORD dwParam2) +{ + if (uMsg == WIM_DATA) { + TLEN_VOICE_CONTROL *control = (TLEN_VOICE_CONTROL *) dwInstance; + if (control->waveHeaders[control->waveHeadersPos].dwBytesRecorded>0) { + control->recordingData = (short *)control->waveHeaders[control->waveHeadersPos].lpData; + TlenVoiceSendParse(control->ft); + } + waveInAddBuffer(control->hWaveIn, &control->waveHeaders[control->waveHeadersPos], sizeof(WAVEHDR)); + control->waveHeadersPos = (control->waveHeadersPos +1) % control->waveHeadersNum; + } +}*/ + +static int TlenVoicePlaybackStart(TLEN_VOICE_CONTROL *control) +{ + WAVEFORMATEX wfm; + MMRESULT mmres; + int i, j; + int iNumDevs, iSelDev; + WAVEOUTCAPS wic; + + memset(&wfm, 0, sizeof(wfm)); + wfm.cbSize = sizeof(WAVEFORMATEX); + wfm.nChannels = 1; + wfm.wBitsPerSample = 16; + wfm.nSamplesPerSec = MODE_FREQUENCY[control->codec]; + wfm.nAvgBytesPerSec = wfm.nSamplesPerSec * wfm.nChannels * wfm.wBitsPerSample/8; + wfm.nBlockAlign = 2 * wfm.nChannels; + wfm.wFormatTag = WAVE_FORMAT_PCM; + + control->waveMode = 0; + control->waveFrameSize = MODE_FRAME_SIZE[control->codec] * 160 * wfm.nChannels;// * wfm.wBitsPerSample / 8; + control->waveHeadersPos = 0; + control->waveHeadersNum = FRAMES_AVAILABLE_MAX_LIMIT + 2; + + j = DBGetContactSettingWord(NULL, control->proto->iface.m_szModuleName, "VoiceDeviceOut", 0); + iSelDev = WAVE_MAPPER; + if (j!=0) { + iNumDevs = waveOutGetNumDevs(); + for (i = 0; i < iNumDevs; i++) { + if (!waveOutGetDevCaps(i, &wic, sizeof(WAVEOUTCAPS))) { + if (wic.dwFormats != 0) { + j--; + if (j == 0) { + iSelDev = i; + break; + } + } + } + } + } + if (!waveOutGetDevCaps(iSelDev, &wic, sizeof(WAVEOUTCAPS))) { + JabberLog(control->proto, "Playback device ID #%u: %s\r\n", iSelDev, wic.szPname); + } + + mmres = waveOutOpen(&control->hWaveOut, iSelDev, &wfm, (DWORD) &TlenVoicePlaybackCallback, (DWORD) control, CALLBACK_FUNCTION); + if (mmres!=MMSYSERR_NOERROR) { + JabberLog(control->proto, "TlenVoiceStart FAILED!"); + return 1; + } + control->waveData = (short *)mir_alloc(control->waveHeadersNum * control->waveFrameSize * 2); + memset(control->waveData, 0, control->waveHeadersNum * control->waveFrameSize * 2); + control->waveHeaders = (WAVEHDR *)mir_alloc(control->waveHeadersNum * sizeof(WAVEHDR)); + JabberLog(control->proto, "TlenVoiceStart OK!"); + return 0; +} + + +static int TlenVoiceRecordingStart(TLEN_VOICE_CONTROL *control) +{ + WAVEFORMATEX wfm; + MMRESULT mmres; + int i, j; + int iNumDevs, iSelDev; + WAVEINCAPS wic; + + memset(&wfm, 0, sizeof(wfm)); + wfm.cbSize = sizeof(WAVEFORMATEX); + wfm.nChannels = 1; + wfm.wBitsPerSample = 16; + wfm.nSamplesPerSec = MODE_FREQUENCY[control->codec]; + wfm.nAvgBytesPerSec = wfm.nSamplesPerSec * wfm.nChannels * wfm.wBitsPerSample/8; + wfm.nBlockAlign = 2 * wfm.nChannels; + wfm.wFormatTag = WAVE_FORMAT_PCM; + + + control->waveMode = 0; +// control->isRunning = 1; + control->waveFrameSize = MODE_FRAME_SIZE[control->codec] * 160 * wfm.nChannels;// * wfm.wBitsPerSample / 8; + control->waveHeadersPos = 0; + control->waveHeadersNum = 2; + + control->hThread = CreateThread( NULL, + 0, + (LPTHREAD_START_ROUTINE)TlenVoiceRecordingThreadProc, + control, + 0, + (LPDWORD)&control->threadID); + + + SetThreadPriority(control->hThread, THREAD_PRIORITY_ABOVE_NORMAL); + + j = DBGetContactSettingWord(NULL, control->proto->iface.m_szModuleName, "VoiceDeviceIn", 0); + iSelDev = WAVE_MAPPER; + if (j!=0) { + iNumDevs = waveInGetNumDevs(); + for (i = 0; i < iNumDevs; i++) { + if (!waveInGetDevCaps(i, &wic, sizeof(WAVEINCAPS))) { + if (wic.dwFormats != 0) { + j--; + if (j == 0) { + iSelDev = i; + break; + } + } + } + } + } + if (!waveInGetDevCaps(iSelDev, &wic, sizeof(WAVEINCAPS))) { + JabberLog(control->proto, "Recording device ID #%u: %s\r\n", iSelDev, wic.szPname); + } + + mmres = waveInOpen(&control->hWaveIn, iSelDev, &wfm, (DWORD) control->threadID, 0, CALLBACK_THREAD); +// mmres = waveInOpen(&control->hWaveIn, 3, &wfm, (DWORD) &TlenVoiceRecordingCallback, (DWORD) control, CALLBACK_FUNCTION); + if (mmres!=MMSYSERR_NOERROR) { + PostThreadMessage(control->threadID, WIM_CLOSE, 0, 0); + JabberLog(control->proto, "TlenVoiceStart FAILED %d!", mmres); + return 1; + } + control->waveData = (short *)mir_alloc(control->waveHeadersNum * control->waveFrameSize * 2); + memset(control->waveData, 0, control->waveHeadersNum * control->waveFrameSize * 2); + control->waveHeaders = (WAVEHDR *)mir_alloc(control->waveHeadersNum * sizeof(WAVEHDR)); + for (i=0;iwaveHeadersNum;i++) { + control->waveHeaders[i].dwFlags = 0;//WHDR_DONE; + control->waveHeaders[i].lpData = (char *) (control->waveData + i * control->waveFrameSize); + control->waveHeaders[i].dwBufferLength = control->waveFrameSize *2; + mmres = waveInPrepareHeader(control->hWaveIn, &control->waveHeaders[i], sizeof(WAVEHDR)); + if (mmres!=MMSYSERR_NOERROR) { + waveInClose(control->hWaveIn); +// PostThreadMessage(control->threadID, WIM_CLOSE, 0, 0); + JabberLog(control->proto, "TlenVoiceStart FAILED #2!"); + return 1; + } + } + for (i=0;iwaveHeadersNum;i++) { + waveInAddBuffer(control->hWaveIn, &control->waveHeaders[i], sizeof(WAVEHDR)); + } + waveInStart(control->hWaveIn); + JabberLog(control->proto, "TlenVoiceRStart OK!"); + return 0; +} + + +static TLEN_VOICE_CONTROL *TlenVoiceCreateVC(TlenProtocol *proto, int codec) +{ + TLEN_VOICE_CONTROL *vc; + vc = (TLEN_VOICE_CONTROL *) mir_alloc(sizeof (TLEN_VOICE_CONTROL)); + memset(vc, 0, sizeof(TLEN_VOICE_CONTROL)); + vc->gsmstate = gsm_create(); + vc->codec = codec; + vc->proto = proto; + return vc; +} +static void TlenVoiceFreeVc(TLEN_VOICE_CONTROL *vc) +{ + int i; + JabberLog(vc->proto, "-> TlenVoiceFreeVc"); + vc->stopThread = 1; + PostThreadMessage(vc->threadID, MM_WIM_CLOSE, 0, 0); + while(vc->isRunning) { + Sleep(50); + } + if (vc->hThread!=NULL) CloseHandle(vc->hThread); + if (vc->hWaveIn) { + for (i=0;iwaveHeadersNum;i++) { + while(waveInUnprepareHeader(vc->hWaveIn, &vc->waveHeaders[i], sizeof(WAVEHDR)) == WAVERR_STILLPLAYING) { + Sleep(50); + } + } + while(waveInClose(vc->hWaveIn) == WAVERR_STILLPLAYING) { + Sleep(50); + } + } + if (vc->hWaveOut) { + for (i=0;iwaveHeadersNum;i++) { + while(waveOutUnprepareHeader(vc->hWaveOut, &vc->waveHeaders[i], sizeof(WAVEHDR)) == WAVERR_STILLPLAYING) { + Sleep(50); + } + } + while(waveOutClose(vc->hWaveOut) == WAVERR_STILLPLAYING) { + Sleep(50); + } + } + if (vc->waveData) mir_free(vc->waveData); + if (vc->waveHeaders) mir_free(vc->waveHeaders); + if (vc->gsmstate) gsm_release(vc->gsmstate); + JabberLog(vc->proto, "<- TlenVoiceFreeVc"); + mir_free(vc); +} + +static void TlenVoiceCrypt(char *buffer, int len) +{ + int i, j, k; + j = 0x71; + for (i=0;iproto, "Thread started: type=file_receive server='%s' port='%d'", ft->hostName, ft->wPort); + nloc.cbSize = NETLIBOPENCONNECTION_V1_SIZE;//sizeof(NETLIBOPENCONNECTION); + nloc.szHost = ft->hostName; + nloc.wPort = ft->wPort; + nloc.flags = 0; + SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Connecting...")); +// ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, ft, 0); + s = (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, (WPARAM) ft->proto->hNetlibUser, (LPARAM) &nloc); + if (s != NULL) { + ft->s = s; + JabberLog(ft->proto, "Entering file receive loop"); + TlenP2PEstablishOutgoingConnection(ft, FALSE); + if (ft->state!=FT_ERROR) { + ft->proto->playbackControl = NULL; + ft->proto->recordingControl = TlenVoiceCreateVC(ft->proto, 3); + ft->proto->recordingControl->ft = ft; + TlenVoiceRecordingStart(ft->proto->recordingControl); + while (ft->state!=FT_DONE && ft->state!=FT_ERROR) { + TlenVoiceReceiveParse(ft); + } + TlenVoiceFreeVc(ft->proto->recordingControl); + ft->proto->playbackControl = NULL; + ft->proto->recordingControl = NULL; + } + if (ft->s) { + Netlib_CloseHandle(s); + } + ft->s = NULL; + } else { + JabberLog(ft->proto, "Connection failed - receiving as server"); + ft->pfnNewConnectionV2 = TlenVoiceReceivingConnection; + s = TlenP2PListen(ft); + if (s != NULL) { + HANDLE hEvent; + char *nick; + SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Waiting for connection...")); + ft->s = s; + hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + ft->hFileEvent = hEvent; + ft->currentFile = 0; + ft->state = FT_CONNECTING; + nick = JabberNickFromJID(ft->jid); + JabberSend(ft->proto, "", nick, ft->iqId, ft->localName, ft->wLocalPort); + mir_free(nick); + JabberLog(ft->proto, "Waiting for the file to be received..."); + WaitForSingleObject(hEvent, INFINITE); + ft->hFileEvent = NULL; + CloseHandle(hEvent); + JabberLog(ft->proto, "Finish all files"); + Netlib_CloseHandle(s); + } else { + ft->state = FT_ERROR; + } + } + JabberListRemove(ft->proto, LIST_VOICE, ft->iqId); + if (ft->state==FT_DONE) { + SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Finished...")); + //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); + } else { + char *nick; + nick = JabberNickFromJID(ft->jid); + JabberSend(ft->proto, "", nick, ft->iqId); + mir_free(nick); + SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Error...")); + //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); + } + JabberLog(ft->proto, "Thread ended: type=file_receive server='%s'", ft->hostName); + + TlenP2PFreeFileTransfer(ft); +} + +static void TlenVoiceReceivingConnection(JABBER_SOCKET hConnection, DWORD dwRemoteIP, void * pExtra) +{ + JABBER_SOCKET slisten; + TLEN_FILE_TRANSFER *ft; + TlenProtocol *proto = (TlenProtocol *)pExtra; + + ft = TlenP2PEstablishIncomingConnection(proto, hConnection, LIST_VOICE, FALSE); + if (ft != NULL) { + slisten = ft->s; + ft->s = hConnection; + JabberLog(ft->proto, "Set ft->s to %d (saving %d)", hConnection, slisten); + JabberLog(ft->proto, "Entering send loop for this file connection... (ft->s is hConnection)"); + proto->playbackControl = NULL; + proto->recordingControl = TlenVoiceCreateVC(proto, 3); + proto->recordingControl->ft = ft; + TlenVoiceRecordingStart(proto->recordingControl); + while (ft->state!=FT_DONE && ft->state!=FT_ERROR) { + TlenVoiceReceiveParse(ft); + } + TlenVoiceFreeVc(proto->recordingControl); + proto->playbackControl = NULL; + proto->recordingControl = NULL; + if (ft->state==FT_DONE) { + SetDlgItemText(proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Finished...")); +// ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); + } else { +// ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); + SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Error...")); + } + JabberLog(ft->proto, "Closing connection for this file transfer... (ft->s is now hBind)"); + ft->s = slisten; + JabberLog(ft->proto, "ft->s is restored to %d", ft->s); + } + Netlib_CloseHandle(hConnection); + if (ft!=NULL && ft->hFileEvent != NULL) + SetEvent(ft->hFileEvent); +} + +static void TlenVoiceReceiveParse(TLEN_FILE_TRANSFER *ft) +{ + char *statusTxt; + int i, j; + char *p; + float val; + TLEN_FILE_PACKET *packet; + packet = TlenP2PPacketReceive(ft->s); + if (packet != NULL) { + statusTxt = " Unknown packet "; + p = packet->packet; + if (packet->type == TLEN_VOICE_PACKET) { + short *out; + int codec, chunkNum; + statusTxt = " OK "; + TlenVoiceCrypt(packet->packet+4, packet->len-4); + codec = *((int *)packet->packet); + if (codec<2 || codec>5) { + statusTxt = " Unknown codec "; + } else { + if (ft->proto->playbackControl == NULL) { + ft->proto->playbackControl = TlenVoiceCreateVC(ft->proto, codec); + TlenVoicePlaybackStart(ft->proto->playbackControl); + ft->proto->framesAvailableForPlayback = 0; + ft->proto->availOverrunValue = 0; + } else if (ft->proto->playbackControl->codec != codec) { + TlenVoiceFreeVc(ft->proto->playbackControl); + ft->proto->playbackControl = TlenVoiceCreateVC(ft->proto, codec); + TlenVoicePlaybackStart(ft->proto->playbackControl); + ft->proto->framesAvailableForPlayback = 0; + ft->proto->availOverrunValue = 0; + } + if (!ft->proto->playbackControl->bDisable) { + ft->proto->playbackControl->waveHeaders[ft->proto->playbackControl->waveHeadersPos].dwFlags = WHDR_DONE; + ft->proto->playbackControl->waveHeaders[ft->proto->playbackControl->waveHeadersPos].lpData = (char *) (ft->proto->playbackControl->waveData + ft->proto->playbackControl->waveHeadersPos * ft->proto->playbackControl->waveFrameSize); + ft->proto->playbackControl->waveHeaders[ft->proto->playbackControl->waveHeadersPos].dwBufferLength = ft->proto->playbackControl->waveFrameSize * 2; + /* + if (availPlayback == 0) { + statusTxt = "!! Buffer is empty !!"; + availPlayback++; + waveOutPrepareHeader(playbackControl->hWaveOut, &playbackControl->waveHeaders[playbackControl->waveHeadersPos], sizeof(WAVEHDR)); + waveOutWrite(playbackControl->hWaveOut, &playbackControl->waveHeaders[playbackControl->waveHeadersPos], sizeof(WAVEHDR)); + playbackControl->waveHeadersPos = (playbackControl->waveHeadersPos +1) % playbackControl->waveHeadersNum; + playbackControl->waveHeaders[playbackControl->waveHeadersPos].dwFlags = WHDR_DONE; + playbackControl->waveHeaders[playbackControl->waveHeadersPos].lpData = (char *) (playbackControl->waveData + playbackControl->waveHeadersPos * playbackControl->waveFrameSize); + playbackControl->waveHeaders[playbackControl->waveHeadersPos].dwBufferLength = playbackControl->waveFrameSize * 2; + } + */ + chunkNum = min(MODE_FRAME_SIZE[codec], (int)(packet->len - 4) / 33); + out = (short *)ft->proto->playbackControl->waveHeaders[ft->proto->playbackControl->waveHeadersPos].lpData; + for (i=0; iproto->playbackControl->gsmstate->gsmFrame[j] = packet->packet[i*33 +j +4]; + } + gsm_decode(ft->proto->playbackControl->gsmstate, out); + out += 160; + } + out = (short *)ft->proto->playbackControl->waveHeaders[ft->proto->playbackControl->waveHeadersPos].lpData; + val = 0; + for (i=0; i VU_METER_LEVELS - 1 ) { + j = VU_METER_LEVELS - 1; + } else if (j<0) { + j = 0; + } + ft->proto->playbackControl->vuMeter = j; + ft->proto->playbackControl->bytesSum += 8 + packet->len; + /* Simple logic to avoid huge delays. If a delay is detected a frame is not played */ + j = ft->proto->availOverrunValue > 0 ? -1 : 0; + while (ft->proto->framesAvailableForPlayback > FRAMES_AVAILABLE_MAX_LIMIT) { + j = 1; + SleepEx(5, FALSE); + } + ft->proto->availOverrunValue += j; + /* 40 frames - 800ms/8kHz */ + if (ft->proto->availOverrunValue < 40) { + ft->proto->framesAvailableForPlayback++; + waveOutPrepareHeader(ft->proto->playbackControl->hWaveOut, &ft->proto->playbackControl->waveHeaders[ft->proto->playbackControl->waveHeadersPos], sizeof(WAVEHDR)); + waveOutWrite(ft->proto->playbackControl->hWaveOut, &ft->proto->playbackControl->waveHeaders[ft->proto->playbackControl->waveHeadersPos], sizeof(WAVEHDR)); + ft->proto->playbackControl->waveHeadersPos = (ft->proto->playbackControl->waveHeadersPos +1) % ft->proto->playbackControl->waveHeadersNum; + } else { + ft->proto->availOverrunValue -= 10; + statusTxt = "!! Skipping frame !!"; + } + } + } + } + { + char ttt[2048]; + sprintf(ttt, "%s %d %d ", statusTxt, ft->proto->framesAvailableForPlayback, ft->proto->availOverrunValue); + SetDlgItemTextA(ft->proto->voiceDlgHWND, IDC_STATUS, ttt); + } + TlenP2PPacketFree(packet); + } + else { + if (ft->proto->playbackControl!=NULL) { + TlenVoiceFreeVc(ft->proto->playbackControl); + ft->proto->playbackControl = NULL; + } + ft->state = FT_ERROR; + } +} + + +void __cdecl TlenVoiceSendingThread(TLEN_FILE_TRANSFER *ft) +{ + JABBER_SOCKET s = NULL; + HANDLE hEvent; + char *nick; + + JabberLog(ft->proto, "Thread started: type=voice_send"); + ft->pfnNewConnectionV2 = TlenVoiceReceivingConnection; + s = TlenP2PListen(ft); + if (s != NULL) { + SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Waiting for connection...")); + //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, ft, 0); + ft->s = s; + //JabberLog("ft->s = %d", s); + //JabberLog("fileCount = %d", ft->fileCount); + + hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + ft->hFileEvent = hEvent; + ft->currentFile = 0; + ft->state = FT_CONNECTING; + + nick = JabberNickFromJID(ft->jid); + JabberSend(ft->proto, "", nick, ft->iqId, ft->localName, ft->wLocalPort); + mir_free(nick); + JabberLog(ft->proto, "Waiting for the voice data to be sent..."); + WaitForSingleObject(hEvent, INFINITE); + ft->hFileEvent = NULL; + CloseHandle(hEvent); + JabberLog(ft->proto, "Finish voice"); + Netlib_CloseHandle(s); + ft->s = NULL; + JabberLog(ft->proto, "ft->s is NULL"); + + if (ft->state == FT_SWITCH) { + NETLIBOPENCONNECTION nloc; + JABBER_SOCKET s; + JabberLog(ft->proto, "Sending as client..."); + ft->state = FT_CONNECTING; + nloc.cbSize = NETLIBOPENCONNECTION_V1_SIZE;//sizeof(NETLIBOPENCONNECTION); + nloc.szHost = ft->hostName; + nloc.wPort = ft->wPort; + nloc.flags = 0; + s = (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, (WPARAM) ft->proto->hNetlibUser, (LPARAM) &nloc); + if (s != NULL) { + SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Connecting...")); + //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, ft, 0); + ft->s = s; + TlenP2PEstablishOutgoingConnection(ft, FALSE); + if (ft->state!=FT_ERROR) { + JabberLog(ft->proto, "Entering send loop for this file connection..."); + ft->proto->playbackControl = NULL; + ft->proto->recordingControl = TlenVoiceCreateVC(ft->proto, 3); + ft->proto->recordingControl->ft = ft; + TlenVoiceRecordingStart(ft->proto->recordingControl); + while (ft->state!=FT_DONE && ft->state!=FT_ERROR) { + TlenVoiceReceiveParse(ft); + } + } + JabberLog(ft->proto, "Closing connection for this file transfer... "); + Netlib_CloseHandle(s); + } else { + ft->state = FT_ERROR; + } + } + } else { + JabberLog(ft->proto, "Cannot allocate port to bind for file server thread, thread ended."); + ft->state = FT_ERROR; + } + JabberListRemove(ft->proto, LIST_VOICE, ft->iqId); + switch (ft->state) { + case FT_DONE: + JabberLog(ft->proto, "Finish successfully"); + SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Finished...")); + //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); + break; + case FT_DENIED: + SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Denied...")); + //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_DENIED, ft, 0); + break; + default: // FT_ERROR: + nick = JabberNickFromJID(ft->jid); + JabberSend(ft->proto, "", nick, ft->iqId); + mir_free(nick); + JabberLog(ft->proto, "Finish with errors"); + SetDlgItemText(ft->proto->voiceDlgHWND, IDC_STATUS, TranslateT("...Error...")); + //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); + break; + } + JabberLog(ft->proto, "Thread ended: type=voice_send"); + TlenP2PFreeFileTransfer(ft); +} + +static void TlenVoiceSendParse(TLEN_FILE_TRANSFER *ft) +{ + int codec, i; + TLEN_FILE_PACKET *packet; + + codec = ft->proto->recordingControl->codec; + if ((packet=TlenP2PPacketCreate(sizeof(DWORD)+MODE_FRAME_SIZE[codec]*33)) != NULL) { + short *in; + float val; + in = ft->proto->recordingControl->recordingData; + TlenP2PPacketSetType(packet, 0x96); + packet->packet[0] = codec; + TlenP2PPacketPackDword(packet, codec); + val = 0; + for (i=0; i VU_METER_LEVELS - 1 ) { + i = VU_METER_LEVELS - 1; + } else if (i<0) { + i = 0; + } + ft->proto->recordingControl->vuMeter = i; + for (i=0; iproto->recordingControl->gsmstate, in + i * 160); + TlenP2PPacketPackBuffer(packet, (char*)ft->proto->recordingControl->gsmstate->gsmFrame, 33); + } + TlenVoiceCrypt(packet->packet+4, packet->len-4); + if (!TlenP2PPacketSend(ft->s, packet)) { + ft->state = FT_ERROR; + } + ft->proto->recordingControl->bytesSum += 8 + packet->len; + TlenP2PPacketFree(packet); + } else { + ft->state = FT_ERROR; + } +} + +int TlenVoiceCancelAll(TlenProtocol *proto) +{ + JABBER_LIST_ITEM *item; + HANDLE hEvent; + int i = 0; + + while ((i=JabberListFindNext(proto, LIST_VOICE, 0)) >=0 ) { + if ((item=JabberListGetItemPtrFromIndex(proto, i)) != NULL) { + TLEN_FILE_TRANSFER *ft = item->ft; + JabberListRemoveByIndex(proto, i); + if (ft != NULL) { + if (ft->s) { + //ProtoBroadcastAck(iface.m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); + JabberLog(proto, "Closing ft->s = %d", ft->s); + ft->state = FT_ERROR; + Netlib_CloseHandle(ft->s); + ft->s = NULL; + if (ft->hFileEvent != NULL) { + hEvent = ft->hFileEvent; + ft->hFileEvent = NULL; + SetEvent(hEvent); + } + } else { + JabberLog(proto, "freeing (V) ft struct"); + TlenP2PFreeFileTransfer(ft); + } + } + } + } + if (proto->voiceDlgHWND !=NULL) { + EndDialog(proto->voiceDlgHWND, 0); + } + return 0; +} + +INT_PTR TlenVoiceContactMenuHandleVoice(void *ptr, WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact; + DBVARIANT dbv; + JABBER_LIST_ITEM *item; + TLEN_FILE_TRANSFER *ft; + TlenProtocol *proto =(TlenProtocol *)ptr; + if (!proto->isOnline) { + return 1; + } + if ((hContact=(HANDLE) wParam)!=NULL) { + if (!DBGetContactSetting(hContact, proto->iface.m_szModuleName, "jid", &dbv)) { + char serialId[32]; + sprintf(serialId, "%d", JabberSerialNext(proto)); + if ((item = JabberListAdd(proto, LIST_VOICE, serialId)) != NULL) { + ft = TlenFileCreateFT(proto, dbv.pszVal); + ft->iqId = mir_strdup(serialId); + item->ft = ft; +// JabberSend(ft->proto, "", ft->jid); +// Sleep(5000); + TlenVoiceStart(ft, 2); + JabberSend(ft->proto, "", ft->jid, serialId); + } + DBFreeVariant(&dbv); + } + } + return 0; +} + +int TlenVoiceIsInUse(TlenProtocol *proto) { + if (JabberListFindNext(proto, LIST_VOICE, 0) >= 0 || proto->voiceDlgHWND!=NULL) { + JabberLog(proto, "voice in use ? %d", proto->voiceDlgHWND); + return 1; + } + return 0; +} + +static HBITMAP TlenVoiceMakeBitmap(int w, int h, int bpp, void *ptr) +{ + BITMAPINFO bmih; + HBITMAP hbm; + HDC hdc; + bmih.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmih.bmiHeader.biWidth = w&0xFFFFFFFC; + bmih.bmiHeader.biHeight = h;//&0xFFFFFFFC; + bmih.bmiHeader.biPlanes = 1; // musi byc 1 + bmih.bmiHeader.biBitCount = bpp; + bmih.bmiHeader.biCompression = BI_RGB; + bmih.bmiHeader.biSizeImage = 0; + bmih.bmiHeader.biXPelsPerMeter = 0; + bmih.bmiHeader.biYPelsPerMeter = 0; + bmih.bmiHeader.biClrUsed = 0; + bmih.bmiHeader.biClrImportant = 0; + hdc = CreateDC(_T("DISPLAY"), NULL, NULL, NULL); + hbm = CreateDIBitmap(hdc, (PBITMAPINFOHEADER) &bmih, CBM_INIT, ptr, &bmih, DIB_RGB_COLORS); + ReleaseDC(NULL,hdc); + return hbm; +} + +static void TlenVoiceInitVUMeters() +{ + int i, v, y, x, x0, col, col0; + unsigned char *pBits; + int ledWidth, ledHeight; + ledWidth = 9; + ledHeight = 6; + VU_METER_HEIGHT = ledHeight; + VU_METER_WIDTH = (VU_METER_LEVELS-1) * ledWidth; + VU_METER_WIDTH = (VU_METER_WIDTH + 3) & (~3); + pBits = (unsigned char *)mir_alloc(3*VU_METER_WIDTH*VU_METER_HEIGHT); + memset(pBits, 0x80, 3*VU_METER_WIDTH*VU_METER_HEIGHT); + for (i=0;i=i) { + if (v < 10) col0 = 0x104010; + else if (v<13) col0 = 0x404010; + else col0 = 0x401010; + } else { + if (v < 10) col0 = 0x00f000; + else if (v<13) col0 = 0xf0f000; + else col0 = 0xf00000; + } + x0 = v * ledWidth; + for (y=1;y>8) &0xFF; + pBits[3*(x+x0+y*VU_METER_WIDTH)+2] = (col>>16) &0xFF; + } + } + } + vuMeterBitmaps[i] = TlenVoiceMakeBitmap(VU_METER_WIDTH, VU_METER_HEIGHT, 24, pBits); + } + mir_free(pBits); +} + +static INT_PTR CALLBACK TlenVoiceDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HDC hDC, hMemDC; + int v; + static int counter; + TlenProtocol *proto = (TlenProtocol *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + switch (msg) { + case WM_INITDIALOG: + proto = (TlenProtocol *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)proto); + proto->voiceDlgHWND = hwndDlg; + TranslateDialogDefault(hwndDlg); + SendDlgItemMessage(hwndDlg, IDC_VCQUALITY, CB_ADDSTRING, 0, (LPARAM) TranslateT("8000 Hz / 13.8 kbps")); + SendDlgItemMessage(hwndDlg, IDC_VCQUALITY, CB_ADDSTRING, 0, (LPARAM) TranslateT("11025 Hz / 19.1 kbps")); + SendDlgItemMessage(hwndDlg, IDC_VCQUALITY, CB_ADDSTRING, 0, (LPARAM) TranslateT("22050 Hz / 36.8 kbps")); + SendDlgItemMessage(hwndDlg, IDC_VCQUALITY, CB_ADDSTRING, 0, (LPARAM) TranslateT("44100 Hz / 72 kbps")); + SendDlgItemMessage(hwndDlg, IDC_VCQUALITY, CB_SETCURSEL, 1, 0); + SendDlgItemMessage(hwndDlg, IDC_MICROPHONE, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_SPEAKER, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_MICROPHONE, BUTTONSETASPUSHBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_SPEAKER, BUTTONSETASPUSHBTN, 0, 0); + { + HICON hIcon = GetIcolibIcon(IDI_MICROPHONE); + SendDlgItemMessage(hwndDlg, IDC_MICROPHONE, BM_SETIMAGE, IMAGE_ICON, (LPARAM) hIcon); + ReleaseIcolibIcon(hIcon); + hIcon = GetIcolibIcon(IDI_SPEAKER); + SendDlgItemMessage(hwndDlg, IDC_SPEAKER, BM_SETIMAGE, IMAGE_ICON, (LPARAM) hIcon); + ReleaseIcolibIcon(hIcon); + } + CheckDlgButton(hwndDlg, IDC_MICROPHONE, TRUE); + CheckDlgButton(hwndDlg, IDC_SPEAKER, TRUE); + TlenVoiceInitVUMeters(); + SetDlgItemText(hwndDlg, IDC_STATUS, TranslateT("...???...")); + counter = 0; + SetTimer(hwndDlg, 1, 100, NULL); + return FALSE; + case WM_TIMER: + if (proto->recordingControl != NULL && !proto->recordingControl->bDisable) { + v = proto->recordingControl->vuMeter % VU_METER_LEVELS; + if (proto->recordingControl->vuMeter >0) { + proto->recordingControl->vuMeter--; + } + } else { + v = 0; + } + hDC = GetDC(GetDlgItem(hwndDlg, IDC_VUMETERIN)); + if (NULL != (hMemDC = CreateCompatibleDC( hDC ))) { + SelectObject( hMemDC, vuMeterBitmaps[v]) ; + BitBlt( hDC, 0, 0, VU_METER_WIDTH, VU_METER_HEIGHT, hMemDC, 0, 0, SRCCOPY ) ; + DeleteDC(hMemDC); + } + ReleaseDC(GetDlgItem(hwndDlg, IDC_PLAN), hDC); + if (proto->playbackControl != NULL && !proto->playbackControl->bDisable) { + v = proto->playbackControl->vuMeter % VU_METER_LEVELS; + if (proto->playbackControl->vuMeter >0) { + proto->playbackControl->vuMeter--; + } + } else { + v = 0; + } + hDC = GetDC(GetDlgItem(hwndDlg, IDC_VUMETEROUT)); + if (NULL != (hMemDC = CreateCompatibleDC( hDC ))) { + SelectObject( hMemDC, vuMeterBitmaps[v]) ; + BitBlt( hDC, 0, 0, VU_METER_WIDTH, VU_METER_HEIGHT, hMemDC, 0, 0, SRCCOPY ) ; + DeleteDC(hMemDC); + } + ReleaseDC(GetDlgItem(hwndDlg, IDC_PLAN), hDC); + counter ++; + if (counter %10 == 0) { + char str[50]; + float fv; + if (proto->recordingControl != NULL) { + fv = (float)proto->recordingControl->bytesSum; + proto->recordingControl->bytesSum = 0; + } else { + fv = 0; + } + sprintf(str, "%.1f kB/s", fv / 1024); + SetDlgItemTextA(hwndDlg, IDC_BYTESOUT, str); + if (proto->playbackControl != NULL) { + fv = (float)proto->playbackControl->bytesSum; + proto->playbackControl->bytesSum = 0; + } else { + fv = 0; + } + sprintf(str, "%.1f kB/s", fv / 1024); + SetDlgItemTextA(hwndDlg, IDC_BYTESIN, str); + } + break; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDCANCEL: + EndDialog(hwndDlg, 0); + return TRUE; + case IDC_VCQUALITY: + if (HIWORD(wParam)==CBN_SELCHANGE) { + if (proto->recordingControl!=NULL) { + int codec; + codec = SendDlgItemMessage(hwndDlg, IDC_VCQUALITY, CB_GETCURSEL, 0, 0) + 2; + if (codec!=proto->recordingControl->codec && codec>1 && codec<6) { + TLEN_FILE_TRANSFER *ft = proto->recordingControl->ft; + TlenVoiceFreeVc(proto->recordingControl); + proto->recordingControl = TlenVoiceCreateVC(ft->proto, codec); + proto->recordingControl->ft = ft; + TlenVoiceRecordingStart(proto->recordingControl); + } + } + } + case IDC_MICROPHONE: + if (proto->recordingControl!=NULL) { + proto->recordingControl->bDisable = !IsDlgButtonChecked(hwndDlg, IDC_MICROPHONE); + } + break; + case IDC_SPEAKER: + if (proto->playbackControl!=NULL) { + proto->playbackControl->bDisable = !IsDlgButtonChecked(hwndDlg, IDC_SPEAKER); + } + break; + } + break; + case WM_CLOSE: + EndDialog(hwndDlg, 0); + break; + case WM_DESTROY: + proto->voiceDlgHWND = NULL; + break; + + } + return FALSE; +} + +static void __cdecl TlenVoiceDlgThread(void *ptr) +{ + + TLEN_FILE_TRANSFER *ft = (TLEN_FILE_TRANSFER *)ptr; + TlenProtocol * proto = ft->proto; + DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_VOICE), NULL, TlenVoiceDlgProc, (LPARAM) proto); + TlenVoiceCancelAll(proto); +} + +int TlenVoiceStart(TLEN_FILE_TRANSFER *ft, int mode) +{ + + JabberLog(ft->proto, "starting voice %d", mode); + if (mode==0) { + JabberForkThread((void (__cdecl *)(void*))TlenVoiceReceiveThread, 0, ft); + } else if (mode==1) { + JabberForkThread((void (__cdecl *)(void*))TlenVoiceSendingThread, 0, ft); + } else { + JabberForkThread((void (__cdecl *)(void*))TlenVoiceDlgThread, 0, ft); + } + return 0; +} + +static char *getDisplayName(TlenProtocol *proto, const char *id) +{ + char jid[256]; + HANDLE hContact; + DBVARIANT dbv; + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { + _snprintf(jid, sizeof(jid), "%s@%s", id, dbv.pszVal); + DBFreeVariant(&dbv); + if ((hContact=JabberHContactFromJID(proto, jid)) != NULL) { + return mir_strdup((char *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, 0)); + } + } + return mir_strdup(id); +} + +typedef struct { + TlenProtocol *proto; + JABBER_LIST_ITEM *item; +}ACCEPTDIALOGDATA; + +static INT_PTR CALLBACK TlenVoiceAcceptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + ACCEPTDIALOGDATA * data; + char *str; + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + data = (ACCEPTDIALOGDATA *) lParam; + str = getDisplayName(data->proto, data->item->nick); + SetDlgItemTextA(hwndDlg, IDC_FROM, str); + mir_free(str); + return FALSE; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_ACCEPT: + EndDialog(hwndDlg, 1); + return TRUE; + case IDCANCEL: + case IDCLOSE: + EndDialog(hwndDlg, 0); + return TRUE; + } + break; + case WM_CLOSE: + EndDialog(hwndDlg, 0); + break; + } + return FALSE; +} + +static void __cdecl TlenVoiceAcceptDlgThread(void *ptr) +{ + + ACCEPTDIALOGDATA *data = (ACCEPTDIALOGDATA *)ptr; + int result = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ACCEPT_VOICE), NULL, TlenVoiceAcceptDlgProc, (LPARAM) data); + if (result && data->proto->isOnline) { + data->item->ft = TlenFileCreateFT(data->proto, data->item->nick); + data->item->ft->iqId = mir_strdup(data->item->jid); + TlenVoiceStart(data->item->ft, 2); + JabberSend(data->proto, "", data->item->nick, data->item->jid); + } else { + if (data->proto->isOnline) { + JabberSend(data->proto, "", data->item->nick, data->item->jid); + } + JabberListRemove(data->proto, LIST_VOICE, data->item->jid); + } + mir_free(data); +} + +int TlenVoiceAccept(TlenProtocol *proto, const char *id, const char *from) +{ + JABBER_LIST_ITEM * item; + if (!TlenVoiceIsInUse(proto)) { + if ((item = JabberListAdd(proto, LIST_VOICE, id)) != NULL) { + int ask, ignore, voiceChatPolicy; + ask = TRUE; + ignore = FALSE; + voiceChatPolicy = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "VoiceChatPolicy", 0); + if (voiceChatPolicy == TLEN_MUC_ASK) { + ignore = FALSE; + ask = TRUE; + } else if (voiceChatPolicy == TLEN_MUC_IGNORE_ALL) { + ignore = TRUE; + } else if (voiceChatPolicy == TLEN_MUC_IGNORE_NIR) { + char jid[256]; + DBVARIANT dbv; + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { + _snprintf(jid, sizeof(jid), "%s@%s", from, dbv.pszVal); + DBFreeVariant(&dbv); + } else { + strcpy(jid, from); + } + ignore = !IsAuthorized(proto, jid); + ask = TRUE; + } else if (voiceChatPolicy == TLEN_MUC_ACCEPT_IR) { + char jid[256]; + JABBER_LIST_ITEM *item; + DBVARIANT dbv; + if (!DBGetContactSetting(NULL, proto->iface.m_szModuleName, "LoginServer", &dbv)) { + _snprintf(jid, sizeof(jid), "%s@%s", from, dbv.pszVal); + DBFreeVariant(&dbv); + } else { + strcpy(jid, from); + } + ask = !IsAuthorized(proto, jid); + ignore = FALSE; + } else if (voiceChatPolicy == TLEN_MUC_ACCEPT_ALL) { + ask = FALSE; + ignore = FALSE; + } + if (ignore) { + if (proto->isOnline) { + JabberSend(proto, "", from, id); + } + JabberListRemove(proto, LIST_VOICE, id); + } else { + item->nick = mir_strdup(from); + if (ask) { + ACCEPTDIALOGDATA *data = (ACCEPTDIALOGDATA *)mir_alloc(sizeof(ACCEPTDIALOGDATA)); + data->proto = proto; + data->item = item; + JabberForkThread((void (__cdecl *)(void*))TlenVoiceAcceptDlgThread, 0, data); + } else if (proto->isOnline) { + item->ft = TlenFileCreateFT(proto, from); + item->ft->iqId = mir_strdup(id); + TlenVoiceStart(item->ft, 2); + JabberSend(proto, "", item->nick, item->jid); + } + } + return 1; + } + } + return 0; +} + +int TlenVoiceBuildInDeviceList(TlenProtocol *proto, HWND hWnd) +{ int i, j, iNumDevs; + WAVEINCAPS wic; + iNumDevs = waveInGetNumDevs(); + SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)TranslateT("Default")); + for (i = j = 0; i < iNumDevs; i++) { + if (!waveInGetDevCaps(i, &wic, sizeof(WAVEINCAPS))) { + if (wic.dwFormats != 0) { + SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)wic.szPname); + j++; + } + } + } + i = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "VoiceDeviceIn", 0); + if (i>j) i = 0; + SendMessage(hWnd, CB_SETCURSEL, i, 0); + return 0; +} + +int TlenVoiceBuildOutDeviceList(TlenProtocol *proto, HWND hWnd) +{ int i, j, iNumDevs; + WAVEOUTCAPS woc; + iNumDevs = waveInGetNumDevs(); + SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)TranslateT("Default")); + for (i = j = 0; i < iNumDevs; i++) { + if (!waveOutGetDevCaps(i, &woc, sizeof(WAVEOUTCAPS))) { + if (woc.dwFormats != 0) { + SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)woc.szPname); + j++; + } + } + } + i = DBGetContactSettingWord(NULL, proto->iface.m_szModuleName, "VoiceDeviceOut", 0); + if (i>j) i = 0; + SendMessage(hWnd, CB_SETCURSEL, i, 0); + return 0; +} diff --git a/plugins/!NotAdopted/Tlen/tlen_voice.h b/plugins/!NotAdopted/Tlen/tlen_voice.h new file mode 100644 index 0000000000..cd38a23c1c --- /dev/null +++ b/plugins/!NotAdopted/Tlen/tlen_voice.h @@ -0,0 +1,68 @@ +/* + +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2004-2007 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef _TLEN_VOICE_H_ +#define _TLEN_VOICE_H_ + +#include +#include + +#include "jabber.h" +#include "codec/gsm.h" + +typedef struct TLEN_VOICE_CONTROL_STRUCT { + int waveMode; + int codec; + int bDisable; + + short *recordingData; + short *waveData; + WAVEHDR *waveHeaders; + int waveFrameSize; + int waveHeadersPos; + int waveHeadersNum; + +// HANDLE hEvent; + HANDLE hThread; + DWORD threadID; + HWAVEOUT hWaveOut; + HWAVEIN hWaveIn; + int isRunning; + int stopThread; + gsm_state *gsmstate; + TLEN_FILE_TRANSFER *ft; + int vuMeter; + int bytesSum; + TlenProtocol *proto; +} TLEN_VOICE_CONTROL; + + +extern void __cdecl TlenVoiceSendingThread(TLEN_FILE_TRANSFER *ft); +extern void __cdecl TlenVoiceReceiveThread(TLEN_FILE_TRANSFER *ft); +extern int TlenVoiceIsInUse(TlenProtocol *proto); +extern INT_PTR TlenVoiceContactMenuHandleVoice(void *ptr, WPARAM wParam, LPARAM lParam); +extern int TlenVoiceCancelAll(TlenProtocol *proto); +extern int TlenVoiceStart(TLEN_FILE_TRANSFER *ft, int mode) ; +extern int TlenVoiceAccept(TlenProtocol *proto, const char *id, const char *from); +extern int TlenVoiceBuildInDeviceList(TlenProtocol *proto, HWND hWnd); +extern int TlenVoiceBuildOutDeviceList(TlenProtocol *proto, HWND hWnd); +#endif + diff --git a/plugins/!NotAdopted/XSoundNotify/DebugLogger.hpp b/plugins/!NotAdopted/XSoundNotify/DebugLogger.hpp new file mode 100644 index 0000000000..3b2c5a5fc1 --- /dev/null +++ b/plugins/!NotAdopted/XSoundNotify/DebugLogger.hpp @@ -0,0 +1,91 @@ +#ifndef _GRS_DEBUG_LOGGER_H +#define _GRS_DEBUG_LOGGER_H + +#include +#include +#include +#include + +/** + * Простой логгер, который можно использовать в любом месте для вывода отладочной информации + * При выводе обычного сообщения надо использовать макрос GRS_DEBUG_LOG + * Для вывода сложного сообщения с использованием операторов ввода/вывода макрос GRS_DEBUG_FORMAT_LOG + * Лог сохраняется в рабочем каталоге под именем : grs_debug.log + */ + +namespace grs +{ + +class DebugLogger +{ +public: + class Except : public std::exception + { + public: + virtual const char * what() const throw() { return "pizda rulu"; } + }; + + DebugLogger() + { + try + { + _strm.open("D:\\grs_debug.log", std::ios::app); + } + catch (...) + { + throw Except(); + } + if (!_strm.is_open()) + throw Except(); + + log("Logger started"); + } + + void log(const std::string & str, const char * fileStr = 0, int line = 0) + { + if (!_strm.is_open()) + return ; + + time_t t(time(0)); + struct tm * timeinfo; + timeinfo = localtime (&t); + char timeStr[9]; + strftime (timeStr, 9, "%H:%M:%S", timeinfo); + _strm << "[" << timeStr << "] "; + if (fileStr) + _strm << fileStr << ":" << line<<" "; + _strm <<"# "<< str << std::endl; + } + + static DebugLogger * instance() + { + //static DebugLogger * logger = 0; + static std::auto_ptr loggerPtr; + if (loggerPtr.get() == 0) + loggerPtr.reset(new DebugLogger()); + return loggerPtr.get(); + } + +private: + std::ofstream _strm; +}; + +} + +#define GRS_DEBUG_FORMAT_LOG(data) {\ + grs::DebugLogger * l = grs::DebugLogger::instance();\ + if (l != 0) \ + {\ + std::stringstream strm;\ + strm << data;\ + l->log(strm.str(), __FILE__, __LINE__);\ + }\ + } + +#define GRS_DEBUG_LOG(data) {\ + grs::DebugLogger * l = grs::DebugLogger::instance();\ + if (l != 0)\ + l->log(data, __FILE__, __LINE__);\ + } + +#endif diff --git a/plugins/!NotAdopted/XSoundNotify/EventProcessor.cpp b/plugins/!NotAdopted/XSoundNotify/EventProcessor.cpp new file mode 100644 index 0000000000..6a97b6b125 --- /dev/null +++ b/plugins/!NotAdopted/XSoundNotify/EventProcessor.cpp @@ -0,0 +1,84 @@ +#include "EventProcessor.h" +#include +#include "m_protocols.h" +#include +#include "DebugLogger.hpp" + +// static area + +static std::unique_ptr XSN_EventProcessorPtr; + +void XSN_EventProcessor::make(PLUGINLINK * pl) +{ + XSN_EventProcessorPtr.reset(new XSN_EventProcessor(pl)); +} + +XSN_EventProcessor & XSN_EventProcessor::instance() +{ + return *XSN_EventProcessorPtr; +} + +// class methods + +XSN_EventProcessor::XSN_EventProcessor(PLUGINLINK * pl) : pluginLink(pl) +{ + +} + +void XSN_EventProcessor::process(WPARAM wParam, LPARAM lParam) +{ + if (!wParam || !lParam || !isReceiveMessage(lParam)) + return ; + try + { + MessageBox(0, "Receive message", "INFO", MB_OK); + /*GRS_DEBUG_LOG("Receive message"); + HANDLE contact = (HANDLE)wParam; + MessageBox(0, "Get protocol", "INFO", MB_OK); + GRS_DEBUG_LOG("Protocol : "); + xsn_string proto = getProtocol(wParam); + MessageBox(0, "Protocol is", proto.c_str(), MB_OK); + GRS_DEBUG_FORMAT_LOG(proto) + //xsn_string nick = getNick(wParam, proto.c_str()); + XSN_Variant sound; + DBGetContactSettingTString(contact, proto.c_str(), "XSNPlugin_sound", &sound); + if (!sound.empty()) + { + GRS_DEBUG_LOG("Sound for user exist"); + GRS_DEBUG_FORMAT_LOG("Playing sound : " << sound.ptszVal << ", for user : " << getNick(wParam, proto.c_str())); + PlaySound(sound.toString().c_str(), nullptr, SND_FILENAME | SND_ASYNC); + }*/ + } + catch (std::runtime_error &) + { + //MessageBoxA(0, e.what(), "Runtime error", MB_OK); + } + catch (...) + { + //MessageBoxA(0, "Unknown error occured", "Exception", MB_OK); + } +} + +bool XSN_EventProcessor::isReceiveMessage(LPARAM event) +{ + DBEVENTINFO info ={ sizeof(info) }; + CallService(MS_DB_EVENT_GET, event, (LPARAM)&info); + + // TODO : rec msg flag : 16, send msg flag : 18 - WTF? + // return (info.eventType == EVENTTYPE_MESSAGE) && (info.flags & DBEF_READ); + // It's condition work well - magic? + return !(((info.eventType != EVENTTYPE_MESSAGE) && !(info.flags & DBEF_READ)) || (info.flags & DBEF_SENT)); +} + +xsn_string XSN_EventProcessor::getProtocol(WPARAM contact) +{ + char *pszProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, contact, 0); + return xsn_string(pszProto); +} + +xsn_string XSN_EventProcessor::getNick(WPARAM contact, LPCTSTR protocol) +{ + XSN_Variant nick; + DBGetContactSettingTString((HANDLE)contact, protocol, "Nick", &nick); + return nick.toString(); +} diff --git a/plugins/!NotAdopted/XSoundNotify/EventProcessor.h b/plugins/!NotAdopted/XSoundNotify/EventProcessor.h new file mode 100644 index 0000000000..6de14f8f98 --- /dev/null +++ b/plugins/!NotAdopted/XSoundNotify/EventProcessor.h @@ -0,0 +1,27 @@ +#ifndef __XSN_EVENT_PROCESSOR +#define __XSN_EVENT_PROCESSOR + +#include +#include "xsn_types.h" +#include + + +class XSN_EventProcessor +{ +public: + static void make(PLUGINLINK * pl); + static XSN_EventProcessor & instance(); + + void process(WPARAM wParam, LPARAM lParam); + +protected: + XSN_EventProcessor(PLUGINLINK * pl); + + bool isReceiveMessage(LPARAM event); + xsn_string getProtocol(WPARAM contact); + xsn_string getNick(WPARAM contact, LPCTSTR protocol); + + PLUGINLINK * pluginLink; +}; + +#endif diff --git a/plugins/!NotAdopted/XSoundNotify/README b/plugins/!NotAdopted/XSoundNotify/README new file mode 100644 index 0000000000..d855b95460 --- /dev/null +++ b/plugins/!NotAdopted/XSoundNotify/README @@ -0,0 +1 @@ +Choose release mode (debug mode not configured) and configure Visual Studio environment for boost and WTL libraries include/libs paths diff --git a/plugins/!NotAdopted/XSoundNotify/SettingsDialog.cpp b/plugins/!NotAdopted/XSoundNotify/SettingsDialog.cpp new file mode 100644 index 0000000000..69b64d776f --- /dev/null +++ b/plugins/!NotAdopted/XSoundNotify/SettingsDialog.cpp @@ -0,0 +1,124 @@ +#include "SettingsDialog.h" +//#include "DebugLogger.hpp" + +template +T * GetComboBoxData(CComboBox & ctrl) +{ + return (T*)(ctrl.GetItemData(ctrl.GetCurSel())); +} + +SettingsDialog::SettingsDialog(SoundNotifyDataStorage & storage) : _dataStorage(storage) +{ + +} + +BOOL SettingsDialog::PreTranslateMessage(MSG* pMsg) +{ + return ::IsDialogMessage(m_hWnd, pMsg); +} + +LRESULT SettingsDialog::onInitDialog(UINT, WPARAM, LPARAM, BOOL&) +{ + _userCombo = GetDlgItem(IDC_COMBO_USERS); + _protoCombo = GetDlgItem(IDC_COMBO_PROTO); + _chooseButton = GetDlgItem(IDC_BUTTON_CHOOSE_SOUND); + _resetButton = GetDlgItem(IDC_BUTTON_RESET_SOUND); + _playButton = GetDlgItem(IDC_BUTTON_TEST_PLAY); + _soundLabel = GetDlgItem(IDC_LABEL_SOUND); + + auto & protocols = _dataStorage.getData(); + for (auto it = protocols.begin(), end = protocols.end(); it != end; ++it) + addProtocolItem(*it); + + _userCombo.EnableWindow(0); + GetDlgItem(IDC_BUTTON_CHOOSE_SOUND).EnableWindow(0); + GetDlgItem(IDC_BUTTON_RESET_SOUND).EnableWindow(0); + GetDlgItem(IDC_BUTTON_TEST_PLAY).EnableWindow(0); + return TRUE; +} + +LRESULT SettingsDialog::onOk(WORD, WORD wID, HWND, BOOL&) +{ + EndDialog(wID); + return 0; +} + +LRESULT SettingsDialog::onCancel(WORD, WORD wID, HWND, BOOL&) +{ + EndDialog(wID); + return 0; +} + +LRESULT SettingsDialog::onSelectProtocol(WORD, WORD, HWND, BOOL&) +{ + _userCombo.ResetContent(); + auto data = GetComboBoxData(_protoCombo); + for (auto it = data->second.begin(), end = data->second.end(); it != end; ++it) + { + int id = _userCombo.AddString(it->first.c_str()); + _userCombo.SetItemData(id, (DWORD_PTR)(&(*it))); + } + _userCombo.EnableWindow(TRUE); + _playButton.EnableWindow(FALSE); + _resetButton.EnableWindow(FALSE); + _chooseButton.EnableWindow(FALSE); + _soundLabel.SetWindowText(TEXT("")); + return 0; +} + +LRESULT SettingsDialog::onSelectUser(WORD, WORD, HWND, BOOL &) +{ + auto user = GetComboBoxData(_userCombo); + _chooseButton.EnableWindow(TRUE); + + BOOL soundSelected = !user->second->soundPath().empty(); + _resetButton.EnableWindow(soundSelected); + _playButton.EnableWindow(soundSelected); + setSoundLabelText(user->second->soundPath().c_str()); + + return 0; +} + +LRESULT SettingsDialog::onChooseSound(WORD, WORD, HWND , BOOL&) +{ + CFileDialog fileDlg(1, 0, 0, OFN_FILEMUSTEXIST, TEXT("WAV files\0*.wav\0\0")); + if (fileDlg.DoModal() != IDOK) + return 0; + + setSoundLabelText(fileDlg.m_szFileName); + auto user = GetComboBoxData(_userCombo); + user->second->setSound(xsn_string(fileDlg.m_szFileName)); + _resetButton.EnableWindow(TRUE); + _playButton.EnableWindow(TRUE); + return 0; +} + +LRESULT SettingsDialog::onResetSound(WORD, WORD wID, HWND , BOOL&) +{ + auto user = GetComboBoxData(_userCombo); + user->second->setSound(xsn_string()); + _resetButton.EnableWindow(FALSE); + _playButton.EnableWindow(FALSE); + _soundLabel.SetWindowText(TEXT("")); + return 0; +} + +LRESULT SettingsDialog::onTestPlay(WORD, WORD wID, HWND , BOOL&) +{ + auto user = GetComboBoxData(_userCombo); + PlaySound(user->second->soundPath().c_str(), nullptr, SND_FILENAME | SND_ASYNC); + return 0; +} + +void SettingsDialog::setSoundLabelText(LPCTSTR text) +{ + _soundLabel.SetWindowText(PathFindFileName(text)); +} + +void SettingsDialog::addProtocolItem(ProtocolTable::value_type & value) +{ + wchar_t protocol[30]; + mbstowcs(protocol, value.first.c_str(), 30); + int idx = _protoCombo.AddString(protocol); + _protoCombo.SetItemData(idx, (DWORD_PTR)(&value)); +} diff --git a/plugins/!NotAdopted/XSoundNotify/SettingsDialog.h b/plugins/!NotAdopted/XSoundNotify/SettingsDialog.h new file mode 100644 index 0000000000..c68503a6e8 --- /dev/null +++ b/plugins/!NotAdopted/XSoundNotify/SettingsDialog.h @@ -0,0 +1,60 @@ +#ifndef __XSN_SETTINGS_DIALOG_H +#define __XSN_SETTINGS_DIALOG_H + +#include +#include +#include +#include +#include +#include "resource.h" +#include "SoundNotifyDataStorage.h" + +class SettingsDialog : public CDialogImpl +{ +private: + CComboBox _userCombo; + CComboBox _protoCombo; + CButton _chooseButton; + CButton _resetButton; + CButton _playButton; + CStatic _soundLabel; + SoundNotifyDataStorage & _dataStorage; + +public: + SettingsDialog(SoundNotifyDataStorage & dataStorage); + virtual ~SettingsDialog() {} + static BOOL DlgProcCluiOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +public: + enum {IDD = IDD_DIALOG1}; + + BEGIN_MSG_MAP(SettingsDialog) + MESSAGE_HANDLER(WM_INITDIALOG, onInitDialog) + COMMAND_HANDLER(IDC_COMBO_PROTO, CBN_SELCHANGE, onSelectProtocol) + COMMAND_HANDLER(IDC_COMBO_USERS, CBN_SELCHANGE, onSelectUser) + COMMAND_ID_HANDLER(IDOK, onOk) + COMMAND_ID_HANDLER(IDCANCEL, onCancel) + COMMAND_ID_HANDLER(IDC_BUTTON_CHOOSE_SOUND, onChooseSound) + COMMAND_ID_HANDLER(IDC_BUTTON_RESET_SOUND, onResetSound) + COMMAND_ID_HANDLER(IDC_BUTTON_TEST_PLAY, onTestPlay) + END_MSG_MAP() + + virtual BOOL PreTranslateMessage(MSG* pMsg); + +protected: + LRESULT onInitDialog(UINT, WPARAM, LPARAM, BOOL&); + + LRESULT onOk(WORD, WORD, HWND, BOOL&); + LRESULT onCancel(WORD, WORD, HWND, BOOL &); + LRESULT onSelectProtocol(WORD, WORD, HWND, BOOL&); + LRESULT onSelectUser(WORD, WORD, HWND, BOOL &); + LRESULT onChooseSound(WORD, WORD, HWND , BOOL&); + LRESULT onResetSound(WORD, WORD, HWND , BOOL&); + LRESULT onTestPlay(WORD, WORD, HWND , BOOL&); + + void addProtocolItem(ProtocolTable::value_type & value); + + void setSoundLabelText(LPCTSTR text); +}; + +#endif diff --git a/plugins/!NotAdopted/XSoundNotify/SoundNotifyData.cpp b/plugins/!NotAdopted/XSoundNotify/SoundNotifyData.cpp new file mode 100644 index 0000000000..1876db6ba0 --- /dev/null +++ b/plugins/!NotAdopted/XSoundNotify/SoundNotifyData.cpp @@ -0,0 +1,37 @@ +#include "SoundNotifyData.h" + +SoundNotifyData::SoundNotifyData() : _contact(0), _soundChanged(false) +{ + +} + +SoundNotifyData::SoundNotifyData(HANDLE contact, const ModuleString & module, const xsn_string & sound) : + _contact(contact), _soundPath(sound), _soundChanged(false) +{ +} + +void SoundNotifyData::setSound(const xsn_string & sound) +{ + _soundChanged = true; + _soundPath = sound; +} + +HANDLE SoundNotifyData::contact() const +{ + return _contact; +} + +const xsn_string & SoundNotifyData::soundPath() const +{ + return _soundPath; +} + +const ModuleString & SoundNotifyData::module() const +{ + return _module; +} + +bool SoundNotifyData::isSoundChanged() const +{ + return _soundChanged; +} diff --git a/plugins/!NotAdopted/XSoundNotify/SoundNotifyData.h b/plugins/!NotAdopted/XSoundNotify/SoundNotifyData.h new file mode 100644 index 0000000000..18cb4844a4 --- /dev/null +++ b/plugins/!NotAdopted/XSoundNotify/SoundNotifyData.h @@ -0,0 +1,33 @@ +#ifndef __XSN_DATA_H +#define __XSN_DATA_H + +#include +#include "xsn_types.h" +#include + +class SoundNotifyData +{ +public: + SoundNotifyData(); + SoundNotifyData(HANDLE contact, const ModuleString & module, const xsn_string & sound); + + void setSound(const xsn_string & sound); + + HANDLE contact() const; + const xsn_string & soundPath() const; + const ModuleString & module() const; + bool isSoundChanged() const; + +private: + HANDLE _contact; + ModuleString _module; + xsn_string _soundPath; + bool _soundChanged; +}; +typedef std::shared_ptr SoundNotifyDataPtr; + +typedef std::unordered_map UserDataTable; +typedef std::unordered_map ProtocolTable; +typedef std::unordered_map ModuleConvertTable; + +#endif diff --git a/plugins/!NotAdopted/XSoundNotify/SoundNotifyDataStorage.cpp b/plugins/!NotAdopted/XSoundNotify/SoundNotifyDataStorage.cpp new file mode 100644 index 0000000000..bd1b90df52 --- /dev/null +++ b/plugins/!NotAdopted/XSoundNotify/SoundNotifyDataStorage.cpp @@ -0,0 +1,74 @@ +#include "SoundNotifyDataStorage.h" +#include +#include +#include "xsn_utils.h" +//#include "DebugLogger.hpp" + +SoundNotifyDataStorage::SoundNotifyDataStorage(PLUGINLINK * pl) : pluginLink(pl) +{ + +} + +void SoundNotifyDataStorage::init() +{ + initModuleConvertTable(_moduleTable); + registerProtocols(); + + HANDLE contact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); + for(; contact; contact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)contact,0)) + { + try + { + addContact(contact); + } + catch (...) + { + // log + } + } +} + +void SoundNotifyDataStorage::commit() +{ + for (auto it = _protocolTable.begin(), end = _protocolTable.end(); it != end; ++it) + for (auto user = it->second.begin(), userEnd = it->second.end(); user != userEnd; ++user) + if (user->second->isSoundChanged()) + { + if (user->second->soundPath().empty()) + DBDeleteContactSetting(user->second->contact(), XSN_ModuleInfo::name(), XSN_ModuleInfo::soundSetting()); + else + DBWriteContactSettingTString(user->second->contact(), XSN_ModuleInfo::name(), XSN_ModuleInfo::soundSetting(), user->second->soundPath().c_str()); + } +} + +void SoundNotifyDataStorage::addContact(HANDLE contact) +{ + ModuleString module = getContactModule(contact); + ProtocolString proto = _moduleTable[module]; + xsn_string user = getContactId(contact, module, proto); + if (user.empty()) + return ; + + XSN_Variant sound; + DBGetContactSettingTString(contact, XSN_ModuleInfo::name(), XSN_ModuleInfo::soundSetting(), &sound); + _protocolTable[proto][user] = SoundNotifyDataPtr(new SoundNotifyData(contact, module, sound.toString())); +} + +xsn_string SoundNotifyDataStorage::getContactId(HANDLE contact, const ModuleString & module, const ProtocolString & proto) +{ + auto it = _registeredProtocols.find(proto); + if (it == _registeredProtocols.end()) + return xsn_string(); + return it->second(contact, module); +} + +ProtocolTable & SoundNotifyDataStorage::getData() +{ + return _protocolTable; +} + +void SoundNotifyDataStorage::registerProtocols() +{ + _registeredProtocols["ICQ"] = &getIcqContactId; + _registeredProtocols["JABBER"] = &getJabberContactId; +} diff --git a/plugins/!NotAdopted/XSoundNotify/SoundNotifyDataStorage.h b/plugins/!NotAdopted/XSoundNotify/SoundNotifyDataStorage.h new file mode 100644 index 0000000000..7dbf03c494 --- /dev/null +++ b/plugins/!NotAdopted/XSoundNotify/SoundNotifyDataStorage.h @@ -0,0 +1,34 @@ +#ifndef _XSN_DATA_STORAGE +#define _XSN_DATA_STORAGE + +#include "SoundNotifyData.h" +#include +#include + +class SoundNotifyDataStorage +{ +public: + SoundNotifyDataStorage(PLUGINLINK * pl); + + void init(); + void commit(); + + ProtocolTable & getData(); + +protected: + void addContact(HANDLE contact); + xsn_string getContactId(HANDLE contact, const ModuleString & module, const ProtocolString & proto); + void registerProtocols(); + +private: + PLUGINLINK * pluginLink; + + ProtocolTable _protocolTable; + ModuleConvertTable _moduleTable; + + typedef boost::function getContactIdFunc; + typedef std::unordered_map RegisteredProtocols; + RegisteredProtocols _registeredProtocols; +}; + +#endif diff --git a/plugins/!NotAdopted/XSoundNotify/XSoundNotify.rc b/plugins/!NotAdopted/XSoundNotify/XSoundNotify.rc new file mode 100644 index 0000000000..ab42834a08 Binary files /dev/null and b/plugins/!NotAdopted/XSoundNotify/XSoundNotify.rc differ diff --git a/plugins/!NotAdopted/XSoundNotify/resource.h b/plugins/!NotAdopted/XSoundNotify/resource.h new file mode 100644 index 0000000000..fcd39e7cf3 Binary files /dev/null and b/plugins/!NotAdopted/XSoundNotify/resource.h differ diff --git a/plugins/!NotAdopted/XSoundNotify/testplug.vcxproj b/plugins/!NotAdopted/XSoundNotify/testplug.vcxproj new file mode 100644 index 0000000000..ebd0a0009f --- /dev/null +++ b/plugins/!NotAdopted/XSoundNotify/testplug.vcxproj @@ -0,0 +1,167 @@ +п»ї + + + + Debug + Win32 + + + Release + Win32 + + + + + + XSoundNotify + + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + false + Unicode + + + + + + + + + + + + + + + .\Release\ + .\Release\ + false + E:\Programming\libs\WTL\Include;$(IncludePath) + + + .\Debug\ + .\Debug\ + true + + + + MultiThreaded + OnlyExplicitInline + true + true + MaxSpeed + true + Level3 + e:\Programming\libs\boost_1_46_1\;../../include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;TESTPLUG_EXPORTS;%(PreprocessorDefinitions) + .\Release\ + .\Release\testplug.pch + .\Release\ + .\Release\ + + + true + NDEBUG;%(PreprocessorDefinitions) + .\Release\testplug.tlb + true + Win32 + + + 0x0809 + NDEBUG;%(PreprocessorDefinitions) + + + true + .\Release\testplug.bsc + + + true + true + Console + release/xsoundnotify.dll + .\Release\testplug.lib + odbc32.lib;odbccp32.lib;winmm.lib;%(AdditionalDependencies) + e:\Programming\libs\wxWidgets-2.9.3\lib\vc_lib\;%(AdditionalLibraryDirectories) + + + + + MultiThreadedDebug + Default + false + Disabled + true + Level3 + true + EditAndContinue + e:\Programming\libs\wxWidgets-2.9.3\include\msvc\;e:\Programming\libs\wxWidgets-2.9.3\include\;../../include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;XSOUNDNOTIFY_EXPORTS;%(PreprocessorDefinitions) + .\Debug\ + .\Debug\testplug.pch + .\Debug\ + .\Debug\ + EnableFastChecks + + + true + _DEBUG;%(PreprocessorDefinitions) + .\Debug\testplug.tlb + true + Win32 + + + 0x0809 + _DEBUG;%(PreprocessorDefinitions) + + + true + .\Debug\testplug.bsc + + + true + true + true + Console + .\Debug\xsoundnotify.dll + .\Debug\xsoundnotify.lib + wxmsw29u_adv.lib;wxmsw29u_core.lib;wxbase29u.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;wxregexu.lib;wxexpat.lib;odbc32.lib;odbccp32.lib;winmm.lib;%(AdditionalDependencies) + + + e:\Programming\libs\wxWidgets-2.9.3\lib\vc_lib\;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/!NotAdopted/XSoundNotify/xsn_main.cpp b/plugins/!NotAdopted/XSoundNotify/xsn_main.cpp new file mode 100644 index 0000000000..ebcf029143 --- /dev/null +++ b/plugins/!NotAdopted/XSoundNotify/xsn_main.cpp @@ -0,0 +1,122 @@ +/* +Miranda plugin template, originally by Richard Hughes +http://miranda-icq.sourceforge.net/ + +This file is placed in the public domain. Anybody is free to use or +modify it as they wish with no restriction. +There is no warranty. +*/ + +#include "SettingsDialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include "xsn_utils.h" +//#include "DebugLogger.hpp" + +HINSTANCE hInst; +PLUGINLINK *pluginLink; +HANDLE AddEventHook; + +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), // Размер стуктуры + "XSoundNotify", // Короткое имя плагинв + PLUGIN_MAKE_VERSION(1,0,0,0), // Версия плагина + "Provides extended options for sound notifications", // Описание плагина + "Roman Torsten", // Автор + "rs_torsten-public@yahoo.com", // Адресс автора + "© 2011 Copyright", // Копирайт + "https://plus.google.com/117081718640940130539", // Адресс сайта разработчика плагина + 0, + 0, + {0x8b86253, 0xec6e, 0x4d09, { 0xb7, 0xa9, 0x64, 0xac, 0xdf, 0x6, 0x27, 0xb8 }} //{08B86253-EC6E-4d09-B7A9-64ACDF0627B8} +}; + +extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + hInst = hinstDLL; + return TRUE; +} + +static int PluginMenuCommand(WPARAM wParam,LPARAM lParam) +{ + try + { + SoundNotifyDataStorage storage(pluginLink); + storage.init(); + SettingsDialog dlg(storage); + if (dlg.DoModal() == IDOK) + storage.commit(); + } + catch (...) + { + MessageBox(0, TEXT("Unknown error occured while configuring"), TEXT("XSoundNotify Error"), MB_OK | MB_ICONERROR); + } + + return 0; +} + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +extern "C" __declspec(dllexport) const MUUID interfaces[] = {MIID_TESTPLUGIN, MIID_LAST}; +extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + +INT processEvent(WPARAM wParam, LPARAM lParam) +{ + try + { + if (!isReceiveMessage(lParam)) + return 0; + + xsn_string sound = getContactSound((HANDLE)wParam); + if (!sound.empty()) + PlaySound(sound.c_str(), nullptr, SND_ASYNC | SND_FILENAME); + } + catch (std::exception & ) + { + // log + } + catch (...) + { + // log + } + + return 0; +} + +extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) +{ + CLISTMENUITEM mi; + + pluginLink=link; + CreateServiceFunction("XSoundNotify/MenuCommand", PluginMenuCommand); + ZeroMemory(&mi,sizeof(mi)); + mi.cbSize=sizeof(mi); + mi.position=-0x7FFFFFFF; + mi.flags=0; + mi.hIcon=LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); + mi.pszName=LPGEN("&XSoundNotify Plugin"); + mi.pszService="XSoundNotify/MenuCommand"; + CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi); + AddEventHook = HookEvent(ME_DB_EVENT_ADDED, processEvent); + + return 0; +} + +extern "C" int __declspec(dllexport) Unload(void) +{ + UnhookEvent(AddEventHook); + return 0; +} + diff --git a/plugins/!NotAdopted/XSoundNotify/xsn_types.cpp b/plugins/!NotAdopted/XSoundNotify/xsn_types.cpp new file mode 100644 index 0000000000..da0cc5b3f9 --- /dev/null +++ b/plugins/!NotAdopted/XSoundNotify/xsn_types.cpp @@ -0,0 +1,32 @@ +#include "xsn_types.h" + +XSN_Variant::XSN_Variant() +{ + ptszVal = nullptr; +} + +XSN_Variant::~XSN_Variant() +{ + if (ptszVal) + DBFreeVariant(this); +} + +xsn_string XSN_Variant::toString() const +{ + return ptszVal == nullptr ? xsn_string() : xsn_string(ptszVal); +} + +bool XSN_Variant::empty() const +{ + return ptszVal == nullptr; +} + +const char * XSN_ModuleInfo::name() +{ + return "XSoundNotify"; +} + +const char * XSN_ModuleInfo::soundSetting() +{ + return "XSNPlugin_sound"; +} diff --git a/plugins/!NotAdopted/XSoundNotify/xsn_types.h b/plugins/!NotAdopted/XSoundNotify/xsn_types.h new file mode 100644 index 0000000000..43f4434fea --- /dev/null +++ b/plugins/!NotAdopted/XSoundNotify/xsn_types.h @@ -0,0 +1,33 @@ +#ifndef __XSN_TYPES +#define __XSN_TYPES + +#include +#include +#include +#include + +#ifndef UNICODE + typedef std::string xsn_string; +#else + typedef std::wstring xsn_string; +#endif + +typedef std::string ModuleString; +typedef std::string ProtocolString; + +struct XSN_Variant : DBVARIANT +{ + XSN_Variant(); + ~XSN_Variant(); + + xsn_string toString() const; + bool empty() const; +}; + +struct XSN_ModuleInfo +{ + static const char * name(); + static const char * soundSetting(); +}; + +#endif diff --git a/plugins/!NotAdopted/XSoundNotify/xsn_utils.cpp b/plugins/!NotAdopted/XSoundNotify/xsn_utils.cpp new file mode 100644 index 0000000000..d597776e8d --- /dev/null +++ b/plugins/!NotAdopted/XSoundNotify/xsn_utils.cpp @@ -0,0 +1,60 @@ +#include "xsn_utils.h" +#include +#include + +void initModuleConvertTable(ModuleConvertTable & table) +{ + int number = 0; + // may be need to free PROTOACCOUNT, but did't found information about it + PROTOACCOUNT ** accounts; + ProtoEnumAccounts(&number, &accounts); + for (int i = 0; i < number; ++i) + table[ModuleString(accounts[i]->szModuleName)] = ProtocolString(accounts[i]->szProtoName); +} + +bool isReceiveMessage(LPARAM event) +{ + DBEVENTINFO info = { sizeof(info) }; + CallService(MS_DB_EVENT_GET, event, (LPARAM)&info); + // i don't understand why it works and how it works, but it works correctly - practice way (методом тыка) + // so, i think correct condition would be : eventType == EVENTTYPE_MESSAGE && info.flags & DBEF_READ, but it really isn't + return !(((info.eventType != EVENTTYPE_MESSAGE) && !(info.flags & DBEF_READ)) || (info.flags & DBEF_SENT)); +} + +xsn_string getContactSound(HANDLE contact) +{ + XSN_Variant sound; + DBGetContactSettingTString(contact, XSN_ModuleInfo::name(), XSN_ModuleInfo::soundSetting(), &sound); + return sound.toString(); +} + +ModuleString getContactModule(HANDLE contact) +{ + char * proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)contact, 0); + if (proto == nullptr) + throw std::runtime_error("MS_PROTO_GETCONTACTBASEPROTO failed"); + return ModuleString(proto); +} + +xsn_string getIcqContactId(HANDLE contact, const ModuleString & module) +{ + XSN_Variant nick; + DBGetContactSettingTString(contact, module.c_str(), "CustomNick", &nick); + if (nick.empty()) + DBGetContactSettingTString(contact, module.c_str(), "Nick", &nick); + DWORD uin = DBGetContactSettingDword(contact, module.c_str(), "UIN", 0); + xsn_string uinStr = boost::lexical_cast(uin); + if (nick.empty()) + return uinStr; + return nick.toString() + TEXT(" (") + uinStr + TEXT(")"); +} + +xsn_string getJabberContactId(HANDLE contact, const ModuleString & module) +{ + XSN_Variant jid, nick; + DBGetContactSettingTString(contact, module.c_str(), "jid", &jid); + DBGetContactSettingTString(contact, "CList", "MyHandle", &nick); + if (nick.empty()) + return jid.toString(); + return nick.toString() + TEXT(" (") + jid.toString() + TEXT(")"); +} diff --git a/plugins/!NotAdopted/XSoundNotify/xsn_utils.h b/plugins/!NotAdopted/XSoundNotify/xsn_utils.h new file mode 100644 index 0000000000..66bdef2526 --- /dev/null +++ b/plugins/!NotAdopted/XSoundNotify/xsn_utils.h @@ -0,0 +1,18 @@ +#ifndef _XSN_UTILS_H +#define _XSN_UTILS_H + +#include "xsn_types.h" +#include "SoundNotifyData.h" + +void initModuleConvertTable(ModuleConvertTable & table); + +bool isReceiveMessage(LPARAM event); + +xsn_string getContactSound(HANDLE contact); +ModuleString getContactModule(HANDLE contact); + +xsn_string getIcqContactId(HANDLE contact, const ModuleString & module); +xsn_string getJabberContactId(HANDLE contact, const ModuleString & module); + + +#endif -- cgit v1.2.3